diff --git a/Source/appfat.cpp b/Source/appfat.cpp new file mode 100644 index 0000000..dd9bc96 --- /dev/null +++ b/Source/appfat.cpp @@ -0,0 +1,820 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int appfat_terminated = 0; // weak +char sz_error_buf[256]; +int terminating; // weak +int cleanup_thread_id; // weak +char empty_string; + +void __cdecl appfat_cpp_init() +{ + appfat_terminated = 0x7F800000; +} + +struct j_appfat_cpp_init +{ + j_appfat_cpp_init() + { + appfat_cpp_init(); + } +} _j_appfat_cpp_init; +/* +bool __cdecl appfat_cpp_free(void *a1) +{ + bool result; // al + + if ( a1 ) + result = SMemFree(a1, "delete", -1, 0); + return result; +} +*/ + +//----- (0040102A) -------------------------------------------------------- +char *__fastcall GetErr(int error_code) +{ + int v1; // edi + unsigned int v2; // eax + signed int v4; // eax + _BYTE *i; // ecx + + v1 = error_code; + v2 = ((unsigned int)error_code >> 16) & 0x1FFF; + if ( v2 == 0x0878 ) + { + GetDSErr(error_code, sz_error_buf, 256); + } + else if ( v2 == 0x0876 ) + { + GetDDErr(error_code, sz_error_buf, 256); + } + else + { + if ( !SErrGetErrorStr(error_code, sz_error_buf, 256) && !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, v1, 0x400u, sz_error_buf, 0x100u, NULL) ) + wsprintfA(sz_error_buf, "unknown error 0x%08x", v1); + } + v4 = strlen(sz_error_buf); + for ( i = (unsigned char *)&appfat_terminated + v4 + 3; v4 > 0; *i = 0 ) + { + --v4; + if ( *--i != '\r' && *i != '\n' ) + break; + } + return sz_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 > DDERR_SURFACEBUSY ) + { + if ( error_code > DDERR_NOPALETTEHW ) + { + if ( error_code > DDERR_CANTPAGELOCK ) + { + switch ( error_code ) + { + case DDERR_CANTPAGEUNLOCK: + v3 = "DDERR_CANTPAGEUNLOCK"; + goto LABEL_182; + case DDERR_NOTPAGELOCKED: + v3 = "DDERR_NOTPAGELOCKED"; + goto LABEL_182; + case DD_OK: + v3 = "DD_OK"; + goto LABEL_182; + } + } + else + { + if ( error_code == DDERR_CANTPAGELOCK ) + { + v3 = "DDERR_CANTPAGELOCK"; + goto LABEL_182; + } + switch ( error_code ) + { + case DDERR_BLTFASTCANTCLIP: + v3 = "DDERR_BLTFASTCANTCLIP"; + goto LABEL_182; + case DDERR_NOBLTHW: + v3 = "DDERR_NOBLTHW"; + goto LABEL_182; + case DDERR_NODDROPSHW: + v3 = "DDERR_NODDROPSHW"; + goto LABEL_182; + case DDERR_OVERLAYNOTVISIBLE: + v3 = "DDERR_OVERLAYNOTVISIBLE"; + goto LABEL_182; + case DDERR_NOOVERLAYDEST: + v3 = "DDERR_NOOVERLAYDEST"; + goto LABEL_182; + case DDERR_INVALIDPOSITION: + v3 = "DDERR_INVALIDPOSITION"; + goto LABEL_182; + case DDERR_NOTAOVERLAYSURFACE: + v3 = "DDERR_NOTAOVERLAYSURFACE"; + goto LABEL_182; + case DDERR_EXCLUSIVEMODEALREADYSET: + v3 = "DDERR_EXCLUSIVEMODEALREADYSET"; + goto LABEL_182; + case DDERR_NOTFLIPPABLE: + v3 = "DDERR_NOTFLIPPABLE"; + goto LABEL_182; + case DDERR_CANTDUPLICATE: + v3 = "DDERR_CANTDUPLICATE"; + goto LABEL_182; + case DDERR_NOTLOCKED: + v3 = "DDERR_NOTLOCKED"; + goto LABEL_182; + case DDERR_CANTCREATEDC: + v3 = "DDERR_CANTCREATEDC"; + goto LABEL_182; + case DDERR_NODC: + v3 = "DDERR_NODC"; + goto LABEL_182; + case DDERR_WRONGMODE: + v3 = "DDERR_WRONGMODE"; + goto LABEL_182; + case DDERR_IMPLICITLYCREATED: + v3 = "DDERR_IMPLICITLYCREATED"; + goto LABEL_182; + case DDERR_NOTPALETTIZED: + v3 = "DDERR_NOTPALETTIZED"; + goto LABEL_182; + case DDERR_NOMIPMAPHW: + v3 = "DDERR_NOMIPMAPHW"; + goto LABEL_182; + case DDERR_INVALIDSURFACETYPE: + v3 = "DDERR_INVALIDSURFACETYPE"; + goto LABEL_182; + case DDERR_DCALREADYCREATED: + v3 = "DDERR_DCALREADYCREATED"; + goto LABEL_182; + default: + goto LABEL_178; + } + } + } + else + { + if ( error_code == DDERR_NOPALETTEHW ) + { + v3 = "DDERR_NOPALETTEHW"; + goto LABEL_182; + } + if ( error_code > DDERR_INVALIDDIRECTDRAWGUID ) + { + switch ( error_code ) + { + case DDERR_DIRECTDRAWALREADYCREATED: + v3 = "DDERR_DIRECTDRAWALREADYCREATED"; + goto LABEL_182; + case DDERR_NODIRECTDRAWHW: + v3 = "DDERR_NODIRECTDRAWHW"; + goto LABEL_182; + case DDERR_PRIMARYSURFACEALREADYEXISTS: + v3 = "DDERR_PRIMARYSURFACEALREADYEXISTS"; + goto LABEL_182; + case DDERR_NOEMULATION: + v3 = "DDERR_NOEMULATION"; + goto LABEL_182; + case DDERR_REGIONTOOSMALL: + v3 = "DDERR_REGIONTOOSMALL"; + goto LABEL_182; + case DDERR_CLIPPERISUSINGHWND: + v3 = "DDERR_CLIPPERISUSINGHWND"; + goto LABEL_182; + case DDERR_NOCLIPPERATTACHED: + v3 = "DDERR_NOCLIPPERATTACHED"; + goto LABEL_182; + case DDERR_NOHWND: + v3 = "DDERR_NOHWND"; + goto LABEL_182; + case DDERR_HWNDSUBCLASSED: + v3 = "DDERR_HWNDSUBCLASSED"; + goto LABEL_182; + case DDERR_HWNDALREADYSET: + v3 = "DDERR_HWNDALREADYSET"; + goto LABEL_182; + case DDERR_NOPALETTEATTACHED: + v3 = "DDERR_NOPALETTEATTACHED"; + goto LABEL_182; + default: + goto LABEL_178; + } + } + else + { + if ( error_code == DDERR_INVALIDDIRECTDRAWGUID ) + { + v3 = "DDERR_INVALIDDIRECTDRAWGUID"; + goto LABEL_182; + } + if ( error_code > DDERR_TOOBIGWIDTH ) + { + switch ( error_code ) + { + case DDERR_UNSUPPORTEDFORMAT: + v3 = "DDERR_UNSUPPORTEDFORMAT"; + goto LABEL_182; + case DDERR_UNSUPPORTEDMASK: + v3 = "DDERR_UNSUPPORTEDMASK"; + goto LABEL_182; + case DDERR_VERTICALBLANKINPROGRESS: + v3 = "DDERR_VERTICALBLANKINPROGRESS"; + goto LABEL_182; + case DDERR_WASSTILLDRAWING: + v3 = "DDERR_WASSTILLDRAWING"; + goto LABEL_182; + case DDERR_XALIGN: + v3 = "DDERR_XALIGN"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case DDERR_TOOBIGWIDTH: + v3 = "DDERR_TOOBIGWIDTH"; + goto LABEL_182; + case DDERR_CANTLOCKSURFACE: + v3 = "DDERR_CANTLOCKSURFACE"; + goto LABEL_182; + case DDERR_SURFACEISOBSCURED: + v3 = "DDERR_SURFACEISOBSCURED"; + goto LABEL_182; + case DDERR_SURFACELOST: + v3 = "DDERR_SURFACELOST"; + goto LABEL_182; + case DDERR_SURFACENOTATTACHED: + v3 = "DDERR_SURFACENOTATTACHED"; + goto LABEL_182; + case DDERR_TOOBIGHEIGHT: + v3 = "DDERR_TOOBIGHEIGHT"; + goto LABEL_182; + case DDERR_TOOBIGSIZE: + v3 = "DDERR_TOOBIGSIZE"; + goto LABEL_182; + } + } + } + } + goto LABEL_178; + } + if ( error_code == DDERR_SURFACEBUSY ) + { + v3 = "DDERR_SURFACEBUSY"; + goto LABEL_182; + } + if ( error_code > DDERR_NOCOLORKEYHW ) + { + if ( error_code > DDERR_NOTEXTUREHW ) + { + if ( error_code > DDERR_OVERLAYCANTCLIP ) + { + switch ( error_code ) + { + case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: + v3 = "DDERR_OVERLAYCOLORKEYONLYONEACTIVE"; + goto LABEL_182; + case DDERR_PALETTEBUSY: + v3 = "DDERR_PALETTEBUSY"; + goto LABEL_182; + case DDERR_COLORKEYNOTSET: + v3 = "DDERR_COLORKEYNOTSET"; + goto LABEL_182; + case DDERR_SURFACEALREADYATTACHED: + v3 = "DDERR_SURFACEALREADYATTACHED"; + goto LABEL_182; + case DDERR_SURFACEALREADYDEPENDENT: + v3 = "DDERR_SURFACEALREADYDEPENDENT"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case DDERR_OVERLAYCANTCLIP: + v3 = "DDERR_OVERLAYCANTCLIP"; + goto LABEL_182; + case DDERR_NOVSYNCHW: + v3 = "DDERR_NOVSYNCHW"; + goto LABEL_182; + case DDERR_NOZBUFFERHW: + v3 = "DDERR_NOZBUFFERHW"; + goto LABEL_182; + case DDERR_NOZOVERLAYHW: + v3 = "DDERR_NOZOVERLAYHW"; + goto LABEL_182; + case DDERR_OUTOFCAPS: + v3 = "DDERR_OUTOFCAPS"; + goto LABEL_182; + case DDERR_OUTOFVIDEOMEMORY: + v3 = "DDERR_OUTOFVIDEOMEMORY"; + goto LABEL_182; + } + } + } + else + { + if ( error_code == DDERR_NOTEXTUREHW ) + { + v3 = "DDERR_NOTEXTUREHW"; + goto LABEL_182; + } + if ( error_code > DDERR_NORASTEROPHW ) + { + switch ( error_code ) + { + case DDERR_NOROTATIONHW: + v3 = "DDERR_NOROTATIONHW"; + goto LABEL_182; + case DDERR_NOSTRETCHHW: + v3 = "DDERR_NOSTRETCHHW"; + goto LABEL_182; + case DDERR_NOT4BITCOLOR: + v3 = "DDERR_NOT4BITCOLOR"; + goto LABEL_182; + case DDERR_NOT4BITCOLORINDEX: + v3 = "DDERR_NOT4BITCOLORINDEX"; + goto LABEL_182; + case DDERR_NOT8BITCOLOR: + v3 = "DDERR_NOT8BITCOLOR"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case DDERR_NORASTEROPHW: + v3 = "DDERR_NORASTEROPHW"; + goto LABEL_182; + case DDERR_NOEXCLUSIVEMODE: + v3 = "DDERR_NOEXCLUSIVEMODE"; + goto LABEL_182; + case DDERR_NOFLIPHW: + v3 = "DDERR_NOFLIPHW"; + goto LABEL_182; + case DDERR_NOGDI: + v3 = "DDERR_NOGDI"; + goto LABEL_182; + case DDERR_NOMIRRORHW: + v3 = "DDERR_NOMIRRORHW"; + goto LABEL_182; + case DDERR_NOTFOUND: + v3 = "DDERR_NOTFOUND"; + goto LABEL_182; + case DDERR_NOOVERLAYHW: + v3 = "DDERR_NOOVERLAYHW"; + goto LABEL_182; + } + } + } + goto LABEL_178; + } + if ( error_code == DDERR_NOCOLORKEYHW ) + { + v3 = "DDERR_NOCOLORKEYHW"; + goto LABEL_182; + } + if ( error_code > DDERR_INVALIDCLIPLIST ) + { + if ( error_code > DDERR_NO3D ) + { + switch ( error_code ) + { + case DDERR_NOALPHAHW: + v3 = "DDERR_NOALPHAHW"; + goto LABEL_182; + case DDERR_NOCLIPLIST: + v3 = "DDERR_NOCLIPLIST"; + goto LABEL_182; + case DDERR_NOCOLORCONVHW: + v3 = "DDERR_NOCOLORCONVHW"; + goto LABEL_182; + case DDERR_NOCOOPERATIVELEVELSET: + v3 = "DDERR_NOCOOPERATIVELEVELSET"; + goto LABEL_182; + case DDERR_NOCOLORKEY: + v3 = "DDERR_NOCOLORKEY"; + goto LABEL_182; + } + } + else + { + switch ( error_code ) + { + case DDERR_NO3D: + v3 = "DDERR_NO3D"; + goto LABEL_182; + case DDERR_INVALIDMODE: + v3 = "DDERR_INVALIDMODE"; + goto LABEL_182; + case DDERR_INVALIDOBJECT: + v3 = "DDERR_INVALIDOBJECT"; + goto LABEL_182; + case DDERR_INVALIDPIXELFORMAT: + v3 = "DDERR_INVALIDPIXELFORMAT"; + goto LABEL_182; + case DDERR_INVALIDRECT: + v3 = "DDERR_INVALIDRECT"; + goto LABEL_182; + case DDERR_LOCKEDSURFACES: + v3 = "DDERR_LOCKEDSURFACES"; + goto LABEL_182; + } + } + goto LABEL_178; + } + if ( error_code == DDERR_INVALIDCLIPLIST ) + { + v3 = "DDERR_INVALIDCLIPLIST"; + goto LABEL_182; + } + if ( error_code > DDERR_CANNOTDETACHSURFACE ) + { + switch ( error_code ) + { + case DDERR_CURRENTLYNOTAVAIL: + v3 = "DDERR_CURRENTLYNOTAVAIL"; + goto LABEL_182; + case DDERR_EXCEPTION: + v3 = "DDERR_EXCEPTION"; + goto LABEL_182; + case DDERR_HEIGHTALIGN: + v3 = "DDERR_HEIGHTALIGN"; + goto LABEL_182; + case DDERR_INCOMPATIBLEPRIMARY: + v3 = "DDERR_INCOMPATIBLEPRIMARY"; + goto LABEL_182; + case DDERR_INVALIDCAPS: + v3 = "DDERR_INVALIDCAPS"; + goto LABEL_182; + } + goto LABEL_178; + } + switch ( error_code ) + { + case DDERR_CANNOTDETACHSURFACE: + v3 = "DDERR_CANNOTDETACHSURFACE"; + goto LABEL_182; + case DDERR_UNSUPPORTED: + v3 = "DDERR_UNSUPPORTED"; + goto LABEL_182; + case DDERR_GENERIC: + v3 = "DDERR_GENERIC"; + goto LABEL_182; + case DDERR_OUTOFMEMORY: + v3 = "DDERR_OUTOFMEMORY"; + goto LABEL_182; + case DDERR_INVALIDPARAMS: + v3 = "DDERR_INVALIDPARAMS"; + goto LABEL_182; + case DDERR_ALREADYINITIALIZED: + v3 = "DDERR_ALREADYINITIALIZED"; + goto LABEL_182; + } + if ( error_code != DDERR_CANNOTATTACHSURFACE ) + { +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 > DSERR_INVALIDCALL ) + { + switch ( error_code ) + { + case DSERR_PRIOLEVELNEEDED: + v3 = "DSERR_PRIOLEVELNEEDED"; + goto LABEL_29; + case DSERR_BADFORMAT: + v3 = "DSERR_BADFORMAT"; + goto LABEL_29; + case DSERR_NODRIVER: + v3 = "DSERR_NODRIVER"; + goto LABEL_29; + case DSERR_ALREADYINITIALIZED: + v3 = "DSERR_ALREADYINITIALIZED"; + goto LABEL_29; + case DSERR_BUFFERLOST: + v3 = "DSERR_BUFFERLOST"; + goto LABEL_29; + case DS_OK: + v3 = "DS_OK"; + goto LABEL_29; + } + goto LABEL_22; + } + switch ( error_code ) + { + case DSERR_INVALIDCALL: + v3 = "DSERR_INVALIDCALL"; + goto LABEL_29; + case E_NOINTERFACE: + v3 = "E_NOINTERFACE"; + goto LABEL_29; + case DSERR_NOAGGREGATION: + v3 = "DSERR_NOAGGREGATION"; + goto LABEL_29; + case DSERR_OUTOFMEMORY: + v3 = "DSERR_OUTOFMEMORY"; + goto LABEL_29; + case DSERR_INVALIDPARAM: + v3 = "DSERR_INVALIDPARAM"; + goto LABEL_29; + case DSERR_ALLOCATED: + v3 = "DSERR_ALLOCATED"; + goto LABEL_29; + } + if ( error_code != DSERR_CONTROLUNAVAIL ) + { +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 *pszFmt, ...) +{ + va_list arglist; // [esp+8h] [ebp+8h] + + va_start(arglist, pszFmt); + FreeDlg(); + if ( pszFmt ) + MsgBox(pszFmt, arglist); + init_cleanup(0); + exit(1); +} + +//----- (00401975) -------------------------------------------------------- +void __fastcall MsgBox(char *pszFmt, va_list va) +{ + char Text[256]; // [esp+0h] [ebp-100h] + + wvsprintfA(Text, pszFmt, va); + if ( ghMainWnd ) + SetWindowPos(ghMainWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE); + MessageBoxA(ghMainWnd, Text, "ERROR", MB_TASKMODAL|MB_ICONHAND); +} + +//----- (004019C7) -------------------------------------------------------- +void __cdecl 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); +} +// 4B7A34: using guessed type int terminating; +// 4B7A38: using guessed type int cleanup_thread_id; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00401A30) -------------------------------------------------------- +void DrawDlg(char *pszFmt, ...) +{ + char text[256]; // [esp+0h] [ebp-100h] + va_list arglist; // [esp+10Ch] [ebp+Ch] + + va_start(arglist, pszFmt); + wvsprintfA(text, pszFmt, arglist); + SDrawMessageBox(text, "Diablo", MB_TASKMODAL|MB_ICONEXCLAMATION); +} + +//----- (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, HORZRES); + v3 = GetDeviceCaps(hdc, VERTRES); + ReleaseDC(hWnd, hdc); + if ( !SetWindowPos(hWnd, HWND_TOP, (v6 - v1) / 2, (v3 - v2) / 2, 0, 0, SWP_NOZORDER|SWP_NOSIZE) ) + { + 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, '\\'); + if ( v7 ) + v6 = v7 + 1; + v8 = GetErr(v4); + wsprintfA((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v6, log_line_nr); + if ( DialogBoxParamA(ghInst, (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 == 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; +} + +//----- (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, '\\'); + if ( v7 ) + v4 = v7 + 1; + v8 = GetErr(v5); + wsprintfA((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v4, log_line_nr); + DialogBoxParamA(ghInst, (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(ghInst, (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(ghInst, (LPCSTR)0x6E, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + TermMsg("DiskFreeDlg"); + TermMsg(0); +} + +//----- (00401D1D) -------------------------------------------------------- +bool __cdecl InsertCDDlg() +{ + INT_PTR v0; // edi + + ShowCursor(1); + v0 = DialogBoxParamA(ghInst, (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(ghInst, (LPCSTR)0x72, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) + TermMsg("DirErrorDlg"); + TermMsg(0); +} diff --git a/Source/appfat.h b/Source/appfat.h new file mode 100644 index 0000000..f9b3381 --- /dev/null +++ b/Source/appfat.h @@ -0,0 +1,37 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//appfat +extern int appfat_terminated; // weak +extern char sz_error_buf[256]; +extern int terminating; // weak +extern int cleanup_thread_id; // weak +extern char empty_string; + +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 *pszFmt, ...); +void __fastcall MsgBox(char *pszFmt, va_list va); +void __cdecl FreeDlg(); +void DrawDlg(char *pszFmt, ...); +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); diff --git a/Source/automap.cpp b/Source/automap.cpp new file mode 100644 index 0000000..286c630 --- /dev/null +++ b/Source/automap.cpp @@ -0,0 +1,993 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +short automaptype[512]; +int AMdword_4B7E40; // weak +int AMdword_4B7E44; // weak +bool automapflag; // idb +char AMbyte_4B7E4C[32]; +char automapview[40][40]; +int AutoMapScale; // idb +int AutoMapXOfs; // weak +int AutoMapYOfs; // weak +int AutoMapPosBits; // weak +int AutoMapXPos; // weak +int AutoMapYPos; // weak +int AMPlayerX; // weak +int AMPlayerY; // weak + +//----- (00401DA4) -------------------------------------------------------- +void __cdecl InitAutomapOnce() +{ + automapflag = 0; + AutoMapScale = 50; + AutoMapPosBits = 32; + AutoMapXPos = 16; + AutoMapYPos = 8; + AMPlayerX = 4; + AMPlayerY = 2; +} +// 4B84B8: using guessed type int AutoMapPosBits; +// 4B84BC: using guessed type int AutoMapXPos; +// 4B84C0: using guessed type int AutoMapYPos; +// 4B84C4: using guessed type int AMPlayerX; +// 4B84C8: using guessed type int AMPlayerY; + +//----- (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; + 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; + AutoMapPosBits = (AutoMapScale << 6) / 100; + AutoMapXPos = AutoMapPosBits >> 1; + AutoMapYPos = AutoMapPosBits >> 2; + AMPlayerX = AutoMapPosBits >> 3; + AMPlayerY = AutoMapPosBits >> 4; + } +} +// 4B84B8: using guessed type int AutoMapPosBits; +// 4B84BC: using guessed type int AutoMapXPos; +// 4B84C0: using guessed type int AutoMapYPos; +// 4B84C4: using guessed type int AMPlayerX; +// 4B84C8: using guessed type int AMPlayerY; + +//----- (00401F80) -------------------------------------------------------- +void __cdecl AutomapZoomOut() +{ + if ( AutoMapScale > 50 ) + { + AutoMapScale -= 5; + AutoMapPosBits = (AutoMapScale << 6) / 100; + AutoMapXPos = AutoMapPosBits >> 1; + AutoMapYPos = AutoMapPosBits >> 2; + AMPlayerX = AutoMapPosBits >> 3; + AMPlayerY = AutoMapPosBits >> 4; + } +} +// 4B84B8: using guessed type int AutoMapPosBits; +// 4B84BC: using guessed type int AutoMapXPos; +// 4B84C0: using guessed type int AutoMapYPos; +// 4B84C4: using guessed type int AMPlayerX; +// 4B84C8: using guessed type int AMPlayerY; + +//----- (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 - AutoMapPosBits * ((v10 - 1) >> 1); + v12 = 336 - AutoMapXPos * ((v10 + 1) >> 1); + } + else + { + v11 = AutoMapXPos - AutoMapPosBits * (v10 >> 1) + 384; + v12 = 336 - AutoMapXPos * (v10 >> 1) - AutoMapYPos; + } + if ( ViewX & 1 ) + { + v11 -= AutoMapYPos; + v12 -= AMPlayerX; + } + if ( ViewY & 1 ) + { + v11 += AutoMapYPos; + v12 -= AMPlayerX; + } + 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 += AutoMapPosBits; + ++v15; + --ty; + } + while ( v15 < v10 ); + } + ++v19; + screen_xa = 0; + v17 = v13 - AutoMapXPos; + screen_y = v14 + AutoMapYPos; + if ( v10 >= 0 ) + { + tya = v19; + do + { + v18 = GetAutomapType(v22 + screen_xa, tya, 1); + if ( v18 ) + DrawAutomapType(v17, screen_y, v18); + v17 += AutoMapPosBits; + ++screen_xa; + --tya; + } + while ( screen_xa <= v10 ); + } + ++v22; + v14 += AutoMapXPos; + --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 AutoMapPosBits; +// 4B84BC: using guessed type int AutoMapXPos; +// 4B84C0: using guessed type int AutoMapYPos; +// 4B84C4: using guessed type int AMPlayerX; +// 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) +{ + short 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 - AMPlayerX, v5 - AMPlayerY, 200); + ENG_set_pixel(v4 - AMPlayerX, AMPlayerY + v5, 200); + ENG_set_pixel(AMPlayerX + v4, v5 - AMPlayerY, 200); + ENG_set_pixel(AMPlayerX + v4, AMPlayerY + v5, 200); + ENG_set_pixel(v4 - AutoMapYPos, v5, 200); + ENG_set_pixel(AutoMapYPos + v4, v5, 200); + ENG_set_pixel(v4, v5 - AMPlayerX, 200); + ENG_set_pixel(v4, AMPlayerX + v5, 200); + ENG_set_pixel(v4 + AMPlayerX - AutoMapXPos, AMPlayerY + v5, 200); + ENG_set_pixel(v4 + AutoMapXPos - AMPlayerX, AMPlayerY + v5, 200); + ENG_set_pixel(v4 - AutoMapYPos, AMPlayerX + v5, 200); + ENG_set_pixel(AutoMapYPos + v4, AMPlayerX + v5, 200); + ENG_set_pixel(v4 - AMPlayerX, v5 + AutoMapYPos - AMPlayerY, 200); + ENG_set_pixel(AMPlayerX + v4, v5 + AutoMapYPos - AMPlayerY, 200); + ENG_set_pixel(v4, AutoMapYPos + v5, 200); + v3 = automap_type; + } + if ( automap_type < 0 ) + { + engine_draw_automap_pixels(v4 - AMPlayerX, v5 - AMPlayerX - AMPlayerY, v4 + AMPlayerX + AutoMapYPos, AMPlayerY + v5, 144); + engine_draw_automap_pixels(v4 - AutoMapYPos, v5 - AMPlayerX, AutoMapYPos + v4, AMPlayerX + v5, 144); + engine_draw_automap_pixels(v4 - AutoMapYPos - AMPlayerX, v5 - AMPlayerY, AMPlayerX + v4, v5 + AMPlayerX + AMPlayerY, 144); + engine_draw_automap_pixels(v4 - AutoMapXPos, v5, v4, v5 + AutoMapYPos, 144); + v3 = automap_type; + } + v31 = 0; + v30 = 0; + v32 = 0; + switch ( v3 & 0xF ) + { + case 1: + a3 = v4 - AutoMapYPos + AutoMapXPos; + a1 = v4 - AutoMapYPos; + a2 = v5 - AutoMapYPos; + automap_typea = v5 - AMPlayerX; + engine_draw_automap_pixels(v4, v5 - AutoMapYPos, v4 - AutoMapYPos, v5 - AMPlayerX, 200); + engine_draw_automap_pixels(v4, a2, a3, automap_typea, 200); + engine_draw_automap_pixels(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 - AutoMapXPos; + v11 = v4 - AutoMapYPos; + v12 = v5 - AutoMapYPos; + automap_typeb = v5 - AMPlayerX; + engine_draw_automap_pixels(v4, v5 - AutoMapYPos, v4 - AMPlayerX, v5 - AutoMapYPos + AMPlayerY, 200); + engine_draw_automap_pixels(v10, v5, v10 + AMPlayerX, v5 - AMPlayerY, 200); + engine_draw_automap_pixels(v11, v12, v10, automap_typeb, 144); + engine_draw_automap_pixels(v11, v12, v4, automap_typeb, 144); + engine_draw_automap_pixels(v11, v5, v10, automap_typeb, 144); + engine_draw_automap_pixels(v11, v5, v4, automap_typeb, 144); + } + if ( v33 & 0x10 ) + { + engine_draw_automap_pixels(v4 - AutoMapYPos, v5 - AMPlayerX, v4 - AutoMapXPos, v5, 200); + v33 |= 4u; + } + if ( v33 & 4 ) + { + v13 = v4 - AutoMapYPos + AutoMapXPos; + v14 = v4 - AutoMapYPos; + v15 = v5 - AutoMapYPos; + automap_typec = v5 - AMPlayerX; + engine_draw_automap_pixels(v4, v5 - AutoMapYPos, v4 - AutoMapYPos, v5 - AMPlayerX, 200); + engine_draw_automap_pixels(v4, v15, v13, automap_typec, 200); + engine_draw_automap_pixels(v4, v5, v14, automap_typec, 200); + engine_draw_automap_pixels(v4, v5, v13, automap_typec, 200); + } + if ( !(v33 & 0x15) ) + engine_draw_automap_pixels(v4, v5 - AutoMapYPos, v4 - AutoMapXPos, v5, 200); + if ( v31 ) + goto LABEL_17; + goto LABEL_25; + case 9: + v32 = 1; +LABEL_17: + if ( v33 & 2 ) + { + v16 = AutoMapYPos + v4; + v17 = v5 - AutoMapYPos; + v18 = v4 + AutoMapXPos; + automap_typed = v5 - AMPlayerX; + engine_draw_automap_pixels(v4, v5 - AutoMapYPos, v4 + AMPlayerX, v5 - AutoMapYPos + AMPlayerY, 200); + engine_draw_automap_pixels(v18, v5, v18 - AMPlayerX, v5 - AMPlayerY, 200); + engine_draw_automap_pixels(v16, v17, v4, automap_typed, 144); + engine_draw_automap_pixels(v16, v17, v18, automap_typed, 144); + engine_draw_automap_pixels(v16, v5, v4, automap_typed, 144); + engine_draw_automap_pixels(v16, v5, v18, automap_typed, 144); + } + if ( v33 & 0x20 ) + { + engine_draw_automap_pixels(AutoMapYPos + v4, v5 - AMPlayerX, v4 + AutoMapXPos, v5, 200); + v33 |= 8u; + } + if ( v33 & 8 ) + { + v19 = v4 - AutoMapYPos + AutoMapXPos; + v20 = v4 - AutoMapYPos; + v21 = v5 - AutoMapYPos; + automap_typee = v5 - AMPlayerX; + engine_draw_automap_pixels(v4, v5 - AutoMapYPos, v4 - AutoMapYPos, v5 - AMPlayerX, 200); + engine_draw_automap_pixels(v4, v21, v19, automap_typee, 200); + engine_draw_automap_pixels(v4, v5, v20, automap_typee, 200); + engine_draw_automap_pixels(v4, v5, v19, automap_typee, 200); + } + if ( !(v33 & 0x2A) ) + engine_draw_automap_pixels(v4, v5 - AutoMapYPos, v4 + AutoMapXPos, 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 - AutoMapXPos; + v23 = v4 - AutoMapYPos; + v24 = AutoMapYPos + v5; + automap_typef = AMPlayerX + v5; + engine_draw_automap_pixels(v4, AutoMapYPos + v5, v4 - AMPlayerX, AutoMapYPos + v5 - AMPlayerY, 200); + engine_draw_automap_pixels(v22, v5, v22 + AMPlayerX, v5 + AMPlayerY, 200); + engine_draw_automap_pixels(v23, v24, v22, automap_typef, 144); + engine_draw_automap_pixels(v23, v24, v4, automap_typef, 144); + engine_draw_automap_pixels(v23, v5, v22, automap_typef, 144); + engine_draw_automap_pixels(v23, v5, v4, automap_typef, 144); + } + else + { + engine_draw_automap_pixels(v4, AutoMapYPos + v5, v4 - AutoMapXPos, v5, 200); + } +LABEL_32: + if ( v32 ) + { +LABEL_33: + if ( v33 & 2 ) + { + v25 = AutoMapYPos + v4; + v26 = AutoMapYPos + v5; + v27 = v4 + AutoMapXPos; + automap_typeg = AMPlayerX + v5; + engine_draw_automap_pixels(v4, AutoMapYPos + v5, v4 + AMPlayerX, AutoMapYPos + v5 - AMPlayerY, 200); + engine_draw_automap_pixels(v27, v5, v27 - AMPlayerX, v5 + AMPlayerY, 200); + engine_draw_automap_pixels(v25, v26, v4, automap_typeg, 144); + engine_draw_automap_pixels(v25, v26, v27, automap_typeg, 144); + engine_draw_automap_pixels(v25, v5, v4, automap_typeg, 144); + engine_draw_automap_pixels(v25, v5, v27, automap_typeg, 144); + } + else + { + v29 = v5; + v28 = v4 + AutoMapXPos; + v9 = AutoMapYPos + v5; +LABEL_36: + engine_draw_automap_pixels(v4, v9, v28, v29, 200); + } + } + break; + default: + return; + } +} +// 4B84BC: using guessed type int AutoMapXPos; +// 4B84C0: using guessed type int AutoMapYPos; +// 4B84C4: using guessed type int AMPlayerX; +// 4B84C8: using guessed type int AMPlayerY; + +//----- (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) + + AutoMapYPos * (v11 - v12) + + 384; + if ( invflag || sbookflag ) + v3 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pxoff / 100 >> 1) + + AutoMapYPos * (v11 - v12) + + 224; + if ( chrflag || questlog ) + v3 += 160; + v4 = AMPlayerX * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336 + - AMPlayerX; + switch ( plr[v0]._pdir ) + { + case DIR_S: + engine_draw_automap_pixels(v3, v4, v3, v4 + AutoMapYPos, 153); + engine_draw_automap_pixels(v3, AutoMapYPos + v4, v3 + AMPlayerY, v4 + AMPlayerX, 153); + v10 = v4 + AMPlayerX; + v9 = v3 - AMPlayerY; + v5 = AutoMapYPos + v4; + goto LABEL_19; + case DIR_SW: + engine_draw_automap_pixels( + v3, + AMPlayerX * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336 + - AMPlayerX, + v3 - AutoMapYPos, + AMPlayerX * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336, + 153); + engine_draw_automap_pixels(v3 - AutoMapYPos, AMPlayerX + v4, v3 - AMPlayerY - AMPlayerX, v4, 153); + v7 = AMPlayerX; + v8 = v3; + v5 = AMPlayerX + v4; + v10 = AMPlayerX + v4; + goto LABEL_23; + case DIR_W: + engine_draw_automap_pixels(v3, v4, v3 - AutoMapYPos, v4, 153); + engine_draw_automap_pixels(v3 - AutoMapYPos, v4, v3 - AMPlayerX, v4 - AMPlayerY, 153); + v5 = v4; + v10 = v4 + AMPlayerY; + v9 = v3 - AMPlayerX; + goto LABEL_24; + case DIR_NW: + engine_draw_automap_pixels(v3, v4, v3 - AutoMapYPos, v4 - AMPlayerX, 153); + engine_draw_automap_pixels(v3 - AutoMapYPos, v4 - AMPlayerX, v3 - AMPlayerX, v4 - AMPlayerX, 153); + v7 = AMPlayerX; + v8 = v3 - AMPlayerY; + v10 = v4; + v5 = v4 - AMPlayerX; +LABEL_23: + v9 = v8 - v7; +LABEL_24: + v6 = v3 - AutoMapYPos; + goto LABEL_25; + case DIR_N: + engine_draw_automap_pixels(v3, v4, v3, v4 - AutoMapYPos, 153); + engine_draw_automap_pixels(v3, v4 - AutoMapYPos, v3 - AMPlayerY, v4 - AMPlayerX, 153); + v10 = v4 - AMPlayerX; + v5 = v4 - AutoMapYPos; + v9 = v3 + AMPlayerY; +LABEL_19: + v6 = v3; + goto LABEL_25; + case DIR_NE: + engine_draw_automap_pixels(v3, v4, v3 + AutoMapYPos, v4 - AMPlayerX, 153); + engine_draw_automap_pixels(AutoMapYPos + v3, v4 - AMPlayerX, v3 + AMPlayerX, v4 - AMPlayerX, 153); + v10 = v4; + v9 = v3 + AMPlayerX + AMPlayerY; + v5 = v4 - AMPlayerX; + goto LABEL_17; + case DIR_E: + engine_draw_automap_pixels(v3, v4, v3 + AutoMapYPos, v4, 153); + engine_draw_automap_pixels(AutoMapYPos + v3, v4, v3 + AMPlayerX, v4 - AMPlayerY, 153); + engine_draw_automap_pixels(AutoMapYPos + v3, v4, v3 + AMPlayerX, v4 + AMPlayerY, 153); + break; + case DIR_SE: + engine_draw_automap_pixels( + v3, + AMPlayerX * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336 + - AMPlayerX, + v3 + AutoMapYPos, + AMPlayerX * (v12 + v11) + + (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + + (AutoMapScale * plr[v0]._pyoff / 100 >> 1) + + 336, + 153); + engine_draw_automap_pixels(AutoMapYPos + v3, AMPlayerX + v4, v3 + AMPlayerX + AMPlayerY, v4, 153); + v5 = AMPlayerX + v4; + v10 = AMPlayerX + v4; + v9 = v3 + AMPlayerX; +LABEL_17: + v6 = AutoMapYPos + v3; +LABEL_25: + engine_draw_automap_pixels(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 AutoMapYPos; +// 4B84C4: using guessed type int AMPlayerX; +// 4B84C8: using guessed type int AMPlayerY; +// 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) == 0x4007 ) + 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 == 0x4007 ) + automapview[1][v4] = 1; + return; + } +LABEL_14: + if ( GetAutomapType(v2, v3 - 1, 0) & 0x4000 ) + automapview[0][v4 - 1] = 1; // 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 ) + automapview[-1][v4] = 1; // *((_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 ) + automapview[0][v4 - 1] = 1; // AMbyte_4B7E4C[v4 + 31] = 1; + goto LABEL_19; + } +LABEL_35: + if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 ) + automapview[-1][v4] = 1; // *((_BYTE *)&AMdword_4B7E44 + v4) = 1; + return; + } + if ( v6 ) + { + if ( GetAutomapType(v2, v3 + 1, 0) == 0x4007 ) + automapview[0][v4 + 1] = 1; + goto LABEL_13; + } + if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 ) + automapview[-1][v4] = 1; // *((_BYTE *)&AMdword_4B7E44 + v4) = 1; + v12 = v3 - 1; + if ( GetAutomapType(v2, v12, 0) & 0x4000 ) + automapview[0][v4 - 1] = 1; // AMbyte_4B7E4C[v4 + 31] = 1; + if ( GetAutomapType(v2 - 1, v12, 0) & 0x4000 ) + automapview[-1][v4 - 1] = 1; /* *((_BYTE *)&AMdword_4B7E40 + v4 + 3) = 1; fix */ +} +// 4B7E40: using guessed type int AMdword_4B7E40; +// 4B7E44: using guessed type int AMdword_4B7E44; + +//----- (004030DD) -------------------------------------------------------- +void __cdecl AutomapZoomReset() +{ + AutoMapXOfs = 0; + AutoMapYOfs = 0; + AutoMapPosBits = (AutoMapScale << 6) / 100; + AutoMapXPos = AutoMapPosBits >> 1; + AutoMapYPos = AutoMapPosBits >> 2; + AMPlayerX = AutoMapPosBits >> 3; + AMPlayerY = AutoMapPosBits >> 4; +} +// 4B84B0: using guessed type int AutoMapXOfs; +// 4B84B4: using guessed type int AutoMapYOfs; +// 4B84B8: using guessed type int AutoMapPosBits; +// 4B84BC: using guessed type int AutoMapXPos; +// 4B84C0: using guessed type int AutoMapYPos; +// 4B84C4: using guessed type int AMPlayerX; +// 4B84C8: using guessed type int AMPlayerY; diff --git a/Source/automap.h b/Source/automap.h new file mode 100644 index 0000000..0eafd35 --- /dev/null +++ b/Source/automap.h @@ -0,0 +1,43 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//automap +extern short automaptype[512]; +extern int AMdword_4B7E40; // weak +extern int AMdword_4B7E44; // weak +extern bool automapflag; // idb +extern char AMbyte_4B7E4C[32]; +extern char automapview[40][40]; +extern int AutoMapScale; // idb +extern int AutoMapXOfs; // weak +extern int AutoMapYOfs; // weak +extern int AutoMapPosBits; // weak +extern int AutoMapXPos; // weak +extern int AutoMapYPos; // weak +extern int AMPlayerX; // weak +extern int AMPlayerY; // weak + +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(); \ No newline at end of file diff --git a/Source/capture.cpp b/Source/capture.cpp new file mode 100644 index 0000000..6d78e36 --- /dev/null +++ b/Source/capture.cpp @@ -0,0 +1,219 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +//----- (0040311B) -------------------------------------------------------- +void __cdecl CaptureScreen() +{ + int v4; // edi + PALETTEENTRY palette[256]; // [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(lpDDPalette, 0, 0, 256, palette); + RedPalette(palette); + dx_lock_mutex(); + v4 = CaptureHdr(hObject, 640, 480); + if ( v4 ) + { + v4 = CapturePix(hObject, 640, 480, 768, gpBuffer->row[0].pixels); + if ( v4 ) + { + v4 = CapturePal(hObject, palette); + } + } + dx_unlock_mutex(); + CloseHandle(hObject); + if ( !v4 ) + DeleteFileA(FileName); + Sleep(300); + IDirectDrawPalette_SetEntries(lpDDPalette, 0, 0, 256, 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 + PCXHeader Buffer; // [esp+Ch] [ebp-84h] + DWORD lpNumBytes; // [esp+8Ch] [ebp-4h] + + v3 = width; + v4 = hFile; + memset(&Buffer, 0, 0x80u); + Buffer.xmax = v3 - 1; + Buffer.vertRes = height; + Buffer.manufacturer = 10; + Buffer.version = 5; + Buffer.encoding = 1; + Buffer.bitsPerPixel = 8; + Buffer.ymax = height - 1; + Buffer.horzRes = v3; + Buffer.numColorPlanes = 1; + Buffer.bytesPerScanLine = v3; + return WriteFile(v4, &Buffer, 0x80u, &lpNumBytes, NULL) && lpNumBytes == 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 lpNumBytes; // [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, &lpNumBytes, 0) && lpNumBytes == 769; +} + +//----- (004032FD) -------------------------------------------------------- +bool __fastcall CapturePix(HANDLE hFile, short width, short height, short stride, char *pixels) +{ + int v5; // esi + char *v6; // edi + char *v7; // eax + int v8; // ebx + DWORD lpNumBytes; // [esp+Ch] [ebp-8h] + HANDLE hFilea; // [esp+10h] [ebp-4h] + + v5 = (unsigned short)width; + hFilea = hFile; + v6 = (char *)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, &lpNumBytes, 0) && lpNumBytes == v8 ); + return 0; +} + +//----- (0040336A) -------------------------------------------------------- +char *__fastcall CaptureEnc(char *src, char *dst, int width) +{ + int v3; // esi + 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 ( (unsigned char)v4 > 0xBFu ) +LABEL_13: + *dst++ = v5 | 0xC0; + *dst++ = v4; + } + while ( v3 ); + return 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, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); +} +// 4033A8: using guessed type char var_64[100]; + +//----- (00403470) -------------------------------------------------------- +void __fastcall RedPalette(PALETTEENTRY *pal) +{ + int i; // eax + PALETTEENTRY red[256]; // [esp+Ch] [ebp-400h] + + for(i = 0; i < 256; i++) + { + red[i].peRed = pal[i].peRed; + red[i].peGreen = 0; + red[i].peBlue = 0; + red[i].peFlags = 0; + } + + IDirectDrawPalette_SetEntries(lpDDPalette, 0, 0, 256, red); +} diff --git a/Source/capture.h b/Source/capture.h new file mode 100644 index 0000000..5702712 --- /dev/null +++ b/Source/capture.h @@ -0,0 +1,18 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +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, char *dst, int width); +HANDLE __fastcall CaptureFile(char *dst_path); +void __fastcall RedPalette(PALETTEENTRY *pal); \ No newline at end of file diff --git a/Source/codec.cpp b/Source/codec.cpp new file mode 100644 index 0000000..51cc2b2 --- /dev/null +++ b/Source/codec.cpp @@ -0,0 +1,199 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +//----- (004034D9) -------------------------------------------------------- +int __fastcall codec_decode(void *pbSrcDst, int size, char *pszPassword) +{ + 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 *)pbSrcDst; + codec_init_key(0, pszPassword); + 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); + SHA1Result(0, dst); + v7 = 0; + do + { + v9[v7] ^= dst[v7 % 20]; + ++v7; + } + while ( v7 < 64 ); + SHA1Calculate(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] ) + { + SHA1Result(0, dst); + if ( *(_DWORD *)v4 == *(_DWORD *)dst ) + { + v8 = v5 + (unsigned char)v4[5] - 64; + goto LABEL_14; + } + memset(dst, 0, 0x14u); + } + v8 = 0; +LABEL_14: + SHA1Clear(); + return v8; +} +// 4034D9: using guessed type char var_98[128]; + +//----- (004035DB) -------------------------------------------------------- +void __fastcall codec_init_key(int unused, char *pszPassword) +{ + 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[136]; // [esp+Ch] [ebp-E0h] + char v10[64]; // [esp+94h] [ebp-58h] + char dst[20]; // [esp+D4h] [ebp-18h] + int v12; // [esp+E8h] [ebp-4h] + + v2 = pszPassword; + srand(0x7058u); + v3 = v9; + v12 = 136; + do + { + *v3++ = rand(); + --v12; + } + while ( v12 ); + v4 = 0; + v5 = 0; + do + { + if ( !v2[v4] ) + v4 = 0; + v6 = v2[v4++]; + v10[v5++] = v6; + } + while ( v5 < 64 ); + SHA1Reset(0); + SHA1Calculate(0, v10, dst); + SHA1Clear(); + v7 = 0; + do + { + v9[v7] ^= dst[(signed int)v7 % 20]; + ++v7; + } + while ( v7 < 0x88 ); + memset(v10, 0, 0x40u); + memset(dst, 0, 0x14u); + v8 = 0; + do + { + SHA1Reset(v8); + SHA1Calculate(v8++, &v9[72], 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 dwSrcBytes) +{ + if ( dwSrcBytes & 0x3F ) + dwSrcBytes += 64 - (dwSrcBytes & 0x3F); + return dwSrcBytes + 8; +} + +//----- (004036BE) -------------------------------------------------------- +void __fastcall codec_encode(void *pbSrcDst, int size, int size_64, char *pszPassword) +{ + char *v4; // esi + char v5; // bl + size_t v6; // edi + signed int v7; // ecx + 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 *)pbSrcDst; + v12 = size; + if ( size_64 != codec_get_encoded_len(size) ) + TermMsg("Invalid encode parameters"); + codec_init_key(1, pszPassword); + 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); + SHA1Result(0, dst); + SHA1Calculate(0, v9, 0); + v7 = 0; + do + { + v9[v7] ^= dst[v7 % 20]; + ++v7; + } + while ( v7 < 64 ); + memset(dst, 0, 0x14u); + memcpy(v4, v9, 0x40u); + v4 += 64; + v12 -= v6; + } + while ( v12 ); + v5 = v6; + } + memset(v9, 0, 0x80u); + SHA1Result(0, v10); + v4[4] = 0; + *((_WORD *)v4 + 3) = 0; + *(_DWORD *)v4 = *(_DWORD *)v10; + v4[5] = v5; + SHA1Clear(); +} +// 4036BE: using guessed type char var_AC[128]; +// 4036BE: using guessed type char dst[20]; diff --git a/Source/codec.h b/Source/codec.h new file mode 100644 index 0000000..12f4bff --- /dev/null +++ b/Source/codec.h @@ -0,0 +1,15 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +int __fastcall codec_decode(void *pbSrcDst, int size, char *pszPassword); +void __fastcall codec_init_key(int unused, char *pszPassword); +int __fastcall codec_get_encoded_len(int dwSrcBytes); +void __fastcall codec_encode(void *pbSrcDst, int size, int size_64, char *pszPassword); \ No newline at end of file diff --git a/Source/control.cpp b/Source/control.cpp new file mode 100644 index 0000000..6fe39f5 --- /dev/null +++ b/Source/control.cpp @@ -0,0 +1,3503 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +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 // should be char [4] +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 + +unsigned char fontframe[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, 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 +}; +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 +}; +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] = +{ + 0, 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, 1, + 1, 1, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 1, 67, 117, + 101, 97, 97, 97, 97, 99, 101, 101, 101, 105, + 105, 105, 65, 65, 69, 97, 65, 111, 111, 111, + 117, 117, 121, 79, 85, 99, 76, 89, 80, 102, + 97, 105, 111, 117, 110, 78, 97, 111, 63, 1, + 1, 1, 1, 33, 60, 62, 111, 43, 50, 51, + 39, 117, 80, 46, 44, 49, 48, 62, 1, 1, + 1, 63, 65, 65, 65, 65, 65, 65, 65, 67, + 69, 69, 69, 69, 73, 73, 73, 73, 68, 78, + 79, 79, 79, 79, 79, 88, 48, 85, 85, 85, + 85, 89, 98, 66, 97, 97, 97, 97, 97, 97, + 97, 99, 101, 101, 101, 101, 105, 105, 105, 105, + 111, 110, 111, 111, 111, 111, 111, 47, 48, 117, + 117, 117, 117, 121, 98, 121 +}; + +/* rdata */ + +unsigned 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" +}; +RECT32 attribute_inc_rects[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 } +}; + +//----- (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] + int _EAX; + char *_EBX; + + 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 ) + { + _EAX = *v6++; + ASM_XLAT(_EAX,_EBX); + *v7++ = _EAX; + if ( !v11 ) + continue; + } + v14 = v11 & 1; + v15 = v11 >> 1; + if ( !v14 ) + goto LABEL_15; + _EAX = *(_WORD *)v6; + v6 += 2; + ASM_XLAT(_EAX,_EBX); + _EAX = __ROR2__(_EAX, 8); + ASM_XLAT(_EAX,_EBX); + *(_WORD *)v7 = __ROR2__(_EAX, 8); + v7 += 2; + if ( v15 ) + { +LABEL_15: + do + { + _EAX = *(_DWORD *)v6; + v6 += 4; + ASM_XLAT(_EAX,_EBX); + _EAX = __ROR4__(_EAX, 8); + ASM_XLAT(_EAX,_EBX); + _EAX = __ROR4__(_EAX, 8); + ASM_XLAT(_EAX,_EBX); + _EAX = __ROR4__(_EAX, 8); + ASM_XLAT(_EAX,_EBX); + *(_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 + 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 ) + { + if ( !CheckSpell(myplr, v1, 1, 1) ) + 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)&spelldata[37].sTownSpell ); + 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; + drawpanflag = 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 drawpanflag; + +//----- (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 = plr[myplr]._pSplHotKey[slot]; /* check */ + } + } + 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)) ) + { + drawpanflag = 255; + plr[v3]._pRSpell = v12; + _LOBYTE(plr[v3]._pRSplType) = *v11; + } + } +} +// 52571C: using guessed type int drawpanflag; + +//----- (004040DA) -------------------------------------------------------- +void __fastcall CPrintString(int No, unsigned char pszStr, int Just) +{ + int *v3; // ebx + char *v4; // esi + char *v5; // edi + int v6; // ebx + signed int v7; // edx + unsigned int v8; // eax + unsigned int v9; // ecx + char v10; // cf + unsigned int v11; // ecx + signed int v12; // edx + int v13; // eax + int v14; // ecx + char v15; // al + signed int v16; // edx + int v17; // eax + int v18; // ecx + char v19; // al + signed int v20; // edx + int v21; // eax + int v22; // ecx + char v23; // al + + v3 = (int *)((char *)pPanelText + 4 * 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 ) + { + v13 = (unsigned char)*v4++; + if ( (v13 & 0x80u) == 0 ) + break; + _LOBYTE(v13) = -(char)v13; + v5 += v13; + v12 -= v13; + if ( !v12 ) + goto LABEL_28; + } + v12 -= v13; + v14 = v13; + do + { + v15 = *v4++; + if ( (unsigned char)v15 > 0xFDu ) + { + v15 = -65; + } + else if ( (unsigned char)v15 >= 0xF0u ) + { + v15 -= 62; + } + *v5++ = v15; + --v14; + } + while ( v14 ); + } + while ( v12 ); +LABEL_28: + v5 -= 781; + } + while ( (char *)v6 != v4 ); + } + else if ( (unsigned char)Just == 2 ) + { + do + { + v16 = 13; + do + { + while ( 1 ) + { + v17 = (unsigned char)*v4++; + if ( (v17 & 0x80u) == 0 ) + break; + _LOBYTE(v17) = -(char)v17; + v5 += v17; + v16 -= v17; + if ( !v16 ) + goto LABEL_39; + } + v16 -= v17; + v18 = v17; + do + { + v19 = *v4++; + if ( (unsigned char)v19 >= 0xF0u ) + v19 -= 16; + *v5++ = v19; + --v18; + } + while ( v18 ); + } + while ( v16 ); +LABEL_39: + v5 -= 781; + } + while ( (char *)v6 != v4 ); + } + else + { + do + { + v20 = 13; + do + { + while ( 1 ) + { + v21 = (unsigned char)*v4++; + if ( (v21 & 0x80u) == 0 ) + break; + _LOBYTE(v21) = -(char)v21; + v5 += v21; + v20 -= v21; + if ( !v20 ) + goto LABEL_52; + } + v20 -= v21; + v22 = v21; + do + { + v23 = *v4++; + if ( (unsigned char)v23 >= 0xF0u ) + { + if ( (unsigned char)v23 >= 0xFEu ) + v23 = -49; + else + v23 -= 46; + } + *v5++ = v23; + --v22; + } + while ( v22 ); + } + while ( v20 ); +LABEL_52: + v5 -= 781; + } + while ( (char *)v6 != v4 ); + } + } + else + { + do + { + v7 = 13; + do + { + while ( 1 ) + { + v8 = (unsigned char)*v4++; + if ( (v8 & 0x80u) == 0 ) + break; + _LOBYTE(v8) = -(char)v8; + v5 += v8; + v7 -= v8; + if ( !v7 ) + goto LABEL_15; + } + v7 -= v8; + v9 = v8 >> 1; + if ( v8 & 1 ) + { + *v5++ = *v4++; + if ( !v9 ) + continue; + } + v10 = v9 & 1; + v11 = v8 >> 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 ); + } +} + +//----- (00404218) -------------------------------------------------------- +void __fastcall AddPanelString(char *str, int just) +{ + strcpy(&panelstr[64 * pnumlines], str); + pstrjust[pnumlines] = just; + + if ( pnumlines < 4 ) + pnumlines++; +} + +//----- (0040424A) -------------------------------------------------------- +void __cdecl ClearPanel() +{ + pnumlines = 0; + pinfoflag = 0; +} +// 4B8824: using guessed type int pinfoflag; + +//----- (00404259) -------------------------------------------------------- +void __fastcall DrawPanelBox(int x, int y, int w, int h, int sx, int sy) +{ + char *v6; // esi + char *v7; // edi + int v8; // edx + unsigned int v9; // ecx + char v10; // cf + unsigned int v11; // ecx + + v6 = (char *)pBtmBuff + 640 * y + x; + v7 = &gpBuffer->row_unused_1[sy].col_unused_1[sx]; + v8 = h; + do + { + v9 = w >> 1; + if ( !(w & 1) || (*v7 = *v6, ++v6, ++v7, v9) ) + { + v10 = v9 & 1; + v11 = w >> 2; + if ( !v10 || (*(_WORD *)v7 = *(_WORD *)v6, v6 += 2, v7 += 2, v11) ) + { + qmemcpy(v7, v6, 4 * v11); + v6 += 4 * v11; + v7 += 4 * v11; + } + } + v6 = &v6[-w + 640]; + v7 = &v7[-w + 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); + CelDecodeRect((char *)pBtmBuff, 0, 143, 640, (char *)pStatusPanel, 1, 640); + v1 = pStatusPanel; + pStatusPanel = 0; + mem_free_dbg(v1); + pStatusPanel = LoadFileInMem("CtrlPan\\P8Bulbs.CEL", 0); + CelDecodeRect((char *)pLifeBuff, 0, 87, 88, (char *)pStatusPanel, 1, 88); + CelDecodeRect((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); + CelDecodeRect((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] ) + CelDecodeOnly(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 ) + { + CelDecodeOnly(151, 634, pMultiBtns, panbtn[6] + 1, 33); + if ( FriendlyMode ) + v3 = panbtn[7] + 3; + else + v3 = panbtn[7] + 5; + CelDecodeOnly(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 ( automapflag ) + 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 ( pcursmonst != -1 ) + { + if ( leveltype ) + { + _LOBYTE(infoclr) = 0; + strcpy(infostr, monster[pcursmonst].mName); + ClearPanel(); + if ( monster[pcursmonst]._uniqtype ) + { + _LOBYTE(infoclr) = 3; + PrintUniqueHistory(); + } + else + { + PrintMonstHistory(monster[pcursmonst].MType->mtype); + } + } + else + { + strcpy(infostr, towner[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, bool center, int lines) +{ + int v4; // edi + char *v5; // ebx + unsigned char v6; // cl + signed int v7; // eax + char *v8; // esi + int v9; // eax + unsigned char v10; // esi + unsigned char v11; // al + int width; // [esp+18h] [ebp+Ch] + + v4 = 0; + v5 = str; + width = lineoffset[y + 4 * lines + lines]; + if ( center == 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 = (unsigned char)v9; + v4 += fontkern[(unsigned char)v9] + 2; + if ( (_BYTE)v9 ) + { + if ( v4 < 288 ) + { + _LOBYTE(v9) = infoclr; + CPrintString(width, v10, v9); + } + } + width += fontkern[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, 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] + + CelDecodeOnly(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); /* should use ClassStrTbl ? */ + } + 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] ) + CelDecodeOnly(201, 319, pChrButtons, chrbtn[0] + 2, 41); + if ( plr[myplr]._pBaseMag < MaxStats[v22][1] ) + CelDecodeOnly(201, 347, pChrButtons, chrbtn[1] + 4, 41); + if ( plr[myplr]._pBaseDex < MaxStats[v22][2] ) + CelDecodeOnly(201, 376, pChrButtons, chrbtn[2] + 6, 41); + if ( plr[myplr]._pBaseVit < MaxStats[v22][3] ) + CelDecodeOnly(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, 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, 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); + CelDecodeOnly(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; + CelDecodeOnly(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] + int _EAX; + char *_EBX; + + v0 = -(light4flag != 0); + _LOWORD(v0) = v0 & 0xF400; + v12 = v0 + 0x1200; + if ( leveltype == 4 ) + { + v7 = gpBuffer->row[0].pixels; + _EBX = &pLightTbl[v12]; + v9 = 352; + do + { + v10 = 640; + do + { + _EAX = *v7; + if ( (unsigned char)*v7 >= 0x20u ) + ASM_XLAT(_EAX,_EBX); + *v7++ = _EAX; + --v10; + } + while ( v10 ); + v7 += 128; + --v9; + } + while ( v9 ); + } + else + { + v1 = gpBuffer->row[0].pixels; + _EBX = &pLightTbl[v12]; + v3 = 352; + do + { + v4 = 640; + do + { + _EAX = *v1; + ASM_XLAT(_EAX,_EBX); + *v1++ = _EAX; + --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 + 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 ) + { + if ( !CheckSpell(myplr, ii, 1, 1) ) + 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] + + CelDecodeOnly(384, 511, pSpellBkCel, 1, 320); + CelDecodeOnly(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, v10, bright); + } + width += fontkern[v11] + 1; + } +} + +//----- (004069B6) -------------------------------------------------------- +void __cdecl CheckSBook() +{ + signed int v0; // ecx + signed int v1; // esi + int 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; + drawpanflag = 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 drawpanflag; + +//----- (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; + CelDecodeOnly(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; + } + CelDecodeOnly(screen_xa, 300, pCelBuff, frame_4B8800, 12); + frame_4B8800 = (frame_4B8800 & 7) + 1; +} + +//----- (00406C40) -------------------------------------------------------- +void __fastcall control_drop_gold(int vkey) +{ + char v1; // bl + int v2; // eax + int v3; // eax + size_t v4; // esi + char v6[6]; // [esp+8h] [ebp-8h] + + v1 = vkey; + if ( (signed int)(plr[myplr]._pHitPoints & 0xFFFFFFC0) <= 0 ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + return; + } + memset(v6, 0, 6u); + _itoa(dropGoldValue, v6, 10); + if ( v1 != VK_RETURN ) + { + if ( v1 == VK_ESCAPE ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + return; + } + if ( v1 == VK_BACK ) + { + v6[strlen(v6) - 1] = '\0'; + v2 = atoi(v6); + } + else + { + v3 = v1 - '0'; + 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, IDI_GOLD); + GetGoldSeed(v2, &plr[v3].HoldItem); + 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 + { + v3 = control_print_talk_msg(v3, 0, v4, &a4, 0); + if ( !v3 ) + goto LABEL_10; + v4 += 13; + } + while ( v4 < 39 ); + *v3 = 0; +LABEL_10: + CelDecDatOnly((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[4]._pName ) + 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; + } + CelDecodeOnly(236, 18 * v5 + 596, pTalkBtns, v7, 61); + goto LABEL_18; + } +} +// 4B8840: using guessed type int sgbPlrTalkTbl; +// 4B8960: using guessed type int talkflag; + +//----- (00407071) -------------------------------------------------------- +char *__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 v10; // dl + int v11; // 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 ) + return 0; + while ( 1 ) + { + v10 = fontframe[fontidx[v7]]; + v11 = v10; + a3 = v8 + fontkern[v10] + 1; + if ( a3 > 514 ) + break; + ++v6; + if ( v10 ) + CPrintString(*a4, v10, just); + *a4 += fontkern[v11] + 1; + v7 = *v6; + if ( !*v6 ) + return 0; + v8 = a3; + } + return v6; +} + +//----- (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_add_server_cmd_W(sgszTalkMsg) ) + NetSendCmdString(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; + drawpanflag = 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 drawpanflag; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00407241) -------------------------------------------------------- +void __cdecl control_reset_talk() +{ + talkflag = 0; + sgbPlrTalkTbl = 0; + drawpanflag = 255; +} +// 4B8840: using guessed type int sgbPlrTalkTbl; +// 4B8960: using guessed type int talkflag; +// 52571C: using guessed type int drawpanflag; + +//----- (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 < VK_SPACE ) + 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 ) + sgszTalkMsg[v1 - 1] = '\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)&sgszTalkSave[8] ); + 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; diff --git a/Source/control.h b/Source/control.h new file mode 100644 index 0000000..1b26c4f --- /dev/null +++ b/Source/control.h @@ -0,0 +1,147 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//control +extern char sgbNextTalkSave; // weak +extern char 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 void *pPanelText; +extern int frame_4B8800; // idb +extern void *pLifeBuff; +extern void *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 void *pManaBuff; +extern int infoclr; // weak +extern int sgbPlrTalkTbl; // weak // should be char [4] +extern void *pGBoxBuff; +extern void *pSBkBtnCel; +extern char tempstr[260]; +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[260]; +extern int numpanbtns; // weak +extern void *pStatusPanel; +extern char panelstr[256]; +extern int panelflag; // weak +extern char byte_4B8B88[256]; +extern int initialDropGoldValue; // idb +extern void *pSpellCels; +extern int panbtndown; // weak +extern void *pTalkPanel; // idb +extern int spselflag; // weak + +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); +void __fastcall CPrintString(int No, unsigned char pszStr, int Just); +void __fastcall AddPanelString(char *str, int just); +void __cdecl ClearPanel(); +void __fastcall DrawPanelBox(int x, int y, int w, int h, 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, bool center, 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 vkey); +void __fastcall control_remove_gold(int pnum, int gold_index); +void __fastcall control_set_gold_curs(int pnum); +void __cdecl DrawTalkPan(); +char *__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); + +/* data */ +extern unsigned char fontframe[127]; +extern unsigned char fontkern[68]; +extern int lineoffset[25]; +extern unsigned char fontidx[256]; + +/* rdata */ + +extern unsigned char SpellITbl[37]; +extern int PanBtnPos[8][5]; +extern char *PanBtnHotKey[8]; +extern char *PanBtnStr[8]; +extern RECT32 attribute_inc_rects[4]; +extern int SpellPages[6][7]; diff --git a/Source/cursor.cpp b/Source/cursor.cpp new file mode 100644 index 0000000..ac400f4 --- /dev/null +++ b/Source/cursor.cpp @@ -0,0 +1,1310 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int cursH; // weak +int icursH28; // idb +int cursW; // idb +int 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 + + +/* data */ +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 +}; + +//----- (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(CURSOR_HAND); + cursmx = ViewX; + cursmy = ViewY; + dword_4B8CCC = -1; + 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 == MIS_TOWN ) + { + 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 == MIS_RPORTAL ) + { + 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 = pcursmonst; + pcursobj = -1; + pcursitem = -1; + v11 = -1; + dword_4B8CCC = pcursmonst; + 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; + } + pcursmonst = v11; +LABEL_200: + v46 = dMonster[0][v43]; + if ( v46 > 0 ) + { + v11 = v46 - 1; + cursmx = v6; + pcursmonst = v46 - 1; + cursmy = v8; + } + v47 = dMonster[1][v43 + 1]; + if ( v47 > 0 ) + { + v11 = v47 - 1; + cursmx = v6 + 1; + pcursmonst = v47 - 1; + cursmy = v8 + 1; + } + if ( !towner[v11]._tSelFlag ) +LABEL_205: + pcursmonst = -1; +LABEL_206: + if ( pcursmonst != -1 ) + { +LABEL_305: + v59 = 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[4].WorldY ); + } + 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[4].WorldY ); + } + ++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 = pcursmonst; + if ( pcursmonst != -1 ) + { +LABEL_285: + if ( pcursplr == -1 ) + goto LABEL_286; +LABEL_306: + if ( pcurs == CURSOR_IDENTIFY ) + { + pcursobj = -1; + v59 = -1; + pcursitem = -1; + pcursmonst = -1; + cursmx = v6; + cursmy = v8; + } + if ( v59 != -1 ) + { + if ( monster[v59]._mFlags & 0x20 ) + pcursmonst = -1; + } + return; + } + if ( pcursplr != pcursmonst ) /* check in future */ + 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 || pcursmonst != -1 ) + goto LABEL_306; + if ( v83 ) + { + v70 = dItem[0][v27 + 1 + v8]; + if ( v70 <= 0 ) + goto LABEL_296; + v69 = v70 - 1; + if ( item[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 ( item[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 = item[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 ( item[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; + 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; + 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; + 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; + 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; + pcursmonst = v26; + } + } + if ( v11 == -1 ) + goto LABEL_128; + if ( monster[v11]._mFlags & 1 ) + { + v11 = -1; + cursmx = v6; + pcursmonst = -1; + cursmy = v8; + } + if ( v11 == -1 ) + goto LABEL_128; + if ( monster[v11]._mFlags & 0x20 ) + { + v11 = -1; + 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; + 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 ) + { + 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: + 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; + 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 ) + { + pcursmonst = v41; + cursmx = v6 + 1; + cursmy = v8 + 1; + } + } + v42 = pcursmonst; + if ( pcursmonst == -1 ) + goto LABEL_207; + if ( monster[pcursmonst]._mFlags & 1 ) + { + v42 = -1; + cursmx = v6; + 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; diff --git a/Source/cursor.h b/Source/cursor.h new file mode 100644 index 0000000..67d82e1 --- /dev/null +++ b/Source/cursor.h @@ -0,0 +1,42 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//cursor +extern int cursH; // weak +extern int icursH28; // idb +extern int cursW; // idb +extern int pcursmonst; // idb +extern int icursW28; // idb +extern void *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 dword_4B8CCC; // weak +extern int pcurs; // idb + +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(); + +/* data */ +extern int InvItemWidth[180]; +extern int InvItemHeight[180]; diff --git a/Source/dead.cpp b/Source/dead.cpp new file mode 100644 index 0000000..e00d109 --- /dev/null +++ b/Source/dead.cpp @@ -0,0 +1,161 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int spurtndx; // weak +DeadStruct dead[31]; +int stonendx; + +//----- (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, int 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)&dDead[112][0] ); + } + v0 = i + 1; + } +} diff --git a/Source/dead.h b/Source/dead.h new file mode 100644 index 0000000..e793fb6 --- /dev/null +++ b/Source/dead.h @@ -0,0 +1,19 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//dead +extern int spurtndx; // weak +extern DeadStruct dead[31]; +extern int stonendx; + +void __cdecl InitDead(); +void __fastcall AddDead(int dx, int dy, char dv, int ddir); +void __cdecl SetDead(); \ No newline at end of file diff --git a/Source/debug.cpp b/Source/debug.cpp new file mode 100644 index 0000000..60c6aec --- /dev/null +++ b/Source/debug.cpp @@ -0,0 +1,225 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +void *pSquareCel; +char dMonsDbg[17][112][112]; +char dFlagDbg[17][112][112]; + +//----- (004086F4) -------------------------------------------------------- +void __cdecl LoadDebugGFX() +{ + if ( visiondebug ) + pSquareCel = LoadFileInMem("Data\\Square.CEL", 0); +} +// 525720: using guessed type int visiondebug; + +//----- (0040870F) -------------------------------------------------------- +void __cdecl FreeDebugGFX() +{ + void *v0; // ecx + + v0 = pSquareCel; + pSquareCel = 0; + mem_free_dbg(v0); +} + +//----- (00408721) -------------------------------------------------------- +void __cdecl CheckDungeonClear() +{ + int i; + int j; + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + if ( dMonster[i][j] ) + TermMsg("Monsters not cleared"); + if ( dPlayer[i][j] ) + TermMsg("Players not cleared"); + + dMonsDbg[currlevel][i][j] = dFlags[i][j] & 2; + dFlagDbg[currlevel][i][j] = dFlags[i][j] & 8; + } + } +} + +#ifdef _DEBUG +void __cdecl 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 __cdecl 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 __cdecl 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 __cdecl MaxSpellsCheat() +{ + int i; // ebp + + for(i = 1; i < 37; i++) + { + if ( spelldata[i].sBookLvl != -1 ) + { + *(_QWORD *)plr[myplr]._pMemSpells |= 1i64 << (i - 1); + plr[myplr]._pSplLvl[i] = 10; + } + } +} + +void __fastcall 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 __cdecl 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 == 16 ) + dbgqst = 0; +} + +void __fastcall 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 __cdecl 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 __cdecl NextDebugMonster() +{ + char dstr[128]; // [esp+0h] [ebp-80h] + + if ( dbgmon++ == 200 ) + dbgmon = 0; + + sprintf(dstr, "Current debug monster = %i", dbgmon); + NetSendCmdString(1 << myplr, dstr); +} +#endif diff --git a/Source/debug.h b/Source/debug.h new file mode 100644 index 0000000..d4e7ec6 --- /dev/null +++ b/Source/debug.h @@ -0,0 +1,30 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//debug +extern void *pSquareCel; +extern char dMonsDbg[17][112][112]; +extern char dFlagDbg[17][112][112]; + +void __cdecl LoadDebugGFX(); +void __cdecl FreeDebugGFX(); +void __cdecl CheckDungeonClear(); +#ifdef _DEBUG +void __cdecl GiveGoldCheat(); +void __cdecl StoresCheat(); +void __cdecl TakeGoldCheat(); +void __cdecl MaxSpellsCheat(); +void __fastcall PrintDebugPlayer(bool bNextPlayer); +void __cdecl PrintDebugQuest(); +void __fastcall PrintDebugMonster(int m); +void __cdecl GetDebugMonster(); +void __cdecl NextDebugMonster(); +#endif \ No newline at end of file diff --git a/Source/diablo.cpp b/Source/diablo.cpp new file mode 100644 index 0000000..f371007 --- /dev/null +++ b/Source/diablo.cpp @@ -0,0 +1,2331 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +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 ghInst; // idb +int DebugMonsters[10]; +char cineflag; // weak +int drawpanflag; // 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 + +int diablo_inf = 0x7F800000; // 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 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 + +//----- (004087B6) -------------------------------------------------------- +struct diablo_cpp_init +{ + diablo_cpp_init() + { + diablo_cpp_init_value = diablo_inf; + } +} _diablo_cpp_init; +// 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 + int v4; // ecx + int pfExitProgram; // [esp+Ch] [ebp-4h] + + v2 = bSinglePlayer; + v3 = a1; + byte_678640 = 1; + while ( 1 ) + { + pfExitProgram = 0; + dword_5256E8 = 0; + if ( !NetInit(v2, &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 = 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 uMsg) +{ + //int v3; // eax + bool v5; // zf + //int v6; // eax + signed int v7; // [esp+8h] [ebp-24h] + LRESULT (__stdcall *saveProc)(HWND, UINT, WPARAM, LPARAM); // [esp+Ch] [ebp-20h] + struct tagMSG msg; // [esp+10h] [ebp-1Ch] + + nthread_ignore_mutex(1); + start_game(uMsg); + saveProc = SetWindowProc(GM_Game); + control_update_life_mana(); + msg_process_net_packets(); + gbRunGame = 1; + gbProcessPlayers = 1; + gbRunGameResult = 1; + drawpanflag = 255; + DrawAndBlit(); + PaletteFadeIn(8); + drawpanflag = 255; + gbGameLoopStartup = 1; + nthread_ignore_mutex(0); + while ( gbRunGame ) + { + diablo_color_cyc_logic(); + if ( PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE) ) + { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); + while ( PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE) ) + { + if ( msg.message == WM_QUIT ) + { + gbRunGameResult = 0; + gbRunGame = 0; + break; + } + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + if ( !gbRunGame || (v7 = 1, !nthread_has_500ms_passed()) ) + v7 = 0; + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + v5 = v7 == 0; + } + else + { + //_LOBYTE(v6) = nthread_has_500ms_passed(); + v5 = nthread_has_500ms_passed() == 0; + } + if ( !v5 ) + { + multi_process_network_packets(); + game_loop(gbGameLoopStartup); + msgcmd_send_chat(); + gbGameLoopStartup = 0; + DrawAndBlit(); + } +#ifdef SLEEP + Sleep(1); +#endif + } + if ( (unsigned char)gbMaxPlayers > 1u ) + pfile_write_hero(); + pfile_flush_W(); + PaletteFadeOut(8); + SetCursor(0); + ClearScreenBuffer(); + drawpanflag = 255; + scrollrt_draw_game_screen(1); + SetWindowProc(saveProc); + 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 drawpanflag; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00408A8C) -------------------------------------------------------- +void __fastcall start_game(int uMsg) +{ + cineflag = 0; + zoomflag = 1; + InitCursor(); + InitLightTable(); + LoadDebugGFX(); + music_stop(); + ShowProgress(uMsg); + gmenu_init_menu(); + InitLevelCursor(); + sgnTimeoutCurs = 0; + sgbMouseDown = 0; + track_repeat_walk(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 i; // esi + + FreeControlPan(); + FreeInvGFX(); + FreeGMenu(); + FreeQuestText(); + FreeStoreMem(); + + for(i = 0; i < 4; i++) + FreePlayerGFX(i); + + FreeItemGFX(); + FreeCursor(); + FreeLightTable(); + FreeDebugGFX(); + FreeGameMem(); +} + +//----- (00408B1E) -------------------------------------------------------- +bool __cdecl diablo_get_not_running() +{ + SetLastError(0); + CreateEventA(NULL, FALSE, FALSE, "DiabloEvent"); + return GetLastError() != ERROR_ALREADY_EXISTS; +} + +//----- (00408B4A) -------------------------------------------------------- +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + HINSTANCE v4; // esi + //int v11; // ecx + char Filename[260]; // [esp+8h] [ebp-10Ch] + char value_name[8]; // [esp+10Ch] [ebp-8h] + + v4 = hInstance; +#ifndef DEBUGGER + diablo_reload_process(hInstance); +#endif + ghInst = v4; + if ( RestrictedTest() ) + ErrDlg(TEMPLATE_ERR_RESTRICTED, 0, "C:\\Src\\Diablo\\Source\\DIABLO.CPP", 877); + if ( ReadOnlyTest() ) + { + if ( !GetModuleFileNameA(ghInst, Filename, 0x104u) ) + *Filename = '\0'; + DirErrDlg(Filename); + } + ShowCursor(FALSE); + srand(GetTickCount()); + encrypt_init_lookup_table(); + exception_get_filter(); + if ( !diablo_find_window("DIABLO") && diablo_get_not_running() ) + { + diablo_init_screen(); + diablo_parse_flags(lpCmdLine); + init_create_window(); + sound_init(); + UiInitialize(); +#ifdef _DEBUG + if ( showintrodebug ) + play_movie("gendata\\logo.smk", 1); +#else + play_movie("gendata\\logo.smk", 1); +#endif + strcpy(value_name, "Intro"); + if ( !SRegLoadValue("Diablo", value_name, 0, (int *)&hInstance) ) + hInstance = (HINSTANCE)1; + if ( hInstance ) + play_movie("gendata\\diablo1.smk", 1); + SRegSaveValue("Diablo", value_name, 0, 0); +#ifdef _DEBUG + if ( showintrodebug ) + { + UiTitleDialog(7); + BlackPalette(); + } +#else + UiTitleDialog(7); + BlackPalette(); +#endif + mainmenu_action(0); /* v11 fix unused arg */ + UiDestroy(); + palette_save_gamme(); + if ( ghMainWnd ) + { + Sleep(300); + DestroyWindow(ghMainWnd); + } + } + return 0; +} + +//----- (00408CB1) -------------------------------------------------------- +void __fastcall diablo_parse_flags(char *args) +{ +#ifdef _DEBUG + int n; // edi + int v15; // eax +#endif + while ( *args ) + { + for ( ; isspace(*args); ++args ) + ; + if ( !_strcmpi("dd_emulate", args) ) + { + gbEmulate = 1; + args += strlen("dd_emulate"); + } + else if ( !_strcmpi("dd_backbuf", args) ) + { + gbBackBuf = 1; + args += strlen("dd_backbuf"); + } + else if ( !_strcmpi("ds_noduplicates", args) ) + { + gbDupSounds = 0; + args += strlen("ds_noduplicates"); + } + else + { +#ifdef _DEBUG + switch ( tolower(*args++) ) + { + case '^': // god mod with all spells as skills + debug_mode_key_inverted_v = 1; + break; + case '$': // demi-god + debug_mode_dollar_sign = 1; + break; + /*case 'b': // enable drop log + debug_mode_key_b = 1; + break;*/ + case 'd': // no startup video+??? + showintrodebug = 0; + debug_mode_key_d = 1; + break; + case 'f': // draw fps + EnableFrameCount(); + break; + case 'i': // disable network timeout + debug_mode_key_i = 1; + break; + /*case 'j': // : init trigger at level + for ( ; isspace(*args); ++args ) + ; + for ( n = 0; isdigit(*args); n = v15 + 10 * n - 48 ) + v15 = *args++; + debug_mode_key_J_trigger = n; + break;*/ + case 'l': // : start in level as type + setlevel = 0; + for ( leveldebug = 1; isspace(*args); ++args ) + ; + for ( n = 0; isdigit(*args); n = v15 + 10 * n - 48 ) + v15 = *args++; + for ( leveltype = n; isspace(*args); ++args ) + ; + for ( n = 0; isdigit(*args); n = v15 + 10 * n - 48 ) + v15 = *args++; + currlevel = n; + plr[0].plrlevel = n; + break; + case 'm': // : add debug monster, up to 10 allowed + for ( monstdebug = 1; isspace(*args); ++args ) + ; + for ( n = 0; isdigit(*args); n = v15 + 10 * n - 48 ) + v15 = *args++; + DebugMonsters[debugmonsttypes++] = n; + break; + case 'n': // disable startup video + showintrodebug = 0; + break; + case 'q': // : force a certain quest + for ( ; isspace(*args); ++args ) + ; + for ( n = 0; isdigit(*args); n = v15 + 10 * n - 48 ) + v15 = *args++; + questdebug = n; + break; + case 'r': // : set map seed to + for ( ; isspace(*args); ++args ) + ; + for ( n = 0; isdigit(*args); n = v15 + 10 * n - 48 ) + v15 = *args++; + setseed = n; + break; + case 's': // unused + debug_mode_key_s = 1; + break; + case 't': // : sets current quest level + leveldebug = 1; + for ( setlevel = 1; isspace(*args); ++args ) + ; + for ( n = 0; isdigit(*args); n = v15 + 10 * n - 48 ) + v15 = *args++; + setlvlnum = n; + break; + case 'v': // draw yellow debug tiles + visiondebug = 1; + break; + case 'w': // rest of the cheats, some only in town + debug_mode_key_w = 1; + break; + case 'x': + fullscreen = 0; + break; + default: + break; + } +#else + tolower(*args++); +#endif + } + } +} +// 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)&screen_y_times_768[1024] ); + 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 dwSize; // 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] + STARTUPINFOA si; // [esp+224h] [ebp-84h] + SYSTEM_INFO sinf; // [esp+268h] [ebp-40h] + PROCESS_INFORMATION pi; // [esp+28Ch] [ebp-1Ch] + DWORD dwProcessId; // [esp+29Ch] [ebp-Ch] + HANDLE hMap; // [esp+2A0h] [ebp-8h] + HWND hWnd; // [esp+2A4h] [ebp-4h] + + *Filename = empty_string; + memset(Filename + 1, 0, sizeof(Filename) - 1); +// *(_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(&sinf); + dwSize = sinf.dwPageSize; + if ( sinf.dwPageSize < 4096 ) + dwSize = 4096; + hMap = CreateFileMappingA((HANDLE)0xFFFFFFFF, NULL, SEC_COMMIT|PAGE_READWRITE, 0, dwSize, Name); + v3 = GetLastError() != ERROR_ALREADY_EXISTS; + if ( hMap ) + { + v4 = (unsigned int *)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, dwSize); + v5 = v4; + if ( v4 ) + { + if ( v3 ) + { + *v4 = -1; + v4[1] = 0; + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + CreateProcessA(Filename, NULL, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi); + WaitForInputIdle(pi.hProcess, 0xFFFFFFFF); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + while ( *v5 < 0 ) + Sleep(1000); + UnmapViewOfFile(v5); + CloseHandle(hMap); + 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(hMap); + 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(VK_ESCAPE); + 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) +{ + 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_repeat_walk(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_repeat_walk(0); + } + } + else if ( uMsg > WM_DIAB && uMsg <= WM_DIABRETOWN ) + { + if ( (unsigned char)gbMaxPlayers > 1u ) + pfile_write_hero(); + nthread_ignore_mutex(1); + PaletteFadeOut(8); + FreeMonsterSnd(); + music_stop(); + track_repeat_walk(0); + sgbMouseDown = 0; + ReleaseCapture(); + ShowProgress(uMsg); + drawpanflag = 255; + DrawAndBlit(); + if ( gbRunGame ) + PaletteFadeIn(8); + nthread_ignore_mutex(0); + 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); + track_repeat_walk(LeftMouseDown(wParam)); + } + 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_on_mouse_move((unsigned short)lParam); + return 0; +} +// 525650: using guessed type int gbRunGame; +// 525698: using guessed type int gbRunGameResult; +// 52571C: using guessed type int drawpanflag; +// 525748: using guessed type char sgbMouseDown; +// 679660: using guessed type char gbMaxPlayers; + +//----- (004093B2) -------------------------------------------------------- +bool __fastcall LeftMouseDown(int a1) +{ + int v1; // edi + int v3; // eax + bool v6; // zf + int v7; // ecx + int v8; // eax + unsigned char v9; // dl + unsigned char v11; // dl + unsigned short v12; // ax + unsigned char v13; // dl + unsigned short v15; // [esp-8h] [ebp-10h] + + v1 = a1; + 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_exception() ) + CheckInvScrn(); + } + DoPanBtn(); + if ( pcurs <= 1 || pcurs >= 12 ) + return 0; + goto LABEL_48; + } + if ( gmenu_exception() || TryIconCurs() ) + return 0; + if ( questlog && MouseX > 32 && MouseX < 288 && MouseY > 32 && MouseY < 308 ) + { + QuestlogESC(); + return 0; + } + if ( qtextflag ) + { + qtextflag = 0; + sfx_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; + } + v3 = 21720 * myplr; + if ( plr[myplr]._pStatPts && !spselflag ) + CheckLvlBtn(); + if ( lvlbtndown ) + return 0; + if ( leveltype ) + { + v7 = abs(plr[myplr].WorldX - cursmx) < 2 && abs(plr[myplr].WorldY - cursmy) < 2; + _HIWORD(v8) = _HIWORD(pcurs); + if ( pcursitem != -1 && pcurs == 1 && v1 != 5 ) + { + _LOWORD(v8) = pcursitem; + NetSendCmdLocParam1(1u, (invflag == 0) + CMD_GOTOGETITEM, cursmx, cursmy, v8); +LABEL_96: + if ( pcursitem != -1 ) + return 0; + v6 = pcursobj == -1; + goto LABEL_98; + } + if ( pcursobj != -1 ) + { + if ( v1 != 5 || v7 && (v7 = 120 * pcursobj, *((_BYTE *)&object[0]._oBreak + v7) == 1) ) + { + _LOWORD(v7) = pcursobj; + NetSendCmdLocParam1(1u, (pcurs == 5) + CMD_OPOBJXY, cursmx, cursmy, v7); + goto LABEL_95; + } + } + if ( plr[myplr]._pwtype == 1 ) + { + if ( v1 == 5 ) + { + v9 = CMD_RATTACKXY; +LABEL_84: + NetSendCmdLoc(1u, v9, cursmx, cursmy); + goto LABEL_95; + } + if ( pcursmonst != -1 ) + { + v15 = pcursmonst; + if ( !CanTalkToMonst(pcursmonst) ) + { + v11 = CMD_RATTACKID; +LABEL_89: + NetSendCmdParam1(1u, v11, v15); + goto LABEL_96; + } +LABEL_88: + v11 = CMD_ATTACKID; + goto LABEL_89; + } + _LOBYTE(v12) = pcursplr; + if ( pcursplr == -1 || FriendlyMode ) + goto LABEL_96; + v13 = CMD_RATTACKPID; + } + else + { + if ( v1 == 5 ) + { + if ( pcursmonst == -1 || !CanTalkToMonst(pcursmonst) ) + { + v9 = CMD_SATTACKXY; + goto LABEL_84; + } + v12 = pcursmonst; + v13 = CMD_ATTACKID; +LABEL_94: + NetSendCmdParam1(1u, v13, v12); +LABEL_95: + if ( v1 == 5 ) + return 0; + goto LABEL_96; + } + if ( pcursmonst != -1 ) + { + v15 = pcursmonst; + goto LABEL_88; + } + _LOBYTE(v12) = pcursplr; + if ( pcursplr == -1 || FriendlyMode ) + goto LABEL_96; + v13 = CMD_ATTACKPID; + } + v12 = (char)v12; + goto LABEL_94; + } + if ( pcursitem != -1 && pcurs == 1 ) + { + _LOWORD(v3) = pcursitem; + NetSendCmdLocParam1(1u, (invflag == 0) + CMD_GOTOGETITEM, cursmx, cursmy, v3); + } + if ( pcursmonst != -1 ) + NetSendCmdLocParam1(1u, CMD_TALKXY, cursmx, cursmy, pcursmonst); + v6 = pcursitem == -1; +LABEL_98: + if ( v6 && pcursmonst == -1 && pcursplr == -1 ) + return 1; + return 0; +} +// 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) -------------------------------------------------------- +bool __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(CURSOR_HAND); + 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 ( 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() +{ + if ( !gmenu_exception() && 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); + } + } + } + } +} +// 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) -------------------------------------------------------- +bool __fastcall PressSysKey(int wParam) +{ + if ( gmenu_exception() || wParam != 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(ghInst, Filename, 0x104u) ) + TermMsg("Can't get program name"); + v2 = strrchr(Filename, '\\'); + if ( v2 ) + *v2 = 0; + strcat(Filename, "\\Diablo.ini"); + GetPrivateProfileStringA("NetMsg", spszMsgKeyTbl[v1], spszMsgTbl[v1], ReturnedString, 0x50u, Filename); + NetSendCmdString(-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 ( !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_repeat_walk(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_repeat_walk(0); + return; + } + invflag = 0; + chrflag = 0; + sbookflag = 0; + spselflag = 0; + if ( qtextflag && !leveltype ) + { + qtextflag = 0; + sfx_stop(); + } + questlog = 0; + automapflag = 0; + msgdelay = 0; + gamemenu_off(); + DisplayHelp(); +LABEL_110: + doom_close(); + return; +#ifdef _DEBUG + case 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); + return; + case VK_F4: + PrintDebugQuest(); + return; +#endif + 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 ( automapflag ) + { + AutomapUp(); + } + return; + case VK_DOWN: + if ( stextflag ) + { + STextDown(); + } + else if ( questlog ) + { + QuestlogDown(); + } + else if ( helpflag ) + { + HelpScrollDown(); + } + else if ( automapflag ) + { + AutomapDown(); + } + return; + case VK_PRIOR: + if ( stextflag ) + STextPrior(); + return; + case VK_NEXT: + if ( stextflag ) + STextNext(); + return; + case VK_LEFT: + if ( automapflag && !talkflag ) + AutomapLeft(); + return; + case VK_RIGHT: + if ( 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; + 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_repeat_walk(0); + } + drawpanflag = 255; + } +} +// 52571C: using guessed type int drawpanflag; +// 525740: using guessed type int PauseMode; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00409F7F) -------------------------------------------------------- +void __fastcall PressChar(int vkey) +{ + int v1; // ebx + BOOL v4; // ecx + int v5; // ecx + int v6; // eax + BOOL v7; // ecx + 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 v18; // [esp-4h] [ebp-8h] + + v1 = vkey; + if ( !gmenu_exception() && !control_talk_last_key(v1) && sgnTimeoutCurs == CURSOR_NONE && !deathflag ) + { + if ( (_BYTE)v1 == 'p' || (_BYTE)v1 == 'P' ) + { + diablo_pause_game(); + } + else if ( PauseMode != 2 ) + { + if ( doomflag ) + { + doom_close(); + return; + } + if ( dropGoldFlag ) + { + control_drop_gold(v1); + 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': +#ifdef _DEBUG + if ( debug_mode_key_inverted_v || debug_mode_key_w ) + { + NetSendCmd(1, CMD_CHEAT_EXPERIENCE); + return; + } +#endif + v9 = myplr; + if ( plr[myplr].SpdList[7]._itype != -1 + && plr[myplr].SpdList[7]._itype != 11 ) + { + v18 = 54; + goto LABEL_72; + } + return; + case '+': + case '=': + if ( automapflag ) + AutomapZoomIn(); + return; + case '-': + case '_': + if ( 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_repeat_walk(0); + } + return; + case 'V': + NetSendCmdString(1 << myplr, gszVersionNumber); + return; + case 'v': + NetSendCmdString(1 << myplr, gszProductName); + return; + case 'Z': + case 'z': + zoomflag = zoomflag == 0; + return; +#ifdef _DEBUG + case '[': + if ( !currlevel && debug_mode_key_w ) + TakeGoldCheat(); + return; + case ']': + if ( !currlevel && 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 '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 && debug_mode_key_w ) + GiveGoldCheat(); + return; + case '~': + if ( !currlevel && debug_mode_key_w ) + StoresCheat(); + return; +#endif + 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 lvldir) +{ + int hnd; // cl + + switch ( leveltype ) + { + case 0: + CreateTown(lvldir); + InitTownTriggers(); + hnd = 0; + break; + case 1: + CreateL5Dungeon(glSeedTbl[currlevel], lvldir); + InitL1Triggers(); + Freeupstairs(); + hnd = 1; + break; + case 2: + CreateL2Dungeon(glSeedTbl[currlevel], lvldir); + InitL2Triggers(); + Freeupstairs(); + hnd = 2; + break; + case 3: + CreateL3Dungeon(glSeedTbl[currlevel], lvldir); + InitL3Triggers(); + Freeupstairs(); + hnd = 3; + break; + case 4: + CreateL4Dungeon(glSeedTbl[currlevel], lvldir); + InitL4Triggers(); + Freeupstairs(); + hnd = 4; + break; + default: + TermMsg("CreateLevel"); + return; + } + + LoadRndLvlPal(hnd); +} +// 5BB1ED: using guessed type char leveltype; + +//----- (0040A5A4) -------------------------------------------------------- +void __fastcall LoadGameLevel(bool firstflag, int lvldir) +{ + int v2; // ebp + bool visited; // edx + int i; // ecx + int j; // eax + + v2 = 0; + if ( setseed ) + glSeedTbl[currlevel] = setseed; + music_stop(); + SetCursor(CURSOR_HAND); + SetRndSeed(glSeedTbl[currlevel]); + IncProgress(); + MakeLightTable(); + LoadLvlGFX(); + IncProgress(); + if ( firstflag ) + { + InitInv(); + InitItemGFX(); + InitQuestText(); + + if ( gbMaxPlayers ) + { + for(i = 0; i < gbMaxPlayers; i++) + InitPlrGFXMem(i); + } + + InitStores(); + InitAutomapOnce(); + InitHelp(); + } + SetRndSeed(glSeedTbl[currlevel]); + if ( !leveltype ) + SetupTownStores(); + IncProgress(); + InitAutomap(); + if ( leveltype && lvldir != 4 ) + { + InitLighting(); + InitVision(); + } + InitLevelMonsters(); + IncProgress(); + if ( !setlevel ) + { + CreateLevel(lvldir); + IncProgress(); + FillSolidBlockTbls(); + SetRndSeed(glSeedTbl[currlevel]); + if ( leveltype ) + { + GetLevelMTypes(); + InitThemes(); + LoadAllGFX(); + } + else + { + InitMissileGFX(); + } + IncProgress(); + if ( lvldir == 3 ) + GetReturnLvlPos(); + if ( lvldir == 5 ) + GetPortalLvlPos(); + IncProgress(); + + for(i = 0; i < 4; i++) + { + if ( plr[i].plractive ) + { + if ( currlevel == plr[i].plrlevel ) + { + InitPlayerGFX(v2); + if ( lvldir != 4 ) + InitPlayer(v2, firstflag); + } + } + ++v2; + } + + PlayDungMsgs(); + InitMultiView(); + IncProgress(); + + visited = 0; + if ( gbMaxPlayers > 0 ) + { + for(i = 0; i < gbMaxPlayers; i++) + { + if ( plr[i].plractive ) + visited = visited || plr[i]._pLvlVisited[currlevel]; + } + } + SetRndSeed(glSeedTbl[currlevel]); + if ( leveltype ) + { + if ( firstflag || lvldir == 4 || !plr[myplr]._pLvlVisited[currlevel] || gbMaxPlayers != 1 ) + { + HoldThemeRooms(); + glMid1Seed[currlevel] = GetRndSeed(); + InitMonsters(); + glMid2Seed[currlevel] = GetRndSeed(); + InitObjects(currlevel); + InitItems(); + CreateThemeRooms(); + glMid3Seed[currlevel] = GetRndSeed(); + InitMissiles(); + InitDead(); + glEndSeed[currlevel] = GetRndSeed(); + if ( gbMaxPlayers != 1 ) + 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; + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + dFlags[i][j] |= 0x40; + } + + InitTowners(); + InitItems(); + InitMissiles(); + IncProgress(); + if ( !firstflag && lvldir != 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 ( lvldir == 5 ) + GetPortalLvlPos(); + + for(i = 0; i < 4; i++) + { + if ( plr[i].plractive ) + { + if ( currlevel == plr[i].plrlevel ) + { + InitPlayerGFX(v2); + if ( lvldir != 4 ) + InitPlayer(v2, firstflag); + } + } + ++v2; + } + + InitMultiView(); + IncProgress(); + if ( firstflag || lvldir == 4 || !plr[myplr]._pSLvlVisited[(unsigned char)setlvlnum] ) + { + InitItems(); + SavePreLighting(); + } + else + { + LoadLevel(); + } + InitMissiles(); + IncProgress(); +LABEL_72: + SyncPortals(); + + for(i = 0; i < 4; i++) + { + if ( plr[i].plractive && plr[i].plrlevel == currlevel && (!plr[i]._pLvlChanging || i == myplr) ) + { + if ( plr[i]._pHitPoints <= 0 ) + dFlags[plr[i].WorldX][plr[i].WorldY] |= 4; + else if ( gbMaxPlayers == 1 ) + dPlayer[plr[i].WorldX][plr[i].WorldY] = i + 1; + else + SyncInitPlrPos(i); + } + } + + if ( leveltype ) + SetDungeonMicros(); + InitLightMax(); + IncProgress(); + IncProgress(); + if ( firstflag ) + { + InitControlPan(); + IncProgress(); + } + if ( leveltype ) + { + ProcessLightList(); + ProcessVisionList(); + } + music_start((unsigned char)leveltype); + //do + // _LOBYTE(v19) = IncProgress(); + while ( !IncProgress() ); + 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 + + 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 ) + { + if ( nthread_has_500ms_passed() ) + { + if ( v2 ) + continue; + } + } + } + return; + } + timeout_cursor(1); + } +} +// 525650: using guessed type int gbRunGame; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0040AB33) -------------------------------------------------------- +void __cdecl game_logic() +{ + if ( PauseMode != 2 ) + { + if ( PauseMode == 1 ) + PauseMode = 2; + if ( gbMaxPlayers == 1 && gmenu_exception() ) + { + drawpanflag |= 1u; + } + else + { + if ( !gmenu_exception() && sgnTimeoutCurs == CURSOR_NONE ) + { + CheckCursMove(); + track_process(); + } + if ( gbProcessPlayers ) + ProcessPlayers(); + if ( leveltype ) + { + ProcessMonsters(); + ProcessObjects(); + ProcessMissiles(); + ProcessItems(); + ProcessLightList(); + ProcessVisionList(); + } + else + { + ProcessTowners(); + ProcessItems(); + ProcessMissiles(); + } +#ifdef _DEBUG + if ( debug_mode_key_inverted_v ) + { + if ( GetAsyncKeyState(VK_SHIFT) & 0x8000 ) + ScrollView(); + } +#endif + sound_update(); + ClearPlrMsg(); + CheckTriggers(); + CheckQuests(); + drawpanflag |= 1u; + pfile_update(0); + } + } +} +// 5256A0: using guessed type int gbProcessPlayers; +// 525718: using guessed type char cineflag; +// 52571C: using guessed type int drawpanflag; +// 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(CURSOR_HOURGLASS); + drawpanflag = 255; + } + scrollrt_draw_game_screen(1); + } + else if ( sgnTimeoutCurs ) + { + SetCursor(sgnTimeoutCurs); + sgnTimeoutCurs = 0; + ClearPanel(); + drawpanflag = 255; + } +} +// 52571C: using guessed type int drawpanflag; +// 525748: using guessed type char sgbMouseDown; + +//----- (0040AC6B) -------------------------------------------------------- +void __cdecl 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 == 4 ) + { + lighting_color_cycling(); + } + else if ( leveltype == 3 ) + { + if ( fullscreen ) + palette_update_caves(); + } + } + } +} +// 484364: using guessed type int fullscreen; +// 52574C: using guessed type int color_cycle_timer; +// 5BB1ED: using guessed type char leveltype; diff --git a/Source/diablo.h b/Source/diablo.h new file mode 100644 index 0000000..722c13d --- /dev/null +++ b/Source/diablo.h @@ -0,0 +1,107 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//diablo +extern int diablo_cpp_init_value; // weak +extern HWND ghMainWnd; +extern int glMid1Seed[17]; +extern int glMid2Seed[17]; +extern int gnLevelTypeTbl[17]; +extern int MouseY; // idb +extern int MouseX; // idb +extern bool gbGameLoopStartup; // idb +extern int glSeedTbl[17]; +extern int gbRunGame; // weak +extern int glMid3Seed[17]; +extern int gbRunGameResult; // weak +extern int zoomflag; // weak +extern int gbProcessPlayers; // weak +extern int glEndSeed[17]; +extern int dword_5256E8; // weak +extern HINSTANCE ghInst; // idb +extern int DebugMonsters[10]; +extern char cineflag; // weak +extern int drawpanflag; // 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 __cdecl diablo_cpp_init(); +void __cdecl FreeGameMem(); +int __fastcall diablo_init_menu(int a1, int bSinglePlayer); +void __fastcall run_game_loop(int uMsg); +void __fastcall start_game(int uMsg); +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); +bool __fastcall LeftMouseDown(int a1); +bool __cdecl TryIconCurs(); +void __cdecl LeftMouseUp(); +void __cdecl RightMouseDown(); +void __fastcall j_gmenu_on_mouse_move(LPARAM lParam); +bool __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 lvldir); +void __fastcall LoadGameLevel(bool firstflag, int lvldir); +void __fastcall game_loop(bool startup); +void __cdecl game_logic(); +void __fastcall timeout_cursor(bool timeout); +void __cdecl diablo_color_cyc_logic(); + +/* data */ + +extern int diablo_inf; // weak + +/* 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 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 diff --git a/Source/doom.cpp b/Source/doom.cpp new file mode 100644 index 0000000..76a6554 --- /dev/null +++ b/Source/doom.cpp @@ -0,0 +1,110 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int doom_quest_time; // weak +int doom_stars_drawn; // weak +void *pDoomCel; +int doomflag; // weak +int DoomQuestState; // idb + +//----- (0040ACAD) -------------------------------------------------------- +int __cdecl doom_get_frame_from_time() +{ + int result; // eax + + if ( DoomQuestState == 36001 ) + result = 31; + else + result = DoomQuestState / 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 ( 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); +} +// 525750: using guessed type int doom_quest_time; + +//----- (0040AD34) -------------------------------------------------------- +void __cdecl 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(); +} +// 525750: using guessed type int doom_quest_time; +// 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 ( 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, pDoomCel, 1, 640); + } +} +// 525750: using guessed type int doom_quest_time; +// 525754: using guessed type int doom_stars_drawn; +// 52575C: using guessed type int doomflag; diff --git a/Source/doom.h b/Source/doom.h new file mode 100644 index 0000000..d9242cf --- /dev/null +++ b/Source/doom.h @@ -0,0 +1,25 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//doom +extern int doom_quest_time; // weak +extern int doom_stars_drawn; // weak +extern void *pDoomCel; +extern int doomflag; // weak +extern int DoomQuestState; // idb + +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(); \ No newline at end of file diff --git a/Source/drlg_l1.cpp b/Source/drlg_l1.cpp new file mode 100644 index 0000000..8f645cb --- /dev/null +++ b/Source/drlg_l1.cpp @@ -0,0 +1,2981 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +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 + +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 } +}; +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 +}; +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 +}; +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 }; +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 }; +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 }; +unsigned char LAMPS[] = { 2, 2, 13, 0, 13, 13, 129, 0, 130, 128 }; +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 }; + +/* rdata */ +unsigned char L5ConvTbl[16] = { 22u, 13u, 1u, 13u, 2u, 13u, 13u, 13u, 4u, 13u, 1u, 13u, 2u, 13u, 16u, 13u }; + +//----- (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 *sFileName, int vx, int vy) +{ + 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 = vx; + dminx = 16; + dminy = 16; + v3 = sFileName; + 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 = vy; + 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 i; // edi + signed int v1; // esi + signed int j; // ebx + int rv; // eax + + i = 0; + do + { + v1 = i; + j = 40; + do + { + if ( !mydflags[0][v1] && dungeon[0][v1] == 13 ) + { + rv = random(0, 3); + if ( rv == 1 ) + dungeon[0][v1] = -94; + if ( rv == 2 ) + dungeon[0][v1] = -93; + } + v1 += 40; + --j; + } + while ( j ); + ++i; + } + while ( i < 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]; /* check */ + 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 *sFileName, int vx, int vy) +{ + 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(sFileName, 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 rseed, int entry) +{ + int v2; // esi + + v2 = entry; + SetRndSeed(rseed); + 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() +{ + setloadflag = 0; + if ( QuestStatus(6) ) + { + pSetPiece = LoadFileInMem("Levels\\L1Data\\rnd6.DUN", 0); + setloadflag = 1; + } + if ( QuestStatus(12) && gbMaxPlayers == 1 ) + { + pSetPiece = LoadFileInMem("Levels\\L1Data\\SKngDO.DUN", 0); + setloadflag = 1; + } + if ( QuestStatus(7) ) + { + 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 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; + if ( QuestStatus(13) ) + { + if ( v13 ) + { + if ( DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, 0, -1, 0) < 0 ) + v2 = 0; + --ViewY; + } + else if ( DRLG_PlaceMiniSet(PWATERIN, 1, 1, 0, 0, 1, -1, 0) < 0 ) + { + v2 = 0; + } + } + if ( QuestStatus(7) ) + { + if ( !v13 ) + { + v5 = DRLG_PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, 1, -1, 0); + goto LABEL_21; + } + if ( DRLG_PlaceMiniSet(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(L5STAIRSUP, 1, 1, 0, 0, 0, -1, 0) < 0 + || DRLG_PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, 1, -1, 1) < 0 ) + { + v2 = 0; + } + goto LABEL_33; + } + if ( DRLG_PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, 1, -1, 0) >= 0 ) + { + v5 = DRLG_PlaceMiniSet(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(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 x, int y) +{ + 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 = y; + v3 = &mydflags[x][y]; + v8 = v3; + v4 = *v3; + if ( v4 < 0 ) + goto LABEL_57; + v5 = v4 & 0x7F; + v6 = &dungeon[x][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 ( x == 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 ( x != 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 ( x != 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 ( x != 1 && v7 == 1 ) + *v6 = 25; + if ( v2 != 1 && v7 == 7 ) + *v6 = 31; + if ( x != 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 sd[2][2]; + + v0 = 1; + do + { + v1 = &dungeon[0][v0 + 39]; + v2 = 40; + do + { + v3 = &SPATS[0].s1; + sd[0][0] = BSTYPES[(unsigned char)v1[1]]; + sd[1][0] = BSTYPES[(unsigned char)*(v1 - 39)]; + sd[0][1] = BSTYPES[(unsigned char)*v1]; + sd[1][1] = BSTYPES[(unsigned char)*(v1 - 40)]; + do + { + if ( *(v3 - 1) == sd[0][0] ) + { + v4 = 1; + if ( *v3 && *v3 != sd[1][1] ) + v4 = 0; + v5 = v3[1]; + if ( v5 && v5 != sd[0][1] ) + v4 = 0; + v6 = v3[2]; + if ( v6 && v6 != sd[1][0] ) + v4 = 0; + if ( v4 == 1 ) + { + v7 = v3[3]; + if ( v7 && !mydflags[v2 - 1][v0 - 1] ) /* !L5dungeon[79][v2 + 39 + v0] ) */ + *(v1 - 40) = v7; + v8 = v3[4]; + if ( v8 && !mydflags[v2][v0 - 1] ) /* !L5dungeon[79][v2 + 79 + v0] ) */ + *v1 = v8; + v9 = v3[5]; + if ( v9 && !mydflags[v2 - 1][v0] ) /* !L5dungeon[79][v2 + 40 + v0] ) */ + *(v1 - 39) = v9; + } + } + v3 += 7; + } + while ( (signed int)v3 < (signed int)&SPATS[37].s1 ); + 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(unsigned char *miniset, int tmin, int tmax, int cx, int cy, bool setview, 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 + unsigned char v19; // cl + int v20; // ebx + int result; // eax + int v22; // eax + unsigned char v23; // dl + unsigned 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] + unsigned 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 = miniset; + v9 = *miniset; + v10 = tmin; + v11 = tmax - tmin; + v30 = miniset; + v36 = *miniset; + v37 = 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 = (unsigned 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 = (unsigned 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 = (unsigned char *)&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; + DRLG_MRectTrans(v14, v15 + 2, v14 + 5, v15 + 4); + TransVal = v24; + quests[13]._qtx = 2 * v14 + 21; + quests[13]._qty = 2 * v15 + 22; + } + result = 1; + if ( setview == 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 + char *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 = &dungeon[v5][18]; + 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 x, int y, int w, int h) +{ + int i; // esi + int v5; // edi + char *v6; // eax + + for ( i = 0; i < h; ++i ) + { + if ( w > 0 ) + { + v5 = w; + v6 = &dungeon[x][i + y]; + do + { + *v6 = 1; + v6 += 40; + --v5; + } + while ( v5 ); + } + } +} + +//----- (0040BD9D) -------------------------------------------------------- +void __fastcall L5roomGen(int x, int y, int w, int h, bool 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; // 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 = y; + txa = 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; + dir_horiza = 0; + twa = w / 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; + 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 + h; + v15 = L5checkRoom(v13 - 1, v29 + h, 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 = 0; + h = v12; + w = v11; + v29 = txb; + txa = v13; + } + dir_horizb = 0; + thb = h / 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; + 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 += w; + 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 = 1; + h = v19; + w = v18; + v29 = v20; + } +} + +//----- (0040BFA4) -------------------------------------------------------- +bool __fastcall L5checkRoom(int x, int y, int width, int height) +{ + int v4; // eax + int v5; // ebx + char *v6; // edi + int v8; // [esp+Ch] [ebp-4h] + + v4 = 0; + if ( height <= 0 ) + return 1; + while ( 1 ) + { + v8 = 0; + if ( width > 0 ) + break; +LABEL_10: + if ( ++v4 >= height ) + return 1; + } + v5 = x; + v6 = &dungeon[x][v4 + y]; + while ( v5 >= 0 && v5 < 40 && v4 + y >= 0 && v4 + y < 40 && !*v6 ) + { + ++v8; + v6 += 40; + ++v5; + if ( v8 >= width ) + goto LABEL_10; + } + return 0; +} + +//----- (0040C008) -------------------------------------------------------- +int __cdecl L5GetArea() +{ + int rv; // eax + signed int i; // edx + _BYTE *v2; // ecx + signed int j; // esi + + rv = 0; + i = 0; + do + { + v2 = (unsigned char *)dungeon + i; + j = 40; + do + { + if ( *v2 == 1 ) + ++rv; + v2 += 40; + --j; + } + while ( j ); + ++i; + } + while ( i < 40 ); + return rv; +} + +//----- (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 i, int j) +{ + int v2; // esi + char *v3; // edi + int v4; // eax + char *v5; // ebx + signed int wallok; // eax + char v7; // dl + int result; // eax + int v9; // [esp+8h] [ebp-4h] + + v2 = 8 * (5 * i + 5); + v9 = 1; + v3 = (char *)dungeon + v2 + j; + if ( *v3 == 13 ) + { + v4 = 8 * (5 * i + 5); + v5 = &dungeon[i + 1][j]; + do + { + if ( *(v3 - 1) != 13 ) + break; + if ( dungeon[0][v2 + 1 + j] != 13 ) + break; + if ( mydflags[0][v2 + j] ) + break; + ++v9; + v5 += 40; + v4 += 40; + v3 = v5; + v2 = v4; + } + while ( *v5 == 13 ); + } + wallok = 0; + v7 = dungeon[v9 + i][j]; + if ( (unsigned char)v7 >= 3u && (unsigned char)v7 <= 7u ) + wallok = 1; + if ( (unsigned char)v7 >= 0x10u && (unsigned char)v7 <= 0x18u ) + wallok = 1; + if ( v7 == 22 ) + wallok = 0; + if ( v9 == 1 ) + wallok = 0; + if ( wallok ) + result = v9; + else + result = -1; + return result; +} + +//----- (0040C2DC) -------------------------------------------------------- +int __fastcall L5VWallOk(int i, int j) +{ + int v2; // ecx + int result; // eax + char *v4; // esi + signed int wallok; // esi + char v6; // dl + + v2 = i; + result = 1; + if ( dungeon[v2][j + 1] == 13 ) + { + v4 = &dungeon[v2][j]; + do + { + if ( v4[result - 40] != 13 ) + break; + if ( dungeon[v2 + 1][result + j] != 13 ) + break; + if ( mydflags[v2][result + j] ) + break; + ++result; + } + while ( v4[result] == 13 ); + } + wallok = 0; + v6 = dungeon[0][result + v2 * 40 + j]; + if ( (unsigned char)v6 >= 3u && (unsigned char)v6 <= 7u ) + wallok = 1; + if ( (unsigned char)v6 >= 0x10u && (unsigned char)v6 <= 0x18u ) + wallok = 1; + if ( v6 == 22 ) + wallok = 0; + if ( result == 1 ) + wallok = 0; + if ( !wallok ) + result = -1; + return result; +} + +//----- (0040C35B) -------------------------------------------------------- +void __fastcall L5HorizWall(int i, int j, char p, int dx) +{ + 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 = j; + v5 = i; + _LOBYTE(i) = 0; + v15 = j; + v6 = random(i, 4); + if ( v6 >= 0 ) + { + if ( v6 <= 1 ) + { + v16 = 2; + } + else if ( v6 == 2 ) + { + v16 = 12; + if ( p == 2 ) + _LOBYTE(p) = 12; + if ( p == 4 ) + _LOBYTE(p) = 10; + } + else if ( v6 == 3 ) + { + v16 = 36; + if ( p == 2 ) + _LOBYTE(p) = 36; + if ( p == 4 ) + _LOBYTE(p) = 27; + } + } + _LOBYTE(v7) = 0; + v8 = random(v7, 6) != 5 ? 26 : 12; + if ( v16 == 12 ) + v8 = 12; + v9 = v4 + 40 * v5; + dungeon[0][v9] = p; + v10 = dx; + if ( dx > 1 ) + { + v11 = &dungeon[1][v9]; + v12 = dx - 1; + do + { + *v11 = v16; + v11 += 40; + --v12; + } + while ( v12 ); + v4 = v15; + } + _LOBYTE(v10) = 0; + v13 = random(v10, dx - 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 i, int j, char p, int dy) +{ + 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 = j; + v5 = i; + _LOBYTE(i) = 0; + v18 = j; + v6 = random(i, 4); + if ( v6 >= 0 ) + { + if ( v6 <= 1 ) + { + v20 = 1; + } + else if ( v6 == 2 ) + { + v20 = 11; + if ( p == 1 ) + _LOBYTE(p) = 11; + if ( p == 4 ) + _LOBYTE(p) = 14; + } + else if ( v6 == 3 ) + { + v20 = 35; + if ( p == 1 ) + _LOBYTE(p) = 35; + if ( p == 4 ) + _LOBYTE(p) = 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] = p; + v11 = dy; + if ( dy > 1 ) + { + v12 = &dungeon[v10][v4 + 1]; + _LOBYTE(v9) = v20; + BYTE1(v9) = v20; + v13 = v9 << 16; + _LOWORD(v13) = v9; + _LOBYTE(v9) = v19; + v14 = (unsigned int)(dy - 1) >> 2; + memset(v12, v13, v14); + memset(&v12[4 * v14], v13, ((_BYTE)dy - 1) & 3); + v11 = dy; + 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 sx, int sy, bool topflag, bool bottomflag, bool leftflag, bool rightflag) +{ + 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 ( topflag == 1 ) + { + v6 = sy + 40 * sx; + 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 ( bottomflag == 1 ) + { + v7 = sy + 11; + v8 = v7 + 40 * sx; + 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; + sy = v7 - 11; + } + if ( leftflag == 1 ) + { + v10 = sy + 40 * sx; + 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 ( rightflag == 1 ) + { + v11 = sx + 11; + v12 = sy + 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; + sx = v11 - 11; + } + v14 = 10; + v15 = sy + 40 * sx; + 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 x1, int y1, int x2, int y2) +{ + int v4; // eax + char *v5; // edx + int v6; // eax + char *v7; // ecx + + if ( y1 == y2 ) + { + if ( x1 < x2 ) + { + v4 = x2 - x1; + v5 = &dungeon[x1][y1 + 3]; + do + { + *(v5 - 3) = 12; + *v5 = 12; + v5 += 40; + --v4; + } + while ( v4 ); + } + } + else + { + v6 = y1; + if ( y1 < y2 ) + { + v7 = dungeon[x1 + 3]; + do + { + v7[v6 - 120] = 11; + v7[v6++] = 11; + } + while ( v6 < y2 ); + } + } +} + +//----- (0040CF17) -------------------------------------------------------- +void __fastcall DRLG_L5SetRoom(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); + v3 = *(unsigned char *)pSetPiece; + setpc_x = rx1; + setpc_y = ry1; + setpc_w = v3; + setpc_h = v2; + v7 = (char *)pSetPiece + 4; + if ( v2 > 0 ) + { + do + { + if ( v3 > 0 ) + { + v6 = v3; + v4 = ry1 + v8 + 40 * rx1; + 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 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 v20; // [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 = j; + v8 = i; + 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 ( v20 = 40 * v8; dungeon[0][v11 + tya] == 13; v11 = v20 ) + { + 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; + v20 += 40; + d = 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 ( 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; + +//----- (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]; /* check */ + 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 ); +} diff --git a/Source/drlg_l1.h b/Source/drlg_l1.h new file mode 100644 index 0000000..5fa8fe2 --- /dev/null +++ b/Source/drlg_l1.h @@ -0,0 +1,74 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//drlg_l1 +extern char L5dungeon[80][80]; +extern char mydflags[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 __cdecl DRLG_Init_Globals(); +void __fastcall LoadL1Dungeon(char *sFileName, int vx, int vy); +void __cdecl DRLG_L1Floor(); +void __cdecl DRLG_L1Pass3(); +void __cdecl DRLG_InitL1Vals(); +void __fastcall LoadPreL1Dungeon(char *sFileName, int vx, int vy); +void __fastcall CreateL5Dungeon(int rseed, int entry); +void __cdecl DRLG_LoadL1SP(); +void __cdecl DRLG_FreeL1SP(); +void __fastcall DRLG_L5(int entry); +void __fastcall DRLG_PlaceDoor(int x, int y); +void __cdecl DRLG_L1Shadows(); +int __fastcall DRLG_PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, bool setview, int noquad, int ldir); +void __cdecl InitL5Dungeon(); +void __cdecl L5ClearFlags(); +void __cdecl L5firstRoom(); +void __fastcall L5drawRoom(int x, int y, int w, int h); +void __fastcall L5roomGen(int x, int y, int w, int h, bool dir); +bool __fastcall L5checkRoom(int x, int y, int width, int height); +int __cdecl L5GetArea(); +void __cdecl L5makeDungeon(); +void __cdecl L5makeDmt(); +void __cdecl L5AddWall(); +int __fastcall L5HWallOk(int i, int j); +int __fastcall L5VWallOk(int i, int j); +void __fastcall L5HorizWall(int i, int j, char p, int dx); +void __fastcall L5VertWall(int i, int j, char p, int dy); +void __cdecl L5tileFix(); +void __cdecl DRLG_L5Subs(); +void __cdecl L5FillChambers(); +void __fastcall DRLG_L5GChamber(int sx, int sy, bool topflag, bool bottomflag, bool leftflag, bool rightflag); +void __fastcall DRLG_L5GHall(int x1, int y1, int x2, int y2); +void __fastcall DRLG_L5SetRoom(int rx1, int ry1); +void __cdecl DRLG_L5FloodTVal(); +void __fastcall DRLG_L5FTVR(int i, int j, int x, int y, int d); +void __cdecl DRLG_L5TransFix(); +void __cdecl DRLG_L5DirtFix(); +void __cdecl DRLG_L5CornerFix(); + +/* data */ +extern ShadowStruct SPATS[37]; +extern unsigned char BSTYPES[206]; +extern unsigned char L5BTYPES[206]; +extern unsigned char STAIRSUP[]; +extern unsigned char L5STAIRSUP[]; +extern unsigned char STAIRSDOWN[]; +extern unsigned char LAMPS[]; +extern unsigned char PWATERIN[]; + +/* rdata */ +extern unsigned char L5ConvTbl[16]; diff --git a/Source/drlg_l2.cpp b/Source/drlg_l2.cpp new file mode 100644 index 0000000..81dbadd --- /dev/null +++ b/Source/drlg_l2.cpp @@ -0,0 +1,3416 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int nSx1; +int nSx2; // weak +int nSy1; +int nSy2; // weak +int nRoomCnt; +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 } +}; + +//----- (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() +{ + int i; // ecx + int j; // edx + bool doorok; // esi + + for(i = 0; i < 40; i++) + { + for(j = 0; j < 40; j++) + { + 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(i = 1; i < 39; i++) + { + for(j = 1; j < 39; j++) + { + if ( dflags[i][j] >= 0 ) + { + if ( (dungeon[i][j] == 2 || dungeon[i][j] == 5) && dungeon[i][j-1] == 3 && dungeon[i][j+1] == 3 ) + { + doorok = 0; + 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 = 1; + ++i; + } + if ( !doorok && dflags[i-1][j] >= 0 ) // dTransVal2[111][40 * i + 80 + j] >= 0 ) + dungeon[i-1][j] = 5; // *((_BYTE *)&dMonster[111][10 * i + 102] + j) = 5; + } + } + } + } + + for(i = 1; i < 39; i++) + { + for(j = 1; j < 39; j++) + { + if ( dflags[i][j] >= 0 ) + { + if ( (dungeon[i][j] == 1 || dungeon[i][j] == 4) + && dungeon[i-1][j] == 3 // *((_BYTE *)&dMonster[111][i / 4 + 102] + j) == 3 + && dungeon[i+1][j] == 3 ) + { + doorok = 0; + while ( 1 ) + { + if ( dungeon[i][j] != 1 && dungeon[i][j] != 4 ) + break; + if ( dungeon[i-1][j] != 3 || dungeon[i+1][j] != 3 ) + break; + if ( dungeon[i][j] == 4 ) + doorok = 1; + ++j; + } + if ( !doorok && dflags[i][j-1] >= 0 ) // *(_BYTE *)(i + j + 5920151) >= 0 ) /* check */ + dungeon[i][j-1] = 4; // *((_BYTE *)&dMonster[111][i / 4 + 111] + j + 3) = 4; + } + } + } + } +} + +//----- (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 rseed, int entry) +{ + int v2; // esi + int v3; // edi + int v4; // ecx + + v2 = entry; + v3 = rseed; + 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() +{ + char *v1; // ecx + + setloadflag_2 = 0; + if ( QuestStatus(8) ) + { + v1 = "Levels\\L2Data\\Blind2.DUN"; + } + else + { + if ( QuestStatus(9) ) + { + v1 = "Levels\\L2Data\\Blood1.DUN"; + } + else + { + if ( !QuestStatus(14) ) + 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(); + v2 = CreateDungeon(); + if ( !v2 ) + continue; + L2TileFix(); + if ( setloadflag_2 ) + DRLG_L2SetRoom(nSx1, nSy1); + DRLG_L2FloodTVal(); + DRLG_L2TransFix(); + if ( !v13 ) + { + v3 = DRLG_L2PlaceMiniSet((char *)USTAIRS, 1, 1, -1, -1, 1, 0); + v1 = v3; + if ( !v3 ) + goto LABEL_21; + v4 = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 0, 1); + v1 = v4; + if ( !v4 || currlevel != 5 ) + goto LABEL_21; + v5 = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 0, 6); +LABEL_20: + v1 = v5; +LABEL_21: + ViewY -= 2; + continue; + } + v6 = DRLG_L2PlaceMiniSet((char *)USTAIRS, 1, 1, -1, -1, 0, 0); + v1 = v6; + if ( v13 != 1 ) + { + if ( !v6 ) + goto LABEL_21; + v9 = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 0, 1); + v1 = v9; + if ( !v9 || currlevel != 5 ) + goto LABEL_21; + v5 = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 1, 6); + goto LABEL_20; + } + if ( v6 ) + { + v7 = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 1, 1); + v1 = v7; + if ( v7 ) + { + if ( currlevel == 5 ) + { + 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 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 + 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 = 0; /* 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 ( setview == 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 rndper) +{ + 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 = rndper; + 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)&SPATSL2[2].s1 ); + 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) -------------------------------------------------------- +bool __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 + bool v8; // eax + int v9; // edi + int v10; // esi + signed int v12; // [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; + v12 = 10; + } + else + { + if ( currlevel != 7 || !quests[8]._qactive ) + goto LABEL_12; + v12 = 15; + } + v0 = v12; + v1 = v12; + } + 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 ); + v8 = DL2_FillVoids(); + if ( v8 ) + { + v9 = 0; + do + { + v10 = 0; + do + DoPatternCheck(v10++, v9); + while ( v10 < 40 ); + ++v9; + } + while ( v9 < 40 ); + v8 = 1; + } + return v8; +} + +//----- (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) -------------------------------------------------------- +bool __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 + bool v10; // eax + int v11; // esi + signed int v12; // ecx + signed int v13; // edi + signed int v14; // edx + signed int v15; // eax + int v16; // ebx + char *v17; // eax + signed int v18; // edx + int k; // eax + int v20; // ebx + int v21; // ebx + char *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 = predungeon[-1][v7]; // *((unsigned char *)&VR1 + v7); + if ( (_BYTE)v8 == 32 && predungeon[1][v7] == 46 ) + { + if ( predungeon[0][v7 + 39] != 46 + || predungeon[1][v7 + 1] != 46 + || predungeon[-1][v7 - 1] != 32 // *((_BYTE *)&HR3 + v7 + 3) != 32 + || predungeon[-1][v7 + 1] != 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 ( predungeon[-1][v7 - 1] != 46 // *((_BYTE *)&HR3 + v7 + 3) != 46 + || predungeon[-1][v7 + 1] != 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 = predungeon[0][v7 - 1]; /* *((_BYTE *)&nRoomCnt + v7 + 3); */ + if ( v9 != 32 || predungeon[0][v7 + 1] != 46 ) + { + if ( predungeon[0][v7 + 1] != 32 + || v9 != 46 + || predungeon[-1][v7 - 1] != 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 + && predungeon[-1][v7 - 1] == 32 // *((_BYTE *)&HR3 + v7 + 3) == 32 + && predungeon[0][v7 + 39] == 32 ) + { + x2f = 1; + x1f = 1; + y1f = 1; + v10 = DL2_Cont(1, 1, 1, 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 = predungeon[v11]; + if ( v22[v21] != 32 ) + v13 = 0; + if ( 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 ( predungeon[v11][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 = predungeon[x2]; + if ( v17[y1] != 32 ) + v13 = 0; + if ( 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 ( predungeon[v16][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; + } + return DL2_NumNoChar() <= 700; +} + +//----- (0040F9B1) -------------------------------------------------------- +bool __fastcall DL2_Cont(bool x1f, bool y1f, bool x2f, bool 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 ) + { + predungeon[x1][i] = 35; + predungeon[x2][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 + char *v6; // eax + int v7; // edi + int v8; // eax + int v9; // ecx + char *v10; // edx + char *v11; // esi + + v4 = x1 + 1; + if ( x1 + 1 < x2 ) + { + v5 = &predungeon[v4][y2 + 1]; + v6 = &predungeon[v4][y1 - 1]; // (char *)&nRoomCnt + 40 * v4 + y1 + 3; /* check */ + 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 = predungeon[x2 + 1]; + do + { + v11 = &predungeon[v9 - 1][v8]; // (char *)&VR1 + v9 * 40 + v8; + if ( *v11 == 46 && predungeon[v9 + 1][v8] == 46 ) + predungeon[v9][v8] = 46; + if ( v10[v8 - 80] == 46 && v10[v8] == 46 ) + v10[v8 - 40] = 46; + if ( *v11 == 68 ) + *v11 = 46; + if ( v10[v8] == 68 ) + 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] ); +} diff --git a/Source/drlg_l2.h b/Source/drlg_l2.h new file mode 100644 index 0000000..7f9862f --- /dev/null +++ b/Source/drlg_l2.h @@ -0,0 +1,179 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//drlg_l2 +extern int nSx1; +extern int nSx2; // weak +extern int nSy1; +extern int nSy2; // weak +extern int nRoomCnt; +extern char predungeon[40][40]; +extern ROOMNODE RoomList[81]; +extern HALLNODE *pHallList; + +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 rseed, 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 setview, int ldir); +void __fastcall DRLG_L2PlaceRndSet(char *miniset, int rndper); +void __cdecl DRLG_L2Subs(); +void __cdecl DRLG_L2Shadows(); +void __fastcall DRLG_L2SetRoom(int rx1, int ry1); +void __cdecl L2TileFix(); +bool __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); +bool __cdecl DL2_FillVoids(); +bool __fastcall DL2_Cont(bool x1f, bool y1f, bool x2f, bool 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(); + +/* 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]; \ No newline at end of file diff --git a/Source/drlg_l3.cpp b/Source/drlg_l3.cpp new file mode 100644 index 0000000..83ca482 --- /dev/null +++ b/Source/drlg_l3.cpp @@ -0,0 +1,3044 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +char lavapool; // weak +int abyssx; // weak +int lockoutcnt; // weak +char lockout[40][40]; + +unsigned char L3ConvTbl[16] = { 8, 11, 3, 10, 1, 9, 12, 12, 6, 13, 4, 13, 2, 14, 5, 7 }; +unsigned char L3UP[20] = { 3, 3, 8, 8, 0, 10, 10, 0, 7, 7, 0, 51, 50, 0, 48, 49, 0, 0, 0, 0 }; +unsigned char L3DOWN[20] = { 3, 3, 8, 9, 7, 8, 9, 7, 0, 0, 0, 0, 47, 0, 0, 46, 0, 0, 0, 0 }; +unsigned char L3HOLDWARP[20] = { 3, 3, 8, 8, 0, 10, 10, 0, 7, 7, 0, 125, 125, 0, 125, 125, 0, 0, 0, 0 }; +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 }; +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 }; +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 }; +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 }; +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 }; +unsigned char L3TITE8[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 52, 0, 0, 0, 0 }; +unsigned char L3TITE9[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 53, 0, 0, 0, 0 }; +unsigned char L3TITE10[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 54, 0, 0, 0, 0 }; +unsigned char L3TITE11[20] = { 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 67, 0, 0, 0, 0 }; +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] = +{ + 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 +}; +unsigned char L3SpawnTbl1[15] = { 0u, 10u, 67u, 5u, 44u, 6u, 9u, 0u, 0u, 28u, 131u, 6u, 9u, 10u, 5u }; /* local spawntable? */ +unsigned char L3SpawnTbl2[15] = { 0u, 10u, 3u, 5u, 12u, 6u, 9u, 0u, 0u, 12u, 3u, 6u, 9u, 10u, 5u }; /* local spawntable? */ +unsigned char L3PoolSub[15] = { 0u, 35u, 26u, 36u, 25u, 29u, 34u, 7u, 33u, 28u, 27u, 37u, 32u, 31u, 30u }; /* local poolsub? */ + +//----- (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) -------------------------------------------------------- +int __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 v7; // ebx + int v8; // edi + int v9; // ecx + signed int v10; // eax + unsigned char v11; // dl + signed int v12; // [esp+Ch] [ebp-Ch] + signed int v13; // [esp+Ch] [ebp-Ch] + signed int v14; // [esp+10h] [ebp-8h] + int v15; // [esp+14h] [ebp-4h] + + v0 = random(0, 29); + v1 = 0; + v15 = random(0, 29); + v12 = 0; + while ( 1 ) + { + if ( v12 >= 200 ) + return 1; + ++v12; + v14 = 1; + v2 = 2; + do + { + if ( v14 != 1 ) + break; + v3 = 0; + v4 = v15 + v1 + 40 * v0; + do + { + if ( v14 != 1 ) + break; + v5 = L3ANVIL[v2]; + if ( v5 && dungeon[0][v4] != v5 ) + v14 = 0; + if ( dflags[0][v4] ) + v14 = 0; + ++v2; + ++v3; + v4 += 40; + } + while ( v3 < 11 ); + ++v1; + } + while ( v1 < 11 ); + v1 = 0; + if ( v14 ) + break; + if ( ++v0 == 29 ) + { + v0 = 0; + if ( ++v15 == 29 ) + v15 = 0; + } + } + if ( v12 >= 200 ) + return 1; + v13 = 11; + v7 = 123; + v8 = v15 + 40 * v0; + do + { + v9 = v8; + v10 = 11; + do + { + v11 = L3ANVIL[v7]; + if ( v11 ) + dungeon[0][v9] = v11; + dflags[0][v9] |= 0x80u; + ++v7; + v9 += 40; + --v10; + } + while ( v10 ); + ++v8; + --v13; + } + while ( v13 ); + setpc_y = v15; + setpc_w = 11; + setpc_h = 11; + setpc_x = v0; + return 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) -------------------------------------------------------- +bool __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); + return v0 == lockoutcnt; +} +// 528380: using guessed type int lockoutcnt; + +//----- (004103A1) -------------------------------------------------------- +void __fastcall CreateL3Dungeon(int rseed, 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(rseed); + 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 x1; // esi + int y1; // eax + int x2; // edi + int y2; // eax + int found; // eax + int genok; // eax + signed int i; // ecx + signed int j; // esi + bool v24; // [esp-8h] [ebp-20h] + + lavapool = 0; + do + { + do + { + do + { + InitL3Dungeon(); + x1 = random(0, 20) + 10; + y1 = random(0, 20); + DRLG_L3FillRoom(x1, y1 + 10, x1 + 2, y1 + 12); + DRLG_L3CreateBlock(x1, y1 + 10, 2, 0); + DRLG_L3CreateBlock(x1 + 2, y1 + 10, 2, 1); + DRLG_L3CreateBlock(x1, y1 + 12, 2, 2); + DRLG_L3CreateBlock(x1, y1 + 10, 2, 3); + + if ( QuestStatus(10) ) + { + x2 = random(0, 10) + 10; + y2 = random(0, 10); + DRLG_L3FloorArea(x2, y2 + 10, x2 + 12, y2 + 22); + } + DRLG_L3FillDiags(); + DRLG_L3FillSingles(); + DRLG_L3FillStraights(); + DRLG_L3FillDiags(); + DRLG_L3Edges(); + if ( DRLG_L3GetFloorArea() < 600 ) + found = 0; + else + found = DRLG_L3Lockout(); + } + while ( !found ); + DRLG_L3MakeMegas(); + if ( !entry ) + { + genok = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 1, 0); + if ( genok ) + continue; + genok = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 0, 1); + if ( genok ) + continue; + if ( currlevel != 9 ) + goto LABEL_24; + genok = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, 0, 6); + goto LABEL_23; + } + genok = DRLG_L3PlaceMiniSet(L3UP, 1, 1, -1, -1, 0, 0); + if ( entry == 1 ) + { + if ( genok ) + continue; + genok = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 1, 1); + ViewX += 2; + ViewY -= 2; + if ( genok ) + continue; + if ( currlevel != 9 ) + goto LABEL_24; + v24 = 0; +LABEL_22: + genok = DRLG_L3PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, v24, 6); +LABEL_23: + if ( genok ) + continue; + goto LABEL_24; + } + if ( genok ) + continue; + genok = DRLG_L3PlaceMiniSet(L3DOWN, 1, 1, -1, -1, 0, 1); + if ( genok ) + continue; + if ( currlevel == 9 ) + { + v24 = 1; + goto LABEL_22; + } +LABEL_24: + if ( !QuestStatus(10) ) + break; + genok = DRLG_L3Anvil(); + } + while ( genok == 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(); + + if ( QuestStatus(10) ) + { + 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(i = 0; i < 40; i++) + { + for(j = 0; j < 40; j++) + pdungeon[i][j] = dungeon[i][j]; + } + + DRLG_Init_Globals(); +} +// 528378: using guessed type char lavapool; + +//----- (0041087F) -------------------------------------------------------- +void __cdecl InitL3Dungeon() +{ + int i; // edx + int j; // ecx + + memset(dungeon, 0, 0x640u); + + for(i = 0; i < 40; i++) + { + for(j = 0; j < 40; j++) + { + dungeon[i][j] = 0; + dflags[i][j] = 0; + } + } +} + +//----- (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 = 0; /* 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)&dungeon[40][39] ); +} + +//----- (00410EFC) -------------------------------------------------------- +int __cdecl DRLG_L3GetFloorArea() +{ + int gfa; // eax + int i; // edx + int j; // esi + + gfa = 0; + + for(i = 0; i < 40; i++) + { + for(j = 0; j < 40; j++) + gfa += dungeon[i][j]; + } + + return gfa; +} + +//----- (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)&dungeon[40][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 river[3][100]; // [esp+Ch] [ebp-4E8h] + int v36; // [esp+4BCh] [ebp-38h] + int v37; // [esp+4C0h] [ebp-34h] + int v38; // [esp+4C4h] [ebp-30h] + int v39; // [esp+4C8h] [ebp-2Ch] + int v40; // [esp+4CCh] [ebp-28h] + int v41; // [esp+4D0h] [ebp-24h] + int v42; // [esp+4D4h] [ebp-20h] + int v43; // [esp+4D8h] [ebp-1Ch] + int v44; // [esp+4DCh] [ebp-18h] + int v45; // [esp+4E0h] [ebp-14h] + int v46; // [esp+4E4h] [ebp-10h] + int v47; // [esp+4E8h] [ebp-Ch] + int v48; // [esp+4ECh] [ebp-8h] + int max; // [esp+4F0h] [ebp-4h] + + v0 = 0; + v39 = 0; + v41 = 0; + while ( v39 < 4 ) + { + v47 = 0; + do + { + if ( v41 >= 200 ) + { + v5 = max; + break; + } + ++v41; + 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: + v48 = 3; + v42 = 2; + river[2][0] = 40; + break; + case 0x1A: + v48 = 0; + v42 = 1; + river[2][0] = 38; + break; + case 0x1B: + v42 = 0; + v48 = 1; + river[2][0] = 41; + break; + case 0x1C: + v48 = 2; + v42 = 3; + river[2][0] = 39; + break; + } + v43 = 0; + max = 1; + v5 = 1; + river[0][0] = v1; + river[1][0] = v2; + v46 = 4; + v45 = 40 * v1; + while ( v5 < 100 ) + { + v38 = v1; + v36 = v45; + v37 = v2; + if ( v43 ) + { + v48 = ((_BYTE)v48 + 1) & 3; + v7 = v48; + } + else + { + v6 = random(0, 4); + v5 = max; + v7 = v6; + v48 = v6; + } + while ( 1 ) + { + ++v43; + if ( v7 != v42 && v7 != v46 ) + break; + v7 = ((_BYTE)v7 + 1) & 3; + } + v48 = 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; + v45 += 40; +LABEL_41: + if ( v7 == 3 && v1 > 0 ) + { + --v1; + v45 -= 40; + } + } +LABEL_44: + if ( dungeon[0][v45 + v2] == 7 ) + { + v43 = 0; + if ( v7 < 2 ) + { + v8 = random(0, 2); + v5 = max; + river[2][max] = v8 + 17; + } + if ( v7 > 1 ) + { + v9 = random(0, 2); + v5 = max; + river[2][max] = v9 + 15; + } + v10 = v40; + river[0][v5] = v1; + river[1][v5++] = v2; + max = v5; + if ( v7 || v10 != 2 ) + { + if ( v7 != 3 ) + goto LABEL_58; + if ( v10 != 1 ) + goto LABEL_70; + } + if ( v5 > 2 ) + river[1][v5 + 98] = 22; + if ( !v7 ) + { + v46 = 1; +LABEL_59: + if ( v10 == 3 ) + goto LABEL_62; + goto LABEL_60; + } + v46 = 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 ) + river[1][v5 + 98] = 21; + if ( !v7 ) + { + v46 = 1; + goto LABEL_83; + } + v46 = 3; +LABEL_67: + if ( v7 != 1 || v10 != 2 ) + { + if ( v7 != 3 ) + goto LABEL_76; +LABEL_70: + if ( v10 ) + goto LABEL_83; + } + if ( v5 > 2 ) + river[1][v5 + 98] = 20; + if ( v7 == 1 ) + { + v46 = 0; + goto LABEL_77; + } + v46 = 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 ) + river[1][v5 + 98] = 19; + v46 = v7 != 1 ? 3 : 0; +LABEL_83: + v40 = v7; + } + else + { + v1 = v38; + v2 = v37; + v45 = v36; + if ( v43 >= 4 ) + break; + } + } + if ( v48 ) + { + v13 = v40; + goto LABEL_94; + } + v11 = &dungeon[v1][v2]; + if ( *(v11 - 1) == 10 && *(v11 - 2) == 8 ) + { + v12 = v5; + river[1][v12] = v2 - 1; + v13 = v40; + v14 = v40 == 2; + river[0][v12] = v1; + river[2][v12] = 24; + if ( v14 ) + river[1][v12 + 99] = 22; + if ( v13 == 3 ) + river[1][v12 + 99] = 21; + v47 = 1; +LABEL_94: + if ( v48 == 1 ) + { + v15 = v2 + 40 * v1; + if ( dungeon[0][v15 + 1] == 2 && dungeon[0][v15 + 2] == 8 ) + { + v16 = v5; + river[0][v16] = v1; + river[1][v16] = v2 + 1; + river[2][v16] = 42; + if ( v13 == 2 ) + river[1][v16 + 99] = 20; + if ( v13 == 3 ) + river[1][v16 + 99] = 19; + v47 = 1; + goto LABEL_102; + } + } + else + { +LABEL_102: + if ( v48 == 2 ) + { + v17 = v2 + 40 * v1; + if ( dungeon[1][v17] != 4 || dungeon[2][v17] != 8 ) + goto LABEL_118; + v18 = v5; + river[0][v18] = v1 + 1; + river[1][v18] = v2; + river[2][v18] = 43; + if ( !v13 ) + river[1][v18 + 99] = 19; + if ( v13 == 1 ) + river[1][v18 + 99] = 21; + v47 = 1; + } + if ( v48 == 3 + && dungeon[v1-1][v2] == 9 // *((_BYTE *)&dMonster[111][10 * v1 + 102] + v2) == 9 /* check */ + && dungeon[0][8 * (5 * v1 - 10) + v2] == 8 ) + { + v19 = v5; + river[0][v19] = v1 - 1; + river[1][v19] = v2; + river[2][v19] = 23; + if ( !v13 ) + river[1][v19 + 99] = 20; + if ( v13 == 1 ) + river[1][v19 + 99] = 22; + v47 = 1; + } + } + } +LABEL_118: + v0 = 0; + } + while ( !v47 ); + if ( v47 == 1 && v5 >= 7 ) + { + v20 = 0; + v47 = 0; +LABEL_124: + while ( v47 < 30 ) + { + ++v47; + v21 = random(0, max); + v44 = v21; + v22 = v21; + v23 = river[2][v22]; + if ( v23 == 15 || v23 == 16 ) + { + v24 = river[1][v22] + 40 * river[0][v22]; + if ( dungeon[0][v24 - 1] == 7 && dungeon[0][v24 + 1] == 7 ) /* *((_BYTE *)&dMonster[111][111] + v24 + 3) check */ + v20 = 1; + } + if ( v23 == 17 || v23 == 18 ) + { + v25 = river[1][v22] + 40 * river[0][v22]; + if ( dungeon[-1][v25] == 7 && dungeon[1][v25] == 7 ) /* *((_BYTE *)&dMonster[111][102] + v25) check */ + v20 = 2; + } + v26 = 0; + if ( max > 0 ) + { + while ( 1 ) + { + if ( !v20 ) + goto LABEL_124; + if ( v20 != 1 ) + goto LABEL_142; + v27 = river[1][v22]; + v28 = river[1][v26]; + if ( (v27 - 1 == v28 || v27 + 1 == v28) && river[0][v22] == river[0][v26] ) + break; +LABEL_147: + if ( ++v26 >= max ) + goto LABEL_148; + } + v20 = 0; +LABEL_142: + if ( v20 == 2 ) + { + v29 = river[0][v22]; + v30 = river[0][v26]; + if ( (v29 - 1 == v30 || v29 + 1 == v30) && river[1][v22] == river[1][v26] ) + v20 = 0; + } + goto LABEL_147; + } +LABEL_148: + if ( v20 ) + break; + } + v0 = 0; + if ( v20 ) + { + river[2][v44] = v20 == 1 ? 44 : 45; + v31 = max; + ++v39; + v44 = 0; + if ( max >= 0 ) + { + do + { + v32 = v44++; + v34 = __OFSUB__(v44, v31); + v14 = v44 == v31; + v33 = v44 - v31 < 0; + dungeon[river[0][v32]][river[1][v32]] = river[2][v32]; + } + while ( (unsigned char)(v33 ^ v34) | v14 ); + } + } + } + if ( v41 >= 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) -------------------------------------------------------- +int __fastcall DRLG_L3PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, bool setview, 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 + unsigned char v23; // dl + int v24; // eax + int v25; // edi + char *v26; // edx + unsigned char v27; // bl + unsigned 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 = 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; + } + 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 = (unsigned 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 ( setview == 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 = v11; + v16 = y + 1; + v17 = v16; + for ( dungeon[v15][v16 - 1] = 128; dungeon[x][v17] == 9; ++v17 ) /* check *((_BYTE *)&dMonster[111][2 * v15 + 111] + v16 + 3) */ + ; + 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 ( !SkipThemeRoom(xa, ya) ) + 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) -------------------------------------------------------- +bool __fastcall WoodVertU(int i, int y) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + bool 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) -------------------------------------------------------- +bool __fastcall WoodVertD(int i, int y) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + bool 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) -------------------------------------------------------- +bool __fastcall WoodHorizL(int x, int j) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + bool 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) -------------------------------------------------------- +bool __fastcall WoodHorizR(int x, int j) +{ + int v2; // eax + char v3; // cl + char *v4; // eax + unsigned char v5; // cl + char v6; // al + bool 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); +} diff --git a/Source/drlg_l3.h b/Source/drlg_l3.h new file mode 100644 index 0000000..03fe16e --- /dev/null +++ b/Source/drlg_l3.h @@ -0,0 +1,93 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//drlg_l3 +extern char lavapool; // weak +extern int abyssx; // weak +extern int lockoutcnt; // weak +extern char lockout[40][40]; + +void __cdecl AddFenceDoors(); +void __cdecl FenceDoorFix(); +int __cdecl DRLG_L3Anvil(); +void __cdecl FixL3Warp(); +void __cdecl FixL3HallofHeroes(); +void __fastcall DRLG_L3LockRec(int x, int y); +bool __cdecl DRLG_L3Lockout(); +void __fastcall CreateL3Dungeon(int rseed, 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(); +int __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(); +int __fastcall DRLG_L3PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, bool setview, int ldir); +void __fastcall DRLG_L3PlaceRndSet(unsigned char *miniset, int rndper); +void __cdecl DRLG_L3Wood(); +bool __fastcall WoodVertU(int i, int y); +bool __fastcall WoodVertD(int i, int y); +bool __fastcall WoodHorizL(int x, int j); +bool __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); + +/* data */ +extern unsigned char L3ConvTbl[16]; +extern unsigned char L3UP[20]; +extern unsigned char L3DOWN[20]; +extern unsigned char L3HOLDWARP[20]; +extern unsigned char L3TITE1[34]; +extern unsigned char L3TITE2[34]; +extern unsigned char L3TITE3[34]; +extern unsigned char L3TITE6[42]; +extern unsigned char L3TITE7[42]; +extern unsigned char L3TITE8[20]; +extern unsigned char L3TITE9[20]; +extern unsigned char L3TITE10[20]; +extern unsigned char L3TITE11[20]; +extern unsigned char L3TITE12[6]; +extern unsigned char L3TITE13[6]; +extern unsigned char L3CREV1[6]; +extern unsigned char L3CREV2[6]; +extern unsigned char L3CREV3[6]; +extern unsigned char L3CREV4[6]; +extern unsigned char L3CREV5[6]; +extern unsigned char L3CREV6[6]; +extern unsigned char L3CREV7[6]; +extern unsigned char L3CREV8[6]; +extern unsigned char L3CREV9[6]; +extern unsigned char L3CREV10[6]; +extern unsigned char L3CREV11[6]; +extern unsigned char L3ISLE1[14]; +extern unsigned char L3ISLE2[14]; +extern unsigned char L3ISLE3[14]; +extern unsigned char L3ISLE4[14]; +extern unsigned char L3ISLE5[10]; +extern unsigned char L3XTRA1[4]; +extern unsigned char L3XTRA2[4]; +extern unsigned char L3XTRA3[4]; +extern unsigned char L3XTRA4[4]; +extern unsigned char L3XTRA5[4]; +extern unsigned char L3ANVIL[244]; +extern unsigned char L3SpawnTbl1[15]; /* local spawntable? */ +extern unsigned char L3SpawnTbl2[15]; /* local spawntable? */ +extern unsigned char L3PoolSub[15]; /* local poolsub? */ diff --git a/Source/drlg_l4.cpp b/Source/drlg_l4.cpp new file mode 100644 index 0000000..1edee28 --- /dev/null +++ b/Source/drlg_l4.cpp @@ -0,0 +1,3424 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.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 +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 + +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] = +{ + 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 +}; + +//----- (00412655) -------------------------------------------------------- +void __cdecl DRLG_LoadL4SP() +{ + setloadflag_2 = 0; + if ( QuestStatus(11) ) + { + 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]; /* check */ + 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(bool preflag) +{ + bool 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) -------------------------------------------------------- +bool __fastcall IsDURWall(char d) +{ + bool result; // al + + if ( d == 25 || d == 28 ) + result = 1; + else + result = d == 23; + return result; +} + +//----- (00412948) -------------------------------------------------------- +bool __fastcall IsDLLWall(char dd) +{ + bool 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)&dung[20][0] ); + *(_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 rseed, int entry) +{ + int v2; // esi + + v2 = entry; + SetRndSeed(rseed); + 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 ( (QuestStatus(11) || 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 ( !QuestStatus(11) ) + { + if ( currlevel == 15 ) + { + if ( !v23 ) + { + v10 = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); + if ( v10 ) + { + if ( gbMaxPlayers != 1 || (v11 = L4PENTA, quests[5]._qactive == 2) ) + v11 = L4PENTA2; + v10 = DRLG_L4PlaceMiniSet(v11, 1, 1, -1, -1, 0, 1); + } + goto LABEL_35; + } + v10 = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if ( v10 ) + { + if ( gbMaxPlayers != 1 || (v12 = L4PENTA, quests[5]._qactive == 2) ) + v12 = L4PENTA2; + v10 = DRLG_L4PlaceMiniSet(v12, 1, 1, -1, -1, 1, 1); + } + } + else + { + if ( !v23 ) + { + v10 = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); + if ( v10 ) + { + if ( currlevel != 16 ) + v10 = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1); + goto LABEL_31; + } +LABEL_35: + ++ViewX; + continue; + } + v10 = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if ( v23 != 1 ) + { + if ( v10 ) + { + if ( currlevel != 16 ) + v10 = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1); +LABEL_46: + if ( v10 ) + { + if ( currlevel == 13 ) + { + v22 = 1; +LABEL_34: + v10 = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, v22, 6); + goto LABEL_35; + } + } + } + goto LABEL_35; + } + if ( v10 ) + { + if ( currlevel != 16 ) + v10 = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 1, 1); + if ( v10 && currlevel == 13 ) + v10 = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6); + } + } + ++ViewY; + continue; + } + if ( !v23 ) + { + v10 = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0); +LABEL_31: + if ( !v10 || currlevel != 13 ) + goto LABEL_35; + v22 = 0; + goto LABEL_34; + } + v10 = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0); + if ( v23 != 1 ) + goto LABEL_46; + if ( v10 && currlevel == 13 ) + 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 ( QuestStatus(11) ) + { + 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 ( dungeon[0][v3 + j - 1] != 6 ) // *((_BYTE *)&dMonster[111][111] + v3 + j + 3) != 6 ) /* check */ + 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 ( QuestStatus(11) || 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) -------------------------------------------------------- +bool __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) -------------------------------------------------------- +bool __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 + bool 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 = 0; /* 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() /* check */ +{ + signed int v0; // edi + char *v1; // esi + signed int v2; // ebx + char v6; // al + 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 + { + if ( IsDURWall(*v1) && *(v1 - 1) == 18 ) + { + v6 = *(v16 - 113); + *(v16 - 1) = v6; + *v16 = v6; + } + if ( IsDLLWall(*v1) && v1[40] == 19 ) + { + v10 = *(v16 - 113); + *(v16 - 112) = v10; + *v16 = v10; + } + if ( *v1 == 18 ) + { + v11 = *(v16 - 113); + *(v16 - 1) = v11; + *v16 = v11; + } + if ( *v1 == 19 ) + { + v12 = *(v16 - 113); + *(v16 - 112) = v12; + *v16 = v12; + } + if ( *v1 == 24 ) + { + v13 = *(v16 - 113); + *(v16 - 1) = v13; + *(v16 - 112) = v13; + *v16 = v13; + } + if ( *v1 == 57 ) + { + v14 = *(v16 - 112); + *(v16 - 225) = v14; + *(v16 - 113) = v14; + } + if ( *v1 == 53 ) + { + v15 = *(v16 - 1); + *(v16 - 114) = v15; + *(v16 - 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 ); +} diff --git a/Source/drlg_l4.h b/Source/drlg_l4.h new file mode 100644 index 0000000..d483a44 --- /dev/null +++ b/Source/drlg_l4.h @@ -0,0 +1,75 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//drlg_l4 +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 int 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 char L4dungeon[80][80]; +extern char dung[20][20]; +//int dword_52A4DC; // weak + +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(bool preflag); +bool __fastcall IsDURWall(char d); +bool __fastcall IsDLLWall(char dd); +void __cdecl L4FixRim(); +void __cdecl DRLG_L4GeneralFix(); +void __fastcall CreateL4Dungeon(int rseed, 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); +bool __fastcall L4checkRoom(int x, int y, int width, int height); +bool __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(); + +/* data */ +extern unsigned char L4ConvTbl[16]; +extern unsigned char L4USTAIRS[42]; +extern unsigned char L4TWARP[42]; +extern unsigned char L4DSTAIRS[52]; +extern unsigned char L4PENTA[52]; +extern unsigned char L4PENTA2[52]; +extern unsigned char L4BTYPES[140]; \ No newline at end of file diff --git a/Source/dthread.cpp b/Source/dthread.cpp new file mode 100644 index 0000000..348adaa --- /dev/null +++ b/Source/dthread.cpp @@ -0,0 +1,221 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int dthread_cpp_init_value; // weak +static CRITICAL_SECTION sgMemCrit; // idb +unsigned int glpDThreadId; // idb +TMegaPkt *sgpInfoHead; /* may not be right struct */ +char byte_52A508; // weak +HANDLE sghWorkToDoEvent; // idb + +int dthread_inf = 0x7F800000; // weak + +/* rdata */ +static HANDLE sghThread = (HANDLE)0xFFFFFFFF; // idb + +//----- (0041509D) -------------------------------------------------------- +struct dthread_cpp_init_1 +{ + dthread_cpp_init_1() + { + dthread_cpp_init_value = dthread_inf; + } +} _dthread_cpp_init_1; +// 47A460: using guessed type int dthread_inf; +// 52A4E0: using guessed type int dthread_cpp_init_value; + +//----- (004150A8) -------------------------------------------------------- +struct dthread_cpp_init_2 +{ + dthread_cpp_init_2() + { + dthread_init_mutex(); + dthread_cleanup_mutex_atexit(); + } +} _dthread_cpp_init_2; + +//----- (004150B2) -------------------------------------------------------- +void __cdecl dthread_init_mutex() +{ + InitializeCriticalSection(&sgMemCrit); +} + +//----- (004150BE) -------------------------------------------------------- +void __cdecl dthread_cleanup_mutex_atexit() +{ + atexit(dthread_cleanup_mutex); +} + +//----- (004150CA) -------------------------------------------------------- +void __cdecl dthread_cleanup_mutex() +{ + DeleteCriticalSection(&sgMemCrit); +} + +//----- (004150D6) -------------------------------------------------------- +void __fastcall dthread_remove_player(int pnum) +{ + int v1; // edi + TMegaPkt *i; // eax + + v1 = pnum; + EnterCriticalSection(&sgMemCrit); + for ( i = sgpInfoHead; i; i = i->pNext ) + { + if ( i->dwSpaceLeft == v1 ) + i->dwSpaceLeft = 4; + } + LeaveCriticalSection(&sgMemCrit); +} + +//----- (00415109) -------------------------------------------------------- +void __fastcall dthread_send_delta(int pnum, int cmd, void *pbSrc, int dwLen) +{ + char v4; // bl + TMegaPkt *v5; // eax + TMegaPkt *v6; // esi + TMegaPkt *v7; // eax + TMegaPkt **v8; // ecx + int v9; // [esp+4h] [ebp-4h] + + v4 = cmd; + v9 = pnum; + if ( gbMaxPlayers != 1 ) + { + v5 = (TMegaPkt *)DiabloAllocPtr(dwLen + 20); + v6 = v5; + v5->pNext = 0; + v5->dwSpaceLeft = v9; + v5->data[0] = v4; + *(_DWORD *)&v5->data[4] = dwLen; + memcpy(&v5->data[8], pbSrc, dwLen); + EnterCriticalSection(&sgMemCrit); + v7 = sgpInfoHead; + v8 = &sgpInfoHead; + while ( v7 ) + { + v8 = &v7->pNext; + v7 = v7->pNext; + } + *v8 = v6; + SetEvent(sghWorkToDoEvent); + LeaveCriticalSection(&sgMemCrit); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00415186) -------------------------------------------------------- +void __cdecl dthread_start() +{ + char *v0; // eax + char *v1; // eax + + if ( gbMaxPlayers != 1 ) + { + sghWorkToDoEvent = CreateEventA(NULL, TRUE, FALSE, NULL); + if ( !sghWorkToDoEvent ) + { + v0 = GetLastErr(); + TermMsg("dthread:1\n%s", v0); + } + byte_52A508 = 1; + sghThread = (HANDLE)_beginthreadex(NULL, 0, dthread_handler, NULL, 0, &glpDThreadId); + 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 + TMegaPkt *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(&sgMemCrit); + v2 = sgpInfoHead; + if ( sgpInfoHead ) + sgpInfoHead = sgpInfoHead->pNext; + else + ResetEvent(sghWorkToDoEvent); + LeaveCriticalSection(&sgMemCrit); + if ( v2 ) + { + v3 = v2->dwSpaceLeft; + if ( v3 != 4 ) + multi_send_zero_packet(v3, v2->data[0], &v2->data[8], *(_DWORD *)&v2->data[4]); + v4 = 1000 * *(_DWORD *)&v2->data[4] / (unsigned int)gdwDeltaBytesSec; + if ( v4 >= 1 ) + v4 = 1; + mem_free_dbg(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 + TMegaPkt *v1; // eax + TMegaPkt *v2; // esi + + if ( sghWorkToDoEvent ) + { + byte_52A508 = 0; + SetEvent(sghWorkToDoEvent); + if ( sghThread != (HANDLE)-1 && glpDThreadId != GetCurrentThreadId() ) + { + if ( WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1 ) + { + v0 = GetLastErr(); + TermMsg("dthread3:\n(%s)", v0); + } + CloseHandle(sghThread); + sghThread = (HANDLE)-1; + } + CloseHandle(sghWorkToDoEvent); + v1 = sgpInfoHead; + sghWorkToDoEvent = 0; + if ( sgpInfoHead ) + { + do + { + v2 = v1->pNext; + sgpInfoHead = 0; + mem_free_dbg(v1); + v1 = v2; + sgpInfoHead = v2; + } + while ( v2 ); + } + } +} +// 52A508: using guessed type char byte_52A508; diff --git a/Source/dthread.h b/Source/dthread.h new file mode 100644 index 0000000..1619b3d --- /dev/null +++ b/Source/dthread.h @@ -0,0 +1,31 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//dthread +extern int dthread_cpp_init_value; // weak +extern unsigned int glpDThreadId; // idb +extern TMegaPkt *sgpInfoHead; /* may not be right struct */ +extern char byte_52A508; // weak +extern HANDLE sghWorkToDoEvent; // idb + +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 pnum); +void __fastcall dthread_send_delta(int pnum, int cmd, void *pbSrc, int dwLen); +void __cdecl dthread_start(); +unsigned int __stdcall dthread_handler(void *a1); +void __cdecl dthread_cleanup(); + +/* data */ +extern int dthread_inf; // weak diff --git a/Source/dx.cpp b/Source/dx.cpp new file mode 100644 index 0000000..67e1906 --- /dev/null +++ b/Source/dx.cpp @@ -0,0 +1,320 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +void *sgpBackBuf; +int dx_cpp_init_value; // weak +IDirectDraw *lpDDInterface; +IDirectDrawPalette *lpDDPalette; // idb +int sgdwLockCount; +Screen *gpBuffer; +IDirectDrawSurface *lpDDSBackBuf; +IDirectDrawSurface *lpDDSPrimary; +static CRITICAL_SECTION sgMemCrit; +char gbBackBuf; // weak +char gbEmulate; // weak +HMODULE ghDiabMod; // idb + +int dx_inf = 0x7F800000; // weak + +//----- (00415367) -------------------------------------------------------- +struct dx_cpp_init_1 +{ + dx_cpp_init_1() + { + dx_cpp_init_value = dx_inf; + } +} _dx_cpp_init_1; +// 47A464: using guessed type int dx_inf; +// 52A514: using guessed type int dx_cpp_init_value; + +//----- (00415372) -------------------------------------------------------- +struct dx_cpp_init_2 +{ + dx_cpp_init_2() + { + dx_init_mutex(); + dx_cleanup_mutex_atexit(); + } +} _dx_cpp_init_2; + +//----- (0041537C) -------------------------------------------------------- +void __cdecl dx_init_mutex() +{ + InitializeCriticalSection(&sgMemCrit); +} + +//----- (00415388) -------------------------------------------------------- +void __cdecl dx_cleanup_mutex_atexit() +{ + atexit(dx_cleanup_mutex); +} + +//----- (00415394) -------------------------------------------------------- +void __cdecl dx_cleanup_mutex() +{ + DeleteCriticalSection(&sgMemCrit); +} + +//----- (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, SW_SHOWNORMAL); + v2 = NULL; + if ( gbEmulate ) + v2 = (GUID *)DDCREATE_EMULATIONONLY; + v3 = dx_DirectDrawCreate(v2, &lpDDInterface, NULL); + if ( v3 ) + TermDlg(104, v3, "C:\\Src\\Diablo\\Source\\dx.cpp", 149); + fullscreen = 1; + v4 = IDirectDraw_SetCooperativeLevel(lpDDInterface, v1, DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT|DDSCL_FULLSCREEN); + if ( v4 == DDERR_EXCLUSIVEMODEALREADYSET ) + { + MI_Dummy(0); // v5 + } + else if ( v4 ) + { + TermDlg(104, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 170); + } + if ( IDirectDraw_SetDisplayMode(lpDDInterface, 640, 480, 8) ) + { + v6 = GetSystemMetrics(SM_CXSCREEN); + v7 = GetSystemMetrics(SM_CYSCREEN); + v8 = IDirectDraw_SetDisplayMode(lpDDInterface, v6, v7, 8); + if ( v8 ) + TermDlg(104, v8, "C:\\Src\\Diablo\\Source\\dx.cpp", 183); + } + dx_create_primary_surface(); + palette_init(); + GdiSetBatchLimit(1); + dx_create_back_buffer(); + SDrawManualInitialize(hWnda, lpDDInterface, lpDDSPrimary, 0, 0, lpDDSBackBuf, lpDDPalette, 0); +} +// 484364: using guessed type int fullscreen; +// 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 + DDSURFACEDESC v4; // [esp+Ch] [ebp-70h] + DDSCAPS v5; // [esp+78h] [ebp-4h] + + v0 = IDirectDrawSurface_GetCaps(lpDDSPrimary, &v5); + if ( v0 ) + DDErrDlg(v0, 59, "C:\\Src\\Diablo\\Source\\dx.cpp"); + if ( !gbBackBuf ) + { + v4.dwSize = 108; + v1 = IDirectDrawSurface_Lock(lpDDSPrimary, NULL, &v4, DDLOCK_WRITEONLY|DDLOCK_WAIT, NULL); + if ( !v1 ) + { + IDirectDrawSurface_Unlock(lpDDSPrimary, NULL); + sgpBackBuf = DiabloAllocPtr(0x7B000); + return; + } + if ( v1 != DDERR_CANTLOCKSURFACE ) + TermDlg(104, v1, "C:\\Src\\Diablo\\Source\\dx.cpp", 81); + } + memset(&v4, 0, 0x6Cu); + v4.dwWidth = 768; + v4.lPitch = 768; + v4.dwSize = 108; + v4.dwFlags = DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS; + v4.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN; + v4.dwHeight = 656; + v4.ddpfPixelFormat.dwSize = 32; + v2 = IDirectDrawSurface_GetPixelFormat(lpDDSPrimary, &v4.ddpfPixelFormat); + if ( v2 ) + TermDlg(104, v2, "C:\\Src\\Diablo\\Source\\dx.cpp", 94); + v3 = IDirectDraw_CreateSurface(lpDDInterface, &v4, &lpDDSBackBuf, NULL); + 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 + DDSURFACEDESC v1; // [esp+0h] [ebp-6Ch] + + memset(&v1, 0, 0x6Cu); + v1.dwSize = 108; + v1.dwFlags = DDSD_CAPS; + v1.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + v0 = IDirectDraw_CreateSurface(lpDDInterface, &v1, &lpDDSPrimary, NULL); + 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 ( !ghDiabMod ) + { + ghDiabMod = LoadLibraryA("ddraw.dll"); + if ( !ghDiabMod ) + { + v4 = GetLastError(); + TermDlg(107, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 122); + } + } + v5 = GetProcAddress(ghDiabMod, "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 + DDSURFACEDESC v2; // [esp+0h] [ebp-6Ch] + + EnterCriticalSection(&sgMemCrit); + v0 = (Screen *)sgpBackBuf; + if ( sgpBackBuf ) + goto LABEL_8; + if ( lpDDSBackBuf ) + { + if ( sgdwLockCount ) + goto LABEL_9; + v2.dwSize = 108; + v1 = IDirectDrawSurface_Lock(lpDDSBackBuf, NULL, &v2, DDLOCK_WAIT, NULL); + if ( v1 ) + DDErrDlg(v1, 235, "C:\\Src\\Diablo\\Source\\dx.cpp"); + v0 = (Screen *)v2.lpSurface; + screen_buf_end += (int)v2.lpSurface; +LABEL_8: + gpBuffer = v0; + goto LABEL_9; + } + Sleep(20000); + 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, NULL); + if ( v1 ) + DDErrDlg(v1, 273, "C:\\Src\\Diablo\\Source\\dx.cpp"); + } + } + LeaveCriticalSection(&sgMemCrit); +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (004157A0) -------------------------------------------------------- +void __cdecl dx_cleanup() +{ + void *v0; // ecx + + if ( ghMainWnd ) + ShowWindow(ghMainWnd, SW_HIDE); + SDrawDestroy(); + EnterCriticalSection(&sgMemCrit); + if ( sgpBackBuf ) + { + v0 = sgpBackBuf; + sgpBackBuf = 0; + mem_free_dbg(v0); + } + else if ( lpDDSBackBuf ) + { + IDirectDrawSurface_Release(lpDDSBackBuf); + lpDDSBackBuf = 0; + } + sgdwLockCount = 0; + gpBuffer = 0; + LeaveCriticalSection(&sgMemCrit); + if ( lpDDSPrimary ) + { + IDirectDrawSurface_Release(lpDDSPrimary); + lpDDSPrimary = 0; + } + if ( lpDDPalette ) + { + IDirectDrawPalette_Release(lpDDPalette); + lpDDPalette = 0; + } + if ( lpDDInterface ) + { + IDirectDraw_Release(lpDDInterface); + lpDDInterface = 0; + } +} + +//----- (00415848) -------------------------------------------------------- +void __cdecl dx_reinit() +{ + int v0; // esi + + EnterCriticalSection(&sgMemCrit); + ClearCursor(); + v0 = sgdwLockCount; + while ( sgdwLockCount ) + dx_unlock_mutex(); + dx_cleanup(); + drawpanflag = 255; + dx_init(ghMainWnd); + for ( ; v0; --v0 ) + dx_lock_mutex(); + LeaveCriticalSection(&sgMemCrit); +} +// 52571C: using guessed type int drawpanflag; diff --git a/Source/dx.h b/Source/dx.h new file mode 100644 index 0000000..45adf4a --- /dev/null +++ b/Source/dx.h @@ -0,0 +1,44 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//dx +extern void *sgpBackBuf; +extern int dx_cpp_init_value; // weak +extern IDirectDraw *lpDDInterface; +extern IDirectDrawPalette *lpDDPalette; // idb +extern int sgdwLockCount; +extern Screen *gpBuffer; +extern IDirectDrawSurface *lpDDSBackBuf; +extern IDirectDrawSurface *lpDDSPrimary; +extern char gbBackBuf; // weak +extern char gbEmulate; // weak +extern HMODULE ghDiabMod; // idb + +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(); + +/* data */ + +extern int dx_inf; // weak diff --git a/Source/effects.cpp b/Source/effects.cpp new file mode 100644 index 0000000..7cf802c --- /dev/null +++ b/Source/effects.cpp @@ -0,0 +1,1444 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int effects_cpp_init_value; // weak +int sfxdelay; // weak +int sfxdnum; +void *sfx_stream; +TSFX *sfx_data_cur; + +int effects_inf = 0x7F800000; // weak +char monster_action_sounds[] = { 'a', 'h', 'd', 's' }; // idb + +/* rdata */ + +TSFX sgSFX[858] = +{ + { 2u, "Sfx\\Misc\\Walk1.wav", NULL }, + { 2u, "Sfx\\Misc\\Walk2.wav", NULL }, + { 2u, "Sfx\\Misc\\Walk3.wav", NULL }, + { 2u, "Sfx\\Misc\\Walk4.wav", NULL }, + { 2u, "Sfx\\Misc\\BFire.wav", NULL }, + { 2u, "Sfx\\Misc\\Fmag.wav", NULL }, + { 2u, "Sfx\\Misc\\Tmag.wav", NULL }, + { 2u, "Sfx\\Misc\\Lghit.wav", NULL }, + { 2u, "Sfx\\Misc\\Lghit1.wav", NULL }, + { 2u, "Sfx\\Misc\\Swing.wav", NULL }, + { 2u, "Sfx\\Misc\\Swing2.wav", NULL }, + { 2u, "Sfx\\Misc\\Dead.wav", NULL }, + { 1u, "Sfx\\Misc\\Questdon.wav", NULL }, + { 2u, "Sfx\\Items\\Armrfkd.wav", NULL }, + { 2u, "Sfx\\Items\\Barlfire.wav", NULL }, + { 2u, "Sfx\\Items\\Barrel.wav", NULL }, + { 2u, "Sfx\\Items\\Bhit.wav", NULL }, + { 2u, "Sfx\\Items\\Bhit1.wav", NULL }, + { 2u, "Sfx\\Items\\Chest.wav", NULL }, + { 2u, "Sfx\\Items\\Doorclos.wav", NULL }, + { 2u, "Sfx\\Items\\Dooropen.wav", NULL }, + { 2u, "Sfx\\Items\\Flipanvl.wav", NULL }, + { 2u, "Sfx\\Items\\Flipaxe.wav", NULL }, + { 2u, "Sfx\\Items\\Flipblst.wav", NULL }, + { 2u, "Sfx\\Items\\Flipbody.wav", NULL }, + { 2u, "Sfx\\Items\\Flipbook.wav", NULL }, + { 2u, "Sfx\\Items\\Flipbow.wav", NULL }, + { 2u, "Sfx\\Items\\Flipcap.wav", NULL }, + { 2u, "Sfx\\Items\\Flipharm.wav", NULL }, + { 2u, "Sfx\\Items\\Fliplarm.wav", NULL }, + { 2u, "Sfx\\Items\\Flipmag.wav", NULL }, + { 2u, "Sfx\\Items\\Flipmag1.wav", NULL }, + { 2u, "Sfx\\Items\\Flipmush.wav", NULL }, + { 2u, "Sfx\\Items\\Flippot.wav", NULL }, + { 2u, "Sfx\\Items\\Flipring.wav", NULL }, + { 2u, "Sfx\\Items\\Fliprock.wav", NULL }, + { 2u, "Sfx\\Items\\Flipscrl.wav", NULL }, + { 2u, "Sfx\\Items\\Flipshld.wav", NULL }, + { 2u, "Sfx\\Items\\Flipsign.wav", NULL }, + { 2u, "Sfx\\Items\\Flipstaf.wav", NULL }, + { 2u, "Sfx\\Items\\Flipswor.wav", NULL }, + { 2u, "Sfx\\Items\\Gold.wav", NULL }, + { 2u, "Sfx\\Items\\Hlmtfkd.wav", NULL }, + { 2u, "Sfx\\Items\\Invanvl.wav", NULL }, + { 2u, "Sfx\\Items\\Invaxe.wav", NULL }, + { 2u, "Sfx\\Items\\Invblst.wav", NULL }, + { 2u, "Sfx\\Items\\Invbody.wav", NULL }, + { 2u, "Sfx\\Items\\Invbook.wav", NULL }, + { 2u, "Sfx\\Items\\Invbow.wav", NULL }, + { 2u, "Sfx\\Items\\Invcap.wav", NULL }, + { 2u, "Sfx\\Items\\Invgrab.wav", NULL }, + { 2u, "Sfx\\Items\\Invharm.wav", NULL }, + { 2u, "Sfx\\Items\\Invlarm.wav", NULL }, + { 2u, "Sfx\\Items\\Invmush.wav", NULL }, + { 2u, "Sfx\\Items\\Invpot.wav", NULL }, + { 2u, "Sfx\\Items\\Invring.wav", NULL }, + { 2u, "Sfx\\Items\\Invrock.wav", NULL }, + { 2u, "Sfx\\Items\\Invscrol.wav", NULL }, + { 2u, "Sfx\\Items\\Invshiel.wav", NULL }, + { 2u, "Sfx\\Items\\Invsign.wav", NULL }, + { 2u, "Sfx\\Items\\Invstaf.wav", NULL }, + { 2u, "Sfx\\Items\\Invsword.wav", NULL }, + { 2u, "Sfx\\Items\\Lever.wav", NULL }, + { 2u, "Sfx\\Items\\Magic.wav", NULL }, + { 2u, "Sfx\\Items\\Magic1.wav", NULL }, + { 2u, "Sfx\\Items\\Readbook.wav", NULL }, + { 2u, "Sfx\\Items\\Sarc.wav", NULL }, + { 2u, "Sfx\\Items\\Shielfkd.wav", NULL }, + { 2u, "Sfx\\Items\\Swrdfkd.wav", NULL }, + { 4u, "Sfx\\Items\\Titlemov.wav", NULL }, + { 4u, "Sfx\\Items\\Titlslct.wav", NULL }, + { 4u, "Sfx\\Misc\\blank.wav", NULL }, + { 2u, "Sfx\\Items\\Trap.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast1.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast10.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast12.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast2.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast3.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast4.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast5.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast6.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast7.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast8.wav", NULL }, + { 2u, "Sfx\\Misc\\Cast9.wav", NULL }, + { 2u, "Sfx\\Misc\\Healing.wav", NULL }, + { 2u, "Sfx\\Misc\\Repair.wav", NULL }, + { 2u, "Sfx\\Misc\\Acids1.wav", NULL }, + { 2u, "Sfx\\Misc\\Acids2.wav", NULL }, + { 2u, "Sfx\\Misc\\Apoc.wav", NULL }, + { 2u, "Sfx\\Misc\\Arrowall.wav", NULL }, + { 2u, "Sfx\\Misc\\Bldboil.wav", NULL }, + { 2u, "Sfx\\Misc\\Blodstar.wav", NULL }, + { 2u, "Sfx\\Misc\\Blsimpt.wav", NULL }, + { 2u, "Sfx\\Misc\\Bonesp.wav", NULL }, + { 2u, "Sfx\\Misc\\Bsimpct.wav", NULL }, + { 2u, "Sfx\\Misc\\Caldron.wav", NULL }, + { 2u, "Sfx\\Misc\\Cbolt.wav", NULL }, + { 2u, "Sfx\\Misc\\Chltning.wav", NULL }, + { 2u, "Sfx\\Misc\\DSerp.wav", NULL }, + { 2u, "Sfx\\Misc\\Elecimp1.wav", NULL }, + { 2u, "Sfx\\Misc\\Elementl.wav", NULL }, + { 2u, "Sfx\\Misc\\Ethereal.wav", NULL }, + { 2u, "Sfx\\Misc\\Fball.wav", NULL }, + { 2u, "Sfx\\Misc\\Fbolt1.wav", NULL }, + { 2u, "Sfx\\Misc\\Fbolt2.wav", NULL }, + { 2u, "Sfx\\Misc\\Firimp1.wav", NULL }, + { 2u, "Sfx\\Misc\\Firimp2.wav", NULL }, + { 2u, "Sfx\\Misc\\Flamwave.wav", NULL }, + { 2u, "Sfx\\Misc\\Flash.wav", NULL }, + { 2u, "Sfx\\Misc\\Fountain.wav", NULL }, + { 2u, "Sfx\\Misc\\Golum.wav", NULL }, + { 2u, "Sfx\\Misc\\Golumded.wav", NULL }, + { 2u, "Sfx\\Misc\\Gshrine.wav", NULL }, + { 2u, "Sfx\\Misc\\Guard.wav", NULL }, + { 2u, "Sfx\\Misc\\Grdlanch.wav", NULL }, + { 2u, "Sfx\\Misc\\Holybolt.wav", NULL }, + { 2u, "Sfx\\Misc\\Hyper.wav", NULL }, + { 2u, "Sfx\\Misc\\Infravis.wav", NULL }, + { 2u, "Sfx\\Misc\\Invisibl.wav", NULL }, + { 2u, "Sfx\\Misc\\Invpot.wav", NULL }, + { 2u, "Sfx\\Misc\\Lning1.wav", NULL }, + { 2u, "Sfx\\Misc\\Ltning.wav", NULL }, + { 2u, "Sfx\\Misc\\Mshield.wav", NULL }, + { 2u, "Sfx\\Misc\\Nova.wav", NULL }, + { 2u, "Sfx\\Misc\\Portal.wav", NULL }, + { 2u, "Sfx\\Misc\\Puddle.wav", NULL }, + { 2u, "Sfx\\Misc\\Resur.wav", NULL }, + { 2u, "Sfx\\Misc\\Scurse.wav", NULL }, + { 2u, "Sfx\\Misc\\Scurimp.wav", NULL }, + { 2u, "Sfx\\Misc\\Sentinel.wav", NULL }, + { 2u, "Sfx\\Misc\\Shatter.wav", NULL }, + { 2u, "Sfx\\Misc\\Soulfire.wav", NULL }, + { 2u, "Sfx\\Misc\\Spoutlop.wav", NULL }, + { 2u, "Sfx\\Misc\\Spoutstr.wav", NULL }, + { 2u, "Sfx\\Misc\\Storm.wav", NULL }, + { 2u, "Sfx\\Misc\\Trapdis.wav", NULL }, + { 2u, "Sfx\\Misc\\Teleport.wav", NULL }, + { 2u, "Sfx\\Misc\\Vtheft.wav", NULL }, + { 2u, "Sfx\\Misc\\Wallloop.wav", NULL }, + { 2u, "Sfx\\Misc\\Wallstrt.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid01.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid02.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid03.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid04.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid05.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid06.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid07.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid08.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid09.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid10.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid11.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid12.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid13.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid14.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid15.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid16.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid17.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid18.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid19.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid20.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid21.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid22.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid23.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid24.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid25.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid26.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid27.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid28.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid29.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid30.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid31.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid32.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid33.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid34.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid35.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid36.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid37.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid38.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid39.wav", NULL }, + { 1u, "Sfx\\Towners\\Bmaid40.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith01.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith02.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith03.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith04.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith05.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith06.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith07.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith08.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith09.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith10.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith11.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith12.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith13.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith14.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith15.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith16.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith17.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith18.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith19.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith20.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith21.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith22.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith23.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith24.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith25.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith26.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith27.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith28.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith29.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith30.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith31.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith32.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith33.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith34.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith35.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith36.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith37.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith38.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith39.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith40.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith41.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith42.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith43.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith44.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith45.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith46.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith47.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith48.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith49.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith50.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith51.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith52.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith53.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith54.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith55.wav", NULL }, + { 1u, "Sfx\\Towners\\Bsmith56.wav", NULL }, + { 0u, "Sfx\\Towners\\Cow1.wav", NULL }, + { 0u, "Sfx\\Towners\\Cow2.wav", NULL }, + { 1u, "Sfx\\Towners\\Deadguy2.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk01.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk02.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk03.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk04.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk05.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk06.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk07.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk08.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk09.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk10.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk11.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk12.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk13.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk14.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk15.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk16.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk17.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk18.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk19.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk20.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk21.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk22.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk23.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk24.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk25.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk26.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk27.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk28.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk29.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk30.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk31.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk32.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk33.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk34.wav", NULL }, + { 1u, "Sfx\\Towners\\Drunk35.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer01.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer02.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer03.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer04.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer05.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer06.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer07.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer08.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer09.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer10.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer11.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer12.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer13.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer14.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer15.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer16.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer17.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer18.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer19.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer20.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer21.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer22.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer23.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer24.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer25.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer26.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer27.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer28.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer29.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer30.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer31.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer32.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer33.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer34.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer35.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer36.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer37.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer38.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer39.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer40.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer41.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer42.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer43.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer44.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer45.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer46.wav", NULL }, + { 1u, "Sfx\\Towners\\Healer47.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy01.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy02.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy03.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy04.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy05.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy06.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy07.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy08.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy09.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy10.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy11.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy12.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy13.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy14.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy15.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy16.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy17.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy18.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy19.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy20.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy21.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy22.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy23.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy24.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy25.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy26.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy27.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy28.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy29.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy30.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy31.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy32.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy33.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy34.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy35.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy36.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy37.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy38.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy39.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy40.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy41.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy42.wav", NULL }, + { 1u, "Sfx\\Towners\\Pegboy43.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest00.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest01.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest02.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest03.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest04.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest05.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest06.wav", NULL }, + { 1u, "Sfx\\Towners\\Priest07.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt00.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt01.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt02.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt03.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt04.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt05.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt06.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt07.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt08.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt09.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt10.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt11.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt12.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt13.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt14.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt15.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt16.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt17.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt18.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt19.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt20.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt21.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt22.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt23.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt24.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt25.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt26.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt27.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt28.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt29.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt30.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt31.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt32.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt33.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt34.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt35.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt36.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt37.wav", NULL }, + { 1u, "Sfx\\Towners\\Storyt38.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown00.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown01.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown02.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown03.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown04.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown05.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown06.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown07.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown08.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown09.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown10.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown11.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown12.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown13.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown14.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown15.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown16.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown17.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown18.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown19.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown20.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown21.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown22.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown23.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown24.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown25.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown26.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown27.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown28.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown29.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown30.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown31.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown32.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown33.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown34.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown35.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown36.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown37.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown38.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown39.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown40.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown41.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown42.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown43.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown44.wav", NULL }, + { 1u, "Sfx\\Towners\\Tavown45.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch01.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch02.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch03.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch04.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch05.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch06.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch07.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch08.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch09.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch10.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch11.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch12.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch13.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch14.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch15.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch16.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch17.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch18.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch19.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch20.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch21.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch22.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch23.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch24.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch25.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch26.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch27.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch28.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch29.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch30.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch31.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch32.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch33.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch34.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch35.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch36.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch37.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch38.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch39.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch40.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch41.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch42.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch43.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch44.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch45.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch46.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch47.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch48.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch49.wav", NULL }, + { 1u, "Sfx\\Towners\\Witch50.wav", NULL }, + { 1u, "Sfx\\Towners\\Wound01.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage01.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage02.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage03.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage04.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage05.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage06.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage07.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage08.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage09.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage10.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage11.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage12.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage13.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage14.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage15.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage16.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage17.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage18.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage19.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage20.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage21.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage22.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage23.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage24.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage25.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage26.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage27.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage28.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage29.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage30.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage31.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage32.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage33.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage34.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage35.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage36.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage37.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage38.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage39.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage40.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage41.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage42.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage43.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage44.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage45.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage46.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage47.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage48.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage49.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage50.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage51.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage52.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage53.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage54.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage55.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage56.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage57.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage58.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage59.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage60.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage61.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage62.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage63.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage64.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage65.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage66.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage67.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage68.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage69.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage69b.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage70.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage71.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage72.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage73.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage74.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage75.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage76.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage77.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage78.wav", NULL }, + { 64u, "Sfx\\Sorceror\\Mage79.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage80.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage81.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage82.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage83.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage84.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage85.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage86.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage87.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage88.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage89.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage90.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage91.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage92.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage93.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage94.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage95.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage96.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage97.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage98.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage99.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage100.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage101.wav", NULL }, + { 65u, "Sfx\\Sorceror\\Mage102.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue01.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue02.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue03.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue04.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue05.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue06.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue07.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue08.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue09.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue10.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue11.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue12.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue13.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue14.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue15.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue16.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue17.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue18.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue19.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue20.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue21.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue22.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue23.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue24.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue25.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue26.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue27.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue28.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue29.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue30.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue31.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue32.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue33.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue34.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue35.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue36.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue37.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue38.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue39.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue40.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue41.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue42.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue43.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue44.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue45.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue46.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue47.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue48.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue49.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue50.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue51.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue52.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue53.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue54.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue55.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue56.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue57.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue58.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue59.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue60.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue61.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue62.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue63.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue64.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue65.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue66.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue67.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue68.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue69.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue69b.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue70.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue71.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue72.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue73.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue74.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue75.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue76.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue77.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue78.wav", NULL }, + { 16u, "Sfx\\Rogue\\Rogue79.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue80.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue81.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue82.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue83.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue84.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue85.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue86.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue87.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue88.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue89.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue90.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue91.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue92.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue93.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue94.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue95.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue96.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue97.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue98.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue99.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue100.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue101.wav", NULL }, + { 17u, "Sfx\\Rogue\\Rogue102.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior01.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior02.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior03.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior04.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior05.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior06.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior07.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior08.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior09.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior10.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior11.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior12.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior13.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior14.wav", NULL }, + { 32u, "Sfx\\Warrior\\Wario14b.wav", NULL }, + { 32u, "Sfx\\Warrior\\Wario14c.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior15.wav", NULL }, + { 32u, "Sfx\\Warrior\\Wario15b.wav", NULL }, + { 32u, "Sfx\\Warrior\\Wario15c.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior16.wav", NULL }, + { 32u, "Sfx\\Warrior\\Wario16b.wav", NULL }, + { 32u, "Sfx\\Warrior\\Wario16c.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior17.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior18.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior19.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior20.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior21.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior22.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior23.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior24.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior25.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior26.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior27.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior28.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior29.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior30.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior31.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior32.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior33.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior34.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior35.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior36.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior37.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior38.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior39.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior40.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior41.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior42.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior43.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior44.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior45.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior46.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior47.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior48.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior49.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior50.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior51.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior52.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior53.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior54.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior55.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior56.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior57.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior58.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior59.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior60.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior61.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior62.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior63.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior64.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior65.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior66.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior67.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior68.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior69.wav", NULL }, + { 32u, "Sfx\\Warrior\\Wario69b.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior70.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior71.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior72.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior73.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior74.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior75.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior76.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior77.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior78.wav", NULL }, + { 32u, "Sfx\\Warrior\\Warior79.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior80.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior81.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior82.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior83.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior84.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior85.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior86.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior87.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior88.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior89.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior90.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior91.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior92.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior93.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior94.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior95.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario95b.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario95c.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario95d.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario95e.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario95f.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario96b.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario97.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario98.wav", NULL }, + { 33u, "Sfx\\Warrior\\Warior99.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario100.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario101.wav", NULL }, + { 33u, "Sfx\\Warrior\\Wario102.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar01.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar02.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar03.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar04.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar05.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar06.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar07.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar08.wav", NULL }, + { 1u, "Sfx\\Narrator\\Nar09.wav", NULL }, + { 1u, "Sfx\\Misc\\Lvl16int.wav", NULL }, + { 1u, "Sfx\\Monsters\\Butcher.wav", NULL }, + { 1u, "Sfx\\Monsters\\Garbud01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Garbud02.wav", NULL }, + { 1u, "Sfx\\Monsters\\Garbud03.wav", NULL }, + { 1u, "Sfx\\Monsters\\Garbud04.wav", NULL }, + { 1u, "Sfx\\Monsters\\Izual01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Lach01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Lach02.wav", NULL }, + { 1u, "Sfx\\Monsters\\Lach03.wav", NULL }, + { 1u, "Sfx\\Monsters\\Laz01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Laz02.wav", NULL }, + { 1u, "Sfx\\Monsters\\Sking01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Snot01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Snot02.wav", NULL }, + { 1u, "Sfx\\Monsters\\Snot03.wav", NULL }, + { 1u, "Sfx\\Monsters\\Warlrd01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Wlock01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Zhar01.wav", NULL }, + { 1u, "Sfx\\Monsters\\Zhar02.wav", NULL }, + { 1u, "Sfx\\Monsters\\DiabloD.wav", NULL } +}; + +//----- (004158AE) -------------------------------------------------------- +struct effects_cpp_init +{ + effects_cpp_init() + { + effects_cpp_init_value = effects_inf; + } +} _effects_cpp_init; +// 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 = v1->pSnd; + 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] + char *ptr; // [esp+10Ch] [ebp-4h] + + v8 = monst; + if ( gbSndInited ) + { + v1 = 0; + v9 = Monsters[monst].mtype << 7; + do + { + if ( monster_action_sounds[v1] != 's' || *(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 = (char *)DiabloAllocPtr(v5 + 1); + strcpy(ptr, v7); + v6 = sound_file_load(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 ( !snd_playing(Monsters[0].Snds[v6]) ) + { + 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 = pSFX->pSnd) == 0 || !snd_playing(v6) ) + { + 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->pSnd ) + v5->pSnd = sound_file_load(v5->pszName); + v8 = v5->pSnd; + 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 ( SFileOpenFile(v4->pszName, &sfx_stream) ) + { + //_LOBYTE(v7) = SFileDdaBeginEx(sfx_stream, 0x40000, 0, 0, v5, lPan, 0); + if ( SFileDdaBeginEx(sfx_stream, 0x40000, 0, 0, v5, lPan, 0) ) + 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 + TSnd *v5; // ecx + + v3 = x; + v4 = RndSFX(psfx); + if ( v4 >= 0 && v4 <= 3 ) + { + v5 = sgSFX[v4].pSnd; + if ( v5 ) + v5->start_tc = 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() +{ + int i; // edi + + for(i = 0; i < 858; i++) + { + if ( sgSFX[i].pSnd ) + snd_stop_snd(sgSFX[i].pSnd); + } +} + +//----- (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 ( SFileDdaGetPos(sfx_stream, (int)&v4, (int)&v3) ) + { + 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 = sgSFX[v0].pSnd; + if ( v1 ) + { + sound_file_cleanup(v1); + sgSFX[v0].pSnd = 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].pSnd ) + { + 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].pSnd = 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].pSnd ) + { + ++v2; + ++v1; + if ( v2 >= 858 ) + return; + } + v3 = &sgSFX[v1].pSnd; + //_LOBYTE(v4) = snd_playing(*v3); + if ( !snd_playing(*v3) ) + snd_play_snd(*v3, 0, 0); + } +} +// 4A22D5: using guessed type char gbSoundOn; diff --git a/Source/effects.h b/Source/effects.h new file mode 100644 index 0000000..9bb97cb --- /dev/null +++ b/Source/effects.h @@ -0,0 +1,47 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//effects +extern int effects_cpp_init_value; // weak +extern int sfxdelay; // weak +extern int sfxdnum; +extern void *sfx_stream; +extern TSFX *sfx_data_cur; + +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); + +/* data */ + +extern int effects_inf; // weak +extern char monster_action_sounds[]; // idb + +/* rdata */ + +extern TSFX sgSFX[858]; diff --git a/Source/encrypt.cpp b/Source/encrypt.cpp new file mode 100644 index 0000000..12c0b8a --- /dev/null +++ b/Source/encrypt.cpp @@ -0,0 +1,225 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int encrypt_table[1280]; + +//----- (00415F43) -------------------------------------------------------- +void __fastcall encrypt_decrypt_block(void *block, int size, int key) // DecryptMPQBlock +{ + 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_table[(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 ); + } +} + +//----- (00415F8F) -------------------------------------------------------- +void __fastcall encrypt_encrypt_block(void *block, int size, int key) // EncryptMPQBlock +{ + 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_table[(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 ); + } +} + +//----- (00415FDF) -------------------------------------------------------- +int __fastcall encrypt_hash(char *s, int type) // HashStringSlash +{ + 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) ^ encrypt_table[v7 + (v2 << 8)]; + v5 = v7 + 33 * v5 + v4 + 3; + } + return v4; +} + +//----- (0041602E) -------------------------------------------------------- +void __cdecl encrypt_init_lookup_table() // InitScratchSpace +{ + 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_table; + 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_table[256] ); +} + +//----- (0041609D) -------------------------------------------------------- +int __fastcall encrypt_compress(void *buf, int size) // MPQCompress_PKWare +{ + 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( + encrypt_pkware_read, + encrypt_pkware_write, + 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; +} + +//----- (00416133) -------------------------------------------------------- +unsigned int __cdecl encrypt_pkware_read(char *buf, unsigned int *size, void *param) // ReadPKWare +{ + 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; +} + +//----- (00416167) -------------------------------------------------------- +void __cdecl encrypt_pkware_write(char *buf, unsigned int *size, void *param) // WritePKWare +{ + TDataInfo * pInfo = (TDataInfo *)param; + + memcpy(&pInfo->pbOutBuffEnd[(unsigned int)pInfo->pbOutBuff], buf, *size); + pInfo->pbOutBuffEnd += *size; +} + +//----- (0041618E) -------------------------------------------------------- +void __fastcall encrypt_decompress(void *param, int recv_size, int dwMaxBytes) // MPQDecompress_PKWare +{ + 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( + encrypt_pkware_read, + encrypt_pkware_write, + ptr, + &info); + memcpy(v3, v5, (size_t)info.pbOutBuffEnd); + mem_free_dbg(ptr); + mem_free_dbg(v5); +} diff --git a/Source/encrypt.h b/Source/encrypt.h new file mode 100644 index 0000000..adb6e89 --- /dev/null +++ b/Source/encrypt.h @@ -0,0 +1,23 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//encrypt +extern int encrypt_table[1280]; +//int encrypt_52B564[257]; + +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); +unsigned int __cdecl encrypt_pkware_read(char *buf, unsigned int *size, void *param); +void __cdecl encrypt_pkware_write(char *buf, unsigned int *size, void *param); +void __fastcall encrypt_decompress(void *param, int recv_size, int dwMaxBytes); \ No newline at end of file diff --git a/Source/engine.cpp b/Source/engine.cpp new file mode 100644 index 0000000..5a8aeb9 --- /dev/null +++ b/Source/engine.cpp @@ -0,0 +1,3019 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int engine_cpp_init_value; // weak +char byte_52B96C; // automap pixel color 8-bit (palette entry) +int dword_52B970; // bool flip - if y < x +int orgseed; // weak +int sgnWidth; +int sglGameSeed; // weak +static CRITICAL_SECTION sgMemCrit; +int SeedCount; // weak +int dword_52B99C; // bool valid - if x/y are in bounds + +int engine_inf = 0x7F800000; // weak + +//----- (00416201) -------------------------------------------------------- +struct engine_cpp_init_1 +{ + engine_cpp_init_1() + { + engine_cpp_init_value = engine_inf; + } +} _engine_cpp_init_1; +// 47A474: using guessed type int engine_inf; +// 52B968: using guessed type int engine_cpp_init_value; + +//----- (0041620C) -------------------------------------------------------- +void __fastcall CelDrawDatOnly(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 CelDecodeOnly(int screen_x, int screen_y, void *pCelBuff, int frame, int frame_width) +{ + if ( gpBuffer ) + { + if ( pCelBuff ) + CelDrawDatOnly( + (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 CelDecDatOnly(char *pBuff, char *pCelBuff, int frame, int frame_width) +{ + if ( pCelBuff ) + { + if ( pBuff ) + CelDrawDatOnly( + pBuff, + &pCelBuff[*(_DWORD *)&pCelBuff[4 * frame]], + *(_DWORD *)&pCelBuff[4 * frame + 4] - *(_DWORD *)&pCelBuff[4 * frame], + frame_width); + } +} + +//----- (004162DE) -------------------------------------------------------- +void __fastcall CelDrawHdrOnly(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; + CelDrawDatOnly( + (char *)gpBuffer + screen_y_times_768[v12 - 16 * always_0] + v11, + &v8[v9], + v10, + frame_width); + } + } + } +} + +//----- (00416359) -------------------------------------------------------- +void __fastcall CelDecodeHdrOnly(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; + CelDrawDatOnly(pBuff, &v7[v8], v10, frame_width); + } + } + } +} + +//----- (004163AC) -------------------------------------------------------- +void __fastcall CelDecDatLightOnly(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; // [esp+0h] [ebp-1Ch] + char *v10; // [esp+4h] [ebp-18h] + + 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; + CelDecDatLightEntry(v8, (char *)(v7 - v8), (char *)(v7 - v8), v6); + v7 = v9; + v6 = v10; + if ( !v9 ) + goto LABEL_9; + } + 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 CelDecDatLightEntry(int a1, char *a2, char *a3, char *v6) +{ + int v4; // ebx + // _BYTE *v6; // esi + char v7; // cf + unsigned char v8; // cl + char v9; // cl + int v10; // eax + char v11; // ch + char v12; // ch + char v13; // ch + + v7 = a1 & 1; + v8 = (unsigned char)a1 >> 1; + if ( v7 ) + { + *a2 = *v6; + *a3 = a2[v4]; + ++v6; + ++a3; + } + v7 = v8 & 1; + v9 = v8 >> 1; + if ( v7 ) + { + *a2 = *v6; + *a3 = a2[v4]; + *a2 = v6[1]; + a3[1] = a2[v4]; + v6 += 2; + a3 += 2; + } + for ( ; v9; --v9 ) + { + v10 = *(_DWORD *)v6; + v6 += 4; + *a2 = v10; + v11 = a2[v4]; + *a2 = BYTE1(v10); + v10 = __ROR4__(v10, 16); + *a3 = v11; + v12 = a2[v4]; + *a2 = v10; + a3[1] = v12; + v13 = a2[v4]; + *a2 = BYTE1(v10); + a3[2] = v13; + a3[3] = a2[v4]; + a3 += 4; + } +} + +//----- (00416488) -------------------------------------------------------- +void __fastcall CelDecDatLightTrans(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] + char *v27; // [esp+Ch] [ebp-14h] + int v28; // [esp+14h] [ebp-Ch] + int _EAX; + char *_EBX; + + if ( pDecodeTo && pRLEBytes ) + { + v27 = &pLightTbl[256 * light_table_index]; + 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; + _EAX = *v4; + ASM_XLAT(_EAX,_EBX); + *(_BYTE *)v5 = _EAX; + v4 += 2; + v5 += 2; + if ( v21 ) + { +LABEL_26: + do + { + _EAX = *(_DWORD *)v4; + v4 += 4; + ASM_XLAT(_EAX,_EBX); + *(_BYTE *)v5 = _EAX; + v25 = (_BYTE *)(v5 + 2); + _EAX = __ROR4__(_EAX, 16); + ASM_XLAT(_EAX,_EBX); + *v25 = _EAX; + v5 = (int)(v25 + 2); + --v21; + } + while ( v21 ); + } + goto LABEL_20; + } + } + else + { + v10 = v8 >> 1; + if ( !(v8 & 1) ) + goto LABEL_17; + _EAX = *v4++; + ASM_XLAT(_EAX,_EBX); + *(_BYTE *)v5++ = _EAX; + if ( v10 ) + { +LABEL_10: + v11 = v10 & 1; + v12 = v10 >> 1; + if ( !v11 ) + goto LABEL_27; + v13 = v4 + 1; + v14 = (_BYTE *)(v5 + 1); + _EAX = *v13; + v4 = v13 + 1; + ASM_XLAT(_EAX,_EBX); + *v14 = _EAX; + v5 = (int)(v14 + 1); + if ( v12 ) + { +LABEL_27: + do + { + _EAX = *(_DWORD *)v4; + v4 += 4; + v18 = (_BYTE *)(v5 + 1); + _EAX = __ROR4__(_EAX, 8); + ASM_XLAT(_EAX,_EBX); + *v18 = _EAX; + _EAX = __ROR4__(_EAX, 16); + v18 += 2; + ASM_XLAT(_EAX,_EBX); + *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 CelDecodeLightOnly(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 ) + CelDecDatLightOnly(v8, v7, v9, frame_width); + else */ + CelDrawDatOnly(v8, v7, v9, frame_width); + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (004165BD) -------------------------------------------------------- +void __fastcall CelDecodeHdrLightOnly(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 ) + CelDecDatLightOnly(v14, v13, v12, frame_width); + else*/ + CelDrawDatOnly(v14, v13, v12, frame_width); + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (0041664B) -------------------------------------------------------- +void __fastcall CelDecodeHdrLightTrans(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 ) + { + CelDecDatLightTrans(pBuff, v12, v11, frame_width); + } + /*else if ( light_table_index ) + { + CelDecDatLightOnly(pBuff, v12, v11, frame_width); + }*/ + else + { + CelDrawDatOnly(pBuff, v12, v11, frame_width); + } + } + } + } +} +// 69BEF8: using guessed type int light_table_index; +// 69CF94: using guessed type int cel_transparency_active; + +//----- (004166BF) -------------------------------------------------------- +void __fastcall CelDrawHdrLightRed(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] + char *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 = &pLightTbl[framea]; + 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 = 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 Cel2DecDatOnly(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 Cel2DrawHdrOnly(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; + Cel2DecDatOnly( + (char *)gpBuffer + screen_y_times_768[v12 - 16 * a6] + v11, + &v8[v9], + v10, + frame_width); + } + } + } +} + +//----- (004168D5) -------------------------------------------------------- +void __fastcall Cel2DecodeHdrOnly(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; + Cel2DecDatOnly(pBuff, &v7[v8], v11, frame_width); + } + } + } +} + +//----- (0041692A) -------------------------------------------------------- +void __fastcall Cel2DecDatLightOnly(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; + Cel2DecDatLightEntry(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 Cel2DecDatLightEntry(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 Cel2DecDatLightTrans(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] + char *v27; // [esp+Ch] [ebp-14h] + int v28; // [esp+14h] [ebp-Ch] + int _EAX; + char *_EBX; + + if ( pDecodeTo && pRLEBytes && gpBuffer ) + { + v27 = &pLightTbl[256 * light_table_index]; + 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; + _EAX = *v4; + ASM_XLAT(_EAX,_EBX); + *(_BYTE *)v5 = _EAX; + v4 += 2; + v5 += 2; + if ( v21 ) + { +LABEL_29: + do + { + _EAX = *(_DWORD *)v4; + v4 += 4; + ASM_XLAT(_EAX,_EBX); + *(_BYTE *)v5 = _EAX; + v25 = (_BYTE *)(v5 + 2); + _EAX = __ROR4__(_EAX, 16); + ASM_XLAT(_EAX,_EBX); + *v25 = _EAX; + v5 = (unsigned int)(v25 + 2); + --v21; + } + while ( v21 ); + } + goto LABEL_23; + } + } + else + { + v10 = v8 >> 1; + if ( !(v8 & 1) ) + goto LABEL_20; + _EAX = *v4++; + ASM_XLAT(_EAX,_EBX); + *(_BYTE *)v5++ = _EAX; + if ( v10 ) + { +LABEL_13: + v11 = v10 & 1; + v12 = v10 >> 1; + if ( !v11 ) + goto LABEL_30; + v13 = v4 + 1; + v14 = (_BYTE *)(v5 + 1); + _EAX = *v13; + v4 = v13 + 1; + ASM_XLAT(_EAX,_EBX); + *v14 = _EAX; + 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(_EAX,_EBX); + *v18 = _EAX; + _EAX = __ROR4__(_EAX, 16); + v18 += 2; + ASM_XLAT(_EAX,_EBX); + *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 Cel2DecodeHdrLight(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 ) + Cel2DecDatLightOnly(v16, v15, v14, frame_width); + else*/ + Cel2DecDatOnly(v16, v15, v14, frame_width); + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00416BA9) -------------------------------------------------------- +void __fastcall Cel2DecodeLightTrans(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 ) + { + Cel2DecDatLightTrans(dst_buf, v13, v12, frame_width); + } + /*else if ( light_table_index ) + { + Cel2DecDatLightOnly(dst_buf, v13, v12, frame_width); + }*/ + else + { + Cel2DecDatOnly(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 Cel2DrawHdrLightRed(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 = &pLightTbl[v14]; + 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 CelDecodeRect(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 CelDecodeClr(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 CelDrawHdrClrHL(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_draw_pixel(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_draw_automap_pixels(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_draw_pixel(v14, v15); + engine_draw_pixel(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_draw_pixel(v30, v15); + v14 = v30 + 1; + engine_draw_pixel(v14, v15); /* fix */ + x -= a4; + engine_draw_pixel(v31, x); + } + else + { + engine_draw_pixel(v30, v15); + v15 += a4; + v14 = v30 + 1; + engine_draw_pixel(v14, v15); + engine_draw_pixel(v31, x); + v37 = v36 - a4; /* fix */ + x = v37; + } + v33 = a5a - 2; + a5a = v33; + engine_draw_pixel(v33, x); /* fix */ + v35 = v44; + } + else + { + v32 = a4 + v15; + engine_draw_pixel(v30, v32); + v15 = a4 + v32; + v14 = v30 + 1; + engine_draw_pixel(v14, v15); + engine_draw_pixel(v31, x - a4); + v33 = a5a - 2; + a5a = v33; + x = v34 - a4; /* fix */ + engine_draw_pixel(v33, v34 - a4); + v35 = 2 * v50; + } + v53 += v35; + --v45; + } + while ( v45 ); + } + if ( !v54 ) + return; + if ( v53 > 0 ) + { + v39 = a4 + v15; + v40 = v14 + 1; + engine_draw_pixel(v40, v39); + if ( v54 > 1 ) + engine_draw_pixel(v40 + 1, v39 + a4); + if ( v54 <= 2 ) + return; + goto LABEL_71; + } + if ( v53 >= v50 ) + { + v42 = v14 + 1; + engine_draw_pixel(v42, a4 + v15); + if ( v54 > 1 ) + engine_draw_pixel(v42 + 1, a4 + v15); /* fix */ + if ( v54 <= 2 ) + return; + if ( v53 > v50 ) + { +LABEL_71: + v26 = v33 - 1; + v29 = x - a4; + goto LABEL_65; + } + } + else + { + v41 = v14 + 1; + engine_draw_pixel(v41, v15); + if ( v54 > 1 ) + engine_draw_pixel(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_draw_pixel(v18, v15); + v14 = v18 + 1; + engine_draw_pixel(v14, v23); /* fix */ + x -= a4; + engine_draw_pixel(a5b, x); + } + else + { + engine_draw_pixel(v18, v15); + v15 += a4; + v14 = v18 + 1; + engine_draw_pixel(v14, v15); + engine_draw_pixel(a5b, x); + v22 = v21 - a4; /* fix */ + x = v22; + } + a5a = a5b - 1; + engine_draw_pixel(a5a, v22); + v17 += v44; + } + else + { + engine_draw_pixel(v18, v15); + v14 = v18 + 1; + engine_draw_pixel(v14, v15); /* fix */ + engine_draw_pixel(a5b, x); + a5a = a5b - 1; + engine_draw_pixel(a5a, v15); /* fix */ + v17 += v52; + } + --v47; + } + while ( v47 ); + } + if ( v54 ) + { + if ( v17 < 0 ) + { + v24 = v14 + 1; + engine_draw_pixel(v24, v15); + if ( v54 > 1 ) + goto LABEL_36; + goto LABEL_37; + } + if ( v17 < v49 ) + { + v24 = v14 + 1; + engine_draw_pixel(v24, v15); + if ( v54 > 1 ) + { + v25 = v15 + a4; +LABEL_36: + engine_draw_pixel(v24 + 1, v15); /* fix */ + } +LABEL_37: + if ( v54 <= 2 ) + return; + v26 = a5a - 1; + goto LABEL_64; + } + v27 = v14 + 1; + engine_draw_pixel(v27, a4 + v15); + if ( v54 > 1 ) + engine_draw_pixel(v27 + 1, v28); /* fix */ + if ( v54 > 2 ) + { + v29 = x - a4; + v26 = a5a - 1; +LABEL_65: + engine_draw_pixel(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 = 0x015A4E35 * sglGameSeed + 1; + return abs(sglGameSeed); +} +// 52B97C: using guessed type int sglGameSeed; +// 52B998: using guessed type int SeedCount; + +//----- (0041754B) -------------------------------------------------------- +int __fastcall random(int idx, int v) +{ + int v2; // esi + int v4; // eax + + v2 = v; + if ( v <= 0 ) + return 0; + v4 = GetRndSeed(); + if ( v2 < 0xFFFF ) + v4 >>= 16; + return v4 % v2; +} + +//----- (0041756D) -------------------------------------------------------- +struct engine_cpp_init_2 +{ + engine_cpp_init_2() + { + mem_init_mutex(); + mem_atexit_mutex(); + } +} _engine_cpp_init_2; + +//----- (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 dwBytes) +{ + int v1; // ebx + void *v2; // ebx + int v3; // eax + + v1 = dwBytes; + 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 *pszName, int *pdwFileLen) +{ + int *v2; // edi + char *v3; // ebx + int v4; // eax + int v5; // esi + char *v6; // edi + void *a1; // [esp+Ch] [ebp-4h] + + v2 = pdwFileLen; + v3 = pszName; + WOpenFile(pszName, &a1, 0); + v4 = WGetFileSize(a1, 0); + v5 = v4; + if ( v2 ) + *v2 = v4; + if ( !v4 ) + TermMsg("Zero length SFILE:\n%s", v3); + v6 = (char *)DiabloAllocPtr(v5); + WReadFile(a1, v6, v5); + WCloseFile(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); + WOpenFile(v3, &a1, 0); + v4 = WGetFileSize(a1, 0); + if ( !v4 ) + TermMsg("Zero length SFILE:\n%s", v3); + WReadFile(a1, v2, v4); + WCloseFile(a1); +} + +//----- (004176D2) -------------------------------------------------------- +void __fastcall Cl2ApplyTrans(char *p, char *ttbl, int last_frame) +{ + 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 <= last_frame; ++i ) + { + v4 = *(_DWORD *)&p[4 * v3]; + v5 = *(_DWORD *)&p[4 * v3 + 4] - v4 - 10; + v6 = &p[v4 + 10]; + while ( v5 ) + { + v7 = *v6++; + --v5; + if ( v7 < 0 ) + { + v8 = -v7; + if ( (char)v8 <= 65 ) + { + v5 -= (char)v8; + if ( v8 ) + { + v9 = v8; + do + { + *v6 = ttbl[(unsigned char)*v6]; + ++v6; + --v9; + } + while ( v9 ); + } + } + else + { + --v5; + *v6 = ttbl[(unsigned char)*v6]; + ++v6; + } + } + } + v3 = i + 1; + } +} + +//----- (00417745) -------------------------------------------------------- +void __fastcall Cl2DecodeFrm1(int x, int y, char *pCelBuff, int nCel, int width, int dir1, int dir2) +{ + char *v8; // edx + char *v9; // ecx + int v10; // ecx + int v11; // eax + char *pCelBuffa; // [esp+18h] [ebp+8h] + + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *(char **)&pCelBuff[4 * nCel]; + pCelBuffa = v9; + v10 = (int)&v9[(_DWORD)v8]; + if ( *(_WORD *)(v10 + dir1) ) + { + if ( dir2 == 8 || (v11 = *(unsigned short *)(v10 + dir2), !*(_WORD *)(v10 + dir2)) ) + v11 = *((_DWORD *)v8 + nCel + 1) - (_DWORD)pCelBuffa; + Cl2DecDatFrm1( + (char *)gpBuffer + screen_y_times_768[y - 16 * dir1] + x, + (char *)(*(unsigned short *)(v10 + dir1) + v10), + v11 - *(unsigned short *)(v10 + dir1), + width); + } + } + } + } +} + +//----- (004177BF) -------------------------------------------------------- +void __fastcall Cl2DecDatFrm1(char *buffer, char *frame_content, int a3, int width) /* fix */ +{ + 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 = frame_content; + v5 = buffer; + v6 = 0; + v7 = width; + 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 = width; + v5 = &v5[-width - 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 = width; + v5 = &v5[-width - 768]; + } + } + } + while ( v8 ); +} + +//----- (00417847) -------------------------------------------------------- +void __fastcall Cl2DecodeFrm2(char colour, int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a7, int a8) +{ + int v8; // ebx + char *v9; // edx + int v10; // eax + int v11; // [esp+Ch] [ebp-8h] + + v11 = screen_x; + if ( gpBuffer ) + { + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v8 = *(_DWORD *)&pCelBuff[4 * nCel]; + v9 = &pCelBuff[v8]; + if ( *(_WORD *)&pCelBuff[v8 + a7] ) + { + if ( a8 == 8 || (v10 = *(unsigned short *)&v9[a8], !*(_WORD *)&v9[a8]) ) + v10 = *(_DWORD *)&pCelBuff[4 * nCel + 4] - v8; + Cl2DecDatFrm2( + (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a7] + v11, + &v9[*(unsigned short *)&pCelBuff[v8 + a7]], + v10 - *(unsigned short *)&pCelBuff[v8 + a7], + frame_width, + colour); + } + } + } + } +} + +//----- (004178C5) -------------------------------------------------------- +void __fastcall Cl2DecDatFrm2(char *buffer, char *frame_content, int a3, int frame_width, char colour) +{ + 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 = frame_content; + v6 = buffer; + v7 = 0; + v8 = frame_width; + v9 = a3; + v10 = colour; + 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 = frame_width; + v6 = &v6[-frame_width - 768]; + } + continue; + } + } + do + { + if ( v7 <= v8 ) + { + v13 = v7; + v6 += v7; + v7 = 0; + } + else + { + v13 = v8; + v6 += v8; + v7 -= v8; + } + v8 -= v13; + if ( !v8 ) + { + v8 = frame_width; + v6 = &v6[-frame_width - 768]; + } + } + while ( v7 ); + v10 = colour; + } + while ( v9 ); +} + +//----- (00417981) -------------------------------------------------------- +void __fastcall Cl2DecodeFrm3(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7, char a8) +{ + char *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 + char *pCelBuffa; // [esp+18h] [ebp+8h] + + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *(_DWORD *)&pCelBuff[4 * nCel]; + v10 = &pCelBuff[v9]; + v11 = *(unsigned short *)&pCelBuff[v9 + a6]; + pCelBuffa = (char *)*(unsigned short *)&pCelBuff[v9 + a6]; + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = *(_DWORD *)&v8[4 * nCel + 4] - 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; + Cl2DecDatLightTbl1( + (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a6] + screen_x, + v13, + v14, + frame_width, + &pLightTbl[v16]); + } + } + } + } +} +// 525728: using guessed type int light4flag; + +//----- (00417A44) -------------------------------------------------------- +void __fastcall Cl2DecDatLightTbl1(char *a1, char *a2, int a3, int a4, char *unused_lindex) /* check 5th arg */ +{ + char *v5; // esi + char *v6; // edi + int v7; // ebx + int v8; // ecx + int v9; // eax + int v10; // edx + char v11; // dl + + v5 = a2; + v6 = a1; + v7 = a4; + v8 = a3; + sgnWidth = 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 = sgnWidth; + v6 = &v6[-sgnWidth - 768]; + } + } + while ( v9 ); + } + else + { + _LOBYTE(v9) = -(char)v9; + if ( (char)v9 <= 65 ) + { + v8 -= v9; + v7 -= v9; + do + { + _LOBYTE(v10) = *v5++; + *v6 = unused_lindex[v10]; + --v9; + ++v6; + } + while ( v9 ); + } + else + { + _LOBYTE(v9) = v9 - 65; + --v8; + v7 -= v9; + _LOBYTE(v10) = *v5++; + v11 = unused_lindex[v10]; + do + { + *v6 = v11; + --v9; + ++v6; + } + while ( v9 ); + } + if ( !v7 ) + { + v7 = sgnWidth; + v6 = &v6[-sgnWidth - 768]; + } + } + } + while ( v8 ); +} +// 52B978: using guessed type int sgnWidth; + +//----- (00417AE9) -------------------------------------------------------- +void __fastcall Cl2DecodeLightTbl(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7) +{ + int v7; // esi + char *v8; // edi + int v9; // ebx + char *v10; // edx + int v11; // eax + int v12; // eax + int v13; // eax + char *v14; // edx + char *v15; // ecx + char *pCelBuffa; // [esp+18h] [ebp+8h] + + v7 = screen_y; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *(_DWORD *)&pCelBuff[4 * nCel]; + v10 = &pCelBuff[v9]; + v11 = *(unsigned short *)&pCelBuff[v9 + a6]; + pCelBuffa = (char *)*(unsigned short *)&pCelBuff[v9 + a6]; + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = *(_DWORD *)&v8[4 * nCel + 4] - v9; + v13 = v12 - (_DWORD)pCelBuffa; + v14 = &v10[(_DWORD)pCelBuffa]; + v15 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + screen_x; + if ( light_table_index ) + Cl2DecDatLightTbl1( + v15, + v14, + v13, + frame_width, + &pLightTbl[256 * light_table_index]); + else + Cl2DecDatFrm1(v15, v14, v13, frame_width); + } + } + } + } +} +// 69BEF8: using guessed type int light_table_index; + +//----- (00417B83) -------------------------------------------------------- +void __fastcall Cl2DecodeFrm4(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7) +{ + int v7; // ebx + char *v8; // edx + char *v9; // ecx + int v10; // ecx + int v11; // eax + int v12; // [esp+Ch] [ebp-4h] + char *pCelBuffa; // [esp+18h] [ebp+8h] + + v7 = screen_y; + v12 = screen_x; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *(char **)&pCelBuff[4 * 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[4 * nCel + 4] - (_DWORD)pCelBuffa; + Cl2DecDatFrm4( + (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + v12, + (char *)(*(unsigned short *)(v10 + a6) + v10), + v11 - *(unsigned short *)(v10 + a6), + frame_width); + } + } + } + } +} + +//----- (00417BFD) -------------------------------------------------------- +void __fastcall Cl2DecDatFrm4(char *buffer, char *a2, int a3, int frame_width) +{ + 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 = frame_width; + 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 = frame_width; + v5 = &v5[-frame_width - 768]; + } + continue; + } + } + } + do + { + if ( v6 <= v7 ) + { + v11 = v6; + v5 += v6; + v6 = 0; + } + else + { + v11 = v7; + v5 += v7; + v6 -= v7; + } + v7 -= v11; + if ( !v7 ) + { + v7 = frame_width; + v5 = &v5[-frame_width - 768]; + } + } + while ( v6 ); + } + while ( v8 ); +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417C99) -------------------------------------------------------- +void __fastcall Cl2DecodeClrHL(char colour, int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, 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 = screen_x; + a5 = colour; + if ( gpBuffer ) + { + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v8 = *(_DWORD *)&pCelBuff[4 * nCel]; + v9 = &pCelBuff[v8]; + v10 = *(unsigned short *)&pCelBuff[v8 + a7]; + if ( *(_WORD *)&pCelBuff[v8 + a7] ) + { + if ( a8 == 8 || (v11 = *(unsigned short *)&v9[a8], !*(_WORD *)&v9[a8]) ) + v11 = *(_DWORD *)&pCelBuff[4 * nCel + 4] - v8; + screen_buf_end -= 768; + Cl2DecDatClrHL( + (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a7] + v12, + &v9[v10], + v11 - v10, + frame_width, + a5); + screen_buf_end += 768; + } + } + } + } +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417D28) -------------------------------------------------------- +void __fastcall Cl2DecDatClrHL(char *dst_buf, char *frame_content, int a3, int frame_width, char colour) +{ + 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 = frame_content; + v6 = dst_buf; + v7 = 0; + v8 = frame_width; + v9 = a3; + v10 = colour; + 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 = frame_width; + v6 = &v6[-frame_width - 768]; + } + continue; + } + } + } + do + { + if ( v7 <= v8 ) + { + v13 = v7; + v6 += v7; + v7 = 0; + } + else + { + v13 = v8; + v6 += v8; + v7 -= v8; + } + v8 -= v13; + if ( !v8 ) + { + v8 = frame_width; + v6 = &v6[-frame_width - 768]; + } + } + while ( v7 ); + v10 = colour; + } + while ( v9 ); +} +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417DF8) -------------------------------------------------------- +void __fastcall Cl2DecodeFrm5(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7, char a8) +{ + char *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 + char *pCelBuffa; // [esp+18h] [ebp+8h] + + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *(_DWORD *)&pCelBuff[4 * nCel]; + v10 = &pCelBuff[v9]; + v11 = *(unsigned __int16 *)&pCelBuff[v9 + a6]; + pCelBuffa = (char *)*(unsigned __int16 *)&pCelBuff[v9 + a6]; + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned __int16 *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = *(_DWORD *)&v8[4 * nCel + 4] - 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; + Cl2DecDatLightTbl2( + (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a6] + screen_x, + v13, + v14, + frame_width, + &pLightTbl[v16]); + } + } + } + } +} +// 525728: using guessed type int light4flag; + +//----- (00417EBB) -------------------------------------------------------- +void __fastcall Cl2DecDatLightTbl2(char *dst_buf, char *a2, int a3, int frame_width, char *a5) /* check 5th arg */ +{ + char *v5; // esi + char *v6; // edi + int v7; // ebx + int v8; // ecx + int v9; // eax + int v10; // edx + char v11; // dl + + v5 = a2; + v6 = dst_buf; + v7 = frame_width; + v8 = a3; + sgnWidth = frame_width; + 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 = a5[v10]; + --v9; + ++v6; + } + while ( v9 ); + goto LABEL_12; + } + v5 += v9; + } + else + { + _LOBYTE(v9) = v9 - 65; + --v8; + _LOBYTE(v10) = *v5++; + v11 = a5[v10]; + if ( (signed int)v6 < screen_buf_end ) + { + v7 -= v9; + do + { + *v6 = v11; + --v9; + ++v6; + } + while ( v9 ); +LABEL_12: + if ( !v7 ) + { + v7 = sgnWidth; + v6 = &v6[-sgnWidth - 768]; + } + continue; + } + } + } + do + { + if ( v9 <= v7 ) + { + v10 = v9; + v6 += v9; + v9 = 0; + } + else + { + v10 = v7; + v6 += v7; + v9 -= v7; + } + v7 -= v10; + if ( !v7 ) + { + v7 = sgnWidth; + v6 = &v6[-sgnWidth - 768]; + } + } + while ( v9 ); + } + while ( v8 ); +} +// 52B978: using guessed type int sgnWidth; +// 69CF0C: using guessed type int screen_buf_end; + +//----- (00417F78) -------------------------------------------------------- +void __fastcall Cl2DecodeFrm6(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7) +{ + int v7; // esi + char *v8; // edi + int v9; // ebx + char *v10; // edx + int v11; // eax + int v12; // eax + int v13; // eax + char *v14; // edx + char *v15; // ecx + char *pCelBuffa; // [esp+18h] [ebp+8h] + + v7 = screen_y; + if ( gpBuffer ) + { + v8 = pCelBuff; + if ( pCelBuff ) + { + if ( nCel > 0 ) + { + v9 = *(_DWORD *)&pCelBuff[4 * nCel]; + v10 = &pCelBuff[v9]; + v11 = *(unsigned short *)&pCelBuff[v9 + a6]; + pCelBuffa = (char *)*(unsigned short *)&pCelBuff[v9 + a6]; + if ( v11 ) + { + if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) ) + v12 = *(_DWORD *)&v8[4 * nCel + 4] - v9; + v13 = v12 - (_DWORD)pCelBuffa; + v14 = &v10[(_DWORD)pCelBuffa]; + v15 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + screen_x; + if ( light_table_index ) + Cl2DecDatLightTbl2(v15, v14, v13, frame_width, &pLightTbl[256 * light_table_index]); + else + Cl2DecDatFrm4(v15, v14, v13, frame_width); + } + } + } + } +} +// 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(); + drawpanflag = 255; + scrollrt_draw_game_screen(1); + PaletteFadeIn(8); + drawpanflag = 255; +} +// 52571C: using guessed type int drawpanflag; diff --git a/Source/engine.h b/Source/engine.h new file mode 100644 index 0000000..55a2791 --- /dev/null +++ b/Source/engine.h @@ -0,0 +1,84 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//offset 0 +//pCelBuff->pFrameTable[0] + +//engine +extern int engine_cpp_init_value; // weak +extern char byte_52B96C; // automap pixel color 8-bit (palette entry) +extern int dword_52B970; // bool flip - if y < x +extern int orgseed; // weak +extern int sgnWidth; +extern int sglGameSeed; // weak +extern int SeedCount; // weak +extern int dword_52B99C; // bool valid - if x/y are in bounds + +void __cdecl engine_cpp_init_1(); +void __fastcall CelDrawDatOnly(char *pDecodeTo, char *pRLEBytes, int dwRLESize, int dwRLEWdt); +void __fastcall CelDecodeOnly(int screen_x, int screen_y, void *pCelBuff, int frame, int frame_width); +void __fastcall CelDecDatOnly(char *pBuff, char *pCelBuff, int frame, int frame_width); +void __fastcall CelDrawHdrOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall CelDecodeHdrOnly(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall CelDecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall CelDecDatLightEntry(int a1, char *a2, char *a3, char *v6); +void __fastcall CelDecDatLightTrans(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall CelDecodeLightOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width); +void __fastcall CelDecodeHdrLightOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall CelDecodeHdrLightTrans(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction); +void __fastcall CelDrawHdrLightRed(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1); +void __fastcall Cel2DecDatOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel2DrawHdrOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction); +void __fastcall Cel2DecodeHdrOnly(char *pBuff, char *pCelBuff, int frame, int frame_width, int a5, int direction); +void __fastcall Cel2DecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel2DecDatLightEntry(int a1, int a2); +void __fastcall Cel2DecDatLightTrans(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); +void __fastcall Cel2DecodeHdrLight(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction); +void __fastcall Cel2DecodeLightTrans(char *dst_buf, char *pCelBuff, int frame, int frame_width, int a5, int direction); +void __fastcall Cel2DrawHdrLightRed(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1); +void __fastcall CelDecodeRect(char *pBuff, int always_0, int dst_height, int dst_width, char *pCelBuff, int frame, int frame_width); +void __fastcall CelDecodeClr(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction); +void __fastcall CelDrawHdrClrHL(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_draw_pixel(int x, int y); +void __fastcall engine_draw_automap_pixels(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 idx, int v); +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 dwBytes); +void __fastcall mem_free_dbg(void *ptr); +unsigned char *__fastcall LoadFileInMem(char *pszName, int *pdwFileLen); +void __fastcall LoadFileWithMem(char *pszName, void *buf); +void __fastcall Cl2ApplyTrans(char *p, char *ttbl, int last_frame); +void __fastcall Cl2DecodeFrm1(int x, int y, char *pCelBuff, int nCel, int width, int dir1, int dir2); +void __fastcall Cl2DecDatFrm1(char *buffer, char *frame_content, int a3, int width); +void __fastcall Cl2DecodeFrm2(char colour, int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a7, int a8); +void __fastcall Cl2DecDatFrm2(char *buffer, char *a2, int a3, int a4, char a5); +void __fastcall Cl2DecodeFrm3(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7, char a8); +void __fastcall Cl2DecDatLightTbl1(char *a1, char *a2, int a3, int a4, char *unused_lindex); +void __fastcall Cl2DecodeLightTbl(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7); +void __fastcall Cl2DecodeFrm4(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7); +void __fastcall Cl2DecDatFrm4(char *buffer, char *a2, int a3, int frame_width); +void __fastcall Cl2DecodeClrHL(char colour, int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a7, int a8); +void __fastcall Cl2DecDatClrHL(char *dst_buf, char *frame_content, int a3, int frame_width, char colour); +void __fastcall Cl2DecodeFrm5(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7, char a8); +void __fastcall Cl2DecDatLightTbl2(char *dst_buf, char *a2, int a3, int frame_width, char *a5); +void __fastcall Cl2DecodeFrm6(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7); +void __fastcall PlayInGameMovie(char *pszMovie); + +/* data */ + +extern int engine_inf; // weak diff --git a/Source/error.cpp b/Source/error.cpp new file mode 100644 index 0000000..1211950 --- /dev/null +++ b/Source/error.cpp @@ -0,0 +1,227 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +char msgtable[80]; +char msgdelay; // weak +char msgflag; // weak +char msgcnt; // weak + +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!" +}; + +//----- (0041804E) -------------------------------------------------------- +void __fastcall InitDiabloMsg(char e) +{ + int i; // edx + bool v2; // sf + unsigned char v3; // of + + i = 0; + if ( msgcnt <= 0 ) + { +LABEL_4: + v3 = __OFSUB__(msgcnt, 80); + v2 = (char)(msgcnt - 80) < 0; + msgtable[msgcnt] = e; + if ( v2 ^ v3 ) + ++msgcnt; + msgdelay = 70; + msgflag = msgtable[0]; + } + else + { + while ( msgtable[i] != e ) + { + if ( ++i >= 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] + + CelDecodeOnly(165, 318, pSTextSlidCels, 1, 12); + CelDecodeOnly(591, 318, pSTextSlidCels, 4, 12); + CelDecodeOnly(165, 366, pSTextSlidCels, 2, 12); + CelDecodeOnly(591, 366, pSTextSlidCels, 3, 12); + screen_x = 173; + v16 = 35; + do + { + CelDecodeOnly(screen_x, 318, pSTextSlidCels, 5, 12); + CelDecodeOnly(screen_x, 366, pSTextSlidCels, 7, 12); + screen_x += 12; + --v16; + } + while ( v16 ); + v0 = 330; + v1 = 3; + do + { + CelDecodeOnly(165, v0, pSTextSlidCels, 6, 12); + CelDecodeOnly(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, 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; diff --git a/Source/error.h b/Source/error.h new file mode 100644 index 0000000..02ae189 --- /dev/null +++ b/Source/error.h @@ -0,0 +1,23 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//error +extern char msgtable[80]; +extern char msgdelay; // weak +extern char msgflag; // weak +extern char msgcnt; // weak + +void __fastcall InitDiabloMsg(char e); +void __cdecl ClrDiabloMsg(); +void __cdecl DrawDiabloMsg(); + +/* data */ +extern char *MsgStrings[44]; \ No newline at end of file diff --git a/Source/fault.cpp b/Source/fault.cpp new file mode 100644 index 0000000..b0afcb2 --- /dev/null +++ b/Source/fault.cpp @@ -0,0 +1,384 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; // idb + +//----- (004182AD) -------------------------------------------------------- +struct exception_cpp_init +{ + exception_cpp_init() + { + exception_install_filter(); + j_exception_init_filter(); + } +} _exception_cpp_init; + +//----- (004182B7) -------------------------------------------------------- +void __cdecl exception_install_filter() +{ + exception_set_filter(); +} + +//----- (004182C1) -------------------------------------------------------- +void __cdecl j_exception_init_filter() +{ + atexit(exception_init_filter); +} + +//----- (004182CD) -------------------------------------------------------- +void __cdecl exception_init_filter() +{ + exception_set_filter_ptr(); +} + +//----- (004182D7) -------------------------------------------------------- +LONG __stdcall TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) +{ + PEXCEPTION_RECORD v1; // esi + char *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] + + log_dump_computer_info(); + v1 = ExceptionInfo->ExceptionRecord; + v2 = exception_get_error_type(ExceptionInfo->ExceptionRecord->ExceptionCode, v5, 0x104u); + log_printf("Exception code: %08X %s\r\n", v1->ExceptionCode, v2); + exception_unknown_module(v1->ExceptionAddress, String1, 260, (int)&a4, (int)&a5); + log_printf("Fault address:\t%08X %02X:%08X %s\r\n", v1->ExceptionAddress, a4, a5, String1); + v3 = 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", + 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(ExceptionInfo); + else + result = 0; + return result; +} + +//----- (00418455) -------------------------------------------------------- +void __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 + + 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"); +} + +//----- (00418518) -------------------------------------------------------- +void __fastcall exception_unknown_module(LPCVOID lpAddress, LPSTR lpString1, int iMaxLength, int a4, int a5) +{ + int v6; // eax + char *v7; // eax + unsigned int v8; // edi + unsigned int v9; // esi + char *v10; // eax + int v11; // edx + unsigned int v12; // 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; + lstrcpynA(lpString1, "*unknown*", iMaxLength); + *(_DWORD *)a4 = 0; + *(_DWORD *)a5 = 0; + if ( VirtualQuery(lpAddress, &Buffer, 0x1Cu) ) + { + hModule = (HMODULE)Buffer.AllocationBase; + if ( !Buffer.AllocationBase ) + hModule = GetModuleHandleA(0); + if ( GetModuleFileNameA(hModule, lpFilename, iMaxLength) ) + { + if ( hModule ) + { + if ( *(_WORD *)hModule == 'ZM' ) + { + v6 = *((_DWORD *)hModule + 15); + if ( v6 ) + { + v7 = (char *)hModule + v6; + if ( *(_DWORD *)v7 == 'EP' ) + { + v8 = *((unsigned __int16 *)v7 + 3); + iMaxLengtha = 0; + v9 = (_BYTE *)lpAddress - (_BYTE *)hModule; + if ( *((_WORD *)v7 + 3) ) + { + v10 = &v7[*((unsigned __int16 *)v7 + 10) + 40]; + while ( 1 ) + { + v11 = *(_DWORD *)v10; + v12 = *((_DWORD *)v10 - 1); + if ( *(_DWORD *)v10 <= *((_DWORD *)v10 - 2) ) + v11 = *((_DWORD *)v10 - 2); + if ( v9 >= v12 && v9 <= v12 + v11 ) + break; + ++iMaxLengtha; + v10 += 40; + if ( iMaxLengtha >= v8 ) + return; + } + *(_DWORD *)a4 = iMaxLengtha + 1; + *(_DWORD *)a5 = v9 - v12; + } + } + } + } + } + } + else + { + lstrcpynA(lpFilename, "*unknown*", iMaxLength); + } + } +} + +//----- (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) -------------------------------------------------------- +char *__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 v3; + } + } + } + v5 = lpString1; + v6 = dwMessageId; + v7 = GetModuleHandleA("NTDLL.DLL"); + if ( !FormatMessageA(FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_IGNORE_INSERTS, v7, v6, 0, v5, nSize, NULL) ) + { + v4 = "*unknown*"; + goto LABEL_42; + } + return 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; +} diff --git a/Source/fault.h b/Source/fault.h new file mode 100644 index 0000000..e888c45 --- /dev/null +++ b/Source/fault.h @@ -0,0 +1,27 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//fault +//int dword_52B9F4; +extern LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; // idb + +void __cdecl exception_cpp_init(); +void __cdecl exception_install_filter(); +void __cdecl j_exception_init_filter(); +void __cdecl exception_init_filter(); +LONG __stdcall TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo); +void __fastcall exception_hex_format(char *a1, char a2); +void __fastcall exception_unknown_module(LPCVOID lpAddress, LPSTR lpString1, int iMaxLength, int a4, int a5); +void __fastcall exception_call_stack(void *a1, LPVOID lp); +char *__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(); \ No newline at end of file diff --git a/Source/gamemenu.cpp b/Source/gamemenu.cpp new file mode 100644 index 0000000..f2e3293 --- /dev/null +++ b/Source/gamemenu.cpp @@ -0,0 +1,358 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.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, (void (__cdecl *)(void))&gamemenu_music_volume }, + { 0xC0000000, NULL, (void (__cdecl *)(void))&gamemenu_sound_volume }, + { 0xC0000000, "Gamma", (void (__cdecl *)(void))&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" }; + +//----- (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(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 && !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() +{ + if ( gmenu_exception() ) + gamemenu_off(); + else + gamemenu_previous(); +} + +//----- (004188F9) -------------------------------------------------------- +void __cdecl gamemenu_new_game() +{ + int i; // eax + + for(i = 0; i < 4; i++) + { + plr[i]._pmode = PM_QUIT; + plr[i]._pInvincible = 1; + } + + deathflag = 0; + drawpanflag = 255; + scrollrt_draw_game_screen(1); + gbRunGame = 0; + gamemenu_off(); +} +// 525650: using guessed type int gbRunGame; +// 52571C: using guessed type int drawpanflag; + +//----- (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 *saveProc)(HWND, UINT, WPARAM, LPARAM); // edi + + saveProc = SetWindowProc(DisableInputWndProc); + gamemenu_off(); + SetCursor(0); + InitDiabloMsg(10); + drawpanflag = 255; + DrawAndBlit(); + LoadGame(0); + ClrDiabloMsg(); + PaletteFadeOut(8); + deathflag = 0; + drawpanflag = 255; + DrawAndBlit(); + PaletteFadeIn(8); + SetCursor(CURSOR_HAND); + interface_msg_pump(); + SetWindowProc(saveProc); +} +// 52571C: using guessed type int drawpanflag; + +//----- (004189BE) -------------------------------------------------------- +void __cdecl gamemenu_save_game() +{ + LRESULT (__stdcall *saveProc)(HWND, UINT, WPARAM, LPARAM); // edi + + if ( pcurs == CURSOR_HAND ) + { + if ( plr[myplr]._pmode == PM_DEATH || deathflag ) + { + gamemenu_off(); + } + else + { + saveProc = SetWindowProc(DisableInputWndProc); + SetCursor(0); + gamemenu_off(); + InitDiabloMsg(11); + drawpanflag = 255; + DrawAndBlit(); + SaveGame(); + ClrDiabloMsg(); + drawpanflag = 255; + SetCursor(CURSOR_HAND); + interface_msg_pump(); + SetWindowProc(saveProc); + } + } +} +// 52571C: using guessed type int drawpanflag; + +//----- (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(sgOptionMenu, 0); +} + +//----- (00418A6C) -------------------------------------------------------- +void __cdecl gamemenu_get_music() +{ + gamemenu_sound_music_toggle(music_toggle_names, sgOptionMenu, sound_get_or_set_music_volume(1)); +} + +//----- (00418A85) -------------------------------------------------------- +void __fastcall gamemenu_sound_music_toggle(char **names, TMenuItem *menu_item, int gamma) +{ + if ( gbSndInited ) + { + menu_item->dwFlags |= 0xC0000000; + menu_item->pszStr = *names; + gmenu_slider_3(menu_item, 17); + gmenu_slider_1(menu_item, -1600, 0, gamma); + } + else + { + menu_item->dwFlags &= 0x3F000000; + menu_item->pszStr = names[1]; + } +} + +//----- (00418AC6) -------------------------------------------------------- +void __cdecl gamemenu_get_sound() +{ + gamemenu_sound_music_toggle(sound_toggle_names, &sgOptionMenu[1], sound_get_or_set_sound_volume(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() +{ + gmenu_slider_3(&sgOptionMenu[2], 15); + gmenu_slider_1(&sgOptionMenu[2], 30, 100, palette_update_gamma(0)); +} + +//----- (00418B1A) -------------------------------------------------------- +void __fastcall gamemenu_music_volume(int a1) +{ + int v1; // esi + + if ( a1 ) + { + 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 __fastcall gamemenu_sound_volume(int a1) +{ + int v1; // ecx + int v2; // esi + + if ( a1 ) + { + 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 __fastcall gamemenu_gamma(int a1) +{ + int v1; // eax + int v2; // eax + + if ( a1 ) + { + 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() +{ + palette_set_color_cycling(palette_get_colour_cycling() == 0); + sgOptionMenu[3].pszStr = color_cycling_toggle_names[palette_get_colour_cycling() & 1]; +} diff --git a/Source/gamemenu.h b/Source/gamemenu.h new file mode 100644 index 0000000..51edcd7 --- /dev/null +++ b/Source/gamemenu.h @@ -0,0 +1,41 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +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, int gamma); +void __cdecl gamemenu_get_sound(); +void __cdecl gamemenu_get_color_cycling(); +void __cdecl gamemenu_get_gamma(); +void __fastcall gamemenu_music_volume(int a1); +int __fastcall gamemenu_slider_music_sound(TMenuItem *menu_item); +void __fastcall gamemenu_sound_volume(int a1); +void __fastcall gamemenu_gamma(int a1); +int __cdecl gamemenu_slider_gamma(); +void __cdecl gamemenu_color_cycling(); + +/* 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[]; \ No newline at end of file diff --git a/Source/gendung.cpp b/Source/gendung.cpp new file mode 100644 index 0000000..14bb945 --- /dev/null +++ b/Source/gendung.cpp @@ -0,0 +1,1482 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +short level_frame_types[2048]; +int themeCount; +char nTransTable[2049]; +//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]; + +//----- (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; /* check error */ + 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] + int _EAX; + char *_EBX; + + 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] ); /* check */ + 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 = &pLightTbl[256 * v65]; + 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 + { + _EAX = *v33++; + ASM_XLAT(_EAX,_EBX); + *v34++ = _EAX; + --v39; + } + while ( v39 ); + } + while ( v37 ); +LABEL_63: + v36 = v47 - 1; + } + while ( v47 != 1 ); + v63 += level_frame_sizes[v54]; + ++v65; + } + while ( v65 < v60 ); + 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 = &pLightTbl[256 * v64]; + for ( k = v51; k; --k ) + { + _EAX = *v27++; + ASM_XLAT(_EAX,_EBX); + *v28++ = _EAX; + } + 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] ); /* check */ +} +// 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_get_dpiece_num_from_coord(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_get_dpiece_num_from_coord(x, v1++); + v0 = (short (*)[112][112])((char *)v0 + 32); + qmemcpy(v3, v2, 0x20u); + } + while ( v1 < 112 ); + ++x; + } + while ( (signed int)v0 < (signed int)&dpiece_defs_map_2[16][0][0] ); +} + +//----- (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] ); /* check */ + 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 DRLG_MRectTrans(int x1, int y1, int x2, int y2) +{ + int v4; // esi + int v5; // edi + int i; // eax + char *v7; // edx + int j; // ecx + int ty_enda; // [esp+10h] [ebp+8h] + + v4 = 2 * x1 + 17; + v5 = 2 * x2 + 16; + i = 2 * y1 + 17; + for ( ty_enda = 2 * y2 + 16; i <= ty_enda; ++i ) + { + if ( v4 <= v5 ) + { + v7 = &dung_map[v4][i]; + j = v5 - v4 + 1; + do + { + *v7 = TransVal; + v7 += 112; + --j; + } + while ( j ); + } + } + ++TransVal; +} +// 5A5590: using guessed type char TransVal; + +//----- (004194D0) -------------------------------------------------------- +void __fastcall 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 = &dung_map[x1][i]; + j = x2 - x1 + 1; + do + { + *v5 = TransVal; + v5 += 112; + --j; + } + while ( j ); + } + } + ++TransVal; +} +// 5A5590: using guessed type char TransVal; + +//----- (00419515) -------------------------------------------------------- +void __fastcall DRLG_CopyTrans(int sx, int sy, int dx, int dy) +{ + dung_map[dx][dy] = dung_map[sx][sy]; +} + +//----- (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) -------------------------------------------------------- +bool __fastcall DRLG_WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height) +{ + int v7; // esi + int v8; // edi + 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 yArray[20]; // [esp+8h] [ebp-BCh] + int xArray[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; + if ( !SkipThemeRoom(x, y) ) + return 0; + memset(xArray, 0, 0x50u); + memset(yArray, 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; + xArray[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; + yArray[v8] = v15; + } + } + v29 += 40; + ++v8; + } + while ( v8 < maxSize ); + v8 = 0; + } + v16 = minSize; + v17 = 0; + if ( minSize > 0 ) + { + while ( xArray[v17] >= minSize && yArray[v17] >= minSize ) + { + if ( ++v17 >= minSize ) + goto LABEL_32; + } + return 0; + } +LABEL_32: + v18 = xArray[0]; + v19 = yArray[0]; + if ( maxSize > 0 ) + { + while ( 1 ) + { + v21 = xArray[v8]; + if ( v21 < v16 ) + break; + v22 = yArray[v8]; + if ( v22 < minSize ) + break; + if ( v21 < v18 ) + v18 = xArray[v8]; + if ( v22 < v19 ) + v19 = yArray[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; + dungeon[-1][v8 * 4 + v2] = 7; // *((_BYTE *)&dMonster[111][v8 + 102] + v2) = 7; /* check */ + dungeon[0][v5 + v2 - 1] = 9; // *((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = 9; + dungeon[-1][v3 + v8 * 4 + v2 - 1] = 6; // *((_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] = 150; + v5 = v3 + 40 * v9; + dungeon[-1][v10 * 4 + v2] = 151; // *((_BYTE *)&dMonster[111][v10 + 102] + v2) = -105; + dungeon[0][v5 + v2 - 1] = 152; // *((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = -104; + dungeon[-1][v3 + v10 * 4 + v2 - 1] = 138; // *((_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; + dungeon[-1][v12 * 4 + v2] = 16; // *((_BYTE *)&dMonster[111][v12 + 102] + v2) = 16; + dungeon[0][v5 + v2 - 1] = 15; // *((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = 15; + dungeon[-1][v3 + v12 * 4 + v2 - 1] = 12; // *((_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; + dungeon[themeLoc[v1].x + themeLoc[v1].width / 2][themeLoc[v1].y + v5 - 1] = 5; /* + *((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width / 2) + 111] + themeLoc[v1].y + + v5 + + 3) = 5; */ + } + } + else + { + v5 = themeLoc[v1].y; + dungeon[themeLoc[v1].x + themeLoc[v1].width -1][themeLoc[v1].height / 2 + v5] = 4; + // *((_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; + dungeon[themeLoc[v1].x + themeLoc[v1].width / 2][themeLoc[v1].y + v5 - 1] = 146; /* + *((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width / 2) + 111] + themeLoc[v1].y + + v5 + + 3) = -110; */ + } + } + else + { + v5 = themeLoc[v1].y; + dungeon[themeLoc[v1].x + themeLoc[v1].width -1][themeLoc[v1].height / 2 + v5] = 147; + // *((_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; + dungeon[0][v18 - 39] = 52; // *((_BYTE *)&dMonster[111][102] + v18 + 1) = 52; + *(v19 - 81) = 54; + } + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00419C10) -------------------------------------------------------- +void __fastcall DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, int rndSize) +{ + 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 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 ) + { + _LOBYTE(v6) = 0; + if ( !random(v6, 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; + _LOBYTE(v6) = 0; + v10 = random(v6, width - (minSize2 - 2) + 1); + _LOBYTE(v11) = 0; + v12 = minSize2 - 2 + random(v11, v10); + if ( v12 < minSize2 - 2 || (width = v12, v12 > v9) ) + width = minSize2 - 2; + _LOBYTE(v13) = 0; + v14 = random(v13, height - v8 + 1); + _LOBYTE(v15) = 0; + v16 = v8 + random(v15, 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 == 3 ) + 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 ); +} +// 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) -------------------------------------------------------- +bool __fastcall 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; +} + +//----- (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; diff --git a/Source/gendung.h b/Source/gendung.h new file mode 100644 index 0000000..9c9f5f8 --- /dev/null +++ b/Source/gendung.h @@ -0,0 +1,101 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//gendung +extern short level_frame_types[2048]; +extern int themeCount; +extern char nTransTable[2049]; +//int dword_52D204; +extern int dMonster[112][112]; +extern char dungeon[40][40]; +extern char dObject[112][112]; +extern void *pSpeedCels; +extern int nlevel_frames; // weak +extern char pdungeon[40][40]; +extern char dDead[112][112]; +extern short dpiece_defs_map_1[16][112][112]; +extern char dTransVal2[112][112]; +extern char TransVal; // weak +extern int dword_5A5594; +extern char dflags[40][40]; +extern int dPiece[112][112]; +extern char dTransVal[112][112]; +extern int setloadflag_2; // weak +extern Tile tile_defs[1024]; +extern void *pMegaTiles; +extern DPiece dpiece_defs[2]; +extern int gnDifficulty; // idb +extern char block_lvid[2049]; +//char byte_5B78EB; +extern char dung_map[112][112]; +extern char nTrapTable[2049]; +extern char leveltype; // weak +extern unsigned char currlevel; // idb +extern char TransList[256]; +extern char nSolidTable[2049]; +extern int level_frame_count[2049]; +extern ScrollStruct ScrollInfo; +extern void *pDungeonCels; +extern int speed_cel_frame_num_from_light_index_frame_num[16][128]; +extern THEME_LOC themeLoc[50]; +extern char dPlayer[112][112]; +extern int dword_5C2FF8; // weak +extern int dword_5C2FFC; // weak +extern int scr_pix_width; // weak +extern int scr_pix_height; // weak +extern char dArch[112][112]; +extern char nBlockTable[2049]; +extern void *level_special_cel; +extern char dFlags[112][112]; +extern char dItem[112][112]; +extern char setlvlnum; // weak +extern int level_frame_sizes[2048]; +extern char nMissileTable[2049]; +extern char *pSetPiece_2; +extern char setlvltype; // weak +extern char setlevel; // weak +extern int LvlViewY; // weak +extern int LvlViewX; // weak +extern int dmaxx; // weak +extern int dmaxy; // weak +extern int setpc_h; // weak +extern int setpc_w; // weak +extern int setpc_x; // idb +extern int ViewX; // idb +extern int ViewY; // idb +extern int setpc_y; // idb +extern char dMissile[112][112]; +extern int dminx; // weak +extern int dminy; // weak +extern short dpiece_defs_map_2[16][112][112]; + +void __cdecl FillSolidBlockTbls(); +void __cdecl gendung_418D91(); +void __fastcall gendung_4191BF(int frames); +void __fastcall gendung_4191FB(int a1, int a2); +int __fastcall gendung_get_dpiece_num_from_coord(int x, int y); +void __cdecl gendung_4192C2(); +void __cdecl SetDungeonMicros(); +void __cdecl DRLG_InitTrans(); +void __fastcall DRLG_MRectTrans(int x1, int y1, int x2, int y2); +void __fastcall DRLG_RectTrans(int x1, int y1, int x2, int y2); +void __fastcall DRLG_CopyTrans(int sx, int sy, int dx, int dy); +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); +bool __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 minSize, int maxSize, int floor, int freq, int rndSize); +void __cdecl DRLG_HoldThemeRooms(); +bool __fastcall SkipThemeRoom(int x, int y); +void __cdecl InitLevels(); \ No newline at end of file diff --git a/Source/gmenu.cpp b/Source/gmenu.cpp new file mode 100644 index 0000000..219fe86 --- /dev/null +++ b/Source/gmenu.cpp @@ -0,0 +1,538 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +void *optbar_cel; +bool byte_634464; // weak +void *PentSpin_cel; +TMenuItem *sgpCurrItem; +void *BigTGold_cel; +int dword_634474; // weak +char byte_634478; // weak +void (__cdecl *dword_63447C)(); +TMenuItem *dword_634480; // idb +void *option_cel; +void *sgpLogo; +int dword_63448C; // weak + +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 +}; +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 +}; + +//----- (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) -------------------------------------------------------- +void __fastcall gmenu_print_text(int x, int y, char *pszStr) +{ + char *v3; // edi + int v4; // ebp + int v5; // esi + unsigned char i; // al + unsigned char v7; // bl + + v3 = pszStr; + v4 = y; + v5 = x; + for ( i = *pszStr; *v3; i = *v3 ) + { + ++v3; + v7 = lfontframe[fontidx[i]]; + if ( v7 ) + CelDecodeLightOnly(v5, v4, (char *)BigTGold_cel, v7, 46); + v5 += lfontkern[v7] + 2; + } +} + +//----- (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(TMenuItem *pItem, void (__cdecl *gmFunc)()) +{ + TMenuItem *v2; // eax + int v3; // ecx + void (__cdecl **v4)(); // edx + + PauseMode = 0; + byte_634464 = 0; + v2 = pItem; + dword_63447C = gmFunc; + dword_634480 = pItem; + if ( gmFunc ) + { + gmFunc(); + v2 = dword_634480; + } + v3 = 0; + dword_63448C = 0; + if ( v2 ) + { + v4 = &v2->fnMenu; + while ( *v4 ) + { + ++v3; + v4 += 3; + dword_63448C = v3; + } + } + sgpCurrItem = &v2[v3 - 1]; + 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) +{ + TMenuItem *v1; // eax + int v2; // edi + + v1 = sgpCurrItem; + if ( sgpCurrItem ) + { + byte_634464 = 0; + v2 = dword_63448C; + while ( v2 ) + { + --v2; + if ( a1 ) + { + ++v1; + sgpCurrItem = v1; + if ( v1->fnMenu ) + goto LABEL_10; + v1 = dword_634480; + } + else + { + if ( v1 == dword_634480 ) + v1 = &dword_634480[dword_63448C]; + --v1; + } + sgpCurrItem = v1; +LABEL_10: + if ( v1->dwFlags < 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 + TMenuItem *i; // esi + DWORD v2; // eax + + if ( dword_634480 ) + { + if ( dword_63447C ) + dword_63447C(); + CelDecodeOnly(236, 262, sgpLogo, 1, 296); + v0 = 320; + for ( i = dword_634480; i->fnMenu; v0 += 45 ) + { + gmenu_draw_menu_item(i, v0); + ++i; + } + 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_draw_menu_item(TMenuItem *pItem, int a2) +{ + int v2; // edi + TMenuItem *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 = pItem; + v4 = gmenu_get_lfont(pItem); + v5 = v4; + v14 = v4; + if ( v3->dwFlags & 0x40000000 ) + { + v6 = (v4 >> 1) + 80; + CelDecodeOnly(v6, v2 - 10, optbar_cel, 1, 287); + v7 = ((unsigned int)v3->dwFlags >> 12) & 0xFFF; + if ( v7 < 2 ) + v7 = 2; + v8 = ((v3->dwFlags & 0xFFFu) << 8) / v7; + v9 = (v5 >> 1) + 82; + v10 = v8; + gmenu_clear_buffer(v9, v2 - 12, v8 + 13, 28); + CelDecodeOnly(v6 + v10 + 2, v2 - 12, option_cel, 1, 27); + v5 = v14; + } + v11 = 384 - (v5 >> 1); + v12 = -(v3->dwFlags < 0); + _LOBYTE(v12) = v12 & 0xF1; + light_table_index = v12 + 15; + gmenu_print_text(384 - (v5 >> 1), v2, v3->pszStr); + if ( v3 == sgpCurrItem ) + { + v13 = v2 + 1; + CelDecodeOnly(v11 - 54, v13, PentSpin_cel, (unsigned char)byte_634478, 48); + CelDecodeOnly(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 width, int height) +{ + int v4; // edi + char *i; // esi + + v4 = height; + for ( i = (char *)gpBuffer + screen_y_times_768[y] + x; v4; --v4 ) + { + memset(i, 205, width); + i -= 768; + } +} + +//----- (0041A272) -------------------------------------------------------- +int __fastcall gmenu_get_lfont(TMenuItem *pItem) +{ + char *v2; // eax + int i; // edx + unsigned char v4; // cl + + if ( pItem->dwFlags & 0x40000000 ) + return 490; + v2 = pItem->pszStr; + 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 ( sgpCurrItem->dwFlags < 0 ) + { + PlaySFX(IS_TITLEMOV); + ((void (__fastcall *)(signed int))sgpCurrItem->fnMenu)(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) +{ + int v1; // edx + int v2; // eax + int v3; // eax + + v1 = sgpCurrItem->dwFlags; + if ( sgpCurrItem->dwFlags & 0x40000000 ) + { + v2 = sgpCurrItem->dwFlags & 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->dwFlags = v1; + sgpCurrItem->dwFlags |= v3; + ((void (__fastcall *)(_DWORD))sgpCurrItem->fnMenu)(0); + } +} + +//----- (0041A37A) -------------------------------------------------------- +int __fastcall gmenu_on_mouse_move(LPARAM lParam) +{ + int v2; // edx + int a1; // [esp+0h] [ebp-4h] + + a1 = lParam; + if ( !byte_634464 ) + return 0; + gmenu_valid_mouse_pos(&a1); + v2 = a1 * ((sgpCurrItem->dwFlags >> 12) & 0xFFF) % 256; + a1 = a1 * ((sgpCurrItem->dwFlags >> 12) & 0xFFF) / 256; + _LOWORD(sgpCurrItem->dwFlags) &= 0xF000u; + sgpCurrItem->dwFlags |= a1; + ((void (__fastcall *)(_DWORD, int))sgpCurrItem->fnMenu)(0, v2); + return 1; +} +// 41A37A: could not find valid save-restore pair for esi +// 634464: using guessed type char byte_634464; + +//----- (0041A3D2) -------------------------------------------------------- +bool __fastcall gmenu_valid_mouse_pos(int *plOffset) +{ + *plOffset = 282; + if ( MouseX < 282 ) + { + *plOffset = 0; + return 0; + } + if ( MouseX > 538 ) + { + *plOffset = 256; + return 0; + } + *plOffset = MouseX - 282; + return 1; +} + +//----- (0041A401) -------------------------------------------------------- +int __fastcall gmenu_left_mouse(int a1) +{ + int result; // eax + unsigned int v2; // eax + unsigned int v3; // eax + TMenuItem *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 = v2; + v4 = &dword_634480[v3]; + if ( v4->dwFlags < 0 ) + { + v5 = (unsigned int)gmenu_get_lfont(&dword_634480[v3]) >> 1; + if ( MouseX >= 320 - v5 && MouseX <= v5 + 320 ) + { + sgpCurrItem = v4; + PlaySFX(IS_TITLEMOV); + if ( v4->dwFlags & 0x40000000 ) + { + byte_634464 = gmenu_valid_mouse_pos(&a1a); + gmenu_on_mouse_move(a1); /* v6 */ + } + else + { + ((void (__fastcall *)(signed int))sgpCurrItem->fnMenu)(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 *pMenuItem, bool enable) +{ + if ( enable ) + pMenuItem->dwFlags |= 0x80000000; + else + pMenuItem->dwFlags &= 0x7F000000; +} + +//----- (0041A4C6) -------------------------------------------------------- +void __fastcall gmenu_slider_1(TMenuItem *pItem, int min, int max, int gamma) +{ + int v4; // esi + int v5; // eax + + v4 = pItem->dwFlags; + v5 = (pItem->dwFlags >> 12) & 0xFFF; + if ( v5 < 2 ) + v5 = 2; + _LOWORD(v4) = v4 & 0xF000; + pItem->dwFlags = v4 | (v5 * (gamma - min) + (max - min - 1) / 2) / (max - min); +} + +//----- (0041A508) -------------------------------------------------------- +int __fastcall gmenu_slider_get(TMenuItem *pItem, int min, int max) +{ + int v3; // eax + int v4; // ecx + + v3 = (pItem->dwFlags >> 12) & 0xFFF; + v4 = pItem->dwFlags & 0xFFF; + if ( v3 < 2 ) + v3 = 2; + return min + (v4 * (max - min) + (v3 - 1) / 2) / v3; +} + +//----- (0041A545) -------------------------------------------------------- +void __fastcall gmenu_slider_3(TMenuItem *pItem, int dwTicks) +{ + pItem->dwFlags ^= (pItem->dwFlags ^ (dwTicks << 12)) & 0xFFF000; +} diff --git a/Source/gmenu.h b/Source/gmenu.h new file mode 100644 index 0000000..db7e44d --- /dev/null +++ b/Source/gmenu.h @@ -0,0 +1,50 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//gmenu +extern void *optbar_cel; +extern bool byte_634464; // weak +extern void *PentSpin_cel; +extern TMenuItem *sgpCurrItem; +extern void *BigTGold_cel; +extern int dword_634474; // weak +extern char byte_634478; // weak +extern void (__cdecl *dword_63447C)(); +extern TMenuItem *dword_634480; // idb +extern void *option_cel; +extern void *sgpLogo; +extern int dword_63448C; // weak + +void __cdecl gmenu_draw_pause(); +void __fastcall gmenu_print_text(int x, int y, char *pszStr); +void __cdecl FreeGMenu(); +void __cdecl gmenu_init_menu(); +bool __cdecl gmenu_exception(); +void __fastcall gmenu_call_proc(TMenuItem *pItem, void (__cdecl *gmFunc)()); +void __fastcall gmenu_up_down(int a1); +void __cdecl gmenu_draw(); +void __fastcall gmenu_draw_menu_item(TMenuItem *pItem, int a2); +void __fastcall gmenu_clear_buffer(int x, int y, int width, int height); +int __fastcall gmenu_get_lfont(TMenuItem *pItem); +int __fastcall gmenu_presskeys(int a1); +void __fastcall gmenu_left_right(int a1); +int __fastcall gmenu_on_mouse_move(LPARAM lParam); +bool __fastcall gmenu_valid_mouse_pos(int *plOffset); +int __fastcall gmenu_left_mouse(int a1); +void __fastcall gmenu_enable(TMenuItem *pMenuItem, bool enable); +void __fastcall gmenu_slider_1(TMenuItem *pItem, int min, int max, int gamma); +int __fastcall gmenu_slider_get(TMenuItem *pItem, int min, int max); +void __fastcall gmenu_slider_3(TMenuItem *pItem, int dwTicks); + +/* data */ + +extern unsigned char lfontframe[127]; +extern unsigned char lfontkern[56]; diff --git a/Source/help.cpp b/Source/help.cpp new file mode 100644 index 0000000..4ea62d2 --- /dev/null +++ b/Source/help.cpp @@ -0,0 +1,285 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int help_select_line; // weak +int dword_634494; // weak +int helpflag; +int displayinghelp[22]; /* check, does nothing? */ +int HelpTop; // weak + +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.|" + "&" +}; + +//----- (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", COL_GOLD, 0); + DrawSLine(5); + v0 = help_select_line; + v1 = gszHelpText; + if ( help_select_line > 0 ) + { + help_line_nr = help_select_line; + do + { + v2 = 0; + v3 = 0; + while ( !*v1 ) + ++v1; + if ( *v1 == '$' ) + ++v1; + v4 = *v1; + if ( *v1 != '&' ) + { + if ( v4 == ('|') ) + 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 == ('|') ) + { + if ( v3 < 577 ) + goto LABEL_18; + break; + } + } + for ( i = (unsigned char *)&tempstr[v2]-1; *i != ' '; --i ) + --v1; +LABEL_18: + if ( *v1 == ('|') ) +LABEL_47: + ++v1; + } + --help_line_nr; + } + while ( help_line_nr ); + } + help_line_nra = 7; + do + { + v7 = 0; + v8 = 0; + while ( !*v1 ) + ++v1; + if ( *v1 == '$' ) + { + ++v1; + _LOBYTE(color) = COL_RED; + } + else + { + _LOBYTE(color) = COL_WHITE; + } + v9 = *v1; + if ( *v1 == '&' ) + { + HelpTop = v0; + } + else + { + if ( v9 == ('|') ) + 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 == ('|') ) + { + if ( v8 < 577 ) + goto LABEL_39; + break; + } + } + while ( tempstr[--v7] != ' ' ) + --v1; +LABEL_39: + if ( v7 ) + { + tempstr[v7] = 0; + DrawHelpLine(0, help_line_nra, tempstr, color); + v0 = help_select_line; + } + if ( *v1 == ('|') ) +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.", COL_GOLD, 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, 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; diff --git a/Source/help.h b/Source/help.h new file mode 100644 index 0000000..cbbe5c5 --- /dev/null +++ b/Source/help.h @@ -0,0 +1,27 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//help +extern int help_select_line; // weak +extern int dword_634494; // weak +extern int helpflag; +extern int displayinghelp[22]; +extern int HelpTop; // weak + +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(); + +/* data */ +extern char gszHelpText[]; diff --git a/Source/init.cpp b/Source/init.cpp new file mode 100644 index 0000000..dd12b73 --- /dev/null +++ b/Source/init.cpp @@ -0,0 +1,553 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +_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; + +int init_inf = 0x7F800000; // weak + +/* rdata */ + +char gszVersionNumber[260] = "internal version unknown"; +char gszProductName[260] = "Diablo v1.09"; + +//----- (0041A7B8) -------------------------------------------------------- +struct init_cpp_init +{ + init_cpp_init() + { + init_cpp_init_value = init_inf; + } +} _init_cpp_init; +// 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 = empty_string; + killed_mom_parent = 0; + memset(pszPath + 1, 0, sizeof(pszPath) - 1); + // *(_WORD *)&pszPath[253] = 0; + //pszPath[255] = 0; + ppidl = 0; + v0 = GetDesktopWindow(); + if ( !SHGetSpecialFolderLocation(v0, CSIDL_STARTMENU, &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] == '\\' ) + strcat(FileName, "*"); + else + strcat(FileName, "\\*"); + v2 = FindFirstFileA(FileName, &FindFileData); + if ( v2 != (HANDLE)-1 ) + { + do + { + if ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { + if ( strcmp(FindFileData.cFileName, ".") && strcmp(FindFileData.cFileName, "..") ) + { + *Directory = empty_string; + memset(Directory + 1, 0, sizeof(Directory) - 1); + v3 = *v1 == 0; + // *(_WORD *)&Directory[257] = 0; + //Directory[259] = 0; + if ( v3 || v1[strlen(v1) - 1] != '\\' ) + 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, SW_SHOWNORMAL); + } + } + 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, KEY_READ|KEY_WRITE, &phkResult) ) + { + if ( v7 ) + { + cbData = 16; + if ( !RegQueryValueExA(phkResult, "ScreenSaveActive", 0, &Type, &Data, &cbData) ) + screensaver_enabled_prev = Data != '0'; + v1 = 0; + } + else + { + v1 = screensaver_enabled_prev; + } + v3 = 0; + Data = (v1 != 0) + '0'; + RegSetValueExA(phkResult, "ScreenSaveActive", 0, REG_SZ, &Data, 2u); + RegCloseKey(phkResult); + } +} + +//----- (0041AAC5) -------------------------------------------------------- +void __cdecl init_create_window() +{ + 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 = init_redraw_window; + wcex.hInstance = ghInst; + wcex.hIcon = LoadIconA(ghInst, (LPCSTR)0x65); + wcex.hCursor = LoadCursorA(0, (LPCSTR)0x7F00); + wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcex.lpszMenuName = "DIABLO"; + wcex.lpszClassName = "DIABLO"; + wcex.hIconSm = (HICON)LoadImageA(ghInst, (LPCSTR)0x65, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + if ( !RegisterClassExA(&wcex) ) + TermMsg("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 = CreateWindowExA(0, "DIABLO", "DIABLO", WS_POPUP, 0, 0, nWidth, nHeight, NULL, NULL, ghInst, NULL); + if ( !hWnd ) + TermMsg("Unable to create main window"); + ShowWindow(hWnd, SW_SHOWNORMAL); + UpdateWindow(hWnd); + init_await_mom_parent_exit(); + dx_init(hWnd); + BlackPalette(); + snd_init(hWnd); + 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, WM_CLOSE, 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, GW_HWNDNEXT) ) + { + 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(250); + } + while ( GetTickCount() - v0 <= 4000 ); +} + +//----- (0041ACA1) -------------------------------------------------------- +void __cdecl 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((int)&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); +} + +//----- (0041AD72) -------------------------------------------------------- +void *__fastcall 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 ( !GetCurrentDirectoryA(0x104u, Buffer) ) + TermMsg("Can't get program path"); + init_strip_trailing_slash(Buffer); + if ( !SFileSetBasePath(Buffer) ) + TermMsg("SFileSetBasePath"); + if ( !GetModuleFileNameA(ghInst, Filename, 0x104u) ) + TermMsg("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; +} + +//----- (0041AF22) -------------------------------------------------------- +char *__fastcall init_strip_trailing_slash(char *path) +{ + char *result; // eax + + result = strrchr(path, '\\'); + 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 + 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 == '\\' ) + ++v4; + v7 = Buffer; + if ( !Buffer[0] ) + return 0; + while ( 1 ) + { + v8 = v7; + v7 += strlen(v7) + 1; + if ( GetDriveTypeA(v8) == DRIVE_CDROM ) + { + strcpy(mpq_patha, v8); + strcat(mpq_patha, v4); + if ( SFileOpenArchive(mpq_patha, flags, 1, archive) ) + 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 uBytes; // [esp+8h] [ebp-Ch] + DWORD dwHandle; // [esp+Ch] [ebp-8h] + VS_FIXEDFILEINFO *lpBuffer; // [esp+10h] [ebp-4h] + + if ( GetModuleFileNameA(ghInst, 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, "\\", (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); + } + } +} + +//----- (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: + drawpanflag = 255; + break; + case WM_CLOSE: + return 0; + } + } + return DefWindowProcA(hWnd, Msg, wParam, lParam); +} +// 52571C: using guessed type int drawpanflag; + +//----- (0041B105) -------------------------------------------------------- +void __fastcall init_activate_window(HWND hWnd, bool activated) +{ + LONG dwNewLong; // eax + + window_activated = activated; + UiAppActivate(activated); + dwNewLong = GetWindowLongA(hWnd, GWL_STYLE); + + if ( window_activated && fullscreen ) + dwNewLong &= ~WS_SYSMENU; + else + dwNewLong |= WS_SYSMENU; + + SetWindowLongA(hWnd, GWL_STYLE, dwNewLong); + + if ( window_activated ) + { + drawpanflag = 255; + ResetPal(); + } +} +// 484364: using guessed type int fullscreen; +// 52571C: using guessed type int drawpanflag; +// 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; +} diff --git a/Source/init.h b/Source/init.h new file mode 100644 index 0000000..3f65b42 --- /dev/null +++ b/Source/init.h @@ -0,0 +1,51 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//init +extern _SNETVERSIONDATA fileinfo; +extern int init_cpp_init_value; // weak +extern int window_activated; // weak +extern char diablo_exe_path[260]; +extern void *unused_mpq; +extern char patch_rt_mpq_path[260]; +extern LRESULT (__stdcall *CurrentProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +extern void *diabdat_mpq; +extern char diabdat_mpq_path[260]; +extern void *patch_rt_mpq; +extern int killed_mom_parent; // weak +extern bool screensaver_enabled_prev; + +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); + +/* data */ +extern int init_inf; // weak + +/* rdata */ + +extern char gszVersionNumber[260]; +extern char gszProductName[260]; \ No newline at end of file diff --git a/Source/interfac.cpp b/Source/interfac.cpp new file mode 100644 index 0000000..6858bd9 --- /dev/null +++ b/Source/interfac.cpp @@ -0,0 +1,400 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +void *sgpBackCel; +float interfac_cpp_init_value; +int sgdwProgress; +int progress_id; // idb + +int interfac_inf = 0x7F800000; // weak +unsigned char progress_bar_colours[3] = { 138u, 43u, 254u }; +POINT32 progress_bar_screen_pos[3] = { { 53, 37 }, { 53, 421 }, { 53, 37 } }; + +//----- (0041B195) -------------------------------------------------------- +struct interfac_cpp_init +{ + interfac_cpp_init() + { + interfac_cpp_init_value = interfac_inf; + } +} _interfac_cpp_init; +// 47AE40: using guessed type int interfac_inf; + +//----- (0041B1A0) -------------------------------------------------------- +void __cdecl interface_msg_pump() +{ + MSG Msg; // [esp+8h] [ebp-1Ch] + + while ( PeekMessageA(&Msg, NULL, 0, 0, PM_REMOVE) ) + { + 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(); + CelDecodeOnly(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(); + drawpanflag = 255; + scrollrt_draw_game_screen(0); +} +// 52571C: using guessed type int drawpanflag; + +//----- (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) +{ + LRESULT (__stdcall *saveProc)(HWND, UINT, WPARAM, LPARAM); // edi + bool v3; // cl + int v4; // eax + int v5; // edx + signed int v7; // [esp-4h] [ebp-10h] + + gbSomebodyWonGameKludge = 0; + plrmsg_delay(1); + saveProc = SetWindowProc(DisableInputWndProc); + interface_msg_pump(); + ClearScreenBuffer(); + scrollrt_draw_game_screen(1); + InitCutscene(uMsg); + BlackPalette(); + DrawCutscene(); + PaletteFadeIn(8); + IncProgress(); + stream_update(); + IncProgress(); + switch ( uMsg ) + { + 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(1); +LABEL_41: + IncProgress(); + break; + default: + break; + } + PaletteFadeOut(8); + FreeInterface(); + SetWindowProc(saveProc); + NetSendCmdLocParam1(1u, CMD_PLAYER_JOINLEVEL, plr[myplr].WorldX, plr[myplr].WorldY, plr[myplr].plrlevel); + 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; diff --git a/Source/interfac.h b/Source/interfac.h new file mode 100644 index 0000000..d859e93 --- /dev/null +++ b/Source/interfac.h @@ -0,0 +1,31 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//interfac +extern void *sgpBackCel; +extern float interfac_cpp_init_value; +extern int sgdwProgress; +extern int progress_id; // idb + +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); + +/* data */ + +extern int interfac_inf; // weak +extern unsigned char progress_bar_colours[3]; +extern POINT32 progress_bar_screen_pos[3]; diff --git a/Source/inv.cpp b/Source/inv.cpp new file mode 100644 index 0000000..18fa6af --- /dev/null +++ b/Source/inv.cpp @@ -0,0 +1,3376 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int invflag; +void *pInvCels; +int drawsbarflag; // idb +int sgdwLastTime; // check name + +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 +}; + +/* rdata */ + +int AP2x2Tbl[10] = { 8, 28, 6, 26, 4, 24, 2, 22, 0, 20 }; // weak + +//----- (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 invtest[40]; // [esp+18h] [ebp-A0h] + + CelDecodeOnly(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; + CelDecodeClr(v4, 517, 219, (char *)pCursCels, v2, v3, 0, 8); + v0 = myplr; + } + if ( plr[v0].InvBody[0]._iStatFlag ) + CelDrawHdrOnly(517, 219, (char *)pCursCels, v2, v3, 0, 8); + else + CelDrawHdrLightRed(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; + CelDecodeClr(v9, 432, 365, (char *)pCursCels, v7, v8, 0, 8); + v5 = myplr; + v8 = screen_y; + } + if ( plr[v5].InvBody[1]._iStatFlag ) + CelDrawHdrOnly(432, 365, (char *)pCursCels, v7, v8, 0, 8); + else + CelDrawHdrLightRed(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; + CelDecodeClr(v14, 633, 365, (char *)pCursCels, v12, v13, 0, 8); + v10 = myplr; + v13 = screen_ya; + } + if ( plr[v10].InvBody[2]._iStatFlag ) + CelDrawHdrOnly(633, 365, (char *)pCursCels, v12, v13, 0, 8); + else + CelDrawHdrLightRed(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; + CelDecodeClr(v19, 589, 220, (char *)pCursCels, v17, v18, 0, 8); + v15 = myplr; + v18 = screen_yb; + } + if ( plr[v15].InvBody[3]._iStatFlag ) + CelDrawHdrOnly(589, 220, (char *)pCursCels, v17, v18, 0, 8); + else + CelDrawHdrLightRed(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; + CelDecodeClr(v25, v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8); + v20 = myplr; + } + if ( plr[v20].InvBody[4]._iStatFlag ) + CelDrawHdrOnly(v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8); + else + CelDrawHdrLightRed(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]; + CelDecodeHdrLightTrans(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; + CelDecodeClr(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 ) + CelDrawHdrOnly(screen_x, screen_yd, (char *)pCursCels, v29, v30, 0, 8); + else + CelDrawHdrLightRed(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; + CelDecodeClr(v36, 517, 320, (char *)pCursCels, v34, v35, 0, 8); + v32 = myplr; + } + if ( plr[v32].InvBody[6]._iStatFlag ) + CelDrawHdrOnly(517, 320, (char *)pCursCels, v34, v35, 0, 8); + else + CelDrawHdrLightRed(517, 320, (char *)pCursCels, v34, v35, 0, 8, 1); + } + v37 = 0; + do + { + if ( plr[myplr].InvGrid[v37] ) + InvDrawSlotBack(InvRect[v37 + 25].X + 64, InvRect[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; + invtest[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; + CelDecodeClr( + v45, + InvRect[v38 + 25].X + 64, + InvRect[v38 + 25].Y + 159, + (char *)pCursCels, + v44, + screen_ye, + 0, + 8); + } + v46 = InvRect[v38 + 25].X + 64; + v47 = InvRect[v38 + 25].Y + 159; + if ( plr[myplr].InvList[v42]._iStatFlag ) + CelDrawHdrOnly(v46, v47, (char *)pCursCels, v44, screen_ye, 0, 8); + else + CelDrawHdrLightRed(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 + unsigned 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(InvRect[v11 + 65].X + 64, InvRect[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; + CelDecodeClr( + v5, + InvRect[v1 + 65].X + 64, + InvRect[v1 + 65].Y + 159, + (char *)pCursCels, + v4, + frame_width, + 0, + 8); + v2 = myplr; + } + v0 = v13; + v6 = InvRect[v1 + 65].Y + 159; + v7 = *(int *)((char *)&plr[v2].SpdList[0]._iStatFlag + v13) == 0; + v8 = InvRect[v1 + 65].X; + if ( v7 ) + CelDrawHdrLightRed(v8 + 64, v6, (char *)pCursCels, v4, frame_width, 0, 8, 1); + else + CelDrawHdrOnly(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 = fontframe[fontidx[(unsigned char)(v11 + 49)]]; + CPrintString( + screen_y_times_768[InvRect[v1 + 65].Y + 159] + - fontkern[v10] + + InvRect[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 = InvRect[v68].X; + if ( v6 >= v8 && v6 < v8 + 28 ) + { + v9 = InvRect[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; + drawpanflag = 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 drawpanflag; + +//----- (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; + RecreateItem(127, idx, wCI, seed, 0); + v7 = &plr[p]; + qmemcpy(&v7->HoldItem, &item[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 = InvRect[v5].X; + if ( mx >= v6 && mx < v6 + 29 ) + { + v7 = InvRect[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 = plr[v3].InvGrid[v5-25]; // *((_BYTE *)&plr[0].InvList[39]._iVAdd2 + v5 + v3 * 21720 + 3); /* find right address */ + 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; + drawpanflag = 255; + } + } +} +// 52571C: using guessed type int drawpanflag; + +//----- (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; + } + drawpanflag = 255; +} +// 52571C: using guessed type int drawpanflag; + +//----- (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[item[ii]._ix][item[ii]._iy] ) + { + if ( myplr == pnum && pcurs >= CURSOR_FIRSTITEM ) + NetSendCmdPItem(1u, CMD_SYNCPUTITEM, plr[myplr].WorldX, plr[myplr].WorldY); + _HIBYTE(item[v2]._iCreateInfo) &= 0x7Fu; + qmemcpy(&plr[pnuma].HoldItem, &item[v2], sizeof(plr[pnuma].HoldItem)); + CheckQuestItem(pnuma); + CheckBookLevel(pnuma); + CheckItemStats(pnuma); + v3 = 0; + dItem[item[v2]._ix][item[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[item[ii]._ix][item[ii]._iy] ) + { + v3 = pnum; + _HIBYTE(item[ii]._iCreateInfo) &= 0x7Fu; + v28 = ii; + qmemcpy(&plr[pnum].HoldItem, &item[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)&AP2x2Tbl[10] ); + 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[item[v28]._ix][item[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, &item[v28], sizeof(plr[v3].HoldItem)); + RespawnItem(i, 1); + NetSendCmdPItem(1u, CMD_RESPAWNITEM, item[v28]._ix, item[v28]._iy); + plr[v3].HoldItem._itype = ITYPE_NONE; + } +} +// 48E9A8: using guessed type int AP2x2Tbl[10]; +// 4B84DC: using guessed type int dropGoldFlag; + +//----- (0041E103) -------------------------------------------------------- +int __fastcall FindGetItem(int indx, unsigned short ci, int iseed) +{ + int i; // ebx + int ii; // esi + + i = 0; + if ( numitems <= 0 ) + return -1; + while ( 1 ) + { + ii = itemactive[i]; + if ( item[ii].IDidx == indx && item[ii]._iSeed == iseed && item[ii]._iCreateInfo == ci ) + break; + if ( ++i >= numitems ) + return -1; + } + return ii; +} + +//----- (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; // edx + int v9; // ecx + //int v10; // ecx + + v5 = dItem[x][y]; + if ( v5 + && (v6 = v5 - 1, v7 = v6, item[v7].IDidx == idx) + && item[v7]._iSeed == iseed + && item[v7]._iCreateInfo == ci ) + { + FindGetItem(idx, ci, iseed); + } + else + { + v6 = FindGetItem(idx, ci, iseed); + } + if ( v6 != -1 ) + { + v8 = 0; + dItem[item[v6]._ix][item[v6]._iy] = 0; + while ( v8 < numitems ) + { + v9 = itemactive[v8]; + if ( v9 == v6 ) + { + DeleteItem(v9, v8); + FindGetItem(idx, ci, iseed); + FindGetItem(idx, ci, iseed); /* check idx */ + v8 = 0; + } + else + { + ++v8; + } + } + 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]) ) /* check */ + 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 DrawInvMsg(char *msg) +{ + char *v1; // esi + int v2; // eax + + v1 = msg; + v2 = GetTickCount(); + if ( (unsigned int)(v2 - sgdwLastTime) >= 5000 ) + { + sgdwLastTime = v2; + ErrorPlrMsg(v1); + } +} + +//----- (0041E3E4) -------------------------------------------------------- +int __fastcall InvPutItem(int pnum, int x, int y) +{ + int v3; // edi + int *v4; // esi + int v5; // ebx + int v6; // esi + int v7; // eax + int v8; // edi + int v9; // esi + int v10; // esi + int v11; // eax + int v12; // edx + int v13; // esi + int v15; // eax + int *v16; // edx + int v17; // edx + ItemStruct *v18; // [esp+Ch] [ebp-1Ch] + int v19; // [esp+10h] [ebp-18h] + signed int v20; // [esp+14h] [ebp-14h] + int v21; // [esp+18h] [ebp-10h] + int v22; // [esp+1Ch] [ebp-Ch] + signed int v23; // [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; + v18 = &plr[pnum].HoldItem; + v5 = y; + if ( FindGetItem(plr[pnum].HoldItem.IDidx, x, plr[pnum].HoldItem._iSeed) != -1 ) + { + DrawInvMsg("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); + v6 = v5 - plr[v3].WorldY; + if ( abs(xa - plr[v3].WorldX) > 1 || abs(v6) > 1 ) + { + v5 = plr[v3].WorldY + offset_y[ya]; + xa = plr[v3].WorldX + offset_x[ya]; + } + if ( !CanPut(xa, v5) ) + { + v7 = plr[v3].WorldX; + v8 = plr[v3].WorldY; + v9 = ((_BYTE)ya - 1) & 7; + v19 = v7; + v5 = v8 + offset_y[v9]; + xa = v7 + offset_x[v9]; + if ( !CanPut(xa, v8 + offset_y[v9]) ) + { + v10 = ((_BYTE)v9 + 2) & 7; + v5 = v8 + offset_y[v10]; + xa = v19 + offset_x[v10]; + if ( !CanPut(xa, v8 + offset_y[v10]) ) + { + v23 = 0; + v11 = -1; + yb = 1; + v20 = -1; + while ( !v23 ) + { + v22 = v11; + while ( v11 <= yb && !v23 ) + { + v21 = v20; + v12 = v8 + v22; + v13 = v19 + v20; + do + { + if ( v23 ) + break; + if ( CanPut(v13, v12) ) + { + v23 = 1; + xa = v13; + v5 = v12; + } + ++v21; + ++v13; + } + while ( v21 <= yb ); + v11 = ++v22; + } + ++yb; + v11 = v20-- - 1; + if ( v20 <= -50 ) + { + if ( v23 ) + break; + return -1; + } + } + } + } + } + CanPut(xa, v5); + v15 = itemavail[0]; + dItem[xa][v5] = _LOBYTE(itemavail[0]) + 1; + yc = v15; + v16 = &itemavail[-numitems + 126]; + itemactive[numitems] = v15; + itemavail[0] = *v16; + v17 = v15; + qmemcpy(&item[v15], v18, sizeof(ItemStruct)); + item[v17]._iy = v5; + item[v17]._ix = xa; + RespawnItem(v15, 1); + ++numitems; + SetCursor(CURSOR_HAND); + 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 int ibuff) +{ + int v13; // ebx + int v14; // edi + int v15; // esi + 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; + v15 = y; + if ( FindGetItem(idx, icreateinfo, iseed) != -1 ) + { + DrawInvMsg("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 == IDI_EAR ) + { + RecreateEar(v25, icreateinfo, iseed, Id, dur, mdur, ch, mch, ivalue, ibuff); + } + else + { + RecreateItem(v25, idx, icreateinfo, iseed, ivalue); + if ( Id ) + item[ic]._iIdentified = 1; + v27 = ic; + item[v27]._iDurability = dur; + item[v27]._iMaxDur = mdur; + item[v27]._iCharges = ch; + item[v27]._iMaxCharges = mch; + } + v28 = ic; + item[v28]._ix = v13; + item[v28]._iy = v15; + RespawnItem(ic, 1); + ++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 = InvRect[v0].X; + if ( MouseX >= result ) + { + result += 29; + if ( MouseX < result ) + { + result = InvRect[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(v3->InvGrid[v0-25]); // abs(*((char *)&v3->InvList[39]._iVAdd2 + v0 + 3)); /* find right address */ + 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) -------------------------------------------------------- +bool __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 ) + return 0; + v0 = myplr; + v1 = 0; + v2 = plr[myplr]._pNumInv; + if ( v2 <= 0 ) + { +LABEL_11: + v4 = 0; + v5 = &plr[v0].SpdList[0]._iMiscId; + while ( *(v5 - 53) == -1 || *v5 != IMISC_SCROLL && *v5 != IMISC_SCROLLT || v5[1] != plr[v0]._pRSpell ) + { + ++v4; + v5 += 92; + if ( v4 >= 8 ) + return 0; + } + } + 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; + } + } + return 1; +} +// 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) -------------------------------------------------------- +bool __cdecl UseStaff() +{ + int v0; // eax + bool result; // al + + result = 0; + 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 > 0 ) + { + result = 1; + } + } + return result; +} + +//----- (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 ( pcursmonst != -1 && !M_Talker(pcursmonst) && !monster[pcursmonst].mtalkmsg ) + NetSendCmdParam1(1u, CMD_KNOCKBACK, pcursmonst); + SetCursor(CURSOR_HAND); +} +// 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; + drawpanflag = 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 drawpanflag; + +//----- (0041F068) -------------------------------------------------------- +int __cdecl DropItemBeforeTrig() +{ + if ( !TryInvPut() ) + return 0; + NetSendCmdPItem(1u, CMD_PUTITEM, cursmx, cursmy); + SetCursor(CURSOR_HAND); + return 1; +} diff --git a/Source/inv.h b/Source/inv.h new file mode 100644 index 0000000..1b3c649 --- /dev/null +++ b/Source/inv.h @@ -0,0 +1,65 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//inv +extern int invflag; +extern void *pInvCels; +extern int drawsbarflag; // idb +extern int sgdwLastTime; // check name + +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); +int __fastcall FindGetItem(int indx, unsigned short 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 DrawInvMsg(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 int ibuff); +int __cdecl CheckInvHLight(); +void __fastcall RemoveScroll(int pnum); +bool __cdecl UseScroll(); +void __fastcall UseStaffCharge(int pnum); +bool __cdecl UseStaff(); +void __cdecl StartGoldDrop(); +int __fastcall UseInvItem(int pnum, int cii); +void __cdecl DoTelekinesis(); +int __fastcall CalculateGold(int pnum); +int __cdecl DropItemBeforeTrig(); + +/* data */ + +extern InvXY InvRect[73]; + +/* rdata */ + +extern int AP2x2Tbl[10]; // weak diff --git a/Source/items.cpp b/Source/items.cpp new file mode 100644 index 0000000..b565ed3 --- /dev/null +++ b/Source/items.cpp @@ -0,0 +1,5803 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int itemactive[127]; +int uitemflag; +int itemavail[127]; +ItemStruct curruitem; +ItemGetRecordStruct itemrecord[127]; +ItemStruct item[128]; +char itemhold[3][3]; +char byte_641234[28]; /* check if part of above */ +int Item2Frm[35]; +int UniqueItemFlag[128]; +int numitems; +int gnNumGetRecords; + + +PLStruct PL_Prefix[84] = +{ + { "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 }, + { &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, -4 }, // cursed + { "tears", IPL_GETHIT, 1, 1, 2, PLT_ARMO|PLT_SHLD|PLT_MISC, 1, 0, 0, 0, 0, -2 }, + { "health", IPL_GETHIT_CURSE, 1, 1, 2, PLT_ARMO|PLT_SHLD|PLT_MISC, 16, 0, 1, 200, 200, 2 }, // not cursed + { "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, -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 }, + { &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, -1, -1, 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, -1, -1, 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 } +}; + +/* rdata */ + + +ItemDataStruct AllItemsList[157] = +{ + { IDROP_REGULAR, ICLASS_GOLD, ILOC_UNEQUIPABLE, 168, 11u, UITYPE_NONE, "Gold", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 1, 0, 0 }, + { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, 64, 1u, UITYPE_NONE, "Short Sword", NULL, 2, 20, 2, 6, 0, 0, 18u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 50, 50 }, + { IDROP_NEVER, ICLASS_ARMOR, ILOC_ONEHAND, 83, 5u, UITYPE_NONE, "Buckler", NULL, 2, 10, 0, 0, 3, 3, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 50, 50 }, + { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, 66, 4u, UITYPE_SPIKCLUB, "Club", NULL, 1, 20, 1, 6, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 20, 20 }, + { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, 118, 3u, UITYPE_NONE, "Short Bow", NULL, 1, 30, 1, 4, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 100, 100 }, + { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, 109, 10u, UITYPE_NONE, "Short Staff of Charged Bolt", NULL, 1, 25, 2, 4, 0, 0, 0u, 20u, 0u, ISPL_NONE, IMISC_STAFF, SPL_CBOLT, 0, 520, 520 }, + { IDROP_NEVER, ICLASS_WEAPON, ILOC_TWOHAND, 106, 2u, UITYPE_CLEAVER, "Cleaver", NULL, 10, 10, 4, 24, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 2000, 2000 }, + { IDROP_NEVER, ICLASS_ARMOR, ILOC_HELM, 78, 7u, UITYPE_SKCROWN, "The Undead Crown", NULL, 0, 50, 0, 0, 15, 15, 0u, 0u, 0u, ISPL_RNDSTEALLIFE, IMISC_UNIQUE, SPL_NULL, 0, 10000, 10000 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_RING, 18, 12u, UITYPE_INFRARING, "Empyrean Band", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 8000, 8000 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 76, 0u, UITYPE_NONE, "Magic Rock", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_AMULET, 44, 13u, UITYPE_OPTAMULET, "Optic Amulet", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 5000, 5000 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_RING, 10, 12u, UITYPE_TRING, "Ring of Truth", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 1000, 1000 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 126, 0u, UITYPE_NONE, "Tavern Sign", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_ARMOR, ILOC_HELM, 93, 7u, UITYPE_HARCREST, "Harlequin Crest", NULL, 0, 15, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 15, 20 }, + { IDROP_NEVER, ICLASS_ARMOR, ILOC_HELM, 85, 7u, UITYPE_STEELVEIL, "Veil of Steel", NULL, 0, 60, 0, 0, 18, 18, 0u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 17, 0u, UITYPE_ELIXIR, "Golden Elixir", NULL, 15, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 140, 0u, UITYPE_NONE, "Anvil of Fury", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 89, 0u, UITYPE_NONE, "Black Mushroom", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 40, 0u, UITYPE_NONE, "Brain", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 97, 0u, UITYPE_NONE, "Fungal Tome", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 15, 0u, UITYPE_ELIXIR, "Spectral Elixir", NULL, 15, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SPECELIX, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 25, 0u, UITYPE_NONE, "Blood Stone", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 96, 0u, UITYPE_MAPOFDOOM, "Map of the Stars", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_MAPOFDOOM, SPL_NULL, 1, 0, 0 }, + { IDROP_NEVER, ICLASS_QUEST, ILOC_UNEQUIPABLE, 19, 0u, UITYPE_NONE, "Heart", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_EAR, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 32, 0u, UITYPE_NONE, "Potion of Healing", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_HEAL, SPL_NULL, 1, 50, 50 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 39, 0u, UITYPE_NONE, "Potion of Mana", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_MANA, SPL_NULL, 1, 50, 50 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Identify", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_IDENTIFY, 1, 200, 200 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Town Portal", NULL, 4, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_TOWN, 1, 200, 200 }, + { IDROP_NEVER, ICLASS_ARMOR, ILOC_ARMOR, 157, 8u, UITYPE_ARMOFVAL, "Arkaine's Valor", NULL, 0, 40, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 35, 0u, UITYPE_NONE, "Potion of Full Healing", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_FULLHEAL, SPL_NULL, 1, 150, 150 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 0, 0u, UITYPE_NONE, "Potion of Full Mana", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_FULLMANA, SPL_NULL, 1, 150, 150 }, + { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, 61, 1u, UITYPE_GRISWOLD, "Griswold's Edge", NULL, 8, 50, 4, 12, 0, 0, 40u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 750, 750 }, + { IDROP_NEVER, ICLASS_WEAPON, ILOC_ONEHAND, 59, 4u, UITYPE_LGTFORGE, "Lightforge", NULL, 2, 32, 1, 8, 0, 0, 16u, 0u, 0u, ISPL_NONE, IMISC_UNIQUE, SPL_NULL, 0, 200, 200 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 155, 0u, UITYPE_LAZSTAFF, "Staff of Lazarus", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Resurrect", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_RESURRECT, 1, 250, 250 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_NONE, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, 91, 7u, UITYPE_NONE, "Cap", "Cap", 1, 15, 0, 0, 1, 3, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 15, 20 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, 90, 7u, UITYPE_SKULLCAP, "Skull Cap", "Cap", 4, 20, 0, 0, 2, 4, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 25, 30 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, 82, 7u, UITYPE_HELM, "Helm", "Helm", 8, 30, 0, 0, 4, 6, 25u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 40, 70 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, 75, 7u, UITYPE_NONE, "Full Helm", "Helm", 12, 35, 0, 0, 6, 8, 35u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 90, 130 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, 95, 7u, UITYPE_CROWN, "Crown", "Crown", 16, 40, 0, 0, 8, 12, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 200, 300 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_HELM, 98, 7u, UITYPE_GREATHELM, "Great Helm", "Helm", 20, 60, 0, 0, 10, 15, 50u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 400, 500 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 150, 6u, UITYPE_CAPE, "Cape", "Cape", 1, 12, 0, 0, 1, 5, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 10, 50 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 128, 6u, UITYPE_RAGS, "Rags", "Rags", 1, 6, 0, 0, 2, 6, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 5, 25 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 149, 6u, UITYPE_CLOAK, "Cloak", "Cloak", 2, 18, 0, 0, 3, 7, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 40, 70 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 137, 6u, UITYPE_ROBE, "Robe", "Robe", 3, 24, 0, 0, 4, 7, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 75, 125 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 129, 6u, UITYPE_NONE, "Quilted Armor", "Armor", 4, 30, 0, 0, 7, 10, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 200, 300 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 135, 6u, UITYPE_LEATHARMOR, "Leather Armor", "Armor", 6, 35, 0, 0, 10, 13, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 300, 400 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 127, 6u, UITYPE_NONE, "Hard Leather Armor", "Armor", 7, 40, 0, 0, 11, 14, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 450, 550 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 107, 6u, UITYPE_STUDARMOR, "Studded Leather Armor", "Armor", 9, 45, 0, 0, 15, 17, 20u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 700, 800 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 154, 8u, UITYPE_NONE, "Ring Mail", "Mail", 11, 50, 0, 0, 17, 20, 25u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 900, 1100 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 111, 8u, UITYPE_CHAINMAIL, "Chain Mail", "Mail", 13, 55, 0, 0, 18, 22, 30u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 1250, 1750 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 114, 8u, UITYPE_NONE, "Scale Mail", "Mail", 15, 60, 0, 0, 23, 28, 35u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 2300, 2800 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 153, 9u, UITYPE_BREASTPLATE, "Breast Plate", "Plate", 16, 80, 0, 0, 20, 24, 40u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 2800, 3200 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 136, 8u, UITYPE_NONE, "Splint Mail", "Mail", 17, 65, 0, 0, 30, 35, 40u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 3250, 3750 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 103, 9u, UITYPE_PLATEMAIL, "Plate Mail", "Plate", 19, 75, 0, 0, 42, 50, 60u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 4600, 5400 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 103, 9u, UITYPE_NONE, "Field Plate", "Plate", 21, 80, 0, 0, 40, 45, 65u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 5800, 6200 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 152, 9u, UITYPE_NONE, "Gothic Plate", "Plate", 23, 100, 0, 0, 50, 60, 80u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 8000, 10000 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ARMOR, 151, 9u, UITYPE_FULLPLATE, "Full Plate Mail", "Plate", 25, 90, 0, 0, 60, 75, 90u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 6500, 8000 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, 83, 5u, UITYPE_BUCKLER, "Buckler", "Shield", 1, 16, 0, 0, 1, 5, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 30, 70 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, 105, 5u, UITYPE_SMALLSHIELD, "Small Shield", "Shield", 5, 24, 0, 0, 3, 8, 25u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 90, 130 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, 147, 5u, UITYPE_LARGESHIELD, "Large Shield", "Shield", 9, 32, 0, 0, 5, 10, 40u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 200, 300 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, 113, 5u, UITYPE_KITESHIELD, "Kite Shield", "Shield", 14, 40, 0, 0, 8, 15, 50u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 400, 700 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, 132, 5u, UITYPE_GOTHSHIELD, "Tower Shield", "Shield", 20, 50, 0, 0, 12, 20, 60u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 850, 1200 }, + { IDROP_REGULAR, ICLASS_ARMOR, ILOC_ONEHAND, 148, 5u, UITYPE_GOTHSHIELD, "Gothic Shield", "Shield", 23, 60, 0, 0, 14, 18, 80u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 2300, 2700 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 32, 0u, UITYPE_NONE, "Potion of Healing", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_HEAL, SPL_NULL, 1, 50, 50 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 35, 0u, UITYPE_NONE, "Potion of Full Healing", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_FULLHEAL, SPL_NULL, 1, 150, 150 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 39, 0u, UITYPE_NONE, "Potion of Mana", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_MANA, SPL_NULL, 1, 50, 50 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 0, 0u, UITYPE_NONE, "Potion of Full Mana", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_FULLMANA, SPL_NULL, 1, 150, 150 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 37, 0u, UITYPE_NONE, "Potion of Rejuvenation", NULL, 3, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_REJUV, SPL_NULL, 1, 120, 120 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 33, 0u, UITYPE_NONE, "Potion of Full Rejuvenation", NULL, 7, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_FULLREJUV, SPL_NULL, 1, 600, 600 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 38, 0u, UITYPE_NONE, "Elixir of Strength", NULL, 15, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_ELIXSTR, SPL_NULL, 1, 5000, 5000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 34, 0u, UITYPE_NONE, "Elixir of Magic", NULL, 15, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_ELIXMAG, SPL_NULL, 1, 5000, 5000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 36, 0u, UITYPE_NONE, "Elixir of Dexterity", NULL, 15, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_ELIXDEX, SPL_NULL, 1, 5000, 5000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 31, 0u, UITYPE_NONE, "Elixir of Vitality", NULL, 20, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_ELIXVIT, SPL_NULL, 1, 5000, 5000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Healing", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_HEAL, 1, 50, 50 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Lightning", NULL, 4, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_LIGHTNING, 1, 150, 150 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Identify", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_IDENTIFY, 1, 100, 100 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Resurrect", NULL, 1, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_RESURRECT, 1, 250, 250 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Fire Wall", NULL, 4, 0, 0, 0, 0, 0, 0u, 17u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_FIREWALL, 1, 400, 400 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Inferno", NULL, 1, 0, 0, 0, 0, 0, 0u, 19u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_FLAME, 1, 100, 100 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Town Portal", NULL, 4, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_TOWN, 1, 200, 200 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Flash", NULL, 6, 0, 0, 0, 0, 0, 0u, 21u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_FLASH, 1, 500, 500 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Infravision", NULL, 8, 0, 0, 0, 0, 0, 0u, 23u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_INFRA, 1, 600, 600 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Phasing", NULL, 6, 0, 0, 0, 0, 0, 0u, 25u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_RNDTELEPORT, 1, 200, 200 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Mana Shield", NULL, 8, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_MANASHIELD, 1, 1200, 1200 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Flame Wave", NULL, 10, 0, 0, 0, 0, 0, 0u, 29u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_WAVE, 1, 650, 650 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Fireball", NULL, 8, 0, 0, 0, 0, 0, 0u, 31u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_FIREBALL, 1, 300, 300 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Stone Curse", NULL, 6, 0, 0, 0, 0, 0, 0u, 33u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_STONE, 1, 800, 800 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Chain Lightning", NULL, 10, 0, 0, 0, 0, 0, 0u, 35u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_CHAIN, 1, 750, 750 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Guardian", NULL, 12, 0, 0, 0, 0, 0, 0u, 47u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_GUARDIAN, 1, 950, 950 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Non Item", NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Nova", NULL, 14, 0, 0, 0, 0, 0, 0u, 57u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_NOVA, 1, 1300, 1300 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Golem", NULL, 10, 0, 0, 0, 0, 0, 0u, 51u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_GOLEM, 1, 1100, 1100 }, + { IDROP_NEVER, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of None", NULL, 99, 0, 0, 0, 0, 0, 0u, 61u, 0u, ISPL_NONE, IMISC_SCROLLT, SPL_NULL, 1, 1000, 1000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Teleport", NULL, 14, 0, 0, 0, 0, 0, 0u, 81u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_TELEPORT, 1, 3000, 3000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 1, 0u, UITYPE_NONE, "Scroll of Apocalypse", NULL, 22, 0, 0, 0, 0, 0, 0u, 117u, 0u, ISPL_NONE, IMISC_SCROLL, SPL_APOCA, 1, 2000, 2000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 88, 0u, UITYPE_NONE, "Book of ", NULL, 2, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_BOOK, SPL_NULL, 1, 0, 0 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 88, 0u, UITYPE_NONE, "Book of ", NULL, 8, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_BOOK, SPL_NULL, 1, 0, 0 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 88, 0u, UITYPE_NONE, "Book of ", NULL, 14, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_BOOK, SPL_NULL, 1, 0, 0 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_UNEQUIPABLE, 88, 0u, UITYPE_NONE, "Book of ", NULL, 20, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_BOOK, SPL_NULL, 1, 0, 0 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 51, 1u, UITYPE_DAGGER, "Dagger", "Dagger", 1, 16, 1, 4, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 60, 60 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 64, 1u, UITYPE_NONE, "Short Sword", "Sword", 1, 24, 2, 6, 0, 0, 18u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 120, 120 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 62, 1u, UITYPE_FALCHION, "Falchion", "Sword", 2, 20, 4, 8, 0, 0, 30u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 250, 250 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 72, 1u, UITYPE_SCIMITAR, "Scimitar", "Sword", 4, 28, 3, 7, 0, 0, 23u, 0u, 23u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 200, 200 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 65, 1u, UITYPE_CLAYMORE, "Claymore", "Sword", 5, 36, 1, 12, 0, 0, 35u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 450, 450 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 56, 1u, UITYPE_NONE, "Blade", "Blade", 4, 30, 3, 8, 0, 0, 25u, 0u, 30u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 280, 280 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 67, 1u, UITYPE_SABRE, "Sabre", "Sabre", 1, 45, 1, 8, 0, 0, 17u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 170, 170 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 60, 1u, UITYPE_LONGSWR, "Long Sword", "Sword", 6, 40, 2, 10, 0, 0, 30u, 0u, 30u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 350, 350 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 61, 1u, UITYPE_BROADSWR, "Broad Sword", "Sword", 8, 50, 4, 12, 0, 0, 40u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 750, 750 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 57, 1u, UITYPE_BASTARDSWR, "Bastard Sword", "Sword", 10, 60, 6, 15, 0, 0, 50u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 1000, 1000 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 110, 1u, UITYPE_TWOHANDSWR, "Two-Handed Sword", "Sword", 14, 75, 8, 16, 0, 0, 65u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 1800, 1800 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 134, 1u, UITYPE_GREATSWR, "Great Sword", "Sword", 17, 100, 10, 20, 0, 0, 75u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 3000, 3000 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 112, 2u, UITYPE_SMALLAXE, "Small Axe", "Axe", 2, 24, 2, 10, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 150, 150 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 144, 2u, UITYPE_NONE, "Axe", "Axe", 4, 32, 4, 12, 0, 0, 22u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 450, 450 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 142, 2u, UITYPE_LARGEAXE, "Large Axe", "Axe", 6, 40, 6, 16, 0, 0, 30u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 750, 750 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 141, 2u, UITYPE_BROADAXE, "Broad Axe", "Axe", 8, 50, 8, 20, 0, 0, 50u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 1000, 1000 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 101, 2u, UITYPE_BATTLEAXE, "Battle Axe", "Axe", 10, 60, 10, 25, 0, 0, 65u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 1500, 1500 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 143, 2u, UITYPE_GREATAXE, "Great Axe", "Axe", 12, 75, 12, 30, 0, 0, 80u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 2500, 2500 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 59, 4u, UITYPE_MACE, "Mace", "Mace", 2, 32, 1, 8, 0, 0, 16u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 200, 200 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 63, 4u, UITYPE_MORNSTAR, "Morning Star", "Mace", 3, 40, 1, 10, 0, 0, 26u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 300, 300 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 121, 4u, UITYPE_WARHAMMER, "War Hammer", "Hammer", 5, 50, 5, 9, 0, 0, 40u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 600, 600 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 70, 4u, UITYPE_SPIKCLUB, "Spiked Club", "Club", 4, 20, 3, 6, 0, 0, 18u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 225, 225 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 66, 4u, UITYPE_SPIKCLUB, "Club", "Club", 1, 20, 1, 6, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 20, 20 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_ONEHAND, 131, 4u, UITYPE_FLAIL, "Flail", "Flail", 7, 36, 2, 12, 0, 0, 30u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 500, 500 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 122, 4u, UITYPE_MAUL, "Maul", "Maul", 10, 50, 6, 20, 0, 0, 55u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 900, 900 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 118, 3u, UITYPE_SHORTBOW, "Short Bow", "Bow", 1, 30, 1, 4, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 100, 100 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 102, 3u, UITYPE_HUNTBOW, "Hunter's Bow", "Bow", 3, 40, 2, 5, 0, 0, 20u, 0u, 35u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 350, 350 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 102, 3u, UITYPE_LONGBOW, "Long Bow", "Bow", 5, 35, 1, 6, 0, 0, 25u, 0u, 30u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 250, 250 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 133, 3u, UITYPE_COMPBOW, "Composite Bow", "Bow", 7, 45, 3, 6, 0, 0, 25u, 0u, 40u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 600, 600 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 167, 3u, UITYPE_NONE, "Short Battle Bow", "Bow", 9, 45, 3, 7, 0, 0, 30u, 0u, 50u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 750, 750 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 119, 3u, UITYPE_BATTLEBOW, "Long Battle Bow", "Bow", 11, 50, 1, 10, 0, 0, 30u, 0u, 60u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 1000, 1000 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 165, 3u, UITYPE_NONE, "Short War Bow", "Bow", 15, 55, 4, 8, 0, 0, 35u, 0u, 70u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 1500, 1500 }, + { IDROP_DOUBLE, ICLASS_WEAPON, ILOC_TWOHAND, 119, 3u, UITYPE_WARBOW, "Long War Bow", "Bow", 19, 60, 1, 14, 0, 0, 45u, 0u, 80u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 2000, 2000 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 109, 10u, UITYPE_SHORTSTAFF, "Short Staff", "Staff", 1, 25, 2, 4, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_STAFF, SPL_NULL, 0, 30, 30 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 123, 10u, UITYPE_LONGSTAFF, "Long Staff", "Staff", 4, 35, 4, 8, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_STAFF, SPL_NULL, 0, 100, 100 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 166, 10u, UITYPE_COMPSTAFF, "Composite Staff", "Staff", 6, 45, 5, 10, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_STAFF, SPL_NULL, 0, 500, 500 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 109, 10u, UITYPE_QUARSTAFF, "Quarter Staff", "Staff", 9, 55, 6, 12, 0, 0, 20u, 0u, 0u, ISPL_NONE, IMISC_STAFF, SPL_NULL, 0, 1000, 1000 }, + { IDROP_REGULAR, ICLASS_WEAPON, ILOC_TWOHAND, 124, 10u, UITYPE_WARSTAFF, "War Staff", "Staff", 12, 75, 8, 16, 0, 0, 30u, 0u, 0u, ISPL_NONE, IMISC_STAFF, SPL_NULL, 0, 1500, 1500 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_RING, 12, 12u, UITYPE_RING, "Ring", "Ring", 5, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_RING, SPL_NULL, 0, 1000, 1000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_RING, 12, 12u, UITYPE_RING, "Ring", "Ring", 10, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_RING, SPL_NULL, 0, 1000, 1000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_RING, 12, 12u, UITYPE_RING, "Ring", "Ring", 15, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_RING, SPL_NULL, 0, 1000, 1000 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_AMULET, 45, 13u, UITYPE_AMULET, "Amulet", "Amulet", 8, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_AMULET, SPL_NULL, 0, 1200, 1200 }, + { IDROP_REGULAR, ICLASS_MISC, ILOC_AMULET, 45, 13u, UITYPE_AMULET, "Amulet", "Amulet", 16, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_AMULET, SPL_NULL, 0, 1200, 1200 }, + { IDROP_NEVER, ICLASS_NONE, ILOC_INVALID, 0, 0u, UITYPE_NONE, NULL, NULL, 0, 0, 0, 0, 0, 0, 0u, 0u, 0u, ISPL_NONE, IMISC_NONE, SPL_NULL, 0, 0, 0 } +}; +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; // weak +int premiumlvladd[6] = { -1, -1, 0, 0, 1, 2 }; + +//----- (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 i; // eax + int ii; // ebx + int xx; // esi + int yy; // eax + int j; // eax + + i = random(11, 3) + 3; + if ( i > 0 ) + { + do + { + ii = itemavail[0]; + itemactive[numitems] = itemavail[0]; + itemavail[0] = itemavail[-numitems + 126]; + do + { + xx = random(12, 80) + 16; + yy = random(12, 80) + 16; + } + while ( !ItemPlace(xx, yy) ); + item[ii]._ix = xx; + item[ii]._iy = yy; + dItem[xx][yy] = ii + 1; + j = GetRndSeed(); + item[ii]._iSeed = j; + SetRndSeed(j); + if ( random(12, 2) ) + GetItemAttrs(ii, IDI_HEAL, currlevel); + else + GetItemAttrs(ii, IDI_MANA, currlevel); + item[ii]._iCreateInfo = currlevel + -32768; + SetupItem(ii); + item[ii]._iAnimFlag = 0; + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iSelFlag = 1; + DeltaAddItem(ii); + ++numitems; + --i; + } + while ( i ); + } +} + +//----- (0041F24E) -------------------------------------------------------- +void __cdecl InitItems() +{ + int *v0; // eax + int v1; // edx + + GetItemAttrs(0, IDI_GOLD, 1); + numitems = 0; + qmemcpy(&golditem, item, sizeof(golditem)); + golditem._iStatFlag = 1; + v0 = &item[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)&item[128]._ix ); + v1 = 0; + memset(itemactive, 0, sizeof(itemactive)); + do + { + itemavail[v1] = v1; + ++v1; + } + while ( v1 < 127 ); + if ( !setlevel ) + { + GetRndSeed(); + if ( QuestStatus(0) ) + SpawnRock(); + if ( QuestStatus(10) ) + 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 p, bool Loadgfx) +{ + 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 = p; + v3 = 0; + v4 = 0; + v5 = arglist; + v38 = Loadgfx; + 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; + drawpanflag = 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]._pNAnim[plr[v5]._pdir + 5430 * arglist]; + plr[v5]._pAnimFrame = 1; + plr[v5]._pAnimData = v31; + plr[v5]._pAnimLen = plr[v5]._pNFrames; + v32 = plr[v5]._pNWidth; + 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 drawpanflag; + +//----- (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; + drawpanflag = 255; + } + } +} +// 52571C: using guessed type int drawpanflag; + +//----- (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 + ItemStruct *v6; // edi + signed int v7; // ebp + + v1 = &plr[pnum]; + v2 = v1; + v3 = v1->InvList; + if ( v1->_pNumInv ) + { + v4 = v1->_pNumInv; + do + { + v3->_iStatFlag = ItemMinStats(v2, v3); + ++v3; + --v4; + } + while ( v4 ); + } + v6 = v2->SpdList; + v7 = 8; + do + { + if ( v6->_itype != -1 ) + { + v6->_iStatFlag = ItemMinStats(v2, v6); + } + ++v6; + --v7; + } + while ( v7 ); +} + +//----- (0041FBF6) -------------------------------------------------------- +bool __fastcall ItemMinStats(PlayerStruct *p, ItemStruct *x) +{ + if ( p->_pStrength < x->_iMinStr || p->_pMagic < x->_iMinMag || p->_pDexterity < x->_iMinDex ) + return 0; + else + return 1; +} + +//----- (0041FC2C) -------------------------------------------------------- +void __fastcall CalcPlrBookVals(int p) +{ + int v1; // esi + int v2; // ebx + int *v3; // edi + int v5; // esi + int *v6; // edi + int v7; // eax + unsigned char v8; // cl + unsigned char v9; // cl + int v10; // 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); + *v3 = StoreStatOk((ItemStruct *)(v3 - 89)); + 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; + } + v6[33] = ItemMinStats(&plr[v5], (ItemStruct *)(v6 - 56)); + } + ++v12; + v6 += 92; + } + while ( v12 < plr[v5]._pNumInv ); + } +} + +//----- (0041FD3E) -------------------------------------------------------- +void __fastcall 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 ) + RecalcStoreStats(); + } +} + +//----- (0041FD98) -------------------------------------------------------- +void __fastcall SetPlrHandItem(ItemStruct *h, int idata) +{ + ItemDataStruct *pAllItem; // edi + + pAllItem = &AllItemsList[idata]; + memset(h, 0, 0x170u); + 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->_iPrePower = -1; + h->_iSufPower = -1; + h->_iMagical = 0; + h->_iIvalue = pAllItem->iValue; + h->IDidx = idata; +} + +//----- (0041FE98) -------------------------------------------------------- +void __fastcall GetPlrHandSeed(ItemStruct *h) +{ + h->_iSeed = GetRndSeed(); +} + +//----- (0041FEA4) -------------------------------------------------------- +void __fastcall GetGoldSeed(int pnum, ItemStruct *h) +{ + int v3; // edi + signed int v4; // esi + int v5; // eax + int i; // ecx + int v7; // edx + ItemStruct *v8; // ecx + + v3 = pnum; + do + { + v4 = 1; + v5 = GetRndSeed(); + for ( i = 0; i < numitems; ++i ) + { + if ( item[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 ); + h->_iSeed = 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 p) +{ + 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 = p; + v1 = p; + v2 = &plr[p].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], IDI_WARRIOR); + GetPlrHandSeed(&plr[v1].InvBody[4]); + SetPlrHandItem(&plr[v1].InvBody[5], IDI_WARRSHLD); + GetPlrHandSeed(&plr[v1].InvBody[5]); + SetPlrHandItem(&plr[v1].HoldItem, IDI_WARRCLUB); + GetPlrHandSeed(&plr[v1].HoldItem); + AutoPlace(player_numa, 0, 1, 3, 1); + goto LABEL_13; + case UI_ROGUE: + SetPlrHandItem(&plr[v1].InvBody[4], IDI_ROGUE); + GetPlrHandSeed(&plr[v1].InvBody[4]); +LABEL_13: + SetPlrHandItem(plr[v1].SpdList, IDI_HEAL); + GetPlrHandSeed(plr[v1].SpdList); + SetPlrHandItem(&plr[v1].SpdList[1], IDI_HEAL); + goto LABEL_14; + case UI_SORCERER: + SetPlrHandItem(&plr[v1].InvBody[4], IDI_SORCEROR); + GetPlrHandSeed(&plr[v1].InvBody[4]); + SetPlrHandItem(plr[v1].SpdList, IDI_MANA); + GetPlrHandSeed(plr[v1].SpdList); + SetPlrHandItem(&plr[v1].SpdList[1], IDI_MANA); +LABEL_14: + GetPlrHandSeed(&plr[v1].SpdList[1]); + break; + } + SetPlrHandItem(&plr[v1].HoldItem, IDI_GOLD); + 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) -------------------------------------------------------- +bool __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]) ) /* check */ + 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) -------------------------------------------------------- +bool __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 + 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 + { + *(_DWORD *)v7 = ItemSpaceOk(v6, v4); + 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)&itemhold[3][0] ); + _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; + item[v18]._ix = v16; + dItem[v16][v17] = inum + 1; + item[v18]._iy = v17; + return 1; +} + +//----- (004202E8) -------------------------------------------------------- +void __fastcall GetSuperItemSpace(int x, int y, char inum) +{ + signed int v4; // edi + signed int v5; // ebx + int v6; // edx + int v7; // esi + 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; + if ( !GetItemSpace(x, y, inum) ) + { + v13 = 2; + v4 = -2; + do + { + v5 = v4; + if ( v4 <= v13 ) + { + while ( 2 ) + { + v12 = v4; + v6 = v5 + v11; + v7 = v4 + v10; + do + { + if ( ItemSpaceOk(v7, v6) ) + { + v9 = inum; + item[v9]._ix = v7; + item[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 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; + if ( ItemSpaceOk(v6, *yy) ) + 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 = item[v1]._iVMult1 + item[v1]._iVMult2; + v3 = v2 < 0; + if ( v2 > 0 ) + { + v2 *= item[v1]._ivalue; + v3 = v2 < 0; + } + if ( v3 ) + v2 = item[v1]._ivalue / v2; + v4 = item[v1]._iVAdd1 + item[v1]._iVAdd2 + v2; + if ( v4 <= 0 ) + v4 = 1; + item[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 == SPL_RESURRECT ) + v6 = SPL_TELEKINESIS; + if ( v6 == SPL_HEALOTHER ) + v6 = SPL_FLARE; + } + if ( v6 == 37 ) + goto LABEL_13; + } + v7 = v3; + v8 = (const char **)&spelldata[v11].sNameText; + strcat(item[v7]._iName, *v8); + strcat(item[v7]._iIName, *v8); + item[v7]._iSpell = v11; + item[v7]._iMinMag = spelldata[v11].sMinInt; + v9 = spelldata[v11].sBookCost; + item[v7]._ivalue += v9; + item[v7]._iIvalue += v9; + v10 = spelldata[v11].sType; + if ( v10 == STYPE_FIRE ) + item[v7]._iCurs = 87; // Red Book + if ( v10 == STYPE_LIGHTNING ) + item[v7]._iCurs = 88; // Blue Book + if ( v10 == STYPE_MAGIC ) + item[v7]._iCurs = 86; // Black Book +} +// 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 v9; // edi + int v10; // ecx + int v11; // ST14_4 + int v12; // esi + char *v13; // edi + int l[256]; // [esp+Ch] [ebp-484h] + char istr[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 ( PL_Prefix[0].PLPower != -1 ) + { + do + { + if ( PL_Prefix[v7].PLIType & 0x100 && PL_Prefix[v7].PLMinLvl <= v4 && (!onlygood || PL_Prefix[v7].PLOk) ) + { + l[v6++] = v7; + if ( PL_Prefix[v7].PLDouble ) + l[v6++] = v7; + } + ++v7; + } + while ( PL_Prefix[v7].PLPower != -1 ); + if ( v6 ) + { + _LOBYTE(v7) = 16; + v5 = l[random(v7, v6)]; + v9 = ia; + v17 = item[ia]._iIName; + sprintf(istr, "%s %s", PL_Prefix[v5].PLName, item[ia]._iIName); + strcpy(v17, istr); + v10 = ia; + v11 = PL_Prefix[v5].PLMultVal; + item[v9]._iMagical = 1; + SaveItemPower( + v10, + PL_Prefix[v5].PLPower, + PL_Prefix[v5].PLParam1, + PL_Prefix[v5].PLParam2, + PL_Prefix[v5].PLMinVal, + PL_Prefix[v5].PLMaxVal, + v11); + item[v9]._iPrePower = PL_Prefix[v5].PLPower; + } + } + } + v12 = ia; + v13 = item[ia]._iIName; + if ( !control_WriteStringToBuffer(item[ia]._iIName) ) + { + strcpy(v13, AllItemsList[item[v12].IDidx].iSName); + if ( v5 != -1 ) + { + sprintf(istr, "%s %s", PL_Prefix[v5].PLName, v13); + strcpy(v13, istr); + } + sprintf(istr, "%s of %s", v13, spelldata[bs].sNameText); + strcpy(v13, istr); + if ( !item[v12]._iMagical ) + strcpy(item[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 l; // esi + int rv; // eax + int s; // ecx + int minc; // ebx + int maxc; // edx + int v; // eax + char istr[64]; // [esp+4h] [ebp-4Ch] + int bs; // [esp+4Ch] [ebp-4h] + + if ( random(17, 4) ) + { + l = lvl >> 1; + if ( !l ) + l = 1; + rv = random(18, 37) + 1; +LABEL_15: + s = 1; + while ( rv > 0 ) + { + if ( spelldata[s].sStaffLvl != -1 && l >= spelldata[s].sStaffLvl ) + { + --rv; + bs = s; + } + ++s; + if ( gbMaxPlayers == 1 ) + { + if ( s == SPL_RESURRECT ) + s = SPL_TELEKINESIS; + if ( s == SPL_HEALOTHER ) + s = SPL_FLARE; + } + if ( s == 37 ) + goto LABEL_15; + } + 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); + minc = spelldata[bs].sStaffMin; + maxc = spelldata[bs].sStaffMax - minc + 1; + item[i]._iSpell = bs; + v = random(19, maxc) + minc; + item[i]._iMinMag = spelldata[bs].sMinInt; + item[i]._iCharges = v; + item[i]._iMaxCharges = v; + v = (v * spelldata[bs].sStaffCost) / 5; + item[i]._ivalue += v; + item[i]._iIvalue += v; + GetStaffPower(i, lvl, bs, onlygood); + } + else + { + GetItemPower(i, lvl >> 1, lvl, 256, onlygood); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0042084A) -------------------------------------------------------- +void __fastcall GetItemAttrs(int i, int idata, int lvl) +{ + int rndv; // eax + + 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]._iMiscId = AllItemsList[idata].iMiscId; + item[i]._iAC = AllItemsList[idata].iMinAC + random(20, AllItemsList[idata].iMaxAC - AllItemsList[idata].iMinAC + 1); + item[i]._iFlags = AllItemsList[idata].iFlags; + item[i]._iSpell = AllItemsList[idata].iSpell; + item[i]._ivalue = AllItemsList[idata].iValue; + item[i]._iIvalue = AllItemsList[idata].iValue; + item[i]._iMagical = 0; + item[i]._iDurability = AllItemsList[idata].iDurability; + item[i]._iMaxDur = AllItemsList[idata].iDurability; + item[i]._iVAdd1 = 0; + item[i]._iMinStr = AllItemsList[idata].iMinStr; + item[i]._iMinMag = AllItemsList[idata].iMinMag; + item[i]._iMinDex = AllItemsList[idata].iMinDex; + 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]._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]._iPrePower = -1; + item[i]._iSufPower = -1; + 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; + + if ( AllItemsList[idata].iMiscId == IMISC_BOOK ) + GetBookSpell(i, lvl); + + if ( item[i]._itype == ITYPE_GOLD ) + { + if ( gnDifficulty ) /* clean this up, NORMAL */ + rndv = lvl; + else + 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 == 4 ) + rndv += rndv >> 3; + if ( rndv > 5000 ) + rndv = 5000; + + item[i]._ivalue = rndv; + + if ( rndv < 2500 ) + item[i]._iCurs = (rndv > 1000) + 4; + else + item[i]._iCurs = 6; + } +} +// 5BB1ED: using guessed type char leveltype; + +//----- (00420B17) -------------------------------------------------------- +int __fastcall RndPL(int param1, int param2) +{ + return param1 + random(22, param2 - param1 + 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 = &item[v8]._iPLToHit; + goto LABEL_115; + case IPL_TOHIT_CURSE: + v12 = &item[v8]._iPLToHit; + goto LABEL_62; + case IPL_DAMP: + v11 = &item[v8]._iPLDam; + goto LABEL_115; + case IPL_DAMP_CURSE: + v12 = &item[v8]._iPLDam; + goto LABEL_62; + case IPL_TOHIT_DAMP: + v10 = RndPL(param1, param2); + v13 = v8; + item[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); + item[v13]._iPLToHit += v14; + break; + case IPL_TOHIT_DAMP_CURSE: + v15 = v8; + item[v15]._iPLDam -= v9; + if ( param1 == 25 ) + v16 = RndPL(1, 5); + else + v16 = param1; + if ( param1 == 50 ) + v16 = RndPL(6, 10); + item[v15]._iPLToHit -= v16; + break; + case IPL_ACP: + v11 = &item[v8]._iPLAC; + goto LABEL_115; + case IPL_ACP_CURSE: + v12 = &item[v8]._iPLAC; + goto LABEL_62; + case IPL_FIRERES: + v11 = &item[v8]._iPLFR; + goto LABEL_115; + case IPL_LIGHTRES: + v11 = &item[v8]._iPLLR; + goto LABEL_115; + case IPL_MAGICRES: + v11 = &item[v8]._iPLMR; + goto LABEL_115; + case IPL_ALLRES: + v17 = v8; + item[v17]._iPLFR += v10; + v18 = item[v8]._iPLFR; + item[v17]._iPLLR += v10; + item[v17]._iPLMR += v10; + v19 = item[v8]._iPLLR; + v20 = item[v8]._iPLMR; + if ( v18 < 0 ) + item[v17]._iPLFR = 0; + if ( v19 < 0 ) + item[v17]._iPLLR = 0; + if ( v20 < 0 ) + item[v17]._iPLMR = 0; + break; + case IPL_SPLLVLADD: + item[v8]._iSplLvlAdd = v9; + break; + case IPL_CHARGES: + v21 = &item[v8]._iCharges; + v22 = param1 * *v21; + *v21 = v22; + item[v8]._iMaxCharges = v22; + break; + case IPL_FIREDAM: + v24 = v8; + item[v24]._iFlags |= 0x10u; + goto LABEL_77; + case IPL_LIGHTDAM: + v25 = v8; + item[v25]._iFlags |= 0x20u; + goto LABEL_79; + case IPL_STR: + v11 = &item[v8]._iPLStr; + goto LABEL_115; + case IPL_STR_CURSE: + v12 = &item[v8]._iPLStr; + goto LABEL_62; + case IPL_MAG: + v11 = &item[v8]._iPLMag; + goto LABEL_115; + case IPL_MAG_CURSE: + v12 = &item[v8]._iPLMag; + goto LABEL_62; + case IPL_DEX: + v11 = &item[v8]._iPLDex; + goto LABEL_115; + case IPL_DEX_CURSE: + v12 = &item[v8]._iPLDex; + goto LABEL_62; + case IPL_VIT: + v11 = &item[v8]._iPLVit; + goto LABEL_115; + case IPL_VIT_CURSE: + v12 = &item[v8]._iPLVit; + goto LABEL_62; + case IPL_ATTRIBS: + v26 = v8; + item[v26]._iPLStr += v10; + item[v26]._iPLMag += v10; + item[v26]._iPLDex += v10; + item[v26]._iPLVit += v10; + break; + case IPL_ATTRIBS_CURSE: + v27 = v8; + item[v27]._iPLStr -= v10; + item[v27]._iPLMag -= v10; + item[v27]._iPLDex -= v10; + item[v27]._iPLVit -= v10; + break; + case IPL_GETHIT: + v11 = &item[v8]._iPLGetHit; + goto LABEL_115; + case IPL_GETHIT_CURSE: + v12 = &item[v8]._iPLGetHit; + goto LABEL_62; + case IPL_LIFE: + v28 = v9 << 6; + v29 = &item[v8]._iPLHP; + goto LABEL_73; + case IPL_LIFE_CURSE: + v30 = v9 << 6; + v31 = &item[v8]._iPLHP; + goto LABEL_75; + case IPL_MANA: + item[v8]._iPLMana += v9 << 6; + goto LABEL_92; + case IPL_MANA_CURSE: + item[v8]._iPLMana -= v9 << 6; + goto LABEL_92; + case IPL_DUR: + v32 = v8; + v33 = item[v8]._iMaxDur; + v34 = v33; + v35 = v10 * v33 / 100; + item[v32]._iDurability += v35; + item[v32]._iMaxDur = v35 + v34; + break; + case IPL_DUR_CURSE: + v36 = v8; + v37 = item[v8]._iMaxDur - v9 * item[v8]._iMaxDur / 100; + item[v8]._iMaxDur = v37; + if ( v37 < 1 ) + item[v36]._iMaxDur = 1; + item[v36]._iDurability = item[v36]._iMaxDur; + break; + case IPL_INDESTRUCTIBLE: + v38 = 255; + goto LABEL_119; + case IPL_LIGHT: + v28 = param1; + v29 = &item[v8]._iPLLight; +LABEL_73: + *v29 += v28; + break; + case IPL_LIGHT_CURSE: + v30 = param1; + v31 = &item[v8]._iPLLight; +LABEL_75: + *v31 -= v30; + break; + case IPL_FIRE_ARROWS: + v24 = v8; + item[v24]._iFlags |= 8u; +LABEL_77: + item[v24]._iFMinDam = param1; + item[v24]._iFMaxDam = param2; + break; + case IPL_LIGHT_ARROWS: + v25 = v8; + _HIBYTE(item[v8]._iFlags) |= 2u; +LABEL_79: + item[v25]._iLMinDam = param1; + item[v25]._iLMaxDam = param2; + break; + case IPL_INVCURS: + item[v8]._iCurs = param1; + break; + case IPL_THORNS: + _HIBYTE(item[v8]._iFlags) |= 4u; + break; + case IPL_NOMANA: + _HIBYTE(item[v8]._iFlags) |= 8u; + goto LABEL_92; + case IPL_NOHEALPLR: + BYTE1(item[v8]._iFlags) |= 1u; + break; + case IPL_ABSHALFTRAP: + _HIBYTE(item[v8]._iFlags) |= 0x10u; + break; + case IPL_KNOCKBACK: + BYTE1(item[v8]._iFlags) |= 8u; + break; + case IPL_NOHEALMON: + BYTE1(item[v8]._iFlags) |= 0x10u; + break; + case IPL_STEALMANA: + if ( param1 == 3 ) + BYTE1(item[v8]._iFlags) |= 0x20u; + if ( param1 == 5 ) + BYTE1(item[v8]._iFlags) |= 0x40u; +LABEL_92: + drawmanaflag = 1; + break; + case IPL_STEALLIFE: + if ( param1 == 3 ) + BYTE1(item[v8]._iFlags) |= 0x80u; + if ( param1 == 5 ) + BYTE2(item[v8]._iFlags) |= 1u; + drawhpflag = 1; + break; + case IPL_TARGAC: + v11 = &item[v8]._iPLEnAc; + goto LABEL_115; + case IPL_FASTATTACK: + if ( param1 == 1 ) + BYTE2(item[v8]._iFlags) |= 2u; + if ( param1 == 2 ) + BYTE2(item[v8]._iFlags) |= 4u; + if ( param1 == 3 ) + BYTE2(item[v8]._iFlags) |= 8u; + if ( param1 == 4 ) + BYTE2(item[v8]._iFlags) |= 0x10u; + break; + case IPL_FASTRECOVER: + if ( param1 == 1 ) + BYTE2(item[v8]._iFlags) |= 0x20u; + if ( param1 == 2 ) + BYTE2(item[v8]._iFlags) |= 0x40u; + if ( param1 == 3 ) + BYTE2(item[v8]._iFlags) |= 0x80u; + break; + case IPL_FASTBLOCK: + _HIBYTE(item[v8]._iFlags) |= 1u; + break; + case IPL_DAMMOD: + v11 = &item[v8]._iPLDamMod; +LABEL_115: + *v11 += v10; + break; + case IPL_RNDARROWVEL: + item[v8]._iFlags |= 4u; + break; + case IPL_SETDAM: + v39 = v8; + item[v39]._iMinDam = param1; + item[v39]._iMaxDam = param2; + break; + case IPL_SETDUR: + v38 = param1; +LABEL_119: + v40 = v8; + item[v40]._iDurability = v38; + item[v40]._iMaxDur = v38; + break; + case IPL_NOMINSTR: + item[v8]._iMinStr = 0; + break; + case IPL_SPELL: + v23 = v8; + item[v23]._iSpell = param1; + item[v23]._iCharges = param1; + item[v23]._iMaxCharges = param2; + break; + case IPL_FASTSWING: + BYTE2(item[v8]._iFlags) |= 8u; + break; + case IPL_ONEHAND: + item[v8]._iLoc = ILOC_ONEHAND; + break; + case IPL_3XDAMVDEM: + _HIBYTE(item[v8]._iFlags) |= 0x40u; + break; + case IPL_ALLRESZERO: + _HIBYTE(item[v8]._iFlags) |= 0x80u; + break; + case IPL_DRAINLIFE: + item[v8]._iFlags |= 0x40u; + break; + case IPL_RNDSTEALLIFE: + item[v8]._iFlags |= 2u; + break; + case IPL_INFRAVISION: + item[v8]._iFlags |= 1u; + break; + case IPL_SETAC: + item[v8]._iAC = v9; + break; + case IPL_ADDACLIFE: + item[v8]._iPLHP = (plr[myplr]._pIBonusAC + plr[myplr]._pIAC + plr[myplr]._pDexterity / 5) << 6; + break; + case IPL_ADDMANAAC: + item[v8]._iAC += (plr[myplr]._pMaxManaBase >> 6) / 10; + break; + case IPL_FIRERESCLVL: + v41 = 30 - plr[myplr]._pLevel; + v42 = &item[v8]._iPLFR; + *v42 = v41; + if ( v41 < 0 ) + *v42 = 0; + break; + case IPL_AC_CURSE: + v12 = &item[v8]._iAC; +LABEL_62: + *v12 -= v10; + break; + default: + break; + } + v43 = v8; + if ( item[v43]._iVAdd1 || item[v43]._iVMult1 ) + { + item[v43]._iVAdd2 = PLVal(v10, param1, param2, minval, maxval); + item[v43]._iVMult2 = multval; + } + else + { + item[v43]._iVAdd1 = PLVal(v10, param1, param2, minval, maxval); + item[v43]._iVMult1 = multval; + } +} + +//----- (004215EF) -------------------------------------------------------- +void __fastcall GetItemPower(int i, int minlvl, int maxlvl, int flgs, int onlygood) +{ + //int v6; // ecx + int pre; // esi + //int v9; // ecx + unsigned char goe; // bl + int v11; // edx + int v14; // ecx + int l[256]; // [esp+4h] [ebp-494h] + char istr[128]; // [esp+404h] [ebp-94h] + int post; // [esp+488h] [ebp-10h] + int sufidx; // [esp+48Ch] [ebp-Ch] + int preidx; // [esp+490h] [ebp-8h] + + pre = random(23, 4); + post = random(23, 3); + if ( pre && !post ) + { + if ( random(23, 2) ) + post = 1; + else + pre = 0; + } + preidx = -1; + sufidx = -1; + goe = 0; + if ( !onlygood ) + { + if ( random(0, 3) ) + onlygood = 1; + } + if ( !pre ) + { + v11 = 0; + if ( PL_Prefix[0].PLPower != -1 ) + { + v14 = 0; + do + { + if ( flgs & PL_Prefix[v14].PLIType ) + { + if ( PL_Prefix[v14].PLMinLvl >= minlvl && PL_Prefix[v14].PLMinLvl <= maxlvl && (!onlygood || PL_Prefix[v14].PLOk) && (flgs != 256 || PL_Prefix[v14].PLPower != 15) ) + { + l[v11++] = v14; + if ( PL_Prefix[v14].PLDouble ) + l[v11++] = v14; + } + } + v14++; + } + while ( PL_Prefix[v14].PLPower != -1 ); + if ( v11 ) + { + preidx = l[random(23, v11)]; + 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); + goe = PL_Prefix[preidx].PLGOE; + item[i]._iPrePower = PL_Prefix[preidx].PLPower; + } + } + } + if ( post ) + { + v11 = 0; + if ( PL_Suffix[0].PLPower != -1 ) + { + v14 = 0; + do + { + if ( flgs & PL_Suffix[v14].PLIType ) + { + if ( PL_Suffix[v14].PLMinLvl >= minlvl && PL_Suffix[v14].PLMinLvl <= maxlvl && (goe | PL_Suffix[v14].PLGOE) != 0x11 && (!onlygood || PL_Suffix[v14].PLOk) ) + l[v11++] = v14; + } + v14++; + } + while ( PL_Suffix[v14].PLPower != -1 ); + if ( v11 ) + { + sufidx = l[random(23, v11)]; + 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) ) + { + strcpy(item[i]._iIName, AllItemsList[item[i].IDidx].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); +} +// 4215EF: using guessed type int var_494[256]; + +//----- (0042191C) -------------------------------------------------------- +void __fastcall GetItemBonus(int i, int idata, int minlvl, int maxlvl, int onlygood) +{ + if ( item[i]._iClass != ICLASS_GOLD ) + { + 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; + default: + return; + } + } +} + +//----- (004219C1) -------------------------------------------------------- +void __fastcall SetupItem(int i) +{ + int it; // eax + int il; // eax + + it = ItemCAnimTbl[item[i]._iCurs]; + item[i]._iAnimWidth = 96; + item[i]._iAnimXOff = 16; + il = ItemAnimLs[it]; + item[i].ItemFrame = Item2Frm[it]; + item[i]._iAnimLen = il; + item[i]._iIdentified = 0; + item[i]._iPostDraw = 0; + + if ( !plr[myplr].pLvlLoad ) + { + item[i]._iSelFlag = 0; + il = 1; + item[i]._iAnimFlag = 1; + } + else + { + item[i]._iAnimFlag = 0; + item[i]._iSelFlag = 1; + } + + item[i]._iAnimFrame = il; +} + +//----- (00421A4B) -------------------------------------------------------- +int __fastcall RndItem(int m) +{ + int ri; // esi + int i; // edx + int ril[512]; // [esp+4h] [ebp-800h] + + if ( monster[m].MData->mTreasure & 0x8000 ) + return -1 - (monster[m].MData->mTreasure & 0xFFF); + if ( monster[m].MData->mTreasure & 0x4000 ) + return 0; + + if ( random(24, 100) > 40 ) + return 0; + if ( random(24, 100) > 25 ) + return 1; + + ri = 0; + i = 0; + if ( AllItemsList[0].iLoc != -1 ) + { + do + { + if ( AllItemsList[i].iRnd == 2 && monster[m].mLevel >= AllItemsList[i].iMinMLvl ) + ril[ri++] = i; + if ( AllItemsList[i].iRnd && 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; + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + + return ril[random(24, ri)] + 1; +} +// 679660: using guessed type char gbMaxPlayers; +// 421A4B: using guessed type int var_800[512]; + +//----- (00421B32) -------------------------------------------------------- +int __fastcall RndUItem(int m) +{ + int ri; // edx + int i; // ebp + bool okflag; // edi + int ril[512]; // [esp+0h] [ebp-800h] + + if ( m != -1 ) + { + if ( monster[m].MData->mTreasure < 0 && gbMaxPlayers == 1 ) + return -1 - (monster[m].MData->mTreasure & 0xFFF); + } + ri = 0; + i = 0; + if ( AllItemsList[0].iLoc != -1 ) + { + do + { + okflag = 1; + if ( !AllItemsList[i].iRnd ) + okflag = 0; + if ( m == -1 ) + { + if ( 2 * currlevel - AllItemsList[i].iMinMLvl < 0 ) + okflag = 0; + } + else + { + if ( monster[m].mLevel - AllItemsList[i].iMinMLvl < 0 ) + okflag = 0; + } + if ( !AllItemsList[i].itype ) + okflag = 0; + if ( AllItemsList[i].itype == ITYPE_GOLD ) + okflag = 0; + if ( AllItemsList[i].itype == ITYPE_0E ) + okflag = 0; + if ( AllItemsList[i].iMiscId == IMISC_BOOK ) + okflag = 1; + if ( AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1 ) + okflag = 0; + if ( AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1 ) + okflag = 0; + if ( okflag ) + ril[ri++] = i; + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + + return ril[random(25, ri)]; +} +// 679660: using guessed type char gbMaxPlayers; +// 421B32: using guessed type int var_800[512]; + +//----- (00421C2A) -------------------------------------------------------- +int __cdecl RndAllItems() +{ + int ri; // esi + int i; // edi + int ril[512]; // [esp+0h] [ebp-800h] + + if ( random(26, 100) > 25 ) + return 0; + + ri = 0; + i = 0; + if ( AllItemsList[0].iLoc != -1 ) + { + do + { + if ( AllItemsList[i].iRnd && 2 * currlevel >= AllItemsList[i].iMinMLvl ) + ril[ri++] = i; + if ( AllItemsList[i].iSpell == SPL_RESURRECT && gbMaxPlayers == 1 ) + --ri; + if ( AllItemsList[i].iSpell == SPL_HEALOTHER && gbMaxPlayers == 1 ) + --ri; + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + return ril[random(26, ri)]; +} +// 679660: using guessed type char gbMaxPlayers; +// 421C2A: using guessed type int var_800[512]; + +//----- (00421CB7) -------------------------------------------------------- +int __fastcall RndTypeItems(int itype, int imid) +{ + int i; // edi + bool okflag; // esi + int ril[512]; // [esp+4h] [ebp-80Ch] + int ri; // [esp+80Ch] [ebp-4h] + + ri = 0; + i = 0; + + if ( AllItemsList[0].iLoc != -1 ) + { + do + { + okflag = 1; + if ( !AllItemsList[i].iRnd ) + okflag = 0; + if ( 2 * currlevel < AllItemsList[i].iMinMLvl ) + okflag = 0; + if ( AllItemsList[i].itype != itype ) + okflag = 0; + if ( imid != -1 && AllItemsList[i].iMiscId != imid ) + okflag = 0; + if ( okflag ) + ril[ri++] = i; + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + + return ril[random(27, ri)]; +} +// 421CB7: using guessed type int var_80C[512]; + +//----- (00421D41) -------------------------------------------------------- +int __fastcall CheckUnique(int i, int lvl, int uper, bool recreate) +{ + int numu; // ebx + int j; // esi + int idata; // eax + char uok[128]; // [esp+8h] [ebp-84h] + + if ( random(28, 100) > uper ) + return -1; + numu = 0; + memset(uok, 0, 0x80u); + + if ( UniqueItemList[0].UIItemId == -1 ) + return -1; + j = 0; + do + { + if ( UniqueItemList[j].UIItemId == AllItemsList[item[i].IDidx].iItemId + && lvl >= UniqueItemList[j].UIMinLvl + && (recreate || !UniqueItemFlag[j] || gbMaxPlayers != 1) ) + { + uok[j] = 1; + ++numu; + } + j++; + } + while ( UniqueItemList[j].UIItemId != -1 ); + if ( !numu ) + return -1; + + random(29, 10); + idata = 0; + if ( numu > 0 ) + { + while ( 1 ) + { + if ( uok[idata] ) + --numu; + if ( numu <= 0 ) + break; + if ( ++idata == 128 ) + idata = 0; + } + } + return idata; +} +// 679660: using guessed type char gbMaxPlayers; +// 421D41: using guessed type char var_84[128]; + +//----- (00421E11) -------------------------------------------------------- +void __fastcall 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]._iCreateInfo |= 0x0200; + item[i]._iUid = uid; + item[i]._iMagical = 2; +} + +//----- (00421F5C) -------------------------------------------------------- +void __fastcall SpawnUnique(int uid, int x, int y) +{ + int ii; // esi + int itype; // edx + + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + itype = 0; + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + + if ( AllItemsList[0].iItemId != UniqueItemList[uid].UIItemId ) + { + while ( AllItemsList[itype].iItemId != UniqueItemList[uid].UIItemId ) + { + itype++; + } + } + + GetItemAttrs(ii, itype, currlevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + ++numitems; + } +} +// 421F5C: could not find valid save-restore pair for esi + +//----- (00421FE6) -------------------------------------------------------- +void __fastcall ItemRndDur(int ii) +{ + if ( item[ii]._iDurability && item[ii]._iDurability != 255 ) + item[ii]._iDurability = random(0, item[ii]._iMaxDur >> 1) + (item[ii]._iMaxDur >> 2) + 1; +} + +//----- (00422024) -------------------------------------------------------- +void __fastcall SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, int onlygood, int recreate, int pregen) +{ + int iblvl; // edi + int uid; // eax + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + GetItemAttrs(ii, idx, lvl >> 1); + item[ii]._iCreateInfo = lvl; + + if ( pregen ) + item[ii]._iCreateInfo = lvl | 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 ) + { + if ( item[ii]._iLoc != ILOC_UNEQUIPABLE ) + GetUniqueItem(ii, iseed); + } + else + { + iblvl = -1; + if ( random(32, 100) > 10 && random(33, 100) > lvl || (iblvl = lvl, lvl == -1) ) + { + + if ( item[ii]._iMiscId != IMISC_STAFF || (iblvl = lvl, lvl == -1) ) + { + if ( item[ii]._iMiscId != IMISC_RING || (iblvl = lvl, lvl == -1) ) + { + if ( item[ii]._iMiscId == IMISC_AMULET ) + iblvl = lvl; + } + } + } + if ( onlygood ) + iblvl = lvl; + 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); + } + SetupItem(ii); +} + +//----- (0042217A) -------------------------------------------------------- +void __fastcall SpawnItem(int m, int x, int y, unsigned char sendmsg) +{ + int ii; // edi + int onlygood; // [esp+Ch] [ebp-Ch] + int idx; // [esp+14h] [ebp-4h] + + if ( !monster[m]._uniqtype && (monster[m].MData->mTreasure >= 0 || gbMaxPlayers == 1) ) + { + if ( quests[1]._qactive == 2 && quests[1]._qvar1 == 5 ) + { + idx = 18; // Brain + quests[1]._qvar1 = 6; + goto LABEL_13; + } + idx = RndItem(m); + if ( !idx ) + return; + if ( idx > 0 ) + { + onlygood = 0; + idx--; + goto LABEL_13; + } +LABEL_10: + SpawnUnique(-1 - idx, x, y); + return; + } + idx = RndUItem(m); + if ( idx < 0 ) + goto LABEL_10; + onlygood = 1; +LABEL_13: + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + + if ( !monster[m]._uniqtype ) + SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 1, onlygood, 0, 0); + else + SetupAllItems(ii, idx, GetRndSeed(), monster[m].MData->mLevel, 15, onlygood, 0, 0); + + ++numitems; + if ( sendmsg ) + NetSendCmdDItem(0, ii); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00422290) -------------------------------------------------------- +void __fastcall CreateItem(int uid, int x, int y) +{ + int ii; // esi + int idx; // edx + + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + idx = 0; + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + + if ( AllItemsList[0].iItemId != UniqueItemList[uid].UIItemId ) + { + while ( AllItemsList[idx].iItemId != UniqueItemList[uid].UIItemId ) + { + idx++; + } + } + + GetItemAttrs(ii, idx, currlevel); + GetUniqueItem(ii, uid); + SetupItem(ii); + ++numitems; + item[ii]._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 idx; // edi + int ii; // esi + + if ( onlygood ) + idx = RndUItem(-1); + else + idx = RndAllItems(); + + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + SetupAllItems(ii, idx, GetRndSeed(), 2 * currlevel, 1, onlygood, 0, delta); + + if ( sendmsg ) + NetSendCmdDItem(0, ii); + if ( delta ) + DeltaAddItem(ii); + + ++numitems; + } +} + +//----- (004223D0) -------------------------------------------------------- +void __fastcall SetupAllUseful(int ii, int iseed, int lvl) +{ + int idx; // esi + + item[ii]._iSeed = iseed; + SetRndSeed(iseed); + idx = 25 - (random(34, 2) != 0); + + if ( lvl > 1 ) + { + if ( !random(34, 3) ) + idx = 27; // unique? + } + + GetItemAttrs(ii, idx, lvl); + item[ii]._iCreateInfo = lvl + 0x180; + SetupItem(ii); +} + +//----- (0042243D) -------------------------------------------------------- +void __fastcall CreateRndUseful(int pnum, int x, int y, unsigned char sendmsg) +{ + int ii; // esi + + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + SetupAllUseful(ii, GetRndSeed(), currlevel); + + if ( sendmsg ) + NetSendCmdDItem(0, ii); + + ++numitems; + } +} + +//----- (004224A6) -------------------------------------------------------- +void __fastcall CreateTypeItem(int x, int y, unsigned char onlygood, int itype, int imisc, int sendmsg, int delta) +{ + int idx; // edi + int ii; // esi + + if ( itype == ITYPE_GOLD ) + idx = 0; + else + idx = RndTypeItems(itype, imisc); + + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + SetupAllItems(ii, idx, GetRndSeed(), 2 * currlevel, 1, onlygood, 0, delta); + + if ( sendmsg ) + NetSendCmdDItem(0, ii); + if ( delta ) + DeltaAddItem(ii); + + ++numitems; + } +} + +//----- (0042254A) -------------------------------------------------------- +void __fastcall RecreateItem(int ii, int idx, unsigned short ic, int iseed, int ivalue) +{ + int uper; // esi + int onlygood; // edx + int recreate; // ebx + int pregen; // edi + + if ( idx ) + { + if ( ic ) + { + if ( ic & 0x7C00 ) + { + RecreateTownItem(ii, idx, ic, iseed, ivalue); + } + else if ( (ic & 0x0180) == 0x0180 ) + { + SetupAllUseful(ii, iseed, ic & 0x3F); + } + else + { + uper = 0; + onlygood = 0; + recreate = 0; + pregen = 0; + if ( ic & 0x0100 ) + uper = 1; + if ( ic & 0x80 ) + uper = 15; + if ( ic & 0x40 ) + onlygood = 1; + if ( ic & 0x0200 ) + recreate = 1; + if ( ic & 0x8000 ) + pregen = 1; + SetupAllItems(ii, idx, iseed, ic & 0x3F, uper, onlygood, recreate, pregen); + } + } + else + { + SetPlrHandItem(&item[ii], idx); + SetPlrHandSeed(&item[ii], iseed); + } + } + else + { + SetPlrHandItem(&item[ii], IDI_GOLD); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = ic; + item[ii]._ivalue = ivalue; + if ( ivalue < 2500 ) + { + if ( ivalue > 1000 ) + item[ii]._iCurs = 5; + else + item[ii]._iCurs = 4; + } + else + { + item[ii]._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) +{ + 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]._iCreateInfo = ic; + item[ii]._ivalue = ivalue & 0x3F; + item[ii]._iSeed = iseed; +} + +//----- (00422795) -------------------------------------------------------- +void __fastcall SpawnQuestItem(int itemid, int x, int y, int randarea, int selflag) +{ + int i; // ebx + BOOL failed; // eax + int j; // esi + int v12; // ebx + int v13; // esi + int tries; // [esp+10h] [ebp-4h] + + if ( randarea ) + { + tries = 0; + while ( 1 ) + { +LABEL_3: + if ( ++tries > 1000 && randarea > 1 ) + --randarea; + + x = random(0, 112); + y = random(0, 112); + i = 0; + failed = 0; + if ( randarea <= 0 ) + break; + while ( !failed ) + { + for(j = 0; j < randarea; j++) + { + if ( failed ) + break; + + failed = ItemSpaceOk(i + x, j + y) == 0; + } + + if ( ++i >= randarea ) + { + if ( failed ) + goto LABEL_3; + goto LABEL_13; + } + } + } + } +LABEL_13: + if ( numitems < 127 ) + { + v12 = itemavail[0]; + v13 = itemavail[0]; + item[v13]._ix = x; + itemactive[numitems] = v12; + item[v13]._iy = y; + itemavail[0] = itemavail[-numitems + 126]; /* double check */ + dItem[x][y] = v12 + 1; + GetItemAttrs(v12, itemid, currlevel); + SetupItem(v12); + item[v13]._iPostDraw = 1; + if ( selflag ) + { + item[v13]._iAnimFlag = 0; + item[v13]._iSelFlag = selflag; + item[v13]._iAnimFrame = item[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 = 0; //v11; /* chceck */ + 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; + item[v6]._ix = v8; + v9 = object[v5]._oy; + itemavail[0] = *v7; + dItem[v8][v9] = v4 + 1; + v10 = currlevel; + item[v6]._iy = v9; + GetItemAttrs(v4, IDI_ROCK, v10); + SetupItem(v4); + ++numitems; + item[v6]._iSelFlag = 2; + item[v6]._iPostDraw = 1; + item[v6]._iAnimFrame = 11; + } +} + +//----- (00422989) -------------------------------------------------------- +void __fastcall RespawnItem(int i, bool FlipFlag) +{ + int it; // ecx + int il; // eax + + item[i]._iAnimWidth = 96; + item[i]._iAnimXOff = 16; + it = ItemCAnimTbl[item[i]._iCurs]; + il = ItemAnimLs[it]; + item[i]._iAnimLen = il; + item[i].ItemFrame = Item2Frm[it]; + item[i]._iPostDraw = 0; + item[i]._iRequest = 0; + + if ( FlipFlag ) + { + item[i]._iSelFlag = 0; + il = 1; + item[i]._iAnimFlag = 1; + } + else + { + item[i]._iAnimFlag = 0; + item[i]._iSelFlag = 1; + } + + item[i]._iAnimFrame = il; + + 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; +} + +//----- (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 idoppelx; // esi + ItemStruct *i; // edx + + if ( gbMaxPlayers != 1 ) + { + for(idoppelx = 16; idoppelx < 96; idoppelx++) + { + if ( dItem[idoppelx][idoppely] ) + { + i = &item[dItem[idoppelx][idoppely]-1]; + if ( i->_ix != idoppelx || i->_iy != idoppely ) + dItem[idoppelx][idoppely] = 0; + } + } + + if ( idoppely++ == 95 ) + idoppely = 16; + } +} +// 492EAC: using guessed type int idoppely; +// 679660: using guessed type char gbMaxPlayers; + +//----- (00422ADE) -------------------------------------------------------- +void __cdecl ProcessItems() +{ + int i; // edi + int ii; // esi + + 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 ) + PlaySfxLoc(ItemDropSnds[ItemCAnimTbl[item[ii]._iCurs]], item[ii]._ix, item[ii]._iy); + + if ( item[ii]._iAnimFrame >= item[ii]._iAnimLen ) + { + item[ii]._iAnimFlag = 0; + item[ii]._iAnimFrame = item[ii]._iAnimLen; + item[ii]._iSelFlag = 1; + } + } + } + } + ItemDoppel(); +} + +//----- (00422BB2) -------------------------------------------------------- +void __cdecl FreeItemGFX() +{ + int i; // esi + void *v1; // ecx + + for(i = 0; i < 35; i++) + { + v1 = (void *)Item2Frm[i]; + Item2Frm[i] = 0; + mem_free_dbg(v1); + } +} + +//----- (00422BCF) -------------------------------------------------------- +void __fastcall GetItemFrm(int i) +{ + item[i].ItemFrame = Item2Frm[ItemCAnimTbl[item[i]._iCurs]]; +} + +//----- (00422BF0) -------------------------------------------------------- +void __fastcall GetItemStr(int i) +{ + int nGold; // esi + + if ( item[i]._itype == ITYPE_GOLD ) + { + nGold = item[i]._ivalue; + sprintf(infostr, "%i gold %s", nGold, get_pieces_str(nGold)); + } + else + { + if ( !item[i]._iIdentified ) + strcpy(infostr, item[i]._iName); + else + strcpy(infostr, item[i]._iIName); + + if ( item[i]._iMagical == 1 ) + infoclr = COL_BLUE; + if ( item[i]._iMagical == 2 ) + infoclr = COL_GOLD; + } +} +// 4B883C: using guessed type int infoclr; + +//----- (00422C63) -------------------------------------------------------- +void __fastcall CheckIdentify(int pnum, int cii) +{ + ItemStruct *pi; // esi + + pi = &plr[pnum].InvBody[cii]; + pi->_iIdentified = 1; + + CalcPlrInv(pnum, 1); + + if ( pnum == myplr ) + SetCursor(CURSOR_HAND); +} + +//----- (00422C9C) -------------------------------------------------------- +void __fastcall DoRepair(int pnum, int cii) +{ + PlayerStruct *p; // eax + ItemStruct *pi; // esi + + p = &plr[pnum]; + pi = &p->InvBody[cii]; + + PlaySfxLoc(IS_REPAIR, p->WorldX, p->WorldY); + RepairItem(pi, p->_pLevel); + CalcPlrInv(pnum, 1); + + if ( pnum == myplr ) + SetCursor(CURSOR_HAND); +} + +//----- (00422CF6) -------------------------------------------------------- +void __fastcall RepairItem(ItemStruct *i, int lvl) +{ + int rep; // edi + int d; // eax + + if ( i->_iDurability != i->_iMaxDur ) + { + if ( i->_iMaxDur > 0 ) + { + rep = 0; + while ( 1 ) + { + rep += lvl + random(37, lvl); + d = i->_iMaxDur / (lvl + 9); + + if ( d < 1 ) + d = 1; + if ( i->_iMaxDur == d ) + break; + + i->_iMaxDur -= d; + + if ( rep + i->_iDurability >= i->_iMaxDur ) + { + i->_iDurability += rep; + if ( i->_iDurability > i->_iMaxDur ) + i->_iDurability = i->_iMaxDur; + return; + } + } + } + i->_itype = -1; + } +} + +//----- (00422D6C) -------------------------------------------------------- +void __fastcall DoRecharge(int pnum, int cii) +{ + PlayerStruct *p; // eax + ItemStruct *pi; // esi + + p = &plr[pnum]; + pi = &p->InvBody[cii]; + + if ( pi->_itype == ITYPE_STAFF && pi->_iSpell ) + { + RechargeItem(pi, random(38, p->_pLevel / spelldata[pi->_iSpell].sBookLvl) + 1); + CalcPlrInv(pnum, 1); + } + + if ( pnum == myplr ) + SetCursor(CURSOR_HAND); +} + +//----- (00422DDD) -------------------------------------------------------- +void __fastcall RechargeItem(ItemStruct *i, int r) +{ + if ( i->_iCharges != i->_iMaxCharges ) + { + while ( 1 ) + { + if ( i->_iMaxCharges-- == 1 ) + break; + + i->_iCharges += r; + + if ( i->_iCharges >= i->_iMaxCharges ) + { + if ( i->_iCharges > i->_iMaxCharges ) + i->_iCharges = i->_iMaxCharges; + return; + } + } + } +} + +//----- (00422E14) -------------------------------------------------------- +void __fastcall PrintItemOil(char IDidx) +{ + switch ( IDidx ) + { + case IMISC_FULLHEAL: + strcpy(tempstr, "fully recover life"); + break; + case IMISC_HEAL: + strcpy(tempstr, "recover partial life"); + break; + case IMISC_OLDHEAL: + strcpy(tempstr, "recover life"); + break; + case IMISC_DEADHEAL: + strcpy(tempstr, "deadly heal"); + break; + case IMISC_MANA: + strcpy(tempstr, "recover mana"); + break; + case IMISC_FULLMANA: + strcpy(tempstr, "fully recover mana"); + break; + case IMISC_ELIXSTR: + strcpy(tempstr, "increase strength"); + break; + case IMISC_ELIXMAG: + strcpy(tempstr, "increase magic"); + break; + case IMISC_ELIXDEX: + strcpy(tempstr, "increase dexterity"); + break; + case IMISC_ELIXVIT: + strcpy(tempstr, "increase vitality"); + break; + case IMISC_ELIXWEAK: + case IMISC_ELIXDIS: + strcpy(tempstr, "decrease strength"); + break; + case IMISC_ELIXCLUM: + strcpy(tempstr, "decrease dexterity"); + break; + case IMISC_ELIXSICK: + strcpy(tempstr, "decrease vitality"); + break; + case IMISC_REJUV: + strcpy(tempstr, "recover life and mana"); + break; + case IMISC_FULLREJUV: + strcpy(tempstr, "fully recover life and mana"); + break; + default: + return; + } + + AddPanelString(tempstr, 1); +} + +//----- (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 DrawUBack() +{ + 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 + + CelDecodeOnly(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, v13, col); + } + v6 += fontkern[v14] + 1; + v12 = a3++ + 1; + if ( a3 >= v15 ) + break; + v5 = str; + } + } +} + +//----- (0042365B) -------------------------------------------------------- +void __fastcall DrawULine(int y) +{ + char *v1; // esi + char *v2; // edi + signed int v3; // edx + + 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, 0x10A); /* find real fix */ + v1 += 264; + v2 += 264; + *v2 = *v1; + v1 += 504; + v2 += 504; + --v3; + } + while ( v3 ); +} + +//----- (004236A6) -------------------------------------------------------- +void __cdecl DrawUniqueInfo() +{ + int v0; // esi + int v1; // esi + int v2; // edi + + if ( !chrflag && !questlog ) + { + v0 = curruitem._iUid; + DrawUBack(); + v1 = v0; + PrintUString(0, 2, 1, UniqueItemList[v1].UIName, 3); + DrawULine(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) +{ + 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); + } +} + +//----- (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 ( !(plr[v10]._pIFlags & 0x8000000) ) + { + 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 == SPL_NOVA ) + NetSendCmdLoc(1u, CMD_NOVA, v37, v39); + return; + } + } + v35 = p; + v36 = p == myplr; + plr[v35]._pTSpell = v32; + _LOBYTE(plr[v35]._pTSplType) = 4; + if ( v36 ) + SetCursor(CURSOR_TELEPORT); + 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) +{ + bool sf; // al + + sf = 1; + if ( plr[myplr]._pStrength < h->_iMinStr + || plr[myplr]._pMagic < h->_iMinMag + || plr[myplr]._pDexterity < h->_iMinDex ) + sf = 0; + return sf; +} + +//----- (0042421C) -------------------------------------------------------- +bool __fastcall SmithItemOk(int i) +{ + unsigned char v1; // cl + bool rv; // eax + + v1 = AllItemsList[i].itype; + rv = 1; + if ( !v1 || v1 == ITYPE_GOLD || v1 == ITYPE_0E || v1 == ITYPE_STAFF || v1 == ITYPE_RING || v1 == ITYPE_AMULET ) + rv = 0; + return rv; +} + +//----- (00424252) -------------------------------------------------------- +int __fastcall RndSmithItem(int lvl) +{ + int ri; // edx + int i; // edi + int ril[512]; // [esp+4h] [ebp-804h] + + ri = 0; + i = 1; + if ( AllItemsList[1].iLoc != -1 ) + { + do + { + if ( AllItemsList[i].iRnd && SmithItemOk(i) && lvl >= AllItemsList[i].iMinMLvl ) + { + ril[ri++] = i; + if ( AllItemsList[i].iRnd == 2 ) + ril[ri++] = i; + } + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + return ril[random(50, ri)] + 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 v3; // ebp + ItemStruct *v4; // ebx + int v9; // [esp+Ch] [ebp-8h] + + v3 = random(50, 10) + 10; + if ( v3 > 0 ) + { + v4 = smithitem; + v9 = v3; + while ( 1 ) + { + do + { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + GetItemAttrs(0, RndSmithItem(lvl) - 1, lvl); + } + while ( item[0]._iIvalue > 140000 ); + qmemcpy(v4, item, sizeof(ItemStruct)); + v4->_iCreateInfo = lvl | 0x400; + v4->_iIdentified = 1; + v4->_iStatFlag = StoreStatOk(v4); + ++v4; + if ( !--v9 ) + break; + } + } + if ( v3 < 20 ) + { + do + { + smithitem[v3]._itype = -1; + v3++; + } + while ( v3 < 20 ); + } + SortSmith(); +} + +//----- (00424420) -------------------------------------------------------- +bool __fastcall PremiumItemOk(int i) +{ + unsigned char v1; // cl + bool rv; // eax + + v1 = AllItemsList[i].itype; + rv = 1; + if ( !v1 || v1 == ITYPE_GOLD || v1 == ITYPE_0E || v1 == ITYPE_STAFF ) + rv = 0; + if ( gbMaxPlayers != 1 && ( v1 == ITYPE_RING || v1 == ITYPE_AMULET ) ) + { + rv = 0; + } + return rv; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0042445F) -------------------------------------------------------- +int __fastcall RndPremiumItem(int minlvl, int maxlvl) +{ + int ri; // edx + int i; // edi + int ril[512]; // [esp+8h] [ebp-804h] + + ri = 0; + i = 1; + if ( AllItemsList[1].iLoc != -1 ) + { + do + { + if ( AllItemsList[i].iRnd ) + { + if ( PremiumItemOk(i) ) + { + if ( AllItemsList[i].iMinMLvl >= minlvl && AllItemsList[i].iMinMLvl <= maxlvl ) + ril[ri++] = i; + } + } + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + return ril[random(50, ri)] + 1; +} +// 42445F: using guessed type int ril[512]; + +//----- (004244C6) -------------------------------------------------------- +void __fastcall SpawnOnePremium(int i, int plvl) +{ + int itype; // esi + ItemStruct holditem; // [esp+Ch] [ebp-178h] + + qmemcpy(&holditem, item, sizeof(ItemStruct)); + if ( plvl > 30 ) + 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 > 140000 ); + qmemcpy(&premiumitem[i], item, sizeof(ItemStruct)); + premiumitem[i]._iCreateInfo = plvl | 0x800; + premiumitem[i]._iIdentified = 1; + premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + qmemcpy(item, &holditem, sizeof(ItemStruct)); +} + +//----- (004245A0) -------------------------------------------------------- +void __fastcall SpawnPremium(int lvl) +{ + int i; // eax + + if ( numpremium < 6 ) + { + for(i = 0; i < 6; i++) + { + if ( premiumitem[i]._itype == -1 ) + SpawnOnePremium(i, premiumlevel + premiumlvladd[i]); + } + numpremium = 6; + } + for ( i = premiumlevel; premiumlevel < lvl; i = premiumlevel ) + { + qmemcpy(premiumitem, &premiumitem[2], sizeof(ItemStruct)); + 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) -------------------------------------------------------- +bool __fastcall WitchItemOk(int i) +{ + bool rv; // eax + unsigned char v3; // dl + int v4; // edx + int v5; // ecx + + rv = 0; + v3 = AllItemsList[i].itype; + if ( !v3 ) + rv = 1; + if ( v3 == ITYPE_STAFF ) + rv = 1; + v4 = AllItemsList[i].iMiscId; + if ( v4 == IMISC_MANA ) + rv = 0; + if ( v4 == IMISC_FULLMANA ) + rv = 0; + if ( v4 == IMISC_FULLHEAL ) + rv = 0; + if ( v4 == IMISC_HEAL ) + rv = 0; + v5 = AllItemsList[i].iSpell; + if ( v5 == SPL_TOWN ) + rv = 0; + if ( v5 == SPL_RESURRECT && gbMaxPlayers == 1 ) + rv = 0; + if ( v5 == SPL_HEALOTHER && gbMaxPlayers == 1 ) + rv = 0; + return rv; +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (004246D2) -------------------------------------------------------- +int __fastcall RndWitchItem(int lvl) +{ + int ri; // ebx + int i; // edi + int ril[512]; // [esp+8h] [ebp-804h] + + ri = 0; + i = 1; + if ( AllItemsList[1].iLoc != -1 ) + { + do + { + if ( AllItemsList[i].iRnd && WitchItemOk(i) && lvl >= AllItemsList[i].iMinMLvl ) + ril[ri++] = i; + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + return ril[random(51, ri)] + 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 slvl; // edi + + if ( witchitem[ii]._iMiscId == IMISC_BOOK ) + { + witchitem[ii]._iMinMag = spelldata[witchitem[ii]._iSpell].sMinInt; + slvl = plr[myplr]._pSplLvl[witchitem[ii]._iSpell]; + if ( slvl ) + { + do + { + witchitem[ii]._iMinMag += 20 * witchitem[ii]._iMinMag / 100; + --slvl; + if ( witchitem[ii]._iMinMag > 255 ) + { + witchitem[ii]._iMinMag = -1; + slvl = 0; + } + } + while ( slvl ); + } + } +} + +//----- (00424815) -------------------------------------------------------- +void __fastcall SpawnWitch(int lvl) +{ + int v2; // ebp + int itype; // esi + int iblvl; // eax + signed int ii; // [esp+10h] [ebp-8h] + ItemStruct *itm; // [esp+14h] [ebp-4h] + + GetItemAttrs(0, IDI_MANA, 1); + qmemcpy(witchitem, item, sizeof(ItemStruct)); + witchitem[0]._iCreateInfo = lvl; + witchitem[0]._iStatFlag = 1; + GetItemAttrs(0, IDI_FULLMANA, 1); + qmemcpy(&witchitem[1], item, sizeof(ItemStruct)); + witchitem[1]._iCreateInfo = lvl; + witchitem[1]._iStatFlag = 1; + GetItemAttrs(0, IDI_PORTAL, 1); + qmemcpy(&witchitem[2], item, sizeof(ItemStruct)); + witchitem[2]._iCreateInfo = lvl; + witchitem[2]._iStatFlag = 1; + v2 = random(51, 8) + 10; + ii = 3; + if ( v2 > 3 ) + { + itm = &witchitem[3]; + while ( 1 ) + { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + itype = RndWitchItem(lvl) - 1; + GetItemAttrs(0, itype, lvl); + if ( random(51, 100) > 5 || (iblvl = 2 * lvl, iblvl == -1) ) + { + if ( item[0]._iMiscId != IMISC_STAFF ) + continue; + iblvl = 2 * lvl; + if ( iblvl == -1 ) + continue; + } + GetItemBonus(0, itype, iblvl >> 1, iblvl, 1); + if ( item[0]._iIvalue <= 140000 ) + { + qmemcpy(itm, item, sizeof(ItemStruct)); + itm->_iIdentified = 1; + itm->_iCreateInfo = lvl | 0x2000; + WitchBookLevel(ii); + ++ii; + itm->_iStatFlag = StoreStatOk(itm); + ++itm; + if ( ii >= v2 ) + break; + } + } + } + if ( v2 < 20 ) + { + do + { + witchitem[v2]._itype = -1; + v2++; + } + while ( v2 < 20 ); + } + SortWitch(); +} + +//----- (004249A4) -------------------------------------------------------- +int __fastcall RndBoyItem(int lvl) +{ + int ri; // edx + int i; // edi + int ril[512]; // [esp+8h] [ebp-800h] + + ri = 0; + i = 1; + if ( AllItemsList[1].iLoc != -1 ) + { + do + { + if ( AllItemsList[i].iRnd && PremiumItemOk(i) && lvl >= AllItemsList[i].iMinMLvl ) + ril[ri++] = i; + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + return ril[random(49, ri)] + 1; +} +// 4249A4: using guessed type int var_800[512]; + +//----- (00424A03) -------------------------------------------------------- +void __fastcall SpawnBoy(int lvl) +{ + int itype; // esi + + if ( boylevel < lvl >> 1 || boyitem._itype == -1 ) + { + 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 > 90000 ); + qmemcpy(&boyitem, item, sizeof(boyitem)); + boyitem._iCreateInfo = lvl | 0x10; + boyitem._iIdentified = 1; + boyitem._iStatFlag = StoreStatOk(&boyitem); + boylevel = lvl >> 1; + } +} +// 6A8A3C: using guessed type int boylevel; + +//----- (00424A9B) -------------------------------------------------------- +bool __fastcall HealerItemOk(int i) +{ + int v1; // ecx + bool 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 ri; // ebx + int i; // edi + int ril[512]; // [esp+8h] [ebp-804h] + + ri = 0; + i = 1; + if ( AllItemsList[1].iLoc != -1 ) + { + do + { + if ( AllItemsList[i].iRnd && HealerItemOk(i) && lvl >= AllItemsList[i].iMinMLvl ) + ril[ri++] = i; + ++i; + } + while ( AllItemsList[i].iLoc != -1 ); + } + return ril[random(50, ri)] + 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 v3; // eax + ItemStruct *v4; // ebp + signed int v8; // [esp-4h] [ebp-20h] + int v10; // [esp+14h] [ebp-8h] + + GetItemAttrs(0, IDI_HEAL, 1); + qmemcpy(healitem, item, sizeof(ItemStruct)); + healitem[0]._iCreateInfo = lvl; + healitem[0]._iStatFlag = 1; + GetItemAttrs(0, IDI_FULLHEAL, 1); + qmemcpy(&healitem[1], item, sizeof(ItemStruct)); + healitem[1]._iCreateInfo = lvl; + healitem[1]._iStatFlag = 1; + if ( gbMaxPlayers == 1 ) + { + v8 = 2; + } + else + { + GetItemAttrs(0, IDI_RESURRECT, 1); + qmemcpy(&healitem[2], item, sizeof(ItemStruct)); + healitem[2]._iCreateInfo = lvl; + healitem[2]._iStatFlag = 1; + v8 = 3; + } + v3 = random(50, 8) + 10; + if ( v8 < v3 ) + { + v4 = &healitem[v8]; + v10 = v3 - v8; + do + { + item[0]._iSeed = GetRndSeed(); + SetRndSeed(item[0]._iSeed); + GetItemAttrs(0, RndHealerItem(lvl) - 1, lvl); + qmemcpy(v4, item, sizeof(ItemStruct)); + v4->_iCreateInfo = lvl | 0x4000; + v4->_iIdentified = 1; + v4->_iStatFlag = StoreStatOk(v4); + ++v4; + --v10; + } + while ( v10 ); + } + if ( v3 < 20 ) + { + do + { + healitem[v3]._itype = -1; + v3++; + } + while ( v3 < 20 ); + } + SortHealer(); +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (00424D57) -------------------------------------------------------- +void __cdecl SpawnStoreGold() +{ + GetItemAttrs(0, IDI_GOLD, 1); + qmemcpy(&golditem, item, sizeof(golditem)); + golditem._iStatFlag = 1; +} + +//----- (00424D80) -------------------------------------------------------- +void __fastcall RecreateSmithItem(int ii, int idx, int plvl, int iseed) +{ + SetRndSeed(iseed); + GetItemAttrs(ii, RndSmithItem(plvl) - 1, plvl); + item[ii]._iSeed = iseed; + item[ii]._iCreateInfo = plvl | 0x400; + item[ii]._iIdentified = 1; +} + +//----- (00424DD1) -------------------------------------------------------- +void __fastcall RecreatePremiumItem(int ii, int idx, int lvl, int iseed) +{ + int itype; // edi + + SetRndSeed(iseed); + itype = RndPremiumItem(lvl >> 2, lvl) - 1; + GetItemAttrs(ii, itype, lvl); + GetItemBonus(ii, itype, lvl >> 1, lvl, 1); + item[ii]._iCreateInfo = lvl | 0x800; + item[ii]._iSeed = iseed; + item[ii]._iIdentified = 1; +} + +//----- (00424E3C) -------------------------------------------------------- +void __fastcall RecreateBoyItem(int ii, int idx, int lvl, int iseed) +{ + int itype; // edi + + SetRndSeed(iseed); + itype = RndBoyItem(lvl) - 1; + GetItemAttrs(ii, itype, lvl); + GetItemBonus(ii, itype, lvl, 2 * lvl, 1); + item[ii]._iCreateInfo = lvl | 0x1000; + item[ii]._iSeed = iseed; + item[ii]._iIdentified = 1; +} + +//----- (00424EA1) -------------------------------------------------------- +void __fastcall RecreateWitchItem(int ii, int idx, int lvl, int iseed) +{ + int itype; // edi + int iblvl; // eax + + 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 = 2 * lvl; + if ( iblvl != -1 && (random(51, 100) <= 5 || item[ii]._iMiscId == IMISC_STAFF) ) + { + GetItemBonus(ii, itype, iblvl >> 1, iblvl, 1); + } + } + item[ii]._iCreateInfo = lvl | 0x2000; + item[ii]._iSeed = iseed; + item[ii]._iIdentified = 1; +} + +//----- (00424F52) -------------------------------------------------------- +void __fastcall RecreateHealerItem(int ii, int idx, int lvl, int iseed) +{ + if ( idx != IDI_HEAL && idx != IDI_FULLHEAL && idx != IDI_RESURRECT ) + { + SetRndSeed(iseed); + idx = RndHealerItem(lvl) - 1; + } + GetItemAttrs(ii, idx, lvl); + item[ii]._iCreateInfo = lvl | 0x4000; + item[ii]._iSeed = iseed; + item[ii]._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() +{ + int i; + + for(i = 0; i < 20; i++) + { + if ( smithitem[i]._itype != -1 ) + smithitem[i]._iStatFlag = StoreStatOk(&smithitem[i]); + if ( witchitem[i]._itype != -1 ) + witchitem[i]._iStatFlag = StoreStatOk(&witchitem[i]); + if ( healitem[i]._itype != -1 ) + healitem[i]._iStatFlag = StoreStatOk(&healitem[i]); + } + + for(i = 0; i < 6; i++) + { + if ( premiumitem[i]._itype != -1 ) + premiumitem[i]._iStatFlag = StoreStatOk(&premiumitem[i]); + } + + boyitem._iStatFlag = StoreStatOk(&boyitem); +} +// 6A6BB8: using guessed type int stextscrl; +// 6AA700: using guessed type int stextdown; + +//----- (004250C0) -------------------------------------------------------- +int __cdecl ItemNoFlippy() +{ + int r; // ecx + + r = itemactive[numitems-1]; + item[r]._iAnimFlag = 0; + item[r]._iAnimFrame = item[r]._iAnimLen; + item[r]._iSelFlag = 1; + + return r; +} + +//----- (004250EF) -------------------------------------------------------- +void __fastcall CreateSpellBook(int x, int y, int ispell, bool sendmsg, int delta) +{ + int ii; // edi + int idx; // [esp+8h] [ebp-8h] + bool done; // [esp+Ch] [ebp-4h] + + done = 0; + idx = RndTypeItems(0, 24); + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + do + { + SetupAllItems(ii, idx, GetRndSeed(), 2 * currlevel, 1, 1, 0, delta); + if ( item[ii]._iMiscId == IMISC_BOOK && item[ii]._iSpell == ispell ) + done = 1; + } + while ( !done ); + if ( sendmsg ) + NetSendCmdDItem(0, ii); + if ( delta ) + DeltaAddItem(ii); + ++numitems; + } +} + +//----- (004251B8) -------------------------------------------------------- +void __fastcall CreateMagicItem(int x, int y, int imisc, int icurs, int sendmsg, int delta) +{ + int ii; // esi + int idx; // ebx + bool done; // [esp+Ch] [ebp-4h] + + done = 0; + idx = RndTypeItems(imisc, 0); + if ( numitems < 127 ) + { + ii = itemavail[0]; + GetSuperItemSpace(x, y, itemavail[0]); + itemactive[numitems] = ii; + itemavail[0] = itemavail[-numitems + 126]; + do + { + SetupAllItems(ii, idx, GetRndSeed(), 2 * currlevel, 1, 1, 0, delta); + if ( item[ii]._iCurs == icurs ) + done = 1; + } + while ( !done ); + if ( sendmsg ) + NetSendCmdDItem(0, ii); + if ( delta ) + DeltaAddItem(ii); + ++numitems; + } +} + +//----- (0042526E) -------------------------------------------------------- +bool __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] + unsigned 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 = &itemrecord[0].nIndex; + v9 = &itemrecord[0].wCI; + v10 = itemrecord; + v4 = &itemrecord[0].dwTimestamp; + while ( v7 - *v4 > 6000 ) + { + 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 i) +{ + int v1; // eax + + v1 = gnNumGetRecords-- - 1; + if ( gnNumGetRecords ) + { + itemrecord[i].nIndex = itemrecord[v1].nIndex; + itemrecord[i].nSeed = itemrecord[v1].nSeed; + itemrecord[i].wCI = itemrecord[v1].wCI; + itemrecord[i].dwTimestamp = itemrecord[v1].dwTimestamp; + } +} + +//----- (00425357) -------------------------------------------------------- +void __fastcall SetItemRecord(int dwSeed, int CI, int indx) +{ + int i; // ecx + + if ( gnNumGetRecords != 127 ) + { + i = gnNumGetRecords++; + itemrecord[i].dwTimestamp = GetTickCount(); + itemrecord[i].nSeed = dwSeed; + itemrecord[i].wCI = CI; + itemrecord[i].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] + unsigned 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 = &itemrecord[0].nIndex; + v8 = &itemrecord[0].wCI; + v9 = itemrecord; + v4 = &itemrecord[0].dwTimestamp; + do + { + if ( v6 - *v4 <= 6000 ) + { + 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 ); + } +} diff --git a/Source/items.h b/Source/items.h new file mode 100644 index 0000000..29f8568 --- /dev/null +++ b/Source/items.h @@ -0,0 +1,153 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//items +extern int itemactive[127]; +extern int uitemflag; +extern int itemavail[127]; +extern ItemStruct curruitem; +extern ItemGetRecordStruct itemrecord[127]; +extern ItemStruct item[128]; +extern char itemhold[3][3]; +extern char byte_641234[28]; /* check if part of above */ +extern int Item2Frm[35]; +extern int UniqueItemFlag[128]; +extern int numitems; +extern int gnNumGetRecords; + +void __cdecl InitItemGFX(); +bool __fastcall ItemPlace(int x, int y); +void __cdecl AddInitItems(); +void __cdecl InitItems(); +void __fastcall CalcPlrItemVals(int p, bool Loadgfx); +void __fastcall CalcPlrScrolls(int p); +void __fastcall CalcPlrStaff(int pnum); +void __fastcall CalcSelfItems(int pnum); +void __fastcall CalcPlrItemMin(int pnum); +bool __fastcall ItemMinStats(PlayerStruct *p, ItemStruct *x); +void __fastcall CalcPlrBookVals(int p); +void __fastcall CalcPlrInv(int p, bool Loadgfx); +void __fastcall SetPlrHandItem(ItemStruct *h, int idata); +void __fastcall GetPlrHandSeed(ItemStruct *h); +void __fastcall GetGoldSeed(int pnum, ItemStruct *h); +void __fastcall SetPlrHandSeed(ItemStruct *h, int iseed); +void __fastcall SetPlrHandGoldCurs(ItemStruct *h); +void __fastcall CreatePlrItems(int p); +bool __fastcall ItemSpaceOk(int i, int j); +bool __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, int 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 m); +int __fastcall RndUItem(int m); +int __cdecl RndAllItems(); +int __fastcall RndTypeItems(int itype, int imid); +int __fastcall CheckUnique(int i, int lvl, int uper, bool recreate); +void __fastcall GetUniqueItem(int i, int uid); +void __fastcall SpawnUnique(int uid, int x, int y); +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 RecreateItem(int ii, int idx, unsigned short ic, int iseed, int ivalue); +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, bool FlipFlag); +void __fastcall DeleteItem(int ii, int i); +void __cdecl ItemDoppel(); +void __cdecl ProcessItems(); +void __cdecl FreeItemGFX(); +void __fastcall GetItemFrm(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 DrawUBack(); +void __fastcall PrintUString(int x, int y, int cjustflag, char *str, int col); +void __fastcall DrawULine(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); +bool __fastcall SmithItemOk(int i); +int __fastcall RndSmithItem(int lvl); +void __fastcall BubbleSwapItem(ItemStruct *a, ItemStruct *b); +void __cdecl SortSmith(); +void __fastcall SpawnSmith(int lvl); +bool __fastcall PremiumItemOk(int i); +int __fastcall RndPremiumItem(int minlvl, int maxlvl); +void __fastcall SpawnOnePremium(int i, int plvl); +void __fastcall SpawnPremium(int lvl); +bool __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); +bool __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(); +int __cdecl ItemNoFlippy(); +void __fastcall CreateSpellBook(int x, int y, int ispell, bool sendmsg, int delta); +void __fastcall CreateMagicItem(int x, int y, int imisc, int icurs, int sendmsg, int delta); +bool __fastcall GetItemRecord(int dwSeed, int CI, int indx); +void __fastcall NextItemRecord(int i); +void __fastcall SetItemRecord(int dwSeed, int CI, int indx); +void __fastcall PutItemRecord(int seed, int ci, int index); + +/* data */ + +extern PLStruct PL_Prefix[84]; +extern PLStruct PL_Suffix[96]; +extern UItemStruct UniqueItemList[91]; + +/* rdata */ + + +extern ItemDataStruct AllItemsList[157]; +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]; diff --git a/Source/lighting.cpp b/Source/lighting.cpp new file mode 100644 index 0000000..2853073 --- /dev/null +++ b/Source/lighting.cpp @@ -0,0 +1,1787 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +LightListStruct VisionList[32]; +char lightactive[32]; +LightListStruct LightList[32]; +int numlights; +char dung_map_radius[2048]; /* char [16][128] */ +int dovision; // weak +int numvision; +char lightmax; // weak +int dolighting; // weak +char dung_map_rgba[16384]; /* int [64][64] short [64][128] char [64][256] */ +int visionid; +char *pLightTbl; /* todo: struct? */ +int lightflag; // weak + +CircleCoord CrawlTable = +{ + 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 } + }, + 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 } + }, + 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 } + }, + 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 } + } +}; + +void *pCrawlTable[19] = /* figure out what this is for */ +{ + &CrawlTable.n_1, &CrawlTable.n_4, &CrawlTable.n_16, + &CrawlTable.n_24, &CrawlTable.n_32, &CrawlTable.n_40, + &CrawlTable.n_48, &CrawlTable.n_56, &CrawlTable.n_64, + &CrawlTable.n_72, &CrawlTable.n_80, &CrawlTable.n_88, + &CrawlTable.n_96, &CrawlTable.n_104, &CrawlTable.n_112, + &CrawlTable.n_120, &CrawlTable.n_128, &CrawlTable.n_136, + &CrawlTable.n_144 +}; +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 }; + +//----- (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) +{ + short *v8; // eax + int v9; // edx + int *v10; // [esp+Ch] [ebp-4h] + short *s_ra; // [esp+18h] [ebp+8h] + + *d_g = 0; + *d_b = 0; + v8 = s_r; + v10 = y; + v9 = *(_DWORD *)s_r; + *(_DWORD *)s_r = 7 - *(_DWORD *)s_g; + *(_DWORD *)s_g = v9; + s_ra = (short *)*s_b; + *s_b = 7 - *d_r; + *d_r = (int)s_ra; + *x = *(_DWORD *)v8 - *s_b; + *v10 = *(_DWORD *)s_g - *d_r; + if ( *x < 0 ) + { + *x += 8; + *d_g = 1; + } + if ( *v10 < 0 ) + { + *v10 += 8; + *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(&x, &y, s_r, s_g, &s_b, &d_r, &d_g, &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(&x, &y, s_r, s_g, &s_b, &d_r, &d_g, &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(&x, &y, s_r, s_g, &s_b, &d_r, &d_g, &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 max_y; // ebx + int y; // esi + int x; // edx + int max_x; // edi + signed int v7; // esi + int v8; // eax + int radius_block; // [esp+14h] [ebp+8h] + + max_y = nYPos + nRadius + 1; + y = nYPos - (nRadius + 1); + x = nXPos - (nRadius + 1); + max_x = nXPos + nRadius + 1; + if ( y < 0 ) + y = 0; + if ( max_y > 112 ) + max_y = 112; + if ( x < 0 ) + x = 0; + if ( max_x > 112 ) + max_x = 112; + for ( radius_block = y; radius_block < max_y; ++radius_block ) + { + v7 = x; + if ( x < max_x ) + { + v8 = radius_block + 112 * x; + do + { + if ( v7 >= 0 && v7 < 112 && radius_block >= 0 && radius_block < 112 ) + dTransVal[0][v8] = dTransVal2[0][v8]; + ++v7; + v8 += 112; + } + while ( v7 < max_x ); + } + } +} + +//----- (00425930) -------------------------------------------------------- +void __fastcall DoUnVision(int nXPos, int nYPos, int nRadius) +{ + int y2; // edi + int y1; // esi + int x1; // edx + int x2; // ecx + char *v7; // eax + int i; // ecx + int j; // edx + + y2 = nYPos + nRadius + 1; + y1 = nYPos - (nRadius + 1); + x1 = nXPos - (nRadius + 1); + x2 = nRadius + 1 + nXPos; + if ( y1 < 0 ) + y1 = 0; + if ( y2 > 112 ) + y2 = 112; + if ( x1 < 0 ) + x1 = 0; + if ( x2 > 112 ) + x2 = 112; + if ( x1 < x2 ) + { + v7 = dFlags[x1]; + i = x2 - x1; + do + { + for ( j = y1; j < y2; ++j ) + v7[j] &= 0xBDu; + v7 += 112; + --i; + } + while ( i ); + } +} + +//----- (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[v20]); 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)&vCrawlTable[23][1] ); + ++v27; + } + while ( v27 < 4 ); +} + +//----- (00425C13) -------------------------------------------------------- +void __cdecl FreeLightTable() +{ + char *v0; // ecx + + v0 = pLightTbl; + pLightTbl = 0; + mem_free_dbg(v0); +} + +//----- (00425C25) -------------------------------------------------------- +void __cdecl InitLightTable() +{ + pLightTbl = (char *)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 + char *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[16]; // [esp+14h] [ebp-2Ch] /* check */ + int v46; // [esp+24h] [ebp-1Ch] + int v47; // [esp+28h] [ebp-18h] + char *v48; // [esp+2Ch] [ebp-14h] + int v49; // [esp+30h] [ebp-10h] + int v50; // [esp+34h] [ebp-Ch] + int v51; // [esp+38h] [ebp-8h] + int v52; // [esp+3Ch] [ebp-4h] + + v51 = 0; + v0 = pLightTbl; + v1 = light4flag != 0 ? 3 : 15; + v50 = light4flag != 0 ? 3 : 15; + if ( v1 > 0 ) + { + v49 = light4flag != 0 ? 3 : 15; + do + { + *v0++ = 0; + v52 = 0; + do + { + v2 = 16 * v52 + 15; + v3 = v51 + 16 * v52; + v4 = 0; + do + { + if ( v4 || v52 ) + *v0++ = v3; + if ( v3 >= v2 ) + { + v2 = 0; + v3 = 0; + } + else + { + ++v3; + } + ++v4; + } + while ( v4 < 16 ); + ++v52; + } + while ( v52 < 8 ); + v52 = 16; + v5 = v51 >> 1; + do + { + v6 = 8; + v7 = v5 + 8 * v52; + v8 = 8 * v52 + 7; + do + { + *v0++ = v7; + if ( v7 >= v8 ) + { + v8 = 0; + v7 = 0; + } + else + { + ++v7; + } + --v6; + } + while ( v6 ); + ++v52; + } + while ( v52 < 20 ); + v52 = 10; + do + { + v9 = 16; + v10 = v51 + 16 * v52; + v11 = 16 * v52 + 15; + do + { + *v0++ = v10; + if ( v10 >= v11 ) + { + v11 = 0; + v10 = 0; + } + else + { + ++v10; + } + if ( v10 == -1 ) + { + v11 = 0; + v10 = 0; + } + --v9; + } + while ( v9 ); + ++v52; + } + while ( v52 < 16 ); + if ( light4flag ) + v51 += 5; + else + ++v51; + --v49; + } + while ( v49 ); + } + memset(v0, 0, 0x100u); + v12 = v0 + 256; + if ( leveltype == 4 ) + { + v13 = pLightTbl; + if ( v1 > 0 ) + { + v14 = v50; + v49 = v50; + do + { + v52 = 0; + v45[0] = 0; + v51 = v14; + v15 = 1; + v48 = (char *)(v50 / v14); + v47 = v50 % v14; + v16 = 1; + do + { + v17 = v51; + v45[v15] = v16; + v51 = v47 + v17; + if ( v47 + v17 > v14 && v15 < 15 ) + { + ++v15; + v51 -= v14; + v45[v15] = v16; + } + if ( (char *)++v52 == v48 ) + { + ++v16; + v52 = 0; + } + ++v15; + } + while ( v15 < 16 ); + *v13 = 0; + v18 = (int)(v13 + 1); + *(_DWORD *)v18 = *(_DWORD *)&v45[1]; + *(_DWORD *)(v18 + 4) = *(_DWORD *)&v45[5]; + *(_DWORD *)(v18 + 8) = *(_DWORD *)&v45[9]; + *(_WORD *)(v18 + 12) = *(_WORD *)&v45[13]; + *(_BYTE *)(v18 + 14) = v45[15]; + v19 = 15; + v20 = (_BYTE *)(v18 + 15); + do + *v20++ = v45[v19--]; + while ( v19 > 0 ); + *v20 = 1; + v13 = (char *)v20 + 225; + --v14; + --v49; + } + while ( v49 ); + } + *v13 = 0; + v21 = 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; + v51 = (int)dung_map_radius; + v52 = 8; + do + { + v36 = 0; + v49 = 0; + v50 = v35 + 1; + do + { + if ( v36 <= v52 ) + *(_BYTE *)(v51 + v36) = (signed __int64)((double)v49 * 15.0 / ((double)v50 * 8.0) + 0.5); + else + *(_BYTE *)(v51 + v36) = 15; + v49 = ++v36; + } + while ( v36 < 128 ); + v52 += 8; + v51 += 128; + v35 = v50; + } + while ( v52 < 136 ); + v49 = 0; + v37 = dung_map_rgba; + do + { + v52 = 0; + do + { + v48 = v37; + v50 = v49; + v47 = 16; + do + { + v38 = 0; + v39 = v50 * v50; + v51 = v52; + do + { + v46 = v39 + v51 * v51; + v46 = (unsigned char)(signed __int64)sqrt((double)v46); + v40 = (double)v46; + if ( v40 >= 0.0 ) + v41 = 0.5; + else + v41 = -0.5; + v42 = (int)v48; + v51 += 8; + v48[v38++] = (signed __int64)(v41 + v40); + } + while ( v38 < 16 ); + v50 += 8; + v43 = (char *)(v42 + 16); + v44 = v47-- == 1; + v48 = v43; + } + while ( !v44 ); + --v52; + v37 = v43; + } + while ( v52 > -8 ); + --v49; + } + while ( (signed int)v43 < (signed int)&dung_map_rgba[16384] ); +} +// 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; + dolighting = 0; + lightflag = 0; + do + { + lightactive[v0] = v0; + ++v0; + } + while ( v0 < 32 ); +} +// 642A18: using guessed type int dolighting; +// 646A28: using guessed type int lightflag; + +//----- (00425FEC) -------------------------------------------------------- +int __fastcall AddLight(int x, int y, int r) +{ + int lid; // eax + + lid = -1; + if ( !lightflag && numlights < 32 ) + { + lid = lightactive[numlights++]; + dolighting = 1; + 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; + } + return lid; +} +// 642A18: using guessed type int dolighting; +// 646A28: using guessed type int lightflag; + +//----- (00426056) -------------------------------------------------------- +void __fastcall AddUnLight(int i) +{ + if ( !lightflag && i != -1 ) + { + LightList[i]._ldel = 1; + dolighting = 1; + } +} +// 642A18: using guessed type int dolighting; +// 646A28: using guessed type int lightflag; + +//----- (00426076) -------------------------------------------------------- +void __fastcall ChangeLightRadius(int i, int r) +{ + if ( !lightflag && i != -1 ) + { + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunflag = 1; + LightList[i]._lunr = LightList[i]._lradius; + dolighting = 1; + LightList[i]._lradius = r; + } +} +// 642A18: using guessed type int dolighting; +// 646A28: using guessed type int lightflag; + +//----- (004260C5) -------------------------------------------------------- +void __fastcall ChangeLightXY(int i, int x, int y) +{ + if ( !lightflag && i != -1 ) + { + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._lunflag = 1; + dolighting = 1; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._ly = y; + LightList[i]._lx = x; + } +} +// 642A18: using guessed type int dolighting; +// 646A28: using guessed type int lightflag; + +//----- (00426120) -------------------------------------------------------- +void __fastcall ChangeLightOff(int i, int x, int y) +{ + if ( !lightflag && i != -1 ) + { + LightList[i]._xoff = x; + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lunflag = 1; + LightList[i]._yoff = y; + dolighting = 1; + } +} +// 642A18: using guessed type int dolighting; +// 646A28: using guessed type int lightflag; + +//----- (0042617B) -------------------------------------------------------- +void __fastcall ChangeLight(int i, int x, int y, int r) +{ + if ( !lightflag && i != -1 ) + { + LightList[i]._lunx = LightList[i]._lx; + LightList[i]._luny = LightList[i]._ly; + LightList[i]._lunr = LightList[i]._lradius; + LightList[i]._lunflag = 1; + LightList[i]._lx = x; + LightList[i]._ly = y; + LightList[i]._lradius = r; + dolighting = 1; + } +} +// 642A18: using guessed type int dolighting; +// 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 ( dolighting ) + { + 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; + } + } + dolighting = 0; + } +} +// 642A18: using guessed type int dolighting; +// 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, bool mine) +{ + int vid; // eax + int v5; // esi + + vid = r; + if ( numvision < 32 ) + { + v5 = numvision; + dovision = 1; + VisionList[v5]._lx = x; + VisionList[v5]._ly = y; + VisionList[v5]._lradius = r; + vid = visionid++; + VisionList[v5]._lid = vid; + VisionList[v5]._ldel = 0; + ++numvision; + VisionList[v5]._lunflag = 0; + VisionList[v5]._lflags = mine != 0; + } + return vid; +} +// 642A0C: using guessed type int dovision; + +//----- (004263A0) -------------------------------------------------------- +void __fastcall ChangeVisionRadius(int id, int r) +{ + int i; // esi + + if ( numvision > 0 ) + { + 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; + } + } + } +} +// 642A0C: using guessed type int dovision; + +//----- (004263E1) -------------------------------------------------------- +void __fastcall ChangeVisionXY(int id, int x, int y) +{ + int i; // esi + + if ( numvision > 0 ) + { + 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; + } + } + } +} +// 642A0C: using guessed type int dovision; + +//----- (0042642B) -------------------------------------------------------- +void __cdecl ProcessVisionList() +{ + bool delflag; // ecx + int i; + + 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; + } + } + + if ( TransVal > 0 ) + memset(TransList, 0, TransVal); + + 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 = 0; + if ( numvision <= 0 ) + break; + for(i = 0; i < numvision; i++) + { + if ( VisionList[i]._ldel ) + { + --numvision; + if ( numvision > 0 && i != numvision ) + qmemcpy(&VisionList[i], &VisionList[numvision], sizeof(LightListStruct)); + delflag = 1; + } + } + } + while ( delflag ); + } + + dovision = 0; +} +// 5A5590: using guessed type char TransVal; +// 642A0C: using guessed type int dovision; + +//----- (0042651F) -------------------------------------------------------- +void __cdecl lighting_color_cycling() +{ + char *v0; // eax + signed int v1; // ebx + char *v2; // eax + char *v3; // edi + char v4; // dl + const void *v5; // esi + + if ( leveltype == 4 ) + { + v0 = pLightTbl; + if ( (light4flag != 0 ? 4 : 16) > 0 ) + { + v1 = light4flag != 0 ? 4 : 16; + do + { + v2 = v0 + 1; + v3 = v2; + v4 = *v2; + v5 = v2 + 1; + v2 += 30; + qmemcpy(v3, v5, 0x1Eu); + *v2 = v4; + v0 = v2 + 225; + --v1; + } + while ( v1 ); + } + } +} +// 525728: using guessed type int light4flag; +// 5BB1ED: using guessed type char leveltype; diff --git a/Source/lighting.h b/Source/lighting.h new file mode 100644 index 0000000..95397bd --- /dev/null +++ b/Source/lighting.h @@ -0,0 +1,58 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//lighting +extern LightListStruct VisionList[32]; +extern char lightactive[32]; +extern LightListStruct LightList[32]; +extern int numlights; +extern char dung_map_radius[2048]; /* char [16][128] */ +extern int dovision; // weak +extern int numvision; +extern char lightmax; // weak +extern int dolighting; // weak +extern char dung_map_rgba[16384]; /* int [64][64] short [64][128] char [64][256] */ +extern int visionid; +extern char *pLightTbl; /* todo: struct? */ +extern int lightflag; // weak + +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, bool 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(); + +/* rdata */ + +extern CircleCoord CrawlTable; +extern void *pCrawlTable[19]; +extern unsigned char vCrawlTable[23][30]; +extern unsigned char byte_49463C[18][18]; +extern unsigned char RadiusAdj[23]; diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp new file mode 100644 index 0000000..3a99742 --- /dev/null +++ b/Source/loadsave.cpp @@ -0,0 +1,1306 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +void *tbuff; + +//----- (00426564) -------------------------------------------------------- +void __fastcall LoadGame(bool firstflag) +{ + int v1; // esi + int v2; // edi + 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 + 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 + char dst[260]; // [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] + int from_save; // [esp+118h] [ebp-8h] + int quest_num; // [esp+11Ch] [ebp-4h] + + 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(); + invflag = OLoad(); + chrflag = OLoad(); + 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(firstflag, 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)&monstkills[200] ); + if ( leveltype ) + { + v12 = monstactive; + do + { + *v12 = ILoad(); + ++v12; + } + while ( (signed int)v12 < (signed int)&monstactive[200] ); + for ( i = 0; i < nummonsters; ++i ) + LoadMonster(monstactive[i]); + v14 = missileactive; + do + { + *v14 = BLoad(); + ++v14; + } + while ( (signed int)v14 < (signed int)&missileactive[125] ); + v15 = missileavail; + do + { + *v15 = BLoad(); + ++v15; + } + while ( (signed int)v15 < (signed int)&missileavail[125] ); + for ( j = 0; j < nummissiles; ++j ) + LoadMissile(missileactive[j]); + v17 = objectactive; + do + { + *v17 = BLoad(); + ++v17; + } + while ( (signed int)v17 < (signed int)&objectactive[127] ); + v18 = objectavail; + do + { + *v18 = BLoad(); + ++v18; + } + while ( (signed int)v18 < (signed int)&objectavail[127] ); + 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)&itemactive[127] ); + 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 + { + *v27 = OLoad(); + ++v27; + } + while ( (signed int)v27 < (signed int)&UniqueItemFlag[128] ); + quest_num = 0; + do + { + from_save = 112; + v29 = (char *)dTransVal + quest_num; + do + { + *v29 = BLoad(); + v29 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + from_save = 112; + v30 = (char *)dFlags + quest_num; + do + { + *v30 = BLoad(); + v30 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + from_save = 112; + v31 = (char *)dPlayer + quest_num; + do + { + *v31 = BLoad(); + v31 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + from_save = 112; + v32 = (char *)dItem + quest_num; + do + { + *v32 = BLoad(); + v32 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + if ( leveltype ) + { + v33 = dMonster; + do + { + v34 = (unsigned int *)v33; + from_save = 112; + do + { + *v34 = ILoad(); + v34 += 112; + --from_save; + } + while ( from_save ); + v33 = (int (*)[112])((char *)v33 + 4); + } + while ( (signed int)v33 < (signed int)dMonster[1] ); + quest_num = 0; + do + { + from_save = 112; + v35 = (char *)dDead + quest_num; + do + { + *v35 = BLoad(); + v35 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + from_save = 112; + v36 = (char *)dObject + quest_num; + do + { + *v36 = BLoad(); + v36 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + from_save = 112; + v37 = (char *)dTransVal + quest_num; + do + { + *v37 = BLoad(); + v37 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + quest_num = 0; + do + { + from_save = 112; + v38 = (char *)dTransVal2 + quest_num; + do + { + *v38 = BLoad(); + v38 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + v39 = 0; + do + { + v40 = (bool *)automapview + v39; + from_save = 40; + do + { + *v40 = OLoad(); + v40 += 40; + --from_save; + } + while ( from_save ); + ++v39; + } + while ( v39 < 40 ); + quest_num = 0; + do + { + from_save = 112; + v41 = (char *)dMissile + quest_num; + do + { + *v41 = BLoad(); + v41 += 112; + --from_save; + } + while ( from_save ); + ++quest_num; + } + while ( quest_num < 112 ); + } + numpremium = ILoad(); + premiumlevel = ILoad(); + v42 = 0; + do + LoadPremium(v42++); + while ( v42 < 6 ); + automapflag = OLoad(); + AutoMapScale = ILoad(); + mem_free_dbg(ptr); + AutomapZoomReset(); + ResyncQuests(); + if ( leveltype ) + ProcessLightList(); + RedoPlayerVision(); + ProcessVisionList(); + missiles_process_charge(); + ResetPal(); + SetCursor(CURSOR_HAND); + 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 i) +{ + memcpy(&plr[i], tbuff, 0x54B0u); + tbuff = (char *)tbuff + 21680; +} + +//----- (00426BA9) -------------------------------------------------------- +void __fastcall LoadMonster(int i) +{ + int v1; // edi + + v1 = i; + memcpy(&monster[i], tbuff, 0xD8u); + tbuff = (char *)tbuff + 216; + SyncMonsterAnim(v1); +} + +//----- (00426BDE) -------------------------------------------------------- +void __fastcall LoadMissile(int i) +{ + memcpy(&missile[i], tbuff, 0xB0u); + tbuff = (char *)tbuff + 176; +} + +//----- (00426C08) -------------------------------------------------------- +void __fastcall LoadObject(int i) +{ + memcpy(&object[i], tbuff, 0x78u); + tbuff = (char *)tbuff + 120; +} + +//----- (00426C2A) -------------------------------------------------------- +void __fastcall LoadItem(int i) +{ + int v1; // edi + + v1 = i; + memcpy(&item[i], tbuff, 0x170u); + tbuff = (char *)tbuff + 368; + GetItemFrm(v1); +} + +//----- (00426C5F) -------------------------------------------------------- +void __fastcall LoadPremium(int i) +{ + memcpy(&premiumitem[i], 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(); + DoomQuestState = ILoad(); +} + +//----- (00426CDE) -------------------------------------------------------- +void __fastcall LoadLighting(int i) +{ + memcpy(&LightList[i], tbuff, 0x34u); + tbuff = (char *)tbuff + 52; +} + +//----- (00426D00) -------------------------------------------------------- +void __fastcall LoadVision(int i) +{ + memcpy(&VisionList[i], tbuff, 0x34u); + tbuff = (char *)tbuff + 52; +} + +//----- (00426D22) -------------------------------------------------------- +void __fastcall LoadPortal(int i) +{ + memcpy(&portal[i], 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); /* FILEBUFF */ + 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)&monstkills[200] ); + if ( leveltype ) + { + v6 = monstactive; + do + { + ISave(*v6); + ++v6; + } + while ( (signed int)v6 < (signed int)&monstactive[200] ); + for ( i = 0; i < nummonsters; ++i ) + SaveMonster(monstactive[i]); + v8 = missileactive; + do + { + BSave(*(_BYTE *)v8); + ++v8; + } + while ( (signed int)v8 < (signed int)&missileactive[125] ); + v9 = missileavail; + do + { + BSave(*(_BYTE *)v9); + ++v9; + } + while ( (signed int)v9 < (signed int)&missileavail[125] ); + for ( j = 0; j < nummissiles; ++j ) + SaveMissile(missileactive[j]); + v11 = objectactive; + do + { + BSave(*(_BYTE *)v11); + ++v11; + } + while ( (signed int)v11 < (signed int)&objectactive[127] ); + v12 = objectavail; + do + { + BSave(*(_BYTE *)v12); + ++v12; + } + while ( (signed int)v12 < (signed int)&objectavail[127] ); + 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)&itemactive[127] ); + 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)&UniqueItemFlag[128] ); + 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, &item[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(DoomQuestState); +} + +//----- (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 + int i; // esi + int j; // esi + void *v47; // esi + int v48; // eax + int v49; // eax + char v50[260]; // [esp+0h] [ebp-10Ch] + void *SaveBuff; // [esp+104h] [ebp-8h] + + if ( !currlevel ) + glSeedTbl[0] = GetRndSeed(); + v0 = codec_get_encoded_len(262147); /* FILEBUFF */ + SaveBuff = DiabloAllocPtr(v0); + tbuff = SaveBuff; + if ( leveltype ) + { + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + BSave(dDead[j][i]); /* check */ + } + } + } + ISave(nummonsters); + ISave(numitems); + ISave(nobjects); + + if ( leveltype ) + { + for(i = 0; i < 200; i++) + ISave(monstactive[i]); + + for(i = 0; i < nummonsters; i++) + SaveMonster(monstactive[i]); + + for(i = 0; i < 127; i++) + BSave(objectactive[i]); + + for(i = 0; i < 127; i++) + BSave(objectavail[i]); + + for(i = 0; i < nobjects; i++) + SaveObject(objectactive[i]); + } + + for(i = 0; i < 127; i++) + BSave(itemactive[i]); + + for(i = 0; i < 127; i++) + BSave(itemavail[i]); + + for(i = 0; i < numitems; i++) + SaveItem(itemactive[i]); + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + BSave(dFlags[j][i] & 0xF8); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + BSave(dItem[j][i]); + } + } + + if ( leveltype ) + { + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + ISave(dMonster[j][i]); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + BSave(dObject[j][i]); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + BSave(dTransVal[j][i]); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + BSave(dTransVal2[j][i]); + } + } + + for(i = 0; i < 40; i++) + { + for(j = 0; j < 40; j++) + { + OSave(automapview[j][i]); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + BSave(dMissile[j][i]); + } + } + } + GetTempLevelNames(v50); + v47 = SaveBuff; + v48 = codec_get_encoded_len((_BYTE *)tbuff - (_BYTE *)SaveBuff); + 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() +{ + int i; // esi + int j; // esi + char dst[260]; // [esp+Ch] [ebp-10Ch] + int len; // [esp+110h] [ebp-8h] + void *LoadBuff; // [esp+114h] [ebp-4h] + + GetPermLevelNames(dst); + LoadBuff = pfile_read(dst, &len); + tbuff = LoadBuff; + + if ( leveltype ) + { + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dDead[j][i] = BLoad(); /* check */ + } + } + + SetDead(); + } + + nummonsters = ILoad(); + numitems = ILoad(); + nobjects = ILoad(); + + if ( leveltype ) + { + for(i = 0; i < 200; i++) + monstactive[i] = ILoad(); + + for(i = 0; i < nummonsters; i++) + LoadMonster(monstactive[i]); + + for(i = 0; i < 127; i++) + objectactive[i] = BLoad(); + + for(i = 0; i < 127; 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 < 127; i++) + itemactive[i] = BLoad(); + + for(i = 0; i < 127; i++) + itemavail[i] = BLoad(); + + for(i = 0; i < numitems; i++) + LoadItem(itemactive[i]); + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dFlags[j][i] = BLoad(); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dItem[j][i] = BLoad(); + } + } + + if ( leveltype ) + { + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dMonster[j][i] = ILoad(); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dObject[j][i] = BLoad(); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dTransVal[j][i] = BLoad(); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dTransVal2[j][i] = BLoad(); + } + } + + for(i = 0; i < 40; i++) + { + for(j = 0; j < 40; j++) + { + automapview[j][i] = OLoad(); + } + } + + for(i = 0; i < 112; i++) + { + for(j = 0; j < 112; j++) + { + dMissile[j][i] = 0; + } + } + } + + AutomapZoomReset(); + ResyncQuests(); + SyncPortals(); + dolighting = 1; + + for(i = 0; i < 4; i++) + { + if ( plr[i].plractive && currlevel == plr[i].plrlevel ) + LightList[plr[i]._plid]._lunflag = 1; + } + + mem_free_dbg(LoadBuff); +} +// 5BB1ED: using guessed type char leveltype; +// 642A18: using guessed type int dolighting; diff --git a/Source/loadsave.h b/Source/loadsave.h new file mode 100644 index 0000000..819af24 --- /dev/null +++ b/Source/loadsave.h @@ -0,0 +1,46 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//loadsave +extern void *tbuff; + +void __fastcall LoadGame(bool firstflag); +char __cdecl BLoad(); +int __cdecl ILoad(); +int __cdecl ILoad_2(); +bool __cdecl OLoad(); +void __fastcall LoadPlayer(int i); +void __fastcall LoadMonster(int i); +void __fastcall LoadMissile(int i); +void __fastcall LoadObject(int i); +void __fastcall LoadItem(int i); +void __fastcall LoadPremium(int i); +void __fastcall LoadQuest(int i); +void __fastcall LoadLighting(int i); +void __fastcall LoadVision(int i); +void __fastcall LoadPortal(int i); +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(); \ No newline at end of file diff --git a/Source/logging.cpp b/Source/logging.cpp new file mode 100644 index 0000000..b2dadbc --- /dev/null +++ b/Source/logging.cpp @@ -0,0 +1,248 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int log_cpp_init_value; // weak +static CRITICAL_SECTION sgMemCrit; +CHAR FileName[260]; // idb +char log_buffer[388]; +LPCVOID lpAddress; // idb +DWORD nNumberOfBytesToWrite; // idb + +int log_inf = 0x7F800000; // weak + +/* rdata */ + +int log_not_created = 1; // weak +HANDLE log_file = (HANDLE)0xFFFFFFFF; // idb + +//----- (004279F7) -------------------------------------------------------- +struct log_cpp_init_1 +{ + log_cpp_init_1() + { + log_cpp_init_value = log_inf; + } +} _log_cpp_init_1; +// 47F070: using guessed type int log_inf; +// 646A30: using guessed type int log_cpp_init_value; + +//----- (00427A02) -------------------------------------------------------- +struct log_cpp_init_2 +{ + log_cpp_init_2() + { + log_init_mutex(); + j_log_cleanup_mutex(); + } +} _log_cpp_init_2; + +//----- (00427A0C) -------------------------------------------------------- +void __cdecl log_init_mutex() +{ + InitializeCriticalSection(&sgMemCrit); +} + +//----- (00427A18) -------------------------------------------------------- +void __cdecl j_log_cleanup_mutex() +{ + atexit(log_cleanup_mutex); +} + +//----- (00427A24) -------------------------------------------------------- +void __cdecl log_cleanup_mutex() +{ + DeleteCriticalSection(&sgMemCrit); +} + +//----- (00427A30) -------------------------------------------------------- +void __cdecl log_flush(bool force_close) +{ + void *v1; // eax + DWORD NumberOfBytesWritten; // [esp+8h] [ebp-4h] + + EnterCriticalSection(&sgMemCrit); + 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; + } + LeaveCriticalSection(&sgMemCrit); +} + +//----- (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, '\\')) != 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, 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; +} +// 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 *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); + EnterCriticalSection(&sgMemCrit); + _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; + } + LeaveCriticalSection(&sgMemCrit); +} + +//----- (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); +} diff --git a/Source/logging.h b/Source/logging.h new file mode 100644 index 0000000..0d955cd --- /dev/null +++ b/Source/logging.h @@ -0,0 +1,37 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//logging +extern int log_cpp_init_value; // weak +extern CHAR FileName[260]; // idb +extern char log_buffer[388]; +extern LPCVOID lpAddress; // idb +extern DWORD nNumberOfBytesToWrite; // idb + +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(); // should be HANDLE +void __fastcall log_get_version(VS_FIXEDFILEINFO *file_info); +void log_printf(char *pszFmt, ...); // LogMessage +void __cdecl log_dump_computer_info(); + +/* data */ + +extern int log_inf; // weak + +/* rdata */ + +extern int log_not_created; // weak +extern HANDLE log_file; // idb diff --git a/Source/mainmenu.cpp b/Source/mainmenu.cpp new file mode 100644 index 0000000..c04ee5c --- /dev/null +++ b/Source/mainmenu.cpp @@ -0,0 +1,206 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int mainmenu_cpp_init_value; // weak +char chr_name_str[16]; + +int mainmenu_inf = 0x7F800000; // weak + +/* rdata */ + +int menu_music_track_id = 5; // idb + +//----- (00427E13) -------------------------------------------------------- +struct mainmenu_cpp_init +{ + mainmenu_cpp_init() + { + mainmenu_cpp_init_value = mainmenu_inf; + } +} _mainmenu_cpp_init; +// 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(a1) ) /* 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) /* 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, + 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: + v1 = 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) -------------------------------------------------------- +int __cdecl mainmenu_multi_player() +{ + gbMaxPlayers = 4; + return 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(); +} diff --git a/Source/mainmenu.h b/Source/mainmenu.h new file mode 100644 index 0000000..aefbc2c --- /dev/null +++ b/Source/mainmenu.h @@ -0,0 +1,32 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//mainmenu +extern int mainmenu_cpp_init_value; // weak +extern char chr_name_str[16]; + +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); +int __cdecl mainmenu_multi_player(); +void __cdecl mainmenu_play_intro(); + +/* data */ + +extern int mainmenu_inf; // weak + +/* rdata */ + +extern int menu_music_track_id; // idb diff --git a/Source/minitext.cpp b/Source/minitext.cpp new file mode 100644 index 0000000..7bc3f46 --- /dev/null +++ b/Source/minitext.cpp @@ -0,0 +1,339 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int qtexty; // weak +char *qtextptr; +int qtextSpd; // weak +char qtextflag; // weak +int scrolltexty; // weak +int sgLastScroll; // weak +void *pMedTextCels; +void *pTextBoxCels; + +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 +}; +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 +}; + +/* rdata */ + +int qscroll_spd_tbl[9] = { 2, 4, 6, 8, 0, -1, -2, -3, -4 }; + +//----- (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) +{ + 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); +} +// 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 + + CelDecodeOnly(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 qstr[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 ) + { + qstr[v2] = v5; + v1 += mfontkern[mfontframe[v5]] + 2; + } + else + { + --v2; + } + } + v6 = *i; + v7 = &qstr[v2]; + qstr[v2] = 0; + if ( v6 == 124 ) + { + *v7 = 0; + v14 = 1; + } + else if ( v6 != 10 ) + { + while ( *v7 != 32 && v2 > 0 ) + { + *v7 = 0; + v7 = &qstr[--v2]; + } + } + v8 = qstr[0]; + if ( qstr[0] ) + { + v9 = qstr; + 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 qstr[128]; diff --git a/Source/minitext.h b/Source/minitext.h new file mode 100644 index 0000000..bb82932 --- /dev/null +++ b/Source/minitext.h @@ -0,0 +1,36 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//minitext +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 __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(); + +/* data */ + +extern unsigned char mfontframe[127]; +extern unsigned char mfontkern[56]; + +/* rdata */ + +extern int qscroll_spd_tbl[9]; diff --git a/Source/missiles.cpp b/Source/missiles.cpp new file mode 100644 index 0000000..9369ed0 --- /dev/null +++ b/Source/missiles.cpp @@ -0,0 +1,7712 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int missileactive[125]; +int missileavail[125]; +MissileStruct missile[125]; +int nummissiles; // idb +int ManashieldFlag; +unk_missile_struct misflagstruct_unknown[125]; +int MissilePreFlag; // weak + + +MissileData missiledata[68] = +{ + { MIS_ARROW, &AddArrow, &MI_Arrow, 1, 0u, 0u, MFILE_ARROWS, -1, -1 }, + { 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, -1 }, + { MIS_LIGHTBALL, &AddLightball, &MI_Lightball, 1, 1u, 2u, MFILE_LGHNING, -1, -1 }, + { 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, -1, -1 }, + { MIS_LIGHTNING, &AddLightning, &MI_Lightning, 1, 1u, 2u, MFILE_LGHNING, LS_LNING1, LS_ELECIMP1 }, + { MIS_MISEXP, &AddMisexp, &MI_Misexp, 1, 2u, 0u, MFILE_MAGBLOS, -1, -1 }, + { 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, -1, -1 }, + { MIS_MANASHIELD, &AddManashield, &MI_SetManashield, 0, 1u, 3u, MFILE_MANASHLD, LS_MSHIELD, -1 }, + { MIS_FIREMOVE, &AddFiremove, &MI_Firemove, 1, 1u, 1u, MFILE_FIREWAL, -1, -1 }, + { MIS_CHAIN, &AddChain, &MI_Chain, 1, 1u, 2u, MFILE_LGHNING, LS_LNING1, LS_ELECIMP1 }, + { MIS_NULL_10, NULL, NULL, 1, 1u, 2u, MFILE_LGHNING, -1, -1 }, + { 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, -1, -1 }, + { MIS_NULL_13, &miss_null_13, &mi_null_11, 1, 2u, 0u, MFILE_METLHIT, -1, -1 }, + { MIS_RHINO, &AddRhino, &MI_Rhino, 1, 2u, 0u, MFILE_NONE, -1, -1 }, + { MIS_MAGMABALL, &AddMagmaball, &MI_Firebolt, 1, 1u, 1u, MFILE_MAGBALL, -1, -1 }, + { MIS_LIGHTCTRL2, &AddLightctrl, &MI_Lightctrl, 0, 1u, 2u, MFILE_THINLGHT, -1, -1 }, + { MIS_LIGHTNING2, &AddLightning, &MI_Lightning, 1, 1u, 2u, MFILE_THINLGHT, -1, -1 }, + { MIS_FLARE, &AddFlare, &MI_Firebolt, 1, 1u, 3u, MFILE_FLARE, -1, -1 }, + { MIS_MISEXP2, &AddMisexp, &MI_Misexp, 1, 2u, 3u, MFILE_FLAREEXP, -1, -1 }, + { MIS_TELEPORT, &AddTeleport, &MI_Teleport, 0, 1u, 0u, MFILE_NONE, LS_ELEMENTL, -1 }, + { MIS_LARROW, &AddLArrow, &MI_LArrow, 1, 0u, 1u, MFILE_FARROW, -1, -1 }, + { MIS_DOOMSERP, NULL, NULL, 0, 1u, 3u, MFILE_DOOM, LS_DSERP, -1 }, + { MIS_NULL_1D, &miss_null_1D, &MI_Firewall, 1, 2u, 1u, MFILE_FIREWAL, -1, -1 }, + { MIS_STONE, &AddStone, &MI_Stone, 0, 1u, 3u, MFILE_NONE, LS_SCURIMP, -1 }, + { MIS_NULL_1F, &miss_null_1F, &MI_Dummy, 1, 1u, 0u, MFILE_NONE, -1, -1 }, + { MIS_INVISIBL, NULL, NULL, 0, 1u, 0u, MFILE_NONE, LS_INVISIBL, -1 }, + { MIS_GOLEM, &AddGolem, &MI_Golem, 0, 1u, 0u, MFILE_NONE, LS_GOLUM, -1 }, + { MIS_ETHEREALIZE, &AddEtherealize, &MI_Etherealize, 1, 1u, 0u, MFILE_ETHRSHLD, LS_ETHEREAL, -1 }, + { MIS_NULL_23, &miss_null_23, &mi_null_11, 1, 2u, 0u, MFILE_BLODBUR, -1, -1 }, + { MIS_BOOM, &AddBoom, &MI_Boom, 1, 2u, 0u, MFILE_NEWEXP, -1, -1 }, + { MIS_HEAL, &AddHeal, &MI_Dummy, 0, 1u, 0u, MFILE_NONE, -1, -1 }, + { MIS_FIREWALLC, &AddFirewallC, &MI_FirewallC, 0, 1u, 1u, MFILE_FIREWAL, -1, -1 }, + { MIS_INFRA, &AddInfra, &MI_Infra, 0, 1u, 0u, MFILE_NONE, LS_INFRAVIS, -1 }, + { MIS_IDENTIFY, &AddIdentify, &MI_Dummy, 0, 1u, 0u, MFILE_NONE, -1, -1 }, + { MIS_WAVE, &AddWave, &MI_Wave, 1, 1u, 1u, MFILE_FIREWAL, LS_FLAMWAVE, -1 }, + { MIS_NOVA, &AddNova, &MI_Nova, 1, 1u, 2u, MFILE_LGHNING, LS_NOVA, -1 }, + { MIS_BLODBOIL, &miss_null_1F, &MI_Blodboil, 1, 1u, 0u, MFILE_NONE, -1, LS_BLODBOIL }, + { MIS_APOCA, &AddApoca, &MI_Apoca, 1, 1u, 3u, MFILE_NEWEXP, LS_APOC, -1 }, + { MIS_REPAIR, &AddRepair, &MI_Dummy, 0, 2u, 0u, MFILE_NONE, -1, -1 }, + { MIS_RECHARGE, &AddRecharge, &MI_Dummy, 0, 2u, 0u, MFILE_NONE, -1, -1 }, + { MIS_DISARM, &AddDisarm, &MI_Dummy, 0, 2u, 0u, MFILE_NONE, LS_TRAPDIS, -1 }, + { MIS_FLAME, &AddFlame, &MI_Flame, 1, 1u, 1u, MFILE_INFERNO, LS_SPOUTSTR, -1 }, + { MIS_FLAMEC, &AddFlamec, &MI_Flamec, 0, 1u, 1u, MFILE_NONE, -1, -1 }, + { MIS_NULL_32, &miss_null_32, &mi_null_32, 1, 2u, 0u, MFILE_NONE, -1, -1 }, + { MIS_NULL_33, &miss_null_33, &mi_null_33, 1, 0u, 1u, MFILE_KRULL, -1, -1 }, + { MIS_CBOLT, &AddCbolt, &MI_Cbolt, 1, 1u, 2u, MFILE_MINILTNG, LS_CBOLT, -1 }, + { MIS_HBOLT, &AddHbolt, &MI_Hbolt, 1, 1u, 0u, MFILE_HOLY, LS_HOLYBOLT, LS_ELECIMP1 }, + { MIS_RESURRECT, &AddResurrect, &MI_Dummy, 0, 1u, 3u, MFILE_NONE, -1, LS_RESUR }, + { MIS_TELEKINESIS, &AddTelekinesis, &MI_Dummy, 0, 1u, 0u, MFILE_NONE, LS_ETHEREAL, -1 }, + { MIS_LARROW2, &AddLArrow, &MI_LArrow, 1, 0u, 2u, MFILE_LARROW, -1, -1 }, + { MIS_ACID, &AddAcid, &MI_Firebolt, 1, 1u, 4u, MFILE_ACIDBF, LS_ACID, -1 }, + { MIS_MISEXP3, &AddMisexp, &MI_Acidsplat, 1, 2u, 4u, MFILE_ACIDSPLA, -1, -1 }, + { MIS_ACIDPUD, &AddAcidpud, &MI_Acidpud, 1, 2u, 4u, MFILE_ACIDPUD, LS_PUDDLE, -1 }, + { MIS_HEALOTHER, &AddHealOther, &MI_Dummy, 0, 1u, 0u, MFILE_NONE, -1, -1 }, + { MIS_ELEMENT, &AddElement, &MI_Element, 1, 1u, 1u, MFILE_FIRERUN, LS_ELEMENTL, -1 }, + { MIS_RESURRECTBEAM, &AddResurrectBeam, &MI_ResurrectBeam, 1, 1u, 0u, MFILE_RESSUR1, -1, -1 }, + { MIS_BONESPIRIT, &AddBoneSpirit, &MI_Bonespirit, 1, 1u, 3u, MFILE_SKLBALL, LS_BONESP, LS_BSIMPCT }, + { MIS_WEAPEXP, &AddWeapexp, &MI_Weapexp, 1, 2u, 0u, MFILE_NONE, -1, -1 }, + { MIS_RPORTAL, &AddRportal, &MI_Rportal, 1, 2u, 0u, MFILE_RPORTAL, LS_SENTINEL, LS_ELEMENTL }, + { MIS_BOOM2, &AddBoom, &MI_Boom, 1, 2u, 0u, MFILE_FIREPLAR, -1, -1 }, + { MIS_DIABAPOCA, &AddDiabApoca, &MI_Dummy, 0, 2u, 0u, MFILE_NONE, -1, -1 } +}; +MisFileData misfiledata[47] = +{ + { + 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 } + }, + { + MFILE_NONE, 0, &empty_string, 0, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 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, -1, -1, -1, 0, 1, 1 }; +int YDirAdd[8] = { 1, 1, 1, 0, -1, -1, -1, 0 }; + +//----- (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[5]; // [esp+10Ch] [ebp-20h] + char urtoll[5]; // [esp+114h] [ebp-18h] + char lltour[5]; // [esp+11Ch] [ebp-10h] + char ultolr[5]; // [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; + missileavail[-nummissiles + 125] = v2; /* *(&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 = 0; // v4; /* check */ + v3 = 0; // 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) -------------------------------------------------------- +bool __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 == MT_ILLWEAV && _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 ( CheckMonsterHit(arglist, (bool *)&t) ) + return t; +#ifdef _DEBUG + if ( v14 >= v10 && !debug_mode_dollar_sign && !debug_mode_key_inverted_v && monster[v6]._mmode != MM_STONE ) + return 0; +#else + if ( v14 >= v10 && monster[v6]._mmode != MM_STONE ) + return 0; +#endif + _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; +#ifdef _DEBUG + if ( debug_mode_dollar_sign || debug_mode_key_inverted_v ) + monster[v6]._mhitpoints = 0; +#endif + 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) -------------------------------------------------------- +bool __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] + bool ret; // [esp+10h] [ebp-14h] + int v25; // [esp+14h] [ebp-10h] + int v26; // [esp+18h] [ebp-Ch] + int pnuma; // [esp+1Ch] [ebp-8h] + int arglist; // [esp+20h] [ebp-4h] + unsigned char dist_3; // [esp+37h] [ebp+13h] + + 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 != MT_DIABLO && monster[v7].MData->mMonstClass ) + { + return 0; + } + if ( monster[v7].MType->mtype == MT_ILLWEAV && _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; + if ( CheckMonsterHit(arglist, &ret) ) + return ret; +#ifdef _DEBUG + if ( v25 >= v13 && !debug_mode_key_inverted_v && !debug_mode_dollar_sign ) + return 0; +#else + if ( v25 >= v13 ) + return 0; +#endif + 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(arglist, 1); + } + else if ( monster[v7]._mmode == MM_STONE ) + { + if ( arglist > 3 ) + M_StartHit(arglist, v21, v19); + monster[v7]._mmode = MM_STONE; + } + else + { + if ( !dist_3 && v22 & 0x800 ) + { + M_GetKnockback(arglist); + v21 = pnuma; + } + if ( arglist > 3 ) + M_StartHit(arglist, v21, v19); + } + } + else if ( monster[v7]._mmode == MM_STONE ) + { + M_StartKill(arglist, v21); + monster[v7]._mmode = MM_STONE; + } + else + { + M_StartKill(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) -------------------------------------------------------- +bool __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); +#ifdef _DEBUG + if ( debug_mode_dollar_sign || debug_mode_key_inverted_v ) + v32 = 1000; +#endif + 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) -------------------------------------------------------- +bool __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, bool shift, int mx, int my, int nodel) +{ + int v7; // ebx + int v8; // esi + char v9; // dl + int v10; // ecx + int v11; // edi + int v12; // eax + bool v13; // eax + char v14; // al + int v15; // ecx + int v16; // edx + bool v17; // eax + int v18; // eax + bool v19; // eax + char v20; // al + int v21; // eax + int v22; // eax + char v23; // al + char v24; // al + int v25; // edx + int v26; // ecx + int v27; // [esp-Ch] [ebp-1Ch] + int v28; // [esp-8h] [ebp-18h] + int mindama; // [esp+Ch] [ebp-4h] + + v7 = mindam; + v8 = i; + mindama = mindam; + v9 = missile[i]._miAnimType; + if ( v9 == 4 || (v10 = missile[v8]._misource, v10 == -1) ) + { + v11 = 112 * mx + my; + v21 = dMonster[0][v11]; + if ( v21 > 0 ) + { + v28 = missile[v8]._mitype; + v27 = missile[v8]._midist; + v22 = v9 == 4 ? MonsterMHit(missile[v8]._misource, v21 - 1, v7, maxdam, v27, v28, shift) : MonsterTrapHit(v21 - 1, v7, maxdam, v27, v28, shift); + if ( v22 ) + { + if ( !(_BYTE)nodel ) + missile[v8]._mirange = 0; + missile[v8]._miHitFlag = 1; + } + } + v23 = dPlayer[0][v11]; + if ( v23 > 0 ) + { + v17 = PlayerMHit( + v23 - 1, + -1, + missile[v8]._midist, + v7, + maxdam, + missile[v8]._mitype, + shift, + _LOBYTE(missile[v8]._miAnimType) == 4); +LABEL_35: + if ( v17 ) + { + if ( !(_BYTE)nodel ) + missile[v8]._mirange = 0; + missile[v8]._miHitFlag = 1; + } + goto LABEL_39; + } + } + else + { + if ( !missile[v8]._micaster ) + { + v11 = 112 * mx + my; + v12 = dMonster[0][v11]; + if ( v12 <= 0 ) + { + if ( v12 >= 0 || monster[-(v12 + 1)]._mmode != MM_STONE ) + { +LABEL_13: + v14 = dPlayer[0][v11]; + if ( v14 <= 0 ) + goto LABEL_39; + v15 = missile[v8]._misource; + v16 = v14 - 1; + if ( v16 == v15 ) + goto LABEL_39; + v17 = Plr2PlrMHit( + v15, + v16, + mindama, + maxdam, + missile[v8]._midist, + missile[v8]._mitype, + shift); + goto LABEL_35; + } + v13 = MonsterMHit( + v10, + -1 - v12, + mindama, + maxdam, + missile[v8]._midist, + missile[v8]._mitype, + shift); + } + else + { + v13 = MonsterMHit(v10, v12 - 1, v7, maxdam, missile[v8]._midist, missile[v8]._mitype, shift); + } + if ( v13 ) + { + if ( !(_BYTE)nodel ) + missile[v8]._mirange = 0; + missile[v8]._miHitFlag = 1; + } + goto LABEL_13; + } + if ( monster[v10]._mFlags & 0x10 ) + { + v18 = dMonster[0][my + 112 * mx]; + if ( v18 > 0 ) + { + if ( monster[v18-1]._mFlags & 0x20 ) /* fix */ + { + v19 = MonsterTrapHit( + v18 - 1, + mindama, + maxdam, + missile[v8]._midist, + missile[v8]._mitype, + shift); + if ( v19 ) + { + if ( !(_BYTE)nodel ) + missile[v8]._mirange = 0; + missile[v8]._miHitFlag = 1; + } + } + } + } + v11 = my + 112 * mx; + v20 = dPlayer[0][v11]; + if ( v20 > 0 ) + { + v17 = PlayerMHit( + v20 - 1, + missile[v8]._misource, + missile[v8]._midist, + mindama, + maxdam, + missile[v8]._mitype, + shift, + 0); + goto LABEL_35; + } + } +LABEL_39: + v24 = dObject[0][v11]; + if ( v24 ) + { + v25 = v24 <= 0 ? -1 - v24 : v24 - 1; + if ( !object[v25]._oMissFlag ) + { + if ( _LOBYTE(object[v25]._oBreak) == 1 ) + BreakObject(-1, v25); + if ( !(_BYTE)nodel ) + missile[v8]._mirange = 0; + missile[v8]._miHitFlag = 0; + } + } + if ( nMissileTable[dPiece[0][v11]] ) + { + if ( !(_BYTE)nodel ) + missile[v8]._mirange = 0; + missile[v8]._miHitFlag = 0; + } + if ( !missile[v8]._mirange ) + { + v26 = missiledata[missile[v8]._mitype].miSFX; + if ( v26 != -1 ) + PlaySfxLoc(v26, missile[v8]._mix, missile[v8]._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)&misflagstruct_unknown[125].field_4 ); + 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 CrawlNum[6]; // [esp+Ch] [ebp-28h] + int v20; // [esp+24h] [ebp-10h] + unsigned char *v21; // [esp+28h] [ebp-Ch] + int v22; // [esp+2Ch] [ebp-8h] + int v23; // [esp+30h] [ebp-4h] + + CrawlNum[0] = 0; + v9 = mi; + v23 = 0; + CrawlNum[1] = 3; + CrawlNum[2] = 12; + CrawlNum[3] = 45; + CrawlNum[4] = 94; + CrawlNum[5] = 159; + missile[mi]._miDelFlag = 1; + do + { + v10 = CrawlNum[v23]; + v11 = *(&CrawlTable.n_1 + v10); + v22 = *(&CrawlTable.n_1 + v10); + if ( v11 <= 0 ) + goto LABEL_13; + v12 = &CrawlTable.delta_1[0].y + v10; + v21 = &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]; + v20 = v17 * 4; + if ( !(dMonster[0][v17] | v18 | v16 | (unsigned char)nSolidTable[dPiece[0][v17]]) ) + break; + v12 = v21; +LABEL_10: + v12 += 2; + --v22; + v21 = v12; + if ( v22 <= 0 ) + goto LABEL_13; + } + missile[v9]._miDelFlag = 0; + missile[v9]._mix = v13; + missile[v9]._miy = v14; + missile[v9]._misx = v13; + missile[v9]._misy = v14; + v23 = 6; +LABEL_13: + ++v23; + } + while ( v23 < 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 == MT_SUCCUBUS ) + SetMissAnim(mi, MFILE_FLAREEXP); + if ( v10->mtype == MT_SNOWWICH ) + SetMissAnim(v9, MFILE_SCBSEXPB); + if ( v10->mtype == MT_HLSPWN ) + SetMissAnim(v9, MFILE_SCBSEXPD); + if ( v10->mtype == MT_SOLBRNR ) + 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) -------------------------------------------------------- +bool __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 CrawlNum[6]; // [esp+Ch] [ebp-28h] + int i; // [esp+24h] [ebp-10h] + unsigned char *v25; // [esp+28h] [ebp-Ch] + int v26; // [esp+2Ch] [ebp-8h] + int v27; // [esp+30h] [ebp-4h] + int x; // [esp+40h] [ebp+Ch] + + _LOBYTE(v9) = dx; + i = mi; + v10 = mi; + CrawlNum[0] = 0; + CrawlNum[1] = 3; + CrawlNum[2] = 12; + CrawlNum[3] = 45; + CrawlNum[4] = 94; + CrawlNum[5] = 159; + if ( currlevel ) + { + _LOBYTE(v11) = dx; + missile[v10]._miDelFlag = 1; + v26 = 0; + do + { + v12 = CrawlNum[v26]; + v13 = *(&CrawlTable.n_1 + v12); + v27 = *(&CrawlTable.n_1 + v12); + if ( v13 > 0 ) + { + v14 = &CrawlTable.delta_1[0].y + v12; + v25 = 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 ( !CheckIfTrig(v9, v11) ) + break; + } + } + v14 = v25 + 2; + --v27; + v25 += 2; + if ( v27 <= 0 ) + goto LABEL_14; + } + missile[v10]._miDelFlag = 0; + missile[v10]._mix = v9; + missile[v10]._miy = v11; + missile[v10]._misx = v9; + missile[v10]._misy = v11; + v26 = 6; + } +LABEL_14: + ++v26; + } + while ( v26 < 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; + v27 = 0; + missile[v10]._mirange = 100; + for ( missile[v10]._miVar1 = 100 - missile[v10]._miAnimLen; v27 < v17; ++v27 ) + { + v18 = missileactive[v27]; + 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 CrawlNum[6]; // [esp+8h] [ebp-38h] + unsigned int v29; // [esp+20h] [ebp-20h] + int v30; // [esp+24h] [ebp-1Ch] + int v31; // [esp+28h] [ebp-18h] + int x1; // [esp+2Ch] [ebp-14h] + int v33; // [esp+30h] [ebp-10h] + unsigned char *v34; // [esp+34h] [ebp-Ch] + int v35; // [esp+38h] [ebp-8h] + int v36; // [esp+3Ch] [ebp-4h] + + CrawlNum[0] = 0; + v9 = 21720 * id; + x1 = sx; + v10 = mi; + _LOBYTE(mi) = 62; + CrawlNum[1] = 3; + CrawlNum[2] = 12; + CrawlNum[3] = 45; + CrawlNum[4] = 94; + CrawlNum[5] = 159; + v33 = 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; + } + v36 = 0; + missile[v11]._miDelFlag = 1; + do + { + v14 = CrawlNum[v36]; + v15 = *(&CrawlTable.n_1 + v14); + v35 = *(&CrawlTable.n_1 + v14); + if ( v15 <= 0 ) + goto LABEL_18; + v16 = &CrawlTable.delta_1[0].y + v14; + v34 = v16; + while ( 1 ) + { + v17 = dx + (char)*(v16 - 1); + v18 = dy + (char)*v16; + v30 = v18 + 112 * (dx + (char)*(v16 - 1)); + v29 = 4 * v30; + v31 = dPiece[0][v30]; + if ( v17 <= 0 || v17 >= 112 || v18 <= 0 || v18 >= 112 ) + goto LABEL_14; + //_LOBYTE(v19) = LineClear(x1, sy, v17, v18); + if ( LineClear(x1, sy, v17, v18) ) + { + if ( !(dMonster[0][v29 / 4] | dObject[0][v30] | dMissile[0][v30] | (unsigned char)nSolidTable[v31] | (unsigned char)nMissileTable[v31]) ) + break; + } + v16 = v34; +LABEL_14: + v16 += 2; + --v35; + v34 = v16; + if ( v35 <= 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); + v36 = 6; +LABEL_17: + v9 = v33; +LABEL_18: + ++v36; + } + while ( v36 < 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 < MT_HORNED || v11 > MT_OBLORD ) + { + if ( v11 < MT_NSNAKE || (v12 = (int)v10->Anims[2].Frames, v11 > MT_GSNAKE) ) + 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 >= MT_NSNAKE && v15 <= MT_GSNAKE ) + 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 == MT_SUCCUBUS ) + SetMissAnim(code, MFILE_FLARE); + if ( v15->mtype == MT_SNOWWICH ) + SetMissAnim(code, MFILE_SCUBMISB); + if ( v15->mtype == MT_HLSPWN ) + SetMissAnim(code, MFILE_SCUBMISD); + if ( v15->mtype == MT_SOLBRNR ) + 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 CrawlNum[6]; // [esp+Ch] [ebp-20h] + int v25; // [esp+24h] [ebp-8h] + int v26; // [esp+28h] [ebp-4h] + + v9 = mi; + CrawlNum[0] = 0; + v26 = 0; + v10 = id; + v11 = id; + CrawlNum[1] = 3; + CrawlNum[2] = 12; + CrawlNum[3] = 45; + CrawlNum[4] = 94; + CrawlNum[5] = 159; + missile[mi]._misource = id; + do + { + v12 = CrawlNum[v26]; + v13 = *(&CrawlTable.n_1 + v12); + v25 = *(&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 != AI_DIABLO ) + { + v17 = monster[v16]._mmode; + if ( v17 != MM_FADEIN && v17 != MM_FADEOUT && v17 != MM_CHARGE ) + break; + } + } + v14 += 2; + if ( --v25 <= 0 ) + goto LABEL_19; + } + v25 = -99; + v26 = 6; + missile[v9]._miVar2 = v16; + v18 = (int *)&monster[v16]._mmode; + v19 = *v18; + *v18 = MM_STONE; + missile[v9]._miVar1 = v19; + } +LABEL_19: + ++v26; + } + while ( v26 < 6 ); + if ( v25 == -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(CURSOR_HEALOTHER); +} + +//----- (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(CURSOR_IDENTIFY); + } +} +// 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 CrawlNum[6]; // [esp+Ch] [ebp-30h] + int v17; // [esp+24h] [ebp-18h] + int v18; // [esp+28h] [ebp-14h] + unsigned char *v19; // [esp+2Ch] [ebp-10h] + int x1; // [esp+30h] [ebp-Ch] + int v21; // [esp+34h] [ebp-8h] + int v22; // [esp+38h] [ebp-4h] + + CrawlNum[0] = 0; + v9 = mi; + v22 = 0; + x1 = sx; + CrawlNum[1] = 3; + CrawlNum[2] = 12; + CrawlNum[3] = 45; + CrawlNum[4] = 94; + CrawlNum[5] = 159; + missile[mi]._miDelFlag = 1; + do + { + v10 = CrawlNum[v22]; + v11 = *(&CrawlTable.n_1 + v10); + v21 = *(&CrawlTable.n_1 + v10); + if ( v11 <= 0 ) + goto LABEL_16; + v12 = &CrawlTable.delta_1[0].y + v10; + v19 = v12; + while ( 1 ) + { + v13 = dx + (char)*(v12 - 1); + v14 = dy + (char)*v12; + if ( v13 <= 0 || v13 >= 112 || v14 <= 0 || v14 >= 112 ) + goto LABEL_13; + v18 = v14 + 112 * v13; + v17 = dPiece[0][v18]; + //_LOBYTE(v15) = LineClear(x1, sy, v13, v14); + if ( LineClear(x1, sy, v13, v14) ) + { + if ( (x1 != v13 || sy != v14) && !((unsigned char)nSolidTable[v17] | dObject[0][v18]) ) + break; + } + v12 = v19; +LABEL_13: + v12 += 2; + --v21; + v19 = v12; + if ( v21 <= 0 ) + goto LABEL_16; + } + missile[v9]._miDelFlag = 0; + missile[v9]._miVar1 = v13; + missile[v9]._miVar2 = v14; + missile[v9]._miVar5 = v13; + missile[v9]._miVar6 = v14; + v22 = 6; +LABEL_16: + ++v22; + } + while ( v22 < 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(CURSOR_REPAIR); + } +} +// 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(CURSOR_RECHARGE); + } +} +// 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(CURSOR_DISARM); +} + +//----- (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(CURSOR_RESURRECT); + 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(CURSOR_TELEKINESIS); +} + +//----- (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 ( LineClear(x1, sy, *(v10 - 1), *v10) ) + 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 ( LineClear(missile[i]._mix, missile[i]._miy, sx, sy) ) + { + v7 = dMonster[0][sy + 112 * v4]; + if ( v7 > 0 && (signed int)(monster[v7-1]._mhitpoints & 0xFFFFFFC0) > 0 && v7 - 1 > 3 ) /* fix monstactive */ + { + 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, MIS_FIREBOLT, 0, v9, missile[v3]._midam, v12); /* check mtype v13 */ + 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 CrawlNum[6]; // [esp+4h] [ebp-38h] + int arglist; // [esp+1Ch] [ebp-20h] + int mi; // [esp+20h] [ebp-1Ch] + unsigned int v16; // [esp+24h] [ebp-18h] + int v17; // [esp+28h] [ebp-14h] + int v18; // [esp+2Ch] [ebp-10h] + unsigned char *v19; // [esp+30h] [ebp-Ch] + int v20; // [esp+34h] [ebp-8h] + int v21; // [esp+38h] [ebp-4h] + + mi = i; + v1 = i; + v2 = missile[i]._misource; + arglist = v2; + v3 = v2; + v4 = monster[v3]._mx == 1; + CrawlNum[0] = 0; + CrawlNum[1] = 3; + CrawlNum[2] = 12; + CrawlNum[3] = 45; + CrawlNum[4] = 94; + CrawlNum[5] = 159; + if ( !v4 || monster[v3]._my ) + goto LABEL_17; + v21 = 0; + do + { + v5 = CrawlNum[v21]; + v6 = *(&CrawlTable.n_1 + v5); + v20 = *(&CrawlTable.n_1 + v5); + if ( v6 <= 0 ) + goto LABEL_16; + v7 = &CrawlTable.delta_1[0].y + v5; + v19 = 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; + v18 = v9 + 112 * v8; + v16 = 4 * v18; + v17 = dPiece[0][v18]; + if ( LineClear(v11, v10, v8, v9) ) + { + if ( !(dMonster[0][v16 / 4] | (unsigned char)nSolidTable[v17] | dObject[0][v18]) ) + break; + } + v7 = v19; +LABEL_13: + v7 += 2; + --v20; + v19 = v7; + if ( v20 <= 0 ) + goto LABEL_16; + } + v21 = 6; + SpawnGolum(arglist, v8, v9, mi); +LABEL_16: + ++v21; + } + while ( v21 < 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 + 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); + } + 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); + } + 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); + 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 + 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); + 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 + 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); + } + 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 + 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); + 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 + + 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); + 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 + + v1 = i; + v2 = i; + v3 = missile[i]._miy; + v4 = missile[i]._midam; + --missile[v2]._mirange; + v5 = missile[i]._mirange; + CheckMissileCol(i, v4, v4, 1, missile[i]._mix, v3, 0); + 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 + int ExpLight[14]; // [esp+8h] [ebp-3Ch] + int ia; // [esp+40h] [ebp-4h] + + v1 = i; + ExpLight[3] = 5; + ExpLight[4] = 5; + ExpLight[11] = 12; + ExpLight[12] = 12; + --missile[v1]._mirange; + ExpLight[0] = 2; + ExpLight[1] = 3; + ExpLight[2] = 4; + ExpLight[5] = 6; + ExpLight[6] = 7; + ExpLight[7] = 8; + ExpLight[8] = 9; + ExpLight[9] = 10; + ExpLight[10] = 11; + ia = i; + ExpLight[13] = 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, 1, missile[v1]._mix, missile[v1]._miy, 1); + 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, ExpLight[0]); + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, ExpLight[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 + 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] + + 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); + 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); + if ( !CheckBlock(fx, fy, tx, ty + 1) ) + CheckMissileCol(ia, v5, v5, 0, tx, ty + 1, 1); + if ( !CheckBlock(fx, fy, tx, ty - 1) ) + CheckMissileCol(ia, v5, v5, 0, tx, ty - 1, 1); + if ( !CheckBlock(fx, fy, tx + 1, ty) ) + CheckMissileCol(ia, v5, v5, 0, tx + 1, ty, 1); + if ( !CheckBlock(fx, fy, tx + 1, ty - 1) ) + CheckMissileCol(ia, v5, v5, 0, tx + 1, ty - 1, 1); /* check x/y */ + if ( !CheckBlock(fx, fy, tx + 1, ty + 1) ) + CheckMissileCol(ia, v5, v5, 0, tx + 1, ty + 1, 1); + if ( !CheckBlock(fx, fy, tx - 1, ty) ) + CheckMissileCol(ia, v5, v5, 0, tx - 1, ty, 1); + if ( !CheckBlock(fx, fy, tx - 1, ty + 1) ) + CheckMissileCol(ia, v5, v5, 0, tx - 1, ty + 1, 1); + if ( !CheckBlock(fx, fy, ty - 2, ty - 1) ) + CheckMissileCol(ia, v5, v5, 0, 0, ty - 1, 1); + v13 = 112 * tx + ty; + if ( !TransList[dung_map[0][v13]] /* check */ + || missile[v1]._mixvel < 0 + && (TransList[dung_map[0][v13 + 1]] && nSolidTable[dPiece[0][v13 + 1]] + || 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[tx + 1][ty]] && nSolidTable[dPiece[1][v13]] + || TransList[dung_map[tx - 1][ty]] && 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[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 >= MT_STORM && (unsigned char)v9 <= MT_MAEL ) + { + _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 + + 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, 1, v3, missile[v2]._miy, 0); + 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 ExpLight[17]; // [esp+8h] [ebp-4Ch] + int ia; // [esp+4Ch] [ebp-8h] + int arglist; // [esp+50h] [ebp-4h] + + v1 = i; + ExpLight[14] = 15; + ExpLight[15] = 15; + ExpLight[16] = 15; + v2 = missile[i]._mirange; + ia = i; + ExpLight[0] = 1; + ExpLight[1] = 2; + ExpLight[2] = 3; + ExpLight[3] = 4; + ExpLight[4] = 5; + ExpLight[5] = 6; + ExpLight[6] = 7; + ExpLight[7] = 8; + ExpLight[8] = 9; + ExpLight[9] = 10; + ExpLight[10] = 11; + ExpLight[11] = 12; + ExpLight[12] = 13; + ExpLight[13] = 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, ExpLight[missile[v1]._miVar2]); + ++missile[v1]._miVar2; + } + 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(arglist); + if ( arglist == myplr ) + { + NetSendCmdParam1(1u, CMD_WARP, missile[v1]._misource); + *(v3 - 13) = 10; + } + } + } + ++arglist; + v3 += 5430; + } + while ( (signed int)v3 < (signed int)&plr[4].plrlevel ); + 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 + + 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, 1, v4 - 1, missile[v2]._miy, 1); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1, missile[v2]._mix, missile[v2]._miy, 1); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1, missile[v2]._mix + 1, missile[v2]._miy, 1); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1, missile[v2]._mix - 1, missile[v2]._miy + 1, 1); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1, missile[v2]._mix, missile[v2]._miy + 1, 1); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1, missile[v2]._mix + 1, missile[v2]._miy + 1, 1); + 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 + + 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, 1, missile[v2]._mix - 1, v4 - 1, 1); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1, missile[v2]._mix, missile[v2]._miy - 1, 1); + CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1, missile[v2]._mix + 1, missile[v2]._miy - 1, 1); + 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 ) + 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 + int ExpLight[14]; // [esp+Ch] [ebp-3Ch] + int ia; // [esp+44h] [ebp-4h] + + v1 = i; + ExpLight[3] = 5; + ExpLight[4] = 5; + missile[v1]._miyoff += 32; + ExpLight[11] = 12; + ExpLight[12] = 12; + --missile[v1]._mix; + --missile[v1]._miy; + ExpLight[0] = 2; + ExpLight[1] = 3; + ExpLight[2] = 4; + ExpLight[5] = 6; + ExpLight[6] = 7; + ExpLight[7] = 8; + ExpLight[8] = 9; + ExpLight[9] = 10; + ExpLight[10] = 11; + ia = i; + ExpLight[13] = 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); + 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, ExpLight[0]); + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, ExpLight[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)&vCrawlTable[23][1] ); + } + 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 CrawlNum[19]; // [esp+Ch] [ebp-68h] + int v2; // [esp+58h] [ebp-1Ch] + int v18; // [esp+5Ch] [ebp-18h] + unsigned char *v19; // [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] + + CrawlNum[0] = 0; + v1 = i; + CrawlNum[1] = 3; + ST1C_4_1 = missile[i]._miVar2; + v3 = missile[i]._mix; + v4 = missile[i]._miy; + v5 = missile[i]._misource; + v6 = missile[i]._miVar1; + 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; + 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 = CrawlNum[j]; + v10 = *(&CrawlTable.n_1 + v9); + if ( v10 > 0 ) + { + v11 = &CrawlTable.delta_1[0].y + v9; + v18 = v10; + v19 = 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 = v19; + } + v11 += 2; + v15 = v18-- == 1; + v19 = 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 + int ExpLight[10]; // [esp+4h] [ebp-2Ch] + int ia; // [esp+2Ch] [ebp-4h] + + ia = i; + v1 = i; + --missile[v1]._mirange; + ExpLight[0] = 9; + ExpLight[1] = 10; + ExpLight[5] = 10; + v2 = missile[i]._mitype; + ExpLight[2] = 11; + ExpLight[4] = 11; + v3 = missile[v1]._misource; + v4 = v2; + v5 = missile[v1]._miVar2 == 1; + ExpLight[3] = 12; + ExpLight[6] = 8; + ExpLight[7] = 6; + ExpLight[8] = 4; + ExpLight[9] = 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); + v8 = missile[v1]._miVar1; + if ( v8 ) + { + if ( missile[v1]._mirange ) + ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, ExpLight[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 ExpLight[10]; // [esp+8h] [ebp-28h] + + v1 = i; + v2 = i; + ExpLight[0] = 9; + v3 = missile[i]._mirange == 1; + --missile[v2]._mirange; + ExpLight[1] = 10; + ExpLight[3] = 12; + ExpLight[2] = 11; + ExpLight[4] = 11; + ExpLight[5] = 10; + ExpLight[6] = 8; + ExpLight[7] = 6; + ExpLight[8] = 4; + ExpLight[9] = 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, ExpLight[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 + + 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); + 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 == AI_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 == AI_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 ( !PosOkMissile(x, y) || 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)&vCrawlTable[23][7] ); + 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 + + 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, 1, v6, v3, 0); + 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 + int bpath[16]; // [esp+Ch] [ebp-44h] + int ia; // [esp+4Ch] [ebp-4h] + + ia = i; + v1 = i; + --missile[v1]._mirange; + v2 = _LOBYTE(missile[i]._miAnimType) == 3; + bpath[0] = -1; + bpath[1] = 0; + bpath[2] = 1; + bpath[3] = -1; + bpath[4] = 0; + bpath[5] = 1; + bpath[6] = -1; + bpath[7] = -1; + bpath[8] = 0; + bpath[9] = 0; + bpath[10] = 1; + bpath[11] = 1; + bpath[12] = 0; + bpath[13] = 1; + bpath[14] = -1; + bpath[15] = 0; + if ( !v2 ) + { + v3 = missile[v1]._miVar3; + if ( v3 ) + { + missile[v1]._miVar3 = v3 - 1; + } + else + { + v4 = missile[v1]._mirnd; + v5 = (missile[v1]._miVar2 + bpath[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); + 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 + + 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); + 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 + 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, 1, v4, y, 1); + my = y + 1; + if ( !CheckBlock(fx, fy, v4, y + 1) ) + CheckMissileCol(ia, v2, v2, 1, v4, my, 1); + tya = y - 1; + if ( !CheckBlock(fx, fy, v4, y - 1) ) + CheckMissileCol(ia, v2, v2, 1, v4, tya, 1); + if ( !CheckBlock(fx, fy, v4 + 1, y) ) + CheckMissileCol(ia, v2, v2, 1, v4 + 1, y, 1); /* check x/y */ + if ( !CheckBlock(fx, fy, v4 + 1, tya) ) + CheckMissileCol(ia, v2, v2, 1, v4 + 1, tya, 1); + if ( !CheckBlock(fx, fy, v4 + 1, my) ) + CheckMissileCol(ia, v2, v2, 1, v4 + 1, my, 1); + v5 = v4 - 1; + if ( !CheckBlock(fx, fy, v5, y) ) + CheckMissileCol(ia, v2, v2, 1, v5, y, 1); + if ( !CheckBlock(fx, fy, v5, my) ) + CheckMissileCol(ia, v2, v2, 1, v5, my, 1); + if ( !CheckBlock(fx, fy, v5, tya) ) + CheckMissileCol(ia, v2, v2, 1, v5, tya, 1); + 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); + 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 + 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); + 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 ExpLight[17]; // [esp+8h] [ebp-48h] + int ia; // [esp+4Ch] [ebp-4h] + + v1 = i; + ExpLight[14] = 15; + ExpLight[15] = 15; + ExpLight[16] = 15; + v2 = missile[i]._mirange; + ia = i; + ExpLight[0] = 1; + ExpLight[1] = 2; + ExpLight[2] = 3; + ExpLight[3] = 4; + ExpLight[4] = 5; + ExpLight[5] = 6; + ExpLight[6] = 7; + ExpLight[7] = 8; + ExpLight[8] = 9; + ExpLight[9] = 10; + ExpLight[10] = 11; + ExpLight[11] = 12; + ExpLight[12] = 13; + ExpLight[13] = 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, ExpLight[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 == MIS_MANASHIELD ) + { + 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 < MT_HORNED || v6 > MT_OBLORD ) + { + if ( v6 < MT_NSNAKE || v6 > MT_GSNAKE ) + 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 mi) +{ + dFlags[missile[mi]._mix][missile[mi]._miy] &= 0xFE; + dMissile[missile[mi]._mix][missile[mi]._miy] = 0; +} diff --git a/Source/missiles.h b/Source/missiles.h new file mode 100644 index 0000000..4abef0b --- /dev/null +++ b/Source/missiles.h @@ -0,0 +1,161 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//missile +extern int missileactive[125]; +extern int missileavail[125]; +extern MissileStruct missile[125]; +extern int nummissiles; // idb +extern int ManashieldFlag; +extern unk_missile_struct misflagstruct_unknown[125]; +extern int MissilePreFlag; // weak +// int END_unkmis_126; // weak + +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); +bool __fastcall MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, int shift); +bool __fastcall MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, int shift); +bool __fastcall PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, int shift, int earflag); +bool __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, bool shift, int mx, int my, int nodel); +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); +bool __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 mi); + +/* rdata */ + +extern MissileData missiledata[68]; +extern MisFileData misfiledata[47]; +extern int XDirAdd[8]; +extern int YDirAdd[8]; diff --git a/Source/monster.cpp b/Source/monster.cpp new file mode 100644 index 0000000..fa3e058 --- /dev/null +++ b/Source/monster.cpp @@ -0,0 +1,9375 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +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 monster_inf = 0x7F800000; // weak +char plr2monst[9] = { 0, 5, 3, 7, 1, 4, 6, 0, 2 }; +unsigned char counsmiss[4] = { MIS_FIREBOLT, MIS_CBOLT, MIS_LIGHTCTRL, MIS_FIREBALL }; + +/* rdata */ + +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", 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 } +}; +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] = +{ + { MT_NGOATMC, "Gharbad the Weak", "BSDB", 4, 120, AI_GARBUD, 3, 8, 16, 96, 0, 0, 0, QUEST_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, QUEST_ZHAR1 }, + { MT_BFALLSP, "Snotspill", "BNG", 4, 220, AI_SNOTSPIL, 3, 10, 18, 4, 0, 0, 0, QUEST_BANNER10 }, + { MT_ADVOCATE, "Arch-Bishop Lazarus", "GENERAL", 0, 600, AI_LAZURUS, 3, 30, 50, 78, 0, 0, 0, QUEST_VILE13 }, + { MT_HLSPWN, "Red Vex", "REDV", 0, 400, AI_LAZHELP, 3, 30, 50, 74, 0, 0, 0, QUEST_VILE13 }, + { MT_HLSPWN, "BlackJade", "BLKJD", 0, 400, AI_LAZHELP, 3, 30, 50, 76, 0, 0, 0, QUEST_VILE13 }, + { MT_RBLACK, "Lachdanan", "BHKA", 14, 500, AI_LACHDAN, 3, 0, 0, 0, 0, 0, 0, QUEST_VEIL9 }, + { MT_BTBLACK, "Warlord of Blood", "GENERAL", 13, 850, AI_WARLORD, 3, 35, 50, 120, 0, 0, 0, QUEST_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 } +}; +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 (__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 +}; + +//----- (00430FE4) -------------------------------------------------------- +struct monster_cpp_init +{ + monster_cpp_init() + { + monster_cpp_init_value = monster_inf; + } +} _monster_cpp_init; +// 47F130: using guessed type int monster_inf; +// 64CCE4: using guessed type int monster_cpp_init_value; + +//----- (00430FEF) -------------------------------------------------------- +void __fastcall InitMonsterTRN(int monst, int special) +{ + signed int i; // ecx + char *v5; // eax + int v6; // ebp + unsigned char v7; // al + int v8; // edi + char **v9; // ebx + signed int v10; // [esp+8h] [ebp-8h] + int v11; // [esp+Ch] [ebp-4h] + + i = 256; + v5 = (char *)Monsters[monst].trans_file; + do + { + if ( *v5 == -1 ) + *v5 = 0; + ++v5; + --i; + } + while ( i ); + v6 = 0; + v11 = (special != 0) + 5; + if ( v11 > 0 ) + { + do + { + if ( v6 != 1 || (v7 = Monsters[monst].mtype, v7 < MT_COUNSLR) || v7 > MT_ADVOCATE ) + { + v10 = 8; + v8 = 44 * v6 + monst * 328; + v9 = (char **)((char *)&Monsters[0].Anims[0].Frames[1] + v8); + do + { + Cl2ApplyTrans( + *v9, + (char *)Monsters[monst].trans_file, + *(int *)((char *)&Monsters[0].Anims[0].Rate + v8)); + ++v9; + --v10; + } + while ( v10 ); + } + ++v6; + } + while ( v6 < v11 ); + } +} + +//----- (0043107B) -------------------------------------------------------- +void __cdecl InitLevelMonsters() +{ + int i; // eax + + nummtypes = 0; + monstimgtot = 0; + MissileFileFlag = 0; + + for(i = 0; i < 16; i++) + Monsters[i].mPlaceFlags = 0; + + ClrAllMonsters(); + nummonsters = 0; + totalmonsters = 200; + + for(i = 0; i < 200; i++) + monstactive[i] = i; + + 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) +{ + bool done; // eax + int i; // esi + + done = 0; + + for(i = 0; i < nummtypes; i++) + { + if ( done ) + break; + + done = type == Monsters[i].mtype; + } + + i--; + + if ( !done ) + { + i = nummtypes++; + Monsters[i].mtype = type; + monstimgtot += monsterdata[type].mType; + InitMonsterGFX(i); + InitMonsterSND(i); + } + Monsters[i].mPlaceFlags |= placeflag; + return i; +} +// 659AE8: using guessed type int monstimgtot; + +//----- (0043114F) -------------------------------------------------------- +void __cdecl GetLevelMTypes() /* note-decompile this function again and check */ +{ + //int v0; // eax + //int v1; // eax + //int v2; // eax + //int v3; // eax + //int v4; // eax + //int v5; // eax + char *v6; // esi + int v7; // edi + int v10; // eax + int v11; // esi + int v12; // edi + 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 typelist[89]; // [esp+Ch] [ebp-324h] + int skeltypes[111]; // [esp+170h] [ebp-1C0h] + int max; // [esp+32Ch] [ebp-4h] + + AddMonsterType(MT_GOLEM, 2); + if ( currlevel == 16 ) + { + AddMonsterType(MT_ADVOCATE, 1); + AddMonsterType(MT_RBLACK, 1); + AddMonsterType(MT_DIABLO, 2); + } + else if ( setlevel ) + { + if ( setlvlnum == SL_SKELKING ) + AddMonsterType(MT_SKING, 4); + } + else + { + if ( QuestStatus(6) ) + AddMonsterType(MT_CLEAVER, 2); + if ( QuestStatus(2) ) + AddMonsterType((char)UniqMonst[0].mtype, 4); + if ( QuestStatus(3) ) + AddMonsterType((char)UniqMonst[2].mtype, 4); + if ( QuestStatus(7) ) + AddMonsterType((char)UniqMonst[3].mtype, 4); + if ( QuestStatus(4) ) + AddMonsterType((char)UniqMonst[7].mtype, 4); + if ( QuestStatus(11) ) + AddMonsterType((char)UniqMonst[8].mtype, 4); + + if ( gbMaxPlayers != 1 && currlevel == quests[12]._qlevel ) + { + AddMonsterType(MT_SKING, 4); + max = 0; + v6 = &monsterdata[8].mMaxDLvl; + v7 = 8; + do + { + if ( IsSkel(v7) ) + { + if ( currlevel >= 15 * (char)*(v6 - 1) / 30 + 1 + && currlevel <= 15 * (char)*v6 / 30 + 1 + && MonstAvailTbl[v7] & 3 ) + { + skeltypes[max++] = v7; + } + } + v6 += 128; + ++v7; + } + while ( (signed int)v6 <= (signed int)&monsterdata[27].mMaxDLvl ); + v10 = random(88, max); + AddMonsterType(skeltypes[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 ) + typelist[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 = &typelist[v15]; + if ( monsterdata[LOBYTE(*v18)].mType <= v17 ) + { + ++v15; + } + else + { + v19 = typelist[v12-- - 1]; //v19 = *(&v22 + v12--); /* fix and check */ + *v18 = v19; + } + } + while ( v15 < v12 ); + v16 = v12 == 0; + } + if ( !v16 ) + { + v20 = &typelist[random(88, v12)]; + AddMonsterType(LOBYTE(*v20), 1); + v21 = typelist[v12-- - 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 != MT_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; + InitMonsterTRN(v18, v17); + v19 = *v15; + *v15 = 0; + mem_free_dbg(v19); + } + if ( v31 >= MT_NMAGMA && v31 <= MT_WMAGMA && !(MissileFileFlag & 1) ) + { + MissileFileFlag |= 1u; + LoadMissileGFX(MFILE_MAGBALL); + } + if ( v31 >= MT_STORM && v31 <= MT_MAEL && !(MissileFileFlag & 2) ) + { + MissileFileFlag |= 2u; + LoadMissileGFX(MFILE_THINLGHT); + } + if ( v31 == MT_SUCCUBUS ) + { + if ( MissileFileFlag & 4 ) + return; + MissileFileFlag |= 4u; + LoadMissileGFX(MFILE_FLARE); + LoadMissileGFX(MFILE_FLAREEXP); + } + if ( v31 == MT_SNOWWICH ) + { + if ( MissileFileFlag & 0x20 ) + return; + MissileFileFlag |= 0x20u; + LoadMissileGFX(MFILE_SCUBMISB); + LoadMissileGFX(MFILE_SCBSEXPB); + } + if ( v31 == MT_HLSPWN ) + { + if ( MissileFileFlag & 0x40 ) + return; + MissileFileFlag |= 0x40u; + LoadMissileGFX(MFILE_SCUBMISD); + LoadMissileGFX(MFILE_SCBSEXPD); + } + if ( v31 == MT_SOLBRNR ) + { + if ( (MissileFileFlag & 0x80u) != 0 ) + return; + MissileFileFlag |= 0x80; + LoadMissileGFX(MFILE_SCUBMISC); + LoadMissileGFX(MFILE_SCBSEXPC); + } + if ( v31 >= MT_INCIN && v31 <= MT_HELLBURN && !(MissileFileFlag & 8) ) + { + MissileFileFlag |= 8u; + LoadMissileGFX(MFILE_KRULL); + } + if ( v31 >= MT_NACID && v31 <= MT_XACID && !(MissileFileFlag & 0x10) ) + { + MissileFileFlag |= 0x10u; + LoadMissileGFX(MFILE_ACIDBF); + LoadMissileGFX(MFILE_ACIDSPLA); + LoadMissileGFX(MFILE_ACIDPUD); + } + if ( v31 == MT_DIABLO ) + { + LoadMissileGFX(MFILE_FIREPLAR); + } +} +// 64CCE0: using guessed type int MissileFileFlag; + +//----- (004316AE) -------------------------------------------------------- +void __fastcall ClearMVars(int i) +{ + 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; +} + +//----- (004316E7) -------------------------------------------------------- +void __fastcall InitMonster(int i, int rd, int mtype, int x, int y) +{ + int v5; // ebx + int v6; // esi + CMonster *monst; // edi + MonsterData *v8; // eax + char *v9; // ecx + int v10; // eax + int v11; // eax + //int v12; // ecx + int v13; // eax + int v16; // eax + MonsterData *v17; // eax + int v18; // eax + MonsterData *v19; // eax + short v20; // cx + int v21; // edx + int v22; // edx + int v24; // ecx + int v25; // ecx + char v26; // dl + int v27; // ecx + char v28; // dl + + v5 = rd; + v6 = i; + monster[v6]._mmode = MM_STAND; + monst = &Monsters[mtype]; + monster[v6]._mx = x; + monster[v6]._mfutx = x; + monster[v6]._moldx = x; + v8 = monst->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 = monst; + monster[v6].MData = v8; + monster[v6]._mAFNum = monst->Anims[0].Frames[rd + 1]; + v10 = monst->Anims[0].Delay; + monster[v6]._mAnimDelay = v10; + monster[v6]._mAnimCnt = random(88, v10 - 1); + v11 = monst->Anims[0].Rate; + monster[v6]._mAnimLen = v11; + v13 = random(88, v11 - 1); + monster[v6]._mAnimFrame = v13 + 1; + if ( monst->mtype == MT_DIABLO ) + v16 = random(88, 1) + 1666; + else + v16 = monst->mMinHP + random(88, monst->mMaxHP - monst->mMinHP + 1); + monster[v6]._mmaxhp = v16 << 6; + if ( gbMaxPlayers == 1 ) + { + monster[v6]._mmaxhp >>= 1; + if ( monster[v6]._mmaxhp < 64 ) + monster[v6]._mmaxhp = 64; + } + monster[v6]._mhitpoints = monster[v6]._mmaxhp; + v17 = monst->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 = monst->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; + monster[v6]._mFlags = v21; + if ( monster[v6]._mAi == AI_GARG ) + { + v22 = monst->Anims[5].Frames[v5 + 1]; + monster[v6]._mFlags |= 4u; + monster[v6]._mAFNum = v22; + monster[v6]._mAnimFrame = 1; + monster[v6]._mmode = MM_SATTACK; + } + 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 + 2); + monster[v6].mMaxDamage = 2 * (monster[v6].mMaxDamage + 2); + monster[v6].mMinDamage2 = 2 * (monster[v6].mMinDamage2 + 2); + _LOBYTE(v25) = 2 * (monster[v6].mMaxDamage2 + 2); + monster[v6].mArmorClass += 50; + monster[v6].mMaxDamage2 = v25; + } + if ( gnDifficulty == 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 i; // edi + int v6; // eax + + for(i = 0; i < 200; 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]._mAFNum = 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; + v6 = random(89, gbActivePlayers); + monster[i]._menemy = v6; + monster[i]._menemyx = plr[v6]._px; + monster[i]._menemyy = plr[v6]._py; + } +} +// 67862C: using guessed type char gbActivePlayers; + +//----- (00431B10) -------------------------------------------------------- +bool __fastcall MonstPlace(int xp, int yp) +{ + if ( xp < 0 || xp >= 112 + || yp < 0 || yp >= 112 + || dMonster[xp][yp] + || dPlayer[xp][yp] + || dFlags[xp][yp] & 2 + || dFlags[xp][yp] & 8 ) + { + return 0; + } + else + { + return SolidLoc(xp, yp) == 0; + } +} + +//----- (00431B5D) -------------------------------------------------------- +void __fastcall PlaceMonster(int i, int mtype, int x, int y) +{ + dMonster[x][y] = i + 1; + InitMonster(i, random(90, 8), mtype, 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 filestr[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 == AI_LAZHELP ) + v3->mtalkmsg = 0; + if ( v29 != AI_LAZURUS || 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(filestr, "Monsters\\Monsters\\%s.TRN", *(_DWORD *)(v17 + 8)); + LoadFileWithMem(filestr, &pLightTbl[256 * (uniquetrans + 19)]); + 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 != AI_GARG ) + { + 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 skeltype; // esi + CMonster *v2; // edi + unsigned char *setp; // esi + + if ( setlevel ) + { + if ( setlvlnum == SL_SKELKING ) + PlaceUniqueMonst(1, 0, 0); + } + else + { + if ( QuestStatus(6) ) + PlaceUniqueMonst(9, 0, 0); + if ( currlevel == quests[12]._qlevel && gbMaxPlayers != 1 ) + { + skeltype = 0; + if ( nummtypes > 0 ) + { + v2 = Monsters; + do + { + if ( IsSkel((unsigned char)v2->mtype) ) + break; + ++skeltype; + ++v2; + } + while ( skeltype < nummtypes ); + } + PlaceUniqueMonst(1, skeltype, 30); + } + if ( QuestStatus(7) ) + { + setp = LoadFileInMem("Levels\\L1Data\\Banner1.DUN", 0); + SetMapMonsters((char *)setp, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(setp); + } + if ( QuestStatus(9) ) + { + setp = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0); + SetMapMonsters((char *)setp, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(setp); + } + if ( QuestStatus(8) ) + { + setp = LoadFileInMem("Levels\\L2Data\\Blind2.DUN", 0); + SetMapMonsters((char *)setp, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(setp); + } + if ( QuestStatus(10) ) + { + setp = LoadFileInMem("Levels\\L3Data\\Anvil.DUN", 0); + SetMapMonsters((char *)setp, 2 * setpc_x + 2, 2 * setpc_y + 2); + mem_free_dbg(setp); + } + if ( QuestStatus(11) ) + { + setp = LoadFileInMem("Levels\\L4Data\\Warlord.DUN", 0); + SetMapMonsters((char *)setp, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(setp); + AddMonsterType((char)UniqMonst[8].mtype, 1); + } + if ( QuestStatus(4) ) + AddMonsterType((char)UniqMonst[7].mtype, 1); + if ( QuestStatus(3) && 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); + setp = LoadFileInMem("Levels\\L4Data\\Vile1.DUN", 0); + SetMapMonsters((char *)setp, 2 * setpc_x, 2 * setpc_y); + mem_free_dbg(setp); + } + } +} +// 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 = 0, v14 >= 4) || (v16 = abs(v9 - v28), v13 = 0, v16 >= 4)) ) /* v15/v17 */ + { + ++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 != AI_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 *lpSetPiece; // esi + + lpSetPiece = LoadFileInMem("Levels\\L4Data\\diab1.DUN", 0); + SetMapMonsters((char *)lpSetPiece, 2 * diabquad1x, 2 * diabquad1y); + mem_free_dbg(lpSetPiece); + lpSetPiece = LoadFileInMem("Levels\\L4Data\\diab2a.DUN", 0); + SetMapMonsters((char *)lpSetPiece, 2 * diabquad2x, 2 * diabquad2y); + mem_free_dbg(lpSetPiece); + lpSetPiece = LoadFileInMem("Levels\\L4Data\\diab3a.DUN", 0); + SetMapMonsters((char *)lpSetPiece, 2 * diabquad3x, 2 * diabquad3y); + mem_free_dbg(lpSetPiece); + lpSetPiece = LoadFileInMem("Levels\\L4Data\\diab4a.DUN", 0); + SetMapMonsters((char *)lpSetPiece, 2 * diabquad4x, 2 * diabquad4y); + mem_free_dbg(lpSetPiece); +} +// 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 + unsigned 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 scattertypes[111]; // [esp+18h] [ebp-1BCh] + + v0 = 0; + max = 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(); + } + 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++; + scattertypes[v13] = v11; + } + ++v11; + v12 += 328; + } + while ( v11 < v9 ); + } + if ( v8 < v10 ) + { + while ( 1 ) + { + _LOBYTE(v8) = 95; + v15 = scattertypes[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(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((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(MonstConvTbl[*(unsigned short *)v8-1], 2); /* fix */ + 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 i; // esi + + if ( nummonsters >= 200 ) + return -1; + i = monstactive[nummonsters++]; + if ( InMap ) + dMonster[x][y] = i + 1; + InitMonster(i, dir, mtype, x, y); + return i; +} + +//----- (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) -------------------------------------------------------- +bool __fastcall M_Ranged(int i) +{ + char v1; // cl + + v1 = monster[i]._mAi; + return v1 == AI_SKELBOW || v1 == AI_GOATBOW || v1 == AI_SUCC || v1 == AI_LAZHELP; +} + +//----- (00432B26) -------------------------------------------------------- +bool __fastcall M_Talker(int i) +{ + char v1; // cl + + v1 = monster[i]._mAi; + return v1 == AI_LAZURUS + || v1 == AI_WARLORD + || v1 == AI_GARBUD + || v1 == AI_ZHAR + || v1 == AI_SNOTSPIL + || v1 == AI_LACHDAN + || v1 == AI_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[4].plrlevel ); + } + 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(monster[v10]._mx - v1->_mx) >= 2 || abs(monster[v10]._my - v1->_my) >= 2) && !M_Ranged(v18) /* v11 */ + || !(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 != MT_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 != AI_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 ( DirOK(i, v3) ) + { + 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 >= MT_SNEAK && v6 <= MT_ILLWEAV || 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 == MT_BLINK ) + { + M_Teleport(v4); + } + else if ( v8 >= MT_NSCAV && v8 <= MT_YSCAV ) + { + _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 >= MT_SNEAK && v6->mtype <= MT_ILLWEAV || 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 >= MT_NSCAV && v7 <= MT_YSCAV ) + { + _LOBYTE(monster[v5]._mgoal) = 1; + } + if ( monster[v5]._mmode != MM_STONE ) + { + v8 = monster[v5].MType; + if ( v8->mtype != MT_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 ( QuestStatus(2) && 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 == MT_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 >= MT_NACID && v13 <= MT_XACID ) + 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 == MT_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 == MT_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 >= MT_NACID && v11 <= MT_XACID ) + 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 == MT_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 + bool 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 != MT_ILLWEAV || _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 ( !CheckMonsterHit(*(int *)arglist, &ret) && 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); +#ifdef _DEBUG + if ( debug_mode_dollar_sign || debug_mode_key_inverted_v ) + v36 = 1000; +#endif + 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 == MT_YZOMBIE && 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 == MT_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 != AI_SNAKE ) + PlayEffect(v1, 0); + } + v4 = monster[v2].MType->mtype; + if ( v4 >= MT_NMAGMA && v4 <= MT_WMAGMA && 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 >= MT_STORM && v5 <= MT_MAEL && 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 == AI_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 == AI_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 < MT_INCIN || v4 > MT_HELLBURN ) + 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; // edi + int v2; // esi + //int v3; // eax + int v4; // eax + int v5; // edx + int v6; // ecx + char v7; // bl + int v8; // eax + char *v9; // eax + + v1 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("M_DoTalk: Invalid monster %d", i); + v2 = v1; + M_StartStand(v1, monster[v1]._mdir); + _LOBYTE(monster[v1]._mgoal) = 7; + //_LOBYTE(v3) = effect_is_playing(alltext[monster[v1].mtalkmsg].sfxnr); + if ( !effect_is_playing(alltext[monster[v1].mtalkmsg].sfxnr) ) + { + InitQTextMsg(monster[v2].mtalkmsg); + if ( monster[v2].mName == UniqMonst[0].mName ) + { + v4 = monster[v2].mtalkmsg; + if ( v4 == QUEST_GARBUD1 ) + quests[2]._qactive = 2; + quests[2]._qlog = 1; + if ( v4 == QUEST_GARBUD2 && !(monster[v2]._mFlags & 0x40) ) + { + SpawnItem(v1, monster[v2]._mx + 1, monster[v2]._my + 1, 1u); + monster[v2]._mFlags |= 0x40u; + } + } + if ( monster[v2].mName == UniqMonst[2].mName + && monster[v2].mtalkmsg == QUEST_ZHAR1 + && !(monster[v2]._mFlags & 0x40) ) + { + v5 = monster[v2]._my + 1; + v6 = monster[v2]._mx + 1; + quests[3]._qactive = 2; + quests[3]._qlog = 1; + CreateTypeItem(v6, v5, 0, 0, 24, 1, 0); + monster[v2]._mFlags |= 0x40u; + } + if ( monster[v2].mName == UniqMonst[3].mName ) + { + if ( monster[v2].mtalkmsg == QUEST_BANNER10 && !(monster[v2]._mFlags & 0x40) ) + { + ObjChangeMap(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 2, (setpc_h >> 1) + setpc_y - 2); + v7 = TransVal; + TransVal = 9; + DRLG_MRectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 4, setpc_y + (setpc_h >> 1)); + TransVal = v7; + quests[7]._qvar1 = 2; + if ( quests[7]._qactive == 1 ) + quests[7]._qactive = 2; + monster[v2]._mFlags |= 0x40u; + } + if ( quests[7]._qvar1 < 2u ) + { + sprintf(tempstr, "SS Talk = %i, Flags = %i", monster[v2].mtalkmsg, monster[v2]._mFlags); + TermMsg(tempstr); + } + } + if ( monster[v2].mName == UniqMonst[7].mName ) + { + v8 = monster[v2].mtalkmsg; + if ( v8 == QUEST_VEIL9 ) + { + quests[4]._qactive = 2; + quests[4]._qlog = 1; + } + if ( v8 == QUEST_VEIL11 && !(monster[v2]._mFlags & 0x40) ) + { + SpawnUnique(UITEM_STEELVEIL, monster[v2]._mx + 1, monster[v2]._my + 1); + monster[v2]._mFlags |= 0x40u; + } + } + v9 = monster[v2].mName; + if ( v9 == UniqMonst[8].mName ) + quests[11]._qvar1 = 2; + if ( v9 == UniqMonst[4].mName && gbMaxPlayers != 1 ) + { + _LOBYTE(monster[v2]._msquelch) = -1; + monster[v2].mtalkmsg = 0; + quests[15]._qvar1 = 6; + _LOBYTE(monster[v2]._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 = 0; /* 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) -------------------------------------------------------- +void __fastcall M_UpdateLeader(int i) +{ + int v1; // edi + int v2; // esi + int j; // edx + int v4; // eax + unsigned char *v5; // 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; + } + if ( monster[v1].leaderflag == 1 ) + { + v5 = &monster[(unsigned char)monster[v1].leader].unpackfilesize; + --*v5; + } +} + +//----- (00435697) -------------------------------------------------------- +void __cdecl DoEnding() +{ + char v0; // al + char *v1; // ecx + char bMusicOn; // bl + int v3; // esi + + if ( (unsigned char)gbMaxPlayers > 1u ) + SNetLeaveGame(0x40000004); + music_stop(); + if ( (unsigned char)gbMaxPlayers > 1u ) + Sleep(1000); + 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); + bMusicOn = 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 = bMusicOn; +} +// 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; + 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[4]._pHitPoints ); +} +// 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 == MT_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 == AI_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 + bool 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; + v5 = LineClearF( + 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 = 0; /* 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 == AI_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 ( UniqMonst[v8-1].mUnqAttr & 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 == AI_GARG ) + { + v12 = monster[v11]._mFlags; + if ( v12 & 4 ) + { + monster[v11]._mmode = MM_SATTACK; + monster[v11]._mFlags = v12 & 0xFFFFFFFB; + } + } + } + } + } + } +} + +//----- (00435DA8) -------------------------------------------------------- +bool __fastcall M_CallWalk(int i, int md) +{ + int v2; // esi + int v3; // edi + int v4; // ebp + //int v5; // eax + int v6; // ecx + bool 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 = DirOK(i, md); + if ( random(v6, 2) ) + { + if ( v7 ) + goto LABEL_10; + v9 = v2; + v2 = left[v2]; + //_LOBYTE(v10) = DirOK(v3, v2); + if ( DirOK(v3, v2) ) + goto LABEL_10; + v2 = right[v9]; + } + else + { + if ( v7 ) + goto LABEL_10; + v11 = v2; + v2 = right[v2]; + //_LOBYTE(v12) = DirOK(v3, v2); + if ( DirOK(v3, v2) ) + goto LABEL_10; + v2 = left[v11]; + } + //_LOBYTE(v13) = DirOK(v3, v2); + if ( !DirOK(v3, v2) ) + { + 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 ( DirOK(v3, v2) ) + goto LABEL_20; + v2 = left[left[v4]]; + } + else + { + if ( v14 ) + goto LABEL_20; + v2 = left[left[v4]]; + //_LOBYTE(v16) = DirOK(v3, v2); + if ( DirOK(v3, v2) ) + goto LABEL_20; + v2 = right[right[v4]]; + } + //_LOBYTE(v17) = DirOK(v3, v2); + if ( DirOK(v3, v2) ) + { +LABEL_20: + v18 = 1; + M_WalkDir(v3, v2); + return v18; + } + return 0; +} + +//----- (00435EB5) -------------------------------------------------------- +bool __fastcall M_PathWalk(int i) +{ + int v1; // esi + bool (__fastcall *Check)(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); + Check = PosOkMonst3; + if ( !(monster[v1]._mFlags & 0x200) ) + Check = PosOkMonst; + if ( !FindPath( + Check, + 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]]); /* plr2monst is local */ + return 1; +} + +//----- (00435F35) -------------------------------------------------------- +bool __fastcall M_CallWalk2(int i, int md) +{ + int v2; // esi + int v3; // ebx + //int v4; // eax + int v5; // ecx + bool v6; // edi + int v7; // edi + //int v8; // eax + int v9; // edi + //int v10; // eax + //int v11; // eax + bool v12; // di + + v2 = md; + v3 = i; + //_LOBYTE(v4) = DirOK(i, md); + _LOBYTE(v5) = 101; + v6 = DirOK(i, md); + if ( random(v5, 2) ) + { + if ( v6 ) + goto LABEL_10; + v7 = v2; + v2 = left[v2]; + //_LOBYTE(v8) = DirOK(v3, v2); + if ( DirOK(v3, v2) ) + goto LABEL_10; + v2 = right[v7]; + } + else + { + if ( v6 ) + goto LABEL_10; + v9 = v2; + v2 = right[v2]; + //_LOBYTE(v10) = DirOK(v3, v2); + if ( DirOK(v3, v2) ) + goto LABEL_10; + v2 = left[v9]; + } + //_LOBYTE(v11) = DirOK(v3, v2); + if ( DirOK(v3, v2) ) + { +LABEL_10: + v12 = 1; + M_WalkDir(v3, v2); + return v12; + } + return 0; +} + +//----- (00435FBA) -------------------------------------------------------- +bool __fastcall M_DumbWalk(int i, int md) +{ + int v2; // esi + int v3; // edi + //int v4; // eax + bool v5; // bl + + v2 = md; + v3 = i; + //_LOBYTE(v4) = DirOK(i, md); + v5 = DirOK(i, md); + if ( v5 ) + M_WalkDir(v3, v2); + return v5; +} + +//----- (00435FDB) -------------------------------------------------------- +bool __fastcall M_RoundWalk(int i, int md, int *dir) +{ + int *v3; // ebp + int v4; // ebx + int v5; // esi + //int v6; // eax + bool 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 = DirOK(i, v5); + if ( v7 ) + goto LABEL_12; + v8 = v5; + if ( !*dir ) + { + v11 = &left[v8]; + v5 = left[v8]; + //_LOBYTE(v12) = DirOK(v4, left[v8]); + if ( DirOK(v4, left[v8]) ) + goto LABEL_11; + v5 = left[*v11]; + //_LOBYTE(v13) = DirOK(v4, left[*v11]); + if ( DirOK(v4, left[*v11]) ) + 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 ( !DirOK(v4, right[v8]) ) + { + v5 = right[right[v8]]; + //_LOBYTE(v10) = DirOK(v4, v5); + if ( !DirOK(v4, v5) ) + 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), v11 >= 2) ) /* v10 = v12, */ + { + 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) -------------------------------------------------------- +bool __fastcall MAI_Path(int i) +{ + int v1; // edi + MonsterStruct *v2; // esi + char v3; // al + bool 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 != MT_GOLEM ) + { + if ( !_LOBYTE(v2->_msquelch) ) + return 0; + if ( v2->_mmode ) + return 0; + v3 = v2->_mgoal; + if ( v3 != 1 && v3 != 4 && v3 != 5 ) + return 0; + if ( v2->_mx == 1 && !v2->_my ) + return 0; + } + v4 = LineClearF1( + PosOkMonst2, + v1, + v2->_mx, + v2->_my, + (unsigned char)v2->_menemyx, + (unsigned char)v2->_menemyy); + if ( !v4 || (v5 = v2->_pathcount, v5 >= 5u) && v5 < 8u ) + { + if ( v2->_mFlags & 0x200 ) + MonstCheckDoors(v1); + if ( ++_LOBYTE(v2->_pathcount) < 5u ) + return 0; + if ( M_PathWalk(v1) ) + return 1; + } + if ( v2->MType->mtype != MT_GOLEM ) + _LOBYTE(v2->_pathcount) = 0; + return 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 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 + char pattern[6]; // [esp+4h] [ebp-1Ch] + int micaster; // [esp+Ch] [ebp-14h] + int midir; // [esp+10h] [ebp-10h] + int v1; // [esp+14h] [ebp-Ch] + int v2; // [esp+18h] [ebp-8h] + int arglist; // [esp+1Ch] [ebp-4h] + + esi1 = i; + arglist = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("MAI_Snake: Invalid monster %d", i); + pattern[2] = 0; + pattern[3] = -1; + pattern[4] = -1; + pattern[5] = 0; + esi3 = &monster[esi1]; + pattern[0] = 1; + pattern[1] = 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(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 = arglist; +LABEL_11: + M_StartDelay(v18, v17); + goto LABEL_49; + } + } + v19 = abs(v7); + //v21 = v20; + if ( v19 >= 3 || (v22 = abs(v10), v22 >= 3) ) /* v21 = v23, */ + { + v24 = arglist; + } + else + { + v24 = arglist; + if ( LineClearF1(PosOkMonst, arglist, esi3->_mx, esi3->_my, v1, v2) && esi3->_mVar1 != 14 ) + { + if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, micaster, arglist, 0, 0) != -1 ) + { + PlayEffect(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 + pattern[v29]; + if ( v30 >= 0 ) + { + v31 = v30 - 8; + if ( v30 < 8 ) + v31 = midir + pattern[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: + if ( !M_DumbWalk(v24, esi3->_mgoalvar2) ) + 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 + bool 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 == MT_GLOOM + && (abs(v5) >= 5 || abs(v6) >= 5) + && v22 < 4 * (unsigned char)esi3->_mint + 33 + && (v11 = LineClearF1( + 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] + bool 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 = M_DumbWalk(arglist, opposite[v17]); + } + } + } + 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 ( LineClear(v2->_mx, v2->_my, v14, v15) ) + 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), v9 >= v6 + 3) || v2->_mgoalvar1 > 8 ) /* v5 = v10, */ + { + 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 == MT_UNSEEN ) + { + _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 ( !LineClear(monster[esi3]._mx, monster[esi3]._my, v1, v2) + || 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 ( LineClear(monster[esi3]._mx, monster[esi3]._my, v1, v2) ) + { + 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 ( M_CallWalk(arglist, opposite[midir]) ) + return; + v15 = midir; + goto LABEL_29; + } + //_LOBYTE(v16) = M_CallWalk(arglist, midir); + if ( !M_CallWalk(arglist, midir) ) + { + 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 == AI_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 + bool 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 || (v18 = DirOK(arglist, md), !v18) ) + { + if ( dung_map[v3->_mx][v3->_my] == *v29 ) + { + //_LOBYTE(v19) = M_RoundWalk(arglist, md, &v3->_mgoalvar2); + if ( !M_RoundWalk(arglist, md, &v3->_mgoalvar2) ) + { + _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), v22 >= 2) ) /* v24 = v23, */ + { + 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 ( LineClear(monster[v4]._mx, monster[v4]._my, x2, y2) ) + { + 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 + unsigned char *v3; // eax + int v4; // ecx + int v5; // ecx + signed int v6; // ebx + signed int v7; // edi + int v8; // edx + int v9; // eax + bool v10; // eax + int v11; // ebx + int v12; // edi + signed int v13; // edi + int v14; // edx + int v15; // eax + bool 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] + && (v10 = LineClearF( + 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] + && (v16 = LineClearF( + 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 ( !M_CallWalk(v1, opposite[v8]) ) + _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 + bool v22; // eax + bool v23; // eax + bool 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 && (v22 = DirOK(arglist, md), v22) ) + { +LABEL_50: + _LOBYTE(v6->_mgoal) = 1; + } + else if ( checkdoorsa < 500 * ((unsigned char)v6->_mint + 1) >> lessmissiles + && (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) + && (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), v27 >= 2) ) /* v13 = v28, */ + { + _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 + bool v21; // eax + bool 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), v13 >= 2) ) /* v12 = v14, */ + { + 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 || (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) + && (v22 = LineClear(v4->_mx, v4->_my, x2, y2), v22) ) + { + v23 = arglist; + } + else + { + v24 = abs(v8); + //v26 = v25; + if ( v24 >= 2 || (v27 = abs(v7), v27 >= 2) ) /* v26 = v28, */ + { + _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 + bool v14; // eax + int *v15; // esi + bool 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 ) + { + v14 = 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; + v16 = M_CallWalk(arglist, plr[arglist]._pdir); + if ( !v16 ) + { + v17 = ((_BYTE)v19 - 1) & 7; + v18 = 0; + while ( !v16 ) + { + v17 = ((_BYTE)v17 + 1) & 7; + 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 + bool v16; // eax + //int v17; // eax + int v18; // ecx + int v19; // eax + bool 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 || (v16 = DirOK(arglist, md), !v16) ) + { + if ( dung_map[v2->_mx][v2->_my] == *v32 ) + { + //_LOBYTE(v17) = M_RoundWalk(arglist, md, &v2->_mgoalvar2); + if ( !M_RoundWalk(arglist, md, &v2->_mgoalvar2) ) + { + _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) + && (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), v26 >= 2) ) /* v25 = v27, */ + { + _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 + bool 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 ( !M_RoundWalk(arglist, midir, &esi3->_mgoalvar2) ) + { + _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 + && (v19 = LineClearF1( + PosOkMonst, + arglist, + esi3->_mx, + esi3->_my, + v1, + v2), + v19) ) + { + if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, esi3->_menemy, 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), v24 >= 2) ) /* v23 = v25, */ + { + _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 ( DirOK(arglist, md) ) + 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), v25 >= 2) ) /* v24 = v26, */ + { + if ( v39 < 5 * ((unsigned char)monster[v2]._mint + 10) ) + { + //_LOBYTE(v31) = LineClear(monster[v2]._mx, monster[v2]._my, x2, y2); + if ( LineClear(monster[v2]._mx, monster[v2]._my, x2, y2) ) + { + _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], /* counsmiss is local */ + (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)QUEST_GARBUD4 + && v5 > (signed int)QUEST_DOOM10 + && !(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 == QUEST_GARBUD4 ) + { + //_LOBYTE(v6) = effect_is_playing(USFX_GARBUD4); + if ( !effect_is_playing(USFX_GARBUD4) && _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 == QUEST_ZHAR1 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + monster[v2].mtalkmsg = QUEST_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 == QUEST_ZHAR2 ) + { + //_LOBYTE(v8) = effect_is_playing(USFX_ZHAR2); + if ( !effect_is_playing(USFX_ZHAR2) && _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 == QUEST_BANNER10 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + monster[v2].mtalkmsg = QUEST_BANNER11; + _LOBYTE(monster[v2]._mgoal) = 6; + } + if ( monster[v2].mtalkmsg == QUEST_BANNER11 && quests[7]._qvar1 == 3 ) + { + monster[v2].mtalkmsg = 0; + _LOBYTE(monster[v2]._mgoal) = 1; + } + if ( dFlags[v4][v3] & 2 ) + { + if ( monster[v2].mtalkmsg == QUEST_BANNER12 ) + { + //_LOBYTE(v6) = effect_is_playing(USFX_SNOT3); + if ( !effect_is_playing(USFX_SNOT3) && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + ObjChangeMap(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 == QUEST_VILE13 ) + { + if ( _LOBYTE(monster[v2]._mgoal) == 6 && plr[myplr].WorldX == QUEST_VILE13 && plr[myplr].WorldY == 46 ) + { + PlayInGameMovie("gendata\\fprst3.smk"); + monster[v2]._mmode = MM_TALK; + quests[15]._qvar1 = 5; + } + if ( monster[v2].mtalkmsg == QUEST_VILE13 ) + { + //_LOBYTE(v6) = effect_is_playing(USFX_LAZ1); + if ( !effect_is_playing(USFX_LAZ1) && _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 == QUEST_VILE13 && _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 == QUEST_VEIL9 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 ) + { + monster[v2].mtalkmsg = QUEST_VEIL10; + _LOBYTE(monster[v2]._mgoal) = 6; + } + if ( dFlags[v4][v3] & 2 ) + { + if ( monster[v2].mtalkmsg == QUEST_VEIL11 ) + { + //_LOBYTE(v5) = effect_is_playing(USFX_LACH3); + if ( !effect_is_playing(USFX_LACH3) && _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 == QUEST_WARLRD9 ) + { + if ( _LOBYTE(monster[v2]._mgoal) == 6 ) + monster[v2]._mmode = MM_TALK; + //_LOBYTE(v6) = effect_is_playing(USFX_WARLRD1); + if ( !effect_is_playing(USFX_WARLRD1) && _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 + bool 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 == MT_CLEAVER ) + 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 != MT_DIABLO ) /* BUG_FIX: change '_mAi' to 'MType->mtype' */ + _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 ) + { + v18 = 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) -------------------------------------------------------- +bool __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 + unsigned 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 || !(UniqMonst[v12-1].mUnqAttr & 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) -------------------------------------------------------- +bool __fastcall PosOkMissile(int x, int y) +{ + int v2; // ecx + bool result; // al + + v2 = x; + result = 0; + if ( !nMissileTable[dPiece[0][v2 * 112 + y]] && !(dFlags[v2][y] & 0x10) ) + result = 1; + return result; +} + +//----- (00439A57) -------------------------------------------------------- +bool __fastcall CheckNoSolid(int x, int y) +{ + return nSolidTable[dPiece[0][y + 112 * x]] == 0; +} + +//----- (00439A71) -------------------------------------------------------- +bool __fastcall LineClearF(bool (__fastcall *Clear)(int, int), 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 + 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; + 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) && !Clear(v22, y1) ) /* check args */ + 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 || Clear(v15, v14) ); +LABEL_29: + if ( v29 != x2 ) + return 0; + } + if ( y1 == y2 ) + return 1; + return 0; +} + +//----- (00439BE0) -------------------------------------------------------- +bool __fastcall LineClear(int x1, int y1, int x2, int y2) +{ + return LineClearF(PosOkMissile, x1, y1, x2, y2); +} + +//----- (00439BFA) -------------------------------------------------------- +bool __fastcall LineClearF1(bool (__fastcall *Clear)(int, int, int), 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 + 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] + + 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) && !Clear(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 || Clear(v25, x1, v15) ); /* check args */ +LABEL_29: + if ( x1 != x2 ) + return 0; + } + if ( y1 == y2 ) + return 1; + return 0; +} + +//----- (00439D75) -------------------------------------------------------- +void __fastcall SyncMonsterAnim(int i) +{ + int v1; // esi + int v2; // 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 = i; + if ( (unsigned int)i >= 0xC8 ) + TermMsg("SyncMonsterAnim: Invalid monster %d", i); + v2 = v1; + v3 = monster[v1]._mMTidx; + v4 = Monsters[v3].MData; + v5 = &Monsters[v3]; + v6 = monster[v2]._uniqtype; + monster[v2].MType = v5; + monster[v2].MData = v4; + if ( v6 ) + v7 = UniqMonst[v6-1].mName; + else + v7 = v4->mName; + v8 = monster[v2]._mmode; + monster[v2].mName = v7; + v9 = monster[v2]._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[v2]._mAFNum = v10; + return; + case MM_CHARGE: + v11 = v5->Anims[2].Frames[v9 + 1]; + monster[v2]._mAnimFrame = 1; + monster[v2]._mAFNum = v11; + v12 = v5->Anims[2].Rate; + break; + default: + v13 = v5->Anims[0].Frames[v9 + 1]; + monster[v2]._mAnimFrame = 1; + monster[v2]._mAFNum = v13; + v12 = v5->Anims[0].Rate; + break; + } + monster[v2]._mAnimLen = v12; +} + +//----- (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 > MT_RFALLSD ) + { + v9 = v6 - 13; + v8 = v9 == 0; + } + else + { + if ( v6 == MT_RFALLSD || (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 == AI_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 == DIFF_NIGHTMARE ) + { + 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 "); + tempstr[strlen(tempstr) - 1] = '\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 "); + tempstr[strlen(tempstr) - 1] = '\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[pcursmonst].mMagicRes & 0x3F; + if ( v0 ) + { + if ( monster[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 < MT_INCIN || v8 > MT_HELLBURN ) + { + 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 != MT_GLOOM && (v22 < MT_INCIN || v22 > MT_HELLBURN) ) + { + M_TryM2MHit(ia, *v21 - 1, 500, (unsigned char)v6->mMinDamage2, (unsigned char)v6->mMaxDamage2); + v23 = v6->MType->mtype; + if ( v23 < MT_NSNAKE || v23 > MT_GSNAKE ) + { + 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 != MT_GLOOM && (v13 < MT_INCIN || v13 > MT_HELLBURN) ) + { + M_TryH2HHit(v5, v12, 500, (unsigned char)v6->mMinDamage2, (unsigned char)v6->mMaxDamage2); + if ( arglist == *v10 - 1 ) + { + v14 = v6->MType->mtype; + if ( v14 < MT_NSNAKE || v14 > MT_GSNAKE ) + { + 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) -------------------------------------------------------- +bool __fastcall PosOkMonst(int i, int x, int y) +{ + int v3; // edi + signed int v4; // ebx + int v5; // ecx + char v6; // dl + bool 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 == MT_DIABLO ) + return 0; + } + } + } + } + } + return result; +} + +//----- (0043A547) -------------------------------------------------------- +bool __fastcall PosOkMonst2(int i, int x, int y) +{ + int v3; // edi + int v4; // ebx + signed int v5; // ebp + bool 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 == MT_DIABLO ) + result = 0; + } + } + } + } + } + } + } + return result; +} + +//----- (0043A613) -------------------------------------------------------- +bool __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 + bool 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 == MT_DIABLO ) + return 0; + } + } + } + } + } + return result; +} + +//----- (0043A73B) -------------------------------------------------------- +bool __fastcall IsSkel(int mt) +{ + return mt >= MT_WSKELAX && mt <= MT_XSKELAX + || mt >= MT_WSKELBW && mt <= MT_XSKELBW + || mt >= MT_WSKELSD && mt <= MT_XSKELSD; +} + +//----- (0043A760) -------------------------------------------------------- +bool __fastcall IsGoat(int mt) +{ + return mt >= MT_NGOATMC && mt <= MT_GGOATMC || mt >= MT_NGOATBW && mt <= MT_GGOATBW; +} + +//----- (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 < nummtypes ); /* 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) -------------------------------------------------------- +bool __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 + bool v9; // eax + int v11; // eax + int v12; // ecx + int v13; // edx + int v14; // esi + int v15; // edi + int v16; // ST04_4 + int monstok[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 = monstok; + 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 ( monstok[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() +{ + int skeltypes; // edx + int j; // edx + int skel; // eax + int i; // [esp+10h] [ebp-4h] + + if ( nummtypes <= 0 ) + return -1; + + for(i = 0; i < nummtypes; i++) + { + if ( IsSkel(Monsters[i].mtype) ) + ++skeltypes; + } + + if ( !skeltypes ) + return -1; + + j = random(136, skeltypes); /* check this code -i integer is messed up*/ + skeltypes = 0; + + for ( i = 0; i < nummtypes; ++i ) + { + if ( skeltypes > j ) + break; + if ( IsSkel(Monsters[i].mtype) ) + ++skeltypes; + } + skel = AddMonster(0, 0, 0, i - 1, 0); + if ( skel != -1 ) + M_StartStand(skel, 0); + return skel; +} + +//----- (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 == AI_SNOTSPIL || v3 == AI_LACHDAN ) + { + //_LOBYTE(v5) = QuestStatus(7); + if ( QuestStatus(7) && quests[7]._qvar1 == 2 && PlrHasItem(v4, IDI_BANNER, &inv_item_num) ) + { + RemoveInvItem(v4, inv_item_num); + quests[7]._qactive = 3; + v2->mtalkmsg = QUEST_BANNER12; + _LOBYTE(v2->_mgoal) = 6; + } + //_LOBYTE(v6) = QuestStatus(4); + if ( QuestStatus(4) && v2->mtalkmsg >= (signed int)QUEST_VEIL9 ) + { + if ( PlrHasItem(v4, IDI_GLDNELIX, &inv_item_num) ) + { + RemoveInvItem(v4, inv_item_num); + v2->mtalkmsg = QUEST_VEIL11; + _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) -------------------------------------------------------- +bool __fastcall CanTalkToMonst(int m) +{ + int v1; // esi + char v2; // al + bool 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) -------------------------------------------------------- +bool __fastcall CheckMonsterHit(int m, bool *ret) +{ + int v2; // edi + bool *v3; // esi + int v4; // ecx + int v5; // eax + bool 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 == AI_GARG && (v5 = monster[v4]._mFlags, v5 & 4) ) + { + _LOBYTE(v5) = v5 & 0xFB; + monster[v4]._mmode = MM_SATTACK; + monster[v4]._mFlags = v5; + result = 1; + *v3 = 1; + } + else + { + v7 = monster[v4].MType->mtype; + if ( v7 < MT_COUNSLR || v7 > MT_ADVOCATE || (result = 1, _LOBYTE(monster[v4]._mgoal) == 1) ) + result = 0; + else + *v3 = 0; + } + return result; +} + +//----- (0043ACB5) -------------------------------------------------------- +int __fastcall encode_enemy(int m) +{ + int v1; // ecx + int result; // eax + + v1 = m; + result = monster[v1]._menemy; + if ( monster[v1]._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; +} diff --git a/Source/monster.h b/Source/monster.h new file mode 100644 index 0000000..fad046a --- /dev/null +++ b/Source/monster.h @@ -0,0 +1,201 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//monster +extern int MissileFileFlag; // weak +extern int monster_cpp_init_value; // weak +extern int monstkills[200]; +extern int monstactive[200]; +extern int nummonsters; +extern int sgbSaveSoundOn; // weak +extern MonsterStruct monster[200]; +extern int totalmonsters; // weak +extern CMonster Monsters[16]; +// int END_Monsters_17; // weak +extern int monstimgtot; // weak +extern int uniquetrans; +extern int nummtypes; + +void __cdecl monster_cpp_init(); +void __fastcall InitMonsterTRN(int monst, 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(); +bool __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); +bool __fastcall M_Ranged(int i); +bool __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); +void __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); +bool __fastcall M_CallWalk(int i, int md); +bool __fastcall M_PathWalk(int i); +bool __fastcall M_CallWalk2(int i, int md); +bool __fastcall M_DumbWalk(int i, int md); +bool __fastcall M_RoundWalk(int i, int md, int *dir); +void __fastcall MAI_Zombie(int i); +void __fastcall MAI_SkelSd(int i); +bool __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(); +bool __fastcall DirOK(int i, int mdir); +bool __fastcall PosOkMissile(int x, int y); +bool __fastcall CheckNoSolid(int x, int y); +bool __fastcall LineClearF(bool (__fastcall *Clear)(int, int), int x1, int y1, int x2, int y2); +bool __fastcall LineClear(int x1, int y1, int x2, int y2); +bool __fastcall LineClearF1(bool (__fastcall *Clear)(int, int, int), int monst, int x1, int y1, int x2, int y2); +void __fastcall SyncMonsterAnim(int i); +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); +bool __fastcall PosOkMonst(int i, int x, int y); +bool __fastcall PosOkMonst2(int i, int x, int y); +bool __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); +bool __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); +bool __fastcall CanTalkToMonst(int m); +bool __fastcall CheckMonsterHit(int m, bool *ret); +int __fastcall encode_enemy(int m); +void __fastcall decode_enemy(int m, int enemy); + +/* data */ + +extern int monster_inf; // weak +extern char plr2monst[9]; +extern unsigned char counsmiss[4]; + +/* rdata */ + +extern MonsterData monsterdata[112]; +extern char MonstConvTbl[128]; +extern unsigned char MonstAvailTbl[112]; +extern UniqMonstStruct UniqMonst[98]; +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 (__fastcall *AiProc[])(int i); diff --git a/Source/movie.cpp b/Source/movie.cpp new file mode 100644 index 0000000..a1413ed --- /dev/null +++ b/Source/movie.cpp @@ -0,0 +1,103 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int movie_cpp_init_value; // weak +char movie_playing; // weak +int loop_movie; // weak + +int movie_inf = 0x7F800000; // weak + +//----- (0043AD38) -------------------------------------------------------- +struct movie_cpp_init +{ + movie_cpp_init() + { + movie_cpp_init_value = movie_inf; + } +} _movie_cpp_init; +// 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 *saveProc)(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 ) + { + saveProc = SetWindowProc(MovieWndProc); + InvalidateRect(ghMainWnd, 0, 0); + UpdateWindow(ghMainWnd); + 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 && !movie_playing ) + break; + while ( PeekMessageA(&Msg, NULL, 0, 0, PM_REMOVE) ) + { + if ( Msg.message != WM_QUIT ) + { + TranslateMessage(&Msg); + DispatchMessageA(&Msg); + } + } + //_LOBYTE(v4) = SVidPlayContinue(); + if ( !SVidPlayContinue() ) + break; + } + while ( video_stream ); + if ( video_stream ) + SVidPlayEnd(video_stream); + } + SetWindowProc(saveProc); + 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: + 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); + movie_playing = 0; + return 0; +} +// 659AF8: using guessed type int movie_playing; diff --git a/Source/movie.h b/Source/movie.h new file mode 100644 index 0000000..ba09ade --- /dev/null +++ b/Source/movie.h @@ -0,0 +1,23 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//movie +extern int movie_cpp_init_value; // weak +extern char movie_playing; // weak +extern int loop_movie; // weak + +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); + +/* data */ + +extern int movie_inf; // weak diff --git a/Source/mpqapi.cpp b/Source/mpqapi.cpp new file mode 100644 index 0000000..a649c33 --- /dev/null +++ b/Source/mpqapi.cpp @@ -0,0 +1,838 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int mpqapi_cpp_init_value; // weak +int sgdwMpqOffset; // idb +char mpq_buf[4096]; +_HASHENTRY *sgpHashTbl; +bool save_archive_modified; // weak +_BLOCKENTRY *sgpBlockTbl; +bool save_archive_open; // weak + +int mpqapi_inf = 0x7F800000; // weak + +/* rdata */ + +HANDLE sghArchive = (HANDLE)0xFFFFFFFF; // idb + +//----- (0043AE95) -------------------------------------------------------- +struct mpqapi_cpp_init +{ + mpqapi_cpp_init() + { + mpqapi_cpp_init_value = mpqapi_inf; + } +} _mpqapi_cpp_init; +// 47F148: using guessed type int mpqapi_inf; +// 659B00: using guessed type int mpqapi_cpp_init_value; + +//----- (0043AEA0) -------------------------------------------------------- +bool __fastcall 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 = GetFileAttributesA(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 = SetFileAttributesA(v2, v6); + return result; +} + +//----- (0043AEDC) -------------------------------------------------------- +void __fastcall 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 = 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 + 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; +} + +//----- (0043AFA5) -------------------------------------------------------- +void __fastcall 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 ); +} + +//----- (0043AFC4) -------------------------------------------------------- +bool __fastcall 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); +} + +//----- (0043B002) -------------------------------------------------------- +void __fastcall 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_alloc_block(v4, v5); + save_archive_modified = 1; + } +} +// 65AB0C: using guessed type int save_archive_modified; + +//----- (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 == sgdwMpqOffset; + if ( v3 + v2 > sgdwMpqOffset ) + { + TermMsg("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; + } +} + +//----- (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 *pszName) // FetchHandle +{ + char *v1; // esi + int v2; // ST00_4 + int v3; // edi + short v4; // ax + + v1 = pszName; + v2 = encrypt_hash(pszName, 2); // MPQ_HASH_NAME_B + v3 = encrypt_hash(v1, 1); // MPQ_HASH_NAME_A + v4 = encrypt_hash(v1, 0); // MPQ_HASH_TABLE_INDEX + 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 + _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; +} + +//----- (0043B1BD) -------------------------------------------------------- +void __fastcall 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++; + } +} + +//----- (0043B1F8) -------------------------------------------------------- +bool __fastcall 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; +} +// 65AB0C: using guessed type int save_archive_modified; + +//----- (0043B23D) -------------------------------------------------------- +_BLOCKENTRY *__fastcall 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 = encrypt_hash(pszName, 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].block; + 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].hashcheck[0] = v5; + sgpHashTbl[v9].hashcheck[1] = v11; + sgpHashTbl[v9].lcid = 0; + sgpHashTbl[v9].block = block_index; + return v12; +} + +//----- (0043B317) -------------------------------------------------------- +bool __fastcall 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; + } + encrypt_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 = encrypt_compress(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_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 = 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; +} + +//----- (0043B570) -------------------------------------------------------- +void __fastcall 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; + } +} +// 65AB0C: using guessed type int save_archive_modified; + +//----- (0043B5AF) -------------------------------------------------------- +bool __fastcall mpqapi_has_file(char *pszName) +{ + return mpqapi_get_hash_index_of_path(pszName) != -1; +} + +//----- (0043B5BF) -------------------------------------------------------- +bool __fastcall 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] + TMPQHeader fhdr; // [esp+18h] [ebp-68h] + + v3 = pszArchive; + v4 = hidden; + lpFileName = pszArchive; + encrypt_init_lookup_table(); + if ( !mpqapi_set_hidden(v3, v4) ) + return 0; + v6 = (unsigned char)gbMaxPlayers > 1u ? FILE_FLAG_WRITE_THROUGH : 0; + save_archive_open = 0; + sghArchive = CreateFileA(v3, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, v6, NULL); + if ( sghArchive == (HANDLE)-1 ) + { + sghArchive = CreateFileA(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.dwBlockTableSize ) + { + if ( SetFilePointer(sghArchive, 104, NULL, FILE_BEGIN) == -1 + || !ReadFile(sghArchive, sgpBlockTbl, 0x8000u, &dwTemp, NULL) ) + { + goto LABEL_15; + } + v8 = encrypt_hash("(block table)", 3); + encrypt_decrypt_block(sgpBlockTbl, 0x8000, v8); + } + sgpHashTbl = (_HASHENTRY *)DiabloAllocPtr(0x8000); + memset(sgpHashTbl, 255, 0x8000u); + if ( fhdr.dwHashTableSize ) + { + if ( SetFilePointer(sghArchive, 32872, NULL, FILE_BEGIN) == -1 + || !ReadFile(sghArchive, sgpHashTbl, 0x8000u, &dwTemp, NULL) ) + { + goto LABEL_15; + } + v10 = encrypt_hash("(hash table)", 3); + encrypt_decrypt_block(sgpHashTbl, 0x8000, v10); + } + } + return 1; +} +// 65AB0C: using guessed type int save_archive_modified; +// 65AB14: using guessed type char save_archive_open; +// 679660: using guessed type char gbMaxPlayers; + +//----- (0043B791) -------------------------------------------------------- +bool __fastcall mpqapi_parse_archive_header(TMPQHeader *pHdr, int *pdwNextFileStart) // ParseMPQHeader +{ + int *v2; // ebp + TMPQHeader *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->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, NULL, FILE_BEGIN) == -1 || !SetEndOfFile(sghArchive) ) + return 0; + memset(v3, 0, 0x68u); + v3->dwID = '\x1AQPM'; + v3->dwHeaderSize = 32; + v3->wSectorSize = 3; + v3->wFormatVersion = 0; + *v2 = 0x10068; + save_archive_modified = 1; + save_archive_open = 1; + } + return 1; +} +// 65AB0C: using guessed type int save_archive_modified; +// 65AB14: using guessed type char save_archive_open; + +//----- (0043B882) -------------------------------------------------------- +void __fastcall 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); + } +} +// 65AB0C: using guessed type int save_archive_modified; +// 65AB14: using guessed type char save_archive_open; + +//----- (0043B8FD) -------------------------------------------------------- +void __fastcall 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 = 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 *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); +} +// 65AB0C: using guessed type int save_archive_modified; + +//----- (0043B9CA) -------------------------------------------------------- +bool __cdecl mpqapi_write_header() // WriteMPQHeader +{ + bool result; // al + TMPQHeader fhdr; // [esp+8h] [ebp-6Ch] + DWORD NumberOfBytesWritten; // [esp+70h] [ebp-4h] + + memset(&fhdr, 0, 0x68u); + fhdr.dwID = '\x1AQPM'; + fhdr.dwHeaderSize = 32; + fhdr.dwArchiveSize = GetFileSize(sghArchive, 0); + fhdr.wFormatVersion = 0; + fhdr.wSectorSize = 3; + fhdr.dwHashTablePos = 32872; + fhdr.dwBlockTablePos = 104; + fhdr.dwHashTableSize = 2048; + fhdr.dwBlockTableSize = 2048; + if ( SetFilePointer(sghArchive, 0, NULL, FILE_BEGIN) != -1 && WriteFile(sghArchive, &fhdr, 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, NULL, FILE_BEGIN) == -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, NULL, FILE_BEGIN) == -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, sgdwMpqOffset, NULL, FILE_BEGIN) == -1 ) + result = 0; + else + result = SetEndOfFile(sghArchive); + return result; +} diff --git a/Source/mpqapi.h b/Source/mpqapi.h new file mode 100644 index 0000000..8f0fd8a --- /dev/null +++ b/Source/mpqapi.h @@ -0,0 +1,56 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//mpqapi +extern int mpqapi_cpp_init_value; // weak +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 + +void __cdecl mpqapi_cpp_init(); +bool __fastcall mpqapi_set_hidden(char *pszArchive, bool hidden); +void __fastcall mpqapi_store_creation_time(char *pszArchive, int dwChar); +bool __fastcall mpqapi_reg_load_modification_time(char *dst, int size); +void __fastcall mpqapi_xor_buf(char *pbData); +bool __fastcall mpqapi_reg_store_modification_time(char *pbData, int dwLen); +_BLOCKENTRY *__fastcall j_mpqapi_remove_hash_entry(char *pszName); +void __fastcall mpqapi_remove_hash_entry(char *pszName); +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 *pszName); +int __fastcall mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale); +void __fastcall mpqapi_remove_hash_entries(bool (__stdcall *fnGetName)(int, char *)); +bool __fastcall mpqapi_write_file(char *pszName, char *pbData, int dwLen); +_BLOCKENTRY *__fastcall mpqapi_add_file(char *pszName, _BLOCKENTRY *pBlk, int block_index); +bool __fastcall mpqapi_write_file_contents(char *pszName, char *pbData, int dwLen, _BLOCKENTRY *pBlk); +int __fastcall mpqapi_find_free_block(int size, int *block_size); +void __fastcall mpqapi_rename(char *pszOld, char *pszNew); +bool __fastcall mpqapi_has_file(char *pszName); +bool __fastcall mpqapi_open_archive(char *pszArchive, bool hidden, int dwChar); +bool __fastcall mpqapi_parse_archive_header(TMPQHeader *pHdr, int *pdwNextFileStart); +void __fastcall mpqapi_close_archive(char *pszArchive, bool bFree, int dwChar); +void __fastcall mpqapi_store_modified_time(char *pszArchive, int dwChar); +void __fastcall mpqapi_flush_and_close(char *pszArchive, bool bFree, int dwChar); +bool __cdecl mpqapi_write_header(); +bool __cdecl mpqapi_write_block_table(); +bool __cdecl mpqapi_write_hash_table(); +bool __cdecl mpqapi_can_seek(); + +/* data */ + +extern int mpqapi_inf; // weak + +/* rdata */ + +extern HANDLE sghArchive; // idb diff --git a/Source/msg.cpp b/Source/msg.cpp new file mode 100644 index 0000000..cef17ab --- /dev/null +++ b/Source/msg.cpp @@ -0,0 +1,3980 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int sgdwOwnerWait; // weak +int msg_cpp_init_value; // weak +int sgdwRecvOffset; // idb +int sgnCurrMegaPlayer; // weak +DLevel sgLevels[17]; +char sbLastCmd; // weak +TMegaPkt *sgpCurrPkt; +char sgRecvBuf[4722]; +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 msg_inf = 0x7F800000; // weak + +//----- (0043BBA9) -------------------------------------------------------- +struct msg_cpp_init +{ + msg_cpp_init() + { + msg_cpp_init_value = msg_inf; + } +} _msg_cpp_init; +// 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) +{ + TFakeDropPlr cmd; // [esp+0h] [ebp-8h] + + cmd.dwReason = reason; + cmd.bCmd = FAKE_CMD_DROPID; + cmd.bPlr = pnum; + msg_send_packet(pnum, &cmd, 6); +} + +//----- (0043BBCF) -------------------------------------------------------- +void __fastcall msg_send_packet(int pnum, void *packet, int dwSize) +{ + void *v3; // edi + TMegaPkt *v4; // eax + TFakeCmdPlr cmd; // [esp+Ah] [ebp-2h] + + v3 = packet; + if ( pnum != sgnCurrMegaPlayer ) + { + sgnCurrMegaPlayer = pnum; + cmd.bCmd = FAKE_CMD_SETID; + cmd.bPlr = pnum; + msg_send_packet(pnum, &cmd, 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 + int 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 ( !SNetGetOwnerTurnsWaiting(&turns) && SErrGetLastError() == STORM_ERROR_NOT_IN_GAME ) + return 100; + if ( GetTickCount() - sgdwOwnerWait <= 2000 && 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 ( nthread_has_500ms_passed() ) + 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 DeltaExportData(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 = DeltaExportItem(v3, &v2[-2794]); + v5 = DeltaExportObject(v4, v2); + v6 = DeltaExportMonster(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)&sgLevels[17].object ); + v8 = DeltaExportJunk((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 DeltaExportItem(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 DeltaExportObject(void *dst, void *src) +{ + char *v2; // esi + + v2 = (char *)dst; + memcpy(dst, src, 0x7Fu); + return v2 + 127; +} + +//----- (0043BF6F) -------------------------------------------------------- +void *__fastcall DeltaExportMonster(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 DeltaExportJunk(char *a1) +{ + char *v1; // ebx + DJunk *v2; // edi + MultiQuests *v3; // esi + unsigned char *v4; // edi + int *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 ( *(_BYTE *)v5 & 1 ) + { + v3->qlog = v4[18]; + v3->qstate = *v4; + v3->qvar1 = v4[13]; + memcpy(v1, v3, 3u); + v1 += 3; + ++v3; + } + v5 += 5; + v4 += 24; + } + while ( (signed int)v5 < (signed int)&questlist[16]._qflags ); + 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, int 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) +{ + unsigned char v1; // bl + bool v2; // zf + int v3; // eax + int i; // ebp + int v5; // ecx + int v6; // esi + DMonsterStr *v7; // edi + + v1 = bLevel; + if ( gbMaxPlayers != 1 ) + { + v2 = currlevel == 0; + if ( !currlevel ) + { + v3 = GetRndSeed(); + v2 = currlevel == 0; + glSeedTbl[0] = v3; + } + if ( !v2 ) + { + for ( i = 0; i < nummonsters; ++i ) + { + v5 = monstactive[i]; + v6 = monstactive[i]; + if ( monster[v6]._mhitpoints ) + { + sgbDeltaChanged = 1; + v7 = &sgLevels[v1].monster[v5]; + v7->_mx = monster[v6]._mx; + v7->_my = monster[v6]._my; + v7->_mdir = monster[v6]._mdir; + v7->_menemy = encode_enemy(v5); + v7->_mhitpoints = monster[v6]._mhitpoints; + v7->_mactive = monster[v6]._msquelch; + } + } + memcpy(&sgLocals[v1], 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 == item[v1].IDidx + && v5->item[0].wCI == item[v7]._iCreateInfo + && v5->item[0].dwSeed == item[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 *)&item[0]._ix + v9); + sgbDeltaChanged = 1; + v4->item[0].x = v10; + v4->item[0].y = *((_BYTE *)&item[0]._iy + v9); + v4->item[0].wIndx = *(_WORD *)((char *)&item[0].IDidx + v9); + v4->item[0].wCI = *(short *)((char *)&item[0]._iCreateInfo + v9); + v4->item[0].dwSeed = *(int *)((char *)&item[0]._iSeed + v9); + v4->item[0].bId = *((_BYTE *)&item[0]._iIdentified + v9); + v4->item[0].bDur = *((_BYTE *)&item[0]._iDurability + v9); + v4->item[0].bMDur = *((_BYTE *)&item[0]._iMaxDur + v9); + v4->item[0].bCh = *((_BYTE *)&item[0]._iCharges + v9); + v11 = *((_BYTE *)&item[0]._iMaxCharges + v9); + _LOWORD(v9) = *(_WORD *)((char *)&item[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[4]._pGFXLoad ); + 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 ) + { + v11 = 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[item[v11]._ix][item[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 == IDI_EAR ) + { + 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); + RecreateItem(v14, v16, v13, v18, v17); + v19 = v8 + 4721 * currlevel; + if ( *(&sgLevels[0].item[0].bId + v19) ) + item[v14]._iIdentified = 1; + v20 = v14; + item[v20]._iDurability = *((unsigned char *)&sgLevels[0].item[0].bDur + v19); + item[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); + item[v20]._iCharges = v21; + item[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; + item[v27]._ix = v24; + item[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 >= CMD_OPENDOOR ) + { + if ( v29 <= CMD_PLROPOBJ ) + { + SyncOpObject(-1, v29, v28); + } + else if ( v29 == CMD_BREAKOBJ ) + { + 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, int 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 = item[v5]._ix; + cmd.y = item[v5]._iy; + v6 = item[v5].IDidx == IDI_EAR; + cmd.wIndx = item[v5].IDidx; + if ( v6 ) + { + _LOBYTE(v7) = 0; + _HIBYTE(v7) = item[v5]._iName[7]; + _LOBYTE(v8) = 0; + _HIBYTE(v8) = item[v5]._iName[18]; + v9 = item[v5]._iName[10]; + cmd.wCI = item[v5]._iName[8] | v7; + cmd.dwSeed = item[v5]._iName[12] | ((item[v5]._iName[11] | ((v9 | (item[v5]._iName[9] << 8)) << 8)) << 8); + cmd.bId = item[v5]._iName[13]; + cmd.bDur = item[v5]._iName[14]; + cmd.bMDur = item[v5]._iName[15]; + cmd.bCh = item[v5]._iName[16]; + cmd.bMCh = item[v5]._iName[17]; + v10 = item[v5]._iName[20]; + cmd.wValue = _LOWORD(item[v5]._ivalue) | v8 | ((_LOWORD(item[v5]._iCurs) - 19) << 6); + cmd.dwBuff = item[v5]._iName[22] | ((item[v5]._iName[21] | ((v10 | (item[v5]._iName[19] << 8)) << 8)) << 8); + } + else + { + cmd.wCI = item[v5]._iCreateInfo; + cmd.dwSeed = item[v5]._iSeed; + cmd.bId = item[v5]._iIdentified; + cmd.bDur = item[v5]._iDurability; + cmd.bMDur = item[v5]._iMaxDur; + cmd.bCh = item[v5]._iCharges; + v11 = item[v5]._iMaxCharges; + v12 = item[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) -------------------------------------------------------- +bool __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 = item[ii]._ix; + cmd.y = item[ii]._iy; + v3 = (short *)&item[ii].IDidx; + v4 = *(_DWORD *)v3 == IDI_EAR; + cmd.wIndx = *v3; + if ( v4 ) + { + _LOBYTE(v5) = 0; + _HIBYTE(v5) = item[v2]._iName[7]; + _LOBYTE(v6) = 0; + _HIBYTE(v6) = item[v2]._iName[18]; + v7 = item[v2]._iName[10]; + cmd.wCI = item[v2]._iName[8] | v5; + cmd.dwSeed = item[v2]._iName[12] | ((item[v2]._iName[11] | ((v7 | (item[v2]._iName[9] << 8)) << 8)) << 8); + cmd.bId = item[v2]._iName[13]; + cmd.bDur = item[v2]._iName[14]; + cmd.bMDur = item[v2]._iName[15]; + cmd.bCh = item[v2]._iName[16]; + cmd.bMCh = item[v2]._iName[17]; + v8 = item[v2]._iName[20]; + cmd.wValue = _LOWORD(item[v2]._ivalue) | v6 | ((_LOWORD(item[v2]._iCurs) - 19) << 6); + cmd.dwBuff = item[v2]._iName[22] | ((item[v2]._iName[21] | ((v8 | (item[v2]._iName[19] << 8)) << 8)) << 8); + } + else + { + cmd.wCI = item[v2]._iCreateInfo; + cmd.dwSeed = item[v2]._iSeed; + cmd.bId = item[v2]._iIdentified; + cmd.bDur = item[v2]._iDurability; + cmd.bMDur = item[v2]._iMaxDur; + cmd.bCh = item[v2]._iCharges; + v9 = item[v2]._iMaxCharges; + v10 = item[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 int 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 NetSendCmdString(int a1, const char *pszStr) +{ + const char *v2; // esi + int v3; // edi + char dwStrLen; // bl + TCmdString cmd; // [esp+Ch] [ebp-54h] + + v2 = pszStr; + v3 = a1; + dwStrLen = strlen(pszStr); + cmd.bCmd = CMD_STRING; + strcpy(cmd.str, v2); + multi_send_msg_packet(v3, &cmd.bCmd, dwStrLen + 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); +#ifdef _DEBUG + case CMD_CHEAT_EXPERIENCE: + return On_CHEAT_EXPERIENCE(v3, pnum); + case CMD_CHEAT_SPELL_LEVEL: + return On_CHEAT_SPELL_LEVEL(v3, pnum); +#else + case CMD_CHEAT_EXPERIENCE: + return On_DEBUG(); + case CMD_CHEAT_SPELL_LEVEL: + return On_DEBUG(); +#endif + 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(&sgRecvBuf[*(unsigned short *)&v7[1].bCmd], &v7[5], *(unsigned short *)&v7[3].bCmd); + sgdwRecvOffset += *(unsigned short *)&v7[3].bCmd; + goto LABEL_100; + } + DeltaImportData(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 DeltaImportData(unsigned char cmd, int recv_offset) +{ + unsigned char v2; // bl + int v3; // esi + void *v4; // eax + void *v5; // eax + + v2 = cmd; + if ( sgRecvBuf[0] ) + encrypt_decompress(&sgRecvBuf[1], recv_offset, 4721); + if ( v2 == CMD_DLEVEL_JUNK ) + { + DeltaImportJunk((int)&sgRecvBuf[1]); + } + else if ( v2 < CMD_DLEVEL_0 || v2 > CMD_DLEVEL_16 ) + { + TermMsg("msg:1"); + } + else + { + v3 = (unsigned char)(v2 - CMD_DLEVEL_0); + v4 = DeltaImportItem(&sgRecvBuf[1], &sgLevels[v3]); + v5 = DeltaImportObject(v4, sgLevels[v3].object); + DeltaImportMonster(v5, sgLevels[v3].monster); + } + ++sgbDeltaChunks; + sgbDeltaChanged = 1; +} +// 67618C: using guessed type char sgbDeltaChanged; +// 67618D: using guessed type char sgbDeltaChunks; + +//----- (0043D6BA) -------------------------------------------------------- +void *__fastcall DeltaImportItem(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 DeltaImportObject(void *src, void *dst) +{ + char *v2; // esi + + v2 = (char *)src; + memcpy(dst, src, 0x7Fu); + return v2 + 127; +} + +//----- (0043D709) -------------------------------------------------------- +void *__fastcall DeltaImportMonster(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 DeltaImportJunk(int a1) +{ + _BYTE *v1; // ebx + int v2; // edi + DJunk *v3; // esi + char result; // al + MultiQuests *v5; // esi + unsigned char *v6; // edi + int *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 ( *(_BYTE *)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 += 5; + v6 += 24; + } + while ( (signed int)v7 < (signed int)&questlist[16]._qflags ); + 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 *pszFmt, ...) +{ + DWORD v1; // eax + char v2[256]; // [esp+0h] [ebp-100h] + va_list va; // [esp+10Ch] [ebp+Ch] + + va_start(va, pszFmt); + v1 = GetTickCount(); + if ( v1 - msg_err_timer >= 5000 ) + { + msg_err_timer = v1; + vsprintf(v2, pszFmt, 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 v4; // edx + int v5; // edx + int v7; // edi + unsigned char v8; // al + int v9; // edx + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + if ( i_own_level(plr[pnum].plrlevel) ) + { + _LOWORD(v4) = v2->wCI; + if ( GetItemRecord(v2->dwSeed, v4, (unsigned short)v2->wIndx) ) + { + _LOWORD(v5) = v2->wCI; + v7 = FindGetItem((unsigned short)v2->wIndx, v5, v2->dwSeed); + v8 = v2->bPnum; + if ( v7 == -1 ) + { + if ( !NetSendCmdReq2(CMD_REQUESTGITEM, myplr, v8, v2) ) + 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 + unsigned 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[4]._pLvlChanging ); + return v1 == myplr; +} +// 676194: using guessed type char gbBufferMsgs; + +//----- (0043DB2D) -------------------------------------------------------- +int __fastcall On_GETITEM(struct TCmdGItem *pCmd, int pnum) +{ + struct TCmdGItem *v2; // esi + int v4; // edi + 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 + { + v4 = FindGetItem((unsigned short)pCmd->wIndx, pCmd->wCI, pCmd->dwSeed); + if ( !delta_get_item(v2, v2->bLevel) ) + { + 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) -------------------------------------------------------- +bool __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 v4; // edx + int v5; // edx + int v7; // zf + unsigned char v8; // al + int v9; // edx + + v2 = pCmd; + if ( gbBufferMsgs != 1 ) + { + if ( i_own_level(plr[pnum].plrlevel) ) + { + _LOWORD(v4) = v2->wCI; + if ( GetItemRecord(v2->dwSeed, v4, (unsigned short)v2->wIndx) ) + { + _LOWORD(v5) = v2->wCI; + v7 = FindGetItem((unsigned short)v2->wIndx, v5, v2->dwSeed); + v8 = v2->bPnum; + if ( v7 == -1 ) + { + if ( !NetSendCmdReq2(CMD_REQUESTAGITEM, myplr, v8, v2) ) + 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 + 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); + if ( !delta_get_item(v2, v2->bLevel) ) + { + 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, item[v8]._ix, item[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, item[v6]._ix, item[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(&item[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 == MIS_GOLEM && 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, + MIS_GOLEM, + 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, CMD_OPENDOOR, (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, CMD_CLOSEDOOR, (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, CMD_OPERATEOBJ, (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, CMD_PLROPOBJ, (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 ) + { + plr[v4].plractive = 1; + ++gbActivePlayers; + EventPlrMsg("Player '%s' (level %d) just joined the game", plr[pnum]._pName, plr[v4]._pLevel); + } + if ( plr[v4].plractive ) + { + 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]._pDWidth; + v7 = plr[v4]._pDAnim[0]; + plr[v4]._pmode = PM_DEATH; + NewPlrAnim(v2, v7, plr[v4]._pDFrames, 1, v6); + 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) == MIS_TOWN + && *(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 ) + { + 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 == MIS_MANASHIELD && missile[v5]._misource == v2 ) + { + ClearMissileSpot(missileactive[i]); + DeleteMissile(v4, i); + } + } + } + return 1; +} +// 676194: using guessed type char gbBufferMsgs; + +#ifdef _DEBUG +int __fastcall On_CHEAT_EXPERIENCE(struct TCmd *pCmd, int pnum) +{ + if ( gbBufferMsgs == 1 ) + { + msg_send_packet(pnum, pCmd, 1); + } + else if ( plr[pnum]._pLevel < 50 ) + { + plr[pnum]._pExperience = plr[pnum]._pNextExper; + NextPlrLevel(pnum); + } + return 1; +} + +int __fastcall On_CHEAT_SPELL_LEVEL(struct TCmd *pCmd, int pnum) +{ + if ( gbBufferMsgs == 1 ) + msg_send_packet(pnum, pCmd, 1); + else + plr[pnum]._pSplLvl[plr[pnum]._pRSpell]++; + + return 1; +} +#endif + +//----- (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; diff --git a/Source/msg.h b/Source/msg.h new file mode 100644 index 0000000..1382a4f --- /dev/null +++ b/Source/msg.h @@ -0,0 +1,171 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//msg +extern int sgdwOwnerWait; // weak +extern int msg_cpp_init_value; // weak +extern int sgdwRecvOffset; // idb +extern int sgnCurrMegaPlayer; // weak +extern DLevel sgLevels[17]; +extern char sbLastCmd; // weak +extern TMegaPkt *sgpCurrPkt; +extern char sgRecvBuf[4722]; +extern unsigned char sgbRecvCmd; // idb +extern LocalLevel sgLocals[17]; +extern DJunk sgJunk[4]; +extern TMegaPkt *sgpMegaPkt; +extern char sgbDeltaChanged; // weak +extern char sgbDeltaChunks; // weak +extern int deltaload; // weak +extern char gbBufferMsgs; // weak +extern int dword_676198; // weak +extern int msg_err_timer; // weak + +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 DeltaExportData(int pnum); +void *__fastcall DeltaExportItem(void *dst, void *src); +void *__fastcall DeltaExportObject(void *dst, void *src); +void *__fastcall DeltaExportMonster(void *dst, void *src); +char *__fastcall DeltaExportJunk(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, int 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, int 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); +bool __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 int dwDam); +void __fastcall NetSendCmdString(int a1, const char *pszStr); +void __fastcall RemovePlrPortal(int pnum); +int __fastcall ParseCmd(int pnum, TCmd *pCmd); +void __fastcall DeltaImportData(unsigned char cmd, int recv_offset); +void *__fastcall DeltaImportItem(void *src, void *dst); +void *__fastcall DeltaImportObject(void *src, void *dst); +void *__fastcall DeltaImportMonster(void *src, void *dst); +char __fastcall DeltaImportJunk(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 *pszFmt, ...); +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); +bool __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); +#ifdef _DEBUG +int __fastcall On_CHEAT_EXPERIENCE(struct TCmd *pCmd, int pnum); +int __fastcall On_CHEAT_SPELL_LEVEL(struct TCmd *pCmd, int pnum); +#endif +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); + +/* data */ + +extern int msg_inf; // weak diff --git a/Source/msgcmd.cpp b/Source/msgcmd.cpp new file mode 100644 index 0000000..963d856 --- /dev/null +++ b/Source/msgcmd.cpp @@ -0,0 +1,296 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int msgcmd_cpp_init_value; // weak +ChatCmd sgChat_Cmd; +int sgdwMsgCmdTimer; + +int msgcmd_inf = 0x7F800000; // weak + +//----- (0043F84E) -------------------------------------------------------- +struct msgcmd_cpp_init_1 +{ + msgcmd_cpp_init_1() + { + msgcmd_cpp_init_value = msgcmd_inf; + } +} _msgcmd_cpp_init_1; +// 47F150: using guessed type int msgcmd_inf; +// 6761A0: using guessed type int msgcmd_cpp_init_value; + +//----- (0043F859) -------------------------------------------------------- +struct msgcmd_cpp_init_2 +{ + msgcmd_cpp_init_2() + { + msgcmd_init_event(); + msgcmd_cleanup_chatcmd_atexit(); + } +} _msgcmd_cpp_init_2; + +//----- (0043F863) -------------------------------------------------------- +void __cdecl msgcmd_init_event() +{ + msgcmd_init_chatcmd(&sgChat_Cmd); +} + +//----- (0043F86D) -------------------------------------------------------- +void __cdecl msgcmd_cleanup_chatcmd_atexit() +{ + atexit(msgcmd_cleanup_chatcmd); +} + +//----- (0043F879) -------------------------------------------------------- +void __cdecl msgcmd_cleanup_chatcmd() +{ + msgcmd_cleanup_chatcmd_1(&sgChat_Cmd); + msgcmd_cleanup_extern_msg(sgChat_Cmd.extern_msgs); +} + +//----- (0043F88D) -------------------------------------------------------- +void __cdecl msgcmd_cmd_cleanup() +{ + msgcmd_free_event(&sgChat_Cmd); +} + +//----- (0043F897) -------------------------------------------------------- +void __cdecl msgcmd_send_chat() +{ + ServerCommand *v0; // esi + int v1; // eax + return; /* fix this */ + if ( (_DWORD)sgChat_Cmd.extern_msgs[1] > 0 ) + { + v0 = sgChat_Cmd.extern_msgs[1]; + v1 = GetTickCount(); + if ( (unsigned int)(v1 - sgdwMsgCmdTimer) >= 2000 ) + { + sgdwMsgCmdTimer = v1; + SNetSendServerChatCommand(v0->command); + msgcmd_delete_server_cmd_W(&sgChat_Cmd, v0); + } + } +} + +//----- (0043F8D4) -------------------------------------------------------- +bool __fastcall msgcmd_add_server_cmd_W(char *chat_message) +{ + if ( *chat_message != '/' ) + return 0; + msgcmd_add_server_cmd(chat_message); + return 1; +} + +//----- (0043F8E5) -------------------------------------------------------- +void __fastcall msgcmd_add_server_cmd(char *command) +{ + char *v1; // edi + size_t v2; // eax + int v3; // edx + size_t v4; // esi + ChatCmd *v5; // eax + + v1 = command; + v2 = strlen(command); + if ( v2 ) + { + v4 = v2 + 1; + if ( v2 + 1 <= 0x80 ) + { + v5 = msgcmd_alloc_event(&sgChat_Cmd, v3, 2, 0, 0); + memcpy(&v5->extern_msgs[1], v1, v4); + } + } +} + +//----- (0043F920) -------------------------------------------------------- +void __fastcall msgcmd_init_chatcmd(ChatCmd *chat_cmd) +{ + ServerCommand **v1; // edx + + v1 = chat_cmd->extern_msgs; + *v1 = 0; + v1[1] = 0; + *v1 = (ServerCommand *)v1; + chat_cmd->next = 0; + chat_cmd->extern_msgs[1] = (ServerCommand *)~(unsigned int)chat_cmd->extern_msgs; +} + +//----- (0043F936) -------------------------------------------------------- +void __fastcall msgcmd_free_event(ChatCmd *a1) +{ + int v1; // edx + ChatCmd *v2; // edi + ChatCmd *v3; // esi + + v2 = a1; + while ( 1 ) + { + v3 = (ChatCmd *)v2->extern_msgs[1]; + if ( (signed int)v3 <= 0 ) + break; + msgcmd_remove_event(v3, v1); + SMemFree(v3, ".?AUEXTERNMESSAGE@@", -2, 0); + } +} + +//----- (0043F95E) -------------------------------------------------------- +bool __fastcall msgcmd_delete_server_cmd_W(ChatCmd *cmd, ServerCommand *extern_msg) +{ + char *v2; // eax + ServerCommand *v3; // eax + bool v4; // si + ChatCmd *ptr; // [esp+Ch] [ebp+4h] + + v2 = (char *)ptr; + if ( !ptr ) + v2 = (char *)cmd->extern_msgs; + v3 = (ServerCommand *)*((_DWORD *)v2 + 1); + if ( (signed int)v3 > 0 ) + v4 = (char)v3; + else + v4 = 0; + msgcmd_remove_event(ptr, (int)extern_msg); + SMemFree(ptr, ".?AUEXTERNMESSAGE@@", -2, 0); + return v4; +} + +//----- (0043F999) -------------------------------------------------------- +ChatCmd *__fastcall msgcmd_alloc_event(ChatCmd *a1, int a2, int a3, int a4, int a5) +{ + int v5; // eax + ChatCmd *v6; // edi + ChatCmd *v7; // eax + int v8; // edx + ChatCmd *v9; // esi + + v5 = a5; + _LOBYTE(v5) = a5 | 8; + v6 = a1; + v7 = (ChatCmd *)SMemAlloc(a4 + 136, ".?AUEXTERNMESSAGE@@", -2, v5); + if ( v7 ) + { + v7->next = 0; + v7->extern_msgs[0] = 0; + v9 = v7; + } + else + { + v9 = 0; + } + if ( a3 ) + msgcmd_event_type(v6, v8, (int *)v9, a3, 0); + return v9; +} + +//----- (0043F9E5) -------------------------------------------------------- +void __fastcall msgcmd_remove_event(ChatCmd *a1, int a2) +{ + ServerCommand **v2; // esi + + v2 = (ServerCommand **)a1; + msgcmd_cleanup_extern_msg((ServerCommand **)a1); + msgcmd_cleanup_extern_msg(v2); + if ( a2 & 1 ) + { + if ( v2 ) + SMemFree(v2, "delete", -1, 0); + } +} + +//----- (0043FA14) -------------------------------------------------------- +void __fastcall msgcmd_event_type(ChatCmd *a1, int a2, int *a3, int a4, int a5) +{ + ChatCmd *v5; // edi + int *v6; // esi + int *v7; // eax + int v8; // ecx + int v9; // edx + int v10; // ecx + int v11; // edx + + v5 = a1; + v6 = a3; + if ( !a3 ) + v6 = (int *)a1->extern_msgs; + if ( *v6 ) + msgcmd_cleanup_extern_msg((ServerCommand **)v6); + v7 = (int *)a5; + if ( !a5 ) + v7 = (int *)v5->extern_msgs; + if ( a4 == 1 ) + { + *v6 = (int)v7; + v6[1] = v7[1]; + v9 = v7[1]; + v10 = (int)v5->next; + if ( v9 > 0 ) + { + if ( v10 < 0 ) + v10 = (int)v7 - *(_DWORD *)(*v7 + 4); + v11 = v10 + v9; + } + else + { + v11 = ~v9; + } + *(_DWORD *)v11 = (unsigned int)v6; + v7[1] = (int)a3; + } + else if ( a4 == 2 ) + { + v8 = *v7; + *v6 = *v7; + v6[1] = *(_DWORD *)(v8 + 4); + *(_DWORD *)(v8 + 4) = (unsigned int)a3; + *v7 = (int)v6; + } +} + +//----- (0043FA85) -------------------------------------------------------- +void __fastcall msgcmd_cleanup_chatcmd_1(ChatCmd *a1) +{ + ChatCmd *v1; // esi + ServerCommand **v2; // ecx + + v1 = a1; + while ( 1 ) + { + v2 = (ServerCommand **)v1->extern_msgs[1]; + if ( (signed int)v2 <= 0 ) + break; + msgcmd_cleanup_extern_msg(v2); + } +} + +//----- (0043FA98) -------------------------------------------------------- +void __fastcall msgcmd_cleanup_extern_msg(ServerCommand **extern_msgs) +{ + ServerCommand *v1; // esi + signed int v2; // edx + int v3; // edx + + v1 = *extern_msgs; + if ( *extern_msgs ) + { + v2 = (signed int)extern_msgs[1]; + if ( v2 > 0 ) + v3 = (int)extern_msgs + v2 - v1->field_4; + else + v3 = ~v2; + *(_DWORD *)v3 = (unsigned int)v1; + (*extern_msgs)->field_4 = (int)extern_msgs[1]; + *extern_msgs = 0; + extern_msgs[1] = 0; + } +} diff --git a/Source/msgcmd.h b/Source/msgcmd.h new file mode 100644 index 0000000..a2ae192 --- /dev/null +++ b/Source/msgcmd.h @@ -0,0 +1,37 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//msgcmd +extern int msgcmd_cpp_init_value; // weak +extern ChatCmd sgChat_Cmd; +extern int sgdwMsgCmdTimer; + +void __cdecl msgcmd_cpp_init_1(); +void __cdecl msgcmd_cpp_init_2(); +void __cdecl msgcmd_init_event(); +void __cdecl msgcmd_cleanup_chatcmd_atexit(); +void __cdecl msgcmd_cleanup_chatcmd(); +void __cdecl msgcmd_cmd_cleanup(); +void __cdecl msgcmd_send_chat(); +bool __fastcall msgcmd_add_server_cmd_W(char *chat_message); +void __fastcall msgcmd_add_server_cmd(char *command); +void __fastcall msgcmd_init_chatcmd(ChatCmd *chat_cmd); +void __fastcall msgcmd_free_event(ChatCmd *a1); +bool __fastcall msgcmd_delete_server_cmd_W(ChatCmd *cmd, ServerCommand *extern_msg); +ChatCmd *__fastcall msgcmd_alloc_event(ChatCmd *a1, int a2, int a3, int a4, int a5); +void __fastcall msgcmd_remove_event(ChatCmd *a1, int a2); +void __fastcall msgcmd_event_type(ChatCmd *a1, int a2, int *a3, int a4, int a5); +void __fastcall msgcmd_cleanup_chatcmd_1(ChatCmd *a1); +void __fastcall msgcmd_cleanup_extern_msg(ServerCommand **extern_msgs); + +/* data */ + +extern int msgcmd_inf; // weak diff --git a/Source/multi.cpp b/Source/multi.cpp new file mode 100644 index 0000000..e2b0b98 --- /dev/null +++ b/Source/multi.cpp @@ -0,0 +1,1208 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +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 multi_inf = 0x7F800000; // weak +event_type event_types[3] = +{ + EVENT_TYPE_PLAYER_LEAVE_GAME, + EVENT_TYPE_PLAYER_CREATE_GAME, + EVENT_TYPE_PLAYER_MESSAGE +}; + +//----- (0043FAC9) -------------------------------------------------------- +struct multi_cpp_init +{ + multi_cpp_init() + { + multi_cpp_init_value = multi_inf; + } +} _multi_cpp_init; +// 47F154: using guessed type int multi_inf; +// 678620: using guessed type int multi_cpp_init_value; + +//----- (0043FAD4) -------------------------------------------------------- +void __fastcall multi_msg_add(unsigned 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 + TPkt pkt; // [esp+8h] [ebp-200h] + + v2 = packet; + v3 = dwSize; + NetRecvPlrData(&pkt); + pkt.hdr.wLen = v3 + 19; + memcpy(pkt.body, v2, v3); + if ( !SNetSendMessage(myplr, &pkt.hdr, (unsigned short)pkt.hdr.wLen) ) + 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 + unsigned char *v5; // eax + TSyncHeader *v6; // eax + int v7; // eax + int v8; // 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; + if ( !SNetSendMessage(-2, &pkt.hdr, v8) ) + nthread_terminate_game("SNetSendMessage"); + } +} +// 678628: using guessed type int dword_678628; +// 679760: using guessed type int gdwNormalMsgSize; + +//----- (0043FD27) -------------------------------------------------------- +unsigned char *__fastcall multi_recv_packet(void *packet, unsigned char *a2, int *a3) +{ + char *v3; // esi + unsigned char *result; // eax + char *v5; // ebx + size_t v6; // edi + char *v7; // ebx + unsigned 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, unsigned char *a2, unsigned char len) +{ + //const void *v3; // edx + signed int v4; // ebx + unsigned int v5; // edi + TPkt pkt; // [esp+Ch] [ebp-204h] + int v8; // [esp+20Ch] [ebp-4h] + + v8 = a1; + NetRecvPlrData(&pkt); + pkt.hdr.wLen = len + 19; + memcpy(pkt.body, a2, len); + v4 = 1; + v5 = 0; + while ( 1 ) + { + if ( v4 & v8 ) + { + if ( !SNetSendMessage(v5, &pkt.hdr, len + 19) && SErrGetLastError() != STORM_ERROR_INVALID_PLAYER ) + 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_parse_turn(v0, *(_DWORD *)glpMsgTbl[v0]); + } + ++v0; + } + while ( v0 < 4 ); +} + +//----- (0043FE3D) -------------------------------------------------------- +void __fastcall multi_parse_turn(int pnum, int turn) +{ + int v2; // esi + unsigned int v3; // esi + + v2 = turn; + if ( turn < 0 ) + multi_handle_turn_upper_bit(pnum); + v3 = v2 & 0x7FFFFFFF; + if ( sgbSentThisCycle < gdwTurnsInTransit + v3 ) + { + if ( v3 >= 0x7FFFFFFF ) + v3 = (unsigned short)v3; + sgbSentThisCycle = v3 + gdwTurnsInTransit; + sgdwGameLoops = 4 * v3 * (unsigned char)byte_679704; + } +} +// 679704: using guessed type char byte_679704; +// 679738: using guessed type int gdwTurnsInTransit; + +//----- (0043FE85) -------------------------------------------------------- +void __fastcall multi_handle_turn_upper_bit(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 ) + { + 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; + 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 recieved; // [esp+4h] [ebp-4h] + + if ( gbGameDestroyed ) + { + gbRunGame = 0; + return 0; + } + v0 = 0; + do + { + if ( sgbSendDeltaTbl[v0] ) + { + sgbSendDeltaTbl[v0] = 0; + DeltaExportData(v0); + } + ++v0; + } + while ( v0 < 4 ); + sgbSentThisCycle = nthread_send_and_recv_turn(sgbSentThisCycle, 1); + if ( !nthread_recv_turns(&recieved) ) + { + multi_begin_timeout(); + return 0; + } + sgbTimeout = 0; + if ( 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)&monster[200]._mAISeed ); +} + +//----- (00440093) -------------------------------------------------------- +void __cdecl multi_begin_timeout() +{ + unsigned char bGroupPlayers; // bl + signed int v1; // eax + signed int nLowestActive; // esi + signed int nLowestPlayer; // edi + signed int v4; // eax + int v5; // edx + unsigned char v6; // [esp+Fh] [ebp-1h] + + bGroupPlayers = 0; +#ifdef _DEBUG + if ( sgbTimeout && !debug_mode_key_i ) +#else + if ( sgbTimeout ) +#endif + { + v1 = GetTickCount() - sglTimeoutStart; + if ( v1 <= 20000 ) + { + if ( v1 >= 10000 ) + { + v6 = 0; + nLowestActive = -1; + nLowestPlayer = -1; + v4 = 0; + do + { + v5 = player_state[v4]; + if ( v5 & 0x10000 ) + { + if ( nLowestPlayer == -1 ) + nLowestPlayer = v4; + if ( v5 & 0x40000 ) + { + ++bGroupPlayers; + if ( nLowestActive == -1 ) + nLowestActive = v4; + } + else + { + ++v6; + } + } + ++v4; + } + while ( v4 < 4 ); + if ( bGroupPlayers >= v6 && (bGroupPlayers != v6 || nLowestPlayer == nLowestActive) ) + { + if ( nLowestActive == 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 + unsigned 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_process_tmsgs(); + //_LOBYTE(v0) = SNetReceiveMessage((int *)arglist, (char **)&pkt, &len); + if ( SNetReceiveMessage((int *)arglist, (char **)&pkt, &len) ) + { + 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 && 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 ( SNetReceiveMessage((int *)arglist, (char **)&pkt, &len) ); + } + if ( SErrGetLastError() != STORM_ERROR_NO_MESSAGES_WAITING ) + 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_process_tmsgs() +{ + 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 *pbSrc, int dwLen) +{ + unsigned int v4; // edi + short v5; // si + unsigned short dwBody; // ax + TPkt pkt; // [esp+Ch] [ebp-208h] + int pnuma; // [esp+20Ch] [ebp-8h] + int v10; // [esp+210h] [ebp-4h] + + v4 = dwLen; + _LOBYTE(v10) = a2; + pnuma = pnum; + v5 = 0; + while ( v4 ) + { + pkt.hdr.wCheck = 'ip'; + pkt.body[0] = v10; + dwBody = 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 ) + dwBody = v4; + *(_WORD *)&pkt.body[3] = dwBody; + memcpy(&pkt.body[5], pbSrc, dwBody); + pkt.hdr.wLen = *(_WORD *)&pkt.body[3] + 24; + if ( !SNetSendMessage(pnuma, &pkt.hdr, *(unsigned short *)&pkt.body[3] + 24) ) + { + nthread_terminate_game("SNetSendMessage2"); + return; + } + pbSrc = (char *)pbSrc + *(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_cmd_cleanup(); + if ( (unsigned char)gbMaxPlayers > 1u ) + Sleep(2000); + } +} +// 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 + { + v4 = (int)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 *pEvt) +{ + int v1; // ecx + int *v2; // eax + int *v3; // eax + + switch ( pEvt->eventid ) + { + case EVENT_TYPE_PLAYER_CREATE_GAME: + v3 = (int *)pEvt->data; + sgGameInitInfo.dwSeed = *v3; + _LOBYTE(sgGameInitInfo.bDiff) = *((_BYTE *)v3 + 4); + sgbPlayerTurnBitTbl[pEvt->playerid] = 1; + break; + case EVENT_TYPE_PLAYER_LEAVE_GAME: + v1 = 0; + sgbPlayerLeftGameTbl[pEvt->playerid] = 1; + sgbPlayerTurnBitTbl[pEvt->playerid] = 0; + v2 = (int *)pEvt->data; + if ( v2 && pEvt->databytes >= 4u ) + v1 = *v2; + sgdwPlayerLeftReasonTbl[pEvt->playerid] = v1; + if ( v1 == 0x40000004 ) + gbSomebodyWonGameKludge = 1; + sgbSendDeltaTbl[pEvt->playerid] = 0; + dthread_remove_player(pEvt->playerid); + if ( (unsigned char)gbDeltaSender == pEvt->playerid ) + gbDeltaSender = 4; + break; + case EVENT_TYPE_PLAYER_MESSAGE: + ErrorPlrMsg((char *)pEvt->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 + 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] + unsigned 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 = gszVersionNumber; + 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; + UiData.profilegetstring = UiProfileGetString(); + 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(0); /* 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 = 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(GAMEINFO_NAME, szPlayerName, 128, len); + if ( !SNetGetGameInfo(GAMEINFO_NAME, szPlayerName, 128, &len) ) + nthread_terminate_game("SNetGetGameInfo1"); + //_LOBYTE(v10) = SNetGetGameInfo(GAMEINFO_PASSWORD, szPlayerDescript, 128, len); + if ( !SNetGetGameInfo(GAMEINFO_PASSWORD, szPlayerDescript, 128, &len) ) + 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 x; // ecx + int y; // edx + + if ( !leveldebug || (unsigned char)gbMaxPlayers > 1u ) + { + 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; +} +// 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 ( SNetInitializeProvider(0, client_info, user_info, ui_info, &fileinfo) ) + { + ui_info = 0; + //_LOBYTE(v5) = SNetCreateGame("local", "local", "local", 0, (char *)&sgGameInitInfo.dwSeed, 8, 1, "local", "local", (int *)&ui_info); + if ( !SNetCreateGame("local", "local", "local", 0, (char *)&sgGameInitInfo.dwSeed, 8, 1, "local", "local", (int *)&ui_info) ) + { + 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() != STORM_ERROR_REQUIRES_UPGRADE || !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 = 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]._pDWidth; + v10 = plr[v6]._pDAnim[0]; + plr[v6]._pmode = 8; + NewPlrAnim(v3, v10, plr[v6]._pDFrames, 1, v9); + 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; diff --git a/Source/multi.h b/Source/multi.h new file mode 100644 index 0000000..39edc66 --- /dev/null +++ b/Source/multi.h @@ -0,0 +1,80 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//multi +extern char gbSomebodyWonGameKludge; // weak +extern char pkdata_6761C0[4100]; +extern char szPlayerDescript[128]; +extern short sgwPackPlrOffsetTbl[4]; +extern PkPlayerStruct pkplr[4]; +extern char sgbPlayerTurnBitTbl[4]; +extern char sgbPlayerLeftGameTbl[4]; +extern int multi_cpp_init_value; // weak +extern int sgbSentThisCycle; // idb +extern int dword_678628; // weak +extern char gbActivePlayers; // weak +extern char gbGameDestroyed; // weak +extern char sgbSendDeltaTbl[4]; +extern _gamedata sgGameInitInfo; +extern char byte_678640; // weak +extern int sglTimeoutStart; // weak +extern int sgdwPlayerLeftReasonTbl[4]; +extern char pkdata_678658[4100]; +extern unsigned int sgdwGameLoops; // idb +extern char gbMaxPlayers; // weak +extern char sgbTimeout; // weak +extern char szPlayerName[128]; +extern char gbDeltaSender; // weak +extern int sgbNetInited; // weak +extern int player_state[4]; + +void __cdecl multi_cpp_init(); +void __fastcall multi_msg_add(unsigned 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); +unsigned char *__fastcall multi_recv_packet(void *packet, unsigned char *a2, int *a3); +void __fastcall multi_send_msg_packet(int a1, unsigned char *a2, unsigned char len); +void __cdecl multi_msg_countdown(); +void __fastcall multi_parse_turn(int pnum, int turn); +void __fastcall multi_handle_turn_upper_bit(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_process_tmsgs(); +void __fastcall multi_send_zero_packet(int pnum, char a2, void *pbSrc, int dwLen); +void __cdecl NetClose(); +char __fastcall multi_event_handler(int a1); +void __stdcall multi_handle_events(_SNETEVENT *pEvt); +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); + +/* data */ + +extern int multi_inf; // weak +extern event_type event_types[3]; diff --git a/Source/nthread.cpp b/Source/nthread.cpp new file mode 100644 index 0000000..88eae9a --- /dev/null +++ b/Source/nthread.cpp @@ -0,0 +1,366 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int nthread_cpp_init_value; // weak +char byte_679704; // weak +int gdwMsgLenTbl[4]; +static CRITICAL_SECTION sgMemCrit; +int gdwDeltaBytesSec; // weak +char byte_679734; // weak +int gdwTurnsInTransit; // weak +int glpMsgTbl[4]; +unsigned int glpNThreadId; +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 nthread_inf = 0x7F800000; // weak + +/* rdata */ +static HANDLE sghThread = (HANDLE)0xFFFFFFFF; // idb + +//----- (00440DB3) -------------------------------------------------------- +struct nthread_cpp_init_1 +{ + nthread_cpp_init_1() + { + nthread_cpp_init_value = nthread_inf; + } +} _nthread_cpp_init_1; +// 47F164: using guessed type int nthread_inf; +// 679700: using guessed type int nthread_cpp_init_value; + +//----- (00440DBE) -------------------------------------------------------- +struct nthread_cpp_init_2 +{ + nthread_cpp_init_2() + { + nthread_init_mutex(); + nthread_cleanup_mutex_atexit(); + } +} _nthread_cpp_init_2; + +//----- (00440DC8) -------------------------------------------------------- +void __cdecl nthread_init_mutex() +{ + InitializeCriticalSection(&sgMemCrit); +} + +//----- (00440DD4) -------------------------------------------------------- +void __cdecl nthread_cleanup_mutex_atexit() +{ + atexit(nthread_cleanup_mutex); +} + +//----- (00440DE0) -------------------------------------------------------- +void __cdecl nthread_cleanup_mutex() +{ + DeleteCriticalSection(&sgMemCrit); +} + +//----- (00440DEC) -------------------------------------------------------- +void __fastcall nthread_terminate_game(char *pszFcn) +{ + char *v1; // esi + int v2; // eax + char *v3; // eax + + v1 = pszFcn; + v2 = SErrGetLastError(); + if ( v2 != STORM_ERROR_INVALID_PLAYER ) + { + if ( v2 == STORM_ERROR_GAME_TERMINATED || v2 == STORM_ERROR_NOT_IN_GAME ) + { + 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 + char *v5; // ecx + int v6; // eax + int turn; // [esp+Ch] [ebp-8h] + int turns; // [esp+10h] [ebp-4h] + + v2 = turn_delta; + v3 = cur_turn; + if ( SNetGetTurnsInTransit(&turns) ) + { + if ( turns >= (unsigned int)gdwTurnsInTransit ) + return v3; + while ( 1 ) + { + ++turns; + v6 = dword_679754 | v3 & 0x7FFFFFFF; + dword_679754 = 0; + turn = v6; + if ( !SNetSendTurn((char *)&turn, 4) ) + 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) -------------------------------------------------------- +int __fastcall nthread_recv_turns(int *pfSendAsync) +{ + int *v1; // esi + bool v2; // zf + + v1 = pfSendAsync; + *pfSendAsync = 0; + if ( --sgbPacketCountdown ) + { + dword_679764 += 50; + return 1; + } + v2 = sgbSyncCountdown-- == 1; + sgbPacketCountdown = byte_679704; + if ( !v2 ) + goto LABEL_11; + if ( SNetReceiveTurns(0, 4, (char **)glpMsgTbl, (unsigned int *)gdwMsgLenTbl, (unsigned long *)player_state) ) + { + if ( !byte_679758 ) + { + byte_679758 = 1; + dword_679764 = GetTickCount(); + } + sgbSyncCountdown = 4; + multi_msg_countdown(); +LABEL_11: + *v1 = 1; + dword_679764 += 50; + return 1; + } + if ( SErrGetLastError() != STORM_ERROR_NO_MESSAGES_WAITING ) + nthread_terminate_game("SNetReceiveTurns"); + byte_679758 = 0; + sgbSyncCountdown = 1; + sgbPacketCountdown = 1; + return 0; +} +// 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 + 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; + if ( !SNetGetProviderCaps(&caps) ) + { + 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(&sgMemCrit); + byte_679734 = 1; + sghThread = (HANDLE)_beginthreadex(NULL, 0, nthread_handler, NULL, 0, &glpNThreadId); + if ( sghThread == (HANDLE)-1 ) + { + v6 = GetLastErr(); + TermMsg("nthread2:\n%s", v6); + } + SetThreadPriority(sghThread, THREAD_PRIORITY_HIGHEST); + } +} +// 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) +{ + signed int v1; // esi + int recieved; // [esp+Ch] [ebp-4h] + + if ( byte_679734 ) + { + while ( 1 ) + { + EnterCriticalSection(&sgMemCrit); + if ( !byte_679734 ) + break; + nthread_send_and_recv_turn(0, 0); + if ( nthread_recv_turns(&recieved) ) + v1 = dword_679764 - GetTickCount(); + else + v1 = 50; + LeaveCriticalSection(&sgMemCrit); + if ( v1 > 0 ) + Sleep(v1); + if ( !byte_679734 ) + return 0; + } + LeaveCriticalSection(&sgMemCrit); + } + 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 ( sghThread != (HANDLE)-1 && glpNThreadId != GetCurrentThreadId() ) + { + if ( !sgbThreadIsRunning ) + LeaveCriticalSection(&sgMemCrit); + if ( WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1 ) + { + v0 = GetLastErr(); + TermMsg("nthread3:\n(%s)", v0); + } + CloseHandle(sghThread); + sghThread = (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 bStart) +{ + bool v1; // bl + + v1 = bStart; + if ( sghThread != (HANDLE)-1 ) + { + if ( bStart ) + LeaveCriticalSection(&sgMemCrit); + else + EnterCriticalSection(&sgMemCrit); + 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; diff --git a/Source/nthread.h b/Source/nthread.h new file mode 100644 index 0000000..4a9f0a6 --- /dev/null +++ b/Source/nthread.h @@ -0,0 +1,47 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//nthread +extern int nthread_cpp_init_value; // weak +extern char byte_679704; // weak +extern int gdwMsgLenTbl[4]; +extern int gdwDeltaBytesSec; // weak +extern char byte_679734; // weak +extern int gdwTurnsInTransit; // weak +extern int glpMsgTbl[4]; +extern unsigned int glpNThreadId; +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 __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 *pszFcn); +int __fastcall nthread_send_and_recv_turn(int cur_turn, int turn_delta); +int __fastcall nthread_recv_turns(int *pfSendAsync); +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 bStart); +bool __cdecl nthread_has_500ms_passed(); + +/* data */ + +extern int nthread_inf; // weak diff --git a/Source/objects.cpp b/Source/objects.cpp new file mode 100644 index 0000000..26c0bec --- /dev/null +++ b/Source/objects.cpp @@ -0,0 +1,7489 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +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 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] = +{ + { 1, OFILE_L1BRAZ, 1, 4, 1, 255, 255, 1, 1, 26, 64, 1, 1, 0, 0, 0, 0 }, + { 1, OFILE_L1DOORS, 1, 4, 1, 255, 255, 0, 1, 0, 64, 0, 0, 1, 0, 3, 1 }, + { 1, OFILE_L1DOORS, 1, 4, 1, 255, 255, 0, 2, 0, 64, 0, 0, 1, 0, 3, 1 }, + { 3, OFILE_SKULFIRE, 0, 0, 0, 3, 255, 1, 2, 11, 96, 1, 1, 0, 0, 0, 0 }, + { 1, OFILE_LEVER, 1, 4, 1, 255, 255, 0, 1, 1, 96, 1, 1, 1, 0, 1, 1 }, + { 1, OFILE_CHEST1, 1, 16, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { 1, OFILE_CHEST2, 1, 16, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { 1, OFILE_CHEST3, 1, 16, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { 2, OFILE_L1BRAZ, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 3, OFILE_CANDLE2, 0, 0, 0, 1, 255, 1, 2, 4, 96, 1, 1, 1, 0, 0, 0 }, + { 2, OFILE_L1BRAZ, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 3, OFILE_BANNER, 0, 0, 0, 3, 255, 0, 2, 0, 96, 1, 1, 1, 0, 0, 0 }, + { 3, OFILE_BANNER, 0, 0, 0, 3, 255, 0, 1, 0, 96, 1, 1, 1, 0, 0, 0 }, + { 3, OFILE_BANNER, 0, 0, 0, 3, 255, 0, 3, 0, 96, 1, 1, 1, 0, 0, 0 }, + { 2, OFILE_SKULPILE, 1, 4, 0, 255, 255, 0, 0, 1, 96, 1, 1, 1, 0, 0, 0 }, + { 2, OFILE_L1BRAZ, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, OFILE_L1BRAZ, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, OFILE_L1BRAZ, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, OFILE_L1BRAZ, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, OFILE_L1BRAZ, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 2, OFILE_CRUXSK1, 0, 0, 0, 255, 255, 0, 1, 15, 96, 1, 0, 1, 1, 3, 0 }, + { 2, OFILE_CRUXSK2, 0, 0, 0, 255, 255, 0, 1, 15, 96, 1, 0, 1, 1, 3, 0 }, + { 2, OFILE_CRUXSK3, 0, 0, 0, 255, 255, 0, 1, 15, 96, 1, 0, 1, 1, 3, 0 }, + { 1, OFILE_ROCKSTAN, 5, 5, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 0, 0 }, + { 2, OFILE_ANGEL, 0, 0, 0, 255, 255, 0, 1, 0, 96, 1, 0, 1, 0, 0, 0 }, + { 2, OFILE_BOOK2, 0, 0, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 2, OFILE_BURNCROS, 0, 0, 0, 255, 255, 1, 0, 10, 160, 1, 0, 0, 0, 0, 0 }, + { 2, OFILE_NUDE2, 0, 0, 0, 255, 255, 1, 3, 6, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_SWITCH4, 16, 16, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { 1, OFILE_TNUDEM, 13, 16, 0, 255, 6, 0, 1, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TNUDEM, 13, 16, 0, 6, 6, 0, 2, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TNUDEM, 13, 16, 0, 6, 6, 0, 3, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TNUDEM, 13, 16, 0, 6, 6, 0, 4, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TNUDEW, 13, 16, 0, 6, 6, 0, 1, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TNUDEW, 13, 16, 0, 6, 6, 0, 2, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TNUDEW, 13, 16, 0, 6, 6, 0, 3, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TSOUL, 13, 16, 0, 255, 6, 0, 1, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TSOUL, 13, 16, 0, 255, 6, 0, 2, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TSOUL, 13, 16, 0, 255, 6, 0, 3, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TSOUL, 13, 16, 0, 255, 6, 0, 4, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_TSOUL, 13, 16, 0, 255, 6, 0, 5, 0, 128, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_BOOK2, 6, 6, 0, 255, 255, 0, 4, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_L2DOORS, 5, 8, 2, 255, 255, 0, 1, 0, 64, 0, 0, 1, 0, 3, 1 }, + { 1, OFILE_L2DOORS, 5, 8, 2, 255, 255, 0, 2, 0, 64, 0, 0, 1, 0, 3, 1 }, + { 1, OFILE_WTORCH4, 5, 8, 2, 255, 255, 1, 1, 9, 96, 0, 1, 0, 0, 0, 0 }, + { 1, OFILE_WTORCH3, 5, 8, 2, 255, 255, 1, 1, 9, 96, 0, 1, 0, 0, 0, 0 }, + { 1, OFILE_WTORCH1, 5, 8, 2, 255, 255, 1, 1, 9, 96, 0, 1, 0, 0, 0, 0 }, + { 1, OFILE_WTORCH2, 5, 8, 2, 255, 255, 1, 1, 9, 96, 0, 1, 0, 0, 0, 0 }, + { 1, OFILE_SARC, 1, 4, 1, 255, 255, 0, 1, 5, 128, 1, 1, 1, 0, 3, 1 }, + { 2, OFILE_FLAME1, 1, 4, 1, 255, 255, 0, 1, 20, 96, 0, 1, 1, 0, 0, 0 }, + { 2, OFILE_LEVER, 1, 4, 1, 255, 255, 0, 1, 2, 96, 1, 1, 1, 0, 1, 1 }, + { 2, OFILE_MINIWATR, 1, 4, 1, 255, 255, 1, 1, 10, 64, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_BOOK1, 3, 4, 1, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_TRAPHOLE, 1, 16, 0, 255, 255, 0, 1, 0, 64, 0, 1, 1, 0, 0, 0 }, + { 1, OFILE_TRAPHOLE, 1, 16, 0, 255, 255, 0, 2, 0, 64, 0, 1, 1, 0, 0, 0 }, + { 2, OFILE_BCASE, 0, 0, 0, 255, 255, 0, 1, 0, 96, 1, 0, 1, 0, 0, 0 }, + { 2, OFILE_WEAPSTND, 0, 0, 0, 255, 255, 0, 1, 0, 96, 1, 0, 1, 0, 0, 0 }, + { 1, OFILE_BARREL, 1, 16, 0, 255, 255, 0, 1, 9, 96, 1, 1, 1, 1, 3, 0 }, + { 1, OFILE_BARRELEX, 1, 16, 0, 255, 255, 0, 1, 10, 96, 1, 1, 1, 1, 3, 0 }, + { 3, OFILE_LSHRINEG, 0, 0, 0, 1, 255, 0, 1, 11, 128, 0, 0, 1, 0, 3, 0 }, + { 3, OFILE_RSHRINEG, 0, 0, 0, 1, 255, 0, 1, 11, 128, 0, 0, 1, 0, 3, 0 }, + { 3, OFILE_BOOK2, 0, 0, 0, 3, 255, 0, 4, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 3, OFILE_BCASE, 0, 0, 0, 5, 255, 0, 3, 0, 96, 0, 0, 1, 0, 3, 0 }, + { 3, OFILE_BCASE, 0, 0, 0, 5, 255, 0, 4, 0, 96, 0, 0, 1, 0, 3, 0 }, + { 3, OFILE_BOOK2, 0, 0, 0, 5, 255, 0, 1, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 3, OFILE_CANDLE2, 0, 0, 0, 5, 255, 1, 2, 4, 96, 1, 1, 1, 0, 0, 0 }, + { 3, OFILE_BLOODFNT, 0, 0, 0, 7, 255, 1, 2, 10, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_DECAP, 13, 16, 0, 8, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 0 }, + { 1, OFILE_CHEST1, 1, 16, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { 1, OFILE_CHEST2, 1, 16, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { 1, OFILE_CHEST3, 1, 16, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { 1, OFILE_BOOK1, 7, 7, 2, 255, 8, 0, 1, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_BOOK1, 5, 5, 2, 255, 9, 0, 4, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_PEDISTL, 5, 5, 2, 255, 9, 0, 1, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_L3DOORS, 9, 12, 3, 255, 255, 0, 1, 0, 64, 0, 0, 1, 0, 3, 1 }, + { 1, OFILE_L3DOORS, 9, 12, 3, 255, 255, 0, 2, 0, 64, 0, 0, 1, 0, 3, 1 }, + { 3, OFILE_PFOUNTN, 0, 0, 0, 9, 255, 1, 2, 10, 128, 1, 1, 1, 0, 3, 0 }, + { 3, OFILE_ARMSTAND, 0, 0, 0, 10, 255, 0, 1, 0, 96, 1, 0, 1, 0, 3, 0 }, + { 3, OFILE_ARMSTAND, 0, 0, 0, 10, 255, 0, 2, 0, 96, 1, 0, 1, 0, 0, 0 }, + { 3, OFILE_GOATSHRN, 0, 0, 0, 11, 255, 1, 2, 10, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_CAULDREN, 13, 16, 0, 255, 255, 0, 1, 0, 96, 1, 0, 1, 0, 3, 0 }, + { 3, OFILE_MFOUNTN, 0, 0, 0, 13, 255, 1, 2, 10, 128, 1, 1, 1, 0, 3, 0 }, + { 3, OFILE_TFOUNTN, 0, 0, 0, 14, 255, 1, 2, 4, 128, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_ALTBOY, 0, 0, 1, 255, 15, 0, 1, 0, 128, 1, 1, 1, 0, 0, 0 }, + { 1, OFILE_MCIRL, 0, 0, 1, 255, 15, 0, 1, 0, 96, 0, 1, 1, 0, 0, 0 }, + { 1, OFILE_MCIRL, 0, 0, 1, 255, 15, 0, 1, 0, 96, 0, 1, 1, 0, 0, 0 }, + { 1, OFILE_BKSLBRNT, 4, 12, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_CANDLE2, 2, 12, 0, 255, 15, 1, 2, 4, 96, 1, 1, 1, 0, 0, 0 }, + { 1, OFILE_BOOK1, 13, 13, 4, 255, 11, 0, 4, 0, 96, 1, 1, 1, 0, 3, 0 }, + { 1, OFILE_ARMSTAND, 13, 13, 0, 255, 11, 0, 1, 0, 96, 1, 0, 1, 0, 3, 0 }, + { 2, OFILE_WEAPSTND, 13, 13, 0, 255, 11, 0, 1, 0, 96, 1, 0, 1, 0, 3, 0 }, + { 2, OFILE_BURNCROS, 0, 0, 0, 15, 255, 1, 0, 10, 160, 1, 0, 0, 0, 0, 0 }, + { 2, OFILE_WEAPSTND, 0, 0, 0, 16, 255, 0, 1, 0, 96, 1, 0, 1, 0, 3, 0 }, + { 2, OFILE_WEAPSTND, 0, 0, 0, 16, 255, 0, 2, 0, 96, 1, 0, 1, 0, 0, 0 }, + { 2, OFILE_MUSHPTCH, 0, 0, 0, 255, 1, 0, 1, 0, 96, 1, 1, 1, 0, 3, 1 }, + { 2, OFILE_LZSTAND, 0, 0, 0, 255, 15, 0, 1, 0, 128, 1, 0, 1, 0, 3, 0 }, + { 1, OFILE_DECAP, 9, 9, 3, 255, 255, 0, 2, 0, 96, 1, 1, 1, 0, 1, 0 }, + { 2, OFILE_CHEST3, 0, 0, 0, 255, 255, 0, 1, 0, 96, 1, 1, 1, 0, 1, 1 }, + { -1, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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] = { -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" +}; +unsigned 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 +}; +unsigned 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 +unsigned 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] = +{ + { QUEST_BOOK11, QUEST_BOOK12, QUEST_BOOK13 }, + { QUEST_BOOK21, QUEST_BOOK22, QUEST_BOOK23 }, + { QUEST_BOOK31, QUEST_BOOK32, QUEST_BOOK33 } +}; + +//----- (0044121D) -------------------------------------------------------- +void __cdecl InitObjectGFX() +{ + ObjDataStruct *v0; // eax + char *v1; // esi + unsigned char v2; // cl + int v3; // edx + int i; // eax + char v5; // al + signed int v7; // ebx + char *v8; // ST08_4 + unsigned char *v9; // eax + int v10; // ecx + unsigned char fileload[56]; // [esp+4h] [ebp-58h] + char filestr[32]; // [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 ) + { + if ( QuestStatus(v5) ) + 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(filestr, "Objects\\%s.CEL", v8); + v9 = LoadFileInMem(filestr, 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) -------------------------------------------------------- +bool __fastcall RndLocOk(int xp, int yp) +{ + int v2; // ecx + int v3; // eax + int v4; // eax + bool 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 numobjs; // ebx + int xp; // esi + int yp; // edi + int i; // [esp+8h] [ebp-4h] + + i = 0; + numobjs = min + random(-117, max - min); + if ( numobjs > 0 ) + { + while ( 1 ) + { + do + { + xp = random(-117, 80) + 16; + yp = random(-117, 80) + 16; + } + while ( !RndLocOk(xp - 1, yp - 1) ); + if ( RndLocOk(xp, yp - 1) ) + { + if ( RndLocOk(xp + 1, yp - 1) ) /* check */ + { + if ( RndLocOk(xp - 1, yp) ) + { + if ( RndLocOk(xp, yp) ) + { + if ( RndLocOk(xp + 1, yp) ) + { + if ( RndLocOk(xp - 1, yp + 1) ) + { + if ( RndLocOk(xp, yp + 1) ) + { + if ( RndLocOk(xp + 1, yp + 1) ) + { + AddObject(objtype, xp, yp); + if ( ++i >= numobjs ) + break; + } + } + } + } + } + } + } + } + } + } +} + +//----- (00441477) -------------------------------------------------------- +void __fastcall InitRndLocBigObj(int min, int max, int objtype) +{ + int xp; // edi + int yp; // esi + int numobjs; // [esp+4h] [ebp-8h] + int i; // [esp+8h] [ebp-4h] + + i = 0; + numobjs = min + random(-116, max - min); + if ( numobjs > 0 ) + { + while ( 1 ) + { + do + { + xp = random(-116, 80) + 16; + yp = random(-116, 80) + 16; + } + while ( !RndLocOk(xp - 1, yp - 2) ); + if ( RndLocOk(xp, yp - 2) ) + { + if ( RndLocOk(xp + 1, yp - 2) ) /* check */ + { + if ( RndLocOk(xp - 1, yp - 1) ) + { + if ( RndLocOk(xp, yp - 1) ) + { + if ( RndLocOk(xp + 1, yp - 1) ) + { + if ( RndLocOk(xp - 1, yp) ) + { + if ( RndLocOk(xp, yp) ) + { + if ( RndLocOk(xp + 1, yp) ) + { + if ( RndLocOk(xp - 1, yp + 1) ) + { + if ( RndLocOk(xp, yp + 1) ) + { + if ( RndLocOk(xp + 1, yp + 1) ) + { + AddObject(objtype, xp, yp); + if ( ++i >= numobjs ) + 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)&object[127]._oy ); + 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(OBJ_TORTURE1, v1 - 2, v0 + 1); + AddObject(OBJ_TORTURE3, v1, v0 - 1); + AddObject(OBJ_TORTURE2, v1 - 2, v0 + 3); + AddObject(OBJ_TORTURE4, v1 + 2, v0 - 1); + AddObject(OBJ_TORTURE5, v1 - 2, v0 + 5); + AddObject(OBJ_TNUDEM1, v1 - 1, v0 + 3); + AddObject(OBJ_TNUDEM2, v1 + 2, v0 + 5); + AddObject(OBJ_TNUDEM3, v1, v0); + AddObject(OBJ_TNUDEM4, v1 + 1, v0 + 2); + AddObject(OBJ_TNUDEW1, v1, v0 + 4); + AddObject(OBJ_TNUDEW2, v1, v0 + 1); + AddObject(OBJ_TNUDEW3, 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(OBJ_STORYCANDLE, quests[13]._qtx - 2, quests[13]._qty + 1); + AddObject(OBJ_STORYCANDLE, v0 + 3, v2); + v1 += 2; + AddObject(OBJ_STORYCANDLE, v0 - 1, v1); + AddObject(OBJ_STORYCANDLE, 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 ( QuestStatus(8) ) + AddObject(OBJ_BLINDBOOK, v9, v10); + //_LOBYTE(v14) = QuestStatus(11); + if ( QuestStatus(11) ) + AddObject(OBJ_STEELTOME, v9, v10); + //_LOBYTE(v15) = QuestStatus(9); + if ( QuestStatus(9) ) + { + v9 = 2 * setpc_x + 25; + v10 = 2 * setpc_y + 40; + AddObject(OBJ_BLOODBOOK, 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 + bool 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(OBJ_BARRELEX - (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(OBJ_BARRELEX - (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(OBJ_L1LIGHT, v4, y); + if ( v6 == 44 || v6 == 51 || v6 == 214 ) + AddObject(OBJ_L1LDOOR, v4, y); + if ( v6 == 46 || v6 == 56 ) + AddObject(OBJ_L1RDOOR, 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(OBJ_L2LDOOR, v4, y); + if ( v6 == 17 || v6 == 542 ) + AddObject(OBJ_L2RDOOR, 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(OBJ_L3LDOOR, v4, y); + if ( v6 == 534 ) + AddObject(OBJ_L3RDOOR, v4, y); + ++v4; + v5 += 112; + } + while ( v4 < x2 ); + } + } +} + +//----- (00441B8A) -------------------------------------------------------- +bool __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 = &dObject[0][v0 - 1]; /* &dungeon[39][v0 + 39]; */ + v5 = v7; + do + { + //_LOBYTE(v3) = WallTrapLocOk(v1, v0); + if ( !WallTrapLocOk(v1, v0) ) + goto LABEL_18; + v6 = (*v5)[0]; + if ( (*v5)[0] == 1 ) + { + _LOBYTE(v4) = -111; + if ( random(v4, 3) ) + goto LABEL_18; + AddObject(OBJ_TORCHL2, v1, v0); + } + if ( v6 == 5 ) + { + _LOBYTE(v4) = -111; + if ( random(v4, 3) ) + goto LABEL_18; + AddObject(OBJ_TORCHR2, v1, v0); + } + if ( v6 == 37 ) + { + _LOBYTE(v4) = -111; + if ( random(v4, 10) || *(v2 - 111) ) + goto LABEL_18; + AddObject(OBJ_TORCHL, v1 - 1, v0); + } + if ( v6 == 41 ) + { + _LOBYTE(v4) = -111; + if ( !random(v4, 10) && !*v2 ) + AddObject(OBJ_TORCHR, 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) -------------------------------------------------------- +bool __fastcall TorchLocOK(int xp, int yp) +{ + int v2; // ecx + bool 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 + char *v2; // edi + int v3; // ebx + int v4; // edi + int *j; // eax + //int v6; // eax + char v7; // al + int v8; // edi + int *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 = (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 = &dPiece[v16][v0-1]; !nSolidTable[*i]; i-- ) /* check dpiece */ + --v8; + //_LOBYTE(v10) = TorchLocOK(x, v8); + if ( TorchLocOK(x, v8) && v0 - v8 > 1 ) + { + AddObject(OBJ_TRAPR, 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 ( TorchLocOK(v4, v0) && x - v4 > 1 ) + { + AddObject(OBJ_TRAPL, 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 = (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(OBJ_STORYBOOK, v0, v1); + AddObject(OBJ_STORYCANDLE, v0 - 2, v1 + 1); + AddObject(OBJ_STORYCANDLE, v0 - 2, v1); + AddObject(OBJ_STORYCANDLE, v0 - 1, v1 - 1); + AddObject(OBJ_STORYCANDLE, v0 + 1, v1 - 1); + v4 = v0 + 2; + AddObject(OBJ_STORYCANDLE, v4, v1); + AddObject(OBJ_STORYCANDLE, 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 ( SkipThemeRoom(x, y) ) + { + 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(OBJ_TORTURE5, v3, v1); + } + else + { + AddObject(OBJ_TORTURE2, v3, v1); + } + } + else + { + AddObject(OBJ_TORTURE1, 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, 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); +} + +//----- (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, OBJ_LAZSTAND); + return; + } + } + AddObject(OBJ_LAZSTAND, v0, v1); + AddObject(OBJ_TNUDEM2, v0, v1 + 2); + AddObject(OBJ_STORYCANDLE, v0 + 1, v1 + 2); + AddObject(OBJ_TNUDEM3, v0 + 2, v1 + 2); + AddObject(OBJ_TNUDEW1, v0, v1 - 2); + AddObject(OBJ_STORYCANDLE, v0 + 1, v1 - 2); + AddObject(OBJ_TNUDEW2, v0 + 2, v1 - 2); + v4 = v0 - 1; + AddObject(OBJ_STORYCANDLE, v4, v1 - 1); + AddObject(OBJ_TNUDEW3, v4, v1); + AddObject(OBJ_STORYCANDLE, 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 ( QuestStatus(6) ) + AddTortures(); + //_LOBYTE(v2) = QuestStatus(13); + if ( QuestStatus(13) ) + AddCandles(); + //_LOBYTE(v3) = QuestStatus(7); + if ( QuestStatus(7) ) + AddObject(OBJ_SIGNCHEST, 2 * setpc_x + 26, 2 * setpc_y + 19); + InitRndLocBigObj(10, 15, OBJ_SARC); + AddL1Objs(0, 0, 112, 112); + InitRndBarrels(); + } + if ( leveltype == 2 ) + { + //_LOBYTE(v4) = QuestStatus(0); + if ( QuestStatus(0) ) + InitRndLocObj5x5(1, 1, OBJ_STAND); + //_LOBYTE(v5) = QuestStatus(14); + if ( QuestStatus(14) ) + InitRndLocObj5x5(1, 1, OBJ_BOOK2R); + AddL2Objs(0, 0, 112, 112); + AddL2Torches(); + //_LOBYTE(v6) = QuestStatus(8); + if ( QuestStatus(8) ) + { + v7 = plr[myplr]._pClass; + if ( v7 ) + { + if ( v7 == 1 ) + { + v8 = QUEST_RBLINDING; + } + else + { + v8 = QUEST_MBLINDING; + if ( v7 != 2 ) + v8 = v16; + } + } + else + { + v8 = QUEST_BLINDING; + } + 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 ( QuestStatus(9) ) + { + v11 = plr[myplr]._pClass; + if ( v11 ) + { + if ( v11 == 1 ) + { + v8 = QUEST_RBLOODY; + } + else if ( v11 == 2 ) + { + v8 = QUEST_MBLOODY; + } + } + else + { + v8 = QUEST_BLOODY; + } + quests[9]._qmsg = v8; + AddBookLever(0, 0, 112, 112, setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7, v8); + AddObject(OBJ_PEDISTAL, 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 ( QuestStatus(11) ) + { + v13 = plr[myplr]._pClass; + if ( v13 ) + { + if ( v13 == 1 ) + { + v8 = QUEST_RBLOODWAR; + } + else if ( v13 == 2 ) + { + v8 = QUEST_MBLOODWAR; + } + } + else + { + v8 = QUEST_BLOODWAR; + } + 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 ( QuestStatus(15) && 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 + 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 fileload[56]; // [esp+Ch] [ebp-10Ch] + char filestr[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(fileload, 0, sizeof(fileload)); + InitObjFlag = 1; + if ( AllObjects[0].oload != -1 ) + { + i = 0; + do + { + if ( AllObjects[i].oload == 1 && leveltype == AllObjects[i].olvltype ) + fileload[AllObjects[i].ofindex] = 1; + i++; + } + while ( AllObjects[i].oload != -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 ) + fileload[(char)AllObjects[ObjTypeConv[(unsigned char)*v13]].ofindex] = 1; + v13 += 2; + --v14; + } + while ( v14 ); + } + --v24; + } + while ( v24 ); + } + v15 = 0; + do + { + if ( fileload[v15] ) + { + v16 = ObjMasterLoadList[v15]; + ObjFileList[numobjfiles] = v15; + sprintf(filestr, "Objects\\%s.CEL", v16); + v17 = LoadFileInMem(filestr, 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; + objectavail[-nobjects + 127] = oi; /* *(&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) +{ + object[i]._oVar1 = x1; + object[i]._oVar2 = y1; + object[i]._oVar3 = x2; + object[i]._oVar4 = y2; + object[i]._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 = dPiece[-4][v5 + y]; // *(_DWORD *)&dflags[28][4 * v9 + 32]; /* check */ + } + object[v4]._oVar4 = 0; + object[v4]._oVar1 = v7; + object[v4]._oVar2 = v8; +} + +//----- (00442B2C) -------------------------------------------------------- +void __fastcall AddSCambBook(int i) +{ + object[i]._oVar1 = setpc_x; + object[i]._oVar2 = setpc_y; + object[i]._oVar3 = setpc_w + setpc_x + 1; + object[i]._oVar4 = setpc_h + setpc_y + 1; + object[i]._oVar6 = object[i]._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 == OBJ_L2LDOOR ) + 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 == OBJ_L3LDOOR ) + 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; + dObject[0][v3 + object[v1]._oy - 1] = v2; /* 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) +{ + object[i]._oVar1 = trapid; + object[i]._oVar2 = 0; + object[i]._oVar3 = trapdir; + object[i]._oVar4 = 0; +} +// 679768: using guessed type int trapid; +// 67976C: using guessed type int trapdir; + +//----- (00442D16) -------------------------------------------------------- +void __fastcall AddFlameLvr(int i) +{ + object[i]._oVar1 = trapid; + object[i]._oVar2 = 49; +} +// 679768: using guessed type int trapid; + +//----- (00442D2F) -------------------------------------------------------- +void __fastcall AddTrap(int i) +{ + int mt; // eax + + mt = random(148, currlevel / 3 + 1); + if ( !mt ) + object[i]._oVar3 = 0; + if ( mt == 1 ) + object[i]._oVar3 = 1; + if ( mt == 2 ) + object[i]._oVar3 = 7; + object[i]._oVar4 = 0; +} + +//----- (00442D8A) -------------------------------------------------------- +void __fastcall AddObjLight(int i, int r) +{ + if ( InitObjFlag ) + { + DoLighting(object[i]._ox, object[i]._oy, r, -1); + object[i]._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 slist[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 = &slist[v3]; + *v4 = 0; + } + else + { + v4 = &slist[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 ( !slist[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 bookframe; // eax + int v7; // eax + + SetRndSeed(glSeedTbl[16]); + bookframe = random(0, 3); + + object[i]._oVar1 = bookframe; + if ( currlevel == 4 ) + object[i]._oVar2 = StoryText[bookframe][0]; + if ( currlevel == 8 ) + object[i]._oVar2 = StoryText[bookframe][1]; + if ( currlevel == 12 ) + object[i]._oVar2 = StoryText[bookframe][2]; + object[i]._oVar3 = ((unsigned int)currlevel >> 2) + 3 * bookframe - 1; + v7 = 5 - 2 * bookframe; + object[i]._oAnimFrame = v7; + object[i]._oVar4 = v7 + 1; +} + +//----- (0044308E) -------------------------------------------------------- +void __fastcall AddWeaponRack(int i) +{ + if ( !weaponFlag ) + { + object[i]._oSelFlag = 0; + object[i]._oAnimFlag = 2; + } + object[i]._oRndSeed = GetRndSeed(); +} +// 6AAA50: using guessed type int weaponFlag; + +//----- (004430C0) -------------------------------------------------------- +void __fastcall AddTorturedBody(int i) +{ + object[i]._oRndSeed = GetRndSeed(); + object[i]._oPreFlag = 1; + object[i]._oAnimFrame = random(0, 4) + 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() +{ + int i; // bl + int y; // [esp+0h] [ebp-8h] + int x; // [esp+4h] [ebp-4h] + + if ( nobjects < 127 ) + { + i = objectavail[0]; + GetRndObjLoc(5, &x, &y); + dObject[x + 1][y + 1] = -1 - i; + dObject[x + 2][y + 1] = -1 - i; + dObject[x + 1][y + 2] = -1 - i; + AddObject(OBJ_MUSHPATCH, x + 2, y + 2); + } +} + +//----- (004431D4) -------------------------------------------------------- +void __cdecl AddSlainHero() +{ + int x; // [esp+0h] [ebp-8h] + int y; // [esp+4h] [ebp-4h] + + GetRndObjLoc(5, &x, &y); + AddObject(OBJ_SLAINHERO, x + 2, y + 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[nobjects] = objectavail[0]; + objectavail[0] = objectavail[-nobjects + 126]; /* double check */ + 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[4].plrlevel ) + { + 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_repeat_walk(0); + sgbMouseDown = 0; + ReleaseCapture(); + ClrPlrPath(myplr); + StartStand(myplr, 0); + } + } +} +// 525748: using guessed type char sgbMouseDown; + +//----- (00443727) -------------------------------------------------------- +void __fastcall Obj_StopAnim(int i) +{ + if ( object[i]._oAnimFrame == object[i]._oAnimLen ) + { + object[i]._oAnimCnt = 0; + object[i]._oAnimDelay = 1000; + } +} + +//----- (0044374A) -------------------------------------------------------- +void __fastcall Obj_Door(int i) +{ + int dy; // edx + int dx; // eax + + if ( object[i]._oVar4 ) + { + dy = object[i]._oy; + dx = object[i]._ox; + _LOBYTE(object[i]._oSelFlag) = 2; + object[i]._oMissFlag = 1; + object[i]._oVar4 = ((dItem[dx][dy] == 0 + && dDead[dx][dy] == 0 + && dPlayer[dx][dy] == 0 + && dMonster[dx][dy] == 0) == 0) + + 1; + } + else + { + object[i]._oMissFlag = 0; + _LOBYTE(object[i]._oSelFlag) = 3; + } +} + +//----- (004437CD) -------------------------------------------------------- +void __fastcall Obj_Sarc(int i) +{ + if ( object[i]._oAnimFrame == object[i]._oAnimLen ) + object[i]._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 damage[5]; // [esp+4h] [ebp-18h] + int v8; // [esp+18h] [ebp-4h] + + v1 = myplr; + v8 = i; + v2 = plr[myplr]._pmode == PM_DEATH; + damage[1] = 6; + damage[2] = 8; + damage[3] = 10; + damage[4] = 12; + if ( !v2 ) + { + v3 = plr[v1]._pFireResist; + if ( v3 > 0 ) + damage[(unsigned char)leveltype] -= v3 * damage[(unsigned char)leveltype] / 100; + if ( plr[v1].WorldX == object[v8]._ox && plr[v1].WorldY == object[v8]._oy - 1 ) + { + v4 = damage[(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_get_dpiece_num_from_coord(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_get_dpiece_num_from_coord(x, y)] = v5; + dpiece_defs_map_1[0][0][16 * gendung_get_dpiece_num_from_coord(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[4].plrlevel ); +} + +//----- (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 ( dPiece[-4][v8] == 396 ) /* check *(_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 ( dPiece[0][v8-1] == 396 ) /* check *(_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 ObjChangeMap(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(2 * v6 + 16, 2 * v4 + 16, 2 * v5 + 17, 2 * y2 + 17); /* v7 */ + } + 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(2 * v6 + 16, v9, v8, y_end); /* v10 */ + } +} +// 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: + ObjChangeMap(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]; /* fix */ + AddMissile(plr[v3].WorldX, plr[v3].WorldY, v1, v2, plr[v3]._pdir, MIS_RNDTELEPORT, 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[SPL_GUARDIAN] < 15 ) + ++plr[0]._pSplLvl[v7 + SPL_GUARDIAN]; + 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, + MIS_GUARDIAN, + 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 ) + ObjChangeMap(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; + DRLG_MRectTrans(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 = QUEST_RBONER; + } + else + { + v5 = QUEST_MBONER; + //if ( v4 != 2 ) + //v5 = speech_id; + } + } + else + { + v5 = QUEST_BONER; + } + 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(IDI_BANNER, 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); + ObjChangeMap(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); + ObjChangeMap(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); + ObjChangeMap(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(CURSOR_HAND); + 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 pnum, int i, int sType) +{ + 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 v138; // [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 = i; + arglist = pnum; + if ( dropGoldFlag ) + { + dropGoldFlag = 0; + dropGoldValue = 0; + } + v3 = i; + v4 = &object[i]._oSelFlag; + if ( _LOBYTE(object[i]._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(sType, 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; + v138 = 0; + v52 = 1; + v53 = arglist; + v54 = plr[arglist]._pMemSpells[1]; + v139 = 37; + do + { + v7 = v138 & v54; + if ( v138 & v54 | v52 & plr[arglist]._pMemSpells[0] ) + ++sfx_ida; + v55 = __PAIR__((unsigned int)v138, v52) >> 31; + v52 *= 2; + v56 = v139-- == 1; + v138 = 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(IMISC_REJUV); + 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(IMISC_FULLREJUV); + 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(IMISC_REJUV); + 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(IMISC_FULLREJUV); + 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, ITYPE_MISC, 19, 0, 1); + CreateTypeItem(object[v3]._ox, object[v3]._oy, 0, ITYPE_MISC, 19, 0, 1); + } + else + { + CreateTypeItem(v85, v86, 0, ITYPE_MISC, 7, 0, 1); + CreateTypeItem(object[v3]._ox, object[v3]._oy, 0, ITYPE_MISC, 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); + drawpanflag = 255; + if ( arglist == myplr ) + NetSendCmdParam2(0, CMD_PLROPOBJ, arglist, param2); + return; + } + } + } +} +// 4B84DC: using guessed type int dropGoldFlag; +// 52571C: using guessed type int drawpanflag; +// 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, ITYPE_MISC, 21, sendmsg, 0); + else + CreateTypeItem(v8, v9, 0, ITYPE_MISC, 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, ITYPE_MISC, 24, sendmsg, 0); + //_LOBYTE(v7) = QuestStatus(3); + if ( QuestStatus(3) + && monster[4].mName == UniqMonst[2].mName + && _LOBYTE(monster[4]._msquelch) == -1 + && monster[4]._mhitpoints ) + { + monster[4].mtalkmsg = QUEST_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, ITYPE_MARMOR, 0, sendmsg, 0); + goto LABEL_15; + } + if ( currlevel >= 0xAu && currlevel <= 0xCu ) + { + CreateTypeItem(object[v4]._ox, object[v4]._oy, 0, ITYPE_HARMOR, 0, sendmsg, 0); + goto LABEL_15; + } + if ( currlevel < 0xDu || currlevel > 0x10u ) + goto LABEL_15; + v10 = sendmsg; + v9 = ITYPE_HARMOR; + } + else + { + v10 = sendmsg; + v9 = ITYPE_LARMOR; + } + 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) -------------------------------------------------------- +int __fastcall FindValidShrine(int i) +{ + bool done; // esi + int rv; // eax + bool v3; // zf + + do + { + done = 0; + do + { + rv = random(0, 26); + if ( currlevel >= shrinemin[rv] && currlevel <= shrinemax[rv] && rv != 8 ) + done = 1; + } + while ( !done ); + if ( gbMaxPlayers == 1 ) + v3 = shrineavail[rv] == 2; + else + v3 = shrineavail[rv] == 1; + } + while ( v3 ); + return rv; +} +// 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 + + v3 = i; + v4 = pnum; + v5 = i; + SetRndSeed(object[i]._oRndSeed); + object[v5]._oVar1 = FindValidShrine(v3); + OperateShrine(v4, v3, sType); + object[v5]._oAnimDelay = 2; + drawpanflag = 255; +} +// 52571C: using guessed type int drawpanflag; + +//----- (004471AA) -------------------------------------------------------- +void __fastcall OperateCauldron(int pnum, int i, int sType) +{ + int v3; // edi + int v4; // ebx + int v5; // esi + + v3 = i; + v4 = pnum; + v5 = i; + SetRndSeed(object[i]._oRndSeed); + object[v5]._oVar1 = FindValidShrine(v3); + OperateShrine(v4, v3, sType); + object[v5]._oAnimFlag = 0; + object[v5]._oAnimFrame = 3; + drawpanflag = 255; +} +// 52571C: using guessed type int drawpanflag; + +//----- (004471FC) -------------------------------------------------------- +bool __fastcall OperateFountains(int pnum, int i) +{ + unsigned short v2; // bx + int v3; // esi + int v4; // edi + bool 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 == OBJ_TEARFTN && _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; + } + drawpanflag = 255; + return v5; +} +// 52571C: using guessed type int drawpanflag; +// 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 = ITYPE_AXE; + goto LABEL_7; + } + v8 = v7 - 1; + if ( !v8 ) + { + v13 = ITYPE_BOW; + goto LABEL_7; + } + if ( v8 == 1 ) + { + v13 = ITYPE_MACE; +LABEL_7: + v9 = v13; + goto LABEL_12; + } + v9 = sendmsg; + } + else + { + v9 = ITYPE_SWORD; + } +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, IS_MAGIC); + 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, LS_GSHRINE); + break; + case OBJ_CAULDRON: + OperateCauldron(v3, i, LS_CALDRON); + 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, IS_MAGIC); + 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, 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_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); + ObjChangeMap(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: + ObjChangeMap(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) ) + ObjChangeMap(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; + DRLG_MRectTrans(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; diff --git a/Source/objects.h b/Source/objects.h new file mode 100644 index 0000000..d4c3246 --- /dev/null +++ b/Source/objects.h @@ -0,0 +1,169 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//objects +extern int trapid; // weak +extern int trapdir; // weak +extern int pObjCels[40]; +extern char ObjFileList[40]; +extern int objectactive[127]; +extern int nobjects; // idb +extern int leverid; // idb +extern int objectavail[127]; +extern ObjectStruct object[127]; +extern int InitObjFlag; // weak +extern int numobjfiles; // weak + +void __cdecl InitObjectGFX(); +void __cdecl FreeObjectGFX(); +bool __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); +bool __fastcall WallTrapLocOk(int xp, int yp); +void __cdecl AddL2Torches(); +bool __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 ObjChangeMap(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 pnum, int i, int sType); +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); +int __fastcall FindValidShrine(int i); +void __fastcall OperateGoatShrine(int pnum, int i, int sType); +void __fastcall OperateCauldron(int pnum, int i, int sType); +bool __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); + +/* rdata */ + +extern int ObjTypeConv[113]; +extern ObjDataStruct AllObjects[99]; +extern char *ObjMasterLoadList[56]; +extern int bxadd[8]; +extern int byadd[8]; +extern char *shrinestrs[26]; +extern unsigned char shrinemin[26]; +extern unsigned char shrinemax[26]; +extern unsigned char shrineavail[26]; +extern char *StoryBookName[9]; +extern int StoryText[3][3]; diff --git a/Source/pack.cpp b/Source/pack.cpp new file mode 100644 index 0000000..f2c43f6 --- /dev/null +++ b/Source/pack.cpp @@ -0,0 +1,302 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int pack_cpp_init_value; // weak + +int pack_inf = 0x7F800000; // weak + +//----- (0044875A) -------------------------------------------------------- +struct pack_cpp_init +{ + pack_cpp_init() + { + pack_cpp_init_value = pack_inf; + } +} _pack_cpp_init; +// 47F168: using guessed type int pack_inf; +// 67D7C8: using guessed type int pack_cpp_init_value; + +//----- (00448765) -------------------------------------------------------- +void __fastcall 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; +} +// 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) +{ + 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; + } + } + } + } + } +} + +//----- (00448AD0) -------------------------------------------------------- +void __fastcall 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; +} + +//----- (00448D48) -------------------------------------------------------- +void __fastcall 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( + 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; + RecreateItem(127, is->idx, v5, v2->iSeed, (unsigned short)v2->wValue); + item[127]._iMagical = (unsigned char)v2->bId >> 1; + item[127]._iIdentified = v2->bId & 1; + item[127]._iDurability = (unsigned char)v2->bDur; + item[127]._iMaxDur = (unsigned char)v2->bMDur; + item[127]._iCharges = (unsigned char)v2->bCh; + item[127]._iMaxCharges = (unsigned char)v2->bMCh; + } + qmemcpy(v3, &item[127], sizeof(ItemStruct)); + } +} diff --git a/Source/pack.h b/Source/pack.h new file mode 100644 index 0000000..cb74ba2 --- /dev/null +++ b/Source/pack.h @@ -0,0 +1,24 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//pack +extern int pack_cpp_init_value; // weak + +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); + +/* data */ + +extern int pack_inf; // weak diff --git a/Source/palette.cpp b/Source/palette.cpp new file mode 100644 index 0000000..0b0e4d3 --- /dev/null +++ b/Source/palette.cpp @@ -0,0 +1,353 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +PALETTEENTRY logical_palette[256]; +int palette_cpp_init_value; // weak +PALETTEENTRY system_palette[256]; +PALETTEENTRY orig_palette[256]; +UINT gdwPalEntries; + +int palette_inf = 0x7F800000; // weak + +/* rdata */ + +int gamma_correction = 100; // idb +int color_cycling_enabled = 1; // idb +bool sgbFadedIn = 1; + +//----- (00448DFA) -------------------------------------------------------- +struct palette_cpp_init +{ + palette_cpp_init() + { + palette_cpp_init_value = palette_inf; + } +} _palette_cpp_init; +// 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); + LoadSysPal(); + v0 = IDirectDraw_CreatePalette(lpDDInterface, DDPCAPS_ALLOW256|DDPCAPS_8BIT, system_palette, &lpDDPalette, NULL); + if ( v0 ) + TermDlg(111, v0, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 143); + v1 = IDirectDrawSurface_SetPalette(lpDDSPrimary, lpDDPalette); + if ( v1 ) + TermDlg(111, v1, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 146); +} + +//----- (00448EAB) -------------------------------------------------------- +void __cdecl palette_load_gamma() +{ + int v3; // eax + int value; // [esp+8h] [ebp-4h] + + value = gamma_correction; + if ( !SRegLoadValue("Diablo", "Gamma Correction", 0, &value) ) + value = 100; + if ( value >= 30 ) + { + if ( value > 100 ) + value = 100; + } + else + { + value = 30; + } + gamma_correction = value - value % 5; + if ( SRegLoadValue("Diablo", "Color Cycling", 0, &value) ) + v3 = value; + else + v3 = 1; + color_cycling_enabled = v3; +} + +//----- (00448F20) -------------------------------------------------------- +void __cdecl LoadSysPal() +{ + HDC hDC; // ebx + int i; // ecx + int iStartIndex; // edi + + for(i = 0; i < 256; i++) + system_palette[i].peFlags = PC_NOCOLLAPSE|PC_RESERVED; + + if ( !fullscreen ) + { + 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; + iStartIndex = 256 - gdwPalEntries; + GetSystemPaletteEntries(hDC, iStartIndex, gdwPalEntries, &system_palette[iStartIndex]); + if ( iStartIndex < 256 ) + { + for(i = iStartIndex; i < 256; i++) + system_palette[i].peFlags = 0; + } + ReleaseDC(NULL, hDC); + } +} +// 484364: using guessed type int fullscreen; + +//----- (00448FC9) -------------------------------------------------------- +void __fastcall LoadPalette(char *pszFileName) +{ + int i; // eax + char PalData[256][3]; // [esp+0h] [ebp-304h] + void *pBuf; // [esp+300h] [ebp-4h] + + WOpenFile(pszFileName, &pBuf, 0); + WReadFile(pBuf, (char *)PalData, 768); + WCloseFile(pBuf); + + for(i = 0; i < 256; i++) + { + orig_palette[i].peFlags = 0; + orig_palette[i].peRed = PalData[i][0]; + orig_palette[i].peGreen = PalData[i][1]; + orig_palette[i].peBlue = PalData[i][2]; + } +} + +//----- (00449025) -------------------------------------------------------- +void __fastcall LoadRndLvlPal(int l) +{ + char *pszPal; // ecx + char szTemp[260]; // [esp+4h] [ebp-104h] + + if ( l ) + { + sprintf(szTemp, "Levels\\L%iData\\L%i_%i.PAL", l, l, random(0, 4) + 1); + pszPal = szTemp; + } + else + { + pszPal = "Levels\\TownData\\Town.pal"; + } + LoadPalette(pszPal); +} + +//----- (0044906C) -------------------------------------------------------- +void __cdecl ResetPal() +{ + if ( !lpDDSPrimary + || IDirectDrawSurface_IsLost(lpDDSPrimary) != DDERR_SURFACELOST + || !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 ( lpDDPalette ) + { + v0 = 0; + v1 = 256; + if ( !fullscreen ) + { + v0 = gdwPalEntries; + v1 = 2 * (128 - gdwPalEntries); + } + SDrawUpdatePalette(v0, v1, &system_palette[v0], 0); + } +} +// 484364: using guessed type int fullscreen; + +//----- (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 = pow(v3->peRed * 0.00390625, v5) * 256.0; + v4->peGreen = pow(v3->peGreen * 0.00390625, v5) * 256.0; + v4->peBlue = pow(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() +{ + SetFadeLevel(0); +} + +//----- (00449245) -------------------------------------------------------- +void __fastcall SetFadeLevel(int fadeval) +{ + int i; // eax + + if ( lpDDInterface ) + { + for(i = 0; i < 255; i++) + { + system_palette[i].peRed = (fadeval * logical_palette[i].peRed) >> 8; + system_palette[i].peGreen = (fadeval * logical_palette[i].peGreen) >> 8; + system_palette[i].peBlue = (fadeval * logical_palette[i].peBlue) >> 8; + } + Sleep(3); + IDirectDraw_WaitForVerticalBlank(lpDDInterface, DDWAITVB_BLOCKBEGIN, NULL); + palette_update(); + } +} + +//----- (004492B0) -------------------------------------------------------- +void __fastcall PaletteFadeIn(int fr) +{ + int i; // ebp + + palette_apply_gamma_correction(logical_palette, orig_palette, 256); + + for(i = 0; i < 256; i += fr) + SetFadeLevel(i); + + SetFadeLevel(256); + memcpy(logical_palette, orig_palette, 0x400u); + sgbFadedIn = 1; +} + +//----- (00449306) -------------------------------------------------------- +void __fastcall PaletteFadeOut(int fr) +{ + int i; // esi + + if ( sgbFadedIn ) + { + for(i = 256; i > 0; i -= fr) + SetFadeLevel(i); + + SetFadeLevel(0); + sgbFadedIn = 0; + } +} + +//----- (00449336) -------------------------------------------------------- +void __cdecl palette_update_caves() +{ + BYTE v0; // cx + signed int v1; // esi + signed int v2; // eax + BYTE v4; // [esp+6h] [ebp-2h] + BYTE v5; + + v0 = system_palette[1].peRed; + v5 = system_palette[1].peGreen; + 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 ); + system_palette[v1].peRed = v0; + system_palette[v1].peGreen = v5; + system_palette[v1].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; +} diff --git a/Source/palette.h b/Source/palette.h new file mode 100644 index 0000000..2cd7d59 --- /dev/null +++ b/Source/palette.h @@ -0,0 +1,49 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//palette +extern PALETTEENTRY logical_palette[256]; +extern int palette_cpp_init_value; // weak +extern PALETTEENTRY system_palette[256]; +extern PALETTEENTRY orig_palette[256]; +extern UINT gdwPalEntries; + +void __cdecl palette_cpp_init(); +void __cdecl palette_save_gamme(); +void __cdecl palette_init(); +void __cdecl palette_load_gamma(); +void __cdecl LoadSysPal(); +void __fastcall LoadPalette(char *pszFileName); +void __fastcall LoadRndLvlPal(int l); +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 SetFadeLevel(int brightness); +void __fastcall PaletteFadeIn(int fr); +void __fastcall PaletteFadeOut(int fr); +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); + +/* data */ + +extern int palette_inf; // weak + +/* rdata */ + +extern int gamma_correction; // idb +extern int color_cycling_enabled; // idb +extern bool sgbFadedIn; diff --git a/Source/path.cpp b/Source/path.cpp new file mode 100644 index 0000000..7693b6f --- /dev/null +++ b/Source/path.cpp @@ -0,0 +1,441 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +PATHNODE path_nodes[300]; +int gdwCurPathStep; +int pnode_vals[26]; +PATHNODE *pnode_ptr; +PATHNODE *pnode_tblptr[300]; +PATHNODE path_2_nodes[300]; + +char pathxdir[8] = { -1, -1, 1, 1, -1, 0, 1, 0 }; +char pathydir[8] = { -1, 1, -1, 1, 0, -1, 0, 1 }; + +/* rdata */ +char path_directions[9] = { 5, 1, 6, 2, 0, 3, 8, 4, 7 }; + +//----- (004493D4) -------------------------------------------------------- +int __fastcall FindPath(bool (__fastcall *PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path) +{ + PATHNODE *v8; // esi + char v9; // al + PATHNODE *v11; // eax + int result; // eax + PATHNODE *v13; // edx + int v14; // eax + int v15; // edi + bool v16; // zf + int *v17; // ecx + char v18; // dl + + pnode_vals[0] = 0; + *(_DWORD *)&path_2_nodes[0].f = (unsigned int)path_new_step(); + gdwCurPathStep = 0; + pnode_ptr = path_new_step(); + v8 = path_new_step(); + v8->g = 0; + v9 = path_get_h_cost(sx, sy, dx, dy); + v8->h = v9; + v8->x = sx; + v8->f = v9 + v8->g; + 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(PosOk, PosOkArg, 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] = 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_get_h_cost(int sx, int sy, int dx, int dy) +{ + int v4; // esi + int v5; // edi + int v6; // eax + int v7; // ecx + + v4 = sy; + v5 = abs(sx - dx); + v6 = abs(v4 - dy); + 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) -------------------------------------------------------- +bool __fastcall path_solid_pieces(PATHNODE *pPath, int dx, int dy) +{ + bool result; // eax + int dir; // ecx + int v8; // ecx + int v10; // edx + + result = 1; + dir = path_directions[3 * (dy - pPath->y) - pPath->x + 4 + dx] - 5; + if ( !dir ) + { + result = 0; + if ( nSolidTable[dPiece[dx][dy + 1]] ) + return result; + v8 = dPiece[dx + 1][dy]; + goto LABEL_13; + } + dir--; + if ( !dir ) + { + v10 = dPiece[dx][dy + 1]; + goto LABEL_9; + } + dir--; + if ( !dir ) + { + v10 = dPiece[dx][dy-1]; /* check */ +LABEL_9: + result = 0; + if ( nSolidTable[v10] ) + return result; + v8 = dPiece[dx-4][dy]; /* check */ + goto LABEL_13; + } + if ( dir == 1 ) + { + result = 0; + if ( !nSolidTable[dPiece[dx + 1][dy]] ) + { + v8 = dPiece[dx][dy-1]; /* check */ +LABEL_13: + if ( nSolidTable[v8] == result ) + result = 1; + return result; + } + } + return result; +} + +//----- (004495ED) -------------------------------------------------------- +int __fastcall path_get_path(bool (__fastcall *PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y) +{ + int v5; // eax + int dx; // esi + int dy; // edi + int i; // [esp+14h] [ebp-4h] + + v5 = 0; + for ( i = 0; ; v5 = i ) + { + dx = pPath->x + pathxdir[v5]; + dy = pPath->y + pathydir[v5]; + if ( !PosOk(PosOkArg, dx, dy) ) + break; + if ( path_solid_pieces(pPath, dx, dy) ) + goto LABEL_8; +LABEL_9: + if ( ++i >= 8 ) + return 1; + } + if ( dx != x || dy != y ) + goto LABEL_9; +LABEL_8: + if ( path_parent_path(pPath, dx, dy, x, y) ) + goto LABEL_9; + return 0; +} + +//----- (0044966F) -------------------------------------------------------- +int __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 = pPath->g + path_check_equal(pPath, dx, dy); + v7 = path_get_node1(a1, dy); + if ( v7 ) + { + v8 = 0; + v9 = v5->Child; + do + { + if ( !*v9 ) + break; + ++v8; + ++v9; + } + while ( v8 < 8 ); + v5->Child[v8] = v7; + if ( v6 < v7->g ) + { + if ( path_solid_pieces(v5, a1, dy) ) + { + v10 = v7->h; + v7->Parent = v5; + v7->g = v6; + v7->f = v6 + v10; + } + } + } + else + { + v11 = path_get_node2(a1, dy); + if ( v11 ) + { + v12 = 0; + v13 = v5->Child; + do + { + if ( !*v13 ) + break; + ++v12; + ++v13; + } + while ( v12 < 8 ); + v5->Child[v12] = v11; + if ( v6 < v11->g && path_solid_pieces(v5, a1, dy) ) + { + v14 = v6 + v11->h; + v11->Parent = v5; + v11->g = v6; + v11->f = v14; + path_set_coords(v11); + } + } + else + { + result = path_new_step(); + v16 = result; + if ( !result ) + return 0; + result->Parent = v5; + result->g = v6; + v17 = path_get_h_cost(a1, dy, sx, sy); + v16->h = v17; + v16->f = v6 + v17; + v16->x = a1; + v16->y = dy; + path_next_node(v16); + v18 = 0; + v19 = v5->Child; + do + { + if ( !*v19 ) + break; + ++v18; + ++v19; + } + while ( v18 < 8 ); + v5->Child[v18] = v16; + } + } + return 1; +} + +//----- (0044979A) -------------------------------------------------------- +PATHNODE *__fastcall path_get_node1(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_node2(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) -------------------------------------------------------- +void __fastcall path_next_node(PATHNODE *pPath) +{ + PATHNODE *v1; // edx + PATHNODE *v2; // eax + + v1 = *(PATHNODE **)&path_2_nodes[0].f; + v2 = *(PATHNODE **)(*(_DWORD *)&path_2_nodes[0].f + 48); + if ( v2 ) + { + do + { + if ( v2->f >= pPath->f ) + break; + v1 = v2; + v2 = v2->NextNode; + } + while ( v2 ); + pPath->NextNode = v2; + } + v1->NextNode = pPath; +} + +//----- (004497F7) -------------------------------------------------------- +void __fastcall path_set_coords(PATHNODE *pPath) +{ + PATHNODE *PathOld; // edi + PATHNODE *PathAct; // esi + char v6; // al + int i; // [esp+0h] [ebp-8h] + PATHNODE **v9; // [esp+4h] [ebp-4h] + + path_push_active_step(pPath); + while ( gdwCurPathStep ) + { + PathOld = path_pop_active_step(); + v9 = PathOld->Child; + for(i = 0; i < 8; i++) + { + PathAct = *v9; + if ( !*v9 ) + break; + + if ( PathOld->g + path_check_equal(PathOld, PathAct->x, PathAct->y) < PathAct->g ) + { + if ( path_solid_pieces(PathOld, PathAct->x, PathAct->y) ) + { + PathAct->Parent = PathOld; + v6 = PathOld->g + path_check_equal(PathOld, PathAct->x, PathAct->y); + PathAct->g = v6; + PathAct->f = v6 + PathAct->h; + path_push_active_step(PathAct); + } + } + ++v9; + } + } +} + +//----- (00449890) -------------------------------------------------------- +void __fastcall path_push_active_step(PATHNODE *pPath) +{ + int v1; // eax + + v1 = gdwCurPathStep++; + pnode_tblptr[v1] = pPath; +} + +//----- (004498A3) -------------------------------------------------------- +PATHNODE *__cdecl path_pop_active_step() +{ + return pnode_tblptr[--gdwCurPathStep]; +} + +//----- (004498B6) -------------------------------------------------------- +PATHNODE *__cdecl path_new_step() +{ + PATHNODE *v1; // esi + + if ( pnode_vals[0] == 300 ) + return 0; + v1 = &path_nodes[pnode_vals[0]++]; + memset(v1, 0, 0x34u); + return v1; +} diff --git a/Source/path.h b/Source/path.h new file mode 100644 index 0000000..d1521f7 --- /dev/null +++ b/Source/path.h @@ -0,0 +1,41 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//path +extern PATHNODE path_nodes[300]; +extern int gdwCurPathStep; +extern int pnode_vals[26]; +extern PATHNODE *pnode_ptr; +extern PATHNODE *pnode_tblptr[300]; +extern PATHNODE path_2_nodes[300]; + +int __fastcall FindPath(bool (__fastcall *PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path); +int __fastcall path_get_h_cost(int sx, int sy, int dx, int dy); +int __fastcall path_check_equal(PATHNODE *pPath, int dx, int dy); +PATHNODE *__cdecl GetNextPath(); +bool __fastcall path_solid_pieces(PATHNODE *pPath, int dx, int dy); +int __fastcall path_get_path(bool (__fastcall *PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y); +int __fastcall path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy); +PATHNODE *__fastcall path_get_node1(int dx, int dy); +PATHNODE *__fastcall path_get_node2(int dx, int dy); +void __fastcall path_next_node(PATHNODE *pPath); +void __fastcall path_set_coords(PATHNODE *pPath); +void __fastcall path_push_active_step(PATHNODE *pPath); +PATHNODE *__cdecl path_pop_active_step(); +PATHNODE *__cdecl path_new_step(); + +/* data */ + +extern char pathxdir[8]; +extern char pathydir[8]; + +/* rdata */ +extern char path_directions[9]; diff --git a/Source/pfile.cpp b/Source/pfile.cpp new file mode 100644 index 0000000..7d4384b --- /dev/null +++ b/Source/pfile.cpp @@ -0,0 +1,970 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int pfile_cpp_init_value; +char hero_names[320]; +bool gbValidSaveFile; // idb +int save_prev_tc; // weak + +int pfile_inf = 0x7F800000; // weak + +//----- (004498F1) -------------------------------------------------------- +struct pfile_cpp_init +{ + pfile_cpp_init() + { + pfile_cpp_init_value = pfile_inf; + } +} _pfile_cpp_init; +// 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(ghInst, 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 == '\\' ) + { + *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 ( pfile_open_archive(1, v0) ) + { + 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 ( mpqapi_open_archive(FileName, 0, v2) ) + 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(ghInst, pszBuf, 0x104u); + v6 = strrchr(v3, '\\'); + 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: + 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[4]._pName ) + 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; + 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 >= 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 ) + { + if ( pfile_read_hero(v7, &pkplr) ) + { + 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 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 = GetModuleFileNameA(ghInst, dst, 0x104u); + v6 = strrchr(v3, '\\'); + 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 *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(v6, v4, password); + if ( dwBytes ) + goto LABEL_11; + if ( (unsigned char)gbMaxPlayers > 1u ) + { + GetComputerNameA(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(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; +} +// 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 SFileOpenArchive(SrcStr, 0x7000, 0, &archive) != 0 ? archive : NULL; +} + +//----- (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 ( !SFileOpenFileEx(hsArchive, "game", 0, &file) ) + 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 ( !pfile_open_archive(0, v1) ) + 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 dwChar; // edi + void *v1; // esi + //int v2; // eax + PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h] + + dwChar = pfile_get_save_num_from_name(chr_name_str); + v1 = pfile_open_save_archive(0, dwChar); + if ( !v1 ) + TermMsg("Unable to open archive"); + //_LOBYTE(v2) = pfile_read_hero(v1, &pkplr); + if ( !pfile_read_hero(v1, &pkplr) ) + TermMsg("Unable to load character"); + UnPackPlayer(&pkplr, myplr, 0); + *(_DWORD *)&gbValidSaveFile = pfile_archive_contains_game(v1); + pfile_SFileCloseArchive(v1); +} + +//----- (0044A419) -------------------------------------------------------- +void __fastcall 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); +} +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (0044A463) -------------------------------------------------------- +void __fastcall 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) ) + TermMsg("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); + } +} +// 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 ( !pfile_open_archive(0, v0) ) + TermMsg("Unable to write to save file archive"); + mpqapi_remove_hash_entries(GetTempSaveNames); + pfile_flush(1, v1); + } +} +// 679660: using guessed type char gbMaxPlayers; + +//----- (0044A563) -------------------------------------------------------- +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; +} + +//----- (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 ( !pfile_open_archive(0, v0) ) + TermMsg("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); +} + +//----- (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 ( !pfile_open_archive(0, v9) ) + 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 ( !SFileOpenFileEx(v4, v13, 0, &file) ) + 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 ( !SFileReadFile(file, (char *)v7, *v2, (unsigned long *)&nread, 0) ) + 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(file, 0, 0, 0) ) + TermMsg("Unable to read save file"); + //_LOBYTE(v11) = SFileReadFile(file, v9, *v2, (unsigned long *)&nread, 0); + if ( !SFileReadFile(file, v9, *v2, (unsigned long *)&nread, 0) ) + 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; diff --git a/Source/pfile.h b/Source/pfile.h new file mode 100644 index 0000000..f72bee4 --- /dev/null +++ b/Source/pfile.h @@ -0,0 +1,58 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//pfile +extern int pfile_cpp_init_value; +extern char hero_names[320]; +extern bool gbValidSaveFile; // idb +extern int save_prev_tc; // weak + +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 GetSaveDirectory(char *dst, int dst_size, int save_num); +bool __fastcall pfile_read_hero(void *archive, PkPlayerStruct *pPack); +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 GetTempLevelNames(char *szTemp); +void __fastcall GetPermLevelNames(char *szPerm); +void __fastcall pfile_get_game_name(char *dst); +void __cdecl pfile_remove_temp_files(); +bool __stdcall GetTempSaveNames(int dwIndex, char *szTemp); +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); + +/* data */ + +extern int pfile_inf; // weak diff --git a/Source/player.cpp b/Source/player.cpp new file mode 100644 index 0000000..3379ace --- /dev/null +++ b/Source/player.cpp @@ -0,0 +1,5857 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +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 +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 + +int player_inf = 0x7F800000; // weak +char ArmourChar[4] = { 'L', 'M', 'H', 0 }; +char WepChar[10] = { 'N', 'U', 'S', 'D', 'B', 'A', 'M', 'H', 'T', 0 }; +char CharChar[4] = { 'W', 'R', 'S', 0 }; + +/* rdata */ + +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[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 }; +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" }; +unsigned char fix[9] = { 0u, 0u, 3u, 3u, 3u, 6u, 6u, 6u, 8u }; /* PM_ChangeLightOff local type */ + +//----- (0044A8EB) -------------------------------------------------------- +struct player_cpp_init +{ + player_cpp_init() + { + player_cpp_init_value = player_inf; + } +} _player_cpp_init; +// 47F204: using guessed type int player_inf; +// 68643C: using guessed type int player_cpp_init_value; + +//----- (0044A8F6) -------------------------------------------------------- +void __fastcall player_init_cl2_hdrs(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 gfxflag) +{ + 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 = gfxflag; + if ( (unsigned int)pnum >= 4 ) + TermMsg("LoadPlrGFX: illegal player %d", pnum); + v3 = &plr[v2]; + sprintf( + v15, + "%c%c%c", + CharChar[SLOBYTE(v3->_pClass)], + ArmourChar[v3->_pgfxnum >> 4], + WepChar[v3->_pgfxnum & 0xF]); + v4 = 1; + v17 = ClassStrTbl[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->_pLData; + v19 = "LM"; + v7 = (char *)v3->_pLAnim; + } + 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->_pHData; + v19 = "HT"; + v7 = (char *)v3->_pHAnim; + } + else + { +LABEL_27: + TermMsg("PLR:2"); + } + } + else + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->_pAData; + v19 = "AT"; + v7 = (char *)v3->_pAAnim; + } + } + else + { + v19 = "AW"; + if ( !v5 ) + v19 = "WL"; + v6 = v3->_pWData; + v7 = (char *)v3->_pWAnim; + } + } + else + { + v19 = "AS"; + if ( !v5 ) + v19 = "ST"; + v6 = v3->_pNData; + v7 = (char *)v3->_pNAnim; + } + } +LABEL_37: + sprintf(arglist, "PlrGFX\\%s\\%s\\%s%s.CL2", v17, v15, v15, v19); + LoadFileWithMem(arglist, v6); + player_init_cl2_hdrs((char *)v6, v7); + v3->_pGFXLoad |= v18; + v5 = leveltype; + goto LABEL_38; + } + v11 = v4 - 32; + if ( !v11 ) + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->_pFData; + v19 = "FM"; + v7 = (char *)v3->_pFAnim; + goto LABEL_37; + } + v12 = v11 - 32; + if ( !v12 ) + { + if ( !v5 ) + goto LABEL_38; + v6 = v3->_pTData; + v19 = "QM"; + v7 = (char *)v3->_pTAnim; + goto LABEL_37; + } + v13 = v12 - 64; + if ( !v13 ) + { + if ( v3->_pgfxnum & 0xF ) + goto LABEL_38; + v6 = v3->_pDData; + v19 = "DT"; + v7 = (char *)v3->_pDAnim; + goto LABEL_37; + } + if ( v13 != 128 ) + goto LABEL_27; + if ( v5 && v3->_pBlockFlag ) + { + v6 = v3->_pBData; + v19 = "BL"; + v7 = (char *)v3->_pBAnim; + 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 = 0x17F; + } + else + { + plr[v1]._pgfxnum = 0; + v2 = 0x80; + } + 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]._pNData = 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]._pWData = 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]._pAData = 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]._pHData = 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]._pLData = 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]._pFData = v15; + if ( v7 ) + { + plr_gfx_flag |= 0x40u; + plr_qframe_size = GetPlrGFXSize("QM"); + } + v16 = DiabloAllocPtr(plr_qframe_size); + v7 = plr_gfx_flag >= 0; + plr[v5]._pTData = 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]._pDData = v17; + if ( v7 ) + { + plr_gfx_bflag |= 1u; + plr_bframe_size = GetPlrGFXSize("BL"); + } + v18 = DiabloAllocPtr(plr_bframe_size); + plr[v5]._pGFXLoad = 0; + plr[v5]._pBData = 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 + char *v2; // edi + char *v3; // esi + char dwInitParam[256]; // [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 = ClassStrTbl; + do + { + v2 = ArmourChar; + do + { + v3 = WepChar; + do + { + sprintf(v6, "%c%c%c", CharChar[v1], *v2, *v3); + sprintf(dwInitParam, "PlrGFX\\%s\\%s\\%s%s.CL2", *v10, v6, v6, v8); + if ( WOpenFile(dwInitParam, &a1, 1) ) + { + v7 = WGetFileSize(a1, 0); + WCloseFile(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]._pNData; + plr[v2]._pNData = 0; + mem_free_dbg(v3); + v4 = plr[v2]._pWData; + plr[v2]._pWData = 0; + mem_free_dbg(v4); + v5 = plr[v2]._pAData; + plr[v2]._pAData = 0; + mem_free_dbg(v5); + v6 = plr[v2]._pHData; + plr[v2]._pHData = 0; + mem_free_dbg(v6); + v7 = plr[v2]._pLData; + plr[v2]._pLData = 0; + mem_free_dbg(v7); + v8 = plr[v2]._pFData; + plr[v2]._pFData = 0; + mem_free_dbg(v8); + v9 = plr[v2]._pTData; + plr[v2]._pTData = 0; + mem_free_dbg(v9); + v10 = plr[v2]._pDData; + plr[v2]._pDData = 0; + mem_free_dbg(v10); + v11 = plr[v2]._pBData; + plr[v2]._pBData = 0; + mem_free_dbg(v11); + plr[v2]._pGFXLoad = 0; +} + +//----- (0044AF37) -------------------------------------------------------- +void __fastcall NewPlrAnim(int pnum, int Peq, int numFrames, int Delay, int width) +{ + int v5; // edi + int v6; // esi + int v7; // eax + + v5 = pnum; + v6 = Peq; + if ( (unsigned int)pnum >= 4 ) + TermMsg("NewPlrAnim: illegal player %d", pnum); + v7 = v5; + plr[v7]._pAnimLen = numFrames; + plr[v7]._pAnimCnt = 0; + plr[v7]._pAnimDelay = Delay; + plr[v7]._pAnimData = v6; + plr[v7]._pAnimWidth = width; + plr[v7]._pAnimFrame = 1; + plr[v7]._pAnimWidth2 = (width - 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]._pNWidth = 96; + plr[v3]._pWWidth = 96; + plr[v3]._pAWidth = 128; + plr[v3]._pHWidth = 96; + plr[v3]._pSWidth = 96; + plr[v3]._pDWidth = 128; + plr[v3]._pBWidth = 96; + if ( v6 ) + { + plr[v3]._pNFrames = PlrGFXAnimLens[v5][7]; + plr[v3]._pWFrames = PlrGFXAnimLens[v5][8]; + plr[v3]._pDFrames = PlrGFXAnimLens[v5][4]; + plr[v3]._pSFrames = PlrGFXAnimLens[v5][5]; + } + else + { + plr[v3]._pNFrames = PlrGFXAnimLens[v5][0]; + plr[v3]._pWFrames = PlrGFXAnimLens[v5][2]; + plr[v3]._pAFrames = PlrGFXAnimLens[v5][1]; + plr[v3]._pHFrames = PlrGFXAnimLens[v5][6]; + plr[v3]._pSFrames = PlrGFXAnimLens[v5][5]; + plr[v3]._pDFrames = PlrGFXAnimLens[v5][4]; + plr[v3]._pBFrames = PlrGFXAnimLens[v5][3]; + plr[v3]._pAFNum = PlrGFXAnimLens[v5][9]; + } + plr[v3]._pSFNum = PlrGFXAnimLens[v5][10]; + v7 = plr[v3]._pgfxnum & 0xF; + if ( !v4 ) + { + if ( v7 == 4 ) + { + if ( v2 ) + plr[v3]._pNFrames = 8; + plr[v3]._pAWidth = 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]._pSWidth = 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, int 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, int 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]._pDWidth; + v11 = plr[v3]._pDAnim[0]; + v4->_pmode = 8; + NewPlrAnim(v2, v11, plr[v3]._pDFrames, 1, v10); + v12 = plr[v3]._pAnimLen; + plr[v3]._pAnimFrame = v12 - 1; + plr[v3]._pVar8 = 2 * v12; + } + else + { + v6 = plr[v3]._pNWidth; + v4->_pmode = 0; + NewPlrAnim(v2, plr[v3]._pNAnim[0], plr[v3]._pNFrames, 3, v6); + _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; +#ifdef _DEBUG + if ( debug_mode_dollar_sign && FirstTime ) + { + plr[pnum]._pMemSpells[0] |= 0x800000; + plr[pnum]._pMemSpells[1] |= 0; + if ( !plr[myplr]._pSplLvl[SPL_TELEPORT] ) + plr[myplr]._pSplLvl[SPL_TELEPORT] = 1; + } + if ( debug_mode_key_inverted_v && FirstTime ) + { + plr[pnum]._pMemSpells[0] = -1; + plr[pnum]._pMemSpells[1] = 0xFFFFFFF; + } +#endif + plr[v3]._pNextExper = ExpLvlsTbl[v19]; + if ( v14 ) + { + deathdelay = 0; + 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) -------------------------------------------------------- +void __fastcall InitPlayerLoc(int pnum, bool flag) +{ + int v2; // esi + int v3; // esi + int v4; // edi + int v5; // ebx + char *v6; // eax + int v7; // ebx + int v8; // edi + char *v9; // eax + int v10; // edi + int v11; // ebx + char *v12; // eax + bool v13; // [esp+Ch] [ebp-Ch] + int v14; // [esp+10h] [ebp-8h] + int v15; // [esp+10h] [ebp-8h] + int v16; // [esp+10h] [ebp-8h] + signed int v17; // [esp+14h] [ebp-4h] + signed int v18; // [esp+14h] [ebp-4h] + signed int v19; // [esp+14h] [ebp-4h] + + v2 = pnum; + v13 = flag; + if ( (unsigned int)pnum >= 4 ) + TermMsg("InitPlayer: illegal player %d", pnum); + v3 = v2; + v14 = 0; + v4 = plr[v3].WorldX - 1; + v5 = plr[v3].WorldY + 1; + v6 = (char *)dpiece_defs_map_1 + 32 * gendung_get_dpiece_num_from_coord(v4, v5); + v17 = 2; + do + v14 |= *(unsigned short *)&v6[2 * v17++]; + while ( v17 < 10 ); + if ( v14 | dArch[v4][v5] | (unsigned char)nSolidTable[dPiece[0][v5 + 112 * v4]] ) + plr[v3]._peflag = 1; + else + plr[v3]._peflag = 0; + if ( v13 == 1 && plr[v3]._peflag == 1 ) + { + v7 = plr[v3].WorldX; + v15 = 0; + v8 = plr[v3].WorldY + 2; + v9 = (char *)dpiece_defs_map_1 + 32 * gendung_get_dpiece_num_from_coord(plr[v3].WorldX, v8); + v18 = 2; + do + v15 |= *(unsigned short *)&v9[2 * v18++]; + while ( v18 < 10 ); + if ( !(v15 | dArch[v7][v8]) ) + { + v16 = 0; + v10 = plr[v3].WorldX - 2; + v11 = plr[v3].WorldY + 1; + v12 = (char *)dpiece_defs_map_1 + 32 * gendung_get_dpiece_num_from_coord(v10, v11); + v19 = 2; + do + v16 |= *(unsigned short *)&v12[2 * v19++]; + while ( v19 < 10 ); + if ( v16 | dArch[v10][v11] ) + plr[v3]._peflag = 2; + } + } +} + +//----- (0044BCC2) -------------------------------------------------------- +bool __fastcall SolidLoc(int x, int y) +{ + bool 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) -------------------------------------------------------- +bool __fastcall PlrDirOK(int pnum, int dir) +{ + int v2; // esi + int v3; // ebx + int v4; // eax + int v5; // esi + int v6; // edi + int v7; // ebp + bool 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 dir) +{ + 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 = dir; + 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; + InitPlayerLoc(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 + + 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); + NewPlrAnim(v2, plr[0]._pNAnim[v3 + 5430 * v2], plr[v4]._pNFrames, 3, plr[v4]._pNWidth); + 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; + InitPlayerLoc(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]._pWWidth; + NewPlrAnim(v11, plr[0]._pWAnim[EndDir + 5430 * v11], plr[v8]._pWFrames, 0, v13); + plr[v8]._pdir = EndDir; + plr[v8]._pVar6 = 0; + plr[v8]._pVar7 = 0; + plr[v8]._pVar8 = 0; + InitPlayerLoc(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 + 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 >= 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]._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; + InitPlayerLoc(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]._pWWidth; + NewPlrAnim(arglist, plr[0]._pWAnim[EndDir + 5430 * arglist], plr[v12]._pWFrames, 0, v20); + plr[v12]._pdir = EndDir; + plr[v12]._pVar8 = 0; + InitPlayerLoc(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]._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); + } +} + +//----- (0044C8BB) -------------------------------------------------------- +void __fastcall 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 >= 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]._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); + } +} + +//----- (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]._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); + } +} + +//----- (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]._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; +} +// 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]._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); + } +} + +//----- (0044CDFD) -------------------------------------------------------- +void __fastcall RespawnDeadItem(ItemStruct *itm, int x, int y) +{ + ItemStruct *v3; // ebx + int v4; // eax + int i; // ST10_4 + //unsigned int v6; // ecx + + v3 = itm; + if ( numitems < 127 ) + { + if ( FindGetItem(itm->IDidx, itm->_iCreateInfo, itm->_iSeed) >= 0 ) + { + DrawInvMsg("A duplicate item has been detected. Destroying duplicate..."); + SyncGetItem(x, y, v3->IDidx, v3->_iCreateInfo, v3->_iSeed); + } + v4 = itemavail[0]; + i = itemavail[0]; + dItem[x][y] = _LOBYTE(itemavail[0]) + 1; + //v6 = 4 * numitems; + itemactive[numitems] = v4; + v4 *= 368; + itemavail[0] = itemavail[-numitems + 126]; /* double check */ + qmemcpy((char *)item + v4, v3, sizeof(ItemStruct)); + *(int *)((char *)&item[0]._ix + v4) = x; + *(int *)((char *)&item[0]._iy + v4) = y; + RespawnItem(i, 1); + ++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 + 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 ) + 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); /* BUG_FIX: uses wrong sound, should use PS_WARR71 */ +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); +} +// 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) && (v8 = ItemSpaceOk(v7, v6), v8) ) + { + v9 = v6; + v10 = pItem; + RespawnDeadItem(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 ( ItemSpaceOk(v13, v12) ) + break; + if ( ++v22 > xxa ) + { + v11 = ++v21; + goto LABEL_14; + } + } + v15 = v13; + v10 = pItem; + RespawnDeadItem(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, 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; + drawpanflag = 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); +} +// 52571C: using guessed type int drawpanflag; + +//----- (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 == MIS_STONE && missile[v5]._misource == v2 ) + monster[missile[v5]._miVar2]._mmode = missile[v5]._miVar1; + if ( v6 == MIS_MANASHIELD && missile[v5]._misource == v2 ) + { + ClearMissileSpot(v4); + DeleteMissile(v4, v1); + } + if ( missile[v5]._mitype == MIS_ETHEREALIZE && missile[v5]._misource == v2 ) + { + ClearMissileSpot(v4); + DeleteMissile(v4, v1); + } + ++v1; + } + while ( v1 < nummissiles ); + } +} + +//----- (0044D8D1) -------------------------------------------------------- +void __fastcall InitLevelChange(int pnum) +{ + int v1; // esi + int v2; // 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); + v2 = v1; + plr[v2].destAction = -1; + v3 = v1 == myplr; + plr[v2]._pLvlChanging = 1; + if ( v3 ) + plr[v2].pLvlLoad = 10; +} +// 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_DoStand(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) -------------------------------------------------------- +bool __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) -------------------------------------------------------- +bool __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 + 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 ) + { + 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) == MT_ILLWEAV && *((_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; + 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 + { + _LOBYTE(v15) = 5; + v16 = plr[v9]._pIMaxDam - plr[v9]._pIMinDam + 1; + v48 = plr[v9]._pIMinDam; + v17 = random(v15, v16); + v18 = 100; + v19 = plr[v9]._pIBonusDamMod + plr[v9]._pDamageMod + (v48 + v17) * plr[v9]._pIBonusDam / 100 + v48 + v17; + if ( !_LOBYTE(plr[v9]._pClass) ) + { + _LOBYTE(v18) = 6; + v48 = plr[v9]._pLevel; + v20 = random(v18, 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 ) + { + _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 = 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; +} + +//----- (0044E442) -------------------------------------------------------- +bool __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 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 ) + { + 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) -------------------------------------------------------- +bool __fastcall 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; +} + +//----- (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 + bool 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 ) // quick attack + plr[v2]._pAnimFrame = 2; + if ( v3 & 0x40000 && (v4 == 1 || v4 == 3) ) // fast attack + ++plr[v2]._pAnimFrame; + if ( v3 & 0x80000 && (v4 == 1 || v4 == 3 || v4 == 5) ) // faster attack + ++plr[v2]._pAnimFrame; + if ( v3 & 0x100000 && (v4 == 1 || v4 == 4) ) // fastest attack + 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, MIS_WEAPEXP, 0, arglist, 0, 0); + v8 = v19; + } + if ( plr[v2]._pIFlags & 0x20 ) + { + AddMissile(v6, v7, 2, 0, 0, MIS_WEAPEXP, 0, arglist, 0, 0); + v8 = v19; + } + v12 = dMonster[0][v8]; + if ( v12 ) + { + if ( v12 <= 0 ) + v13 = -1 - v12; + else + v13 = v12 - 1; + 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; + v14 = PlrHitPlr(arglist, v16); +LABEL_46: + if ( v14 ) + { + //_LOBYTE(v17) = WeaponDur(arglist, 30); + if ( WeaponDur(arglist, 30) ) + goto LABEL_48; + } + goto LABEL_49; + } + if ( dObject[0][v8] > 0 ) + { + 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 ( !CanTalkToMonst(v10) ) + { + 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 ) // fire arrow + v5 = MIS_LARROW; + if ( v3 & 0x2000000 ) // lightning arrow + v5 = MIS_LARROW2; + 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 ( !WeaponDur(v1, 40) ) + { +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; + drawpanflag = 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; + drawpanflag = 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 drawpanflag; +// 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 ) + { + 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 ( dObject[object[v47]._ox-1][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 ( _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 ( dObject[object[v47]._ox-1][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 ( _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 - 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 ( _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 != QUEST_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 != QUEST_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-1][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 ( _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 != QUEST_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; + } + } +} + +//----- (0044F9BA) -------------------------------------------------------- +bool __fastcall PlrDeathModeOK(int pnum) +{ + int v1; // esi + bool 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)&spelldata[37].sBookLvl ); + *(_QWORD *)plr[v1]._pMemSpells &= v14; +} + +//----- (0044FB32) -------------------------------------------------------- +void __cdecl 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 ) + { + 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 ( !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_DoStand(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[4]._pHitPoints ); +} +// 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) -------------------------------------------------------- +bool __fastcall 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; +} + +//----- (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 ) + { + v6 = CheckSpell(v0, v2, v1, 0); + } + else + { + if ( (_BYTE)v1 != 2 ) + { + if ( (_BYTE)v1 == 3 ) + { + v6 = 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; + } + 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; + } +} +// 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]._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: + 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) && !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; + } + } +} +// 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; diff --git a/Source/player.h b/Source/player.h new file mode 100644 index 0000000..60dcaed --- /dev/null +++ b/Source/player.h @@ -0,0 +1,145 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//player +extern int plr_lframe_size; // idb +extern int plr_wframe_size; // idb +extern char plr_gfx_flag; // weak +extern int player_cpp_init_value; // weak +extern int plr_aframe_size; // idb +extern int myplr; +extern PlayerStruct plr[4]; +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 __cdecl player_cpp_init(); +void __fastcall player_init_cl2_hdrs(char *src, char *dst); +void __fastcall LoadPlrGFX(int pnum, int gfxflag); +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, int width); +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, int exp); +void __fastcall AddPlrMonstExper(int lvl, int exp, char pmask); +void __fastcall InitPlayer(int pnum, bool FirstTime); +void __cdecl InitMultiView(); +void __fastcall InitPlayerLoc(int pnum, bool flag); +bool __fastcall SolidLoc(int x, int y); +bool __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 dir); +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 d, int cx, int cy); +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 RespawnDeadItem(ItemStruct *itm, int x, int y); +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); +void __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_DoStand(int pnum); +int __fastcall PM_DoWalk(int pnum); +int __fastcall PM_DoWalk2(int pnum); +int __fastcall PM_DoWalk3(int pnum); +bool __fastcall WeaponDur(int pnum, int durrnd); +bool __fastcall PlrHitMonst(int pnum, int m); +bool __fastcall PlrHitPlr(int pnum, char p); +bool __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); +bool __fastcall PlrDeathModeOK(int pnum); +void __cdecl ValidatePlayer(); +void __cdecl ProcessPlayers(); +void __fastcall CheckCheatStats(int pnum); +void __fastcall ClrPlrPath(int pnum); +bool __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(); + +/* data */ + +extern int player_inf; +extern char ArmourChar[4]; +extern char WepChar[10]; +extern char CharChar[4]; + +/* rdata */ + +extern int plrxoff[9]; +extern int plryoff[9]; +extern int plrxoff2[9]; +extern int plryoff2[9]; +extern char PlrGFXAnimLens[3][11]; +extern int PWVel[4][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]; +extern unsigned char fix[9]; diff --git a/Source/plrmsg.cpp b/Source/plrmsg.cpp new file mode 100644 index 0000000..387a9db --- /dev/null +++ b/Source/plrmsg.cpp @@ -0,0 +1,235 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +int plrmsg_ticks; // weak +char plr_msg_slot; // weak +_plrmsg plr_msgs[8]; + +text_color text_color_from_player_num[2] = { COL_WHITE, COL_GOLD }; + +//----- (00450D33) -------------------------------------------------------- +void __fastcall 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 ); + } +} +// 69B7D0: using guessed type int plrmsg_ticks; + +//----- (00450D6A) -------------------------------------------------------- +char *__fastcall 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; +} +// 69B7D4: using guessed type char plr_msg_slot; + +//----- (00450DB3) -------------------------------------------------------- +size_t 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); +} +// 69B7D4: using guessed type char plr_msg_slot; + +//----- (00450DFA) -------------------------------------------------------- +void __fastcall 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); +} +// 69B7D4: using guessed type char plr_msg_slot; + +//----- (00450E64) -------------------------------------------------------- +void __cdecl 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 ); +} + +//----- (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].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 ); +} +// 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, v14, just); + v9 += fontkern[v14] + 1; + } + v6 = v16 + 10; + ++v17; + v16 += 10; + } + while ( v17 != 3 && *v5 ); + } +} diff --git a/Source/plrmsg.h b/Source/plrmsg.h new file mode 100644 index 0000000..2d115aa --- /dev/null +++ b/Source/plrmsg.h @@ -0,0 +1,28 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//plrmsg +extern int plrmsg_ticks; // weak +extern char plr_msg_slot; // weak +extern _plrmsg plr_msgs[8]; + +void __fastcall plrmsg_delay(int a1); +char *__fastcall ErrorPlrMsg(char *pszMsg); +size_t EventPlrMsg(char *pszFmt, ...); +void __fastcall SendPlrMsg(int pnum, const char *pszStr); +void __cdecl ClearPlrMsg(); +void __cdecl InitPlrMsg(); +void __cdecl DrawPlrMsg(); +void __fastcall PrintPlrMsg(int no, int x, int y, char *str, int just); + +/* data */ + +extern text_color text_color_from_player_num[2]; diff --git a/Source/portal.cpp b/Source/portal.cpp new file mode 100644 index 0000000..f4460bc --- /dev/null +++ b/Source/portal.cpp @@ -0,0 +1,234 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +#include "../types.h" + +PortalStruct portal[4]; +int portalindex; + +int WarpDropX[4] = { 57, 59, 61, 63 }; +int WarpDropY[4] = { 40, 40, 40, 40 }; + +//----- (00450FFE) -------------------------------------------------------- +void __cdecl InitPortals() +{ + int i; // edi + + for(i = 0; i < 4; i++) + { + if(delta_portal_inited(i)) + portal[i].open = 0; + } +} + +//----- (00451024) -------------------------------------------------------- +void __fastcall 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; +} + +//----- (00451062) -------------------------------------------------------- +void __fastcall 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; + } +} + +//----- (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)&portal[4].level ); +} +// 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) +{ + 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; + } +} + +//----- (0045118A) -------------------------------------------------------- +void __fastcall DeactivatePortal(int i) +{ + portal[i].open = 0; +} + +//----- (00451196) -------------------------------------------------------- +bool __fastcall PortalOnLevel(int i) +{ + if ( portal[i].level == currlevel ) + return 1; + else + return currlevel == 0; +} + +//----- (004511B8) -------------------------------------------------------- +void __fastcall 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); + } + } +} + +//----- (00451234) -------------------------------------------------------- +void __fastcall SetCurrentPortal(int p) +{ + portalindex = p; +} + +//----- (0045123B) -------------------------------------------------------- +void __cdecl 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); + } + } +} +// 5BB1ED: using guessed type char leveltype; +// 5CCB10: using guessed type char setlvlnum; +// 5CF31D: using guessed type char setlevel; + +//----- (004512E3) -------------------------------------------------------- +void __cdecl 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; + } +} + +//----- (00451346) -------------------------------------------------------- +bool __fastcall PosOkPortal(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)&portal[4].x ) + return 0; + } + return 1; +} +// 69BCFC: using guessed type int END_portalstruct; diff --git a/Source/portal.h b/Source/portal.h new file mode 100644 index 0000000..309de31 --- /dev/null +++ b/Source/portal.h @@ -0,0 +1,33 @@ +/* + * UNPUBLISHED -- Rights reserved under the copyright laws of the + * United States. Use of a copyright notice is precautionary only and + * does not imply publication or disclosure. + * + * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION + * OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR + * EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT. + */ + +//portal +extern PortalStruct portal[4]; +extern int portalindex; +// int END_portalstruct; // weak + +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); +bool __fastcall PortalOnLevel(int i); +void __fastcall RemovePortalMissile(int id); +void __fastcall SetCurrentPortal(int p); +void __cdecl GetPortalLevel(); +void __cdecl GetPortalLvlPos(); +bool __fastcall PosOkPortal(int level, int x, int y); + +/* rdata */ +extern int WarpDropX[4]; +extern int WarpDropY[4];