
//----- (0040102A) --------------------------------------------------------
char *__fastcall GetErr(int error_code)
{
	int v1; // edi
	unsigned int v2; // eax
	int v3; // eax
	signed int v4; // eax
	_BYTE *i; // ecx

	v1 = error_code;
	v2 = ((unsigned int)error_code >> 16) & 0x1FFF;
	if ( v2 == 2168 )
	{
		GetDSErr(error_code, (char *)error_buf, 256);
	}
	else if ( v2 == 2166 )
	{
		GetDDErr(error_code, (char *)error_buf, 256);
	}
	else
	{
		_LOBYTE(v3) = SErrGetErrorStr(error_code, (char *)error_buf, 256);
		if ( !v3 && !FormatMessageA(0x1000u, 0, v1, 0x400u, (LPSTR)error_buf, 0x100u, 0) )
			wsprintfA((LPSTR)error_buf, "unknown error 0x%08x", v1);
	}
	v4 = strlen((const char *)error_buf);
	for ( i = (unsigned char *)&appfat_terminated + v4 + 3; v4 > 0; *i = 0 )
	{
		--v4;
		if ( *--i != 13 && *i != 10 )
			break;
	}
	return (char *)error_buf;
}
// 4B7930: using guessed type int appfat_terminated;

//----- (004010CE) --------------------------------------------------------
void __fastcall GetDDErr(int error_code, char *error_buf, int error_buf_len)
{
	const char *v3; // eax
	char v4[4]; // [esp+0h] [ebp-14h]

	if ( error_code > (signed int)0x887601AE )
	{
		if ( error_code > (signed int)0x8876023D )
		{
			if ( error_code > (signed int)0x88760280 )
			{
				switch ( error_code )
				{
					case (int)0x88760294:
						v3 = "DDERR_CANTPAGEUNLOCK";
						goto LABEL_182;
					case (int)0x887602A8:
						v3 = "DDERR_NOTPAGELOCKED";
						goto LABEL_182;
					case 0:
						v3 = "DD_OK";
						goto LABEL_182;
				}
			}
			else
			{
				if ( error_code == 0x88760280 )
				{
					v3 = "DDERR_CANTPAGELOCK";
					goto LABEL_182;
				}
				switch ( error_code )
				{
					case (int)0x8876023E:
						v3 = "DDERR_BLTFASTCANTCLIP";
						goto LABEL_182;
					case (int)0x8876023F:
						v3 = "DDERR_NOBLTHW";
						goto LABEL_182;
					case (int)0x88760240:
						v3 = "DDERR_NODDROPSHW";
						goto LABEL_182;
					case (int)0x88760241:
						v3 = "DDERR_OVERLAYNOTVISIBLE";
						goto LABEL_182;
					case (int)0x88760242:
						v3 = "DDERR_NOOVERLAYDEST";
						goto LABEL_182;
					case (int)0x88760243:
						v3 = "DDERR_INVALIDPOSITION";
						goto LABEL_182;
					case (int)0x88760244:
						v3 = "DDERR_NOTAOVERLAYSURFACE";
						goto LABEL_182;
					case (int)0x88760245:
						v3 = "DDERR_EXCLUSIVEMODEALREADYSET";
						goto LABEL_182;
					case (int)0x88760246:
						v3 = "DDERR_NOTFLIPPABLE";
						goto LABEL_182;
					case (int)0x88760247:
						v3 = "DDERR_CANTDUPLICATE";
						goto LABEL_182;
					case (int)0x88760248:
						v3 = "DDERR_NOTLOCKED";
						goto LABEL_182;
					case (int)0x88760249:
						v3 = "DDERR_CANTCREATEDC";
						goto LABEL_182;
					case (int)0x8876024A:
						v3 = "DDERR_NODC";
						goto LABEL_182;
					case (int)0x8876024B:
						v3 = "DDERR_WRONGMODE";
						goto LABEL_182;
					case (int)0x8876024C:
						v3 = "DDERR_IMPLICITLYCREATED";
						goto LABEL_182;
					case (int)0x8876024D:
						v3 = "DDERR_NOTPALETTIZED";
						goto LABEL_182;
					case (int)0x8876024F:
						v3 = "DDERR_NOMIPMAPHW";
						goto LABEL_182;
					case (int)0x88760250:
						v3 = "DDERR_INVALIDSURFACETYPE";
						goto LABEL_182;
					case (int)0x8876026C:
						v3 = "DDERR_DCALREADYCREATED";
						goto LABEL_182;
					default:
						goto LABEL_178;
				}
			}
		}
		else
		{
			if ( error_code == 0x8876023D )
			{
				v3 = "DDERR_NOPALETTEHW";
				goto LABEL_182;
			}
			if ( error_code > (signed int)0x88760231 )
			{
				switch ( error_code )
				{
					case (int)0x88760232:
						v3 = "DDERR_DIRECTDRAWALREADYCREATED";
						goto LABEL_182;
					case (int)0x88760233:
						v3 = "DDERR_NODIRECTDRAWHW";
						goto LABEL_182;
					case (int)0x88760234:
						v3 = "DDERR_PRIMARYSURFACEALREADYEXISTS";
						goto LABEL_182;
					case (int)0x88760235:
						v3 = "DDERR_NOEMULATION";
						goto LABEL_182;
					case (int)0x88760236:
						v3 = "DDERR_REGIONTOOSMALL";
						goto LABEL_182;
					case (int)0x88760237:
						v3 = "DDERR_CLIPPERISUSINGHWND";
						goto LABEL_182;
					case (int)0x88760238:
						v3 = "DDERR_NOCLIPPERATTACHED";
						goto LABEL_182;
					case (int)0x88760239:
						v3 = "DDERR_NOHWND";
						goto LABEL_182;
					case (int)0x8876023A:
						v3 = "DDERR_HWNDSUBCLASSED";
						goto LABEL_182;
					case (int)0x8876023B:
						v3 = "DDERR_HWNDALREADYSET";
						goto LABEL_182;
					case (int)0x8876023C:
						v3 = "DDERR_NOPALETTEATTACHED";
						goto LABEL_182;
					default:
						goto LABEL_178;
				}
			}
			else
			{
				if ( error_code == 0x88760231 )
				{
					v3 = "DDERR_INVALIDDIRECTDRAWGUID";
					goto LABEL_182;
				}
				if ( error_code > (signed int)0x887601EA )
				{
					switch ( error_code )
					{
						case (int)0x887601FE:
							v3 = "DDERR_UNSUPPORTEDFORMAT";
							goto LABEL_182;
						case (int)0x88760208:
							v3 = "DDERR_UNSUPPORTEDMASK";
							goto LABEL_182;
						case (int)0x88760219:
							v3 = "DDERR_VERTICALBLANKINPROGRESS";
							goto LABEL_182;
						case (int)0x8876021C:
							v3 = "DDERR_WASSTILLDRAWING";
							goto LABEL_182;
						case (int)0x88760230:
							v3 = "DDERR_XALIGN";
							goto LABEL_182;
					}
				}
				else
				{
					switch ( error_code )
					{
						case (int)0x887601EA:
							v3 = "DDERR_TOOBIGWIDTH";
							goto LABEL_182;
						case (int)0x887601B3:
							v3 = "DDERR_CANTLOCKSURFACE";
							goto LABEL_182;
						case (int)0x887601B8:
							v3 = "DDERR_SURFACEISOBSCURED";
							goto LABEL_182;
						case (int)0x887601C2:
							v3 = "DDERR_SURFACELOST";
							goto LABEL_182;
						case (int)0x887601CC:
							v3 = "DDERR_SURFACENOTATTACHED";
							goto LABEL_182;
						case (int)0x887601D6:
							v3 = "DDERR_TOOBIGHEIGHT";
							goto LABEL_182;
						case (int)0x887601E0:
							v3 = "DDERR_TOOBIGSIZE";
							goto LABEL_182;
					}
				}
			}
		}
		goto LABEL_178;
	}
	if ( error_code == 0x887601AE )
	{
		v3 = "DDERR_SURFACEBUSY";
		goto LABEL_182;
	}
	if ( error_code > (signed int)0x887600DC )
	{
		if ( error_code > (signed int)0x8876014A )
		{
			if ( error_code > (signed int)0x8876017E )
			{
				switch ( error_code )
				{
					case (int)0x88760180:
						v3 = "DDERR_OVERLAYCOLORKEYONLYONEACTIVE";
						goto LABEL_182;
					case (int)0x88760183:
						v3 = "DDERR_PALETTEBUSY";
						goto LABEL_182;
					case (int)0x88760190:
						v3 = "DDERR_COLORKEYNOTSET";
						goto LABEL_182;
					case (int)0x8876019A:
						v3 = "DDERR_SURFACEALREADYATTACHED";
						goto LABEL_182;
					case (int)0x887601A4:
						v3 = "DDERR_SURFACEALREADYDEPENDENT";
						goto LABEL_182;
				}
			}
			else
			{
				switch ( error_code )
				{
					case (int)0x8876017E:
						v3 = "DDERR_OVERLAYCANTCLIP";
						goto LABEL_182;
					case (int)0x8876014F:
						v3 = "DDERR_NOVSYNCHW";
						goto LABEL_182;
					case (int)0x88760154:
						v3 = "DDERR_NOZBUFFERHW";
						goto LABEL_182;
					case (int)0x8876015E:
						v3 = "DDERR_NOZOVERLAYHW";
						goto LABEL_182;
					case (int)0x88760168:
						v3 = "DDERR_OUTOFCAPS";
						goto LABEL_182;
					case (int)0x8876017C:
						v3 = "DDERR_OUTOFVIDEOMEMORY";
						goto LABEL_182;
				}
			}
		}
		else
		{
			if ( error_code == 0x8876014A )
			{
				v3 = "DDERR_NOTEXTUREHW";
				goto LABEL_182;
			}
			if ( error_code > (signed int)0x88760118 )
			{
				switch ( error_code )
				{
					case (int)0x88760122:
						v3 = "DDERR_NOROTATIONHW";
						goto LABEL_182;
					case (int)0x88760136:
						v3 = "DDERR_NOSTRETCHHW";
						goto LABEL_182;
					case (int)0x8876013C:
						v3 = "DDERR_NOT4BITCOLOR";
						goto LABEL_182;
					case (int)0x8876013D:
						v3 = "DDERR_NOT4BITCOLORINDEX";
						goto LABEL_182;
					case (int)0x88760140:
						v3 = "DDERR_NOT8BITCOLOR";
						goto LABEL_182;
				}
			}
			else
			{
				switch ( error_code )
				{
					case (int)0x88760118:
						v3 = "DDERR_NORASTEROPHW";
						goto LABEL_182;
					case (int)0x887600E1:
						v3 = "DDERR_NOEXCLUSIVEMODE";
						goto LABEL_182;
					case (int)0x887600E6:
						v3 = "DDERR_NOFLIPHW";
						goto LABEL_182;
					case (int)0x887600F0:
						v3 = "DDERR_NOGDI";
						goto LABEL_182;
					case (int)0x887600FA:
						v3 = "DDERR_NOMIRRORHW";
						goto LABEL_182;
					case (int)0x887600FF:
						v3 = "DDERR_NOTFOUND";
						goto LABEL_182;
					case (int)0x88760104:
						v3 = "DDERR_NOOVERLAYHW";
						goto LABEL_182;
				}
			}
		}
		goto LABEL_178;
	}
	if ( error_code == 0x887600DC )
	{
		v3 = "DDERR_NOCOLORKEYHW";
		goto LABEL_182;
	}
	if ( error_code > (signed int)0x8876006E )
	{
		if ( error_code > (signed int)0x887600AA )
		{
			switch ( error_code )
			{
				case (int)0x887600B4:
					v3 = "DDERR_NOALPHAHW";
					goto LABEL_182;
				case (int)0x887600CD:
					v3 = "DDERR_NOCLIPLIST";
					goto LABEL_182;
				case (int)0x887600D2:
					v3 = "DDERR_NOCOLORCONVHW";
					goto LABEL_182;
				case (int)0x887600D4:
					v3 = "DDERR_NOCOOPERATIVELEVELSET";
					goto LABEL_182;
				case (int)0x887600D7:
					v3 = "DDERR_NOCOLORKEY";
					goto LABEL_182;
			}
		}
		else
		{
			switch ( error_code )
			{
				case (int)0x887600AA:
					v3 = "DDERR_NO3D";
					goto LABEL_182;
				case (int)0x88760078:
					v3 = "DDERR_INVALIDMODE";
					goto LABEL_182;
				case (int)0x88760082:
					v3 = "DDERR_INVALIDOBJECT";
					goto LABEL_182;
				case (int)0x88760091:
					v3 = "DDERR_INVALIDPIXELFORMAT";
					goto LABEL_182;
				case (int)0x88760096:
					v3 = "DDERR_INVALIDRECT";
					goto LABEL_182;
				case (int)0x887600A0:
					v3 = "DDERR_LOCKEDSURFACES";
					goto LABEL_182;
			}
		}
		goto LABEL_178;
	}
	if ( error_code == 0x8876006E )
	{
		v3 = "DDERR_INVALIDCLIPLIST";
		goto LABEL_182;
	}
	if ( error_code > (signed int)0x88760014 )
	{
		switch ( error_code )
		{
			case (int)0x88760028:
				v3 = "DDERR_CURRENTLYNOTAVAIL";
				goto LABEL_182;
			case (int)0x88760037:
				v3 = "DDERR_EXCEPTION";
				goto LABEL_182;
			case (int)0x8876005A:
				v3 = "DDERR_HEIGHTALIGN";
				goto LABEL_182;
			case (int)0x8876005F:
				v3 = "DDERR_INCOMPATIBLEPRIMARY";
				goto LABEL_182;
			case (int)0x88760064:
				v3 = "DDERR_INVALIDCAPS";
				goto LABEL_182;
		}
		goto LABEL_178;
	}
	switch ( error_code )
	{
		case (int)0x88760014:
			v3 = "DDERR_CANNOTDETACHSURFACE";
			goto LABEL_182;
		case (int)0x80004001:
			v3 = "DDERR_UNSUPPORTED";
			goto LABEL_182;
		case (int)0x80004005:
			v3 = "DDERR_GENERIC";
			goto LABEL_182;
		case (int)0x8007000E:
			v3 = "DDERR_OUTOFMEMORY";
			goto LABEL_182;
		case (int)0x80070057:
			v3 = "DDERR_INVALIDPARAMS";
			goto LABEL_182;
		case (int)0x88760005:
			v3 = "DDERR_ALREADYINITIALIZED";
			goto LABEL_182;
	}
	if ( error_code != 0x8876000A )
	{
LABEL_178:
		strcpy(v4, "DDERR unknown 0x%x");
		sprintf(error_buf, v4, error_code);
		return;
	}
	v3 = "DDERR_CANNOTATTACHSURFACE";
LABEL_182:
	strncpy(error_buf, v3, error_buf_len);
}

//----- (00401831) --------------------------------------------------------
void __fastcall GetDSErr(int error_code, char *error_buf, int error_buf_len)
{
	const char *v3; // eax
	char v4[4]; // [esp+0h] [ebp-14h]

	if ( error_code > (signed int)0x88780032 )
	{
		switch ( error_code )
		{
			case (int)0x88780046:
				v3 = "DSERR_PRIOLEVELNEEDED";
				goto LABEL_29;
			case (int)0x88780064:
				v3 = "DSERR_BADFORMAT";
				goto LABEL_29;
			case (int)0x88780078:
				v3 = "DSERR_NODRIVER";
				goto LABEL_29;
			case (int)0x88780082:
				v3 = "DSERR_ALREADYINITIALIZED";
				goto LABEL_29;
			case (int)0x88780096:
				v3 = "DSERR_BUFFERLOST";
				goto LABEL_29;
			case 0:
				v3 = "DS_OK";
				goto LABEL_29;
		}
		goto LABEL_22;
	}
	switch ( error_code )
	{
		case (int)0x88780032:
			v3 = "DSERR_INVALIDCALL";
			goto LABEL_29;
		case (int)0x80004002:
			v3 = "E_NOINTERFACE";
			goto LABEL_29;
		case (int)0x80040110:
			v3 = "DSERR_NOAGGREGATION";
			goto LABEL_29;
		case (int)0x8007000E:
			v3 = "DSERR_OUTOFMEMORY";
			goto LABEL_29;
		case (int)0x80070057:
			v3 = "DSERR_INVALIDPARAM";
			goto LABEL_29;
		case (int)0x8878000A:
			v3 = "DSERR_ALLOCATED";
			goto LABEL_29;
	}
	if ( error_code != 0x8878001E )
	{
LABEL_22:
		strcpy(v4, "DSERR unknown 0x%x");
		sprintf(error_buf, v4, error_code);
		return;
	}
	v3 = "DSERR_CONTROLUNAVAIL";
LABEL_29:
	strncpy(error_buf, v3, error_buf_len);
}

//----- (0040193A) --------------------------------------------------------
char *__cdecl GetLastErr()
{
	int v0; // eax

	v0 = GetLastError();
	return GetErr(v0);
}

//----- (00401947) --------------------------------------------------------
void TermMsg(char *format, ...)
{
	va_list arglist; // [esp+8h] [ebp+8h]

	va_start(arglist, format);
	FreeDlg();
	if ( format )
		MsgBox(format, arglist);
	init_cleanup(0);
	exit(1);
}

//----- (00401975) --------------------------------------------------------
void __fastcall MsgBox(char *format, va_list va)
{
	char Text[256]; // [esp+0h] [ebp-100h]

	wvsprintfA(Text, format, va);
	if ( ghMainWnd )
		SetWindowPos(ghMainWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x13u);
	MessageBoxA(ghMainWnd, Text, "ERROR", 0x2010u);
}

//----- (004019C7) --------------------------------------------------------
void __cdecl FreeDlg()
{
	int v0; // eax

	if ( terminating && cleanup_thread_id != GetCurrentThreadId() )
		Sleep(20000u);
	terminating = 1;
	cleanup_thread_id = GetCurrentThreadId();
	dx_cleanup();
	if ( (unsigned char)gbMaxPlayers > 1u )
	{
		_LOBYTE(v0) = SNetLeaveGame(3);
		if ( v0 )
			Sleep(2000u);
	}
	SNetDestroy();
	ShowCursor(1);
}
// 4B7A34: using guessed type int terminating;
// 4B7A38: using guessed type int cleanup_thread_id;
// 679660: using guessed type char gbMaxPlayers;

//----- (00401A30) --------------------------------------------------------
void DrawDlg(char *format, ...)
{
	char text[256]; // [esp+0h] [ebp-100h]
	va_list arglist; // [esp+10Ch] [ebp+Ch]

	va_start(arglist, format);
	wvsprintfA(text, format, arglist);
	SDrawMessageBox(text, "Diablo", 8240);
}

//----- (00401A65) --------------------------------------------------------
void __fastcall DDErrDlg(int error_code, int log_line_nr, char *log_file_path)
{
	int v3; // esi
	char *v4; // eax

	v3 = log_line_nr;
	if ( error_code )
	{
		v4 = GetErr(error_code);
		TermMsg("Direct draw error (%s:%d)\n%s", log_file_path, v3, v4);
	}
}

//----- (00401A88) --------------------------------------------------------
void __fastcall DSErrDlg(int error_code, int log_line_nr, char *log_file_path)
{
	int v3; // esi
	char *v4; // eax

	v3 = log_line_nr;
	if ( error_code )
	{
		v4 = GetErr(error_code);
		TermMsg("Direct sound error (%s:%d)\n%s", log_file_path, v3, v4);
	}
}

//----- (00401AAB) --------------------------------------------------------
void __fastcall CenterDlg(HWND hDlg)
{
	LONG v1; // esi
	LONG v2; // edi
	int v3; // ebx
	char *v4; // eax
	struct tagRECT Rect; // [esp+Ch] [ebp-1Ch]
	int v6; // [esp+1Ch] [ebp-Ch]
	HDC hdc; // [esp+20h] [ebp-8h]
	HWND hWnd; // [esp+24h] [ebp-4h]

	hWnd = hDlg;
	GetWindowRect(hDlg, &Rect);
	v1 = Rect.right - Rect.left;
	v2 = Rect.bottom - Rect.top;
	hdc = GetDC(hWnd);
	v6 = GetDeviceCaps(hdc, 8);
	v3 = GetDeviceCaps(hdc, 10);
	ReleaseDC(hWnd, hdc);
	if ( !SetWindowPos(hWnd, 0, (v6 - v1) / 2, (v3 - v2) / 2, 0, 0, 5u) )
	{
		v4 = GetLastErr();
		TermMsg("center_window: %s", v4);
	}
}

//----- (00401B3D) --------------------------------------------------------
void __fastcall TermDlg(int template_id, int error_code, char *log_file_path, int log_line_nr)
{
	int v4; // ebx
	int v5; // edi
	char *v6; // esi
	char *v7; // eax
	char *v8; // eax
	LPARAM dwInitParam[128]; // [esp+Ch] [ebp-200h]

	v4 = error_code;
	v5 = template_id;
	FreeDlg();
	v6 = log_file_path;
	v7 = strrchr(log_file_path, 92);
	if ( v7 )
		v6 = v7 + 1;
	v8 = GetErr(v4);
	wsprintfA((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v6, log_line_nr);
	if ( DialogBoxParamA(hInstance, (LPCSTR)(unsigned short)v5, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam) == -1 )
		TermMsg("ErrDlg: %d", v5);
	TermMsg(0);
}

//----- (00401BCA) --------------------------------------------------------
bool __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text)
{
	if ( uMsg == 272 )
	{
		TextDlg(hDlg, text);
	}
	else
	{
		if ( uMsg != 273 )
			return 0;
		if ( (_WORD)wParam == 1 )
		{
			EndDialog(hDlg, 1);
		}
		else if ( (_WORD)wParam == 2 )
		{
			EndDialog(hDlg, 0);
		}
	}
	return 1;
}

//----- (00401C0F) --------------------------------------------------------
void __fastcall TextDlg(HWND hDlg, char *text)
{
	char *v2; // esi
	HWND v3; // edi

	v2 = text;
	v3 = hDlg;
	CenterDlg(hDlg);
	if ( v2 )
		SetDlgItemTextA(v3, 1000, v2);
}

//----- (00401C2E) --------------------------------------------------------
void __fastcall ErrDlg(template_id template_id, int error_code, char *log_file_path, int log_line_nr)
{
	char *v4; // esi
	int v5; // edi
	unsigned short v6; // bx
	char *v7; // eax
	char *v8; // eax
	LPARAM dwInitParam[128]; // [esp+Ch] [ebp-200h]

	v4 = log_file_path;
	v5 = error_code;
	v6 = template_id;
	v7 = strrchr(log_file_path, 92);
	if ( v7 )
		v4 = v7 + 1;
	v8 = GetErr(v5);
	wsprintfA((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v4, log_line_nr);
	DialogBoxParamA(hInstance, (LPCSTR)v6, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam);
}

//----- (00401C9C) --------------------------------------------------------
void __fastcall FileErrDlg(char *error)
{
	char *v1; // esi

	v1 = error;
	FreeDlg();
	if ( !v1 )
		v1 = &empty_string;
	if ( DialogBoxParamA(hInstance, (LPCSTR)0x6A, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 )
		TermMsg("FileErrDlg");
	TermMsg(0);
}

//----- (00401CE1) --------------------------------------------------------
void __fastcall DiskFreeDlg(char *error)
{
	char *v1; // esi

	v1 = error;
	FreeDlg();
	if ( DialogBoxParamA(hInstance, (LPCSTR)0x6E, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 )
		TermMsg("DiskFreeDlg");
	TermMsg(0);
}

//----- (00401D1D) --------------------------------------------------------
bool __cdecl InsertCDDlg()
{
	INT_PTR v0; // edi

	ShowCursor(1);
	v0 = DialogBoxParamA(hInstance, (LPCSTR)0x70, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)&empty_string);
	if ( v0 == -1 )
		TermMsg("InsertCDDlg");
	ShowCursor(0);
	return v0 == 1;
}

//----- (00401D68) --------------------------------------------------------
void __fastcall DirErrDlg(char *error)
{
	char *v1; // esi

	v1 = error;
	FreeDlg();
	if ( DialogBoxParamA(hInstance, (LPCSTR)0x72, ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 )
		TermMsg("DirErrorDlg");
	TermMsg(0);
}

//----- (00401DA4) --------------------------------------------------------
void __cdecl InitAutomapOnce()
{
	*(_DWORD *)&automapflag = 0;
	AutoMapScale = 50;
	CT_4B84B8 = 32;
	CT_4B84BC = 16;
	CT_4B84C0 = 8;
	CT_4B84C4 = 4;
	CT_4B84C8 = 2;
}
// 4B84B8: using guessed type int CT_4B84B8;
// 4B84BC: using guessed type int CT_4B84BC;
// 4B84C0: using guessed type int CT_4B84C0;
// 4B84C4: using guessed type int CT_4B84C4;
// 4B84C8: using guessed type int CT_4B84C8;

//----- (00401DE8) --------------------------------------------------------
void __cdecl InitAutomap()
{
	signed int v0; // edi
	signed int v1; // ecx
	int v2; // esi
	char v3; // al
	int v4; // esi
	char v5; // al
	char *v6; // ecx
	unsigned char *v7; // eax
	int v8; // ecx
	unsigned char *v9; // edx
	unsigned int i; // esi
	unsigned char v11; // bl
	_BYTE *v12; // edx
	signed int v13; // ecx
	_BYTE *v14; // eax
	signed int v15; // edx
	int size; // [esp+Ch] [ebp-4h]

	v0 = 50;
	v1 = 0;
	do
	{
		v2 = (v0 << 6) / 100;
		v3 = 2 * (320 / v2);
		v4 = 320 % v2;
		v5 = v3 + 1;
		AMbyte_4B7E4C[v1] = v5;
		if ( v4 )
			AMbyte_4B7E4C[v1] = v5 + 1;
		if ( v4 >= 32 * v0 / 100 )
			++AMbyte_4B7E4C[v1];
		v0 += 5;
		++v1;
	}
	while ( v1 < 31 );
	memset(automaptype, 0, 0x400u);
	switch ( leveltype )
	{
		case DTYPE_CATHEDRAL:
			v6 = "Levels\\L1Data\\L1.AMP";
			break;
		case DTYPE_CATACOMBS:
			v6 = "Levels\\L2Data\\L2.AMP";
			break;
		case DTYPE_CAVES:
			v6 = "Levels\\L3Data\\L3.AMP";
			break;
		case DTYPE_HELL:
			v6 = "Levels\\L4Data\\L4.AMP";
			break;
		default:
			return;
	}
	v7 = LoadFileInMem(v6, &size);
	size = (unsigned int)size >> 1;
	v9 = v7;
	for ( i = 1; i <= size; ++i )
	{
		v11 = *v9;
		v12 = v9 + 1;
		_LOWORD(v0) = v11;
		_LOBYTE(v8) = *v12;
		v9 = v12 + 1;
		_LOWORD(v8) = (unsigned char)v8;
		v8 = v0 + (v8 << 8);
		automaptype[i] = v8;
	}
	mem_free_dbg(v7);
	memset(automapview, 0, 0x640u);
	v13 = 0;
	do
	{
		v14 = (unsigned char *)dFlags + v13;
		v15 = 112;
		do
		{
			*v14 &= 0x7Fu;
			v14 += 112;
			--v15;
		}
		while ( v15 );
		++v13;
	}
	while ( v13 < 112 );
}
// 5BB1ED: using guessed type char leveltype;

//----- (00401EF4) --------------------------------------------------------
void __cdecl StartAutomap()
{
	AutoMapXOfs = 0;
	AutoMapYOfs = 0;
	*(_DWORD *)&automapflag = 1;
}
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;

//----- (00401F0D) --------------------------------------------------------
void __cdecl AutomapUp()
{
	--AutoMapXOfs;
	--AutoMapYOfs;
}
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;

//----- (00401F1A) --------------------------------------------------------
void __cdecl AutomapDown()
{
	++AutoMapXOfs;
	++AutoMapYOfs;
}
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;

//----- (00401F27) --------------------------------------------------------
void __cdecl AutomapLeft()
{
	--AutoMapXOfs;
	++AutoMapYOfs;
}
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;

//----- (00401F34) --------------------------------------------------------
void __cdecl AutomapRight()
{
	++AutoMapXOfs;
	--AutoMapYOfs;
}
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;

//----- (00401F41) --------------------------------------------------------
void __cdecl AutomapZoomIn()
{
	if ( AutoMapScale < 200 )
	{
		AutoMapScale += 5;
		CT_4B84B8 = (AutoMapScale << 6) / 100;
		CT_4B84BC = CT_4B84B8 >> 1;
		CT_4B84C0 = CT_4B84B8 >> 2;
		CT_4B84C4 = CT_4B84B8 >> 3;
		CT_4B84C8 = CT_4B84B8 >> 4;
	}
}
// 4B84B8: using guessed type int CT_4B84B8;
// 4B84BC: using guessed type int CT_4B84BC;
// 4B84C0: using guessed type int CT_4B84C0;
// 4B84C4: using guessed type int CT_4B84C4;
// 4B84C8: using guessed type int CT_4B84C8;

//----- (00401F80) --------------------------------------------------------
void __cdecl AutomapZoomOut()
{
	if ( AutoMapScale > 50 )
	{
		AutoMapScale -= 5;
		CT_4B84B8 = (AutoMapScale << 6) / 100;
		CT_4B84BC = CT_4B84B8 >> 1;
		CT_4B84C0 = CT_4B84B8 >> 2;
		CT_4B84C4 = CT_4B84B8 >> 3;
		CT_4B84C8 = CT_4B84B8 >> 4;
	}
}
// 4B84B8: using guessed type int CT_4B84B8;
// 4B84BC: using guessed type int CT_4B84BC;
// 4B84C0: using guessed type int CT_4B84C0;
// 4B84C4: using guessed type int CT_4B84C4;
// 4B84C8: using guessed type int CT_4B84C8;

//----- (00401FBD) --------------------------------------------------------
void __cdecl DrawAutomap()
{
	int v0; // eax
	int v1; // ecx
	int v2; // edx
	int v3; // edx
	int v4; // ecx
	int v5; // eax
	int v6; // esi
	int v7; // edx
	int v8; // edx
	int v9; // esi
	int v10; // ebx
	int v11; // edi
	int v12; // esi
	int v13; // edi
	int v14; // esi
	int v15; // ebp
	short v16; // ax
	int v17; // ebp
	short v18; // ax
	int v19; // [esp+0h] [ebp-18h]
	int screen_x; // [esp+4h] [ebp-14h]
	int screen_xa; // [esp+4h] [ebp-14h]
	int v22; // [esp+8h] [ebp-10h]
	int ty; // [esp+Ch] [ebp-Ch]
	int tya; // [esp+Ch] [ebp-Ch]
	int v25; // [esp+10h] [ebp-8h]
	int screen_y; // [esp+14h] [ebp-4h]

	if ( leveltype )
	{
		screen_buf_end = (int)gpBuffer->row[352].col_unused_1;
		v0 = AutoMapXOfs;
		v1 = (ViewX - 16) >> 1;
		v2 = AutoMapXOfs + v1;
		if ( AutoMapXOfs + v1 < 0 )
		{
			do
			{
				++v0;
				++v2;
			}
			while ( v2 < 0 );
			AutoMapXOfs = v0;
		}
		v3 = v0 + v1;
		if ( v0 + v1 >= 40 )
		{
			do
			{
				--v0;
				--v3;
			}
			while ( v3 >= 40 );
			AutoMapXOfs = v0;
		}
		v4 = v0 + v1;
		AMdword_4B7E40 = v4;
		v5 = AutoMapYOfs;
		v6 = (ViewY - 16) >> 1;
		v7 = AutoMapYOfs + v6;
		if ( AutoMapYOfs + v6 < 0 )
		{
			do
			{
				++v5;
				++v7;
			}
			while ( v7 < 0 );
			AutoMapYOfs = v5;
		}
		v8 = v5 + v6;
		if ( v5 + v6 >= 40 )
		{
			do
			{
				--v5;
				--v8;
			}
			while ( v8 >= 40 );
			AutoMapYOfs = v5;
		}
		v9 = v5 + v6;
		AMdword_4B7E44 = v9;
		v10 = AMbyte_4B7E4C[(AutoMapScale - 50) / 5];
		if ( ScrollInfo._sxoff + ScrollInfo._syoff )
			++v10;
		v22 = v4 - v10;
		v19 = v9 - 1;
		if ( v10 & 1 )
		{
			v11 = 384 - CT_4B84B8 * ((v10 - 1) >> 1);
			v12 = 336 - CT_4B84BC * ((v10 + 1) >> 1);
		}
		else
		{
			v11 = CT_4B84BC - CT_4B84B8 * (v10 >> 1) + 384;
			v12 = 336 - CT_4B84BC * (v10 >> 1) - CT_4B84C0;
		}
		if ( ViewX & 1 )
		{
			v11 -= CT_4B84C0;
			v12 -= CT_4B84C4;
		}
		if ( ViewY & 1 )
		{
			v11 += CT_4B84C0;
			v12 -= CT_4B84C4;
		}
		v13 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) + v11;
		v14 = (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + v12;
		if ( invflag || sbookflag )
			v13 -= 160;
		if ( chrflag || questlog )
			v13 += 160;
		if ( v10 + 1 >= 0 )
		{
			v25 = v10 + 2;
			do
			{
				v15 = 0;
				screen_x = v13;
				if ( v10 > 0 )
				{
					ty = v19;
					do
					{
						v16 = GetAutomapType(v22 + v15, ty, 1);
						if ( v16 )
							DrawAutomapType(screen_x, v14, v16);
						screen_x += CT_4B84B8;
						++v15;
						--ty;
					}
					while ( v15 < v10 );
				}
				++v19;
				screen_xa = 0;
				v17 = v13 - CT_4B84BC;
				screen_y = v14 + CT_4B84C0;
				if ( v10 >= 0 )
				{
					tya = v19;
					do
					{
						v18 = GetAutomapType(v22 + screen_xa, tya, 1);
						if ( v18 )
							DrawAutomapType(v17, screen_y, v18);
						v17 += CT_4B84B8;
						++screen_xa;
						--tya;
					}
					while ( screen_xa <= v10 );
				}
				++v22;
				v14 += CT_4B84BC;
				--v25;
			}
			while ( v25 );
		}
		DrawAutomapPlr();
		DrawAutomapGame();
	}
	else
	{
		DrawAutomapGame();
	}
}
// 4B7E40: using guessed type int AMdword_4B7E40;
// 4B7E44: using guessed type int AMdword_4B7E44;
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;
// 4B84B8: using guessed type int CT_4B84B8;
// 4B84BC: using guessed type int CT_4B84BC;
// 4B84C0: using guessed type int CT_4B84C0;
// 4B84C4: using guessed type int CT_4B84C4;
// 4B8968: using guessed type int sbookflag;
// 5BB1ED: using guessed type char leveltype;
// 69BD04: using guessed type int questlog;
// 69CF0C: using guessed type int screen_buf_end;

//----- (00402233) --------------------------------------------------------
void __fastcall DrawAutomapType(int screen_x, int screen_y, short automap_type)
{
	char v3; // al
	int v4; // ebx
	int v5; // edi
	int a3; // ST2C_4
	int a1; // ST28_4
	int a2; // ST24_4
	int v9; // edx
	int v10; // ST28_4
	int v11; // ST2C_4
	int v12; // ST24_4
	int v13; // ST2C_4
	int v14; // ST28_4
	int v15; // ST24_4
	int v16; // ST28_4
	int v17; // ST24_4
	int v18; // ST2C_4
	int v19; // ST2C_4
	int v20; // ST28_4
	int v21; // ST24_4
	int v22; // ST28_4
	int v23; // ST2C_4
	int v24; // ST24_4
	int v25; // ST28_4
	int v26; // ST24_4
	int v27; // ST2C_4
	int v28; // [esp-Ch] [ebp-34h]
	int v29; // [esp-8h] [ebp-30h]
	signed int v30; // [esp+Ch] [ebp-1Ch]
	signed int v31; // [esp+10h] [ebp-18h]
	signed int v32; // [esp+14h] [ebp-14h]
	char v33; // [esp+27h] [ebp-1h]
	int automap_typea; // [esp+30h] [ebp+8h]
	int automap_typeb; // [esp+30h] [ebp+8h]
	int automap_typec; // [esp+30h] [ebp+8h]
	int automap_typed; // [esp+30h] [ebp+8h]
	int automap_typee; // [esp+30h] [ebp+8h]
	int automap_typef; // [esp+30h] [ebp+8h]
	int automap_typeg; // [esp+30h] [ebp+8h]

	v3 = automap_type;
	v4 = screen_x;
	v5 = screen_y;
	v33 = _HIBYTE(automap_type);
	if ( automap_type & 0x4000 )
	{
		ENG_set_pixel(screen_x, screen_y, 200);
		ENG_set_pixel(v4 - CT_4B84C4, v5 - CT_4B84C8, 200);
		ENG_set_pixel(v4 - CT_4B84C4, CT_4B84C8 + v5, 200);
		ENG_set_pixel(CT_4B84C4 + v4, v5 - CT_4B84C8, 200);
		ENG_set_pixel(CT_4B84C4 + v4, CT_4B84C8 + v5, 200);
		ENG_set_pixel(v4 - CT_4B84C0, v5, 200);
		ENG_set_pixel(CT_4B84C0 + v4, v5, 200);
		ENG_set_pixel(v4, v5 - CT_4B84C4, 200);
		ENG_set_pixel(v4, CT_4B84C4 + v5, 200);
		ENG_set_pixel(v4 + CT_4B84C4 - CT_4B84BC, CT_4B84C8 + v5, 200);
		ENG_set_pixel(v4 + CT_4B84BC - CT_4B84C4, CT_4B84C8 + v5, 200);
		ENG_set_pixel(v4 - CT_4B84C0, CT_4B84C4 + v5, 200);
		ENG_set_pixel(CT_4B84C0 + v4, CT_4B84C4 + v5, 200);
		ENG_set_pixel(v4 - CT_4B84C4, v5 + CT_4B84C0 - CT_4B84C8, 200);
		ENG_set_pixel(CT_4B84C4 + v4, v5 + CT_4B84C0 - CT_4B84C8, 200);
		ENG_set_pixel(v4, CT_4B84C0 + v5, 200);
		v3 = automap_type;
	}
	if ( automap_type < 0 )
	{
		engine_4170BD(v4 - CT_4B84C4, v5 - CT_4B84C4 - CT_4B84C8, v4 + CT_4B84C4 + CT_4B84C0, CT_4B84C8 + v5, 144);
		engine_4170BD(v4 - CT_4B84C0, v5 - CT_4B84C4, CT_4B84C0 + v4, CT_4B84C4 + v5, 144);
		engine_4170BD(v4 - CT_4B84C0 - CT_4B84C4, v5 - CT_4B84C8, CT_4B84C4 + v4, v5 + CT_4B84C4 + CT_4B84C8, 144);
		engine_4170BD(v4 - CT_4B84BC, v5, v4, v5 + CT_4B84C0, 144);
		v3 = automap_type;
	}
	v31 = 0;
	v30 = 0;
	v32 = 0;
	switch ( v3 & 0xF )
	{
		case 1:
			a3 = v4 - CT_4B84C0 + CT_4B84BC;
			a1 = v4 - CT_4B84C0;
			a2 = v5 - CT_4B84C0;
			automap_typea = v5 - CT_4B84C4;
			engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C0, v5 - CT_4B84C4, 200);
			engine_4170BD(v4, a2, a3, automap_typea, 200);
			engine_4170BD(v4, v5, a1, automap_typea, 200);
			v9 = v5;
			v29 = automap_typea;
			v28 = a3;
			goto LABEL_36;
		case 2:
		case 5:
			goto LABEL_8;
		case 3:
		case 6:
			goto LABEL_17;
		case 4:
			v31 = 1;
			goto LABEL_8;
		case 7:
			goto LABEL_25;
		case 8:
			v30 = 1;
LABEL_8:
			if ( automap_type & 0x100 )
			{
				v10 = v4 - CT_4B84BC;
				v11 = v4 - CT_4B84C0;
				v12 = v5 - CT_4B84C0;
				automap_typeb = v5 - CT_4B84C4;
				engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C4, v5 - CT_4B84C0 + CT_4B84C8, 200);
				engine_4170BD(v10, v5, v10 + CT_4B84C4, v5 - CT_4B84C8, 200);
				engine_4170BD(v11, v12, v10, automap_typeb, 144);
				engine_4170BD(v11, v12, v4, automap_typeb, 144);
				engine_4170BD(v11, v5, v10, automap_typeb, 144);
				engine_4170BD(v11, v5, v4, automap_typeb, 144);
			}
			if ( v33 & 0x10 )
			{
				engine_4170BD(v4 - CT_4B84C0, v5 - CT_4B84C4, v4 - CT_4B84BC, v5, 200);
				v33 |= 4u;
			}
			if ( v33 & 4 )
			{
				v13 = v4 - CT_4B84C0 + CT_4B84BC;
				v14 = v4 - CT_4B84C0;
				v15 = v5 - CT_4B84C0;
				automap_typec = v5 - CT_4B84C4;
				engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C0, v5 - CT_4B84C4, 200);
				engine_4170BD(v4, v15, v13, automap_typec, 200);
				engine_4170BD(v4, v5, v14, automap_typec, 200);
				engine_4170BD(v4, v5, v13, automap_typec, 200);
			}
			if ( !(v33 & 0x15) )
				engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84BC, v5, 200);
			if ( v31 )
				goto LABEL_17;
			goto LABEL_25;
		case 9:
			v32 = 1;
LABEL_17:
			if ( v33 & 2 )
			{
				v16 = CT_4B84C0 + v4;
				v17 = v5 - CT_4B84C0;
				v18 = v4 + CT_4B84BC;
				automap_typed = v5 - CT_4B84C4;
				engine_4170BD(v4, v5 - CT_4B84C0, v4 + CT_4B84C4, v5 - CT_4B84C0 + CT_4B84C8, 200);
				engine_4170BD(v18, v5, v18 - CT_4B84C4, v5 - CT_4B84C8, 200);
				engine_4170BD(v16, v17, v4, automap_typed, 144);
				engine_4170BD(v16, v17, v18, automap_typed, 144);
				engine_4170BD(v16, v5, v4, automap_typed, 144);
				engine_4170BD(v16, v5, v18, automap_typed, 144);
			}
			if ( v33 & 0x20 )
			{
				engine_4170BD(CT_4B84C0 + v4, v5 - CT_4B84C4, v4 + CT_4B84BC, v5, 200);
				v33 |= 8u;
			}
			if ( v33 & 8 )
			{
				v19 = v4 - CT_4B84C0 + CT_4B84BC;
				v20 = v4 - CT_4B84C0;
				v21 = v5 - CT_4B84C0;
				automap_typee = v5 - CT_4B84C4;
				engine_4170BD(v4, v5 - CT_4B84C0, v4 - CT_4B84C0, v5 - CT_4B84C4, 200);
				engine_4170BD(v4, v21, v19, automap_typee, 200);
				engine_4170BD(v4, v5, v20, automap_typee, 200);
				engine_4170BD(v4, v5, v19, automap_typee, 200);
			}
			if ( !(v33 & 0x2A) )
				engine_4170BD(v4, v5 - CT_4B84C0, v4 + CT_4B84BC, v5, 200);
LABEL_25:
			if ( v30 )
				goto LABEL_26;
			goto LABEL_32;
		case 0xA:
			goto LABEL_26;
		case 0xB:
			goto LABEL_33;
		case 0xC:
			v32 = 1;
LABEL_26:
			if ( v33 & 1 )
			{
				v22 = v4 - CT_4B84BC;
				v23 = v4 - CT_4B84C0;
				v24 = CT_4B84C0 + v5;
				automap_typef = CT_4B84C4 + v5;
				engine_4170BD(v4, CT_4B84C0 + v5, v4 - CT_4B84C4, CT_4B84C0 + v5 - CT_4B84C8, 200);
				engine_4170BD(v22, v5, v22 + CT_4B84C4, v5 + CT_4B84C8, 200);
				engine_4170BD(v23, v24, v22, automap_typef, 144);
				engine_4170BD(v23, v24, v4, automap_typef, 144);
				engine_4170BD(v23, v5, v22, automap_typef, 144);
				engine_4170BD(v23, v5, v4, automap_typef, 144);
			}
			else
			{
				engine_4170BD(v4, CT_4B84C0 + v5, v4 - CT_4B84BC, v5, 200);
			}
LABEL_32:
			if ( v32 )
			{
LABEL_33:
				if ( v33 & 2 )
				{
					v25 = CT_4B84C0 + v4;
					v26 = CT_4B84C0 + v5;
					v27 = v4 + CT_4B84BC;
					automap_typeg = CT_4B84C4 + v5;
					engine_4170BD(v4, CT_4B84C0 + v5, v4 + CT_4B84C4, CT_4B84C0 + v5 - CT_4B84C8, 200);
					engine_4170BD(v27, v5, v27 - CT_4B84C4, v5 + CT_4B84C8, 200);
					engine_4170BD(v25, v26, v4, automap_typeg, 144);
					engine_4170BD(v25, v26, v27, automap_typeg, 144);
					engine_4170BD(v25, v5, v4, automap_typeg, 144);
					engine_4170BD(v25, v5, v27, automap_typeg, 144);
				}
				else
				{
					v29 = v5;
					v28 = v4 + CT_4B84BC;
					v9 = CT_4B84C0 + v5;
LABEL_36:
					engine_4170BD(v4, v9, v28, v29, 200);
				}
			}
			break;
		default:
			return;
	}
}
// 4B84BC: using guessed type int CT_4B84BC;
// 4B84C0: using guessed type int CT_4B84C0;
// 4B84C4: using guessed type int CT_4B84C4;
// 4B84C8: using guessed type int CT_4B84C8;

//----- (004029A8) --------------------------------------------------------
void __cdecl DrawAutomapPlr()
{
	int v0; // ebx
	int v1; // eax
	int v2; // ecx
	int v3; // esi
	int v4; // edi
	int v5; // edx
	int v6; // ecx
	int v7; // eax
	int v8; // ecx
	int v9; // [esp-Ch] [ebp-20h]
	int v10; // [esp-8h] [ebp-1Ch]
	int v11; // [esp+Ch] [ebp-8h]
	int v12; // [esp+10h] [ebp-4h]

	v0 = myplr;
	if ( plr[myplr]._pmode == PM_WALK3 )
	{
		v1 = plr[v0]._px;
		v2 = plr[v0]._py;
		if ( plr[v0]._pdir == 2 )
			++v1;
		else
			++v2;
	}
	else
	{
		v1 = plr[v0].WorldX;
		v2 = plr[v0].WorldY;
	}
	v11 = v1 - 2 * AutoMapXOfs - ViewX;
	v12 = v2 - 2 * AutoMapYOfs - ViewY;
	v3 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1)
	   + (AutoMapScale * plr[v0]._pxoff / 100 >> 1)
	   + CT_4B84C0 * (v11 - v12)
	   + 384;
	if ( invflag || sbookflag )
		v3 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1)
		   + (AutoMapScale * plr[v0]._pxoff / 100 >> 1)
		   + CT_4B84C0 * (v11 - v12)
		   + 224;
	if ( chrflag || questlog )
		v3 += 160;
	v4 = CT_4B84C4 * (v12 + v11)
	   + (AutoMapScale * ScrollInfo._syoff / 100 >> 1)
	   + (AutoMapScale * plr[v0]._pyoff / 100 >> 1)
	   + 336
	   - CT_4B84C4;
	switch ( plr[v0]._pdir )
	{
		case DIR_S:
			engine_4170BD(v3, v4, v3, v4 + CT_4B84C0, 153);
			engine_4170BD(v3, CT_4B84C0 + v4, v3 + CT_4B84C8, v4 + CT_4B84C4, 153);
			v10 = v4 + CT_4B84C4;
			v9 = v3 - CT_4B84C8;
			v5 = CT_4B84C0 + v4;
			goto LABEL_19;
		case DIR_SW:
			engine_4170BD(
				v3,
				CT_4B84C4 * (v12 + v11)
			  + (AutoMapScale * ScrollInfo._syoff / 100 >> 1)
			  + (AutoMapScale * plr[v0]._pyoff / 100 >> 1)
			  + 336
			  - CT_4B84C4,
				v3 - CT_4B84C0,
				CT_4B84C4 * (v12 + v11)
			  + (AutoMapScale * ScrollInfo._syoff / 100 >> 1)
			  + (AutoMapScale * plr[v0]._pyoff / 100 >> 1)
			  + 336,
				153);
			engine_4170BD(v3 - CT_4B84C0, CT_4B84C4 + v4, v3 - CT_4B84C8 - CT_4B84C4, v4, 153);
			v7 = CT_4B84C4;
			v8 = v3;
			v5 = CT_4B84C4 + v4;
			v10 = CT_4B84C4 + v4;
			goto LABEL_23;
		case DIR_W:
			engine_4170BD(v3, v4, v3 - CT_4B84C0, v4, 153);
			engine_4170BD(v3 - CT_4B84C0, v4, v3 - CT_4B84C4, v4 - CT_4B84C8, 153);
			v5 = v4;
			v10 = v4 + CT_4B84C8;
			v9 = v3 - CT_4B84C4;
			goto LABEL_24;
		case DIR_NW:
			engine_4170BD(v3, v4, v3 - CT_4B84C0, v4 - CT_4B84C4, 153);
			engine_4170BD(v3 - CT_4B84C0, v4 - CT_4B84C4, v3 - CT_4B84C4, v4 - CT_4B84C4, 153);
			v7 = CT_4B84C4;
			v8 = v3 - CT_4B84C8;
			v10 = v4;
			v5 = v4 - CT_4B84C4;
LABEL_23:
			v9 = v8 - v7;
LABEL_24:
			v6 = v3 - CT_4B84C0;
			goto LABEL_25;
		case DIR_N:
			engine_4170BD(v3, v4, v3, v4 - CT_4B84C0, 153);
			engine_4170BD(v3, v4 - CT_4B84C0, v3 - CT_4B84C8, v4 - CT_4B84C4, 153);
			v10 = v4 - CT_4B84C4;
			v5 = v4 - CT_4B84C0;
			v9 = v3 + CT_4B84C8;
LABEL_19:
			v6 = v3;
			goto LABEL_25;
		case DIR_NE:
			engine_4170BD(v3, v4, v3 + CT_4B84C0, v4 - CT_4B84C4, 153);
			engine_4170BD(CT_4B84C0 + v3, v4 - CT_4B84C4, v3 + CT_4B84C4, v4 - CT_4B84C4, 153);
			v10 = v4;
			v9 = v3 + CT_4B84C4 + CT_4B84C8;
			v5 = v4 - CT_4B84C4;
			goto LABEL_17;
		case DIR_E:
			engine_4170BD(v3, v4, v3 + CT_4B84C0, v4, 153);
			engine_4170BD(CT_4B84C0 + v3, v4, v3 + CT_4B84C4, v4 - CT_4B84C8, 153);
			engine_4170BD(CT_4B84C0 + v3, v4, v3 + CT_4B84C4, v4 + CT_4B84C8, 153);
			break;
		case DIR_SE:
			engine_4170BD(
				v3,
				CT_4B84C4 * (v12 + v11)
			  + (AutoMapScale * ScrollInfo._syoff / 100 >> 1)
			  + (AutoMapScale * plr[v0]._pyoff / 100 >> 1)
			  + 336
			  - CT_4B84C4,
				v3 + CT_4B84C0,
				CT_4B84C4 * (v12 + v11)
			  + (AutoMapScale * ScrollInfo._syoff / 100 >> 1)
			  + (AutoMapScale * plr[v0]._pyoff / 100 >> 1)
			  + 336,
				153);
			engine_4170BD(CT_4B84C0 + v3, CT_4B84C4 + v4, v3 + CT_4B84C4 + CT_4B84C8, v4, 153);
			v5 = CT_4B84C4 + v4;
			v10 = CT_4B84C4 + v4;
			v9 = v3 + CT_4B84C4;
LABEL_17:
			v6 = CT_4B84C0 + v3;
LABEL_25:
			engine_4170BD(v6, v5, v9, v10, 153);
			break;
		default:
			return;
	}
}
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;
// 4B84C0: using guessed type int CT_4B84C0;
// 4B84C4: using guessed type int CT_4B84C4;
// 4B84C8: using guessed type int CT_4B84C8;
// 4B8968: using guessed type int sbookflag;
// 69BD04: using guessed type int questlog;

//----- (00402D83) --------------------------------------------------------
short __fastcall GetAutomapType(int tx, int ty, bool view)
{
	int v3; // edi
	int v4; // esi
	int v6; // eax
	short v7; // bp

	v3 = ty;
	v4 = tx;
	if ( view )
	{
		if ( tx == -1 && ty >= 0 && ty < 40 && automapview[0][ty] )
		{
			tx = 0;
			return ~GetAutomapType(tx, ty, 0) & 0x4000;
		}
		if ( ty == -1 )
		{
			if ( tx < 0 )
				return 0;
			if ( tx < 40 && automapview[tx][0] )
			{
				ty = 0;
				return ~GetAutomapType(tx, ty, 0) & 0x4000;
			}
		}
	}
	if ( tx < 0 )
		return 0;
	if ( tx >= 40 )
		return 0;
	if ( ty < 0 )
		return 0;
	if ( ty >= 40 )
		return 0;
	v6 = ty + 40 * tx;
	if ( !automapview[0][v6] && view )
		return 0;
	v7 = automaptype[(unsigned char)dungeon[0][v6]];
	if ( v7 == 7 && ((unsigned short)GetAutomapType(tx - 1, ty, 0) >> 8) & 8 )
	{
		if ( ((unsigned short)GetAutomapType(v4, v3 - 1, 0) >> 8) & 4 )
			v7 = 1;
	}
	return v7;
}

//----- (00402E4A) --------------------------------------------------------
void __cdecl DrawAutomapGame()
{
	int v0; // esi
	char *v1; // eax
	char *v2; // eax
	char v3[256]; // [esp+4h] [ebp-100h]

	v0 = 20;
	if ( (unsigned char)gbMaxPlayers > 1u )
	{
		v1 = strcpy(v3, "game: ");
		strcat(v1, szPlayerName);
		PrintGameStr(8, 20, v3, 3);
		v0 = 35;
		if ( szPlayerDescript[0] )
		{
			v2 = strcpy(v3, "password: ");
			strcat(v2, szPlayerDescript);
			PrintGameStr(8, 35, v3, 3);
			v0 = 50;
		}
	}
	if ( setlevel )
	{
		PrintGameStr(8, v0, quest_level_names[(unsigned char)setlvlnum], 3);
	}
	else if ( currlevel )
	{
		sprintf(v3, "Level: %i", currlevel);
		PrintGameStr(8, v0, v3, 3);
	}
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;
// 679660: using guessed type char gbMaxPlayers;

//----- (00402F27) --------------------------------------------------------
void __fastcall SetAutomapView(int x, int y)
{
	signed int v2; // esi
	signed int v3; // edi
	int v4; // ebx
	short v5; // ax
	short v6; // cx
	int v7; // eax
	int v8; // eax
	int v9; // eax
	int v10; // eax
	short v11; // ax
	int v12; // edi

	v2 = (x - 16) >> 1;
	v3 = (y - 16) >> 1;
	if ( v2 < 0 || v2 >= 40 || v3 < 0 || v3 >= 40 )
		return;
	v4 = v3 + 40 * v2;
	automapview[0][v4] = 1;
	v5 = GetAutomapType((x - 16) >> 1, (y - 16) >> 1, 0);
	v6 = v5 & 0x4000;
	v7 = (v5 & 0xF) - 2;
	if ( !v7 )
	{
		if ( v6 )
		{
LABEL_19:
			if ( GetAutomapType(v2, v3 + 1, 0) == 16391 )
				automapview[0][v4 + 1] = 1;
			return;
		}
		goto LABEL_35;
	}
	v8 = v7 - 1;
	if ( !v8 )
	{
		if ( v6 )
		{
			v11 = GetAutomapType(v2 + 1, v3, 0);
LABEL_32:
			if ( v11 == 16391 )
				automapview[1][v4] = 1;
			return;
		}
LABEL_14:
		if ( GetAutomapType(v2, v3 - 1, 0) & 0x4000 )
			AMbyte_4B7E4C[v4 + 31] = 1;
		return;
	}
	v9 = v8 - 1;
	if ( v9 )
	{
		v10 = v9 - 1;
		if ( v10 )
		{
			if ( v10 != 1 )
				return;
			if ( v6 )
			{
				if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 )
					*((_BYTE *)&AMdword_4B7E44 + v4) = 1;
LABEL_13:
				v11 = GetAutomapType(v2 + 1, v3, 0);
				goto LABEL_32;
			}
			goto LABEL_14;
		}
		if ( v6 )
		{
			if ( GetAutomapType(v2, v3 - 1, 0) & 0x4000 )
				AMbyte_4B7E4C[v4 + 31] = 1;
			goto LABEL_19;
		}
LABEL_35:
		if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 )
			*((_BYTE *)&AMdword_4B7E44 + v4) = 1;
		return;
	}
	if ( v6 )
	{
		if ( GetAutomapType(v2, v3 + 1, 0) == 16391 )
			automapview[0][v4 + 1] = 1;
		goto LABEL_13;
	}
	if ( GetAutomapType(v2 - 1, v3, 0) & 0x4000 )
		*((_BYTE *)&AMdword_4B7E44 + v4) = 1;
	v12 = v3 - 1;
	if ( GetAutomapType(v2, v12, 0) & 0x4000 )
		AMbyte_4B7E4C[v4 + 31] = 1;
	if ( GetAutomapType(v2 - 1, v12, 0) & 0x4000 )
		*((_BYTE *)&AMdword_4B7E40 + v4 + 3) = 1;
}
// 4B7E40: using guessed type int AMdword_4B7E40;
// 4B7E44: using guessed type int AMdword_4B7E44;

//----- (004030DD) --------------------------------------------------------
void __cdecl AutomapZoomReset()
{
	AutoMapXOfs = 0;
	AutoMapYOfs = 0;
	CT_4B84B8 = (AutoMapScale << 6) / 100;
	CT_4B84BC = CT_4B84B8 >> 1;
	CT_4B84C0 = CT_4B84B8 >> 2;
	CT_4B84C4 = CT_4B84B8 >> 3;
	CT_4B84C8 = CT_4B84B8 >> 4;
}
// 4B84B0: using guessed type int AutoMapXOfs;
// 4B84B4: using guessed type int AutoMapYOfs;
// 4B84B8: using guessed type int CT_4B84B8;
// 4B84BC: using guessed type int CT_4B84BC;
// 4B84C0: using guessed type int CT_4B84C0;
// 4B84C4: using guessed type int CT_4B84C4;
// 4B84C8: using guessed type int CT_4B84C8;

//----- (0040311B) --------------------------------------------------------
void __cdecl CaptureScreen()
{
	int v0; // ebx
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // edi
	int v5; // eax
	int v6; // eax
	PALETTEENTRY palette; // [esp+0h] [ebp-508h]
	char FileName[260]; // [esp+400h] [ebp-108h]
	HANDLE hObject; // [esp+504h] [ebp-4h]

	hObject = CaptureFile(FileName);
	if ( hObject != (HANDLE)-1 )
	{
		DrawAndBlit();
		IDirectDrawPalette_GetEntries(
			(IDirectDrawPalette *)lpDDPRed,
			0,
			0,
			256,
			&palette);
		CaptureRedPal(&palette);
		dx_lock_mutex();
		_LOBYTE(v3) = CaptureHdr(hObject, 640, 480);
		v4 = v3;
		if ( v3 )
		{
			_LOBYTE(v5) = CapturePix(hObject, 640, 480, 768, gpBuffer->row[0].pixels);
			v4 = v5;
			if ( v5 )
			{
				_LOBYTE(v6) = CapturePal(hObject, &palette);
				v4 = v6;
			}
		}
		dx_unlock_mutex();
		CloseHandle(hObject);
		if ( !v4 )
			DeleteFileA(FileName);
		Sleep(0x12Cu);
		IDirectDrawPalette_SetEntries((IDirectDrawPalette *)lpDDPRed, 0, 0, 0, &palette);
	}
}
// 40311B: could not find valid save-restore pair for ebx
// 40311B: could not find valid save-restore pair for edi
// 40311B: could not find valid save-restore pair for esi

//----- (00403204) --------------------------------------------------------
bool __fastcall CaptureHdr(HANDLE hFile, short width, int height)
{
	short v3; // si
	HANDLE v4; // ebx
	char Buffer[128]; // [esp+Ch] [ebp-84h]
	DWORD NumberOfBytesWritten; // [esp+8Ch] [ebp-4h]

	v3 = width;
	v4 = hFile;
	memset(Buffer, 0, 0x80u);
	*(_WORD *)&Buffer[8] = v3 - 1;
	*(_WORD *)&Buffer[14] = height;
	Buffer[0] = 10;
	Buffer[1] = 5;
	Buffer[2] = 1;
	Buffer[3] = 8;
	*(_WORD *)&Buffer[10] = height - 1;
	*(_WORD *)&Buffer[12] = v3;
	Buffer[65] = 1;
	*(_WORD *)&Buffer[66] = v3;
	return WriteFile(v4, Buffer, 0x80u, &NumberOfBytesWritten, 0) && NumberOfBytesWritten == 128;
}

//----- (00403294) --------------------------------------------------------
bool __fastcall CapturePal(HANDLE hFile, PALETTEENTRY *palette)
{
	BYTE *v2; // eax
	char *v3; // esi
	signed int v4; // edx
	char Buffer[772]; // [esp+8h] [ebp-308h]
	DWORD NumberOfBytesWritten; // [esp+30Ch] [ebp-4h]

	v2 = &palette->peBlue;
	Buffer[0] = 12;
	v3 = &Buffer[2];
	v4 = 256;
	do
	{
		*(v3 - 1) = *(v2 - 2);
		*v3 = *(v2 - 1);
		v3[1] = *v2;
		v2 += 4;
		v3 += 3;
		--v4;
	}
	while ( v4 );
	return WriteFile(hFile, Buffer, 0x301u, &NumberOfBytesWritten, 0) && NumberOfBytesWritten == 769;
}

//----- (004032FD) --------------------------------------------------------
bool __fastcall CapturePix(HANDLE hFile, short width, short height, short stride, char *pixels)
{
	int v5; // esi
	void *v6; // edi
	char *v7; // eax
	int v8; // ebx
	DWORD NumberOfBytesWritten; // [esp+Ch] [ebp-8h]
	HANDLE hFilea; // [esp+10h] [ebp-4h]

	v5 = (unsigned short)width;
	hFilea = hFile;
	v6 = DiabloAllocPtr(2 * (unsigned short)width);
	do
	{
		if ( !height )
		{
			mem_free_dbg(v6);
			return 1;
		}
		*(_DWORD *)&height = height + 0xFFFF;
		v7 = CaptureEnc(pixels, v6, v5);
		pixels += (unsigned short)stride;
		v8 = v7 - v6;
	}
	while ( WriteFile(hFilea, v6, v7 - v6, &NumberOfBytesWritten, 0) && NumberOfBytesWritten == v8 );
	return 0;
}

//----- (0040336A) --------------------------------------------------------
char *__fastcall CaptureEnc(char *src, void *dst, int width)
{
	int v3; // esi
	unsigned char v4; // bl
	signed int v5; // eax

	v3 = width;
	do
	{
		v4 = *src++;
		v5 = 1;
		--v3;
		if ( v4 == *src )
		{
			do
			{
				if ( v5 >= 63 )
					break;
				if ( !v3 )
					break;
				++v5;
				--v3;
				++src;
			}
			while ( v4 == *src );
			if ( v5 > 1 )
				goto LABEL_13;
		}
		if ( v4 > 0xBFu )
		{
LABEL_13:
			*(_BYTE *)dst = v5 | 0xC0;
			dst = (char *)dst + 1;
		}
		*(_BYTE *)dst = v4;
		dst = (char *)dst + 1;
	}
	while ( v3 );
	return (char *)dst;
}

//----- (004033A8) --------------------------------------------------------
HANDLE __fastcall CaptureFile(char *dst_path)
{
	char *v1; // edi
	__int32 v2; // esi
	int v3; // eax
	int v5; // [esp-4h] [ebp-18Ch]
	struct _finddata_t v6; // [esp+Ch] [ebp-17Ch]
	char v7[100]; // [esp+124h] [ebp-64h]

	v1 = dst_path;
	memset(v7, 0, 0x64u);
	v2 = _findfirst("screen??.PCX", &v6);
	if ( v2 != -1 )
	{
		do
		{
			if ( isdigit(v6.name[6]) )
			{
				if ( isdigit(v6.name[7]) )
					v7[10 * v6.name[6] - 528 + v6.name[7]] = 1;
			}
		}
		while ( !_findnext(v2, &v6) );
	}
	v3 = 0;
	while ( v7[v3] )
	{
		if ( ++v3 >= 100 )
			return (HANDLE)-1;
	}
	v5 = v3;
	sprintf(v1, "screen%02d.PCX", v3);
	return CreateFileA(v1, 0x40000000u, 0, 0, 2u, 0x80u, 0);
}
// 4033A8: using guessed type char var_64[100];

//----- (00403470) --------------------------------------------------------
void __fastcall CaptureRedPal(PALETTEENTRY *palette_orig)
{
	signed int v1; // esi
	int v2; // eax
	char v3; // bl
	char v4[1024]; // [esp+Ch] [ebp-400h]

	v1 = 0;
	do
	{
		v2 = 4 * v1++;
		v4[v2 + 1] = 0;
		v4[v2 + 2] = 0;
		v3 = v4[(char *)palette_orig - v4 + v2];
		v4[v2 + 3] = 0;
		v4[v2] = v3;
	}
	while ( v1 < 256 );
	IDirectDrawPalette_SetEntries((IDirectDrawPalette *)lpDDPRed, 0, 0, 256, (LPPALETTEENTRY)v4);
}

//----- (004034D9) --------------------------------------------------------
int __fastcall codec_decode(void *src_dst, int size, char *password)
{
	unsigned int v3; // ebx
	char *v4; // esi
	int v5; // ebx
	signed int v7; // ecx
	int v8; // esi
	char v9[128]; // [esp+8h] [ebp-98h]
	char dst[20]; // [esp+88h] [ebp-18h]
	int v11; // [esp+9Ch] [ebp-4h]
	char *passworda; // [esp+A8h] [ebp+8h]

	v3 = size;
	v4 = (char *)src_dst;
	codec_init_key(0, password);
	if ( v3 <= 8 )
		return 0;
	v5 = v3 - 8;
	v11 = v5;
	if ( v5 & 0x3F )
		return 0;
	passworda = (char *)v5;
	if ( v5 )
	{
		do
		{
			memcpy(v9, v4, 0x40u);
			sha1_final(0, (char (*)[20])dst);
			v7 = 0;
			do
			{
				v9[v7] ^= dst[v7 % 20];
				++v7;
			}
			while ( v7 < 64 );
			sha1(0, v9, 0);
			memset(dst, 0, 0x14u);
			memcpy(v4, v9, 0x40u);
			v4 += 64;
			passworda -= 64;
		}
		while ( passworda );
		v5 = v11;
	}
	memset(v9, 0, 0x80u);
	if ( !v4[4] )
	{
		sha1_final(0, (char (*)[20])dst);
		if ( *(_DWORD *)v4 == *(_DWORD *)dst )
		{
			v8 = v5 + (unsigned char)v4[5] - 64;
			goto LABEL_14;
		}
		memset(dst, 0, 0x14u);
	}
	v8 = 0;
LABEL_14:
	sha1_reset();
	return v8;
}
// 4034D9: using guessed type char var_98[128];

//----- (004035DB) --------------------------------------------------------
void __fastcall codec_init_key(int unused, char *password)
{
	char *v2; // edi
	char *v3; // esi
	int v4; // eax
	signed int v5; // ecx
	char v6; // dl
	unsigned int v7; // ecx
	signed int v8; // esi
	char v9[72]; // [esp+Ch] [ebp-E0h]
	char data[64]; // [esp+54h] [ebp-98h]
	char v11[64]; // [esp+94h] [ebp-58h]
	char dst[20]; // [esp+D4h] [ebp-18h]
	int v13; // [esp+E8h] [ebp-4h]

	v2 = password;
	srand(0x7058u);
	v3 = v9;
	v13 = 136;
	do
	{
		*v3++ = rand();
		--v13;
	}
	while ( v13 );
	v4 = 0;
	v5 = 0;
	do
	{
		if ( !v2[v4] )
			v4 = 0;
		v6 = v2[v4++];
		v11[v5++] = v6;
	}
	while ( v5 < 64 );
	sha1_init(0);
	sha1(0, v11, (char (*)[20])dst);
	sha1_reset();
	v7 = 0;
	do
	{
		v9[v7] ^= dst[(signed int)v7 % 20];
		++v7;
	}
	while ( v7 < 0x88 );
	memset(v11, 0, 0x40u);
	memset(dst, 0, 0x14u);
	v8 = 0;
	do
	{
		sha1_init(v8);
		sha1(v8++, data, 0);
	}
	while ( v8 < 3 );
	memset(v9, 0, 0x88u);
}
// 4035DB: using guessed type char var_E0[72];
// 4035DB: using guessed type char var_58[64];
// 4035DB: using guessed type char dst[20];

//----- (004036AC) --------------------------------------------------------
int __fastcall codec_get_encoded_len(int n)
{
	if ( n & 0x3F )
		n += 64 - (n & 0x3F);
	return n + 8;
}

//----- (004036BE) --------------------------------------------------------
void __fastcall codec_encode(void *src_dst, int size, int size_64, char *password)
{
	char *v4; // esi
	char v5; // bl
	size_t v6; // edi
	signed int v7; // ecx
	int v8; // eax
	char v9[128]; // [esp+8h] [ebp-ACh]
	char v10[20]; // [esp+88h] [ebp-2Ch]
	char dst[20]; // [esp+9Ch] [ebp-18h]
	size_t v12; // [esp+B0h] [ebp-4h]

	v4 = (char *)src_dst;
	v12 = size;
	if ( size_64 != codec_get_encoded_len(size) )
		TermMsg("Invalid encode parameters");
	codec_init_key(1, password);
	v5 = 0;
	if ( v12 )
	{
		do
		{
			v6 = v12;
			if ( v12 >= 0x40 )
				v6 = 64;
			memcpy(v9, v4, v6);
			if ( v6 < 0x40 )
				memset(&v9[v6], 0, 64 - v6);
			sha1_final(0, (char (*)[20])dst);
			sha1(0, v9, 0);
			v7 = 0;
			do
			{
				v9[v7] ^= dst[v7 % 20];
				++v7;
			}
			while ( v7 < 64 );
			memset(dst, 0, 0x14u);
			memcpy(v4, v9, 0x40u);
			v4 += 16;
			v12 -= v6;
		}
		while ( v12 );
		v5 = v6;
	}
	memset(v9, 0, 0x80u);
	sha1_final(0, (char (*)[20])v10);
	v8 = *(_DWORD *)v10;
	*((_BYTE *)v4 + 4) = 0;
	*((_WORD *)v4 + 3) = 0;
	*v4 = v8;
	*((_BYTE *)v4 + 5) = v5;
	sha1_reset();
}
// 4036BE: using guessed type char var_AC[128];
// 4036BE: using guessed type char dst[20];

//----- (004037D4) --------------------------------------------------------
void __fastcall DrawSpellCel(int xp, int yp, char *Trans, int nCel, int w)
{
/*	char *v5; // ebx
	char *v6; // esi
	char *v7; // edi
	int v9; // edx
	unsigned int v10; // eax
	unsigned int v11; // ecx
	char v14; // cf
	unsigned int v15; // ecx
	int v18; // [esp+Ch] [ebp-Ch]

	v5 = &Trans[4 * nCel];
	v6 = &Trans[*(_DWORD *)v5];
	v7 = (char *)gpBuffer + screen_y_times_768[yp] + xp;
	v18 = (int)&v6[*((_DWORD *)v5 + 1) - *(_DWORD *)v5];
	_EBX = byte_4B8B88;
	do
	{
		v9 = w;
		do
		{
			while ( 1 )
			{
				v10 = (unsigned char)*v6++;
				if ( (v10 & 0x80u) == 0 )
					break;
				_LOBYTE(v10) = -(char)v10;
				v7 += v10;
				v9 -= v10;
				if ( !v9 )
					goto LABEL_12;
			}
			v9 -= v10;
			v11 = v10 >> 1;
			if ( v10 & 1 )
			{
				_AL = *v6++;
				__asm { xlat }
				*v7++ = _AL;
				if ( !v11 )
					continue;
			}
			v14 = v11 & 1;
			v15 = v11 >> 1;
			if ( !v14 )
				goto LABEL_15;
			_AX = *(_WORD *)v6;
			v6 += 2;
			__asm { xlat }
			_AX = __ROR2__(_AX, 8);
			__asm { xlat }
			*(_WORD *)v7 = __ROR2__(_AX, 8);
			v7 += 2;
			if ( v15 )
			{
LABEL_15:
				do
				{
					_EAX = *(_DWORD *)v6;
					v6 += 4;
					__asm { xlat }
					_EAX = __ROR4__(_EAX, 8);
					__asm { xlat }
					_EAX = __ROR4__(_EAX, 8);
					__asm { xlat }
					_EAX = __ROR4__(_EAX, 8);
					__asm { xlat }
					*(_DWORD *)v7 = __ROR4__(_EAX, 8);
					v7 += 4;
					--v15;
				}
				while ( v15 );
			}
		}
		while ( v9 );
LABEL_12:
		v7 = &v7[-w - 768];
	}
	while ( v6 != (char *)v18 );
*/
}

//----- (0040387E) --------------------------------------------------------
void __fastcall SetSpellTrans(char t)
{
	signed int v1; // eax
	signed int v2; // eax
	signed int v3; // eax
	char *v4; // ecx
	signed int v5; // eax
	char *v6; // ecx
	signed int v7; // eax
	char *v8; // ecx
	signed int v9; // eax
	char *v10; // ecx

	if ( !t )
	{
		v1 = 0;
		do
		{
			byte_4B8B88[v1] = v1;
			++v1;
		}
		while ( v1 < 128 );
	}
	v2 = 128;
	do
	{
		byte_4B8B88[v2] = v2;
		++v2;
	}
	while ( v2 < 256 );
	byte_4B8B88[255] = 0;
	switch ( t )
	{
		case 1:
			byte_4B8B88[144] = -79;
			byte_4B8B88[145] = -77;
			byte_4B8B88[146] = -75;
			v9 = 176;
			do
			{
				v10 = &byte_4B8B88[v9 + 32];
				byte_4B8B88[v9 - 16] = v9;
				*(v10 - 16) = v9;
				*v10 = v9++;
			}
			while ( v9 < 192 );
			break;
		case 2:
			byte_4B8B88[144] = -95;
			byte_4B8B88[145] = -93;
			byte_4B8B88[146] = -91;
			v7 = 160;
			do
			{
				v8 = &byte_4B8B88[v7 + 48];
				*(v8 - 16) = v7;
				*v8 = v7++;
			}
			while ( v7 < 176 );
			break;
		case 3:
			byte_4B8B88[144] = -47;
			byte_4B8B88[145] = -45;
			byte_4B8B88[146] = -43;
			v5 = 208;
			do
			{
				v6 = &byte_4B8B88[v5 - 16];
				*(v6 - 32) = v5;
				*v6 = v5++;
			}
			while ( v5 < 224 );
			break;
		case 4:
			byte_4B8B88[144] = -15;
			byte_4B8B88[145] = -13;
			byte_4B8B88[146] = -11;
			v3 = 240;
			do
			{
				v4 = &byte_4B8B88[v3 - 48];
				*(v4 - 32) = v3;
				*v4 = v3;
				v4[16] = v3++;
			}
			while ( v3 < 255 );
			byte_4B8B88[175] = 0;
			byte_4B8B88[207] = 0;
			byte_4B8B88[223] = 0;
			break;
	}
}

//----- (004039C7) --------------------------------------------------------
void __cdecl DrawSpell()
{
	int v0; // ebp
	char v1; // cl
	char v2; // bl
	int v3; // edi
	int v4; // esi
	int v5; // eax
	char v6; // [esp+Fh] [ebp-5h]

	v0 = myplr;
	v1 = plr[myplr]._pRSpell;
	v2 = plr[myplr]._pRSplType;
	v3 = v1;
	v6 = plr[myplr]._pRSpell;
	v4 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v1];
	if ( v2 == 1 && v1 != -1 )
	{
		_LOBYTE(v5) = CheckSpell(myplr, v1, 1, 1);
		if ( !v5 )
			v2 = 4;
		v0 = myplr;
		if ( v4 <= 0 )
			v2 = 4;
	}
	if ( !currlevel && v2 != 4 && !*(_DWORD *)&spelldata[v3].sTownSpell )
		v2 = 4;
	if ( plr[v0]._pRSpell < 0 )
		v2 = 4;
	SetSpellTrans(v2);
	if ( v6 == -1 )
		DrawSpellCel(629, 631, (char *)pSpellCels, 27, 56);
	else
		DrawSpellCel(629, 631, (char *)pSpellCels, (char)SpellITbl[v3], 56);
}

//----- (00403A8E) --------------------------------------------------------
void __cdecl DrawSpellList()
{
	int v0; // esi
	signed int v1; // edi
	int v2; // ecx
	int v3; // eax
	signed int v4; // ebp
	int v5; // eax
	int v6; // esi
	int v7; // eax
	bool v8; // sf
	int v9; // esi
	int v10; // eax
	int v11; // ebp
	int v12; // edx
	int *v13; // ecx
	int *v14; // eax
	signed int v15; // edx
	signed int v16; // edi
	int v17; // [esp+Ch] [ebp-34h]
	__int32 xp; // [esp+10h] [ebp-30h]
	__int32 yp; // [esp+14h] [ebp-2Ch]
	unsigned char *v20; // [esp+18h] [ebp-28h]
	__int32 nCel; // [esp+1Ch] [ebp-24h]
	int v22; // [esp+20h] [ebp-20h]
	__int32 v23; // [esp+24h] [ebp-1Ch]
	signed int v24; // [esp+28h] [ebp-18h]
	unsigned __int64 v25; // [esp+2Ch] [ebp-14h]
	signed __int64 v26; // [esp+34h] [ebp-Ch]

	pSpell = -1;
	infostr[0] = 0;
	v17 = 636;
	xp = 495;
	ClearPanel();
	v0 = myplr;
	v1 = 0;
	v24 = 0;
	do
	{
		switch ( v1 )
		{
			case RSPLTYPE_SKILL:
				SetSpellTrans(0);
				yp = 46;
				v2 = plr[v0]._pAblSpells[0];
				v3 = plr[v0]._pAblSpells[1];
				goto LABEL_10;
			case RSPLTYPE_SPELL:
				yp = 47;
				v2 = plr[v0]._pMemSpells[0];
				v3 = plr[v0]._pMemSpells[1];
				goto LABEL_10;
			case RSPLTYPE_SCROLL:
				SetSpellTrans(2);
				yp = 44;
				v2 = plr[v0]._pScrlSpells[0];
				v3 = plr[v0]._pScrlSpells[1];
				goto LABEL_10;
			case RSPLTYPE_CHARGES:
				SetSpellTrans(3);
				yp = 45;
				v2 = plr[v0]._pISpells[0];
				v3 = plr[v0]._pISpells[1];
LABEL_10:
				v25 = __PAIR__(v3, v2);
				break;
		}
		v20 = &spelldata[1].sTownSpell;
		v4 = 1;
		v26 = 1i64;
		v23 = 1;
		v22 = xp - 216;
		do
		{
			if ( !(v25 & v26) )
				goto LABEL_68;
			if ( v1 == RSPLTYPE_SPELL )
			{
				v5 = v0;
				v6 = plr[v0]._pSplLvl[v4];
				v7 = plr[v5]._pISplLvlAdd;
				v8 = v7 + v6 < 0;
				v9 = v7 + v6;
				nCel = v9;
				if ( v8 )
				{
					nCel = 0;
					v9 = 0;
				}
				SetSpellTrans(v9 <= 0 ? 4 : 1);
			}
			else
			{
				v9 = nCel;
			}
			if ( !currlevel && !*(_DWORD *)v20 )
				SetSpellTrans(4);
			DrawSpellCel(v17, xp, (char *)pSpellCels, (char)SpellITbl[v4], 56);
			if ( MouseX >= v17 - 64 && MouseX < v17 - 64 + 56 && MouseY >= v22 && MouseY < v22 + 56 )
			{
				pSpell = v4;
				pSplType = v1;
				DrawSpellCel(v17, xp, (char *)pSpellCels, yp, 56);
				if ( v1 )
				{
					switch ( v1 )
					{
						case RSPLTYPE_SPELL:
							sprintf(infostr, "%s Spell", spelldata[pSpell].sNameText);
							if ( pSpell == 31 )
							{
								sprintf(tempstr, "Damages undead only");
								AddPanelString(tempstr, 1);
							}
							if ( v9 )
								sprintf(tempstr, "Spell Level %i", v9);
							else
								sprintf(tempstr, "Spell Level 0 - Unusable");
LABEL_32:
							AddPanelString(tempstr, 1);
							break;
						case RSPLTYPE_SCROLL:
							sprintf(infostr, "Scroll of %s", spelldata[pSpell].sNameText);
							v10 = myplr;
							v11 = 0;
							v12 = plr[myplr]._pNumInv;
							if ( v12 > 0 )
							{
								v13 = &plr[v10].InvList[0]._iMiscId;
								do
								{
									if ( *(v13 - 53) != -1
									  && (*v13 == IMISC_SCROLL || *v13 == IMISC_SCROLLT)
									  && v13[1] == pSpell )
									{
										++v11;
									}
									v13 += 92;
									--v12;
								}
								while ( v12 );
							}
							v14 = &plr[v10].SpdList[0]._iMiscId;
							v15 = 8;
							do
							{
								if ( *(v14 - 53) != -1
								  && (*v14 == IMISC_SCROLL || *v14 == IMISC_SCROLLT)
								  && v14[1] == pSpell )
								{
									++v11;
								}
								v14 += 92;
								--v15;
							}
							while ( v15 );
							if ( v11 == 1 )
								strcpy(tempstr, "1 Scroll");
							else
								sprintf(tempstr, "%i Scrolls", v11);
							AddPanelString(tempstr, 1);
							v4 = v23;
							break;
						case RSPLTYPE_CHARGES:
							sprintf(infostr, "Staff of %s", spelldata[pSpell].sNameText);
							if ( plr[myplr].InvBody[4]._iCharges == 1 )
								strcpy(tempstr, "1 Charge");
							else
								sprintf(tempstr, "%i Charges", plr[myplr].InvBody[4]._iCharges);
							goto LABEL_32;
					}
				}
				else
				{
					sprintf(infostr, "%s Skill", spelldata[pSpell].sSkillText);
				}
				v0 = myplr;
				v16 = 0;
				do
				{
					if ( plr[0]._pSplHotKey[v16 + 5430 * v0] == pSpell && plr[v0]._pSplTHotKey[v16] == pSplType )
					{
						DrawSpellCel(v17, xp, (char *)pSpellCels, v16 + 48, 56);
						sprintf(tempstr, "Spell Hot Key #F%i", v16 + 5);
						AddPanelString(tempstr, 1);
						v0 = myplr;
					}
					++v16;
				}
				while ( v16 < 4 );
				v1 = v24;
				goto LABEL_66;
			}
			v0 = myplr;
LABEL_66:
			v17 -= 56;
			if ( v17 == 20 )
			{
				xp -= 56;
				v22 -= 56;
				v17 = 636;
			}
LABEL_68:
			v20 += 56;
			++v4;
			v26 *= 2i64;
			v23 = v4;
		}
		while ( (signed int)v20 < (signed int)"Heal Other" );
		if ( v25 && v17 != 636 )
			v17 -= 56;
		if ( v17 == 20 )
		{
			xp -= 56;
			v17 = 636;
		}
		v24 = ++v1;
	}
	while ( v1 < 4 );
}
// 4B8834: using guessed type int pSpell;
// 4B8954: using guessed type int pSplType;

//----- (00403F69) --------------------------------------------------------
void __cdecl SetSpell()
{
	int v0; // eax

	spselflag = 0;
	if ( pSpell != -1 )
	{
		ClearPanel();
		v0 = myplr;
		force_redraw = 255;
		plr[v0]._pRSpell = pSpell;
		_LOBYTE(plr[v0]._pRSplType) = pSplType;
	}
}
// 4B8834: using guessed type int pSpell;
// 4B8954: using guessed type int pSplType;
// 4B8C98: using guessed type int spselflag;
// 52571C: using guessed type int force_redraw;

//----- (00403FAC) --------------------------------------------------------
void __fastcall SetSpeedSpell(int slot)
{
	int v1; // esi
	int v2; // eax
	signed int v3; // ebp
	int v4; // edx
	int v5; // ebx
	int *v6; // edi

	v1 = pSpell;
	if ( pSpell != -1 )
	{
		v2 = myplr;
		v3 = 0;
		v4 = myplr;
		v5 = pSplType;
		v6 = plr[myplr]._pSplHotKey;
		do
		{
			if ( *v6 == v1 && plr[v4]._pSplTHotKey[v3] == v5 )
				*v6 = -1;
			++v3;
			++v6;
		}
		while ( v3 < 4 );
		plr[0]._pSplHotKey[slot + 5430 * v2] = v1;
		plr[v4]._pSplTHotKey[slot] = v5;
	}
}
// 4B8834: using guessed type int pSpell;
// 4B8954: using guessed type int pSplType;

//----- (00404017) --------------------------------------------------------
void __fastcall ToggleSpell(int slot)
{
	int v1; // eax
	int v2; // edx
	int v3; // esi
	char *v4; // eax
	int v5; // eax
	int v6; // eax
	int v7; // eax
	int v8; // ebx
	int v9; // edi
	int v10; // [esp+4h] [ebp-Ch]
	char *v11; // [esp+8h] [ebp-8h]
	int v12; // [esp+Ch] [ebp-4h]

	v1 = slot + 5430 * myplr;
	v2 = plr[0]._pSplHotKey[v1];
	v12 = plr[0]._pSplHotKey[v1];
	if ( v2 != -1 )
	{
		v3 = myplr;
		v4 = &plr[myplr]._pSplTHotKey[slot];
		v11 = v4;
		v5 = *v4;
		if ( v5 )
		{
			v6 = v5 - 1;
			if ( v6 )
			{
				v7 = v6 - 1;
				if ( v7 )
				{
					if ( v7 == 1 )
					{
						v8 = plr[v3]._pISpells[0];
						v9 = plr[v3]._pISpells[1];
					}
					else
					{
						v9 = (int)v11;
						v8 = v10;
					}
				}
				else
				{
					v8 = plr[v3]._pScrlSpells[0];
					v9 = plr[v3]._pScrlSpells[1];
				}
			}
			else
			{
				v8 = plr[v3]._pMemSpells[0];
				v9 = plr[v3]._pMemSpells[1];
			}
		}
		else
		{
			v8 = plr[v3]._pAblSpells[0];
			v9 = plr[v3]._pAblSpells[1];
		}
		if ( v9 & ((unsigned __int64)(1i64 << ((unsigned char)v2 - 1)) >> 32) | v8 & (unsigned int)(1i64 << ((unsigned char)v2 - 1)) )
		{
			force_redraw = 255;
			plr[v3]._pRSpell = v12;
			_LOBYTE(plr[v3]._pRSplType) = *v11;
		}
	}
}
// 52571C: using guessed type int force_redraw;

//----- (004040DA) --------------------------------------------------------
int __fastcall CPrintString(int No, char *pszStr, int Just)
{
	_DWORD *v3; // ebx
	char *v4; // esi
	char *v5; // edi
	int v6; // ebx
	signed int v7; // edx
	int result; // eax
	unsigned int v9; // ecx
	char v10; // cf
	unsigned int v11; // ecx
	signed int v12; // edx
	int v13; // ecx
	signed int v14; // edx
	int v15; // ecx
	signed int v16; // edx
	int v17; // ecx

	v3 = (unsigned int *)pPanelText + 4 * (_DWORD)pszStr;
	v4 = (char *)pPanelText + *v3;
	v5 = (char *)gpBuffer + No;
	v6 = (int)&v4[v3[1] - *v3];
	if ( (_BYTE)Just )
	{
		if ( (unsigned char)Just == 1 )
		{
			do
			{
				v12 = 13;
				do
				{
					while ( 1 )
					{
						result = (unsigned char)*v4++;
						if ( (result & 0x80u) == 0 )
							break;
						_LOBYTE(result) = -(char)result;
						v5 += result;
						v12 -= result;
						if ( !v12 )
							goto LABEL_28;
					}
					v12 -= result;
					v13 = result;
					do
					{
						_LOBYTE(result) = *v4++;
						if ( (unsigned char)result > 0xFDu )
						{
							_LOBYTE(result) = -65;
						}
						else if ( (unsigned char)result >= 0xF0u )
						{
							_LOBYTE(result) = result - 62;
						}
						*v5++ = result;
						--v13;
					}
					while ( v13 );
				}
				while ( v12 );
LABEL_28:
				v5 -= 781;
			}
			while ( (char *)v6 != v4 );
		}
		else if ( (unsigned char)Just == 2 )
		{
			do
			{
				v14 = 13;
				do
				{
					while ( 1 )
					{
						result = (unsigned char)*v4++;
						if ( (result & 0x80u) == 0 )
							break;
						_LOBYTE(result) = -(char)result;
						v5 += result;
						v14 -= result;
						if ( !v14 )
							goto LABEL_39;
					}
					v14 -= result;
					v15 = result;
					do
					{
						_LOBYTE(result) = *v4++;
						if ( (unsigned char)result >= 0xF0u )
							_LOBYTE(result) = result - 16;
						*v5++ = result;
						--v15;
					}
					while ( v15 );
				}
				while ( v14 );
LABEL_39:
				v5 -= 781;
			}
			while ( (char *)v6 != v4 );
		}
		else
		{
			do
			{
				v16 = 13;
				do
				{
					while ( 1 )
					{
						result = (unsigned char)*v4++;
						if ( (result & 0x80u) == 0 )
							break;
						_LOBYTE(result) = -(char)result;
						v5 += result;
						v16 -= result;
						if ( !v16 )
							goto LABEL_52;
					}
					v16 -= result;
					v17 = result;
					do
					{
						_LOBYTE(result) = *v4++;
						if ( (unsigned char)result >= 0xF0u )
						{
							if ( (unsigned char)result >= 0xFEu )
								_LOBYTE(result) = -49;
							else
								_LOBYTE(result) = result - 46;
						}
						*v5++ = result;
						--v17;
					}
					while ( v17 );
				}
				while ( v16 );
LABEL_52:
				v5 -= 781;
			}
			while ( (char *)v6 != v4 );
		}
	}
	else
	{
		do
		{
			v7 = 13;
			do
			{
				while ( 1 )
				{
					result = (unsigned char)*v4++;
					if ( (result & 0x80u) == 0 )
						break;
					_LOBYTE(result) = -(char)result;
					v5 += result;
					v7 -= result;
					if ( !v7 )
						goto LABEL_15;
				}
				v7 -= result;
				v9 = (unsigned int)result >> 1;
				if ( result & 1 )
				{
					*v5++ = *v4++;
					if ( !v9 )
						continue;
				}
				v10 = v9 & 1;
				v11 = (unsigned int)result >> 2;
				if ( v10 )
				{
					*(_WORD *)v5 = *(_WORD *)v4;
					v4 += 2;
					v5 += 2;
					if ( !v11 )
						continue;
				}
				qmemcpy(v5, v4, 4 * v11);
				v4 += 4 * v11;
				v5 += 4 * v11;
			}
			while ( v7 );
LABEL_15:
			v5 -= 781;
		}
		while ( (char *)v6 != v4 );
	}
	return result;
}

//----- (00404218) --------------------------------------------------------
void __fastcall AddPanelString(char *str, int just)
{
	int v2; // esi
	int v3; // eax
	bool v4; // sf
	unsigned char v5; // of

	v2 = just;
	strcpy(&panelstr[64 * pnumlines], str);
	v3 = pnumlines;
	v5 = __OFSUB__(pnumlines, 4);
	v4 = pnumlines - 4 < 0;
	pstrjust[pnumlines] = v2;
	if ( v4 ^ v5 )
		pnumlines = v3 + 1;
}

//----- (0040424A) --------------------------------------------------------
void __cdecl ClearPanel()
{
	pnumlines = 0;
	pinfoflag = 0;
}
// 4B8824: using guessed type int pinfoflag;

//----- (00404259) --------------------------------------------------------
void __fastcall DrawPanelBox(int x, int y, unsigned short a3, unsigned short a4, int sx, int sy)
{
	_WORD *v6; // esi
	char *v7; // edi
	int v8; // edx
	unsigned int v9; // ecx
	char v10; // cf
	unsigned int v11; // ecx

	v6 = (unsigned short *)pBtmBuff + 640 * y + x;
	v7 = &gpBuffer->row_unused_1[sy].col_unused_1[sx];
	v8 = a4;
	do
	{
		v9 = (unsigned int)a3 >> 1;
		if ( !(a3 & 1) || (*v7 = *(_BYTE *)v6, v6 = (_WORD *)((char *)v6 + 1), ++v7, v9) )
		{
			v10 = v9 & 1;
			v11 = (unsigned int)a3 >> 2;
			if ( !v10 || (*(_WORD *)v7 = *v6, ++v6, v7 += 2, v11) )
			{
				qmemcpy(v7, v6, 4 * v11);
				v6 += 2 * v11;
				v7 += 4 * v11;
			}
		}
		v6 = (_WORD *)((char *)v6 - a3 + 640);
		v7 = &v7[-a3 + 768];
		--v8;
	}
	while ( v8 );
}

//----- (004042CA) --------------------------------------------------------
void __fastcall SetFlaskHeight(char *buf, int min, int max, int c, int r)
{
	char *v5; // esi
	char *v6; // edi
	int v7; // edx

	v5 = &buf[88 * min];
	v6 = &gpBuffer->row_unused_1[r].col_unused_1[c];
	v7 = max - min;
	do
	{
		qmemcpy(v6, v5, 0x58u);
		v5 += 88;
		v6 += 768;
		--v7;
	}
	while ( v7 );
}

//----- (0040431B) --------------------------------------------------------
void __fastcall DrawFlask(void *a1, int a2, int a3, void *a4, int a5, int a6)
{
	char *v6; // esi
	_BYTE *v7; // edi
	int v8; // edx
	signed int v9; // ecx
	char v10; // al
	int v11; // [esp+Ch] [ebp-4h]

	v11 = a2;
	v6 = (char *)a1 + a3;
	v7 = (unsigned char *)a4 + a5;
	v8 = a6;
	do
	{
		v9 = 59;
		do
		{
			v10 = *v6++;
			if ( v10 )
				*v7 = v10;
			++v7;
			--v9;
		}
		while ( v9 );
		v6 = &v6[v11 - 59];
		v7 += 709;
		--v8;
	}
	while ( v8 );
}

//----- (0040435B) --------------------------------------------------------
void __cdecl DrawLifeFlask()
{
	signed __int64 v0; // rax
	signed int v1; // esi
	int v2; // esi

	v0 = (signed __int64)((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0);
	plr[myplr]._pHPPer = v0;
	if ( (signed int)v0 > 80 )
		LODWORD(v0) = 80;
	v1 = 80 - v0;
	if ( 80 - (signed int)v0 > 11 )
		v1 = 11;
	v2 = v1 + 2;
	DrawFlask(pLifeBuff, 88, 277, gpBuffer, 383405, v2);
	if ( v2 != 13 )
		DrawFlask(pBtmBuff, 640, 640 * v2 + 2029, gpBuffer, 768 * v2 + 383405, 13 - v2);
}

//----- (004043F4) --------------------------------------------------------
void __cdecl UpdateLifeFlask()
{
	signed __int64 v0; // rax
	signed int v1; // edi

	v0 = (signed __int64)((double)plr[myplr]._pHitPoints / (double)plr[myplr]._pMaxHP * 80.0);
	v1 = v0;
	plr[myplr]._pHPPer = v0;
	if ( (signed int)v0 > 69 )
	{
		v1 = 69;
LABEL_8:
		DrawPanelBox(96, 85 - v1, 0x58u, v1, 160, 581 - v1);
		return;
	}
	if ( (signed int)v0 < 0 )
		v1 = 0;
	if ( v1 != 69 )
		SetFlaskHeight((char *)pLifeBuff, 16, 85 - v1, 160, 512);
	if ( v1 )
		goto LABEL_8;
}

//----- (00404475) --------------------------------------------------------
void __cdecl DrawManaFlask()
{
	int v0; // eax
	int v1; // esi
	int v2; // esi

	v0 = plr[myplr]._pManaPer;
	if ( v0 > 80 )
		v0 = 80;
	v1 = 80 - v0;
	if ( 80 - v0 > 11 )
		v1 = 11;
	v2 = v1 + 2;
	DrawFlask(pManaBuff, 88, 277, gpBuffer, 383771, v2);
	if ( v2 != 13 )
		DrawFlask(pBtmBuff, 640, 640 * v2 + 2395, gpBuffer, 768 * v2 + 383771, 13 - v2);
}

//----- (004044F6) --------------------------------------------------------
void __cdecl control_update_life_mana()
{
	int v0; // esi
	signed __int64 v1; // rax
	int v2; // [esp+4h] [ebp-8h]
	int v3; // [esp+8h] [ebp-4h]

	v0 = myplr;
	v3 = plr[myplr]._pMaxMana;
	v2 = plr[myplr]._pMana;
	if ( plr[myplr]._pMaxMana < 0 )
		v3 = 0;
	if ( plr[myplr]._pMana < 0 )
		v2 = 0;
	if ( v3 )
		v1 = (signed __int64)((double)v2 / (double)v3 * 80.0);
	else
		LODWORD(v1) = 0;
	plr[v0]._pManaPer = v1;
	plr[v0]._pHPPer = (signed __int64)((double)plr[v0]._pHitPoints / (double)plr[v0]._pMaxHP * 80.0);
}

//----- (0040456A) --------------------------------------------------------
void __cdecl UpdateManaFlask()
{
	signed int v0; // edi
	int v1; // [esp+8h] [ebp-8h]
	int v2; // [esp+Ch] [ebp-4h]

	v2 = plr[myplr]._pMaxMana;
	v1 = plr[myplr]._pMana;
	if ( plr[myplr]._pMaxMana < 0 )
		v2 = 0;
	if ( plr[myplr]._pMana < 0 )
		v1 = 0;
	if ( v2 )
		v0 = (signed __int64)((double)v1 / (double)v2 * 80.0);
	else
		v0 = 0;
	plr[myplr]._pManaPer = v0;
	if ( v0 > 69 )
		v0 = 69;
	if ( v0 != 69 )
		SetFlaskHeight((char *)pManaBuff, 16, 85 - v0, 528, 512);
	if ( v0 )
		DrawPanelBox(464, 85 - v0, 0x58u, v0, 528, 581 - v0);
	DrawSpell();
}

//----- (00404616) --------------------------------------------------------
void __cdecl InitControlPan()
{
	size_t v0; // esi
	void *v1; // ecx
	void *v2; // ecx
	void *v3; // ecx
	char v4; // al
	unsigned char *v5; // eax

	v0 = 0x16800;
	if ( gbMaxPlayers != 1 )
		v0 = 0x2D000;
	pBtmBuff = DiabloAllocPtr(v0);
	memset(pBtmBuff, 0, v0);
	pManaBuff = DiabloAllocPtr(0x1E40);
	memset(pManaBuff, 0, 0x1E40u);
	pLifeBuff = DiabloAllocPtr(0x1E40);
	memset(pLifeBuff, 0, 0x1E40u);
	pPanelText = LoadFileInMem("CtrlPan\\SmalText.CEL", 0);
	pChrPanel = LoadFileInMem("Data\\Char.CEL", 0);
	pSpellCels = LoadFileInMem("CtrlPan\\SpelIcon.CEL", 0);
	SetSpellTrans(0);
	pStatusPanel = LoadFileInMem("CtrlPan\\Panel8.CEL", 0);
	Cel_into_rect_of_buf((char *)pBtmBuff, 0, 143, 640, (char *)pStatusPanel, 1, 640);
	v1 = pStatusPanel;
	pStatusPanel = 0;
	mem_free_dbg(v1);
	pStatusPanel = LoadFileInMem("CtrlPan\\P8Bulbs.CEL", 0);
	Cel_into_rect_of_buf((char *)pLifeBuff, 0, 87, 88, (char *)pStatusPanel, 1, 88);
	Cel_into_rect_of_buf((char *)pManaBuff, 0, 87, 88, (char *)pStatusPanel, 2, 88);
	v2 = pStatusPanel;
	pStatusPanel = 0;
	mem_free_dbg(v2);
	talkflag = 0;
	if ( gbMaxPlayers != 1 )
	{
		pTalkPanel = LoadFileInMem("CtrlPan\\TalkPanl.CEL", 0);
		Cel_into_rect_of_buf((char *)pBtmBuff, 0, 287, 640, (char *)pTalkPanel, 1, 640);
		v3 = pTalkPanel;
		pTalkPanel = 0;
		mem_free_dbg(v3);
		pMultiBtns = LoadFileInMem("CtrlPan\\P8But2.CEL", 0);
		pTalkBtns = LoadFileInMem("CtrlPan\\TalkButt.CEL", 0);
		sgbPlrTalkTbl = 0;
		*(_DWORD *)&tempstr[256] = 0x1010101;
		talkbtndown[0] = 0;
		talkbtndown[1] = 0;
		sgszTalkMsg[0] = 0;
		talkbtndown[2] = 0;
	}
	panelflag = 0;
	lvlbtndown = 0;
	pPanelButtons = LoadFileInMem("CtrlPan\\Panel8bu.CEL", 0);
	memset(panbtn, 0, sizeof(panbtn));
	panbtndown = 0;
	numpanbtns = 2 * (gbMaxPlayers != 1) + 6;
	pChrButtons = LoadFileInMem("Data\\CharBut.CEL", 0);
	chrbtn[0] = 0;
	chrbtn[1] = 0;
	chrbtn[2] = 0;
	chrbtnactive = 0;
	chrbtn[3] = 0;
	pDurIcons = LoadFileInMem("Items\\DurIcons.CEL", 0);
	strcpy(infostr, &empty_string);
	ClearPanel();
	drawhpflag = 1;
	drawmanaflag = 1;
	chrflag = 0;
	spselflag = 0;
	pSpellBkCel = LoadFileInMem("Data\\SpellBk.CEL", 0);
	pSBkBtnCel = LoadFileInMem("Data\\SpellBkB.CEL", 0);
	pSBkIconCels = LoadFileInMem("Data\\SpellI2.CEL", 0);
	sbooktab = 0;
	sbookflag = 0;
	v4 = plr[myplr]._pClass;
	if ( v4 )
	{
		if ( v4 == UI_ROGUE )
		{
			SpellPages[0][0] = SPL_DISARM;
		}
		else if ( v4 == UI_SORCERER )
		{
			SpellPages[0][0] = SPL_RECHARGE;
		}
	}
	else
	{
		SpellPages[0][0] = SPL_REPAIR;
	}
	pQLogCel = LoadFileInMem("Data\\Quest.CEL", 0);
	v5 = LoadFileInMem("CtrlPan\\Golddrop.cel", 0);
	frame_4B8800 = 1;
	dropGoldFlag = 0;
	dropGoldValue = 0;
	initialDropGoldValue = 0;
	initialDropGoldIndex = 0;
	pGBoxBuff = v5;
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B851C: using guessed type int lvlbtndown;
// 4B87A8: using guessed type int chrbtnactive;
// 4B8840: using guessed type int sgbPlrTalkTbl;
// 4B8950: using guessed type int sbooktab;
// 4B8960: using guessed type int talkflag;
// 4B8968: using guessed type int sbookflag;
// 4B8A7C: using guessed type int numpanbtns;
// 4B8B84: using guessed type int panelflag;
// 4B8C90: using guessed type int panbtndown;
// 4B8C98: using guessed type int spselflag;
// 679660: using guessed type char gbMaxPlayers;

//----- (00404934) --------------------------------------------------------
void __cdecl ClearCtrlPan()
{
	DrawPanelBox(0, sgbPlrTalkTbl + 16, 0x280u, 0x80u, 64, 512);
	DrawInfoBox();
}
// 4B8840: using guessed type int sgbPlrTalkTbl;

//----- (00404959) --------------------------------------------------------
void __cdecl DrawCtrlPan()
{
	signed int v0; // edi
	int *v1; // esi
	int v2; // ecx
	int v3; // eax

	v0 = 0;
	v1 = (int *)PanBtnPos;
	do
	{
		v2 = *v1;
		if ( panbtn[v0] )
			Cel_decode(v2 + 64, v1[1] + 178, pPanelButtons, v0 + 1, 71);
		else
			DrawPanelBox(v2, v1[1] - 336, 0x47u, 0x14u, v2 + 64, v1[1] + 160);
		++v0;
		v1 += 5;
	}
	while ( v0 < 6 );
	if ( numpanbtns == 8 )
	{
		Cel_decode(151, 634, pMultiBtns, panbtn[6] + 1, 33);
		if ( FriendlyMode )
			v3 = panbtn[7] + 3;
		else
			v3 = panbtn[7] + 5;
		Cel_decode(591, 634, pMultiBtns, v3, 33);
	}
}
// 484368: using guessed type int FriendlyMode;
// 4B8A7C: using guessed type int numpanbtns;

//----- (00404A0A) --------------------------------------------------------
void __cdecl DoSpeedBook()
{
	int v0; // eax
	signed int v1; // ebx
	bool v2; // zf
	unsigned __int64 v3; // rdi
	unsigned int v4; // ecx
	unsigned int v5; // [esp+4h] [ebp-20h]
	unsigned int v6; // [esp+8h] [ebp-1Ch]
	unsigned int v7; // [esp+8h] [ebp-1Ch]
	int X; // [esp+Ch] [ebp-18h]
	int Y; // [esp+10h] [ebp-14h]
	signed int v10; // [esp+14h] [ebp-10h]
	int v11; // [esp+18h] [ebp-Ch]
	signed int v12; // [esp+1Ch] [ebp-8h]
	signed int v13; // [esp+20h] [ebp-4h]

	v0 = myplr;
	v13 = 636;
	v1 = 1;
	v2 = plr[myplr]._pRSpell == -1;
	spselflag = 1;
	v12 = 495;
	X = 600;
	Y = 307;
	if ( !v2 )
	{
		v11 = 0;
		v3 = __PAIR__(v5, v6);
		while ( 1 )
		{
			if ( v11 )
			{
				switch ( v11 )
				{
					case RSPLTYPE_SPELL:
						HIDWORD(v3) = plr[v0]._pMemSpells[0];
						LODWORD(v3) = plr[v0]._pMemSpells[1];
						break;
					case RSPLTYPE_SCROLL:
						HIDWORD(v3) = plr[v0]._pScrlSpells[0];
						LODWORD(v3) = plr[v0]._pScrlSpells[1];
						break;
					case RSPLTYPE_CHARGES:
						HIDWORD(v3) = plr[v0]._pISpells[0];
						LODWORD(v3) = plr[v0]._pISpells[1];
						break;
				}
			}
			else
			{
				HIDWORD(v3) = plr[v0]._pAblSpells[0];
				LODWORD(v3) = plr[v0]._pAblSpells[1];
			}
			v7 = 0;
			v10 = 1;
			do
			{
				if ( (unsigned int)v3 & v7 | HIDWORD(v3) & v1 )
				{
					if ( v10 == plr[v0]._pRSpell && v11 == SLOBYTE(plr[v0]._pRSplType) )
					{
						X = v13 - 36;
						Y = v12 - 188;
					}
					v13 -= 56;
					if ( v13 == 20 )
					{
						v12 -= 56;
						v13 = 636;
					}
				}
				v4 = __PAIR__(v7, v1) >> 31;
				v1 *= 2;
				++v10;
				v7 = v4;
			}
			while ( v10 < 37 );
			if ( v3 && v13 != 636 )
				v13 -= 56;
			if ( v13 == 20 )
			{
				v12 -= 56;
				v13 = 636;
			}
			if ( ++v11 >= 4 )
				break;
			v1 = 1;
		}
	}
	SetCursorPos(X, Y);
}
// 4B8C98: using guessed type int spselflag;

//----- (00404B52) --------------------------------------------------------
void __cdecl DoPanBtn()
{
	int v0; // edx
	int v1; // ebx
	int v2; // edi
	int v3; // esi
	int (*v4)[5]; // eax
	int v5; // ecx

	v0 = MouseX;
	v1 = MouseY;
	v2 = numpanbtns;
	v3 = 0;
	if ( numpanbtns > 0 )
	{
		v4 = PanBtnPos;
		do
		{
			if ( v0 >= (*v4)[0] && v0 <= (*v4)[0] + (*v4)[2] )
			{
				v5 = (*v4)[1];
				if ( v1 >= v5 && v1 <= v5 + (*v4)[3] )
				{
					panbtn[v3] = 1;
					drawbtnflag = 1;
					panbtndown = 1;
				}
			}
			++v3;
			++v4;
		}
		while ( v3 < v2 );
	}
	if ( !spselflag && v0 >= 565 && v0 < 621 && v1 >= 416 && v1 < 472 )
	{
		DoSpeedBook();
		gamemenu_off();
	}
}
// 4B8A7C: using guessed type int numpanbtns;
// 4B8C90: using guessed type int panbtndown;
// 4B8C98: using guessed type int spselflag;

//----- (00404BEB) --------------------------------------------------------
void __fastcall control_set_button_down(int btn_id)
{
	panbtn[btn_id] = 1;
	drawbtnflag = 1;
	panbtndown = 1;
}
// 4B8C90: using guessed type int panbtndown;

//----- (00404C00) --------------------------------------------------------
void __cdecl control_check_btn_press()
{
	int v0; // edx
	int v1; // esi

	v0 = MouseX;
	v1 = MouseY;
	if ( MouseX >= PanBtnPos[3][0]
	  && MouseX <= PanBtnPos[3][0] + PanBtnPos[3][2]
	  && MouseY >= PanBtnPos[3][1]
	  && MouseY <= PanBtnPos[3][1] + PanBtnPos[3][3] )
	{
		control_set_button_down(3);
	}
	if ( v0 >= PanBtnPos[6][0]
	  && v0 <= PanBtnPos[6][0] + PanBtnPos[6][2]
	  && v1 >= PanBtnPos[6][1]
	  && v1 <= PanBtnPos[6][1] + PanBtnPos[6][3] )
	{
		control_set_button_down(6);
	}
}

//----- (00404C74) --------------------------------------------------------
void __cdecl DoAutoMap()
{
	if ( currlevel || gbMaxPlayers != 1 )
	{
		if ( *(_DWORD *)&automapflag )
			*(_DWORD *)&automapflag = 0;
		else
			StartAutomap();
	}
	else
	{
		InitDiabloMsg(1);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00404CA0) --------------------------------------------------------
void __cdecl CheckPanelInfo()
{
	int v0; // edi
	int v1; // eax
	int v2; // ecx
	int v3; // ecx
	int v4; // edi
	int v5; // eax
	int *v6; // edx
	int v7; // ebx
	int v8; // ebx
	int *v9; // eax
	signed int v10; // edx
	int v11; // ecx
	int v12; // [esp+10h] [ebp-4h]

	v0 = 0;
	panelflag = 0;
	ClearPanel();
	if ( numpanbtns > 0 )
	{
		do
		{
			v1 = v0;
			v2 = PanBtnPos[v0][0];
			if ( MouseX >= v2 && MouseX <= v2 + PanBtnPos[v1][2] )
			{
				v3 = PanBtnPos[v1][1];
				if ( MouseY >= v3 && MouseY <= v3 + PanBtnPos[v1][3] )
				{
					if ( v0 == 7 )
					{
						if ( FriendlyMode )
							strcpy(infostr, "Player friendly");
						else
							strcpy(infostr, "Player attack");
					}
					else
					{
						strcpy(infostr, PanBtnStr[v0]);
					}
					if ( PanBtnHotKey[v0] )
					{
						sprintf(tempstr, "Hotkey : %s", PanBtnHotKey[v0]);
						AddPanelString(tempstr, 1);
					}
					_LOBYTE(infoclr) = 0;
					panelflag = 1;
					pinfoflag = 1;
				}
			}
			++v0;
		}
		while ( v0 < numpanbtns );
	}
	if ( !spselflag && MouseX >= 565 && MouseX < 621 && MouseY >= 416 && MouseY < 472 )
	{
		strcpy(infostr, "Select current spell button");
		_LOBYTE(infoclr) = 0;
		panelflag = 1;
		pinfoflag = 1;
		strcpy(tempstr, "Hotkey : 's'");
		AddPanelString(tempstr, 1);
		v4 = plr[myplr]._pRSpell;
		if ( v4 != -1 )
		{
			switch ( _LOBYTE(plr[myplr]._pRSplType) )
			{
				case RSPLTYPE_SKILL:
					sprintf(tempstr, "%s Skill", spelldata[v4].sSkillText);
LABEL_54:
					AddPanelString(tempstr, 1);
					break;
				case RSPLTYPE_SPELL:
					sprintf(tempstr, "%s Spell", spelldata[v4].sNameText);
					AddPanelString(tempstr, 1);
					v11 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v4];
					if ( v11 < 0 )
						v11 = 0;
					if ( v11 )
						sprintf(tempstr, "Spell Level %i", v11);
					else
						sprintf(tempstr, "Spell Level 0 - Unusable");
					goto LABEL_54;
				case RSPLTYPE_SCROLL:
					sprintf(tempstr, "Scroll of %s", spelldata[v4].sNameText);
					AddPanelString(tempstr, 1);
					v12 = 0;
					v5 = myplr;
					if ( plr[myplr]._pNumInv > 0 )
					{
						v6 = &plr[v5].InvList[0]._iMiscId;
						v7 = plr[myplr]._pNumInv;
						do
						{
							if ( *(v6 - 53) != -1 && (*v6 == IMISC_SCROLL || *v6 == IMISC_SCROLLT) && v6[1] == v4 )
								++v12;
							v6 += 92;
							--v7;
						}
						while ( v7 );
					}
					v8 = v12;
					v9 = &plr[v5].SpdList[0]._iMiscId;
					v10 = 8;
					do
					{
						if ( *(v9 - 53) != -1 && (*v9 == IMISC_SCROLL || *v9 == IMISC_SCROLLT) && v9[1] == v4 )
							++v8;
						v9 += 92;
						--v10;
					}
					while ( v10 );
					if ( v8 == 1 )
						strcpy(tempstr, "1 Scroll");
					else
						sprintf(tempstr, "%i Scrolls", v8);
					goto LABEL_54;
				case RSPLTYPE_CHARGES:
					sprintf(tempstr, "Staff of %s", spelldata[v4].sNameText);
					AddPanelString(tempstr, 1);
					if ( plr[myplr].InvBody[4]._iCharges == 1 )
						strcpy(tempstr, "1 Charge");
					else
						sprintf(tempstr, "%i Charges", plr[myplr].InvBody[4]._iCharges);
					goto LABEL_54;
			}
		}
	}
	if ( MouseX > 190 && MouseX < 437 && MouseY > 356 && MouseY < 385 )
		pcursinvitem = CheckInvHLight();
}
// 484368: using guessed type int FriendlyMode;
// 4B8824: using guessed type int pinfoflag;
// 4B883C: using guessed type int infoclr;
// 4B8A7C: using guessed type int numpanbtns;
// 4B8B84: using guessed type int panelflag;
// 4B8C98: using guessed type int spselflag;
// 4B8CB8: using guessed type char pcursinvitem;

//----- (00404FE4) --------------------------------------------------------
void __cdecl CheckBtnUp()
{
	signed int v0; // esi
	int *v1; // eax
	int v2; // edx
	signed int v3; // eax
	int v4; // ecx
	int v5; // ecx
	char v6; // [esp+Fh] [ebp-1h]

	v6 = 1;
	drawbtnflag = 1;
	panbtndown = 0;
	v0 = 0;
	do
	{
		v1 = &panbtn[v0];
		if ( *v1 )
		{
			v2 = MouseX;
			*v1 = 0;
			v3 = v0;
			v4 = PanBtnPos[v0][0];
			if ( v2 >= v4 && v2 <= v4 + PanBtnPos[v3][2] )
			{
				v5 = PanBtnPos[v3][1];
				if ( MouseY >= v5 && MouseY <= v5 + PanBtnPos[v3][3] )
				{
					switch ( v0 )
					{
						case PANBTN_CHARINFO:
							questlog = 0;
							chrflag = chrflag == 0;
							break;
						case PANBTN_QLOG:
							chrflag = 0;
							if ( questlog )
								questlog = 0;
							else
								StartQuestlog();
							break;
						case PANBTN_AUTOMAP:
							DoAutoMap();
							break;
						case PANBTN_MAINMENU:
							qtextflag = 0;
							gamemenu_handle_previous();
							v6 = 0;
							break;
						case PANBTN_INVENTORY:
							sbookflag = 0;
							invflag = invflag == 0;
							if ( dropGoldFlag )
							{
								dropGoldFlag = 0;
								dropGoldValue = 0;
							}
							break;
						case PANBTN_SPELLBOOK:
							invflag = 0;
							if ( dropGoldFlag )
							{
								dropGoldFlag = 0;
								dropGoldValue = 0;
							}
							sbookflag = sbookflag == 0;
							break;
						case PANBTN_SENDMSG:
							if ( talkflag )
								control_reset_talk();
							else
								control_type_message();
							break;
						case PANBTN_FRIENDLY:
							FriendlyMode = FriendlyMode == 0;
							break;
						default:
							break;
					}
				}
			}
		}
		++v0;
	}
	while ( v0 < 8 );
	if ( v6 )
		gamemenu_off();
}
// 484368: using guessed type int FriendlyMode;
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8960: using guessed type int talkflag;
// 4B8968: using guessed type int sbookflag;
// 4B8C90: using guessed type int panbtndown;
// 646D00: using guessed type char qtextflag;
// 69BD04: using guessed type int questlog;

//----- (00405181) --------------------------------------------------------
void __cdecl FreeControlPan()
{
	void *v0; // ecx
	void *v1; // ecx
	void *v2; // ecx
	void *v3; // ecx
	void *v4; // ecx
	void *v5; // ecx
	void *v6; // ecx
	void *v7; // ecx
	void *v8; // ecx
	void *v9; // ecx
	void *v10; // ecx
	void *v11; // ecx
	void *v12; // ecx
	void *v13; // ecx
	void *v14; // ecx
	void *v15; // ecx

	v0 = pBtmBuff;
	pBtmBuff = 0;
	mem_free_dbg(v0);
	v1 = pManaBuff;
	pManaBuff = 0;
	mem_free_dbg(v1);
	v2 = pLifeBuff;
	pLifeBuff = 0;
	mem_free_dbg(v2);
	v3 = pPanelText;
	pPanelText = 0;
	mem_free_dbg(v3);
	v4 = pChrPanel;
	pChrPanel = 0;
	mem_free_dbg(v4);
	v5 = pSpellCels;
	pSpellCels = 0;
	mem_free_dbg(v5);
	v6 = pPanelButtons;
	pPanelButtons = 0;
	mem_free_dbg(v6);
	v7 = pMultiBtns;
	pMultiBtns = 0;
	mem_free_dbg(v7);
	v8 = pTalkBtns;
	pTalkBtns = 0;
	mem_free_dbg(v8);
	v9 = pChrButtons;
	pChrButtons = 0;
	mem_free_dbg(v9);
	v10 = pDurIcons;
	pDurIcons = 0;
	mem_free_dbg(v10);
	v11 = pQLogCel;
	pQLogCel = 0;
	mem_free_dbg(v11);
	v12 = pSpellBkCel;
	pSpellBkCel = 0;
	mem_free_dbg(v12);
	v13 = pSBkBtnCel;
	pSBkBtnCel = 0;
	mem_free_dbg(v13);
	v14 = pSBkIconCels;
	pSBkIconCels = 0;
	mem_free_dbg(v14);
	v15 = pGBoxBuff;
	pGBoxBuff = 0;
	mem_free_dbg(v15);
}

//----- (00405295) --------------------------------------------------------
int __fastcall control_WriteStringToBuffer(char *str)
{
	signed int v1; // edx
	unsigned char v2; // al

	v1 = 0;
	do
	{
		v2 = *str;
		if ( !*str )
			return 1;
		++str;
		v1 += fontkern[fontframe[fontidx[v2]]];
	}
	while ( v1 < 125 );
	return 0;
}

//----- (004052C8) --------------------------------------------------------
void __cdecl DrawInfoBox()
{
	int v0; // ecx
	int v1; // eax
	int v2; // eax
	int v3; // esi
	char *v4; // eax
	const char *v5; // eax
	char v6; // al
	signed int v7; // edi
	signed int v8; // ebp
	int v9; // esi
	char *v10; // ebx

	DrawPanelBox(177, 62, 0x120u, 0x3Cu, 241, 558);
	v0 = trigflag[3];
	v1 = spselflag;
	if ( !panelflag && !trigflag[3] && pcursinvitem == -1 )
	{
		if ( spselflag )
		{
LABEL_32:
			_LOBYTE(infoclr) = 0;
			goto LABEL_33;
		}
		infostr[0] = 0;
		_LOBYTE(infoclr) = 0;
		ClearPanel();
	}
	if ( v1 || v0 )
		goto LABEL_32;
	if ( pcurs < CURSOR_FIRSTITEM )
	{
		if ( pcursitem != -1 )
			GetItemStr(pcursitem);
		if ( pcursobj != -1 )
			GetObjectStr(pcursobj);
		if ( *(_DWORD *)&pcursmonst != -1 )
		{
			if ( leveltype )
			{
				_LOBYTE(infoclr) = 0;
				strcpy(infostr, monster[*(_DWORD *)&pcursmonst].mName);
				ClearPanel();
				if ( monster[*(_DWORD *)&pcursmonst]._uniqtype )
				{
					_LOBYTE(infoclr) = 3;
					PrintUniqueHistory();
				}
				else
				{
					PrintMonstHistory(monster[*(_DWORD *)&pcursmonst].MType->mtype);
				}
			}
			else
			{
				strcpy(infostr, towner[*(_DWORD *)&pcursmonst]._tName);
			}
		}
		if ( pcursplr != -1 )
		{
			_LOBYTE(infoclr) = 3;
			strcpy(infostr, plr[pcursplr]._pName);
			ClearPanel();
			sprintf(tempstr, "Level : %i", plr[pcursplr]._pLevel);
			AddPanelString(tempstr, 1);
			sprintf(tempstr, "Hit Points %i of %i", plr[pcursplr]._pHitPoints >> 6, plr[pcursplr]._pMaxHP >> 6);
			AddPanelString(tempstr, 1);
		}
	}
	else
	{
		v2 = myplr;
		if ( plr[myplr].HoldItem._itype == ITYPE_GOLD )
		{
			v3 = plr[v2].HoldItem._ivalue;
			v4 = get_pieces_str(plr[v2].HoldItem._ivalue);
			sprintf(infostr, "%i gold %s", v3, v4);
		}
		else if ( plr[v2].HoldItem._iStatFlag )
		{
			if ( plr[v2].HoldItem._iIdentified )
				v5 = plr[v2].HoldItem._iIName;
			else
				v5 = plr[v2].HoldItem._iName;
			strcpy(infostr, v5);
			v6 = plr[myplr].HoldItem._iMagical;
			if ( v6 == 1 )
				_LOBYTE(infoclr) = 1;
			if ( v6 == 2 )
				_LOBYTE(infoclr) = 3;
		}
		else
		{
			ClearPanel();
			AddPanelString("Requirements not met", 1);
			pinfoflag = 1;
		}
	}
LABEL_33:
	if ( (infostr[0] || pnumlines) && !talkflag )
	{
		v7 = 0;
		v8 = 1;
		if ( infostr[0] )
		{
			control_print_info_str(0, infostr, 1, pnumlines);
			v7 = 1;
			v8 = 0;
		}
		v9 = 0;
		if ( pnumlines > 0 )
		{
			v10 = panelstr;
			do
			{
				control_print_info_str(v9 + v7, v10, pstrjust[v9], pnumlines - v8);
				++v9;
				v10 += 64;
			}
			while ( v9 < pnumlines );
		}
	}
}
// 4B8824: using guessed type int pinfoflag;
// 4B883C: using guessed type int infoclr;
// 4B8960: using guessed type int talkflag;
// 4B8B84: using guessed type int panelflag;
// 4B8C98: using guessed type int spselflag;
// 4B8CB8: using guessed type char pcursinvitem;
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC1: using guessed type char pcursobj;
// 4B8CC2: using guessed type char pcursplr;
// 5BB1ED: using guessed type char leveltype;

//----- (004055BC) --------------------------------------------------------
void __fastcall control_print_info_str(int y, char *str, int a3, int lines)
{
	int v4; // edi
	char *v5; // ebx
	unsigned char v6; // cl
	signed int v7; // eax
	char *v8; // esi
	int v9; // eax
	char *v10; // esi
	unsigned char v11; // al
	int width; // [esp+18h] [ebp+Ch]

	v4 = 0;
	v5 = str;
	width = lineoffset[y + 4 * lines + lines];
	if ( a3 == 1 )
	{
		v6 = *str;
		v7 = 0;
		v8 = str;
		if ( !*str )
			goto LABEL_14;
		do
		{
			++v8;
			v7 += fontkern[fontframe[fontidx[v6]]] + 2;
			v6 = *v8;
		}
		while ( *v8 );
		if ( v7 < 288 )
LABEL_14:
			v4 = (288 - v7) >> 1;
		width += v4;
	}
	while ( 1 )
	{
		v11 = *v5;
		if ( !*v5 )
			break;
		++v5;
		v9 = fontidx[v11];
		_LOBYTE(v9) = fontframe[v9];
		v10 = (char *)(unsigned char)v9;
		v4 += fontkern[(unsigned char)v9] + 2;
		if ( (_BYTE)v9 )
		{
			if ( v4 < 288 )
			{
				_LOBYTE(v9) = infoclr;
				CPrintString(width, v10, v9);
			}
		}
		width += fontkern[(_DWORD)v10] + 2;
	}
}
// 4B883C: using guessed type int infoclr;

//----- (00405681) --------------------------------------------------------
void __fastcall PrintGameStr(int x, int y, char *str, int color)
{
	char *v4; // edi
	int v5; // esi
	unsigned char i; // al
	unsigned char v7; // bl

	v4 = str;
	v5 = screen_y_times_768[y + 160] + x + 64;
	for ( i = *str; *v4; i = *v4 )
	{
		++v4;
		v7 = fontframe[fontidx[i]];
		if ( v7 )
			CPrintString(v5, (char *)v7, color);
		v5 += fontkern[v7] + 1;
	}
}

//----- (004056D8) --------------------------------------------------------
void __cdecl DrawChr()
{
	char v0; // al
	int v1; // ecx
	int v2; // ecx
	int v3; // eax
	int v4; // eax
	bool v5; // zf
	int v6; // eax
	int v7; // edi
	int v8; // edi
	char v9; // al
	char v10; // al
	char v11; // al
	int v12; // ecx
	int v13; // eax
	int v14; // ecx
	int v15; // eax
	int v16; // ecx
	int v17; // eax
	int v18; // ecx
	int v19; // eax
	int *v20; // edi
	int v21; // edi
	int v22; // edi
	int v23; // ecx
	int v24; // eax
	int v25; // ecx
	int v26; // ecx
	char a4[64]; // [esp+Ch] [ebp-50h]
	int v28; // [esp+4Ch] [ebp-10h]
	int v29; // [esp+50h] [ebp-Ch]
	int v30; // [esp+54h] [ebp-8h]
	char a5[4]; // [esp+58h] [ebp-4h]

	Cel_decode(64, 511, pChrPanel, 1, 320);
	ADD_PlrStringXY(20, 32, 151, plr[myplr]._pName, 0);
	v0 = plr[myplr]._pClass;
	if ( v0 )
	{
		if ( v0 == 1 )
		{
			ADD_PlrStringXY(168, 32, 299, "Rogue", 0);
		}
		else if ( v0 == 2 )
		{
			ADD_PlrStringXY(168, 32, 299, "Sorceror", 0);
		}
	}
	else
	{
		ADD_PlrStringXY(168, 32, 299, "Warrior", 0);
	}
	sprintf(a4, "%i", plr[myplr]._pLevel);
	ADD_PlrStringXY(66, 69, 109, a4, 0);
	sprintf(a4, "%li", plr[myplr]._pExperience);
	ADD_PlrStringXY(216, 69, 300, a4, 0);
	if ( plr[myplr]._pLevel == 50 )
	{
		strcpy(a4, "None");
		a5[0] = 3;
	}
	else
	{
		sprintf(a4, "%li", plr[myplr]._pNextExper);
		a5[0] = 0;
	}
	ADD_PlrStringXY(216, 97, 300, a4, a5[0]);
	sprintf(a4, "%i", plr[myplr]._pGold);
	ADD_PlrStringXY(216, 146, 300, a4, 0);
	a5[0] = 0;
	v29 = plr[myplr]._pIBonusAC;
	if ( v29 > 0 )
		a5[0] = 1;
	if ( v29 < 0 )
		a5[0] = 2;
	sprintf(a4, "%i", v29 + plr[myplr]._pIAC + plr[myplr]._pDexterity / 5);
	ADD_PlrStringXY(258, 183, 301, a4, a5[0]);
	a5[0] = 0;
	v1 = plr[myplr]._pIBonusToHit;
	if ( v1 > 0 )
		a5[0] = 1;
	if ( v1 < 0 )
		a5[0] = 2;
	sprintf(a4, "%i%%", (plr[myplr]._pDexterity >> 1) + v1 + 50);
	ADD_PlrStringXY(258, 211, 301, a4, a5[0]);
	a5[0] = 0;
	v2 = myplr;
	v3 = plr[myplr]._pIBonusDam;
	if ( v3 > 0 )
		a5[0] = 1;
	if ( v3 < 0 )
		a5[0] = 2;
	v30 = plr[v2]._pIMinDam;
	v30 += plr[v2]._pIBonusDamMod + v30 * v3 / 100;
	v4 = plr[v2]._pDamageMod;
	v5 = plr[v2].InvBody[4]._itype == ITYPE_BOW;
	v29 = plr[v2]._pDamageMod;
	if ( v5 && _LOBYTE(plr[v2]._pClass) != 1 )
		v4 >>= 1;
	v30 += v4;
	v6 = plr[v2]._pIBonusDam;
	v28 = plr[v2]._pIMaxDam;
	v7 = plr[v2]._pIBonusDamMod + v28 * v6 / 100 + v28;
	if ( plr[v2].InvBody[4]._itype != ITYPE_BOW || _LOBYTE(plr[v2]._pClass) == 1 )
		v8 = v29 + v7;
	else
		v8 = (v29 >> 1) + v7;
	sprintf(a4, "%i-%i", v30, v8);
	if ( v30 >= 100 || v8 >= 100 )
		MY_PlrStringXY(254, 239, 305, a4, a5[0], -1);
	else
		MY_PlrStringXY(258, 239, 301, a4, a5[0], 0);
	v9 = plr[myplr]._pMagResist;
	a5[0] = v9 != 0;
	if ( v9 >= 75 )
	{
		a5[0] = 3;
		sprintf(a4, "MAX");
	}
	else
	{
		sprintf(a4, "%i%%", v9);
	}
	ADD_PlrStringXY(257, 276, 300, a4, a5[0]);
	v10 = plr[myplr]._pFireResist;
	a5[0] = v10 != 0;
	if ( v10 >= 75 )
	{
		a5[0] = 3;
		sprintf(a4, "MAX");
	}
	else
	{
		sprintf(a4, "%i%%", v10);
	}
	ADD_PlrStringXY(257, 304, 300, a4, a5[0]);
	v11 = plr[myplr]._pLghtResist;
	a5[0] = v11 != 0;
	if ( v11 >= 75 )
	{
		a5[0] = 3;
		sprintf(a4, "MAX");
	}
	else
	{
		sprintf(a4, "%i%%", v11);
	}
	ADD_PlrStringXY(257, 332, 300, a4, a5[0]);
	a5[0] = 0;
	sprintf(a4, "%i", plr[myplr]._pBaseStr);
	if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][0] == plr[myplr]._pBaseStr )
		a5[0] = 3;
	ADD_PlrStringXY(95, 155, 126, a4, a5[0]);
	a5[0] = 0;
	sprintf(a4, "%i", plr[myplr]._pBaseMag);
	if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][1] == plr[myplr]._pBaseMag )
		a5[0] = 3;
	ADD_PlrStringXY(95, 183, 126, a4, a5[0]);
	a5[0] = 0;
	sprintf(a4, "%i", plr[myplr]._pBaseDex);
	if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][2] == plr[myplr]._pBaseDex )
		a5[0] = 3;
	ADD_PlrStringXY(95, 211, 126, a4, a5[0]);
	a5[0] = 0;
	sprintf(a4, "%i", plr[myplr]._pBaseVit);
	if ( MaxStats[SLOBYTE(plr[myplr]._pClass)][3] == plr[myplr]._pBaseVit )
		a5[0] = 3;
	ADD_PlrStringXY(95, 239, 126, a4, a5[0]);
	a5[0] = 0;
	v12 = plr[myplr]._pStrength;
	v13 = plr[myplr]._pBaseStr;
	if ( v12 > v13 )
		a5[0] = 1;
	if ( v12 < v13 )
		a5[0] = 2;
	sprintf(a4, "%i", v12);
	ADD_PlrStringXY(143, 155, 173, a4, a5[0]);
	a5[0] = 0;
	v14 = plr[myplr]._pMagic;
	v15 = plr[myplr]._pBaseMag;
	if ( v14 > v15 )
		a5[0] = 1;
	if ( v14 < v15 )
		a5[0] = 2;
	sprintf(a4, "%i", v14);
	ADD_PlrStringXY(143, 183, 173, a4, a5[0]);
	a5[0] = 0;
	v16 = plr[myplr]._pDexterity;
	v17 = plr[myplr]._pBaseDex;
	if ( v16 > v17 )
		a5[0] = 1;
	if ( v16 < v17 )
		a5[0] = 2;
	sprintf(a4, "%i", v16);
	ADD_PlrStringXY(143, 211, 173, a4, a5[0]);
	a5[0] = 0;
	v18 = plr[myplr]._pVitality;
	v19 = plr[myplr]._pBaseVit;
	if ( v18 > v19 )
		a5[0] = 1;
	if ( v18 < v19 )
		a5[0] = 2;
	sprintf(a4, "%i", v18);
	ADD_PlrStringXY(143, 239, 173, a4, a5[0]);
	v20 = &plr[myplr]._pStatPts;
	if ( *v20 > 0 )
	{
		v20 = &plr[myplr]._pStatPts;
		if ( CalcStatDiff(myplr) < *v20 )
		{
			v20 = &plr[myplr]._pStatPts;
			*v20 = CalcStatDiff(myplr);
		}
	}
	v21 = *v20;
	if ( v21 > 0 )
	{
		sprintf(a4, "%i", v21);
		ADD_PlrStringXY(95, 266, 126, a4, 2);
		v22 = SLOBYTE(plr[myplr]._pClass);
		if ( plr[myplr]._pBaseStr < MaxStats[v22][0] )
			Cel_decode(201, 319, pChrButtons, chrbtn[0] + 2, 41);
		if ( plr[myplr]._pBaseMag < MaxStats[v22][1] )
			Cel_decode(201, 347, pChrButtons, chrbtn[1] + 4, 41);
		if ( plr[myplr]._pBaseDex < MaxStats[v22][2] )
			Cel_decode(201, 376, pChrButtons, chrbtn[2] + 6, 41);
		if ( plr[myplr]._pBaseVit < MaxStats[v22][3] )
			Cel_decode(201, 404, pChrButtons, chrbtn[3] + 8, 41);
	}
	v23 = plr[myplr]._pMaxHP;
	a5[0] = v23 > plr[myplr]._pMaxHPBase;
	sprintf(a4, "%i", v23 >> 6);
	ADD_PlrStringXY(95, 304, 126, a4, a5[0]);
	v24 = plr[myplr]._pHitPoints;
	if ( v24 != plr[myplr]._pMaxHP )
		a5[0] = 2;
	sprintf(a4, "%i", v24 >> 6);
	ADD_PlrStringXY(143, 304, 174, a4, a5[0]);
	v25 = plr[myplr]._pMaxMana;
	a5[0] = v25 > plr[myplr]._pMaxManaBase;
	sprintf(a4, "%i", v25 >> 6);
	ADD_PlrStringXY(95, 332, 126, a4, a5[0]);
	v26 = plr[myplr]._pMana;
	if ( v26 != plr[myplr]._pMaxMana )
		a5[0] = 2;
	sprintf(a4, "%i", v26 >> 6);
	ADD_PlrStringXY(143, 332, 174, a4, a5[0]);
}

//----- (00406058) --------------------------------------------------------
void __fastcall ADD_PlrStringXY(int x, int y, int width, char *pszStr, char col)
{
	int v5; // eax
	char *v6; // edx
	unsigned char v7; // al
	int v8; // esi
	int v9; // edi
	int v10; // ecx
	unsigned char v11; // bl
	unsigned char v12; // al
	int v13; // ebx
	int widtha; // [esp+Ch] [ebp-4h]
	int widthb; // [esp+Ch] [ebp-4h]

	v5 = screen_y_times_768[y + 160];
	v6 = pszStr;
	widtha = v5 + x + 64;
	v7 = *pszStr;
	v8 = width - x + 1;
	v9 = 0;
	v10 = 0;
	if ( *pszStr )
	{
		v11 = *pszStr;
		do
		{
			++v6;
			v10 += fontkern[fontframe[fontidx[v11]]] + 1;
			v11 = *v6;
		}
		while ( *v6 );
	}
	if ( v10 < v8 )
		v9 = (v8 - v10) >> 1;
	widthb = v9 + widtha;
	while ( v7 )
	{
		++pszStr;
		v12 = fontframe[fontidx[v7]];
		v13 = v12;
		v9 += fontkern[v12] + 1;
		if ( v12 )
		{
			if ( v9 < v8 )
				CPrintString(widthb, (char *)v12, col);
		}
		widthb += fontkern[v13] + 1;
		v7 = *pszStr;
	}
}

//----- (0040610F) --------------------------------------------------------
void __fastcall MY_PlrStringXY(int x, int y, int width, char *pszStr, char col, int base)
{
	char *v6; // ebx
	unsigned char v7; // al
	int v8; // edx
	int v9; // esi
	char *v10; // edi
	unsigned char v11; // cl
	unsigned char v12; // al
	int v13; // edi
	int widtha; // [esp+Ch] [ebp-4h]
	int widthb; // [esp+Ch] [ebp-4h]
	int v16; // [esp+18h] [ebp+8h]

	v6 = pszStr;
	widtha = screen_y_times_768[y + 160] + x + 64;
	v7 = *pszStr;
	v8 = 0;
	v9 = width - x + 1;
	v16 = 0;
	v10 = pszStr;
	if ( *pszStr )
	{
		v11 = *pszStr;
		do
		{
			++v10;
			v8 += base + fontkern[fontframe[fontidx[v11]]];
			v11 = *v10;
		}
		while ( *v10 );
	}
	if ( v8 < v9 )
		v16 = (v9 - v8) >> 1;
	widthb = v16 + widtha;
	while ( v7 )
	{
		++v6;
		v12 = fontframe[fontidx[v7]];
		v13 = v12;
		v16 += base + fontkern[v12];
		if ( v12 )
		{
			if ( v16 < v9 )
				CPrintString(widthb, (char *)v12, col);
		}
		widthb += base + fontkern[v13];
		v7 = *v6;
	}
}

//----- (004061CA) --------------------------------------------------------
void __cdecl CheckLvlBtn()
{
	if ( !lvlbtndown && MouseX >= 40 && MouseX <= 81 && MouseY >= 313 && MouseY <= 335 )
		lvlbtndown = 1;
}
// 4B851C: using guessed type int lvlbtndown;

//----- (00406200) --------------------------------------------------------
void __cdecl ReleaseLvlBtn()
{
	if ( MouseX >= 40 && MouseX <= 81 && MouseY >= 313 && MouseY <= 335 )
		chrflag = 1;
	lvlbtndown = 0;
}
// 4B851C: using guessed type int lvlbtndown;

//----- (00406234) --------------------------------------------------------
void __cdecl DrawLevelUpIcon()
{
	int v0; // esi

	if ( !stextflag )
	{
		v0 = (lvlbtndown != 0) + 2;
		ADD_PlrStringXY(0, 303, 120, "Level Up", 0);
		Cel_decode(104, 495, pChrButtons, v0, 41);
	}
}
// 4B851C: using guessed type int lvlbtndown;
// 6AA705: using guessed type char stextflag;

//----- (0040627A) --------------------------------------------------------
void __cdecl CheckChrBtns()
{
	int v0; // esi
	int v1; // ecx
	int v2; // ebx
	int v3; // edi
	int v4; // edx
	bool v5; // sf
	unsigned char v6; // of
	int v7; // edx
	int v8; // edx
	int v9; // edx
	int v10; // eax
	int v11; // edx
	int v12; // edx

	v0 = 0;
	if ( !chrbtnactive )
	{
		v1 = myplr;
		if ( plr[myplr]._pStatPts )
		{
			v2 = MouseX;
			v3 = SLOBYTE(plr[v1]._pClass);
			while ( 1 )
			{
				if ( !v0 )
				{
					v9 = plr[v1]._pBaseStr;
					v6 = __OFSUB__(v9, MaxStats[v3][0]);
					v5 = v9 - MaxStats[v3][0] < 0;
					goto LABEL_12;
				}
				if ( v0 == 1 )
				{
					v8 = plr[v1]._pBaseMag;
					v6 = __OFSUB__(v8, MaxStats[v3][1]);
					v5 = v8 - MaxStats[v3][1] < 0;
					goto LABEL_12;
				}
				if ( v0 == 2 )
					break;
				if ( v0 == 3 )
				{
					v4 = plr[v1]._pBaseVit;
					v6 = __OFSUB__(v4, MaxStats[v3][3]);
					v5 = v4 - MaxStats[v3][3] < 0;
LABEL_12:
					if ( v5 ^ v6 )
					{
						v10 = v0;
						v11 = attribute_inc_rects[v0].x;
						if ( v2 >= v11 && v2 <= v11 + attribute_inc_rects[v10].w )
						{
							v12 = attribute_inc_rects[v10].y;
							if ( MouseY >= v12 && MouseY <= v12 + attribute_inc_rects[v10].h )
							{
								chrbtn[v0] = 1;
								chrbtnactive = 1;
							}
						}
					}
				}
				if ( ++v0 >= 4 )
					return;
			}
			v7 = plr[v1]._pBaseDex;
			v6 = __OFSUB__(v7, MaxStats[v3][2]);
			v5 = v7 - MaxStats[v3][2] < 0;
			goto LABEL_12;
		}
	}
}
// 4B87A8: using guessed type int chrbtnactive;

//----- (00406366) --------------------------------------------------------
void __cdecl ReleaseChrBtns()
{
	signed int v0; // esi
	int *v1; // eax
	signed int v2; // eax
	int v3; // ecx
	int v4; // ecx
	unsigned char v5; // dl

	chrbtnactive = 0;
	v0 = 0;
	do
	{
		v1 = &chrbtn[v0];
		if ( *v1 )
		{
			*v1 = 0;
			v2 = v0;
			v3 = attribute_inc_rects[v0].x;
			if ( MouseX >= v3 && MouseX <= v3 + attribute_inc_rects[v2].w )
			{
				v4 = attribute_inc_rects[v2].y;
				if ( MouseY >= v4 && MouseY <= v4 + attribute_inc_rects[v2].h )
				{
					if ( v0 )
					{
						switch ( v0 )
						{
							case ATTRIB_MAG:
								v5 = CMD_ADDMAG;
								break;
							case ATTRIB_DEX:
								v5 = CMD_ADDDEX;
								break;
							case ATTRIB_VIT:
								v5 = CMD_ADDVIT;
								break;
							default:
								goto LABEL_16;
						}
					}
					else
					{
						v5 = CMD_ADDSTR;
					}
					NetSendCmdParam1(1u, v5, 1u);
					--plr[myplr]._pStatPts;
				}
			}
		}
LABEL_16:
		++v0;
	}
	while ( v0 < 4 );
}
// 4B87A8: using guessed type int chrbtnactive;

//----- (00406408) --------------------------------------------------------
void __cdecl DrawDurIcon()
{
	int v0; // edx
	PlayerStruct *v1; // esi
	int v2; // eax
	int v3; // eax
	int v4; // eax

	if ( !chrflag && !questlog || !invflag && !sbookflag )
	{
		v0 = 656;
		if ( invflag || sbookflag )
			v0 = 336;
		v1 = &plr[myplr];
		v2 = DrawDurIcon4Item(v1->InvBody, v0, 4);
		v3 = DrawDurIcon4Item(&v1->InvBody[6], v2, 3);
		v4 = DrawDurIcon4Item(&v1->InvBody[4], v3, 0);
		DrawDurIcon4Item(&v1->InvBody[5], v4, 0);
	}
}
// 4B8968: using guessed type int sbookflag;
// 69BD04: using guessed type int questlog;

//----- (0040648E) --------------------------------------------------------
int __fastcall DrawDurIcon4Item(ItemStruct *pItem, int x, int c)
{
	int v3; // eax
	int v4; // edi
	int v5; // esi
	signed int v7; // edx
	int v8; // eax
	int v9; // eax
	int v10; // eax
	int v11; // eax
	signed int v12; // [esp-4h] [ebp-Ch]

	v3 = pItem->_itype;
	v4 = x;
	if ( v3 == -1 )
		return x;
	v5 = pItem->_iDurability;
	if ( v5 > 5 )
		return x;
	v7 = c;
	if ( !c )
	{
		if ( pItem->_iClass != 1 )
		{
			v7 = 1;
			goto LABEL_18;
		}
		v8 = v3 - 1;
		if ( !v8 )
		{
			v12 = 2;
			goto LABEL_15;
		}
		v9 = v8 - 1;
		if ( !v9 )
		{
			v12 = 6;
			goto LABEL_15;
		}
		v10 = v9 - 1;
		if ( !v10 )
		{
			v12 = 7;
			goto LABEL_15;
		}
		v11 = v10 - 1;
		if ( !v11 )
		{
			v12 = 5;
			goto LABEL_15;
		}
		if ( v11 == 6 )
		{
			v12 = 8;
LABEL_15:
			v7 = v12;
			goto LABEL_18;
		}
	}
LABEL_18:
	if ( v5 > 2 )
		v7 += 8;
	Cel_decode(v4, 495, pDurIcons, v7, 32);
	return v4 - 40;
}

//----- (00406508) --------------------------------------------------------
void __cdecl RedBack()
{
/*	int v0; // eax
	char *v1; // edi
	signed int v3; // edx
	signed int v4; // ecx
	char *v7; // edi
	signed int v9; // edx
	signed int v10; // ecx
	int v12; // [esp+8h] [ebp-4h]

	v0 = -(light4flag != 0);
	_LOWORD(v0) = v0 & 0xF400;
	v12 = v0 + 0x1200;
	if ( leveltype == 4 )
	{
		v7 = gpBuffer->row[0].pixels;
		_EBX = v12 + dword_646A20;
		v9 = 352;
		do
		{
			v10 = 640;
			do
			{
				_AL = *v7;
				if ( (unsigned char)*v7 >= 0x20u )
					__asm { xlat }
				*v7++ = _AL;
				--v10;
			}
			while ( v10 );
			v7 += 128;
			--v9;
		}
		while ( v9 );
	}
	else
	{
		v1 = gpBuffer->row[0].pixels;
		_EBX = v12 + dword_646A20;
		v3 = 352;
		do
		{
			v4 = 640;
			do
			{
				_AL = *v1;
				__asm { xlat }
				*v1++ = _AL;
				--v4;
			}
			while ( v4 );
			v1 += 128;
			--v3;
		}
		while ( v3 );
	}
*/
}
// 525728: using guessed type int light4flag;
// 5BB1ED: using guessed type char leveltype;

//----- (00406592) --------------------------------------------------------
int __fastcall GetSBookTrans(int ii, unsigned char townok)
{
	int v2; // edi
	int v3; // esi
	int result; // eax
	int v5; // eax
	char v6; // [esp+13h] [ebp-5h]
	int v7; // [esp+14h] [ebp-4h]

	v2 = ii;
	v7 = townok;
	v6 = 1;
	v3 = myplr;
	if ( ((unsigned __int64)(1i64 << ((unsigned char)ii - 1)) >> 32) & plr[v3]._pISpells[1] | (unsigned int)(1i64 << ((unsigned char)ii - 1)) & plr[v3]._pISpells[0] )
		v6 = 3;
	result = plr[v3]._pAblSpells[1] & (1 << (ii - 1) >> 31) | plr[v3]._pAblSpells[0] & (1 << (ii - 1));
	if ( result )
		v6 = 0;
	if ( v6 == 1 )
	{
		_LOBYTE(v5) = CheckSpell(myplr, ii, 1, 1);
		if ( !v5 )
			v6 = 4;
		result = 21720 * myplr;
		if ( (char)(plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v2]) <= 0 )
			v6 = 4;
	}
	if ( v7 && !currlevel && v6 != 4 && !*(_DWORD *)&spelldata[v2].sTownSpell )
		v6 = 4;
	_LOBYTE(result) = v6;
	return result;
}

//----- (00406667) --------------------------------------------------------
void __cdecl DrawSpellBook()
{
	int v0; // edi
	int v1; // ebp
	int v2; // esi
	char v3; // al
	int v4; // eax
	int v5; // ebx
	int v6; // ecx
	char v7; // [esp+Bh] [ebp-1Dh]
	int v8; // [esp+Ch] [ebp-1Ch]
	signed int v9; // [esp+10h] [ebp-18h]
	int sel; // [esp+14h] [ebp-14h]
	int v11; // [esp+18h] [ebp-10h]
	int v12; // [esp+1Ch] [ebp-Ch]

	Cel_decode(384, 511, pSpellBkCel, 1, 320);
	Cel_decode(76 * sbooktab + 391, 508, pSBkBtnCel, sbooktab + 1, 76);
	v9 = 1;
	v8 = 214;
	v0 = plr[myplr]._pISpells[0] | plr[myplr]._pMemSpells[0] | plr[myplr]._pAblSpells[0];
	v1 = plr[myplr]._pISpells[1] | plr[myplr]._pMemSpells[1] | plr[myplr]._pAblSpells[1];
	do
	{
		v2 = *(&attribute_inc_rects[3].h + v9 + 7 * sbooktab);
		if ( v2 != -1
		  && v1 & ((unsigned __int64)(1i64 << ((unsigned char)v2 - 1)) >> 32) | v0 & (unsigned int)(1i64 << ((unsigned char)v2 - 1)) )
		{
			v7 = GetSBookTrans(v2, 1u);
			SetSpellTrans(v7);
			DrawSpellCel(395, v8 + 1, (char *)pSBkIconCels, (char)SpellITbl[v2], 37);
			if ( v2 == plr[myplr]._pRSpell && v7 == _LOBYTE(plr[myplr]._pRSplType) )
			{
				SetSpellTrans(0);
				DrawSpellCel(395, v8 + 1, (char *)pSBkIconCels, 43, 37);
			}
			PrintSBookStr(10, v8 - 22, 0, spelldata[v2].sNameText, 0);
			v3 = GetSBookTrans(v2, 0);
			if ( v3 )
			{
				if ( v3 == 3 )
				{
					sprintf(tempstr, "Staff (%i charges)", plr[myplr].InvBody[4]._iCharges);
				}
				else
				{
					v4 = GetManaAmount(myplr, v2);
					v5 = v4 >> 6;
					v12 = v4 >> 6;
					GetDamageAmt(v2, &sel, &v11);
					if ( sel == -1 )
						sprintf(tempstr, "Mana: %i   Dam: n/a", v5);
					else
						sprintf(tempstr, "Mana: %i  Dam: %i - %i", v5, sel, v11);
					if ( v2 == SPL_BONESPIRIT )
						sprintf(tempstr, "Mana: %i  Dam: 1/3 tgt hp", v12);
					PrintSBookStr(10, v8, 0, tempstr, 0);
					v6 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[v2];
					if ( v6 < 0 )
						v6 = 0;
					if ( v6 )
						sprintf(tempstr, "Spell Level %i", v6);
					else
						sprintf(tempstr, "Spell Level 0 - Unusable");
				}
			}
			else
			{
				strcpy(tempstr, "Skill");
			}
			PrintSBookStr(10, v8 - 11, 0, tempstr, 0);
		}
		v8 += 43;
		++v9;
	}
	while ( v9 < 8 );
}
// 4B8950: using guessed type int sbooktab;

//----- (004068F4) --------------------------------------------------------
void __fastcall PrintSBookStr(int x, int y, bool cjustflag, char *pszStr, int bright)
{
	char *v5; // ebx
	signed int v6; // eax
	int v7; // edi
	unsigned char v8; // cl
	char *v9; // esi
	unsigned char v10; // al
	int v11; // esi
	unsigned char v12; // al
	int width; // [esp+Ch] [ebp-4h]

	v5 = pszStr;
	width = screen_y_times_768[y] + x + 440;
	v6 = 0;
	v7 = 0;
	if ( cjustflag )
	{
		v8 = *pszStr;
		v9 = pszStr;
		if ( !*pszStr )
			goto LABEL_14;
		do
		{
			++v9;
			v6 += fontkern[fontframe[fontidx[v8]]] + 1;
			v8 = *v9;
		}
		while ( *v9 );
		if ( v6 < 222 )
LABEL_14:
			v7 = (222 - v6) >> 1;
		width += v7;
	}
	while ( 1 )
	{
		v12 = *v5;
		if ( !*v5 )
			break;
		++v5;
		v10 = fontframe[fontidx[v12]];
		v11 = v10;
		v7 += fontkern[v10] + 1;
		if ( v10 )
		{
			if ( v7 <= 222 )
				CPrintString(width, (char *)v10, bright);
		}
		width += fontkern[v11] + 1;
	}
}

//----- (004069B6) --------------------------------------------------------
void __cdecl CheckSBook()
{
	signed int v0; // ecx
	signed int v1; // esi
	spell_id v2; // eax
	int v3; // esi
	signed __int64 v4; // rax
	char v5; // cl
	__int64 v6; // [esp+8h] [ebp-10h]
	int v7; // [esp+10h] [ebp-8h]

	v0 = MouseY;
	v1 = MouseX;
	if ( MouseX >= 331 && MouseX < 368 && MouseY >= 18 && MouseY < 314 )
	{
		v2 = SpellPages[0][7 * sbooktab + (MouseY - 18) / 43];
		v7 = SpellPages[0][7 * sbooktab + (MouseY - 18) / 43];
		if ( v2 != -1 )
		{
			v3 = myplr;
			LODWORD(v6) = plr[myplr]._pAblSpells[0];
			HIDWORD(v6) = plr[myplr]._pAblSpells[1];
			v4 = 1i64 << ((unsigned char)v2 - 1);
			if ( HIDWORD(v4) & (HIDWORD(v6) | plr[myplr]._pISpells[1] | plr[myplr]._pMemSpells[1]) | (unsigned int)v4 & ((unsigned int)v6 | plr[myplr]._pISpells[0] | plr[myplr]._pMemSpells[0]) )
			{
				v5 = 3;
				if ( !(plr[v3]._pISpells[1] & HIDWORD(v4) | plr[v3]._pISpells[0] & (unsigned int)v4) )
					v5 = 1;
				if ( v6 & v4 )
					v5 = 0;
				force_redraw = 255;
				plr[v3]._pRSpell = v7;
				_LOBYTE(plr[v3]._pRSplType) = v5;
			}
			v1 = MouseX;
			v0 = MouseY;
		}
	}
	if ( v1 >= 327 && v1 < 633 && v0 >= 320 && v0 < 349 )
		sbooktab = (v1 - 327) / 76;
}
// 4B8950: using guessed type int sbooktab;
// 52571C: using guessed type int force_redraw;

//----- (00406AF8) --------------------------------------------------------
char *__fastcall get_pieces_str(int nGold)
{
	char *result; // eax

	result = "piece";
	if ( nGold != 1 )
		result = "pieces";
	return result;
}

//----- (00406B08) --------------------------------------------------------
void __fastcall DrawGoldSplit(int amount)
{
	int v1; // ebp
	char *v2; // eax
	char v3; // cl
	signed int i; // eax
	int screen_x; // [esp+10h] [ebp-4h]
	int screen_xa; // [esp+10h] [ebp-4h]

	screen_x = 0;
	v1 = amount;
	Cel_decode(415, 338, pGBoxBuff, 1, 261);
	sprintf(tempstr, "You have %u gold", initialDropGoldValue);
	ADD_PlrStringXY(366, 87, 600, tempstr, 3);
	v2 = get_pieces_str(initialDropGoldValue);
	sprintf(tempstr, "%s.  How many do", v2);
	ADD_PlrStringXY(366, 103, 600, tempstr, 3);
	ADD_PlrStringXY(366, 121, 600, "you want to remove?", 3);
	if ( v1 <= 0 )
	{
		screen_xa = 450;
	}
	else
	{
		sprintf(tempstr, "%u", v1);
		PrintGameStr(388, 140, tempstr, 0);
		v3 = tempstr[0];
		for ( i = 0; i < v3; v3 = tempstr[i] )
		{
			++i;
			screen_x += fontkern[fontframe[fontidx[(unsigned char)v3]]] + 1;
		}
		screen_xa = screen_x + 452;
	}
	Cel_decode(screen_xa, 300, pCelBuff, frame_4B8800, 12);
	frame_4B8800 = (frame_4B8800 & 7) + 1;
}

//----- (00406C40) --------------------------------------------------------
void __fastcall control_drop_gold(int a1)
{
	char v1; // bl
	int v2; // eax
	int v3; // eax
	size_t v4; // esi
	char v5; // [esp+7h] [ebp-9h]
	char v6[8]; // [esp+8h] [ebp-8h]

	v1 = a1;
	if ( (signed int)(plr[myplr]._pHitPoints & 0xFFFFFFC0) <= 0 )
	{
		dropGoldFlag = 0;
		dropGoldValue = 0;
		return;
	}
	memset(v6, 0, 6u);
	_itoa(dropGoldValue, v6, 10);
	if ( v1 != 13 )
	{
		if ( v1 == 27 )
		{
			dropGoldFlag = 0;
			dropGoldValue = 0;
			return;
		}
		if ( v1 == 8 )
		{
			*(&v5 + strlen(v6)) = 0;
			v2 = atoi(v6);
		}
		else
		{
			v3 = v1 - 48;
			if ( v3 < 0 || v3 > 9 )
				return;
			if ( dropGoldValue || atoi(v6) <= initialDropGoldValue )
			{
				v6[strlen(v6)] = v1;
				if ( atoi(v6) > initialDropGoldValue )
					return;
				v4 = strlen(v6);
				if ( v4 > strlen(v6) )
					return;
			}
			else
			{
				v6[0] = v1;
			}
			v2 = atoi(v6);
		}
		dropGoldValue = v2;
		return;
	}
	if ( dropGoldValue > 0 )
		control_remove_gold(myplr, initialDropGoldIndex);
	dropGoldFlag = 0;
}
// 4B84DC: using guessed type int dropGoldFlag;
// 406C40: using guessed type char var_8[8];

//----- (00406D6E) --------------------------------------------------------
void __fastcall control_remove_gold(int pnum, int gold_index)
{
	int v2; // edi
	int v3; // esi
	int v4; // edx
	_DWORD *v5; // eax
	int v6; // edx
	_DWORD *v7; // eax
	int v8; // eax

	v2 = pnum;
	v3 = pnum;
	if ( gold_index > 46 )
	{
		v6 = gold_index - 47;
		v7 = (unsigned int *)((char *)&plr[0].SpdList[v6]._ivalue + v3 * 21720);
		*v7 -= dropGoldValue;
		if ( *v7 <= 0 )
			RemoveSpdBarItem(pnum, v6);
		else
			SetSpdbarGoldCurs(pnum, v6);
	}
	else
	{
		v4 = gold_index - 7;
		v5 = (unsigned int *)((char *)&plr[0].InvList[v4]._ivalue + v3 * 21720);
		*v5 -= dropGoldValue;
		if ( *v5 <= 0 )
			RemoveInvItem(pnum, v4);
		else
			SetGoldCurs(pnum, v4);
	}
	SetPlrHandItem(&plr[v3].HoldItem, 0);
	GetGoldSeed(v2, &plr[v3].HoldItem._iSeed);
	plr[v3].HoldItem._ivalue = dropGoldValue;
	plr[v3].HoldItem._iStatFlag = 1;
	control_set_gold_curs(v2);
	v8 = CalculateGold(v2);
	dropGoldValue = 0;
	plr[v3]._pGold = v8;
}

//----- (00406E24) --------------------------------------------------------
void __fastcall control_set_gold_curs(int pnum)
{
	int v1; // ecx
	int v2; // eax
	int *v3; // eax
	bool v4; // zf
	bool v5; // sf
	unsigned char v6; // of

	v1 = pnum;
	v2 = plr[v1].HoldItem._ivalue;
	if ( v2 < 2500 )
	{
		v6 = __OFSUB__(v2, 1000);
		v4 = v2 == 1000;
		v5 = v2 - 1000 < 0;
		v3 = &plr[v1].HoldItem._iCurs;
		if ( (unsigned char)(v5 ^ v6) | v4 )
			*v3 = 4;
		else
			*v3 = 5;
	}
	else
	{
		v3 = &plr[v1].HoldItem._iCurs;
		plr[v1].HoldItem._iCurs = 6;
	}
	SetCursor(*v3 + 12);
}

//----- (00406E6A) --------------------------------------------------------
void __cdecl DrawTalkPan()
{
	int v0; // esi
	signed int v1; // edi
	signed int v2; // esi
	char *v3; // eax
	int v4; // esi
	int v5; // esi
	int v6; // ebx
	int v7; // eax
	int a4; // [esp+4h] [ebp-Ch]
	char *a1; // [esp+8h] [ebp-8h]
	int v10; // [esp+Ch] [ebp-4h]

	v0 = 0;
	if ( talkflag )
	{
		DrawPanelBox(175, sgbPlrTalkTbl + 20, 0x126u, 5u, 239, 516);
		v1 = 293;
		do
		{
			DrawPanelBox((v0 >> 1) + 175, sgbPlrTalkTbl + v0 + 25, v1, 1u, (v0 >> 1) + 239, v0 + 521);
			++v0;
			--v1;
		}
		while ( v1 > 283 );
		DrawPanelBox(185, sgbPlrTalkTbl + 35, 0x112u, 0x1Eu, 249, 531);
		DrawPanelBox(180, sgbPlrTalkTbl + 65, 0x11Cu, 5u, 244, 561);
		v2 = 0;
		do
		{
			DrawPanelBox(180, sgbPlrTalkTbl + v2 + 70, v2 + 284, 1u, 244, v2 + 566);
			++v2;
		}
		while ( v2 < 10 );
		DrawPanelBox(170, sgbPlrTalkTbl + 80, 0x136u, 0x37u, 234, 576);
		v3 = sgszTalkMsg;
		v4 = 0;
		do
		{
			control_print_talk_msg(v3, 0, v4, &a4, 0);
			if ( !v3 )
				goto LABEL_10;
			v4 += 13;
		}
		while ( v4 < 39 );
		*v3 = 0;
LABEL_10:
		Cel_into_buf((char *)gpBuffer + a4, (char *)pCelBuff, frame, 12);
		v5 = 0;
		a1 = plr[0]._pName;
		v10 = 0;
		frame = (frame & 7) + 1;
		while ( v10 == myplr )
		{
LABEL_21:
			a1 += 21720;
			++v10;
			if ( (signed int)a1 >= (signed int)&plr_msgs[1].msg[115] )
				return;
		}
		if ( tempstr[v10 + 256] )
		{
			v6 = 3;
			if ( !talkbtndown[v5] )
			{
LABEL_18:
				if ( *(a1 - 291) )
					control_print_talk_msg(a1, 46, 18 * v5 + 60, &a4, v6);
				++v5;
				goto LABEL_21;
			}
			v7 = (v5 != 0) + 3;
		}
		else
		{
			v7 = (v5 != 0) + 1;
			v6 = 2;
			if ( talkbtndown[v5] )
				v7 = (v5 != 0) + 5;
		}
		Cel_decode(236, 18 * v5 + 596, pTalkBtns, v7, 61);
		goto LABEL_18;
	}
}
// 4B8840: using guessed type int sgbPlrTalkTbl;
// 4B8960: using guessed type int talkflag;

//----- (00407071) --------------------------------------------------------
void __fastcall control_print_talk_msg(char *msg, int x, int y, int *a4, int just)
{
	int v5; // edx
	char *v6; // ebx
	unsigned char v7; // al
	int v8; // ecx
	unsigned char v9; // dl
	int v10; // edi
	int a3; // [esp+14h] [ebp+8h]

	v5 = x + 264;
	v6 = msg;
	*a4 = v5 + screen_y_times_768[y + 534];
	v7 = *msg;
	v8 = v5;
	if ( v7 )
	{
		while ( 1 )
		{
			v9 = fontframe[fontidx[v7]];
			v10 = v9;
			a3 = v8 + fontkern[v9] + 1;
			if ( a3 > 514 )
				break;
			++v6;
			if ( v9 )
				CPrintString(*a4, (char *)v9, just);
			*a4 += fontkern[v10] + 1;
			v7 = *v6;
			if ( !*v6 )
				break;
			v8 = a3;
		}
	}
}

//----- (004070F3) --------------------------------------------------------
int __cdecl control_check_talk_btn()
{
	int v0; // ecx
	int result; // eax

	if ( !talkflag )
		return 0;
	if ( MouseX < 172 )
		return 0;
	v0 = MouseY;
	if ( MouseY < 421 || MouseX > 233 )
		return 0;
	result = 0;
	if ( MouseY <= 475 )
	{
		talkbtndown[0] = 0;
		talkbtndown[1] = 0;
		talkbtndown[2] = 0;
		talkbtndown[(v0 - 421) / 18] = 1;
		result = 1;
	}
	return result;
}
// 4B8960: using guessed type int talkflag;

//----- (0040714D) --------------------------------------------------------
void __cdecl control_release_talk_btn()
{
	signed int v0; // ecx
	int v1; // eax
	signed int v2; // ecx

	if ( talkflag )
	{
		v0 = MouseX;
		talkbtndown[0] = 0;
		talkbtndown[1] = 0;
		talkbtndown[2] = 0;
		if ( v0 >= 172 && MouseY >= 421 && v0 <= 233 && MouseY <= 475 )
		{
			v1 = (MouseY - 421) / 18;
			v2 = 0;
			do
			{
				if ( v1 == -1 )
					break;
				if ( v2 != myplr )
					--v1;
				++v2;
			}
			while ( v2 < 4 );
			if ( v2 <= 4 )
				tempstr[v2 + 255] = tempstr[v2 + 255] == 0;
		}
	}
}
// 4B8960: using guessed type int talkflag;

//----- (004071C0) --------------------------------------------------------
void __cdecl control_reset_talk_msg()
{
	int v0; // edi
	signed int v1; // ecx

	v0 = 0;
	v1 = 0;
	do
	{
		if ( tempstr[v1 + 256] )
			v0 |= 1 << v1;
		++v1;
	}
	while ( v1 < 4 );
	if ( !msgcmd_check_set_event((int)sgszTalkMsg) )
		msg_init_msg(v0, sgszTalkMsg);
}

//----- (004071FA) --------------------------------------------------------
void __cdecl control_type_message()
{
	if ( gbMaxPlayers != 1 )
	{
		sgszTalkMsg[0] = 0;
		talkflag = 1;
		frame = 1;
		talkbtndown[0] = 0;
		talkbtndown[1] = 0;
		talkbtndown[2] = 0;
		sgbPlrTalkTbl = 144;
		force_redraw = 255;
		sgbTalkSavePos = sgbNextTalkSave;
	}
}
// 4B84CC: using guessed type char sgbNextTalkSave;
// 4B84CD: using guessed type char sgbTalkSavePos;
// 4B8840: using guessed type int sgbPlrTalkTbl;
// 4B8960: using guessed type int talkflag;
// 52571C: using guessed type int force_redraw;
// 679660: using guessed type char gbMaxPlayers;

//----- (00407241) --------------------------------------------------------
void __cdecl control_reset_talk()
{
	talkflag = 0;
	sgbPlrTalkTbl = 0;
	force_redraw = 255;
}
// 4B8840: using guessed type int sgbPlrTalkTbl;
// 4B8960: using guessed type int talkflag;
// 52571C: using guessed type int force_redraw;

//----- (0040725A) --------------------------------------------------------
int __fastcall control_talk_last_key(int a1)
{
	char v1; // bl
	signed int v3; // eax

	v1 = a1;
	if ( gbMaxPlayers == 1 || !talkflag || (unsigned int)a1 < 0x20 )
		return 0;
	v3 = strlen(sgszTalkMsg);
	if ( v3 < 78 )
	{
		sgszTalkMsg[v3 + 1] = 0;
		sgszTalkMsg[v3] = v1;
	}
	return 1;
}
// 4B8960: using guessed type int talkflag;
// 679660: using guessed type char gbMaxPlayers;

//----- (0040729A) --------------------------------------------------------
int __fastcall control_presskeys(int a1)
{
	signed int v1; // eax
	char v2; // cl

	if ( gbMaxPlayers != 1 && talkflag )
	{
		switch ( a1 )
		{
			case VK_SPACE:
				return 1;
			case VK_ESCAPE:
				control_reset_talk();
				return 1;
			case VK_RETURN:
				control_press_enter();
				return 1;
			case VK_BACK:
				v1 = strlen(sgszTalkMsg);
				if ( v1 > 0 )
					*((_BYTE *)&chrbtnactive + v1 + 3) = 0;
				return 1;
			case VK_DOWN:
				v2 = 1;
LABEL_15:
				control_up_down(v2);
				return 1;
			case VK_UP:
				v2 = -1;
				goto LABEL_15;
		}
	}
	return 0;
}
// 4B87A8: using guessed type int chrbtnactive;
// 4B8960: using guessed type int talkflag;
// 679660: using guessed type char gbMaxPlayers;

//----- (00407304) --------------------------------------------------------
void __cdecl control_press_enter()
{
	signed int v0; // esi
	char (*v1)[80]; // ebp
	char v2; // al
	int v3; // ecx
	char *v4; // ebp

	if ( sgszTalkMsg[0] )
	{
		control_reset_talk_msg();
		v0 = 0;
		v1 = sgszTalkSave;
		do
		{
			if ( !strcmp((const char *)v1, sgszTalkMsg) )
				break;
			++v1;
			++v0;
		}
		while ( (signed int)v1 < (signed int)&dropGoldValue );
		if ( v0 < 8 )
		{
			v2 = sgbNextTalkSave;
			v3 = (sgbNextTalkSave - 1) & 7;
			if ( v0 != v3 )
			{
				v4 = sgszTalkSave[v3];
				strcpy(sgszTalkSave[v0], sgszTalkSave[v3]);
				strcpy(v4, sgszTalkMsg);
				v2 = sgbNextTalkSave;
			}
		}
		else
		{
			strcpy(sgszTalkSave[(unsigned char)sgbNextTalkSave], sgszTalkMsg);
			v2 = (sgbNextTalkSave + 1) & 7;
			sgbNextTalkSave = (sgbNextTalkSave + 1) & 7;
		}
		sgszTalkMsg[0] = 0;
		sgbTalkSavePos = v2;
	}
	control_reset_talk();
}
// 4B84CC: using guessed type char sgbNextTalkSave;
// 4B84CD: using guessed type char sgbTalkSavePos;

//----- (004073C2) --------------------------------------------------------
void __fastcall control_up_down(char a1)
{
	unsigned char v1; // al
	int v2; // esi

	v1 = sgbTalkSavePos;
	v2 = 0;
	while ( 1 )
	{
		v1 = (a1 + v1) & 7;
		sgbTalkSavePos = v1;
		if ( sgszTalkSave[v1][0] )
			break;
		if ( ++v2 >= 8 )
			return;
	}
	strcpy(sgszTalkMsg, sgszTalkSave[v1]);
}
// 4B84CD: using guessed type char sgbTalkSavePos;

//----- (0040740A) --------------------------------------------------------
void __cdecl InitCursor()
{
	pCursCels = LoadFileInMem("Data\\Inv\\Objcurs.CEL", 0);
	ClearCursor();
}

//----- (00407420) --------------------------------------------------------
void __cdecl FreeCursor()
{
	void *v0; // ecx

	v0 = pCursCels;
	pCursCels = 0;
	mem_free_dbg(v0);
	ClearCursor();
}

//----- (00407437) --------------------------------------------------------
void __fastcall SetICursor(int i)
{
	int v1; // ecx

	v1 = i;
	icursW = InvItemWidth[v1];
	icursH = InvItemHeight[v1];
	icursW28 = icursW / 28;
	icursH28 = icursH / 28;
}
// 4B8CB4: using guessed type int icursH;
// 4B8CBC: using guessed type int icursW;

//----- (0040746B) --------------------------------------------------------
void __fastcall SetCursor(int i)
{
	int v1; // eax

	v1 = InvItemWidth[i];
	pcurs = i;
	cursW = v1;
	cursH = InvItemHeight[i];
	SetICursor(i);
}
// 4B8C9C: using guessed type int cursH;

//----- (00407493) --------------------------------------------------------
void __cdecl InitLevelCursor()
{
	SetCursor(1);
	cursmx = ViewX;
	cursmy = ViewY;
	dword_4B8CCC = -1;
	*(_DWORD *)&pcursmonst = -1;
	pcursobj = -1;
	pcursitem = -1;
	pcursplr = -1;
	ClearCursor();
}
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC1: using guessed type char pcursobj;
// 4B8CC2: using guessed type char pcursplr;
// 4B8CCC: using guessed type int dword_4B8CCC;

//----- (004074D0) --------------------------------------------------------
void __cdecl CheckTown()
{
	int v0; // ecx
	int v1; // eax
	int v2; // esi
	int v3; // edx
	int v4; // ebx
	int v5; // [esp+0h] [ebp-4h]

	v5 = 0;
	if ( nummissiles > 0 )
	{
		v0 = cursmx;
		v1 = cursmy;
		do
		{
			v2 = missileactive[v5];
			if ( missile[v2]._mitype == 10 )
			{
				if ( (v3 = missile[v2]._mix, v4 = v3 - 1, v0 == v3 - 1) && v1 == missile[v2]._miy
				  || v0 == v3 && v1 == missile[v2]._miy - 1
				  || v0 == v4 && v1 == missile[v2]._miy - 1
				  || v0 == v3 - 2 && (v1 == missile[v2]._miy - 1 || v0 == v3 - 2 && v1 == missile[v2]._miy - 2)
				  || v0 == v4 && v1 == missile[v2]._miy - 2
				  || v0 == v3 && v1 == missile[v2]._miy )
				{
					trigflag[3] = 1;
					ClearPanel();
					strcpy(infostr, "Town Portal");
					sprintf(tempstr, "from %s", plr[missile[v2]._misource]._pName);
					AddPanelString(tempstr, 1);
					v0 = missile[v2]._mix;
					v1 = missile[v2]._miy;
					cursmx = missile[v2]._mix;
					cursmy = v1;
				}
			}
			++v5;
		}
		while ( v5 < nummissiles );
	}
}

//----- (004075FD) --------------------------------------------------------
void __cdecl CheckRportal()
{
	int v0; // ecx
	int v1; // eax
	int v2; // esi
	int v3; // edx
	int v4; // ebx
	int v5; // [esp+0h] [ebp-4h]

	v5 = 0;
	if ( nummissiles > 0 )
	{
		v0 = cursmx;
		v1 = cursmy;
		do
		{
			v2 = missileactive[v5];
			if ( missile[v2]._mitype == 65 )
			{
				if ( (v3 = missile[v2]._mix, v4 = v3 - 1, v0 == v3 - 1) && v1 == missile[v2]._miy
				  || v0 == v3 && v1 == missile[v2]._miy - 1
				  || v0 == v4 && v1 == missile[v2]._miy - 1
				  || v0 == v3 - 2 && (v1 == missile[v2]._miy - 1 || v0 == v3 - 2 && v1 == missile[v2]._miy - 2)
				  || v0 == v4 && v1 == missile[v2]._miy - 2
				  || v0 == v3 && v1 == missile[v2]._miy )
				{
					trigflag[3] = 1;
					ClearPanel();
					strcpy(infostr, "Portal to");
					if ( setlevel )
						strcpy(tempstr, "level 15");
					else
						strcpy(tempstr, "The Unholy Altar");
					AddPanelString(tempstr, 1);
					v0 = missile[v2]._mix;
					v1 = missile[v2]._miy;
					cursmx = missile[v2]._mix;
					cursmy = v1;
				}
			}
			++v5;
		}
		while ( v5 < nummissiles );
	}
}
// 5CF31D: using guessed type char setlevel;

//----- (00407729) --------------------------------------------------------
void __cdecl CheckCursMove()
{
	int v0; // esi
	signed int v1; // edi
	int v2; // esi
	int v3; // edi
	int v4; // edx
	int v5; // ebx
	int v6; // edi
	int v7; // eax
	int v8; // esi
	BOOL v9; // eax
	int v10; // ecx
	int v11; // edx
	int v12; // ecx
	int v13; // ebx
	int v14; // ebx
	int v15; // eax
	bool v16; // zf
	int v17; // ecx
	int v18; // eax
	int v19; // ecx
	int v20; // eax
	int v21; // ecx
	int v22; // eax
	int v23; // eax
	int v24; // ecx
	int v25; // eax
	int v26; // ecx
	int v27; // ebx
	int v28; // edx
	int v29; // eax
	int v30; // ecx
	int v31; // eax
	int v32; // eax
	int v33; // eax
	int v34; // ecx
	int v35; // eax
	int v36; // ecx
	int v37; // eax
	int v38; // eax
	int v39; // ecx
	int v40; // eax
	int v41; // ecx
	signed int v42; // eax
	int v43; // ecx
	int v44; // eax
	int v45; // eax
	int v46; // eax
	int v47; // eax
	char v48; // al
	char v49; // cl
	char v50; // al
	char v51; // al
	char v52; // cl
	int v53; // ecx
	int *v54; // eax
	int v55; // edx
	int *v56; // ecx
	char v57; // al
	char v58; // cl
	signed int v59; // edx
	char v60; // al
	char v61; // cl
	char v62; // al
	char v63; // al
	char v64; // cl
	char v65; // al
	char v66; // al
	char v67; // cl
	char v68; // al
	char v69; // al
	char v70; // al
	char v71; // al
	char v72; // al
	char v73; // cl
	char v74; // al
	char v75; // al
	int v76; // [esp+Ch] [ebp-18h]
	char *v77; // [esp+Ch] [ebp-18h]
	int v78; // [esp+10h] [ebp-14h]
	signed int v79; // [esp+14h] [ebp-10h]
	signed int v80; // [esp+18h] [ebp-Ch]
	int v81; // [esp+1Ch] [ebp-8h]
	int v82; // [esp+1Ch] [ebp-8h]
	signed int v83; // [esp+20h] [ebp-4h]

	v0 = MouseX;
	v1 = MouseY;
	if ( chrflag || questlog )
	{
		if ( MouseX >= 160 )
		{
			v0 = MouseX - 160;
			goto LABEL_10;
		}
		goto LABEL_9;
	}
	if ( invflag || sbookflag )
	{
		if ( MouseX <= 320 )
		{
			v0 = MouseX + 160;
			goto LABEL_10;
		}
LABEL_9:
		v0 = 0;
	}
LABEL_10:
	if ( MouseY > 351 && track_isscrolling() )
		v1 = 351;
	if ( !zoomflag )
	{
		v0 >>= 1;
		v1 >>= 1;
	}
	v2 = v0 - ScrollInfo._sxoff;
	v3 = v1 - ScrollInfo._syoff;
	if ( ScrollInfo._sdir )
	{
		v2 += ((plr[myplr]._pVar6 + plr[myplr]._pxvel) >> 8) - (plr[myplr]._pVar6 >> 8);
		v3 += ((plr[myplr]._pVar7 + plr[myplr]._pyvel) >> 8) - (plr[myplr]._pVar7 >> 8);
	}
	if ( v2 < 0 )
		v2 = 0;
	if ( v2 >= 640 )
		v2 = 640;
	if ( v3 < 0 )
		v3 = 0;
	if ( v3 >= 480 )
		v3 = 480;
	v4 = v3 >> 5;
	v5 = v3 & 0x1F;
	v76 = v2 & 0x3F;
	v6 = (v2 >> 6) + (v3 >> 5) + ViewX - (zoomflag != 0 ? 10 : 5);
	v7 = v76 >> 1;
	v8 = v4 + ViewY - (v2 >> 6);
	if ( v5 < v76 >> 1 )
		--v8;
	v9 = v5 >= 32 - v7;
	if ( v9 )
		++v6;
	if ( v6 < 0 )
		v6 = 0;
	if ( v6 >= 112 )
		v6 = 111;
	if ( v8 < 0 )
		v8 = 0;
	if ( v8 >= 112 )
		v8 = 111;
	if ( v5 >= v76 >> 1 )
	{
		if ( !v9 )
			goto LABEL_49;
		goto LABEL_48;
	}
	if ( !v9 )
	{
LABEL_48:
		if ( v76 < 32 )
			goto LABEL_39;
LABEL_49:
		v83 = 0;
		goto LABEL_40;
	}
LABEL_39:
	v83 = 1;
LABEL_40:
	v10 = *(_DWORD *)&pcursmonst;
	pcursobj = -1;
	pcursitem = -1;
	v11 = -1;
	dword_4B8CCC = *(_DWORD *)&pcursmonst;
	*(_DWORD *)&pcursmonst = -1;
	if ( pcursinvitem != -1 )
		drawsbarflag = 1;
	pcursinvitem = -1;
	pcursplr = -1;
	v16 = plr[myplr]._pInvincible == 0;
	uitemflag = 0;
	panelflag = 0;
	trigflag[3] = 0;
	if ( !v16 )
		return;
	if ( pcurs >= CURSOR_FIRSTITEM || spselflag )
	{
		cursmx = v6;
		cursmy = v8;
		return;
	}
	if ( MouseY > 352 )
	{
		CheckPanelInfo();
		return;
	}
	if ( doomflag )
		return;
	if ( invflag && MouseX > 320 )
	{
		pcursinvitem = CheckInvHLight();
		return;
	}
	if ( sbookflag && MouseX > 320 || (chrflag || questlog) && MouseX < 320 )
		return;
	if ( !leveltype )
	{
		if ( v83 )
		{
			v27 = 112 * v6;
			v78 = 112 * v6;
			v43 = 112 * v6 + v8;
			v45 = dMonster[0][v43 + 1];
			if ( v45 <= 0 )
				goto LABEL_200;
			v11 = v45 - 1;
			cursmx = v6;
			cursmy = v8 + 1;
		}
		else
		{
			v27 = 112 * v6;
			v78 = 112 * v6;
			v43 = 112 * v6 + v8;
			v44 = dMonster[1][v43];
			if ( v44 <= 0 )
				goto LABEL_200;
			v11 = v44 - 1;
			cursmx = v6 + 1;
			cursmy = v8;
		}
		*(_DWORD *)&pcursmonst = v11;
LABEL_200:
		v46 = dMonster[0][v43];
		if ( v46 > 0 )
		{
			v11 = v46 - 1;
			cursmx = v6;
			*(_DWORD *)&pcursmonst = v46 - 1;
			cursmy = v8;
		}
		v47 = dMonster[1][v43 + 1];
		if ( v47 > 0 )
		{
			v11 = v47 - 1;
			cursmx = v6 + 1;
			*(_DWORD *)&pcursmonst = v47 - 1;
			cursmy = v8 + 1;
		}
		if ( !towner[v11]._tSelFlag )
LABEL_205:
			*(_DWORD *)&pcursmonst = -1;
LABEL_206:
		if ( *(_DWORD *)&pcursmonst != -1 )
		{
LABEL_305:
			v59 = *(_DWORD *)&pcursmonst;
			goto LABEL_306;
		}
LABEL_207:
		if ( v83 )
		{
			v50 = dPlayer[0][v27 + 1 + v8];
			if ( v50 )
			{
				v49 = v50 <= 0 ? -1 - v50 : v50 - 1;
				if ( v49 != myplr && plr[v49]._pHitPoints )
				{
					cursmx = v6;
					cursmy = v8 + 1;
					goto LABEL_222;
				}
			}
		}
		else
		{
			v48 = dPlayer[1][v27 + v8];
			if ( v48 )
			{
				v49 = v48 <= 0 ? -1 - v48 : v48 - 1;
				if ( v49 != myplr && plr[v49]._pHitPoints )
				{
					cursmy = v8;
					cursmx = v6 + 1;
LABEL_222:
					pcursplr = v49;
					goto LABEL_223;
				}
			}
		}
LABEL_223:
		v51 = dPlayer[0][v27 + v8];
		if ( v51 )
		{
			v52 = v51 <= 0 ? -1 - v51 : v51 - 1;
			if ( v52 != myplr )
			{
				cursmx = v6;
				cursmy = v8;
				pcursplr = v52;
			}
		}
		if ( dFlags[0][v27 + v8] & 4 )
		{
			v53 = 0;
			v54 = &plr[0].WorldY;
			do
			{
				if ( *(v54 - 1) == v6 && *v54 == v8 && v53 != myplr )
				{
					cursmx = v6;
					cursmy = v8;
					pcursplr = v53;
				}
				v54 += 5430;
				++v53;
			}
			while ( (signed int)v54 < (signed int)&plr_msgs[0].msg[7] );
		}
		if ( pcurs == CURSOR_RESURRECT )
		{
			v79 = -1;
			v77 = &nBlockTable[v27 + 1944 + v8];
			do
			{
				v80 = -1;
				v55 = v8 - 1;
				do
				{
					if ( v77[v80] & 4 )
					{
						v82 = 0;
						v56 = &plr[0].WorldY;
						do
						{
							if ( *(v56 - 1) == v6 + v79 && *v56 == v55 && v82 != myplr )
							{
								cursmx = v6 + v79;
								cursmy = v55;
								pcursplr = v82;
							}
							++v82;
							v56 += 5430;
						}
						while ( (signed int)v56 < (signed int)&plr_msgs[0].msg[7] );
					}
					++v80;
					++v55;
				}
				while ( v80 < 2 );
				++v79;
				v77 += 112;
			}
			while ( v79 < 2 );
			v27 = v78;
		}
		v57 = dPlayer[1][v27 + 1 + v8];
		if ( v57 )
		{
			v58 = v57 <= 0 ? -1 - v57 : v57 - 1;
			if ( v58 != myplr && plr[v58]._pHitPoints )
			{
				pcursplr = v58;
				cursmx = v6 + 1;
				cursmy = v8 + 1;
			}
		}
		v59 = *(_DWORD *)&pcursmonst;
		if ( *(_DWORD *)&pcursmonst != -1 )
		{
LABEL_285:
			if ( pcursplr == -1 )
				goto LABEL_286;
LABEL_306:
			if ( pcurs == CURSOR_IDENTIFY )
			{
				pcursobj = -1;
				v59 = -1;
				pcursitem = -1;
				*(_DWORD *)&pcursmonst = -1;
				cursmx = v6;
				cursmy = v8;
			}
			if ( v59 != -1 )
			{
				if ( monster[v59]._mFlags & 0x20 )
					*(_DWORD *)&pcursmonst = -1;
			}
			return;
		}
		if ( pcursplr != (_BYTE)pcursmonst )
			goto LABEL_306;
		if ( v83 )
		{
			v62 = dObject[0][v27 + 1 + v8];
			if ( !v62 )
				goto LABEL_272;
			v61 = v62 <= 0 ? -1 - v62 : v62 - 1;
			if ( SLOBYTE(object[v61]._oSelFlag) < 2 )
				goto LABEL_272;
			cursmx = v6;
			cursmy = v8 + 1;
		}
		else
		{
			v60 = dObject[1][v27 + v8];
			if ( !v60 )
				goto LABEL_272;
			v61 = v60 <= 0 ? -1 - v60 : v60 - 1;
			if ( SLOBYTE(object[v61]._oSelFlag) < 2 )
				goto LABEL_272;
			cursmy = v8;
			cursmx = v6 + 1;
		}
		pcursobj = v61;
LABEL_272:
		v63 = dObject[0][v27 + v8];
		if ( v63 )
		{
			v64 = v63 <= 0 ? -1 - v63 : v63 - 1;
			v65 = object[v64]._oSelFlag;
			if ( v65 == 1 || v65 == 3 )
			{
				cursmx = v6;
				cursmy = v8;
				pcursobj = v64;
			}
		}
		v66 = dObject[1][v27 + 1 + v8];
		if ( !v66 || (v66 <= 0 ? (v67 = -1 - v66) : (v67 = v66 - 1), SLOBYTE(object[v67]._oSelFlag) < 2) )
		{
LABEL_286:
			if ( pcursobj != -1 || *(_DWORD *)&pcursmonst != -1 )
				goto LABEL_306;
			if ( v83 )
			{
				v70 = dItem[0][v27 + 1 + v8];
				if ( v70 <= 0 )
					goto LABEL_296;
				v69 = v70 - 1;
				if ( items[v69]._iSelFlag < 2 )
					goto LABEL_296;
				cursmx = v6;
				cursmy = v8 + 1;
			}
			else
			{
				v68 = dItem[1][v27 + v8];
				if ( v68 <= 0 )
					goto LABEL_296;
				v69 = v68 - 1;
				if ( items[v69]._iSelFlag < 2 )
					goto LABEL_296;
				cursmy = v8;
				cursmx = v6 + 1;
			}
			pcursitem = v69;
LABEL_296:
			v71 = dItem[0][v27 + v8];
			if ( v71 > 0 )
			{
				v72 = v71 - 1;
				v73 = items[v72]._iSelFlag;
				if ( v73 == 1 || v73 == 3 )
				{
					cursmx = v6;
					cursmy = v8;
					pcursitem = v72;
				}
			}
			v74 = dItem[1][v27 + 1 + v8];
			if ( v74 > 0 )
			{
				v75 = v74 - 1;
				if ( items[v75]._iSelFlag >= 2 )
				{
					pcursitem = v75;
					cursmx = v6 + 1;
					cursmy = v8 + 1;
				}
			}
			if ( pcursitem != -1 )
				goto LABEL_306;
			cursmx = v6;
			cursmy = v8;
			CheckTrigForce();
			CheckTown();
			CheckRportal();
			goto LABEL_305;
		}
		pcursobj = v67;
		cursmx = v6 + 1;
		cursmy = v8 + 1;
		goto LABEL_285;
	}
	if ( v10 == -1 )
		goto LABEL_128;
	v12 = 112 * v6 + v8;
	v81 = 112 * v6 + v8;
	v13 = 112 * v6 + v8;
	if ( v83 )
	{
		v14 = v13;
		v15 = dMonster[1][v14 + 2];
		if ( !v15 )
			goto LABEL_74;
		v16 = (dFlags[1][v12 + 2] & 0x40) == 0;
	}
	else
	{
		v14 = v13;
		v15 = dMonster[2][v14 + 1];
		if ( !v15 )
			goto LABEL_74;
		v16 = (dFlags[2][v12 + 1] & 0x40) == 0;
	}
	if ( !v16 )
	{
		v17 = v15 <= 0 ? -1 - v15 : v15 - 1;
		if ( v17 == dword_4B8CCC
		  && (signed int)(monster[v17]._mhitpoints & 0xFFFFFFC0) > 0
		  && monster[v17].MData->mSelFlag & 4 )
		{
			v11 = v17;
			cursmx = v6 + 1;
			cursmy = v8 + 2;
			*(_DWORD *)&pcursmonst = v17;
		}
	}
LABEL_74:
	v18 = dMonster[2][v14 + 2];
	if ( v18 && dFlags[2][v81 + 2] & 0x40 )
	{
		v19 = v18 <= 0 ? -1 - v18 : v18 - 1;
		if ( v19 == dword_4B8CCC
		  && (signed int)(monster[v19]._mhitpoints & 0xFFFFFFC0) > 0
		  && monster[v19].MData->mSelFlag & 4 )
		{
			v11 = v19;
			cursmx = v6 + 2;
			cursmy = v8 + 2;
			*(_DWORD *)&pcursmonst = v19;
		}
	}
	if ( v83 )
	{
		v22 = dMonster[0][v14 + 1];
		if ( v22 && dFlags[0][v81 + 1] & 0x40 )
		{
			v21 = v22 <= 0 ? -1 - v22 : v22 - 1;
			if ( v21 == dword_4B8CCC
			  && (signed int)(monster[v21]._mhitpoints & 0xFFFFFFC0) > 0
			  && monster[v21].MData->mSelFlag & 2 )
			{
				cursmx = v6;
				cursmy = v8 + 1;
				goto LABEL_102;
			}
		}
	}
	else
	{
		v20 = dMonster[1][v14];
		if ( v20 && dFlags[1][v81] & 0x40 )
		{
			v21 = v20 <= 0 ? -1 - v20 : v20 - 1;
			if ( v21 == dword_4B8CCC
			  && (signed int)(monster[v21]._mhitpoints & 0xFFFFFFC0) > 0
			  && monster[v21].MData->mSelFlag & 2 )
			{
				cursmy = v8;
				cursmx = v6 + 1;
LABEL_102:
				v11 = v21;
				*(_DWORD *)&pcursmonst = v21;
				goto LABEL_103;
			}
		}
	}
LABEL_103:
	v23 = dMonster[0][v14];
	if ( v23 && dFlags[0][v81] & 0x40 )
	{
		v24 = v23 <= 0 ? -1 - v23 : v23 - 1;
		if ( v24 == dword_4B8CCC
		  && (signed int)(monster[v24]._mhitpoints & 0xFFFFFFC0) > 0
		  && monster[v24].MData->mSelFlag & 1 )
		{
			v11 = v24;
			cursmx = v6;
			cursmy = v8;
			*(_DWORD *)&pcursmonst = v24;
		}
	}
	v25 = dMonster[1][v14 + 1];
	if ( v25 && dFlags[1][v81 + 1] & 0x40 )
	{
		v26 = v25 <= 0 ? -1 - v25 : v25 - 1;
		if ( v26 == dword_4B8CCC
		  && (signed int)(monster[v26]._mhitpoints & 0xFFFFFFC0) > 0
		  && monster[v26].MData->mSelFlag & 2 )
		{
			v11 = v26;
			cursmx = v6 + 1;
			cursmy = v8 + 1;
			*(_DWORD *)&pcursmonst = v26;
		}
	}
	if ( v11 == -1 )
		goto LABEL_128;
	if ( monster[v11]._mFlags & 1 )
	{
		v11 = -1;
		cursmx = v6;
		*(_DWORD *)&pcursmonst = -1;
		cursmy = v8;
	}
	if ( v11 == -1 )
		goto LABEL_128;
	if ( monster[v11]._mFlags & 0x20 )
	{
		v11 = -1;
		*(_DWORD *)&pcursmonst = -1;
	}
	if ( v11 == -1 )
	{
LABEL_128:
		v27 = 112 * v6;
		v78 = 112 * v6;
		if ( v83 )
		{
			v28 = v27 + v8;
			v32 = dMonster[1][v28 + 2];
			if ( v32 && dFlags[1][v27 + 2 + v8] & 0x40 )
			{
				v30 = v32 <= 0 ? -1 - v32 : v32 - 1;
				if ( (signed int)(monster[v30]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v30].MData->mSelFlag & 4 )
				{
					cursmx = v6 + 1;
					v31 = v8 + 2;
					goto LABEL_145;
				}
			}
		}
		else
		{
			v28 = v27 + v8;
			v29 = dMonster[2][v28 + 1];
			if ( v29 && dFlags[2][v27 + 1 + v8] & 0x40 )
			{
				v30 = v29 <= 0 ? -1 - v29 : v29 - 1;
				if ( (signed int)(monster[v30]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v30].MData->mSelFlag & 4 )
				{
					cursmx = v6 + 2;
					v31 = v8 + 1;
LABEL_145:
					cursmy = v31;
					*(_DWORD *)&pcursmonst = v30;
					goto LABEL_146;
				}
			}
		}
LABEL_146:
		v33 = dMonster[2][v28 + 2];
		if ( v33 && dFlags[2][v27 + 2 + v8] & 0x40 )
		{
			v34 = v33 <= 0 ? -1 - v33 : v33 - 1;
			if ( (signed int)(monster[v34]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v34].MData->mSelFlag & 4 )
			{
				*(_DWORD *)&pcursmonst = v34;
				cursmx = v6 + 2;
				cursmy = v8 + 2;
			}
		}
		if ( v83 )
		{
			v37 = dMonster[0][v28 + 1];
			if ( v37 && dFlags[0][v27 + 1 + v8] & 0x40 )
			{
				v36 = v37 <= 0 ? -1 - v37 : v37 - 1;
				if ( (signed int)(monster[v36]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v36].MData->mSelFlag & 2 )
				{
					cursmx = v6;
					cursmy = v8 + 1;
					goto LABEL_171;
				}
			}
		}
		else
		{
			v35 = dMonster[1][v28];
			if ( v35 && dFlags[1][v27 + v8] & 0x40 )
			{
				v36 = v35 <= 0 ? -1 - v35 : v35 - 1;
				if ( (signed int)(monster[v36]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v36].MData->mSelFlag & 2 )
				{
					cursmy = v8;
					cursmx = v6 + 1;
LABEL_171:
					*(_DWORD *)&pcursmonst = v36;
					goto LABEL_172;
				}
			}
		}
LABEL_172:
		v38 = dMonster[0][v28];
		if ( v38 && dFlags[0][v27 + v8] & 0x40 )
		{
			v39 = v38 <= 0 ? -1 - v38 : v38 - 1;
			if ( (signed int)(monster[v39]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v39].MData->mSelFlag & 1 )
			{
				cursmx = v6;
				cursmy = v8;
				*(_DWORD *)&pcursmonst = v39;
			}
		}
		v40 = dMonster[1][v28 + 1];
		if ( v40 && dFlags[1][v27 + 1 + v8] & 0x40 )
		{
			v41 = v40 <= 0 ? -1 - v40 : v40 - 1;
			if ( (signed int)(monster[v41]._mhitpoints & 0xFFFFFFC0) > 0 && monster[v41].MData->mSelFlag & 2 )
			{
				*(_DWORD *)&pcursmonst = v41;
				cursmx = v6 + 1;
				cursmy = v8 + 1;
			}
		}
		v42 = *(_DWORD *)&pcursmonst;
		if ( *(_DWORD *)&pcursmonst == -1 )
			goto LABEL_207;
		if ( monster[*(_DWORD *)&pcursmonst]._mFlags & 1 )
		{
			v42 = -1;
			cursmx = v6;
			*(_DWORD *)&pcursmonst = -1;
			cursmy = v8;
		}
		if ( v42 == -1 )
			goto LABEL_207;
		if ( monster[v42]._mFlags & 0x20 )
			goto LABEL_205;
		goto LABEL_206;
	}
}
// 4B8968: using guessed type int sbookflag;
// 4B8B84: using guessed type int panelflag;
// 4B8C98: using guessed type int spselflag;
// 4B8CB8: using guessed type char pcursinvitem;
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC1: using guessed type char pcursobj;
// 4B8CC2: using guessed type char pcursplr;
// 4B8CCC: using guessed type int dword_4B8CCC;
// 52569C: using guessed type int zoomflag;
// 52575C: using guessed type int doomflag;
// 5BB1ED: using guessed type char leveltype;
// 69BD04: using guessed type int questlog;

//----- (004084A6) --------------------------------------------------------
void __cdecl InitDead()
{
	int v0; // ebx
	int *v1; // edx
	int *v2; // eax
	int v3; // ecx
	int v4; // edx
	int v5; // eax
	int v6; // edx
	int v7; // esi
	int *v8; // eax
	int v9; // edx
	CMonster *v10; // ecx
	char *v11; // edi
	int *v12; // ebx
	int mtypes[200]; // [esp+Ch] [ebp-330h]
	int *v14; // [esp+32Ch] [ebp-10h]
	int *v15; // [esp+330h] [ebp-Ch]
	int v16; // [esp+334h] [ebp-8h]
	int v17; // [esp+338h] [ebp-4h]

	memset(mtypes, 0, sizeof(mtypes));
	v0 = 0;
	if ( nummtypes > 0 )
	{
		v1 = &dead[0]._deadFrame;
		v2 = &Monsters[0].Anims[4].Rate;
		v17 = nummtypes;
		do
		{
			v15 = &mtypes[*((unsigned char *)v2 - 216)];
			if ( !*v15 )
			{
				qmemcpy(v1 - 8, v2 - 8, 0x20u);
				v3 = *v2;
				*((_BYTE *)v1 + 12) = 0;
				*v1 = v3;
				v1[1] = v2[21];
				v1[2] = v2[22];
				*((_BYTE *)v2 + 101) = ++v0;
				v1 += 12;
				*v15 = v0;
			}
			v2 += 82;
			--v17;
		}
		while ( v17 );
	}
	v16 = 0;
	v4 = v0;
	memset(&dead[v0], misfiledata[16].mAnimCel[0], 8u);
	_LOBYTE(dead[v4]._deadtrans) = 0;
	dead[v4]._deadFrame = 8;
	v5 = misfiledata[18].mAnimCel[0];
	dead[v4].field_24 = 128;
	dead[v4].field_28 = 32;
	v6 = v0 + 1;
	spurtndx = v0 + 1;
	memset(&dead[v6], v5, 8u);
	_LOBYTE(dead[v6]._deadtrans) = 0;
	stonendx = v0 + 2;
	v7 = nummonsters;
	dead[v6]._deadFrame = 12;
	dead[v6].field_24 = 128;
	dead[v6].field_28 = 32;
	v17 = v0 + 2;
	if ( v7 > 0 )
	{
		v8 = &dead[v0 + 2]._deadFrame;
		do
		{
			v9 = monstactive[v16];
			if ( monster[v9]._uniqtype )
			{
				v10 = monster[v9].MType;
				v11 = (char *)(v8 - 8);
				v15 = (int *)8;
				v14 = &v10->Anims[4].Frames[1];
				do
				{
					v12 = v14;
					++v14;
					*(_DWORD *)v11 = *v12;
					v11 += 4;
					v15 = (int *)((char *)v15 - 1);
				}
				while ( v15 );
				*v8 = v10->Anims[4].Rate;
				v8[1] = v10->flags_1;
				v8[2] = v10->flags_2;
				*((_BYTE *)v8 + 12) = monster[v9]._uniqtrans + 4;
				monster[v9]._udeadval = ++v17;
				v8 += 12;
			}
			++v16;
		}
		while ( v16 < v7 );
	}
}
// 4B8CD8: using guessed type int spurtndx;

//----- (0040865C) --------------------------------------------------------
void __fastcall AddDead(int dx, int dy, char dv, direction ddir)
{
	dDead[dx][dy] = (dv & 0x1F) + 32 * ddir;
}

//----- (0040867D) --------------------------------------------------------
void __cdecl SetDead()
{
	int v0; // eax
	int v1; // esi
	int v2; // ebp
	char (*v3)[112]; // ebx
	int v4; // edi
	int i; // [esp+0h] [ebp-4h]

	v0 = 0;
	for ( i = 0; i < nummonsters; ++i )
	{
		v1 = monstactive[v0];
		if ( monster[v1]._uniqtype )
		{
			v2 = 0;
			v3 = dDead;
			do
			{
				v4 = 0;
				do
				{
					if ( ((*v3)[v4] & 0x1F) == monster[v1]._udeadval )
						ChangeLightXY((unsigned char)monster[v1].mlid, v2, v4);
					++v4;
				}
				while ( v4 < 112 );
				++v3;
				++v2;
			}
			while ( (signed int)v3 < (signed int)dpiece_defs_map_1 );
		}
		v0 = i + 1;
	}
}

//----- (004086F4) --------------------------------------------------------
void __cdecl LoadDebugGFX()
{
	if ( visiondebug )
		pSquareCel = LoadFileInMem("Data\\Square.CEL", 0);
}
// 525720: using guessed type int visiondebug;

//----- (0040870F) --------------------------------------------------------
void __cdecl FreeDebug()
{
	void *v0; // ecx

	v0 = pSquareCel;
	pSquareCel = 0;
	mem_free_dbg(v0);
}

//----- (00408721) --------------------------------------------------------
void __cdecl CheckClearDbg()
{
	int v0; // esi
	signed int v1; // ebx
	int v2; // edi
	char v3; // cl
	int v4; // eax
	int (*v5)[112]; // [esp+Ch] [ebp-8h]
	int (*v6)[112]; // [esp+10h] [ebp-4h]

	v0 = 0;
	v6 = dMonster;
	do
	{
		v1 = 0;
		v5 = v6;
		v2 = v0;
		do
		{
			if ( (*v5)[0] )
				TermMsg("Monsters not cleared");
			if ( dPlayer[0][v2] )
				TermMsg("Players not cleared");
			v3 = dFlags[0][v2];
			v4 = v1 + 112 * currlevel;
			++v5;
			++v1;
			v2 += 112;
			debug_dMonster[0][v4][v0] = v3 & 2;
			debug_dflags[0][v4][v0] = v3 & 8;
		}
		while ( v1 < 112 );
		v6 = (int (*)[112])((char *)v6 + 4);
		++v0;
	}
	while ( (signed int)v6 < (signed int)dMonster[1] );
}

//----- (004087B6) --------------------------------------------------------
void __cdecl diablo_cpp_init()
{
	diablo_cpp_init_value = diablo_inf;
}
// 479BF8: using guessed type int diablo_inf;
// 525514: using guessed type int diablo_cpp_init_value;

//----- (004087C1) --------------------------------------------------------
void __cdecl FreeGameMem()
{
	void *v0; // ecx
	void *v1; // ecx
	void *v2; // ecx
	void *v3; // ecx
	void *v4; // ecx

	music_stop();
	v0 = pDungeonCels;
	pDungeonCels = 0;
	mem_free_dbg(v0);
	v1 = pMegaTiles;
	pMegaTiles = 0;
	mem_free_dbg(v1);
	v2 = *(void **)&dpiece_defs[0].blocks;
	*(_DWORD *)&dpiece_defs[0].blocks = 0;
	mem_free_dbg(v2);
	v3 = level_special_cel;
	level_special_cel = 0;
	mem_free_dbg(v3);
	v4 = pSpeedCels;
	pSpeedCels = 0;
	mem_free_dbg(v4);
	FreeMissiles();
	FreeMonsters();
	FreeObjectGFX();
	FreeEffects();
	FreeTownerGFX();
}

//----- (00408838) --------------------------------------------------------
int __fastcall diablo_init_menu(int a1, int bSinglePlayer)
{
	int v2; // esi
	int v3; // edi
	interface_mode v4; // ecx
	unsigned char pfExitProgram[4]; // [esp+Ch] [ebp-4h]

	v2 = bSinglePlayer;
	v3 = a1;
	byte_678640 = 1;
	while ( 1 )
	{
		*(_DWORD *)pfExitProgram = 0;
		dword_5256E8 = 0;
		if ( !NetInit(v2, (int *)pfExitProgram) )
			break;
		byte_678640 = 0;
		if ( (v3 || !*(_DWORD *)&gbValidSaveFile)
		  && (InitLevels(), InitQuests(), InitPortals(), InitDungMsgs(myplr), !*(_DWORD *)&gbValidSaveFile)
		  || (v4 = WM_DIABLOADGAME, !dword_5256E8) )
		{
			v4 = WM_DIABNEWGAME;
		}
		run_game_loop(v4);
		NetClose();
		pfile_create_player_description(0, 0);
		if ( !gbRunGameResult )
			goto LABEL_11;
	}
	gbRunGameResult = *(_DWORD *)pfExitProgram == 0;
LABEL_11:
	SNetDestroy();
	return gbRunGameResult;
}
// 525698: using guessed type int gbRunGameResult;
// 5256E8: using guessed type int dword_5256E8;
// 678640: using guessed type char byte_678640;

//----- (004088E2) --------------------------------------------------------
void __fastcall run_game_loop(int interface_mode)
{
	int v1; // esi
	HANDLE v2; // eax
	int v3; // eax
	HANDLE v4; // eax
	bool v5; // zf
	int v6; // eax
	signed int v7; // [esp+8h] [ebp-24h]
	LRESULT (__stdcall *func)(HWND, UINT, WPARAM, LPARAM); // [esp+Ch] [ebp-20h]
	struct tagMSG Msg; // [esp+10h] [ebp-1Ch]

	v1 = interface_mode;
	nthread_ignore_mutex(1);
	start_game(v1);
	func = SetWindowProc(GM_Game);
	control_update_life_mana();
	msg_process_net_packets();
	gbRunGame = 1;
	gbProcessPlayers = 1;
	gbRunGameResult = 1;
	force_redraw = 255;
	DrawAndBlit();
	PaletteFadeIn(8);
	force_redraw = 255;
	*(_DWORD *)&gbGameLoopStartup = 1;
	nthread_ignore_mutex(0);
	while ( gbRunGame )
	{
		diablo_color_cyc_logic();
		if ( PeekMessageA(&Msg, 0, 0, 0, 0) )
		{
			v2 = GetCurrentThread();
			SetThreadPriority(v2, 1);
			while ( PeekMessageA(&Msg, 0, 0, 0, 1u) )
			{
				if ( Msg.message == 18 )
				{
					gbRunGameResult = 0;
					gbRunGame = 0;
					break;
				}
				TranslateMessage(&Msg);
				DispatchMessageA(&Msg);
			}
			if ( !gbRunGame || (_LOBYTE(v3) = nthread_has_500ms_passed(), v7 = 1, !v3) )
				v7 = 0;
			v4 = GetCurrentThread();
			SetThreadPriority(v4, 0);
			v5 = v7 == 0;
		}
		else
		{
			_LOBYTE(v6) = nthread_has_500ms_passed();
			v5 = v6 == 0;
		}
		if ( !v5 )
		{
			multi_process_network_packets();
			game_loop(gbGameLoopStartup);
			msgcmd_send_chat();
			*(_DWORD *)&gbGameLoopStartup = 0;
			DrawAndBlit();
		}
	}
	if ( (unsigned char)gbMaxPlayers > 1u )
		pfile_write_hero();
	pfile_flush_W();
	PaletteFadeOut(8);
	SetCursor(0);
	ClearScreenBuffer();
	force_redraw = 255;
	scrollrt_455E65(1);
	SetWindowProc(func);
	free_game();
	if ( cineflag )
	{
		cineflag = 0;
		DoEnding();
	}
}
// 525650: using guessed type int gbRunGame;
// 525698: using guessed type int gbRunGameResult;
// 5256A0: using guessed type int gbProcessPlayers;
// 525718: using guessed type char cineflag;
// 52571C: using guessed type int force_redraw;
// 679660: using guessed type char gbMaxPlayers;

//----- (00408A8C) --------------------------------------------------------
void __fastcall start_game(int interface_mode)
{
	int v1; // esi

	cineflag = 0;
	v1 = interface_mode;
	zoomflag = 1;
	InitCursor();
	InitLightTable();
	LoadDebugGFX();
	music_stop();
	ShowProgress(v1);
	gmenu_init_menu();
	InitLevelCursor();
	sgnTimeoutCurs = 0;
	sgbMouseDown = 0;
	track_mouse_stance(0);
}
// 52569C: using guessed type int zoomflag;
// 525718: using guessed type char cineflag;
// 525748: using guessed type char sgbMouseDown;

//----- (00408ADB) --------------------------------------------------------
void __cdecl free_game()
{
	int v0; // esi

	FreeControlPan();
	FreeInvGFX();
	FreeGMenu();
	FreeQuestText();
	FreeStoreMem();
	v0 = 0;
	do
		FreePlayerGFX(v0++);
	while ( v0 < 4 );
	FreeItemGFX();
	FreeCursor();
	FreeLightTable();
	FreeDebug();
	FreeGameMem();
}

//----- (00408B1E) --------------------------------------------------------
bool __cdecl diablo_get_not_running()
{
	SetLastError(0);
	CreateEventA(0, 0, 0, "DiabloEvent");
	return GetLastError() != ERROR_ALREADY_EXISTS;
}

//----- (00408B4A) --------------------------------------------------------
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	HINSTANCE v4; // esi
	int v5; // eax
	int v6; // eax
	unsigned int v7; // eax
	int v8; // eax
	int v9; // esi
	int v10; // eax
	int v11; // ecx
	char Filename[260]; // [esp+8h] [ebp-10Ch]
	char value_name[8]; // [esp+10Ch] [ebp-8h]

	v4 = hInstance;
	diablo_reload_process(hInstance);
	::hInstance = v4;
	_LOBYTE(v5) = RestrictedTest();
	if ( v5 )
		ErrDlg(TEMPLATE_ERR_RESTRICTED, 0, "C:\\Src\\Diablo\\Source\\DIABLO.CPP", 877);
	_LOBYTE(v6) = ReadOnlyTest();
	if ( v6 )
	{
		if ( !GetModuleFileNameA(::hInstance, Filename, 0x104u) )
			Filename[0] = 0;
		DirErrDlg(Filename);
	}
	ShowCursor(0);
	v7 = GetTickCount();
	srand(v7);
	encrypt_init_lookup_table();
	exception_get_filter();
	_LOBYTE(v8) = diablo_get_not_running();
	v9 = v8;
	if ( !diablo_find_window("DIABLO") && v9 )
	{
		diablo_init_screen();
		diablo_parse_flags(lpCmdLine);
		init_create_window();
		sound_init();
		UiInitialize();
		play_movie("gendata\\logo.smk", 1);
		strcpy(value_name, "Intro");
		_LOBYTE(v10) = SRegLoadValue("Diablo", value_name, 0, (int *)&hInstance);
		if ( !v10 )
			hInstance = (HINSTANCE)1;
		if ( hInstance )
			play_movie("gendata\\diablo1.smk", 1);
		SRegSaveValue("Diablo", value_name, 0, 0);
		UiTitleDialog(7);
		BlackPalette();
		mainmenu_action(v11);
		UiDestroy();
		palette_save_gamme();
		if ( ghMainWnd )
		{
			Sleep(0x12Cu);
			DestroyWindow(ghMainWnd);
		}
	}
	return 0;
}

//----- (00408CB1) --------------------------------------------------------
void __fastcall diablo_parse_flags(char *args)
{
	char *v1; // esi
	int i; // eax
	size_t v3; // eax
	size_t v4; // eax
	size_t v5; // eax
	size_t v6; // eax

	v1 = args;
	for ( _LOBYTE(i) = *args; *v1; _LOBYTE(i) = *v1 )
	{
		for ( i = (char)i; isspace(i); i = *v1 )
			++v1;
		v3 = strlen("dd_emulate");
		if ( !_strnicmp("dd_emulate", v1, v3) )
		{
			gbEmulate = 1;
			v4 = strlen("dd_emulate");
		}
		else
		{
			v5 = strlen("dd_backbuf");
			if ( !_strnicmp("dd_backbuf", v1, v5) )
			{
				gbBackBuf = 1;
				v4 = strlen("dd_backbuf");
			}
			else
			{
				v6 = strlen("ds_noduplicates");
				if ( _strnicmp("ds_noduplicates", v1, v6) )
				{
					tolower(*v1++);
					continue;
				}
				gbDupSounds = 0;
				v4 = strlen("ds_noduplicates");
			}
		}
		v1 += v4;
	}
}
// 4A22D6: using guessed type char gbDupSounds;
// 52A548: using guessed type char gbBackBuf;
// 52A549: using guessed type char gbEmulate;

//----- (00408D61) --------------------------------------------------------
void __cdecl diablo_init_screen()
{
	int v0; // ecx
	int *v1; // eax

	v0 = 0;
	MouseX = 320;
	MouseY = 240;
	ScrollInfo._sdx = 0;
	ScrollInfo._sdy = 0;
	ScrollInfo._sxoff = 0;
	ScrollInfo._syoff = 0;
	ScrollInfo._sdir = 0;
	v1 = screen_y_times_768;
	do
	{
		*v1 = v0;
		++v1;
		v0 += 768;
	}
	while ( (signed int)v1 < (signed int)&scrollrt_cpp_init_value );
	ClrDiabloMsg();
}
// 69CEFC: using guessed type int scrollrt_cpp_init_value;

//----- (00408DB1) --------------------------------------------------------
HWND __fastcall diablo_find_window(LPCSTR lpClassName)
{
	HWND result; // eax
	HWND v2; // esi
	HWND v3; // eax
	HWND v4; // edi

	result = FindWindowA(lpClassName, 0);
	v2 = result;
	if ( result )
	{
		v3 = GetLastActivePopup(result);
		if ( v3 )
			v2 = v3;
		v4 = GetTopWindow(v2);
		if ( !v4 )
			v4 = v2;
		SetForegroundWindow(v2);
		SetFocus(v4);
		result = (HWND)1;
	}
	return result;
}

//----- (00408DF4) --------------------------------------------------------
void __fastcall diablo_reload_process(HMODULE hModule)
{
	char *i; // eax
	DWORD v2; // esi
	BOOL v3; // edi
	_DWORD *v4; // eax
	_DWORD *v5; // esi
	HWND v6; // eax
	char Name[276]; // [esp+Ch] [ebp-29Ch]
	char Filename[260]; // [esp+120h] [ebp-188h]
	struct _STARTUPINFOA StartupInfo; // [esp+224h] [ebp-84h]
	struct _SYSTEM_INFO SystemInfo; // [esp+268h] [ebp-40h]
	struct _PROCESS_INFORMATION ProcessInformation; // [esp+28Ch] [ebp-1Ch]
	DWORD dwProcessId; // [esp+29Ch] [ebp-Ch]
	HANDLE hFileMappingObject; // [esp+2A0h] [ebp-8h]
	HWND hWnd; // [esp+2A4h] [ebp-4h]

	Filename[0] = empty_string;
	memset(&Filename[1], 0, 0x100u);
	*(_WORD *)&Filename[257] = 0;
	Filename[259] = 0;
	GetModuleFileNameA(hModule, Filename, 0x104u);
	wsprintfA(Name, "Reload-%s", Filename);
	for ( i = Name; *i; ++i )
	{
		if ( *i == '\\' )
			*i = '/';
	}
	GetSystemInfo(&SystemInfo);
	v2 = SystemInfo.dwPageSize;
	if ( SystemInfo.dwPageSize < 0x1000 )
		v2 = 4096;
	hFileMappingObject = CreateFileMappingA((HANDLE)0xFFFFFFFF, 0, 0x8000004u, 0, v2, Name);
	v3 = GetLastError() != ERROR_ALREADY_EXISTS;
	if ( hFileMappingObject )
	{
		v4 = (unsigned int *)MapViewOfFile(hFileMappingObject, 0xF001Fu, 0, 0, v2);
		v5 = v4;
		if ( v4 )
		{
			if ( v3 )
			{
				*v4 = -1;
				v4[1] = 0;
				memset(&StartupInfo, 0, 0x44u);
				StartupInfo.cb = 68;
				CreateProcessA(Filename, 0, 0, 0, 0, 0x200u, 0, 0, &StartupInfo, &ProcessInformation);
				WaitForInputIdle(ProcessInformation.hProcess, 0xFFFFFFFF);
				CloseHandle(ProcessInformation.hThread);
				CloseHandle(ProcessInformation.hProcess);
				while ( *v5 < 0 )
					Sleep(0x3E8u);
				UnmapViewOfFile(v5);
				CloseHandle(hFileMappingObject);
				ExitProcess(0);
			}
			if ( InterlockedIncrement((long *)v4) )
			{
				v6 = GetForegroundWindow();
				do
				{
					hWnd = v6;
					v6 = GetWindow(v6, 3u);
				}
				while ( v6 );
				while ( 1 )
				{
					GetWindowThreadProcessId(hWnd, &dwProcessId);
					if ( dwProcessId == v5[1] )
						break;
					hWnd = GetWindow(hWnd, 2u);
					if ( !hWnd )
						goto LABEL_23;
				}
				SetForegroundWindow(hWnd);
LABEL_23:
				UnmapViewOfFile(v5);
				CloseHandle(hFileMappingObject);
				ExitProcess(0);
			}
			v5[1] = GetCurrentProcessId();
		}
	}
}

//----- (00408FCF) --------------------------------------------------------
int __cdecl PressEscKey()
{
	int result; // eax

	result = 0;
	if ( doomflag )
	{
		doom_close();
		result = 1;
	}
	if ( helpflag )
	{
		helpflag = 0;
		result = 1;
	}
	if ( qtextflag )
	{
		qtextflag = 0;
		sfx_stop();
	}
	else
	{
		if ( !stextflag )
			goto LABEL_10;
		STextESC();
	}
	result = 1;
LABEL_10:
	if ( msgflag )
	{
		msgdelay = 0;
		result = 1;
	}
	if ( talkflag )
	{
		control_reset_talk();
		result = 1;
	}
	if ( dropGoldFlag )
	{
		control_drop_gold(27);
		result = 1;
	}
	if ( spselflag )
	{
		spselflag = 0;
		result = 1;
	}
	return result;
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8960: using guessed type int talkflag;
// 4B8C98: using guessed type int spselflag;
// 52575C: using guessed type int doomflag;
// 52B9F0: using guessed type char msgdelay;
// 52B9F1: using guessed type char msgflag;
// 646D00: using guessed type char qtextflag;
// 6AA705: using guessed type char stextflag;

//----- (0040905E) --------------------------------------------------------
LRESULT __stdcall DisableInputWndProc(HWND hWnd, int uMsg, int wParam, int lParam)
{
	bool v5; // zf

	if ( uMsg <= (unsigned int)WM_LBUTTONDOWN )
	{
		if ( uMsg != WM_LBUTTONDOWN )
		{
			if ( uMsg >= (unsigned int)WM_KEYFIRST
			  && (uMsg <= (unsigned int)WM_CHAR
			   || uMsg == WM_SYSKEYDOWN
			   || uMsg == WM_SYSCOMMAND
			   || uMsg == WM_MOUSEFIRST) )
			{
				return 0;
			}
			return init_palette(hWnd, uMsg, wParam, lParam);
		}
		if ( !sgbMouseDown )
		{
			sgbMouseDown = 1;
LABEL_21:
			SetCapture(hWnd);
			return 0;
		}
		return 0;
	}
	if ( uMsg == WM_LBUTTONUP )
	{
		v5 = sgbMouseDown == 1;
		goto LABEL_23;
	}
	if ( uMsg != WM_RBUTTONDOWN )
	{
		if ( uMsg != WM_RBUTTONUP )
		{
			if ( uMsg == WM_CAPTURECHANGED )
			{
				if ( hWnd != (HWND)lParam )
					sgbMouseDown = 0;
				return 0;
			}
			return init_palette(hWnd, uMsg, wParam, lParam);
		}
		v5 = sgbMouseDown == 2;
LABEL_23:
		if ( v5 )
		{
			sgbMouseDown = 0;
			ReleaseCapture();
		}
		return 0;
	}
	if ( !sgbMouseDown )
	{
		sgbMouseDown = 2;
		goto LABEL_21;
	}
	return 0;
}
// 525748: using guessed type char sgbMouseDown;

//----- (00409131) --------------------------------------------------------
int __stdcall GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	int v4; // eax

	if ( uMsg > WM_LBUTTONDOWN )
	{
		if ( uMsg == WM_LBUTTONUP )
		{
			MouseX = (unsigned short)lParam;
			MouseY = (unsigned int)lParam >> 16;
			if ( sgbMouseDown != 1 )
				return 0;
			sgbMouseDown = 0;
			LeftMouseUp();
			track_mouse_stance(0);
		}
		else
		{
			if ( uMsg == WM_RBUTTONDOWN )
			{
				MouseX = (unsigned short)lParam;
				MouseY = (unsigned int)lParam >> 16;
				if ( !sgbMouseDown )
				{
					sgbMouseDown = 2;
					SetCapture(hWnd);
					RightMouseDown();
				}
				return 0;
			}
			if ( uMsg != WM_RBUTTONUP )
			{
				if ( uMsg == WM_CAPTURECHANGED )
				{
					if ( hWnd != (HWND)lParam )
					{
						sgbMouseDown = 0;
						track_mouse_stance(0);
					}
				}
				else if ( uMsg > 0x401 && uMsg <= WM_DIABRETOWN )
				{
					if ( (unsigned char)gbMaxPlayers > 1u )
						pfile_write_hero();
					nthread_ignore_mutex(1);
					PaletteFadeOut(8);
					FreeMonsterSnd();
					music_stop();
					track_mouse_stance(0);
					sgbMouseDown = 0;
					ReleaseCapture();
					ShowProgress(uMsg);
					force_redraw = 255;
					DrawAndBlit();
					if ( gbRunGame )
						PaletteFadeIn(8);
					nthread_ignore_mutex(0);
					*(_DWORD *)&gbGameLoopStartup = 1;
					return 0;
				}
				return init_palette(hWnd, uMsg, wParam, lParam);
			}
			MouseX = (unsigned short)lParam;
			MouseY = (unsigned int)lParam >> 16;
			if ( sgbMouseDown != 2 )
				return 0;
			sgbMouseDown = 0;
		}
		ReleaseCapture();
		return 0;
	}
	switch ( uMsg )
	{
		case WM_LBUTTONDOWN:
			MouseX = (unsigned short)lParam;
			MouseY = (unsigned int)lParam >> 16;
			if ( !sgbMouseDown )
			{
				sgbMouseDown = 1;
				SetCapture(hWnd);
				LeftMouseDown();
				track_mouse_stance(v4);
			}
			return 0;
		case WM_KEYFIRST:
			PressKey(wParam);
			return 0;
		case WM_KEYUP:
			ReleaseKey(wParam);
			return 0;
		case WM_CHAR:
			PressChar(wParam);
			return 0;
		case WM_SYSKEYDOWN:
			if ( PressSysKey(wParam) )
				return 0;
			return init_palette(hWnd, uMsg, wParam, lParam);
		case WM_SYSCOMMAND:
			if ( wParam == SC_CLOSE )
			{
				gbRunGame = 0;
				gbRunGameResult = 0;
				return 0;
			}
			return init_palette(hWnd, uMsg, wParam, lParam);
	}
	if ( uMsg != WM_MOUSEFIRST )
		return init_palette(hWnd, uMsg, wParam, lParam);
	MouseX = (unsigned short)lParam;
	MouseY = (unsigned int)lParam >> 16;
	gmenu_run_item((unsigned short)lParam);
	return 0;
}
// 525650: using guessed type int gbRunGame;
// 525698: using guessed type int gbRunGameResult;
// 52571C: using guessed type int force_redraw;
// 525748: using guessed type char sgbMouseDown;
// 679660: using guessed type char gbMaxPlayers;

//----- (004093B2) --------------------------------------------------------
void __cdecl LeftMouseDown()
{
	int v0; // ecx
	int v1; // edi
	int v2; // eax
	int v3; // eax
	int v4; // eax
	int v5; // ecx
	int v6; // eax
	unsigned char v7; // dl
	int v8; // eax
	unsigned char v9; // dl
	unsigned short v10; // ax
	unsigned char v11; // dl
	int v12; // eax
	unsigned short v13; // [esp-8h] [ebp-10h]

	v1 = v0;
	if ( !gmenu_left_mouse(1) && !control_check_talk_btn() && sgnTimeoutCurs == CURSOR_NONE )
	{
		if ( *(_DWORD *)&deathflag )
		{
			control_check_btn_press();
			return;
		}
		if ( PauseMode != 2 )
		{
			if ( doomflag )
			{
				doom_close();
				return;
			}
			if ( spselflag )
			{
				SetSpell();
				return;
			}
			if ( stextflag )
			{
				CheckStoreBtn();
				return;
			}
			if ( MouseY >= 352 )
			{
				if ( !talkflag && !dropGoldFlag )
				{
					_LOBYTE(v4) = gmenu_exception();
					if ( !v4 )
						CheckInvScrn();
				}
				DoPanBtn();
				if ( pcurs > 1 && pcurs < 12 )
				{
LABEL_48:
					SetCursor(1);
					return;
				}
			}
			else
			{
				_LOBYTE(v2) = gmenu_exception();
				if ( !v2 && !TryIconCurs() )
				{
					if ( questlog && MouseX > 32 && MouseX < 288 && MouseY > 32 && MouseY < 308 )
					{
						QuestlogESC();
						return;
					}
					if ( qtextflag )
					{
						qtextflag = 0;
						sfx_stop();
						return;
					}
					if ( chrflag && MouseX < 320 )
					{
						CheckChrBtns();
						return;
					}
					if ( invflag && MouseX > 320 )
					{
						if ( !dropGoldFlag )
							CheckInvItem();
						return;
					}
					if ( sbookflag && MouseX > 320 )
					{
						CheckSBook();
						return;
					}
					if ( pcurs >= CURSOR_FIRSTITEM )
					{
						if ( !TryInvPut() )
							return;
						NetSendCmdPItem(1u, CMD_PUTITEM, cursmx, cursmy);
						goto LABEL_48;
					}
					v3 = 21720 * myplr;
					if ( plr[myplr]._pStatPts && !spselflag )
						CheckLvlBtn();
					if ( !lvlbtndown )
					{
						if ( !leveltype )
						{
							if ( pcursitem != -1 && pcurs == 1 )
							{
								_LOWORD(v3) = pcursitem;
								NetSendCmdLocParam1(1u, (invflag == 0) + CMD_GOTOGETITEM, cursmx, cursmy, v3);
							}
							if ( *(_DWORD *)&pcursmonst != -1 )
								NetSendCmdLocParam1(1u, CMD_TALKXY, cursmx, cursmy, *(int *)&pcursmonst);
							return;
						}
						v5 = abs(plr[myplr].WorldX - cursmx) < 2 && abs(plr[myplr].WorldY - cursmy) < 2;
						_HIWORD(v6) = _HIWORD(pcurs);
						if ( pcursitem != -1 && pcurs == 1 && v1 != 5 )
						{
							_LOWORD(v6) = pcursitem;
							NetSendCmdLocParam1(1u, (invflag == 0) + CMD_GOTOGETITEM, cursmx, cursmy, v6);
							return;
						}
						if ( pcursobj != -1 )
						{
							if ( v1 != 5 || v5 && (v5 = 120 * pcursobj, *((_BYTE *)&object[0]._oBreak + v5) == 1) )
							{
								_LOWORD(v5) = pcursobj;
								NetSendCmdLocParam1(1u, (pcurs == 5) + CMD_OPOBJXY, cursmx, cursmy, v5);
								return;
							}
						}
						if ( plr[myplr]._pwtype == 1 )
						{
							if ( v1 == 5 )
							{
								v7 = CMD_RATTACKXY;
LABEL_84:
								NetSendCmdLoc(1u, v7, cursmx, cursmy);
								return;
							}
							if ( *(_DWORD *)&pcursmonst != -1 )
							{
								_LOBYTE(v8) = CanTalkToMonst(*(int *)&pcursmonst);
								v13 = pcursmonst;
								if ( !v8 )
								{
									v9 = CMD_RATTACKID;
LABEL_89:
									NetSendCmdParam1(1u, v9, v13);
									return;
								}
LABEL_88:
								v9 = CMD_ATTACKID;
								goto LABEL_89;
							}
							_LOBYTE(v10) = pcursplr;
							if ( pcursplr == -1 || FriendlyMode )
								return;
							v11 = CMD_RATTACKPID;
						}
						else
						{
							if ( v1 == 5 )
							{
								if ( *(_DWORD *)&pcursmonst == -1
								  || (_LOBYTE(v12) = CanTalkToMonst(*(int *)&pcursmonst), !v12) )
								{
									v7 = CMD_SATTACKXY;
									goto LABEL_84;
								}
								v10 = pcursmonst;
								v11 = CMD_ATTACKID;
LABEL_94:
								NetSendCmdParam1(1u, v11, v10);
								return;
							}
							if ( *(_DWORD *)&pcursmonst != -1 )
							{
								v13 = pcursmonst;
								goto LABEL_88;
							}
							_LOBYTE(v10) = pcursplr;
							if ( pcursplr == -1 || FriendlyMode )
								return;
							v11 = CMD_ATTACKPID;
						}
						v10 = (char)v10;
						goto LABEL_94;
					}
				}
			}
		}
	}
}
// 484368: using guessed type int FriendlyMode;
// 4B84DC: using guessed type int dropGoldFlag;
// 4B851C: using guessed type int lvlbtndown;
// 4B8960: using guessed type int talkflag;
// 4B8968: using guessed type int sbookflag;
// 4B8C98: using guessed type int spselflag;
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC1: using guessed type char pcursobj;
// 4B8CC2: using guessed type char pcursplr;
// 525740: using guessed type int PauseMode;
// 52575C: using guessed type int doomflag;
// 5BB1ED: using guessed type char leveltype;
// 646D00: using guessed type char qtextflag;
// 69BD04: using guessed type int questlog;
// 6AA705: using guessed type char stextflag;

//----- (004097EC) --------------------------------------------------------
int __cdecl TryIconCurs()
{
	unsigned char v0; // dl
	int v1; // edx
	int v2; // eax
	int v3; // eax
	int v4; // ST0C_4
	int v5; // eax

	switch ( pcurs )
	{
		case CURSOR_RESURRECT:
			v0 = CMD_RESURRECT;
LABEL_3:
			NetSendCmdParam1(1u, v0, pcursplr);
			return 1;
		case CURSOR_HEALOTHER:
			v0 = CMD_HEALOTHER;
			goto LABEL_3;
		case CURSOR_TELEKINESIS:
			DoTelekinesis();
			return 1;
		case CURSOR_IDENTIFY:
			if ( pcursinvitem != -1 )
			{
				CheckIdentify(myplr, pcursinvitem);
				return 1;
			}
LABEL_26:
			SetCursor(1);
			return 1;
		case CURSOR_REPAIR:
			if ( pcursinvitem != -1 )
			{
				DoRepair(myplr, pcursinvitem);
				return 1;
			}
			goto LABEL_26;
		case CURSOR_RECHARGE:
			if ( pcursinvitem != -1 )
			{
				DoRecharge(myplr, pcursinvitem);
				return 1;
			}
			goto LABEL_26;
		case CURSOR_TELEPORT:
			v1 = plr[myplr]._pTSpell;
			if ( *(_DWORD *)&pcursmonst == -1 )
			{
				if ( pcursplr == -1 )
				{
					v4 = GetSpellLevel(myplr, v1);
					v5 = 21720 * myplr;
					_LOWORD(v5) = plr[myplr]._pTSpell;
					NetSendCmdLocParam2(1u, CMD_TSPELLXY, cursmx, cursmy, v5, v4);
				}
				else
				{
					v3 = GetSpellLevel(myplr, v1);
					NetSendCmdParam3(1u, CMD_TSPELLPID, pcursplr, plr[myplr]._pTSpell, v3);
				}
			}
			else
			{
				v2 = GetSpellLevel(myplr, v1);
				NetSendCmdParam3(1u, CMD_TSPELLID, pcursmonst, plr[myplr]._pTSpell, v2);
			}
			goto LABEL_26;
	}
	if ( pcurs == CURSOR_DISARM && pcursobj == -1 )
		goto LABEL_26;
	return 0;
}
// 4B8CB8: using guessed type char pcursinvitem;
// 4B8CC1: using guessed type char pcursobj;
// 4B8CC2: using guessed type char pcursplr;

//----- (00409963) --------------------------------------------------------
void __cdecl LeftMouseUp()
{
	gmenu_left_mouse(0);
	control_release_talk_btn();
	if ( panbtndown )
		CheckBtnUp();
	if ( chrbtnactive )
		ReleaseChrBtns();
	if ( lvlbtndown )
		ReleaseLvlBtn();
	if ( stextflag )
		ReleaseStoreBtn();
}
// 4B851C: using guessed type int lvlbtndown;
// 4B87A8: using guessed type int chrbtnactive;
// 4B8C90: using guessed type int panbtndown;
// 6AA705: using guessed type char stextflag;

//----- (004099A8) --------------------------------------------------------
void __cdecl RightMouseDown()
{
	int v0; // eax

	_LOBYTE(v0) = gmenu_exception();
	if ( !v0 && sgnTimeoutCurs == CURSOR_NONE && PauseMode != 2 && !plr[myplr]._pInvincible )
	{
		if ( doomflag )
		{
			doom_close();
		}
		else if ( !stextflag )
		{
			if ( spselflag )
			{
				SetSpell();
			}
			else if ( MouseY >= 352
				   || (!sbookflag || MouseX <= 320)
				   && !TryIconCurs()
				   && (pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem)) )
			{
				if ( pcurs == 1 )
				{
					if ( pcursinvitem == -1 || !UseInvItem(myplr, pcursinvitem) )
						CheckPlrSpell();
				}
				else if ( pcurs > 1 && pcurs < 12 )
				{
					SetCursor(1);
				}
			}
		}
	}
}
// 4B8968: using guessed type int sbookflag;
// 4B8C98: using guessed type int spselflag;
// 4B8CB8: using guessed type char pcursinvitem;
// 525740: using guessed type int PauseMode;
// 52575C: using guessed type int doomflag;
// 6AA705: using guessed type char stextflag;

//----- (00409A8E) --------------------------------------------------------
int __fastcall PressSysKey(int wParam)
{
	int v1; // esi
	int v2; // eax

	v1 = wParam;
	_LOBYTE(v2) = gmenu_exception();
	if ( v2 || v1 != VK_F10 )
		return 0;
	diablo_hotkey_msg(1);
	return 1;
}

//----- (00409AB0) --------------------------------------------------------
void __fastcall diablo_hotkey_msg(int dwMsg)
{
	int v1; // esi
	char *v2; // eax
	char Filename[260]; // [esp+4h] [ebp-154h]
	char ReturnedString[80]; // [esp+108h] [ebp-50h]

	v1 = dwMsg;
	if ( gbMaxPlayers != 1 )
	{
		if ( !GetModuleFileNameA(hInstance, Filename, 0x104u) )
			TermMsg("Can't get program name");
		v2 = strrchr(Filename, 92);
		if ( v2 )
			*v2 = 0;
		strcat(Filename, "\\Diablo.ini");
		GetPrivateProfileStringA("NetMsg", spszMsgKeyTbl[v1], spszMsgTbl[v1], ReturnedString, 0x50u, Filename);
		msg_init_msg(-1, ReturnedString);
	}
}
// 48436C: using guessed type char *spszMsgTbl[4];
// 48437C: using guessed type char *spszMsgKeyTbl[4];
// 679660: using guessed type char gbMaxPlayers;

//----- (00409B51) --------------------------------------------------------
void __fastcall ReleaseKey(int vkey)
{
	if ( vkey == VK_SNAPSHOT )
		CaptureScreen();
}

//----- (00409B5C) --------------------------------------------------------
void __fastcall PressKey(int vkey)
{
	int v1; // esi
	int v2; // ecx
	int v3; // ecx
	signed int v4; // eax

	v1 = vkey;
	if ( !gmenu_presskeys(vkey) && !control_presskeys(v1) )
	{
		if ( !*(_DWORD *)&deathflag )
			goto LABEL_113;
		if ( sgnTimeoutCurs == CURSOR_NONE )
		{
			if ( v1 == VK_F9 )
				diablo_hotkey_msg(0);
			if ( v1 == VK_F10 )
				diablo_hotkey_msg(1);
			if ( v1 == VK_F11 )
				diablo_hotkey_msg(2);
			if ( v1 == VK_F12 )
				diablo_hotkey_msg(3);
			if ( v1 == VK_RETURN )
				control_type_message();
			if ( v1 == VK_ESCAPE )
			{
LABEL_113:
				if ( v1 == VK_ESCAPE )
				{
					if ( !PressEscKey() )
					{
						track_mouse_stance(0);
						gamemenu_previous();
					}
					return;
				}
				if ( sgnTimeoutCurs == CURSOR_NONE && !dropGoldFlag )
				{
					if ( v1 == VK_PAUSE )
					{
						diablo_pause_game();
						return;
					}
					if ( PauseMode != 2 )
					{
						switch ( v1 )
						{
							case VK_RETURN:
								if ( stextflag )
								{
									STextEnter();
								}
								else if ( questlog )
								{
									QuestlogEnter();
								}
								else
								{
									control_type_message();
								}
								return;
							case VK_F1:
								if ( helpflag )
								{
									helpflag = 0;
									return;
								}
								if ( stextflag )
								{
									ClearPanel();
									AddPanelString("No help available", 1);
									AddPanelString("while in stores", 1);
									track_mouse_stance(0);
									return;
								}
								invflag = 0;
								chrflag = 0;
								sbookflag = 0;
								spselflag = 0;
								if ( qtextflag && !leveltype )
								{
									qtextflag = 0;
									sfx_stop();
								}
								questlog = 0;
								*(_DWORD *)&automapflag = 0;
								msgdelay = 0;
								gamemenu_off();
								DisplayHelp();
LABEL_110:
								doom_close();
								return;
							case VK_F5:
								v2 = 0;
								goto LABEL_48;
							case VK_F6:
								v2 = 1;
								goto LABEL_48;
							case VK_F7:
								v2 = 2;
								goto LABEL_48;
							case VK_F8:
								v2 = 3;
LABEL_48:
								if ( spselflag )
									SetSpeedSpell(v2);
								else
									ToggleSpell(v2);
								return;
							case VK_F9:
								v3 = 0;
LABEL_59:
								diablo_hotkey_msg(v3);
								return;
							case VK_F10:
								v3 = 1;
								goto LABEL_59;
							case VK_F11:
								v3 = 2;
								goto LABEL_59;
							case VK_F12:
								v3 = 3;
								goto LABEL_59;
							case VK_UP:
								if ( stextflag )
								{
									STextUp();
								}
								else if ( questlog )
								{
									QuestlogUp();
								}
								else if ( helpflag )
								{
									HelpScrollUp();
								}
								else if ( *(_DWORD *)&automapflag )
								{
									AutomapUp();
								}
								return;
							case VK_DOWN:
								if ( stextflag )
								{
									STextDown();
								}
								else if ( questlog )
								{
									QuestlogDown();
								}
								else if ( helpflag )
								{
									HelpScrollDown();
								}
								else if ( *(_DWORD *)&automapflag )
								{
									AutomapDown();
								}
								return;
							case VK_PRIOR:
								if ( stextflag )
									STextPrior();
								return;
							case VK_NEXT:
								if ( stextflag )
									STextNext();
								return;
							case VK_LEFT:
								if ( *(_DWORD *)&automapflag && !talkflag )
									AutomapLeft();
								return;
							case VK_RIGHT:
								if ( *(_DWORD *)&automapflag && !talkflag )
									AutomapRight();
								return;
							case VK_TAB:
								DoAutoMap();
								return;
							case VK_SPACE:
								if ( !chrflag )
								{
									if ( !invflag )
									{
LABEL_106:
										helpflag = 0;
										invflag = 0;
										chrflag = 0;
										sbookflag = 0;
										spselflag = 0;
										if ( qtextflag && !leveltype )
										{
											qtextflag = 0;
											sfx_stop();
										}
										questlog = 0;
										*(_DWORD *)&automapflag = 0;
										msgdelay = 0;
										gamemenu_off();
										goto LABEL_110;
									}
									v4 = MouseX;
									if ( MouseX >= 480 || MouseY >= 352 )
									{
LABEL_101:
										if ( !invflag && chrflag && v4 > 160 && MouseY < 352 )
											SetCursorPos(v4 - 160, MouseY);
										goto LABEL_106;
									}
									SetCursorPos(MouseX + 160, MouseY);
								}
								v4 = MouseX;
								goto LABEL_101;
						}
					}
				}
			}
		}
	}
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8960: using guessed type int talkflag;
// 4B8968: using guessed type int sbookflag;
// 4B8C98: using guessed type int spselflag;
// 525740: using guessed type int PauseMode;
// 52B9F0: using guessed type char msgdelay;
// 5BB1ED: using guessed type char leveltype;
// 646D00: using guessed type char qtextflag;
// 69BD04: using guessed type int questlog;
// 6AA705: using guessed type char stextflag;

//----- (00409F43) --------------------------------------------------------
void __cdecl diablo_pause_game()
{
	if ( (unsigned char)gbMaxPlayers <= 1u )
	{
		if ( PauseMode )
		{
			PauseMode = 0;
		}
		else
		{
			PauseMode = 2;
			FreeMonsterSnd();
			track_mouse_stance(0);
		}
		force_redraw = 255;
	}
}
// 52571C: using guessed type int force_redraw;
// 525740: using guessed type int PauseMode;
// 679660: using guessed type char gbMaxPlayers;

//----- (00409F7F) --------------------------------------------------------
void __fastcall PressChar(int vkey)
{
	int v1; // ebx
	int v2; // eax
	int v3; // ecx
	BOOL v4; // ecx
	int v5; // ecx
	int v6; // eax
	BOOL v7; // ecx
	const char *v8; // edx
	int v9; // ecx
	int v10; // eax
	int v11; // eax
	int v12; // eax
	int v13; // eax
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // eax
	int v18; // [esp-4h] [ebp-8h]

	v1 = vkey;
	_LOBYTE(v2) = gmenu_exception();
	if ( !v2 && !control_talk_last_key(v1) && sgnTimeoutCurs == CURSOR_NONE && !*(_DWORD *)&deathflag )
	{
		if ( (_BYTE)v1 == 'p' || (_BYTE)v1 == 'P' )
		{
			diablo_pause_game();
		}
		else if ( PauseMode != 2 )
		{
			if ( doomflag )
			{
				doom_close();
				return;
			}
			if ( dropGoldFlag )
			{
				_LOBYTE(v3) = v1;
				control_drop_gold(v3);
				return;
			}
			switch ( v1 )
			{
				case '!':
				case '1':
					v9 = myplr;
					v10 = plr[myplr].SpdList[0]._itype;
					if ( v10 != -1 && v10 != 11 )
					{
						v18 = 47;
						goto LABEL_72;
					}
					return;
				case '#':
				case '3':
					v9 = myplr;
					v12 = plr[myplr].SpdList[2]._itype;
					if ( v12 != -1 && v12 != 11 )
					{
						v18 = 49;
						goto LABEL_72;
					}
					return;
				case '$':
				case '4':
					v9 = myplr;
					v13 = plr[myplr].SpdList[3]._itype;
					if ( v13 != -1 && v13 != 11 )
					{
						v18 = 50;
						goto LABEL_72;
					}
					return;
				case '%':
				case '5':
					v9 = myplr;
					v14 = plr[myplr].SpdList[4]._itype;
					if ( v14 != -1 && v14 != 11 )
					{
						v18 = 51;
						goto LABEL_72;
					}
					return;
				case '&':
				case '7':
					v9 = myplr;
					v16 = plr[myplr].SpdList[6]._itype;
					if ( v16 != -1 && v16 != 11 )
					{
						v18 = 53;
						goto LABEL_72;
					}
					return;
				case '*':
				case '8':
					v9 = myplr;
					v17 = plr[myplr].SpdList[7]._itype;
					if ( v17 != -1 && v17 != 11 )
					{
						v18 = 54;
						goto LABEL_72;
					}
					return;
				case '+':
				case '=':
					if ( *(_DWORD *)&automapflag )
						AutomapZoomIn();
					return;
				case '-':
				case '_':
					if ( *(_DWORD *)&automapflag )
						AutomapZoomOut();
					return;
				case '2':
				case '@':
					v9 = myplr;
					v11 = plr[myplr].SpdList[1]._itype;
					if ( v11 != -1 && v11 != 11 )
					{
						v18 = 48;
						goto LABEL_72;
					}
					return;
				case '6':
				case '^':
					v9 = myplr;
					v15 = plr[myplr].SpdList[5]._itype;
					if ( v15 != -1 && v15 != 11 )
					{
						v18 = 52;
LABEL_72:
						UseInvItem(v9, v18);
					}
					return;
				case 'B':
				case 'b':
					if ( !stextflag )
					{
						invflag = 0;
						sbookflag = sbookflag == 0;
					}
					return;
				case 'C':
				case 'c':
					if ( !stextflag )
					{
						questlog = 0;
						v7 = chrflag == 0;
						chrflag = chrflag == 0;
						if ( !v7 || invflag )
							goto LABEL_18;
						goto LABEL_24;
					}
					return;
				case 'F':
				case 'f':
					palette_inc_gamma();
					return;
				case 'G':
				case 'g':
					palette_dec_gamma();
					return;
				case 'I':
				case 'i':
					if ( stextflag )
						return;
					sbookflag = 0;
					v4 = invflag == 0;
					invflag = invflag == 0;
					if ( !v4 || chrflag )
					{
LABEL_24:
						if ( MouseX < 480 )
						{
							v5 = MouseY;
							if ( MouseY < 352 )
							{
								v6 = MouseX + 160;
								goto LABEL_27;
							}
						}
					}
					else
					{
LABEL_18:
						if ( MouseX > 160 )
						{
							v5 = MouseY;
							if ( MouseY < 352 )
							{
								v6 = MouseX - 160;
LABEL_27:
								SetCursorPos(v6, v5);
								return;
							}
						}
					}
					break;
				case 'Q':
				case 'q':
					if ( !stextflag )
					{
						chrflag = 0;
						if ( questlog )
							questlog = 0;
						else
							StartQuestlog();
					}
					return;
				case 'S':
				case 's':
					if ( !stextflag )
					{
						invflag = 0;
						if ( spselflag )
							spselflag = 0;
						else
							DoSpeedBook();
						track_mouse_stance(0);
					}
					return;
				case 'V':
					v8 = "internal version unknown";
					goto LABEL_47;
				case 'Z':
				case 'z':
					zoomflag = zoomflag == 0;
					return;
				case 'v':
					v8 = "Diablo v1.09";
LABEL_47:
					msg_init_msg(1 << myplr, v8);
					return;
				default:
					return;
			}
		}
	}
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8968: using guessed type int sbookflag;
// 4B8C98: using guessed type int spselflag;
// 52569C: using guessed type int zoomflag;
// 525740: using guessed type int PauseMode;
// 52575C: using guessed type int doomflag;
// 69BD04: using guessed type int questlog;
// 6AA705: using guessed type char stextflag;

//----- (0040A391) --------------------------------------------------------
void __cdecl LoadLvlGFX()
{
	unsigned char *v0; // eax
	char *v1; // ecx
	unsigned char *v2; // eax
	char *v3; // ecx
	unsigned char *v4; // eax
	char *v5; // ecx

	if ( !leveltype )
	{
		pDungeonCels = LoadFileInMem("Levels\\TownData\\Town.CEL", 0);
		pMegaTiles = LoadFileInMem("Levels\\TownData\\Town.TIL", 0);
		v4 = LoadFileInMem("Levels\\TownData\\Town.MIN", 0);
		v5 = "Levels\\TownData\\TownS.CEL";
		goto LABEL_14;
	}
	if ( leveltype == 1 )
	{
		pDungeonCels = LoadFileInMem("Levels\\L1Data\\L1.CEL", 0);
		v2 = LoadFileInMem("Levels\\L1Data\\L1.TIL", 0);
		v3 = "Levels\\L1Data\\L1.MIN";
		goto LABEL_12;
	}
	if ( leveltype != 2 )
	{
		if ( leveltype != 3 )
		{
			if ( leveltype != 4 )
			{
				TermMsg("LoadLvlGFX");
				return;
			}
			pDungeonCels = LoadFileInMem("Levels\\L4Data\\L4.CEL", 0);
			v0 = LoadFileInMem("Levels\\L4Data\\L4.TIL", 0);
			v1 = "Levels\\L4Data\\L4.MIN";
			goto LABEL_10;
		}
		pDungeonCels = LoadFileInMem("Levels\\L3Data\\L3.CEL", 0);
		v2 = LoadFileInMem("Levels\\L3Data\\L3.TIL", 0);
		v3 = "Levels\\L3Data\\L3.MIN";
LABEL_12:
		pMegaTiles = v2;
		v4 = LoadFileInMem(v3, 0);
		v5 = "Levels\\L1Data\\L1S.CEL";
		goto LABEL_14;
	}
	pDungeonCels = LoadFileInMem("Levels\\L2Data\\L2.CEL", 0);
	v0 = LoadFileInMem("Levels\\L2Data\\L2.TIL", 0);
	v1 = "Levels\\L2Data\\L2.MIN";
LABEL_10:
	pMegaTiles = v0;
	v4 = LoadFileInMem(v1, 0);
	v5 = "Levels\\L2Data\\L2S.CEL";
LABEL_14:
	*(_DWORD *)&dpiece_defs[0].blocks = (unsigned int)v4;
	level_special_cel = LoadFileInMem(v5, 0);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0040A4B4) --------------------------------------------------------
void __cdecl LoadAllGFX()
{
	pSpeedCels = DiabloAllocPtr(0x100000);
	IncProgress();
	IncProgress();
	InitObjectGFX();
	IncProgress();
	InitMissileGFX();
	IncProgress();
}

//----- (0040A4E1) --------------------------------------------------------
void __fastcall CreateLevel(int entry)
{
	char v1; // cl
	char v2; // [esp-4h] [ebp-4h]

	if ( leveltype )
	{
		if ( leveltype == 1 )
		{
			CreateL5Dungeon(glSeedTbl[currlevel], entry);
			InitL1Triggers();
			Freeupstairs();
			v1 = 1;
		}
		else
		{
			switch ( leveltype )
			{
				case 2:
					CreateL2Dungeon(glSeedTbl[currlevel], entry);
					InitL2Triggers();
					Freeupstairs();
					v2 = 2;
					break;
				case 3:
					CreateL3Dungeon(glSeedTbl[currlevel], entry);
					InitL3Triggers();
					Freeupstairs();
					v2 = 3;
					break;
				case 4:
					CreateL4Dungeon(glSeedTbl[currlevel], entry);
					InitL4Triggers();
					Freeupstairs();
					v2 = 4;
					break;
				default:
					TermMsg("CreateLevel");
					return;
			}
			v1 = v2;
		}
	}
	else
	{
		CreateTown(entry);
		InitTownTriggers();
		v1 = 0;
	}
	LoadRndLvlPal(v1);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0040A5A4) --------------------------------------------------------
void __fastcall LoadGameLevel(bool from_save, int entry)
{
	int v2; // ebp
	int v3; // ebx
	int v4; // esi
	int *v5; // edi
	int v6; // eax
	BOOL v7; // edx
	int v8; // ecx
	int v9; // eax
	int v10; // ecx
	int v11; // eax
	bool v12; // zf
	char (*v13)[112]; // ecx
	signed int v14; // eax
	int *v15; // edi
	int v16; // ebx
	int *v17; // esi
	char *v18; // eax
	int v19; // eax
	BOOL FirstTime; // [esp+0h] [ebp-8h]
	int v21; // [esp+4h] [ebp-4h]

	v2 = 0;
	v3 = entry;
	v21 = entry;
	FirstTime = from_save;
	if ( setseed )
		glSeedTbl[currlevel] = setseed;
	music_stop();
	SetCursor(1);
	SetRndSeed(glSeedTbl[currlevel]);
	IncProgress();
	MakeLightTable();
	LoadLvlGFX();
	IncProgress();
	if ( FirstTime )
	{
		InitInv();
		InitItemGFX();
		InitQuestText();
		v4 = 0;
		if ( gbMaxPlayers )
		{
			do
				InitPlrGFXMem(v4++);
			while ( v4 < (unsigned char)gbMaxPlayers );
		}
		InitStores();
		InitAutomapOnce();
		InitHelp();
	}
	SetRndSeed(glSeedTbl[currlevel]);
	if ( !leveltype )
		SetupTownStores();
	IncProgress();
	InitAutomap();
	if ( leveltype && v3 != 4 )
	{
		InitLighting();
		InitVision();
	}
	InitLevelMonsters();
	IncProgress();
	if ( !setlevel )
	{
		CreateLevel(v3);
		IncProgress();
		FillSolidBlockTbls();
		SetRndSeed(glSeedTbl[currlevel]);
		if ( leveltype )
		{
			GetLevelMTypes();
			InitThemes();
			LoadAllGFX();
		}
		else
		{
			InitMissileGFX();
		}
		IncProgress();
		if ( v3 == 3 )
			GetReturnLvlPos();
		if ( v3 == 5 )
			GetPortalLvlPos();
		IncProgress();
		v5 = &plr[0].plrlevel;
		do
		{
			if ( *((_BYTE *)v5 - 23) )
			{
				if ( currlevel == *v5 )
				{
					InitPlayerGFX(v2);
					if ( v3 != 4 )
						InitPlayer(v2, FirstTime);
				}
			}
			v5 += 5430;
			++v2;
		}
		while ( (signed int)v5 < (signed int)&plr_msgs[0].player );
		PlayDungMsgs();
		InitMultiView();
		IncProgress();
		v6 = (unsigned char)gbMaxPlayers;
		v7 = 0;
		if ( (signed int)(unsigned char)gbMaxPlayers > 0 )
		{
			v8 = 0;
			do
			{
				if ( plr[v8].plractive[0] )
					v7 = v7 || plr[0]._pLvlVisited[currlevel + v8 * 21720];
				++v8;
				--v6;
			}
			while ( v6 );
		}
		SetRndSeed(glSeedTbl[currlevel]);
		if ( leveltype )
		{
			if ( FirstTime || v21 == 4 || !plr[myplr]._pLvlVisited[currlevel] || gbMaxPlayers != 1 )
			{
				HoldThemeRooms();
				glMid1Seed[currlevel] = GetRndSeed();
				InitMonsters();
				v9 = GetRndSeed();
				v10 = currlevel;
				glMid2Seed[v10] = v9;
				InitObjects(v10);
				InitItems();
				CreateThemeRooms();
				glMid3Seed[currlevel] = GetRndSeed();
				InitMissiles();
				InitDead();
				v11 = GetRndSeed();
				v12 = gbMaxPlayers == 1;
				glEndSeed[currlevel] = v11;
				if ( !v12 )
					DeltaLoadLevel();
				IncProgress();
				SavePreLighting();
				goto LABEL_55;
			}
			InitMonsters();
			InitMissiles();
			InitDead();
			IncProgress();
			LoadLevel();
LABEL_54:
			IncProgress();
LABEL_55:
			if ( gbMaxPlayers == 1 )
				ResyncQuests();
			else
				ResyncMPQuests();
			goto LABEL_72;
		}
		v13 = dFlags;
		do
		{
			v14 = 0;
			do
				(*v13)[v14++] |= 0x40u;
			while ( v14 < 112 );
			++v13;
		}
		while ( (signed int)v13 < (signed int)dItem );
		InitTowners();
		InitItems();
		InitMissiles();
		IncProgress();
		if ( !FirstTime && v21 != 4 && plr[myplr]._pLvlVisited[currlevel] )
		{
			if ( gbMaxPlayers != 1 )
				goto LABEL_53;
			LoadLevel();
		}
		if ( gbMaxPlayers == 1 )
			goto LABEL_54;
LABEL_53:
		DeltaLoadLevel();
		goto LABEL_54;
	}
	pSpeedCels = DiabloAllocPtr(0x100000);
	LoadSetMap();
	IncProgress();
	GetLevelMTypes();
	InitMonsters();
	InitMissileGFX();
	InitDead();
	FillSolidBlockTbls();
	IncProgress();
	if ( v3 == 5 )
		GetPortalLvlPos();
	v15 = &plr[0].plrlevel;
	do
	{
		if ( *((_BYTE *)v15 - 23) )
		{
			if ( currlevel == *v15 )
			{
				InitPlayerGFX(v2);
				if ( v3 != 4 )
					InitPlayer(v2, FirstTime);
			}
		}
		v15 += 5430;
		++v2;
	}
	while ( (signed int)v15 < (signed int)&plr_msgs[0].player );
	InitMultiView();
	IncProgress();
	if ( FirstTime || v3 == 4 || !plr[myplr]._pSLvlVisited[(unsigned char)setlvlnum] )
	{
		InitItems();
		SavePreLighting();
	}
	else
	{
		LoadLevel();
	}
	InitMissiles();
	IncProgress();
LABEL_72:
	SyncPortals();
	v16 = 0;
	v17 = &plr[0].plrlevel;
	do
	{
		if ( *((_BYTE *)v17 - 23) && *v17 == currlevel && (!*((_BYTE *)v17 + 267) || v16 == myplr) )
		{
			if ( v17[89] <= 0 )
			{
				v18 = &dFlags[v17[1]][v17[2]];
				*v18 |= 4u;
			}
			else if ( gbMaxPlayers == 1 )
			{
				dPlayer[v17[1]][v17[2]] = v16 + 1;
			}
			else
			{
				SyncInitPlrPos(v16);
			}
		}
		v17 += 5430;
		++v16;
	}
	while ( (signed int)v17 < (signed int)&plr_msgs[0].player );
	if ( leveltype )
		SetDungeonMicros();
	InitLightMax();
	IncProgress();
	IncProgress();
	if ( FirstTime )
	{
		InitControlPan();
		IncProgress();
	}
	if ( leveltype )
	{
		ProcessLightList();
		ProcessVisionList();
	}
	music_start((unsigned char)leveltype);
	do
		_LOBYTE(v19) = IncProgress();
	while ( !v19 );
	if ( setlevel && setlvlnum == SL_SKELKING && quests[12]._qactive == 2 )
		PlaySFX(USFX_SKING1);
}
// 525738: using guessed type int setseed;
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;
// 679660: using guessed type char gbMaxPlayers;

//----- (0040AAE3) --------------------------------------------------------
void __fastcall game_loop(bool startup)
{
	int v1; // ecx
	int v2; // esi
	int v3; // eax

	v1 = startup != 0 ? 0x39 : 0;
	v2 = v1 + 3;
	if ( v1 != -3 )
	{
		while ( 1 )
		{
			--v2;
			if ( !multi_handle_delta() )
				break;
			timeout_cursor(0);
			game_logic();
			if ( gbRunGame )
			{
				if ( gbMaxPlayers != 1 )
				{
					_LOBYTE(v3) = nthread_has_500ms_passed();
					if ( v3 )
					{
						if ( v2 )
							continue;
					}
				}
			}
			return;
		}
		timeout_cursor(1);
	}
}
// 525650: using guessed type int gbRunGame;
// 679660: using guessed type char gbMaxPlayers;

//----- (0040AB33) --------------------------------------------------------
void __cdecl game_logic()
{
	int v0; // eax
	int v1; // eax

	if ( PauseMode != 2 )
	{
		if ( PauseMode == 1 )
			PauseMode = 2;
		if ( gbMaxPlayers == 1 && (_LOBYTE(v0) = gmenu_exception(), v0) )
		{
			force_redraw |= 1u;
		}
		else
		{
			_LOBYTE(v1) = gmenu_exception();
			if ( !v1 && sgnTimeoutCurs == CURSOR_NONE )
			{
				CheckCursMove();
				track_repeat_walk();
			}
			if ( gbProcessPlayers )
				ProcessPlayers();
			if ( leveltype )
			{
				ProcessMonsters();
				ProcessObjects();
				ProcessMissiles();
				ProcessItems();
				ProcessLightList();
				ProcessVisionList();
			}
			else
			{
				ProcessTowners();
				ProcessItems();
				ProcessMissiles();
			}
			sound_update();
			ClearPlrMsg();
			CheckTriggers();
			CheckQuests();
			force_redraw |= 1u;
			pfile_update(0);
		}
	}
}
// 5256A0: using guessed type int gbProcessPlayers;
// 525718: using guessed type char cineflag;
// 52571C: using guessed type int force_redraw;
// 525740: using guessed type int PauseMode;
// 5BB1ED: using guessed type char leveltype;
// 679660: using guessed type char gbMaxPlayers;

//----- (0040ABE7) --------------------------------------------------------
void __fastcall timeout_cursor(bool timeout)
{
	if ( timeout )
	{
		if ( sgnTimeoutCurs == CURSOR_NONE && !sgbMouseDown )
		{
			sgnTimeoutCurs = pcurs;
			multi_net_ping();
			ClearPanel();
			AddPanelString("-- Network timeout --", 1);
			AddPanelString("-- Waiting for players --", 1);
			SetCursor(11);
			force_redraw = 255;
		}
		scrollrt_455E65(1);
	}
	else if ( sgnTimeoutCurs )
	{
		SetCursor(sgnTimeoutCurs);
		sgnTimeoutCurs = 0;
		ClearPanel();
		force_redraw = 255;
	}
}
// 52571C: using guessed type int force_redraw;
// 525748: using guessed type char sgbMouseDown;

//----- (0040AC6B) --------------------------------------------------------
void __cdecl diablo_color_cyc_logic()
{
	DWORD v0; // eax
	int v1; // eax

	v0 = GetTickCount();
	if ( v0 - dword_52574C >= 0x32 )
	{
		dword_52574C = v0;
		_LOBYTE(v1) = palette_get_colour_cycling();
		if ( v1 )
		{
			if ( leveltype == 4 )
			{
				lighting_color_cycling();
			}
			else if ( leveltype == 3 )
			{
				if ( exclusive )
					palette_update_caves();
			}
		}
	}
}
// 484364: using guessed type int exclusive;
// 52574C: using guessed type int dword_52574C;
// 5BB1ED: using guessed type char leveltype;

//----- (0040ACAD) --------------------------------------------------------
int __cdecl doom_get_frame_from_time()
{
	int result; // eax

	if ( dword_525760 == 36001 )
		result = 31;
	else
		result = dword_525760 / 1200;
	return result;
}

//----- (0040ACC6) --------------------------------------------------------
void __cdecl doom_alloc_cel()
{
	pDoomCel = DiabloAllocPtr(229376);
}

//----- (0040ACD6) --------------------------------------------------------
void __cdecl doom_cleanup()
{
	void *v0; // ecx

	v0 = pDoomCel;
	pDoomCel = 0;
	mem_free_dbg(v0);
}

//----- (0040ACE8) --------------------------------------------------------
void __cdecl doom_load_graphics()
{
	if ( dword_525750 == 31 )
	{
		strcpy(tempstr, "Items\\Map\\MapZDoom.CEL");
	}
	else if ( dword_525750 >= 10 )
	{
		sprintf(tempstr, "Items\\Map\\MapZ00%i.CEL", dword_525750);
	}
	else
	{
		sprintf(tempstr, "Items\\Map\\MapZ000%i.CEL", dword_525750);
	}
	LoadFileWithMem(tempstr, pDoomCel);
}
// 525750: using guessed type int dword_525750;

//----- (0040AD34) --------------------------------------------------------
void __cdecl doom_init()
{
	int v0; // eax

	doomflag = 1;
	doom_alloc_cel();
	v0 = -(doom_get_frame_from_time() != 31);
	_LOBYTE(v0) = v0 & 0xE1;
	dword_525750 = v0 + 31;
	doom_load_graphics();
}
// 525750: using guessed type int dword_525750;
// 52575C: using guessed type int doomflag;

//----- (0040AD5E) --------------------------------------------------------
void __cdecl doom_close()
{
	if ( doomflag )
	{
		doomflag = 0;
		doom_cleanup();
	}
}
// 52575C: using guessed type int doomflag;

//----- (0040AD74) --------------------------------------------------------
void __cdecl doom_draw()
{
	if ( doomflag )
	{
		if ( dword_525750 != 31 && ++dword_525754 >= 5 )
		{
			dword_525754 = 0;
			if ( ++dword_525750 > doom_get_frame_from_time() )
				dword_525750 = 0;
			doom_load_graphics();
		}
		Cel_decode(64, 511, pDoomCel, 1, 640);
	}
}
// 525750: using guessed type int dword_525750;
// 525754: using guessed type int dword_525754;
// 52575C: using guessed type int doomflag;

//----- (0040ADD6) --------------------------------------------------------
void __cdecl DRLG_Init_Globals()
{
	char v0; // al

	memset(dFlags, 0, 0x3100u);
	memset(dPlayer, 0, 0x3100u);
	memset(dMonster, 0, 0xC400u);
	memset(dDead, 0, 0x3100u);
	memset(dObject, 0, 0x3100u);
	memset(dItem, 0, 0x3100u);
	memset(dMissile, 0, 0x3100u);
	memset(dArch, 0, 0x3100u);
	if ( lightflag )
		v0 = 0;
	else
		v0 = light4flag == 0 ? 15 : 3;
	memset(dTransVal, v0, 0x3100u);
}
// 525728: using guessed type int light4flag;
// 646A28: using guessed type int lightflag;

//----- (0040AE79) --------------------------------------------------------
void __fastcall LoadL1Dungeon(char *dun_path, int view_x, int view_y)
{
	char *v3; // esi
	unsigned char *v4; // esi
	signed int v5; // ecx
	signed int v6; // eax
	signed int v7; // edx
	int v8; // edi
	int v9; // ebx
	char *v10; // eax
	int v11; // ecx
	char v12; // dl
	int v13; // [esp+Ch] [ebp-Ch]
	int v14; // [esp+10h] [ebp-8h]
	int v15; // [esp+14h] [ebp-4h]

	v13 = view_x;
	dminx = 16;
	dminy = 16;
	v3 = dun_path;
	dmaxx = 96;
	dmaxy = 96;
	DRLG_InitTrans();
	v4 = LoadFileInMem(v3, 0);
	v5 = 0;
	do
	{
		v6 = v5;
		v7 = 40;
		do
		{
			mydflags[0][v6] = 0;
			dungeon[0][v6] = 22;
			v6 += 40;
			--v7;
		}
		while ( v7 );
		++v5;
	}
	while ( v5 < 40 );
	v15 = 0;
	v8 = *v4;
	v9 = v4[2];
	v10 = (char *)(v4 + 4);
	if ( v9 > 0 )
	{
		do
		{
			if ( v8 > 0 )
			{
				v11 = v15;
				v14 = v8;
				do
				{
					v12 = *v10;
					if ( *v10 )
					{
						mydflags[0][v11] |= 0x80u;
						dungeon[0][v11] = v12;
					}
					else
					{
						dungeon[0][v11] = 13;
					}
					v11 += 40;
					v10 += 2;
					--v14;
				}
				while ( v14 );
			}
			++v15;
		}
		while ( v15 < v9 );
	}
	DRLG_L1Floor();
	ViewX = v13;
	ViewY = view_y;
	DRLG_L1Pass3();
	DRLG_Init_Globals();
	DRLG_InitL1Vals();
	SetMapMonsters((char *)v4, 0, 0);
	SetMapObjects((char *)v4, 0, 0);
	mem_free_dbg(v4);
}
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;

//----- (0040AF65) --------------------------------------------------------
void __cdecl DRLG_L1Floor()
{
	signed int v0; // edi
	signed int v1; // esi
	signed int v2; // ebx
	int v3; // eax

	v0 = 0;
	do
	{
		v1 = v0;
		v2 = 40;
		do
		{
			if ( !mydflags[0][v1] && dungeon[0][v1] == 13 )
			{
				v3 = random(0, 3);
				if ( v3 == 1 )
					dungeon[0][v1] = -94;
				if ( v3 == 2 )
					dungeon[0][v1] = -93;
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040AFB3) --------------------------------------------------------
void __cdecl DRLG_L1Pass3()
{
	int v0; // eax
	int *v1; // edx
	int *v2; // eax
	signed int v3; // ecx
	signed int v4; // ebx
	int *v5; // ecx
	unsigned char *v6; // edx
	unsigned short *v7; // esi
	unsigned short v8; // ax
	int v9; // eax
	int v10; // ST24_4
	int v11; // ST20_4
	int v12; // ST1C_4
	signed int v13; // [esp+Ch] [ebp-1Ch]
	int *v14; // [esp+10h] [ebp-18h]
	int v15; // [esp+14h] [ebp-14h]
	int v16; // [esp+18h] [ebp-10h]
	int v17; // [esp+1Ch] [ebp-Ch]
	int v18; // [esp+20h] [ebp-8h]

	v0 = *((unsigned short *)pMegaTiles + 84) + 1;
	v18 = *((unsigned short *)pMegaTiles + 84) + 1;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 85);
	v17 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 86);
	v16 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 87);
	v15 = v0 + 1;
	v1 = dPiece[1];
	do
	{
		v2 = v1;
		v3 = 56;
		do
		{
			*(v2 - 112) = v18;
			*v2 = v17;
			*(v2 - 111) = v16;
			v2[1] = v15;
			v2 += 224;
			--v3;
		}
		while ( v3 );
		v1 += 2;
	}
	while ( (signed int)v1 < (signed int)dPiece[2] );
	v4 = 0;
	v14 = &dPiece[17][16];
	do
	{
		v5 = v14;
		v6 = (unsigned char *)dungeon + v4;
		v13 = 40;
		do
		{
			v7 = (unsigned short *)((char *)pMegaTiles + 8 * (*v6 - 1));
			v8 = *v7;
			++v7;
			v9 = v8 + 1;
			v10 = v9;
			_LOWORD(v9) = *v7;
			++v7;
			v11 = ++v9;
			_LOWORD(v9) = *v7;
			v12 = ++v9;
			_LOWORD(v9) = v7[1];
			v6 += 40;
			*(v5 - 112) = v10;
			*v5 = v11;
			*(v5 - 111) = v12;
			v5[1] = v9 + 1;
			v5 += 224;
			--v13;
		}
		while ( v13 );
		v14 += 2;
		++v4;
	}
	while ( v4 < 40 );
}

//----- (0040B0A5) --------------------------------------------------------
void __cdecl DRLG_InitL1Vals()
{
	int v0; // esi
	int (*v1)[112]; // edx
	char *v2; // ecx
	int v3; // eax
	char v4; // al
	char v5; // [esp-4h] [ebp-18h]
	signed int v6; // [esp+Ch] [ebp-8h]
	int (*v7)[112]; // [esp+10h] [ebp-4h]

	v0 = 0;
	v7 = dPiece;
	do
	{
		v1 = v7;
		v2 = (char *)dArch + v0;
		v6 = 112;
		do
		{
			v3 = (*v1)[0];
			if ( (*v1)[0] != 12 )
			{
				if ( v3 == 11 )
					goto LABEL_21;
				if ( v3 != 71 )
				{
					if ( v3 == 259 )
					{
						v5 = 5;
LABEL_9:
						v4 = v5;
						goto LABEL_22;
					}
					if ( v3 == 249 || v3 == 325 )
						goto LABEL_21;
					if ( v3 != 321 )
					{
						if ( v3 == 255 )
						{
							v5 = 4;
							goto LABEL_9;
						}
						if ( v3 != 211 )
						{
							if ( v3 == 344 )
								goto LABEL_21;
							if ( v3 != 341 )
							{
								if ( v3 == 331 )
									goto LABEL_21;
								if ( v3 != 418 )
								{
									if ( v3 != 421 )
										goto LABEL_23;
LABEL_21:
									v4 = 2;
									goto LABEL_22;
								}
							}
						}
					}
				}
			}
			v4 = 1;
LABEL_22:
			*v2 = v4;
LABEL_23:
			++v1;
			v2 += 112;
			--v6;
		}
		while ( v6 );
		v7 = (int (*)[112])((char *)v7 + 4);
		++v0;
	}
	while ( (signed int)v7 < (signed int)dPiece[1] );
}

//----- (0040B160) --------------------------------------------------------
void __fastcall LoadPreL1Dungeon(char *dun_path, int view_x, int view_y)
{
	unsigned char *v3; // ebx
	signed int v4; // ecx
	signed int v5; // eax
	signed int v6; // edx
	int v7; // esi
	int v8; // edi
	char *v9; // eax
	int v10; // ecx
	char v11; // dl
	signed int v12; // esi
	signed int v13; // eax
	signed int v14; // edi
	int v15; // [esp+Ch] [ebp-8h]
	int v16; // [esp+10h] [ebp-4h]

	dminx = 16;
	dminy = 16;
	dmaxx = 96;
	dmaxy = 96;
	v3 = LoadFileInMem(dun_path, 0);
	v4 = 0;
	do
	{
		v5 = v4;
		v6 = 40;
		do
		{
			mydflags[0][v5] = 0;
			dungeon[0][v5] = 22;
			v5 += 40;
			--v6;
		}
		while ( v6 );
		++v4;
	}
	while ( v4 < 40 );
	v16 = 0;
	v7 = *v3;
	v8 = v3[2];
	v9 = (char *)(v3 + 4);
	if ( v8 > 0 )
	{
		do
		{
			if ( v7 > 0 )
			{
				v10 = v16;
				v15 = v7;
				do
				{
					v11 = *v9;
					if ( *v9 )
					{
						mydflags[0][v10] |= 0x80u;
						dungeon[0][v10] = v11;
					}
					else
					{
						dungeon[0][v10] = 13;
					}
					v10 += 40;
					v9 += 2;
					--v15;
				}
				while ( v15 );
			}
			++v16;
		}
		while ( v16 < v8 );
	}
	DRLG_L1Floor();
	v12 = 0;
	do
	{
		v13 = v12;
		v14 = 40;
		do
		{
			pdungeon[0][v13] = dungeon[0][v13];
			v13 += 40;
			--v14;
		}
		while ( v14 );
		++v12;
	}
	while ( v12 < 40 );
	mem_free_dbg(v3);
}
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;

//----- (0040B229) --------------------------------------------------------
void __fastcall CreateL5Dungeon(int seed, int entry)
{
	int v2; // esi

	v2 = entry;
	SetRndSeed(seed);
	dminx = 16;
	dminy = 16;
	dmaxx = 96;
	dmaxy = 96;
	DRLG_InitTrans();
	DRLG_InitSetPC();
	DRLG_LoadL1SP();
	DRLG_L5(v2);
	DRLG_L1Pass3();
	DRLG_FreeL1SP();
	DRLG_InitL1Vals();
	DRLG_SetPC();
}
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;

//----- (0040B276) --------------------------------------------------------
void __cdecl DRLG_LoadL1SP()
{
	int v0; // eax
	int v1; // eax
	int v2; // eax

	setloadflag = 0;
	_LOBYTE(v0) = QuestStatus(6);
	if ( v0 )
	{
		pSetPiece = LoadFileInMem("Levels\\L1Data\\rnd6.DUN", 0);
		setloadflag = 1;
	}
	_LOBYTE(v1) = QuestStatus(12);
	if ( v1 && gbMaxPlayers == 1 )
	{
		pSetPiece = LoadFileInMem("Levels\\L1Data\\SKngDO.DUN", 0);
		setloadflag = 1;
	}
	_LOBYTE(v2) = QuestStatus(7);
	if ( v2 )
	{
		pSetPiece = LoadFileInMem("Levels\\L1Data\\Banner2.DUN", 0);
		setloadflag = 1;
	}
}
// 5276A4: using guessed type int setloadflag;
// 679660: using guessed type char gbMaxPlayers;

//----- (0040B2F4) --------------------------------------------------------
void __cdecl DRLG_FreeL1SP()
{
	void *v0; // ecx

	v0 = pSetPiece;
	pSetPiece = 0;
	mem_free_dbg(v0);
}

//----- (0040B306) --------------------------------------------------------
void __fastcall DRLG_L5(int entry)
{
	signed int v1; // esi
	signed int v2; // edi
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // ebx
	int v7; // edi
	int v8; // edi
	int v9; // ebp
	_BYTE *v10; // ebx
	signed int v11; // eax
	signed int v12; // ecx
	int v13; // [esp+10h] [ebp-8h]
	int v14; // [esp+10h] [ebp-8h]
	int v15; // [esp+14h] [ebp-4h]
	_BYTE *v16; // [esp+14h] [ebp-4h]

	v13 = entry;
	if ( currlevel == 1 )
	{
		v15 = 533;
	}
	else if ( currlevel == 2 )
	{
		v15 = 693;
	}
	else if ( currlevel > 2u && currlevel <= 4u )
	{
		v15 = 761;
	}
	v1 = 0;
	while ( 1 )
	{
		DRLG_InitTrans();
		do
		{
			InitL5Dungeon();
			L5firstRoom();
		}
		while ( L5GetArea() < v15 );
		L5makeDungeon();
		L5makeDmt();
		L5FillChambers();
		L5tileFix();
		L5AddWall();
		L5ClearFlags();
		DRLG_L5FloodTVal();
		v2 = 1;
		_LOBYTE(v3) = QuestStatus(13);
		if ( v3 )
		{
			if ( v13 )
			{
				if ( DRLG_PlaceMiniSet((char *)PWATERIN, 1, 1, 0, 0, 0, -1, 0) < 0 )
					v2 = 0;
				--ViewY;
			}
			else if ( DRLG_PlaceMiniSet((char *)PWATERIN, 1, 1, 0, 0, 1, -1, 0) < 0 )
			{
				v2 = 0;
			}
		}
		_LOBYTE(v4) = QuestStatus(7);
		if ( v4 )
		{
			if ( !v13 )
			{
				v5 = DRLG_PlaceMiniSet((char *)STAIRSUP, 1, 1, 0, 0, 1, -1, 0);
				goto LABEL_21;
			}
			if ( DRLG_PlaceMiniSet((char *)STAIRSUP, 1, 1, 0, 0, 0, -1, 0) < 0 )
				v2 = 0;
			if ( v13 == 1 )
			{
				ViewX = 2 * setpc_x + 20;
				ViewY = 2 * setpc_y + 28;
				goto LABEL_34;
			}
LABEL_33:
			--ViewY;
			goto LABEL_34;
		}
		if ( v13 )
		{
			if ( DRLG_PlaceMiniSet((char *)L5STAIRSUP, 1, 1, 0, 0, 0, -1, 0) < 0
			  || DRLG_PlaceMiniSet((char *)STAIRSDOWN, 1, 1, 0, 0, 1, -1, 1) < 0 )
			{
				v2 = 0;
			}
			goto LABEL_33;
		}
		if ( DRLG_PlaceMiniSet((char *)L5STAIRSUP, 1, 1, 0, 0, 1, -1, 0) >= 0 )
		{
			v5 = DRLG_PlaceMiniSet((char *)STAIRSDOWN, 1, 1, 0, 0, 0, -1, 1);
LABEL_21:
			if ( v5 < 0 )
				v2 = 0;
LABEL_34:
			if ( v2 )
				break;
		}
	}
	v14 = 0;
	v6 = 16;
	do
	{
		v7 = 16;
		v16 = (unsigned char *)dungeon + v14;
		do
		{
			if ( *v16 == 64 )
			{
				DRLG_CopyTrans(v7, v6 + 1, v7, v6);
				DRLG_CopyTrans(v7 + 1, v6 + 1, v7 + 1, v6);
			}
			v16 += 40;
			v7 += 2;
		}
		while ( v7 < 96 );
		++v14;
		v6 += 2;
	}
	while ( v6 < 96 );
	DRLG_L5TransFix();
	DRLG_L5DirtFix();
	DRLG_L5CornerFix();
	v8 = 0;
	do
	{
		v9 = 0;
		v10 = (unsigned char *)mydflags + v8;
		do
		{
			if ( *v10 & 0x7F )
				DRLG_PlaceDoor(v9, v8);
			++v9;
			v10 += 40;
		}
		while ( v9 < 40 );
		++v8;
	}
	while ( v8 < 40 );
	DRLG_L5Subs();
	DRLG_L1Shadows();
	DRLG_PlaceMiniSet((char *)LAMPS, 5, 10, 0, 0, 0, -1, 4);
	DRLG_L1Floor();
	do
	{
		v11 = v1;
		v12 = 40;
		do
		{
			pdungeon[0][v11] = dungeon[0][v11];
			v11 += 40;
			--v12;
		}
		while ( v12 );
		++v1;
	}
	while ( v1 < 40 );
	DRLG_Init_Globals();
	DRLG_CheckQuests(setpc_x, setpc_y);
}

//----- (0040B56F) --------------------------------------------------------
void __fastcall DRLG_PlaceDoor(int tx, int ty)
{
	int v2; // edi
	char *v3; // eax
	char v4; // al
	char v5; // dl
	char *v6; // eax
	char v7; // bl
	char *v8; // [esp+Ch] [ebp-8h]

	v2 = ty;
	v3 = &mydflags[tx][ty];
	v8 = v3;
	v4 = *v3;
	if ( v4 < 0 )
		goto LABEL_57;
	v5 = v4 & 0x7F;
	v6 = &dungeon[tx][v2];
	v7 = *v6;
	if ( v5 == 1 )
	{
		if ( v2 != 1 )
		{
			if ( v7 == 2 )
				*v6 = 26;
			if ( v7 == 7 )
				*v6 = 31;
			if ( v7 == 14 )
				*v6 = 42;
			if ( v7 == 4 )
				*v6 = 43;
		}
		if ( tx == 1 )
			goto LABEL_57;
		if ( v7 == 1 )
			*v6 = 25;
		if ( v7 == 10 )
			*v6 = 40;
		if ( v7 != 6 )
			goto LABEL_57;
		*v6 = 30;
	}
	if ( v5 != 2 )
		goto LABEL_36;
	if ( tx != 1 )
	{
		if ( v7 == 1 )
			*v6 = 25;
		if ( v7 == 6 )
			*v6 = 30;
		if ( v7 == 10 )
			*v6 = 40;
		if ( v7 == 4 )
			*v6 = 41;
	}
	if ( v2 != 1 )
	{
		if ( v7 == 2 )
			*v6 = 26;
		if ( v7 == 14 )
			*v6 = 42;
		if ( v7 == 7 )
		{
			*v6 = 31;
LABEL_36:
			if ( v5 == 3 )
			{
				if ( tx != 1 )
				{
					if ( v2 != 1 && v7 == 4 )
						*v6 = 28;
					if ( v7 == 10 )
						*v6 = 40;
				}
				if ( v2 != 1 )
				{
					if ( v7 == 14 )
						*v6 = 42;
					if ( v7 == 2 )
						*v6 = 26;
				}
				if ( tx != 1 && v7 == 1 )
					*v6 = 25;
				if ( v2 != 1 && v7 == 7 )
					*v6 = 31;
				if ( tx != 1 && v7 == 6 )
					*v6 = 30;
			}
			goto LABEL_57;
		}
	}
LABEL_57:
	*v8 = -128;
}

//----- (0040B699) --------------------------------------------------------
void __cdecl DRLG_L1Shadows()
{
	signed int v0; // ebx
	char *v1; // eax
	signed int v2; // edx
	unsigned char *v3; // esi
	signed int v4; // edi
	char v5; // cl
	char v6; // cl
	char v7; // cl
	char v8; // cl
	char v9; // cl
	signed int v10; // edi
	signed int v11; // eax
	signed int v12; // esi
	char v13; // cl
	char v14; // dl
	char v15; // cl
	char v16; // dl
	char v17; // cl
	char v18; // dl
	unsigned char v19; // [esp+Ch] [ebp-4h]
	unsigned char v20; // [esp+Dh] [ebp-3h]
	unsigned char v21; // [esp+Eh] [ebp-2h]
	unsigned char v22; // [esp+Fh] [ebp-1h]

	v0 = 1;
	do
	{
		v1 = &dungeon[0][v0 + 39];
		v2 = 40;
		do
		{
			v3 = &SPATS[0].s1;
			v19 = BSTYPES[(unsigned char)v1[1]];
			v21 = BSTYPES[(unsigned char)*(v1 - 39)];
			v20 = BSTYPES[(unsigned char)*v1];
			v22 = BSTYPES[(unsigned char)*(v1 - 40)];
			do
			{
				if ( *(v3 - 1) == v19 )
				{
					v4 = 1;
					if ( *v3 && *v3 != v22 )
						v4 = 0;
					v5 = v3[1];
					if ( v5 && v5 != v20 )
						v4 = 0;
					v6 = v3[2];
					if ( v6 && v6 != v21 )
						v4 = 0;
					if ( v4 == 1 )
					{
						v7 = v3[3];
						if ( v7 && !L5dungeon[79][v2 + 39 + v0] )
							*(v1 - 40) = v7;
						v8 = v3[4];
						if ( v8 && !L5dungeon[79][v2 + 79 + v0] )
							*v1 = v8;
						v9 = v3[5];
						if ( v9 && !L5dungeon[79][v2 + 40 + v0] )
							*(v1 - 39) = v9;
					}
				}
				v3 += 7;
			}
			while ( (signed int)v3 < (signed int)BSTYPES );
			v2 += 40;
			v1 += 40;
		}
		while ( v2 < 1600 );
		++v0;
	}
	while ( v0 < 40 );
	v10 = 1;
	do
	{
		v11 = v10;
		v12 = 39;
		do
		{
			if ( dungeon[0][v11] == -117 && !mydflags[0][v11] )
			{
				v13 = dungeon[1][v11];
				v14 = -117;
				if ( v13 == 29 )
					v14 = -115;
				if ( v13 == 32 )
					v14 = -115;
				if ( v13 == 35 )
					v14 = -115;
				if ( v13 == 37 )
					v14 = -115;
				if ( v13 == 38 )
					v14 = -115;
				if ( v13 == 39 )
					v14 = -115;
				dungeon[0][v11] = v14;
			}
			if ( dungeon[0][v11] == -107 && !mydflags[0][v11] )
			{
				v15 = dungeon[1][v11];
				v16 = -107;
				if ( v15 == 29 )
					v16 = -103;
				if ( v15 == 32 )
					v16 = -103;
				if ( v15 == 35 )
					v16 = -103;
				if ( v15 == 37 )
					v16 = -103;
				if ( v15 == 38 )
					v16 = -103;
				if ( v15 == 39 )
					v16 = -103;
				dungeon[0][v11] = v16;
			}
			if ( dungeon[0][v11] == -108 && !mydflags[0][v11] )
			{
				v17 = dungeon[1][v11];
				v18 = -108;
				if ( v17 == 29 )
					v18 = -102;
				if ( v17 == 32 )
					v18 = -102;
				if ( v17 == 35 )
					v18 = -102;
				if ( v17 == 37 )
					v18 = -102;
				if ( v17 == 38 )
					v18 = -102;
				if ( v17 == 39 )
					v18 = -102;
				dungeon[0][v11] = v18;
			}
			v11 += 40;
			--v12;
		}
		while ( v12 );
		++v10;
	}
	while ( v10 < 40 );
}

//----- (0040B881) --------------------------------------------------------
int __fastcall DRLG_PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int noquad, int ldir)
{
	unsigned char *v8; // ebx
	int v9; // edi
	int v10; // esi
	int v11; // edx
	int v12; // eax
	int v13; // ecx
	int v14; // esi
	int v15; // edi
	int v16; // ebx
	signed int v17; // edx
	int v18; // eax
	char v19; // cl
	int v20; // ebx
	int result; // eax
	int v22; // eax
	char v23; // dl
	char v24; // bl
	bool v25; // zf
	bool v26; // sf
	unsigned char v27; // of
	int v28; // [esp-4h] [ebp-34h]
	int v29; // [esp+Ch] [ebp-24h]
	char *v30; // [esp+10h] [ebp-20h]
	int v31; // [esp+14h] [ebp-1Ch]
	int v32; // [esp+18h] [ebp-18h]
	int v33; // [esp+1Ch] [ebp-14h]
	signed int v34; // [esp+20h] [ebp-10h]
	int max; // [esp+24h] [ebp-Ch]
	int v36; // [esp+28h] [ebp-8h]
	int v37; // [esp+2Ch] [ebp-4h]
	int tmaxa; // [esp+38h] [ebp+8h]
	int tmaxb; // [esp+38h] [ebp+8h]

	v8 = (unsigned char *)miniset;
	v9 = (unsigned char)*miniset;
	v10 = tmin;
	v11 = tmax - tmin;
	v30 = miniset;
	v36 = (unsigned char)*miniset;
	v37 = (unsigned char)miniset[1];
	if ( v11 )
	{
		_LOBYTE(miniset) = 0;
		v31 = v10 + random((int)miniset, v11);
	}
	else
	{
		v31 = 1;
	}
	v32 = 0;
	if ( v31 > 0 )
	{
		max = 40 - v9;
		v29 = 40 - v37;
		while ( 1 )
		{
			_LOBYTE(miniset) = 0;
			v12 = random((int)miniset, max);
			_LOBYTE(v13) = 0;
			v14 = v12;
			v33 = 0;
			v15 = random(v13, v29);
			while ( 1 )
			{
				tmaxa = 1;
				if ( cx != -1 && v14 >= cx - v36 && v14 <= cx + 12 )
				{
					++v14;
					tmaxa = 0;
				}
				miniset = (char *)cy;
				if ( cy != -1 && v15 >= cy - v37 && v15 <= cy + 12 )
				{
					++v15;
					tmaxa = 0;
				}
				v16 = 0;
				switch ( noquad )
				{
					case 0:
						if ( v14 >= cx )
							goto LABEL_29;
						goto LABEL_27;
					case 1:
						if ( v14 <= cx )
							goto LABEL_29;
LABEL_27:
						if ( v15 >= cy )
							goto LABEL_29;
LABEL_28:
						tmaxa = 0;
						goto LABEL_29;
					case 2:
						if ( v14 >= cx )
							goto LABEL_29;
LABEL_22:
						if ( v15 <= cy )
							goto LABEL_29;
						goto LABEL_28;
				}
				if ( noquad == 3 && v14 > cx )
					goto LABEL_22;
LABEL_29:
				v17 = 2;
				if ( v37 > 0 )
				{
					do
					{
						if ( tmaxa != 1 )
							break;
						v34 = 0;
						if ( v36 > 0 )
						{
							v18 = v15 + v16 + 40 * v14;
							do
							{
								if ( tmaxa != 1 )
									break;
								v19 = v30[v17];
								if ( v19 && dungeon[0][v18] != v19 )
									tmaxa = 0;
								if ( mydflags[0][v18] )
									tmaxa = 0;
								miniset = (char *)v36;
								++v17;
								++v34;
								v18 += 40;
							}
							while ( v34 < v36 );
						}
						++v16;
					}
					while ( v16 < v37 );
				}
				v20 = 0;
				if ( tmaxa )
					break;
				if ( ++v14 == max )
				{
					v14 = 0;
					if ( ++v15 == v29 )
						v15 = 0;
				}
				if ( ++v33 > 4000 )
					return -1;
			}
			v22 = v36 * v37 + 2;
			if ( v37 > 0 )
			{
				do
				{
					if ( v36 > 0 )
					{
						tmaxb = v36;
						miniset = &dungeon[v14][v20 + v15];
						do
						{
							v23 = v30[v22];
							if ( v23 )
								*miniset = v23;
							++v22;
							miniset += 40;
							--tmaxb;
						}
						while ( tmaxb );
					}
					++v20;
				}
				while ( v20 < v37 );
			}
			if ( ++v32 >= v31 )
			{
				v8 = (unsigned char *)v30;
				goto LABEL_57;
			}
		}
	}
	v14 = cx;
	v15 = cx;
LABEL_57:
	if ( v8 == PWATERIN )
	{
		v24 = TransVal;
		TransVal = 0;
		Make_RectTrans(v14, v15 + 2, v14 + 5, v15 + 4);
		TransVal = v24;
		quests[13]._qtx = 2 * v14 + 21;
		quests[13]._qty = 2 * v15 + 22;
	}
	result = 1;
	if ( set_view == 1 )
	{
		ViewX = 2 * v14 + 19;
		ViewY = 2 * v15 + 20;
	}
	if ( !ldir )
	{
		LvlViewX = 2 * v14 + 19;
		LvlViewY = 2 * v15 + 20;
	}
	v27 = __OFSUB__(v14, cx);
	v25 = v14 == cx;
	v26 = v14 - cx < 0;
	if ( v14 < cx )
	{
		if ( v15 < cy )
			return 0;
		v27 = __OFSUB__(v14, cx);
		v25 = v14 == cx;
		v26 = v14 - cx < 0;
	}
	if ( (unsigned char)(v26 ^ v27) | v25 || v15 >= cy )
	{
		if ( v14 >= cx || v15 <= cy )
			v28 = 3;
		else
			v28 = 2;
		result = v28;
	}
	return result;
}
// 5A5590: using guessed type char TransVal;
// 5CF320: using guessed type int LvlViewY;
// 5CF324: using guessed type int LvlViewX;

//----- (0040BAF6) --------------------------------------------------------
void __cdecl InitL5Dungeon()
{
	signed int v0; // edx
	signed int v1; // eax
	signed int v2; // ecx

	v0 = 0;
	do
	{
		v1 = v0;
		v2 = 40;
		do
		{
			dungeon[0][v1] = 0;
			mydflags[0][v1] = 0;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040BB18) --------------------------------------------------------
void __cdecl L5ClearFlags()
{
	signed int v0; // ecx
	_BYTE *v1; // eax
	signed int v2; // edx

	v0 = 0;
	do
	{
		v1 = (unsigned char *)mydflags + v0;
		v2 = 40;
		do
		{
			*v1 &= 0xBFu;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040BB33) --------------------------------------------------------
void __cdecl L5firstRoom()
{
	signed int v0; // ebx
	signed int v1; // ebp
	signed int i; // ecx
	char *v3; // eax
	signed int v4; // ebp
	signed int v5; // ebx
	int v6; // ebp
	_BYTE *v7; // eax

	if ( random(0, 2) )
	{
		v4 = 39;
		v5 = 1;
		HR1 = random(0, 2);
		HR2 = random(0, 2);
		HR3 = random(0, 2);
		if ( HR1 + HR3 <= 1 )
			HR2 = 1;
		if ( HR1 )
			L5drawRoom(1, 15, 10, 10);
		else
			v5 = 18;
		if ( HR2 )
			L5drawRoom(15, 15, 10, 10);
		if ( HR3 )
			L5drawRoom(29, 15, 10, 10);
		else
			v4 = 22;
		if ( v5 < v4 )
		{
			v6 = v4 - v5;
			v7 = (_BYTE *)(40 * v5 + 5477914);
			do
			{
				*(v7 - 1) = 1;
				*v7 = 1;
				v7[1] = 1;
				v7[2] = 1;
				v7[3] = 1;
				v7[4] = 1;
				v7 += 40;
				--v6;
			}
			while ( v6 );
		}
		if ( HR1 )
			L5roomGen(1, 15, 10, 10, 1);
		if ( HR2 )
			L5roomGen(15, 15, 10, 10, 1);
		if ( HR3 )
			L5roomGen(29, 15, 10, 10, 1);
		VR3 = 0;
		VR2 = 0;
		VR1 = 0;
	}
	else
	{
		v0 = 39;
		v1 = 1;
		VR1 = random(0, 2);
		VR2 = random(0, 2);
		VR3 = random(0, 2);
		if ( VR1 + VR3 <= 1 )
			VR2 = 1;
		if ( VR1 )
			L5drawRoom(15, 1, 10, 10);
		else
			v1 = 18;
		if ( VR2 )
			L5drawRoom(15, 15, 10, 10);
		if ( VR3 )
			L5drawRoom(15, 29, 10, 10);
		else
			v0 = 22;
		for ( i = v1; i < v0; v3[160] = 1 )
		{
			v3 = &dungeon[18][i++];
			*(v3 - 40) = 1;
			*v3 = 1;
			v3[40] = 1;
			v3[80] = 1;
			v3[120] = 1;
		}
		if ( VR1 )
			L5roomGen(15, 1, 10, 10, 0);
		if ( VR2 )
			L5roomGen(15, 15, 10, 10, 0);
		if ( VR3 )
			L5roomGen(15, 29, 10, 10, 0);
		HR3 = 0;
		HR2 = 0;
		HR1 = 0;
	}
}

//----- (0040BD66) --------------------------------------------------------
void __fastcall L5drawRoom(int tx, int ty, int tw, int th)
{
	int i; // esi
	int v5; // edi
	char *v6; // eax

	for ( i = 0; i < th; ++i )
	{
		if ( tw > 0 )
		{
			v5 = tw;
			v6 = &dungeon[tx][i + ty];
			do
			{
				*v6 = 1;
				v6 += 40;
				--v5;
			}
			while ( v5 );
		}
	}
}

//----- (0040BD9D) --------------------------------------------------------
void __fastcall L5roomGen(int tx, int ty, int tw, int th, bool dir_horiz)
{
	int v5; // eax
	int v6; // ecx
	int v7; // eax
	int v8; // ecx
	int v9; // eax
	int v10; // ecx
	int v11; // esi
	int v12; // edi
	int v13; // ebx
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // ecx
	int v18; // esi
	int v19; // edi
	int v20; // ebx
	int v21; // eax
	int v22; // eax
	int tya; // [esp+Ch] [ebp-10h]
	int tyb; // [esp+Ch] [ebp-10h]
	int v25; // [esp+10h] [ebp-Ch]
	int v26; // [esp+10h] [ebp-Ch]
	int txa; // [esp+14h] [ebp-8h]
	int txb; // [esp+14h] [ebp-8h]
	int v29; // [esp+18h] [ebp-4h]
	int twa; // [esp+24h] [ebp+8h]
	int tha; // [esp+28h] [ebp+Ch]
	int thb; // [esp+28h] [ebp+Ch]
	int thc; // [esp+28h] [ebp+Ch]
	signed int dir_horiza; // [esp+2Ch] [ebp+10h]
	signed int dir_horizb; // [esp+2Ch] [ebp+10h]

	v29 = ty;
	txa = tx;
	while ( 1 )
	{
		while ( 1 )
		{
			_LOBYTE(tx) = 0;
			v5 = random(tx, 4);
			v6 = 0;
			_LOBYTE(v6) = dir_horiz == 1 ? v5 != 0 : v5 == 0;
			v7 = v6;
			v8 = 0;
			if ( !v7 )
				break;
			if ( v7 != 1 )
				return;
			dir_horiza = 0;
			twa = tw / 2;
			do
			{
				_LOBYTE(v8) = 0;
				v9 = random(v8, 5);
				_LOBYTE(v10) = 0;
				v11 = (v9 + 2) & 0xFFFFFFFE;
				v12 = (random(v10, 5) + 2) & 0xFFFFFFFE;
				v13 = txa + twa - v11 / 2;
				tya = v29 - v12;
				_LOBYTE(v14) = L5checkRoom(v13 - 1, v29 - v12 - 1, v11 + 2, v12 + 1);
				++dir_horiza;
				v25 = v14;
			}
			while ( !v14 && dir_horiza < 20 );
			if ( v14 == 1 )
				L5drawRoom(v13, tya, v11, v12);
			txb = v29 + th;
			_LOBYTE(v15) = L5checkRoom(v13 - 1, v29 + th, v11 + 2, v12 + 1);
			tha = v15;
			if ( v15 == 1 )
				L5drawRoom(v13, txb, v11, v12);
			if ( v25 == 1 )
				L5roomGen(v13, tya, v11, v12, 0);
			if ( tha != 1 )
				return;
			*(_DWORD *)&dir_horiz = 0;
			th = v12;
			tw = v11;
			v29 = txb;
			txa = v13;
		}
		dir_horizb = 0;
		thb = th / 2;
		do
		{
			_LOBYTE(v8) = 0;
			v16 = random(v8, 5);
			_LOBYTE(v17) = 0;
			v18 = (v16 + 2) & 0xFFFFFFFE;
			v19 = (random(v17, 5) + 2) & 0xFFFFFFFE;
			v20 = v29 + thb - v19 / 2;
			tyb = txa - v18;
			_LOBYTE(v21) = L5checkRoom(txa - v18 - 1, v20 - 1, v19 + 2, v18 + 1);
			++dir_horizb;
			v26 = v21;
		}
		while ( !v21 && dir_horizb < 20 );
		if ( v21 == 1 )
			L5drawRoom(tyb, v20, v18, v19);
		txa += tw;
		_LOBYTE(v22) = L5checkRoom(txa, v20 - 1, v18 + 1, v19 + 2);
		thc = v22;
		if ( v22 == 1 )
			L5drawRoom(txa, v20, v18, v19);
		if ( v26 == 1 )
			L5roomGen(tyb, v20, v18, v19, 1);
		if ( thc != 1 )
			break;
		*(_DWORD *)&dir_horiz = 1;
		th = v19;
		tw = v18;
		v29 = v20;
	}
}

//----- (0040BFA4) --------------------------------------------------------
bool __fastcall L5checkRoom(int tx, int ty, int tw, int th)
{
	int v4; // eax
	int v5; // ebx
	char *v6; // edi
	int v8; // [esp+Ch] [ebp-4h]

	v4 = 0;
	if ( th <= 0 )
		return 1;
	while ( 1 )
	{
		v8 = 0;
		if ( tw > 0 )
			break;
LABEL_10:
		if ( ++v4 >= th )
			return 1;
	}
	v5 = tx;
	v6 = &dungeon[tx][v4 + ty];
	while ( v5 >= 0 && v5 < 40 && v4 + ty >= 0 && v4 + ty < 40 && !*v6 )
	{
		++v8;
		v6 += 40;
		++v5;
		if ( v8 >= tw )
			goto LABEL_10;
	}
	return 0;
}

//----- (0040C008) --------------------------------------------------------
int __cdecl L5GetArea()
{
	int result; // eax
	signed int v1; // edx
	_BYTE *v2; // ecx
	signed int v3; // esi

	result = 0;
	v1 = 0;
	do
	{
		v2 = (unsigned char *)dungeon + v1;
		v3 = 40;
		do
		{
			if ( *v2 == 1 )
				++result;
			v2 += 40;
			--v3;
		}
		while ( v3 );
		++v1;
	}
	while ( v1 < 40 );
	return result;
}

//----- (0040C02A) --------------------------------------------------------
void __cdecl L5makeDungeon()
{
	signed int v0; // edi
	signed int v1; // esi
	char *v2; // edx
	char v3; // cl
	int v4; // eax
	int v5; // eax

	v0 = 0;
	do
	{
		v1 = 0;
		v2 = (char *)dungeon + v0;
		do
		{
			v3 = *v2;
			v2 += 40;
			v4 = 160 * v1++;
			v5 = v4 + 2 * v0;
			L5dungeon[0][v5] = v3;
			L5dungeon[0][v5 + 1] = v3;
			L5dungeon[1][v5] = v3;
			L5dungeon[1][v5 + 1] = v3;
		}
		while ( v1 < 40 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040C06E) --------------------------------------------------------
void __cdecl L5makeDmt()
{
	signed int v0; // ecx
	_BYTE *v1; // eax
	signed int v2; // edx
	signed int v3; // esi
	char (*v4)[40]; // ecx
	char *v5; // eax
	signed int v6; // edi
	int v7; // edx
	int v8; // ebx
	char (*v9)[40]; // [esp+0h] [ebp-4h]

	v0 = 0;
	do
	{
		v1 = (unsigned char *)dungeon + v0;
		v2 = 40;
		do
		{
			*v1 = 22;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
	v3 = 1;
	v9 = dungeon;
	do
	{
		v4 = v9;
		v5 = &L5dungeon[1][v3 + 1];
		v6 = 39;
		do
		{
			v7 = (unsigned char)v5[80];
			v8 = (unsigned char)*v5;
			v5 += 160;
			*(_BYTE *)v4 = L5ConvTbl[2 * ((unsigned char)*(v5 - 81) + 2 * (v8 + 2 * v7))
								   + (unsigned char)*(v5 - 161)];
			++v4;
			--v6;
		}
		while ( v6 );
		v9 = (char (*)[40])((char *)v9 + 1);
		v3 += 2;
	}
	while ( v3 <= 77 );
}

//----- (0040C0E0) --------------------------------------------------------
void __cdecl L5AddWall()
{
	int v0; // edi
	int v1; // esi
	int v2; // ebx
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // eax
	int v7; // eax
	int v8; // eax

	v0 = 0;
	do
	{
		v1 = 0;
		v2 = v0;
		do
		{
			if ( !mydflags[0][v2] )
			{
				if ( dungeon[0][v2] == 3 )
				{
					if ( random(0, 100) < 100 )
					{
						v3 = L5HWallOk(v1, v0);
						if ( v3 != -1 )
							L5HorizWall(v1, v0, 2, v3);
					}
					if ( dungeon[0][v2] == 3 && random(0, 100) < 100 )
					{
						v4 = L5VWallOk(v1, v0);
						if ( v4 != -1 )
							L5VertWall(v1, v0, 1, v4);
					}
				}
				if ( dungeon[0][v2] == 6 && random(0, 100) < 100 )
				{
					v5 = L5HWallOk(v1, v0);
					if ( v5 != -1 )
						L5HorizWall(v1, v0, 4, v5);
				}
				if ( dungeon[0][v2] == 7 && random(0, 100) < 100 )
				{
					v6 = L5VWallOk(v1, v0);
					if ( v6 != -1 )
						L5VertWall(v1, v0, 4, v6);
				}
				if ( dungeon[0][v2] == 2 && random(0, 100) < 100 )
				{
					v7 = L5HWallOk(v1, v0);
					if ( v7 != -1 )
						L5HorizWall(v1, v0, 2, v7);
				}
				if ( dungeon[0][v2] == 1 && random(0, 100) < 100 )
				{
					v8 = L5VWallOk(v1, v0);
					if ( v8 != -1 )
						L5VertWall(v1, v0, 1, v8);
				}
			}
			++v1;
			v2 += 40;
		}
		while ( v1 < 40 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040C23C) --------------------------------------------------------
int __fastcall L5HWallOk(int tx, int ty)
{
	int v2; // esi
	char *v3; // edi
	int v4; // eax
	char *v5; // ebx
	signed int v6; // eax
	char v7; // dl
	int result; // eax
	int v9; // [esp+8h] [ebp-4h]

	v2 = 8 * (5 * tx + 5);
	v9 = 1;
	v3 = (char *)dungeon + v2 + ty;
	if ( *v3 == 13 )
	{
		v4 = 8 * (5 * tx + 5);
		v5 = &dungeon[tx + 1][ty];
		do
		{
			if ( *(v3 - 1) != 13 )
				break;
			if ( dungeon[0][v2 + 1 + ty] != 13 )
				break;
			if ( mydflags[0][v2 + ty] )
				break;
			++v9;
			v5 += 40;
			v4 += 40;
			v3 = v5;
			v2 = v4;
		}
		while ( *v5 == 13 );
	}
	v6 = 0;
	v7 = dungeon[v9 + tx][ty];
	if ( (unsigned char)v7 >= 3u && (unsigned char)v7 <= 7u )
		v6 = 1;
	if ( (unsigned char)v7 >= 0x10u && (unsigned char)v7 <= 0x18u )
		v6 = 1;
	if ( v7 == 22 )
		v6 = 0;
	if ( v9 == 1 )
		v6 = 0;
	if ( v6 )
		result = v9;
	else
		result = -1;
	return result;
}

//----- (0040C2DC) --------------------------------------------------------
int __fastcall L5VWallOk(int tx, int ty)
{
	int v2; // ecx
	int result; // eax
	char *v4; // esi
	signed int v5; // esi
	char v6; // dl

	v2 = tx;
	result = 1;
	if ( dungeon[v2][ty + 1] == 13 )
	{
		v4 = &dungeon[v2][ty];
		do
		{
			if ( v4[result - 40] != 13 )
				break;
			if ( dungeon[v2 + 1][result + ty] != 13 )
				break;
			if ( mydflags[v2][result + ty] )
				break;
			++result;
		}
		while ( v4[result] == 13 );
	}
	v5 = 0;
	v6 = dungeon[0][result + v2 * 40 + ty];
	if ( (unsigned char)v6 >= 3u && (unsigned char)v6 <= 7u )
		v5 = 1;
	if ( (unsigned char)v6 >= 0x10u && (unsigned char)v6 <= 0x18u )
		v5 = 1;
	if ( v6 == 22 )
		v5 = 0;
	if ( result == 1 )
		v5 = 0;
	if ( !v5 )
		result = -1;
	return result;
}

//----- (0040C35B) --------------------------------------------------------
void __fastcall L5HorizWall(int tx, int ty, int tile_id, int tw)
{
	int v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // ecx
	char v8; // bl
	int v9; // eax
	int v10; // ecx
	char *v11; // edi
	int v12; // eax
	int v13; // eax
	int v14; // eax
	int v15; // [esp+8h] [ebp-8h]
	char v16; // [esp+Fh] [ebp-1h]

	v4 = ty;
	v5 = tx;
	_LOBYTE(tx) = 0;
	v15 = ty;
	v6 = random(tx, 4);
	if ( v6 >= 0 )
	{
		if ( v6 <= 1 )
		{
			v16 = 2;
		}
		else if ( v6 == 2 )
		{
			v16 = 12;
			if ( (_BYTE)tile_id == 2 )
				_LOBYTE(tile_id) = 12;
			if ( (_BYTE)tile_id == 4 )
				_LOBYTE(tile_id) = 10;
		}
		else if ( v6 == 3 )
		{
			v16 = 36;
			if ( (_BYTE)tile_id == 2 )
				_LOBYTE(tile_id) = 36;
			if ( (_BYTE)tile_id == 4 )
				_LOBYTE(tile_id) = 27;
		}
	}
	_LOBYTE(v7) = 0;
	v8 = random(v7, 6) != 5 ? 26 : 12;
	if ( v16 == 12 )
		v8 = 12;
	v9 = v4 + 40 * v5;
	dungeon[0][v9] = tile_id;
	v10 = tw;
	if ( tw > 1 )
	{
		v11 = &dungeon[1][v9];
		v12 = tw - 1;
		do
		{
			*v11 = v16;
			v11 += 40;
			--v12;
		}
		while ( v12 );
		v4 = v15;
	}
	_LOBYTE(v10) = 0;
	v13 = random(v10, tw - 1) + 1;
	if ( v8 == 12 )
	{
		dungeon[v5 + v13][v4] = 12;
	}
	else
	{
		v14 = v4 + 40 * (v5 + v13);
		mydflags[0][v14] |= 1u;
		dungeon[0][v14] = 2;
	}
}

//----- (0040C449) --------------------------------------------------------
void __fastcall L5VertWall(int tx, int ty, int tile_id, int th)
{
	int v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // ecx
	int v8; // eax
	int v9; // ebx
	int v10; // esi
	int v11; // ecx
	char *v12; // edi
	int v13; // eax
	unsigned int v14; // ecx
	int v15; // edx
	int v16; // eax
	int v17; // eax
	int v18; // [esp+8h] [ebp-8h]
	char v19; // [esp+Eh] [ebp-2h]
	char v20; // [esp+Fh] [ebp-1h]

	v4 = ty;
	v5 = tx;
	_LOBYTE(tx) = 0;
	v18 = ty;
	v6 = random(tx, 4);
	if ( v6 >= 0 )
	{
		if ( v6 <= 1 )
		{
			v20 = 1;
		}
		else if ( v6 == 2 )
		{
			v20 = 11;
			if ( (_BYTE)tile_id == 1 )
				_LOBYTE(tile_id) = 11;
			if ( (_BYTE)tile_id == 4 )
				_LOBYTE(tile_id) = 14;
		}
		else if ( v6 == 3 )
		{
			v20 = 35;
			if ( (_BYTE)tile_id == 1 )
				_LOBYTE(tile_id) = 35;
			if ( (_BYTE)tile_id == 4 )
				_LOBYTE(tile_id) = 37;
		}
	}
	_LOBYTE(v7) = 0;
	v8 = random(v7, 6);
	v9 = 5 - v8;
	_LOBYTE(v9) = v8 != 5 ? 25 : 11;
	v19 = v8 != 5 ? 25 : 11;
	if ( v20 == 11 )
	{
		_LOBYTE(v9) = 11;
		v19 = 11;
	}
	v10 = v5;
	dungeon[v10][v4] = tile_id;
	v11 = th;
	if ( th > 1 )
	{
		v12 = &dungeon[v10][v4 + 1];
		_LOBYTE(v9) = v20;
		BYTE1(v9) = v20;
		v13 = v9 << 16;
		_LOWORD(v13) = v9;
		_LOBYTE(v9) = v19;
		v14 = (unsigned int)(th - 1) >> 2;
		memset(v12, v13, v14);
		memset(&v12[4 * v14], v13, ((_BYTE)th - 1) & 3);
		v11 = th;
		v4 = v18;
	}
	v15 = v11 - 1;
	_LOBYTE(v11) = 0;
	v16 = random(v11, v15) + 1;
	if ( (_BYTE)v9 == 11 )
	{
		dungeon[0][v16 + v10 * 40 + v4] = 11;
	}
	else
	{
		v17 = v16 + v10 * 40 + v4;
		mydflags[0][v17] |= 2u;
		dungeon[0][v17] = 1;
	}
}

//----- (0040C551) --------------------------------------------------------
void __cdecl L5tileFix()
{
	signed int v0; // esi
	char *v1; // eax
	signed int v2; // edx
	char v3; // cl
	signed int v4; // ecx
	signed int v5; // edi
	signed int v6; // eax
	char *v7; // esi
	char v8; // bl
	char *v9; // edx
	char *v10; // edx
	char *v11; // edx
	char *v12; // edx
	char *v13; // edx
	char *v14; // edx
	char *v15; // edx
	char *v16; // edx
	char *v17; // edx
	char *v18; // edx
	char *v19; // edx
	char *v20; // edx
	char *v21; // edx
	char *v22; // edx
	char *v23; // edx
	char *v24; // edx
	char *v25; // edx
	char *v26; // edx
	char *v27; // edx
	char *v28; // edx
	char *v29; // edx
	char *v30; // edx
	char *v31; // edx
	char *v32; // edx
	char *v33; // edx
	char *v34; // eax
	signed int v35; // edx
	char *v36; // eax
	signed int v37; // esi
	char v38; // cl

	v0 = 0;
	do
	{
		v1 = &dungeon[1][v0];
		v2 = 40;
		do
		{
			v3 = *(v1 - 40);
			if ( v3 == 2 && *v1 == 22 )
				*v1 = 23;
			if ( v3 == 13 )
			{
				if ( *v1 == 22 )
					*v1 = 18;
				if ( *v1 == 2 )
					*v1 = 7;
			}
			if ( v3 == 6 && *v1 == 22 )
				*v1 = 24;
			if ( v3 == 1 && *(v1 - 39) == 22 )
				*(v1 - 39) = 24;
			if ( v3 == 13 )
			{
				if ( *(v1 - 39) == 1 )
					*(v1 - 39) = 6;
				if ( *(v1 - 39) == 22 )
					*(v1 - 39) = 19;
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
	v4 = 0;
	do
	{
		v5 = 0;
		do
		{
			v6 = v5;
			v7 = &dungeon[v5][v4];
			v8 = *v7;
			if ( *v7 == 13 )
			{
				v9 = &dungeon[v6 + 1][v4];
				if ( *v9 == 19 )
					*v9 = 21;
				v10 = &dungeon[v6 + 1][v4];
				if ( *v10 == 22 )
					*v10 = 20;
			}
			if ( v8 == 7 )
			{
				v11 = &dungeon[v6 + 1][v4];
				if ( *v11 == 22 )
					*v11 = 23;
			}
			if ( v8 == 13 )
			{
				v12 = &dungeon[v6 + 1][v4];
				if ( *v12 == 24 )
					*v12 = 21;
			}
			if ( v8 == 19 )
			{
				v13 = &dungeon[v6 + 1][v4];
				if ( *v13 == 22 )
					*v13 = 20;
			}
			if ( v8 == 2 )
			{
				v14 = &dungeon[v6 + 1][v4];
				if ( *v14 == 19 )
					*v14 = 21;
			}
			if ( v8 == 19 )
			{
				v15 = &dungeon[v6 + 1][v4];
				if ( *v15 == 1 )
					*v15 = 6;
			}
			if ( v8 == 7 )
			{
				v16 = &dungeon[v6 + 1][v4];
				if ( *v16 == 19 )
					*v16 = 21;
			}
			if ( v8 == 2 )
			{
				v17 = &dungeon[v6 + 1][v4];
				if ( *v17 == 1 )
					*v17 = 6;
			}
			if ( v8 == 3 )
			{
				v18 = &dungeon[v6 + 1][v4];
				if ( *v18 == 22 )
					*v18 = 24;
			}
			if ( v8 == 21 )
			{
				v19 = &dungeon[v6 + 1][v4];
				if ( *v19 == 1 )
					*v19 = 6;
			}
			if ( v8 == 7 )
			{
				v20 = &dungeon[v6 + 1][v4];
				if ( *v20 == 1 )
					*v20 = 6;
				v21 = &dungeon[v6 + 1][v4];
				if ( *v21 == 24 )
					*v21 = 21;
			}
			if ( v8 == 4 )
			{
				v22 = &dungeon[v6 + 1][v4];
				if ( *v22 == 16 )
					*v22 = 17;
			}
			if ( v8 == 7 )
			{
				v23 = &dungeon[v6 + 1][v4];
				if ( *v23 == 13 )
					*v23 = 17;
			}
			if ( v8 == 2 )
			{
				v24 = &dungeon[v6 + 1][v4];
				if ( *v24 == 24 )
					*v24 = 21;
				v25 = &dungeon[v6 + 1][v4];
				if ( *v25 == 13 )
					*v25 = 17;
			}
			if ( v8 == 23 && *(v7 - 40) == 22 )
				*(v7 - 40) = 19;
			if ( v8 == 19 && *(v7 - 40) == 23 )
				*(v7 - 40) = 21;
			if ( v8 == 6 )
			{
				if ( *(v7 - 40) == 22 )
					*(v7 - 40) = 24;
				if ( *(v7 - 40) == 23 )
					*(v7 - 40) = 21;
			}
			if ( v8 == 1 )
			{
				v26 = &dungeon[v6][v4 + 1];
				if ( *v26 == 2 )
					*v26 = 7;
			}
			if ( v8 == 6 )
			{
				v27 = &dungeon[v6][v4 + 1];
				if ( *v27 == 18 )
					*v27 = 21;
			}
			if ( v8 == 18 )
			{
				v28 = &dungeon[v6][v4 + 1];
				if ( *v28 == 2 )
					*v28 = 7;
			}
			if ( v8 == 6 )
			{
				v29 = &dungeon[v6][v4 + 1];
				if ( *v29 == 2 )
					*v29 = 7;
			}
			if ( v8 == 21 )
			{
				v30 = &dungeon[v6][v4 + 1];
				if ( *v30 == 2 )
					*v30 = 7;
			}
			if ( v8 == 6 )
			{
				v31 = &dungeon[v6][v4 + 1];
				if ( *v31 == 22 )
					*v31 = 24;
				v32 = &dungeon[v6][v4 + 1];
				if ( *v32 == 13 )
					*v32 = 16;
			}
			if ( v8 == 1 )
			{
				v33 = &dungeon[v6][v4 + 1];
				if ( *v33 == 13 )
					*v33 = 16;
			}
			if ( v8 == 13 )
			{
				v34 = &dungeon[v6][v4 + 1];
				if ( *v34 == 16 )
					*v34 = 17;
			}
			if ( v8 == 6 )
			{
				if ( *(v7 - 1) == 22 )
					*(v7 - 1) = 7;
				if ( *(v7 - 1) == 22 )
					*(v7 - 1) = 24;
			}
			if ( v8 == 7 && *(v7 - 1) == 24 )
				*(v7 - 1) = 21;
			if ( v8 == 18 && *(v7 - 1) == 24 )
				*(v7 - 1) = 21;
			++v5;
		}
		while ( v5 < 40 );
		++v4;
	}
	while ( v4 < 40 );
	v35 = 0;
	do
	{
		v36 = (char *)dungeon + v35;
		v37 = 40;
		do
		{
			v38 = *v36;
			if ( *v36 == 4 && v36[1] == 2 )
				v36[1] = 7;
			if ( v38 == 2 && v36[40] == 19 )
				v36[40] = 21;
			if ( v38 == 18 && v36[1] == 22 )
				v36[1] = 20;
			v36 += 40;
			--v37;
		}
		while ( v37 );
		++v35;
	}
	while ( v35 < 40 );
}

//----- (0040C8C0) --------------------------------------------------------
void __cdecl DRLG_L5Subs()
{
	signed int v0; // edi
	int v1; // esi
	unsigned char v2; // bl
	int v3; // eax
	signed int v4; // ecx
	signed int v5; // [esp+Ch] [ebp-4h]

	v0 = 0;
	do
	{
		v1 = v0 - 1;
		v5 = 40;
		do
		{
			if ( !random(0, 4) )
			{
				v2 = L5BTYPES[(unsigned char)dungeon[0][v1 + 1]];
				if ( v2 )
				{
					if ( !mydflags[0][v1 + 1] )
					{
						v3 = random(0, 16);
						v4 = -1;
						if ( v3 >= 0 )
						{
							do
							{
								if ( ++v4 == 206 )
									v4 = 0;
								if ( v2 == L5BTYPES[v4] )
									--v3;
							}
							while ( v3 >= 0 );
							if ( v4 == 89 )
							{
								if ( L5BTYPES[(unsigned char)dungeon[0][v1]] == 79 && !mydflags[0][v1] )
								{
									dungeon[0][v1] = 90;
									goto LABEL_22;
								}
								v4 = 79;
							}
							if ( v4 == 91 )
							{
								if ( L5BTYPES[(unsigned char)dungeon[1][v1 + 1]] != 80 || mydflags[1][v1 + 1] )
									_LOBYTE(v4) = 80;
								else
									dungeon[1][v1 + 1] = 92;
							}
						}
LABEL_22:
						dungeon[0][v1 + 1] = v4;
						goto LABEL_23;
					}
				}
			}
LABEL_23:
			v1 += 40;
			--v5;
		}
		while ( v5 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040C99D) --------------------------------------------------------
void __cdecl L5FillChambers()
{
	int v0; // edi
	int v1; // edi
	int v2; // edx
	int v3; // ecx
	int v4; // edi
	signed int v5; // [esp-4h] [ebp-10h]

	v0 = 1;
	if ( HR1 )
		DRLG_L5GChamber(0, 14, 0, 0, 0, 1);
	if ( !HR2 )
		goto LABEL_16;
	if ( HR1 )
	{
		if ( !HR3 )
			DRLG_L5GChamber(14, 14, 0, 0, 1, 0);
		if ( HR1 )
			goto LABEL_111;
	}
	if ( HR3 )
		DRLG_L5GChamber(14, 14, 0, 0, 0, 1);
	if ( HR1 )
	{
LABEL_111:
		if ( HR3 )
			DRLG_L5GChamber(14, 14, 0, 0, 1, 1);
		if ( HR1 )
		{
LABEL_16:
			if ( !HR3 )
				goto LABEL_18;
			goto LABEL_17;
		}
	}
	if ( !HR3 )
	{
		DRLG_L5GChamber(14, 14, 0, 0, 0, 0);
		goto LABEL_16;
	}
LABEL_17:
	DRLG_L5GChamber(28, 14, 0, 0, 1, 0);
LABEL_18:
	if ( HR1 )
	{
		if ( !HR2 )
			goto LABEL_24;
		DRLG_L5GHall(12, 18, 14, 18);
	}
	if ( HR2 && HR3 )
		DRLG_L5GHall(26, 18, 28, 18);
LABEL_24:
	if ( HR1 && !HR2 && HR3 )
		DRLG_L5GHall(12, 18, 28, 18);
	if ( VR1 )
		DRLG_L5GChamber(14, 0, 0, 1, 0, 0);
	if ( !VR2 )
		goto LABEL_43;
	if ( VR1 )
	{
		if ( !VR3 )
			DRLG_L5GChamber(14, 14, 1, 0, 0, 0);
		if ( VR1 )
			goto LABEL_112;
	}
	if ( VR3 )
		DRLG_L5GChamber(14, 14, 0, 1, 0, 0);
	if ( VR1 )
	{
LABEL_112:
		if ( VR3 )
			DRLG_L5GChamber(14, 14, 1, 1, 0, 0);
		if ( VR1 )
		{
LABEL_43:
			if ( !VR3 )
				goto LABEL_45;
			goto LABEL_44;
		}
	}
	if ( !VR3 )
	{
		DRLG_L5GChamber(14, 14, 0, 0, 0, 0);
		goto LABEL_43;
	}
LABEL_44:
	DRLG_L5GChamber(14, 28, 1, 0, 0, 0);
LABEL_45:
	if ( VR1 )
	{
		if ( !VR2 )
			goto LABEL_51;
		DRLG_L5GHall(18, 12, 18, 14);
	}
	if ( VR2 && VR3 )
		DRLG_L5GHall(18, 26, 18, 28);
LABEL_51:
	if ( VR1 && !VR2 && VR3 )
		DRLG_L5GHall(18, 12, 18, 28);
	if ( setloadflag )
	{
		if ( !VR1 && !VR2 && !VR3 )
		{
			if ( HR1 )
				goto LABEL_113;
			if ( HR2 && HR3 )
			{
				if ( random(0, 2) )
					v0 = 2;
				if ( HR1 )
				{
LABEL_113:
					if ( HR2 && !HR3 && random(0, 2) )
						v0 = 0;
					if ( HR1 )
					{
						if ( !HR2 && HR3 )
							v0 = random(0, 2) != 0 ? 0 : 2;
						if ( HR1 && HR2 )
						{
							if ( HR3 )
								v0 = random(0, 3);
						}
					}
				}
			}
			if ( !v0 )
			{
				v3 = 2;
				v2 = 16;
				goto LABEL_108;
			}
			v1 = v0 - 1;
			if ( v1 )
			{
				if ( v1 != 1 )
					return;
				v2 = 16;
				v5 = 30;
				goto LABEL_107;
			}
LABEL_81:
			v3 = 16;
			v2 = 16;
LABEL_108:
			DRLG_L5SetRoom(v3, v2);
			return;
		}
		if ( VR1 )
			goto LABEL_114;
		if ( VR2 && VR3 )
		{
			if ( random(0, 2) )
				v0 = 2;
			if ( VR1 )
			{
LABEL_114:
				if ( VR2 && !VR3 && random(0, 2) )
					v0 = 0;
				if ( VR1 )
				{
					if ( !VR2 && VR3 )
						v0 = random(0, 2) != 0 ? 0 : 2;
					if ( VR1 && VR2 && VR3 )
						v0 = random(0, 3);
				}
			}
		}
		if ( v0 )
		{
			v4 = v0 - 1;
			if ( !v4 )
				goto LABEL_81;
			if ( v4 != 1 )
				return;
			v2 = 30;
		}
		else
		{
			v2 = 2;
		}
		v5 = 16;
LABEL_107:
		v3 = v5;
		goto LABEL_108;
	}
}
// 5276A4: using guessed type int setloadflag;

//----- (0040CD86) --------------------------------------------------------
void __fastcall DRLG_L5GChamber(int tx, int ty, bool top_right, bool bottom_left, bool top_left, bool bottom_right)
{
	int v6; // eax
	int v7; // edx
	int v8; // eax
	char *v9; // eax
	int v10; // eax
	int v11; // ecx
	int v12; // eax
	char *v13; // eax
	signed int v14; // edi
	int v15; // eax
	int v16; // edx
	int v17; // ecx
	signed int v18; // esi

	if ( top_right == 1 )
	{
		v6 = ty + 40 * tx;
		dungeon[2][v6] = 12;
		dungeon[3][v6] = 12;
		dungeon[4][v6] = 3;
		dungeon[7][v6] = 9;
		dungeon[8][v6] = 12;
		dungeon[9][v6] = 2;
	}
	if ( bottom_left == 1 )
	{
		v7 = ty + 11;
		v8 = v7 + 40 * tx;
		dungeon[2][v8] = 10;
		dungeon[3][v8] = 12;
		dungeon[4][v8] = 8;
		dungeon[7][v8] = 5;
		dungeon[8][v8] = 12;
		v9 = &dungeon[9][v8];
		if ( *v9 != 4 )
			*v9 = 21;
		ty = v7 - 11;
	}
	if ( top_left == 1 )
	{
		v10 = ty + 40 * tx;
		dungeon[0][v10 + 2] = 11;
		dungeon[0][v10 + 3] = 11;
		dungeon[0][v10 + 4] = 3;
		dungeon[0][v10 + 7] = 8;
		dungeon[0][v10 + 8] = 11;
		dungeon[0][v10 + 9] = 1;
	}
	if ( bottom_right == 1 )
	{
		v11 = tx + 11;
		v12 = ty + 40 * v11;
		dungeon[0][v12 + 2] = 14;
		dungeon[0][v12 + 3] = 11;
		dungeon[0][v12 + 4] = 9;
		dungeon[0][v12 + 7] = 5;
		dungeon[0][v12 + 8] = 11;
		v13 = &dungeon[0][v12 + 9];
		if ( *v13 != 4 )
			*v13 = 21;
		tx = v11 - 11;
	}
	v14 = 10;
	v15 = ty + 40 * tx;
	v16 = v15 + 1;
	do
	{
		v17 = v16;
		v18 = 10;
		do
		{
			mydflags[1][v17] |= 0x40u;
			dungeon[1][v17] = 13;
			v17 += 40;
			--v18;
		}
		while ( v18 );
		++v16;
		--v14;
	}
	while ( v14 );
	dungeon[4][v15 + 4] = 15;
	dungeon[7][v15 + 4] = 15;
	dungeon[4][v15 + 7] = 15;
	dungeon[7][v15 + 7] = 15;
}

//----- (0040CEC7) --------------------------------------------------------
void __fastcall DRLG_L5GHall(int tx_start, int ty_start, int tx_end, int ty_end)
{
	int v4; // eax
	char *v5; // edx
	int v6; // eax
	int v7; // ecx

	if ( ty_start == ty_end )
	{
		if ( tx_start < tx_end )
		{
			v4 = tx_end - tx_start;
			v5 = &dungeon[tx_start][ty_start + 3];
			do
			{
				*(v5 - 3) = 12;
				*v5 = 12;
				v5 += 40;
				--v4;
			}
			while ( v4 );
		}
	}
	else
	{
		v6 = ty_start;
		if ( ty_start < ty_end )
		{
			v7 = 40 * tx_start + 5478016;
			do
			{
				*(_BYTE *)(v7 + v6 - 120) = 11;
				*(_BYTE *)(v7 + v6++) = 11;
			}
			while ( v6 < ty_end );
		}
	}
}

//----- (0040CF17) --------------------------------------------------------
void __fastcall DRLG_L5SetRoom(int tx, int ty)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax
	char v5; // bl
	int v6; // [esp+8h] [ebp-Ch]
	char *v7; // [esp+Ch] [ebp-8h]
	int v8; // [esp+10h] [ebp-4h]

	v8 = 0;
	v2 = *((unsigned char *)pSetPiece + 2);
	v3 = *(unsigned char *)pSetPiece;
	setpc_x = tx;
	setpc_y = ty;
	setpc_w = v3;
	setpc_h = v2;
	v7 = (char *)pSetPiece + 4;
	if ( v2 > 0 )
	{
		do
		{
			if ( v3 > 0 )
			{
				v6 = v3;
				v4 = ty + v8 + 40 * tx;
				do
				{
					v5 = *v7;
					if ( *v7 )
					{
						mydflags[0][v4] |= 0x80u;
						dungeon[0][v4] = v5;
					}
					else
					{
						dungeon[0][v4] = 13;
					}
					v7 += 2;
					v4 += 40;
					--v6;
				}
				while ( v6 );
			}
			++v8;
		}
		while ( v8 < v2 );
	}
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (0040CF9C) --------------------------------------------------------
void __cdecl DRLG_L5FloodTVal()
{
	int v0; // ebx
	int v1; // esi
	char *v2; // edi
	_BYTE *v3; // [esp+Ch] [ebp-Ch]
	signed int x; // [esp+10h] [ebp-8h]
	signed int tx; // [esp+14h] [ebp-4h]

	v0 = 16;
	v1 = 0;
	do
	{
		tx = 0;
		x = 16;
		v2 = &dung_map[16][v0];
		v3 = (unsigned char *)dungeon + v1;
		do
		{
			if ( *v3 == 13 && !*v2 )
			{
				DRLG_L5FTVR(tx, v1, x, v0, 0);
				++TransVal;
			}
			x += 2;
			v3 += 40;
			v2 += 224;
			++tx;
		}
		while ( tx < 40 );
		v0 += 2;
		++v1;
	}
	while ( v1 < 40 );
}
// 5A5590: using guessed type char TransVal;

//----- (0040D00B) --------------------------------------------------------
void __fastcall DRLG_L5FTVR(int tx, int ty, int x, int y, int direction)
{
	int v5; // ebx
	int v6; // esi
	int v7; // edi
	int v8; // edx
	int v9; // ecx
	int v10; // ebx
	int v11; // eax
	int v12; // edi
	char v13; // al
	char v14; // al
	int v15; // ecx
	int v16; // ecx
	int v17; // ecx
	int v18; // ecx
	int v19; // [esp+Ch] [ebp-14h]
	int i; // [esp+10h] [ebp-10h]
	int v21; // [esp+14h] [ebp-Ch]
	int tya; // [esp+18h] [ebp-8h]
	int txa; // [esp+1Ch] [ebp-4h]
	int ya; // [esp+2Ch] [ebp+Ch]

	v5 = x;
	v6 = y;
	v7 = ty;
	v8 = tx;
	v9 = 112 * x + y;
	tya = v7;
	v21 = v8;
	if ( !dung_map[0][v9] )
	{
		v19 = x;
		txa = v8 - 1;
		v10 = x - 2;
		v11 = 40 * v8;
		ya = v7 - 1;
		v12 = v6 - 2;
		for ( i = 40 * v8; dungeon[0][v11 + tya] == 13; v11 = i )
		{
			v13 = TransVal;
			dung_map[0][v9] = TransVal;
			dung_map[1][v9] = v13;
			dung_map[0][v9 + 1] = v13;
			dung_map[1][v9 + 1] = v13;
			DRLG_L5FTVR(txa + 2, tya, v10 + 4, v6, 1);
			DRLG_L5FTVR(txa, tya, v10, v6, 2);
			DRLG_L5FTVR(v21, ya + 2, x, v12 + 4, 3);
			DRLG_L5FTVR(v21, ya, x, v12, 4);
			DRLG_L5FTVR(txa, ya, v10, v12, 5);
			DRLG_L5FTVR(txa + 2, ya, v10 + 4, v12, 6);
			DRLG_L5FTVR(txa, ya + 2, v10, v12 + 4, 7);
			v19 += 2;
			i += 40;
			direction = 8;
			x += 2;
			v6 += 2;
			v12 += 2;
			v10 += 2;
			++tya;
			++ya;
			++v21;
			++txa;
			v9 = v19 * 112 + v6;
			if ( dung_map[v19][v6] )
				break;
		}
		v5 = x;
	}
	v14 = TransVal;
	if ( direction == 1 )
	{
		v15 = v6 + 112 * v5;
		dung_map[0][v15] = TransVal;
		dung_map[0][v15 + 1] = v14;
	}
	if ( direction == 2 )
	{
		v16 = v6 + 112 * v5;
		dung_map[1][v16] = v14;
		dung_map[1][v16 + 1] = v14;
	}
	if ( direction == 3 )
	{
		v17 = v6 + 112 * v5;
		dung_map[0][v17] = v14;
		dung_map[1][v17] = v14;
	}
	if ( direction == 4 )
	{
		v18 = v6 + 112 * v5;
		dung_map[0][v18 + 1] = v14;
		dung_map[1][v18 + 1] = v14;
	}
	if ( direction == 5 )
		dung_map[v5 + 1][v6 + 1] = v14;
	if ( direction == 6 )
		dung_map[v5][v6 + 1] = v14;
	if ( direction == 7 )
		dung_map[v5 + 1][v6] = v14;
	if ( direction == 8 )
		dung_map[v5][v6] = v14;
}
// 5A5590: using guessed type char TransVal;

//----- (0040D1FB) --------------------------------------------------------
void __cdecl DRLG_L5TransFix()
{
	signed int v0; // esi
	char *v1; // eax
	char *v2; // ecx
	signed int v3; // edi
	char v4; // bl
	char v5; // dl
	char v6; // dl
	char v7; // dl
	char v8; // dl
	char v9; // dl
	char *v10; // [esp+Ch] [ebp-4h]

	v0 = 0;
	v10 = &dung_map[16][16];
	do
	{
		v1 = v10;
		v2 = (char *)dungeon + v0;
		v3 = 40;
		do
		{
			v4 = *v2;
			if ( *v2 == 23 && *(v2 - 1) == 18 )
			{
				v5 = *v1;
				v1[112] = *v1;
				v1[113] = v5;
			}
			if ( v4 == 24 && v2[40] == 19 )
			{
				v6 = *v1;
				v1[1] = *v1;
				v1[113] = v6;
			}
			if ( v4 == 18 )
			{
				v7 = *v1;
				v1[112] = *v1;
				v1[113] = v7;
			}
			if ( v4 == 19 )
			{
				v8 = *v1;
				v1[1] = *v1;
				v1[113] = v8;
			}
			if ( v4 == 20 )
			{
				v9 = *v1;
				v1[112] = *v1;
				v1[1] = v9;
				v1[113] = v9;
			}
			v1 += 224;
			v2 += 40;
			--v3;
		}
		while ( v3 );
		v10 += 2;
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040D283) --------------------------------------------------------
void __cdecl DRLG_L5DirtFix()
{
	signed int v0; // ecx
	char *v1; // eax
	signed int v2; // edx

	v0 = 0;
	do
	{
		v1 = (char *)dungeon + v0;
		v2 = 40;
		do
		{
			if ( *v1 == 21 && v1[40] != 19 )
				*v1 = -54;
			if ( *v1 == 19 && v1[40] != 19 )
				*v1 = -56;
			if ( *v1 == 24 && v1[40] != 19 )
				*v1 = -51;
			if ( *v1 == 18 && v1[1] != 18 )
				*v1 = -57;
			if ( *v1 == 21 && v1[1] != 18 )
				*v1 = -54;
			if ( *v1 == 23 && v1[1] != 18 )
				*v1 = -52;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040D2EF) --------------------------------------------------------
void __cdecl DRLG_L5CornerFix()
{
	signed int v0; // esi
	signed int v1; // eax
	signed int v2; // edi

	v0 = 1;
	do
	{
		v1 = v0;
		v2 = 38;
		do
		{
			if ( mydflags[1][v1] >= 0 && dungeon[1][v1] == 17 && dungeon[0][v1] == 13 && dungeon[0][v1 + 39] == 1 )
			{
				mydflags[0][v1 + 39] &= 0x80u;
				dungeon[1][v1] = 16;
			}
			if ( dungeon[1][v1] == -54 && dungeon[2][v1] == 13 && dungeon[1][v1 + 1] == 1 )
				dungeon[1][v1] = 8;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 39 );
}

//----- (0040D357) --------------------------------------------------------
void __cdecl InitDungeon()
{
	signed int v0; // edx
	signed int v1; // eax
	signed int v2; // ecx

	v0 = 0;
	do
	{
		v1 = v0;
		v2 = 40;
		do
		{
			dflags[0][v1] = 0;
			predungeon[0][v1] = 32;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040D379) --------------------------------------------------------
void __cdecl L2LockoutFix()
{
	signed int v0; // ecx
	_BYTE *v1; // eax
	signed int v2; // edx
	signed int v3; // ecx
	signed int v4; // edi
	signed int v5; // eax
	char *v6; // esi
	signed int v7; // edx
	char v8; // al
	unsigned int v9; // ecx
	signed int v10; // eax
	char v11; // dl
	signed int v12; // esi
	char v13; // bl
	char *v14; // edx

	v0 = 0;
	do
	{
		v1 = (unsigned char *)dungeon + v0;
		v2 = 40;
		do
		{
			if ( *v1 == 4 && *(v1 - 40) != 3 )
				*v1 = 1;
			if ( *v1 == 5 && *(v1 - 1) != 3 )
				*v1 = 2;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
	v3 = 1;
	do
	{
		v4 = 1;
		do
		{
			v5 = v4;
			if ( dflags[v4][v3] >= 0 )
			{
				v6 = &dungeon[v5][v3];
				if ( (*v6 == 2 || *v6 == 5) && *(v6 - 1) == 3 && dungeon[v5][v3 + 1] == 3 )
				{
					v7 = 0;
					while ( 1 )
					{
						v8 = *v6;
						if ( *v6 != 2 && v8 != 5 )
							break;
						if ( *(v6 - 1) != 3 || v6[1] != 3 )
							break;
						if ( v8 == 5 )
							v7 = 1;
						++v4;
						v6 += 40;
					}
					if ( !v7 && dTransVal2[111][40 * v4 + 80 + v3] >= 0 )
						*((_BYTE *)&dMonster[111][10 * v4 + 102] + v3) = 5;
				}
			}
			++v4;
		}
		while ( v4 < 39 );
		++v3;
	}
	while ( v3 < 39 );
	v9 = 40;
	do
	{
		v10 = 1;
		do
		{
			if ( dflags[v9 / 0x28][v10] >= 0 )
			{
				v11 = dungeon[v9 / 0x28][v10];
				if ( (v11 == 1 || v11 == 4)
				  && *((_BYTE *)&dMonster[111][v9 / 4 + 102] + v10) == 3
				  && dungeon[v9 / 0x28 + 1][v10] == 3 )
				{
					v12 = 0;
					while ( 1 )
					{
						v13 = dungeon[v9 / 0x28][v10];
						if ( v13 != 1 && v13 != 4 )
							break;
						v14 = &dungeon[v9 / 0x28 + 1][v10];
						if ( *(v14 - 80) != 3 || *v14 != 3 )
							break;
						if ( v13 == 4 )
							v12 = 1;
						++v10;
					}
					if ( !v12 && *(_BYTE *)(v9 + v10 + 5920151) >= 0 )
						*((_BYTE *)&dMonster[111][v9 / 4 + 111] + v10 + 3) = 4;
				}
			}
			++v10;
		}
		while ( v10 < 39 );
		v9 += 40;
	}
	while ( (signed int)v9 < 1560 );
}

//----- (0040D4CC) --------------------------------------------------------
void __cdecl L2DoorFix()
{
	signed int v0; // ecx
	char *v1; // eax
	signed int v2; // edx

	v0 = 1;
	do
	{
		v1 = &dungeon[1][v0];
		v2 = 39;
		do
		{
			if ( *v1 == 4 && *(v1 - 1) == 3 )
				*v1 = 7;
			if ( *v1 == 5 && *(v1 - 40) == 3 )
				*v1 = 9;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040D501) --------------------------------------------------------
void __fastcall LoadL2Dungeon(char *sFileName, int vx, int vy)
{
	char *v3; // esi
	unsigned char *v4; // edi
	signed int v5; // edx
	signed int v6; // eax
	signed int v7; // ecx
	int v8; // esi
	int v9; // eax
	int v10; // ebx
	int v11; // edi
	char *v12; // eax
	int v13; // ecx
	char v14; // dl
	signed int v15; // ecx
	_BYTE *v16; // eax
	signed int v17; // edx
	int v18; // ebx
	int (*v19)[112]; // esi
	char *v20; // ecx
	signed int v21; // edi
	int v22; // edx
	char v23; // al
	int v24; // ecx
	int (*v25)[112]; // edi
	char *v26; // eax
	int (*v27)[112]; // edx
	signed int v28; // ebx
	int v29; // esi
	int v30; // [esp+Ch] [ebp-Ch]
	char *ptr; // [esp+10h] [ebp-8h]
	int v32; // [esp+14h] [ebp-4h]
	int (*v33)[112]; // [esp+14h] [ebp-4h]

	v30 = vx;
	v3 = sFileName;
	InitDungeon();
	DRLG_InitTrans();
	v4 = LoadFileInMem(v3, 0);
	v5 = 0;
	ptr = (char *)v4;
	do
	{
		v6 = v5;
		v7 = 40;
		do
		{
			dflags[0][v6] = 0;
			dungeon[0][v6] = 12;
			v6 += 40;
			--v7;
		}
		while ( v7 );
		++v5;
	}
	while ( v5 < 40 );
	v8 = *v4;
	v9 = (int)(v4 + 2);
	v10 = 0;
	v11 = v4[2];
	v12 = (char *)(v9 + 2);
	if ( v11 > 0 )
	{
		do
		{
			if ( v8 > 0 )
			{
				v13 = v10;
				v32 = v8;
				do
				{
					v14 = *v12;
					if ( *v12 )
					{
						dflags[0][v13] |= 0x80u;
						dungeon[0][v13] = v14;
					}
					else
					{
						dungeon[0][v13] = 3;
					}
					v13 += 40;
					v12 += 2;
					--v32;
				}
				while ( v32 );
			}
			++v10;
		}
		while ( v10 < v11 );
	}
	v15 = 0;
	do
	{
		v16 = (unsigned char *)dungeon + v15;
		v17 = 40;
		do
		{
			if ( !*v16 )
				*v16 = 12;
			v16 += 40;
			--v17;
		}
		while ( v17 );
		++v15;
	}
	while ( v15 < 40 );
	DRLG_L2Pass3();
	DRLG_Init_Globals();
	v18 = 0;
	v33 = dPiece;
	do
	{
		v19 = v33;
		v20 = (char *)dArch + v18;
		v21 = 112;
		do
		{
			v22 = (*v19)[0];
			v23 = 0;
			if ( (*v19)[0] == 541 )
				v23 = 5;
			if ( v22 == 178 )
				v23 = 5;
			if ( v22 == 551 )
				v23 = 5;
			if ( v22 == 542 )
				v23 = 6;
			if ( v22 == 553 )
				v23 = 6;
			if ( v22 == 13 )
				v23 = 5;
			if ( v22 == 17 )
				v23 = 6;
			*v20 = v23;
			++v19;
			v20 += 112;
			--v21;
		}
		while ( v21 );
		v33 = (int (*)[112])((char *)v33 + 4);
		++v18;
	}
	while ( (signed int)v33 < (signed int)dPiece[1] );
	v24 = 0;
	v25 = dPiece;
	do
	{
		v26 = &dArch[0][v24 + 2];
		v27 = v25;
		v28 = 112;
		do
		{
			v29 = (*v27)[0];
			if ( (*v27)[0] == 132 )
			{
				*(v26 - 1) = 2;
				*v26 = 1;
			}
			else if ( v29 == 135 || v29 == 139 )
			{
				v26[110] = 3;
				v26[222] = 4;
			}
			++v27;
			v26 += 112;
			--v28;
		}
		while ( v28 );
		v25 = (int (*)[112])((char *)v25 + 4);
		++v24;
	}
	while ( (signed int)v25 < (signed int)dPiece[1] );
	ViewX = v30;
	ViewY = vy;
	SetMapMonsters(ptr, 0, 0);
	SetMapObjects(ptr, 0, 0);
	mem_free_dbg(ptr);
}

//----- (0040D6C1) --------------------------------------------------------
void __cdecl DRLG_L2Pass3()
{
	int v0; // eax
	int *v1; // edx
	int *v2; // eax
	signed int v3; // ecx
	signed int v4; // ebx
	int *v5; // ecx
	unsigned char *v6; // edx
	unsigned short *v7; // esi
	unsigned short v8; // ax
	int v9; // eax
	int v10; // ST24_4
	int v11; // ST20_4
	int v12; // ST1C_4
	signed int v13; // [esp+Ch] [ebp-1Ch]
	int *v14; // [esp+10h] [ebp-18h]
	int v15; // [esp+14h] [ebp-14h]
	int v16; // [esp+18h] [ebp-10h]
	int v17; // [esp+1Ch] [ebp-Ch]
	int v18; // [esp+20h] [ebp-8h]

	v0 = *((unsigned short *)pMegaTiles + 44) + 1;
	v18 = *((unsigned short *)pMegaTiles + 44) + 1;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 45);
	v17 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 46);
	v16 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 47);
	v15 = v0 + 1;
	v1 = dPiece[1];
	do
	{
		v2 = v1;
		v3 = 56;
		do
		{
			*(v2 - 112) = v18;
			*v2 = v17;
			*(v2 - 111) = v16;
			v2[1] = v15;
			v2 += 224;
			--v3;
		}
		while ( v3 );
		v1 += 2;
	}
	while ( (signed int)v1 < (signed int)dPiece[2] );
	v4 = 0;
	v14 = &dPiece[17][16];
	do
	{
		v5 = v14;
		v6 = (unsigned char *)dungeon + v4;
		v13 = 40;
		do
		{
			v7 = (unsigned short *)((char *)pMegaTiles + 8 * (*v6 - 1));
			v8 = *v7;
			++v7;
			v9 = v8 + 1;
			v10 = v9;
			_LOWORD(v9) = *v7;
			++v7;
			v11 = ++v9;
			_LOWORD(v9) = *v7;
			v12 = ++v9;
			_LOWORD(v9) = v7[1];
			v6 += 40;
			*(v5 - 112) = v10;
			*v5 = v11;
			*(v5 - 111) = v12;
			v5[1] = v9 + 1;
			v5 += 224;
			--v13;
		}
		while ( v13 );
		v14 += 2;
		++v4;
	}
	while ( v4 < 40 );
}

//----- (0040D7B3) --------------------------------------------------------
void __fastcall LoadPreL2Dungeon(char *sFileName, int vx, int vy)
{
	char *v3; // esi
	unsigned char *v4; // ebx
	signed int v5; // esi
	signed int v6; // edx
	signed int v7; // eax
	int v8; // eax
	int v9; // edi
	char *v10; // edx
	int v11; // esi
	char v12; // bl
	signed int v13; // eax
	_BYTE *v14; // edx
	signed int v15; // esi
	signed int v16; // eax
	signed int v17; // edx
	signed int v18; // esi
	unsigned char *ptr; // [esp+8h] [ebp-Ch]
	int v20; // [esp+Ch] [ebp-8h]
	int v21; // [esp+10h] [ebp-4h]

	v3 = sFileName;
	InitDungeon();
	DRLG_InitTrans();
	v4 = LoadFileInMem(v3, 0);
	v5 = 0;
	ptr = v4;
	do
	{
		v6 = v5;
		v7 = 40;
		do
		{
			dflags[0][v6] = 0;
			dungeon[0][v6] = 12;
			v6 += 40;
			--v7;
		}
		while ( v7 );
		++v5;
	}
	while ( v5 < 40 );
	v21 = 0;
	v8 = v4[2];
	v9 = *v4;
	v10 = (char *)(v4 + 4);
	if ( v8 > 0 )
	{
		do
		{
			if ( v9 > 0 )
			{
				v11 = v21;
				v20 = v9;
				do
				{
					v12 = *v10;
					if ( *v10 )
					{
						dflags[0][v11] |= 0x80u;
						dungeon[0][v11] = v12;
					}
					else
					{
						dungeon[0][v11] = 3;
					}
					v11 += 40;
					v10 += 2;
					--v20;
				}
				while ( v20 );
			}
			++v21;
		}
		while ( v21 < v8 );
	}
	v13 = 0;
	do
	{
		v14 = (unsigned char *)dungeon + v13;
		v15 = 40;
		do
		{
			if ( !*v14 )
				*v14 = 12;
			v14 += 40;
			--v15;
		}
		while ( v15 );
		++v13;
	}
	while ( v13 < 40 );
	v16 = 0;
	do
	{
		v17 = v16;
		v18 = 40;
		do
		{
			pdungeon[0][v17] = dungeon[0][v17];
			v17 += 40;
			--v18;
		}
		while ( v18 );
		++v16;
	}
	while ( v16 < 40 );
	mem_free_dbg(ptr);
}

//----- (0040D888) --------------------------------------------------------
void __fastcall CreateL2Dungeon(int seed, int entry)
{
	int v2; // esi
	int v3; // edi
	int v4; // ecx

	v2 = entry;
	v3 = seed;
	if ( gbMaxPlayers == 1 )
	{
		if ( currlevel == 7 )
		{
			if ( quests[8]._qactive )
				goto LABEL_10;
			currlevel = 6;
			CreateL2Dungeon(glSeedTbl[6], 4);
			currlevel = 7;
		}
		if ( currlevel == 8 )
		{
			if ( quests[8]._qactive )
			{
				v4 = glSeedTbl[7];
				currlevel = 7;
			}
			else
			{
				v4 = glSeedTbl[6];
				currlevel = 6;
			}
			CreateL2Dungeon(v4, 4);
			currlevel = 8;
		}
	}
LABEL_10:
	SetRndSeed(v3);
	dminx = 16;
	dminy = 16;
	dmaxx = 96;
	dmaxy = 96;
	DRLG_InitTrans();
	DRLG_InitSetPC();
	DRLG_LoadL2SP();
	DRLG_L2(v2);
	DRLG_L2Pass3();
	DRLG_FreeL2SP();
	DRLG_InitL2Vals();
	DRLG_SetPC();
}
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;
// 679660: using guessed type char gbMaxPlayers;

//----- (0040D94F) --------------------------------------------------------
void __cdecl DRLG_LoadL2SP()
{
	int v0; // eax
	char *v1; // ecx
	int v2; // eax
	int v3; // eax

	setloadflag_2 = 0;
	_LOBYTE(v0) = QuestStatus(8);
	if ( v0 )
	{
		v1 = "Levels\\L2Data\\Blind2.DUN";
	}
	else
	{
		_LOBYTE(v2) = QuestStatus(9);
		if ( v2 )
		{
			v1 = "Levels\\L2Data\\Blood1.DUN";
		}
		else
		{
			_LOBYTE(v3) = QuestStatus(14);
			if ( !v3 )
				return;
			v1 = "Levels\\L2Data\\Bonestr2.DUN";
		}
	}
	pSetPiece_2 = (char *)LoadFileInMem(v1, 0);
	setloadflag_2 = 1;
}
// 5B50D8: using guessed type int setloadflag_2;

//----- (0040D9A4) --------------------------------------------------------
void __cdecl DRLG_FreeL2SP()
{
	char *v0; // ecx

	v0 = pSetPiece_2;
	pSetPiece_2 = 0;
	mem_free_dbg(v0);
}

//----- (0040D9B6) --------------------------------------------------------
void __fastcall DRLG_L2(int entry)
{
	int v1; // esi
	int v2; // eax
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // eax
	signed int v10; // ecx
	signed int v11; // eax
	signed int v12; // esi
	int v13; // [esp+10h] [ebp-4h]

	v1 = 0;
	v13 = entry;
	do
	{
		nRoomCnt = 0;
		InitDungeon();
		DRLG_InitTrans();
		CreateDungeon();
		if ( !v2 )
			continue;
		L2TileFix();
		if ( setloadflag_2 )
			DRLG_L2SetRoom(nSx1, nSy1);
		DRLG_L2FloodTVal();
		DRLG_L2TransFix();
		if ( !v13 )
		{
			_LOBYTE(v3) = DRLG_L2PlaceMiniSet((char *)USTAIRS, 1, 1, -1, -1, 1, 0);
			v1 = v3;
			if ( !v3 )
				goto LABEL_21;
			_LOBYTE(v4) = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 0, 1);
			v1 = v4;
			if ( !v4 || currlevel != 5 )
				goto LABEL_21;
			_LOBYTE(v5) = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 0, 6);
LABEL_20:
			v1 = v5;
LABEL_21:
			ViewY -= 2;
			continue;
		}
		_LOBYTE(v6) = DRLG_L2PlaceMiniSet((char *)USTAIRS, 1, 1, -1, -1, 0, 0);
		v1 = v6;
		if ( v13 != 1 )
		{
			if ( !v6 )
				goto LABEL_21;
			_LOBYTE(v9) = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 0, 1);
			v1 = v9;
			if ( !v9 || currlevel != 5 )
				goto LABEL_21;
			_LOBYTE(v5) = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 1, 6);
			goto LABEL_20;
		}
		if ( v6 )
		{
			_LOBYTE(v7) = DRLG_L2PlaceMiniSet((char *)DSTAIRS, 1, 1, -1, -1, 1, 1);
			v1 = v7;
			if ( v7 )
			{
				if ( currlevel == 5 )
				{
					_LOBYTE(v8) = DRLG_L2PlaceMiniSet((char *)WARPSTAIRS, 1, 1, -1, -1, 0, 6);
					v1 = v8;
				}
			}
		}
		--ViewX;
	}
	while ( !v1 );
	L2LockoutFix();
	L2DoorFix();
	L2DirtFix();
	DRLG_PlaceThemeRooms(6, 10, 3, 0, 0);
	DRLG_L2PlaceRndSet((char *)CTRDOOR1, 100);
	DRLG_L2PlaceRndSet((char *)CTRDOOR2, 100);
	DRLG_L2PlaceRndSet((char *)CTRDOOR3, 100);
	DRLG_L2PlaceRndSet((char *)CTRDOOR4, 100);
	DRLG_L2PlaceRndSet((char *)CTRDOOR5, 100);
	DRLG_L2PlaceRndSet((char *)CTRDOOR6, 100);
	DRLG_L2PlaceRndSet((char *)CTRDOOR7, 100);
	DRLG_L2PlaceRndSet((char *)CTRDOOR8, 100);
	DRLG_L2PlaceRndSet((char *)VARCH33, 100);
	DRLG_L2PlaceRndSet((char *)VARCH34, 100);
	DRLG_L2PlaceRndSet((char *)VARCH35, 100);
	DRLG_L2PlaceRndSet((char *)VARCH36, 100);
	DRLG_L2PlaceRndSet((char *)VARCH37, 100);
	DRLG_L2PlaceRndSet((char *)VARCH38, 100);
	DRLG_L2PlaceRndSet((char *)VARCH39, 100);
	DRLG_L2PlaceRndSet((char *)VARCH40, 100);
	DRLG_L2PlaceRndSet((char *)VARCH1, 100);
	DRLG_L2PlaceRndSet((char *)VARCH2, 100);
	DRLG_L2PlaceRndSet((char *)VARCH3, 100);
	DRLG_L2PlaceRndSet((char *)VARCH4, 100);
	DRLG_L2PlaceRndSet((char *)VARCH5, 100);
	DRLG_L2PlaceRndSet((char *)VARCH6, 100);
	DRLG_L2PlaceRndSet((char *)VARCH7, 100);
	DRLG_L2PlaceRndSet((char *)VARCH8, 100);
	DRLG_L2PlaceRndSet((char *)VARCH9, 100);
	DRLG_L2PlaceRndSet((char *)VARCH10, 100);
	DRLG_L2PlaceRndSet((char *)VARCH11, 100);
	DRLG_L2PlaceRndSet((char *)VARCH12, 100);
	DRLG_L2PlaceRndSet((char *)VARCH13, 100);
	DRLG_L2PlaceRndSet((char *)VARCH14, 100);
	DRLG_L2PlaceRndSet((char *)VARCH15, 100);
	DRLG_L2PlaceRndSet((char *)VARCH16, 100);
	DRLG_L2PlaceRndSet((char *)VARCH17, 100);
	DRLG_L2PlaceRndSet((char *)VARCH18, 100);
	DRLG_L2PlaceRndSet((char *)VARCH19, 100);
	DRLG_L2PlaceRndSet((char *)VARCH20, 100);
	DRLG_L2PlaceRndSet((char *)VARCH21, 100);
	DRLG_L2PlaceRndSet((char *)VARCH22, 100);
	DRLG_L2PlaceRndSet((char *)VARCH23, 100);
	DRLG_L2PlaceRndSet((char *)VARCH24, 100);
	DRLG_L2PlaceRndSet((char *)VARCH25, 100);
	DRLG_L2PlaceRndSet((char *)VARCH26, 100);
	DRLG_L2PlaceRndSet((char *)VARCH27, 100);
	DRLG_L2PlaceRndSet((char *)VARCH28, 100);
	DRLG_L2PlaceRndSet((char *)VARCH29, 100);
	DRLG_L2PlaceRndSet((char *)VARCH30, 100);
	DRLG_L2PlaceRndSet((char *)VARCH31, 100);
	DRLG_L2PlaceRndSet((char *)VARCH32, 100);
	DRLG_L2PlaceRndSet((char *)HARCH1, 100);
	DRLG_L2PlaceRndSet((char *)HARCH2, 100);
	DRLG_L2PlaceRndSet((char *)HARCH3, 100);
	DRLG_L2PlaceRndSet((char *)HARCH4, 100);
	DRLG_L2PlaceRndSet((char *)HARCH5, 100);
	DRLG_L2PlaceRndSet((char *)HARCH6, 100);
	DRLG_L2PlaceRndSet((char *)HARCH7, 100);
	DRLG_L2PlaceRndSet((char *)HARCH8, 100);
	DRLG_L2PlaceRndSet((char *)HARCH9, 100);
	DRLG_L2PlaceRndSet((char *)HARCH10, 100);
	DRLG_L2PlaceRndSet((char *)HARCH11, 100);
	DRLG_L2PlaceRndSet((char *)HARCH12, 100);
	DRLG_L2PlaceRndSet((char *)HARCH13, 100);
	DRLG_L2PlaceRndSet((char *)HARCH14, 100);
	DRLG_L2PlaceRndSet((char *)HARCH15, 100);
	DRLG_L2PlaceRndSet((char *)HARCH16, 100);
	DRLG_L2PlaceRndSet((char *)HARCH17, 100);
	DRLG_L2PlaceRndSet((char *)HARCH18, 100);
	DRLG_L2PlaceRndSet((char *)HARCH19, 100);
	DRLG_L2PlaceRndSet((char *)HARCH20, 100);
	DRLG_L2PlaceRndSet((char *)HARCH21, 100);
	DRLG_L2PlaceRndSet((char *)HARCH22, 100);
	DRLG_L2PlaceRndSet((char *)HARCH23, 100);
	DRLG_L2PlaceRndSet((char *)HARCH24, 100);
	DRLG_L2PlaceRndSet((char *)HARCH25, 100);
	DRLG_L2PlaceRndSet((char *)HARCH26, 100);
	DRLG_L2PlaceRndSet((char *)HARCH27, 100);
	DRLG_L2PlaceRndSet((char *)HARCH28, 100);
	DRLG_L2PlaceRndSet((char *)HARCH29, 100);
	DRLG_L2PlaceRndSet((char *)HARCH30, 100);
	DRLG_L2PlaceRndSet((char *)HARCH31, 100);
	DRLG_L2PlaceRndSet((char *)HARCH32, 100);
	DRLG_L2PlaceRndSet((char *)HARCH33, 100);
	DRLG_L2PlaceRndSet((char *)HARCH34, 100);
	DRLG_L2PlaceRndSet((char *)HARCH35, 100);
	DRLG_L2PlaceRndSet((char *)HARCH36, 100);
	DRLG_L2PlaceRndSet((char *)HARCH37, 100);
	DRLG_L2PlaceRndSet((char *)HARCH38, 100);
	DRLG_L2PlaceRndSet((char *)HARCH39, 100);
	DRLG_L2PlaceRndSet((char *)HARCH40, 100);
	DRLG_L2PlaceRndSet((char *)CRUSHCOL, 99);
	DRLG_L2PlaceRndSet((char *)RUINS1, 10);
	DRLG_L2PlaceRndSet((char *)RUINS2, 10);
	DRLG_L2PlaceRndSet((char *)RUINS3, 10);
	DRLG_L2PlaceRndSet((char *)RUINS4, 10);
	DRLG_L2PlaceRndSet((char *)RUINS5, 10);
	DRLG_L2PlaceRndSet((char *)RUINS6, 10);
	DRLG_L2PlaceRndSet((char *)RUINS7, 50);
	DRLG_L2PlaceRndSet((char *)PANCREAS1, 1);
	DRLG_L2PlaceRndSet((char *)PANCREAS2, 1);
	DRLG_L2PlaceRndSet((char *)BIG1, 3);
	DRLG_L2PlaceRndSet((char *)BIG2, 3);
	DRLG_L2PlaceRndSet((char *)BIG3, 3);
	DRLG_L2PlaceRndSet((char *)BIG4, 3);
	DRLG_L2PlaceRndSet((char *)BIG5, 3);
	DRLG_L2PlaceRndSet((char *)BIG6, 20);
	DRLG_L2PlaceRndSet((char *)BIG7, 20);
	DRLG_L2PlaceRndSet((char *)BIG8, 3);
	DRLG_L2PlaceRndSet((char *)BIG9, 20);
	DRLG_L2PlaceRndSet((char *)BIG10, 20);
	DRLG_L2Subs();
	DRLG_L2Shadows();
	v10 = 0;
	do
	{
		v11 = v10;
		v12 = 40;
		do
		{
			pdungeon[0][v11] = dungeon[0][v11];
			v11 += 40;
			--v12;
		}
		while ( v12 );
		++v10;
	}
	while ( v10 < 40 );
	DRLG_Init_Globals();
	DRLG_CheckQuests(nSx1, nSy1);
}
// 5B50D8: using guessed type int setloadflag_2;

//----- (0040E074) --------------------------------------------------------
bool __fastcall DRLG_L2PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int ldir)
{
	int v7; // ebx
	int v8; // esi
	int v9; // edi
	int v10; // edx
	int v11; // eax
	int v12; // ecx
	int v13; // esi
	int v14; // ebx
	int v15; // ecx
	int v16; // eax
	int v17; // ecx
	int v18; // eax
	int v19; // ecx
	int v20; // edi
	signed int i; // eax
	int v22; // ecx
	char v23; // dl
	int v24; // eax
	int v25; // edi
	char *v26; // edx
	char v27; // bl
	bool result; // al
	char *v29; // [esp+Ch] [ebp-28h]
	int v30; // [esp+10h] [ebp-24h]
	int v31; // [esp+14h] [ebp-20h]
	int v32; // [esp+18h] [ebp-1Ch]
	signed int v33; // [esp+1Ch] [ebp-18h]
	int v34; // [esp+20h] [ebp-14h]
	int v35; // [esp+24h] [ebp-10h]
	int v36; // [esp+28h] [ebp-Ch]
	int max; // [esp+2Ch] [ebp-8h]
	int v38; // [esp+30h] [ebp-4h]
	int v39; // [esp+30h] [ebp-4h]
	int tmaxa; // [esp+3Ch] [ebp+8h]

	v7 = (unsigned char)miniset[1];
	v8 = tmin;
	v9 = (unsigned char)*miniset;
	v29 = miniset;
	v10 = tmax - tmin;
	v34 = (unsigned char)*miniset;
	v35 = (unsigned char)miniset[1];
	if ( v10 )
	{
		_LOBYTE(miniset) = 0;
		v30 = v8 + random((int)miniset, v10);
	}
	else
	{
		v30 = 1;
	}
	v31 = 0;
	if ( v30 <= 0 )
	{
		v13 = ldir;
		v14 = v38;
	}
	else
	{
		max = 40 - v9;
		v36 = 40 - v7;
		do
		{
			_LOBYTE(miniset) = 0;
			v11 = random((int)miniset, max);
			_LOBYTE(v12) = 0;
			v13 = v11;
			v33 = 0;
			v14 = random(v12, v36);
			v39 = v14;
			do
			{
				if ( v33 >= 200 )
					return 0;
				tmaxa = 1;
				if ( v13 >= nSx1 && v13 <= nSx2 && v14 >= nSy1 && v14 <= nSy2 )
					tmaxa = 0;
				if ( cx != -1 )
				{
					v15 = cx - v34;
					if ( v13 >= cx - v34 && v13 <= cx + 12 )
					{
						_LOBYTE(v15) = 0;
						v16 = random(v15, max);
						_LOBYTE(v17) = 0;
						v13 = v16;
						tmaxa = 0;
						v39 = random(v17, v36);
						v14 = v39;
					}
				}
				if ( cy != -1 && v14 >= cy - v35 && v14 <= cy + 12 )
				{
					v18 = random(cy - v35, max);
					_LOBYTE(v19) = 0;
					v13 = v18;
					tmaxa = 0;
					v39 = random(v19, v36);
					v14 = v39;
				}
				v20 = 0;
				for ( i = 2; v20 < v35; ++v20 )
				{
					if ( tmaxa != 1 )
						break;
					v32 = 0;
					if ( v34 > 0 )
					{
						v22 = v14 + v20 + 40 * v13;
						do
						{
							if ( tmaxa != 1 )
								break;
							v23 = v29[i];
							if ( v23 && dungeon[0][v22] != v23 )
								tmaxa = 0;
							if ( dflags[0][v22] )
								tmaxa = 0;
							++i;
							++v32;
							v22 += 40;
						}
						while ( v32 < v34 );
					}
				}
				if ( !tmaxa && ++v13 == max )
				{
					v13 = 0;
					v39 = ++v14;
					if ( v14 == v36 )
					{
						v39 = 0;
						v14 = 0;
					}
				}
				++v33;
			}
			while ( !tmaxa );
			if ( v33 >= 200 )
				return 0;
			v24 = 0;
			for ( miniset = (char *)(v34 * v35 + 2); v24 < v35; ++v24 )
			{
				v25 = v34;
				if ( v34 > 0 )
				{
					v26 = &dungeon[v13][v24 + v14];
					do
					{
						v27 = v29[(_DWORD)miniset];
						if ( v27 )
							*v26 = v27;
						++miniset;
						v26 += 40;
						--v25;
					}
					while ( v25 );
					v14 = v39;
				}
			}
			++v31;
		}
		while ( v31 < v30 );
	}
	result = 1;
	if ( set_view == 1 )
	{
		ViewX = 2 * v13 + 21;
		ViewY = 2 * v14 + 22;
	}
	if ( !ldir )
	{
		LvlViewX = 2 * v13 + 21;
		LvlViewY = 2 * v14 + 22;
	}
	if ( ldir == 6 )
	{
		LvlViewX = 2 * v13 + 21;
		LvlViewY = 2 * v14 + 22;
	}
	return result;
}
// 5276CC: using guessed type int nSx2;
// 5276D4: using guessed type int nSy2;
// 5CF320: using guessed type int LvlViewY;
// 5CF324: using guessed type int LvlViewX;

//----- (0040E2D1) --------------------------------------------------------
void __fastcall DRLG_L2PlaceRndSet(char *miniset, int probability)
{
	char *v2; // ebx
	signed int v3; // esi
	signed int v4; // ecx
	int v5; // edx
	signed int v6; // edi
	signed int i; // edx
	signed int v8; // esi
	int v9; // eax
	char v10; // cl
	int v11; // edi
	_BYTE *v12; // ecx
	int v13; // esi
	int v14; // eax
	int v15; // eax
	signed int j; // edx
	signed int v17; // esi
	char *v18; // eax
	char v19; // cl
	int v20; // [esp+8h] [ebp-3Ch]
	char *v21; // [esp+10h] [ebp-34h]
	int v22; // [esp+14h] [ebp-30h]
	int v23; // [esp+18h] [ebp-2Ch]
	int v24; // [esp+1Ch] [ebp-28h]
	int v25; // [esp+20h] [ebp-24h]
	int v26; // [esp+24h] [ebp-20h]
	int v27; // [esp+28h] [ebp-1Ch]
	int v28; // [esp+2Ch] [ebp-18h]
	int v29; // [esp+30h] [ebp-14h]
	signed int v30; // [esp+34h] [ebp-10h]
	signed int v31; // [esp+38h] [ebp-Ch]
	int v32; // [esp+3Ch] [ebp-8h]
	signed int v33; // [esp+40h] [ebp-4h]

	v2 = miniset;
	v32 = 0;
	v20 = probability;
	v3 = (unsigned char)miniset[1];
	v4 = (unsigned char)*miniset;
	v21 = v2;
	v30 = v4;
	v26 = 40 - v3;
	v31 = v3;
	if ( 40 - v3 > 0 )
	{
		v27 = 40 - v4;
		v23 = -v3;
		while ( 1 )
		{
			v5 = 0;
			v25 = 0;
			if ( v27 > 0 )
			{
				v29 = -v4;
				v22 = v4 * v3 + 2;
				v28 = 0;
				v24 = -40 * v4;
				do
				{
					v33 = 1;
					v6 = 2;
					if ( v5 >= nSx1 && v5 <= nSx2 && v32 >= nSy1 && v32 <= nSy2 )
						v33 = 0;
					for ( i = 0; i < v31; ++i )
					{
						if ( v33 != 1 )
							break;
						v8 = 0;
						if ( v30 > 0 )
						{
							v9 = v32 + i + v28;
							do
							{
								if ( v33 != 1 )
									break;
								v10 = v2[v6];
								if ( v10 && dungeon[0][v9] != v10 )
									v33 = 0;
								if ( dflags[0][v9] )
									v33 = 0;
								++v6;
								++v8;
								v9 += 40;
							}
							while ( v8 < v30 );
						}
					}
					v11 = v22;
					if ( v33 == 1 )
					{
						v12 = (_BYTE *)v31;
						v13 = v23;
						if ( v23 >= v32 + 2 * v31 )
						{
LABEL_34:
							_LOBYTE(v12) = 0;
							if ( random((int)v12, 100) < v20 )
							{
								for ( j = 0; j < v31; ++j )
								{
									v17 = v30;
									if ( v30 > 0 )
									{
										v18 = (char *)dungeon + j + v28 + v32;
										do
										{
											v19 = v2[v11];
											if ( v19 )
												*v18 = v19;
											++v11;
											v18 += 40;
											--v17;
										}
										while ( v17 );
									}
								}
							}
						}
						else
						{
							while ( v33 == 1 )
							{
								v12 = (_BYTE *)v30;
								v14 = v25 + 2 * v30;
								if ( v29 < v14 )
								{
									v15 = v14 - v29;
									v12 = (unsigned char *)dungeon + v24 + v13;
									do
									{
										if ( *v12 == v2[v22] )
											v33 = 0;
										v12 += 40;
										--v15;
									}
									while ( v15 );
									v2 = v21;
								}
								if ( ++v13 >= v32 + 2 * v31 )
								{
									if ( v33 != 1 )
										break;
									goto LABEL_34;
								}
							}
						}
					}
					v24 += 40;
					v28 += 40;
					v5 = v25 + 1;
					++v29;
					++v25;
				}
				while ( v25 < v27 );
			}
			++v32;
			++v23;
			if ( v32 >= v26 )
				break;
			v4 = v30;
			v3 = v31;
		}
	}
}
// 5276CC: using guessed type int nSx2;
// 5276D4: using guessed type int nSy2;

//----- (0040E49C) --------------------------------------------------------
void __cdecl DRLG_L2Subs()
{
	signed int v0; // edi
	unsigned char v1; // bl
	int v2; // eax
	signed int v3; // edx
	int v4; // esi
	int i; // ebx
	int j; // eax
	signed int v7; // [esp+Ch] [ebp-10h]
	char *v8; // [esp+10h] [ebp-Ch]
	signed int v9; // [esp+14h] [ebp-8h]
	int v10; // [esp+18h] [ebp-4h]

	v0 = 3;
	v9 = -2;
	v7 = 3;
	do
	{
		v10 = 0;
		v8 = &dungeon[0][v9 + 2];
		do
		{
			if ( (v10 < nSx1 || v10 > nSx2) && (v0 - 3 < nSy1 || v0 - 3 > nSy2) && !random(0, 4) )
			{
				v1 = BTYPESL2[(unsigned char)*v8];
				if ( v1 )
				{
					v2 = random(0, 16);
					v3 = -1;
					while ( v2 >= 0 )
					{
						if ( ++v3 == 161 )
							v3 = 0;
						if ( v1 == BTYPESL2[v3] )
							--v2;
					}
					v4 = v9;
					for ( i = v0 - 1; v4 < i; ++v4 )
					{
						for ( j = v10 - 2; j < v10 + 2; ++j )
						{
							v0 = v7;
							if ( (unsigned char)dungeon[j][v4] == v3 )
							{
								v4 = v7;
								j = v10 + 2;
							}
						}
					}
					if ( v4 < v0 )
						*v8 = v3;
				}
			}
			++v10;
			v8 += 40;
		}
		while ( v10 < 40 );
		++v9;
		v7 = ++v0;
	}
	while ( v0 - 3 < 40 );
}
// 5276CC: using guessed type int nSx2;
// 5276D4: using guessed type int nSy2;

//----- (0040E59C) --------------------------------------------------------
void __cdecl DRLG_L2Shadows()
{
	char *v0; // eax
	unsigned char *v1; // esi
	unsigned char v2; // dl
	signed int v3; // edi
	char v4; // cl
	char v5; // cl
	char v6; // cl
	char v7; // cl
	char v8; // cl
	signed int v9; // [esp+8h] [ebp-Ch]
	signed int v10; // [esp+Ch] [ebp-8h]
	unsigned char v11; // [esp+11h] [ebp-3h]
	unsigned char v12; // [esp+12h] [ebp-2h]
	unsigned char v13; // [esp+13h] [ebp-1h]

	v10 = 1;
	do
	{
		v9 = 39;
		v0 = &dungeon[0][v10 + 39];
		do
		{
			v1 = &SPATSL2[0].s1;
			v2 = BSTYPESL2[(unsigned char)v0[1]];
			v12 = BSTYPESL2[(unsigned char)*(v0 - 39)];
			v11 = BSTYPESL2[(unsigned char)*v0];
			v13 = BSTYPESL2[(unsigned char)*(v0 - 40)];
			do
			{
				if ( *(v1 - 1) == v2 )
				{
					v3 = 1;
					if ( *v1 && *v1 != v13 )
						v3 = 0;
					v4 = v1[1];
					if ( v4 && v4 != v11 )
						v3 = 0;
					v5 = v1[2];
					if ( v5 && v5 != v12 )
						v3 = 0;
					if ( v3 == 1 )
					{
						v6 = v1[3];
						if ( v6 )
							*(v0 - 40) = v6;
						v7 = v1[4];
						if ( v7 )
							*v0 = v7;
						v8 = v1[5];
						if ( v8 )
							*(v0 - 39) = v8;
					}
				}
				v1 += 7;
			}
			while ( (signed int)v1 < (signed int)&word_48489A + 1 );
			v0 += 40;
			--v9;
		}
		while ( v9 );
		++v10;
	}
	while ( v10 < 40 );
}
// 48489A: using guessed type short word_48489A;

//----- (0040E66B) --------------------------------------------------------
void __fastcall DRLG_L2SetRoom(int rx1, int ry1)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax
	char v5; // bl
	int v6; // [esp+8h] [ebp-Ch]
	char *v7; // [esp+Ch] [ebp-8h]
	int v8; // [esp+10h] [ebp-4h]

	v8 = 0;
	v2 = (unsigned char)pSetPiece_2[2];
	v3 = (unsigned char)*pSetPiece_2;
	setpc_x = rx1;
	setpc_y = ry1;
	setpc_w = v3;
	setpc_h = v2;
	v7 = pSetPiece_2 + 4;
	if ( v2 > 0 )
	{
		do
		{
			if ( v3 > 0 )
			{
				v6 = v3;
				v4 = ry1 + v8 + 40 * rx1;
				do
				{
					v5 = *v7;
					if ( *v7 )
					{
						dflags[0][v4] |= 0x80u;
						dungeon[0][v4] = v5;
					}
					else
					{
						dungeon[0][v4] = 3;
					}
					v7 += 2;
					v4 += 40;
					--v6;
				}
				while ( v6 );
			}
			++v8;
		}
		while ( v8 < v2 );
	}
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (0040E6F0) --------------------------------------------------------
void __cdecl L2TileFix()
{
	signed int v0; // edx
	char *v1; // eax
	signed int v2; // esi
	char v3; // cl

	v0 = 0;
	do
	{
		v1 = (char *)dungeon + v0;
		v2 = 40;
		do
		{
			v3 = *v1;
			if ( *v1 == 1 && v1[1] == 3 )
				v1[1] = 1;
			if ( v3 == 3 )
			{
				if ( v1[1] == 1 )
					v1[1] = 3;
				if ( v1[40] == 7 )
					v1[40] = 3;
			}
			if ( v3 == 2 && v1[40] == 3 )
				v1[40] = 2;
			if ( v3 == 11 && v1[40] == 14 )
				v1[40] = 16;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040E74F) --------------------------------------------------------
void __cdecl CreateDungeon()
{
	int v0; // esi
	int v1; // edx
	int v2; // ecx
	signed int v3; // esi
	char *v4; // eax
	signed int v5; // ebx
	_BYTE *v6; // ecx
	bool v7; // zf
	int v8; // eax
	int v9; // edi
	int v10; // esi
	signed int v11; // [esp-4h] [ebp-20h]
	int nX1; // [esp+8h] [ebp-14h]
	int nY1; // [esp+Ch] [ebp-10h]
	int nX2; // [esp+10h] [ebp-Ch]
	int nY2; // [esp+14h] [ebp-8h]
	int nHd; // [esp+18h] [ebp-4h]

	v0 = 0;
	v1 = 0;
	v2 = 0;
	if ( currlevel == 5 )
	{
		if ( !quests[9]._qactive )
			goto LABEL_12;
		v1 = 20;
		v0 = 14;
	}
	else
	{
		if ( currlevel == 6 )
		{
			if ( !quests[14]._qactive )
				goto LABEL_12;
			v11 = 10;
		}
		else
		{
			if ( currlevel != 7 || !quests[8]._qactive )
				goto LABEL_12;
			v11 = 15;
		}
		v0 = v11;
		v1 = v11;
	}
	v2 = 1;
LABEL_12:
	CreateRoom(2, 2, 39, 39, 0, 0, v2, v1, v0);
	while ( pHallList )
	{
		GetHall(&nX1, &nY1, &nX2, &nY2, &nHd);
		ConnectHall(nX1, nY1, nX2, nY2, nHd);
	}
	v3 = 0;
	do
	{
		v4 = &predungeon[-1][v3];
		v5 = 41;
		do
		{
			v6 = (unsigned  char *)v4 + 40;
			if ( v4[40] == 67 )
				*v6 = 35;
			if ( *v6 == 66 )
				*v6 = 35;
			if ( *v6 == 69 )
				*v6 = 35;
			if ( *v6 == 65 )
				*v6 = 35;
			if ( *v6 == 44 )
			{
				v7 = *(v4 - 1) == 32;
				*v6 = 46;
				if ( v7 )
					*(v4 - 1) = 35;
				if ( *v4 == 32 )
					*v4 = 35;
				if ( v4[1] == 32 )
					v4[1] = 35;
				if ( v4[79] == 32 )
					v4[79] = 35;
				if ( v4[80] == 32 )
					v4[80] = 35;
				if ( v4[81] == 32 )
					v4[81] = 35;
				if ( v4[39] == 32 )
					v4[39] = 35;
				if ( v4[41] == 32 )
					v4[41] = 35;
			}
			--v5;
			v4 += 40;
		}
		while ( v5 );
		++v3;
	}
	while ( v3 <= 40 );
	DL2_FillVoids();
	if ( v8 )
	{
		v9 = 0;
		do
		{
			v10 = 0;
			do
				DoPatternCheck(v10++, v9);
			while ( v10 < 40 );
			++v9;
		}
		while ( v9 < 40 );
	}
}

//----- (0040E8A4) --------------------------------------------------------
void __fastcall CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, int ForceHW, int nH, int nW)
{
	int v9; // esi
	int v10; // ebx
	int v11; // edx
	int v12; // eax
	int v13; // edx
	int v14; // edx
	int v15; // edi
	int v16; // ecx
	int v17; // esi
	int v18; // ebx
	int v19; // edx
	int v20; // ecx
	int v21; // eax
	int v22; // ecx
	int v23; // eax
	int v24; // eax
	int v25; // ecx
	int v26; // eax
	int *v27; // ecx
	int v28; // eax
	int v29; // eax
	int *v30; // ecx
	int v31; // eax
	int nX1a; // [esp+Ch] [ebp-30h]
	int v33; // [esp+10h] [ebp-2Ch]
	int v34; // [esp+14h] [ebp-28h]
	int v35; // [esp+18h] [ebp-24h]
	int v36; // [esp+1Ch] [ebp-20h]
	int v37; // [esp+20h] [ebp-1Ch]
	int nY1a; // [esp+24h] [ebp-18h]
	int v39; // [esp+28h] [ebp-14h]
	int v40; // [esp+2Ch] [ebp-10h]
	int v41; // [esp+30h] [ebp-Ch]
	int v42; // [esp+34h] [ebp-8h]
	int v43; // [esp+38h] [ebp-4h]
	int *ForceHWa; // [esp+54h] [ebp+18h]
	int *ForceHWb; // [esp+54h] [ebp+18h]

	v39 = nY1;
	v37 = nX1;
	if ( nRoomCnt < 80 )
	{
		v40 = nX2 - 2;
		nY1a = nY1 + 2;
		while ( 1 )
		{
			v9 = nX2 - v37;
			v10 = nY2 - v39;
			if ( nX2 - v37 < Area_Min || v10 < Area_Min )
				return;
			if ( v9 > Room_Max )
				break;
			nX1 = Room_Min;
			if ( v9 > Room_Min )
			{
				v11 = v9 - Room_Min;
				goto LABEL_7;
			}
			v41 = nX2 - v37;
LABEL_11:
			v13 = Room_Max;
			if ( v10 <= Room_Max )
			{
				if ( v10 <= nX1 )
				{
					v36 = nY2 - v39;
					goto LABEL_16;
				}
				v13 = nY2 - v39;
			}
			v14 = v13 - nX1;
			_LOBYTE(nX1) = 0;
			v36 = Room_Min + random(nX1, v14);
LABEL_16:
			if ( ForceHW == 1 )
			{
				v41 = nW;
				v36 = nH;
			}
			_LOBYTE(nX1) = 0;
			v15 = v37 + random(nX1, v9);
			_LOBYTE(v16) = 0;
			v17 = v39 + random(v16, v10);
			v18 = v15 + v41;
			v43 = v17 + v36;
			if ( v15 + v41 > nX2 )
			{
				v18 = nX2;
				v15 = nX2 - v41;
			}
			if ( v17 + v36 > nY2 )
			{
				v43 = nY2;
				v17 = nY2 - v36;
			}
			if ( v15 >= 38 )
				v15 = 38;
			if ( v17 >= 38 )
				v17 = 38;
			if ( v15 <= 1 )
				v15 = 1;
			if ( v17 <= 1 )
				v17 = 1;
			if ( v18 >= 38 )
				v18 = 38;
			if ( v43 >= 38 )
				v43 = 38;
			if ( v18 <= 1 )
				v18 = 1;
			if ( v43 <= 1 )
				v43 = 1;
			DefineRoom(v15, v17, v18, v43, ForceHW);
			if ( ForceHW == 1 )
			{
				nSx2 = v18;
				nSx1 = v15 + 2;
				nSy1 = v17 + 2;
				nSy2 = v43;
			}
			v19 = nRoomCnt;
			v20 = nRDest;
			v42 = nRoomCnt;
			RoomList[nRoomCnt].nRoomDest = nRDest;
			if ( nRDest )
			{
				if ( nHDir == 1 )
				{
					_LOBYTE(v20) = 0;
					v21 = random(v20, v18 - v15 - 2);
					_LOBYTE(v22) = 0;
					nX1a = v21 + v15 + 1;
					v33 = v17;
					v23 = random(v22, RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2);
					v20 = 20 * nRDest;
					v34 = v23 + RoomList[nRDest].nRoomx1 + 1;
					v35 = RoomList[nRDest].nRoomy2;
				}
				if ( nHDir == 3 )
				{
					_LOBYTE(v20) = 0;
					v24 = random(v20, v18 - v15 - 2);
					_LOBYTE(v25) = 0;
					nX1a = v24 + v15 + 1;
					v33 = v43;
					v26 = random(v25, RoomList[nRDest].nRoomx2 - RoomList[nRDest].nRoomx1 - 2);
					v20 = 20 * nRDest;
					v34 = v26 + RoomList[nRDest].nRoomx1 + 1;
					v35 = RoomList[nRDest].nRoomy1;
				}
				if ( nHDir == 2 )
				{
					_LOBYTE(v20) = 0;
					nX1a = v18;
					v33 = random(v20, v43 - v17 - 2) + v17 + 1;
					v34 = RoomList[nRDest].nRoomx1;
					v27 = &RoomList[nRDest].nRoomy1;
					ForceHWa = v27;
					v28 = RoomList[nRDest].nRoomy2 - *v27;
					_LOBYTE(v27) = 0;
					v29 = random((int)v27, v28 - 2);
					v20 = *ForceHWa;
					v35 = v29 + *ForceHWa + 1;
				}
				if ( nHDir == 4 )
				{
					_LOBYTE(v20) = 0;
					nX1a = v15;
					v33 = random(v20, v43 - v17 - 2) + v17 + 1;
					v34 = RoomList[nRDest].nRoomx2;
					v30 = &RoomList[nRDest].nRoomy1;
					ForceHWb = v30;
					v31 = RoomList[nRDest].nRoomy2 - *v30;
					_LOBYTE(v30) = 0;
					v35 = random((int)v30, v31 - 2) + *ForceHWb + 1;
				}
				AddHall(nX1a, v33, v34, v35, nHDir);
				v19 = v42;
			}
			if ( v36 <= v41 )
			{
				CreateRoom(v37 + 2, nY1a, v18 - 2, v17 - 2, v19, 3, 0, 0, 0);
				CreateRoom(v15 + 2, v43 + 2, v40, nY2 - 2, v42, 1, 0, 0, 0);
				CreateRoom(v37 + 2, v17 + 2, v15 - 2, nY2 - 2, v42, 2, 0, 0, 0);
				nHDir = 4;
				nW = 0;
				nH = 0;
				ForceHW = 0;
				nRDest = v42;
				nY2 = v43 - 2;
				nX2 -= 2;
				v40 -= 2;
				v39 += 2;
				nY1a += 2;
				v37 = v18 + 2;
			}
			else
			{
				CreateRoom(v37 + 2, nY1a, v15 - 2, v43 - 2, v19, 2, 0, 0, 0);
				CreateRoom(v18 + 2, v17 + 2, v40, nY2 - 2, v42, 4, 0, 0, 0);
				CreateRoom(v37 + 2, v43 + 2, v18 - 2, nY2 - 2, v42, 1, 0, 0, 0);
				nW = 0;
				nH = 0;
				ForceHW = 0;
				nRDest = v42;
				nHDir = 3;
				nX2 -= 2;
				v40 -= 2;
				v39 += 2;
				nY1a += 2;
				nY2 = v17 - 2;
				v37 = v15 + 2;
			}
			if ( nRoomCnt >= 80 )
				return;
		}
		v11 = Room_Max - Room_Min;
LABEL_7:
		_LOBYTE(nX1) = 0;
		v12 = random(nX1, v11);
		nX1 = Room_Min;
		v41 = Room_Min + v12;
		goto LABEL_11;
	}
}
// 484858: using guessed type int Area_Min;
// 48485C: using guessed type int Room_Max;
// 484860: using guessed type int Room_Min;
// 5276CC: using guessed type int nSx2;
// 5276D4: using guessed type int nSy2;

//----- (0040ECF9) --------------------------------------------------------
void __fastcall DefineRoom(int nX1, int nY1, int nX2, int nY2, int ForceHW)
{
	int v5; // esi
	int v6; // edi
	int v7; // eax
	int i; // eax
	bool v9; // zf
	int v10; // ecx
	char *v11; // eax
	char *v12; // ebx
	int v13; // eax
	int v14; // [esp+10h] [ebp-4h]
	int v15; // [esp+10h] [ebp-4h]
	int nY2a; // [esp+20h] [ebp+Ch]
	char *ForceHWa; // [esp+24h] [ebp+10h]

	v5 = nX1;
	v6 = nX2;
	predungeon[v5][nY1] = 67;
	predungeon[v5][nY2] = 69;
	predungeon[v6][nY1] = 66;
	predungeon[v6][nY2] = 65;
	v7 = nRoomCnt + 1;
	nRoomCnt = v7;
	v7 *= 20;
	*(int *)((char *)&RoomList[0].nRoomx1 + v7) = nX1;
	*(int *)((char *)&RoomList[0].nRoomx2 + v7) = nX2;
	*(int *)((char *)&RoomList[0].nRoomy1 + v7) = nY1;
	*(int *)((char *)&RoomList[0].nRoomy2 + v7) = nY2;
	if ( ForceHW == 1 )
	{
		for ( i = nX1; i < nX2; ++i )
		{
			if ( i < nY2 )
			{
				ForceHWa = &dflags[i][nY1];
				v14 = nY2 - i;
				i = nY2;
				do
				{
					*ForceHWa |= 0x80u;
					v9 = v14-- == 1;
					ForceHWa += 40;
				}
				while ( !v9 );
			}
		}
	}
	v10 = nX1 + 1;
	if ( v10 <= nX2 - 1 )
	{
		v15 = nX2 - v10;
		v11 = &predungeon[v10][nY2];
		do
		{
			v11[nY1 - nY2] = 35;
			*v11 = 35;
			v11 += 40;
			--v15;
		}
		while ( v15 );
	}
	nY2a = nY2 - 1;
	while ( ++nY1 <= nY2a )
	{
		predungeon[v5][nY1] = 35;
		predungeon[v6][nY1] = 35;
		if ( v10 < nX2 )
		{
			v12 = &predungeon[v10][nY1];
			v13 = nX2 - v10;
			do
			{
				*v12 = 46;
				v12 += 40;
				--v13;
			}
			while ( v13 );
		}
	}
}

//----- (0040EE1D) --------------------------------------------------------
void __fastcall AddHall(int nX1, int nY1, int nX2, int nY2, int nHd)
{
	int v5; // edi
	int v6; // esi
	HALLNODE *v7; // eax
	HALLNODE *i; // ecx

	v5 = nX1;
	v6 = nY1;
	if ( pHallList )
	{
		v7 = (HALLNODE *)DiabloAllocPtr(24);
		v7->pNext = 0;
		v7->nHallx2 = nX2;
		v7->nHally2 = nY2;
		v7->nHallx1 = v5;
		v7->nHally1 = v6;
		v7->nHalldir = nHd;
		for ( i = pHallList; i->pNext; i = i->pNext )
			;
		i->pNext = v7;
	}
	else
	{
		pHallList = (HALLNODE *)DiabloAllocPtr(24);
		pHallList->nHallx1 = v5;
		pHallList->nHally1 = v6;
		pHallList->nHallx2 = nX2;
		pHallList->nHally2 = nY2;
		pHallList->nHalldir = nHd;
		pHallList->pNext = 0;
	}
}

//----- (0040EEAC) --------------------------------------------------------
void __fastcall GetHall(int *nX1, int *nY1, int *nX2, int *nY2, int *nHd)
{
	HALLNODE *v5; // esi
	HALLNODE *v6; // ecx

	v5 = pHallList->pNext;
	*nX1 = pHallList->nHallx1;
	*nY1 = pHallList->nHally1;
	*nX2 = pHallList->nHallx2;
	*nY2 = pHallList->nHally2;
	*nHd = pHallList->nHalldir;
	v6 = pHallList;
	pHallList = 0;
	mem_free_dbg(v6);
	pHallList = v5;
}

//----- (0040EF09) --------------------------------------------------------
void __fastcall ConnectHall(int nX1, int nY1, int nX2, int nY2, int nHd)
{
	int v5; // edi
	signed int v6; // esi
	int v7; // eax
	int v8; // ecx
	int v9; // edi
	int v10; // ebx
	int v11; // ecx
	char v12; // al
	int v13; // eax
	int v14; // ecx
	char *v15; // ebx
	int v16; // ecx
	int v17; // edx
	int v18; // ecx
	int v19; // edx
	int v20; // eax
	int v21; // ST04_4
	int v22; // ecx
	int v23; // ebx
	int v24; // ebx
	bool v25; // zf
	signed int v26; // [esp-4h] [ebp-34h]
	signed int v27; // [esp-4h] [ebp-34h]
	signed int v28; // [esp-4h] [ebp-34h]
	signed int v29; // [esp-4h] [ebp-34h]
	int v30; // [esp+Ch] [ebp-24h]
	int v31; // [esp+10h] [ebp-20h]
	int v32; // [esp+14h] [ebp-1Ch]
	signed int v33; // [esp+18h] [ebp-18h]
	signed int v34; // [esp+1Ch] [ebp-14h]
	signed int v35; // [esp+20h] [ebp-10h]
	int v36; // [esp+24h] [ebp-Ch]
	char *v37; // [esp+28h] [ebp-8h]
	signed int nY; // [esp+2Ch] [ebp-4h]
	int nX2a; // [esp+38h] [ebp+8h]
	int nY2a; // [esp+3Ch] [ebp+Ch]
	int nHda; // [esp+40h] [ebp+10h]

	v34 = 0;
	v5 = nY1;
	v6 = nX1;
	_LOBYTE(nX1) = 0;
	nY = nY1;
	v7 = random(nX1, 100);
	_LOBYTE(v8) = 0;
	v33 = v7;
	v32 = random(v8, 100);
	v31 = v6;
	v30 = v5;
	CreateDoorType(v6, v5);
	CreateDoorType(nX2, nY2);
	abs(nX2 - v6);
	abs(nY2 - v5);
	v9 = nHd;
	v10 = nX2 - Dir_Xadd[nHd];
	v11 = nY2 - Dir_Yadd[nHd];
	nHda = 0;
	nY2a = v11;
	nX2a = v10;
	predungeon[v10][v11] = 44;
	v37 = &predungeon[v6][nY];
	do
	{
		if ( v6 >= 38 && v9 == 2 )
			v9 = 4;
		if ( nY >= 38 && v9 == 3 )
			v9 = 1;
		if ( v6 <= 1 && v9 == 4 )
			v9 = 2;
		if ( nY <= 1 && v9 == 1 )
			v9 = 3;
		v12 = *v37;
		if ( *v37 == 67 && (v9 == 1 || v9 == 4) )
			v9 = 2;
		if ( v12 == 66 && (v9 == 1 || v9 == 2) )
			v9 = 3;
		if ( v12 == 69 && (v9 == 4 || v9 == 3) )
			v9 = 1;
		if ( v12 == 65 && (v9 == 2 || v9 == 3) )
			v9 = 4;
		v13 = Dir_Xadd[v9];
		v14 = Dir_Yadd[v9];
		nY += v14;
		v6 += v13;
		v15 = &predungeon[v6][nY];
		v37 = v15;
		if ( *v15 == 32 )
		{
			if ( nHda )
			{
				CreateDoorType(v6 - v13, nY - v14);
			}
			else
			{
				if ( v33 < 50 )
				{
					if ( v9 == 1 || v9 == 3 )
					{
						v17 = nY;
						v16 = v6 - 1;
					}
					else
					{
						v16 = v6;
						v17 = nY - 1;
					}
					PlaceHallExt(v16, v17);
				}
				if ( v32 < 50 )
				{
					if ( v9 == 1 || v9 == 3 )
					{
						v19 = nY;
						v18 = v6 + 1;
					}
					else
					{
						v18 = v6;
						v19 = nY + 1;
					}
					PlaceHallExt(v18, v19);
				}
			}
			nHda = 0;
			*v15 = 44;
		}
		else
		{
			if ( !nHda && *v15 == 35 )
				CreateDoorType(v6, nY);
			if ( *v15 != 44 )
				nHda = 1;
		}
		v36 = abs(nX2a - v6);
		v20 = abs(nY2a - nY);
		v22 = v21;
		v35 = v20;
		if ( v36 <= v20 )
		{
			v24 = 5 * v20;
			if ( 5 * v20 > 80 )
				v24 = 80;
			_LOBYTE(v22) = 0;
			if ( random(v22, 100) < v24 )
			{
				if ( nY2a <= nY || nY >= 40 )
				{
					v9 = 1;
					goto LABEL_67;
				}
				v26 = 3;
				goto LABEL_58;
			}
		}
		else
		{
			v23 = 2 * v36;
			if ( 2 * v36 > 30 )
				v23 = 30;
			_LOBYTE(v22) = 0;
			if ( random(v22, 100) < v23 )
			{
				if ( nX2a <= v6 || v6 >= 40 )
					v26 = 4;
				else
					v26 = 2;
LABEL_58:
				v9 = v26;
				goto LABEL_67;
			}
		}
LABEL_67:
		if ( v35 < 10 && v6 == nX2a && (v9 == 2 || v9 == 4) )
		{
			if ( nY2a <= nY || nY >= 40 )
				v9 = 1;
			else
				v9 = 3;
		}
		if ( v36 < 10 && nY == nY2a && (v9 == 1 || v9 == 3) )
		{
			if ( nX2a <= v6 || v6 >= 40 )
				v27 = 4;
			else
				v27 = 2;
			v9 = v27;
		}
		if ( v35 == 1 )
		{
			v25 = v36 == 1;
			if ( v36 <= 1 )
				goto LABEL_94;
			if ( v9 == 1 || v9 == 3 )
			{
				if ( nX2a <= v6 || v6 >= 40 )
					v28 = 4;
				else
					v28 = 2;
				v9 = v28;
			}
		}
		v25 = v36 == 1;
LABEL_94:
		if ( v25 )
		{
			if ( v35 <= 1 || v9 != 2 && v9 != 4 )
				goto LABEL_109;
			if ( nY2a > nY && v6 < 40 )
				goto LABEL_100;
			v9 = 1;
		}
		if ( !v36 && *v37 != 32 && (v9 == 2 || v9 == 4) )
		{
			if ( nX2a <= v31 || v6 >= 40 )
			{
				v9 = 1;
				goto LABEL_109;
			}
LABEL_100:
			v9 = 3;
		}
LABEL_109:
		if ( !v35 && *v37 != 32 && (v9 == 1 || v9 == 3) )
		{
			if ( nY2a <= v30 || nY >= 40 )
				v29 = 4;
			else
				v29 = 2;
			v9 = v29;
		}
		if ( v6 == nX2a && nY == nY2a )
			v34 = 1;
	}
	while ( !v34 );
}

//----- (0040F265) --------------------------------------------------------
void __fastcall CreateDoorType(int nX, int nY)
{
	int v2; // eax
	signed int v3; // esi
	char *v4; // ecx
	char v5; // al

	v2 = nX;
	v3 = 0;
	v4 = &predungeon[nX][nY];
	if ( *(v4 - 40) == 68 )
		v3 = 1;
	if ( predungeon[v2 + 1][nY] == 68 )
		v3 = 1;
	if ( *(v4 - 1) == 68 )
		v3 = 1;
	if ( predungeon[v2][nY + 1] == 68 )
		v3 = 1;
	v5 = *v4;
	if ( *v4 == 66 || v5 == 67 || v5 == 65 || v5 == 69 )
		v3 = 1;
	if ( !v3 )
		*v4 = 68;
}

//----- (0040F2BD) --------------------------------------------------------
void __fastcall PlaceHallExt(int nX, int nY)
{
	char *v2; // eax

	v2 = &predungeon[nX][nY];
	if ( *v2 == 32 )
		*v2 = 44;
}

//----- (0040F2D0) --------------------------------------------------------
void __fastcall DoPatternCheck(int i, int j)
{
	int v2; // edx
	signed int v3; // eax
	signed int v4; // ebp
	int v5; // esi
	int v6; // ecx
	bool v7; // zf
	char v8; // bl
	bool v9; // zf
	char v10; // bl
	int *v11; // [esp+0h] [ebp-10h]
	int v12; // [esp+4h] [ebp-Ch]
	int v13; // [esp+8h] [ebp-8h]
	int v14; // [esp+Ch] [ebp-4h]

	v13 = j;
	v14 = i;
	if ( Patterns[0][4] != 255 )
	{
		v12 = 0;
		v2 = i - 1;
		v11 = &Patterns[0][4];
		do
		{
			v3 = v2;
			v4 = 254;
			v5 = v13 - 1;
			v6 = 0;
			while ( v4 == 254 )
			{
				v4 = 255;
				if ( v6 == 3 || v6 == 6 )
				{
					++v5;
					v3 = v2;
				}
				if ( v3 < 0 || v3 >= 40 || v5 < 0 || v5 >= 40 )
				{
LABEL_26:
					v4 = 254;
				}
				else
				{
					switch ( Patterns[0][v6 + v12] )
					{
						case 0:
							goto LABEL_26;
						case 1:
							v7 = predungeon[v3][v5] == 35;
							goto LABEL_25;
						case 2:
							v7 = predungeon[v3][v5] == 46;
							goto LABEL_25;
						case 3:
							v7 = predungeon[v3][v5] == 68;
							goto LABEL_25;
						case 4:
							v7 = predungeon[v3][v5] == 32;
							goto LABEL_25;
						case 5:
							v8 = predungeon[v3][v5];
							v9 = v8 == 68;
							goto LABEL_23;
						case 6:
							v10 = predungeon[v3][v5];
							if ( v10 == 68 )
								goto LABEL_26;
							v7 = v10 == 35;
							goto LABEL_25;
						case 7:
							v8 = predungeon[v3][v5];
							v9 = v8 == 32;
							goto LABEL_23;
						case 8:
							v8 = predungeon[v3][v5];
							if ( v8 == 68 )
								goto LABEL_26;
							v9 = v8 == 35;
LABEL_23:
							if ( v9 )
								goto LABEL_26;
							v7 = v8 == 46;
LABEL_25:
							if ( v7 )
								goto LABEL_26;
							break;
						default:
							break;
					}
				}
				++v3;
				if ( ++v6 >= 9 )
				{
					if ( v4 == 254 )
						dungeon[v14][v13] = *((_BYTE *)v11 + 20);
					break;
				}
			}
			v11 += 10;
			v12 += 10;
		}
		while ( *v11 != 255 );
	}
}

//----- (0040F459) --------------------------------------------------------
void __cdecl DL2_FillVoids()
{
	int i; // eax
	int v1; // ecx
	int v2; // eax
	int v3; // ecx
	int v4; // edi
	int v5; // eax
	int v6; // ebx
	int v7; // eax
	int v8; // ecx
	char v9; // dl
	int v10; // eax
	int v11; // esi
	signed int v12; // ecx
	signed int v13; // edi
	signed int v14; // edx
	signed int v15; // eax
	int v16; // ebx
	int v17; // eax
	signed int v18; // edx
	int k; // eax
	int v20; // ebx
	int v21; // ebx
	int v22; // eax
	int v23; // ebx
	signed int v24; // edx
	int v25; // eax
	int v26; // esi
	int v27; // edx
	int v28; // esi
	int v29; // edx
	int v30; // edx
	signed int v31; // ebx
	int v32; // edi
	int v33; // ecx
	char *v34; // eax
	int v35; // edi
	int v36; // edx
	signed int v37; // ecx
	signed int v38; // eax
	int v39; // edx
	int v40; // edx
	int v41; // edx
	signed int v42; // ebx
	int j; // edi
	int v44; // ecx
	char *v45; // eax
	int v46; // edi
	int v47; // [esp-4h] [ebp-30h]
	signed int v48; // [esp+Ch] [ebp-20h]
	signed int y1f; // [esp+10h] [ebp-1Ch]
	signed int y2f; // [esp+14h] [ebp-18h]
	signed int x2f; // [esp+18h] [ebp-14h]
	signed int x1f; // [esp+1Ch] [ebp-10h]
	int x2; // [esp+20h] [ebp-Ch]
	int x2a; // [esp+20h] [ebp-Ch]
	int y1; // [esp+24h] [ebp-8h]
	int y1a; // [esp+24h] [ebp-8h]
	int y1b; // [esp+24h] [ebp-8h]
	int y2; // [esp+28h] [ebp-4h]
	int y2a; // [esp+28h] [ebp-4h]
	int y2b; // [esp+28h] [ebp-4h]

	v48 = 0;
	for ( i = DL2_NumNoChar(); i > 700 && v48 < 100; i = DL2_NumNoChar() )
	{
		_LOBYTE(v1) = 0;
		v2 = random(v1, 38);
		_LOBYTE(v3) = 0;
		v4 = v2 + 1;
		v5 = random(v3, 38);
		v6 = v5 + 1;
		v7 = v5 + 1 + 40 * v4;
		if ( predungeon[0][v7] != 35 )
			continue;
		y2f = 0;
		y1f = 0;
		x2f = 0;
		x1f = 0;
		v8 = *((unsigned char *)&VR1 + v7);
		if ( (_BYTE)v8 == 32 && predungeon[1][v7] == 46 )
		{
			if ( predungeon[0][v7 + 39] != 46
			  || predungeon[1][v7 + 1] != 46
			  || *((_BYTE *)&HR3 + v7 + 3) != 32
			  || *((_BYTE *)&VR1 + v7 + 1) != 32 )
			{
				goto LABEL_34;
			}
			y1f = 1;
LABEL_32:
			x1f = 1;
LABEL_33:
			y2f = 1;
			goto LABEL_34;
		}
		if ( predungeon[1][v7] == 32 && (_BYTE)v8 == 46 )
		{
			if ( *((_BYTE *)&HR3 + v7 + 3) != 46
			  || *((_BYTE *)&VR1 + v7 + 1) != 46
			  || predungeon[0][v7 + 39] != 32
			  || predungeon[1][v7 + 1] != 32 )
			{
				goto LABEL_34;
			}
			y1f = 1;
			x2f = 1;
			goto LABEL_33;
		}
		v9 = *(_BYTE *)(v7 + 5404379);
		if ( v9 != 32 || predungeon[0][v7 + 1] != 46 )
		{
			if ( predungeon[0][v7 + 1] != 32
			  || v9 != 46
			  || *((_BYTE *)&HR3 + v7 + 3) != 46
			  || predungeon[0][v7 + 39] != 46
			  || predungeon[-1][v7 + 1] != 32
			  || predungeon[1][v7 + 1] != 32 )
			{
				goto LABEL_34;
			}
			x2f = 1;
			goto LABEL_32;
		}
		if ( predungeon[-1][v7 + 1] == 46
		  && predungeon[1][v7 + 1] == 46
		  && *((_BYTE *)&HR3 + v7 + 3) == 32
		  && predungeon[0][v7 + 39] == 32 )
		{
			x2f = 1;
			x1f = 1;
			y1f = 1;
			v10 = DL2_Cont(1u, 1u, 1u, 0);
			goto LABEL_35;
		}
LABEL_34:
		v10 = DL2_Cont(x1f, y1f, x2f, y2f);
LABEL_35:
		if ( v10 )
		{
			v11 = v4 - 1;
			if ( !x1f )
				v11 = v4;
			v12 = x2f;
			if ( x2f )
				++v4;
			x2 = v4;
			v13 = y1f;
			if ( y1f )
				y1 = v6 - 1;
			else
				y1 = v6;
			v14 = y2f;
			if ( y2f )
				++v6;
			v15 = x1f;
			y2 = v6;
			if ( x1f )
			{
				if ( x2f )
				{
					if ( y1f )
					{
						if ( y2f )
							goto LABEL_177;
						v37 = x1f;
						v38 = x2f;
						v39 = x2;
						while ( v37 || v38 )
						{
							if ( !v11 )
								v37 = 0;
							if ( v39 == 39 )
								v38 = 0;
							if ( v39 - v11 >= 14 )
							{
								v37 = 0;
								v38 = 0;
							}
							if ( v37 )
								--v11;
							if ( v38 )
								++v39;
							if ( predungeon[v11][y1] != 32 )
								v37 = 0;
							if ( predungeon[v39][y1] != 32 )
								v38 = 0;
						}
						v28 = v11 + 2;
						v40 = v39 - 2;
						x2a = v40;
						v41 = v40 - v28;
						if ( v41 <= 5 )
							goto LABEL_177;
						v42 = y1f;
						for ( j = y1; ; --j )
						{
							if ( !j )
								v42 = 0;
							if ( y2 - j >= 12 )
								v42 = 0;
							if ( v28 <= x2a )
							{
								v44 = v41 + 1;
								v45 = &predungeon[v28][j];
								do
								{
									if ( *v45 != 32 )
										v42 = 0;
									v45 += 40;
									--v44;
								}
								while ( v44 );
							}
							if ( !v42 )
								break;
						}
						v46 = j + 2;
						if ( y2 - v46 <= 5 )
							goto LABEL_177;
						DL2_DrawRoom(v28, v46, x2a, y2);
						v36 = v46;
						v47 = y2;
					}
					else
					{
						v27 = x2;
						while ( v15 || v12 )
						{
							if ( !v11 )
								v15 = 0;
							if ( v27 == 39 )
								v12 = 0;
							if ( v27 - v11 >= 14 )
							{
								v15 = 0;
								v12 = 0;
							}
							if ( v15 )
								--v11;
							if ( v12 )
								++v27;
							if ( predungeon[v11][v6] != 32 )
								v15 = 0;
							if ( predungeon[v27][v6] != 32 )
								v12 = 0;
						}
						v28 = v11 + 2;
						v29 = v27 - 2;
						x2a = v29;
						v30 = v29 - v28;
						if ( v30 <= 5 )
							goto LABEL_177;
						v31 = y2f;
						v32 = y2;
						if ( y2f )
						{
							while ( 1 )
							{
								if ( v32 == 39 )
									v31 = 0;
								if ( v32 - y1 >= 12 )
									v31 = 0;
								if ( v28 <= x2a )
								{
									v33 = v30 + 1;
									v34 = &predungeon[v28][v32];
									do
									{
										if ( *v34 != 32 )
											v31 = 0;
										v34 += 40;
										--v33;
									}
									while ( v33 );
								}
								if ( !v31 )
									break;
								++v32;
							}
						}
						v35 = v32 - 2;
						if ( v35 - y1 <= 5 )
							goto LABEL_177;
						DL2_DrawRoom(v28, y1, x2a, v35);
						v36 = y1;
						v47 = v35;
					}
					DL2_KnockWalls(v28, v36, x2a, v47);
				}
				else
				{
					v21 = y1;
					while ( v13 || v14 )
					{
						if ( !v21 )
							v13 = 0;
						if ( y2 == 39 )
							v14 = 0;
						if ( y2 - v21 >= 14 )
						{
							v13 = 0;
							v14 = 0;
						}
						if ( v13 )
							--v21;
						if ( v14 )
							++y2;
						v22 = 40 * v11 + 5404380;
						if ( *(_BYTE *)(v22 + v21) != 32 )
							v13 = 0;
						if ( *(_BYTE *)(v22 + y2) != 32 )
							v14 = 0;
					}
					y2b = y2 - 2;
					v23 = v21 + 2;
					y1b = v23;
					if ( y2b - v23 > 5 )
					{
						v24 = x1f;
						while ( 1 )
						{
							if ( !v11 )
								v24 = 0;
							if ( x2 - v11 >= 12 )
								v24 = 0;
							v25 = v23;
							if ( v23 <= y2b )
							{
								do
								{
									if ( *(_BYTE *)(40 * v11 + 5404380 + v25) != 32 )
										v24 = 0;
									++v25;
								}
								while ( v25 <= y2b );
								v23 = y1b;
							}
							if ( !v24 )
								break;
							--v11;
						}
						v26 = v11 + 2;
						if ( x2 - v26 > 5 )
						{
							DL2_DrawRoom(v26, v23, x2, y2b);
							DL2_KnockWalls(v26, v23, x2, y2b);
						}
					}
				}
			}
			else
			{
				v16 = x2;
				while ( v13 || v14 )
				{
					if ( !y1 )
						v13 = 0;
					if ( y2 == 39 )
						v14 = 0;
					if ( y2 - y1 >= 14 )
					{
						v13 = 0;
						v14 = 0;
					}
					if ( v13 )
						--y1;
					if ( v14 )
						++y2;
					v17 = 40 * x2 + 5404380;
					if ( *(_BYTE *)(v17 + y1) != 32 )
						v13 = 0;
					if ( *(_BYTE *)(v17 + y2) != 32 )
						v14 = 0;
				}
				y2a = y2 - 2;
				y1a = y1 + 2;
				if ( y2a - y1a > 5 )
				{
					v18 = x2f;
					if ( x2f )
					{
						while ( 1 )
						{
							if ( v16 == 39 )
								v18 = 0;
							if ( v16 - v11 >= 12 )
								v18 = 0;
							for ( k = y1a; k <= y2a; ++k )
							{
								if ( *(_BYTE *)(40 * v16 + 5404380 + k) != 32 )
									v18 = 0;
							}
							if ( !v18 )
								break;
							++v16;
						}
					}
					v20 = v16 - 2;
					if ( v20 - v11 > 5 )
					{
						DL2_DrawRoom(v11, y1a, v20, y2a);
						DL2_KnockWalls(v11, y1a, v20, y2a);
					}
				}
			}
		}
LABEL_177:
		++v48;
	}
	DL2_NumNoChar();
}

//----- (0040F9B1) --------------------------------------------------------
int __fastcall DL2_Cont(unsigned char x1f, unsigned char y1f, unsigned char x2f, unsigned char y2f)
{
	bool v4; // zf

	if ( x1f && x2f )
	{
		if ( !y1f )
			goto LABEL_16;
		if ( y2f )
			return 0;
		if ( !y1f )
		{
LABEL_16:
			v4 = y2f == 0;
			goto LABEL_11;
		}
		return 1;
	}
	if ( !y1f || !y2f )
		return 0;
	if ( x1f )
		return 1;
	v4 = x2f == 0;
LABEL_11:
	if ( !v4 )
		return 1;
	return 0;
}

//----- (0040F9EE) --------------------------------------------------------
int __cdecl DL2_NumNoChar()
{
	int result; // eax
	signed int v1; // edx
	_BYTE *v2; // ecx
	signed int v3; // esi

	result = 0;
	v1 = 0;
	do
	{
		v2 = (unsigned char *)predungeon + v1;
		v3 = 40;
		do
		{
			if ( *v2 == 32 )
				++result;
			v2 += 40;
			--v3;
		}
		while ( v3 );
		++v1;
	}
	while ( v1 < 40 );
	return result;
}

//----- (0040FA10) --------------------------------------------------------
void __fastcall DL2_DrawRoom(int x1, int y1, int x2, int y2)
{
	int v4; // ebx
	char *v5; // edx
	int v6; // esi
	int i; // esi
	char *v8; // esi
	int v9; // eax
	int v10; // [esp+Ch] [ebp-4h]

	v4 = y1;
	v10 = y1;
	while ( v4 <= y2 )
	{
		if ( x1 <= x2 )
		{
			v5 = &predungeon[x1][v4];
			v6 = x2 - x1 + 1;
			do
			{
				*v5 = 46;
				v5 += 40;
				--v6;
			}
			while ( v6 );
		}
		++v4;
	}
	for ( i = v10; i <= y2; ++i )
	{
		*(_BYTE *)(40 * x1 + 5404380 + i) = 35;
		*(_BYTE *)(40 * x2 + 5404380 + i) = 35;
	}
	if ( x1 <= x2 )
	{
		v8 = &predungeon[x1][y2];
		v9 = x2 - x1 + 1;
		do
		{
			v8[v10 - y2] = 35;
			*v8 = 35;
			v8 += 40;
			--v9;
		}
		while ( v9 );
	}
}

//----- (0040FA97) --------------------------------------------------------
void __fastcall DL2_KnockWalls(int x1, int y1, int x2, int y2)
{
	int v4; // esi
	char *v5; // ebx
	_BYTE *v6; // eax
	int v7; // edi
	int v8; // eax
	int v9; // ecx
	int v10; // edx
	_BYTE *v11; // esi

	v4 = x1 + 1;
	if ( x1 + 1 < x2 )
	{
		v5 = &predungeon[v4][y2 + 1];
		v6 = (_BYTE *)(40 * v4 + y1 + 5404379);
		v7 = x2 - v4;
		do
		{
			if ( *v6 == 46 && v6[2] == 46 )
				v6[1] = 46;
			if ( v6[y2 - y1] == 46 && *v5 == 46 )
				*(v5 - 1) = 46;
			if ( *v6 == 68 )
				*v6 = 46;
			if ( *v5 == 68 )
				*v5 = 46;
			v6 += 40;
			v5 += 40;
			--v7;
		}
		while ( v7 );
	}
	v8 = y1 + 1;
	if ( y1 + 1 < y2 )
	{
		v9 = x1;
		v10 = 40 * x2 + 5404420;
		do
		{
			v11 = (unsigned char *)&VR1 + v9 * 40 + v8;
			if ( *v11 == 46 && predungeon[v9 + 1][v8] == 46 )
				predungeon[v9][v8] = 46;
			if ( *(_BYTE *)(v10 + v8 - 80) == 46 && *(_BYTE *)(v10 + v8) == 46 )
				*(_BYTE *)(v10 + v8 - 40) = 46;
			if ( *v11 == 68 )
				*v11 = 46;
			if ( *(_BYTE *)(v10 + v8) == 68 )
				*(_BYTE *)(v10 + v8) = 46;
			++v8;
		}
		while ( v8 < y2 );
	}
}

//----- (0040FB6C) --------------------------------------------------------
void __cdecl DRLG_L2FloodTVal()
{
	int v0; // ebx
	int v1; // esi
	char *v2; // edi
	_BYTE *v3; // [esp+Ch] [ebp-Ch]
	signed int x; // [esp+10h] [ebp-8h]
	signed int i; // [esp+14h] [ebp-4h]

	v0 = 16;
	v1 = 0;
	do
	{
		i = 0;
		x = 16;
		v2 = &dung_map[16][v0];
		v3 = (unsigned char *)dungeon + v1;
		do
		{
			if ( *v3 == 3 && !*v2 )
			{
				DRLG_L2FTVR(i, v1, x, v0, 0);
				++TransVal;
			}
			x += 2;
			v3 += 40;
			v2 += 224;
			++i;
		}
		while ( i < 40 );
		v0 += 2;
		++v1;
	}
	while ( v1 < 40 );
}
// 5A5590: using guessed type char TransVal;

//----- (0040FBDB) --------------------------------------------------------
void __fastcall DRLG_L2FTVR(int i, int j, int x, int y, int d)
{
	int v5; // ebx
	int v6; // esi
	int v7; // edi
	int v8; // edx
	int v9; // ecx
	int v10; // ebx
	int v11; // eax
	int v12; // edi
	char v13; // al
	char v14; // al
	int v15; // ecx
	int v16; // ecx
	int v17; // ecx
	int v18; // ecx
	int v19; // [esp+Ch] [ebp-14h]
	int k; // [esp+10h] [ebp-10h]
	int v21; // [esp+14h] [ebp-Ch]
	int ja; // [esp+18h] [ebp-8h]
	int ia; // [esp+1Ch] [ebp-4h]
	int ya; // [esp+2Ch] [ebp+Ch]

	v5 = x;
	v6 = y;
	v7 = j;
	v8 = i;
	v9 = 112 * x + y;
	ja = v7;
	v21 = v8;
	if ( !dung_map[0][v9] )
	{
		v19 = x;
		ia = v8 - 1;
		v10 = x - 2;
		v11 = 40 * v8;
		ya = v7 - 1;
		v12 = v6 - 2;
		for ( k = 40 * v8; dungeon[0][v11 + ja] == 3; v11 = k )
		{
			v13 = TransVal;
			dung_map[0][v9] = TransVal;
			dung_map[1][v9] = v13;
			dung_map[0][v9 + 1] = v13;
			dung_map[1][v9 + 1] = v13;
			DRLG_L2FTVR(ia + 2, ja, v10 + 4, v6, 1);
			DRLG_L2FTVR(ia, ja, v10, v6, 2);
			DRLG_L2FTVR(v21, ya + 2, x, v12 + 4, 3);
			DRLG_L2FTVR(v21, ya, x, v12, 4);
			DRLG_L2FTVR(ia, ya, v10, v12, 5);
			DRLG_L2FTVR(ia + 2, ya, v10 + 4, v12, 6);
			DRLG_L2FTVR(ia, ya + 2, v10, v12 + 4, 7);
			v19 += 2;
			k += 40;
			d = 8;
			x += 2;
			v6 += 2;
			v12 += 2;
			v10 += 2;
			++ja;
			++ya;
			++v21;
			++ia;
			v9 = v19 * 112 + v6;
			if ( dung_map[v19][v6] )
				break;
		}
		v5 = x;
	}
	v14 = TransVal;
	if ( d == 1 )
	{
		v15 = v6 + 112 * v5;
		dung_map[0][v15] = TransVal;
		dung_map[0][v15 + 1] = v14;
	}
	if ( d == 2 )
	{
		v16 = v6 + 112 * v5;
		dung_map[1][v16] = v14;
		dung_map[1][v16 + 1] = v14;
	}
	if ( d == 3 )
	{
		v17 = v6 + 112 * v5;
		dung_map[0][v17] = v14;
		dung_map[1][v17] = v14;
	}
	if ( d == 4 )
	{
		v18 = v6 + 112 * v5;
		dung_map[0][v18 + 1] = v14;
		dung_map[1][v18 + 1] = v14;
	}
	if ( d == 5 )
		dung_map[v5 + 1][v6 + 1] = v14;
	if ( d == 6 )
		dung_map[v5][v6 + 1] = v14;
	if ( d == 7 )
		dung_map[v5 + 1][v6] = v14;
	if ( d == 8 )
		dung_map[v5][v6] = v14;
}
// 5A5590: using guessed type char TransVal;

//----- (0040FDCB) --------------------------------------------------------
void __cdecl DRLG_L2TransFix()
{
	signed int v0; // esi
	char *v1; // eax
	char *v2; // ecx
	signed int v3; // edi
	char v4; // bl
	char v5; // dl
	char v6; // dl
	char v7; // dl
	char v8; // dl
	char v9; // dl
	char *v10; // [esp+Ch] [ebp-4h]

	v0 = 0;
	v10 = &dung_map[16][16];
	do
	{
		v1 = v10;
		v2 = (char *)dungeon + v0;
		v3 = 40;
		do
		{
			v4 = *v2;
			if ( *v2 == 14 && *(v2 - 1) == 10 )
			{
				v5 = *v1;
				v1[112] = *v1;
				v1[113] = v5;
			}
			if ( v4 == 15 && v2[40] == 11 )
			{
				v6 = *v1;
				v1[1] = *v1;
				v1[113] = v6;
			}
			if ( v4 == 10 )
			{
				v7 = *v1;
				v1[112] = *v1;
				v1[113] = v7;
			}
			if ( v4 == 11 )
			{
				v8 = *v1;
				v1[1] = *v1;
				v1[113] = v8;
			}
			if ( v4 == 16 )
			{
				v9 = *v1;
				v1[112] = *v1;
				v1[1] = v9;
				v1[113] = v9;
			}
			v1 += 224;
			v2 += 40;
			--v3;
		}
		while ( v3 );
		v10 += 2;
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040FE53) --------------------------------------------------------
void __cdecl L2DirtFix()
{
	signed int v0; // ecx
	char *v1; // eax
	signed int v2; // edx

	v0 = 0;
	do
	{
		v1 = (char *)dungeon + v0;
		v2 = 40;
		do
		{
			if ( *v1 == 13 && v1[40] != 11 )
				*v1 = -110;
			if ( *v1 == 11 && v1[40] != 11 )
				*v1 = -112;
			if ( *v1 == 15 && v1[40] != 11 )
				*v1 = -108;
			if ( *v1 == 10 && v1[1] != 10 )
				*v1 = -113;
			if ( *v1 == 13 && v1[1] != 10 )
				*v1 = -110;
			if ( *v1 == 14 && v1[1] != 15 )
				*v1 = -109;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040FEBF) --------------------------------------------------------
void __cdecl DRLG_InitL2Vals()
{
	int v0; // edi
	int (*v1)[112]; // ebx
	char *v2; // ecx
	int (*v3)[112]; // edx
	signed int v4; // esi
	int v5; // eax
	int v6; // ecx
	int (*v7)[112]; // esi
	char *v8; // eax
	int (*v9)[112]; // edx
	signed int v10; // ebx
	int v11; // edi
	char v12; // [esp-4h] [ebp-14h]

	v0 = 0;
	v1 = dPiece;
	do
	{
		v2 = (char *)dArch + v0;
		v3 = v1;
		v4 = 112;
		do
		{
			v5 = (*v3)[0];
			if ( (*v3)[0] != 541 && v5 != 178 && v5 != 551 )
			{
				if ( v5 == 542 || v5 == 553 )
					goto LABEL_11;
				if ( v5 != 13 )
				{
					if ( v5 != 17 )
						goto LABEL_13;
LABEL_11:
					v12 = 6;
					goto LABEL_12;
				}
			}
			v12 = 5;
LABEL_12:
			*v2 = v12;
LABEL_13:
			++v3;
			v2 += 112;
			--v4;
		}
		while ( v4 );
		v1 = (int (*)[112])((char *)v1 + 4);
		++v0;
	}
	while ( (signed int)v1 < (signed int)dPiece[1] );
	v6 = 0;
	v7 = dPiece;
	do
	{
		v8 = &dArch[0][v6 + 2];
		v9 = v7;
		v10 = 112;
		do
		{
			v11 = (*v9)[0];
			if ( (*v9)[0] == 132 )
			{
				*(v8 - 1) = 2;
				*v8 = 1;
			}
			else if ( v11 == 135 || v11 == 139 )
			{
				v8[110] = 3;
				v8[222] = 4;
			}
			++v9;
			v8 += 112;
			--v10;
		}
		while ( v10 );
		v7 = (int (*)[112])((char *)v7 + 4);
		++v6;
	}
	while ( (signed int)v7 < (signed int)dPiece[1] );
}

//----- (0040FF81) --------------------------------------------------------
void __cdecl AddFenceDoors()
{
	signed int v0; // esi
	char *v1; // eax
	signed int v2; // ebx
	unsigned char v3; // cl
	char v4; // cl
	char v5; // cl

	v0 = 0;
	do
	{
		v1 = &dungeon[-1][v0 + 39];
		v2 = 40;
		do
		{
			if ( v1[1] == 7 )
			{
				v3 = *(v1 - 39);
				if ( v3 > 0x98u
				  || v3 < 0x82u
				  || (v4 = v1[41], (unsigned char)v4 > 0x98u)
				  || (unsigned char)v4 < 0x82u )
				{
					if ( (unsigned char)*v1 <= 0x98u && (unsigned char)*v1 >= 0x82u )
					{
						v5 = v1[2];
						if ( (unsigned char)v5 <= 0x98u && (unsigned char)v5 >= 0x82u )
							v1[1] = -109;
					}
				}
				else
				{
					v1[1] = -110;
				}
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (0040FFEC) --------------------------------------------------------
void __cdecl FenceDoorFix()
{
	signed int v0; // edi
	char *v1; // eax
	signed int v2; // esi
	char v3; // bl
	char v4; // cl
	unsigned char v5; // cl
	char v6; // dl
	char v7; // cl
	char v8; // cl
	char v9; // dl

	v0 = 0;
	do
	{
		v1 = &dungeon[-1][v0 + 39];
		v2 = 40;
		do
		{
			v3 = v1[1];
			if ( v3 == -110
			  && ((v4 = v1[41], (unsigned char)v4 > 0x98u)
			   || (unsigned char)v4 < 0x82u
			   || (v5 = *(v1 - 39), v5 > 0x98u)
			   || v5 < 0x82u
			   || (v6 = v1[41], v6 != -126)
			   && v5 != -126
			   && v6 != -124
			   && v5 != -124
			   && v6 != -123
			   && v5 != -123
			   && v6 != -122
			   && v5 != -122
			   && v6 != -120
			   && v5 != -120
			   && v6 != -118
			   && v5 != -118
			   && v6 != -116
			   && v5 != -116)
			  || v3 == -109
			  && ((v7 = v1[2], (unsigned char)v7 > 0x98u)
			   || (unsigned char)v7 < 0x82u
			   || (v8 = *v1, (unsigned char)*v1 > 0x98u)
			   || (unsigned char)v8 < 0x82u
			   || (v9 = v1[2], v9 != -125)
			   && v8 != -125
			   && v9 != -124
			   && v8 != -124
			   && v9 != -123
			   && v8 != -123
			   && v9 != -121
			   && v8 != -121
			   && v9 != -119
			   && v8 != -119
			   && v9 != -118
			   && v8 != -118
			   && v9 != -117
			   && v8 != -117) )
			{
				v1[1] = 7;
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (00410105) --------------------------------------------------------
void __cdecl DRLG_L3Anvil()
{
	int v0; // esi
	signed int v1; // edi
	signed int v2; // ebx
	signed int v3; // eax
	int v4; // ecx
	unsigned char v5; // dl
	signed int v6; // ebx
	int v7; // edi
	int v8; // ecx
	signed int v9; // eax
	unsigned char v10; // dl
	signed int v11; // [esp+Ch] [ebp-Ch]
	signed int v12; // [esp+Ch] [ebp-Ch]
	signed int v13; // [esp+10h] [ebp-8h]
	int v14; // [esp+14h] [ebp-4h]

	v0 = random(0, 29);
	v1 = 0;
	v14 = random(0, 29);
	v11 = 0;
	while ( v11 < 200 )
	{
		++v11;
		v13 = 1;
		v2 = 2;
		do
		{
			if ( v13 != 1 )
				break;
			v3 = 0;
			v4 = v14 + v1 + 40 * v0;
			do
			{
				if ( v13 != 1 )
					break;
				v5 = L3ANVIL[v2];
				if ( v5 && dungeon[0][v4] != v5 )
					v13 = 0;
				if ( dflags[0][v4] )
					v13 = 0;
				++v2;
				++v3;
				v4 += 40;
			}
			while ( v3 < 11 );
			++v1;
		}
		while ( v1 < 11 );
		v1 = 0;
		if ( v13 )
		{
			if ( v11 < 200 )
			{
				v12 = 11;
				v6 = 123;
				v7 = v14 + 40 * v0;
				do
				{
					v8 = v7;
					v9 = 11;
					do
					{
						v10 = L3ANVIL[v6];
						if ( v10 )
							dungeon[0][v8] = v10;
						dflags[0][v8] |= 0x80u;
						++v6;
						v8 += 40;
						--v9;
					}
					while ( v9 );
					++v7;
					--v12;
				}
				while ( v12 );
				setpc_y = v14;
				setpc_w = 11;
				setpc_h = 11;
				setpc_x = v0;
			}
			return;
		}
		if ( ++v0 == 29 )
		{
			v0 = 0;
			if ( ++v14 == 29 )
				v14 = 0;
		}
	}
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00410215) --------------------------------------------------------
void __cdecl FixL3Warp()
{
	int v0; // ecx
	signed int v1; // esi
	char *v2; // eax
	char v3; // dl
	signed int v4; // eax

	v0 = 0;
	while ( 2 )
	{
		v1 = 0;
		v2 = &dungeon[1][v0 + 1];
		do
		{
			v3 = *(v2 - 41);
			if ( v3 == 125 && *(v2 - 1) == 125 && *(v2 - 40) == 125 && *v2 == 125 )
			{
				v4 = v1;
				dungeon[v4][v0] = -100;
				dungeon[v4 + 1][v0] = -101;
				dungeon[v4][v0 + 1] = -103;
				dungeon[v4 + 1][v0 + 1] = -102;
				return;
			}
			if ( v3 == 5 && *v2 == 7 )
				*(v2 - 41) = 7;
			++v1;
			v2 += 40;
		}
		while ( v1 < 40 );
		if ( ++v0 < 40 )
			continue;
		break;
	}
}

//----- (0041027D) --------------------------------------------------------
void __cdecl FixL3HallofHeroes()
{
	signed int v0; // ecx
	char *v1; // eax
	signed int v2; // edx
	signed int v3; // ecx
	char *v4; // eax
	signed int v5; // edx

	v0 = 0;
	do
	{
		v1 = (char *)dungeon + v0;
		v2 = 40;
		do
		{
			if ( *v1 == 5 && v1[41] == 7 )
				*v1 = 7;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
	v3 = 0;
	do
	{
		v4 = (char *)dungeon + v3;
		v5 = 40;
		do
		{
			if ( *v4 == 5 )
			{
				if ( v4[41] == 12 && v4[40] == 7 )
				{
					*v4 = 7;
					v4[1] = 7;
					v4[41] = 7;
				}
				if ( *v4 == 5 && v4[41] == 12 && v4[1] == 7 )
				{
					*v4 = 7;
					v4[40] = 7;
					v4[41] = 7;
				}
			}
			v4 += 40;
			--v5;
		}
		while ( v5 );
		++v3;
	}
	while ( v3 < 40 );
}

//----- (004102F1) --------------------------------------------------------
void __fastcall DRLG_L3LockRec(int x, int y)
{
	int v2; // esi
	int v3; // edi
	char *v4; // eax
	char *v5; // ebp

	v2 = x;
	v3 = y;
	v4 = &lockout[x][y];
	if ( *v4 )
	{
		v5 = &lockout[x][y];
		do
		{
			*v4 = 0;
			++lockoutcnt;
			DRLG_L3LockRec(v2, v3 - 1);
			DRLG_L3LockRec(v2, v3 + 1);
			DRLG_L3LockRec(v2 - 1, v3);
			v5 += 40;
			++v2;
			v4 = v5;
		}
		while ( *v5 );
	}
}
// 528380: using guessed type int lockoutcnt;

//----- (00410344) --------------------------------------------------------
void __cdecl DRLG_L3Lockout()
{
	int v0; // esi
	signed int v1; // edx
	signed int v2; // ecx
	signed int v3; // eax
	int x; // [esp+4h] [ebp-8h]
	int y; // [esp+8h] [ebp-4h]

	v0 = 0;
	v1 = 0;
	do
	{
		v2 = 0;
		v3 = v1;
		do
		{
			if ( dungeon[0][v3] )
			{
				lockout[0][v3] = 1;
				x = v2;
				y = v1;
				++v0;
			}
			else
			{
				lockout[0][v3] = 0;
			}
			++v2;
			v3 += 40;
		}
		while ( v2 < 40 );
		++v1;
	}
	while ( v1 < 40 );
	lockoutcnt = 0;
	DRLG_L3LockRec(x, y);
}
// 528380: using guessed type int lockoutcnt;

//----- (004103A1) --------------------------------------------------------
void __fastcall CreateL3Dungeon(int seed, int entry)
{
	int v2; // esi
	int v3; // edi
	int v4; // esi
	signed int v5; // eax
	signed int *v6; // [esp+8h] [ebp-8h]
	int (*v7)[112]; // [esp+Ch] [ebp-4h]

	v2 = entry;
	SetRndSeed(seed);
	dminx = 16;
	dminy = 16;
	dmaxx = 96;
	dmaxy = 96;
	DRLG_InitTrans();
	DRLG_InitSetPC();
	DRLG_L3(v2);
	DRLG_L3Pass3();
	v3 = 0;
	v7 = dPiece;
	do
	{
		v4 = 0;
		v6 = (signed int *)v7;
		do
		{
			v5 = *v6;
			if ( *v6 >= 56 && v5 <= 147 || v5 >= 154 && v5 <= 161 || v5 == 150 || v5 == 152 )
				DoLighting(v4, v3, 7, -1);
			v6 += 112;
			++v4;
		}
		while ( v4 < 112 );
		v7 = (int (*)[112])((char *)v7 + 4);
		++v3;
	}
	while ( (signed int)v7 < (signed int)dPiece[1] );
	DRLG_SetPC();
}
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;

//----- (0041044E) --------------------------------------------------------
void __fastcall DRLG_L3(int entry)
{
	int v1; // ecx
	int v2; // eax
	int v3; // ecx
	int v4; // esi
	int v5; // eax
	int v6; // edi
	int y; // ST28_4
	int v8; // eax
	int v9; // ecx
	int v10; // eax
	int v11; // ecx
	int v12; // esi
	int v13; // eax
	signed int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // eax
	int v18; // eax
	int v19; // eax
	char *v20; // eax
	signed int v21; // ecx
	signed int v22; // eax
	signed int v23; // esi
	bool v24; // [esp-8h] [ebp-20h]
	int v25; // [esp+10h] [ebp-8h]

	lavapool = 0;
	v25 = entry;
	do
	{
		do
		{
			do
			{
				InitL3Dungeon();
				_LOBYTE(v1) = 0;
				v2 = random(v1, 20);
				_LOBYTE(v3) = 0;
				v4 = v2 + 10;
				v5 = random(v3, 20);
				v6 = v5 + 10;
				y = v5 + 12;
				DRLG_L3FillRoom(v4, v5 + 10, v4 + 2, v5 + 12);
				DRLG_L3CreateBlock(v4, v6, 2, 0);
				DRLG_L3CreateBlock(v4 + 2, v6, 2, 1);
				DRLG_L3CreateBlock(v4, y, 2, 2);
				DRLG_L3CreateBlock(v4, v6, 2, 3);
				_LOBYTE(v8) = QuestStatus(10);
				if ( v8 )
				{
					_LOBYTE(v9) = 0;
					v10 = random(v9, 10);
					_LOBYTE(v11) = 0;
					v12 = v10 + 10;
					v13 = random(v11, 10);
					DRLG_L3FloorArea(v12, v13 + 10, v12 + 12, v13 + 22);
				}
				DRLG_L3FillDiags();
				DRLG_L3FillSingles();
				DRLG_L3FillStraights();
				DRLG_L3FillDiags();
				DRLG_L3Edges();
				DRLG_L3GetFloorArea();
				if ( v14 < 600 )
					v15 = 0;
				else
					DRLG_L3Lockout();
			}
			while ( !v15 );
			DRLG_L3MakeMegas();
			if ( !v25 )
			{
				_LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3UP, 1, 1, -1, -1, 1, 0);
				if ( v16 )
					continue;
				_LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3DOWN, 1, 1, -1, -1, 0, 1);
				if ( v16 )
					continue;
				if ( currlevel != 9 )
					goto LABEL_24;
				_LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3HOLDWARP, 1, 1, -1, -1, 0, 6);
				goto LABEL_23;
			}
			_LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3UP, 1, 1, -1, -1, 0, 0);
			if ( v25 == 1 )
			{
				if ( v16 )
					continue;
				_LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3DOWN, 1, 1, -1, -1, 1, 1);
				ViewX += 2;
				ViewY -= 2;
				if ( v16 )
					continue;
				if ( currlevel != 9 )
					goto LABEL_24;
				v24 = 0;
LABEL_22:
				_LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3HOLDWARP, 1, 1, -1, -1, v24, 6);
LABEL_23:
				if ( v16 )
					continue;
				goto LABEL_24;
			}
			if ( v16 )
				continue;
			_LOBYTE(v16) = DRLG_L3PlaceMiniSet((char *)L3DOWN, 1, 1, -1, -1, 0, 1);
			if ( v16 )
				continue;
			if ( currlevel == 9 )
			{
				v24 = 1;
				goto LABEL_22;
			}
LABEL_24:
			_LOBYTE(v17) = QuestStatus(10);
			if ( !v17 )
				break;
			DRLG_L3Anvil();
		}
		while ( v16 == 1 );
		DRLG_L3Pool();
	}
	while ( !lavapool );
	DRLG_L3PoolFix();
	FixL3Warp();
	DRLG_L3PlaceRndSet(L3ISLE1, 70);
	DRLG_L3PlaceRndSet(L3ISLE2, 70);
	DRLG_L3PlaceRndSet(L3ISLE3, 30);
	DRLG_L3PlaceRndSet(L3ISLE4, 30);
	DRLG_L3PlaceRndSet(L3ISLE1, 100);
	DRLG_L3PlaceRndSet(L3ISLE2, 100);
	DRLG_L3PlaceRndSet(L3ISLE5, 90);
	FixL3HallofHeroes();
	DRLG_L3River();
	_LOBYTE(v18) = QuestStatus(10);
	if ( v18 )
	{
		v19 = setpc_y + 40 * setpc_x;
		dungeon[7][v19 + 5] = 7;
		dungeon[8][v19 + 5] = 7;
		dungeon[9][v19 + 5] = 7;
		v20 = &dungeon[10][v19 + 5];
		if ( *v20 == 17 || *v20 == 18 )
			*v20 = 45;
	}
	DRLG_PlaceThemeRooms(5, 10, 7, 0, 0);
	DRLG_L3Wood();
	DRLG_L3PlaceRndSet(L3TITE1, 10);
	DRLG_L3PlaceRndSet(L3TITE2, 10);
	DRLG_L3PlaceRndSet(L3TITE3, 10);
	DRLG_L3PlaceRndSet(L3TITE6, 20);
	DRLG_L3PlaceRndSet(L3TITE7, 20);
	DRLG_L3PlaceRndSet(L3TITE8, 20);
	DRLG_L3PlaceRndSet(L3TITE9, 20);
	DRLG_L3PlaceRndSet(L3TITE10, 20);
	DRLG_L3PlaceRndSet(L3TITE11, 30);
	DRLG_L3PlaceRndSet(L3TITE12, 20);
	DRLG_L3PlaceRndSet(L3TITE13, 20);
	DRLG_L3PlaceRndSet(L3CREV1, 30);
	DRLG_L3PlaceRndSet(L3CREV2, 30);
	DRLG_L3PlaceRndSet(L3CREV3, 30);
	DRLG_L3PlaceRndSet(L3CREV4, 30);
	DRLG_L3PlaceRndSet(L3CREV5, 30);
	DRLG_L3PlaceRndSet(L3CREV6, 30);
	DRLG_L3PlaceRndSet(L3CREV7, 30);
	DRLG_L3PlaceRndSet(L3CREV8, 30);
	DRLG_L3PlaceRndSet(L3CREV9, 30);
	DRLG_L3PlaceRndSet(L3CREV10, 30);
	DRLG_L3PlaceRndSet(L3CREV11, 30);
	DRLG_L3PlaceRndSet(L3XTRA1, 25);
	DRLG_L3PlaceRndSet(L3XTRA2, 25);
	DRLG_L3PlaceRndSet(L3XTRA3, 25);
	DRLG_L3PlaceRndSet(L3XTRA4, 25);
	DRLG_L3PlaceRndSet(L3XTRA5, 25);
	v21 = 0;
	do
	{
		v22 = v21;
		v23 = 40;
		do
		{
			pdungeon[0][v22] = dungeon[0][v22];
			v22 += 40;
			--v23;
		}
		while ( v23 );
		++v21;
	}
	while ( v21 < 40 );
	DRLG_Init_Globals();
}
// 528378: using guessed type char lavapool;

//----- (0041087F) --------------------------------------------------------
void __cdecl InitL3Dungeon()
{
	signed int v0; // edx
	signed int v1; // eax
	signed int v2; // ecx

	memset(dungeon, 0, 0x640u);
	v0 = 0;
	do
	{
		v1 = v0;
		v2 = 40;
		do
		{
			dungeon[0][v1] = 0;
			dflags[0][v1] = 0;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (004108B5) --------------------------------------------------------
int __fastcall DRLG_L3FillRoom(int x1, int y1, int x2, int y2)
{
	int v4; // esi
	int v5; // eax
	int v6; // edi
	int v7; // edx
	int v8; // ecx
	char *v9; // ecx
	int v10; // eax
	int v11; // ebx
	char *v12; // edx
	int v13; // eax
	int i; // ebx
	int v15; // ecx
	int v16; // ecx
	char *v17; // ebx
	int v18; // edi
	int v19; // ecx
	int v21; // [esp+Ch] [ebp-4h]
	int x2a; // [esp+18h] [ebp+8h]
	int y2a; // [esp+1Ch] [ebp+Ch]

	v4 = x1;
	v5 = y1;
	v21 = y1;
	if ( x1 <= 1 )
		return 0;
	v6 = x2;
	if ( x2 >= 34 || y1 <= 1 || y2 >= 38 )
		return 0;
	v7 = 0;
	v8 = v5;
	x2a = v5;
	if ( v5 <= y2 )
	{
		do
		{
			if ( v4 <= v6 )
			{
				v9 = &dungeon[v4][v8];
				v10 = v6 - v4 + 1;
				do
				{
					v7 += (unsigned char)*v9;
					v9 += 40;
					--v10;
				}
				while ( v10 );
			}
			v8 = x2a++ + 1;
		}
		while ( x2a <= y2 );
		if ( !v7 )
		{
			v5 = v21;
			goto LABEL_12;
		}
		return 0;
	}
LABEL_12:
	v11 = v5 + 1;
	if ( v5 + 1 < y2 )
	{
		v8 = v4 + 1;
		do
		{
			if ( v8 < v6 )
			{
				v12 = &dungeon[v8][v11];
				v13 = v6 - v8;
				do
				{
					*v12 = 1;
					v12 += 40;
					--v13;
				}
				while ( v13 );
			}
			++v11;
		}
		while ( v11 < y2 );
		v5 = v21;
	}
	for ( i = v5; i <= y2; ++i )
	{
		_LOBYTE(v8) = 0;
		if ( random(v8, 2) )
			dungeon[v4][i] = 1;
		_LOBYTE(v15) = 0;
		if ( random(v15, 2) )
			dungeon[v6][i] = 1;
	}
	if ( v4 <= v6 )
	{
		v16 = y2;
		v17 = &dungeon[v4][y2];
		v18 = v6 - v4 + 1;
		y2a = v21 - y2;
		do
		{
			_LOBYTE(v16) = 0;
			if ( random(v16, 2) )
				v17[y2a] = 1;
			_LOBYTE(v19) = 0;
			if ( random(v19, 2) )
				*v17 = 1;
			v17 += 40;
			--v18;
		}
		while ( v18 );
	}
	return 1;
}

//----- (004109F0) --------------------------------------------------------
void __fastcall DRLG_L3CreateBlock(int x, int y, int obs, int dir)
{
	int v4; // esi
	int v5; // edi
	int v6; // eax
	int v7; // ecx
	int v8; // ecx
	int v9; // ebx
	bool v10; // zf
	bool v11; // zf
	int v12; // ecx
	int y2; // [esp+Ch] [ebp-14h]
	int x2; // [esp+10h] [ebp-10h]
	int i; // [esp+14h] [ebp-Ch]
	int v16; // [esp+18h] [ebp-8h]
	int max; // [esp+1Ch] [ebp-4h]

	v4 = obs;
	v5 = obs;
	v16 = y;
	for ( i = x; ; i = v4 )
	{
		_LOBYTE(x) = 0;
		v6 = random(x, 2);
		_LOBYTE(v7) = 0;
		max = v6 + 3;
		v9 = random(v7, 2) + 3;
		if ( !dir )
		{
			y2 = v16 - 1;
			v5 = v16 - 1 - v9;
			if ( max < obs )
			{
				_LOBYTE(v8) = 0;
				v4 = i + random(v8, max);
			}
			if ( max == obs )
				v4 = i;
			if ( max > obs )
			{
				_LOBYTE(v8) = 0;
				v4 = i - random(v8, max);
			}
			x2 = v4 + max;
		}
		if ( dir == 3 )
		{
			x2 = i - 1;
			v4 = i - 1 - max;
			v10 = v9 == obs;
			if ( v9 < obs )
			{
				_LOBYTE(v8) = 0;
				v5 = v16 + random(v8, v9);
				v10 = v9 == obs;
			}
			if ( v10 )
				v5 = v16;
			if ( v9 > obs )
			{
				_LOBYTE(v8) = 0;
				v5 = v16 - random(v8, v9);
			}
			y2 = v5 + v9;
		}
		if ( dir == 2 )
		{
			v5 = v16 + 1;
			y2 = v16 + 1 + v9;
			if ( max < obs )
			{
				_LOBYTE(v8) = 0;
				v4 = i + random(v8, max);
			}
			if ( max == obs )
				v4 = i;
			if ( max > obs )
			{
				_LOBYTE(v8) = 0;
				v4 = i - random(v8, max);
			}
			x2 = v4 + max;
		}
		if ( dir == 1 )
		{
			v4 = i + 1;
			v11 = v9 == obs;
			x2 = i + 1 + max;
			if ( v9 < obs )
			{
				_LOBYTE(v8) = 0;
				v5 = v16 + random(v8, v9);
				v11 = v9 == obs;
			}
			if ( v11 )
				v5 = v16;
			if ( v9 > obs )
			{
				_LOBYTE(v8) = 0;
				v5 = v16 - random(v8, v9);
			}
			y2 = v5 + v9;
		}
		if ( DRLG_L3FillRoom(v4, v5, x2, y2) != 1 )
			break;
		_LOBYTE(v12) = 0;
		if ( !random(v12, 4) )
			break;
		if ( dir != 2 )
			DRLG_L3CreateBlock(v4, v5, v9, 0);
		if ( dir != 3 )
			DRLG_L3CreateBlock(x2, v5, max, 1);
		if ( dir )
			DRLG_L3CreateBlock(v4, y2, v9, 2);
		if ( dir == 1 )
			break;
		dir = 3;
		obs = max;
		v16 = v5;
	}
}

//----- (00410BC0) --------------------------------------------------------
void __fastcall DRLG_L3FloorArea(int x1, int y1, int x2, int y2)
{
	int i; // esi
	char *v5; // edx
	int v6; // eax

	for ( i = y1; i <= y2; ++i )
	{
		if ( x1 <= x2 )
		{
			v5 = &dungeon[x1][i];
			v6 = x2 - x1 + 1;
			do
			{
				*v5 = 1;
				v5 += 40;
				--v6;
			}
			while ( v6 );
		}
	}
}

//----- (00410BF4) --------------------------------------------------------
void __cdecl DRLG_L3FillDiags()
{
	signed int v0; // ebx
	char *v1; // esi
	signed int v2; // ebp
	int v3; // ecx
	int v4; // edi

	v0 = 0;
	do
	{
		v1 = &dungeon[1][v0 + 1];
		v2 = 39;
		do
		{
			v3 = (unsigned char)*v1;
			v4 = v3
			   + 2 * ((unsigned char)*(v1 - 40) + 2 * ((unsigned char)*(v1 - 1) + 2 * (unsigned char)*(v1 - 41)));
			if ( v4 == 6 )
			{
				_LOBYTE(v3) = 0;
				if ( !random(v3, 2) )
				{
					*(v1 - 41) = 1;
					goto LABEL_11;
				}
				*v1 = 1;
			}
			if ( v4 == 9 )
			{
				_LOBYTE(v3) = 0;
				if ( random(v3, 2) )
					*(v1 - 40) = 1;
				else
					*(v1 - 1) = 1;
			}
LABEL_11:
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 39 );
}

//----- (00410C65) --------------------------------------------------------
void __cdecl DRLG_L3FillSingles()
{
	signed int v0; // ecx
	char *v1; // eax
	signed int v2; // edx

	v0 = 1;
	do
	{
		v1 = &dungeon[0][v0 + 39];
		v2 = 38;
		do
		{
			if ( !v1[1]
			  && (unsigned char)*v1 + (unsigned char)v1[40] + (unsigned char)*(v1 - 40) == 3
			  && (unsigned char)*(v1 - 39) + (unsigned char)v1[41] == 2
			  && (unsigned char)v1[2] + (unsigned char)*(v1 - 38) + (unsigned char)v1[42] == 3 )
			{
				v1[1] = 1;
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 39 );
}

//----- (00410CC4) --------------------------------------------------------
void __cdecl DRLG_L3FillStraights()
{
	int v0; // esi
	char *v1; // ecx
	signed int v2; // eax
	char *v3; // ebx
	int v4; // edi
	int v5; // ebx
	char v6; // al
	char *v7; // ecx
	signed int v8; // eax
	char *v9; // ebx
	int v10; // edi
	int v11; // ebx
	char v12; // al
	signed int v13; // ebx
	signed int v14; // eax
	signed int v15; // esi
	signed int i; // edi
	signed int v17; // ebx
	signed int v18; // eax
	signed int v19; // esi
	signed int j; // edi
	int v21; // [esp+Ch] [ebp-14h]
	char *v22; // [esp+Ch] [ebp-14h]
	char *v23; // [esp+Ch] [ebp-14h]
	char *v24; // [esp+10h] [ebp-10h]
	signed int v25; // [esp+14h] [ebp-Ch]
	signed int v26; // [esp+14h] [ebp-Ch]
	signed int v27; // [esp+18h] [ebp-8h]
	signed int v28; // [esp+18h] [ebp-8h]
	int v29; // [esp+1Ch] [ebp-4h]
	int v30; // [esp+1Ch] [ebp-4h]

	v27 = 0;
	v0 = v21;
	do
	{
		v1 = (char *)v27;
		v2 = 0;
		v29 = 0;
		v3 = &dungeon[0][v27 + 1];
		v4 = 40 * v0;
		v25 = 0;
		v22 = &dungeon[0][v27 + 1];
		do
		{
			if ( *(v3 - 1) || *v3 != 1 )
			{
				if ( v2 > 3 )
				{
					_LOBYTE(v1) = 0;
					if ( random((int)v1, 2) )
					{
						if ( v0 < v29 )
						{
							v5 = v29 - v0;
							v24 = (char *)dungeon + v4 + v27;
							do
							{
								_LOBYTE(v1) = 0;
								v6 = random((int)v1, 2);
								v1 = v24;
								v24 += 40;
								--v5;
								*v1 = v6;
							}
							while ( v5 );
							v3 = v22;
						}
					}
				}
				v2 = 0;
			}
			else
			{
				if ( !v2 )
				{
					v0 = v29;
					v4 = v25;
				}
				++v2;
			}
			v25 += 40;
			++v29;
			v3 += 40;
			v22 = v3;
		}
		while ( v25 < 1480 );
		++v27;
	}
	while ( v27 < 39 );
	v28 = 0;
	do
	{
		v7 = (char *)v28;
		v8 = 0;
		v30 = 0;
		v9 = &dungeon[0][v28 + 1];
		v26 = 0;
		v10 = 40 * v0;
		v23 = &dungeon[0][v28 + 1];
		do
		{
			if ( *(v9 - 1) != 1 || *v9 )
			{
				if ( v8 > 3 )
				{
					_LOBYTE(v7) = 0;
					if ( random((int)v7, 2) )
					{
						if ( v0 < v30 )
						{
							v11 = v30 - v0;
							v24 = &dungeon[0][v10 + 1 + v28];
							do
							{
								_LOBYTE(v7) = 0;
								v12 = random((int)v7, 2);
								v7 = v24;
								v24 += 40;
								--v11;
								*v7 = v12;
							}
							while ( v11 );
							v9 = v23;
						}
					}
				}
				v8 = 0;
			}
			else
			{
				if ( !v8 )
				{
					v0 = v30;
					v10 = v26;
				}
				++v8;
			}
			v26 += 40;
			++v30;
			v9 += 40;
			v23 = v9;
		}
		while ( v26 < 1480 );
		++v28;
	}
	while ( v28 < 39 );
	v13 = 0;
	do
	{
		v14 = 0;
		v15 = 0;
		do
		{
			if ( dungeon[v13][v15] || dungeon[v13 + 1][v15] != 1 )
			{
				if ( v14 > 3 )
				{
					_LOBYTE(v7) = 0;
					if ( random((int)v7, 2) )
					{
						for ( i = (signed int)v24; i < v15; ++i )
						{
							_LOBYTE(v7) = 0;
							dungeon[v13][i] = random((int)v7, 2);
						}
					}
				}
				v14 = 0;
			}
			else
			{
				if ( !v14 )
					v24 = (char *)v15;
				++v14;
			}
			++v15;
		}
		while ( v15 < 37 );
		++v13;
	}
	while ( v13 < 39 );
	v17 = 0;
	do
	{
		v18 = 0;
		v19 = 0;
		do
		{
			if ( dungeon[v17][v19] != 1 || dungeon[v17 + 1][v19] )
			{
				if ( v18 > 3 )
				{
					_LOBYTE(v7) = 0;
					if ( random((int)v7, 2) )
					{
						for ( j = (signed int)v24; j < v19; ++j )
						{
							_LOBYTE(v7) = 0;
							dungeon[v17 + 1][j] = random((int)v7, 2);
						}
					}
				}
				v18 = 0;
			}
			else
			{
				if ( !v18 )
					v24 = (char *)v19;
				++v18;
			}
			++v19;
		}
		while ( v19 < 37 );
		++v17;
	}
	while ( v17 < 39 );
}

//----- (00410EDB) --------------------------------------------------------
void __cdecl DRLG_L3Edges()
{
	char *v0; // eax

	memset(dungeon[39], 0, sizeof(char[40]));
	v0 = &dungeon[0][39];
	do
	{
		*v0 = 0;
		v0 += 40;
	}
	while ( (signed int)v0 < (signed int)&dObject[0][39] );
}

//----- (00410EFC) --------------------------------------------------------
void __cdecl DRLG_L3GetFloorArea()
{
	int v0; // eax
	signed int v1; // edx
	unsigned char *v2; // ecx
	signed int v3; // esi

	v0 = 0;
	v1 = 0;
	do
	{
		v2 = (unsigned char *)dungeon + v1;
		v3 = 40;
		do
		{
			v0 += *v2;
			v2 += 40;
			--v3;
		}
		while ( v3 );
		++v1;
	}
	while ( v1 < 40 );
}

//----- (00410F1F) --------------------------------------------------------
void __cdecl DRLG_L3MakeMegas()
{
	signed int v0; // edi
	char *v1; // esi
	signed int v2; // ebp
	int v3; // ecx
	int v4; // eax
	char *v5; // eax

	v0 = 0;
	do
	{
		v1 = &dungeon[0][v0 + 1];
		v2 = 39;
		do
		{
			v3 = (unsigned char)v1[40];
			v4 = v3 + 2 * ((unsigned char)*v1 + 2 * ((unsigned char)v1[39] + 2 * (unsigned char)*(v1 - 1)));
			if ( v4 == 6 )
			{
				_LOBYTE(v3) = 0;
				if ( !random(v3, 2) )
				{
					v4 = 12;
					goto LABEL_9;
				}
				v4 = 5;
			}
			if ( v4 == 9 )
			{
				_LOBYTE(v3) = 0;
				v4 = (random(v3, 2) != 0) + 13;
			}
LABEL_9:
			--v2;
			*(v1 - 1) = L3ConvTbl[v4];
			v1 += 40;
		}
		while ( v2 );
		dungeon[39][v0++] = 8;
	}
	while ( v0 < 39 );
	v5 = &dungeon[0][39];
	do
	{
		*v5 = 8;
		v5 += 40;
	}
	while ( (signed int)v5 < (signed int)&dObject[0][39] );
}

//----- (00410FAD) --------------------------------------------------------
void __cdecl DRLG_L3River()
{
	signed int v0; // ebx
	int v1; // esi
	int v2; // edi
	char v3; // al
	char v4; // al
	signed int v5; // edx
	int v6; // eax
	int v7; // ebx
	unsigned char v8; // al
	unsigned char v9; // al
	int v10; // eax
	char *v11; // eax
	signed int v12; // eax
	int v13; // ecx
	bool v14; // zf
	int v15; // eax
	signed int v16; // eax
	int v17; // eax
	signed int v18; // eax
	signed int v19; // eax
	signed int v20; // edi
	int v21; // eax
	int v22; // eax
	int v23; // edx
	int v24; // ecx
	int v25; // ecx
	int v26; // esi
	int v27; // ecx
	int v28; // edx
	int v29; // ecx
	int v30; // edx
	int v31; // ecx
	int v32; // edx
	bool v33; // sf
	unsigned char v34; // of
	int v35[100]; // [esp+Ch] [ebp-4E8h]
	int v36[98]; // [esp+19Ch] [ebp-358h]
	int v37; // [esp+324h] [ebp-1D0h]
	int v38; // [esp+328h] [ebp-1CCh]
	int v39[100]; // [esp+32Ch] [ebp-1C8h]
	int v40; // [esp+4BCh] [ebp-38h]
	int v41; // [esp+4C0h] [ebp-34h]
	int v42; // [esp+4C4h] [ebp-30h]
	int v43; // [esp+4C8h] [ebp-2Ch]
	int v44; // [esp+4CCh] [ebp-28h]
	int v45; // [esp+4D0h] [ebp-24h]
	int v46; // [esp+4D4h] [ebp-20h]
	int v47; // [esp+4D8h] [ebp-1Ch]
	int v48; // [esp+4DCh] [ebp-18h]
	int v49; // [esp+4E0h] [ebp-14h]
	int v50; // [esp+4E4h] [ebp-10h]
	int v51; // [esp+4E8h] [ebp-Ch]
	int v52; // [esp+4ECh] [ebp-8h]
	int max; // [esp+4F0h] [ebp-4h]

	v0 = 0;
	v43 = 0;
	v45 = 0;
	while ( v43 < 4 )
	{
		v51 = 0;
		do
		{
			if ( v45 >= 200 )
			{
				v5 = max;
				break;
			}
			++v45;
			v1 = 0;
			v2 = 0;
			while ( 1 )
			{
				v3 = dungeon[v1][v2];
				if ( (unsigned char)v3 >= 0x19u && (unsigned char)v3 <= 0x1Cu )
					break;
				if ( v0 >= 100 )
					return;
				v1 = random(0, 40);
				v2 = random(0, 40);
				++v0;
				while ( 1 )
				{
					v4 = dungeon[v1][v2];
					if ( (unsigned char)v4 >= 0x19u && (unsigned char)v4 <= 0x1Cu )
						break;
					if ( v2 >= 40 )
						break;
					if ( ++v1 >= 40 )
					{
						v1 = 0;
						++v2;
					}
				}
			}
			if ( v0 >= 100 )
				return;
			switch ( dungeon[v1][v2] )
			{
				case 0x19:
					v52 = 3;
					v46 = 2;
					v39[0] = 40;
					break;
				case 0x1A:
					v52 = 0;
					v46 = 1;
					v39[0] = 38;
					break;
				case 0x1B:
					v46 = 0;
					v52 = 1;
					v39[0] = 41;
					break;
				case 0x1C:
					v52 = 2;
					v46 = 3;
					v39[0] = 39;
					break;
			}
			v47 = 0;
			max = 1;
			v5 = 1;
			v35[0] = v1;
			v36[0] = v2;
			v50 = 4;
			v49 = 40 * v1;
			while ( v5 < 100 )
			{
				v42 = v1;
				v40 = v49;
				v41 = v2;
				if ( v47 )
				{
					v52 = ((_BYTE)v52 + 1) & 3;
					v7 = v52;
				}
				else
				{
					v6 = random(0, 4);
					v5 = max;
					v7 = v6;
					v52 = v6;
				}
				while ( 1 )
				{
					++v47;
					if ( v7 != v46 && v7 != v50 )
						break;
					v7 = ((_BYTE)v7 + 1) & 3;
				}
				v52 = v7;
				if ( !v7 )
				{
					if ( v2 <= 0 )
						goto LABEL_44;
					--v2;
				}
				if ( v7 == 1 )
				{
					if ( v2 >= 40 )
						goto LABEL_44;
					++v2;
				}
				if ( v7 != 2 )
					goto LABEL_41;
				if ( v1 < 40 )
				{
					++v1;
					v49 += 40;
LABEL_41:
					if ( v7 == 3 && v1 > 0 )
					{
						--v1;
						v49 -= 40;
					}
				}
LABEL_44:
				if ( dungeon[0][v49 + v2] == 7 )
				{
					v47 = 0;
					if ( v7 < 2 )
					{
						v8 = random(0, 2);
						v5 = max;
						v39[max] = v8 + 17;
					}
					if ( v7 > 1 )
					{
						v9 = random(0, 2);
						v5 = max;
						v39[max] = v9 + 15;
					}
					v10 = v44;
					v35[v5] = v1;
					v36[v5++] = v2;
					max = v5;
					if ( v7 || v10 != 2 )
					{
						if ( v7 != 3 )
							goto LABEL_58;
						if ( v10 != 1 )
							goto LABEL_70;
					}
					if ( v5 > 2 )
						*(&v37 + v5) = 22;
					if ( !v7 )
					{
						v50 = 1;
LABEL_59:
						if ( v10 == 3 )
							goto LABEL_62;
						goto LABEL_60;
					}
					v50 = 2;
LABEL_58:
					if ( !v7 )
						goto LABEL_59;
LABEL_60:
					if ( v7 != 2 )
						goto LABEL_67;
					if ( v10 != 1 )
						goto LABEL_79;
LABEL_62:
					if ( v5 > 2 )
						*(&v37 + v5) = 21;
					if ( !v7 )
					{
						v50 = 1;
						goto LABEL_83;
					}
					v50 = 3;
LABEL_67:
					if ( v7 != 1 || v10 != 2 )
					{
						if ( v7 != 3 )
							goto LABEL_76;
LABEL_70:
						if ( v10 )
							goto LABEL_83;
					}
					if ( v5 > 2 )
						*(&v37 + v5) = 20;
					if ( v7 == 1 )
					{
						v50 = 0;
						goto LABEL_77;
					}
					v50 = 2;
LABEL_76:
					if ( v7 != 1 )
						goto LABEL_78;
LABEL_77:
					if ( v10 != 3 )
					{
LABEL_78:
						if ( v7 != 2 )
							goto LABEL_83;
LABEL_79:
						if ( v10 )
							goto LABEL_83;
					}
					if ( v5 > 2 )
						*(&v37 + v5) = 19;
					v50 = v7 != 1 ? 3 : 0;
LABEL_83:
					v44 = v7;
				}
				else
				{
					v1 = v42;
					v2 = v41;
					v49 = v40;
					if ( v47 >= 4 )
						break;
				}
			}
			if ( v52 )
			{
				v13 = v44;
				goto LABEL_94;
			}
			v11 = &dungeon[v1][v2];
			if ( *(v11 - 1) == 10 && *(v11 - 2) == 8 )
			{
				v12 = v5;
				v36[v12] = v2 - 1;
				v13 = v44;
				v14 = v44 == 2;
				v35[v12] = v1;
				v39[v12] = 24;
				if ( v14 )
					*(int *)((char *)&v38 + v12 * 4) = 22;
				if ( v13 == 3 )
					*(int *)((char *)&v38 + v12 * 4) = 21;
				v51 = 1;
LABEL_94:
				if ( v52 == 1 )
				{
					v15 = v2 + 40 * v1;
					if ( dungeon[0][v15 + 1] == 2 && dungeon[0][v15 + 2] == 8 )
					{
						v16 = v5;
						v35[v16] = v1;
						v36[v16] = v2 + 1;
						v39[v16] = 42;
						if ( v13 == 2 )
							*(int *)((char *)&v38 + v16 * 4) = 20;
						if ( v13 == 3 )
							*(int *)((char *)&v38 + v16 * 4) = 19;
						v51 = 1;
						goto LABEL_102;
					}
				}
				else
				{
LABEL_102:
					if ( v52 == 2 )
					{
						v17 = v2 + 40 * v1;
						if ( dungeon[1][v17] != 4 || dungeon[2][v17] != 8 )
							goto LABEL_118;
						v18 = v5;
						v35[v18] = v1 + 1;
						v36[v18] = v2;
						v39[v18] = 43;
						if ( !v13 )
							*(int *)((char *)&v38 + v18 * 4) = 19;
						if ( v13 == 1 )
							*(int *)((char *)&v38 + v18 * 4) = 21;
						v51 = 1;
					}
					if ( v52 == 3
					  && *((_BYTE *)&dMonster[111][10 * v1 + 102] + v2) == 9
					  && dungeon[0][8 * (5 * v1 - 10) + v2] == 8 )
					{
						v19 = v5;
						v35[v19] = v1 - 1;
						v36[v19] = v2;
						v39[v19] = 23;
						if ( !v13 )
							*(int *)((char *)&v38 + v19 * 4) = 20;
						if ( v13 == 1 )
							*(int *)((char *)&v38 + v19 * 4) = 22;
						v51 = 1;
					}
				}
			}
LABEL_118:
			v0 = 0;
		}
		while ( !v51 );
		if ( v51 == 1 && v5 >= 7 )
		{
			v20 = 0;
			v51 = 0;
LABEL_124:
			while ( v51 < 30 )
			{
				++v51;
				v21 = random(0, max);
				v48 = v21;
				v22 = v21;
				v23 = v39[v22];
				if ( v23 == 15 || v23 == 16 )
				{
					v24 = v36[v22] + 40 * v35[v22];
					if ( *((_BYTE *)&dMonster[111][111] + v24 + 3) == 7 && dungeon[0][v24 + 1] == 7 )
						v20 = 1;
				}
				if ( v23 == 17 || v23 == 18 )
				{
					v25 = v36[v22] + 40 * v35[v22];
					if ( *((_BYTE *)&dMonster[111][102] + v25) == 7 && dungeon[1][v25] == 7 )
						v20 = 2;
				}
				v26 = 0;
				if ( max > 0 )
				{
					while ( 1 )
					{
						if ( !v20 )
							goto LABEL_124;
						if ( v20 != 1 )
							goto LABEL_142;
						v27 = v36[v22];
						v28 = v36[v26];
						if ( (v27 - 1 == v28 || v27 + 1 == v28) && v35[v22] == v35[v26] )
							break;
LABEL_147:
						if ( ++v26 >= max )
							goto LABEL_148;
					}
					v20 = 0;
LABEL_142:
					if ( v20 == 2 )
					{
						v29 = v35[v22];
						v30 = v35[v26];
						if ( (v29 - 1 == v30 || v29 + 1 == v30) && v36[v22] == v36[v26] )
							v20 = 0;
					}
					goto LABEL_147;
				}
LABEL_148:
				if ( v20 )
					break;
			}
			v0 = 0;
			if ( v20 )
			{
				v39[v48] = v20 == 1 ? 44 : 45;
				v31 = max;
				++v43;
				v48 = 0;
				if ( max >= 0 )
				{
					do
					{
						v32 = v48++;
						v34 = __OFSUB__(v48, v31);
						v14 = v48 == v31;
						v33 = v48 - v31 < 0;
						dungeon[v35[v32]][v36[v32]] = v39[v32];
					}
					while ( (unsigned char)(v33 ^ v34) | v14 );
				}
			}
		}
		if ( v45 >= 200 )
			return;
	}
}
// 410FAD: using guessed type int var_1C8[100];
// 410FAD: using guessed type int var_4E8[100];
// 410FAD: using guessed type int var_358[98];

//----- (00411614) --------------------------------------------------------
void __cdecl DRLG_L3Pool()
{
	int v0; // ebx
	_BYTE *v1; // ecx
	int v2; // esi
	int v3; // ecx
	signed int v4; // eax
	signed int v5; // eax
	signed int v6; // eax
	int v7; // eax
	int v8; // edi
	int v9; // ecx
	int v10; // eax
	int v11; // esi
	char *v12; // edx
	unsigned char v13; // al
	unsigned char v14; // al
	signed int v15; // [esp+Ch] [ebp-18h]
	char *v16; // [esp+10h] [ebp-14h]
	signed int v17; // [esp+14h] [ebp-10h]
	int v18; // [esp+18h] [ebp-Ch]
	int totarea; // [esp+1Ch] [ebp-8h]
	int x; // [esp+20h] [ebp-4h]

	v0 = 0;
	v18 = 0;
	do
	{
		x = 0;
		v1 = (unsigned char *)dungeon + v0;
		v16 = (char *)dungeon + v0;
		do
		{
			if ( *v1 == 8 )
			{
				*v1 = -120;
				v2 = x - 1;
				totarea = 1;
				v3 = x - 1 + 2;
				v4 = v3 >= 40 ? 1 : DRLG_L3SpawnEdge(v3, v0, &totarea);
				v5 = v2 <= 0 || v4 ? 1 : DRLG_L3SpawnEdge(v2, v0, &totarea);
				v6 = v0 + 1 >= 40 || v5 ? 1 : DRLG_L3SpawnEdge(x, v0 + 1, &totarea);
				v17 = v0 - 1 <= 0 || v6 ? 1 : DRLG_L3SpawnEdge(x, v0 - 1, &totarea);
				_LOBYTE(v3) = 0;
				v7 = random(v3, 100);
				v8 = totarea;
				v15 = v7;
				v9 = v0 - totarea;
				if ( v0 - totarea < totarea + v0 )
				{
					totarea = x - totarea;
					v10 = v8 + x;
					do
					{
						v11 = totarea;
						if ( totarea < v10 )
						{
							v12 = &dungeon[totarea][v9];
							do
							{
								if ( *v12 < 0 && v9 >= 0 && v9 < 40 && v11 >= 0 && v11 < 40 )
								{
									v13 = *v12 & 0x7F;
									*v12 = v13;
									if ( v8 > 4 )
									{
										if ( v15 < 25 && !v17 )
										{
											v14 = L3PoolSub[v13];
											if ( v14 )
											{
												if ( v14 <= 0x25u )
													*v12 = v14;
											}
											lavapool = 1;
										}
										v0 = v18;
									}
								}
								++v11;
								v10 = v8 + x;
								v12 += 40;
							}
							while ( v11 < v8 + x );
						}
						++v9;
					}
					while ( v9 < v8 + v0 );
				}
			}
			++x;
			v1 = (unsigned char *)v16 + 40;
			v16 += 40;
		}
		while ( x < 40 );
		v18 = ++v0;
	}
	while ( v0 < 40 );
}
// 528378: using guessed type char lavapool;

//----- (00411772) --------------------------------------------------------
int __fastcall DRLG_L3SpawnEdge(int x, int y, int *totarea)
{
	int *v3; // ebp
	int v4; // edi
	int v5; // esi
	char *v6; // ecx
	int *v7; // eax
	int v8; // eax
	int *totareaa; // [esp+14h] [ebp+4h]

	v3 = totarea;
	v4 = y;
	v5 = x;
	if ( *totarea <= 40 && x >= 0 && y >= 0 && x < 40 && y < 40 )
	{
		v6 = &dungeon[x][y];
		_LOBYTE(v7) = *v6;
		if ( *v6 < 0 )
			return 0;
		if ( (unsigned char)v7 <= 0xFu )
		{
			*v6 = (unsigned char)v7 | 0x80;
			++*totarea;
			if ( (_BYTE)v7 == 8 )
			{
				if ( DRLG_L3SpawnEdge(v5 + 1, y, totarea) == 1
				  || DRLG_L3SpawnEdge(v5 - 1, v4, totarea) == 1
				  || DRLG_L3SpawnEdge(v5, v4 + 1, totarea) == 1 )
				{
					return 1;
				}
				v8 = DRLG_L3SpawnEdge(v5, v4 - 1, totarea);
LABEL_24:
				if ( v8 == 1 )
					return 1;
				return 0;
			}
			v7 = (int *)(unsigned char)v7;
			totareaa = v7;
			if ( L3SpawnTbl2[(unsigned char)v7] & 8 )
			{
				if ( DRLG_L3Spawn(v5, y - 1, v3) == 1 )
					return 1;
				v7 = totareaa;
			}
			if ( L3SpawnTbl2[(_DWORD)v7] & 4 )
			{
				if ( DRLG_L3Spawn(v5, v4 + 1, v3) == 1 )
					return 1;
				v7 = totareaa;
			}
			if ( !(L3SpawnTbl2[(_DWORD)v7] & 2) )
				goto LABEL_18;
			if ( DRLG_L3Spawn(v5 + 1, v4, v3) != 1 )
			{
				v7 = totareaa;
LABEL_18:
				if ( L3SpawnTbl2[(_DWORD)v7] & 1 )
				{
					v8 = DRLG_L3Spawn(v5 - 1, v4, v3);
					goto LABEL_24;
				}
				return 0;
			}
			return 1;
		}
	}
	return 1;
}

//----- (0041189C) --------------------------------------------------------
int __fastcall DRLG_L3Spawn(int x, int y, int *totarea)
{
	int v3; // edi
	int v4; // esi
	char *v5; // eax
	unsigned char v6; // cl
	int v7; // ebx
	int result; // eax

	v3 = y;
	v4 = x;
	result = 1;
	if ( *totarea <= 40 && x >= 0 && y >= 0 && x < 40 && y < 40 )
	{
		v5 = &dungeon[x][y];
		v6 = *v5;
		if ( *v5 < 0
		  || v6 <= 0xFu
		  && ((v7 = v6, *v5 = v6 | 0x80, ++*totarea, !(L3SpawnTbl1[v6] & 8)) || DRLG_L3Spawn(v4, y - 1, totarea) != 1)
		  && (!(L3SpawnTbl1[v7] & 4) || DRLG_L3Spawn(v4, v3 + 1, totarea) != 1)
		  && (!(L3SpawnTbl1[v7] & 2) || DRLG_L3Spawn(v4 + 1, v3, totarea) != 1)
		  && (!(L3SpawnTbl1[v7] & 1) || DRLG_L3Spawn(v4 - 1, v3, totarea) != 1)
		  && ((L3SpawnTbl1[v7] & 0x80u) == 0 || DRLG_L3SpawnEdge(v4, v3 - 1, totarea) != 1)
		  && (!(L3SpawnTbl1[v7] & 0x40) || DRLG_L3SpawnEdge(v4, v3 + 1, totarea) != 1)
		  && (!(L3SpawnTbl1[v7] & 0x20) || DRLG_L3SpawnEdge(v4 + 1, v3, totarea) != 1)
		  && (!(L3SpawnTbl1[v7] & 0x10) || DRLG_L3SpawnEdge(v4 - 1, v3, totarea) != 1) )
		{
			result = 0;
		}
	}
	return result;
}

//----- (004119E0) --------------------------------------------------------
void __cdecl DRLG_L3PoolFix()
{
	signed int v0; // esi
	char *v1; // eax
	char *v2; // edi
	unsigned char v3; // cl
	char v4; // cl
	char v5; // cl
	char v6; // cl
	char v7; // cl
	char v8; // cl
	char v9; // al
	bool v10; // zf
	signed int v11; // [esp+10h] [ebp-4h]

	v0 = 0;
	do
	{
		v1 = &dungeon[-1][v0];
		v11 = 40;
		do
		{
			v2 = v1 + 40;
			if ( v1[40] == 8 )
			{
				v3 = *(v1 - 1);
				if ( v3 >= 0x19u && v3 <= 0x29u && (unsigned char)*v1 >= 0x19u && (unsigned char)*v1 <= 0x29u )
				{
					v4 = v1[1];
					if ( (unsigned char)v4 >= 0x19u && (unsigned char)v4 <= 0x29u )
					{
						v5 = v1[39];
						if ( (unsigned char)v5 >= 0x19u && (unsigned char)v5 <= 0x29u )
						{
							v6 = v1[41];
							if ( (unsigned char)v6 >= 0x19u && (unsigned char)v6 <= 0x29u )
							{
								v7 = v1[79];
								if ( (unsigned char)v7 >= 0x19u && (unsigned char)v7 <= 0x29u )
								{
									v8 = v1[80];
									if ( (unsigned char)v8 >= 0x19u && (unsigned char)v8 <= 0x29u )
									{
										v9 = v1[81];
										if ( (unsigned char)v9 >= 0x19u && (unsigned char)v9 <= 0x29u )
											*v2 = 33;
									}
								}
							}
						}
					}
				}
			}
			v10 = v11-- == 1;
			v1 = v2;
		}
		while ( !v10 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (00411A74) --------------------------------------------------------
bool __fastcall DRLG_L3PlaceMiniSet(char *miniset, int tmin, int tmax, int cx, int cy, bool set_view, int ldir)
{
	int v7; // ebx
	int v8; // esi
	int v9; // edi
	int v10; // edx
	int v11; // eax
	int v12; // ecx
	int v13; // esi
	signed int v14; // ebx
	int v15; // ecx
	int v16; // eax
	int v17; // ecx
	int v18; // eax
	int v19; // ecx
	int v20; // edi
	signed int i; // eax
	int v22; // ecx
	char v23; // dl
	int v24; // eax
	int v25; // edi
	char *v26; // edx
	char v27; // bl
	char *v29; // [esp+Ch] [ebp-24h]
	int v30; // [esp+10h] [ebp-20h]
	int v31; // [esp+14h] [ebp-1Ch]
	int v32; // [esp+18h] [ebp-18h]
	signed int v33; // [esp+1Ch] [ebp-14h]
	int v34; // [esp+20h] [ebp-10h]
	int v35; // [esp+24h] [ebp-Ch]
	int v36; // [esp+28h] [ebp-8h]
	int max; // [esp+2Ch] [ebp-4h]

	v7 = (unsigned char)miniset[1];
	v8 = tmin;
	v9 = (unsigned char)*miniset;
	v29 = miniset;
	v10 = tmax - tmin;
	v34 = (unsigned char)*miniset;
	v35 = (unsigned char)miniset[1];
	if ( v10 )
	{
		_LOBYTE(miniset) = 0;
		v30 = v8 + random((int)miniset, v10);
	}
	else
	{
		v30 = 1;
	}
	v31 = 0;
	if ( v30 <= 0 )
	{
		v13 = tmax;
	}
	else
	{
		max = 40 - v9;
		v36 = 40 - v7;
		do
		{
			_LOBYTE(miniset) = 0;
			v11 = random((int)miniset, max);
			_LOBYTE(v12) = 0;
			v13 = v11;
			v33 = 0;
			tmax = random(v12, v36);
			while ( 1 )
			{
				if ( v33 >= 200 )
					return 1;
				++v33;
				v14 = 1;
				if ( cx != -1 )
				{
					v15 = cx - v34;
					if ( v13 >= cx - v34 && v13 <= cx + 12 )
					{
						_LOBYTE(v15) = 0;
						v16 = random(v15, max);
						_LOBYTE(v17) = 0;
						v13 = v16;
						tmax = random(v17, v36);
						v14 = 0;
					}
				}
				if ( cy != -1 && tmax >= cy - v35 && tmax <= cy + 12 )
				{
					v18 = random(cy - v35, max);
					_LOBYTE(v19) = 0;
					v13 = v18;
					tmax = random(v19, v36);
					v14 = 0;
				}
				v20 = 0;
				for ( i = 2; v20 < v35; ++v20 )
				{
					if ( v14 != 1 )
						break;
					v32 = 0;
					if ( v34 > 0 )
					{
						v22 = tmax + v20 + 40 * v13;
						do
						{
							if ( v14 != 1 )
								break;
							v23 = v29[i];
							if ( v23 && dungeon[0][v22] != v23 )
								v14 = 0;
							if ( dflags[0][v22] )
								v14 = 0;
							++i;
							++v32;
							v22 += 40;
						}
						while ( v32 < v34 );
					}
				}
				v24 = 0;
				if ( v14 )
					break;
				if ( ++v13 == max )
				{
					v13 = 0;
					if ( ++tmax == v36 )
						tmax = 0;
				}
			}
			if ( v33 >= 200 )
				return 1;
			miniset = (char *)(v34 * v35 + 2);
			if ( v35 > 0 )
			{
				do
				{
					v25 = v34;
					if ( v34 > 0 )
					{
						v26 = &dungeon[v13][v24 + tmax];
						do
						{
							v27 = v29[(_DWORD)miniset];
							if ( v27 )
								*v26 = v27;
							++miniset;
							v26 += 40;
							--v25;
						}
						while ( v25 );
					}
					++v24;
				}
				while ( v24 < v35 );
			}
			++v31;
		}
		while ( v31 < v30 );
	}
	if ( set_view == 1 )
	{
		ViewX = 2 * v13 + 17;
		ViewY = 2 * tmax + 19;
	}
	if ( !ldir )
	{
		LvlViewX = 2 * v13 + 17;
		LvlViewY = 2 * tmax + 19;
	}
	return 0;
}
// 5CF320: using guessed type int LvlViewY;
// 5CF324: using guessed type int LvlViewX;

//----- (00411C83) --------------------------------------------------------
void __fastcall DRLG_L3PlaceRndSet(unsigned char *miniset, int rndper)
{
	unsigned char *v2; // ebx
	int v3; // ecx
	int v4; // eax
	char *v5; // ecx
	int v6; // esi
	signed int i; // edx
	int v8; // edi
	int v9; // eax
	unsigned char v10; // cl
	int v11; // edi
	unsigned char v12; // al
	char v13; // al
	int j; // edx
	int v15; // esi
	unsigned char *v16; // eax
	unsigned char v17; // cl
	bool v18; // zf
	int v19; // [esp+8h] [ebp-30h]
	int v20; // [esp+10h] [ebp-28h]
	char *v21; // [esp+14h] [ebp-24h]
	int v22; // [esp+18h] [ebp-20h]
	int v23; // [esp+1Ch] [ebp-1Ch]
	int v24; // [esp+20h] [ebp-18h]
	int v25; // [esp+24h] [ebp-14h]
	int v26; // [esp+28h] [ebp-10h]
	int v27; // [esp+2Ch] [ebp-Ch]
	int v28; // [esp+30h] [ebp-8h]
	signed int v29; // [esp+34h] [ebp-4h]

	v2 = miniset;
	v19 = rndper;
	v3 = miniset[1];
	v4 = 0;
	v23 = 40 - v3;
	v27 = *v2;
	v28 = v3;
	v24 = 0;
	if ( 40 - v3 > 0 )
	{
		v22 = 40 - *v2;
		v21 = dungeon[-1];
		while ( v22 <= 0 )
		{
LABEL_44:
			v4 = v24++ + 1;
			if ( v24 >= v23 )
				return;
		}
		v26 = 0;
		v20 = v22;
		v5 = &v21[v4];
		v25 = (int)&v21[v4];
		while ( 1 )
		{
			v6 = 0;
			v29 = 1;
			for ( i = 2; v6 < v28; ++v6 )
			{
				if ( v29 != 1 )
					break;
				v8 = 0;
				if ( v27 > 0 )
				{
					v9 = v24 + v6 + v26;
					do
					{
						if ( v29 != 1 )
							break;
						v10 = v2[i];
						if ( v10 && dungeon[0][v9] != v10 )
							v29 = 0;
						if ( dflags[0][v9] )
							v29 = 0;
						++i;
						++v8;
						v9 += 40;
					}
					while ( v8 < v27 );
					v5 = (char *)v25;
				}
			}
			v11 = v27 * v28 + 2;
			v12 = v2[v11];
			if ( v12 < 0x54u || v12 > 0x64u )
				goto LABEL_33;
			if ( v29 == 1 )
				break;
LABEL_43:
			v26 += 40;
			v5 += 40;
			v18 = v20-- == 1;
			v25 = (int)v5;
			if ( v18 )
				goto LABEL_44;
		}
		v13 = *v5;
		if ( (unsigned char)*v5 >= 0x54u && (unsigned char)v13 <= 0x64u )
			v29 = 0;
		if ( (unsigned char)v5[80] >= 0x54u && (unsigned char)v13 <= 0x64u )
			v29 = 0;
		if ( (unsigned char)v5[41] >= 0x54u && (unsigned char)v13 <= 0x64u )
			v29 = 0;
		if ( (unsigned char)v5[39] >= 0x54u && (unsigned char)v13 <= 0x64u )
			v29 = 0;
LABEL_33:
		if ( v29 == 1 )
		{
			_LOBYTE(v5) = 0;
			if ( random((int)v5, 100) < v19 )
			{
				for ( j = 0; j < v28; ++j )
				{
					v15 = v27;
					if ( v27 > 0 )
					{
						v16 = (unsigned char *)dungeon + j + v26 + v24;
						do
						{
							v17 = v2[v11];
							if ( v17 )
								*v16 = v17;
							++v11;
							v16 += 40;
							--v15;
						}
						while ( v15 );
					}
				}
			}
			v5 = (char *)v25;
		}
		goto LABEL_43;
	}
}

//----- (00411E0E) --------------------------------------------------------
void __cdecl DRLG_L3Wood()
{
	char *v0; // edi
	int v1; // edx
	_BYTE *v2; // eax
	int v3; // edx
	_BYTE *v4; // ebx
	int v5; // esi
	int v6; // esi
	int v7; // ebx
	int v8; // ebx
	signed int v9; // esi
	_BYTE *v10; // eax
	int v11; // esi
	int v12; // ebx
	int v13; // eax
	_BYTE *v14; // ecx
	int v15; // ecx
	int v16; // eax
	int v17; // esi
	int v18; // esi
	int v19; // eax
	int v20; // edi
	int v21; // esi
	int i; // edx
	int v23; // esi
	int v24; // edi
	signed int v25; // ecx
	int v26; // ebx
	char *v27; // esi
	int v28; // ecx
	int v29; // edi
	int v30; // ecx
	int v31; // edi
	int v32; // ebx
	int v33; // ebx
	char *v34; // esi
	signed int v35; // ecx
	int v36; // [esp+Ch] [ebp-14h]
	int v37; // [esp+10h] [ebp-10h]
	int v38; // [esp+10h] [ebp-10h]
	int v39; // [esp+10h] [ebp-10h]
	int v40; // [esp+10h] [ebp-10h]
	int v41; // [esp+10h] [ebp-10h]
	int x; // [esp+14h] [ebp-Ch]
	int xa; // [esp+14h] [ebp-Ch]
	signed int v44; // [esp+18h] [ebp-8h]
	signed int v45; // [esp+18h] [ebp-8h]
	int y; // [esp+1Ch] [ebp-4h]
	signed int ya; // [esp+1Ch] [ebp-4h]

	y = 0;
	do
	{
		x = 0;
		v44 = 1;
		v0 = (char *)dungeon + y;
		do
		{
			if ( *v0 == 10 && random(0, 2) )
			{
				v1 = v44 - 1;
				if ( *v0 == 10 )
				{
					v2 = (unsigned char *)v0;
					do
					{
						v2 += 40;
						++v1;
					}
					while ( *v2 == 10 );
				}
				v3 = v1 - 1;
				v37 = v3;
				if ( v3 - (v44 - 1) > 0 )
				{
					*v0 = 127;
					if ( v44 < v3 )
					{
						v4 = (unsigned char *)v0 + 40;
						v5 = v3 - v44;
						do
						{
							*v4 = random(0, 2) != 0 ? 126 : -127;
							v4 += 40;
							--v5;
						}
						while ( v5 );
					}
					dungeon[v37][y] = -128;
				}
			}
			if ( *v0 == 9 && random(0, 2) )
			{
				v6 = y;
				v7 = y;
				if ( *v0 == 9 )
				{
					do
						++v7;
					while ( dungeon[x][v7] == 9 );
				}
				v8 = v7 - 1;
				if ( v8 - y > 0 )
				{
					*v0 = 123;
					while ( ++v6 < v8 )
					{
						if ( random(0, 2) )
							dungeon[x][v6] = 121;
						else
							dungeon[x][v6] = 124;
					}
					dungeon[x][v8] = 122;
				}
			}
			if ( *v0 == 11 && v0[40] == 10 && v0[1] == 9 && random(0, 2) )
			{
				v9 = v44;
				*v0 = 125;
				if ( v0[40] == 10 )
				{
					v10 = (unsigned char *)v0 + 40;
					do
					{
						v10 += 40;
						++v9;
					}
					while ( *v10 == 10 );
				}
				v11 = v9 - 1;
				if ( v44 < v11 )
				{
					v38 = (int)(v0 + 40);
					v12 = v11 - v44;
					do
					{
						v13 = random(0, 2);
						v14 = (_BYTE *)v38;
						v38 += 40;
						--v12;
						*v14 = v13 != 0 ? 126 : -127;
					}
					while ( v12 );
				}
				v15 = 5 * v11;
				v16 = y + 1;
				v17 = v16;
				for ( *((_BYTE *)&dMonster[111][2 * v15 + 111] + v16 + 3) = -128; dungeon[x][v17] == 9; ++v17 )
					;
				v18 = v17 - 1;
				v39 = y + 1;
				if ( v16 < v18 )
				{
					do
					{
						if ( random(0, 2) )
							dungeon[x][v39] = 121;
						else
							dungeon[x][v39] = 124;
						++v39;
					}
					while ( v39 < v18 );
				}
				dungeon[x][v18] = 122;
			}
			++v44;
			++x;
			v0 += 40;
		}
		while ( v44 - 1 < 39 );
		++y;
	}
	while ( y < 39 );
	ya = 0;
	do
	{
		xa = 0;
		v45 = 0;
		do
		{
			if ( dungeon[v45][ya] != 7 )
				goto LABEL_112;
			if ( random(0, 1) )
				goto LABEL_112;
			_LOBYTE(v19) = SkipThemeRoom(xa, ya);
			if ( !v19 )
				goto LABEL_112;
			v36 = random(0, 2);
			if ( !v36 )
			{
				v20 = ya;
				v21 = ya;
				for ( i = ya; WoodVertU(xa, i); i = v21 )
					--v21;
				v23 = v21 + 1;
				while ( WoodVertD(xa, v20) )
					++v20;
				v24 = v20 - 1;
				v25 = 1;
				if ( dungeon[v45][v23] == 7 )
					v25 = 0;
				if ( dungeon[v45][v24] == 7 )
					v25 = 0;
				if ( v24 - v23 <= 1 )
					goto LABEL_112;
				if ( !v25 )
					goto LABEL_112;
				v40 = random(0, v24 - v23 - 1) + v23 + 1;
				v26 = v23;
				if ( v23 > v24 )
					goto LABEL_112;
				do
				{
					if ( v26 != v40 )
					{
						v27 = &dungeon[v45][v26];
						if ( *v27 == 7 )
							*v27 = random(0, 2) != 0 ? -121 : -119;
						if ( *v27 == 10 )
							*v27 = -125;
						if ( *v27 == 126 )
							*v27 = -123;
						if ( *v27 == -127 )
							*v27 = -123;
						if ( *v27 == 2 )
							*v27 = -117;
						if ( *v27 == -122 )
							*v27 = -118;
						if ( *v27 == -120 )
							*v27 = -118;
					}
					++v26;
				}
				while ( v26 <= v24 );
			}
			if ( v36 == 1 )
			{
				v28 = xa;
				v29 = xa;
				while ( WoodHorizL(v28, ya) )
					v28 = --v29;
				v30 = xa;
				v31 = v29 + 1;
				v32 = xa;
				while ( WoodHorizR(v30, ya) )
					v30 = ++v32;
				v33 = v32 - 1;
				v34 = &dungeon[v31][ya];
				v35 = 1;
				if ( *v34 == 7 )
					v35 = 0;
				if ( dungeon[v33][ya] == 7 )
					v35 = 0;
				if ( v33 - v31 > 1 && v35 )
				{
					v41 = random(0, v33 - v31 - 1) + v31 + 1;
					while ( 1 )
					{
						if ( v31 > v33 )
							break;
						if ( v31 != v41 )
						{
							if ( *v34 == 7 )
							{
								if ( random(0, 2) )
								{
									*v34 = -122;
									goto LABEL_110;
								}
								*v34 = -120;
							}
							if ( *v34 == 9 )
								*v34 = -126;
							if ( *v34 == 121 )
								*v34 = -124;
							if ( *v34 == 124 )
								*v34 = -124;
							if ( *v34 == 4 )
								*v34 = -116;
							if ( *v34 == -121 )
								*v34 = -118;
							if ( *v34 == -119 )
								*v34 = -118;
						}
LABEL_110:
						++v31;
						v34 += 40;
					}
				}
			}
LABEL_112:
			++v45;
			++xa;
		}
		while ( v45 < 40 );
		++ya;
	}
	while ( ya < 40 );
	AddFenceDoors();
	FenceDoorFix();
}

//----- (0041223E) --------------------------------------------------------
int __fastcall WoodVertU(int i, int y)
{
	int v2; // eax
	char v3; // cl
	char *v4; // eax
	unsigned char v5; // cl
	char v6; // al
	int result; // eax

	v2 = i;
	v3 = dungeon[i + 1][y];
	result = 0;
	if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u )
	{
		v4 = &dungeon[v2][y];
		v5 = *(v4 - 40);
		if ( v5 > 0x98u || v5 < 0x82u )
		{
			v6 = *v4;
			if ( v6 == 7 || v6 == 10 || v6 == 126 || v6 == -127 || v6 == -122 || v6 == -120 )
				result = 1;
		}
	}
	return result;
}

//----- (0041228A) --------------------------------------------------------
int __fastcall WoodVertD(int i, int y)
{
	int v2; // eax
	char v3; // cl
	char *v4; // eax
	unsigned char v5; // cl
	char v6; // al
	int result; // eax

	v2 = i;
	v3 = dungeon[i + 1][y];
	result = 0;
	if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u )
	{
		v4 = &dungeon[v2][y];
		v5 = *(v4 - 40);
		if ( v5 > 0x98u || v5 < 0x82u )
		{
			v6 = *v4;
			if ( v6 == 7 || v6 == 2 || v6 == -122 || v6 == -120 )
				result = 1;
		}
	}
	return result;
}

//----- (004122CE) --------------------------------------------------------
int __fastcall WoodHorizL(int x, int j)
{
	int v2; // eax
	char v3; // cl
	char *v4; // eax
	unsigned char v5; // cl
	char v6; // al
	int result; // eax

	v2 = x;
	v3 = dungeon[x][j + 1];
	result = 0;
	if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u )
	{
		v4 = &dungeon[v2][j];
		v5 = *(v4 - 1);
		if ( v5 > 0x98u || v5 < 0x82u )
		{
			v6 = *v4;
			if ( v6 == 7 || v6 == 9 || v6 == 121 || v6 == 124 || v6 == -121 || v6 == -119 )
				result = 1;
		}
	}
	return result;
}

//----- (0041231A) --------------------------------------------------------
int __fastcall WoodHorizR(int x, int j)
{
	int v2; // eax
	char v3; // cl
	char *v4; // eax
	unsigned char v5; // cl
	char v6; // al
	int result; // eax

	v2 = x;
	v3 = dungeon[x][j + 1];
	result = 0;
	if ( (unsigned char)v3 > 0x98u || (unsigned char)v3 < 0x82u )
	{
		v4 = &dungeon[v2][j];
		v5 = *(v4 - 1);
		if ( v5 > 0x98u || v5 < 0x82u )
		{
			v6 = *v4;
			if ( v6 == 7 || v6 == 4 || v6 == -121 || v6 == -119 )
				result = 1;
		}
	}
	return result;
}

//----- (0041235E) --------------------------------------------------------
void __cdecl DRLG_L3Pass3()
{
	int v0; // eax
	int *v1; // esi
	int *v2; // eax
	signed int v3; // ecx
	signed int v4; // ebx
	int *v5; // ecx
	unsigned char *v6; // edi
	unsigned short *v7; // esi
	unsigned short v8; // ax
	int v9; // eax
	signed int v10; // [esp+Ch] [ebp-1Ch]
	int *v11; // [esp+10h] [ebp-18h]
	int v12; // [esp+14h] [ebp-14h]
	int v13; // [esp+18h] [ebp-10h]
	int v14; // [esp+18h] [ebp-10h]
	int v15; // [esp+1Ch] [ebp-Ch]
	int v16; // [esp+1Ch] [ebp-Ch]
	int v17; // [esp+20h] [ebp-8h]
	int v18; // [esp+20h] [ebp-8h]
	int v19; // [esp+24h] [ebp-4h]
	int v20; // [esp+24h] [ebp-4h]

	v0 = *((unsigned short *)pMegaTiles + 28) + 1;
	v19 = *((unsigned short *)pMegaTiles + 28) + 1;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 29);
	v17 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 30);
	v15 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 31);
	v13 = v0 + 1;
	v1 = dPiece[1];
	do
	{
		v2 = v1;
		v3 = 56;
		do
		{
			*(v2 - 112) = v19;
			*v2 = v17;
			*(v2 - 111) = v15;
			v2[1] = v13;
			v2 += 224;
			--v3;
		}
		while ( v3 );
		v1 += 2;
	}
	while ( (signed int)v1 < (signed int)dPiece[2] );
	v4 = 0;
	v11 = &dPiece[17][16];
	do
	{
		v5 = v11;
		v6 = (unsigned char *)dungeon + v4;
		v10 = 40;
		do
		{
			v12 = *v6 - 1;
			if ( v12 < 0 )
			{
				v20 = 0;
				v18 = 0;
				v16 = 0;
				v14 = 0;
			}
			else
			{
				v7 = (unsigned short *)((char *)pMegaTiles + 8 * v12);
				v8 = *v7;
				++v7;
				v9 = v8 + 1;
				v20 = v9;
				_LOWORD(v9) = *v7;
				++v7;
				v18 = ++v9;
				_LOWORD(v9) = *v7;
				v16 = ++v9;
				_LOWORD(v9) = v7[1];
				v14 = v9 + 1;
			}
			v6 += 40;
			*(v5 - 112) = v20;
			*v5 = v18;
			*(v5 - 111) = v16;
			v5[1] = v14;
			v5 += 224;
			--v10;
		}
		while ( v10 );
		v11 += 2;
		++v4;
	}
	while ( v4 < 40 );
}

//----- (00412466) --------------------------------------------------------
void __fastcall LoadL3Dungeon(char *sFileName, int vx, int vy)
{
	char *v3; // esi
	unsigned char *v4; // eax
	char *v5; // esi
	int v6; // edi
	int v7; // ecx
	_BYTE *v8; // eax
	_BYTE *v9; // edx
	int v10; // ebx
	signed int v11; // ecx
	_BYTE *v12; // eax
	signed int v13; // edx
	int v14; // edi
	signed int v15; // eax
	int v16; // [esp+Ch] [ebp-8h]
	signed int *v17; // [esp+Ch] [ebp-8h]
	int v18; // [esp+10h] [ebp-4h]
	int (*v19)[112]; // [esp+10h] [ebp-4h]

	v3 = sFileName;
	InitL3Dungeon();
	dminx = 16;
	dminy = 16;
	dmaxx = 96;
	dmaxy = 96;
	DRLG_InitTrans();
	v4 = LoadFileInMem(v3, 0);
	v5 = (char *)v4;
	v18 = 0;
	v6 = *v4;
	v4 += 2;
	v7 = *v4;
	v8 = v4 + 2;
	if ( v7 > 0 )
	{
		do
		{
			if ( v6 > 0 )
			{
				v16 = v6;
				v9 = (unsigned char *)dungeon + v18;
				do
				{
					if ( *v8 )
						*v9 = *v8;
					else
						*v9 = 7;
					v9 += 40;
					v8 += 2;
					--v16;
				}
				while ( v16 );
			}
			++v18;
		}
		while ( v18 < v7 );
	}
	v10 = 0;
	v11 = 0;
	do
	{
		v12 = (unsigned char *)dungeon + v11;
		v13 = 40;
		do
		{
			if ( !*v12 )
				*v12 = 8;
			v12 += 40;
			--v13;
		}
		while ( v13 );
		++v11;
	}
	while ( v11 < 40 );
	abyssx = 112;
	DRLG_L3Pass3();
	DRLG_Init_Globals();
	ViewX = 31;
	ViewY = 83;
	SetMapMonsters(v5, 0, 0);
	SetMapObjects(v5, 0, 0);
	v19 = dPiece;
	do
	{
		v14 = 0;
		v17 = (signed int *)v19;
		do
		{
			v15 = *v17;
			if ( *v17 >= 56 && v15 <= 147 || v15 >= 154 && v15 <= 161 || v15 == 150 || v15 == 152 )
				DoLighting(v14, v10, 7, -1);
			v17 += 112;
			++v14;
		}
		while ( v14 < 112 );
		v19 = (int (*)[112])((char *)v19 + 4);
		++v10;
	}
	while ( (signed int)v19 < (signed int)dPiece[1] );
	mem_free_dbg(v5);
}
// 52837C: using guessed type int abyssx;
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;

//----- (004125B0) --------------------------------------------------------
void __fastcall LoadPreL3Dungeon(char *sFileName, int vx, int vy)
{
	char *v3; // esi
	unsigned char *v4; // eax
	unsigned char *v5; // esi
	int v6; // edx
	int v7; // edi
	_BYTE *v8; // eax
	_BYTE *v9; // ecx
	signed int v10; // ecx
	_BYTE *v11; // eax
	signed int v12; // edx
	int v13; // [esp+8h] [ebp-8h]
	int v14; // [esp+Ch] [ebp-4h]

	v3 = sFileName;
	InitL3Dungeon();
	DRLG_InitTrans();
	v4 = LoadFileInMem(v3, 0);
	v5 = v4;
	v14 = 0;
	v6 = *v4;
	v4 += 2;
	v7 = *v4;
	v8 = v4 + 2;
	if ( v7 > 0 )
	{
		do
		{
			if ( v6 > 0 )
			{
				v13 = v6;
				v9 = (unsigned char *)dungeon + v14;
				do
				{
					if ( *v8 )
						*v9 = *v8;
					else
						*v9 = 7;
					v9 += 40;
					v8 += 2;
					--v13;
				}
				while ( v13 );
			}
			++v14;
		}
		while ( v14 < v7 );
	}
	v10 = 0;
	do
	{
		v11 = (unsigned char *)dungeon + v10;
		v12 = 40;
		do
		{
			if ( !*v11 )
				*v11 = 8;
			v11 += 40;
			--v12;
		}
		while ( v12 );
		++v10;
	}
	while ( v10 < 40 );
	memcpy(pdungeon, dungeon, 0x640u);
	mem_free_dbg(v5);
}

//----- (00412655) --------------------------------------------------------
void __cdecl DRLG_LoadL4SP()
{
	int v0; // eax

	setloadflag_2 = 0;
	_LOBYTE(v0) = QuestStatus(11);
	if ( v0 )
	{
		pSetPiece_2 = (char *)LoadFileInMem("Levels\\L4Data\\Warlord.DUN", 0);
		setloadflag_2 = 1;
	}
	if ( currlevel == 15 && gbMaxPlayers != 1 )
	{
		pSetPiece_2 = (char *)LoadFileInMem("Levels\\L4Data\\Vile1.DUN", 0);
		setloadflag_2 = 1;
	}
}
// 5B50D8: using guessed type int setloadflag_2;
// 679660: using guessed type char gbMaxPlayers;

//----- (004126AD) --------------------------------------------------------
void __cdecl DRLG_FreeL4SP()
{
	char *v0; // ecx

	v0 = pSetPiece_2;
	pSetPiece_2 = 0;
	mem_free_dbg(v0);
}

//----- (004126BF) --------------------------------------------------------
void __fastcall DRLG_L4SetSPRoom(int rx1, int ry1)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax
	char v5; // bl
	int v6; // [esp+8h] [ebp-Ch]
	char *v7; // [esp+Ch] [ebp-8h]
	int v8; // [esp+10h] [ebp-4h]

	v8 = 0;
	v2 = (unsigned char)pSetPiece_2[2];
	v3 = (unsigned char)*pSetPiece_2;
	setpc_x = rx1;
	setpc_y = ry1;
	setpc_w = v3;
	setpc_h = v2;
	v7 = pSetPiece_2 + 4;
	if ( v2 > 0 )
	{
		do
		{
			if ( v3 > 0 )
			{
				v6 = v3;
				v4 = ry1 + v8 + 40 * rx1;
				do
				{
					v5 = *v7;
					if ( *v7 )
					{
						dflags[0][v4] |= 0x80u;
						dungeon[0][v4] = v5;
					}
					else
					{
						dungeon[0][v4] = 6;
					}
					v7 += 2;
					v4 += 40;
					--v6;
				}
				while ( v6 );
			}
			++v8;
		}
		while ( v8 < v2 );
	}
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00412744) --------------------------------------------------------
void __cdecl L4SaveQuads()
{
	char *v0; // esi
	char *v1; // edx
	char *v2; // edi
	char *v3; // eax
	char *v4; // ecx
	char *v5; // ebx
	signed int v6; // [esp+Ch] [ebp-14h]
	signed int v7; // [esp+10h] [ebp-10h]
	char *v8; // [esp+14h] [ebp-Ch]
	char *v9; // [esp+18h] [ebp-8h]
	char *v10; // [esp+1Ch] [ebp-4h]

	v0 = &dflags[39][l4holdy - 40 * l4holdx];
	v1 = &dflags[39][-l4holdy + 39 + -40 * l4holdx];
	v9 = &dflags[l4holdx][l4holdy];
	v8 = &dflags[0][40 * l4holdx - l4holdy + 39];
	v6 = 14;
	do
	{
		v2 = v1;
		v10 = v8;
		v3 = v9;
		v4 = v0;
		v7 = 14;
		do
		{
			v5 = v10;
			v10 += 40;
			*v3 = 1;
			*v4 = 1;
			*v5 = 1;
			*v2 = 1;
			v4 -= 40;
			v2 -= 40;
			v3 += 40;
			--v7;
		}
		while ( v7 );
		++v9;
		--v8;
		--v1;
		++v0;
		--v6;
	}
	while ( v6 );
}
// 528A34: using guessed type int l4holdx;
// 528A38: using guessed type int l4holdy;

//----- (004127D3) --------------------------------------------------------
void __fastcall DRLG_L4SetRoom(unsigned char *pSetPiece, int rx1, int ry1)
{
	int v3; // ebx
	int v4; // edi
	unsigned char *v5; // esi
	int v6; // eax
	char v7; // cl
	int v8; // [esp+Ch] [ebp-8h]
	int v9; // [esp+10h] [ebp-4h]

	v3 = *pSetPiece;
	v4 = 0;
	v8 = pSetPiece[2];
	v5 = pSetPiece + 4;
	if ( v8 > 0 )
	{
		do
		{
			if ( v3 > 0 )
			{
				v9 = v3;
				v6 = ry1 + v4 + 40 * rx1;
				do
				{
					v7 = *v5;
					if ( *v5 )
					{
						dflags[0][v6] |= 0x80u;
						dungeon[0][v6] = v7;
					}
					else
					{
						dungeon[0][v6] = 6;
					}
					v6 += 40;
					v5 += 2;
					--v9;
				}
				while ( v9 );
			}
			++v4;
		}
		while ( v4 < v8 );
	}
}

//----- (00412831) --------------------------------------------------------
void __fastcall DRLG_LoadDiabQuads(char preflag)
{
	int v1; // esi
	unsigned char *v2; // edi
	char *v3; // ecx
	unsigned char *v4; // edi
	char *v5; // ecx
	unsigned char *v6; // edi
	char *v7; // ecx
	unsigned char *v8; // esi

	v1 = preflag;
	v2 = LoadFileInMem("Levels\\L4Data\\diab1.DUN", 0);
	diabquad1x = l4holdx + 4;
	diabquad1y = l4holdy + 4;
	DRLG_L4SetRoom(v2, l4holdx + 4, l4holdy + 4);
	mem_free_dbg(v2);
	v3 = "Levels\\L4Data\\diab2b.DUN";
	if ( !v1 )
		v3 = "Levels\\L4Data\\diab2a.DUN";
	v4 = LoadFileInMem(v3, 0);
	diabquad2y = l4holdy + 1;
	diabquad2x = 27 - l4holdx;
	DRLG_L4SetRoom(v4, 27 - l4holdx, l4holdy + 1);
	mem_free_dbg(v4);
	v5 = "Levels\\L4Data\\diab3b.DUN";
	if ( !v1 )
		v5 = "Levels\\L4Data\\diab3a.DUN";
	v6 = LoadFileInMem(v5, 0);
	diabquad3x = l4holdx + 1;
	diabquad3y = 27 - l4holdy;
	DRLG_L4SetRoom(v6, l4holdx + 1, 27 - l4holdy);
	mem_free_dbg(v6);
	v7 = "Levels\\L4Data\\diab4b.DUN";
	if ( !v1 )
		v7 = "Levels\\L4Data\\diab4a.DUN";
	v8 = LoadFileInMem(v7, 0);
	diabquad4y = 28 - l4holdy;
	diabquad4x = 28 - l4holdx;
	DRLG_L4SetRoom(v8, 28 - l4holdx, 28 - l4holdy);
	mem_free_dbg(v8);
}
// 5289C4: using guessed type int diabquad1x;
// 5289C8: using guessed type int diabquad1y;
// 528A34: using guessed type int l4holdx;
// 528A38: using guessed type int l4holdy;

//----- (00412933) --------------------------------------------------------
unsigned char __fastcall IsDURWall(char d)
{
	unsigned char result; // al

	if ( d == 25 || d == 28 )
		result = 1;
	else
		result = d == 23;
	return result;
}

//----- (00412948) --------------------------------------------------------
unsigned char __fastcall IsDLLWall(char dd)
{
	unsigned char result; // al

	if ( dd == 27 || dd == 26 )
		result = 1;
	else
		result = dd == 22;
	return result;
}

//----- (0041295D) --------------------------------------------------------
void __cdecl L4FixRim()
{
	char (*v0)[20]; // eax

	v0 = dung;
	do
	{
		*(_BYTE *)v0 = 0;
		++v0;
	}
	while ( (signed int)v0 < (signed int)&dword_52A4DC );
	*(_DWORD *)&dung[0][0] = 0;
	*(_DWORD *)&dung[0][4] = 0;
	*(_DWORD *)&dung[0][8] = 0;
	*(_DWORD *)&dung[0][12] = 0;
	*(_DWORD *)&dung[0][16] = 0;
}
// 52A4DC: using guessed type int dword_52A4DC;

//----- (0041297B) --------------------------------------------------------
void __cdecl DRLG_L4GeneralFix()
{
	signed int v0; // ecx
	char *v1; // eax
	signed int v2; // esi

	v0 = 0;
	do
	{
		v1 = (char *)dungeon + v0;
		v2 = 39;
		do
		{
			if ( (*v1 == 24 || *v1 == 122) && v1[40] == 2 && v1[1] == 5 )
				*v1 = 17;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 39 );
}

//----- (004129B0) --------------------------------------------------------
void __fastcall CreateL4Dungeon(int seed, int entry)
{
	int v2; // esi

	v2 = entry;
	SetRndSeed(seed);
	dminx = 16;
	dminy = 16;
	dmaxx = 96;
	dmaxy = 96;
	ViewX = 40;
	ViewY = 40;
	DRLG_InitSetPC();
	DRLG_LoadL4SP();
	DRLG_L4(v2);
	DRLG_L4Pass3();
	DRLG_FreeL4SP();
	DRLG_SetPC();
}
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;

//----- (00412A00) --------------------------------------------------------
void __fastcall DRLG_L4(int entry)
{
	signed int v1; // ebp
	int v2; // eax
	int v3; // edx
	char *v4; // edi
	char v5; // bp
	unsigned int v6; // ecx
	char *v7; // edi
	int v8; // ecx
	int v9; // eax
	int v10; // eax
	unsigned char *v11; // ecx
	unsigned char *v12; // ecx
	int v13; // eax
	signed int v14; // eax
	signed int v15; // ecx
	int v16; // ebx
	int v17; // edi
	char *v18; // ebp
	signed int v19; // ecx
	signed int v20; // eax
	signed int v21; // esi
	int v22; // [esp-8h] [ebp-20h]
	int v23; // [esp+10h] [ebp-8h]
	int v24; // [esp+14h] [ebp-4h]

	v1 = 0;
	v23 = entry;
	do
	{
		DRLG_InitTrans();
		do
		{
			InitL4Dungeon();
			L4firstRoom();
			L4FixRim();
		}
		while ( GetArea() < 173 );
		uShape();
		L4makeDungeon();
		L4makeDmt();
		L4tileFix();
		if ( currlevel == 16 )
			L4SaveQuads();
		_LOBYTE(v2) = QuestStatus(11);
		if ( (v2 || currlevel == quests[15]._qlevel && gbMaxPlayers != 1) && SP4x1 < SP4x2 )
		{
			v3 = SP4x1;
			v24 = SP4x2 - SP4x1;
			do
			{
				if ( SP4y1 < SP4y2 )
				{
					v4 = &dflags[v3][SP4y1];
					v5 = SP4y2 - SP4y1;
					v6 = (unsigned int)(SP4y2 - SP4y1) >> 2;
					memset(v4, 1u, 4 * v6);
					v7 = &v4[4 * v6];
					v8 = v5 & 3;
					v1 = 0;
					memset(v7, 1, v8);
				}
				++v3;
				--v24;
			}
			while ( v24 );
		}
		L4AddWall();
		DRLG_L4FloodTVal();
		DRLG_L4TransFix();
		if ( setloadflag_2 )
			DRLG_L4SetSPRoom(SP4x1, SP4y1);
		if ( currlevel == 16 )
			DRLG_LoadDiabQuads(1);
		_LOBYTE(v9) = QuestStatus(11);
		if ( !v9 )
		{
			if ( currlevel == 15 )
			{
				if ( !v23 )
				{
					_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0);
					if ( v10 )
					{
						if ( gbMaxPlayers != 1 || (v11 = L4PENTA, quests[5]._qactive == 2) )
							v11 = L4PENTA2;
						_LOBYTE(v10) = DRLG_L4PlaceMiniSet(v11, 1, 1, -1, -1, 0, 1);
					}
					goto LABEL_35;
				}
				_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0);
				if ( v10 )
				{
					if ( gbMaxPlayers != 1 || (v12 = L4PENTA, quests[5]._qactive == 2) )
						v12 = L4PENTA2;
					_LOBYTE(v10) = DRLG_L4PlaceMiniSet(v12, 1, 1, -1, -1, 1, 1);
				}
			}
			else
			{
				if ( !v23 )
				{
					_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0);
					if ( v10 )
					{
						if ( currlevel != 16 )
							_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1);
						goto LABEL_31;
					}
LABEL_35:
					++ViewX;
					continue;
				}
				_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0);
				if ( v23 != 1 )
				{
					if ( v10 )
					{
						if ( currlevel != 16 )
							_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 0, 1);
LABEL_46:
						if ( v10 )
						{
							if ( currlevel == 13 )
							{
								v22 = 1;
LABEL_34:
								_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, v22, 6);
								goto LABEL_35;
							}
						}
					}
					goto LABEL_35;
				}
				if ( v10 )
				{
					if ( currlevel != 16 )
						_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, 1, 1);
					if ( v10 && currlevel == 13 )
						_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6);
				}
			}
			++ViewY;
			continue;
		}
		if ( !v23 )
		{
			_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 1, 0);
LABEL_31:
			if ( !v10 || currlevel != 13 )
				goto LABEL_35;
			v22 = 0;
			goto LABEL_34;
		}
		_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, 0, 0);
		if ( v23 != 1 )
			goto LABEL_46;
		if ( v10 && currlevel == 13 )
			_LOBYTE(v10) = DRLG_L4PlaceMiniSet(L4TWARP, 1, 1, -1, -1, 0, 6);
		ViewX = 2 * setpc_x + 22;
		ViewY = 2 * setpc_y + 22;
	}
	while ( !v10 );
	DRLG_L4GeneralFix();
	if ( currlevel != 16 )
		DRLG_PlaceThemeRooms(7, 10, 6, 8, 1);
	DRLG_L4Shadows();
	DRLG_L4Corners();
	DRLG_L4Subs();
	DRLG_Init_Globals();
	_LOBYTE(v13) = QuestStatus(11);
	if ( v13 )
	{
		do
		{
			v14 = v1;
			v15 = 40;
			do
			{
				pdungeon[0][v14] = dungeon[0][v14];
				v14 += 40;
				--v15;
			}
			while ( v15 );
			++v1;
		}
		while ( v1 < 40 );
	}
	DRLG_CheckQuests(SP4x1, SP4y1);
	if ( currlevel == 15 )
	{
		v16 = -1;
		do
		{
			v17 = -1;
			v18 = &dungeon[0][v16 + 1];
			do
			{
				if ( *v18 == 98 )
					Make_SetPC(v17, v16, 5, 5);
				if ( *v18 == 107 )
					Make_SetPC(v17, v16, 5, 5);
				v18 += 40;
				++v17;
			}
			while ( v17 + 1 < 40 );
			++v16;
		}
		while ( v16 < 39 );
	}
	if ( currlevel == 16 )
	{
		v19 = 0;
		do
		{
			v20 = v19;
			v21 = 40;
			do
			{
				pdungeon[0][v20] = dungeon[0][v20];
				v20 += 40;
				--v21;
			}
			while ( v21 );
			++v19;
		}
		while ( v19 < 40 );
		DRLG_LoadDiabQuads(0);
	}
}
// 528A40: using guessed type int SP4x2;
// 528A48: using guessed type int SP4y2;
// 5B50D8: using guessed type int setloadflag_2;
// 679660: using guessed type char gbMaxPlayers;

//----- (00412DDD) --------------------------------------------------------
void __cdecl DRLG_L4Shadows()
{
	signed int v0; // esi
	char *v1; // eax
	signed int v2; // edi
	char v3; // dl
	signed int v4; // ecx

	v0 = 1;
	do
	{
		v1 = &dungeon[1][v0];
		v2 = 39;
		do
		{
			v3 = *v1;
			v4 = 0;
			if ( *v1 == 3 )
				v4 = 1;
			if ( v3 == 4 )
				v4 = 1;
			if ( v3 == 8 )
				v4 = 1;
			if ( v3 == 15 )
				v4 = 1;
			if ( v4 )
			{
				if ( *(v1 - 40) == 6 )
					*(v1 - 40) = 47;
				if ( *(v1 - 41) == 6 )
					*(v1 - 41) = 48;
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (00412E34) --------------------------------------------------------
void __cdecl InitL4Dungeon()
{
	signed int v0; // edx
	signed int v1; // eax
	signed int v2; // ecx

	memset(dung, 0, 0x190u);
	memset(L4dungeon, 0, 0x1900u);
	v0 = 0;
	do
	{
		v1 = v0;
		v2 = 40;
		do
		{
			dflags[0][v1] = 0;
			dungeon[0][v1] = 30;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (00412E7B) --------------------------------------------------------
void __cdecl L4makeDmt()
{
	signed int v0; // ecx
	char (*v1)[40]; // ebp
	char (*v2)[40]; // esi
	char *v3; // eax
	signed int v4; // edi
	int v5; // edx
	int v6; // ebx

	v0 = 1;
	v1 = dungeon;
	do
	{
		v2 = v1;
		v3 = &L4dungeon[1][v0 + 1];
		v4 = 39;
		do
		{
			v5 = (unsigned char)v3[80];
			v6 = (unsigned char)*v3;
			v3 += 160;
			*(_BYTE *)v2 = L4ConvTbl[2 * ((unsigned char)*(v3 - 81) + 2 * (v6 + 2 * v5))
								   + (unsigned char)*(v3 - 161)];
			++v2;
			--v4;
		}
		while ( v4 );
		v1 = (char (*)[40])((char *)v1 + 1);
		v0 += 2;
	}
	while ( v0 <= 77 );
}

//----- (00412ECB) --------------------------------------------------------
void __cdecl L4AddWall()
{
	int v0; // edi
	int v1; // esi
	int v2; // ebx
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // eax
	int v10; // eax
	int v11; // eax
	int v12; // eax
	int v13; // eax
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // eax

	v0 = 0;
	do
	{
		v1 = 0;
		v2 = v0;
		do
		{
			if ( !dflags[0][v2] )
			{
				if ( dungeon[0][v2] == 10 && random(0, 100) < 100 )
				{
					v3 = L4HWallOk(v1, v0);
					if ( v3 != -1 )
						L4HorizWall(v1, v0, v3);
				}
				if ( dungeon[0][v2] == 12 && random(0, 100) < 100 )
				{
					v4 = L4HWallOk(v1, v0);
					if ( v4 != -1 )
						L4HorizWall(v1, v0, v4);
				}
				if ( dungeon[0][v2] == 13 && random(0, 100) < 100 )
				{
					v5 = L4HWallOk(v1, v0);
					if ( v5 != -1 )
						L4HorizWall(v1, v0, v5);
				}
				if ( dungeon[0][v2] == 15 && random(0, 100) < 100 )
				{
					v6 = L4HWallOk(v1, v0);
					if ( v6 != -1 )
						L4HorizWall(v1, v0, v6);
				}
				if ( dungeon[0][v2] == 16 && random(0, 100) < 100 )
				{
					v7 = L4HWallOk(v1, v0);
					if ( v7 != -1 )
						L4HorizWall(v1, v0, v7);
				}
				if ( dungeon[0][v2] == 21 && random(0, 100) < 100 )
				{
					v8 = L4HWallOk(v1, v0);
					if ( v8 != -1 )
						L4HorizWall(v1, v0, v8);
				}
				if ( dungeon[0][v2] == 22 && random(0, 100) < 100 )
				{
					v9 = L4HWallOk(v1, v0);
					if ( v9 != -1 )
						L4HorizWall(v1, v0, v9);
				}
				if ( dungeon[0][v2] == 8 && random(0, 100) < 100 )
				{
					v10 = L4VWallOk(v1, v0);
					if ( v10 != -1 )
						L4VertWall(v1, v0, v10);
				}
				if ( dungeon[0][v2] == 9 && random(0, 100) < 100 )
				{
					v11 = L4VWallOk(v1, v0);
					if ( v11 != -1 )
						L4VertWall(v1, v0, v11);
				}
				if ( dungeon[0][v2] == 11 && random(0, 100) < 100 )
				{
					v12 = L4VWallOk(v1, v0);
					if ( v12 != -1 )
						L4VertWall(v1, v0, v12);
				}
				if ( dungeon[0][v2] == 14 && random(0, 100) < 100 )
				{
					v13 = L4VWallOk(v1, v0);
					if ( v13 != -1 )
						L4VertWall(v1, v0, v13);
				}
				if ( dungeon[0][v2] == 15 && random(0, 100) < 100 )
				{
					v14 = L4VWallOk(v1, v0);
					if ( v14 != -1 )
						L4VertWall(v1, v0, v14);
				}
				if ( dungeon[0][v2] == 16 && random(0, 100) < 100 )
				{
					v15 = L4VWallOk(v1, v0);
					if ( v15 != -1 )
						L4VertWall(v1, v0, v15);
				}
				if ( dungeon[0][v2] == 21 && random(0, 100) < 100 )
				{
					v16 = L4VWallOk(v1, v0);
					if ( v16 != -1 )
						L4VertWall(v1, v0, v16);
				}
				if ( dungeon[0][v2] == 23 && random(0, 100) < 100 )
				{
					v17 = L4VWallOk(v1, v0);
					if ( v17 != -1 )
						L4VertWall(v1, v0, v17);
				}
			}
			++v1;
			v2 += 40;
		}
		while ( v1 < 40 );
		++v0;
	}
	while ( v0 < 40 );
}

//----- (004131C2) --------------------------------------------------------
int __fastcall L4HWallOk(int i, int j)
{
	int v2; // esi
	int v3; // edi
	char *v4; // ebx
	int result; // eax
	signed int v6; // esi
	char v7; // dl
	int v8; // [esp+8h] [ebp-4h]

	v2 = 8 * (5 * i + 5);
	v8 = 1;
	if ( dungeon[0][v2 + j] == 6 )
	{
		v3 = 8 * (5 * i + 5);
		v4 = &dungeon[i + 1][j];
		do
		{
			if ( dflags[0][v3 + j] )
				break;
			if ( *((_BYTE *)&dMonster[111][111] + v3 + j + 3) != 6 )
				break;
			if ( dungeon[0][v3 + 1 + j] != 6 )
				break;
			++v8;
			v4 += 40;
			v2 += 40;
			v3 = v2;
		}
		while ( *v4 == 6 );
	}
	result = v8;
	v6 = 0;
	v7 = dungeon[v8 + i][j];
	if ( v7 == 10 )
		v6 = 1;
	if ( v7 == 12 )
		v6 = 1;
	if ( v7 == 13 )
		v6 = 1;
	if ( v7 == 15 )
		v6 = 1;
	if ( v7 == 16 )
		v6 = 1;
	if ( v7 == 21 )
		v6 = 1;
	if ( v7 == 22 )
		v6 = 1;
	if ( v8 <= 3 )
		v6 = 0;
	if ( !v6 )
		result = -1;
	return result;
}

//----- (00413270) --------------------------------------------------------
int __fastcall L4VWallOk(int i, int j)
{
	int v2; // ecx
	int result; // eax
	char *v4; // esi
	signed int v5; // esi
	char v6; // dl

	v2 = i;
	result = 1;
	if ( dungeon[v2][j + 1] == 6 )
	{
		do
		{
			if ( dflags[v2][j + result] )
				break;
			v4 = &dungeon[v2][j];
			if ( v4[result - 40] != 6 )
				break;
			if ( dungeon[v2 + 1][result + j] != 6 )
				break;
			++result;
		}
		while ( v4[result] == 6 );
	}
	v5 = 0;
	v6 = dungeon[0][result + v2 * 40 + j];
	if ( v6 == 8 )
		v5 = 1;
	if ( v6 == 9 )
		v5 = 1;
	if ( v6 == 11 )
		v5 = 1;
	if ( v6 == 14 )
		v5 = 1;
	if ( v6 == 15 )
		v5 = 1;
	if ( v6 == 16 )
		v5 = 1;
	if ( v6 == 21 )
		v5 = 1;
	if ( v6 == 23 )
		v5 = 1;
	if ( result <= 3 )
		v5 = 0;
	if ( !v5 )
		result = -1;
	return result;
}

//----- (0041330B) --------------------------------------------------------
void __fastcall L4HorizWall(int i, int j, int dx)
{
	int v3; // esi
	int v4; // edi
	int v5; // eax
	int v6; // ecx
	char *v7; // eax
	int v8; // edx
	char *v9; // eax
	int v10; // eax
	bool v11; // zf
	char *v12; // eax

	v3 = i;
	v4 = j;
	v5 = j + 40 * i;
	if ( dungeon[0][v5] == 13 )
		dungeon[0][v5] = 17;
	if ( dungeon[0][v5] == 16 )
		dungeon[0][v5] = 11;
	if ( dungeon[0][v5] == 12 )
		dungeon[0][v5] = 14;
	v6 = dx;
	if ( dx > 1 )
	{
		v7 = &dungeon[1][v5];
		v8 = dx - 1;
		do
		{
			*v7 = 2;
			v7 += 40;
			--v8;
		}
		while ( v8 );
	}
	v9 = &dungeon[v3 + dx][v4];
	if ( *v9 == 15 )
		*v9 = 14;
	if ( *v9 == 10 )
		*v9 = 17;
	if ( *v9 == 21 )
		*v9 = 23;
	if ( *v9 == 22 )
		*v9 = 29;
	_LOBYTE(v6) = 0;
	v10 = v4 + 40 * (v3 + random(v6, dx - 3) + 1);
	dungeon[2][v10] = 56;
	dungeon[1][v10] = 60;
	v11 = dungeon[0][v10 - 1] == 6;
	dungeon[0][v10] = 57;
	if ( v11 )
		dungeon[0][v10 - 1] = 58;
	v12 = &dungeon[0][v10 + 39];
	if ( *v12 == 6 )
		*v12 = 59;
}

//----- (004133D6) --------------------------------------------------------
void __fastcall L4VertWall(int i, int j, int dy)
{
	int v3; // edi
	int v4; // esi
	int v5; // edx
	int v6; // ecx
	_BYTE *v7; // eax
	int v8; // edx
	int v9; // eax
	char *v10; // ecx
	bool v11; // zf
	int v12; // [esp+8h] [ebp-4h]

	v3 = j;
	v4 = 40 * i;
	v12 = j;
	v5 = 40 * i + j;
	if ( dungeon[0][v5] == 14 )
		dungeon[0][v5] = 17;
	if ( dungeon[0][v5] == 8 )
		dungeon[0][v5] = 9;
	if ( dungeon[0][v5] == 15 )
		dungeon[0][v5] = 10;
	v6 = dy;
	if ( dy > 1 )
	{
		memset(&dungeon[0][v5 + 1], 1u, dy - 1);
		v3 = v12;
		v6 = dy;
	}
	v7 = (unsigned char *)dungeon + v5 + v6;
	if ( *v7 == 11 )
		*v7 = 17;
	if ( *v7 == 9 )
		*v7 = 10;
	if ( *v7 == 16 )
		*v7 = 13;
	if ( *v7 == 21 )
		*v7 = 22;
	if ( *v7 == 23 )
		*v7 = 29;
	v8 = v6 - 3;
	_LOBYTE(v6) = 0;
	v9 = random(v6, v8) + 1 + v4 + v3;
	v10 = (char *)dungeon + v9;
	dungeon[0][v9 + 2] = 52;
	dungeon[0][v9 + 1] = 6;
	v11 = dungeon[-1][v9] == 6;
	dungeon[0][v9] = 53;
	if ( v11 )
		*(v10 - 40) = 54;
	if ( *(v10 - 41) == 6 )
		*(v10 - 41) = 55;
}

//----- (004134B4) --------------------------------------------------------
void __cdecl L4tileFix()
{
	signed int v0; // edx
	char *v1; // eax
	signed int v2; // esi
	char v3; // cl
	signed int v4; // edx
	char *v5; // eax
	signed int v6; // esi
	char v7; // cl
	signed int v8; // ecx
	int v9; // eax
	int v10; // eax
	char *v11; // esi
	char v12; // bl
	char *v13; // edx
	char *v14; // edx
	char *v15; // edx
	char *v16; // edx
	char *v17; // edx
	char *v18; // edx
	char *v19; // edx
	char *v20; // edx
	char *v21; // edx
	char *v22; // edx
	char *v23; // edx
	char *v24; // edx
	char *v25; // edx
	char *v26; // edx
	char *v27; // edx
	char *v28; // edx
	char *v29; // edx
	char *v30; // edx
	char *v31; // edx
	char *v32; // edx
	char *v33; // edx
	char *v34; // edx
	char *v35; // edx
	char *v36; // edx
	char *v37; // edx
	char *v38; // edx
	char *v39; // edx
	char *v40; // edx
	char *v41; // edx
	char *v42; // edx
	char *v43; // edx
	char *v44; // edx
	char *v45; // edx
	char *v46; // edx
	char *v47; // edx
	char *v48; // edx
	char *v49; // edx
	char *v50; // edx
	char *v51; // edx
	char *v52; // edx
	char *v53; // edx
	char *v54; // edx
	char *v55; // edx
	char *v56; // edx
	char *v57; // edx
	char *v58; // edx
	char *v59; // edx
	char *v60; // edx
	char *v61; // edx
	char *v62; // edx
	char *v63; // edx
	char *v64; // edx
	char *v65; // edx
	char *v66; // edx
	char *v67; // edx
	char *v68; // edx
	char *v69; // edx
	char *v70; // edx
	char *v71; // edx
	char *v72; // edx
	char *v73; // edx
	char *v74; // edx
	char *v75; // edx
	char *v76; // edx
	char *v77; // edx
	char *v78; // edx
	char *v79; // edx
	char *v80; // edx
	char *v81; // edx
	char *v82; // edx
	char *v83; // edx
	char *v84; // edx
	char *v85; // edx
	char *v86; // edx
	char *v87; // edx
	char *v88; // edx
	char *v89; // edx
	char *v90; // edx
	char *v91; // edx
	char *v92; // edx
	char *v93; // edx
	char *v94; // edx
	char *v95; // edx
	signed int v96; // ecx
	signed int v97; // edi
	signed int v98; // eax
	char *v99; // esi
	char v100; // bl
	char *v101; // edx
	char *v102; // edx
	char *v103; // edx
	char *v104; // edx
	char *v105; // edx
	char *v106; // edx
	char *v107; // edx
	char *v108; // edx
	char *v109; // edx
	char *v110; // edx
	char *v111; // edx
	char *v112; // edx
	char *v113; // edx
	char *v114; // edx
	char *v115; // edx
	char *v116; // edx
	char *v117; // edx
	char *v118; // edx
	char *v119; // edx
	char *v120; // edx
	char *v121; // edx
	char *v122; // edx
	char *v123; // edx
	char *v124; // edx
	char *v125; // edx
	char *v126; // edx
	char *v127; // edx
	char *v128; // edx
	char *v129; // edx
	char *v130; // edx
	signed int v131; // edx
	char *v132; // eax
	signed int v133; // esi
	char v134; // cl
	signed int v135; // edx
	char *v136; // eax
	signed int v137; // esi
	char v138; // cl
	signed int v139; // [esp+8h] [ebp-4h]

	v0 = 0;
	do
	{
		v1 = &dungeon[1][v0];
		v2 = 40;
		do
		{
			v3 = *(v1 - 40);
			if ( v3 == 2 )
			{
				if ( *v1 == 6 )
					*v1 = 5;
				if ( *v1 == 1 )
					*v1 = 13;
			}
			if ( v3 == 1 && *(v1 - 39) == 2 )
				*(v1 - 39) = 14;
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
	v4 = 0;
	do
	{
		v5 = &dungeon[1][v4];
		v6 = 40;
		do
		{
			v7 = *(v5 - 40);
			if ( v7 == 2 )
			{
				if ( *v5 == 6 )
					*v5 = 2;
				if ( *v5 == 9 )
					*v5 = 11;
			}
			if ( v7 == 9 && *v5 == 6 )
				*v5 = 12;
			if ( v7 == 14 && *v5 == 1 )
				*v5 = 13;
			if ( v7 == 6 )
			{
				if ( *v5 == 14 )
					*v5 = 15;
				if ( *(v5 - 39) == 13 )
					*(v5 - 39) = 16;
			}
			if ( v7 == 1 && *(v5 - 39) == 9 )
				*(v5 - 39) = 10;
			if ( v7 == 6 && *(v5 - 41) == 1 )
				*(v5 - 41) = 1;
			v5 += 40;
			--v6;
		}
		while ( v6 );
		++v4;
	}
	while ( v4 < 40 );
	v8 = 0;
	do
	{
		v9 = 0;
		v139 = 0;
		do
		{
			v10 = v9;
			v11 = &dungeon[v10][v8];
			v12 = *v11;
			if ( *v11 == 13 )
			{
				v13 = &dungeon[v10][v8 + 1];
				if ( *v13 == 30 )
					*v13 = 27;
			}
			if ( v12 == 27 )
			{
				v14 = &dungeon[v10 + 1][v8];
				if ( *v14 == 30 )
					*v14 = 19;
			}
			if ( v12 == 1 )
			{
				v15 = &dungeon[v10][v8 + 1];
				if ( *v15 == 30 )
					*v15 = 27;
			}
			if ( v12 == 27 )
			{
				v16 = &dungeon[v10 + 1][v8];
				if ( *v16 == 1 )
					*v16 = 16;
			}
			if ( v12 == 19 )
			{
				v17 = &dungeon[v10 + 1][v8];
				if ( *v17 == 27 )
					*v17 = 26;
			}
			if ( v12 == 27 )
			{
				v18 = &dungeon[v10 + 1][v8];
				if ( *v18 == 30 )
					*v18 = 19;
			}
			if ( v12 == 2 )
			{
				v19 = &dungeon[v10 + 1][v8];
				if ( *v19 == 15 )
					*v19 = 14;
			}
			if ( v12 == 14 )
			{
				v20 = &dungeon[v10 + 1][v8];
				if ( *v20 == 15 )
					*v20 = 14;
			}
			if ( v12 == 22 )
			{
				v21 = &dungeon[v10 + 1][v8];
				if ( *v21 == 1 )
					*v21 = 16;
			}
			if ( v12 == 27 )
			{
				v22 = &dungeon[v10 + 1][v8];
				if ( *v22 == 1 )
					*v22 = 16;
			}
			if ( v12 == 6 )
			{
				v23 = &dungeon[v10 + 1][v8];
				if ( *v23 == 27 )
				{
					if ( dungeon[v10 + 1][v8 + 1] )
						*v23 = 22;
				}
			}
			if ( v12 == 22 )
			{
				v24 = &dungeon[v10 + 1][v8];
				if ( *v24 == 30 )
					*v24 = 19;
			}
			if ( v12 == 21 )
			{
				v25 = &dungeon[v10 + 1][v8];
				if ( *v25 == 1 && dungeon[v10][v8 + 39] == 1 )
					*v25 = 13;
			}
			if ( v12 == 14 )
			{
				v26 = &dungeon[v10 + 1][v8];
				if ( *v26 == 30 && dungeon[v10][v8 + 1] == 6 )
					*v26 = 28;
			}
			if ( v12 == 16 )
			{
				if ( dungeon[v10 + 1][v8] == 6 )
				{
					v27 = &dungeon[v10][v8 + 1];
					if ( *v27 == 30 )
						*v27 = 27;
				}
				v28 = &dungeon[v10][v8 + 1];
				if ( *v28 == 30 && dungeon[v10 + 1][v8 + 1] == 30 )
					*v28 = 27;
			}
			if ( v12 == 6 )
			{
				v29 = &dungeon[v10 + 1][v8];
				if ( *v29 == 30 && dungeon[v10][v8 + 39] == 6 )
					*v29 = 21;
			}
			if ( v12 == 2 )
			{
				v30 = &dungeon[v10 + 1][v8];
				if ( *v30 == 27 && dungeon[v10 + 1][v8 + 1] == 9 )
					*v30 = 29;
			}
			if ( v12 == 9 )
			{
				v31 = &dungeon[v10 + 1][v8];
				if ( *v31 == 15 )
					*v31 = 14;
			}
			if ( v12 == 15 )
			{
				v32 = &dungeon[v10 + 1][v8];
				if ( *v32 == 27 && dungeon[v10 + 1][v8 + 1] == 2 )
					*v32 = 29;
			}
			if ( v12 == 19 )
			{
				v33 = &dungeon[v10 + 1][v8];
				if ( *v33 == 18 )
					*v33 = 24;
			}
			if ( v12 == 9 )
			{
				v34 = &dungeon[v10 + 1][v8];
				if ( *v34 == 15 )
					*v34 = 14;
			}
			if ( v12 == 19 )
			{
				v35 = &dungeon[v10 + 1][v8];
				if ( *v35 == 19 && dungeon[v10][v8 + 39] == 30 )
					*v35 = 24;
			}
			if ( v12 == 24 && *(v11 - 1) == 30 && *(v11 - 2) == 6 )
				*(v11 - 1) = 21;
			if ( v12 == 2 )
			{
				v36 = &dungeon[v10 + 1][v8];
				if ( *v36 == 30 )
					*v36 = 28;
			}
			if ( v12 == 15 )
			{
				v37 = &dungeon[v10 + 1][v8];
				if ( *v37 == 30 )
					*v37 = 28;
			}
			if ( v12 == 28 )
			{
				v38 = &dungeon[v10][v8 + 1];
				if ( *v38 == 30 )
					*v38 = 18;
				v39 = &dungeon[v10][v8 + 1];
				if ( *v39 == 2 )
					*v39 = 15;
			}
			if ( v12 == 19 )
			{
				if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 18 && dungeon[v10 + 1][v8 + 1] == 1 )
					dungeon[v10 + 1][v8] = 17;
				if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 22 && dungeon[v10 + 1][v8 + 1] == 1 )
					dungeon[v10 + 1][v8] = 17;
				if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 18 && dungeon[v10 + 1][v8 + 1] == 13 )
					dungeon[v10 + 1][v8] = 17;
			}
			if ( v12 == 21 )
			{
				if ( dungeon[v10 + 2][v8] == 2 && dungeon[v10][v8 + 39] == 18 && dungeon[v10 + 1][v8 + 1] == 1 )
					dungeon[v10 + 1][v8] = 17;
				if ( dungeon[v10 + 1][v8 + 1] == 1 && dungeon[v10][v8 + 39] == 22 && dungeon[v10 + 2][v8] == 3 )
					dungeon[v10 + 1][v8] = 17;
			}
			if ( v12 == 15 )
			{
				v40 = &dungeon[v10 + 1][v8];
				if ( *v40 == 28 && dungeon[v10 + 2][v8] == 30 && dungeon[v10][v8 + 39] == 6 )
					*v40 = 23;
			}
			if ( v12 == 14 )
			{
				v41 = &dungeon[v10 + 1][v8];
				if ( *v41 == 28 && dungeon[v10 + 2][v8] == 1 )
					*v41 = 23;
			}
			if ( v12 == 15 )
			{
				v42 = &dungeon[v10 + 1][v8];
				if ( *v42 == 27 && dungeon[v10 + 1][v8 + 1] == 30 )
					*v42 = 29;
			}
			if ( v12 == 28 )
			{
				v43 = &dungeon[v10][v8 + 1];
				if ( *v43 == 9 )
					*v43 = 15;
			}
			if ( v12 == 21 && dungeon[v10][v8 + 39] == 21 )
				dungeon[v10 + 1][v8] = 24;
			if ( v12 == 2 )
			{
				v44 = &dungeon[v10 + 1][v8];
				if ( *v44 == 27 && dungeon[v10 + 1][v8 + 1] == 30 )
					*v44 = 29;
				v45 = &dungeon[v10 + 1][v8];
				if ( *v45 == 18 )
					*v45 = 25;
			}
			if ( v12 == 21 )
			{
				v46 = &dungeon[v10 + 1][v8];
				if ( *v46 == 9 && dungeon[v10 + 2][v8] == 2 )
					*v46 = 11;
			}
			if ( v12 == 19 )
			{
				v47 = &dungeon[v10 + 1][v8];
				if ( *v47 == 10 )
					*v47 = 17;
			}
			if ( v12 == 15 )
			{
				v48 = &dungeon[v10][v8 + 1];
				if ( *v48 == 3 )
					*v48 = 4;
			}
			if ( v12 == 22 )
			{
				v49 = &dungeon[v10][v8 + 1];
				if ( *v49 == 9 )
					*v49 = 15;
			}
			if ( v12 == 18 )
			{
				v50 = &dungeon[v10][v8 + 1];
				if ( *v50 == 30 )
					*v50 = 18;
			}
			if ( v12 == 24 && *(v11 - 40) == 30 )
				*(v11 - 40) = 19;
			if ( v12 == 21 )
			{
				v51 = &dungeon[v10][v8 + 1];
				if ( *v51 == 2 )
					*v51 = 15;
				v52 = &dungeon[v10][v8 + 1];
				if ( *v52 == 9 )
					*v52 = 10;
			}
			if ( v12 == 22 )
			{
				v53 = &dungeon[v10][v8 + 1];
				if ( *v53 == 30 )
					*v53 = 18;
			}
			if ( v12 == 21 )
			{
				v54 = &dungeon[v10][v8 + 1];
				if ( *v54 == 30 )
					*v54 = 18;
			}
			if ( v12 == 16 )
			{
				v55 = &dungeon[v10][v8 + 1];
				if ( *v55 == 2 )
					*v55 = 15;
			}
			if ( v12 == 13 )
			{
				v56 = &dungeon[v10][v8 + 1];
				if ( *v56 == 2 )
					*v56 = 15;
			}
			if ( v12 == 22 )
			{
				v57 = &dungeon[v10][v8 + 1];
				if ( *v57 == 2 )
					*v57 = 15;
			}
			if ( v12 == 21 )
			{
				v58 = &dungeon[v10 + 1][v8];
				if ( *v58 == 18 && dungeon[v10 + 2][v8] == 30 )
					*v58 = 24;
				v59 = &dungeon[v10 + 1][v8];
				if ( *v59 == 9 && dungeon[v10 + 1][v8 + 1] == 1 )
					*v59 = 16;
			}
			if ( v12 == 2 )
			{
				v60 = &dungeon[v10 + 1][v8];
				if ( *v60 == 27 && dungeon[v10 + 1][v8 + 1] == 2 )
					*v60 = 29;
			}
			if ( v12 == 23 )
			{
				v61 = &dungeon[v10][v8 + 1];
				if ( *v61 == 2 )
					*v61 = 15;
				v62 = &dungeon[v10][v8 + 1];
				if ( *v62 == 9 )
					*v62 = 15;
			}
			if ( v12 == 25 )
			{
				v63 = &dungeon[v10][v8 + 1];
				if ( *v63 == 2 )
					*v63 = 15;
			}
			if ( v12 == 22 )
			{
				v64 = &dungeon[v10 + 1][v8];
				if ( *v64 == 9 )
					*v64 = 11;
			}
			if ( v12 == 23 )
			{
				v65 = &dungeon[v10 + 1][v8];
				if ( *v65 == 9 )
					*v65 = 11;
			}
			if ( v12 == 15 )
			{
				v66 = &dungeon[v10 + 1][v8];
				if ( *v66 == 1 )
					*v66 = 16;
			}
			if ( v12 == 11 )
			{
				v67 = &dungeon[v10 + 1][v8];
				if ( *v67 == 15 )
					*v67 = 14;
			}
			if ( v12 == 23 )
			{
				v68 = &dungeon[v10 + 1][v8];
				if ( *v68 == 1 )
					*v68 = 16;
			}
			if ( v12 == 21 )
			{
				v69 = &dungeon[v10 + 1][v8];
				if ( *v69 == 27 )
					*v69 = 26;
				v70 = &dungeon[v10 + 1][v8];
				if ( *v70 == 18 )
					*v70 = 24;
			}
			if ( v12 == 26 )
			{
				v71 = &dungeon[v10 + 1][v8];
				if ( *v71 == 1 )
					*v71 = 16;
			}
			if ( v12 == 29 )
			{
				v72 = &dungeon[v10 + 1][v8];
				if ( *v72 == 1 )
					*v72 = 16;
				v73 = &dungeon[v10][v8 + 1];
				if ( *v73 == 2 )
					*v73 = 15;
			}
			if ( v12 == 1 && *(v11 - 1) == 15 )
				*(v11 - 1) = 10;
			if ( v12 == 18 )
			{
				v74 = &dungeon[v10][v8 + 1];
				if ( *v74 == 2 )
					*v74 = 15;
			}
			if ( v12 == 23 )
			{
				v75 = &dungeon[v10][v8 + 1];
				if ( *v75 == 30 )
					*v75 = 18;
			}
			if ( v12 == 18 )
			{
				v76 = &dungeon[v10][v8 + 1];
				if ( *v76 == 9 )
					*v76 = 10;
			}
			if ( v12 == 14 )
			{
				v77 = &dungeon[v10 + 1][v8];
				if ( *v77 == 30 && dungeon[v10 + 1][v8 + 1] == 30 )
					*v77 = 23;
			}
			if ( v12 == 2 )
			{
				v78 = &dungeon[v10 + 1][v8];
				if ( *v78 == 28 && dungeon[v10][v8 + 39] == 6 )
					*v78 = 23;
			}
			if ( v12 == 23 )
			{
				v79 = &dungeon[v10 + 1][v8];
				if ( *v79 == 18 && *(v11 - 1) == 6 )
					*v79 = 24;
			}
			if ( v12 == 14 )
			{
				v80 = &dungeon[v10 + 1][v8];
				if ( *v80 == 23 && dungeon[v10 + 2][v8] == 30 )
					*v80 = 28;
				v81 = &dungeon[v10 + 1][v8];
				if ( *v81 == 28 && dungeon[v10 + 2][v8] == 30 && dungeon[v10][v8 + 39] == 6 )
					*v81 = 23;
			}
			if ( v12 == 23 )
			{
				v82 = &dungeon[v10 + 1][v8];
				if ( *v82 == 30 )
					*v82 = 19;
			}
			if ( v12 == 29 )
			{
				v83 = &dungeon[v10 + 1][v8];
				if ( *v83 == 30 )
					*v83 = 19;
				v84 = &dungeon[v10][v8 + 1];
				if ( *v84 == 30 )
					*v84 = 18;
			}
			if ( v12 == 19 )
			{
				v85 = &dungeon[v10 + 1][v8];
				if ( *v85 == 30 )
					*v85 = 19;
			}
			if ( v12 == 21 )
			{
				v86 = &dungeon[v10 + 1][v8];
				if ( *v86 == 30 )
					*v86 = 19;
			}
			if ( v12 == 26 )
			{
				v87 = &dungeon[v10 + 1][v8];
				if ( *v87 == 30 )
					*v87 = 19;
			}
			if ( v12 == 16 )
			{
				v88 = &dungeon[v10][v8 + 1];
				if ( *v88 == 30 )
					*v88 = 18;
			}
			if ( v12 == 13 )
			{
				v89 = &dungeon[v10][v8 + 1];
				if ( *v89 == 9 )
					*v89 = 10;
			}
			if ( v12 == 25 )
			{
				v90 = &dungeon[v10][v8 + 1];
				if ( *v90 == 30 )
					*v90 = 18;
			}
			if ( v12 == 18 )
			{
				v91 = &dungeon[v10][v8 + 1];
				if ( *v91 == 2 )
					*v91 = 15;
			}
			if ( v12 == 11 )
			{
				v92 = &dungeon[v10 + 1][v8];
				if ( *v92 == 3 )
					*v92 = 5;
			}
			if ( v12 == 19 )
			{
				v93 = &dungeon[v10 + 1][v8];
				if ( *v93 == 9 )
					*v93 = 11;
				v94 = &dungeon[v10 + 1][v8];
				if ( *v94 == 1 )
					*v94 = 13;
				v95 = &dungeon[v10 + 1][v8];
				if ( *v95 == 13 && dungeon[v10][v8 + 39] == 6 )
					*v95 = 16;
			}
			v9 = v139++ + 1;
		}
		while ( v139 < 40 );
		++v8;
	}
	while ( v8 < 40 );
	v96 = 0;
	do
	{
		v97 = 0;
		do
		{
			v98 = v97;
			v99 = &dungeon[v97][v96];
			v100 = *v99;
			if ( *v99 == 21 )
			{
				v101 = &dungeon[v98][v96 + 1];
				if ( *v101 == 24 && dungeon[v98][v96 + 2] == 1 )
					*v101 = 17;
			}
			if ( v100 == 15
			  && dungeon[v98 + 1][v96 + 1] == 9
			  && dungeon[v98][v96 + 39] == 1
			  && dungeon[v98 + 2][v96] == 16 )
			{
				dungeon[v98 + 1][v96] = 29;
			}
			if ( v100 == 2 && *(v99 - 40) == 6 )
				*(v99 - 40) = 8;
			if ( v100 == 1 && *(v99 - 1) == 6 )
				*(v99 - 1) = 7;
			if ( v100 == 6 )
			{
				v102 = &dungeon[v98 + 1][v96];
				if ( *v102 == 15 && dungeon[v98 + 1][v96 + 1] == 4 )
					*v102 = 10;
			}
			if ( v100 == 1 )
			{
				v103 = &dungeon[v98][v96 + 1];
				if ( *v103 == 3 )
					*v103 = 4;
				v104 = &dungeon[v98][v96 + 1];
				if ( *v104 == 6 )
					*v104 = 4;
			}
			if ( v100 == 9 )
			{
				v105 = &dungeon[v98][v96 + 1];
				if ( *v105 == 3 )
					*v105 = 4;
			}
			if ( v100 == 10 )
			{
				v106 = &dungeon[v98][v96 + 1];
				if ( *v106 == 3 )
					*v106 = 4;
			}
			if ( v100 == 13 )
			{
				v107 = &dungeon[v98][v96 + 1];
				if ( *v107 == 3 )
					*v107 = 4;
			}
			if ( v100 == 1 )
			{
				v108 = &dungeon[v98][v96 + 1];
				if ( *v108 == 5 )
					*v108 = 12;
				v109 = &dungeon[v98][v96 + 1];
				if ( *v109 == 16 )
					*v109 = 13;
			}
			if ( v100 == 6 )
			{
				v110 = &dungeon[v98][v96 + 1];
				if ( *v110 == 13 )
					*v110 = 16;
			}
			if ( v100 == 25 )
			{
				v111 = &dungeon[v98][v96 + 1];
				if ( *v111 == 9 )
					*v111 = 10;
			}
			if ( v100 == 13 )
			{
				v112 = &dungeon[v98][v96 + 1];
				if ( *v112 == 5 )
					*v112 = 12;
			}
			if ( v100 == 28 && *(v99 - 1) == 6 )
			{
				v113 = &dungeon[v98 + 1][v96];
				if ( *v113 == 1 )
					*v113 = 23;
			}
			if ( v100 == 19 )
			{
				v114 = &dungeon[v98 + 1][v96];
				if ( *v114 == 10 )
					*v114 = 17;
			}
			if ( v100 == 21 )
			{
				v115 = &dungeon[v98 + 1][v96];
				if ( *v115 == 9 )
					*v115 = 11;
			}
			if ( v100 == 11 )
			{
				v116 = &dungeon[v98 + 1][v96];
				if ( *v116 == 3 )
					*v116 = 5;
			}
			if ( v100 == 10 )
			{
				v117 = &dungeon[v98 + 1][v96];
				if ( *v117 == 4 )
					*v117 = 12;
			}
			if ( v100 == 14 )
			{
				v118 = &dungeon[v98 + 1][v96];
				if ( *v118 == 4 )
					*v118 = 12;
			}
			if ( v100 == 27 )
			{
				v119 = &dungeon[v98 + 1][v96];
				if ( *v119 == 9 )
					*v119 = 11;
			}
			if ( v100 == 15 )
			{
				v120 = &dungeon[v98 + 1][v96];
				if ( *v120 == 4 )
					*v120 = 12;
			}
			if ( v100 == 21 )
			{
				v121 = &dungeon[v98 + 1][v96];
				if ( *v121 == 1 )
					*v121 = 16;
			}
			if ( v100 == 11 )
			{
				v122 = &dungeon[v98 + 1][v96];
				if ( *v122 == 4 )
					*v122 = 12;
			}
			if ( v100 == 2 )
			{
				v123 = &dungeon[v98 + 1][v96];
				if ( *v123 == 3 )
					*v123 = 5;
			}
			if ( v100 == 9 )
			{
				v124 = &dungeon[v98 + 1][v96];
				if ( *v124 == 3 )
					*v124 = 5;
			}
			if ( v100 == 14 )
			{
				v125 = &dungeon[v98 + 1][v96];
				if ( *v125 == 3 )
					*v125 = 5;
			}
			if ( v100 == 15 )
			{
				v126 = &dungeon[v98 + 1][v96];
				if ( *v126 == 3 )
					*v126 = 5;
			}
			if ( v100 == 2 )
			{
				v127 = &dungeon[v98 + 1][v96];
				if ( *v127 == 5 && dungeon[v98][v96 + 39] == 16 )
					*v127 = 12;
				v128 = &dungeon[v98 + 1][v96];
				if ( *v128 == 4 )
					*v128 = 12;
			}
			if ( v100 == 9 )
			{
				v129 = &dungeon[v98 + 1][v96];
				if ( *v129 == 4 )
					*v129 = 12;
			}
			if ( v100 == 1 && *(v99 - 1) == 8 )
				*(v99 - 1) = 9;
			if ( v100 == 28 )
			{
				v130 = &dungeon[v98 + 1][v96];
				if ( *v130 == 23 && dungeon[v98 + 1][v96 + 1] == 3 )
					*v130 = 16;
			}
			++v97;
		}
		while ( v97 < 40 );
		++v96;
	}
	while ( v96 < 40 );
	v131 = 0;
	do
	{
		v132 = &dungeon[0][v131 + 1];
		v133 = 40;
		do
		{
			v134 = *(v132 - 1);
			if ( v134 == 21 && v132[39] == 10 )
				v132[39] = 17;
			if ( v134 == 17 && v132[39] == 4 )
				v132[39] = 12;
			if ( v134 == 10 && v132[39] == 4 )
				v132[39] = 12;
			if ( v134 == 17 && *v132 == 5 )
				*v132 = 12;
			if ( v134 == 29 && *v132 == 9 )
				*v132 = 10;
			if ( v134 == 13 && *v132 == 5 )
				*v132 = 12;
			if ( v134 == 9 && *v132 == 16 )
				*v132 = 13;
			if ( v134 == 10 && *v132 == 16 )
				*v132 = 13;
			if ( v134 == 16 && *v132 == 3 )
				*v132 = 4;
			if ( v134 == 11 && *v132 == 5 )
				*v132 = 12;
			if ( v134 == 10 && v132[39] == 3 && v132[38] == 16 )
				v132[39] = 12;
			if ( v134 == 16 && *v132 == 5 )
				*v132 = 12;
			if ( v134 == 1 && *v132 == 6 )
				*v132 = 4;
			if ( v134 == 21 && v132[39] == 13 && *v132 == 10 )
				v132[40] = 12;
			if ( v134 == 15 && v132[39] == 10 )
				v132[39] = 17;
			if ( v134 == 22 && *v132 == 11 )
				*v132 = 17;
			if ( v134 == 15 && v132[39] == 28 && v132[79] == 16 )
				v132[39] = 23;
			if ( v134 == 28 && v132[39] == 23 && v132[40] == 1 && v132[79] == 6 )
				v132[39] = 16;
			v132 += 40;
			--v133;
		}
		while ( v133 );
		++v131;
	}
	while ( v131 < 40 );
	v135 = 0;
	do
	{
		v136 = (char *)dungeon + v135;
		v137 = 40;
		do
		{
			v138 = *v136;
			if ( *v136 == 15 && v136[40] == 28 && v136[80] == 16 )
				v136[40] = 23;
			if ( v138 == 21 && v136[39] == 21 && v136[41] == 13 && v136[80] == 2 )
				v136[40] = 17;
			if ( v138 == 19 && v136[40] == 15 && v136[41] == 12 )
				v136[40] = 17;
			v136 += 40;
			--v137;
		}
		while ( v137 );
		++v135;
	}
	while ( v135 < 40 );
}

//----- (004142DD) --------------------------------------------------------
void __cdecl DRLG_L4Subs()
{
	signed int v0; // edi
	signed int v1; // esi
	signed int v2; // ebp
	unsigned char v3; // bl
	int v4; // eax
	signed int v5; // ecx
	signed int v6; // edi
	signed int v7; // esi
	signed int v8; // ebx

	v0 = 0;
	do
	{
		v1 = v0;
		v2 = 40;
		do
		{
			if ( !random(0, 3) )
			{
				v3 = L4BTYPES[(unsigned char)dungeon[0][v1]];
				if ( v3 )
				{
					if ( !dflags[0][v1] )
					{
						v4 = random(0, 16);
						v5 = -1;
						while ( v4 >= 0 )
						{
							if ( ++v5 == 140 )
								v5 = 0;
							if ( v3 == L4BTYPES[v5] )
								--v4;
						}
						dungeon[0][v1] = v5;
					}
				}
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 40 );
	v6 = 0;
	do
	{
		v7 = v6;
		v8 = 40;
		do
		{
			if ( !random(0, 10) && L4BTYPES[(unsigned char)dungeon[0][v7]] == 6 && !dflags[0][v7] )
				dungeon[0][v7] = random(0, 3) + 95;
			v7 += 40;
			--v8;
		}
		while ( v8 );
		++v6;
	}
	while ( v6 < 40 );
}

//----- (0041439A) --------------------------------------------------------
void __cdecl L4makeDungeon()
{
	signed int v0; // ebx
	signed int v1; // esi
	char *v2; // edx
	char v3; // cl
	int v4; // eax
	int v5; // eax
	int v6; // ebx
	char *v7; // esi
	signed int v8; // edx
	char v9; // cl
	int v10; // eax
	int v11; // eax
	signed int v12; // ebx
	signed int v13; // esi
	char *v14; // edx
	char v15; // cl
	int v16; // eax
	int v17; // eax
	int v18; // ebx
	char *v19; // esi
	signed int v20; // edx
	char v21; // cl
	int v22; // eax
	int v23; // eax
	signed int v24; // [esp+Ch] [ebp-8h]
	char *v25; // [esp+10h] [ebp-4h]
	char *v26; // [esp+10h] [ebp-4h]

	v0 = 0;
	do
	{
		v1 = 0;
		v2 = (char *)dung + v0;
		do
		{
			v3 = *v2;
			v2 += 20;
			v4 = 160 * v1++;
			v5 = v4 + 2 * v0;
			L4dungeon[0][v5] = v3;
			L4dungeon[0][v5 + 1] = v3;
			L4dungeon[1][v5] = v3;
			L4dungeon[1][v5 + 1] = v3;
		}
		while ( v1 < 20 );
		++v0;
	}
	while ( v0 < 20 );
	v6 = 0;
	v25 = &dung[0][19];
	v24 = 20;
	do
	{
		v7 = v25;
		v8 = 0;
		do
		{
			v9 = *v7;
			v7 += 20;
			v10 = 160 * v8++;
			v11 = v10 + 2 * v6;
			L4dungeon[0][v11 + 40] = v9;
			L4dungeon[0][v11 + 41] = v9;
			L4dungeon[1][v11 + 40] = v9;
			L4dungeon[1][v11 + 41] = v9;
		}
		while ( v8 < 20 );
		++v6;
		--v25;
		--v24;
	}
	while ( v24 );
	v12 = 0;
	do
	{
		v13 = 0;
		v14 = &dung[19][v12];
		do
		{
			v15 = *v14;
			v14 -= 20;
			v16 = 160 * v13++;
			v17 = v16 + 2 * v12;
			L4dungeon[40][v17] = v15;
			L4dungeon[40][v17 + 1] = v15;
			L4dungeon[41][v17] = v15;
			L4dungeon[41][v17 + 1] = v15;
		}
		while ( v13 < 20 );
		++v12;
	}
	while ( v12 < 20 );
	v18 = 0;
	v26 = &dung[19][19];
	do
	{
		v19 = v26;
		v20 = 0;
		do
		{
			v21 = *v19;
			v19 -= 20;
			v22 = 160 * v20++;
			v23 = v22 + 2 * v18;
			L4dungeon[40][v23 + 40] = v21;
			L4dungeon[40][v23 + 41] = v21;
			L4dungeon[41][v23 + 40] = v21;
			L4dungeon[41][v23 + 41] = v21;
		}
		while ( v20 < 20 );
		++v18;
		--v26;
	}
	while ( (signed int)v26 > (signed int)&dung[18][19] );
}

//----- (004144B1) --------------------------------------------------------
void __cdecl uShape()
{
	int v0; // ecx
	signed int v1; // esi
	signed int v2; // eax
	char v3; // dl
	int v4; // eax
	signed int v5; // esi
	int v6; // ecx
	int v7; // ecx
	int *v8; // esi
	signed int v9; // eax
	char v10; // dl
	int v11; // eax
	signed int v12; // esi
	char *v13; // edx

	v0 = 19;
	do
	{
		v1 = 19;
		do
		{
			v2 = v1;
			v3 = dung[v1][v0];
			if ( v3 == 1 || (hallok[v0] = 0, v3 == 1) )
			{
				hallok[v0] = dung[v2][v0 + 1] == 1 && !dung[v2 + 1][v0 + 1];
				v1 = 0;
			}
			--v1;
		}
		while ( v1 >= 0 );
		--v0;
	}
	while ( v0 >= 0 );
	_LOBYTE(v0) = 0;
	v4 = random(v0, 19) + 1;
	do
	{
		if ( hallok[v4] )
		{
			v5 = 19;
			do
			{
				v6 = v4 + 20 * v5;
				if ( dung[0][v6] == 1 )
				{
					v5 = -1;
					v4 = 0;
				}
				else
				{
					dung[0][v6] = 1;
					dung[0][v6 + 1] = 1;
				}
				--v5;
			}
			while ( v5 >= 0 );
		}
		else if ( ++v4 == 20 )
		{
			v4 = 1;
		}
	}
	while ( v4 );
	v7 = 380;
	v8 = &hallok[19];
	do
	{
		v9 = 19;
		do
		{
			v10 = dung[0][v7 + v9];
			if ( v10 == 1 || (*v8 = 0, v10 == 1) )
			{
				*v8 = dung[1][v7 + v9] == 1 && !dung[1][v7 + 1 + v9];
				v9 = 0;
			}
			--v9;
		}
		while ( v9 >= 0 );
		--v8;
		v7 -= 20;
	}
	while ( (signed int)v8 >= (signed int)hallok );
	_LOBYTE(v7) = 0;
	v11 = random(v7, 19) + 1;
	do
	{
		if ( hallok[v11] )
		{
			v12 = 19;
			do
			{
				v13 = &dung[v11][v12];
				if ( *v13 == 1 )
				{
					v12 = -1;
					v11 = 0;
				}
				else
				{
					*v13 = 1;
					dung[v11 + 1][v12] = 1;
				}
				--v12;
			}
			while ( v12 >= 0 );
		}
		else if ( ++v11 == 20 )
		{
			v11 = 1;
		}
	}
	while ( v11 );
}

//----- (004145E4) --------------------------------------------------------
int __cdecl GetArea()
{
	int result; // eax
	signed int v1; // edx
	_BYTE *v2; // ecx
	signed int v3; // esi

	result = 0;
	v1 = 0;
	do
	{
		v2 = (unsigned char *)dung + v1;
		v3 = 20;
		do
		{
			if ( *v2 == 1 )
				++result;
			v2 += 20;
			--v3;
		}
		while ( v3 );
		++v1;
	}
	while ( v1 < 20 );
	return result;
}

//----- (00414606) --------------------------------------------------------
void __cdecl L4firstRoom()
{
	int v0; // esi
	int v1; // edi
	int v2; // ebx
	int v3; // eax
	int v4; // eax
	int v5; // ebp
	int v6; // eax
	int v7; // eax
	int v8; // eax
	signed int v9; // [esp-4h] [ebp-18h]

	if ( currlevel == 16 )
	{
		v9 = 14;
	}
	else
	{
		if ( (currlevel != quests[11]._qlevel || !quests[11]._qactive)
		  && (currlevel != quests[15]._qlevel || gbMaxPlayers == 1) )
		{
			v0 = random(0, 5) + 2;
			v1 = random(0, 5) + 2;
			goto LABEL_10;
		}
		v9 = 11;
	}
	v1 = v9;
	v0 = v9;
LABEL_10:
	v2 = 20 - v0;
	v3 = ((20 - v0) >> 1) + random(0, 20 - ((20 - v0) >> 1) - v0);
	if ( v3 + v0 <= 19 )
		v2 = v3;
	v4 = ((20 - v1) >> 1) + random(0, 20 - ((20 - v1) >> 1) - v1);
	v5 = 20 - v1;
	if ( v4 + v1 <= 19 )
		v5 = v4;
	if ( currlevel == 16 )
	{
		l4holdx = v2;
		l4holdy = v5;
	}
	_LOBYTE(v6) = QuestStatus(11);
	if ( v6 || currlevel == quests[15]._qlevel && gbMaxPlayers != 1 )
	{
		SP4x1 = v2 + 1;
		SP4y1 = v5 + 1;
		v7 = v0 + v2 + 1;
		SP4y2 = v1 + v5 + 1;
	}
	else
	{
		v7 = 0;
		SP4x1 = 0;
		SP4y1 = 0;
		SP4y2 = 0;
	}
	SP4x2 = v7;
	L4drawRoom(v2, v5, v0, v1);
	v8 = random(0, 2);
	L4roomGen(v2, v5, v0, v1, v8);
}
// 528A34: using guessed type int l4holdx;
// 528A38: using guessed type int l4holdy;
// 528A40: using guessed type int SP4x2;
// 528A48: using guessed type int SP4y2;
// 679660: using guessed type char gbMaxPlayers;

//----- (00414738) --------------------------------------------------------
void __fastcall L4drawRoom(int x, int y, int width, int height)
{
	int i; // esi
	int v5; // edi
	char *v6; // eax

	for ( i = 0; i < height; ++i )
	{
		if ( width > 0 )
		{
			v5 = width;
			v6 = &dung[x][i + y];
			do
			{
				*v6 = 1;
				v6 += 20;
				--v5;
			}
			while ( v5 );
		}
	}
}

//----- (0041476F) --------------------------------------------------------
void __fastcall L4roomGen(int x, int y, int w, int h, int dir)
{
	int v5; // eax
	int v6; // ecx
	int v7; // eax
	int v8; // ecx
	int v9; // eax
	int v10; // ecx
	int v11; // esi
	int v12; // edi
	int v13; // ebx
	int v14; // eax
	int v15; // eax
	int v16; // ecx
	int v17; // esi
	int v18; // edi
	int v19; // ebx
	int v20; // eax
	int ya; // [esp+Ch] [ebp-10h]
	int yb; // [esp+Ch] [ebp-10h]
	int v23; // [esp+10h] [ebp-Ch]
	int v24; // [esp+10h] [ebp-Ch]
	int xa; // [esp+14h] [ebp-8h]
	int xb; // [esp+14h] [ebp-8h]
	int v27; // [esp+18h] [ebp-4h]
	int wa; // [esp+24h] [ebp+8h]
	int ha; // [esp+28h] [ebp+Ch]
	int hb; // [esp+28h] [ebp+Ch]
	int hc; // [esp+28h] [ebp+Ch]
	int dira; // [esp+2Ch] [ebp+10h]
	int dirb; // [esp+2Ch] [ebp+10h]

	v27 = y;
	xa = x;
	while ( 1 )
	{
		while ( 1 )
		{
			_LOBYTE(x) = 0;
			v5 = random(x, 4);
			v6 = 0;
			_LOBYTE(v6) = dir == 1 ? v5 != 0 : v5 == 0;
			v7 = v6;
			v8 = 0;
			if ( !v7 )
				break;
			if ( v7 != 1 )
				return;
			dira = 0;
			wa = w / 2;
			do
			{
				_LOBYTE(v8) = 0;
				v9 = random(v8, 5);
				_LOBYTE(v10) = 0;
				v11 = (v9 + 2) & 0xFFFFFFFE;
				v12 = (random(v10, 5) + 2) & 0xFFFFFFFE;
				v13 = xa + wa - v11 / 2;
				ya = v27 - v12;
				v14 = L4checkRoom(v13 - 1, v27 - v12 - 1, v11 + 2, v12 + 1);
				++dira;
				v23 = v14;
			}
			while ( !v14 && dira < 20 );
			if ( v14 == 1 )
				L4drawRoom(v13, ya, v11, v12);
			xb = v27 + h;
			ha = L4checkRoom(v13 - 1, v27 + h, v11 + 2, v12 + 1);
			if ( ha == 1 )
				L4drawRoom(v13, xb, v11, v12);
			if ( v23 == 1 )
				L4roomGen(v13, ya, v11, v12, 0);
			if ( ha != 1 )
				return;
			dir = 0;
			h = v12;
			w = v11;
			v27 = xb;
			xa = v13;
		}
		dirb = 0;
		hb = h / 2;
		do
		{
			_LOBYTE(v8) = 0;
			v15 = random(v8, 5);
			_LOBYTE(v16) = 0;
			v17 = (v15 + 2) & 0xFFFFFFFE;
			v18 = (random(v16, 5) + 2) & 0xFFFFFFFE;
			v19 = v27 + hb - v18 / 2;
			yb = xa - v17;
			v20 = L4checkRoom(xa - v17 - 1, v19 - 1, v18 + 2, v17 + 1);
			++dirb;
			v24 = v20;
		}
		while ( !v20 && dirb < 20 );
		if ( v20 == 1 )
			L4drawRoom(yb, v19, v17, v18);
		xa += w;
		hc = L4checkRoom(xa, v19 - 1, v17 + 1, v18 + 2);
		if ( hc == 1 )
			L4drawRoom(xa, v19, v17, v18);
		if ( v24 == 1 )
			L4roomGen(yb, v19, v17, v18, 1);
		if ( hc != 1 )
			break;
		dir = 1;
		h = v18;
		w = v17;
		v27 = v19;
	}
}

//----- (00414976) --------------------------------------------------------
int __fastcall L4checkRoom(int x, int y, int width, int height)
{
	int v4; // esi
	int v5; // ebx
	char *v6; // edi
	int v8; // [esp+Ch] [ebp-4h]

	v4 = 0;
	if ( x > 0 && y > 0 )
	{
		if ( height <= 0 )
			return 1;
		while ( 1 )
		{
			v8 = 0;
			if ( width > 0 )
				break;
LABEL_12:
			if ( ++v4 >= height )
				return 1;
		}
		v5 = x;
		v6 = &dung[x][v4 + y];
		while ( v5 >= 0 && v5 < 20 && v4 + y >= 0 && v4 + y < 20 && !*v6 )
		{
			++v8;
			v6 += 20;
			++v5;
			if ( v8 >= width )
				goto LABEL_12;
		}
	}
	return 0;
}

//----- (004149E2) --------------------------------------------------------
unsigned char __fastcall DRLG_L4PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, int setview, int ldir)
{
	int v7; // ebx
	int v8; // esi
	int v9; // edi
	int v10; // edx
	int v11; // eax
	int v12; // ecx
	int v13; // esi
	int v14; // ebx
	int v15; // ecx
	int v16; // eax
	int v17; // ecx
	int v18; // eax
	int v19; // ecx
	int v20; // edi
	signed int i; // eax
	int v22; // ecx
	unsigned char v23; // dl
	int v24; // eax
	int v25; // edi
	int v26; // edx
	unsigned char v27; // bl
	unsigned char result; // al
	unsigned char *v29; // [esp+Ch] [ebp-28h]
	int v30; // [esp+10h] [ebp-24h]
	int v31; // [esp+14h] [ebp-20h]
	int v32; // [esp+18h] [ebp-1Ch]
	signed int v33; // [esp+1Ch] [ebp-18h]
	int v34; // [esp+20h] [ebp-14h]
	int v35; // [esp+24h] [ebp-10h]
	int v36; // [esp+28h] [ebp-Ch]
	int max; // [esp+2Ch] [ebp-8h]
	int v38; // [esp+30h] [ebp-4h]
	int v39; // [esp+30h] [ebp-4h]
	int tmaxa; // [esp+3Ch] [ebp+8h]

	v7 = miniset[1];
	v8 = tmin;
	v9 = *miniset;
	v29 = miniset;
	v10 = tmax - tmin;
	v34 = *miniset;
	v35 = miniset[1];
	if ( v10 )
	{
		_LOBYTE(miniset) = 0;
		v30 = v8 + random((int)miniset, v10);
	}
	else
	{
		v30 = 1;
	}
	v31 = 0;
	if ( v30 <= 0 )
	{
		v13 = tmax;
		v14 = v38;
	}
	else
	{
		max = 40 - v9;
		v36 = 40 - v7;
		do
		{
			_LOBYTE(miniset) = 0;
			v11 = random((int)miniset, max);
			_LOBYTE(v12) = 0;
			v13 = v11;
			v33 = 0;
			v14 = random(v12, v36);
			v39 = v14;
			do
			{
				if ( v33 >= 200 )
					return 0;
				tmaxa = 1;
				if ( v13 >= SP4x1 && v13 <= SP4x2 && v14 >= SP4y1 && v14 <= SP4y2 )
					tmaxa = 0;
				if ( cx != -1 )
				{
					v15 = cx - v34;
					if ( v13 >= cx - v34 && v13 <= cx + 12 )
					{
						_LOBYTE(v15) = 0;
						v16 = random(v15, max);
						_LOBYTE(v17) = 0;
						v13 = v16;
						tmaxa = 0;
						v39 = random(v17, v36);
						v14 = v39;
					}
				}
				if ( cy != -1 && v14 >= cy - v35 && v14 <= cy + 12 )
				{
					v18 = random(cy - v35, max);
					_LOBYTE(v19) = 0;
					v13 = v18;
					tmaxa = 0;
					v39 = random(v19, v36);
					v14 = v39;
				}
				v20 = 0;
				for ( i = 2; v20 < v35; ++v20 )
				{
					if ( tmaxa != 1 )
						break;
					v32 = 0;
					if ( v34 > 0 )
					{
						v22 = v14 + v20 + 40 * v13;
						do
						{
							if ( tmaxa != 1 )
								break;
							v23 = v29[i];
							if ( v23 && dungeon[0][v22] != v23 )
								tmaxa = 0;
							if ( dflags[0][v22] )
								tmaxa = 0;
							++i;
							++v32;
							v22 += 40;
						}
						while ( v32 < v34 );
					}
				}
				if ( !tmaxa && ++v13 == max )
				{
					v13 = 0;
					v39 = ++v14;
					if ( v14 == v36 )
					{
						v39 = 0;
						v14 = 0;
					}
				}
				++v33;
			}
			while ( !tmaxa );
			if ( v33 >= 200 )
				return 0;
			v24 = 0;
			for ( miniset = (unsigned char *)(v34 * v35 + 2); v24 < v35; ++v24 )
			{
				v25 = v34;
				if ( v34 > 0 )
				{
					v26 = v14 + v24 + 40 * v13;
					do
					{
						v27 = v29[(_DWORD)miniset];
						if ( v27 )
						{
							dflags[0][v26] |= 8u;
							dungeon[0][v26] = v27;
						}
						++miniset;
						v26 += 40;
						--v25;
					}
					while ( v25 );
					v14 = v39;
				}
			}
			++v31;
		}
		while ( v31 < v30 );
	}
	if ( currlevel == 15 )
	{
		quests[15]._qtx = v13 + 1;
		quests[15]._qty = v14 + 1;
	}
	result = 1;
	if ( setview == 1 )
	{
		ViewX = 2 * v13 + 21;
		ViewY = 2 * v14 + 22;
	}
	if ( !ldir )
	{
		LvlViewX = 2 * v13 + 21;
		LvlViewY = 2 * v14 + 22;
	}
	return result;
}
// 528A40: using guessed type int SP4x2;
// 528A48: using guessed type int SP4y2;
// 5CF320: using guessed type int LvlViewY;
// 5CF324: using guessed type int LvlViewX;

//----- (00414C44) --------------------------------------------------------
void __cdecl DRLG_L4FloodTVal()
{
	int v0; // ebx
	int v1; // esi
	char *v2; // edi
	_BYTE *v3; // [esp+Ch] [ebp-Ch]
	signed int x; // [esp+10h] [ebp-8h]
	signed int i; // [esp+14h] [ebp-4h]

	v0 = 16;
	v1 = 0;
	do
	{
		i = 0;
		x = 16;
		v2 = &dung_map[16][v0];
		v3 = (unsigned char *)dungeon + v1;
		do
		{
			if ( *v3 == 6 && !*v2 )
			{
				DRLG_L4FTVR(i, v1, x, v0, 0);
				++TransVal;
			}
			x += 2;
			v3 += 40;
			v2 += 224;
			++i;
		}
		while ( i < 40 );
		v0 += 2;
		++v1;
	}
	while ( v1 < 40 );
}
// 5A5590: using guessed type char TransVal;

//----- (00414CB3) --------------------------------------------------------
void __fastcall DRLG_L4FTVR(int i, int j, int x, int y, int d)
{
	int v5; // ebx
	int v6; // esi
	int v7; // edi
	int v8; // edx
	int v9; // ecx
	int v10; // ebx
	int v11; // eax
	int v12; // edi
	char v13; // al
	char v14; // al
	int v15; // ecx
	int v16; // ecx
	int v17; // ecx
	int v18; // ecx
	int v19; // [esp+Ch] [ebp-14h]
	int k; // [esp+10h] [ebp-10h]
	int v21; // [esp+14h] [ebp-Ch]
	int ja; // [esp+18h] [ebp-8h]
	int ia; // [esp+1Ch] [ebp-4h]
	int ya; // [esp+2Ch] [ebp+Ch]

	v5 = x;
	v6 = y;
	v7 = j;
	v8 = i;
	v9 = 112 * x + y;
	ja = v7;
	v21 = v8;
	if ( !dung_map[0][v9] )
	{
		v19 = x;
		ia = v8 - 1;
		v10 = x - 2;
		v11 = 40 * v8;
		ya = v7 - 1;
		v12 = v6 - 2;
		for ( k = 40 * v8; dungeon[0][v11 + ja] == 6; v11 = k )
		{
			v13 = TransVal;
			dung_map[0][v9] = TransVal;
			dung_map[1][v9] = v13;
			dung_map[0][v9 + 1] = v13;
			dung_map[1][v9 + 1] = v13;
			DRLG_L4FTVR(ia + 2, ja, v10 + 4, v6, 1);
			DRLG_L4FTVR(ia, ja, v10, v6, 2);
			DRLG_L4FTVR(v21, ya + 2, x, v12 + 4, 3);
			DRLG_L4FTVR(v21, ya, x, v12, 4);
			DRLG_L4FTVR(ia, ya, v10, v12, 5);
			DRLG_L4FTVR(ia + 2, ya, v10 + 4, v12, 6);
			DRLG_L4FTVR(ia, ya + 2, v10, v12 + 4, 7);
			v19 += 2;
			k += 40;
			d = 8;
			x += 2;
			v6 += 2;
			v12 += 2;
			v10 += 2;
			++ja;
			++ya;
			++v21;
			++ia;
			v9 = v19 * 112 + v6;
			if ( dung_map[v19][v6] )
				break;
		}
		v5 = x;
	}
	v14 = TransVal;
	if ( d == 1 )
	{
		v15 = v6 + 112 * v5;
		dung_map[0][v15] = TransVal;
		dung_map[0][v15 + 1] = v14;
	}
	if ( d == 2 )
	{
		v16 = v6 + 112 * v5;
		dung_map[1][v16] = v14;
		dung_map[1][v16 + 1] = v14;
	}
	if ( d == 3 )
	{
		v17 = v6 + 112 * v5;
		dung_map[0][v17] = v14;
		dung_map[1][v17] = v14;
	}
	if ( d == 4 )
	{
		v18 = v6 + 112 * v5;
		dung_map[0][v18 + 1] = v14;
		dung_map[1][v18 + 1] = v14;
	}
	if ( d == 5 )
		dung_map[v5 + 1][v6 + 1] = v14;
	if ( d == 6 )
		dung_map[v5][v6 + 1] = v14;
	if ( d == 7 )
		dung_map[v5 + 1][v6] = v14;
	if ( d == 8 )
		dung_map[v5][v6] = v14;
}
// 5A5590: using guessed type char TransVal;

//----- (00414EA3) --------------------------------------------------------
void __cdecl DRLG_L4TransFix()
{
	signed int v0; // edi
	char *v1; // esi
	signed int v2; // ebx
	int v3; // eax
	_BYTE *v4; // edx
	char v5; // cl
	char v6; // al
	int v7; // eax
	_BYTE *v8; // edx
	char v9; // cl
	char v10; // al
	char v11; // al
	char v12; // al
	char v13; // al
	char v14; // al
	char v15; // al
	char *v16; // [esp+Ch] [ebp-4h]

	v0 = 0;
	v16 = &dung_map[17][17];
	do
	{
		v1 = (char *)dungeon + v0;
		v2 = 40;
		do
		{
			_LOBYTE(v3) = IsDURWall(*v1);
			if ( v3 && *(v1 - 1) == 18 )
			{
				v6 = *(v4 - 113);
				*(v4 - 1) = v6;
				*v4 = v6;
			}
			_LOBYTE(v7) = IsDLLWall(v5);
			if ( v7 && v1[40] == 19 )
			{
				v10 = *(v8 - 113);
				*(v8 - 112) = v10;
				*v8 = v10;
			}
			if ( v9 == 18 )
			{
				v11 = *(v8 - 113);
				*(v8 - 1) = v11;
				*v8 = v11;
			}
			if ( v9 == 19 )
			{
				v12 = *(v8 - 113);
				*(v8 - 112) = v12;
				*v8 = v12;
			}
			if ( v9 == 24 )
			{
				v13 = *(v8 - 113);
				*(v8 - 1) = v13;
				*(v8 - 112) = v13;
				*v8 = v13;
			}
			if ( v9 == 57 )
			{
				v14 = *(v8 - 112);
				*(v8 - 225) = v14;
				*(v8 - 113) = v14;
			}
			if ( v9 == 53 )
			{
				v15 = *(v8 - 1);
				*(v8 - 114) = v15;
				*(v8 - 113) = v15;
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		v16 += 2;
		++v0;
	}
	while ( v0 < 40 );
}

//----- (00414F5B) --------------------------------------------------------
void __cdecl DRLG_L4Corners()
{
	signed int v0; // edx
	char *v1; // ecx
	signed int v2; // esi
	char v3; // al

	v0 = 1;
	do
	{
		v1 = &dungeon[1][v0];
		v2 = 38;
		do
		{
			v3 = *v1;
			if ( (unsigned char)*v1 >= 0x12u
			  && (unsigned char)v3 <= 0x1Eu
			  && ((unsigned char)v1[40] < 0x12u || (unsigned char)v1[1] < 0x12u) )
			{
				*v1 = v3 + 98;
			}
			v1 += 40;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 39 );
}

//----- (00414F90) --------------------------------------------------------
void __cdecl DRLG_L4Pass3()
{
	int v0; // eax
	int *v1; // esi
	int *v2; // eax
	signed int v3; // ecx
	signed int v4; // ebx
	int *v5; // ecx
	unsigned char *v6; // edi
	unsigned short *v7; // esi
	unsigned short v8; // ax
	int v9; // eax
	signed int v10; // [esp+Ch] [ebp-1Ch]
	int *v11; // [esp+10h] [ebp-18h]
	int v12; // [esp+14h] [ebp-14h]
	int v13; // [esp+18h] [ebp-10h]
	int v14; // [esp+18h] [ebp-10h]
	int v15; // [esp+1Ch] [ebp-Ch]
	int v16; // [esp+1Ch] [ebp-Ch]
	int v17; // [esp+20h] [ebp-8h]
	int v18; // [esp+20h] [ebp-8h]
	int v19; // [esp+24h] [ebp-4h]
	int v20; // [esp+24h] [ebp-4h]

	v0 = *((unsigned short *)pMegaTiles + 116) + 1;
	v19 = *((unsigned short *)pMegaTiles + 116) + 1;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 117);
	v17 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 118);
	v15 = ++v0;
	_LOWORD(v0) = *((_WORD *)pMegaTiles + 119);
	v13 = v0 + 1;
	v1 = dPiece[1];
	do
	{
		v2 = v1;
		v3 = 56;
		do
		{
			*(v2 - 112) = v19;
			*v2 = v17;
			*(v2 - 111) = v15;
			v2[1] = v13;
			v2 += 224;
			--v3;
		}
		while ( v3 );
		v1 += 2;
	}
	while ( (signed int)v1 < (signed int)dPiece[2] );
	v4 = 0;
	v11 = &dPiece[17][16];
	do
	{
		v5 = v11;
		v6 = (unsigned char *)dungeon + v4;
		v10 = 40;
		do
		{
			v12 = *v6 - 1;
			if ( v12 < 0 )
			{
				v20 = 0;
				v18 = 0;
				v16 = 0;
				v14 = 0;
			}
			else
			{
				v7 = (unsigned short *)((char *)pMegaTiles + 8 * v12);
				v8 = *v7;
				++v7;
				v9 = v8 + 1;
				v20 = v9;
				_LOWORD(v9) = *v7;
				++v7;
				v18 = ++v9;
				_LOWORD(v9) = *v7;
				v16 = ++v9;
				_LOWORD(v9) = v7[1];
				v14 = v9 + 1;
			}
			v6 += 40;
			*(v5 - 112) = v20;
			*v5 = v18;
			*(v5 - 111) = v16;
			v5[1] = v14;
			v5 += 224;
			--v10;
		}
		while ( v10 );
		v11 += 2;
		++v4;
	}
	while ( v4 < 40 );
}

//----- (0041509D) --------------------------------------------------------
void __cdecl dthread_cpp_init_1()
{
	dthread_cpp_init_value = dthread_inf;
}
// 47A460: using guessed type int dthread_inf;
// 52A4E0: using guessed type int dthread_cpp_init_value;

//----- (004150A8) --------------------------------------------------------
void __cdecl dthread_cpp_init_2()
{
	dthread_init_mutex();
	dthread_cleanup_mutex_atexit();
}

//----- (004150B2) --------------------------------------------------------
void __cdecl dthread_init_mutex()
{
	InitializeCriticalSection(&CriticalSection);
}

//----- (004150BE) --------------------------------------------------------
void __cdecl dthread_cleanup_mutex_atexit()
{
	atexit(dthread_cleanup_mutex);
}

//----- (004150CA) --------------------------------------------------------
void __cdecl dthread_cleanup_mutex()
{
	DeleteCriticalSection(&CriticalSection);
}

//----- (004150D6) --------------------------------------------------------
void __fastcall dthread_remove_player(int player_num)
{
	int v1; // edi
	_DWORD *i; // eax

	v1 = player_num;
	EnterCriticalSection(&CriticalSection);
	for ( i = (_DWORD *)sgpInfoHead; i; i = (_DWORD *)*i )
	{
		if ( i[1] == v1 )
			i[1] = 4;
	}
	LeaveCriticalSection(&CriticalSection);
}

//----- (00415109) --------------------------------------------------------
void __fastcall dthread_send_delta(int player_num, int cmd, void *src, int len)
{
	char v4; // bl
	_DWORD *v5; // eax
	int v6; // esi
	int *v7; // eax
	int *v8; // ecx
	int v9; // [esp+4h] [ebp-4h]

	v4 = cmd;
	v9 = player_num;
	if ( gbMaxPlayers != 1 )
	{
		v5 = (unsigned int *)DiabloAllocPtr(len + 20);
		v6 = (int)v5;
		*v5 = 0;
		v5[1] = v9;
		*((_BYTE *)v5 + 8) = v4;
		v5[3] = len;
		memcpy(v5 + 4, src, len);
		EnterCriticalSection(&CriticalSection);
		v7 = (int *)sgpInfoHead;
		v8 = &sgpInfoHead;
		while ( v7 )
		{
			v8 = v7;
			v7 = (int *)*v7;
		}
		*v8 = v6;
		SetEvent(sghWorkToDoEvent);
		LeaveCriticalSection(&CriticalSection);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00415186) --------------------------------------------------------
void __cdecl dthread_start()
{
	char *v0; // eax
	char *v1; // eax

	if ( gbMaxPlayers != 1 )
	{
		sghWorkToDoEvent = CreateEventA(0, 1, 0, 0);
		if ( !sghWorkToDoEvent )
		{
			v0 = GetLastErr();
			TermMsg("dthread:1\n%s", v0);
		}
		byte_52A508 = 1;
		sghThread = (HANDLE)_beginthreadex(0, 0, dthread_handler, 0, 0, &ThreadId);
		if ( sghThread == (HANDLE)-1 )
		{
			v1 = GetLastErr();
			TermMsg("dthread2:\n%s", v1);
		}
	}
}
// 52A508: using guessed type char byte_52A508;
// 679660: using guessed type char gbMaxPlayers;

//----- (004151F3) --------------------------------------------------------
unsigned int __stdcall dthread_handler(void *a1)
{
	char *v1; // eax
	int v2; // esi
	int v3; // ecx
	unsigned int v4; // edi

	while ( byte_52A508 )
	{
		if ( !sgpInfoHead && WaitForSingleObject(sghWorkToDoEvent, 0xFFFFFFFF) == -1 )
		{
			v1 = GetLastErr();
			TermMsg("dthread4:\n%s", v1);
		}
		EnterCriticalSection(&CriticalSection);
		v2 = sgpInfoHead;
		if ( sgpInfoHead )
			sgpInfoHead = *(_DWORD *)sgpInfoHead;
		else
			ResetEvent(sghWorkToDoEvent);
		LeaveCriticalSection(&CriticalSection);
		if ( v2 )
		{
			v3 = *(_DWORD *)(v2 + 4);
			if ( v3 != 4 )
				multi_send_zero_packet(v3, *(_BYTE *)(v2 + 8), (void *)(v2 + 16), *(_DWORD *)(v2 + 12));
			v4 = 1000 * *(_DWORD *)(v2 + 12) / (unsigned int)gdwDeltaBytesSec;
			if ( v4 >= 1 )
				v4 = 1;
			mem_free_dbg((void *)v2);
			if ( v4 )
				Sleep(v4);
		}
	}
	return 0;
}
// 52A508: using guessed type char byte_52A508;
// 679730: using guessed type int gdwDeltaBytesSec;

//----- (004152C0) --------------------------------------------------------
void __cdecl dthread_cleanup()
{
	char *v0; // eax
	int *v1; // eax
	int v2; // esi

	if ( sghWorkToDoEvent )
	{
		byte_52A508 = 0;
		SetEvent(sghWorkToDoEvent);
		if ( sghThread != (HANDLE)-1 && ThreadId != GetCurrentThreadId() )
		{
			if ( WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1 )
			{
				v0 = GetLastErr();
				TermMsg("dthread3:\n(%s)", v0);
			}
			CloseHandle(sghThread);
			sghThread = (HANDLE)-1;
		}
		CloseHandle(sghWorkToDoEvent);
		v1 = (int *)sgpInfoHead;
		sghWorkToDoEvent = 0;
		if ( sgpInfoHead )
		{
			do
			{
				v2 = *v1;
				sgpInfoHead = 0;
				mem_free_dbg(v1);
				v1 = (int *)v2;
				sgpInfoHead = v2;
			}
			while ( v2 );
		}
	}
}
// 52A508: using guessed type char byte_52A508;

//----- (00415367) --------------------------------------------------------
void __cdecl dx_cpp_init_1()
{
	dx_cpp_init_value = dx_inf;
}
// 47A464: using guessed type int dx_inf;
// 52A514: using guessed type int dx_cpp_init_value;

//----- (00415372) --------------------------------------------------------
void __cdecl dx_cpp_init_2()
{
	dx_init_mutex();
	dx_cleanup_mutex_atexit();
}

//----- (0041537C) --------------------------------------------------------
void __cdecl dx_init_mutex()
{
	InitializeCriticalSection(&stru_52A530);
}

//----- (00415388) --------------------------------------------------------
void __cdecl dx_cleanup_mutex_atexit()
{
	atexit(dx_cleanup_mutex);
}

//----- (00415394) --------------------------------------------------------
void __cdecl dx_cleanup_mutex()
{
	DeleteCriticalSection(&stru_52A530);
}

//----- (004153A0) --------------------------------------------------------
void __fastcall dx_init(HWND hWnd)
{
	HWND v1; // esi
	GUID *v2; // ecx
	int v3; // eax
	int v4; // eax
	int v5; // ecx
	int v6; // edi
	int v7; // eax
	int v8; // eax
	HWND hWnda; // [esp+1Ch] [ebp-4h]

	v1 = hWnd;
	hWnda = hWnd;
	SetFocus(hWnd);
	ShowWindow(v1, 1);
	v2 = 0;
	if ( gbEmulate )
		v2 = (GUID *)2;
	v3 = dx_DirectDrawCreate(v2, (IDirectDraw **)&lpDDPPrimary, 0);
	if ( v3 )
		TermDlg(104, v3, "C:\\Src\\Diablo\\Source\\dx.cpp", 149);
	exclusive = 1;
	v4 = IDirectDrawPalette_SetEntries(
			 (IDirectDrawPalette *)lpDDPPrimary,
			 (unsigned long)v1,
			 19, 0, 0);
	if ( v4 == -2005532091 )
	{
		MI_Dummy(v5);
	}
	else if ( v4 )
	{
		TermDlg(104, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 170);
	}
	int xyz=640;
	if ( lpDDPPrimary->QueryInterface(
			 (const struct _GUID &)xyz,
			 (void **)480) )
	{
		v6 = GetSystemMetrics(0);
		v7 = GetSystemMetrics(1);
		v8 = lpDDPPrimary->QueryInterface(
				 (const struct _GUID &)v6,
				 (void **)v7);
		if ( v8 )
			TermDlg(104, v8, "C:\\Src\\Diablo\\Source\\dx.cpp", 183);
	}
	dx_create_primary_surface();
	palette_init();
	GdiSetBatchLimit(1u);
	dx_create_back_buffer();
	SDrawManualInitialize(hWnda, (IDirectDraw *)lpDDPPrimary, lpDDSPrimary, 0, 0, lpDDSBackBuf, (IDirectDrawPalette *)lpDDPRed, 0);
}
// 484364: using guessed type int exclusive;
// 52A549: using guessed type char gbEmulate;

//----- (004154B5) --------------------------------------------------------
void __cdecl dx_create_back_buffer()
{
	int v0; // eax
	int v1; // eax
	int v2; // eax
	int v3; // eax
	int v4; // [esp+Ch] [ebp-70h]
	int v5; // [esp+10h] [ebp-6Ch]
	int v6; // [esp+14h] [ebp-68h]
	int v7; // [esp+18h] [ebp-64h]
	int v8[14]; // [esp+1Ch] [ebp-60h]
	int v9[8]; // [esp+54h] [ebp-28h]
	int v10; // [esp+74h] [ebp-8h]
	char v11; // [esp+78h] [ebp-4h]

	v0 = IDirectDrawSurface_GetCaps(lpDDSPrimary, (LPDDSCAPS)&v11);
	if ( v0 )
		DDErrDlg(v0, 59, "C:\\Src\\Diablo\\Source\\dx.cpp");
	if ( !gbBackBuf )
	{
		v4 = 108;
		v1 = IDirectDrawSurface_Lock(lpDDSPrimary, 0, (LPDDSURFACEDESC)&v4, 33, 0);
		if ( !v1 )
		{
			IDirectDrawSurface_Unlock(lpDDSPrimary, 0);
			sgpBackBuf = DiabloAllocPtr(503808);
			return;
		}
		if ( v1 != -2005532237 )
			TermDlg(104, v1, "C:\\Src\\Diablo\\Source\\dx.cpp", 81);
	}
	memset(&v4, 0, 0x6Cu);
	v7 = 768;
	v8[0] = 768;
	v4 = 108;
	v5 = 4111;
	v10 = 2112;
	v6 = 656;
	v9[0] = 32;
	v2 = IDirectDrawSurface_GetPixelFormat(lpDDSPrimary, (LPDDPIXELFORMAT)v9);
	if ( v2 )
		TermDlg(104, v2, "C:\\Src\\Diablo\\Source\\dx.cpp", 94);
	v3 = lpDDPPrimary->SetEntries(
			 (unsigned long)&v4,
			 (unsigned long)&lpDDSBackBuf,
			 0, 0);
	if ( v3 )
		TermDlg(104, v3, "C:\\Src\\Diablo\\Source\\dx.cpp", 96);
}
// 52A548: using guessed type char gbBackBuf;

//----- (004155C2) --------------------------------------------------------
void __cdecl dx_create_primary_surface()
{
	int v0; // eax
	int v1; // [esp+0h] [ebp-6Ch]
	int v2[25]; // [esp+4h] [ebp-68h]
	int v3; // [esp+68h] [ebp-4h]

	memset(&v1, 0, 0x6Cu);
	v1 = 108;
	v2[0] = 1;
	v3 = 512;
	v0 = lpDDPPrimary->SetEntries(
			 (unsigned long)&v1,
			 (unsigned long)&lpDDSPrimary,
			 0, 0);
	if ( v0 )
		TermDlg(104, v0, "C:\\Src\\Diablo\\Source\\dx.cpp", 109);
}

//----- (0041561A) --------------------------------------------------------
HRESULT __fastcall dx_DirectDrawCreate(GUID *guid, IDirectDraw **DD, void *unknown)
{
	IDirectDraw **v3; // ebp
	int v4; // eax
	FARPROC v5; // ebx
	int v6; // eax
	GUID *v8; // [esp+10h] [ebp-4h]

	v3 = DD;
	v8 = guid;
	if ( !hModule )
	{
		hModule = LoadLibraryA("ddraw.dll");
		if ( !hModule )
		{
			v4 = GetLastError();
			TermDlg(107, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 122);
		}
	}
	v5 = GetProcAddress(hModule, "DirectDrawCreate");
	if ( !v5 )
	{
		v6 = GetLastError();
		TermDlg(107, v6, "C:\\Src\\Diablo\\Source\\dx.cpp", 127);
	}
	return ((int (__stdcall *)(GUID *, IDirectDraw **, void *))v5)(v8, v3, unknown);
}

//----- (0041569A) --------------------------------------------------------
void __cdecl dx_lock_mutex()
{
	Screen *v0; // eax
	int v1; // eax
	int v2[9]; // [esp+0h] [ebp-6Ch]
	int v3[18]; // [esp+24h] [ebp-48h]

	EnterCriticalSection(&stru_52A530);
	v0 = (Screen *)sgpBackBuf;
	if ( sgpBackBuf )
		goto LABEL_8;
	if ( lpDDSBackBuf )
	{
		if ( sgdwLockCount )
			goto LABEL_9;
		v2[0] = 108;
		v1 = IDirectDrawSurface_Lock(lpDDSBackBuf, 0, (LPDDSURFACEDESC)v2, 1, 0);
		if ( v1 )
			DDErrDlg(v1, 235, "C:\\Src\\Diablo\\Source\\dx.cpp");
		v0 = (Screen *)v3[0];
		screen_buf_end += v3[0];
LABEL_8:
		gpBuffer = v0;
		goto LABEL_9;
	}
	Sleep(0x4E20u);
	TermMsg("lock_buf_priv");
LABEL_9:
	++sgdwLockCount;
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (00415725) --------------------------------------------------------
void __cdecl dx_unlock_mutex()
{
	Screen *v0; // eax
	int v1; // eax

	if ( !sgdwLockCount )
		TermMsg("draw main unlock error");
	if ( !gpBuffer )
		TermMsg("draw consistency error");
	if ( !--sgdwLockCount )
	{
		v0 = gpBuffer;
		gpBuffer = 0;
		screen_buf_end -= (signed int)v0;
		if ( !sgpBackBuf )
		{
			v1 = IDirectDrawSurface_Unlock(lpDDSBackBuf, 0);
			if ( v1 )
				DDErrDlg(v1, 273, "C:\\Src\\Diablo\\Source\\dx.cpp");
		}
	}
	LeaveCriticalSection(&stru_52A530);
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (004157A0) --------------------------------------------------------
void __cdecl dx_cleanup()
{
	void *v0; // ecx

	if ( ghMainWnd )
		ShowWindow(ghMainWnd, 0);
	SDrawDestroy();
	EnterCriticalSection(&stru_52A530);
	if ( sgpBackBuf )
	{
		v0 = sgpBackBuf;
		sgpBackBuf = 0;
		mem_free_dbg(v0);
	}
	else if ( lpDDSBackBuf )
	{
		IDirectDrawSurface_Release(lpDDSBackBuf);
		lpDDSBackBuf = 0;
	}
	sgdwLockCount = 0;
	gpBuffer = 0;
	LeaveCriticalSection(&stru_52A530);
	if ( lpDDSPrimary )
	{
		IDirectDrawSurface_Release(lpDDSPrimary);
		lpDDSPrimary = 0;
	}
	if ( lpDDPRed )
	{
		IDirectDrawSurface_Release(lpDDPRed);
		lpDDPRed = 0;
	}
	if ( lpDDPPrimary )
	{
		IDirectDrawSurface_Release(lpDDPPrimary);
		lpDDPPrimary = 0;
	}
}

//----- (00415848) --------------------------------------------------------
void __cdecl dx_reinit()
{
	int v0; // esi

	EnterCriticalSection(&stru_52A530);
	ClearCursor();
	v0 = sgdwLockCount;
	while ( sgdwLockCount )
		dx_unlock_mutex();
	dx_cleanup();
	force_redraw = 255;
	dx_init(ghMainWnd);
	for ( ; v0; --v0 )
		dx_lock_mutex();
	LeaveCriticalSection(&stru_52A530);
}
// 52571C: using guessed type int force_redraw;

//----- (004158AE) --------------------------------------------------------
void __cdecl effects_cpp_init()
{
	effects_cpp_init_value = effects_inf;
}
// 47A468: using guessed type int effects_inf;
// 52A550: using guessed type int effects_cpp_init_value;

//----- (004158B9) --------------------------------------------------------
bool __fastcall effect_is_playing(int nSFX)
{
	TSFX *v1; // eax
	TSnd *v2; // ecx

	v1 = &sgSFX[nSFX];
	v2 = (TSnd *)v1->Channel;
	if ( v2 )
		return snd_playing(v2);
	if ( v1->bFlags & 1 )
		return v1 == sfx_data_cur;
	return 0;
}

//----- (004158E2) --------------------------------------------------------
void __cdecl sfx_stop()
{
	if ( sfx_stream )
	{
		SFileDdaEnd(sfx_stream);
		SFileCloseFile(sfx_stream);
		sfx_stream = 0;
		sfx_data_cur = 0;
	}
}

//----- (0041590B) --------------------------------------------------------
void __fastcall InitMonsterSND(int monst)
{
	signed int v1; // ebx
	int v2; // eax
	TSnd **v3; // esi
	int v4; // edi
	size_t v5; // eax
	TSnd *v6; // eax
	char v7[260]; // [esp+0h] [ebp-110h]
	int v8; // [esp+104h] [ebp-Ch]
	int v9; // [esp+108h] [ebp-8h]
	void *ptr; // [esp+10Ch] [ebp-4h]

	v8 = monst;
	if ( gbSndInited )
	{
		v1 = 0;
		v9 = (unsigned char)Monsters[monst].mtype << 7;
		do
		{
			if ( monster_action_sounds[v1] != 115 || *(int *)((char *)&monsterdata[0].snd_special + v9) )
			{
				v2 = 0;
				v3 = &Monsters[0].Snds[2 * (v1 + 41 * v8)];
				do
				{
					v4 = v2 + 1;
					sprintf(
						v7,
						*(const char **)((char *)&monsterdata[0].sndfile + v9),
						monster_action_sounds[v1],
						v2 + 1);
					v5 = strlen(v7);
					ptr = DiabloAllocPtr(v5 + 1);
					strcpy((char *)ptr, v7);
					v6 = sound_file_load((char *)ptr);
					*v3 = v6;
					if ( !v6 )
						mem_free_dbg(ptr);
					v2 = v4;
					++v3;
				}
				while ( v4 < 2 );
			}
			++v1;
		}
		while ( v1 < 4 );
	}
}

//----- (004159DB) --------------------------------------------------------
void __cdecl FreeEffects()
{
	TSnd **v0; // esi
	signed int v1; // ebp
	signed int v2; // ebx
	TSnd *v3; // ecx
	void *v4; // edi
	TSnd **v5; // [esp+0h] [ebp-8h]
	int v6; // [esp+4h] [ebp-4h]

	v6 = 0;
	if ( nummtypes > 0 )
	{
		v5 = Monsters[0].Snds;
		do
		{
			v0 = v5;
			v1 = 4;
			do
			{
				v2 = 2;
				do
				{
					v3 = *v0;
					if ( *v0 )
					{
						*v0 = 0;
						v4 = (void *)v3->sound_path;
						v3->sound_path = 0;
						sound_file_cleanup(v3);
						mem_free_dbg(v4);
					}
					++v0;
					--v2;
				}
				while ( v2 );
				--v1;
			}
			while ( v1 );
			++v6;
			v5 += 82;
		}
		while ( v6 < nummtypes );
	}
}

//----- (00415A45) --------------------------------------------------------
void __fastcall PlayEffect(int i, int mode)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax
	int v5; // esi
	int v6; // eax
	TSnd *v7; // edi
	int v8; // eax
	int volume_delta; // [esp+8h] [ebp-8h]
	int pan; // [esp+Ch] [ebp-4h]

	v2 = mode;
	v3 = i;
	if ( !plr[myplr].pLvlLoad )
	{
		_LOBYTE(i) = -92;
		v4 = random(i, 2);
		if ( gbSndInited )
		{
			if ( gbSoundOn )
			{
				if ( !gbBufferMsgs )
				{
					v5 = v3;
					v6 = v4 + 2 * (v2 + 41 * monster[v5]._mMTidx);
					v7 = Monsters[0].Snds[v6];
					if ( v7 )
					{
						_LOBYTE(v8) = snd_playing(Monsters[0].Snds[v6]);
						if ( !v8 )
						{
							if ( calc_snd_position(monster[v5]._mx, monster[v5]._my, &volume_delta, &pan) )
								snd_play_snd(v7, volume_delta, pan);
						}
					}
				}
			}
		}
	}
}
// 4A22D5: using guessed type char gbSoundOn;
// 676194: using guessed type char gbBufferMsgs;

//----- (00415AE1) --------------------------------------------------------
int __fastcall calc_snd_position(int x, int y, int *plVolume, int *plPan)
{
	int v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // ebx
	int v8; // eax
	int v9; // eax

	v4 = x - plr[myplr].WorldX;
	v5 = y - plr[myplr].WorldY;
	v6 = (v4 - v5) << 8;
	*plPan = v6;
	if ( abs(v6) > 6400 )
		return 0;
	v7 = abs(v4);
	v8 = v7 <= abs(v5) ? abs(v5) : abs(v4);
	v9 = v8 << 6;
	*plVolume = v9;
	if ( v9 >= 6400 )
		return 0;
	*plVolume = -v9;
	return 1;
}

//----- (00415B59) --------------------------------------------------------
void __fastcall PlaySFX(int psfx)
{
	int v1; // eax

	v1 = RndSFX(psfx);
	PlaySFX_priv(&sgSFX[v1], 0, 0, 0);
}

//----- (00415B71) --------------------------------------------------------
void __fastcall PlaySFX_priv(TSFX *pSFX, char loc, int x, int y)
{
	int v4; // edi
	TSFX *v5; // esi
	TSnd *v6; // ecx
	int v7; // eax
	TSnd *v8; // ecx
	int volume_delta; // [esp+Ch] [ebp-8h]
	int pan; // [esp+10h] [ebp-4h]

	v4 = loc;
	v5 = pSFX;
	if ( !plr[myplr].pLvlLoad || gbMaxPlayers == 1 )
	{
		if ( gbSndInited )
		{
			if ( gbSoundOn )
			{
				if ( !gbBufferMsgs )
				{
					if ( pSFX->bFlags & 3 || (v6 = (TSnd *)pSFX->Channel) == 0 || (_LOBYTE(v7) = snd_playing(v6), !v7) )
					{
						pan = 0;
						volume_delta = 0;
						if ( !v4 || calc_snd_position(x, y, &volume_delta, &pan) )
						{
							if ( v5->bFlags & 1 )
							{
								stream_play(v5, volume_delta, pan);
							}
							else
							{
								if ( !v5->Channel )
									v5->Channel = (int)sound_file_load(v5->pszName);
								v8 = (TSnd *)v5->Channel;
								if ( v8 )
									snd_play_snd(v8, volume_delta, pan);
							}
						}
					}
				}
			}
		}
	}
}
// 4A22D5: using guessed type char gbSoundOn;
// 676194: using guessed type char gbBufferMsgs;
// 679660: using guessed type char gbMaxPlayers;

//----- (00415C2A) --------------------------------------------------------
void __fastcall stream_play(TSFX *pSFX, int lVolume, int lPan)
{
	int v3; // esi
	TSFX *v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // eax

	v3 = lVolume;
	v4 = pSFX;
	sfx_stop();
	v5 = sound_get_or_set_sound_volume(1) + v3;
	if ( v5 >= -1600 )
	{
		if ( v5 > 0 )
			v5 = 0;
		_LOBYTE(v6) = SFileOpenFile(v4->pszName, &sfx_stream);
		if ( v6 )
		{
			_LOBYTE(v7) = SFileDdaBeginEx(sfx_stream, 0x40000, 0, 0, v5, lPan, 0);
			if ( v7 )
				sfx_data_cur = v4;
			else
				sfx_stop();
		}
		else
		{
			sfx_stream = 0;
		}
	}
}

//----- (00415C97) --------------------------------------------------------
int __fastcall RndSFX(int psfx)
{
	int v1; // esi
	int v3; // [esp-4h] [ebp-8h]

	v1 = psfx;
	switch ( psfx )
	{
		case PS_WARR69:
			goto LABEL_12;
		case PS_WARR14:
		case PS_WARR15:
		case PS_WARR16:
			goto LABEL_19;
		case PS_MAGE69:
		case PS_ROGUE69:
		case PS_SWING:
		case LS_ACID:
		case IS_FMAG:
		case IS_MAGIC:
		case IS_BHIT:
LABEL_12:
			v3 = 2;
LABEL_15:
			_LOBYTE(psfx) = -91;
			return v1 + random(psfx, v3);
		case PS_WARR2:
LABEL_19:
			v3 = 3;
			goto LABEL_15;
	}
	return psfx;
}

//----- (00415D01) --------------------------------------------------------
void __fastcall PlaySfxLoc(int psfx, int x, int y)
{
	int v3; // esi
	int v4; // eax
	int v5; // ecx

	v3 = x;
	v4 = RndSFX(psfx);
	if ( v4 >= 0 && v4 <= 3 )
	{
		v5 = sgSFX[v4].Channel;
		if ( v5 )
			*(_DWORD *)(v5 + 36) = 0;
	}
	PlaySFX_priv(&sgSFX[v4], 1, v3, y);
}

//----- (00415D39) --------------------------------------------------------
void __cdecl FreeMonsterSnd()
{
	TSnd **v0; // esi
	signed int v1; // ebx
	signed int v2; // edi
	int v3; // [esp+0h] [ebp-8h]
	TSnd **v4; // [esp+4h] [ebp-4h]

	snd_update(1);
	sfx_stop();
	sound_stop();
	v3 = 0;
	if ( nummtypes > 0 )
	{
		v4 = Monsters[0].Snds;
		do
		{
			v0 = v4;
			v1 = 4;
			do
			{
				v2 = 2;
				do
				{
					snd_stop_snd(*v0);
					++v0;
					--v2;
				}
				while ( v2 );
				--v1;
			}
			while ( v1 );
			++v3;
			v4 += 82;
		}
		while ( v3 < nummtypes );
	}
}

//----- (00415D9A) --------------------------------------------------------
void __cdecl sound_stop()
{
	TSnd **v0; // esi
	signed int v1; // edi

	v0 = (TSnd **)&sgSFX[0].Channel;
	v1 = 858;
	do
	{
		if ( *v0 )
			snd_stop_snd(*v0);
		v0 = (TSnd **)((char *)v0 + 9);
		--v1;
	}
	while ( v1 );
}

//----- (00415DBA) --------------------------------------------------------
void __cdecl sound_update()
{
	int v0; // ebp
	unsigned int v1; // ecx
	int v2; // eax
	unsigned int v3; // [esp-Ch] [ebp-Ch]
	unsigned int v4; // [esp-8h] [ebp-8h]
	int v5; // [esp-4h] [ebp-4h]

	if ( gbSndInited )
	{
		snd_update(0);
		v5 = v0;
		v4 = v1;
		v3 = v1;
		if ( sfx_stream )
		{
			_LOBYTE(v2) = SFileDdaGetPos(sfx_stream, (int)&v4, (int)&v3);
			if ( v2 )
			{
				if ( v4 >= v3 )
					sfx_stop();
			}
		}
	}
}
// 415DBA: could not find valid save-restore pair for ebp

//----- (00415DFF) --------------------------------------------------------
void __cdecl effects_cleanup_sfx()
{
	unsigned int v0; // edi
	TSnd *v1; // ecx

	FreeMonsterSnd();
	v0 = 0;
	do
	{
		v1 = (TSnd *)sgSFX[v0].Channel;
		if ( v1 )
		{
			sound_file_cleanup(v1);
			sgSFX[v0].Channel = 0;
		}
		++v0;
	}
	while ( v0 < 858 );
}

//----- (00415E2A) --------------------------------------------------------
void __cdecl stream_update()
{
	char v0; // bl
	char v1; // al

	v0 = 0;
	if ( (unsigned char)gbMaxPlayers <= 1u )
	{
		v1 = plr[myplr]._pClass;
		if ( v1 )
		{
			if ( v1 == 1 )
			{
				v0 = 16;
			}
			else if ( v1 == 2 )
			{
				v0 = 64;
			}
			else
			{
				TermMsg("effects:1");
			}
		}
		else
		{
			v0 = 32;
		}
	}
	else
	{
		v0 = 112;
	}
	priv_sound_init(v0);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00415E77) --------------------------------------------------------
void __fastcall priv_sound_init(int bLoadMask)
{
	unsigned char v1; // bl
	unsigned char v2; // cl
	unsigned int v3; // esi
	unsigned char v4; // al
	TSnd *v5; // eax
	unsigned char v6; // [esp+0h] [ebp-4h]

	if ( gbSndInited )
	{
		v1 = bLoadMask & 0x70;
		v2 = bLoadMask & 0x70 ^ bLoadMask;
		v3 = 0;
		v6 = v2;
		do
		{
			if ( !sgSFX[v3].Channel )
			{
				v4 = sgSFX[v3].bFlags;
				if ( !(v4 & 1) && (!v2 || v4 & v2) && (!(v4 & 0x70) || v4 & v1) )
				{
					v5 = sound_file_load(sgSFX[v3].pszName);
					v2 = v6;
					sgSFX[v3].Channel = (int)v5;
				}
			}
			++v3;
		}
		while ( v3 < 858 );
	}
}

//----- (00415ED8) --------------------------------------------------------
void __cdecl sound_init()
{
	priv_sound_init(4);
}

//----- (00415EDF) --------------------------------------------------------
void __stdcall effects_play_sound(char *snd_file)
{
	int v1; // edi
	unsigned int v2; // esi
	TSnd **v3; // esi
	int v4; // eax

	if ( gbSndInited && gbSoundOn )
	{
		v1 = 0;
		v2 = 0;
		while ( _strcmpi(sgSFX[v2].pszName, snd_file) || !sgSFX[v2].Channel )
		{
			++v2;
			++v1;
			if ( v2 >= 858 )
				return;
		}
		v3 = (TSnd **)&sgSFX[v1].Channel;
		_LOBYTE(v4) = snd_playing(*v3);
		if ( !v4 )
			snd_play_snd(*v3, 0, 0);
	}
}
// 4A22D5: using guessed type char gbSoundOn;

//----- (00415F43) --------------------------------------------------------
void __fastcall encrypt_decrypt_block(void *block, int size, int key)
{
	unsigned int v3; // edx
	int v4; // eax
	unsigned int v5; // edi
	unsigned int v6; // edx
	int v7; // eax
	int v8; // esi

	v3 = (unsigned int)size >> 2;
	v4 = 0xEEEEEEEE;
	if ( v3 )
	{
		v5 = v3;
		v6 = key;
		do
		{
			v7 = encrypt_52B564[(unsigned char)v6] + v4;
			*(_DWORD *)block ^= v7 + v6;
			v8 = *(_DWORD *)block;
			block = (char *)block + 4;
			v4 = 33 * v7 + v8 + 3;
			v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11);
			--v5;
		}
		while ( v5 );
	}
}

//----- (00415F8F) --------------------------------------------------------
void __fastcall encrypt_encrypt_block(void *block, int size, int key)
{
	unsigned int v3; // edx
	int v4; // eax
	unsigned int v5; // edi
	unsigned int v6; // edx
	int v7; // eax
	int v8; // ebx

	v3 = (unsigned int)size >> 2;
	v4 = 0xEEEEEEEE;
	if ( v3 )
	{
		v5 = v3;
		v6 = key;
		do
		{
			v7 = encrypt_52B564[(unsigned char)v6] + v4;
			v8 = *(_DWORD *)block ^ (v7 + v6);
			v4 = 33 * v7 + *(_DWORD *)block + 3;
			*(_DWORD *)block = v8;
			block = (char *)block + 4;
			v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11);
			--v5;
		}
		while ( v5 );
	}
}

//----- (00415FDF) --------------------------------------------------------
int __fastcall encrypt_hash(char *s, int type)
{
	int v2; // ebp
	char *v3; // ebx
	signed int v4; // esi
	int v5; // edi
	int v6; // ST00_4
	char v7; // al

	v2 = type;
	v3 = s;
	v4 = 2146271213;
	v5 = -286331154;
	while ( v3 && *v3 )
	{
		v6 = *v3++;
		v7 = toupper(v6);
		v4 = (v5 + v4) ^ encrypt_52A564[v7 + (v2 << 8)];
		v5 = v7 + 33 * v5 + v4 + 3;
	}
	return v4;
}

//----- (0041602E) --------------------------------------------------------
void __cdecl encrypt_init_lookup_table()
{
	unsigned int v0; // eax
	int *v1; // edi
	unsigned int v2; // eax
	int v3; // ecx
	signed int v4; // [esp+Ch] [ebp-8h]
	int *v5; // [esp+10h] [ebp-4h]

	v0 = 0x100001;
	v5 = encrypt_52A564;
	do
	{
		v1 = v5;
		v4 = 5;
		do
		{
			v2 = (125 * v0 + 3) % 0x2AAAAB;
			v3 = (unsigned short)v2 << 16;
			v0 = (125 * v2 + 3) % 0x2AAAAB;
			*v1 = (unsigned short)v0 | v3;
			v1 += 256;
			--v4;
		}
		while ( v4 );
		++v5;
	}
	while ( (signed int)v5 < (signed int)&encrypt_52A564[256] );
}

//----- (0041609D) --------------------------------------------------------
int __fastcall encrypt_compress(void *buf, int size)
{
	void *v2; // ebx
	unsigned int v3; // esi
	int v4; // ecx
	void *v5; // edi
	void *param; // [esp+Ch] [ebp-20h]
	int v8; // [esp+10h] [ebp-1Ch]
	void *v9; // [esp+14h] [ebp-18h]
	size_t v10; // [esp+18h] [ebp-14h]
	unsigned int v11; // [esp+1Ch] [ebp-10h]
	unsigned int type; // [esp+20h] [ebp-Ch]
	unsigned int dsize; // [esp+24h] [ebp-8h]
	void *ptr; // [esp+28h] [ebp-4h]

	v2 = buf;
	v3 = size;
	ptr = DiabloAllocPtr(36312);
	v4 = 2 * v3;
	if ( 2 * v3 < 0x2000 )
		v4 = 0x2000;
	v5 = DiabloAllocPtr(v4);
	v8 = 0;
	v10 = 0;
	type = 0;
	param = v2;
	v9 = v5;
	v11 = v3;
	dsize = 4096;
	implode(
		(unsigned int (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_read,
		(void (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_write,
		(char *)ptr,
		&param,
		&type,
		&dsize);
	if ( v10 < v3 )
	{
		memcpy(v2, v5, v10);
		v3 = v10;
	}
	mem_free_dbg(ptr);
	mem_free_dbg(v5);
	return v3;
}

//----- (00416133) --------------------------------------------------------
int __cdecl encrypt_pkware_read(void *buf, int *size, void *param)
{
	int v3; // edi
	int v4; // ecx

	v3 = *size;
	v4 = *((_DWORD *)param + 1);
	if ( *size >= (unsigned int)(*((_DWORD *)param + 4) - v4) )
		v3 = *((_DWORD *)param + 4) - v4;
	memcpy(buf, (const void *)(v4 + *(_DWORD *)param), v3);
	*((_DWORD *)param + 1) += v3;
	return v3;
}

//----- (00416167) --------------------------------------------------------
int __cdecl encrypt_pkware_write(void *buf, int *size, void *param)
{
	int result; // eax

	memcpy((void *)(*((_DWORD *)param + 3) + *((_DWORD *)param + 2)), buf, *size);
	result = *size;
	*((_DWORD *)param + 3) += *size;
	return result;
}

//----- (0041618E) --------------------------------------------------------
void __fastcall encrypt_decompress(void *param, int a2, int size)
{
	void *v3; // edi
	int v4; // ebx
	void *v5; // esi
	void *parama; // [esp+Ch] [ebp-18h]
	int v7; // [esp+10h] [ebp-14h]
	void *v8; // [esp+14h] [ebp-10h]
	size_t v9; // [esp+18h] [ebp-Ch]
	int v10; // [esp+1Ch] [ebp-8h]
	void *ptr; // [esp+20h] [ebp-4h]

	v3 = param;
	v4 = a2;
	ptr = DiabloAllocPtr(36312);
	v5 = DiabloAllocPtr(size);
	v7 = 0;
	v9 = 0;
	parama = v3;
	v8 = v5;
	v10 = v4;
	explode(
		(unsigned int (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_read,
		(void (__cdecl *)(char *, unsigned int *, void *))encrypt_pkware_write,
		(char *)ptr,
		&parama);
	memcpy(v3, v5, v9);
	mem_free_dbg(ptr);
	mem_free_dbg(v5);
}

//----- (00416201) --------------------------------------------------------
void __cdecl engine_cpp_init_1()
{
	engine_cpp_init_value = engine_inf;
}
// 47A474: using guessed type int engine_inf;
// 52B968: using guessed type int engine_cpp_init_value;

//----- (0041620C) --------------------------------------------------------
void __fastcall Cel_content_into_buf(char *pDecodeTo, char *pRLEBytes, int dwRLESize, int dwRLEWdt)
{
	char *v4; // esi
	char *v5; // edi
	int v6; // edx
	unsigned int v7; // eax
	unsigned int v8; // ecx
	char v9; // cf
	unsigned int v10; // ecx
	char *v11; // [esp+4h] [ebp-8h]

	v11 = pRLEBytes;
	if ( pDecodeTo && pRLEBytes )
	{
		v4 = pRLEBytes;
		v5 = pDecodeTo;
		do
		{
			v6 = dwRLEWdt;
			do
			{
				while ( 1 )
				{
					v7 = (unsigned char)*v4++;
					if ( (v7 & 0x80u) == 0 )
						break;
					_LOBYTE(v7) = -(char)v7;
					v5 += v7;
					v6 -= v7;
					if ( !v6 )
						goto LABEL_14;
				}
				v6 -= v7;
				v8 = v7 >> 1;
				if ( v7 & 1 )
				{
					*v5++ = *v4++;
					if ( !v8 )
						continue;
				}
				v9 = v8 & 1;
				v10 = v7 >> 2;
				if ( v9 )
				{
					*(_WORD *)v5 = *(_WORD *)v4;
					v4 += 2;
					v5 += 2;
					if ( !v10 )
						continue;
				}
				qmemcpy(v5, v4, 4 * v10);
				v4 += 4 * v10;
				v5 += 4 * v10;
			}
			while ( v6 );
LABEL_14:
			v5 += -dwRLEWdt - 768;
		}
		while ( &v11[dwRLESize] != v4 );
	}
}

//----- (00416274) --------------------------------------------------------
void __fastcall Cel_decode(int screen_x, int screen_y, void *pCelBuff, int frame, int frame_width)
{
	if ( gpBuffer )
	{
		if ( pCelBuff )
			Cel_content_into_buf(
				(char *)gpBuffer + screen_y_times_768[screen_y] + screen_x,
				(char *)pCelBuff + *((_DWORD *)pCelBuff + frame),
				*((_DWORD *)pCelBuff + frame + 1) - *((_DWORD *)pCelBuff + frame),
				frame_width);
	}
}

//----- (004162B8) --------------------------------------------------------
void __fastcall Cel_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width)
{
	if ( pCelBuff )
	{
		if ( pBuff )
			Cel_content_into_buf(
				pBuff,
				&pCelBuff[*(_DWORD *)&pCelBuff[4 * frame]],
				*(_DWORD *)&pCelBuff[4 * frame + 4] - *(_DWORD *)&pCelBuff[4 * frame],
				frame_width);
	}
}

//----- (004162DE) --------------------------------------------------------
void __fastcall Cel_header(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction)
{
	int v7; // edx
	char *v8; // eax
	int v9; // edi
	int v10; // ecx
	int v11; // [esp+Ch] [ebp-8h]
	int v12; // [esp+10h] [ebp-4h]

	v12 = screen_y;
	v11 = screen_x;
	if ( gpBuffer )
	{
		if ( pCelBuff )
		{
			v7 = *(_DWORD *)&pCelBuff[4 * frame];
			v8 = &pCelBuff[v7];
			v9 = *(unsigned short *)&pCelBuff[v7 + always_0];
			if ( *(_WORD *)&pCelBuff[v7 + always_0] )
			{
				if ( direction != 8 && *(_WORD *)&v8[direction] )
					v10 = *(unsigned short *)&v8[direction] - v9;
				else
					v10 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v7 - v9;
				Cel_content_into_buf(
					(char *)gpBuffer + screen_y_times_768[v12 - 16 * always_0] + v11,
					&v8[v9],
					v10,
					frame_width);
			}
		}
	}
}

//----- (00416359) --------------------------------------------------------
void __fastcall Cel_header_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction)
{
	int v6; // esi
	char *v7; // eax
	int v8; // ebx
	int v9; // edx
	int v10; // edx

	if ( pCelBuff )
	{
		if ( pBuff )
		{
			v6 = *(_DWORD *)&pCelBuff[4 * frame];
			v7 = &pCelBuff[v6];
			v8 = *(unsigned short *)&pCelBuff[v6 + always_0];
			if ( *(_WORD *)&pCelBuff[v6 + always_0] )
			{
				v9 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v6;
				if ( direction != 8 && *(_WORD *)&v7[direction] )
					v10 = *(unsigned short *)&v7[direction] - v8;
				else
					v10 = v9 - v8;
				Cel_content_into_buf(pBuff, &v7[v8], v10, frame_width);
			}
		}
	}
}

//----- (004163AC) --------------------------------------------------------
void __fastcall Cel_content_light_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width)
{
	char *v4; // esi
	char *v5; // edi
	char *v6; // ebx
	int v7; // edx
	int v8; // eax
	int v9; // ST00_4

	if ( pDecodeTo && pRLEBytes )
	{
		v4 = pRLEBytes;
		v5 = pDecodeTo;
		v6 = &pRLEBytes[frame_content_size];
		do
		{
			v7 = frame_width;
			do
			{
				while ( 1 )
				{
					v8 = (unsigned char)*v4++;
					if ( (v8 & 0x80u) != 0 )
						break;
					v9 = v7 - v8;
					Cel_content_light_entry_into_buf(v8, v7 - v8);
					v7 = v9;
					if ( !v9 )
						goto LABEL_9;
				}
				_LOBYTE(v8) = -(char)v8;
				v5 += v8;
				v7 -= v8;
			}
			while ( v7 );
LABEL_9:
			v5 += -frame_width - 768;
		}
		while ( v6 != v4 );
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00416423) --------------------------------------------------------
void __fastcall Cel_content_light_entry_into_buf(int a1, int a2)
{
	int v2; // ebx
	_BYTE *v3; // edi
	_BYTE *v4; // esi
	char v5; // cf
	unsigned char v6; // cl
	char v7; // cl
	int v8; // eax
	char v9; // ch
	char v10; // ch
	char v11; // ch

	v5 = a1 & 1;
	v6 = (unsigned char)a1 >> 1;
	if ( v5 )
	{
		_LOBYTE(a2) = *v4;
		*v3 = *(_BYTE *)(v2 + a2);
		++v4;
		++v3;
	}
	v5 = v6 & 1;
	v7 = v6 >> 1;
	if ( v5 )
	{
		_LOBYTE(a2) = *v4;
		*v3 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = v4[1];
		v3[1] = *(_BYTE *)(v2 + a2);
		v4 += 2;
		v3 += 2;
	}
	for ( ; v7; --v7 )
	{
		v8 = *(_DWORD *)v4;
		v4 += 4;
		_LOBYTE(a2) = v8;
		v9 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = BYTE1(v8);
		v8 = __ROR4__(v8, 16);
		*v3 = v9;
		v10 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = v8;
		v3[1] = v10;
		v11 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = BYTE1(v8);
		v3[2] = v11;
		v3[3] = *(_BYTE *)(v2 + a2);
		v3 += 4;
	}
}

//----- (00416488) --------------------------------------------------------
void __fastcall Cel_content_light_trans_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width)
{
	char *v4; // esi
	int v5; // edi
	char *v6; // ebx
	int v7; // edx
	unsigned int v8; // eax
	unsigned int v10; // ecx
	char v11; // cf
	unsigned int v12; // ecx
	char *v13; // esi
	_BYTE *v14; // edi
	_BYTE *v18; // edi
	unsigned int v21; // ecx
	_BYTE *v25; // edi
	char *v26; // [esp-4h] [ebp-24h]
	int v27; // [esp+Ch] [ebp-14h]
	int v28; // [esp+14h] [ebp-Ch]

	if ( pDecodeTo && pRLEBytes )
	{
		v27 = dword_646A20 + (light_table_index << 8);
		v4 = pRLEBytes;
		v5 = (int)pDecodeTo;
		v6 = &pRLEBytes[frame_content_size];
		v28 = (unsigned char)pDecodeTo & 1;
		do
		{
			v7 = frame_width;
			do
			{
/*				while ( 1 )
				{
					v8 = (unsigned char)*v4++;
					if ( (v8 & 0x80u) != 0 )
						break;
					v26 = v6;
					_EBX = v27;
					v7 -= v8;
					if ( (v5 & 1) == v28 )
					{
						v10 = v8 >> 1;
						if ( !(v8 & 1) )
							goto LABEL_10;
						++v4;
						++v5;
						if ( v10 )
						{
LABEL_17:
							v11 = v10 & 1;
							v21 = v10 >> 1;
							if ( !v11 )
								goto LABEL_26;
							_AL = *v4;
							__asm { xlat }
							*(_BYTE *)v5 = _AL;
							v4 += 2;
							v5 += 2;
							if ( v21 )
							{
LABEL_26:
								do
								{
									_EAX = *(_DWORD *)v4;
									v4 += 4;
									__asm { xlat }
									*(_BYTE *)v5 = _EAX;
									v25 = (_BYTE *)(v5 + 2);
									_EAX = __ROR4__(_EAX, 16);
									__asm { xlat }
									*v25 = _EAX;
									v5 = (int)(v25 + 2);
									--v21;
								}
								while ( v21 );
							}
							goto LABEL_20;
						}
					}
					else
					{
						v10 = v8 >> 1;
						if ( !(v8 & 1) )
							goto LABEL_17;
						_AL = *v4++;
						__asm { xlat }
						*(_BYTE *)v5++ = _AL;
						if ( v10 )
						{
LABEL_10:
							v11 = v10 & 1;
							v12 = v10 >> 1;
							if ( !v11 )
								goto LABEL_27;
							v13 = v4 + 1;
							v14 = (_BYTE *)(v5 + 1);
							_AL = *v13;
							v4 = v13 + 1;
							__asm { xlat }
							*v14 = _AL;
							v5 = (int)(v14 + 1);
							if ( v12 )
							{
LABEL_27:
								do
								{
									_EAX = *(_DWORD *)v4;
									v4 += 4;
									v18 = (_BYTE *)(v5 + 1);
									_EAX = __ROR4__(_EAX, 8);
									__asm { xlat }
									*v18 = _EAX;
									_EAX = __ROR4__(_EAX, 16);
									v18 += 2;
									__asm { xlat }
									*v18 = _EAX;
									v5 = (int)(v18 + 1);
									--v12;
								}
								while ( v12 );
							}
							goto LABEL_20;
						}
					}
LABEL_20:
					v6 = v26;
					if ( !v7 )
						goto LABEL_23;
				}*/
				_LOBYTE(v8) = -(char)v8;
				v5 += v8;
				v7 -= v8;
			}
			while ( v7 );
LABEL_23:
			v5 -= frame_width + 768;
			v28 = ((_BYTE)v28 + 1) & 1;
		}
		while ( v6 != v4 );
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00416565) --------------------------------------------------------
void __fastcall Cel_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width)
{
	int v5; // ebx
	int v6; // esi
	char *v7; // edx
	char *v8; // ecx
	int v9; // [esp-8h] [ebp-14h]

	v5 = screen_y;
	if ( gpBuffer && pCelBuff )
	{
		v6 = *(_DWORD *)&pCelBuff[4 * frame];
		v7 = &pCelBuff[v6];
		v8 = (char *)gpBuffer + screen_y_times_768[v5] + screen_x;
		v9 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v6;
		if ( light_table_index )
			Cel_content_light_into_buf(v8, v7, v9, frame_width);
		else
			Cel_content_into_buf(v8, v7, v9, frame_width);
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (004165BD) --------------------------------------------------------
void __fastcall Cel_header_and_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction)
{
	int v7; // esi
	char *v8; // ecx
	int v9; // edi
	char *v10; // edx
	int v11; // ebx
	int v12; // ebx
	char *v13; // edx
	char *v14; // ecx
	int v15; // [esp+Ch] [ebp-4h]
	char *cel_buf; // [esp+18h] [ebp+8h]

	v7 = screen_y;
	v15 = screen_x;
	if ( gpBuffer )
	{
		v8 = pCelBuff;
		if ( pCelBuff )
		{
			v9 = *(_DWORD *)&pCelBuff[4 * frame];
			v10 = &pCelBuff[v9];
			v11 = *(unsigned short *)&pCelBuff[v9 + always_0];
			cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + always_0];
			if ( v11 )
			{
				if ( direction != 8 && *(_WORD *)&v10[direction] )
					v12 = *(unsigned short *)&v10[direction] - (_DWORD)cel_buf;
				else
					v12 = *(_DWORD *)&v8[4 * frame + 4] - v9 - (_DWORD)cel_buf;
				v13 = &v10[(_DWORD)cel_buf];
				v14 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * always_0] + v15;
				if ( light_table_index )
					Cel_content_light_into_buf(v14, v13, v12, frame_width);
				else
					Cel_content_into_buf(v14, v13, v12, frame_width);
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (0041664B) --------------------------------------------------------
void __fastcall Cel_header_light_and_trans_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction)
{
	char *v6; // eax
	int v7; // esi
	char *v8; // edx
	int v9; // ebx
	int v10; // eax
	int v11; // eax
	char *v12; // edx

	v6 = pCelBuff;
	if ( pCelBuff )
	{
		if ( pBuff )
		{
			v7 = *(_DWORD *)&pCelBuff[4 * frame];
			v8 = &pCelBuff[v7];
			v9 = *(unsigned short *)&v6[v7 + always_0];
			if ( *(_WORD *)&v6[v7 + always_0] )
			{
				v10 = *(_DWORD *)&v6[4 * frame + 4] - v7;
				if ( direction != 8 && *(_WORD *)&v8[direction] )
					v11 = *(unsigned short *)&v8[direction] - v9;
				else
					v11 = v10 - v9;
				v12 = &v8[v9];
				if ( cel_transparency_active )
				{
					Cel_content_light_trans_into_buf(pBuff, v12, v11, frame_width);
				}
				else if ( light_table_index )
				{
					Cel_content_light_into_buf(pBuff, v12, v11, frame_width);
				}
				else
				{
					Cel_content_into_buf(pBuff, v12, v11, frame_width);
				}
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;
// 69CF94: using guessed type int cel_transparency_active;

//----- (004166BF) --------------------------------------------------------
void __fastcall Cel_header_and_light_not_equipable(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1)
{
	char *v8; // esi
	int v9; // ebx
	int v10; // eax
	char *v11; // edi
	int v12; // ecx
	int v13; // esi
	int v14; // eax
	int v15; // eax
	_BYTE *v16; // esi
	char *v17; // edi
	int v18; // edx
	int v19; // eax
	int v20; // ecx
	int v21; // [esp+Ch] [ebp-4h]
	int v22; // [esp+Ch] [ebp-4h]
	char *cel_buf; // [esp+18h] [ebp+8h]
	char *cel_bufa; // [esp+18h] [ebp+8h]
	int framea; // [esp+1Ch] [ebp+Ch]
	int always_0a; // [esp+24h] [ebp+14h]
	int directiona; // [esp+28h] [ebp+18h]

	v21 = screen_x;
	if ( gpBuffer )
	{
		v8 = pCelBuff;
		if ( pCelBuff )
		{
			v9 = *(_DWORD *)&pCelBuff[4 * frame];
			v10 = always_0;
			v11 = &pCelBuff[v9];
			v12 = *(unsigned short *)&pCelBuff[v9 + always_0];
			cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + always_0];
			if ( v12 )
			{
				v13 = *(_DWORD *)&v8[4 * frame + 4] - v9;
				if ( direction != 8 && *(_WORD *)&v11[direction] )
					always_0a = *(unsigned short *)&v11[direction] - (_DWORD)cel_buf;
				else
					always_0a = v13 - (_DWORD)cel_buf;
				directiona = (int)&v11[(_DWORD)cel_buf];
				cel_bufa = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * v10] + v21;
				v14 = -(light4flag != 0);
				_LOWORD(v14) = v14 & 0xF400;
				v15 = v14 + 4096;
				framea = v15;
				if ( always_1 == 2 )
				{
					v15 += 256;
					framea = v15;
				}
				if ( always_1 >= 4 )
					framea = v15 + (always_1 << 8) - 256;
				v22 = framea + dword_646A20;
				v16 = (_BYTE *)directiona;
				v17 = cel_bufa;
				do
				{
					v18 = frame_width;
					do
					{
						while ( 1 )
						{
							v19 = (unsigned char)*v16++;
							if ( (v19 & 0x80u) == 0 )
								break;
							_LOBYTE(v19) = -(char)v19;
							v17 += v19;
							v18 -= v19;
							if ( !v18 )
								goto LABEL_20;
						}
						v18 -= v19;
						v20 = v19;
						do
						{
							_LOBYTE(v19) = *v16++;
							*v17 = *(_BYTE *)(v22 + v19);
							--v20;
							++v17;
						}
						while ( v20 );
					}
					while ( v18 );
LABEL_20:
					v17 += -frame_width - 768;
				}
				while ( (_BYTE *)(directiona + always_0a) != v16 );
			}
		}
	}
}
// 525728: using guessed type int light4flag;

//----- (004167DB) --------------------------------------------------------
void __fastcall Cel2_content_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width)
{
	char *v4; // esi
	char *v5; // edi
	int v6; // edx
	unsigned int v7; // eax
	unsigned int v8; // ecx
	char v9; // cf
	unsigned int v10; // ecx
	char *v11; // [esp+4h] [ebp-8h]

	v11 = pRLEBytes;
	if ( pDecodeTo && pRLEBytes && gpBuffer )
	{
		v4 = pRLEBytes;
		v5 = pDecodeTo;
		do
		{
			v6 = frame_width;
			do
			{
				while ( 1 )
				{
					v7 = (unsigned char)*v4++;
					if ( (v7 & 0x80u) == 0 )
						break;
					_LOBYTE(v7) = -(char)v7;
					v5 += v7;
					v6 -= v7;
					if ( !v6 )
						goto LABEL_17;
				}
				v6 -= v7;
				if ( (unsigned int)v5 < screen_buf_end )
				{
					v8 = v7 >> 1;
					if ( !(v7 & 1) || (*v5 = *v4, ++v4, ++v5, v8) )
					{
						v9 = v8 & 1;
						v10 = v7 >> 2;
						if ( !v9 || (*(_WORD *)v5 = *(_WORD *)v4, v4 += 2, v5 += 2, v10) )
						{
							qmemcpy(v5, v4, 4 * v10);
							v4 += 4 * v10;
							v5 += 4 * v10;
						}
					}
				}
				else
				{
					v4 += v7;
					v5 += v7;
				}
			}
			while ( v6 );
LABEL_17:
			v5 += -frame_width - 768;
		}
		while ( &v11[frame_content_size] != v4 );
	}
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (0041685A) --------------------------------------------------------
void __fastcall Cel2_header(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction)
{
	int v7; // edx
	char *v8; // eax
	int v9; // edi
	int v10; // ecx
	int v11; // [esp+Ch] [ebp-8h]
	int v12; // [esp+10h] [ebp-4h]

	v12 = screen_y;
	v11 = screen_x;
	if ( gpBuffer )
	{
		if ( pCelBuff )
		{
			v7 = *(_DWORD *)&pCelBuff[4 * frame];
			v8 = &pCelBuff[v7];
			v9 = *(unsigned short *)&pCelBuff[v7 + a6];
			if ( *(_WORD *)&pCelBuff[v7 + a6] )
			{
				if ( direction != 8 && *(_WORD *)&v8[direction] )
					v10 = *(unsigned short *)&v8[direction] - v9;
				else
					v10 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v7 - v9;
				Cel2_content_into_buf(
					(char *)gpBuffer + screen_y_times_768[v12 - 16 * a6] + v11,
					&v8[v9],
					v10,
					frame_width);
			}
		}
	}
}

//----- (004168D5) --------------------------------------------------------
void __fastcall Cel2_header_into_buf(char *pBuff, char *pCelBuff, int frame, int frame_width, int a5, int direction)
{
	int v6; // edi
	char *v7; // esi
	int v8; // ebx
	int v9; // eax
	int v10; // edx
	int v11; // eax

	if ( pCelBuff )
	{
		if ( pBuff )
		{
			v6 = *(_DWORD *)&pCelBuff[4 * frame];
			v7 = &pCelBuff[v6];
			v8 = *(unsigned short *)&pCelBuff[v6 + a5];
			if ( *(_WORD *)&pCelBuff[v6 + a5] )
			{
				v9 = *(_DWORD *)&pCelBuff[4 * frame + 4] - v6;
				v10 = *(unsigned short *)&v7[direction];
				if ( direction == 8 )
					v10 = 0;
				if ( v10 )
					v11 = v10 - v8;
				else
					v11 = v9 - v8;
				Cel2_content_into_buf(pBuff, &v7[v8], v11, frame_width);
			}
		}
	}
}

//----- (0041692A) --------------------------------------------------------
void __fastcall Cel2_content_light_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width)
{
	char *v4; // esi
	char *v5; // edi
	char *v6; // ebx
	int v7; // edx
	int v8; // eax
	int v9; // ST00_4

	if ( pDecodeTo && pRLEBytes && gpBuffer )
	{
		v4 = pRLEBytes;
		v5 = pDecodeTo;
		v6 = &pRLEBytes[frame_content_size];
		do
		{
			v7 = frame_width;
			do
			{
				while ( 1 )
				{
					v8 = (unsigned char)*v4++;
					if ( (v8 & 0x80u) == 0 )
						break;
					_LOBYTE(v8) = -(char)v8;
					v5 += v8;
					v7 -= v8;
					if ( !v7 )
						goto LABEL_13;
				}
				v7 -= v8;
				if ( (unsigned int)v5 < screen_buf_end )
				{
					v9 = v7;
					Cel2_content_light_entry_into_buf(v8, v7);
					v7 = v9;
				}
				else
				{
					v4 += v8;
					v5 += v8;
				}
			}
			while ( v7 );
LABEL_13:
			v5 += -frame_width - 768;
		}
		while ( v6 != v4 );
	}
}
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;

//----- (004169BC) --------------------------------------------------------
void __fastcall Cel2_content_light_entry_into_buf(int a1, int a2)
{
	int v2; // ebx
	_BYTE *v3; // edi
	_BYTE *v4; // esi
	char v5; // cf
	unsigned char v6; // cl
	char v7; // cl
	int v8; // eax
	char v9; // ch
	char v10; // ch
	char v11; // ch

	v5 = a1 & 1;
	v6 = (unsigned char)a1 >> 1;
	if ( v5 )
	{
		_LOBYTE(a2) = *v4;
		*v3 = *(_BYTE *)(v2 + a2);
		++v4;
		++v3;
	}
	v5 = v6 & 1;
	v7 = v6 >> 1;
	if ( v5 )
	{
		_LOBYTE(a2) = *v4;
		*v3 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = v4[1];
		v3[1] = *(_BYTE *)(v2 + a2);
		v4 += 2;
		v3 += 2;
	}
	for ( ; v7; --v7 )
	{
		v8 = *(_DWORD *)v4;
		v4 += 4;
		_LOBYTE(a2) = v8;
		v9 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = BYTE1(v8);
		v8 = __ROR4__(v8, 16);
		*v3 = v9;
		v10 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = v8;
		v3[1] = v10;
		v11 = *(_BYTE *)(v2 + a2);
		_LOBYTE(a2) = BYTE1(v8);
		v3[2] = v11;
		v3[3] = *(_BYTE *)(v2 + a2);
		v3 += 4;
	}
}

//----- (00416A21) --------------------------------------------------------
void __fastcall Cel2_content_light_trans_into_buf(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width)
{
	char *v4; // esi
	unsigned int v5; // edi
	char *v6; // ebx
	int v7; // edx
	unsigned int v8; // eax
	unsigned int v10; // ecx
	char v11; // cf
	unsigned int v12; // ecx
	char *v13; // esi
	_BYTE *v14; // edi
	_BYTE *v18; // edi
	unsigned int v21; // ecx
	_BYTE *v25; // edi
	char *v26; // [esp-4h] [ebp-24h]
	int v27; // [esp+Ch] [ebp-14h]
	int v28; // [esp+14h] [ebp-Ch]

	if ( pDecodeTo && pRLEBytes && gpBuffer )
	{
		v27 = dword_646A20 + (light_table_index << 8);
		v4 = pRLEBytes;
		v5 = (unsigned int)pDecodeTo;
		v6 = &pRLEBytes[frame_content_size];
		v28 = (unsigned char)pDecodeTo & 1;
		do
		{
			v7 = frame_width;
			do
			{
/*				while ( 1 )
				{
					v8 = (unsigned char)*v4++;
					if ( (v8 & 0x80u) != 0 )
						break;
					v26 = v6;
					_EBX = v27;
					v7 -= v8;
					if ( v5 < screen_buf_end )
					{
						if ( (v5 & 1) == v28 )
						{
							v10 = v8 >> 1;
							if ( !(v8 & 1) )
								goto LABEL_13;
							++v4;
							++v5;
							if ( v10 )
							{
LABEL_20:
								v11 = v10 & 1;
								v21 = v10 >> 1;
								if ( !v11 )
									goto LABEL_29;
								_AL = *v4;
								__asm { xlat }
								*(_BYTE *)v5 = _AL;
								v4 += 2;
								v5 += 2;
								if ( v21 )
								{
LABEL_29:
									do
									{
										_EAX = *(_DWORD *)v4;
										v4 += 4;
										__asm { xlat }
										*(_BYTE *)v5 = _EAX;
										v25 = (_BYTE *)(v5 + 2);
										_EAX = __ROR4__(_EAX, 16);
										__asm { xlat }
										*v25 = _EAX;
										v5 = (unsigned int)(v25 + 2);
										--v21;
									}
									while ( v21 );
								}
								goto LABEL_23;
							}
						}
						else
						{
							v10 = v8 >> 1;
							if ( !(v8 & 1) )
								goto LABEL_20;
							_AL = *v4++;
							__asm { xlat }
							*(_BYTE *)v5++ = _AL;
							if ( v10 )
							{
LABEL_13:
								v11 = v10 & 1;
								v12 = v10 >> 1;
								if ( !v11 )
									goto LABEL_30;
								v13 = v4 + 1;
								v14 = (_BYTE *)(v5 + 1);
								_AL = *v13;
								v4 = v13 + 1;
								__asm { xlat }
								*v14 = _AL;
								v5 = (unsigned int)(v14 + 1);
								if ( v12 )
								{
LABEL_30:
									do
									{
										_EAX = *(_DWORD *)v4;
										v4 += 4;
										v18 = (_BYTE *)(v5 + 1);
										_EAX = __ROR4__(_EAX, 8);
										__asm { xlat }
										*v18 = _EAX;
										_EAX = __ROR4__(_EAX, 16);
										v18 += 2;
										__asm { xlat }
										*v18 = _EAX;
										v5 = (unsigned int)(v18 + 1);
										--v12;
									}
									while ( v12 );
								}
								goto LABEL_23;
							}
						}
					}
					else
					{
						v4 += v8;
						v5 += v8;
					}
LABEL_23:
					v6 = v26;
					if ( !v7 )
						goto LABEL_26;
				}*/
				_LOBYTE(v8) = -(char)v8;
				v5 += v8;
				v7 -= v8;
			}
			while ( v7 );
LABEL_26:
			v5 -= frame_width + 768;
			v28 = ((_BYTE)v28 + 1) & 1;
		}
		while ( v6 != v4 );
	}
}
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;

//----- (00416B19) --------------------------------------------------------
void __fastcall Cel2_header_and_light(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction)
{
	int v7; // esi
	char *v8; // eax
	int v9; // edi
	char *v10; // edx
	int v11; // ebx
	int v12; // eax
	int v13; // edi
	int v14; // eax
	char *v15; // edx
	char *v16; // ecx
	char *cel_buf; // [esp+18h] [ebp+8h]

	v7 = screen_y;
	if ( gpBuffer )
	{
		v8 = pCelBuff;
		if ( pCelBuff )
		{
			v9 = *(_DWORD *)&pCelBuff[4 * frame];
			v10 = &pCelBuff[v9];
			v11 = *(unsigned short *)&pCelBuff[v9 + a6];
			cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + a6];
			if ( v11 )
			{
				v12 = *(_DWORD *)&v8[4 * frame + 4] - v9;
				v13 = *(unsigned short *)&v10[direction];
				if ( direction == 8 )
					v13 = 0;
				if ( v13 )
					v14 = v13 - (_DWORD)cel_buf;
				else
					v14 = v12 - (_DWORD)cel_buf;
				v15 = &v10[(_DWORD)cel_buf];
				v16 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + screen_x;
				if ( light_table_index )
					Cel2_content_light_into_buf(v16, v15, v14, frame_width);
				else
					Cel2_content_into_buf(v16, v15, v14, frame_width);
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00416BA9) --------------------------------------------------------
void __fastcall Cel2_header_light_and_trans_into_buf(char *dst_buf, char *pCelBuff, int frame, int frame_width, int a5, int direction)
{
	char *v6; // eax
	int v7; // esi
	char *v8; // edx
	int v9; // ebx
	int v10; // eax
	int v11; // esi
	int v12; // eax
	char *v13; // edx

	v6 = pCelBuff;
	if ( pCelBuff )
	{
		v7 = *(_DWORD *)&pCelBuff[4 * frame];
		v8 = &pCelBuff[v7];
		v9 = *(unsigned short *)&v6[v7 + a5];
		if ( *(_WORD *)&v6[v7 + a5] )
		{
			v10 = *(_DWORD *)&v6[4 * frame + 4] - v7;
			v11 = *(unsigned short *)&v8[direction];
			if ( direction == 8 )
				v11 = 0;
			if ( v11 )
				v12 = v11 - v9;
			else
				v12 = v10 - v9;
			v13 = &v8[v9];
			if ( cel_transparency_active )
			{
				Cel2_content_light_trans_into_buf(dst_buf, v13, v12, frame_width);
			}
			else if ( light_table_index )
			{
				Cel2_content_light_into_buf(dst_buf, v13, v12, frame_width);
			}
			else
			{
				Cel2_content_into_buf(dst_buf, v13, v12, frame_width);
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;
// 69CF94: using guessed type int cel_transparency_active;

//----- (00416C1B) --------------------------------------------------------
void __fastcall Cel2_header_and_light_not_equipable(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1)
{
	char *v8; // esi
	int v9; // ebx
	char *v10; // edi
	int v11; // ecx
	int v12; // esi
	int v13; // eax
	int v14; // eax
	_BYTE *v15; // esi
	_BYTE *v16; // edi
	int v17; // ecx
	int v18; // edx
	int v19; // ecx
	int v20; // eax
	_BYTE *v21; // [esp-4h] [ebp-14h]
	int v22; // [esp+Ch] [ebp-4h]
	char *cel_buf; // [esp+18h] [ebp+8h]
	char *cel_bufa; // [esp+18h] [ebp+8h]
	int framea; // [esp+1Ch] [ebp+Ch]
	char *always_0a; // [esp+24h] [ebp+14h]
	int directiona; // [esp+28h] [ebp+18h]

	v22 = screen_x;
	if ( gpBuffer )
	{
		v8 = pCelBuff;
		if ( pCelBuff )
		{
			v9 = *(_DWORD *)&pCelBuff[4 * frame];
			v10 = &pCelBuff[v9];
			v11 = *(unsigned short *)&pCelBuff[v9 + always_0];
			cel_buf = (char *)*(unsigned short *)&pCelBuff[v9 + always_0];
			if ( v11 )
			{
				v12 = *(_DWORD *)&v8[4 * frame + 4] - v9;
				if ( direction != 8 && *(_WORD *)&v10[direction] )
					framea = *(unsigned short *)&v10[direction] - (_DWORD)cel_buf;
				else
					framea = v12 - (_DWORD)cel_buf;
				directiona = (int)&v10[(_DWORD)cel_buf];
				always_0a = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * always_0] + v22;
				v13 = -(light4flag != 0);
				_LOWORD(v13) = v13 & 0xF400;
				v14 = v13 + 4096;
				if ( always_1 == 2 )
					v14 += 256;
				if ( always_1 >= 4 )
					v14 = v14 + (always_1 << 8) - 256;
				cel_bufa = (char *)(v14 + dword_646A20);
				v15 = (_BYTE *)directiona;
				v16 = (unsigned char *)always_0a;
				v17 = directiona + framea;
				do
				{
					v21 = (_BYTE *)v17;
					v18 = frame_width;
					v19 = 0;
					do
					{
						while ( 1 )
						{
							v20 = (unsigned char)*v15++;
							if ( (v20 & 0x80u) == 0 )
								break;
							_LOBYTE(v20) = -(char)v20;
							v16 += v20;
							v18 -= v20;
							if ( !v18 )
								goto LABEL_21;
						}
						v18 -= v20;
						if ( (unsigned int)v16 < screen_buf_end )
						{
							do
							{
								_LOBYTE(v19) = *v15++;
								*v16 = cel_bufa[v19];
								--v20;
								++v16;
							}
							while ( v20 );
						}
						else
						{
							v15 += v20;
							v16 += v20;
						}
					}
					while ( v18 );
LABEL_21:
					v17 = (int)v21;
					v16 += -frame_width - 768;
				}
				while ( v21 != v15 );
			}
		}
	}
}
// 525728: using guessed type int light4flag;
// 69CF0C: using guessed type int screen_buf_end;

//----- (00416D3C) --------------------------------------------------------
void __fastcall Cel_into_rect_of_buf(char *pBuff, int always_0, int dst_height, int dst_width, char *pCelBuff, int frame, int frame_width)
{
	char *v7; // ebx
	char *v8; // esi
	char *v9; // edi
	int v10; // ebx
	int v11; // edx
	unsigned int v12; // eax
	unsigned int v13; // ecx
	char v14; // cf
	unsigned int v15; // ecx
	int dst_widtha; // [esp+14h] [ebp+Ch]

	if ( pCelBuff && pBuff )
	{
		v7 = &pCelBuff[4 * frame];
		v8 = &pCelBuff[*(_DWORD *)v7];
		v9 = &pBuff[dst_width * dst_height + always_0];
		dst_widtha = frame_width + dst_width;
		v10 = (int)&v8[*((_DWORD *)v7 + 1) - *(_DWORD *)v7];
		do
		{
			v11 = frame_width;
			do
			{
				while ( 1 )
				{
					v12 = (unsigned char)*v8++;
					if ( (v12 & 0x80u) == 0 )
						break;
					_LOBYTE(v12) = -(char)v12;
					v9 += v12;
					v11 -= v12;
					if ( !v11 )
						goto LABEL_14;
				}
				v11 -= v12;
				v13 = v12 >> 1;
				if ( v12 & 1 )
				{
					*v9++ = *v8++;
					if ( !v13 )
						continue;
				}
				v14 = v13 & 1;
				v15 = v12 >> 2;
				if ( v14 )
				{
					*(_WORD *)v9 = *(_WORD *)v8;
					v8 += 2;
					v9 += 2;
					if ( !v15 )
						continue;
				}
				qmemcpy(v9, v8, 4 * v15);
				v8 += 4 * v15;
				v9 += 4 * v15;
			}
			while ( v11 );
LABEL_14:
			v9 -= dst_widtha;
		}
		while ( (char *)v10 != v8 );
	}
}

//----- (00416DC6) --------------------------------------------------------
void __fastcall Cel_colour(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction)
{
	char *v8; // ebx
	int v9; // eax
	char *v10; // esi
	char *v11; // edi
	int v12; // edx
	int v13; // eax
	int v14; // ecx
	char v15; // al
	int v16; // [esp+Ch] [ebp-10h]
	char *v17; // [esp+10h] [ebp-Ch]
	int v18; // [esp+14h] [ebp-8h]
	char v19; // [esp+18h] [ebp-4h]

	v19 = colour;
	if ( pCelBuff )
	{
		if ( gpBuffer )
		{
			v8 = &pCelBuff[4 * frame];
			v17 = &pCelBuff[*(_DWORD *)v8];
			v16 = *(unsigned short *)&v17[a7];
			if ( *(_WORD *)&v17[a7] )
			{
				if ( direction == 8 )
					v9 = 0;
				else
					v9 = *(unsigned short *)&v17[direction];
				if ( v9 )
					v18 = v9 - v16;
				else
					v18 = *((_DWORD *)v8 + 1) - *(_DWORD *)v8 - v16;
				v10 = &v17[v16];
				v11 = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a7] + screen_x;
				do
				{
					v12 = frame_width;
					do
					{
						while ( 1 )
						{
							v13 = (unsigned char)*v10++;
							if ( (v13 & 0x80u) == 0 )
								break;
							_LOBYTE(v13) = -(char)v13;
							v11 += v13;
							v12 -= v13;
							if ( !v12 )
								goto LABEL_20;
						}
						v12 -= v13;
						v14 = v13;
						do
						{
							v15 = *v10++;
							if ( v15 )
							{
								*(v11 - 768) = v19;
								*(v11 - 1) = v19;
								v11[1] = v19;
								v11[768] = v19;
							}
							++v11;
							--v14;
						}
						while ( v14 );
					}
					while ( v12 );
LABEL_20:
					v11 += -frame_width - 768;
				}
				while ( &v17[v16 + v18] != v10 );
			}
		}
	}
}

//----- (00416EC0) --------------------------------------------------------
void __fastcall Cel_header_and_colour_highlight(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction)
{
	char *v8; // ebx
	int v9; // eax
	char *v10; // esi
	char *v11; // edi
	int v12; // edx
	int v13; // eax
	int v14; // ecx
	char v15; // al
	int v16; // ecx
	char v17; // al
	int v18; // [esp+Ch] [ebp-10h]
	char *v19; // [esp+10h] [ebp-Ch]
	int v20; // [esp+14h] [ebp-8h]
	char v21; // [esp+18h] [ebp-4h]

	v21 = colour;
	if ( pCelBuff )
	{
		if ( gpBuffer )
		{
			v8 = &pCelBuff[4 * frame];
			v19 = &pCelBuff[*(_DWORD *)v8];
			v18 = *(unsigned short *)&v19[a7];
			if ( *(_WORD *)&v19[a7] )
			{
				if ( direction == 8 )
					v9 = 0;
				else
					v9 = *(unsigned short *)&v19[direction];
				if ( v9 )
					v20 = v9 - v18;
				else
					v20 = *((_DWORD *)v8 + 1) - *(_DWORD *)v8 - v18;
				v10 = &v19[v18];
				v11 = (char *)gpBuffer + screen_y_times_768[screen_y - 16 * a7] + screen_x;
				do
				{
					v12 = frame_width;
					do
					{
						while ( 1 )
						{
							v13 = (unsigned char)*v10++;
							if ( (v13 & 0x80u) == 0 )
								break;
							_LOBYTE(v13) = -(char)v13;
							v11 += v13;
							v12 -= v13;
							if ( !v12 )
								goto LABEL_28;
						}
						v12 -= v13;
						if ( (unsigned int)v11 < screen_buf_end )
						{
							if ( (unsigned int)v11 >= screen_buf_end - 768 )
							{
								v16 = v13;
								do
								{
									v17 = *v10++;
									if ( v17 )
									{
										*(v11 - 768) = v21;
										*(v11 - 1) = v21;
										v11[1] = v21;
									}
									++v11;
									--v16;
								}
								while ( v16 );
							}
							else
							{
								v14 = v13;
								do
								{
									v15 = *v10++;
									if ( v15 )
									{
										*(v11 - 768) = v21;
										*(v11 - 1) = v21;
										v11[1] = v21;
										v11[768] = v21;
									}
									++v11;
									--v14;
								}
								while ( v14 );
							}
						}
						else
						{
							v10 += v13;
							v11 += v13;
						}
					}
					while ( v12 );
LABEL_28:
					v11 += -frame_width - 768;
				}
				while ( &v19[v18 + v20] != v10 );
			}
		}
	}
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (00416FEF) --------------------------------------------------------
void __fastcall ENG_set_pixel(int screen_x, int screen_y, char pixel)
{
	char *v3; // edi

	if ( screen_y >= 0 && screen_y < 640 && screen_x >= 64 && screen_x < 704 )
	{
		v3 = (char *)gpBuffer + screen_y_times_768[screen_y] + screen_x;
		if ( (unsigned int)v3 < screen_buf_end )
			*v3 = pixel;
	}
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (00417034) --------------------------------------------------------
void __fastcall engine_417034(int x, int y)
{
	_BYTE *v2; // eax

	if ( dword_52B970 )
	{
		if ( !dword_52B99C || x >= 0 && x < 640 && y >= 64 && y < 704 )
		{
			v2 = (unsigned char *)gpBuffer + screen_y_times_768[x] + y;
			goto LABEL_14;
		}
	}
	else if ( !dword_52B99C || y >= 0 && y < 640 && x >= 64 && x < 704 )
	{
		v2 = (unsigned char *)gpBuffer + screen_y_times_768[y] + x;
LABEL_14:
		if ( (unsigned int)v2 < screen_buf_end )
			*v2 = byte_52B96C;
		return;
	}
}
// 52B96C: using guessed type char byte_52B96C;
// 52B970: using guessed type int dword_52B970;
// 52B99C: using guessed type int dword_52B99C;
// 69CF0C: using guessed type int screen_buf_end;

//----- (004170BD) --------------------------------------------------------
void __fastcall engine_4170BD(int x1, int y1, int x2, int y2, char a5)
{
	int v5; // edi
	int v6; // edx
	int v7; // ecx
	int v8; // eax
	int v9; // edx
	int v10; // eax
	int v11; // ebx
	int v12; // edx
	int v13; // eax
	int v14; // esi
	int v15; // edi
	__int64 v16; // rax
	int v17; // ebx
	int v18; // esi
	int v19; // edx
	int v20; // edx
	int v21; // edx
	int v22; // edx
	int v23; // edx
	int v24; // esi
	int v25; // edx
	int v26; // ecx
	int v27; // esi
	int v28; // edx
	int v29; // edx
	int v30; // esi
	int v31; // ebx
	int v32; // edi
	int v33; // ebx
	int v34; // edx
	int v35; // eax
	int v36; // edx
	int v37; // edx
	int v38; // edx
	int v39; // edi
	int v40; // esi
	int v41; // esi
	int v42; // esi
	int v43; // edx
	int v44; // [esp+Ch] [ebp-18h]
	int v45; // [esp+10h] [ebp-14h]
	int v46; // [esp+14h] [ebp-10h]
	int v47; // [esp+14h] [ebp-10h]
	int v48; // [esp+18h] [ebp-Ch]
	int v49; // [esp+18h] [ebp-Ch]
	int v50; // [esp+18h] [ebp-Ch]
	int v51; // [esp+1Ch] [ebp-8h]
	int v52; // [esp+1Ch] [ebp-8h]
	int v53; // [esp+1Ch] [ebp-8h]
	signed int v54; // [esp+20h] [ebp-4h]
	int xa; // [esp+2Ch] [ebp+8h]
	int x; // [esp+2Ch] [ebp+8h]
	signed int a4; // [esp+30h] [ebp+Ch]
	int a5a; // [esp+34h] [ebp+10h]
	int a5b; // [esp+34h] [ebp+10h]

	dword_52B99C = 0;
	v5 = y1;
	v6 = x1;
	byte_52B96C = a5;
	v51 = v5;
	v48 = x1;
	if ( x1 < 64 || x1 >= 704 )
		dword_52B99C = 1;
	if ( x2 < 64 || x2 >= 704 )
		dword_52B99C = 1;
	if ( v5 < 160 || v5 >= 512 )
		dword_52B99C = 1;
	v7 = y2;
	if ( y2 < 160 || y2 >= 512 )
		dword_52B99C = 1;
	v8 = x2 - v6;
	v9 = 2 * (x2 - v6 >= 0) - 1;
	v10 = v9 * v8;
	v46 = v10;
	v11 = (2 * (y2 - v5 >= 0) - 1) * (y2 - v5);
	a4 = 2 * (v9 == 2 * (y2 - v5 >= 0) - 1) - 1;
	v12 = v48;
	if ( v11 <= v10 )
	{
		dword_52B970 = 0;
	}
	else
	{
		xa = v7 ^ x2;
		v7 ^= xa;
		v13 = v11 ^ v10;
		v51 = v5 ^ v48 ^ v5;
		v11 ^= v13;
		v12 = v51 ^ v5 ^ v48;
		x2 = v7 ^ xa;
		v10 = v11 ^ v13;
		dword_52B970 = 1;
		v46 = v10;
	}
	v14 = x2;
	if ( v12 <= x2 )
	{
		v15 = v51;
		v14 = v12;
		v12 = x2;
	}
	else
	{
		v15 = v7;
		v7 = v51;
	}
	a5a = v12;
	x = v7;
	v16 = v10 - 1;
	v54 = v16 % 4;
	v45 = v16 / 4;
	engine_417034(v14, v15);
	engine_417034(a5a, x);
	v49 = 2 * v11;
	v44 = 2 * (2 * v11 - v46);
	if ( v44 >= 0 )
	{
		v50 = 2 * (v11 - v46);
		v53 = v46 + 4 * (v11 - v46);
		if ( v45 <= 0 )
		{
			v33 = a5a;
		}
		else
		{
			do
			{
				v30 = v14 + 1;
				v31 = a5a - 1;
				if ( v53 <= 0 )
				{
					if ( v53 >= v50 )
					{
						v15 += a4;
						engine_417034(v30, v15);
						v14 = v30 + 1;
						engine_417034(v14, v38);
						x -= a4;
						engine_417034(v31, x);
					}
					else
					{
						engine_417034(v30, v15);
						v15 += a4;
						v14 = v30 + 1;
						engine_417034(v14, v15);
						engine_417034(v31, x);
						v37 = v36 - a4;
						x = v37;
					}
					v33 = a5a - 2;
					a5a = v33;
					engine_417034(v33, v37);
					v35 = v44;
				}
				else
				{
					v32 = a4 + v15;
					engine_417034(v30, v32);
					v15 = a4 + v32;
					v14 = v30 + 1;
					engine_417034(v14, v15);
					engine_417034(v31, x - a4);
					v33 = a5a - 2;
					a5a = v33;
					x = v34 - a4;
					engine_417034(v33, v34 - a4);
					v35 = 2 * v50;
				}
				v53 += v35;
				--v45;
			}
			while ( v45 );
		}
		if ( !v54 )
			return;
		if ( v53 > 0 )
		{
			v39 = a4 + v15;
			v40 = v14 + 1;
			engine_417034(v40, v39);
			if ( v54 > 1 )
				engine_417034(v40 + 1, v39 + a4);
			if ( v54 <= 2 )
				return;
			goto LABEL_71;
		}
		if ( v53 >= v50 )
		{
			v42 = v14 + 1;
			engine_417034(v42, a4 + v15);
			if ( v54 > 1 )
				engine_417034(v42 + 1, v43);
			if ( v54 <= 2 )
				return;
			if ( v53 > v50 )
			{
LABEL_71:
				v26 = v33 - 1;
				v29 = x - a4;
				goto LABEL_65;
			}
		}
		else
		{
			v41 = v14 + 1;
			engine_417034(v41, v15);
			if ( v54 > 1 )
				engine_417034(v41 + 1, v15 + a4);
			if ( v54 <= 2 )
				return;
		}
		v26 = v33 - 1;
LABEL_64:
		v29 = x;
		goto LABEL_65;
	}
	v52 = 4 * v11;
	v17 = 4 * v11 - v46;
	if ( v45 > 0 )
	{
		v47 = v45;
		do
		{
			v18 = v14 + 1;
			a5b = a5a - 1;
			if ( v17 >= 0 )
			{
				if ( v17 >= v49 )
				{
					v15 += a4;
					engine_417034(v18, v15);
					v14 = v18 + 1;
					engine_417034(v14, v23);
					x -= a4;
					engine_417034(a5b, x);
				}
				else
				{
					engine_417034(v18, v15);
					v15 += a4;
					v14 = v18 + 1;
					engine_417034(v14, v15);
					engine_417034(a5b, x);
					v22 = v21 - a4;
					x = v22;
				}
				a5a = a5b - 1;
				engine_417034(a5a, v22);
				v17 += v44;
			}
			else
			{
				engine_417034(v18, v15);
				v14 = v18 + 1;
				engine_417034(v14, v19);
				engine_417034(a5b, x);
				a5a = a5b - 1;
				engine_417034(a5a, v20);
				v17 += v52;
			}
			--v47;
		}
		while ( v47 );
	}
	if ( v54 )
	{
		if ( v17 < 0 )
		{
			v24 = v14 + 1;
			engine_417034(v24, v15);
			if ( v54 > 1 )
				goto LABEL_36;
			goto LABEL_37;
		}
		if ( v17 < v49 )
		{
			v24 = v14 + 1;
			engine_417034(v24, v15);
			if ( v54 > 1 )
			{
				v25 = v15 + a4;
LABEL_36:
				engine_417034(v24 + 1, v25);
			}
LABEL_37:
			if ( v54 <= 2 )
				return;
			v26 = a5a - 1;
			goto LABEL_64;
		}
		v27 = v14 + 1;
		engine_417034(v27, a4 + v15);
		if ( v54 > 1 )
			engine_417034(v27 + 1, v28);
		if ( v54 > 2 )
		{
			v29 = x - a4;
			v26 = a5a - 1;
LABEL_65:
			engine_417034(v26, v29);
			return;
		}
	}
}
// 52B96C: using guessed type char byte_52B96C;
// 52B970: using guessed type int dword_52B970;
// 52B99C: using guessed type int dword_52B99C;

//----- (004174B3) --------------------------------------------------------
int __fastcall GetDirection(int x1, int y1, int x2, int y2)
{
	int v4; // esi
	int v5; // ecx
	int v6; // edx
	int result; // eax
	int v8; // esi
	int v9; // edx

	v4 = x2 - x1;
	v5 = y2 - y1;
	if ( v4 < 0 )
	{
		v8 = -v4;
		v9 = 2 * v8;
		if ( v5 < 0 )
		{
			v5 = -v5;
			result = 4;
			if ( v9 < v5 )
				result = 5;
		}
		else
		{
			result = 2;
			if ( v9 < v5 )
				result = 1;
		}
		if ( 2 * v5 < v8 )
			return 3;
	}
	else
	{
		v6 = 2 * v4;
		if ( v5 < 0 )
		{
			v5 = -v5;
			result = 6;
			if ( v6 < v5 )
				result = 5;
		}
		else
		{
			result = 0;
			if ( v6 < v5 )
				result = 1;
		}
		if ( 2 * v5 < v4 )
			return 7;
	}
	return result;
}

//----- (00417518) --------------------------------------------------------
void __fastcall SetRndSeed(int s)
{
	SeedCount = 0;
	sglGameSeed = s;
	orgseed = s;
}
// 52B974: using guessed type int orgseed;
// 52B97C: using guessed type int sglGameSeed;
// 52B998: using guessed type int SeedCount;

//----- (0041752C) --------------------------------------------------------
int __cdecl GetRndSeed()
{
	++SeedCount;
	sglGameSeed = 22695477 * sglGameSeed + 1;
	return abs(sglGameSeed);
}
// 52B97C: using guessed type int sglGameSeed;
// 52B998: using guessed type int SeedCount;

//----- (0041754B) --------------------------------------------------------
int __fastcall random(int unused, int max)
{
	int v2; // esi
	int v4; // eax

	v2 = max;
	if ( max <= 0 )
		return 0;
	v4 = GetRndSeed();
	if ( v2 < 0xFFFF )
		v4 >>= 16;
	return v4 % v2;
}

//----- (0041756D) --------------------------------------------------------
void __cdecl engine_cpp_init_2()
{
	mem_init_mutex();
	mem_atexit_mutex();
}

//----- (00417577) --------------------------------------------------------
void __cdecl mem_init_mutex()
{
	InitializeCriticalSection(&sgMemCrit);
}

//----- (00417583) --------------------------------------------------------
void __cdecl mem_atexit_mutex()
{
	atexit(mem_free_mutex);
}

//----- (0041758F) --------------------------------------------------------
void __cdecl mem_free_mutex()
{
	DeleteCriticalSection(&sgMemCrit);
}

//----- (0041759B) --------------------------------------------------------
void *__fastcall DiabloAllocPtr(int size)
{
	int v1; // ebx
	void *v2; // ebx
	int v3; // eax

	v1 = size;
	EnterCriticalSection(&sgMemCrit);
	v2 = SMemAlloc(v1, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2236, 0);
	LeaveCriticalSection(&sgMemCrit);
	if ( !v2 )
	{
		v3 = GetLastError();
		TermDlg(105, v3, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2269);
	}
	return v2;
}

//----- (004175E8) --------------------------------------------------------
void __fastcall mem_free_dbg(void *ptr)
{
	void *v1; // edi

	v1 = ptr;
	if ( ptr )
	{
		EnterCriticalSection(&sgMemCrit);
		SMemFree(v1, "C:\\Src\\Diablo\\Source\\ENGINE.CPP", 2317, 0);
		LeaveCriticalSection(&sgMemCrit);
	}
}

//----- (00417618) --------------------------------------------------------
unsigned char *__fastcall LoadFileInMem(char *file_path, void *size)
{
	_DWORD *v2; // edi
	char *v3; // ebx
	int v4; // eax
	int v5; // esi
	char *v6; // edi
	void *a1; // [esp+Ch] [ebp-4h]

	v2 = (unsigned int *)size;
	v3 = file_path;
	wave_open_file((LPARAM)file_path, (DIABFILE *)&a1, 0);
	v4 = wave_get_file_size((int *)a1, 0);
	v5 = v4;
	if ( v2 )
		*v2 = v4;
	if ( !v4 )
		TermMsg("Zero length SFILE:\n%s", v3);
	v6 = (char *)DiabloAllocPtr(v5);
	wave_read_file((int)a1, v6, v5);
	wave_close_file(a1);
	return (unsigned char *)v6;
}

//----- (00417673) --------------------------------------------------------
void __fastcall LoadFileWithMem(char *pszName, void *buf)
{
	char *v2; // ebx
	char *v3; // edi
	int v4; // esi
	void *a1; // [esp+Ch] [ebp-4h]

	v2 = (char *)buf;
	v3 = pszName;
	if ( !buf )
		TermMsg("LoadFileWithMem(NULL):\n%s", pszName);
	wave_open_file((LPARAM)v3, (DIABFILE *)&a1, 0);
	v4 = wave_get_file_size((int *)a1, 0);
	if ( !v4 )
		TermMsg("Zero length SFILE:\n%s", v3);
	wave_read_file((int)a1, v2, v4);
	wave_close_file(a1);
}

//----- (004176D2) --------------------------------------------------------
void __fastcall engine_cel_trn(int p, int ttbl, int a3)
{
	int v3; // eax
	int v4; // edi
	int v5; // esi
	char *v6; // eax
	char v7; // bl
	unsigned char v8; // bl
	int v9; // edi
	int i; // [esp+0h] [ebp-4h]

	v3 = 1;
	for ( i = 1; i <= a3; ++i )
	{
		v4 = *(_DWORD *)(4 * v3 + p);
		v5 = *(_DWORD *)(4 * v3 + p + 4) - v4 - 10;
		v6 = (char *)(v4 + p + 10);
		while ( v5 )
		{
			v7 = *v6++;
			--v5;
			if ( v7 < 0 )
			{
				v8 = -v7;
				if ( (char)v8 <= 65 )
				{
					v5 -= (char)v8;
					if ( v8 )
					{
						v9 = v8;
						do
						{
							*v6 = *(_BYTE *)((unsigned char)*v6 + ttbl);
							++v6;
							--v9;
						}
						while ( v9 );
					}
				}
				else
				{
					--v5;
					*v6 = *(_BYTE *)((unsigned char)*v6 + ttbl);
					++v6;
				}
			}
		}
		v3 = i + 1;
	}
}

//----- (00417745) --------------------------------------------------------
void __fastcall engine_417745(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7)
{
	int v7; // ebx
	void *v8; // edx
	char *v9; // ecx
	int v10; // ecx
	int v11; // eax
	int v12; // [esp+Ch] [ebp-4h]
	void *pCelBuffa; // [esp+18h] [ebp+8h]

	v7 = a2;
	v12 = a1;
	if ( gpBuffer )
	{
		v8 = pCelBuff;
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v9 = (char *)*((_DWORD *)pCelBuff + nCel);
				pCelBuffa = v9;
				v10 = (int)&v9[(_DWORD)v8];
				if ( *(_WORD *)(v10 + a6) )
				{
					if ( a7 == 8 || (v11 = *(unsigned short *)(v10 + a7), !*(_WORD *)(v10 + a7)) )
						v11 = *((_DWORD *)v8 + nCel + 1) - (_DWORD)pCelBuffa;
					engine_4177BF(
						(char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + v12,
						(char *)(*(unsigned short *)(v10 + a6) + v10),
						v11 - *(unsigned short *)(v10 + a6),
						a5);
				}
			}
		}
	}
}

//----- (004177BF) --------------------------------------------------------
void __fastcall engine_4177BF(char *buffer, char *a2, int a3, int a4)
{
	char *v4; // esi
	char *v5; // edi
	int v6; // eax
	int v7; // ebx
	int v8; // ecx
	char v9; // dl
	char v10; // dl
	int v11; // edx

	v4 = a2;
	v5 = buffer;
	v6 = 0;
	v7 = a4;
	v8 = a3;
	do
	{
		_LOBYTE(v6) = *v4++;
		--v8;
		if ( (v6 & 0x80u) == 0 )
		{
			do
			{
				if ( v6 <= v7 )
				{
					v11 = v6;
					v5 += v6;
					v6 = 0;
				}
				else
				{
					v11 = v7;
					v5 += v7;
					v6 -= v7;
				}
				v7 -= v11;
				if ( !v7 )
				{
					v7 = a4;
					v5 = &v5[-a4 - 768];
				}
			}
			while ( v6 );
		}
		else
		{
			_LOBYTE(v6) = -(char)v6;
			if ( (char)v6 <= 65 )
			{
				v8 -= v6;
				v7 -= v6;
				do
				{
					v10 = *v4++;
					*v5 = v10;
					--v6;
					++v5;
				}
				while ( v6 );
			}
			else
			{
				_LOBYTE(v6) = v6 - 65;
				--v8;
				v9 = *v4++;
				v7 -= v6;
				do
				{
					*v5 = v9;
					--v6;
					++v5;
				}
				while ( v6 );
			}
			if ( !v7 )
			{
				v7 = a4;
				v5 = &v5[-a4 - 768];
			}
		}
	}
	while ( v8 );
}

//----- (00417847) --------------------------------------------------------
void __fastcall engine_417847(char a1, int a2, int a3, void *pCelBuff, int nCel, int a6, int a7, int a8)
{
	int v8; // ebx
	char *v9; // edx
	int v10; // eax
	int v11; // [esp+Ch] [ebp-8h]

	v11 = a2;
	if ( gpBuffer )
	{
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v8 = *((_DWORD *)pCelBuff + nCel);
				v9 = (char *)pCelBuff + v8;
				if ( *(_WORD *)((char *)pCelBuff + v8 + a7) )
				{
					if ( a8 == 8 || (v10 = *(unsigned short *)&v9[a8], !*(_WORD *)&v9[a8]) )
						v10 = *((_DWORD *)pCelBuff + nCel + 1) - v8;
					engine_4178C5(
						(char *)gpBuffer + screen_y_times_768[a3 - 16 * a7] + v11,
						&v9[*(unsigned short *)((char *)pCelBuff + v8 + a7)],
						(char *)(v10 - *(unsigned short *)((char *)pCelBuff + v8 + a7)),
						a6,
						a1);
				}
			}
		}
	}
}

//----- (004178C5) --------------------------------------------------------
void __fastcall engine_4178C5(char *buffer, char *a2, char *a3, int a4, char a5)
{
	char *v5; // esi
	char *v6; // edi
	int v7; // eax
	int v8; // ebx
	char *v9; // ecx
	char v10; // dl
	char v11; // dh
	char v12; // dh
	int v13; // edx

	v5 = a2;
	v6 = buffer;
	v7 = 0;
	v8 = a4;
	v9 = a3;
	v10 = a5;
	do
	{
		_LOBYTE(v7) = *v5++;
		--v9;
		if ( (v7 & 0x80u) != 0 )
		{
			_LOBYTE(v7) = -(char)v7;
			if ( (char)v7 <= 65 )
			{
				v9 -= v7;
				v8 -= v7;
				do
				{
					v12 = *v5++;
					if ( v12 )
					{
						*(v6 - 1) = v10;
						v6[1] = v10;
						*(v6 - 768) = v10;
						v6[768] = v10;
					}
					--v7;
					++v6;
				}
				while ( v7 );
				goto LABEL_12;
			}
			_LOBYTE(v7) = v7 - 65;
			--v9;
			v11 = *v5++;
			if ( v11 )
			{
				*(v6 - 1) = v10;
				v8 -= v7;
				v6[v7] = v10;
				do
				{
					*(v6 - 768) = v10;
					v6[768] = v10;
					--v7;
					++v6;
				}
				while ( v7 );
LABEL_12:
				if ( !v8 )
				{
					v8 = a4;
					v6 = &v6[-a4 - 768];
				}
				continue;
			}
		}
		do
		{
			if ( v7 <= v8 )
			{
				v13 = v7;
				v6 += v7;
				v7 = 0;
			}
			else
			{
				v13 = v8;
				v6 += v8;
				v7 -= v8;
			}
			v8 -= v13;
			if ( !v8 )
			{
				v8 = a4;
				v6 = &v6[-a4 - 768];
			}
		}
		while ( v7 );
		v10 = a5;
	}
	while ( v9 );
}

//----- (00417981) --------------------------------------------------------
void __fastcall engine_417981(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7, char a8)
{
	_DWORD *v8; // edi
	int v9; // ebx
	char *v10; // esi
	int v11; // eax
	int v12; // eax
	char *v13; // esi
	int v14; // edi
	int v15; // eax
	int v16; // eax
	void *pCelBuffa; // [esp+18h] [ebp+8h]

	if ( gpBuffer )
	{
		v8 = (unsigned int *)pCelBuff;
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v9 = *((_DWORD *)pCelBuff + nCel);
				v10 = (char *)pCelBuff + v9;
				v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6);
				pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6);
				if ( v11 )
				{
					if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) )
						v12 = v8[nCel + 1] - v9;
					v13 = &v10[(_DWORD)pCelBuffa];
					v14 = v12 - (_DWORD)pCelBuffa;
					v15 = -(light4flag != 0);
					_LOWORD(v15) = v15 & 0xF400;
					v16 = v15 + 4096;
					if ( a8 == 2 )
						v16 += 256;
					if ( a8 >= 4 )
						v16 = v16 + (a8 << 8) - 256;
					engine_417A44(
						(char *)gpBuffer + screen_y_times_768[a2 - 16 * a6] + a1,
						v13,
						v14,
						a5,
						v16 + dword_646A20);
				}
			}
		}
	}
}
// 525728: using guessed type int light4flag;

//----- (00417A44) --------------------------------------------------------
void __fastcall engine_417A44(char *a1, char *a2, int a3, int a4, int unused_lindex)
{
	char *v5; // esi
	char *v6; // edi
	int v7; // ebx
	int v8; // ecx
	int v9; // eax
	int v10; // edx
	char v11; // dl
	char vars0[4]; // [esp+Ch] [ebp+0h]

	v5 = a2;
	v6 = a1;
	v7 = a4;
	v8 = a3;
	dword_52B978 = a4;
	v9 = 0;
	v10 = 0;
	do
	{
		_LOBYTE(v9) = *v5++;
		--v8;
		if ( (v9 & 0x80u) == 0 )
		{
			do
			{
				if ( v9 <= v7 )
				{
					v10 = v9;
					v6 += v9;
					v9 = 0;
				}
				else
				{
					v10 = v7;
					v6 += v7;
					v9 -= v7;
				}
				v7 -= v10;
				if ( !v7 )
				{
					v7 = dword_52B978;
					v6 = &v6[-dword_52B978 - 768];
				}
			}
			while ( v9 );
		}
		else
		{
			_LOBYTE(v9) = -(char)v9;
			if ( (char)v9 <= 65 )
			{
				v8 -= v9;
				v7 -= v9;
				do
				{
					_LOBYTE(v10) = *v5++;
					*v6 = vars0[v10];
					--v9;
					++v6;
				}
				while ( v9 );
			}
			else
			{
				_LOBYTE(v9) = v9 - 65;
				--v8;
				v7 -= v9;
				_LOBYTE(v10) = *v5++;
				v11 = vars0[v10];
				do
				{
					*v6 = v11;
					--v9;
					++v6;
				}
				while ( v9 );
			}
			if ( !v7 )
			{
				v7 = dword_52B978;
				v6 = &v6[-dword_52B978 - 768];
			}
		}
	}
	while ( v8 );
}
// 52B978: using guessed type int dword_52B978;
// 417A44: using guessed type char var_s0[4];

//----- (00417AE9) --------------------------------------------------------
void __fastcall engine_417AE9(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7)
{
	int v7; // esi
	_DWORD *v8; // edi
	int v9; // ebx
	char *v10; // edx
	int v11; // eax
	int v12; // eax
	int v13; // eax
	char *v14; // edx
	char *v15; // ecx
	void *pCelBuffa; // [esp+18h] [ebp+8h]

	v7 = a2;
	if ( gpBuffer )
	{
		v8 = (unsigned int *)pCelBuff;
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v9 = *((_DWORD *)pCelBuff + nCel);
				v10 = (char *)pCelBuff + v9;
				v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6);
				pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6);
				if ( v11 )
				{
					if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) )
						v12 = v8[nCel + 1] - v9;
					v13 = v12 - (_DWORD)pCelBuffa;
					v14 = &v10[(_DWORD)pCelBuffa];
					v15 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + a1;
					if ( light_table_index )
						engine_417A44(v15, v14, v13, a5, dword_646A20 + (light_table_index << 8));
					else
						engine_4177BF(v15, v14, v13, a5);
				}
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00417B83) --------------------------------------------------------
void __fastcall engine_417B83(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7)
{
	int v7; // ebx
	void *v8; // edx
	char *v9; // ecx
	int v10; // ecx
	int v11; // eax
	int v12; // [esp+Ch] [ebp-4h]
	void *pCelBuffa; // [esp+18h] [ebp+8h]

	v7 = a2;
	v12 = a1;
	if ( gpBuffer )
	{
		v8 = pCelBuff;
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v9 = (char *)*((_DWORD *)pCelBuff + nCel);
				pCelBuffa = v9;
				v10 = (int)&v9[(_DWORD)v8];
				if ( *(_WORD *)(v10 + a6) )
				{
					if ( a7 == 8 || (v11 = *(unsigned short *)(v10 + a7), !*(_WORD *)(v10 + a7)) )
						v11 = *((_DWORD *)v8 + nCel + 1) - (_DWORD)pCelBuffa;
					engine_417BFD(
						(char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + v12,
						(char *)(*(unsigned short *)(v10 + a6) + v10),
						v11 - *(unsigned short *)(v10 + a6),
						a5);
				}
			}
		}
	}
}

//----- (00417BFD) --------------------------------------------------------
void __fastcall engine_417BFD(char *a1, char *a2, int a3, int a4)
{
	char *v4; // esi
	char *v5; // edi
	int v6; // eax
	int v7; // ebx
	int v8; // ecx
	char v9; // dl
	char v10; // dl
	int v11; // edx

	v4 = a2;
	v5 = a1;
	v6 = 0;
	v7 = a4;
	v8 = a3;
	do
	{
		_LOBYTE(v6) = *v4++;
		--v8;
		if ( (v6 & 0x80u) != 0 )
		{
			_LOBYTE(v6) = -(char)v6;
			if ( (char)v6 <= 65 )
			{
				v8 -= v6;
				if ( (signed int)v5 < screen_buf_end )
				{
					v7 -= v6;
					do
					{
						v10 = *v4++;
						*v5 = v10;
						--v6;
						++v5;
					}
					while ( v6 );
					goto LABEL_12;
				}
				v4 += v6;
			}
			else
			{
				_LOBYTE(v6) = v6 - 65;
				--v8;
				v9 = *v4++;
				if ( (signed int)v5 < screen_buf_end )
				{
					v7 -= v6;
					do
					{
						*v5 = v9;
						--v6;
						++v5;
					}
					while ( v6 );
LABEL_12:
					if ( !v7 )
					{
						v7 = a4;
						v5 = &v5[-a4 - 768];
					}
					continue;
				}
			}
		}
		do
		{
			if ( v6 <= v7 )
			{
				v11 = v6;
				v5 += v6;
				v6 = 0;
			}
			else
			{
				v11 = v7;
				v5 += v7;
				v6 -= v7;
			}
			v7 -= v11;
			if ( !v7 )
			{
				v7 = a4;
				v5 = &v5[-a4 - 768];
			}
		}
		while ( v6 );
	}
	while ( v8 );
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (00417C99) --------------------------------------------------------
void __fastcall engine_417C99(char a1, int a2, int a3, void *pCelBuff, int nCel, int a6, int a7, int a8)
{
	int v8; // ebx
	char *v9; // edx
	int v10; // ecx
	int v11; // eax
	int v12; // [esp+Ch] [ebp-8h]
	char a5; // [esp+10h] [ebp-4h]

	v12 = a2;
	a5 = a1;
	if ( gpBuffer )
	{
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v8 = *((_DWORD *)pCelBuff + nCel);
				v9 = (char *)pCelBuff + v8;
				v10 = *(unsigned short *)((char *)pCelBuff + v8 + a7);
				if ( *(_WORD *)((char *)pCelBuff + v8 + a7) )
				{
					if ( a8 == 8 || (v11 = *(unsigned short *)&v9[a8], !*(_WORD *)&v9[a8]) )
						v11 = *((_DWORD *)pCelBuff + nCel + 1) - v8;
					screen_buf_end -= 768;
					engine_417D28(
						(char *)gpBuffer + screen_y_times_768[a3 - 16 * a7] + v12,
						&v9[v10],
						v11 - v10,
						a6,
						a5);
					screen_buf_end += 768;
				}
			}
		}
	}
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (00417D28) --------------------------------------------------------
void __fastcall engine_417D28(char *a1, char *a2, int a3, int a4, char a5)
{
	char *v5; // esi
	char *v6; // edi
	int v7; // eax
	int v8; // ebx
	int v9; // ecx
	char v10; // dl
	char v11; // dh
	char v12; // dh
	int v13; // edx

	v5 = a2;
	v6 = a1;
	v7 = 0;
	v8 = a4;
	v9 = a3;
	v10 = a5;
	do
	{
		_LOBYTE(v7) = *v5++;
		--v9;
		if ( (v7 & 0x80u) != 0 )
		{
			_LOBYTE(v7) = -(char)v7;
			if ( (char)v7 <= 65 )
			{
				v9 -= v7;
				if ( (signed int)v6 < screen_buf_end )
				{
					v8 -= v7;
					do
					{
						v12 = *v5++;
						if ( v12 )
						{
							*(v6 - 1) = v10;
							v6[1] = v10;
							*(v6 - 768) = v10;
							v6[768] = v10;
						}
						--v7;
						++v6;
					}
					while ( v7 );
					goto LABEL_15;
				}
				v5 += v7;
			}
			else
			{
				_LOBYTE(v7) = v7 - 65;
				--v9;
				v11 = *v5++;
				if ( v11 && (signed int)v6 < screen_buf_end )
				{
					*(v6 - 1) = v10;
					v8 -= v7;
					v6[v7] = v10;
					do
					{
						*(v6 - 768) = v10;
						v6[768] = v10;
						--v7;
						++v6;
					}
					while ( v7 );
LABEL_15:
					if ( !v8 )
					{
						v8 = a4;
						v6 = &v6[-a4 - 768];
					}
					continue;
				}
			}
		}
		do
		{
			if ( v7 <= v8 )
			{
				v13 = v7;
				v6 += v7;
				v7 = 0;
			}
			else
			{
				v13 = v8;
				v6 += v8;
				v7 -= v8;
			}
			v8 -= v13;
			if ( !v8 )
			{
				v8 = a4;
				v6 = &v6[-a4 - 768];
			}
		}
		while ( v7 );
		v10 = a5;
	}
	while ( v9 );
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (00417DF8) --------------------------------------------------------
void __fastcall engine_417DF8(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7, char a8)
{
	_DWORD *v8; // edi
	int v9; // ebx
	char *v10; // esi
	int v11; // eax
	int v12; // eax
	char *v13; // esi
	int v14; // edi
	int v15; // eax
	int v16; // eax
	void *pCelBuffa; // [esp+18h] [ebp+8h]

	if ( gpBuffer )
	{
		v8 = (unsigned int *)pCelBuff;
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v9 = *((_DWORD *)pCelBuff + nCel);
				v10 = (char *)pCelBuff + v9;
				v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6);
				pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6);
				if ( v11 )
				{
					if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) )
						v12 = v8[nCel + 1] - v9;
					v13 = &v10[(_DWORD)pCelBuffa];
					v14 = v12 - (_DWORD)pCelBuffa;
					v15 = -(light4flag != 0);
					_LOWORD(v15) = v15 & 0xF400;
					v16 = v15 + 4096;
					if ( a8 == 2 )
						v16 += 256;
					if ( a8 >= 4 )
						v16 = v16 + (a8 << 8) - 256;
					engine_417EBB(
						(char *)gpBuffer + screen_y_times_768[a2 - 16 * a6] + a1,
						v13,
						v14,
						a5,
						v16 + dword_646A20);
				}
			}
		}
	}
}
// 525728: using guessed type int light4flag;

//----- (00417EBB) --------------------------------------------------------
void __fastcall engine_417EBB(char *a1, char *a2, int a3, int a4, int a5)
{
	char *v5; // esi
	char *v6; // edi
	int v7; // ebx
	int v8; // ecx
	int v9; // eax
	int v10; // edx
	char v11; // dl
	char vars0[4]; // [esp+Ch] [ebp+0h]

	v5 = a2;
	v6 = a1;
	v7 = a4;
	v8 = a3;
	dword_52B978 = a4;
	v9 = 0;
	v10 = 0;
	do
	{
		_LOBYTE(v9) = *v5++;
		--v8;
		if ( (v9 & 0x80u) != 0 )
		{
			_LOBYTE(v9) = -(char)v9;
			if ( (char)v9 <= 65 )
			{
				v8 -= v9;
				if ( (signed int)v6 < screen_buf_end )
				{
					v7 -= v9;
					do
					{
						_LOBYTE(v10) = *v5++;
						*v6 = vars0[v10];
						--v9;
						++v6;
					}
					while ( v9 );
					goto LABEL_12;
				}
				v5 += v9;
			}
			else
			{
				_LOBYTE(v9) = v9 - 65;
				--v8;
				_LOBYTE(v10) = *v5++;
				v11 = vars0[v10];
				if ( (signed int)v6 < screen_buf_end )
				{
					v7 -= v9;
					do
					{
						*v6 = v11;
						--v9;
						++v6;
					}
					while ( v9 );
LABEL_12:
					if ( !v7 )
					{
						v7 = dword_52B978;
						v6 = &v6[-dword_52B978 - 768];
					}
					continue;
				}
			}
		}
		do
		{
			if ( v9 <= v7 )
			{
				v10 = v9;
				v6 += v9;
				v9 = 0;
			}
			else
			{
				v10 = v7;
				v6 += v7;
				v9 -= v7;
			}
			v7 -= v10;
			if ( !v7 )
			{
				v7 = dword_52B978;
				v6 = &v6[-dword_52B978 - 768];
			}
		}
		while ( v9 );
	}
	while ( v8 );
}
// 52B978: using guessed type int dword_52B978;
// 69CF0C: using guessed type int screen_buf_end;
// 417EBB: using guessed type char var_s0[4];

//----- (00417F78) --------------------------------------------------------
void __fastcall engine_417F78(int a1, int a2, void *pCelBuff, int nCel, int a5, int a6, int a7)
{
	int v7; // esi
	_DWORD *v8; // edi
	int v9; // ebx
	char *v10; // edx
	int v11; // eax
	int v12; // eax
	int v13; // eax
	char *v14; // edx
	char *v15; // ecx
	void *pCelBuffa; // [esp+18h] [ebp+8h]

	v7 = a2;
	if ( gpBuffer )
	{
		v8 = (unsigned int *)pCelBuff;
		if ( pCelBuff )
		{
			if ( nCel > 0 )
			{
				v9 = *((_DWORD *)pCelBuff + nCel);
				v10 = (char *)pCelBuff + v9;
				v11 = *(unsigned short *)((char *)pCelBuff + v9 + a6);
				pCelBuffa = (void *)*(unsigned short *)((char *)pCelBuff + v9 + a6);
				if ( v11 )
				{
					if ( a7 == 8 || (v12 = *(unsigned short *)&v10[a7], !*(_WORD *)&v10[a7]) )
						v12 = v8[nCel + 1] - v9;
					v13 = v12 - (_DWORD)pCelBuffa;
					v14 = &v10[(_DWORD)pCelBuffa];
					v15 = (char *)gpBuffer + screen_y_times_768[v7 - 16 * a6] + a1;
					if ( light_table_index )
						engine_417EBB(v15, v14, v13, a5, dword_646A20 + (light_table_index << 8));
					else
						engine_417BFD(v15, v14, v13, a5);
				}
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00418012) --------------------------------------------------------
void __fastcall PlayInGameMovie(char *pszMovie)
{
	char *v1; // esi

	v1 = pszMovie;
	PaletteFadeOut(8);
	play_movie(v1, 0);
	ClearScreenBuffer();
	force_redraw = 255;
	scrollrt_455E65(1);
	PaletteFadeIn(8);
	force_redraw = 255;
}
// 52571C: using guessed type int force_redraw;

//----- (0041804E) --------------------------------------------------------
void __fastcall InitDiabloMsg(int error_id)
{
	int v1; // edx
	bool v2; // sf
	unsigned char v3; // of

	v1 = 0;
	if ( msgcnt <= 0 )
	{
LABEL_4:
		v3 = __OFSUB__(msgcnt, 80);
		v2 = (char)(msgcnt - 80) < 0;
		msgtable[msgcnt] = error_id;
		if ( v2 ^ v3 )
			++msgcnt;
		msgdelay = 70;
		msgflag = msgtable[0];
	}
	else
	{
		while ( msgtable[v1] != (_BYTE)error_id )
		{
			if ( ++v1 >= msgcnt )
				goto LABEL_4;
		}
	}
}
// 52B9F0: using guessed type char msgdelay;
// 52B9F1: using guessed type char msgflag;
// 52B9F2: using guessed type char msgcnt;

//----- (0041808F) --------------------------------------------------------
void __cdecl ClrDiabloMsg()
{
	msgflag = 0;
	msgcnt = 0;
	memset(msgtable, 0, sizeof(msgtable));
}
// 52B9F1: using guessed type char msgflag;
// 52B9F2: using guessed type char msgcnt;

//----- (004180AA) --------------------------------------------------------
void __cdecl DrawDiabloMsg()
{
	int v0; // esi
	signed int v1; // edi
	char *v2; // edi
	signed int v3; // edx
	signed int v4; // ecx
	int v5; // edi
	signed int v6; // ecx
	_BYTE *v7; // edi
	int v8; // edi
	signed int v9; // ebx
	signed int v10; // eax
	signed int v11; // ecx
	int v12; // esi
	signed int v13; // esi
	unsigned char v14; // bl
	bool v15; // zf
	signed int v16; // [esp+Ch] [ebp-8h]
	signed int v17; // [esp+Ch] [ebp-8h]
	signed int screen_x; // [esp+10h] [ebp-4h]

	Cel_decode(165, 318, pSTextSlidCels, 1, 12);
	Cel_decode(591, 318, pSTextSlidCels, 4, 12);
	Cel_decode(165, 366, pSTextSlidCels, 2, 12);
	Cel_decode(591, 366, pSTextSlidCels, 3, 12);
	screen_x = 173;
	v16 = 35;
	do
	{
		Cel_decode(screen_x, 318, pSTextSlidCels, 5, 12);
		Cel_decode(screen_x, 366, pSTextSlidCels, 7, 12);
		screen_x += 12;
		--v16;
	}
	while ( v16 );
	v0 = 330;
	v1 = 3;
	do
	{
		Cel_decode(165, v0, pSTextSlidCels, 6, 12);
		Cel_decode(591, v0, pSTextSlidCels, 8, 12);
		v0 += 12;
		--v1;
	}
	while ( v1 );
	v2 = &gpBuffer->row[203].pixels[104];
	v3 = 27;
	do
	{
		v4 = 216;
		do
		{
			*v2 = 0;
			v2 += 2;
			--v4;
		}
		while ( v4 );
		v5 = (int)(v2 - 1200);
		v6 = 216;
		do
		{
			v7 = (_BYTE *)(v5 + 1);
			*v7 = 0;
			v5 = (int)(v7 + 1);
			--v6;
		}
		while ( v6 );
		v2 = (char *)(v5 - 1200);
		--v3;
	}
	while ( v3 );
	strcpy(tempstr, MsgStrings[msgflag]);
	v8 = screen_y_times_768[342] + 165;
	v9 = strlen(tempstr);
	v10 = 0;
	v11 = 0;
	v17 = v9;
	if ( v9 <= 0 )
		goto LABEL_27;
	do
	{
		v12 = (unsigned char)tempstr[v11++];
		v10 += fontkern[fontframe[fontidx[v12]]] + 1;
	}
	while ( v11 < v9 );
	if ( v10 < 442 )
LABEL_27:
		v8 += (442 - v10) >> 1;
	v13 = 0;
	if ( v9 > 0 )
	{
		do
		{
			v14 = fontframe[fontidx[(unsigned char)tempstr[v13]]];
			if ( v14 )
				CPrintString(v8, (char *)v14, 3);
			++v13;
			v8 += fontkern[v14] + 1;
		}
		while ( v13 < v17 );
	}
	v15 = msgdelay == 0;
	if ( msgdelay > 0 )
		v15 = --msgdelay == 0;
	if ( v15 )
	{
		v15 = msgcnt-- == 1;
		msgdelay = 70;
		if ( v15 )
			msgflag = 0;
		else
			msgflag = msgtable[msgcnt];
	}
}
// 52B9F0: using guessed type char msgdelay;
// 52B9F1: using guessed type char msgflag;
// 52B9F2: using guessed type char msgcnt;

//----- (004182AD) --------------------------------------------------------
void __cdecl exception_cpp_init()
{
	exception_install_filter();
	j_exception_init_filter();
}

//----- (004182B7) --------------------------------------------------------
int *__cdecl exception_install_filter()
{
	int *result; // eax

	exception_set_filter();
	return result;
}

//----- (004182C1) --------------------------------------------------------
void __cdecl j_exception_init_filter()
{
	atexit(exception_init_filter);
}

//----- (004182CD) --------------------------------------------------------
void __cdecl exception_init_filter()
{
	exception_set_filter_ptr();
}

//----- (004182D7) --------------------------------------------------------
LONG __fastcall TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
	DWORD *v1; // esi
	int v2; // eax
	PCONTEXT v3; // esi
	LONG result; // eax
	CHAR v5[260]; // [esp+Ch] [ebp-210h]
	char String1[260]; // [esp+110h] [ebp-10Ch]
	int a5; // [esp+214h] [ebp-8h]
	int a4; // [esp+218h] [ebp-4h]
	struct _EXCEPTION_POINTERS *ExceptionInfoa; // [esp+224h] [ebp+8h]

	log_dump_computer_info();
	v1 = &ExceptionInfoa->ExceptionRecord->ExceptionCode;
	v2 = exception_get_error_type(ExceptionInfoa->ExceptionRecord->ExceptionCode, v5, 0x104u);
	log_printf("Exception code: %08X %s\r\n", *v1, v2);
	exception_unknown_module((LPCVOID)v1[3], String1, 260, (int)&a4, (int)&a5);
	log_printf("Fault address:\t%08X %02X:%08X %s\r\n", v1[3], a4, a5, String1);
	v3 = ExceptionInfoa->ContextRecord;
	log_printf("\r\nRegisters:\r\n");
	log_printf(
		"EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n",
		v3->Eax,
		v3->Ebx,
		v3->Ecx,
		v3->Edx,
		v3->Esi,
		v3->Edi);
	log_printf("CS:EIP:%04X:%08X\r\n", v3->SegCs, v3->Eip);
	log_printf("SS:ESP:%04X:%08X EBP:%08X\r\n", v3->SegSs, v3->Esp, v3->Ebp);
	log_printf("DS:%04X ES:%04X FS:%04X GS:%04X\r\n", v3->SegDs, v3->SegEs, v3->SegFs, v3->SegGs);
	log_printf("Flags:%08X\r\n", v3->EFlags);
	exception_call_stack((void *)v3->Eip, (LPVOID)v3->Ebp);
	log_printf("Stack bytes:\r\n");
	exception_hex_format((char *)v3->Esp, 0);
	log_printf("Code bytes:\r\n");
	exception_hex_format((char *)v3->Eip, 16);
	log_printf("\r\n");
	log_flush(1);
	if ( lpTopLevelExceptionFilter )
		result = lpTopLevelExceptionFilter(ExceptionInfoa);
	else
		result = 0;
	return result;
}

//----- (00418455) --------------------------------------------------------
int __fastcall exception_hex_format(char *a1, char a2)
{
	unsigned int v2; // ebp
	char *v3; // edi
	UINT_PTR v4; // ebx
	unsigned int v5; // esi
	char *v6; // eax
	int v7; // ST04_4
	UINT_PTR v8; // esi
	unsigned char v9; // al
	int result; // eax

	v2 = a2;
	v3 = a1;
	if ( a2 )
	{
		do
		{
			v4 = 16;
			if ( v2 < 0x10 )
				v4 = v2;
			if ( IsBadReadPtr(v3, v4) )
				break;
			log_printf("0x%08x: ");
			v5 = 0;
			do
			{
				v6 = "%02x ";
				if ( v5 >= v4 )
					v6 = "   ";
				v7 = (unsigned char)v3[v5];
				log_printf(v6);
				if ( (v5 & 3) == 3 )
					log_printf(" ");
				++v5;
			}
			while ( v5 < 0x10 );
			v8 = 0;
			if ( v4 )
			{
				do
				{
					if ( isprint((unsigned char)v3[v8]) )
						v9 = v3[v8];
					else
						v9 = 46;
					log_printf("%c", v9);
					++v8;
				}
				while ( v8 < v4 );
			}
			log_printf("\r\n");
			v3 += v4;
			v2 -= v4;
		}
		while ( v2 );
	}
	log_printf("\r\n");
	return result;
}

//----- (00418518) --------------------------------------------------------
int __fastcall exception_unknown_module(LPCVOID lpAddress, LPSTR lpString1, int iMaxLength, int a4, int a5)
{
	LPCVOID v5; // esi
	int result; // eax
	unsigned int v7; // edi
	unsigned int v8; // esi
	int v9; // edx
	unsigned int v10; // ecx
	struct _MEMORY_BASIC_INFORMATION Buffer; // [esp+Ch] [ebp-24h]
	LPSTR lpFilename; // [esp+28h] [ebp-8h]
	HMODULE hModule; // [esp+2Ch] [ebp-4h]
	unsigned int iMaxLengtha; // [esp+38h] [ebp+8h]

	lpFilename = lpString1;
	v5 = lpAddress;
	lstrcpynA(lpString1, "*unknown*", iMaxLength);
	*(_DWORD *)a4 = 0;
	*(_DWORD *)a5 = 0;
	result = VirtualQuery(v5, &Buffer, 0x1Cu);
	if ( result )
	{
		hModule = (HMODULE)Buffer.AllocationBase;
		if ( !Buffer.AllocationBase )
			hModule = GetModuleHandleA(0);
		result = GetModuleFileNameA(hModule, lpFilename, iMaxLength);
		if ( result )
		{
			if ( hModule )
			{
				if ( *(_WORD *)hModule == 23117 )
				{
					result = *((_DWORD *)hModule + 15);
					if ( result )
					{
						result += (int)hModule;
						if ( *(_DWORD *)result == 17744 )
						{
							v7 = *(unsigned short *)(result + 6);
							iMaxLengtha = 0;
							v8 = (_BYTE *)v5 - (_BYTE *)hModule;
							if ( *(_WORD *)(result + 6) )
							{
								result += *(unsigned short *)(result + 20) + 40;
								while ( 1 )
								{
									v9 = *(_DWORD *)result;
									v10 = *(_DWORD *)(result - 4);
									if ( *(_DWORD *)result <= *(_DWORD *)(result - 8) )
										v9 = *(_DWORD *)(result - 8);
									if ( v8 >= v10 && v8 <= v10 + v9 )
										break;
									++iMaxLengtha;
									result += 40;
									if ( iMaxLengtha >= v7 )
										return result;
								}
								*(_DWORD *)a4 = iMaxLengtha + 1;
								result = a5;
								*(_DWORD *)a5 = v8 - v10;
							}
						}
					}
				}
			}
		}
		else
		{
			result = (int)lstrcpynA(lpFilename, "*unknown*", iMaxLength);
		}
	}
	return result;
}

//----- (004185FF) --------------------------------------------------------
void __fastcall exception_call_stack(void *a1, LPVOID lp)
{
	_DWORD *v2; // ebx
	void *v3; // edi
	_DWORD *v4; // eax
	char String1[260]; // [esp+Ch] [ebp-10Ch]
	int a5; // [esp+110h] [ebp-8h]
	int a4; // [esp+114h] [ebp-4h]

	v2 = (unsigned int *)lp;
	v3 = a1;
	log_printf("Call stack:\r\nAddress  Frame	Logical addr  Module\r\n");
	do
	{
		exception_unknown_module(v3, String1, 260, (int)&a4, (int)&a5);
		log_printf("%08X %08X %04X:%08X %s\r\n", v3, v2, a4, a5, String1);
		if ( IsBadWritePtr(v2, 8u) )
			break;
		v3 = (void *)v2[1];
		v4 = v2;
		v2 = (_DWORD *)*v2;
		if ( (unsigned char)v2 & 3 )
			break;
	}
	while ( v2 > v4 && !IsBadWritePtr(v2, 8u) );
	log_printf("\r\n");
}

//----- (00418688) --------------------------------------------------------
int __fastcall exception_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize)
{
	CHAR *v3; // esi
	const CHAR *v4; // eax
	CHAR *v5; // ST10_4
	DWORD v6; // ST08_4
	HMODULE v7; // eax

	v3 = lpString1;
	if ( dwMessageId > EXCEPTION_FLT_DENORMAL_OPERAND )
	{
		if ( dwMessageId <= EXCEPTION_STACK_OVERFLOW )
		{
			if ( dwMessageId == EXCEPTION_STACK_OVERFLOW )
			{
				v4 = "STACK_OVERFLOW";
				goto LABEL_42;
			}
			switch ( dwMessageId )
			{
				case EXCEPTION_FLT_DIVIDE_BY_ZERO:
					v4 = "FLT_DIVIDE_BY_ZERO";
					goto LABEL_42;
				case EXCEPTION_FLT_INEXACT_RESULT:
					v4 = "FLT_INEXACT_RESULT";
					goto LABEL_42;
				case EXCEPTION_FLT_INVALID_OPERATION:
					v4 = "FLT_INVALID_OPERATION";
					goto LABEL_42;
				case EXCEPTION_FLT_OVERFLOW:
					v4 = "FLT_OVERFLOW";
					goto LABEL_42;
				case EXCEPTION_FLT_STACK_CHECK:
					v4 = "FLT_STACK_CHECK";
					goto LABEL_42;
				case EXCEPTION_FLT_UNDERFLOW:
					v4 = "FLT_UNDERFLOW";
					goto LABEL_42;
				case EXCEPTION_INT_DIVIDE_BY_ZERO:
					v4 = "INT_DIVIDE_BY_ZERO";
					goto LABEL_42;
				case EXCEPTION_INT_OVERFLOW:
					v4 = "INT_OVERFLOW";
					goto LABEL_42;
				case EXCEPTION_PRIV_INSTRUCTION:
					v4 = "PRIV_INSTRUCTION";
					goto LABEL_42;
				default:
					break;
			}
		}
	}
	else
	{
		if ( dwMessageId == EXCEPTION_FLT_DENORMAL_OPERAND )
		{
			v4 = "FLT_DENORMAL_OPERAND";
			goto LABEL_42;
		}
		if ( dwMessageId > EXCEPTION_IN_PAGE_ERROR )
		{
			switch ( dwMessageId )
			{
				case EXCEPTION_INVALID_HANDLE:
					v4 = "INVALID_HANDLE";
					goto LABEL_42;
				case EXCEPTION_ILLEGAL_INSTRUCTION:
					v4 = "ILLEGAL_INSTRUCTION";
					goto LABEL_42;
				case EXCEPTION_NONCONTINUABLE_EXCEPTION:
					v4 = "NONCONTINUABLE_EXCEPTION";
					goto LABEL_42;
				case EXCEPTION_INVALID_DISPOSITION:
					v4 = "INVALID_DISPOSITION";
					goto LABEL_42;
				case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
					v4 = "ARRAY_BOUNDS_EXCEEDED";
					goto LABEL_42;
			}
		}
		else
		{
			switch ( dwMessageId )
			{
				case EXCEPTION_IN_PAGE_ERROR:
					v4 = "IN_PAGE_ERROR";
					goto LABEL_42;
				case EXCEPTION_GUARD_PAGE:
					v4 = "GUARD_PAGE";
					goto LABEL_42;
				case EXCEPTION_DATATYPE_MISALIGNMENT:
					v4 = "DATATYPE_MISALIGNMENT";
					goto LABEL_42;
				case EXCEPTION_BREAKPOINT:
					v4 = "BREAKPOINT";
					goto LABEL_42;
				case EXCEPTION_SINGLE_STEP:
					v4 = "SINGLE_STEP";
					goto LABEL_42;
				case EXCEPTION_ACCESS_VIOLATION:
					v4 = "ACCESS_VIOLATION";
LABEL_42:
					lstrcpynA(v3, v4, nSize);
					return (int)v3;
			}
		}
	}
	v5 = lpString1;
	v6 = dwMessageId;
	v7 = GetModuleHandleA("NTDLL.DLL");
	if ( !FormatMessageA(0xA00u, v7, v6, 0, v5, nSize, 0) )
	{
		v4 = "*unknown*";
		goto LABEL_42;
	}
	return (int)v3;
}

//----- (0041883C) --------------------------------------------------------
void __fastcall exception_set_filter()
{
	lpTopLevelExceptionFilter = SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopLevelExceptionFilter);
}

//----- (00418853) --------------------------------------------------------
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_set_filter_ptr()
{
	return SetUnhandledExceptionFilter(lpTopLevelExceptionFilter);
}

//----- (00418860) --------------------------------------------------------
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_get_filter()
{
	return lpTopLevelExceptionFilter;
}

//----- (00418866) --------------------------------------------------------
void __cdecl gamemenu_previous()
{
	void (__cdecl *v0)(); // edx
	TMenuItem *v1; // ecx

	if ( gbMaxPlayers == 1 )
	{
		v0 = gamemenu_enable_single;
		v1 = sgSingleMenu;
	}
	else
	{
		v0 = gamemenu_enable_multi;
		v1 = sgMultiMenu;
	}
	gmenu_call_proc((int)v1, v0);
	PressEscKey();
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0041888F) --------------------------------------------------------
void __cdecl gamemenu_enable_single()
{
	bool v0; // dl

	gmenu_enable(&sgSingleMenu[3], gbValidSaveFile);
	v0 = 0;
	if ( plr[myplr]._pmode != PM_DEATH && !*(_DWORD *)&deathflag )
		v0 = 1;
	gmenu_enable(sgSingleMenu, v0);
}

//----- (004188C8) --------------------------------------------------------
void __cdecl gamemenu_enable_multi()
{
	gmenu_enable(&sgMultiMenu[2], deathflag);
}

//----- (004188D8) --------------------------------------------------------
void __cdecl gamemenu_off()
{
	gmenu_call_proc(0, 0);
}

//----- (004188E1) --------------------------------------------------------
void __cdecl gamemenu_handle_previous()
{
	int v0; // eax

	_LOBYTE(v0) = gmenu_exception();
	if ( v0 )
		gamemenu_off();
	else
		gamemenu_previous();
}

//----- (004188F9) --------------------------------------------------------
void __cdecl gamemenu_new_game()
{
	char *v0; // eax

	v0 = &plr[0]._pInvincible;
	do
	{
		*(_DWORD *)(v0 - 317) = 11;
		*v0 = 1;
		v0 += 21720;
	}
	while ( (signed int)v0 < (signed int)&plr_msgs[1].msg[112] );
	*(_DWORD *)&deathflag = 0;
	force_redraw = 255;
	scrollrt_455E65(1);
	gbRunGame = 0;
	gamemenu_off();
}
// 525650: using guessed type int gbRunGame;
// 52571C: using guessed type int force_redraw;

//----- (0041893B) --------------------------------------------------------
void __cdecl gamemenu_quit_game()
{
	gamemenu_new_game();
	gbRunGameResult = 0;
}
// 525698: using guessed type int gbRunGameResult;

//----- (00418948) --------------------------------------------------------
void __cdecl gamemenu_load_game()
{
	LRESULT (__stdcall *v0)(HWND, UINT, WPARAM, LPARAM); // edi
	int v1; // ecx

	v0 = SetWindowProc(DisableInputWndProc);
	gamemenu_off();
	SetCursor(0);
	_LOBYTE(v1) = 10;
	InitDiabloMsg(v1);
	force_redraw = 255;
	DrawAndBlit();
	LoadGame(0);
	ClrDiabloMsg();
	PaletteFadeOut(8);
	*(_DWORD *)&deathflag = 0;
	force_redraw = 255;
	DrawAndBlit();
	PaletteFadeIn(8);
	SetCursor(1);
	interface_msg_pump();
	SetWindowProc(v0);
}
// 52571C: using guessed type int force_redraw;

//----- (004189BE) --------------------------------------------------------
void __cdecl gamemenu_save_game()
{
	LRESULT (__stdcall *v0)(HWND, UINT, WPARAM, LPARAM); // edi
	int v1; // ecx

	if ( pcurs == CURSOR_HAND )
	{
		if ( plr[myplr]._pmode == 8 || *(_DWORD *)&deathflag )
		{
			gamemenu_off();
		}
		else
		{
			v0 = SetWindowProc(DisableInputWndProc);
			SetCursor(0);
			gamemenu_off();
			_LOBYTE(v1) = 11;
			InitDiabloMsg(v1);
			force_redraw = 255;
			DrawAndBlit();
			SaveGame();
			ClrDiabloMsg();
			force_redraw = 255;
			SetCursor(1);
			interface_msg_pump();
			SetWindowProc(v0);
		}
	}
}
// 52571C: using guessed type int force_redraw;

//----- (00418A42) --------------------------------------------------------
void __cdecl gamemenu_restart_town()
{
	NetSendCmd(1u, CMD_RETOWN);
}

//----- (00418A4C) --------------------------------------------------------
void __cdecl gamemenu_options()
{
	gamemenu_get_music();
	gamemenu_get_sound();
	gamemenu_get_gamma();
	gamemenu_get_color_cycling();
	gmenu_call_proc((int)sgOptionMenu, 0);
}

//----- (00418A6C) --------------------------------------------------------
void __cdecl gamemenu_get_music()
{
	sound_get_or_set_music_volume(1);
	gamemenu_sound_music_toggle(music_toggle_names, sgOptionMenu);
}

//----- (00418A85) --------------------------------------------------------
void __fastcall gamemenu_sound_music_toggle(char **names, TMenuItem *menu_item)
{
	TMenuItem *v2; // esi
	int gamma; // [esp+8h] [ebp+4h]

	v2 = menu_item;
	if ( gbSndInited )
	{
		_HIBYTE(menu_item->dwFlags) |= 0xC0u;
		menu_item->pszStr = *names;
		gmenu_slider_3(&menu_item->dwFlags, 17);
		gmenu_slider_1(&v2->dwFlags, -1600, 0, gamma);
	}
	else
	{
		_HIBYTE(menu_item->dwFlags) &= 0x3Fu;
		menu_item->pszStr = names[1];
	}
}

//----- (00418AC6) --------------------------------------------------------
void __cdecl gamemenu_get_sound()
{
	sound_get_or_set_sound_volume(1);
	gamemenu_sound_music_toggle(sound_toggle_names, &sgOptionMenu[1]);
}

//----- (00418ADF) --------------------------------------------------------
void __cdecl gamemenu_get_color_cycling()
{
	sgOptionMenu[3].pszStr = color_cycling_toggle_names[palette_get_colour_cycling()];
}

//----- (00418AF4) --------------------------------------------------------
void __cdecl gamemenu_get_gamma()
{
	int v0; // eax

	gmenu_slider_3(&sgOptionMenu[2].dwFlags, 15);
	v0 = palette_update_gamma(0);
	gmenu_slider_1(&sgOptionMenu[2].dwFlags, 30, 100, v0);
}

//----- (00418B1A) --------------------------------------------------------
void __cdecl gamemenu_music_volume()
{
	int v0; // ecx
	int v1; // esi

	if ( v0 )
	{
		if ( gbMusicOn )
		{
			gbMusicOn = 0;
			music_stop();
			sound_get_or_set_music_volume(-1600);
			goto LABEL_11;
		}
		gbMusicOn = 1;
		sound_get_or_set_music_volume(0);
LABEL_10:
		music_start((unsigned char)leveltype);
		goto LABEL_11;
	}
	v1 = gamemenu_slider_music_sound(sgOptionMenu);
	sound_get_or_set_music_volume(v1);
	if ( v1 != -1600 )
	{
		if ( gbMusicOn )
			goto LABEL_11;
		gbMusicOn = 1;
		goto LABEL_10;
	}
	if ( gbMusicOn )
	{
		gbMusicOn = 0;
		music_stop();
	}
LABEL_11:
	gamemenu_get_music();
}
// 4A22D4: using guessed type char gbMusicOn;
// 5BB1ED: using guessed type char leveltype;

//----- (00418BA3) --------------------------------------------------------
int __fastcall gamemenu_slider_music_sound(TMenuItem *menu_item)
{
	return gmenu_slider_get(menu_item, -1600, 0);
}

//----- (00418BB0) --------------------------------------------------------
void __cdecl gamemenu_sound_volume()
{
	int v0; // ecx
	int v1; // ecx
	int v2; // esi

	if ( v0 )
	{
		if ( gbSoundOn )
		{
			gbSoundOn = 0;
			FreeMonsterSnd();
			v1 = -1600;
		}
		else
		{
			gbSoundOn = 1;
			v1 = 0;
		}
		sound_get_or_set_sound_volume(v1);
	}
	else
	{
		v2 = gamemenu_slider_music_sound(&sgOptionMenu[1]);
		sound_get_or_set_sound_volume(v2);
		if ( v2 == -1600 )
		{
			if ( gbSoundOn )
			{
				gbSoundOn = 0;
				FreeMonsterSnd();
			}
		}
		else if ( !gbSoundOn )
		{
			gbSoundOn = 1;
		}
	}
	PlaySFX(IS_TITLEMOV);
	gamemenu_get_sound();
}
// 4A22D5: using guessed type char gbSoundOn;

//----- (00418C30) --------------------------------------------------------
void __cdecl gamemenu_gamma()
{
	int v0; // ecx
	int v1; // eax
	int v2; // eax

	if ( v0 )
	{
		v1 = -(palette_update_gamma(0) != 30);
		_LOBYTE(v1) = v1 & 0xBA;
		v2 = v1 + 100;
	}
	else
	{
		v2 = gamemenu_slider_gamma();
	}
	palette_update_gamma(v2);
	gamemenu_get_gamma();
}

//----- (00418C5A) --------------------------------------------------------
int __cdecl gamemenu_slider_gamma()
{
	return gmenu_slider_get(&sgOptionMenu[2], 30, 100);
}

//----- (00418C6A) --------------------------------------------------------
void __cdecl gamemenu_color_cycling()
{
	int v0; // eax
	char v1; // al

	_LOBYTE(v0) = palette_get_colour_cycling();
	palette_set_color_cycling(v0 == 0);
	sgOptionMenu[3].pszStr = color_cycling_toggle_names[v1 & 1];
}

//----- (00418C8B) --------------------------------------------------------
void __cdecl FillSolidBlockTbls()
{
	unsigned char *v0; // eax
	char *v1; // ecx
	unsigned char *v2; // esi
	int v3; // edx
	unsigned char v4; // bl
	int size; // [esp+8h] [ebp-4h]

	memset(nBlockTable, 0, 0x801u);
	memset(nSolidTable, 0, 0x801u);
	memset(nTransTable, 0, 0x801u);
	memset(nMissileTable, 0, 0x801u);
	memset(nTrapTable, 0, 0x801u);
	if ( leveltype )
	{
		switch ( leveltype )
		{
			case DTYPE_CATHEDRAL:
				v1 = "Levels\\L1Data\\L1.SOL";
				break;
			case DTYPE_CATACOMBS:
				v1 = "Levels\\L2Data\\L2.SOL";
				break;
			case DTYPE_CAVES:
				v1 = "Levels\\L3Data\\L3.SOL";
				break;
			case DTYPE_HELL:
				v1 = "Levels\\L4Data\\L4.SOL";
				break;
			default:
				TermMsg("FillSolidBlockTbls");
				v0 = (unsigned char *)size;
				goto LABEL_13;
		}
	}
	else
	{
		v1 = "Levels\\TownData\\Town.SOL";
	}
	v0 = LoadFileInMem(v1, &size);
LABEL_13:
	v2 = v0;
	if ( (unsigned int)size >= 1 )
	{
		v3 = 0;
		do
		{
			v4 = *v2++;
			if ( v4 & 1 )
				nSolidTable[v3 + 1] = 1;
			if ( v4 & 2 )
				nBlockTable[v3 + 1] = 1;
			if ( v4 & 4 )
				nMissileTable[v3 + 1] = 1;
			if ( v4 & 8 )
				nTransTable[v3 + 1] = 1;
			if ( (v4 & 0x80u) != 0 )
				nTrapTable[v3 + 1] = 1;
			block_lvid[v3++ + 1] = (v4 >> 4) & 7;
		}
		while ( v3 + 1 <= (unsigned int)size );
	}
	mem_free_dbg(v0);
}
// 5BB1ED: using guessed type char leveltype;

//----- (00418D91) --------------------------------------------------------
void __cdecl gendung_418D91()
{
	signed int v0; // edx
	short (*v1)[112][112]; // edi
	short (*v2)[112][112]; // esi
	signed int v3; // ebx
	int i; // edx
	short v5; // ax
	int v6; // ecx
	signed int v7; // edx
	int v8; // eax
	int v9; // edi
	char *v10; // esi
	int j; // ecx
	unsigned char v12; // al
	unsigned char *v13; // esi
	int v14; // ecx
	signed int v15; // edx
	int v16; // eax
	int v17; // ecx
	unsigned char v18; // al
	signed int v19; // ecx
	int v20; // edi
	int v21; // edx
	int v22; // edi
	int v23; // eax
	int v24; // eax
	bool v25; // zf
	int v26; // edx
	char *v27; // esi
	char *v28; // edi
	int k; // ecx
	char *v33; // esi
	char *v34; // edi
	int v36; // ecx
	signed int v37; // edx
	int v38; // eax
	int v39; // ecx
	short (*v42)[112][112]; // esi
	short v43; // ax
	unsigned short v44; // dx
	short v45; // ax
	int v46; // [esp-4h] [ebp-38h]
	int v47; // [esp-4h] [ebp-38h]
	int v48; // [esp+Ch] [ebp-28h]
	int (*v49)[128]; // [esp+10h] [ebp-24h]
	int (*v50)[112]; // [esp+10h] [ebp-24h]
	int v51; // [esp+14h] [ebp-20h]
	short (*v52)[112][112]; // [esp+14h] [ebp-20h]
	signed int v53; // [esp+18h] [ebp-1Ch]
	int v54; // [esp+18h] [ebp-1Ch]
	short (*v55)[112][112]; // [esp+18h] [ebp-1Ch]
	int v56; // [esp+1Ch] [ebp-18h]
	int (*v57)[112]; // [esp+1Ch] [ebp-18h]
	signed int v58; // [esp+20h] [ebp-14h]
	int v59; // [esp+20h] [ebp-14h]
	int v60; // [esp+24h] [ebp-10h]
	signed int v61; // [esp+24h] [ebp-10h]
	int v62; // [esp+28h] [ebp-Ch]
	int v63; // [esp+2Ch] [ebp-8h]
	signed int v64; // [esp+30h] [ebp-4h]
	signed int v65; // [esp+30h] [ebp-4h]

	v0 = 0;
	memset(level_frame_types, 0, sizeof(level_frame_types));
	memset(level_frame_count, 0, 0x2000u);
	do
	{
		*((_DWORD *)&tile_defs[0].top + v0) = v0;
		++v0;
	}
	while ( v0 < 2048 );
	v1 = dpiece_defs_map_2;
	v48 = 2 * (leveltype == 4) + 10;
	do
	{
		v2 = v1;
		v3 = 112;
		do
		{
			for ( i = 0; i < v48; ++i )
			{
				v5 = (*v2)[0][i];
				if ( (*v2)[0][i] )
				{
					v6 = v5 & 0xFFF;
					++level_frame_count[v6];
					level_frame_types[v6] = v5 & 0x7000;
				}
			}
			v2 = (short (*)[112][112])((char *)v2 + 3584);
			--v3;
		}
		while ( v3 );
		v1 = (short (*)[112][112])((char *)v1 + 32);
	}
	while ( (signed int)v1 < (signed int)dpiece_defs_map_2[0][16] );
	v7 = 1;
	nlevel_frames = *(_DWORD *)pDungeonCels & 0xFFFF;
	v8 = nlevel_frames;
	if ( nlevel_frames > 1 )
	{
		do
		{
			level_frame_sizes[v7] = (*((_DWORD *)pDungeonCels + v7 + 1) - *((_DWORD *)pDungeonCels + v7)) & 0xFFFF;
			v8 = nlevel_frames;
			++v7;
		}
		while ( v7 < nlevel_frames );
	}
	v9 = 0;
	level_frame_sizes[0] = 0;
	if ( leveltype == 4 && v8 > 0 )
	{
		do
		{
			if ( !v9 )
				level_frame_count[0] = 0;
			v53 = 1;
			if ( level_frame_count[v9] )
			{
				if ( level_frame_types[v9] == 4096 )
				{
					v13 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + v9);
					v14 = 32;
					do
					{
						v46 = v14;
						v15 = 32;
						do
						{
							while ( 1 )
							{
								v16 = *v13++;
								if ( (v16 & 0x80u) == 0 )
									break;
								_LOBYTE(v16) = -(char)v16;
								v15 -= v16;
								if ( !v15 )
									goto LABEL_36;
							}
							v15 -= v16;
							v17 = v16;
							do
							{
								v18 = *v13++;
								if ( v18 && v18 < 0x20u )
									v53 = 0;
								--v17;
							}
							while ( v17 );
						}
						while ( v15 );
LABEL_36:
						v14 = v46 - 1;
					}
					while ( v46 != 1 );
				}
				else
				{
					v10 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + v9);
					for ( j = level_frame_sizes[v9]; j; --j )
					{
						v12 = *v10++;
						if ( v12 && v12 < 0x20u )
							v53 = 0;
					}
				}
				if ( !v53 )
					level_frame_count[v9] = 0;
			}
			++v9;
		}
		while ( v9 < nlevel_frames );
	}
	gendung_4191BF(2047);
	v19 = 0;
	v20 = 0;
	if ( light4flag )
	{
		do
		{
			v21 = level_frame_sizes[v20++];
			v19 += 2 * v21;
		}
		while ( v19 < 0x100000 );
	}
	else
	{
		do
			v19 += 14 * level_frame_sizes[v20++];
		while ( v19 < 0x100000 );
	}
	v22 = v20 - 1;
	v58 = v22;
	if ( v22 > 128 )
	{
		v58 = 128;
		v22 = 128;
	}
	v23 = -(light4flag != 0);
	v63 = 0;
	_LOBYTE(v23) = v23 & 0xF4;
	v54 = 0;
	v60 = v23 + 15;
	if ( v22 > 0 )
	{
		v56 = 0;
		v49 = speed_cel_frame_num_from_light_index_frame_num;
		do
		{
			v24 = v54;
			v25 = level_frame_types[v54] == 4096;
			v62 = *((_DWORD *)&tile_defs[0].top + v54);
			(*v49)[0] = v62;
			if ( v25 )
			{
				v65 = 1;
				if ( v60 > 1 )
				{
/*					do
					{
						speed_cel_frame_num_from_light_index_frame_num[0][v65 + v56] = v63;
						v33 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + v62);
						v34 = (char *)pSpeedCels + v63;
						_EBX = dword_646A20 + (v65 << 8);
						v36 = 32;
						do
						{
							v47 = v36;
							v37 = 32;
							do
							{
								while ( 1 )
								{
									v38 = (unsigned char)*v33++;
									*v34++ = v38;
									if ( (v38 & 0x80u) == 0 )
										break;
									_LOBYTE(v38) = -(char)v38;
									v37 -= v38;
									if ( !v37 )
										goto LABEL_63;
								}
								v37 -= v38;
								v39 = v38;
								do
								{
									_AL = *v33++;
									__asm { xlat }
									*v34++ = _AL;
									--v39;
								}
								while ( v39 );
							}
							while ( v37 );
LABEL_63:
							v36 = v47 - 1;
						}
						while ( v47 != 1 );
						v63 += level_frame_sizes[v54];
						++v65;
					}
					while ( v65 < v60 );
					*/
LABEL_63:
					goto LABEL_65;
				}
			}
			else
			{
				v26 = level_frame_sizes[v24];
				v51 = level_frame_sizes[v24];
				v64 = 1;
				if ( v60 > 1 )
				{
					do
					{
						speed_cel_frame_num_from_light_index_frame_num[0][v64 + v56] = v63;
						v27 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + v62);
						v28 = (char *)pSpeedCels + v63;
/*						_EBX = dword_646A20 + (v64 << 8);
						for ( k = v51; k; --k )
						{
							_AL = *v27++;
							__asm { xlat }
							*v28++ = _AL;
						}
						v63 += v26;
						++v64;*/
					}
					while ( v64 < v60 );
LABEL_65:
					v22 = v58;
					goto LABEL_66;
				}
			}
LABEL_66:
			++v54;
			v49 = (int (*)[128])((char *)v49 + 64);
			v56 += 16;
		}
		while ( v54 < v22 );
	}
	v57 = dPiece;
	v55 = dpiece_defs_map_2;
	do
	{
		v61 = 112;
		v52 = v55;
		v50 = v57;
		do
		{
			if ( (*v50)[0] && v48 > 0 )
			{
				v42 = v52;
				v59 = v48;
				do
				{
					v43 = *(_WORD *)v42;
					if ( *(_WORD *)v42 )
					{
						v44 = 0;
						if ( v22 > 0 )
						{
							do
							{
								if ( (v43 & 0xFFF) == *((_DWORD *)&tile_defs[0].top + v44) )
								{
									v45 = v44 + level_frame_types[v44];
									v44 = v22;
									v43 = v45 + -32768;
								}
								++v44;
							}
							while ( v44 < v22 );
							*(_WORD *)v42 = v43;
						}
					}
					v42 = (short (*)[112][112])((char *)v42 + 2);
					--v59;
				}
				while ( v59 );
			}
			++v50;
			v52 = (short (*)[112][112])((char *)v52 + 3584);
			--v61;
		}
		while ( v61 );
		v55 = (short (*)[112][112])((char *)v55 + 32);
		v57 = (int (*)[112])((char *)v57 + 4);
	}
	while ( (signed int)v55 < (signed int)dpiece_defs_map_2[0][16] );
}
// 525728: using guessed type int light4flag;
// 53CD4C: using guessed type int nlevel_frames;
// 5BB1ED: using guessed type char leveltype;

//----- (004191BF) --------------------------------------------------------
void __fastcall gendung_4191BF(int frames)
{
	int v1; // edi
	signed int v2; // eax
	int i; // esi

	v1 = frames;
	v2 = 0;
	while ( v1 > 0 && !v2 )
	{
		v2 = 1;
		for ( i = 0; i < v1; ++i )
		{
			if ( level_frame_count[i] < level_frame_count[i + 1] )
			{
				gendung_4191FB(i, i + 1);
				v2 = 0;
			}
		}
		--v1;
	}
}

//----- (004191FB) --------------------------------------------------------
void __fastcall gendung_4191FB(int a1, int a2)
{
	int v2; // esi
	int *v3; // edi
	short *v4; // edx
	int v5; // ST10_4
	int *v6; // edi
	int *v7; // eax
	int v8; // ST10_4
	short *v9; // ecx
	int v10; // edx

	v2 = a2;
	v3 = &level_frame_count[a1];
	v4 = &level_frame_types[a2];
	v2 *= 4;
	v5 = *v3;
	*v3 = *(int *)((char *)level_frame_count + v2);
	v6 = (int *)((char *)tile_defs + 4 * a1);
	*(int *)((char *)level_frame_count + v2) = v5;
	v7 = &level_frame_sizes[a1];
	v8 = *v6;
	*v6 = *(_DWORD *)((char *)&tile_defs[0].top + v2);
	*(_DWORD *)((char *)&tile_defs[0].top + v2) = v8;
	v9 = &level_frame_types[a1];
	_LOWORD(v6) = *v9;
	*v9 = *v4;
	*v4 = (signed short)v6;
	v10 = *v7;
	*v7 = *(int *)((char *)level_frame_sizes + v2);
	*(int *)((char *)level_frame_sizes + v2) = v10;
}

//----- (0041927A) --------------------------------------------------------
int __fastcall gendung_41927A(int x, int y)
{
	__int64 v3; // rax

	if ( x < 112 - y )
		return (y * (y + 1) + x * (x + 2 * y + 3)) / 2;
	v3 = (111 - y) * (111 - y + 1) + (111 - x) * (111 - x + 2 * (111 - y) + 3);
	return 12543 - (((signed int)v3 - HIDWORD(v3)) >> 1);
}

//----- (004192C2) --------------------------------------------------------
void __cdecl gendung_4192C2()
{
	short (*v0)[112][112]; // ebx
	int v1; // ebp
	short (*v2)[112][112]; // esi
	char *v3; // edi
	int x; // [esp+10h] [ebp-4h]

	x = 0;
	v0 = dpiece_defs_map_2;
	do
	{
		v1 = 0;
		do
		{
			v2 = v0;
			v3 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, v1++);
			v0 = (short (*)[112][112])((char *)v0 + 32);
			qmemcpy(v3, v2, 0x20u);
		}
		while ( v1 < 112 );
		++x;
	}
	while ( (signed int)v0 < (signed int)&optbar_cel );
}

//----- (0041930B) --------------------------------------------------------
void __cdecl SetDungeonMicros()
{
	signed int v0; // esi
	short (*v1)[112][112]; // edx
	int (*v2)[112]; // ebp
	int v3; // eax
	int v4; // eax
	signed int i; // ecx
	_WORD *v6; // edi
	int j; // ecx
	short (*v8)[112][112]; // [esp+8h] [ebp-Ch]
	int (*v9)[112]; // [esp+Ch] [ebp-8h]
	signed int v10; // [esp+10h] [ebp-4h]

	if ( leveltype == 4 )
	{
		dword_5A5594 = 12;
		v0 = 16;
	}
	else
	{
		dword_5A5594 = 10;
		v0 = 10;
	}
	v9 = dPiece;
	v8 = dpiece_defs_map_2;
	do
	{
		v1 = v8;
		v2 = v9;
		v10 = 112;
		do
		{
			if ( (*v2)[0] )
			{
				v3 = (*v2)[0] - 1;
				if ( leveltype == 4 )
					v4 = *(_DWORD *)&dpiece_defs[0].blocks + 32 * v3;
				else
					v4 = *(_DWORD *)&dpiece_defs[0].blocks + 20 * v3;
				for ( i = 0; i < v0; ++i )
					(*v1)[0][i] = *(_WORD *)(v4 + 2 * (v0 + (i & 1) - (i & 0xE)) - 4);
			}
			else if ( v0 > 0 )
			{
				memset(v1, 0, 4 * ((unsigned int)v0 >> 1));
				v6 = (_WORD *)((char *)v1 + 4 * ((unsigned int)v0 >> 1));
				for ( j = v0 & 1; j; --j )
				{
					*v6 = 0;
					++v6;
				}
			}
			++v2;
			v1 = (short (*)[112][112])((char *)v1 + 3584);
			--v10;
		}
		while ( v10 );
		v8 = (short (*)[112][112])((char *)v8 + 32);
		v9 = (int (*)[112])((char *)v9 + 4);
	}
	while ( (signed int)v8 < (signed int)dpiece_defs_map_2[0][16] );
	gendung_418D91();
	gendung_4192C2();
	if ( zoomflag )
	{
		scr_pix_width = 640;
		scr_pix_height = 352;
		dword_5C2FF8 = 10;
		dword_5C2FFC = 11;
	}
	else
	{
		scr_pix_width = 384;
		scr_pix_height = 224;
		dword_5C2FF8 = 6;
		dword_5C2FFC = 7;
	}
}
// 52569C: using guessed type int zoomflag;
// 5BB1ED: using guessed type char leveltype;
// 5C2FF8: using guessed type int dword_5C2FF8;
// 5C2FFC: using guessed type int dword_5C2FFC;
// 5C3000: using guessed type int scr_pix_width;
// 5C3004: using guessed type int scr_pix_height;

//----- (0041944A) --------------------------------------------------------
void __cdecl DRLG_InitTrans()
{
	memset(dung_map, 0, 0x3100u);
	memset(TransList, 0, 0x100u);
	TransVal = 1;
}
// 5A5590: using guessed type char TransVal;

//----- (00419477) --------------------------------------------------------
void __fastcall Make_RectTrans(int tx_start, int ty_start, int tx_end, int ty_end)
{
	int v4; // esi
	int v5; // edi
	int v6; // eax
	char *v7; // edx
	int v8; // ecx
	int ty_enda; // [esp+10h] [ebp+8h]

	v4 = 2 * tx_start + 17;
	v5 = 2 * tx_end + 16;
	v6 = 2 * ty_start + 17;
	for ( ty_enda = 2 * ty_end + 16; v6 <= ty_enda; ++v6 )
	{
		if ( v4 <= v5 )
		{
			v7 = &dung_map[v4][v6];
			v8 = v5 - v4 + 1;
			do
			{
				*v7 = TransVal;
				v7 += 112;
				--v8;
			}
			while ( v8 );
		}
	}
	++TransVal;
}
// 5A5590: using guessed type char TransVal;

//----- (004194D0) --------------------------------------------------------
void __fastcall DRLG_RectTrans(int x_start, int y_start, int x_end, int y_end)
{
	int i; // esi
	char *v5; // edx
	int v6; // eax

	for ( i = y_start; i <= y_end; ++i )
	{
		if ( x_start <= x_end )
		{
			v5 = &dung_map[x_start][i];
			v6 = x_end - x_start + 1;
			do
			{
				*v5 = TransVal;
				v5 += 112;
				--v6;
			}
			while ( v6 );
		}
	}
	++TransVal;
}
// 5A5590: using guessed type char TransVal;

//----- (00419515) --------------------------------------------------------
void __fastcall DRLG_CopyTrans(int src_x, int src_y, int dst_x, int dst_y)
{
	dung_map[dst_x][dst_y] = dung_map[src_x][src_y];
}

//----- (00419534) --------------------------------------------------------
void __fastcall DRLG_ListTrans(int num, unsigned char *List)
{
	unsigned char *v2; // esi
	int v3; // edi
	unsigned char v4; // al
	unsigned char *v5; // esi
	unsigned char v6; // cl
	unsigned char v7; // dl
	unsigned char v8; // bl

	v2 = List;
	if ( num > 0 )
	{
		v3 = num;
		do
		{
			v4 = *v2;
			v5 = v2 + 1;
			v6 = *v5++;
			v7 = *v5++;
			v8 = *v5;
			v2 = v5 + 1;
			DRLG_RectTrans(v4, v6, v7, v8);
			--v3;
		}
		while ( v3 );
	}
}

//----- (00419565) --------------------------------------------------------
void __fastcall DRLG_AreaTrans(int num, unsigned char *List)
{
	unsigned char *v2; // esi
	int v3; // edi
	unsigned char v4; // al
	unsigned char *v5; // esi
	unsigned char v6; // cl
	unsigned char v7; // dl
	unsigned char v8; // bl

	v2 = List;
	if ( num > 0 )
	{
		v3 = num;
		do
		{
			v4 = *v2;
			v5 = v2 + 1;
			v6 = *v5++;
			v7 = *v5++;
			v8 = *v5;
			v2 = v5 + 1;
			DRLG_RectTrans(v4, v6, v7, v8);
			--TransVal;
			--v3;
		}
		while ( v3 );
	}
	++TransVal;
}
// 5A5590: using guessed type char TransVal;

//----- (004195A2) --------------------------------------------------------
void __cdecl DRLG_InitSetPC()
{
	setpc_x = 0;
	setpc_y = 0;
	setpc_w = 0;
	setpc_h = 0;
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (004195B9) --------------------------------------------------------
void __cdecl DRLG_SetPC()
{
	int v0; // ebx
	int v1; // edx
	int v2; // ecx
	int v3; // esi
	int i; // eax
	int v5; // ebp
	char *v6; // edi

	v0 = 0;
	v1 = 2 * setpc_w;
	v2 = 2 * setpc_h;
	v3 = 2 * setpc_x + 16;
	for ( i = 2 * setpc_y + 16; v0 < v2; ++v0 )
	{
		if ( v1 > 0 )
		{
			v5 = v1;
			v6 = &dFlags[v3][v0 + i];
			do
			{
				*v6 |= 8u;
				v6 += 112;
				--v5;
			}
			while ( v5 );
		}
	}
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (0041960C) --------------------------------------------------------
void __fastcall Make_SetPC(int x, int y, int w, int h)
{
	int v4; // eax
	int v5; // esi
	int v6; // ebx
	int i; // eax
	int v8; // edx
	char *v9; // ecx
	int wa; // [esp+14h] [ebp+8h]

	v4 = w;
	wa = 0;
	v5 = 2 * v4;
	v6 = 2 * x + 16;
	for ( i = 2 * y + 16; wa < 2 * h; ++wa )
	{
		if ( v5 > 0 )
		{
			v8 = v5;
			v9 = &dFlags[v6][wa + i];
			do
			{
				*v9 |= 8u;
				v9 += 112;
				--v8;
			}
			while ( v8 );
		}
	}
}

//----- (0041965B) --------------------------------------------------------
unsigned char __fastcall DRLG_WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height)
{
	int v7; // esi
	int v8; // edi
	int v9; // eax
	int v10; // ebx
	int v11; // edx
	unsigned char *v12; // eax
	int v13; // eax
	int i; // eax
	int v15; // eax
	int v16; // esi
	int v17; // eax
	int v18; // edx
	int v19; // ecx
	int v21; // eax
	int v22; // esi
	int v23[20]; // [esp+8h] [ebp-BCh]
	int v24[20]; // [esp+58h] [ebp-6Ch]
	int v25; // [esp+A8h] [ebp-1Ch]
	int v26; // [esp+ACh] [ebp-18h]
	int v27; // [esp+B0h] [ebp-14h]
	int v28; // [esp+B4h] [ebp-10h]
	char *v29; // [esp+B8h] [ebp-Ch]
	int v30; // [esp+BCh] [ebp-8h]
	int v31; // [esp+C0h] [ebp-4h]

	v28 = 1;
	v27 = 1;
	v7 = x;
	v8 = 0;
	v25 = floor;
	v31 = 0;
	v30 = 0;
	if ( x > 40 - maxSize && y > 40 - maxSize )
		return 0;
	_LOBYTE(v9) = SkipThemeRoom(x, y);
	if ( !v9 )
		return 0;
	memset(v24, 0, 0x50u);
	memset(v23, 0, 0x50u);
	if ( maxSize > 0 )
	{
		v10 = 40 * v7;
		v26 = 40 * v7;
		v29 = dungeon[v7];
		do
		{
			if ( v27 )
			{
				v11 = v7;
				if ( v7 < v7 + maxSize )
				{
					v12 = (unsigned char *)dungeon + v8 + v10 + y;
					do
					{
						if ( *v12 == v25 )
						{
							++v31;
						}
						else
						{
							if ( v11 >= minSize )
								break;
							v27 = 0;
						}
						++v11;
						v12 += 40;
					}
					while ( v11 < v7 + maxSize );
					v10 = v26;
				}
				if ( v27 )
				{
					v13 = v31;
					v31 = 0;
					v24[v8] = v13;
				}
			}
			if ( v28 )
			{
				for ( i = y; i < y + maxSize; ++i )
				{
					if ( (unsigned char)v29[i] == v25 )
					{
						++v30;
					}
					else
					{
						if ( i >= minSize )
							break;
						v28 = 0;
					}
				}
				if ( v28 )
				{
					v15 = v30;
					v30 = 0;
					v23[v8] = v15;
				}
			}
			v29 += 40;
			++v8;
		}
		while ( v8 < maxSize );
		v8 = 0;
	}
	v16 = minSize;
	v17 = 0;
	if ( minSize > 0 )
	{
		while ( v24[v17] >= minSize && v23[v17] >= minSize )
		{
			if ( ++v17 >= minSize )
				goto LABEL_32;
		}
		return 0;
	}
LABEL_32:
	v18 = v24[0];
	v19 = v23[0];
	if ( maxSize > 0 )
	{
		while ( 1 )
		{
			v21 = v24[v8];
			if ( v21 < v16 )
				break;
			v22 = v23[v8];
			if ( v22 < minSize )
				break;
			if ( v21 < v18 )
				v18 = v24[v8];
			if ( v22 < v19 )
				v19 = v23[v8];
			if ( ++v8 >= maxSize )
				break;
			v16 = minSize;
		}
	}
	*width = v18 - 2;
	*height = v19 - 2;
	return 1;
}
// 41965B: using guessed type int var_6C[20];
// 41965B: using guessed type int var_BC[20];

//----- (004197F4) --------------------------------------------------------
void __fastcall DRLG_CreateThemeRoom(int themeIndex)
{
	int v1; // esi
	int v2; // eax
	int v3; // edi
	int v4; // ebx
	int v5; // ecx
	int v6; // ecx
	int v7; // ebx
	int v8; // edx
	int v9; // ebx
	int v10; // edx
	int v11; // ebx
	int v12; // edx
	int v13; // eax
	int v14; // eax
	int v15; // eax
	int v16; // ecx
	char *v17; // eax
	int v18; // ecx
	char *v19; // eax
	int v20; // [esp+Ch] [ebp-8h]
	char *v21; // [esp+10h] [ebp-4h]

	v1 = themeIndex;
	v2 = themeLoc[themeIndex].y;
	v3 = themeLoc[themeIndex].height;
	v4 = v2;
	v5 = v3 + v2;
	if ( v2 < v3 + v2 )
	{
		v20 = themeLoc[v1].x + themeLoc[v1].width;
		while ( 1 )
		{
			v6 = themeLoc[v1].x;
			if ( v6 < v20 )
				break;
LABEL_52:
			++v4;
			v5 = v3 + v2;
			if ( v4 >= v3 + v2 )
				goto LABEL_53;
		}
		v21 = &dungeon[v6][v4];
		while ( 1 )
		{
			if ( leveltype != 2 )
				goto LABEL_21;
			if ( v4 == v2 && v6 >= themeLoc[v1].x && v6 <= v20 )
				goto LABEL_12;
			if ( v4 != v3 + v2 - 1 )
				goto LABEL_13;
			if ( v6 >= themeLoc[v1].x )
				break;
LABEL_16:
			if ( v6 == v20 - 1 && v4 >= v2 && v4 <= v3 + v2 )
				goto LABEL_19;
			*v21 = 3;
LABEL_21:
			if ( leveltype == 3 )
			{
				if ( v4 == v2 && v6 >= themeLoc[v1].x && v6 <= v20 )
				{
LABEL_28:
					*v21 = -122;
					goto LABEL_51;
				}
				if ( v4 == v3 + v2 - 1 )
				{
					if ( v6 >= themeLoc[v1].x )
					{
						if ( v6 <= v20 )
							goto LABEL_28;
						goto LABEL_29;
					}
				}
				else
				{
LABEL_29:
					if ( v6 == themeLoc[v1].x && v4 >= v2 && v4 <= v3 + v2 )
					{
LABEL_35:
						*v21 = -119;
						goto LABEL_51;
					}
				}
				if ( v6 == v20 - 1 && v4 >= v2 && v4 <= v3 + v2 )
					goto LABEL_35;
				*v21 = 7;
			}
			if ( leveltype != 4 )
				goto LABEL_51;
			if ( v4 != v2 || v6 < themeLoc[v1].x || v6 > v20 )
			{
				if ( v4 != v3 + v2 - 1 )
					goto LABEL_44;
				if ( v6 < themeLoc[v1].x )
					goto LABEL_47;
				if ( v6 > v20 )
				{
LABEL_44:
					if ( v6 != themeLoc[v1].x || v4 < v2 || v4 > v3 + v2 )
					{
LABEL_47:
						if ( v6 != v20 - 1 || v4 < v2 || v4 > v3 + v2 )
						{
							*v21 = 6;
							goto LABEL_51;
						}
					}
LABEL_19:
					*v21 = 1;
					goto LABEL_51;
				}
			}
LABEL_12:
			*v21 = 2;
LABEL_51:
			v21 += 40;
			if ( ++v6 >= v20 )
				goto LABEL_52;
		}
		if ( v6 <= v20 )
			goto LABEL_12;
LABEL_13:
		if ( v6 == themeLoc[v1].x && v4 >= v2 && v4 <= v3 + v2 )
			goto LABEL_19;
		goto LABEL_16;
	}
LABEL_53:
	if ( leveltype == 2 )
	{
		v7 = themeLoc[v1].x;
		v8 = 10 * (v7 + themeLoc[v1].width);
		dungeon[v7][v2] = 8;
		v5 = v3 + 40 * v7;
		*((_BYTE *)&dMonster[111][v8 + 102] + v2) = 7;
		*((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = 9;
		*((_BYTE *)&dMonster[111][101] + v3 + v8 * 4 + v2 + 3) = 6;
	}
	if ( leveltype == 3 )
	{
		v9 = themeLoc[v1].x;
		v10 = 10 * (v9 + themeLoc[v1].width);
		dungeon[v9][v2] = -106;
		v5 = v3 + 40 * v9;
		*((_BYTE *)&dMonster[111][v10 + 102] + v2) = -105;
		*((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = -104;
		*((_BYTE *)&dMonster[111][101] + v3 + v10 * 4 + v2 + 3) = -118;
	}
	if ( leveltype == 4 )
	{
		v11 = themeLoc[v1].x;
		v12 = 10 * (v11 + themeLoc[v1].width);
		dungeon[v11][v2] = 9;
		v5 = v3 + 40 * v11;
		*((_BYTE *)&dMonster[111][v12 + 102] + v2) = 16;
		*((_BYTE *)&dMonster[111][111] + v5 + v2 + 3) = 15;
		*((_BYTE *)&dMonster[111][101] + v3 + v12 * 4 + v2 + 3) = 12;
	}
	if ( leveltype == 2 )
	{
		_LOBYTE(v5) = 0;
		v13 = random(v5, 2);
		if ( v13 )
		{
			if ( v13 == 1 )
			{
				v5 = themeLoc[v1].height;
				*((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width / 2) + 111] + themeLoc[v1].y
																								+ v5
																								+ 3) = 5;
			}
		}
		else
		{
			v5 = themeLoc[v1].y;
			*((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width) + 102] + themeLoc[v1].height / 2 + v5) = 4;
		}
	}
	if ( leveltype == 3 )
	{
		_LOBYTE(v5) = 0;
		v14 = random(v5, 2);
		if ( v14 )
		{
			if ( v14 == 1 )
			{
				v5 = themeLoc[v1].height;
				*((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width / 2) + 111] + themeLoc[v1].y
																								+ v5
																								+ 3) = -110;
			}
		}
		else
		{
			v5 = themeLoc[v1].y;
			*((_BYTE *)&dMonster[111][10 * (themeLoc[v1].x + themeLoc[v1].width) + 102] + themeLoc[v1].height / 2 + v5) = -109;
		}
	}
	if ( leveltype == 4 )
	{
		_LOBYTE(v5) = 0;
		v15 = random(v5, 2);
		if ( v15 )
		{
			if ( v15 == 1 )
			{
				v16 = themeLoc[v1].y + 40 * (themeLoc[v1].x + themeLoc[v1].width / 2) + themeLoc[v1].height;
				v17 = (char *)dungeon + v16;
				*(v17 - 41) = 57;
				*(v17 - 1) = 6;
				dungeon[0][v16 + 39] = 56;
				*(v17 - 2) = 59;
				*(v17 - 42) = 58;
			}
		}
		else
		{
			v18 = themeLoc[v1].height / 2 + 40 * (themeLoc[v1].x + themeLoc[v1].width) + themeLoc[v1].y;
			v19 = (char *)dungeon + v18;
			*(v19 - 41) = 53;
			*(v19 - 40) = 6;
			*((_BYTE *)&dMonster[111][102] + v18 + 1) = 52;
			*(v19 - 81) = 54;
		}
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (00419C10) --------------------------------------------------------
void __fastcall DRLG_PlaceThemeRooms(int min_size, int max_size, int floor, int frequency, int rnd_size)
{
	int v5; // ebx
	int v6; // ecx
	int v7; // eax
	int v8; // esi
	int v9; // edi
	int v10; // eax
	int v11; // ecx
	int v12; // eax
	int v13; // ecx
	int v14; // eax
	int v15; // ecx
	int v16; // eax
	int v17; // edi
	int v18; // esi
	int v19; // ecx
	int v20; // ecx
	int v21; // eax
	int minSize; // [esp+10h] [ebp-1Ch]
	int maxSize; // [esp+14h] [ebp-18h]
	unsigned char *v24; // [esp+18h] [ebp-14h]
	signed int x_start; // [esp+1Ch] [ebp-10h]
	int x; // [esp+20h] [ebp-Ch]
	int width; // [esp+24h] [ebp-8h]
	int height; // [esp+28h] [ebp-4h]

	v5 = 0;
	maxSize = max_size;
	minSize = min_size;
	themeCount = 0;
	memset(themeLoc, 0, 0x14u);
	do
	{
		x = 0;
		x_start = 20;
		v24 = (unsigned char *)dungeon + v5;
		do
		{
			if ( *v24 == floor )
			{
				_LOBYTE(v6) = 0;
				if ( !random(v6, frequency) )
				{
					_LOBYTE(v7) = DRLG_WillThemeRoomFit(floor, x, v5, minSize, maxSize, &width, &height);
					if ( v7 )
					{
						if ( rnd_size )
						{
							v8 = minSize - 2;
							v9 = maxSize - 2;
							_LOBYTE(v6) = 0;
							v10 = random(v6, width - (minSize - 2) + 1);
							_LOBYTE(v11) = 0;
							v12 = minSize - 2 + random(v11, v10);
							if ( v12 < minSize - 2 || (width = v12, v12 > v9) )
								width = minSize - 2;
							_LOBYTE(v13) = 0;
							v14 = random(v13, height - v8 + 1);
							_LOBYTE(v15) = 0;
							v16 = v8 + random(v15, v14);
							if ( v16 < v8 || v16 > v9 )
								v16 = minSize - 2;
							height = v16;
						}
						else
						{
							v16 = height;
						}
						v17 = themeCount;
						v18 = themeCount;
						themeLoc[v18].x = x + 1;
						themeLoc[v18].y = v5 + 1;
						v19 = width;
						themeLoc[v18].width = width;
						themeLoc[v18].height = v16;
						v20 = x + v19;
						v21 = v5 + v16;
						if ( leveltype == 3 )
							DRLG_RectTrans(x_start, 2 * v5 + 20, 2 * v20 + 15, 2 * v21 + 15);
						else
							Make_RectTrans(x + 1, v5 + 1, v20, v21);
						themeLoc[v18].ttval = TransVal - 1;
						DRLG_CreateThemeRoom(v17);
						++themeCount;
					}
				}
			}
			x_start += 2;
			++x;
			v24 += 40;
		}
		while ( x_start < 100 );
		++v5;
	}
	while ( v5 < 40 );
}
// 5A5590: using guessed type char TransVal;
// 5BB1ED: using guessed type char leveltype;

//----- (00419D92) --------------------------------------------------------
void __cdecl DRLG_HoldThemeRooms()
{
	int *v0; // esi
	int v1; // edi
	int v2; // edx
	int v3; // ebx
	int v4; // edi
	int v5; // ecx
	int v6; // eax
	int v7; // [esp+0h] [ebp-Ch]
	int v8; // [esp+4h] [ebp-8h]
	int v9; // [esp+8h] [ebp-4h]

	if ( themeCount > 0 )
	{
		v0 = &themeLoc[0].height;
		v8 = themeCount;
		do
		{
			v1 = *(v0 - 3);
			if ( v1 < v1 + *v0 - 1 )
			{
				v2 = *(v0 - 4);
				v3 = 2 * v1 + 16;
				v7 = v2 + *(v0 - 1) - 1;
				v9 = *v0 - 1;
				do
				{
					if ( v2 < v7 )
					{
						v4 = 224 * (v2 + 8);
						v5 = v7 - v2;
						do
						{
							v6 = v3 + v4;
							v4 += 224;
							dFlags[0][v6] |= 8u;
							dFlags[1][v6] |= 8u;
							dFlags[0][v6 + 1] |= 8u;
							dFlags[1][v6 + 1] |= 8u;
							--v5;
						}
						while ( v5 );
					}
					v3 += 2;
					--v9;
				}
				while ( v9 );
			}
			v0 += 5;
			--v8;
		}
		while ( v8 );
	}
}

//----- (00419E1F) --------------------------------------------------------
unsigned char __fastcall SkipThemeRoom(int x, int y)
{
	int v2; // ebx
	THEME_LOC *v3; // eax
	int v4; // esi

	v2 = 0;
	if ( themeCount <= 0 )
		return 1;
	v3 = themeLoc;
	while ( 1 )
	{
		if ( x >= v3->x - 2 && x <= v3->x + v3->width + 2 )
		{
			v4 = v3->y;
			if ( y >= v4 - 2 && y <= v4 + v3->height + 2 )
				break;
		}
		++v2;
		++v3;
		if ( v2 >= themeCount )
			return 1;
	}
	return 0;
}

//----- (00419E71) --------------------------------------------------------
void __cdecl InitLevels()
{
	if ( !leveldebug )
	{
		currlevel = 0;
		leveltype = 0;
		setlevel = 0;
	}
}
// 52572C: using guessed type int leveldebug;
// 5BB1ED: using guessed type char leveltype;
// 5CF31D: using guessed type char setlevel;

//----- (00419E8B) --------------------------------------------------------
void __cdecl gmenu_draw_pause()
{
	if ( currlevel )
		RedBack();
	if ( !dword_634480 )
	{
		light_table_index = 0;
		gmenu_print_text(316, 336, "Pause");
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00419EBE) --------------------------------------------------------
int __fastcall gmenu_print_text(int x, int y, char *str)
{
	char *v3; // edi
	int v4; // ebp
	int v5; // esi
	int result; // eax
	unsigned char v7; // bl

	v3 = str;
	v4 = y;
	v5 = x;
	for ( _LOBYTE(result) = *str; *v3; _LOBYTE(result) = *v3 )
	{
		++v3;
		v7 = lfontframe[fontidx[(unsigned char)result]];
		if ( v7 )
			Cel_light(v5, v4, (char *)BigTGold_cel, v7, 46);
		result = lfontkern[v7];
		v5 += result + 2;
	}
	return result;
}

//----- (00419F17) --------------------------------------------------------
void __cdecl FreeGMenu()
{
	void *v0; // ecx
	void *v1; // ecx
	void *v2; // ecx
	void *v3; // ecx
	void *v4; // ecx

	v0 = sgpLogo;
	sgpLogo = 0;
	mem_free_dbg(v0);
	v1 = BigTGold_cel;
	BigTGold_cel = 0;
	mem_free_dbg(v1);
	v2 = PentSpin_cel;
	PentSpin_cel = 0;
	mem_free_dbg(v2);
	v3 = option_cel;
	option_cel = 0;
	mem_free_dbg(v3);
	v4 = optbar_cel;
	optbar_cel = 0;
	mem_free_dbg(v4);
}

//----- (00419F70) --------------------------------------------------------
void __cdecl gmenu_init_menu()
{
	byte_634478 = 1;
	dword_634480 = 0;
	sgpCurrItem = 0;
	dword_63447C = 0;
	dword_63448C = 0;
	byte_634464 = 0;
	sgpLogo = LoadFileInMem("Data\\Diabsmal.CEL", 0);
	BigTGold_cel = LoadFileInMem("Data\\BigTGold.CEL", 0);
	PentSpin_cel = LoadFileInMem("Data\\PentSpin.CEL", 0);
	option_cel = LoadFileInMem("Data\\option.CEL", 0);
	optbar_cel = LoadFileInMem("Data\\optbar.CEL", 0);
}
// 634464: using guessed type char byte_634464;
// 634478: using guessed type char byte_634478;
// 63448C: using guessed type int dword_63448C;

//----- (00419FE8) --------------------------------------------------------
bool __cdecl gmenu_exception()
{
	return dword_634480 != 0;
}

//----- (00419FF4) --------------------------------------------------------
void __fastcall gmenu_call_proc(int a1, void (__cdecl *gmFunc)())
{
	int v2; // eax
	int v3; // ecx
	_DWORD *v4; // edx

	PauseMode = 0;
	byte_634464 = 0;
	v2 = a1;
	dword_63447C = gmFunc;
	dword_634480 = a1;
	if ( gmFunc )
	{
		gmFunc();
		v2 = dword_634480;
	}
	v3 = 0;
	dword_63448C = 0;
	if ( v2 )
	{
		v4 = (_DWORD *)(v2 + 8);
		while ( *v4 )
		{
			++v3;
			v4 += 3;
			dword_63448C = v3;
		}
	}
	sgpCurrItem = (void **)(v2 + 12 * v3 - 12);
	gmenu_up_down(1);
}
// 525740: using guessed type int PauseMode;
// 634464: using guessed type char byte_634464;
// 63448C: using guessed type int dword_63448C;

//----- (0041A04E) --------------------------------------------------------
void __fastcall gmenu_up_down(int a1)
{
	void **v1; // eax
	int v2; // edi

	v1 = sgpCurrItem;
	if ( sgpCurrItem )
	{
		byte_634464 = 0;
		v2 = dword_63448C;
		while ( v2 )
		{
			--v2;
			if ( a1 )
			{
				v1 += 3;
				sgpCurrItem = v1;
				if ( v1[2] )
					goto LABEL_10;
				v1 = (void **)dword_634480;
			}
			else
			{
				if ( v1 == (void **)dword_634480 )
					v1 = (void **)(dword_634480 + 12 * dword_63448C);
				v1 -= 3;
			}
			sgpCurrItem = v1;
LABEL_10:
			if ( *((_BYTE *)v1 + 3) < 0 )
			{
				if ( v2 )
					PlaySFX(IS_TITLEMOV);
				return;
			}
		}
	}
}
// 634464: using guessed type char byte_634464;
// 63448C: using guessed type int dword_63448C;

//----- (0041A0B6) --------------------------------------------------------
void __cdecl gmenu_draw()
{
	int v0; // edi
	int i; // esi
	DWORD v2; // eax

	if ( dword_634480 )
	{
		if ( dword_63447C )
			dword_63447C();
		Cel_decode(236, 262, sgpLogo, 1, 296);
		v0 = 320;
		for ( i = dword_634480; *(_DWORD *)(i + 8); v0 += 45 )
		{
			gmenu_spinners(i, v0);
			i += 12;
		}
		v2 = GetTickCount();
		if ( (signed int)(v2 - dword_634474) > 25 )
		{
			if ( ++byte_634478 == 9 )
				byte_634478 = 1;
			dword_634474 = v2;
		}
	}
}
// 634474: using guessed type int dword_634474;
// 634478: using guessed type char byte_634478;

//----- (0041A145) --------------------------------------------------------
void __fastcall gmenu_spinners(int a1, int a2)
{
	int v2; // edi
	int v3; // ebx
	unsigned int v4; // eax
	unsigned int v5; // ebp
	int v6; // esi
	unsigned int v7; // ecx
	unsigned int v8; // eax
	int v9; // ecx
	unsigned int v10; // ebp
	int v11; // esi
	int v12; // eax
	int v13; // edi
	unsigned int v14; // [esp+10h] [ebp-4h]

	v2 = a2;
	v3 = a1;
	v4 = gmenu_get_lfont(a1);
	v5 = v4;
	v14 = v4;
	if ( *(_BYTE *)(v3 + 3) & 0x40 )
	{
		v6 = (v4 >> 1) + 80;
		Cel_decode(v6, v2 - 10, optbar_cel, 1, 287);
		v7 = (*(_DWORD *)v3 >> 12) & 0xFFF;
		if ( v7 < 2 )
			v7 = 2;
		v8 = ((*(_DWORD *)v3 & 0xFFFu) << 8) / v7;
		v9 = (v5 >> 1) + 82;
		v10 = v8;
		gmenu_clear_buffer(v9, v2 - 12, v8 + 13, 28);
		Cel_decode(v6 + v10 + 2, v2 - 12, option_cel, 1, 27);
		v5 = v14;
	}
	v11 = 384 - (v5 >> 1);
	v12 = -(*(_DWORD *)v3 < 0);
	_LOBYTE(v12) = v12 & 0xF1;
	light_table_index = v12 + 15;
	gmenu_print_text(384 - (v5 >> 1), v2, *(char **)(v3 + 4));
	if ( (void **)v3 == sgpCurrItem )
	{
		v13 = v2 + 1;
		Cel_decode(v11 - 54, v13, PentSpin_cel, (unsigned char)byte_634478, 48);
		Cel_decode(v11 + v5 + 4, v13, PentSpin_cel, (unsigned char)byte_634478, 48);
	}
}
// 634478: using guessed type char byte_634478;
// 69BEF8: using guessed type int light_table_index;

//----- (0041A239) --------------------------------------------------------
void __fastcall gmenu_clear_buffer(int x, int y, int size, int a4)
{
	int v4; // edi
	char *i; // esi

	v4 = a4;
	for ( i = (char *)gpBuffer + screen_y_times_768[y] + x; v4; --v4 )
	{
		memset(i, 205, size);
		i -= 768;
	}
}

//----- (0041A272) --------------------------------------------------------
int __fastcall gmenu_get_lfont(int a1)
{
	unsigned char *v2; // eax
	int i; // edx
	unsigned char v4; // cl

	if ( *(_BYTE *)(a1 + 3) & 0x40 )
		return 490;
	v2 = *(unsigned char **)(a1 + 4);
	for ( i = 0; ; i += lfontkern[lfontframe[fontidx[v4]]] + 2 )
	{
		v4 = *v2;
		if ( !*v2 )
			break;
		++v2;
	}
	return i - 2;
}

//----- (0041A2AE) --------------------------------------------------------
int __fastcall gmenu_presskeys(int a1)
{
	int v1; // ecx
	int v2; // ecx

	if ( !dword_634480 )
		return 0;
	switch ( a1 )
	{
		case VK_RETURN:
			if ( *((_BYTE *)sgpCurrItem + 3) < 0 )
			{
				PlaySFX(IS_TITLEMOV);
				((void (__fastcall *)(signed int))sgpCurrItem[2])(1);
			}
			return 1;
		case VK_ESCAPE:
			PlaySFX(IS_TITLEMOV);
			gmenu_call_proc(0, 0);
			return 1;
		case VK_SPACE:
			return 0;
		case VK_LEFT:
			v2 = 0;
			goto LABEL_12;
		case VK_UP:
			v1 = 0;
			goto LABEL_10;
		case VK_RIGHT:
			v2 = 1;
LABEL_12:
			gmenu_left_right(v2);
			return 1;
		case VK_DOWN:
			v1 = 1;
LABEL_10:
			gmenu_up_down(v1);
			break;
	}
	return 1;
}

//----- (0041A32A) --------------------------------------------------------
void __fastcall gmenu_left_right(int a1)
{
	signed int v1; // edx
	unsigned int v2; // eax
	int v3; // eax

	v1 = (signed int)*sgpCurrItem;
	if ( (unsigned int)*sgpCurrItem & 0x40000000 )
	{
		v2 = (unsigned int)*sgpCurrItem & 0xFFF;
		if ( a1 )
		{
			if ( v2 == ((v1 >> 12) & 0xFFF) )
				return;
			v3 = v2 + 1;
		}
		else
		{
			if ( !(v1 & 0xFFF) )
				return;
			v3 = v2 - 1;
		}
		_LOWORD(v1) = v1 & 0xF000;
		*sgpCurrItem = (void *)v1;
		*sgpCurrItem = (void *)(v3 | (unsigned int)*sgpCurrItem);
		((void (__fastcall *)(_DWORD))sgpCurrItem[2])(0);
	}
}

//----- (0041A37A) --------------------------------------------------------
int __fastcall gmenu_run_item(LPARAM lParam)
{
	int v2; // edx
	int a1; // [esp+0h] [ebp-4h]

	a1 = lParam;
	if ( !byte_634464 )
		return 0;
	gmenu_valid_mouse_pos((int)&a1);
	v2 = a1 * (((signed int)*sgpCurrItem >> 12) & 0xFFF) % 256;
	a1 = a1 * (((signed int)*sgpCurrItem >> 12) & 0xFFF) / 256;
	*(_WORD *)sgpCurrItem &= 0xF000u;
	*sgpCurrItem = (void *)(a1 | (unsigned int)*sgpCurrItem);
	((void (__fastcall *)(_DWORD, int))sgpCurrItem[2])(0, v2);
	return 1;
}
// 41A37A: could not find valid save-restore pair for esi
// 634464: using guessed type char byte_634464;

//----- (0041A3D2) --------------------------------------------------------
char __fastcall gmenu_valid_mouse_pos(int a1)
{
	*(_DWORD *)a1 = 282;
	if ( MouseX < 282 )
	{
		*(_DWORD *)a1 = 0;
		return 0;
	}
	if ( MouseX > 538 )
	{
		*(_DWORD *)a1 = 256;
		return 0;
	}
	*(_DWORD *)a1 = MouseX - 282;
	return 1;
}

//----- (0041A401) --------------------------------------------------------
int __fastcall gmenu_left_mouse(int a1)
{
	int result; // eax
	unsigned int v2; // eax
	int v3; // eax
	int v4; // esi
	unsigned int v5; // eax
	LPARAM v6; // ecx
	int a1a; // [esp+4h] [ebp-4h]

	if ( a1 )
	{
		if ( !dword_634480 || MouseY >= 352 )
			return 0;
		if ( MouseY - 117 >= 0 )
		{
			v2 = (MouseY - 117) / 45;
			if ( v2 < dword_63448C )
			{
				v3 = 3 * v2;
				v4 = dword_634480 + 4 * v3;
				if ( *(_BYTE *)(v4 + 3) < 0 )
				{
					v5 = (unsigned int)gmenu_get_lfont(dword_634480 + 4 * v3) >> 1;
					if ( MouseX >= 320 - v5 && MouseX <= v5 + 320 )
					{
						sgpCurrItem = (void **)v4;
						PlaySFX(IS_TITLEMOV);
						if ( *(_BYTE *)(v4 + 3) & 0x40 )
						{
							byte_634464 = gmenu_valid_mouse_pos((int)&a1a);
							gmenu_run_item(v6);
						}
						else
						{
							((void (__fastcall *)(signed int))sgpCurrItem[2])(1);
						}
					}
				}
			}
		}
	}
	else
	{
		result = 0;
		if ( !byte_634464 )
			return result;
		byte_634464 = 0;
	}
	return 1;
}
// 634464: using guessed type char byte_634464;
// 63448C: using guessed type int dword_63448C;

//----- (0041A4B8) --------------------------------------------------------
void __fastcall gmenu_enable(TMenuItem *menu_item, bool enable)
{
	if ( enable )
		_HIBYTE(menu_item->dwFlags) |= 0x80u;
	else
		_HIBYTE(menu_item->dwFlags) &= 0x7Fu;
}

//----- (0041A4C6) --------------------------------------------------------
int __fastcall gmenu_slider_1(int *a1, int min, int max, int gamma)
{
	int v4; // esi
	int v5; // eax
	int result; // eax

	v4 = *a1;
	v5 = (*a1 >> 12) & 0xFFF;
	if ( v5 < 2 )
		v5 = 2;
	_LOWORD(v4) = v4 & 0xF000;
	result = v4 | (v5 * (gamma - min) + (max - min - 1) / 2) / (max - min);
	*a1 = result;
	return result;
}

//----- (0041A508) --------------------------------------------------------
int __fastcall gmenu_slider_get(TMenuItem *menu_item, int min, int max)
{
	int v3; // eax
	int v4; // ecx
	signed int v5; // esi

	v3 = (menu_item->dwFlags >> 12) & 0xFFF;
	v4 = menu_item->dwFlags & 0xFFF;
	v5 = v3;
	if ( v3 < 2 )
		v5 = 2;
	return min + (v4 * (max - min) + (v5 - 1) / 2) / v5;
}

//----- (0041A545) --------------------------------------------------------
void __fastcall gmenu_slider_3(int *a1, int a2)
{
	*a1 ^= (*a1 ^ (a2 << 12)) & 0xFFF000;
}

//----- (0041A553) --------------------------------------------------------
void __cdecl InitHelp()
{
	helpflag = 0;
	dword_634494 = 0;
	displayinghelp[0] = 0;
}
// 634494: using guessed type int dword_634494;

//----- (0041A565) --------------------------------------------------------
void __cdecl DrawHelp()
{
	int v0; // edi
	const char *v1; // esi
	int v2; // edx
	signed int v3; // ecx
	char v4; // al
	unsigned char v5; // al
	_BYTE *i; // eax
	int v7; // eax
	signed int v8; // edx
	char v9; // cl
	unsigned char v10; // cl
	text_color color; // [esp+Ch] [ebp-8h]
	int help_line_nr; // [esp+10h] [ebp-4h]
	signed int help_line_nra; // [esp+10h] [ebp-4h]

	DrawSTextHelp();
	DrawQTextBack();
	PrintSString(0, 2, 1u, "Diablo Help", 3, 0);
	DrawSLine(5);
	v0 = help_select_line;
	v1 = "$Keyboard Shortcuts:|F1:	Open Help Screen|Esc:   Display Main Menu|Tab:   Display Auto-map|Space: Hide all i"
		 "nfo screens|S: Open Speedbook|B: Open Spellbook|I: Open Inventory screen|C: Open Character screen|Q: Open Quest"
		 " log|F: Reduce screen brightness|G: Increase screen brightness|Z: Zoom Game Screen|+ / -: Zoom Automap|1 - 8: U"
		 "se Belt item|F5, F6, F7, F8:	 Set hot key for skill or spell|Shift + Left Click: Attack without moving||$Mov"
		 "ement:|If you hold the mouse button down while moving, the character will continue to move in that direction.||"
		 "$Combat:|Holding down the shift key and then left-clicking allows the character to attack without moving.||$Aut"
		 "o-map:|To access the auto-map, click the 'MAP' button on the Information Bar or press 'TAB' on the keyboard. Zo"
		 "oming in and out of the map is done with the + and - keys. Scrolling the map uses the arrow keys.||$Picking up "
		 "Objects:|Useable items that are small in size, such as potions or scrolls, are automatically placed in your 'be"
		 "lt' located at the top of the Interface bar . When an item is placed in the belt, a small number appears in tha"
		 "t box. Items may be used by either pressing the corresponding number or right-clicking on the item.||$Gold|You "
		 "can select a specific amount of gold to drop by right clicking on a pile of gold in your inventory.||$Skills & "
		 "Spells:|You can access your list of skills and spells by left-clicking on the 'SPELLS' button in the interface "
		 "bar. Memorized spells and those available through staffs are listed here. Left-clicking on the spell you wish t"
		 "o cast will ready the spell. A readied spell may be cast by simply right-clicking in the play area.||$Using the"
		 " Speedbook for Spells|Left-clicking on the 'readied spell' button will open the 'Speedbook' which allows you to"
		 " select a skill or spell for immediate use.  To use a readied skill or spell, simply right-click in the main pl"
		 "ay area.||$Setting Spell Hotkeys|You can assign up to four Hot Keys for skills, spells or scrolls.  Start by op"
		 "ening the 'speedbook' as described in the section above. Press the F5, F6, F7 or F8 keys after highlighting the"
		 " spell you wish to assign.||$Spell Books|Reading more than one book increases your knowledge of that spell, all"
		 "owing you to cast the spell more effectively.|&";
	if ( help_select_line > 0 )
	{
		help_line_nr = help_select_line;
		do
		{
			v2 = 0;
			v3 = 0;
			while ( !*v1 )
				++v1;
			if ( *v1 == 36 )
				++v1;
			v4 = *v1;
			if ( *v1 != 38 )
			{
				if ( v4 == 124 )
					goto LABEL_47;
				while ( v3 < 577 )
				{
					if ( !v4 )
					{
						do
							++v1;
						while ( !*v1 );
					}
					v5 = *v1;
					tempstr[v2++] = *v1++;
					v3 += fontkern[fontframe[fontidx[v5]]] + 1;
					v4 = *v1;
					if ( *v1 == 124 )
					{
						if ( v3 < 577 )
							goto LABEL_18;
						break;
					}
				}
				for ( i = (_BYTE *)(v2 + 4950091); *i != 32; --i )
					--v1;
LABEL_18:
				if ( *v1 == 124 )
LABEL_47:
					++v1;
			}
			--help_line_nr;
		}
		while ( help_line_nr );
	}
	help_line_nra = 7;
	do
	{
		v7 = 0;
		v8 = 0;
		while ( !*v1 )
			++v1;
		if ( *v1 == 36 )
		{
			++v1;
			_LOBYTE(color) = 2;
		}
		else
		{
			_LOBYTE(color) = 0;
		}
		v9 = *v1;
		if ( *v1 == 38 )
		{
			HelpTop = v0;
		}
		else
		{
			if ( v9 == 124 )
				goto LABEL_48;
			while ( v8 < 577 )
			{
				if ( !v9 )
				{
					do
						++v1;
					while ( !*v1 );
				}
				v10 = *v1;
				tempstr[v7++] = *v1++;
				v8 += fontkern[fontframe[fontidx[v10]]] + 1;
				v9 = *v1;
				if ( *v1 == 124 )
				{
					if ( v8 < 577 )
						goto LABEL_39;
					break;
				}
			}
			while ( tempstr[--v7] != 32 )
				--v1;
LABEL_39:
			if ( v7 )
			{
				tempstr[v7] = 0;
				DrawHelpLine(0, help_line_nra, tempstr, color);
				v0 = help_select_line;
			}
			if ( *v1 == 124 )
LABEL_48:
				++v1;
		}
		++help_line_nra;
	}
	while ( help_line_nra < 22 );
	PrintSString(0, 23, 1u, "Press ESC to end or the arrow keys to scroll.", 3, 0);
}
// 634490: using guessed type int help_select_line;
// 634960: using guessed type int HelpTop;

//----- (0041A6FA) --------------------------------------------------------
void __fastcall DrawHelpLine(int always_0, int help_line_nr, char *text, text_color color)
{
	signed int v4; // ebx
	int v5; // edi
	unsigned char i; // al
	unsigned char v7; // al
	int v8; // esi

	v4 = 0;
	v5 = screen_y_times_768[SStringY[help_line_nr] + 204] + always_0 + 96;
	for ( i = *text; *text; i = *text )
	{
		++text;
		v7 = fontframe[fontidx[i]];
		v8 = v7;
		v4 += fontkern[v7] + 1;
		if ( v7 )
		{
			if ( v4 <= 577 )
				CPrintString(v5, (char *)v7, color);
		}
		v5 += fontkern[v8] + 1;
	}
}

//----- (0041A773) --------------------------------------------------------
void __cdecl DisplayHelp()
{
	help_select_line = 0;
	helpflag = 1;
	HelpTop = 5000;
}
// 634490: using guessed type int help_select_line;
// 634960: using guessed type int HelpTop;

//----- (0041A78F) --------------------------------------------------------
void __cdecl HelpScrollUp()
{
	if ( help_select_line > 0 )
		--help_select_line;
}
// 634490: using guessed type int help_select_line;

//----- (0041A79F) --------------------------------------------------------
void __cdecl HelpScrollDown()
{
	if ( help_select_line < HelpTop )
		++help_select_line;
}
// 634490: using guessed type int help_select_line;
// 634960: using guessed type int HelpTop;

//----- (0041A7B8) --------------------------------------------------------
void __cdecl init_cpp_init()
{
	init_cpp_init_value = init_inf;
}
// 47AE20: using guessed type int init_inf;
// 63497C: using guessed type int init_cpp_init_value;

//----- (0041A7C3) --------------------------------------------------------
void __fastcall init_cleanup(bool show_cursor)
{
	int v1; // edi

	v1 = show_cursor;
	pfile_flush_W();
	init_disable_screensaver(0);
	init_run_office_from_start_menu();
	if ( diabdat_mpq )
	{
		SFileCloseArchive(diabdat_mpq);
		diabdat_mpq = 0;
	}
	if ( patch_rt_mpq )
	{
		SFileCloseArchive(patch_rt_mpq);
		patch_rt_mpq = 0;
	}
	if ( unused_mpq )
	{
		SFileCloseArchive(unused_mpq);
		unused_mpq = 0;
	}
	UiDestroy();
	effects_cleanup_sfx();
	sound_cleanup();
	NetClose();
	dx_cleanup();
	MI_Dummy(v1);
	StormDestroy();
	if ( v1 )
		ShowCursor(1);
}

//----- (0041A84C) --------------------------------------------------------
void __cdecl init_run_office_from_start_menu()
{
	HWND v0; // eax
	char pszPath[256]; // [esp+0h] [ebp-104h]
/*	LPITEMIDLIST ppidl; // [esp+100h] [ebp-4h]

	if ( killed_mom_parent )
	{
		pszPath[0] = empty_string;
		killed_mom_parent = 0;
		memset(&pszPath[1], 0, 0xFCu);
		*(_WORD *)&pszPath[253] = 0;
		pszPath[255] = 0;
		ppidl = 0;
		v0 = GetDesktopWindow();
		if ( !SHGetSpecialFolderLocation(v0, 11, &ppidl) )
		{
			SHGetPathFromIDListA(ppidl, pszPath);
			init_run_office(pszPath);
		}
	}*/
}
// 634CA0: using guessed type int killed_mom_parent;

//----- (0041A8B9) --------------------------------------------------------
void __fastcall init_run_office(char *dir)
{
	char *v1; // esi
	HANDLE v2; // ebx
	bool v3; // zf
	HWND v4; // eax
	char Directory[260]; // [esp+8h] [ebp-348h]
	char FileName[260]; // [esp+10Ch] [ebp-244h]
	struct _WIN32_FIND_DATAA FindFileData; // [esp+210h] [ebp-140h]

/*	v1 = dir;
	strcpy(FileName, dir);
	if ( FileName[0] && Directory[strlen(FileName) + 259] == 92 )
		strcat(FileName, "*");
	else
		strcat(FileName, "\\*");
	v2 = FindFirstFileA(FileName, &FindFileData);
	if ( v2 != (HANDLE)-1 )
	{
		do
		{
			if ( FindFileData.dwFileAttributes & 0x10 )
			{
				if ( strcmp(FindFileData.cFileName, ".") && strcmp(FindFileData.cFileName, "..") )
				{
					Directory[0] = empty_string;
					memset(&Directory[1], 0, 0x100u);
					v3 = *v1 == 0;
					*(_WORD *)&Directory[257] = 0;
					Directory[259] = 0;
					if ( v3 || v1[strlen(v1) - 1] != 92 )
						sprintf(Directory, "%s\\%s\\", v1, FindFileData.cFileName);
					else
						sprintf(Directory, "%s%s\\", v1, FindFileData.cFileName);
					init_run_office(Directory);
				}
			}
			else if ( !_strcmpi(FindFileData.cFileName, "Microsoft Office Shortcut Bar.lnk") )
			{
				v4 = GetDesktopWindow();
				ShellExecuteA(v4, "open", FindFileData.cFileName, &empty_string, v1, 1);
			}
		}
		while ( FindNextFileA(v2, &FindFileData) );
		FindClose(v2);
	}*/
}

//----- (0041AA2C) --------------------------------------------------------
void __fastcall init_disable_screensaver(bool disable)
{
	bool v1; // al
	BYTE Data; // [esp+4h] [ebp-20h]
	char v3; // [esp+5h] [ebp-1Fh]
	DWORD Type; // [esp+14h] [ebp-10h]
	DWORD cbData; // [esp+18h] [ebp-Ch]
	HKEY phkResult; // [esp+1Ch] [ebp-8h]
	bool v7; // [esp+20h] [ebp-4h]

	v7 = disable;
	if ( !RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, 0x2001Fu, &phkResult) )
	{
		if ( v7 )
		{
			cbData = 16;
			if ( !RegQueryValueExA(phkResult, "ScreenSaveActive", 0, &Type, &Data, &cbData) )
				screensaver_enabled_prev = Data != 48;
			v1 = 0;
		}
		else
		{
			v1 = screensaver_enabled_prev;
		}
		v3 = 0;
		Data = (v1 != 0) + 48;
		RegSetValueExA(phkResult, "ScreenSaveActive", 0, 1u, &Data, 2u);
		RegCloseKey(phkResult);
	}
}

//----- (0041AAC5) --------------------------------------------------------
void __cdecl init_create_window()
{
	signed int v0; // eax
	HWND v1; // esi
	WNDCLASSEXA v2; // [esp+8h] [ebp-34h]
	int nWidth; // [esp+38h] [ebp-4h]

	init_kill_mom_parent();
	pfile_init_save_directory();
	memset(&v2, 0, 0x30u);
	v2.cbSize = 48;
	v2.style = 3;
	v2.lpfnWndProc = init_redraw_window;
	v2.hInstance = hInstance;
	v2.hIcon = LoadIconA(hInstance, (LPCSTR)0x65);
	v2.hCursor = LoadCursorA(0, (LPCSTR)0x7F00);
	v2.hbrBackground = (HBRUSH)GetStockObject(4);
	v2.lpszMenuName = "DIABLO";
	v2.lpszClassName = "DIABLO";
	v2.hIconSm = (HICON)LoadImageA(hInstance, (LPCSTR)0x65, 1u, 16, 16, 0);
	if ( !RegisterClassExA(&v2) )
		TermMsg("Unable to register window class");
	if ( GetSystemMetrics(0) >= 640 )
		nWidth = GetSystemMetrics(0);
	else
		nWidth = 640;
	if ( GetSystemMetrics(1) >= 480 )
		v0 = GetSystemMetrics(1);
	else
		v0 = 480;
	v1 = CreateWindowExA(0, "DIABLO", "DIABLO", 0x80000000, 0, 0, nWidth, v0, 0, 0, hInstance, 0);
	if ( !v1 )
		TermMsg("Unable to create main window");
	ShowWindow(v1, 1);
	UpdateWindow(v1);
	init_await_mom_parent_exit();
	dx_init(v1);
	BlackPalette();
	snd_init(v1);
	init_archives();
	init_disable_screensaver(1);
}

//----- (0041AC00) --------------------------------------------------------
void __cdecl init_kill_mom_parent()
{
	HWND v0; // eax

	v0 = init_find_mom_parent();
	if ( v0 )
	{
		PostMessageA(v0, 0x10u, 0, 0);
		killed_mom_parent = 1;
	}
}
// 634CA0: using guessed type int killed_mom_parent;

//----- (0041AC21) --------------------------------------------------------
HWND __cdecl init_find_mom_parent()
{
	HWND i; // eax
	HWND v1; // esi
	char ClassName[256]; // [esp+4h] [ebp-100h]

	for ( i = GetForegroundWindow(); ; i = GetWindow(v1, 2u) )
	{
		v1 = i;
		if ( !i )
			break;
		GetClassNameA(i, ClassName, 255);
		if ( !_strcmpi(ClassName, "MOM Parent") )
			break;
	}
	return v1;
}

//----- (0041AC71) --------------------------------------------------------
void __cdecl init_await_mom_parent_exit()
{
	DWORD v0; // edi

	v0 = GetTickCount();
	do
	{
		if ( !init_find_mom_parent() )
			break;
		Sleep(0xFAu);
	}
	while ( GetTickCount() - v0 <= 0xFA0 );
}

//----- (0041ACA1) --------------------------------------------------------
void __cdecl init_archives()
{
	void *a1; // [esp+8h] [ebp-8h]
	int v1; // [esp+Ch] [ebp-4h]

	fileinfo.size = 20;
	fileinfo.versionstring = "internal version unknown";
	fileinfo.executablefile = diablo_exe_path;
	fileinfo.originalarchivefile = diabdat_mpq_path;
	fileinfo.patcharchivefile = patch_rt_mpq_path;
	init_get_file_info();
	while ( 1 )
	{
		diabdat_mpq = init_test_access(diabdat_mpq_path, "\\diabdat.mpq", "DiabloCD", 1000, 1);
		if ( diabdat_mpq )
			break;
		UiCopyProtError((int)&v1);
		if ( v1 == COPYPROT_CANCEL )
			FileErrDlg("diabdat.mpq");
	}
	if ( !wave_open_file((LPARAM)"ui_art\\title.pcx", (DIABFILE *)&a1, 1) )
		FileErrDlg("Main program archive: diabdat.mpq");
	wave_close_file(a1);
	patch_rt_mpq = init_test_access(patch_rt_mpq_path, "\\patch_rt.mpq", "DiabloInstall", 2000, 0);
}

//----- (0041AD72) --------------------------------------------------------
void *__fastcall init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags, bool on_cd)
{
	char *v5; // esi
	int v6; // eax
	char *v7; // eax
	int v8; // eax
	int v9; // eax
	int v10; // eax
	int v11; // eax
	char Filename[260]; // [esp+Ch] [ebp-314h]
	char Buffer[260]; // [esp+110h] [ebp-210h]
	char v15[260]; // [esp+214h] [ebp-10Ch]
	char *mpq_namea; // [esp+318h] [ebp-8h]
	void *archive; // [esp+31Ch] [ebp-4h]

	mpq_namea = mpq_name;
	v5 = mpq_path;
	if ( !GetCurrentDirectoryA(0x104u, Buffer) )
		TermMsg("Can't get program path");
	init_strip_trailing_slash(Buffer);
	_LOBYTE(v6) = SFileSetBasePath(Buffer);
	if ( !v6 )
		TermMsg("SFileSetBasePath");
	if ( !GetModuleFileNameA(hInstance, Filename, 0x104u) )
		TermMsg("Can't get program name");
	v7 = strrchr(Filename, 92);
	if ( v7 )
		*v7 = 0;
	init_strip_trailing_slash(Filename);
	strcpy(v5, Buffer);
	strcat(v5, mpq_namea);
	_LOBYTE(v8) = SFileOpenArchive(v5, flags, on_cd, &archive);
	if ( v8 )
		return archive;
	if ( strcmp(Filename, Buffer) )
	{
		strcpy(v5, Filename);
		strcat(v5, mpq_namea);
		_LOBYTE(v9) = SFileOpenArchive(v5, flags, on_cd, &archive);
		if ( v9 )
			return archive;
	}
	v15[0] = 0;
	if ( reg_loc )
	{
		_LOBYTE(v10) = SRegLoadString((const char *)"Archives", (const char *)reg_loc, 0, v15, 260);
		if ( v10 )
		{
			init_strip_trailing_slash(v15);
			strcpy(v5, v15);
			strcat(v5, mpq_namea);
			_LOBYTE(v11) = SFileOpenArchive(v5, flags, on_cd, &archive);
			if ( v11 )
				return archive;
		}
	}
	if ( on_cd && init_read_test_file(v15, mpq_namea, flags, &archive) )
	{
		strcpy(v5, v15);
		return archive;
	}
	return 0;
}

//----- (0041AF22) --------------------------------------------------------
char *__fastcall init_strip_trailing_slash(char *path)
{
	char *result; // eax

	result = strrchr(path, 92);
	if ( result )
	{
		if ( !result[1] )
			*result = 0;
	}
	return result;
}

//----- (0041AF3A) --------------------------------------------------------
int __fastcall init_read_test_file(char *mpq_path, char *mpq_name, int flags, void **archive)
{
	char *v4; // edi
	DWORD v5; // eax
	const char *v7; // ebx
	const char *v8; // esi
	int v9; // eax
	char Buffer[260]; // [esp+Ch] [ebp-108h]
	char *mpq_patha; // [esp+110h] [ebp-4h]

	v4 = mpq_name;
	mpq_patha = mpq_path;
	v5 = GetLogicalDriveStringsA(0x104u, Buffer);
	if ( !v5 || v5 > 0x104 )
		return 0;
	while ( *v4 == 92 )
		++v4;
	v7 = Buffer;
	if ( !Buffer[0] )
		return 0;
	while ( 1 )
	{
		v8 = v7;
		v7 += strlen(v7) + 1;
		if ( GetDriveTypeA(v8) == 5 )
		{
			strcpy(mpq_patha, v8);
			strcat(mpq_patha, v4);
			_LOBYTE(v9) = SFileOpenArchive(mpq_patha, flags, 1, archive);
			if ( v9 )
				break;
		}
		if ( !*v7 )
			return 0;
	}
	return 1;
}

//----- (0041AFCE) --------------------------------------------------------
void __cdecl init_get_file_info()
{
	int v0; // eax
	DWORD v1; // edi
	void *v2; // ebx
	unsigned int puLen; // [esp+8h] [ebp-Ch]
	DWORD dwHandle; // [esp+Ch] [ebp-8h]
	LPVOID lpBuffer; // [esp+10h] [ebp-4h]

	if ( GetModuleFileNameA(hInstance, diablo_exe_path, 0x104u) )
	{
		v0 = GetFileVersionInfoSizeA(diablo_exe_path, &dwHandle);
		v1 = v0;
		if ( v0 )
		{
			v2 = DiabloAllocPtr(v0);
			if ( GetFileVersionInfoA(diablo_exe_path, 0, v1, v2) )
			{
				if ( VerQueryValueA(v2, "\\", &lpBuffer, &puLen) )
					sprintf(
						"internal version unknown",
						"version %d.%d.%d.%d",
						*((unsigned short *)lpBuffer + 9),
						*((_DWORD *)lpBuffer + 4) & 0xFFFF,
						*((unsigned short *)lpBuffer + 11),
						*((_DWORD *)lpBuffer + 5) & 0xFFFF);
			}
			mem_free_dbg(v2);
		}
	}
}

//----- (0041B06C) --------------------------------------------------------
LRESULT __stdcall init_palette(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	if ( Msg > WM_ERASEBKGND )
	{
		if ( Msg == WM_ACTIVATEAPP )
		{
			init_activate_window(hWnd, wParam);
		}
		else
		{
			if ( Msg == WM_QUERYNEWPALETTE )
			{
				SDrawRealizePalette();
				return 1;
			}
			if ( Msg == WM_PALETTECHANGED && (HWND)wParam != hWnd )
				SDrawRealizePalette();
		}
	}
	else
	{
		switch ( Msg )
		{
			case WM_ERASEBKGND:
				return 0;
			case WM_CREATE:
				ghMainWnd = hWnd;
				break;
			case WM_DESTROY:
				init_cleanup(1);
				ghMainWnd = 0;
				PostQuitMessage(0);
				break;
			case WM_PAINT:
				force_redraw = 255;
				break;
			case WM_CLOSE:
				return 0;
		}
	}
	return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
// 52571C: using guessed type int force_redraw;

//----- (0041B105) --------------------------------------------------------
void __fastcall init_activate_window(HWND hWnd, bool activated)
{
	HWND v2; // esi
	LONG v3; // eax
	LONG v4; // eax

	v2 = hWnd;
	window_activated = activated;
	UiAppActivate(activated);
	v3 = GetWindowLongA(v2, -16);
	if ( window_activated && exclusive )
		v4 = v3 & 0xFFF7FFFF;
	else
		v4 = v3 | 0x80000;
	SetWindowLongA(v2, -16, v4);
	if ( window_activated )
	{
		force_redraw = 255;
		ResetPal();
	}
}
// 484364: using guessed type int exclusive;
// 52571C: using guessed type int force_redraw;
// 634980: using guessed type int window_activated;

//----- (0041B15F) --------------------------------------------------------
LRESULT __stdcall init_redraw_window(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	LRESULT result; // eax

	if ( CurrentProc )
		result = CurrentProc(hWnd, Msg, wParam, lParam);
	else
		result = init_palette(hWnd, Msg, wParam, lParam);
	return result;
}

//----- (0041B184) --------------------------------------------------------
LRESULT (__stdcall *__fastcall SetWindowProc(void *func))(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	LRESULT (__stdcall *result)(HWND, UINT, WPARAM, LPARAM); // eax

	result = CurrentProc;
	CurrentProc = (LRESULT (__stdcall *)(HWND, UINT, WPARAM, LPARAM))func;
	return result;
}

//----- (0041B195) --------------------------------------------------------
void __cdecl interfac_cpp_init()
{
	LODWORD(interfac_cpp_init_value) = interfac_inf;
}
// 47AE40: using guessed type int interfac_inf;

//----- (0041B1A0) --------------------------------------------------------
void __cdecl interface_msg_pump()
{
	MSG Msg; // [esp+8h] [ebp-1Ch]

	while ( PeekMessageA(&Msg, 0, 0, 0, 1u) )
	{
		if ( Msg.message != WM_QUIT )
		{
			TranslateMessage(&Msg);
			DispatchMessageA(&Msg);
		}
	}
}

//----- (0041B1DF) --------------------------------------------------------
bool __cdecl IncProgress()
{
	interface_msg_pump();
	sgdwProgress += 15;
	if ( (unsigned int)sgdwProgress > 0x216 )
		sgdwProgress = 534;
	if ( sgpBackCel )
		DrawCutscene();
	return (unsigned int)sgdwProgress >= 0x216;
}

//----- (0041B218) --------------------------------------------------------
void __cdecl DrawCutscene()
{
	unsigned int v0; // esi

	dx_lock_mutex();
	Cel_decode(64, 639, sgpBackCel, 1, 640);
	v0 = 0;
	if ( sgdwProgress )
	{
		do
			DrawProgress(
				progress_bar_screen_pos[progress_id].x + v0++ + 64,
				progress_bar_screen_pos[progress_id].y + 160,
				progress_id);
		while ( v0 < sgdwProgress );
	}
	dx_unlock_mutex();
	force_redraw = 255;
	scrollrt_455E65(0);
}
// 52571C: using guessed type int force_redraw;

//----- (0041B28D) --------------------------------------------------------
void __fastcall DrawProgress(int screen_x, int screen_y, int progress_id)
{
	_BYTE *v3; // eax
	signed int v4; // ecx

	v3 = (unsigned char *)gpBuffer + screen_y_times_768[screen_y] + screen_x;
	v4 = 22;
	do
	{
		*v3 = progress_bar_colours[progress_id];
		v3 += 768;
		--v4;
	}
	while ( v4 );
}

//----- (0041B2B6) --------------------------------------------------------
void __fastcall ShowProgress(int uMsg)
{
	int v1; // esi
	LRESULT (__stdcall *v2)(HWND, UINT, WPARAM, LPARAM); // edi
	bool v3; // cl
	int v4; // eax
	int v5; // edx
	int v6; // ecx
	signed int v7; // [esp-4h] [ebp-10h]

	gbSomebodyWonGameKludge = 0;
	v1 = uMsg;
	plrmsg_delay(1);
	v2 = SetWindowProc(DisableInputWndProc);
	interface_msg_pump();
	ClearScreenBuffer();
	scrollrt_455E65(1);
	InitCutscene(v1);
	BlackPalette();
	DrawCutscene();
	PaletteFadeIn(8);
	IncProgress();
	stream_update();
	IncProgress();
	switch ( v1 )
	{
		case WM_DIABNEXTLVL:
			IncProgress();
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			FreeGameMem();
			v4 = ++currlevel;
			goto LABEL_38;
		case WM_DIABPREVLVL:
			IncProgress();
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			IncProgress();
			FreeGameMem();
			leveltype = gnLevelTypeTbl[--currlevel];
			IncProgress();
			v5 = 1;
			goto LABEL_33;
		case WM_DIABRTNLVL:
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			setlevel = 0;
			FreeGameMem();
			IncProgress();
			GetReturnLvlPos();
			v7 = 3;
			goto LABEL_32;
		case WM_DIABSETLVL:
			SetReturnLvlPos();
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			setlevel = 1;
			leveltype = setlvltype;
			FreeGameMem();
			IncProgress();
			v7 = 2;
			goto LABEL_32;
		case WM_DIABWARPLVL:
			IncProgress();
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			FreeGameMem();
			GetPortalLevel();
			IncProgress();
			v7 = 5;
			goto LABEL_32;
		case WM_DIABTOWNWARP:
			IncProgress();
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			FreeGameMem();
			currlevel = plr[myplr].plrlevel;
			leveltype = gnLevelTypeTbl[currlevel];
			IncProgress();
			v7 = 6;
			goto LABEL_32;
		case WM_DIABTWARPUP:
			IncProgress();
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			FreeGameMem();
			currlevel = plr[myplr].plrlevel;
			leveltype = gnLevelTypeTbl[currlevel];
			IncProgress();
			v7 = 7;
LABEL_32:
			v5 = v7;
LABEL_33:
			v3 = 0;
			goto LABEL_40;
		case WM_DIABRETOWN:
			IncProgress();
			if ( gbMaxPlayers == 1 )
				SaveLevel();
			else
				DeltaSaveLevel();
			FreeGameMem();
			currlevel = plr[myplr].plrlevel;
			v4 = currlevel;
LABEL_38:
			leveltype = gnLevelTypeTbl[v4];
			IncProgress();
			v3 = 0;
			goto LABEL_39;
		case WM_DIABNEWGAME:
			IncProgress();
			FreeGameMem();
			IncProgress();
			pfile_remove_temp_files();
			v3 = 1;
LABEL_39:
			v5 = 0;
LABEL_40:
			LoadGameLevel(v3, v5);
			goto LABEL_41;
		case WM_DIABLOADGAME:
			IncProgress();
			LoadGame((void *)1);
LABEL_41:
			IncProgress();
			break;
		default:
			break;
	}
	PaletteFadeOut(8);
	FreeInterface();
	SetWindowProc(v2);
	_LOWORD(v6) = plr[myplr].plrlevel;
	NetSendCmdLocParam1(1u, CMD_PLAYER_JOINLEVEL, plr[myplr].WorldX, plr[myplr].WorldY, v6);
	plrmsg_delay(0);
	ResetPal();
	if ( gbSomebodyWonGameKludge && plr[myplr].plrlevel == 16 )
		PrepDoEnding();
	gbSomebodyWonGameKludge = 0;
}
// 5BB1ED: using guessed type char leveltype;
// 5CF31C: using guessed type char setlvltype;
// 5CF31D: using guessed type char setlevel;
// 6761B8: using guessed type char gbSomebodyWonGameKludge;
// 679660: using guessed type char gbMaxPlayers;

//----- (0041B5F5) --------------------------------------------------------
void __cdecl FreeInterface()
{
	void *v0; // ecx

	v0 = sgpBackCel;
	sgpBackCel = 0;
	mem_free_dbg(v0);
}

//----- (0041B607) --------------------------------------------------------
void __fastcall InitCutscene(int interface_mode)
{
	int v1; // eax
	int v2; // eax
	int v3; // eax
	int v4; // eax
	unsigned char *v5; // eax
	char *v6; // ecx
	int *v7; // eax
	int v8; // eax
	int v9; // eax
	int v10; // eax
	int v11; // eax
	int v12; // eax
	int v13; // eax
	int v14; // eax

	switch ( interface_mode )
	{
		case WM_DIABNEXTLVL:
			v1 = gnLevelTypeTbl[currlevel];
			if ( !v1 )
				goto LABEL_31;
			v2 = v1 - 1;
			if ( !v2 )
				goto LABEL_10;
			v3 = v2 - 1;
			if ( !v3 )
				goto LABEL_9;
			v4 = v3 - 1;
			if ( !v4 )
				goto LABEL_29;
			if ( v4 != 1 )
				goto LABEL_10;
			if ( currlevel < 0xFu )
				goto LABEL_28;
			v5 = LoadFileInMem("Gendata\\Cutgate.CEL", 0);
			v6 = "Gendata\\Cutgate.pal";
			goto LABEL_30;
		case WM_DIABPREVLVL:
			v7 = &gnLevelTypeTbl[currlevel];
			if ( !*(v7 - 1) )
				goto LABEL_31;
			v8 = *v7;
			if ( !v8 )
				goto LABEL_31;
			v9 = v8 - 1;
			if ( !v9 )
				goto LABEL_10;
			v10 = v9 - 1;
			if ( !v10 )
			{
LABEL_9:
				sgpBackCel = LoadFileInMem("Gendata\\Cut2.CEL", 0);
				LoadPalette("Gendata\\Cut2.pal");
				progress_id = 2;
				goto LABEL_33;
			}
			v11 = v10 - 1;
			if ( !v11 )
				goto LABEL_29;
			if ( v11 == 1 )
				goto LABEL_28;
LABEL_10:
			sgpBackCel = LoadFileInMem("Gendata\\Cutl1d.CEL", 0);
			LoadPalette("Gendata\\Cutl1d.pal");
			progress_id = 0;
			goto LABEL_33;
		case WM_DIABRTNLVL:
		case WM_DIABSETLVL:
			if ( setlvlnum == SL_BONECHAMB )
				goto LABEL_21;
			if ( setlvlnum != SL_VILEBETRAYER )
				goto LABEL_10;
			v5 = LoadFileInMem("Gendata\\Cutportr.CEL", 0);
			v6 = "Gendata\\Cutportr.pal";
			goto LABEL_30;
		case WM_DIABWARPLVL:
			v5 = LoadFileInMem("Gendata\\Cutportl.CEL", 0);
			v6 = "Gendata\\Cutportl.pal";
			goto LABEL_30;
		case WM_DIABTOWNWARP:
		case WM_DIABTWARPUP:
			v12 = gnLevelTypeTbl[plr[myplr].plrlevel];
			if ( !v12 )
				goto LABEL_31;
			v13 = v12 - 2;
			if ( !v13 )
			{
LABEL_21:
				sgpBackCel = LoadFileInMem("Gendata\\Cut2.CEL", 0);
				LoadPalette("Gendata\\Cut2.pal");
				progress_id = SL_BONECHAMB;
				goto LABEL_33;
			}
			v14 = v13 - 1;
			if ( v14 )
			{
				if ( v14 != 1 )
					goto LABEL_33;
LABEL_28:
				v5 = LoadFileInMem("Gendata\\Cut4.CEL", 0);
				v6 = "Gendata\\Cut4.pal";
			}
			else
			{
LABEL_29:
				v5 = LoadFileInMem("Gendata\\Cut3.CEL", 0);
				v6 = "Gendata\\Cut3.pal";
			}
LABEL_30:
			sgpBackCel = v5;
			LoadPalette(v6);
			progress_id = 1;
LABEL_33:
			sgdwProgress = 0;
			return;
		case WM_DIABRETOWN:
LABEL_31:
			v5 = LoadFileInMem("Gendata\\Cuttt.CEL", 0);
			v6 = "Gendata\\Cuttt.pal";
			goto LABEL_30;
		case WM_DIABNEWGAME:
		case WM_DIABLOADGAME:
			v5 = LoadFileInMem("Gendata\\Cutstart.CEL", 0);
			v6 = "Gendata\\Cutstart.pal";
			goto LABEL_30;
		default:
			TermMsg("Unknown progress mode");
			goto LABEL_33;
	}
}
// 5CCB10: using guessed type char setlvlnum;

//----- (0041B814) --------------------------------------------------------
void __cdecl FreeInvGFX()
{
	void *v0; // ecx

	v0 = pInvCels;
	pInvCels = 0;
	mem_free_dbg(v0);
}

//----- (0041B826) --------------------------------------------------------
void __cdecl InitInv()
{
	char v0; // al
	char *v1; // ecx

	v0 = plr[myplr]._pClass;
	switch ( v0 )
	{
		case UI_WARRIOR:
			v1 = "Data\\Inv\\Inv.CEL";
LABEL_7:
			pInvCels = LoadFileInMem(v1, 0);
			break;
		case UI_ROGUE:
			v1 = "Data\\Inv\\Inv_rog.CEL";
			goto LABEL_7;
		case UI_SORCERER:
			v1 = "Data\\Inv\\Inv_Sor.CEL";
			goto LABEL_7;
	}
	invflag = 0;
	drawsbarflag = 0;
}

//----- (0041B871) --------------------------------------------------------
void __fastcall InvDrawSlotBack(int X, int Y, int W, int H)
{
	unsigned char *v4; // edi
	int v5; // edx
	int v6; // ecx
	unsigned char v7; // al
	unsigned char v8; // al

	v4 = (unsigned char *)gpBuffer + screen_y_times_768[Y] + X;
	v5 = (unsigned short)H;
	do
	{
		v6 = (unsigned short)W;
		do
		{
			v7 = *v4;
			if ( *v4 < 0xB0u )
				goto LABEL_9;
			if ( v7 > 0xBFu )
			{
				if ( v7 < 0xF0u )
					goto LABEL_9;
				v8 = v7 - 80;
			}
			else
			{
				v8 = v7 - 16;
			}
			*v4 = v8;
LABEL_9:
			++v4;
			--v6;
		}
		while ( v6 );
		v4 = &v4[-(unsigned short)W - 768];
		--v5;
	}
	while ( v5 );
}

//----- (0041B8C4) --------------------------------------------------------
void __cdecl DrawInv()
{
	int v0; // ecx
	int v1; // eax
	int v2; // esi
	int v3; // ebp
	char v4; // cl
	int v5; // ecx
	int v6; // eax
	int v7; // edi
	int v8; // edx
	char v9; // cl
	int v10; // ecx
	int v11; // eax
	int v12; // edi
	int v13; // edx
	char v14; // cl
	int v15; // ecx
	int v16; // eax
	int v17; // esi
	int v18; // edx
	char v19; // cl
	int v20; // ecx
	int v21; // eax
	int v22; // esi
	int v23; // edi
	int v24; // ebp
	char v25; // cl
	char *v26; // ecx
	int v27; // ebp
	int v28; // eax
	int v29; // esi
	int v30; // edi
	char v31; // cl
	int v32; // ecx
	int v33; // eax
	int v34; // esi
	int v35; // edi
	char v36; // cl
	signed int v37; // esi
	signed int v38; // edi
	int v39; // ecx
	char v40; // al
	int v41; // eax
	int v42; // ebp
	int v43; // ecx
	int v44; // esi
	char v45; // al
	int v46; // ecx
	int v47; // edx
	int screen_y; // [esp+10h] [ebp-A8h]
	int screen_ya; // [esp+10h] [ebp-A8h]
	int screen_yb; // [esp+10h] [ebp-A8h]
	signed int screen_yc; // [esp+10h] [ebp-A8h]
	signed int screen_yd; // [esp+10h] [ebp-A8h]
	int screen_ye; // [esp+10h] [ebp-A8h]
	signed int screen_x; // [esp+14h] [ebp-A4h]
	int v55[40]; // [esp+18h] [ebp-A0h]

	Cel_decode(384, 511, pInvCels, 1, 320);
	if ( plr[myplr].InvBody[0]._itype != -1 )
	{
		InvDrawSlotBack(517, 219, 56, 56);
		v0 = myplr;
		v1 = myplr;
		v2 = plr[myplr].InvBody[0]._iCurs + 12;
		v3 = InvItemWidth[v2];
		if ( !pcursinvitem )
		{
			v4 = -59;
			if ( plr[v1].InvBody[0]._iMagical )
				v4 = -75;
			if ( !plr[v1].InvBody[0]._iStatFlag )
				v4 = -27;
			Cel_colour(v4, 517, 219, (char *)pCursCels, v2, v3, 0, 8);
			v0 = myplr;
		}
		if ( plr[v0].InvBody[0]._iStatFlag )
			Cel_header(517, 219, (char *)pCursCels, v2, v3, 0, 8);
		else
			Cel_header_and_light_not_equipable(517, 219, (char *)pCursCels, v2, v3, 0, 8, 1);
	}
	if ( plr[myplr].InvBody[1]._itype != -1 )
	{
		InvDrawSlotBack(432, 365, 28, 28);
		v5 = myplr;
		v6 = myplr;
		v7 = plr[myplr].InvBody[1]._iCurs + 12;
		v8 = InvItemWidth[v7];
		screen_y = InvItemWidth[v7];
		if ( pcursinvitem == 1 )
		{
			v9 = -59;
			if ( plr[v6].InvBody[1]._iMagical )
				v9 = -75;
			if ( !plr[v6].InvBody[1]._iStatFlag )
				v9 = -27;
			Cel_colour(v9, 432, 365, (char *)pCursCels, v7, v8, 0, 8);
			v5 = myplr;
			v8 = screen_y;
		}
		if ( plr[v5].InvBody[1]._iStatFlag )
			Cel_header(432, 365, (char *)pCursCels, v7, v8, 0, 8);
		else
			Cel_header_and_light_not_equipable(432, 365, (char *)pCursCels, v7, v8, 0, 8, 1);
	}
	if ( plr[myplr].InvBody[2]._itype != -1 )
	{
		InvDrawSlotBack(633, 365, 28, 28);
		v10 = myplr;
		v11 = myplr;
		v12 = plr[myplr].InvBody[2]._iCurs + 12;
		v13 = InvItemWidth[v12];
		screen_ya = InvItemWidth[v12];
		if ( pcursinvitem == 2 )
		{
			v14 = -59;
			if ( plr[v11].InvBody[2]._iMagical )
				v14 = -75;
			if ( !plr[v11].InvBody[2]._iStatFlag )
				v14 = -27;
			Cel_colour(v14, 633, 365, (char *)pCursCels, v12, v13, 0, 8);
			v10 = myplr;
			v13 = screen_ya;
		}
		if ( plr[v10].InvBody[2]._iStatFlag )
			Cel_header(633, 365, (char *)pCursCels, v12, v13, 0, 8);
		else
			Cel_header_and_light_not_equipable(633, 365, (char *)pCursCels, v12, v13, 0, 8, 1);
	}
	if ( plr[myplr].InvBody[3]._itype != -1 )
	{
		InvDrawSlotBack(589, 220, 28, 28);
		v15 = myplr;
		v16 = myplr;
		v17 = plr[myplr].InvBody[3]._iCurs + 12;
		v18 = InvItemWidth[v17];
		screen_yb = InvItemWidth[v17];
		if ( pcursinvitem == 3 )
		{
			v19 = -59;
			if ( plr[v16].InvBody[3]._iMagical )
				v19 = -75;
			if ( !plr[v16].InvBody[3]._iStatFlag )
				v19 = -27;
			Cel_colour(v19, 589, 220, (char *)pCursCels, v17, v18, 0, 8);
			v15 = myplr;
			v18 = screen_yb;
		}
		if ( plr[v15].InvBody[3]._iStatFlag )
			Cel_header(589, 220, (char *)pCursCels, v17, v18, 0, 8);
		else
			Cel_header_and_light_not_equipable(589, 220, (char *)pCursCels, v17, v18, 0, 8, 1);
	}
	if ( plr[myplr].InvBody[4]._itype != -1 )
	{
		InvDrawSlotBack(401, 320, 56, 84);
		v20 = myplr;
		v21 = myplr;
		v22 = plr[myplr].InvBody[4]._iCurs + 12;
		v23 = InvItemWidth[v22];
		v24 = v23 != 28 ? 401 : 415;
		screen_yc = InvItemHeight[v22] != 84 ? 306 : 320;
		if ( pcursinvitem == 4 )
		{
			v25 = -59;
			if ( plr[v21].InvBody[4]._iMagical )
				v25 = -75;
			if ( !plr[v21].InvBody[4]._iStatFlag )
				v25 = -27;
			Cel_colour(v25, v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8);
			v20 = myplr;
		}
		if ( plr[v20].InvBody[4]._iStatFlag )
			Cel_header(v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8);
		else
			Cel_header_and_light_not_equipable(v24, screen_yc, (char *)pCursCels, v22, v23, 0, 8, 1);
		if ( plr[myplr].InvBody[4]._iLoc == ILOC_TWOHAND )
		{
			InvDrawSlotBack(631, 320, 56, 84);
			light_table_index = 0;
			cel_transparency_active = 1;
			v26 = &gpBuffer->row[160].pixels[581];
			if ( v23 != 28 )
				v26 = &gpBuffer->row[160].pixels[567];
			Cel_header_light_and_trans_into_buf(v26, (char *)pCursCels, v22, v23, 0, 8);
			cel_transparency_active = 0;
		}
	}
	if ( plr[myplr].InvBody[5]._itype != -1 )
	{
		InvDrawSlotBack(631, 320, 56, 84);
		v27 = myplr;
		v28 = myplr;
		v29 = plr[myplr].InvBody[5]._iCurs + 12;
		v30 = InvItemWidth[v29];
		screen_yd = InvItemHeight[v29] != 84 ? 306 : 320;
		if ( pcursinvitem == 5 )
		{
			v31 = -59;
			if ( plr[v28].InvBody[5]._iMagical )
				v31 = -75;
			if ( !plr[v28].InvBody[5]._iStatFlag )
				v31 = -27;
			Cel_colour(v31, v30 != 28 ? 633 : 645, screen_yd, (char *)pCursCels, v29, v30, 0, 8);
			v27 = myplr;
		}
		screen_x = v30 != 28 ? 633 : 645;
		if ( plr[v27].InvBody[5]._iStatFlag )
			Cel_header(screen_x, screen_yd, (char *)pCursCels, v29, v30, 0, 8);
		else
			Cel_header_and_light_not_equipable(screen_x, screen_yd, (char *)pCursCels, v29, v30, 0, 8, 1);
	}
	if ( plr[myplr].InvBody[6]._itype != -1 )
	{
		InvDrawSlotBack(517, 320, 56, 84);
		v32 = myplr;
		v33 = myplr;
		v34 = plr[myplr].InvBody[6]._iCurs + 12;
		v35 = InvItemWidth[v34];
		if ( pcursinvitem == 6 )
		{
			v36 = -59;
			if ( plr[v33].InvBody[6]._iMagical )
				v36 = -75;
			if ( !plr[v33].InvBody[6]._iStatFlag )
				v36 = -27;
			Cel_colour(v36, 517, 320, (char *)pCursCels, v34, v35, 0, 8);
			v32 = myplr;
		}
		if ( plr[v32].InvBody[6]._iStatFlag )
			Cel_header(517, 320, (char *)pCursCels, v34, v35, 0, 8);
		else
			Cel_header_and_light_not_equipable(517, 320, (char *)pCursCels, v34, v35, 0, 8, 1);
	}
	v37 = 0;
	do
	{
		if ( plr[myplr].InvGrid[v37] )
			InvDrawSlotBack(inv_screen_pos[v37 + 25].x + 64, inv_screen_pos[v37 + 25].y + 159, 28, 28);
		++v37;
	}
	while ( v37 < 40 );
	v38 = 0;
	do
	{
		v39 = 21720 * myplr;
		v40 = plr[myplr].InvGrid[v38];
		if ( v40 > 0 )
		{
			v41 = v40 - 1;
			v55[v38] = 1;
			v42 = v41;
			v43 = 368 * v41 + v39;
			v44 = *(int *)((char *)&plr[0].InvList[0]._iCurs + v43) + 12;
			screen_ye = InvItemWidth[v44];
			if ( pcursinvitem == v41 + 7 )
			{
				v45 = -59;
				if ( *(&plr[0].InvList[0]._iMagical + v43) )
					v45 = -75;
				if ( !*(int *)((char *)&plr[0].InvList[0]._iStatFlag + v43) )
					v45 = -27;
				Cel_colour(
					v45,
					inv_screen_pos[v38 + 25].x + 64,
					inv_screen_pos[v38 + 25].y + 159,
					(char *)pCursCels,
					v44,
					screen_ye,
					0,
					8);
			}
			v46 = inv_screen_pos[v38 + 25].x + 64;
			v47 = inv_screen_pos[v38 + 25].y + 159;
			if ( plr[myplr].InvList[v42]._iStatFlag )
				Cel_header(v46, v47, (char *)pCursCels, v44, screen_ye, 0, 8);
			else
				Cel_header_and_light_not_equipable(v46, v47, (char *)pCursCels, v44, screen_ye, 0, 8, 1);
		}
		++v38;
	}
	while ( v38 < 40 );
}
// 4B8CB8: using guessed type char pcursinvitem;
// 69BEF8: using guessed type int light_table_index;
// 69CF94: using guessed type int cel_transparency_active;
// 41B8C4: using guessed type int var_A0[40];

//----- (0041C060) --------------------------------------------------------
void __cdecl DrawInvBelt()
{
	int v0; // ebx
	signed int v1; // esi
	int v2; // ecx
	int v3; // eax
	int v4; // edi
	char v5; // cl
	int v6; // edx
	bool v7; // zf
	int v8; // ecx
	int v9; // eax
	char *v10; // edx
	signed int v11; // [esp+4h] [ebp-Ch]
	int frame_width; // [esp+8h] [ebp-8h]
	int v13; // [esp+Ch] [ebp-4h]

	v0 = 0;
	if ( !talkflag )
	{
		DrawPanelBox(205, 21, 0xE8u, 0x1Cu, 269, 517);
		v11 = 0;
		v13 = 0;
		do
		{
			if ( *(int *)((char *)&plr[myplr].SpdList[0]._itype + v0) != -1 )
			{
				v1 = v11;
				InvDrawSlotBack(inv_screen_pos[v11 + 65].x + 64, inv_screen_pos[v11 + 65].y + 159, 28, 28);
				v2 = myplr;
				v3 = v0 + 21720 * myplr;
				v4 = *(int *)((char *)&plr[0].SpdList[0]._iCurs + v3) + 12;
				frame_width = InvItemWidth[v4];
				if ( pcursinvitem == v11 + 47 )
				{
					v5 = -59;
					if ( *(&plr[0].SpdList[0]._iMagical + v3) )
						v5 = -75;
					if ( !*(int *)((char *)&plr[0].SpdList[0]._iStatFlag + v3) )
						v5 = -27;
					Cel_colour(
						v5,
						inv_screen_pos[v1 + 65].x + 64,
						inv_screen_pos[v1 + 65].y + 159,
						(char *)pCursCels,
						v4,
						frame_width,
						0,
						8);
					v2 = myplr;
				}
				v0 = v13;
				v6 = inv_screen_pos[v1 + 65].y + 159;
				v7 = *(int *)((char *)&plr[v2].SpdList[0]._iStatFlag + v13) == 0;
				v8 = inv_screen_pos[v1 + 65].x;
				if ( v7 )
					Cel_header_and_light_not_equipable(v8 + 64, v6, (char *)pCursCels, v4, frame_width, 0, 8, 1);
				else
					Cel_header(v8 + 64, v6, (char *)pCursCels, v4, frame_width, 0, 8);
				v9 = v13 + 21720 * myplr;
				if ( AllItemsList[*(int *)((char *)&plr[0].SpdList[0].IDidx + v9)].iUsable
				  && *(int *)((char *)&plr[0].SpdList[0]._iStatFlag + v9)
				  && *(int *)((char *)&plr[0].SpdList[0]._itype + v9) != 11 )
				{
					v10 = (char *)fontframe[fontidx[(unsigned char)(v11 + 49)]];
					CPrintString(
						screen_y_times_768[inv_screen_pos[v1 + 65].y + 159]
					  - fontkern[(_DWORD)v10]
					  + inv_screen_pos[v1 + 65].x
					  + 92,
						v10,
						0);
				}
			}
			++v11;
			v0 += 368;
			v13 = v0;
		}
		while ( v11 < 8 );
	}
}
// 4B8960: using guessed type int talkflag;
// 4B8CB8: using guessed type char pcursinvitem;

//----- (0041C23F) --------------------------------------------------------
int __fastcall AutoPlace(int pnum, int ii, int sx, int sy, int saveflag)
{
	__int64 v5; // rax
	int v6; // ebx
	signed int v7; // edx
	signed int v8; // eax
	signed int v9; // esi
	int j; // edi
	int v11; // eax
	signed int v12; // esi
	signed int v13; // ecx
	int v14; // edi
	char *v15; // ecx
	char v16; // dl
	signed int v18; // [esp+Ch] [ebp-Ch]
	int p; // [esp+10h] [ebp-8h]
	int v20; // [esp+14h] [ebp-4h]
	int i; // [esp+14h] [ebp-4h]

	p = pnum;
	v5 = ii;
	v6 = 1;
	v18 = v5 % 10;
	v7 = 10 * (unsigned __int64)(v5 / 10);
	v8 = v7;
	if ( v7 < 0 )
		v8 = 0;
	v20 = 0;
	if ( sy <= 0 )
	{
LABEL_16:
		if ( saveflag )
		{
			v11 = pnum;
			qmemcpy(
				&plr[pnum].InvList[plr[pnum]._pNumInv],
				&plr[pnum].HoldItem,
				sizeof(plr[pnum].InvList[plr[pnum]._pNumInv]));
			++plr[v11]._pNumInv;
			v12 = v7;
			if ( v7 < 0 )
				v12 = 0;
			for ( i = 0; i < sy; ++i )
			{
				v13 = v18;
				if ( v18 < 0 )
					v13 = 0;
				v14 = 0;
				if ( sx > 0 )
				{
					v15 = &plr[v11].InvGrid[v13 + v12];
					do
					{
						if ( v14 || i != sy - 1 )
							v16 = -_LOBYTE(plr[v11]._pNumInv);
						else
							v16 = plr[v11]._pNumInv;
						*v15++ = v16;
						++v14;
					}
					while ( v14 < sx );
				}
				v12 += 10;
			}
			CalcPlrScrolls(p);
		}
	}
	else
	{
		while ( v6 )
		{
			if ( v8 >= 40 )
				v6 = 0;
			v9 = v18;
			if ( v18 < 0 )
				v9 = 0;
			for ( j = 0; j < sx; ++j )
			{
				if ( !v6 )
					break;
				v6 = 0;
				if ( v9 < 10 )
					_LOBYTE(v6) = plr[pnum].InvGrid[v9 + v8] == 0;
				++v9;
			}
			v8 += 10;
			if ( ++v20 >= sy )
			{
				if ( !v6 )
					return v6;
				goto LABEL_16;
			}
		}
	}
	return v6;
}

//----- (0041C373) --------------------------------------------------------
int __fastcall SpecialAutoPlace(int pnum, int ii, int sx, int sy, int saveflag)
{
	__int64 v5; // rax
	int v6; // ebx
	signed int v7; // edx
	signed int v8; // eax
	signed int v9; // esi
	int j; // edi
	signed int v11; // ecx
	int *v12; // eax
	int v13; // eax
	signed int v14; // esi
	signed int v15; // ecx
	int v16; // edi
	char *v17; // ecx
	char v18; // dl
	signed int v20; // [esp+Ch] [ebp-Ch]
	int p; // [esp+10h] [ebp-8h]
	int v22; // [esp+14h] [ebp-4h]
	int i; // [esp+14h] [ebp-4h]

	p = pnum;
	v5 = ii;
	v6 = 1;
	v20 = v5 % 10;
	v7 = 10 * (unsigned __int64)(v5 / 10);
	v8 = v7;
	if ( v7 < 0 )
		v8 = 0;
	v22 = 0;
	if ( sy <= 0 )
	{
LABEL_25:
		if ( saveflag )
		{
			v13 = p;
			qmemcpy(&plr[p].InvList[plr[p]._pNumInv], &plr[p].HoldItem, sizeof(plr[p].InvList[plr[p]._pNumInv]));
			++plr[v13]._pNumInv;
			v14 = v7;
			if ( v7 < 0 )
				v14 = 0;
			for ( i = 0; i < sy; ++i )
			{
				v15 = v20;
				if ( v20 < 0 )
					v15 = 0;
				v16 = 0;
				if ( sx > 0 )
				{
					v17 = &plr[v13].InvGrid[v15 + v14];
					do
					{
						if ( v16 || i != sy - 1 )
							v18 = -_LOBYTE(plr[v13]._pNumInv);
						else
							v18 = plr[v13]._pNumInv;
						*v17++ = v18;
						++v16;
					}
					while ( v16 < sx );
				}
				v14 += 10;
			}
			CalcPlrScrolls(p);
		}
		return v6;
	}
	while ( v6 )
	{
		if ( v8 >= 40 )
			v6 = 0;
		v9 = v20;
		if ( v20 < 0 )
			v9 = 0;
		for ( j = 0; j < sx; ++j )
		{
			if ( !v6 )
				break;
			v6 = 0;
			if ( v9 < 10 )
				_LOBYTE(v6) = plr[pnum].InvGrid[v9 + v8] == 0;
			++v9;
		}
		v8 += 10;
		if ( ++v22 >= sy )
		{
			if ( v6 )
				goto LABEL_25;
			break;
		}
	}
	if ( sx <= 1 && sy <= 1 )
	{
		v11 = 0;
		v12 = &plr[p].SpdList[0]._itype;
		while ( *v12 != -1 )
		{
			++v11;
			v12 += 92;
			if ( v11 >= 8 )
				goto LABEL_24;
		}
		v6 = 1;
		goto LABEL_25;
	}
	v6 = 0;
LABEL_24:
	if ( v6 )
		goto LABEL_25;
	return v6;
}

//----- (0041C4E0) --------------------------------------------------------
int __fastcall GoldAutoPlace(int pnum)
{
	int v1; // ebp
	int v2; // edi
	int v3; // ecx
	int *v4; // esi
	int v5; // eax
	int v6; // edi
	int *v7; // esi
	int v8; // eax
	signed int v9; // ebx
	char *v10; // edx
	int v11; // eax
	int v12; // ecx
	int pnuma; // [esp+10h] [ebp-4h]

	pnuma = pnum;
	v1 = pnum;
	v2 = 0;
	v3 = 0;
	if ( plr[v1]._pNumInv <= 0 )
	{
LABEL_14:
		v6 = 0;
		if ( plr[v1]._pNumInv <= 0 )
		{
LABEL_28:
			v9 = 39;
			do
			{
				if ( v3 )
					break;
				v10 = &plr[0].InvGrid[10 * (v9 / 10) + v1 * 21720 + v9 % 10];
				if ( !*v10 )
				{
					v11 = v1 * 21720 + 368 * plr[v1]._pNumInv;
					qmemcpy((char *)plr[0].InvList + v11, &plr[v1].HoldItem, 0x170u);
					++plr[v1]._pNumInv;
					*v10 = plr[v1]._pNumInv;
					v12 = plr[v1].HoldItem._ivalue;
					if ( v12 < 2500 )
					{
						if ( v12 > 1000 )
							*(int *)((char *)&plr[0].InvList[0]._iCurs + v11) = 5;
						else
							*(int *)((char *)&plr[0].InvList[0]._iCurs + v11) = 4;
					}
					else
					{
						*(int *)((char *)&plr[0].InvList[0]._iCurs + v11) = 6;
					}
					plr[v1]._pGold = CalculateGold(pnuma);
					v3 = 1;
				}
				--v9;
			}
			while ( v9 >= 0 );
		}
		else
		{
			v7 = &plr[v1].InvList[0]._ivalue;
			while ( !v3 )
			{
				if ( *(v7 - 47) == 11 && *v7 < 5000 )
				{
					v8 = plr[v1].HoldItem._ivalue + *v7;
					if ( v8 <= 5000 )
					{
						*v7 = v8;
						if ( v8 < 2500 )
						{
							if ( v8 > 1000 )
								*(v7 - 1) = 5;
							else
								*(v7 - 1) = 4;
						}
						else
						{
							*(v7 - 1) = 6;
						}
						plr[v1]._pGold = CalculateGold(pnuma);
						v3 = 1;
					}
				}
				++v6;
				v7 += 92;
				if ( v6 >= plr[v1]._pNumInv )
				{
					if ( v3 )
						return v3;
					goto LABEL_28;
				}
			}
		}
	}
	else
	{
		v4 = &plr[v1].InvList[0]._ivalue;
		while ( !v3 )
		{
			if ( *(v4 - 47) == 11 )
			{
				v5 = *v4 + plr[v1].HoldItem._ivalue;
				if ( v5 <= 5000 )
				{
					*v4 = v5;
					if ( v5 < 2500 )
					{
						if ( v5 > 1000 )
							*(v4 - 1) = 5;
						else
							*(v4 - 1) = 4;
					}
					else
					{
						*(v4 - 1) = 6;
					}
					plr[v1]._pGold = CalculateGold(pnuma);
					v3 = 1;
				}
			}
			++v2;
			v4 += 92;
			if ( v2 >= plr[v1]._pNumInv )
			{
				if ( v3 )
					return v3;
				goto LABEL_14;
			}
		}
	}
	return v3;
}

//----- (0041C6A9) --------------------------------------------------------
int __fastcall WeaponAutoPlace(int pnum)
{
	int v1; // edi
	int v2; // eax
	int v3; // ecx
	ItemStruct *v4; // esi
	ItemStruct *v5; // edi
	int result; // eax

	v1 = pnum;
	if ( plr[pnum].HoldItem._iLoc == ILOC_TWOHAND )
	{
		if ( plr[v1].InvBody[4]._itype != -1 || plr[v1].InvBody[5]._itype != -1 )
			return 0;
LABEL_12:
		NetSendCmdChItem(1u, 4u);
		v4 = &plr[v1].HoldItem;
		v5 = &plr[v1].InvBody[4];
		goto LABEL_13;
	}
	v2 = plr[v1].InvBody[4]._itype;
	if ( v2 != -1 && plr[v1].InvBody[4]._iClass == 1 )
		return 0;
	v3 = plr[v1].InvBody[5]._itype;
	if ( v3 != -1 && plr[v1].InvBody[5]._iClass == 1 )
		return 0;
	if ( v2 == -1 )
		goto LABEL_12;
	if ( v3 == -1 && plr[v1].InvBody[4]._iLoc != ILOC_TWOHAND )
	{
		NetSendCmdChItem(1u, 5u);
		v4 = &plr[v1].HoldItem;
		v5 = &plr[v1].InvBody[5];
LABEL_13:
		result = 1;
		qmemcpy(v5, v4, sizeof(ItemStruct));
		return result;
	}
	return 0;
}

//----- (0041C746) --------------------------------------------------------
int __fastcall SwapItem(ItemStruct *a, ItemStruct *b)
{
	int v2; // eax
	ItemStruct h; // [esp+8h] [ebp-170h]

	qmemcpy(&h, a, sizeof(h));
	v2 = h._iCurs;
	qmemcpy(a, b, sizeof(ItemStruct));
	qmemcpy(b, &h, sizeof(ItemStruct));
	return v2 + 12;
}

//----- (0041C783) --------------------------------------------------------
void __fastcall CheckInvPaste(int pnum, int mx, int my)
{
	int v3; // ebx
	int v4; // edi
	int v5; // eax
	int v6; // esi
	signed int v7; // edi
	int v8; // edx
	int v9; // edx
	signed int v10; // edi
	char v11; // al
	signed int v12; // ecx
	int v13; // eax
	int v14; // eax
	char *v15; // edi
	int v16; // esi
	int v17; // ecx
	int v18; // edx
	char v19; // al
	int v20; // ecx
	int v21; // esi
	ItemStruct *v22; // edi
	ItemStruct *v23; // ecx
	int v24; // eax
	int v25; // eax
	int v26; // edx
	ItemStruct *v27; // esi
	int v28; // eax
	int v29; // ecx
	int v30; // esi
	int v31; // eax
	int v32; // eax
	int v33; // ecx
	int v34; // eax
	int v35; // ecx
	char *v36; // eax
	int v37; // edx
	int v38; // ecx
	int v39; // edi
	int v40; // esi
	int v41; // ebx
	int v42; // edx
	int v43; // eax
	int v44; // eax
	signed int v45; // ecx
	int v46; // edx
	char *v47; // eax
	int v48; // edi
	int v49; // eax
	int v50; // ecx
	char *v51; // esi
	char v52; // cl
	int v53; // ecx
	int v54; // eax
	int v55; // edi
	int v56; // edx
	int v57; // esi
	int v58; // ebx
	int v59; // eax
	int v60; // esi
	ItemStruct tempitem; // [esp+Ch] [ebp-190h]
	int v62; // [esp+17Ch] [ebp-20h]
	int p; // [esp+180h] [ebp-1Ch]
	int v64; // [esp+184h] [ebp-18h]
	int v65; // [esp+188h] [ebp-14h]
	int v66; // [esp+18Ch] [ebp-10h]
	int v67; // [esp+190h] [ebp-Ch]
	int v68; // [esp+194h] [ebp-8h]
	int v69; // [esp+198h] [ebp-4h]
	char cursor_id; // [esp+1A4h] [ebp+8h]
	char cursor_ida; // [esp+1A4h] [ebp+8h]

	p = pnum;
	v3 = pnum;
	v4 = mx;
	SetICursor(plr[pnum].HoldItem._iCurs + 12);
	v5 = my + (icursH >> 1);
	v6 = v4 + (icursW >> 1);
	v64 = icursW28;
	v7 = 0;
	v67 = icursH28;
	v68 = 0;
	do
	{
		if ( v7 )
			goto LABEL_18;
		v8 = inv_screen_pos[v68].x;
		if ( v6 >= v8 && v6 < v8 + 28 )
		{
			v9 = inv_screen_pos[v68].y;
			if ( v5 >= v9 - 29 && v5 < v9 )
			{
				v7 = 1;
				--v68;
			}
		}
		if ( v68 != 24 )
			goto LABEL_13;
		if ( !(v64 & 1) )
			v6 -= 14;
		if ( !(v67 & 1) )
		{
			v5 -= 14;
LABEL_13:
			if ( v68 == 64 && !(v67 & 1) )
				v5 += 14;
		}
		++v68;
	}
	while ( (unsigned int)v68 < 0x49 );
	if ( !v7 )
		return;
LABEL_18:
	v10 = v68;
	v69 = ILOC_UNEQUIPABLE;
	if ( v68 >= 0 && v68 <= ILOC_ARMOR )
		v69 = ILOC_HELM;
	if ( v68 >= ILOC_HELM && v68 <= ILOC_RING )
		v69 = ILOC_RING;
	if ( v68 == ILOC_AMULET )
		v69 = ILOC_AMULET;
	if ( v68 >= ILOC_UNEQUIPABLE && v68 <= 18 )
		v69 = ILOC_ONEHAND;
	if ( v68 >= 19 && v68 <= 24 )
		v69 = ILOC_ARMOR;
	if ( v68 >= 65 && v68 <= 72 )
		v69 = ILOC_BELT;
	v11 = plr[v3].HoldItem._iLoc;
	v12 = 0;
	if ( (char)v11 == v69 )
		v12 = 1;
	if ( v69 == 1 && v11 == ILOC_TWOHAND )
	{
		v69 = ILOC_TWOHAND;
		v12 = 1;
	}
	if ( v11 != 7 || v69 != ILOC_BELT )
	{
LABEL_50:
		if ( v69 != ILOC_UNEQUIPABLE )
			goto LABEL_81;
		v66 = 0;
		cursor_id = 1;
		v13 = (v68 - 25) / 10;
		if ( plr[v3].HoldItem._itype == ITYPE_GOLD )
		{
			_LOBYTE(v13) = plr[0].InvGrid[10 * v13 + v3 * 21720 + (v68 - 25) % 10];
			if ( !(_BYTE)v13 )
				goto LABEL_93;
			v13 = (char)v13;
			if ( (char)v13 <= 0 )
			{
				v13 = -v13;
			}
			else if ( *(int *)((char *)&plr[0].InvBody[v13 + 6]._itype + v3 * 21720) == ITYPE_GOLD )
			{
				goto LABEL_93;
			}
			v66 = v13;
LABEL_93:
			v21 = p;
			if ( p == myplr )
			{
				PlaySFX(ItemInvSnds[ItemCAnimTbl[plr[v3].HoldItem._iCurs]]);
				v10 = v68;
			}
			cursor_ida = 1;
			switch ( v69 )
			{
				case ILOC_ONEHAND:
					if ( v10 > 12 )
					{
						if ( plr[v3].InvBody[5]._itype == ITYPE_NONE )
						{
							v25 = plr[v3].InvBody[4]._itype;
							if ( v25 == ITYPE_NONE )
								goto LABEL_232;
							if ( plr[v3].InvBody[4]._iLoc == ILOC_TWOHAND )
							{
								NetSendCmdDelItem(0, 4u);
								NetSendCmdChItem(0, 5u);
								SwapItem(&plr[v3].InvBody[5], &plr[v3].InvBody[4]);
								v23 = &plr[v3].InvBody[5];
LABEL_99:
								v24 = SwapItem(v23, &plr[v3].HoldItem);
LABEL_172:
								cursor_ida = v24;
								goto LABEL_226;
							}
							if ( v25 == ITYPE_NONE || plr[v3].InvBody[4]._iClass != plr[v3].HoldItem._iClass )
							{
LABEL_232:
								NetSendCmdChItem(0, 5u);
								v22 = &plr[v3].InvBody[5];
LABEL_158:
								qmemcpy(v22, &plr[v3].HoldItem, sizeof(ItemStruct));
								goto LABEL_226;
							}
						}
						else if ( plr[v3].InvBody[4]._itype == ITYPE_NONE
							   || plr[v3].InvBody[4]._iClass != plr[v3].HoldItem._iClass )
						{
							goto LABEL_114;
						}
					}
					else
					{
						if ( plr[v3].InvBody[4]._itype == ITYPE_NONE )
						{
							if ( plr[v3].InvBody[5]._itype != ITYPE_NONE
							  && plr[v3].InvBody[5]._iClass == plr[v3].HoldItem._iClass )
							{
LABEL_114:
								NetSendCmdChItem(0, 5u);
								v23 = &plr[v3].InvBody[5];
								goto LABEL_99;
							}
							NetSendCmdChItem(0, 4u);
							v22 = &plr[v3].InvBody[4];
							goto LABEL_158;
						}
						if ( plr[v3].InvBody[5]._itype != ITYPE_NONE
						  && plr[v3].InvBody[5]._iClass == plr[v3].HoldItem._iClass )
						{
							goto LABEL_114;
						}
					}
					NetSendCmdChItem(0, 4u);
					v23 = &plr[v3].InvBody[4];
					goto LABEL_99;
				case ILOC_TWOHAND:
					NetSendCmdDelItem(0, 5u);
					if ( plr[v3].InvBody[4]._itype == ITYPE_NONE )
						goto LABEL_147;
					v26 = plr[v3].InvBody[5]._itype;
					if ( v26 == -1 )
						goto LABEL_146;
					qmemcpy(&tempitem, &plr[v3].HoldItem, sizeof(tempitem));
					v27 = &plr[v3].InvBody[5];
					if ( v26 != 5 )
						v27 = &plr[v3].InvBody[4];
					v28 = p;
					qmemcpy(&plr[v3].HoldItem, v27, sizeof(plr[v3].HoldItem));
					v29 = plr[v3].HoldItem._iCurs + 12;
					if ( v28 == myplr )
						SetCursor(v29);
					else
						SetICursor(v29);
					v67 = 0;
					v30 = 0;
					do
					{
						if ( v67 )
							break;
						v31 = AutoPlace(p, v30++, icursW28, icursH28, 1);
						v67 = v31;
					}
					while ( v30 < 40 );
					v32 = p;
					qmemcpy(&plr[v3].HoldItem, &tempitem, sizeof(plr[v3].HoldItem));
					v33 = plr[v3].HoldItem._iCurs + 12;
					if ( v32 == myplr )
						SetCursor(v33);
					else
						SetICursor(v33);
					if ( !v67 )
						return;
					if ( plr[v3].InvBody[5]._itype == ITYPE_SHIELD )
						plr[v3].InvBody[5]._itype = ITYPE_NONE;
					else
						plr[v3].InvBody[4]._itype = ITYPE_NONE;
LABEL_146:
					if ( plr[v3].InvBody[4]._itype != ITYPE_NONE )
						goto LABEL_149;
LABEL_147:
					if ( plr[v3].InvBody[5]._itype == ITYPE_NONE )
					{
						NetSendCmdChItem(0, 4u);
						qmemcpy(&plr[v3].InvBody[4], &plr[v3].HoldItem, sizeof(plr[v3].InvBody[4]));
					}
					else
					{
LABEL_149:
						NetSendCmdChItem(0, 4u);
						if ( plr[v3].InvBody[4]._itype == ITYPE_NONE )
							SwapItem(&plr[v3].InvBody[4], &plr[v3].InvBody[5]);
						cursor_ida = SwapItem(&plr[v3].InvBody[4], &plr[v3].HoldItem);
					}
					if ( plr[v3].InvBody[4]._itype == ITYPE_STAFF )
					{
						v34 = plr[v3].InvBody[4]._iSpell;
						if ( v34 )
						{
							if ( plr[v3].InvBody[4]._iCharges > 0 )
							{
								plr[v3]._pRSpell = v34;
								_LOBYTE(plr[v3]._pRSplType) = 3;
								force_redraw = 255;
							}
						}
					}
					goto LABEL_226;
				case ILOC_ARMOR:
					NetSendCmdChItem(0, 6u);
					if ( plr[v3].InvBody[6]._itype == ITYPE_NONE )
					{
						v22 = &plr[v3].InvBody[6];
						goto LABEL_158;
					}
					v23 = &plr[v3].InvBody[6];
					goto LABEL_99;
				case ILOC_HELM:
					NetSendCmdChItem(0, 0);
					if ( plr[v3].InvBody[0]._itype == ITYPE_NONE )
					{
						v22 = plr[v3].InvBody;
						goto LABEL_158;
					}
					v23 = plr[v3].InvBody;
					goto LABEL_99;
				case ILOC_RING:
					if ( v10 == 4 )
					{
						NetSendCmdChItem(0, 1u);
						if ( plr[v3].InvBody[1]._itype == ITYPE_NONE )
						{
							v22 = &plr[v3].InvBody[1];
							goto LABEL_158;
						}
						v23 = &plr[v3].InvBody[1];
					}
					else
					{
						NetSendCmdChItem(0, 2u);
						if ( plr[v3].InvBody[2]._itype == ITYPE_NONE )
						{
							v22 = &plr[v3].InvBody[2];
							goto LABEL_158;
						}
						v23 = &plr[v3].InvBody[2];
					}
					goto LABEL_99;
				case ILOC_AMULET:
					NetSendCmdChItem(0, 3u);
					if ( plr[v3].InvBody[3]._itype == ITYPE_NONE )
					{
						v22 = &plr[v3].InvBody[3];
						goto LABEL_158;
					}
					v23 = &plr[v3].InvBody[3];
					goto LABEL_99;
				case ILOC_UNEQUIPABLE:
					v35 = plr[v3].HoldItem._itype;
					if ( v35 == 11 )
					{
						if ( !v66 )
						{
							v36 = &plr[0].InvGrid[10 * ((v68 - 25) / 10) + v3 * 21720 + (v68 - 25) % 10];
							if ( *v36 <= 0 )
							{
								v42 = 368 * plr[v3]._pNumInv + v3 * 21720;
								qmemcpy((char *)plr[0].InvList + v42, &plr[v3].HoldItem, 0x170u);
								++plr[v3]._pNumInv;
								*v36 = plr[v3]._pNumInv;
								v43 = plr[v3].HoldItem._ivalue;
								plr[v3]._pGold += v43;
								if ( v43 <= 5000 )
								{
									if ( v43 < 2500 )
									{
										if ( v43 > 1000 )
											*(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 5;
										else
											*(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 4;
									}
									else
									{
										*(int *)((char *)&plr[0].InvList[0]._iCurs + v42) = 6;
									}
								}
								goto LABEL_226;
							}
							v37 = plr[v3].HoldItem._ivalue;
							v38 = 368 * (*v36 - 1) + v3 * 21720;
							v39 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v38);
							v40 = v37 + v39;
							if ( v37 + v39 <= 5000 )
							{
								*(int *)((char *)&plr[0].InvList[0]._ivalue + v38) = v40;
								plr[v3]._pGold += plr[v3].HoldItem._ivalue;
								if ( v40 < 2500 )
								{
									if ( v40 > 1000 )
										*(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 5;
									else
										*(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 4;
								}
								else
								{
									*(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 6;
								}
								goto LABEL_226;
							}
							plr[v3]._pGold += 5000 - v39;
							plr[v3].HoldItem._ivalue = v37 - (5000 - v39);
							*(int *)((char *)&plr[0].InvList[0]._ivalue + v38) = 5000;
							*(int *)((char *)&plr[0].InvList[0]._iCurs + v38) = 6;
							v41 = plr[v3].HoldItem._ivalue;
							if ( v41 >= 2500 )
							{
								cursor_ida = 18;
								goto LABEL_226;
							}
							v24 = (v41 > 1000) + 16;
							goto LABEL_172;
						}
					}
					else if ( !v66 )
					{
						qmemcpy((char *)&plr[0].InvList[plr[v3]._pNumInv++] + v3 * 21720, &plr[v3].HoldItem, 0x170u);
						v66 = plr[v3]._pNumInv;
LABEL_191:
						v48 = v67;
						v49 = 10 * ((v68 - 25) / 10 - ((v67 - 1) >> 1));
						if ( v49 < 0 )
							v49 = 0;
						v65 = 0;
						if ( v67 > 0 )
						{
							v69 = (v68 - 25) % 10 - ((v64 - 1) >> 1);
							do
							{
								v50 = v69;
								if ( v69 < 0 )
									v50 = 0;
								v67 = 0;
								if ( v64 > 0 )
								{
									v51 = &plr[v3].InvGrid[v50 + v49];
									do
									{
										if ( v67 || v65 != v48 - 1 )
											v52 = -(char)v66;
										else
											v52 = v66;
										*v51++ = v52;
										++v67;
									}
									while ( v67 < v64 );
								}
								v49 += 10;
								++v65;
							}
							while ( v65 < v48 );
						}
						goto LABEL_226;
					}
					v44 = v66 - 1;
					if ( v35 == 11 )
						plr[v3]._pGold += plr[v3].HoldItem._ivalue;
					cursor_ida = SwapItem((ItemStruct *)((char *)&plr[0].InvList[v44] + v3 * 21720), &plr[v3].HoldItem);
					if ( plr[v3].HoldItem._itype == ITYPE_GOLD )
						plr[v3]._pGold = CalculateGold(v21);
					v45 = 0;
					v46 = -v66;
					do
					{
						v47 = &plr[v3].InvGrid[v45];
						if ( *v47 == v66 )
							*v47 = 0;
						if ( *v47 == v46 )
							*v47 = 0;
						++v45;
					}
					while ( v45 < 40 );
					goto LABEL_191;
				case ILOC_BELT:
					v53 = v3 * 21720 + 368 * (v68 - 65);
					if ( plr[v3].HoldItem._itype != ITYPE_GOLD )
					{
						if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v53) == ITYPE_NONE )
						{
							qmemcpy((char *)plr[0].SpdList + v53, &plr[v3].HoldItem, 0x170u);
						}
						else
						{
							cursor_ida = SwapItem((ItemStruct *)((char *)plr[0].SpdList + v53), &plr[v3].HoldItem);
							if ( plr[v3].HoldItem._itype == ITYPE_GOLD )
								plr[v3]._pGold = CalculateGold(p);
						}
						goto LABEL_225;
					}
					v54 = *(int *)((char *)&plr[0].SpdList[0]._itype + v53);
					if ( v54 != -1 )
					{
						if ( v54 == 11 )
						{
							v55 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v53);
							v56 = plr[v3].HoldItem._ivalue;
							v57 = v55 + v56;
							if ( v55 + v56 <= 5000 )
							{
								*(int *)((char *)&plr[0].SpdList[0]._ivalue + v53) = v57;
								plr[v3]._pGold += plr[v3].HoldItem._ivalue;
								if ( v57 < 2500 )
								{
									if ( v57 > 1000 )
										*(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 5;
									else
										*(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 4;
								}
								else
								{
									*(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 6;
								}
								goto LABEL_225;
							}
							plr[v3]._pGold += 5000 - v55;
							plr[v3].HoldItem._ivalue = v56 - (5000 - v55);
							*(int *)((char *)&plr[0].SpdList[0]._ivalue + v53) = 5000;
							*(int *)((char *)&plr[0].SpdList[0]._iCurs + v53) = 6;
							v58 = plr[v3].HoldItem._ivalue;
							if ( v58 >= 2500 )
							{
								cursor_ida = 18;
								goto LABEL_225;
							}
							v59 = (v58 > 1000) + 16;
						}
						else
						{
							plr[v3]._pGold += plr[v3].HoldItem._ivalue;
							v59 = SwapItem((ItemStruct *)((char *)plr[0].SpdList + v53), &plr[v3].HoldItem);
						}
						cursor_ida = v59;
						goto LABEL_225;
					}
					qmemcpy((char *)plr[0].SpdList + v53, &plr[v3].HoldItem, 0x170u);
					plr[v3]._pGold += plr[v3].HoldItem._ivalue;
LABEL_225:
					drawsbarflag = 1;
LABEL_226:
					v60 = p;
					CalcPlrInv(p, 1u);
					if ( v60 == myplr )
					{
						if ( cursor_ida == 1 )
							SetCursorPos(MouseX + (cursW >> 1), MouseY + (cursH >> 1));
						SetCursor(cursor_ida);
					}
					return;
				default:
					goto LABEL_226;
			}
		}
		v62 = (v68 - 25) % 10;
		v14 = 10 * (v13 - ((v67 - 1) >> 1));
		if ( v14 < 0 )
			v14 = 0;
		v65 = 0;
		if ( v67 <= 0 )
			goto LABEL_93;
		v15 = &plr[v3].InvGrid[v14];
		while ( 1 )
		{
			if ( cursor_id == CURSOR_NONE )
				return;
			if ( v14 >= 40 )
				cursor_id = 0;
			v16 = v62 - ((v64 - 1) >> 1);
			if ( v16 < 0 )
				v16 = 0;
			v17 = 0;
			if ( v64 > 0 )
				break;
LABEL_79:
			v14 += 10;
			v15 += 10;
			if ( ++v65 >= v67 )
			{
				v12 = cursor_id;
				v10 = v68;
				goto LABEL_81;
			}
		}
		while ( 1 )
		{
			if ( cursor_id == CURSOR_NONE )
				goto LABEL_79;
			if ( v16 >= 10 )
				goto LABEL_233;
			_LOBYTE(v18) = v15[v16];
			if ( (_BYTE)v18 )
			{
				v18 = (char)v18;
				if ( (v18 & 0x80u) != 0 )
					v18 = -v18;
				if ( !v66 )
				{
					v66 = v18;
					goto LABEL_78;
				}
				if ( v66 != v18 )
LABEL_233:
					cursor_id = 0;
			}
LABEL_78:
			++v16;
			if ( ++v17 >= v64 )
				goto LABEL_79;
		}
	}
	if ( v64 == 1 && v67 == 1 )
	{
		v12 = 1;
		if ( !AllItemsList[plr[v3].HoldItem.IDidx].iUsable )
			v12 = 0;
		if ( !plr[v3].HoldItem._iStatFlag )
			v12 = 0;
		if ( plr[v3].HoldItem._itype == ITYPE_GOLD )
		{
			v12 = 0;
			goto LABEL_50;
		}
	}
LABEL_81:
	if ( !v12 )
		return;
	if ( v69 == ILOC_UNEQUIPABLE || v69 == ILOC_BELT || plr[v3].HoldItem._iStatFlag )
		goto LABEL_92;
	v19 = plr[v3]._pClass;
	if ( !v19 )
	{
		v20 = PS_WARR13;
		goto LABEL_89;
	}
	if ( v19 != 1 )
	{
		if ( v19 != 2 )
			return;
		PlaySFX(PS_MAGE13);
		v12 = 0;
		v10 = v68;
LABEL_92:
		if ( !v12 )
			return;
		goto LABEL_93;
	}
	v20 = PS_ROGUE13;
LABEL_89:
	PlaySFX(v20);
}
// 4B8C9C: using guessed type int cursH;
// 4B8CB4: using guessed type int icursH;
// 4B8CBC: using guessed type int icursW;
// 52571C: using guessed type int force_redraw;

//----- (0041D2CF) --------------------------------------------------------
void __fastcall CheckInvSwap(int pnum, int bLoc, int idx, int wCI, int seed, int bId)
{
	unsigned char v6; // bl
	PlayerStruct *v7; // eax
	int p; // [esp+Ch] [ebp-4h]

	v6 = bLoc;
	p = pnum;
	TempItemGeneration(127, idx, wCI, seed, 0);
	v7 = &plr[p];
	qmemcpy(&v7->HoldItem, &items[127], sizeof(v7->HoldItem));
	if ( bId )
		v7->HoldItem._iIdentified = 1;
	if ( v6 < 7u )
	{
		qmemcpy(&v7->InvBody[v6], &v7->HoldItem, sizeof(v7->InvBody[v6]));
		if ( v6 == 4 )
		{
			if ( v7->HoldItem._iLoc == ILOC_TWOHAND )
				v7->InvBody[5]._itype = ITYPE_NONE;
		}
		else if ( v6 == 5 && v7->HoldItem._iLoc == ILOC_TWOHAND )
		{
			v7->InvBody[4]._itype = ITYPE_NONE;
		}
	}
	CalcPlrInv(p, 1u);
}

//----- (0041D378) --------------------------------------------------------
void __fastcall CheckInvCut(int pnum, int mx, int my)
{
	int v3; // ebp
	signed int v4; // ecx
	signed int v5; // ebx
	int v6; // eax
	int v7; // eax
	char v8; // al
	int v9; // edx
	signed int v10; // esi
	char *v11; // eax
	int v12; // ecx
	int v13; // edx
	int v14; // eax
	signed int v15; // esi
	char *v16; // eax
	int v17; // eax
	int v18; // eax
	signed int v19; // [esp+Ch] [ebp-Ch]
	int p; // [esp+10h] [ebp-8h]
	int v21; // [esp+14h] [ebp-4h]

	p = pnum;
	v3 = pnum;
	v21 = mx;
	if ( plr[pnum]._pmode > PM_WALK3 )
		return;
	v4 = 0;
	if ( dropGoldFlag )
	{
		dropGoldFlag = 0;
		dropGoldValue = 0;
	}
	v5 = 0;
	v19 = 0;
	while ( !v4 )
	{
		v6 = inv_screen_pos[v5].x;
		if ( mx >= v6 && mx < v6 + 29 )
		{
			v7 = inv_screen_pos[v5].y;
			if ( my >= v7 - 29 && my < v7 )
			{
				v4 = 1;
				--v5;
			}
		}
		v19 = ++v5;
		if ( (unsigned int)v5 >= 0x49 )
		{
			if ( !v4 )
				return;
			break;
		}
	}
	plr[v3].HoldItem._itype = ITYPE_NONE;
	if ( v5 >= 0 && v5 <= 3 && plr[v3].InvBody[0]._itype != ITYPE_NONE )
	{
		NetSendCmdDelItem(0, 0);
		qmemcpy(&plr[v3].HoldItem, plr[v3].InvBody, sizeof(plr[v3].HoldItem));
		plr[v3].InvBody[0]._itype = ITYPE_NONE;
	}
	if ( v5 == 4 )
	{
		if ( plr[v3].InvBody[1]._itype == ITYPE_NONE )
			goto LABEL_60;
		NetSendCmdDelItem(0, 1u);
		qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[1], sizeof(plr[v3].HoldItem));
		plr[v3].InvBody[1]._itype = ITYPE_NONE;
	}
	if ( v5 == 5 )
	{
		if ( plr[v3].InvBody[2]._itype == ITYPE_NONE )
			goto LABEL_60;
		NetSendCmdDelItem(0, 2u);
		qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[2], sizeof(plr[v3].HoldItem));
		plr[v3].InvBody[2]._itype = ITYPE_NONE;
	}
	if ( v5 != 6 )
		goto LABEL_26;
	if ( plr[v3].InvBody[3]._itype != ITYPE_NONE )
	{
		NetSendCmdDelItem(0, 3u);
		qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[3], sizeof(plr[v3].HoldItem));
		plr[v3].InvBody[3]._itype = ITYPE_NONE;
LABEL_26:
		if ( v5 >= 7 && v5 <= 12 && plr[v3].InvBody[4]._itype != ITYPE_NONE )
		{
			NetSendCmdDelItem(0, 4u);
			qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[4], sizeof(plr[v3].HoldItem));
			plr[v3].InvBody[4]._itype = ITYPE_NONE;
		}
		if ( v5 >= 13 && v5 <= 18 && plr[v3].InvBody[5]._itype != ITYPE_NONE )
		{
			NetSendCmdDelItem(0, 5u);
			qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[5], sizeof(plr[v3].HoldItem));
			plr[v3].InvBody[5]._itype = ITYPE_NONE;
		}
		if ( v5 >= 19 && v5 <= 24 && plr[v3].InvBody[6]._itype != ITYPE_NONE )
		{
			NetSendCmdDelItem(0, 6u);
			qmemcpy(&plr[v3].HoldItem, &plr[v3].InvBody[6], sizeof(plr[v3].HoldItem));
			plr[v3].InvBody[6]._itype = ITYPE_NONE;
		}
		if ( v5 >= 25 && v5 <= 64 )
		{
			v8 = *((_BYTE *)&plr[0].InvList[39]._iVAdd2 + v5 + v3 * 21720 + 3);
			if ( v8 )
			{
				v9 = v8;
				if ( v8 <= 0 )
					v9 = -v8;
				v10 = 0;
				do
				{
					v11 = &plr[0].InvGrid[v10 + v3 * 21720];
					v12 = *v11;
					if ( v12 == v9 || v12 == -v9 )
						*v11 = 0;
					++v10;
				}
				while ( v10 < 40 );
				v13 = v9 - 1;
				qmemcpy(&plr[v3].HoldItem, (char *)&plr[0].InvList[v13] + v3 * 21720, sizeof(plr[v3].HoldItem));
				v14 = --plr[v3]._pNumInv;
				if ( v14 > 0 && v14 != v13 )
				{
					qmemcpy(
						(char *)&plr[0].InvList[v13] + v3 * 21720,
						(char *)&plr[0].InvList[v14] + v3 * 21720,
						0x170u);
					v15 = 0;
					do
					{
						v16 = &plr[0].InvGrid[v15 + v3 * 21720];
						if ( *v16 == plr[v3]._pNumInv + 1 )
							*v16 = v13 + 1;
						if ( *v16 == -1 - plr[v3]._pNumInv )
							*v16 = -1 - v13;
						++v15;
					}
					while ( v15 < 40 );
				}
				v5 = v19;
			}
		}
		if ( v5 >= 65 )
		{
			v17 = v3 * 21720 + 368 * (v5 - 65);
			if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v17) != -1 )
			{
				qmemcpy(&plr[v3].HoldItem, (char *)plr[0].SpdList + v17, sizeof(plr[v3].HoldItem));
				*(int *)((char *)&plr[0].SpdList[0]._itype + v17) = -1;
				drawsbarflag = 1;
			}
		}
	}
LABEL_60:
	v18 = plr[v3].HoldItem._itype;
	if ( v18 != ITYPE_NONE )
	{
		if ( v18 == ITYPE_GOLD )
			plr[v3]._pGold = CalculateGold(p);
		CalcPlrInv(p, 1u);
		CheckItemStats(p);
		if ( p == myplr )
		{
			PlaySFX(IS_IGRAB);
			SetCursor(plr[v3].HoldItem._iCurs + 12);
			SetCursorPos(v21 - (cursW >> 1), MouseY - (cursH >> 1));
		}
	}
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8C9C: using guessed type int cursH;

//----- (0041D6EB) --------------------------------------------------------
void __fastcall inv_update_rem_item(int pnum, int iv)
{
	unsigned char v2; // dl

	if ( (unsigned char)iv < 7u )
		plr[pnum].InvBody[(unsigned char)iv]._itype = -1;
	v2 = 0;
	if ( plr[pnum]._pmode != PM_DEATH )
		v2 = 1;
	CalcPlrInv(pnum, v2);
}

//----- (0041D722) --------------------------------------------------------
void __fastcall RemoveInvItem(int pnum, int iv)
{
	int v2; // edx
	signed int v3; // ecx
	int v4; // ebx
	char *v5; // eax
	int v6; // esi
	int v7; // edx
	int v8; // eax
	signed int v9; // edi
	char *v10; // esi
	int v11; // eax
	int p; // [esp+Ch] [ebp-4h]

	p = pnum;
	v2 = iv + 1;
	v3 = 0;
	v4 = p;
	do
	{
		v5 = &plr[v4].InvGrid[v3];
		v6 = *v5;
		if ( v6 == v2 || v6 == -v2 )
			*v5 = 0;
		++v3;
	}
	while ( v3 < 40 );
	v7 = v2 - 1;
	v8 = --plr[v4]._pNumInv;
	if ( v8 > 0 && v8 != v7 )
	{
		qmemcpy((char *)&plr[0].InvList[v7] + v4 * 21720, (char *)&plr[0].InvList[v8] + v4 * 21720, 0x170u);
		v9 = 0;
		do
		{
			v10 = &plr[v4].InvGrid[v9];
			if ( *v10 == plr[v4]._pNumInv + 1 )
				*v10 = v7 + 1;
			if ( *v10 == -1 - plr[v4]._pNumInv )
				*v10 = -1 - v7;
			++v9;
		}
		while ( v9 < 40 );
	}
	CalcPlrScrolls(p);
	if ( _LOBYTE(plr[v4]._pRSplType) == 2 )
	{
		v11 = plr[v4]._pRSpell;
		if ( v11 != -1 )
		{
			if ( !(plr[v4]._pScrlSpells[1] & (1 << (v11 - 1) >> 31) | plr[v4]._pScrlSpells[0] & (1 << (v11 - 1))) )
				plr[v4]._pRSpell = -1;
			force_redraw = 255;
		}
	}
}
// 52571C: using guessed type int force_redraw;

//----- (0041D810) --------------------------------------------------------
void __fastcall RemoveSpdBarItem(int pnum, int iv)
{
	int v2; // esi
	int v3; // eax

	v2 = pnum;
	plr[pnum].SpdList[iv]._itype = -1;
	CalcPlrScrolls(pnum);
	if ( _LOBYTE(plr[v2]._pRSplType) == 2 )
	{
		v3 = plr[v2]._pRSpell;
		if ( v3 != -1 && !(plr[v2]._pScrlSpells[1] & (1 << (v3 - 1) >> 31) | plr[v2]._pScrlSpells[0] & (1 << (v3 - 1))) )
			plr[v2]._pRSpell = -1;
	}
	force_redraw = 255;
}
// 52571C: using guessed type int force_redraw;

//----- (0041D86C) --------------------------------------------------------
void __cdecl CheckInvItem()
{
	if ( pcurs < CURSOR_FIRSTITEM )
		CheckInvCut(myplr, MouseX, MouseY);
	else
		CheckInvPaste(myplr, MouseX, MouseY);
}

//----- (0041D893) --------------------------------------------------------
void __cdecl CheckInvScrn()
{
	if ( MouseX > 190 && MouseX < 437 && MouseY > 352 && MouseY < 385 )
		CheckInvItem();
}

//----- (0041D8BF) --------------------------------------------------------
void __fastcall CheckItemStats(int pnum)
{
	PlayerStruct *v1; // eax
	int v2; // ecx

	v1 = &plr[pnum];
	v2 = v1->HoldItem._iMinStr;
	v1->HoldItem._iStatFlag = 0;
	if ( v1->_pStrength >= v2
	  && v1->_pMagic >= (unsigned char)v1->HoldItem._iMinMag
	  && v1->_pDexterity >= v1->HoldItem._iMinDex )
	{
		v1->HoldItem._iStatFlag = 1;
	}
}

//----- (0041D90B) --------------------------------------------------------
void __fastcall CheckBookLevel(int pnum)
{
	int v1; // ecx
	int v2; // eax
	unsigned char v3; // bl
	int v4; // edi

	v1 = pnum;
	if ( plr[v1].HoldItem._iMiscId == IMISC_BOOK )
	{
		v2 = plr[v1].HoldItem._iSpell;
		v3 = spelldata[plr[v1].HoldItem._iSpell].sMinInt;
		plr[v1].HoldItem._iMinMag = v3;
		v4 = plr[0]._pSplLvl[v2 + v1 * 21720];
		if ( plr[0]._pSplLvl[v2 + v1 * 21720] )
		{
			do
			{
				v3 += 20 * v3 / 100;
				--v4;
				if ( v3 + 20 * v3 / 100 > 255 )
				{
					v3 = -1;
					v4 = 0;
				}
			}
			while ( v4 );
			plr[v1].HoldItem._iMinMag = v3;
		}
	}
}

//----- (0041D97F) --------------------------------------------------------
void __fastcall CheckQuestItem(int pnum)
{
	int v1; // ecx
	int v2; // esi
	char v3; // cl
	char v4; // cl
	char v5; // cl
	char v6; // cl
	char v7; // al

	v1 = pnum;
	v2 = plr[v1].HoldItem.IDidx;
	if ( v2 == IDI_OPTAMULET )
		quests[8]._qactive = 3;
	if ( v2 == IDI_MUSHROOM && quests[1]._qactive == 2 && quests[1]._qvar1 == 3 )
	{
		v3 = plr[v1]._pClass;
		sfxdelay = IDI_OPTAMULET;
		if ( v3 )
		{
			if ( v3 == 1 )
			{
				sfxdnum = PS_ROGUE95;
			}
			else if ( v3 == 2 )
			{
				sfxdnum = PS_MAGE95;
			}
		}
		else
		{
			sfxdnum = PS_WARR95;
		}
		quests[1]._qvar1 = 4;
	}
	if ( v2 == IDI_ANVIL )
	{
		if ( quests[10]._qactive == 1 )
		{
			quests[10]._qactive = 2;
			quests[10]._qvar1 = 1;
		}
		if ( quests[10]._qlog == 1 )
		{
			sfxdelay = IDI_OPTAMULET;
			v4 = plr[myplr]._pClass;
			if ( v4 )
			{
				if ( v4 == 1 )
				{
					sfxdnum = PS_ROGUE89;
				}
				else if ( v4 == 2 )
				{
					sfxdnum = PS_MAGE89;
				}
			}
			else
			{
				sfxdnum = PS_WARR89;
			}
		}
	}
	if ( v2 == IDI_GLDNELIX )
	{
		sfxdelay = 30;
		v5 = plr[myplr]._pClass;
		if ( v5 )
		{
			if ( v5 == 1 )
			{
				sfxdnum = PS_ROGUE88;
			}
			else if ( v5 == 2 )
			{
				sfxdnum = PS_MAGE88;
			}
		}
		else
		{
			sfxdnum = PS_WARR88;
		}
	}
	if ( v2 == IDI_ROCK )
	{
		if ( quests[0]._qactive == 1 )
		{
			quests[0]._qactive = 2;
			quests[0]._qvar1 = 1;
		}
		if ( quests[0]._qlog == 1 )
		{
			sfxdelay = IDI_OPTAMULET;
			v6 = plr[myplr]._pClass;
			if ( v6 )
			{
				if ( v6 == 1 )
				{
					sfxdnum = PS_ROGUE87;
				}
				else if ( v6 == 2 )
				{
					sfxdnum = PS_MAGE87;
				}
			}
			else
			{
				sfxdnum = PS_WARR87;
			}
		}
	}
	if ( v2 == IDI_ARMOFVAL )
	{
		quests[9]._qactive = 3;
		sfxdelay = 20;
		v7 = plr[myplr]._pClass;
		if ( v7 )
		{
			if ( v7 == 1 )
			{
				sfxdnum = PS_ROGUE91;
			}
			else if ( v7 == 2 )
			{
				sfxdnum = PS_MAGE91;
			}
		}
		else
		{
			sfxdnum = PS_WARR91;
		}
	}
}
// 52A554: using guessed type int sfxdelay;

//----- (0041DB65) --------------------------------------------------------
void __fastcall InvGetItem(int pnum, int ii)
{
	int v2; // ebp
	int v3; // edx
	int v4; // ecx
	int v5; // ecx
	int pnuma; // [esp+4h] [ebp-8h]
	int v7; // [esp+8h] [ebp-4h]

	v7 = ii;
	pnuma = pnum;
	if ( dropGoldFlag )
	{
		dropGoldFlag = 0;
		dropGoldValue = 0;
	}
	v2 = ii;
	if ( dItem[items[ii]._ix][items[ii]._iy] )
	{
		if ( myplr == pnum && pcurs >= CURSOR_FIRSTITEM )
			NetSendCmdPItem(1u, CMD_SYNCPUTITEM, plr[myplr].WorldX, plr[myplr].WorldY);
		_HIBYTE(items[v2]._iCreateInfo) &= 0x7Fu;
		qmemcpy(&plr[pnuma].HoldItem, &items[v2], sizeof(plr[pnuma].HoldItem));
		CheckQuestItem(pnuma);
		CheckBookLevel(pnuma);
		CheckItemStats(pnuma);
		v3 = 0;
		dItem[items[v2]._ix][items[v2]._iy] = 0;
		while ( v3 < numitems )
		{
			v4 = itemactive[v3];
			if ( v4 == v7 )
			{
				DeleteItem(v4, v3);
				v3 = 0;
			}
			else
			{
				++v3;
			}
		}
		v5 = plr[pnuma].HoldItem._iCurs;
		pcursitem = -1;
		SetCursor(v5 + 12);
	}
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8CC0: using guessed type char pcursitem;

//----- (0041DC79) --------------------------------------------------------
void __fastcall AutoGetItem(int pnum, int ii)
{
	int v2; // ebx
	int v3; // ebp
	int v4; // eax
	int v5; // ecx
	int v6; // edi
	int v7; // edi
	int v8; // edi
	int v9; // edi
	int v10; // edx
	int v11; // ecx
	char v12; // al
	int v13; // ecx
	int iia; // [esp+10h] [ebp-18h]
	signed int iib; // [esp+10h] [ebp-18h]
	signed int iic; // [esp+10h] [ebp-18h]
	signed int iid; // [esp+10h] [ebp-18h]
	signed int iie; // [esp+10h] [ebp-18h]
	signed int iif; // [esp+10h] [ebp-18h]
	signed int iig; // [esp+10h] [ebp-18h]
	signed int iih; // [esp+10h] [ebp-18h]
	signed int iii; // [esp+10h] [ebp-18h]
	signed int iij; // [esp+10h] [ebp-18h]
	ItemStruct *v24; // [esp+14h] [ebp-14h]
	int *v25; // [esp+14h] [ebp-14h]
	int v26; // [esp+18h] [ebp-10h]
	int i; // [esp+1Ch] [ebp-Ch]
	int v28; // [esp+20h] [ebp-8h]
	int v29; // [esp+24h] [ebp-4h]

	v2 = pnum;
	i = ii;
	if ( dropGoldFlag )
	{
		dropGoldFlag = 0;
		dropGoldValue = 0;
	}
	if ( ii == 127 || dItem[items[ii]._ix][items[ii]._iy] )
	{
		v3 = pnum;
		_HIBYTE(items[ii]._iCreateInfo) &= 0x7Fu;
		v28 = ii;
		qmemcpy(&plr[pnum].HoldItem, &items[ii], sizeof(plr[pnum].HoldItem));
		CheckQuestItem(pnum);
		CheckBookLevel(v2);
		CheckItemStats(v2);
		SetICursor(plr[v2].HoldItem._iCurs + 12);
		if ( plr[v2].HoldItem._itype == ITYPE_GOLD )
		{
			v4 = GoldAutoPlace(v2);
		}
		else
		{
			v4 = 0;
			if ( (!(plr[v3]._pgfxnum & 0xF) || (plr[v3]._pgfxnum & 0xF) == 1) && plr[v3]._pmode <= PM_WALK3 )
			{
				if ( plr[v3].HoldItem._iStatFlag )
				{
					if ( plr[v3].HoldItem._iClass == 1 )
					{
						v4 = WeaponAutoPlace(v2);
						if ( v4 )
						{
							CalcPlrInv(v2, 1u);
							goto LABEL_71;
						}
					}
				}
			}
			v5 = icursW28;
			v29 = icursW28;
			v26 = icursH28;
			if ( icursW28 == 1 )
			{
				if ( icursH28 == 1 )
				{
					if ( plr[v3].HoldItem._iStatFlag && AllItemsList[plr[v3].HoldItem.IDidx].iUsable )
					{
						iia = 0;
						v24 = plr[v3].SpdList;
						do
						{
							if ( v4 )
								break;
							if ( v24->_itype == -1 )
							{
								qmemcpy(v24, &plr[v3].HoldItem, sizeof(ItemStruct));
								CalcPlrScrolls(v2);
								v4 = 1;
								drawsbarflag = 1;
							}
							++iia;
							++v24;
						}
						while ( iia < 8 );
					}
					v6 = 30;
					do
					{
						if ( v4 )
							break;
						v4 = AutoPlace(v2, v6++, 1, 1, 1);
					}
					while ( v6 <= 39 );
					v7 = 20;
					do
					{
						if ( v4 )
							break;
						v4 = AutoPlace(v2, v7++, 1, 1, 1);
					}
					while ( v7 <= 29 );
					v8 = 10;
					do
					{
						if ( v4 )
							break;
						v4 = AutoPlace(v2, v8++, 1, 1, 1);
					}
					while ( v8 <= 19 );
					v9 = 0;
					while ( !v4 )
					{
						v4 = AutoPlace(v2, v9++, 1, 1, 1);
						if ( v9 > 9 )
							goto LABEL_35;
					}
					goto LABEL_71;
				}
LABEL_35:
				if ( v26 == 2 )
				{
					iib = 29;
					do
					{
						if ( v4 )
							break;
						v4 = AutoPlace(v2, iib--, 1, 2, 1);
					}
					while ( iib >= 20 );
					iic = 9;
					do
					{
						if ( v4 )
							break;
						v4 = AutoPlace(v2, iic--, 1, 2, 1);
					}
					while ( iic >= 0 );
					iid = 19;
					while ( !v4 )
					{
						v4 = AutoPlace(v2, iid--, 1, 2, 1);
						if ( iid < 10 )
							goto LABEL_45;
					}
					goto LABEL_71;
				}
LABEL_45:
				if ( v26 == 3 )
				{
					iie = 0;
					while ( !v4 )
					{
						v4 = AutoPlace(v2, iie++, 1, 3, 1);
						if ( iie >= 20 )
							goto LABEL_49;
					}
					goto LABEL_71;
				}
			}
			else
			{
LABEL_49:
				if ( v29 == 2 )
				{
					if ( v26 == 2 )
					{
						v25 = AP2x2Tbl;
						do
						{
							if ( v4 )
								break;
							v4 = AutoPlace(v2, *v25, 2, 2, 1);
							++v25;
						}
						while ( (signed int)v25 < (signed int)"Data\\Inv\\Inv_Sor.CEL" );
						iif = 21;
						do
						{
							if ( v4 )
								break;
							v4 = AutoPlace(v2, iif, 2, 2, 1);
							iif += 2;
						}
						while ( iif < 29 );
						iig = 1;
						do
						{
							if ( v4 )
								break;
							v4 = AutoPlace(v2, iig, 2, 2, 1);
							iig += 2;
						}
						while ( iig < 9 );
						iih = 10;
						while ( !v4 )
						{
							v4 = AutoPlace(v2, iih++, 2, 2, 1);
							if ( iih >= 19 )
								goto LABEL_63;
						}
						goto LABEL_71;
					}
LABEL_63:
					if ( v26 == 3 )
					{
						iii = 0;
						do
						{
							if ( v4 )
								break;
							v4 = AutoPlace(v2, iii++, 2, 3, 1);
						}
						while ( iii < 9 );
						iij = 10;
						while ( !v4 )
						{
							v4 = AutoPlace(v2, iij++, 2, 3, 1);
							if ( iij >= 19 )
								goto LABEL_70;
						}
						goto LABEL_71;
					}
				}
			}
		}
LABEL_70:
		if ( v4 )
		{
LABEL_71:
			v10 = 0;
			dItem[items[v28]._ix][items[v28]._iy] = 0;
			while ( v10 < numitems )
			{
				v11 = itemactive[v10];
				if ( v11 == i )
				{
					DeleteItem(v11, v10);
					v10 = 0;
				}
				else
				{
					++v10;
				}
			}
			return;
		}
		if ( v2 == myplr )
		{
			v12 = plr[v3]._pClass;
			switch ( v12 )
			{
				case UI_WARRIOR:
					_LOBYTE(v5) = 0;
					v13 = random(v5, 3) + PS_WARR14;
LABEL_84:
					PlaySFX(v13);
					break;
				case UI_ROGUE:
					_LOBYTE(v5) = 0;
					v13 = random(v5, 3) + PS_ROGUE14;
					goto LABEL_84;
				case UI_SORCERER:
					_LOBYTE(v5) = 0;
					v13 = random(v5, 3) + PS_MAGE14;
					goto LABEL_84;
			}
		}
		qmemcpy(&plr[v3].HoldItem, &items[v28], sizeof(plr[v3].HoldItem));
		RespawnItem(i, 1u);
		NetSendCmdPItem(1u, CMD_RESPAWNITEM, items[v28]._ix, items[v28]._iy);
		plr[v3].HoldItem._itype = ITYPE_NONE;
	}
}
// 48E9A8: using guessed type int AP2x2Tbl[10];
// 4B84DC: using guessed type int dropGoldFlag;

//----- (0041E103) --------------------------------------------------------
void __fastcall FindGetItem(int indx, int ci, int iseed)
{
	int i; // ebx
	int v4; // esi

	for ( i = 0; i < numitems; ++i )
	{
		v4 = itemactive[i];
		if ( items[v4].IDidx == indx && items[v4]._iSeed == iseed && items[v4]._iCreateInfo == (_WORD)ci )
			break;
	}
}

//----- (0041E158) --------------------------------------------------------
void __fastcall SyncGetItem(int x, int y, int idx, unsigned short ci, int iseed)
{
	char v5; // cl
	int v6; // esi
	int v7; // eax
	int v8; // eax
	int v9; // edx
	int v10; // ecx
	int v11; // ecx

	v5 = dItem[x][y];
	if ( v5
	  && (v6 = v5 - 1, v7 = v6, items[v7].IDidx == idx)
	  && items[v7]._iSeed == iseed
	  && items[v7]._iCreateInfo == ci )
	{
		FindGetItem(idx, ci, iseed);
	}
	else
	{
		FindGetItem(idx, ci, iseed);
		v6 = v8;
	}
	if ( v6 != -1 )
	{
		v9 = 0;
		dItem[items[v6]._ix][items[v6]._iy] = 0;
		while ( v9 < numitems )
		{
			v10 = itemactive[v9];
			if ( v10 == v6 )
			{
				DeleteItem(v10, v9);
				FindGetItem(idx, ci, iseed);
				FindGetItem(v11, ci, iseed);
				v9 = 0;
			}
			else
			{
				++v9;
			}
		}
		FindGetItem(idx, ci, iseed);
	}
}

//----- (0041E222) --------------------------------------------------------
int __fastcall CanPut(int i, int j)
{
	int v2; // ecx
	int v3; // esi
	char v4; // al
	int v5; // eax
	char v6; // al
	bool v7; // sf
	char v8; // al
	char v9; // cl

	v2 = i;
	if ( dItem[v2][j] )
		return 0;
	v3 = v2 * 112 + j;
	if ( nSolidTable[dPiece[0][v3]] )
		return 0;
	v4 = dObject[v2][j];
	if ( v4 )
	{
		v5 = v4 <= 0 ? -1 - v4 : v4 - 1;
		if ( object[v5]._oSolidFlag )
			return 0;
	}
	v6 = dObject[v2 + 1][j + 1];
	v7 = v6 < 0;
	if ( v6 > 0 )
	{
		if ( _LOBYTE(objectavail[30 * v6 + 113]) )
			return 0;
		v7 = v6 < 0;
	}
	if ( v7 && _LOBYTE(object[-(v6 + 1)]._oSelFlag) )
		return 0;
	v8 = dObject[v2 + 1][j];
	if ( v8 > 0 )
	{
		v9 = dObject[v2][j + 1];
		if ( v9 > 0 && _LOBYTE(objectavail[30 * v8 + 113]) && _LOBYTE(objectavail[30 * v9 + 113]) )
			return 0;
	}
	if ( !currlevel && (dMonster[0][v3] || dMonster[1][v3 + 1]) )
		return 0;
	return 1;
}

//----- (0041E2F9) --------------------------------------------------------
int __cdecl TryInvPut()
{
	int result; // eax
	int v1; // eax
	char v2; // si
	int v3; // edi
	int v4; // ebx
	int v5; // esi

	if ( numitems >= 127 )
		return 0;
	v1 = GetDirection(plr[myplr].WorldX, plr[myplr].WorldY, cursmx, cursmy);
	v2 = v1;
	v3 = plr[myplr].WorldY;
	v4 = plr[myplr].WorldX;
	if ( CanPut(v4 + offset_x[v1], v3 + offset_y[v1])
	  || (v5 = (v2 - 1) & 7, CanPut(v4 + offset_x[v5], v3 + offset_y[v5]))
	  || CanPut(v4 + offset_x[((_BYTE)v5 + 2) & 7], v3 + offset_y[((_BYTE)v5 + 2) & 7]) )
	{
		result = 1;
	}
	else
	{
		result = CanPut(v4, v3);
	}
	return result;
}

//----- (0041E3BC) --------------------------------------------------------
void __fastcall DupeInvMsg(char *msg)
{
	char *v1; // esi
	int v2; // eax

	v1 = msg;
	v2 = GetTickCount();
	if ( (unsigned int)(v2 - dupe_delay) >= 0x1388 )
	{
		dupe_delay = v2;
		ErrorPlrMsg(v1);
	}
}

//----- (0041E3E4) --------------------------------------------------------
int __fastcall InvPutItem(int pnum, int x, int y)
{
	int v3; // edi
	int *v4; // esi
	int v5; // ebx
	int v6; // eax
	int v7; // esi
	int v8; // eax
	int v9; // edi
	int v10; // esi
	int v11; // esi
	int v12; // eax
	int v13; // edx
	int v14; // esi
	int v16; // eax
	int *v17; // edx
	int v18; // edx
	ItemStruct *v19; // [esp+Ch] [ebp-1Ch]
	int v20; // [esp+10h] [ebp-18h]
	signed int v21; // [esp+14h] [ebp-14h]
	int v22; // [esp+18h] [ebp-10h]
	int v23; // [esp+1Ch] [ebp-Ch]
	signed int v24; // [esp+20h] [ebp-8h]
	int xa; // [esp+24h] [ebp-4h]
	int ya; // [esp+30h] [ebp+8h]
	int yb; // [esp+30h] [ebp+8h]
	int yc; // [esp+30h] [ebp+8h]

	xa = x;
	if ( numitems >= 127 )
		return -1;
	v3 = pnum;
	_LOWORD(x) = plr[pnum].HoldItem._iCreateInfo;
	v4 = &plr[pnum].HoldItem._iSeed;
	v19 = &plr[pnum].HoldItem;
	FindGetItem(plr[pnum].HoldItem.IDidx, x, plr[pnum].HoldItem._iSeed);
	v5 = y;
	if ( v6 != -1 )
	{
		DupeInvMsg("A duplicate item has been detected.  Destroying duplicate...");
		SyncGetItem(xa, y, plr[v3].HoldItem.IDidx, plr[v3].HoldItem._iCreateInfo, *v4);
	}
	ya = GetDirection(plr[v3].WorldX, plr[v3].WorldY, xa, y);
	v7 = v5 - plr[v3].WorldY;
	if ( abs(xa - plr[v3].WorldX) > 1 || abs(v7) > 1 )
	{
		v5 = plr[v3].WorldY + offset_y[ya];
		xa = plr[v3].WorldX + offset_x[ya];
	}
	if ( !CanPut(xa, v5) )
	{
		v8 = plr[v3].WorldX;
		v9 = plr[v3].WorldY;
		v10 = ((_BYTE)ya - 1) & 7;
		v20 = v8;
		v5 = v9 + offset_y[v10];
		xa = v8 + offset_x[v10];
		if ( !CanPut(xa, v9 + offset_y[v10]) )
		{
			v11 = ((_BYTE)v10 + 2) & 7;
			v5 = v9 + offset_y[v11];
			xa = v20 + offset_x[v11];
			if ( !CanPut(xa, v9 + offset_y[v11]) )
			{
				v24 = 0;
				v12 = -1;
				yb = 1;
				v21 = -1;
				while ( !v24 )
				{
					v23 = v12;
					while ( v12 <= yb && !v24 )
					{
						v22 = v21;
						v13 = v9 + v23;
						v14 = v20 + v21;
						do
						{
							if ( v24 )
								break;
							if ( CanPut(v14, v13) )
							{
								v24 = 1;
								xa = v14;
								v5 = v13;
							}
							++v22;
							++v14;
						}
						while ( v22 <= yb );
						v12 = ++v23;
					}
					++yb;
					v12 = v21-- - 1;
					if ( v21 <= -50 )
					{
						if ( v24 )
							break;
						return -1;
					}
				}
			}
		}
	}
	CanPut(xa, v5);
	v16 = itemavail[0];
	dItem[xa][v5] = _LOBYTE(itemavail[0]) + 1;
	yc = v16;
	v17 = &itemavail[-numitems + 126];
	itemactive[numitems] = v16;
	itemavail[0] = *v17;
	v18 = v16;
	qmemcpy(&items[v16], v19, sizeof(ItemStruct));
	items[v18]._iy = v5;
	items[v18]._ix = xa;
	RespawnItem(v16, 1u);
	++numitems;
	SetCursor(1);
	return yc;
}

//----- (0041E639) --------------------------------------------------------
int __fastcall SyncPutItem(int pnum, int x, int y, int idx, int icreateinfo, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, unsigned __int32 ibuff)
{
	int v13; // ebx
	int v14; // edi
	int v15; // esi
	int v16; // eax
	int v17; // edi
	int v18; // ecx
	int v19; // edi
	int v20; // eax
	int v21; // eax
	int v22; // eax
	int v23; // edx
	int v25; // ecx
	int *v26; // edx
	int v27; // eax
	int v28; // eax
	int v29; // [esp+Ch] [ebp-18h]
	int v30; // [esp+Ch] [ebp-18h]
	signed int v31; // [esp+10h] [ebp-14h]
	int v32; // [esp+14h] [ebp-10h]
	int v33; // [esp+18h] [ebp-Ch]
	int o1; // [esp+1Ch] [ebp-8h]
	signed int v35; // [esp+20h] [ebp-4h]
	int i; // [esp+2Ch] [ebp+8h]
	int ia; // [esp+2Ch] [ebp+8h]
	int ib; // [esp+2Ch] [ebp+8h]
	int ic; // [esp+2Ch] [ebp+8h]

	v13 = x;
	v14 = pnum;
	if ( numitems >= 127 )
		return -1;
	FindGetItem(idx, icreateinfo, iseed);
	v15 = y;
	if ( v16 != -1 )
	{
		DupeInvMsg("A duplicate item has been detected from another player.");
		SyncGetItem(v13, y, idx, icreateinfo, iseed);
	}
	v17 = v14;
	i = GetDirection(plr[v17].WorldX, plr[v17].WorldY, v13, y);
	v29 = v15 - plr[v17].WorldY;
	if ( abs(v13 - plr[v17].WorldX) > 1 || abs(v29) > 1 )
	{
		v13 = plr[v17].WorldX + offset_x[i];
		v15 = plr[v17].WorldY + offset_y[i];
	}
	if ( !CanPut(v13, v15) )
	{
		v18 = plr[v17].WorldX;
		v19 = plr[v17].WorldY;
		v20 = ((_BYTE)i - 1) & 7;
		v30 = v18;
		ia = v20;
		v20 *= 4;
		v13 = v18 + *(int *)((char *)offset_x + v20);
		v15 = v19 + *(int *)((char *)offset_y + v20);
		if ( !CanPut(v18 + *(int *)((char *)offset_x + v20), v19 + *(int *)((char *)offset_y + v20)) )
		{
			v21 = ((_BYTE)ia + 2) & 7;
			v13 = v30 + offset_x[v21];
			v15 = v19 + offset_y[v21];
			if ( !CanPut(v30 + offset_x[v21], v19 + offset_y[v21]) )
			{
				v35 = 0;
				v22 = -1;
				ib = 1;
				v31 = -1;
				while ( !v35 )
				{
					v33 = v22;
					while ( v22 <= ib && !v35 )
					{
						v23 = v19 + v33;
						v32 = v31;
						o1 = v30 + v31;
						do
						{
							if ( v35 )
								break;
							if ( CanPut(o1, v23) )
							{
								v13 = o1;
								v35 = 1;
								v15 = v23;
							}
							++v32;
							++o1;
						}
						while ( v32 <= ib );
						v22 = ++v33;
					}
					++ib;
					v22 = v31-- - 1;
					if ( v31 <= -50 )
					{
						if ( v35 )
							break;
						return -1;
					}
				}
			}
		}
	}
	CanPut(v13, v15);
	v25 = itemavail[0];
	ic = itemavail[0];
	dItem[v13][v15] = _LOBYTE(itemavail[0]) + 1;
	v26 = &itemavail[-numitems + 126];
	itemactive[numitems] = v25;
	itemavail[0] = *v26;
	if ( idx == 23 )
	{
		RecreateEar(v25, icreateinfo, iseed, Id, dur, mdur, ch, mch, ivalue, ibuff);
	}
	else
	{
		TempItemGeneration(v25, idx, icreateinfo, iseed, ivalue);
		if ( Id )
			items[ic]._iIdentified = 1;
		v27 = ic;
		items[v27]._iDurability = dur;
		items[v27]._iMaxDur = mdur;
		items[v27]._iCharges = ch;
		items[v27]._iMaxCharges = mch;
	}
	v28 = ic;
	items[v28]._ix = v13;
	items[v28]._iy = v15;
	RespawnItem(ic, 1u);
	++numitems;
	return ic;
}

//----- (0041E8DD) --------------------------------------------------------
int __cdecl CheckInvHLight()
{
	signed int v0; // ebx
	int result; // eax
	ItemStruct *v2; // edi
	PlayerStruct *v3; // esi
	int v4; // eax
	int v5; // ebx
	int v6; // edi
	char *v7; // eax
	char v8; // al
	char v9; // [esp+Fh] [ebp-1h]

	v0 = 0;
	do
	{
		result = inv_screen_pos[v0].x;
		if ( MouseX >= result )
		{
			result += 29;
			if ( MouseX < result )
			{
				result = inv_screen_pos[v0].y;
				if ( MouseY >= result - 29 && MouseY < result )
					break;
			}
		}
		++v0;
	}
	while ( (unsigned int)v0 < 0x49 );
	if ( (unsigned int)v0 >= 0x49 )
		goto LABEL_37;
	v9 = -1;
	_LOBYTE(infoclr) = 0;
	v2 = 0;
	v3 = &plr[myplr];
	ClearPanel();
	if ( v0 >= 0 && v0 <= 3 )
	{
		v9 = 0;
		v2 = v3->InvBody;
		goto LABEL_36;
	}
	switch ( v0 )
	{
		case 4:
			v9 = 1;
			v2 = &v3->InvBody[1];
			goto LABEL_36;
		case 5:
			v9 = 2;
			v2 = &v3->InvBody[2];
			goto LABEL_36;
		case 6:
			v9 = 3;
			v2 = &v3->InvBody[3];
			goto LABEL_36;
	}
	if ( v0 >= 7 && v0 <= 12 )
	{
		v9 = 4;
		v2 = &v3->InvBody[4];
		goto LABEL_36;
	}
	if ( v0 < 13 || v0 > 18 )
	{
		if ( v0 >= 19 && v0 <= 24 )
		{
			v9 = 6;
			v2 = &v3->InvBody[6];
			goto LABEL_36;
		}
		if ( v0 < 25 || v0 > 64 )
		{
			if ( v0 < 65 )
				goto LABEL_36;
			v5 = v0 - 65;
			drawsbarflag = 1;
			result = 368 * v5;
			v2 = &v3->SpdList[v5];
			if ( v3->SpdList[v5]._itype != -1 )
			{
				v9 = v5 + 47;
				goto LABEL_36;
			}
		}
		else
		{
			result = abs(*((char *)&v3->InvList[39]._iVAdd2 + v0 + 3));
			if ( result )
			{
				v4 = result - 1;
				v9 = v4 + 7;
				v2 = &v3->InvList[v4];
				goto LABEL_36;
			}
		}
LABEL_37:
		_LOBYTE(result) = -1;
		return result;
	}
	v2 = &v3->InvBody[4];
	if ( v3->InvBody[4]._itype == -1 || v3->InvBody[4]._iLoc != 2 )
	{
		v9 = 5;
		v2 = &v3->InvBody[5];
	}
	else
	{
		v9 = 4;
	}
LABEL_36:
	result = v2->_itype;
	if ( result == ITYPE_NONE )
		goto LABEL_37;
	if ( result == ITYPE_GOLD )
	{
		v6 = v2->_ivalue;
		v7 = get_pieces_str(v6);
		result = sprintf(infostr, "%i gold %s", v6, v7);
	}
	else
	{
		v8 = v2->_iMagical;
		if ( v8 == 1 )
		{
			_LOBYTE(infoclr) = 1;
		}
		else if ( v8 == 2 )
		{
			_LOBYTE(infoclr) = 3;
		}
		strcpy(infostr, v2->_iName);
		if ( v2->_iIdentified )
		{
			strcpy(infostr, v2->_iIName);
			PrintItemDetails(v2);
		}
		else
		{
			PrintItemDur(v2);
		}
	}
	_LOBYTE(result) = v9;
	return result;
}
// 4B883C: using guessed type int infoclr;

//----- (0041EAEA) --------------------------------------------------------
void __fastcall RemoveScroll(int pnum)
{
	int v1; // eax
	int v2; // esi
	int v3; // edx
	int *v4; // ecx
	int v5; // edx
	int *v6; // ecx
	int p; // [esp+Ch] [ebp-4h]

	p = pnum;
	v1 = pnum;
	v2 = plr[pnum]._pNumInv;
	v3 = 0;
	if ( v2 <= 0 )
	{
LABEL_8:
		v5 = 0;
		v6 = &plr[v1].SpdList[0]._iMiscId;
		while ( *(v6 - 53) == -1 || *v6 != IMISC_SCROLL && *v6 != IMISC_SCROLLT || v6[1] != plr[v1]._pSpell )
		{
			++v5;
			v6 += 92;
			if ( v5 >= 8 )
				return;
		}
		RemoveSpdBarItem(p, v5);
	}
	else
	{
		v4 = &plr[v1].InvList[0]._iMiscId;
		while ( *(v4 - 53) == -1 || *v4 != IMISC_SCROLL && *v4 != IMISC_SCROLLT || v4[1] != plr[v1]._pSpell )
		{
			++v3;
			v4 += 92;
			if ( v3 >= v2 )
				goto LABEL_8;
		}
		RemoveInvItem(p, v3);
	}
	CalcPlrScrolls(p);
}

//----- (0041EB8B) --------------------------------------------------------
void __cdecl UseScroll()
{
	int v0; // eax
	int v1; // esi
	int v2; // ecx
	int *v3; // edx
	signed int v4; // esi
	int *v5; // ecx

	if ( pcurs == CURSOR_HAND && (leveltype || *(_DWORD *)&spelldata[plr[myplr]._pRSpell].sTownSpell) )
	{
		v0 = myplr;
		v1 = 0;
		v2 = plr[myplr]._pNumInv;
		if ( v2 <= 0 )
		{
LABEL_11:
			v4 = 0;
			v5 = &plr[v0].SpdList[0]._iMiscId;
			do
			{
				if ( *(v5 - 53) != -1 && (*v5 == IMISC_SCROLL || *v5 == IMISC_SCROLLT) && v5[1] == plr[v0]._pRSpell )
					break;
				++v4;
				v5 += 92;
			}
			while ( v4 < 8 );
		}
		else
		{
			v3 = &plr[v0].InvList[0]._iMiscId;
			while ( *(v3 - 53) == -1 || *v3 != IMISC_SCROLL && *v3 != IMISC_SCROLLT || v3[1] != plr[v0]._pRSpell )
			{
				++v1;
				v3 += 92;
				if ( v1 >= v2 )
					goto LABEL_11;
			}
		}
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (0041EC42) --------------------------------------------------------
void __fastcall UseStaffCharge(int pnum)
{
	int v1; // eax
	int *v2; // eax

	v1 = pnum;
	if ( plr[pnum].InvBody[4]._itype != ITYPE_NONE
	  && plr[v1].InvBody[4]._iMiscId == IMISC_STAFF
	  && plr[v1].InvBody[4]._iSpell == plr[v1]._pRSpell )
	{
		v2 = &plr[v1].InvBody[4]._iCharges;
		if ( *v2 > 0 )
		{
			--*v2;
			CalcPlrStaff(pnum);
		}
	}
}

//----- (0041EC7F) --------------------------------------------------------
void __cdecl UseStaff()
{
	int v0; // eax

	if ( pcurs == CURSOR_HAND )
	{
		v0 = myplr;
		if ( plr[myplr].InvBody[4]._itype != ITYPE_NONE
		  && plr[v0].InvBody[4]._iMiscId == IMISC_STAFF
		  && plr[v0].InvBody[4]._iSpell == plr[v0]._pRSpell )
		{
			plr[v0].InvBody[4]._iCharges;
		}
	}
}

//----- (0041ECC3) --------------------------------------------------------
void __cdecl StartGoldDrop()
{
	int v0; // eax

	initialDropGoldIndex = pcursinvitem;
	if ( pcursinvitem > 46 )
		v0 = plr[myplr].InvBody[pcursinvitem]._iMaxDur;
	else
		v0 = plr[myplr].InvBody[pcursinvitem]._ivalue;
	dropGoldValue = 0;
	initialDropGoldValue = v0;
	dropGoldFlag = 1;
	if ( talkflag )
		control_reset_talk();
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8960: using guessed type int talkflag;
// 4B8CB8: using guessed type char pcursinvitem;

//----- (0041ED29) --------------------------------------------------------
int __fastcall UseInvItem(int pnum, int cii)
{
	int v2; // esi
	int result; // eax
	int v4; // ebx
	int v5; // ebp
	_DWORD *v6; // edi
	char v7; // al
	int v8; // ecx
	int v9; // eax
	int v10; // ecx
	char v11; // al
	char v12; // al
	int p; // [esp+10h] [ebp-8h]
	signed int v14; // [esp+14h] [ebp-4h]

	v2 = pnum;
	p = pnum;
	if ( plr[pnum]._pInvincible && !plr[v2]._pHitPoints && pnum == myplr )
		return 1;
	result = 1;
	if ( pcurs == 1 && !stextflag )
	{
		if ( cii <= 5 )
			return 0;
		if ( cii > 46 )
		{
			if ( talkflag )
				return result;
			v4 = cii - 47;
			v14 = 1;
			v5 = 368 * (cii - 47) + v2 * 21720;
			v6 = (_DWORD *)((char *)plr[0].SpdList + v5);
		}
		else
		{
			v4 = cii - 7;
			v14 = 0;
			v5 = 368 * (cii - 7) + v2 * 21720;
			v6 = (_DWORD *)((char *)plr[0].InvList + v5);
		}
		if ( v6[90] == 17 )
		{
			v12 = plr[v2]._pClass;
			sfxdelay = 10;
			if ( v12 )
			{
				if ( v12 == 1 )
				{
					sfxdnum = PS_ROGUE95;
				}
				else if ( v12 == 2 )
				{
					sfxdnum = PS_MAGE95;
				}
			}
			else
			{
				sfxdnum = PS_WARR95;
			}
			return 1;
		}
		if ( v6[90] == 19 )
		{
			PlaySFX(IS_IBOOK);
			v11 = plr[v2]._pClass;
			sfxdelay = 10;
			if ( v11 )
			{
				if ( v11 == 1 )
				{
					sfxdnum = PS_ROGUE29;
				}
				else if ( v11 == 2 )
				{
					sfxdnum = PS_MAGE29;
				}
			}
			else
			{
				sfxdnum = PS_WARR29;
			}
			return 1;
		}
		if ( !AllItemsList[v6[90]].iUsable )
			return 0;
		if ( !v6[89] )
		{
			v7 = plr[v2]._pClass;
			if ( v7 )
			{
				if ( v7 == 1 )
				{
					v8 = PS_ROGUE13;
				}
				else
				{
					if ( v7 != 2 )
						return 1;
					v8 = PS_MAGE13;
				}
			}
			else
			{
				v8 = PS_WARR13;
			}
			PlaySFX(v8);
			return 1;
		}
		v9 = v6[55];
		if ( !v9 && v6[2] == 11 )
		{
			StartGoldDrop();
			return 1;
		}
		if ( dropGoldFlag )
		{
			dropGoldFlag = 0;
			dropGoldValue = 0;
		}
		if ( v9 == 21 && !currlevel && !*(_DWORD *)&spelldata[v6[56]].sTownSpell
		  || v9 == 22 && !currlevel && !*(_DWORD *)&spelldata[v6[56]].sTownSpell )
		{
			return 1;
		}
		if ( v9 == 24 )
		{
			v10 = 65;
		}
		else
		{
			if ( pnum != myplr )
				goto LABEL_39;
			v10 = ItemInvSnds[ItemCAnimTbl[v6[48]]];
		}
		PlaySFX(v10);
LABEL_39:
		UseItem(p, v6[55], v6[56]);
		if ( v14 )
		{
			RemoveSpdBarItem(p, v4);
		}
		else if ( *(int *)((char *)&plr[0].InvList[0]._iMiscId + v5) != IMISC_MAPOFDOOM )
		{
			RemoveInvItem(p, v4);
		}
		return 1;
	}
	return result;
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8960: using guessed type int talkflag;
// 52A554: using guessed type int sfxdelay;
// 6AA705: using guessed type char stextflag;

//----- (0041EFA1) --------------------------------------------------------
void __cdecl DoTelekinesis()
{
	if ( pcursobj != -1 )
		NetSendCmdParam1(1u, CMD_OPOBJT, pcursobj);
	if ( pcursitem != -1 )
		NetSendCmdGItem(1u, CMD_REQUESTAGITEM, myplr, myplr, pcursitem);
	if ( *(_DWORD *)&pcursmonst != -1 && !M_Talker(*(int *)&pcursmonst) && !monster[*(_DWORD *)&pcursmonst].mtalkmsg )
		NetSendCmdParam1(1u, CMD_KNOCKBACK, pcursmonst);
	SetCursor(1);
}
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC1: using guessed type char pcursobj;

//----- (0041F013) --------------------------------------------------------
int __fastcall CalculateGold(int pnum)
{
	int result; // eax
	int v2; // ecx
	int *v3; // edx
	signed int v4; // esi
	int v5; // edx
	int *v6; // ecx

	result = 0;
	v2 = pnum;
	v3 = &plr[v2].SpdList[0]._ivalue;
	v4 = 8;
	do
	{
		if ( *(v3 - 47) == 11 )
		{
			result += *v3;
			force_redraw = 255;
		}
		v3 += 92;
		--v4;
	}
	while ( v4 );
	v5 = plr[v2]._pNumInv;
	if ( v5 > 0 )
	{
		v6 = &plr[v2].InvList[0]._ivalue;
		do
		{
			if ( *(v6 - 47) == 11 )
				result += *v6;
			v6 += 92;
			--v5;
		}
		while ( v5 );
	}
	return result;
}
// 52571C: using guessed type int force_redraw;

//----- (0041F068) --------------------------------------------------------
int __cdecl DropItemBeforeTrig()
{
	if ( !TryInvPut() )
		return 0;
	NetSendCmdPItem(1u, CMD_PUTITEM, cursmx, cursmy);
	SetCursor(1);
	return 1;
}

//----- (0041F096) --------------------------------------------------------
void __cdecl InitItemGFX()
{
	signed int v0; // esi
	char arglist[64]; // [esp+4h] [ebp-40h]

	v0 = 0;
	do
	{
		sprintf(arglist, "Items\\%s.CEL", ItemDropStrs[v0]);
		Item2Frm[v0] = (int)LoadFileInMem(arglist, 0);
		++v0;
	}
	while ( v0 < 35 );
	memset(UniqueItemFlag, 0, 0x200u);
}

//----- (0041F0E8) --------------------------------------------------------
bool __fastcall ItemPlace(int x, int y)
{
	int v2; // ecx
	int v3; // eax
	bool result; // al

	v2 = x;
	v3 = v2 * 112 + y;
	if ( dMonster[0][v3] || dPlayer[v2][y] || dItem[v2][y] || dObject[v2][y] || dFlags[v2][y] & 8 )
		result = 0;
	else
		result = nSolidTable[dPiece[0][v3]] == 0;
	return result;
}

//----- (0041F13A) --------------------------------------------------------
void __cdecl AddInitItems()
{
	int v0; // eax
	int v1; // ebx
	int *v2; // ecx
	int v3; // esi
	int v4; // eax
	int v5; // eax
	int v6; // edx
	int v7; // edi
	int v8; // eax
	int v9; // eax
	int v10; // [esp+0h] [ebp-4h]

	v0 = random(11, 3) + 3;
	if ( v0 > 0 )
	{
		v10 = v0;
		do
		{
			v1 = itemavail[0];
			v2 = &itemavail[-numitems + 126];
			itemactive[numitems] = itemavail[0];
			itemavail[0] = *v2;
			do
			{
				v3 = random(12, 80) + 16;
				v4 = random(12, 80);
				_LOBYTE(v5) = ItemPlace(v3, v4 + 16);
			}
			while ( !v5 );
			v7 = v1;
			items[v7]._ix = v3;
			items[v7]._iy = v6;
			dItem[v3][v6] = v1 + 1;
			v8 = GetRndSeed();
			items[v7]._iSeed = v8;
			SetRndSeed(v8);
			if ( random(12, 2) )
				GetItemAttrs(v1, 24, currlevel);
			else
				GetItemAttrs(v1, 25, currlevel);
			items[v7]._iCreateInfo = currlevel + -32768;
			SetupItem(v1);
			v9 = items[v7]._iAnimLen;
			items[v7]._iAnimFlag = 0;
			items[v7]._iAnimFrame = v9;
			items[v7]._iSelFlag = 1;
			DeltaAddItem(v1);
			++numitems;
			--v10;
		}
		while ( v10 );
	}
}

//----- (0041F24E) --------------------------------------------------------
void __cdecl InitItems()
{
	int *v0; // eax
	int v1; // edx
	int v2; // eax
	int v3; // eax

	GetItemAttrs(0, 0, 1);
	numitems = 0;
	qmemcpy(&golditem, items, sizeof(golditem));
	golditem._iStatFlag = 1;
	v0 = &items[0]._ix;
	do
	{
		*(v0 - 1) = 0;
		*v0 = 0;
		v0[1] = 0;
		v0[2] = 0;
		*((_BYTE *)v0 + 36) = 0;
		v0[11] = 0;
		v0[10] = 0;
		v0 += 92;
	}
	while ( (signed int)v0 < (signed int)&items[127]._ix );
	v1 = 0;
	memset(itemactive, 0, sizeof(itemactive));
	do
	{
		itemavail[v1] = v1;
		++v1;
	}
	while ( v1 < 127 );
	if ( !setlevel )
	{
		GetRndSeed();
		_LOBYTE(v2) = QuestStatus(0);
		if ( v2 )
			SpawnRock();
		_LOBYTE(v3) = QuestStatus(10);
		if ( v3 )
			SpawnQuestItem(16, 2 * setpc_x + 27, 2 * setpc_y + 27, 0, 1);
		if ( currlevel > 0u && currlevel < 0x10u )
			AddInitItems();
	}
	uitemflag = 0;
}
// 5CF31D: using guessed type char setlevel;

//----- (0041F320) --------------------------------------------------------
void __fastcall CalcPlrItemVals(int player_num, bool load_gfx)
{
	int v2; // eax
	int v3; // ecx
	int v4; // ebx
	int v5; // esi
	int *v6; // edi
	int v7; // edx
	int v8; // ecx
	int v9; // eax
	int v10; // edx
	int v11; // eax
	int *v12; // ecx
	int *v13; // eax
	int v14; // eax
	int v15; // eax
	signed int v16; // ecx
	bool v17; // zf
	signed int v18; // eax
	signed int v19; // ecx
	signed int v20; // ebx
	char v21; // dl
	int v22; // eax
	int v23; // ecx
	int v24; // eax
	int v25; // eax
	int v26; // edx
	int v27; // edx
	int v28; // eax
	int v29; // ebx
	int v30; // ecx
	int v31; // eax
	int v32; // eax
	int v33; // ecx
	int i; // edx
	int v35; // eax
	signed int v36; // [esp-4h] [ebp-84h]
	__int64 v37; // [esp+Ch] [ebp-74h]
	BOOL v38; // [esp+14h] [ebp-6Ch]
	signed int v39; // [esp+18h] [ebp-68h]
	int v40; // [esp+1Ch] [ebp-64h]
	int v41; // [esp+20h] [ebp-60h]
	int v42; // [esp+24h] [ebp-5Ch]
	int v43; // [esp+28h] [ebp-58h]
	int v44; // [esp+2Ch] [ebp-54h]
	int v45; // [esp+30h] [ebp-50h]
	int v46; // [esp+34h] [ebp-4Ch]
	signed int v47; // [esp+38h] [ebp-48h]
	signed int v48; // [esp+3Ch] [ebp-44h]
	signed int v49; // [esp+40h] [ebp-40h]
	int v50; // [esp+44h] [ebp-3Ch]
	char v51; // [esp+48h] [ebp-38h]
	int v52; // [esp+4Ch] [ebp-34h]
	int v53; // [esp+50h] [ebp-30h]
	int v54; // [esp+54h] [ebp-2Ch]
	int v55; // [esp+58h] [ebp-28h]
	int v56; // [esp+5Ch] [ebp-24h]
	int v57; // [esp+60h] [ebp-20h]
	int v58; // [esp+64h] [ebp-1Ch]
	int v59; // [esp+68h] [ebp-18h]
	int v60; // [esp+6Ch] [ebp-14h]
	int v61; // [esp+70h] [ebp-10h]
	int arglist; // [esp+74h] [ebp-Ch]
	int v63; // [esp+78h] [ebp-8h]
	int v64; // [esp+78h] [ebp-8h]
	signed int r; // [esp+7Ch] [ebp-4h]

	v2 = 0;
	arglist = player_num;
	v3 = 0;
	v4 = 0;
	v5 = arglist;
	v38 = load_gfx;
	v58 = 0;
	v57 = 0;
	v56 = 0;
	v55 = 0;
	v59 = 0;
	v53 = 0;
	v60 = 0;
	v52 = 0;
	v61 = 0;
	v37 = 0i64;
	v49 = 0;
	v48 = 0;
	v47 = 0;
	v54 = 0;
	r = 10;
	v46 = 0;
	v63 = 0;
	v51 = 0;
	v50 = 0;
	v45 = 0;
	v44 = 0;
	v43 = 0;
	v42 = 0;
	v6 = &plr[arglist].InvBody[0]._iStatFlag;
	v39 = 7;
	do
	{
		if ( *(v6 - 87) != -1 && *v6 )
		{
			v3 += *(v6 - 38);
			v58 += *(v6 - 36);
			v2 += *(v6 - 37);
			v7 = *(v6 - 33);
			v40 = v3;
			v41 = v2;
			if ( v7 )
				v37 |= 1i64 << ((unsigned char)v7 - 1);
			if ( !*((_BYTE *)v6 - 296) || *(v6 - 75) )
			{
				v57 += *(v6 - 28);
				v56 += *(v6 - 27);
				v8 = *(v6 - 26);
				if ( v8 )
				{
					v9 = v8 * *(v6 - 36) / 100;
					if ( !v9 )
						v9 = 1;
					v55 += v9;
					v2 = v41;
				}
				v4 += *(v6 - 16);
				v59 |= *(v6 - 35);
				v53 += *(v6 - 25);
				v60 += *(v6 - 24);
				v52 += *(v6 - 23);
				v61 += *(v6 - 22);
				v49 += *(v6 - 21);
				v48 += *(v6 - 20);
				v47 += *(v6 - 19);
				v54 += *(v6 - 15);
				r += *(v6 - 14);
				v46 += *(v6 - 17);
				v63 += *(v6 - 18);
				v51 += *((_BYTE *)v6 - 52);
				v50 += *(v6 - 7);
				v45 += *(v6 - 11);
				v44 += *(v6 - 10);
				v43 += *(v6 - 9);
				v42 += *(v6 - 8);
				v3 = v40;
			}
		}
		v6 += 92;
		--v39;
	}
	while ( v39 );
	if ( !v3 && !v2 )
	{
		v2 = 1;
		v3 = 1;
		if ( plr[v5].InvBody[4]._itype == ITYPE_SHIELD && plr[v5].InvBody[4]._iStatFlag )
			v2 = 3;
		if ( plr[v5].InvBody[5]._itype == ITYPE_SHIELD && plr[v5].InvBody[5]._iStatFlag )
			v2 = 3;
	}
	plr[v5]._pIMaxDam = v2;
	plr[v5]._pIAC = v58;
	plr[v5]._pIBonusDam = v57;
	plr[v5]._pIBonusToHit = v56;
	plr[v5]._pIBonusAC = v55;
	plr[v5]._pIFlags = v59;
	plr[v5]._pIGetHit = v54;
	plr[v5]._pIMinDam = v3;
	plr[v5]._pIBonusDamMod = v4;
	if ( r < 2 )
		r = 2;
	if ( r > 15 )
		r = 15;
	if ( plr[v5]._pLightRad != r && arglist == myplr )
	{
		ChangeLightRadius(plr[v5]._plid, r);
		v10 = 10;
		if ( r >= 10 )
			v10 = r;
		ChangeVisionRadius(plr[v5]._pvid, v10);
		plr[v5]._pLightRad = r;
	}
	plr[v5]._pStrength = v53 + plr[v5]._pBaseStr;
	v11 = myplr;
	v12 = &plr[myplr]._pStrength;
	if ( *v12 <= 0 )
		*v12 = 0;
	plr[v5]._pMagic = v60 + plr[v5]._pBaseMag;
	if ( plr[v11]._pMagic <= 0 )
		plr[v11]._pMagic = 0;
	plr[v5]._pDexterity = v52 + plr[v5]._pBaseDex;
	if ( plr[v11]._pDexterity <= 0 )
		plr[v11]._pDexterity = 0;
	v13 = &plr[v11]._pVitality;
	plr[v5]._pVitality = v61 + plr[v5]._pBaseVit;
	if ( *v13 <= 0 )
		*v13 = 0;
	v14 = plr[v5]._pLevel;
	if ( _LOBYTE(plr[v5]._pClass) == 1 )
	{
		v15 = (plr[v5]._pStrength + plr[v5]._pDexterity) * v14;
		v16 = 200;
	}
	else
	{
		v15 = plr[v5]._pStrength * v14;
		v16 = 100;
	}
	v17 = _LOBYTE(plr[v5]._pRSplType) == 3;
	plr[v5]._pISpells[0] = v37;
	plr[v5]._pISpells[1] = HIDWORD(v37);
	plr[v5]._pDamageMod = v15 / v16;
	if ( v17 && !(v37 & (1i64 << (_LOBYTE(plr[v5]._pRSpell) - 1))) )
	{
		plr[v5]._pRSpell = -1;
		_LOBYTE(plr[v5]._pRSplType) = 4;
		force_redraw = 255;
	}
	plr[v5]._pISplLvlAdd = v51;
	plr[v5]._pIEnAc = v50;
	if ( v59 >= 0 )
	{
		v19 = v49;
		v20 = v48;
		v18 = v47;
	}
	else
	{
		v18 = 0;
		v19 = 0;
		v20 = 0;
	}
	if ( v18 > 75 )
		_LOBYTE(v18) = 75;
	plr[v5]._pMagResist = v18;
	if ( v19 > 75 )
		_LOBYTE(v19) = 75;
	plr[v5]._pFireResist = v19;
	if ( v20 > 75 )
		_LOBYTE(v20) = 75;
	v21 = plr[v5]._pClass;
	v22 = v61;
	plr[v5]._pLghtResist = v20;
	if ( !v21 )
		v22 = 2 * v61;
	if ( v21 == 1 )
		v22 += v22 >> 1;
	v23 = (v22 << 6) + v46;
	v24 = v60;
	if ( v21 == 2 )
		v24 = 2 * v60;
	if ( v21 == 1 )
		v24 += v24 >> 1;
	v64 = (v24 << 6) + v63;
	v25 = v23 + plr[v5]._pHPBase;
	v26 = v23 + plr[v5]._pMaxHPBase;
	plr[v5]._pHitPoints = v25;
	v17 = arglist == myplr;
	plr[v5]._pMaxHP = v26;
	if ( v17 && (signed int)(v25 & 0xFFFFFFC0) <= 0 )
		SetPlayerHitPoints(arglist, 0);
	plr[v5]._pMana = v64 + plr[v5]._pManaBase;
	plr[v5]._pMaxMana = v64 + plr[v5]._pMaxManaBase;
	plr[v5]._pIFMinDam = v45;
	plr[v5]._pIFMaxDam = v44;
	plr[v5]._pILMinDam = v43;
	plr[v5]._pILMaxDam = v42;
	if ( v59 & 1 )
		plr[v5]._pInfraFlag = 1;
	else
		plr[v5]._pInfraFlag = 0;
	v27 = plr[v5].InvBody[4]._itype;
	plr[v5]._pBlockFlag = 0;
	v28 = 0;
	plr[v5]._pwtype = 0;
	if ( v27 != ITYPE_NONE && plr[v5].InvBody[4]._iClass == 1 && plr[v5].InvBody[4]._iStatFlag )
		v28 = v27;
	v29 = plr[v5].InvBody[5]._itype;
	if ( v29 != ITYPE_NONE && plr[v5].InvBody[5]._iClass == 1 && plr[v5].InvBody[5]._iStatFlag )
		v28 = plr[v5].InvBody[5]._itype;
	switch ( v28 )
	{
		case ITYPE_SWORD:
			v36 = 2;
			goto LABEL_86;
		case ITYPE_AXE:
			v36 = 5;
			goto LABEL_86;
		case ITYPE_BOW:
			plr[v5]._pwtype = 1;
			v36 = 4;
			goto LABEL_86;
		case ITYPE_MACE:
			v36 = 6;
			goto LABEL_86;
		case ITYPE_STAFF:
			v36 = 8;
LABEL_86:
			v28 = v36;
			break;
	}
	if ( v27 == ITYPE_SHIELD && plr[v5].InvBody[4]._iStatFlag )
	{
		plr[v5]._pBlockFlag = 1;
		++v28;
	}
	if ( v29 == ITYPE_SHIELD && plr[v5].InvBody[5]._iStatFlag )
	{
		plr[v5]._pBlockFlag = 1;
		++v28;
	}
	v30 = plr[v5].InvBody[6]._itype;
	if ( v30 == ITYPE_MARMOR && plr[v5].InvBody[6]._iStatFlag )
		v28 += 16;
	if ( v30 == ITYPE_HARMOR && plr[v5].InvBody[6]._iStatFlag )
		v28 += 32;
	if ( plr[v5]._pgfxnum != v28 && v38 )
	{
		plr[v5]._pgfxnum = v28;
		plr[v5]._pGFXLoad = 0;
		LoadPlrGFX(arglist, 1);
		SetPlrAnims(arglist);
		v31 = plr[0]._peqN[plr[v5]._pdir + 5430 * arglist];
		plr[v5]._pAnimFrame = 1;
		plr[v5]._pAnimData = v31;
		plr[v5]._pAnimLen = plr[v5]._pNFrames;
		v32 = plr[v5]._pNFNum;
		plr[v5]._pAnimWidth = v32;
		plr[v5]._pAnimCnt = 0;
		plr[v5]._pAnimDelay = 3;
		plr[v5]._pAnimWidth2 = (v32 - 64) >> 1;
	}
	else
	{
		plr[v5]._pgfxnum = v28;
	}
	v33 = nummissiles;
	for ( i = 0; i < v33; ++i )
	{
		v35 = missileactive[i];
		if ( missile[v35]._mitype == 13 && missile[v35]._misource == arglist )
		{
			missile[v35]._miVar1 = plr[v5]._pHitPoints;
			missile[v35]._miVar2 = plr[v5]._pHPBase;
		}
	}
	drawmanaflag = 1;
	drawhpflag = 1;
}
// 52571C: using guessed type int force_redraw;

//----- (0041F953) --------------------------------------------------------
void __fastcall CalcPlrScrolls(int p)
{
	int v1; // esi
	int v2; // eax
	int *v3; // edi
	int v4; // ebx
	signed __int64 v5; // rax
	int *v6; // edi
	signed int v7; // ebx
	signed __int64 v8; // rax
	__int64 v9; // rax

	v1 = p;
	v2 = plr[p]._pNumInv;
	plr[v1]._pScrlSpells[0] = 0;
	plr[v1]._pScrlSpells[1] = 0;
	if ( v2 > 0 )
	{
		v3 = &plr[v1].InvList[0]._iMiscId;
		v4 = v2;
		do
		{
			if ( *(v3 - 53) != -1 && (*v3 == IMISC_SCROLL || *v3 == IMISC_SCROLLT) && v3[34] )
			{
				v5 = 1i64 << (*((_BYTE *)v3 + 4) - 1);
				plr[v1]._pScrlSpells[0] |= v5;
				plr[v1]._pScrlSpells[1] |= HIDWORD(v5);
			}
			v3 += 92;
			--v4;
		}
		while ( v4 );
	}
	v6 = &plr[v1].SpdList[0]._iMiscId;
	v7 = 8;
	do
	{
		if ( *(v6 - 53) != -1 && (*v6 == IMISC_SCROLL || *v6 == IMISC_SCROLLT) && v6[34] )
		{
			v8 = 1i64 << (*((_BYTE *)v6 + 4) - 1);
			plr[v1]._pScrlSpells[0] |= v8;
			plr[v1]._pScrlSpells[1] |= HIDWORD(v8);
		}
		v6 += 92;
		--v7;
	}
	while ( v7 );
	if ( _LOBYTE(plr[v1]._pRSplType) == 2 )
	{
		v9 = 1 << (_LOBYTE(plr[v1]._pRSpell) - 1);
		if ( !(plr[v1]._pScrlSpells[1] & HIDWORD(v9) | plr[v1]._pScrlSpells[0] & (unsigned int)v9) )
		{
			plr[v1]._pRSpell = -1;
			_LOBYTE(plr[v1]._pRSplType) = 4;
			force_redraw = 255;
		}
	}
}
// 52571C: using guessed type int force_redraw;

//----- (0041FA4A) --------------------------------------------------------
void __fastcall CalcPlrStaff(int pnum)
{
	int v1; // esi
	bool v2; // zf
	signed __int64 v3; // rax

	v1 = pnum;
	v2 = plr[pnum].InvBody[4]._itype == ITYPE_NONE;
	plr[v1]._pISpells[0] = 0;
	plr[v1]._pISpells[1] = 0;
	if ( !v2 && plr[v1].InvBody[4]._iStatFlag && plr[v1].InvBody[4]._iCharges > 0 )
	{
		v3 = 1i64 << (_LOBYTE(plr[v1].InvBody[4]._iSpell) - 1);
		plr[v1]._pISpells[0] = v3;
		plr[v1]._pISpells[1] = HIDWORD(v3);
	}
}

//----- (0041FA97) --------------------------------------------------------
void __fastcall CalcSelfItems(int pnum)
{
	PlayerStruct *v1; // ecx
	int v2; // edx
	int v3; // esi
	int v4; // edi
	int *v5; // eax
	signed int v6; // ebx
	bool v7; // zf
	char *v8; // eax
	signed int v9; // [esp+Ch] [ebp-10h]
	signed int v10; // [esp+10h] [ebp-Ch]
	int v11; // [esp+14h] [ebp-8h]
	signed int v12; // [esp+18h] [ebp-4h]

	v1 = &plr[pnum];
	v2 = 0;
	v3 = 0;
	v4 = 0;
	v5 = &v1->InvBody[0]._iStatFlag;
	v6 = 7;
	do
	{
		if ( *(v5 - 87) != -1 )
		{
			v7 = *(v5 - 75) == 0;
			*v5 = 1;
			if ( !v7 )
			{
				v2 += *(v5 - 25);
				v3 += *(v5 - 24);
				v4 += *(v5 - 23);
			}
		}
		v5 += 92;
		--v6;
	}
	while ( v6 );
	v11 = v4;
	do
	{
		v9 = 0;
		v8 = &v1->InvBody[0]._iMinStr;
		v10 = 7;
		do
		{
			if ( *((_DWORD *)v8 - 86) != -1 && *((_DWORD *)v8 + 1) )
			{
				v12 = 1;
				if ( v2 + v1->_pBaseStr < *v8 )
					v12 = 0;
				if ( v3 + v1->_pBaseMag < (unsigned char)v8[1] )
					v12 = 0;
				if ( v11 + v1->_pBaseDex < v8[2] )
					v12 = 0;
				if ( !v12 )
				{
					v7 = *((_DWORD *)v8 - 74) == 0;
					v9 = 1;
					*((_DWORD *)v8 + 1) = 0;
					if ( !v7 )
					{
						v2 -= *((_DWORD *)v8 - 24);
						v3 -= *((_DWORD *)v8 - 23);
						v11 -= *((_DWORD *)v8 - 22);
					}
				}
			}
			v8 += 368;
			--v10;
		}
		while ( v10 );
	}
	while ( v9 );
}

//----- (0041FB91) --------------------------------------------------------
void __fastcall CalcPlrItemMin(int pnum)
{
	PlayerStruct *v1; // ecx
	PlayerStruct *v2; // esi
	ItemStruct *v3; // edi
	int v4; // ebp
	int v5; // eax
	ItemStruct *v6; // edi
	signed int v7; // ebp
	int v8; // eax

	v1 = &plr[pnum];
	v2 = v1;
	v3 = v1->InvList;
	if ( v1->_pNumInv )
	{
		v4 = v1->_pNumInv;
		do
		{
			_LOBYTE(v5) = ItemMinStats(v2, v3);
			v3->_iStatFlag = v5;
			++v3;
			--v4;
		}
		while ( v4 );
	}
	v6 = v2->SpdList;
	v7 = 8;
	do
	{
		if ( v6->_itype != -1 )
		{
			_LOBYTE(v8) = ItemMinStats(v2, v6);
			v6->_iStatFlag = v8;
		}
		++v6;
		--v7;
	}
	while ( v7 );
}

//----- (0041FBF6) --------------------------------------------------------
unsigned char __fastcall ItemMinStats(PlayerStruct *p, ItemStruct *x)
{
	unsigned char result; // al

	if ( p->_pMagic < (unsigned char)x->_iMinMag || p->_pStrength < x->_iMinStr )
		result = 0;
	else
		result = p->_pDexterity >= x->_iMinDex;
	return result;
}

//----- (0041FC2C) --------------------------------------------------------
void __fastcall CalcPlrBookVals(int p)
{
	int v1; // esi
	int v2; // ebx
	int *v3; // edi
	int v4; // eax
	int v5; // esi
	int *v6; // edi
	int v7; // eax
	unsigned char v8; // cl
	unsigned char v9; // cl
	int v10; // eax
	int v11; // eax
	int v12; // [esp+Ch] [ebp-Ch]
	int v13; // [esp+10h] [ebp-8h]
	unsigned char v14; // [esp+17h] [ebp-1h]

	v1 = p;
	if ( !currlevel )
	{
		v2 = 1;
		if ( witchitem[1]._itype != -1 )
		{
			v3 = &witchitem[1]._iStatFlag;
			do
			{
				WitchBookLevel(v2);
				_LOBYTE(v4) = StoreStatOk((ItemStruct *)(v3 - 89));
				*v3 = v4;
				v3 += 92;
				++v2;
			}
			while ( *(v3 - 87) != -1 );
		}
	}
	v5 = v1;
	v12 = 0;
	if ( plr[v5]._pNumInv > 0 )
	{
		v6 = &plr[v5].InvList[0]._iSpell;
		do
		{
			if ( !*(v6 - 54) && *(v6 - 1) == 24 )
			{
				v7 = *v6;
				v8 = spelldata[*v6].sMinInt;
				*((_BYTE *)v6 + 129) = v8;
				v13 = plr[0]._pSplLvl[v7 + v5 * 21720];
				if ( plr[0]._pSplLvl[v7 + v5 * 21720] )
				{
					do
					{
						v9 = 20 * v8 / 100 + v8;
						--v13;
						v14 = v9;
						v10 = v9 + 20 * v9 / 100;
						v8 = -1;
						if ( v10 <= 255 )
							v8 = v14;
						else
							v13 = 0;
					}
					while ( v13 );
					*((_BYTE *)v6 + 129) = v8;
				}
				_LOBYTE(v11) = ItemMinStats(&plr[v5], (ItemStruct *)(v6 - 56));
				v6[33] = v11;
			}
			++v12;
			v6 += 92;
		}
		while ( v12 < plr[v5]._pNumInv );
	}
}

//----- (0041FD3E) --------------------------------------------------------
void __fastcall CalcPlrInv(int p, unsigned char Loadgfx)
{
	unsigned char v2; // di
	int v3; // esi

	v2 = Loadgfx;
	v3 = p;
	CalcPlrItemMin(p);
	CalcSelfItems(v3);
	CalcPlrItemVals(v3, v2);
	CalcPlrItemMin(v3);
	if ( v3 == myplr )
	{
		CalcPlrBookVals(v3);
		CalcPlrScrolls(v3);
		CalcPlrStaff(v3);
		if ( v3 == myplr && !currlevel )
			RecalcStoreStats();
	}
}

//----- (0041FD98) --------------------------------------------------------
void __fastcall SetPlrHandItem(ItemStruct *item, int item_id)
{
	int v2; // ebx
	ItemStruct *v3; // esi
	ItemDataStruct *v4; // edi
	int v5; // eax

	v2 = item_id;
	v3 = item;
	v4 = &AllItemsList[item_id];
	memset(item, 0, 0x170u);
	v3->_itype = (char)v4->itype;
	v3->_iCurs = v4->iCurs;
	strcpy(v3->_iName, v4->iName);
	strcpy(v3->_iIName, v4->iName);
	v3->_iLoc = v4->iLoc;
	v3->_iClass = v4->iClass;
	v3->_iMinDam = v4->iMinDam;
	v3->_iMaxDam = v4->iMaxDam;
	v3->_iAC = v4->iMinAC;
	v3->_iMiscId = v4->iMiscId;
	v3->_iSpell = v4->iSpell;
	if ( v4->iMiscId == IMISC_STAFF )
		v3->_iCharges = 40;
	v3->_iMaxCharges = v3->_iCharges;
	v3->_iDurability = v4->iDurability;
	v3->_iMaxDur = v4->iDurability;
	v3->_iMinStr = v4->iMinStr;
	v3->_iMinMag = v4->iMinMag;
	v3->_iMinDex = v4->iMinDex;
	v3->_ivalue = v4->iValue;
	v5 = v4->iValue;
	v3->_iPrePower = -1;
	v3->_iSufPower = -1;
	v3->_iMagical = 0;
	v3->_iIvalue = v5;
	v3->IDidx = v2;
}

//----- (0041FE98) --------------------------------------------------------
void __fastcall GetPlrHandSeed(ItemStruct *item)
{
	item->_iSeed = GetRndSeed();
}

//----- (0041FEA4) --------------------------------------------------------
void __fastcall GetGoldSeed(int player_num, int *item_seed)
{
	int *v2; // ebx
	int v3; // edi
	signed int v4; // esi
	int v5; // eax
	int i; // ecx
	int v7; // edx
	ItemStruct *v8; // ecx

	v2 = item_seed;
	v3 = player_num;
	do
	{
		v4 = 1;
		v5 = GetRndSeed();
		for ( i = 0; i < numitems; ++i )
		{
			if ( items[itemactive[i]]._iSeed == v5 )
				v4 = 0;
		}
		if ( v3 == myplr )
		{
			v7 = plr[v3]._pNumInv;
			if ( v7 > 0 )
			{
				v8 = plr[v3].InvList;
				do
				{
					if ( v8->_iSeed == v5 )
						v4 = 0;
					++v8;
					--v7;
				}
				while ( v7 );
			}
		}
	}
	while ( !v4 );
	*v2 = v5;
}

//----- (0041FF16) --------------------------------------------------------
void __fastcall SetPlrHandSeed(ItemStruct *h, int iseed)
{
	h->_iSeed = iseed;
}

//----- (0041FF19) --------------------------------------------------------
void __fastcall SetPlrHandGoldCurs(ItemStruct *h)
{
	int v1; // eax

	v1 = h->_ivalue;
	if ( v1 < 2500 )
	{
		if ( v1 > 1000 )
			h->_iCurs = 5;
		else
			h->_iCurs = 4;
	}
	else
	{
		h->_iCurs = 6;
	}
}

//----- (0041FF4E) --------------------------------------------------------
void __fastcall CreatePlrItems(int player_num)
{
	int v1; // ebx
	int *v2; // eax
	signed int v3; // ecx
	int *v4; // eax
	signed int v5; // ecx
	int *v6; // eax
	signed int v7; // ecx
	int player_numa; // [esp+Ch] [ebp-4h]

	player_numa = player_num;
	v1 = player_num;
	v2 = &plr[player_num].InvBody[0]._itype;
	v3 = 7;
	do
	{
		*v2 = -1;
		v2 += 92;
		--v3;
	}
	while ( v3 );
	memset(plr[v1].InvGrid, 0, 0x28u);
	v4 = &plr[v1].InvList[0]._itype;
	v5 = 40;
	do
	{
		*v4 = -1;
		v4 += 92;
		--v5;
	}
	while ( v5 );
	plr[v1]._pNumInv = 0;
	v6 = &plr[v1].SpdList[0]._itype;
	v7 = 8;
	do
	{
		*v6 = -1;
		v6 += 92;
		--v7;
	}
	while ( v7 );
	switch ( _LOBYTE(plr[v1]._pClass) )
	{
		case UI_WARRIOR:
			SetPlrHandItem(&plr[v1].InvBody[4], 1);
			GetPlrHandSeed(&plr[v1].InvBody[4]);
			SetPlrHandItem(&plr[v1].InvBody[5], 2);
			GetPlrHandSeed(&plr[v1].InvBody[5]);
			SetPlrHandItem(&plr[v1].HoldItem, 3);
			GetPlrHandSeed(&plr[v1].HoldItem);
			AutoPlace(player_numa, 0, 1, 3, 1);
			goto LABEL_13;
		case UI_ROGUE:
			SetPlrHandItem(&plr[v1].InvBody[4], 4);
			GetPlrHandSeed(&plr[v1].InvBody[4]);
LABEL_13:
			SetPlrHandItem(plr[v1].SpdList, 24);
			GetPlrHandSeed(plr[v1].SpdList);
			SetPlrHandItem(&plr[v1].SpdList[1], 24);
			goto LABEL_14;
		case UI_SORCERER:
			SetPlrHandItem(&plr[v1].InvBody[4], 5);
			GetPlrHandSeed(&plr[v1].InvBody[4]);
			SetPlrHandItem(plr[v1].SpdList, 25);
			GetPlrHandSeed(plr[v1].SpdList);
			SetPlrHandItem(&plr[v1].SpdList[1], 25);
LABEL_14:
			GetPlrHandSeed(&plr[v1].SpdList[1]);
			break;
	}
	SetPlrHandItem(&plr[v1].HoldItem, 0);
	GetPlrHandSeed(&plr[v1].HoldItem);
	plr[v1].HoldItem._iCurs = 4;
	plr[v1].HoldItem._ivalue = 100;
	plr[v1]._pGold = 100;
	qmemcpy((char *)&plr[0].InvList[plr[v1]._pNumInv++] + v1 * 21720, &plr[v1].HoldItem, 0x170u);
	plr[v1].InvGrid[30] = plr[v1]._pNumInv;
	CalcPlrItemVals(player_numa, 0);
}

//----- (004200F8) --------------------------------------------------------
unsigned char __fastcall ItemSpaceOk(int i, int j)
{
	int v2; // eax
	int v3; // esi
	char v4; // cl
	int v5; // ecx
	char v6; // cl
	bool v7; // sf
	char v8; // cl
	char v9; // al

	if ( i < 0 )
		return 0;
	if ( i >= 112 )
		return 0;
	if ( j < 0 )
		return 0;
	if ( j >= 112 )
		return 0;
	v2 = i;
	v3 = 112 * i + j;
	if ( dMonster[0][v3] || dPlayer[v2][j] || dItem[v2][j] )
		return 0;
	v4 = dObject[v2][j];
	if ( v4 )
	{
		v5 = v4 <= 0 ? -1 - v4 : v4 - 1;
		if ( object[v5]._oSolidFlag )
			return 0;
	}
	v6 = dObject[v2 + 1][j + 1];
	v7 = v6 < 0;
	if ( v6 > 0 )
	{
		if ( _LOBYTE(objectavail[30 * v6 + 113]) )
			return 0;
		v7 = v6 < 0;
	}
	if ( !v7 || !_LOBYTE(object[-(v6 + 1)]._oSelFlag) )
	{
		v8 = dObject[v2 + 1][j];
		if ( v8 <= 0 )
			return nSolidTable[dPiece[0][v3]] == 0;
		v9 = dObject[v2][j + 1];
		if ( v9 <= 0 || !_LOBYTE(objectavail[30 * v8 + 113]) || !_LOBYTE(objectavail[30 * v9 + 113]) )
			return nSolidTable[dPiece[0][v3]] == 0;
	}
	return 0;
}

//----- (004201F2) --------------------------------------------------------
unsigned char __fastcall GetItemSpace(int x, int y, char inum)
{
	int v3; // eax
	int v4; // edx
	char (*v5)[3]; // edi
	int v6; // ebx
	char (*v7)[3]; // esi
	int v8; // eax
	signed int v9; // esi
	char (*v10)[3]; // eax
	int v11; // ecx
	int v12; // eax
	int v14; // ecx
	int v15; // edx
	int v16; // eax
	int v17; // esi
	int v18; // ecx
	int v19; // [esp+8h] [ebp-Ch]
	int v20; // [esp+Ch] [ebp-8h]
	char (*v21)[3]; // [esp+10h] [ebp-4h]

	v3 = y;
	v19 = y;
	v4 = y - 1;
	v20 = x;
	v5 = itemhold;
	if ( v4 <= v19 + 1 )
	{
		v21 = itemhold;
		do
		{
			v6 = x - 1;
			if ( (unsigned char)(__OFSUB__(x - 1, x + 1) ^ 1) | (x - 1 == x + 1) )
			{
				v7 = v21;
				do
				{
					_LOBYTE(v8) = ItemSpaceOk(v6, v4);
					*(_DWORD *)v7 = v8;
					v7 += 4;
					++v6;
				}
				while ( v6 <= v20 + 1 );
				v3 = v19;
				x = v20;
			}
			v21 = (char (*)[3])((char *)v21 + 4);
			++v4;
		}
		while ( v4 <= v3 + 1 );
	}
	v9 = 0;
	do
	{
		v10 = v5;
		v11 = 3;
		do
		{
			if ( *(_DWORD *)v10 )
				v9 = 1;
			v10 += 4;
			--v11;
		}
		while ( v11 );
		v5 = (char (*)[3])((char *)v5 + 4);
	}
	while ( (signed int)v5 < (signed int)byte_641234 );
	_LOBYTE(v11) = 13;
	v12 = random(v11, 15) + 1;
	if ( !v9 )
		return 0;
	v14 = 0;
	v15 = 0;
	if ( v12 > 0 )
	{
		while ( 1 )
		{
			if ( *(_DWORD *)&itemhold[0][4 * (v15 + 2 * v14 + v14)] )
				--v12;
			if ( v12 <= 0 )
				break;
			if ( ++v14 == 3 )
			{
				v14 = 0;
				if ( ++v15 == 3 )
					v15 = 0;
			}
		}
	}
	v16 = v14 + v20 - 1;
	v17 = v15 + v19 - 1;
	v18 = inum;
	items[v18]._ix = v16;
	dItem[v16][v17] = inum + 1;
	items[v18]._iy = v17;
	return 1;
}

//----- (004202E8) --------------------------------------------------------
void __fastcall GetSuperItemSpace(int x, int y, char inum)
{
	int v3; // eax
	signed int v4; // edi
	signed int v5; // ebx
	int v6; // edx
	int v7; // esi
	int v8; // eax
	int v9; // eax
	int v10; // [esp+Ch] [ebp-10h]
	int v11; // [esp+10h] [ebp-Ch]
	signed int v12; // [esp+14h] [ebp-8h]
	signed int v13; // [esp+18h] [ebp-4h]

	v11 = y;
	v10 = x;
	_LOBYTE(v3) = GetItemSpace(x, y, inum);
	if ( !v3 )
	{
		v13 = 2;
		v4 = -2;
		do
		{
			v5 = v4;
			if ( v4 <= v13 )
			{
				while ( 2 )
				{
					v12 = v4;
					v6 = v5 + v11;
					v7 = v4 + v10;
					do
					{
						_LOBYTE(v8) = ItemSpaceOk(v7, v6);
						if ( v8 )
						{
							v9 = inum;
							items[v9]._ix = v7;
							items[v9]._iy = v6;
							dItem[v7][v6] = inum + 1;
							return;
						}
						++v12;
						++v7;
					}
					while ( v12 <= v13 );
					if ( ++v5 <= v13 )
						continue;
					break;
				}
			}
			++v13;
			--v4;
		}
		while ( v4 > -50 );
	}
}

//----- (00420376) --------------------------------------------------------
void __fastcall GetSuperItemLoc(int x, int y, int *xx, int *yy)
{
	signed int v4; // edi
	signed int v5; // ebx
	int v6; // esi
	int v7; // eax
	int v8; // [esp+Ch] [ebp-10h]
	int v9; // [esp+10h] [ebp-Ch]
	signed int v10; // [esp+14h] [ebp-8h]
	signed int v11; // [esp+18h] [ebp-4h]

	v9 = y;
	v8 = x;
	v11 = 1;
	v4 = -1;
	while ( 1 )
	{
		v5 = v4;
		if ( v4 <= v11 )
			break;
LABEL_7:
		++v11;
		if ( --v4 <= -50 )
			return;
	}
LABEL_3:
	v10 = v4;
	*yy = v5 + v9;
	v6 = v4 + v8;
	while ( 1 )
	{
		*xx = v6;
		_LOBYTE(v7) = ItemSpaceOk(v6, *yy);
		if ( v7 )
			break;
		++v10;
		++v6;
		if ( v10 > v11 )
		{
			if ( ++v5 <= v11 )
				goto LABEL_3;
			goto LABEL_7;
		}
	}
}

//----- (004203E0) --------------------------------------------------------
void __fastcall CalcItemValue(int i)
{
	int v1; // ecx
	int v2; // esi
	bool v3; // sf
	int v4; // esi

	v1 = i;
	v2 = items[v1]._iVMult1 + items[v1]._iVMult2;
	v3 = v2 < 0;
	if ( v2 > 0 )
	{
		v2 *= items[v1]._ivalue;
		v3 = v2 < 0;
	}
	if ( v3 )
		v2 = items[v1]._ivalue / v2;
	v4 = items[v1]._iVAdd1 + items[v1]._iVAdd2 + v2;
	if ( v4 <= 0 )
		v4 = 1;
	items[v1]._iIvalue = v4;
}

//----- (0042042C) --------------------------------------------------------
void __fastcall GetBookSpell(int i, int lvl)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax
	int v5; // edx
	signed int v6; // ecx
	int v7; // esi
	const char **v8; // ebx
	int v9; // eax
	char v10; // al
	int v11; // [esp+8h] [ebp-4h]

	v2 = lvl;
	v3 = i;
	if ( !lvl )
		v2 = lvl + 1;
	_LOBYTE(i) = 14;
	v4 = random(i, 37) + 1;
LABEL_13:
	v6 = 1;
	while ( v4 > 0 )
	{
		v5 = spelldata[v6].sBookLvl;
		if ( v5 != -1 && v2 >= v5 )
		{
			--v4;
			v11 = v6;
		}
		++v6;
		if ( gbMaxPlayers == 1 )
		{
			if ( v6 == 32 )
				v6 = 33;
			if ( v6 == 34 )
				v6 = 35;
		}
		if ( v6 == 37 )
			goto LABEL_13;
	}
	v7 = v3;
	v8 = (const char **)&spelldata[v11].sNameText;
	strcat(items[v7]._iName, *v8);
	strcat(items[v7]._iIName, *v8);
	items[v7]._iSpell = v11;
	items[v7]._iMinMag = spelldata[v11].sMinInt;
	v9 = spelldata[v11].sBookCost;
	items[v7]._ivalue += v9;
	items[v7]._iIvalue += v9;
	v10 = spelldata[v11].sType;
	if ( v10 == STYPE_FIRE )
		items[v7]._iCurs = 87;
	if ( v10 == 1 )
		items[v7]._iCurs = 88;
	if ( v10 == 2 )
		items[v7]._iCurs = 86;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00420514) --------------------------------------------------------
void __fastcall GetStaffPower(int i, int lvl, int bs, unsigned char onlygood)
{
	int v4; // esi
	int v5; // ebx
	int v6; // edx
	int v7; // ecx
	int *v8; // eax
	int v9; // edi
	int v10; // ecx
	int v11; // ST14_4
	int v12; // esi
	char *v13; // edi
	int v14[256]; // [esp+Ch] [ebp-484h]
	char v15[128]; // [esp+40Ch] [ebp-84h]
	int ia; // [esp+48Ch] [ebp-4h]
	char *v17; // [esp+49Ch] [ebp+Ch]

	v4 = lvl;
	ia = i;
	_LOBYTE(i) = 15;
	v5 = -1;
	if ( !random(i, 10) || onlygood )
	{
		v6 = 0;
		v7 = 0;
		if ( *(_DWORD *)&PL_Prefix[0].PLPower != -1 )
		{
			v8 = &PL_Prefix[0].PLMinLvl;
			do
			{
				if ( *((_BYTE *)v8 + 5) & 1 && *(char *)v8 <= v4 && (!onlygood || v8[4]) )
				{
					v14[v6++] = v7;
					if ( v8[3] )
						v14[v6++] = v7;
				}
				v8 += 12;
				++v7;
			}
			while ( *(v8 - 3) != -1 );
			if ( v6 )
			{
				_LOBYTE(v7) = 16;
				v5 = v14[random(v7, v6)];
				v9 = ia;
				v17 = items[ia]._iIName;
				sprintf(v15, "%s %s", PL_Prefix[v5].PLName, items[ia]._iIName);
				strcpy(v17, v15);
				v10 = ia;
				v11 = PL_Prefix[v5].PLMultVal;
				items[v9]._iMagical = 1;
				SaveItemPower(
					v10,
					*(_DWORD *)&PL_Prefix[v5].PLPower,
					PL_Prefix[v5].PLParam1,
					PL_Prefix[v5].PLParam2,
					PL_Prefix[v5].PLMinVal,
					PL_Prefix[v5].PLMaxVal,
					v11);
				items[v9]._iPrePower = PL_Prefix[v5].PLPower;
			}
		}
	}
	v12 = ia;
	v13 = items[ia]._iIName;
	if ( !control_WriteStringToBuffer(items[ia]._iIName) )
	{
		strcpy(v13, AllItemsList[items[v12].IDidx].iSName);
		if ( v5 != -1 )
		{
			sprintf(v15, "%s %s", PL_Prefix[v5].PLName, v13);
			strcpy(v13, v15);
		}
		sprintf(v15, "%s of %s", v13, spelldata[bs].sNameText);
		strcpy(v13, v15);
		if ( !items[v12]._iMagical )
			strcpy(items[v12]._iName, v13);
	}
	CalcItemValue(ia);
}
// 420514: using guessed type int var_484[256];

//----- (004206E5) --------------------------------------------------------
void __fastcall GetStaffSpell(int i, int lvl, unsigned char onlygood)
{
	int v3; // esi
	int v4; // ecx
	signed int v5; // esi
	int v6; // eax
	int v7; // edx
	int v8; // ecx
	int v9; // edi
	int v10; // esi
	char *v11; // ebx
	int v12; // ebx
	int v13; // edx
	int v14; // ecx
	int v15; // eax
	int v16; // ecx
	int v17; // eax
	int v18; // edx
	int v19; // ecx
	int v20; // ST08_4
	char v21[64]; // [esp+4h] [ebp-4Ch]
	int lvla; // [esp+44h] [ebp-Ch]
	int ia; // [esp+48h] [ebp-8h]
	int bs; // [esp+4Ch] [ebp-4h]

	v3 = lvl;
	ia = i;
	_LOBYTE(i) = 17;
	lvla = lvl;
	if ( random(i, 4) )
	{
		v5 = v3 >> 1;
		if ( !v5 )
			v5 = 1;
		_LOBYTE(v4) = 18;
		v6 = random(v4, 37) + 1;
LABEL_15:
		v8 = 1;
		while ( v6 > 0 )
		{
			v7 = spelldata[v8].sStaffLvl;
			if ( v7 != -1 && v5 >= v7 )
			{
				--v6;
				bs = v8;
			}
			++v8;
			if ( gbMaxPlayers == 1 )
			{
				if ( v8 == 32 )
					v8 = 33;
				if ( v8 == 34 )
					v8 = 35;
			}
			if ( v8 == 37 )
				goto LABEL_15;
		}
		v9 = bs;
		v10 = ia;
		v11 = items[ia]._iName;
		sprintf(v21, "%s of %s", items[ia]._iName, spelldata[bs].sNameText);
		if ( !control_WriteStringToBuffer(v21) )
			sprintf(v21, "Staff of %s", spelldata[v9].sNameText);
		strcpy(v11, v21);
		strcpy(items[v10]._iIName, v21);
		v12 = spelldata[v9].sStaffMin;
		v13 = spelldata[v9].sStaffMax - v12 + 1;
		_LOBYTE(v14) = 19;
		items[v10]._iSpell = bs;
		v15 = random(v14, v13);
		v16 = v15 + v12;
		items[v10]._iMinMag = spelldata[v9].sMinInt;
		v17 = (v15 + v12) * spelldata[v9].sStaffCost;
		items[v10]._iCharges = v16;
		items[v10]._iMaxCharges = v16;
		v17 /= 5;
		v18 = lvla;
		v19 = ia;
		v20 = bs;
		items[v10]._ivalue += v17;
		items[v10]._iIvalue += v17;
		GetStaffPower(v19, v18, v20, onlygood);
	}
	else
	{
		GetItemPower(ia, v3 >> 1, v3, 256, onlygood);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0042084A) --------------------------------------------------------
void __fastcall GetItemAttrs(int i, int idata, int lvl)
{
	int v3; // ST20_4
	int v4; // edi
	const char **v5; // ebx
	int v6; // esi
	const char *v7; // ST0C_4
	int v8; // edx
	int v9; // edx
	int v10; // ecx
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // eax
	int ia; // [esp+Ch] [ebp-8h]

	v3 = idata;
	v4 = idata;
	v5 = (const char **)&AllItemsList[idata].iName;
	ia = i;
	v6 = i;
	v7 = *v5;
	items[v6]._itype = (char)AllItemsList[idata].itype;
	items[v6]._iCurs = AllItemsList[idata].iCurs;
	strcpy(items[i]._iName, v7);
	strcpy(items[v6]._iIName, *v5);
	v8 = AllItemsList[v4].iMaxAC;
	items[v6]._iLoc = AllItemsList[v4].iLoc;
	items[v6]._iClass = AllItemsList[v4].iClass;
	v9 = v8 - AllItemsList[v4].iMinAC;
	items[v6]._iMinDam = AllItemsList[v4].iMinDam;
	_LOBYTE(v10) = 20;
	items[v6]._iMaxDam = AllItemsList[v4].iMaxDam;
	v11 = AllItemsList[v4].iMinAC + random(v10, v9 + 1);
	v12 = AllItemsList[v4].iMiscId;
	items[v6]._iMiscId = v12;
	items[v6]._iAC = v11;
	items[v6]._iFlags = AllItemsList[v4].iFlags;
	items[v6]._iSpell = AllItemsList[v4].iSpell;
	v13 = AllItemsList[v4].iValue;
	items[v6]._ivalue = v13;
	items[v6]._iIvalue = v13;
	v14 = AllItemsList[v4].iDurability;
	items[v6]._iMagical = 0;
	items[v6]._iDurability = v14;
	items[v6]._iMaxDur = v14;
	_LOBYTE(v14) = AllItemsList[v4].iMinStr;
	items[v6]._iVAdd1 = 0;
	items[v6]._iMinStr = v14;
	items[v6]._iMinMag = AllItemsList[v4].iMinMag;
	items[v6]._iMinDex = AllItemsList[v4].iMinDex;
	items[v6]._iVMult1 = 0;
	items[v6]._iVAdd2 = 0;
	items[v6]._iVMult2 = 0;
	items[v6]._iPLDam = 0;
	items[v6]._iPLToHit = 0;
	items[v6]._iPLAC = 0;
	items[v6]._iPLStr = 0;
	items[v6]._iPLMag = 0;
	items[v6]._iPLDex = 0;
	items[v6]._iPLVit = 0;
	items[v6]._iCharges = 0;
	items[v6]._iMaxCharges = 0;
	items[v6]._iPLFR = 0;
	items[v6]._iPLLR = 0;
	items[v6]._iPLMR = 0;
	items[v6].IDidx = v3;
	items[v6]._iPLDamMod = 0;
	items[v6]._iPLGetHit = 0;
	items[v6]._iPLLight = 0;
	items[v6]._iSplLvlAdd = 0;
	items[v6]._iPrePower = -1;
	items[v6]._iSufPower = -1;
	items[v6]._iRequest = 0;
	items[v6]._iFMinDam = 0;
	items[v6]._iFMaxDam = 0;
	items[v6]._iLMinDam = 0;
	items[v6]._iLMaxDam = 0;
	items[v6]._iPLEnAc = 0;
	items[v6]._iPLMana = 0;
	items[v6]._iPLHP = 0;
	if ( v12 == 24 )
		GetBookSpell(ia, lvl);
	if ( items[v6]._itype == ITYPE_GOLD )
	{
		if ( gnDifficulty )
		{
			v16 = lvl;
		}
		else
		{
			_LOBYTE(v12) = 21;
			v15 = random(v12, 10 * currlevel);
			v12 = 5 * currlevel;
			v16 = v12 + v15;
		}
		if ( gnDifficulty == DIFF_NIGHTMARE )
		{
			_LOBYTE(v12) = 21;
			v17 = random(v12, 10 * (currlevel + 16));
			v12 = 5 * (currlevel + 16);
			v16 = v12 + v17;
		}
		if ( gnDifficulty == DIFF_HELL )
		{
			_LOBYTE(v12) = 21;
			v16 = 5 * (currlevel + 32) + random(v12, 10 * (currlevel + 32));
		}
		if ( leveltype == 4 )
			v16 += v16 >> 3;
		if ( v16 > 5000 )
			v16 = 5000;
		items[v6]._ivalue = v16;
		if ( v16 < 2500 )
			items[v6]._iCurs = (v16 > 1000) + 4;
		else
			items[v6]._iCurs = 6;
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (00420B17) --------------------------------------------------------
int __fastcall RndPL(int param1, int param2)
{
	int v2; // esi
	int v3; // edx

	v2 = param1;
	v3 = param2 - param1;
	_LOBYTE(param1) = 22;
	return v2 + random(param1, v3 + 1);
}

//----- (00420B28) --------------------------------------------------------
int __fastcall PLVal(int pv, int p1, int p2, int minv, int maxv)
{
	if ( p1 == p2 )
		return minv;
	if ( minv == maxv )
		return minv;
	return minv + (maxv - minv) * (100 * (pv - p1) / (p2 - p1)) / 100;
}

//----- (00420B68) --------------------------------------------------------
void __fastcall SaveItemPower(int i, int power, int param1, int param2, int minval, int maxval, int multval)
{
	int v7; // edi
	int v8; // esi
	int v9; // eax
	int v10; // ebx
	int *v11; // eax
	int *v12; // eax
	int v13; // edi
	int v14; // eax
	int v15; // edi
	int v16; // eax
	int v17; // eax
	int v18; // ecx
	int v19; // edx
	int v20; // edi
	int *v21; // edx
	int v22; // eax
	int v23; // eax
	int v24; // eax
	int v25; // eax
	int v26; // eax
	int v27; // eax
	int v28; // ecx
	int *v29; // eax
	int v30; // ecx
	int *v31; // eax
	int v32; // ecx
	int v33; // eax
	int v34; // ST18_4
	int v35; // eax
	int v36; // ecx
	int v37; // edx
	signed int v38; // ecx
	int v39; // eax
	int v40; // eax
	int v41; // ecx
	int *v42; // eax
	int v43; // esi

	v7 = power;
	v8 = i;
	v9 = RndPL(param1, param2);
	v10 = v9;
	switch ( v7 )
	{
		case IPL_TOHIT:
			v11 = &items[v8]._iPLToHit;
			goto LABEL_115;
		case IPL_TOHIT_CURSE:
			v12 = &items[v8]._iPLToHit;
			goto LABEL_62;
		case IPL_DAMP:
			v11 = &items[v8]._iPLDam;
			goto LABEL_115;
		case IPL_DAMP_CURSE:
			v12 = &items[v8]._iPLDam;
			goto LABEL_62;
		case IPL_TOHIT_DAMP:
			v10 = RndPL(param1, param2);
			v13 = v8;
			items[v13]._iPLDam += v10;
			if ( param1 == 20 )
				v14 = RndPL(1, 5);
			else
				v14 = param1;
			if ( param1 == 36 )
				v14 = RndPL(6, 10);
			if ( param1 == 51 )
				v14 = RndPL(11, 15);
			if ( param1 == 66 )
				v14 = RndPL(16, 20);
			if ( param1 == 81 )
				v14 = RndPL(21, 30);
			if ( param1 == 96 )
				v14 = RndPL(31, 40);
			if ( param1 == 111 )
				v14 = RndPL(41, 50);
			if ( param1 == 126 )
				v14 = RndPL(51, 75);
			if ( param1 == 151 )
				v14 = RndPL(76, 100);
			items[v13]._iPLToHit += v14;
			break;
		case IPL_TOHIT_DAMP_CURSE:
			v15 = v8;
			items[v15]._iPLDam -= v9;
			if ( param1 == 25 )
				v16 = RndPL(1, 5);
			else
				v16 = param1;
			if ( param1 == 50 )
				v16 = RndPL(6, 10);
			items[v15]._iPLToHit -= v16;
			break;
		case IPL_ACP:
			v11 = &items[v8]._iPLAC;
			goto LABEL_115;
		case IPL_ACP_CURSE:
			v12 = &items[v8]._iPLAC;
			goto LABEL_62;
		case IPL_FIRERES:
			v11 = &items[v8]._iPLFR;
			goto LABEL_115;
		case IPL_LIGHTRES:
			v11 = &items[v8]._iPLLR;
			goto LABEL_115;
		case IPL_MAGICRES:
			v11 = &items[v8]._iPLMR;
			goto LABEL_115;
		case IPL_ALLRES:
			v17 = v8;
			items[v17]._iPLFR += v10;
			v18 = items[v8]._iPLFR;
			items[v17]._iPLLR += v10;
			items[v17]._iPLMR += v10;
			v19 = items[v8]._iPLLR;
			v20 = items[v8]._iPLMR;
			if ( v18 < 0 )
				items[v17]._iPLFR = 0;
			if ( v19 < 0 )
				items[v17]._iPLLR = 0;
			if ( v20 < 0 )
				items[v17]._iPLMR = 0;
			break;
		case IPL_SPLLVLADD:
			items[v8]._iSplLvlAdd = v9;
			break;
		case IPL_CHARGES:
			v21 = &items[v8]._iCharges;
			v22 = param1 * *v21;
			*v21 = v22;
			items[v8]._iMaxCharges = v22;
			break;
		case IPL_FIREDAM:
			v24 = v8;
			items[v24]._iFlags |= 0x10u;
			goto LABEL_77;
		case IPL_LIGHTDAM:
			v25 = v8;
			items[v25]._iFlags |= 0x20u;
			goto LABEL_79;
		case IPL_STR:
			v11 = &items[v8]._iPLStr;
			goto LABEL_115;
		case IPL_STR_CURSE:
			v12 = &items[v8]._iPLStr;
			goto LABEL_62;
		case IPL_MAG:
			v11 = &items[v8]._iPLMag;
			goto LABEL_115;
		case IPL_MAG_CURSE:
			v12 = &items[v8]._iPLMag;
			goto LABEL_62;
		case IPL_DEX:
			v11 = &items[v8]._iPLDex;
			goto LABEL_115;
		case IPL_DEX_CURSE:
			v12 = &items[v8]._iPLDex;
			goto LABEL_62;
		case IPL_VIT:
			v11 = &items[v8]._iPLVit;
			goto LABEL_115;
		case IPL_VIT_CURSE:
			v12 = &items[v8]._iPLVit;
			goto LABEL_62;
		case IPL_ATTRIBS:
			v26 = v8;
			items[v26]._iPLStr += v10;
			items[v26]._iPLMag += v10;
			items[v26]._iPLDex += v10;
			items[v26]._iPLVit += v10;
			break;
		case IPL_ATTRIBS_CURSE:
			v27 = v8;
			items[v27]._iPLStr -= v10;
			items[v27]._iPLMag -= v10;
			items[v27]._iPLDex -= v10;
			items[v27]._iPLVit -= v10;
			break;
		case IPL_GETHIT:
			v11 = &items[v8]._iPLGetHit;
			goto LABEL_115;
		case IPL_GETHIT_CURSE:
			v12 = &items[v8]._iPLGetHit;
			goto LABEL_62;
		case IPL_LIFE:
			v28 = v9 << 6;
			v29 = &items[v8]._iPLHP;
			goto LABEL_73;
		case IPL_LIFE_CURSE:
			v30 = v9 << 6;
			v31 = &items[v8]._iPLHP;
			goto LABEL_75;
		case IPL_MANA:
			items[v8]._iPLMana += v9 << 6;
			goto LABEL_92;
		case IPL_MANA_CURSE:
			items[v8]._iPLMana -= v9 << 6;
			goto LABEL_92;
		case IPL_DUR:
			v32 = v8;
			v33 = items[v8]._iMaxDur;
			v34 = v33;
			v35 = v10 * v33 / 100;
			items[v32]._iDurability += v35;
			items[v32]._iMaxDur = v35 + v34;
			break;
		case IPL_DUR_CURSE:
			v36 = v8;
			v37 = items[v8]._iMaxDur - v9 * items[v8]._iMaxDur / 100;
			items[v8]._iMaxDur = v37;
			if ( v37 < 1 )
				items[v36]._iMaxDur = 1;
			items[v36]._iDurability = items[v36]._iMaxDur;
			break;
		case IPL_INDESTRUCTIBLE:
			v38 = 255;
			goto LABEL_119;
		case IPL_LIGHT:
			v28 = param1;
			v29 = &items[v8]._iPLLight;
LABEL_73:
			*v29 += v28;
			break;
		case IPL_LIGHT_CURSE:
			v30 = param1;
			v31 = &items[v8]._iPLLight;
LABEL_75:
			*v31 -= v30;
			break;
		case IPL_FIRE_ARROWS:
			v24 = v8;
			items[v24]._iFlags |= 8u;
LABEL_77:
			items[v24]._iFMinDam = param1;
			items[v24]._iFMaxDam = param2;
			break;
		case IPL_LIGHT_ARROWS:
			v25 = v8;
			_HIBYTE(items[v8]._iFlags) |= 2u;
LABEL_79:
			items[v25]._iLMinDam = param1;
			items[v25]._iLMaxDam = param2;
			break;
		case IPL_INVCURS:
			items[v8]._iCurs = param1;
			break;
		case IPL_THORNS:
			_HIBYTE(items[v8]._iFlags) |= 4u;
			break;
		case IPL_NOMANA:
			_HIBYTE(items[v8]._iFlags) |= 8u;
			goto LABEL_92;
		case IPL_NOHEALPLR:
			BYTE1(items[v8]._iFlags) |= 1u;
			break;
		case IPL_ABSHALFTRAP:
			_HIBYTE(items[v8]._iFlags) |= 0x10u;
			break;
		case IPL_KNOCKBACK:
			BYTE1(items[v8]._iFlags) |= 8u;
			break;
		case IPL_NOHEALMON:
			BYTE1(items[v8]._iFlags) |= 0x10u;
			break;
		case IPL_STEALMANA:
			if ( param1 == 3 )
				BYTE1(items[v8]._iFlags) |= 0x20u;
			if ( param1 == 5 )
				BYTE1(items[v8]._iFlags) |= 0x40u;
LABEL_92:
			drawmanaflag = 1;
			break;
		case IPL_STEALLIFE:
			if ( param1 == 3 )
				BYTE1(items[v8]._iFlags) |= 0x80u;
			if ( param1 == 5 )
				BYTE2(items[v8]._iFlags) |= 1u;
			drawhpflag = 1;
			break;
		case IPL_TARGAC:
			v11 = &items[v8]._iPLEnAc;
			goto LABEL_115;
		case IPL_FASTATTACK:
			if ( param1 == 1 )
				BYTE2(items[v8]._iFlags) |= 2u;
			if ( param1 == 2 )
				BYTE2(items[v8]._iFlags) |= 4u;
			if ( param1 == 3 )
				BYTE2(items[v8]._iFlags) |= 8u;
			if ( param1 == 4 )
				BYTE2(items[v8]._iFlags) |= 0x10u;
			break;
		case IPL_FASTRECOVER:
			if ( param1 == 1 )
				BYTE2(items[v8]._iFlags) |= 0x20u;
			if ( param1 == 2 )
				BYTE2(items[v8]._iFlags) |= 0x40u;
			if ( param1 == 3 )
				BYTE2(items[v8]._iFlags) |= 0x80u;
			break;
		case IPL_FASTBLOCK:
			_HIBYTE(items[v8]._iFlags) |= 1u;
			break;
		case IPL_DAMMOD:
			v11 = &items[v8]._iPLDamMod;
LABEL_115:
			*v11 += v10;
			break;
		case IPL_RNDARROWVEL:
			items[v8]._iFlags |= 4u;
			break;
		case IPL_SETDAM:
			v39 = v8;
			items[v39]._iMinDam = param1;
			items[v39]._iMaxDam = param2;
			break;
		case IPL_SETDUR:
			v38 = param1;
LABEL_119:
			v40 = v8;
			items[v40]._iDurability = v38;
			items[v40]._iMaxDur = v38;
			break;
		case IPL_NOMINSTR:
			items[v8]._iMinStr = 0;
			break;
		case IPL_SPELL:
			v23 = v8;
			items[v23]._iSpell = param1;
			items[v23]._iCharges = param1;
			items[v23]._iMaxCharges = param2;
			break;
		case IPL_FASTSWING:
			BYTE2(items[v8]._iFlags) |= 8u;
			break;
		case IPL_ONEHAND:
			items[v8]._iLoc = ILOC_ONEHAND;
			break;
		case IPL_3XDAMVDEM:
			_HIBYTE(items[v8]._iFlags) |= 0x40u;
			break;
		case IPL_ALLRESZERO:
			_HIBYTE(items[v8]._iFlags) |= 0x80u;
			break;
		case IPL_DRAINLIFE:
			items[v8]._iFlags |= 0x40u;
			break;
		case IPL_RNDSTEALLIFE:
			items[v8]._iFlags |= 2u;
			break;
		case IPL_INFRAVISION:
			items[v8]._iFlags |= 1u;
			break;
		case IPL_SETAC:
			items[v8]._iAC = v9;
			break;
		case IPL_ADDACLIFE:
			items[v8]._iPLHP = (plr[myplr]._pIBonusAC + plr[myplr]._pIAC + plr[myplr]._pDexterity / 5) << 6;
			break;
		case IPL_ADDMANAAC:
			items[v8]._iAC += (plr[myplr]._pMaxManaBase >> 6) / 10;
			break;
		case IPL_FIRERESCLVL:
			v41 = 30 - plr[myplr]._pLevel;
			v42 = &items[v8]._iPLFR;
			*v42 = v41;
			if ( v41 < 0 )
				*v42 = 0;
			break;
		case IPL_AC_CURSE:
			v12 = &items[v8]._iAC;
LABEL_62:
			*v12 -= v10;
			break;
		default:
			break;
	}
	v43 = v8;
	if ( items[v43]._iVAdd1 || items[v43]._iVMult1 )
	{
		items[v43]._iVAdd2 = PLVal(v10, param1, param2, minval, maxval);
		items[v43]._iVMult2 = multval;
	}
	else
	{
		items[v43]._iVAdd1 = PLVal(v10, param1, param2, minval, maxval);
		items[v43]._iVMult1 = multval;
	}
}

//----- (004215EF) --------------------------------------------------------
void __fastcall GetItemPower(int i, int minlvl, int maxlvl, __int32 flgs, int onlygood)
{
	int v5; // eax
	int v6; // ecx
	int v7; // esi
	int v8; // eax
	int v9; // ecx
	unsigned char v10; // bl
	int v11; // edx
	int v12; // edi
	int *v13; // eax
	__int32 v14; // ecx
	int v15; // eax
	int v16; // edi
	char *v17; // ebx
	int v18; // esi
	int v19; // ecx
	int v20; // ST14_4
	int v21; // edi
	int v22; // esi
	int *v23; // eax
	__int32 v24; // ecx
	int v25; // eax
	int v26; // edi
	int v27; // esi
	char *v28; // ebx
	int v29; // ecx
	int v30; // ST14_4
	int v31; // esi
	char *v32; // edi
	int v33; // ebx
	int v34; // esi
	int v35[256]; // [esp+4h] [ebp-494h]
	char v36[128]; // [esp+404h] [ebp-94h]
	int v37; // [esp+484h] [ebp-14h]
	int v38; // [esp+488h] [ebp-10h]
	int v39; // [esp+48Ch] [ebp-Ch]
	int v40; // [esp+490h] [ebp-8h]
	int ia; // [esp+494h] [ebp-4h]

	v37 = minlvl;
	ia = i;
	_LOBYTE(i) = 23;
	v5 = random(i, 4);
	_LOBYTE(v6) = 23;
	v7 = v5;
	v8 = random(v6, 3);
	v38 = v8;
	if ( v7 && !v8 )
	{
		_LOBYTE(v9) = 23;
		if ( random(v9, 2) )
			v38 = 1;
		else
			v7 = 0;
	}
	v40 = -1;
	v39 = -1;
	v10 = 0;
	if ( !onlygood )
	{
		_LOBYTE(v9) = 0;
		if ( random(v9, 3) )
			onlygood = 1;
	}
	if ( !v7 )
	{
		v11 = 0;
		if ( *(_DWORD *)&PL_Prefix[0].PLPower != -1 )
		{
			v12 = *(_DWORD *)&PL_Prefix[0].PLPower;
			v13 = &PL_Prefix[0].PLMinLvl;
			do
			{
				v14 = flgs;
				if ( flgs & v13[1] )
				{
					v14 = *(char *)v13;
					if ( v14 >= v37 && v14 <= maxlvl && (!onlygood || v13[4]) && (flgs != 256 || v12 != 15) )
					{
						v35[v11++] = v7;
						if ( v13[3] )
							v35[v11++] = v7;
					}
				}
				v12 = v13[9];
				v13 += 12;
				++v7;
			}
			while ( v12 != -1 );
			if ( v11 )
			{
				_LOBYTE(v14) = 23;
				v15 = random(v14, v11);
				v16 = ia;
				v40 = v35[v15];
				v17 = items[ia]._iIName;
				v18 = v40;
				sprintf(v36, "%s %s", PL_Prefix[v40].PLName, items[ia]._iIName);
				strcpy(v17, v36);
				v19 = ia;
				v20 = PL_Prefix[v18].PLMultVal;
				items[v16]._iMagical = 1;
				SaveItemPower(
					v19,
					*(_DWORD *)&PL_Prefix[v18].PLPower,
					PL_Prefix[v18].PLParam1,
					PL_Prefix[v18].PLParam2,
					PL_Prefix[v18].PLMinVal,
					PL_Prefix[v18].PLMaxVal,
					v20);
				v10 = PL_Prefix[v18].PLGOE;
				items[v16]._iPrePower = PL_Prefix[v18].PLPower;
			}
		}
	}
	v21 = 0;
	if ( v38 )
	{
		v22 = 0;
		if ( *(_DWORD *)&PL_Suffix[0].PLPower != -1 )
		{
			v23 = &PL_Suffix[0].PLMinLvl;
			do
			{
				v24 = flgs;
				if ( flgs & v23[1] )
				{
					v24 = *(char *)v23;
					if ( v24 >= v37 && v24 <= maxlvl && (v10 | *((_BYTE *)v23 + 8)) != 17 && (!onlygood || v23[4]) )
						v35[v22++] = v21;
				}
				v23 += 12;
				++v21;
			}
			while ( *(v23 - 3) != -1 );
			if ( v22 )
			{
				_LOBYTE(v24) = 23;
				v25 = random(v24, v22);
				v26 = ia;
				v39 = v35[v25];
				v27 = v39;
				v28 = items[ia]._iIName;
				sprintf(v36, "%s of %s", items[ia]._iIName, PL_Suffix[v39].PLName);
				strcpy(v28, v36);
				v29 = ia;
				v30 = PL_Suffix[v27].PLMultVal;
				items[v26]._iMagical = 1;
				SaveItemPower(
					v29,
					*(_DWORD *)&PL_Suffix[v27].PLPower,
					PL_Suffix[v27].PLParam1,
					PL_Suffix[v27].PLParam2,
					PL_Suffix[v27].PLMinVal,
					PL_Suffix[v27].PLMaxVal,
					v30);
				items[v26]._iSufPower = PL_Suffix[v27].PLPower;
			}
		}
	}
	v31 = ia;
	v32 = items[ia]._iIName;
	if ( control_WriteStringToBuffer(items[ia]._iIName) )
	{
		v33 = v40;
		v34 = v39;
	}
	else
	{
		strcpy(v32, AllItemsList[items[v31].IDidx].iSName);
		v33 = v40;
		if ( v40 != -1 )
		{
			sprintf(v36, "%s %s", PL_Prefix[v40].PLName, v32);
			strcpy(v32, v36);
		}
		v34 = v39;
		if ( v39 != -1 )
		{
			sprintf(v36, "%s of %s", v32, PL_Suffix[v39].PLName);
			strcpy(v32, v36);
		}
	}
	if ( v33 != -1 || v34 != -1 )
		CalcItemValue(ia);
}
// 4215EF: using guessed type int var_494[256];

//----- (0042191C) --------------------------------------------------------
void __fastcall GetItemBonus(int i, int idata, int minlvl, int maxlvl, int onlygood)
{
	signed int v5; // edx

	if ( items[i]._iClass != 4 )
	{
		v5 = minlvl;
		if ( minlvl > 25 )
			v5 = 25;
		switch ( items[i]._itype )
		{
			case ITYPE_SWORD:
			case ITYPE_AXE:
			case ITYPE_MACE:
				GetItemPower(i, v5, maxlvl, 4096, onlygood);
				break;
			case ITYPE_BOW:
				GetItemPower(i, v5, maxlvl, 16, onlygood);
				break;
			case ITYPE_SHIELD:
				GetItemPower(i, v5, maxlvl, 0x10000, onlygood);
				break;
			case ITYPE_LARMOR:
			case ITYPE_HELM:
			case ITYPE_MARMOR:
			case ITYPE_HARMOR:
				GetItemPower(i, v5, maxlvl, 0x100000, onlygood);
				break;
			case ITYPE_STAFF:
				GetStaffSpell(i, maxlvl, onlygood);
				break;
			case ITYPE_RING:
			case ITYPE_AMULET:
				GetItemPower(i, v5, maxlvl, 1, onlygood);
				break;
			default:
				return;
		}
	}
}

//----- (004219C1) --------------------------------------------------------
void __fastcall SetupItem(int i)
{
	int v1; // ecx
	int v2; // esi
	int v3; // eax
	int v4; // edx
	int v5; // eax
	bool v6; // zf

	v1 = i;
	v2 = myplr;
	v3 = ItemCAnimTbl[items[v1]._iCurs];
	items[v1]._iAnimWidth = 96;
	items[v1]._iAnimXOff = 16;
	v4 = Item2Frm[v3];
	v5 = ItemAnimLs[v3];
	items[v1].ItemFrame = v4;
	v6 = plr[v2].pLvlLoad == 0;
	items[v1]._iAnimLen = v5;
	items[v1]._iIdentified = 0;
	items[v1]._iPostDraw = 0;
	if ( v6 )
	{
		items[v1]._iSelFlag = 0;
		v5 = 1;
		items[v1]._iAnimFlag = 1;
	}
	else
	{
		items[v1]._iAnimFlag = 0;
		items[v1]._iSelFlag = 1;
	}
	items[v1]._iAnimFrame = v5;
}

//----- (00421A4B) --------------------------------------------------------
int __fastcall RndItem(int monster_num)
{
	int v1; // edi
	int v3; // ecx
	int v4; // ecx
	int v5; // esi
	int v6; // edx
	int *v7; // eax
	int v8; // ecx
	int v9[512]; // [esp+4h] [ebp-800h]

	v1 = monster_num;
	_LOWORD(monster_num) = monster[monster_num].MData->mTreasure;
	if ( (monster_num & 0x8000) != 0 )
		return -1 - (monster_num & 0xFFF);
	if ( monster_num & 0x4000 )
		return 0;
	_LOBYTE(monster_num) = 24;
	if ( random(monster_num, 100) > 40 )
		return 0;
	_LOBYTE(v3) = 24;
	if ( random(v3, 100) > 25 )
		return 1;
	v5 = 0;
	v6 = 0;
	if ( AllItemsList[0].iLoc != ILOC_INVALID )
	{
		v7 = &AllItemsList[0].iMinMLvl;
		do
		{
			v8 = *(v7 - 6);
			if ( v8 == 2 && SLOBYTE(monster[v1].mLevel) >= *(_BYTE *)v7 )
				v9[v5++] = v6;
			if ( v8 && SLOBYTE(monster[v1].mLevel) >= *(_BYTE *)v7 )
				v9[v5++] = v6;
			v4 = v7[9];
			if ( v4 == 32 && gbMaxPlayers == 1 )
				--v5;
			if ( v4 == 34 && gbMaxPlayers == 1 )
				--v5;
			v7 += 19;
			++v6;
		}
		while ( *((_BYTE *)v7 - 19) != -1 );
	}
	_LOBYTE(v4) = 24;
	return v9[random(v4, v5)] + 1;
}
// 679660: using guessed type char gbMaxPlayers;
// 421A4B: using guessed type int var_800[512];

//----- (00421B32) --------------------------------------------------------
int __fastcall RndUItem(int m)
{
	short v1; // dx
	int v3; // edx
	int v4; // ebp
	unsigned char *v5; // esi
	signed int v6; // edi
	char v7; // al
	bool v8; // sf
	unsigned char v9; // of
	int v10; // ebx
	int v11; // eax
	unsigned char v12; // bl
	int v13; // ebx
	int v14[512]; // [esp+0h] [ebp-800h]

	if ( m != -1 )
	{
		v1 = monster[m].MData->mTreasure;
		if ( v1 < 0 && gbMaxPlayers == 1 )
			return -1 - (v1 & 0xFFF);
	}
	v3 = 0;
	v4 = 0;
	if ( AllItemsList[0].iLoc != -1 )
	{
		v5 = &AllItemsList[0].itype;
		do
		{
			v6 = 1;
			if ( !*((_DWORD *)v5 - 3) )
				v6 = 0;
			if ( m == -1 )
			{
				v10 = (char)v5[12];
				v11 = 2 * currlevel;
				v9 = __OFSUB__(v11, v10);
				v8 = v11 - v10 < 0;
			}
			else
			{
				v7 = monster[m].mLevel;
				v9 = __OFSUB__(v7, v5[12]);
				v8 = (char)(v7 - v5[12]) < 0;
			}
			if ( v8 ^ v9 )
				v6 = 0;
			v12 = *v5;
			if ( !*v5 )
				v6 = 0;
			if ( v12 == 11 )
				v6 = 0;
			if ( v12 == 14 )
				v6 = 0;
			if ( *((_DWORD *)v5 + 11) == 24 )
				v6 = 1;
			v13 = *((_DWORD *)v5 + 12);
			if ( v13 == 32 && gbMaxPlayers == 1 )
				v6 = 0;
			if ( v13 == 34 && gbMaxPlayers == 1 )
				v6 = 0;
			if ( v6 )
				v14[v3++] = v4;
			v5 += 76;
			++v4;
		}
		while ( *(v5 - 7) != -1 );
	}
	_LOBYTE(m) = 25;
	return v14[random(m, v3)];
}
// 679660: using guessed type char gbMaxPlayers;
// 421B32: using guessed type int var_800[512];

//----- (00421C2A) --------------------------------------------------------
int __cdecl RndAllItems()
{
	int v1; // esi
	int v2; // edi
	char v3; // dl
	int *v4; // eax
	int v5[512]; // [esp+0h] [ebp-800h]

	if ( random(26, 100) > 25 )
		return 0;
	v1 = 0;
	v2 = 0;
	if ( AllItemsList[0].iLoc != ILOC_INVALID )
	{
		v3 = gbMaxPlayers;
		v4 = &AllItemsList[0].iSpell;
		do
		{
			if ( *(v4 - 15) && 2 * currlevel >= *((char *)v4 - 36) )
				v5[v1++] = v2;
			if ( *v4 == 32 && v3 == 1 )
				--v1;
			if ( *v4 == 34 && v3 == 1 )
				--v1;
			v4 += 19;
			++v2;
		}
		while ( *((_BYTE *)v4 - 55) != -1 );
	}
	return v5[random(26, v1)];
}
// 679660: using guessed type char gbMaxPlayers;
// 421C2A: using guessed type int var_800[512];

//----- (00421CB7) --------------------------------------------------------
int __fastcall RndTypeItems(int itype, int imid)
{
	int v2; // edi
	int *v3; // eax
	signed int v4; // esi
	int v6[512]; // [esp+4h] [ebp-80Ch]
	int v7; // [esp+804h] [ebp-Ch]
	int v8; // [esp+808h] [ebp-8h]
	int max; // [esp+80Ch] [ebp-4h]

	max = 0;
	v2 = 0;
	v7 = itype;
	if ( AllItemsList[0].iLoc != ILOC_INVALID )
	{
		v8 = 2 * currlevel;
		v3 = &AllItemsList[0].iMinMLvl;
		do
		{
			v4 = 1;
			if ( !*(v3 - 6) )
				v4 = 0;
			if ( v8 < *(char *)v3 )
				v4 = 0;
			itype = *((char *)v3 - 12);
			if ( itype != v7 )
				v4 = 0;
			if ( imid != -1 && v3[8] != imid )
				v4 = 0;
			if ( v4 )
			{
				itype = max++;
				v6[itype] = v2;
			}
			v3 += 19;
			++v2;
		}
		while ( *((_BYTE *)v3 - 19) != -1 );
	}
	_LOBYTE(itype) = 27;
	return v6[random(itype, max)];
}
// 421CB7: using guessed type int var_80C[512];

//----- (00421D41) --------------------------------------------------------
void __fastcall GetUniqueItem(int i, int uid)
{
	int v2; // esi
	int v3; // ebx
	char v4; // al
	int *v5; // edi
	int v6; // ecx
	char *v7; // esi
	char v8; // dl
	char *v9; // ecx
	int v10; // eax
	char v11[128]; // [esp+8h] [ebp-84h]
	int v12; // [esp+88h] [ebp-4h]
	int v13; // [esp+94h] [ebp+8h]
	int v14; // [esp+98h] [ebp+Ch]

	v12 = uid;
	v2 = i;
	_LOBYTE(i) = 28;
	if ( random(i, 100) <= v13 )
	{
		v3 = 0;
		memset(v11, 0, 0x80u);
		v4 = UniqueItemList[0].UIItemId;
		if ( UniqueItemList[0].UIItemId != -1 )
		{
			v5 = UniqueItemFlag;
			v6 = items[v2].IDidx;
			v7 = &UniqueItemList[0].UIItemId;
			v8 = AllItemsList[v6].iItemId;
			v9 = v11;
			do
			{
				if ( v4 == v8 && v12 >= *((char *)v7 + 1) && (v14 || !*v5 || gbMaxPlayers != 1) )
				{
					*v9 = 1;
					++v3;
				}
				v7 += 84;
				++v5;
				++v9;
				v4 = *v7;
			}
			while ( *v7 != -1 );
			if ( v3 )
			{
				_LOBYTE(v9) = 29;
				random((int)v9, 10);
				v10 = 0;
				if ( v3 > 0 )
				{
					while ( 1 )
					{
						if ( v11[v10] )
							--v3;
						if ( v3 <= 0 )
							break;
						if ( ++v10 == 128 )
							v10 = 0;
					}
				}
			}
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;
// 421D41: using guessed type char var_84[128];

//----- (00421E11) --------------------------------------------------------
void __fastcall SpawnUnique(int uid, int x, int y)
{
	int v3; // esi
	int v4; // ST04_4
	int v5; // edi
	int v6; // edi
	bool v7; // zf
	int v8; // [esp+10h] [ebp-4h]

	v3 = x;
	v8 = x;
	v4 = UniqueItemList[x].UIParam2;
	UniqueItemFlag[x] = 1;
	v5 = uid;
	SaveItemPower(uid, (char)UniqueItemList[x].UIPower1, UniqueItemList[x].UIParam1, v4, 0, 0, 1);
	if ( UniqueItemList[v3].UINumPL > 1 )
		SaveItemPower(
			v5,
			(char)UniqueItemList[v3].UIPower2,
			UniqueItemList[v3].UIParam3,
			UniqueItemList[v3].UIParam4,
			0,
			0,
			1);
	if ( UniqueItemList[v3].UINumPL > 2 )
		SaveItemPower(
			v5,
			(char)UniqueItemList[v3].UIPower3,
			UniqueItemList[v3].UIParam5,
			UniqueItemList[v3].UIParam6,
			0,
			0,
			1);
	if ( UniqueItemList[v3].UINumPL > 3 )
		SaveItemPower(
			v5,
			(char)UniqueItemList[v3].UIPower4,
			UniqueItemList[v3].UIParam7,
			UniqueItemList[v3].UIParam8,
			0,
			0,
			1);
	if ( UniqueItemList[v3].UINumPL > 4 )
		SaveItemPower(
			v5,
			(char)UniqueItemList[v3].UIPower5,
			UniqueItemList[v3].UIParam9,
			UniqueItemList[v3].UIParam10,
			0,
			0,
			1);
	if ( UniqueItemList[v3].UINumPL > 5 )
		SaveItemPower(
			v5,
			(char)UniqueItemList[v3].UIPower6,
			UniqueItemList[v3].UIParam11,
			UniqueItemList[v3].UIParam12,
			0,
			0,
			1);
	v6 = v5;
	strcpy(items[v6]._iIName, UniqueItemList[v3].UIName);
	v7 = items[v6]._iMiscId == IMISC_UNIQUE;
	items[v6]._iIvalue = UniqueItemList[v3].UIValue;
	if ( v7 )
		items[v6]._iSeed = v8;
	_HIBYTE(items[v6]._iCreateInfo) |= 2u;
	items[v6]._iUid = v8;
	items[v6]._iMagical = 2;
}

//----- (00421F5C) --------------------------------------------------------
int __fastcall CheckUnique(int i, int lvl, int uper, unsigned char recreate)
{
	int v4; // esi
	int result; // eax
	int v6; // edi
	int v7; // esi
	int *v8; // ecx
	int v9; // edx
	char v10; // al
	char *v11; // ecx
	int v12; // [esp-8h] [ebp-Ch]
	int retaddr; // [esp+4h] [ebp+0h]

	result = lvl;
	v6 = i;
	if ( numitems < 127 )
	{
		v12 = v4;
		v7 = itemavail[0];
		GetSuperItemSpace(lvl, retaddr, itemavail[0]);
		v8 = &itemavail[-numitems + 126];
		v9 = 0;
		itemactive[numitems] = v7;
		v10 = UniqueItemList[v6].UIItemId;
		itemavail[0] = *v8;
		if ( AllItemsList[0].iItemId != v10 )
		{
			v11 = &AllItemsList[0].iItemId;
			do
			{
				v11 += 76;
				++v9;
			}
			while ( *v11 != v10 );
		}
		GetItemAttrs(v7, v9, currlevel);
		SpawnUnique(v7, v6, v12);
		SetupItem(v7);
		++numitems;
	}
	return result;
}
// 421F5C: could not find valid save-restore pair for esi

//----- (00421FE6) --------------------------------------------------------
void __fastcall ItemRndDur(int ii)
{
	int v1; // esi
	int v2; // eax

	v1 = ii;
	v2 = items[ii]._iDurability;
	if ( v2 )
	{
		if ( v2 != 255 )
		{
			_LOBYTE(ii) = 0;
			items[v1]._iDurability = random(ii, items[v1]._iMaxDur >> 1) + (items[v1]._iMaxDur >> 2) + 1;
		}
	}
}

//----- (00422024) --------------------------------------------------------
void __fastcall SetupAllItems(int ii, int idx, int iseed, int lvl, int uper, int onlygood, int recreate, int pregen)
{
	int v8; // esi
	int v9; // ecx
	int v10; // edi
	int v11; // ecx
	int v12; // eax
	int v13; // eax
	int v14; // [esp-4h] [ebp-18h]
	int idata; // [esp+Ch] [ebp-8h]
	int i; // [esp+10h] [ebp-4h]

	i = ii;
	v8 = ii;
	idata = idx;
	items[ii]._iSeed = iseed;
	SetRndSeed(iseed);
	GetItemAttrs(i, idata, lvl >> 1);
	items[v8]._iCreateInfo = lvl;
	if ( pregen )
		items[v8]._iCreateInfo = lvl | 0x8000;
	if ( onlygood )
		_LOBYTE(items[v8]._iCreateInfo) |= 0x40u;
	if ( uper == 15 )
	{
		_LOBYTE(items[v8]._iCreateInfo) |= 0x80u;
	}
	else if ( uper == 1 )
	{
		_HIBYTE(items[v8]._iCreateInfo) |= 1u;
	}
	if ( items[v8]._iMiscId == IMISC_UNIQUE )
	{
		if ( items[v8]._iLoc != ILOC_UNEQUIPABLE )
			SpawnUnique(i, iseed, v14);
	}
	else
	{
		_LOBYTE(v9) = 32;
		v10 = -1;
		if ( random(v9, 100) > 10 && (_LOBYTE(v11) = 33, random(v11, 100) > lvl) || (v10 = lvl, lvl == -1) )
		{
			v12 = items[v8]._iMiscId;
			if ( v12 != IMISC_STAFF || (v10 = lvl, lvl == -1) )
			{
				if ( v12 != IMISC_RING || (v10 = lvl, lvl == -1) )
				{
					if ( v12 == IMISC_AMULET )
						v10 = lvl;
				}
			}
		}
		if ( onlygood )
			v10 = lvl;
		if ( uper == 15 )
			v10 = lvl + 4;
		if ( v10 != -1 )
		{
			GetUniqueItem(i, v10);
			if ( v13 == -1 )
			{
				GetItemBonus(i, idata, v10 >> 1, v10, onlygood);
			}
			else
			{
				SpawnUnique(i, v13, uper);
				_HIBYTE(items[v8]._iCreateInfo) |= 2u;
			}
		}
		if ( items[v8]._iMagical != 2 )
			ItemRndDur(i);
	}
	SetupItem(i);
}

//----- (0042217A) --------------------------------------------------------
void __fastcall SpawnItem(int m, int x, int y, unsigned char sendmsg)
{
	int v4; // esi
	int v5; // eax
	int v6; // edi
	int *v7; // ecx
	bool v8; // zf
	MonsterData *v9; // eax
	int v10; // eax
	int v11; // ST04_4
	int v12; // eax
	int v13; // [esp-10h] [ebp-28h]
	unsigned char v14; // [esp+0h] [ebp-18h]
	char *v15; // [esp+Ch] [ebp-Ch]
	int xa; // [esp+10h] [ebp-8h]
	int idx; // [esp+14h] [ebp-4h]

	v4 = m;
	xa = x;
	if ( !monster[m]._uniqtype && (monster[v4].MData->mTreasure >= 0 || gbMaxPlayers == 1) )
	{
		if ( quests[1]._qactive == 2 && quests[1]._qvar1 == 5 )
		{
			idx = 18;
			quests[1]._qvar1 = 6;
			goto LABEL_13;
		}
		v5 = RndItem(m);
		if ( !v5 )
			return;
		if ( v5 > 0 )
		{
			v15 = 0;
			idx = v5 - 1;
			goto LABEL_13;
		}
LABEL_10:
		CheckUnique(-1 - v5, xa, y, v14);
		return;
	}
	v5 = RndUItem(m);
	idx = v5;
	if ( v5 < 0 )
		goto LABEL_10;
	v15 = (char *)1;
LABEL_13:
	if ( numitems < 127 )
	{
		v6 = itemavail[0];
		GetSuperItemSpace(xa, y, itemavail[0]);
		v7 = &itemavail[-numitems + 126];
		v8 = monster[v4]._uniqtype == 0;
		itemactive[numitems] = v6;
		v9 = monster[v4].MData;
		itemavail[0] = *v7;
		v10 = (char)v9->mLevel;
		if ( v8 )
			v13 = 1;
		else
			v13 = 15;
		v11 = v10;
		v12 = GetRndSeed();
		SetupAllItems(v6, idx, v12, v11, v13, (int)v15, 0, 0);
		++numitems;
		if ( sendmsg )
			NetSendCmdDItem(0, v6);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00422290) --------------------------------------------------------
void __fastcall CreateItem(int uid, int x, int y)
{
	int v3; // esi
	int v4; // edi
	int v5; // esi
	int *v6; // ecx
	int v7; // edx
	char v8; // al
	char *v9; // ecx
	int v10; // [esp-8h] [ebp-Ch]
	int retaddr; // [esp+4h] [ebp+0h]

	v4 = uid;
	if ( numitems < 127 )
	{
		v10 = v3;
		v5 = itemavail[0];
		GetSuperItemSpace(x, retaddr, itemavail[0]);
		v6 = &itemavail[-numitems + 126];
		v7 = 0;
		itemactive[numitems] = v5;
		v8 = UniqueItemList[v4].UIItemId;
		itemavail[0] = *v6;
		if ( AllItemsList[0].iItemId != v8 )
		{
			v9 = &AllItemsList[0].iItemId;
			do
			{
				v9 += 76;
				++v7;
			}
			while ( *v9 != v8 );
		}
		GetItemAttrs(v5, v7, currlevel);
		SpawnUnique(v5, v4, v10);
		SetupItem(v5);
		++numitems;
		items[v5]._iMagical = 2;
	}
}
// 422290: could not find valid save-restore pair for esi

//----- (0042232B) --------------------------------------------------------
void __fastcall CreateRndItem(int x, int y, unsigned char onlygood, unsigned char sendmsg, int delta)
{
	int v5; // ebx
	int v6; // eax
	int v7; // edi
	int v8; // esi
	int *v9; // ecx
	int v10; // ST04_4
	int v11; // eax
	int xa; // [esp+8h] [ebp-4h]

	v5 = y;
	xa = x;
	if ( onlygood )
		v6 = RndUItem(-1);
	else
		v6 = RndAllItems();
	v7 = v6;
	if ( numitems < 127 )
	{
		v8 = itemavail[0];
		GetSuperItemSpace(xa, v5, itemavail[0]);
		v9 = &itemavail[-numitems + 126];
		itemactive[numitems] = v8;
		v10 = 2 * currlevel;
		itemavail[0] = *v9;
		v11 = GetRndSeed();
		SetupAllItems(v8, v7, v11, v10, 1, onlygood, 0, delta);
		if ( sendmsg )
			NetSendCmdDItem(0, v8);
		if ( delta )
			DeltaAddItem(v8);
		++numitems;
	}
}

//----- (004223D0) --------------------------------------------------------
void __fastcall SetupAllUseful(int ii, int iseed, int lvl)
{
	int v3; // ebx
	int v4; // edi
	int v5; // ecx
	int v6; // ecx
	int v7; // esi

	v3 = ii;
	v4 = ii;
	items[ii]._iSeed = iseed;
	SetRndSeed(iseed);
	_LOBYTE(v5) = 34;
	v7 = 25 - (random(v5, 2) != 0);
	if ( lvl > 1 )
	{
		_LOBYTE(v6) = 34;
		if ( !random(v6, 3) )
			v7 = 27;
	}
	GetItemAttrs(v3, v7, lvl);
	items[v4]._iCreateInfo = lvl + 384;
	SetupItem(v3);
}

//----- (0042243D) --------------------------------------------------------
void __fastcall CreateRndUseful(int pnum, int x, int y, unsigned char sendmsg)
{
	int v4; // esi
	int *v5; // ecx
	int v6; // ST00_4
	int v7; // eax

	if ( numitems < 127 )
	{
		v4 = itemavail[0];
		GetSuperItemSpace(x, y, itemavail[0]);
		v5 = &itemavail[-numitems + 126];
		itemactive[numitems] = v4;
		v6 = currlevel;
		itemavail[0] = *v5;
		v7 = GetRndSeed();
		SetupAllUseful(v4, v7, v6);
		if ( sendmsg )
			NetSendCmdDItem(0, v4);
		++numitems;
	}
}

//----- (004224A6) --------------------------------------------------------
void __fastcall CreateTypeItem(int x, int y, unsigned char onlygood, int itype, int imisc, int sendmsg, int delta)
{
	int v7; // ebx
	int v8; // edi
	int v9; // esi
	int *v10; // ecx
	int v11; // ST04_4
	int v12; // eax
	int xa; // [esp+8h] [ebp-4h]

	xa = x;
	v7 = y;
	if ( itype == ITYPE_GOLD )
		v8 = 0;
	else
		v8 = RndTypeItems(itype, imisc);
	if ( numitems < 127 )
	{
		v9 = itemavail[0];
		GetSuperItemSpace(xa, v7, itemavail[0]);
		v10 = &itemavail[-numitems + 126];
		itemactive[numitems] = v9;
		v11 = 2 * currlevel;
		itemavail[0] = *v10;
		v12 = GetRndSeed();
		SetupAllItems(v9, v8, v12, v11, 1, onlygood, 0, delta);
		if ( sendmsg )
			NetSendCmdDItem(0, v9);
		if ( delta )
			DeltaAddItem(v9);
		++numitems;
	}
}

//----- (0042254A) --------------------------------------------------------
void __fastcall TempItemGeneration(int ii, int idx, int wCI, int seed, int value)
{
	int v5; // esi
	ItemStruct *v6; // edi
	ItemStruct *v7; // esi
	int v8; // esi
	int v9; // edx
	int v10; // ebx
	int v11; // edi
	int idxa; // [esp+8h] [ebp-4h]

	idxa = idx;
	if ( idx )
	{
		if ( (_WORD)wCI )
		{
			if ( wCI & 0x7C00 )
			{
				RecreateTownItem(ii, idx, wCI, seed, value);
			}
			else if ( (wCI & 0x180) == 384 )
			{
				SetupAllUseful(ii, seed, wCI & 0x3F);
			}
			else
			{
				v8 = 0;
				v9 = 0;
				v10 = 0;
				v11 = 0;
				if ( wCI & 0x100 )
					v8 = 1;
				if ( (wCI & 0x80u) != 0 )
					v8 = 15;
				if ( wCI & 0x40 )
					v9 = 1;
				if ( wCI & 0x200 )
					v10 = 1;
				if ( (wCI & 0x8000) != 0 )
					v11 = 1;
				SetupAllItems(ii, idxa, seed, wCI & 0x3F, v8, v9, v10, v11);
			}
		}
		else
		{
			v7 = &items[ii];
			SetPlrHandItem(&items[ii], idx);
			SetPlrHandSeed(v7, seed);
		}
	}
	else
	{
		v5 = ii;
		v6 = &items[ii];
		SetPlrHandItem(&items[ii], 0);
		v6->_iSeed = seed;
		items[v5]._iCreateInfo = wCI;
		items[v5]._ivalue = value;
		if ( value < 2500 )
		{
			if ( value > 1000 )
				items[v5]._iCurs = 5;
			else
				items[v5]._iCurs = 4;
		}
		else
		{
			items[v5]._iCurs = 6;
		}
	}
}

//----- (0042265C) --------------------------------------------------------
void __fastcall RecreateEar(int ii, unsigned short ic, int iseed, unsigned char Id, int dur, int mdur, int ch, int mch, int ivalue, int ibuff)
{
	int v10; // esi
	short v11; // ST18_2
	ItemStruct *v12; // ebx

	v10 = ii;
	v11 = ic;
	v12 = &items[ii];
	SetPlrHandItem(&items[ii], 23);
	tempstr[16] = 0;
	tempstr[0] = _HIBYTE(v11) & 0x7F;
	tempstr[1] = v11 & 0x7F;
	tempstr[2] = _HIBYTE(iseed) & 0x7F;
	tempstr[3] = BYTE2(iseed) & 0x7F;
	tempstr[5] = iseed & 0x7F;
	tempstr[6] = Id & 0x7F;
	tempstr[7] = dur & 0x7F;
	tempstr[8] = mdur & 0x7F;
	tempstr[9] = ch & 0x7F;
	tempstr[10] = mch & 0x7F;
	tempstr[11] = BYTE1(ivalue) & 0x7F;
	tempstr[4] = BYTE1(iseed) & 0x7F;
	tempstr[12] = _HIBYTE(ibuff) & 0x7F;
	tempstr[13] = BYTE2(ibuff) & 0x7F;
	tempstr[14] = BYTE1(ibuff) & 0x7F;
	tempstr[15] = ibuff & 0x7F;
	sprintf(items[v10]._iName, "Ear of %s", tempstr);
	items[v10]._iCurs = ((ivalue >> 6) & 3) + 19;
	items[v10]._iCreateInfo = v11;
	items[v10]._ivalue = ivalue & 0x3F;
	v12->_iSeed = iseed;
}

//----- (00422795) --------------------------------------------------------
void __fastcall SpawnQuestItem(int itemid, int x, int y, int randarea, int selflag)
{
	int v5; // edi
	int v6; // eax
	int v7; // ecx
	int v8; // ebx
	BOOL v9; // eax
	int v10; // esi
	int v11; // eax
	int v12; // ebx
	int v13; // esi
	unsigned int v14; // eax
	int v15; // ecx
	int idata; // [esp+Ch] [ebp-8h]
	int v17; // [esp+10h] [ebp-4h]

	v5 = x;
	idata = itemid;
	if ( randarea )
	{
		v17 = 0;
		while ( 1 )
		{
LABEL_3:
			if ( ++v17 > 1000 && randarea > 1 )
				--randarea;
			_LOBYTE(itemid) = 0;
			v6 = random(itemid, 112);
			_LOBYTE(v7) = 0;
			v5 = v6;
			y = random(v7, 112);
			v8 = 0;
			v9 = 0;
			if ( randarea <= 0 )
				break;
			while ( !v9 )
			{
				v10 = 0;
				do
				{
					if ( v9 )
						break;
					_LOBYTE(v11) = ItemSpaceOk(v8 + v5, v10 + y);
					v9 = v11 == 0;
					++v10;
				}
				while ( v10 < randarea );
				if ( ++v8 >= randarea )
				{
					if ( v9 )
						goto LABEL_3;
					goto LABEL_13;
				}
			}
		}
	}
LABEL_13:
	if ( numitems < 127 )
	{
		v12 = itemavail[0];
		v13 = itemavail[0];
		v14 = 4 * numitems;
		items[v13]._ix = v5;
		itemactive[v14 / 4] = v12;
		v15 = itemavail[v14 / 0xFFFFFFFC + 126];
		items[v13]._iy = y;
		itemavail[0] = v15;
		dItem[v5][y] = v12 + 1;
		GetItemAttrs(v12, idata, currlevel);
		SetupItem(v12);
		items[v13]._iPostDraw = 1;
		if ( selflag )
		{
			items[v13]._iAnimFlag = 0;
			items[v13]._iSelFlag = selflag;
			items[v13]._iAnimFrame = items[v13]._iAnimLen;
		}
		++numitems;
	}
}

//----- (004228B1) --------------------------------------------------------
void __cdecl SpawnRock()
{
	BOOL v0; // edx
	int v1; // eax
	int v2; // ecx
	BOOL v3; // ebx
	int v4; // ebx
	int v5; // ecx
	int v6; // esi
	int *v7; // edx
	int v8; // eax
	int v9; // edi
	int v10; // ST04_4
	int v11; // [esp+8h] [ebp-4h]

	v0 = 0;
	v1 = 0;
	if ( nobjects > 0 )
	{
		v2 = v11;
		while ( !v0 )
		{
			v2 = objectactive[v1];
			v3 = object[objectactive[v1++]]._otype == OBJ_STAND;
			v0 = v3;
			if ( v1 >= nobjects )
			{
				if ( !v3 )
					return;
				break;
			}
		}
		v4 = itemavail[0];
		v5 = v2;
		v6 = itemavail[0];
		v7 = &itemavail[-numitems + 126];
		itemactive[numitems] = itemavail[0];
		v8 = object[v5]._ox;
		items[v6]._ix = v8;
		v9 = object[v5]._oy;
		itemavail[0] = *v7;
		dItem[v8][v9] = v4 + 1;
		v10 = currlevel;
		items[v6]._iy = v9;
		GetItemAttrs(v4, 9, v10);
		SetupItem(v4);
		++numitems;
		items[v6]._iSelFlag = 2;
		items[v6]._iPostDraw = 1;
		items[v6]._iAnimFrame = 11;
	}
}

//----- (00422989) --------------------------------------------------------
void __fastcall RespawnItem(int i, unsigned char FlipFlag)
{
	int v2; // esi
	int v3; // edi
	int v4; // eax
	int v5; // ecx
	int v6; // eax
	int v7; // ecx
	int v8; // ST00_4
	int v9; // edx
	int v10; // ecx
	int v11; // eax

	v2 = i;
	v3 = items[i]._iCurs;
	items[v2]._iAnimWidth = 96;
	items[v2]._iAnimXOff = 16;
	v4 = ItemCAnimTbl[v3];
	v5 = v4;
	v6 = ItemAnimLs[v4];
	v7 = v5;
	items[v2]._iAnimLen = v6;
	items[v2].ItemFrame = Item2Frm[v7];
	items[v2]._iPostDraw = 0;
	items[v2]._iRequest = 0;
	if ( FlipFlag )
	{
		items[v2]._iSelFlag = 0;
		v6 = 1;
		items[v2]._iAnimFlag = 1;
	}
	else
	{
		items[v2]._iAnimFlag = 0;
		items[v2]._iSelFlag = 1;
	}
	items[v2]._iAnimFrame = v6;
	if ( v3 == 76 )
	{
		v8 = items[v2]._iy;
		v9 = items[v2]._ix;
		v10 = ItemDropSnds[v7];
		items[v2]._iSelFlag = 1;
		PlaySfxLoc(v10, v9, v8);
	}
	v11 = items[v2]._iCurs;
	if ( v11 == 126 )
		items[v2]._iSelFlag = 1;
	if ( v11 == 140 )
		items[v2]._iSelFlag = 1;
}

//----- (00422A50) --------------------------------------------------------
void __fastcall DeleteItem(int ii, int i)
{
	int v2; // eax
	bool v3; // zf
	bool v4; // sf

	v2 = numitems - 1;
	v3 = numitems == 1;
	v4 = numitems - 1 < 0;
	itemavail[-numitems + 127] = ii;
	numitems = v2;
	if ( !v4 && !v3 && i != v2 )
		itemactive[i] = itemactive[v2];
}

//----- (00422A84) --------------------------------------------------------
void __cdecl ItemDoppel()
{
	int v0; // eax
	signed int v1; // esi
	char *v2; // ecx
	ItemStruct *v3; // edx

	if ( gbMaxPlayers != 1 )
	{
		v0 = idoppely;
		v1 = 16;
		v2 = &dItem[16][idoppely];
		do
		{
			if ( *v2 )
			{
				v3 = &item_stru_6358B8 + *v2;
				if ( v3->_ix != v1 || v3->_iy != v0 )
					*v2 = 0;
			}
			++v1;
			v2 += 112;
		}
		while ( v1 < 96 );
		idoppely = v0 + 1;
		if ( v0 == 95 )
			idoppely = 16;
	}
}
// 492EAC: using guessed type int idoppely;
// 679660: using guessed type char gbMaxPlayers;

//----- (00422ADE) --------------------------------------------------------
void __cdecl ProcessItems()
{
	int i; // edi
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	char v4; // al
	int v5; // eax

	for ( i = 0; i < numitems; ++i )
	{
		v1 = itemactive[i];
		if ( items[v1]._iAnimFlag )
		{
			v2 = items[v1]._iCurs;
			v3 = ++items[v1]._iAnimFrame;
			if ( v2 == 76 )
			{
				v4 = items[v1]._iSelFlag;
				if ( v4 == 1 && v3 == 11 )
					items[v1]._iAnimFrame = 1;
				if ( v4 == 2 && items[v1]._iAnimFrame == 21 )
					items[v1]._iAnimFrame = 11;
			}
			else
			{
				if ( v3 == items[v1]._iAnimLen >> 1 )
					PlaySfxLoc(ItemDropSnds[ItemCAnimTbl[v2]], items[v1]._ix, items[v1]._iy);
				v5 = items[v1]._iAnimLen;
				if ( items[v1]._iAnimFrame >= v5 )
				{
					items[v1]._iAnimFlag = 0;
					items[v1]._iAnimFrame = v5;
					items[v1]._iSelFlag = 1;
				}
			}
		}
	}
	ItemDoppel();
}

//----- (00422BB2) --------------------------------------------------------
void __cdecl FreeItemGFX()
{
	int *v0; // esi
	void *v1; // ecx

	v0 = Item2Frm;
	do
	{
		v1 = (void *)*v0;
		*v0 = 0;
		mem_free_dbg(v1);
		++v0;
	}
	while ( (signed int)v0 < (signed int)UniqueItemFlag );
}

//----- (00422BCF) --------------------------------------------------------
void __fastcall items_get_drop_cel(int i)
{
	items[i].ItemFrame = Item2Frm[ItemCAnimTbl[items[i]._iCurs]];
}

//----- (00422BF0) --------------------------------------------------------
void __fastcall GetItemStr(int i)
{
	int v1; // esi
	const char *v2; // eax
	char v3; // al
	int v4; // esi
	char *v5; // eax

	v1 = i;
	if ( items[i]._itype == ITYPE_GOLD )
	{
		v4 = items[v1]._ivalue;
		v5 = get_pieces_str(v4);
		sprintf(infostr, "%i gold %s", v4, v5);
	}
	else
	{
		v2 = items[v1]._iIName;
		if ( !items[v1]._iIdentified )
			v2 = items[v1]._iName;
		strcpy(infostr, v2);
		v3 = items[v1]._iMagical;
		if ( v3 == 1 )
			_LOBYTE(infoclr) = 1;
		if ( v3 == 2 )
			_LOBYTE(infoclr) = 3;
	}
}
// 4B883C: using guessed type int infoclr;

//----- (00422C63) --------------------------------------------------------
void __fastcall CheckIdentify(int pnum, int cii)
{
	int v2; // esi

	v2 = pnum;
	plr[pnum].InvBody[cii]._iIdentified = 1;
	CalcPlrInv(pnum, 1u);
	if ( v2 == myplr )
		SetCursor(1);
}

//----- (00422C9C) --------------------------------------------------------
void __fastcall DoRepair(int pnum, int cii)
{
	int v2; // ebx
	PlayerStruct *v3; // esi
	int v4; // edi

	v2 = pnum;
	v3 = &plr[pnum];
	v4 = cii;
	PlaySfxLoc(IS_REPAIR, v3->WorldX, v3->WorldY);
	RepairItem(&v3->InvBody[v4], v3->_pLevel);
	CalcPlrInv(v2, 1u);
	if ( v2 == myplr )
		SetCursor(1);
}

//----- (00422CF6) --------------------------------------------------------
void __fastcall RepairItem(ItemStruct *i, int lvl)
{
	ItemStruct *v2; // esi
	int v3; // ebx
	int v4; // eax
	int v5; // edi
	int v6; // ebp
	int v7; // eax
	bool v8; // zf
	signed int v9; // eax

	v2 = i;
	v3 = lvl;
	v4 = i->_iMaxDur;
	if ( i->_iDurability != v4 )
	{
		if ( v4 > 0 )
		{
			v5 = 0;
			v6 = lvl + 9;
			while ( 1 )
			{
				_LOBYTE(i) = 37;
				v5 += v3 + random((int)i, v3);
				v7 = v2->_iMaxDur / v6;
				if ( v7 < 1 )
					v7 = 1;
				v8 = v2->_iMaxDur == v7;
				v2->_iMaxDur -= v7;
				v9 = v2->_iMaxDur;
				if ( v8 )
					break;
				i = (ItemStruct *)(v5 + v2->_iDurability);
				if ( (signed int)i >= v9 )
				{
					v2->_iDurability += v5;
					if ( v2->_iDurability > v9 )
						v2->_iDurability = v9;
					return;
				}
			}
		}
		v2->_itype = -1;
	}
}

//----- (00422D6C) --------------------------------------------------------
void __fastcall DoRecharge(int pnum, int cii)
{
	int v2; // edi
	int v3; // edx
	PlayerStruct *v4; // eax
	ItemStruct *v5; // esi
	int v6; // ecx
	int v7; // ecx
	int v8; // eax
	int v9; // eax

	v2 = pnum;
	v3 = cii;
	v4 = &plr[pnum];
	v5 = &v4->InvBody[v3];
	if ( v4->InvBody[v3]._itype == ITYPE_STAFF )
	{
		v6 = v4->InvBody[v3]._iSpell;
		if ( v6 )
		{
			v7 = spelldata[v6].sBookLvl;
			v8 = v4->_pLevel / v7;
			_LOBYTE(v7) = 38;
			v9 = random(v7, v8);
			RechargeItem(v5, v9 + 1);
			CalcPlrInv(v2, 1u);
		}
	}
	if ( v2 == myplr )
		SetCursor(1);
}

//----- (00422DDD) --------------------------------------------------------
void __fastcall RechargeItem(ItemStruct *i, int r)
{
	bool v2; // zf
	int v3; // esi
	int v4; // eax

	if ( i->_iCharges != i->_iMaxCharges )
	{
		while ( 1 )
		{
			v2 = i->_iMaxCharges-- == 1;
			v3 = i->_iMaxCharges;
			if ( v2 )
				break;
			i->_iCharges += r;
			v4 = i->_iCharges;
			if ( v4 >= v3 )
			{
				if ( v4 > v3 )
					i->_iCharges = v3;
				return;
			}
		}
	}
}

//----- (00422E14) --------------------------------------------------------
void __fastcall PrintItemOil(char IDidx)
{
	switch ( IDidx )
	{
		case IMISC_FULLHEAL:
			strcpy(tempstr, "fully recover life");
			goto LABEL_17;
		case IMISC_HEAL:
			strcpy(tempstr, "recover partial life");
			goto LABEL_17;
		case IMISC_OLDHEAL:
			strcpy(tempstr, "recover life");
			goto LABEL_17;
		case IMISC_DEADHEAL:
			strcpy(tempstr, "deadly heal");
			goto LABEL_17;
		case IMISC_MANA:
			strcpy(tempstr, "recover mana");
			goto LABEL_17;
		case IMISC_FULLMANA:
			strcpy(tempstr, "fully recover mana");
			goto LABEL_17;
		case IMISC_ELIXSTR:
			strcpy(tempstr, "increase strength");
			goto LABEL_17;
		case IMISC_ELIXMAG:
			strcpy(tempstr, "increase magic");
			goto LABEL_17;
		case IMISC_ELIXDEX:
			strcpy(tempstr, "increase dexterity");
			goto LABEL_17;
		case IMISC_ELIXVIT:
			strcpy(tempstr, "increase vitality");
			goto LABEL_17;
		case IMISC_ELIXWEAK:
		case IMISC_ELIXDIS:
			strcpy(tempstr, "decrease strength");
			goto LABEL_17;
		case IMISC_ELIXCLUM:
			strcpy(tempstr, "decrease dexterity");
			goto LABEL_17;
		case IMISC_ELIXSICK:
			strcpy(tempstr, "decrease vitality");
			goto LABEL_17;
		case IMISC_REJUV:
			strcpy(tempstr, "recover life and mana");
			goto LABEL_17;
		case IMISC_FULLREJUV:
			strcpy(tempstr, "fully recover life and mana");
LABEL_17:
			AddPanelString(tempstr, 1);
			break;
		default:
			return;
	}
}

//----- (00422EF4) --------------------------------------------------------
void __fastcall PrintItemPower(char plidx, ItemStruct *x)
{
	ItemStruct *v2; // esi
	int *v3; // esi
	int *v4; // esi
	int v5; // esi
	const char *v6; // [esp-4h] [ebp-Ch]
	const char *v7; // [esp-4h] [ebp-Ch]
	const char *v8; // [esp-4h] [ebp-Ch]
	const char *v9; // [esp-4h] [ebp-Ch]

	v2 = x;
	switch ( plidx )
	{
		case IPL_TOHIT:
		case IPL_TOHIT_CURSE:
			sprintf(tempstr, "chance to hit : %+i%%", x->_iPLToHit);
			return;
		case IPL_DAMP:
		case IPL_DAMP_CURSE:
			sprintf(tempstr, "%+i%% damage", x->_iPLDam);
			return;
		case IPL_TOHIT_DAMP:
		case IPL_TOHIT_DAMP_CURSE:
			sprintf(tempstr, "to hit: %+i%%, %+i%% damage", x->_iPLToHit, x->_iPLDam);
			return;
		case IPL_ACP:
		case IPL_ACP_CURSE:
			sprintf(tempstr, "%+i%% armor", x->_iPLAC);
			return;
		case IPL_FIRERES:
			if ( x->_iPLFR < 75 )
				sprintf(tempstr, "Resist Fire : %+i%%", x->_iPLFR);
			if ( v2->_iPLFR >= 75 )
			{
				v6 = "Resist Fire : 75%% MAX";
				goto LABEL_11;
			}
			return;
		case IPL_LIGHTRES:
			if ( x->_iPLLR < 75 )
				sprintf(tempstr, "Resist Lightning : %+i%%", x->_iPLLR);
			if ( v2->_iPLLR >= 75 )
			{
				v6 = "Resist Lightning : 75%% MAX";
				goto LABEL_11;
			}
			return;
		case IPL_MAGICRES:
			if ( x->_iPLMR < 75 )
				sprintf(tempstr, "Resist Magic : %+i%%", x->_iPLMR);
			if ( v2->_iPLMR >= 75 )
			{
				v6 = "Resist Magic : 75%% MAX";
				goto LABEL_11;
			}
			return;
		case IPL_ALLRES:
			if ( x->_iPLFR < 75 )
				sprintf(tempstr, "Resist All : %+i%%", x->_iPLFR);
			if ( v2->_iPLFR >= 75 )
			{
				v6 = "Resist All : 75%% MAX";
LABEL_11:
				sprintf(tempstr, v6);
			}
			return;
		case IPL_SPLLVLADD:
			if ( x->_iSplLvlAdd == 1 )
				strcpy(tempstr, "spells are increased 1 level");
			if ( v2->_iSplLvlAdd == 2 )
				strcpy(tempstr, "spells are increased 2 levels");
			if ( v2->_iSplLvlAdd < 1 )
			{
				v7 = "spells are decreased 1 level";
				goto LABEL_81;
			}
			return;
		case IPL_CHARGES:
			v8 = "Extra charges";
			goto LABEL_104;
		case IPL_FIREDAM:
			sprintf(tempstr, "Fire hit damage: %i-%i", x->_iFMinDam, x->_iFMaxDam);
			return;
		case IPL_LIGHTDAM:
			sprintf(tempstr, "Lightning hit damage: %i-%i", x->_iLMinDam, x->_iLMaxDam);
			return;
		case IPL_STR:
		case IPL_STR_CURSE:
			sprintf(tempstr, "%+i to strength", x->_iPLStr);
			return;
		case IPL_MAG:
		case IPL_MAG_CURSE:
			sprintf(tempstr, "%+i to magic", x->_iPLMag);
			return;
		case IPL_DEX:
		case IPL_DEX_CURSE:
			sprintf(tempstr, "%+i to dexterity", x->_iPLDex);
			return;
		case IPL_VIT:
		case IPL_VIT_CURSE:
			sprintf(tempstr, "%+i to vitality", x->_iPLVit);
			return;
		case IPL_ATTRIBS:
		case IPL_ATTRIBS_CURSE:
			sprintf(tempstr, "%+i to all attributes", x->_iPLStr);
			return;
		case IPL_GETHIT:
		case IPL_GETHIT_CURSE:
			sprintf(tempstr, "%+i damage from enemies", x->_iPLGetHit);
			return;
		case IPL_LIFE:
		case IPL_LIFE_CURSE:
			sprintf(tempstr, "Hit Points : %+i", x->_iPLHP >> 6);
			return;
		case IPL_MANA:
		case IPL_MANA_CURSE:
			sprintf(tempstr, "Mana : %+i", x->_iPLMana >> 6);
			return;
		case IPL_DUR:
			v8 = "high durability";
			goto LABEL_104;
		case IPL_DUR_CURSE:
			v8 = "decreased durability";
			goto LABEL_104;
		case IPL_INDESTRUCTIBLE:
			v8 = "indestructible";
			goto LABEL_104;
		case IPL_LIGHT:
			sprintf(tempstr, "+%i%% light radius", 10 * x->_iPLLight);
			return;
		case IPL_LIGHT_CURSE:
			sprintf(tempstr, "-%i%% light radius", -10 * x->_iPLLight);
			return;
		case IPL_FIRE_ARROWS:
			sprintf(tempstr, "fire arrows damage: %i-%i", x->_iFMinDam, x->_iFMaxDam);
			return;
		case IPL_LIGHT_ARROWS:
			sprintf(tempstr, "lightning arrows damage %i-%i", x->_iLMinDam, x->_iLMaxDam);
			return;
		case IPL_INVCURS:
			v8 = " ";
			goto LABEL_104;
		case IPL_THORNS:
			v8 = "attacker takes 1-3 damage";
			goto LABEL_104;
		case IPL_NOMANA:
			v8 = "user loses all mana";
			goto LABEL_104;
		case IPL_NOHEALPLR:
			v8 = "you can't heal";
			goto LABEL_104;
		case IPL_ABSHALFTRAP:
			v8 = "absorbs half of trap damage";
			goto LABEL_104;
		case IPL_KNOCKBACK:
			v8 = "knocks target back";
			goto LABEL_104;
		case IPL_NOHEALMON:
			v8 = "hit monster doesn't heal";
			goto LABEL_104;
		case IPL_STEALMANA:
			v3 = &x->_iFlags;
			if ( x->_iFlags & 0x2000 )
				strcpy(tempstr, "hit steals 3% mana");
			if ( !(*((_BYTE *)v3 + 1) & 0x40) )
				return;
			v7 = "hit steals 5% mana";
			goto LABEL_81;
		case IPL_STEALLIFE:
			v4 = &x->_iFlags;
			if ( (x->_iFlags & 0x8000) != 0 )
				strcpy(tempstr, "hit steals 3% life");
			if ( !(*((_BYTE *)v4 + 2) & 1) )
				return;
			v7 = "hit steals 5% life";
			goto LABEL_81;
		case IPL_TARGAC:
			v8 = "damages target's armor";
			goto LABEL_104;
		case IPL_FASTATTACK:
			if ( x->_iFlags & 0x20000 )
				strcpy(tempstr, "quick attack");
			if ( v2->_iFlags & 0x40000 )
				strcpy(tempstr, "fast attack");
			if ( v2->_iFlags & 0x80000 )
				strcpy(tempstr, "faster attack");
			if ( !(v2->_iFlags & 0x100000) )
				return;
			v7 = "fastest attack";
			goto LABEL_81;
		case IPL_FASTRECOVER:
			if ( x->_iFlags & 0x200000 )
				strcpy(tempstr, "fast hit recovery");
			if ( v2->_iFlags & 0x400000 )
				strcpy(tempstr, "faster hit recovery");
			if ( (v2->_iFlags & 0x800000) != 0 )
			{
				v7 = "fastest hit recovery";
LABEL_81:
				strcpy(tempstr, v7);
			}
			return;
		case IPL_FASTBLOCK:
			v8 = "fast block";
			goto LABEL_104;
		case IPL_DAMMOD:
			sprintf(tempstr, "adds %i points to damage", x->_iPLDamMod);
			return;
		case IPL_RNDARROWVEL:
			v8 = "fires random speed arrows";
			goto LABEL_104;
		case IPL_SETDAM:
			v9 = "unusual item damage";
			goto LABEL_98;
		case IPL_SETDUR:
			v8 = "altered durability";
			goto LABEL_104;
		case IPL_NOMINSTR:
			v8 = "no strength requirement";
			goto LABEL_104;
		case IPL_SPELL:
			sprintf(tempstr, "%i %s charges", x->_iMaxCharges, spelldata[x->_iSpell].sNameText);
			return;
		case IPL_FASTSWING:
			v8 = "Faster attack swing";
			goto LABEL_104;
		case IPL_ONEHAND:
			v8 = "one handed sword";
			goto LABEL_104;
		case IPL_3XDAMVDEM:
			v8 = "+200% damage vs. demons";
			goto LABEL_104;
		case IPL_ALLRESZERO:
			v8 = "All Resistance equals 0";
			goto LABEL_104;
		case IPL_DRAINLIFE:
			v8 = "constantly lose hit points";
			goto LABEL_104;
		case IPL_RNDSTEALLIFE:
			v8 = "life stealing";
			goto LABEL_104;
		case IPL_INFRAVISION:
			v8 = "see with infravision";
			goto LABEL_104;
		case IPL_SETAC:
		case IPL_AC_CURSE:
			sprintf(tempstr, "armor class: %i", x->_iAC);
			return;
		case IPL_ADDACLIFE:
			v8 = "Armor class added to life";
			goto LABEL_104;
		case IPL_ADDMANAAC:
			v8 = "10% of mana added to armor";
			goto LABEL_104;
		case IPL_FIRERESCLVL:
			v5 = x->_iPLFR;
			if ( v5 > 0 )
			{
				if ( v5 >= 1 )
					sprintf(tempstr, "Resist Fire : %+i%%", v5);
			}
			else
			{
				v9 = " ";
LABEL_98:
				sprintf(tempstr, v9);
			}
			break;
		default:
			v8 = "Another ability (NW)";
LABEL_104:
			strcpy(tempstr, v8);
			break;
	}
}

//----- (00423530) --------------------------------------------------------
void __cdecl items_unique_info_cel()
{
	char *v0; // edi
	signed int v1; // edx
	signed int v2; // ecx
	int v3; // edi
	signed int v4; // ecx
	_BYTE *v5; // edi
	signed int v6; // ecx

	Cel_decode(88, 487, pSTextBoxCels, 1, 271);
	v0 = &gpBuffer->row[324].pixels[27];
	v1 = 148;
	do
	{
		v2 = 132;
		do
		{
			*v0 = 0;
			v0 += 2;
			--v2;
		}
		while ( v2 );
		*v0 = 0;
		v3 = (int)(v0 - 1032);
		v4 = 132;
		do
		{
			v5 = (_BYTE *)(v3 + 1);
			*v5 = 0;
			v3 = (int)(v5 + 1);
			--v4;
		}
		while ( v4 );
		v0 = (char *)(v3 - 1032);
		--v1;
	}
	while ( v1 );
	v6 = 132;
	do
	{
		*v0 = 0;
		v0 += 2;
		--v6;
	}
	while ( v6 );
	*v0 = 0;
}

//----- (0042358C) --------------------------------------------------------
void __fastcall PrintUString(int x, int y, int cjustflag, char *str, int col)
{
	char *v5; // edi
	int v6; // ebx
	size_t v7; // eax
	int v8; // esi
	int v9; // ecx
	signed int v10; // eax
	int v11; // edx
	int v12; // eax
	unsigned char v13; // al
	int v14; // edi
	int v15; // [esp+Ch] [ebp-4h]
	int a3; // [esp+18h] [ebp+8h]

	v5 = str;
	v6 = screen_y_times_768[SStringY[y] + 204] + x + 96;
	v7 = strlen(str);
	v8 = 0;
	v9 = 0;
	v15 = v7;
	if ( cjustflag )
	{
		v10 = 0;
		if ( v15 <= 0 )
			goto LABEL_16;
		do
		{
			v11 = (unsigned char)str[v9++];
			v10 += fontkern[fontframe[fontidx[v11]]] + 1;
		}
		while ( v9 < v15 );
		if ( v10 < 257 )
LABEL_16:
			v8 = (257 - v10) >> 1;
		v6 += v8;
	}
	v12 = 0;
	a3 = 0;
	if ( v15 > 0 )
	{
		while ( 1 )
		{
			v13 = fontframe[fontidx[(unsigned char)v5[v12]]];
			v14 = v13;
			v8 += fontkern[v13] + 1;
			if ( v13 )
			{
				if ( v8 <= 257 )
					CPrintString(v6, (char *)v13, col);
			}
			v6 += fontkern[v14] + 1;
			v12 = a3++ + 1;
			if ( a3 >= v15 )
				break;
			v5 = str;
		}
	}
}

//----- (0042365B) --------------------------------------------------------
void __fastcall items_unique_info_box(int y)
{
	char *v1; // esi
	char *v2; // edi
	signed int v3; // edx
	_WORD *v4; // edi
	_WORD *v5; // esi

	v1 = &gpBuffer->row[25].pixels[26];
	v2 = &gpBuffer->row_unused_1[0].pixels[screen_y_times_768[SStringY[y] + 198] + 26];
	v3 = 3;
	do
	{
		qmemcpy(v2, v1, 0x108u);
		v5 = (unsigned short *)v1 + 264;
		v4 = (unsigned short *)v2 + 264;
		*v4 = *v5;
		v1 = (char *)(v5 + 252);
		v2 = (char *)(v4 + 252);
		--v3;
	}
	while ( v3 );
}

//----- (004236A6) --------------------------------------------------------
void __cdecl DrawUniqueInfo()
{
	int v0; // esi
	int v1; // esi
	int v2; // edi

	if ( !chrflag && !questlog )
	{
		v0 = curruitem._iUid;
		items_unique_info_cel();
		v1 = v0;
		PrintUString(0, 2, 1, UniqueItemList[v1].UIName, 3);
		items_unique_info_box(5);
		PrintItemPower(UniqueItemList[v1].UIPower1, &curruitem);
		v2 = 14 - (char)UniqueItemList[v1].UINumPL;
		PrintUString(0, v2, 1, tempstr, 0);
		if ( UniqueItemList[v1].UINumPL > 1 )
		{
			PrintItemPower(UniqueItemList[v1].UIPower2, &curruitem);
			PrintUString(0, v2 + 2, 1, tempstr, 0);
		}
		if ( UniqueItemList[v1].UINumPL > 2 )
		{
			PrintItemPower(UniqueItemList[v1].UIPower3, &curruitem);
			PrintUString(0, v2 + 4, 1, tempstr, 0);
		}
		if ( UniqueItemList[v1].UINumPL > 3 )
		{
			PrintItemPower(UniqueItemList[v1].UIPower4, &curruitem);
			PrintUString(0, v2 + 6, 1, tempstr, 0);
		}
		if ( UniqueItemList[v1].UINumPL > 4 )
		{
			PrintItemPower(UniqueItemList[v1].UIPower5, &curruitem);
			PrintUString(0, v2 + 8, 1, tempstr, 0);
		}
		if ( UniqueItemList[v1].UINumPL > 5 )
		{
			PrintItemPower(UniqueItemList[v1].UIPower6, &curruitem);
			PrintUString(0, v2 + 10, 1, tempstr, 0);
		}
	}
}
// 69BD04: using guessed type int questlog;

//----- (004237DC) --------------------------------------------------------
void __fastcall PrintItemMisc(ItemStruct *x)
{
	ItemStruct *v1; // edi
	signed int v2; // eax

	v1 = x;
	if ( x->_iMiscId == IMISC_SCROLL )
	{
		strcpy(tempstr, "Right-click to read");
		AddPanelString(tempstr, 1);
	}
	if ( v1->_iMiscId == IMISC_SCROLLT )
	{
		strcpy(tempstr, "Right-click to read, then");
		AddPanelString(tempstr, 1);
		strcpy(tempstr, "left-click to target");
		AddPanelString(tempstr, 1);
	}
	v2 = v1->_iMiscId;
	if ( v2 >= 1 && v2 <= (signed int)IMISC_USELAST )
	{
		PrintItemOil(v1->_iMiscId);
		strcpy(tempstr, "Right click to use");
		AddPanelString(tempstr, 1);
	}
	if ( v1->_iMiscId == IMISC_BOOK )
	{
		strcpy(tempstr, "Right click to read");
		AddPanelString(tempstr, 1);
	}
	if ( v1->_iMiscId == IMISC_MAPOFDOOM )
	{
		strcpy(tempstr, "Right click to view");
		AddPanelString(tempstr, 1);
	}
	if ( v1->_iMiscId == IMISC_EAR )
	{
		sprintf(tempstr, "Level : %i", v1->_ivalue);
		AddPanelString(tempstr, 1);
	}
}

//----- (004238D4) --------------------------------------------------------
void __fastcall PrintItemDetails(ItemStruct *x)
{
	ItemStruct *v1; // ebp
	char v2; // cl
	char v3; // cl
	char v4; // al
	unsigned char v5; // al
	char v6; // al

	v1 = x;
	if ( x->_iClass == 1 )
	{
		if ( x->_iMaxDur == 255 )
			sprintf(tempstr, "damage: %i-%i  Indestructible", x->_iMinDam, x->_iMaxDam);
		else
			sprintf(tempstr, "damage: %i-%i  Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur);
		AddPanelString(tempstr, 1);
	}
	if ( v1->_iClass == 2 )
	{
		if ( v1->_iMaxDur == 255 )
			sprintf(tempstr, "armor: %i  Indestructible", v1->_iAC);
		else
			sprintf(tempstr, "armor: %i  Dur: %i/%i", v1->_iAC, v1->_iDurability, v1->_iMaxDur);
		AddPanelString(tempstr, 1);
	}
	if ( v1->_iMiscId == IMISC_STAFF && v1->_iMaxCharges )
	{
		sprintf(tempstr, "dam: %i-%i  Dur: %i/%i", v1->_iMinDam, v1->_iMaxDam, v1->_iDurability, v1->_iMaxDur);
		sprintf(tempstr, "Charges: %i/%i", v1->_iCharges, v1->_iMaxCharges);
		AddPanelString(tempstr, 1);
	}
	v2 = v1->_iPrePower;
	if ( v2 != -1 )
	{
		PrintItemPower(v2, v1);
		AddPanelString(tempstr, 1);
	}
	v3 = v1->_iSufPower;
	if ( v3 != -1 )
	{
		PrintItemPower(v3, v1);
		AddPanelString(tempstr, 1);
	}
	if ( v1->_iMagical == 2 )
	{
		AddPanelString("unique item", 1);
		uitemflag = 1;
		qmemcpy(&curruitem, v1, sizeof(curruitem));
	}
	PrintItemMisc(v1);
	if ( (unsigned char)v1->_iMinMag + v1->_iMinDex + v1->_iMinStr )
	{
		strcpy(tempstr, "Required:");
		v4 = v1->_iMinStr;
		if ( v4 )
			sprintf(tempstr, "%s %i Str", tempstr, v4);
		v5 = v1->_iMinMag;
		if ( v5 )
			sprintf(tempstr, "%s %i Mag", tempstr, v5);
		v6 = v1->_iMinDex;
		if ( v6 )
			sprintf(tempstr, "%s %i Dex", tempstr, v6);
		AddPanelString(tempstr, 1);
	}
	pinfoflag = 1;
}
// 4B8824: using guessed type int pinfoflag;

//----- (00423AE1) --------------------------------------------------------
void __fastcall PrintItemDur(ItemStruct *x)
{
	ItemStruct *v1; // esi
	int v2; // eax
	char v3; // al
	unsigned char v4; // al
	char v5; // al

	v1 = x;
	if ( x->_iClass == 1 )
	{
		if ( x->_iMaxDur == 255 )
			sprintf(tempstr, "damage: %i-%i  Indestructible", x->_iMinDam, x->_iMaxDam);
		else
			sprintf(tempstr, "damage: %i-%i  Dur: %i/%i", x->_iMinDam, x->_iMaxDam, x->_iDurability, x->_iMaxDur);
		AddPanelString(tempstr, 1);
		if ( v1->_iMiscId == IMISC_STAFF && v1->_iMaxCharges )
		{
			sprintf(tempstr, "Charges: %i/%i", v1->_iCharges, v1->_iMaxCharges);
			AddPanelString(tempstr, 1);
		}
		if ( v1->_iMagical )
			AddPanelString("Not Identified", 1);
	}
	if ( v1->_iClass == 2 )
	{
		if ( v1->_iMaxDur == 255 )
			sprintf(tempstr, "armor: %i  Indestructible", v1->_iAC);
		else
			sprintf(tempstr, "armor: %i  Dur: %i/%i", v1->_iAC, v1->_iDurability, v1->_iMaxDur);
		AddPanelString(tempstr, 1);
		if ( v1->_iMagical )
			AddPanelString("Not Identified", 1);
		if ( v1->_iMiscId == IMISC_STAFF && v1->_iMaxCharges )
		{
			sprintf(tempstr, "Charges: %i/%i", v1->_iCharges, v1->_iMaxCharges);
			AddPanelString(tempstr, 1);
		}
	}
	v2 = v1->_itype;
	if ( v2 == ITYPE_RING || v2 == ITYPE_AMULET )
		AddPanelString("Not Identified", 1);
	PrintItemMisc(v1);
	if ( (unsigned char)v1->_iMinMag + v1->_iMinDex + v1->_iMinStr )
	{
		strcpy(tempstr, "Required:");
		v3 = v1->_iMinStr;
		if ( v3 )
			sprintf(tempstr, "%s %i Str", tempstr, v3);
		v4 = v1->_iMinMag;
		if ( v4 )
			sprintf(tempstr, "%s %i Mag", tempstr, v4);
		v5 = v1->_iMinDex;
		if ( v5 )
			sprintf(tempstr, "%s %i Dex", tempstr, v5);
		AddPanelString(tempstr, 1);
	}
	pinfoflag = 1;
}
// 4B8824: using guessed type int pinfoflag;

//----- (00423CE0) --------------------------------------------------------
void __fastcall UseItem(int p, int Mid, int spl)
{
	int v3; // esi
	int v4; // edx
	int v5; // edx
	int v6; // edx
	int v7; // edx
	int v8; // edx
	int v9; // esi
	int v10; // esi
	int v11; // edi
	unsigned int v12; // edi
	char v13; // al
	int v14; // edi
	int v15; // ecx
	int *v16; // eax
	int *v17; // eax
	int v18; // esi
	int v19; // esi
	int v20; // edx
	int v21; // edx
	int v22; // edx
	int v23; // edx
	int v24; // edx
	int v25; // edi
	char *v26; // eax
	int v27; // edx
	int *v28; // ecx
	int v29; // eax
	int *v30; // ecx
	int v31; // edi
	int v32; // edi
	int v33; // eax
	int v34; // ecx
	int v35; // eax
	bool v36; // zf
	int v37; // ecx
	int v38; // eax
	int v39; // edx
	int v40; // eax
	int v41; // edx
	int v42; // esi
	int v43; // edi
	unsigned int v44; // edi
	char v45; // al
	int v46; // edi
	int v47; // ecx
	int *v48; // eax
	int v49; // ecx
	int *v50; // eax
	int v51; // edi
	int v52; // edx
	unsigned int v53; // edi
	char v54; // al
	int v55; // edi
	int v56; // ecx
	int *v57; // eax
	int *v58; // eax
	int v59; // esi
	int v60; // edx
	int v61; // esi
	int v62; // edi
	unsigned int v63; // edi
	char v64; // al
	int v65; // edi
	int v66; // ecx
	int *v67; // eax
	int *v68; // eax
	int v69; // esi
	int v70; // edx
	int pa; // [esp+Ch] [ebp-4h]

	v3 = p;
	pa = p;
	if ( Mid > 28 )
	{
		v70 = Mid - 42;
		if ( !v70 )
		{
			doom_init();
			return;
		}
		if ( v70 != 2 )
			return;
		ModifyPlrStr(p, 3);
		ModifyPlrMag(v3, 3);
		ModifyPlrDex(v3, 3);
		v60 = 3;
LABEL_82:
		ModifyPlrVit(v3, v60);
		return;
	}
	if ( Mid == 28 )
		goto LABEL_71;
	if ( Mid <= 12 )
	{
		if ( Mid == 12 )
		{
			ModifyPlrDex(p, 1);
			return;
		}
		v4 = Mid - 2;
		if ( !v4 )
		{
			v19 = p;
			plr[v19]._pHitPoints = plr[v19]._pMaxHP;
			plr[v19]._pHPBase = plr[p]._pMaxHPBase;
LABEL_25:
			drawhpflag = 1;
			return;
		}
		v5 = v4 - 1;
		if ( v5 )
		{
			v6 = v5 - 3;
			if ( v6 )
			{
				v7 = v6 - 1;
				if ( v7 )
				{
					v8 = v7 - 3;
					if ( v8 )
					{
						if ( v8 == 1 )
							ModifyPlrMag(p, 1);
					}
					else
					{
						ModifyPlrStr(p, 1);
					}
					return;
				}
				v9 = p;
				if ( plr[p]._pIFlags & 0x8000000 )
					return;
				plr[v9]._pMana = plr[v9]._pMaxMana;
				plr[v9]._pManaBase = plr[v9]._pMaxManaBase;
LABEL_41:
				drawmanaflag = 1;
				return;
			}
			v10 = p;
			_LOBYTE(p) = 40;
			v11 = plr[v10]._pMaxMana >> 8;
			v12 = (v11 & 0xFFFFFFFE) + 2 * random(p, v11);
			v13 = plr[v10]._pClass;
			v14 = 32 * v12;
			if ( v13 == 2 )
				v14 *= 2;
			if ( v13 == 1 )
				v14 += v14 >> 1;
			if ( !(*(_BYTE *)(v10 * 21720 + 6863003) & 8) )
			{
				v15 = plr[v10]._pMaxMana;
				v16 = &plr[v10]._pMana;
				*v16 += v14;
				if ( plr[v10]._pMana > v15 )
					*v16 = v15;
				v17 = &plr[v10]._pManaBase;
				v18 = plr[v10]._pMaxManaBase;
				*v17 += v14;
				if ( *v17 > v18 )
					*v17 = v18;
				goto LABEL_41;
			}
			return;
		}
LABEL_71:
		v61 = p;
		_LOBYTE(p) = 39;
		v62 = plr[v61]._pMaxHP >> 8;
		v63 = (v62 & 0xFFFFFFFE) + 2 * random(p, v62);
		v64 = plr[v61]._pClass;
		v65 = 32 * v63;
		if ( !v64 )
			v65 *= 2;
		if ( v64 == 1 )
			v65 += v65 >> 1;
		v66 = plr[v61]._pMaxHP;
		v67 = &plr[v61]._pHitPoints;
		*v67 += v65;
		if ( plr[v61]._pHitPoints > v66 )
			*v67 = v66;
		v68 = &plr[v61]._pHPBase;
		v69 = plr[v61]._pMaxHPBase;
		*v68 += v65;
		if ( *v68 > v69 )
			*v68 = v69;
		goto LABEL_25;
	}
	v20 = Mid - 13;
	if ( !v20 )
	{
		v60 = 1;
		goto LABEL_82;
	}
	v21 = v20 - 5;
	if ( v21 )
	{
		v22 = v21 - 1;
		if ( v22 )
		{
			v23 = v22 - 2;
			if ( v23 )
			{
				v24 = v23 - 1;
				if ( v24 )
				{
					if ( v24 != 2 )
						return;
					v25 = p;
					*(_QWORD *)plr[p]._pMemSpells |= 1i64 << ((unsigned char)spl - 1);
					v26 = &plr[p]._pSplLvl[spl];
					if ( *v26 < 15 )
						++*v26;
					v27 = plr[v25]._pMaxMana;
					v28 = &plr[v25]._pMana;
					v29 = spelldata[spl].sManaCost << 6;
					*v28 += v29;
					if ( plr[v25]._pMana > v27 )
						*v28 = v27;
					v30 = &plr[v25]._pManaBase;
					v31 = plr[v25]._pMaxManaBase;
					*v30 += v29;
					if ( *v30 > v31 )
						*v30 = v31;
					if ( pa == myplr )
						CalcPlrBookVals(pa);
					goto LABEL_41;
				}
				v32 = spl;
				if ( !spelldata[spl].sTargeted )
				{
					ClrPlrPath(p);
					v33 = v3;
					plr[v33].destParam1 = cursmx;
					v34 = cursmy;
					plr[v33]._pSpell = spl;
					plr[v33]._pSplType = 4;
					plr[v33]._pSplFrom = 3;
					plr[v33].destAction = 12;
					plr[v33].destParam2 = v34;
					return;
				}
			}
			else
			{
				v32 = spl;
				if ( !spelldata[spl].sTargeted )
				{
					ClrPlrPath(p);
					v37 = cursmx;
					v38 = v3;
					v39 = cursmy;
					v36 = v3 == myplr;
					plr[v38]._pSpell = spl;
					plr[v38]._pSplType = 4;
					plr[v38]._pSplFrom = 3;
					plr[v38].destAction = 12;
					plr[v38].destParam1 = v37;
					plr[v38].destParam2 = v39;
					if ( v36 && spl == 18 )
						NetSendCmdLoc(1u, CMD_NOVA, v37, v39);
					return;
				}
			}
			v35 = p;
			v36 = p == myplr;
			plr[v35]._pTSpell = v32;
			_LOBYTE(plr[v35]._pTSplType) = 4;
			if ( v36 )
				SetCursor(9);
			return;
		}
		v40 = p;
		plr[v40]._pHitPoints = plr[p]._pMaxHP;
		plr[v40]._pHPBase = plr[p]._pMaxHPBase;
		v36 = (plr[p]._pIFlags & 0x8000000) == 0;
		drawhpflag = 1;
		if ( v36 )
		{
			v41 = plr[v40]._pMaxMana;
			drawmanaflag = 1;
			plr[v40]._pMana = v41;
			plr[v40]._pManaBase = plr[v40]._pMaxManaBase;
		}
	}
	else
	{
		v42 = p;
		_LOBYTE(p) = 39;
		v43 = plr[v42]._pMaxHP >> 8;
		v44 = (v43 & 0xFFFFFFFE) + 2 * random(p, v43);
		v45 = plr[v42]._pClass;
		v46 = 32 * v44;
		if ( !v45 )
			v46 *= 2;
		if ( v45 == 1 )
			v46 += v46 >> 1;
		v47 = plr[v42]._pMaxHP;
		v48 = &plr[v42]._pHitPoints;
		*v48 += v46;
		if ( plr[v42]._pHitPoints > v47 )
			*v48 = v47;
		v49 = plr[v42]._pMaxHPBase;
		v50 = &plr[v42]._pHPBase;
		*v50 += v46;
		if ( plr[v42]._pHPBase > v49 )
			*v50 = v49;
		v51 = plr[v42]._pMaxMana >> 8;
		v52 = plr[v42]._pMaxMana >> 8;
		_LOBYTE(v49) = 40;
		drawhpflag = 1;
		v53 = (v51 & 0xFFFFFFFE) + 2 * random(v49, v52);
		v54 = plr[v42]._pClass;
		v55 = 32 * v53;
		if ( v54 == 2 )
			v55 *= 2;
		if ( v54 == 1 )
			v55 += v55 >> 1;
		if ( !(plr[v42]._pIFlags & 0x8000000) )
		{
			v56 = plr[v42]._pMaxMana;
			v57 = &plr[v42]._pMana;
			*v57 += v55;
			if ( plr[v42]._pMana > v56 )
				*v57 = v56;
			v58 = &plr[v42]._pManaBase;
			v59 = plr[v42]._pMaxManaBase;
			*v58 += v55;
			if ( *v58 > v59 )
				*v58 = v59;
			drawmanaflag = 1;
		}
	}
}

//----- (004241D7) --------------------------------------------------------
bool __fastcall StoreStatOk(ItemStruct *h)
{
	int v1; // edx
	bool result; // al

	v1 = myplr;
	result = 1;
	if ( plr[myplr]._pStrength < h->_iMinStr )
		result = 0;
	if ( plr[v1]._pMagic < (unsigned char)h->_iMinMag )
		result = 0;
	if ( plr[v1]._pDexterity < h->_iMinDex )
		result = 0;
	return result;
}

//----- (0042421C) --------------------------------------------------------
int __fastcall SmithItemOk(int i)
{
	unsigned char v1; // cl
	int result; // eax

	v1 = AllItemsList[i].itype;
	result = 1;
	if ( !v1 )
		result = 0;
	if ( v1 == ITYPE_GOLD )
		result = 0;
	if ( v1 == ITYPE_0E )
		result = 0;
	if ( v1 == ITYPE_STAFF )
		result = 0;
	if ( v1 == ITYPE_RING )
		result = 0;
	if ( v1 == ITYPE_AMULET )
		result = 0;
	return result;
}

//----- (00424252) --------------------------------------------------------
int __fastcall RndSmithItem(int lvl)
{
	int v1; // edx
	int v2; // edi
	ItemDataStruct *v3; // esi
	int v4; // ebx
	int v6[512]; // [esp+4h] [ebp-804h]
	int v7; // [esp+804h] [ebp-4h]

	v1 = 0;
	v2 = 1;
	v7 = lvl;
	if ( AllItemsList[1].iLoc != ILOC_INVALID )
	{
		v3 = &AllItemsList[1];
		do
		{
			v4 = v3->iRnd;
			if ( v3->iRnd )
			{
				if ( SmithItemOk(v2) )
				{
					if ( v7 >= SLOBYTE(v3->iMinMLvl) )
					{
						v6[v1++] = v2;
						if ( v4 == 2 )
							v6[v1++] = v2;
					}
				}
			}
			++v3;
			++v2;
		}
		while ( v3->iLoc != -1 );
	}
	_LOBYTE(lvl) = 50;
	return v6[random(lvl, v1)] + 1;
}
// 424252: using guessed type int var_804[512];

//----- (004242C1) --------------------------------------------------------
void __fastcall BubbleSwapItem(ItemStruct *a, ItemStruct *b)
{
	ItemStruct h; // [esp+8h] [ebp-170h]

	qmemcpy(&h, a, sizeof(h));
	qmemcpy(a, b, sizeof(ItemStruct));
	qmemcpy(b, &h, sizeof(ItemStruct));
}

//----- (004242F5) --------------------------------------------------------
void __cdecl SortSmith()
{
	int v0; // esi
	int *v1; // eax
	signed int v2; // ecx
	int *v3; // eax
	int v4; // ebx
	int v5; // edi

	v0 = 0;
	if ( smithitem[1]._itype != -1 )
	{
		v1 = &smithitem[1]._itype;
		do
		{
			v1 += 92;
			++v0;
		}
		while ( *v1 != -1 );
	}
	v2 = 0;
	while ( v0 > 0 && !v2 )
	{
		v2 = 1;
		if ( v0 > 0 )
		{
			v3 = &smithitem[0].IDidx;
			v4 = v0;
			do
			{
				v5 = (int)(v3 + 92);
				if ( *v3 > v3[92] )
				{
					BubbleSwapItem((ItemStruct *)(v3 - 90), (ItemStruct *)(v3 + 2));
					v2 = 0;
				}
				--v4;
				v3 = (int *)v5;
			}
			while ( v4 );
		}
		--v0;
	}
}

//----- (00424351) --------------------------------------------------------
void __fastcall SpawnSmith(int lvl)
{
	int v1; // esi
	int v2; // eax
	int v3; // ebp
	ItemStruct *v4; // ebx
	int v5; // eax
	int v6; // eax
	int *v7; // ebp
	short v8; // [esp+8h] [ebp-Ch]
	int v9; // [esp+Ch] [ebp-8h]
	int v10; // [esp+10h] [ebp-4h]

	v1 = lvl;
	_LOBYTE(lvl) = 50;
	v10 = v1;
	v2 = random(lvl, 10);
	v3 = v2 + 10;
	if ( v2 + 10 > 0 )
	{
		v8 = v1 | 0x400;
		v4 = smithitem;
		v9 = v2 + 10;
		while ( 1 )
		{
			do
			{
				items[0]._iSeed = GetRndSeed();
				SetRndSeed(items[0]._iSeed);
				v5 = RndSmithItem(v1);
				GetItemAttrs(0, v5 - 1, v1);
			}
			while ( items[0]._iIvalue > 140000 );
			qmemcpy(v4, items, sizeof(ItemStruct));
			v4->_iCreateInfo = v8;
			v4->_iIdentified = 1;
			_LOBYTE(v6) = StoreStatOk(v4);
			v4->_iStatFlag = v6;
			++v4;
			if ( !--v9 )
				break;
			v1 = v10;
		}
	}
	if ( v3 < 20 )
	{
		v7 = &smithitem[v3]._itype;
		do
		{
			*v7 = -1;
			v7 += 92;
		}
		while ( (signed int)v7 < (signed int)sync_word_6AA708 );
	}
	SortSmith();
}

//----- (00424420) --------------------------------------------------------
int __fastcall PremiumItemOk(int i)
{
	unsigned char v1; // cl
	int result; // eax

	v1 = AllItemsList[i].itype;
	result = 1;
	if ( !v1 )
		result = 0;
	if ( v1 == ITYPE_GOLD )
		result = 0;
	if ( v1 == ITYPE_0E )
		result = 0;
	if ( v1 == ITYPE_STAFF )
		result = 0;
	if ( gbMaxPlayers != 1 )
	{
		if ( v1 == ITYPE_RING )
			result = 0;
		if ( v1 == ITYPE_AMULET )
			result = 0;
	}
	return result;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0042445F) --------------------------------------------------------
int __fastcall RndPremiumItem(int minlvl, int maxlvl)
{
	int v2; // edx
	int v3; // edi
	int v4; // ebx
	int *v5; // esi
	int v6; // eax
	int ril[512]; // [esp+8h] [ebp-804h]
	int v9; // [esp+808h] [ebp-4h]

	v9 = maxlvl;
	v2 = 0;
	v3 = 1;
	v4 = minlvl;
	if ( AllItemsList[1].iLoc != ILOC_INVALID )
	{
		v5 = &AllItemsList[1].iMinMLvl;
		do
		{
			if ( *(v5 - 6) )
			{
				if ( PremiumItemOk(v3) )
				{
					v6 = *(char *)v5;
					if ( v6 >= v4 && v6 <= v9 )
						ril[v2++] = v3;
				}
			}
			v5 += 19;
			++v3;
		}
		while ( *((_BYTE *)v5 - 19) != -1 );
	}
	_LOBYTE(minlvl) = 50;
	return ril[random(minlvl, v2)] + 1;
}
// 42445F: using guessed type int ril[512];

//----- (004244C6) --------------------------------------------------------
void __fastcall SpawnOnePremium(int i, int plvl)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // ebx
	ItemStruct *v6; // edx
	short v7; // ax
	int v8; // eax
	char v9[368]; // [esp+Ch] [ebp-178h]
	int v10; // [esp+17Ch] [ebp-8h]
	int lvl; // [esp+180h] [ebp-4h]

	v10 = i;
	lvl = plvl;
	qmemcpy(v9, items, sizeof(v9));
	if ( plvl > 30 )
		lvl = 30;
	if ( lvl < 1 )
		lvl = 1;
	v2 = lvl >> 2;
	v3 = lvl >> 1;
	do
	{
		items[0]._iSeed = GetRndSeed();
		SetRndSeed(items[0]._iSeed);
		v4 = RndPremiumItem(v2, lvl) - 1;
		GetItemAttrs(0, v4, lvl);
		GetItemBonus(0, v4, v3, lvl, 1);
	}
	while ( items[0]._iIvalue > 140000 );
	v7 = lvl | 0x800;
	v5 = v10;
	v6 = &premiumitem[v10];
	qmemcpy(&premiumitem[v10], items, sizeof(ItemStruct));
	premiumitem[v5]._iCreateInfo = v7;
	premiumitem[v5]._iIdentified = 1;
	_LOBYTE(v8) = StoreStatOk(v6);
	premiumitem[v5]._iStatFlag = v8;
	qmemcpy(items, v9, 0x170u);
}

//----- (004245A0) --------------------------------------------------------
void __fastcall SpawnPremium(int lvl)
{
	int v1; // edi
	int *v2; // esi
	int i; // eax
	int v4; // [esp+Ch] [ebp-4h]

	v4 = lvl;
	if ( numpremium < 6 )
	{
		v1 = 0;
		v2 = &premiumitem[0]._itype;
		do
		{
			if ( *v2 == -1 )
				SpawnOnePremium(v1, premiumlevel + premiumlvladd[v1]);
			v2 += 92;
			++v1;
		}
		while ( (signed int)v2 < (signed int)&talker );
		numpremium = 6;
	}
	for ( i = premiumlevel; premiumlevel < v4; i = premiumlevel )
	{
		qmemcpy(premiumitem, &premiumitem[2], 0x170u);
		qmemcpy(&premiumitem[1], &premiumitem[3], sizeof(ItemStruct));
		qmemcpy(&premiumitem[2], &premiumitem[4], sizeof(ItemStruct));
		premiumlevel = i + 1;
		SpawnOnePremium(3, premiumlvladd[3] + i + 1);
		qmemcpy(&premiumitem[4], &premiumitem[5], sizeof(ItemStruct));
		SpawnOnePremium(5, premiumlvladd[5] + premiumlevel);
	}
}
// 69FB38: using guessed type int talker;

//----- (0042466C) --------------------------------------------------------
int __fastcall WitchItemOk(int i)
{
	int v1; // ecx
	int result; // eax
	unsigned char v3; // dl
	int v4; // edx
	int v5; // ecx

	v1 = i;
	result = 0;
	v3 = AllItemsList[v1].itype;
	if ( !v3 )
		result = 1;
	if ( v3 == ITYPE_STAFF )
		result = 1;
	v4 = AllItemsList[v1].iMiscId;
	if ( v4 == IMISC_MANA )
		result = 0;
	if ( v4 == IMISC_FULLMANA )
		result = 0;
	v5 = AllItemsList[v1].iSpell;
	if ( v5 == SPL_TOWN )
		result = 0;
	if ( v4 == SPL_HEAL )
		result = 0;
	if ( v4 == SPL_LIGHTNING )
		result = 0;
	if ( v5 == SPL_RESURRECT && gbMaxPlayers == 1 )
		result = 0;
	if ( v5 == SPL_HEALOTHER && gbMaxPlayers == 1 )
		result = 0;
	return result;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (004246D2) --------------------------------------------------------
int __fastcall RndWitchItem(int lvl)
{
	int v1; // ebx
	int v2; // edi
	int *v3; // esi
	int v5[512]; // [esp+8h] [ebp-804h]
	int v6; // [esp+808h] [ebp-4h]

	v1 = 0;
	v2 = 1;
	v6 = lvl;
	if ( AllItemsList[1].iLoc != ILOC_INVALID )
	{
		v3 = &AllItemsList[1].iMinMLvl;
		do
		{
			if ( *(v3 - 6) && WitchItemOk(v2) && v6 >= *(char *)v3 )
				v5[v1++] = v2;
			v3 += 19;
			++v2;
		}
		while ( *((_BYTE *)v3 - 19) != -1 );
	}
	_LOBYTE(lvl) = 51;
	return v5[random(lvl, v1)] + 1;
}
// 4246D2: using guessed type int var_804[512];

//----- (00424735) --------------------------------------------------------
void __cdecl SortWitch()
{
	signed int v0; // esi
	int *v1; // eax
	signed int v2; // ecx
	int *v3; // eax
	int v4; // ebx
	int v5; // edi

	v0 = 3;
	if ( witchitem[4]._itype != -1 )
	{
		v1 = &witchitem[4]._itype;
		do
		{
			v1 += 92;
			++v0;
		}
		while ( *v1 != -1 );
	}
	v2 = 0;
	while ( v0 > 3 && !v2 )
	{
		v2 = 1;
		if ( v0 > 3 )
		{
			v3 = &witchitem[3].IDidx;
			v4 = v0 - 3;
			do
			{
				v5 = (int)(v3 + 92);
				if ( *v3 > v3[92] )
				{
					BubbleSwapItem((ItemStruct *)(v3 - 90), (ItemStruct *)(v3 + 2));
					v2 = 0;
				}
				--v4;
				v3 = (int *)v5;
			}
			while ( v4 );
		}
		--v0;
	}
}

//----- (00424795) --------------------------------------------------------
void __fastcall WitchBookLevel(int ii)
{
	int v1; // ecx
	int v2; // eax
	unsigned char v3; // bl
	int v4; // edx
	int v5; // edi

	v1 = ii;
	if ( witchitem[v1]._iMiscId == IMISC_BOOK )
	{
		v2 = witchitem[v1]._iSpell;
		v3 = spelldata[witchitem[v1]._iSpell].sMinInt;
		v4 = myplr;
		witchitem[v1]._iMinMag = v3;
		v5 = plr[v4]._pSplLvl[v2];
		if ( plr[v4]._pSplLvl[v2] )
		{
			do
			{
				v3 += 20 * v3 / 100;
				--v5;
				if ( v3 + 20 * v3 / 100 > 255 )
				{
					v3 = -1;
					v5 = 0;
				}
			}
			while ( v5 );
			witchitem[v1]._iMinMag = v3;
		}
	}
}

//----- (00424815) --------------------------------------------------------
void __fastcall SpawnWitch(int lvl)
{
	int v1; // ebx
	int v2; // ebp
	int v3; // esi
	int v4; // ecx
	int v5; // eax
	int v6; // eax
	int *v7; // ebp
	signed int ii; // [esp+10h] [ebp-8h]
	ItemStruct *item; // [esp+14h] [ebp-4h]

	v1 = lvl;
	GetItemAttrs(0, 25, 1);
	qmemcpy(witchitem, items, 0x170u);
	witchitem[0]._iCreateInfo = v1;
	witchitem[0]._iStatFlag = 1;
	GetItemAttrs(0, 30, 1);
	qmemcpy(&witchitem[1], items, sizeof(ItemStruct));
	witchitem[1]._iCreateInfo = v1;
	witchitem[1]._iStatFlag = 1;
	GetItemAttrs(0, 27, 1);
	qmemcpy(&witchitem[2], items, sizeof(ItemStruct));
	witchitem[2]._iCreateInfo = v1;
	witchitem[2]._iStatFlag = 1;
	v2 = random(51, 8) + 10;
	ii = 3;
	if ( v2 > 3 )
	{
		item = &witchitem[3];
		while ( 1 )
		{
			items[0]._iSeed = GetRndSeed();
			SetRndSeed(items[0]._iSeed);
			v3 = RndWitchItem(v1) - 1;
			GetItemAttrs(0, v3, v1);
			_LOBYTE(v4) = 51;
			if ( random(v4, 100) > 5 || (v5 = 2 * v1, 2 * v1 == -1) )
			{
				if ( items[0]._iMiscId != IMISC_STAFF )
					continue;
				v5 = 2 * v1;
				if ( 2 * v1 == -1 )
					continue;
			}
			GetItemBonus(0, v3, v5 >> 1, v5, 1);
			if ( items[0]._iIvalue <= 140000 )
			{
				qmemcpy(item, items, sizeof(ItemStruct));
				item->_iIdentified = 1;
				item->_iCreateInfo = v1 | 0x2000;
				WitchBookLevel(ii);
				_LOBYTE(v6) = StoreStatOk(item);
				++ii;
				item->_iStatFlag = v6;
				++item;
				if ( ii >= v2 )
					break;
			}
		}
	}
	if ( v2 < 20 )
	{
		v7 = &witchitem[v2]._itype;
		do
		{
			*v7 = -1;
			v7 += 92;
		}
		while ( (signed int)v7 < (signed int)healitem );
	}
	SortWitch();
}

//----- (004249A4) --------------------------------------------------------
int __fastcall RndBoyItem(int lvl)
{
	int v1; // edx
	int v2; // edi
	int v3; // ebx
	int *v4; // esi
	int v6[512]; // [esp+8h] [ebp-800h]

	v1 = 0;
	v2 = 1;
	v3 = lvl;
	if ( AllItemsList[1].iLoc != ILOC_INVALID )
	{
		v4 = &AllItemsList[1].iMinMLvl;
		do
		{
			if ( *(v4 - 6) && PremiumItemOk(v2) && v3 >= *(char *)v4 )
				v6[v1++] = v2;
			v4 += 19;
			++v2;
		}
		while ( *((_BYTE *)v4 - 19) != -1 );
	}
	_LOBYTE(lvl) = 49;
	return v6[random(lvl, v1)] + 1;
}
// 4249A4: using guessed type int var_800[512];

//----- (00424A03) --------------------------------------------------------
void __fastcall SpawnBoy(int lvl)
{
	int v1; // ebx
	int v2; // ebp
	int v3; // esi
	int v4; // eax

	v1 = lvl;
	v2 = lvl >> 1;
	if ( boylevel < lvl >> 1 || boyitem._itype == -1 )
	{
		do
		{
			items[0]._iSeed = GetRndSeed();
			SetRndSeed(items[0]._iSeed);
			v3 = RndBoyItem(v1) - 1;
			GetItemAttrs(0, v3, v1);
			GetItemBonus(0, v3, v1, 2 * v1, 1);
		}
		while ( items[0]._iIvalue > 90000 );
		BYTE1(v1) |= 0x10u;
		qmemcpy(&boyitem, items, sizeof(boyitem));
		boyitem._iCreateInfo = v1;
		boyitem._iIdentified = 1;
		_LOBYTE(v4) = StoreStatOk(&boyitem);
		boyitem._iStatFlag = v4;
		boylevel = v2;
	}
}
// 6A8A3C: using guessed type int boylevel;

//----- (00424A9B) --------------------------------------------------------
int __fastcall HealerItemOk(int i)
{
	int v1; // ecx
	int result; // eax
	int v3; // esi

	v1 = i;
	result = 0;
	if ( AllItemsList[v1].itype )
		return 0;
	v3 = AllItemsList[v1].iMiscId;
	if ( v3 == IMISC_SCROLL && AllItemsList[v1].iSpell == SPL_HEAL )
		result = 1;
	if ( v3 != IMISC_SCROLLT )
		goto LABEL_12;
	if ( AllItemsList[v1].iSpell == SPL_RESURRECT && gbMaxPlayers != 1 )
		result = 0;
	if ( AllItemsList[v1].iSpell != SPL_HEALOTHER )
	{
LABEL_12:
		if ( gbMaxPlayers != 1 )
			goto LABEL_21;
		goto LABEL_13;
	}
	if ( gbMaxPlayers != 1 )
	{
		result = 1;
		goto LABEL_12;
	}
LABEL_13:
	if ( v3 == IMISC_ELIXSTR )
		result = 1;
	if ( v3 == IMISC_ELIXMAG )
		result = 1;
	if ( v3 == IMISC_ELIXDEX )
		result = 1;
	if ( v3 == IMISC_ELIXVIT )
		result = 1;
LABEL_21:
	if ( v3 == IMISC_FULLHEAL )
		result = 1;
	if ( v3 == IMISC_REJUV )
		result = 1;
	if ( v3 == IMISC_FULLREJUV )
		result = 1;
	if ( v3 == IMISC_HEAL )
		result = 0;
	if ( v3 == IMISC_FULLHEAL )
		result = 0;
	if ( v3 == IMISC_MANA )
		result = 0;
	if ( v3 == IMISC_FULLMANA )
		return 0;
	return result;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00424B49) --------------------------------------------------------
int __fastcall RndHealerItem(int lvl)
{
	int v1; // ebx
	int v2; // edi
	int *v3; // esi
	int v5[512]; // [esp+8h] [ebp-804h]
	int v6; // [esp+808h] [ebp-4h]

	v1 = 0;
	v2 = 1;
	v6 = lvl;
	if ( AllItemsList[1].iLoc != ILOC_INVALID )
	{
		v3 = &AllItemsList[1].iMinMLvl;
		do
		{
			if ( *(v3 - 6) && HealerItemOk(v2) && v6 >= *(char *)v3 )
				v5[v1++] = v2;
			v3 += 19;
			++v2;
		}
		while ( *((_BYTE *)v3 - 19) != -1 );
	}
	_LOBYTE(lvl) = 50;
	return v5[random(lvl, v1)] + 1;
}
// 424B49: using guessed type int var_804[512];

//----- (00424BAC) --------------------------------------------------------
void __cdecl SortHealer()
{
	signed int v0; // esi
	int *v1; // eax
	signed int v2; // ecx
	int *v3; // eax
	int v4; // ebx
	int v5; // edi

	v0 = 2;
	if ( healitem[3]._itype != -1 )
	{
		v1 = &healitem[3]._itype;
		do
		{
			v1 += 92;
			++v0;
		}
		while ( *v1 != -1 );
	}
	v2 = 0;
	while ( v0 > 2 && !v2 )
	{
		v2 = 1;
		if ( v0 > 2 )
		{
			v3 = &healitem[2].IDidx;
			v4 = v0 - 2;
			do
			{
				v5 = (int)(v3 + 92);
				if ( *v3 > v3[92] )
				{
					BubbleSwapItem((ItemStruct *)(v3 - 90), (ItemStruct *)(v3 + 2));
					v2 = 0;
				}
				--v4;
				v3 = (int *)v5;
			}
			while ( v4 );
		}
		--v0;
	}
}

//----- (00424C0C) --------------------------------------------------------
void __fastcall SpawnHealer(int lvl)
{
	int v1; // ebx
	int v2; // ecx
	int v3; // eax
	ItemStruct *v4; // ebp
	int v5; // eax
	int v6; // eax
	int *v7; // eax
	signed int v8; // [esp-4h] [ebp-20h]
	short v9; // [esp+10h] [ebp-Ch]
	int v10; // [esp+14h] [ebp-8h]
	int v11; // [esp+18h] [ebp-4h]

	v1 = lvl;
	GetItemAttrs(0, 24, 1);
	qmemcpy(healitem, items, 0x170u);
	healitem[0]._iCreateInfo = v1;
	healitem[0]._iStatFlag = 1;
	GetItemAttrs(0, 29, 1);
	qmemcpy(&healitem[1], items, sizeof(ItemStruct));
	v2 = 0;
	healitem[1]._iCreateInfo = v1;
	healitem[1]._iStatFlag = 1;
	if ( gbMaxPlayers == 1 )
	{
		v8 = 2;
	}
	else
	{
		GetItemAttrs(0, 34, 1);
		qmemcpy(&healitem[2], items, sizeof(ItemStruct));
		v2 = 0;
		healitem[2]._iCreateInfo = v1;
		healitem[2]._iStatFlag = 1;
		v8 = 3;
	}
	_LOBYTE(v2) = 50;
	v3 = random(v2, 8) + 10;
	v11 = v3;
	if ( v8 < v3 )
	{
		_LOBYTE(v9) = v1;
		v4 = &healitem[v8];
		v10 = v3 - v8;
		do
		{
			items[0]._iSeed = GetRndSeed();
			SetRndSeed(items[0]._iSeed);
			v5 = RndHealerItem(v1);
			GetItemAttrs(0, v5 - 1, v1);
			qmemcpy(v4, items, sizeof(ItemStruct));
			_HIBYTE(v9) = BYTE1(v1) | 0x40;
			v4->_iCreateInfo = v9;
			v4->_iIdentified = 1;
			_LOBYTE(v6) = StoreStatOk(v4);
			v4->_iStatFlag = v6;
			++v4;
			--v10;
		}
		while ( v10 );
		v3 = v11;
	}
	if ( v3 < 20 )
	{
		v7 = &healitem[v3]._itype;
		do
		{
			*v7 = -1;
			v7 += 92;
		}
		while ( (signed int)v7 < (signed int)&golditem._itype );
	}
	SortHealer();
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00424D57) --------------------------------------------------------
void __cdecl SpawnStoreGold()
{
	GetItemAttrs(0, 0, 1);
	qmemcpy(&golditem, items, sizeof(golditem));
	golditem._iStatFlag = 1;
}

//----- (00424D80) --------------------------------------------------------
void __fastcall RecreateSmithItem(int ii, int idx, int plvl, int iseed)
{
	int v4; // ebx
	int v5; // eax
	int v6; // eax

	v4 = ii;
	SetRndSeed(iseed);
	v5 = RndSmithItem(plvl);
	GetItemAttrs(v4, v5 - 1, plvl);
	v6 = v4;
	items[v6]._iSeed = iseed;
	items[v6]._iCreateInfo = plvl | 0x400;
	items[v6]._iIdentified = 1;
}

//----- (00424DD1) --------------------------------------------------------
void __fastcall RecreatePremiumItem(int ii, int idx, int lvl, int iseed)
{
	int v4; // ebx
	int v5; // edi
	int v6; // eax

	v4 = ii;
	SetRndSeed(iseed);
	v5 = RndPremiumItem(lvl >> 2, lvl) - 1;
	GetItemAttrs(v4, v5, lvl);
	GetItemBonus(v4, v5, lvl >> 1, lvl, 1);
	v6 = v4;
	items[v6]._iCreateInfo = lvl | 0x800;
	items[v6]._iSeed = iseed;
	items[v6]._iIdentified = 1;
}

//----- (00424E3C) --------------------------------------------------------
void __fastcall RecreateBoyItem(int ii, int idx, int lvl, int iseed)
{
	int v4; // ebx
	int v5; // edi
	int v6; // eax

	v4 = ii;
	SetRndSeed(iseed);
	v5 = RndBoyItem(lvl) - 1;
	GetItemAttrs(v4, v5, lvl);
	GetItemBonus(v4, v5, lvl, 2 * lvl, 1);
	v6 = v4;
	items[v6]._iCreateInfo = lvl | 0x1000;
	items[v6]._iSeed = iseed;
	items[v6]._iIdentified = 1;
}

//----- (00424EA1) --------------------------------------------------------
void __fastcall RecreateWitchItem(int ii, int idx, int lvl, int iseed)
{
	int v4; // ebx
	short v5; // si
	int v6; // edi
	int v7; // ecx
	int v8; // eax
	int v9; // eax

	v4 = ii;
	if ( idx == 25 || idx == 30 || idx == 27 )
	{
		v5 = lvl;
		GetItemAttrs(ii, idx, lvl);
	}
	else
	{
		SetRndSeed(iseed);
		v5 = lvl;
		v6 = RndWitchItem(lvl) - 1;
		GetItemAttrs(v4, v6, lvl);
		_LOBYTE(v7) = 51;
		if ( random(v7, 100) <= 5 && (v8 = 2 * lvl, 2 * lvl != -1)
		  || items[v4]._iMiscId == IMISC_STAFF && (v8 = 2 * lvl, 2 * lvl != -1) )
		{
			GetItemBonus(v4, v6, v8 >> 1, v8, 1);
		}
	}
	v9 = v4;
	items[v9]._iCreateInfo = v5 | 0x2000;
	items[v9]._iSeed = iseed;
	items[v9]._iIdentified = 1;
}

//----- (00424F52) --------------------------------------------------------
void __fastcall RecreateHealerItem(int ii, int idx, int lvl, int iseed)
{
	int v4; // edi
	int v5; // esi
	int v6; // eax

	v4 = ii;
	if ( idx == 24 || idx == 29 || idx == 34 )
	{
		v5 = lvl;
	}
	else
	{
		SetRndSeed(iseed);
		v5 = lvl;
		idx = RndHealerItem(lvl) - 1;
	}
	GetItemAttrs(v4, idx, v5);
	v6 = v4;
	items[v6]._iCreateInfo = v5 | 0x4000;
	items[v6]._iSeed = iseed;
	items[v6]._iIdentified = 1;
}

//----- (00424FB8) --------------------------------------------------------
void __fastcall RecreateTownItem(int ii, int idx, unsigned short icreateinfo, int iseed, int ivalue)
{
	if ( icreateinfo & 0x400 )
	{
		RecreateSmithItem(ii, idx, icreateinfo & 0x3F, iseed);
	}
	else if ( icreateinfo & 0x800 )
	{
		RecreatePremiumItem(ii, idx, icreateinfo & 0x3F, iseed);
	}
	else if ( icreateinfo & 0x1000 )
	{
		RecreateBoyItem(ii, idx, icreateinfo & 0x3F, iseed);
	}
	else if ( icreateinfo & 0x2000 )
	{
		RecreateWitchItem(ii, idx, icreateinfo & 0x3F, iseed);
	}
	else if ( icreateinfo & 0x4000 )
	{
		RecreateHealerItem(ii, idx, icreateinfo & 0x3F, iseed);
	}
}

//----- (0042501F) --------------------------------------------------------
void __cdecl RecalcStoreStats()
{
	ItemStruct *v0; // esi
	int v1; // eax
	ItemStruct *v2; // esi
	int v3; // eax
	ItemStruct *v4; // esi
	int v5; // eax
	ItemStruct *v6; // esi
	int v7; // eax
	int v8; // eax

	v0 = smithitem;
	do
	{
		if ( v0->_itype != -1 )
		{
			_LOBYTE(v1) = StoreStatOk(v0);
			v0->_iStatFlag = v1;
		}
		++v0;
	}
	while ( (signed int)v0 < (signed int)&stextdown );
	v2 = premiumitem;
	do
	{
		if ( v2->_itype != -1 )
		{
			_LOBYTE(v3) = StoreStatOk(v2);
			v2->_iStatFlag = v3;
		}
		++v2;
	}
	while ( (signed int)v2 < (signed int)&pSTextBoxCels );
	v4 = witchitem;
	do
	{
		if ( v4->_itype != -1 )
		{
			_LOBYTE(v5) = StoreStatOk(v4);
			v4->_iStatFlag = v5;
		}
		++v4;
	}
	while ( (signed int)v4 < (signed int)&stextscrl );
	v6 = healitem;
	do
	{
		if ( v6->_itype != -1 )
		{
			_LOBYTE(v7) = StoreStatOk(v6);
			v6->_iStatFlag = v7;
		}
		++v6;
	}
	while ( (signed int)v6 < (signed int)&golditem );
	_LOBYTE(v8) = StoreStatOk(&boyitem);
	boyitem._iStatFlag = v8;
}
// 6A6BB8: using guessed type int stextscrl;
// 6AA700: using guessed type int stextdown;

//----- (004250C0) --------------------------------------------------------
void __cdecl ItemNoFlippy()
{
	int v0; // ecx
	int v1; // edx

	v0 = *(&dupe_delay + numitems);
	v1 = items[v0]._iAnimLen;
	items[v0]._iAnimFlag = 0;
	items[v0]._iAnimFrame = v1;
	items[v0]._iSelFlag = 1;
}

//----- (004250EF) --------------------------------------------------------
void __fastcall CreateSpellBook(int x, int y, int ispell, unsigned char sendmsg, int delta)
{
	int v5; // esi
	int v6; // ebx
	int v7; // edi
	int v8; // esi
	int v9; // ecx
	int v10; // ST04_4
	int v11; // eax
	int idx; // [esp+8h] [ebp-8h]
	signed int v13; // [esp+Ch] [ebp-4h]

	v13 = 0;
	v5 = y;
	v6 = x;
	idx = RndTypeItems(0, 24);
	if ( numitems < 127 )
	{
		v7 = itemavail[0];
		GetSuperItemSpace(v6, v5, itemavail[0]);
		v8 = v7;
		v9 = itemavail[-numitems + 126];
		itemactive[numitems] = v7;
		itemavail[0] = v9;
		do
		{
			v10 = 2 * currlevel;
			v11 = GetRndSeed();
			SetupAllItems(v7, idx, v11, v10, 1, 1, 0, delta);
			if ( items[v8]._iMiscId == IMISC_BOOK && items[v8]._iSpell == ispell )
				v13 = 1;
		}
		while ( !v13 );
		if ( sendmsg )
			NetSendCmdDItem(0, v7);
		if ( delta )
			DeltaAddItem(v7);
		++numitems;
	}
}

//----- (004251B8) --------------------------------------------------------
void __fastcall CreateMagicItem(int x, int y, int imisc, int icurs, int sendmsg, int delta)
{
	int v6; // esi
	int *v7; // ecx
	int i; // ebx
	int v9; // ST04_4
	int v10; // eax

	if ( numitems < 127 )
	{
		v6 = itemavail[0];
		GetSuperItemSpace(x, y, itemavail[0]);
		v7 = &itemavail[-numitems + 126];
		itemactive[numitems] = v6;
		itemavail[0] = *v7;
		for ( i = RndTypeItems(imisc, 0); ; i = RndTypeItems(imisc, 0) )
		{
			v9 = 2 * currlevel;
			v10 = GetRndSeed();
			SetupAllItems(v6, i, v10, v9, 1, 1, 0, delta);
			if ( items[v6]._iCurs == icurs )
				break;
		}
		if ( sendmsg )
			NetSendCmdDItem(0, v6);
		if ( delta )
			DeltaAddItem(v6);
		++numitems;
	}
}

//----- (0042526E) --------------------------------------------------------
int __fastcall GetItemRecord(int dwSeed, int CI, int indx)
{
	int v3; // edi
	int *v4; // ebx
	int v6; // [esp+Ch] [ebp-18h]
	DWORD v7; // [esp+10h] [ebp-14h]
	int *v8; // [esp+14h] [ebp-10h]
	short *v9; // [esp+18h] [ebp-Ch]
	ItemGetRecordStruct *v10; // [esp+1Ch] [ebp-8h]
	short v11; // [esp+20h] [ebp-4h]

	v11 = CI;
	v6 = dwSeed;
	v3 = 0;
	v7 = GetTickCount();
	if ( gnNumGetRecords <= 0 )
		return 1;
	v8 = &itemrecords[0].nIndex;
	v9 = &itemrecords[0].wCI;
	v10 = itemrecords;
	v4 = &itemrecords[0].dwTimestamp;
	while ( v7 - *v4 > 0x1770 )
	{
		NextItemRecord(v3);
		--v10;
		v9 -= 8;
		--v3;
		v4 -= 4;
		v8 -= 4;
LABEL_8:
		++v10;
		v9 += 8;
		v8 += 4;
		++v3;
		v4 += 4;
		if ( v3 >= gnNumGetRecords )
			return 1;
	}
	if ( v6 != v10->nSeed || v11 != *v9 || indx != *v8 )
		goto LABEL_8;
	return 0;
}

//----- (00425311) --------------------------------------------------------
void __fastcall NextItemRecord(int a1)
{
	int v1; // eax
	int v2; // eax
	int v3; // ecx

	v1 = gnNumGetRecords-- - 1;
	if ( gnNumGetRecords )
	{
		v2 = v1;
		v3 = a1;
		itemrecords[v3].nIndex = itemrecords[v2].nIndex;
		itemrecords[v3].nSeed = itemrecords[v2].nSeed;
		itemrecords[v3].wCI = itemrecords[v2].wCI;
		itemrecords[v3].dwTimestamp = itemrecords[v2].dwTimestamp;
	}
}

//----- (00425357) --------------------------------------------------------
void __fastcall SetItemRecord(int dwSeed, int CI, int indx)
{
	short v3; // si
	int v4; // edi
	int v5; // eax
	int v6; // ecx

	v3 = CI;
	v4 = dwSeed;
	v5 = GetTickCount();
	if ( gnNumGetRecords != 127 )
	{
		v6 = gnNumGetRecords++;
		itemrecords[v6].dwTimestamp = v5;
		itemrecords[v6].nSeed = v4;
		itemrecords[v6].wCI = v3;
		itemrecords[v6].nIndex = indx;
	}
}

//----- (0042539E) --------------------------------------------------------
void __fastcall PutItemRecord(int seed, int ci, int index)
{
	int v3; // edi
	int *v4; // ebx
	int v5; // [esp+Ch] [ebp-18h]
	DWORD v6; // [esp+10h] [ebp-14h]
	int *v7; // [esp+14h] [ebp-10h]
	short *v8; // [esp+18h] [ebp-Ch]
	ItemGetRecordStruct *v9; // [esp+1Ch] [ebp-8h]
	short v10; // [esp+20h] [ebp-4h]

	v10 = ci;
	v5 = seed;
	v3 = 0;
	v6 = GetTickCount();
	if ( gnNumGetRecords > 0 )
	{
		v7 = &itemrecords[0].nIndex;
		v8 = &itemrecords[0].wCI;
		v9 = itemrecords;
		v4 = &itemrecords[0].dwTimestamp;
		do
		{
			if ( v6 - *v4 <= 0x1770 )
			{
				if ( v5 == v9->nSeed && v10 == *v8 && index == *v7 )
				{
					NextItemRecord(v3);
					return;
				}
			}
			else
			{
				NextItemRecord(v3);
				--v9;
				v8 -= 8;
				--v3;
				v4 -= 4;
				v7 -= 4;
			}
			++v9;
			v8 += 8;
			v7 += 4;
			++v3;
			v4 += 4;
		}
		while ( v3 < gnNumGetRecords );
	}
}

//----- (00425443) --------------------------------------------------------
void __fastcall SetLightFX(int x, int y, short s_r, short s_g, int s_b, int d_r, int d_g, int d_b)
{
	_DWORD *v8; // eax
	int v9; // edx
	_DWORD *v10; // [esp+Ch] [ebp-4h]
	int s_ra; // [esp+18h] [ebp+8h]

	*(_DWORD *)d_g = 0;
	*(_DWORD *)d_b = 0;
	v8 = (_DWORD *)s_r;
	v10 = (_DWORD *)y;
	v9 = *(_DWORD *)s_r;
	*(_DWORD *)s_r = 7 - *(_DWORD *)s_g;
	*(_DWORD *)s_g = v9;
	s_ra = *(_DWORD *)s_b;
	*(_DWORD *)s_b = 7 - *(_DWORD *)d_r;
	*(_DWORD *)d_r = s_ra;
	*(_DWORD *)x = *v8 - *(_DWORD *)s_b;
	*v10 = *(_DWORD *)s_g - *(_DWORD *)d_r;
	if ( *(_DWORD *)x < 0 )
	{
		*(_DWORD *)x += 8;
		*(_DWORD *)d_g = 1;
	}
	if ( *v10 < 0 )
	{
		*v10 += 8;
		*(_DWORD *)d_b = 1;
	}
}

//----- (004254BA) --------------------------------------------------------
void __fastcall DoLighting(int nXPos, int nYPos, int nRadius, int Lnum)
{
	int v4; // edi
	int v5; // ebx
	int v6; // ecx
	int v7; // eax
	int v8; // edx
	int v9; // esi
	int v10; // eax
	char *v11; // edi
	signed int v12; // ecx
	int v13; // edx
	_BYTE *v14; // ecx
	int v15; // ebx
	bool v16; // sf
	unsigned char v17; // of
	int v18; // esi
	int v19; // ecx
	char *v20; // edi
	signed int v21; // eax
	int v22; // edx
	_BYTE *v23; // eax
	int v24; // ebx
	int v25; // eax
	int v26; // esi
	char *v27; // edi
	signed int v28; // ecx
	int v29; // edx
	_BYTE *v30; // ecx
	int v31; // ebx
	signed int v32; // ebx
	int v33; // ecx
	char *v34; // esi
	signed int v35; // eax
	int v36; // edx
	_BYTE *v37; // eax
	int v38; // edi
	short s_r[2]; // [esp+Ch] [ebp-44h]
	short s_g[2]; // [esp+10h] [ebp-40h]
	int s_b; // [esp+14h] [ebp-3Ch]
	int d_r; // [esp+18h] [ebp-38h]
	int v43; // [esp+1Ch] [ebp-34h]
	int v44; // [esp+20h] [ebp-30h]
	int v45; // [esp+24h] [ebp-2Ch]
	int v46; // [esp+28h] [ebp-28h]
	int v47; // [esp+2Ch] [ebp-24h]
	int v48; // [esp+30h] [ebp-20h]
	int d_g; // [esp+34h] [ebp-1Ch]
	int d_b; // [esp+38h] [ebp-18h]
	int v51; // [esp+3Ch] [ebp-14h]
	int v52; // [esp+40h] [ebp-10h]
	int y; // [esp+44h] [ebp-Ch]
	int x; // [esp+48h] [ebp-8h]
	int v55; // [esp+4Ch] [ebp-4h]
	int Lnuma; // [esp+5Ch] [ebp+Ch]
	int Lnumb; // [esp+5Ch] [ebp+Ch]
	int Lnumc; // [esp+5Ch] [ebp+Ch]
	int Lnumd; // [esp+5Ch] [ebp+Ch]

	v4 = nYPos;
	v5 = nXPos;
	v6 = 0;
	v7 = 0;
	v48 = nYPos;
	v52 = v5;
	x = 0;
	y = 0;
	s_b = 0;
	d_r = 0;
	d_g = 0;
	d_b = 0;
	if ( Lnum >= 0 )
	{
		v7 = LightList[Lnum]._yoff;
		x = LightList[Lnum]._xoff;
		v6 = x;
		y = v7;
		if ( x < 0 )
		{
			v6 = x + 8;
			--v5;
			x += 8;
			v52 = v5;
		}
		if ( v7 < 0 )
		{
			v7 += 8;
			v4 = nYPos - 1;
			y = v7;
			v48 = nYPos - 1;
		}
	}
	*(_DWORD *)s_r = v6;
	*(_DWORD *)s_g = v7;
	v8 = 15;
	if ( v5 - 15 >= 0 )
		v44 = 15;
	else
		v44 = v5 + 1;
	if ( v5 + 15 <= 112 )
		v46 = 15;
	else
		v46 = 112 - v5;
	if ( v4 - 15 >= 0 )
		v43 = 15;
	else
		v43 = v4 + 1;
	if ( v4 + 15 > 112 )
		v8 = 112 - v4;
	v45 = v8;
	if ( v5 >= 0 && v5 < 112 && v4 >= 0 && v4 < 112 )
		dTransVal[v5][v4] = 0;
	v55 = 0;
	v51 = v6 + 8 * v7;
	if ( v43 > 0 )
	{
		v47 = v4;
		do
		{
			Lnuma = 1;
			if ( v46 > 1 )
			{
				v9 = v5 + 1;
				v10 = 112 * (v5 + 1);
				v11 = &dung_map_rgba[16 * (v55 + 16 * v51)];
				do
				{
					v12 = (unsigned char)v11[Lnuma];
					if ( v12 < 128 )
					{
						v13 = (unsigned char)dung_map_radius[128 * nRadius + v12];
						if ( v9 >= 0 && v9 < 112 && v47 >= 0 && v47 < 112 )
						{
							v14 = (unsigned char *)dTransVal + v47 + v10;
							v15 = (char)*v14;
							v17 = __OFSUB__(v13, v15);
							v16 = v13 - v15 < 0;
							v5 = v52;
							if ( v16 ^ v17 )
								*v14 = v13;
						}
					}
					++Lnuma;
					v10 += 112;
					++v9;
				}
				while ( Lnuma < v46 );
				v4 = v48;
			}
			++v55;
			++v47;
		}
		while ( v55 < v43 );
	}
	SetLightFX((int)&x, (int)&y, (unsigned int)s_r, (unsigned int)s_g, (int)&s_b, (int)&d_r, (int)&d_g, (int)&d_b);
	v18 = 0;
	v51 = x + 8 * y;
	if ( v45 > 0 )
	{
		v47 = 112 * v5;
		do
		{
			Lnumb = 1;
			if ( v46 > 1 )
			{
				v19 = v4 - 1;
				v20 = &dung_map_rgba[16 * (d_b + v18 + 16 * v51) + d_g];
				do
				{
					v21 = (unsigned char)v20[Lnumb];
					if ( v21 < 128 )
					{
						v22 = (unsigned char)dung_map_radius[128 * nRadius + v21];
						if ( v18 + v5 >= 0 && v18 + v5 < 112 && v19 >= 0 && v19 < 112 )
						{
							v23 = (unsigned char *)dTransVal + v47 + v19;
							v24 = (char)*v23;
							v17 = __OFSUB__(v22, v24);
							v16 = v22 - v24 < 0;
							v5 = v52;
							if ( v16 ^ v17 )
								*v23 = v22;
						}
					}
					++Lnumb;
					--v19;
				}
				while ( Lnumb < v46 );
				v4 = v48;
			}
			v47 += 112;
			++v18;
		}
		while ( v18 < v45 );
	}
	SetLightFX((int)&x, (int)&y, (unsigned int)s_r, (unsigned int)s_g, (int)&s_b, (int)&d_r, (int)&d_g, (int)&d_b);
	v55 = 0;
	v51 = x + 8 * y;
	if ( v45 > 0 )
	{
		v46 = v4;
		do
		{
			Lnumc = 1;
			if ( v44 > 1 )
			{
				v25 = 112 * v5 - 112;
				v26 = v5 - 1;
				v27 = &dung_map_rgba[16 * (d_b + v55 + 16 * v51) + d_g];
				do
				{
					v28 = (unsigned char)v27[Lnumc];
					if ( v28 < 128 )
					{
						v29 = (unsigned char)dung_map_radius[128 * nRadius + v28];
						if ( v26 >= 0 && v26 < 112 && v46 >= 0 && v46 < 112 )
						{
							v30 = (unsigned char *)dTransVal + v46 + v25;
							v31 = (char)*v30;
							v17 = __OFSUB__(v29, v31);
							v16 = v29 - v31 < 0;
							v5 = v52;
							if ( v16 ^ v17 )
								*v30 = v29;
						}
					}
					++Lnumc;
					v25 -= 112;
					--v26;
				}
				while ( Lnumc < v44 );
				v4 = v48;
			}
			++v55;
			--v46;
		}
		while ( v55 < v45 );
	}
	SetLightFX((int)&x, (int)&y, (unsigned int)s_r, (unsigned int)s_g, (int)&s_b, (int)&d_r, (int)&d_g, (int)&d_b);
	v55 = 0;
	v51 = x + 8 * y;
	if ( v43 > 0 )
	{
		Lnumd = v5;
		*(_DWORD *)s_r = 112 * v5;
		do
		{
			v32 = 1;
			if ( v44 > 1 )
			{
				v33 = v4 + 1;
				v34 = &dung_map_rgba[16 * (d_b + v55 + 16 * v51) + d_g];
				do
				{
					v35 = (unsigned char)v34[v32];
					if ( v35 < 128 )
					{
						v36 = (unsigned char)dung_map_radius[128 * nRadius + v35];
						if ( Lnumd >= 0 && Lnumd < 112 && v33 >= 0 && v33 < 112 )
						{
							v37 = (unsigned char *)dTransVal + v33 + *(_DWORD *)s_r;
							v38 = (char)*v37;
							v17 = __OFSUB__(v36, v38);
							v16 = v36 - v38 < 0;
							v4 = v48;
							if ( v16 ^ v17 )
								*v37 = v36;
						}
					}
					++v32;
					++v33;
				}
				while ( v32 < v44 );
			}
			++v55;
			--Lnumd;
			*(_DWORD *)s_r -= 112;
		}
		while ( v55 < v43 );
	}
}

//----- (004258B0) --------------------------------------------------------
void __fastcall DoUnLight(int nXPos, int nYPos, int nRadius)
{
	int v3; // ebx
	int v4; // esi
	int v5; // edx
	int v6; // edi
	signed int v7; // esi
	int v8; // eax
	int nRadiusa; // [esp+14h] [ebp+8h]

	v3 = nYPos + nRadius + 1;
	v4 = nYPos - (nRadius + 1);
	v5 = nXPos - (nRadius + 1);
	v6 = nXPos + nRadius + 1;
	if ( v4 < 0 )
		v4 = 0;
	if ( v3 > 112 )
		v3 = 112;
	if ( v5 < 0 )
		v5 = 0;
	if ( v6 > 112 )
		v6 = 112;
	for ( nRadiusa = v4; nRadiusa < v3; ++nRadiusa )
	{
		v7 = v5;
		if ( v5 < v6 )
		{
			v8 = nRadiusa + 112 * v5;
			do
			{
				if ( v7 >= 0 && v7 < 112 && nRadiusa >= 0 && nRadiusa < 112 )
					dTransVal[0][v8] = dTransVal2[0][v8];
				++v7;
				v8 += 112;
			}
			while ( v7 < v6 );
		}
	}
}

//----- (00425930) --------------------------------------------------------
void __fastcall DoUnVision(int nXPos, int nYPos, int nRadius)
{
	int v3; // edi
	int v4; // esi
	int v5; // edx
	int v6; // ecx
	char *v7; // eax
	int v8; // ecx
	int i; // edx

	v3 = nYPos + nRadius + 1;
	v4 = nYPos - (nRadius + 1);
	v5 = nXPos - (nRadius + 1);
	v6 = nRadius + 1 + nXPos;
	if ( v4 < 0 )
		v4 = 0;
	if ( v3 > 112 )
		v3 = 112;
	if ( v5 < 0 )
		v5 = 0;
	if ( v6 > 112 )
		v6 = 112;
	if ( v5 < v6 )
	{
		v7 = dFlags[v5];
		v8 = v6 - v5;
		do
		{
			for ( i = v4; i < v3; ++i )
				v7[i] &= 0xBDu;
			v7 += 112;
			--v8;
		}
		while ( v8 );
	}
}

//----- (0042598A) --------------------------------------------------------
void __fastcall DoVision(int nXPos, int nYPos, int nRadius, unsigned char doautomap, int visible)
{
	char *v5; // esi
	int v6; // esi
	int v7; // edi
	unsigned char *v8; // eax
	int v9; // ebx
	int v10; // ecx
	unsigned char v11; // dl
	int v12; // ecx
	int v13; // ecx
	unsigned char v14; // cl
	unsigned char v15; // dl
	int v16; // ecx
	int v17; // ecx
	int i; // [esp+Ch] [ebp-34h]
	unsigned char *v19; // [esp+10h] [ebp-30h]
	int v20; // [esp+14h] [ebp-2Ch]
	int v21; // [esp+18h] [ebp-28h]
	int v22; // [esp+1Ch] [ebp-24h]
	signed int v23; // [esp+20h] [ebp-20h]
	signed int v24; // [esp+24h] [ebp-1Ch]
	signed int v25; // [esp+28h] [ebp-18h]
	signed int v26; // [esp+2Ch] [ebp-14h]
	signed int v27; // [esp+30h] [ebp-10h]
	int v28; // [esp+34h] [ebp-Ch]
	int v29; // [esp+38h] [ebp-8h]
	unsigned char v30; // [esp+3Fh] [ebp-1h]
	unsigned char v31; // [esp+3Fh] [ebp-1h]

	v28 = nYPos;
	v29 = nXPos;
	if ( nXPos >= 0 && nXPos <= 112 && nYPos >= 0 && nYPos <= 112 )
	{
		if ( doautomap )
		{
			v5 = &dFlags[nXPos][nYPos];
			if ( *v5 >= 0 )
			{
				SetAutomapView(nXPos, nXPos);
				nYPos = v28;
				nXPos = v29;
			}
			*v5 |= 0x80u;
		}
		if ( visible )
			dFlags[nXPos][nYPos] |= 0x40u;
		dFlags[nXPos][nYPos] |= 2u;
	}
	v27 = 0;
	v6 = doautomap;
	v7 = doautomap;
	do
	{
		v20 = 0;
		v8 = &vCrawlTable[0][1];
		v19 = &vCrawlTable[0][1];
		do
		{
			v9 = 0;
			v21 = 0;
			for ( i = 2 * (nRadius - RadiusAdj[21][v20 + 10]); v9 < i; v9 += 2 )
			{
				if ( v21 )
					break;
				v26 = 0;
				v24 = 0;
				v25 = 0;
				v23 = 0;
				if ( v27 )
				{
					switch ( v27 )
					{
						case 1:
							v13 = v8[v9 - 1];
							v6 = v29 - (unsigned char)v13;
							v31 = v8[v9];
							v7 = v28 - v31;
							if ( (_BYTE)v13 && v31 )
							{
								v25 = 1;
								v24 = 1;
							}
							break;
						case 2:
							v12 = v8[v9 - 1];
							v30 = v8[v9];
							v6 = v29 + (unsigned char)v12;
							v7 = v28 - v30;
							if ( (_BYTE)v12 && v30 )
							{
								v26 = -1;
								v23 = 1;
							}
							break;
						case 3:
							v10 = v8[v9 - 1];
							v6 = v29 - (unsigned char)v10;
							v11 = v8[v9];
							v7 = v28 + v11;
							if ( (_BYTE)v10 )
							{
								if ( v11 )
								{
									v25 = -1;
									v24 = 1;
								}
							}
							break;
					}
				}
				else
				{
					v14 = v8[v9 - 1];
					v15 = v8[v9];
					v6 = v29 + v14;
					v7 = v28 + v15;
					if ( v14 && v15 )
					{
						v26 = -1;
						v23 = -1;
					}
				}
				if ( v6 >= 0 && v6 <= 112 && v7 >= 0 && v7 <= 112 )
				{
					v22 = v7 + 112 * v6;
					v21 = (unsigned char)nBlockTable[dPiece[0][v22]];
					if ( !nBlockTable[dPiece[0][v25 + v7 + 112 * (v6 + v26)]]
					  || !nBlockTable[dPiece[0][v23 + v7 + 112 * (v6 + v24)]] )
					{
						v16 = v7 + 112 * v6;
						if ( doautomap )
						{
							if ( dFlags[0][v22] >= 0 )
							{
								SetAutomapView(v6, v7);
								v16 = v7 + 112 * v6;
								v8 = v19;
							}
							dFlags[0][v16] |= 0x80u;
						}
						if ( visible )
							dFlags[0][v16] |= 0x40u;
						dFlags[0][v16] |= 2u;
						if ( !v21 )
						{
							v17 = dung_map[0][v16];
							if ( v17 )
								TransList[v17] = 1;
						}
					}
				}
			}
			++v20;
			v8 += 30;
			v19 = v8;
		}
		while ( (signed int)v8 < (signed int)RadiusAdj );
		++v27;
	}
	while ( v27 < 4 );
}

//----- (00425C13) --------------------------------------------------------
void __cdecl FreeLightTable()
{
	void *v0; // ecx

	v0 = (void *)dword_646A20;
	dword_646A20 = 0;
	mem_free_dbg(v0);
}

//----- (00425C25) --------------------------------------------------------
void __cdecl InitLightTable()
{
	dword_646A20 = (int)DiabloAllocPtr(6912);
}

//----- (00425C35) --------------------------------------------------------
void __cdecl MakeLightTable()
{
	char *v0; // ebx
	signed int v1; // esi
	unsigned char v2; // al
	unsigned char v3; // cl
	signed int v4; // edi
	int v5; // edx
	signed int v6; // edi
	unsigned char v7; // cl
	unsigned char v8; // al
	signed int v9; // edx
	unsigned char v10; // cl
	unsigned char v11; // al
	char *v12; // ebx
	_BYTE *v13; // ebx
	int v14; // ecx
	signed int v15; // esi
	char v16; // al
	int v17; // edx
	int v18; // ebx
	signed int v19; // esi
	_BYTE *v20; // ebx
	char *v21; // ebx
	int v22; // edi
	unsigned char *v23; // esi
	signed int v24; // edx
	unsigned char *v25; // esi
	signed int v26; // edx
	signed int v27; // ecx
	char v28; // al
	_BYTE *v29; // ebx
	signed int v30; // edx
	char v31; // al
	signed int v32; // ecx
	signed int v33; // ecx
	char v34; // al
	int v35; // eax
	signed int v36; // esi
	char *v37; // eax
	signed int v38; // ebx
	int v39; // esi
	double v40; // st7
	double v41; // st6
	int v42; // ecx
	char *v43; // ecx
	bool v44; // zf
	char v45; // [esp+14h] [ebp-2Ch]
	int v46; // [esp+15h] [ebp-2Bh]
	int v47; // [esp+19h] [ebp-27h]
	int v48; // [esp+1Dh] [ebp-23h]
	short v49; // [esp+21h] [ebp-1Fh]
	char v50; // [esp+23h] [ebp-1Dh]
	int v51; // [esp+24h] [ebp-1Ch]
	int v52; // [esp+28h] [ebp-18h]
	char *v53; // [esp+2Ch] [ebp-14h]
	int v54; // [esp+30h] [ebp-10h]
	int v55; // [esp+34h] [ebp-Ch]
	int v56; // [esp+38h] [ebp-8h]
	int v57; // [esp+3Ch] [ebp-4h]

	v56 = 0;
	v0 = (char *)dword_646A20;
	v1 = light4flag != 0 ? 3 : 15;
	v55 = light4flag != 0 ? 3 : 15;
	if ( v1 > 0 )
	{
		v54 = light4flag != 0 ? 3 : 15;
		do
		{
			*v0++ = 0;
			v57 = 0;
			do
			{
				v2 = 16 * v57 + 15;
				v3 = v56 + 16 * v57;
				v4 = 0;
				do
				{
					if ( v4 || v57 )
						*v0++ = v3;
					if ( v3 >= v2 )
					{
						v2 = 0;
						v3 = 0;
					}
					else
					{
						++v3;
					}
					++v4;
				}
				while ( v4 < 16 );
				++v57;
			}
			while ( v57 < 8 );
			v57 = 16;
			v5 = v56 >> 1;
			do
			{
				v6 = 8;
				v7 = v5 + 8 * v57;
				v8 = 8 * v57 + 7;
				do
				{
					*v0++ = v7;
					if ( v7 >= v8 )
					{
						v8 = 0;
						v7 = 0;
					}
					else
					{
						++v7;
					}
					--v6;
				}
				while ( v6 );
				++v57;
			}
			while ( v57 < 20 );
			v57 = 10;
			do
			{
				v9 = 16;
				v10 = v56 + 16 * v57;
				v11 = 16 * v57 + 15;
				do
				{
					*v0++ = v10;
					if ( v10 >= v11 )
					{
						v11 = 0;
						v10 = 0;
					}
					else
					{
						++v10;
					}
					if ( v10 == -1 )
					{
						v11 = 0;
						v10 = 0;
					}
					--v9;
				}
				while ( v9 );
				++v57;
			}
			while ( v57 < 16 );
			if ( light4flag )
				v56 += 5;
			else
				++v56;
			--v54;
		}
		while ( v54 );
	}
	memset(v0, 0, 0x100u);
	v12 = v0 + 256;
	if ( leveltype == 4 )
	{
		v13 = (_BYTE *)dword_646A20;
		if ( v1 > 0 )
		{
			v14 = v55;
			v54 = v55;
			do
			{
				v57 = 0;
				v45 = 0;
				v56 = v14;
				v15 = 1;
				v53 = (char *)(v55 / v14);
				v52 = v55 % v14;
				v16 = 1;
				do
				{
					v17 = v56;
					*(&v45 + v15) = v16;
					v56 = v52 + v17;
					if ( v52 + v17 > v14 && v15 < 15 )
					{
						++v15;
						v56 -= v14;
						*(&v45 + v15) = v16;
					}
					if ( (char *)++v57 == v53 )
					{
						++v16;
						v57 = 0;
					}
					++v15;
				}
				while ( v15 < 16 );
				*v13 = 0;
				v18 = (int)(v13 + 1);
				*(_DWORD *)v18 = v46;
				*(_DWORD *)(v18 + 4) = v47;
				*(_DWORD *)(v18 + 8) = v48;
				*(_WORD *)(v18 + 12) = v49;
				*(_BYTE *)(v18 + 14) = v50;
				v19 = 15;
				v20 = (_BYTE *)(v18 + 15);
				do
					*v20++ = *(&v45 + v19--);
				while ( v19 > 0 );
				*v20 = 1;
				v13 = v20 + 225;
				--v14;
				--v54;
			}
			while ( v54 );
		}
		*v13 = 0;
		v21 = (char *)v13 + 1;
		memset(v21, 1u, 0x1Cu);
		v22 = (int)(v21 + 28);
		*(_WORD *)v22 = 257;
		*(_BYTE *)(v22 + 2) = 1;
		v12 = v21 + 255;
	}
	v23 = LoadFileInMem("PlrGFX\\Infra.TRN", 0);
	v24 = 0;
	do
		*v12++ = v23[v24++];
	while ( v24 < 256 );
	mem_free_dbg(v23);
	v25 = LoadFileInMem("PlrGFX\\Stone.TRN", 0);
	v26 = 0;
	do
		*v12++ = v25[v26++];
	while ( v26 < 256 );
	mem_free_dbg(v25);
	v27 = 0;
	do
	{
		v28 = -30;
		do
		{
			if ( v27 || v28 != -30 )
				*v12 = v28;
			else
				*v12 = 0;
			++v12;
			++v28;
		}
		while ( (unsigned char)v28 < 0xEFu );
		*v12 = 0;
		v29 = (unsigned char *)v12 + 1;
		*v29++ = 0;
		*v29 = 0;
		v12 = (char *)v29 + 1;
		++v27;
	}
	while ( v27 < 8 );
	v30 = 4;
	do
	{
		v31 = -32;
		v32 = 8;
		do
		{
			*v12++ = v31;
			v31 += 2;
			--v32;
		}
		while ( v32 );
		--v30;
	}
	while ( v30 );
	v33 = 6;
	do
	{
		v34 = -32;
		do
			*v12++ = v34++;
		while ( (unsigned char)v34 < 0xEFu );
		*v12++ = 0;
		--v33;
	}
	while ( v33 );
	v35 = 0;
	v56 = (int)dung_map_radius;
	v57 = 8;
	do
	{
		v36 = 0;
		v54 = 0;
		v55 = v35 + 1;
		do
		{
			if ( v36 <= v57 )
				*(_BYTE *)(v56 + v36) = (signed __int64)((double)v54 * 15.0 / ((double)v55 * 8.0) + 0.5);
			else
				*(_BYTE *)(v56 + v36) = 15;
			v54 = ++v36;
		}
		while ( v36 < 128 );
		v57 += 8;
		v56 += 128;
		v35 = v55;
	}
	while ( v57 < 136 );
	v54 = 0;
	v37 = dung_map_rgba;
	do
	{
		v57 = 0;
		do
		{
			v53 = v37;
			v55 = v54;
			v52 = 16;
			do
			{
				v38 = 0;
				v39 = v55 * v55;
				v56 = v57;
				do
				{
					v51 = v39 + v56 * v56;
					v51 = (unsigned char)(signed __int64)sqrt((double)v51);
					v40 = (double)v51;
					if ( v40 >= 0.0 )
						v41 = 0.5;
					else
						v41 = -0.5;
					v42 = (int)v53;
					v56 += 8;
					v53[v38++] = (signed __int64)(v41 + v40);
				}
				while ( v38 < 16 );
				v55 += 8;
				v43 = (char *)(v42 + 16);
				v44 = v52-- == 1;
				v53 = v43;
			}
			while ( !v44 );
			--v57;
			v37 = v43;
		}
		while ( v57 > -8 );
		--v54;
	}
	while ( (signed int)v43 < (signed int)&visionid );
}
// 525728: using guessed type int light4flag;
// 5BB1ED: using guessed type char leveltype;

//----- (00425FB8) --------------------------------------------------------
void __cdecl InitLightMax()
{
	lightmax = light4flag == 0 ? 15 : 3;
}
// 525728: using guessed type int light4flag;
// 642A14: using guessed type char lightmax;

//----- (00425FCE) --------------------------------------------------------
void __cdecl InitLighting()
{
	signed int v0; // eax

	v0 = 0;
	numlights = 0;
	dword_642A18 = 0;
	lightflag = 0;
	do
	{
		lightactive[v0] = v0;
		++v0;
	}
	while ( v0 < 32 );
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (00425FEC) --------------------------------------------------------
int __fastcall AddLight(int x, int y, int r)
{
	int result; // eax
	int v4; // esi

	result = -1;
	if ( !lightflag && numlights < 32 )
	{
		result = (unsigned char)lightactive[numlights];
		dword_642A18 = 1;
		++numlights;
		v4 = result;
		LightList[v4]._lx = x;
		LightList[v4]._ly = y;
		LightList[v4]._lradius = r;
		LightList[v4]._xoff = 0;
		LightList[v4]._yoff = 0;
		LightList[v4]._ldel = 0;
		LightList[v4]._lunflag = 0;
	}
	return result;
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (00426056) --------------------------------------------------------
void __fastcall AddUnLight(int i)
{
	if ( !lightflag && i != -1 )
	{
		LightList[i]._ldel = 1;
		dword_642A18 = 1;
	}
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (00426076) --------------------------------------------------------
void __fastcall ChangeLightRadius(int i, int r)
{
	int v2; // eax
	int v3; // edi

	if ( !lightflag && i != -1 )
	{
		v2 = i;
		LightList[v2]._lunx = LightList[v2]._lx;
		LightList[v2]._luny = LightList[v2]._ly;
		v3 = LightList[i]._lradius;
		LightList[v2]._lunflag = 1;
		LightList[v2]._lunr = v3;
		dword_642A18 = 1;
		LightList[v2]._lradius = r;
	}
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (004260C5) --------------------------------------------------------
void __fastcall ChangeLightXY(int i, int x, int y)
{
	int v3; // eax

	if ( !lightflag && i != -1 )
	{
		v3 = i;
		LightList[v3]._lunx = LightList[v3]._lx;
		LightList[v3]._lunflag = 1;
		dword_642A18 = 1;
		LightList[v3]._luny = LightList[v3]._ly;
		LightList[v3]._lunr = LightList[v3]._lradius;
		LightList[i]._ly = y;
		LightList[i]._lx = x;
	}
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (00426120) --------------------------------------------------------
void __fastcall ChangeLightOff(int i, int x, int y)
{
	int v3; // eax
	int v4; // esi

	if ( !lightflag && i != -1 )
	{
		v3 = i;
		v4 = LightList[i]._lx;
		LightList[v3]._xoff = x;
		LightList[v3]._lunx = v4;
		LightList[v3]._luny = LightList[v3]._ly;
		LightList[v3]._lunr = LightList[v3]._lradius;
		LightList[v3]._lunflag = 1;
		LightList[v3]._yoff = y;
		dword_642A18 = 1;
	}
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (0042617B) --------------------------------------------------------
void __fastcall ChangeLight(int i, int x, int y, int r)
{
	int v4; // eax

	if ( !lightflag && i != -1 )
	{
		v4 = i;
		LightList[v4]._lunx = LightList[v4]._lx;
		LightList[v4]._luny = LightList[v4]._ly;
		LightList[v4]._lunr = LightList[v4]._lradius;
		LightList[v4]._lunflag = 1;
		LightList[v4]._lx = x;
		LightList[v4]._ly = y;
		LightList[i]._lradius = r;
		dword_642A18 = 1;
	}
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (004261E7) --------------------------------------------------------
void __cdecl ProcessLightList()
{
	int v0; // ebp
	int v1; // edi
	int v2; // esi
	int i; // esi
	int v4; // eax
	int v5; // ecx
	unsigned char v6; // bl
	char v7; // dl

	v0 = 0;
	if ( !lightflag )
	{
		if ( dword_642A18 )
		{
			v1 = numlights;
			if ( numlights > 0 )
			{
				do
				{
					v2 = (unsigned char)lightactive[v0];
					if ( LightList[v2]._ldel )
						DoUnLight(LightList[v2]._lx, LightList[v2]._ly, LightList[v2]._lradius);
					if ( LightList[v2]._lunflag )
					{
						DoUnLight(LightList[v2]._lunx, LightList[v2]._luny, LightList[v2]._lunr);
						LightList[v2]._lunflag = 0;
					}
					++v0;
				}
				while ( v0 < v1 );
			}
			for ( i = 0; i < v1; ++i )
			{
				v4 = (unsigned char)lightactive[i];
				if ( !LightList[v4]._ldel )
					DoLighting(
						LightList[v4]._lx,
						LightList[v4]._ly,
						LightList[v4]._lradius,
						(unsigned char)lightactive[i]);
			}
			v5 = 0;
			if ( v1 > 0 )
			{
				do
				{
					v6 = lightactive[v5];
					if ( LightList[v6]._ldel )
					{
						v7 = lightactive[--v1];
						lightactive[v1] = v6;
						lightactive[v5] = v7;
					}
					else
					{
						++v5;
					}
				}
				while ( v5 < v1 );
				numlights = v1;
			}
		}
		dword_642A18 = 0;
	}
}
// 642A18: using guessed type int dword_642A18;
// 646A28: using guessed type int lightflag;

//----- (004262E0) --------------------------------------------------------
void __cdecl SavePreLighting()
{
	memcpy(dTransVal2, dTransVal, 0x3100u);
}

//----- (004262F8) --------------------------------------------------------
void __cdecl InitVision()
{
	numvision = 0;
	dovision = 0;
	visionid = 1;
	if ( TransVal > 0 )
		memset(TransList, 0, TransVal);
}
// 5A5590: using guessed type char TransVal;
// 642A0C: using guessed type int dovision;

//----- (00426333) --------------------------------------------------------
int __fastcall AddVision(int x, int y, int r, unsigned char mine)
{
	int result; // eax
	int v5; // esi

	result = r;
	if ( numvision < 32 )
	{
		v5 = numvision;
		dovision = 1;
		VisionList[v5]._lx = x;
		VisionList[v5]._ly = y;
		VisionList[v5]._lradius = r;
		result = visionid++;
		VisionList[v5]._lid = result;
		VisionList[v5]._ldel = 0;
		++numvision;
		VisionList[v5]._lunflag = 0;
		VisionList[v5]._lflags = mine != 0;
	}
	return result;
}
// 642A0C: using guessed type int dovision;

//----- (004263A0) --------------------------------------------------------
void __fastcall ChangeVisionRadius(int id, int r)
{
	int v2; // esi
	int *v3; // eax
	int v4; // ebx

	v2 = numvision;
	if ( numvision > 0 )
	{
		v3 = &VisionList[0]._lunflag;
		do
		{
			if ( *(v3 - 2) == id )
			{
				v4 = *(v3 - 5);
				*v3 = 1;
				v3[2] = v4;
				v3[3] = *(v3 - 4);
				v3[4] = *(v3 - 3);
				*(v3 - 3) = r;
				dovision = 1;
			}
			v3 += 13;
			--v2;
		}
		while ( v2 );
	}
}
// 642A0C: using guessed type int dovision;

//----- (004263E1) --------------------------------------------------------
void __fastcall ChangeVisionXY(int id, int x, int y)
{
	int v3; // esi
	int *v4; // eax
	int v5; // ebx

	v3 = numvision;
	if ( numvision > 0 )
	{
		v4 = &VisionList[0]._lunflag;
		do
		{
			if ( *(v4 - 2) == id )
			{
				v5 = *(v4 - 5);
				*v4 = 1;
				v4[2] = v5;
				v4[3] = *(v4 - 4);
				v4[4] = *(v4 - 3);
				*(v4 - 5) = x;
				*(v4 - 4) = y;
				dovision = 1;
			}
			v4 += 13;
			--v3;
		}
		while ( v3 );
	}
}
// 642A0C: using guessed type int dovision;

//----- (0042642B) --------------------------------------------------------
void __cdecl ProcessVisionList()
{
	int v0; // ebx
	int *v1; // esi
	int v2; // edi
	int v3; // edi
	int *v4; // esi
	signed int v5; // ecx
	int v6; // ebp
	LightListStruct *v7; // edx
	LightListStruct *v8; // eax

	if ( dovision )
	{
		v0 = numvision;
		if ( numvision > 0 )
		{
			v1 = &VisionList[0]._lradius;
			v2 = numvision;
			do
			{
				if ( v1[2] )
					DoUnVision(*(v1 - 2), *(v1 - 1), *v1);
				if ( v1[3] )
				{
					DoUnVision(v1[5], v1[6], v1[7]);
					v1[3] = 0;
				}
				v1 += 13;
				--v2;
			}
			while ( v2 );
		}
		if ( TransVal > 0 )
			memset(TransList, 0, TransVal);
		v3 = 0;
		if ( v0 > 0 )
		{
			v4 = &VisionList[0]._lflags;
			do
			{
				if ( !*(v4 - 8) )
				{
					DoVision(*(v4 - 12), *(v4 - 11), *(v4 - 10), *(_BYTE *)v4 & 1, *v4 & 1);
					v0 = numvision;
				}
				++v3;
				v4 += 13;
			}
			while ( v3 < v0 );
		}
		do
		{
			v5 = 0;
			v6 = 0;
			if ( v0 <= 0 )
				break;
			v7 = VisionList;
			v8 = &VisionList[v0];
			do
			{
				if ( v7->_ldel )
				{
					--v0;
					--v8;
					if ( v0 > 0 && v6 != v0 )
						qmemcpy(v7, v8, sizeof(LightListStruct));
					v5 = 1;
				}
				++v6;
				++v7;
			}
			while ( v6 < v0 );
		}
		while ( v5 );
		numvision = v0;
	}
	dovision = 0;
}
// 5A5590: using guessed type char TransVal;
// 642A0C: using guessed type int dovision;

//----- (0042651F) --------------------------------------------------------
void __cdecl lighting_color_cycling()
{
	int v0; // eax
	signed int v1; // ebx
	char *v2; // eax
	char *v3; // edi
	char v4; // dl
	const void *v5; // esi

	if ( leveltype == 4 )
	{
		v0 = dword_646A20;
		if ( (light4flag != 0 ? 4 : 16) > 0 )
		{
			v1 = light4flag != 0 ? 4 : 16;
			do
			{
				v2 = (char *)(v0 + 1);
				v3 = v2;
				v4 = *v2;
				v5 = v2 + 1;
				v2 += 30;
				qmemcpy(v3, v5, 0x1Eu);
				*v2 = v4;
				v0 = (int)(v2 + 225);
				--v1;
			}
			while ( v1 );
		}
	}
}
// 525728: using guessed type int light4flag;
// 5BB1ED: using guessed type char leveltype;

//----- (00426564) --------------------------------------------------------
void __fastcall LoadGame(void *a1)
{
	int v1; // esi
	int v2; // edi
	int v3; // eax
	int v4; // eax
	int v5; // ebx
	int v6; // eax
	int v7; // eax
	int v8; // ecx
	bool v9; // sf
	unsigned char v10; // of
	int *v11; // esi
	int *v12; // esi
	int i; // esi
	int *v14; // esi
	int *v15; // esi
	int j; // esi
	int *v17; // esi
	int *v18; // esi
	int k; // esi
	int l; // esi
	signed int v21; // esi
	int m; // esi
	int v23; // esi
	int *v24; // esi
	int *v25; // esi
	int n; // esi
	int *v27; // esi
	int v28; // eax
	char *v29; // edi
	char *v30; // edi
	char *v31; // edi
	char *v32; // edi
	int (*v33)[112]; // ebx
	_DWORD *v34; // edi
	char *v35; // edi
	char *v36; // edi
	char *v37; // edi
	char *v38; // edi
	signed int v39; // ebx
	bool *v40; // edi
	char *v41; // edi
	int v42; // esi
	int v43; // eax
	char dst; // [esp+0h] [ebp-120h]
	int len; // [esp+104h] [ebp-1Ch]
	int v46; // [esp+108h] [ebp-18h]
	int v47; // [esp+10Ch] [ebp-14h]
	void *ptr; // [esp+110h] [ebp-10h]
	int v49; // [esp+114h] [ebp-Ch]
	bool from_save[4]; // [esp+118h] [ebp-8h]
	int quest_num; // [esp+11Ch] [ebp-4h]

	*(_DWORD *)from_save = (unsigned int)a1;
	FreeGameMem();
	pfile_remove_temp_files();
	pfile_get_game_name(&dst);
	ptr = pfile_read(&dst, &len);
	tbuff = ptr;
	if ( ILoad_2() != 'RETL' )
		TermMsg("Invalid save file");
	setlevel = OLoad();
	setlvlnum = ILoad();
	currlevel = ILoad();
	leveltype = ILoad();
	v1 = ILoad();
	v2 = ILoad();
	_LOBYTE(v3) = OLoad();
	invflag = v3;
	_LOBYTE(v4) = OLoad();
	chrflag = v4;
	v5 = ILoad();
	v47 = ILoad();
	v49 = ILoad();
	v6 = ILoad();
	quest_num = 0;
	v46 = v6;
	do
	{
		*(int *)((char *)glSeedTbl + quest_num) = ILoad_2();
		v7 = ILoad();
		v8 = quest_num;
		quest_num += 4;
		v10 = __OFSUB__(quest_num, 68);
		v9 = quest_num - 68 < 0;
		*(int *)((char *)gnLevelTypeTbl + v8) = v7;
	}
	while ( v9 ^ v10 );
	LoadPlayer(myplr);
	quest_num = 0;
	do
		LoadQuest(quest_num++);
	while ( quest_num < 16 );
	quest_num = 0;
	do
		LoadPortal(quest_num++);
	while ( quest_num < 4 );
	LoadGameLevel(from_save[0], 4);
	SyncInitPlr(myplr);
	SyncPlrAnim(myplr);
	ViewX = v1;
	numitems = v47;
	nummissiles = v49;
	ViewY = v2;
	nummonsters = v5;
	nobjects = v46;
	v11 = monstkills;
	do
	{
		*v11 = ILoad_2();
		++v11;
	}
	while ( (signed int)v11 < (signed int)monstactive );
	if ( leveltype )
	{
		v12 = monstactive;
		do
		{
			*v12 = ILoad();
			++v12;
		}
		while ( (signed int)v12 < (signed int)&nummonsters );
		for ( i = 0; i < nummonsters; ++i )
			LoadMonster(monstactive[i]);
		v14 = missileactive;
		do
		{
			*v14 = BLoad();
			++v14;
		}
		while ( (signed int)v14 < (signed int)missileavail );
		v15 = missileavail;
		do
		{
			*v15 = BLoad();
			++v15;
		}
		while ( (signed int)v15 < (signed int)missile );
		for ( j = 0; j < nummissiles; ++j )
			LoadMissile(missileactive[j]);
		v17 = objectactive;
		do
		{
			*v17 = BLoad();
			++v17;
		}
		while ( (signed int)v17 < (signed int)&nobjects );
		v18 = objectavail;
		do
		{
			*v18 = BLoad();
			++v18;
		}
		while ( (signed int)v18 < (signed int)object );
		for ( k = 0; k < nobjects; ++k )
			LoadObject(objectactive[k]);
		for ( l = 0; l < nobjects; ++l )
			SyncObjectAnim(objectactive[l]);
		numlights = ILoad();
		v21 = 0;
		do
			lightactive[v21++] = BLoad();
		while ( v21 < 32 );
		for ( m = 0; m < numlights; ++m )
			LoadLighting((unsigned char)lightactive[m]);
		visionid = ILoad();
		v23 = 0;
		numvision = ILoad();
		if ( numvision > 0 )
		{
			do
				LoadVision(v23++);
			while ( v23 < numvision );
		}
	}
	v24 = itemactive;
	do
	{
		*v24 = BLoad();
		++v24;
	}
	while ( (signed int)v24 < (signed int)&uitemflag );
	v25 = itemavail;
	do
	{
		*v25 = BLoad();
		++v25;
	}
	while ( (signed int)v25 < (signed int)&itemavail[127] );
	for ( n = 0; n < numitems; ++n )
		LoadItem(itemactive[n]);
	v27 = UniqueItemFlag;
	do
	{
		_LOBYTE(v28) = OLoad();
		*v27 = v28;
		++v27;
	}
	while ( (signed int)v27 < (signed int)&numitems );
	quest_num = 0;
	do
	{
		*(_DWORD *)from_save = 112;
		v29 = (char *)dTransVal + quest_num;
		do
		{
			*v29 = BLoad();
			v29 += 112;
			--*(_DWORD *)from_save;
		}
		while ( *(_DWORD *)from_save );
		++quest_num;
	}
	while ( quest_num < 112 );
	quest_num = 0;
	do
	{
		*(_DWORD *)from_save = 112;
		v30 = (char *)dFlags + quest_num;
		do
		{
			*v30 = BLoad();
			v30 += 112;
			--*(_DWORD *)from_save;
		}
		while ( *(_DWORD *)from_save );
		++quest_num;
	}
	while ( quest_num < 112 );
	quest_num = 0;
	do
	{
		*(_DWORD *)from_save = 112;
		v31 = (char *)dPlayer + quest_num;
		do
		{
			*v31 = BLoad();
			v31 += 112;
			--*(_DWORD *)from_save;
		}
		while ( *(_DWORD *)from_save );
		++quest_num;
	}
	while ( quest_num < 112 );
	quest_num = 0;
	do
	{
		*(_DWORD *)from_save = 112;
		v32 = (char *)dItem + quest_num;
		do
		{
			*v32 = BLoad();
			v32 += 112;
			--*(_DWORD *)from_save;
		}
		while ( *(_DWORD *)from_save );
		++quest_num;
	}
	while ( quest_num < 112 );
	if ( leveltype )
	{
		v33 = dMonster;
		do
		{
			v34 = (unsigned int *)v33;
			*(_DWORD *)from_save = 112;
			do
			{
				*v34 = ILoad();
				v34 += 112;
				--*(_DWORD *)from_save;
			}
			while ( *(_DWORD *)from_save );
			v33 = (int (*)[112])((char *)v33 + 4);
		}
		while ( (signed int)v33 < (signed int)dMonster[1] );
		quest_num = 0;
		do
		{
			*(_DWORD *)from_save = 112;
			v35 = (char *)dDead + quest_num;
			do
			{
				*v35 = BLoad();
				v35 += 112;
				--*(_DWORD *)from_save;
			}
			while ( *(_DWORD *)from_save );
			++quest_num;
		}
		while ( quest_num < 112 );
		quest_num = 0;
		do
		{
			*(_DWORD *)from_save = 112;
			v36 = (char *)dObject + quest_num;
			do
			{
				*v36 = BLoad();
				v36 += 112;
				--*(_DWORD *)from_save;
			}
			while ( *(_DWORD *)from_save );
			++quest_num;
		}
		while ( quest_num < 112 );
		quest_num = 0;
		do
		{
			*(_DWORD *)from_save = 112;
			v37 = (char *)dTransVal + quest_num;
			do
			{
				*v37 = BLoad();
				v37 += 112;
				--*(_DWORD *)from_save;
			}
			while ( *(_DWORD *)from_save );
			++quest_num;
		}
		while ( quest_num < 112 );
		quest_num = 0;
		do
		{
			*(_DWORD *)from_save = 112;
			v38 = (char *)dTransVal2 + quest_num;
			do
			{
				*v38 = BLoad();
				v38 += 112;
				--*(_DWORD *)from_save;
			}
			while ( *(_DWORD *)from_save );
			++quest_num;
		}
		while ( quest_num < 112 );
		v39 = 0;
		do
		{
			v40 = (bool *)automapview + v39;
			*(_DWORD *)from_save = 40;
			do
			{
				*v40 = OLoad();
				v40 += 40;
				--*(_DWORD *)from_save;
			}
			while ( *(_DWORD *)from_save );
			++v39;
		}
		while ( v39 < 40 );
		quest_num = 0;
		do
		{
			*(_DWORD *)from_save = 112;
			v41 = (char *)dMissile + quest_num;
			do
			{
				*v41 = BLoad();
				v41 += 112;
				--*(_DWORD *)from_save;
			}
			while ( *(_DWORD *)from_save );
			++quest_num;
		}
		while ( quest_num < 112 );
	}
	numpremium = ILoad();
	premiumlevel = ILoad();
	v42 = 0;
	do
		LoadPremium(v42++);
	while ( v42 < 6 );
	_LOBYTE(v43) = OLoad();
	*(_DWORD *)&automapflag = v43;
	AutoMapScale = ILoad();
	mem_free_dbg(ptr);
	AutomapZoomReset();
	ResyncQuests();
	if ( leveltype )
		ProcessLightList();
	RedoPlayerVision();
	ProcessVisionList();
	missiles_process_charge();
	ResetPal();
	SetCursor(1);
	gbProcessPlayers = 1;
}
// 5256A0: using guessed type int gbProcessPlayers;
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (00426AE2) --------------------------------------------------------
char __cdecl BLoad()
{
	char result; // al

	result = *(_BYTE *)tbuff;
	tbuff = (char *)tbuff + 1;
	return result;
}

//----- (00426AF0) --------------------------------------------------------
int __cdecl ILoad()
{
	int v0; // eax
	int v1; // eax
	unsigned short v2; // dx
	int result; // eax

	v0 = *(unsigned char *)tbuff << 24;
	tbuff = (char *)tbuff + 1;
	v1 = (*(unsigned char *)tbuff << 16) | v0;
	_LOBYTE(v2) = 0;
	tbuff = (char *)tbuff + 1;
	_HIBYTE(v2) = *(_BYTE *)tbuff;
	tbuff = (char *)tbuff + 1;
	result = *(unsigned char *)tbuff | v2 | v1;
	tbuff = (char *)tbuff + 1;
	return result;
}

//----- (00426B2C) --------------------------------------------------------
int __cdecl ILoad_2()
{
	int v0; // eax
	int v1; // eax
	unsigned short v2; // dx
	int result; // eax

	v0 = *(unsigned char *)tbuff << 24;
	tbuff = (char *)tbuff + 1;
	v1 = (*(unsigned char *)tbuff << 16) | v0;
	_LOBYTE(v2) = 0;
	tbuff = (char *)tbuff + 1;
	_HIBYTE(v2) = *(_BYTE *)tbuff;
	tbuff = (char *)tbuff + 1;
	result = *(unsigned char *)tbuff | v2 | v1;
	tbuff = (char *)tbuff + 1;
	return result;
}

//----- (00426B68) --------------------------------------------------------
bool __cdecl OLoad()
{
	char v0; // cl
	bool result; // al

	v0 = *(_BYTE *)tbuff;
	tbuff = (char *)tbuff + 1;
	result = 1;
	if ( v0 != 1 )
		result = 0;
	return result;
}

//----- (00426B7F) --------------------------------------------------------
void __fastcall LoadPlayer(int player_num)
{
	memcpy(&plr[player_num], tbuff, 0x54B0u);
	tbuff = (char *)tbuff + 21680;
}

//----- (00426BA9) --------------------------------------------------------
void __fastcall LoadMonster(int monster_num)
{
	int v1; // edi

	v1 = monster_num;
	memcpy(&monster[monster_num], tbuff, 0xD8u);
	tbuff = (char *)tbuff + 216;
	SyncMonsterAnim(v1);
}

//----- (00426BDE) --------------------------------------------------------
void __fastcall LoadMissile(int missile_num)
{
	memcpy(&missile[missile_num], tbuff, 0xB0u);
	tbuff = (char *)tbuff + 176;
}

//----- (00426C08) --------------------------------------------------------
void __fastcall LoadObject(int object_num)
{
	memcpy(&object[object_num], tbuff, 0x78u);
	tbuff = (char *)tbuff + 120;
}

//----- (00426C2A) --------------------------------------------------------
void __fastcall LoadItem(int item_num)
{
	int v1; // edi

	v1 = item_num;
	memcpy(&items[item_num], tbuff, 0x170u);
	tbuff = (char *)tbuff + 368;
	items_get_drop_cel(v1);
}

//----- (00426C5F) --------------------------------------------------------
void __fastcall LoadPremium(int griswold_premium_item_num)
{
	memcpy(&premiumitem[griswold_premium_item_num], tbuff, 0x170u);
	tbuff = (char *)tbuff + 368;
}

//----- (00426C89) --------------------------------------------------------
void __fastcall LoadQuest(int i)
{
	memcpy(&quests[i], tbuff, 0x18u);
	tbuff = (char *)tbuff + 24;
	ReturnLvlX = ILoad();
	ReturnLvlY = ILoad();
	ReturnLvl = ILoad();
	ReturnLvlT = ILoad();
	dword_525760 = ILoad();
}

//----- (00426CDE) --------------------------------------------------------
void __fastcall LoadLighting(int light_num)
{
	memcpy(&LightList[light_num], tbuff, 0x34u);
	tbuff = (char *)tbuff + 52;
}

//----- (00426D00) --------------------------------------------------------
void __fastcall LoadVision(int vision_num)
{
	memcpy(&VisionList[vision_num], tbuff, 0x34u);
	tbuff = (char *)tbuff + 52;
}

//----- (00426D22) --------------------------------------------------------
void __fastcall LoadPortal(int portal_num)
{
	memcpy(&portal[portal_num], tbuff, 0x18u);
	tbuff = (char *)tbuff + 24;
}

//----- (00426D45) --------------------------------------------------------
void __cdecl SaveGame()
{
	int v0; // eax
	signed int v1; // ebx
	signed int v2; // esi
	int v3; // esi
	int v4; // esi
	int *v5; // esi
	int *v6; // esi
	int i; // esi
	int *v8; // esi
	int *v9; // esi
	int j; // esi
	int *v11; // esi
	int *v12; // esi
	int k; // esi
	signed int v14; // esi
	int l; // esi
	int m; // esi
	int *v17; // esi
	int *v18; // esi
	int n; // esi
	int *v20; // esi
	char *v21; // edi
	signed int v22; // ebx
	_BYTE *v23; // edi
	signed int v24; // ebx
	char *v25; // edi
	signed int v26; // ebx
	char *v27; // edi
	int (*v28)[112]; // ebx
	int *v29; // edi
	signed int v30; // ebx
	char *v31; // edi
	signed int v32; // ebx
	char *v33; // edi
	signed int v34; // ebx
	char *v35; // edi
	signed int v36; // ebx
	char *v37; // edi
	signed int v38; // ebx
	unsigned char *v39; // edi
	signed int v40; // ebx
	char *v41; // edi
	int v42; // esi
	void *v43; // esi
	int v44; // eax
	char v45[260]; // [esp+Ch] [ebp-10Ch]
	void *ptr; // [esp+110h] [ebp-8h]
	int v47; // [esp+114h] [ebp-4h]

	v0 = codec_get_encoded_len(262147);
	ptr = DiabloAllocPtr(v0);
	tbuff = ptr;
	ISave_2('RETL');
	OSave(setlevel);
	ISave((unsigned char)setlvlnum);
	ISave(currlevel);
	ISave((unsigned char)leveltype);
	ISave(ViewX);
	ISave(ViewY);
	OSave(invflag);
	OSave(chrflag);
	ISave(nummonsters);
	ISave(numitems);
	ISave(nummissiles);
	ISave(nobjects);
	v1 = 0;
	v2 = 0;
	do
	{
		ISave_2(glSeedTbl[v2]);
		ISave(gnLevelTypeTbl[v2]);
		++v2;
	}
	while ( v2 < 17 );
	SavePlayer(myplr);
	v3 = 0;
	do
		SaveQuest(v3++);
	while ( v3 < 16 );
	v4 = 0;
	do
		SavePortal(v4++);
	while ( v4 < 4 );
	v5 = monstkills;
	do
	{
		ISave_2(*v5);
		++v5;
	}
	while ( (signed int)v5 < (signed int)monstactive );
	if ( leveltype )
	{
		v6 = monstactive;
		do
		{
			ISave(*v6);
			++v6;
		}
		while ( (signed int)v6 < (signed int)&nummonsters );
		for ( i = 0; i < nummonsters; ++i )
			SaveMonster(monstactive[i]);
		v8 = missileactive;
		do
		{
			BSave(*(_BYTE *)v8);
			++v8;
		}
		while ( (signed int)v8 < (signed int)missileavail );
		v9 = missileavail;
		do
		{
			BSave(*(_BYTE *)v9);
			++v9;
		}
		while ( (signed int)v9 < (signed int)missile );
		for ( j = 0; j < nummissiles; ++j )
			SaveMissile(missileactive[j]);
		v11 = objectactive;
		do
		{
			BSave(*(_BYTE *)v11);
			++v11;
		}
		while ( (signed int)v11 < (signed int)&nobjects );
		v12 = objectavail;
		do
		{
			BSave(*(_BYTE *)v12);
			++v12;
		}
		while ( (signed int)v12 < (signed int)object );
		for ( k = 0; k < nobjects; ++k )
			SaveObject(objectactive[k]);
		ISave(numlights);
		v14 = 0;
		do
			BSave(lightactive[v14++]);
		while ( v14 < 32 );
		for ( l = 0; l < numlights; ++l )
			SaveLighting((unsigned char)lightactive[l]);
		ISave(visionid);
		ISave(numvision);
		for ( m = 0; m < numvision; ++m )
			SaveVision(m);
	}
	v17 = itemactive;
	do
	{
		BSave(*(_BYTE *)v17);
		++v17;
	}
	while ( (signed int)v17 < (signed int)&uitemflag );
	v18 = itemavail;
	do
	{
		BSave(*(_BYTE *)v18);
		++v18;
	}
	while ( (signed int)v18 < (signed int)&itemavail[127] );
	for ( n = 0; n < numitems; ++n )
		SaveItem(itemactive[n]);
	v20 = UniqueItemFlag;
	do
	{
		OSave(*v20);
		++v20;
	}
	while ( (signed int)v20 < (signed int)&numitems );
	do
	{
		v21 = (char *)dTransVal + v1;
		v47 = 112;
		do
		{
			BSave(*v21);
			v21 += 112;
			--v47;
		}
		while ( v47 );
		++v1;
	}
	while ( v1 < 112 );
	v22 = 0;
	do
	{
		v23 = (unsigned char *)dFlags + v22;
		v47 = 112;
		do
		{
			BSave(*v23 & 0xF8);
			v23 += 112;
			--v47;
		}
		while ( v47 );
		++v22;
	}
	while ( v22 < 112 );
	v24 = 0;
	do
	{
		v25 = (char *)dPlayer + v24;
		v47 = 112;
		do
		{
			BSave(*v25);
			v25 += 112;
			--v47;
		}
		while ( v47 );
		++v24;
	}
	while ( v24 < 112 );
	v26 = 0;
	do
	{
		v27 = (char *)dItem + v26;
		v47 = 112;
		do
		{
			BSave(*v27);
			v27 += 112;
			--v47;
		}
		while ( v47 );
		++v26;
	}
	while ( v26 < 112 );
	if ( leveltype )
	{
		v28 = dMonster;
		do
		{
			v29 = (int *)v28;
			v47 = 112;
			do
			{
				ISave(*v29);
				v29 += 112;
				--v47;
			}
			while ( v47 );
			v28 = (int (*)[112])((char *)v28 + 4);
		}
		while ( (signed int)v28 < (signed int)dMonster[1] );
		v30 = 0;
		do
		{
			v31 = (char *)dDead + v30;
			v47 = 112;
			do
			{
				BSave(*v31);
				v31 += 112;
				--v47;
			}
			while ( v47 );
			++v30;
		}
		while ( v30 < 112 );
		v32 = 0;
		do
		{
			v33 = (char *)dObject + v32;
			v47 = 112;
			do
			{
				BSave(*v33);
				v33 += 112;
				--v47;
			}
			while ( v47 );
			++v32;
		}
		while ( v32 < 112 );
		v34 = 0;
		do
		{
			v35 = (char *)dTransVal + v34;
			v47 = 112;
			do
			{
				BSave(*v35);
				v35 += 112;
				--v47;
			}
			while ( v47 );
			++v34;
		}
		while ( v34 < 112 );
		v36 = 0;
		do
		{
			v37 = (char *)dTransVal2 + v36;
			v47 = 112;
			do
			{
				BSave(*v37);
				v37 += 112;
				--v47;
			}
			while ( v47 );
			++v36;
		}
		while ( v36 < 112 );
		v38 = 0;
		do
		{
			v39 = (unsigned char *)automapview + v38;
			v47 = 40;
			do
			{
				OSave(*v39);
				v39 += 40;
				--v47;
			}
			while ( v47 );
			++v38;
		}
		while ( v38 < 40 );
		v40 = 0;
		do
		{
			v41 = (char *)dMissile + v40;
			v47 = 112;
			do
			{
				BSave(*v41);
				v41 += 112;
				--v47;
			}
			while ( v47 );
			++v40;
		}
		while ( v40 < 112 );
	}
	ISave(numpremium);
	ISave(premiumlevel);
	v42 = 0;
	do
		SavePremium(v42++);
	while ( v42 < 6 );
	OSave(automapflag);
	ISave(AutoMapScale);
	pfile_get_game_name(v45);
	v43 = ptr;
	v44 = codec_get_encoded_len((_BYTE *)tbuff - (_BYTE *)ptr);
	pfile_write_save_file(v45, v43, (_BYTE *)tbuff - (_BYTE *)v43, v44);
	mem_free_dbg(v43);
	*(_DWORD *)&gbValidSaveFile = 1;
	pfile_rename_temp_to_perm();
	pfile_write_hero();
}
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (00427203) --------------------------------------------------------
void __fastcall BSave(char v)
{
	*(_BYTE *)tbuff = v;
	tbuff = (char *)tbuff + 1;
}

//----- (00427211) --------------------------------------------------------
void __fastcall ISave(int v)
{
	*(_BYTE *)tbuff = _HIBYTE(v);
	tbuff = (char *)tbuff + 1;
	*(_BYTE *)tbuff = BYTE2(v);
	tbuff = (char *)tbuff + 1;
	*(_BYTE *)tbuff = BYTE1(v);
	tbuff = (char *)tbuff + 1;
	*(_BYTE *)tbuff = v;
	tbuff = (char *)tbuff + 1;
}

//----- (00427258) --------------------------------------------------------
void __fastcall ISave_2(int v)
{
	*(_BYTE *)tbuff = _HIBYTE(v);
	tbuff = (char *)tbuff + 1;
	*(_BYTE *)tbuff = BYTE2(v);
	tbuff = (char *)tbuff + 1;
	*(_BYTE *)tbuff = BYTE1(v);
	tbuff = (char *)tbuff + 1;
	*(_BYTE *)tbuff = v;
	tbuff = (char *)tbuff + 1;
}

//----- (0042729F) --------------------------------------------------------
void __fastcall OSave(unsigned char v)
{
	if ( v )
		*(_BYTE *)tbuff = 1;
	else
		*(_BYTE *)tbuff = 0;
	tbuff = (char *)tbuff + 1;
}

//----- (004272B7) --------------------------------------------------------
void __fastcall SavePlayer(int i)
{
	memcpy(tbuff, &plr[i], 0x54B0u);
	tbuff = (char *)tbuff + 21680;
}

//----- (004272E1) --------------------------------------------------------
void __fastcall SaveMonster(int i)
{
	memcpy(tbuff, &monster[i], 0xD8u);
	tbuff = (char *)tbuff + 216;
}

//----- (0042730B) --------------------------------------------------------
void __fastcall SaveMissile(int i)
{
	memcpy(tbuff, &missile[i], 0xB0u);
	tbuff = (char *)tbuff + 176;
}

//----- (00427335) --------------------------------------------------------
void __fastcall SaveObject(int i)
{
	memcpy(tbuff, &object[i], 0x78u);
	tbuff = (char *)tbuff + 120;
}

//----- (00427357) --------------------------------------------------------
void __fastcall SaveItem(int i)
{
	memcpy(tbuff, &items[i], 0x170u);
	tbuff = (char *)tbuff + 368;
}

//----- (00427381) --------------------------------------------------------
void __fastcall SavePremium(int i)
{
	memcpy(tbuff, &premiumitem[i], 0x170u);
	tbuff = (char *)tbuff + 368;
}

//----- (004273AB) --------------------------------------------------------
void __fastcall SaveQuest(int i)
{
	memcpy(tbuff, &quests[i], 0x18u);
	tbuff = (char *)tbuff + 24;
	ISave(ReturnLvlX);
	ISave(ReturnLvlY);
	ISave(ReturnLvl);
	ISave(ReturnLvlT);
	ISave(dword_525760);
}

//----- (00427404) --------------------------------------------------------
void __fastcall SaveLighting(int i)
{
	memcpy(tbuff, &LightList[i], 0x34u);
	tbuff = (char *)tbuff + 52;
}

//----- (00427426) --------------------------------------------------------
void __fastcall SaveVision(int i)
{
	memcpy(tbuff, &VisionList[i], 0x34u);
	tbuff = (char *)tbuff + 52;
}

//----- (00427448) --------------------------------------------------------
void __fastcall SavePortal(int i)
{
	memcpy(tbuff, &portal[i], 0x18u);
	tbuff = (char *)tbuff + 24;
}

//----- (0042746B) --------------------------------------------------------
void __cdecl SaveLevel()
{
	int v0; // eax
	signed int v1; // esi
	char *v2; // edx
	signed int v3; // ebx
	int v4; // edx
	int *v5; // esi
	int i; // esi
	int *v7; // edx
	int v8; // edx
	int *v9; // edx
	int v10; // edx
	int j; // esi
	int *v12; // edx
	int v13; // edx
	int *v14; // edx
	int v15; // edx
	int k; // esi
	signed int v17; // esi
	_BYTE *v18; // edx
	signed int v19; // ebx
	int v20; // edx
	signed int v21; // esi
	char *v22; // edx
	signed int v23; // ebx
	int v24; // edx
	int (*v25)[112]; // ebx
	int *v26; // esi
	signed int v27; // esi
	char *v28; // edx
	signed int v29; // ebx
	int v30; // edx
	signed int v31; // esi
	char *v32; // edx
	signed int v33; // ebx
	int v34; // edx
	signed int v35; // esi
	char *v36; // edx
	signed int v37; // ebx
	int v38; // edx
	signed int v39; // esi
	unsigned char *v40; // edx
	signed int v41; // ebx
	int v42; // edx
	signed int v43; // esi
	char *v44; // edx
	signed int v45; // ebx
	int v46; // edx
	void *v47; // esi
	int v48; // eax
	int v49; // eax
	char v50[260]; // [esp+0h] [ebp-10Ch]
	void *ptr; // [esp+104h] [ebp-8h]
	int v52; // [esp+108h] [ebp-4h]

	if ( !currlevel )
		glSeedTbl[0] = GetRndSeed();
	v0 = codec_get_encoded_len(262147);
	ptr = DiabloAllocPtr(v0);
	tbuff = ptr;
	if ( leveltype )
	{
		v1 = 0;
		do
		{
			v2 = (char *)dDead + v1;
			v3 = 112;
			do
			{
				BSave(*v2);
				v2 = (char *)(v4 + 112);
				--v3;
			}
			while ( v3 );
			++v1;
		}
		while ( v1 < 112 );
	}
	ISave(nummonsters);
	ISave(numitems);
	ISave(nobjects);
	if ( leveltype )
	{
		v5 = monstactive;
		do
		{
			ISave(*v5);
			++v5;
		}
		while ( (signed int)v5 < (signed int)&nummonsters );
		for ( i = 0; i < nummonsters; ++i )
			SaveMonster(monstactive[i]);
		v7 = objectactive;
		do
		{
			BSave(*(_BYTE *)v7);
			v7 = (int *)(v8 + 4);
		}
		while ( (signed int)v7 < (signed int)&nobjects );
		v9 = objectavail;
		do
		{
			BSave(*(_BYTE *)v9);
			v9 = (int *)(v10 + 4);
		}
		while ( (signed int)v9 < (signed int)object );
		for ( j = 0; j < nobjects; ++j )
			SaveObject(objectactive[j]);
	}
	v12 = itemactive;
	do
	{
		BSave(*(_BYTE *)v12);
		v12 = (int *)(v13 + 4);
	}
	while ( (signed int)v12 < (signed int)&uitemflag );
	v14 = itemavail;
	do
	{
		BSave(*(_BYTE *)v14);
		v14 = (int *)(v15 + 4);
	}
	while ( (signed int)v14 < (signed int)&itemavail[127] );
	for ( k = 0; k < numitems; ++k )
		SaveItem(itemactive[k]);
	v17 = 0;
	do
	{
		v18 = (unsigned char *)dFlags + v17;
		v19 = 112;
		do
		{
			BSave(*v18 & 0xF8);
			v18 = (_BYTE *)(v20 + 112);
			--v19;
		}
		while ( v19 );
		++v17;
	}
	while ( v17 < 112 );
	v21 = 0;
	do
	{
		v22 = (char *)dItem + v21;
		v23 = 112;
		do
		{
			BSave(*v22);
			v22 = (char *)(v24 + 112);
			--v23;
		}
		while ( v23 );
		++v21;
	}
	while ( v21 < 112 );
	if ( leveltype )
	{
		v25 = dMonster;
		do
		{
			v26 = (int *)v25;
			v52 = 112;
			do
			{
				ISave(*v26);
				v26 += 112;
				--v52;
			}
			while ( v52 );
			v25 = (int (*)[112])((char *)v25 + 4);
		}
		while ( (signed int)v25 < (signed int)dMonster[1] );
		v27 = 0;
		do
		{
			v28 = (char *)dObject + v27;
			v29 = 112;
			do
			{
				BSave(*v28);
				v28 = (char *)(v30 + 112);
				--v29;
			}
			while ( v29 );
			++v27;
		}
		while ( v27 < 112 );
		v31 = 0;
		do
		{
			v32 = (char *)dTransVal + v31;
			v33 = 112;
			do
			{
				BSave(*v32);
				v32 = (char *)(v34 + 112);
				--v33;
			}
			while ( v33 );
			++v31;
		}
		while ( v31 < 112 );
		v35 = 0;
		do
		{
			v36 = (char *)dTransVal2 + v35;
			v37 = 112;
			do
			{
				BSave(*v36);
				v36 = (char *)(v38 + 112);
				--v37;
			}
			while ( v37 );
			++v35;
		}
		while ( v35 < 112 );
		v39 = 0;
		do
		{
			v40 = (unsigned char *)automapview + v39;
			v41 = 40;
			do
			{
				OSave(*v40);
				v40 = (unsigned char *)(v42 + 40);
				--v41;
			}
			while ( v41 );
			++v39;
		}
		while ( v39 < 40 );
		v43 = 0;
		do
		{
			v44 = (char *)dMissile + v43;
			v45 = 112;
			do
			{
				BSave(*v44);
				v44 = (char *)(v46 + 112);
				--v45;
			}
			while ( v45 );
			++v43;
		}
		while ( v43 < 112 );
	}
	pfile_get_temp_level_name(v50);
	v47 = ptr;
	v48 = codec_get_encoded_len((_BYTE *)tbuff - (_BYTE *)ptr);
	pfile_write_save_file(v50, v47, (_BYTE *)tbuff - (_BYTE *)v47, v48);
	mem_free_dbg(v47);
	v49 = myplr;
	if ( setlevel )
		plr[v49]._pSLvlVisited[(unsigned char)setlvlnum] = 1;
	else
		plr[v49]._pLvlVisited[currlevel] = 1;
}
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (0042772F) --------------------------------------------------------
void __cdecl LoadLevel()
{
	signed int v0; // esi
	char v1; // al
	int v2; // edx
	char *v3; // ecx
	int v4; // esi
	int *v5; // edi
	int v6; // edi
	char v7; // al
	_DWORD *v8; // ecx
	char v9; // al
	_DWORD *v10; // ecx
	int i; // esi
	int j; // esi
	char v13; // al
	_DWORD *v14; // ecx
	char v15; // al
	_DWORD *v16; // ecx
	int k; // esi
	signed int v18; // esi
	char v19; // al
	int v20; // edx
	char *v21; // ecx
	signed int v22; // esi
	char v23; // al
	int v24; // edx
	char *v25; // ecx
	int (*v26)[112]; // edi
	_DWORD *v27; // esi
	signed int v28; // ebx
	signed int v29; // esi
	char v30; // al
	int v31; // edx
	char *v32; // ecx
	signed int v33; // esi
	char v34; // al
	int v35; // edx
	char *v36; // ecx
	signed int v37; // esi
	char v38; // al
	int v39; // edx
	char *v40; // ecx
	signed int v41; // esi
	signed int v42; // edi
	bool v43; // al
	bool *v44; // edx
	signed int v45; // ecx
	_BYTE *v46; // eax
	signed int v47; // edx
	int *v48; // eax
	char dst[260]; // [esp+Ch] [ebp-10Ch]
	int len; // [esp+110h] [ebp-8h]
	void *ptr; // [esp+114h] [ebp-4h]

	pfile_get_perm_level_name(dst);
	ptr = pfile_read(dst, &len);
	tbuff = ptr;
	if ( leveltype )
	{
		do
		{
			v0 = 112;
			do
			{
				v1 = BLoad();
				*v3 = v1;
				--v0;
			}
			while ( v0 );
		}
		while ( v2 + 1 < 112 );
		SetDead();
	}
	v4 = ILoad();
	nummonsters = v4;
	numitems = ILoad();
	nobjects = ILoad();
	if ( leveltype )
	{
		v5 = monstactive;
		do
		{
			*v5 = ILoad();
			++v5;
		}
		while ( (signed int)v5 < (signed int)&nummonsters );
		v6 = 0;
		if ( v4 > 0 )
		{
			do
				LoadMonster(monstactive[v6++]);
			while ( v6 < nummonsters );
		}
		do
		{
			v7 = BLoad();
			*v8 = v7;
		}
		while ( (signed int)(v8 + 1) < (signed int)&nobjects );
		do
		{
			v9 = BLoad();
			*v10 = v9;
		}
		while ( (signed int)(v10 + 1) < (signed int)object );
		for ( i = 0; i < nobjects; ++i )
			LoadObject(objectactive[i]);
		for ( j = 0; j < nobjects; ++j )
			SyncObjectAnim(objectactive[j]);
	}
	do
	{
		v13 = BLoad();
		*v14 = v13;
	}
	while ( (signed int)(v14 + 1) < (signed int)&uitemflag );
	do
	{
		v15 = BLoad();
		*v16 = v15;
	}
	while ( (signed int)(v16 + 1) < (signed int)&itemavail[127] );
	for ( k = 0; k < numitems; ++k )
		LoadItem(itemactive[k]);
	do
	{
		v18 = 112;
		do
		{
			v19 = BLoad();
			*v21 = v19;
			--v18;
		}
		while ( v18 );
	}
	while ( v20 + 1 < 112 );
	do
	{
		v22 = 112;
		do
		{
			v23 = BLoad();
			*v25 = v23;
			--v22;
		}
		while ( v22 );
	}
	while ( v24 + 1 < 112 );
	if ( leveltype )
	{
		v26 = dMonster;
		do
		{
			v27 = (unsigned int *)v26;
			v28 = 112;
			do
			{
				*v27 = ILoad();
				v27 += 112;
				--v28;
			}
			while ( v28 );
			v26 = (int (*)[112])((char *)v26 + 4);
		}
		while ( (signed int)v26 < (signed int)dMonster[1] );
		do
		{
			v29 = 112;
			do
			{
				v30 = BLoad();
				*v32 = v30;
				--v29;
			}
			while ( v29 );
		}
		while ( v31 + 1 < 112 );
		do
		{
			v33 = 112;
			do
			{
				v34 = BLoad();
				*v36 = v34;
				--v33;
			}
			while ( v33 );
		}
		while ( v35 + 1 < 112 );
		do
		{
			v37 = 112;
			do
			{
				v38 = BLoad();
				*v40 = v38;
				--v37;
			}
			while ( v37 );
		}
		while ( v39 + 1 < 112 );
		v41 = 0;
		do
		{
			v42 = 40;
			do
			{
				v43 = OLoad();
				*v44 = v43;
				--v42;
			}
			while ( v42 );
			++v41;
		}
		while ( v41 < 40 );
		v45 = 0;
		do
		{
			v46 = (unsigned char *)dMissile + v45;
			v47 = 112;
			do
			{
				*v46 = 0;
				v46 += 112;
				--v47;
			}
			while ( v47 );
			++v45;
		}
		while ( v45 < 112 );
	}
	AutomapZoomReset();
	ResyncQuests();
	SyncPortals();
	v48 = &plr[0].plrlevel;
	dword_642A18 = 1;
	do
	{
		if ( *((_BYTE *)v48 - 23) && currlevel == *v48 )
			LightList[v48[26]]._lunflag = 1;
		v48 += 5430;
	}
	while ( (signed int)v48 < (signed int)&plr_msgs[0].player );
	mem_free_dbg(ptr);
}
// 5BB1ED: using guessed type char leveltype;
// 642A18: using guessed type int dword_642A18;

//----- (004279F7) --------------------------------------------------------
void __cdecl log_cpp_init_1()
{
	dword_646A30 = log_inf;
}
// 47F070: using guessed type int log_inf;
// 646A30: using guessed type int dword_646A30;

//----- (00427A02) --------------------------------------------------------
void __cdecl log_cpp_init_2()
{
	log_init_mutex();
	j_log_cleanup_mutex();
}

//----- (00427A0C) --------------------------------------------------------
void __cdecl log_init_mutex()
{
	InitializeCriticalSection(&stru_646A38);
}

//----- (00427A18) --------------------------------------------------------
void __cdecl j_log_cleanup_mutex()
{
	atexit(log_cleanup_mutex);
}

//----- (00427A24) --------------------------------------------------------
void __cdecl log_cleanup_mutex()
{
	DeleteCriticalSection(&stru_646A38);
}

//----- (00427A30) --------------------------------------------------------
void __cdecl log_flush(bool force_close)
{
	void *v1; // eax
	DWORD NumberOfBytesWritten; // [esp+8h] [ebp-4h]

	EnterCriticalSection(&stru_646A38);
	if ( nNumberOfBytesToWrite )
	{
		if ( log_file == (HANDLE)-1 )
		{
			v1 = log_create();
			log_file = v1;
			if ( v1 == (void *)-1 )
			{
				nNumberOfBytesToWrite = 0;
				return;
			}
			SetFilePointer(v1, 0, 0, 2u);
		}
		WriteFile(log_file, lpAddress, nNumberOfBytesToWrite, &NumberOfBytesWritten, 0);
		nNumberOfBytesToWrite = 0;
	}
	if ( force_close && log_file != (HANDLE)-1 )
	{
		CloseHandle(log_file);
		log_file = (HANDLE)-1;
	}
	LeaveCriticalSection(&stru_646A38);
}

//----- (00427AC2) --------------------------------------------------------
void *__cdecl log_create()
{
	char *v0; // eax
	void *v1; // ebx
	HANDLE v2; // eax
	char *v3; // edx
	char Filename[260]; // [esp+Ch] [ebp-15Ch]
	VS_FIXEDFILEINFO file_info; // [esp+110h] [ebp-58h]
	char Buffer[32]; // [esp+144h] [ebp-24h]
	DWORD pcbBuffer; // [esp+164h] [ebp-4h]

	if ( log_not_created )
	{
		if ( GetModuleFileNameA(0, Filename, 0x104u) && (v0 = strrchr(Filename, 92)) != 0 )
			v0[1] = 0;
		else
			Filename[0] = 0;
		pcbBuffer = 32;
		if ( !GetUserNameA(Buffer, &pcbBuffer) )
			Buffer[0] = 0;
		log_get_version(&file_info);
		_snprintf(
			FileName,
			0x104u,
			"%s%s%02u%02u%02u.ERR",
			Filename,
			Buffer,
			_LOWORD(file_info.dwProductVersionMS),
			file_info.dwProductVersionLS >> 16,
			_LOWORD(file_info.dwProductVersionLS));
	}
	v1 = (void *)-1;
	for ( pcbBuffer = log_not_created == 0; (signed int)pcbBuffer < 2; ++pcbBuffer )
	{
		v2 = CreateFileA(FileName, 0x40000000u, 1u, 0, 4u, 0x80u, 0);
		v1 = v2;
		if ( v2 != (HANDLE)-1 )
		{
			if ( GetFileSize(v2, 0) > 0x10000 )
				SetEndOfFile(v1);
			break;
		}
		v3 = strrchr(FileName, 92);
		if ( !v3 )
			v3 = FileName;
		strcpy(Filename, "c:\\");
		memset(&Filename[4], 0, 0x100u);
		strcat(Filename, v3);
		strcpy(FileName, Filename);
	}
	log_not_created = 0;
	return v1;
}
// 4947D4: using guessed type int log_not_created;

//----- (00427C18) --------------------------------------------------------
void __fastcall log_get_version(VS_FIXEDFILEINFO *file_info)
{
	DWORD v1; // eax
	DWORD v2; // esi
	void *v3; // ebx
	unsigned int v4; // eax
	char Filename[260]; // [esp+8h] [ebp-114h]
	DWORD dwHandle; // [esp+10Ch] [ebp-10h]
	LPVOID lpBuffer; // [esp+110h] [ebp-Ch]
	unsigned int puLen; // [esp+114h] [ebp-8h]
	void *v9; // [esp+118h] [ebp-4h]

	v9 = file_info;
	memset(file_info, 0, 0x34u);
	if ( GetModuleFileNameA(0, Filename, 0x104u) )
	{
		v1 = GetFileVersionInfoSizeA(Filename, &dwHandle);
		v2 = v1;
		if ( v1 )
		{
			v3 = VirtualAlloc(0, v1, 0x1000u, 4u);
			if ( GetFileVersionInfoA(Filename, 0, v2, v3) && VerQueryValueA(v3, "\\", &lpBuffer, &puLen) )
			{
				v4 = puLen;
				if ( puLen >= 0x34 )
					v4 = 52;
				memcpy(v9, lpBuffer, v4);
			}
			VirtualFree(v3, 0, 0x8000u);
		}
	}
}

//----- (00427CC9) --------------------------------------------------------
void log_printf(char *format, ...)
{
	size_t v1; // edi
	char *v2; // eax
	char v3[512]; // [esp+Ch] [ebp-200h]
	va_list va; // [esp+218h] [ebp+Ch]

	va_start(va, format);
	EnterCriticalSection(&stru_646A38);
	_vsnprintf(v3, 0x200u, format, va);
	v3[511] = 0;
	v1 = strlen(v3);
	if ( v1 + nNumberOfBytesToWrite > 0x1000 )
		log_flush(0);
	v2 = (char *)lpAddress;
	if ( lpAddress
	  || (v2 = (char *)VirtualAlloc((LPVOID)lpAddress, 0x1000u, 0x1000u, 4u),
		  nNumberOfBytesToWrite = 0,
		  (lpAddress = v2) != 0) )
	{
		memcpy(&v2[nNumberOfBytesToWrite], v3, v1);
		nNumberOfBytesToWrite += v1;
	}
	LeaveCriticalSection(&stru_646A38);
}

//----- (00427D75) --------------------------------------------------------
void __cdecl log_dump_computer_info()
{
	char Buffer[64]; // [esp+0h] [ebp-88h]
	VS_FIXEDFILEINFO file_info; // [esp+40h] [ebp-48h]
	struct _SYSTEMTIME SystemTime; // [esp+74h] [ebp-14h]
	DWORD pcbBuffer; // [esp+84h] [ebp-4h]

	GetLocalTime(&SystemTime);
	pcbBuffer = 64;
	if ( !GetUserNameA(Buffer, &pcbBuffer) )
		Buffer[0] = 0;
	log_get_version(&file_info);
	log_printf(
		"\r\n"
		"------------------------------------------------------\r\n"
		"PROGRAM VERSION: %d.%d.%d.%d\r\n"
		"COMPUTER NAME: %s\r\n"
		"TIME: %02u/%02u/%02u %02u:%02u:%02u\r\n"
		"INFO: %s\r\n"
		"\r\n",
		file_info.dwProductVersionMS >> 16,
		_LOWORD(file_info.dwProductVersionMS),
		file_info.dwProductVersionLS >> 16,
		_LOWORD(file_info.dwProductVersionLS),
		Buffer,
		SystemTime.wMonth,
		SystemTime.wDay,
		SystemTime.wYear % 100,
		SystemTime.wHour,
		SystemTime.wMinute,
		SystemTime.wSecond,
		log_buffer);
}

//----- (00427E13) --------------------------------------------------------
void __cdecl mainmenu_cpp_init()
{
	mainmenu_cpp_init_value = mainmenu_inf;
}
// 47F074: using guessed type int mainmenu_inf;
// 646CE0: using guessed type int mainmenu_cpp_init_value;

//----- (00427E1E) --------------------------------------------------------
void __cdecl mainmenu_refresh_music()
{
	int v0; // eax

	music_start(menu_music_track_id);
	v0 = menu_music_track_id;
	do
	{
		if ( ++v0 == 6 )
			v0 = 0;
	}
	while ( !v0 || v0 == 1 );
	menu_music_track_id = v0;
}

//----- (00427E45) --------------------------------------------------------
void __stdcall mainmenu_create_hero(char *a1, char *a2)
{
	char *v2; // [esp-14h] [ebp-14h]

	if ( UiValidPlayerName(v2) )
		pfile_create_save_file(a1, a2);
}

//----- (00427E62) --------------------------------------------------------
int __stdcall mainmenu_select_hero_dialog(int u1, int u2, int u3, int u4, int mode, char *cname, int clen, char *cdesc, int cdlen, int *multi)
{
	int v10; // eax
	int a6; // [esp+8h] [ebp-8h]
	int a5; // [esp+Ch] [ebp-4h]

	a6 = 1;
	a5 = 0;
	if ( gbMaxPlayers == 1 )
	{
		if ( !UiSelHeroSingDialog(
				  pfile_ui_set_hero_infos,
				  pfile_ui_save_create,
				  pfile_delete_save,
				  pfile_ui_set_class_stats,
				  &a5,
				  chr_name_str,
				  &gnDifficulty) )
			TermMsg("Unable to display SelHeroSing");
		if ( a5 == 2 )
		{
			dword_5256E8 = 1;
			goto LABEL_6;
		}
		dword_5256E8 = 0;
	}
	else if ( !UiSelHeroMultDialog(
				   pfile_ui_set_hero_infos,
				   pfile_ui_save_create,
				   pfile_delete_save,
				   pfile_ui_set_class_stats,
				   &a5,
				   &a6,
				   chr_name_str) )
	{
		TermMsg("Can't load multiplayer dialog");
	}
	if ( a5 == 4 )
	{
		SErrSetLastError(1223);
		return 0;
	}
LABEL_6:
	pfile_create_player_description(cdesc, cdlen);
	if ( multi )
	{
		if ( mode == 'BNET' )
			v10 = a6 || !plr[myplr].pBattleNet;
		else
			v10 = a6;
		*multi = v10;
	}
	if ( cname )
	{
		if ( clen )
			SStrCopy(cname, chr_name_str, clen);
	}
	return 1;
}
// 5256E8: using guessed type int dword_5256E8;
// 679660: using guessed type char gbMaxPlayers;

//----- (00427F76) --------------------------------------------------------
void __fastcall mainmenu_action(int option)
{
	int v1; // eax
	int a2; // [esp+0h] [ebp-4h]

	a2 = option;
	mainmenu_refresh_music();
	do
	{
		while ( 1 )
		{
			a2 = 0;
			if ( !UiMainMenuDialog("Diablo v1.09", &a2, effects_play_sound, 30) )
				TermMsg("Unable to display mainmenu");
			if ( a2 == 1 )
				break;
			switch ( a2 )
			{
				case MAINMENU_MULTIPLAYER:
					mainmenu_multi_player();
					goto LABEL_15;
				case MAINMENU_REPLAY_INTRO:
					goto LABEL_10;
				case MAINMENU_SHOW_CREDITS:
					UiCreditsDialog(16);
					break;
				case MAINMENU_EXIT_DIABLO:
					goto LABEL_16;
				case MAINMENU_ATTRACT_MODE:
LABEL_10:
					if ( window_activated )
						mainmenu_play_intro();
					break;
			}
		}
		v1 = mainmenu_single_player();
LABEL_15:
		;
	}
	while ( v1 );
LABEL_16:
	music_stop();
}
// 634980: using guessed type int window_activated;

//----- (00427FEC) --------------------------------------------------------
int __cdecl mainmenu_single_player()
{
	gbMaxPlayers = 1;
	return mainmenu_init_menu(1);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00427FFA) --------------------------------------------------------
int __fastcall mainmenu_init_menu(int a1)
{
	int v1; // esi
	int v3; // esi

	v1 = a1;
	if ( a1 == 4 )
		return 1;
	music_stop();
	v3 = diablo_init_menu(v1 != 2, v1 != 3);
	if ( v3 )
		mainmenu_refresh_music();
	return v3;
}

//----- (00428030) --------------------------------------------------------
void __cdecl mainmenu_multi_player()
{
	gbMaxPlayers = 4;
	mainmenu_init_menu(3);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0042803F) --------------------------------------------------------
void __cdecl mainmenu_play_intro()
{
	music_stop();
	play_movie("gendata\\diablo1.smk", 1);
	mainmenu_refresh_music();
}

//----- (00428056) --------------------------------------------------------
void __cdecl FreeQuestText()
{
	void *v0; // ecx
	void *v1; // ecx

	v0 = pMedTextCels;
	pMedTextCels = 0;
	mem_free_dbg(v0);
	v1 = pTextBoxCels;
	pTextBoxCels = 0;
	mem_free_dbg(v1);
}

//----- (0042807A) --------------------------------------------------------
void __cdecl InitQuestText()
{
	unsigned char *v0; // eax

	pMedTextCels = LoadFileInMem("Data\\MedTextS.CEL", 0);
	v0 = LoadFileInMem("Data\\TextBox.CEL", 0);
	qtextflag = 0;
	pTextBoxCels = v0;
}
// 646D00: using guessed type char qtextflag;

//----- (004280A4) --------------------------------------------------------
void __fastcall InitQTextMsg(int m)
{
	int v1; // ecx
	int v2; // esi
	char *v3; // eax
	int v4; // eax

	v1 = m;
	v2 = v1 * 16;
	if ( alltext[v1].scrlltxt )
	{
		v3 = alltext[v1].txtstr;
		questlog = 0;
		qtextptr = v3;
		v4 = alltext[v1].txtspd;
		qtextflag = 1;
		qtexty = 500;
		sgLastScroll = *(_DWORD *)&aUnableToDisp_0[4 * v4 + 24];
		scrolltexty = sgLastScroll;
		qtextSpd = GetTickCount();
	}
	PlaySFX(*(_sfx_id *)((char *)&alltext[0].sfxnr + v2));
}
// 646CF4: using guessed type int qtexty;
// 646CFC: using guessed type int qtextSpd;
// 646D00: using guessed type char qtextflag;
// 646D04: using guessed type int scrolltexty;
// 646D08: using guessed type int sgLastScroll;
// 69BD04: using guessed type int questlog;

//----- (00428104) --------------------------------------------------------
void __cdecl DrawQTextBack()
{
	char *v0; // edi
	signed int v1; // edx
	signed int v2; // ecx
	int v3; // edi
	signed int v4; // ecx
	_BYTE *v5; // edi
	signed int v6; // ecx

	Cel_decode(88, 487, pTextBoxCels, 1, 591);
	v0 = &gpBuffer->row[324].pixels[27];
	v1 = 148;
	do
	{
		v2 = 292;
		do
		{
			*v0 = 0;
			v0 += 2;
			--v2;
		}
		while ( v2 );
		*v0 = 0;
		v3 = (int)(v0 - 1352);
		v4 = 292;
		do
		{
			v5 = (_BYTE *)(v3 + 1);
			*v5 = 0;
			v3 = (int)(v5 + 1);
			--v4;
		}
		while ( v4 );
		v0 = (char *)(v3 - 1352);
		--v1;
	}
	while ( v1 );
	v6 = 292;
	do
	{
		*v0 = 0;
		v0 += 2;
		--v6;
	}
	while ( v6 );
	*v0 = 0;
}

//----- (00428160) --------------------------------------------------------
void __fastcall PrintQTextChr(int screen_x, int screen_y, char *cel_buf, int frame)
{
	char *v4; // ebx
	char *v5; // esi
	char *v6; // edi
	int v7; // ebx
	signed int v8; // edx
	unsigned int v9; // eax
	unsigned int v10; // ecx
	char v11; // cf
	unsigned int v12; // ecx
	char *v13; // [esp+14h] [ebp-8h]
	char *v14; // [esp+18h] [ebp-4h]

	v13 = (char *)gpBuffer + screen_y_times_768[209];
	v14 = (char *)gpBuffer + screen_y_times_768[469];
	v4 = &cel_buf[4 * frame];
	v5 = &cel_buf[*(_DWORD *)v4];
	v6 = (char *)gpBuffer + screen_y_times_768[screen_y] + screen_x;
	v7 = (int)&v5[*((_DWORD *)v4 + 1) - *(_DWORD *)v4];
	do
	{
		v8 = 22;
		do
		{
			while ( 1 )
			{
				v9 = (unsigned char)*v5++;
				if ( (v9 & 0x80u) == 0 )
					break;
				_LOBYTE(v9) = -(char)v9;
				v6 += v9;
				v8 -= v9;
				if ( !v8 )
					goto LABEL_15;
			}
			v8 -= v9;
			if ( v6 < v13 || v6 > v14 )
			{
				v5 += v9;
				v6 += v9;
			}
			else
			{
				v10 = v9 >> 1;
				if ( !(v9 & 1) || (*v6 = *v5, ++v5, ++v6, v10) )
				{
					v11 = v10 & 1;
					v12 = v9 >> 2;
					if ( !v11 || (*(_WORD *)v6 = *(_WORD *)v5, v5 += 2, v6 += 2, v12) )
					{
						qmemcpy(v6, v5, 4 * v12);
						v5 += 4 * v12;
						v6 += 4 * v12;
					}
				}
			}
		}
		while ( v8 );
LABEL_15:
		v6 -= 790;
	}
	while ( (char *)v7 != v5 );
}

//----- (00428202) --------------------------------------------------------
void __cdecl DrawQText()
{
	char *v0; // edi
	signed int v1; // edx
	int v2; // ecx
	char *i; // esi
	unsigned char v4; // al
	unsigned char v5; // al
	char v6; // dl
	char *v7; // eax
	unsigned char v8; // al
	char *v9; // esi
	unsigned char v10; // bl
	DWORD v11; // eax
	char tempstr[128]; // [esp+8h] [ebp-90h]
	char *v13; // [esp+88h] [ebp-10h]
	int v14; // [esp+8Ch] [ebp-Ch]
	int screen_y; // [esp+90h] [ebp-8h]
	int screen_x; // [esp+94h] [ebp-4h]

	DrawQTextBack();
	v0 = qtextptr;
	screen_x = 112;
	v13 = 0;
	screen_y = qtexty;
	v14 = 0;
	do
	{
		v1 = 0;
		v2 = 0;
		for ( i = v0; *i != 10; ++v2 )
		{
			if ( *i == 124 || v1 >= 543 )
				break;
			v4 = *i++;
			v5 = fontidx[v4];
			if ( v5 )
			{
				tempstr[v2] = v5;
				v1 += mfontkern[mfontframe[v5]] + 2;
			}
			else
			{
				--v2;
			}
		}
		v6 = *i;
		v7 = &tempstr[v2];
		tempstr[v2] = 0;
		if ( v6 == 124 )
		{
			*v7 = 0;
			v14 = 1;
		}
		else if ( v6 != 10 )
		{
			while ( *v7 != 32 && v2 > 0 )
			{
				*v7 = 0;
				v7 = &tempstr[--v2];
			}
		}
		v8 = tempstr[0];
		if ( tempstr[0] )
		{
			v9 = tempstr;
			do
			{
				++v0;
				v10 = mfontframe[fontidx[v8]];
				if ( *v0 == 10 )
					++v0;
				if ( v10 )
					PrintQTextChr(screen_x, screen_y, (char *)pMedTextCels, v10);
				++v9;
				screen_x += mfontkern[v10] + 2;
				v8 = *v9;
			}
			while ( *v9 );
		}
		if ( !v13 )
			v13 = v0;
		screen_y += 38;
		screen_x = 112;
		if ( screen_y > 501 )
			v14 = 1;
	}
	while ( !v14 );
	v11 = GetTickCount();
	while ( 1 )
	{
		if ( sgLastScroll <= 0 )
		{
			qtexty = qtexty + sgLastScroll - 1;
			goto LABEL_33;
		}
		if ( --scrolltexty )
		{
			--qtexty;
LABEL_33:
			if ( scrolltexty )
				goto LABEL_35;
		}
		scrolltexty = sgLastScroll;
LABEL_35:
		if ( qtexty <= 209 )
			break;
		qtextSpd += 50;
		if ( v11 - qtextSpd >= 0x7FFFFFFF )
			return;
	}
	qtexty += 38;
	qtextptr = v13;
	if ( *v13 == 124 )
		qtextflag = 0;
}
// 646CF4: using guessed type int qtexty;
// 646CFC: using guessed type int qtextSpd;
// 646D00: using guessed type char qtextflag;
// 646D04: using guessed type int scrolltexty;
// 646D08: using guessed type int sgLastScroll;
// 428202: using guessed type char tempstr[128];

//----- (004283C0) --------------------------------------------------------
void __fastcall GetDamageAmt(int i, int *mind, int *maxd)
{
	int v3; // eax
	int v4; // esi
	int v5; // eax
	int v6; // ecx
	int v7; // eax
	int *v8; // eax
	signed int v9; // ecx
	int v10; // eax
	int v11; // ecx
	int v12; // eax
	int v13; // eax
	int v14; // eax
	int v15; // ecx
	int *v16; // ecx
	int v17; // eax
	int v18; // ecx
	int v19; // eax
	int v20; // ecx
	int v21; // eax
	signed int v22; // eax
	signed int v23; // ecx
	int v24; // eax
	int v25; // ecx
	int v26; // ecx
	int v27; // eax
	signed int v28; // ecx

	v3 = myplr;
	v4 = plr[myplr]._pISplLvlAdd + plr[myplr]._pSplLvl[i];
	switch ( i )
	{
		case SPL_FIREBOLT:
			*mind = (plr[v3]._pMagic >> 3) + v4 + 1;
			v5 = (plr[myplr]._pMagic >> 3) + v4 + 10;
			goto LABEL_73;
		case SPL_HEAL:
			v6 = plr[v3]._pLevel + v4 + 1;
			*mind = v6;
			v7 = myplr;
			if ( !_LOBYTE(plr[myplr]._pClass) )
			{
				*mind = 2 * v6;
				v7 = myplr;
			}
			if ( _LOBYTE(plr[v7]._pClass) == 1 )
				*mind += *mind >> 1;
			v8 = maxd;
			v9 = 0;
			*maxd = 10;
			if ( plr[myplr]._pLevel > 0 )
			{
				do
				{
					*maxd += 4;
					++v9;
				}
				while ( v9 < plr[myplr]._pLevel );
			}
			goto LABEL_65;
		case SPL_LIGHTNING:
			v10 = 2;
			*mind = 2;
			v11 = plr[myplr]._pLevel;
			goto LABEL_43;
		case SPL_FLASH:
			v12 = plr[v3]._pLevel;
			*mind = v12;
			if ( v4 > 0 )
			{
				do
				{
					v12 += v12 >> 3;
					--v4;
				}
				while ( v4 );
				*mind = v12;
			}
			v13 = (*mind >> 1) + *mind;
			*mind = v13;
			goto LABEL_33;
		case SPL_IDENTIFY:
		case SPL_TOWN:
		case SPL_STONE:
		case SPL_INFRA:
		case SPL_RNDTELEPORT:
		case SPL_MANASHIELD:
		case SPL_DOOMSERP:
		case SPL_BLODRIT:
		case SPL_INVISIBIL:
		case SPL_BLODBOIL:
		case SPL_TELEPORT:
		case SPL_ETHEREALIZE:
		case SPL_REPAIR:
		case SPL_RECHARGE:
		case SPL_DISARM:
		case SPL_RESURRECT:
		case SPL_TELEKINESIS:
		case SPL_BONESPIRIT:
			v8 = maxd;
			goto LABEL_71;
		case SPL_FIREWALL:
			*mind = (4 * plr[v3]._pLevel + 8) >> 1;
			v5 = (4 * plr[myplr]._pLevel + 80) >> 1;
			goto LABEL_73;
		case SPL_FIREBALL:
			v14 = 2 * plr[v3]._pLevel + 4;
			*mind = v14;
			if ( v4 > 0 )
			{
				v15 = v4;
				do
				{
					v14 += v14 >> 3;
					--v15;
				}
				while ( v15 );
				*mind = v14;
			}
			v16 = maxd;
			v5 = 2 * plr[myplr]._pLevel + 40;
			*maxd = v5;
			if ( v4 <= 0 )
				return;
			do
			{
				v5 += v5 >> 3;
				--v4;
			}
			while ( v4 );
			goto LABEL_74;
		case SPL_GUARDIAN:
			v17 = (plr[v3]._pLevel >> 1) + 1;
			*mind = v17;
			if ( v4 > 0 )
			{
				v18 = v4;
				do
				{
					v17 += v17 >> 3;
					--v18;
				}
				while ( v18 );
				*mind = v17;
			}
			v16 = maxd;
			v5 = (plr[myplr]._pLevel >> 1) + 10;
			*maxd = v5;
			if ( v4 <= 0 )
				return;
			do
			{
				v5 += v5 >> 3;
				--v4;
			}
			while ( v4 );
			goto LABEL_74;
		case SPL_CHAIN:
			*mind = 4;
			v5 = 2 * plr[myplr]._pLevel + 4;
			goto LABEL_73;
		case SPL_WAVE:
			*mind = 6 * (plr[v3]._pLevel + 1);
			v13 = 3 * (plr[myplr]._pLevel + 10);
LABEL_33:
			v5 = 2 * v13;
			goto LABEL_73;
		case SPL_NOVA:
			v19 = (plr[v3]._pLevel + 5) >> 1;
			*mind = v19;
			if ( v4 > 0 )
			{
				v20 = v4;
				do
				{
					v19 += v19 >> 3;
					--v20;
				}
				while ( v20 );
				*mind = v19;
			}
			v16 = maxd;
			*mind *= 5;
			v21 = (plr[myplr]._pLevel + 30) >> 1;
			*maxd = v21;
			if ( v4 > 0 )
			{
				do
				{
					v21 += v21 >> 3;
					--v4;
				}
				while ( v4 );
				*maxd = v21;
			}
			v5 = 5 * *maxd;
			goto LABEL_74;
		case SPL_FLAME:
			*mind = 3;
			v10 = plr[myplr]._pLevel + 4;
			v11 = v10 >> 1;
LABEL_43:
			*maxd = v10 + v11;
			return;
		case SPL_GOLEM:
			*mind = 11;
			*maxd = 17;
			return;
		case SPL_APOCA:
			*mind = 0;
			v22 = 0;
			if ( plr[myplr]._pLevel > 0 )
			{
				do
				{
					++*mind;
					++v22;
				}
				while ( v22 < plr[myplr]._pLevel );
			}
			v23 = 0;
			*maxd = 0;
			if ( plr[myplr]._pLevel > 0 )
			{
				do
				{
					*maxd += 6;
					++v23;
				}
				while ( v23 < plr[myplr]._pLevel );
			}
			return;
		case SPL_ELEMENT:
			v24 = 2 * plr[v3]._pLevel + 4;
			*mind = v24;
			if ( v4 > 0 )
			{
				v25 = v4;
				do
				{
					v24 += v24 >> 3;
					--v25;
				}
				while ( v25 );
				*mind = v24;
			}
			v16 = maxd;
			v5 = 2 * plr[myplr]._pLevel + 40;
			*maxd = v5;
			if ( v4 <= 0 )
				return;
			do
			{
				v5 += v5 >> 3;
				--v4;
			}
			while ( v4 );
			goto LABEL_74;
		case SPL_CBOLT:
			*mind = 1;
			v5 = (plr[myplr]._pMagic >> 2) + 1;
			goto LABEL_73;
		case SPL_HBOLT:
			*mind = plr[v3]._pLevel + 9;
			v5 = plr[myplr]._pLevel + 18;
			goto LABEL_73;
		case SPL_HEALOTHER:
			v26 = plr[v3]._pLevel + v4 + 1;
			*mind = v26;
			v27 = myplr;
			if ( !_LOBYTE(plr[myplr]._pClass) )
			{
				*mind = 2 * v26;
				v27 = myplr;
			}
			if ( _LOBYTE(plr[v27]._pClass) == 1 )
				*mind += *mind >> 1;
			v8 = maxd;
			v28 = 0;
			*maxd = 10;
			if ( plr[myplr]._pLevel > 0 )
			{
				do
				{
					*maxd += 4;
					++v28;
				}
				while ( v28 < plr[myplr]._pLevel );
			}
LABEL_65:
			if ( v4 > 0 )
				*v8 += 6 * v4;
			if ( !_LOBYTE(plr[myplr]._pClass) )
				*v8 *= 2;
			if ( _LOBYTE(plr[myplr]._pClass) == 1 )
				*v8 += *v8 >> 1;
LABEL_71:
			*mind = -1;
			*v8 = -1;
			break;
		case SPL_FLARE:
			v5 = 3 * v4 + (plr[v3]._pMagic >> 1) - (plr[v3]._pMagic >> 3);
			*mind = v5;
LABEL_73:
			v16 = maxd;
LABEL_74:
			*v16 = v5;
			break;
		default:
			return;
	}
}

//----- (00428921) --------------------------------------------------------
int __fastcall CheckBlock(int fx, int fy, int tx, int ty)
{
	int v4; // edi
	int v5; // esi
	int v6; // ebx
	int v7; // eax

	v4 = fy;
	v5 = fx;
	v6 = 0;
	while ( v5 != tx || v4 != ty )
	{
		v7 = GetDirection(v5, v4, tx, ty);
		v5 += XDirAdd[v7];
		v4 += YDirAdd[v7];
		if ( nSolidTable[dPiece[0][v4 + 112 * v5]] )
			v6 = 1;
	}
	return v6;
}

//----- (0042897A) --------------------------------------------------------
int __fastcall FindClosest(int sx, int sy, int rad)
{
	int v3; // eax
	int v4; // eax
	int v5; // ebx
	unsigned char *v6; // esi
	int v7; // eax
	int v8; // ecx
	int v9; // edi
	int CrawlNum[19]; // [esp+0h] [ebp-58h]
	int fy; // [esp+4Ch] [ebp-Ch]
	int v13; // [esp+50h] [ebp-8h]
	int fx; // [esp+54h] [ebp-4h]

	CrawlNum[0] = 0;
	fy = sy;
	fx = sx;
	CrawlNum[1] = 3;
	CrawlNum[2] = 12;
	CrawlNum[3] = 45;
	CrawlNum[4] = 94;
	CrawlNum[5] = 159;
	CrawlNum[6] = 240;
	CrawlNum[7] = 337;
	CrawlNum[8] = 450;
	CrawlNum[9] = 579;
	CrawlNum[10] = 724;
	CrawlNum[11] = 885;
	CrawlNum[12] = 1062;
	CrawlNum[13] = 1255;
	CrawlNum[14] = 1464;
	CrawlNum[15] = 1689;
	CrawlNum[16] = 1930;
	CrawlNum[17] = 2187;
	CrawlNum[18] = 2460;
	if ( rad > 19 )
		rad = 19;
	v3 = 1;
	v13 = 1;
	if ( rad <= 1 )
		return -1;
	while ( 1 )
	{
		v4 = CrawlNum[v3];
		v5 = *(&CrawlTable.n_1 + v4);
		if ( v5 > 0 )
			break;
LABEL_13:
		v3 = v13++ + 1;
		if ( v13 >= rad )
			return -1;
	}
	v6 = &CrawlTable.delta_1[0].y + v4;
	while ( 1 )
	{
		v7 = fx + (char)*(v6 - 1);
		v8 = fy + (char)*v6;
		if ( v7 > 0 && v7 < 112 && v8 > 0 && v8 < 112 )
		{
			v9 = dMonster[0][v8 + 112 * v7];
			if ( v9 > 0 && !CheckBlock(fx, fy, v7, fy + (char)*v6) )
				return v9 - 1;
		}
		v6 += 2;
		if ( --v5 <= 0 )
			goto LABEL_13;
	}
}

//----- (00428A99) --------------------------------------------------------
int __fastcall GetSpellLevel(int id, int sn)
{
	int result; // eax

	if ( id == myplr )
		result = plr[id]._pISplLvlAdd + plr[id]._pSplLvl[sn];
	else
		result = 1;
	if ( result < 0 )
		result = 0;
	return result;
}

//----- (00428AC4) --------------------------------------------------------
int __fastcall GetDirection8(int x1, int y1, int x2, int y2)
{
	int v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // eax
	int result; // eax
	int v9; // [esp+8h] [ebp-110h]
	char Dirs[16][16]; // [esp+Ch] [ebp-10Ch]
	char lrtoul[3]; // [esp+10Ch] [ebp-Ch]
	char urtoll[3]; // [esp+10Fh] [ebp-9h]
	char lltour[3]; // [esp+112h] [ebp-6h]
	char ultolr[3]; // [esp+115h] [ebp-3h]

	v9 = y1;
	v4 = x1;
	strcpy((char *)Dirs, "c");
	*(_QWORD *)&Dirs[0][2] = 0i64;
	*(_DWORD *)&Dirs[0][10] = 0;
	*(_WORD *)&Dirs[0][14] = 0;
	*(_QWORD *)&Dirs[1][0] = 0x1010102i64;
	*(_QWORD *)&Dirs[1][8] = 0i64;
	*(_QWORD *)&Dirs[2][0] = 0x1010101010102i64;
	*(_QWORD *)&Dirs[2][8] = 0i64;
	*(_QWORD *)&Dirs[3][0] = 0x101010101010102i64;
	*(_QWORD *)&Dirs[3][8] = 1i64;
	*(_QWORD *)&Dirs[4][0] = 0x101010101010202i64;
	*(_QWORD *)&Dirs[4][8] = 0x1010101i64;
	*(_QWORD *)&Dirs[5][0] = 0x101010101010202i64;
	*(_QWORD *)&Dirs[5][8] = 0x10101010101i64;
	*(_QWORD *)&Dirs[6][0] = 0x101010101010202i64;
	*(_QWORD *)&Dirs[6][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[7][0] = 0x101010101020202i64;
	*(_QWORD *)&Dirs[7][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[8][0] = 0x101010101020202i64;
	*(_QWORD *)&Dirs[8][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[9][0] = 0x101010102020202i64;
	*(_QWORD *)&Dirs[9][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[10][0] = 0x101010102020202i64;
	*(_QWORD *)&Dirs[10][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[11][0] = 0x101010102020202i64;
	*(_QWORD *)&Dirs[11][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[12][0] = 0x101010202020202i64;
	*(_QWORD *)&Dirs[12][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[13][0] = 0x101010202020202i64;
	*(_QWORD *)&Dirs[13][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[14][0] = 0x101020202020202i64;
	*(_QWORD *)&Dirs[14][8] = 0x101010101010101i64;
	lltour[1] = 0;
	*(_QWORD *)&Dirs[15][0] = 0x101020202020202i64;
	*(_QWORD *)&Dirs[15][8] = 0x101010101010101i64;
	lrtoul[0] = 3;
	lrtoul[1] = 4;
	lrtoul[2] = 5;
	urtoll[0] = 3;
	urtoll[1] = 2;
	urtoll[2] = 1;
	ultolr[0] = 7;
	ultolr[1] = 6;
	ultolr[2] = 5;
	lltour[0] = 7;
	lltour[2] = 1;
	v5 = abs(x2 - x1);
	if ( v5 > 15 )
		v5 = 15;
	v6 = abs(y2 - v9);
	if ( v6 > 15 )
		v6 = 15;
	v7 = (unsigned char)Dirs[v6][v5];
	if ( v4 <= x2 )
	{
		if ( v9 <= y2 )
			result = (unsigned char)lltour[v7];
		else
			result = (unsigned char)ultolr[v7];
	}
	else if ( v9 <= y2 )
	{
		result = (unsigned char)urtoll[v7];
	}
	else
	{
		result = (unsigned char)lrtoul[v7];
	}
	return result;
}

//----- (004290EE) --------------------------------------------------------
int __fastcall GetDirection16(int x1, int y1, int x2, int y2)
{
	int v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // eax
	int result; // eax
	int v9; // [esp+8h] [ebp-124h]
	char Dirs[16][16]; // [esp+Ch] [ebp-120h]
	char lrtoul[8]; // [esp+10Ch] [ebp-20h]
	char urtoll[8]; // [esp+114h] [ebp-18h]
	char lltour[8]; // [esp+11Ch] [ebp-10h]
	char ultolr[8]; // [esp+124h] [ebp-8h]

	v9 = y1;
	v4 = x1;
	strcpy((char *)Dirs, "c");
	*(_QWORD *)&Dirs[0][2] = 0i64;
	*(_DWORD *)&Dirs[0][10] = 0;
	*(_WORD *)&Dirs[0][14] = 0;
	*(_QWORD *)&Dirs[1][0] = 0x1010204i64;
	*(_QWORD *)&Dirs[1][8] = 0i64;
	*(_QWORD *)&Dirs[2][0] = 0x101010101020304i64;
	*(_QWORD *)&Dirs[2][8] = 0i64;
	*(_QWORD *)&Dirs[3][0] = 0x101010202030304i64;
	*(_QWORD *)&Dirs[3][8] = 0x1010101i64;
	*(_QWORD *)&Dirs[4][0] = 0x101010202030404i64;
	*(_QWORD *)&Dirs[4][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[5][0] = 0x102020203030404i64;
	*(_QWORD *)&Dirs[5][8] = 0x101010101010101i64;
	*(_QWORD *)&Dirs[6][0] = 0x202020203030404i64;
	*(_QWORD *)&Dirs[6][8] = 0x101010101010102i64;
	*(_QWORD *)&Dirs[7][0] = 0x202030303030404i64;
	*(_QWORD *)&Dirs[7][8] = 0x101010101010202i64;
	*(_QWORD *)&Dirs[8][0] = 0x202030303040404i64;
	*(_QWORD *)&Dirs[8][8] = 0x101010101020202i64;
	*(_QWORD *)&Dirs[9][0] = 0x203030303040404i64;
	*(_QWORD *)&Dirs[9][8] = 0x101010102020202i64;
	*(_QWORD *)&Dirs[10][0] = 0x303030303040404i64;
	*(_QWORD *)&Dirs[10][8] = 0x101020202020202i64;
	*(_QWORD *)&Dirs[11][0] = 0x303030303040404i64;
	*(_QWORD *)&Dirs[11][8] = 0x102020202020203i64;
	*(_QWORD *)&Dirs[12][0] = 0x303030304040404i64;
	*(_QWORD *)&Dirs[12][8] = 0x202020202020303i64;
	*(_QWORD *)&Dirs[13][0] = 0x303030304040404i64;
	*(_QWORD *)&Dirs[13][8] = 0x202020202020303i64;
	*(_QWORD *)&Dirs[14][0] = 0x303030304040404i64;
	*(_QWORD *)&Dirs[14][8] = 0x202020202030303i64;
	lrtoul[2] = 0;
	*(_QWORD *)&Dirs[15][0] = 0x303030304040404i64;
	*(_QWORD *)&Dirs[15][8] = 0x202020203030303i64;
	urtoll[0] = 6;
	urtoll[1] = 7;
	urtoll[2] = 8;
	urtoll[3] = 9;
	urtoll[4] = 10;
	ultolr[0] = 6;
	ultolr[1] = 5;
	ultolr[2] = 4;
	ultolr[3] = 3;
	ultolr[4] = 2;
	lltour[0] = 14;
	lltour[1] = 13;
	lltour[2] = 12;
	lltour[3] = 11;
	lltour[4] = 10;
	lrtoul[0] = 14;
	lrtoul[1] = 15;
	lrtoul[3] = 1;
	lrtoul[4] = 2;
	v5 = abs(x2 - x1);
	if ( v5 > 15 )
		v5 = 15;
	v6 = abs(y2 - v9);
	if ( v6 > 15 )
		v6 = 15;
	v7 = (unsigned char)Dirs[v6][v5];
	if ( v4 <= x2 )
	{
		if ( v9 <= y2 )
			result = (unsigned char)lrtoul[v7];
		else
			result = (unsigned char)lltour[v7];
	}
	else if ( v9 <= y2 )
	{
		result = (unsigned char)ultolr[v7];
	}
	else
	{
		result = (unsigned char)urtoll[v7];
	}
	return result;
}

//----- (0042977E) --------------------------------------------------------
void __fastcall DeleteMissile(int mi, int i)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // eax
	bool v6; // zf
	bool v7; // sf

	v2 = mi;
	v3 = i;
	if ( missile[mi]._mitype == MIS_MANASHIELD )
	{
		v4 = missile[mi]._misource;
		if ( v4 == myplr )
			NetSendCmd(1u, CMD_REMSHIELD);
		plr[v4].pManaShield = 0;
	}
	v5 = nummissiles - 1;
	v6 = nummissiles == 1;
	v7 = nummissiles - 1 < 0;
	*(&missile[0]._mitype - nummissiles) = v2;
	nummissiles = v5;
	if ( !v7 && !v6 && v3 != v5 )
		missileactive[v3] = missileactive[v5];
}

//----- (004297EE) --------------------------------------------------------
void __fastcall GetMissileVel(int i, int sx, int sy, int dx, int dy, int v)
{
	int v6; // eax
	double v7; // ST18_8
	double v8; // ST10_8
	int v9; // esi
	double v10; // st7

	if ( dx != sx || dy != sy )
	{
		v7 = (double)((dx + sy - sx - dy) << 21);
		v8 = (double)((dy + dx - sx - sy) << 21);
		v9 = i;
		v10 = 1.0 / sqrt(v8 * v8 + v7 * v7);
		missile[v9]._mixvel = (signed __int64)((double)(v << 16) * v7 * v10);
		missile[v9]._miyvel = (signed __int64)((double)(v << 15) * v8 * v10);
	}
	else
	{
		v6 = i;
		missile[v6]._mixvel = 0;
		missile[v6]._miyvel = 0;
	}
}

//----- (004298AD) --------------------------------------------------------
void __fastcall PutMissile(int i)
{
	int v1; // eax
	int v2; // edx
	int v3; // esi
	int v4; // edx
	_BYTE *v5; // edx

	v1 = i;
	v2 = missile[i]._mix;
	v3 = missile[i]._miy;
	if ( v2 <= 0 || v3 <= 0 || v2 >= 112 || v3 >= 112 )
		missile[v1]._miDelFlag = 1;
	if ( !missile[v1]._miDelFlag )
	{
		v4 = v3 + 112 * v2;
		dFlags[0][v4] |= 1u;
		v5 = (unsigned char *)dMissile + v4;
		if ( *v5 )
			*v5 = -1;
		else
			*v5 = i + 1;
		if ( missile[v1]._miPreFlag )
			MissilePreFlag = 1;
	}
}
// 64CCD4: using guessed type int MissilePreFlag;

//----- (00429918) --------------------------------------------------------
void __fastcall GetMissilePos(int i)
{
	int v1; // ecx
	int v2; // eax
	int v3; // esi
	int v4; // edi
	int v5; // edx
	int v6; // edi
	int v7; // esi
	int v8; // edi
	int v9; // edx
	int v10; // esi
	int v11; // edx
	int v12; // [esp+Ch] [ebp-8h]

	v1 = i;
	v2 = SHIWORD(missile[v1]._mityoff);
	v3 = SHIWORD(missile[v1]._mitxoff);
	v4 = 2 * v2 + v3;
	v5 = 2 * v2 - v3;
	if ( v4 >= 0 )
	{
		v7 = v4 >> 3;
		v8 = v4 >> 6;
	}
	else
	{
		v6 = -v4;
		v7 = -(v6 >> 3);
		v8 = -(v6 >> 6);
	}
	v12 = v7;
	if ( v5 >= 0 )
	{
		v10 = v5 >> 3;
		v11 = v5 >> 6;
	}
	else
	{
		v9 = -v5;
		v10 = -(v9 >> 3);
		v11 = -(v9 >> 6);
	}
	missile[v1]._mix = v8 + missile[v1]._misx;
	missile[v1]._miy = v11 + missile[v1]._misy;
	missile[v1]._mixoff = SHIWORD(missile[v1]._mitxoff) + 32 * v11 - 32 * v8;
	missile[v1]._miyoff = v2 - 16 * v11 - 16 * v8;
	ChangeLightOff(missile[v1]._mlid, v12 - 8 * v8, v10 - 8 * v11);
}

//----- (004299EA) --------------------------------------------------------
void __fastcall MoveMissilePos(int i)
{
	int v1; // esi
	signed int v2; // ebx
	signed int v3; // edi
	signed int v4; // [esp+Ch] [ebp-4h]

	v1 = i;
	switch ( missile[i]._mimfnum )
	{
		case 0:
		case 1:
		case 7:
			v2 = 1;
			goto LABEL_3;
		case 2:
			v2 = 0;
LABEL_3:
			v3 = 1;
			break;
		case 3:
		case 4:
		case 5:
			v2 = 0;
			goto LABEL_7;
		case 6:
			v2 = 1;
LABEL_7:
			v3 = 0;
			break;
		default:
			v2 = v4;
			v3 = v4;
			break;
	}
	if ( PosOkMonst(missile[v1]._misource, v2 + missile[v1]._mix, v3 + missile[v1]._miy) )
	{
		missile[v1]._mix += v2;
		missile[v1]._miy += v3;
		missile[v1]._mixoff += 32 * v3 - 32 * v2;
		missile[v1]._miyoff -= 16 * v2 + 16 * v3;
	}
}

//----- (00429A99) --------------------------------------------------------
unsigned char __fastcall MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, int shift)
{
	int v6; // esi
	int v8; // ecx
	int v9; // eax
	int v10; // edi
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	int v14; // [esp+Ch] [ebp-10h]
	int v15; // [esp+10h] [ebp-Ch]
	signed int v16; // [esp+14h] [ebp-8h]
	signed int arglist; // [esp+18h] [ebp-4h]

	v16 = 0;
	arglist = m;
	v6 = m;
	v15 = mindam;
	if ( monster[m].mtalkmsg
	  || (signed int)(monster[v6]._mhitpoints & 0xFFFFFFC0) <= 0
	  || monster[v6].MType->mtype == MON_SNEAKD && _LOBYTE(monster[v6]._mgoal) == 2 )
	{
		return 0;
	}
	if ( monster[v6]._mmode == MM_CHARGE )
		return 0;
	v8 = _LOWORD(monster[v6].mMagicRes);
	v9 = missiledata[t].mResist;
	if ( v8 & 8 )
	{
		if ( v9 == 3 )
			return 0;
	}
	if ( v8 & 0x10 && v9 == 1 || v8 & 0x20 && v9 == 2 )
		return 0;
	if ( v8 & 1 && v9 == 3 || v8 & 2 && v9 == 1 || v8 & 4 && v9 == 2 )
		v16 = 1;
	_LOBYTE(v8) = 68;
	v14 = random(v8, 100);
	v10 = 90 - (unsigned char)monster[v6].mArmorClass - dist;
	if ( v10 < 5 )
		v10 = 5;
	if ( v10 > 95 )
		v10 = 95;
	_LOBYTE(v11) = CheckMonsterHit(arglist, (unsigned char *)&t);
	if ( v11 )
		return t;
	if ( v14 >= v10 && monster[v6]._mmode != MM_STONE )
		return 0;
	_LOBYTE(v12) = 68;
	v13 = v15 + random(v12, maxdam - v15 + 1);
	if ( !(_BYTE)shift )
		v13 <<= 6;
	if ( v16 )
		monster[v6]._mhitpoints -= v13 >> 2;
	else
		monster[v6]._mhitpoints -= v13;
	if ( (signed int)(monster[v6]._mhitpoints & 0xFFFFFFC0) > 0 )
	{
		if ( v16 )
		{
			PlayEffect(arglist, 1);
			return 1;
		}
		if ( monster[v6]._mmode != MM_STONE )
		{
			if ( arglist > 3 )
				M_StartHit(arglist, -1, v13);
			return 1;
		}
		if ( arglist > 3 )
			M_StartHit(arglist, -1, v13);
	}
	else
	{
		if ( monster[v6]._mmode != MM_STONE )
		{
			M_StartKill(arglist, -1);
			return 1;
		}
		M_StartKill(arglist, -1);
	}
	monster[v6]._mmode = MM_STONE;
	return 1;
}

//----- (00429C3B) --------------------------------------------------------
unsigned char __fastcall MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, int shift)
{
	int v7; // edi
	bool v8; // zf
	short v9; // ax
	int v10; // ecx
	int v11; // eax
	int v12; // esi
	int v13; // ebx
	char v14; // al
	int v15; // eax
	int v16; // eax
	int v17; // ecx
	int v19; // ebx
	int v20; // ebx
	int v21; // edx
	int v22; // eax
	int v23; // [esp+Ch] [ebp-18h]
	unsigned char ret[4]; // [esp+10h] [ebp-14h]
	int v25; // [esp+14h] [ebp-10h]
	int v26; // [esp+18h] [ebp-Ch]
	int pnuma; // [esp+1Ch] [ebp-8h]
	char arglist[4]; // [esp+20h] [ebp-4h]
	unsigned char dist_3; // [esp+37h] [ebp+13h]

	*(_DWORD *)arglist = m;
	v7 = m;
	v26 = 0;
	v8 = monster[m].mtalkmsg == 0;
	pnuma = pnum;
	if ( !v8
	  || (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) <= 0
	  || t == 53 && monster[v7].MType->mtype != MON_DIABLO && monster[v7].MData->mMonstClass )
	{
		return 0;
	}
	if ( monster[v7].MType->mtype == MON_SNEAKD && _LOBYTE(monster[v7]._mgoal) == 2 )
		return 0;
	if ( monster[v7]._mmode == MM_CHARGE )
		return 0;
	v9 = monster[v7].mMagicRes;
	v10 = missiledata[t].mResist;
	v23 = t;
	if ( v9 & 8 )
	{
		if ( v10 == 3 )
			return 0;
	}
	if ( v9 & 0x10 && v10 == 1 || v9 & 0x20 && v10 == 2 || (v9 & 0x80u) != 0 && v10 == 4 )
		return 0;
	if ( v9 & 1 && v10 == 3 || v9 & 2 && v10 == 1 || v9 & 4 && v10 == 2 )
		v26 = 1;
	_LOBYTE(v10) = 69;
	v11 = random(v10, 100);
	v8 = missiledata[t].mType == 0;
	v25 = v11;
	if ( v8 )
	{
		v12 = pnuma;
		v13 = plr[v12]._pDexterity
			+ plr[v12]._pIBonusToHit
			+ plr[v12]._pLevel
			- (unsigned char)monster[v7].mArmorClass
			- (dist * dist >> 1)
			+ plr[pnuma]._pIEnAc
			+ 50;
		v14 = plr[pnuma]._pClass;
		if ( v14 == 1 )
			v13 = plr[v12]._pDexterity
				+ plr[v12]._pIBonusToHit
				+ plr[v12]._pLevel
				- (unsigned char)monster[v7].mArmorClass
				- (dist * dist >> 1)
				+ plr[pnuma]._pIEnAc
				+ 70;
		if ( !v14 )
			v13 += 10;
	}
	else
	{
		v12 = pnuma;
		v15 = 2 * SLOBYTE(monster[v7].mLevel);
		v13 = plr[pnuma]._pMagic - v15 - dist + 50;
		if ( _LOBYTE(plr[pnuma]._pClass) == 2 )
			v13 = plr[v12]._pMagic - v15 - dist + 70;
	}
	if ( v13 < 5 )
		v13 = 5;
	if ( v13 > 95 )
		v13 = 95;
	if ( monster[v7]._mmode == MM_STONE )
		v25 = 0;
	_LOBYTE(v16) = CheckMonsterHit(*(int *)arglist, ret);
	if ( v16 )
		return ret[0];
	if ( v25 >= v13 )
		return 0;
	if ( t == 63 )
	{
		v19 = monster[v7]._mhitpoints / 3 >> 6;
	}
	else
	{
		_LOBYTE(v17) = 70;
		v19 = mindam + random(v17, maxdam - mindam + 1);
	}
	dist_3 = missiledata[v23].mType;
	if ( !missiledata[v23].mType )
	{
		v20 = plr[v12]._pIBonusDamMod + v19 * plr[v12]._pIBonusDam / 100 + v19;
		if ( _LOBYTE(plr[v12]._pClass) == 1 )
			v19 = plr[v12]._pDamageMod + v20;
		else
			v19 = (plr[v12]._pDamageMod >> 1) + v20;
	}
	if ( !(_BYTE)shift )
		v19 <<= 6;
	if ( v26 )
		v19 >>= 2;
	v21 = pnuma;
	if ( pnuma == myplr )
		monster[v7]._mhitpoints -= v19;
	v22 = plr[v12]._pIFlags;
	if ( v22 & 8 )
		monster[v7]._mFlags |= 8u;
	if ( (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) > 0 )
	{
		if ( v26 )
		{
			PlayEffect(*(int *)arglist, 1);
		}
		else if ( monster[v7]._mmode == MM_STONE )
		{
			if ( *(_DWORD *)arglist > 3 )
				M_StartHit(*(int *)arglist, v21, v19);
			monster[v7]._mmode = MM_STONE;
		}
		else
		{
			if ( !dist_3 && v22 & 0x800 )
			{
				M_GetKnockback(*(int *)arglist);
				v21 = pnuma;
			}
			if ( *(_DWORD *)arglist > 3 )
				M_StartHit(*(int *)arglist, v21, v19);
		}
	}
	else if ( monster[v7]._mmode == MM_STONE )
	{
		M_StartKill(*(int *)arglist, v21);
		monster[v7]._mmode = MM_STONE;
	}
	else
	{
		M_StartKill(*(int *)arglist, v21);
	}
	if ( !_LOBYTE(monster[v7]._msquelch) )
	{
		_LOBYTE(monster[v7]._msquelch) = -1;
		monster[v7]._lastx = plr[v12].WorldX;
		monster[v7]._lasty = plr[v12].WorldY;
	}
	return 1;
}

//----- (00429F4E) --------------------------------------------------------
unsigned char __fastcall PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, int shift, int earflag)
{
	int v8; // ebx
	int v9; // esi
	int v10; // edi
	int v11; // ecx
	int v12; // eax
	int v13; // edi
	int v14; // edi
	int v15; // eax
	int v16; // eax
	int v17; // ebx
	int v18; // ebx
	unsigned char v19; // al
	int v20; // eax
	int v21; // ecx
	int v22; // ecx
	int v23; // ecx
	int v24; // edi
	int v25; // ecx
	int v26; // eax
	char v27; // al
	int v28; // ecx
	int v29; // eax
	int v30; // eax
	int v32; // [esp+Ch] [ebp-14h]
	int arglist; // [esp+14h] [ebp-Ch]
	int v34; // [esp+18h] [ebp-8h]
	int v35; // [esp+1Ch] [ebp-4h]
	int dista; // [esp+28h] [ebp+8h]

	v8 = m;
	arglist = pnum;
	v9 = pnum;
	v34 = m;
	if ( (signed int)(plr[pnum]._pHitPoints & 0xFFFFFFC0) <= 0
	  || plr[v9]._pInvincible
	  || plr[v9]._pSpellFlags & 1 && !missiledata[mtype].mType )
	{
		return 0;
	}
	_LOBYTE(pnum) = 72;
	v10 = 100;
	v32 = random(pnum, 100);
	if ( !missiledata[mtype].mType )
	{
		v11 = 5;
		v12 = plr[v9]._pIAC + plr[v9]._pIBonusAC + plr[v9]._pDexterity / 5;
		if ( v8 != -1 )
		{
			v11 = 2 * dist;
			v13 = (unsigned char)monster[v8].mHit
				+ 2 * (SLOBYTE(monster[v8].mLevel) - plr[v9]._pLevel)
				+ 30
				- 2 * dist;
LABEL_8:
			v14 = v13 - v12;
			goto LABEL_14;
		}
		v15 = v12 >> 1;
LABEL_12:
		v13 = v10 - v15;
		v12 = 2 * dist;
		goto LABEL_8;
	}
	if ( v8 != -1 )
	{
		v10 = 2 * SLOBYTE(monster[v8].mLevel) + 40;
		v15 = 2 * plr[v9]._pLevel;
		goto LABEL_12;
	}
	v14 = 40;
LABEL_14:
	if ( v14 < 10 )
		v14 = 10;
	if ( currlevel == 14 )
	{
		if ( v14 >= 20 )
			goto LABEL_25;
		v14 = 20;
	}
	if ( currlevel == 15 )
	{
		if ( v14 >= 25 )
			goto LABEL_25;
		v14 = 25;
	}
	if ( currlevel == 16 && v14 < 30 )
		v14 = 30;
LABEL_25:
	v16 = plr[v9]._pmode;
	if ( v16 && v16 != 4 || !plr[v9]._pBlockFlag )
	{
		v35 = 100;
	}
	else
	{
		_LOBYTE(v11) = 73;
		v35 = random(v11, 100);
	}
	if ( (_BYTE)shift == 1 )
		v35 = 100;
	if ( mtype == 59 )
		v35 = 100;
	if ( v8 == -1 )
		v17 = plr[v9]._pBaseToBlk;
	else
		v17 = plr[v9]._pBaseToBlk + 2 * plr[v9]._pLevel - 2 * SLOBYTE(monster[v8].mLevel);
	v18 = plr[v9]._pDexterity + v17;
	if ( v18 < 0 )
		v18 = 0;
	if ( v18 > 100 )
		v18 = 100;
	v19 = missiledata[mtype].mResist;
	if ( v19 == 1 )
	{
		v20 = plr[v9]._pFireResist;
	}
	else if ( v19 == 2 )
	{
		v20 = plr[v9]._pLghtResist;
	}
	else
	{
		if ( v19 <= 2u || v19 > 4u )
		{
			dista = 0;
			goto LABEL_50;
		}
		v20 = plr[v9]._pMagResist;
	}
	dista = v20;
LABEL_50:
	if ( v32 < v14 )
	{
		if ( mtype == 63 )
		{
			v21 = plr[v9]._pHitPoints / 3;
		}
		else
		{
			_LOBYTE(v11) = 75;
			if ( (_BYTE)shift )
			{
				v23 = mind + random(v11, maxd - mind + 1);
				if ( v34 == -1 && plr[v9]._pIFlags & 0x10000000 )
					v23 >>= 1;
				v21 = plr[v9]._pIGetHit + v23;
			}
			else
			{
				v22 = (mind << 6) + random(v11, (maxd - mind + 1) << 6);
				if ( v34 == -1 && plr[v9]._pIFlags & 0x10000000 )
					v22 >>= 1;
				v21 = (plr[v9]._pIGetHit << 6) + v22;
			}
			if ( v21 < 64 )
				v21 = 64;
		}
		if ( dista <= 0 )
		{
			if ( v35 < v18 )
			{
				if ( v34 == -1 )
					v29 = plr[v9]._pdir;
				else
					v29 = GetDirection(plr[v9].WorldX, plr[v9].WorldY, monster[v34]._mx, monster[v34]._my);
				StartPlrBlock(arglist, v29);
				return 1;
			}
			v24 = arglist;
			if ( arglist == myplr )
			{
				plr[v9]._pHitPoints -= v21;
				plr[v9]._pHPBase -= v21;
			}
			v30 = plr[v9]._pMaxHP;
			if ( plr[v9]._pHitPoints > v30 )
			{
				plr[v9]._pHitPoints = v30;
				plr[v9]._pHPBase = plr[v9]._pMaxHPBase;
			}
			if ( (signed int)(plr[v9]._pHitPoints & 0xFFFFFFC0) > 0 )
			{
				StartPlrHit(arglist, v21, 0);
				return 1;
			}
			goto LABEL_70;
		}
		v24 = arglist;
		v25 = dista * v21 / -100 + v21;
		if ( arglist == myplr )
		{
			plr[v9]._pHitPoints -= v25;
			plr[v9]._pHPBase -= v25;
		}
		v26 = plr[v9]._pMaxHP;
		if ( plr[v9]._pHitPoints > v26 )
		{
			plr[v9]._pHitPoints = v26;
			plr[v9]._pHPBase = plr[v9]._pMaxHPBase;
		}
		if ( (signed int)(plr[v9]._pHitPoints & 0xFFFFFFC0) <= 0 )
		{
LABEL_70:
			SyncPlrKill(v24, earflag);
			return 1;
		}
		v27 = plr[v9]._pClass;
		if ( v27 )
		{
			if ( v27 == 1 )
			{
				v28 = PS_ROGUE69;
			}
			else
			{
				if ( v27 != 2 )
				{
LABEL_78:
					drawhpflag = 1;
					return 1;
				}
				v28 = PS_MAGE69;
			}
		}
		else
		{
			v28 = PS_WARR69;
		}
		PlaySfxLoc(v28, plr[v9].WorldX, plr[v9].WorldY);
		goto LABEL_78;
	}
	return 0;
}

//----- (0042A307) --------------------------------------------------------
unsigned char __fastcall Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, int shift)
{
	int v7; // edi
	unsigned char v8; // al
	int v9; // eax
	int v10; // esi
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	int v14; // ecx
	bool v15; // sf
	int v16; // ecx
	int v17; // ebx
	char v18; // al
	int v19; // ecx
	int v20; // eax
	int v22; // [esp+Ch] [ebp-14h]
	int v23; // [esp+10h] [ebp-10h]
	int v24; // [esp+10h] [ebp-10h]
	int arglist; // [esp+14h] [ebp-Ch]
	int v26; // [esp+18h] [ebp-8h]
	int v27; // [esp+1Ch] [ebp-4h]
	int dista; // [esp+30h] [ebp+10h]

	arglist = p;
	v7 = p;
	v26 = pnum;
	if ( plr[p]._pInvincible || mtype == 53 || plr[v7]._pSpellFlags & 1 && !missiledata[mtype].mType )
		return 0;
	v22 = mtype;
	v8 = missiledata[mtype].mResist;
	if ( v8 == 1 )
	{
		v9 = plr[v7]._pFireResist;
	}
	else if ( v8 == 2 )
	{
		v9 = plr[v7]._pLghtResist;
	}
	else
	{
		if ( v8 <= 2u || v8 > 4u )
		{
			v27 = 0;
			goto LABEL_14;
		}
		v9 = plr[v7]._pMagResist;
	}
	v27 = v9;
LABEL_14:
	_LOBYTE(pnum) = 69;
	v23 = random(pnum, 100);
	if ( missiledata[mtype].mType )
	{
		v10 = v26;
		v12 = 2 * plr[v7]._pLevel;
		v11 = plr[v26]._pMagic - v12 - dist + 50;
		if ( _LOBYTE(plr[v26]._pClass) == 2 )
			v11 = plr[v10]._pMagic - v12 - dist + 70;
	}
	else
	{
		v10 = v26;
		v12 = plr[v10]._pIBonusToHit
			+ plr[v10]._pLevel
			- (dist * dist >> 1)
			- plr[v7]._pDexterity / 5
			- plr[v7]._pIBonusAC
			- plr[v7]._pIAC;
		v11 = v12 + plr[v26]._pDexterity + 50;
		_LOBYTE(v12) = plr[v26]._pClass;
		if ( (_BYTE)v12 == 1 )
			v11 += 20;
		if ( !(_BYTE)v12 )
			v11 += 10;
	}
	if ( v11 < 5 )
		v11 = 5;
	if ( v11 > 95 )
		v11 = 95;
	if ( v23 < v11 )
	{
		v13 = plr[v7]._pmode;
		if ( v13 && v13 != 4 || !plr[v7]._pBlockFlag )
		{
			v24 = 100;
		}
		else
		{
			_LOBYTE(v12) = 73;
			v24 = random(v12, 100);
		}
		if ( (_BYTE)shift == 1 )
			v24 = 100;
		v14 = plr[v7]._pBaseToBlk + 2 * plr[v7]._pLevel - 2 * plr[v10]._pLevel;
		v15 = plr[v7]._pDexterity + v14 < 0;
		v16 = plr[v7]._pDexterity + v14;
		dista = v16;
		if ( v15 )
		{
			dista = 0;
			v16 = 0;
		}
		if ( v16 > 100 )
		{
			dista = 100;
			v16 = 100;
		}
		if ( mtype == 63 )
		{
			v17 = plr[v7]._pHitPoints / 3;
		}
		else
		{
			_LOBYTE(v16) = 70;
			v17 = mindam + random(v16, maxdam - mindam + 1);
			if ( !missiledata[v22].mType )
				v17 += plr[v10]._pIBonusDamMod + plr[v10]._pDamageMod + v17 * plr[v10]._pIBonusDam / 100;
			v16 = dista;
			if ( !(_BYTE)shift )
				v17 <<= 6;
		}
		if ( missiledata[v22].mType )
			v17 >>= 1;
		if ( v27 <= 0 )
		{
			if ( v24 >= v16 )
			{
				if ( v26 == myplr )
					NetSendCmdDamage(1u, arglist, v17);
				StartPlrHit(arglist, v17, 0);
			}
			else
			{
				v20 = GetDirection(plr[v7].WorldX, plr[v7].WorldY, plr[v10].WorldX, plr[v10].WorldY);
				StartPlrBlock(arglist, v20);
			}
			return 1;
		}
		if ( v26 == myplr )
			NetSendCmdDamage(1u, arglist, v17 - v27 * v17 / 100);
		v18 = plr[v10]._pClass;
		if ( v18 )
		{
			if ( v18 == 1 )
			{
				v19 = PS_ROGUE69;
			}
			else
			{
				if ( v18 != 2 )
					return 1;
				v19 = PS_MAGE69;
			}
		}
		else
		{
			v19 = PS_WARR69;
		}
		PlaySfxLoc(v19, plr[v10].WorldX, plr[v10].WorldY);
		return 1;
	}
	return 0;
}

//----- (0042A5DB) --------------------------------------------------------
void __fastcall CheckMissileCol(int i, int mindam, int maxdam, unsigned char shift, int mx, int my, int nodel, bool HurtPlr)
{
	int v8; // ebx
	int v9; // esi
	char v10; // dl
	int v11; // ecx
	int v12; // edi
	int v13; // eax
	int v14; // eax
	char v15; // al
	int v16; // ecx
	int v17; // edx
	int v18; // eax
	int v19; // eax
	int v20; // eax
	char v21; // al
	int v22; // eax
	int v23; // eax
	char v24; // al
	char v25; // al
	int v26; // edx
	int v27; // ecx
	int v28; // [esp-Ch] [ebp-1Ch]
	int v29; // [esp-8h] [ebp-18h]
	int mindama; // [esp+Ch] [ebp-4h]

	v8 = mindam;
	v9 = i;
	mindama = mindam;
	v10 = missile[i]._miAnimType;
	if ( v10 == 4 || (v11 = missile[v9]._misource, v11 == -1) )
	{
		v12 = 112 * mx + my;
		v22 = dMonster[0][v12];
		if ( v22 > 0 )
		{
			v29 = missile[v9]._mitype;
			v28 = missile[v9]._midist;
			_LOBYTE(v23) = v10 == 4 ? MonsterMHit(missile[v9]._misource, v22 - 1, v8, maxdam, v28, v29, shift) : MonsterTrapHit(v22 - 1, v8, maxdam, v28, v29, shift);
			if ( v23 )
			{
				if ( !(_BYTE)nodel )
					missile[v9]._mirange = 0;
				missile[v9]._miHitFlag = 1;
			}
		}
		v24 = dPlayer[0][v12];
		if ( v24 > 0 )
		{
			_LOBYTE(v18) = PlayerMHit(
							  v24 - 1,
							  -1,
							  missile[v9]._midist,
							  v8,
							  maxdam,
							  missile[v9]._mitype,
							  shift,
							  _LOBYTE(missile[v9]._miAnimType) == 4);
LABEL_35:
			if ( v18 )
			{
				if ( !(_BYTE)nodel )
					missile[v9]._mirange = 0;
				missile[v9]._miHitFlag = 1;
			}
			goto LABEL_39;
		}
	}
	else
	{
		if ( !missile[v9]._micaster )
		{
			v12 = 112 * mx + my;
			v13 = dMonster[0][v12];
			if ( v13 <= 0 )
			{
				if ( v13 >= 0 || monster[-(v13 + 1)]._mmode != MM_STONE )
				{
LABEL_13:
					v15 = dPlayer[0][v12];
					if ( v15 <= 0 )
						goto LABEL_39;
					v16 = missile[v9]._misource;
					v17 = v15 - 1;
					if ( v17 == v16 )
						goto LABEL_39;
					_LOBYTE(v18) = Plr2PlrMHit(
									  v16,
									  v17,
									  mindama,
									  maxdam,
									  missile[v9]._midist,
									  missile[v9]._mitype,
									  shift);
					goto LABEL_35;
				}
				_LOBYTE(v14) = MonsterMHit(
								  v11,
								  -1 - v13,
								  mindama,
								  maxdam,
								  missile[v9]._midist,
								  missile[v9]._mitype,
								  shift);
			}
			else
			{
				_LOBYTE(v14) = MonsterMHit(v11, v13 - 1, v8, maxdam, missile[v9]._midist, missile[v9]._mitype, shift);
			}
			if ( v14 )
			{
				if ( !(_BYTE)nodel )
					missile[v9]._mirange = 0;
				missile[v9]._miHitFlag = 1;
			}
			goto LABEL_13;
		}
		if ( monster[v11]._mFlags & 0x10 )
		{
			v19 = dMonster[0][my + 112 * mx];
			if ( v19 > 0 )
			{
				if ( monstactive[57 * v19 + 184] & 0x20 )
				{
					_LOBYTE(v20) = MonsterTrapHit(
									  v19 - 1,
									  mindama,
									  maxdam,
									  missile[v9]._midist,
									  missile[v9]._mitype,
									  shift);
					if ( v20 )
					{
						if ( !(_BYTE)nodel )
							missile[v9]._mirange = 0;
						missile[v9]._miHitFlag = 1;
					}
				}
			}
		}
		v12 = my + 112 * mx;
		v21 = dPlayer[0][v12];
		if ( v21 > 0 )
		{
			_LOBYTE(v18) = PlayerMHit(
							  v21 - 1,
							  missile[v9]._misource,
							  missile[v9]._midist,
							  mindama,
							  maxdam,
							  missile[v9]._mitype,
							  shift,
							  0);
			goto LABEL_35;
		}
	}
LABEL_39:
	v25 = dObject[0][v12];
	if ( v25 )
	{
		v26 = v25 <= 0 ? -1 - v25 : v25 - 1;
		if ( !object[v26]._oMissFlag )
		{
			if ( _LOBYTE(object[v26]._oBreak) == 1 )
				BreakObject(-1, v26);
			if ( !(_BYTE)nodel )
				missile[v9]._mirange = 0;
			missile[v9]._miHitFlag = 0;
		}
	}
	if ( nMissileTable[dPiece[0][v12]] )
	{
		if ( !(_BYTE)nodel )
			missile[v9]._mirange = 0;
		missile[v9]._miHitFlag = 0;
	}
	if ( !missile[v9]._mirange )
	{
		v27 = missiledata[missile[v9]._mitype].miSFX;
		if ( v27 != -1 )
			PlaySfxLoc(v27, missile[v9]._mix, missile[v9]._miy);
	}
}

//----- (0042A8D5) --------------------------------------------------------
void __fastcall SetMissAnim(int mi, int animtype)
{
	int v2; // ecx
	int v3; // esi
	int v4; // edi
	int v5; // eax
	int v6; // edx
	int v7; // esi
	int v8; // eax
	int v9; // eax
	int v10; // edi
	int v11; // eax

	v2 = mi;
	v3 = missile[v2]._mimfnum;
	_LOBYTE(missile[v2]._miAnimType) = animtype;
	v4 = misfiledata[animtype].mFlags;
	v5 = v3 + 236 * animtype;
	v6 = v3 + 59 * animtype;
	v7 = misfiledata[0].mAnimDelay[v5];
	v8 = misfiledata[0].mAnimLen[v5];
	missile[v2]._miAnimCnt = 0;
	missile[v2]._miAnimLen = v8;
	v9 = misfiledata[0].mAnimWidth[v6];
	missile[v2]._miAnimFlags = v4;
	v10 = misfiledata[0].mAnimCel[v6];
	missile[v2]._miAnimWidth = v9;
	v11 = misfiledata[0].mAnimWidth2[v6];
	missile[v2]._miAnimCel = v10;
	missile[v2]._miAnimDelay = v7;
	missile[v2]._miAnimWidth2 = v11;
	missile[v2]._miAnimFrame = 1;
}

//----- (0042A959) --------------------------------------------------------
void __fastcall SetMissDir(int mi, int dir)
{
	missile[mi]._mimfnum = dir;
	SetMissAnim(mi, _LOBYTE(missile[mi]._miAnimType));
}

//----- (0042A973) --------------------------------------------------------
void __fastcall LoadMissileGFX(int mi)
{
	MisFileData *v1; // esi
	unsigned char *v2; // eax
	signed int v3; // ecx
	int *v4; // edx
	int v5; // edi
	unsigned char v6; // cl
	int v7; // eax
	_DWORD *v8; // edi
	int v9; // ebx
	char arglist[256]; // [esp+8h] [ebp-100h]

	v1 = &misfiledata[(unsigned char)mi];
	if ( v1->mFlags & 4 )
	{
		sprintf(arglist, "Missiles\\%s.CL2", v1->mName);
		v2 = LoadFileInMem(arglist, 0);
		v3 = 0;
		if ( v1->mAnimFAmt )
		{
			v4 = v1->mAnimCel;
			do
			{
				v5 = (int)&v2[*(_DWORD *)&v2[4 * v3++]];
				*v4 = v5;
				++v4;
			}
			while ( v3 < v1->mAnimFAmt );
		}
	}
	else
	{
		v6 = v1->mAnimFAmt;
		if ( v6 == 1 )
		{
			sprintf(arglist, "Missiles\\%s.CL2", v1->mName);
			if ( !v1->mAnimCel[0] )
				v1->mAnimCel[0] = (int)LoadFileInMem(arglist, 0);
		}
		else
		{
			v7 = 0;
			if ( v6 )
			{
				v8 = (unsigned int *)v1->mAnimCel;
				do
				{
					v9 = v7 + 1;
					sprintf(arglist, "Missiles\\%s%i.CL2", v1->mName, v7 + 1);
					if ( !*v8 )
						*v8 = (unsigned int)LoadFileInMem(arglist, 0);
					v7 = v9;
					++v8;
				}
				while ( v9 < v1->mAnimFAmt );
			}
		}
	}
}

//----- (0042AA5C) --------------------------------------------------------
void __cdecl InitMissileGFX()
{
	char v0; // bl
	unsigned char *v1; // esi

	v0 = 0;
	if ( misfiledata[0].mAnimFAmt )
	{
		v1 = &misfiledata[0].mAnimFAmt;
		do
		{
			if ( !(v1[7] & 1) )
				LoadMissileGFX(v0);
			v1 += 236;
			++v0;
		}
		while ( *v1 );
	}
}

//----- (0042AA89) --------------------------------------------------------
void __fastcall FreeMissileGFX(int mi)
{
	int v1; // esi
	int v2; // ecx
	signed int v3; // ebx
	void **v4; // edi
	void *v5; // ecx

	v1 = mi;
	if ( misfiledata[mi].mFlags & 4 )
	{
		v2 = misfiledata[v1].mAnimCel[0];
		if ( v2 )
		{
			mem_free_dbg((void *)(v2 - 4 * misfiledata[v1].mAnimFAmt));
			misfiledata[v1].mAnimCel[0] = 0;
		}
	}
	else
	{
		v3 = 0;
		if ( misfiledata[v1].mAnimFAmt )
		{
			v4 = (void **)misfiledata[v1].mAnimCel;
			do
			{
				v5 = *v4;
				if ( *v4 )
				{
					*v4 = 0;
					mem_free_dbg(v5);
				}
				++v3;
				++v4;
			}
			while ( v3 < misfiledata[v1].mAnimFAmt );
		}
	}
}

//----- (0042AAF2) --------------------------------------------------------
void __cdecl FreeMissiles()
{
	int v0; // edi
	unsigned char *v1; // esi

	v0 = 0;
	if ( misfiledata[0].mAnimFAmt )
	{
		v1 = &misfiledata[0].mAnimFAmt;
		do
		{
			if ( !(v1[7] & 1) )
				FreeMissileGFX(v0);
			v1 += 236;
			++v0;
		}
		while ( *v1 );
	}
}

//----- (0042AB20) --------------------------------------------------------
void __cdecl FreeMissiles2()
{
	int v0; // edi
	unsigned char *v1; // esi

	v0 = 0;
	if ( misfiledata[0].mAnimFAmt )
	{
		v1 = &misfiledata[0].mAnimFAmt;
		do
		{
			if ( v1[7] & 1 )
				FreeMissileGFX(v0);
			v1 += 236;
			++v0;
		}
		while ( *v1 );
	}
}

//----- (0042AB4E) --------------------------------------------------------
void __cdecl InitMissiles()
{
	int v0; // eax
	int i; // esi
	int v2; // eax
	int v3; // eax
	int v4; // edx
	int *v5; // eax
	signed int v6; // ecx
	_BYTE *v7; // eax
	signed int v8; // edx

	v0 = myplr;
	_LOBYTE(plr[v0]._pSpellFlags) &= 0xFEu;
	if ( plr[v0]._pInfraFlag == 1 )
	{
		for ( i = 0; i < nummissiles; ++i )
		{
			v2 = missileactive[i];
			if ( missile[v2]._mitype == MIS_INFRA )
			{
				v3 = missile[v2]._misource;
				if ( v3 == myplr )
					CalcPlrItemVals(v3, 1);
			}
		}
	}
	v4 = 0;
	memset(missileactive, 0, sizeof(missileactive));
	nummissiles = 0;
	do
	{
		missileavail[v4] = v4;
		++v4;
	}
	while ( v4 < 125 );
	END_unkmis_126 = 0;
	v5 = &misflagstruct_unknown[0].field_4;
	do
	{
		*(v5 - 1) = -1;
		*v5 = 0;
		v5[1] = 0;
		v5 += 3;
	}
	while ( (signed int)v5 < (signed int)&END_unkmis_126 );
	v6 = 0;
	do
	{
		v7 = (unsigned char *)dFlags + v6;
		v8 = 112;
		do
		{
			*v7 &= 0xFEu;
			v7 += 112;
			--v8;
		}
		while ( v8 );
		++v6;
	}
	while ( v6 < 112 );
}
// 64CCD8: using guessed type int END_unkmis_126;

//----- (0042AC0C) --------------------------------------------------------
void __fastcall AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // ebx
	int v11; // edi
	int v12; // eax
	char v13; // dl
	int v14; // eax
	int v15; // esi
	int v16; // [esp-4h] [ebp-14h]
	int mia; // [esp+Ch] [ebp-4h]

	v9 = dx;
	v10 = sx;
	v11 = dy;
	mia = mi;
	if ( sx == dx && sy == dy )
	{
		v9 = XDirAdd[midir] + dx;
		v11 = YDirAdd[midir] + dy;
	}
	if ( (_BYTE)mienemy )
	{
		v16 = 32;
		goto LABEL_11;
	}
	v12 = id;
	v13 = plr[id]._pClass;
	if ( v13 == 1 )
	{
		v16 = (plr[v12]._pLevel >> 2) + 31;
LABEL_11:
		GetMissileVel(mi, v10, sy, v9, v11, v16);
		goto LABEL_12;
	}
	if ( v13 )
		GetMissileVel(mi, v10, sy, v9, v11, 32);
	else
		GetMissileVel(mi, v10, sy, v9, v11, (plr[v12]._pLevel >> 3) + 31);
LABEL_12:
	v14 = GetDirection16(v10, sy, v9, v11);
	SetMissDir(mia, v14);
	v15 = mia;
	missile[v15]._mirange = 256;
	missile[v15]._miVar1 = v10;
	missile[v15]._miVar2 = sy;
	missile[v15]._mlid = AddLight(v10, sy, 5);
}

//----- (0042ACD9) --------------------------------------------------------
void __fastcall AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ebx
	int v10; // esi
	int v11; // edi
	int v12; // eax
	char v13; // cl
	int v14; // esi
	int v15; // eax
	int x1; // [esp+8h] [ebp-8h]
	int i; // [esp+Ch] [ebp-4h]

	v9 = dy;
	v10 = dx;
	x1 = sx;
	i = mi;
	if ( sx == dx && sy == dy )
	{
		v10 = XDirAdd[midir] + dx;
		v9 = YDirAdd[midir] + dy;
		dx += XDirAdd[midir];
	}
	if ( (_BYTE)mienemy )
	{
		GetMissileVel(mi, sx, sy, v10, v9, 32);
	}
	else
	{
		v11 = id;
		v12 = 32;
		if ( plr[id]._pIFlags & 4 )
		{
			_LOBYTE(mi) = 64;
			v12 = random(mi, 32) + 16;
		}
		v13 = plr[v11]._pClass;
		if ( v13 == 1 )
			v12 += (plr[v11]._pLevel - 1) >> 2;
		if ( !v13 )
			v12 += (plr[v11]._pLevel - 1) >> 3;
		GetMissileVel(i, x1, sy, v10, v9, v12);
	}
	v14 = i;
	v15 = GetDirection16(x1, sy, dx, v9);
	missile[v14]._mirange = 256;
	missile[v14]._miAnimFrame = v15 + 1;
}

//----- (0042ADAA) --------------------------------------------------------
void __fastcall GetVileMissPos(int mi, int dx, int dy)
{
	signed int v3; // edi
	int v4; // ebx
	int v5; // esi
	int v6; // eax
	int v7; // eax
	int v8; // [esp+Ch] [ebp-14h]
	int v9; // [esp+10h] [ebp-10h]
	signed int v10; // [esp+14h] [ebp-Ch]
	signed int v11; // [esp+18h] [ebp-8h]
	signed int v12; // [esp+1Ch] [ebp-4h]

	v8 = dx;
	v9 = mi;
	v12 = 1;
	v3 = -1;
	do
	{
		v11 = v3;
		if ( v3 <= v12 )
		{
			while ( 2 )
			{
				v10 = v3;
				v4 = v11 + dy;
				v5 = v3 + v8;
				do
				{
					if ( PosOkPlayer(myplr, v5, v4) )
					{
						v7 = v9;
						missile[v7]._mix = v5;
						missile[v7]._miy = v4;
						return;
					}
					++v10;
					++v5;
				}
				while ( v10 <= v12 );
				if ( ++v11 <= v12 )
					continue;
				break;
			}
		}
		++v12;
		--v3;
	}
	while ( v3 > -50 );
	v6 = v9;
	missile[v6]._mix = v8;
	missile[v6]._miy = dy;
}

//----- (0042AE48) --------------------------------------------------------
void __fastcall AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // eax
	int v10; // ecx
	int v11; // esi
	int v12; // eax
	int v13; // ecx
	int v14; // edi
	int v15; // ecx
	int v16; // eax
	bool v17; // zf
	int v18; // ecx
	int v19; // ecx
	int v20; // [esp+Ch] [ebp-Ch]
	int mia; // [esp+10h] [ebp-8h]
	int v22; // [esp+14h] [ebp-4h]

	v22 = 0;
	v20 = sx;
	mia = mi;
	while ( ++v22 <= 500 )
	{
		_LOBYTE(mi) = 58;
		v9 = random(mi, 3);
		_LOBYTE(v10) = 58;
		v11 = v9 + 4;
		v12 = random(v10, 3);
		_LOBYTE(v13) = 58;
		v14 = v12 + 4;
		if ( random(v13, 2) == 1 )
			v11 = -v11;
		_LOBYTE(v15) = 58;
		if ( random(v15, 2) == 1 )
			v14 = -v14;
		mi = 4 * (sy + v14 + 112 * (v11 + v20));
		if ( !nSolidTable[dPiece[0][mi / 4u]] && !dObject[v11 + v20][sy + v14] && !dMonster[0][mi / 4u] )
			goto LABEL_12;
	}
	v11 = 0;
	v14 = 0;
LABEL_12:
	v16 = mia;
	missile[v16]._miVar1 = 0;
	v17 = setlevel == 0;
	missile[v16]._mirange = 2;
	if ( v17 || setlvlnum != SL_VILEBETRAYER )
	{
		missile[v16]._mix = v20 + v11;
		missile[v16]._miy = sy + v14;
		if ( !(_BYTE)mienemy )
			UseMana(id, 10);
	}
	else
	{
		v18 = object[dObject[dx][dy] - 1]._otype;
		if ( v18 == OBJ_MCIRCLE1 || v18 == OBJ_MCIRCLE2 )
		{
			v19 = myplr;
			missile[v16]._mix = dx;
			missile[v16]._miy = dy;
			if ( !PosOkPlayer(v19, dx, dy) )
				GetVileMissPos(mia, dx, dy);
		}
	}
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (0042AF8B) --------------------------------------------------------
void __fastcall AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam)
{
	int v9; // ebx
	int v10; // esi
	int v11; // edi
	int v12; // eax
	int v13; // eax
	int v14; // eax
	int v15; // esi
	signed int v16; // [esp-4h] [ebp-14h]
	int i; // [esp+Ch] [ebp-4h]
	int micastera; // [esp+28h] [ebp+18h]

	v9 = dx;
	v10 = dy;
	v11 = sx;
	i = mi;
	if ( sx == dx && sy == dy )
	{
		v9 = XDirAdd[midir] + dx;
		v10 = YDirAdd[midir] + dy;
	}
	if ( (_BYTE)micaster )
	{
		v16 = 26;
		goto LABEL_17;
	}
	for ( micastera = 0; micastera < nummissiles; ++micastera )
	{
		v12 = missileactive[micastera];
		if ( missile[v12]._mitype == 2 && missile[v12]._misource == id && missile[v12]._miVar3 == mi )
			break;
	}
	if ( micastera == nummissiles )
		UseMana(id, 1);
	if ( id == -1 )
	{
		v16 = 16;
		goto LABEL_17;
	}
	v13 = 2 * missile[i]._mispllvl + 16;
	if ( v13 >= 63 )
	{
		v16 = 63;
LABEL_17:
		v13 = v16;
	}
	GetMissileVel(i, v11, sy, v9, v10, v13);
	v14 = GetDirection16(v11, sy, v9, v10);
	SetMissDir(i, v14);
	v15 = i;
	missile[v15]._mirange = 256;
	missile[v15]._miVar1 = v11;
	missile[v15]._miVar2 = sy;
	missile[v15]._mlid = AddLight(v11, sy, 8);
}

//----- (0042B09A) --------------------------------------------------------
void __fastcall AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // edi
	int i; // ST1C_4

	v9 = mi;
	v10 = sx;
	i = mi;
	GetMissileVel(mi, sx, sy, dx, dy, 16);
	v9 *= 176;
	*(int *)((char *)&missile[0]._mitxoff + v9) += 3 * *(int *)((char *)&missile[0]._mixvel + v9);
	*(int *)((char *)&missile[0]._mityoff + v9) += 3 * *(int *)((char *)&missile[0]._miyvel + v9);
	GetMissilePos(i);
	*(int *)((char *)&missile[0]._mirange + v9) = 256;
	*(int *)((char *)&missile[0]._miVar1 + v9) = v10;
	*(int *)((char *)&missile[0]._miVar2 + v9) = sy;
	*(int *)((char *)&missile[0]._mlid + v9) = AddLight(v10, sy, 8);
}

//----- (0042B113) --------------------------------------------------------
void __fastcall miss_null_33(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // edi
	int v11; // eax

	v9 = sx;
	v10 = mi;
	GetMissileVel(mi, sx, sy, dx, dy, 16);
	v11 = v10;
	missile[v11]._mirange = 256;
	missile[v11]._miVar1 = v9;
	missile[v11]._miVar2 = sy;
	PutMissile(v10);
}

//----- (0042B159) --------------------------------------------------------
void __fastcall AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // eax
	int v11; // ecx
	unsigned char *v12; // edx
	int v13; // ecx
	int v14; // eax
	int v15; // edx
	int v16; // ebx
	int v17; // edi
	int v18; // edx
	int v19; // [esp+Ch] [ebp-28h]
	int v20; // [esp+10h] [ebp-24h]
	int v21; // [esp+14h] [ebp-20h]
	int v22; // [esp+18h] [ebp-1Ch]
	int v23; // [esp+1Ch] [ebp-18h]
	int v24; // [esp+20h] [ebp-14h]
	int v25; // [esp+24h] [ebp-10h]
	unsigned char *v26; // [esp+28h] [ebp-Ch]
	int v27; // [esp+2Ch] [ebp-8h]
	int v28; // [esp+30h] [ebp-4h]

	v19 = 0;
	v9 = mi;
	v28 = 0;
	v20 = 3;
	v21 = 12;
	v22 = 45;
	v23 = 94;
	v24 = 159;
	missile[mi]._miDelFlag = 1;
	do
	{
		v10 = *(&v19 + v28);
		v11 = *(&CrawlTable.n_1 + v10);
		v27 = *(&CrawlTable.n_1 + v10);
		if ( v11 <= 0 )
			goto LABEL_13;
		v12 = &CrawlTable.delta_1[0].y + v10;
		v26 = &CrawlTable.delta_1[0].y + v10;
		while ( 1 )
		{
			v13 = dx + (char)*(v12 - 1);
			v14 = dy + (char)*v12;
			if ( v13 <= 0 || v13 >= 112 || v14 <= 0 || v14 >= 112 )
				goto LABEL_10;
			v15 = v14 + 112 * v13;
			v16 = dPlayer[0][v15];
			v17 = v15;
			v18 = dObject[0][v15];
			v25 = v17 * 4;
			if ( !(dMonster[0][v17] | v18 | v16 | (unsigned char)nSolidTable[dPiece[0][v17]]) )
				break;
			v12 = v26;
LABEL_10:
			v12 += 2;
			--v27;
			v26 = v12;
			if ( v27 <= 0 )
				goto LABEL_13;
		}
		missile[v9]._miDelFlag = 0;
		missile[v9]._mix = v13;
		missile[v9]._miy = v14;
		missile[v9]._misx = v13;
		missile[v9]._misy = v14;
		v28 = 6;
LABEL_13:
		++v28;
	}
	while ( v28 < 6 );
	if ( !missile[v9]._miDelFlag )
	{
		UseMana(id, 23);
		missile[v9]._mirange = 2;
	}
}

//----- (0042B284) --------------------------------------------------------
void __fastcall AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edi
	int v10; // esi
	int v11; // esi
	int v12; // ecx
	int v13; // eax
	int v14; // eax

	v9 = sx;
	v10 = mi;
	GetMissileVel(mi, sx, sy, dx, dy, 16);
	v11 = v10;
	_LOBYTE(v12) = 63;
	missile[v11]._midam = dam;
	v13 = random(v12, 8);
	missile[v11]._mirange = 255;
	missile[v11]._miAnimFrame = v13 + 1;
	if ( id >= 0 )
	{
		v14 = plr[id].WorldY;
		missile[v11]._miVar1 = plr[id].WorldX;
		missile[v11]._miVar2 = v14;
	}
	else
	{
		missile[v11]._miVar1 = v9;
		missile[v11]._miVar2 = sy;
	}
}

//----- (0042B303) --------------------------------------------------------
void __fastcall AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ST20_4
	int i; // ST1C_4
	int v11; // esi
	int v12; // eax
	int v13; // ecx
	int v14; // eax
	int v15; // eax
	int v16; // eax

	v9 = sx;
	i = mi;
	_LOBYTE(mi) = 53;
	v11 = i;
	v12 = random(mi, 10);
	_LOBYTE(v13) = 53;
	missile[v11]._midam = 16 * (random(v13, 10) + v12 + plr[id]._pLevel + 2) >> 1;
	GetMissileVel(i, v9, sy, dx, dy, 16);
	v14 = missile[i]._mispllvl;
	missile[v11]._mirange = 10;
	if ( v14 > 0 )
		missile[v11]._mirange = 2 * (5 * v14 + 5);
	v15 = ((missile[v11]._mirange * plr[id]._pISplDur >> 3) & 0xFFFFFFF0) + 16 * missile[v11]._mirange;
	missile[v11]._mirange = v15;
	v16 = v15 - missile[v11]._miAnimLen;
	missile[v11]._miVar2 = 0;
	missile[v11]._miVar1 = v16;
}

//----- (0042B3C0) --------------------------------------------------------
void __fastcall AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edi
	int v10; // eax
	int v11; // ecx
	int v12; // ecx
	int v13; // edx
	int v14; // esi
	int v15; // eax
	int v16; // esi
	int i; // [esp+Ch] [ebp-4h]
	int mienemya; // [esp+28h] [ebp+18h]

	v9 = sx;
	i = mi;
	if ( sx == dx )
	{
		mi = dy;
		if ( sy == dy )
		{
			mi = YDirAdd[midir] + dy;
			dx += XDirAdd[midir];
			dy += YDirAdd[midir];
		}
	}
	if ( (_BYTE)mienemy )
	{
		v14 = 16;
	}
	else
	{
		_LOBYTE(mi) = 60;
		v10 = random(mi, 10);
		_LOBYTE(v11) = 60;
		v12 = 2 * (plr[id]._pLevel + random(v11, 10) + v10) + 4;
		v13 = missile[i]._mispllvl;
		missile[i]._midam = v12;
		if ( v13 > 0 )
		{
			mienemya = v13;
			do
			{
				v12 += v12 >> 3;
				--mienemya;
			}
			while ( mienemya );
			missile[i]._midam = v12;
		}
		v14 = 2 * v13 + 16;
		if ( v14 > 50 )
			v14 = 50;
		UseMana(id, 12);
	}
	GetMissileVel(i, v9, sy, dx, dy, v14);
	v15 = GetDirection16(v9, sy, dx, dy);
	SetMissDir(i, v15);
	v16 = i;
	missile[v16]._miVar3 = 0;
	missile[v16]._mirange = 256;
	missile[v16]._miVar1 = v9;
	missile[v16]._miVar2 = sy;
	missile[v16]._miVar4 = v9;
	missile[v16]._miVar5 = sy;
	missile[v16]._mlid = AddLight(v9, sy, 8);
}

//----- (0042B4E7) --------------------------------------------------------
void __fastcall AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edi
	int v10; // ebx
	int v11; // esi
	int v12; // ecx
	int v13; // eax

	v9 = sx;
	v10 = mi;
	if ( !dam && !(_BYTE)mienemy )
		UseMana(id, 3);
	v11 = v10;
	missile[v11]._miVar1 = v9;
	missile[v11]._miVar2 = sy;
	GetMissileVel(v10, v9, sy, dx, dy, 32);
	_LOBYTE(v12) = 52;
	v13 = random(v12, 8);
	missile[v11]._mirange = 256;
	missile[v11]._miAnimFrame = v13 + 1;
}

//----- (0042B553) --------------------------------------------------------
void __fastcall AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi

	v9 = mi;
	missile[v9]._misx = dx;
	missile[v9]._misy = dy;
	if ( midir >= 0 )
	{
		missile[v9]._mixoff = missile[midir]._mixoff;
		missile[v9]._miyoff = missile[midir]._miyoff;
		mi = missile[midir]._mitxoff;
		missile[v9]._mitxoff = mi;
		missile[v9]._mityoff = missile[midir]._mityoff;
	}
	_LOBYTE(mi) = 52;
	missile[v9]._miAnimFrame = random(mi, 8) + 1;
	if ( midir < 0 )
		goto LABEL_9;
	if ( (_BYTE)mienemy == 1 )
	{
		if ( id != -1 )
		{
			missile[v9]._mirange = 10;
			goto LABEL_10;
		}
LABEL_9:
		missile[v9]._mirange = 8;
		goto LABEL_10;
	}
	if ( id == -1 )
		goto LABEL_9;
	missile[v9]._mirange = (missile[v9]._mispllvl >> 1) + 6;
LABEL_10:
	missile[v9]._mlid = AddLight(missile[v9]._mix, missile[v9]._miy, 4);
}

//----- (0042B620) --------------------------------------------------------
void __fastcall AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edi
	CMonster *v10; // esi
	int v11; // eax
	int v12; // ecx

	v9 = mi;
	if ( (_BYTE)mienemy && id > 0 )
	{
		v10 = monster[id].MType;
		if ( v10->mtype == MON_SUCCA )
			SetMissAnim(mi, MFILE_FLAREEXP);
		if ( v10->mtype == MON_SUCCB )
			SetMissAnim(v9, MFILE_SCBSEXPB);
		if ( v10->mtype == MON_SUCCC )
			SetMissAnim(v9, MFILE_SCBSEXPD);
		if ( v10->mtype == MON_SUCCD )
			SetMissAnim(v9, MFILE_SCBSEXPC);
	}
	v11 = v9;
	missile[v11]._mix = missile[dx]._mix;
	missile[v11]._miy = missile[dx]._miy;
	missile[v11]._misx = missile[dx]._misx;
	missile[v11]._misy = missile[dx]._misy;
	missile[v11]._mixoff = missile[dx]._mixoff;
	missile[v11]._miyoff = missile[dx]._miyoff;
	missile[v11]._mitxoff = missile[dx]._mitxoff;
	v12 = missile[dx]._mityoff;
	missile[v11]._mixvel = 0;
	missile[v11]._miyvel = 0;
	missile[v11]._miVar1 = 0;
	missile[v11]._mityoff = v12;
	missile[v11]._mirange = missile[v9]._miAnimLen;
}

//----- (0042B711) --------------------------------------------------------
void __fastcall AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi

	v9 = mi;
	missile[v9]._miy = sy;
	missile[v9]._misy = sy;
	missile[v9]._mix = sx;
	missile[v9]._misx = sx;
	missile[v9]._mixvel = 0;
	missile[v9]._miyvel = 0;
	missile[v9]._miVar1 = 0;
	missile[v9]._miVar2 = dx;
	missile[v9]._mimfnum = 0;
	if ( dx == 1 )
		SetMissAnim(mi, 5);
	else
		SetMissAnim(mi, MFILE_MINILTNG);
	missile[v9]._mirange = missile[v9]._miAnimLen - 1;
}

//----- (0042B77C) --------------------------------------------------------
unsigned char __fastcall CheckIfTrig(int x, int y)
{
	int v2; // edi
	int v3; // ebx
	int *v4; // esi
	int v5; // eax
	int v7; // [esp+Ch] [ebp-4h]

	v7 = 0;
	v2 = y;
	v3 = x;
	if ( trigflag[4] <= 0 )
		return 0;
	v4 = &trigs[0]._ty;
	while ( 1 )
	{
		v5 = *(v4 - 1);
		if ( v3 == v5 && v2 == *v4 )
			break;
		if ( abs(v5 - v3) < 2 && abs(*v4 - v2) < 2 )
			break;
		++v7;
		v4 += 4;
		if ( v7 >= trigflag[4] )
			return 0;
	}
	return 1;
}

//----- (0042B7DF) --------------------------------------------------------
void __fastcall AddTown(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ebx
	int v10; // esi
	int v11; // edi
	int v12; // eax
	int v13; // ecx
	unsigned char *v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // ecx
	int v18; // eax
	int v19; // eax
	int v20; // ecx
	int v21; // eax
	int v22; // ST0C_4
	int v23; // [esp+Ch] [ebp-28h]
	int v24; // [esp+10h] [ebp-24h]
	int v25; // [esp+14h] [ebp-20h]
	int v26; // [esp+18h] [ebp-1Ch]
	int v27; // [esp+1Ch] [ebp-18h]
	int v28; // [esp+20h] [ebp-14h]
	int i; // [esp+24h] [ebp-10h]
	unsigned char *v30; // [esp+28h] [ebp-Ch]
	int v31; // [esp+2Ch] [ebp-8h]
	int v32; // [esp+30h] [ebp-4h]
	int x; // [esp+40h] [ebp+Ch]

	_LOBYTE(v9) = dx;
	i = mi;
	v10 = mi;
	v23 = 0;
	v24 = 3;
	v25 = 12;
	v26 = 45;
	v27 = 94;
	v28 = 159;
	if ( currlevel )
	{
		_LOBYTE(v11) = dx;
		missile[v10]._miDelFlag = 1;
		v31 = 0;
		do
		{
			v12 = *(&v23 + v31);
			v13 = *(&CrawlTable.n_1 + v12);
			v32 = *(&CrawlTable.n_1 + v12);
			if ( v13 > 0 )
			{
				v14 = &CrawlTable.delta_1[0].y + v12;
				v30 = v14;
				while ( 1 )
				{
					v9 = dx + (char)*(v14 - 1);
					v11 = dy + (char)*v14;
					if ( v9 > 0 && v9 < 112 && v11 > 0 && v11 < 112 )
					{
						v15 = v11 + 112 * v9;
						if ( !(dObject[0][v15] | dPlayer[0][v15] | dMissile[0][v15] | (unsigned char)nSolidTable[dPiece[0][v15]] | (unsigned char)nMissileTable[dPiece[0][v15]]) )
						{
							_LOBYTE(v16) = CheckIfTrig(v9, v11);
							if ( !v16 )
								break;
						}
					}
					v14 = v30 + 2;
					--v32;
					v30 += 2;
					if ( v32 <= 0 )
						goto LABEL_14;
				}
				missile[v10]._miDelFlag = 0;
				missile[v10]._mix = v9;
				missile[v10]._miy = v11;
				missile[v10]._misx = v9;
				missile[v10]._misy = v11;
				v31 = 6;
			}
LABEL_14:
			++v31;
		}
		while ( v31 < 6 );
	}
	else
	{
		_LOBYTE(v11) = dy;
		missile[v10]._mix = dx;
		missile[v10]._miy = dy;
		missile[v10]._misx = dx;
		missile[v10]._misy = dy;
		missile[v10]._miDelFlag = 0;
	}
	v17 = nummissiles;
	missile[v10]._miVar2 = 0;
	v32 = 0;
	missile[v10]._mirange = 100;
	for ( missile[v10]._miVar1 = 100 - missile[v10]._miAnimLen; v32 < v17; ++v32 )
	{
		v18 = missileactive[v32];
		x = v18;
		v19 = v18;
		if ( missile[v19]._mitype == 10 && x != i && missile[v19]._misource == id )
			missile[v19]._mirange = 0;
	}
	PutMissile(i);
	_HIWORD(v21) = _HIWORD(id);
	if ( id == myplr && !missile[v10]._miDelFlag && currlevel )
	{
		if ( setlevel )
		{
			_LOWORD(v21) = (unsigned char)leveltype;
			v22 = v21;
			_LOWORD(v21) = (unsigned char)setlvlnum;
			NetSendCmdLocParam3(1u, CMD_ACTIVATEPORTAL, v9, v11, v21, v22, 1);
		}
		else
		{
			_LOWORD(v20) = (unsigned char)leveltype;
			_LOWORD(v21) = currlevel;
			NetSendCmdLocParam3(1u, CMD_ACTIVATEPORTAL, v9, v11, v21, v20, 0);
		}
	}
}
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (0042B9FC) --------------------------------------------------------
void __fastcall AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	signed int v10; // ebx
	char *v11; // edi
	int v12; // ecx
	int v13; // eax
	int v14; // eax

	v9 = mi;
	if ( (_BYTE)mienemy )
	{
		v14 = 2 * SLOBYTE(monster[id].mLevel);
		goto LABEL_12;
	}
	if ( id == -1 )
	{
		v14 = (unsigned int)currlevel >> 1;
LABEL_12:
		missile[v9]._midam = v14;
		goto LABEL_13;
	}
	v10 = 0;
	v11 = &plr[id]._pLevel;
	missile[v9]._midam = 0;
	if ( *v11 >= 0 )
	{
		do
		{
			_LOBYTE(mi) = 55;
			missile[v9]._midam += random(mi, 20) + 1;
			++v10;
		}
		while ( v10 <= *v11 );
	}
	v12 = missile[v9]._mispllvl;
	if ( v12 > 0 )
	{
		v13 = missile[v9]._midam;
		do
		{
			v13 += v13 >> 3;
			--v12;
		}
		while ( v12 );
		missile[v9]._midam = v13;
	}
	missile[v9]._midam += missile[v9]._midam >> 1;
LABEL_13:
	missile[v9]._mirange = 19;
}

//----- (0042BAC1) --------------------------------------------------------
void __fastcall AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	char *v10; // edi
	signed int v11; // ebx
	int v12; // ecx
	int v13; // eax
	int v14; // eax
	int v15; // [esp+4h] [ebp-4h]

	v15 = mi;
	if ( !(_BYTE)mienemy )
	{
		if ( id == -1 )
		{
			missile[mi]._midam = (unsigned int)currlevel >> 1;
		}
		else
		{
			v9 = mi;
			v10 = &plr[id]._pLevel;
			v11 = 0;
			for ( missile[mi]._midam = 0; v11 <= *v10; ++v11 )
			{
				_LOBYTE(mi) = 56;
				missile[v9]._midam += random(mi, 2) + 1;
			}
			v12 = missile[v9]._mispllvl;
			if ( v12 > 0 )
			{
				v13 = missile[v9]._midam;
				do
				{
					v13 += v13 >> 3;
					--v12;
				}
				while ( v12 );
				missile[v9]._midam = v13;
			}
			missile[v9]._midam += missile[v9]._midam >> 1;
		}
	}
	v14 = v15;
	missile[v14]._miPreFlag = 1;
	missile[v14]._mirange = 19;
}

//----- (0042BB83) --------------------------------------------------------
void __fastcall AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // eax

	v9 = mi;
	missile[v9]._miVar8 = -1;
	missile[v9]._mirange = 48 * plr[id]._pLevel;
	missile[v9]._miVar1 = plr[id]._pHitPoints;
	missile[v9]._miVar2 = plr[id]._pHPBase;
	if ( !(_BYTE)mienemy )
		UseMana(id, 11);
	if ( id == myplr )
		NetSendCmd(1u, CMD_SETSHIELD);
	plr[id].pManaShield = 1;
}

//----- (0042BBFA) --------------------------------------------------------
void __fastcall AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edi
	int v10; // ebx
	int v11; // esi

	v9 = mi;
	v10 = sx;
	v11 = mi;
	_LOBYTE(mi) = 59;
	v11 *= 176;
	*(int *)((char *)&missile[0]._midam + v11) = random(mi, 10) + plr[id]._pLevel + 1;
	GetMissileVel(v9, v10, sy, dx, dy, 16);
	*(int *)((char *)&missile[0]._miVar1 + v11) = 0;
	*(int *)((char *)&missile[0]._miVar2 + v11) = 0;
	++*(int *)((char *)&missile[0]._mix + v11);
	++*(int *)((char *)&missile[0]._miy + v11);
	*(int *)((char *)&missile[0]._miyoff + v11) -= 32;
	*(int *)((char *)&missile[0]._mirange + v11) = 255;
}

//----- (0042BC76) --------------------------------------------------------
void __fastcall AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edi
	int v10; // esi
	int v11; // esi
	int v12; // eax
	int v13; // ecx
	int v14; // eax
	int v15; // ecx
	unsigned char *v16; // eax
	int v17; // ebx
	int v18; // edi
	int v19; // eax
	int v20; // edx
	int v21; // ecx
	int v22; // eax
	int v23; // ecx
	int v24; // eax
	int v25; // eax
	int v26; // eax
	int v27; // eax
	int v28; // [esp+8h] [ebp-38h]
	int v29; // [esp+Ch] [ebp-34h]
	int v30; // [esp+10h] [ebp-30h]
	int v31; // [esp+14h] [ebp-2Ch]
	int v32; // [esp+18h] [ebp-28h]
	int v33; // [esp+1Ch] [ebp-24h]
	unsigned int v34; // [esp+20h] [ebp-20h]
	int v35; // [esp+24h] [ebp-1Ch]
	int v36; // [esp+28h] [ebp-18h]
	int x1; // [esp+2Ch] [ebp-14h]
	int v38; // [esp+30h] [ebp-10h]
	unsigned char *v39; // [esp+34h] [ebp-Ch]
	int v40; // [esp+38h] [ebp-8h]
	int v41; // [esp+3Ch] [ebp-4h]

	v28 = 0;
	v9 = 21720 * id;
	x1 = sx;
	v10 = mi;
	_LOBYTE(mi) = 62;
	v29 = 3;
	v30 = 12;
	v31 = 45;
	v32 = 94;
	v33 = 159;
	v38 = 21720 * id;
	v11 = v10;
	v12 = random(mi, 10) + (plr[id]._pLevel >> 1) + 1;
	v13 = missile[v11]._mispllvl;
	missile[v11]._midam = v12;
	if ( v13 > 0 )
	{
		do
		{
			v12 += v12 >> 3;
			--v13;
		}
		while ( v13 );
		missile[v11]._midam = v12;
	}
	v41 = 0;
	missile[v11]._miDelFlag = 1;
	do
	{
		v14 = *(&v28 + v41);
		v15 = *(&CrawlTable.n_1 + v14);
		v40 = *(&CrawlTable.n_1 + v14);
		if ( v15 <= 0 )
			goto LABEL_18;
		v16 = &CrawlTable.delta_1[0].y + v14;
		v39 = v16;
		while ( 1 )
		{
			v17 = dx + (char)*(v16 - 1);
			v18 = dy + (char)*v16;
			v35 = v18 + 112 * (dx + (char)*(v16 - 1));
			v34 = 4 * v35;
			v36 = dPiece[0][v35];
			if ( v17 <= 0 || v17 >= 112 || v18 <= 0 || v18 >= 112 )
				goto LABEL_14;
			_LOBYTE(v19) = LineClear(x1, sy, v17, v18);
			if ( v19 )
			{
				if ( !(dMonster[0][v34 / 4] | dObject[0][v35] | dMissile[0][v35] | (unsigned char)nSolidTable[v36] | (unsigned char)nMissileTable[v36]) )
					break;
			}
			v16 = v39;
LABEL_14:
			v16 += 2;
			--v40;
			v39 = v16;
			if ( v40 <= 0 )
				goto LABEL_17;
		}
		missile[v11]._miDelFlag = 0;
		missile[v11]._mix = v17;
		missile[v11]._miy = v18;
		missile[v11]._misx = v17;
		missile[v11]._misy = v18;
		UseMana(id, 13);
		v41 = 6;
LABEL_17:
		v9 = v38;
LABEL_18:
		++v41;
	}
	while ( v41 < 6 );
	if ( missile[v11]._miDelFlag != 1 )
	{
		v20 = missile[v11]._miy;
		v21 = missile[v11]._mix;
		missile[v11]._misource = id;
		v22 = AddLight(v21, v20, 1);
		v23 = missile[v11]._mispllvl;
		missile[v11]._mlid = v22;
		v24 = v23 + (*(&plr[0]._pLevel + v9) >> 1);
		v25 = (v24 * *(int *)((char *)&plr[0]._pISplDur + v9) >> 7) + v24;
		missile[v11]._mirange = v25;
		if ( v25 > 30 )
			missile[v11]._mirange = 30;
		missile[v11]._mirange *= 16;
		if ( missile[v11]._mirange < 30 )
			missile[v11]._mirange = 30;
		v26 = missile[v11]._mirange;
		missile[v11]._miVar3 = 1;
		v27 = v26 - missile[v11]._miAnimLen;
		missile[v11]._miVar2 = 0;
		missile[v11]._miVar1 = v27;
	}
}

//----- (0042BE98) --------------------------------------------------------
void __fastcall AddChain(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ecx

	v9 = mi;
	missile[v9]._miVar1 = dx;
	missile[v9]._miVar2 = dy;
	missile[v9]._mirange = 1;
}

//----- (0042BECB) --------------------------------------------------------
void __fastcall miss_null_11(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // eax

	v9 = mi;
	SetMissDir(mi, dx);
	v10 = v9;
	missile[v10]._midam = 0;
	missile[v10]._miLightFlag = 1;
	missile[v10]._mirange = 250;
}

//----- (0042BEFE) --------------------------------------------------------
void __fastcall miss_null_12(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	signed int v9; // edx
	int v10; // esi
	int v11; // eax

	v9 = dx;
	v10 = mi;
	if ( dx > 3 )
		v9 = 2;
	SetMissDir(mi, v9);
	v11 = v10;
	missile[v11]._midam = 0;
	missile[v11]._miLightFlag = 1;
	missile[v11]._mirange = 250;
}

//----- (0042BF3B) --------------------------------------------------------
void __fastcall miss_null_13(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	signed int v9; // edx
	int v10; // esi
	int v11; // eax
	int v12; // ecx

	v9 = dx;
	v10 = mi;
	if ( dx > 3 )
		v9 = 2;
	SetMissDir(mi, v9);
	v11 = v10;
	v12 = missile[v10]._miAnimLen;
	missile[v11]._midam = 0;
	missile[v11]._miLightFlag = 1;
	missile[v11]._mirange = v12;
}

//----- (0042BF7A) --------------------------------------------------------
void __fastcall AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	CMonster *v10; // eax
	char v11; // cl
	int v12; // edi
	int v13; // eax
	CMonster *v14; // ecx
	char v15; // cl
	bool v16; // zf
	int i; // [esp+8h] [ebp-4h]

	v9 = id;
	i = mi;
	v10 = monster[id].MType;
	v11 = v10->mtype;
	if ( v10->mtype < MON_RHINOA || v11 > MON_RHINOD )
	{
		if ( v11 < MON_SNAKEA || (v12 = (int)v10->Anims[2].Frames, v11 > MON_SNAKED) )
			v12 = (int)v10->Anims[1].Frames;
	}
	else
	{
		v12 = (int)v10->Anims[5].Frames;
	}
	GetMissileVel(i, sx, sy, dx, dy, 18);
	v13 = i;
	missile[v13]._miAnimFlags = 0;
	missile[v13]._mimfnum = midir;
	missile[v13]._miAnimCel = *(_DWORD *)(v12 + 4 * midir + 4);
	missile[v13]._miAnimDelay = *(_DWORD *)(v12 + 40);
	missile[v13]._miAnimLen = *(_DWORD *)(v12 + 36);
	v14 = monster[v9].MType;
	missile[v13]._miAnimWidth = v14->flags_1;
	missile[v13]._miAnimWidth2 = v14->flags_2;
	missile[v13]._miAnimAdd = 1;
	v15 = v14->mtype;
	if ( v15 >= MON_SNAKEA && v15 <= MON_SNAKED )
		missile[v13]._miAnimFrame = 7;
	missile[v13]._miVar1 = 0;
	missile[v13]._miVar2 = 0;
	v16 = monster[v9]._uniqtype == 0;
	missile[v13]._miLightFlag = 1;
	if ( !v16 )
	{
		missile[v13]._miUniqTrans = (unsigned char)monster[v9]._uniqtrans + 1;
		missile[v13]._mlid = (unsigned char)monster[v9].mlid;
	}
	missile[v13]._mirange = 256;
	PutMissile(i);
}

//----- (0042C08B) --------------------------------------------------------
void __fastcall miss_null_32(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // ebx
	AnimStruct *v11; // edi
	int v12; // eax
	CMonster *v13; // ecx
	bool v14; // zf
	int v15; // ecx

	v9 = id;
	v10 = mi;
	v11 = &monster[id].MType->Anims[1];
	GetMissileVel(mi, sx, sy, dx, dy, 16);
	v12 = v10;
	missile[v12]._mimfnum = midir;
	missile[v12]._miAnimFlags = 0;
	missile[v12]._miAnimCel = v11->Frames[midir + 1];
	missile[v12]._miAnimDelay = v11->Delay;
	missile[v12]._miAnimLen = v11->Rate;
	v13 = monster[id].MType;
	missile[v12]._miAnimWidth = v13->flags_1;
	missile[v12]._miAnimWidth2 = v13->flags_2;
	v14 = monster[id]._uniqtype == 0;
	missile[v12]._miAnimAdd = 1;
	missile[v12]._miVar1 = 0;
	missile[v12]._miVar2 = 0;
	missile[v12]._miLightFlag = 1;
	if ( !v14 )
		missile[v12]._miUniqTrans = (unsigned char)monster[v9]._uniqtrans + 1;
	v15 = monster[v9]._mx;
	missile[v12]._mirange = 256;
	dMonster[0][monster[v9]._my + 112 * v15] = 0;
	PutMissile(v10);
}

//----- (0042C167) --------------------------------------------------------
void __fastcall AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edi
	int v10; // edx
	int v11; // esi
	int v12; // ecx
	int v13; // esi
	int v14; // eax
	CMonster *v15; // esi
	int code; // [esp+Ch] [ebp-4h]

	v9 = sx;
	v10 = dx;
	v11 = mi;
	v12 = dy;
	code = v11;
	if ( v9 == dx && sy == dy )
	{
		v10 = XDirAdd[midir] + dx;
		v12 = YDirAdd[midir] + dy;
	}
	GetMissileVel(v11, v9, sy, v10, v12, 16);
	v13 = v11;
	missile[v13]._mirange = 256;
	missile[v13]._miVar1 = v9;
	missile[v13]._miVar2 = sy;
	missile[v13]._mlid = AddLight(v9, sy, 8);
	if ( (_BYTE)mienemy )
	{
		if ( id > 0 )
		{
			v15 = monster[id].MType;
			if ( v15->mtype == MON_SUCCA )
				SetMissAnim(code, MFILE_FLARE);
			if ( v15->mtype == MON_SUCCB )
				SetMissAnim(code, MFILE_SCUBMISB);
			if ( v15->mtype == MON_SUCCC )
				SetMissAnim(code, MFILE_SCUBMISD);
			if ( v15->mtype == MON_SUCCD )
				SetMissAnim(code, MFILE_SCUBMISC);
		}
	}
	else
	{
		UseMana(id, 35);
		v14 = id;
		drawhpflag = 1;
		plr[v14]._pHPBase -= 320;
		plr[v14]._pHitPoints -= 320;
		if ( plr[id]._pHitPoints <= 0 )
			SyncPlrKill(id, 0);
	}
}

//----- (0042C276) --------------------------------------------------------
void __fastcall AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // edi
	int v11; // eax
	int v12; // eax
	int v13; // ecx

	v9 = sx;
	v10 = mi;
	GetMissileVel(mi, sx, sy, dx, dy, 16);
	v11 = GetDirection16(v9, sy, dx, dy);
	SetMissDir(v10, v11);
	v12 = v10;
	v13 = (unsigned char)monster[id]._mint;
	missile[v12]._mlid = -1;
	missile[v12]._miVar1 = v9;
	missile[v12]._miVar2 = sy;
	missile[v12]._mirange = 5 * (v13 + 4);
	PutMissile(v10);
}

//----- (0042C2EE) --------------------------------------------------------
void __fastcall miss_null_1D(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ecx
	int v10; // eax

	v9 = mi;
	missile[v9]._midam = dam;
	missile[v9]._mirange = 50;
	v10 = 50 - missile[v9]._miAnimLen;
	missile[v9]._mixvel = 0;
	missile[v9]._miyvel = 0;
	missile[v9]._miVar1 = v10;
	missile[v9]._miVar2 = 0;
}

//----- (0042C32A) --------------------------------------------------------
void __fastcall AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // edi
	int v11; // eax

	v9 = mi;
	v10 = missile[mi]._misource;
	_LOBYTE(mi) = 50;
	missile[v9]._mixvel = 0;
	missile[v9]._miyvel = 0;
	missile[v9]._mixoff = 0;
	missile[v9]._miyoff = 0;
	missile[v9]._miLightFlag = 1;
	v11 = random(mi, 15);
	missile[v9]._miPreFlag = 1;
	missile[v9]._mirange = v11 + 40 * ((unsigned char)monster[v10]._mint + 1);
}

//----- (0042C38E) --------------------------------------------------------
void __fastcall AddStone(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // eax
	int v10; // edx
	int v11; // esi
	int v12; // edi
	int v13; // ecx
	unsigned char *v14; // ecx
	int v15; // ebx
	int v16; // ebx
	int v17; // edi
	int *v18; // edi
	int v19; // ecx
	int v20; // edx
	int v21; // ecx
	int v22; // edx
	int *v23; // eax
	int v24; // [esp+Ch] [ebp-20h]
	int v25; // [esp+10h] [ebp-1Ch]
	int v26; // [esp+14h] [ebp-18h]
	int v27; // [esp+18h] [ebp-14h]
	int v28; // [esp+1Ch] [ebp-10h]
	int v29; // [esp+20h] [ebp-Ch]
	int v30; // [esp+24h] [ebp-8h]
	int v31; // [esp+28h] [ebp-4h]

	v9 = mi;
	v24 = 0;
	v31 = 0;
	v10 = id;
	v11 = id;
	v25 = 3;
	v26 = 12;
	v27 = 45;
	v28 = 94;
	v29 = 159;
	missile[mi]._misource = id;
	do
	{
		v12 = *(&v24 + v31);
		v13 = *(&CrawlTable.n_1 + v12);
		v30 = *(&CrawlTable.n_1 + v12);
		if ( v13 > 0 )
		{
			v14 = &CrawlTable.delta_1[0].y + v12;
			while ( 1 )
			{
				v10 = dx + (char)*(v14 - 1);
				v11 = dy + (char)*v14;
				if ( v10 > 0 && v10 < 112 && v11 > 0 && v11 < 112 )
				{
					v15 = dMonster[0][v11 + 112 * v10];
					v16 = v15 <= 0 ? -1 - v15 : v15 - 1;
					if ( v16 > 3 && monster[v16]._mAi != MG_DIABLO )
					{
						v17 = monster[v16]._mmode;
						if ( v17 != MM_FADEIN && v17 != MM_FADEOUT && v17 != MM_CHARGE )
							break;
					}
				}
				v14 += 2;
				if ( --v30 <= 0 )
					goto LABEL_19;
			}
			v30 = -99;
			v31 = 6;
			missile[v9]._miVar2 = v16;
			v18 = (int *)&monster[v16]._mmode;
			v19 = *v18;
			*v18 = MM_STONE;
			missile[v9]._miVar1 = v19;
		}
LABEL_19:
		++v31;
	}
	while ( v31 < 6 );
	if ( v30 == -99 )
	{
		missile[v9]._mix = v10;
		missile[v9]._misx = v10;
		v20 = missile[v9]._mispllvl + 6;
		v21 = v20 * plr[id]._pISplDur >> 7;
		missile[v9]._miy = v11;
		missile[v9]._misy = v11;
		v22 = v21 + v20;
		v23 = &missile[v9]._mirange;
		*v23 = v22;
		if ( v22 > 15 )
			*v23 = 15;
		*v23 *= 16;
		UseMana(id, 8);
	}
	else
	{
		missile[v9]._miDelFlag = 1;
	}
}

//----- (0042C518) --------------------------------------------------------
void __fastcall AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // eax
	int v10; // ebx
	int v11; // edi
	int v12; // ecx
	bool v13; // zf
	bool v14; // sf
	int v15; // esi
	int v16; // esi
	int v17; // [esp+Ch] [ebp-8h]
	int v18; // [esp+10h] [ebp-4h]

	v18 = mi;
	v9 = mi;
	v10 = id;
	v11 = nummissiles;
	v12 = 0;
	v13 = nummissiles == 0;
	v14 = nummissiles < 0;
	missile[v9]._miDelFlag = 0;
	if ( v14 || v13 )
	{
LABEL_6:
		missile[v9]._miVar1 = sx;
		missile[v9]._miVar2 = sy;
		missile[v9]._miVar4 = dx;
		missile[v9]._miVar5 = dy;
		if ( (monster[v10]._mx != 1 || monster[v10]._my) && v10 == myplr )
			M_StartKill(v10, v10);
	}
	else
	{
		while ( 1 )
		{
			v15 = missileactive[v12];
			v17 = v15;
			v16 = v15;
			if ( missile[v16]._mitype == 33 )
			{
				v10 = id;
				if ( v17 != v18 && missile[v16]._misource == id )
					break;
			}
			if ( ++v12 >= v11 )
				goto LABEL_6;
		}
		missile[v9]._miDelFlag = 1;
	}
}

//----- (0042C5DA) --------------------------------------------------------
void __fastcall AddEtherealize(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // edx
	int v10; // eax
	int v11; // ecx
	int v12; // esi
	int v13; // esi
	int v14; // ecx

	v9 = id;
	v10 = mi;
	v11 = missile[mi]._mispllvl;
	v12 = 16 * plr[id]._pLevel >> 1;
	missile[v10]._mirange = v12;
	if ( v11 > 0 )
	{
		do
		{
			v12 += v12 >> 3;
			--v11;
		}
		while ( v11 );
		missile[v10]._mirange = v12;
	}
	v13 = missile[v10]._mirange + (missile[v10]._mirange * plr[v9]._pISplDur >> 7);
	missile[v10]._miVar1 = plr[v9]._pHitPoints;
	v14 = plr[v9]._pHPBase;
	missile[v10]._mirange = v13;
	missile[v10]._miVar2 = v14;
	if ( !(_BYTE)mienemy )
		UseMana(id, 25);
}

//----- (0042C664) --------------------------------------------------------
void __fastcall miss_null_1F(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	missile[mi]._miDelFlag = 1;
}

//----- (0042C677) --------------------------------------------------------
void __fastcall miss_null_23(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // edx
	int v11; // eax

	v9 = mi;
	missile[v9]._mix = sx;
	missile[v9]._miy = sy;
	missile[v9]._misx = sx;
	missile[v9]._misy = sy;
	v10 = 0;
	missile[v9]._midam = dam;
	missile[v9]._misource = id;
	if ( dam != 1 )
		v10 = 1;
	SetMissDir(mi, v10);
	v11 = missile[v9]._miAnimLen;
	missile[v9]._miLightFlag = 1;
	missile[v9]._mirange = v11;
}

//----- (0042C6D9) --------------------------------------------------------
void __fastcall AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ecx
	int v10; // edx

	v9 = mi;
	missile[v9]._miy = dy;
	missile[v9]._misy = dy;
	missile[v9]._mix = dx;
	missile[v9]._misx = dx;
	missile[v9]._midam = dam;
	v10 = missile[v9]._miAnimLen;
	missile[v9]._mixvel = 0;
	missile[v9]._miyvel = 0;
	missile[v9]._mirange = v10;
	missile[v9]._miVar1 = 0;
}

//----- (0042C72C) --------------------------------------------------------
void __fastcall AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	signed int v10; // ebx
	int v11; // ecx
	int v12; // edi
	int i; // ebx
	char v14; // al
	int v15; // ecx
	int *v16; // eax
	int *v17; // eax
	int v18; // esi
	int v19; // [esp+Ch] [ebp-8h]
	int v20; // [esp+10h] [ebp-4h]

	v19 = mi;
	_LOBYTE(mi) = 57;
	v9 = id;
	v10 = 0;
	v12 = (random(mi, 10) + 1) << 6;
	if ( plr[id]._pLevel > 0 )
	{
		do
		{
			_LOBYTE(v11) = 57;
			v12 += (random(v11, 4) + 1) << 6;
			++v10;
		}
		while ( v10 < plr[v9]._pLevel );
	}
	v20 = 0;
	for ( i = v19; v20 < missile[i]._mispllvl; ++v20 )
	{
		_LOBYTE(v11) = 57;
		v12 += (random(v11, 6) + 1) << 6;
	}
	v14 = plr[v9]._pClass;
	if ( !v14 )
		v12 *= 2;
	if ( v14 == 1 )
		v12 += v12 >> 1;
	v15 = plr[v9]._pMaxHP;
	v16 = &plr[v9]._pHitPoints;
	*v16 += v12;
	if ( plr[v9]._pHitPoints > v15 )
		*v16 = v15;
	v17 = &plr[v9]._pHPBase;
	v18 = plr[v9]._pMaxHPBase;
	*v17 += v12;
	if ( *v17 > v18 )
		*v17 = v18;
	missile[i]._miDelFlag = 1;
	drawhpflag = 1;
}

//----- (0042C80C) --------------------------------------------------------
void __fastcall AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	missile[mi]._miDelFlag = 1;
	UseMana(mienemy, 34);
	if ( mienemy == myplr )
		SetCursor(10);
}

//----- (0042C83F) --------------------------------------------------------
void __fastcall AddElement(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ebx
	int v10; // edi
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	int v14; // esi
	int v15; // ecx
	int v16; // eax
	int x; // [esp+Ch] [ebp-8h]
	int i; // [esp+10h] [ebp-4h]

	v9 = dx;
	v10 = dy;
	x = sx;
	i = mi;
	if ( sx == dx && sy == dy )
	{
		v9 = XDirAdd[midir] + dx;
		v10 = YDirAdd[midir] + dy;
	}
	_LOBYTE(mi) = 60;
	v11 = random(mi, 10);
	_LOBYTE(v12) = 60;
	v13 = 2 * (plr[id]._pLevel + random(v12, 10) + v11) + 4;
	v14 = i;
	v15 = missile[i]._mispllvl;
	missile[i]._midam = v13;
	if ( v15 > 0 )
	{
		do
		{
			v13 += v13 >> 3;
			--v15;
		}
		while ( v15 );
		missile[v14]._midam = v13;
	}
	missile[v14]._midam >>= 1;
	GetMissileVel(i, x, sy, v9, v10, 16);
	v16 = GetDirection8(x, sy, v9, v10);
	SetMissDir(i, v16);
	missile[v14]._miVar3 = 0;
	missile[v14]._mirange = 256;
	missile[v14]._miVar1 = x;
	missile[v14]._miVar2 = sy;
	missile[v14]._miVar4 = v9;
	missile[v14]._miVar5 = v10;
	missile[v14]._mlid = AddLight(x, sy, 8);
}

//----- (0042C942) --------------------------------------------------------
void __fastcall AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	missile[mi]._miDelFlag = 1;
	UseMana(mienemy, 5);
	if ( mienemy == myplr )
	{
		if ( sbookflag )
			sbookflag = 0;
		if ( !invflag )
			invflag = 1;
		SetCursor(2);
	}
}
// 4B8968: using guessed type int sbookflag;

//----- (0042C993) --------------------------------------------------------
void __fastcall AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // eax
	int v11; // ecx
	unsigned char *v12; // eax
	int v13; // ebx
	int v14; // edi
	int v15; // eax
	int v16; // [esp+Ch] [ebp-30h]
	int v17; // [esp+10h] [ebp-2Ch]
	int v18; // [esp+14h] [ebp-28h]
	int v19; // [esp+18h] [ebp-24h]
	int v20; // [esp+1Ch] [ebp-20h]
	int v21; // [esp+20h] [ebp-1Ch]
	int v22; // [esp+24h] [ebp-18h]
	int v23; // [esp+28h] [ebp-14h]
	unsigned char *v24; // [esp+2Ch] [ebp-10h]
	int x1; // [esp+30h] [ebp-Ch]
	int v26; // [esp+34h] [ebp-8h]
	int v27; // [esp+38h] [ebp-4h]

	v16 = 0;
	v9 = mi;
	v27 = 0;
	x1 = sx;
	v17 = 3;
	v18 = 12;
	v19 = 45;
	v20 = 94;
	v21 = 159;
	missile[mi]._miDelFlag = 1;
	do
	{
		v10 = *(&v16 + v27);
		v11 = *(&CrawlTable.n_1 + v10);
		v26 = *(&CrawlTable.n_1 + v10);
		if ( v11 <= 0 )
			goto LABEL_16;
		v12 = &CrawlTable.delta_1[0].y + v10;
		v24 = v12;
		while ( 1 )
		{
			v13 = dx + (char)*(v12 - 1);
			v14 = dy + (char)*v12;
			if ( v13 <= 0 || v13 >= 112 || v14 <= 0 || v14 >= 112 )
				goto LABEL_13;
			v23 = v14 + 112 * v13;
			v22 = dPiece[0][v23];
			_LOBYTE(v15) = LineClear(x1, sy, v13, v14);
			if ( v15 )
			{
				if ( (x1 != v13 || sy != v14) && !((unsigned char)nSolidTable[v22] | dObject[0][v23]) )
					break;
			}
			v12 = v24;
LABEL_13:
			v12 += 2;
			--v26;
			v24 = v12;
			if ( v26 <= 0 )
				goto LABEL_16;
		}
		missile[v9]._miDelFlag = 0;
		missile[v9]._miVar1 = v13;
		missile[v9]._miVar2 = v14;
		missile[v9]._miVar5 = v13;
		missile[v9]._miVar6 = v14;
		v27 = 6;
LABEL_16:
		++v27;
	}
	while ( v27 < 6 );
	if ( missile[v9]._miDelFlag != 1 )
	{
		missile[v9]._miVar7 = 0;
		missile[v9]._miVar8 = 0;
		missile[v9]._miVar3 = (midir - 2) & 7;
		missile[v9]._mirange = 7;
		missile[v9]._miVar4 = (midir + 2) & 7;
		UseMana(id, 6);
	}
}

//----- (0042CAF5) --------------------------------------------------------
void __fastcall AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ecx
	int v10; // eax
	int v11; // edx

	v9 = mi;
	v10 = 1584;
	v11 = missile[v9]._mispllvl;
	missile[v9]._mirange = 1584;
	if ( v11 > 0 )
	{
		do
		{
			v10 += v10 >> 3;
			--v11;
		}
		while ( v11 );
		missile[v9]._mirange = v10;
	}
	missile[v9]._mirange += missile[v9]._mirange * plr[id]._pISplDur >> 7;
	if ( !(_BYTE)mienemy )
		UseMana(id, 9);
}

//----- (0042CB5C) --------------------------------------------------------
void __fastcall AddWave(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ecx

	v9 = mi;
	missile[v9]._miVar3 = 0;
	missile[v9]._miVar4 = 0;
	missile[v9]._miVar1 = dx;
	missile[v9]._miVar2 = dy;
	missile[v9]._mirange = 1;
	missile[v9]._miAnimFrame = 4;
}

//----- (0042CBA7) --------------------------------------------------------
void __fastcall AddNova(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // eax
	int v11; // ecx
	int v12; // ebx
	int v13; // eax
	int v14; // ecx
	int v15; // ebx
	int v16; // eax
	int v17; // ecx
	int v18; // ebx
	int v19; // eax
	int v20; // ecx
	int v21; // ebx
	int v22; // eax
	int v23; // ecx
	int v24; // eax
	int v25; // eax
	int v26; // ecx
	int v27; // edi
	int v28; // eax
	int v29; // ecx

	v9 = mi;
	missile[v9]._miVar1 = dx;
	missile[v9]._miVar2 = dy;
	_LOBYTE(mi) = 66;
	if ( id == -1 )
	{
		v25 = random(mi, 3);
		_LOBYTE(v26) = 66;
		v27 = v25;
		v28 = random(v26, 3);
		_LOBYTE(v29) = 66;
		missile[v9]._midam = ((unsigned int)currlevel >> 1) + random(v29, 3) + v28 + v27;
	}
	else
	{
		v10 = random(mi, 6);
		_LOBYTE(v11) = 66;
		v12 = v10;
		v13 = random(v11, 6);
		_LOBYTE(v14) = 66;
		v15 = v13 + v12;
		v16 = random(v14, 6);
		_LOBYTE(v17) = 66;
		v18 = v16 + v15;
		v19 = random(v17, 6);
		_LOBYTE(v20) = 66;
		v21 = v19 + v18;
		v22 = random(v20, 6);
		v23 = missile[v9]._mispllvl;
		v24 = (v22 + v21 + plr[id]._pLevel + 5) >> 1;
		missile[v9]._midam = v24;
		if ( v23 > 0 )
		{
			do
			{
				v24 += v24 >> 3;
				--v23;
			}
			while ( v23 );
			missile[v9]._midam = v24;
		}
		if ( !(_BYTE)mienemy )
			UseMana(id, 18);
	}
	missile[v9]._mirange = 1;
}

//----- (0042CC98) --------------------------------------------------------
void __fastcall AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	missile[mi]._miDelFlag = 1;
	UseMana(mienemy, 26);
	if ( mienemy == myplr )
	{
		if ( sbookflag )
			sbookflag = 0;
		if ( !invflag )
			invflag = 1;
		SetCursor(3);
	}
}
// 4B8968: using guessed type int sbookflag;

//----- (0042CCE9) --------------------------------------------------------
void __fastcall AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	missile[mi]._miDelFlag = 1;
	UseMana(mienemy, 27);
	if ( mienemy == myplr )
	{
		if ( sbookflag )
			sbookflag = 0;
		if ( !invflag )
			invflag = 1;
		SetCursor(4);
	}
}
// 4B8968: using guessed type int sbookflag;

//----- (0042CD3A) --------------------------------------------------------
void __fastcall AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	missile[mi]._miDelFlag = 1;
	UseMana(mienemy, 28);
	if ( mienemy == myplr )
		SetCursor(5);
}

//----- (0042CD6D) --------------------------------------------------------
void __fastcall AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // eax
	int v11; // edx
	int v12; // ecx
	signed int v13; // ebx
	char *v14; // edi

	v9 = mi;
	v10 = sx - 8;
	v11 = sx + 8;
	missile[v9]._miVar1 = 8;
	missile[v9]._miVar2 = sy - 8;
	missile[v9]._miVar3 = sy + 8;
	missile[v9]._miVar4 = v10;
	missile[v9]._miVar5 = v11;
	missile[v9]._miVar6 = v10;
	if ( sy - 8 <= 0 )
		missile[v9]._miVar2 = 1;
	v12 = 111;
	if ( sy + 8 >= 112 )
		missile[v9]._miVar3 = 111;
	if ( v10 <= 0 )
		missile[v9]._miVar4 = 1;
	if ( v11 >= 112 )
		missile[v9]._miVar5 = 111;
	v13 = 0;
	v14 = &plr[id]._pLevel;
	if ( *v14 > 0 )
	{
		do
		{
			_LOBYTE(v12) = 67;
			missile[v9]._midam += random(v12, 6) + 1;
			++v13;
		}
		while ( v13 < *v14 );
	}
	missile[v9]._miDelFlag = 0;
	missile[v9]._mirange = 255;
}

//----- (0042CE32) --------------------------------------------------------
void __fastcall AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // ecx
	int v11; // eax
	int v12; // ecx
	int v13; // edi
	int v14; // eax

	v9 = mi;
	missile[mi]._miVar2 = 0;
	if ( dam > 0 )
		missile[v9]._miVar2 = 5 * dam;
	missile[v9]._misx = dx;
	missile[v9]._misy = dy;
	missile[v9]._mixoff = missile[midir]._mixoff;
	missile[v9]._miyoff = missile[midir]._miyoff;
	missile[v9]._mitxoff = missile[midir]._mitxoff;
	missile[v9]._mityoff = missile[midir]._mityoff;
	missile[v9]._mirange = missile[v9]._miVar2 + 20;
	missile[v9]._mlid = AddLight(sx, sy, 1);
	if ( (_BYTE)mienemy )
	{
		_LOBYTE(v10) = 77;
		missile[v9]._midam = (unsigned char)monster[id].mMinDamage
						   + random(
								 v10,
								 (unsigned char)monster[id].mMaxDamage - (unsigned char)monster[id].mMinDamage + 1);
	}
	else
	{
		_LOBYTE(v10) = 79;
		v11 = random(v10, plr[id]._pLevel);
		_LOBYTE(v12) = 79;
		v13 = v11;
		v14 = random(v12, 2);
		missile[v9]._midam = 8 * (v14 + v13) + 16 + ((8 * (v14 + v13) + 16) >> 1);
	}
}

//----- (0042CF35) --------------------------------------------------------
void __fastcall AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi
	int v10; // edx
	int v11; // ebx
	int v12; // ecx
	int v13; // eax

	v9 = sx;
	v10 = dx;
	v11 = mi;
	v12 = dy;
	if ( v9 == dx && sy == dy )
	{
		v10 = XDirAdd[midir] + dx;
		v12 = YDirAdd[midir] + dy;
	}
	GetMissileVel(v11, v9, sy, v10, v12, 32);
	if ( !(_BYTE)mienemy )
		UseMana(id, 20);
	v13 = v11;
	missile[v13]._miVar3 = 0;
	missile[v13]._miVar2 = sy;
	missile[v13]._miVar1 = v9;
	missile[v13]._mirange = 256;
}

//----- (0042CFAD) --------------------------------------------------------
void __fastcall AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam)
{
	int v9; // esi
	int v10; // eax
	int v11; // ecx
	int v12; // edx
	int v13; // eax
	int v14; // ecx
	int i; // [esp+Ch] [ebp-8h]
	int x; // [esp+10h] [ebp-4h]

	i = mi;
	v9 = mi;
	x = sx;
	_LOBYTE(mi) = 63;
	if ( (_BYTE)micaster )
	{
		v13 = random(mi, 15);
		missile[v9]._midam = 15;
		missile[v9]._mirnd = v13 + 1;
	}
	else
	{
		v10 = random(mi, 15);
		_LOBYTE(v11) = 68;
		v12 = plr[id]._pMagic;
		missile[v9]._mirnd = v10 + 1;
		missile[v9]._midam = random(v11, v12 >> 2) + 1;
	}
	v14 = dx;
	if ( x == dx && sy == dy )
	{
		v14 = XDirAdd[midir] + dx;
		dx += XDirAdd[midir];
		dy += YDirAdd[midir];
	}
	_LOBYTE(v14) = 63;
	missile[v9]._miAnimFrame = random(v14, 8) + 1;
	missile[v9]._mlid = AddLight(x, sy, 5);
	GetMissileVel(i, x, sy, dx, dy, 8);
	missile[v9]._miVar3 = 0;
	missile[v9]._miVar1 = 5;
	missile[v9]._miVar2 = midir;
	missile[v9]._mirange = 256;
}

//----- (0042D098) --------------------------------------------------------
void __fastcall AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, int micaster, int id, int dam)
{
	int v9; // esi
	int v10; // ecx
	int v11; // edi
	int v12; // eax
	int v13; // eax
	int v14; // esi
	int v15; // eax
	int v16; // ecx
	signed int v17; // [esp-4h] [ebp-14h]
	int i; // [esp+Ch] [ebp-4h]

	v9 = dy;
	i = mi;
	v10 = dx;
	v11 = sx;
	if ( sx == dx && sy == dy )
	{
		v10 = XDirAdd[midir] + dx;
		v9 = YDirAdd[midir] + dy;
		dx += XDirAdd[midir];
	}
	if ( id == -1 )
	{
		v17 = 16;
		goto LABEL_8;
	}
	v12 = 2 * missile[i]._mispllvl + 16;
	if ( v12 >= 63 )
	{
		v17 = 63;
LABEL_8:
		v12 = v17;
	}
	GetMissileVel(i, sx, sy, v10, v9, v12);
	v13 = GetDirection16(v11, sy, dx, v9);
	SetMissDir(i, v13);
	v14 = i;
	missile[v14]._mirange = 256;
	missile[v14]._miVar1 = v11;
	missile[v14]._miVar2 = sy;
	v15 = AddLight(v11, sy, 8);
	_LOBYTE(v16) = 69;
	missile[v14]._mlid = v15;
	missile[v14]._midam = random(v16, 10) + plr[id]._pLevel + 9;
}

//----- (0042D178) --------------------------------------------------------
void __fastcall AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // esi

	v9 = mi;
	UseMana(mienemy, 32);
	if ( mienemy == myplr )
		SetCursor(8);
	missile[v9]._miDelFlag = 1;
}

//----- (0042D1AF) --------------------------------------------------------
void __fastcall AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ecx
	int v10; // eax

	v9 = mi;
	missile[v9]._mixvel = 0;
	missile[v9]._miyvel = 0;
	missile[v9]._mix = dx;
	missile[v9]._misx = dx;
	v10 = misfiledata[36].mAnimLen[0];
	missile[v9]._miy = dy;
	missile[v9]._misy = dy;
	missile[v9]._mirange = v10;
}

//----- (0042D1F3) --------------------------------------------------------
void __fastcall AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	missile[mi]._miDelFlag = 1;
	UseMana(mienemy, 33);
	if ( mienemy == myplr )
		SetCursor(7);
}

//----- (0042D226) --------------------------------------------------------
void __fastcall AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // ebx
	int v10; // edi
	int v11; // esi
	int v12; // eax
	int v13; // eax
	int mia; // [esp+Ch] [ebp-8h]
	int x; // [esp+10h] [ebp-4h]

	v9 = dx;
	v10 = dy;
	x = sx;
	mia = mi;
	if ( sx == dx && sy == dy )
	{
		v9 = XDirAdd[midir] + dx;
		v10 = YDirAdd[midir] + dy;
	}
	v11 = mi;
	missile[mi]._midam = 0;
	GetMissileVel(mi, sx, sy, v9, v10, 16);
	v12 = GetDirection8(x, sy, v9, v10);
	SetMissDir(mia, v12);
	missile[v11]._miVar3 = 0;
	missile[v11]._mirange = 256;
	missile[v11]._miVar1 = x;
	missile[v11]._miVar2 = sy;
	missile[v11]._miVar4 = v9;
	missile[v11]._miVar5 = v10;
	missile[v11]._mlid = AddLight(x, sy, 8);
	if ( !(_BYTE)mienemy )
	{
		UseMana(id, 36);
		v13 = id;
		drawhpflag = 1;
		plr[v13]._pHPBase -= 384;
		plr[v13]._pHitPoints -= 384;
		if ( plr[id]._pHitPoints <= 0 )
			SyncPlrKill(id, 0);
	}
}

//----- (0042D311) --------------------------------------------------------
void __fastcall AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	int v9; // eax
	int v10; // edx

	v9 = mi;
	missile[v9]._miVar2 = 0;
	missile[v9]._mix = sx;
	missile[v9]._misx = sx;
	missile[v9]._mirange = 100;
	v10 = 100 - missile[mi]._miAnimLen;
	missile[v9]._miy = sy;
	missile[v9]._misy = sy;
	missile[v9]._miVar1 = v10;
	PutMissile(mi);
}

//----- (0042D35B) --------------------------------------------------------
void __fastcall AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, int mienemy, int id, int dam)
{
	signed int v9; // edi
	int *v10; // esi
	int v11; // eax
	int x1; // [esp+4h] [ebp-8h]
	int v13; // [esp+8h] [ebp-4h]

	v9 = 0;
	x1 = sx;
	v13 = mi;
	if ( gbMaxPlayers )
	{
		v10 = &plr[0]._py;
		do
		{
			if ( *((_BYTE *)v10 - 39) )
			{
				_LOBYTE(v11) = LineClear(x1, sy, *(v10 - 1), *v10);
				if ( v11 )
					AddMissile(0, 0, *(v10 - 1), *v10, 0, 66, mienemy, id, dam, 0);
				mi = v13;
			}
			++v9;
			v10 += 5430;
		}
		while ( v9 < (unsigned char)gbMaxPlayers );
	}
	missile[mi]._miDelFlag = 1;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0042D3DA) --------------------------------------------------------
int __fastcall AddMissile(int sx, int sy, int v1, int v2, int midir, int mitype, int micaster, int id, int v3, int spllvl)
{
	int v10; // esi
	int v11; // ecx
	int v12; // ecx
	int v13; // ebx
	int v14; // esi
	int v15; // esi
	int v16; // edi
	int v17; // ecx
	char v18; // al
	int v19; // edx
	int v20; // ecx
	int v21; // eax
	int sya; // [esp+8h] [ebp-8h]
	int sxa; // [esp+Ch] [ebp-4h]

	sya = sy;
	sxa = sx;
	if ( nummissiles >= 125 )
		return -1;
	if ( mitype != 13 || plr[id].pManaShield != 1 )
		goto LABEL_9;
	if ( currlevel != plr[id].plrlevel )
		return -1;
	v10 = 0;
	if ( nummissiles > 0 )
	{
		do
		{
			v11 = missileactive[v10];
			if ( missile[v11]._mitype == 13 && missile[v11]._misource == id )
				return -1;
		}
		while ( ++v10 < nummissiles );
	}
LABEL_9:
	v12 = nummissiles;
	v13 = missileavail[0];
	v14 = missileavail[-nummissiles++ + 124];
	missileavail[0] = v14;
	v15 = v13;
	missile[v15]._mitype = mitype;
	v16 = mitype;
	missileactive[v12] = v13;
	v17 = missiledata[mitype].mDraw;
	missile[v15]._micaster = (char)micaster;
	v18 = missiledata[mitype].mFileNum;
	missile[v15]._misource = id;
	v19 = midir;
	missile[v15]._miDrawFlag = v17;
	_LOBYTE(missile[v15]._miAnimType) = v18;
	missile[v15]._mispllvl = spllvl;
	missile[v15]._mimfnum = midir;
	if ( v18 == -1 || misfiledata[(unsigned char)v18].mAnimFAmt < 8u )
		v19 = 0;
	SetMissDir(v13, v19);
	v20 = sya;
	missile[v15]._mlid = -1;
	missile[v15]._mixoff = 0;
	missile[v15]._miyoff = 0;
	missile[v15]._mitxoff = 0;
	missile[v15]._mityoff = 0;
	missile[v15]._miDelFlag = 0;
	missile[v15]._miLightFlag = 0;
	missile[v15]._miPreFlag = 0;
	missile[v15]._miUniqTrans = 0;
	missile[v15]._miHitFlag = 0;
	missile[v15]._midist = 0;
	missile[v15]._mirnd = 0;
	v21 = missiledata[v16].mlSFX;
	missile[v15]._mix = sxa;
	missile[v15]._misx = sxa;
	missile[v15]._miy = sya;
	missile[v15]._misy = sya;
	missile[v15]._miAnimAdd = 1;
	missile[v15]._midam = v3;
	if ( v21 != -1 )
	{
		PlaySfxLoc(v21, sxa, sya);
		v20 = sya;
	}
	missiledata[v16].mAddProc(v13, sxa, v20, v1, v2, midir, micaster, id, v3);
	return v13;
}

//----- (0042D5A3) --------------------------------------------------------
int __fastcall Sentfire(int i, int sx, int sy)
{
	int v3; // esi
	int v4; // ebx
	int v5; // edi
	int v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // edi
	int midir; // ST30_4
	int v11; // ecx
	int v12; // eax
	int v13; // edx
	int mi; // [esp+Ch] [ebp-8h]

	mi = i;
	v3 = i;
	v4 = sx;
	v5 = 0;
	_LOBYTE(v6) = LineClear(missile[i]._mix, missile[i]._miy, sx, sy);
	if ( v6 )
	{
		v7 = dMonster[0][sy + 112 * v4];
		if ( v7 > 0 && (signed int)(monstactive[57 * v7 + 182] & 0xFFFFFFC0) > 0 && v7 - 1 > 3 )
		{
			v8 = GetDirection(missile[v3]._mix, missile[v3]._miy, v4, sy);
			v9 = missile[v3]._misource;
			midir = v8;
			v11 = missile[v3]._misource;
			missile[v3]._miVar3 = missileavail[0];
			v12 = GetSpellLevel(v11, 1);
			AddMissile(missile[v3]._mix, missile[v3]._miy, v4, sy, midir, v13, 0, v9, missile[v3]._midam, v12);
			v5 = -1;
			SetMissDir(mi, 2);
			missile[v3]._miVar2 = 3;
		}
	}
	return v5;
}

void __fastcall MI_Dummy(int i)
{
	return;
}

//----- (0042D680) --------------------------------------------------------
void __fastcall MI_Golem(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // eax
	bool v4; // zf
	int v5; // eax
	int v6; // ecx
	unsigned char *v7; // eax
	int v8; // ebx
	int v9; // edi
	int v10; // edx
	int v11; // ecx
	int v12; // eax
	int v13; // [esp+4h] [ebp-38h]
	int v14; // [esp+8h] [ebp-34h]
	int v15; // [esp+Ch] [ebp-30h]
	int v16; // [esp+10h] [ebp-2Ch]
	int v17; // [esp+14h] [ebp-28h]
	int v18; // [esp+18h] [ebp-24h]
	char arglist[4]; // [esp+1Ch] [ebp-20h]
	int mi; // [esp+20h] [ebp-1Ch]
	unsigned int v21; // [esp+24h] [ebp-18h]
	int v22; // [esp+28h] [ebp-14h]
	int v23; // [esp+2Ch] [ebp-10h]
	unsigned char *v24; // [esp+30h] [ebp-Ch]
	int v25; // [esp+34h] [ebp-8h]
	int v26; // [esp+38h] [ebp-4h]

	mi = i;
	v1 = i;
	v2 = missile[i]._misource;
	*(_DWORD *)arglist = v2;
	v3 = v2;
	v4 = monster[v3]._mx == 1;
	v13 = 0;
	v14 = 3;
	v15 = 12;
	v16 = 45;
	v17 = 94;
	v18 = 159;
	if ( !v4 || monster[v3]._my )
		goto LABEL_17;
	v26 = 0;
	do
	{
		v5 = *(&v13 + v26);
		v6 = *(&CrawlTable.n_1 + v5);
		v25 = *(&CrawlTable.n_1 + v5);
		if ( v6 <= 0 )
			goto LABEL_16;
		v7 = &CrawlTable.delta_1[0].y + v5;
		v24 = v7;
		while ( 1 )
		{
			v8 = missile[v1]._miVar4 + (char)*(v7 - 1);
			v9 = missile[v1]._miVar5 + (char)*v7;
			if ( v8 <= 0 || v8 >= 112 || v9 <= 0 || v9 >= 112 )
				goto LABEL_13;
			v10 = missile[v1]._miVar2;
			v11 = missile[v1]._miVar1;
			v23 = v9 + 112 * v8;
			v21 = 4 * v23;
			v22 = dPiece[0][v23];
			_LOBYTE(v12) = LineClear(v11, v10, v8, v9);
			if ( v12 )
			{
				if ( !(dMonster[0][v21 / 4] | (unsigned char)nSolidTable[v22] | dObject[0][v23]) )
					break;
			}
			v7 = v24;
LABEL_13:
			v7 += 2;
			--v25;
			v24 = v7;
			if ( v25 <= 0 )
				goto LABEL_16;
		}
		v26 = 6;
		SpawnGolum(*(int *)arglist, v8, v9, mi);
LABEL_16:
		++v26;
	}
	while ( v26 < 6 );
LABEL_17:
	missile[v1]._miDelFlag = 1;
}

//----- (0042D7C7) --------------------------------------------------------
void __fastcall MI_SetManashield(int i)
{
	ManashieldFlag = 1;
}

//----- (0042D7D2) --------------------------------------------------------
void __fastcall MI_LArrow(int i)
{
	int v1; // esi
	char v2; // al
	int v3; // ebx
	int v4; // eax
	int v5; // ecx
	int v6; // edi
	int v7; // ecx
	int v8; // eax
	int v9; // ecx
	int v10; // edx
	int v11; // ST0C_4
	unsigned char *v12; // eax
	unsigned char v13; // bl
	int v14; // eax
	int v15; // edx
	int v16; // ecx
	int v17; // ST10_4
	int v18; // ecx
	int v19; // edi
	int v20; // eax
	int v21; // eax
	int v22; // ecx
	int v23; // ST0C_4
	int v24; // edi
	int v25; // eax
	int v26; // eax
	int v27; // ecx
	int v28; // ST10_4
	int v29; // ecx
	bool v30; // [esp-8h] [ebp-1Ch]
	bool v31; // [esp-4h] [ebp-18h]
	unsigned char v32; // [esp+Ch] [ebp-8h]
	int ia; // [esp+10h] [ebp-4h]

	v1 = i;
	ia = i;
	v2 = missile[i]._miAnimType;
	--missile[v1]._mirange;
	v3 = missile[i]._misource;
	if ( v2 == 26 || v2 == 5 )
	{
		ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, missile[v1]._miAnimFrame + 5);
		v18 = missiledata[missile[v1]._mitype].mResist;
		v32 = missiledata[missile[v1]._mitype].mResist;
		if ( missile[v1]._mitype == 56 )
		{
			if ( v3 == -1 )
			{
				_LOBYTE(v18) = 68;
				v21 = random(v18, 10);
				v22 = currlevel;
				v19 = v21 + currlevel + 1;
				_LOBYTE(v22) = 68;
				v20 = random(v22, 10) + 2 * currlevel + 1;
			}
			else
			{
				v19 = plr[v3]._pILMinDam;
				v20 = plr[v3]._pILMaxDam;
			}
			v23 = missile[v1]._miy;
			missiledata[56].mResist = 2;
			CheckMissileCol(ia, v19, v20, 0, missile[v1]._mix, v23, 1, v30);
		}
		if ( missile[v1]._mitype == 27 )
		{
			if ( v3 == -1 )
			{
				_LOBYTE(v18) = 68;
				v26 = random(v18, 10);
				v27 = currlevel;
				v24 = v26 + currlevel + 1;
				_LOBYTE(v27) = 68;
				v25 = random(v27, 10) + 2 * currlevel + 1;
			}
			else
			{
				v24 = plr[v3]._pIFMinDam;
				v25 = plr[v3]._pIFMaxDam;
			}
			v28 = missile[v1]._miy;
			missiledata[27].mResist = 1;
			CheckMissileCol(ia, v24, v25, 0, missile[v1]._mix, v28, 1, v31);
		}
		missiledata[missile[v1]._mitype].mResist = v32;
	}
	else
	{
		v4 = missile[v1]._mixvel;
		++missile[v1]._midist;
		missile[v1]._mitxoff += v4;
		missile[v1]._mityoff += missile[v1]._miyvel;
		GetMissilePos(i);
		if ( v3 == -1 )
		{
			_LOBYTE(v5) = 68;
			v8 = random(v5, 10);
			v9 = currlevel;
			v6 = v8 + currlevel + 1;
			_LOBYTE(v9) = 68;
			v7 = random(v9, 10) + 2 * currlevel + 1;
		}
		else if ( missile[v1]._micaster )
		{
			v6 = (unsigned char)monster[v3].mMinDamage;
			v7 = (unsigned char)monster[v3].mMaxDamage;
		}
		else
		{
			v6 = plr[v3]._pIMinDam;
			v7 = plr[v3]._pIMaxDam;
		}
		v10 = missile[v1]._mix;
		if ( v10 != missile[v1]._misx || missile[v1]._miy != missile[v1]._misy )
		{
			v11 = missile[v1]._miy;
			v12 = &missiledata[missile[v1]._mitype].mResist;
			v13 = *v12;
			*v12 = 0;
			CheckMissileCol(ia, v6, v7, 0, v10, v11, 0, v30);
			missiledata[missile[v1]._mitype].mResist = v13;
		}
		if ( missile[v1]._mirange )
		{
			v15 = missile[v1]._mix;
			if ( v15 != missile[v1]._miVar1 || missile[v1]._miy != missile[v1]._miVar2 )
			{
				v16 = missile[v1]._mlid;
				missile[v1]._miVar1 = v15;
				v17 = missile[v1]._miy;
				missile[v1]._miVar2 = v17;
				ChangeLight(v16, v15, v17, 5);
			}
		}
		else
		{
			missile[v1]._mitxoff -= missile[v1]._mixvel;
			v14 = missile[v1]._miyvel;
			missile[v1]._mimfnum = 0;
			missile[v1]._mityoff -= v14;
			GetMissilePos(ia);
			if ( missile[v1]._mitype == 56 )
				SetMissAnim(ia, 26);
			else
				SetMissAnim(ia, MFILE_MAGBLOS);
			missile[v1]._mirange = missile[v1]._miAnimLen - 1;
		}
	}
	if ( !missile[v1]._mirange )
	{
		v29 = missile[v1]._mlid;
		missile[v1]._miDelFlag = 1;
		AddUnLight(v29);
	}
	PutMissile(ia);
}

//----- (0042DAD0) --------------------------------------------------------
void __fastcall MI_Arrow(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // edx
	int v7; // eax
	int v8; // eax
	int v9; // ecx
	bool v10; // [esp-4h] [ebp-Ch]
	int ia; // [esp+4h] [ebp-4h]

	v1 = i;
	ia = i;
	v2 = missile[i]._mixvel;
	--missile[v1]._mirange;
	missile[v1]._mitxoff += v2;
	v3 = missile[i]._miyvel;
	++missile[v1]._midist;
	missile[v1]._mityoff += v3;
	GetMissilePos(i);
	v4 = missile[v1]._misource;
	if ( v4 == -1 )
	{
		v6 = currlevel;
		v7 = 2 * currlevel;
	}
	else if ( missile[v1]._micaster )
	{
		v8 = v4;
		v6 = (unsigned char)monster[v8].mMinDamage;
		v7 = (unsigned char)monster[v8].mMaxDamage;
	}
	else
	{
		v5 = v4;
		v6 = plr[v5]._pIMinDam;
		v7 = plr[v5]._pIMaxDam;
	}
	v9 = missile[v1]._mix;
	if ( v9 != missile[v1]._misx || missile[v1]._miy != missile[v1]._misy )
		CheckMissileCol(ia, v6, v7, 0, v9, missile[v1]._miy, 0, v10);
	if ( !missile[v1]._mirange )
		missile[v1]._miDelFlag = 1;
	PutMissile(ia);
}

//----- (0042DBA1) --------------------------------------------------------
void __fastcall MI_Firebolt(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // ecx
	int v4; // ST1C_4
	int v5; // edx
	int v6; // ecx
	int v7; // eax
	int v8; // ecx
	int v9; // edi
	int v10; // eax
	int v11; // edi
	int v12; // eax
	int v13; // ecx
	int v14; // ecx
	int v15; // eax
	int v16; // esi
	int v17; // edx
	int v18; // eax
	int v19; // esi
	bool v20; // [esp+0h] [ebp-18h]
	int v21; // [esp+Ch] [ebp-Ch]
	int v22; // [esp+10h] [ebp-8h]
	int ia; // [esp+14h] [ebp-4h]

	v1 = i;
	ia = i;
	v2 = i;
	--missile[v2]._mirange;
	if ( missile[i]._mitype == 63 && missile[v2]._mimfnum == 8 )
	{
		if ( !missile[i]._mirange )
		{
			v3 = missile[v2]._mlid;
			if ( v3 >= 0 )
				AddUnLight(v3);
			v4 = missile[v2]._miy;
			v5 = missile[v2]._mix;
			missile[v2]._miDelFlag = 1;
			PlaySfxLoc(LS_BSIMPCT, v5, v4);
		}
		goto LABEL_39;
	}
	v6 = missile[v2]._mityoff;
	v22 = missile[v2]._mitxoff;
	v21 = v6;
	v7 = v6 + missile[v2]._miyvel;
	missile[v2]._mitxoff = v22 + missile[v2]._mixvel;
	missile[v2]._mityoff = v7;
	GetMissilePos(v1);
	v9 = missile[v2]._misource;
	if ( v9 == -1 )
	{
		_LOBYTE(v8) = 78;
		v12 = random(v8, 2 * currlevel);
		v13 = currlevel;
		goto LABEL_17;
	}
	if ( missile[v2]._micaster )
	{
		v11 = v9;
		_LOBYTE(v8) = 77;
		v12 = random(v8, (unsigned char)monster[v11].mMaxDamage - (unsigned char)monster[v11].mMinDamage + 1);
		v13 = (unsigned char)monster[v11].mMinDamage;
LABEL_17:
		v10 = v13 + v12;
		goto LABEL_19;
	}
	switch ( missile[v2]._mitype )
	{
		case 1:
			_LOBYTE(v8) = 75;
			v10 = (plr[v9]._pMagic >> 3) + random(v8, 10) + missile[v2]._mispllvl + 1;
			break;
		case 0x18:
			v10 = (plr[v9]._pMagic >> 1) + 3 * missile[v2]._mispllvl - (plr[v9]._pMagic >> 3);
			break;
		case 0x3F:
			v10 = 0;
			break;
		default:
			v10 = v21;
			break;
	}
LABEL_19:
	v14 = missile[v2]._mix;
	if ( v14 == missile[v2]._misx && missile[v2]._miy == missile[v2]._misy )
	{
		v1 = ia;
	}
	else
	{
		v1 = ia;
		CheckMissileCol(ia, v10, v10, 0, v14, missile[v2]._miy, 0, v20);
	}
	if ( missile[v2]._mirange )
	{
		v17 = missile[v2]._mix;
		if ( v17 != missile[v2]._miVar1 || missile[v2]._miy != missile[v2]._miVar2 )
		{
			missile[v2]._miVar1 = v17;
			v18 = missile[v2]._miy;
			missile[v2]._miVar2 = v18;
			v19 = missile[v2]._mlid;
			if ( v19 >= 0 )
				ChangeLight(v19, v17, v18, 8);
		}
	}
	else
	{
		missile[v2]._mitxoff = v22;
		missile[v2]._miDelFlag = 1;
		missile[v2]._mityoff = v21;
		GetMissilePos(v1);
		v15 = missile[v2]._mitype - 1;
		if ( missile[v2]._mitype == 1 || (v15 = missile[v2]._mitype - 21, missile[v2]._mitype == 21) )
		{
			_LOBYTE(v15) = missile[v2]._micaster;
			AddMissile(
				missile[v2]._mix,
				missile[v2]._miy,
				v1,
				0,
				missile[v2]._mimfnum,
				9,
				v15,
				missile[v2]._misource,
				0,
				0);
		}
		else
		{
			switch ( missile[v2]._mitype )
			{
				case 0x18:
					AddMissile(
						missile[v2]._mix,
						missile[v2]._miy,
						v1,
						0,
						missile[v2]._mimfnum,
						25,
						_LOBYTE(missile[v2]._micaster),
						missile[v2]._misource,
						0,
						0);
					break;
				case 0x39:
					AddMissile(
						missile[v2]._mix,
						missile[v2]._miy,
						v1,
						0,
						missile[v2]._mimfnum,
						58,
						_LOBYTE(missile[v2]._micaster),
						missile[v2]._misource,
						0,
						0);
					break;
				case 0x3F:
					SetMissDir(v1, 8);
					missile[v2]._mirange = 7;
					missile[v2]._miDelFlag = 0;
					goto LABEL_39;
			}
		}
		v16 = missile[v2]._mlid;
		if ( v16 >= 0 )
			AddUnLight(v16);
	}
LABEL_39:
	PutMissile(v1);
}

//----- (0042DE5A) --------------------------------------------------------
void __fastcall MI_Lightball(int i)
{
	int v1; // esi
	int v2; // ebx
	int v3; // eax
	int v4; // edi
	char v5; // al
	int v6; // eax
	int v7; // eax
	bool v8; // [esp-4h] [ebp-18h]
	int ia; // [esp+Ch] [ebp-8h]
	int v10; // [esp+10h] [ebp-4h]

	v1 = i;
	ia = i;
	v2 = missile[i]._miVar1;
	missile[v1]._mitxoff += missile[i]._mixvel;
	v3 = missile[i]._miyvel;
	v4 = missile[i]._miVar2;
	--missile[v1]._mirange;
	missile[v1]._mityoff += v3;
	GetMissilePos(i);
	v10 = missile[v1]._mirange;
	CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 0, missile[v1]._mix, missile[v1]._miy, 0, v8);
	if ( missile[v1]._miHitFlag == 1 )
		missile[v1]._mirange = v10;
	v5 = dObject[v2][v4];
	if ( v5 && v2 == missile[v1]._mix && v4 == missile[v1]._miy )
	{
		v6 = v5 <= 0 ? -1 - v5 : v5 - 1;
		v7 = object[v6]._otype;
		if ( v7 == OBJ_SHRINEL || v7 == OBJ_SHRINER )
			missile[v1]._mirange = v10;
	}
	if ( !missile[v1]._mirange )
		missile[v1]._miDelFlag = 1;
	PutMissile(ia);
}

//----- (0042DF42) --------------------------------------------------------
void __fastcall mi_null_33(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	bool v4; // [esp-4h] [ebp-Ch]

	v1 = i;
	v2 = i;
	v3 = missile[i]._mixvel;
	--missile[v2]._mirange;
	missile[v2]._mitxoff += v3;
	missile[v2]._mityoff += missile[i]._miyvel;
	GetMissilePos(i);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 0, missile[v2]._mix, missile[v2]._miy, 0, v4);
	if ( !missile[v2]._mirange )
		missile[v2]._miDelFlag = 1;
	PutMissile(v1);
}

//----- (0042DFAB) --------------------------------------------------------
void __fastcall MI_Acidpud(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // ST0C_4
	int v4; // edx
	int v5; // edi
	bool v6; // [esp-4h] [ebp-10h]

	v1 = i;
	v2 = i;
	v3 = missile[i]._miy;
	v4 = missile[i]._midam;
	--missile[v2]._mirange;
	v5 = missile[i]._mirange;
	CheckMissileCol(i, v4, v4, 1u, missile[i]._mix, v3, 0, v6);
	missile[v2]._mirange = v5;
	if ( !v5 )
	{
		if ( missile[v2]._mimfnum )
		{
			missile[v2]._miDelFlag = 1;
		}
		else
		{
			SetMissDir(v1, 1);
			missile[v2]._mirange = missile[v2]._miAnimLen;
		}
	}
	PutMissile(v1);
}

//----- (0042E01E) --------------------------------------------------------
void __fastcall MI_Firewall(int i)
{
	int v1; // esi
	int v2; // ecx
	int v3; // ecx
	int v4; // eax
	bool v5; // [esp-4h] [ebp-48h]
	int r; // [esp+8h] [ebp-3Ch]
	int v7; // [esp+Ch] [ebp-38h]
	int v8; // [esp+10h] [ebp-34h]
	int v9; // [esp+14h] [ebp-30h]
	int v10; // [esp+18h] [ebp-2Ch]
	int v11; // [esp+1Ch] [ebp-28h]
	int v12; // [esp+20h] [ebp-24h]
	int v13; // [esp+24h] [ebp-20h]
	int v14; // [esp+28h] [ebp-1Ch]
	int v15; // [esp+2Ch] [ebp-18h]
	int v16; // [esp+30h] [ebp-14h]
	int v17; // [esp+34h] [ebp-10h]
	int v18; // [esp+38h] [ebp-Ch]
	int v19; // [esp+3Ch] [ebp-8h]
	int ia; // [esp+40h] [ebp-4h]

	v1 = i;
	v9 = 5;
	v10 = 5;
	v17 = 12;
	v18 = 12;
	--missile[v1]._mirange;
	r = 2;
	v7 = 3;
	v8 = 4;
	v11 = 6;
	v12 = 7;
	v13 = 8;
	v14 = 9;
	v15 = 10;
	v16 = 11;
	ia = i;
	v19 = 0;
	if ( missile[i]._mirange == missile[i]._miVar1 )
	{
		SetMissDir(i, 1);
		_LOBYTE(v2) = 83;
		missile[v1]._miAnimFrame = random(v2, 11) + 1;
	}
	if ( missile[v1]._mirange == missile[v1]._miAnimLen - 1 )
	{
		SetMissDir(ia, 0);
		missile[v1]._miAnimAdd = -1;
		missile[v1]._miAnimFrame = 13;
	}
	CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 1u, missile[v1]._mix, missile[v1]._miy, 1, v5);
	if ( !missile[v1]._mirange )
	{
		v3 = missile[v1]._mlid;
		missile[v1]._miDelFlag = 1;
		AddUnLight(v3);
	}
	if ( missile[v1]._mimfnum )
	{
		if ( missile[v1]._mirange )
		{
			if ( missile[v1]._miAnimAdd != -1 )
			{
				v4 = missile[v1]._miVar2;
				if ( v4 < 12 )
				{
					if ( !v4 )
						missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, r);
					ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2));
					++missile[v1]._miVar2;
				}
			}
		}
	}
	PutMissile(ia);
}

//----- (0042E18F) --------------------------------------------------------
void __fastcall MI_Fireball(int i)
{
	int v1; // esi
	bool v2; // zf
	int v3; // eax
	int v4; // ecx
	int v5; // edi
	int v6; // eax
	int v7; // edx
	int v8; // eax
	int v9; // eax
	int v10; // ecx
	int v11; // eax
	int v12; // edx
	int v13; // eax
	int v14; // ecx
	int v15; // ST10_4
	bool v16; // [esp-4h] [ebp-24h]
	bool v17; // [esp+0h] [ebp-20h]
	bool v18; // [esp+4h] [ebp-1Ch]
	bool v19; // [esp+8h] [ebp-18h]
	int fx; // [esp+Ch] [ebp-14h]
	int fxa; // [esp+Ch] [ebp-14h]
	int fxb; // [esp+Ch] [ebp-14h]
	int fy; // [esp+10h] [ebp-10h]
	int fya; // [esp+10h] [ebp-10h]
	int fyb; // [esp+10h] [ebp-10h]
	int ia; // [esp+14h] [ebp-Ch]
	int ib; // [esp+14h] [ebp-Ch]
	int ty; // [esp+18h] [ebp-8h]
	int tya; // [esp+18h] [ebp-8h]
	int tyb; // [esp+18h] [ebp-8h]
	int tx; // [esp+1Ch] [ebp-4h]
	int txa; // [esp+1Ch] [ebp-4h]
	bool savedregs; // [esp+20h] [ebp+0h]

	ia = i;
	v1 = i;
	--missile[v1]._mirange;
	v2 = missile[i]._micaster == 0;
	v3 = missile[i]._misource;
	v4 = missile[i]._mirange;
	v5 = missile[v1]._midam;
	if ( v2 )
	{
		v6 = v3;
		v7 = plr[v6].WorldX;
		v8 = plr[v6].WorldY;
	}
	else
	{
		v9 = v3;
		v7 = monster[v9]._mx;
		v8 = monster[v9]._my;
	}
	fx = v7;
	fy = v8;
	if ( _LOBYTE(missile[v1]._miAnimType) == 19 )
	{
		if ( !v4 )
		{
			v10 = missile[v1]._mlid;
			missile[v1]._miDelFlag = 1;
			AddUnLight(v10);
		}
	}
	else
	{
		missile[v1]._mitxoff += missile[v1]._mixvel;
		missile[v1]._mityoff += missile[v1]._miyvel;
		GetMissilePos(ia);
		v11 = missile[v1]._mix;
		if ( v11 != missile[v1]._misx || missile[v1]._miy != missile[v1]._misy )
			CheckMissileCol(ia, v5, v5, 0, v11, missile[v1]._miy, 0, v16);
		v12 = missile[v1]._mix;
		if ( missile[v1]._mirange )
		{
			if ( v12 != missile[v1]._miVar1 || missile[v1]._miy != missile[v1]._miVar2 )
			{
				v14 = missile[v1]._mlid;
				missile[v1]._miVar1 = v12;
				v15 = missile[v1]._miy;
				missile[v1]._miVar2 = v15;
				ChangeLight(v14, v12, v15, 8);
			}
		}
		else
		{
			tx = missile[v1]._mix;
			ty = missile[v1]._miy;
			ChangeLight(missile[v1]._mlid, v12, ty, missile[v1]._miAnimFrame);
			if ( !CheckBlock(fx, fy, tx, ty) )
				CheckMissileCol(ia, v5, v5, 0, tx, ty, 1, v17);
			if ( !CheckBlock(fx, fy, tx, ty + 1) )
				CheckMissileCol(ia, v5, v5, 0, tx, ty + 1, 1, v18);
			if ( !CheckBlock(fx, fy, tx, ty - 1) )
				CheckMissileCol(ia, v5, v5, 0, tx, ty - 1, 1, v19);
			if ( !CheckBlock(fx, fy, tx + 1, ty) )
				CheckMissileCol(ia, v5, v5, 0, tx + 1, ty, 1, fx);
			if ( !CheckBlock(fx, fy, tx + 1, ty - 1) )
				CheckMissileCol(ia, v5, v5, 0, tx + 1, ty - 1, 1, fy);
			if ( !CheckBlock(fxa, fy, tx + 1, ty + 1) )
				CheckMissileCol(ia, v5, v5, 0, tx + 1, ty + 1, 1, ia);
			if ( !CheckBlock(fxb, fya, tx - 1, ty) )
				CheckMissileCol(ib, v5, v5, 0, tx - 1, ty, 1, ty);
			if ( !CheckBlock(fxb, fyb, tx - 1, ty + 1) )
				CheckMissileCol(ia, v5, v5, 0, tx - 1, tya + 1, 1, tx);
			if ( !CheckBlock(fxb, fyb, tya - 2, tya - 1) )
				CheckMissileCol(ia, v5, v5, 0, 0, tyb - 1, 1, savedregs);
			v13 = 112 * txa + tyb;
			if ( !TransList[dung_map[0][v13]]
			  || missile[v1]._mixvel < 0
			  && (TransList[dung_map[0][v13 + 1]] && nSolidTable[dPiece[0][v13 + 1]]
			   || TransList[*(&byte_5B78EB + v13)] && nSolidTable[*(_DWORD *)&dflags[39][4 * v13 + 36]]) )
			{
				++missile[v1]._mix;
				++missile[v1]._miy;
				missile[v1]._miyoff -= 32;
			}
			if ( missile[v1]._miyvel > 0
			  && (TransList[dung_map[txa + 1][tyb]] && nSolidTable[dPiece[1][v13]]
			   || TransList[block_lvid[v13 + 1940]] && nSolidTable[*(_DWORD *)&dflags[28][4 * v13 + 32]]) )
			{
				missile[v1]._miyoff -= 32;
			}
			if ( missile[v1]._mixvel > 0
			  && (TransList[dung_map[0][v13 + 1]] && nSolidTable[dPiece[0][v13 + 1]]
			   || TransList[*(&byte_5B78EB + v13)] && nSolidTable[*(_DWORD *)&dflags[39][4 * v13 + 36]]) )
			{
				missile[v1]._mixoff -= 32;
			}
			missile[v1]._mimfnum = 0;
			SetMissAnim(ia, MFILE_BIGEXP);
			missile[v1]._mirange = missile[v1]._miAnimLen - 1;
		}
	}
	PutMissile(ia);
}

//----- (0042E5A7) --------------------------------------------------------
void __fastcall MI_Lightctrl(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // eax
	int v4; // ecx
	int v5; // edi
	signed int v6; // ebx
	signed int v7; // edx
	int v8; // ecx
	int v9; // eax
	int v10; // [esp-10h] [ebp-24h]
	int v11; // [esp-Ch] [ebp-20h]
	int v12; // [esp-8h] [ebp-1Ch]
	int v13; // [esp+Ch] [ebp-8h]
	int ia; // [esp+10h] [ebp-4h]

	ia = i;
	v1 = i;
	v2 = missile[i]._misource;
	--missile[v1]._mirange;
	if ( v2 == -1 )
	{
		_LOBYTE(i) = 81;
		v5 = random(i, currlevel) + 2 * currlevel;
	}
	else if ( missile[v1]._micaster )
	{
		_LOBYTE(i) = 80;
		v5 = 2
		   * ((unsigned char)monster[v2].mMinDamage
			+ random(i, (unsigned char)monster[v2].mMaxDamage - (unsigned char)monster[v2].mMinDamage + 1));
	}
	else
	{
		_LOBYTE(i) = 79;
		v3 = random(i, plr[v2]._pLevel);
		_LOBYTE(v4) = 79;
		v5 = (v3 + random(v4, 2) + 2) << 6;
	}
	missile[v1]._mitxoff += missile[v1]._mixvel;
	missile[v1]._mityoff += missile[v1]._miyvel;
	GetMissilePos(ia);
	v6 = missile[v1]._mix;
	v7 = missile[v1]._miy;
	v8 = missile[v1]._misource;
	v13 = missile[v1]._miy;
	v9 = dPiece[0][v7 + 112 * missile[v1]._mix];
	if ( v8 != -1 || v6 != missile[v1]._misx || v7 != missile[v1]._misy )
	{
		if ( !nMissileTable[v9] )
			goto LABEL_12;
		missile[v1]._mirange = 0;
	}
	if ( !nMissileTable[v9] )
	{
LABEL_12:
		if ( v6 == missile[v1]._miVar1 && v7 == missile[v1]._miVar2 || v6 <= 0 || v7 <= 0 || v6 >= 112 || v7 >= 112 )
			goto LABEL_27;
		if ( v8 == -1 )
		{
			v12 = missile[v1]._mispllvl;
			v11 = v5;
			v10 = -1;
		}
		else
		{
			if ( missile[v1]._micaster == 1 )
			{
				v9 = (int)monster[v8].MType;
				_LOBYTE(v9) = *(_BYTE *)v9;
				if ( (unsigned char)v9 >= MON_THINA && (unsigned char)v9 <= MON_THIND )
				{
					_LOBYTE(v9) = missile[v1]._micaster;
					AddMissile(v6, v7, missile[v1]._misx, missile[v1]._misy, ia, 23, v9, v8, v5, missile[v1]._mispllvl);
LABEL_26:
					v7 = v13;
					missile[v1]._miVar1 = missile[v1]._mix;
					missile[v1]._miVar2 = missile[v1]._miy;
					goto LABEL_27;
				}
			}
			v12 = missile[v1]._mispllvl;
			v11 = v5;
			v10 = v8;
		}
		_LOBYTE(v9) = missile[v1]._micaster;
		AddMissile(v6, v7, missile[v1]._misx, missile[v1]._misy, ia, 8, v9, v10, v11, v12);
		goto LABEL_26;
	}
LABEL_27:
	if ( !missile[v1]._mirange || v6 <= 0 || v7 <= 0 || v6 >= 112 || v7 > 112 )
		missile[v1]._miDelFlag = 1;
}

//----- (0042E79B) --------------------------------------------------------
void __fastcall MI_Lightning(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // ebx
	int v5; // ecx
	bool v6; // [esp-4h] [ebp-10h]

	v1 = i;
	v2 = i;
	v3 = missile[i]._mix;
	--missile[v2]._mirange;
	v4 = missile[i]._mirange;
	if ( v3 != missile[i]._misx || missile[v2]._miy != missile[v2]._misy )
		CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 1u, v3, missile[v2]._miy, 0, v6);
	if ( missile[v2]._miHitFlag == 1 )
		missile[v2]._mirange = v4;
	if ( !missile[v2]._mirange )
	{
		v5 = missile[v2]._mlid;
		missile[v2]._miDelFlag = 1;
		AddUnLight(v5);
	}
	PutMissile(v1);
}

//----- (0042E820) --------------------------------------------------------
void __fastcall MI_Town(int i)
{
	int v1; // esi
	int v2; // eax
	int *v3; // edi
	int v4; // ecx
	int r; // [esp+8h] [ebp-4Ch]
	int v6; // [esp+Ch] [ebp-48h]
	int v7; // [esp+10h] [ebp-44h]
	int v8; // [esp+14h] [ebp-40h]
	int v9; // [esp+18h] [ebp-3Ch]
	int v10; // [esp+1Ch] [ebp-38h]
	int v11; // [esp+20h] [ebp-34h]
	int v12; // [esp+24h] [ebp-30h]
	int v13; // [esp+28h] [ebp-2Ch]
	int v14; // [esp+2Ch] [ebp-28h]
	int v15; // [esp+30h] [ebp-24h]
	int v16; // [esp+34h] [ebp-20h]
	int v17; // [esp+38h] [ebp-1Ch]
	int v18; // [esp+3Ch] [ebp-18h]
	int v19; // [esp+40h] [ebp-14h]
	int v20; // [esp+44h] [ebp-10h]
	int v21; // [esp+48h] [ebp-Ch]
	int ia; // [esp+4Ch] [ebp-8h]
	char arglist[4]; // [esp+50h] [ebp-4h]

	v1 = i;
	v19 = 15;
	v20 = 15;
	v21 = 15;
	v2 = missile[i]._mirange;
	ia = i;
	r = 1;
	v6 = 2;
	v7 = 3;
	v8 = 4;
	v9 = 5;
	v10 = 6;
	v11 = 7;
	v12 = 8;
	v13 = 9;
	v14 = 10;
	v15 = 11;
	v16 = 12;
	v17 = 13;
	v18 = 14;
	if ( v2 > 1 )
		missile[v1]._mirange = v2 - 1;
	if ( missile[v1]._mirange == missile[v1]._miVar1 )
		SetMissDir(i, 1);
	if ( currlevel && missile[v1]._mimfnum != 1 && missile[v1]._mirange )
	{
		if ( !missile[v1]._miVar2 )
			missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, 1);
		ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2));
		++missile[v1]._miVar2;
	}
	*(_DWORD *)arglist = 0;
	v3 = &plr[0].plrlevel;
	do
	{
		if ( *((_BYTE *)v3 - 23) )
		{
			if ( currlevel == *v3
			  && !*((_BYTE *)v3 + 267)
			  && !*(v3 - 13)
			  && v3[1] == missile[v1]._mix
			  && v3[2] == missile[v1]._miy )
			{
				ClrPlrPath(*(int *)arglist);
				if ( *(_DWORD *)arglist == myplr )
				{
					NetSendCmdParam1(1u, CMD_WARP, missile[v1]._misource);
					*(v3 - 13) = 10;
				}
			}
		}
		++*(_DWORD *)arglist;
		v3 += 5430;
	}
	while ( (signed int)v3 < (signed int)&plr_msgs[0].player );
	if ( !missile[v1]._mirange )
	{
		v4 = missile[v1]._mlid;
		missile[v1]._miDelFlag = 1;
		AddUnLight(v4);
	}
	PutMissile(ia);
}

//----- (0042E9CB) --------------------------------------------------------
void __fastcall MI_Flash(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // eax
	bool v5; // zf
	int v6; // esi
	bool v7; // [esp-18h] [ebp-24h]
	bool v8; // [esp-14h] [ebp-20h]
	bool v9; // [esp-10h] [ebp-1Ch]
	bool v10; // [esp-Ch] [ebp-18h]
	bool v11; // [esp-8h] [ebp-14h]
	bool v12; // [esp-4h] [ebp-10h]

	v1 = i;
	v2 = i;
	if ( !missile[i]._micaster )
	{
		v3 = missile[v2]._misource;
		if ( v3 != -1 )
			plr[v3]._pInvincible = 1;
	}
	v4 = missile[v2]._mix;
	--missile[v2]._mirange;
	CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 1u, v4 - 1, missile[v2]._miy, 1, v7);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix, missile[v2]._miy, 1, v8);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix + 1, missile[v2]._miy, 1, v9);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix - 1, missile[v2]._miy + 1, 1, v10);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix, missile[v2]._miy + 1, 1, v11);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix + 1, missile[v2]._miy + 1, 1, v12);
	if ( !missile[v2]._mirange )
	{
		v5 = missile[v2]._micaster == 0;
		missile[v2]._miDelFlag = 1;
		if ( v5 )
		{
			v6 = missile[v2]._misource;
			if ( v6 != -1 )
				plr[v6]._pInvincible = 0;
		}
	}
	PutMissile(v1);
}

//----- (0042EAF1) --------------------------------------------------------
void __fastcall MI_Flash2(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // eax
	bool v5; // zf
	int v6; // esi
	bool v7; // [esp-Ch] [ebp-18h]
	bool v8; // [esp-8h] [ebp-14h]
	bool v9; // [esp-4h] [ebp-10h]

	v1 = i;
	v2 = i;
	if ( !missile[i]._micaster )
	{
		v3 = missile[v2]._misource;
		if ( v3 != -1 )
			plr[v3]._pInvincible = 1;
	}
	v4 = missile[v2]._miy;
	--missile[v2]._mirange;
	CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix - 1, v4 - 1, 1, v7);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix, missile[v2]._miy - 1, 1, v8);
	CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 1u, missile[v2]._mix + 1, missile[v2]._miy - 1, 1, v9);
	if ( !missile[v2]._mirange )
	{
		v5 = missile[v2]._micaster == 0;
		missile[v2]._miDelFlag = 1;
		if ( v5 )
		{
			v6 = missile[v2]._misource;
			if ( v6 != -1 )
				plr[v6]._pInvincible = 0;
		}
	}
	PutMissile(v1);
}

//----- (0042EBBF) --------------------------------------------------------
void __fastcall MI_Manashield(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // edx
	int v4; // eax
	int v5; // ecx
	int v6; // edx
	bool v7; // zf
	int v8; // eax
	int v9; // ecx
	int v10; // edx
	int v11; // ecx
	int v12; // ecx
	bool v13; // sf
	int v14; // [esp+Ch] [ebp-10h]
	int ia; // [esp+14h] [ebp-8h]
	int arglist; // [esp+18h] [ebp-4h]

	ia = i;
	v1 = i;
	arglist = missile[i]._misource;
	v2 = arglist;
	v3 = plr[arglist]._pxoff;
	v4 = plr[arglist].WorldX;
	v5 = plr[arglist].WorldY;
	missile[v1]._mix = v4;
	missile[v1]._mitxoff = v3 << 16;
	v6 = plr[arglist]._pyoff << 16;
	v7 = plr[arglist]._pmode == PM_WALK3;
	missile[v1]._miy = v5;
	missile[v1]._mityoff = v6;
	if ( v7 )
	{
		missile[v1]._misx = plr[v2]._px;
		missile[v1]._misy = plr[v2]._py;
	}
	else
	{
		missile[v1]._misx = v4;
		missile[v1]._misy = v5;
	}
	GetMissilePos(ia);
	if ( plr[v2]._pmode == PM_WALK3 )
	{
		if ( plr[v2]._pdir == 2 )
			++missile[v1]._mix;
		else
			++missile[v1]._miy;
	}
	if ( arglist != myplr )
	{
		if ( currlevel != plr[v2].plrlevel )
			missile[v1]._miDelFlag = 1;
		goto LABEL_33;
	}
	v8 = plr[v2]._pMana;
	v14 = plr[v2]._pMana;
	if ( v8 <= 0 || !plr[v2].plractive[0] )
		missile[v1]._mirange = 0;
	v9 = missile[v1]._miVar1;
	if ( plr[v2]._pHitPoints >= v9 )
		goto LABEL_26;
	v10 = v9 - plr[v2]._pHitPoints;
	if ( missile[v1]._mispllvl > 0 )
	{
		v10 = v10 / -3 + v9 - plr[v2]._pHitPoints;
		v8 = v14;
	}
	if ( v10 < 0 )
		v10 = 0;
	drawmanaflag = 1;
	drawhpflag = 1;
	if ( v8 >= v10 )
	{
		plr[v2]._pHitPoints = v9;
		v11 = missile[v1]._miVar2;
		plr[v2]._pManaBase -= v10;
		plr[v2]._pHPBase = v11;
		plr[v2]._pMana = v8 - v10;
LABEL_26:
		if ( arglist == myplr && !plr[v2]._pHitPoints && !missile[v1]._miVar1 && plr[v2]._pmode != PM_DEATH )
		{
			missile[v1]._mirange = 0;
			missile[v1]._miDelFlag = 1;
			SyncPlrKill(arglist, -1);
		}
		goto LABEL_31;
	}
	missile[v1]._miDelFlag = 1;
	plr[v2]._pHitPoints = v8 + v9 - v10;
	plr[v2]._pHPBase = v8 + missile[v1]._miVar2 - v10;
	v12 = plr[v2]._pMaxManaBase - plr[v2]._pMaxMana;
	v13 = plr[v2]._pHitPoints < 0;
	plr[v2]._pMana = 0;
	missile[v1]._mirange = 0;
	plr[v2]._pManaBase = v12;
	if ( v13 )
		SetPlayerHitPoints(arglist, 0);
	if ( plr[v2]._pHitPoints & 0xFFFFFFC0 )
		goto LABEL_26;
	if ( arglist == myplr )
	{
		SyncPlrKill(arglist, missile[v1]._miVar8);
		goto LABEL_26;
	}
LABEL_31:
	v7 = missile[v1]._mirange == 0;
	missile[v1]._miVar1 = plr[v2]._pHitPoints;
	missile[v1]._miVar2 = plr[v2]._pHPBase;
	if ( v7 )
	{
		missile[v1]._miDelFlag = 1;
		NetSendCmd(1u, CMD_ENDSHIELD);
	}
LABEL_33:
	PutMissile(ia);
}

//----- (0042EE19) --------------------------------------------------------
void __fastcall MI_Etherealize(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // edi
	int v4; // edi
	int v5; // edx
	int v6; // eax
	int v7; // ecx
	int v8; // edx
	bool v9; // zf
	char v10; // al

	v1 = i;
	v2 = i;
	v3 = missile[i]._misource;
	--missile[v2]._mirange;
	v4 = v3;
	v5 = plr[v4]._pxoff;
	v6 = plr[v4].WorldX;
	v7 = plr[v4].WorldY;
	missile[v2]._mix = v6;
	missile[v2]._mitxoff = v5 << 16;
	v8 = plr[v4]._pyoff << 16;
	v9 = plr[v4]._pmode == PM_WALK3;
	missile[v2]._miy = v7;
	missile[v2]._mityoff = v8;
	if ( v9 )
	{
		missile[v2]._misx = plr[v4]._px;
		missile[v2]._misy = plr[v4]._py;
	}
	else
	{
		missile[v2]._misx = v6;
		missile[v2]._misy = v7;
	}
	GetMissilePos(v1);
	if ( plr[v4]._pmode == PM_WALK3 )
	{
		if ( plr[v4]._pdir == 2 )
			++missile[v2]._mix;
		else
			++missile[v2]._miy;
	}
	_LOBYTE(plr[v4]._pSpellFlags) |= 1u;
	v10 = plr[v4]._pSpellFlags;
	if ( !missile[v2]._mirange || plr[v4]._pHitPoints <= 0 )
	{
		missile[v2]._miDelFlag = 1;
		_LOBYTE(plr[v4]._pSpellFlags) = v10 & 0xFE;
	}
	PutMissile(v1);
}

//----- (0042EEFD) --------------------------------------------------------
void __fastcall MI_Firemove(int i)
{
	int v1; // esi
	int *v2; // eax
	int v3; // ecx
	int v4; // ecx
	int v5; // ebx
	int v6; // ecx
	int v7; // edx
	int v8; // ecx
	int v9; // ST10_4
	int v10; // ecx
	bool v11; // [esp-4h] [ebp-4Ch]
	int r; // [esp+Ch] [ebp-3Ch]
	int v13; // [esp+10h] [ebp-38h]
	int v14; // [esp+14h] [ebp-34h]
	int v15; // [esp+18h] [ebp-30h]
	int v16; // [esp+1Ch] [ebp-2Ch]
	int v17; // [esp+20h] [ebp-28h]
	int v18; // [esp+24h] [ebp-24h]
	int v19; // [esp+28h] [ebp-20h]
	int v20; // [esp+2Ch] [ebp-1Ch]
	int v21; // [esp+30h] [ebp-18h]
	int v22; // [esp+34h] [ebp-14h]
	int v23; // [esp+38h] [ebp-10h]
	int v24; // [esp+3Ch] [ebp-Ch]
	int v25; // [esp+40h] [ebp-8h]
	int ia; // [esp+44h] [ebp-4h]

	v1 = i;
	v15 = 5;
	v16 = 5;
	missile[v1]._miyoff += 32;
	v23 = 12;
	v24 = 12;
	--missile[v1]._mix;
	--missile[v1]._miy;
	r = 2;
	v13 = 3;
	v14 = 4;
	v17 = 6;
	v18 = 7;
	v19 = 8;
	v20 = 9;
	v21 = 10;
	v22 = 11;
	ia = i;
	v25 = 0;
	v2 = &missile[i]._miVar1;
	if ( ++*v2 == missile[i]._miAnimLen )
	{
		SetMissDir(i, 1);
		_LOBYTE(v3) = 82;
		missile[v1]._miAnimFrame = random(v3, 11) + 1;
	}
	v4 = ia;
	missile[v1]._mitxoff += missile[v1]._mixvel;
	missile[v1]._mityoff += missile[v1]._miyvel;
	GetMissilePos(v4);
	v5 = missile[v1]._mirange;
	CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 0, missile[v1]._mix, missile[v1]._miy, 0, v11);
	if ( missile[v1]._miHitFlag == 1 )
		missile[v1]._mirange = v5;
	if ( !missile[v1]._mirange )
	{
		v6 = missile[v1]._mlid;
		missile[v1]._miDelFlag = 1;
		AddUnLight(v6);
	}
	if ( missile[v1]._mimfnum || !missile[v1]._mirange )
	{
		v7 = missile[v1]._mix;
		if ( v7 != missile[v1]._miVar3 || missile[v1]._miy != missile[v1]._miVar4 )
		{
			v8 = missile[v1]._mlid;
			missile[v1]._miVar3 = v7;
			v9 = missile[v1]._miy;
			missile[v1]._miVar4 = v9;
			ChangeLight(v8, v7, v9, 8);
		}
	}
	else
	{
		if ( !missile[v1]._miVar2 )
			missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, r);
		ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2));
		++missile[v1]._miVar2;
	}
	++missile[v1]._mix;
	v10 = ia;
	++missile[v1]._miy;
	missile[v1]._miyoff -= 32;
	PutMissile(v10);
}

//----- (0042F0C8) --------------------------------------------------------
void __fastcall MI_Guardian(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	unsigned char *v4; // edi
	int v5; // eax
	signed int v6; // ecx
	unsigned char *v7; // ebx
	unsigned char v8; // dl
	unsigned char *v9; // edi
	int v10; // ecx
	int *v11; // eax
	int v12; // ecx
	int v13; // ecx
	signed int v14; // [esp+Ch] [ebp-14h]
	int v15; // [esp+10h] [ebp-10h]
	int v16; // [esp+14h] [ebp-Ch]
	unsigned char *v17; // [esp+18h] [ebp-8h]
	int ia; // [esp+1Ch] [ebp-4h]

	ia = i;
	v1 = i;
	v2 = missile[i]._miVar2;
	--missile[v1]._mirange;
	v3 = missile[i]._mirange;
	v16 = 0;
	v15 = 0;
	if ( v2 > 0 )
		missile[v1]._miVar2 = v2 - 1;
	if ( v3 == missile[v1]._miVar1 || missile[v1]._mimfnum == 2 && !missile[v1]._miVar2 )
		SetMissDir(ia, 1);
	if ( !(missile[v1]._mirange % 16) )
	{
		v4 = &vCrawlTable[0][1];
		v5 = 0;
		v17 = &vCrawlTable[0][1];
		do
		{
			if ( v5 == -1 )
				break;
			v6 = 10;
			v14 = 10;
			do
			{
				v7 = &v4[v6 - 1];
				v8 = *v7;
				if ( !*v7 && !v4[v6] )
					break;
				if ( v16 != v8 || v15 != v4[v6] )
				{
					v9 = &v4[v6];
					v5 = Sentfire(ia, v8 + missile[v1]._mix, missile[v1]._miy + *v9);
					if ( v5 == -1
					  || (v5 = Sentfire(ia, missile[v1]._mix - *v7, missile[v1]._miy - *v9), v5 == -1)
					  || (v5 = Sentfire(ia, missile[v1]._mix + *v7, missile[v1]._miy - *v9), v5 == -1)
					  || (v5 = Sentfire(ia, missile[v1]._mix - *v7, missile[v1]._miy + *v9), v5 == -1) )
					{
						v4 = v17;
						break;
					}
					v16 = *v7;
					v10 = *v9;
					v4 = v17;
					v15 = v10;
					v6 = v14;
				}
				v6 -= 2;
				v14 = v6;
			}
			while ( v6 >= 0 );
			v4 += 30;
			v17 = v4;
		}
		while ( (signed int)v4 < (signed int)RadiusAdj );
	}
	if ( missile[v1]._mirange == 14 )
	{
		SetMissDir(ia, 0);
		missile[v1]._miAnimAdd = -1;
		missile[v1]._miAnimFrame = 15;
	}
	v11 = &missile[v1]._miVar3;
	*v11 += missile[v1]._miAnimAdd;
	v12 = missile[v1]._miVar3;
	if ( v12 <= 15 )
	{
		if ( v12 > 0 )
			ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, missile[v1]._miVar3);
	}
	else
	{
		*v11 = 15;
	}
	if ( !missile[v1]._mirange )
	{
		v13 = missile[v1]._mlid;
		missile[v1]._miDelFlag = 1;
		AddUnLight(v13);
	}
	PutMissile(ia);
}

//----- (0042F2C2) --------------------------------------------------------
void __fastcall MI_Chain(int i)
{
	int v1; // esi
	int ST1C_4_1; // ST1C_4
	int v3; // edi
	int v4; // ebx
	int v5; // eax
	int v6; // ST18_4
	int v7; // eax
	int v8; // edi
	int v9; // ecx
	int v10; // eax
	unsigned char *v11; // ecx
	int v12; // ebx
	int v13; // eax
	int v14; // eax
	bool v15; // zf
	int v16; // [esp+Ch] [ebp-68h]
	int v17; // [esp+10h] [ebp-64h]
	int v18; // [esp+14h] [ebp-60h]
	int v19; // [esp+18h] [ebp-5Ch]
	int v20; // [esp+1Ch] [ebp-58h]
	int v21; // [esp+20h] [ebp-54h]
	int v22; // [esp+24h] [ebp-50h]
	int v23; // [esp+28h] [ebp-4Ch]
	int v24; // [esp+2Ch] [ebp-48h]
	int v25; // [esp+30h] [ebp-44h]
	int v26; // [esp+34h] [ebp-40h]
	int v27; // [esp+38h] [ebp-3Ch]
	int v28; // [esp+3Ch] [ebp-38h]
	int v29; // [esp+40h] [ebp-34h]
	int v30; // [esp+44h] [ebp-30h]
	int v31; // [esp+48h] [ebp-2Ch]
	int v32; // [esp+4Ch] [ebp-28h]
	int v33; // [esp+50h] [ebp-24h]
	int v34; // [esp+54h] [ebp-20h]
	int v2; // [esp+58h] [ebp-1Ch]
	int v36; // [esp+5Ch] [ebp-18h]
	unsigned char *v37; // [esp+60h] [ebp-14h]
	int id; // [esp+64h] [ebp-10h]
	int sx; // [esp+68h] [ebp-Ch]
	int sy; // [esp+6Ch] [ebp-8h]
	int j; // [esp+70h] [ebp-4h]

	v16 = 0;
	v1 = i;
	v17 = 3;
	ST1C_4_1 = missile[i]._miVar2;
	v3 = missile[i]._mix;
	v4 = missile[i]._miy;
	v5 = missile[i]._misource;
	v6 = missile[i]._miVar1;
	v18 = 12;
	v19 = 45;
	v20 = 94;
	v21 = 159;
	v22 = 240;
	v23 = 337;
	v24 = 450;
	v25 = 579;
	v26 = 724;
	v27 = 885;
	v28 = 1062;
	v29 = 1255;
	v30 = 1464;
	v31 = 1689;
	v32 = 1930;
	v33 = 2187;
	v34 = 2460;
	id = v5;
	sx = v3;
	sy = v4;
	v7 = GetDirection(v3, v4, v6, ST1C_4_1);
	AddMissile(v3, v4, missile[v1]._miVar1, missile[v1]._miVar2, v7, 7, 0, id, 1, missile[v1]._mispllvl);
	v8 = missile[v1]._mispllvl + 3;
	if ( v8 > 19 )
		v8 = 19;
	for ( j = 1; j < v8; ++j )
	{
		v9 = *(&v16 + j);
		v10 = *(&CrawlTable.n_1 + v9);
		if ( v10 > 0 )
		{
			v11 = &CrawlTable.delta_1[0].y + v9;
			v36 = v10;
			v37 = v11;
			do
			{
				v12 = sx + (char)*(v11 - 1);
				v13 = sy + (char)*v11;
				v2 = sy + (char)*v11;
				if ( v12 > 0 && v12 < 112 && v13 > 0 && v13 < 112 && dMonster[0][v13 + 112 * v12] > 0 )
				{
					v14 = GetDirection(sx, sy, v12, v13);
					AddMissile(sx, sy, v12, v2, v14, 7, 0, id, 1, missile[v1]._mispllvl);
					v11 = v37;
				}
				v11 += 2;
				v15 = v36-- == 1;
				v37 = v11;
			}
			while ( !v15 );
		}
	}
	v15 = missile[v1]._mirange-- == 1;
	if ( v15 )
		missile[v1]._miDelFlag = 1;
}

//----- (0042F475) --------------------------------------------------------
void __fastcall mi_null_11(int i)
{
	int v1; // eax
	bool v2; // zf

	v1 = i;
	v2 = missile[i]._mirange == 1;
	--missile[v1]._mirange;
	if ( v2 )
		missile[v1]._miDelFlag = 1;
	if ( missile[v1]._miAnimFrame == missile[v1]._miAnimLen )
		missile[v1]._miPreFlag = 1;
	PutMissile(i);
}

//----- (0042F4A9) --------------------------------------------------------
void __fastcall MI_Weapexp(int i)
{
	int v1; // esi
	int v2; // ecx
	int v3; // eax
	int v4; // ecx
	bool v5; // zf
	int v6; // edx
	int v7; // eax
	int v8; // eax
	int v9; // ecx
	bool v10; // [esp-4h] [ebp-34h]
	int r; // [esp+4h] [ebp-2Ch]
	int v12; // [esp+8h] [ebp-28h]
	int v13; // [esp+Ch] [ebp-24h]
	int v14; // [esp+10h] [ebp-20h]
	int v15; // [esp+14h] [ebp-1Ch]
	int v16; // [esp+18h] [ebp-18h]
	int v17; // [esp+1Ch] [ebp-14h]
	int v18; // [esp+20h] [ebp-10h]
	int v19; // [esp+24h] [ebp-Ch]
	int v20; // [esp+28h] [ebp-8h]
	int ia; // [esp+2Ch] [ebp-4h]

	ia = i;
	v1 = i;
	--missile[v1]._mirange;
	r = 9;
	v12 = 10;
	v16 = 10;
	v2 = missile[i]._mitype;
	v13 = 11;
	v15 = 11;
	v3 = missile[v1]._misource;
	v4 = v2;
	v5 = missile[v1]._miVar2 == 1;
	v14 = 12;
	v17 = 8;
	v18 = 6;
	v19 = 4;
	v20 = 2;
	if ( v5 )
	{
		v6 = plr[v3]._pIFMinDam;
		v7 = plr[v3]._pIFMaxDam;
		missiledata[v4].mResist = 1;
	}
	else
	{
		v6 = plr[v3]._pILMinDam;
		v7 = plr[v3]._pILMaxDam;
		missiledata[v4].mResist = 2;
	}
	CheckMissileCol(ia, v6, v7, 0, missile[v1]._mix, missile[v1]._miy, 0, v10);
	v8 = missile[v1]._miVar1;
	if ( v8 )
	{
		if ( missile[v1]._mirange )
			ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + v8));
	}
	else
	{
		missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, 9);
	}
	++missile[v1]._miVar1;
	if ( missile[v1]._mirange )
	{
		PutMissile(ia);
	}
	else
	{
		v9 = missile[v1]._mlid;
		missile[v1]._miDelFlag = 1;
		AddUnLight(v9);
	}
}

//----- (0042F5D6) --------------------------------------------------------
void __fastcall MI_Misexp(int i)
{
	int v1; // edi
	int v2; // esi
	bool v3; // zf
	int v4; // ecx
	int v5; // eax
	int r; // [esp+8h] [ebp-28h]
	int v7; // [esp+Ch] [ebp-24h]
	int v8; // [esp+10h] [ebp-20h]
	int v9; // [esp+14h] [ebp-1Ch]
	int v10; // [esp+18h] [ebp-18h]
	int v11; // [esp+1Ch] [ebp-14h]
	int v12; // [esp+20h] [ebp-10h]
	int v13; // [esp+24h] [ebp-Ch]
	int v14; // [esp+28h] [ebp-8h]
	int v15; // [esp+2Ch] [ebp-4h]

	v1 = i;
	v2 = i;
	r = 9;
	v3 = missile[i]._mirange == 1;
	--missile[v2]._mirange;
	v7 = 10;
	v9 = 12;
	v8 = 11;
	v10 = 11;
	v11 = 10;
	v12 = 8;
	v13 = 6;
	v14 = 4;
	v15 = 2;
	if ( v3 )
	{
		v4 = missile[v2]._mlid;
		missile[v2]._miDelFlag = 1;
		AddUnLight(v4);
	}
	else
	{
		v5 = missile[v2]._miVar1;
		if ( v5 )
			ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, *(&r + v5));
		else
			missile[v2]._mlid = AddLight(missile[v2]._mix, missile[v2]._miy, 9);
		++missile[v2]._miVar1;
		PutMissile(v1);
	}
}

//----- (0042F692) --------------------------------------------------------
void __fastcall MI_Acidsplat(int i)
{
	int v1; // eax
	int v2; // edx
	int v3; // edx
	int v4; // edx
	int v5; // ST1C_4

	v1 = i;
	v2 = missile[i]._mirange;
	if ( v2 == missile[i]._miAnimLen )
	{
		++missile[v1]._mix;
		++missile[v1]._miy;
		missile[v1]._miyoff -= 32;
	}
	v3 = v2 - 1;
	missile[v1]._mirange = v3;
	if ( v3 )
	{
		PutMissile(i);
	}
	else
	{
		v4 = missile[v1]._misource;
		v5 = missile[v1]._mispllvl;
		missile[v1]._miDelFlag = 1;
		AddMissile(
			missile[v1]._mix,
			missile[v1]._miy,
			i,
			0,
			missile[v1]._mimfnum,
			59,
			1,
			v4,
			(monster[v4].MData->mLevel >= 2) + 1,
			v5);
	}
}

//----- (0042F723) --------------------------------------------------------
void __fastcall MI_Teleport(int i)
{
	int v1; // edi
	int v2; // ebx
	int *v3; // eax
	int v4; // esi
	int v5; // ecx
	int v6; // edx
	int v7; // ecx
	int v8; // edx
	int v9; // edx
	int v10; // eax
	bool v11; // zf

	v1 = i;
	v2 = missile[i]._misource;
	v3 = &missile[i]._mirange;
	if ( --*v3 > 0 )
	{
		v4 = v2;
		v5 = plr[v2].WorldX;
		v6 = plr[v2].WorldY;
		dPlayer[plr[v2].WorldX][v6] = 0;
		PlrClrTrans(v5, v6);
		v7 = missile[v1]._mix;
		v8 = missile[v1]._miy;
		plr[v4].WorldX = v7;
		plr[v4].WorldY = v8;
		plr[v4]._px = v7;
		plr[v4]._py = v8;
		plr[v4]._poldx = v7;
		plr[v4]._poldy = v8;
		PlrDoTrans(v7, v8);
		v9 = plr[v2].WorldX;
		missile[v1]._miVar1 = 1;
		v10 = plr[v2].WorldY;
		v11 = leveltype == 0;
		dPlayer[v9][v10] = v2 + 1;
		if ( !v11 )
		{
			ChangeLightXY(plr[v4]._plid, v9, v10);
			ChangeVisionXY(plr[v4]._pvid, plr[v4].WorldX, plr[v4].WorldY);
		}
		if ( v2 == myplr )
		{
			ViewX = plr[v4].WorldX - ScrollInfo._sdx;
			ViewY = plr[v4].WorldY - ScrollInfo._sdy;
		}
	}
	else
	{
		missile[v1]._miDelFlag = 1;
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (0042F82C) --------------------------------------------------------
void __fastcall MI_Stone(int i)
{
	int v1; // esi
	int v2; // edi
	int v3; // edi
	bool v4; // zf
	bool v5; // sf
	int ia; // [esp+Ch] [ebp-4h]

	v1 = i;
	ia = i;
	v2 = missile[i]._miVar2;
	--missile[v1]._mirange;
	v3 = v2;
	if ( !monster[v3]._mhitpoints && _LOBYTE(missile[v1]._miAnimType) != 18 )
	{
		missile[v1]._mimfnum = 0;
		missile[v1]._miDrawFlag = 1;
		SetMissAnim(i, MFILE_SHATTER1);
		missile[v1]._mirange = 11;
	}
	if ( monster[v3]._mmode == MM_STONE )
	{
		if ( !missile[v1]._mirange )
		{
			v4 = monster[v3]._mhitpoints == 0;
			v5 = monster[v3]._mhitpoints < 0;
			missile[v1]._miDelFlag = 1;
			if ( v5 || v4 )
				AddDead(monster[v3]._mx, monster[v3]._my, stonendx, (direction)monster[v3]._mdir);
			else
				monster[v3]._mmode = missile[v1]._miVar1;
		}
		if ( _LOBYTE(missile[v1]._miAnimType) == 18 )
			PutMissile(ia);
	}
	else
	{
		missile[v1]._miDelFlag = 1;
	}
}

//----- (0042F8EE) --------------------------------------------------------
void __fastcall MI_Boom(int i)
{
	int v1; // edi
	int v2; // esi
	bool v3; // [esp-4h] [ebp-10h]

	v1 = i;
	v2 = i;
	--missile[v2]._mirange;
	if ( !missile[i]._miVar1 )
		CheckMissileCol(i, missile[v2]._midam, missile[v2]._midam, 0, missile[v2]._mix, missile[v2]._miy, 1, v3);
	if ( missile[v2]._miHitFlag == 1 )
		missile[v2]._miVar1 = 1;
	if ( !missile[v2]._mirange )
		missile[v2]._miDelFlag = 1;
	PutMissile(v1);
}

//----- (0042F94F) --------------------------------------------------------
void __fastcall MI_Rhino(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // edi
	int v4; // edi
	int v5; // eax
	int v6; // eax
	int v7; // ebx
	bool v8; // zf
	int x; // [esp+Ch] [ebp-1Ch]
	int v10; // [esp+10h] [ebp-18h]
	int y; // [esp+14h] [ebp-14h]
	int a2; // [esp+18h] [ebp-10h]
	int a3; // [esp+1Ch] [ebp-Ch]
	int arglist; // [esp+20h] [ebp-8h]
	int a1; // [esp+24h] [ebp-4h]

	v1 = i;
	v2 = i;
	arglist = i;
	v3 = missile[i]._misource;
	a1 = v3;
	v4 = v3;
	if ( monster[v4]._mmode != MM_CHARGE )
		goto LABEL_12;
	GetMissilePos(i);
	v5 = missile[v2]._mix;
	x = v5;
	v10 = missile[v2]._miy;
	dMonster[0][v10 + 112 * v5] = 0;
	v6 = missile[v2]._mixvel;
	if ( monster[v4]._mAi == MG_SNAKE )
	{
		missile[v2]._mitxoff += 2 * v6;
		missile[v2]._mityoff += 2 * missile[v2]._miyvel;
		GetMissilePos(v1);
		a2 = missile[v2]._mix;
		a3 = missile[v2]._miy;
		missile[v2]._mitxoff -= missile[v2]._mixvel;
		missile[v2]._mityoff -= missile[v2]._miyvel;
	}
	else
	{
		missile[v2]._mitxoff += v6;
		missile[v2]._mityoff += missile[v2]._miyvel;
	}
	GetMissilePos(v1);
	v7 = missile[v2]._mix;
	y = missile[v2]._miy;
	if ( !PosOkMonst(a1, missile[v2]._mix, missile[v2]._miy) || monster[v4]._mAi == MG_SNAKE && !PosOkMonst(a1, a2, a3) )
	{
		MissToMonst(arglist, x, v10);
LABEL_12:
		missile[v2]._miDelFlag = 1;
		return;
	}
	v8 = monster[v4]._uniqtype == 0;
	monster[v4]._mfutx = v7;
	monster[v4]._moldx = v7;
	dMonster[0][y + 112 * v7] = -1 - a1;
	monster[v4]._mx = v7;
	monster[v4]._mfuty = y;
	monster[v4]._moldy = y;
	monster[v4]._my = y;
	if ( !v8 )
		ChangeLightXY(missile[v2]._mlid, v7, y);
	MoveMissilePos(arglist);
	PutMissile(arglist);
}

//----- (0042FAD0) --------------------------------------------------------
void __fastcall mi_null_32(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // eax
	int v6; // eax
	int v7; // ecx
	int v8; // eax
	int v9; // eax
	int v10; // ebx
	int v11; // eax
	int v12; // eax
	int v13; // ecx
	int v14; // ecx
	int v15; // eax
	int v16; // [esp+Ch] [ebp-14h]
	int arglist; // [esp+10h] [ebp-10h]
	int x; // [esp+14h] [ebp-Ch]
	int y; // [esp+18h] [ebp-8h]
	int a3; // [esp+1Ch] [ebp-4h]

	v1 = i;
	arglist = i;
	GetMissilePos(i);
	v2 = v1;
	v3 = missile[v1]._mix;
	a3 = missile[v1]._miy;
	missile[v2]._mitxoff += missile[v1]._mixvel;
	missile[v2]._mityoff += missile[v1]._miyvel;
	GetMissilePos(v1);
	v4 = missile[v1]._misource;
	y = missile[v2]._miy;
	v5 = monster[v4]._menemy;
	x = missile[v2]._mix;
	if ( monster[v4]._mFlags & 0x10 )
	{
		v9 = v5;
		v7 = monster[v9]._mx;
		v8 = monster[v9]._my;
	}
	else
	{
		v6 = v5;
		v7 = plr[v6].WorldX;
		v8 = plr[v6].WorldY;
	}
	v16 = v8;
	if ( (missile[v2]._mix != v3 || y != a3)
	  && (missile[v2]._miVar1 & 1 && (abs(v3 - v7) >= 4 || abs(a3 - v16) >= 4) || missile[v2]._miVar2 > 1)
	  && PosOkMonst(missile[v2]._misource, v3, a3) )
	{
		MissToMonst(arglist, v3, a3);
		v10 = v16;
		missile[v2]._miDelFlag = 1;
	}
	else
	{
		v11 = x;
		if ( monster[v4]._mFlags & 0x10 )
			v10 = dMonster[0][y + v11 * 112];
		else
			v10 = dPlayer[v11][y];
	}
	_LOBYTE(v12) = PosOkMissile(x, y);
	if ( !v12 || v10 > 0 && !(missile[v2]._miVar1 & 1) )
	{
		missile[v2]._mixvel = -missile[v2]._mixvel;
		v13 = missile[v2]._mimfnum;
		missile[v2]._miyvel = -missile[v2]._miyvel;
		v14 = opposite[v13];
		missile[v2]._mimfnum = v14;
		v15 = monster[v4].MType->Anims[1].Frames[v14 + 1];
		++missile[v2]._miVar2;
		missile[v2]._miAnimCel = v15;
		if ( v10 > 0 )
			missile[v2]._miVar1 |= 1u;
	}
	MoveMissilePos(arglist);
	PutMissile(arglist);
}

//----- (0042FC74) --------------------------------------------------------
void __fastcall MI_FirewallC(int i)
{
	int v1; // esi
	int v2; // edx
	bool v3; // zf
	int v4; // eax
	int v5; // edi
	int v6; // ecx
	int v7; // ebx
	int v8; // eax
	int v9; // edi
	int v10; // ecx
	int v11; // ebx
	int id; // [esp+Ch] [ebp-4h]

	v1 = i;
	v2 = missile[i]._misource;
	v3 = missile[i]._mirange == 1;
	--missile[v1]._mirange;
	id = v2;
	if ( v3 )
	{
		missile[v1]._miDelFlag = 1;
	}
	else
	{
		v4 = missile[v1]._miVar3;
		v5 = missile[v1]._miVar1 + XDirAdd[v4];
		v6 = missile[v1]._miVar2;
		v7 = v6 + YDirAdd[v4];
		if ( nMissileTable[dPiece[0][v6 + 112 * missile[v1]._miVar1]]
		  || missile[v1]._miVar8
		  || v5 <= 0
		  || v5 >= 112
		  || v7 <= 0
		  || v7 >= 112 )
		{
			missile[v1]._miVar8 = 1;
		}
		else
		{
			AddMissile(
				missile[v1]._miVar1,
				v6,
				missile[v1]._miVar1,
				v6,
				plr[v2]._pdir,
				5,
				0,
				v2,
				0,
				missile[v1]._mispllvl);
			v2 = id;
			missile[v1]._miVar1 = v5;
			missile[v1]._miVar2 = v7;
		}
		v8 = missile[v1]._miVar4;
		v9 = missile[v1]._miVar5 + XDirAdd[v8];
		v10 = missile[v1]._miVar6;
		v11 = v10 + YDirAdd[v8];
		if ( nMissileTable[dPiece[0][v10 + 112 * missile[v1]._miVar5]]
		  || missile[v1]._miVar7
		  || v9 <= 0
		  || v9 >= 112
		  || v11 <= 0
		  || v11 >= 112 )
		{
			missile[v1]._miVar7 = 1;
		}
		else
		{
			AddMissile(
				missile[v1]._miVar5,
				v10,
				missile[v1]._miVar5,
				v10,
				plr[v2]._pdir,
				5,
				0,
				v2,
				0,
				missile[v1]._mispllvl);
			missile[v1]._miVar5 = v9;
			missile[v1]._miVar6 = v11;
		}
	}
}

//----- (0042FDE3) --------------------------------------------------------
void __fastcall MI_Infra(int i)
{
	int v1; // eax
	int *v2; // ecx
	int v3; // esi
	int v4; // ecx

	v1 = i;
	v2 = &missile[i]._mirange;
	v3 = --*v2;
	v4 = missile[v1]._misource;
	plr[missile[v1]._misource]._pInfraFlag = 1;
	if ( !v3 )
	{
		missile[v1]._miDelFlag = 1;
		CalcPlrItemVals(v4, 1);
	}
}

//----- (0042FE20) --------------------------------------------------------
void __fastcall MI_Apoca(int i)
{
	int v1; // esi
	int v2; // edi
	signed int v3; // eax
	int v4; // ecx
	int v5; // ebx
	int id; // [esp+8h] [ebp-8h]
	int v7; // [esp+Ch] [ebp-4h]

	v1 = i;
	v2 = missile[i]._miVar2;
	id = missile[i]._misource;
	v3 = 0;
	if ( v2 >= missile[i]._miVar3 )
		goto LABEL_18;
	do
	{
		if ( v3 )
			break;
		v4 = missile[v1]._miVar4;
		v7 = missile[v1]._miVar4;
		if ( v4 >= missile[v1]._miVar5 )
		{
LABEL_11:
			missile[v1]._miVar4 = missile[v1]._miVar6;
		}
		else
		{
			v5 = v2 + 112 * v4;
			while ( !v3 )
			{
				if ( dMonster[0][v5] > 3 && !nSolidTable[dPiece[0][v5]] )
				{
					AddMissile(v4, v2, v4, v2, plr[id]._pdir, 36, 0, id, missile[v1]._midam, 0);
					v4 = v7;
					v3 = 1;
				}
				++v4;
				v5 += 112;
				v7 = v4;
				if ( v4 >= missile[v1]._miVar5 )
				{
					if ( v3 )
						break;
					goto LABEL_11;
				}
			}
		}
		++v2;
	}
	while ( v2 < missile[v1]._miVar3 );
	if ( v3 != 1 )
	{
LABEL_18:
		missile[v1]._miDelFlag = 1;
	}
	else
	{
		missile[v1]._miVar2 = v2 - 1;
		missile[v1]._miVar4 = v7;
	}
}

//----- (0042FF0B) --------------------------------------------------------
void __fastcall MI_Wave(int i)
{
	int v1; // esi
	int v2; // ebx
	int v3; // eax
	int v4; // edi
	int v5; // ecx
	int v6; // eax
	int v7; // ebx
	int v8; // eax
	int v9; // ebx
	int v10; // eax
	int v11; // ebx
	bool v12; // zf
	int v13; // [esp+Ch] [ebp-2Ch]
	int v14; // [esp+10h] [ebp-28h]
	int v15; // [esp+14h] [ebp-24h]
	int v16; // [esp+14h] [ebp-24h]
	signed int v17; // [esp+18h] [ebp-20h]
	int *v18; // [esp+1Ch] [ebp-1Ch]
	signed int v19; // [esp+20h] [ebp-18h]
	int v20; // [esp+24h] [ebp-14h]
	int v21; // [esp+24h] [ebp-14h]
	int v22; // [esp+28h] [ebp-10h]
	int j; // [esp+28h] [ebp-10h]
	int id; // [esp+2Ch] [ebp-Ch]
	int sx; // [esp+30h] [ebp-8h]
	int sy; // [esp+34h] [ebp-4h]
	int sya; // [esp+34h] [ebp-4h]

	v19 = 0;
	v1 = i;
	v17 = 0;
	v2 = missile[i]._mix;
	id = missile[i]._misource;
	v14 = v2;
	v20 = missile[i]._miy;
	v3 = GetDirection(v2, v20, missile[i]._miVar1, missile[i]._miVar2);
	v22 = ((_BYTE)v3 - 2) & 7;
	v4 = v3;
	v15 = ((_BYTE)v3 + 2) & 7;
	v5 = YDirAdd[v3];
	v6 = XDirAdd[v3];
	v7 = v6 + v2;
	sy = v5 + v20;
	if ( !nMissileTable[dPiece[0][v5 + v20 + 112 * v7]] )
	{
		v18 = &plr[id]._pdir;
		AddMissile(v7, sy, v7 + v6, sy + v5, *v18, 14, 0, id, 0, missile[v1]._mispllvl);
		v13 = v22;
		sya = YDirAdd[v22] + sy;
		v8 = v15;
		sx = XDirAdd[v22] + v7;
		v16 = v8 * 4;
		v9 = XDirAdd[v8];
		v10 = v20 + YDirAdd[v4] + YDirAdd[v8];
		v11 = v14 + XDirAdd[v4] + v9;
		v21 = 0;
		for ( j = v10; v21 < (missile[v1]._mispllvl >> 1) + 2; ++v21 )
		{
			if ( nMissileTable[dPiece[0][sya + 112 * sx]] || v19 || sx <= 0 || sx >= 112 || sya <= 0 || sya >= 112 )
			{
				v19 = 1;
			}
			else
			{
				AddMissile(sx, sya, sx + XDirAdd[v4], sya + YDirAdd[v4], *v18, 14, 0, id, 0, missile[v1]._mispllvl);
				sx += XDirAdd[v13];
				sya += YDirAdd[v13];
				v10 = j;
			}
			if ( nMissileTable[dPiece[0][v10 + 112 * v11]] || v17 || v11 <= 0 || v11 >= 112 || v10 <= 0 || v10 >= 112 )
			{
				v17 = 1;
			}
			else
			{
				AddMissile(v11, v10, v11 + XDirAdd[v4], v10 + YDirAdd[v4], *v18, 14, 0, id, 0, missile[v1]._mispllvl);
				v11 += *(int *)((char *)XDirAdd + v16);
				j += *(int *)((char *)YDirAdd + v16);
				v10 = j;
			}
		}
	}
	v12 = missile[v1]._mirange-- == 1;
	if ( v12 )
		missile[v1]._miDelFlag = 1;
}

//----- (00430154) --------------------------------------------------------
void __fastcall MI_Nova(int i)
{
	int v1; // edi
	int v2; // edx
	int eax1; // eax
	int v4; // ebx
	unsigned char *v5; // esi
	int v6; // eax
	bool v7; // zf
	int v8; // [esp+Ch] [ebp-18h]
	int sy; // [esp+10h] [ebp-14h]
	int id; // [esp+14h] [ebp-10h]
	int v3; // [esp+18h] [ebp-Ch]
	int midir; // [esp+1Ch] [ebp-8h]
	signed int micaster; // [esp+20h] [ebp-4h]

	v1 = i;
	v2 = 0;
	eax1 = missile[i]._misource;
	v4 = missile[i]._mix;
	v3 = missile[i]._midam;
	v8 = 0;
	id = missile[i]._misource;
	sy = missile[i]._miy;
	if ( eax1 == -1 )
	{
		midir = 0;
		micaster = 1;
	}
	else
	{
		micaster = 0;
		midir = plr[eax1]._pdir;
	}
	v5 = &vCrawlTable[0][7];
	do
	{
		v6 = *(v5 - 1);
		if ( v2 != v6 || v8 != *v5 )
		{
			AddMissile(v4, sy, v4 + v6, sy + *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl);
			AddMissile(v4, sy, v4 - *(v5 - 1), sy - *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl);
			AddMissile(v4, sy, v4 - *(v5 - 1), sy + *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl);
			AddMissile(v4, sy, v4 + *(v5 - 1), sy - *v5, midir, 4, micaster, id, v3, missile[v1]._mispllvl);
			v2 = *(v5 - 1);
			v8 = *v5;
		}
		v5 += 30;
	}
	while ( (signed int)v5 < (signed int)&RadiusAdj[0][6] );
	v7 = missile[v1]._mirange-- == 1;
	if ( v7 )
		missile[v1]._miDelFlag = 1;
}

//----- (004302A7) --------------------------------------------------------
void __fastcall MI_Blodboil(int i)
{
	missile[i]._miDelFlag = 1;
}

//----- (004302B8) --------------------------------------------------------
void __fastcall MI_Flame(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // ST0C_4
	int v4; // edx
	int v5; // edi
	int v6; // ST08_4
	int v7; // eax
	int v8; // eax
	int v9; // ecx
	bool v10; // [esp-4h] [ebp-10h]

	v1 = i;
	v2 = i;
	v3 = missile[i]._miy;
	v4 = missile[i]._midam;
	--missile[v2]._mirange;
	v5 = missile[i]._mirange;
	v6 = missile[i]._mix;
	--missile[v2]._miVar2;
	CheckMissileCol(i, v4, v4, 1u, v6, v3, 0, v10);
	if ( !missile[v2]._mirange && missile[v2]._miHitFlag == 1 )
		missile[v2]._mirange = v5;
	v7 = missile[v2]._miVar2;
	if ( !v7 )
		missile[v2]._miAnimFrame = 20;
	if ( v7 <= 0 )
	{
		v8 = missile[v2]._miAnimFrame;
		if ( v8 > 11 )
			v8 = 24 - v8;
		ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, v8);
	}
	if ( !missile[v2]._mirange )
	{
		v9 = missile[v2]._mlid;
		missile[v2]._miDelFlag = 1;
		AddUnLight(v9);
	}
	if ( missile[v2]._miVar2 <= 0 )
		PutMissile(v1);
}

//----- (0043037E) --------------------------------------------------------
void __fastcall MI_Flamec(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // ebx
	int v5; // ecx
	int v6; // edx
	int v7; // eax
	int v8; // eax

	v1 = i;
	v2 = i;
	v3 = missile[i]._mixvel;
	--missile[v2]._mirange;
	missile[v2]._mitxoff += v3;
	v4 = missile[i]._misource;
	missile[v2]._mityoff += missile[i]._miyvel;
	GetMissilePos(i);
	v5 = missile[v2]._mix;
	if ( v5 != missile[v2]._miVar1 || missile[v2]._miy != missile[v2]._miVar2 )
	{
		v6 = missile[v2]._miy;
		v7 = dPiece[0][v6 + 112 * v5];
		if ( nMissileTable[v7] )
		{
			missile[v2]._mirange = 0;
		}
		else
		{
			_LOBYTE(v7) = missile[v2]._micaster;
			AddMissile(
				v5,
				v6,
				missile[v2]._misx,
				missile[v2]._misy,
				v1,
				48,
				v7,
				v4,
				missile[v2]._miVar3,
				missile[v2]._mispllvl);
		}
		v8 = missile[v2]._mix;
		++missile[v2]._miVar3;
		missile[v2]._miVar1 = v8;
		missile[v2]._miVar2 = missile[v2]._miy;
	}
	if ( !missile[v2]._mirange || missile[v2]._miVar3 == 3 )
		missile[v2]._miDelFlag = 1;
}

//----- (0043045C) --------------------------------------------------------
void __fastcall MI_Cbolt(int i)
{
	int v1; // esi
	bool v2; // zf
	int v3; // eax
	int v4; // edx
	int v5; // eax
	int v6; // ecx
	int v7; // ecx
	int v8; // ecx
	int v9; // ecx
	bool v10; // [esp-4h] [ebp-54h]
	int v11; // [esp+Ch] [ebp-44h]
	int v12; // [esp+10h] [ebp-40h]
	int v13; // [esp+14h] [ebp-3Ch]
	int v14; // [esp+18h] [ebp-38h]
	int v15; // [esp+1Ch] [ebp-34h]
	int v16; // [esp+20h] [ebp-30h]
	int v17; // [esp+24h] [ebp-2Ch]
	int v18; // [esp+28h] [ebp-28h]
	int v19; // [esp+2Ch] [ebp-24h]
	int v20; // [esp+30h] [ebp-20h]
	int v21; // [esp+34h] [ebp-1Ch]
	int v22; // [esp+38h] [ebp-18h]
	int v23; // [esp+3Ch] [ebp-14h]
	int v24; // [esp+40h] [ebp-10h]
	int v25; // [esp+44h] [ebp-Ch]
	int v26; // [esp+48h] [ebp-8h]
	int ia; // [esp+4Ch] [ebp-4h]

	ia = i;
	v1 = i;
	--missile[v1]._mirange;
	v2 = _LOBYTE(missile[i]._miAnimType) == 3;
	v11 = -1;
	v12 = 0;
	v13 = 1;
	v14 = -1;
	v15 = 0;
	v16 = 1;
	v17 = -1;
	v18 = -1;
	v19 = 0;
	v20 = 0;
	v21 = 1;
	v22 = 1;
	v23 = 0;
	v24 = 1;
	v25 = -1;
	v26 = 0;
	if ( !v2 )
	{
		v3 = missile[v1]._miVar3;
		if ( v3 )
		{
			missile[v1]._miVar3 = v3 - 1;
		}
		else
		{
			v4 = missile[v1]._mirnd;
			v5 = (missile[v1]._miVar2 + *(&v11 + v4)) & 7;
			missile[v1]._mirnd = ((_BYTE)v4 + 1) & 0xF;
			GetMissileVel(
				ia,
				missile[v1]._mix,
				missile[v1]._miy,
				missile[v1]._mix + XDirAdd[v5],
				missile[v1]._miy + YDirAdd[v5],
				8);
			missile[v1]._miVar3 = 16;
		}
		v6 = ia;
		missile[v1]._mitxoff += missile[v1]._mixvel;
		missile[v1]._mityoff += missile[v1]._miyvel;
		GetMissilePos(v6);
		CheckMissileCol(ia, missile[v1]._midam, missile[v1]._midam, 0, missile[v1]._mix, missile[v1]._miy, 0, v10);
		if ( missile[v1]._miHitFlag == 1 )
		{
			v7 = ia;
			missile[v1]._miVar1 = 8;
			missile[v1]._mimfnum = 0;
			missile[v1]._mixoff = 0;
			missile[v1]._miyoff = 0;
			SetMissAnim(v7, MFILE_LGHNING);
			v8 = ia;
			missile[v1]._mirange = missile[v1]._miAnimLen;
			GetMissilePos(v8);
		}
		ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, missile[v1]._miVar1);
	}
	if ( !missile[v1]._mirange )
	{
		v9 = missile[v1]._mlid;
		missile[v1]._miDelFlag = 1;
		AddUnLight(v9);
	}
	PutMissile(ia);
}

//----- (004305E2) --------------------------------------------------------
void __fastcall MI_Hbolt(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // edx
	int v5; // ecx
	int v6; // ST10_4
	int v7; // ecx
	bool v8; // [esp+0h] [ebp-8h]

	v1 = i;
	v2 = i;
	--missile[v2]._mirange;
	if ( _LOBYTE(missile[i]._miAnimType) == 28 )
	{
		ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, missile[v2]._miAnimFrame + 7);
		if ( !missile[v2]._mirange )
		{
			v7 = missile[v2]._mlid;
			missile[v2]._miDelFlag = 1;
			AddUnLight(v7);
		}
	}
	else
	{
		missile[v2]._mitxoff += missile[v2]._mixvel;
		missile[v2]._mityoff += missile[v2]._miyvel;
		GetMissilePos(i);
		v3 = missile[v2]._mix;
		if ( v3 != missile[v2]._misx || missile[v2]._miy != missile[v2]._misy )
			CheckMissileCol(v1, missile[v2]._midam, missile[v2]._midam, 0, v3, missile[v2]._miy, 0, v8);
		if ( missile[v2]._mirange )
		{
			v4 = missile[v2]._mix;
			if ( v4 != missile[v2]._miVar1 || missile[v2]._miy != missile[v2]._miVar2 )
			{
				v5 = missile[v2]._mlid;
				missile[v2]._miVar1 = v4;
				v6 = missile[v2]._miy;
				missile[v2]._miVar2 = v6;
				ChangeLight(v5, v4, v6, 8);
			}
		}
		else
		{
			missile[v2]._mitxoff -= missile[v2]._mixvel;
			missile[v2]._mityoff -= missile[v2]._miyvel;
			GetMissilePos(v1);
			missile[v2]._mimfnum = 0;
			SetMissAnim(v1, MFILE_HOLYEXPL);
			missile[v2]._mirange = missile[v2]._miAnimLen - 1;
		}
	}
	PutMissile(v1);
}

//----- (0043071F) --------------------------------------------------------
void __fastcall MI_Element(int i)
{
	int v1; // esi
	int v2; // edi
	int v3; // eax
	int v4; // ebx
	int v5; // ebx
	int v6; // ecx
	int v7; // ebx
	int v8; // eax
	int v9; // edi
	int v10; // eax
	int v11; // edi
	int v12; // ecx
	bool v13; // [esp-4h] [ebp-28h]
	bool v14; // [esp+0h] [ebp-24h]
	bool v15; // [esp+4h] [ebp-20h]
	bool v16; // [esp+8h] [ebp-1Ch]
	int ty; // [esp+Ch] [ebp-18h]
	int tya; // [esp+Ch] [ebp-18h]
	int tyb; // [esp+Ch] [ebp-18h]
	int my; // [esp+10h] [ebp-14h]
	int mya; // [esp+10h] [ebp-14h]
	int myb; // [esp+10h] [ebp-14h]
	int fx; // [esp+14h] [ebp-10h]
	int fxa; // [esp+14h] [ebp-10h]
	int fy; // [esp+18h] [ebp-Ch]
	int ia; // [esp+1Ch] [ebp-8h]
	int y; // [esp+20h] [ebp-4h]
	int ya; // [esp+20h] [ebp-4h]

	v1 = i;
	ia = i;
	--missile[v1]._mirange;
	v2 = missile[i]._midam;
	ty = missile[i]._misource;
	if ( _LOBYTE(missile[i]._miAnimType) == 19 )
	{
		v3 = missile[i]._misource;
		v4 = missile[v1]._mix;
		y = missile[v1]._miy;
		fx = plr[v3].WorldX;
		fy = plr[v3].WorldY;
		ChangeLight(missile[v1]._mlid, v4, y, missile[v1]._miAnimFrame);
		if ( !CheckBlock(fx, fy, v4, y) )
			CheckMissileCol(ia, v2, v2, 1u, v4, y, 1, v13);
		my = y + 1;
		if ( !CheckBlock(fx, fy, v4, y + 1) )
			CheckMissileCol(ia, v2, v2, 1u, v4, my, 1, v14);
		tya = y - 1;
		if ( !CheckBlock(fx, fy, v4, y - 1) )
			CheckMissileCol(ia, v2, v2, 1u, v4, tya, 1, v15);
		if ( !CheckBlock(fx, fy, v4 + 1, y) )
			CheckMissileCol(ia, v2, v2, 1u, v4 + 1, y, 1, v16);
		if ( !CheckBlock(fx, fy, v4 + 1, tya) )
			CheckMissileCol(ia, v2, v2, 1u, v4 + 1, tya, 1, tya);
		if ( !CheckBlock(fx, fy, v4 + 1, my) )
			CheckMissileCol(ia, v2, v2, 1u, v4 + 1, my, 1, my);
		v5 = v4 - 1;
		if ( !CheckBlock(fx, fy, v5, y) )
			CheckMissileCol(ia, v2, v2, 1u, v5, y, 1, fx);
		if ( !CheckBlock(mya, fy, v5, mya) )
			CheckMissileCol(ia, v2, v2, 1u, v5, myb, 1, fy);
		if ( !CheckBlock(fxa, tyb, v5, tyb) )
			CheckMissileCol(ia, v2, v2, 1u, v5, tyb, 1, ia);
		if ( !missile[v1]._mirange )
		{
			v6 = missile[v1]._mlid;
			missile[v1]._miDelFlag = 1;
			AddUnLight(v6);
		}
	}
	else
	{
		missile[v1]._mitxoff += missile[v1]._mixvel;
		missile[v1]._mityoff += missile[v1]._miyvel;
		GetMissilePos(i);
		v7 = missile[v1]._mix;
		ya = missile[v1]._miy;
		CheckMissileCol(ia, v2, v2, 0, missile[v1]._mix, ya, 0, v13);
		if ( !missile[v1]._miVar3 && v7 == missile[v1]._miVar4 && ya == missile[v1]._miVar5 )
			missile[v1]._miVar3 = 1;
		if ( missile[v1]._miVar3 == 1 )
		{
			missile[v1]._miVar3 = 2;
			missile[v1]._mirange = 255;
			v8 = FindClosest(v7, ya, 19);
			if ( v8 <= 0 )
			{
				v11 = plr[ty]._pdir;
				SetMissDir(ia, plr[ty]._pdir);
				GetMissileVel(ia, v7, ya, v7 + XDirAdd[v11], ya + YDirAdd[v11], 16);
			}
			else
			{
				v9 = v8;
				v10 = GetDirection8(v7, ya, monster[v8]._mx, monster[v8]._my);
				SetMissDir(ia, v10);
				GetMissileVel(ia, v7, ya, monster[v9]._mx, monster[v9]._my, 16);
			}
		}
		if ( v7 != missile[v1]._miVar1 || ya != missile[v1]._miVar2 )
		{
			missile[v1]._miVar2 = ya;
			v12 = missile[v1]._mlid;
			missile[v1]._miVar1 = v7;
			ChangeLight(v12, v7, ya, 8);
		}
		if ( !missile[v1]._mirange )
		{
			missile[v1]._mimfnum = 0;
			SetMissAnim(ia, MFILE_BIGEXP);
			missile[v1]._mirange = missile[v1]._miAnimLen - 1;
		}
	}
	PutMissile(ia);
}

//----- (00430A98) --------------------------------------------------------
void __fastcall MI_Bonespirit(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // eax
	int v4; // ecx
	int v5; // ecx
	int v6; // edi
	int v7; // ebx
	int v8; // eax
	int v9; // edi
	int v10; // ST14_4
	int v11; // ST10_4
	int v12; // eax
	int v13; // ST24_4
	int v14; // ecx
	bool v15; // [esp-4h] [ebp-20h]
	int v16; // [esp+Ch] [ebp-10h]
	int maxdam; // [esp+10h] [ebp-Ch]
	int y1; // [esp+14h] [ebp-8h]
	int ia; // [esp+18h] [ebp-4h]

	v1 = i;
	v2 = i;
	ia = i;
	v3 = missile[i]._midam;
	--missile[v2]._mirange;
	maxdam = v3;
	v16 = missile[i]._misource;
	if ( missile[i]._mimfnum == 8 )
	{
		ChangeLight(missile[v2]._mlid, missile[v2]._mix, missile[v2]._miy, missile[v2]._miAnimFrame);
		if ( !missile[v2]._mirange )
		{
			v4 = missile[v2]._mlid;
			missile[v2]._miDelFlag = 1;
			AddUnLight(v4);
		}
		v5 = v1;
	}
	else
	{
		missile[v2]._mitxoff += missile[v2]._mixvel;
		missile[v2]._mityoff += missile[v2]._miyvel;
		GetMissilePos(i);
		v6 = missile[v2]._miy;
		v7 = missile[v2]._mix;
		y1 = missile[v2]._miy;
		CheckMissileCol(ia, maxdam, maxdam, 0, missile[v2]._mix, v6, 0, v15);
		if ( !missile[v2]._miVar3 && v7 == missile[v2]._miVar4 && v6 == missile[v2]._miVar5 )
			missile[v2]._miVar3 = 1;
		if ( missile[v2]._miVar3 == 1 )
		{
			missile[v2]._miVar3 = 2;
			missile[v2]._mirange = 255;
			v8 = FindClosest(v7, v6, 19);
			if ( v8 <= 0 )
			{
				v13 = plr[v16]._pdir;
				SetMissDir(ia, v13);
				GetMissileVel(ia, v7, v6, v7 + XDirAdd[v13], v6 + YDirAdd[v13], 16);
			}
			else
			{
				v9 = v8;
				v10 = monster[v8]._my;
				v11 = monster[v8]._mx;
				missile[v2]._midam = monster[v8]._mhitpoints >> 7;
				v12 = GetDirection8(v7, y1, v11, v10);
				SetMissDir(ia, v12);
				GetMissileVel(ia, v7, y1, monster[v9]._mx, monster[v9]._my, 16);
				v6 = y1;
			}
		}
		if ( v7 != missile[v2]._miVar1 || v6 != missile[v2]._miVar2 )
		{
			v14 = missile[v2]._mlid;
			missile[v2]._miVar1 = v7;
			missile[v2]._miVar2 = v6;
			ChangeLight(v14, v7, v6, 8);
		}
		if ( !missile[v2]._mirange )
		{
			SetMissDir(ia, 8);
			missile[v2]._mirange = 7;
		}
		v5 = ia;
	}
	PutMissile(v5);
}

//----- (00430C8D) --------------------------------------------------------
void __fastcall MI_ResurrectBeam(int i)
{
	int v1; // eax
	bool v2; // zf

	v1 = i;
	v2 = missile[i]._mirange == 1;
	--missile[v1]._mirange;
	if ( v2 )
		missile[v1]._miDelFlag = 1;
	PutMissile(i);
}

//----- (00430CAC) --------------------------------------------------------
void __fastcall MI_Rportal(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	int r; // [esp+8h] [ebp-48h]
	int v5; // [esp+Ch] [ebp-44h]
	int v6; // [esp+10h] [ebp-40h]
	int v7; // [esp+14h] [ebp-3Ch]
	int v8; // [esp+18h] [ebp-38h]
	int v9; // [esp+1Ch] [ebp-34h]
	int v10; // [esp+20h] [ebp-30h]
	int v11; // [esp+24h] [ebp-2Ch]
	int v12; // [esp+28h] [ebp-28h]
	int v13; // [esp+2Ch] [ebp-24h]
	int v14; // [esp+30h] [ebp-20h]
	int v15; // [esp+34h] [ebp-1Ch]
	int v16; // [esp+38h] [ebp-18h]
	int v17; // [esp+3Ch] [ebp-14h]
	int v18; // [esp+40h] [ebp-10h]
	int v19; // [esp+44h] [ebp-Ch]
	int v20; // [esp+48h] [ebp-8h]
	int ia; // [esp+4Ch] [ebp-4h]

	v1 = i;
	v18 = 15;
	v19 = 15;
	v20 = 15;
	v2 = missile[i]._mirange;
	ia = i;
	r = 1;
	v5 = 2;
	v6 = 3;
	v7 = 4;
	v8 = 5;
	v9 = 6;
	v10 = 7;
	v11 = 8;
	v12 = 9;
	v13 = 10;
	v14 = 11;
	v15 = 12;
	v16 = 13;
	v17 = 14;
	if ( v2 > 1 )
		missile[v1]._mirange = v2 - 1;
	if ( missile[v1]._mirange == missile[v1]._miVar1 )
		SetMissDir(i, 1);
	if ( currlevel && missile[v1]._mimfnum != 1 )
	{
		if ( !missile[v1]._mirange )
		{
LABEL_12:
			v3 = missile[v1]._mlid;
			missile[v1]._miDelFlag = 1;
			AddUnLight(v3);
			goto LABEL_13;
		}
		if ( !missile[v1]._miVar2 )
			missile[v1]._mlid = AddLight(missile[v1]._mix, missile[v1]._miy, 1);
		ChangeLight(missile[v1]._mlid, missile[v1]._mix, missile[v1]._miy, *(&r + missile[v1]._miVar2));
		++missile[v1]._miVar2;
	}
	if ( !missile[v1]._mirange )
		goto LABEL_12;
LABEL_13:
	PutMissile(ia);
}

//----- (00430DDA) --------------------------------------------------------
void __cdecl ProcessMissiles()
{
	int v0; // eax
	int i; // edx
	int v2; // ecx
	int v3; // edx
	int v4; // edi
	int v5; // esi
	int *v6; // eax
	int v7; // ecx
	int *v8; // eax
	int v9; // esi
	int v10; // esi
	int v11; // edx

	v0 = nummissiles;
	for ( i = 0; i < v0; dMissile[0][v2] = 0 )
	{
		v2 = 112 * missile[missileactive[i]]._mix + missile[missileactive[i]]._miy;
		dFlags[0][v2] &= 0xFEu;
		++i;
	}
	v3 = 0;
	while ( v3 < v0 )
	{
		if ( missile[missileactive[v3]]._miDelFlag )
		{
			DeleteMissile(missileactive[v3], v3);
			v0 = nummissiles;
			v3 = 0;
		}
		else
		{
			++v3;
		}
	}
	v4 = 0;
	MissilePreFlag = 0;
	ManashieldFlag = 0;
	if ( v0 > 0 )
	{
		do
		{
			v5 = missileactive[v4];
			missiledata[missile[v5]._mitype].mProc(missileactive[v4]);
			if ( !(missile[v5]._miAnimFlags & 2) )
			{
				v6 = &missile[v5]._miAnimCnt;
				++*v6;
				if ( missile[v5]._miAnimCnt >= missile[v5]._miAnimDelay )
				{
					v7 = missile[v5]._miAnimAdd;
					*v6 = 0;
					v8 = &missile[v5]._miAnimFrame;
					v9 = missile[v5]._miAnimLen;
					*v8 += v7;
					if ( *v8 > v9 )
						*v8 = 1;
					if ( *v8 < 1 )
						*v8 = v9;
				}
			}
			v0 = nummissiles;
			++v4;
		}
		while ( v4 < nummissiles );
		if ( ManashieldFlag )
		{
			v10 = 0;
			if ( nummissiles > 0 )
			{
				do
				{
					if ( missile[missileactive[v10]]._mitype == 13 )
					{
						MI_Manashield(missileactive[v10]);
						v0 = nummissiles;
					}
					++v10;
				}
				while ( v10 < v0 );
			}
		}
	}
	v11 = 0;
	while ( v11 < v0 )
	{
		if ( missile[missileactive[v11]]._miDelFlag )
		{
			DeleteMissile(missileactive[v11], v11);
			v0 = nummissiles;
			v11 = 0;
		}
		else
		{
			++v11;
		}
	}
}
// 64CCD4: using guessed type int MissilePreFlag;

//----- (00430F35) --------------------------------------------------------
void __cdecl missiles_process_charge()
{
	int v0; // ebx
	int i; // edi
	int v2; // ecx
	int v3; // esi
	bool v4; // zf
	CMonster *v5; // eax
	char v6; // dl
	int v7; // eax

	v0 = nummissiles;
	for ( i = 0; i < v0; ++i )
	{
		v2 = missileactive[i];
		v3 = missile[v2]._mimfnum;
		v4 = missile[v2]._mitype == MIS_RHINO;
		missile[v2]._miAnimCel = misfiledata[0].mAnimCel[v3 + 59 * _LOBYTE(missile[v2]._miAnimType)];
		if ( v4 )
		{
			v5 = monster[missile[v2]._misource].MType;
			v6 = v5->mtype;
			if ( v5->mtype < MON_RHINOA || v6 > MON_RHINOD )
			{
				if ( v6 < MON_SNAKEA || v6 > MON_SNAKED )
					v7 = (int)v5->Anims[1].Frames;
				else
					v7 = (int)v5->Anims[2].Frames;
			}
			else
			{
				v7 = (int)v5->Anims[5].Frames;
			}
			missile[v2]._miAnimCel = *(_DWORD *)(v7 + 4 * v3 + 4);
		}
	}
}

//----- (00430FB9) --------------------------------------------------------
void __fastcall ClearMissileSpot(int i)
{
	int v1; // eax

	v1 = missile[i]._miy + 112 * missile[i]._mix;
	dFlags[0][v1] &= 0xFEu;
	dMissile[0][v1] = 0;
}

//----- (00430FE4) --------------------------------------------------------
void __cdecl monster_cpp_init()
{
	monster_cpp_init_value = monster_inf;
}
// 47F130: using guessed type int monster_inf;
// 64CCE4: using guessed type int monster_cpp_init_value;

//----- (00430FEF) --------------------------------------------------------
void __fastcall monster_init_special(int mon_id, int special)
{
	int v2; // esi
	signed int v3; // ecx
	int v4; // esi
	_BYTE *v5; // eax
	int v6; // ebp
	unsigned char v7; // al
	int v8; // edi
	int *v9; // ebx
	signed int v10; // [esp+8h] [ebp-8h]
	int v11; // [esp+Ch] [ebp-4h]

	v2 = mon_id;
	v3 = 256;
	v4 = v2;
	v5 = (unsigned char *)Monsters[v4].trans_file;
	do
	{
		if ( *v5 == -1 )
			*v5 = 0;
		++v5;
		--v3;
	}
	while ( v3 );
	v6 = 0;
	v11 = (special != 0) + 5;
	if ( v11 > 0 )
	{
		do
		{
			if ( v6 != 1 || (v7 = Monsters[v4].mtype, v7 < MON_MAGEA) || v7 > MON_MAGED )
			{
				v10 = 8;
				v8 = 44 * v6 + v4 * 328;
				v9 = (int *)((char *)&Monsters[0].Anims[0].Frames[1] + v8);
				do
				{
					engine_cel_trn(*v9, (int)Monsters[v4].trans_file, *(int *)((char *)&Monsters[0].Anims[0].Rate + v8));
					++v9;
					--v10;
				}
				while ( v10 );
			}
			++v6;
		}
		while ( v6 < v11 );
	}
}

//----- (0043107B) --------------------------------------------------------
void __cdecl InitLevelMonsters()
{
	char *v0; // eax
	int v1; // eax

	nummtypes = 0;
	monstimgtot = 0;
	MissileFileFlag = 0;
	v0 = &Monsters[0].mPlaceFlags;
	do
	{
		*v0 = 0;
		v0 += 328;
	}
	while ( (signed int)v0 < (signed int)&END_Monsters_17 );
	ClrAllMonsters();
	nummonsters = 0;
	totalmonsters = 200;
	v1 = 0;
	do
	{
		monstactive[v1] = v1;
		++v1;
	}
	while ( v1 < 200 );
	uniquetrans = 0;
}
// 64CCE0: using guessed type int MissileFileFlag;
// 658550: using guessed type int totalmonsters;
// 6599D9: using guessed type int END_Monsters_17;
// 659AE8: using guessed type int monstimgtot;

//----- (004310CF) --------------------------------------------------------
int __fastcall AddMonsterType(int type, int placeflag)
{
	char v2; // bl
	int v3; // eax
	int v4; // esi
	CMonster *v5; // edi
	int v6; // eax
	int v7; // esi

	v2 = placeflag;
	v3 = 0;
	v4 = 0;
	if ( nummtypes > 0 )
	{
		v5 = Monsters;
		do
		{
			if ( v3 )
				break;
			v6 = -(type != (unsigned char)v5->mtype);
			++v5;
			v3 = v6 + 1;
			++v4;
		}
		while ( v4 < nummtypes );
	}
	v7 = v4 - 1;
	if ( !v3 )
	{
		v7 = nummtypes++;
		Monsters[v7].mtype = type;
		monstimgtot += monsterdata[type].mType;
		InitMonsterGFX(v7);
		InitMonsterSND(v7);
	}
	Monsters[v7].mPlaceFlags |= v2;
	return v7;
}
// 659AE8: using guessed type int monstimgtot;

//----- (0043114F) --------------------------------------------------------
void __cdecl GetLevelMTypes()
{
	int v0; // eax
	int v1; // eax
	int v2; // eax
	int v3; // eax
	int v4; // eax
	int v5; // eax
	unsigned char *v6; // esi
	int v7; // edi
	int v8; // ecx
	int v9; // eax
	int v10; // eax
	int v11; // esi
	int v12; // edi
	unsigned char *v13; // ecx
	int i; // esi
	int v15; // ecx
	bool v16; // zf
	int v17; // edx
	int *v18; // eax
	int v19; // esi
	int *v20; // esi
	int v21; // eax
	int v22; // [esp+8h] [ebp-328h]
	int v23[89]; // [esp+Ch] [ebp-324h]
	int v24[111]; // [esp+170h] [ebp-1C0h]
	int max; // [esp+32Ch] [ebp-4h]

	AddMonsterType(109, 2);
	if ( currlevel == 16 )
	{
		AddMonsterType(108, 1);
		AddMonsterType(96, 1);
		AddMonsterType(110, 2);
	}
	else if ( setlevel )
	{
		if ( setlvlnum == SL_SKELKING )
			AddMonsterType(50, 4);
	}
	else
	{
		_LOBYTE(v0) = QuestStatus(6);
		if ( v0 )
			AddMonsterType(51, 2);
		_LOBYTE(v1) = QuestStatus(2);
		if ( v1 )
			AddMonsterType((char)UniqMonst[0].mtype, 4);
		_LOBYTE(v2) = QuestStatus(3);
		if ( v2 )
			AddMonsterType((char)UniqMonst[2].mtype, 4);
		_LOBYTE(v3) = QuestStatus(7);
		if ( v3 )
			AddMonsterType((char)UniqMonst[3].mtype, 4);
		_LOBYTE(v4) = QuestStatus(4);
		if ( v4 )
			AddMonsterType((char)UniqMonst[7].mtype, 4);
		_LOBYTE(v5) = QuestStatus(11);
		if ( v5 )
			AddMonsterType((char)UniqMonst[8].mtype, 4);
		if ( gbMaxPlayers != 1 && currlevel == quests[12]._qlevel )
		{
			AddMonsterType(50, 4);
			max = 0;
			v6 = &monsterdata[8].mMaxDLvl;
			v7 = 8;
			do
			{
				if ( IsSkel(v7) )
				{
					v8 = currlevel;
					if ( currlevel >= 15 * (char)*(v6 - 1) / 30 + 1
					  && currlevel <= 15 * (char)*v6 / 30 + 1
					  && MonstAvailTbl[v7] & 3 )
					{
						v9 = max++;
						v24[v9] = v7;
					}
				}
				v6 += 128;
				++v7;
			}
			while ( (signed int)v6 <= (signed int)&monsterdata[27].mMaxDLvl );
			_LOBYTE(v8) = 88;
			v10 = random(v8, max);
			AddMonsterType(v24[v10], 1);
		}
		v11 = currlevel;
		v12 = 0;
		v13 = &monsterdata[0].mMaxDLvl;
		max = 0;
		do
		{
			if ( v11 >= 15 * (char)*(v13 - 1) / 30 + 1 && v11 <= 15 * (char)*v13 / 30 + 1 && MonstAvailTbl[max] & 3 )
				v23[v12++] = max;
			++max;
			v13 += 128;
		}
		while ( (signed int)v13 < (signed int)&monsterdata[111].mMaxDLvl );
		if ( monstdebug )
		{
			for ( i = 0; i < debugmonsttypes; ++i )
				AddMonsterType(DebugMonsters[i], 1);
		}
		else
		{
			while ( v12 > 0 )
			{
				if ( nummtypes >= 16 || monstimgtot >= 4000 )
					break;
				v15 = 0;
				v16 = v12 == 0;
				if ( v12 > 0 )
				{
					v17 = 4000 - monstimgtot;
					do
					{
						v18 = &v23[v15];
						if ( monsterdata[*v18].mType <= v17 )
						{
							++v15;
						}
						else
						{
							v19 = *(&v22 + v12--);
							*v18 = v19;
						}
					}
					while ( v15 < v12 );
					v16 = v12 == 0;
				}
				if ( !v16 )
				{
					_LOBYTE(v15) = 88;
					v20 = &v23[random(v15, v12)];
					AddMonsterType(*v20, 1);
					v21 = *(&v22 + v12--);
					*v20 = v21;
				}
			}
		}
	}
}
// 525730: using guessed type int monstdebug;
// 52573C: using guessed type int debugmonsttypes;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;
// 659AE8: using guessed type int monstimgtot;
// 679660: using guessed type char gbMaxPlayers;
// 43114F: using guessed type int var_1C0[111];
// 43114F: using guessed type int var_324[89];

//----- (004313F9) --------------------------------------------------------
void __fastcall InitMonsterGFX(int monst)
{
	int v1; // esi
	int v2; // ebx
	int v3; // ebx
	int *v4; // edi
	int *v5; // eax
	char v6; // cl
	unsigned char *v7; // eax
	char v8; // cl
	int *v9; // ecx
	int v10; // edx
	int v11; // ecx
	int v12; // ecx
	bool v13; // zf
	int v14; // ecx
	void **v15; // esi
	unsigned char *v16; // eax
	int v17; // edx
	int v18; // ecx
	void *v19; // ecx
	int v20; // ecx
	int v21; // ecx
	int v22; // ecx
	int v23; // ecx
	int v24; // ecx
	int v25; // ecx
	char strBuff[256]; // [esp+Ch] [ebp-114h]
	int mon_id; // [esp+10Ch] [ebp-14h]
	int *v28; // [esp+110h] [ebp-10h]
	int v29; // [esp+114h] [ebp-Ch]
	int *v30; // [esp+118h] [ebp-8h]
	int v31; // [esp+11Ch] [ebp-4h]

	v29 = 0;
	mon_id = monst;
	v1 = monst;
	v2 = (unsigned char)Monsters[monst].mtype;
	v31 = v2;
	v3 = v2 << 7;
	v4 = &Monsters[monst].Anims[0].Frames[1];
	v5 = (int *)((char *)monsterdata[0].Frames + v3);
	v30 = &Monsters[monst].Anims[0].Frames[1];
	v28 = (int *)((char *)monsterdata[0].Frames + v3);
	do
	{
		v6 = animletter[v29];
		if ( (v6 != 's' || *(int *)((char *)&monsterdata[0].has_special + v3)) && *v5 > 0 )
		{
			sprintf(strBuff, *(const char **)((char *)&monsterdata[0].GraphicType + v3), v6);
			v7 = LoadFileInMem(strBuff, 0);
			*(v4 - 1) = (int)v7;
			if ( Monsters[v1].mtype != MON_GOLEM || (v8 = animletter[v29], v8 != 's') && v8 != 'd' )
			{
				v30 = 0;
				v9 = v4;
				do
				{
					v10 = (int)&v7[*(_DWORD *)&v7[4 * (_DWORD)v30]];
					v30 = (int *)((char *)v30 + 1);
					*v9 = v10;
					++v9;
				}
				while ( (signed int)v30 < 8 );
			}
			else
			{
				memset(v4, (int)v7, 8u);
				v4 = v30;
			}
			v5 = v28;
		}
		v11 = *v5;
		++v29;
		v4[8] = v11;
		v4[9] = v5[6];
		++v5;
		v4 += 11;
		v28 = v5;
		v30 = v4;
	}
	while ( v29 < 6 );
	Monsters[v1].MData = (MonsterData *)((char *)monsterdata + v3);
	v12 = *(int *)((char *)&monsterdata[0].flags + v3);
	Monsters[v1].flags_1 = v12;
	Monsters[v1].flags_2 = (v12 - 64) >> 1;
	Monsters[v1].mMinHP = *((_BYTE *)&monsterdata[0].mMinHP + v3);
	v13 = *(int *)((char *)&monsterdata[0].has_trans + v3) == 0;
	Monsters[v1].mMaxHP = *((_BYTE *)&monsterdata[0].mMaxHP + v3);
	v14 = *(int *)((char *)&monsterdata[0].has_special + v3);
	Monsters[v1].has_special = v14;
	Monsters[v1].mAFNum = *(&monsterdata[0].mAFNum + v3);
	if ( !v13 )
	{
		v15 = &Monsters[v1].trans_file;
		v16 = LoadFileInMem(*(char **)((char *)&monsterdata[0].TransFile + v3), 0);
		v17 = *(int *)((char *)&monsterdata[0].has_special + v3);
		v18 = mon_id;
		*v15 = v16;
		monster_init_special(v18, v17);
		v19 = *v15;
		*v15 = 0;
		mem_free_dbg(v19);
	}
	if ( v31 >= MON_MAGMAA && v31 <= MON_MAGMAD && !(MissileFileFlag & 1) )
	{
		MissileFileFlag |= 1u;
		_LOBYTE(v14) = MFILE_MAGBALL;
		LoadMissileGFX(v14);
	}
	if ( v31 >= MON_THINA && v31 <= MON_THIND && !(MissileFileFlag & 2) )
	{
		MissileFileFlag |= 2u;
		_LOBYTE(v14) = MFILE_THINLGHT;
		LoadMissileGFX(v14);
	}
	if ( v31 == MON_SUCCA )
	{
		if ( MissileFileFlag & 4 )
			return;
		MissileFileFlag |= 4u;
		_LOBYTE(v14) = MFILE_FLARE;
		LoadMissileGFX(v14);
		_LOBYTE(v20) = MFILE_FLAREEXP;
		LoadMissileGFX(v20);
	}
	if ( v31 == MON_SUCCB )
	{
		if ( MissileFileFlag & 0x20 )
			return;
		MissileFileFlag |= 0x20u;
		_LOBYTE(v14) = MFILE_SCUBMISB;
		LoadMissileGFX(v14);
		_LOBYTE(v21) = MFILE_SCBSEXPB;
		LoadMissileGFX(v21);
	}
	if ( v31 == MON_SUCCC )
	{
		if ( MissileFileFlag & 0x40 )
			return;
		MissileFileFlag |= 0x40u;
		_LOBYTE(v14) = MFILE_SCUBMISD;
		LoadMissileGFX(v14);
		_LOBYTE(v22) = MFILE_SCBSEXPD;
		LoadMissileGFX(v22);
	}
	if ( v31 == MON_SUCCD )
	{
		if ( (MissileFileFlag & 0x80u) != 0 )
			return;
		_LOBYTE(MissileFileFlag) = MissileFileFlag | 0x80;
		_LOBYTE(v14) = MFILE_SCUBMISC;
		LoadMissileGFX(v14);
		_LOBYTE(v23) = MFILE_SCBSEXPC;
		LoadMissileGFX(v23);
	}
	if ( v31 >= MON_FIREMANA && v31 <= MON_FIREMAND && !(MissileFileFlag & 8) )
	{
		MissileFileFlag |= 8u;
		_LOBYTE(v14) = MFILE_KRULL;
		LoadMissileGFX(v14);
	}
	if ( v31 >= MON_ACIDA && v31 <= MON_ACIDD && !(MissileFileFlag & 0x10) )
	{
		MissileFileFlag |= 0x10u;
		_LOBYTE(v14) = MFILE_ACIDBF;
		LoadMissileGFX(v14);
		_LOBYTE(v24) = MFILE_ACIDSPLA;
		LoadMissileGFX(v24);
		_LOBYTE(v25) = MFILE_ACIDPUD;
		LoadMissileGFX(v25);
	}
	if ( v31 == MON_DIABLO )
	{
		_LOBYTE(v14) = MFILE_FIREPLAR;
		LoadMissileGFX(v14);
	}
}
// 64CCE0: using guessed type int MissileFileFlag;

//----- (004316AE) --------------------------------------------------------
void __fastcall ClearMVars(int i)
{
	int v1; // ecx

	v1 = i;
	monster[v1]._mVar1 = 0;
	monster[v1]._mVar2 = 0;
	monster[v1]._mVar3 = 0;
	monster[v1]._mVar4 = 0;
	monster[v1]._mVar5 = 0;
	monster[v1]._mVar6 = 0;
	monster[v1]._mVar7 = 0;
	monster[v1]._mVar8 = 0;
}

//----- (004316E7) --------------------------------------------------------
void __fastcall InitMonster(int i, int rd, int mtype, int x, int y)
{
	int v5; // ebx
	int v6; // esi
	CMonster *v7; // edi
	MonsterData *v8; // eax
	char *v9; // ecx
	int v10; // eax
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	bool v14; // zf
	int v15; // ecx
	int v16; // eax
	MonsterData *v17; // eax
	int v18; // eax
	MonsterData *v19; // eax
	short v20; // cx
	int v21; // edx
	int v22; // edx
	int v23; // edi
	int v24; // ecx
	int v25; // ecx
	char v26; // dl
	int v27; // ecx
	char v28; // dl

	v5 = rd;
	v6 = i;
	monster[v6]._mmode = MM_STAND;
	v7 = &Monsters[mtype];
	monster[v6]._mx = x;
	monster[v6]._mfutx = x;
	monster[v6]._moldx = x;
	v8 = v7->MData;
	monster[v6]._mdir = rd;
	monster[v6]._my = y;
	monster[v6]._mfuty = y;
	monster[v6]._moldy = y;
	monster[v6]._mMTidx = mtype;
	v9 = v8->mName;
	monster[v6].mName = v9;
	monster[v6].MType = v7;
	monster[v6].MData = v8;
	monster[v6]._mAFNum = v7->Anims[0].Frames[rd + 1];
	v10 = v7->Anims[0].Delay;
	_LOBYTE(v9) = 88;
	monster[v6]._mAnimDelay = v10;
	monster[v6]._mAnimCnt = random((int)v9, v10 - 1);
	v11 = v7->Anims[0].Rate;
	_LOBYTE(v12) = 88;
	monster[v6]._mAnimLen = v11;
	v13 = random(v12, v11 - 1);
	v14 = v7->mtype == 110;
	monster[v6]._mAnimFrame = v13 + 1;
	_LOBYTE(v15) = 88;
	if ( v14 )
		v16 = random(v15, 1) + 1666;
	else
		v16 = (unsigned char)v7->mMinHP + random(v15, (unsigned char)v7->mMaxHP - (unsigned char)v7->mMinHP + 1);
	v14 = gbMaxPlayers == 1;
	monster[v6]._mmaxhp = v16 << 6;
	if ( v14 )
	{
		monster[v6]._mmaxhp >>= 1;
		if ( monster[v6]._mmaxhp < 64 )
			monster[v6]._mmaxhp = 64;
	}
	monster[v6]._mhitpoints = monster[v6]._mmaxhp;
	v17 = v7->MData;
	monster[v6]._mAi = v17->mAi;
	monster[v6]._mint = v17->mInt;
	_LOBYTE(monster[v6]._pathcount) = 0;
	monster[v6]._uniqtype = 0;
	_LOBYTE(monster[v6]._msquelch) = 0;
	_LOBYTE(monster[v6]._mgoal) = 1;
	monster[v6]._mgoalvar1 = 0;
	monster[v6]._mgoalvar2 = 0;
	monster[v6]._mgoalvar3 = 0;
	monster[v6].field_18 = 0;
	monster[v6]._mDelFlag = 0;
	monster[v6]._mRndSeed = GetRndSeed();
	v18 = GetRndSeed();
	monster[v6].mWhoHit = 0;
	monster[v6]._mAISeed = v18;
	v19 = v7->MData;
	_LOBYTE(monster[v6].mLevel) = v19->mLevel;
	monster[v6].mExp = v19->mExp;
	monster[v6].mHit = v19->mHit;
	monster[v6].mMinDamage = v19->mMinDamage;
	monster[v6].mMaxDamage = v19->mMaxDamage;
	monster[v6].mHit2 = v19->mHit2;
	monster[v6].mMinDamage2 = v19->mMinDamage2;
	monster[v6].mMaxDamage2 = v19->mMaxDamage2;
	monster[v6].mArmorClass = v19->mArmorClass;
	v20 = v19->mMagicRes;
	monster[v6].leader = 0;
	monster[v6].leaderflag = 0;
	_LOWORD(monster[v6].mMagicRes) = v20;
	v21 = v19->mFlags;
	monster[v6].mtalkmsg = 0;
	v14 = monster[v6]._mAi == MG_GARG;
	monster[v6]._mFlags = v21;
	if ( v14 )
	{
		v22 = v7->Anims[5].Frames[v5 + 1];
		monster[v6]._mFlags |= 4u;
		monster[v6]._mAFNum = v22;
		monster[v6]._mAnimFrame = 1;
		monster[v6]._mmode = MM_SATTACK;
	}
	v23 = gnDifficulty;
	if ( gnDifficulty == DIFF_NIGHTMARE )
	{
		v24 = monster[v6]._mmaxhp;
		_LOBYTE(monster[v6].mLevel) += 15;
		monster[v6].mHit += 85;
		monster[v6].mHit2 += 85;
		v25 = 3 * v24 + 64;
		monster[v6]._mmaxhp = v25;
		monster[v6]._mhitpoints = v25;
		monster[v6].mExp = 2 * (monster[v6].mExp + 1000);
		monster[v6].mMinDamage = 2 * (monster[v6].mMinDamage + DIFF_HELL);
		monster[v6].mMaxDamage = 2 * (monster[v6].mMaxDamage + DIFF_HELL);
		monster[v6].mMinDamage2 = 2 * (monster[v6].mMinDamage2 + DIFF_HELL);
		_LOBYTE(v25) = 2 * (monster[v6].mMaxDamage2 + DIFF_HELL);
		monster[v6].mArmorClass += 50;
		monster[v6].mMaxDamage2 = v25;
	}
	if ( v23 == DIFF_HELL )
	{
		v26 = 4 * monster[v6].mMinDamage;
		v27 = 4 * monster[v6]._mmaxhp + 192;
		_LOBYTE(monster[v6].mLevel) += 30;
		monster[v6]._mmaxhp = v27;
		monster[v6]._mhitpoints = v27;
		_LOWORD(v27) = monster[v6].mExp;
		monster[v6].mHit += 120;
		monster[v6].mHit2 += 120;
		monster[v6].mExp = 4 * (v27 + 1000);
		monster[v6].mMinDamage = v26 + 6;
		monster[v6].mMaxDamage = 4 * monster[v6].mMaxDamage + 6;
		monster[v6].mMinDamage2 = 4 * monster[v6].mMinDamage2 + 6;
		v28 = 4 * monster[v6].mMaxDamage2 + 6;
		monster[v6].mArmorClass += 80;
		monster[v6].mMaxDamage2 = v28;
		_LOWORD(monster[v6].mMagicRes) = v19->mMagicRes2;
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00431A6B) --------------------------------------------------------
void __cdecl ClrAllMonsters()
{
	int v0; // edi
	int *v1; // esi
	int v2; // ecx
	int v3; // eax
	int v4; // edx
	int v5; // ecx
	int v6; // eax
	char v7; // cl

	v0 = 0;
	v1 = &monster[0]._mgoal;
	do
	{
		ClearMVars(v0);
		_LOBYTE(v2) = 89;
		v1[52] = (int)"Invalid Monster";
		*(_BYTE *)v1 = 0;
		*(v1 - 1) = 0;
		v1[26] = 0;
		v1[27] = 0;
		v1[6] = 0;
		v1[7] = 0;
		v1[8] = 0;
		v1[9] = 0;
		v1[10] = 0;
		v1[11] = 0;
		v3 = random(v2, 8);
		v4 = (unsigned char)gbActivePlayers;
		_LOBYTE(v5) = 89;
		v1[16] = v3;
		v1[14] = 0;
		v1[15] = 0;
		v1[19] = 0;
		v1[20] = 0;
		v1[21] = 0;
		v1[22] = 0;
		v1[23] = 0;
		v1[37] = 0;
		v1[25] = 0;
		v6 = random(v5, v4);
		v1[17] = v6;
		v6 *= 21720;
		v7 = *((_BYTE *)&plr[0]._px + v6);
		_LOBYTE(v6) = *((_BYTE *)&plr[0]._py + v6);
		*((_BYTE *)v1 + 72) = v7;
		*((_BYTE *)v1 + 73) = v6;
		v1 += 57;
		++v0;
	}
	while ( (signed int)v1 < (signed int)Monsters );
}
// 67862C: using guessed type char gbActivePlayers;

//----- (00431B10) --------------------------------------------------------
int __fastcall MonstPlace(int xp, int yp)
{
	int v2; // eax
	char v3; // al
	int result; // eax

	if ( xp < 0
	  || xp >= 112
	  || yp < 0
	  || yp >= 112
	  || (v2 = xp, dMonster[0][112 * xp + yp])
	  || dPlayer[v2][yp]
	  || (v3 = dFlags[v2][yp], v3 & 2)
	  || v3 & 8 )
	{
		result = 0;
	}
	else
	{
		result = SolidLoc(xp, yp) == 0;
	}
	return result;
}

//----- (00431B5D) --------------------------------------------------------
void __fastcall PlaceMonster(int i, int mtype, int x, int y)
{
	int v4; // esi
	int v5; // ecx
	int v6; // edi
	int v7; // eax

	v4 = i;
	v5 = y + 112 * x;
	v6 = mtype;
	dMonster[0][v5] = v4 + 1;
	_LOBYTE(v5) = 90;
	v7 = random(v5, 8);
	InitMonster(v4, v7, v6, x, y);
}

//----- (00431B99) --------------------------------------------------------
void __fastcall PlaceUniqueMonst(int uniqindex, int miniontype, int unpackfilesize)
{
	MonsterStruct *v3; // esi
	CMonster *v4; // ecx
	int v5; // edx
	int v6; // eax
	int v7; // ecx
	int v8; // edi
	int v9; // eax
	int v10; // ebx
	int v11; // eax
	int i; // edx
	int v13; // edx
	BOOL v14; // edx
	int (*v15)[112]; // ecx
	int (*v16)[112]; // eax
	int v17; // edi
	char v18; // al
	char *v19; // eax
	int v20; // eax
	bool v21; // zf
	signed int v22; // eax
	char v23; // cl
	char v24; // al
	int v25; // edx
	int v26; // eax
	int v27; // ecx
	char v28; // al
	char v29; // al
	int v30; // ecx
	int v31; // eax
	int v32; // eax
	int v33; // eax
	int v34; // eax
	char v35; // al
	short v36; // cx
	char v37; // al
	int v38; // ecx
	int v39; // eax
	int v40; // edx
	int v41; // eax
	char arglist[64]; // [esp+4h] [ebp-60h]
	int v43; // [esp+44h] [ebp-20h]
	CMonster *v44; // [esp+48h] [ebp-1Ch]
	int v45; // [esp+4Ch] [ebp-18h]
	int *v46; // [esp+50h] [ebp-14h]
	int v47; // [esp+54h] [ebp-10h]
	int v48; // [esp+58h] [ebp-Ch]
	int mtype; // [esp+5Ch] [ebp-8h]
	int xp; // [esp+60h] [ebp-4h]

	v46 = 0;
	v48 = uniqindex;
	v3 = &monster[nummonsters];
	v4 = (CMonster *)&UniqMonst[uniqindex];
	v43 = miniontype;
	v44 = v4;
	if ( (uniquetrans + 19) << 8 < 6912 )
	{
		mtype = 0;
		if ( nummtypes > 0 )
		{
			v5 = v4->mtype;
			v4 = Monsters;
			do
			{
				if ( (unsigned char)v4->mtype == v5 )
					break;
				++mtype;
				++v4;
			}
			while ( mtype < nummtypes );
		}
		do
		{
			do
			{
				_LOBYTE(v4) = 91;
				v6 = random((int)v4, 80);
				_LOBYTE(v7) = 91;
				v8 = v6 + 16;
				v9 = random(v7, 80);
				v47 = 0;
				v4 = (CMonster *)(v8 - 3);
				v10 = v9 + 16;
				xp = v8 - 3;
				if ( __OFSUB__(v8 - 3, v8 + 3) ^ 1 )
				{
					v11 = v9 + 19;
					do
					{
						for ( i = v10 - 3; ; i = v45 + 1 )
						{
							v45 = i;
							if ( i >= v11 )
								break;
							if ( i >= 0 && i < 112 && xp >= 0 && xp < 112 && MonstPlace(xp, i) )
								++v47;
							v11 = v10 + 3;
						}
						++xp;
						v4 = (CMonster *)(v8 + 3);
					}
					while ( xp < v8 + 3 );
					if ( v47 >= 9 )
						break;
				}
				v46 = (int *)((char *)v46 + 1);
			}
			while ( (signed int)v46 < 1000 );
		}
		while ( !MonstPlace(v8, v10) );
		v13 = v48;
		if ( v48 == 3 )
		{
			v8 = 2 * setpc_x + 24;
			v10 = 2 * setpc_y + 28;
		}
		if ( v48 == 8 )
		{
			v8 = 2 * setpc_x + 22;
			v10 = 2 * setpc_y + 23;
		}
		if ( v48 == 2 )
		{
			xp = 0;
			v45 = 1;
			if ( themeCount > 0 )
			{
				v46 = &themeLoc[0].y;
				do
				{
					if ( xp == zharlib && v45 == 1 )
					{
						v45 = 0;
						v8 = 2 * *(v46 - 1) + 20;
						v10 = 2 * *v46 + 20;
					}
					++xp;
					v46 += 5;
				}
				while ( xp < themeCount );
			}
			v13 = v48;
		}
		if ( gbMaxPlayers == 1 )
		{
			if ( v13 == 4 )
			{
				v8 = 32;
				v10 = 46;
			}
			if ( v13 == 5 )
			{
				v8 = 40;
				v10 = 45;
			}
			if ( v13 == 6 )
			{
				v8 = 38;
				v10 = 49;
			}
			if ( v13 == 1 )
			{
				v8 = 35;
				v10 = 47;
			}
		}
		else
		{
			if ( v13 == 4 )
			{
				v8 = 2 * setpc_x + 19;
				v10 = 2 * setpc_y + 22;
			}
			if ( v13 == 5 )
			{
				v8 = 2 * setpc_x + 21;
				v10 = 2 * setpc_y + 19;
			}
			if ( v13 == 6 )
			{
				v8 = 2 * setpc_x + 21;
				v10 = 2 * setpc_y + 25;
			}
		}
		if ( v13 == 9 )
		{
			v14 = 0;
			v10 = 0;
			v15 = dPiece;
			do
			{
				if ( v14 )
					break;
				v8 = 0;
				v16 = v15;
				do
				{
					if ( v14 )
						break;
					v14 = (*v16)[0] == 367;
					++v8;
					++v16;
				}
				while ( v8 < 112 );
				v15 = (int (*)[112])((char *)v15 + 4);
				++v10;
			}
			while ( (signed int)v15 < (signed int)dPiece[1] );
		}
		PlaceMonster(nummonsters, mtype, v8, v10);
		v17 = (int)v44;
		v3->_uniqtype = v48 + 1;
		v18 = *(_BYTE *)(v17 + 12);
		if ( v18 )
			_LOBYTE(v3->mLevel) = 2 * v18;
		else
			_LOBYTE(v3->mLevel) += 5;
		v19 = *(char **)(v17 + 4);
		v3->mExp *= 2;
		v3->mName = v19;
		v20 = *(unsigned short *)(v17 + 14) << 6;
		v21 = gbMaxPlayers == 1;
		v3->_mmaxhp = v20;
		if ( v21 )
		{
			v22 = v20 >> 1;
			v3->_mmaxhp = v22;
			if ( v22 < 64 )
				v3->_mmaxhp = 64;
		}
		v23 = *(_BYTE *)(v17 + 19);
		v3->_mhitpoints = v3->_mmaxhp;
		v3->_mAi = *(_BYTE *)(v17 + 16);
		v3->_mint = *(_BYTE *)(v17 + 17);
		v24 = *(_BYTE *)(v17 + 18);
		v25 = v3->_my;
		v3->mMinDamage = v24;
		v3->mMinDamage2 = v24;
		_LOWORD(v3->mMagicRes) = *(_WORD *)(v17 + 20);
		v26 = *(_DWORD *)(v17 + 28);
		v3->mMaxDamage = v23;
		v3->mMaxDamage2 = v23;
		v27 = v3->_mx;
		v3->mtalkmsg = v26;
		v28 = AddLight(v27, v25, 3);
		v21 = gbMaxPlayers == 1;
		v3->mlid = v28;
		if ( v21 )
			goto LABEL_83;
		v29 = v3->_mAi;
		if ( v29 == 29 )
			v3->mtalkmsg = 0;
		if ( v29 != 28 || quests[15]._qvar1 <= 3u )
		{
LABEL_83:
			if ( v3->mtalkmsg )
				_LOBYTE(v3->_mgoal) = 6;
		}
		else
		{
			_LOBYTE(v3->_mgoal) = 1;
		}
		v30 = gnDifficulty;
		if ( gnDifficulty == DIFF_NIGHTMARE )
		{
			v31 = v3->_mmaxhp;
			_LOBYTE(v3->mLevel) += 15;
			v32 = 3 * v31 + 64;
			v3->_mmaxhp = v32;
			v3->_mhitpoints = v32;
			v3->mExp = 2 * (v3->mExp + 1000);
			v3->mMinDamage = 2 * (v3->mMinDamage + 2);
			v3->mMaxDamage = 2 * (v3->mMaxDamage + 2);
			v3->mMinDamage2 = 2 * (v3->mMinDamage2 + 2);
			v3->mMaxDamage2 = 2 * (v3->mMaxDamage2 + 2);
		}
		if ( v30 == DIFF_HELL )
		{
			v33 = v3->_mmaxhp;
			_LOBYTE(v3->mLevel) += 30;
			v34 = 4 * v33 + 192;
			v3->_mmaxhp = v34;
			v3->_mhitpoints = v34;
			v3->mExp = 4 * (v3->mExp + 1000);
			v3->mMinDamage = 4 * v3->mMinDamage + 6;
			v3->mMaxDamage = 4 * v3->mMaxDamage + 6;
			v3->mMinDamage2 = 4 * v3->mMinDamage2 + 6;
			v3->mMaxDamage2 = 4 * v3->mMaxDamage2 + 6;
		}
		sprintf(arglist, "Monsters\\Monsters\\%s.TRN", *(_DWORD *)(v17 + 8));
		LoadFileWithMem(arglist, (void *)(dword_646A20 + ((uniquetrans + 19) << 8)));
		v35 = uniquetrans;
		v36 = *(_WORD *)(v17 + 22);
		++uniquetrans;
		v3->_uniqtrans = v35;
		if ( v36 & 4 )
		{
			v37 = *(_BYTE *)(v17 + 24);
			v3->mHit = v37;
			v3->mHit2 = v37;
		}
		if ( v36 & 8 )
			v3->mArmorClass = *(_BYTE *)(v17 + 24);
		++nummonsters;
		if ( v36 & 1 )
			PlaceGroup(v43, unpackfilesize, v36, nummonsters - 1);
		if ( v3->_mAi != 12 )
		{
			v38 = (int)v3->MType;
			v39 = *(_DWORD *)(v38 + 4 * v3->_mdir + 8);
			v40 = v3->_mAnimLen - 1;
			_LOBYTE(v38) = 88;
			v3->_mAFNum = v39;
			v41 = random(v38, v40);
			v3->_mFlags &= 0xFFFFFFFB;
			v3->_mmode = 0;
			v3->_mAnimFrame = v41 + 1;
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;
// 6AAA64: using guessed type int zharlib;

//----- (00432088) --------------------------------------------------------
void __cdecl PlaceQuestMonsters()
{
	int v0; // eax
	int v1; // esi
	CMonster *v2; // edi
	int v3; // eax
	unsigned char *v4; // esi
	int v5; // eax
	unsigned char *v6; // esi
	int v7; // eax
	unsigned char *v8; // esi
	int v9; // eax
	unsigned char *v10; // esi
	int v11; // eax
	unsigned char *v12; // esi
	int v13; // eax
	int v14; // eax
	unsigned char *v15; // esi

	if ( setlevel )
	{
		if ( setlvlnum == SL_SKELKING )
			PlaceUniqueMonst(1, 0, 0);
	}
	else
	{
		_LOBYTE(v0) = QuestStatus(6);
		if ( v0 )
			PlaceUniqueMonst(9, 0, 0);
		if ( currlevel == quests[12]._qlevel && gbMaxPlayers != 1 )
		{
			v1 = 0;
			if ( nummtypes > 0 )
			{
				v2 = Monsters;
				do
				{
					if ( IsSkel((unsigned char)v2->mtype) )
						break;
					++v1;
					++v2;
				}
				while ( v1 < nummtypes );
			}
			PlaceUniqueMonst(1, v1, 30);
		}
		_LOBYTE(v3) = QuestStatus(7);
		if ( v3 )
		{
			v4 = LoadFileInMem("Levels\\L1Data\\Banner1.DUN", 0);
			SetMapMonsters((char *)v4, 2 * setpc_x, 2 * setpc_y);
			mem_free_dbg(v4);
		}
		_LOBYTE(v5) = QuestStatus(9);
		if ( v5 )
		{
			v6 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0);
			SetMapMonsters((char *)v6, 2 * setpc_x, 2 * setpc_y);
			mem_free_dbg(v6);
		}
		_LOBYTE(v7) = QuestStatus(8);
		if ( v7 )
		{
			v8 = LoadFileInMem("Levels\\L2Data\\Blind2.DUN", 0);
			SetMapMonsters((char *)v8, 2 * setpc_x, 2 * setpc_y);
			mem_free_dbg(v8);
		}
		_LOBYTE(v9) = QuestStatus(10);
		if ( v9 )
		{
			v10 = LoadFileInMem("Levels\\L3Data\\Anvil.DUN", 0);
			SetMapMonsters((char *)v10, 2 * setpc_x + 2, 2 * setpc_y + 2);
			mem_free_dbg(v10);
		}
		_LOBYTE(v11) = QuestStatus(11);
		if ( v11 )
		{
			v12 = LoadFileInMem("Levels\\L4Data\\Warlord.DUN", 0);
			SetMapMonsters((char *)v12, 2 * setpc_x, 2 * setpc_y);
			mem_free_dbg(v12);
			AddMonsterType((char)UniqMonst[8].mtype, 1);
		}
		_LOBYTE(v13) = QuestStatus(4);
		if ( v13 )
			AddMonsterType((char)UniqMonst[7].mtype, 1);
		_LOBYTE(v14) = QuestStatus(3);
		if ( v14 && zharlib == -1 )
			quests[3]._qactive = 0;
		if ( currlevel == quests[15]._qlevel && gbMaxPlayers != 1 )
		{
			AddMonsterType((char)UniqMonst[4].mtype, 4);
			AddMonsterType((char)UniqMonst[5].mtype, 4);
			PlaceUniqueMonst(4, 0, 0);
			PlaceUniqueMonst(5, 0, 0);
			PlaceUniqueMonst(6, 0, 0);
			v15 = LoadFileInMem("Levels\\L4Data\\Vile1.DUN", 0);
			SetMapMonsters((char *)v15, 2 * setpc_x, 2 * setpc_y);
			mem_free_dbg(v15);
		}
	}
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;
// 679660: using guessed type char gbMaxPlayers;
// 6AAA64: using guessed type int zharlib;

//----- (004322FA) --------------------------------------------------------
void __fastcall PlaceGroup(int mtype, int num, unsigned char leaderf, int leader)
{
	int v4; // ecx
	int *v5; // eax
	int v6; // edx
	int v7; // eax
	int v8; // edi
	int v9; // esi
	int v10; // eax
	int v11; // ecx
	int v12; // eax
	int v13; // ecx
	int v14; // eax
	int v15; // ST04_4
	int v16; // eax
	int v17; // ST04_4
	int v18; // eax
	int *v19; // edx
	int v20; // ecx
	int v21; // ebx
	int v22; // ecx
	int v23; // ecx
	int mtypea; // [esp+Ch] [ebp-24h]
	signed int v25; // [esp+14h] [ebp-1Ch]
	int v26; // [esp+18h] [ebp-18h]
	signed int i; // [esp+1Ch] [ebp-14h]
	int v28; // [esp+20h] [ebp-10h]
	int v29; // [esp+24h] [ebp-Ch]
	int v30; // [esp+28h] [ebp-8h]
	int v31; // [esp+2Ch] [ebp-4h]

	mtypea = mtype;
	v4 = 0;
	v31 = num;
	v30 = 0;
	v25 = 0;
	do
	{
		if ( v4 )
		{
			v30 = 0;
			v5 = &monster[nummonsters]._my;
			nummonsters -= v4;
			do
			{
				v6 = *(v5 - 58);
				v5 -= 57;
				--v4;
				dMonster[0][*v5 + 112 * v6] = 0;
			}
			while ( v4 );
		}
		if ( leaderf & 1 )
		{
			_LOBYTE(v4) = 92;
			v7 = random(v4, 8);
			v8 = monster[leader]._mx + offset_x[v7];
			v9 = monster[leader]._my + offset_y[v7];
			v29 = monster[leader]._mx + offset_x[v7];
			v28 = monster[leader]._my + offset_y[v7];
		}
		else
		{
			do
			{
				_LOBYTE(v4) = 93;
				v10 = random(v4, 80);
				_LOBYTE(v11) = 93;
				v8 = v10 + 16;
				v29 = v10 + 16;
				v12 = random(v11, 80);
				v9 = v12 + 16;
				v28 = v12 + 16;
			}
			while ( !MonstPlace(v8, v12 + 16) );
		}
		if ( nummonsters + v31 > totalmonsters )
			v31 = totalmonsters - nummonsters;
		v26 = 0;
		for ( i = 0; v26 < v31; v9 += offset_x[random(v23, 8)] )
		{
			if ( i >= 100 )
				break;
			if ( !MonstPlace(v8, v9)
			  || (v13 = 112 * v29, dung_map[v8][v9] != dung_map[v29][v28])
			  || leaderf & 2
			  && ((v14 = abs(v8 - v29), v13 = v15, v14 >= 4) || (v16 = abs(v9 - v28), v13 = v17, v16 >= 4)) )
			{
				++i;
			}
			else
			{
				PlaceMonster(nummonsters, mtypea, v8, v9);
				if ( leaderf & 1 )
				{
					v18 = nummonsters;
					v19 = &monster[nummonsters]._mmaxhp;
					v20 = 2 * *v19;
					*v19 = v20;
					monster[v18]._mhitpoints = v20;
					v13 = 228 * leader;
					monster[v18]._mint = monster[leader]._mint;
					if ( leaderf & 2 )
					{
						monster[v18].leader = leader;
						monster[v18].leaderflag = 1;
						monster[v18]._mAi = *(&monster[0]._mAi + v13);
					}
					if ( monster[v18]._mAi != MG_GARG )
					{
						v21 = nummonsters;
						v22 = monster[v18].MType->Anims[0].Frames[monster[v18]._mdir + 1];
						monster[v18]._mAFNum = v22;
						_LOBYTE(v22) = 88;
						monster[v21]._mAnimFrame = random(v22, monster[v21]._mAnimLen - 1) + 1;
						monster[v21]._mFlags &= 0xFFFFFFFB;
						monster[v21]._mmode = MM_STAND;
					}
				}
				++nummonsters;
				++v30;
				++v26;
			}
			_LOBYTE(v13) = 94;
			v8 += offset_x[random(v13, 8)];
			_LOBYTE(v23) = 94;
		}
		v4 = v30;
		if ( v30 >= v31 )
			break;
		++v25;
	}
	while ( v25 < 10 );
	if ( leaderf & 2 )
		monster[leader].unpackfilesize = v30;
}
// 658550: using guessed type int totalmonsters;

//----- (00432585) --------------------------------------------------------
void __cdecl LoadDiabMonsts()
{
	unsigned char *v0; // esi
	unsigned char *v1; // esi
	unsigned char *v2; // esi
	unsigned char *v3; // esi

	v0 = LoadFileInMem("Levels\\L4Data\\diab1.DUN", 0);
	SetMapMonsters((char *)v0, 2 * diabquad1x, 2 * diabquad1y);
	mem_free_dbg(v0);
	v1 = LoadFileInMem("Levels\\L4Data\\diab2a.DUN", 0);
	SetMapMonsters((char *)v1, 2 * diabquad2x, 2 * diabquad2y);
	mem_free_dbg(v1);
	v2 = LoadFileInMem("Levels\\L4Data\\diab3a.DUN", 0);
	SetMapMonsters((char *)v2, 2 * diabquad3x, 2 * diabquad3y);
	mem_free_dbg(v2);
	v3 = LoadFileInMem("Levels\\L4Data\\diab4a.DUN", 0);
	SetMapMonsters((char *)v3, 2 * diabquad4x, 2 * diabquad4y);
	mem_free_dbg(v3);
}
// 5289C4: using guessed type int diabquad1x;
// 5289C8: using guessed type int diabquad1y;

//----- (00432637) --------------------------------------------------------
void __cdecl InitMonsters()
{
	int v0; // ebp
	int v1; // ebx
	TriggerStruct *v2; // esi
	signed int v3; // ebp
	signed int v4; // edi
	int v5; // edi
	int v6; // esi
	int v7; // eax
	int v8; // ecx
	int v9; // edx
	int v10; // eax
	int v11; // esi
	char *v12; // edi
	int v13; // ebx
	int v14; // ecx
	int v15; // esi
	int v16; // ecx
	int v17; // eax
	int v18; // eax
	int v19; // ebx
	TriggerStruct *v20; // esi
	signed int v21; // ebp
	signed int v22; // edi
	int max; // [esp+10h] [ebp-1C4h]
	int v24; // [esp+14h] [ebp-1C0h]
	int v25[111]; // [esp+18h] [ebp-1BCh]

	v0 = 0;
	max = 0;
	if ( gbMaxPlayers != 1 )
		CheckClearDbg();
	if ( !setlevel )
	{
		AddMonster(1, 0, 0, 0, 0);
		AddMonster(1, 0, 0, 0, 0);
		AddMonster(1, 0, 0, 0, 0);
		AddMonster(1, 0, 0, 0, 0);
		if ( !setlevel && currlevel == 16 )
			LoadDiabMonsts();
	}
	v24 = trigflag[4];
	if ( currlevel == 15 )
		v24 = 1;
	v1 = v24;
	if ( v24 > 0 )
	{
		v2 = trigs;
		do
		{
			v3 = -2;
			do
			{
				v4 = -2;
				do
					DoVision(v3 + v2->_tx, v4++ + v2->_ty, 15, 0, 0);
				while ( v4 < 2 );
				++v3;
			}
			while ( v3 < 2 );
			++v2;
			--v1;
		}
		while ( v1 );
		v0 = 0;
	}
	PlaceQuestMonsters();
	if ( !setlevel )
	{
		PlaceUniques();
		v5 = 16;
		do
		{
			v6 = 16;
			do
			{
				if ( !SolidLoc(v5, v6) )
					++v0;
				++v6;
			}
			while ( v6 < 96 );
			++v5;
		}
		while ( v5 < 96 );
		v7 = v0 / 30;
		if ( gbMaxPlayers != 1 )
			v7 += v7 >> 1;
		v8 = nummonsters;
		if ( nummonsters + v7 > 190 )
			v7 = 190 - nummonsters;
		v9 = nummtypes;
		v10 = nummonsters + v7;
		v11 = 0;
		totalmonsters = v10;
		if ( nummtypes > 0 )
		{
			v12 = &Monsters[0].mPlaceFlags;
			do
			{
				if ( *v12 & 1 )
				{
					v13 = max++;
					v25[v13] = v11;
				}
				++v11;
				v12 += 328;
			}
			while ( v11 < v9 );
		}
		if ( v8 < v10 )
		{
			while ( 1 )
			{
				_LOBYTE(v8) = 95;
				v15 = v25[random(v8, max)];
				if ( currlevel == 1 )
					break;
				_LOBYTE(v14) = 95;
				if ( !random(v14, 2) )
					break;
				_LOBYTE(v16) = 95;
				if ( currlevel == 2 )
				{
					v17 = random(v16, 2) + 1;
LABEL_40:
					v18 = v17 + 1;
					goto LABEL_41;
				}
				v18 = random(v16, 3) + 3;
LABEL_41:
				PlaceGroup(v15, v18, 0, 0);
				if ( nummonsters >= totalmonsters )
					goto LABEL_42;
			}
			v17 = 0;
			goto LABEL_40;
		}
	}
LABEL_42:
	v19 = v24;
	if ( v24 > 0 )
	{
		v20 = trigs;
		do
		{
			v21 = -2;
			do
			{
				v22 = -2;
				do
					DoUnVision(v21 + v20->_tx, v22++ + v20->_ty, 15);
				while ( v22 < 2 );
				++v21;
			}
			while ( v21 < 2 );
			++v20;
			--v19;
		}
		while ( v19 );
	}
}
// 5CF31D: using guessed type char setlevel;
// 658550: using guessed type int totalmonsters;
// 679660: using guessed type char gbMaxPlayers;
// 432637: using guessed type int var_1BC[111];

//----- (0043283D) --------------------------------------------------------
void __cdecl PlaceUniques()
{
	int v0; // edi
	int v1; // eax
	UniqMonstStruct *v2; // ecx
	int v3; // eax
	int v4; // edx
	CMonster *v5; // esi
	int v6; // eax
	int v7; // edx

	v0 = 0;
	if ( UniqMonst[0].mtype != -1 )
	{
		v1 = 0;
		v2 = UniqMonst;
		while ( UniqMonst[v1].mlevel != currlevel )
		{
LABEL_25:
			v1 = ++v0;
			v2 = &UniqMonst[v0];
			if ( v2->mtype == -1 )
				return;
		}
		v3 = 0;
		v4 = 0;
		if ( nummtypes > 0 )
		{
			v5 = Monsters;
			do
			{
				if ( v3 )
					break;
				v6 = -((char)v2->mtype != (unsigned char)v5->mtype);
				++v5;
				v3 = v6 + 1;
				++v4;
			}
			while ( v4 < nummtypes );
		}
		v7 = v4 - 1;
		if ( !v0 )
		{
			if ( quests[2]._qactive )
				goto LABEL_23;
			v3 = 0;
		}
		if ( v0 == 2 )
		{
			if ( quests[3]._qactive )
				goto LABEL_23;
			v3 = 0;
		}
		if ( v0 == 3 )
		{
			if ( quests[7]._qactive )
				goto LABEL_23;
			v3 = 0;
		}
		if ( v0 != 7 )
		{
LABEL_20:
			if ( v0 == 8 && !quests[11]._qactive )
				v3 = 0;
			goto LABEL_23;
		}
		if ( !quests[4]._qactive )
		{
			v3 = 0;
			goto LABEL_20;
		}
LABEL_23:
		if ( v3 )
			PlaceUniqueMonst(v0, v7, 8);
		goto LABEL_25;
	}
}

//----- (0043290E) --------------------------------------------------------
void __fastcall SetMapMonsters(char *pMap, int startx, int starty)
{
	char *v3; // esi
	unsigned short v4; // cx
	int v5; // edx
	int v6; // edi
	int v7; // ecx
	char *v8; // edx
	int i; // esi
	int v10; // eax
	int v11; // ecx
	int v12; // [esp+Ch] [ebp-Ch]
	int v13; // [esp+10h] [ebp-8h]
	char *v14; // [esp+14h] [ebp-4h]
	int startya; // [esp+20h] [ebp+8h]

	v12 = startx;
	v3 = pMap;
	AddMonsterType(109, 2);
	AddMonster(1, 0, 0, 0, 0);
	AddMonster(1, 0, 0, 0, 0);
	AddMonster(1, 0, 0, 0, 0);
	AddMonster(1, 0, 0, 0, 0);
	if ( setlevel && setlvlnum == SL_VILEBETRAYER )
	{
		AddMonsterType((char)UniqMonst[4].mtype, 4);
		AddMonsterType((char)UniqMonst[5].mtype, 4);
		AddMonsterType((char)UniqMonst[6].mtype, 4);
		PlaceUniqueMonst(4, 0, 0);
		PlaceUniqueMonst(5, 0, 0);
		PlaceUniqueMonst(6, 0, 0);
	}
	v4 = *((_WORD *)v3 + 1);
	v5 = *(unsigned short *)v3 * v4;
	v6 = (unsigned short)(2 * *(_WORD *)v3);
	v7 = (unsigned short)(2 * v4);
	v8 = &v3[2 * v5 + 4 + 2 * v7 * v6];
	v14 = v8;
	if ( v7 > 0 )
	{
		v13 = v7;
		startya = starty + 16;
		do
		{
			for ( i = 0; i < v6; v14 += 2 )
			{
				if ( *(_WORD *)v8 )
				{
					v10 = AddMonsterType(*((char *)&monsterdata[111].mExp + *(unsigned short *)v8 + 3), 2);
					v11 = nummonsters++;
					PlaceMonster(v11, v10, i + v12 + 16, startya);
				}
				v8 = v14 + 2;
				++i;
			}
			++startya;
			--v13;
		}
		while ( v13 );
	}
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (00432A4D) --------------------------------------------------------
void __fastcall DeleteMonster(int i)
{
	int *v1; // ecx
	int *v2; // eax
	int v3; // edx

	--nummonsters;
	v1 = &monstactive[i];
	v2 = &monstactive[nummonsters];
	v3 = *v2;
	*v2 = *v1;
	*v1 = v3;
}

//----- (00432A71) --------------------------------------------------------
int __fastcall AddMonster(int x, int y, int dir, int mtype, int InMap)
{
	int v5; // esi

	if ( nummonsters >= 200 )
		return -1;
	v5 = monstactive[nummonsters++];
	if ( InMap )
		dMonster[0][y + 112 * x] = v5 + 1;
	InitMonster(v5, dir, mtype, x, y);
	return v5;
}

//----- (00432AC1) --------------------------------------------------------
void __fastcall NewMonsterAnim(int i, AnimStruct *anim, int md)
{
	MonsterStruct *v3; // eax
	int v4; // esi
	int v5; // edx

	v3 = &monster[i];
	v3->_mAFNum = anim->Frames[md + 1];
	v4 = anim->Rate;
	v3->_mAnimCnt = 0;
	v3->_mAnimLen = v4;
	v3->_mAnimFrame = 1;
	v5 = anim->Delay;
	v3->_mFlags &= 0xFFFFFFF9;
	v3->_mAnimDelay = v5;
	v3->_mdir = md;
}

//----- (00432AFF) --------------------------------------------------------
int __fastcall M_Ranged(int i)
{
	char v1; // cl

	v1 = monster[i]._mAi;
	return v1 == MG_SKELBOW || v1 == MG_GOATBOW || v1 == MG_SUCC || v1 == MG_LAZHELP;
}

//----- (00432B26) --------------------------------------------------------
int __fastcall M_Talker(int i)
{
	char v1; // cl

	v1 = monster[i]._mAi;
	return v1 == MG_LAZURUS
		|| v1 == MG_WARLORD
		|| v1 == MG_GARBUD
		|| v1 == MG_ZHAR
		|| v1 == MG_SNOTSPIL
		|| v1 == MG_LACHDANAN
		|| v1 == MG_LAZHELP;
}

//----- (00432B5C) --------------------------------------------------------
void __fastcall M_Enemy(int i)
{
	MonsterStruct *v1; // esi
	int *v2; // edi
	int v3; // eax
	int v4; // ecx
	int v5; // ebx
	int v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // ecx
	int v10; // edi
	int v11; // edx
	int v12; // eax
	int v13; // ecx
	int v14; // ebx
	int v15; // eax
	int v16; // eax
	int v17; // [esp+Ch] [ebp-20h]
	int v18; // [esp+10h] [ebp-1Ch]
	BOOL v19; // [esp+14h] [ebp-18h]
	BOOL v20; // [esp+14h] [ebp-18h]
	signed int v21; // [esp+18h] [ebp-14h]
	int j; // [esp+18h] [ebp-14h]
	signed int v23; // [esp+1Ch] [ebp-10h]
	signed int v24; // [esp+20h] [ebp-Ch]
	BOOL v25; // [esp+24h] [ebp-8h]
	char v26; // [esp+2Ah] [ebp-2h]
	char v27; // [esp+2Bh] [ebp-1h]

	v24 = -1;
	v18 = i;
	v23 = -1;
	v1 = &monster[i];
	v25 = 0;
	if ( !(v1->_mFlags & 0x20) )
	{
		v21 = 0;
		v2 = &plr[0].plrlevel;
		do
		{
			if ( !*((_BYTE *)v2 - 23) || currlevel != *v2 || *((_BYTE *)v2 + 267) || !v2[89] && gbMaxPlayers != 1 )
				goto LABEL_18;
			v3 = v1->_my;
			v4 = v2[2];
			v19 = dung_map[v2[1]][v4] == dung_map[v1->_mx][v3];
			v5 = abs(v3 - v4);
			if ( abs(v1->_mx - v2[1]) <= v5 )
				v6 = v1->_my - v2[2];
			else
				v6 = v1->_mx - v2[1];
			v7 = abs(v6);
			if ( v19 )
			{
				if ( !v25 )
					goto LABEL_17;
			}
			else if ( v25 )
			{
				goto LABEL_16;
			}
			if ( v7 < v23 )
				goto LABEL_17;
LABEL_16:
			if ( v24 == -1 )
			{
LABEL_17:
				v1->_mFlags &= 0xFFFFFFEF;
				v24 = v21;
				v27 = *((_BYTE *)v2 + 12);
				v26 = *((_BYTE *)v2 + 16);
				v23 = v7;
				v25 = v19;
			}
LABEL_18:
			++v21;
			v2 += 5430;
		}
		while ( (signed int)v2 < (signed int)&plr_msgs[0].player );
	}
	v8 = 0;
	for ( j = 0; j < nummonsters; v8 = j++ + 1 )
	{
		v9 = monstactive[v8];
		v17 = monstactive[v8];
		if ( v9 == v18 )
			continue;
		v10 = v9;
		if ( monster[v9]._mx == 1 && !monster[v10]._my )
			continue;
		if ( M_Talker(v9) && monster[v10].mtalkmsg )
			continue;
		if ( !(v1->_mFlags & 0x20)
		  && ((abs(v11 - v1->_mx) >= 2 || abs(monster[v10]._my - v1->_my) >= 2) && !M_Ranged(v18)
		   || !(v1->_mFlags & 0x20) && !(monster[v10]._mFlags & 0x20)) )
		{
			continue;
		}
		v12 = v1->_my;
		v13 = monster[v10]._my;
		v20 = dung_map[monster[v10]._mx][v13] == dung_map[v1->_mx][v12];
		v14 = abs(v12 - v13);
		if ( abs(v1->_mx - monster[v10]._mx) <= v14 )
			v15 = v1->_my - monster[v10]._my;
		else
			v15 = v1->_mx - monster[v10]._mx;
		v16 = abs(v15);
		if ( v20 )
		{
			if ( !v25 )
				goto LABEL_40;
		}
		else if ( v25 )
		{
			goto LABEL_39;
		}
		if ( v16 < v23 )
			goto LABEL_40;
LABEL_39:
		if ( v24 == -1 )
		{
LABEL_40:
			v1->_mFlags |= 0x10u;
			v24 = v17;
			v27 = monster[v10]._mfutx;
			v26 = monster[v10]._mfuty;
			v23 = v16;
			v25 = v20;
		}
	}
	if ( v24 == -1 )
	{
		BYTE1(v1->_mFlags) |= 4u;
	}
	else
	{
		BYTE1(v1->_mFlags) &= 0xFBu;
		v1->_menemy = v24;
		v1->_menemyx = v27;
		v1->_menemyy = v26;
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00432E15) --------------------------------------------------------
int __fastcall M_GetDir(int i)
{
	return GetDirection(
			   monster[i]._mx,
			   monster[i]._my,
			   (unsigned char)monster[i]._menemyx,
			   (unsigned char)monster[i]._menemyy);
}

//----- (00432E3D) --------------------------------------------------------
void __fastcall M_CheckEFlag(int i)
{
	int v1; // ecx
	int v2; // edi
	char *v3; // eax
	signed int v4; // edx

	v1 = i;
	v2 = 0;
	v3 = (char *)dpiece_defs_map_2 + 32 * (112 * (monster[v1]._mx - 1) + monster[v1]._my + 1);
	if ( v3 < (char *)dpiece_defs_map_2 )
		goto LABEL_9;
	v4 = 2;
	do
		v2 |= *(unsigned short *)&v3[2 * v4++];
	while ( v4 < 10 );
	if ( v2 | dArch[monster[v1]._mx - 1][monster[v1]._my + 1] )
		monster[v1]._meflag = 1;
	else
LABEL_9:
		monster[v1]._meflag = 0;
}

//----- (00432E9D) --------------------------------------------------------
void __fastcall M_StartStand(int i, int md)
{
	int v2; // ebx
	int v3; // edi
	int v4; // esi
	CMonster *v5; // eax
	AnimStruct *v6; // edx
	int v7; // eax
	int v8; // ecx

	v2 = md;
	v3 = i;
	ClearMVars(i);
	v4 = v3;
	v5 = monster[v3].MType;
	v6 = &v5->Anims[1];
	if ( v5->mtype != MON_GOLEM )
		v6 = v5->Anims;
	NewMonsterAnim(v3, v6, v2);
	monster[v4]._mdir = v2;
	monster[v4]._mVar1 = monster[v4]._mmode;
	monster[v4]._mVar2 = 0;
	monster[v4]._mmode = 0;
	v7 = monster[v4]._mx;
	monster[v4]._mxoff = 0;
	monster[v4]._myoff = 0;
	v8 = monster[v4]._my;
	monster[v4]._mfuty = v8;
	monster[v4]._moldy = v8;
	monster[v4]._mfutx = v7;
	monster[v4]._moldx = v7;
	M_CheckEFlag(v3);
	M_Enemy(v3);
}

//----- (00432F29) --------------------------------------------------------
void __fastcall M_StartDelay(int i, int len)
{
	int v2; // eax

	if ( len > 0 )
	{
		v2 = i;
		if ( monster[i]._mAi != MG_LAZURUS )
		{
			monster[v2]._mVar2 = len;
			monster[v2]._mmode = MM_DELAY;
		}
	}
}

//----- (00432F4F) --------------------------------------------------------
void __fastcall M_StartSpStand(int i, int md)
{
	int v2; // ebx
	int v3; // esi
	int v4; // edi
	int v5; // eax
	int v6; // ecx

	v2 = i;
	v3 = i;
	v4 = md;
	NewMonsterAnim(i, &monster[i].MType->Anims[5], md);
	v5 = monster[v3]._mx;
	v6 = monster[v3]._my;
	monster[v3]._mxoff = 0;
	monster[v3]._myoff = 0;
	monster[v3]._mdir = v4;
	monster[v3]._mmode = MM_SPSTAND;
	monster[v3]._mfutx = v5;
	monster[v3]._mfuty = v6;
	monster[v3]._moldx = v5;
	monster[v3]._moldy = v6;
	M_CheckEFlag(v2);
}

//----- (00432FBC) --------------------------------------------------------
void __fastcall M_StartWalk(int i, int xvel, int yvel, int xadd, int yadd, int EndDir)
{
	int v6; // ST18_4
	int v7; // esi
	int v8; // eax
	int v9; // ecx
	CMonster *v10; // edx

	v6 = i;
	v7 = i;
	v8 = monster[i]._mx;
	monster[v7]._moldx = v8;
	v9 = monster[i]._my;
	monster[v7]._mfuty = v9 + yadd;
	monster[v7]._mxvel = xvel;
	monster[v7]._myvel = yvel;
	monster[v7]._mVar1 = xadd;
	monster[v7]._mVar2 = yadd;
	dMonster[0][v9 + yadd + 112 * (v8 + xadd)] = -1 - v6;
	v10 = monster[v7].MType;
	monster[v7]._moldy = v9;
	monster[v7]._mmode = MM_WALK;
	monster[v7]._mfutx = v8 + xadd;
	monster[v7]._mVar3 = EndDir;
	monster[v7]._mdir = EndDir;
	NewMonsterAnim(v6, &v10->Anims[1], EndDir);
	monster[v7]._mVar6 = 0;
	monster[v7]._mVar7 = 0;
	monster[v7]._mVar8 = 0;
	M_CheckEFlag(v6);
}

//----- (0043308F) --------------------------------------------------------
void __fastcall M_StartWalk2(int i, int xvel, int yvel, int a4, int a5, int a6, int a7, int EndDir)
{
	int v8; // esi
	int v9; // edx
	int v10; // ecx
	int v11; // eax
	int v12; // eax
	bool v13; // zf
	CMonster *v14; // edx
	int v15; // [esp+Ch] [ebp-8h]
	int ia; // [esp+10h] [ebp-4h]
	int EndDira; // [esp+28h] [ebp+14h]

	v15 = xvel;
	ia = i;
	v8 = i;
	v9 = a6 + monster[i]._mx;
	EndDira = monster[i]._mx;
	v10 = monster[i]._my;
	v11 = monster[v8]._my;
	monster[v8]._mVar2 = v10;
	dMonster[0][v10 + 112 * EndDira] = -1 - ia;
	monster[v8]._mVar1 = EndDira;
	monster[v8]._moldx = EndDira;
	v12 = a7 + v11;
	monster[v8]._moldy = v10;
	v13 = monster[v8]._uniqtype == 0;
	monster[v8]._mx = v9;
	monster[v8]._my = v12;
	monster[v8]._mfutx = v9;
	monster[v8]._mfuty = v12;
	dMonster[0][v12 + 112 * v9] = ia + 1;
	if ( !v13 )
		ChangeLightXY((unsigned char)monster[v8].mlid, v9, v12);
	v14 = monster[v8].MType;
	monster[v8]._mxvel = v15;
	monster[v8]._myvel = yvel;
	monster[v8]._mxoff = a4;
	monster[v8]._myoff = a5;
	monster[v8]._mmode = MM_WALK2;
	monster[v8]._mVar3 = EndDir;
	monster[v8]._mdir = EndDir;
	NewMonsterAnim(ia, &v14->Anims[1], EndDir);
	monster[v8]._mVar8 = 0;
	monster[v8]._mVar6 = 16 * a4;
	monster[v8]._mVar7 = 16 * a5;
	M_CheckEFlag(ia);
}

//----- (004331AA) --------------------------------------------------------
void __fastcall M_StartWalk3(int i, int xvel, int yvel, int a4, int a5, int a6, int a7, int a8, int a9, int EndDir)
{
	int v10; // esi
	int v11; // ebx
	int v12; // edi
	int v13; // edi
	int v14; // ebx
	int v15; // ecx
	CMonster *v16; // edx
	int v17; // [esp+Ch] [ebp-8h]
	int ia; // [esp+10h] [ebp-4h]
	int a6a; // [esp+28h] [ebp+14h]
	int a7a; // [esp+2Ch] [ebp+18h]

	ia = i;
	v10 = i;
	v11 = monster[i]._my;
	v12 = monster[i]._mx;
	v17 = xvel;
	a6a = v12 + a6;
	a7a = v11 + a7;
	v13 = a8 + v12;
	v14 = a9 + v11;
	if ( monster[i]._uniqtype )
		ChangeLightXY((unsigned char)monster[v10].mlid, v13, v14);
	v15 = monster[v10]._my + 112 * monster[v10]._mx;
	monster[v10]._mVar4 = v13;
	dMonster[0][v15] = -1 - ia;
	monster[v10]._mVar5 = v14;
	dMonster[0][a7a + 112 * a6a] = -1 - ia;
	monster[v10]._moldx = monster[v10]._mx;
	monster[v10]._moldy = monster[v10]._my;
	monster[v10]._mfutx = a6a;
	monster[v10]._mxvel = v17;
	dFlags[v13][v14] |= 0x10u;
	v16 = monster[v10].MType;
	monster[v10]._myvel = yvel;
	monster[v10]._mfuty = a7a;
	monster[v10]._mVar1 = a6a;
	monster[v10]._mVar2 = a7a;
	monster[v10]._mxoff = a4;
	monster[v10]._myoff = a5;
	monster[v10]._mmode = MM_WALK3;
	monster[v10]._mVar3 = EndDir;
	monster[v10]._mdir = EndDir;
	NewMonsterAnim(ia, &v16->Anims[1], EndDir);
	monster[v10]._mVar8 = 0;
	monster[v10]._mVar6 = 16 * a4;
	monster[v10]._mVar7 = 16 * a5;
	M_CheckEFlag(ia);
}

//----- (004332F6) --------------------------------------------------------
void __fastcall M_StartAttack(int i)
{
	int v1; // edi
	int v2; // ebx
	int v3; // esi
	int v4; // ecx
	int v5; // eax

	v1 = i;
	v2 = M_GetDir(i);
	v3 = v1;
	NewMonsterAnim(v1, &monster[v1].MType->Anims[2], v2);
	v4 = monster[v1]._my;
	v5 = monster[v1]._mx;
	monster[v3]._mxoff = 0;
	monster[v3]._myoff = 0;
	monster[v3]._mfuty = v4;
	monster[v3]._moldy = v4;
	monster[v3]._mmode = MM_ATTACK;
	monster[v3]._mfutx = v5;
	monster[v3]._moldx = v5;
	monster[v3]._mdir = v2;
	M_CheckEFlag(v1);
}

//----- (00433367) --------------------------------------------------------
void __fastcall M_StartRAttack(int i, int missile_type, int dam)
{
	int v3; // ebp
	int v4; // edi
	int v5; // ebx
	int v6; // esi
	int v7; // ecx
	int v8; // eax

	v3 = missile_type;
	v4 = i;
	v5 = M_GetDir(i);
	v6 = v4;
	NewMonsterAnim(v4, &monster[v4].MType->Anims[2], v5);
	v7 = monster[v4]._my;
	monster[v6]._mxoff = 0;
	monster[v6]._myoff = 0;
	monster[v6]._mVar2 = dam;
	v8 = monster[v4]._mx;
	monster[v6]._mfuty = v7;
	monster[v6]._moldy = v7;
	monster[v6]._mmode = MM_RATTACK;
	monster[v6]._mVar1 = v3;
	monster[v6]._mfutx = v8;
	monster[v6]._moldx = v8;
	monster[v6]._mdir = v5;
	M_CheckEFlag(v4);
}

//----- (004333EF) --------------------------------------------------------
void __fastcall M_StartRSpAttack(int i, int missile_type, int dam)
{
	int v3; // ebp
	int v4; // edi
	int v5; // ebx
	int v6; // esi
	int v7; // ecx
	int v8; // eax

	v3 = missile_type;
	v4 = i;
	v5 = M_GetDir(i);
	v6 = v4;
	NewMonsterAnim(v4, &monster[v4].MType->Anims[5], v5);
	monster[v6]._mmode = MM_RSPATTACK;
	monster[v6]._mVar2 = 0;
	monster[v6]._mVar3 = dam;
	v7 = monster[v4]._my;
	monster[v6]._mxoff = 0;
	monster[v6]._myoff = 0;
	v8 = monster[v4]._mx;
	monster[v6]._mfuty = v7;
	monster[v6]._moldy = v7;
	monster[v6]._mVar1 = v3;
	monster[v6]._mfutx = v8;
	monster[v6]._moldx = v8;
	monster[v6]._mdir = v5;
	M_CheckEFlag(v4);
}

//----- (00433480) --------------------------------------------------------
void __fastcall M_StartSpAttack(int i)
{
	int v1; // edi
	int v2; // ebx
	int v3; // esi
	int v4; // ecx
	int v5; // eax

	v1 = i;
	v2 = M_GetDir(i);
	v3 = v1;
	NewMonsterAnim(v1, &monster[v1].MType->Anims[5], v2);
	v4 = monster[v1]._my;
	v5 = monster[v1]._mx;
	monster[v3]._mxoff = 0;
	monster[v3]._myoff = 0;
	monster[v3]._mfuty = v4;
	monster[v3]._moldy = v4;
	monster[v3]._mmode = MM_SATTACK;
	monster[v3]._mfutx = v5;
	monster[v3]._moldx = v5;
	monster[v3]._mdir = v2;
	M_CheckEFlag(v1);
}

//----- (004334F4) --------------------------------------------------------
void __fastcall M_StartEat(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // ecx
	int v4; // eax

	v1 = i;
	v2 = i;
	NewMonsterAnim(i, &monster[i].MType->Anims[5], monster[i]._mdir);
	v3 = monster[v2]._my;
	v4 = monster[v2]._mx;
	monster[v2]._mxoff = 0;
	monster[v2]._myoff = 0;
	monster[v2]._mfuty = v3;
	monster[v2]._moldy = v3;
	monster[v2]._mmode = MM_SATTACK;
	monster[v2]._mfutx = v4;
	monster[v2]._moldx = v4;
	M_CheckEFlag(v1);
}

//----- (0043355C) --------------------------------------------------------
void __fastcall M_ClearSquares(int i)
{
	int v1; // edx
	int v2; // eax
	int v3; // esi
	int v4; // ecx
	int v5; // edi
	int v6; // [esp+8h] [ebp-Ch]
	_DWORD *v7; // [esp+Ch] [ebp-8h]
	int v8; // [esp+10h] [ebp-4h]

	v1 = monster[i]._moldx;
	v2 = monster[i]._moldy;
	v3 = -1 - i;
	v6 = i + 1;
	v4 = v2 - 1;
	v5 = v2 + 1;
	if ( (unsigned char)(__OFSUB__(v2 - 1, v2 + 1) ^ 1) | (v2 - 1 == v2 + 1) )
	{
		do
		{
			if ( v4 >= 0 && v4 < 112 )
			{
				v8 = v1 - 1;
				if ( (unsigned char)(__OFSUB__(v1 - 1, v1 + 1) ^ 1) | (v1 - 1 == v1 + 1) )
				{
					v7 = (_DWORD *)((char *)dMonster + 4 * (v4 + 112 * (v1 - 1)));
					do
					{
						if ( v8 >= 0 && v8 < 112 && (*v7 == v3 || *v7 == v6) )
							*v7 = 0;
						++v8;
						v7 += 112;
					}
					while ( v8 <= v1 + 1 );
				}
			}
			++v4;
			v5 = v2 + 1;
		}
		while ( v4 <= v2 + 1 );
	}
	if ( v1 + 1 < 112 )
		dFlags[v1 + 1][v2] &= 0xEFu;
	if ( v5 < 112 )
		dFlags[v1][v2 + 1] &= 0xEFu;
}

//----- (0043361B) --------------------------------------------------------
void __fastcall M_GetKnockback(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // ebx
	int v4; // eax
	int v5; // ST00_4
	AnimStruct *v6; // edx
	int v7; // eax
	int v8; // ecx
	int v9; // eax

	v1 = i;
	v2 = i;
	v3 = ((unsigned char)monster[i]._mdir - 4) & 7;
	_LOBYTE(v4) = DirOK(i, v3);
	if ( v4 )
	{
		M_ClearSquares(v1);
		v5 = monster[v2]._mdir;
		v6 = &monster[v2].MType->Anims[3];
		v7 = offset_y[v3];
		monster[v2]._moldx += offset_x[v3];
		monster[v2]._moldy += v7;
		NewMonsterAnim(v1, v6, v5);
		v8 = monster[v2]._moldy;
		v9 = monster[v2]._moldx;
		monster[v2]._mxoff = 0;
		monster[v2]._myoff = 0;
		monster[v2]._my = v8;
		monster[v2]._mfuty = v8;
		monster[v2]._mmode = MM_GOTHIT;
		monster[v2]._mx = v9;
		monster[v2]._mfutx = v9;
		M_CheckEFlag(v1);
		M_ClearSquares(v1);
		dMonster[0][monster[v2]._my + 112 * monster[v2]._mx] = v1 + 1;
	}
}

//----- (004336E5) --------------------------------------------------------
void __fastcall M_StartHit(int i, int pnum, int dam)
{
	int v3; // ebx
	int v4; // edi
	int v5; // esi
	unsigned char v6; // al
	char v7; // al
	unsigned char v8; // al
	int v9; // ecx
	int v10; // eax

	v3 = pnum;
	v4 = i;
	if ( pnum >= 0 )
		monster[i].mWhoHit |= 1 << pnum;
	if ( pnum == myplr )
	{
		delta_monster_hp(i, monster[i]._mhitpoints, currlevel);
		NetSendCmdParam2(0, CMD_MONSTDAMAGE, v4, dam);
	}
	PlayEffect(v4, 1);
	v5 = v4;
	v6 = monster[v4].MType->mtype;
	if ( v6 >= MON_SNEAKA && v6 <= MON_SNEAKD || dam >> 6 >= SLOBYTE(monster[v5].mLevel) + 3 )
	{
		if ( v3 >= 0 )
		{
			monster[v5]._mFlags &= 0xFFFFFFEF;
			monster[v5]._menemy = v3;
			v7 = plr[v3]._py;
			monster[v5]._menemyx = plr[v3]._px;
			monster[v5]._menemyy = v7;
			monster[v5]._mdir = M_GetDir(v4);
		}
		v8 = monster[v5].MType->mtype;
		if ( v8 == MON_BATB )
		{
			M_Teleport(v4);
		}
		else if ( v8 >= MON_SCAVA && v8 <= MON_SCAVD )
		{
			_LOBYTE(monster[v5]._mgoal) = 1;
		}
		if ( monster[v5]._mmode != MM_STONE )
		{
			NewMonsterAnim(v4, &monster[v5].MType->Anims[3], monster[v5]._mdir);
			v9 = monster[v5]._moldy;
			v10 = monster[v5]._moldx;
			monster[v5]._mxoff = 0;
			monster[v5]._myoff = 0;
			monster[v5]._my = v9;
			monster[v5]._mfuty = v9;
			monster[v5]._mmode = MM_GOTHIT;
			monster[v5]._mx = v10;
			monster[v5]._mfutx = v10;
			M_CheckEFlag(v4);
			M_ClearSquares(v4);
			dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v4 + 1;
		}
	}
}

//----- (0043385A) --------------------------------------------------------
void __fastcall M_DiabloDeath(int i, unsigned char sendmsg)
{
	int v2; // esi
	int v3; // edi
	int v4; // eax
	int v5; // ebx
	int v6; // esi
	int v7; // ecx
	int v8; // eax
	int v9; // esi
	int v10; // eax
	double v11; // st7
	int v12; // eax
	int v13; // ecx
	int v14; // esi
	int v15; // [esp+8h] [ebp-8h]
	int j; // [esp+Ch] [ebp-4h]
	int v17; // [esp+Ch] [ebp-4h]

	v15 = i;
	v2 = sendmsg;
	v3 = i;
	PlaySFX(USFX_DIABLOD);
	quests[5]._qactive = 3;
	if ( v2 )
		NetSendCmdQuest(1u, 5u);
	gbProcessPlayers = 0;
	_LOBYTE(sgbSaveSoundOn) = gbSoundOn;
	v4 = 0;
	for ( j = 0; j < nummonsters; ++j )
	{
		v5 = monstactive[v4];
		if ( v5 != v15 && _LOBYTE(monster[v3]._msquelch) )
		{
			v6 = v5;
			NewMonsterAnim(monstactive[v4], &monster[v5].MType->Anims[4], monster[v5]._mdir);
			v7 = monster[v5]._moldy;
			monster[v6]._mxoff = 0;
			monster[v6]._myoff = 0;
			monster[v6]._mVar1 = 0;
			v8 = monster[v5]._moldx;
			monster[v6]._my = v7;
			monster[v6]._mfuty = v7;
			monster[v6]._mmode = MM_DEATH;
			monster[v6]._mx = v8;
			monster[v6]._mfutx = v8;
			M_CheckEFlag(v5);
			M_ClearSquares(v5);
			dMonster[0][monster[v6]._my + 112 * monster[v6]._mx] = v5 + 1;
		}
		v4 = j + 1;
	}
	AddLight(monster[v3]._mx, monster[v3]._my, 8);
	DoVision(monster[v3]._mx, monster[v3]._my, 8, 0, 1);
	v9 = abs(ViewY - monster[v3]._my);
	if ( abs(ViewX - monster[v3]._mx) <= v9 )
		v10 = ViewY - monster[v3]._my;
	else
		v10 = ViewX - monster[v3]._mx;
	v17 = abs(v10);
	if ( v17 > 20 )
		v17 = 20;
	v11 = (double)v17;
	v12 = ViewX << 16;
	v13 = monster[v3]._mx << 16;
	monster[v3]._mVar3 = ViewX << 16;
	v14 = ViewY << 16;
	monster[v3]._mVar4 = ViewY << 16;
	monster[v3]._mVar5 = (signed __int64)((double)(v12 - v13) / v11);
	monster[v3]._mVar6 = (signed __int64)((double)(v14 - (monster[v3]._my << 16)) / v11);
}
// 4A22D5: using guessed type char gbSoundOn;
// 5256A0: using guessed type int gbProcessPlayers;
// 64D32C: using guessed type int sgbSaveSoundOn;

//----- (00433A4C) --------------------------------------------------------
void __fastcall M2MStartHit(int mid, int i, int dam)
{
	int v3; // edi
	int v4; // ebx
	int v5; // esi
	CMonster *v6; // eax
	char v7; // al
	CMonster *v8; // eax
	int v9; // ecx
	int v10; // eax
	int v11; // [esp+Ch] [ebp-4h]

	v3 = mid;
	v4 = i;
	v11 = i;
	if ( (unsigned int)mid >= 0xC8 )
		TermMsg("Invalid monster %d getting hit by monster", mid);
	v5 = v3;
	if ( !monster[v3].MType )
		TermMsg("Monster %d \"%s\" getting hit by monster: MType NULL", v3, monster[v5].mName);
	if ( v4 >= 0 )
		monster[v4].mWhoHit |= 1 << v4;
	delta_monster_hp(v3, monster[v5]._mhitpoints, currlevel);
	NetSendCmdParam2(0, CMD_MONSTDAMAGE, v3, dam);
	PlayEffect(v3, 1);
	v6 = monster[v5].MType;
	if ( v6->mtype >= MON_SNEAKA && v6->mtype <= MON_SNEAKD || dam >> 6 >= SLOBYTE(monster[v5].mLevel) + 3 )
	{
		if ( v11 >= 0 )
			monster[v5]._mdir = ((unsigned char)monster[v11]._mdir - 4) & 7;
		v7 = v6->mtype;
		if ( v7 == 39 )
		{
			M_Teleport(v3);
		}
		else if ( v7 >= MON_SCAVA && v7 <= MON_SCAVD )
		{
			_LOBYTE(monster[v5]._mgoal) = 1;
		}
		if ( monster[v5]._mmode != MM_STONE )
		{
			v8 = monster[v5].MType;
			if ( v8->mtype != MON_GOLEM )
			{
				NewMonsterAnim(v3, &v8->Anims[3], monster[v5]._mdir);
				monster[v5]._mmode = MM_GOTHIT;
			}
			v9 = monster[v5]._moldy;
			v10 = monster[v5]._moldx;
			monster[v5]._mxoff = 0;
			monster[v5]._myoff = 0;
			monster[v5]._my = v9;
			monster[v5]._mfuty = v9;
			monster[v5]._mx = v10;
			monster[v5]._mfutx = v10;
			M_CheckEFlag(v3);
			M_ClearSquares(v3);
			dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v3 + 1;
		}
	}
}

//----- (00433BCC) --------------------------------------------------------
void __fastcall MonstStartKill(int i, int pnum, unsigned char sendmsg)
{
	signed int v3; // edi
	int v4; // ebx
	signed int v5; // esi
	int v6; // ecx
	int v7; // eax
	int v8; // eax
	int v9; // eax
	AnimStruct *v10; // edx
	int v11; // ecx
	int v12; // eax
	unsigned char v13; // al

	v3 = i;
	v4 = pnum;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MonstStartKill: Invalid monster %d", i);
	v5 = v3;
	if ( !monster[v3].MType )
		TermMsg("MonstStartKill: Monster %d \"%s\" MType NULL", v3, monster[v5].mName);
	if ( v4 >= 0 )
		monster[v5].mWhoHit |= 1 << v4;
	if ( v4 < 4 && v3 > 4 )
		AddPlrMonstExper(SLOBYTE(monster[v5].mLevel), (unsigned short)monster[v5].mExp, monster[v5].mWhoHit);
	v6 = monster[v5]._mRndSeed;
	v7 = monster[v5].MType->mtype;
	monster[v5]._mhitpoints = 0;
	++monstkills[v7];
	SetRndSeed(v6);
	_LOBYTE(v8) = QuestStatus(2);
	if ( v8 && monster[v5].mName == UniqMonst[0].mName )
	{
		CreateTypeItem(monster[v5]._mx + 1, monster[v5]._my + 1, 1u, 4, 0, 1, 0);
	}
	else if ( v3 > 3 )
	{
		SpawnItem(v3, monster[v5]._mx, monster[v5]._my, sendmsg);
	}
	if ( monster[v5].MType->mtype == MON_DIABLO )
		M_DiabloDeath(v3, 1u);
	else
		PlayEffect(v3, 2);
	if ( v4 < 0 )
		v9 = monster[v5]._mdir;
	else
		v9 = M_GetDir(v3);
	v10 = &monster[v5].MType->Anims[4];
	monster[v5]._mdir = v9;
	NewMonsterAnim(v3, v10, v9);
	v11 = monster[v5]._moldy;
	v12 = monster[v5]._moldx;
	monster[v5]._my = v11;
	monster[v5]._mfuty = v11;
	monster[v5]._mmode = MM_DEATH;
	monster[v5]._mxoff = 0;
	monster[v5]._myoff = 0;
	monster[v5]._mVar1 = 0;
	monster[v5]._mx = v12;
	monster[v5]._mfutx = v12;
	M_CheckEFlag(v3);
	M_ClearSquares(v3);
	dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v3 + 1;
	CheckQuestKill(v3, sendmsg);
	M_FallenFear(monster[v5]._mx, monster[v5]._my);
	v13 = monster[v5].MType->mtype;
	if ( v13 >= MON_ACIDA && v13 <= MON_ACIDD )
		AddMissile(monster[v5]._mx, monster[v5]._my, 0, 0, 0, 59, 1, v3, (unsigned char)monster[v5]._mint + 1, 0);
}

//----- (00433DC2) --------------------------------------------------------
void __fastcall M2MStartKill(int i, int mid)
{
	signed int v2; // ebx
	signed int v3; // edi
	signed int v4; // esi
	int v5; // ecx
	int v6; // eax
	CMonster *v7; // ecx
	int v8; // eax
	int v9; // ecx
	int v10; // eax
	unsigned char v11; // al

	v2 = i;
	v3 = mid;
	if ( (unsigned int)i >= 0xC8 )
	{
		TermMsg("M2MStartKill: Invalid monster (attacker) %d", i);
		TermMsg("M2MStartKill: Invalid monster (killed) %d", v3);
	}
	if ( !monster[v2].MType )
		TermMsg("M2MStartKill: Monster %d \"%s\" MType NULL", v3, monster[v3].mName);
	v4 = v3;
	delta_kill_monster(v3, monster[v3]._mx, monster[v3]._my, currlevel);
	NetSendCmdLocParam1(0, CMD_MONSTDEATH, monster[v4]._mx, monster[v4]._my, v3);
	monster[v4].mWhoHit |= 1 << v2;
	if ( v2 < 4 )
		AddPlrMonstExper(SLOBYTE(monster[v4].mLevel), (unsigned short)monster[v4].mExp, monster[v3].mWhoHit);
	v5 = monster[v4]._mRndSeed;
	v6 = monster[v4].MType->mtype;
	monster[v4]._mhitpoints = 0;
	++monstkills[v6];
	SetRndSeed(v5);
	if ( v3 >= 4 )
		SpawnItem(v3, monster[v4]._mx, monster[v4]._my, 1u);
	if ( monster[v4].MType->mtype == MON_DIABLO )
		M_DiabloDeath(v3, 1u);
	else
		PlayEffect(v2, 2);
	PlayEffect(v3, 2);
	v7 = monster[v4].MType;
	v8 = ((unsigned char)monster[v2]._mdir - 4) & 7;
	if ( v7->mtype == MON_GOLEM )
		v8 = 0;
	monster[v4]._mdir = v8;
	NewMonsterAnim(v3, &v7->Anims[4], v8);
	v9 = monster[v4]._moldy;
	v10 = monster[v4]._moldx;
	monster[v4]._my = v9;
	monster[v4]._mfuty = v9;
	monster[v4]._mmode = MM_DEATH;
	monster[v4]._mxoff = 0;
	monster[v4]._myoff = 0;
	monster[v4]._mx = v10;
	monster[v4]._mfutx = v10;
	M_CheckEFlag(v3);
	M_ClearSquares(v3);
	dMonster[0][monster[v4]._my + 112 * monster[v4]._mx] = v3 + 1;
	CheckQuestKill(v3, 1u);
	M_FallenFear(monster[v4]._mx, monster[v4]._my);
	v11 = monster[v4].MType->mtype;
	if ( v11 >= MON_ACIDA && v11 <= MON_ACIDD )
		AddMissile(monster[v4]._mx, monster[v4]._my, 0, 0, 0, 59, 1, v3, (unsigned char)monster[v4]._mint + 1, 0);
}

//----- (00433FC7) --------------------------------------------------------
void __fastcall M_StartKill(int i, int pnum)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // eax

	v2 = i;
	v3 = pnum;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_StartKill: Invalid monster %d", i);
	if ( myplr == v3 )
	{
		v4 = v2;
		delta_kill_monster(v2, monster[v2]._mx, monster[v2]._my, currlevel);
		if ( v2 == v3 )
		{
			_LOWORD(v5) = currlevel;
			NetSendCmdLocParam1(0, CMD_KILLGOLEM, monster[v4]._mx, monster[v4]._my, v5);
		}
		else
		{
			NetSendCmdLocParam1(0, CMD_MONSTDEATH, monster[v4]._mx, monster[v4]._my, v2);
		}
	}
	MonstStartKill(v2, v3, 1u);
}

//----- (00434045) --------------------------------------------------------
void __fastcall M_SyncStartKill(int i, int x, int y, int pnum)
{
	int v4; // esi
	int v5; // ebx
	int v6; // esi
	int arglist; // [esp+Ch] [ebp-4h]

	v4 = i;
	v5 = x;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_SyncStartKill: Invalid monster %d", i);
	v6 = v4;
	if ( monster[v6]._mhitpoints && monster[v6]._mmode != MM_DEATH )
	{
		if ( !dMonster[0][y + 112 * v5] )
		{
			M_ClearSquares(arglist);
			monster[v6]._mx = v5;
			monster[v6]._my = y;
			monster[v6]._moldx = v5;
			monster[v6]._moldy = y;
		}
		if ( monster[v6]._mmode == MM_STONE )
		{
			MonstStartKill(arglist, pnum, 0);
			monster[v6]._mmode = MM_STONE;
		}
		else
		{
			MonstStartKill(arglist, pnum, 0);
		}
	}
}

//----- (004340E0) --------------------------------------------------------
void __fastcall M_StartFadein(int i, int md, unsigned char backwards)
{
	int v3; // esi
	int v4; // ebx
	int v5; // esi
	int v6; // ecx
	int v7; // eax
	int *v8; // eax
	int arglist; // [esp+Ch] [ebp-4h]

	v3 = i;
	v4 = md;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_StartFadein: Invalid monster %d", i);
	v5 = v3;
	if ( !monster[v5].MType )
		TermMsg("M_StartFadein: Monster %d \"%s\" MType NULL", arglist, monster[v5].mName);
	NewMonsterAnim(arglist, &monster[v5].MType->Anims[5], v4);
	v6 = monster[v5]._my;
	v7 = monster[v5]._mx;
	monster[v5]._mfuty = v6;
	monster[v5]._moldy = v6;
	monster[v5]._mmode = MM_FADEIN;
	monster[v5]._mxoff = 0;
	monster[v5]._myoff = 0;
	monster[v5]._mfutx = v7;
	monster[v5]._moldx = v7;
	M_CheckEFlag(arglist);
	v8 = &monster[v5]._mFlags;
	monster[v5]._mdir = v4;
	*v8 &= 0xFFFFFFFE;
	if ( backwards )
	{
		*v8 = monster[v5]._mFlags | 2;
		monster[v5]._mAnimFrame = monster[v5]._mAnimLen;
	}
}

//----- (004341AD) --------------------------------------------------------
void __fastcall M_StartFadeout(int i, int md, unsigned char backwards)
{
	int v3; // ebx
	int v4; // esi
	CMonster **v5; // edi
	int v6; // ecx
	int v7; // eax
	int v8; // eax
	int mda; // [esp+Ch] [ebp-4h]

	v3 = i;
	mda = md;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_StartFadeout: Invalid monster %d", i);
	v4 = v3;
	v5 = &monster[v3].MType;
	if ( !*v5 )
		TermMsg("M_StartFadeout: Monster %d \"%s\" MType NULL", v3, monster[v4].mName);
	NewMonsterAnim(v3, &(*v5)->Anims[5], mda);
	v6 = monster[v4]._my;
	v7 = monster[v4]._mx;
	monster[v4]._mfuty = v6;
	monster[v4]._moldy = v6;
	monster[v4]._mmode = MM_FADEOUT;
	monster[v4]._mxoff = 0;
	monster[v4]._myoff = 0;
	monster[v4]._mfutx = v7;
	monster[v4]._moldx = v7;
	M_CheckEFlag(v3);
	monster[v4]._mdir = mda;
	if ( backwards )
	{
		v8 = monster[v4]._mAnimLen;
		monster[v4]._mFlags |= 2u;
		monster[v4]._mAnimFrame = v8;
	}
}

//----- (00434272) --------------------------------------------------------
void __fastcall M_StartHeal(int i)
{
	int v1; // edi
	int v2; // esi
	CMonster *v3; // eax
	int v4; // ecx
	int v5; // eax

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_StartHeal: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_StartHeal: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	v3 = monster[v2].MType;
	v4 = v3->Anims[5].Frames[monster[v2]._mdir + 1];
	monster[v2]._mAFNum = v4;
	v5 = v3->Anims[5].Rate;
	monster[v2]._mFlags |= 2u;
	_LOBYTE(v4) = 97;
	monster[v2]._mAnimFrame = v5;
	monster[v2]._mmode = MM_HEAL;
	monster[v2]._mVar1 = monster[v2]._mmaxhp / (16 * (random(v4, 5) + 4));
}

//----- (0043430A) --------------------------------------------------------
void __fastcall M_ChangeLightOffset(int monst)
{
	int v1; // esi
	int v2; // ecx
	int v3; // eax
	int v4; // esi
	int v5; // edx
	int v6; // eax
	signed int v7; // esi
	int v8; // edx
	signed int v9; // esi

	v1 = monst;
	if ( (unsigned int)monst >= 0xC8 )
		TermMsg("M_ChangeLightOffset: Invalid monster %d", monst);
	v2 = v1;
	v3 = monster[v1]._myoff;
	v4 = monster[v1]._mxoff;
	v3 *= 2;
	v5 = v4 + v3;
	v6 = v3 - v4;
	if ( v5 >= 0 )
	{
		v7 = 1;
	}
	else
	{
		v7 = -1;
		v5 = -v5;
	}
	v8 = v7 * (v5 >> 3);
	if ( v6 >= 0 )
	{
		v9 = 1;
	}
	else
	{
		v9 = -1;
		v6 = -v6;
	}
	ChangeLightOff((unsigned char)monster[v2].mlid, v8, v9 * (v6 >> 3));
}

//----- (00434374) --------------------------------------------------------
int __fastcall M_DoStand(int i)
{
	int v1; // edi
	int v2; // esi
	CMonster *v3; // eax
	int v4; // ecx
	int v5; // eax

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoStand: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_DoStand: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	v3 = monster[v2].MType;
	v4 = monster[v2]._mdir;
	if ( v3->mtype == MON_GOLEM )
		v5 = v3->Anims[1].Frames[v4 + 1];
	else
		v5 = v3->Anims[0].Frames[v4 + 1];
	monster[v2]._mAFNum = v5;
	if ( monster[v2]._mAnimFrame == monster[v2]._mAnimLen )
		M_Enemy(v1);
	++monster[v2]._mVar2;
	return 0;
}

//----- (004343F3) --------------------------------------------------------
int __fastcall M_DoWalk(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // edi
	int v4; // eax
	int v5; // edi
	int v6; // ecx
	int v7; // edx
	int v8; // eax
	bool v9; // zf
	int v10; // ecx
	int v11; // edx
	int v12; // eax
	int v13; // ecx

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoWalk: Invalid monster %d", i);
	v2 = v1;
	v3 = 0;
	if ( !monster[v1].MType )
		TermMsg("M_DoWalk: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	v4 = monster[v2]._mVar8;
	if ( v4 == monster[v2].MType->Anims[1].Rate )
	{
		v5 = monster[v2]._my;
		v6 = monster[v2]._mx;
		dMonster[0][v5 + 112 * monster[v2]._mx] = 0;
		v7 = v6 + monster[v2]._mVar1;
		monster[v2]._mx = v7;
		v8 = v5 + monster[v2]._mVar2;
		v9 = monster[v2]._uniqtype == 0;
		monster[v2]._my = v8;
		dMonster[0][v8 + 112 * v7] = v1 + 1;
		if ( !v9 )
			ChangeLightXY((unsigned char)monster[v2].mlid, v7, v8);
		M_StartStand(v1, monster[v2]._mdir);
		v3 = 1;
	}
	else if ( !monster[v2]._mAnimCnt )
	{
		v10 = monster[v2]._mxvel;
		v11 = monster[v2]._myvel;
		monster[v2]._mVar8 = v4 + 1;
		monster[v2]._mVar6 += v10;
		v12 = monster[v2]._mVar6 >> 4;
		monster[v2]._mVar7 += v11;
		v13 = monster[v2]._mVar7 >> 4;
		monster[v2]._mxoff = v12;
		monster[v2]._myoff = v13;
	}
	if ( monster[v2]._uniqtype )
		M_ChangeLightOffset(v1);
	return v3;
}

//----- (00434509) --------------------------------------------------------
int __fastcall M_DoWalk2(int i)
{
	int v1; // ebp
	int v2; // esi
	int v3; // eax
	bool v4; // zf
	int v5; // edi
	int v6; // ecx
	int v7; // edx
	int v8; // eax
	int v9; // ecx

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoWalk2: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_DoWalk2: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	v3 = monster[v2]._mVar8;
	if ( v3 == monster[v2].MType->Anims[1].Rate )
	{
		v4 = monster[v2]._uniqtype == 0;
		dMonster[0][monster[v2]._mVar2 + 112 * monster[v2]._mVar1] = 0;
		if ( !v4 )
			ChangeLightXY((unsigned char)monster[v2].mlid, monster[v2]._mx, monster[v2]._my);
		M_StartStand(v1, monster[v2]._mdir);
		v5 = 1;
	}
	else
	{
		if ( !monster[v2]._mAnimCnt )
		{
			v6 = monster[v2]._mxvel;
			v7 = monster[v2]._myvel;
			monster[v2]._mVar8 = v3 + 1;
			monster[v2]._mVar6 += v6;
			v8 = monster[v2]._mVar6 >> 4;
			monster[v2]._mVar7 += v7;
			v9 = monster[v2]._mVar7 >> 4;
			monster[v2]._mxoff = v8;
			monster[v2]._myoff = v9;
		}
		v5 = 0;
	}
	if ( monster[v2]._uniqtype )
		M_ChangeLightOffset(v1);
	return v5;
}

//----- (004345FC) --------------------------------------------------------
int __fastcall M_DoWalk3(int i)
{
	int v1; // ebp
	int v2; // esi
	int v3; // eax
	int v4; // edi
	int v5; // edx
	int v6; // ecx
	int v7; // edx
	char *v8; // eax
	bool v9; // zf
	int v10; // edi
	int v11; // ecx
	int v12; // edx
	int v13; // eax
	int v14; // ecx

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoWalk3: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_DoWalk3: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	v3 = monster[v2]._mVar8;
	if ( v3 == monster[v2].MType->Anims[1].Rate )
	{
		v4 = monster[v2]._mVar2;
		v5 = monster[v2]._my + 112 * monster[v2]._mx;
		monster[v2]._my = v4;
		v6 = monster[v2]._mVar5;
		dMonster[0][v5] = 0;
		v7 = monster[v2]._mVar1;
		monster[v2]._mx = v7;
		v8 = &dFlags[monster[v2]._mVar4][v6];
		*v8 &= 0xEFu;
		v9 = monster[v2]._uniqtype == 0;
		dMonster[0][v4 + 112 * v7] = v1 + 1;
		if ( !v9 )
			ChangeLightXY((unsigned char)monster[v2].mlid, v7, v4);
		M_StartStand(v1, monster[v2]._mdir);
		v10 = 1;
	}
	else
	{
		if ( !monster[v2]._mAnimCnt )
		{
			v11 = monster[v2]._mxvel;
			v12 = monster[v2]._myvel;
			monster[v2]._mVar8 = v3 + 1;
			monster[v2]._mVar6 += v11;
			v13 = monster[v2]._mVar6 >> 4;
			monster[v2]._mVar7 += v12;
			v14 = monster[v2]._mVar7 >> 4;
			monster[v2]._mxoff = v13;
			monster[v2]._myoff = v14;
		}
		v10 = 0;
	}
	if ( monster[v2]._uniqtype )
		M_ChangeLightOffset(v1);
	return v10;
}

//----- (00434722) --------------------------------------------------------
void __fastcall M_TryM2MHit(int i, int mid, int hper, int mind, int maxd)
{
	int v5; // edi
	int v6; // ST08_4
	int v7; // esi
	int v8; // ebx
	int v9; // eax
	int v10; // ecx
	int v11; // eax
	unsigned char ret; // [esp+Ch] [ebp-Ch]
	char v13[4]; // [esp+10h] [ebp-8h]
	char arglist[4]; // [esp+14h] [ebp-4h]

	v5 = mid;
	*(_DWORD *)arglist = mid;
	*(_DWORD *)v13 = i;
	if ( (unsigned int)mid >= 0xC8 )
	{
		TermMsg("M_TryM2MHit: Invalid monster %d", mid);
		i = v6;
	}
	v7 = v5;
	if ( !monster[v5].MType )
		TermMsg("M_TryM2MHit: Monster %d \"%s\" MType NULL", v5, monster[v7].mName);
	if ( (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) > 0
	  && (monster[v7].MType->mtype != MON_SNEAKD || _LOBYTE(monster[v7]._mgoal) != 2) )
	{
		_LOBYTE(i) = 4;
		v8 = random(i, 100);
		if ( monster[v7]._mmode == MM_STONE )
			v8 = 0;
		_LOBYTE(v9) = CheckMonsterHit(*(int *)arglist, &ret);
		if ( !v9 && v8 < hper )
		{
			_LOBYTE(v10) = 5;
			v11 = (mind + random(v10, maxd - mind + 1)) << 6;
			monster[v7]._mhitpoints -= v11;
			if ( (signed int)(monster[v7]._mhitpoints & 0xFFFFFFC0) > 0 )
			{
				if ( monster[v7]._mmode == MM_STONE )
				{
					M2MStartHit(*(int *)arglist, *(int *)v13, v11);
					goto LABEL_15;
				}
				M2MStartHit(*(int *)arglist, *(int *)v13, v11);
			}
			else
			{
				if ( monster[v7]._mmode == MM_STONE )
				{
					M2MStartKill(*(int *)v13, *(int *)arglist);
LABEL_15:
					monster[v7]._mmode = MM_STONE;
					return;
				}
				M2MStartKill(*(int *)v13, *(int *)arglist);
			}
		}
	}
}

//----- (0043482C) --------------------------------------------------------
void __fastcall M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam)
{
	int v5; // esi
	int v6; // ebx
	int v7; // esi
	int v8; // edi
	int v9; // eax
	int v10; // ST08_4
	int v11; // ecx
	int v12; // ecx
	int v13; // edi
	int v14; // eax
	int v15; // eax
	int *v16; // ecx
	int v17; // eax
	int v18; // edi
	int v19; // edx
	int v20; // eax
	int v21; // eax
	int v22; // edx
	int v23; // eax
	bool v24; // zf
	bool v25; // sf
	unsigned char v26; // of
	int v27; // eax
	int v28; // ecx
	int v29; // edi
	int v30; // eax
	int v31; // eax
	int v32; // eax
	int v33; // edi
	int v34; // ebx
	int v35; // edx
	int v36; // [esp+Ch] [ebp-Ch]
	int arglist; // [esp+10h] [ebp-8h]
	int plr_num; // [esp+14h] [ebp-4h]
	int hper; // [esp+20h] [ebp+8h]

	v5 = i;
	plr_num = pnum;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_TryH2HHit: Invalid monster %d", i);
	v6 = v5;
	if ( !monster[v5].MType )
		TermMsg("M_TryH2HHit: Monster %d \"%s\" MType NULL", v5, monster[v6].mName);
	if ( monster[v6]._mFlags & 0x10 )
	{
		M_TryM2MHit(v5, plr_num, Hit, MinDam, MaxDam);
		return;
	}
	v7 = plr_num;
	if ( (signed int)(plr[plr_num]._pHitPoints & 0xFFFFFFC0) > 0 && !plr[v7]._pInvincible && !(plr[v7]._pSpellFlags & 1) )
	{
		v8 = abs(monster[v6]._mx - plr[v7].WorldX);
		v9 = abs(monster[v6]._my - plr[v7].WorldY);
		v11 = v10;
		if ( v8 < 2 && v9 < 2 )
		{
			_LOBYTE(v11) = 98;
			v36 = random(v11, 100);
			v12 = 5;
			v13 = Hit
				+ 2 * (SLOBYTE(monster[v6].mLevel) - plr[v7]._pLevel)
				+ 30
				- plr[v7]._pIBonusAC
				- plr[v7]._pIAC
				- plr[v7]._pDexterity / 5;
			if ( v13 < 15 )
				v13 = 15;
			if ( currlevel == 14 )
			{
				if ( v13 >= 20 )
					goto LABEL_23;
				v13 = 20;
			}
			if ( currlevel != 15 )
			{
LABEL_20:
				if ( currlevel == 16 && v13 < 30 )
					v13 = 30;
				goto LABEL_23;
			}
			if ( v13 < 25 )
			{
				v13 = 25;
				goto LABEL_20;
			}
LABEL_23:
			v14 = plr[v7]._pmode;
			if ( v14 && v14 != 4 || !plr[v7]._pBlockFlag )
			{
				v15 = 100;
			}
			else
			{
				_LOBYTE(v12) = 98;
				v15 = random(v12, 100);
			}
			v16 = (int *)(plr[v7]._pDexterity
						+ plr[v7]._pBaseToBlk
						- 2 * SLOBYTE(monster[v6].mLevel)
						+ 2 * plr[v7]._pLevel);
			if ( (signed int)v16 < 0 )
				v16 = 0;
			if ( (signed int)v16 > 100 )
				v16 = (int *)100;
			if ( v36 < v13 )
			{
				if ( v15 >= (signed int)v16 )
				{
					if ( monster[v6].MType->mtype == MON_ZOMBIED && plr_num == myplr )
					{
						v18 = -1;
						v19 = 0;
						for ( hper = -1; v19 < nummissiles; ++v19 )
						{
							v20 = missileactive[v19];
							if ( missile[v20]._mitype == 13 )
							{
								if ( missile[v20]._misource == plr_num )
								{
									v18 = missileactive[v19];
									hper = missileactive[v19];
								}
								else
								{
									v18 = hper;
								}
							}
						}
						v16 = &plr[v7]._pMaxHP;
						v21 = plr[v7]._pMaxHP;
						if ( v21 > 64 )
						{
							v22 = plr[v7]._pMaxHPBase;
							if ( v22 > 64 )
							{
								v23 = v21 - 64;
								v26 = __OFSUB__(plr[v7]._pHitPoints, v23);
								v24 = plr[v7]._pHitPoints == v23;
								v25 = plr[v7]._pHitPoints - v23 < 0;
								*v16 = v23;
								if ( !((unsigned char)(v25 ^ v26) | v24) )
								{
									plr[v7]._pHitPoints = v23;
									if ( v18 >= 0 )
										missile[v18]._miVar1 = v23;
								}
								v16 = &plr[v7]._pHPBase;
								v27 = v22 - 64;
								plr[v7]._pMaxHPBase = v22 - 64;
								if ( plr[v7]._pHPBase > v22 - 64 )
								{
									*v16 = v27;
									if ( v18 >= 0 )
										missile[v18]._miVar2 = v27;
								}
							}
						}
					}
					_LOBYTE(v16) = 99;
					v29 = (plr[v7]._pIGetHit << 6) + (MinDam << 6) + random((int)v16, (MaxDam - MinDam + 1) << 6);
					if ( v29 < 64 )
						v29 = 64;
					if ( plr_num == myplr )
					{
						plr[v7]._pHitPoints -= v29;
						plr[v7]._pHPBase -= v29;
					}
					if ( plr[v7]._pIFlags & 0x4000000 )
					{
						_LOBYTE(v28) = 99;
						v30 = (random(v28, 3) + 1) << 6;
						monster[v6]._mhitpoints -= v30;
						if ( (signed int)(monster[v6]._mhitpoints & 0xFFFFFFC0) > 0 )
							M_StartHit(arglist, plr_num, v30);
						else
							M_StartKill(arglist, plr_num);
					}
					if ( !(monster[v6]._mFlags & 0x1000) && monster[v6].MType->mtype == MON_SKING && gbMaxPlayers != 1 )
						monster[v6]._mhitpoints += v29;
					v31 = plr[v7]._pMaxHP;
					if ( plr[v7]._pHitPoints > v31 )
					{
						plr[v7]._pHitPoints = v31;
						plr[v7]._pHPBase = plr[v7]._pMaxHPBase;
					}
					if ( (signed int)(plr[v7]._pHitPoints & 0xFFFFFFC0) > 0 )
					{
						StartPlrHit(plr_num, v29, 0);
						if ( SLOBYTE(monster[v6]._mFlags) < 0 )
						{
							if ( plr[v7]._pmode != PM_GOTHIT )
								StartPlrHit(plr_num, 0, 1u);
							v32 = monster[v6]._mdir;
							v33 = plr[v7].WorldX + offset_x[v32];
							v34 = plr[v7].WorldY + offset_y[v32];
							if ( PosOkPlayer(plr_num, v33, v34) )
							{
								v35 = plr[v7]._pdir;
								plr[v7].WorldX = v33;
								plr[v7].WorldY = v34;
								FixPlayerLocation(plr_num, v35);
								FixPlrWalkTags(plr_num);
								dPlayer[v33][v34] = plr_num + 1;
								SetPlayerOld(plr_num);
							}
						}
					}
					else
					{
						SyncPlrKill(plr_num, 0);
					}
				}
				else
				{
					v17 = GetDirection(plr[v7].WorldX, plr[v7].WorldY, monster[v6]._mx, monster[v6]._my);
					StartPlrBlock(plr_num, v17);
				}
			}
			return;
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00434C3B) --------------------------------------------------------
int __fastcall M_DoAttack(int i)
{
	int v1; // edi
	int v2; // esi
	CMonster **v3; // ebx
	unsigned char v4; // al
	unsigned char v5; // al

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoAttack: Invalid monster %d", i);
	v2 = v1;
	v3 = &monster[v1].MType;
	if ( !*v3 )
	{
		TermMsg("M_DoAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
		if ( !*v3 )
			TermMsg("M_DoAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName);
	}
	if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum )
	{
		M_TryH2HHit(
			v1,
			monster[v2]._menemy,
			(unsigned char)monster[v2].mHit,
			(unsigned char)monster[v2].mMinDamage,
			(unsigned char)monster[v2].mMaxDamage);
		if ( monster[v2]._mAi != MG_SNAKE )
			PlayEffect(v1, 0);
	}
	v4 = monster[v2].MType->mtype;
	if ( v4 >= MON_MAGMAA && v4 <= MON_MAGMAD && monster[v2]._mAnimFrame == 9 )
	{
		M_TryH2HHit(
			v1,
			monster[v2]._menemy,
			(unsigned char)monster[v2].mHit + 10,
			(unsigned char)monster[v2].mMinDamage - 2,
			(unsigned char)monster[v2].mMaxDamage - 2);
		PlayEffect(v1, 0);
	}
	v5 = monster[v2].MType->mtype;
	if ( v5 >= MON_THINA && v5 <= MON_THIND && monster[v2]._mAnimFrame == 13 )
	{
		M_TryH2HHit(
			v1,
			monster[v2]._menemy,
			(unsigned char)monster[v2].mHit - 20,
			(unsigned char)monster[v2].mMinDamage + 4,
			(unsigned char)monster[v2].mMaxDamage + 4);
		PlayEffect(v1, 0);
	}
	if ( monster[v2]._mAi == MG_SNAKE && monster[v2]._mAnimFrame == 1 )
		PlayEffect(v1, 0);
	if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen )
		return 0;
	M_StartStand(v1, monster[v2]._mdir);
	return 1;
}

//----- (00434DBD) --------------------------------------------------------
int __fastcall M_DoRAttack(int i)
{
	int v1; // ebx
	int v2; // esi
	CMonster **v3; // edi
	int v4; // eax
	int v5; // eax
	int v6; // edi

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoRAttack: Invalid monster %d", i);
	v2 = v1;
	v3 = &monster[v1].MType;
	if ( !*v3 )
	{
		TermMsg("M_DoRAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
		if ( !*v3 )
			TermMsg("M_DoRAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName);
	}
	if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum )
	{
		v4 = monster[v2]._mVar1;
		if ( v4 != -1 )
		{
			v5 = 2 * (v4 == 52) + 1;
			if ( v5 > 0 )
			{
				v6 = v5;
				do
				{
					AddMissile(
						monster[v2]._mx,
						monster[v2]._my,
						(unsigned char)monster[v2]._menemyx,
						(unsigned char)monster[v2]._menemyy,
						monster[v2]._mdir,
						monster[v2]._mVar1,
						1,
						v1,
						monster[v2]._mVar2,
						0);
					--v6;
				}
				while ( v6 );
			}
		}
		PlayEffect(v1, 0);
	}
	if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen )
		return 0;
	M_StartStand(v1, monster[v2]._mdir);
	return 1;
}

//----- (00434EB2) --------------------------------------------------------
int __fastcall M_DoRSpAttack(int i)
{
	int v1; // ebx
	int v2; // esi
	CMonster **v3; // edi
	bool v4; // zf
	int v5; // ecx

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoRSpAttack: Invalid monster %d", i);
	v2 = v1;
	v3 = &monster[v1].MType;
	v4 = *v3 == 0;
	if ( !*v3 )
	{
		TermMsg("M_DoRSpAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
		v4 = *v3 == 0;
	}
	if ( v4 )
		TermMsg("M_DoRSpAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName);
	if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum2 && !monster[v2]._mAnimCnt )
	{
		AddMissile(
			monster[v2]._mx,
			monster[v2]._my,
			(unsigned char)monster[v2]._menemyx,
			(unsigned char)monster[v2]._menemyy,
			monster[v2]._mdir,
			monster[v2]._mVar1,
			1,
			v1,
			monster[v2]._mVar3,
			0);
		PlayEffect(v1, 3);
	}
	if ( monster[v2]._mAi == MG_MEGA && monster[v2]._mAnimFrame == 3 )
	{
		v5 = monster[v2]._mVar2;
		monster[v2]._mVar2 = v5 + 1;
		if ( v5 )
		{
			if ( v5 == 14 )
				monster[v2]._mFlags &= 0xFFFFFFFB;
		}
		else
		{
			monster[v2]._mFlags |= 4u;
		}
	}
	if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen )
		return 0;
	M_StartStand(v1, monster[v2]._mdir);
	return 1;
}

//----- (00434FC7) --------------------------------------------------------
int __fastcall M_DoSAttack(int i)
{
	int v1; // ebx
	int v2; // esi
	CMonster **v3; // edi
	bool v4; // zf

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoSAttack: Invalid monster %d", i);
	v2 = v1;
	v3 = &monster[v1].MType;
	v4 = *v3 == 0;
	if ( !*v3 )
	{
		TermMsg("M_DoSAttack: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
		v4 = *v3 == 0;
	}
	if ( v4 )
		TermMsg("M_DoSAttack: Monster %d \"%s\" MData NULL", v1, monster[v2].mName);
	if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum2 )
		M_TryH2HHit(
			v1,
			monster[v2]._menemy,
			(unsigned char)monster[v2].mHit2,
			(unsigned char)monster[v2].mMinDamage2,
			(unsigned char)monster[v2].mMaxDamage2);
	if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen )
		return 0;
	M_StartStand(v1, monster[v2]._mdir);
	return 1;
}

//----- (0043507E) --------------------------------------------------------
int __fastcall M_DoFadein(int i)
{
	int v1; // edi
	int v2; // esi

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoFadein: Invalid monster %d", i);
	v2 = v1;
	if ( (!(monster[v1]._mFlags & 2) || monster[v2]._mAnimFrame != 1)
	  && (monster[v1]._mFlags & 2 || monster[v2]._mAnimFrame != monster[v2]._mAnimLen) )
	{
		return 0;
	}
	M_StartStand(v1, monster[v2]._mdir);
	monster[v2]._mFlags &= 0xFFFFFFFD;
	return 1;
}

//----- (004350E3) --------------------------------------------------------
int __fastcall M_DoFadeout(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	signed int v4; // edx
	int v5; // ecx
	int v6; // edx

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoFadeout: Invalid monster %d", i);
	v2 = v1;
	v3 = monster[v1]._mFlags;
	if ( (!(monster[v1]._mFlags & 2) || monster[v2]._mAnimFrame != 1)
	  && (monster[v1]._mFlags & 2 || monster[v2]._mAnimFrame != monster[v2]._mAnimLen) )
	{
		return 0;
	}
	v4 = monster[v2].MType->mtype;
	if ( v4 < MON_FIREMANA || v4 > MON_FIREMAND )
		v5 = v3 & 0xFFFFFFFD | 1;
	else
		v5 = v3 & 0xFFFFFFFD;
	v6 = monster[v2]._mdir;
	monster[v2]._mFlags = v5;
	M_StartStand(v1, v6);
	return 1;
}

//----- (00435165) --------------------------------------------------------
int __fastcall M_DoHeal(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // esi
	int *v4; // edx
	int v5; // ecx
	int v6; // edi
	int v7; // edi
	int v8; // esi

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoHeal: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mFlags & 8 )
	{
		monster[v2]._mFlags &= 0xFFFFFFFB;
		monster[v2]._mmode = MM_SATTACK;
	}
	else if ( monster[v2]._mAnimFrame == 1 )
	{
		v3 = monster[v2]._mVar1;
		v4 = &monster[v2]._mhitpoints;
		v5 = monster[v2]._mFlags & 0xFFFFFFFD | 4;
		v6 = monster[v2]._mhitpoints;
		monster[v2]._mFlags = v5;
		v7 = v3 + v6;
		v8 = monster[v2]._mmaxhp;
		if ( v7 >= v8 )
		{
			*v4 = v8;
			monster[v2]._mFlags = v5 & 0xFFFFFFFB;
			monster[v2]._mmode = MM_SATTACK;
		}
		else
		{
			*v4 = v7;
		}
	}
	return 0;
}

//----- (004351F5) --------------------------------------------------------
int __fastcall M_DoTalk(int i)
{
	int v1; // ebp
	int v2; // edi
	int v3; // esi
	int v4; // eax
	int v5; // eax
	int v6; // edx
	int v7; // ecx
	char v8; // bl
	int v9; // eax
	char *v10; // eax
	unsigned char v12; // [esp-8h] [ebp-10h]

	v2 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoTalk: Invalid monster %d", i);
	v3 = v2;
	M_StartStand(v2, monster[v2]._mdir);
	_LOBYTE(monster[v2]._mgoal) = 7;
	_LOBYTE(v4) = effect_is_playing(alltext[monster[v2].mtalkmsg].sfxnr);
	if ( !v4 )
	{
		v12 = v1;
		InitQTextMsg(monster[v3].mtalkmsg);
		if ( monster[v3].mName == UniqMonst[0].mName )
		{
			v5 = monster[v3].mtalkmsg;
			if ( v5 == TEXT_GARBUD1 )
				quests[2]._qactive = 2;
			quests[2]._qlog = 1;
			if ( v5 == TEXT_GARBUD2 && !(monster[v3]._mFlags & 0x40) )
			{
				SpawnItem(v2, monster[v3]._mx + 1, monster[v3]._my + 1, 1u);
				monster[v3]._mFlags |= 0x40u;
			}
		}
		if ( monster[v3].mName == UniqMonst[2].mName
		  && monster[v3].mtalkmsg == TEXT_ZHAR1
		  && !(monster[v3]._mFlags & 0x40) )
		{
			v6 = monster[v3]._my + 1;
			v7 = monster[v3]._mx + 1;
			quests[3]._qactive = 2;
			quests[3]._qlog = 1;
			CreateTypeItem(v7, v6, 0, 0, 24, 1, 0);
			monster[v3]._mFlags |= 0x40u;
		}
		if ( monster[v3].mName == UniqMonst[3].mName )
		{
			if ( monster[v3].mtalkmsg == TEXT_SNOT1 && !(monster[v3]._mFlags & 0x40) )
			{
				DRLG_MRectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 2, (setpc_h >> 1) + setpc_y - 2);
				v8 = TransVal;
				TransVal = 9;
				Make_RectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 4, setpc_y + (setpc_h >> 1));
				TransVal = v8;
				quests[7]._qvar1 = 2;
				if ( quests[7]._qactive == 1 )
					quests[7]._qactive = 2;
				monster[v3]._mFlags |= 0x40u;
			}
			if ( quests[7]._qvar1 < 2u )
			{
				sprintf(tempstr, "SS Talk = %i, Flags = %i", monster[v3].mtalkmsg, monster[v3]._mFlags, v1);
				TermMsg(tempstr);
			}
		}
		if ( monster[v3].mName == UniqMonst[7].mName )
		{
			v9 = monster[v3].mtalkmsg;
			if ( v9 == TEXT_LACH1 )
			{
				quests[4]._qactive = 2;
				quests[4]._qlog = 1;
			}
			if ( v9 == TEXT_LACH3 && !(monster[v3]._mFlags & 0x40) )
			{
				CheckUnique(6, monster[v3]._mx + 1, monster[v3]._my + 1, v12);
				monster[v3]._mFlags |= 0x40u;
			}
		}
		v10 = monster[v3].mName;
		if ( v10 == UniqMonst[8].mName )
			quests[11]._qvar1 = 2;
		if ( v10 == UniqMonst[4].mName && gbMaxPlayers != 1 )
		{
			_LOBYTE(monster[v3]._msquelch) = -1;
			monster[v3].mtalkmsg = 0;
			quests[15]._qvar1 = 6;
			_LOBYTE(monster[v3]._mgoal) = 1;
		}
	}
	return 0;
}
// 4351F5: could not find valid save-restore pair for ebp
// 5A5590: using guessed type char TransVal;
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043547A) --------------------------------------------------------
void __fastcall M_Teleport(int i)
{
	int v1; // ebx
	int v2; // ST04_4
	MonsterStruct *v3; // esi
	int v4; // eax
	int v5; // ecx
	int v6; // edi
	int v7; // ebx
	int v8; // eax
	int v9; // [esp+Ch] [ebp-24h]
	int v10; // [esp+10h] [ebp-20h]
	int v11; // [esp+14h] [ebp-1Ch]
	int v12; // [esp+18h] [ebp-18h]
	int v13; // [esp+1Ch] [ebp-14h]
	int a1; // [esp+20h] [ebp-10h]
	signed int v15; // [esp+24h] [ebp-Ch]
	signed int v16; // [esp+28h] [ebp-8h]
	signed int v17; // [esp+2Ch] [ebp-4h]

	v1 = i;
	a1 = i;
	if ( (unsigned int)i >= 0xC8 )
	{
		TermMsg("M_Teleport: Invalid monster %d", i);
		i = v2;
	}
	v15 = 0;
	v3 = &monster[v1];
	if ( v3->_mmode != 15 )
	{
		v10 = (unsigned char)v3->_menemyx;
		_LOBYTE(i) = 100;
		v12 = (unsigned char)v3->_menemyy;
		v4 = random(i, 2);
		_LOBYTE(v5) = 100;
		v11 = 2 * v4 - 1;
		v17 = -1;
		v6 = v9;
		v13 = 2 * random(v5, 2) - 1;
		while ( !v15 )
		{
			v16 = -1;
			v7 = v12 - v13;
			do
			{
				if ( v15 )
					break;
				if ( v17 || v16 )
				{
					v9 = v7;
					v6 = v10 + v11 * v17;
					if ( v7 >= 0 && v7 < 112 && v6 >= 0 && v6 < 112 && v6 != v3->_mx && v7 != v3->_my )
					{
						if ( PosOkMonst(a1, v10 + v11 * v17, v7) )
							v15 = 1;
					}
				}
				++v16;
				v7 += v13;
			}
			while ( v16 < 1 );
			if ( ++v17 > 1 )
			{
				if ( !v15 )
					return;
				v1 = a1;
				break;
			}
			v1 = a1;
		}
		M_ClearSquares(v1);
		v8 = v3->_my + 112 * v3->_mx;
		v3->_moldx = v6;
		dMonster[0][v8] = 0;
		v3->_moldy = v9;
		dMonster[0][v9 + 112 * v6] = v1 + 1;
		v3->_mdir = M_GetDir(v1);
		M_CheckEFlag(v1);
	}
}

//----- (004355BB) --------------------------------------------------------
int __fastcall M_DoGotHit(int i)
{
	int v1; // edi
	int v2; // esi

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoGotHit: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_DoGotHit: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen )
		return 0;
	M_StartStand(v1, monster[v2]._mdir);
	return 1;
}

//----- (0043561E) --------------------------------------------------------
int __fastcall M_UpdateLeader(int i)
{
	int v1; // edi
	int v2; // esi
	int j; // edx
	int v4; // eax
	int result; // eax

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_UpdateLeader: Invalid monster %d", i);
	v2 = nummonsters;
	for ( j = 0; j < v2; ++j )
	{
		v4 = monstactive[j];
		if ( monster[v4].leaderflag == 1 && (unsigned char)monster[v4].leader == v1 )
			monster[v4].leaderflag = 0;
	}
	result = 228 * v1;
	if ( monster[v1].leaderflag == 1 )
	{
		result = (int)&monster[*((unsigned char *)&monster[0].leader + result)].unpackfilesize;
		--*(_BYTE *)result;
	}
	return result;
}

//----- (00435697) --------------------------------------------------------
void __cdecl DoEnding()
{
	char v0; // al
	char *v1; // ecx
	char v2; // bl
	int v3; // esi

	if ( (unsigned char)gbMaxPlayers > 1u )
		SNetLeaveGame(1073741828);
	music_stop();
	if ( (unsigned char)gbMaxPlayers > 1u )
		Sleep(0x3E8u);
	v0 = plr[myplr]._pClass;
	if ( v0 )
	{
		v1 = "gendata\\DiabVic1.smk";
		if ( v0 != 2 )
			v1 = "gendata\\DiabVic3.smk";
	}
	else
	{
		v1 = "gendata\\DiabVic2.smk";
	}
	play_movie(v1, 0);
	play_movie("gendata\\Diabend.smk", 0);
	v2 = gbMusicOn;
	gbMusicOn = 1;
	v3 = sound_get_or_set_music_volume(1);
	sound_get_or_set_music_volume(0);
	music_start(2);
	loop_movie = 1;
	play_movie("gendata\\loopdend.smk", 1);
	loop_movie = 0;
	music_stop();
	sound_get_or_set_music_volume(v3);
	gbMusicOn = v2;
}
// 4A22D4: using guessed type char gbMusicOn;
// 659AFC: using guessed type int loop_movie;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043575C) --------------------------------------------------------
void __cdecl PrepDoEnding()
{
	int *v0; // eax
	int v1; // ecx
	int *v2; // eax
	bool v3; // cf
	bool v4; // zf

	gbSoundOn = sgbSaveSoundOn;
	gbRunGame = 0;
	*(_DWORD *)&deathflag = 0;
	v0 = &plr[myplr].pDiabloKillLevel;
	v1 = gnDifficulty + 1;
	cineflag = 1;
	if ( *v0 > (unsigned int)(gnDifficulty + 1) )
		v1 = *v0;
	*v0 = v1;
	v2 = &plr[0]._pHitPoints;
	do
	{
		v3 = (unsigned char)gbMaxPlayers < 1u;
		v4 = gbMaxPlayers == 1;
		*(v2 - 102) = 11;
		*((_BYTE *)v2 - 91) = 1;
		if ( !v3 && !v4 )
		{
			if ( !(*v2 & 0xFFFFFFC0) )
				*v2 = 64;
			if ( !(v2[5] & 0xFFFFFFC0) )
				v2[5] = 64;
		}
		v2 += 5430;
	}
	while ( (signed int)v2 < (signed int)&plr_msgs[2].msg[51] );
}
// 4A22D5: using guessed type char gbSoundOn;
// 525650: using guessed type int gbRunGame;
// 525718: using guessed type char cineflag;
// 64D32C: using guessed type int sgbSaveSoundOn;
// 679660: using guessed type char gbMaxPlayers;

//----- (004357DF) --------------------------------------------------------
int __fastcall M_DoDeath(int i)
{
	int v1; // edi
	int v2; // esi
	CMonster *v3; // ecx
	int v4; // eax
	int v5; // ecx
	signed int v6; // ecx
	int v7; // esi
	int v8; // esi
	signed int v9; // ecx
	char v10; // al
	int v11; // eax

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoDeath: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_DoDeath: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	v3 = monster[v2].MType;
	v4 = ++monster[v2]._mVar1;
	if ( v3->mtype == MON_DIABLO )
	{
		v5 = monster[v2]._mx - ViewX;
		if ( v5 >= 0 )
			v6 = v5 > 0;
		else
			v6 = -1;
		v7 = monster[v2]._my;
		ViewX += v6;
		v8 = v7 - ViewY;
		if ( v8 >= 0 )
		{
			v9 = v8 < 0;
			_LOBYTE(v9) = v8 > 0;
		}
		else
		{
			v9 = -1;
		}
		ViewY += v9;
		if ( v4 == 140 )
			PrepDoEnding();
	}
	else if ( monster[v2]._mAnimFrame == monster[v2]._mAnimLen )
	{
		if ( monster[v2]._uniqtype )
			v10 = monster[v2]._udeadval;
		else
			v10 = v3->mdeadval;
		AddDead(monster[v2]._mx, monster[v2]._my, v10, (direction)monster[v2]._mdir);
		v11 = monster[v2]._my + 112 * monster[v2]._mx;
		monster[v2]._mDelFlag = 1;
		dMonster[0][v11] = 0;
		M_UpdateLeader(v1);
	}
	return 0;
}

//----- (004358EC) --------------------------------------------------------
int __fastcall M_DoSpStand(int i)
{
	int v1; // ebx
	int v2; // esi

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoSpStand: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_DoSpStand: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	if ( monster[v2]._mAnimFrame == monster[v2].MData->mAFNum2 )
		PlayEffect(v1, 3);
	if ( monster[v2]._mAnimFrame != monster[v2]._mAnimLen )
		return 0;
	M_StartStand(v1, monster[v2]._mdir);
	return 1;
}

//----- (0043596B) --------------------------------------------------------
int __fastcall M_DoDelay(int i)
{
	int v1; // ebp
	int v2; // esi
	int v3; // eax
	bool v4; // zf
	int v5; // ecx
	int v6; // ecx
	int v7; // ebx

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoDelay: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1].MType )
		TermMsg("M_DoDelay: Monster %d \"%s\" MType NULL", v1, monster[v2].mName);
	v3 = M_GetDir(v1);
	v4 = monster[v2]._mAi == MG_LAZURUS;
	monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v3 + 1];
	if ( v4 )
	{
		v5 = monster[v2]._mVar2;
		if ( v5 > 8 || v5 < 0 )
			monster[v2]._mVar2 = 8;
	}
	v6 = monster[v2]._mVar2;
	monster[v2]._mVar2 = v6 - 1;
	if ( v6 )
		return 0;
	v7 = monster[v2]._mAnimFrame;
	M_StartStand(v1, monster[v2]._mdir);
	monster[v2]._mAnimFrame = v7;
	return 1;
}

//----- (00435A14) --------------------------------------------------------
int __fastcall M_DoStone(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_DoStone: Invalid monster %d", i);
	v2 = v1;
	if ( !monster[v1]._mhitpoints )
	{
		v3 = monster[v2]._mx;
		monster[v2]._mDelFlag = 1;
		dMonster[0][monster[v2]._my + 112 * v3] = 0;
	}
	return 0;
}

//----- (00435A62) --------------------------------------------------------
void __fastcall M_WalkDir(int i, int md)
{
	int v2; // esi
	int v3; // edi
	int v4; // eax
	int v5; // eax
	int v6; // edx
	int v7; // ecx
	int v8; // eax
	int v9; // edx
	int v10; // eax
	int v11; // [esp-14h] [ebp-1Ch]
	int v12; // [esp-Ch] [ebp-14h]
	int v13; // [esp-Ch] [ebp-14h]
	int v14; // [esp-8h] [ebp-10h]
	int v15; // [esp-8h] [ebp-10h]
	int v16; // [esp-4h] [ebp-Ch]
	int v17; // [esp-4h] [ebp-Ch]

	v2 = i;
	v3 = md;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_WalkDir: Invalid monster %d", i);
	v4 = monster[v2].MType->Anims[1].Rate - 1;
	switch ( v3 )
	{
		case DIR_S:
			M_StartWalk2(v2, 0, MWVel[v4][1], 0, -32, 1, 1, 0);
			return;
		case DIR_SW:
			v17 = 1;
			v8 = v4;
			v15 = 1;
			v13 = 0;
			v11 = 32;
			v9 = -MWVel[v8][1];
			goto LABEL_10;
		case DIR_W:
			M_StartWalk3(v2, -MWVel[v4][2], 0, 32, -16, -1, 1, 0, 1, 2);
			return;
		case DIR_NW:
			v16 = 3;
			v10 = v4;
			v14 = 0;
			v12 = -1;
			v7 = -MWVel[v10][0];
			v6 = -MWVel[v10][1];
			goto LABEL_15;
		case DIR_N:
			M_StartWalk(v2, 0, -MWVel[v4][1], -1, -1, 4);
			break;
		case DIR_NE:
			v16 = 5;
			v5 = v4;
			v14 = -1;
			v12 = 0;
			v6 = MWVel[v5][1];
			v7 = -MWVel[v5][0];
LABEL_15:
			M_StartWalk(v2, v6, v7, v12, v14, v16);
			break;
		case DIR_E:
			M_StartWalk3(v2, MWVel[v4][2], 0, -32, -16, 1, -1, 1, 0, 6);
			break;
		case DIR_SE:
			v17 = 7;
			v8 = v4;
			v15 = 0;
			v13 = 1;
			v9 = MWVel[v8][1];
			v11 = -32;
LABEL_10:
			M_StartWalk2(v2, v9, MWVel[v8][0], v11, -16, v13, v15, v17);
			break;
		default:
			return;
	}
}

//----- (00435BB5) --------------------------------------------------------
void __fastcall GroupUnity(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // ebp
	int v4; // edi
	int v5; // eax
	int v6; // eax
	int v7; // ecx
	unsigned char v8; // al
	int v9; // ebp
	int j; // edi
	int v11; // eax
	int v12; // ecx
	int v13; // [esp+10h] [ebp-4h]

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("GroupUnity: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1].leaderflag )
	{
		v3 = (unsigned char)monster[v2].leader;
		v4 = v3;
		_LOBYTE(v5) = LineClearF(
						 (unsigned char (__cdecl *)())CheckNoSolid,
						 monster[v2]._mx,
						 monster[v2]._my,
						 monster[v4]._mfutx,
						 monster[v4]._mfuty);
		if ( v5 )
		{
			if ( monster[v2].leaderflag == 2
			  && abs(monster[v2]._mx - monster[v4]._mfutx) < 4
			  && abs(monster[v2]._my - monster[v4]._mfuty) < 4 )
			{
				++monster[v4].unpackfilesize;
				monster[v2].leaderflag = 1;
			}
		}
		else
		{
			if ( monster[v2].leaderflag != 1 )
				goto LABEL_18;
			--monster[v4].unpackfilesize;
			monster[v2].leaderflag = 2;
		}
	}
	else
	{
		v3 = v13;
	}
	if ( monster[v2].leaderflag == 1 )
	{
		v6 = v3;
		if ( _LOBYTE(monster[v2]._msquelch) > _LOBYTE(monster[v3]._msquelch) )
		{
			monster[v6]._lastx = monster[v2]._mx;
			monster[v6]._lasty = monster[v2]._my;
			_LOBYTE(monster[v6]._msquelch) = _LOBYTE(monster[v2]._msquelch) - 1;
		}
		if ( monster[v6]._mAi == MG_GARG )
		{
			v7 = monster[v6]._mFlags;
			if ( v7 & 4 )
			{
				monster[v6]._mmode = MM_SATTACK;
				monster[v6]._mFlags = v7 & 0xFFFFFFFB;
			}
		}
		return;
	}
LABEL_18:
	v8 = monster[v2]._uniqtype;
	if ( v8 )
	{
		if ( MonstAvailTbl[32 * v8 + 102] & 2 )
		{
			v9 = nummonsters;
			for ( j = 0; j < v9; ++j )
			{
				v11 = monstactive[j];
				if ( monster[v11].leaderflag == 1 && (unsigned char)monster[v11].leader == v1 )
				{
					if ( _LOBYTE(monster[v2]._msquelch) > _LOBYTE(monster[v11]._msquelch) )
					{
						monster[v11]._lastx = monster[v2]._mx;
						monster[v11]._lasty = monster[v2]._my;
						_LOBYTE(monster[v11]._msquelch) = _LOBYTE(monster[v2]._msquelch) - 1;
					}
					if ( monster[v11]._mAi == MG_GARG )
					{
						v12 = monster[v11]._mFlags;
						if ( v12 & 4 )
						{
							monster[v11]._mmode = MM_SATTACK;
							monster[v11]._mFlags = v12 & 0xFFFFFFFB;
						}
					}
				}
			}
		}
	}
}

//----- (00435DA8) --------------------------------------------------------
unsigned char __fastcall M_CallWalk(int i, int md)
{
	int v2; // esi
	int v3; // edi
	int v4; // ebp
	int v5; // eax
	int v6; // ecx
	int v7; // ebx
	int v8; // ecx
	int v9; // ebx
	int v10; // eax
	int v11; // ebx
	int v12; // eax
	int v13; // eax
	signed int v14; // ebx
	int v15; // eax
	int v16; // eax
	int v17; // eax
	unsigned char v18; // bl

	v2 = md;
	v3 = i;
	v4 = md;
	_LOBYTE(v5) = DirOK(i, md);
	_LOBYTE(v6) = 101;
	v7 = v5;
	if ( random(v6, 2) )
	{
		if ( v7 )
			goto LABEL_10;
		v9 = v2;
		v2 = left[v2];
		_LOBYTE(v10) = DirOK(v3, v2);
		if ( v10 )
			goto LABEL_10;
		v2 = right[v9];
	}
	else
	{
		if ( v7 )
			goto LABEL_10;
		v11 = v2;
		v2 = right[v2];
		_LOBYTE(v12) = DirOK(v3, v2);
		if ( v12 )
			goto LABEL_10;
		v2 = left[v11];
	}
	_LOBYTE(v13) = DirOK(v3, v2);
	if ( !v13 )
	{
		v14 = 0;
		goto LABEL_11;
	}
LABEL_10:
	v14 = 1;
LABEL_11:
	_LOBYTE(v8) = 102;
	if ( random(v8, 2) )
	{
		if ( v14 )
			goto LABEL_20;
		v2 = right[right[v4]];
		_LOBYTE(v15) = DirOK(v3, v2);
		if ( v15 )
			goto LABEL_20;
		v2 = left[left[v4]];
	}
	else
	{
		if ( v14 )
			goto LABEL_20;
		v2 = left[left[v4]];
		_LOBYTE(v16) = DirOK(v3, v2);
		if ( v16 )
			goto LABEL_20;
		v2 = right[right[v4]];
	}
	_LOBYTE(v17) = DirOK(v3, v2);
	if ( v17 )
	{
LABEL_20:
		v18 = 1;
		M_WalkDir(v3, v2);
		return v18;
	}
	return 0;
}

//----- (00435EB5) --------------------------------------------------------
int __fastcall M_PathWalk(int i)
{
	int v1; // esi
	int (__fastcall *v2)(int, int, int); // ecx
	char path[25]; // [esp+4h] [ebp-1Ch]

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("M_PathWalk: Invalid monster %d", i);
	v2 = PosOkMonst3;
	if ( !(monster[v1]._mFlags & 0x200) )
		v2 = PosOkMonst;
	if ( !FindPath(
			  v2,
			  v1,
			  monster[v1]._mx,
			  monster[v1]._my,
			  (unsigned char)monster[v1]._menemyx,
			  (unsigned char)monster[v1]._menemyy,
			  path) )
		return 0;
	M_CallWalk(v1, (char)plr2monst[path[0]]);
	return 1;
}

//----- (00435F35) --------------------------------------------------------
unsigned char __fastcall M_CallWalk2(int i, int md)
{
	int v2; // esi
	int v3; // ebx
	int v4; // eax
	int v5; // ecx
	int v6; // edi
	int v7; // edi
	int v8; // eax
	int v9; // edi
	int v10; // eax
	int v11; // eax
	unsigned char v12; // di

	v2 = md;
	v3 = i;
	_LOBYTE(v4) = DirOK(i, md);
	_LOBYTE(v5) = 101;
	v6 = v4;
	if ( random(v5, 2) )
	{
		if ( v6 )
			goto LABEL_10;
		v7 = v2;
		v2 = left[v2];
		_LOBYTE(v8) = DirOK(v3, v2);
		if ( v8 )
			goto LABEL_10;
		v2 = right[v7];
	}
	else
	{
		if ( v6 )
			goto LABEL_10;
		v9 = v2;
		v2 = right[v2];
		_LOBYTE(v10) = DirOK(v3, v2);
		if ( v10 )
			goto LABEL_10;
		v2 = left[v9];
	}
	_LOBYTE(v11) = DirOK(v3, v2);
	if ( v11 )
	{
LABEL_10:
		v12 = 1;
		M_WalkDir(v3, v2);
		return v12;
	}
	return 0;
}

//----- (00435FBA) --------------------------------------------------------
unsigned char __fastcall M_DumbWalk(int i, int md)
{
	int v2; // esi
	int v3; // edi
	int v4; // eax
	unsigned char v5; // bl

	v2 = md;
	v3 = i;
	_LOBYTE(v4) = DirOK(i, md);
	v5 = v4;
	if ( v4 )
		M_WalkDir(v3, v2);
	return v5;
}

//----- (00435FDB) --------------------------------------------------------
unsigned char __fastcall M_RoundWalk(int i, int md, int *dir)
{
	int *v3; // ebp
	int v4; // ebx
	int v5; // esi
	int v6; // eax
	unsigned char v7; // di
	int v8; // edi
	int v9; // eax
	int v10; // eax
	int *v11; // ebp
	int v12; // eax
	int v13; // eax

	v3 = dir;
	v4 = i;
	if ( *dir )
		v5 = left[left[md]];
	else
		v5 = right[right[md]];
	_LOBYTE(v6) = DirOK(i, v5);
	v7 = v6;
	if ( v6 )
		goto LABEL_12;
	v8 = v5;
	if ( !*dir )
	{
		v11 = &left[v8];
		v5 = left[v8];
		_LOBYTE(v12) = DirOK(v4, left[v8]);
		if ( v12 )
			goto LABEL_11;
		v5 = left[*v11];
		_LOBYTE(v13) = DirOK(v4, left[*v11]);
		if ( v13 )
			goto LABEL_11;
		v3 = dir;
LABEL_14:
		*v3 = *v3 == 0;
		return M_CallWalk(v4, opposite[v8]);
	}
	v5 = right[v8];
	_LOBYTE(v9) = DirOK(v4, right[v8]);
	if ( !v9 )
	{
		v5 = right[right[v8]];
		_LOBYTE(v10) = DirOK(v4, v5);
		if ( !v10 )
			goto LABEL_14;
	}
LABEL_11:
	v7 = 1;
LABEL_12:
	M_WalkDir(v4, v5);
	return v7;
}

//----- (004360B1) --------------------------------------------------------
void __fastcall MAI_Zombie(int i)
{
	int v1; // esi
	int v2; // ST04_4
	MonsterStruct *v3; // esi
	int v4; // edi
	int v5; // ebx
	int v6; // edi
	int v7; // eax
	int v8; // ecx
	int v9; // eax
	int v10; // eax
	int v11; // eax
	int v12; // ecx
	int md; // [esp+Ch] [ebp-Ch]
	int v14; // [esp+10h] [ebp-8h]
	int arglist; // [esp+14h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
	{
		TermMsg("MAI_Zombie: Invalid monster %d", i);
		i = v2;
	}
	v3 = &monster[v1];
	if ( v3->_mmode == MM_STAND )
	{
		v4 = v3->_my;
		if ( dFlags[v3->_mx][v4] & 2 )
		{
			v5 = v3->_mx - (unsigned char)v3->_menemyx;
			v6 = v4 - (unsigned char)v3->_menemyy;
			_LOBYTE(i) = 103;
			md = v3->_mdir;
			v14 = random(i, 100);
			if ( abs(v5) >= 2 || abs(v6) >= 2 )
			{
				if ( v14 < 2 * (unsigned char)v3->_mint + 10 )
				{
					v7 = abs(v5);
					v8 = 2 * (unsigned char)v3->_mint + 4;
					if ( v7 >= v8 || (v9 = abs(v6), v8 = 2 * (unsigned char)v3->_mint + 4, v9 >= v8) )
					{
						_LOBYTE(v8) = 104;
						v11 = random(v8, 100);
						v12 = 2 * (unsigned char)v3->_mint + 20;
						if ( v11 < v12 )
						{
							_LOBYTE(v12) = 104;
							md = random(v12, 8);
						}
						M_DumbWalk(arglist, md);
					}
					else
					{
						v10 = M_GetDir(arglist);
						M_CallWalk(arglist, v10);
					}
				}
			}
			else if ( v14 < 2 * (unsigned char)v3->_mint + 10 )
			{
				M_StartAttack(arglist);
			}
			if ( v3->_mmode == MM_STAND )
				v3->_mAFNum = v3->MType->Anims[0].Frames[v3->_mdir + 1];
		}
	}
}

//----- (004361F7) --------------------------------------------------------
void __fastcall MAI_SkelSd(int i)
{
	int v1; // esi
	MonsterStruct *v2; // esi
	int v3; // ecx
	int v4; // edx
	int v5; // edi
	int v6; // ebp
	int v7; // ebx
	int v8; // eax
	int v9; // ST04_4
	int v10; // ecx
	int v11; // eax
	int v12; // ST04_4
	int v13; // eax
	int v14; // ecx
	int v15; // edx
	int v16; // eax
	int v17; // ecx
	int arglist; // [esp+8h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_SkelSd: Invalid monster %d", i);
	v2 = &monster[v1];
	if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) )
	{
		v3 = v2->_mx;
		v4 = v2->_my;
		v5 = v3 - (unsigned char)v2->_menemyx;
		v6 = v4 - (unsigned char)v2->_menemyy;
		v7 = GetDirection(v3, v4, v2->_lastx, v2->_lasty);
		v2->_mdir = v7;
		v8 = abs(v5);
		v10 = v9;
		if ( v8 >= 2 || (v11 = abs(v6), v10 = v12, v11 >= 2) )
		{
			if ( v2->_mVar1 != 13 )
			{
				_LOBYTE(v10) = 106;
				v16 = random(v10, 100);
				v17 = 4 * (unsigned char)v2->_mint;
				if ( v16 < 35 - v17 )
				{
					_LOBYTE(v17) = 106;
					v15 = 15 - 2 * (unsigned char)v2->_mint + random(v17, 10);
					goto LABEL_10;
				}
			}
			M_CallWalk(arglist, v7);
		}
		else
		{
			if ( v2->_mVar1 != 13 )
			{
				_LOBYTE(v10) = 105;
				v13 = random(v10, 100);
				v14 = 2 * (unsigned char)v2->_mint + 20;
				if ( v13 >= v14 )
				{
					_LOBYTE(v14) = 105;
					v15 = random(v14, 10) + 2 * (5 - (unsigned char)v2->_mint);
LABEL_10:
					M_StartDelay(arglist, v15);
					goto LABEL_16;
				}
			}
			M_StartAttack(arglist);
		}
LABEL_16:
		if ( v2->_mmode == MM_STAND )
			v2->_mAFNum = v2->MType->Anims[0].Frames[v7 + 1];
	}
}

//----- (00436331) --------------------------------------------------------
void __fastcall MAI_Path(int i)
{
	int v1; // edi
	MonsterStruct *v2; // esi
	char v3; // al
	int v4; // eax
	unsigned char v5; // al

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Path: Invalid monster %d", i);
	v2 = &monster[v1];
	if ( v2->MType->mtype == MON_GOLEM
	  || _LOBYTE(v2->_msquelch)
	  && v2->_mmode == MM_STAND
	  && ((v3 = v2->_mgoal, v3 == 1) || v3 == 4 || v3 == 5)
	  && (v2->_mx != 1 || v2->_my) )
	{
		_LOBYTE(v4) = LineClearF1(
						 (unsigned char (__cdecl *)())PosOkMonst2,
						 v1,
						 v2->_mx,
						 v2->_my,
						 (unsigned char)v2->_menemyx,
						 (unsigned char)v2->_menemyy);
		if ( v4 )
		{
			v5 = v2->_pathcount;
			if ( v5 < 5u || v5 >= 8u )
				goto LABEL_22;
		}
		if ( v2->_mFlags & 0x200 )
			MonstCheckDoors(v1);
		if ( ++_LOBYTE(v2->_pathcount) >= 5u && !M_PathWalk(v1) )
		{
LABEL_22:
			if ( v2->MType->mtype != MON_GOLEM )
				_LOBYTE(v2->_pathcount) = 0;
		}
	}
}

//----- (004363F9) --------------------------------------------------------
void __fastcall MAI_Snake(int i)
{
	int esi1; // esi
	MonsterStruct *esi3; // esi
	bool v3; // zf
	int v4; // ecx
	int v5; // eax
	int v6; // ST1C_4
	int v7; // edi
	int v8; // edx
	int v9; // ST18_4
	int v10; // ebx
	int v11; // eax
	int v12; // ST1C_4
	int v13; // ecx
	int v14; // eax
	int v15; // eax
	int v16; // ecx
	int v17; // edx
	int v18; // ecx
	int v19; // eax
	int v20; // ST1C_4
	int v21; // ecx
	int v22; // eax
	int v23; // ST1C_4
	int v24; // ebx
	int v25; // eax
	int v26; // ecx
	int v27; // eax
	int v28; // ecx
	int v29; // ecx
	int v30; // eax
	int v31; // edx
	int v32; // eax
	int v33; // ecx
	int v34; // ecx
	int v35; // eax
	int v36; // eax
	char v37; // [esp+4h] [ebp-1Ch]
	char v38; // [esp+5h] [ebp-1Bh]
	char v39; // [esp+6h] [ebp-1Ah]
	char v40; // [esp+7h] [ebp-19h]
	char v41; // [esp+8h] [ebp-18h]
	char v42; // [esp+9h] [ebp-17h]
	int micaster; // [esp+Ch] [ebp-14h]
	int midir; // [esp+10h] [ebp-10h]
	int v1; // [esp+14h] [ebp-Ch]
	int v2; // [esp+18h] [ebp-8h]
	char arglist[4]; // [esp+1Ch] [ebp-4h]

	esi1 = i;
	*(_DWORD *)arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Snake: Invalid monster %d", i);
	v39 = 0;
	v40 = -1;
	v41 = -1;
	v42 = 0;
	esi3 = &monster[esi1];
	v37 = 1;
	v38 = 1;
	v3 = esi3->_mmode == 0;
	micaster = esi3->_menemy;
	if ( v3 && _LOBYTE(esi3->_msquelch) )
	{
		v4 = esi3->_mx;
		v5 = (unsigned char)esi3->_menemyy;
		v6 = esi3->_lasty;
		v1 = (unsigned char)esi3->_menemyx;
		v7 = v4 - v1;
		v8 = esi3->_my;
		v9 = esi3->_lastx;
		v2 = v5;
		v10 = v8 - v5;
		midir = GetDirection(v4, v8, v9, v6);
		esi3->_mdir = midir;
		if ( abs(v7) < 2 )
		{
			v11 = abs(v10);
			v13 = v12;
			if ( v11 < 2 )
			{
				v14 = esi3->_mVar1;
				if ( v14 == 13
				  || v14 == 14
				  || (_LOBYTE(v13) = 105, v15 = random(v13, 100), v16 = (unsigned char)esi3->_mint + 20, v15 < v16) )
				{
					M_StartAttack(*(int *)arglist);
LABEL_49:
					if ( esi3->_mmode == MM_STAND )
						esi3->_mAFNum = esi3->MType->Anims[0].Frames[esi3->_mdir + 1];
					return;
				}
				_LOBYTE(v16) = 105;
				v17 = 10 - (unsigned char)esi3->_mint + random(v16, 10);
				v18 = *(_DWORD *)arglist;
LABEL_11:
				M_StartDelay(v18, v17);
				goto LABEL_49;
			}
		}
		v19 = abs(v7);
		v21 = v20;
		if ( v19 >= 3 || (v22 = abs(v10), v21 = v23, v22 >= 3) )
		{
			v24 = *(_DWORD *)arglist;
		}
		else
		{
			v24 = *(_DWORD *)arglist;
			_LOBYTE(v25) = LineClearF1(
							  (unsigned char (__cdecl *)())PosOkMonst,
							  *(int *)arglist,
							  esi3->_mx,
							  esi3->_my,
							  v1,
							  v2);
			if ( v25 && esi3->_mVar1 != 14 )
			{
				if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, micaster, *(int *)arglist, 0, 0) != -1 )
				{
					PlayEffect(*(int *)arglist, 0);
					v26 = esi3->_my + 112 * esi3->_mx;
					esi3->_mmode = 14;
					dMonster[0][v26] = -1 - v24;
				}
				goto LABEL_49;
			}
		}
		if ( esi3->_mVar1 != 13 )
		{
			_LOBYTE(v21) = 106;
			v27 = random(v21, 100);
			v28 = 2 * (unsigned char)esi3->_mint;
			if ( v27 < 35 - v28 )
			{
				_LOBYTE(v28) = 106;
				v17 = 15 - (unsigned char)esi3->_mint + random(v28, 10);
				v18 = v24;
				goto LABEL_11;
			}
		}
		v29 = esi3->_mgoalvar1;
		v30 = midir + *(&v37 + v29);
		if ( v30 >= 0 )
		{
			v31 = v30 - 8;
			if ( v30 < 8 )
				v31 = midir + *(&v37 + v29);
		}
		else
		{
			v31 = v30 + 8;
		}
		esi3->_mgoalvar1 = v29 + 1;
		if ( v29 + 1 > 5 )
			esi3->_mgoalvar1 = 0;
		v32 = esi3->_mgoalvar2;
		v33 = v31 - v32;
		if ( v31 - v32 >= 0 )
		{
			if ( v33 >= 8 )
				v33 -= 8;
		}
		else
		{
			v33 += 8;
		}
		if ( v33 <= 0 )
		{
LABEL_47:
			_LOBYTE(v36) = M_DumbWalk(v24, esi3->_mgoalvar2);
			if ( !v36 )
				M_CallWalk2(v24, esi3->_mdir);
			goto LABEL_49;
		}
		if ( v33 >= 4 )
		{
			if ( v33 == 4 )
			{
				esi3->_mgoalvar2 = v31;
				goto LABEL_47;
			}
			v34 = v32 - 1;
			if ( v32 - 1 < 0 )
			{
				v35 = v32 + 7;
				goto LABEL_46;
			}
			if ( v34 >= 8 )
			{
				v35 = v32 - 9;
				goto LABEL_46;
			}
		}
		else
		{
			v34 = v32 + 1;
			if ( v32 + 1 < 0 )
			{
				v35 = v32 + 9;
LABEL_46:
				esi3->_mgoalvar2 = v35;
				goto LABEL_47;
			}
			if ( v34 >= 8 )
			{
				v35 = v32 - 7;
				goto LABEL_46;
			}
		}
		v35 = v34;
		goto LABEL_46;
	}
}

//----- (0043668F) --------------------------------------------------------
void __fastcall MAI_Bat(int i)
{
	int esi1; // esi
	MonsterStruct *esi3; // esi
	int v3; // ecx
	int v4; // edx
	int v5; // edi
	int v6; // ebx
	int v7; // eax
	int v8; // ecx
	int v9; // ecx
	int v10; // edx
	int v11; // eax
	int v12; // ecx
	int v13; // ecx
	CMonster *v14; // eax
	int v15; // edi
	int v16; // eax
	signed int v17; // ecx
	int v18; // eax
	int micaster; // [esp+Ch] [ebp-18h]
	int v1; // [esp+10h] [ebp-14h]
	int v2; // [esp+14h] [ebp-10h]
	int v22; // [esp+18h] [ebp-Ch]
	int midir; // [esp+1Ch] [ebp-8h]
	int arglist; // [esp+20h] [ebp-4h]

	esi1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Bat: Invalid monster %d", i);
	esi3 = &monster[esi1];
	micaster = esi3->_menemy;
	if ( esi3->_mmode == MM_STAND && _LOBYTE(esi3->_msquelch) )
	{
		v3 = esi3->_mx;
		v4 = esi3->_my;
		v5 = v3 - (unsigned char)esi3->_menemyx;
		v6 = v4 - (unsigned char)esi3->_menemyy;
		v7 = GetDirection(v3, v4, esi3->_lastx, esi3->_lasty);
		_LOBYTE(v8) = 107;
		midir = v7;
		esi3->_mdir = v7;
		v22 = random(v8, 100);
		if ( _LOBYTE(esi3->_mgoal) == 2 )
		{
			if ( esi3->_mgoalvar1 )
			{
				_LOBYTE(v9) = 108;
				if ( random(v9, 2) )
					v10 = left[midir];
				else
					v10 = right[midir];
				M_CallWalk(arglist, v10);
				_LOBYTE(esi3->_mgoal) = 1;
			}
			else
			{
				M_CallWalk(arglist, opposite[midir]);
				++esi3->_mgoalvar1;
			}
		}
		else
		{
			v1 = (unsigned char)esi3->_menemyx;
			v2 = (unsigned char)esi3->_menemyy;
			if ( esi3->MType->mtype == MON_BATC
			  && (abs(v5) >= 5 || abs(v6) >= 5)
			  && v22 < 4 * (unsigned char)esi3->_mint + 33
			  && (_LOBYTE(v11) = LineClearF1(
									(unsigned char (__cdecl *)())PosOkMonst,
									arglist,
									esi3->_mx,
									esi3->_my,
									v1,
									v2),
				  v11) )
			{
				if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, micaster, arglist, 0, 0) != -1 )
				{
					v12 = esi3->_my + 112 * esi3->_mx;
					esi3->_mmode = 14;
					dMonster[0][v12] = -1 - arglist;
				}
			}
			else if ( abs(v5) >= 2 || abs(v6) >= 2 )
			{
				v17 = esi3->_mVar2;
				if ( v17 > 20 && v22 < (unsigned char)esi3->_mint + 13
				  || ((v18 = esi3->_mVar1, v18 == 1) || v18 == 2 || v18 == 3)
				  && !v17
				  && v22 < (unsigned char)esi3->_mint + 63 )
				{
					M_CallWalk(arglist, midir);
				}
			}
			else if ( v22 < 4 * (unsigned char)esi3->_mint + 8 )
			{
				M_StartAttack(arglist);
				v14 = esi3->MType;
				esi3->_mgoalvar1 = 0;
				_LOBYTE(esi3->_mgoal) = 2;
				if ( v14->mtype == 41 )
				{
					v15 = (unsigned char)esi3->_menemyx;
					_LOBYTE(v13) = 109;
					v16 = random(v13, 10);
					AddMissile(v15, (unsigned char)esi3->_menemyy, v15 + 1, 0, -1, 8, 1, arglist, v16 + 1, 0);
				}
			}
			if ( esi3->_mmode == MM_STAND )
				esi3->_mAFNum = esi3->MType->Anims[0].Frames[midir + 1];
		}
	}
}

//----- (004368F7) --------------------------------------------------------
void __fastcall MAI_SkelBow(int i)
{
	int v1; // esi
	MonsterStruct *v2; // esi
	int v3; // edi
	int v4; // ebx
	int v5; // eax
	int v6; // ecx
	int v7; // eax
	int v8; // ST04_4
	int v9; // ecx
	int v10; // eax
	int v11; // ST04_4
	int v12; // eax
	int v13; // eax
	int v14; // edi
	int v15; // ebx
	int v16; // eax
	int v17; // [esp+4h] [ebp-10h]
	int v18; // [esp+8h] [ebp-Ch]
	int v19; // [esp+Ch] [ebp-8h]
	int arglist; // [esp+10h] [ebp-4h]

	v18 = 0;
	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_SkelBow: Invalid monster %d", i);
	v2 = &monster[v1];
	if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) )
	{
		v3 = v2->_mx - (unsigned char)v2->_menemyx;
		v4 = v2->_my - (unsigned char)v2->_menemyy;
		v5 = M_GetDir(arglist);
		_LOBYTE(v6) = 110;
		v17 = v5;
		v2->_mdir = v5;
		v19 = random(v6, 100);
		v7 = abs(v3);
		v9 = v8;
		if ( v7 < 4 )
		{
			v10 = abs(v4);
			v9 = v11;
			if ( v10 < 4 )
			{
				if ( (v9 = v2->_mVar2, v9 > 20) && v19 < 2 * (unsigned char)v2->_mint + 13
				  || ((v12 = v2->_mVar1, v12 == 1) || v12 == 2 || v12 == 3)
				  && !v9
				  && v19 < 2 * (unsigned char)v2->_mint + 63 )
				{
					_LOBYTE(v13) = M_DumbWalk(arglist, opposite[v17]);
					v18 = v13;
				}
			}
		}
		v14 = (unsigned char)v2->_menemyx;
		v15 = (unsigned char)v2->_menemyy;
		if ( !v18 )
		{
			_LOBYTE(v9) = 110;
			if ( random(v9, 100) < 2 * (unsigned char)v2->_mint + 3 )
			{
				_LOBYTE(v16) = LineClear(v2->_mx, v2->_my, v14, v15);
				if ( v16 )
					M_StartRAttack(arglist, 0, 4);
			}
		}
		if ( v2->_mmode == MM_STAND )
			v2->_mAFNum = v2->MType->Anims[0].Frames[v17 + 1];
	}
}

//----- (00436A38) --------------------------------------------------------
void __fastcall MAI_Fat(int i)
{
	int v1; // esi
	MonsterStruct *v2; // esi
	int v3; // edi
	int v4; // ebx
	int v5; // eax
	int v6; // ecx
	int v7; // eax
	signed int v8; // ecx
	int v9; // eax
	int md; // [esp+4h] [ebp-Ch]
	int arglist; // [esp+8h] [ebp-8h]
	int v12; // [esp+Ch] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Fat: Invalid monster %d", i);
	v2 = &monster[v1];
	if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) )
	{
		v3 = v2->_mx - (unsigned char)v2->_menemyx;
		v4 = v2->_my - (unsigned char)v2->_menemyy;
		v5 = M_GetDir(arglist);
		_LOBYTE(v6) = 111;
		md = v5;
		v2->_mdir = v5;
		v12 = random(v6, 100);
		if ( abs(v3) >= 2 || abs(v4) >= 2 )
		{
			v8 = v2->_mVar2;
			if ( v8 > 20 && v12 < 4 * (unsigned char)v2->_mint + 20
			  || ((v9 = v2->_mVar1, v9 == 1) || v9 == 2 || v9 == 3) && !v8 && v12 < 4 * (unsigned char)v2->_mint + 70 )
			{
				M_CallWalk(arglist, md);
			}
		}
		else
		{
			v7 = (unsigned char)v2->_mint;
			if ( v12 >= 4 * v7 + 15 )
			{
				if ( v12 < 4 * v7 + 20 )
					M_StartSpAttack(arglist);
			}
			else
			{
				M_StartAttack(arglist);
			}
		}
		if ( v2->_mmode == MM_STAND )
			v2->_mAFNum = v2->MType->Anims[0].Frames[md + 1];
	}
}

//----- (00436B60) --------------------------------------------------------
void __fastcall MAI_Sneak(int i)
{
	int v1; // edi
	MonsterStruct *v2; // esi
	int v3; // ebx
	int v4; // ebx
	int v5; // ecx
	int v6; // edi
	int v7; // eax
	int v8; // ST04_4
	int v9; // eax
	int v10; // ST04_4
	int v11; // eax
	int v12; // edi
	signed int v13; // ecx
	int v14; // eax
	int v15; // [esp+Ch] [ebp-10h]
	int arglist; // [esp+10h] [ebp-Ch]
	int v17; // [esp+14h] [ebp-8h]
	int md; // [esp+18h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Sneak: Invalid monster %d", i);
	v2 = &monster[v1];
	if ( v2->_mmode == MM_STAND )
	{
		v3 = v2->_my;
		if ( dTransVal[v2->_mx][v3] != lightmax )
		{
			v17 = v2->_mx - (unsigned char)v2->_menemyx;
			v4 = v3 - (unsigned char)v2->_menemyy;
			md = M_GetDir(v1);
			v6 = 5 - (unsigned char)v2->_mint;
			if ( v2->_mVar1 == 5 )
			{
				v2->_mgoalvar1 = 0;
				_LOBYTE(v2->_mgoal) = 2;
			}
			else
			{
				v7 = abs(v17);
				v5 = v8;
				if ( v7 >= v6 + 3 || (v9 = abs(v4), v5 = v10, v9 >= v6 + 3) || v2->_mgoalvar1 > 8 )
				{
					v2->_mgoalvar1 = 0;
					_LOBYTE(v2->_mgoal) = 1;
				}
			}
			if ( _LOBYTE(v2->_mgoal) == 2 )
			{
				if ( v2->_mFlags & 0x10 )
					md = GetDirection(v2->_mx, v2->_my, plr[v2->_menemy]._pownerx, plr[v2->_menemy]._pownery);
				md = opposite[md];
				if ( v2->MType->mtype == MON_SNEAKC )
				{
					_LOBYTE(v5) = 112;
					if ( random(v5, 2) )
						v11 = left[md];
					else
						v11 = right[md];
					md = v11;
				}
			}
			_LOBYTE(v5) = 112;
			v2->_mdir = md;
			v15 = random(v5, 100);
			if ( abs(v17) < v6 && abs(v4) < v6 && v2->_mFlags & 1 )
			{
				M_StartFadein(arglist, md, 0);
			}
			else
			{
				v12 = v6 + 1;
				if ( abs(v17) < v12 && abs(v4) < v12 || v2->_mFlags & 1 )
				{
					if ( _LOBYTE(v2->_mgoal) == 2
					  || (abs(v17) >= 2 || abs(v4) >= 2)
					  && ((v13 = v2->_mVar2, v13 > 20) && v15 < 4 * (unsigned char)v2->_mint + 14
					   || ((v14 = v2->_mVar1, v14 == 1) || v14 == 2 || v14 == 3)
					   && !v13
					   && v15 < 4 * (unsigned char)v2->_mint + 64) )
					{
						++v2->_mgoalvar1;
						M_CallWalk(arglist, md);
					}
				}
				else
				{
					M_StartFadeout(arglist, md, 1u);
				}
			}
			if ( v2->_mmode == MM_STAND )
			{
				if ( abs(v17) >= 2 || abs(v4) >= 2 || v15 >= 4 * (unsigned char)v2->_mint + 10 )
					v2->_mAFNum = v2->MType->Anims[0].Frames[md + 1];
				else
					M_StartAttack(arglist);
			}
		}
	}
}
// 642A14: using guessed type char lightmax;

//----- (00436DC8) --------------------------------------------------------
void __fastcall MAI_Fireman(int i)
{
	int esi1; // esi
	int esi3; // esi
	int v3; // ecx
	int v4; // eax
	int v5; // ebx
	int v6; // edi
	int v7; // edx
	int v8; // ecx
	char v9; // al
	int v10; // eax
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	int v14; // eax
	int v15; // edx
	int v16; // eax
	int v17; // eax
	int micaster; // [esp+Ch] [ebp-14h]
	int v1; // [esp+10h] [ebp-10h]
	int v2; // [esp+14h] [ebp-Ch]
	int midir; // [esp+18h] [ebp-8h]
	int arglist; // [esp+1Ch] [ebp-4h]

	esi1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Fireman: Invalid monster %d", i);
	esi3 = esi1;
	if ( monster[esi3]._mmode || !_LOBYTE(monster[esi3]._msquelch) )
		return;
	v3 = (unsigned char)monster[esi3]._menemyy;
	micaster = monster[esi3]._menemy;
	v4 = (unsigned char)monster[esi3]._menemyx;
	v2 = v3;
	v5 = monster[esi3]._my - v3;
	v1 = v4;
	v6 = monster[esi3]._mx - v4;
	v7 = M_GetDir(arglist);
	v9 = monster[esi3]._mgoal;
	midir = v7;
	switch ( v9 )
	{
		case 1:
			_LOBYTE(v10) = LineClear(monster[esi3]._mx, monster[esi3]._my, v1, v2);
			if ( !v10
			  || AddMissile(monster[esi3]._mx, monster[esi3]._my, v1, v2, midir, 50, micaster, arglist, 0, 0) == -1 )
			{
				break;
			}
			monster[esi3]._mgoalvar1 = 0;
			monster[esi3]._mmode = MM_CHARGE;
			goto LABEL_18;
		case 5:
			if ( monster[esi3]._mgoalvar1 == 3 )
			{
				_LOBYTE(monster[esi3]._mgoal) = 1;
				M_StartFadeout(arglist, v7, 1u);
			}
			else
			{
				_LOBYTE(v11) = LineClear(monster[esi3]._mx, monster[esi3]._my, v1, v2);
				if ( v11 )
				{
					M_StartRAttack(arglist, 51, 4);
				}
				else
				{
					_LOBYTE(v12) = 112;
					v13 = random(v12, 10);
					M_StartDelay(arglist, v13 + 5);
				}
				++monster[esi3]._mgoalvar1;
			}
			break;
		case 2:
			M_StartFadein(arglist, v7, 0);
LABEL_18:
			_LOBYTE(monster[esi3]._mgoal) = 5;
			break;
	}
	_LOBYTE(v8) = 112;
	monster[esi3]._mdir = midir;
	random(v8, 100);
	if ( monster[esi3]._mmode )
		return;
	if ( abs(v6) < 2 && abs(v5) < 2 && _LOBYTE(monster[esi3]._mgoal) == 1 )
	{
		M_TryH2HHit(
			arglist,
			monster[esi3]._menemy,
			(unsigned char)monster[esi3].mHit,
			(unsigned char)monster[esi3].mMinDamage,
			(unsigned char)monster[esi3].mMaxDamage);
		_LOBYTE(monster[esi3]._mgoal) = 2;
		_LOBYTE(v14) = M_CallWalk(arglist, opposite[midir]);
		if ( v14 )
			return;
		v15 = midir;
		goto LABEL_29;
	}
	_LOBYTE(v16) = M_CallWalk(arglist, midir);
	if ( !v16 )
	{
		v17 = _LOBYTE(monster[esi3]._mgoal);
		if ( (_BYTE)v17 == 1 || (_BYTE)v17 == 2 )
		{
			v15 = midir;
LABEL_29:
			M_StartFadein(arglist, v15, 0);
			_LOBYTE(monster[esi3]._mgoal) = 5;
			return;
		}
	}
}

//----- (00436FEC) --------------------------------------------------------
void __fastcall MAI_Fallen(int i)
{
	int v1; // edi
	int v2; // ST04_4
	int v3; // esi
	int v4; // eax
	int v5; // ecx
	int *v6; // eax
	int v7; // edx
	int v8; // edx
	int j; // edi
	int k; // ecx
	int v11; // eax
	int v12; // eax
	char v13; // al
	int v14; // edx
	int v15; // eax
	int v16; // esi

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
	{
		TermMsg("MAI_Fallen: Invalid monster %d", i);
		i = v2;
	}
	v3 = v1;
	if ( _LOBYTE(monster[v1]._mgoal) == 5 )
	{
		i = monster[v3]._mgoalvar1;
		if ( i )
			monster[v3]._mgoalvar1 = --i;
		else
			_LOBYTE(monster[v3]._mgoal) = 1;
	}
	if ( monster[v3]._mmode == MM_STAND && _LOBYTE(monster[v3]._msquelch) )
	{
		if ( _LOBYTE(monster[v3]._mgoal) == 2 )
		{
			i = monster[v3]._mgoalvar1;
			monster[v3]._mgoalvar1 = i - 1;
			if ( !i )
			{
				v4 = monster[v3]._mdir;
				_LOBYTE(monster[v3]._mgoal) = 1;
				M_StartStand(v1, opposite[v4]);
			}
		}
		if ( monster[v3]._mAnimFrame != monster[v3]._mAnimLen )
		{
			v13 = monster[v3]._mgoal;
			if ( v13 == 2 )
			{
				v14 = monster[v3]._mdir;
			}
			else
			{
				if ( v13 != 5 )
				{
					MAI_SkelSd(v1);
					return;
				}
				v15 = monster[v3]._mx - (unsigned char)monster[v3]._menemyx;
				v16 = monster[v3]._my - (unsigned char)monster[v3]._menemyy;
				if ( abs(v15) < 2 && abs(v16) < 2 )
				{
					M_StartAttack(v1);
					return;
				}
				v14 = M_GetDir(v1);
			}
			M_CallWalk(v1, v14);
			return;
		}
		_LOBYTE(i) = 113;
		if ( !random(i, 4) )
		{
			if ( !(monster[v3]._mFlags & 8) )
			{
				M_StartSpStand(v1, monster[v3]._mdir);
				v5 = 2 * (unsigned char)monster[v3]._mint + 2;
				v6 = &monster[v3]._mhitpoints;
				v7 = monster[v3]._mhitpoints;
				if ( monster[v3]._mmaxhp - v5 < v7 )
					*v6 = monster[v3]._mmaxhp;
				else
					*v6 = v5 + v7;
			}
			v8 = 2 * (unsigned char)monster[v3]._mint + 4;
			for ( j = -v8; j <= v8; ++j )
			{
				for ( k = -v8; k <= v8; ++k )
				{
					if ( j >= 0 && j < 112 && k >= 0 && k < 112 )
					{
						v11 = dMonster[0][j + monster[v3]._my + 112 * (k + monster[v3]._mx)];
						if ( v11 > 0 )
						{
							v12 = v11 - 1;
							if ( monster[v12]._mAi == MG_FALLEN )
							{
								_LOBYTE(monster[v12]._mgoal) = 5;
								monster[v12]._mgoalvar1 = 30 * (unsigned char)monster[v3]._mint + 105;
							}
						}
					}
				}
			}
		}
	}
}

//----- (004371D7) --------------------------------------------------------
void __fastcall MAI_Cleaver(int i)
{
	int v1; // esi
	MonsterStruct *v2; // esi
	int v3; // ecx
	int v4; // edx
	int v5; // edi
	int v6; // ebp
	int v7; // ebx
	int arglist; // [esp+8h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Cleaver: Invalid monster %d", i);
	v2 = &monster[v1];
	if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) )
	{
		v3 = v2->_mx;
		v4 = v2->_my;
		v5 = v3 - (unsigned char)v2->_menemyx;
		v6 = v4 - (unsigned char)v2->_menemyy;
		v7 = GetDirection(v3, v4, v2->_lastx, v2->_lasty);
		v2->_mdir = v7;
		if ( abs(v5) >= 2 || abs(v6) >= 2 )
			M_CallWalk(arglist, v7);
		else
			M_StartAttack(arglist);
		if ( v2->_mmode == MM_STAND )
			v2->_mAFNum = v2->MType->Anims[0].Frames[v7 + 1];
	}
}

//----- (00437285) --------------------------------------------------------
void __fastcall MAI_Round(int i, unsigned char special)
{
	int v2; // esi
	MonsterStruct *v3; // esi
	int v4; // edx
	int v5; // ecx
	int v6; // edi
	int v7; // ebx
	int v8; // ecx
	int v9; // eax
	int v10; // ST04_4
	int v11; // ecx
	int v12; // eax
	int v13; // ST04_4
	int v14; // ecx
	int v15; // edi
	int v16; // eax
	int v17; // ecx
	int v18; // eax
	int v19; // eax
	int v20; // ecx
	int v21; // eax
	int v22; // eax
	int v23; // ST04_4
	int v24; // ecx
	signed int v25; // ecx
	int v26; // eax
	int v27; // [esp+4h] [ebp-18h]
	int v28; // [esp+8h] [ebp-14h]
	char *v29; // [esp+8h] [ebp-14h]
	int v30; // [esp+Ch] [ebp-10h]
	int md; // [esp+10h] [ebp-Ch]
	int v32; // [esp+14h] [ebp-8h]
	int arglist; // [esp+18h] [ebp-4h]

	v2 = i;
	v27 = special;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Round: Invalid monster %d", i);
	v3 = &monster[v2];
	if ( v3->_mmode == MM_STAND && _LOBYTE(v3->_msquelch) )
	{
		v4 = v3->_my;
		v5 = v3->_mx;
		v28 = (unsigned char)v3->_menemyy;
		v6 = (unsigned char)v3->_menemyx;
		v7 = v5 - v6;
		v32 = v4 - v28;
		md = GetDirection(v5, v4, v3->_lastx, v3->_lasty);
		if ( _LOBYTE(v3->_msquelch) < 0xFFu )
			MonstCheckDoors(arglist);
		_LOBYTE(v8) = 114;
		v30 = random(v8, 100);
		if ( (abs(v7) >= 2 || abs(v32) >= 2) && _LOBYTE(v3->_msquelch) == -1 )
		{
			v29 = &dung_map[v6][v28];
			if ( dung_map[v3->_mx][v3->_my] == *v29 )
			{
				if ( _LOBYTE(v3->_mgoal) != 4 )
				{
					v9 = abs(v7);
					v11 = v10;
					if ( v9 < 4 )
					{
						v12 = abs(v32);
						v11 = v13;
						if ( v12 < 4 )
							goto LABEL_26;
					}
					_LOBYTE(v11) = 115;
					if ( random(v11, 4) )
						goto LABEL_26;
					if ( _LOBYTE(v3->_mgoal) != 4 )
					{
						v3->_mgoalvar1 = 0;
						_LOBYTE(v14) = 116;
						v3->_mgoalvar2 = random(v14, 2);
					}
				}
				_LOBYTE(v3->_mgoal) = 4;
				v15 = abs(v32);
				if ( abs(v7) <= v15 )
					v16 = abs(v32);
				else
					v16 = abs(v7);
				v17 = v3->_mgoalvar1;
				v3->_mgoalvar1 = v17 + 1;
				if ( v17 < 2 * v16 || (_LOBYTE(v18) = DirOK(arglist, md), !v18) )
				{
					if ( dung_map[v3->_mx][v3->_my] == *v29 )
					{
						_LOBYTE(v19) = M_RoundWalk(arglist, md, &v3->_mgoalvar2);
						if ( !v19 )
						{
							_LOBYTE(v20) = 125;
							v21 = random(v20, 10);
							M_StartDelay(arglist, v21 + 10);
						}
						goto LABEL_26;
					}
				}
			}
		}
		_LOBYTE(v3->_mgoal) = 1;
LABEL_26:
		if ( _LOBYTE(v3->_mgoal) == 1 )
		{
			if ( abs(v7) >= 2 || (v22 = abs(v32), v24 = v23, v22 >= 2) )
			{
				v25 = v3->_mVar2;
				if ( v25 > 20 && v30 < 2 * (unsigned char)v3->_mint + 28
				  || ((v26 = v3->_mVar1, v26 == 1) || v26 == 2 || v26 == 3)
				  && !v25
				  && v30 < 2 * (unsigned char)v3->_mint + 78 )
				{
					M_CallWalk(arglist, md);
				}
			}
			else if ( v30 < 2 * (unsigned char)v3->_mint + 23 )
			{
				v3->_mdir = md;
				if ( v27 && v3->_mhitpoints < v3->_mmaxhp >> 1 && (_LOBYTE(v24) = 117, random(v24, 2)) )
					M_StartSpAttack(arglist);
				else
					M_StartAttack(arglist);
			}
		}
		if ( v3->_mmode == MM_STAND )
			v3->_mAFNum = v3->MType->Anims[0].Frames[md + 1];
	}
}

//----- (00437520) --------------------------------------------------------
void __fastcall MAI_GoatMc(int i)
{
	MAI_Round(i, 1u);
}

//----- (00437528) --------------------------------------------------------
void __fastcall MAI_Ranged(int i, int missile_type, unsigned char special)
{
	int v3; // edi
	int v4; // esi
	char v5; // al
	int v6; // eax
	int v7; // ecx
	int v8; // ebx
	int v9; // edi
	int v10; // ecx
	bool v11; // zf
	int v12; // eax
	int v13; // eax
	int v14; // ST00_4
	int v15; // ecx
	int v16; // eax
	int x2; // [esp+8h] [ebp-14h]
	int y2; // [esp+Ch] [ebp-10h]
	int missile_typea; // [esp+10h] [ebp-Ch]
	int v20; // [esp+14h] [ebp-8h]
	int arglist; // [esp+18h] [ebp-4h]

	v3 = i;
	missile_typea = missile_type;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Ranged: Invalid monster %d", i);
	v4 = v3;
	if ( monster[v3]._mmode == MM_STAND )
	{
		v5 = monster[v4]._msquelch;
		if ( v5 == -1 || monster[v4]._mFlags & 0x10 )
		{
			v7 = (unsigned char)monster[v4]._menemyy;
			y2 = v7;
			v8 = monster[v4]._my - v7;
			x2 = (unsigned char)monster[v4]._menemyx;
			v9 = monster[v4]._mx - x2;
			v20 = M_GetDir(arglist);
			if ( _LOBYTE(monster[v4]._msquelch) < 0xFFu )
				MonstCheckDoors(arglist);
			v11 = monster[v4]._mVar1 == 10;
			monster[v4]._mdir = v20;
			if ( v11 )
			{
				_LOBYTE(v10) = 118;
				v12 = random(v10, 20);
				M_StartDelay(arglist, v12);
			}
			else if ( abs(v9) < 4 )
			{
				v13 = abs(v8);
				v15 = v14;
				if ( v13 < 4 )
				{
					_LOBYTE(v15) = 119;
					if ( random(v15, 100) < 10 * ((unsigned char)monster[v4]._mint + 7) )
						M_CallWalk(arglist, opposite[v20]);
				}
			}
			if ( monster[v4]._mmode == MM_STAND )
			{
				_LOBYTE(v16) = LineClear(monster[v4]._mx, monster[v4]._my, x2, y2);
				if ( v16 )
				{
					if ( special )
						M_StartRSpAttack(arglist, missile_typea, 4);
					else
						M_StartRAttack(arglist, missile_typea, 4);
				}
				else
				{
					monster[v4]._mAFNum = monster[v4].MType->Anims[0].Frames[v20 + 1];
				}
			}
		}
		else if ( v5 )
		{
			v6 = GetDirection(monster[v4]._mx, monster[v4]._my, monster[v4]._lastx, monster[v4]._lasty);
			M_CallWalk(v3, v6);
		}
	}
}

//----- (004376B3) --------------------------------------------------------
void __fastcall MAI_GoatBow(int i)
{
	MAI_Ranged(i, 0, 0);
}

//----- (004376BD) --------------------------------------------------------
void __fastcall MAI_Succ(int i)
{
	MAI_Ranged(i, 24, 0);
}

//----- (004376C8) --------------------------------------------------------
void __fastcall MAI_AcidUniq(int i)
{
	MAI_Ranged(i, 57, 1u);
}

//----- (004376D3) --------------------------------------------------------
void __fastcall MAI_Scav(int i)
{
	int v1; // edi
	int v2; // esi
	char *v3; // eax
	int v4; // ecx
	int v5; // ecx
	signed int v6; // ebx
	signed int v7; // edi
	int v8; // edx
	int v9; // eax
	int v10; // eax
	int v11; // ebx
	int v12; // edi
	signed int v13; // edi
	int v14; // edx
	int v15; // eax
	int v16; // eax
	int v17; // eax
	int v18; // eax
	int arglist; // [esp+Ch] [ebp-8h]
	BOOL v20; // [esp+10h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Scav: Invalid monster %d", i);
	v2 = v1;
	v20 = 0;
	if ( monster[v1]._mmode == MM_STAND )
	{
		if ( monster[v2]._mhitpoints < monster[v2]._mmaxhp >> 1 )
		{
			if ( _LOBYTE(monster[v2]._mgoal) == 3 )
				goto LABEL_10;
			if ( monster[v2].leaderflag )
			{
				v3 = &monster[(unsigned char)monster[v2].leader].unpackfilesize;
				--*v3;
				monster[v2].leaderflag = 0;
			}
			_LOBYTE(monster[v2]._mgoal) = 3;
			monster[v2]._mgoalvar3 = 10;
		}
		if ( _LOBYTE(monster[v2]._mgoal) != 3 )
		{
LABEL_52:
			if ( monster[v2]._mmode == MM_STAND )
				MAI_SkelSd(arglist);
			return;
		}
LABEL_10:
		v4 = monster[v2]._mgoalvar3;
		if ( v4 )
		{
			monster[v2]._mgoalvar3 = v4 - 1;
			v5 = monster[v2]._my;
			if ( dDead[monster[v2]._mx][v5] )
			{
				M_StartEat(v1);
				if ( !(monster[v2]._mFlags & 8) )
					monster[v2]._mhitpoints += 64;
				if ( monster[v2]._mhitpoints >= (monster[v2]._mmaxhp >> 1) + (monster[v2]._mmaxhp >> 2) )
				{
					_LOBYTE(monster[v2]._mgoal) = 1;
					monster[v2]._mgoalvar1 = 0;
					monster[v2]._mgoalvar2 = 0;
				}
			}
			else
			{
				if ( !monster[v2]._mgoalvar1 )
				{
					_LOBYTE(v5) = 120;
					v6 = arglist;
					if ( random(v5, 2) )
					{
						v7 = -4;
						do
						{
							if ( v20 )
								break;
							v6 = -4;
							do
							{
								if ( v20 )
									break;
								if ( v7 >= 0 && v7 < 112 && v6 >= 0 && v6 < 112 )
								{
									v8 = monster[v2]._mx;
									v9 = monster[v2]._my;
									v20 = dDead[v8 + v6][v9 + v7]
									   && (_LOBYTE(v10) = LineClearF(
															 (unsigned char (__cdecl *)())CheckNoSolid,
															 v8,
															 v9,
															 v8 + v6,
															 v9 + v7),
										   v10);
								}
								++v6;
							}
							while ( v6 <= 4 );
							++v7;
						}
						while ( v7 <= 4 );
						v11 = v6 - 1;
						v12 = v7 - 1;
					}
					else
					{
						v13 = 4;
						do
						{
							if ( v20 )
								break;
							v6 = 4;
							do
							{
								if ( v20 )
									break;
								if ( v13 >= 0 && v13 < 112 && v6 >= 0 && v6 < 112 )
								{
									v14 = monster[v2]._mx;
									v15 = monster[v2]._my;
									v20 = dDead[v14 + v6][v15 + v13]
									   && (_LOBYTE(v16) = LineClearF(
															 (unsigned char (__cdecl *)())CheckNoSolid,
															 v14,
															 v15,
															 v14 + v6,
															 v15 + v13),
										   v16);
								}
								--v6;
							}
							while ( v6 >= -4 );
							--v13;
						}
						while ( v13 >= -4 );
						v11 = v6 + 1;
						v12 = v13 + 1;
					}
					if ( v20 )
					{
						monster[v2]._mgoalvar1 = monster[v2]._mx + v11 + 1;
						monster[v2]._mgoalvar2 = monster[v2]._my + v12 + 1;
					}
				}
				v17 = monster[v2]._mgoalvar1;
				if ( v17 )
				{
					v18 = GetDirection(monster[v2]._mx, monster[v2]._my, v17 - 1, monster[v2]._mgoalvar2 - 1);
					monster[v2]._mdir = v18;
					M_CallWalk(arglist, v18);
				}
			}
		}
		goto LABEL_52;
	}
}

//----- (00437957) --------------------------------------------------------
void __fastcall MAI_Garg(int i)
{
	int v1; // ebp
	MonsterStruct *v2; // esi
	int v3; // edi
	int v4; // ebx
	char v5; // al
	int v6; // edi
	int v7; // eax
	int v8; // [esp+10h] [ebp-4h]

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Garg: Invalid monster %d", i);
	v2 = &monster[v1];
	v3 = v2->_mx - v2->_lastx;
	v4 = v2->_my - v2->_lasty;
	v8 = M_GetDir(v1);
	v5 = v2->_msquelch;
	if ( v5 && v2->_mFlags & 4 )
	{
		M_Enemy(v1);
		v6 = v2->_my - (unsigned char)v2->_menemyy;
		if ( abs(v2->_mx - (unsigned char)v2->_menemyx) < (unsigned char)v2->_mint + 2
		  && abs(v6) < (unsigned char)v2->_mint + 2 )
		{
			v2->_mFlags &= 0xFFFFFFFB;
		}
	}
	else if ( v2->_mmode == MM_STAND && v5 )
	{
		if ( v2->_mhitpoints < v2->_mmaxhp >> 1 && !(v2->_mFlags & 8) )
			_LOBYTE(v2->_mgoal) = 2;
		if ( _LOBYTE(v2->_mgoal) == 2 )
		{
			if ( abs(v3) >= (unsigned char)v2->_mint + 2 || abs(v4) >= (unsigned char)v2->_mint + 2 )
			{
				_LOBYTE(v2->_mgoal) = 1;
				M_StartHeal(v1);
			}
			else
			{
				_LOBYTE(v7) = M_CallWalk(v1, opposite[v8]);
				if ( !v7 )
					_LOBYTE(v2->_mgoal) = 1;
			}
		}
		MAI_Round(v1, 0);
	}
}

//----- (00437A8B) --------------------------------------------------------
void __fastcall MAI_RoundRanged(int i, int missile_type, unsigned char checkdoors, int dam, int lessmissiles)
{
	int v5; // esi
	MonsterStruct *v6; // esi
	int v7; // edx
	int v8; // ebx
	int v9; // edi
	int v10; // ecx
	int v11; // eax
	int v12; // ST04_4
	int v13; // ecx
	int v14; // eax
	int v15; // ST04_4
	int v16; // eax
	int v17; // ST04_4
	int v18; // ecx
	int v19; // ebx
	int v20; // eax
	int v21; // ecx
	int v22; // eax
	int v23; // eax
	int v24; // eax
	int v25; // eax
	int v26; // ST04_4
	int v27; // eax
	int v28; // ST04_4
	int v29; // eax
	int v30; // edx
	int v31; // eax
	int missile_typea; // [esp+4h] [ebp-18h]
	int v33; // [esp+8h] [ebp-14h]
	int x2; // [esp+Ch] [ebp-10h]
	int md; // [esp+10h] [ebp-Ch]
	int y2; // [esp+14h] [ebp-8h]
	int arglist; // [esp+18h] [ebp-4h]
	int checkdoorsa; // [esp+24h] [ebp+8h]

	v5 = i;
	missile_typea = missile_type;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_RoundRanged: Invalid monster %d", i);
	v6 = &monster[v5];
	if ( v6->_mmode == MM_STAND && _LOBYTE(v6->_msquelch) )
	{
		v7 = v6->_my;
		y2 = (unsigned char)v6->_menemyy;
		v8 = v7 - y2;
		x2 = (unsigned char)v6->_menemyx;
		v9 = v6->_mx - x2;
		v33 = v7 - y2;
		md = GetDirection(v6->_mx, v7, v6->_lastx, v6->_lasty);
		if ( checkdoors && _LOBYTE(v6->_msquelch) < 0xFFu )
			MonstCheckDoors(arglist);
		_LOBYTE(v10) = 121;
		checkdoorsa = random(v10, 10000);
		v11 = abs(v9);
		v13 = v12;
		if ( v11 < 2 )
		{
			v14 = abs(v8);
			v13 = v15;
			if ( v14 < 2 )
				goto LABEL_50;
		}
		if ( _LOBYTE(v6->_msquelch) != -1 )
			goto LABEL_50;
		v13 = y2;
		if ( dung_map[v6->_mx][v6->_my] != dung_map[x2][y2] )
			goto LABEL_50;
		if ( _LOBYTE(v6->_mgoal) != 4 )
		{
			if ( abs(v9) < 3 )
			{
				v16 = abs(v8);
				v13 = v17;
				if ( v16 < 3 )
					goto LABEL_28;
			}
			v18 = lessmissiles;
			_LOBYTE(v18) = 122;
			if ( random(v18, 4 << lessmissiles) )
				goto LABEL_28;
			if ( _LOBYTE(v6->_mgoal) != 4 )
			{
				v6->_mgoalvar1 = 0;
				_LOBYTE(v13) = 123;
				v6->_mgoalvar2 = random(v13, 2);
			}
		}
		_LOBYTE(v6->_mgoal) = 4;
		v19 = abs(v8);
		if ( abs(v9) <= v19 )
		{
			v8 = v33;
			v20 = abs(v33);
		}
		else
		{
			v20 = abs(v9);
			v8 = v33;
		}
		v21 = v6->_mgoalvar1;
		v6->_mgoalvar1 = v21 + 1;
		if ( v21 >= 2 * v20 && (_LOBYTE(v22) = DirOK(arglist, md), v22) )
		{
LABEL_50:
			_LOBYTE(v6->_mgoal) = 1;
		}
		else if ( checkdoorsa < 500 * ((unsigned char)v6->_mint + 1) >> lessmissiles
			   && (_LOBYTE(v23) = LineClear(v6->_mx, v6->_my, x2, y2), v23) )
		{
			M_StartRSpAttack(arglist, missile_typea, dam);
		}
		else
		{
			M_RoundWalk(arglist, md, &v6->_mgoalvar2);
		}
LABEL_28:
		if ( _LOBYTE(v6->_mgoal) == 1 )
		{
			if ( ((abs(v9) >= 3 || abs(v8) >= 3) && checkdoorsa < 500 * ((unsigned char)v6->_mint + 2) >> lessmissiles
			   || checkdoorsa < 500 * ((unsigned char)v6->_mint + 1) >> lessmissiles)
			  && (_LOBYTE(v24) = LineClear(v6->_mx, v6->_my, x2, y2), v24) )
			{
				M_StartRSpAttack(arglist, missile_typea, dam);
			}
			else
			{
				v25 = abs(v9);
				v13 = v26;
				if ( v25 >= 2 || (v27 = abs(v8), v13 = v28, v27 >= 2) )
				{
					_LOBYTE(v13) = 124;
					v29 = random(v13, 100);
					v30 = (unsigned char)v6->_mint;
					if ( v29 < 1000 * (v30 + 5)
					  || ((v13 = v6->_mVar1, v13 == 1) || v13 == 2 || v13 == 3) && !v6->_mVar2 && v29 < 1000 * (v30 + 8) )
					{
						M_CallWalk(arglist, md);
					}
				}
				else if ( checkdoorsa < 1000 * ((unsigned char)v6->_mint + 6) )
				{
					v6->_mdir = md;
					M_StartAttack(arglist);
				}
			}
		}
		if ( v6->_mmode == MM_STAND )
		{
			_LOBYTE(v13) = 125;
			v31 = random(v13, 10);
			M_StartDelay(arglist, v31 + 5);
		}
	}
}

//----- (00437D93) --------------------------------------------------------
void __fastcall MAI_Magma(int i)
{
	MAI_RoundRanged(i, 21, 1u, 4, 0);
}

//----- (00437DA2) --------------------------------------------------------
void __fastcall MAI_Storm(int i)
{
	MAI_RoundRanged(i, 22, 1u, 4, 0);
}

//----- (00437DB1) --------------------------------------------------------
void __fastcall MAI_Acid(int i)
{
	MAI_RoundRanged(i, 57, 0, 4, 1);
}

//----- (00437DC0) --------------------------------------------------------
void __fastcall MAI_Diablo(int i)
{
	MAI_RoundRanged(i, 67, 0, 40, 0);
}

//----- (00437DCF) --------------------------------------------------------
void __fastcall MAI_RR2(int i, int mistype, int dam)
{
	int v3; // ebx
	MonsterStruct *v4; // esi
	int v5; // edi
	int v6; // edx
	int v7; // ebx
	int v8; // edi
	int v9; // ecx
	int v10; // eax
	int v11; // ST04_4
	int v12; // ecx
	int v13; // eax
	int v14; // ST04_4
	int v15; // eax
	int v16; // ST04_4
	int v17; // eax
	int v18; // ST04_4
	int v19; // ebx
	int v20; // eax
	int v21; // eax
	int v22; // eax
	int v23; // ecx
	int v24; // eax
	int v25; // ST04_4
	int v26; // ecx
	int v27; // eax
	int v28; // ST04_4
	int v29; // eax
	int v30; // eax
	int v31; // eax
	int v32; // edx
	int v33; // eax
	int missile_type; // [esp+Ch] [ebp-1Ch]
	int x2; // [esp+10h] [ebp-18h]
	int v36; // [esp+14h] [ebp-14h]
	int y2; // [esp+18h] [ebp-10h]
	int v38; // [esp+1Ch] [ebp-Ch]
	int md; // [esp+20h] [ebp-8h]
	int arglist; // [esp+24h] [ebp-4h]

	v3 = i;
	missile_type = mistype;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_RR2: Invalid monster %d", i);
	v4 = &monster[v3];
	v5 = v4->_my - (unsigned char)v4->_menemyy;
	if ( abs(v4->_mx - (unsigned char)v4->_menemyx) >= 5 || abs(v5) >= 5 )
	{
		MAI_SkelSd(v3);
		return;
	}
	if ( v4->_mmode == MM_STAND && _LOBYTE(v4->_msquelch) )
	{
		v6 = v4->_my;
		y2 = (unsigned char)v4->_menemyy;
		v7 = v6 - y2;
		x2 = (unsigned char)v4->_menemyx;
		v8 = v4->_mx - x2;
		v36 = v6 - y2;
		md = GetDirection(v4->_mx, v6, v4->_lastx, v4->_lasty);
		if ( _LOBYTE(v4->_msquelch) < 0xFFu )
			MonstCheckDoors(arglist);
		_LOBYTE(v9) = 121;
		v38 = random(v9, 100);
		v10 = abs(v8);
		v12 = v11;
		if ( v10 >= 2 || (v13 = abs(v7), v12 = v14, v13 >= 2) )
		{
			if ( _LOBYTE(v4->_msquelch) == -1 )
			{
				v12 = y2;
				if ( dung_map[v4->_mx][v4->_my] == dung_map[x2][y2] )
				{
					if ( _LOBYTE(v4->_mgoal) != 4 )
					{
						v15 = abs(v8);
						v12 = v16;
						if ( v15 < 3 )
						{
							v17 = abs(v7);
							v12 = v18;
							if ( v17 < 3 )
								goto LABEL_26;
						}
						if ( _LOBYTE(v4->_mgoal) != 4 )
						{
							v4->_mgoalvar1 = 0;
							_LOBYTE(v12) = 123;
							v4->_mgoalvar2 = random(v12, 2);
						}
					}
					_LOBYTE(v4->_mgoal) = 4;
					v4->_mgoalvar3 = 4;
					v19 = abs(v7);
					if ( abs(v8) <= v19 )
					{
						v7 = v36;
						v20 = abs(v36);
					}
					else
					{
						v20 = abs(v8);
						v7 = v36;
					}
					v12 = v4->_mgoalvar1;
					v4->_mgoalvar1 = v12 + 1;
					if ( v12 < 2 * v20 || (_LOBYTE(v21) = DirOK(arglist, md), !v21) )
					{
						if ( v38 < 5 * ((unsigned char)v4->_mint + 16) )
							M_RoundWalk(arglist, md, &v4->_mgoalvar2);
LABEL_26:
						if ( _LOBYTE(v4->_mgoal) != 1 )
							goto LABEL_48;
						if ( ((abs(v8) >= 3 || abs(v7) >= 3) && v38 < 5 * ((unsigned char)v4->_mint + 2)
						   || v38 < 5 * ((unsigned char)v4->_mint + 1)
						   || v4->_mgoalvar3 == 4)
						  && (_LOBYTE(v22) = LineClear(v4->_mx, v4->_my, x2, y2), v22) )
						{
							v23 = arglist;
						}
						else
						{
							v24 = abs(v8);
							v26 = v25;
							if ( v24 >= 2 || (v27 = abs(v7), v26 = v28, v27 >= 2) )
							{
								_LOBYTE(v26) = 124;
								v31 = random(v26, 100);
								v12 = (unsigned char)v4->_mint;
								if ( v31 < 2 * (5 * v12 + 25)
								  || ((v32 = v4->_mVar1, v32 == 1) || v32 == 2 || v32 == 3)
								  && !v4->_mVar2
								  && (v12 = 2 * (5 * v12 + 40), v31 < v12) )
								{
									M_CallWalk(arglist, md);
								}
								goto LABEL_47;
							}
							_LOBYTE(v26) = 124;
							v29 = random(v26, 100);
							v12 = 10 * ((unsigned char)v4->_mint + 4);
							if ( v29 >= v12 )
							{
LABEL_47:
								v4->_mgoalvar3 = 1;
LABEL_48:
								if ( v4->_mmode == MM_STAND )
								{
									_LOBYTE(v12) = 125;
									v33 = random(v12, 10);
									M_StartDelay(arglist, v33 + 5);
								}
								return;
							}
							_LOBYTE(v12) = 124;
							v4->_mdir = md;
							v30 = random(v12, 2);
							v23 = arglist;
							if ( v30 )
							{
								M_StartAttack(arglist);
								goto LABEL_47;
							}
						}
						M_StartRSpAttack(v23, missile_type, dam);
						goto LABEL_47;
					}
				}
			}
		}
		_LOBYTE(v4->_mgoal) = 1;
		goto LABEL_26;
	}
}

//----- (004380DE) --------------------------------------------------------
void __fastcall MAI_Mega(int i)
{
	MAI_RR2(i, 49, 0);
}

//----- (004380E9) --------------------------------------------------------
void __fastcall MAI_Golum(int i)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // eax
	int v5; // edx
	int v6; // edi
	int v7; // ebx
	int v8; // eax
	char v9; // cl
	int *v10; // eax
	signed int v11; // edx
	signed int v12; // ecx
	int v13; // eax
	int v14; // eax
	int *v15; // esi
	int v16; // eax
	int v17; // esi
	int v18; // edi
	int v19; // [esp+Ch] [ebp-Ch]
	unsigned int v20; // [esp+10h] [ebp-8h]
	int arglist; // [esp+14h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Golum: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mx != 1 || monster[v2]._my )
	{
		v3 = monster[v2]._mmode;
		if ( v3 != MM_DEATH && v3 != MM_SPSTAND && (v3 < MM_WALK || v3 > MM_WALK3) )
		{
			if ( !(monster[v2]._mFlags & 0x10) )
				M_Enemy(v1);
			v20 = ((unsigned int)~monster[v2]._mFlags >> 10) & 1;
			if ( monster[v2]._mmode != MM_ATTACK )
			{
				v4 = monster[v2]._menemy;
				v5 = monster[v2]._my;
				v6 = monster[v2]._mx - monster[v4]._mfutx;
				v7 = v5 - monster[v4]._mfuty;
				v19 = GetDirection(monster[v2]._mx, v5, monster[v4]._mx, monster[v4]._my);
				monster[v2]._mdir = v19;
				if ( abs(v6) >= 2 || abs(v7) >= 2 )
				{
					if ( v20 )
					{
						MAI_Path(arglist);
						if ( v14 )
							return;
					}
				}
				else if ( v20 )
				{
					v8 = monster[v2]._menemy;
					monster[v2]._menemyx = monster[v8]._mx;
					v9 = monster[v8]._my;
					v10 = &monster[v8]._msquelch;
					monster[v2]._menemyy = v9;
					if ( !*(_BYTE *)v10 )
					{
						*(_BYTE *)v10 = -1;
						monster[monster[v2]._menemy]._lastx = monster[v2]._mx;
						v11 = 0;
						monster[monster[v2]._menemy]._lasty = monster[v2]._my;
						do
						{
							v12 = 0;
							do
							{
								v13 = *(_DWORD *)&nTransTable[4
															* (monster[v2]._my + v11 + 112 * (v12 + monster[v2]._mx))
															+ 1148];
								if ( v13 > 0 )
									_LOBYTE(monster[v13]._msquelch) = -1;
								++v12;
							}
							while ( v12 < 5 );
							++v11;
						}
						while ( v11 < 5 );
					}
					M_StartAttack(arglist);
					return;
				}
				v15 = &monster[v2]._pathcount;
				if ( ++*(_BYTE *)v15 > 8u )
					*(_BYTE *)v15 = 5;
				_LOBYTE(v16) = M_CallWalk(arglist, plr[arglist]._pdir);
				if ( !v16 )
				{
					v17 = ((_BYTE)v19 - 1) & 7;
					v18 = 0;
					while ( !v16 )
					{
						v17 = ((_BYTE)v17 + 1) & 7;
						_LOBYTE(v16) = DirOK(arglist, v17);
						if ( ++v18 >= 8 )
						{
							if ( !v16 )
								return;
							break;
						}
					}
					M_WalkDir(arglist, v17);
				}
			}
		}
	}
}

//----- (00438304) --------------------------------------------------------
void __fastcall MAI_SkelKing(int i)
{
	int v1; // esi
	MonsterStruct *v2; // esi
	int v3; // edx
	int v4; // ebx
	int v5; // edi
	int v6; // ecx
	int v7; // eax
	int v8; // ST04_4
	int v9; // ecx
	int v10; // eax
	int v11; // ST04_4
	int v12; // ecx
	int v13; // ebx
	int v14; // eax
	int v15; // ecx
	int v16; // eax
	int v17; // eax
	int v18; // ecx
	int v19; // eax
	int v20; // eax
	int v21; // edi
	int v22; // ebx
	int v23; // eax
	int v24; // ST04_4
	int v25; // ecx
	int v26; // eax
	int v27; // ST04_4
	int v28; // eax
	int v29; // ecx
	int v30; // edx
	int v31; // eax
	char *v32; // [esp+4h] [ebp-1Ch]
	int x2; // [esp+8h] [ebp-18h]
	int v34; // [esp+Ch] [ebp-14h]
	int v35; // [esp+10h] [ebp-10h]
	int y2; // [esp+14h] [ebp-Ch]
	int md; // [esp+18h] [ebp-8h]
	int arglist; // [esp+1Ch] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_SkelKing: Invalid monster %d", i);
	v2 = &monster[v1];
	if ( v2->_mmode == MM_STAND && _LOBYTE(v2->_msquelch) )
	{
		v3 = v2->_my;
		y2 = (unsigned char)v2->_menemyy;
		v4 = v3 - y2;
		x2 = (unsigned char)v2->_menemyx;
		v5 = v2->_mx - x2;
		v34 = v3 - y2;
		md = GetDirection(v2->_mx, v3, v2->_lastx, v2->_lasty);
		if ( _LOBYTE(v2->_msquelch) < 0xFFu )
			MonstCheckDoors(arglist);
		_LOBYTE(v6) = 126;
		v35 = random(v6, 100);
		if ( (abs(v5) >= 2 || abs(v4) >= 2) && _LOBYTE(v2->_msquelch) == -1 )
		{
			v32 = &dung_map[x2][y2];
			if ( dung_map[v2->_mx][v2->_my] == *v32 )
			{
				if ( _LOBYTE(v2->_mgoal) != 4 )
				{
					v7 = abs(v5);
					v9 = v8;
					if ( v7 < 3 )
					{
						v10 = abs(v4);
						v9 = v11;
						if ( v10 < 3 )
							goto LABEL_26;
					}
					_LOBYTE(v9) = 127;
					if ( random(v9, 4) )
						goto LABEL_26;
					if ( _LOBYTE(v2->_mgoal) != 4 )
					{
						v2->_mgoalvar1 = 0;
						_LOBYTE(v12) = -128;
						v2->_mgoalvar2 = random(v12, 2);
					}
				}
				_LOBYTE(v2->_mgoal) = 4;
				v13 = abs(v4);
				if ( abs(v5) <= v13 )
				{
					v4 = v34;
					v14 = abs(v34);
				}
				else
				{
					v14 = abs(v5);
					v4 = v34;
				}
				v15 = v2->_mgoalvar1;
				v2->_mgoalvar1 = v15 + 1;
				if ( v15 < 2 * v14 || (_LOBYTE(v16) = DirOK(arglist, md), !v16) )
				{
					if ( dung_map[v2->_mx][v2->_my] == *v32 )
					{
						_LOBYTE(v17) = M_RoundWalk(arglist, md, &v2->_mgoalvar2);
						if ( !v17 )
						{
							_LOBYTE(v18) = 125;
							v19 = random(v18, 10);
							M_StartDelay(arglist, v19 + 10);
						}
						goto LABEL_26;
					}
				}
			}
		}
		_LOBYTE(v2->_mgoal) = 1;
LABEL_26:
		if ( _LOBYTE(v2->_mgoal) == 1 )
		{
			if ( gbMaxPlayers == 1
			  && ((abs(v5) >= 3 || abs(v4) >= 3) && v35 < 4 * (unsigned char)v2->_mint + 35 || v35 < 6)
			  && (_LOBYTE(v20) = LineClear(v2->_mx, v2->_my, x2, y2), v20) )
			{
				v21 = v2->_mx + offset_x[md];
				v22 = v2->_my + offset_y[md];
				if ( PosOkMonst(arglist, v21, v22) && nummonsters < 200 )
				{
					M_SpawnSkel(v21, v22, md);
					M_StartSpStand(arglist, md);
				}
			}
			else
			{
				v23 = abs(v5);
				v25 = v24;
				if ( v23 >= 2 || (v26 = abs(v4), v25 = v27, v26 >= 2) )
				{
					_LOBYTE(v25) = -127;
					v28 = random(v25, 100);
					v29 = (unsigned char)v2->_mint;
					if ( v28 >= v29 + 25
					  && ((v30 = v2->_mVar1, v30 != 1) && v30 != 2 && v30 != 3 || v2->_mVar2 || (v29 += 75, v28 >= v29)) )
					{
						_LOBYTE(v29) = -126;
						v31 = random(v29, 10);
						M_StartDelay(arglist, v31 + 10);
					}
					else
					{
						M_CallWalk(arglist, md);
					}
				}
				else if ( v35 < (unsigned char)v2->_mint + 20 )
				{
					v2->_mdir = md;
					M_StartAttack(arglist);
				}
			}
		}
		if ( v2->_mmode == MM_STAND )
			v2->_mAFNum = v2->MType->Anims[0].Frames[md + 1];
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0043862D) --------------------------------------------------------
void __fastcall MAI_Rhino(int i)
{
	int esi1; // esi
	MonsterStruct *esi3; // esi
	int v3; // edx
	int v4; // ebx
	int v5; // edi
	int v6; // ecx
	int v7; // eax
	int v8; // ST1C_4
	int v9; // ecx
	int v10; // eax
	int v11; // ST1C_4
	int v12; // ecx
	int v13; // ebx
	int v14; // eax
	int v15; // ecx
	int v16; // eax
	int v17; // ecx
	int v18; // eax
	int v19; // eax
	int v20; // ecx
	int v21; // eax
	int v22; // ST1C_4
	int v23; // ecx
	int v24; // eax
	int v25; // ST1C_4
	int v26; // eax
	int v27; // ecx
	int v28; // edx
	int v29; // eax
	int v30; // [esp+4h] [ebp-18h]
	int v31; // [esp+8h] [ebp-14h]
	int v1; // [esp+Ch] [ebp-10h]
	int midir; // [esp+10h] [ebp-Ch]
	int v2; // [esp+14h] [ebp-8h]
	int arglist; // [esp+18h] [ebp-4h]

	esi1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Rhino: Invalid monster %d", i);
	esi3 = &monster[esi1];
	if ( esi3->_mmode == MM_STAND && _LOBYTE(esi3->_msquelch) )
	{
		v3 = esi3->_my;
		v2 = (unsigned char)esi3->_menemyy;
		v4 = v3 - v2;
		v1 = (unsigned char)esi3->_menemyx;
		v5 = esi3->_mx - v1;
		v31 = v3 - v2;
		midir = GetDirection(esi3->_mx, v3, esi3->_lastx, esi3->_lasty);
		if ( _LOBYTE(esi3->_msquelch) < 0xFFu )
			MonstCheckDoors(arglist);
		_LOBYTE(v6) = -125;
		v30 = random(v6, 100);
		if ( abs(v5) >= 2 || abs(v4) >= 2 )
		{
			if ( _LOBYTE(esi3->_mgoal) != 4 )
			{
				v7 = abs(v5);
				v9 = v8;
				if ( v7 < 5 )
				{
					v10 = abs(v4);
					v9 = v11;
					if ( v10 < 5 )
						goto LABEL_23;
				}
				_LOBYTE(v9) = -124;
				if ( !random(v9, 4) )
					goto LABEL_23;
				if ( _LOBYTE(esi3->_mgoal) != 4 )
				{
					esi3->_mgoalvar1 = 0;
					_LOBYTE(v12) = -123;
					esi3->_mgoalvar2 = random(v12, 2);
				}
			}
			_LOBYTE(esi3->_mgoal) = 4;
			v13 = abs(v4);
			if ( abs(v5) <= v13 )
			{
				v4 = v31;
				v14 = abs(v31);
			}
			else
			{
				v14 = abs(v5);
				v4 = v31;
			}
			v15 = esi3->_mgoalvar1;
			esi3->_mgoalvar1 = v15 + 1;
			if ( v15 < 2 * v14 && dung_map[esi3->_mx][esi3->_my] == dung_map[v1][v2] )
			{
				_LOBYTE(v16) = M_RoundWalk(arglist, midir, &esi3->_mgoalvar2);
				if ( !v16 )
				{
					_LOBYTE(v17) = 125;
					v18 = random(v17, 10);
					M_StartDelay(arglist, v18 + 10);
				}
				goto LABEL_23;
			}
		}
		_LOBYTE(esi3->_mgoal) = 1;
LABEL_23:
		if ( _LOBYTE(esi3->_mgoal) == 1 )
		{
			if ( (abs(v5) >= 5 || abs(v4) >= 5)
			  && v30 < 2 * (unsigned char)esi3->_mint + 43
			  && (_LOBYTE(v19) = LineClearF1(
									(unsigned char (__cdecl *)())PosOkMonst,
									arglist,
									esi3->_mx,
									esi3->_my,
									v1,
									v2),
				  v19) )
			{
				_LOBYTE(v19) = esi3->_menemy;
				if ( AddMissile(esi3->_mx, esi3->_my, v1, v2, midir, 20, v19, arglist, 0, 0) != -1 )
				{
					if ( esi3->MData->snd_special )
						PlayEffect(arglist, 3);
					v20 = esi3->_my + 112 * esi3->_mx;
					esi3->_mmode = 14;
					dMonster[0][v20] = -1 - arglist;
				}
			}
			else
			{
				v21 = abs(v5);
				v23 = v22;
				if ( v21 >= 2 || (v24 = abs(v4), v23 = v25, v24 >= 2) )
				{
					_LOBYTE(v23) = -122;
					v26 = random(v23, 100);
					v27 = 2 * (unsigned char)esi3->_mint;
					if ( v26 >= v27 + 33
					  && ((v28 = esi3->_mVar1, v28 != 1) && v28 != 2 && v28 != 3
					   || esi3->_mVar2
					   || (v27 += 83, v26 >= v27)) )
					{
						_LOBYTE(v27) = -121;
						v29 = random(v27, 10);
						M_StartDelay(arglist, v29 + 10);
					}
					else
					{
						M_CallWalk(arglist, midir);
					}
				}
				else if ( v30 < 2 * (unsigned char)esi3->_mint + 28 )
				{
					esi3->_mdir = midir;
					M_StartAttack(arglist);
				}
			}
		}
		if ( esi3->_mmode == MM_STAND )
			esi3->_mAFNum = esi3->MType->Anims[0].Frames[esi3->_mdir + 1];
	}
}

//----- (0043891F) --------------------------------------------------------
void __fastcall MAI_Counselor(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // ecx
	int v4; // edi
	int v5; // edx
	int v6; // ebp
	int v7; // ecx
	int v8; // ecx
	char v9; // al
	int v10; // ecx
	bool v11; // zf
	bool v12; // sf
	unsigned char v13; // of
	int v14; // edx
	int v15; // ecx
	int v16; // ebx
	int v17; // eax
	int v18; // ebx
	int v19; // edx
	int v20; // ecx
	int v21; // eax
	int v22; // eax
	int v23; // ST1C_4
	int v24; // ecx
	int v25; // eax
	int v26; // ST1C_4
	int v27; // edx
	int v28; // eax
	int v29; // eax
	int v30; // ecx
	int v31; // eax
	int v32; // eax
	int v33; // eax
	int v34; // eax
	int md; // [esp+8h] [ebp-14h]
	int arglist; // [esp+Ch] [ebp-10h]
	int y2; // [esp+10h] [ebp-Ch]
	int x2; // [esp+14h] [ebp-8h]
	int v39; // [esp+18h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Counselor: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mmode == MM_STAND && _LOBYTE(monster[v2]._msquelch) )
	{
		v3 = monster[v2]._mx;
		x2 = (unsigned char)monster[v2]._menemyx;
		v4 = v3 - x2;
		v5 = monster[v2]._my;
		y2 = (unsigned char)monster[v2]._menemyy;
		v6 = v5 - y2;
		md = GetDirection(v3, v5, monster[v2]._lastx, monster[v2]._lasty);
		if ( _LOBYTE(monster[v2]._msquelch) < 0xFFu )
			MonstCheckDoors(v1);
		_LOBYTE(v7) = 121;
		v39 = random(v7, 100);
		v9 = monster[v2]._mgoal;
		if ( v9 == 2 )
		{
			v10 = monster[v2]._mgoalvar1;
			v13 = __OFSUB__(v10, 3);
			v11 = v10 == 3;
			v12 = v10 - 3 < 0;
			v14 = v10 + 1;
			v15 = v1;
			monster[v2]._mgoalvar1 = v14;
			if ( (unsigned char)(v12 ^ v13) | v11 )
			{
				M_CallWalk(v1, opposite[md]);
				goto LABEL_39;
			}
			goto LABEL_21;
		}
		if ( v9 == 4 )
		{
			v16 = abs(v6);
			if ( abs(v4) <= v16 )
				v17 = abs(v6);
			else
				v17 = abs(v4);
			v18 = v17;
			if ( abs(v4) < 2 && abs(v6) < 2
			  || _LOBYTE(monster[v2]._msquelch) != -1
			  || dung_map[monster[v2]._mx][monster[v2]._my] != dung_map[x2][y2] )
			{
				v1 = arglist;
LABEL_20:
				v15 = v1;
LABEL_21:
				_LOBYTE(monster[v2]._mgoal) = 1;
				M_StartFadein(v15, md, 1u);
				goto LABEL_39;
			}
			v19 = 2 * v18;
			v1 = arglist;
			v20 = monster[v2]._mgoalvar1;
			monster[v2]._mgoalvar1 = v20 + 1;
			if ( v20 >= v19 )
			{
				_LOBYTE(v21) = DirOK(arglist, md);
				if ( v21 )
					goto LABEL_20;
			}
			M_RoundWalk(arglist, md, &monster[v2]._mgoalvar2);
LABEL_39:
			if ( monster[v2]._mmode == MM_STAND )
			{
				_LOBYTE(v8) = 125;
				v34 = random(v8, 10);
				M_StartDelay(v1, v34 + 5);
			}
			return;
		}
		if ( v9 != 1 )
			goto LABEL_39;
		v22 = abs(v4);
		v24 = v23;
		if ( v22 >= 2 || (v25 = abs(v6), v24 = v26, v25 >= 2) )
		{
			if ( v39 < 5 * ((unsigned char)monster[v2]._mint + 10) )
			{
				_LOBYTE(v31) = LineClear(monster[v2]._mx, monster[v2]._my, x2, y2);
				if ( v31 )
				{
					_LOBYTE(v24) = 77;
					v32 = random(
							  v24,
							  (unsigned char)monster[v2].mMaxDamage - (unsigned char)monster[v2].mMinDamage + 1);
					M_StartRAttack(
						v1,
						(unsigned char)counsmiss[(unsigned char)monster[v2]._mint],
						(unsigned char)monster[v2].mMinDamage + v32);
					goto LABEL_39;
				}
			}
			_LOBYTE(v24) = 124;
			if ( random(v24, 100) < 30 )
			{
				v27 = md;
				_LOBYTE(monster[v2]._mgoal) = 4;
				goto LABEL_29;
			}
		}
		else
		{
			v27 = md;
			v28 = monster[v2]._mmaxhp >> 1;
			v13 = __OFSUB__(monster[v2]._mhitpoints, v28);
			v12 = monster[v2]._mhitpoints - v28 < 0;
			monster[v2]._mdir = md;
			if ( v12 ^ v13 )
			{
				_LOBYTE(monster[v2]._mgoal) = 2;
LABEL_29:
				monster[v2]._mgoalvar1 = 0;
				M_StartFadeout(v1, v27, 0);
				goto LABEL_39;
			}
			if ( monster[v2]._mVar1 == 13
			  || (_LOBYTE(v24) = 105, v29 = random(v24, 100),
									 v30 = 2 * (unsigned char)monster[v2]._mint + 20,
									 v29 < v30) )
			{
				M_StartRAttack(v1, -1, 0);
				AddMissile(monster[v2]._mx, monster[v2]._my, 0, 0, monster[v2]._mdir, 11, 1, v1, 4, 0);
				AddMissile(monster[v2]._mx, monster[v2]._my, 0, 0, monster[v2]._mdir, 12, 1, v1, 4, 0);
				goto LABEL_39;
			}
		}
		_LOBYTE(v30) = 105;
		v33 = random(v30, 10);
		M_StartDelay(v1, v33 + 2 * (5 - (unsigned char)monster[v2]._mint));
		goto LABEL_39;
	}
}

//----- (00438C79) --------------------------------------------------------
void __fastcall MAI_Garbud(int i)
{
	int v1; // esi
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // eax
	int v6; // eax
	char v7; // al
	int v8; // [esp+4h] [ebp-8h]
	int arglist; // [esp+8h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Garbud: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v2]._mmode == MM_STAND )
	{
		v3 = monster[v2]._my;
		v4 = monster[v2]._mx;
		v8 = M_GetDir(arglist);
		v5 = monster[v2].mtalkmsg;
		if ( v5 < (signed int)TEXT_GARBUD4
		  && v5 > (signed int)TEXT_PEGBOY20
		  && !(dFlags[v4][v3] & 2)
		  && _LOBYTE(monster[v2]._mgoal) == 7 )
		{
			_LOBYTE(monster[v2]._mgoal) = 6;
			monster[v2].mtalkmsg = v5 + 1;
		}
		if ( dFlags[v4][v3] & 2 )
		{
			if ( monster[v2].mtalkmsg == TEXT_GARBUD4 )
			{
				_LOBYTE(v6) = effect_is_playing(USFX_GARBUD4);
				if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 )
				{
					_LOBYTE(monster[v2]._msquelch) = -1;
					monster[v2].mtalkmsg = 0;
					_LOBYTE(monster[v2]._mgoal) = 1;
				}
			}
		}
		v7 = monster[v2]._mgoal;
		if ( v7 == 1 || v7 == 4 )
			MAI_Round(arglist, 1u);
		monster[v2]._mdir = v8;
		if ( monster[v2]._mmode == MM_STAND )
			monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v8 + 1];
	}
}

//----- (00438D7E) --------------------------------------------------------
void __fastcall MAI_Zhar(int i)
{
	int v1; // ebp
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // edi
	int v6; // ebx
	int v7; // ebp
	int v8; // eax
	char v9; // al
	int arglist; // [esp+8h] [ebp-8h]
	int v11; // [esp+Ch] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Zhar: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mmode == MM_STAND )
	{
		v3 = monster[v2]._my;
		v4 = monster[v2]._mx;
		v11 = M_GetDir(v1);
		if ( monster[v2].mtalkmsg == TEXT_ZHAR1 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 )
		{
			monster[v2].mtalkmsg = TEXT_ZHAR2;
			_LOBYTE(monster[v2]._mgoal) = 6;
		}
		if ( dFlags[v4][v3] & 2 )
		{
			v5 = monster[v2]._mx - (unsigned char)monster[v2]._menemyx;
			v6 = monster[v2]._my - (unsigned char)monster[v2]._menemyy;
			v7 = abs(v6);
			if ( abs(v5) <= v7 )
				abs(v6);
			else
				abs(v5);
			if ( monster[v2].mtalkmsg == TEXT_ZHAR2 )
			{
				_LOBYTE(v8) = effect_is_playing(USFX_ZHAR2);
				if ( !v8 && _LOBYTE(monster[v2]._mgoal) == 7 )
				{
					_LOBYTE(monster[v2]._msquelch) = -1;
					monster[v2].mtalkmsg = 0;
					_LOBYTE(monster[v2]._mgoal) = 1;
				}
			}
		}
		v9 = monster[v2]._mgoal;
		if ( v9 == 1 || v9 == 2 || v9 == 4 )
			MAI_Counselor(arglist);
		monster[v2]._mdir = v11;
		if ( monster[v2]._mmode == MM_STAND )
			monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v11 + 1];
	}
}

//----- (00438EC2) --------------------------------------------------------
void __fastcall MAI_SnotSpil(int i)
{
	int v1; // ebp
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // ebp
	int v6; // eax
	char v7; // al
	int arglist; // [esp+8h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_SnotSpil: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mmode == MM_STAND )
	{
		v3 = monster[v2]._my;
		v4 = monster[v2]._mx;
		v5 = M_GetDir(v1);
		if ( monster[v2].mtalkmsg == TEXT_SNOT1 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 )
		{
			monster[v2].mtalkmsg = TEXT_SNOT2;
			_LOBYTE(monster[v2]._mgoal) = 6;
		}
		if ( monster[v2].mtalkmsg == TEXT_SNOT2 && quests[7]._qvar1 == 3 )
		{
			monster[v2].mtalkmsg = 0;
			_LOBYTE(monster[v2]._mgoal) = 1;
		}
		if ( dFlags[v4][v3] & 2 )
		{
			if ( monster[v2].mtalkmsg == TEXT_SNOT3 )
			{
				_LOBYTE(v6) = effect_is_playing(USFX_SNOT3);
				if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 )
				{
					DRLG_MRectTrans(setpc_x, setpc_y, setpc_w + setpc_x + 1, setpc_h + setpc_y + 1);
					quests[7]._qvar1 = 3;
					RedoPlayerVision();
					_LOBYTE(monster[v2]._msquelch) = -1;
					monster[v2].mtalkmsg = 0;
					_LOBYTE(monster[v2]._mgoal) = 1;
				}
			}
			if ( quests[7]._qvar1 == 3 )
			{
				v7 = monster[v2]._mgoal;
				if ( v7 == 1 || v7 == 5 )
					MAI_Fallen(arglist);
			}
		}
		monster[v2]._mdir = v5;
		if ( monster[v2]._mmode == MM_STAND )
			monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1];
	}
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00439016) --------------------------------------------------------
void __fastcall MAI_Lazurus(int i)
{
	int v1; // ebx
	int v2; // esi
	int v3; // ebp
	int v4; // edi
	int v5; // ebx
	int v6; // eax
	char v7; // al
	int v8; // eax
	int arglist; // [esp+8h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Lazurus: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mmode == MM_STAND )
	{
		v3 = monster[v2]._my;
		v4 = monster[v2]._mx;
		v5 = M_GetDir(v1);
		if ( dFlags[v4][v3] & 2 )
		{
			if ( gbMaxPlayers != 1 )
				goto LABEL_29;
			if ( monster[v2].mtalkmsg == TEXT_LAZ1_1 )
			{
				if ( _LOBYTE(monster[v2]._mgoal) == 6 && plr[myplr].WorldX == TEXT_LAZ1_1 && plr[myplr].WorldY == 46 )
				{
					PlayInGameMovie("gendata\\fprst3.smk");
					monster[v2]._mmode = MM_TALK;
					quests[15]._qvar1 = 5;
				}
				if ( monster[v2].mtalkmsg == TEXT_LAZ1_1 )
				{
					_LOBYTE(v6) = effect_is_playing(USFX_LAZ1);
					if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 )
					{
						ObjChangeMapResync(1, 18, 20, 24);
						RedoPlayerVision();
						_LOBYTE(monster[v2]._msquelch) = -1;
						monster[v2].mtalkmsg = 0;
						quests[15]._qvar1 = 6;
						_LOBYTE(monster[v2]._mgoal) = 1;
					}
				}
			}
			if ( gbMaxPlayers != 1 )
			{
LABEL_29:
				if ( monster[v2].mtalkmsg == TEXT_LAZ1_1 && _LOBYTE(monster[v2]._mgoal) == 6 && quests[15]._qvar1 <= 3u )
					monster[v2]._mmode = MM_TALK;
			}
		}
		v7 = monster[v2]._mgoal;
		if ( v7 == 1 || v7 == 2 || v7 == 4 )
		{
			monster[v2].mtalkmsg = 0;
			MAI_Counselor(arglist);
		}
		monster[v2]._mdir = v5;
		v8 = monster[v2]._mmode;
		if ( v8 == MM_STAND || v8 == MM_TALK )
			monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1];
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00439196) --------------------------------------------------------
void __fastcall MAI_Lazhelp(int i)
{
	int v1; // esi
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // [esp+4h] [ebp-8h]
	int ia; // [esp+8h] [ebp-4h]

	v1 = i;
	ia = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Lazhelp: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v2]._mmode == MM_STAND )
	{
		v3 = monster[v2]._my;
		v4 = monster[v2]._mx;
		v5 = M_GetDir(ia);
		if ( dFlags[v4][v3] & 2 )
		{
			if ( gbMaxPlayers == 1 )
			{
				if ( quests[15]._qvar1 <= 5u )
				{
					_LOBYTE(monster[v2]._mgoal) = 6;
					goto LABEL_10;
				}
				monster[v2].mtalkmsg = 0;
			}
			_LOBYTE(monster[v2]._mgoal) = 1;
		}
LABEL_10:
		if ( _LOBYTE(monster[v2]._mgoal) == 1 )
			MAI_Succ(ia);
		monster[v2]._mdir = v5;
		if ( monster[v2]._mmode == MM_STAND )
			monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1];
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00439253) --------------------------------------------------------
void __fastcall MAI_Lachdanan(int i)
{
	int v1; // ebp
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // eax
	int v6; // [esp+8h] [ebp-4h]

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Lachdanan: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mmode == MM_STAND )
	{
		v3 = monster[v2]._my;
		v4 = monster[v2]._mx;
		v6 = M_GetDir(v1);
		if ( monster[v2].mtalkmsg == TEXT_LACH1 && !(dFlags[v4][v3] & 2) && _LOBYTE(monster[v2]._mgoal) == 7 )
		{
			monster[v2].mtalkmsg = TEXT_LACH2;
			_LOBYTE(monster[v2]._mgoal) = 6;
		}
		if ( dFlags[v4][v3] & 2 )
		{
			if ( monster[v2].mtalkmsg == TEXT_LACH3 )
			{
				_LOBYTE(v5) = effect_is_playing(USFX_LACH3);
				if ( !v5 && _LOBYTE(monster[v2]._mgoal) == 7 )
				{
					monster[v2].mtalkmsg = 0;
					quests[4]._qactive = 3;
					M_StartKill(v1, -1);
				}
			}
		}
		monster[v2]._mdir = v6;
		if ( monster[v2]._mmode == MM_STAND )
			monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v6 + 1];
	}
}

//----- (00439338) --------------------------------------------------------
void __fastcall MAI_Warlord(int i)
{
	int v1; // ebp
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // ebp
	int v6; // eax
	int v7; // eax
	int arglist; // [esp+8h] [ebp-4h]

	v1 = i;
	arglist = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("MAI_Warlord: Invalid monster %d", i);
	v2 = v1;
	if ( monster[v1]._mmode == MM_STAND )
	{
		v3 = monster[v2]._my;
		v4 = monster[v2]._mx;
		v5 = M_GetDir(v1);
		if ( dFlags[v4][v3] & 2 && monster[v2].mtalkmsg == TEXT_WARLRD1 )
		{
			if ( _LOBYTE(monster[v2]._mgoal) == 6 )
				monster[v2]._mmode = MM_TALK;
			_LOBYTE(v6) = effect_is_playing(USFX_WARLRD1);
			if ( !v6 && _LOBYTE(monster[v2]._mgoal) == 7 )
			{
				_LOBYTE(monster[v2]._msquelch) = -1;
				monster[v2].mtalkmsg = 0;
				_LOBYTE(monster[v2]._mgoal) = 1;
			}
		}
		if ( _LOBYTE(monster[v2]._mgoal) == 1 )
			MAI_SkelSd(arglist);
		monster[v2]._mdir = v5;
		v7 = monster[v2]._mmode;
		if ( v7 == MM_STAND || v7 == MM_TALK )
			monster[v2]._mAFNum = monster[v2].MType->Anims[0].Frames[v5 + 1];
	}
}

//----- (00439419) --------------------------------------------------------
void __cdecl DeleteMonsterList()
{
	int *v0; // eax
	signed int v1; // ecx

	v0 = &monster[0]._my;
	do
	{
		if ( v0[18] )
		{
			*(v0 - 1) = 1;
			*v0 = 0;
			v0[1] = 0;
			v0[2] = 0;
			v0[3] = 0;
			v0[4] = 0;
			v0[18] = 0;
		}
		v0 += 57;
	}
	while ( (signed int)v0 < (signed int)&monster[4]._my );
	v1 = 4;
	while ( v1 < nummonsters )
	{
		if ( monster[monstactive[v1]]._mDelFlag )
		{
			DeleteMonster(v1);
			v1 = 0;
		}
		else
		{
			++v1;
		}
	}
}

//----- (0043947E) --------------------------------------------------------
void __cdecl ProcessMonsters()
{
	int v0; // edi
	int v1; // esi
	int v2; // ecx
	int v3; // eax
	char *v4; // ebx
	unsigned int v5; // eax
	int v6; // eax
	int v7; // edx
	int v8; // eax
	unsigned int v9; // eax
	int v10; // eax
	bool v11; // zf
	char *v12; // ecx
	char *v13; // eax
	int v14; // ecx
	int v15; // eax
	char v16; // al
	int v17; // ecx
	int v18; // eax
	int v19; // eax
	int v20; // ecx
	int *v21; // eax
	int *v22; // eax
	int v23; // [esp+0h] [ebp-Ch]
	int v24; // [esp+4h] [ebp-8h]
	int v25; // [esp+8h] [ebp-4h]

	DeleteMonsterList();
	v24 = 0;
	if ( nummonsters <= 0 )
		goto LABEL_60;
	do
	{
		v25 = 0;
		v23 = monstactive[v24];
		v0 = v23;
		v1 = v23;
		if ( (unsigned char)gbMaxPlayers > 1u )
		{
			SetRndSeed(monster[v1]._mAISeed);
			monster[v1]._mAISeed = GetRndSeed();
		}
		if ( !(monster[v1]._mFlags & 8) )
		{
			v2 = monster[v1]._mhitpoints;
			if ( v2 < monster[v1]._mmaxhp && (signed int)(v2 & 0xFFFFFFC0) > 0 )
			{
				v3 = SLOBYTE(monster[v1].mLevel);
				if ( (char)v3 > 1 )
					v3 = (char)v3 >> 1;
				monster[v1]._mhitpoints = v2 + v3;
			}
		}
		v4 = &dFlags[monster[v1]._mx][monster[v1]._my];
		if ( *v4 & 2 && !_LOBYTE(monster[v1]._msquelch) && monster[v1].MType->mtype == MON_BUTCH )
			PlaySFX(USFX_CLEAVER);
		if ( monster[v1]._mFlags & 0x10 )
		{
			v5 = monster[v1]._menemy;
			if ( v5 >= 0xC8 )
				TermMsg("Illegal enemy monster %d for monster \"%s\"", v5, monster[v1].mName);
			v6 = monster[v1]._menemy;
			v7 = monster[v6]._mfutx;
			monster[v1]._lastx = v7;
			monster[v1]._menemyx = v7;
			v8 = monster[v6]._mfuty;
			monster[v1]._menemyy = v8;
			monster[v1]._lasty = v8;
		}
		else
		{
			v9 = monster[v1]._menemy;
			if ( v9 >= 4 )
				TermMsg("Illegal enemy player %d for monster \"%s\"", v9, monster[v1].mName);
			v10 = monster[v1]._menemy;
			v11 = (*v4 & 2) == 0;
			v12 = (char *)&plr[v10]._px;
			v13 = (char *)&plr[v10]._py;
			monster[v1]._menemyx = *v12;
			monster[v1]._menemyy = *v13;
			if ( v11 )
			{
				v16 = monster[v1]._msquelch;
				if ( v16 && monster[v1]._mAi != MON_DIABLO )
					_LOBYTE(monster[v1]._msquelch) = v16 - 1;
			}
			else
			{
				v14 = *(_DWORD *)v12;
				v15 = *(_DWORD *)v13;
				_LOBYTE(monster[v1]._msquelch) = -1;
				monster[v1]._lastx = v14;
				monster[v1]._lasty = v15;
			}
			v0 = v23;
		}
		while ( 1 )
		{
			v17 = v0;
			if ( monster[v1]._mFlags & 0x100 )
			{
				MAI_Path(v0);
				if ( v18 )
					goto LABEL_30;
				v17 = v0;
			}
			AiProc[(unsigned char)monster[v1]._mAi](v17);
LABEL_30:
			switch ( monster[v1]._mmode )
			{
				case MM_STAND:
					v19 = M_DoStand(v0);
					goto LABEL_48;
				case MM_WALK:
					v19 = M_DoWalk(v0);
					goto LABEL_48;
				case MM_WALK2:
					v19 = M_DoWalk2(v0);
					goto LABEL_48;
				case MM_WALK3:
					v19 = M_DoWalk3(v0);
					goto LABEL_48;
				case MM_ATTACK:
					v19 = M_DoAttack(v0);
					goto LABEL_48;
				case MM_GOTHIT:
					v19 = M_DoGotHit(v0);
					goto LABEL_48;
				case MM_DEATH:
					v19 = M_DoDeath(v0);
					goto LABEL_48;
				case MM_SATTACK:
					v19 = M_DoSAttack(v0);
					goto LABEL_48;
				case MM_FADEIN:
					v19 = M_DoFadein(v0);
					goto LABEL_48;
				case MM_FADEOUT:
					v19 = M_DoFadeout(v0);
					goto LABEL_48;
				case MM_RATTACK:
					v19 = M_DoRAttack(v0);
					goto LABEL_48;
				case MM_SPSTAND:
					v19 = M_DoSpStand(v0);
					goto LABEL_48;
				case MM_RSPATTACK:
					v19 = M_DoRSpAttack(v0);
					goto LABEL_48;
				case MM_DELAY:
					v19 = M_DoDelay(v0);
					goto LABEL_48;
				case MM_CHARGE:
					goto LABEL_51;
				case MM_STONE:
					v19 = M_DoStone(v0);
					goto LABEL_48;
				case MM_HEAL:
					v19 = M_DoHeal(v0);
					goto LABEL_48;
				case MM_TALK:
					v19 = M_DoTalk(v0);
LABEL_48:
					v25 = v19;
					break;
				default:
					break;
			}
			if ( !v25 )
				break;
			GroupUnity(v0);
		}
LABEL_51:
		if ( monster[v1]._mmode != MM_STONE )
		{
			v20 = monster[v1]._mFlags;
			v21 = &monster[v1]._mAnimCnt;
			++*v21;
			if ( !(v20 & 4) && monster[v1]._mAnimCnt >= monster[v1]._mAnimDelay )
			{
				*v21 = 0;
				v22 = &monster[v1]._mAnimFrame;
				if ( v20 & 2 )
				{
					v11 = (*v22)-- == 1;
					if ( v11 )
						*v22 = monster[v1]._mAnimLen;
				}
				else if ( ++*v22 > monster[v1]._mAnimLen )
				{
					*v22 = 1;
				}
			}
		}
		++v24;
	}
	while ( v24 < nummonsters );
LABEL_60:
	DeleteMonsterList();
}
// 679660: using guessed type char gbMaxPlayers;

//----- (004397C5) --------------------------------------------------------
void __cdecl FreeMonsters()
{
	void **v0; // edi
	int v1; // ebx
	signed int v2; // ebp
	void **v3; // esi
	void *v4; // ecx
	int v5; // [esp+0h] [ebp-4h]

	v5 = 0;
	if ( nummtypes > 0 )
	{
		v0 = (void **)Monsters[0].Anims;
		do
		{
			v1 = *((unsigned char *)v0 - 4);
			v2 = 0;
			v3 = v0;
			do
			{
				if ( animletter[v2] != 's' || monsterdata[v1].has_special )
				{
					v4 = *v3;
					*v3 = 0;
					mem_free_dbg(v4);
				}
				++v2;
				v3 += 11;
			}
			while ( v2 < 6 );
			++v5;
			v0 += 82;
		}
		while ( v5 < nummtypes );
	}
	FreeMissiles2();
}

//----- (00439831) --------------------------------------------------------
unsigned char __fastcall DirOK(int i, int mdir)
{
	int v2; // ebx
	int v3; // esi
	int v4; // ebx
	int v5; // edi
	int v6; // esi
	int v7; // edi
	bool v8; // zf
	int v9; // edx
	char *v11; // ebx
	unsigned char v12; // al
	int v13; // edx
	int v14; // eax
	int v15; // edi
	int v16; // ecx
	signed int j; // esi
	int v18; // eax
	bool v19; // zf
	int v20; // eax
	int v21; // [esp+Ch] [ebp-14h]
	int v22; // [esp+10h] [ebp-10h]
	int v23; // [esp+14h] [ebp-Ch]
	int a1; // [esp+18h] [ebp-8h]
	int v25; // [esp+1Ch] [ebp-4h]
	int v26; // [esp+1Ch] [ebp-4h]

	v2 = i;
	v3 = mdir;
	v25 = mdir;
	a1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("DirOK: Invalid monster %d", i);
	v4 = v2;
	v5 = offset_y[v3];
	v6 = monster[v4]._mx + offset_x[v3];
	v7 = monster[v4]._my + v5;
	if ( v7 < 0 || v7 >= 112 || v6 < 0 || v6 >= 112 || !PosOkMonst(a1, v6, v7) )
		return 0;
	if ( v25 == DIR_E )
	{
		if ( !SolidLoc(v6, v7 + 1) )
		{
			v8 = (dFlags[v6][v7 + 1] & 0x10) == 0;
			goto LABEL_18;
		}
		return 0;
	}
	if ( v25 == DIR_W )
	{
		if ( SolidLoc(v6 + 1, v7) )
			return 0;
		v8 = (dFlags[v6 + 1][v7] & 0x10) == 0;
	}
	else
	{
		if ( v25 == DIR_N )
		{
			if ( SolidLoc(v6 + 1, v7) )
				return 0;
			v9 = v7 + 1;
		}
		else
		{
			if ( v25 )
				goto LABEL_24;
			if ( SolidLoc(v6 - 1, v7) )
				return 0;
			v9 = v7 - 1;
		}
		v8 = SolidLoc(v6, v9) == 0;
	}
LABEL_18:
	if ( !v8 )
		return 0;
LABEL_24:
	if ( monster[v4].leaderflag == 1 )
	{
		v11 = &monster[v4].leader;
		if ( abs(v6 - monster[(unsigned char)*v11]._mfutx) >= 4
		  || abs(v7 - monster[(unsigned char)*v11]._mfuty) >= 4 )
		{
			return 0;
		}
		return 1;
	}
	v12 = monster[v4]._uniqtype;
	if ( !v12 || !(MonstAvailTbl[32 * v12 + 102] & 2) )
		return 1;
	v26 = 0;
	v13 = v6 - 3;
	v21 = v6 + 3;
	if ( v6 - 3 <= v6 + 3 )
	{
		v14 = v7 - 3;
		v15 = v7 + 3;
		v23 = v14;
		v22 = v15;
		v16 = 112 * v13;
		do
		{
			for ( j = v23; j <= v15; ++j )
			{
				if ( j >= 0 && j < 112 && v16 >= 0 && v16 < 12544 )
				{
					v18 = dMonster[0][v16 + j];
					v19 = v18 == 0;
					if ( v18 < 0 )
					{
						v18 = -v18;
						v19 = v18 == 0;
					}
					if ( !v19 )
						--v18;
					v20 = v18;
					if ( monster[v20].leaderflag == 1
					  && (unsigned char)monster[v20].leader == a1
					  && monster[v20]._mfutx == v13
					  && monster[v20]._mfuty == j )
					{
						++v26;
					}
				}
				v15 = v22;
			}
			++v13;
			v16 += 112;
		}
		while ( v13 <= v21 );
	}
	return v26 == (unsigned char)monster[v4].unpackfilesize;
}

//----- (00439A32) --------------------------------------------------------
unsigned char __fastcall PosOkMissile(int x, int y)
{
	int v2; // ecx
	unsigned char result; // al

	v2 = x;
	result = 0;
	if ( !nMissileTable[dPiece[0][v2 * 112 + y]] && !(dFlags[v2][y] & 0x10) )
		result = 1;
	return result;
}

//----- (00439A57) --------------------------------------------------------
unsigned char __fastcall CheckNoSolid(int x, int y)
{
	return nSolidTable[dPiece[0][y + 112 * x]] == 0;
}

//----- (00439A71) --------------------------------------------------------
unsigned char __fastcall LineClearF(unsigned char (__cdecl *Clear)(), int x1, int y1, int x2, int y2)
{
	int v5; // esi
	int v6; // edi
	int v7; // ebx
	int v8; // eax
	int v9; // eax
	int v10; // eax
	int v11; // ebx
	int v12; // esi
	signed int v13; // edi
	int v14; // edx
	int v15; // ecx
	int v16; // eax
	int v17; // eax
	int v18; // eax
	int v19; // ebx
	int v20; // edi
	signed int v21; // esi
	int v22; // ecx
	unsigned char (__cdecl *v24)(); // [esp+Ch] [ebp-14h]
	int v25; // [esp+10h] [ebp-10h]
	int v26; // [esp+14h] [ebp-Ch]
	int v27; // [esp+18h] [ebp-8h]
	int v28; // [esp+18h] [ebp-8h]
	int v29; // [esp+1Ch] [ebp-4h]

	v5 = y2 - y1;
	v29 = x1;
	v24 = Clear;
	v25 = x1;
	v26 = y1;
	v6 = x2 - x1;
	v7 = abs(y2 - y1);
	if ( abs(v6) <= v7 )
	{
		if ( v5 < 0 )
		{
			v16 = y1;
			y1 = y2;
			y2 = v16;
			v17 = v29;
			v5 = -v5;
			v29 = x2;
			x2 = v17;
			v6 = -v6;
		}
		v18 = 2 * v6;
		v28 = 2 * v6;
		if ( v6 <= 0 )
		{
			v19 = v18 + v5;
			v20 = 2 * (v5 + v6);
			v21 = -1;
		}
		else
		{
			v19 = v18 - v5;
			v20 = 2 * (v6 - v5);
			v21 = 1;
		}
		while ( 1 )
		{
			v22 = v29;
			if ( y1 == y2 && v29 == x2 )
				break;
			if ( v19 <= 0 == v21 < 0 )
			{
				v19 += v20;
				v22 = v21 + v29;
				v29 += v21;
			}
			else
			{
				v19 += v28;
			}
			if ( (++y1 != v26 || v22 != v25) && !((int (__fastcall *)(int))v24)(v22) )
				goto LABEL_29;
		}
	}
	else
	{
		if ( v6 < 0 )
		{
			v8 = v29;
			v29 = x2;
			x2 = v8;
			v9 = y1;
			v6 = -v6;
			y1 = y2;
			y2 = v9;
			v5 = -v5;
		}
		v10 = 2 * v5;
		v27 = 2 * v5;
		if ( v5 <= 0 )
		{
			v11 = v10 + v6;
			v12 = 2 * (v6 + v5);
			v13 = -1;
		}
		else
		{
			v11 = v10 - v6;
			v12 = 2 * (v5 - v6);
			v13 = 1;
		}
		do
		{
			v14 = y1;
			if ( v29 == x2 && y1 == y2 )
				break;
			if ( v11 <= 0 == v13 < 0 )
			{
				v11 += v12;
				v14 = v13 + y1;
				y1 += v13;
			}
			else
			{
				v11 += v27;
			}
			v15 = v29 + 1;
		}
		while ( ++v29 == v25 && v14 == v26 || ((int (__fastcall *)(int, int))v24)(v15, v14) );
LABEL_29:
		if ( v29 != x2 )
			return 0;
	}
	if ( y1 == y2 )
		return 1;
	return 0;
}

//----- (00439BE0) --------------------------------------------------------
unsigned char __fastcall LineClear(int x1, int y1, int x2, int y2)
{
	return LineClearF((unsigned char (__cdecl *)())PosOkMissile, x1, y1, x2, y2);
}

//----- (00439BFA) --------------------------------------------------------
unsigned char __fastcall LineClearF1(unsigned char (__cdecl *Clear)(), int monst, int x1, int y1, int x2, int y2)
{
	int v6; // esi
	int v7; // edi
	int v8; // ebx
	int v9; // eax
	int v10; // eax
	int v11; // eax
	int v12; // ebx
	int v13; // esi
	signed int v14; // edi
	int v15; // eax
	int v16; // eax
	int v17; // eax
	int v18; // eax
	int v19; // ebx
	int v20; // edi
	signed int v21; // esi
	int v22; // edx
	unsigned char (__cdecl *v24)(); // [esp+Ch] [ebp-14h]
	int v25; // [esp+10h] [ebp-10h]
	int v26; // [esp+14h] [ebp-Ch]
	int v27; // [esp+18h] [ebp-8h]
	int v28; // [esp+1Ch] [ebp-4h]
	int v29; // [esp+1Ch] [ebp-4h]

	v24 = Clear;
	v6 = y2 - y1;
	v25 = monst;
	v26 = x1;
	v27 = y1;
	v7 = x2 - x1;
	v8 = abs(y2 - y1);
	if ( abs(x2 - x1) <= v8 )
	{
		if ( v6 < 0 )
		{
			v16 = y1;
			y1 = y2;
			y2 = v16;
			v17 = x1;
			v6 = -v6;
			x1 = x2;
			x2 = v17;
			v7 = -v7;
		}
		v18 = 2 * v7;
		v29 = 2 * v7;
		if ( v7 <= 0 )
		{
			v19 = v18 + v6;
			v20 = 2 * (v6 + v7);
			v21 = -1;
		}
		else
		{
			v19 = v18 - v6;
			v20 = 2 * (v7 - v6);
			v21 = 1;
		}
		while ( 1 )
		{
			v22 = x1;
			if ( y1 == y2 && x1 == x2 )
				break;
			if ( v19 <= 0 == v21 < 0 )
			{
				v19 += v20;
				v22 = v21 + x1;
				x1 += v21;
			}
			else
			{
				v19 += v29;
			}
			if ( (++y1 != v27 || v22 != v26) && !((int (__fastcall *)(int, int, int))v24)(v25, v22, y1) )
				goto LABEL_29;
		}
	}
	else
	{
		if ( v7 < 0 )
		{
			v9 = x1;
			x1 = x2;
			x2 = v9;
			v10 = y1;
			v7 = -v7;
			y1 = y2;
			y2 = v10;
			v6 = -v6;
		}
		v11 = 2 * v6;
		v28 = 2 * v6;
		if ( v6 <= 0 )
		{
			v12 = v11 + v7;
			v13 = 2 * (v7 + v6);
			v14 = -1;
		}
		else
		{
			v12 = v11 - v7;
			v13 = 2 * (v6 - v7);
			v14 = 1;
		}
		do
		{
			v15 = y1;
			if ( x1 == x2 && y1 == y2 )
				break;
			if ( v12 <= 0 == v14 < 0 )
			{
				v12 += v13;
				v15 = v14 + y1;
				y1 += v14;
			}
			else
			{
				v12 += v28;
			}
		}
		while ( ++x1 == v26 && v15 == v27 || ((int (__fastcall *)(int, int))v24)(v25, v15) );
LABEL_29:
		if ( x1 != x2 )
			return 0;
	}
	if ( y1 == y2 )
		return 1;
	return 0;
}

//----- (00439D75) --------------------------------------------------------
int __fastcall SyncMonsterAnim(int monst)
{
	int v1; // esi
	int result; // eax
	int v3; // edx
	MonsterData *v4; // esi
	CMonster *v5; // ecx
	unsigned char v6; // dl
	char *v7; // edx
	int v8; // esi
	int v9; // edx
	int v10; // ecx
	int v11; // edx
	int v12; // ecx
	int v13; // edx

	v1 = monst;
	if ( (unsigned int)monst >= 0xC8 )
		TermMsg("SyncMonsterAnim: Invalid monster %d", monst);
	result = v1;
	v3 = monster[v1]._mMTidx;
	v4 = Monsters[v3].MData;
	v5 = &Monsters[v3];
	v6 = monster[result]._uniqtype;
	monster[result].MType = v5;
	monster[result].MData = v4;
	if ( v6 )
		v7 = *(char **)&MonstAvailTbl[32 * v6 + 84];
	else
		v7 = v4->mName;
	v8 = monster[result]._mmode;
	monster[result].mName = v7;
	v9 = monster[result]._mdir;
	switch ( v8 )
	{
		case MM_STAND:
		case MM_DELAY:
		case MM_TALK:
			v10 = v5->Anims[0].Frames[v9 + 1];
			goto LABEL_13;
		case MM_WALK:
		case MM_WALK2:
		case MM_WALK3:
			v10 = v5->Anims[1].Frames[v9 + 1];
			goto LABEL_13;
		case MM_ATTACK:
		case MM_RATTACK:
			v10 = v5->Anims[2].Frames[v9 + 1];
			goto LABEL_13;
		case MM_GOTHIT:
			v10 = v5->Anims[3].Frames[v9 + 1];
			goto LABEL_13;
		case MM_DEATH:
			v10 = v5->Anims[4].Frames[v9 + 1];
			goto LABEL_13;
		case MM_SATTACK:
		case MM_FADEIN:
		case MM_FADEOUT:
		case MM_SPSTAND:
		case MM_RSPATTACK:
		case MM_HEAL:
			v10 = v5->Anims[5].Frames[v9 + 1];
LABEL_13:
			monster[result]._mAFNum = v10;
			return result * 228;
		case MM_CHARGE:
			v11 = v5->Anims[2].Frames[v9 + 1];
			monster[result]._mAnimFrame = 1;
			monster[result]._mAFNum = v11;
			v12 = v5->Anims[2].Rate;
			break;
		default:
			v13 = v5->Anims[0].Frames[v9 + 1];
			monster[result]._mAnimFrame = 1;
			monster[result]._mAFNum = v13;
			v12 = v5->Anims[0].Rate;
			break;
	}
	monster[result]._mAnimLen = v12;
	return result * 228;
}

//----- (00439EA8) --------------------------------------------------------
void __fastcall M_FallenFear(int x, int y)
{
	int v2; // eax
	int *v3; // ebx
	int v4; // edi
	int v5; // esi
	signed int v6; // eax
	int v7; // eax
	bool v8; // zf
	int v9; // eax
	int v10; // eax
	signed int v11; // [esp-10h] [ebp-1Ch]
	int v12; // [esp+0h] [ebp-Ch]
	int x1; // [esp+4h] [ebp-8h]
	int y1; // [esp+8h] [ebp-4h]

	v2 = 0;
	y1 = y;
	x1 = x;
	v12 = 0;
	if ( nummonsters > 0 )
	{
		v3 = &monster[0]._mx;
		do
		{
			v4 = 0;
			v5 = monstactive[v2];
			v6 = monster[v5].MType->mtype;
			if ( v6 > MON_FALSWORDA )
			{
				v9 = v6 - 13;
				v8 = v9 == 0;
			}
			else
			{
				if ( v6 == MON_FALSWORDA || (v7 = v6 - 4) == 0 )
				{
					v11 = 7;
					goto LABEL_15;
				}
				v9 = v7 - 1;
				v8 = v9 == 0;
			}
			if ( v8 )
			{
				v11 = 5;
			}
			else
			{
				v10 = v9 - 1;
				if ( v10 )
				{
					if ( v10 != 1 )
						goto LABEL_16;
					v11 = 2;
				}
				else
				{
					v11 = 3;
				}
			}
LABEL_15:
			v4 = v11;
LABEL_16:
			if ( monster[v5]._mAi == MG_FALLEN
			  && v4
			  && abs(x1 - monster[v5]._mx) < 5
			  && abs(y1 - monster[v5]._my) < 5
			  && (signed int)(monster[v5]._mhitpoints & 0xFFFFFFC0) > 0 )
			{
				_LOBYTE(monster[v5]._mgoal) = 2;
				monster[v5]._mgoalvar1 = v4;
				monster[v5]._mdir = GetDirection(x1, y1, *v3, v3[1]);
			}
			v3 += 57;
			v2 = v12++ + 1;
		}
		while ( v12 < nummonsters );
	}
}

//----- (00439F92) --------------------------------------------------------
void __fastcall PrintMonstHistory(int mt)
{
	int v1; // edi
	int *v2; // ebx
	int v3; // ecx
	int v4; // eax
	int v5; // edi
	short v6; // bx
	int v7; // ebx

	v1 = mt;
	v2 = &monstkills[mt];
	sprintf(tempstr, "Total kills : %i", *v2);
	AddPanelString(tempstr, 1);
	if ( *v2 >= 30 )
	{
		v3 = monsterdata[v1].mMinHP;
		v4 = monsterdata[v1].mMaxHP;
		if ( gbMaxPlayers == 1 )
		{
			v3 = monsterdata[v1].mMinHP >> 1;
			v4 = monsterdata[v1].mMaxHP >> 1;
		}
		if ( v3 < 1 )
			v3 = 1;
		if ( v4 < 1 )
			v4 = 1;
		if ( gnDifficulty == 1 )
		{
			v3 = 3 * v3 + 1;
			v4 = 3 * v4 + 1;
		}
		if ( gnDifficulty == DIFF_HELL )
		{
			v3 = 4 * v3 + 3;
			v4 = 4 * v4 + 3;
		}
		sprintf(tempstr, "Hit Points : %i-%i", v3, v4);
		AddPanelString(tempstr, 1);
	}
	if ( *v2 >= 15 )
	{
		v5 = v1 << 7;
		if ( gnDifficulty == DIFF_HELL )
			v6 = *(short *)((char *)&monsterdata[0].mMagicRes2 + v5);
		else
			v6 = *(short *)((char *)&monsterdata[0].mMagicRes + v5);
		v7 = v6 & 0x3F;
		if ( v7 )
		{
			if ( v7 & 7 )
			{
				strcpy(tempstr, "Resists : ");
				if ( v7 & 1 )
					strcat(tempstr, "Magic ");
				if ( v7 & 2 )
					strcat(tempstr, "Fire ");
				if ( v7 & 4 )
					strcat(tempstr, "Lightning ");
				*(_BYTE *)(strlen(tempstr) + 4950091) = 0;
				AddPanelString(tempstr, 1);
			}
			if ( v7 & 0x38 )
			{
				strcpy(tempstr, "Immune : ");
				if ( v7 & 8 )
					strcat(tempstr, "Magic ");
				if ( v7 & 0x10 )
					strcat(tempstr, "Fire ");
				if ( v7 & 0x20 )
					strcat(tempstr, "Lightning ");
				*(_BYTE *)(strlen(tempstr) + 4950091) = 0;
				AddPanelString(tempstr, 1);
			}
		}
		else
		{
			strcpy(tempstr, "No magic resistance");
			AddPanelString(tempstr, 1);
		}
	}
	pinfoflag = 1;
}
// 4B8824: using guessed type int pinfoflag;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043A13A) --------------------------------------------------------
void __cdecl PrintUniqueHistory()
{
	char v0; // bl

	v0 = monster[*(_DWORD *)&pcursmonst].mMagicRes & 0x3F;
	if ( v0 )
	{
		if ( monster[*(_DWORD *)&pcursmonst].mMagicRes & 7 )
			strcpy(tempstr, "Some Magic Resistances");
		else
			strcpy(tempstr, "No resistances");
		AddPanelString(tempstr, 1);
		if ( v0 & 0x38 )
		{
			strcpy(tempstr, "Some Magic Immunities");
			goto LABEL_4;
		}
	}
	else
	{
		strcpy(tempstr, "No resistances");
		AddPanelString(tempstr, 1);
	}
	strcpy(tempstr, "No Immunities");
LABEL_4:
	AddPanelString(tempstr, 1);
	pinfoflag = 1;
}
// 4B8824: using guessed type int pinfoflag;

//----- (0043A1C1) --------------------------------------------------------
void __fastcall MissToMonst(int i, int x, int y)
{
	int v3; // edi
	MissileStruct *v4; // edi
	unsigned int v5; // ebx
	MonsterStruct *v6; // esi
	int v7; // edx
	char v8; // al
	int v9; // eax
	char *v10; // edi
	int v11; // eax
	int v12; // edx
	char v13; // al
	char v14; // al
	int v15; // ebx
	int v16; // eax
	int v17; // esi
	int v18; // edi
	int v19; // esi
	int v20; // edx
	int *v21; // ebx
	char v22; // cl
	char v23; // al
	int v24; // esi
	int v25; // edi
	int v26; // esi
	int v27; // eax
	int v28; // eax
	int ia; // [esp+Ch] [ebp-10h]
	int v30; // [esp+10h] [ebp-Ch]
	int v31; // [esp+14h] [ebp-8h]
	int v32; // [esp+18h] [ebp-4h]
	int arglist; // [esp+24h] [ebp+8h]

	v3 = i;
	v30 = x;
	if ( (unsigned int)i >= 0x7D )
		TermMsg("MissToMonst: Invalid missile %d", i);
	v4 = &missile[v3];
	v5 = v4->_misource;
	ia = v4->_misource;
	if ( v5 >= 0xC8 )
		TermMsg("MissToMonst: Invalid monster %d", v5);
	v32 = v4->_mix;
	v31 = v4->_miy;
	v6 = &monster[v5];
	v6->_mx = v30;
	dMonster[0][y + 112 * v30] = v5 + 1;
	v7 = v4->_mimfnum;
	v6->_mdir = v7;
	v6->_my = y;
	M_StartStand(v5, v7);
	v8 = v6->MType->mtype;
	if ( v8 < MON_FIREMANA || v8 > MON_FIREMAND )
	{
		if ( v6->_mFlags & 0x10 )
			M2MStartHit(v5, -1, 0);
		else
			M_StartHit(v5, -1, 0);
	}
	else
	{
		M_StartFadein(v5, v6->_mdir, 0);
	}
	v9 = v32;
	if ( v6->_mFlags & 0x10 )
	{
		v21 = (int *)((char *)dMonster + 4 * (v31 + v9 * 112));
		if ( *v21 > 0 )
		{
			v22 = v6->MType->mtype;
			if ( v22 != MON_BATC && (v22 < MON_FIREMANA || v22 > MON_FIREMAND) )
			{
				M_TryM2MHit(ia, *v21 - 1, 500, (unsigned char)v6->mMinDamage2, (unsigned char)v6->mMaxDamage2);
				v23 = v6->MType->mtype;
				if ( v23 < MON_SNAKEA || v23 > MON_SNAKED )
				{
					v24 = v6->_mdir;
					v25 = v32 + offset_x[v24];
					v26 = v31 + offset_y[v24];
					if ( PosOkMonst(*v21 - 1, v25, v26) )
					{
						v27 = *v21;
						dMonster[0][v26 + 112 * v25] = *v21;
						*v21 = 0;
						v28 = v27 - 1;
						monster[v28]._mx = v25;
						monster[v28]._mfutx = v25;
						monster[v28]._my = v26;
						monster[v28]._mfuty = v26;
					}
				}
			}
		}
	}
	else
	{
		v10 = &dPlayer[v9][v31];
		v11 = *v10;
		v12 = v11 - 1;
		arglist = v11 - 1;
		if ( *v10 > 0 )
		{
			v13 = v6->MType->mtype;
			if ( v13 != MON_BATC && (v13 < MON_FIREMANA || v13 > MON_FIREMAND) )
			{
				M_TryH2HHit(v5, v12, 500, (unsigned char)v6->mMinDamage2, (unsigned char)v6->mMaxDamage2);
				if ( arglist == *v10 - 1 )
				{
					v14 = v6->MType->mtype;
					if ( v14 < MON_SNAKEA || v14 > MON_SNAKED )
					{
						v15 = arglist;
						v16 = plr[arglist]._pmode;
						if ( v16 != 7 && v16 != 8 )
							StartPlrHit(arglist, 0, 1u);
						v17 = v6->_mdir;
						v18 = v32 + offset_x[v17];
						v19 = v31 + offset_y[v17];
						if ( PosOkPlayer(arglist, v18, v19) )
						{
							v20 = plr[v15]._pdir;
							plr[v15].WorldX = v18;
							plr[v15].WorldY = v19;
							FixPlayerLocation(arglist, v20);
							FixPlrWalkTags(arglist);
							dPlayer[v18][v19] = arglist + 1;
							SetPlayerOld(arglist);
						}
					}
				}
			}
		}
	}
}

//----- (0043A45E) --------------------------------------------------------
int __fastcall PosOkMonst(int i, int x, int y)
{
	int v3; // edi
	signed int v4; // ebx
	int v5; // ecx
	char v6; // dl
	int result; // eax
	int v8; // edx
	int v9; // ecx
	int v10; // [esp+Ch] [ebp-4h]

	v3 = x;
	v10 = i;
	v4 = 0;
	if ( SolidLoc(x, y) )
		return 0;
	v5 = 112 * v3;
	if ( dPlayer[v3][y] || dMonster[0][v5 + y] )
		return 0;
	v6 = dObject[0][v5 + y];
	result = 1;
	if ( v6 )
	{
		v8 = v6 <= 0 ? -1 - v6 : v6 - 1;
		if ( object[v8]._oSolidFlag )
			return 0;
	}
	_LOBYTE(v5) = dMissile[0][v5 + y];
	if ( (_BYTE)v5 )
	{
		if ( v10 >= 0 )
		{
			v5 = (char)v5;
			if ( (char)v5 > 0 )
			{
				if ( missile[v5]._mitype == 5 )
					goto LABEL_24;
				v9 = 0;
				if ( nummissiles > 0 )
				{
					do
					{
						if ( missile[missileactive[v9]]._mitype == 5 )
							v4 = 1;
						++v9;
					}
					while ( v9 < nummissiles );
					if ( v4 )
					{
LABEL_24:
						if ( !(monster[v10].mMagicRes & 0x10) || monster[v10].MType->mtype == MON_DIABLO )
							return 0;
					}
				}
			}
		}
	}
	return result;
}

//----- (0043A547) --------------------------------------------------------
int __fastcall PosOkMonst2(int i, int x, int y)
{
	int v3; // edi
	int v4; // ebx
	signed int v5; // ebp
	int result; // eax
	char v7; // dl
	int v8; // edx
	int v9; // ecx
	int v10; // ecx

	v3 = x;
	v4 = i;
	v5 = 0;
	result = SolidLoc(x, y) == 0;
	if ( result )
	{
		v7 = dObject[v3][y];
		if ( v7 )
		{
			v8 = v7 <= 0 ? -1 - v7 : v7 - 1;
			if ( object[v8]._oSolidFlag )
				result = 0;
		}
		if ( result )
		{
			_LOBYTE(v9) = dMissile[v3][y];
			if ( (_BYTE)v9 )
			{
				if ( v4 >= 0 )
				{
					v9 = (char)v9;
					if ( (char)v9 > 0 )
					{
						if ( missile[v9]._mitype == 5 )
							goto LABEL_23;
						v10 = 0;
						if ( nummissiles > 0 )
						{
							do
							{
								if ( missile[missileactive[v10]]._mitype == 5 )
									v5 = 1;
								++v10;
							}
							while ( v10 < nummissiles );
							if ( v5 )
							{
LABEL_23:
								if ( !(monster[v4].mMagicRes & 0x10) || monster[v4].MType->mtype == MON_DIABLO )
									result = 0;
							}
						}
					}
				}
			}
		}
	}
	return result;
}

//----- (0043A613) --------------------------------------------------------
int __fastcall PosOkMonst3(int i, int x, int y)
{
	int v3; // esi
	signed int v4; // ebp
	char v5; // al
	int v6; // eax
	int v7; // eax
	int v8; // ecx
	int v9; // ecx
	int result; // eax
	int v11; // ecx
	signed int v12; // [esp+10h] [ebp-8h]
	int v13; // [esp+14h] [ebp-4h]

	v12 = 0;
	v3 = x;
	v4 = 0;
	v13 = i;
	v5 = dObject[x][y];
	if ( v5 )
	{
		if ( v5 <= 0 )
			v6 = -1 - v5;
		else
			v6 = v5 - 1;
		v7 = v6;
		v8 = object[v7]._otype;
		v4 = 1;
		if ( v8 != 1
		  && v8 != OBJ_L1RDOOR
		  && v8 != OBJ_L2LDOOR
		  && v8 != OBJ_L2RDOOR
		  && v8 != OBJ_L3LDOOR
		  && v8 != OBJ_L3RDOOR )
		{
			v4 = 0;
		}
		if ( object[v7]._oSolidFlag && !v4 )
			return 0;
	}
	if ( SolidLoc(x, y) && !v4 || dPlayer[v3][y] || dMonster[0][v3 * 112 + y] )
		return 0;
	_LOBYTE(v9) = dMissile[v3][y];
	result = 1;
	if ( (_BYTE)v9 )
	{
		if ( v13 >= 0 )
		{
			v9 = (char)v9;
			if ( (char)v9 > 0 )
			{
				if ( missile[v9]._mitype == 5 )
					goto LABEL_33;
				v11 = 0;
				if ( nummissiles > 0 )
				{
					do
					{
						if ( missile[missileactive[v11]]._mitype == 5 )
							v12 = 1;
						++v11;
					}
					while ( v11 < nummissiles );
					if ( v12 )
					{
LABEL_33:
						if ( !(monster[v13].mMagicRes & 0x10) || monster[v13].MType->mtype == MON_DIABLO )
							return 0;
					}
				}
			}
		}
	}
	return result;
}

//----- (0043A73B) --------------------------------------------------------
BOOL __fastcall IsSkel(int mt)
{
	return mt >= MON_SKELAXEA && mt <= MON_SKELAXED
		|| mt >= MON_SKELBOWA && mt <= MON_SKELBOWD
		|| mt >= MON_SKELSDA && mt <= MON_SKELSDD;
}

//----- (0043A760) --------------------------------------------------------
BOOL __fastcall IsGoat(int mt)
{
	return mt >= MON_GOATMACEA && mt <= MON_GOATMACED || mt >= MON_GOATBOWA && mt <= MON_GOATBOWD;
}

//----- (0043A77B) --------------------------------------------------------
int __fastcall M_SpawnSkel(int x, int y, int dir)
{
	CMonster *v3; // ebx
	CMonster *v4; // esi
	int v5; // edx
	int v6; // ecx
	int v7; // esi
	int v8; // edx
	int v9; // eax
	int v10; // esi
	int xa; // [esp+Ch] [ebp-10h]
	int ya; // [esp+10h] [ebp-Ch]
	int v14; // [esp+14h] [ebp-8h]
	int v15; // [esp+18h] [ebp-4h]
	int v16; // [esp+18h] [ebp-4h]

	ya = y;
	xa = x;
	if ( nummtypes <= 0 )
		return -1;
	v3 = Monsters;
	v15 = nummtypes;
	v4 = Monsters;
	do
	{
		if ( IsSkel((unsigned char)v4->mtype) )
			++v5;
		++v4;
		--v15;
	}
	while ( v15 );
	if ( !v5 )
		return -1;
	_LOBYTE(v6) = -120;
	v7 = 0;
	v14 = random(v6, v5);
	v16 = 0;
	if ( nummtypes > 0 )
	{
		do
		{
			if ( v16 > v14 )
				break;
			if ( IsSkel((unsigned char)v3->mtype) )
				++v16;
			++v7;
			++v3;
		}
		while ( v7 < v8 );
	}
	v9 = AddMonster(xa, ya, dir, v7 - 1, 1);
	v10 = v9;
	if ( v9 != -1 )
		M_StartSpStand(v9, dir);
	return v10;
}

//----- (0043A828) --------------------------------------------------------
void __fastcall ActivateSpawn(int i, int x, int y, int dir)
{
	int v4; // eax

	dMonster[0][y + 112 * x] = i + 1;
	v4 = i;
	monster[v4]._mx = x;
	monster[v4]._mfutx = x;
	monster[v4]._moldx = x;
	monster[v4]._my = y;
	monster[v4]._mfuty = y;
	monster[v4]._moldy = y;
	M_StartSpStand(i, dir);
}

//----- (0043A879) --------------------------------------------------------
int __fastcall SpawnSkeleton(int ii, int x, int y)
{
	int v3; // esi
	int v4; // ebx
	int v5; // ST04_4
	int v6; // ecx
	int v7; // edi
	int *v8; // esi
	int v9; // eax
	int v11; // eax
	int v12; // ecx
	int v13; // edx
	int v14; // esi
	int v15; // edi
	int v16; // ST04_4
	int v17[9]; // [esp+Ch] [ebp-34h]
	int i; // [esp+30h] [ebp-10h]
	int x2; // [esp+34h] [ebp-Ch]
	int v20; // [esp+38h] [ebp-8h]
	int *v21; // [esp+3Ch] [ebp-4h]
	int a3; // [esp+48h] [ebp+8h]
	int a3a; // [esp+48h] [ebp+8h]

	i = ii;
	v3 = x;
	x2 = x;
	if ( ii == -1 )
		return 0;
	v4 = y;
	if ( !PosOkMonst(-1, x, y) )
	{
		v20 = 0;
		v6 = y - 1;
		a3 = y - 1;
		if ( (unsigned char)(__OFSUB__(v4 - 1, v4 + 1) ^ 1) | (v4 - 1 == v4 + 1) )
		{
			v21 = v17;
			do
			{
				v7 = v3 - 1;
				if ( (unsigned char)(__OFSUB__(v3 - 1, v3 + 1) ^ 1) | (v3 - 1 == v3 + 1) )
				{
					v8 = v21;
					do
					{
						v9 = PosOkMonst(-1, v7, a3);
						v20 |= v9;
						*v8 = v9;
						v8 += 3;
						++v7;
					}
					while ( v7 <= x2 + 1 );
					v3 = x2;
				}
				++v21;
				++a3;
			}
			while ( a3 <= v4 + 1 );
			if ( v20 )
			{
				_LOBYTE(v6) = -119;
				v11 = random(v6, 15);
				v12 = 0;
				v13 = 0;
				a3a = v11 + 1;
				if ( v11 + 1 > 0 )
				{
					while ( 1 )
					{
						if ( v17[v13 + 2 * v12 + v12] )
							--a3a;
						if ( a3a <= 0 )
							break;
						if ( ++v12 == 3 )
						{
							v12 = 0;
							if ( ++v13 == 3 )
								v13 = 0;
						}
					}
				}
				v14 = v12 + v3 - 1;
				v15 = v13 + v4 - 1;
				v16 = GetDirection(v14, v15, x2, v4);
				ActivateSpawn(i, v14, v15, v16);
				return 1;
			}
		}
		return 0;
	}
	v5 = GetDirection(v3, y, v3, y);
	ActivateSpawn(i, v3, y, v5);
	return 1;
}
// 43A879: using guessed type int var_34[9];

//----- (0043A979) --------------------------------------------------------
int __cdecl PreSpawnSkeleton()
{
	CMonster *v0; // edi
	int v1; // ebp
	CMonster *v2; // esi
	int v3; // edx
	int v4; // ecx
	int v5; // eax
	int v6; // esi
	int v7; // ebp
	int v8; // edx
	int v9; // edx
	int v10; // eax
	int v11; // esi
	int i; // [esp+10h] [ebp-4h]

	if ( nummtypes <= 0 )
		return -1;
	v0 = Monsters;
	v1 = nummtypes;
	v2 = Monsters;
	do
	{
		if ( IsSkel((unsigned char)v2->mtype) )
			++v3;
		++v2;
		--v1;
	}
	while ( v1 );
	if ( !v3 )
		return -1;
	_LOBYTE(v4) = -120;
	v5 = random(v4, v3);
	v6 = nummtypes;
	v7 = 0;
	v8 = 0;
	for ( i = v5; v8 < v6; ++v0 )
	{
		if ( v7 > i )
			break;
		if ( IsSkel((unsigned char)v0->mtype) )
			++v7;
		v8 = v9 + 1;
	}
	v10 = AddMonster(0, 0, 0, v8 - 1, 0);
	v11 = v10;
	if ( v10 != -1 )
		M_StartStand(v10, 0);
	return v11;
}

//----- (0043AA0C) --------------------------------------------------------
void __fastcall TalktoMonster(int i)
{
	int v1; // esi
	MonsterStruct *v2; // esi
	char v3; // al
	int v4; // edi
	int v5; // eax
	int v6; // eax
	int inv_item_num; // [esp+8h] [ebp-4h]

	v1 = i;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("TalktoMonster: Invalid monster %d", i);
	v2 = &monster[v1];
	v3 = v2->_mAi;
	v4 = v2->_menemy;
	v2->_mmode = MM_TALK;
	if ( v3 == MG_SNOTSPIL || v3 == MG_LACHDANAN )
	{
		_LOBYTE(v5) = QuestStatus(7);
		if ( v5 && quests[7]._qvar1 == 2 && PlrHasItem(v4, IDI_BANNER, &inv_item_num) )
		{
			RemoveInvItem(v4, inv_item_num);
			quests[7]._qactive = 3;
			v2->mtalkmsg = TEXT_SNOT3;
			_LOBYTE(v2->_mgoal) = 6;
		}
		_LOBYTE(v6) = QuestStatus(4);
		if ( v6 && v2->mtalkmsg >= (signed int)TEXT_LACH1 )
		{
			if ( PlrHasItem(v4, IDI_GLDNELIX, &inv_item_num) )
			{
				RemoveInvItem(v4, inv_item_num);
				v2->mtalkmsg = TEXT_LACH3;
				_LOBYTE(v2->_mgoal) = 6;
			}
		}
	}
}

//----- (0043AADA) --------------------------------------------------------
void __fastcall SpawnGolum(int i, int x, int y, int mi)
{
	int v4; // edi
	int v5; // ebx
	int v6; // esi
	int v7; // eax
	int *v8; // edx
	int v9; // eax
	char v10; // cl
	int v11; // eax

	v4 = i;
	v5 = x;
	if ( (unsigned int)i >= 0xC8 )
		TermMsg("SpawnGolum: Invalid monster %d", i);
	v6 = v4;
	monster[v6]._mx = v5;
	monster[v6]._my = y;
	monster[v6]._mfuty = y;
	monster[v6]._moldy = y;
	monster[v6]._mfutx = v5;
	monster[v6]._moldx = v5;
	v7 = plr[v4]._pMaxMana;
	dMonster[0][y + 112 * v5] = v4 + 1;
	_LOBYTE(monster[v6]._pathcount) = 0;
	monster[v6]._mFlags |= 0x20u;
	v8 = &missile[mi]._mispllvl;
	monster[v6].mArmorClass = 25;
	v9 = 320 * *v8 + v7 / 3;
	v10 = *(_BYTE *)v8;
	_LOBYTE(v8) = plr[v4]._pLevel;
	v9 *= 2;
	monster[v6]._mmaxhp = v9;
	monster[v6]._mhitpoints = v9;
	monster[v6].mHit = 5 * (v10 + 8) + 2 * (_BYTE)v8;
	monster[v6].mMinDamage = 2 * (v10 + 4);
	monster[v6].mMaxDamage = 2 * (v10 + 8);
	M_StartSpStand(v4, 0);
	M_Enemy(v4);
	if ( v4 == myplr )
	{
		_LOBYTE(v11) = currlevel;
		NetSendCmdGolem(
			monster[v6]._mx,
			monster[v6]._my,
			monster[v6]._mdir,
			monster[v6]._menemy,
			monster[v6]._mhitpoints,
			v11);
	}
}

//----- (0043AC0C) --------------------------------------------------------
unsigned char __fastcall CanTalkToMonst(int m)
{
	int v1; // esi
	char v2; // al
	unsigned char result; // al

	v1 = m;
	if ( (unsigned int)m >= 0xC8 )
		TermMsg("CanTalkToMonst: Invalid monster %d", m);
	v2 = monster[v1]._mgoal;
	if ( v2 == 6 )
		result = 1;
	else
		result = v2 == 7;
	return result;
}

//----- (0043AC43) --------------------------------------------------------
unsigned char __fastcall CheckMonsterHit(int m, unsigned char *ret)
{
	int v2; // edi
	unsigned char *v3; // esi
	int v4; // ecx
	int v5; // eax
	unsigned char result; // al
	unsigned char v7; // al

	v2 = m;
	v3 = ret;
	if ( (unsigned int)m >= 0xC8 )
		TermMsg("CheckMonsterHit: Invalid monster %d", m);
	v4 = v2;
	if ( monster[v2]._mAi == MG_GARG && (v5 = monster[v4]._mFlags, v5 & 4) )
	{
		_LOBYTE(v5) = v5 & 0xFB;
		monster[v4]._mmode = MM_SATTACK;
		monster[v4]._mFlags = v5;
		result = 1;
		*(_DWORD *)v3 = 1;
	}
	else
	{
		v7 = monster[v4].MType->mtype;
		if ( v7 < MON_MAGEA || v7 > MON_MAGED || (result = 1, _LOBYTE(monster[v4]._mgoal) == 1) )
			result = 0;
		else
			*(_DWORD *)v3 = 0;
	}
	return result;
}

//----- (0043ACB5) --------------------------------------------------------
int __cdecl encode_enemy(int m)
{
	int v1; // ecx
	int v2; // ecx
	int result; // eax

	v2 = v1;
	result = monster[v2]._menemy;
	if ( monster[v2]._mFlags & 0x10 )
		result += 4;
	return result;
}

//----- (0043ACCE) --------------------------------------------------------
void __fastcall decode_enemy(int m, int enemy)
{
	int v2; // eax
	int v3; // edx
	char v4; // cl
	int v5; // edx

	v2 = m;
	if ( enemy >= 4 )
	{
		monster[v2]._mFlags |= 0x10u;
		v5 = enemy - 4;
		monster[v2]._menemy = v5;
		monster[v2]._menemyx = monster[v5]._mfutx;
		v4 = monster[v5]._mfuty;
	}
	else
	{
		monster[v2]._mFlags &= 0xFFFFFFEF;
		monster[v2]._menemy = enemy;
		v3 = enemy;
		monster[v2]._menemyx = plr[v3]._px;
		v4 = plr[v3]._py;
	}
	monster[v2]._menemyy = v4;
}

//----- (0043AD38) --------------------------------------------------------
void __cdecl movie_cpp_init()
{
	movie_cpp_init_value = movie_inf;
}
// 47F144: using guessed type int movie_inf;
// 659AF4: using guessed type int movie_cpp_init_value;

//----- (0043AD43) --------------------------------------------------------
void __fastcall play_movie(char *pszMovie, bool user_can_close)
{
	char *v2; // esi
	LRESULT (__stdcall *v3)(HWND, UINT, WPARAM, LPARAM); // edi
	int v4; // eax
	MSG Msg; // [esp+8h] [ebp-24h]
	BOOL v6; // [esp+24h] [ebp-8h]
	void *video_stream; // [esp+28h] [ebp-4h]

	v6 = user_can_close;
	v2 = pszMovie;
	if ( window_activated )
	{
		v3 = SetWindowProc(MovieWndProc);
		InvalidateRect(ghMainWnd, 0, 0);
		UpdateWindow(ghMainWnd);
		_LOBYTE(movie_playing) = 1;
		sound_disable_music(1);
		sfx_stop();
		effects_play_sound("Sfx\\Misc\\blank.wav");
		SVidPlayBegin(v2, 0, 0, 0, 0, loop_movie != 0 ? 0x100C0808 : 0x10280808, &video_stream);
		if ( video_stream )
		{
			do
			{
				if ( !window_activated || v6 && !(_BYTE)movie_playing )
					break;
				while ( PeekMessageA(&Msg, 0, 0, 0, 1u) )
				{
					if ( Msg.message != WM_QUIT )
					{
						TranslateMessage(&Msg);
						DispatchMessageA(&Msg);
					}
				}
				_LOBYTE(v4) = SVidPlayContinue();
				if ( !v4 )
					break;
			}
			while ( video_stream );
			if ( video_stream )
				SVidPlayEnd(video_stream);
		}
		SetWindowProc(v3);
		sound_disable_music(0);
	}
}
// 634980: using guessed type int window_activated;
// 659AF8: using guessed type int movie_playing;
// 659AFC: using guessed type int loop_movie;

//----- (0043AE3E) --------------------------------------------------------
LRESULT __stdcall MovieWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	if ( Msg == WM_KEYFIRST || Msg == WM_CHAR )
	{
LABEL_6:
		_LOBYTE(movie_playing) = 0;
		return init_palette(hWnd, Msg, wParam, lParam);
	}
	if ( Msg != WM_SYSCOMMAND )
	{
		if ( Msg != WM_LBUTTONDOWN && Msg != WM_RBUTTONDOWN )
			return init_palette(hWnd, Msg, wParam, lParam);
		goto LABEL_6;
	}
	if ( wParam != SC_CLOSE )
		return init_palette(hWnd, Msg, wParam, lParam);
	_LOBYTE(movie_playing) = 0;
	return 0;
}
// 659AF8: using guessed type int movie_playing;

//----- (0043AE95) --------------------------------------------------------
void __cdecl mpqapi_cpp_init()
{
	mpqapi_cpp_init_value = mpqapi_inf;
}
// 47F148: using guessed type int mpqapi_inf;
// 659B00: using guessed type int mpqapi_cpp_init_value;

//----- (0043AEA0) --------------------------------------------------------
bool __fastcall mpqapi_set_hidden(char *save_path, bool hidden)
{
	char *v2; // edi
	BOOL v3; // esi
	DWORD v4; // eax
	bool result; // al
	DWORD v6; // esi

	v2 = save_path;
	v3 = hidden;
	v4 = GetFileAttributesA(save_path);
	if ( v4 == -1 )
		return GetLastError() == ERROR_FILE_NOT_FOUND;
	v6 = v3 != 0 ? 6 : 0;
	if ( v4 == v6 )
		result = 1;
	else
		result = SetFileAttributesA(v2, v6);
	return result;
}

//----- (0043AEDC) --------------------------------------------------------
void __fastcall mpqapi_store_creation_time(char *save_path, int save_num)
{
	int v2; // esi
	char *v3; // ebx
	HANDLE v4; // eax
	int v5; // esi
	struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h]
	char dst[160]; // [esp+148h] [ebp-A0h]

	v2 = save_num;
	v3 = save_path;
	if ( gbMaxPlayers != 1 )
	{
		mpqapi_reg_load_modification_time(dst, 160);
		v4 = FindFirstFileA(v3, &FindFileData);
		if ( v4 != (HANDLE)-1 )
		{
			FindClose(v4);
			v5 = 16 * v2;
			*(_DWORD *)&dst[v5] = FindFileData.ftCreationTime.dwLowDateTime;
			*(_DWORD *)&dst[v5 + 4] = FindFileData.ftCreationTime.dwHighDateTime;
			mpqapi_reg_store_modification_time(dst, 160);
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0043AF4F) --------------------------------------------------------
bool __fastcall mpqapi_reg_load_modification_time(char *dst, int size)
{
	unsigned int v2; // esi
	char *v3; // edi
	int v4; // eax
	unsigned int v6; // esi
	char *v7; // ecx
	int nbytes_read; // [esp+8h] [ebp-4h]

	v2 = size;
	v3 = dst;
	memset(dst, 0, size);
	_LOBYTE(v4) = SRegLoadData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2, (unsigned long *)&nbytes_read);
	if ( !v4 || nbytes_read != v2 )
		return 0;
	if ( v2 >= 8 )
	{
		v6 = v2 >> 3;
		do
		{
			v7 = v3;
			v3 += 8;
			mpqapi_xor_buf(v7);
			--v6;
		}
		while ( v6 );
	}
	return 1;
}

//----- (0043AFA5) --------------------------------------------------------
void __fastcall mpqapi_xor_buf(char *buf)
{
	signed int v1; // eax
	char *v2; // esi
	signed int v3; // edi

	v1 = 0xF0761AB;
	v2 = buf;
	v3 = 8;
	do
	{
		*v2 ^= v1;
		++v2;
		v1 = _rotl(v1, 1);
		--v3;
	}
	while ( v3 );
}

//----- (0043AFC4) --------------------------------------------------------
bool __fastcall mpqapi_reg_store_modification_time(char *src, int len)
{
	int v2; // ebx
	char *v3; // ebp
	char *v4; // edi
	unsigned int v5; // esi
	char *v6; // ecx

	v2 = len;
	v3 = src;
	v4 = src;
	if ( (unsigned int)len >= 8 )
	{
		v5 = (unsigned int)len >> 3;
		do
		{
			v6 = v4;
			v4 += 8;
			mpqapi_xor_buf(v6);
			--v5;
		}
		while ( v5 );
	}
	return SRegSaveData("Diablo", "Video Player ", 0, (unsigned char *)v3, v2);
}

//----- (0043B002) --------------------------------------------------------
void __fastcall mpqapi_remove_hash_entry(char *path)
{
	int v1; // eax
	_BLOCKENTRY *v2; // ecx
	_BLOCKENTRY *v3; // eax
	int v4; // esi
	int v5; // edi

	v1 = mpqapi_get_hash_index_of_path(path);
	if ( v1 != -1 )
	{
		v2 = &sgpHashTbl[v1];
		v3 = &sgpBlockTbl[v2->flags];
		v2->flags = -2;
		v4 = v3->offset;
		v5 = v3->sizealloc;
		memset(v3, 0, 0x10u);
		mpqapi_alloc_block(v4, v5);
		dword_65AB0C = 1;
	}
}
// 65AB0C: using guessed type int dword_65AB0C;

//----- (0043B054) --------------------------------------------------------
void __fastcall mpqapi_alloc_block(int block_offset, int block_size)
{
	int v2; // esi
	int v3; // edi
	_BLOCKENTRY *v4; // eax
	signed int v5; // edx
	signed int v6; // ecx
	int v7; // ecx
	bool v8; // zf
	_BLOCKENTRY *v9; // eax

	v2 = block_size;
	v3 = block_offset;
LABEL_2:
	v4 = sgpBlockTbl;
	v5 = 2048;
	while ( 1 )
	{
		v6 = v5--;
		if ( !v6 )
			break;
		v7 = v4->offset;
		if ( v4->offset && !v4->flags && !v4->sizefile )
		{
			if ( v7 + v4->sizealloc == v3 )
			{
				v3 = v4->offset;
LABEL_11:
				v2 += v4->sizealloc;
				memset(v4, 0, 0x10u);
				goto LABEL_2;
			}
			if ( v3 + v2 == v7 )
				goto LABEL_11;
		}
		++v4;
	}
	v8 = v3 + v2 == lDistanceToMove;
	if ( v3 + v2 > (unsigned int)lDistanceToMove )
	{
		TermMsg("MPQ free list error");
		v8 = v3 + v2 == lDistanceToMove;
	}
	if ( v8 )
	{
		lDistanceToMove = v3;
	}
	else
	{
		v9 = mpqapi_new_block(0);
		v9->offset = v3;
		v9->sizealloc = v2;
		v9->sizefile = 0;
		v9->flags = 0;
	}
}

//----- (0043B0E4) --------------------------------------------------------
_BLOCKENTRY *__fastcall mpqapi_new_block(int *block_index)
{
	_BLOCKENTRY *result; // eax
	unsigned int v2; // edx

	result = sgpBlockTbl;
	v2 = 0;
	while ( result->offset || result->sizealloc || result->flags || result->sizefile )
	{
		++v2;
		++result;
		if ( v2 >= 0x800 )
		{
			TermMsg("Out of free block entries");
			return 0;
		}
	}
	if ( block_index )
		*block_index = v2;
	return result;
}

//----- (0043B123) --------------------------------------------------------
int __fastcall mpqapi_get_hash_index_of_path(char *path)
{
	char *v1; // esi
	int v2; // ST00_4
	int v3; // edi
	short v4; // ax

	v1 = path;
	v2 = encrypt_hash(path, 2);
	v3 = encrypt_hash(v1, 1);
	v4 = encrypt_hash(v1, 0);
	return mpqapi_get_hash_index(v4, v3, v2, 0);
}

//----- (0043B153) --------------------------------------------------------
int __fastcall mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale)
{
	int v4; // ecx
	signed int v5; // eax
	signed int v6; // edx
	_BLOCKENTRY *v7; // ecx
	int v8; // edi
	int v10; // [esp+Ch] [ebp-8h]
	int i; // [esp+10h] [ebp-4h]

	v4 = index & 0x7FF;
	v10 = hash_a;
	v5 = 2048;
	for ( i = v4; ; i = (i + 1) & 0x7FF )
	{
		v7 = &sgpHashTbl[v4];
		v8 = v7->flags;
		if ( v8 == -1 )
			return -1;
		v6 = v5--;
		if ( !v6 )
			return -1;
		if ( v7->offset == v10 && v7->sizealloc == hash_b && v7->sizefile == locale && v8 != -2 )
			break;
		v4 = (i + 1) & 0x7FF;
	}
	return i;
}

//----- (0043B1BD) --------------------------------------------------------
void __fastcall mpqapi_remove_hash_entries(bool (__stdcall *get_file_name)(int lvl, char *file_name))
{
	bool (__stdcall *v1)(int, char *); // edi
	signed int v2; // esi
	int i; // eax
	int v4; // eax
	char v5[260]; // [esp+8h] [ebp-104h]

	v1 = get_file_name;
	v2 = 1;
	for ( i = get_file_name(0, v5); i; i = v1(v4, v5) )
	{
		mpqapi_remove_hash_entry(v5);
		v4 = v2++;
	}
}

//----- (0043B1F8) --------------------------------------------------------
bool __fastcall mpqapi_write_file(char *file_name, char *buf, int len)
{
	char *v3; // edi
	char *v4; // esi
	_BLOCKENTRY *v5; // eax
	int v6; // eax

	v3 = buf;
	v4 = file_name;
	dword_65AB0C = 1;
	mpqapi_remove_hash_entry(file_name);
	v5 = mpqapi_add_file(v4, 0, 0);
	_LOBYTE(v6) = mpqapi_write_file_contents(v4, v3, len, v5);
	if ( v6 )
		return 1;
	mpqapi_remove_hash_entry(v4);
	return 0;
}
// 65AB0C: using guessed type int dword_65AB0C;

//----- (0043B23D) --------------------------------------------------------
_BLOCKENTRY *__fastcall mpqapi_add_file(char *path, _BLOCKENTRY *block, int block_index)
{
	char *v3; // edi
	short v4; // si
	int v5; // ebx
	signed int v6; // edx
	int v7; // esi
	int v8; // ecx
	int v9; // esi
	int v11; // [esp+Ch] [ebp-8h]
	_BLOCKENTRY *v12; // [esp+10h] [ebp-4h]

	v12 = block;
	v3 = path;
	v4 = encrypt_hash(path, 0);
	v5 = encrypt_hash(v3, 1);
	v11 = encrypt_hash(v3, 2);
	if ( mpqapi_get_hash_index(v4, v5, v11, 0) != -1 )
		TermMsg("Hash collision between \"%s\" and existing file\n", v3);
	v6 = 2048;
	v7 = v4 & 0x7FF;
	while ( 1 )
	{
		--v6;
		v8 = sgpHashTbl[v7].flags;
		if ( v8 == -1 || v8 == -2 )
			break;
		v7 = (v7 + 1) & 0x7FF;
		if ( !v6 )
		{
			v6 = -1;
			break;
		}
	}
	if ( v6 < 0 )
		TermMsg("Out of hash space");
	if ( !v12 )
		v12 = mpqapi_new_block(&block_index);
	v9 = v7;
	sgpHashTbl[v9].offset = v5;
	sgpHashTbl[v9].sizealloc = v11;
	sgpHashTbl[v9].sizefile = 0;
	sgpHashTbl[v9].flags = block_index;
	return v12;
}

//----- (0043B317) --------------------------------------------------------
bool __fastcall mpqapi_write_file_contents(char *path, char *buf, int len, _BLOCKENTRY *block)
{
	char *v4; // esi
	char *v5; // eax
	unsigned int v6; // ebx
	char *v7; // eax
	unsigned int v8; // esi
	_BLOCKENTRY *v9; // edi
	int v10; // eax
	signed int v11; // eax
	unsigned int v13; // eax
	unsigned int v14; // eax
	int v15; // ecx
	int size; // [esp+Ch] [ebp-10h]
	char *v17; // [esp+10h] [ebp-Ch]
	int v18; // [esp+14h] [ebp-8h]
	DWORD nNumberOfBytesToWrite; // [esp+18h] [ebp-4h]

	v4 = path;
	v17 = buf;
	v5 = strchr(path, 58);
	v6 = 0;
	while ( v5 )
	{
		v4 = v5 + 1;
		v5 = strchr(v5 + 1, 58);
	}
	while ( 1 )
	{
		v7 = strchr(v4, 92);
		if ( !v7 )
			break;
		v4 = v7 + 1;
	}
	encrypt_hash(v4, 3);
	v8 = len;
	v9 = block;
	size = 4 * ((unsigned int)(len + 4095) >> 12) + 4;
	nNumberOfBytesToWrite = 4 * ((unsigned int)(len + 4095) >> 12) + 4;
	v10 = mpqapi_find_free_block(size + len, &block->sizealloc);
	v9->offset = v10;
	v9->sizefile = v8;
	v9->flags = 0x80000100;
	if ( SetFilePointer(sghArchive, v10, 0, 0) == -1 )
		return 0;
	block = 0;
	v18 = 0;
	while ( v8 )
	{
		v11 = 0;
		do
			*((_BYTE *)mpq_buf + v11++) -= 86;
		while ( v11 < 4096 );
		len = v8;
		if ( v8 >= 0x1000 )
			len = 4096;
		memcpy(mpq_buf, v17, len);
		v17 += len;
		len = encrypt_compress(mpq_buf, len);
		if ( !v18 )
		{
			nNumberOfBytesToWrite = size;
			block = (_BLOCKENTRY *)DiabloAllocPtr(size);
			memset(block, 0, nNumberOfBytesToWrite);
			if ( !WriteFile(sghArchive, block, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0) )
				goto LABEL_25;
			v6 += nNumberOfBytesToWrite;
		}
		*(&block->offset + v18) = v6;
		if ( !WriteFile(sghArchive, mpq_buf, len, (LPDWORD)&len, 0) )
			goto LABEL_25;
		++v18;
		if ( v8 <= 0x1000 )
			v8 = 0;
		else
			v8 -= 4096;
		v6 += len;
	}
	*(&block->offset + v18) = v6;
	if ( SetFilePointer(sghArchive, -v6, 0, 1u) == -1
	  || !WriteFile(sghArchive, block, nNumberOfBytesToWrite, &nNumberOfBytesToWrite, 0)
	  || SetFilePointer(sghArchive, v6 - nNumberOfBytesToWrite, 0, 1u) == -1 )
	{
LABEL_25:
		if ( block )
			mem_free_dbg(block);
		return 0;
	}
	mem_free_dbg(block);
	v13 = v9->sizealloc;
	if ( v6 < v13 )
	{
		v14 = v13 - v6;
		if ( v14 >= 0x400 )
		{
			v15 = v6 + v9->offset;
			v9->sizealloc = v6;
			mpqapi_alloc_block(v15, v14);
		}
	}
	return 1;
}

//----- (0043B51C) --------------------------------------------------------
int __fastcall mpqapi_find_free_block(int size, int *block_size)
{
	_BLOCKENTRY *v2; // eax
	signed int v3; // esi
	int result; // eax
	int v5; // esi
	bool v6; // zf

	v2 = sgpBlockTbl;
	v3 = 2048;
	while ( 1 )
	{
		--v3;
		if ( v2->offset )
		{
			if ( !v2->flags && !v2->sizefile && v2->sizealloc >= (unsigned int)size )
				break;
		}
		++v2;
		if ( !v3 )
		{
			*block_size = size;
			result = lDistanceToMove;
			lDistanceToMove += size;
			return result;
		}
	}
	v5 = v2->offset;
	*block_size = size;
	v2->offset += size;
	v6 = v2->sizealloc == size;
	v2->sizealloc -= size;
	if ( v6 )
		memset(v2, 0, 0x10u);
	return v5;
}

//----- (0043B570) --------------------------------------------------------
void __fastcall mpqapi_rename(char *old_name, char *new_name)
{
	char *v2; // esi
	int v3; // eax
	_BLOCKENTRY *v4; // eax
	int v5; // ST00_4
	_BLOCKENTRY *v6; // edx

	v2 = new_name;
	v3 = mpqapi_get_hash_index_of_path(old_name);
	if ( v3 != -1 )
	{
		v4 = &sgpHashTbl[v3];
		v5 = v4->flags;
		v6 = &sgpBlockTbl[v5];
		v4->flags = -2;
		mpqapi_add_file(v2, v6, v5);
		dword_65AB0C = 1;
	}
}
// 65AB0C: using guessed type int dword_65AB0C;

//----- (0043B5AF) --------------------------------------------------------
bool __fastcall mpqapi_has_file(char *path)
{
	return mpqapi_get_hash_index_of_path(path) != -1;
}

//----- (0043B5BF) --------------------------------------------------------
bool __fastcall mpqapi_open_archive(char *save_path, bool hidden, int save_num)
{
	char *v3; // ebp
	BOOL v4; // esi
	int v5; // eax
	DWORD v6; // edi
	int v7; // eax
	int v8; // eax
	int v10; // eax
	char *lpFileName; // [esp+10h] [ebp-70h]
	DWORD NumberOfBytesRead; // [esp+14h] [ebp-6Ch]
	_DWORD v13[26]; // [esp+18h] [ebp-68h]

	v3 = save_path;
	v4 = hidden;
	lpFileName = save_path;
	encrypt_init_lookup_table();
	_LOBYTE(v5) = mpqapi_set_hidden(v3, v4);
	if ( !v5 )
		return 0;
	v6 = (unsigned char)gbMaxPlayers > 1u ? 0x80000000 : 0;
	byte_65AB14 = 0;
	sghArchive = CreateFileA(v3, 0xC0000000, 0, 0, 3u, v6, 0);
	if ( sghArchive == (HANDLE)-1 )
	{
		sghArchive = CreateFileA(lpFileName, 0xC0000000, 0, 0, 2u, v6 | (v4 != 0 ? 6 : 0), 0);
		if ( sghArchive == (HANDLE)-1 )
			return 0;
		byte_65AB14 = 1;
		dword_65AB0C = 1;
	}
	if ( !sgpBlockTbl || !sgpHashTbl )
	{
		memset(v13, 0, 0x68u);
		_LOBYTE(v7) = mpqapi_parse_archive_header((TMPQHeader *)v13, (int *)&lDistanceToMove);
		if ( !v7 )
		{
LABEL_15:
			mpqapi_close_archive(lpFileName, 1, save_num);
			return 0;
		}
		sgpBlockTbl = (_BLOCKENTRY *)DiabloAllocPtr(0x8000);
		memset(sgpBlockTbl, 0, 0x8000u);
		if ( v13[7] )
		{
			if ( SetFilePointer(sghArchive, 104, 0, 0) == -1
			  || !ReadFile(sghArchive, sgpBlockTbl, 0x8000u, &NumberOfBytesRead, 0) )
			{
				goto LABEL_15;
			}
			v8 = encrypt_hash("(block table)", 3);
			encrypt_decrypt_block(sgpBlockTbl, 0x8000, v8);
		}
		sgpHashTbl = (_BLOCKENTRY *)DiabloAllocPtr(0x8000);
		memset(sgpHashTbl, 255, 0x8000u);
		if ( v13[6] )
		{
			if ( SetFilePointer(sghArchive, 32872, 0, 0) == -1
			  || !ReadFile(sghArchive, sgpHashTbl, 0x8000u, &NumberOfBytesRead, 0) )
			{
				goto LABEL_15;
			}
			v10 = encrypt_hash("(hash table)", 3);
			encrypt_decrypt_block(sgpHashTbl, 0x8000, v10);
		}
	}
	return 1;
}
// 65AB0C: using guessed type int dword_65AB0C;
// 65AB14: using guessed type char byte_65AB14;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043B791) --------------------------------------------------------
bool __fastcall mpqapi_parse_archive_header(TMPQHeader *header, int *mpq_offset)
{
	int *v2; // ebp
	TMPQHeader *v3; // esi
	DWORD v4; // eax
	DWORD v5; // edi
	DWORD NumberOfBytesRead; // [esp+10h] [ebp-4h]

	v2 = mpq_offset;
	v3 = header;
	v4 = GetFileSize(sghArchive, 0);
	v5 = v4;
	*v2 = v4;
	if ( v4 == -1
	  || v4 < 0x68
	  || !ReadFile(sghArchive, v3, 0x68u, &NumberOfBytesRead, 0)
	  || NumberOfBytesRead != 104
	  || v3->dwID != '\x1AQPM'
	  || v3->dwHeaderSize != 32
	  || v3->wFormatVersion > 0u
	  || v3->wSectorSize != 3
	  || v3->dwArchiveSize != v5
	  || v3->dwHashTablePos != 32872
	  || v3->dwBlockTablePos != 104
	  || v3->dwHashTableSize != 2048
	  || v3->dwBlockTableSize != 2048 )
	{
		if ( SetFilePointer(sghArchive, 0, 0, 0) == -1 || !SetEndOfFile(sghArchive) )
			return 0;
		memset(v3, 0, 0x68u);
		v3->dwID = '\x1AQPM';
		v3->dwHeaderSize = 32;
		v3->wSectorSize = 3;
		v3->wFormatVersion = 0;
		*v2 = 0x10068;
		dword_65AB0C = 1;
		byte_65AB14 = 1;
	}
	return 1;
}
// 65AB0C: using guessed type int dword_65AB0C;
// 65AB14: using guessed type char byte_65AB14;

//----- (0043B882) --------------------------------------------------------
void __fastcall mpqapi_close_archive(char *save_path, bool free_tables, int save_num)
{
	char *v3; // esi
	_BLOCKENTRY *v4; // ecx
	_BLOCKENTRY *v5; // ecx

	v3 = save_path;
	if ( free_tables )
	{
		v4 = sgpBlockTbl;
		sgpBlockTbl = 0;
		mem_free_dbg(v4);
		v5 = sgpHashTbl;
		sgpHashTbl = 0;
		mem_free_dbg(v5);
	}
	if ( sghArchive != (HANDLE)-1 )
	{
		CloseHandle(sghArchive);
		sghArchive = (HANDLE)-1;
	}
	if ( dword_65AB0C )
	{
		dword_65AB0C = 0;
		mpqapi_store_modified_time(v3, save_num);
	}
	if ( byte_65AB14 )
	{
		byte_65AB14 = 0;
		mpqapi_store_creation_time(v3, save_num);
	}
}
// 65AB0C: using guessed type int dword_65AB0C;
// 65AB14: using guessed type char byte_65AB14;

//----- (0043B8FD) --------------------------------------------------------
void __fastcall mpqapi_store_modified_time(char *save_path, int save_num)
{
	int v2; // esi
	char *v3; // ebx
	HANDLE v4; // eax
	int v5; // esi
	struct _WIN32_FIND_DATAA FindFileData; // [esp+8h] [ebp-1E0h]
	char dst[160]; // [esp+148h] [ebp-A0h]

	v2 = save_num;
	v3 = save_path;
	if ( gbMaxPlayers != 1 )
	{
		mpqapi_reg_load_modification_time(dst, 160);
		v4 = FindFirstFileA(v3, &FindFileData);
		if ( v4 != (HANDLE)-1 )
		{
			FindClose(v4);
			v5 = 16 * v2;
			*(_DWORD *)&dst[v5 + 8] = FindFileData.ftLastWriteTime.dwLowDateTime;
			*(_DWORD *)&dst[v5 + 12] = FindFileData.ftLastWriteTime.dwHighDateTime;
			mpqapi_reg_store_modification_time(dst, 160);
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0043B970) --------------------------------------------------------
void __fastcall mpqapi_flush_and_close(char *save_path, bool is_single_player, int save_num)
{
	bool v3; // di
	char *v4; // ebx
	int v5; // eax
	int v6; // eax
	int v7; // eax

	v3 = is_single_player;
	v4 = save_path;
	if ( sghArchive != (HANDLE)-1 )
	{
		if ( dword_65AB0C )
		{
			_LOBYTE(v5) = mpqapi_can_seek();
			if ( v5 )
			{
				_LOBYTE(v6) = mpqapi_write_header();
				if ( v6 )
				{
					_LOBYTE(v7) = mpqapi_write_block_table();
					if ( v7 )
						mpqapi_write_hash_table();
				}
			}
		}
	}
	mpqapi_close_archive(v4, v3, save_num);
}
// 65AB0C: using guessed type int dword_65AB0C;

//----- (0043B9CA) --------------------------------------------------------
bool __cdecl mpqapi_write_header()
{
	bool result; // al
	TMPQHeader Buffer; // [esp+8h] [ebp-6Ch]
	DWORD NumberOfBytesWritten; // [esp+70h] [ebp-4h]

	memset(&Buffer, 0, 0x68u);
	Buffer.dwID = '\x1AQPM';
	Buffer.dwHeaderSize = 32;
	Buffer.dwArchiveSize = GetFileSize(sghArchive, 0);
	Buffer.wFormatVersion = 0;
	Buffer.wSectorSize = 3;
	Buffer.dwHashTablePos = 32872;
	Buffer.dwBlockTablePos = 104;
	Buffer.dwHashTableSize = 2048;
	Buffer.dwBlockTableSize = 2048;
	if ( SetFilePointer(sghArchive, 0, 0, 0) != -1 && WriteFile(sghArchive, &Buffer, 0x68u, &NumberOfBytesWritten, 0) )
		result = NumberOfBytesWritten == 104;
	else
		result = 0;
	return result;
}

//----- (0043BA60) --------------------------------------------------------
bool __cdecl mpqapi_write_block_table()
{
	int v1; // eax
	BOOL v2; // ebx
	int v3; // eax
	DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h]

	if ( SetFilePointer(sghArchive, 104, 0, 0) == -1 )
		return 0;
	v1 = encrypt_hash("(block table)", 3);
	encrypt_encrypt_block(sgpBlockTbl, 0x8000, v1);
	v2 = WriteFile(sghArchive, sgpBlockTbl, 0x8000u, &NumberOfBytesWritten, 0);
	v3 = encrypt_hash("(block table)", 3);
	encrypt_decrypt_block(sgpBlockTbl, 0x8000, v3);
	return v2 && NumberOfBytesWritten == 0x8000;
}

//----- (0043BAEB) --------------------------------------------------------
bool __cdecl mpqapi_write_hash_table()
{
	int v1; // eax
	BOOL v2; // ebx
	int v3; // eax
	DWORD NumberOfBytesWritten; // [esp+4h] [ebp-4h]

	if ( SetFilePointer(sghArchive, 32872, 0, 0) == -1 )
		return 0;
	v1 = encrypt_hash("(hash table)", 3);
	encrypt_encrypt_block(sgpHashTbl, 0x8000, v1);
	v2 = WriteFile(sghArchive, sgpHashTbl, 0x8000u, &NumberOfBytesWritten, 0);
	v3 = encrypt_hash("(hash table)", 3);
	encrypt_decrypt_block(sgpHashTbl, 0x8000, v3);
	return v2 && NumberOfBytesWritten == 0x8000;
}

//----- (0043BB79) --------------------------------------------------------
bool __cdecl mpqapi_can_seek()
{
	bool result; // al

	if ( SetFilePointer(sghArchive, lDistanceToMove, 0, 0) == -1 )
		result = 0;
	else
		result = SetEndOfFile(sghArchive);
	return result;
}

//----- (0043BBA9) --------------------------------------------------------
void __cdecl msg_cpp_init()
{
	msg_cpp_init_value = msg_inf;
}
// 47F14C: using guessed type int msg_inf;
// 65AB1C: using guessed type int msg_cpp_init_value;

//----- (0043BBB4) --------------------------------------------------------
void __fastcall msg_send_drop_pkt(int pnum, int reason)
{
	_cmd_id packet; // [esp+0h] [ebp-8h]
	char v3; // [esp+1h] [ebp-7h]
	int v4; // [esp+2h] [ebp-6h]

	v4 = reason;
	packet = FAKE_CMD_DROPID;
	v3 = pnum;
	msg_send_packet(pnum, &packet, 6);
}

//----- (0043BBCF) --------------------------------------------------------
void __fastcall msg_send_packet(int pnum, void *packet, int dwSize)
{
	void *v3; // edi
	TMegaPkt *v4; // eax
	_cmd_id packeta; // [esp+Ah] [ebp-2h]
	char v6; // [esp+Bh] [ebp-1h]

	v3 = packet;
	if ( pnum != sgnCurrMegaPlayer )
	{
		sgnCurrMegaPlayer = pnum;
		packeta = FAKE_CMD_SETID;
		v6 = pnum;
		msg_send_packet(pnum, &packeta, 2);
	}
	v4 = sgpCurrPkt;
	if ( sgpCurrPkt->dwSpaceLeft < (unsigned int)dwSize )
	{
		msg_get_next_packet();
		v4 = sgpCurrPkt;
	}
	memcpy((char *)&v4[1] - v4->dwSpaceLeft, v3, dwSize);
	sgpCurrPkt->dwSpaceLeft -= dwSize;
}
// 65AB24: using guessed type int sgnCurrMegaPlayer;

//----- (0043BC31) --------------------------------------------------------
TMegaPkt *__cdecl msg_get_next_packet()
{
	TMegaPkt *v0; // eax
	TMegaPkt *v1; // ecx
	TMegaPkt *result; // eax

	v0 = (TMegaPkt *)DiabloAllocPtr(32008);
	sgpCurrPkt = v0;
	v0->pNext = 0;
	sgpCurrPkt->dwSpaceLeft = 32000;
	v1 = sgpMegaPkt;
	result = (TMegaPkt *)&sgpMegaPkt;
	while ( v1 )
	{
		result = v1;
		v1 = v1->pNext;
	}
	result->pNext = sgpCurrPkt;
	return result;
}

//----- (0043BC6D) --------------------------------------------------------
int __cdecl msg_wait_resync()
{
	int v0; // eax

	msg_get_next_packet();
	sgbDeltaChunks = 0;
	sgnCurrMegaPlayer = -1;
	sgbRecvCmd = CMD_DLEVEL_END;
	gbBufferMsgs = 1;
	sgdwOwnerWait = GetTickCount();
	v0 = UiProgressDialog(ghMainWnd, "Waiting for game data...", 1, msg_wait_for_turns, 20);
	gbBufferMsgs = 0;
	if ( !v0 )
		goto LABEL_6;
	if ( gbGameDestroyed )
	{
		DrawDlg("The game ended");
LABEL_6:
		msg_free_packets();
		return 0;
	}
	if ( sgbDeltaChunks != 21 )
	{
		DrawDlg("Unable to get level data");
		goto LABEL_6;
	}
	return 1;
}
// 65AB18: using guessed type int sgdwOwnerWait;
// 65AB24: using guessed type int sgnCurrMegaPlayer;
// 67618D: using guessed type char sgbDeltaChunks;
// 676194: using guessed type char gbBufferMsgs;
// 67862D: using guessed type char gbGameDestroyed;

//----- (0043BCED) --------------------------------------------------------
void __cdecl msg_free_packets()
{
	TMegaPkt *v0; // eax
	TMegaPkt *v1; // ecx

	v0 = sgpMegaPkt;
	while ( v0 )
	{
		v1 = v0->pNext;
		sgpMegaPkt = 0;
		sgpCurrPkt = v1;
		mem_free_dbg(v0);
		v0 = sgpCurrPkt;
		sgpMegaPkt = sgpCurrPkt;
	}
}

//----- (0043BD19) --------------------------------------------------------
int __cdecl msg_wait_for_turns()
{
	int v0; // eax
	int v2; // eax
	bool recieved; // [esp+0h] [ebp-8h]
	int turns; // [esp+4h] [ebp-4h]

	if ( !sgbDeltaChunks )
	{
		nthread_send_and_recv_turn(0, 0);
		_LOBYTE(v0) = SNetGetOwnerTurnsWaiting(&turns);
		if ( !v0 && SErrGetLastError() == 0x85100070 )
			return 100;
		if ( GetTickCount() - sgdwOwnerWait <= 0x7D0 && turns < (unsigned int)gdwTurnsInTransit )
			return 0;
		++sgbDeltaChunks;
	}
	multi_process_network_packets();
	nthread_send_and_recv_turn(0, 0);
	_LOBYTE(v2) = nthread_has_500ms_passed();
	if ( v2 )
		nthread_recv_turns(&recieved);
	if ( gbGameDestroyed )
		return 100;
	if ( (unsigned char)gbDeltaSender >= 4u )
	{
		sgbDeltaChunks = 0;
		sgbRecvCmd = CMD_DLEVEL_END;
		gbDeltaSender = myplr;
		nthread_set_turn_upper_bit();
	}
	if ( sgbDeltaChunks == 20 )
	{
		sgbDeltaChunks = 21;
		return 99;
	}
	return 100 * (unsigned char)sgbDeltaChunks / 21;
}
// 65AB18: using guessed type int sgdwOwnerWait;
// 67618D: using guessed type char sgbDeltaChunks;
// 67862D: using guessed type char gbGameDestroyed;
// 6796E4: using guessed type char gbDeltaSender;
// 679738: using guessed type int gdwTurnsInTransit;

//----- (0043BDEB) --------------------------------------------------------
void __cdecl msg_process_net_packets()
{
	if ( gbMaxPlayers != 1 )
	{
		gbBufferMsgs = 2;
		msg_pre_packet();
		gbBufferMsgs = 0;
		msg_free_packets();
	}
}
// 676194: using guessed type char gbBufferMsgs;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043BE0D) --------------------------------------------------------
void __cdecl msg_pre_packet()
{
	TMegaPkt *v0; // edi
	int i; // ebp
	signed int v2; // ebx
	TFakeCmdPlr *v3; // esi
	TFakeCmdPlr *v4; // eax
	TFakeDropPlr *v5; // eax
	int v6; // eax

	v0 = sgpMegaPkt;
	for ( i = -1; v0; v0 = v0->pNext )
	{
		v2 = 32000;
		v3 = (TFakeCmdPlr *)v0->data;
		while ( v2 != v0->dwSpaceLeft )
		{
			if ( v3->bCmd == FAKE_CMD_SETID )
			{
				v4 = v3;
				++v3;
				i = (unsigned char)v4->bPlr;
				v2 -= 2;
			}
			else if ( v3->bCmd == FAKE_CMD_DROPID )
			{
				v5 = (TFakeDropPlr *)v3;
				v3 += 3;
				v2 -= 6;
				multi_player_left((unsigned char)v5->bPlr, v5->dwReason);
			}
			else
			{
				v6 = ParseCmd(i, (TCmd *)v3);
				v3 = (TFakeCmdPlr *)((char *)v3 + v6);
				v2 -= v6;
			}
		}
	}
}

//----- (0043BE74) --------------------------------------------------------
void __fastcall msg_do_sync(int pnum)
{
	char *v1; // edi
	DObjectStr *v2; // esi
	void *v3; // ebx
	void *v4; // eax
	void *v5; // eax
	void *v6; // eax
	int v7; // eax
	char *v8; // eax
	int v9; // eax
	int player_num; // [esp+0h] [ebp-Ch]
	int v11; // [esp+4h] [ebp-8h]
	char src; // [esp+Bh] [ebp-1h]

	player_num = pnum;
	if ( sgbDeltaChanged )
	{
		v11 = 0;
		v1 = (char *)DiabloAllocPtr(4722);
		v2 = sgLevels[0].object;
		v3 = v1 + 1;
		do
		{
			v4 = msg_sync_items(v3, &v2[-2794]);
			v5 = msg_sync_objects(v4, v2);
			v6 = msg_sync_monsters(v5, &v2[127]);
			v7 = msg_comp_level(v1, (int)v6);
			dthread_send_delta(player_num, (_BYTE)v11++ + CMD_DLEVEL_0, v1, v7);
			v2 += 4721;
		}
		while ( (signed int)v2 < (signed int)&sgTempLevel.item[126].bMCh );
		v8 = msg_sync_portals((char *)v3);
		v9 = msg_comp_level(v1, (int)v8);
		dthread_send_delta(player_num, CMD_DLEVEL_JUNK, v1, v9);
		mem_free_dbg(v1);
	}
	src = 0;
	dthread_send_delta(player_num, CMD_DLEVEL_END, &src, 1);
}
// 67618C: using guessed type char sgbDeltaChanged;

//----- (0043BF2B) --------------------------------------------------------
void *__fastcall msg_sync_items(void *dst, void *src)
{
	_BYTE *v2; // edi
	_BYTE *v3; // esi
	signed int v4; // ebx

	v2 = (unsigned char *)src;
	v3 = (unsigned char *)dst;
	v4 = 127;
	do
	{
		if ( *v2 == -1 )
		{
			*v3++ = -1;
		}
		else
		{
			memcpy(v3, v2, 0x16u);
			v3 += 22;
		}
		v2 += 22;
		--v4;
	}
	while ( v4 );
	return v3;
}

//----- (0043BF5B) --------------------------------------------------------
void *__fastcall msg_sync_objects(void *dst, void *src)
{
	char *v2; // esi

	v2 = (char *)dst;
	memcpy(dst, src, 0x7Fu);
	return v2 + 127;
}

//----- (0043BF6F) --------------------------------------------------------
void *__fastcall msg_sync_monsters(void *dst, void *src)
{
	_BYTE *v2; // edi
	_BYTE *v3; // esi
	signed int v4; // ebx

	v2 = (unsigned char *)src;
	v3 = (unsigned char *)dst;
	v4 = 200;
	do
	{
		if ( *v2 == -1 )
		{
			*v3++ = -1;
		}
		else
		{
			memcpy(v3, v2, 9u);
			v3 += 9;
		}
		v2 += 9;
		--v4;
	}
	while ( v4 );
	return v3;
}

//----- (0043BFA1) --------------------------------------------------------
char *__fastcall msg_sync_portals(char *a1)
{
	char *v1; // ebx
	DJunk *v2; // edi
	MultiQuests *v3; // esi
	char *v4; // edi
	unsigned char *v5; // ebp

	v1 = a1;
	v2 = sgJunk;
	v3 = sgJunk[0].quests;
	do
	{
		if ( v2->portal[0].x == -1 )
		{
			*v1++ = -1;
		}
		else
		{
			memcpy(v1, v2, 5u);
			v1 += 5;
		}
		v2 = (DJunk *)((char *)v2 + 5);
	}
	while ( (signed int)v2 < (signed int)sgJunk[0].quests );
	v4 = &quests[0]._qactive;
	v5 = &questlist[0]._qflags;
	do
	{
		if ( *v5 & 1 )
		{
			v3->qlog = v4[18];
			v3->qstate = *v4;
			v3->qvar1 = v4[13];
			memcpy(v1, v3, 3u);
			v1 += 3;
			++v3;
		}
		v5 += 20;
		v4 += 24;
	}
	while ( (signed int)v5 < (signed int)questyoff );
	return v1;
}

//----- (0043C019) --------------------------------------------------------
int __fastcall msg_comp_level(char *buffer, int size)
{
	char *v2; // esi
	int v3; // edi
	int v4; // eax

	v2 = buffer;
	v3 = size - (_DWORD)buffer - 1;
	v4 = encrypt_compress(buffer + 1, v3);
	*v2 = v3 != v4;
	return v4 + 1;
}

//----- (0043C035) --------------------------------------------------------
void __cdecl delta_init()
{
	sgbDeltaChanged = 0;
	memset(sgJunk, 255, 0x20u);
	memset(sgLevels, 255, 0x13981u);
	memset(sgLocals, 0, 0x6A40u);
	deltaload = 0;
}
// 67618C: using guessed type char sgbDeltaChanged;
// 676190: using guessed type int deltaload;

//----- (0043C07C) --------------------------------------------------------
void __fastcall delta_kill_monster(int mi, unsigned char x, unsigned char y, unsigned char bLevel)
{
	DMonsterStr *v4; // eax
	char v5; // cl

	if ( gbMaxPlayers != 1 )
	{
		v4 = &sgLevels[bLevel].monster[mi];
		sgbDeltaChanged = 1;
		v5 = monster[mi]._mdir;
		v4->_mhitpoints = 0;
		v4->_mx = x;
		v4->_mdir = v5;
		v4->_my = y;
	}
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C0C2) --------------------------------------------------------
void __fastcall delta_monster_hp(int mi, __int32 hp, unsigned char bLevel)
{
	DMonsterStr *v3; // eax

	if ( gbMaxPlayers != 1 )
	{
		sgbDeltaChanged = 1;
		v3 = &sgLevels[bLevel].monster[mi];
		if ( v3->_mhitpoints > hp )
			v3->_mhitpoints = hp;
	}
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C0F2) --------------------------------------------------------
void __fastcall delta_sync_monster(TCmdLocParam1 *packet, char level)
{
	DMonsterStr *v2; // eax
	char v3; // dl

	if ( gbMaxPlayers != 1 )
	{
		sgbDeltaChanged = 1;
		v2 = &sgLevels[(unsigned char)level].monster[(unsigned char)packet->bCmd];
		if ( v2->_mhitpoints )
		{
			v2->_mx = packet->x;
			v3 = packet->y;
			v2->_mactive = -1;
			v2->_my = v3;
			v2->_menemy = packet->wParam1;
		}
	}
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C134) --------------------------------------------------------
void __fastcall delta_sync_golem(TCmdGolem *pG, int pnum, int bLevel)
{
	DMonsterStr *v3; // eax
	char v4; // dl

	if ( gbMaxPlayers != 1 )
	{
		sgbDeltaChanged = 1;
		v3 = &sgLevels[(unsigned char)bLevel].monster[pnum];
		v3->_mx = pG->_mx;
		v4 = pG->_my;
		v3->_mactive = -1;
		v3->_my = v4;
		v3->_menemy = pG->_menemy;
		v3->_mdir = pG->_mdir;
		v3->_mhitpoints = pG->_mhitpoints;
	}
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C17D) --------------------------------------------------------
void __fastcall delta_leave_sync(unsigned char bLevel)
{
	int v1; // edi
	unsigned char v2; // bl
	bool v3; // zf
	int v4; // eax
	int v5; // ebp
	int v6; // ecx
	int v7; // esi
	DMonsterStr *v8; // edi
	int v9; // [esp-Ch] [ebp-10h]

	v2 = bLevel;
	if ( gbMaxPlayers != 1 )
	{
		v3 = currlevel == 0;
		if ( !currlevel )
		{
			v4 = GetRndSeed();
			v3 = currlevel == 0;
			glSeedTbl[0] = v4;
		}
		if ( !v3 )
		{
			v5 = 0;
			if ( nummonsters > 0 )
			{
				v9 = v1;
				do
				{
					v6 = monstactive[v5];
					v7 = monstactive[v5];
					if ( monster[v7]._mhitpoints )
					{
						sgbDeltaChanged = 1;
						v8 = &sgLevels[v2].monster[v6];
						v8->_mx = monster[v7]._mx;
						v8->_my = monster[v7]._my;
						v8->_mdir = monster[v7]._mdir;
						v8->_menemy = encode_enemy(v9);
						v8->_mhitpoints = monster[v7]._mhitpoints;
						v8->_mactive = monster[v7]._msquelch;
					}
					++v5;
				}
				while ( v5 < nummonsters );
			}
			memcpy(&sgLocals[v2], automapview, 0x640u);
		}
	}
}
// 43C17D: could not find valid save-restore pair for edi
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C24F) --------------------------------------------------------
bool __fastcall delta_portal_inited(int portal_num)
{
	return sgJunk[0].portal[portal_num].x == -1;
}

//----- (0043C25D) --------------------------------------------------------
bool __fastcall delta_quest_inited(int quest_num)
{
	return sgJunk[0].quests[quest_num].qstate != -1;
}

//----- (0043C26B) --------------------------------------------------------
void __fastcall DeltaAddItem(int ii)
{
	int v1; // eax
	int v2; // ecx
	signed int v3; // ebp
	DLevel *v4; // edx
	DLevel *v5; // edi
	char v6; // bl
	int v7; // esi
	signed int v8; // esi
	int v9; // eax
	char v10; // cl
	char v11; // cl

	v1 = ii;
	if ( gbMaxPlayers != 1 )
	{
		v2 = currlevel;
		v3 = 0;
		v4 = &sgLevels[v2];
		v5 = &sgLevels[v2];
		while ( 1 )
		{
			v6 = v5->item[0].bCmd;
			if ( v5->item[0].bCmd != -1 )
			{
				v7 = v1;
				if ( (unsigned short)v5->item[0].wIndx == items[v1].IDidx
				  && v5->item[0].wCI == items[v7]._iCreateInfo
				  && v5->item[0].dwSeed == items[v7]._iSeed
				  && (v6 == 1 || !v6) )
				{
					break;
				}
			}
			++v3;
			v5 = (DLevel *)((char *)v5 + 22);
			if ( v3 >= 127 )
			{
				v8 = 0;
				while ( v4->item[0].bCmd != -1 )
				{
					++v8;
					v4 = (DLevel *)((char *)v4 + 22);
					if ( v8 >= 127 )
						return;
				}
				v4->item[0].bCmd = 0;
				v9 = 368 * v1;
				v10 = *((_BYTE *)&items[0]._ix + v9);
				sgbDeltaChanged = 1;
				v4->item[0].x = v10;
				v4->item[0].y = *((_BYTE *)&items[0]._iy + v9);
				v4->item[0].wIndx = *(_WORD *)((char *)&items[0].IDidx + v9);
				v4->item[0].wCI = *(short *)((char *)&items[0]._iCreateInfo + v9);
				v4->item[0].dwSeed = *(int *)((char *)&items[0]._iSeed + v9);
				v4->item[0].bId = *((_BYTE *)&items[0]._iIdentified + v9);
				v4->item[0].bDur = *((_BYTE *)&items[0]._iDurability + v9);
				v4->item[0].bMDur = *((_BYTE *)&items[0]._iMaxDur + v9);
				v4->item[0].bCh = *((_BYTE *)&items[0]._iCharges + v9);
				v11 = *((_BYTE *)&items[0]._iMaxCharges + v9);
				_LOWORD(v9) = *(_WORD *)((char *)&items[0]._ivalue + v9);
				v4->item[0].bMCh = v11;
				v4->item[0].wValue = v9;
				return;
			}
		}
	}
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C372) --------------------------------------------------------
void __cdecl DeltaSaveLevel()
{
	int v0; // eax
	int v1; // edx
	int *v2; // ecx
	unsigned char v3; // cl

	if ( gbMaxPlayers != 1 )
	{
		v0 = myplr;
		v1 = 0;
		v2 = &plr[0]._pGFXLoad;
		do
		{
			if ( v1 != v0 )
				*v2 = 0;
			v2 += 5430;
			++v1;
		}
		while ( (signed int)v2 < (signed int)&plr_msgs[3].msg[27] );
		v3 = currlevel;
		plr[v0]._pLvlVisited[currlevel] = 1;
		delta_leave_sync(v3);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C3BA) --------------------------------------------------------
void __cdecl DeltaLoadLevel()
{
	int v0; // ebx
	int *v1; // esi
	int v2; // eax
	int v3; // ecx
	int v4; // edx
	int v5; // edi
	char v6; // al
	int v7; // eax
	signed int v8; // esi
	int v9; // eax
	char v10; // cl
	int v11; // eax
	char *v12; // edx
	int v13; // eax
	int v14; // ebx
	int *v15; // edx
	unsigned short v16; // cx
	int v17; // ST1C_4
	int v18; // ST18_4
	int v19; // eax
	int v20; // ecx
	int v21; // edx
	int v22; // eax
	int v23; // eax
	int v24; // esi
	int v25; // edi
	int v26; // eax
	int v27; // eax
	int v28; // esi
	unsigned char v29; // al
	int j; // esi
	int v31; // eax
	signed int v32; // [esp+0h] [ebp-24h]
	int v33; // [esp+4h] [ebp-20h]
	int o2; // [esp+8h] [ebp-1Ch]
	int i; // [esp+Ch] [ebp-18h]
	signed int v36; // [esp+10h] [ebp-14h]
	int v37; // [esp+14h] [ebp-10h]
	signed int v38; // [esp+18h] [ebp-Ch]
	signed int v39; // [esp+1Ch] [ebp-8h]
	int v40; // [esp+20h] [ebp-4h]
	signed int v41; // [esp+20h] [ebp-4h]

	if ( gbMaxPlayers != 1 )
	{
		deltaload = 1;
		if ( currlevel )
		{
			v0 = 0;
			if ( nummonsters > 0 )
			{
				v40 = 0;
				v1 = &monster[0]._mfuty;
				do
				{
					if ( sgLevels[currlevel].monster[v40]._mx != -1 )
					{
						M_ClearSquares(v0);
						v2 = v40 * 9 + 4721 * currlevel;
						v3 = *((unsigned char *)&sgLevels[0].monster[0]._mx + v2);
						v4 = *((unsigned char *)&sgLevels[0].monster[0]._my + v2);
						v5 = *(int *)((char *)&sgLevels[0].monster[0]._mhitpoints + v2);
						*(v1 - 3) = v3;
						*(v1 - 2) = v4;
						v1[1] = v3;
						v1[2] = v4;
						*(v1 - 1) = v3;
						*v1 = v4;
						if ( v5 != -1 )
							v1[26] = v5;
						if ( v5 )
						{
							decode_enemy(v0, *((unsigned char *)&sgLevels[0].monster[0]._menemy + v2));
							v7 = *(v1 - 3);
							if ( v7 && v7 != 1 || *(v1 - 2) )
								dMonster[0][*(v1 - 2) + 112 * v7] = v0 + 1;
							if ( (signed int)v1 >= (signed int)&monster[4]._mfuty )
							{
								M_StartStand(v0, v1[7]);
							}
							else
							{
								MAI_Golum(v0);
								v1[28] |= 0x30u;
							}
							*((_BYTE *)v1 + 116) = sgLevels[currlevel].monster[v40]._mactive;
						}
						else
						{
							v1[1] = v3;
							v1[2] = v4;
							M_ClearSquares(v0);
							if ( *((_BYTE *)v1 + 108) != 27 )
							{
								if ( *((_BYTE *)v1 + 144) )
									v6 = *((_BYTE *)v1 + 146);
								else
									v6 = *(_BYTE *)(v1[44] + 317);
								AddDead(*(v1 - 3), *(v1 - 2), v6, (direction)v1[7]);
							}
							v1[16] = 1;
							M_UpdateLeader(v0);
						}
					}
					++v40;
					++v0;
					v1 += 57;
				}
				while ( v0 < nummonsters );
			}
			memcpy(automapview, &sgLocals[currlevel], 0x640u);
		}
		v8 = 0;
		i = 0;
		v32 = 0;
		do
		{
			v9 = v8 + 4721 * currlevel;
			v10 = *(&sgLevels[0].item[0].bCmd + v9);
			if ( v10 != -1 )
			{
				if ( v10 == 1 )
				{
					FindGetItem(
						*(unsigned short *)((char *)&sgLevels[0].item[0].wIndx + v9),
						*(short *)((char *)&sgLevels[0].item[0].wCI + v9),
						*(int *)((char *)&sgLevels[0].item[0].dwSeed + v9));
					if ( v11 != -1 )
					{
						v12 = &dItem[items[v11]._ix][items[v11]._iy];
						if ( *v12 == v11 + 1 )
							*v12 = 0;
						DeleteItem(v11, i);
					}
				}
				v13 = v8 + 4721 * currlevel;
				if ( *(&sgLevels[0].item[0].bCmd + v13) == 2 )
				{
					v14 = itemavail[0];
					v33 = itemavail[0];
					v15 = &itemavail[-numitems + 126];
					itemactive[numitems] = itemavail[0];
					v16 = *(short *)((char *)&sgLevels[0].item[0].wIndx + v13);
					itemavail[0] = *v15;
					if ( v16 == 23 )
					{
						RecreateEar(
							v14,
							*(short *)((char *)&sgLevels[0].item[0].wCI + v13),
							*(int *)((char *)&sgLevels[0].item[0].dwSeed + v13),
							*(&sgLevels[0].item[0].bId + v13),
							*((unsigned char *)&sgLevels[0].item[0].bDur + v13),
							*((unsigned char *)&sgLevels[0].item[0].bMDur + v13),
							*((unsigned char *)&sgLevels[0].item[0].bCh + v13),
							*((unsigned char *)&sgLevels[0].item[0].bMCh + v13),
							*(unsigned short *)((char *)&sgLevels[0].item[0].wValue + v13),
							*(int *)((char *)&sgLevels[0].item[0].dwBuff + v13));
					}
					else
					{
						v17 = *(unsigned short *)((char *)&sgLevels[0].item[0].wValue + v13);
						v18 = *(int *)((char *)&sgLevels[0].item[0].dwSeed + v13);
						_LOWORD(v13) = *(short *)((char *)&sgLevels[0].item[0].wCI + v13);
						TempItemGeneration(v14, v16, v13, v18, v17);
						v19 = v8 + 4721 * currlevel;
						if ( *(&sgLevels[0].item[0].bId + v19) )
							items[v14]._iIdentified = 1;
						v20 = v14;
						items[v20]._iDurability = *((unsigned char *)&sgLevels[0].item[0].bDur + v19);
						items[v20]._iMaxDur = *((unsigned char *)&sgLevels[0].item[0].bMDur + v19);
						v21 = *((unsigned char *)&sgLevels[0].item[0].bCh + v19);
						v22 = *((unsigned char *)&sgLevels[0].item[0].bMCh + v19);
						items[v20]._iCharges = v21;
						items[v20]._iMaxCharges = v22;
					}
					v23 = v8 + 4721 * currlevel;
					v24 = *((unsigned char *)&sgLevels[0].item[0].x + v23);
					v25 = *((unsigned char *)&sgLevels[0].item[0].y + v23);
					if ( !CanPut(v24, v25) )
					{
						v39 = 0;
						v26 = -1;
						v41 = 1;
						v36 = -1;
						do
						{
							if ( v39 )
								break;
							v37 = v26;
							while ( v26 <= v41 && !v39 )
							{
								o2 = v25 + v37;
								v38 = v36;
								do
								{
									if ( v39 )
										break;
									if ( CanPut(v38 + v24, o2) )
									{
										v25 = o2;
										v39 = 1;
										v24 += v38;
									}
									++v38;
									v14 = v33;
								}
								while ( v38 <= v41 );
								v26 = ++v37;
							}
							++v41;
							v26 = v36-- - 1;
						}
						while ( v36 > -50 );
					}
					v27 = v14;
					items[v27]._ix = v24;
					items[v27]._iy = v25;
					dItem[v24][v25] = v14 + 1;
					RespawnItem(v14, 0);
					++numitems;
					v8 = v32;
				}
			}
			++i;
			v8 += 22;
			v32 = v8;
		}
		while ( v8 < 2794 );
		if ( currlevel )
		{
			v28 = 0;
			do
			{
				v29 = sgLevels[currlevel].object[v28].bCmd;
				if ( v29 >= 0x2Bu )
				{
					if ( v29 <= 0x2Eu )
					{
						SyncOpObject(-1, v29, v28);
					}
					else if ( v29 == 47 )
					{
						SyncBreakObj(-1, v28);
					}
				}
				++v28;
			}
			while ( v28 < 127 );
			for ( j = 0; j < nobjects; ++j )
			{
				v31 = object[objectactive[j]]._otype;
				if ( v31 == OBJ_TRAPL || v31 == OBJ_TRAPR )
					Obj_Trap(objectactive[j]);
			}
		}
		deltaload = 0;
	}
}
// 676190: using guessed type int deltaload;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043C873) --------------------------------------------------------
void __fastcall NetSendCmd(unsigned char bHiPri, unsigned char bCmd)
{
	TCmd cmd; // [esp+3h] [ebp-1h]

	cmd.bCmd = bCmd;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 1u);
	else
		NetSendLoPri((unsigned char *)&cmd, 1u);
}

//----- (0043C891) --------------------------------------------------------
void __fastcall NetSendCmdGolem(unsigned char mx, unsigned char my, unsigned char dir, unsigned char menemy, __int32 hp, int cl)
{
	TCmdGolem cmd; // [esp+0h] [ebp-Ch]

	cmd._mx = mx;
	cmd._mdir = dir;
	cmd._menemy = menemy;
	cmd._mhitpoints = hp;
	cmd._my = my;
	cmd.bCmd = CMD_AWAKEGOLEM;
	cmd._currlevel = cl;
	NetSendLoPri((unsigned char *)&cmd, 0xAu);
}

//----- (0043C8C7) --------------------------------------------------------
void __fastcall NetSendCmdLoc(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y)
{
	TCmdLoc cmd; // [esp+1h] [ebp-3h]

	cmd.bCmd = bCmd;
	cmd.x = x;
	cmd.y = y;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 3u);
	else
		NetSendLoPri((unsigned char *)&cmd, 3u);
}

//----- (0043C8F3) --------------------------------------------------------
void __fastcall NetSendCmdLocParam1(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1)
{
	TCmdLocParam1 cmd; // [esp+0h] [ebp-8h]

	cmd.bCmd = bCmd;
	cmd.x = x;
	cmd.y = y;
	cmd.wParam1 = wParam1;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 5u);
	else
		NetSendLoPri((unsigned char *)&cmd, 5u);
}

//----- (0043C928) --------------------------------------------------------
void __fastcall NetSendCmdLocParam2(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1, int wParam2)
{
	TCmdLocParam2 cmd; // [esp+0h] [ebp-8h]

	cmd.bCmd = bCmd;
	cmd.x = x;
	cmd.y = y;
	cmd.wParam1 = wParam1;
	cmd.wParam2 = wParam2;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 7u);
	else
		NetSendLoPri((unsigned char *)&cmd, 7u);
}

//----- (0043C965) --------------------------------------------------------
void __fastcall NetSendCmdLocParam3(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y, int wParam1, int wParam2, int wParam3)
{
	TCmdLocParam3 cmd; // [esp+0h] [ebp-Ch]

	cmd.bCmd = bCmd;
	cmd.x = x;
	cmd.y = y;
	cmd.wParam1 = wParam1;
	cmd.wParam2 = wParam2;
	cmd.wParam3 = wParam3;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 9u);
	else
		NetSendLoPri((unsigned char *)&cmd, 9u);
}

//----- (0043C9AB) --------------------------------------------------------
void __fastcall NetSendCmdParam1(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1)
{
	TCmdParam1 cmd; // [esp+1h] [ebp-3h]

	cmd.bCmd = bCmd;
	cmd.wParam1 = wParam1;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 3u);
	else
		NetSendLoPri((unsigned char *)&cmd, 3u);
}

//----- (0043C9D3) --------------------------------------------------------
void __fastcall NetSendCmdParam2(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1, unsigned short wParam2)
{
	TCmdParam2 cmd; // [esp+0h] [ebp-8h]

	cmd.bCmd = bCmd;
	cmd.wParam1 = wParam1;
	cmd.wParam2 = wParam2;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 5u);
	else
		NetSendLoPri((unsigned char *)&cmd, 5u);
}

//----- (0043CA04) --------------------------------------------------------
void __fastcall NetSendCmdParam3(unsigned char bHiPri, unsigned char bCmd, unsigned short wParam1, unsigned short wParam2, int wParam3)
{
	TCmdParam3 cmd; // [esp+0h] [ebp-8h]

	cmd.bCmd = bCmd;
	cmd.wParam1 = wParam1;
	cmd.wParam2 = wParam2;
	cmd.wParam3 = wParam3;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 7u);
	else
		NetSendLoPri((unsigned char *)&cmd, 7u);
}

//----- (0043CA3D) --------------------------------------------------------
void __fastcall NetSendCmdQuest(unsigned char bHiPri, unsigned char q)
{
	int v2; // eax
	char v3; // dl
	TCmdQuest cmd; // [esp+0h] [ebp-8h]

	cmd.q = q;
	cmd.bCmd = CMD_SYNCQUEST;
	v2 = 24 * q;
	cmd.qstate = *(&quests[0]._qactive + v2);
	v3 = *((_BYTE *)&quests[0]._qlog + v2);
	_LOBYTE(v2) = *(&quests[0]._qvar1 + v2);
	cmd.qlog = v3;
	cmd.qvar1 = v2;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 5u);
	else
		NetSendLoPri((unsigned char *)&cmd, 5u);
}

//----- (0043CA84) --------------------------------------------------------
void __fastcall NetSendCmdGItem(unsigned char bHiPri, unsigned char bCmd, unsigned char mast, unsigned char pnum, int ii)
{
	int v5; // eax
	bool v6; // zf
	short v7; // dx
	short v8; // bx
	int v9; // esi
	int v10; // esi
	char v11; // dl
	short v12; // ax
	TCmdGItem cmd; // [esp+4h] [ebp-20h]

	cmd.bCmd = bCmd;
	cmd.bPnum = pnum;
	cmd.bMaster = mast;
	cmd.bLevel = currlevel;
	cmd.bCursitem = ii;
	cmd.dwTime = 0;
	v5 = (unsigned char)ii;
	cmd.x = items[v5]._ix;
	cmd.y = items[v5]._iy;
	v6 = items[v5].IDidx == IDI_EAR;
	cmd.wIndx = items[v5].IDidx;
	if ( v6 )
	{
		_LOBYTE(v7) = 0;
		_HIBYTE(v7) = items[v5]._iName[7];
		_LOBYTE(v8) = 0;
		_HIBYTE(v8) = items[v5]._iName[18];
		v9 = items[v5]._iName[10];
		cmd.wCI = items[v5]._iName[8] | v7;
		cmd.dwSeed = items[v5]._iName[12] | ((items[v5]._iName[11] | ((v9 | (items[v5]._iName[9] << 8)) << 8)) << 8);
		cmd.bId = items[v5]._iName[13];
		cmd.bDur = items[v5]._iName[14];
		cmd.bMDur = items[v5]._iName[15];
		cmd.bCh = items[v5]._iName[16];
		cmd.bMCh = items[v5]._iName[17];
		v10 = items[v5]._iName[20];
		cmd.wValue = _LOWORD(items[v5]._ivalue) | v8 | ((_LOWORD(items[v5]._iCurs) - 19) << 6);
		cmd.dwBuff = items[v5]._iName[22] | ((items[v5]._iName[21] | ((v10 | (items[v5]._iName[19] << 8)) << 8)) << 8);
	}
	else
	{
		cmd.wCI = items[v5]._iCreateInfo;
		cmd.dwSeed = items[v5]._iSeed;
		cmd.bId = items[v5]._iIdentified;
		cmd.bDur = items[v5]._iDurability;
		cmd.bMDur = items[v5]._iMaxDur;
		cmd.bCh = items[v5]._iCharges;
		v11 = items[v5]._iMaxCharges;
		v12 = items[v5]._ivalue;
		cmd.bMCh = v11;
		cmd.wValue = v12;
	}
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 0x1Eu);
	else
		NetSendLoPri((unsigned char *)&cmd, 0x1Eu);
}

//----- (0043CC09) --------------------------------------------------------
void __fastcall NetSendCmdGItem2(unsigned char usonly, unsigned char bCmd, unsigned char mast, unsigned char pnum, struct TCmdGItem *p)
{
	unsigned char v5; // bl
	int v6; // esi
	int v7; // eax
	TCmdGItem cmd; // [esp+8h] [ebp-20h]

	v5 = bCmd;
	v6 = usonly;
	memcpy(&cmd, p, 0x1Eu);
	cmd.bPnum = pnum;
	cmd.bCmd = v5;
	cmd.bMaster = mast;
	if ( !v6 )
	{
		cmd.dwTime = 0;
		NetSendHiPri((unsigned char *)&cmd, 0x1Eu);
		return;
	}
	v7 = GetTickCount();
	if ( cmd.dwTime )
	{
		if ( v7 - cmd.dwTime > 5000 )
			return;
	}
	else
	{
		cmd.dwTime = v7;
	}
	multi_msg_add(&cmd.bCmd, 0x1Eu);
}

//----- (0043CC74) --------------------------------------------------------
unsigned char __fastcall NetSendCmdReq2(unsigned char bCmd, unsigned char mast, unsigned char pnum, struct TCmdGItem *p)
{
	unsigned char v4; // bl
	int v5; // eax
	TCmdGItem cmd; // [esp+4h] [ebp-24h]
	unsigned char v8; // [esp+24h] [ebp-4h]

	v4 = mast;
	v8 = bCmd;
	memcpy(&cmd, p, 0x1Eu);
	cmd.bCmd = v8;
	cmd.bPnum = pnum;
	cmd.bMaster = v4;
	v5 = GetTickCount();
	if ( !cmd.dwTime )
	{
		cmd.dwTime = v5;
LABEL_3:
		multi_msg_add(&cmd.bCmd, 0x1Eu);
		return 1;
	}
	if ( v5 - cmd.dwTime <= 5000 )
		goto LABEL_3;
	return 0;
}

//----- (0043CCCF) --------------------------------------------------------
void __fastcall NetSendCmdExtra(struct TCmdGItem *p)
{
	TCmdGItem cmd; // [esp+0h] [ebp-20h]

	memcpy(&cmd, p, 0x1Eu);
	cmd.dwTime = 0;
	cmd.bCmd = CMD_ITEMEXTRA;
	NetSendHiPri((unsigned char *)&cmd, 0x1Eu);
}

//----- (0043CCF8) --------------------------------------------------------
void __fastcall NetSendCmdPItem(unsigned char bHiPri, unsigned char bCmd, unsigned char x, unsigned char y)
{
	int v4; // eax
	short *v5; // edx
	bool v6; // zf
	short v7; // dx
	short v8; // bx
	int v9; // esi
	int v10; // esi
	char v11; // dl
	short v12; // ax
	TCmdPItem cmd; // [esp+4h] [ebp-18h]

	cmd.bCmd = bCmd;
	cmd.x = x;
	cmd.y = y;
	v4 = myplr;
	v5 = (short *)&plr[myplr].HoldItem.IDidx;
	v6 = *(_DWORD *)v5 == IDI_EAR;
	cmd.wIndx = *v5;
	if ( v6 )
	{
		_LOBYTE(v7) = 0;
		_HIBYTE(v7) = plr[v4].HoldItem._iName[7];
		_LOBYTE(v8) = 0;
		_HIBYTE(v8) = plr[v4].HoldItem._iName[18];
		v9 = plr[v4].HoldItem._iName[10];
		cmd.wCI = plr[v4].HoldItem._iName[8] | v7;
		cmd.dwSeed = plr[v4].HoldItem._iName[12] | ((plr[v4].HoldItem._iName[11] | ((v9 | (plr[v4].HoldItem._iName[9] << 8)) << 8)) << 8);
		cmd.bId = plr[v4].HoldItem._iName[13];
		cmd.bDur = plr[v4].HoldItem._iName[14];
		cmd.bMDur = plr[v4].HoldItem._iName[15];
		cmd.bCh = plr[v4].HoldItem._iName[16];
		cmd.bMCh = plr[v4].HoldItem._iName[17];
		v10 = plr[v4].HoldItem._iName[20];
		cmd.wValue = _LOWORD(plr[v4].HoldItem._ivalue) | v8 | ((_LOWORD(plr[v4].HoldItem._iCurs) - 19) << 6);
		cmd.dwBuff = plr[v4].HoldItem._iName[22] | ((plr[v4].HoldItem._iName[21] | ((v10 | (plr[v4].HoldItem._iName[19] << 8)) << 8)) << 8);
	}
	else
	{
		cmd.wCI = plr[v4].HoldItem._iCreateInfo;
		cmd.dwSeed = plr[v4].HoldItem._iSeed;
		cmd.bId = plr[v4].HoldItem._iIdentified;
		cmd.bDur = plr[v4].HoldItem._iDurability;
		cmd.bMDur = plr[v4].HoldItem._iMaxDur;
		cmd.bCh = plr[v4].HoldItem._iCharges;
		v11 = plr[v4].HoldItem._iMaxCharges;
		v12 = plr[v4].HoldItem._ivalue;
		cmd.bMCh = v11;
		cmd.wValue = v12;
	}
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 0x16u);
	else
		NetSendLoPri((unsigned char *)&cmd, 0x16u);
}

//----- (0043CE5B) --------------------------------------------------------
void __fastcall NetSendCmdChItem(unsigned char bHiPri, unsigned char bLoc)
{
	short v2; // dx
	char v3; // al
	TCmdChItem cmd; // [esp+0h] [ebp-Ch]

	cmd.bLoc = bLoc;
	v2 = plr[myplr].HoldItem.IDidx;
	cmd.bCmd = CMD_CHANGEPLRITEMS;
	cmd.wIndx = v2;
	cmd.wCI = plr[myplr].HoldItem._iCreateInfo;
	v3 = plr[myplr].HoldItem._iIdentified;
	cmd.dwSeed = plr[myplr].HoldItem._iSeed;
	cmd.bId = v3;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 0xBu);
	else
		NetSendLoPri((unsigned char *)&cmd, 0xBu);
}

//----- (0043CEB2) --------------------------------------------------------
void __fastcall NetSendCmdDelItem(unsigned char bHiPri, unsigned char bLoc)
{
	TCmdDelItem cmd; // [esp+2h] [ebp-2h]

	cmd.bLoc = bLoc;
	cmd.bCmd = CMD_DELPLRITEMS;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 2u);
	else
		NetSendLoPri((unsigned char *)&cmd, 2u);
}

//----- (0043CED4) --------------------------------------------------------
void __fastcall NetSendCmdDItem(unsigned char bHiPri, int ii)
{
	int v2; // eax
	short *v3; // edx
	bool v4; // zf
	short v5; // dx
	short v6; // bx
	int v7; // esi
	int v8; // esi
	char v9; // dl
	short v10; // ax
	TCmdPItem cmd; // [esp+4h] [ebp-18h]

	v2 = ii;
	cmd.bCmd = CMD_DROPITEM;
	cmd.x = items[ii]._ix;
	cmd.y = items[ii]._iy;
	v3 = (short *)&items[ii].IDidx;
	v4 = *(_DWORD *)v3 == IDI_EAR;
	cmd.wIndx = *v3;
	if ( v4 )
	{
		_LOBYTE(v5) = 0;
		_HIBYTE(v5) = items[v2]._iName[7];
		_LOBYTE(v6) = 0;
		_HIBYTE(v6) = items[v2]._iName[18];
		v7 = items[v2]._iName[10];
		cmd.wCI = items[v2]._iName[8] | v5;
		cmd.dwSeed = items[v2]._iName[12] | ((items[v2]._iName[11] | ((v7 | (items[v2]._iName[9] << 8)) << 8)) << 8);
		cmd.bId = items[v2]._iName[13];
		cmd.bDur = items[v2]._iName[14];
		cmd.bMDur = items[v2]._iName[15];
		cmd.bCh = items[v2]._iName[16];
		cmd.bMCh = items[v2]._iName[17];
		v8 = items[v2]._iName[20];
		cmd.wValue = _LOWORD(items[v2]._ivalue) | v6 | ((_LOWORD(items[v2]._iCurs) - 19) << 6);
		cmd.dwBuff = items[v2]._iName[22] | ((items[v2]._iName[21] | ((v8 | (items[v2]._iName[19] << 8)) << 8)) << 8);
	}
	else
	{
		cmd.wCI = items[v2]._iCreateInfo;
		cmd.dwSeed = items[v2]._iSeed;
		cmd.bId = items[v2]._iIdentified;
		cmd.bDur = items[v2]._iDurability;
		cmd.bMDur = items[v2]._iMaxDur;
		cmd.bCh = items[v2]._iCharges;
		v9 = items[v2]._iMaxCharges;
		v10 = items[v2]._ivalue;
		cmd.bMCh = v9;
		cmd.wValue = v10;
	}
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 0x16u);
	else
		NetSendLoPri((unsigned char *)&cmd, 0x16u);
}

//----- (0043D039) --------------------------------------------------------
void __fastcall NetSendCmdDamage(unsigned char bHiPri, unsigned char bPlr, unsigned __int32 dwDam)
{
	TCmdDamage cmd; // [esp+0h] [ebp-8h]

	cmd.bPlr = bPlr;
	cmd.bCmd = CMD_PLRDAMAGE;
	cmd.dwDam = dwDam;
	if ( bHiPri )
		NetSendHiPri((unsigned char *)&cmd, 6u);
	else
		NetSendLoPri((unsigned char *)&cmd, 6u);
}

//----- (0043D064) --------------------------------------------------------
void __fastcall msg_init_msg(int a1, const char *pszStr)
{
	const char *v2; // esi
	int v3; // edi
	char v4; // bl
	char v5[84]; // [esp+Ch] [ebp-54h]

	v2 = pszStr;
	v3 = a1;
	v4 = strlen(pszStr);
	v5[0] = 78;
	strcpy(&v5[1], v2);
	multi_send_msg_packet(v3, v5, v4 + 2);
}

//----- (0043D09D) --------------------------------------------------------
void __fastcall RemovePlrPortal(int pnum)
{
	memset((char *)sgJunk + 5 * pnum, 255, 5u);
	sgbDeltaChanged = 1;
}
// 67618C: using guessed type char sgbDeltaChanged;

//----- (0043D0BC) --------------------------------------------------------
int __fastcall ParseCmd(int pnum, TCmd *pCmd)
{
	bool v2; // zf
	TCmd *v3; // eax
	char v4; // dl
	unsigned char v5; // bl
	int result; // eax
	TCmd *v7; // esi

	v2 = sgwPackPlrOffsetTbl[pnum] == 0;
	v3 = pCmd;
	v4 = pCmd->bCmd;
	sbLastCmd = v4;
	if ( !v2 && v4 != CMD_ACK_PLRINFO && v4 != CMD_SEND_PLRINFO )
		return 0;
	v5 = v3->bCmd;
	switch ( v3->bCmd )
	{
		case CMD_WALKXY:
			return On_WALKXY((struct TCmdLoc *)v3, pnum);
		case CMD_ACK_PLRINFO:
			return On_ACK_PLRINFO((struct TCmdPlrInfoHdr *)v3, pnum);
		case CMD_ADDSTR:
			return On_ADDSTR((struct TCmdParam1 *)v3, pnum);
		case CMD_ADDMAG:
			return On_ADDMAG((struct TCmdParam1 *)v3, pnum);
		case CMD_ADDDEX:
			return On_ADDDEX((struct TCmdParam1 *)v3, pnum);
		case CMD_ADDVIT:
			return On_ADDVIT((struct TCmdParam1 *)v3, pnum);
		case CMD_SBSPELL:
			return On_SBSPELL((struct TCmdParam1 *)v3, pnum);
		case CMD_GETITEM:
			return On_GETITEM((struct TCmdGItem *)v3, pnum);
		case CMD_AGETITEM:
			return On_AGETITEM((struct TCmdGItem *)v3, pnum);
		case CMD_PUTITEM:
			return On_PUTITEM((struct TCmdPItem *)v3, pnum);
		case CMD_RESPAWNITEM:
			return On_RESPAWNITEM((struct TCmdPItem *)v3, pnum);
		case CMD_ATTACKXY:
			return On_ATTACKXY((struct TCmdLoc *)v3, pnum);
		case CMD_RATTACKXY:
			return On_RATTACKXY((struct TCmdLoc *)v3, pnum);
		case CMD_SPELLXY:
			return On_SPELLXY((struct TCmdLocParam2 *)v3, pnum);
		case CMD_TSPELLXY:
			return On_TSPELLXY((struct TCmdLocParam2 *)v3, pnum);
		case CMD_OPOBJXY:
			return On_OPOBJXY((struct TCmdLocParam1 *)v3, pnum);
		case CMD_DISARMXY:
			return On_DISARMXY((struct TCmdLocParam1 *)v3, pnum);
		case CMD_ATTACKID:
			return On_ATTACKID((struct TCmdParam1 *)v3, pnum);
		case CMD_ATTACKPID:
			return On_ATTACKPID((struct TCmdParam1 *)v3, pnum);
		case CMD_RATTACKID:
			return On_RATTACKID((struct TCmdParam1 *)v3, pnum);
		case CMD_RATTACKPID:
			return On_RATTACKPID((struct TCmdParam1 *)v3, pnum);
		case CMD_SPELLID:
			return On_SPELLID((struct TCmdLocParam2 *)v3, pnum);
		case CMD_SPELLPID:
			return On_SPELLPID((struct TCmdLocParam2 *)v3, pnum);
		case CMD_TSPELLID:
			return On_TSPELLID((struct TCmdLocParam2 *)v3, pnum);
		case CMD_TSPELLPID:
			return On_TSPELLPID((struct TCmdLocParam2 *)v3, pnum);
		case CMD_RESURRECT:
			return On_RESURRECT((struct TCmdParam1 *)v3, pnum);
		case CMD_OPOBJT:
			return On_OPOBJT((struct TCmdParam1 *)v3, pnum);
		case CMD_KNOCKBACK:
			return On_KNOCKBACK((struct TCmdParam1 *)v3, pnum);
		case CMD_TALKXY:
			return On_TALKXY((struct TCmdLocParam1 *)v3, pnum);
		case CMD_NEWLVL:
			return On_NEWLVL((struct TCmdParam2 *)v3, pnum);
		case CMD_WARP:
			return On_WARP((struct TCmdParam1 *)v3, pnum);
		case CMD_CHEAT_EXPERIENCE:
			return On_DEBUG();
		case CMD_CHEAT_SPELL_LEVEL:
			return On_DEBUG();
		case CMD_DEBUG:
			return On_DEBUG();
		case CMD_SYNCDATA:
			return On_SYNCDATA(v3, pnum);
		case CMD_MONSTDEATH:
			return On_MONSTDEATH((struct TCmdLocParam1 *)v3, pnum);
		case CMD_MONSTDAMAGE:
			return On_MONSTDAMAGE((struct TCmdLocParam1 *)v3, pnum);
		case CMD_PLRDEAD:
			return On_PLRDEAD((struct TCmdParam1 *)v3, pnum);
		case CMD_REQUESTGITEM:
			return On_REQUESTGITEM((struct TCmdGItem *)v3, pnum);
		case CMD_REQUESTAGITEM:
			return On_REQUESTAGITEM((struct TCmdGItem *)v3, pnum);
		case CMD_GOTOGETITEM:
			return On_GOTOGETITEM((struct TCmdLocParam1 *)v3, pnum);
		case CMD_GOTOAGETITEM:
			return On_GOTOAGETITEM((struct TCmdLocParam1 *)v3, pnum);
		case CMD_OPENDOOR:
			return On_OPENDOOR((struct TCmdParam1 *)v3, pnum);
		case CMD_CLOSEDOOR:
			return On_CLOSEDOOR((struct TCmdParam1 *)v3, pnum);
		case CMD_OPERATEOBJ:
			return On_OPERATEOBJ((struct TCmdParam1 *)v3, pnum);
		case CMD_PLROPOBJ:
			return On_PLROPOBJ((struct TCmdParam2 *)v3, pnum);
		case CMD_BREAKOBJ:
			return On_BREAKOBJ((struct TCmdParam2 *)v3, pnum);
		case CMD_CHANGEPLRITEMS:
			return On_CHANGEPLRITEMS((struct TCmdChItem *)v3, pnum);
		case CMD_DELPLRITEMS:
			return On_DELPLRITEMS((struct TCmdDelItem *)v3, pnum);
		case CMD_PLRDAMAGE:
			return On_PLRDAMAGE((struct TCmdDamage *)v3, pnum);
		case CMD_PLRLEVEL:
			return On_PLRLEVEL((struct TCmdParam1 *)v3, pnum);
		case CMD_DROPITEM:
			return On_DROPITEM((struct TCmdPItem *)v3, pnum);
		case CMD_PLAYER_JOINLEVEL:
			return On_PLAYER_JOINLEVEL((struct TCmdLocParam1 *)v3, pnum);
		case CMD_SEND_PLRINFO:
			return On_SEND_PLRINFO((struct TCmdPlrInfoHdr *)v3, pnum);
		case CMD_SATTACKXY:
			return On_SATTACKXY((struct TCmdLoc *)v3, pnum);
		case CMD_ACTIVATEPORTAL:
			return On_ACTIVATEPORTAL((DJunk *)v3, pnum);
		case CMD_DEACTIVATEPORTAL:
			return On_DEACTIVATEPORTAL(v3, pnum);
		case CMD_HEALOTHER:
			return On_HEALOTHER((struct TCmdParam1 *)v3, pnum);
		case CMD_STRING:
			return On_STRING((struct TCmdString *)v3, pnum);
		case CMD_SETSTR:
			return On_SETSTR((struct TCmdParam1 *)v3, pnum);
		case CMD_SETMAG:
			return On_SETMAG((struct TCmdParam1 *)v3, pnum);
		case CMD_SETDEX:
			return On_SETDEX((struct TCmdParam1 *)v3, pnum);
		case CMD_SETVIT:
			return On_SETVIT((struct TCmdParam1 *)v3, pnum);
		case CMD_RETOWN:
			return On_RETOWN(v3, pnum);
		case CMD_SPELLXYD:
			return On_SPELLXYD((struct TCmdLocParam3 *)v3, pnum);
		case CMD_ITEMEXTRA:
			return On_ITEMEXTRA((struct TCmdGItem *)v3, pnum);
		case CMD_SYNCPUTITEM:
			return On_SYNCPUTITEM((struct TCmdPItem *)v3, pnum);
		case CMD_KILLGOLEM:
			return On_KILLGOLEM((struct TCmdLocParam1 *)v3, pnum);
		case CMD_SYNCQUEST:
			return On_SYNCQUEST((struct TCmdQuest *)v3, pnum);
		case CMD_ENDSHIELD:
			return On_ENDSHIELD((int)v3, pnum);
		case CMD_AWAKEGOLEM:
			return On_AWAKEGOLEM((struct TCmdGolem *)v3, pnum);
		case CMD_NOVA:
			return On_NOVA((struct TCmdLoc *)v3, pnum);
		case CMD_SETSHIELD:
			return On_SETSHIELD((int)v3, pnum);
		case CMD_REMSHIELD:
			return On_REMSHIELD((int)v3, pnum);
		default:
			if ( v5 < CMD_DLEVEL_0 || v5 > CMD_DLEVEL_END )
			{
				SNetDropPlayer(pnum, 0x40000006);
				return 0;
			}
			v7 = v3;
			if ( (unsigned char)gbDeltaSender == pnum )
			{
				if ( sgbRecvCmd != CMD_DLEVEL_END )
				{
					if ( sgbRecvCmd == v3->bCmd )
					{
LABEL_99:
						memcpy(
							(char *)&sgTempLevel + *(unsigned short *)&v7[1].bCmd,
							&v7[5],
							*(unsigned short *)&v7[3].bCmd);
						sgdwRecvOffset += *(unsigned short *)&v7[3].bCmd;
						goto LABEL_100;
					}
					DoCopySync(sgbRecvCmd, sgdwRecvOffset);
					if ( v7->bCmd == CMD_DLEVEL_END )
					{
						sgbDeltaChunks = 20;
						sgbRecvCmd = CMD_DLEVEL_END;
						goto LABEL_100;
					}
					sgdwRecvOffset = 0;
LABEL_98:
					sgbRecvCmd = v7->bCmd;
					goto LABEL_99;
				}
			}
			else
			{
				if ( v3->bCmd != CMD_DLEVEL_END && (v3->bCmd != CMD_DLEVEL_0 || *(_WORD *)&v3[1].bCmd) )
					goto LABEL_100;
				gbDeltaSender = pnum;
				sgbRecvCmd = CMD_DLEVEL_END;
			}
			if ( v3->bCmd == CMD_DLEVEL_END )
			{
				sgbDeltaChunks = 20;
				goto LABEL_100;
			}
			if ( v3->bCmd == CMD_DLEVEL_0 && !*(_WORD *)&v3[1].bCmd )
			{
				sgdwRecvOffset = 0;
				goto LABEL_98;
			}
LABEL_100:
			result = *(unsigned short *)&v7[3].bCmd + 5;
			break;
	}
	return result;
}
// 66E4A9: using guessed type char sbLastCmd;
// 67618D: using guessed type char sgbDeltaChunks;
// 6796E4: using guessed type char gbDeltaSender;

//----- (0043D632) --------------------------------------------------------
void __fastcall DoCopySync(unsigned char cmd, int recv_offset)
{
	unsigned char v2; // bl
	int v3; // esi
	void *v4; // eax
	void *v5; // eax

	v2 = cmd;
	if ( sgTempLevel.item[0].bCmd )
		encrypt_decompress(&sgTempLevel.item[0].x, recv_offset, 4721);
	if ( v2 == CMD_DLEVEL_JUNK )
	{
		msg_copy_portals((int)&sgTempLevel.item[0].x);
	}
	else if ( v2 < CMD_DLEVEL_0 || v2 > CMD_DLEVEL_16 )
	{
		TermMsg("msg:1");
	}
	else
	{
		v3 = (unsigned char)(v2 - CMD_DLEVEL_0);
		v4 = msg_copy_items(&sgTempLevel.item[0].x, &sgLevels[v3]);
		v5 = msg_copy_objects(v4, sgLevels[v3].object);
		msg_copy_monsters(v5, sgLevels[v3].monster);
	}
	++sgbDeltaChunks;
	sgbDeltaChanged = 1;
}
// 67618C: using guessed type char sgbDeltaChanged;
// 67618D: using guessed type char sgbDeltaChunks;

//----- (0043D6BA) --------------------------------------------------------
void *__fastcall msg_copy_items(void *src, void *dst)
{
	char *v2; // edi
	_BYTE *v3; // esi
	signed int v4; // ebx

	v2 = (char *)dst;
	v3 = (unsigned char *)src;
	v4 = 127;
	do
	{
		if ( *v3 == -1 )
		{
			memset(v2, 255, 0x16u);
			++v3;
		}
		else
		{
			memcpy(v2, v3, 0x16u);
			v3 += 22;
		}
		v2 += 22;
		--v4;
	}
	while ( v4 );
	return v3;
}

//----- (0043D6F5) --------------------------------------------------------
void *__fastcall msg_copy_objects(void *src, void *dst)
{
	char *v2; // esi

	v2 = (char *)src;
	memcpy(dst, src, 0x7Fu);
	return v2 + 127;
}

//----- (0043D709) --------------------------------------------------------
void *__fastcall msg_copy_monsters(void *src, void *dst)
{
	char *v2; // edi
	_BYTE *v3; // esi
	signed int v4; // ebx

	v2 = (char *)dst;
	v3 = (unsigned char *)src;
	v4 = 200;
	do
	{
		if ( *v3 == -1 )
		{
			memset(v2, 255, 9u);
			++v3;
		}
		else
		{
			memcpy(v2, v3, 9u);
			v3 += 9;
		}
		v2 += 9;
		--v4;
	}
	while ( v4 );
	return v3;
}

//----- (0043D746) --------------------------------------------------------
char __fastcall msg_copy_portals(int a1)
{
	_BYTE *v1; // ebx
	int v2; // edi
	DJunk *v3; // esi
	char result; // al
	MultiQuests *v5; // esi
	char *v6; // edi
	unsigned char *v7; // ebp

	v1 = (_BYTE *)a1;
	v2 = 0;
	v3 = sgJunk;
	do
	{
		if ( *v1 == -1 )
		{
			memset(v3, 255, 5u);
			++v1;
			SetPortalStats(v2, 0, 0, 0, 0, 0);
		}
		else
		{
			memcpy(v3, v1, 5u);
			v1 += 5;
			SetPortalStats(
				v2,
				1,
				(unsigned char)v3->portal[0].x,
				(unsigned char)v3->portal[0].y,
				(unsigned char)v3->portal[0].level,
				(unsigned char)v3->portal[0].ltype);
		}
		v3 = (DJunk *)((char *)v3 + 5);
		++v2;
	}
	while ( (signed int)v3 < (signed int)sgJunk[0].quests );
	v5 = sgJunk[0].quests;
	v6 = &quests[0]._qactive;
	v7 = &questlist[0]._qflags;
	do
	{
		if ( *v7 & 1 )
		{
			memcpy(v5, v1, 3u);
			*(_DWORD *)(v6 + 18) = (unsigned char)v5->qlog;
			*v6 = v5->qstate;
			result = v5->qvar1;
			v1 += 3;
			v6[13] = result;
			++v5;
		}
		v7 += 20;
		v6 += 24;
	}
	while ( (signed int)v7 < (signed int)questyoff );
	return result;
}

//----- (0043D7F1) --------------------------------------------------------
int __fastcall On_SYNCDATA(void *packet, int pnum)
{
	return SyncData(pnum, (TSyncHeader *)packet);
}

//----- (0043D7FC) --------------------------------------------------------
int __fastcall On_WALKXY(struct TCmdLoc *pCmd, int pnum)
{
	int v2; // ebx
	struct TCmdLoc *v3; // edi
	int v4; // esi

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v4 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			ClrPlrPath(pnum);
			MakePlrPath(v2, (unsigned char)v3->x, (unsigned char)v3->y, 1u);
			plr[v4].destAction = -1;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043D84A) --------------------------------------------------------
int __fastcall On_ADDSTR(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x100u )
			ModifyPlrStr(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043D87B) --------------------------------------------------------
int __fastcall On_ADDMAG(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x100u )
			ModifyPlrMag(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043D8AC) --------------------------------------------------------
int __fastcall On_ADDDEX(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x100u )
			ModifyPlrDex(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043D8DD) --------------------------------------------------------
int __fastcall On_ADDVIT(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x100u )
			ModifyPlrVit(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043D90E) --------------------------------------------------------
int __fastcall On_SBSPELL(struct TCmdParam1 *pCmd, int pnum)
{
	int v2; // eax

	if ( gbBufferMsgs != 1 )
	{
		if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
		{
			v2 = pnum;
			plr[v2]._pSpell = (unsigned short)pCmd->wParam1;
			plr[v2]._pSplType = plr[v2]._pSBkSplType;
			plr[v2]._pSplFrom = 1;
			plr[v2].destAction = 12;
		}
		else
		{
			msg_errorf("%s has cast an illegal spell.", plr[pnum]._pName);
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043D97D) --------------------------------------------------------
void msg_errorf(char *format, ...)
{
	DWORD v1; // eax
	char v2[256]; // [esp+0h] [ebp-100h]
	va_list va; // [esp+10Ch] [ebp+Ch]

	va_start(va, format);
	v1 = GetTickCount();
	if ( v1 - msg_err_timer >= 5000 )
	{
		msg_err_timer = v1;
		vsprintf(v2, format, va);
		ErrorPlrMsg(v2);
	}
}
// 67619C: using guessed type int msg_err_timer;

//----- (0043D9C4) --------------------------------------------------------
int __fastcall On_GOTOGETITEM(struct TCmdLocParam1 *pCmd, int pnum)
{
	struct TCmdLocParam1 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0);
			plr[v3].destAction = 15;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DA16) --------------------------------------------------------
int __fastcall On_REQUESTGITEM(struct TCmdGItem *pCmd, int pnum)
{
	struct TCmdGItem *v2; // esi
	int v3; // eax
	int v4; // edx
	int v5; // edx
	int v6; // eax
	int v7; // edi
	unsigned char v8; // al
	int v9; // edx
	int v10; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		_LOBYTE(v3) = i_own_level(plr[pnum].plrlevel);
		if ( v3 )
		{
			_LOWORD(v4) = v2->wCI;
			if ( GetItemRecord(v2->dwSeed, v4, (unsigned short)v2->wIndx) )
			{
				_LOWORD(v5) = v2->wCI;
				FindGetItem((unsigned short)v2->wIndx, v5, v2->dwSeed);
				v7 = v6;
				v8 = v2->bPnum;
				if ( v7 == -1 )
				{
					_LOBYTE(v10) = NetSendCmdReq2(CMD_REQUESTGITEM, myplr, v8, v2);
					if ( !v10 )
						NetSendCmdExtra(v2);
				}
				else
				{
					NetSendCmdGItem2(0, CMD_GETITEM, myplr, v8, v2);
					if ( (unsigned char)v2->bPnum == myplr )
						InvGetItem(myplr, v7);
					else
						SyncGetItem(
							(unsigned char)v2->x,
							(unsigned char)v2->y,
							(unsigned short)v2->wIndx,
							v2->wCI,
							v2->dwSeed);
					_LOWORD(v9) = v2->wCI;
					SetItemRecord(v2->dwSeed, v9, (unsigned short)v2->wIndx);
				}
			}
		}
	}
	return 30;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DAE6) --------------------------------------------------------
bool __fastcall i_own_level(int nReqLevel)
{
	int v1; // edx
	char *v2; // eax

	v1 = 0;
	v2 = &plr[0]._pLvlChanging;
	do
	{
		if ( *(v2 - 290) && !*v2 && *(_DWORD *)(v2 - 267) == nReqLevel && (v1 != myplr || !gbBufferMsgs) )
			break;
		v2 += 21720;
		++v1;
	}
	while ( (signed int)v2 < (signed int)&plr_msgs[1].msg[114] );
	return v1 == myplr;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DB2D) --------------------------------------------------------
int __fastcall On_GETITEM(struct TCmdGItem *pCmd, int pnum)
{
	struct TCmdGItem *v2; // esi
	int v3; // eax
	int v4; // edi
	int v5; // eax
	char v6; // al
	int v7; // ecx
	int v8; // edx
	int v9; // eax
	int v10; // edx

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet((unsigned short)pnum, pCmd, 30);
	}
	else
	{
		FindGetItem((unsigned short)pCmd->wIndx, pCmd->wCI, pCmd->dwSeed);
		v4 = v3;
		_LOBYTE(v5) = delta_get_item(v2, v2->bLevel);
		if ( !v5 )
		{
			NetSendCmdGItem2(1u, CMD_GETITEM, v2->bMaster, v2->bPnum, v2);
			return 30;
		}
		v6 = v2->bLevel;
		v7 = myplr;
		if ( (currlevel == v6 || (unsigned char)v2->bPnum == myplr) && (unsigned char)v2->bMaster != myplr )
		{
			if ( (unsigned char)v2->bPnum != myplr )
			{
				SyncGetItem(
					(unsigned char)v2->x,
					(unsigned char)v2->y,
					(unsigned short)v2->wIndx,
					v2->wCI,
					v2->dwSeed);
				return 30;
			}
			if ( currlevel == v6 )
			{
				v10 = v4;
			}
			else
			{
				v8 = (unsigned char)v2->bId;
				_LOWORD(v8) = v2->wCI;
				v9 = SyncPutItem(
						 myplr,
						 plr[myplr].WorldX,
						 plr[myplr].WorldY,
						 (unsigned short)v2->wIndx,
						 v8,
						 v2->dwSeed,
						 (unsigned char)v2->bId,
						 (unsigned char)v2->bDur,
						 (unsigned char)v2->bMDur,
						 (unsigned char)v2->bCh,
						 (unsigned char)v2->bMCh,
						 (unsigned short)v2->wValue,
						 v2->dwBuff);
				if ( v9 == -1 )
					return 30;
				v7 = myplr;
				v10 = v9;
			}
			InvGetItem(v7, v10);
			return 30;
		}
	}
	return 30;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DC3D) --------------------------------------------------------
unsigned char __fastcall delta_get_item(struct TCmdGItem *pI, unsigned char bLevel)
{
	struct TCmdGItem *v2; // esi
	signed int v3; // ecx
	DLevel *v4; // edi
	DLevel *v5; // eax
	char v6; // cl
	DLevel *v8; // eax
	signed int v9; // ecx

	v2 = pI;
	if ( gbMaxPlayers != 1 )
	{
		v3 = 0;
		v4 = &sgLevels[bLevel];
		v5 = &sgLevels[bLevel];
		while ( v5->item[0].bCmd == -1
			 || v5->item[0].wIndx != v2->wIndx
			 || v5->item[0].wCI != v2->wCI
			 || v5->item[0].dwSeed != v2->dwSeed )
		{
			++v3;
			v5 = (DLevel *)((char *)v5 + 22);
			if ( v3 >= 127 )
				goto LABEL_15;
		}
		v6 = v5->item[0].bCmd;
		if ( v5->item[0].bCmd == 1 )
			return 1;
		if ( !v6 )
		{
			sgbDeltaChanged = 1;
			v5->item[0].bCmd = 1;
			return 1;
		}
		if ( v6 == 2 )
		{
			v5->item[0].bCmd = -1;
			sgbDeltaChanged = 1;
			return 1;
		}
		TermMsg("delta:1");
LABEL_15:
		if ( v2->wCI >= 0 )
			return 0;
		v8 = v4;
		v9 = 0;
		while ( v8->item[0].bCmd != -1 )
		{
			++v9;
			v8 = (DLevel *)((char *)v8 + 22);
			if ( v9 >= 127 )
				return 1;
		}
		sgbDeltaChanged = 1;
		v8->item[0].bCmd = 1;
		v8->item[0].x = v2->x;
		v8->item[0].y = v2->y;
		v8->item[0].wIndx = v2->wIndx;
		v8->item[0].wCI = v2->wCI;
		v8->item[0].dwSeed = v2->dwSeed;
		v8->item[0].bId = v2->bId;
		v8->item[0].bDur = v2->bDur;
		v8->item[0].bMDur = v2->bMDur;
		v8->item[0].bCh = v2->bCh;
		v8->item[0].bMCh = v2->bMCh;
		v8->item[0].wValue = v2->wValue;
		v8->item[0].dwBuff = v2->dwBuff;
	}
	return 1;
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043DD40) --------------------------------------------------------
int __fastcall On_GOTOAGETITEM(struct TCmdLocParam1 *pCmd, int pnum)
{
	struct TCmdLocParam1 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0);
			plr[v3].destAction = 16;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DD92) --------------------------------------------------------
int __fastcall On_REQUESTAGITEM(struct TCmdGItem *pCmd, int pnum)
{
	struct TCmdGItem *v2; // esi
	int v3; // eax
	int v4; // edx
	int v5; // edx
	int v6; // eax
	bool v7; // zf
	unsigned char v8; // al
	int v9; // edx
	int v10; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		_LOBYTE(v3) = i_own_level(plr[pnum].plrlevel);
		if ( v3 )
		{
			_LOWORD(v4) = v2->wCI;
			if ( GetItemRecord(v2->dwSeed, v4, (unsigned short)v2->wIndx) )
			{
				_LOWORD(v5) = v2->wCI;
				FindGetItem((unsigned short)v2->wIndx, v5, v2->dwSeed);
				v7 = v6 == -1;
				v8 = v2->bPnum;
				if ( v7 )
				{
					_LOBYTE(v10) = NetSendCmdReq2(CMD_REQUESTAGITEM, myplr, v8, v2);
					if ( !v10 )
						NetSendCmdExtra(v2);
				}
				else
				{
					NetSendCmdGItem2(0, CMD_AGETITEM, myplr, v8, v2);
					if ( (unsigned char)v2->bPnum == myplr )
						AutoGetItem(myplr, (unsigned char)v2->bCursitem);
					else
						SyncGetItem(
							(unsigned char)v2->x,
							(unsigned char)v2->y,
							(unsigned short)v2->wIndx,
							v2->wCI,
							v2->dwSeed);
					_LOWORD(v9) = v2->wCI;
					SetItemRecord(v2->dwSeed, v9, (unsigned short)v2->wIndx);
				}
			}
		}
	}
	return 30;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DE60) --------------------------------------------------------
int __fastcall On_AGETITEM(struct TCmdGItem *pCmd, int pnum)
{
	struct TCmdGItem *v2; // esi
	int v3; // eax
	char v4; // al
	int v5; // ecx
	int v6; // edx
	int v7; // eax
	int v8; // edx

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet((unsigned short)pnum, pCmd, 30);
	}
	else
	{
		FindGetItem((unsigned short)pCmd->wIndx, pCmd->wCI, pCmd->dwSeed);
		_LOBYTE(v3) = delta_get_item(v2, v2->bLevel);
		if ( !v3 )
		{
			NetSendCmdGItem2(1u, CMD_AGETITEM, v2->bMaster, v2->bPnum, v2);
			return 30;
		}
		v4 = v2->bLevel;
		v5 = myplr;
		if ( (currlevel == v4 || (unsigned char)v2->bPnum == myplr) && (unsigned char)v2->bMaster != myplr )
		{
			if ( (unsigned char)v2->bPnum != myplr )
			{
				SyncGetItem(
					(unsigned char)v2->x,
					(unsigned char)v2->y,
					(unsigned short)v2->wIndx,
					v2->wCI,
					v2->dwSeed);
				return 30;
			}
			if ( currlevel == v4 )
			{
				v8 = (unsigned char)v2->bCursitem;
			}
			else
			{
				v6 = (unsigned char)v2->bId;
				_LOWORD(v6) = v2->wCI;
				v7 = SyncPutItem(
						 myplr,
						 plr[myplr].WorldX,
						 plr[myplr].WorldY,
						 (unsigned short)v2->wIndx,
						 v6,
						 v2->dwSeed,
						 (unsigned char)v2->bId,
						 (unsigned char)v2->bDur,
						 (unsigned char)v2->bMDur,
						 (unsigned char)v2->bCh,
						 (unsigned char)v2->bMCh,
						 (unsigned short)v2->wValue,
						 v2->dwBuff);
				if ( v7 == -1 )
					return 30;
				v5 = myplr;
				v8 = v7;
			}
			AutoGetItem(v5, v8);
			return 30;
		}
	}
	return 30;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DF6E) --------------------------------------------------------
int __fastcall On_ITEMEXTRA(struct TCmdGItem *pCmd, int pnum)
{
	int v2; // edi
	struct TCmdGItem *v3; // esi

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 30);
	}
	else
	{
		delta_get_item(pCmd, pCmd->bLevel);
		if ( currlevel == plr[v2].plrlevel )
			SyncGetItem(
				(unsigned char)v3->x,
				(unsigned char)v3->y,
				(unsigned short)v3->wIndx,
				v3->wCI,
				v3->dwSeed);
	}
	return 30;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043DFC9) --------------------------------------------------------
int __fastcall On_PUTITEM(struct TCmdPItem *pCmd, int pnum)
{
	int v2; // edi
	struct TCmdPItem *v3; // esi
	unsigned char *v4; // ebx
	int v5; // edx
	int v6; // eax
	int v7; // edx
	int v8; // ebp

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 22);
		return 22;
	}
	v4 = (unsigned char *)&plr[pnum].plrlevel;
	if ( currlevel != *(_DWORD *)v4 )
	{
		_LOWORD(pnum) = pCmd->wCI;
		PutItemRecord(pCmd->dwSeed, pnum, (unsigned short)pCmd->wIndx);
		delta_put_item(v3, (unsigned char)v3->x, (unsigned char)v3->y, *v4);
		check_update_plr(v2);
		return 22;
	}
	v5 = (unsigned char)pCmd->x;
	if ( v2 == myplr )
		v6 = InvPutItem(v2, v5, (unsigned char)pCmd->y);
	else
		v6 = SyncPutItem(
				 v2,
				 v5,
				 (unsigned char)pCmd->y,
				 (unsigned short)pCmd->wIndx,
				 (unsigned short)pCmd->wCI,
				 pCmd->dwSeed,
				 (unsigned char)pCmd->bId,
				 (unsigned char)pCmd->bDur,
				 (unsigned char)pCmd->bMDur,
				 (unsigned char)pCmd->bCh,
				 (unsigned char)pCmd->bMCh,
				 (unsigned short)pCmd->wValue,
				 pCmd->dwBuff);
	v8 = v6;
	if ( v6 != -1 )
	{
		_LOWORD(v7) = v3->wCI;
		PutItemRecord(v3->dwSeed, v7, (unsigned short)v3->wIndx);
		delta_put_item(v3, items[v8]._ix, items[v8]._iy, *v4);
		check_update_plr(v2);
	}
	return 22;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E0CE) --------------------------------------------------------
void __fastcall delta_put_item(struct TCmdPItem *pI, int x, int y, unsigned char bLevel)
{
	struct TCmdPItem *v4; // ebx
	int v5; // eax
	DLevel *v6; // esi
	DLevel *v7; // edi
	char v8; // al
	signed int v9; // eax
	char v10; // [esp+Ch] [ebp-4h]
	signed int bLevela; // [esp+1Ch] [ebp+Ch]

	v10 = x;
	v4 = pI;
	if ( gbMaxPlayers != 1 )
	{
		v5 = bLevel;
		bLevela = 0;
		v6 = &sgLevels[v5];
		v7 = &sgLevels[v5];
		do
		{
			v8 = v7->item[0].bCmd;
			if ( v7->item[0].bCmd != 1
			  && v8 != -1
			  && v7->item[0].wIndx == v4->wIndx
			  && v7->item[0].wCI == v4->wCI
			  && v7->item[0].dwSeed == v4->dwSeed )
			{
				if ( v8 == 2 )
					return;
				TermMsg("Trying to drop a floor item?");
			}
			++bLevela;
			v7 = (DLevel *)((char *)v7 + 22);
		}
		while ( bLevela < 127 );
		v9 = 0;
		while ( v6->item[0].bCmd != -1 )
		{
			++v9;
			v6 = (DLevel *)((char *)v6 + 22);
			if ( v9 >= 127 )
				return;
		}
		sgbDeltaChanged = 1;
		memcpy(v6, v4, 0x16u);
		v6->item[0].x = v10;
		v6->item[0].bCmd = 2;
		v6->item[0].y = y;
	}
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043E179) --------------------------------------------------------
void __fastcall check_update_plr(int pnum)
{
	if ( gbMaxPlayers != 1 && pnum == myplr )
		pfile_update(1);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0043E193) --------------------------------------------------------
int __fastcall On_SYNCPUTITEM(struct TCmdPItem *pCmd, int pnum)
{
	int v2; // ebx
	struct TCmdPItem *v3; // esi
	unsigned char *v4; // edi
	int v5; // edx
	int v6; // ebp

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 22);
		return 22;
	}
	v4 = (unsigned char *)&plr[pnum].plrlevel;
	if ( currlevel != *(_DWORD *)v4 )
	{
		_LOWORD(pnum) = pCmd->wCI;
		PutItemRecord(pCmd->dwSeed, pnum, (unsigned short)pCmd->wIndx);
		delta_put_item(v3, (unsigned char)v3->x, (unsigned char)v3->y, *v4);
		check_update_plr(v2);
		return 22;
	}
	v6 = SyncPutItem(
			 pnum,
			 (unsigned char)pCmd->x,
			 (unsigned char)pCmd->y,
			 (unsigned short)pCmd->wIndx,
			 (unsigned short)pCmd->wCI,
			 pCmd->dwSeed,
			 (unsigned char)pCmd->bId,
			 (unsigned char)pCmd->bDur,
			 (unsigned char)pCmd->bMDur,
			 (unsigned char)pCmd->bCh,
			 (unsigned char)pCmd->bMCh,
			 (unsigned short)pCmd->wValue,
			 pCmd->dwBuff);
	if ( v6 != -1 )
	{
		_LOWORD(v5) = v3->wCI;
		PutItemRecord(v3->dwSeed, v5, (unsigned short)v3->wIndx);
		delta_put_item(v3, items[v6]._ix, items[v6]._iy, *v4);
		check_update_plr(v2);
	}
	return 22;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E284) --------------------------------------------------------
int __fastcall On_RESPAWNITEM(struct TCmdPItem *pCmd, int pnum)
{
	struct TCmdPItem *v2; // esi
	unsigned char *v3; // edi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 22);
	}
	else
	{
		v3 = (unsigned char *)&plr[pnum].plrlevel;
		if ( currlevel == *(_DWORD *)v3 && pnum != myplr )
			SyncPutItem(
				pnum,
				(unsigned char)pCmd->x,
				(unsigned char)pCmd->y,
				(unsigned short)pCmd->wIndx,
				(unsigned short)pCmd->wCI,
				pCmd->dwSeed,
				(unsigned char)pCmd->bId,
				(unsigned char)pCmd->bDur,
				(unsigned char)pCmd->bMDur,
				(unsigned char)pCmd->bCh,
				(unsigned char)pCmd->bMCh,
				(unsigned short)pCmd->wValue,
				pCmd->dwBuff);
		_LOWORD(pnum) = v2->wCI;
		PutItemRecord(v2->dwSeed, pnum, (unsigned short)v2->wIndx);
		delta_put_item(v2, (unsigned char)v2->x, (unsigned char)v2->y, *v3);
	}
	return 22;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E32A) --------------------------------------------------------
int __fastcall On_ATTACKXY(struct TCmdLoc *pCmd, int pnum)
{
	struct TCmdLoc *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0);
			plr[v3].destAction = 9;
			plr[v3].destParam1 = (unsigned char)v2->x;
			plr[v3].destParam2 = (unsigned char)v2->y;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E386) --------------------------------------------------------
int __fastcall On_SATTACKXY(struct TCmdLoc *pCmd, int pnum)
{
	struct TCmdLoc *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			ClrPlrPath(pnum);
			plr[v3].destAction = 9;
			plr[v3].destParam1 = (unsigned char)v2->x;
			plr[v3].destParam2 = (unsigned char)v2->y;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E3D5) --------------------------------------------------------
int __fastcall On_RATTACKXY(struct TCmdLoc *pCmd, int pnum)
{
	struct TCmdLoc *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			ClrPlrPath(pnum);
			plr[v3].destAction = 10;
			plr[v3].destParam1 = (unsigned char)v2->x;
			plr[v3].destParam2 = (unsigned char)v2->y;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E424) --------------------------------------------------------
int __fastcall On_SPELLXYD(struct TCmdLocParam3 *pCmd, int pnum)
{
	struct TCmdLocParam3 *v2; // edi
	int v3; // esi
	int v4; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
			{
				ClrPlrPath(pnum);
				plr[v3].destAction = 26;
				plr[v3].destParam1 = (unsigned char)v2->x;
				plr[v3].destParam2 = (unsigned char)v2->y;
				plr[v3].destParam3 = (unsigned short)v2->wParam2;
				plr[v3].destParam4 = (unsigned short)v2->wParam3;
				v4 = (unsigned short)v2->wParam1;
				plr[v3]._pSplFrom = 0;
				plr[v3]._pSpell = v4;
				plr[v3]._pSplType = plr[v3]._pRSplType;
			}
			else
			{
				msg_errorf("%s has cast an illegal spell.", plr[v3]._pName);
			}
		}
	}
	return 9;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E4D2) --------------------------------------------------------
int __fastcall On_SPELLXY(struct TCmdLocParam2 *pCmd, int pnum)
{
	struct TCmdLocParam2 *v2; // edi
	int v3; // esi
	int v4; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
			{
				ClrPlrPath(pnum);
				plr[v3].destAction = 12;
				plr[v3].destParam1 = (unsigned char)v2->x;
				plr[v3].destParam2 = (unsigned char)v2->y;
				plr[v3].destParam3 = (unsigned short)v2->wParam2;
				v4 = (unsigned short)v2->wParam1;
				plr[v3]._pSplFrom = 0;
				plr[v3]._pSpell = v4;
				plr[v3]._pSplType = plr[v3]._pRSplType;
			}
			else
			{
				msg_errorf("%s has cast an illegal spell.", plr[v3]._pName);
			}
		}
	}
	return 7;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E576) --------------------------------------------------------
int __fastcall On_TSPELLXY(struct TCmdLocParam2 *pCmd, int pnum)
{
	struct TCmdLocParam2 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
			{
				ClrPlrPath(pnum);
				plr[v3].destAction = 12;
				plr[v3].destParam1 = (unsigned char)v2->x;
				plr[v3].destParam2 = (unsigned char)v2->y;
				plr[v3].destParam3 = (unsigned short)v2->wParam2;
				plr[v3]._pSpell = (unsigned short)v2->wParam1;
				plr[v3]._pSplType = plr[v3]._pTSplType;
				plr[v3]._pSplFrom = 2;
			}
			else
			{
				msg_errorf("%s has cast an illegal spell.", plr[v3]._pName);
			}
		}
	}
	return 7;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E61A) --------------------------------------------------------
int __fastcall On_OPOBJXY(struct TCmdLocParam1 *pCmd, int pnum)
{
	struct TCmdLocParam1 *v2; // esi
	int v3; // edi
	int v4; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			v4 = (unsigned short)pCmd->wParam1;
			if ( object[v4]._oSolidFlag || object[v4]._oDoorFlag )
				MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0);
			else
				MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 1u);
			plr[v3].destAction = 13;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E68A) --------------------------------------------------------
int __fastcall On_DISARMXY(struct TCmdLocParam1 *pCmd, int pnum)
{
	struct TCmdLocParam1 *v2; // esi
	int v3; // edi
	int v4; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			v4 = (unsigned short)pCmd->wParam1;
			if ( object[v4]._oSolidFlag || object[v4]._oDoorFlag )
				MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0);
			else
				MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 1u);
			plr[v3].destAction = 14;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E6FA) --------------------------------------------------------
int __fastcall On_OPOBJT(struct TCmdParam1 *pCmd, int pnum)
{
	int v2; // eax

	if ( gbBufferMsgs != 1 )
	{
		v2 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			plr[v2].destAction = 18;
			plr[v2].destParam1 = (unsigned short)pCmd->wParam1;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E732) --------------------------------------------------------
int __fastcall On_ATTACKID(struct TCmdParam1 *pCmd, int pnum)
{
	int v2; // ebp
	struct TCmdParam1 *v3; // edi
	int v4; // esi
	int v5; // ebx
	int v6; // eax

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v4 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			v5 = abs(plr[v4].WorldX - monster[(unsigned short)pCmd->wParam1]._mfutx);
			v6 = abs(plr[v4].WorldY - monster[(unsigned short)v3->wParam1]._mfuty);
			if ( v5 > 1 || v6 > 1 )
				MakePlrPath(
					v2,
					monster[(unsigned short)v3->wParam1]._mfutx,
					monster[(unsigned short)v3->wParam1]._mfuty,
					0);
			plr[v4].destAction = 20;
			plr[v4].destParam1 = (unsigned short)v3->wParam1;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E7DF) --------------------------------------------------------
int __fastcall On_ATTACKPID(struct TCmdParam1 *pCmd, int pnum)
{
	struct TCmdParam1 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			MakePlrPath(pnum, plr[(unsigned short)pCmd->wParam1]._px, plr[(unsigned short)pCmd->wParam1]._py, 0);
			plr[v3].destAction = 21;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E840) --------------------------------------------------------
int __fastcall On_RATTACKID(struct TCmdParam1 *pCmd, int pnum)
{
	struct TCmdParam1 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			ClrPlrPath(pnum);
			plr[v3].destAction = 22;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E885) --------------------------------------------------------
int __fastcall On_RATTACKPID(struct TCmdParam1 *pCmd, int pnum)
{
	struct TCmdParam1 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			ClrPlrPath(pnum);
			plr[v3].destAction = 23;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E8CA) --------------------------------------------------------
int __fastcall On_SPELLID(struct TCmdLocParam2 *pCmd, int pnum)
{
	struct TCmdLocParam2 *v2; // edi
	int v3; // esi
	int v4; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
			{
				ClrPlrPath(pnum);
				plr[v3].destAction = 24;
				plr[v3].destParam1 = *(unsigned short *)&v2->x;
				plr[v3].destParam2 = (unsigned short)v2->wParam2;
				v4 = (unsigned short)v2->wParam1;
				plr[v3]._pSplFrom = 0;
				plr[v3]._pSpell = v4;
				plr[v3]._pSplType = plr[v3]._pRSplType;
			}
			else
			{
				msg_errorf("%s has cast an illegal spell.", plr[v3]._pName);
			}
		}
	}
	return 7;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E964) --------------------------------------------------------
int __fastcall On_SPELLPID(struct TCmdLocParam2 *pCmd, int pnum)
{
	struct TCmdLocParam2 *v2; // edi
	int v3; // esi
	int v4; // eax

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
			{
				ClrPlrPath(pnum);
				plr[v3].destAction = 25;
				plr[v3].destParam1 = *(unsigned short *)&v2->x;
				plr[v3].destParam2 = (unsigned short)v2->wParam2;
				v4 = (unsigned short)v2->wParam1;
				plr[v3]._pSplFrom = 0;
				plr[v3]._pSpell = v4;
				plr[v3]._pSplType = plr[v3]._pRSplType;
			}
			else
			{
				msg_errorf("%s has cast an illegal spell.", plr[v3]._pName);
			}
		}
	}
	return 7;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043E9FE) --------------------------------------------------------
int __fastcall On_TSPELLID(struct TCmdLocParam2 *pCmd, int pnum)
{
	struct TCmdLocParam2 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
			{
				ClrPlrPath(pnum);
				plr[v3].destAction = 24;
				plr[v3].destParam1 = *(unsigned short *)&v2->x;
				plr[v3].destParam2 = (unsigned short)v2->wParam2;
				plr[v3]._pSpell = (unsigned short)v2->wParam1;
				plr[v3]._pSplType = plr[v3]._pTSplType;
				plr[v3]._pSplFrom = 2;
			}
			else
			{
				msg_errorf("%s has cast an illegal spell.", plr[v3]._pName);
			}
		}
	}
	return 7;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EA98) --------------------------------------------------------
int __fastcall On_TSPELLPID(struct TCmdLocParam2 *pCmd, int pnum)
{
	struct TCmdLocParam2 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( currlevel || *(_DWORD *)&spelldata[(unsigned short)pCmd->wParam1].sTownSpell )
			{
				ClrPlrPath(pnum);
				plr[v3].destAction = 25;
				plr[v3].destParam1 = *(unsigned short *)&v2->x;
				plr[v3].destParam2 = (unsigned short)v2->wParam2;
				plr[v3]._pSpell = (unsigned short)v2->wParam1;
				plr[v3]._pSplType = plr[v3]._pTSplType;
				plr[v3]._pSplFrom = 2;
			}
			else
			{
				msg_errorf("%s has cast an illegal spell.", plr[v3]._pName);
			}
		}
	}
	return 7;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EB32) --------------------------------------------------------
int __fastcall On_KNOCKBACK(struct TCmdParam1 *pCmd, int pnum)
{
	int v2; // edi
	struct TCmdParam1 *v3; // esi

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel )
	{
		M_GetKnockback((unsigned short)pCmd->wParam1);
		M_StartHit((unsigned short)v3->wParam1, v2, 0);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EB74) --------------------------------------------------------
int __fastcall On_RESURRECT(struct TCmdParam1 *pCmd, int pnum)
{
	int v2; // esi

	v2 = pnum;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		DoResurrect(pnum, (unsigned short)pCmd->wParam1);
		check_update_plr(v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EBA4) --------------------------------------------------------
int __fastcall On_HEALOTHER(struct TCmdParam1 *pCmd, int pnum)
{
	if ( gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel )
		DoHealOther(pnum, (unsigned short)pCmd->wParam1);
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EBD5) --------------------------------------------------------
int __fastcall On_TALKXY(struct TCmdLocParam1 *pCmd, int pnum)
{
	struct TCmdLocParam1 *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			MakePlrPath(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, 0);
			plr[v3].destAction = 17;
			plr[v3].destParam1 = (unsigned short)v2->wParam1;
		}
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EC27) --------------------------------------------------------
int __fastcall On_NEWLVL(struct TCmdParam2 *pCmd, int pnum)
{
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 5);
	}
	else if ( pnum != myplr )
	{
		StartNewLvl(pnum, (unsigned short)pCmd->wParam1, (unsigned short)pCmd->wParam2);
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EC5B) --------------------------------------------------------
int __fastcall On_WARP(struct TCmdParam1 *pCmd, int pnum)
{
	int v2; // esi

	v2 = pnum;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		StartWarpLvl(pnum, (unsigned short)pCmd->wParam1);
		if ( v2 == myplr && pcurs >= CURSOR_FIRSTITEM )
		{
			qmemcpy(&items[127], &plr[myplr].HoldItem, sizeof(ItemStruct));
			AutoGetItem(myplr, 127);
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043ECBA) --------------------------------------------------------
int __fastcall On_MONSTDEATH(struct TCmdLocParam1 *pCmd, int pnum)
{
	struct TCmdLocParam1 *v2; // esi
	unsigned char *v3; // edi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 5);
	}
	else if ( pnum != myplr )
	{
		v3 = (unsigned char *)&plr[pnum].plrlevel;
		if ( currlevel == *(_DWORD *)v3 )
			M_SyncStartKill((unsigned short)pCmd->wParam1, (unsigned char)pCmd->x, (unsigned char)pCmd->y, pnum);
		delta_kill_monster((unsigned short)v2->wParam1, v2->x, v2->y, *v3);
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043ED23) --------------------------------------------------------
int __fastcall On_KILLGOLEM(struct TCmdLocParam1 *pCmd, int pnum)
{
	int v2; // edi
	struct TCmdLocParam1 *v3; // esi

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 5);
	}
	else if ( pnum != myplr )
	{
		if ( currlevel == pCmd->wParam1 )
			M_SyncStartKill(pnum, (unsigned char)pCmd->x, (unsigned char)pCmd->y, pnum);
		delta_kill_monster(v2, v3->x, v3->y, plr[v2].plrlevel);
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043ED89) --------------------------------------------------------
int __fastcall On_AWAKEGOLEM(struct TCmdGolem *pCmd, int pnum)
{
	int v2; // esi
	int v3; // eax
	signed int v4; // ebp
	int v5; // edi
	int v6; // edx

	v2 = pnum;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 10);
	}
	else
	{
		v3 = 21720 * pnum;
		if ( currlevel == plr[pnum].plrlevel )
		{
			if ( pnum != myplr )
			{
				v4 = 1;
				v5 = 0;
				if ( nummissiles <= 0 )
					goto LABEL_16;
				do
				{
					v6 = missileactive[v5];
					if ( missile[v6]._mitype == 33 && missile[v6]._misource == v2 )
						v4 = 0;
					++v5;
				}
				while ( v5 < nummissiles );
				if ( v4 )
LABEL_16:
					AddMissile(
						*(int *)((char *)&plr[0].WorldX + v3),
						*(int *)((char *)&plr[0].WorldY + v3),
						(unsigned char)pCmd->_mx,
						(unsigned char)pCmd->_my,
						(unsigned char)pCmd->_mdir,
						33,
						0,
						v2,
						0,
						1);
			}
		}
		else
		{
			_LOBYTE(v3) = pCmd->_currlevel;
			delta_sync_golem(pCmd, pnum, v3);
		}
	}
	return 10;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EE3D) --------------------------------------------------------
int __fastcall On_MONSTDAMAGE(struct TCmdLocParam1 *pCmd, int pnum)
{
	int v2; // edi
	struct TCmdLocParam1 *v3; // edx
	unsigned char *v4; // ebx
	char *v5; // esi
	int *v6; // ecx
	int *v7; // eax

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(v2, pCmd, 5);
	}
	else if ( v2 != myplr )
	{
		v4 = (unsigned char *)&plr[v2].plrlevel;
		if ( currlevel == *(_DWORD *)v4 )
		{
			v5 = &monster[*(unsigned short *)&pCmd->x].mWhoHit;
			*v5 |= 1 << v2;
			v6 = &monster[*(unsigned short *)&pCmd->x]._mhitpoints;
			if ( *v6 )
			{
				*v6 -= (unsigned short)v3->wParam1;
				v7 = &monster[*(unsigned short *)&v3->x]._mhitpoints;
				if ( (signed int)(*v7 & 0xFFFFFFC0) < 64 )
					*v7 = 64;
				delta_monster_hp(*(unsigned short *)&v3->x, monster[*(unsigned short *)&v3->x]._mhitpoints, *v4);
			}
		}
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EEF5) --------------------------------------------------------
int __fastcall On_PLRDEAD(struct TCmdParam1 *pCmd, int pnum)
{
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else if ( pnum == myplr )
	{
		check_update_plr(pnum);
	}
	else
	{
		StartPlayerKill(pnum, (unsigned short)pCmd->wParam1);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EF2D) --------------------------------------------------------
int __fastcall On_PLRDAMAGE(struct TCmdDamage *pCmd, int pnum)
{
	int v2; // edi
	int v3; // eax
	int v4; // esi
	int *v5; // esi
	int v6; // ecx

	v2 = myplr;
	if ( (unsigned char)pCmd->bPlr == myplr )
	{
		if ( currlevel )
		{
			if ( gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel && pCmd->dwDam <= 0x2EE00u )
			{
				v3 = myplr;
				v4 = plr[myplr]._pHitPoints;
				if ( (signed int)(v4 & 0xFFFFFFC0) > 0 )
				{
					drawhpflag = 1;
					plr[v3]._pHitPoints = v4 - pCmd->dwDam;
					v5 = &plr[v3]._pHPBase;
					*v5 -= pCmd->dwDam;
					v6 = plr[v3]._pMaxHP;
					if ( plr[v3]._pHitPoints > v6 )
					{
						plr[v3]._pHitPoints = v6;
						*v5 = plr[v3]._pMaxHPBase;
					}
					if ( (signed int)(plr[v3]._pHitPoints & 0xFFFFFFC0) <= 0 )
						SyncPlrKill(v2, 1);
				}
			}
		}
	}
	return 6;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043EFDD) --------------------------------------------------------
int __fastcall On_OPENDOOR(struct TCmdParam1 *pCmd, int pnum)
{
	struct TCmdParam1 *v2; // edi
	unsigned char *v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v3 = (unsigned char *)&plr[pnum].plrlevel;
		if ( currlevel == *(_DWORD *)v3 )
			SyncOpObject(pnum, 43, (unsigned short)pCmd->wParam1);
		delta_sync_object((unsigned short)v2->wParam1, 0x2Bu, *v3);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F033) --------------------------------------------------------
void __fastcall delta_sync_object(int oi, unsigned char bCmd, unsigned char bLevel)
{
	if ( gbMaxPlayers != 1 )
	{
		sgbDeltaChanged = 1;
		sgLevels[bLevel].object[oi].bCmd = bCmd;
	}
}
// 67618C: using guessed type char sgbDeltaChanged;
// 679660: using guessed type char gbMaxPlayers;

//----- (0043F058) --------------------------------------------------------
int __fastcall On_CLOSEDOOR(struct TCmdParam1 *pCmd, int pnum)
{
	struct TCmdParam1 *v2; // edi
	unsigned char *v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v3 = (unsigned char *)&plr[pnum].plrlevel;
		if ( currlevel == *(_DWORD *)v3 )
			SyncOpObject(pnum, 44, (unsigned short)pCmd->wParam1);
		delta_sync_object((unsigned short)v2->wParam1, 0x2Cu, *v3);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F0AE) --------------------------------------------------------
int __fastcall On_OPERATEOBJ(struct TCmdParam1 *pCmd, int pnum)
{
	struct TCmdParam1 *v2; // edi
	unsigned char *v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v3 = (unsigned char *)&plr[pnum].plrlevel;
		if ( currlevel == *(_DWORD *)v3 )
			SyncOpObject(pnum, 45, (unsigned short)pCmd->wParam1);
		delta_sync_object((unsigned short)v2->wParam1, 0x2Du, *v3);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F104) --------------------------------------------------------
int __fastcall On_PLROPOBJ(struct TCmdParam2 *pCmd, int pnum)
{
	struct TCmdParam2 *v2; // esi
	unsigned char *v3; // edi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 5);
	}
	else
	{
		v3 = (unsigned char *)&plr[pnum].plrlevel;
		if ( currlevel == *(_DWORD *)v3 )
			SyncOpObject((unsigned short)pCmd->wParam1, 46, (unsigned short)pCmd->wParam2);
		delta_sync_object((unsigned short)v2->wParam2, 0x2Eu, *v3);
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F15C) --------------------------------------------------------
int __fastcall On_BREAKOBJ(struct TCmdParam2 *pCmd, int pnum)
{
	struct TCmdParam2 *v2; // esi
	unsigned char *v3; // edi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 5);
	}
	else
	{
		v3 = (unsigned char *)&plr[pnum].plrlevel;
		if ( currlevel == *(_DWORD *)v3 )
			SyncBreakObj((unsigned short)pCmd->wParam1, (unsigned short)pCmd->wParam2);
		delta_sync_object((unsigned short)v2->wParam2, 0x2Fu, *v3);
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F1B0) --------------------------------------------------------
int __fastcall On_CHANGEPLRITEMS(struct TCmdChItem *pCmd, int pnum)
{
	int v2; // eax
	int v3; // edx
	int v4; // ST04_4
	int v5; // edx

	v2 = pnum;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 11);
	}
	else if ( pnum != myplr )
	{
		v3 = (unsigned char)pCmd->bId;
		_LOWORD(v3) = pCmd->wCI;
		v4 = v3;
		v5 = (unsigned short)pCmd->wIndx;
		_LOBYTE(v5) = pCmd->bLoc;
		CheckInvSwap(v2, v5, (unsigned short)pCmd->wIndx, v4, pCmd->dwSeed, (unsigned char)pCmd->bId);
	}
	return 11;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F1F0) --------------------------------------------------------
int __fastcall On_DELPLRITEMS(struct TCmdDelItem *pCmd, int pnum)
{
	int v2; // eax

	v2 = pnum;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 2);
	}
	else if ( pnum != myplr )
	{
		_LOBYTE(pnum) = pCmd->bLoc;
		inv_update_rem_item(v2, pnum);
	}
	return 2;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F21E) --------------------------------------------------------
int __fastcall On_PLRLEVEL(struct TCmdParam1 *pCmd, int pnum)
{
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else if ( pCmd->wParam1 <= 0x33u && pnum != myplr )
	{
		plr[pnum]._pLevel = pCmd->wParam1;
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F258) --------------------------------------------------------
int __fastcall On_DROPITEM(struct TCmdPItem *pCmd, int pnum)
{
	if ( gbBufferMsgs == 1 )
		msg_send_packet(pnum, pCmd, 22);
	else
		delta_put_item(pCmd, (unsigned char)pCmd->x, (unsigned char)pCmd->y, plr[pnum].plrlevel);
	return 22;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F28F) --------------------------------------------------------
int __fastcall On_SEND_PLRINFO(struct TCmdPlrInfoHdr *pCmd, int pnum)
{
	struct TCmdPlrInfoHdr *v2; // esi

	v2 = pCmd;
	if ( gbBufferMsgs == 1 )
		msg_send_packet(pnum, pCmd, (unsigned short)pCmd->wBytes + 5);
	else
		multi_player_joins(pnum, pCmd, pCmd->bCmd == 2);
	return (unsigned short)v2->wBytes + 5;
}
// 676194: using guessed type char gbBufferMsgs;

int __fastcall On_ACK_PLRINFO(struct TCmdPlrInfoHdr *pCmd, int pnum)
{
  return On_SEND_PLRINFO(pCmd, pnum);
}

//----- (0043F2CE) --------------------------------------------------------
int __fastcall On_PLAYER_JOINLEVEL(struct TCmdLocParam1 *pCmd, int pnum)
{
	int v2; // ebx
	struct TCmdLocParam1 *v3; // edi
	int v4; // esi
	int v5; // ecx
	int v6; // ST08_4
	int v7; // edx
	int v8; // eax
	int v9; // ecx
	int v10; // eax
	int v11; // eax

	v2 = pnum;
	v3 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 5);
	}
	else
	{
		v4 = pnum;
		plr[pnum]._pLvlChanging = 0;
		if ( plr[pnum]._pName[0] && !plr[v4].plractive[0] )
		{
			plr[v4].plractive[0] = 1;
			++gbActivePlayers;
			EventPlrMsg("Player '%s' (level %d) just joined the game", plr[pnum]._pName, plr[v4]._pLevel);
		}
		if ( plr[v4].plractive[0] )
		{
			if ( myplr != v2 )
			{
				plr[v4].WorldX = (unsigned char)v3->x;
				plr[v4].WorldY = (unsigned char)v3->y;
				v5 = (unsigned short)v3->wParam1;
				plr[v4]._pGFXLoad = 0;
				plr[v4].plrlevel = v5;
				if ( currlevel == plr[v4].plrlevel )
				{
					LoadPlrGFX(v2, 1);
					SyncInitPlr(v2);
					if ( (signed int)(plr[v4]._pHitPoints & 0xFFFFFFC0) <= 0 )
					{
						plr[v4]._pgfxnum = 0;
						LoadPlrGFX(v2, 128);
						v6 = plr[v4]._pDFNum;
						v7 = plr[v4]._peqD[0];
						plr[v4]._pmode = PM_DEATH;
						NewPlrAnim(v2, v7, plr[v4]._pDFrames, 1);
						v8 = plr[v4]._pAnimLen;
						v9 = v8 - 1;
						plr[v4]._pVar8 = 2 * v8;
						v10 = plr[v4].WorldX;
						plr[v4]._pAnimFrame = v9;
						dFlags[v10][plr[v4].WorldY] |= 4u;
					}
					else
					{
						StartStand(v2, 0);
					}
					v11 = AddVision(plr[v4].WorldX, plr[v4].WorldY, plr[v4]._pLightRad, v2 == myplr);
					plr[v4]._plid = -1;
					plr[v4]._pvid = v11;
				}
			}
		}
	}
	return 5;
}
// 676194: using guessed type char gbBufferMsgs;
// 67862C: using guessed type char gbActivePlayers;

//----- (0043F448) --------------------------------------------------------
int __fastcall On_ACTIVATEPORTAL(DJunk *pCmd, int pnum)
{
	signed int v2; // ebx
	int v3; // edi
	DJunk *v4; // esi
	int v5; // eax
	int v6; // edx
	int v7; // ecx
	int v8; // ST0C_4
	int v9; // ST08_4
	int v10; // ST04_4

	v2 = 1;
	v3 = pnum;
	v4 = pCmd;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 9);
	}
	else
	{
		ActivatePortal(
			pnum,
			(unsigned char)pCmd->portal[0].y,
			(unsigned char)pCmd->portal[0].level,
			*(unsigned short *)&pCmd->portal[0].ltype,
			*(unsigned short *)&pCmd->portal[1].x,
			*(unsigned short *)&pCmd->portal[1].level);
		if ( v3 != myplr )
		{
			if ( currlevel )
			{
				if ( currlevel == plr[v3].plrlevel )
				{
					v6 = nummissiles;
					v7 = 0;
					if ( nummissiles <= 0 )
						goto LABEL_19;
					do
					{
						v5 = 176 * missileactive[v7];
						if ( *(int *)((char *)&missile[0]._mitype + v5) == 10
						  && *(int *)((char *)&missile[0]._misource + v5) == v3 )
						{
							v2 = 0;
						}
						++v7;
					}
					while ( v7 < nummissiles );
					if ( v2 )
LABEL_19:
						AddWarpMissile(v3, (unsigned char)v4->portal[0].y, (unsigned char)v4->portal[0].level);
				}
				else
				{
					RemovePortalMissile(v3);
				}
			}
			else
			{
				AddInTownPortal(v3);
			}
		}
		_LOBYTE(v5) = v4->portal[1].level;
		_LOBYTE(v6) = v4->portal[0].y;
		v8 = v5;
		_LOBYTE(v5) = v4->portal[1].x;
		v9 = v5;
		_LOBYTE(v5) = v4->portal[0].ltype;
		v10 = v5;
		_LOBYTE(v5) = v4->portal[0].level;
		delta_open_portal(v3, v6, v5, v10, v9, v8);
	}
	return 9;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F521) --------------------------------------------------------
void __fastcall delta_open_portal(int pnum, int x, int y, int bLevel, int bLType, int bSetLvl)
{
	int v6; // eax

	v6 = pnum;
	sgbDeltaChanged = 1;
	sgJunk[0].portal[v6].y = y;
	sgJunk[0].portal[v6].level = bLevel;
	sgJunk[0].portal[v6].ltype = bLType;
	sgJunk[0].portal[v6].x = x;
	sgJunk[0].portal[v6].setlvl = bSetLvl;
}
// 67618C: using guessed type char sgbDeltaChanged;

//----- (0043F55C) --------------------------------------------------------
int __fastcall On_DEACTIVATEPORTAL(struct TCmd *pCmd, int pnum)
{
	int v2; // esi

	v2 = pnum;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 1);
	}
	else
	{
		if ( PortalOnLevel(pnum) )
			RemovePortalMissile(v2);
		DeactivatePortal(v2);
		RemovePlrPortal(v2);
	}
	return 1;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F59A) --------------------------------------------------------
int __fastcall On_RETOWN(struct TCmd *pCmd, int pnum)
{
	int v2; // esi

	v2 = pnum;
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 1);
	}
	else
	{
		if ( pnum == myplr )
		{
			*(_DWORD *)&deathflag = 0;
			gamemenu_off();
		}
		RestartTownLvl(v2);
	}
	return 1;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F5D3) --------------------------------------------------------
int __fastcall On_SETSTR(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x2EEu && pnum != myplr )
			SetPlrStr(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F60C) --------------------------------------------------------
int __fastcall On_SETDEX(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x2EEu && pnum != myplr )
			SetPlrDex(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F645) --------------------------------------------------------
int __fastcall On_SETMAG(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x2EEu && pnum != myplr )
			SetPlrMag(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F67E) --------------------------------------------------------
int __fastcall On_SETVIT(struct TCmdParam1 *pCmd, int pnum)
{
	unsigned short v2; // cx

	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 3);
	}
	else
	{
		v2 = pCmd->wParam1;
		if ( v2 <= 0x2EEu && pnum != myplr )
			SetPlrVit(pnum, v2);
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F6B7) --------------------------------------------------------
int __fastcall On_STRING(struct TCmdString *pCmd, int pnum)
{
	const char *v2; // esi
	int v3; // edi
	size_t v4; // ebx

	v2 = pCmd->str;
	v3 = pnum;
	v4 = strlen(pCmd->str);
	if ( !gbBufferMsgs )
		SendPlrMsg(v3, v2);
	return v4 + 2;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F6EC) --------------------------------------------------------
int __fastcall On_SYNCQUEST(struct TCmdQuest *pCmd, int pnum)
{
	if ( gbBufferMsgs == 1 )
	{
		msg_send_packet(pnum, pCmd, 5);
	}
	else
	{
		if ( pnum != myplr )
			SetMultiQuest(
				(unsigned char)pCmd->q,
				(unsigned char)pCmd->qstate,
				pCmd->qlog,
				(unsigned char)pCmd->qvar1);
		sgbDeltaChanged = 1;
	}
	return 5;
}
// 67618C: using guessed type char sgbDeltaChanged;
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F72E) --------------------------------------------------------
int __fastcall On_ENDSHIELD(int a1, int pnum)
{
	int v2; // ebx
	int i; // esi
	int v4; // edi
	int v5; // eax

	v2 = pnum;
	if ( gbBufferMsgs != 1 && pnum != myplr && currlevel == plr[pnum].plrlevel )
	{
		for ( i = 0; i < nummissiles; ++i )
		{
			v4 = missileactive[i];
			v5 = missileactive[i];
			if ( missile[v5]._mitype == 13 && missile[v5]._misource == v2 )
			{
				ClearMissileSpot(missileactive[i]);
				DeleteMissile(v4, i);
			}
		}
	}
	return 1;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F7A5) --------------------------------------------------------
int __cdecl On_DEBUG()
{
	return 1;
}

//----- (0043F7A9) --------------------------------------------------------
int __fastcall On_NOVA(struct TCmdLoc *pCmd, int pnum)
{
	struct TCmdLoc *v2; // edi
	int v3; // esi

	v2 = pCmd;
	if ( gbBufferMsgs != 1 )
	{
		v3 = pnum;
		if ( currlevel == plr[pnum].plrlevel && pnum != myplr )
		{
			ClrPlrPath(pnum);
			plr[v3]._pSpell = SPL_NOVA;
			plr[v3]._pSplType = 4;
			plr[v3]._pSplFrom = 3;
			plr[v3].destAction = 12;
			plr[v3].destParam1 = (unsigned char)v2->x;
			plr[v3].destParam2 = (unsigned char)v2->y;
		}
	}
	return 3;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F818) --------------------------------------------------------
int __fastcall On_SETSHIELD(int unused, int pnum)
{
	int result; // eax

	result = 1;
	if ( gbBufferMsgs != 1 )
		plr[pnum].pManaShield = 1;
	return result;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F830) --------------------------------------------------------
int __fastcall On_REMSHIELD(int unused, int pnum)
{
	int result; // eax

	result = 1;
	if ( gbBufferMsgs != 1 )
		plr[pnum].pManaShield = 0;
	return result;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043F84E) --------------------------------------------------------
void __cdecl msgcmd_cpp_init_1()
{
	msgcmd_cpp_init_value = msgcmd_inf;
}
// 47F150: using guessed type int msgcmd_inf;
// 6761A0: using guessed type int msgcmd_cpp_init_value;

//----- (0043F859) --------------------------------------------------------
void __cdecl msgcmd_cpp_init_2()
{
	msgcmd_init_event();
	msgcmd_init_exit_event();
}

//----- (0043F863) --------------------------------------------------------
_SNETEVENT *__cdecl msgcmd_init_event()
{
	return msgcmd_clear_event(&pEvent);
}

//----- (0043F86D) --------------------------------------------------------
int __cdecl msgcmd_init_exit_event()
{
	return atexit(msgcmd_clear_all_events);
}

//----- (0043F879) --------------------------------------------------------
void __cdecl msgcmd_clear_all_events()
{
	msgcmd_wait_zero_event(&pEvent);
	msgcmd_zero_event((_SNETEVENT *)((char *)&pEvent + 4));
}

//----- (0043F88D) --------------------------------------------------------
void __cdecl msgcmd_free_pevent()
{
	msgcmd_free_event(&pEvent);
}

//----- (0043F897) --------------------------------------------------------
void __cdecl msgcmd_send_chat()
{
	char *v0; // esi
	int v1; // eax

	if ( (_DWORD)pEvent.data > 0 )
	{
		v0 = (char *)pEvent.data;
		v1 = GetTickCount();
		if ( (unsigned int)(v1 - pEvent.databytes) >= 2000 )
		{
			pEvent.databytes = v1;
			SNetSendServerChatCommand(v0 + 8);
			msgcmd_free_str_event(&pEvent);
		}
	}
}

//----- (0043F8D4) --------------------------------------------------------
int __fastcall msgcmd_check_set_event(int a1)
{
	if ( *(_BYTE *)a1 != 47 )
		return 0;
	msgcmd_set_event((const char *)a1);
	return 1;
}

//----- (0043F8E5) --------------------------------------------------------
int __fastcall msgcmd_set_event(const char *a1)
{
	const char *v1; // edi
	int result; // eax
	int v3; // edx
	size_t v4; // esi
	int v5; // eax

	v1 = a1;
	result = strlen(a1);
	if ( result )
	{
		v4 = result + 1;
		if ( (unsigned int)(result + 1) <= 0x80 )
		{
			v5 = msgcmd_alloc_event((int *)&pEvent, v3, 2, 0);
			result = (int)memcpy((void *)(v5 + 8), v1, v4);
		}
	}
	return result;
}

//----- (0043F920) --------------------------------------------------------
_SNETEVENT *__fastcall msgcmd_clear_event(_SNETEVENT *a1)
{
	_SNETEVENT *result; // eax
	int *v2; // edx

	result = a1;
	v2 = &a1->playerid;
	*v2 = 0;
	v2[1] = 0;
	*v2 = (int)v2;
	a1->eventid = 0;
	result->data = (void *)~(unsigned int)&result->playerid;
	return result;
}

//----- (0043F936) --------------------------------------------------------
bool __fastcall msgcmd_free_event(_SNETEVENT *a1)
{
	_SNETEVENT *v1; // edi
	_SNETEVENT *v2; // esi
	bool result; // al

	v1 = a1;
	while ( 1 )
	{
		v2 = (_SNETEVENT *)v1->data;
		if ( (signed int)v2 <= 0 )
			break;
		msgcmd_remove_event(v2);
		result = SMemFree(v2, ".?AUEXTERNMESSAGE@@", -2, 0);
	}
	return result;
}

//----- (0043F95E) --------------------------------------------------------
int __fastcall msgcmd_free_str_event(_SNETEVENT *a1)
{
	char *v1; // eax
	int v2; // eax
	int v3; // esi
	_SNETEVENT *ptr; // [esp+Ch] [ebp+4h]

	v1 = (char *)ptr;
	if ( !ptr )
		v1 = (char *)&a1->playerid;
	v2 = *((_DWORD *)v1 + 1);
	if ( v2 > 0 )
		v3 = v2;
	else
		v3 = 0;
	msgcmd_remove_event(ptr);
	SMemFree(ptr, ".?AUEXTERNMESSAGE@@", -2, 0);
	return v3;
}

//----- (0043F999) --------------------------------------------------------
int __fastcall msgcmd_alloc_event(int *a1, int a2, int a3, int a4)
{
	int v4; // eax
	int *v5; // edi
	int *v6; // eax
	int v7; // edx
	int *v8; // esi
	int v10; // [esp+18h] [ebp+Ch]

	v4 = v10;
	_LOBYTE(v4) = v10 | 8;
	v5 = a1;
	v6 = (int *)SMemAlloc(a4 + 136, ".?AUEXTERNMESSAGE@@", -2, v4);
	if ( v6 )
	{
		*v6 = 0;
		v6[1] = 0;
		v8 = v6;
	}
	else
	{
		v8 = 0;
	}
	if ( a3 )
		msgcmd_event_type((_SNETEVENT *)v5, v7, v8, a3);
	return (int)v8;
}

//----- (0043F9E5) --------------------------------------------------------
char *__fastcall msgcmd_remove_event(_SNETEVENT *a1)
{
	_SNETEVENT *v1; // esi
	char v3; // [esp+8h] [ebp+4h]

	v1 = a1;
	msgcmd_zero_event(a1);
	msgcmd_zero_event(v1);
	if ( v3 & 1 && v1 )
		SMemFree(v1, "delete", -1, 0);
	return (char *)v1;
}

//----- (0043FA14) --------------------------------------------------------
char *__fastcall msgcmd_event_type(_SNETEVENT *a1, int a2, int *a3, int a4)
{
	_SNETEVENT *v4; // edi
	_SNETEVENT *v5; // esi
	char *result; // eax
	int v7; // ecx
	int v8; // edx
	char *v9; // ecx
	int v10; // edx
	char *v11; // [esp+18h] [ebp+Ch]

	v4 = a1;
	v5 = (_SNETEVENT *)a3;
	if ( !a3 )
		v5 = (_SNETEVENT *)((char *)a1 + 4);
	if ( v5->eventid )
		msgcmd_zero_event(v5);
	result = v11;
	if ( !v11 )
		result = (char *)&v4->playerid;
	if ( a4 == 1 )
	{
		v5->eventid = (int)result;
		v5->playerid = *((_DWORD *)result + 1);
		v8 = *((_DWORD *)result + 1);
		v9 = (char *)v4->eventid;
		if ( v8 > 0 )
		{
			if ( (signed int)v9 < 0 )
				v9 = &result[-*(_DWORD *)(*(_DWORD *)result + 4)];
			v10 = (int)&v9[v8];
		}
		else
		{
			v10 = ~v8;
		}
		*(_DWORD *)v10 = (unsigned int)v5;
		*((_DWORD *)result + 1) = (unsigned int)a3;
	}
	else if ( a4 == 2 )
	{
		v7 = *(_DWORD *)result;
		v5->eventid = *(_DWORD *)result;
		v5->playerid = *(_DWORD *)(v7 + 4);
		*(_DWORD *)(v7 + 4) = (unsigned int)a3;
		*(_DWORD *)result = (unsigned int)v5;
	}
	return result;
}

//----- (0043FA85) --------------------------------------------------------
void __fastcall msgcmd_wait_zero_event(_SNETEVENT *a1)
{
	_SNETEVENT *v1; // esi
	_SNETEVENT *v2; // ecx

	v1 = a1;
	while ( 1 )
	{
		v2 = (_SNETEVENT *)v1->data;
		if ( (signed int)v2 <= 0 )
			break;
		msgcmd_zero_event(v2);
	}
}

//----- (0043FA98) --------------------------------------------------------
void __fastcall msgcmd_zero_event(_SNETEVENT *a1)
{
	int v1; // esi
	int v2; // edx
	int v3; // edx

	v1 = a1->eventid;
	if ( a1->eventid )
	{
		v2 = a1->playerid;
		if ( v2 > 0 )
			v3 = (int)a1 + v2 - *(_DWORD *)(v1 + 4);
		else
			v3 = ~v2;
		*(_DWORD *)v3 = v1;
		*(_DWORD *)(a1->eventid + 4) = a1->playerid;
		a1->eventid = 0;
		a1->playerid = 0;
	}
}

//----- (0043FAC9) --------------------------------------------------------
void __cdecl multi_cpp_init()
{
	multi_cpp_init_value = multi_inf;
}
// 47F154: using guessed type int multi_inf;
// 678620: using guessed type int multi_cpp_init_value;

//----- (0043FAD4) --------------------------------------------------------
void __fastcall multi_msg_add(char *a1, unsigned char a2)
{
	if ( a1 )
	{
		if ( a2 )
			tmsg_add(a1, a2);
	}
}

//----- (0043FAE2) --------------------------------------------------------
void __fastcall NetSendLoPri(unsigned char *pbMsg, unsigned char bLen)
{
	unsigned char *v2; // esi
	unsigned char v3; // bl
	int v4; // edx

	v2 = pbMsg;
	v3 = bLen;
	if ( pbMsg )
	{
		if ( bLen )
		{
			multi_copy_packet(pkdata_678658, pbMsg, bLen);
			_LOBYTE(v4) = v3;
			multi_send_packet(v2, v4);
		}
	}
}

//----- (0043FB0B) --------------------------------------------------------
void __fastcall multi_copy_packet(void *a1, void *packet, int size)
{
	int v3; // eax
	int v4; // ebx
	char *v5; // esi

	v3 = *(_DWORD *)a1;
	v4 = *(_DWORD *)a1 + (unsigned char)size;
	if ( (unsigned int)(v4 + 2) <= 0x1000 )
	{
		*(_DWORD *)a1 = v4 + 1;
		*((_BYTE *)a1 + v3 + 4) = size;
		v5 = (char *)a1 + v3 + 5;
		memcpy(v5, packet, (unsigned char)size);
		v5[(unsigned char)size] = 0;
	}
}

//----- (0043FB4D) --------------------------------------------------------
void __fastcall multi_send_packet(void *packet, int dwSize)
{
	void *v2; // esi
	unsigned char v3; // bl
	int v4; // eax
	TPkt pkt; // [esp+8h] [ebp-200h]

	v2 = packet;
	v3 = dwSize;
	NetRecvPlrData(&pkt);
	pkt.hdr.wLen = v3 + 19;
	memcpy(pkt.body, v2, v3);
	_LOBYTE(v4) = SNetSendMessage(myplr, &pkt.hdr, (unsigned short)pkt.hdr.wLen);
	if ( !v4 )
		nthread_terminate_game("SNetSendMessage0");
}

//----- (0043FBB5) --------------------------------------------------------
void __fastcall NetRecvPlrData(TPkt *pkt)
{
	pkt->hdr.wCheck = 'ip';
	pkt->hdr.px = plr[myplr].WorldX;
	pkt->hdr.py = plr[myplr].WorldY;
	pkt->hdr.targx = plr[myplr]._ptargx;
	pkt->hdr.targy = plr[myplr]._ptargy;
	pkt->hdr.php = plr[myplr]._pHitPoints;
	pkt->hdr.pmhp = plr[myplr]._pMaxHP;
	pkt->hdr.bstr = plr[myplr]._pBaseStr;
	pkt->hdr.bmag = plr[myplr]._pBaseMag;
	pkt->hdr.bdex = plr[myplr]._pBaseDex;
}

//----- (0043FC6F) --------------------------------------------------------
void __fastcall NetSendHiPri(unsigned char *pbMsg, unsigned char bLen)
{
	unsigned char *v2; // edi
	unsigned char v3; // bl
	int v4; // edx
	char *v5; // eax
	TSyncHeader *v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // eax
	TPkt pkt; // [esp+Ch] [ebp-204h]
	int size; // [esp+20Ch] [ebp-4h]

	v2 = pbMsg;
	v3 = bLen;
	if ( pbMsg && bLen )
	{
		multi_copy_packet(pkdata_6761C0, pbMsg, bLen);
		_LOBYTE(v4) = v3;
		multi_send_packet(v2, v4);
	}
	if ( !dword_678628 )
	{
		dword_678628 = 1;
		NetRecvPlrData(&pkt);
		size = gdwNormalMsgSize - 19;
		v5 = multi_recv_packet(pkdata_6761C0, pkt.body, &size);
		v6 = (TSyncHeader *)multi_recv_packet(pkdata_678658, v5, &size);
		v7 = sync_all_monsters(v6, size);
		size = v7;
		v8 = gdwNormalMsgSize - v7;
		pkt.hdr.wLen = v8;
		_LOBYTE(v9) = SNetSendMessage(-2, &pkt.hdr, v8);
		if ( !v9 )
			nthread_terminate_game("SNetSendMessage");
	}
}
// 678628: using guessed type int dword_678628;
// 679760: using guessed type int gdwNormalMsgSize;

//----- (0043FD27) --------------------------------------------------------
char *__fastcall multi_recv_packet(void *packet, char *a2, int *a3)
{
	char *v3; // esi
	char *result; // eax
	char *v5; // ebx
	size_t v6; // edi
	char *v7; // ebx
	char *v8; // [esp+4h] [ebp-4h]

	v3 = (char *)packet;
	result = a2;
	v8 = a2;
	if ( *(_DWORD *)packet )
	{
		v5 = (char *)packet + 4;
		while ( *v5 )
		{
			v6 = (unsigned char)*v5;
			if ( v6 > *a3 )
				break;
			v7 = v5 + 1;
			memcpy(v8, v7, v6);
			v8 += v6;
			v5 = &v7[v6];
			*a3 -= v6;
		}
		memcpy(v3 + 4, v5, (size_t)&v3[*(_DWORD *)v3 - (_DWORD)v5 + 5]);
		*(_DWORD *)v3 += v3 - v5 + 4;
		result = v8;
	}
	return result;
}

//----- (0043FD90) --------------------------------------------------------
void __fastcall multi_send_msg_packet(int a1, char *a2, unsigned char len)
{
	const void *v3; // edx
	signed int v4; // ebx
	unsigned int v5; // edi
	int v6; // eax
	TPkt pkt; // [esp+Ch] [ebp-204h]
	int v8; // [esp+20Ch] [ebp-4h]

	v8 = a1;
	NetRecvPlrData(&pkt);
	pkt.hdr.wLen = len + 19;
	memcpy(pkt.body, v3, len);
	v4 = 1;
	v5 = 0;
	while ( 1 )
	{
		if ( v4 & v8 )
		{
			_LOBYTE(v6) = SNetSendMessage(v5, &pkt.hdr, len + 19);
			if ( !v6 && SErrGetLastError() != 0x8510006A )
				break;
		}
		++v5;
		v4 *= 2;
		if ( v5 >= 4 )
			return;
	}
	nthread_terminate_game("SNetSendMessage");
}

//----- (0043FE0E) --------------------------------------------------------
void __cdecl multi_msg_countdown()
{
	int v0; // esi

	v0 = 0;
	do
	{
		if ( player_state[v0] & 0x20000 )
		{
			if ( gdwMsgLenTbl[v0] == 4 )
				multi_start_countdown(v0, *(_DWORD *)glpMsgTbl[v0]);
		}
		++v0;
	}
	while ( v0 < 4 );
}

//----- (0043FE3D) --------------------------------------------------------
int __fastcall multi_start_countdown(int pnum, int a2)
{
	int v2; // esi
	int result; // eax
	unsigned int v4; // esi

	v2 = a2;
	if ( a2 < 0 )
		multi_wait_delta_send(pnum);
	result = gdwTurnsInTransit;
	v4 = v2 & 0x7FFFFFFF;
	if ( sgbSentThisCycle < gdwTurnsInTransit + v4 )
	{
		if ( v4 >= 0x7FFFFFFF )
			v4 = (unsigned short)v4;
		sgbSentThisCycle = v4 + gdwTurnsInTransit;
		result = 4 * v4 * (unsigned char)byte_679704;
		sgdwGameLoops = 4 * v4 * (unsigned char)byte_679704;
	}
	return result;
}
// 679704: using guessed type char byte_679704;
// 679738: using guessed type int gdwTurnsInTransit;

//----- (0043FE85) --------------------------------------------------------
void __fastcall multi_wait_delta_send(int pnum)
{
	signed int v1; // eax

	v1 = 0;
	do
	{
		if ( player_state[v1] & 0x10000 && v1 != pnum )
			break;
		++v1;
	}
	while ( v1 < 4 );
	if ( myplr == v1 )
	{
		sgbSendDeltaTbl[pnum] = 1;
	}
	else if ( myplr == pnum )
	{
		gbDeltaSender = v1;
	}
}
// 6796E4: using guessed type char gbDeltaSender;

//----- (0043FEB7) --------------------------------------------------------
void __fastcall multi_player_left(int pnum, int reason)
{
	sgbPlayerLeftGameTbl[pnum] = 1;
	sgdwPlayerLeftReasonTbl[pnum] = reason;
	multi_clear_left_tbl();
}

//----- (0043FECA) --------------------------------------------------------
void __cdecl multi_clear_left_tbl()
{
	int v0; // esi

	v0 = 0;
	do
	{
		if ( sgbPlayerLeftGameTbl[v0] )
		{
			if ( gbBufferMsgs == 1 )
				msg_send_drop_pkt(v0, sgdwPlayerLeftReasonTbl[v0]);
			else
				multi_player_left_msg(v0, 1);
			sgbPlayerLeftGameTbl[v0] = 0;
			sgdwPlayerLeftReasonTbl[v0] = 0;
		}
		++v0;
	}
	while ( v0 < 4 );
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0043FF0E) --------------------------------------------------------
void __fastcall multi_player_left_msg(int pnum, int left)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	char *v5; // eax
	int v6; // edi

	v2 = pnum;
	v3 = left;
	v4 = pnum;
	if ( plr[pnum].plractive[0] )
	{
		RemovePlrFromMap(pnum);
		RemovePortalMissile(v2);
		DeactivatePortal(v2);
		RemovePlrPortal(v2);
		RemovePlrMissiles(v2);
		if ( v3 )
		{
			v5 = "Player '%s' just left the game";
			v6 = sgdwPlayerLeftReasonTbl[v2] - 0x40000004;
			if ( v6 )
			{
				if ( v6 == 2 )
					v5 = "Player '%s' dropped due to timeout";
			}
			else
			{
				v5 = "Player '%s' killed Diablo and left the game!";
				gbSomebodyWonGameKludge = 1;
			}
			EventPlrMsg(v5, plr[v4]._pName);
		}
		plr[v4].plractive[0] = 0;
		plr[v4]._pName[0] = 0;
		--gbActivePlayers;
	}
}
// 6761B8: using guessed type char gbSomebodyWonGameKludge;
// 67862C: using guessed type char gbActivePlayers;

//----- (0043FF9D) --------------------------------------------------------
void __cdecl multi_net_ping()
{
	sgbTimeout = 1;
	sglTimeoutStart = GetTickCount();
}
// 678644: using guessed type int sglTimeoutStart;
// 679661: using guessed type char sgbTimeout;

//----- (0043FFB0) --------------------------------------------------------
int __cdecl multi_handle_delta()
{
	int v0; // esi
	int v1; // eax
	bool recieved[4]; // [esp+4h] [ebp-4h]

	if ( gbGameDestroyed )
	{
		gbRunGame = 0;
		return 0;
	}
	v0 = 0;
	do
	{
		if ( sgbSendDeltaTbl[v0] )
		{
			sgbSendDeltaTbl[v0] = 0;
			msg_do_sync(v0);
		}
		++v0;
	}
	while ( v0 < 4 );
	sgbSentThisCycle = nthread_send_and_recv_turn(sgbSentThisCycle, 1);
	nthread_recv_turns(recieved);
	if ( !v1 )
	{
		multi_begin_timeout();
		return 0;
	}
	sgbTimeout = 0;
	if ( *(_DWORD *)recieved )
	{
		if ( dword_678628 )
		{
			dword_678628 = 0;
			if ( !multi_check_pkt_valid(pkdata_6761C0) )
				NetSendHiPri(0, 0);
		}
		else
		{
			NetSendHiPri(0, 0);
			dword_678628 = 0;
		}
	}
	multi_mon_seeds();
	return 1;
}
// 525650: using guessed type int gbRunGame;
// 678628: using guessed type int dword_678628;
// 67862D: using guessed type char gbGameDestroyed;
// 679661: using guessed type char sgbTimeout;

//----- (00440058) --------------------------------------------------------
// Microsoft VisualC 2-11/net runtime
int __fastcall multi_check_pkt_valid(char *a1)
{
	return *(_DWORD *)a1 == 0;
}

//----- (00440060) --------------------------------------------------------
void __cdecl multi_mon_seeds()
{
	unsigned int v0; // eax
	int v1; // edx
	int *v2; // ecx
	int v3; // esi

	v0 = _rotr(++sgdwGameLoops, 8);
	v1 = 0;
	v2 = &monster[0]._mAISeed;
	do
	{
		v3 = v1++ + v0;
		*v2 = v3;
		v2 += 57;
	}
	while ( (signed int)v2 < (signed int)&Monsters[0].Anims[3].Rate );
}

//----- (00440093) --------------------------------------------------------
void __cdecl multi_begin_timeout()
{
	unsigned char v0; // bl
	signed __int32 v1; // eax
	signed int v2; // esi
	signed int v3; // edi
	signed int v4; // eax
	int v5; // edx
	unsigned char v6; // [esp+Fh] [ebp-1h]

	v0 = 0;
	if ( sgbTimeout )
	{
		v1 = GetTickCount() - sglTimeoutStart;
		if ( v1 <= 20000 )
		{
			if ( v1 >= 10000 )
			{
				v6 = 0;
				v2 = -1;
				v3 = -1;
				v4 = 0;
				do
				{
					v5 = player_state[v4];
					if ( v5 & 0x10000 )
					{
						if ( v3 == -1 )
							v3 = v4;
						if ( v5 & 0x40000 )
						{
							++v0;
							if ( v2 == -1 )
								v2 = v4;
						}
						else
						{
							++v6;
						}
					}
					++v4;
				}
				while ( v4 < 4 );
				if ( v0 >= v6 && (v0 != v6 || v3 == v2) )
				{
					if ( v2 == myplr )
						multi_check_drop_player();
				}
				else
				{
					gbGameDestroyed = 1;
				}
			}
		}
		else
		{
			gbRunGame = 0;
		}
	}
}
// 525650: using guessed type int gbRunGame;
// 67862D: using guessed type char gbGameDestroyed;
// 678644: using guessed type int sglTimeoutStart;
// 679661: using guessed type char sgbTimeout;

//----- (00440128) --------------------------------------------------------
void __cdecl multi_check_drop_player()
{
	int v0; // esi
	int v1; // eax

	v0 = 0;
	do
	{
		v1 = player_state[v0];
		if ( !(v1 & 0x40000) )
		{
			if ( v1 & 0x10000 )
				SNetDropPlayer(v0, 0x40000006);
		}
		++v0;
	}
	while ( v0 < 4 );
}

//----- (00440153) --------------------------------------------------------
void __cdecl multi_process_network_packets()
{
	int v0; // eax
	TPktHdr *v1; // ecx
	TPktHdr *v2; // edi
	int v3; // eax
	bool v4; // zf
	char *v5; // esi
	int v6; // ebx
	int v7; // eax
	int v8; // ecx
	int v9; // eax
	int v10; // eax
	int v11; // esi
	int v12; // eax
	int v13; // ecx
	int v14; // eax
	int v15; // eax
	TPktHdr *pkt; // [esp+0h] [ebp-Ch]
	int len; // [esp+4h] [ebp-8h]
	char arglist[4]; // [esp+8h] [ebp-4h]

	multi_clear_left_tbl();
	multi_start_packets();
	_LOBYTE(v0) = SNetReceiveMessage((int *)arglist, (char **)&pkt, &len);
	if ( v0 )
	{
		do
		{
			++dword_676198;
			multi_clear_left_tbl();
			v1 = pkt;
			v2 = pkt;
			if ( (unsigned int)len >= 0x13
			  && *(_DWORD *)arglist < 4u
			  && pkt->wCheck == 'ip'
			  && (unsigned short)pkt->wLen == len )
			{
				v3 = *(_DWORD *)arglist;
				v4 = *(_DWORD *)arglist == myplr;
				plr[v3]._pownerx = (unsigned char)pkt->px;
				v5 = &v1->py;
				plr[v3]._pownery = (unsigned char)v1->py;
				if ( !v4 )
				{
					v4 = gbBufferMsgs == 1;
					plr[v3]._pHitPoints = v1->php;
					plr[v3]._pMaxHP = v1->pmhp;
					plr[v3]._pBaseStr = (unsigned char)v1->bstr;
					plr[v3]._pBaseMag = (unsigned char)v1->bmag;
					plr[v3]._pBaseDex = (unsigned char)v1->bdex;
					if ( !v4 && plr[v3].plractive[0] && plr[v3]._pHitPoints )
					{
						if ( currlevel != plr[v3].plrlevel || plr[v3]._pLvlChanging )
						{
							plr[v3].WorldX = (unsigned char)v1->px;
							plr[v3].WorldY = (unsigned char)*v5;
							plr[v3]._px = (unsigned char)v1->px;
							plr[v3]._py = (unsigned char)*v5;
							plr[v3]._ptargx = (unsigned char)v1->targx;
							plr[v3]._ptargy = (unsigned char)v1->targy;
						}
						else
						{
							v6 = abs(plr[v3].WorldX - (unsigned char)v1->px);
							v7 = abs(plr[*(_DWORD *)arglist].WorldY - (unsigned char)*v5);
							if ( (v6 > 3 || v7 > 3) && !dPlayer[(unsigned char)v2->px][(unsigned char)*v5] )
							{
								FixPlrWalkTags(*(int *)arglist);
								v8 = *(_DWORD *)arglist;
								v9 = *(_DWORD *)arglist;
								plr[v9]._poldx = plr[*(_DWORD *)arglist].WorldX;
								plr[v9]._poldy = plr[v9].WorldY;
								FixPlrWalkTags(v8);
								v10 = *(_DWORD *)arglist;
								plr[v10].WorldX = (unsigned char)v2->px;
								plr[v10].WorldY = (unsigned char)*v5;
								plr[v10]._px = (unsigned char)v2->px;
								plr[v10]._py = (unsigned char)*v5;
								dPlayer[plr[v10].WorldX][plr[v10].WorldY] = arglist[0] + 1;
							}
							v11 = abs(plr[*(_DWORD *)arglist]._px - plr[*(_DWORD *)arglist].WorldX);
							v12 = abs(plr[*(_DWORD *)arglist]._py - plr[*(_DWORD *)arglist].WorldY);
							v13 = *(_DWORD *)arglist;
							if ( v11 > 1 || v12 > 1 )
							{
								v14 = *(_DWORD *)arglist;
								plr[v14]._px = plr[*(_DWORD *)arglist].WorldX;
								plr[v14]._py = plr[v13].WorldY;
							}
							MakePlrPath(v13, (unsigned char)v2->targx, (unsigned char)v2->targy, 1u);
						}
					}
				}
				multi_handle_all_packets(*(int *)arglist, (TPkt *)&v2[1], len - 19);
			}
			_LOBYTE(v15) = SNetReceiveMessage((int *)arglist, (char **)&pkt, &len);
		}
		while ( v15 );
	}
	if ( SErrGetLastError() != 0x8510006B )
		nthread_terminate_game("SNetReceiveMsg");
}
// 676194: using guessed type char gbBufferMsgs;
// 676198: using guessed type int dword_676198;

//----- (0044041D) --------------------------------------------------------
void __fastcall multi_handle_all_packets(int players, TPkt *packet, int a3)
{
	TCmd *v3; // esi
	int i; // edi
	int v5; // eax

	v3 = (TCmd *)packet;
	for ( i = players; a3; a3 -= v5 )
	{
		v5 = ParseCmd(i, v3);
		if ( !v5 )
			break;
		v3 += v5;
	}
}

//----- (00440444) --------------------------------------------------------
void __cdecl multi_start_packets()
{
	int v0; // eax
	TPkt pkt; // [esp+0h] [ebp-200h]

	while ( 1 )
	{
		v0 = tmsg_get(&pkt.hdr.px, 512);
		if ( !v0 )
			break;
		multi_handle_all_packets(myplr, &pkt, v0);
	}
}

//----- (00440477) --------------------------------------------------------
void __fastcall multi_send_zero_packet(int pnum, char a2, void *ptr, int len)
{
	unsigned int v4; // edi
	short v5; // si
	unsigned short v6; // ax
	int v7; // eax
	TPkt pkt; // [esp+Ch] [ebp-208h]
	int pnuma; // [esp+20Ch] [ebp-8h]
	int v10; // [esp+210h] [ebp-4h]

	v4 = len;
	_LOBYTE(v10) = a2;
	pnuma = pnum;
	v5 = 0;
	while ( v4 )
	{
		pkt.hdr.wCheck = 'ip';
		pkt.body[0] = v10;
		v6 = gdwLargestMsgSize - 24;
		pkt.hdr.px = 0;
		pkt.hdr.py = 0;
		pkt.hdr.targx = 0;
		pkt.hdr.targy = 0;
		pkt.hdr.php = 0;
		pkt.hdr.pmhp = 0;
		pkt.hdr.bstr = 0;
		pkt.hdr.bmag = 0;
		pkt.hdr.bdex = 0;
		*(_WORD *)&pkt.body[1] = v5;
		if ( v4 < gdwLargestMsgSize - 24 )
			v6 = v4;
		*(_WORD *)&pkt.body[3] = v6;
		memcpy(&pkt.body[5], ptr, v6);
		pkt.hdr.wLen = *(_WORD *)&pkt.body[3] + 24;
		_LOBYTE(v7) = SNetSendMessage(pnuma, &pkt.hdr, *(unsigned short *)&pkt.body[3] + 24);
		if ( !v7 )
		{
			nthread_terminate_game("SNetSendMessage2");
			return;
		}
		ptr = (char *)ptr + *(unsigned short *)&pkt.body[3];
		v4 -= *(unsigned short *)&pkt.body[3];
		v5 += *(_WORD *)&pkt.body[3];
	}
}
// 67975C: using guessed type int gdwLargestMsgSize;

//----- (0044055D) --------------------------------------------------------
void __cdecl NetClose()
{
	if ( sgbNetInited )
	{
		sgbNetInited = 0;
		nthread_cleanup();
		dthread_cleanup();
		tmsg_cleanup();
		multi_event_handler(0);
		SNetLeaveGame(3);
		msgcmd_free_pevent();
		if ( (unsigned char)gbMaxPlayers > 1u )
			Sleep(0x7D0u);
	}
}
// 679660: using guessed type char gbMaxPlayers;
// 6796E8: using guessed type int sgbNetInited;

//----- (004405A4) --------------------------------------------------------
char __fastcall multi_event_handler(int a1)
{
	int v1; // edi
	void *(__stdcall *v2)(int, void (__stdcall *)(_SNETEVENT *)); // ebx
	unsigned int v3; // esi
	int v4; // eax
	char *v5; // eax

	v1 = a1;
	v2 = SNetRegisterEventHandler;
	if ( !a1 )
		v2 = SNetUnregisterEventHandler;
	v3 = 0;
	do
	{
		_LOBYTE(v4) = (unsigned char)v2(event_types[v3], multi_handle_events);
		if ( !v4 && v1 )
		{
			v5 = GetLastErr();
			TermMsg("SNetRegisterEventHandler:\n%s", v5);
		}
		++v3;
	}
	while ( v3 < 3 );
	return v4;
}

//----- (004405EC) --------------------------------------------------------
void __stdcall multi_handle_events(_SNETEVENT *event)
{
	int v1; // ecx
	int *v2; // eax
	int *v3; // eax

	switch ( event->eventid )
	{
		case EVENT_TYPE_PLAYER_CREATE_GAME:
			v3 = (int *)event->data;
			sgGameInitInfo.dwSeed = *v3;
			_LOBYTE(sgGameInitInfo.bDiff) = *((_BYTE *)v3 + 4);
			sgbPlayerTurnBitTbl[event->playerid] = 1;
			break;
		case EVENT_TYPE_PLAYER_LEAVE_GAME:
			v1 = 0;
			sgbPlayerLeftGameTbl[event->playerid] = 1;
			sgbPlayerTurnBitTbl[event->playerid] = 0;
			v2 = (int *)event->data;
			if ( v2 && event->databytes >= 4u )
				v1 = *v2;
			sgdwPlayerLeftReasonTbl[event->playerid] = v1;
			if ( v1 == 0x40000004 )
				gbSomebodyWonGameKludge = 1;
			sgbSendDeltaTbl[event->playerid] = 0;
			dthread_remove_player(event->playerid);
			if ( (unsigned char)gbDeltaSender == event->playerid )
				gbDeltaSender = 4;
			break;
		case EVENT_TYPE_PLAYER_MESSAGE:
			ErrorPlrMsg((char *)event->data);
			break;
	}
}
// 6761B8: using guessed type char gbSomebodyWonGameKludge;
// 6796E4: using guessed type char gbDeltaSender;

//----- (00440694) --------------------------------------------------------
int __fastcall NetInit(int bSinglePlayer, int *pfExitProgram)
{
	int v2; // ebx
	void (__cdecl *v3)(); // eax
	int v4; // eax
	int v5; // ecx
	TCmdPlrInfoHdr *v6; // edx
	bool v7; // zf
	int v9; // eax
	int v10; // eax
	_SNETPROGRAMDATA ProgramData; // [esp+8h] [ebp-A8h]
	_SNETUIDATA UiData; // [esp+44h] [ebp-6Ch]
	_SNETPLAYERDATA a2; // [esp+94h] [ebp-1Ch]
	int v14; // [esp+A4h] [ebp-Ch]
	int len; // [esp+A8h] [ebp-8h]
	int *a4; // [esp+ACh] [ebp-4h]

	a4 = pfExitProgram;
	v14 = bSinglePlayer;
	v2 = 0;
	while ( 1 )
	{
		*a4 = 0;
		SetRndSeed(0);
		sgGameInitInfo.dwSeed = time(0);
		_LOBYTE(sgGameInitInfo.bDiff) = gnDifficulty;
		memset(&ProgramData, 0, 0x3Cu);
		ProgramData.size = 60;
		ProgramData.programname = "Diablo Retail";
		ProgramData.programdescription = "internal version unknown";
		ProgramData.programid = 'DRTL';
		ProgramData.versionid = 42;
		ProgramData.maxplayers = 4;
		ProgramData.multi_seed = (int)&sgGameInitInfo;
		ProgramData.initdata = (void *)8;
		ProgramData.reserved2 = (void *)15;
		ProgramData.languageid = 1033;
		memset(&a2, 0, 0x10u);
		a2.size = 16;
		memset(&UiData, 0, 0x50u);
		UiData.size = 80;
		UiData.parentwindow = SDrawGetFrameWindow(0);
		UiData.artcallback = UiArtCallback;
		UiData.createcallback = UiCreateGameCallback;
		UiData.drawdesccallback = UiDrawDescCallback;
		UiData.messageboxcallback = UiMessageBoxCallback;
		UiData.soundcallback = UiSoundCallback;
		UiData.authcallback = UiAuthCallback;
		UiData.getdatacallback = UiGetDataCallback;
		UiData.categorycallback = UiCategoryCallback;
		UiData.selecthero = (void (__cdecl *)())mainmenu_select_hero_dialog;
		UiData.createhero = (void (__cdecl *)())mainmenu_create_hero;
		UiData.profiledraw = UiProfileDraw;
		UiData.profilecallback = UiProfileCallback;
		UiProfileGetString();
		UiData.profilegetstring = v3;
		memset(sgbPlayerTurnBitTbl, 0, 4u);
		gbGameDestroyed = 0;
		memset(sgbPlayerLeftGameTbl, 0, 4u);
		memset(sgdwPlayerLeftReasonTbl, 0, 0x10u);
		memset(sgbSendDeltaTbl, 0, 4u);
		memset(plr, 0, 0x15360u);
		memset(sgwPackPlrOffsetTbl, 0, 8u);
		SNetSetBasePlayer(0);
		if ( v14 )
			v4 = multi_init_single(&ProgramData, &a2, &UiData);
		else
			v4 = multi_init_multi(&ProgramData, &a2, &UiData, a4);
		if ( !v4 )
			return 0;
		sgbNetInited = 1;
		sgbTimeout = 0;
		delta_init();
		InitPlrMsg();
		multi_clear_pkt(pkdata_6761C0);
		multi_clear_pkt(pkdata_678658);
		dword_678628 = 0;
		sync_clear_pkt();
		nthread_start(sgbPlayerTurnBitTbl[myplr]);
		dthread_start();
		MI_Dummy(v5);
		sgdwGameLoops = 0;
		sgbSentThisCycle = 0;
		gbDeltaSender = myplr;
		gbSomebodyWonGameKludge = 0;
		nthread_send_and_recv_turn(0, 0);
		SetupLocalCoords();
		_LOBYTE(v6) = CMD_SEND_PLRINFO;
		multi_send_pinfo(-2, v6);
		gbActivePlayers = 1;
		v7 = sgbPlayerTurnBitTbl[myplr] == 0;
		plr[myplr].plractive[0] = 1;
		if ( v7 || msg_wait_resync() )
			break;
		NetClose();
		byte_678640 = 0;
	}
	gnDifficulty = _LOBYTE(sgGameInitInfo.bDiff);
	SetRndSeed(sgGameInitInfo.dwSeed);
	do
	{
		glSeedTbl[v2] = GetRndSeed();
		gnLevelTypeTbl[v2] = InitNewSeed(v2);
		++v2;
	}
	while ( v2 < 17 );
	_LOBYTE(v9) = SNetGetGameInfo(GAME_INFO_NAME, szPlayerName, 128, (unsigned int *)len);
	if ( !v9 )
		nthread_terminate_game("SNetGetGameInfo1");
	_LOBYTE(v10) = SNetGetGameInfo(GAME_INFO_PASS, szPlayerDescript, 128, (unsigned int *)len);
	if ( !v10 )
		nthread_terminate_game("SNetGetGameInfo2");
	return 1;
}
// 6761B8: using guessed type char gbSomebodyWonGameKludge;
// 678628: using guessed type int dword_678628;
// 67862C: using guessed type char gbActivePlayers;
// 67862D: using guessed type char gbGameDestroyed;
// 678640: using guessed type char byte_678640;
// 679661: using guessed type char sgbTimeout;
// 6796E4: using guessed type char gbDeltaSender;
// 6796E8: using guessed type int sgbNetInited;

//----- (00440992) --------------------------------------------------------
void __fastcall multi_clear_pkt(char *a1)
{
	*(_DWORD *)a1 = 0;
	a1[4] = 0;
}

//----- (0044099A) --------------------------------------------------------
void __fastcall multi_send_pinfo(int pnum, TCmdPlrInfoHdr *cmd)
{
	char v2; // bl
	int v3; // esi
	int v4; // edx
	PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h]

	v2 = (char)cmd;
	v3 = pnum;
	PackPlayer(&pkplr, myplr, 1);
	_LOBYTE(v4) = v2;
	dthread_send_delta(v3, v4, &pkplr, 1266);
}

//----- (004409D5) --------------------------------------------------------
int __fastcall InitNewSeed(int newseed)
{
	int result; // eax

	result = 0;
	if ( newseed )
	{
		result = 1;
		if ( newseed < 1 || newseed > 4 )
		{
			if ( newseed < 5 || newseed > 8 )
			{
				if ( newseed < 9 || newseed > 12 )
					result = 4;
				else
					result = 3;
			}
			else
			{
				result = 2;
			}
		}
	}
	return result;
}

//----- (00440A05) --------------------------------------------------------
void __cdecl SetupLocalCoords()
{
	int v0; // eax
	int v1; // ecx
	int v2; // edx

	if ( !leveldebug || (unsigned char)gbMaxPlayers > 1u )
	{
		currlevel = 0;
		leveltype = 0;
		setlevel = 0;
	}
	v0 = myplr;
	v1 = plrxoff[myplr] + 75;
	v2 = plryoff[myplr] + 68;
	plr[v0].WorldX = v1;
	plr[v0].WorldY = v2;
	plr[v0]._px = v1;
	plr[v0]._py = v2;
	plr[v0]._ptargx = v1;
	plr[v0]._ptargy = v2;
	plr[v0].plrlevel = currlevel;
	plr[v0]._pLvlChanging = 1;
	plr[v0].pLvlLoad = 0;
	plr[v0]._pmode = PM_NEWLVL;
	plr[v0].destAction = -1;
}
// 52572C: using guessed type int leveldebug;
// 5BB1ED: using guessed type char leveltype;
// 5CF31D: using guessed type char setlevel;
// 679660: using guessed type char gbMaxPlayers;

//----- (00440A9B) --------------------------------------------------------
int __fastcall multi_init_single(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info)
{
	int v3; // eax
	int result; // eax
	int v5; // eax
	char *v6; // eax

	_LOBYTE(v3) = SNetInitializeProvider(0, client_info, user_info, ui_info, &fileinfo);
	if ( v3 )
	{
		ui_info = 0;
		_LOBYTE(v5) = SNetCreateGame(
						 "local",
						 "local",
						 "local",
						 0,
						 (char *)&sgGameInitInfo.dwSeed,
						 8,
						 1,
						 "local",
						 "local",
						 (int *)&ui_info);
		if ( !v5 )
		{
			v6 = GetLastErr();
			TermMsg("SNetCreateGame1:\n%s", v6);
		}
		myplr = 0;
		gbMaxPlayers = 1;
		result = 1;
	}
	else
	{
		SErrGetLastError();
		result = 0;
	}
	return result;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00440B09) --------------------------------------------------------
int __fastcall multi_init_multi(_SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, int *a4)
{
	_SNETPLAYERDATA *v4; // ebx
	signed int i; // edi
	int a6; // [esp+Ch] [ebp-Ch]
	int a2; // [esp+10h] [ebp-8h]
	int type; // [esp+14h] [ebp-4h]

	v4 = user_info;
	a2 = (int)client_info;
	for ( i = 1; ; i = 0 )
	{
		type = 0;
		if ( byte_678640 )
		{
			if ( !UiSelectProvider(0, (_SNETPROGRAMDATA *)a2, v4, ui_info, &fileinfo, &type)
			  && (!i || SErrGetLastError() != 0x85100077 || !multi_upgrade(a4)) )
			{
				return 0;
			}
			if ( type == 'BNET' )
				plr[0].pBattleNet = 1;
		}
		multi_event_handler(1);
		if ( UiSelectGame(1, (_SNETPROGRAMDATA *)a2, v4, ui_info, &fileinfo, &a6) )
			break;
		byte_678640 = 1;
	}
	if ( (unsigned int)a6 >= 4 )
		return 0;
	myplr = a6;
	gbMaxPlayers = 4;
	pfile_read_player_from_save();
	if ( type == 'BNET' )
		plr[myplr].pBattleNet = 1;
	return 1;
}
// 678640: using guessed type char byte_678640;
// 679660: using guessed type char gbMaxPlayers;

//----- (00440BDB) --------------------------------------------------------
int __fastcall multi_upgrade(int *a1)
{
	int *v1; // esi
	int result; // eax
	int status; // [esp+4h] [ebp-4h]

	v1 = a1;
	SNetPerformUpgrade((unsigned long *)&status);
	result = 1;
	if ( status && status != 1 )
	{
		if ( status == 2 )
		{
			*v1 = 1;
		}
		else if ( status == -1 )
		{
			DrawDlg("Network upgrade failed");
		}
		result = 0;
	}
	return result;
}

//----- (00440C17) --------------------------------------------------------
void __fastcall multi_player_joins(int pnum, TCmdPlrInfoHdr *cmd, int a3)
{
	int v3; // ebx
	TCmdPlrInfoHdr *v4; // edi
	short *v5; // esi
	int v6; // esi
	bool v7; // zf
	char *v8; // eax
	int v9; // ST08_4
	int v10; // edx
	int v11; // eax
	int v12; // ecx
	int v13; // eax

	v3 = pnum;
	v4 = cmd;
	if ( myplr != pnum )
	{
		v5 = &sgwPackPlrOffsetTbl[pnum];
		if ( *v5 == cmd->wOffset || (*v5 = 0, !cmd->wOffset) )
		{
			if ( !a3 && !*v5 )
			{
				_LOBYTE(cmd) = CMD_ACK_PLRINFO;
				multi_send_pinfo(pnum, cmd);
			}
			memcpy((char *)&pkplr[v3] + (unsigned short)v4->wOffset, &v4[1], (unsigned short)v4->wBytes);
			*v5 += v4->wBytes;
			if ( *v5 == 1266 )
			{
				*v5 = 0;
				multi_player_left_msg(v3, 0);
				v6 = v3;
				plr[v3]._pGFXLoad = 0;
				UnPackPlayer(&pkplr[v3], v3, 1);
				if ( a3 )
				{
					++gbActivePlayers;
					v7 = sgbPlayerTurnBitTbl[v3] == 0;
					plr[v6].plractive[0] = 1;
					v8 = "Player '%s' (level %d) just joined the game";
					if ( v7 )
						v8 = "Player '%s' (level %d) is already in the game";
					EventPlrMsg(v8, plr[v6]._pName, plr[v6]._pLevel);
					LoadPlrGFX(v3, 1);
					SyncInitPlr(v3);
					if ( plr[v6].plrlevel == currlevel )
					{
						if ( (signed int)(plr[v6]._pHitPoints & 0xFFFFFFC0) <= 0 )
						{
							plr[v6]._pgfxnum = 0;
							LoadPlrGFX(v3, 128);
							v9 = plr[v6]._pDFNum;
							v10 = plr[v6]._peqD[0];
							plr[v6]._pmode = 8;
							NewPlrAnim(v3, v10, plr[v6]._pDFrames, 1);
							v11 = plr[v6]._pAnimLen;
							v12 = v11 - 1;
							plr[v6]._pVar8 = 2 * v11;
							v13 = plr[v6].WorldX;
							plr[v6]._pAnimFrame = v12;
							dFlags[v13][plr[v6].WorldY] |= 4u;
						}
						else
						{
							StartStand(v3, 0);
						}
					}
				}
			}
		}
	}
}
// 67862C: using guessed type char gbActivePlayers;

//----- (00440DB3) --------------------------------------------------------
void __cdecl nthread_cpp_init_1()
{
	nthread_cpp_init_value = nthread_inf;
}
// 47F164: using guessed type int nthread_inf;
// 679700: using guessed type int nthread_cpp_init_value;

//----- (00440DBE) --------------------------------------------------------
void __cdecl nthread_cpp_init_2()
{
	nthread_init_mutex();
	nthread_cleanup_mutex_atexit();
}

//----- (00440DC8) --------------------------------------------------------
void __cdecl nthread_init_mutex()
{
	InitializeCriticalSection(&stru_679718);
}

//----- (00440DD4) --------------------------------------------------------
void __cdecl nthread_cleanup_mutex_atexit()
{
	atexit(nthread_cleanup_mutex);
}

//----- (00440DE0) --------------------------------------------------------
void __cdecl nthread_cleanup_mutex()
{
	DeleteCriticalSection(&stru_679718);
}

//----- (00440DEC) --------------------------------------------------------
void __fastcall nthread_terminate_game(char *func_name)
{
	char *v1; // esi
	int v2; // eax
	char *v3; // eax

	v1 = func_name;
	v2 = SErrGetLastError();
	if ( v2 != 0x8510006A )
	{
		if ( v2 == 0x85100069 || v2 == 0x85100070 )
		{
			gbGameDestroyed = 1;
		}
		else
		{
			v3 = GetLastErr();
			TermMsg("%s:\n%s", v1, v3);
		}
	}
}
// 67862D: using guessed type char gbGameDestroyed;

//----- (00440E28) --------------------------------------------------------
int __fastcall nthread_send_and_recv_turn(int cur_turn, int turn_delta)
{
	int v2; // ebx
	unsigned int v3; // edi
	int v4; // eax
	char *v5; // ecx
	int v6; // eax
	int v7; // eax
	int turn; // [esp+Ch] [ebp-8h]
	int turns; // [esp+10h] [ebp-4h]

	v2 = turn_delta;
	v3 = cur_turn;
	_LOBYTE(v4) = SNetGetTurnsInTransit(&turns);
	if ( v4 )
	{
		if ( turns >= (unsigned int)gdwTurnsInTransit )
			return v3;
		while ( 1 )
		{
			++turns;
			v6 = dword_679754 | v3 & 0x7FFFFFFF;
			dword_679754 = 0;
			turn = v6;
			_LOBYTE(v7) = SNetSendTurn((char *)&turn, 4);
			if ( !v7 )
				break;
			v3 += v2;
			if ( v3 >= 0x7FFFFFFF )
				v3 = (unsigned short)v3;
			if ( turns >= (unsigned int)gdwTurnsInTransit )
				return v3;
		}
		v5 = "SNetSendTurn";
	}
	else
	{
		v5 = "SNetGetTurnsInTransit";
	}
	nthread_terminate_game(v5);
	return 0;
}
// 679738: using guessed type int gdwTurnsInTransit;
// 679754: using guessed type int dword_679754;

//----- (00440EAA) --------------------------------------------------------
void __fastcall nthread_recv_turns(bool *recieved)
{
	bool *v1; // esi
	bool v2; // zf
	int v3; // eax

	v1 = recieved;
	*(_DWORD *)recieved = 0;
	if ( --sgbPacketCountdown )
	{
		dword_679764 += 50;
		return;
	}
	v2 = sgbSyncCountdown-- == 1;
	sgbPacketCountdown = byte_679704;
	if ( !v2 )
		goto LABEL_11;
	_LOBYTE(v3) = SNetReceiveTurns(0, 4, (char **)glpMsgTbl, (unsigned int *)gdwMsgLenTbl, (unsigned long *)player_state);
	if ( v3 )
	{
		if ( !byte_679758 )
		{
			byte_679758 = 1;
			dword_679764 = GetTickCount();
		}
		sgbSyncCountdown = 4;
		multi_msg_countdown();
LABEL_11:
		*(_DWORD *)v1 = 1;
		dword_679764 += 50;
		return;
	}
	if ( SErrGetLastError() != 0x8510006B )
		nthread_terminate_game("SNetReceiveTurns");
	byte_679758 = 0;
	sgbSyncCountdown = 1;
	sgbPacketCountdown = 1;
}
// 679704: using guessed type char byte_679704;
// 679750: using guessed type char sgbSyncCountdown;
// 679758: using guessed type char byte_679758;
// 679759: using guessed type char sgbPacketCountdown;
// 679764: using guessed type int dword_679764;

//----- (00440F56) --------------------------------------------------------
void __cdecl nthread_set_turn_upper_bit()
{
	dword_679754 = 0x80000000;
}
// 679754: using guessed type int dword_679754;

//----- (00440F61) --------------------------------------------------------
void __fastcall nthread_start(bool set_turn_upper_bit)
{
	BOOL v1; // esi
	int v2; // eax
	char *v3; // eax
	unsigned int v4; // esi
	unsigned int v5; // eax
	char *v6; // eax
	_SNETCAPS caps; // [esp+8h] [ebp-24h]

	v1 = set_turn_upper_bit;
	dword_679764 = GetTickCount();
	sgbPacketCountdown = 1;
	sgbSyncCountdown = 1;
	byte_679758 = 1;
	if ( v1 )
		nthread_set_turn_upper_bit();
	else
		dword_679754 = 0;
	caps.size = 36;
	_LOBYTE(v2) = SNetGetProviderCaps(&caps);
	if ( !v2 )
	{
		v3 = GetLastErr();
		TermMsg("SNetGetProviderCaps:\n%s", v3);
	}
	gdwTurnsInTransit = caps.defaultturnsintransit;
	if ( !caps.defaultturnsintransit )
		gdwTurnsInTransit = 1;
	if ( caps.defaultturnssec <= 0x14u && caps.defaultturnssec )
		byte_679704 = 0x14u / caps.defaultturnssec;
	else
		byte_679704 = 1;
	v4 = 512;
	if ( caps.maxmessagesize < 0x200u )
		v4 = caps.maxmessagesize;
	gdwDeltaBytesSec = (unsigned int)caps.bytessec >> 2;
	gdwLargestMsgSize = v4;
	if ( caps.maxplayers > 4u )
		caps.maxplayers = 4;
	v5 = (3 * (caps.bytessec * (unsigned int)(unsigned char)byte_679704 / 0x14) >> 2) / caps.maxplayers;
	gdwNormalMsgSize = v5;
	if ( v5 < 0x80 )
	{
		do
		{
			byte_679704 *= 2;
			v5 *= 2;
		}
		while ( v5 < 0x80 );
		gdwNormalMsgSize = v5;
	}
	if ( v5 > v4 )
		gdwNormalMsgSize = v4;
	if ( (unsigned char)gbMaxPlayers > 1u )
	{
		sgbThreadIsRunning = 0;
		EnterCriticalSection(&stru_679718);
		byte_679734 = 1;
		hObject = (HANDLE)_beginthreadex(0, 0, nthread_handler, 0, 0, (unsigned int *)&dword_67974C);
		if ( hObject == (HANDLE)-1 )
		{
			v6 = GetLastErr();
			TermMsg("nthread2:\n%s", v6);
		}
		SetThreadPriority(hObject, 2);
	}
}
// 679660: using guessed type char gbMaxPlayers;
// 679704: using guessed type char byte_679704;
// 679730: using guessed type int gdwDeltaBytesSec;
// 679734: using guessed type char byte_679734;
// 679738: using guessed type int gdwTurnsInTransit;
// 679750: using guessed type char sgbSyncCountdown;
// 679754: using guessed type int dword_679754;
// 679758: using guessed type char byte_679758;
// 679759: using guessed type char sgbPacketCountdown;
// 67975A: using guessed type char sgbThreadIsRunning;
// 67975C: using guessed type int gdwLargestMsgSize;
// 679760: using guessed type int gdwNormalMsgSize;
// 679764: using guessed type int dword_679764;

//----- (004410CF) --------------------------------------------------------
unsigned int __stdcall nthread_handler(void *a1)
{
	int v1; // eax
	signed __int32 v2; // esi
	bool recieved; // [esp+Ch] [ebp-4h]

	if ( byte_679734 )
	{
		while ( 1 )
		{
			EnterCriticalSection(&stru_679718);
			if ( !byte_679734 )
				break;
			nthread_send_and_recv_turn(0, 0);
			nthread_recv_turns(&recieved);
			if ( v1 )
				v2 = dword_679764 - GetTickCount();
			else
				v2 = 50;
			LeaveCriticalSection(&stru_679718);
			if ( v2 > 0 )
				Sleep(v2);
			if ( !byte_679734 )
				return 0;
		}
		LeaveCriticalSection(&stru_679718);
	}
	return 0;
}
// 679734: using guessed type char byte_679734;
// 679764: using guessed type int dword_679764;

//----- (00441145) --------------------------------------------------------
void __cdecl nthread_cleanup()
{
	char *v0; // eax

	byte_679734 = 0;
	gdwTurnsInTransit = 0;
	gdwNormalMsgSize = 0;
	gdwLargestMsgSize = 0;
	if ( hObject != (HANDLE)-1 && dword_67974C != GetCurrentThreadId() )
	{
		if ( !sgbThreadIsRunning )
			LeaveCriticalSection(&stru_679718);
		if ( WaitForSingleObject(hObject, 0xFFFFFFFF) == -1 )
		{
			v0 = GetLastErr();
			TermMsg("nthread3:\n(%s)", v0);
		}
		CloseHandle(hObject);
		hObject = (HANDLE)-1;
	}
}
// 679734: using guessed type char byte_679734;
// 679738: using guessed type int gdwTurnsInTransit;
// 67975A: using guessed type char sgbThreadIsRunning;
// 67975C: using guessed type int gdwLargestMsgSize;
// 679760: using guessed type int gdwNormalMsgSize;

//----- (004411C4) --------------------------------------------------------
void __fastcall nthread_ignore_mutex(bool ignore_mutex)
{
	bool v1; // bl

	v1 = ignore_mutex;
	if ( hObject != (HANDLE)-1 )
	{
		if ( ignore_mutex )
			LeaveCriticalSection(&stru_679718);
		else
			EnterCriticalSection(&stru_679718);
		sgbThreadIsRunning = v1;
	}
}
// 67975A: using guessed type char sgbThreadIsRunning;

//----- (004411EF) --------------------------------------------------------
bool __cdecl nthread_has_500ms_passed()
{
	DWORD v0; // eax
	int v1; // ecx

	v0 = GetTickCount();
	v1 = v0 - dword_679764;
	if ( gbMaxPlayers == 1 && v1 > 500 )
	{
		dword_679764 = v0;
		v1 = 0;
	}
	return v1 >= 0;
}
// 679660: using guessed type char gbMaxPlayers;
// 679764: using guessed type int dword_679764;

//----- (0044121D) --------------------------------------------------------
void __cdecl InitObjectGFX()
{
	ObjDataStruct *v0; // eax
	unsigned char *v1; // esi
	unsigned char v2; // cl
	int v3; // edx
	int i; // eax
	char v5; // al
	int v6; // eax
	signed int v7; // ebx
	char *v8; // ST08_4
	unsigned char *v9; // eax
	int v10; // ecx
	char fileload[56]; // [esp+4h] [ebp-58h]
	char arglist; // [esp+3Ch] [ebp-20h]

	memset(fileload, 0, 0x38u);
	if ( AllObjects[0].oload != -1 )
	{
		v0 = AllObjects;
		v1 = &AllObjects[0].otheme;
		do
		{
			if ( v0->oload == 1 && currlevel >= (signed int)(char)*(v1 - 3) && currlevel <= (signed int)(char)*(v1 - 2) )
				fileload[(char)*(v1 - 4)] = 1;
			v2 = *v1;
			if ( *v1 != -1 )
			{
				v3 = numthemes;
				for ( i = 0; i < v3; ++i )
				{
					if ( _LOBYTE(themes[i].ttype) == v2 )
						fileload[(char)*(v1 - 4)] = 1;
				}
			}
			v5 = v1[1];
			if ( v5 != -1 )
			{
				_LOBYTE(v6) = QuestStatus(v5);
				if ( v6 )
					fileload[(char)*(v1 - 4)] = 1;
			}
			v1 += 44;
			v0 = (ObjDataStruct *)(v1 - 5);
		}
		while ( *(v1 - 5) != -1 );
	}
	v7 = 0;
	do
	{
		if ( fileload[v7] )
		{
			v8 = ObjMasterLoadList[v7];
			ObjFileList[numobjfiles] = v7;
			sprintf(&arglist, "Objects\\%s.CEL", v8);
			v9 = LoadFileInMem(&arglist, 0);
			v10 = numobjfiles++;
			pObjCels[v10] = (int)v9;
		}
		++v7;
	}
	while ( v7 < 56 );
}
// 67D7C4: using guessed type int numobjfiles;
// 44121D: using guessed type char fileload[56];

//----- (00441317) --------------------------------------------------------
void __cdecl FreeObjectGFX()
{
	int i; // esi
	void *v1; // ecx

	for ( i = 0; i < numobjfiles; ++i )
	{
		v1 = (void *)pObjCels[i];
		pObjCels[i] = 0;
		mem_free_dbg(v1);
	}
	numobjfiles = 0;
}
// 67D7C4: using guessed type int numobjfiles;

//----- (00441345) --------------------------------------------------------
int __fastcall RndLocOk(int xp, int yp)
{
	int v2; // ecx
	int v3; // eax
	int v4; // eax
	int result; // eax

	v2 = xp;
	v3 = v2 * 112 + yp;
	result = 0;
	if ( !dMonster[0][v3] && !dPlayer[v2][yp] && !dObject[v2][yp] && !(dFlags[v2][yp] & 8) )
	{
		v4 = dPiece[0][v3];
		if ( !nSolidTable[v4] && (leveltype != 1 || v4 <= 126 || v4 >= 144) )
			result = 1;
	}
	return result;
}
// 5BB1ED: using guessed type char leveltype;

//----- (004413A0) --------------------------------------------------------
void __fastcall InitRndLocObj(int min, int max, int objtype)
{
	int v3; // esi
	int v4; // ecx
	int v5; // ebx
	int v6; // eax
	int v7; // ecx
	int v8; // esi
	int v9; // eax
	int v10; // edi
	int v11; // edx
	int v12; // edx
	int v13; // edx
	int v14; // edx
	int v15; // edx
	int v16; // edx
	int v17; // [esp+8h] [ebp-4h]

	v3 = min;
	_LOBYTE(min) = -117;
	v17 = 0;
	v5 = v3 + random(min, max - v3);
	if ( v5 > 0 )
	{
		while ( 1 )
		{
			do
			{
				_LOBYTE(v4) = -117;
				v6 = random(v4, 80);
				_LOBYTE(v7) = -117;
				v8 = v6 + 16;
				v9 = random(v7, 80);
				v10 = v9 + 16;
			}
			while ( !RndLocOk(v8 - 1, v9 + 15) );
			if ( RndLocOk(v8, v11) )
			{
				if ( RndLocOk(v8 + 1, v12) )
				{
					if ( RndLocOk(v8 - 1, v10) )
					{
						if ( RndLocOk(v8, v13) )
						{
							if ( RndLocOk(v8 + 1, v14) )
							{
								if ( RndLocOk(v8 - 1, v10 + 1) )
								{
									if ( RndLocOk(v8, v15) )
									{
										if ( RndLocOk(v8 + 1, v16) )
										{
											AddObject(objtype, v8, v10);
											if ( ++v17 >= v5 )
												break;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

//----- (00441477) --------------------------------------------------------
void __fastcall InitRndLocBigObj(int min, int max, int objtype)
{
	int v3; // esi
	int v4; // edx
	int v5; // ecx
	int v6; // eax
	int v7; // ecx
	int v8; // edi
	int v9; // eax
	int v10; // esi
	int v11; // edx
	int v12; // edx
	int v13; // edx
	int v14; // edx
	int v15; // edx
	int v16; // edx
	int v17; // edx
	int v18; // edx
	int v19; // [esp+4h] [ebp-8h]
	int v20; // [esp+8h] [ebp-4h]

	v3 = min;
	v4 = max - min;
	_LOBYTE(min) = -116;
	v20 = 0;
	v19 = v3 + random(min, v4);
	if ( v19 > 0 )
	{
		while ( 1 )
		{
			do
			{
				_LOBYTE(v5) = -116;
				v6 = random(v5, 80);
				_LOBYTE(v7) = -116;
				v8 = v6 + 16;
				v9 = random(v7, 80);
				v10 = v9 + 16;
			}
			while ( !RndLocOk(v8 - 1, v9 + 14) );
			if ( RndLocOk(v8, v11) )
			{
				if ( RndLocOk(v8 + 1, v12) )
				{
					if ( RndLocOk(v8 - 1, v10 - 1) )
					{
						if ( RndLocOk(v8, v13) )
						{
							if ( RndLocOk(v8 + 1, v14) )
							{
								if ( RndLocOk(v8 - 1, v10) )
								{
									if ( RndLocOk(v8, v15) )
									{
										if ( RndLocOk(v8 + 1, v16) )
										{
											if ( RndLocOk(v8 - 1, v10 + 1) )
											{
												if ( RndLocOk(v8, v17) )
												{
													if ( RndLocOk(v8 + 1, v18) )
													{
														AddObject(objtype, v8, v10);
														if ( ++v20 >= v19 )
															break;
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

//----- (00441584) --------------------------------------------------------
void __fastcall InitRndLocObj5x5(int min, int max, int objtype)
{
	int v3; // esi
	int v4; // edx
	int v5; // ecx
	int v6; // ebx
	int v7; // eax
	int v8; // ecx
	int v9; // edi
	int v10; // esi
	int v11; // edx
	signed int v12; // [esp+Ch] [ebp-14h]
	int v13; // [esp+10h] [ebp-10h]
	int v14; // [esp+14h] [ebp-Ch]
	signed int v15; // [esp+18h] [ebp-8h]
	signed int v16; // [esp+1Ch] [ebp-4h]

	v3 = min;
	v4 = max - min;
	_LOBYTE(min) = -117;
	v13 = 0;
	v6 = v3 + random(min, v4);
	if ( v6 > 0 )
	{
		do
		{
			v14 = 0;
			while ( 1 )
			{
				_LOBYTE(v5) = -117;
				v12 = 1;
				v7 = random(v5, 80);
				_LOBYTE(v8) = -117;
				v9 = v7 + 16;
				v15 = -2;
				v10 = random(v8, 80) + 16;
				do
				{
					v16 = -2;
					v11 = v15 + v10;
					do
					{
						if ( !RndLocOk(v16 + v9, v11) )
							v12 = 0;
						++v16;
					}
					while ( v16 <= 2 );
					++v15;
				}
				while ( v15 <= 2 );
				if ( v12 )
					break;
				if ( ++v14 > 20000 )
					return;
			}
			AddObject(objtype, v9, v10);
			++v13;
		}
		while ( v13 < v6 );
	}
}

//----- (0044163B) --------------------------------------------------------
void __cdecl ClrAllObjects()
{
	int *v0; // eax
	int v1; // edx

	v0 = &object[0]._oy;
	do
	{
		*(v0 - 1) = 0;
		*v0 = 0;
		v0[3] = 0;
		v0[4] = 0;
		v0[5] = 0;
		v0[6] = 0;
		v0[7] = 0;
		v0[10] = 0;
		v0[20] = 0;
		v0[21] = 0;
		v0[22] = 0;
		v0[23] = 0;
		v0 += 30;
	}
	while ( (signed int)v0 < (signed int)&hero_cpp_init_value );
	v1 = 0;
	memset(objectactive, 0, sizeof(objectactive));
	nobjects = 0;
	do
	{
		objectavail[v1] = v1;
		++v1;
	}
	while ( v1 < 127 );
	trapdir = 0;
	trapid = 1;
	leverid = 1;
}
// 679768: using guessed type int trapid;
// 67976C: using guessed type int trapdir;
// 67D7C8: using guessed type int hero_cpp_init_value;

//----- (004416A8) --------------------------------------------------------
void __cdecl AddTortures()
{
	int v0; // esi
	int v1; // edi
	_DWORD *v2; // [esp+Ch] [ebp-4h]

	v0 = 0;
	do
	{
		v1 = 2;
		v2 = (_DWORD *)((char *)dPiece + 4 * v0);
		do
		{
			if ( *v2 == 367 )
			{
				AddObject(36, v1 - 2, v0 + 1);
				AddObject(38, v1, v0 - 1);
				AddObject(37, v1 - 2, v0 + 3);
				AddObject(39, v1 + 2, v0 - 1);
				AddObject(40, v1 - 2, v0 + 5);
				AddObject(29, v1 - 1, v0 + 3);
				AddObject(30, v1 + 2, v0 + 5);
				AddObject(31, v1, v0);
				AddObject(32, v1 + 1, v0 + 2);
				AddObject(33, v1, v0 + 4);
				AddObject(34, v1, v0 + 1);
				AddObject(35, v1 + 2, v0 + 2);
			}
			v2 += 112;
			++v1;
		}
		while ( v1 - 2 < 112 );
		++v0;
	}
	while ( v0 < 112 );
}

//----- (0044179F) --------------------------------------------------------
void __cdecl AddCandles()
{
	int v0; // esi
	int v1; // edi
	int v2; // ebx

	v0 = quests[13]._qtx;
	v1 = quests[13]._qty;
	v2 = quests[13]._qty + 1;
	AddObject(87, quests[13]._qtx - 2, quests[13]._qty + 1);
	AddObject(87, v0 + 3, v2);
	v1 += 2;
	AddObject(87, v0 - 1, v1);
	AddObject(87, v0 + 2, v1);
}

//----- (004417E8) --------------------------------------------------------
void __fastcall AddBookLever(int lx1, int ly1, int lx2, int ly2, int x1, int y1, int x2, int y2, int msg)
{
	int v9; // esi
	int v10; // edi
	signed int v11; // ebx
	int v12; // edx
	int v13; // eax
	int v14; // eax
	int v15; // eax
	int v16; // esi
	signed int v17; // [esp+Ch] [ebp-Ch]
	int v18; // [esp+10h] [ebp-8h]
	signed int v19; // [esp+14h] [ebp-4h]

	v18 = 0;
	while ( 1 )
	{
		v17 = 1;
		v9 = random(-117, 80) + 16;
		v10 = random(-117, 80) + 16;
		v11 = -2;
		do
		{
			v19 = -2;
			v12 = v11 + v10;
			do
			{
				if ( !RndLocOk(v19 + v9, v12) )
					v17 = 0;
				++v19;
			}
			while ( v19 <= 2 );
			++v11;
		}
		while ( v11 <= 2 );
		if ( v17 )
			break;
		if ( ++v18 > 20000 )
			return;
	}
	_LOBYTE(v13) = QuestStatus(8);
	if ( v13 )
		AddObject(71, v9, v10);
	_LOBYTE(v14) = QuestStatus(11);
	if ( v14 )
		AddObject(88, v9, v10);
	_LOBYTE(v15) = QuestStatus(9);
	if ( v15 )
	{
		v9 = 2 * setpc_x + 25;
		v10 = 2 * setpc_y + 40;
		AddObject(72, v9, v10);
	}
	v16 = dObject[v9][v10] - 1;
	SetObjMapRange(v16, x1, y1, x2, y2, leverid);
	SetBookMsg(v16, msg);
	++leverid;
	object[v16]._oVar6 = object[v16]._oAnimFrame + 1;
}

//----- (00441904) --------------------------------------------------------
void __cdecl InitRndBarrels()
{
	int v0; // ebp
	int v1; // esi
	int v2; // edi
	int v3; // eax
	int v4; // ebx
	int v5; // edx
	int v6; // eax
	int v7; // eax
	signed int v8; // [esp+4h] [ebp-Ch]
	signed int v9; // [esp+8h] [ebp-8h]
	int v10; // [esp+Ch] [ebp-4h]

	v10 = 0;
	v0 = random(-113, 5) + 3;
	if ( v0 > 0 )
	{
		do
		{
			do
			{
				v1 = random(-113, 80) + 16;
				v2 = random(-113, 80) + 16;
			}
			while ( !RndLocOk(v1, v2) );
			v3 = random(-113, 4);
			AddObject(58 - (v3 != 0), v1, v2);
			v4 = 1;
			v5 = 0;
			v9 = 1;
			while ( !random(-113, v5) && v4 )
			{
				v8 = 0;
				v4 = 0;
				do
				{
					if ( v8 >= 3 )
						break;
					v6 = random(-113, 8);
					v1 += bxadd[v6];
					v2 += byadd[v6];
					++v8;
					v4 = RndLocOk(v1, v2);
				}
				while ( !v4 );
				if ( v4 )
				{
					v7 = random(-113, 5);
					AddObject(58 - (v7 != 0), v1, v2);
					++v9;
				}
				v5 = v9 >> 1;
			}
			++v10;
		}
		while ( v10 < v0 );
	}
}

//----- (00441A00) --------------------------------------------------------
void __fastcall AddL1Objs(int x1, int y1, int x2, int y2)
{
	int v4; // ebx
	int *v5; // edi
	int v6; // esi
	int x; // [esp+0h] [ebp-8h]
	int y; // [esp+4h] [ebp-4h]

	x = x1;
	for ( y = y1; y < y2; ++y )
	{
		v4 = x;
		if ( x < x2 )
		{
			v5 = (int *)((char *)dPiece + 4 * (y + 112 * x));
			do
			{
				v6 = *v5;
				if ( *v5 == 270 )
					AddObject(0, v4, y);
				if ( v6 == 44 || v6 == 51 || v6 == 214 )
					AddObject(1, v4, y);
				if ( v6 == 46 || v6 == 56 )
					AddObject(2, v4, y);
				++v4;
				v5 += 112;
			}
			while ( v4 < x2 );
		}
	}
}

//----- (00441A98) --------------------------------------------------------
void __fastcall AddL2Objs(int x1, int y1, int x2, int y2)
{
	int v4; // ebx
	int *v5; // esi
	int v6; // edi
	int x; // [esp+0h] [ebp-8h]
	int y; // [esp+4h] [ebp-4h]

	x = x1;
	for ( y = y1; y < y2; ++y )
	{
		v4 = x;
		if ( x < x2 )
		{
			v5 = (int *)((char *)dPiece + 4 * (y + 112 * x));
			do
			{
				v6 = *v5;
				if ( *v5 == 13 || v6 == 541 )
					AddObject(42, v4, y);
				if ( v6 == 17 || v6 == 542 )
					AddObject(43, v4, y);
				++v4;
				v5 += 112;
			}
			while ( v4 < x2 );
		}
	}
}

//----- (00441B16) --------------------------------------------------------
void __fastcall AddL3Objs(int x1, int y1, int x2, int y2)
{
	int v4; // edi
	int *v5; // esi
	int v6; // ebx
	int x; // [esp+0h] [ebp-8h]
	int y; // [esp+4h] [ebp-4h]

	x = x1;
	for ( y = y1; y < y2; ++y )
	{
		v4 = x;
		if ( x < x2 )
		{
			v5 = (int *)((char *)dPiece + 4 * (y + 112 * x));
			do
			{
				v6 = *v5;
				if ( *v5 == 531 )
					AddObject(74, v4, y);
				if ( v6 == 534 )
					AddObject(75, v4, y);
				++v4;
				v5 += 112;
			}
			while ( v4 < x2 );
		}
	}
}

//----- (00441B8A) --------------------------------------------------------
unsigned char __fastcall WallTrapLocOk(int xp, int yp)
{
	return (~dFlags[xp][yp] & 8u) >> 3;
}

//----- (00441BA0) --------------------------------------------------------
void __cdecl AddL2Torches()
{
	int v0; // esi
	int v1; // edi
	char *v2; // ebx
	int v3; // eax
	int v4; // ecx
	int (*v5)[112]; // [esp+Ch] [ebp-Ch]
	int v6; // [esp+10h] [ebp-8h]
	int (*v7)[112]; // [esp+14h] [ebp-4h]

	v0 = 0;
	v7 = dPiece;
	do
	{
		v1 = 0;
		v2 = &dungeon[39][v0 + 39];
		v5 = v7;
		do
		{
			_LOBYTE(v3) = WallTrapLocOk(v1, v0);
			if ( !v3 )
				goto LABEL_18;
			v6 = (*v5)[0];
			if ( (*v5)[0] == 1 )
			{
				_LOBYTE(v4) = -111;
				if ( random(v4, 3) )
					goto LABEL_18;
				AddObject(46, v1, v0);
			}
			if ( v6 == 5 )
			{
				_LOBYTE(v4) = -111;
				if ( random(v4, 3) )
					goto LABEL_18;
				AddObject(47, v1, v0);
			}
			if ( v6 == 37 )
			{
				_LOBYTE(v4) = -111;
				if ( random(v4, 10) || *(v2 - 111) )
					goto LABEL_18;
				AddObject(44, v1 - 1, v0);
			}
			if ( v6 == 41 )
			{
				_LOBYTE(v4) = -111;
				if ( !random(v4, 10) && !*v2 )
					AddObject(45, v1, v0 - 1);
			}
LABEL_18:
			++v5;
			++v1;
			v2 += 112;
		}
		while ( v1 < 112 );
		v7 = (int (*)[112])((char *)v7 + 4);
		++v0;
	}
	while ( (signed int)v7 < (signed int)dPiece[1] );
}

//----- (00441C8C) --------------------------------------------------------
unsigned char __fastcall TorchLocOK(int xp, int yp)
{
	int v2; // ecx
	unsigned char result; // al

	v2 = xp;
	if ( dFlags[v2][yp] & 8 )
		result = 0;
	else
		result = nTrapTable[dPiece[0][yp + v2 * 112]] != 0;
	return result;
}

//----- (00441CB3) --------------------------------------------------------
void __cdecl AddObjTraps()
{
	int v0; // esi
	int *v1; // eax
	_BYTE *v2; // edi
	int v3; // ebx
	int v4; // edi
	int *j; // eax
	int v6; // eax
	char v7; // al
	int v8; // edi
	char *i; // eax
	int v10; // eax
	int v11; // eax
	int *v12; // [esp+0h] [ebp-18h]
	char *v13; // [esp+4h] [ebp-14h]
	int *v14; // [esp+8h] [ebp-10h]
	int v15; // [esp+Ch] [ebp-Ch]
	signed int v16; // [esp+10h] [ebp-8h]
	int x; // [esp+14h] [ebp-4h]

	if ( currlevel == 1 )
		v15 = 10;
	if ( currlevel >= 2u )
		v15 = 15;
	if ( currlevel >= 5u )
		v15 = 20;
	if ( currlevel >= 7u )
		v15 = 25;
	v0 = 0;
	v1 = dPiece[-1];
	v12 = dPiece[-1];
	do
	{
		x = 0;
		v16 = 0;
		v2 = (unsigned char *)dObject + v0;
		v14 = v1;
		v13 = (char *)dObject + v0;
		do
		{
			if ( *v2 > 0 && random(-112, 100) < v15 )
			{
				v3 = (char)(*v2 - 1);
				if ( AllObjects[object[v3]._otype].oTrapFlag )
				{
					if ( random(-112, 2) )
					{
						v8 = v0 - 1;
						for ( i = &dflags[39][4 * (v0 + v16 * 112) + 36]; !nSolidTable[*(_DWORD *)i]; i -= 4 )
							--v8;
						_LOBYTE(v10) = TorchLocOK(x, v8);
						if ( v10 && v0 - v8 > 1 )
						{
							AddObject(54, x, v8);
							v7 = dObject[v16][v8];
							goto LABEL_27;
						}
					}
					else
					{
						v4 = x - 1;
						for ( j = v14; !nSolidTable[*j]; j -= 112 )
							--v4;
						_LOBYTE(v6) = TorchLocOK(v4, v0);
						if ( v6 && x - v4 > 1 )
						{
							AddObject(53, v4, v0);
							v7 = dObject[v4][v0];
LABEL_27:
							v11 = (char)(v7 - 1);
							object[v11]._oVar2 = v0;
							object[v11]._oVar1 = x;
							object[v3]._oTrapFlag = 1;
							goto LABEL_28;
						}
					}
				}
			}
LABEL_28:
			++v16;
			++x;
			v14 += 112;
			v2 = (unsigned char *)v13 + 112;
			v13 += 112;
		}
		while ( v16 < 112 );
		++v0;
		v1 = v12 + 1;
		++v12;
	}
	while ( (signed int)v12 < (signed int)dPiece );
}

//----- (00441E58) --------------------------------------------------------
void __cdecl AddChestTraps()
{
	signed int v0; // ebp
	_BYTE *v1; // ebx
	int v2; // esi
	int v3; // eax
	bool v4; // zf
	int v5; // eax
	signed int v6; // [esp+10h] [ebp-4h]

	v0 = 0;
	do
	{
		v1 = (unsigned char *)dObject + v0;
		v6 = 112;
		do
		{
			if ( *v1 > 0 )
			{
				v2 = (char)(*v1 - 1);
				v3 = object[v2]._otype;
				if ( v3 >= OBJ_CHEST1 && v3 <= OBJ_CHEST3 && !object[v2]._oTrapFlag && random(0, 100) < 10 )
				{
					object[v2]._otype += OBJ_BOOKCASER;
					v4 = leveltype == 2;
					object[v2]._oTrapFlag = 1;
					if ( v4 )
						v5 = random(0, 2);
					else
						v5 = random(0, 3);
					object[v2]._oVar4 = v5;
				}
			}
			v1 += 112;
			--v6;
		}
		while ( v6 );
		++v0;
	}
	while ( v0 < 112 );
}
// 5BB1ED: using guessed type char leveltype;

//----- (00441EE4) --------------------------------------------------------
void __fastcall LoadMapObjects(unsigned char *pMap, int startx, int starty, int x1, int y1, int w, int h, int leveridx)
{
	unsigned char *v8; // ebx
	int v9; // esi
	int v10; // ecx
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	int v14; // esi
	unsigned char *v15; // ebx
	int i; // edi
	int v17; // eax
	int v18; // [esp+8h] [ebp-10h]
	int v19; // [esp+Ch] [ebp-Ch]
	int v20; // [esp+10h] [ebp-8h]
	int v21; // [esp+14h] [ebp-4h]
	int y; // [esp+20h] [ebp+8h]

	v8 = pMap + 2;
	InitObjFlag = 1;
	v9 = *pMap;
	v10 = pMap[2];
	v11 = v10;
	v12 = 2 * v10;
	v20 = startx;
	v13 = v9 * v11;
	v14 = 2 * v9;
	v19 = v14;
	v18 = v12;
	v15 = &v8[4 * v14 * v12 + 2 + 2 * v13];
	if ( v12 > 0 )
	{
		v21 = -16 - starty;
		y = starty + 16;
		do
		{
			for ( i = 0; i < v14; ++i )
			{
				if ( *v15 )
				{
					AddObject(ObjTypeConv[*v15], i + v20 + 16, y);
					v17 = ObjIndex(i + v20 + 16, y);
					SetObjMapRange(v17, x1, y1, x1 + w, y1 + h, leveridx);
					v14 = v19;
					v12 = v18;
				}
				v15 += 2;
			}
			++y;
		}
		while ( y + v21 < v12 );
	}
	InitObjFlag = 0;
}
// 67D7C0: using guessed type int InitObjFlag;

//----- (00441FAF) --------------------------------------------------------
void __fastcall LoadMapObjs(unsigned char *pMap, int startx, int starty)
{
	unsigned char *v3; // esi
	int v4; // eax
	int v5; // edi
	int v6; // ecx
	int v7; // eax
	int v8; // ecx
	int v9; // edi
	unsigned char *v10; // esi
	int i; // ebx
	int v12; // [esp+8h] [ebp-8h]
	int v13; // [esp+Ch] [ebp-4h]
	int y; // [esp+18h] [ebp+8h]

	v3 = pMap + 2;
	InitObjFlag = 1;
	v4 = pMap[2];
	v5 = *pMap;
	v6 = v4;
	v7 = 2 * v4;
	v12 = startx;
	v8 = v5 * v6;
	v9 = 2 * v5;
	v10 = &v3[4 * v9 * v7 + 2 + 2 * v8];
	if ( v7 > 0 )
	{
		v13 = v7;
		y = starty + 16;
		do
		{
			for ( i = 0; i < v9; ++i )
			{
				if ( *v10 )
					AddObject(ObjTypeConv[*v10], i + v12 + 16, y);
				v10 += 2;
			}
			++y;
			--v13;
		}
		while ( v13 );
	}
	InitObjFlag = 0;
}
// 67D7C0: using guessed type int InitObjFlag;

//----- (00442036) --------------------------------------------------------
void __cdecl AddDiabObjs()
{
	unsigned char *v0; // esi
	unsigned char *v1; // esi
	unsigned char *v2; // esi

	v0 = LoadFileInMem("Levels\\L4Data\\diab1.DUN", 0);
	LoadMapObjects(v0, 2 * diabquad1x, 2 * diabquad1y, diabquad2x, diabquad2y, 11, 12, 1);
	mem_free_dbg(v0);
	v1 = LoadFileInMem("Levels\\L4Data\\diab2a.DUN", 0);
	LoadMapObjects(v1, 2 * diabquad2x, 2 * diabquad2y, diabquad3x, diabquad3y, 11, 11, 2);
	mem_free_dbg(v1);
	v2 = LoadFileInMem("Levels\\L4Data\\diab3a.DUN", 0);
	LoadMapObjects(v2, 2 * diabquad3x, 2 * diabquad3y, diabquad4x, diabquad4y, 9, 9, 3);
	mem_free_dbg(v2);
}
// 5289C4: using guessed type int diabquad1x;
// 5289C8: using guessed type int diabquad1y;

//----- (004420F2) --------------------------------------------------------
void __cdecl AddStoryBooks()
{
	int v0; // esi
	int v1; // edi
	signed int v2; // ebx
	int v3; // edx
	int v4; // esi
	int y; // [esp+Ch] [ebp-Ch]
	int v6; // [esp+10h] [ebp-8h]
	signed int v7; // [esp+14h] [ebp-4h]

	v6 = 0;
	while ( 1 )
	{
		y = 1;
		v0 = random(-117, 80) + 16;
		v1 = random(-117, 80) + 16;
		v2 = -2;
		do
		{
			v7 = -3;
			v3 = v2 + v1;
			do
			{
				if ( !RndLocOk(v7 + v0, v3) )
					y = 0;
				++v7;
			}
			while ( v7 <= 3 );
			++v2;
		}
		while ( v2 <= 2 );
		if ( y )
			break;
		if ( ++v6 > 20000 )
			return;
	}
	AddObject(86, v0, v1);
	AddObject(87, v0 - 2, v1 + 1);
	AddObject(87, v0 - 2, v1);
	AddObject(87, v0 - 1, v1 - 1);
	AddObject(87, v0 + 1, v1 - 1);
	v4 = v0 + 2;
	AddObject(87, v4, v1);
	AddObject(87, v4, v1 + 1);
}

//----- (004421CA) --------------------------------------------------------
void __fastcall AddHookedBodies(int freq)
{
	int v1; // ebx
	char *v2; // esi
	int v3; // edi
	int v4; // eax
	int v5; // eax
	int v6; // eax
	int v7; // eax
	int v8; // [esp-8h] [ebp-20h]
	int v9; // [esp-4h] [ebp-1Ch]
	int max; // [esp+Ch] [ebp-Ch]
	int x; // [esp+10h] [ebp-8h]
	int y; // [esp+14h] [ebp-4h]

	y = 0;
	max = freq;
	v1 = 16;
	do
	{
		x = 0;
		v2 = (char *)dungeon + y;
		v3 = 17;
		do
		{
			if ( *v2 == 1 || *v2 == 2 )
			{
				_LOBYTE(freq) = 0;
				if ( !random(freq, max) )
				{
					_LOBYTE(v4) = SkipThemeRoom(x, y);
					if ( v4 )
					{
						if ( *v2 != 1 || v2[40] != 6 )
						{
							if ( *v2 == 2 && v2[1] == 6 )
							{
								_LOBYTE(freq) = 0;
								v7 = random(freq, 2);
								if ( v7 )
								{
									if ( v7 != 1 )
										goto LABEL_22;
									v9 = v1;
									v8 = 39;
								}
								else
								{
									v9 = v1;
									v8 = 38;
								}
								AddObject(v8, v3 - 1, v9);
							}
						}
						else
						{
							_LOBYTE(freq) = 0;
							v5 = random(freq, 3);
							if ( v5 )
							{
								v6 = v5 - 1;
								if ( v6 )
								{
									if ( v6 == 1 )
										AddObject(40, v3, v1);
								}
								else
								{
									AddObject(37, v3, v1);
								}
							}
							else
							{
								AddObject(36, v3, v1);
							}
						}
					}
				}
			}
LABEL_22:
			++x;
			v3 += 2;
			v2 += 40;
		}
		while ( v3 < 97 );
		++y;
		v1 += 2;
	}
	while ( v1 < 96 );
}

//----- (0044229F) --------------------------------------------------------
void __cdecl AddL4Goodies()
{
	AddHookedBodies(6);
	InitRndLocObj(2, 6, 29);
	InitRndLocObj(2, 6, 30);
	InitRndLocObj(2, 6, 31);
	InitRndLocObj(2, 6, 32);
	InitRndLocObj(2, 6, 33);
	InitRndLocObj(2, 6, 34);
	InitRndLocObj(2, 6, 35);
	InitRndLocObj(2, 6, 67);
	InitRndLocObj(1, 3, 80);
}

//----- (00442316) --------------------------------------------------------
void __cdecl AddLazStand()
{
	int v0; // edi
	int v1; // esi
	signed int v2; // ebx
	int v3; // edx
	int v4; // edi
	signed int v5; // [esp+Ch] [ebp-Ch]
	int v6; // [esp+10h] [ebp-8h]
	signed int v7; // [esp+14h] [ebp-4h]

	v6 = 0;
	while ( 1 )
	{
		v5 = 1;
		v0 = random(-117, 80) + 16;
		v1 = random(-117, 80) + 16;
		v2 = -3;
		do
		{
			v7 = -2;
			v3 = v2 + v1;
			do
			{
				if ( !RndLocOk(v7 + v0, v3) )
					v5 = 0;
				++v7;
			}
			while ( v7 <= 3 );
			++v2;
		}
		while ( v2 <= 3 );
		if ( v5 )
			break;
		if ( ++v6 > 10000 )
		{
			InitRndLocObj(1, 1, 95);
			return;
		}
	}
	AddObject(95, v0, v1);
	AddObject(30, v0, v1 + 2);
	AddObject(87, v0 + 1, v1 + 2);
	AddObject(31, v0 + 2, v1 + 2);
	AddObject(33, v0, v1 - 2);
	AddObject(87, v0 + 1, v1 - 2);
	AddObject(34, v0 + 2, v1 - 2);
	v4 = v0 - 1;
	AddObject(87, v4, v1 - 1);
	AddObject(35, v4, v1);
	AddObject(87, v4, v1 + 1);
}

//----- (00442418) --------------------------------------------------------
void __fastcall InitObjects(int a1)
{
	int v1; // eax
	int v2; // eax
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // eax
	char v7; // al
	signed int v8; // ebx
	unsigned char *v9; // esi
	int v10; // eax
	char v11; // al
	int v12; // eax
	char v13; // al
	unsigned char *v14; // esi
	int v15; // eax
	int v16; // [esp+0h] [ebp-4h]

	v16 = a1;
	ClrAllObjects();
	if ( currlevel == 16 )
	{
		AddDiabObjs();
	}
	else
	{
		InitObjFlag = 1;
		GetRndSeed();
		if ( currlevel == 9 && gbMaxPlayers == 1 )
			AddSlainHero();
		if ( currlevel == quests[1]._qlevel && quests[1]._qactive == 1 )
			AddMushPatch();
		if ( currlevel == 4 )
			AddStoryBooks();
		if ( currlevel == 8 )
			AddStoryBooks();
		if ( currlevel == 12 )
			AddStoryBooks();
		if ( leveltype == 1 )
		{
			_LOBYTE(v1) = QuestStatus(6);
			if ( v1 )
				AddTortures();
			_LOBYTE(v2) = QuestStatus(13);
			if ( v2 )
				AddCandles();
			_LOBYTE(v3) = QuestStatus(7);
			if ( v3 )
				AddObject(97, 2 * setpc_x + 26, 2 * setpc_y + 19);
			InitRndLocBigObj(10, 15, 48);
			AddL1Objs(0, 0, 112, 112);
			InitRndBarrels();
		}
		if ( leveltype == 2 )
		{
			_LOBYTE(v4) = QuestStatus(0);
			if ( v4 )
				InitRndLocObj5x5(1, 1, 23);
			_LOBYTE(v5) = QuestStatus(14);
			if ( v5 )
				InitRndLocObj5x5(1, 1, 41);
			AddL2Objs(0, 0, 112, 112);
			AddL2Torches();
			_LOBYTE(v6) = QuestStatus(8);
			if ( v6 )
			{
				v7 = plr[myplr]._pClass;
				if ( v7 )
				{
					if ( v7 == 1 )
					{
						v8 = 245;
					}
					else
					{
						v8 = 241;
						if ( v7 != 2 )
							v8 = v16;
					}
				}
				else
				{
					v8 = 237;
				}
				quests[8]._qmsg = v8;
				AddBookLever(0, 0, 112, 112, setpc_x, setpc_y, setpc_w + setpc_x + 1, setpc_h + setpc_y + 1, v8);
				v9 = LoadFileInMem("Levels\\L2Data\\Blind2.DUN", 0);
				LoadMapObjs(v9, 2 * setpc_x, 2 * setpc_y);
				mem_free_dbg(v9);
			}
			else
			{
				v8 = v16;
			}
			_LOBYTE(v10) = QuestStatus(9);
			if ( v10 )
			{
				v11 = plr[myplr]._pClass;
				if ( v11 )
				{
					if ( v11 == 1 )
					{
						v8 = 244;
					}
					else if ( v11 == 2 )
					{
						v8 = 240;
					}
				}
				else
				{
					v8 = 236;
				}
				quests[9]._qmsg = v8;
				AddBookLever(0, 0, 112, 112, setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7, v8);
				AddObject(73, 2 * setpc_x + 25, 2 * setpc_y + 32);
			}
			InitRndBarrels();
		}
		else
		{
			v8 = v16;
		}
		if ( leveltype == 3 )
		{
			AddL3Objs(0, 0, 112, 112);
			InitRndBarrels();
		}
		if ( leveltype == 4 )
		{
			_LOBYTE(v12) = QuestStatus(11);
			if ( v12 )
			{
				v13 = plr[myplr]._pClass;
				if ( v13 )
				{
					if ( v13 == 1 )
					{
						v8 = 246;
					}
					else if ( v13 == 2 )
					{
						v8 = 242;
					}
				}
				else
				{
					v8 = 238;
				}
				quests[11]._qmsg = v8;
				AddBookLever(0, 0, 112, 112, setpc_x, setpc_y, setpc_x + setpc_w, setpc_y + setpc_h, v8);
				v14 = LoadFileInMem("Levels\\L4Data\\Warlord.DUN", 0);
				LoadMapObjs(v14, 2 * setpc_x, 2 * setpc_y);
				mem_free_dbg(v14);
			}
			_LOBYTE(v15) = QuestStatus(15);
			if ( v15 && gbMaxPlayers == 1 )
				AddLazStand();
			InitRndBarrels();
			AddL4Goodies();
		}
		InitRndLocObj(5, 10, 5);
		InitRndLocObj(3, 6, 6);
		InitRndLocObj(1, 5, 7);
		if ( leveltype != 4 )
			AddObjTraps();
		if ( (unsigned char)leveltype > 1u )
			AddChestTraps();
		InitObjFlag = 0;
	}
}
// 5BB1ED: using guessed type char leveltype;
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;
// 679660: using guessed type char gbMaxPlayers;
// 67D7C0: using guessed type int InitObjFlag;

//----- (004427C5) --------------------------------------------------------
void __fastcall SetMapObjects(char *pMap, int startx, int starty)
{
	char *v3; // esi
	unsigned char v4; // al
	char *v5; // ecx
	int v6; // edi
	int v7; // eax
	int v8; // esi
	int v9; // ecx
	int v10; // esi
	int v11; // ecx
	int v12; // edi
	_BYTE *v13; // eax
	int v14; // ebx
	signed int v15; // ebx
	char *v16; // ST08_4
	unsigned char *v17; // eax
	int v18; // ecx
	int i; // ebx
	int v20[56]; // [esp+Ch] [ebp-10Ch]
	char arglist[32]; // [esp+ECh] [ebp-2Ch]
	_BYTE *v22; // [esp+10Ch] [ebp-Ch]
	int v23; // [esp+110h] [ebp-8h]
	_BYTE *v24; // [esp+114h] [ebp-4h]
	int y; // [esp+120h] [ebp+8h]

	v23 = startx;
	v3 = pMap;
	ClrAllObjects();
	memset(v20, 0, sizeof(v20));
	v4 = AllObjects[0].oload;
	InitObjFlag = 1;
	if ( AllObjects[0].oload != -1 )
	{
		v5 = &AllObjects[0].ofindex;
		do
		{
			if ( v4 == 1 && (unsigned char)leveltype == *((char *)v5 + 3) )
				v20[*(char *)v5] = 1;
			v4 = *((_BYTE *)v5 + 43);
			v5 += 44;
		}
		while ( v4 != -1 );
	}
	v6 = (unsigned char)*v3;
	v7 = (int)(v3 + 2);
	v8 = (unsigned char)v3[2];
	v9 = v8;
	v10 = 2 * v8;
	v11 = v6 * v9;
	v12 = 2 * v6;
	v13 = (_BYTE *)(2 * v11 + 2 + 4 * v12 * v10 + v7);
	v22 = v13;
	if ( v10 > 0 )
	{
		v24 = (_BYTE *)v10;
		do
		{
			if ( v12 > 0 )
			{
				v14 = v12;
				do
				{
					if ( *v13 )
						v20[(char)AllObjects[ObjTypeConv[(unsigned char)*v13]].ofindex] = 1;
					v13 += 2;
					--v14;
				}
				while ( v14 );
			}
			--v24;
		}
		while ( v24 );
	}
	v15 = 0;
	do
	{
		if ( v20[v15] )
		{
			v16 = ObjMasterLoadList[v15];
			ObjFileList[numobjfiles] = v15;
			sprintf(arglist, "Objects\\%s.CEL", v16);
			v17 = LoadFileInMem(arglist, 0);
			v18 = numobjfiles++;
			pObjCels[v18] = (int)v17;
		}
		++v15;
	}
	while ( v15 < 56 );
	v24 = v22;
	if ( v10 > 0 )
	{
		y = starty + 16;
		do
		{
			for ( i = 0; i < v12; ++i )
			{
				if ( *v24 )
					AddObject(ObjTypeConv[(unsigned char)*v24], i + v23 + 16, y);
				v24 += 2;
			}
			++y;
			--v10;
		}
		while ( v10 );
	}
	InitObjFlag = 0;
}
// 5BB1ED: using guessed type char leveltype;
// 67D7C0: using guessed type int InitObjFlag;
// 67D7C4: using guessed type int numobjfiles;
// 4427C5: using guessed type int var_10C[56];

//----- (0044292B) --------------------------------------------------------
void __fastcall DeleteObject(int oi, int i)
{
	int v2; // eax
	bool v3; // zf
	bool v4; // sf

	dObject[object[oi]._ox][object[oi]._oy] = 0;
	v2 = nobjects - 1;
	v3 = nobjects == 1;
	v4 = nobjects - 1 < 0;
	*(&object[0]._otype - nobjects) = oi;
	nobjects = v2;
	if ( !v4 && !v3 && i != v2 )
		objectactive[i] = objectactive[v2];
}

//----- (0044297B) --------------------------------------------------------
void __fastcall SetupObject(int i, int x, int y, int ot)
{
	int v4; // esi
	int v5; // edi
	int v6; // ecx
	int v7; // edx
	int v8; // eax
	int v9; // eax
	int v10; // edx
	int v11; // eax
	int v12; // ecx
	int v13; // eax
	int v14; // eax
	unsigned char v15; // al

	v4 = i;
	object[v4]._otype = ot;
	v5 = ot;
	v6 = AllObjects[ot].ofindex;
	object[v4]._ox = x;
	object[v4]._oy = y;
	v7 = ObjFileList[0];
	v8 = 0;
	while ( v7 != v6 )
		v7 = ObjFileList[v8++ + 1];
	object[v4]._oAnimCel = pObjCels[v8];
	v9 = AllObjects[v5].oAnimFlag;
	object[v4]._oAnimFlag = v9;
	if ( v9 )
	{
		v10 = AllObjects[v5].oAnimDelay;
		_LOBYTE(v6) = -110;
		object[v4]._oAnimDelay = v10;
		object[v4]._oAnimCnt = random(v6, v10);
		v11 = AllObjects[v5].oAnimLen;
		_LOBYTE(v12) = -110;
		object[v4]._oAnimLen = v11;
		v13 = random(v12, v11 - 1) + 1;
	}
	else
	{
		v14 = AllObjects[v5].oAnimLen;
		object[v4]._oAnimDelay = 1000;
		object[v4]._oAnimLen = v14;
		v13 = AllObjects[v5].oAnimDelay;
		object[v4]._oAnimCnt = 0;
	}
	object[v4]._oAnimFrame = v13;
	object[v4]._oAnimWidth = AllObjects[v5].oAnimWidth;
	object[v4]._oSolidFlag = AllObjects[v5].oSolidFlag;
	object[v4]._oMissFlag = AllObjects[v5].oMissFlag;
	object[v4]._oLight = AllObjects[v5].oLightFlag;
	_LOBYTE(object[v4]._oBreak) = AllObjects[v5].oBreak;
	v15 = AllObjects[v5].oSelFlag;
	object[v4]._oDelFlag = 0;
	_LOBYTE(object[v4]._oSelFlag) = v15;
	object[v4]._oPreFlag = 0;
	object[v4]._oTrapFlag = 0;
	object[v4]._oDoorFlag = 0;
}

//----- (00442A9D) --------------------------------------------------------
void __fastcall SetObjMapRange(int i, int x1, int y1, int x2, int y2, int v)
{
	int v6; // ecx

	v6 = i;
	object[v6]._oVar2 = y1;
	object[v6]._oVar3 = x2;
	object[v6]._oVar4 = y2;
	object[v6]._oVar1 = x1;
	object[v6]._oVar8 = v;
}

//----- (00442AD1) --------------------------------------------------------
void __fastcall SetBookMsg(int i, int msg)
{
	object[i]._oVar7 = msg;
}

//----- (00442ADB) --------------------------------------------------------
void __fastcall AddL1Door(int i, int x, int y, int ot)
{
	int v4; // ecx
	int v5; // edx
	int *v6; // eax
	int v7; // edx
	int v8; // eax
	int v9; // eax

	v4 = i;
	v5 = 112 * x;
	object[v4]._oDoorFlag = 1;
	if ( ot == 1 )
	{
		v6 = (int *)((char *)dPiece + 4 * (y + v5));
		v7 = *v6;
		v8 = *(v6 - 1);
	}
	else
	{
		v9 = v5 + y;
		v7 = dPiece[0][v5 + y];
		v8 = *(_DWORD *)&dflags[28][4 * v9 + 32];
	}
	object[v4]._oVar4 = 0;
	object[v4]._oVar1 = v7;
	object[v4]._oVar2 = v8;
}

//----- (00442B2C) --------------------------------------------------------
void __fastcall AddSCambBook(int i)
{
	int v1; // ecx
	int v2; // eax
	int v3; // edx
	int v4; // esi

	v1 = i;
	v2 = setpc_x;
	v3 = setpc_y;
	v4 = setpc_w;
	object[v1]._oVar1 = setpc_x;
	object[v1]._oVar2 = v3;
	object[v1]._oVar3 = v4 + v2 + 1;
	object[v1]._oVar4 = setpc_h + v3 + 1;
	object[v1]._oVar6 = object[v1]._oAnimFrame + 1;
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00442B75) --------------------------------------------------------
void __fastcall AddChest(int i, int t)
{
	int v2; // edi
	int v3; // esi
	int v4; // esi
	int v5; // ecx
	int v6; // [esp-4h] [ebp-Ch]

	v2 = t;
	v3 = i;
	_LOBYTE(i) = -109;
	if ( !random(i, 2) )
		object[v3]._oAnimFrame += 3;
	v4 = v3;
	object[v4]._oRndSeed = GetRndSeed();
	switch ( v2 )
	{
		case OBJ_CHEST1:
			goto LABEL_22;
		case OBJ_CHEST2:
LABEL_12:
			if ( setlevel )
			{
				object[v4]._oVar1 = 2;
				break;
			}
			v6 = 3;
			goto LABEL_18;
		case OBJ_CHEST3:
LABEL_9:
			if ( setlevel )
			{
				object[v4]._oVar1 = 3;
				break;
			}
			v6 = 4;
LABEL_18:
			_LOBYTE(v5) = -109;
			object[v4]._oVar1 = random(v5, v6);
			break;
		case OBJ_TCHEST1:
LABEL_22:
			if ( setlevel )
			{
				object[v4]._oVar1 = 1;
				break;
			}
			v6 = 2;
			goto LABEL_18;
		case OBJ_TCHEST2:
			goto LABEL_12;
		case OBJ_TCHEST3:
			goto LABEL_9;
	}
	_LOBYTE(v5) = -109;
	object[v4]._oVar2 = random(v5, 8);
}
// 5CF31D: using guessed type char setlevel;

//----- (00442C27) --------------------------------------------------------
void __fastcall AddL2Door(int i, int x, int y, int ot)
{
	int v4; // esi

	v4 = i;
	object[i]._oDoorFlag = 1;
	if ( ot == 42 )
		ObjSetMicro(x, y, 538);
	else
		ObjSetMicro(x, y, 540);
	object[v4]._oVar4 = 0;
}

//----- (00442C62) --------------------------------------------------------
void __fastcall AddL3Door(int i, int x, int y, int ot)
{
	int v4; // esi

	v4 = i;
	object[i]._oDoorFlag = 1;
	if ( ot == 74 )
		ObjSetMicro(x, y, 531);
	else
		ObjSetMicro(x, y, 534);
	object[v4]._oVar4 = 0;
}

//----- (00442C9D) --------------------------------------------------------
void __fastcall AddSarc(int i)
{
	int v1; // esi
	char v2; // al
	int v3; // ecx
	int v4; // eax
	bool v5; // sf
	unsigned char v6; // of

	v1 = i;
	v2 = -1 - i;
	v3 = 112 * object[i]._ox;
	dungeon[39][v3 + 39 + object[v1]._oy] = v2;
	_LOBYTE(v3) = -103;
	object[v1]._oVar1 = random(v3, 10);
	v4 = GetRndSeed();
	v6 = __OFSUB__(object[v1]._oVar1, 8);
	v5 = object[v1]._oVar1 - 8 < 0;
	object[v1]._oRndSeed = v4;
	if ( !(v5 ^ v6) )
		object[v1]._oVar2 = PreSpawnSkeleton();
}

//----- (00442CEE) --------------------------------------------------------
void __fastcall AddFlameTrap(int i)
{
	int v1; // ecx
	int v2; // eax

	v1 = i;
	v2 = trapid;
	object[v1]._oVar2 = 0;
	object[v1]._oVar4 = 0;
	object[v1]._oVar1 = v2;
	object[v1]._oVar3 = trapdir;
}
// 679768: using guessed type int trapid;
// 67976C: using guessed type int trapdir;

//----- (00442D16) --------------------------------------------------------
void __fastcall AddFlameLvr(int i)
{
	int v1; // ecx

	v1 = i;
	object[v1]._oVar1 = trapid;
	object[v1]._oVar2 = 49;
}
// 679768: using guessed type int trapid;

//----- (00442D2F) --------------------------------------------------------
void __fastcall AddTrap(int i)
{
	int v1; // esi
	int v2; // eax

	v1 = i;
	v2 = random(148, currlevel / 3 + 1);
	if ( !v2 )
		object[v1]._oVar3 = 0;
	if ( v2 == 1 )
		object[v1]._oVar3 = 1;
	if ( v2 == 2 )
		object[v1]._oVar3 = 7;
	object[v1]._oVar4 = 0;
}

//----- (00442D8A) --------------------------------------------------------
void __fastcall AddObjLight(int i, int r)
{
	int v2; // esi

	if ( InitObjFlag )
	{
		v2 = i;
		DoLighting(object[i]._ox, object[i]._oy, r, -1);
		object[v2]._oVar1 = -1;
	}
	else
	{
		object[i]._oVar1 = 0;
	}
}
// 67D7C0: using guessed type int InitObjFlag;

//----- (00442DC1) --------------------------------------------------------
void __fastcall AddBarrel(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	int v4; // eax
	int v5; // ecx
	int v6; // eax
	bool v7; // sf
	unsigned char v8; // of

	v1 = i;
	object[i]._oVar1 = 0;
	v2 = GetRndSeed();
	_LOBYTE(v3) = -107;
	object[v1]._oRndSeed = v2;
	v4 = random(v3, 10);
	_LOBYTE(v5) = -107;
	object[v1]._oVar2 = v4;
	v6 = random(v5, 3);
	v8 = __OFSUB__(object[v1]._oVar2, 8);
	v7 = object[v1]._oVar2 - 8 < 0;
	object[v1]._oVar3 = v6;
	if ( !(v7 ^ v8) )
		object[v1]._oVar4 = PreSpawnSkeleton();
}

//----- (00442E0F) --------------------------------------------------------
void __fastcall AddShrine(int i)
{
	int v1; // esi
	signed int v2; // edi
	signed int v3; // eax
	int *v4; // ecx
	bool v5; // zf
	int v6; // eax
	int v7[26]; // [esp+8h] [ebp-68h]

	v1 = i;
	v2 = currlevel;
	v3 = 0;
	object[i]._oPreFlag = 1;
	do
	{
		if ( v2 < (char)shrinemin[v3] || v2 > (char)shrinemax[v3] )
		{
			v4 = &v7[v3];
			*v4 = 0;
		}
		else
		{
			v4 = &v7[v3];
			*v4 = 1;
		}
		if ( gbMaxPlayers == 1 )
			v5 = shrineavail[v3] == 2;
		else
			v5 = shrineavail[v3] == 1;
		if ( v5 )
			*v4 = 0;
		++v3;
	}
	while ( v3 < 26 );
	do
	{
		_LOBYTE(v4) = -106;
		v6 = random((int)v4, 26);
	}
	while ( !v7[v6] );
	_LOBYTE(v4) = -106;
	object[v1]._oVar1 = v6;
	if ( random((int)v4, 2) )
	{
		object[v1]._oAnimFrame = 12;
		object[v1]._oAnimLen = 22;
	}
}
// 679660: using guessed type char gbMaxPlayers;
// 442E0F: using guessed type int var_68[26];

//----- (00442EB2) --------------------------------------------------------
void __fastcall AddBookcase(int i)
{
	int v1; // esi

	v1 = i;
	object[v1]._oRndSeed = GetRndSeed();
	object[v1]._oPreFlag = 1;
}

//----- (00442ECF) --------------------------------------------------------
void __fastcall AddPurifyingFountain(int i)
{
	char *v1; // eax

	v1 = &dObject[object[i]._ox][object[i]._oy];
	*(v1 - 1) = -1 - i;
	*(v1 - 112) = -1 - i;
	*(v1 - 113) = -1 - i;
	object[i]._oRndSeed = GetRndSeed();
}

//----- (00442F08) --------------------------------------------------------
void __fastcall AddArmorStand(int i)
{
	int v1; // eax

	if ( !armorFlag )
	{
		v1 = i;
		_LOBYTE(object[v1]._oSelFlag) = 0;
		object[v1]._oAnimFlag = 2;
	}
	object[i]._oRndSeed = GetRndSeed();
}
// 6AAA3C: using guessed type int armorFlag;

//----- (00442F3A) --------------------------------------------------------
void __fastcall AddDecap(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	int v4; // eax

	v1 = i;
	v2 = GetRndSeed();
	_LOBYTE(v3) = -105;
	object[v1]._oRndSeed = v2;
	v4 = random(v3, 8);
	object[v1]._oPreFlag = 1;
	object[v1]._oAnimFrame = v4 + 1;
}

//----- (00442F68) --------------------------------------------------------
void __fastcall AddVilebook(int i)
{
	if ( setlevel )
	{
		if ( setlvlnum == SL_VILEBETRAYER )
			object[i]._oAnimFrame = 4;
	}
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (00442F88) --------------------------------------------------------
void __fastcall AddMagicCircle(int i)
{
	int v1; // esi
	int v2; // eax

	v1 = i;
	v2 = GetRndSeed();
	object[v1]._oVar6 = 0;
	object[v1]._oRndSeed = v2;
	object[v1]._oPreFlag = 1;
	object[v1]._oVar5 = 1;
}

//----- (00442FB1) --------------------------------------------------------
void __fastcall AddBookstand(int i)
{
	object[i]._oRndSeed = GetRndSeed();
}

//----- (00442FC4) --------------------------------------------------------
void __fastcall AddPedistal(int i)
{
	int v1; // ecx
	int v2; // eax
	int v3; // edx
	int v4; // esi
	int v5; // esi
	int v6; // eax

	v1 = i;
	v2 = setpc_x;
	v3 = setpc_y;
	v4 = setpc_w;
	object[v1]._oVar1 = setpc_x;
	v5 = v2 + v4;
	v6 = setpc_h;
	object[v1]._oVar3 = v5;
	object[v1]._oVar2 = v3;
	object[v1]._oVar4 = v3 + v6;
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00442FFC) --------------------------------------------------------
void __fastcall AddStoryBook(int i)
{
	int v1; // esi
	int v2; // ecx
	int v3; // eax
	unsigned char v4; // dl
	int v5; // ecx
	bool v6; // zf
	int v7; // eax

	v1 = i;
	SetRndSeed(glSeedTbl[16]);
	_LOBYTE(v2) = 0;
	v3 = random(v2, 3);
	v4 = currlevel;
	v5 = v1;
	v6 = currlevel == 4;
	object[v1]._oVar1 = v3;
	if ( v6 )
		object[v5]._oVar2 = StoryText[v3][0];
	if ( v4 == 8 )
		object[v5]._oVar2 = StoryText[v3][1];
	if ( v4 == 12 )
		object[v5]._oVar2 = StoryText[v3][2];
	object[v5]._oVar3 = ((unsigned int)v4 >> 2) + 3 * v3 - 1;
	v7 = 5 - 2 * v3;
	object[v5]._oAnimFrame = v7;
	object[v5]._oVar4 = v7 + 1;
}

//----- (0044308E) --------------------------------------------------------
void __fastcall AddWeaponRack(int i)
{
	int v1; // eax

	if ( !weaponFlag )
	{
		v1 = i;
		_LOBYTE(object[v1]._oSelFlag) = 0;
		object[v1]._oAnimFlag = 2;
	}
	object[i]._oRndSeed = GetRndSeed();
}
// 6AAA50: using guessed type int weaponFlag;

//----- (004430C0) --------------------------------------------------------
void __fastcall AddTorturedBody(int i)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	int v4; // eax

	v1 = i;
	v2 = GetRndSeed();
	_LOBYTE(v3) = 0;
	object[v1]._oRndSeed = v2;
	v4 = random(v3, 4);
	object[v1]._oPreFlag = 1;
	object[v1]._oAnimFrame = v4 + 1;
}

//----- (004430EE) --------------------------------------------------------
void __fastcall GetRndObjLoc(int randarea, int *xx, int *yy)
{
	int *v3; // ebx
	int v4; // eax
	int v5; // ecx
	int v6; // eax
	int v7; // esi
	BOOL v8; // eax
	int v9; // edi
	int v10; // [esp+Ch] [ebp-Ch]
	int v11; // [esp+10h] [ebp-8h]
	int v12; // [esp+14h] [ebp-4h]

	v3 = xx;
	v12 = randarea;
	if ( randarea )
	{
		v10 = 0;
		while ( 1 )
		{
LABEL_3:
			if ( ++v10 > 1000 && v12 > 1 )
				--v12;
			_LOBYTE(randarea) = 0;
			v4 = random(randarea, 112);
			_LOBYTE(v5) = 0;
			*v3 = v4;
			v6 = random(v5, 112);
			v7 = v6;
			*yy = v6;
			v8 = 0;
			v11 = 0;
			if ( v12 <= 0 )
				break;
			while ( !v8 )
			{
				v9 = 0;
				do
				{
					if ( v8 )
						break;
					v8 = RndLocOk(v11 + *v3, v7 + v9++) == 0;
				}
				while ( v9 < v12 );
				randarea = ++v11;
				if ( v11 >= v12 )
				{
					if ( v8 )
						goto LABEL_3;
					return;
				}
			}
		}
	}
}

//----- (00443178) --------------------------------------------------------
void __cdecl AddMushPatch()
{
	char v0; // bl
	int v1; // esi
	int v2; // eax
	int v3; // edx
	int yy; // [esp+0h] [ebp-8h]
	int xx; // [esp+4h] [ebp-4h]

	if ( nobjects < 127 )
	{
		v0 = objectavail[0];
		GetRndObjLoc(5, &xx, &yy);
		v1 = xx;
		v2 = yy + 112 * xx;
		v3 = yy + 2;
		dObject[1][v2 + 1] = -1 - v0;
		dObject[2][v2 + 1] = -1 - v0;
		dObject[1][v2 + 2] = -1 - v0;
		AddObject(94, v1 + 2, v3);
	}
}

//----- (004431D4) --------------------------------------------------------
void __cdecl AddSlainHero()
{
	int xx; // [esp+0h] [ebp-8h]
	int yy; // [esp+4h] [ebp-4h]

	GetRndObjLoc(5, &xx, &yy);
	AddObject(96, xx + 2, yy + 2);
}

//----- (004431FF) --------------------------------------------------------
void __fastcall AddObject(int ot, int ox, int oy)
{
	int v3; // ebp
	int v4; // esi
	unsigned int v5; // eax
	int v6; // ebx
	int v7; // ebx
	int v8; // eax

	v3 = ox;
	v4 = ot;
	if ( nobjects < 127 )
	{
		v5 = 4 * nobjects;
		v6 = objectavail[0];
		objectactive[v5 / 4] = objectavail[0];
		objectavail[0] = objectavail[v5 / 0xFFFFFFFC + 126];
		dObject[ox][oy] = v6 + 1;
		SetupObject(v6, ox, oy, ot);
		switch ( v4 )
		{
			case OBJ_L1LIGHT:
			case OBJ_SKFIRE:
			case OBJ_CANDLE1:
			case OBJ_CANDLE2:
			case OBJ_BOOKCANDLE:
				goto LABEL_31;
			case OBJ_L1LDOOR:
			case OBJ_L1RDOOR:
				AddL1Door(v6, v3, oy, v4);
				break;
			case OBJ_CHEST1:
			case OBJ_CHEST2:
			case OBJ_CHEST3:
			case OBJ_TCHEST1:
			case OBJ_TCHEST2:
			case OBJ_TCHEST3:
				AddChest(v6, v4);
				break;
			case OBJ_BOOK2L:
				AddVilebook(v6);
				break;
			case OBJ_BCROSS:
			case OBJ_TBCROSS:
				AddBookstand(v6);
LABEL_31:
				AddObjLight(v6, 5);
				break;
			case OBJ_TNUDEM2:
				AddTorturedBody(v6);
				break;
			case OBJ_BOOK2R:
				AddSCambBook(v6);
				break;
			case OBJ_L2LDOOR:
			case OBJ_L2RDOOR:
				AddL2Door(v6, v3, oy, v4);
				break;
			case OBJ_TORCHL:
			case OBJ_TORCHR:
			case OBJ_TORCHL2:
			case OBJ_TORCHR2:
				AddObjLight(v6, 8);
				break;
			case OBJ_SARC:
				AddSarc(v6);
				break;
			case OBJ_FLAMEHOLE:
				AddFlameTrap(v6);
				break;
			case OBJ_FLAMELVR:
				AddFlameLvr(v6);
				break;
			case OBJ_WATER:
				object[v6]._oAnimFrame = 1;
				break;
			case OBJ_TRAPL:
			case OBJ_TRAPR:
				AddTrap(v6);
				break;
			case OBJ_BARREL:
			case OBJ_BARRELEX:
				AddBarrel(v6);
				break;
			case OBJ_SHRINEL:
			case OBJ_SHRINER:
				AddShrine(v6);
				break;
			case OBJ_SKELBOOK:
			case OBJ_BOOKSTAND:
				AddBookstand(v6);
				break;
			case OBJ_BOOKCASEL:
			case OBJ_BOOKCASER:
				AddBookcase(v6);
				break;
			case OBJ_BLOODFTN:
				AddBookstand(v6);
				break;
			case OBJ_DECAP:
				AddDecap(v6);
				break;
			case OBJ_PEDISTAL:
				AddPedistal(v6);
				break;
			case OBJ_L3LDOOR:
			case OBJ_L3RDOOR:
				AddL3Door(v6, v3, oy, v4);
				break;
			case OBJ_PURIFYINGFTN:
				AddPurifyingFountain(v6);
				break;
			case OBJ_ARMORSTAND:
			case OBJ_WARARMOR:
				AddArmorStand(v6);
				break;
			case OBJ_GOATSHRINE:
				AddBookstand(v6);
				break;
			case OBJ_CAULDRON:
				AddBookstand(v6);
				break;
			case OBJ_MURKYFTN:
				AddPurifyingFountain(v6);
				break;
			case OBJ_TEARFTN:
				AddBookstand(v6);
				break;
			case OBJ_MCIRCLE1:
			case OBJ_MCIRCLE2:
				AddMagicCircle(v6);
				break;
			case OBJ_STORYBOOK:
				AddStoryBook(v6);
				break;
			case OBJ_STORYCANDLE:
				AddObjLight(v6, 3);
				break;
			case OBJ_WARWEAP:
			case OBJ_WEAPONRACK:
				AddWeaponRack(v6);
				break;
			default:
				break;
		}
		v7 = v6;
		v8 = object[v7]._oAnimWidth - 64;
		++nobjects;
		object[v7]._oAnimWidth2 = v8 >> 1;
	}
}

//----- (004434CB) --------------------------------------------------------
void __fastcall Obj_Light(int i, int lr)
{
	int v2; // esi
	int v3; // ebx
	int *v4; // edi
	int v5; // ST18_4
	int v6; // eax
	int r; // [esp+Ch] [ebp-14h]
	int x; // [esp+14h] [ebp-Ch]
	int y; // [esp+18h] [ebp-8h]
	signed int v10; // [esp+1Ch] [ebp-4h]

	v2 = i;
	r = lr;
	if ( object[i]._oVar1 != -1 )
	{
		v10 = 0;
		x = object[v2]._ox;
		v3 = lr + 10;
		y = object[v2]._oy;
		if ( lightflag )
		{
LABEL_15:
			if ( object[v2]._oVar1 == 1 )
				AddUnLight(object[v2]._olid);
			object[v2]._oVar1 = 0;
		}
		else
		{
			v4 = &plr[0].plrlevel;
			while ( !v10 )
			{
				if ( *((_BYTE *)v4 - 23) )
				{
					if ( currlevel == *v4 )
					{
						v5 = abs(v4[1] - x);
						v6 = abs(v4[2] - y);
						if ( v5 < v3 && v6 < v3 )
							v10 = 1;
					}
				}
				v4 += 5430;
				if ( (signed int)v4 >= (signed int)&plr_msgs[0].player )
				{
					if ( !v10 )
						goto LABEL_15;
					break;
				}
			}
			if ( !object[v2]._oVar1 )
				object[v2]._olid = AddLight(x, y, r);
			object[v2]._oVar1 = 1;
		}
	}
}
// 646A28: using guessed type int lightflag;

//----- (004435B5) --------------------------------------------------------
void __fastcall Obj_Circle(int i)
{
	int v1; // ecx
	int v2; // edx
	int v3; // esi
	int v4; // eax
	int v5; // ST1C_4
	int v6; // edx
	int v7; // eax

	v1 = i;
	v2 = object[v1]._ox;
	v3 = object[v1]._oy;
	if ( plr[myplr].WorldX != v2 || plr[myplr].WorldY != v3 )
	{
		v7 = object[v1]._otype;
		if ( v7 == OBJ_MCIRCLE1 )
			object[v1]._oAnimFrame = 1;
		if ( v7 == OBJ_MCIRCLE2 )
			object[v1]._oAnimFrame = 3;
		object[v1]._oVar6 = 0;
	}
	else
	{
		v4 = object[v1]._otype;
		if ( v4 == OBJ_MCIRCLE1 )
			object[v1]._oAnimFrame = 2;
		if ( v4 == OBJ_MCIRCLE2 )
			object[v1]._oAnimFrame = 4;
		if ( v2 == 45 )
		{
			if ( v3 == 47 )
			{
				object[v1]._oVar6 = 2;
				return;
			}
		}
		else if ( v2 == 26 && v3 == 46 )
		{
			object[v1]._oVar6 = 1;
			return;
		}
		object[v1]._oVar6 = 0;
		if ( v2 == 35 && v3 == 36 && object[v1]._oVar5 == 3 )
		{
			v5 = object[v1]._oVar4;
			v6 = object[v1]._oVar2;
			object[v1]._oVar6 = 4;
			ObjChangeMapResync(object[v1]._oVar1, v6, object[v1]._oVar3, v5);
			if ( quests[15]._qactive == 2 )
				quests[15]._qvar1 = 4;
			AddMissile(plr[myplr].WorldX, plr[myplr].WorldY, 35, 46, plr[myplr]._pdir, 3, 0, myplr, 0, 0);
			track_mouse_stance(0);
			sgbMouseDown = 0;
			ReleaseCapture();
			ClrPlrPath(myplr);
			StartStand(myplr, 0);
		}
	}
}
// 525748: using guessed type char sgbMouseDown;

//----- (00443727) --------------------------------------------------------
void __fastcall Obj_StopAnim(int i)
{
	int v1; // ecx

	v1 = i;
	if ( object[v1]._oAnimFrame == object[v1]._oAnimLen )
	{
		object[v1]._oAnimCnt = 0;
		object[v1]._oAnimDelay = 1000;
	}
}

//----- (0044374A) --------------------------------------------------------
void __fastcall Obj_Door(int i)
{
	int v1; // ecx
	int v2; // edx
	int v3; // eax

	v1 = i;
	if ( object[v1]._oVar4 )
	{
		v2 = object[v1]._oy;
		v3 = object[v1]._ox;
		_LOBYTE(object[v1]._oSelFlag) = 2;
		object[v1]._oMissFlag = 1;
		object[v1]._oVar4 = ((dItem[v3][v2] == 0
						   && dDead[v3][v2] == 0
						   && dPlayer[v3][v2] == 0
						   && dMonster[0][v3 * 112 + v2] == 0) == 0)
						  + 1;
	}
	else
	{
		object[v1]._oMissFlag = 0;
		_LOBYTE(object[v1]._oSelFlag) = 3;
	}
}

//----- (004437CD) --------------------------------------------------------
void __fastcall Obj_Sarc(int i)
{
	int v1; // ecx

	v1 = i;
	if ( object[v1]._oAnimFrame == object[v1]._oAnimLen )
		object[v1]._oAnimFlag = 0;
}

//----- (004437E6) --------------------------------------------------------
void __fastcall ActivateTrapLine(int ttype, int tid)
{
	int v2; // edi
	int i; // ebp
	int v4; // esi
	int v5; // edx
	int v6; // ecx
	int v7; // [esp+8h] [ebp-4h]

	v2 = 0;
	v7 = tid;
	for ( i = ttype; v2 < nobjects; ++v2 )
	{
		v4 = objectactive[v2];
		if ( object[v4]._otype == i && object[v4]._oVar1 == v7 )
		{
			v5 = object[v4]._oy;
			v6 = object[v4]._ox;
			object[v4]._oVar4 = 1;
			object[v4]._oAnimFlag = 1;
			object[v4]._oAnimDelay = 1;
			object[v4]._olid = AddLight(v6, v5, 1);
		}
	}
}

//----- (00443855) --------------------------------------------------------
void __fastcall Obj_FlameTrap(int i)
{
	int v1; // ecx
	int *v2; // esi
	int v3; // eax
	int v4; // ecx
	bool v5; // zf
	bool v6; // sf
	unsigned char v7; // of
	int v8; // edx
	int v9; // eax
	signed int v10; // esi
	int v11; // eax
	_BYTE *v12; // edx
	_DWORD *v13; // eax
	int v14; // eax
	_BYTE *v15; // edx
	_DWORD *v16; // eax
	int *v17; // eax

	v1 = i;
	if ( object[v1]._oVar2 )
	{
		v2 = &object[v1]._oVar4;
		if ( !object[v1]._oVar4 )
			return;
		v3 = --object[v1]._oAnimFrame;
		if ( v3 == 1 )
		{
			v4 = object[v1]._olid;
			*v2 = 0;
			AddUnLight(v4);
			return;
		}
		v7 = __OFSUB__(v3, 4);
		v5 = v3 == 4;
		v6 = v3 - 4 < 0;
		goto LABEL_24;
	}
	if ( object[v1]._oVar4 )
	{
		v17 = &object[v1]._oAnimFrame;
		if ( object[v1]._oAnimFrame == object[v1]._oAnimLen )
			*v17 = 11;
		v3 = *v17;
		v7 = __OFSUB__(v3, 5);
		v5 = v3 == 5;
		v6 = v3 - 5 < 0;
LABEL_24:
		if ( (unsigned char)(v6 ^ v7) | v5 )
			ChangeLightRadius(object[v1]._olid, v3);
		return;
	}
	v8 = object[v1]._oy;
	v9 = object[v1]._ox;
	v10 = 5;
	if ( object[v1]._oVar3 == 2 )
	{
		v11 = v8 + 112 * (v9 - 2);
		v12 = (unsigned char *)dPlayer + v11;
		v13 = (_DWORD *)((char *)dMonster + 4 * v11);
		do
		{
			if ( *v12 || *v13 )
				object[v1]._oVar4 = 1;
			v13 += 112;
			v12 += 112;
			--v10;
		}
		while ( v10 );
	}
	else
	{
		v14 = v8 - 2 + 112 * v9;
		v15 = (unsigned char *)dPlayer + v14;
		v16 = (_DWORD *)((char *)dMonster + 4 * v14);
		do
		{
			if ( *v15 || *v16 )
				object[v1]._oVar4 = 1;
			++v16;
			++v15;
			--v10;
		}
		while ( v10 );
	}
	if ( object[v1]._oVar4 )
		ActivateTrapLine(object[v1]._otype, object[v1]._oVar1);
}

//----- (00443966) --------------------------------------------------------
void __fastcall Obj_Trap(int i)
{
	int edi1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // eax
	int v5; // ebx
	int v6; // ecx
	int v7; // eax
	int v8; // ecx
	char *j; // edx
	int v10; // eax
	int v11; // [esp+8h] [ebp-1Ch]
	int v12; // [esp+10h] [ebp-14h]
	int sx; // [esp+14h] [ebp-10h]
	int sy; // [esp+18h] [ebp-Ch]
	int v15; // [esp+1Ch] [ebp-8h]
	int v1; // [esp+20h] [ebp-4h]

	edi1 = i;
	if ( object[i]._oVar4 )
		return;
	v2 = dObject[object[edi1]._oVar1][object[edi1]._oVar2] - 1;
	v3 = object[v2]._otype;
	if ( v3 <= OBJ_L2RDOOR )
	{
		if ( v3 < OBJ_L2LDOOR )
		{
			if ( v3 <= 0 )
				return;
			if ( v3 > OBJ_L1RDOOR )
			{
				if ( v3 <= OBJ_SKFIRE || v3 > OBJ_CHEST3 && v3 != OBJ_SWITCHSKL )
					return;
				goto LABEL_9;
			}
		}
LABEL_17:
		if ( !object[v2]._oVar4 )
			return;
		goto LABEL_10;
	}
	if ( v3 != OBJ_SARC )
	{
		if ( v3 <= OBJ_PEDISTAL || v3 > OBJ_L3RDOOR )
			return;
		goto LABEL_17;
	}
LABEL_9:
	if ( _LOBYTE(object[v2]._oSelFlag) )
		return;
LABEL_10:
	v4 = object[edi1]._ox;
	object[edi1]._oVar4 = 1;
	v5 = object[v2]._oy;
	v6 = object[v2]._ox;
	sx = v4;
	sy = object[edi1]._oy;
	v7 = v5 - 1;
	v1 = object[v2]._ox;
	v11 = v5 + 1;
	if ( (unsigned char)(__OFSUB__(v5 - 1, v5 + 1) ^ 1) | (v5 - 1 == v5 + 1) )
	{
		v12 = v6 - 1;
		v15 = v6 + 1;
		do
		{
			v8 = v12;
			if ( v12 <= v15 )
			{
				for ( j = &dPlayer[v12][v7]; ; j += 112 )
				{
					if ( *j )
					{
						v1 = v8;
						v5 = v7;
					}
					if ( ++v8 > v15 )
						break;
				}
			}
			++v7;
		}
		while ( v7 <= v11 );
		v6 = v1;
	}
	if ( !deltaload )
	{
		v10 = GetDirection(sx, sy, v6, v5);
		AddMissile(sx, sy, v1, v5, v10, object[edi1]._oVar3, 1, -1, 0, 0);
		PlaySfxLoc(IS_TRAP, object[v2]._ox, object[v2]._oy);
	}
	object[v2]._oTrapFlag = 0;
}
// 676190: using guessed type int deltaload;

//----- (00443AD5) --------------------------------------------------------
void __fastcall Obj_BCrossDamage(int i)
{
	int v1; // esi
	bool v2; // zf
	int v3; // ecx
	int v4; // edx
	char v5; // al
	int v6; // ecx
	int v7; // [esp+4h] [ebp-18h]
	int v8; // [esp+8h] [ebp-14h]
	int v9; // [esp+Ch] [ebp-10h]
	int v10; // [esp+10h] [ebp-Ch]
	int v11; // [esp+14h] [ebp-8h]
	int v12; // [esp+18h] [ebp-4h]

	v1 = myplr;
	v12 = i;
	v2 = plr[myplr]._pmode == PM_DEATH;
	v8 = 6;
	v9 = PM_DEATH;
	v10 = 10;
	v11 = 12;
	if ( !v2 )
	{
		v3 = plr[v1]._pFireResist;
		if ( v3 > 0 )
			*(&v7 + (unsigned char)leveltype) -= v3 * *(&v7 + (unsigned char)leveltype) / 100;
		if ( plr[v1].WorldX == object[v12]._ox && plr[v1].WorldY == object[v12]._oy - 1 )
		{
			v4 = *(&v7 + (unsigned char)leveltype);
			plr[v1]._pHitPoints -= v4;
			plr[v1]._pHPBase -= v4;
			if ( (signed int)(plr[v1]._pHitPoints & 0xFFFFFFC0) <= 0 )
			{
				SyncPlrKill(myplr, 0);
LABEL_15:
				drawhpflag = 1;
				return;
			}
			v5 = plr[v1]._pClass;
			if ( v5 )
			{
				if ( v5 == 1 )
				{
					v6 = PS_ROGUE68;
				}
				else
				{
					if ( v5 != 2 )
						goto LABEL_15;
					v6 = PS_MAGE68;
				}
			}
			else
			{
				v6 = PS_WARR68;
			}
			PlaySfxLoc(v6, plr[v1].WorldX, plr[v1].WorldY);
			goto LABEL_15;
		}
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (00443BD2) --------------------------------------------------------
void __cdecl ProcessObjects()
{
	int v0; // ebx
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int *v4; // eax
	int *v5; // eax
	int v6; // edx

	v0 = 0;
	if ( nobjects > 0 )
	{
		while ( 1 )
		{
			v1 = objectactive[v0];
			v2 = objectactive[v0];
			v3 = object[v2]._otype;
			if ( v3 <= OBJ_SARC )
				break;
			if ( v3 <= OBJ_L3RDOOR )
			{
				if ( v3 >= OBJ_L3LDOOR )
					goto LABEL_32;
				if ( v3 == OBJ_FLAMEHOLE )
				{
					Obj_FlameTrap(v1);
					goto LABEL_40;
				}
				if ( v3 <= OBJ_BOOKLVR )
					goto LABEL_40;
				if ( v3 <= OBJ_TRAPR )
				{
					Obj_Trap(v1);
					goto LABEL_40;
				}
				if ( v3 <= OBJ_WEAPRACK )
					goto LABEL_40;
				if ( v3 <= OBJ_SHRINER )
				{
LABEL_29:
					Obj_StopAnim(v1);
					goto LABEL_40;
				}
				if ( v3 != OBJ_BOOKCANDLE )
					goto LABEL_40;
LABEL_28:
				Obj_Light(v1, 5);
				goto LABEL_40;
			}
			if ( v3 < OBJ_MCIRCLE1 )
				goto LABEL_40;
			if ( v3 <= OBJ_MCIRCLE2 )
			{
				Obj_Circle(v1);
			}
			else
			{
				if ( v3 != OBJ_STORYCANDLE )
				{
					if ( v3 != OBJ_TBCROSS )
						goto LABEL_40;
					goto LABEL_37;
				}
				Obj_Light(v1, 3);
			}
LABEL_40:
			if ( object[v2]._oAnimFlag )
			{
				v4 = &object[v2]._oAnimCnt;
				++*v4;
				if ( object[v2]._oAnimCnt >= object[v2]._oAnimDelay )
				{
					*v4 = 0;
					v5 = &object[v2]._oAnimFrame;
					++*v5;
					if ( object[v2]._oAnimFrame > object[v2]._oAnimLen )
						*v5 = 1;
				}
			}
			if ( ++v0 >= nobjects )
				goto LABEL_45;
		}
		if ( v3 == OBJ_SARC )
		{
			Obj_Sarc(v1);
			goto LABEL_40;
		}
		if ( v3 > OBJ_CRUX3 )
		{
			if ( v3 != OBJ_BCROSS )
			{
				if ( v3 <= OBJ_BOOK2R )
					goto LABEL_40;
				if ( v3 > OBJ_L2RDOOR )
				{
					if ( v3 <= OBJ_TORCHR2 )
						Obj_Light(v1, 8);
					goto LABEL_40;
				}
LABEL_32:
				Obj_Door(v1);
				goto LABEL_40;
			}
LABEL_37:
			Obj_Light(v1, 10);
			Obj_BCrossDamage(v1);
			goto LABEL_40;
		}
		if ( v3 >= OBJ_CRUX1 )
			goto LABEL_29;
		if ( !v3 )
		{
			Obj_Light(v1, 10);
			goto LABEL_40;
		}
		if ( v3 <= 0 )
			goto LABEL_40;
		if ( v3 <= OBJ_L1RDOOR )
			goto LABEL_32;
		if ( v3 != OBJ_SKFIRE && v3 != OBJ_CANDLE2 )
			goto LABEL_40;
		goto LABEL_28;
	}
LABEL_45:
	v6 = 0;
	while ( v6 < nobjects )
	{
		if ( object[objectactive[v6]]._oDelFlag )
		{
			DeleteObject(objectactive[v6], v6);
			v6 = 0;
		}
		else
		{
			++v6;
		}
	}
}

//----- (00443D69) --------------------------------------------------------
void __fastcall ObjSetMicro(int dx, int dy, int pn)
{
	int v3; // esi
	char *v4; // eax
	int v5; // edx
	signed int v6; // ecx
	int v7; // esi
	signed int v8; // ecx

	dPiece[0][dy + 112 * dx] = pn;
	v3 = pn - 1;
	v4 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(dx, dy);
	if ( leveltype == 4 )
	{
		v7 = *(_DWORD *)&dpiece_defs[0].blocks + 32 * v3;
		v8 = 0;
		do
		{
			*(_WORD *)&v4[2 * v8] = *(_WORD *)(v7 + 2 * ((v8 & 1) - (v8 & 0xE)) + 28);
			++v8;
		}
		while ( v8 < 16 );
	}
	else
	{
		v5 = *(_DWORD *)&dpiece_defs[0].blocks + 20 * v3;
		v6 = 0;
		do
		{
			*(_WORD *)&v4[2 * v6] = *(_WORD *)(v5 + 2 * ((v6 & 1) - (v6 & 0xE)) + 16);
			++v6;
		}
		while ( v6 < 10 );
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (00443DEA) --------------------------------------------------------
void __fastcall objects_set_door_piece(int x, int y)
{
	int v2; // edi
	int v3; // ST10_4
	int v4; // ST18_4
	short v5; // ST14_2
	short v6; // ST0C_2

	v2 = y;
	v3 = x;
	v4 = dPiece[0][y + 112 * x] - 1;
	v5 = *(_WORD *)(20 * (unsigned short)v4 + *(_DWORD *)&dpiece_defs[0].blocks + 16);
	v6 = *(_WORD *)(20 * (unsigned short)v4 + *(_DWORD *)&dpiece_defs[0].blocks + 18);
	dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y)] = v5;
	dpiece_defs_map_1[0][0][16 * gendung_41927A(v3, v2) + 1] = v6;
}

//----- (00443E62) --------------------------------------------------------
void __fastcall ObjSetMini(int x, int y, int v)
{
	unsigned short *v3; // esi
	unsigned short v4; // ax
	int v5; // eax
	int pn; // ST1C_4
	int v7; // ST18_4
	int v8; // ST14_4
	int v9; // ST10_4
	int v10; // esi
	int v11; // edi

	v3 = (unsigned short *)((char *)pMegaTiles + 8 * ((unsigned short)v - 1));
	v4 = *v3;
	++v3;
	v5 = v4 + 1;
	pn = v5;
	_LOWORD(v5) = *v3;
	++v3;
	v7 = ++v5;
	_LOWORD(v5) = *v3;
	v8 = ++v5;
	_LOWORD(v5) = v3[1];
	v9 = v5 + 1;
	v10 = 2 * x + 16;
	v11 = 2 * y + 16;
	ObjSetMicro(v10, v11, pn);
	ObjSetMicro(v10 + 1, v11++, v7);
	ObjSetMicro(v10, v11, v8);
	ObjSetMicro(v10 + 1, v11, v9);
}

//----- (00443EDA) --------------------------------------------------------
void __fastcall ObjL1Special(int x1, int y1, int x2, int y2)
{
	int i; // ebx
	int v5; // edx
	_BYTE *v6; // eax
	int *v7; // edi
	int v8; // edx
	int v9; // esi

	for ( i = y1; i <= y2; ++i )
	{
		if ( x1 <= x2 )
		{
			v5 = 112 * x1 + i;
			v6 = (unsigned char *)dArch + v5;
			v7 = (int *)((char *)dPiece + 4 * v5);
			v8 = x2 - x1 + 1;
			do
			{
				v9 = *v7;
				*v6 = 0;
				if ( v9 == 12 )
					*v6 = 1;
				if ( v9 == 11 )
					*v6 = 2;
				if ( v9 == 71 )
					*v6 = 1;
				if ( v9 == 259 )
					*v6 = 5;
				if ( v9 == 249 )
					*v6 = 2;
				if ( v9 == 325 )
					*v6 = 2;
				if ( v9 == 321 )
					*v6 = 1;
				if ( v9 == 255 )
					*v6 = 4;
				if ( v9 == 211 )
					*v6 = 1;
				if ( v9 == 344 )
					*v6 = 2;
				if ( v9 == 341 )
					*v6 = 1;
				if ( v9 == 331 )
					*v6 = 2;
				if ( v9 == 418 )
					*v6 = 1;
				if ( v9 == 421 )
					*v6 = 2;
				v7 += 112;
				v6 += 112;
				--v8;
			}
			while ( v8 );
		}
	}
}

//----- (00443FC6) --------------------------------------------------------
void __fastcall ObjL2Special(int x1, int y1, int x2, int y2)
{
	int v4; // edi
	int v5; // esi
	_BYTE *v6; // eax
	int *v7; // ebx
	int v8; // esi
	int v9; // edx
	int i; // edi
	int v11; // eax
	char *v12; // edx
	int *v13; // esi
	int v14; // eax
	int v15; // ebx
	int v16; // [esp+Ch] [ebp-4h]

	v4 = y1;
	v16 = y1;
	if ( y1 <= y2 )
	{
		do
		{
			if ( x1 <= x2 )
			{
				v5 = 112 * x1 + v4;
				v6 = (unsigned char *)dArch + v5;
				v7 = (int *)((char *)dPiece + 4 * v5);
				v8 = x2 - x1 + 1;
				do
				{
					v9 = *v7;
					*v6 = 0;
					if ( v9 == 541 )
						*v6 = 5;
					if ( v9 == 178 )
						*v6 = 5;
					if ( v9 == 551 )
						*v6 = 5;
					if ( v9 == 542 )
						*v6 = 6;
					if ( v9 == 553 )
						*v6 = 6;
					if ( v9 == 13 )
						*v6 = 5;
					if ( v9 == 17 )
						*v6 = 6;
					v7 += 112;
					v6 += 112;
					--v8;
				}
				while ( v8 );
			}
			++v4;
		}
		while ( v4 <= y2 );
		for ( i = v16; i <= y2; ++i )
		{
			if ( x1 <= x2 )
			{
				v11 = i + 112 * x1;
				v12 = &dArch[0][v11 + 2];
				v13 = (int *)((char *)dPiece + 4 * v11);
				v14 = x2 - x1 + 1;
				do
				{
					v15 = *v13;
					if ( *v13 == 132 )
					{
						*(v12 - 1) = 2;
						*v12 = 1;
					}
					if ( v15 == 135 || v15 == 139 )
					{
						v12[110] = 3;
						v12[222] = 4;
					}
					v13 += 112;
					v12 += 112;
					--v14;
				}
				while ( v14 );
			}
		}
	}
}

//----- (004440C2) --------------------------------------------------------
void __fastcall DoorSet(int oi, int dx, int dy)
{
	int v3; // esi
	int v4; // ebp
	int v5; // ebx
	ObjectStruct *v6; // ebp

	v3 = dx;
	v4 = oi;
	v5 = dPiece[0][dy + 112 * dx];
	if ( v5 == 43 )
		ObjSetMicro(dx, dy, 392);
	if ( v5 == 45 )
		ObjSetMicro(v3, dy, 394);
	if ( v5 != 50 )
		goto LABEL_10;
	v6 = &object[v4];
	if ( v6->_otype == OBJ_L1LDOOR )
		ObjSetMicro(v3, dy, 411);
	if ( v6->_otype == OBJ_L1RDOOR )
	{
		ObjSetMicro(v3, dy, 412);
LABEL_10:
		if ( v5 == 54 )
			ObjSetMicro(v3, dy, 397);
		if ( v5 == 55 )
			ObjSetMicro(v3, dy, 398);
		if ( v5 == 61 )
			ObjSetMicro(v3, dy, 399);
		if ( v5 == 67 )
			ObjSetMicro(v3, dy, 400);
		if ( v5 == 68 )
			ObjSetMicro(v3, dy, 401);
		if ( v5 == 69 )
			ObjSetMicro(v3, dy, 403);
		if ( v5 == 70 )
			ObjSetMicro(v3, dy, 404);
		if ( v5 == 72 )
			ObjSetMicro(v3, dy, 406);
		if ( v5 == 212 )
			ObjSetMicro(v3, dy, 407);
		if ( v5 == 354 )
			ObjSetMicro(v3, dy, 409);
		if ( v5 == 355 )
			ObjSetMicro(v3, dy, 410);
		if ( v5 == 411 )
			ObjSetMicro(v3, dy, 396);
		if ( v5 == 412 )
			ObjSetMicro(v3, dy, 396);
	}
}

//----- (00444246) --------------------------------------------------------
void __cdecl RedoPlayerVision()
{
	int *v0; // esi

	v0 = &plr[0].plrlevel;
	do
	{
		if ( *((_BYTE *)v0 - 23) )
		{
			if ( currlevel == *v0 )
				ChangeVisionXY(v0[27], v0[1], v0[2]);
		}
		v0 += 5430;
	}
	while ( (signed int)v0 < (signed int)&plr_msgs[0].player );
}

//----- (0044427B) --------------------------------------------------------
void __fastcall OperateL1RDoor(int pnum, int oi, unsigned char sendflag)
{
	int v3; // esi
	int v4; // eax
	int v5; // ebx
	int v6; // edi
	int v7; // ST04_4
	int v8; // [esp+Ch] [ebp-Ch]
	int v9; // [esp+10h] [ebp-8h]
	int param1; // [esp+14h] [ebp-4h]

	v3 = oi;
	param1 = oi;
	v9 = pnum;
	v4 = object[oi]._oVar4;
	if ( v4 != 2 )
	{
		v5 = object[v3]._ox;
		v6 = object[v3]._oy;
		if ( v4 )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_DOORCLOS, v5, object[v3]._oy);
			v8 = v6 + 112 * v5;
			if ( dDead[0][v8] != 0 || dMonster[0][v8] != 0 || dItem[0][v8] != 0 )
			{
				object[v3]._oVar4 = 2;
				return;
			}
			if ( v9 == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1);
			v7 = object[v3]._oVar1;
			object[v3]._oVar4 = 0;
			_LOBYTE(object[v3]._oSelFlag) = 3;
			ObjSetMicro(v5, v6, v7);
			if ( object[v3]._oVar2 == 50 )
			{
				if ( *(_DWORD *)&dflags[28][4 * v8 + 32] == 396 )
					ObjSetMicro(v5 - 1, v6, 411);
				else
					ObjSetMicro(v5 - 1, v6, 50);
			}
			else
			{
				ObjSetMicro(v5 - 1, v6, object[v3]._oVar2);
			}
			object[v3]._oAnimFrame -= 2;
			object[v3]._oPreFlag = 0;
		}
		else
		{
			if ( pnum == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_OPENDOOR, oi);
			if ( !deltaload )
				PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy);
			ObjSetMicro(v5, v6, 395);
			dArch[v5][v6] = 8;
			objects_set_door_piece(v5, v6 - 1);
			object[v3]._oAnimFrame += 2;
			object[v3]._oPreFlag = 1;
			DoorSet(param1, v5 - 1, v6);
			object[v3]._oVar4 = 1;
			_LOBYTE(object[v3]._oSelFlag) = 2;
		}
		RedoPlayerVision();
		return;
	}
	if ( !deltaload )
		PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy);
}
// 676190: using guessed type int deltaload;

//----- (0044443C) --------------------------------------------------------
void __fastcall OperateL1LDoor(int pnum, int oi, unsigned char sendflag)
{
	int v3; // esi
	int v4; // eax
	int v5; // ebx
	int v6; // edi
	int v7; // ST04_4
	int v8; // [esp+Ch] [ebp-Ch]
	int v9; // [esp+10h] [ebp-8h]
	int param1; // [esp+14h] [ebp-4h]

	v3 = oi;
	param1 = oi;
	v9 = pnum;
	v4 = object[oi]._oVar4;
	if ( v4 != 2 )
	{
		v5 = object[v3]._ox;
		v6 = object[v3]._oy;
		if ( v4 )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_DOORCLOS, v5, object[v3]._oy);
			v8 = v6 + 112 * v5;
			if ( dDead[v5][v6] != 0 || dMonster[0][v8] != 0 || dItem[v5][v6] != 0 )
			{
				object[v3]._oVar4 = 2;
				return;
			}
			if ( v9 == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1);
			v7 = object[v3]._oVar1;
			object[v3]._oVar4 = 0;
			_LOBYTE(object[v3]._oSelFlag) = 3;
			ObjSetMicro(v5, v6, v7);
			if ( object[v3]._oVar2 == 50 )
			{
				if ( *(_DWORD *)&dflags[39][v8 * 4 + 36] == 396 )
					ObjSetMicro(v5, v6 - 1, 412);
				else
					ObjSetMicro(v5, v6 - 1, 50);
			}
			else
			{
				ObjSetMicro(v5, v6 - 1, object[v3]._oVar2);
			}
			object[v3]._oAnimFrame -= 2;
			object[v3]._oPreFlag = 0;
		}
		else
		{
			if ( pnum == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_OPENDOOR, oi);
			if ( !deltaload )
				PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy);
			if ( object[v3]._oVar1 == 214 )
				ObjSetMicro(v5, v6, 408);
			else
				ObjSetMicro(v5, v6, 393);
			dArch[v5][v6] = 7;
			objects_set_door_piece(v5 - 1, v6);
			object[v3]._oAnimFrame += 2;
			object[v3]._oPreFlag = 1;
			DoorSet(param1, v5, v6 - 1);
			object[v3]._oVar4 = 1;
			_LOBYTE(object[v3]._oSelFlag) = 2;
		}
		RedoPlayerVision();
		return;
	}
	if ( !deltaload )
		PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy);
}
// 676190: using guessed type int deltaload;

//----- (00444613) --------------------------------------------------------
void __fastcall OperateL2RDoor(int pnum, int oi, unsigned char sendflag)
{
	int v3; // esi
	int v4; // eax
	int v5; // ebx
	short param1; // [esp+Ch] [ebp-Ch]
	int v7; // [esp+10h] [ebp-8h]
	int v8; // [esp+14h] [ebp-4h]

	v3 = oi;
	param1 = oi;
	v7 = pnum;
	v4 = object[oi]._oVar4;
	if ( v4 != 2 )
	{
		v5 = object[v3]._oy;
		v8 = object[v3]._ox;
		if ( v4 )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5);
			if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 )
			{
				object[v3]._oVar4 = 2;
				return;
			}
			if ( v7 == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1);
			object[v3]._oVar4 = 0;
			_LOBYTE(object[v3]._oSelFlag) = 3;
			ObjSetMicro(v8, v5, 540);
			object[v3]._oAnimFrame -= 2;
			object[v3]._oPreFlag = 0;
		}
		else
		{
			if ( pnum == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_OPENDOOR, oi);
			if ( !deltaload )
				PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy);
			ObjSetMicro(v8, v5, 17);
			object[v3]._oAnimFrame += 2;
			object[v3]._oPreFlag = 1;
			object[v3]._oVar4 = 1;
			_LOBYTE(object[v3]._oSelFlag) = 2;
		}
		RedoPlayerVision();
		return;
	}
	if ( !deltaload )
		PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy);
}
// 676190: using guessed type int deltaload;

//----- (00444775) --------------------------------------------------------
void __fastcall OperateL2LDoor(int pnum, int oi, unsigned char sendflag)
{
	int v3; // esi
	int v4; // eax
	int v5; // ebx
	short param1; // [esp+Ch] [ebp-Ch]
	int v7; // [esp+10h] [ebp-8h]
	int v8; // [esp+14h] [ebp-4h]

	v3 = oi;
	param1 = oi;
	v7 = pnum;
	v4 = object[oi]._oVar4;
	if ( v4 != 2 )
	{
		v5 = object[v3]._oy;
		v8 = object[v3]._ox;
		if ( v4 )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5);
			if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 )
			{
				object[v3]._oVar4 = 2;
				return;
			}
			if ( v7 == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1);
			object[v3]._oVar4 = 0;
			_LOBYTE(object[v3]._oSelFlag) = 3;
			ObjSetMicro(v8, v5, 538);
			object[v3]._oAnimFrame -= 2;
			object[v3]._oPreFlag = 0;
		}
		else
		{
			if ( pnum == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_OPENDOOR, oi);
			if ( !deltaload )
				PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy);
			ObjSetMicro(v8, v5, 13);
			object[v3]._oAnimFrame += 2;
			object[v3]._oPreFlag = 1;
			object[v3]._oVar4 = 1;
			_LOBYTE(object[v3]._oSelFlag) = 2;
		}
		RedoPlayerVision();
		return;
	}
	if ( !deltaload )
		PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy);
}
// 676190: using guessed type int deltaload;

//----- (004448D7) --------------------------------------------------------
void __fastcall OperateL3RDoor(int pnum, int oi, unsigned char sendflag)
{
	int v3; // esi
	int v4; // eax
	int v5; // ebx
	short param1; // [esp+Ch] [ebp-Ch]
	int v7; // [esp+10h] [ebp-8h]
	int v8; // [esp+14h] [ebp-4h]

	v3 = oi;
	param1 = oi;
	v7 = pnum;
	v4 = object[oi]._oVar4;
	if ( v4 != 2 )
	{
		v5 = object[v3]._oy;
		v8 = object[v3]._ox;
		if ( v4 )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5);
			if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 )
			{
				object[v3]._oVar4 = 2;
				return;
			}
			if ( v7 == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1);
			object[v3]._oVar4 = 0;
			_LOBYTE(object[v3]._oSelFlag) = 3;
			ObjSetMicro(v8, v5, 534);
			object[v3]._oAnimFrame -= 2;
			object[v3]._oPreFlag = 0;
		}
		else
		{
			if ( pnum == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_OPENDOOR, oi);
			if ( !deltaload )
				PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy);
			ObjSetMicro(v8, v5, 541);
			object[v3]._oAnimFrame += 2;
			object[v3]._oPreFlag = 1;
			object[v3]._oVar4 = 1;
			_LOBYTE(object[v3]._oSelFlag) = 2;
		}
		RedoPlayerVision();
		return;
	}
	if ( !deltaload )
		PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy);
}
// 676190: using guessed type int deltaload;

//----- (00444A3C) --------------------------------------------------------
void __fastcall OperateL3LDoor(int pnum, int oi, unsigned char sendflag)
{
	int v3; // esi
	int v4; // eax
	int v5; // ebx
	short param1; // [esp+Ch] [ebp-Ch]
	int v7; // [esp+10h] [ebp-8h]
	int v8; // [esp+14h] [ebp-4h]

	v3 = oi;
	param1 = oi;
	v7 = pnum;
	v4 = object[oi]._oVar4;
	if ( v4 != 2 )
	{
		v5 = object[v3]._oy;
		v8 = object[v3]._ox;
		if ( v4 )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, v5);
			if ( dDead[v8][v5] != 0 || dMonster[0][v5 + 112 * v8] != 0 || dItem[v8][v5] != 0 )
			{
				object[v3]._oVar4 = 2;
				return;
			}
			if ( v7 == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_CLOSEDOOR, param1);
			object[v3]._oVar4 = 0;
			_LOBYTE(object[v3]._oSelFlag) = 3;
			ObjSetMicro(v8, v5, 531);
			object[v3]._oAnimFrame -= 2;
			object[v3]._oPreFlag = 0;
		}
		else
		{
			if ( pnum == myplr && sendflag )
				NetSendCmdParam1(1u, CMD_OPENDOOR, oi);
			if ( !deltaload )
				PlaySfxLoc(IS_DOOROPEN, object[v3]._ox, object[v3]._oy);
			ObjSetMicro(v8, v5, 538);
			object[v3]._oAnimFrame += 2;
			object[v3]._oPreFlag = 1;
			object[v3]._oVar4 = 1;
			_LOBYTE(object[v3]._oSelFlag) = 2;
		}
		RedoPlayerVision();
		return;
	}
	if ( !deltaload )
		PlaySfxLoc(IS_DOORCLOS, object[v3]._ox, object[v3]._oy);
}
// 676190: using guessed type int deltaload;

//----- (00444BA1) --------------------------------------------------------
void __fastcall MonstCheckDoors(int m)
{
	int v1; // ecx
	int v2; // eax
	int v3; // ecx
	int v4; // eax
	char *v5; // ecx
	int v6; // eax
	int v7; // esi
	int v8; // esi
	int v9; // eax
	int v10; // ebx
	int v11; // eax
	bool v12; // zf
	bool v13; // sf
	unsigned char v14; // of
	int v15; // eax
	int v16; // ebx
	int v17; // eax
	bool v18; // zf
	bool v19; // sf
	unsigned char v20; // of
	int v21; // eax
	int v22; // ebx
	int v23; // eax
	bool v24; // zf
	bool v25; // sf
	unsigned char v26; // of
	int v27; // [esp+0h] [ebp-14h]
	int v28; // [esp+4h] [ebp-10h]
	int v29; // [esp+8h] [ebp-Ch]
	int v30; // [esp+Ch] [ebp-8h]
	int v31; // [esp+Ch] [ebp-8h]
	int v32; // [esp+Ch] [ebp-8h]
	int oi; // [esp+10h] [ebp-4h]

	v1 = m;
	v2 = monster[v1]._mx;
	v3 = monster[v1]._my;
	v29 = v2;
	v4 = v3 + 112 * v2;
	v28 = v3;
	v5 = (char *)dObject + v4;
	if ( dObject[-1][v4 - 1]
	  || *(v5 - 1)
	  || dObject[0][v4 + 111]
	  || *(v5 - 112)
	  || dObject[1][v4]
	  || dObject[-1][v4 + 1]
	  || dObject[0][v4 + 1]
	  || dObject[1][v4 + 1] )
	{
		v6 = 0;
		v27 = 0;
		if ( nobjects > 0 )
		{
			while ( 1 )
			{
				v7 = objectactive[v6];
				oi = v7;
				v8 = v7;
				v9 = object[v8]._otype;
				if ( v9 != 1 && v9 != OBJ_L1RDOOR || object[v8]._oVar4 )
					goto LABEL_21;
				v10 = abs(object[v8]._ox - v29);
				v11 = abs(object[v8]._oy - v28);
				v14 = __OFSUB__(v10, 1);
				v12 = v10 == 1;
				v13 = v10 - 1 < 0;
				v30 = v11;
				if ( v10 != 1 )
					goto LABEL_17;
				if ( v11 <= 1 && object[v8]._otype == 1 )
					break;
LABEL_18:
				if ( v30 == 1 && object[v8]._otype == OBJ_L1RDOOR )
					OperateL1RDoor(myplr, oi, 1u);
LABEL_21:
				v15 = object[v8]._otype;
				if ( v15 != OBJ_L2LDOOR && v15 != OBJ_L2RDOOR || object[v8]._oVar4 )
					goto LABEL_32;
				v16 = abs(object[v8]._ox - v29);
				v17 = abs(object[v8]._oy - v28);
				v20 = __OFSUB__(v16, 1);
				v18 = v16 == 1;
				v19 = v16 - 1 < 0;
				v31 = v17;
				if ( v16 != 1 )
					goto LABEL_28;
				if ( v17 <= 1 && object[v8]._otype == OBJ_L2LDOOR )
				{
					OperateL2LDoor(myplr, oi, 1u);
					v20 = 0;
					v18 = 1;
					v19 = 0;
LABEL_28:
					if ( !((unsigned char)(v19 ^ v20) | v18) )
						goto LABEL_32;
				}
				if ( v31 == 1 && object[v8]._otype == OBJ_L2RDOOR )
					OperateL2RDoor(myplr, oi, 1u);
LABEL_32:
				v21 = object[v8]._otype;
				if ( v21 != OBJ_L3LDOOR && v21 != OBJ_L3RDOOR || object[v8]._oVar4 )
					goto LABEL_43;
				v22 = abs(object[v8]._ox - v29);
				v23 = abs(object[v8]._oy - v28);
				v26 = __OFSUB__(v22, 1);
				v24 = v22 == 1;
				v25 = v22 - 1 < 0;
				v32 = v23;
				if ( v22 == 1 )
				{
					if ( v23 > 1 || object[v8]._otype != OBJ_L3RDOOR )
					{
LABEL_40:
						if ( v32 == 1 && object[v8]._otype == OBJ_L3LDOOR )
							OperateL3LDoor(myplr, oi, 1u);
						goto LABEL_43;
					}
					OperateL3RDoor(myplr, oi, 1u);
					v26 = 0;
					v24 = 1;
					v25 = 0;
				}
				if ( (unsigned char)(v25 ^ v26) | v24 )
					goto LABEL_40;
LABEL_43:
				v6 = v27++ + 1;
				if ( v27 >= nobjects )
					return;
			}
			OperateL1LDoor(myplr, oi, 1u);
			v14 = 0;
			v12 = 1;
			v13 = 0;
LABEL_17:
			if ( !((unsigned char)(v13 ^ v14) | v12) )
				goto LABEL_21;
			goto LABEL_18;
		}
	}
}

//----- (00444DC3) --------------------------------------------------------
void __fastcall DRLG_MRectTrans(int x1, int y1, int x2, int y2)
{
	int v4; // ebx
	int v5; // edi
	int v6; // esi
	int v7; // ecx
	int v8; // edi
	int v9; // ebx
	int v10; // ecx
	int v11; // [esp+Ch] [ebp-8h]
	int a2; // [esp+10h] [ebp-4h]
	int i; // [esp+1Ch] [ebp+8h]
	int y_end; // [esp+20h] [ebp+Ch]

	v4 = y1;
	v5 = x2;
	v6 = x1;
	for ( a2 = y1; a2 <= y2; ++a2 )
	{
		i = v6;
		if ( v6 <= v5 )
		{
			v11 = a2 + 40 * v6;
			do
			{
				ObjSetMini(i++, a2, (unsigned char)pdungeon[0][v11]);
				dungeon[0][v11] = pdungeon[0][v11];
				v11 += 40;
			}
			while ( i <= v5 );
		}
	}
	if ( leveltype == 1 )
	{
		ObjL1Special(2 * v6 + 16, 2 * v4 + 16, 2 * v5 + 17, 2 * y2 + 17);
		AddL1Objs(v7, 2 * v4 + 16, 2 * v5 + 17, 2 * y2 + 17);
	}
	if ( leveltype == 2 )
	{
		v8 = 2 * v5 + 17;
		v9 = 2 * v4 + 16;
		y_end = 2 * y2 + 17;
		ObjL2Special(2 * v6 + 16, v9, v8, y_end);
		AddL2Objs(v10, v9, v8, y_end);
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (00444E9E) --------------------------------------------------------
void __fastcall ObjChangeMapResync(int x1, int y1, int x2, int y2)
{
	int v4; // edi
	int v5; // esi
	int v6; // ebx
	int v7; // edi
	int v8; // [esp+Ch] [ebp-Ch]
	int i; // [esp+10h] [ebp-8h]
	int a2; // [esp+14h] [ebp-4h]

	v4 = y2;
	v5 = y1;
	v6 = x1;
	v8 = y1;
	for ( a2 = y1; a2 <= v4; ++a2 )
	{
		i = v6;
		if ( v6 <= x2 )
		{
			v7 = a2 + 40 * v6;
			do
			{
				ObjSetMini(i++, a2, (unsigned char)pdungeon[0][v7]);
				dungeon[0][v7] = pdungeon[0][v7];
				v7 += 40;
			}
			while ( i <= x2 );
			v4 = y2;
			v5 = v8;
		}
	}
	if ( leveltype == 1 )
		ObjL1Special(2 * v6 + 16, 2 * v5 + 16, 2 * x2 + 17, 2 * v4 + 17);
	if ( leveltype == 2 )
		ObjL2Special(2 * v6 + 16, 2 * v5 + 16, 2 * x2 + 17, 2 * v4 + 17);
}
// 5BB1ED: using guessed type char leveltype;

//----- (00444F4F) --------------------------------------------------------
void __fastcall OperateL1Door(int pnum, int i, unsigned char sendflag)
{
	int v3; // ebx
	int v4; // edi
	int v5; // esi
	int v6; // ST1C_4
	int v7; // eax
	bool v8; // zf
	bool v9; // sf
	unsigned char v10; // of
	int v11; // [esp+Ch] [ebp-Ch]
	int pnuma; // [esp+10h] [ebp-8h]

	v3 = i;
	v4 = i;
	pnuma = pnum;
	v5 = pnum;
	v6 = abs(object[i]._ox - plr[pnum].WorldX);
	v7 = abs(object[v4]._oy - plr[v5].WorldY);
	v10 = __OFSUB__(v6, 1);
	v8 = v6 == 1;
	v9 = v6 - 1 < 0;
	v11 = v7;
	if ( v6 != 1 )
	{
LABEL_5:
		if ( !((unsigned char)(v9 ^ v10) | v8) )
			return;
		goto LABEL_6;
	}
	if ( v7 <= 1 && object[v4]._otype == 1 )
	{
		OperateL1LDoor(pnuma, v3, sendflag);
		v10 = 0;
		v8 = 1;
		v9 = 0;
		goto LABEL_5;
	}
LABEL_6:
	if ( v11 == 1 && object[v4]._otype == OBJ_L1RDOOR )
		OperateL1RDoor(pnuma, v3, sendflag);
}

//----- (00444FDE) --------------------------------------------------------
void __fastcall OperateLever(int pnum, int i)
{
	int v2; // esi
	int *v3; // edi
	signed int v4; // edi
	int v5; // ecx
	int v6; // eax
	short param1; // [esp+8h] [ebp-8h]
	int v8; // [esp+Ch] [ebp-4h]

	param1 = i;
	v2 = i;
	v3 = &object[i]._oSelFlag;
	v8 = pnum;
	if ( *(_BYTE *)v3 )
	{
		if ( !deltaload )
			PlaySfxLoc(IS_LEVER, object[v2]._ox, object[v2]._oy);
		*(_BYTE *)v3 = 0;
		++object[v2]._oAnimFrame;
		v4 = 1;
		if ( currlevel != 16 )
			goto LABEL_17;
		v5 = 0;
		if ( nobjects <= 0 )
			goto LABEL_17;
		do
		{
			v6 = objectactive[v5];
			if ( object[v6]._otype == OBJ_SWITCHSKL
			  && object[v2]._oVar8 == object[v6]._oVar8
			  && _LOBYTE(object[v6]._oSelFlag) )
			{
				v4 = 0;
			}
			++v5;
		}
		while ( v5 < nobjects );
		if ( v4 )
LABEL_17:
			DRLG_MRectTrans(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4);
		if ( v8 == myplr )
			NetSendCmdParam1(0, CMD_OPERATEOBJ, param1);
	}
}
// 676190: using guessed type int deltaload;

//----- (004450AC) --------------------------------------------------------
void __fastcall OperateBook(int pnum, int i)
{
	int esi1; // esi
	int v3; // edx
	signed int v4; // ecx
	int v5; // eax
	bool v6; // zf
	int v7; // ecx
	int *v8; // eax
	int j; // esi
	int v10; // [esp+Ch] [ebp-14h]
	signed int v11; // [esp+10h] [ebp-10h]
	signed int v1; // [esp+14h] [ebp-Ch]
	signed int v2; // [esp+18h] [ebp-8h]
	int v14; // [esp+1Ch] [ebp-4h]

	esi1 = i;
	v3 = pnum;
	v10 = pnum;
	if ( !_LOBYTE(object[esi1]._oSelFlag) )
		return;
	if ( !setlevel || setlvlnum != SL_VILEBETRAYER )
		goto LABEL_17;
	v4 = 0;
	v11 = 0;
	v14 = 0;
	if ( nobjects > 0 )
	{
		while ( 1 )
		{
			v5 = objectactive[v14];
			if ( object[v5]._otype == OBJ_MCIRCLE2 )
			{
				if ( object[v5]._oVar6 == 1 )
				{
					v1 = 27;
					v2 = 29;
					object[v5]._oVar6 = 4;
					v4 = 1;
				}
				if ( object[v5]._oVar6 == 2 )
				{
					v1 = 43;
					v2 = 29;
					object[v5]._oVar6 = 4;
					v4 = 1;
				}
			}
			if ( v4 )
			{
				++objectavail[30 * dObject[35][36] + 123];
				AddMissile(plr[v3].WorldX, plr[v3].WorldY, v1, v2, plr[v3]._pdir, 3, 0, v3, 0, 0);
				v11 = 1;
				v4 = 0;
			}
			if ( ++v14 >= nobjects )
				break;
			v3 = v10;
		}
		if ( v11 )
		{
			v3 = v10;
LABEL_17:
			++object[esi1]._oAnimFrame;
			v6 = setlevel == 0;
			_LOBYTE(object[esi1]._oSelFlag) = 0;
			if ( !v6 )
			{
				if ( setlvlnum == SL_BONECHAMB )
				{
					v7 = 21720 * myplr;
					v8 = plr[myplr]._pMemSpells;
					*((_BYTE *)v8 + 1) |= 0x10u;
					v8[1] = v8[1];
					if ( plr[v3]._pSplLvl[13] < 15 )
						++plr[0]._pSplLvl[v7 + 13];
					quests[14]._qactive = 3;
					if ( !deltaload )
						PlaySfxLoc(IS_QUESTDN, object[esi1]._ox, object[esi1]._oy);
					_LOBYTE(v7) = 43;
					InitDiabloMsg(v7);
					AddMissile(
						plr[myplr].WorldX,
						plr[myplr].WorldY,
						object[esi1]._ox - 2,
						object[esi1]._oy - 4,
						plr[myplr]._pdir,
						2,
						0,
						myplr,
						0,
						0);
				}
				if ( setlevel )
				{
					if ( setlvlnum == SL_VILEBETRAYER )
					{
						ObjChangeMapResync(
							object[esi1]._oVar1,
							object[esi1]._oVar2,
							object[esi1]._oVar3,
							object[esi1]._oVar4);
						for ( j = 0; j < nobjects; ++j )
							SyncObjectAnim(objectactive[j]);
					}
				}
			}
			return;
		}
	}
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;
// 676190: using guessed type int deltaload;

//----- (004452D1) --------------------------------------------------------
void __fastcall OperateBookLever(int pnum, int i)
{
	int v2; // esi
	int v3; // edi
	int v4; // ebp
	int v5; // edx
	int v6; // eax
	int v7; // ST0C_4
	int v8; // edx
	char v9; // bl
	int v10; // ST08_4
	int v11; // ecx
	int v12; // ecx
	int v13; // [esp+Ch] [ebp-8h]
	short param1; // [esp+10h] [ebp-4h]

	param1 = i;
	v2 = i;
	v13 = pnum;
	v3 = 2 * setpc_x + 16;
	v4 = 2 * setpc_y + 16;
	if ( _LOBYTE(object[i]._oSelFlag) && !qtextflag )
	{
		v5 = object[v2]._otype;
		if ( v5 == OBJ_BLINDBOOK && !quests[8]._qvar1 )
		{
			quests[8]._qactive = 2;
			quests[8]._qlog = 1;
			quests[8]._qvar1 = 1;
		}
		if ( v5 == OBJ_BLOODBOOK && !quests[9]._qvar1 )
		{
			quests[9]._qactive = 2;
			quests[9]._qlog = 1;
			quests[9]._qvar1 = 1;
			SpawnQuestItem(21, 2 * setpc_x + 19, 2 * setpc_y + 26, 0, 1);
			SpawnQuestItem(21, 2 * setpc_x + 31, 2 * setpc_y + 26, 0, 1);
			SpawnQuestItem(21, 2 * setpc_x + 25, 2 * setpc_y + 33, 0, 1);
		}
		v6 = object[v2]._otype;
		if ( v6 == OBJ_STEELTOME && !quests[11]._qvar1 )
		{
			quests[11]._qactive = 2;
			quests[11]._qlog = 1;
			quests[11]._qvar1 = 1;
		}
		if ( object[v2]._oAnimFrame != object[v2]._oVar6 )
		{
			if ( v6 != OBJ_BLOODBOOK )
				DRLG_MRectTrans(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4);
			if ( object[v2]._otype == OBJ_BLINDBOOK )
			{
				CreateItem(3, v3 + 5, v4 + 5);
				v7 = object[v2]._oVar4;
				v8 = object[v2]._oVar2;
				v9 = TransVal;
				v10 = object[v2]._oVar3;
				v11 = object[v2]._oVar1;
				TransVal = 9;
				Make_RectTrans(v11, v8, v10, v7);
				TransVal = v9;
			}
		}
		v12 = object[v2]._oVar7;
		object[v2]._oAnimFrame = object[v2]._oVar6;
		InitQTextMsg(v12);
		if ( v13 == myplr )
			NetSendCmdParam1(0, CMD_OPERATEOBJ, param1);
	}
}
// 5A5590: using guessed type char TransVal;
// 646D00: using guessed type char qtextflag;

//----- (00445483) --------------------------------------------------------
void __fastcall OperateSChambBk(int pnum, int i)
{
	int v2; // esi
	int j; // edi
	char v4; // al
	signed int v5; // ecx
	int speech_id; // [esp+4h] [ebp-4h]

	v2 = i;
	if ( _LOBYTE(object[i]._oSelFlag) && !qtextflag )
	{
		if ( object[v2]._oAnimFrame != object[v2]._oVar6 )
		{
			ObjChangeMapResync(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4);
			for ( j = 0; j < nobjects; ++j )
				SyncObjectAnim(objectactive[j]);
		}
		object[v2]._oAnimFrame = object[v2]._oVar6;
		if ( quests[14]._qactive == 1 )
		{
			quests[14]._qactive = 2;
			quests[14]._qlog = 1;
		}
		v4 = plr[myplr]._pClass;
		if ( v4 )
		{
			if ( v4 == 1 )
			{
				v5 = 243;
			}
			else
			{
				v5 = 239;
				if ( v4 != 2 )
					v5 = speech_id;
			}
		}
		else
		{
			v5 = 235;
		}
		quests[14]._qmsg = v5;
		InitQTextMsg(v5);
	}
}
// 646D00: using guessed type char qtextflag;

//----- (0044555A) --------------------------------------------------------
void __fastcall OperateChest(int pnum, int i, unsigned char sendmsg)
{
	int v3; // esi
	bool v4; // zf
	int v5; // edi
	int v6; // eax
	int v7; // eax
	int v8; // ecx
	int v9; // ecx
	int v10; // ecx
	signed int v11; // [esp-8h] [ebp-18h]
	short param2; // [esp+8h] [ebp-8h]
	int param1; // [esp+Ch] [ebp-4h]

	param2 = i;
	v3 = i;
	param1 = pnum;
	if ( _LOBYTE(object[i]._oSelFlag) )
	{
		if ( !deltaload )
			PlaySfxLoc(IS_CHEST, object[v3]._ox, object[v3]._oy);
		object[v3]._oAnimFrame += 2;
		v4 = deltaload == 0;
		_LOBYTE(object[v3]._oSelFlag) = 0;
		if ( v4 )
		{
			SetRndSeed(object[v3]._oRndSeed);
			v5 = 0;
			if ( setlevel )
			{
				if ( object[v3]._oVar1 > 0 )
				{
					do
					{
						CreateRndItem(object[v3]._ox, object[v3]._oy, 1u, sendmsg, 0);
						++v5;
					}
					while ( v5 < object[v3]._oVar1 );
				}
			}
			else if ( object[v3]._oVar1 > 0 )
			{
				do
				{
					if ( object[v3]._oVar2 )
						CreateRndItem(object[v3]._ox, object[v3]._oy, 0, sendmsg, 0);
					else
						CreateRndUseful(param1, object[v3]._ox, object[v3]._oy, sendmsg);
					++v5;
				}
				while ( v5 < object[v3]._oVar1 );
			}
			if ( !object[v3]._oTrapFlag )
				goto LABEL_26;
			v6 = object[v3]._otype;
			if ( v6 < OBJ_TCHEST1 || v6 > OBJ_TCHEST3 )
				goto LABEL_26;
			v7 = GetDirection(object[v3]._ox, object[v3]._oy, plr[param1].WorldX, plr[param1].WorldY);
			v8 = object[v3]._oVar4;
			if ( v8 )
			{
				v9 = v8 - 1;
				if ( v9 )
				{
					if ( v9 != 1 )
					{
						v10 = sendmsg;
						goto LABEL_25;
					}
					v11 = 42;
				}
				else
				{
					v11 = 27;
				}
				v10 = v11;
			}
			else
			{
				v10 = 0;
			}
LABEL_25:
			AddMissile(object[v3]._ox, object[v3]._oy, plr[param1].WorldX, plr[param1].WorldY, v7, v10, 1, -1, 0, 0);
			object[v3]._oTrapFlag = 0;
LABEL_26:
			if ( param1 == myplr )
				NetSendCmdParam2(0, CMD_PLROPOBJ, param1, param2);
			return;
		}
	}
}
// 5CF31D: using guessed type char setlevel;
// 676190: using guessed type int deltaload;

//----- (004456E3) --------------------------------------------------------
void __fastcall OperateMushPatch(int pnum, int i)
{
	int v2; // esi
	bool v3; // zf
	char v4; // al
	int v5; // ecx
	int xx; // [esp+8h] [ebp-8h]
	int yy; // [esp+Ch] [ebp-4h]

	if ( quests[1]._qactive != 2 || quests[1]._qvar1 < 2u )
	{
		if ( !deltaload && pnum == myplr )
		{
			v4 = plr[myplr]._pClass;
			if ( v4 )
			{
				if ( v4 == 1 )
				{
					v5 = PS_ROGUE13;
				}
				else
				{
					if ( v4 != 2 )
						return;
					v5 = PS_MAGE13;
				}
			}
			else
			{
				v5 = PS_WARR13;
			}
			PlaySFX(v5);
		}
	}
	else
	{
		v2 = i;
		if ( _LOBYTE(object[i]._oSelFlag) )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_CHEST, object[v2]._ox, object[v2]._oy);
			++object[v2]._oAnimFrame;
			v3 = deltaload == 0;
			_LOBYTE(object[v2]._oSelFlag) = 0;
			if ( v3 )
			{
				GetSuperItemLoc(object[v2]._ox, object[v2]._oy, &xx, &yy);
				SpawnQuestItem(17, xx, yy, 0, 0);
				quests[1]._qvar1 = 3;
			}
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (004457B8) --------------------------------------------------------
void __fastcall OperateInnSignChest(int pnum, int i)
{
	char v2; // al
	int v3; // ecx
	int v4; // esi
	bool v5; // zf
	int xx; // [esp+8h] [ebp-8h]
	int yy; // [esp+Ch] [ebp-4h]

	if ( quests[7]._qvar1 == 2 )
	{
		v4 = i;
		if ( _LOBYTE(object[i]._oSelFlag) )
		{
			if ( !deltaload )
				PlaySfxLoc(IS_CHEST, object[v4]._ox, object[v4]._oy);
			object[v4]._oAnimFrame += 2;
			v5 = deltaload == 0;
			_LOBYTE(object[v4]._oSelFlag) = 0;
			if ( v5 )
			{
				GetSuperItemLoc(object[v4]._ox, object[v4]._oy, &xx, &yy);
				SpawnQuestItem(12, xx, yy, 0, 0);
			}
		}
	}
	else if ( !deltaload && pnum == myplr )
	{
		v2 = plr[myplr]._pClass;
		switch ( v2 )
		{
			case UI_WARRIOR:
				v3 = PS_WARR24;
LABEL_8:
				PlaySFX(v3);
				return;
			case UI_ROGUE:
				v3 = PS_ROGUE24;
				goto LABEL_8;
			case UI_SORCERER:
				v3 = PS_MAGE24;
				goto LABEL_8;
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (00445880) --------------------------------------------------------
void __fastcall OperateSlainHero(int pnum, int i, unsigned char sendmsg)
{
	unsigned short v3; // di
	int v4; // esi
	int v5; // eax
	bool v6; // zf
	char v7; // cl
	int v8; // ecx

	v3 = i;
	v4 = pnum;
	v5 = i;
	if ( _LOBYTE(object[i]._oSelFlag) )
	{
		v6 = deltaload == 0;
		_LOBYTE(object[v5]._oSelFlag) = 0;
		if ( v6 )
		{
			v7 = plr[pnum]._pClass;
			if ( v7 )
			{
				if ( v7 == 1 )
				{
					CreateMagicItem(object[v5]._ox, object[v5]._oy, 3, 119, 0, 1);
					v8 = PS_ROGUE9;
				}
				else
				{
					if ( v7 != 2 )
						goto LABEL_10;
					CreateSpellBook(object[v5]._ox, object[v5]._oy, 3, 0, 1);
					v8 = PS_MAGE9;
				}
			}
			else
			{
				CreateMagicItem(object[v5]._ox, object[v5]._oy, 9, 153, 0, 1);
				v8 = PS_WARR9;
			}
			PlaySfxLoc(v8, plr[myplr].WorldX, plr[myplr].WorldY);
LABEL_10:
			if ( v4 == myplr )
				NetSendCmdParam1(0, CMD_OPERATEOBJ, v3);
			return;
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (00445954) --------------------------------------------------------
void __fastcall OperateTrapLvr(int i)
{
	int v1; // ecx
	int v2; // eax
	int v3; // esi
	int v4; // edx
	int v5; // eax
	int v6; // eax

	v1 = i;
	v2 = object[v1]._oAnimFrame;
	v3 = nobjects;
	v4 = 0;
	if ( v2 == 1 )
	{
		object[v1]._oAnimFrame = 2;
		if ( v3 > 0 )
		{
			do
			{
				v5 = objectactive[v4];
				if ( object[v5]._otype == object[v1]._oVar2 && object[v5]._oVar1 == object[v1]._oVar1 )
				{
					object[v5]._oAnimFlag = 0;
					object[v5]._oVar2 = 1;
				}
				++v4;
			}
			while ( v4 < v3 );
		}
	}
	else
	{
		object[v1]._oAnimFrame = v2 - 1;
		if ( v3 > 0 )
		{
			do
			{
				v6 = objectactive[v4];
				if ( object[v6]._otype == object[v1]._oVar2 && object[v6]._oVar1 == object[v1]._oVar1 )
				{
					object[v6]._oVar2 = 0;
					if ( object[v6]._oVar4 )
						object[v6]._oAnimFlag = 1;
				}
				++v4;
			}
			while ( v4 < v3 );
		}
	}
}

//----- (00445A0B) --------------------------------------------------------
void __fastcall OperateSarc(int pnum, int i, unsigned char sendmsg)
{
	unsigned short v3; // bp
	int v4; // esi
	bool v5; // zf
	int v6; // ecx
	int v7; // [esp+Ch] [ebp-4h]

	v3 = i;
	v4 = i;
	v7 = pnum;
	if ( _LOBYTE(object[i]._oSelFlag) )
	{
		if ( !deltaload )
			PlaySfxLoc(IS_SARC, object[v4]._ox, object[v4]._oy);
		v5 = deltaload == 0;
		_LOBYTE(object[v4]._oSelFlag) = 0;
		if ( v5 )
		{
			v6 = object[v4]._oRndSeed;
			object[v4]._oAnimFlag = 1;
			object[v4]._oAnimDelay = 3;
			SetRndSeed(v6);
			if ( object[v4]._oVar1 <= 2 )
				CreateRndItem(object[v4]._ox, object[v4]._oy, 0, sendmsg, 0);
			if ( object[v4]._oVar1 >= 8 )
				SpawnSkeleton(object[v4]._oVar2, object[v4]._ox, object[v4]._oy);
			if ( v7 == myplr )
				NetSendCmdParam1(0, CMD_OPERATEOBJ, v3);
		}
		else
		{
			object[v4]._oAnimFrame = object[v4]._oAnimLen;
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (00445ADC) --------------------------------------------------------
void __fastcall OperateL2Door(int pnum, int i, unsigned char sendflag)
{
	int v3; // ebx
	int v4; // edi
	int v5; // esi
	int v6; // ST1C_4
	int v7; // eax
	bool v8; // zf
	bool v9; // sf
	unsigned char v10; // of
	int v11; // [esp+Ch] [ebp-Ch]
	int pnuma; // [esp+10h] [ebp-8h]

	v3 = i;
	v4 = i;
	pnuma = pnum;
	v5 = pnum;
	v6 = abs(object[i]._ox - plr[pnum].WorldX);
	v7 = abs(object[v4]._oy - plr[v5].WorldY);
	v10 = __OFSUB__(v6, 1);
	v8 = v6 == 1;
	v9 = v6 - 1 < 0;
	v11 = v7;
	if ( v6 != 1 )
	{
LABEL_5:
		if ( !((unsigned char)(v9 ^ v10) | v8) )
			return;
		goto LABEL_6;
	}
	if ( v7 <= 1 && object[v4]._otype == OBJ_L2LDOOR )
	{
		OperateL2LDoor(pnuma, v3, sendflag);
		v10 = 0;
		v8 = 1;
		v9 = 0;
		goto LABEL_5;
	}
LABEL_6:
	if ( v11 == 1 && object[v4]._otype == OBJ_L2RDOOR )
		OperateL2RDoor(pnuma, v3, sendflag);
}

//----- (00445B6C) --------------------------------------------------------
void __fastcall OperateL3Door(int pnum, int i, unsigned char sendflag)
{
	int v3; // ebx
	int v4; // edi
	int v5; // esi
	int v6; // ST1C_4
	int v7; // eax
	bool v8; // zf
	bool v9; // sf
	unsigned char v10; // of
	int v11; // [esp+Ch] [ebp-Ch]
	int pnuma; // [esp+10h] [ebp-8h]

	v3 = i;
	v4 = i;
	pnuma = pnum;
	v5 = pnum;
	v6 = abs(object[i]._ox - plr[pnum].WorldX);
	v7 = abs(object[v4]._oy - plr[v5].WorldY);
	v10 = __OFSUB__(v6, 1);
	v8 = v6 == 1;
	v9 = v6 - 1 < 0;
	v11 = v7;
	if ( v6 != 1 )
	{
LABEL_5:
		if ( !((unsigned char)(v9 ^ v10) | v8) )
			return;
		goto LABEL_6;
	}
	if ( v7 <= 1 && object[v4]._otype == OBJ_L3RDOOR )
	{
		OperateL3RDoor(pnuma, v3, sendflag);
		v10 = 0;
		v8 = 1;
		v9 = 0;
		goto LABEL_5;
	}
LABEL_6:
	if ( v11 == 1 && object[v4]._otype == OBJ_L3LDOOR )
		OperateL3LDoor(pnuma, v3, sendflag);
}

//----- (00445BFC) --------------------------------------------------------
void __fastcall OperatePedistal(int pnum, int i)
{
	int v2; // esi
	int v3; // edi
	unsigned char *v4; // edi
	int inv_item_num; // [esp+8h] [ebp-4h]

	v2 = i;
	v3 = pnum;
	if ( object[i]._oVar6 != 3 )
	{
		if ( PlrHasItem(pnum, 21, &inv_item_num) )
		{
			RemoveInvItem(v3, inv_item_num);
			++object[v2]._oAnimFrame;
			++object[v2]._oVar6;
		}
		if ( object[v2]._oVar6 == 1 )
		{
			if ( !deltaload )
				PlaySfxLoc(LS_PUDDLE, object[v2]._ox, object[v2]._oy);
			DRLG_MRectTrans(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7);
		}
		if ( object[v2]._oVar6 == 2 )
		{
			if ( !deltaload )
				PlaySfxLoc(LS_PUDDLE, object[v2]._ox, object[v2]._oy);
			DRLG_MRectTrans(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7);
		}
		if ( object[v2]._oVar6 == 3 )
		{
			if ( !deltaload )
				PlaySfxLoc(LS_BLODSTAR, object[v2]._ox, object[v2]._oy);
			DRLG_MRectTrans(object[v2]._oVar1, object[v2]._oVar2, object[v2]._oVar3, object[v2]._oVar4);
			v4 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0);
			LoadMapObjs(v4, 2 * setpc_x, 2 * setpc_y);
			mem_free_dbg(v4);
			CreateItem(7, 2 * setpc_x + 25, 2 * setpc_y + 19);
			_LOBYTE(object[v2]._oSelFlag) = 0;
		}
	}
}
// 5CF334: using guessed type int setpc_w;
// 676190: using guessed type int deltaload;

//----- (00445D5F) --------------------------------------------------------
void __fastcall TryDisarm(int pnum, int i)
{
	int v2; // edi
	int v3; // esi
	int v4; // esi
	int v5; // edi
	int v6; // ebx
	int j; // edx
	signed int v8; // edi
	int v9; // eax
	int v10; // ecx
	int v11; // eax
	int v12; // [esp+Ch] [ebp-4h]

	v2 = pnum;
	v3 = i;
	v12 = i;
	if ( pnum == myplr )
		SetCursor(1);
	v4 = v3;
	if ( object[v4]._oTrapFlag )
	{
		_LOBYTE(pnum) = -102;
		v5 = 2 * plr[v2]._pDexterity - 5 * currlevel;
		if ( random(pnum, 100) <= v5 )
		{
			v6 = nobjects;
			for ( j = 0; j < v6; ++j )
			{
				v8 = 0;
				v9 = objectactive[j];
				v10 = object[v9]._otype;
				if ( v10 == OBJ_TRAPL )
					v8 = 1;
				if ( v10 == OBJ_TRAPR )
					v8 = 1;
				if ( v8 && dObject[object[v9]._oVar1][object[v9]._oVar2] - 1 == v12 )
				{
					object[v9]._oVar4 = 1;
					object[v4]._oTrapFlag = 0;
				}
			}
			v11 = object[v4]._otype;
			if ( v11 >= OBJ_TCHEST1 && v11 <= OBJ_TCHEST3 )
				object[v4]._oTrapFlag = 0;
		}
	}
}

//----- (00445E33) --------------------------------------------------------
int __fastcall ItemMiscIdIdx(int imiscid)
{
	int result; // eax
	int *i; // edx

	result = 0;
	for ( i = &AllItemsList[0].iMiscId; !*(i - 14) || *i != imiscid; i += 19 )
		++result;
	return result;
}

//----- (00445E4B) --------------------------------------------------------
void __fastcall OperateShrine(int player_num, int object_num, int sfx_id)
{
	int v3; // esi
	int *v4; // ebx
	int v5; // eax
	int v6; // ecx
	int v7; // ecx
	int v8; // ecx
	int v9; // eax
	int v10; // eax
	int v11; // eax
	int v12; // edx
	int v13; // esi
	signed int v14; // ebx
	int *v15; // eax
	int *v16; // eax
	int v17; // edx
	int v18; // ebx
	int *v19; // eax
	signed int v20; // edx
	int v21; // eax
	int v22; // ecx
	int *v23; // eax
	int v24; // edx
	int v25; // esi
	int v26; // eax
	int v27; // ecx
	int v28; // edx
	int *v29; // ecx
	int v30; // edx
	int v31; // ebx
	signed int v32; // edx
	int v33; // edx
	int v34; // eax
	int v35; // ecx
	int v36; // esi
	signed int v37; // edx
	int v38; // eax
	int *v39; // ecx
	signed int v40; // esi
	int v41; // esi
	int *v42; // ecx
	int *v43; // eax
	signed int v44; // ecx
	int v45; // eax
	int *v46; // ecx
	signed int v47; // edx
	int v48; // ebx
	int *v49; // ecx
	int *v50; // eax
	signed int v51; // ecx
	signed int v52; // edi
	int v53; // esi
	int v54; // ebx
	int v55; // eax
	bool v56; // zf
	signed int v57; // ebx
	unsigned int v58; // edi
	signed int v59; // edx
	int v60; // ebx
	char *v61; // esi
	int j; // edi
	int v63; // esi
	int v64; // eax
	int *v65; // eax
	int v66; // edx
	char v67; // al
	char v68; // al
	int v69; // esi
	int v70; // edx
	int v71; // ebx
	int v72; // edi
	int v73; // eax
	int v74; // edx
	int v75; // edx
	int v76; // edx
	int v77; // esi
	int v78; // ebx
	int *v79; // eax
	int v80; // eax
	int v81; // eax
	int *v82; // eax
	int v83; // eax
	int v84; // eax
	int v85; // ecx
	int v86; // edx
	int v87; // eax
	int v88; // ebx
	int v89; // eax
	int v90; // ecx
	int v91; // esi
	int v92; // eax
	int v93; // edx
	int *v94; // eax
	int v95; // edx
	char v96; // al
	char v97; // al
	int v98; // esi
	int v99; // edx
	int v100; // ebx
	int v101; // edi
	int v102; // eax
	int v103; // edx
	int v104; // edx
	int v105; // edx
	int v106; // ebx
	int v107; // ST38_4
	int v108; // ST34_4
	int v109; // ST3C_4
	int v110; // eax
	_BYTE *v111; // eax
	signed int v112; // edx
	int *v113; // eax
	int v114; // edx
	char v115; // al
	char v116; // al
	int v117; // esi
	int v118; // edx
	int v119; // ebx
	int v120; // edi
	int v121; // eax
	int v122; // edx
	int v123; // edx
	int v124; // edx
	int v125; // eax
	int *v126; // ecx
	signed int v127; // esi
	int v128; // esi
	int *v129; // ecx
	int *v130; // eax
	signed int v131; // ecx
	int v132; // ecx
	int v133; // eax
	int v134; // ebx
	int v135; // edi
	int v136; // esi
	unsigned short param2; // [esp+Ch] [ebp-18h]
	int i; // [esp+14h] [ebp-10h]
	signed int v139; // [esp+1Ch] [ebp-8h]
	int *v140; // [esp+1Ch] [ebp-8h]
	signed int v141; // [esp+1Ch] [ebp-8h]
	int arglist; // [esp+20h] [ebp-4h]
	int sfx_ida; // [esp+2Ch] [ebp+8h]
	int sfx_ide; // [esp+2Ch] [ebp+8h]
	int sfx_idb; // [esp+2Ch] [ebp+8h]
	int *sfx_idc; // [esp+2Ch] [ebp+8h]
	int sfx_idf; // [esp+2Ch] [ebp+8h]
	int sfx_idd; // [esp+2Ch] [ebp+8h]
	int sfx_idg; // [esp+2Ch] [ebp+8h]

	param2 = object_num;
	arglist = player_num;
	if ( dropGoldFlag )
	{
		dropGoldFlag = 0;
		dropGoldValue = 0;
	}
	v3 = object_num;
	v4 = &object[object_num]._oSelFlag;
	if ( _LOBYTE(object[object_num]._oSelFlag) )
	{
		SetRndSeed(object[v3]._oRndSeed);
		v5 = deltaload;
		*(_BYTE *)v4 = 0;
		if ( v5 )
		{
			v6 = object[v3]._oAnimLen;
			object[v3]._oAnimFlag = 0;
			object[v3]._oAnimFrame = v6;
		}
		else
		{
			PlaySfxLoc(sfx_id, object[v3]._ox, object[v3]._oy);
			object[v3]._oAnimFlag = 1;
			object[v3]._oAnimDelay = 1;
			v5 = deltaload;
		}
		v7 = object[v3]._oVar1;
		switch ( v7 )
		{
			case 0:
				if ( !v5 && arglist == myplr )
				{
					ModifyPlrStr(arglist, -1);
					ModifyPlrMag(arglist, -1);
					ModifyPlrDex(arglist, -1);
					ModifyPlrVit(arglist, -1);
					_LOBYTE(v8) = 0;
					v9 = random(v8, 4);
					if ( v9 )
					{
						v10 = v9 - 1;
						if ( v10 )
						{
							v11 = v10 - 1;
							if ( v11 )
							{
								if ( v11 == 1 )
									ModifyPlrVit(arglist, 6);
							}
							else
							{
								ModifyPlrDex(arglist, 6);
							}
						}
						else
						{
							ModifyPlrMag(arglist, 6);
						}
					}
					else
					{
						ModifyPlrStr(arglist, 6);
					}
					CheckStats(arglist);
					_LOBYTE(v7) = 12;
					goto LABEL_221;
				}
				return;
			case 1:
				v12 = 0;
				if ( v5 || arglist != myplr )
					return;
				v13 = arglist;
				v14 = 7;
				v15 = &plr[arglist].InvBody[0]._itype;
				v7 = 7;
				do
				{
					if ( *v15 != -1 )
						++v12;
					v15 += 92;
					--v7;
				}
				while ( v7 );
				if ( v12 <= 0 )
					goto LABEL_47;
				v16 = &plr[v13].InvBody[0]._iMaxDur;
				do
				{
					if ( *(v16 - 58) != -1 )
					{
						v7 = *v16;
						if ( *v16 != 255 )
						{
							if ( v7 )
							{
								*(v16 - 1) += 10;
								v17 = *(v16 - 1);
								v7 += 10;
								*v16 = v7;
								if ( v17 > v7 )
									*(v16 - 1) = v7;
							}
						}
					}
					v16 += 92;
					--v14;
				}
				while ( v14 );
				while ( 1 )
				{
					v18 = 0;
					v19 = &plr[v13].InvBody[0]._iMaxDur;
					v20 = 7;
					do
					{
						if ( *(v19 - 58) != -1 )
						{
							v7 = *v19;
							if ( *v19 != 255 )
							{
								if ( v7 )
									++v18;
							}
						}
						v19 += 92;
						--v20;
					}
					while ( v20 );
					if ( !v18 )
						goto LABEL_47;
					_LOBYTE(v7) = 0;
					v21 = random(v7, 7);
					v7 = v13 * 21720 + 368 * v21;
					if ( *(int *)((char *)&plr[0].InvBody[0]._itype + v7) != -1 )
					{
						v7 = *(int *)((char *)&plr[0].InvBody[0]._iMaxDur + v7);
						if ( v7 != 255 )
						{
							if ( v7 )
								break;
						}
					}
				}
				v22 = 368 * v21 + v13 * 21720;
				v23 = (int *)((char *)&plr[0].InvBody[0]._iDurability + v22);
				v7 = (int)&plr[0].InvBody[0]._iMaxDur + v22;
				*v23 -= 20;
				v24 = *v23;
				*(_DWORD *)v7 -= 20;
				v25 = *(_DWORD *)v7;
				if ( v24 <= 0 )
					*v23 = 1;
				if ( v25 <= 0 )
					*(_DWORD *)v7 = 1;
LABEL_47:
				_LOBYTE(v7) = 13;
				goto LABEL_221;
			case 2:
				if ( v5 )
					return;
				if ( arglist != myplr )
					goto LABEL_280;
				v26 = arglist;
				if ( plr[arglist].InvBody[0]._itype != ITYPE_NONE )
					plr[v26].InvBody[0]._iAC += 2;
				if ( plr[v26].InvBody[6]._itype != ITYPE_NONE )
					plr[v26].InvBody[6]._iAC += 2;
				v27 = plr[v26].InvBody[4]._itype;
				if ( v27 != ITYPE_NONE )
				{
					if ( v27 == ITYPE_SHIELD )
					{
						plr[v26].InvBody[4]._iAC += 2;
					}
					else
					{
						v28 = plr[v26].InvBody[4]._iMinDam;
						v29 = &plr[v26].InvBody[4]._iMaxDam;
						--*v29;
						if ( plr[v26].InvBody[4]._iMaxDam < v28 )
							*v29 = v28;
					}
				}
				v7 = plr[v26].InvBody[5]._itype;
				if ( v7 != ITYPE_NONE )
				{
					if ( v7 == ITYPE_SHIELD )
					{
						plr[v26].InvBody[5]._iAC += 2;
					}
					else
					{
						v30 = plr[v26].InvBody[5]._iMinDam;
						v7 = (int)&plr[v26].InvBody[5]._iMaxDam;
						--*(_DWORD *)v7;
						if ( plr[v26].InvBody[5]._iMaxDam < v30 )
							*(_DWORD *)v7 = v30;
					}
				}
				v31 = 0;
				if ( plr[v26]._pNumInv <= 0 )
					goto LABEL_73;
				v7 = (int)&plr[v26].InvList[0]._iAC;
				break;
			case 3:
				if ( v5 )
					return;
				if ( arglist != myplr )
					goto LABEL_280;
				v34 = arglist;
				v35 = plr[arglist].InvBody[4]._itype;
				if ( v35 != ITYPE_NONE && v35 != ITYPE_SHIELD )
					++plr[v34].InvBody[4]._iMaxDam;
				v7 = plr[v34].InvBody[5]._itype;
				if ( v7 != ITYPE_NONE && v7 != ITYPE_SHIELD )
					++plr[v34].InvBody[5]._iMaxDam;
				v36 = 0;
				if ( plr[v34]._pNumInv > 0 )
				{
					v7 = (int)&plr[v34].InvList[0]._iMaxDam;
					do
					{
						v37 = *(_DWORD *)(v7 - 200);
						if ( v37 > 0 && (v37 <= 4 || v37 == 10) )
							++*(_DWORD *)v7;
						++v36;
						v7 += 368;
					}
					while ( v36 < plr[v34]._pNumInv );
				}
				_LOBYTE(v7) = 15;
				goto LABEL_221;
			case 4:
			case 11:
				if ( v5 )
					return;
				AddMissile(
					plr[arglist].WorldX,
					plr[arglist].WorldY,
					plr[arglist].WorldX,
					plr[arglist].WorldY,
					plr[arglist]._pdir,
					13,
					-1,
					arglist,
					0,
					2 * (unsigned char)leveltype);
				if ( arglist != myplr )
					return;
				_LOBYTE(v7) = 16;
				goto LABEL_221;
			case 5:
				if ( v5 )
					return;
				if ( arglist != myplr )
					goto LABEL_280;
				v38 = arglist;
				v39 = &plr[arglist].InvBody[0]._iMaxCharges;
				v40 = 7;
				do
				{
					if ( *(v39 - 56) == 10 )
						*(v39 - 1) = *v39;
					v39 += 92;
					--v40;
				}
				while ( v40 );
				v41 = 0;
				if ( plr[v38]._pNumInv > 0 )
				{
					v42 = &plr[v38].InvList[0]._iMaxCharges;
					do
					{
						if ( *(v42 - 56) == 10 )
							*(v42 - 1) = *v42;
						++v41;
						v42 += 92;
					}
					while ( v41 < plr[v38]._pNumInv );
				}
				v43 = &plr[v38].SpdList[0]._iMaxCharges;
				v44 = 8;
				do
				{
					if ( *(v43 - 56) == 10 )
						*(v43 - 1) = *v43;
					v43 += 92;
					--v44;
				}
				while ( v44 );
				v7 = 17;
				goto LABEL_221;
			case 6:
				if ( v5 )
					return;
				if ( arglist != myplr )
					goto LABEL_280;
				v45 = arglist;
				v46 = &plr[arglist].InvBody[0]._iDurability;
				v47 = 7;
				do
				{
					*v46 = v46[1];
					v46 += 92;
					--v47;
				}
				while ( v47 );
				v48 = 0;
				if ( plr[v45]._pNumInv > 0 )
				{
					v49 = &plr[v45].InvList[0]._iDurability;
					do
					{
						++v48;
						*v49 = v49[1];
						v49 += 92;
					}
					while ( v48 < plr[v45]._pNumInv );
				}
				v50 = &plr[v45].SpdList[0]._iDurability;
				v51 = 8;
				do
				{
					*v50 = v50[1];
					v50 += 92;
					--v51;
				}
				while ( v51 );
				v7 = 18;
				goto LABEL_221;
			case 7:
				if ( v5 || arglist != myplr )
					return;
				sfx_ida = 0;
				i = 0;
				v52 = 1;
				v53 = arglist;
				v54 = plr[arglist]._pMemSpells[1];
				v139 = 37;
				do
				{
					v7 = i & v54;
					if ( i & v54 | v52 & plr[arglist]._pMemSpells[0] )
						++sfx_ida;
					v55 = __PAIR__((unsigned int)i, v52) >> 31;
					v52 *= 2;
					v56 = v139-- == 1;
					i = v55;
				}
				while ( !v56 );
				v57 = 1;
				if ( sfx_ida > 1 )
				{
					v58 = 0;
					v59 = 1;
					do
					{
						v7 = v58 & plr[v53]._pMemSpells[1];
						if ( v7 | v57 & plr[v53]._pMemSpells[0] )
						{
							v7 = (int)&plr[v53]._pSplLvl[v59];
							if ( *(_BYTE *)v7 < 15 )
								++*(_BYTE *)v7;
						}
						v58 = __PAIR__(v58, v57) >> 31;
						v57 *= 2;
						++v59;
					}
					while ( v59 <= 37 );
					do
					{
						_LOBYTE(v7) = 0;
						v60 = random(v7, 37);
						v7 = v60;
					}
					while ( !(plr[v53]._pMemSpells[1] & ((unsigned __int64)(1i64 << v60) >> 32) | plr[v53]._pMemSpells[0] & (unsigned int)(1i64 << v60)) );
					v61 = &plr[v53]._pSplLvl[v60 + 1];
					if ( *v61 < 2 )
						*v61 = 0;
					else
						*v61 -= 2;
				}
				_LOBYTE(v7) = 19;
				goto LABEL_221;
			case 8:
				for ( j = 0; j < nobjects; ++j )
				{
					v63 = objectactive[j];
					v7 = object[v63]._otype;
					if ( (v7 == OBJ_CHEST1 || v7 == OBJ_CHEST2 || v7 == OBJ_CHEST3) && !_LOBYTE(object[v63]._oSelFlag) )
					{
						v64 = GetRndSeed();
						object[v63]._oAnimFrame -= 2;
						object[v63]._oRndSeed = v64;
						v5 = deltaload;
						_LOBYTE(object[v63]._oSelFlag) = 1;
					}
				}
				if ( v5 )
					return;
				if ( arglist != myplr )
					goto LABEL_280;
				_LOBYTE(v7) = 20;
				goto LABEL_221;
			case 9:
				if ( v5 || arglist != myplr )
					return;
				v7 = 21720 * arglist;
				v65 = plr[arglist]._pMemSpells;
				v66 = plr[arglist]._pMemSpells[1];
				*v65 |= 1u;
				v65[1] = v66;
				v67 = plr[arglist]._pSplLvl[1];
				if ( v67 < 15 )
					plr[0]._pSplLvl[v7 + 1] = v67 + 1;
				v68 = plr[0]._pSplLvl[v7 + 1];
				if ( v68 < 15 )
					plr[0]._pSplLvl[v7 + 1] = v68 + 1;
				v69 = *(int *)((char *)&plr[0]._pMaxManaBase + v7);
				v70 = *(int *)((char *)&plr[0]._pManaBase + v7);
				v71 = *(int *)((char *)&plr[0]._pMana + v7) - v70;
				v72 = *(int *)((char *)&plr[0]._pMaxManaBase + v7) / 10;
				v73 = *(int *)((char *)&plr[0]._pMaxMana + v7) - v69;
				*(int *)((char *)&plr[0]._pManaBase + v7) = v70 - v72;
				v74 = *(int *)((char *)&plr[0]._pMana + v7) - v72;
				sfx_ide = v74;
				*(int *)((char *)&plr[0]._pMana + v7) = v74;
				v75 = *(int *)((char *)&plr[0]._pMaxMana + v7);
				*(int *)((char *)&plr[0]._pMaxManaBase + v7) = v69 - v72;
				v76 = v75 - v72;
				*(int *)((char *)&plr[0]._pMaxMana + v7) = v76;
				if ( (signed int)(sfx_ide & 0xFFFFFFC0) <= 0 )
				{
					*(int *)((char *)&plr[0]._pManaBase + v7) = 0;
					*(int *)((char *)&plr[0]._pMana + v7) = v71;
				}
				if ( (signed int)(v76 & 0xFFFFFFC0) <= 0 )
				{
					*(int *)((char *)&plr[0]._pMaxManaBase + v7) = 0;
					*(int *)((char *)&plr[0]._pMaxMana + v7) = v73;
				}
				_LOBYTE(v7) = 21;
				goto LABEL_221;
			case 10:
				if ( v5 )
					return;
				v77 = arglist;
				AddMissile(
					plr[arglist].WorldX,
					plr[arglist].WorldY,
					plr[arglist].WorldX,
					plr[arglist].WorldY,
					plr[arglist]._pdir,
					42,
					-1,
					arglist,
					0,
					2 * (unsigned char)leveltype);
				if ( arglist != myplr )
					return;
				_LOBYTE(v7) = 22;
				plr[v77]._pMana = plr[v77]._pMaxMana;
				plr[v77]._pManaBase = plr[v77]._pMaxManaBase;
				goto LABEL_221;
			case 12:
				if ( v5 )
					return;
				if ( arglist != myplr )
					goto LABEL_280;
				sfx_idb = 0;
				v78 = arglist;
				if ( plr[arglist]._pNumInv > 0 )
				{
					v79 = &plr[v78].InvList[0]._iMiscId;
					v140 = &plr[v78].InvList[0]._iMiscId;
					do
					{
						if ( !*(v79 - 53) )
						{
							if ( *v79 == IMISC_HEAL || *v79 == IMISC_MANA )
							{
								v80 = ItemMiscIdIdx(18);
								SetPlrHandItem(&plr[v78].HoldItem, v80);
								GetPlrHandSeed(&plr[v78].HoldItem);
								v79 = v140;
								plr[v78].HoldItem._iStatFlag = 1;
								qmemcpy(v140 - 55, &plr[v78].HoldItem, 0x170u);
							}
							if ( *v79 == IMISC_FULLHEAL || *v79 == IMISC_FULLMANA )
							{
								v81 = ItemMiscIdIdx(19);
								SetPlrHandItem(&plr[v78].HoldItem, v81);
								GetPlrHandSeed(&plr[v78].HoldItem);
								v79 = v140;
								plr[v78].HoldItem._iStatFlag = 1;
								qmemcpy(v140 - 55, &plr[v78].HoldItem, 0x170u);
							}
						}
						++sfx_idb;
						v79 += 92;
						v7 = sfx_idb;
						v140 = v79;
					}
					while ( sfx_idb < plr[v78]._pNumInv );
				}
				v82 = &plr[v78].SpdList[0]._iMiscId;
				v141 = 8;
				sfx_idc = &plr[v78].SpdList[0]._iMiscId;
				do
				{
					if ( !*(v82 - 53) )
					{
						if ( *v82 == IMISC_HEAL || *v82 == IMISC_MANA )
						{
							v83 = ItemMiscIdIdx(18);
							SetPlrHandItem(&plr[v78].HoldItem, v83);
							GetPlrHandSeed(&plr[v78].HoldItem);
							v82 = sfx_idc;
							plr[v78].HoldItem._iStatFlag = 1;
							qmemcpy(sfx_idc - 55, &plr[v78].HoldItem, 0x170u);
						}
						v7 = *v82;
						if ( *v82 == IMISC_FULLHEAL || v7 == IMISC_FULLMANA )
						{
							v84 = ItemMiscIdIdx(19);
							SetPlrHandItem(&plr[v78].HoldItem, v84);
							GetPlrHandSeed(&plr[v78].HoldItem);
							v82 = sfx_idc;
							plr[v78].HoldItem._iStatFlag = 1;
							qmemcpy(sfx_idc - 55, &plr[v78].HoldItem, 0x170u);
							v7 = 0;
						}
					}
					v82 += 92;
					v56 = v141-- == 1;
					sfx_idc = v82;
				}
				while ( !v56 );
				_LOBYTE(v7) = 24;
				goto LABEL_221;
			case 13:
				if ( v5 || arglist != myplr )
					return;
				ModifyPlrMag(arglist, 2);
				CheckStats(arglist);
				_LOBYTE(v7) = 25;
				goto LABEL_221;
			case 14:
				if ( v5 || arglist != myplr )
					return;
				v85 = object[v3]._ox;
				v86 = object[v3]._oy;
				if ( 2 * currlevel >= 7 )
				{
					CreateTypeItem(v85, v86, 0, 0, 19, 0, 1);
					CreateTypeItem(object[v3]._ox, object[v3]._oy, 0, 0, 19, 0, 1);
				}
				else
				{
					CreateTypeItem(v85, v86, 0, 0, 7, 0, 1);
					CreateTypeItem(object[v3]._ox, object[v3]._oy, 0, 0, 2, 0, 1);
				}
				v87 = arglist;
				plr[v87]._pMana = plr[arglist]._pMaxMana;
				plr[v87]._pManaBase = plr[arglist]._pMaxManaBase;
				plr[v87]._pHitPoints = plr[arglist]._pMaxHP;
				v7 = plr[arglist]._pMaxHPBase;
				plr[v87]._pHPBase = v7;
				_LOBYTE(v7) = 26;
				goto LABEL_221;
			case 15:
				if ( v5 )
					return;
				v88 = 0;
				do
				{
					_LOBYTE(v7) = -97;
					v89 = random(v7, 112);
					_LOBYTE(v90) = -97;
					v91 = v89;
					v92 = random(v90, 112);
					if ( ++v88 > 12544 )
						break;
					v7 = v92 + 112 * v91;
					v93 = v92 + 112 * v91;
				}
				while ( nSolidTable[dPiece[0][v93]] || dObject[0][v7] || dMonster[0][v93] );
				AddMissile(
					plr[arglist].WorldX,
					plr[arglist].WorldY,
					v91,
					v92,
					plr[arglist]._pdir,
					3,
					-1,
					arglist,
					0,
					2 * (unsigned char)leveltype);
				if ( arglist != myplr )
					return;
				_LOBYTE(v7) = 27;
				goto LABEL_221;
			case 16:
				if ( v5 || arglist != myplr )
					return;
				v7 = 21720 * arglist;
				v94 = plr[arglist]._pMemSpells;
				v95 = plr[arglist]._pMemSpells[1];
				*((_BYTE *)v94 + 3) |= 0x20u;
				v94[1] = v95;
				v96 = plr[arglist]._pSplLvl[30];
				if ( v96 < 15 )
					plr[0]._pSplLvl[v7 + 30] = v96 + 1;
				v97 = plr[0]._pSplLvl[v7 + 30];
				if ( v97 < 15 )
					plr[0]._pSplLvl[v7 + 30] = v97 + 1;
				v98 = *(int *)((char *)&plr[0]._pMaxManaBase + v7);
				v99 = *(int *)((char *)&plr[0]._pManaBase + v7);
				v100 = *(int *)((char *)&plr[0]._pMana + v7) - v99;
				v101 = *(int *)((char *)&plr[0]._pMaxManaBase + v7) / 10;
				v102 = *(int *)((char *)&plr[0]._pMaxMana + v7) - v98;
				*(int *)((char *)&plr[0]._pManaBase + v7) = v99 - v101;
				v103 = *(int *)((char *)&plr[0]._pMana + v7) - v101;
				sfx_idf = v103;
				*(int *)((char *)&plr[0]._pMana + v7) = v103;
				v104 = *(int *)((char *)&plr[0]._pMaxMana + v7);
				*(int *)((char *)&plr[0]._pMaxManaBase + v7) = v98 - v101;
				v105 = v104 - v101;
				*(int *)((char *)&plr[0]._pMaxMana + v7) = v105;
				if ( (signed int)(sfx_idf & 0xFFFFFFC0) <= 0 )
				{
					*(int *)((char *)&plr[0]._pManaBase + v7) = 0;
					*(int *)((char *)&plr[0]._pMana + v7) = v100;
				}
				if ( (signed int)(v105 & 0xFFFFFFC0) <= 0 )
				{
					*(int *)((char *)&plr[0]._pMaxManaBase + v7) = 0;
					*(int *)((char *)&plr[0]._pMaxMana + v7) = v102;
				}
				_LOBYTE(v7) = 28;
				goto LABEL_221;
			case 17:
				if ( v5 || arglist != myplr )
					return;
				sfx_idd = 0;
				v106 = arglist;
				do
				{
					if ( !plr[v106].InvGrid[sfx_idd] )
					{
						_LOBYTE(v7) = -96;
						v107 = 5 * (unsigned char)leveltype + random(v7, 10 * (unsigned char)leveltype);
						v108 = plr[v106]._pNumInv;
						v109 = v106 * 21720 + 368 * v108;
						qmemcpy((char *)plr[0].InvList + v109, &golditem, 0x170u);
						*(int *)((char *)&plr[0].InvList[0]._iSeed + v109) = GetRndSeed();
						++plr[v106]._pNumInv;
						plr[v106].InvGrid[sfx_idd] = plr[v106]._pNumInv;
						*(int *)((char *)&plr[0].InvList[0]._ivalue + v109) = v107;
						plr[v106]._pGold += v107;
						SetGoldCurs(arglist, v108);
					}
					++sfx_idd;
				}
				while ( sfx_idd < 40 );
				_LOBYTE(v7) = 29;
				goto LABEL_221;
			case 18:
				if ( v5 )
					return;
				if ( arglist == myplr )
				{
					_LOBYTE(v7) = 30;
					goto LABEL_221;
				}
				_LOBYTE(v7) = 31;
				InitDiabloMsg(v7);
				v110 = myplr;
				plr[v110]._pHitPoints = plr[myplr]._pMaxHP;
				plr[v110]._pHPBase = plr[v110]._pMaxHPBase;
				plr[v110]._pMana = plr[v110]._pMaxMana;
				plr[v110]._pManaBase = plr[v110]._pMaxManaBase;
				goto LABEL_280;
			case 19:
				if ( v5 || arglist != myplr )
					return;
				ModifyPlrDex(arglist, 2);
				CheckStats(arglist);
				if ( arglist != myplr )
					goto LABEL_280;
				_LOBYTE(v7) = 32;
				goto LABEL_221;
			case 20:
				if ( v5 || arglist != myplr )
					return;
				ModifyPlrStr(arglist, 2);
				CheckStats(arglist);
				if ( arglist != myplr )
					goto LABEL_280;
				_LOBYTE(v7) = 33;
				goto LABEL_221;
			case 21:
				if ( v5 || arglist != myplr )
					return;
				ModifyPlrVit(arglist, 2);
				CheckStats(arglist);
				if ( arglist != myplr )
					goto LABEL_280;
				_LOBYTE(v7) = 34;
				goto LABEL_221;
			case 22:
				if ( v5 )
					return;
				if ( arglist != myplr )
					goto LABEL_280;
				v7 = 0;
				do
				{
					v111 = (unsigned char *)automapview + v7;
					v112 = 40;
					do
					{
						*v111 = 1;
						v111 += 40;
						--v112;
					}
					while ( v112 );
					++v7;
				}
				while ( v7 < 40 );
				_LOBYTE(v7) = 35;
				goto LABEL_221;
			case 23:
				if ( v5 || arglist != myplr )
					return;
				v7 = 21720 * arglist;
				v113 = plr[arglist]._pMemSpells;
				v114 = plr[arglist]._pMemSpells[1];
				*((_BYTE *)v113 + 3) |= 0x40u;
				v113[1] = v114;
				v115 = plr[arglist]._pSplLvl[31];
				if ( v115 < 15 )
					plr[0]._pSplLvl[v7 + 31] = v115 + 1;
				v116 = plr[0]._pSplLvl[v7 + 31];
				if ( v116 < 15 )
					plr[0]._pSplLvl[v7 + 31] = v116 + 1;
				v117 = *(int *)((char *)&plr[0]._pMaxManaBase + v7);
				v118 = *(int *)((char *)&plr[0]._pManaBase + v7);
				v119 = *(int *)((char *)&plr[0]._pMana + v7) - v118;
				v120 = *(int *)((char *)&plr[0]._pMaxManaBase + v7) / 10;
				v121 = *(int *)((char *)&plr[0]._pMaxMana + v7) - v117;
				*(int *)((char *)&plr[0]._pManaBase + v7) = v118 - v120;
				v122 = *(int *)((char *)&plr[0]._pMana + v7) - v120;
				sfx_idg = v122;
				*(int *)((char *)&plr[0]._pMana + v7) = v122;
				v123 = *(int *)((char *)&plr[0]._pMaxMana + v7);
				*(int *)((char *)&plr[0]._pMaxManaBase + v7) = v117 - v120;
				v124 = v123 - v120;
				*(int *)((char *)&plr[0]._pMaxMana + v7) = v124;
				if ( (signed int)(sfx_idg & 0xFFFFFFC0) <= 0 )
				{
					*(int *)((char *)&plr[0]._pManaBase + v7) = 0;
					*(int *)((char *)&plr[0]._pMana + v7) = v119;
				}
				if ( (signed int)(v124 & 0xFFFFFFC0) <= 0 )
				{
					*(int *)((char *)&plr[0]._pMaxManaBase + v7) = 0;
					*(int *)((char *)&plr[0]._pMaxMana + v7) = v121;
				}
				_LOBYTE(v7) = 36;
				goto LABEL_221;
			case 24:
				if ( v5 || arglist != myplr )
					return;
				v125 = arglist;
				v126 = &plr[arglist].InvBody[0]._iIdentified;
				v127 = 7;
				do
				{
					if ( *((_BYTE *)v126 + 4) && !*v126 )
						*v126 = 1;
					v126 += 92;
					--v127;
				}
				while ( v127 );
				v128 = 0;
				if ( plr[v125]._pNumInv > 0 )
				{
					v129 = &plr[v125].InvList[0]._iIdentified;
					do
					{
						if ( *((_BYTE *)v129 + 4) && !*v129 )
							*v129 = 1;
						++v128;
						v129 += 92;
					}
					while ( v128 < plr[v125]._pNumInv );
				}
				v130 = &plr[v125].SpdList[0]._iIdentified;
				v131 = 8;
				do
				{
					if ( *((_BYTE *)v130 + 4) && !*v130 )
						*v130 = 1;
					v130 += 92;
					--v131;
				}
				while ( v131 );
				v7 = 37;
				goto LABEL_221;
			case 25:
				if ( v5 )
					return;
				if ( arglist == myplr )
				{
					_LOBYTE(v7) = 38;
					goto LABEL_221;
				}
				_LOBYTE(v7) = 39;
				InitDiabloMsg(v7);
				_LOBYTE(v132) = -101;
				v133 = random(v132, 4);
				v134 = 1;
				v135 = 2 * (v133 == 1) - 1;
				if ( v133 == 2 || (v134 = -1, v133 != 3) )
					v136 = -1;
				else
					v136 = 1;
				ModifyPlrStr(myplr, 2 * (v133 == 0) - 1);
				ModifyPlrMag(myplr, v135);
				ModifyPlrDex(myplr, v134);
				ModifyPlrVit(myplr, v136);
				CheckStats(myplr);
				goto LABEL_280;
			default:
				goto LABEL_280;
		}
		while ( 1 )
		{
			v32 = *(_DWORD *)(v7 - 204);
			if ( v32 > 0 )
			{
				if ( v32 <= 4 )
					goto LABEL_70;
				if ( v32 <= 9 )
				{
					*(_DWORD *)v7 += 2;
				}
				else if ( v32 == 10 )
				{
LABEL_70:
					--*(_DWORD *)(v7 - 4);
					v33 = *(_DWORD *)(v7 - 8);
					if ( *(_DWORD *)(v7 - 4) < v33 )
						*(_DWORD *)(v7 - 4) = v33;
					goto LABEL_72;
				}
			}
LABEL_72:
			++v31;
			v7 += 368;
			if ( v31 >= plr[v26]._pNumInv )
			{
LABEL_73:
				_LOBYTE(v7) = 14;
LABEL_221:
				InitDiabloMsg(v7);
LABEL_280:
				CalcPlrInv(arglist, 1u);
				force_redraw = 255;
				if ( arglist == myplr )
					NetSendCmdParam2(0, CMD_PLROPOBJ, arglist, param2);
				return;
			}
		}
	}
}
// 4B84DC: using guessed type int dropGoldFlag;
// 52571C: using guessed type int force_redraw;
// 5BB1ED: using guessed type char leveltype;
// 676190: using guessed type int deltaload;

//----- (00446E6A) --------------------------------------------------------
void __fastcall OperateSkelBook(int pnum, int i, unsigned char sendmsg)
{
	unsigned short v3; // di
	int v4; // esi
	bool v5; // zf
	int v6; // ecx
	int v7; // eax
	int v8; // ecx
	int v9; // edx
	int v10; // [esp+Ch] [ebp-4h]

	v3 = i;
	v4 = i;
	v10 = pnum;
	if ( _LOBYTE(object[i]._oSelFlag) )
	{
		if ( !deltaload )
			PlaySfxLoc(IS_ISCROL, object[v4]._ox, object[v4]._oy);
		object[v4]._oAnimFrame += 2;
		v5 = deltaload == 0;
		_LOBYTE(object[v4]._oSelFlag) = 0;
		if ( v5 )
		{
			SetRndSeed(object[v4]._oRndSeed);
			_LOBYTE(v6) = -95;
			v7 = random(v6, 5);
			v8 = object[v4]._ox;
			v9 = object[v4]._oy;
			if ( v7 )
				CreateTypeItem(v8, v9, 0, 0, 21, sendmsg, 0);
			else
				CreateTypeItem(v8, v9, 0, 0, 24, sendmsg, 0);
			if ( v10 == myplr )
				NetSendCmdParam1(0, CMD_OPERATEOBJ, v3);
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (00446F08) --------------------------------------------------------
void __fastcall OperateBookCase(int pnum, int i, unsigned char sendmsg)
{
	unsigned short v3; // di
	int v4; // ebp
	int v5; // esi
	bool v6; // zf
	int v7; // eax

	v3 = i;
	v4 = pnum;
	v5 = i;
	if ( _LOBYTE(object[i]._oSelFlag) )
	{
		if ( !deltaload )
			PlaySfxLoc(IS_ISCROL, object[v5]._ox, object[v5]._oy);
		object[v5]._oAnimFrame -= 2;
		v6 = deltaload == 0;
		_LOBYTE(object[v5]._oSelFlag) = 0;
		if ( v6 )
		{
			SetRndSeed(object[v5]._oRndSeed);
			CreateTypeItem(object[v5]._ox, object[v5]._oy, 0, 0, 24, sendmsg, 0);
			_LOBYTE(v7) = QuestStatus(3);
			if ( v7
			  && monster[4].mName == UniqMonst[2].mName
			  && _LOBYTE(monster[4]._msquelch) == -1
			  && monster[4]._mhitpoints )
			{
				monster[4].mtalkmsg = TEXT_ZHAR2;
				M_StartStand(0, monster[4]._mdir);
				_LOBYTE(monster[4]._mgoal) = 5;
				monster[4]._mmode = MM_TALK;
			}
			if ( v4 == myplr )
				NetSendCmdParam1(0, CMD_OPERATEOBJ, v3);
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (00446FE8) --------------------------------------------------------
void __fastcall OperateDecap(int pnum, int i, unsigned char sendmsg)
{
	unsigned short v3; // bp
	int v4; // esi
	int v5; // edi
	int *v6; // eax
	bool v7; // zf

	v3 = i;
	v4 = i;
	v5 = pnum;
	v6 = &object[i]._oSelFlag;
	if ( *(_BYTE *)v6 )
	{
		v7 = deltaload == 0;
		*(_BYTE *)v6 = 0;
		if ( v7 )
		{
			SetRndSeed(object[v4]._oRndSeed);
			CreateRndItem(object[v4]._ox, object[v4]._oy, 0, sendmsg, 0);
			if ( v5 == myplr )
				NetSendCmdParam1(0, CMD_OPERATEOBJ, v3);
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (00447046) --------------------------------------------------------
void __fastcall OperateArmorStand(int pnum, int i, unsigned char sendmsg)
{
	unsigned short v3; // di
	int v4; // esi
	int *v5; // eax
	bool v6; // zf
	int v7; // ecx
	unsigned char v8; // al
	int v9; // [esp-10h] [ebp-20h]
	int v10; // [esp-8h] [ebp-18h]
	int v11; // [esp+Ch] [ebp-4h]

	v3 = i;
	v4 = i;
	v11 = pnum;
	v5 = &object[i]._oSelFlag;
	if ( *(_BYTE *)v5 )
	{
		++object[v4]._oAnimFrame;
		v6 = deltaload == 0;
		*(_BYTE *)v5 = 0;
		if ( v6 )
		{
			SetRndSeed(object[v4]._oRndSeed);
			_LOBYTE(v7) = 0;
			v8 = random(v7, 2);
			if ( currlevel > 5u )
			{
				if ( currlevel >= 6u && currlevel <= 9u )
				{
					CreateTypeItem(object[v4]._ox, object[v4]._oy, v8, 8, 0, sendmsg, 0);
					goto LABEL_15;
				}
				if ( currlevel >= 0xAu && currlevel <= 0xCu )
				{
					CreateTypeItem(object[v4]._ox, object[v4]._oy, 0, 9, 0, sendmsg, 0);
					goto LABEL_15;
				}
				if ( currlevel < 0xDu || currlevel > 0x10u )
					goto LABEL_15;
				v10 = sendmsg;
				v9 = 9;
			}
			else
			{
				v10 = sendmsg;
				v9 = 6;
			}
			CreateTypeItem(object[v4]._ox, object[v4]._oy, 1u, v9, 0, v10, 0);
LABEL_15:
			if ( v11 == myplr )
				NetSendCmdParam1(0, CMD_OPERATEOBJ, v3);
			return;
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (0044710C) --------------------------------------------------------
void __fastcall FindValidShrine()
{
	signed int v0; // esi
	int v1; // eax
	bool v2; // zf

	do
	{
		v0 = 0;
		do
		{
			v1 = random(0, 26);
			if ( currlevel >= (signed int)(char)shrinemin[v1] && currlevel <= (signed int)(char)shrinemax[v1] && v1 != 8 )
				v0 = 1;
		}
		while ( !v0 );
		if ( gbMaxPlayers == 1 )
			v2 = shrineavail[v1] == 2;
		else
			v2 = shrineavail[v1] == 1;
	}
	while ( v2 );
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044715F) --------------------------------------------------------
void __fastcall OperateGoatShrine(int pnum, int i, int sType)
{
	int v3; // edi
	int v4; // ebx
	int v5; // esi
	int v6; // eax

	v3 = i;
	v4 = pnum;
	v5 = i;
	SetRndSeed(object[i]._oRndSeed);
	FindValidShrine();
	object[v5]._oVar1 = v6;
	OperateShrine(v4, v3, sType);
	object[v5]._oAnimDelay = 2;
	force_redraw = 255;
}
// 52571C: using guessed type int force_redraw;

//----- (004471AA) --------------------------------------------------------
void __fastcall OperateCauldron(int pnum, int i, int sType)
{
	int v3; // edi
	int v4; // ebx
	int v5; // esi
	int v6; // eax

	v3 = i;
	v4 = pnum;
	v5 = i;
	SetRndSeed(object[i]._oRndSeed);
	FindValidShrine();
	object[v5]._oVar1 = v6;
	OperateShrine(v4, v3, sType);
	object[v5]._oAnimFlag = 0;
	object[v5]._oAnimFrame = 3;
	force_redraw = 255;
}
// 52571C: using guessed type int force_redraw;

//----- (004471FC) --------------------------------------------------------
unsigned char __fastcall OperateFountains(int pnum, int i)
{
	unsigned short v2; // bx
	int v3; // esi
	int v4; // edi
	unsigned char v5; // bp
	int v6; // ecx
	signed int v7; // ebx
	int v8; // ebp
	int v10; // eax
	int v11; // esi
	int v12; // eax
	int v13; // eax
	int v14; // edi
	int v15; // edx
	int v16; // edx
	int v17; // ecx
	int *v18; // eax
	int v19; // ecx
	int v20; // edi
	int v21; // edx
	int v22; // ecx
	int v23; // [esp-4h] [ebp-20h]
	signed int v24; // [esp+10h] [ebp-Ch]
	signed int v25; // [esp+14h] [ebp-8h]
	short param1; // [esp+18h] [ebp-4h]

	v2 = i;
	v3 = i;
	v4 = pnum;
	param1 = i;
	v5 = 0;
	SetRndSeed(object[i]._oRndSeed);
	switch ( object[v3]._otype )
	{
		case OBJ_BLOODFTN:
			if ( !deltaload && v4 == myplr )
			{
				v20 = v4;
				v23 = object[v3]._oy;
				v15 = object[v3]._ox;
				if ( plr[v20]._pHitPoints < plr[v20]._pMaxHP )
				{
					PlaySfxLoc(LS_FOUNTAIN, v15, v23);
					plr[v20]._pHitPoints += 64;
					v21 = plr[v20]._pHitPoints;
					v22 = plr[v20]._pMaxHP;
					v18 = &plr[v20]._pHPBase;
					*v18 += 64;
					if ( v21 <= v22 )
						goto LABEL_39;
					plr[v20]._pHitPoints = v22;
					v19 = plr[v20]._pMaxHPBase;
					goto LABEL_38;
				}
LABEL_45:
				PlaySfxLoc(LS_FOUNTAIN, v15, v23);
				break;
			}
			return 0;
		case OBJ_PURIFYINGFTN:
			if ( !deltaload && v4 == myplr )
			{
				v14 = v4;
				v23 = object[v3]._oy;
				v15 = object[v3]._ox;
				if ( plr[v14]._pMana < plr[v14]._pMaxMana )
				{
					PlaySfxLoc(LS_FOUNTAIN, v15, v23);
					plr[v14]._pMana += 64;
					v16 = plr[v14]._pMana;
					v17 = plr[v14]._pMaxMana;
					v18 = &plr[v14]._pManaBase;
					*v18 += 64;
					if ( v16 <= v17 )
					{
LABEL_39:
						v5 = 1;
						break;
					}
					plr[v14]._pMana = v17;
					v19 = plr[v14]._pMaxManaBase;
LABEL_38:
					*v18 = v19;
					goto LABEL_39;
				}
				goto LABEL_45;
			}
			return 0;
		case OBJ_MURKYFTN:
			if ( _LOBYTE(object[v3]._oSelFlag) )
			{
				if ( !deltaload )
					PlaySfxLoc(LS_FOUNTAIN, object[v3]._ox, object[v3]._oy);
				_LOBYTE(object[v3]._oSelFlag) = 0;
				if ( deltaload )
					return 0;
				AddMissile(
					plr[v4].WorldX,
					plr[v4].WorldY,
					plr[v4].WorldX,
					plr[v4].WorldY,
					plr[v4]._pdir,
					39,
					-1,
					v4,
					0,
					2 * (unsigned char)leveltype);
				v5 = 1;
				if ( v4 == myplr )
					NetSendCmdParam1(0, CMD_OPERATEOBJ, v2);
			}
			break;
		default:
			if ( object[v3]._otype == 82 && _LOBYTE(object[v3]._oSelFlag) )
			{
				v7 = -1;
				v8 = -1;
				v25 = 0;
				v24 = 0;
				if ( !deltaload )
					PlaySfxLoc(LS_FOUNTAIN, object[v3]._ox, object[v3]._oy);
				_LOBYTE(object[v3]._oSelFlag) = 0;
				if ( deltaload || v4 != myplr )
					return 0;
				do
				{
					_LOBYTE(v6) = 0;
					v10 = random(v6, 4);
					v11 = v10;
					if ( v10 != v7 )
					{
						if ( v10 )
						{
							v12 = v10 - 1;
							if ( v12 )
							{
								v13 = v12 - 1;
								if ( v13 )
								{
									if ( v13 == 1 )
										ModifyPlrVit(v4, v8);
								}
								else
								{
									ModifyPlrDex(v4, v8);
								}
							}
							else
							{
								ModifyPlrMag(v4, v8);
							}
						}
						else
						{
							ModifyPlrStr(v4, v8);
						}
						v7 = v11;
						v8 = 1;
						++v24;
					}
					if ( v24 > 1 )
						v25 = 1;
				}
				while ( !v25 );
				CheckStats(v4);
				v5 = 1;
				if ( v4 == myplr )
					NetSendCmdParam1(0, CMD_OPERATEOBJ, param1);
			}
			break;
	}
	force_redraw = 255;
	return v5;
}
// 52571C: using guessed type int force_redraw;
// 5BB1ED: using guessed type char leveltype;
// 676190: using guessed type int deltaload;

//----- (004474AD) --------------------------------------------------------
void __fastcall OperateWeaponRack(int pnum, int i, unsigned char sendmsg)
{
	unsigned short v3; // di
	int v4; // esi
	int v5; // ecx
	int v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // eax
	bool v10; // zf
	int v11; // ecx
	int v12; // edx
	signed int v13; // [esp-4h] [ebp-14h]
	int v14; // [esp+Ch] [ebp-4h]

	v3 = i;
	v4 = i;
	v14 = pnum;
	if ( !_LOBYTE(object[i]._oSelFlag) )
		return;
	SetRndSeed(object[v4]._oRndSeed);
	_LOBYTE(v5) = 0;
	v6 = random(v5, 4);
	if ( v6 )
	{
		v7 = v6 - 1;
		if ( !v7 )
		{
			v13 = 2;
			goto LABEL_7;
		}
		v8 = v7 - 1;
		if ( !v8 )
		{
			v13 = 3;
			goto LABEL_7;
		}
		if ( v8 == 1 )
		{
			v13 = 4;
LABEL_7:
			v9 = v13;
			goto LABEL_12;
		}
		v9 = sendmsg;
	}
	else
	{
		v9 = 1;
	}
LABEL_12:
	++object[v4]._oAnimFrame;
	v10 = deltaload == 0;
	_LOBYTE(object[v4]._oSelFlag) = 0;
	if ( v10 )
	{
		v11 = object[v4]._ox;
		v12 = object[v4]._oy;
		if ( (unsigned char)leveltype <= 1u )
			CreateTypeItem(v11, v12, 0, v9, 0, sendmsg, 0);
		else
			CreateTypeItem(v11, v12, 1u, v9, 0, sendmsg, 0);
		if ( v14 == myplr )
			NetSendCmdParam1(0, CMD_OPERATEOBJ, v3);
	}
}
// 5BB1ED: using guessed type char leveltype;
// 676190: using guessed type int deltaload;

//----- (00447558) --------------------------------------------------------
void __fastcall OperateStoryBook(int pnum, int i)
{
	unsigned short v2; // di
	int v3; // esi
	int v4; // ST04_4
	int v5; // edx

	v2 = i;
	v3 = i;
	if ( _LOBYTE(object[i]._oSelFlag) && !deltaload && !qtextflag && pnum == myplr )
	{
		v4 = object[v3]._oy;
		v5 = object[v3]._ox;
		object[v3]._oAnimFrame = object[v3]._oVar4;
		PlaySfxLoc(IS_ISCROL, v5, v4);
		InitQTextMsg(object[v3]._oVar2);
		NetSendCmdParam1(0, CMD_OPERATEOBJ, v2);
	}
}
// 646D00: using guessed type char qtextflag;
// 676190: using guessed type int deltaload;

//----- (004475BB) --------------------------------------------------------
void __fastcall OperateLazStand(int pnum, int i)
{
	int v2; // eax
	int v3; // edx
	int xx; // [esp+4h] [ebp-8h]
	int yy; // [esp+8h] [ebp-4h]

	v2 = i;
	if ( _LOBYTE(object[i]._oSelFlag) && !deltaload && !qtextflag && pnum == myplr )
	{
		v3 = object[v2]._oy;
		++object[v2]._oAnimFrame;
		_LOBYTE(object[v2]._oSelFlag) = 0;
		GetSuperItemLoc(object[v2]._ox, v3, &xx, &yy);
		SpawnQuestItem(33, xx, yy, 0, 0);
	}
}
// 646D00: using guessed type char qtextflag;
// 676190: using guessed type int deltaload;

//----- (00447620) --------------------------------------------------------
void __fastcall OperateObject(int pnum, int i, unsigned char TeleFlag)
{
	int v3; // esi
	int v4; // edi
	ObjectStruct *v5; // ebx
	int v6; // ecx
	bool sendmsg; // [esp+Ch] [ebp-4h]

	v3 = pnum;
	v4 = i;
	sendmsg = pnum == myplr;
	v5 = &object[i];
	v6 = v5->_otype;
	switch ( v5->_otype )
	{
		case OBJ_L1LDOOR:
		case OBJ_L1RDOOR:
			if ( TeleFlag )
			{
				if ( v6 == OBJ_L1LDOOR )
					OperateL1LDoor(v3, i, OBJ_L1LDOOR);
				if ( v5->_otype == OBJ_L1RDOOR )
					OperateL1RDoor(v3, v4, 1u);
			}
			else if ( v3 == myplr )
			{
				OperateL1Door(v3, i, 1u);
			}
			break;
		case OBJ_LEVER:
		case OBJ_SWITCHSKL:
			OperateLever(v3, i);
			break;
		case OBJ_CHEST1:
		case OBJ_CHEST2:
		case OBJ_CHEST3:
		case OBJ_TCHEST1:
		case OBJ_TCHEST2:
		case OBJ_TCHEST3:
			OperateChest(v3, i, sendmsg);
			break;
		case OBJ_BOOK2L:
			OperateBook(v3, i);
			break;
		case OBJ_BOOK2R:
			OperateSChambBk(v3, i);
			break;
		case OBJ_L2LDOOR:
		case OBJ_L2RDOOR:
			if ( TeleFlag )
			{
				if ( v6 == OBJ_L2LDOOR )
					OperateL2LDoor(v3, i, 1u);
				if ( v5->_otype == OBJ_L2RDOOR )
					OperateL2RDoor(v3, v4, 1u);
			}
			else if ( v3 == myplr )
			{
				OperateL2Door(v3, i, 1u);
			}
			break;
		case OBJ_SARC:
			OperateSarc(v3, i, sendmsg);
			break;
		case OBJ_FLAMELVR:
			OperateTrapLvr(i);
			break;
		case OBJ_SHRINEL:
		case OBJ_SHRINER:
			OperateShrine(v3, i, 63);
			break;
		case OBJ_SKELBOOK:
		case OBJ_BOOKSTAND:
			OperateSkelBook(v3, i, sendmsg);
			break;
		case OBJ_BOOKCASEL:
		case OBJ_BOOKCASER:
			OperateBookCase(v3, i, sendmsg);
			break;
		case OBJ_BLOODFTN:
		case OBJ_PURIFYINGFTN:
		case OBJ_MURKYFTN:
		case OBJ_TEARFTN:
			OperateFountains(v3, i);
			break;
		case OBJ_DECAP:
			OperateDecap(v3, i, sendmsg);
			break;
		case OBJ_BLINDBOOK:
		case OBJ_BLOODBOOK:
		case OBJ_STEELTOME:
			OperateBookLever(v3, i);
			break;
		case OBJ_PEDISTAL:
			OperatePedistal(v3, i);
			break;
		case OBJ_L3LDOOR:
		case OBJ_L3RDOOR:
			if ( TeleFlag )
			{
				if ( v6 == OBJ_L3LDOOR )
					OperateL3LDoor(v3, i, 1u);
				if ( v5->_otype == OBJ_L3RDOOR )
					OperateL3RDoor(v3, v4, 1u);
			}
			else if ( v3 == myplr )
			{
				OperateL3Door(v3, i, 1u);
			}
			break;
		case OBJ_ARMORSTAND:
		case OBJ_WARARMOR:
			OperateArmorStand(v3, i, sendmsg);
			break;
		case OBJ_GOATSHRINE:
			OperateGoatShrine(v3, i, 112);
			break;
		case OBJ_CAULDRON:
			OperateCauldron(v3, i, 95);
			break;
		case OBJ_STORYBOOK:
			OperateStoryBook(v3, i);
			break;
		case OBJ_WARWEAP:
		case OBJ_WEAPONRACK:
			OperateWeaponRack(v3, i, sendmsg);
			break;
		case OBJ_MUSHPATCH:
			OperateMushPatch(v3, i);
			break;
		case OBJ_LAZSTAND:
			OperateLazStand(v3, i);
			break;
		case OBJ_SLAINHERO:
			OperateSlainHero(v3, i, sendmsg);
			break;
		case OBJ_SIGNCHEST:
			OperateInnSignChest(v3, i);
			break;
		default:
			return;
	}
}

//----- (00447932) --------------------------------------------------------
void __fastcall SyncOpL1Door(int pnum, int cmd, int i)
{
	signed int v3; // eax
	ObjectStruct *v4; // esi

	if ( pnum != myplr )
	{
		v3 = 0;
		if ( cmd == 43 )
		{
			if ( object[i]._oVar4 )
				return;
			v3 = 1;
		}
		if ( cmd == 44 && object[i]._oVar4 == 1 )
			v3 = 1;
		if ( v3 )
		{
			v4 = &object[i];
			if ( v4->_otype == 1 )
				OperateL1LDoor(-1, i, 0);
			if ( v4->_otype == OBJ_L1RDOOR )
				OperateL1RDoor(-1, i, 0);
		}
	}
}

//----- (004479A3) --------------------------------------------------------
void __fastcall SyncOpL2Door(int pnum, int cmd, int i)
{
	signed int v3; // eax
	ObjectStruct *v4; // esi

	if ( pnum != myplr )
	{
		v3 = 0;
		if ( cmd == 43 )
		{
			if ( object[i]._oVar4 )
				return;
			v3 = 1;
		}
		if ( cmd == 44 && object[i]._oVar4 == 1 )
			v3 = 1;
		if ( v3 )
		{
			v4 = &object[i];
			if ( v4->_otype == OBJ_L2LDOOR )
				OperateL2LDoor(-1, i, 0);
			if ( v4->_otype == OBJ_L2RDOOR )
				OperateL2RDoor(-1, i, 0);
		}
	}
}

//----- (00447A15) --------------------------------------------------------
void __fastcall SyncOpL3Door(int pnum, int cmd, int i)
{
	signed int v3; // eax
	ObjectStruct *v4; // esi

	if ( pnum != myplr )
	{
		v3 = 0;
		if ( cmd == 43 )
		{
			if ( object[i]._oVar4 )
				return;
			v3 = 1;
		}
		if ( cmd == 44 && object[i]._oVar4 == 1 )
			v3 = 1;
		if ( v3 )
		{
			v4 = &object[i];
			if ( v4->_otype == OBJ_L3LDOOR )
				OperateL3LDoor(-1, i, 0);
			if ( v4->_otype == OBJ_L3RDOOR )
				OperateL3RDoor(-1, i, 0);
		}
	}
}

//----- (00447A87) --------------------------------------------------------
void __fastcall SyncOpObject(int pnum, int cmd, int i)
{
	switch ( object[i]._otype )
	{
		case OBJ_L1LDOOR:
		case OBJ_L1RDOOR:
			SyncOpL1Door(pnum, cmd, i);
			break;
		case OBJ_LEVER:
		case OBJ_SWITCHSKL:
			OperateLever(pnum, i);
			break;
		case OBJ_CHEST1:
		case OBJ_CHEST2:
		case OBJ_CHEST3:
		case OBJ_TCHEST1:
		case OBJ_TCHEST2:
		case OBJ_TCHEST3:
			OperateChest(pnum, i, 0);
			break;
		case OBJ_L2LDOOR:
		case OBJ_L2RDOOR:
			SyncOpL2Door(pnum, cmd, i);
			break;
		case OBJ_SARC:
			OperateSarc(pnum, i, 0);
			break;
		case OBJ_SHRINEL:
		case OBJ_SHRINER:
			OperateShrine(pnum, i, 63);
			break;
		case OBJ_SKELBOOK:
		case OBJ_BOOKSTAND:
			OperateSkelBook(pnum, i, 0);
			break;
		case OBJ_BOOKCASEL:
		case OBJ_BOOKCASER:
			OperateBookCase(pnum, i, 0);
			break;
		case OBJ_DECAP:
			OperateDecap(pnum, i, 0);
			break;
		case OBJ_BLINDBOOK:
		case OBJ_BLOODBOOK:
		case OBJ_STEELTOME:
			OperateBookLever(pnum, i);
			break;
		case OBJ_PEDISTAL:
			OperatePedistal(pnum, i);
			break;
		case OBJ_L3LDOOR:
		case OBJ_L3RDOOR:
			SyncOpL3Door(pnum, cmd, i);
			break;
		case OBJ_ARMORSTAND:
		case OBJ_WARARMOR:
			OperateArmorStand(pnum, i, 0);
			break;
		case OBJ_GOATSHRINE:
			OperateGoatShrine(pnum, i, 112);
			break;
		case OBJ_CAULDRON:
			OperateCauldron(pnum, i, 95);
			break;
		case OBJ_MURKYFTN:
		case OBJ_TEARFTN:
			OperateFountains(pnum, i);
			break;
		case OBJ_STORYBOOK:
			OperateStoryBook(pnum, i);
			break;
		case OBJ_WARWEAP:
		case OBJ_WEAPONRACK:
			OperateWeaponRack(pnum, i, 0);
			break;
		case OBJ_MUSHPATCH:
			OperateMushPatch(pnum, i);
			break;
		case OBJ_SLAINHERO:
			OperateSlainHero(pnum, i, 0);
			break;
		case OBJ_SIGNCHEST:
			OperateInnSignChest(pnum, i);
			break;
		default:
			return;
	}
}

//----- (00447C2D) --------------------------------------------------------
void __fastcall BreakCrux(int i)
{
	int v1; // esi
	int v2; // edi
	int v3; // edx
	signed int v4; // eax
	int v5; // ecx
	int v6; // ebx

	v1 = i;
	v2 = nobjects;
	_LOBYTE(object[v1]._oBreak) = -1;
	_LOBYTE(object[v1]._oSelFlag) = 0;
	v3 = 0;
	v4 = 1;
	object[v1]._oAnimFlag = 1;
	object[v1]._oAnimFrame = 1;
	object[v1]._oAnimDelay = 1;
	object[v1]._oSolidFlag = 1;
	object[v1]._oMissFlag = 1;
	if ( v2 <= 0 )
		goto LABEL_15;
	do
	{
		v5 = objectactive[v3];
		v6 = object[v5]._otype;
		if ( (v6 == OBJ_CRUX1 || v6 == OBJ_CRUX2 || v6 == OBJ_CRUX3)
		  && object[v1]._oVar8 == object[v5]._oVar8
		  && _LOBYTE(object[v5]._oBreak) != -1 )
		{
			v4 = 0;
		}
		++v3;
	}
	while ( v3 < v2 );
	if ( v4 )
	{
LABEL_15:
		if ( !deltaload )
			PlaySfxLoc(IS_LEVER, object[v1]._ox, object[v1]._oy);
		DRLG_MRectTrans(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4);
	}
}
// 676190: using guessed type int deltaload;

//----- (00447CEF) --------------------------------------------------------
void __fastcall BreakBarrel(int pnum, int i, int dam, unsigned char forcebreak, int sendmsg)
{
	int v5; // esi
	bool v6; // zf
	int v7; // eax
	int v8; // edx
	int v9; // eax
	int v10; // eax
	int v11; // eax
	char v12; // al
	char v13; // al
	int v14; // edx
	int v15; // [esp-4h] [ebp-24h]
	short param2; // [esp+Ch] [ebp-14h]
	int param1; // [esp+10h] [ebp-10h]
	int v18; // [esp+14h] [ebp-Ch]
	int *v19; // [esp+18h] [ebp-8h]
	int v20; // [esp+1Ch] [ebp-4h]
	int forcebreaka; // [esp+2Ch] [ebp+Ch]

	param2 = i;
	v5 = i;
	param1 = pnum;
	if ( _LOBYTE(object[i]._oSelFlag) )
	{
		if ( forcebreak )
		{
			object[v5]._oVar1 = 0;
		}
		else
		{
			object[v5]._oVar1 -= dam;
			if ( pnum != myplr && object[v5]._oVar1 <= 0 )
				object[v5]._oVar1 = 1;
		}
		if ( object[v5]._oVar1 <= 0 )
		{
			_LOBYTE(object[v5]._oBreak) = -1;
			v6 = deltaload == 0;
			object[v5]._oVar1 = 0;
			object[v5]._oAnimFlag = 1;
			object[v5]._oAnimFrame = 1;
			object[v5]._oAnimDelay = 1;
			object[v5]._oSolidFlag = 0;
			object[v5]._oMissFlag = 1;
			_LOBYTE(object[v5]._oSelFlag) = 0;
			object[v5]._oPreFlag = 1;
			if ( v6 )
			{
				v8 = object[v5]._ox;
				v15 = object[v5]._oy;
				if ( object[v5]._otype == OBJ_BARRELEX )
				{
					PlaySfxLoc(IS_BARLFIRE, v8, v15);
					v9 = object[v5]._oy;
					v20 = v9 - 1;
					if ( v9 - 1 <= v9 + 1 )
					{
						do
						{
							v10 = object[v5]._ox;
							v18 = v10 - 1;
							if ( v10 - 1 <= v10 + 1 )
							{
								forcebreaka = 112 * (v10 - 1) + v20;
								v19 = (int *)((char *)dMonster + 4 * forcebreaka);
								do
								{
									v11 = *v19;
									if ( *v19 > 0 )
										MonsterTrapHit(v11 - 1, 1, 4, 0, 1, 0);
									v12 = dPlayer[0][forcebreaka];
									if ( v12 > 0 )
										PlayerMHit(v12 - 1, -1, 0, 8, 16, 1, 0, 0);
									v13 = dObject[0][forcebreaka];
									if ( v13 > 0 )
									{
										v14 = v13 - 1;
										if ( object[v14]._otype == OBJ_BARRELEX && _LOBYTE(object[v14]._oBreak) != -1 )
											BreakBarrel(param1, v14, dam, 1u, sendmsg);
									}
									++v18;
									v19 += 112;
									forcebreaka += 112;
								}
								while ( v18 <= object[v5]._ox + 1 );
							}
							++v20;
						}
						while ( v20 <= object[v5]._oy + 1 );
					}
				}
				else
				{
					PlaySfxLoc(IS_BARREL, v8, v15);
					SetRndSeed(object[v5]._oRndSeed);
					if ( object[v5]._oVar2 <= 1 )
					{
						if ( object[v5]._oVar3 )
							CreateRndItem(object[v5]._ox, object[v5]._oy, 0, sendmsg, 0);
						else
							CreateRndUseful(param1, object[v5]._ox, object[v5]._oy, sendmsg);
					}
					if ( object[v5]._oVar2 >= 8 )
						SpawnSkeleton(object[v5]._oVar4, object[v5]._ox, object[v5]._oy);
				}
				if ( param1 == myplr )
					NetSendCmdParam2(0, CMD_BREAKOBJ, param1, param2);
			}
			else
			{
				v7 = object[v5]._oAnimLen;
				object[v5]._oAnimCnt = 0;
				object[v5]._oAnimFrame = v7;
				object[v5]._oAnimDelay = 1000;
			}
		}
		else if ( !deltaload )
		{
			PlaySfxLoc(IS_IBOW, object[v5]._ox, object[v5]._oy);
		}
	}
}
// 676190: using guessed type int deltaload;

//----- (00447F63) --------------------------------------------------------
void __fastcall BreakObject(int pnum, int oi)
{
	int v2; // ebx
	int v3; // ebp
	int v4; // esi
	int v5; // edi
	int v6; // ecx
	int v7; // ecx
	int v8; // eax

	v2 = pnum;
	v3 = oi;
	if ( pnum == -1 )
	{
		v7 = 10;
	}
	else
	{
		v4 = pnum;
		_LOBYTE(pnum) = -93;
		v5 = plr[v2]._pIMinDam;
		v6 = v5 + random(pnum, plr[v2]._pIMaxDam - v5 + 1);
		v7 = plr[v4]._pIBonusDamMod + plr[v4]._pDamageMod + v6 * plr[v4]._pIBonusDam / 100 + v6;
	}
	v8 = object[v3]._otype;
	if ( v8 >= OBJ_CRUX1 )
	{
		if ( v8 <= OBJ_CRUX3 )
		{
			BreakCrux(v3);
		}
		else if ( v8 > OBJ_WEAPRACK && v8 <= OBJ_BARRELEX )
		{
			BreakBarrel(v2, v3, v7, 0, 1);
		}
	}
}

//----- (00447FEF) --------------------------------------------------------
void __fastcall SyncBreakObj(int pnum, int oi)
{
	int v2; // eax

	v2 = object[oi]._otype;
	if ( v2 >= OBJ_BARREL && v2 <= OBJ_BARRELEX )
		BreakBarrel(pnum, oi, 0, 1u, 0);
}

//----- (00448010) --------------------------------------------------------
void __fastcall SyncL1Doors(int i)
{
	int v1; // ebx
	int v2; // eax
	int v3; // esi
	int v4; // edi
	bool v5; // zf

	v1 = i;
	v2 = i;
	if ( object[i]._oVar4 )
	{
		v3 = object[v2]._oy;
		v4 = object[v2]._ox;
		v5 = object[v2]._otype == 1;
		object[v2]._oMissFlag = 1;
		_LOBYTE(object[v2]._oSelFlag) = 2;
		if ( v5 )
		{
			if ( object[v2]._oVar1 == 214 )
				ObjSetMicro(v4, v3, 408);
			else
				ObjSetMicro(v4, v3, 393);
			dArch[v4][v3] = 7;
			objects_set_door_piece(v4 - 1, v3--);
		}
		else
		{
			ObjSetMicro(v4, v3, 395);
			dArch[v4][v3] = 8;
			objects_set_door_piece(v4--, v3 - 1);
		}
		DoorSet(v1, v4, v3);
	}
	else
	{
		object[v2]._oMissFlag = 0;
	}
}

//----- (004480BB) --------------------------------------------------------
void __fastcall SyncCrux(int i)
{
	signed int v1; // ebx
	int v2; // edx
	int v3; // eax
	int v4; // esi

	v1 = 1;
	v2 = 0;
	if ( nobjects <= 0 )
		goto LABEL_13;
	do
	{
		v3 = objectactive[v2];
		v4 = object[v3]._otype;
		if ( (v4 == OBJ_CRUX1 || v4 == OBJ_CRUX2 || v4 == OBJ_CRUX3)
		  && object[i]._oVar8 == object[v3]._oVar8
		  && _LOBYTE(object[v3]._oBreak) != -1 )
		{
			v1 = 0;
		}
		++v2;
	}
	while ( v2 < nobjects );
	if ( v1 )
LABEL_13:
		DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4);
}

//----- (00448139) --------------------------------------------------------
void __fastcall SyncLever(int i)
{
	int v1; // ecx

	v1 = i;
	if ( !_LOBYTE(object[v1]._oSelFlag) )
		DRLG_MRectTrans(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4);
}

//----- (00448163) --------------------------------------------------------
void __fastcall SyncQSTLever(int i)
{
	int v1; // esi
	int v2; // edx
	int v3; // ecx
	int v4; // ST04_4
	char v5; // bl
	int v6; // ST00_4

	v1 = i;
	if ( object[i]._oAnimFrame == object[i]._oVar6 )
	{
		ObjChangeMapResync(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4);
		if ( object[v1]._otype == OBJ_BLINDBOOK )
		{
			v2 = object[v1]._oVar2;
			v3 = object[v1]._oVar1;
			v4 = object[v1]._oVar4;
			v5 = TransVal;
			v6 = object[v1]._oVar3;
			TransVal = 9;
			Make_RectTrans(v3, v2, v6, v4);
			TransVal = v5;
		}
	}
}
// 5A5590: using guessed type char TransVal;

//----- (004481D2) --------------------------------------------------------
void __fastcall SyncPedistal(int i)
{
	int v1; // esi
	unsigned char *v2; // esi

	v1 = i;
	if ( object[i]._oVar6 == 1 )
		ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7);
	if ( object[v1]._oVar6 == 2 )
	{
		ObjChangeMapResync(setpc_x, setpc_y + 3, setpc_x + 2, setpc_y + 7);
		ObjChangeMapResync(setpc_x + 6, setpc_y + 3, setpc_x + setpc_w, setpc_y + 7);
	}
	if ( object[v1]._oVar6 == 3 )
	{
		ObjChangeMapResync(object[v1]._oVar1, object[v1]._oVar2, object[v1]._oVar3, object[v1]._oVar4);
		v2 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0);
		LoadMapObjs(v2, 2 * setpc_x, 2 * setpc_y);
		mem_free_dbg(v2);
	}
}
// 5CF334: using guessed type int setpc_w;

//----- (00448298) --------------------------------------------------------
void __fastcall SyncL2Doors(int i)
{
	int v1; // eax
	int v2; // esi
	int v3; // ecx
	int v4; // edx
	int v5; // eax

	v1 = i;
	v2 = object[i]._oVar4;
	if ( v2 )
		object[v1]._oMissFlag = 1;
	else
		object[v1]._oMissFlag = 0;
	v3 = object[v1]._ox;
	v4 = object[v1]._oy;
	_LOBYTE(object[v1]._oSelFlag) = 2;
	v5 = object[v1]._otype;
	if ( v5 != OBJ_L2LDOOR )
		goto LABEL_18;
	if ( !v2 )
	{
		ObjSetMicro(v3, v4, 538);
		return;
	}
	if ( v2 != 1 && v2 != 2 )
	{
LABEL_18:
		if ( v5 == OBJ_L2RDOOR )
		{
			if ( v2 )
			{
				if ( v2 == 1 || v2 == 2 )
					ObjSetMicro(v3, v4, 17);
			}
			else
			{
				ObjSetMicro(v3, v4, 540);
			}
		}
	}
	else
	{
		ObjSetMicro(v3, v4, 13);
	}
}

//----- (0044831E) --------------------------------------------------------
void __fastcall SyncL3Doors(int i)
{
	int v1; // eax
	int v2; // esi
	int v3; // ecx
	int v4; // edx
	int v5; // ebx
	int v6; // eax

	v1 = i;
	v2 = object[i]._otype;
	v3 = object[i]._ox;
	v4 = object[v1]._oy;
	object[v1]._oMissFlag = 1;
	_LOBYTE(object[v1]._oSelFlag) = 2;
	if ( v2 != OBJ_L3LDOOR )
		goto LABEL_15;
	if ( !object[v1]._oVar4 )
	{
		ObjSetMicro(v3, v4, 531);
		return;
	}
	v5 = object[v1]._oVar4;
	if ( v5 != 1 && v5 != 2 )
	{
LABEL_15:
		if ( v2 == OBJ_L3RDOOR )
		{
			if ( object[v1]._oVar4 )
			{
				v6 = object[v1]._oVar4;
				if ( v6 == 1 || v6 == 2 )
					ObjSetMicro(v3, v4, 541);
			}
			else
			{
				ObjSetMicro(v3, v4, 534);
			}
		}
	}
	else
	{
		ObjSetMicro(v3, v4, 538);
	}
}

//----- (004483B0) --------------------------------------------------------
void __fastcall SyncObjectAnim(int o)
{
	int v1; // edx
	int v2; // ebx
	int v3; // esi

	v1 = object[o]._otype;
	v2 = ObjFileList[0];
	v3 = 0;
	while ( v2 != (char)AllObjects[object[o]._otype].ofindex )
		v2 = ObjFileList[v3++ + 1];
	object[o]._oAnimCel = pObjCels[v3];
	if ( v1 <= OBJ_BOOK2R )
	{
		if ( v1 != OBJ_BOOK2R )
		{
			if ( v1 > OBJ_L1LIGHT )
			{
				if ( v1 <= OBJ_L1RDOOR )
				{
					SyncL1Doors(o);
				}
				else
				{
					if ( v1 == OBJ_LEVER )
						goto LABEL_30;
					if ( v1 > OBJ_SKSTICK5 )
					{
						if ( v1 <= OBJ_CRUX3 )
						{
							SyncCrux(o);
							return;
						}
						if ( v1 == OBJ_BOOK2L || v1 == OBJ_SWITCHSKL )
LABEL_30:
							SyncLever(o);
					}
				}
			}
			return;
		}
LABEL_24:
		SyncQSTLever(o);
		return;
	}
	if ( v1 >= OBJ_L2LDOOR )
	{
		if ( v1 <= OBJ_L2RDOOR )
		{
			SyncL2Doors(o);
			return;
		}
		if ( v1 == OBJ_BLINDBOOK )
			goto LABEL_24;
		if ( v1 == OBJ_PEDISTAL )
		{
			SyncPedistal(o);
			return;
		}
		if ( v1 > OBJ_PEDISTAL )
		{
			if ( v1 <= OBJ_L3RDOOR )
			{
				SyncL3Doors(o);
				return;
			}
			if ( v1 == OBJ_STEELTOME )
				goto LABEL_24;
		}
	}
}

//----- (0044845E) --------------------------------------------------------
void __fastcall GetObjectStr(int i)
{
	int v1; // edi

	v1 = i;
	switch ( object[i]._otype )
	{
		case OBJ_L1LDOOR:
		case OBJ_L1RDOOR:
		case OBJ_L2LDOOR:
		case OBJ_L2RDOOR:
		case OBJ_L3LDOOR:
		case OBJ_L3RDOOR:
			if ( object[v1]._oVar4 == 1 )
				strcpy(infostr, "Open Door");
			if ( !object[v1]._oVar4 )
				strcpy(infostr, "Closed Door");
			if ( object[v1]._oVar4 == 2 )
				strcpy(infostr, "Blocked Door");
			break;
		case OBJ_LEVER:
		case OBJ_FLAMELVR:
			strcpy(infostr, "Lever");
			break;
		case OBJ_CHEST1:
		case OBJ_TCHEST1:
			strcpy(infostr, "Small Chest");
			break;
		case OBJ_CHEST2:
		case OBJ_TCHEST2:
			strcpy(infostr, "Chest");
			break;
		case OBJ_CHEST3:
		case OBJ_TCHEST3:
		case OBJ_SIGNCHEST:
			strcpy(infostr, "Large Chest");
			break;
		case OBJ_CRUX1:
		case OBJ_CRUX2:
		case OBJ_CRUX3:
			strcpy(infostr, "Crucified Skeleton");
			break;
		case OBJ_BOOK2L:
			if ( setlevel )
			{
				if ( setlvlnum == SL_BONECHAMB )
				{
					strcpy(infostr, "Ancient Tome");
				}
				else if ( setlvlnum == SL_VILEBETRAYER )
				{
					strcpy(infostr, "Book of Vileness");
				}
			}
			break;
		case OBJ_SWITCHSKL:
			strcpy(infostr, "Skull Lever");
			break;
		case OBJ_BOOK2R:
			strcpy(infostr, "Mythical Book");
			break;
		case OBJ_SARC:
			strcpy(infostr, "Sarcophagus");
			break;
		case OBJ_BOOKSHELF:
			strcpy(infostr, "Bookshelf");
			break;
		case OBJ_BARREL:
		case OBJ_BARRELEX:
			strcpy(infostr, "Barrel");
			break;
		case OBJ_SHRINEL:
		case OBJ_SHRINER:
			sprintf(tempstr, "%s Shrine", shrinestrs[object[v1]._oVar1]);
			strcpy(infostr, tempstr);
			break;
		case OBJ_SKELBOOK:
			strcpy(infostr, "Skeleton Tome");
			break;
		case OBJ_BOOKCASEL:
		case OBJ_BOOKCASER:
			strcpy(infostr, "Bookcase");
			break;
		case OBJ_BOOKSTAND:
			strcpy(infostr, "Library Book");
			break;
		case OBJ_BLOODFTN:
			strcpy(infostr, "Blood Fountain");
			break;
		case OBJ_DECAP:
			strcpy(infostr, "Decapitated Body");
			break;
		case OBJ_BLINDBOOK:
			strcpy(infostr, "Book of the Blind");
			break;
		case OBJ_BLOODBOOK:
			strcpy(infostr, "Book of Blood");
			break;
		case OBJ_PEDISTAL:
			strcpy(infostr, "Pedestal of Blood");
			break;
		case OBJ_PURIFYINGFTN:
			strcpy(infostr, "Purifying Spring");
			break;
		case OBJ_ARMORSTAND:
		case OBJ_WARARMOR:
			strcpy(infostr, "Armor");
			break;
		case OBJ_GOATSHRINE:
			strcpy(infostr, "Goat Shrine");
			break;
		case OBJ_CAULDRON:
			strcpy(infostr, "Cauldron");
			break;
		case OBJ_MURKYFTN:
			strcpy(infostr, "Murky Pool");
			break;
		case OBJ_TEARFTN:
			strcpy(infostr, "Fountain of Tears");
			break;
		case OBJ_STORYBOOK:
			strcpy(infostr, StoryBookName[object[v1]._oVar3]);
			break;
		case OBJ_STEELTOME:
			strcpy(infostr, "Steel Tome");
			break;
		case OBJ_WARWEAP:
		case OBJ_WEAPONRACK:
			strcpy(infostr, "Weapon Rack");
			break;
		case OBJ_MUSHPATCH:
			strcpy(infostr, "Mushroom Patch");
			break;
		case OBJ_LAZSTAND:
			strcpy(infostr, "Vile Stand");
			break;
		case OBJ_SLAINHERO:
			strcpy(infostr, "Slain Hero");
			break;
		default:
			break;
	}
	if ( _LOBYTE(plr[myplr]._pClass) == 1 )
	{
		if ( object[v1]._oTrapFlag )
		{
			sprintf(tempstr, "Trapped %s", infostr);
			strcpy(infostr, tempstr);
			_LOBYTE(infoclr) = 2;
		}
	}
}
// 4B883C: using guessed type int infoclr;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (0044875A) --------------------------------------------------------
void __cdecl pack_cpp_init()
{
	hero_cpp_init_value = hero_inf;
}
// 47F168: using guessed type int hero_inf;
// 67D7C8: using guessed type int hero_cpp_init_value;

//----- (00448765) --------------------------------------------------------
void __fastcall PackPlayer(PkPlayerStruct *pPack, int pnum, bool manashield)
{
	PkPlayerStruct *v3; // esi
	int v4; // edi
	PlayerStruct *v5; // edi
	signed int v6; // eax
	signed int v7; // eax
	signed int i; // [esp+8h] [ebp-Ch]
	signed int ia; // [esp+8h] [ebp-Ch]
	signed int ib; // [esp+8h] [ebp-Ch]
	ItemStruct *pi; // [esp+Ch] [ebp-8h]
	ItemStruct *pia; // [esp+Ch] [ebp-8h]
	ItemStruct *pib; // [esp+Ch] [ebp-8h]
	PkItemStruct *pki; // [esp+10h] [ebp-4h]
	PkItemStruct *pkia; // [esp+10h] [ebp-4h]
	PkItemStruct *pkib; // [esp+10h] [ebp-4h]

	v3 = pPack;
	v4 = pnum;
	memset(pPack, 0, 0x4F2u);
	v5 = &plr[v4];
	v3->destAction = v5->destAction;
	v3->destParam1 = v5->destParam1;
	v3->destParam2 = v5->destParam2;
	v3->plrlevel = v5->plrlevel;
	v3->px = v5->WorldX;
	v3->py = v5->WorldY;
	v3->targx = v5->_ptargx;
	v3->targy = v5->_ptargy;
	strcpy(v3->pName, v5->_pName);
	v3->pClass = v5->_pClass;
	v3->pBaseStr = v5->_pBaseStr;
	v3->pBaseMag = v5->_pBaseMag;
	v3->pBaseDex = v5->_pBaseDex;
	v3->pBaseVit = v5->_pBaseVit;
	v3->pLevel = v5->_pLevel;
	v3->pStatPts = v5->_pStatPts;
	v3->pExperience = v5->_pExperience;
	v3->pGold = v5->_pGold;
	v3->pHPBase = v5->_pHPBase;
	v3->pMaxHPBase = v5->_pMaxHPBase;
	v3->pManaBase = v5->_pManaBase;
	v3->pMaxManaBase = v5->_pMaxManaBase;
	v3->pMemSpells = v5->_pMemSpells[0];
	v3->pMemSpells2 = v5->_pMemSpells[1];
	v6 = 0;
	do
	{
		v3->pSplLvl[v6] = v5->_pSplLvl[v6];
		++v6;
	}
	while ( v6 < 37 );
	pki = v3->InvBody;
	pi = v5->InvBody;
	i = 7;
	do
	{
		PackItem(pki, pi);
		++pki;
		++pi;
		--i;
	}
	while ( i );
	ia = 40;
	pkia = v3->InvList;
	pia = v5->InvList;
	do
	{
		PackItem(pkia, pia);
		++pkia;
		++pia;
		--ia;
	}
	while ( ia );
	v7 = 0;
	do
	{
		v3->InvGrid[v7] = v5->InvGrid[v7];
		++v7;
	}
	while ( v7 < 40 );
	ib = 8;
	v3->_pNumInv = v5->_pNumInv;
	pkib = v3->SpdList;
	pib = v5->SpdList;
	do
	{
		PackItem(pkib, pib);
		++pkib;
		++pib;
		--ib;
	}
	while ( ib );
	v3->pDiabloKillLevel = v5->pDiabloKillLevel;
	if ( gbMaxPlayers == 1 || manashield )
		v3->pManaShield = v5->pManaShield;
	else
		v3->pManaShield = 0;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00448953) --------------------------------------------------------
void __fastcall PackItem(PkItemStruct *id, ItemStruct *is)
{
	short v2; // ax
	short v3; // bx

	if ( is->_itype == -1 )
	{
		id->idx = -1;
	}
	else
	{
		id->idx = is->IDidx;
		if ( is->IDidx == IDI_EAR )
		{
			_LOBYTE(v2) = 0;
			_LOBYTE(v3) = 0;
			_HIBYTE(v2) = is->_iName[7];
			id->iCreateInfo = is->_iName[8] | v2;
			id->iSeed = is->_iName[12] | ((is->_iName[11] | ((is->_iName[10] | (is->_iName[9] << 8)) << 8)) << 8);
			id->bId = is->_iName[13];
			id->bDur = is->_iName[14];
			id->bMDur = is->_iName[15];
			id->bCh = is->_iName[16];
			id->bMCh = is->_iName[17];
			_HIBYTE(v3) = is->_iName[18];
			id->wValue = _LOWORD(is->_ivalue) | v3 | ((_LOWORD(is->_iCurs) - 19) << 6);
			id->dwBuff = is->_iName[22] | ((is->_iName[21] | ((is->_iName[20] | (is->_iName[19] << 8)) << 8)) << 8);
		}
		else
		{
			id->iSeed = is->_iSeed;
			id->iCreateInfo = is->_iCreateInfo;
			id->bId = _LOBYTE(is->_iIdentified) + 2 * is->_iMagical;
			id->bDur = is->_iDurability;
			id->bMDur = is->_iMaxDur;
			id->bCh = is->_iCharges;
			id->bMCh = is->_iMaxCharges;
			if ( !is->IDidx )
				id->wValue = is->_ivalue;
		}
	}
}

//----- (00448A5E) --------------------------------------------------------
void __fastcall VerifyGoldSeeds(PlayerStruct *pPlayer)
{
	PlayerStruct *v1; // esi
	int v2; // ebp
	int v3; // eax
	PlayerStruct *v4; // ebx
	signed int v5; // ecx
	int v6; // eax

	v1 = pPlayer;
	v2 = 0;
	v3 = pPlayer->_pNumInv;
	if ( v3 > 0 )
	{
		v4 = pPlayer;
		do
		{
			v5 = 0;
			if ( !v4->InvList[0].IDidx && v3 > 0 )
			{
				do
				{
					if ( v2 != v5 )
					{
						v6 = (int)v1 + 368 * v5;
						if ( !*(_DWORD *)(v6 + 3828) && v4->InvList[0]._iSeed == *(_DWORD *)(v6 + 3468) )
						{
							v4->InvList[0]._iSeed = GetRndSeed();
							v5 = -1;
						}
					}
					++v5;
				}
				while ( v5 < v1->_pNumInv );
			}
			v3 = v1->_pNumInv;
			++v2;
			v4 = (PlayerStruct *)((char *)v4 + 368);
		}
		while ( v2 < v3 );
	}
}

//----- (00448AD0) --------------------------------------------------------
void __fastcall UnPackPlayer(PkPlayerStruct *pPack, int pnum, bool killok)
{
	int v3; // ebx
	PlayerStruct *v4; // esi
	PkPlayerStruct *v5; // edi
	signed int v6; // eax
	signed int v7; // eax
	signed int v8; // eax
	int *v9; // eax
	int pPlayer; // [esp+Ch] [ebp-Ch]
	signed int i; // [esp+10h] [ebp-8h]
	signed int ia; // [esp+10h] [ebp-8h]
	signed int ib; // [esp+10h] [ebp-8h]
	ItemStruct *pi; // [esp+14h] [ebp-4h]
	ItemStruct *pia; // [esp+14h] [ebp-4h]
	ItemStruct *pib; // [esp+14h] [ebp-4h]
	PkItemStruct *pki; // [esp+20h] [ebp+8h]
	PkItemStruct *pkia; // [esp+20h] [ebp+8h]
	PkItemStruct *pkib; // [esp+20h] [ebp+8h]

	v3 = pnum;
	v4 = &plr[pnum];
	v5 = pPack;
	pPlayer = pnum;
	ClearPlrRVars(&plr[pnum]);
	v4->WorldX = (unsigned char)v5->px;
	v4->WorldY = (unsigned char)v5->py;
	v4->_px = (unsigned char)v5->px;
	v4->_py = (unsigned char)v5->py;
	v4->_ptargx = (unsigned char)v5->targx;
	v4->_ptargy = (unsigned char)v5->targy;
	v4->plrlevel = (unsigned char)v5->plrlevel;
	ClrPlrPath(v3);
	v4->destAction = -1;
	strcpy(v4->_pName, v5->pName);
	_LOBYTE(v4->_pClass) = v5->pClass;
	InitPlayer(v3, 1);
	v4->_pBaseStr = (unsigned char)v5->pBaseStr;
	v4->_pStrength = (unsigned char)v5->pBaseStr;
	v4->_pBaseMag = (unsigned char)v5->pBaseMag;
	v4->_pMagic = (unsigned char)v5->pBaseMag;
	v4->_pBaseDex = (unsigned char)v5->pBaseDex;
	v4->_pDexterity = (unsigned char)v5->pBaseDex;
	v4->_pBaseVit = (unsigned char)v5->pBaseVit;
	v4->_pVitality = (unsigned char)v5->pBaseVit;
	v4->_pLevel = v5->pLevel;
	v4->_pStatPts = (unsigned char)v5->pStatPts;
	v4->_pExperience = v5->pExperience;
	v4->_pGold = v5->pGold;
	v4->_pMaxHPBase = v5->pMaxHPBase;
	v6 = v5->pHPBase;
	v4->_pHPBase = v6;
	if ( !killok )
	{
		_LOBYTE(v6) = v6 & 0xC0;
		if ( v6 < 64 )
			v4->_pHPBase = 64;
	}
	v4->_pMaxManaBase = v5->pMaxManaBase;
	v4->_pManaBase = v5->pManaBase;
	v4->_pMemSpells[0] = v5->pMemSpells;
	v4->_pMemSpells[1] = v5->pMemSpells2;
	v7 = 0;
	do
	{
		v4->_pSplLvl[v7] = v5->pSplLvl[v7];
		++v7;
	}
	while ( v7 < 37 );
	i = 7;
	pki = v5->InvBody;
	pi = v4->InvBody;
	do
	{
		UnPackItem(pki, pi);
		++pki;
		++pi;
		--i;
	}
	while ( i );
	ia = 40;
	pkia = v5->InvList;
	pia = v4->InvList;
	do
	{
		UnPackItem(pkia, pia);
		++pkia;
		++pia;
		--ia;
	}
	while ( ia );
	v8 = 0;
	do
	{
		v4->InvGrid[v8] = v5->InvGrid[v8];
		++v8;
	}
	while ( v8 < 40 );
	v4->_pNumInv = (unsigned char)v5->_pNumInv;
	VerifyGoldSeeds(v4);
	ib = 8;
	pkib = v5->SpdList;
	pib = v4->SpdList;
	do
	{
		UnPackItem(pkib, pib);
		++pkib;
		++pib;
		--ib;
	}
	while ( ib );
	if ( pPlayer == myplr )
	{
		v9 = &witchitem[0]._itype;
		do
		{
			*v9 = -1;
			v9 += 92;
		}
		while ( (signed int)v9 < (signed int)healitem );
	}
	CalcPlrInv(pPlayer, 0);
	v4->pTownWarps = 0;
	v4->pDungMsgs = 0;
	v4->pLvlLoad = 0;
	v4->pDiabloKillLevel = v5->pDiabloKillLevel;
	v4->pBattleNet = v5->pBattleNet;
	v4->pManaShield = v5->pManaShield;
}

//----- (00448D48) --------------------------------------------------------
void __fastcall UnPackItem(PkItemStruct *is, ItemStruct *id)
{
	PkItemStruct *v2; // esi
	ItemStruct *v3; // edi
	unsigned short v4; // ax
	int v5; // ecx

	v2 = is;
	v3 = id;
	v4 = is->idx;
	if ( v4 == -1 )
	{
		id->_itype = -1;
	}
	else
	{
		if ( v4 == IDI_EAR )
		{
			RecreateEar(
				127,
				is->iCreateInfo,
				is->iSeed,
				is->bId,
				(unsigned char)is->bDur,
				(unsigned char)is->bMDur,
				(unsigned char)is->bCh,
				(unsigned char)is->bMCh,
				(unsigned short)is->wValue,
				is->dwBuff);
		}
		else
		{
			v5 = (unsigned short)is->wValue;
			_LOWORD(v5) = v2->iCreateInfo;
			TempItemGeneration(127, v4, v5, v2->iSeed, (unsigned short)v2->wValue);
			items[127]._iMagical = (unsigned char)v2->bId >> 1;
			items[127]._iIdentified = v2->bId & 1;
			items[127]._iDurability = (unsigned char)v2->bDur;
			items[127]._iMaxDur = (unsigned char)v2->bMDur;
			items[127]._iCharges = (unsigned char)v2->bCh;
			items[127]._iMaxCharges = (unsigned char)v2->bMCh;
		}
		qmemcpy(v3, &items[127], sizeof(ItemStruct));
	}
}

//----- (00448DFA) --------------------------------------------------------
void __cdecl palette_cpp_init()
{
	palette_cpp_init_value = palette_inf;
}
// 47F16C: using guessed type int palette_inf;
// 67DBCC: using guessed type int palette_cpp_init_value;

//----- (00448E05) --------------------------------------------------------
void __cdecl palette_save_gamme()
{
	SRegSaveValue("Diablo", "Gamma Correction", 0, gamma_correction);
	SRegSaveValue("Diablo", "Color Cycling", 0, color_cycling_enabled);
}

//----- (00448E33) --------------------------------------------------------
void __cdecl palette_init()
{
	int v0; // eax
	int v1; // eax

	palette_load_gamma();
	memcpy(system_palette, orig_palette, 0x400u);
	palette_load_system_palette();
	v0 = lpDDPPrimary->Initialize(
			 (IDirectDraw *)68,
			 (unsigned long)system_palette,
			 (tagPALETTEENTRY *)&lpDDPRed);
	if ( v0 )
		TermDlg(111, v0, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 143);
	v1 = IDirectDrawSurface_SetPalette(lpDDSPrimary, lpDDPRed);
	if ( v1 )
		TermDlg(111, v1, "C:\\Src\\Diablo\\Source\\PALETTE.CPP", 146);
}

//----- (00448EAB) --------------------------------------------------------
void __cdecl palette_load_gamma()
{
	int v0; // eax
	int v1; // ecx
	int v2; // eax
	int v3; // eax
	int value; // [esp+8h] [ebp-4h]

	value = gamma_correction;
	_LOBYTE(v0) = SRegLoadValue("Diablo", "Gamma Correction", 0, &value);
	if ( !v0 )
		value = 100;
	v1 = value;
	if ( value >= 30 )
	{
		if ( value > 100 )
			v1 = 100;
	}
	else
	{
		v1 = 30;
	}
	gamma_correction = v1 - v1 % 5;
	_LOBYTE(v2) = SRegLoadValue("Diablo", "Color Cycling", 0, &value);
	if ( v2 )
		v3 = value;
	else
		v3 = 1;
	color_cycling_enabled = v3;
}

//----- (00448F20) --------------------------------------------------------
void __cdecl palette_load_system_palette()
{
	BYTE *v0; // eax
	HDC v1; // ebx
	signed int v2; // eax
	signed int i; // ecx
	int v4; // esi
	int v5; // edi
	BYTE *v6; // eax

	v0 = &system_palette[0].peFlags;
	do
	{
		*v0 = 5;
		v0 += 4;
	}
	while ( (signed int)v0 < (signed int)&orig_palette[0].peFlags );
	if ( !exclusive )
	{
		v1 = GetDC(0);
		nsystem_reserve_palette_entries = GetDeviceCaps(v1, 106) / 2;
		GetSystemPaletteEntries(v1, 0, nsystem_reserve_palette_entries, system_palette);
		v2 = nsystem_reserve_palette_entries;
		for ( i = 0; i < v2; ++i )
			system_palette[i].peFlags = 0;
		v4 = 256 - v2;
		v5 = 256 - v2;
		GetSystemPaletteEntries(v1, 256 - v2, v2, &system_palette[v5]);
		if ( v4 < 256 )
		{
			v6 = &system_palette[v5].peFlags;
			do
			{
				*v6 = 0;
				v6 += 4;
			}
			while ( (signed int)v6 < (signed int)&orig_palette[0].peFlags );
		}
		ReleaseDC(0, v1);
	}
}
// 484364: using guessed type int exclusive;

//----- (00448FC9) --------------------------------------------------------
void __fastcall LoadPalette(char *pal_path)
{
	char *v1; // eax
	char *v2; // ecx
	char v3; // dl
	char a2[768]; // [esp+0h] [ebp-304h]
	void *a1; // [esp+300h] [ebp-4h]

	wave_open_file((LPARAM)pal_path, (DIABFILE *)&a1, 0);
	wave_read_file((int)a1, a2, 768);
	wave_close_file(a1);
	v1 = (char *)&orig_palette[0].peGreen;
	v2 = &a2[1];
	do
	{
		v3 = *(v2 - 1);
		v1[2] = 0;
		*(v1 - 1) = v3;
		*v1 = *v2;
		v1[1] = v2[1];
		v1 += 4;
		v2 += 3;
	}
	while ( (signed int)v1 < (signed int)&nsystem_reserve_palette_entries + 1 );
}

//----- (00449025) --------------------------------------------------------
void __fastcall LoadRndLvlPal(char dtype)
{
	int v1; // esi
	char *v2; // ecx
	int v3; // ecx
	int v4; // eax
	char v5[260]; // [esp+4h] [ebp-104h]

	v1 = dtype;
	if ( (_DWORD)dtype )
	{
		_LOBYTE(v3) = 0;
		v4 = random(v3, 4);
		sprintf(v5, "Levels\\L%iData\\L%i_%i.PAL", v1, v1, v4 + 1);
		v2 = v5;
	}
	else
	{
		v2 = "Levels\\TownData\\Town.pal";
	}
	LoadPalette(v2);
}

//----- (0044906C) --------------------------------------------------------
void __cdecl ResetPal()
{
	if ( !lpDDSPrimary
	  || IDirectDrawSurface_IsLost(lpDDSPrimary) != 0x887601C2
	  || !IDirectDrawSurface_Restore(lpDDSPrimary) )
	{
		SDrawRealizePalette();
	}
}

//----- (00449097) --------------------------------------------------------
void __cdecl palette_inc_gamma()
{
	if ( gamma_correction < 100 )
	{
		gamma_correction += 5;
		if ( gamma_correction > 100 )
			gamma_correction = 100;
		palette_apply_gamma_correction(system_palette, logical_palette, 256);
		palette_update();
	}
}

//----- (004490D0) --------------------------------------------------------
void __cdecl palette_update()
{
	int v0; // ecx
	int v1; // eax

	if ( lpDDPRed )
	{
		v0 = 0;
		v1 = 256;
		if ( !exclusive )
		{
			v0 = nsystem_reserve_palette_entries;
			v1 = 2 * (128 - nsystem_reserve_palette_entries);
		}
		SDrawUpdatePalette(v0, v1, &system_palette[v0], 0);
	}
}
// 484364: using guessed type int exclusive;

//----- (00449107) --------------------------------------------------------
void __fastcall palette_apply_gamma_correction(PALETTEENTRY *dst, PALETTEENTRY *src, int n)
{
	PALETTEENTRY *v3; // edi
	PALETTEENTRY *v4; // esi
	double v5; // [esp+18h] [ebp-Ch]

	v3 = src;
	v4 = dst;
	v5 = (double)gamma_correction * 0.01;
	if ( n > 0 )
	{
		do
		{
			v4->peRed = (signed __int64)(pow((double)v3->peRed * 0.00390625, v5) * 256.0);
			v4->peGreen = (signed __int64)(pow((double)v3->peGreen * 0.00390625, v5) * 256.0);
			v4->peBlue = (signed __int64)(pow((double)v3->peBlue * 0.00390625, v5) * 256.0);
			++v4;
			++v3;
			--n;
		}
		while ( n );
	}
}

//----- (004491D0) --------------------------------------------------------
void __cdecl palette_dec_gamma()
{
	if ( gamma_correction > 30 )
	{
		gamma_correction -= 5;
		if ( gamma_correction < 30 )
			gamma_correction = 30;
		palette_apply_gamma_correction(system_palette, logical_palette, 256);
		palette_update();
	}
}

//----- (00449209) --------------------------------------------------------
int __fastcall palette_update_gamma(int gamma)
{
	if ( gamma )
	{
		gamma_correction = 130 - gamma;
		palette_apply_gamma_correction(system_palette, logical_palette, 256);
		palette_update();
	}
	return 130 - gamma_correction;
}

//----- (0044923E) --------------------------------------------------------
void __cdecl BlackPalette()
{
	palette_set_brightness(0);
}

//----- (00449245) --------------------------------------------------------
void __fastcall palette_set_brightness(int brightness)
{
	signed int v1; // eax

	if ( lpDDPPrimary )
	{
		v1 = 0;
		do
		{
			system_palette[v1].peRed = (unsigned short)(brightness * logical_palette[v1].peRed) >> 8;
			system_palette[v1].peGreen = (unsigned short)(brightness * logical_palette[v1].peGreen) >> 8;
			system_palette[v1].peBlue = (unsigned short)(brightness * logical_palette[v1].peBlue) >> 8;
			++v1;
		}
		while ( v1 < 255 );
		Sleep(3u);
		IDirectDrawPalette_AddRef(
			lpDDPPrimary);
		palette_update();
	}
}

//----- (004492B0) --------------------------------------------------------
void __fastcall PaletteFadeIn(int inc)
{
	int v1; // ebp
	int v2; // [esp+10h] [ebp-4h]

	v2 = inc;
	palette_apply_gamma_correction(logical_palette, orig_palette, 256);
	v1 = 0;
	do
	{
		palette_set_brightness(v1);
		v1 += v2;
	}
	while ( v1 < 256 );
	palette_set_brightness(256);
	memcpy(logical_palette, orig_palette, 0x400u);
	palette_bright = 1;
}

//----- (00449306) --------------------------------------------------------
void __fastcall PaletteFadeOut(int dec)
{
	int v1; // edi
	int v2; // esi

	v1 = dec;
	if ( palette_bright )
	{
		v2 = 256;
		do
		{
			palette_set_brightness(v2);
			v2 -= v1;
		}
		while ( v2 > 0 );
		palette_set_brightness(0);
		palette_bright = 0;
	}
}

//----- (00449336) --------------------------------------------------------
void __cdecl palette_update_caves()
{
	short v0; // cx
	signed int v1; // esi
	signed int v2; // eax
	signed int v3; // eax
	BYTE v4; // [esp+6h] [ebp-2h]

	v0 = *(_WORD *)&system_palette[1].peRed;
	v4 = system_palette[1].peBlue;
	v1 = 1;
	do
	{
		v2 = v1++;
		system_palette[v2].peRed = system_palette[v2 + 1].peRed;
		system_palette[v2].peGreen = system_palette[v2 + 1].peGreen;
		system_palette[v2].peBlue = system_palette[v2 + 1].peBlue;
	}
	while ( v1 < 31 );
	v3 = v1;
	system_palette[v3].peRed = v0;
	system_palette[v3].peGreen = _HIBYTE(v0);
	system_palette[v3].peBlue = v4;
	palette_update();
}

//----- (00449398) --------------------------------------------------------
void __fastcall palette_update_quest_palette(int n)
{
	int i; // eax

	for ( i = 32 - n; i >= 0; --i )
		logical_palette[i] = orig_palette[i];
	palette_apply_gamma_correction(system_palette, logical_palette, 32);
	palette_update();
}

//----- (004493C6) --------------------------------------------------------
bool __cdecl palette_get_colour_cycling()
{
	return color_cycling_enabled;
}

//----- (004493CC) --------------------------------------------------------
void __fastcall palette_set_color_cycling(bool enabled)
{
	color_cycling_enabled = enabled;
}

//----- (004493D4) --------------------------------------------------------
int __fastcall FindPath(int (__fastcall *PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path)
{
	PATHNODE *v7; // eax
	PATHNODE *v8; // esi
	char v9; // al
	char v10; // cl
	PATHNODE *v11; // eax
	int result; // eax
	PATHNODE *v13; // edx
	int v14; // eax
	int v15; // edi
	bool v16; // zf
	int *v17; // ecx
	char v18; // dl
	int (__fastcall *a1)(int, int, int); // [esp+Ch] [ebp-8h]
	int a2; // [esp+10h] [ebp-4h]

	pnode_vals[0] = 0;
	a2 = PosOkArg;
	a1 = PosOk;
	*(_DWORD *)&path_2_nodes[0].f = (unsigned int)path_clear_node();
	v7 = path_clear_node();
	dword_6820C8 = 0;
	pnode_ptr = v7;
	v8 = path_clear_node();
	_LOBYTE(v8->g) = 0;
	v9 = path_xycoord(sx, sy, dx, dy);
	v10 = v8->g;
	v8->h = v9;
	v8->x = sx;
	v8->f = v9 + v10;
	v8->y = sy;
	*(_DWORD *)(*(_DWORD *)&path_2_nodes[0].f + 48) = (unsigned int)v8;
	while ( 1 )
	{
		v11 = GetNextPath();
		if ( !v11 )
			return 0;
		if ( v11->x == dx && v11->y == dy )
			break;
		if ( !path_get_path(a1, a2, v11, dx, dy) )
			return 0;
	}
	v13 = v11;
	v14 = (int)&v11->Parent;
	v15 = 0;
	if ( *(_DWORD *)v14 )
	{
		while ( 1 )
		{
			v16 = v15 == 25;
			if ( v15 >= 25 )
				break;
			pnode_vals[++v15] = (char)path_directions[3 * (v13->y - *(_DWORD *)(*(_DWORD *)v14 + 8))
													- *(_DWORD *)(*(_DWORD *)v14 + 4)
													+ 4
													+ v13->x];
			v13 = *(PATHNODE **)v14;
			v14 = *(_DWORD *)v14 + 12;
			if ( !*(_DWORD *)v14 )
			{
				v16 = v15 == 25;
				break;
			}
		}
		if ( v16 )
			return 0;
	}
	result = 0;
	if ( v15 > 0 )
	{
		v17 = &pnode_vals[v15];
		do
		{
			v18 = *(_BYTE *)v17;
			--v17;
			path[result++] = v18;
		}
		while ( result < v15 );
	}
	return result;
}

//----- (004494D3) --------------------------------------------------------
int __fastcall path_xycoord(int x, int y, int xx, int yy)
{
	int v4; // esi
	int v5; // edi
	int v6; // eax
	int v7; // ecx

	v4 = y;
	v5 = abs(x - xx);
	v6 = abs(v4 - yy);
	v7 = v5;
	if ( v5 >= v6 )
	{
		v7 = v6;
		if ( v5 > v6 )
			v6 = v5;
	}
	return 2 * (v7 + v6);
}

//----- (00449504) --------------------------------------------------------
int __fastcall path_check_equal(PATHNODE *pPath, int dx, int dy)
{
	int v4; // [esp-4h] [ebp-4h]

	if ( pPath->x == dx || pPath->y == dy )
		v4 = 2;
	else
		v4 = 3;
	return v4;
}

//----- (0044951C) --------------------------------------------------------
PATHNODE *__cdecl GetNextPath()
{
	PATHNODE *result; // eax

	result = *(PATHNODE **)(*(_DWORD *)&path_2_nodes[0].f + 48);
	if ( result )
	{
		*(_DWORD *)(*(_DWORD *)&path_2_nodes[0].f + 48) = (unsigned int)result->NextNode;
		result->NextNode = pnode_ptr->NextNode;
		pnode_ptr->NextNode = result;
	}
	return result;
}

//----- (00449546) --------------------------------------------------------
PATHNODE *__fastcall path_solid_pieces(PATHNODE *pPath, int dx, int dy)
{
	PATHNODE *result; // eax
	int v4; // ecx
	int v5; // ecx
	int v6; // ecx
	int v7; // edx
	int v8; // ecx
	int v9; // ecx
	int v10; // edx
	int v11; // edx

	result = (PATHNODE *)1;
	v4 = (char)path_directions[3 * (dy - pPath->y) - pPath->x + 4 + dx] - 5;
	if ( !v4 )
	{
		result = 0;
		v11 = dy + 112 * dx;
		if ( nSolidTable[dPiece[0][v11 + 1]] )
			return result;
		v8 = dPiece[1][v11];
		goto LABEL_13;
	}
	v5 = v4 - 1;
	if ( !v5 )
	{
		v9 = 112 * dx + dy;
		v10 = dPiece[0][v9 + 1];
		goto LABEL_9;
	}
	v6 = v5 - 1;
	if ( !v6 )
	{
		v9 = 112 * dx + dy;
		v10 = *(_DWORD *)&dflags[39][4 * v9 + 36];
LABEL_9:
		result = 0;
		if ( nSolidTable[v10] )
			return result;
		v8 = *(_DWORD *)&dflags[28][4 * v9 + 32];
		goto LABEL_13;
	}
	if ( v6 == 1 )
	{
		result = 0;
		v7 = dy + 112 * dx;
		if ( !nSolidTable[dPiece[1][v7]] )
		{
			v8 = *(_DWORD *)&dflags[39][v7 * 4 + 36];
LABEL_13:
			if ( nSolidTable[v8] == (_BYTE)result )
				result = (PATHNODE *)1;
			return result;
		}
	}
	return result;
}

//----- (004495ED) --------------------------------------------------------
int __fastcall path_get_path(int (__fastcall *PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y)
{
	int v5; // eax
	int v6; // esi
	int v7; // edi
	int (__fastcall *v9)(int, int, int); // [esp+Ch] [ebp-Ch]
	int v10; // [esp+10h] [ebp-8h]
	int i; // [esp+14h] [ebp-4h]

	v5 = 0;
	v10 = PosOkArg;
	v9 = PosOk;
	for ( i = 0; ; v5 = i )
	{
		v6 = pPath->x + (char)pathxdir[v5];
		v7 = pPath->y + (char)pathydir[v5];
		if ( !v9(v10, v6, v7) )
			break;
		if ( path_solid_pieces(pPath, v6, v7) )
			goto LABEL_8;
LABEL_9:
		if ( ++i >= 8 )
			return 1;
	}
	if ( v6 != x || v7 != y )
		goto LABEL_9;
LABEL_8:
	if ( path_parent_path(pPath, v6, v7, x, y) )
		goto LABEL_9;
	return 0;
}

//----- (0044966F) --------------------------------------------------------
PATHNODE *__fastcall path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy)
{
	PATHNODE *v5; // edi
	int v6; // ebx
	PATHNODE *v7; // esi
	signed int v8; // eax
	struct PATHNODE **v9; // ecx
	char v10; // al
	PATHNODE *v11; // esi
	signed int v12; // eax
	struct PATHNODE **v13; // ecx
	char v14; // al
	PATHNODE *result; // eax
	PATHNODE *v16; // esi
	char v17; // al
	signed int v18; // ecx
	struct PATHNODE **v19; // eax
	int a1; // [esp+Ch] [ebp-4h]

	a1 = dx;
	v5 = pPath;
	v6 = SLOBYTE(pPath->g) + path_check_equal(pPath, dx, dy);
	v7 = path_get_node_xy(a1, dy);
	if ( v7 )
	{
		v8 = 0;
		v9 = v5->Child;
		do
		{
			if ( !*v9 )
				break;
			++v8;
			++v9;
		}
		while ( v8 < 8 );
		v5->Child[v8] = v7;
		if ( v6 < SLOBYTE(v7->g) )
		{
			if ( path_solid_pieces(v5, a1, dy) )
			{
				v10 = v7->h;
				v7->Parent = v5;
				_LOBYTE(v7->g) = v6;
				v7->f = v6 + v10;
			}
		}
	}
	else
	{
		v11 = path_get_node_xyptr(a1, dy);
		if ( v11 )
		{
			v12 = 0;
			v13 = v5->Child;
			do
			{
				if ( !*v13 )
					break;
				++v12;
				++v13;
			}
			while ( v12 < 8 );
			v5->Child[v12] = v11;
			if ( v6 < SLOBYTE(v11->g) && path_solid_pieces(v5, a1, dy) )
			{
				v14 = v6 + v11->h;
				v11->Parent = v5;
				_LOBYTE(v11->g) = v6;
				v11->f = v14;
				path_set_coords(v11);
			}
		}
		else
		{
			result = path_clear_node();
			v16 = result;
			if ( !result )
				return result;
			result->Parent = v5;
			_LOBYTE(result->g) = v6;
			v17 = path_xycoord(a1, dy, sx, sy);
			v16->h = v17;
			v16->f = v6 + v17;
			v16->x = a1;
			v16->y = dy;
			path_get_node2(v16);
			v18 = 0;
			v19 = v5->Child;
			do
			{
				if ( !*v19 )
					break;
				++v18;
				++v19;
			}
			while ( v18 < 8 );
			v5->Child[v18] = v16;
		}
	}
	return (PATHNODE *)1;
}

//----- (0044979A) --------------------------------------------------------
PATHNODE *__fastcall path_get_node_xy(int dx, int dy)
{
	PATHNODE *result; // eax

	result = *(PATHNODE **)&path_2_nodes[0].f;
	do
		result = result->NextNode;
	while ( result && (result->x != dx || result->y != dy) );
	return result;
}

//----- (004497B3) --------------------------------------------------------
PATHNODE *__fastcall path_get_node_xyptr(int dx, int dy)
{
	PATHNODE *result; // eax

	result = pnode_ptr;
	do
		result = result->NextNode;
	while ( result && (result->x != dx || result->y != dy) );
	return result;
}

//----- (004497CC) --------------------------------------------------------
PATHNODE *__fastcall path_get_node2(PATHNODE *pPath)
{
	PATHNODE *v1; // edx
	PATHNODE *result; // eax

	v1 = *(PATHNODE **)&path_2_nodes[0].f;
	result = *(PATHNODE **)(*(_DWORD *)&path_2_nodes[0].f + 48);
	if ( result )
	{
		do
		{
			if ( result->f >= pPath->f )
				break;
			v1 = result;
			result = result->NextNode;
		}
		while ( result );
		pPath->NextNode = result;
	}
	v1->NextNode = pPath;
	return result;
}

//----- (004497F7) --------------------------------------------------------
PATHNODE *__fastcall path_set_coords(PATHNODE *pPath)
{
	PATHNODE *result; // eax
	PATHNODE *v2; // edi
	PATHNODE *v3; // esi
	int v4; // ebx
	int v5; // edx
	int v6; // edx
	char v7; // al
	char v8; // cl
	signed int v9; // [esp+0h] [ebp-8h]
	PATHNODE *v10; // [esp+4h] [ebp-4h]

	result = path_set_node_ptr(pPath);
	while ( dword_6820C8 )
	{
		v9 = 0;
		v2 = path_decrease_node();
		v10 = (PATHNODE *)((char *)v2 + 16);
		do
		{
			result = v10;
			v3 = *(PATHNODE **)&v10->f;
			if ( !*(_DWORD *)&v10->f )
				break;
			v4 = v3->y;
			result = (PATHNODE *)(SLOBYTE(v2->g) + path_check_equal(v2, v3->x, v3->y));
			if ( (signed int)result < SLOBYTE(v3->g) )
			{
				result = path_solid_pieces(v2, v5, v4);
				if ( result )
				{
					v6 = v3->x;
					v3->Parent = v2;
					v7 = _LOBYTE(v2->g) + path_check_equal(v2, v6, v4);
					v8 = v3->h;
					_LOBYTE(v3->g) = v7;
					v3->f = v7 + v8;
					result = path_set_node_ptr(v3);
				}
			}
			++v9;
			v10 = (PATHNODE *)((char *)v10 + 4);
		}
		while ( v9 < 8 );
	}
	return result;
}

//----- (00449890) --------------------------------------------------------
PATHNODE *__fastcall path_set_node_ptr(PATHNODE *pPath)
{
	PATHNODE *result; // eax

	result = (PATHNODE *)dword_6820C8++;
	pnode_tblptr[(_DWORD)result] = pPath;
	return result;
}

//----- (004498A3) --------------------------------------------------------
PATHNODE *__cdecl path_decrease_node()
{
	return pnode_tblptr[--dword_6820C8];
}

//----- (004498B6) --------------------------------------------------------
PATHNODE *__cdecl path_clear_node()
{
	PATHNODE *v1; // esi

	if ( pnode_vals[0] == 300 )
		return 0;
	v1 = &path_nodes[pnode_vals[0]++];
	memset(v1, 0, 0x34u);
	return v1;
}

//----- (004498F1) --------------------------------------------------------
void __cdecl pfile_cpp_init()
{
	pfile_cpp_init_value = pfile_inf;
}
// 47F1C0: using guessed type int pfile_inf;

//----- (004498FC) --------------------------------------------------------
void __cdecl pfile_init_save_directory()
{
	char Buffer[260]; // [esp+4h] [ebp-104h]

	if ( GetWindowsDirectoryA(Buffer, 0x104u)
	  && (pfile_check_available_space(Buffer), GetModuleFileNameA(hInstance, Buffer, 0x104u)) )
	{
		pfile_check_available_space(Buffer);
	}
	else
	{
		TermMsg("Unable to initialize save directory");
	}
}

//----- (0044995B) --------------------------------------------------------
void __fastcall pfile_check_available_space(char *pszDir)
{
	char *v1; // edi
	char *v2; // eax
	char v3; // cl
	BOOL v4; // esi
	DWORD TotalNumberOfClusters; // [esp+8h] [ebp-10h]
	DWORD NumberOfFreeClusters; // [esp+Ch] [ebp-Ch]
	DWORD BytesPerSector; // [esp+10h] [ebp-8h]
	DWORD SectorsPerCluster; // [esp+14h] [ebp-4h]

	v1 = pszDir;
	v2 = pszDir;
	while ( 1 )
	{
		v3 = *v2;
		if ( !*v2 )
			break;
		++v2;
		if ( v3 == 92 )
		{
			*v2 = 0;
			break;
		}
	}
	v4 = GetDiskFreeSpaceA(v1, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters, &TotalNumberOfClusters);
	if ( !v4 )
		goto LABEL_12;
	if ( (signed __int64)(BytesPerSector * (unsigned __int64)SectorsPerCluster * NumberOfFreeClusters) < 0xA00000 )
		v4 = 0;
	if ( !v4 )
LABEL_12:
		DiskFreeDlg(v1);
}

//----- (004499C3) --------------------------------------------------------
void __cdecl pfile_write_hero()
{
	int v0; // eax
	int v1; // esi
	int v2; // eax
	PkPlayerStruct pkplr; // [esp+4h] [ebp-4F4h]

	v0 = pfile_get_save_num_from_name(plr[myplr]._pName);
	v1 = v0;
	_LOBYTE(v2) = pfile_open_archive(1, v0);
	if ( v2 )
	{
		PackPlayer(&pkplr, myplr, gbMaxPlayers == 1);
		pfile_encode_hero(&pkplr);
		pfile_flush(gbMaxPlayers == 1, v1);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00449A33) --------------------------------------------------------
int __fastcall pfile_get_save_num_from_name(char *name)
{
	char *v1; // ebx
	unsigned int v2; // esi
	char *v3; // edi

	v1 = name;
	v2 = 0;
	v3 = hero_names;
	do
	{
		if ( !_strcmpi(v3, v1) )
			break;
		++v2;
		v3 += 32;
	}
	while ( v2 < 0xA );
	return v2;
}

//----- (00449A5B) --------------------------------------------------------
void __fastcall pfile_encode_hero(PkPlayerStruct *pPack)
{
	int v1; // ebx
	void *v2; // edi
	char password[16]; // [esp+Ch] [ebp-14h]
	void *v4; // [esp+1Ch] [ebp-4h]

	strcpy(password, "xrgyrkj1");
	*(_DWORD *)&password[9] = 0;
	*(_WORD *)&password[13] = 0;
	v4 = pPack;
	password[15] = 0;
	if ( (unsigned char)gbMaxPlayers > 1u )
		strcpy(password, "szqnlsk1");
	v1 = codec_get_encoded_len(1266);
	v2 = DiabloAllocPtr(v1);
	memcpy(v2, v4, 0x4F2u);
	codec_encode(v2, 1266, v1, password);
	mpqapi_write_file("hero", (char *)v2, v1);
	mem_free_dbg(v2);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00449ADF) --------------------------------------------------------
bool __fastcall pfile_open_archive(bool a1, int save_num)
{
	int v2; // esi
	BOOL v3; // edi
	int v4; // eax
	char FileName[260]; // [esp+8h] [ebp-104h]

	v2 = save_num;
	v3 = a1;
	pfile_get_save_path(FileName, 260, save_num);
	_LOBYTE(v4) = mpqapi_open_archive(FileName, 0, v2);
	if ( v4 )
		return 1;
	if ( v3 )
	{
		if ( (unsigned char)gbMaxPlayers > 1u )
			MI_Dummy(v2);
	}
	return 0;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00449B30) --------------------------------------------------------
void __fastcall pfile_get_save_path(char *pszBuf, int dwBufSize, int save_num)
{
	char *v3; // esi
	const char *v4; // ebx
	DWORD v5; // edi
	char *v6; // eax
	char v7[260]; // [esp+8h] [ebp-104h]

	v3 = pszBuf;
	v4 = "\\multi_%d.sv";
	if ( (unsigned char)gbMaxPlayers <= 1u )
		v4 = "\\single_%d.sv";
	v5 = GetModuleFileNameA(hInstance, pszBuf, 0x104u);
	v6 = strrchr(v3, 92);
	if ( v6 )
		*v6 = 0;
	if ( !v5 )
		TermMsg("Unable to get save directory");
	sprintf(v7, v4, save_num);
	strcat(v3, v7);
	strlwr(v3);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00449BB2) --------------------------------------------------------
void __fastcall pfile_flush(bool is_single_player, int save_num)
{
	int v2; // esi
	bool v3; // di
	char FileName[260]; // [esp+8h] [ebp-104h]

	v2 = save_num;
	v3 = is_single_player;
	pfile_get_save_path(FileName, 260, save_num);
	mpqapi_flush_and_close(FileName, v3, v2);
}

//----- (00449BE4) --------------------------------------------------------
bool __fastcall pfile_create_player_description(char *dst, int len)
{
	int v2; // edi
	char *v3; // ebx
	int v4; // eax
	char src[128]; // [esp+Ch] [ebp-ACh]
	_uiheroinfo hero_info; // [esp+8Ch] [ebp-2Ch]

	myplr = 0;
	v2 = len;
	v3 = dst;
	pfile_read_player_from_save();
	game_2_ui_player(plr, &hero_info, gbValidSaveFile);
	UiSetupPlayerInfo(chr_name_str, &hero_info, 'DRTL');
	if ( !v3 || !v2 )
		goto LABEL_5;
	v4 = UiCreatePlayerDescription(&hero_info, 'DRTL', src);
	if ( v4 )
	{
		SStrCopy(v3, src, v2);
LABEL_5:
		_LOBYTE(v4) = 1;
	}
	return v4;
}

//----- (00449C5A) --------------------------------------------------------
int __fastcall pfile_create_save_file(char *name_1, char *name_2)
{
	char *v2; // edi
	char *v3; // ebp
	int v4; // esi
	int v5; // eax
	char *v7; // [esp+20h] [ebp-30h]
	_uiheroinfo heroinfo; // [esp+24h] [ebp-2Ch]

	v2 = name_2;
	v3 = name_1;
	if ( pfile_get_save_num_from_name(name_2) != 10 )
		return 0;
	v4 = 0;
	v7 = plr[0]._pName;
	while ( _strcmpi(v3, v7) )
	{
		v7 += 21720;
		++v4;
		if ( v7 == &plr_msgs[1].msg[115] )
			return 0;
	}
	v5 = pfile_get_save_num_from_name(v3);
	if ( v5 == 10 )
		return 0;
	SStrCopy(&hero_names[32 * v5], v2, 32);
	SStrCopy(plr[v4]._pName, v2, 32);
	if ( !_strcmpi(chr_name_str, v3) )
		SStrCopy(chr_name_str, v2, 16);
	game_2_ui_player(plr, &heroinfo, gbValidSaveFile);
	UiSetupPlayerInfo(chr_name_str, &heroinfo, 'DRTL');
	pfile_write_hero();
	return 1;
}

//----- (00449D22) --------------------------------------------------------
void __cdecl pfile_flush_W()
{
	int v0; // eax

	v0 = pfile_get_save_num_from_name(plr[myplr]._pName);
	pfile_flush(1, v0);
}

//----- (00449D43) --------------------------------------------------------
void __fastcall game_2_ui_player(PlayerStruct *p, _uiheroinfo *heroinfo, bool bHasSaveFile)
{
	_uiheroinfo *v3; // esi
	PlayerStruct *v4; // edi
	char v5; // al

	v3 = heroinfo;
	v4 = p;
	memset(heroinfo, 0, 0x2Cu);
	strncpy(v3->name, v4->_pName, 0xFu);
	v3->name[15] = 0;
	v3->level = v4->_pLevel;
	v3->heroclass = game_2_ui_class(v4);
	v3->strength = v4->_pStrength;
	v3->magic = v4->_pMagic;
	v3->dexterity = v4->_pDexterity;
	v3->vitality = v4->_pVitality;
	v3->gold = v4->_pGold;
	v3->hassaved = bHasSaveFile;
	v5 = v4->pDiabloKillLevel;
	v3->spawned = 0;
	v3->herorank = v5;
}

//----- (00449DD0) --------------------------------------------------------
char __fastcall game_2_ui_class(PlayerStruct *p)
{
	char result; // al

	result = p->_pClass;
	if ( result )
		result = (result != 1) + 1;
	return result;
}

//----- (00449DE3) --------------------------------------------------------
bool __stdcall pfile_ui_set_hero_infos(void (__stdcall *ui_add_hero_info)(_uiheroinfo *))
{
	char *v1; // esi
	int v2; // eax
	int v3; // eax
	DWORD v4; // eax
	unsigned int v5; // esi
	char *v6; // ebx
	void *v7; // eax
	void *v8; // edi
	int v9; // eax
	bool v10; // al
	PkPlayerStruct pkplr; // [esp+Ch] [ebp-7BCh]
	struct _OFSTRUCT ReOpenBuff; // [esp+500h] [ebp-2C8h]
	char FileName[260]; // [esp+588h] [ebp-240h]
	char NewFileName[260]; // [esp+68Ch] [ebp-13Ch]
	_uiheroinfo hero_info; // [esp+790h] [ebp-38h]
	int unused; // [esp+7BCh] [ebp-Ch]
	LPCSTR lpSrcStr; // [esp+7C0h] [ebp-8h]
	int save_num; // [esp+7C4h] [ebp-4h]

	memset(hero_names, 0, 0x140u);
	if ( (unsigned char)gbMaxPlayers > 1u )
	{
		lpSrcStr = 0;
		save_num = 0;
		do
		{
			if ( (unsigned int)save_num >= 0xA )
				break;
			pfile_get_archive_path(FileName, 260, (int)lpSrcStr);
			v1 = strrchr(FileName, 92) + 1;
			if ( v1 != (char *)1 && OpenFile(FileName, &ReOpenBuff, 0x4000u) != -1 )
			{
				_LOBYTE(v2) = SRegLoadString((const char *)"Diablo\\Converted", (const char *)v1, 0, NewFileName, 260);
				if ( !v2 )
				{
					while ( 1 )
					{
						v3 = save_num++;
						pfile_get_save_path(NewFileName, 260, v3);
						if ( OpenFile(NewFileName, &ReOpenBuff, 0x4000u) == -1 )
							break;
						if ( (unsigned int)save_num >= 0xA )
							goto LABEL_13;
					}
					if ( CopyFileA(FileName, NewFileName, 1) )
					{
						SRegSaveString("Diablo\\Converted", v1, 0, NewFileName);
						v4 = GetFileAttributesA(NewFileName);
						if ( v4 != -1 )
						{
							_LOBYTE(v4) = v4 & 0xF9;
							SetFileAttributesA(NewFileName, v4);
						}
					}
				}
			}
LABEL_13:
			++lpSrcStr;
		}
		while ( (unsigned int)lpSrcStr < 0xA );
	}
	unused = 1;
	v5 = 0;
	v6 = hero_names;
	do
	{
		v7 = pfile_open_save_archive(&unused, v5);
		v8 = v7;
		if ( v7 )
		{
			_LOBYTE(v9) = pfile_read_hero(v7, &pkplr);
			if ( v9 )
			{
				strcpy(v6, pkplr.pName);
				UnPackPlayer(&pkplr, 0, 0);
				v10 = pfile_archive_contains_game(v8);
				game_2_ui_player(plr, &hero_info, v10);
				ui_add_hero_info(&hero_info);
			}
			pfile_SFileCloseArchive(v8);
		}
		++v5;
		v6 += 32;
	}
	while ( v5 < 0xA );
	return 1;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00449FAA) --------------------------------------------------------
char *__fastcall pfile_get_archive_path(char *dst, int dst_size, int save_num)
{
	char *v3; // esi
	const char *v4; // ebx
	DWORD v5; // edi
	char *v6; // eax
	char path_buf[260]; // [esp+Ch] [ebp-104h]

	v3 = dst;
	if ( (unsigned char)gbMaxPlayers <= 1u )
	{
		v4 = "\\single_%d.sv";
		v5 = GetModuleFileNameA(hInstance, dst, 0x104u);
		v6 = strrchr(v3, 92);
		if ( v6 )
			*v6 = 0;
	}
	else
	{
		v4 = "\\dlinfo_%d.drv";
		v5 = GetWindowsDirectoryA(dst, 0x104u);
	}
	if ( !v5 )
		TermMsg("Unable to get save directory");
	sprintf(path_buf, v4, save_num);
	strcat(v3, path_buf);
	return strlwr(v3);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044A036) --------------------------------------------------------
bool __fastcall pfile_read_hero(void *archive, PkPlayerStruct *hero)
{
	BOOL v2; // eax
	int v3; // eax
	int v4; // edi
	char *v5; // eax
	char *v6; // esi
	int v7; // eax
	int v8; // eax
	char password[16]; // [esp+4h] [ebp-24h]
	void *v11; // [esp+14h] [ebp-14h]
	DWORD nSize; // [esp+18h] [ebp-10h]
	int v13; // [esp+1Ch] [ebp-Ch]
	int nread; // [esp+20h] [ebp-8h]
	void *file; // [esp+24h] [ebp-4h]

	v11 = hero;
	_LOBYTE(v2) = SFileOpenFileEx(archive, "hero", 0, &file);
	if ( v2 )
	{
		strcpy(password, "xrgyrkj1");
		v13 = 0;
		*(_DWORD *)&password[9] = 0;
		*(_WORD *)&password[13] = 0;
		password[15] = 0;
		nSize = 16;
		if ( (unsigned char)gbMaxPlayers > 1u )
			strcpy(password, "szqnlsk1");
		v3 = SFileGetFileSize((int *)file, 0);
		v4 = v3;
		if ( !v3 )
			goto LABEL_15;
		v5 = (char *)DiabloAllocPtr(v3);
		v6 = v5;
		_LOBYTE(v7) = SFileReadFile(file, v5, v4, (unsigned long *)&nread, 0);
		if ( v7 )
		{
			nread = codec_decode(v6, v4, password);
			if ( nread )
				goto LABEL_11;
			if ( (unsigned char)gbMaxPlayers > 1u )
			{
				GetComputerNameA(password, &nSize);
				if ( !SFileSetFilePointer((int)file, 0, 0, 0) )
				{
					_LOBYTE(v8) = SFileReadFile(file, v6, v4, (unsigned long *)&nread, 0);
					if ( v8 )
					{
						nread = codec_decode(v6, v4, password);
LABEL_11:
						if ( nread == 1266 )
						{
							memcpy(v11, v6, 0x4F2u);
							v13 = 1;
						}
						goto LABEL_13;
					}
				}
			}
		}
LABEL_13:
		if ( v6 )
			mem_free_dbg(v6);
LABEL_15:
		SFileCloseFile(file);
		_LOBYTE(v2) = v13;
	}
	return v2;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044A158) --------------------------------------------------------
void *__fastcall pfile_open_save_archive(int *unused, int save_num)
{
	int v2; // eax
	char SrcStr[260]; // [esp+0h] [ebp-108h]
	void *archive; // [esp+104h] [ebp-4h]

	pfile_get_save_path(SrcStr, 260, save_num);
	_LOBYTE(v2) = SFileOpenArchive(SrcStr, 0x7000, 0, &archive);
	return (void *)(v2 != 0 ? (unsigned int)archive : 0);
}

//----- (0044A192) --------------------------------------------------------
void __fastcall pfile_SFileCloseArchive(void *hsArchive)
{
	SFileCloseArchive(hsArchive);
}

//----- (0044A199) --------------------------------------------------------
bool __fastcall pfile_archive_contains_game(void *hsArchive)
{
	int v1; // eax
	void *file; // [esp+0h] [ebp-4h]

	file = hsArchive;
	if ( gbMaxPlayers != 1 )
		return 0;
	_LOBYTE(v1) = SFileOpenFileEx(hsArchive, "game", 0, &file);
	if ( !v1 )
		return 0;
	SFileCloseFile(file);
	return 1;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044A1CC) --------------------------------------------------------
bool __stdcall pfile_ui_set_class_stats(int player_class_nr, _uidefaultstats *class_stats)
{
	int v2; // eax

	v2 = (char)pfile_get_player_class(player_class_nr);
	class_stats->strength = StrengthTbl[v2];
	class_stats->magic = MagicTbl[v2];
	class_stats->dexterity = DexterityTbl[v2];
	class_stats->vitality = VitalityTbl[v2];
	return 1;
}

//----- (0044A210) --------------------------------------------------------
int __fastcall pfile_get_player_class(int player_class_nr)
{
	int result; // eax

	if ( player_class_nr )
		_LOBYTE(result) = (player_class_nr != 1) + 1;
	else
		_LOBYTE(result) = 0;
	return result;
}

//----- (0044A220) --------------------------------------------------------
bool __stdcall pfile_ui_save_create(_uiheroinfo *heroinfo)
{
	unsigned int v1; // edi
	char *v2; // eax
	int v3; // eax
	char v5; // al
	PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h]

	v1 = pfile_get_save_num_from_name(heroinfo->name);
	if ( v1 == 10 )
	{
		v1 = 0;
		v2 = hero_names;
		do
		{
			if ( !*v2 )
				break;
			++v1;
			v2 += 32;
		}
		while ( v1 < 0xA );
		if ( v1 == 10 )
			return 0;
	}
	_LOBYTE(v3) = pfile_open_archive(0, v1);
	if ( !v3 )
		return 0;
	mpqapi_remove_hash_entries(pfile_get_file_name);
	strncpy(&hero_names[32 * v1], heroinfo->name, 0x20u);
	hero_names[32 * v1 + 31] = 0;
	v5 = pfile_get_player_class((unsigned char)heroinfo->heroclass);
	CreatePlayer(0, v5);
	strncpy(plr[0]._pName, heroinfo->name, 0x20u);
	plr[0]._pName[31] = 0;
	PackPlayer(&pkplr, 0, 1);
	pfile_encode_hero(&pkplr);
	game_2_ui_player(plr, heroinfo, 0);
	pfile_flush(1, v1);
	return 1;
}

//----- (0044A2FF) --------------------------------------------------------
bool __stdcall pfile_get_file_name(int lvl, char *dst)
{
	int v2; // ecx
	bool v3; // zf
	const char *v4; // eax

	v2 = lvl;
	if ( (unsigned char)gbMaxPlayers > 1u )
	{
		v3 = lvl == 0;
		goto LABEL_10;
	}
	if ( (unsigned int)lvl < 0x11 )
	{
		v4 = "perml%02d";
LABEL_12:
		sprintf(dst, v4, v2);
		return 1;
	}
	if ( (unsigned int)lvl < 0x22 )
	{
		v2 = lvl - 17;
		v4 = "perms%02d";
		goto LABEL_12;
	}
	if ( lvl == 34 )
	{
		v4 = "game";
		goto LABEL_12;
	}
	v3 = lvl == 35;
LABEL_10:
	if ( v3 )
	{
		v4 = "hero";
		goto LABEL_12;
	}
	return 0;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044A356) --------------------------------------------------------
bool __stdcall pfile_delete_save(_uiheroinfo *hero_info)
{
	unsigned int v1; // eax
	char FileName[260]; // [esp+0h] [ebp-104h]

	v1 = pfile_get_save_num_from_name(hero_info->name);
	if ( v1 < 0xA )
	{
		hero_names[32 * v1] = 0;
		pfile_get_save_path(FileName, 260, v1);
		DeleteFileA(FileName);
	}
	return 1;
}

//----- (0044A3A0) --------------------------------------------------------
void __cdecl pfile_read_player_from_save()
{
	int v0; // edi
	void *v1; // esi
	int v2; // eax
	int v3; // eax
	PkPlayerStruct pkplr; // [esp+8h] [ebp-4F4h]

	v0 = pfile_get_save_num_from_name(chr_name_str);
	v1 = pfile_open_save_archive(0, v0);
	if ( !v1 )
		TermMsg("Unable to open archive");
	_LOBYTE(v2) = pfile_read_hero(v1, &pkplr);
	if ( !v2 )
		TermMsg("Unable to load character");
	UnPackPlayer(&pkplr, myplr, 0);
	_LOBYTE(v3) = pfile_archive_contains_game(v1);
	*(_DWORD *)&gbValidSaveFile = v3;
	pfile_SFileCloseArchive(v1);
}

//----- (0044A419) --------------------------------------------------------
void __fastcall pfile_get_temp_level_name(char *dst)
{
	char *v1; // esi

	v1 = dst;
	pfile_get_save_num_from_name(plr[myplr]._pName);
	if ( setlevel )
		sprintf(v1, "temps%02d", (unsigned char)setlvlnum);
	else
		sprintf(v1, "templ%02d", currlevel);
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (0044A463) --------------------------------------------------------
void __fastcall pfile_get_perm_level_name(char *dst)
{
	char *v1; // esi
	int v2; // ebx
	int v3; // eax
	int v4; // eax
	int v5; // edi

	v1 = dst;
	v2 = pfile_get_save_num_from_name(plr[myplr]._pName);
	pfile_get_temp_level_name(v1);
	_LOBYTE(v3) = pfile_open_archive(0, v2);
	if ( !v3 )
		TermMsg("Unable to read to save file archive");
	_LOBYTE(v4) = mpqapi_has_file(v1);
	v5 = v4;
	pfile_flush(1, v2);
	if ( !v5 )
	{
		if ( setlevel )
			sprintf(v1, "perms%02d", (unsigned char)setlvlnum);
		else
			sprintf(v1, "perml%02d", currlevel);
	}
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (0044A4E9) --------------------------------------------------------
void __fastcall pfile_get_game_name(char *dst)
{
	char *v1; // esi

	v1 = dst;
	pfile_get_save_num_from_name(plr[myplr]._pName);
	strcpy(v1, "game");
}

//----- (0044A512) --------------------------------------------------------
void __cdecl pfile_remove_temp_files()
{
	int v0; // eax
	int v1; // esi
	int v2; // eax

	if ( (unsigned char)gbMaxPlayers <= 1u )
	{
		v0 = pfile_get_save_num_from_name(plr[myplr]._pName);
		v1 = v0;
		_LOBYTE(v2) = pfile_open_archive(0, v0);
		if ( !v2 )
			TermMsg("Unable to write to save file archive");
		mpqapi_remove_hash_entries(pfile_get_temp_name);
		pfile_flush(1, v1);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044A563) --------------------------------------------------------
bool __stdcall pfile_get_temp_name(int a1, char *dst)
{
	int v2; // eax
	const char *v3; // ecx

	v2 = a1;
	if ( (unsigned int)a1 < 0x11 )
	{
		v3 = "templ%02d";
LABEL_5:
		sprintf(dst, v3, v2);
		return 1;
	}
	if ( (unsigned int)a1 < 0x22 )
	{
		v2 = a1 - 17;
		v3 = "temps%02d";
		goto LABEL_5;
	}
	return 0;
}

//----- (0044A598) --------------------------------------------------------
void __cdecl pfile_rename_temp_to_perm()
{
	int v0; // eax
	int v1; // edi
	int v2; // eax
	int v3; // esi
	int v4; // eax
	int v5; // eax
	int v6; // eax
	char v7[260]; // [esp+8h] [ebp-208h]
	char v8[260]; // [esp+10Ch] [ebp-104h]

	v0 = pfile_get_save_num_from_name(plr[myplr]._pName);
	v1 = v0;
	_LOBYTE(v2) = pfile_open_archive(0, v0);
	if ( !v2 )
		TermMsg("Unable to write to save file archive");
	v3 = 0;
	while ( 1 )
	{
		_LOBYTE(v6) = pfile_get_temp_name(v3, v7);
		if ( !v6 )
			break;
		GetPermSaveNames(v3++, v8);
		_LOBYTE(v4) = mpqapi_has_file(v7);
		if ( v4 )
		{
			_LOBYTE(v5) = mpqapi_has_file(v8);
			if ( v5 )
				mpqapi_remove_hash_entry(v8);
			mpqapi_rename(v7, v8);
		}
	}
	GetPermSaveNames(v3, v8);
	pfile_flush(1, v1);
}

//----- (0044A644) --------------------------------------------------------
bool __stdcall GetPermSaveNames(int dwIndex, char *szPerm)
{
	int v2; // eax
	const char *v3; // ecx

	v2 = dwIndex;
	if ( (unsigned int)dwIndex < 0x11 )
	{
		v3 = "perml%02d";
LABEL_5:
		sprintf(szPerm, v3, v2);
		return 1;
	}
	if ( (unsigned int)dwIndex < 0x22 )
	{
		v2 = dwIndex - 17;
		v3 = "perms%02d";
		goto LABEL_5;
	}
	return 0;
}

//----- (0044A679) --------------------------------------------------------
void __fastcall pfile_write_save_file(char *pszName, void *pbData, int dwLen, int qwLen)
{
	void *v4; // ebx
	int v5; // eax
	int v6; // eax
	char file_name[260]; // [esp+Ch] [ebp-118h]
	char password[16]; // [esp+110h] [ebp-14h]
	int v9; // [esp+120h] [ebp-4h]

	v4 = pbData;
	pfile_strcpy(file_name, pszName);
	v5 = pfile_get_save_num_from_name(plr[myplr]._pName);
	strcpy(password, "xrgyrkj1");
	v9 = v5;
	*(_DWORD *)&password[9] = 0;
	*(_WORD *)&password[13] = 0;
	password[15] = 0;
	if ( (unsigned char)gbMaxPlayers > 1u )
		strcpy(password, "szqnlsk1");
	codec_encode(v4, dwLen, qwLen, password);
	_LOBYTE(v6) = pfile_open_archive(0, v9);
	if ( !v6 )
		TermMsg("Unable to write to save file archive");
	mpqapi_write_file(file_name, (char *)v4, qwLen);
	pfile_flush(1, v9);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044A727) --------------------------------------------------------
void __fastcall pfile_strcpy(char *dst, char *src)
{
	strcpy(dst, src);
}

//----- (0044A731) --------------------------------------------------------
char *__fastcall pfile_read(char *pszName, int *pdwLen)
{
	int *v2; // ebx
	int v3; // eax
	void *v4; // edi
	int v5; // eax
	int v6; // eax
	void *v7; // eax
	int v8; // eax
	char *v9; // esi
	int v10; // eax
	int v11; // eax
	char v13[260]; // [esp+Ch] [ebp-124h]
	char password[16]; // [esp+110h] [ebp-20h]
	void *src_dst; // [esp+120h] [ebp-10h]
	int nread; // [esp+124h] [ebp-Ch]
	DWORD nSize; // [esp+128h] [ebp-8h]
	void *file; // [esp+12Ch] [ebp-4h]

	v2 = pdwLen;
	pfile_strcpy(v13, pszName);
	v3 = pfile_get_save_num_from_name(plr[myplr]._pName);
	v4 = pfile_open_save_archive(0, v3);
	if ( !v4 )
		TermMsg("Unable to open save file archive");
	_LOBYTE(v5) = SFileOpenFileEx(v4, v13, 0, &file);
	if ( !v5 )
		TermMsg("Unable to open save file");
	v6 = SFileGetFileSize((int *)file, 0);
	*v2 = v6;
	if ( !v6 )
		TermMsg("Invalid save file");
	v7 = DiabloAllocPtr(*v2);
	src_dst = v7;
	_LOBYTE(v8) = SFileReadFile(file, (char *)v7, *v2, (unsigned long *)&nread, 0);
	if ( !v8 )
		TermMsg("Unable to read save file");
	SFileCloseFile(file);
	pfile_SFileCloseArchive(v4);
	strcpy(password, "xrgyrkj1");
	nSize = 16;
	*(_DWORD *)&password[9] = 0;
	*(_WORD *)&password[13] = 0;
	password[15] = 0;
	if ( (unsigned char)gbMaxPlayers > 1u )
		strcpy(password, "szqnlsk1");
	v9 = (char *)src_dst;
	v10 = codec_decode(src_dst, *v2, password);
	*v2 = v10;
	if ( !v10 )
	{
		if ( (unsigned char)gbMaxPlayers > 1u )
		{
			GetComputerNameA(password, &nSize);
			if ( SFileSetFilePointer((int)file, 0, 0, 0) )
				TermMsg("Unable to read save file");
			_LOBYTE(v11) = SFileReadFile(file, v9, *v2, (unsigned long *)&nread, 0);
			if ( !v11 )
				TermMsg("Unable to read save file");
			*v2 = codec_decode(v9, *v2, password);
		}
		if ( !*v2 )
			TermMsg("Invalid save file");
	}
	return v9;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044A8B3) --------------------------------------------------------
void __fastcall pfile_update(bool force_save)
{
	BOOL v1; // esi
	DWORD v2; // eax

	v1 = force_save;
	if ( gbMaxPlayers != 1 )
	{
		v2 = GetTickCount();
		if ( v1 || (signed int)(v2 - save_prev_tc) > 60000 )
		{
			save_prev_tc = v2;
			pfile_write_hero();
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;
// 686428: using guessed type int save_prev_tc;

//----- (0044A8EB) --------------------------------------------------------
void __cdecl player_cpp_init()
{
	player_cpp_init_value = player_inf;
}
// 47F204: using guessed type int player_inf;
// 68643C: using guessed type int player_cpp_init_value;

//----- (0044A8F6) --------------------------------------------------------
void __fastcall player_copy_frames(char *src, char *dst)
{
	char *v2; // eax
	int v3; // esi
	signed int v4; // edx

	v2 = dst;
	v3 = src - dst;
	v4 = 8;
	do
	{
		*(_DWORD *)v2 = (unsigned int)&src[*(_DWORD *)&v2[v3]];
		v2 += 4;
		--v4;
	}
	while ( v4 );
}

//----- (0044A911) --------------------------------------------------------
void __fastcall LoadPlrGFX(int pnum, int a2)
{
	int v2; // esi
	PlayerStruct *v3; // esi
	unsigned int v4; // ecx
	char v5; // al
	void *v6; // edi
	char *v7; // ebx
	int v8; // ecx
	int v9; // ecx
	int v10; // ecx
	int v11; // ecx
	int v12; // ecx
	int v13; // ecx
	char arglist[256]; // [esp+Ch] [ebp-120h]
	char v15[16]; // [esp+10Ch] [ebp-20h]
	int v16; // [esp+11Ch] [ebp-10h]
	char *v17; // [esp+120h] [ebp-Ch]
	unsigned int v18; // [esp+124h] [ebp-8h]
	const char *v19; // [esp+128h] [ebp-4h]

	v2 = pnum;
	v16 = a2;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("LoadPlrGFX: illegal player %d", pnum);
	v3 = &plr[v2];
	sprintf(
		v15,
		"%c%c%c",
		(char)CharChar[SLOBYTE(v3->_pClass)],
		(char)ArmourChar[v3->_pgfxnum >> 4],
		(char)WepChar[v3->_pgfxnum & 0xF]);
	v4 = 1;
	v17 = ClassNameTbl[SLOBYTE(v3->_pClass)];
	v5 = leveltype;
	v6 = v17;
	v7 = v17;
	v18 = 1;
	do
	{
		if ( !(v4 & v16) )
			goto LABEL_38;
		if ( v4 <= 0x10 )
		{
			if ( v4 == 16 )
			{
				if ( !v5 )
					goto LABEL_38;
				v6 = v3->pLFrame;
				v19 = "LM";
				v7 = (char *)v3->_peqS2_LM;
			}
			else
			{
				v8 = v4 - 1;
				if ( v8 )
				{
					v9 = v8 - 1;
					if ( v9 )
					{
						v10 = v9 - 2;
						if ( v10 )
						{
							if ( v10 == 4 )
							{
								if ( !v5 )
									goto LABEL_38;
								v6 = v3->pHFrame;
								v19 = "HT";
								v7 = (char *)v3->_peqH;
							}
							else
							{
LABEL_27:
								TermMsg("PLR:2");
							}
						}
						else
						{
							if ( !v5 )
								goto LABEL_38;
							v6 = v3->pAFrame;
							v19 = "AT";
							v7 = (char *)v3->_peqA;
						}
					}
					else
					{
						v19 = "AW";
						if ( !v5 )
							v19 = "WL";
						v6 = v3->pWFrame;
						v7 = (char *)v3->_peqW;
					}
				}
				else
				{
					v19 = "AS";
					if ( !v5 )
						v19 = "ST";
					v6 = v3->pSFrame;
					v7 = (char *)v3->_peqN;
				}
			}
LABEL_37:
			sprintf(arglist, "PlrGFX\\%s\\%s\\%s%s.CL2", v17, v15, v15, v19);
			LoadFileWithMem(arglist, v6);
			player_copy_frames((char *)v6, v7);
			v3->_pGFXLoad |= v18;
			v5 = leveltype;
			goto LABEL_38;
		}
		v11 = v4 - 32;
		if ( !v11 )
		{
			if ( !v5 )
				goto LABEL_38;
			v6 = v3->pFFrame;
			v19 = "FM";
			v7 = (char *)v3->_peqS1_FM;
			goto LABEL_37;
		}
		v12 = v11 - 32;
		if ( !v12 )
		{
			if ( !v5 )
				goto LABEL_38;
			v6 = v3->pQFrame;
			v19 = "QM";
			v7 = (char *)v3->_peqS3_QM;
			goto LABEL_37;
		}
		v13 = v12 - 64;
		if ( !v13 )
		{
			if ( v3->_pgfxnum & 0xF )
				goto LABEL_38;
			v6 = v3->pDFrame;
			v19 = "DT";
			v7 = (char *)v3->_peqD;
			goto LABEL_37;
		}
		if ( v13 != 128 )
			goto LABEL_27;
		if ( v5 && v3->_pBlockFlag )
		{
			v6 = v3->pBFrame;
			v19 = "BL";
			v7 = (char *)v3->_peqB;
			goto LABEL_37;
		}
LABEL_38:
		v4 = 2 * v18;
		v18 *= 2;
	}
	while ( v18 <= 0x17F );
}
// 5BB1ED: using guessed type char leveltype;

//----- (0044AB70) --------------------------------------------------------
void __fastcall InitPlayerGFX(int pnum)
{
	int v1; // esi
	int v2; // edx

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("InitPlayerGFX: illegal player %d", pnum);
	if ( plr[v1]._pHitPoints & 0xFFFFFFC0 )
	{
		v2 = 383;
	}
	else
	{
		plr[v1]._pgfxnum = 0;
		v2 = 128;
	}
	LoadPlrGFX(v1, v2);
}

//----- (0044ABB4) --------------------------------------------------------
void __fastcall InitPlrGFXMem(int pnum)
{
	int v1; // esi
	unsigned int v2; // ebp
	unsigned int v3; // eax
	char *v4; // ecx
	int v5; // esi
	void *v6; // eax
	bool v7; // zf
	unsigned int v8; // ebx
	unsigned int v9; // eax
	char *v10; // ecx
	void *v11; // eax
	void *v12; // eax
	void *v13; // eax
	void *v14; // eax
	void *v15; // eax
	void *v16; // eax
	void *v17; // eax
	void *v18; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("InitPlrGFXMem: illegal player %d", pnum);
	if ( !(plr_gfx_flag & 1) )
	{
		plr_gfx_flag |= 1u;
		v2 = GetPlrGFXSize("ST");
		v3 = GetPlrGFXSize("AS");
		v4 = "AS";
		if ( v3 <= v2 )
			v4 = "ST";
		plr_sframe_size = GetPlrGFXSize(v4);
	}
	v5 = v1;
	v6 = DiabloAllocPtr(plr_sframe_size);
	v7 = (plr_gfx_flag & 2) == 0;
	plr[v5].pSFrame = v6;
	if ( v7 )
	{
		plr_gfx_flag |= 2u;
		v8 = GetPlrGFXSize("WL");
		v9 = GetPlrGFXSize("AW");
		v10 = "AW";
		if ( v9 <= v8 )
			v10 = "WL";
		plr_wframe_size = GetPlrGFXSize(v10);
	}
	v11 = DiabloAllocPtr(plr_wframe_size);
	v7 = (plr_gfx_flag & 4) == 0;
	plr[v5].pWFrame = v11;
	if ( v7 )
	{
		plr_gfx_flag |= 4u;
		plr_aframe_size = GetPlrGFXSize("AT");
	}
	v12 = DiabloAllocPtr(plr_aframe_size);
	v7 = (plr_gfx_flag & 8) == 0;
	plr[v5].pAFrame = v12;
	if ( v7 )
	{
		plr_gfx_flag |= 8u;
		plr_hframe_size = GetPlrGFXSize("HT");
	}
	v13 = DiabloAllocPtr(plr_hframe_size);
	v7 = (plr_gfx_flag & 0x10) == 0;
	plr[v5].pHFrame = v13;
	if ( v7 )
	{
		plr_gfx_flag |= 0x10u;
		plr_lframe_size = GetPlrGFXSize("LM");
	}
	v14 = DiabloAllocPtr(plr_lframe_size);
	v7 = (plr_gfx_flag & 0x20) == 0;
	plr[v5].pLFrame = v14;
	if ( v7 )
	{
		plr_gfx_flag |= 0x20u;
		plr_fframe_size = GetPlrGFXSize("FM");
	}
	v15 = DiabloAllocPtr(plr_fframe_size);
	v7 = (plr_gfx_flag & 0x40) == 0;
	plr[v5].pFFrame = v15;
	if ( v7 )
	{
		plr_gfx_flag |= 0x40u;
		plr_qframe_size = GetPlrGFXSize("QM");
	}
	v16 = DiabloAllocPtr(plr_qframe_size);
	v7 = plr_gfx_flag >= 0;
	plr[v5].pQFrame = v16;
	if ( v7 )
	{
		plr_gfx_flag |= 0x80u;
		plr_dframe_size = GetPlrGFXSize("DT");
	}
	v17 = DiabloAllocPtr(plr_dframe_size);
	v7 = (plr_gfx_bflag & 1) == 0;
	plr[v5].pDFrame = v17;
	if ( v7 )
	{
		plr_gfx_bflag |= 1u;
		plr_bframe_size = GetPlrGFXSize("BL");
	}
	v18 = DiabloAllocPtr(plr_bframe_size);
	plr[v5]._pGFXLoad = 0;
	plr[v5].pBFrame = v18;
}
// 686438: using guessed type char plr_gfx_flag;
// 69B7BC: using guessed type char plr_gfx_bflag;

//----- (0044ADC8) --------------------------------------------------------
int __fastcall GetPlrGFXSize(char *szCel)
{
	unsigned int v1; // ebx
	unsigned char *v2; // edi
	unsigned char *v3; // esi
	int dwInitParam[64]; // [esp+Ch] [ebp-124h]
	char v6[16]; // [esp+10Ch] [ebp-24h]
	unsigned int v7; // [esp+11Ch] [ebp-14h]
	char *v8; // [esp+120h] [ebp-10h]
	void *a1; // [esp+124h] [ebp-Ch]
	char **v10; // [esp+128h] [ebp-8h]
	unsigned int v11; // [esp+12Ch] [ebp-4h]

	v1 = 0;
	v8 = szCel;
	v11 = 0;
	v10 = ClassNameTbl;
	do
	{
		v2 = ArmourChar;
		do
		{
			v3 = WepChar;
			do
			{
				sprintf(v6, "%c%c%c", (char)CharChar[v1], (char)*v2, (char)*v3);
				sprintf((char *)dwInitParam, "PlrGFX\\%s\\%s\\%s%s.CL2", *v10, v6, v6, v8);
				if ( wave_open_file((LPARAM)dwInitParam, (DIABFILE *)&a1, 1) )
				{
					v7 = wave_get_file_size((int *)a1, 0);
					wave_close_file(a1);
					if ( v11 <= v7 )
						v11 = v7;
				}
				++v3;
			}
			while ( *v3 );
			++v2;
		}
		while ( *v2 );
		++v10;
		++v1;
	}
	while ( v1 < 3 );
	return v11;
}

//----- (0044AE89) --------------------------------------------------------
void __fastcall FreePlayerGFX(int pnum)
{
	int v1; // esi
	int v2; // esi
	void *v3; // ecx
	void *v4; // ecx
	void *v5; // ecx
	void *v6; // ecx
	void *v7; // ecx
	void *v8; // ecx
	void *v9; // ecx
	void *v10; // ecx
	void *v11; // ecx

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("FreePlayerGFX: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v2].pSFrame;
	plr[v2].pSFrame = 0;
	mem_free_dbg(v3);
	v4 = plr[v2].pWFrame;
	plr[v2].pWFrame = 0;
	mem_free_dbg(v4);
	v5 = plr[v2].pAFrame;
	plr[v2].pAFrame = 0;
	mem_free_dbg(v5);
	v6 = plr[v2].pHFrame;
	plr[v2].pHFrame = 0;
	mem_free_dbg(v6);
	v7 = plr[v2].pLFrame;
	plr[v2].pLFrame = 0;
	mem_free_dbg(v7);
	v8 = plr[v2].pFFrame;
	plr[v2].pFFrame = 0;
	mem_free_dbg(v8);
	v9 = plr[v2].pQFrame;
	plr[v2].pQFrame = 0;
	mem_free_dbg(v9);
	v10 = plr[v2].pDFrame;
	plr[v2].pDFrame = 0;
	mem_free_dbg(v10);
	v11 = plr[v2].pBFrame;
	plr[v2].pBFrame = 0;
	mem_free_dbg(v11);
	plr[v2]._pGFXLoad = 0;
}

//----- (0044AF37) --------------------------------------------------------
void __fastcall NewPlrAnim(int pnum, int Peq, int numFrames, int Delay)
{
	int v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // [esp+14h] [ebp+Ch]

	v4 = pnum;
	v5 = Peq;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("NewPlrAnim: illegal player %d", pnum);
	v6 = v4;
	plr[v6]._pAnimLen = numFrames;
	plr[v6]._pAnimCnt = 0;
	plr[v6]._pAnimDelay = Delay;
	plr[v6]._pAnimData = v5;
	plr[v6]._pAnimWidth = v7;
	plr[v6]._pAnimFrame = 1;
	plr[v6]._pAnimWidth2 = (v7 - 64) >> 1;
}

//----- (0044AF9C) --------------------------------------------------------
void __fastcall ClearPlrPVars(int pnum)
{
	int v1; // esi
	int v2; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("ClearPlrPVars: illegal player %d", pnum);
	v2 = v1;
	plr[v2]._pVar1 = 0;
	plr[v2]._pVar2 = 0;
	plr[v2]._pVar3 = 0;
	plr[v2]._pVar4 = 0;
	plr[v2]._pVar5 = 0;
	plr[v2]._pVar6 = 0;
	plr[v2]._pVar7 = 0;
	plr[v2]._pVar8 = 0;
}

//----- (0044AFED) --------------------------------------------------------
void __fastcall SetPlrAnims(int pnum)
{
	int v1; // esi
	char v2; // bl
	int v3; // eax
	int v4; // esi
	int v5; // ecx
	bool v6; // zf
	int v7; // ecx

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SetPlrAnims: illegal player %d", pnum);
	v2 = leveltype;
	v3 = v1;
	v4 = SLOBYTE(plr[v1]._pClass);
	v5 = v4;
	v6 = leveltype == 0;
	plr[v3]._pNFNum = 96;
	plr[v3]._pWFNum = 96;
	plr[v3].frame_9_unk = 128;
	plr[v3]._pHFNum = 96;
	plr[v3].frame_A_unk = 96;
	plr[v3]._pDFNum = 128;
	plr[v3]._pBFNum = 96;
	if ( v6 )
	{
		plr[v3]._pNFrames = (char)PlrGFXAnimLens[v5].TNFrame;
		plr[v3]._pWFrames = (char)PlrGFXAnimLens[v5].TWFrame;
		plr[v3]._pDFrames = (char)PlrGFXAnimLens[v5].DFrame;
		plr[v3]._pSFrames = (char)PlrGFXAnimLens[v5].SFrame;
	}
	else
	{
		plr[v3]._pNFrames = (char)PlrGFXAnimLens[v5].NFrame;
		plr[v3]._pWFrames = (char)PlrGFXAnimLens[v5].WFrame;
		plr[v3]._pAFrames = (char)PlrGFXAnimLens[v5].AFrame;
		plr[v3]._pHFrames = (char)PlrGFXAnimLens[v5].HFrame;
		plr[v3]._pSFrames = (char)PlrGFXAnimLens[v5].SFrame;
		plr[v3]._pDFrames = (char)PlrGFXAnimLens[v5].DFrame;
		plr[v3]._pBFrames = (char)PlrGFXAnimLens[v5].BFrame;
		plr[v3]._pAFNum = (char)PlrGFXAnimLens[v5].A2Frame;
	}
	plr[v3]._pSFNum = (char)PlrGFXAnimLens[v5].A3Frame;
	v7 = plr[v3]._pgfxnum & 0xF;
	if ( !v4 )
	{
		if ( v7 == 4 )
		{
			if ( v2 )
				plr[v3]._pNFrames = 8;
			plr[v3].frame_9_unk = 96;
			goto LABEL_11;
		}
		if ( v7 == 5 )
		{
			plr[v3]._pAFrames = 20;
			plr[v3]._pAFNum = 10;
			return;
		}
LABEL_19:
		if ( v7 == 8 )
		{
			plr[v3]._pAFrames = 16;
LABEL_11:
			plr[v3]._pAFNum = 11;
			return;
		}
		return;
	}
	if ( v4 == 1 )
	{
		if ( v7 == 5 )
		{
			plr[v3]._pAFrames = 22;
			plr[v3]._pAFNum = 13;
			return;
		}
		if ( v7 == 4 )
		{
			plr[v3]._pAFrames = 12;
			plr[v3]._pAFNum = 7;
			return;
		}
		goto LABEL_19;
	}
	if ( v4 != 2 )
		return;
	plr[v3].frame_A_unk = 128;
	switch ( v7 )
	{
		case 0:
			plr[v3]._pAFrames = 20;
			return;
		case 1:
			plr[v3]._pAFNum = 9;
			return;
		case 4:
			plr[v3]._pAFrames = 20;
			break;
		case 5:
			plr[v3]._pAFrames = 24;
			break;
		default:
			return;
	}
	plr[v3]._pAFNum = 16;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0044B1FD) --------------------------------------------------------
void __fastcall ClearPlrRVars(PlayerStruct *pPlayer)
{
	pPlayer->bReserved[0] = 0;
	pPlayer->bReserved[1] = 0;
	pPlayer->bReserved[2] = 0;
	pPlayer->wReserved[0] = 0;
	pPlayer->wReserved[1] = 0;
	pPlayer->wReserved[2] = 0;
	pPlayer->wReserved[3] = 0;
	pPlayer->wReserved[4] = 0;
	pPlayer->wReserved[5] = 0;
	pPlayer->wReserved[6] = 0;
	pPlayer->wReserved[7] = 0;
	pPlayer->dwReserved[0] = 0;
	pPlayer->dwReserved[1] = 0;
	pPlayer->dwReserved[2] = 0;
	pPlayer->dwReserved[3] = 0;
	pPlayer->dwReserved[4] = 0;
	pPlayer->dwReserved[5] = 0;
	pPlayer->dwReserved[6] = 0;
}

//----- (0044B274) --------------------------------------------------------
void __fastcall CreatePlayer(int pnum, char c)
{
	unsigned int v2; // edi
	char v3; // bl
	int v4; // esi
	int v5; // eax
	int v6; // ecx
	char v7; // al
	char v8; // al
	char v9; // al
	char v10; // al
	int v11; // edi
	signed int v12; // ebp
	int v13; // eax
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // eax
	bool v18; // zf
	char v19; // [esp+Ch] [ebp-8h]
	int arglist; // [esp+10h] [ebp-4h]

	v2 = pnum;
	v3 = c;
	v4 = pnum;
	v19 = c;
	arglist = pnum;
	ClearPlrRVars(&plr[pnum]);
	v5 = GetTickCount();
	SetRndSeed(v5);
	if ( v2 >= 4 )
		TermMsg("CreatePlayer: illegal player %d", v2);
	v6 = v3;
	_LOBYTE(plr[v4]._pClass) = v3;
	v7 = StrengthTbl[v6];
	if ( v7 < 0 )
		v7 = 0;
	plr[v4]._pStrength = v7;
	plr[v4]._pBaseStr = v7;
	v8 = MagicTbl[v6];
	if ( v8 < 0 )
		v8 = 0;
	plr[v4]._pMagic = v8;
	plr[v4]._pBaseMag = v8;
	v9 = DexterityTbl[v6];
	if ( v9 < 0 )
		v9 = 0;
	plr[v4]._pDexterity = v9;
	plr[v4]._pBaseDex = v9;
	v10 = VitalityTbl[v6];
	if ( v10 < 0 )
		v10 = 0;
	v11 = v10;
	plr[v4]._pVitality = v10;
	plr[v4]._pBaseVit = v10;
	plr[v4]._pStatPts = 0;
	plr[v4].pTownWarps = 0;
	plr[v4].pDungMsgs = 0;
	plr[v4].pLvlLoad = 0;
	plr[v4].pDiabloKillLevel = 0;
	if ( v19 == 1 )
	{
		v12 = 200;
		v13 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity);
	}
	else
	{
		v13 = plr[v4]._pStrength * plr[v4]._pLevel;
		v12 = 100;
	}
	plr[v4]._pDamageMod = v13 / v12;
	plr[v4]._pBaseToBlk = ToBlkTbl[v6];
	plr[v4]._pHitPoints = (v11 + 10) << 6;
	if ( !v19 )
		plr[v4]._pHitPoints = (v11 + 10) << 7;
	if ( v19 == 1 )
		plr[v4]._pHitPoints += plr[v4]._pHitPoints >> 1;
	v14 = plr[v4]._pHitPoints;
	plr[v4]._pMaxHP = v14;
	plr[v4]._pHPBase = v14;
	plr[v4]._pMaxHPBase = v14;
	v15 = plr[v4]._pMagic << 6;
	plr[v4]._pMana = v15;
	if ( v19 == 2 )
		plr[v4]._pMana = 2 * v15;
	if ( v19 == 1 )
		plr[v4]._pMana += plr[v4]._pMana >> 1;
	v16 = plr[v4]._pMana;
	plr[v4]._pMaxMana = v16;
	plr[v4]._pManaBase = v16;
	plr[v4]._pMaxManaBase = v16;
	v17 = ExpLvlsTbl[1];
	plr[v4]._pLevel = 1;
	plr[v4]._pMaxLvl = 1;
	plr[v4]._pExperience = 0;
	plr[v4]._pMaxExp = 0;
	plr[v4]._pNextExper = v17;
	plr[v4]._pArmorClass = 0;
	plr[v4]._pMagResist = 0;
	plr[v4]._pFireResist = 0;
	plr[v4]._pLghtResist = 0;
	plr[v4]._pLightRad = 10;
	plr[v4]._pInfraFlag = 0;
	if ( !v19 )
	{
		plr[v4]._pAblSpells[0] = 0x2000000;
LABEL_26:
		plr[v4]._pAblSpells[1] = 0;
LABEL_27:
		plr[v4]._pMemSpells[0] = 0;
		goto LABEL_28;
	}
	if ( v19 == 1 )
	{
		plr[v4]._pAblSpells[0] = 0x8000000;
		goto LABEL_26;
	}
	if ( v19 != 2 )
		goto LABEL_27;
	plr[v4]._pAblSpells[0] = 0x4000000;
	plr[v4]._pAblSpells[1] = 0;
	plr[v4]._pMemSpells[0] = 1;
LABEL_28:
	plr[v4]._pMemSpells[1] = 0;
	memset(plr[v4]._pSplLvl, 0, sizeof(plr[v4]._pSplLvl));
	v18 = _LOBYTE(plr[v4]._pClass) == 2;
	_LOBYTE(plr[v4]._pSpellFlags) = 0;
	if ( v18 )
		plr[v4]._pSplLvl[1] = 2;
	plr[v4]._pSplHotKey[0] = -1;
	plr[v4]._pSplHotKey[1] = -1;
	plr[v4]._pSplHotKey[2] = -1;
	if ( v19 )
	{
		if ( v19 == 1 )
		{
			plr[v4]._pgfxnum = 4;
		}
		else if ( v19 == 2 )
		{
			plr[v4]._pgfxnum = 8;
		}
	}
	else
	{
		plr[v4]._pgfxnum = 3;
	}
	*(_DWORD *)plr[v4]._pLvlVisited = 0;
	*(_DWORD *)&plr[v4]._pLvlVisited[4] = 0;
	*(_DWORD *)&plr[v4]._pLvlVisited[8] = 0;
	*(_DWORD *)&plr[v4]._pLvlVisited[12] = 0;
	plr[v4]._pLvlVisited[16] = 0;
	*(_DWORD *)plr[v4]._pSLvlVisited = 0;
	*(_DWORD *)&plr[v4]._pSLvlVisited[4] = 0;
	*(_WORD *)&plr[v4]._pSLvlVisited[8] = 0;
	plr[v4]._pLvlChanging = 0;
	plr[v4].pTownWarps = 0;
	plr[v4].pLvlLoad = 0;
	plr[v4].pBattleNet = 0;
	plr[v4].pManaShield = 0;
	InitDungMsgs(arglist);
	CreatePlrItems(arglist);
	SetRndSeed(0);
}

//----- (0044B582) --------------------------------------------------------
int __fastcall CalcStatDiff(int pnum)
{
	int v1; // ecx
	int v2; // edx

	v1 = pnum;
	v2 = SLOBYTE(plr[v1]._pClass);
	return MaxStats[v2][0]
		 + MaxStats[v2][1]
		 + MaxStats[v2][2]
		 + MaxStats[v2][3]
		 - plr[v1]._pBaseVit
		 - plr[v1]._pBaseDex
		 - plr[v1]._pBaseMag
		 - plr[v1]._pBaseStr;
}

//----- (0044B5C3) --------------------------------------------------------
void __fastcall NextPlrLevel(int pnum)
{
	int v1; // edi
	int v2; // esi
	char *v3; // eax
	char v4; // bl
	int v5; // eax
	char v6; // bl
	char v7; // al
	signed int v8; // edx
	int v9; // ebp
	signed int v10; // eax
	int v11; // edx

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("NextPlrLevel: illegal player %d", pnum);
	v2 = v1;
	v3 = &plr[v1]._pLevel;
	v4 = ++*v3;
	++plr[v2]._pMaxLvl;
	if ( CalcStatDiff(v1) >= 5 )
		plr[v2]._pStatPts += 5;
	else
		plr[v2]._pStatPts = CalcStatDiff(v1);
	v5 = v4;
	v6 = gbMaxPlayers;
	plr[v2]._pNextExper = ExpLvlsTbl[v5];
	v7 = plr[v2]._pClass;
	v8 = v7 != 2 ? 128 : 64;
	if ( v6 == 1 )
		v8 = v7 != 2 ? 129 : 65;
	v9 = myplr;
	plr[v2]._pMaxHP += v8;
	plr[v2]._pHitPoints = plr[v2]._pMaxHP;
	plr[v2]._pMaxHPBase += v8;
	plr[v2]._pHPBase = plr[v2]._pMaxHPBase;
	if ( v1 == v9 )
		drawhpflag = 1;
	v10 = v7 != 0 ? 128 : 64;
	if ( v6 == 1 )
		++v10;
	plr[v2]._pMaxMana += v10;
	plr[v2]._pMaxManaBase += v10;
	v11 = plr[v2]._pMaxManaBase;
	if ( !(plr[v1]._pIFlags & 0x8000000) )
	{
		plr[v2]._pMana = plr[v2]._pMaxMana;
		plr[v2]._pManaBase = v11;
	}
	if ( v1 == v9 )
		drawmanaflag = 1;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044B6C8) --------------------------------------------------------
void __fastcall AddPlrExperience(int pnum, int lvl, __int32 exp)
{
	int v3; // eax
	int v4; // esi
	int v5; // esi
	char v6; // bl
	int v7; // edi
	signed int v8; // ecx
	int v9; // ecx
	int *v10; // eax
	int v11; // eax
	int v12; // ecx
	int v13; // ecx
	int v14; // esi
	int arglist; // [esp+4h] [ebp-Ch]
	int v16; // [esp+8h] [ebp-8h]

	v3 = myplr;
	v4 = pnum;
	v16 = lvl;
	arglist = pnum;
	if ( pnum == myplr )
	{
		if ( (unsigned int)myplr >= 4 )
		{
			TermMsg("AddPlrExperience: illegal player %d", myplr);
			v3 = myplr;
		}
		if ( plr[v3]._pHitPoints > 0 )
		{
			v5 = v4;
			v6 = plr[v5]._pLevel;
			v7 = (signed __int64)((((double)v16 - (double)v6) * 0.1 + 1.0) * (double)exp);
			if ( v7 < 0 )
				v7 = 0;
			if ( (unsigned char)gbMaxPlayers > 1u )
			{
				if ( v6 >= 0 )
				{
					v8 = v6;
					if ( v6 >= 50 )
						v8 = 50;
				}
				else
				{
					v8 = 0;
				}
				if ( v7 >= ExpLvlsTbl[v8] / 20 )
					v7 = ExpLvlsTbl[v8] / 20;
				v9 = 200 * v8;
				if ( v7 >= v9 )
					v7 = v9;
			}
			v10 = &plr[v5]._pExperience;
			*v10 += v7;
			if ( plr[v5]._pExperience > 2000000000u )
				*v10 = 2000000000;
			v11 = *v10;
			if ( v11 < ExpLvlsTbl[49] )
			{
				v12 = 0;
				if ( v11 >= ExpLvlsTbl[0] )
				{
					do
						++v12;
					while ( v11 >= ExpLvlsTbl[v12] );
				}
				if ( v12 != v6 )
				{
					v13 = v12 - v6;
					if ( v13 > 0 )
					{
						v14 = v13;
						do
						{
							NextPlrLevel(arglist);
							--v14;
						}
						while ( v14 );
					}
				}
				NetSendCmdParam1(0, CMD_PLRLEVEL, plr[myplr]._pLevel);
			}
			else
			{
				plr[v5]._pLevel = 50;
			}
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044B7F8) --------------------------------------------------------
void __fastcall AddPlrMonstExper(int lvl, __int32 exp, char pmask)
{
	int v3; // ebx
	int v4; // edi
	signed int v5; // ecx

	v3 = lvl;
	v4 = 0;
	v5 = 0;
	do
	{
		if ( (1 << v5) & pmask )
			++v4;
		++v5;
	}
	while ( v5 < 4 );
	if ( v4 )
	{
		if ( (1 << myplr) & pmask )
			AddPlrExperience(myplr, v3, exp / v4);
	}
}

//----- (0044B83C) --------------------------------------------------------
void __fastcall InitPlayer(int pnum, bool FirstTime)
{
	int v2; // ebx
	int v3; // esi
	PlayerStruct *v4; // edi
	int v5; // eax
	int v6; // ST08_4
	int v7; // ecx
	int v8; // eax
	int v9; // ecx
	int v10; // ST08_4
	int v11; // edx
	int v12; // eax
	unsigned int v13; // edi
	bool v14; // zf
	int v15; // eax
	int v16; // ecx
	int v17; // edx
	char v18; // al
	int v19; // eax
	BOOL v20; // [esp+8h] [ebp-4h]

	v2 = pnum;
	v20 = FirstTime;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("InitPlayer: illegal player %d", pnum);
	v3 = v2;
	v4 = &plr[v2];
	ClearPlrRVars(&plr[v2]);
	if ( v20 )
	{
		v5 = plr[v3]._pgfxnum;
		plr[v3]._pRSpell = -1;
		plr[v3]._pSBkSpell = -1;
		plr[v3]._pSpell = -1;
		_LOBYTE(plr[v3]._pRSplType) = 4;
		plr[v3]._pSplType = 4;
		plr[v3]._pwtype = (v5 & 0xF) == 4;
		plr[v3].pManaShield = 0;
	}
	if ( plr[v3].plrlevel == currlevel || leveldebug )
	{
		SetPlrAnims(v2);
		plr[v3]._pxoff = 0;
		plr[v3]._pyoff = 0;
		plr[v3]._pxvel = 0;
		plr[v3]._pyvel = 0;
		ClearPlrPVars(v2);
		if ( (signed int)(plr[v3]._pHitPoints & 0xFFFFFFC0) <= 0 )
		{
			v10 = plr[v3]._pDFNum;
			v11 = plr[v3]._peqD[0];
			v4->_pmode = 8;
			NewPlrAnim(v2, v11, plr[v3]._pDFrames, 1);
			v12 = plr[v3]._pAnimLen;
			plr[v3]._pAnimFrame = v12 - 1;
			plr[v3]._pVar8 = 2 * v12;
		}
		else
		{
			v6 = plr[v3]._pNFNum;
			v4->_pmode = 0;
			NewPlrAnim(v2, plr[v3]._peqN[0], plr[v3]._pNFrames, 3);
			_LOBYTE(v7) = 2;
			v8 = random(v7, plr[v3]._pNFrames - 1);
			_LOBYTE(v9) = 2;
			plr[v3]._pAnimFrame = v8 + 1;
			plr[v3]._pAnimCnt = random(v9, 3);
		}
		v13 = 0;
		v14 = v2 == myplr;
		plr[v3]._pdir = 0;
		plr[v3]._peflag = 0;
		if ( v14 )
		{
			if ( !v20 || currlevel )
			{
				plr[v3].WorldX = ViewX;
				plr[v3].WorldY = ViewY;
			}
			plr[v3]._ptargx = plr[v3].WorldX;
			plr[v3]._ptargy = plr[v3].WorldY;
		}
		else
		{
			plr[v3]._ptargx = plr[v3].WorldX;
			plr[v3]._ptargy = plr[v3].WorldY;
			do
			{
				if ( PosOkPlayer(v2, plr[v3].WorldX + plrxoff2[v13], plr[v3].WorldY + plryoff2[v13]) )
					break;
				++v13;
			}
			while ( v13 < 8 );
			v15 = plryoff2[v13];
			plr[v3].WorldX += plrxoff2[v13];
			plr[v3].WorldY += v15;
		}
		v16 = plr[v3].WorldX;
		v17 = plr[v3].WorldY;
		plr[v3].walkpath[0] = -1;
		plr[v3].destAction = -1;
		v14 = v2 == myplr;
		plr[v3]._px = v16;
		plr[v3]._py = v17;
		if ( v14 )
			plr[v3]._plid = AddLight(v16, v17, plr[v3]._pLightRad);
		else
			plr[v3]._plid = -1;
		plr[v3]._pvid = AddVision(plr[v3].WorldX, plr[v3].WorldY, plr[v3]._pLightRad, v2 == myplr);
	}
	v18 = plr[v3]._pClass;
	if ( v18 )
	{
		if ( v18 == 1 )
		{
			plr[v3]._pAblSpells[0] = 0x8000000;
		}
		else
		{
			if ( v18 != 2 )
				goto LABEL_33;
			plr[v3]._pAblSpells[0] = 0x4000000;
		}
	}
	else
	{
		plr[v3]._pAblSpells[0] = 0x2000000;
	}
	plr[v3]._pAblSpells[1] = 0;
LABEL_33:
	v19 = plr[v3]._pLevel;
	plr[v3]._pInvincible = 0;
	v14 = v2 == myplr;
	plr[v3]._pNextExper = ExpLvlsTbl[v19];
	if ( v14 )
	{
		deathdelay = 0;
		*(_DWORD *)&deathflag = 0;
		ScrollInfo._sxoff = 0;
		ScrollInfo._syoff = 0;
		ScrollInfo._sdir = 0;
	}
}
// 44B83C: could not find valid save-restore pair for edi
// 52572C: using guessed type int leveldebug;
// 69B7C4: using guessed type int deathdelay;

//----- (0044BB33) --------------------------------------------------------
void __cdecl InitMultiView()
{
	int v0; // eax

	if ( (unsigned int)myplr >= 4 )
		TermMsg("InitPlayer: illegal player %d", myplr);
	v0 = plr[myplr].WorldY;
	ViewX = plr[myplr].WorldX;
	ViewY = v0;
}

//----- (0044BB6D) --------------------------------------------------------
int __fastcall CheckLeighSolid(int x, int y)
{
	int v2; // esi
	int v3; // esi
	int v4; // edi
	int v5; // ebx
	char *v6; // eax
	int result; // eax
	int v8; // ebx
	int v9; // edi
	char *v10; // eax
	int v11; // edi
	int v12; // ebx
	char *v13; // eax
	int v14; // [esp+Ch] [ebp-Ch]
	int v15; // [esp+10h] [ebp-8h]
	int v16; // [esp+10h] [ebp-8h]
	int v17; // [esp+10h] [ebp-8h]
	signed int v18; // [esp+14h] [ebp-4h]
	signed int v19; // [esp+14h] [ebp-4h]
	signed int v20; // [esp+14h] [ebp-4h]

	v2 = x;
	v14 = y;
	if ( (unsigned int)x >= 4 )
		TermMsg("InitPlayer: illegal player %d", x);
	v3 = v2;
	v15 = 0;
	v4 = plr[v3].WorldX - 1;
	v5 = plr[v3].WorldY + 1;
	v6 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(v4, v5);
	v18 = 2;
	do
		v15 |= *(unsigned short *)&v6[2 * v18++];
	while ( v18 < 10 );
	result = 1;
	if ( v15 | dArch[v4][v5] | (unsigned char)nSolidTable[dPiece[0][v5 + 112 * v4]] )
		plr[v3]._peflag = 1;
	else
		plr[v3]._peflag = 0;
	if ( v14 == 1 && plr[v3]._peflag == 1 )
	{
		v8 = plr[v3].WorldX;
		v16 = 0;
		v9 = plr[v3].WorldY + 2;
		v10 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(plr[v3].WorldX, v9);
		v19 = 2;
		do
			v16 |= *(unsigned short *)&v10[2 * v19++];
		while ( v19 < 10 );
		result = v16 | dArch[v8][v9];
		if ( !result )
		{
			v17 = 0;
			v11 = plr[v3].WorldX - 2;
			v12 = plr[v3].WorldY + 1;
			v13 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(v11, v12);
			v20 = 2;
			do
				v17 |= *(unsigned short *)&v13[2 * v20++];
			while ( v20 < 10 );
			result = v17 | dArch[v11][v12];
			if ( result )
				plr[v3]._peflag = 2;
		}
	}
	return result;
}

//----- (0044BCC2) --------------------------------------------------------
int __fastcall SolidLoc(int x, int y)
{
	int result; // eax

	if ( x < 0 || y < 0 || x >= 112 || y >= 112 )
		result = 0;
	else
		result = (unsigned char)nSolidTable[dPiece[0][y + 112 * x]];
	return result;
}

//----- (0044BCEB) --------------------------------------------------------
int __fastcall PlrDirOK(int pnum, int dir)
{
	int v2; // esi
	int v3; // ebx
	int v4; // eax
	int v5; // esi
	int v6; // edi
	int v7; // ebp
	int result; // eax
	bool v9; // zf
	int p; // [esp+10h] [ebp-4h]

	v2 = pnum;
	v3 = dir;
	p = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PlrDirOK: illegal player %d", pnum);
	v4 = v2;
	v5 = plr[v2].WorldX + offset_x[v3];
	v6 = plr[v4].WorldY + offset_y[v3];
	if ( v5 < 0 )
		return 0;
	v7 = 112 * v5 + v6;
	if ( !dPiece[0][v7] || !PosOkPlayer(p, v5, v6) )
		return 0;
	result = 1;
	if ( v3 == 6 )
	{
		if ( SolidLoc(v5, v6 + 1) )
			return 0;
		v9 = (dFlags[0][v7 + 1] & 0x20) == 0;
	}
	else
	{
		if ( v3 != 2 )
			return result;
		if ( SolidLoc(v5 + 1, v6) )
			return 0;
		v9 = (dFlags[1][v7] & 0x20) == 0;
	}
	if ( v9 )
		return 1;
	return 0;
}

//----- (0044BD9A) --------------------------------------------------------
void __fastcall PlrClrTrans(int x, int y)
{
	int v2; // esi
	int v3; // ebx
	int v4; // edx
	int v5; // edi
	char *v6; // ecx
	int v7; // eax
	int v8; // ebp

	v2 = y - 1;
	v3 = y + 1;
	if ( (unsigned char)(__OFSUB__(y - 1, y + 1) ^ 1) | (y - 1 == y + 1) )
	{
		v4 = x - 1;
		v5 = x + 1;
		do
		{
			if ( v4 <= v5 )
			{
				v6 = &dung_map[v4][v2];
				v7 = v5 - v4 + 1;
				do
				{
					v8 = *v6;
					v6 += 112;
					TransList[v8] = 0;
					--v7;
				}
				while ( v7 );
			}
			++v2;
		}
		while ( v2 <= v3 );
	}
}

//----- (0044BDDD) --------------------------------------------------------
void __fastcall PlrDoTrans(int x, int y)
{
	int v2; // edi
	int v3; // ebx
	int v4; // eax
	_BYTE *v5; // ecx
	_DWORD *v6; // esi
	int v7; // eax
	int v8; // [esp+8h] [ebp-4h]

	if ( leveltype == 1 || leveltype == 2 )
	{
		v2 = y - 1;
		if ( y - 1 <= y + 1 )
		{
			v3 = x - 1;
			v8 = x + 1;
			do
			{
				if ( v3 <= v8 )
				{
					v4 = v2 + 112 * v3;
					v5 = (unsigned char *)dung_map + v4;
					v6 = (_DWORD *)((char *)dPiece + 4 * v4);
					v7 = v8 - v3 + 1;
					do
					{
						if ( !nSolidTable[*v6] )
						{
							if ( *v5 )
								TransList[(char)*v5] = 1;
						}
						v6 += 112;
						v5 += 112;
						--v7;
					}
					while ( v7 );
				}
				++v2;
			}
			while ( v2 <= y + 1 );
		}
	}
	else
	{
		TransList[1] = 1;
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (0044BE5E) --------------------------------------------------------
void __fastcall SetPlayerOld(int pnum)
{
	int v1; // esi
	int v2; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SetPlayerOld: illegal player %d", pnum);
	v2 = v1;
	plr[v2]._poldx = plr[v1].WorldX;
	plr[v2]._poldy = plr[v1].WorldY;
}

//----- (0044BE95) --------------------------------------------------------
void __fastcall FixPlayerLocation(int pnum, int a2)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // ecx
	int v6; // eax
	bool v7; // zf
	int v8; // eax
	int v9; // eax

	v2 = pnum;
	v3 = a2;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("FixPlayerLocation: illegal player %d", pnum);
	v4 = v2;
	v5 = plr[v2].WorldY;
	v6 = plr[v2].WorldX;
	plr[v4]._py = v5;
	plr[v4]._ptargy = v5;
	plr[v4]._px = v6;
	plr[v4]._ptargx = v6;
	plr[v4]._pxoff = 0;
	plr[v4]._pyoff = 0;
	CheckLeighSolid(v2, 0);
	v7 = v2 == myplr;
	plr[v4]._pdir = v3;
	if ( v7 )
	{
		v8 = plr[v4].WorldX;
		ScrollInfo._sxoff = 0;
		ViewX = v8;
		v9 = plr[v4].WorldY;
		ScrollInfo._syoff = 0;
		ScrollInfo._sdir = 0;
		ViewY = v9;
	}
}

//----- (0044BF2D) --------------------------------------------------------
void __fastcall StartStand(int pnum, int dir)
{
	int v2; // ebx
	int v3; // edi
	int v4; // esi
	int v5; // ST08_4

	v2 = pnum;
	v3 = dir;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartStand: illegal player %d", pnum);
	v4 = v2;
	if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr )
	{
		if ( !(plr[v4]._pGFXLoad & 1) )
			LoadPlrGFX(v2, 1);
		v5 = plr[v4]._pNFNum;
		NewPlrAnim(v2, plr[0]._peqN[v3 + 5430 * v2], plr[v4]._pNFrames, 3);
		plr[v4]._pmode = PM_STAND;
		FixPlayerLocation(v2, v3);
		FixPlrWalkTags(v2);
		dPlayer[plr[v4].WorldX][plr[v4].WorldY] = v2 + 1;
		SetPlayerOld(v2);
	}
	else
	{
		SyncPlrKill(v2, -1);
	}
}

//----- (0044BFE8) --------------------------------------------------------
void __fastcall StartWalkStand(int pnum)
{
	int v1; // edi
	int v2; // esi
	int v3; // eax
	int v4; // eax
	int v5; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartWalkStand: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1].WorldX;
	plr[v2]._pmode = 0;
	plr[v2]._px = v3;
	plr[v2]._py = plr[v1].WorldY;
	plr[v2]._pxoff = 0;
	plr[v2]._pyoff = 0;
	CheckLeighSolid(v1, 0);
	if ( v1 == myplr )
	{
		v4 = plr[v2].WorldX;
		ScrollInfo._sxoff = 0;
		ViewX = v4;
		v5 = plr[v2].WorldY;
		ScrollInfo._syoff = 0;
		ScrollInfo._sdir = 0;
		ViewY = v5;
	}
}

//----- (0044C070) --------------------------------------------------------
void __fastcall PM_ChangeLightOff(int pnum)
{
	int v1; // esi
	int v2; // esi
	signed int v3; // ebx
	int v4; // edi
	int v5; // edx
	LightListStruct *v6; // eax
	int v7; // ecx
	int v8; // edx
	signed int v9; // edi
	int v10; // ebx
	int v11; // edx
	int v12; // ecx
	int v13; // ebp
	int ly; // [esp+10h] [ebp-Ch]
	int lx; // [esp+18h] [ebp-4h]

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_ChangeLightOff: illegal player %d", pnum);
	v2 = v1;
	v3 = -1;
	v4 = plr[v2]._pxoff;
	v5 = 2 * plr[v2]._pyoff;
	v6 = &LightList[plr[v2]._plid];
	v7 = v4 + v5;
	v8 = v5 - v4;
	if ( v7 >= 0 )
	{
		v9 = 1;
	}
	else
	{
		v9 = -1;
		v7 = -v7;
	}
	if ( v8 >= 0 )
		v3 = 1;
	else
		v8 = -v8;
	v10 = v3 * (v8 >> 3);
	v11 = 8 * v6->_ly;
	ly = v11 + v10;
	lx = v9 * (v7 >> 3);
	v12 = 8 * v6->_lx;
	v13 = v11 + v6->_yoff;
	if ( abs(lx - v6->_xoff) >= 3 || abs(ly - v13) >= 3 )
		ChangeLightOff(plr[v2]._plid, lx, v10);
}

//----- (0044C13D) --------------------------------------------------------
void __fastcall PM_ChangeOffset(int pnum)
{
	int v1; // esi
	int v2; // eax
	int v3; // edi
	int v4; // ebx
	int v5; // ecx
	int *v6; // esi
	int v7; // edi
	int v8; // ebx
	int v9; // edx
	int v10; // edi
	int v11; // edi
	int v12; // edi
	int v13; // ecx
	int v14; // edx
	int arglist; // [esp+8h] [ebp-8h]
	int v16; // [esp+Ch] [ebp-4h]

	v1 = pnum;
	arglist = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_ChangeOffset: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pVar6;
	v4 = plr[v1]._pxvel;
	v5 = v3;
	v6 = &plr[v1]._pVar7;
	v7 = v4 + v3;
	v8 = plr[v2]._pyvel;
	v9 = *v6;
	v16 = v7;
	plr[v2]._pVar6 = v7;
	v10 = *v6;
	++plr[v2]._pVar8;
	v11 = v8 + v10;
	*v6 = v11;
	v12 = v11 >> 8;
	plr[v2]._pxoff = v16 >> 8;
	plr[v2]._pyoff = v12;
	v13 = v5 >> 8;
	v14 = v9 >> 8;
	if ( arglist == myplr && ScrollInfo._sdir )
	{
		ScrollInfo._sxoff += v13 - (v16 >> 8);
		ScrollInfo._syoff += v14 - v12;
	}
	PM_ChangeLightOff(arglist);
}

//----- (0044C1E2) --------------------------------------------------------
void __fastcall StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int sdir)
{
	int v7; // edi
	int v8; // esi
	int v9; // edi
	int v10; // ebx
	int v11; // ecx
	bool v12; // zf
	int v13; // ST08_4
	int v14; // eax
	bool v15; // sf
	unsigned char v16; // of
	int v17; // eax
	int v18; // [esp+Ch] [ebp-8h]
	int arglist; // [esp+10h] [ebp-4h]

	v7 = pnum;
	v18 = xvel;
	arglist = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartWalk: illegal player %d", pnum);
	v8 = v7;
	if ( plr[v7]._pInvincible && !plr[v8]._pHitPoints && v7 == myplr )
	{
		SyncPlrKill(v7, -1);
		return;
	}
	SetPlayerOld(v7);
	v9 = xadd + plr[v8].WorldX;
	v10 = yadd + plr[v8].WorldY;
	if ( PlrDirOK(arglist, EndDir) )
	{
		v11 = arglist;
		plr[v8]._px = v9;
		v12 = arglist == myplr;
		plr[v8]._py = v10;
		if ( v12 )
		{
			ScrollInfo._sdx = plr[v8].WorldX - ViewX;
			ScrollInfo._sdy = plr[v8].WorldY - ViewY;
		}
		plr[v8]._pmode = PM_WALK;
		dPlayer[v9][v10] = -1 - arglist;
		plr[v8]._pxvel = v18;
		v12 = (plr[v8]._pGFXLoad & 2) == 0;
		plr[v8]._pyvel = yvel;
		plr[v8]._pVar1 = xadd;
		plr[v8]._pxoff = 0;
		plr[v8]._pyoff = 0;
		plr[v8]._pVar2 = yadd;
		plr[v8]._pVar3 = EndDir;
		if ( v12 )
		{
			LoadPlrGFX(arglist, 2);
			v11 = arglist;
		}
		v13 = plr[v8]._pWFNum;
		NewPlrAnim(v11, plr[0]._peqW[EndDir + 5430 * v11], plr[v8]._pWFrames, 0);
		plr[v8]._pdir = EndDir;
		plr[v8]._pVar6 = 0;
		plr[v8]._pVar7 = 0;
		plr[v8]._pVar8 = 0;
		CheckLeighSolid(arglist, 0);
		if ( arglist == myplr )
		{
			if ( zoomflag )
			{
				if ( abs(ScrollInfo._sdx) < 3 )
				{
					v14 = abs(ScrollInfo._sdy);
					v16 = __OFSUB__(v14, 3);
					v15 = v14 - 3 < 0;
					goto LABEL_18;
				}
			}
			else if ( abs(ScrollInfo._sdx) < 2 )
			{
				v17 = abs(ScrollInfo._sdy);
				v16 = __OFSUB__(v17, 2);
				v15 = v17 - 2 < 0;
LABEL_18:
				if ( v15 ^ v16 )
				{
					ScrollInfo._sdir = sdir;
					return;
				}
				goto LABEL_20;
			}
LABEL_20:
			ScrollInfo._sdir = 0;
			return;
		}
	}
}
// 52569C: using guessed type int zoomflag;

//----- (0044C3AC) --------------------------------------------------------
void __fastcall StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir)
{
	int v9; // edi
	int v10; // esi
	int v11; // ebx
	int v12; // edi
	bool v13; // zf
	int v14; // eax
	int v15; // ecx
	int v16; // ecx
	int v17; // ecx
	int v18; // ST08_4
	int v19; // edx
	int v20; // eax
	bool v21; // sf
	unsigned char v22; // of
	int v23; // eax
	int v24; // [esp+Ch] [ebp-8h]
	int arglist; // [esp+10h] [ebp-4h]
	int x; // [esp+28h] [ebp+14h]

	v9 = pnum;
	v24 = xvel;
	arglist = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartWalk2: illegal player %d", pnum);
	v10 = v9;
	if ( plr[v9]._pInvincible && !plr[v10]._pHitPoints && v9 == myplr )
	{
		SyncPlrKill(v9, -1);
		return;
	}
	SetPlayerOld(v9);
	v11 = xadd + plr[v10].WorldX;
	v12 = yadd + plr[v10].WorldY;
	x = xadd + plr[v10].WorldX;
	if ( PlrDirOK(arglist, EndDir) )
	{
		plr[v10]._px = v11;
		v13 = arglist == myplr;
		plr[v10]._py = v12;
		if ( v13 )
		{
			ScrollInfo._sdx = plr[v10].WorldX - ViewX;
			ScrollInfo._sdy = plr[v10].WorldY - ViewY;
		}
		v14 = plr[v10].WorldY;
		v15 = plr[v10].WorldX;
		plr[v10]._pVar2 = v14;
		dPlayer[v15][v14] = -1 - arglist;
		v16 = plr[v10].WorldX;
		plr[v10].WorldX = v11;
		dPlayer[v11][v12] = arglist + 1;
		plr[v10]._pVar1 = v16;
		v17 = plr[v10]._plid;
		plr[v10].WorldY = v12;
		plr[v10]._pxoff = xoff;
		plr[v10]._pyoff = yoff;
		ChangeLightXY(v17, x, v12);
		PM_ChangeLightOff(arglist);
		plr[v10]._pxvel = v24;
		plr[v10]._pyvel = yvel;
		plr[v10]._pVar6 = xoff << 8;
		v13 = (plr[v10]._pGFXLoad & 2) == 0;
		plr[v10]._pmode = PM_WALK2;
		plr[v10]._pVar7 = yoff << 8;
		plr[v10]._pVar3 = EndDir;
		if ( v13 )
			LoadPlrGFX(arglist, PM_WALK2);
		v18 = plr[v10]._pWFNum;
		NewPlrAnim(arglist, plr[0]._peqW[EndDir + 5430 * arglist], plr[v10]._pWFrames, 0);
		plr[v10]._pVar8 = 0;
		v19 = 0;
		plr[v10]._pdir = EndDir;
		if ( EndDir == 7 )
			v19 = 1;
		CheckLeighSolid(arglist, v19);
		if ( arglist == myplr )
		{
			if ( zoomflag )
			{
				if ( abs(ScrollInfo._sdx) < 3 )
				{
					v20 = abs(ScrollInfo._sdy);
					v22 = __OFSUB__(v20, 3);
					v21 = v20 - 3 < 0;
					goto LABEL_20;
				}
			}
			else if ( abs(ScrollInfo._sdx) < PM_WALK2 )
			{
				v23 = abs(ScrollInfo._sdy);
				v22 = __OFSUB__(v23, 2);
				v21 = v23 - PM_WALK2 < 0;
LABEL_20:
				if ( v21 ^ v22 )
				{
					ScrollInfo._sdir = sdir;
					return;
				}
				goto LABEL_22;
			}
LABEL_22:
			ScrollInfo._sdir = 0;
			return;
		}
	}
}
// 52569C: using guessed type int zoomflag;

//----- (0044C5CF) --------------------------------------------------------
void __fastcall StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir)
{
	int v11; // edi
	int v12; // esi
	int v13; // eax
	int v14; // ecx
	int v15; // ebx
	int v16; // edi
	bool v17; // zf
	int v18; // edx
	int v19; // ecx
	int v20; // ST08_4
	int v21; // eax
	bool v22; // sf
	unsigned char v23; // of
	int v24; // eax
	int v25; // [esp+10h] [ebp-8h]
	int arglist; // [esp+14h] [ebp-4h]
	int a6; // [esp+2Ch] [ebp+14h]
	int x; // [esp+30h] [ebp+18h]
	int y; // [esp+34h] [ebp+1Ch]

	v11 = pnum;
	v25 = xvel;
	arglist = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartWalk3: illegal player %d", pnum);
	v12 = v11;
	if ( plr[v11]._pInvincible && !plr[v12]._pHitPoints && v11 == myplr )
	{
		SyncPlrKill(v11, -1);
		return;
	}
	SetPlayerOld(v11);
	v13 = plr[v12].WorldX;
	a6 = v13 + xadd;
	v14 = plr[v12].WorldY;
	v15 = v14 + yadd;
	x = mapx + v13;
	v16 = v14 + mapy;
	y = v14 + mapy;
	if ( PlrDirOK(arglist, EndDir) )
	{
		v17 = arglist == myplr;
		plr[v12]._px = a6;
		plr[v12]._py = v15;
		if ( v17 )
		{
			ScrollInfo._sdx = plr[v12].WorldX - ViewX;
			ScrollInfo._sdy = plr[v12].WorldY - ViewY;
		}
		v18 = plr[v12].WorldY;
		v19 = plr[v12].WorldX;
		plr[v12]._pVar5 = v16;
		dPlayer[v19][v18] = -1 - arglist;
		dPlayer[a6][v15] = -1 - arglist;
		plr[v12]._pVar4 = x;
		plr[v12]._pyoff = yoff;
		dFlags[x][v16] |= 0x20u;
		v17 = leveltype == 0;
		plr[v12]._pxoff = xoff;
		if ( !v17 )
		{
			ChangeLightXY(plr[v12]._plid, x, y);
			PM_ChangeLightOff(arglist);
		}
		plr[v12]._pmode = PM_WALK3;
		plr[v12]._pxvel = v25;
		plr[v12]._pyvel = yvel;
		plr[v12]._pVar1 = a6;
		plr[v12]._pVar6 = xoff << 8;
		v17 = (plr[v12]._pGFXLoad & 2) == 0;
		plr[v12]._pVar7 = yoff << 8;
		plr[v12]._pVar2 = v15;
		plr[v12]._pVar3 = EndDir;
		if ( v17 )
			LoadPlrGFX(arglist, 2);
		v20 = plr[v12]._pWFNum;
		NewPlrAnim(arglist, plr[0]._peqW[EndDir + 5430 * arglist], plr[v12]._pWFrames, 0);
		plr[v12]._pdir = EndDir;
		plr[v12]._pVar8 = 0;
		CheckLeighSolid(arglist, 0);
		if ( arglist == myplr )
		{
			if ( zoomflag )
			{
				if ( abs(ScrollInfo._sdx) < 3 )
				{
					v21 = abs(ScrollInfo._sdy);
					v23 = __OFSUB__(v21, 3);
					v22 = v21 - 3 < 0;
					goto LABEL_20;
				}
			}
			else if ( abs(ScrollInfo._sdx) < 2 )
			{
				v24 = abs(ScrollInfo._sdy);
				v23 = __OFSUB__(v24, 2);
				v22 = v24 - 2 < 0;
LABEL_20:
				if ( v22 ^ v23 )
				{
					ScrollInfo._sdir = sdir;
					return;
				}
				goto LABEL_22;
			}
LABEL_22:
			ScrollInfo._sdir = 0;
			return;
		}
	}
}
// 52569C: using guessed type int zoomflag;
// 5BB1ED: using guessed type char leveltype;

//----- (0044C81E) --------------------------------------------------------
void __fastcall StartAttack(int pnum, int d)
{
	int v2; // edi
	int v3; // ebp
	int v4; // esi
	int v5; // ST08_4

	v2 = pnum;
	v3 = d;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartAttack: illegal player %d", pnum);
	v4 = v2;
	if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr )
	{
		if ( !(plr[v4]._pGFXLoad & 4) )
			LoadPlrGFX(v2, 4);
		v5 = plr[v4].frame_9_unk;
		NewPlrAnim(v2, plr[0]._peqA[v3 + 5430 * v2], plr[v4]._pAFrames, 0);
		plr[v4]._pmode = 4;
		FixPlayerLocation(v2, v3);
		SetPlayerOld(v2);
	}
	else
	{
		SyncPlrKill(v2, -1);
	}
}

//----- (0044C8BB) --------------------------------------------------------
void __fastcall StartRangeAttack(int pnum, int a2, int a3, int a4)
{
	int v4; // edi
	int v5; // esi
	int v6; // ST08_4
	int a2a; // [esp+8h] [ebp-4h]

	v4 = pnum;
	a2a = a2;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartRangeAttack: illegal player %d", pnum);
	v5 = v4;
	if ( !plr[v4]._pInvincible || plr[v5]._pHitPoints || v4 != myplr )
	{
		if ( !(plr[v5]._pGFXLoad & 4) )
			LoadPlrGFX(v4, 4);
		v6 = plr[v5].frame_9_unk;
		NewPlrAnim(v4, plr[0]._peqA[a2a + 5430 * v4], plr[v5]._pAFrames, 0);
		plr[v5]._pmode = PM_RATTACK;
		FixPlayerLocation(v4, a2a);
		SetPlayerOld(v4);
		plr[v5]._pVar1 = a3;
		plr[v5]._pVar2 = a4;
	}
	else
	{
		SyncPlrKill(v4, -1);
	}
}

//----- (0044C973) --------------------------------------------------------
void __fastcall StartPlrBlock(int pnum, int dir)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // ST08_4

	v2 = pnum;
	v3 = dir;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartPlrBlock: illegal player %d", pnum);
	v4 = v2;
	if ( !plr[v2]._pInvincible || plr[v4]._pHitPoints || v2 != myplr )
	{
		PlaySfxLoc(IS_ISWORD, plr[v4].WorldX, plr[v4].WorldY);
		if ( !(plr[v4]._pGFXLoad & 0x100) )
			LoadPlrGFX(v2, 256);
		v5 = plr[v4]._pBFNum;
		NewPlrAnim(v2, plr[0]._peqB[v3 + 5430 * v2], plr[v4]._pBFrames, 2);
		plr[v4]._pmode = PM_BLOCK;
		FixPlayerLocation(v2, v3);
		SetPlayerOld(v2);
	}
	else
	{
		SyncPlrKill(v2, -1);
	}
}

//----- (0044CA26) --------------------------------------------------------
void __fastcall StartSpell(int pnum, int d, int cx, int cy)
{
	int v4; // edi
	int v5; // esi
	int v6; // edx
	int v7; // ST08_4
	int v8; // edx
	int a2; // [esp+Ch] [ebp-4h]

	v4 = pnum;
	a2 = d;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartSpell: illegal player %d", pnum);
	v5 = v4;
	if ( plr[v4]._pInvincible && !plr[v5]._pHitPoints && v4 == myplr )
	{
		SyncPlrKill(v4, -1);
		return;
	}
	if ( leveltype )
	{
		switch ( spelldata[plr[v5]._pSpell].sType )
		{
			case STYPE_FIRE:
				if ( !(plr[v5]._pGFXLoad & 0x20) )
					LoadPlrGFX(v4, 32);
				v6 = plr[0]._peqS1_FM[a2 + 5430 * v4];
				goto LABEL_20;
			case STYPE_LIGHTNING:
				if ( !(plr[v5]._pGFXLoad & 0x10) )
					LoadPlrGFX(v4, 16);
				v6 = plr[0]._peqS2_LM[a2 + 5430 * v4];
				goto LABEL_20;
			case STYPE_MAGIC:
				if ( !(plr[v5]._pGFXLoad & 0x40) )
					LoadPlrGFX(v4, 64);
				v6 = plr[0]._peqS3_QM[a2 + 5430 * v4];
LABEL_20:
				v7 = plr[v5].frame_A_unk;
				NewPlrAnim(v4, v6, plr[v5]._pSFrames, 0);
				break;
		}
	}
	PlaySfxLoc((unsigned char)spelldata[plr[v5]._pSpell].sSFX, plr[v5].WorldX, plr[v5].WorldY);
	plr[v5]._pmode = PM_SPELL;
	FixPlayerLocation(v4, a2);
	SetPlayerOld(v4);
	v8 = plr[v5]._pSpell;
	plr[v5]._pVar1 = cx;
	plr[v5]._pVar2 = cy;
	plr[v5]._pVar4 = GetSpellLevel(v4, v8);
	plr[v5]._pVar8 = 1;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0044CB95) --------------------------------------------------------
void __fastcall FixPlrWalkTags(int pnum)
{
	int v1; // esi
	int v2; // edx
	int v3; // ecx
	int v4; // eax
	int v5; // esi
	int v6; // edi
	int v7; // ebx
	int v8; // edi
	bool v9; // zf
	bool v10; // sf
	unsigned char v11; // of
	int v12; // eax
	int v13; // [esp+8h] [ebp-Ch]
	int v14; // [esp+Ch] [ebp-8h]
	char *v15; // [esp+10h] [ebp-4h]

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("FixPlrWalkTags: illegal player %d", pnum);
	v13 = v1 + 1;
	v2 = -1 - v1;
	v3 = plr[v1]._poldx;
	v4 = plr[v1]._poldy;
	v5 = v4 - 1;
	if ( (unsigned char)(__OFSUB__(v4 - 1, v4 + 1) ^ 1) | (v4 - 1 == v4 + 1) )
	{
		v6 = v3 + 1;
		do
		{
			v7 = v3 - 1;
			v14 = v3 - 1;
			if ( v3 - 1 <= v6 )
			{
				v15 = &dPlayer[v7][v5];
				do
				{
					if ( v7 >= 0 && v7 < 112 && v5 >= 0 && v5 < 112 )
					{
						v8 = *v15;
						if ( v8 == v13 || v8 == v2 )
							*v15 = 0;
					}
					v15 += 112;
					v7 = v14 + 1;
					v6 = v3 + 1;
					v11 = __OFSUB__(v14 + 1, v3 + 1);
					v9 = v14 + 1 == v3 + 1;
					v10 = v14++ - v3 < 0;
				}
				while ( (unsigned char)(v10 ^ v11) | v9 );
			}
			++v5;
		}
		while ( v5 <= v4 + 1 );
	}
	if ( v3 >= 0 && v3 < 111 && v4 >= 0 && v4 < 111 )
	{
		v12 = 112 * v3 + v4;
		dFlags[1][v12] &= 0xDFu;
		dFlags[0][v12 + 1] &= 0xDFu;
	}
}

//----- (0044CC62) --------------------------------------------------------
void __fastcall RemovePlrFromMap(int pnum)
{
	int v1; // esi
	signed int v2; // edi
	signed int v3; // edx
	signed int v4; // ebx
	char v5; // al
	signed int v6; // edx
	_BYTE *v7; // eax
	signed int v8; // edi
	int v9; // ecx
	int v10; // [esp+Ch] [ebp-4h]

	v1 = -1 - pnum;
	v10 = pnum + 1;
	v2 = 1;
	do
	{
		v3 = v2;
		v4 = 111;
		do
		{
			if ( dPlayer[0][v3 + 111] == v1 || dPlayer[0][v3] == v1 )
			{
				v5 = dFlags[1][v3];
				if ( v5 & 0x20 )
					dFlags[1][v3] = v5 & 0xDF;
			}
			v3 += 112;
			--v4;
		}
		while ( v4 );
		++v2;
	}
	while ( v2 < 112 );
	v6 = 0;
	do
	{
		v7 = (unsigned char *)dPlayer + v6;
		v8 = 112;
		do
		{
			v9 = (char)*v7;
			if ( v9 == v10 || v9 == v1 )
				*v7 = 0;
			v7 += 112;
			--v8;
		}
		while ( v8 );
		++v6;
	}
	while ( v6 < 112 );
}

//----- (0044CCD8) --------------------------------------------------------
void __fastcall StartPlrHit(int pnum, int dam, unsigned char forcehit)
{
	int v3; // ebx
	int v4; // edi
	int v5; // esi
	char v6; // al
	int v7; // ecx
	int v8; // eax
	int v9; // edi
	int v10; // ST08_4

	v3 = pnum;
	v4 = dam;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("StartPlrHit: illegal player %d", pnum);
	v5 = v3;
	if ( plr[v3]._pInvincible && !plr[v5]._pHitPoints && v3 == myplr )
	{
		SyncPlrKill(v3, -1);
		return;
	}
	v6 = plr[v5]._pClass;
	switch ( v6 )
	{
		case UI_WARRIOR:
			v7 = PS_WARR69;
LABEL_13:
			PlaySfxLoc(v7, plr[v5].WorldX, plr[v5].WorldY);
			break;
		case UI_ROGUE:
			v7 = PS_ROGUE69;
			goto LABEL_13;
		case UI_SORCERER:
			v7 = PS_MAGE69;
			goto LABEL_13;
	}
	v8 = plr[v5]._pLevel;
	drawhpflag = 1;
	if ( v4 >> 6 >= v8 || forcehit )
	{
		v9 = plr[v5]._pdir;
		if ( !(plr[v5]._pGFXLoad & 8) )
			LoadPlrGFX(v3, 8);
		v10 = plr[v5]._pHFNum;
		NewPlrAnim(v3, plr[0]._peqH[v9 + 5430 * v3], plr[v5]._pHFrames, 0);
		plr[v5]._pmode = PM_GOTHIT;
		FixPlayerLocation(v3, v9);
		plr[v5]._pVar8 = 1;
		FixPlrWalkTags(v3);
		dPlayer[plr[v5].WorldX][plr[v5].WorldY] = v3 + 1;
		SetPlayerOld(v3);
	}
}

//----- (0044CDFD) --------------------------------------------------------
void __fastcall DestroyDupeItem(ItemStruct *pItem, int ci, int a3)
{
	ItemStruct *v3; // ebx
	int v4; // eax
	int v5; // eax
	int i; // ST10_4
	unsigned int v7; // ecx
	int x; // [esp+8h] [ebp-4h]

	x = ci;
	v3 = pItem;
	if ( numitems < 127 )
	{
		_LOWORD(ci) = pItem->_iCreateInfo;
		FindGetItem(pItem->IDidx, ci, pItem->_iSeed);
		if ( v4 >= 0 )
		{
			DupeInvMsg("A duplicate item has been detected.  Destroying duplicate...");
			SyncGetItem(x, a3, v3->IDidx, v3->_iCreateInfo, v3->_iSeed);
		}
		v5 = itemavail[0];
		i = itemavail[0];
		dItem[x][a3] = _LOBYTE(itemavail[0]) + 1;
		v7 = 4 * numitems;
		itemactive[v7 / 4] = v5;
		v5 *= 368;
		itemavail[0] = itemavail[v7 / 0xFFFFFFFC + 126];
		qmemcpy((char *)items + v5, v3, sizeof(ItemStruct));
		*(int *)((char *)&items[0]._ix + v5) = x;
		*(int *)((char *)&items[0]._iy + v5) = a3;
		RespawnItem(i, 1u);
		++numitems;
		v3->_itype = -1;
	}
}

//----- (0044CEC9) --------------------------------------------------------
void __fastcall StartPlayerKill(int pnum, int earflag)
{
	unsigned int v2; // edi
	unsigned int v3; // esi
	char v4; // al
	int v5; // ecx
	int v6; // ST0C_4
	bool v7; // zf
	int *v8; // eax
	signed int v9; // ecx
	char *v10; // eax
	char v11; // al
	short v12; // cx
	short v13; // ax
	int v14; // ecx
	int v15; // eax
	int v16; // eax
	signed int v17; // ebx
	int v18; // eax
	ItemStruct item; // [esp+Ch] [ebp-178h]
	BOOL v20; // [esp+17Ch] [ebp-8h]
	struct ItemStruct *itm; // [esp+180h] [ebp-4h]

	v2 = pnum;
	v3 = 21720 * pnum;
	itm = (struct ItemStruct *)earflag;
	if ( plr[pnum]._pHitPoints <= 0 && plr[v3 / 0x54D8]._pmode == PM_DEATH )
		return;
	if ( myplr == pnum )
		NetSendCmdParam1(1u, CMD_PLRDEAD, earflag);
	v20 = (unsigned char)gbMaxPlayers > 1u && plr[v3 / 0x54D8].plrlevel == 16;
	if ( v2 >= 4 )
		TermMsg("StartPlayerKill: illegal player %d", v2);
	v4 = plr[v3 / 0x54D8]._pClass;
	if ( v4 )
	{
		if ( v4 == 1 )
		{
			v5 = PS_ROGUE71;
		}
		else
		{
			if ( v4 != 2 )
				goto LABEL_18;
			v5 = PS_MAGE71;
		}
		PlaySfxLoc(v5, plr[v3 / 0x54D8].WorldX, plr[v3 / 0x54D8].WorldY);
		goto LABEL_18;
	}
	PlaySfxLoc(PS_DEAD, plr[v3 / 0x54D8].WorldX, plr[v3 / 0x54D8].WorldY);
LABEL_18:
	if ( plr[v3 / 0x54D8]._pgfxnum )
	{
		plr[v3 / 0x54D8]._pgfxnum = 0;
		plr[v3 / 0x54D8]._pGFXLoad = 0;
		SetPlrAnims(v2);
	}
	if ( SLOBYTE(plr[v3 / 0x54D8]._pGFXLoad) >= 0 )
		LoadPlrGFX(v2, 128);
	v6 = plr[v3 / 0x54D8]._pDFNum;
	NewPlrAnim(v2, plr[0]._peqD[plr[v3 / 0x54D8]._pdir + v3 / 4], plr[v3 / 0x54D8]._pDFrames, 1);
	plr[v3 / 0x54D8]._pBlockFlag = 0;
	plr[v3 / 0x54D8]._pmode = PM_DEATH;
	plr[v3 / 0x54D8]._pInvincible = 1;
	SetPlayerHitPoints(v2, 0);
	v7 = v2 == myplr;
	plr[v3 / 0x54D8]._pVar8 = 1;
	if ( !v7 && !itm && !v20 )
	{
		v8 = &plr[v3 / 0x54D8].InvBody[0]._itype;
		v9 = 7;
		do
		{
			*v8 = -1;
			v8 += 92;
			--v9;
		}
		while ( v9 );
		CalcPlrInv(v2, 0);
	}
	if ( plr[v3 / 0x54D8].plrlevel == currlevel )
	{
		FixPlayerLocation(v2, plr[v3 / 0x54D8]._pdir);
		RemovePlrFromMap(v2);
		v10 = &dFlags[plr[v3 / 0x54D8].WorldX][plr[v3 / 0x54D8].WorldY];
		*v10 |= 4u;
		SetPlayerOld(v2);
		if ( v2 == myplr )
		{
			drawhpflag = 1;
			deathdelay = 30;
			if ( pcurs >= CURSOR_FIRSTITEM )
			{
				PlrDeadItem(v2, &plr[v3 / 0x54D8].HoldItem, 0, 0);
				SetCursor(1);
			}
			if ( !v20 )
			{
				DropHalfPlayersGold(v2);
				if ( itm != (struct ItemStruct *)-1 )
				{
					if ( itm )
					{
						SetPlrHandItem(&item, 23);
						sprintf(item._iName, "Ear of %s", plr[v3 / 0x54D8]._pName);
						v11 = plr[v3 / 0x54D8]._pClass;
						if ( v11 == 2 )
						{
							item._iCurs = 19;
						}
						else if ( v11 )
						{
							if ( v11 == 1 )
								item._iCurs = 21;
						}
						else
						{
							item._iCurs = 20;
						}
						_LOBYTE(v12) = 0;
						_HIBYTE(v12) = plr[v3 / 0x54D8]._pName[0];
						v13 = v12 | plr[v3 / 0x54D8]._pName[1];
						v14 = plr[v3 / 0x54D8]._pName[3];
						item._iCreateInfo = v13;
						v15 = plr[v3 / 0x54D8]._pName[5] | ((plr[v3 / 0x54D8]._pName[4] | ((v14 | (plr[v3 / 0x54D8]._pName[2] << 8)) << 8)) << 8);
						item._ivalue = plr[v3 / 0x54D8]._pLevel;
						item._iSeed = v15;
						FindGetItem(23, *(int *)&item._iCreateInfo, v15);
						if ( v16 == -1 )
							PlrDeadItem(v2, &item, 0, 0);
					}
					else
					{
						itm = plr[v3 / 0x54D8].InvBody;
						v17 = 7;
						do
						{
							v18 = ((_BYTE)--v17 + (unsigned char)plr[v3 / 0x54D8]._pdir) & 7;
							PlrDeadItem(v2, itm, offset_x[v18], offset_y[v18]);
							++itm;
						}
						while ( v17 );
						CalcPlrInv(v2, 0);
					}
				}
			}
		}
	}
	SetPlayerHitPoints(v2, 0);
}
// 679660: using guessed type char gbMaxPlayers;
// 69B7C4: using guessed type int deathdelay;

//----- (0044D1F4) --------------------------------------------------------
void __fastcall PlrDeadItem(int pnum, struct ItemStruct *itm, int xx, int yy)
{
	int v4; // edi
	int v5; // edi
	int v6; // esi
	int v7; // ebx
	int v8; // eax
	int v9; // ST04_4
	ItemStruct *v10; // esi
	int v11; // eax
	int v12; // ebx
	int v13; // esi
	int v14; // eax
	int v15; // edx
	unsigned char v16; // [esp-8h] [ebp-24h]
	unsigned char v17; // [esp-4h] [ebp-20h]
	int x; // [esp+Ch] [ebp-10h]
	ItemStruct *pItem; // [esp+10h] [ebp-Ch]
	int v20; // [esp+14h] [ebp-8h]
	int v21; // [esp+14h] [ebp-8h]
	int v22; // [esp+18h] [ebp-4h]
	int xxa; // [esp+24h] [ebp+8h]
	int yya; // [esp+28h] [ebp+Ch]

	pItem = itm;
	v4 = pnum;
	if ( itm->_itype != -1 )
	{
		if ( (unsigned int)pnum >= 4 )
			TermMsg("PlrDeadItem: illegal player %d", pnum);
		v5 = v4;
		v6 = yy + plr[v5].WorldY;
		v7 = xx + plr[v5].WorldX;
		v20 = yy + plr[v5].WorldY;
		if ( (xx || yy) && (_LOBYTE(v8) = ItemSpaceOk(v7, v6), v8) )
		{
			v9 = v6;
			v10 = pItem;
			DestroyDupeItem(pItem, v7, v9);
			v17 = v20;
			v16 = v7;
		}
		else
		{
			yya = -1;
			xxa = 1;
			while ( 1 )
			{
				v11 = yya;
				v21 = yya;
LABEL_14:
				if ( v11 <= xxa )
					break;
				++xxa;
				if ( --yya <= -50 )
					return;
			}
			v12 = v21 + plr[v5].WorldY;
			v22 = yya;
			while ( 1 )
			{
				v13 = v22 + plr[v5].WorldX;
				x = v22 + plr[v5].WorldX;
				_LOBYTE(v14) = ItemSpaceOk(v13, v12);
				if ( v14 )
					break;
				if ( ++v22 > xxa )
				{
					v11 = ++v21;
					goto LABEL_14;
				}
			}
			v15 = v13;
			v10 = pItem;
			DestroyDupeItem(pItem, v15, v12);
			v17 = v12;
			v16 = x;
		}
		qmemcpy(&plr[v5].HoldItem, v10, sizeof(plr[v5].HoldItem));
		NetSendCmdPItem(0, CMD_RESPAWNITEM, v16, v17);
	}
}

//----- (0044D2F3) --------------------------------------------------------
void __fastcall DropHalfPlayersGold(int pnum)
{
	int v1; // ebx
	int v2; // esi
	int v3; // edi
	int v4; // ecx
	int v5; // eax
	int v6; // ecx
	int v7; // eax
	int v8; // edx
	int v9; // ecx
	int v10; // eax
	int v11; // edx
	int v12; // ecx
	int v13; // eax
	int v14; // [esp+Ch] [ebp-8h]
	int v15; // [esp+Ch] [ebp-8h]
	int v16; // [esp+Ch] [ebp-8h]
	int v17; // [esp+Ch] [ebp-8h]
	signed int i; // [esp+10h] [ebp-4h]
	signed int ia; // [esp+10h] [ebp-4h]
	signed int ib; // [esp+10h] [ebp-4h]
	signed int ic; // [esp+10h] [ebp-4h]

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("DropHalfPlayersGold: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pGold >> 1;
	i = 0;
	while ( v3 > 0 )
	{
		v4 = 368 * i + v2 * 21720;
		v14 = v4;
		if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v4) == ITYPE_GOLD )
		{
			v5 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v4);
			if ( v5 != 5000 )
			{
				if ( v3 >= v5 )
				{
					v3 -= v5;
					RemoveSpdBarItem(v1, i);
					SetPlrHandItem(&plr[v2].HoldItem, 0);
					GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
					SetPlrHandGoldCurs(&plr[v2].HoldItem);
					plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v14);
					PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
					i = -1;
				}
				else
				{
					*(int *)((char *)&plr[0].SpdList[0]._ivalue + v4) = v5 - v3;
					SetSpdbarGoldCurs(v1, i);
					SetPlrHandItem(&plr[v2].HoldItem, 0);
					GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
					SetPlrHandGoldCurs(&plr[v2].HoldItem);
					plr[v2].HoldItem._ivalue = v3;
					v3 = 0;
					PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
				}
			}
		}
		if ( ++i >= 8 )
		{
			if ( v3 > 0 )
			{
				ia = 0;
				do
				{
					if ( v3 <= 0 )
						break;
					v6 = 368 * ia + v2 * 21720;
					v15 = v6;
					if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v6) == ITYPE_GOLD )
					{
						v7 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v6);
						if ( v3 >= v7 )
						{
							v3 -= v7;
							RemoveSpdBarItem(v1, ia);
							SetPlrHandItem(&plr[v2].HoldItem, 0);
							GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
							SetPlrHandGoldCurs(&plr[v2].HoldItem);
							plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v15);
							PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
							ia = -1;
						}
						else
						{
							*(int *)((char *)&plr[0].SpdList[0]._ivalue + v6) = v7 - v3;
							SetSpdbarGoldCurs(v1, ia);
							SetPlrHandItem(&plr[v2].HoldItem, 0);
							GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
							SetPlrHandGoldCurs(&plr[v2].HoldItem);
							plr[v2].HoldItem._ivalue = v3;
							v3 = 0;
							PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
						}
					}
					++ia;
				}
				while ( ia < 8 );
			}
			break;
		}
	}
	v8 = 0;
	force_redraw = 255;
	if ( v3 > 0 )
	{
		ib = 0;
		if ( plr[v2]._pNumInv <= 0 )
		{
LABEL_28:
			if ( v3 > 0 )
			{
				v11 = 0;
				for ( ic = 0; ic < plr[v2]._pNumInv; v11 = ic++ + 1 )
				{
					if ( v3 <= 0 )
						break;
					v12 = 368 * v11 + v2 * 21720;
					v17 = v12;
					if ( *(int *)((char *)&plr[0].InvList[0]._itype + v12) == ITYPE_GOLD )
					{
						v13 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v12);
						if ( v3 >= v13 )
						{
							v3 -= v13;
							RemoveInvItem(v1, v11);
							SetPlrHandItem(&plr[v2].HoldItem, 0);
							GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
							SetPlrHandGoldCurs(&plr[v2].HoldItem);
							plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].InvList[0]._ivalue + v17);
							PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
							ic = -1;
						}
						else
						{
							*(int *)((char *)&plr[0].InvList[0]._ivalue + v12) = v13 - v3;
							SetGoldCurs(v1, v11);
							SetPlrHandItem(&plr[v2].HoldItem, 0);
							GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
							SetPlrHandGoldCurs(&plr[v2].HoldItem);
							plr[v2].HoldItem._ivalue = v3;
							v3 = 0;
							PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
						}
					}
				}
			}
		}
		else
		{
			while ( v3 > 0 )
			{
				v9 = 368 * v8 + v2 * 21720;
				v16 = v9;
				if ( *(int *)((char *)&plr[0].InvList[0]._itype + v9) == ITYPE_GOLD )
				{
					v10 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v9);
					if ( v10 != 5000 )
					{
						if ( v3 >= v10 )
						{
							v3 -= v10;
							RemoveInvItem(v1, v8);
							SetPlrHandItem(&plr[v2].HoldItem, 0);
							GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
							SetPlrHandGoldCurs(&plr[v2].HoldItem);
							plr[v2].HoldItem._ivalue = *(int *)((char *)&plr[0].InvList[0]._ivalue + v16);
							PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
							ib = -1;
						}
						else
						{
							*(int *)((char *)&plr[0].InvList[0]._ivalue + v9) = v10 - v3;
							SetGoldCurs(v1, v8);
							SetPlrHandItem(&plr[v2].HoldItem, 0);
							GetGoldSeed(v1, &plr[v2].HoldItem._iSeed);
							SetPlrHandGoldCurs(&plr[v2].HoldItem);
							plr[v2].HoldItem._ivalue = v3;
							v3 = 0;
							PlrDeadItem(v1, &plr[v2].HoldItem, 0, 0);
						}
					}
				}
				v8 = ib++ + 1;
				if ( ib >= plr[v2]._pNumInv )
					goto LABEL_28;
			}
		}
	}
	plr[v2]._pGold = CalculateGold(v1);
}
// 52571C: using guessed type int force_redraw;

//----- (0044D70B) --------------------------------------------------------
void __fastcall SyncPlrKill(int pnum, int earflag)
{
	int v2; // esi
	int v3; // ebx
	int v4; // edx
	int v5; // eax

	v2 = pnum;
	v3 = earflag;
	if ( plr[pnum]._pHitPoints || currlevel )
	{
		v4 = 0;
		if ( nummissiles <= 0 )
		{
LABEL_9:
			SetPlayerHitPoints(pnum, 0);
			StartPlayerKill(v2, v3);
		}
		else
		{
			while ( 1 )
			{
				v5 = missileactive[v4];
				if ( missile[v5]._mitype == 13 && missile[v5]._misource == pnum && !missile[v5]._miDelFlag )
					break;
				if ( ++v4 >= nummissiles )
					goto LABEL_9;
			}
			if ( v3 != -1 )
				missile[missileactive[v4]]._miVar8 = v3;
		}
	}
	else
	{
		SetPlayerHitPoints(pnum, 64);
	}
}

//----- (0044D7A0) --------------------------------------------------------
void __fastcall RemovePlrMissiles(int pnum)
{
	int v1; // ebx
	int v2; // ebp
	int v3; // ecx
	int v4; // edi
	int v5; // esi
	int v6; // eax

	v1 = 0;
	v2 = pnum;
	if ( currlevel && pnum == myplr && (monster[myplr]._mx != 1 || monster[myplr]._my) )
	{
		M_StartKill(myplr, myplr);
		AddDead(monster[myplr]._mx, monster[myplr]._my, monster[myplr].MType->mdeadval, (direction)monster[myplr]._mdir);
		v3 = monster[myplr]._my + 112 * monster[myplr]._mx;
		monster[myplr]._mDelFlag = 1;
		dMonster[0][v3] = 0;
		DeleteMonsterList();
	}
	if ( nummissiles > 0 )
	{
		do
		{
			v4 = missileactive[v1];
			v5 = missileactive[v1];
			v6 = missile[v5]._mitype;
			if ( v6 == 30 && missile[v5]._misource == v2 )
				monster[missile[v5]._miVar2]._mmode = missile[v5]._miVar1;
			if ( v6 == 13 && missile[v5]._misource == v2 )
			{
				ClearMissileSpot(v4);
				DeleteMissile(v4, v1);
			}
			if ( missile[v5]._mitype == 34 && missile[v5]._misource == v2 )
			{
				ClearMissileSpot(v4);
				DeleteMissile(v4, v1);
			}
			++v1;
		}
		while ( v1 < nummissiles );
	}
}

//----- (0044D8D1) --------------------------------------------------------
int __fastcall InitLevelChange(int pnum)
{
	int v1; // esi
	int result; // eax
	bool v3; // zf

	v1 = pnum;
	RemovePlrMissiles(pnum);
	if ( v1 == myplr && qtextflag )
	{
		qtextflag = 0;
		sfx_stop();
	}
	RemovePlrFromMap(v1);
	SetPlayerOld(v1);
	if ( v1 == myplr )
		dPlayer[plr[myplr].WorldX][plr[myplr].WorldY] = myplr + 1;
	else
		plr[v1]._pLvlVisited[plr[v1].plrlevel] = 1;
	ClrPlrPath(v1);
	result = v1;
	plr[result].destAction = -1;
	v3 = v1 == myplr;
	plr[result]._pLvlChanging = 1;
	if ( v3 )
		plr[result].pLvlLoad = 10;
	return result * 21720;
}
// 646D00: using guessed type char qtextflag;

//----- (0044D973) --------------------------------------------------------
void __fastcall StartNewLvl(int pnum, int fom, int lvl)
{
	int v3; // edi
	unsigned int v4; // esi
	unsigned int v5; // eax
	HWND v6; // ST00_4

	v3 = fom;
	v4 = pnum;
	InitLevelChange(pnum);
	if ( v4 >= 4 )
		TermMsg("StartNewLvl: illegal player %d", v4);
	if ( v3 < WM_DIABNEXTLVL )
	{
LABEL_10:
		TermMsg("StartNewLvl");
		goto LABEL_11;
	}
	if ( v3 <= WM_DIABPREVLVL || v3 == WM_DIABRTNLVL )
		goto LABEL_16;
	if ( v3 != WM_DIABSETLVL )
	{
		if ( v3 != WM_DIABTOWNWARP )
		{
			if ( v3 != WM_DIABTWARPUP )
			{
				if ( v3 == WM_DIABRETOWN )
					goto LABEL_11;
				goto LABEL_10;
			}
			plr[myplr].pTownWarps |= 1 << (leveltype - 2);
		}
LABEL_16:
		plr[v4].plrlevel = lvl;
		goto LABEL_11;
	}
	setlvlnum = lvl;
LABEL_11:
	if ( v4 == myplr )
	{
		v5 = v4;
		v6 = ghMainWnd;
		plr[v5]._pmode = PM_NEWLVL;
		plr[v5]._pInvincible = 1;
		PostMessageA(v6, v3, 0, 0);
		if ( (unsigned char)gbMaxPlayers > 1u )
			NetSendCmdParam2(1u, CMD_NEWLVL, v3, lvl);
	}
}
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 679660: using guessed type char gbMaxPlayers;

//----- (0044DA6F) --------------------------------------------------------
void __fastcall RestartTownLvl(int pnum)
{
	unsigned int v1; // edi
	unsigned int v2; // esi
	int v3; // eax
	HWND v4; // ST00_4

	v1 = pnum;
	InitLevelChange(pnum);
	if ( v1 >= 4 )
		TermMsg("RestartTownLvl: illegal player %d", v1);
	v2 = v1;
	plr[v2].plrlevel = 0;
	plr[v2]._pInvincible = 0;
	SetPlayerHitPoints(v1, 64);
	v3 = plr[v2]._pMaxManaBase - plr[v2]._pMaxMana;
	plr[v2]._pMana = 0;
	plr[v2]._pManaBase = v3;
	CalcPlrInv(v1, 0);
	if ( v1 == myplr )
	{
		plr[v2]._pmode = PM_NEWLVL;
		v4 = ghMainWnd;
		plr[v2]._pInvincible = 1;
		PostMessageA(v4, WM_DIABRETOWN, 0, 0);
	}
}

//----- (0044DAFC) --------------------------------------------------------
void __fastcall StartWarpLvl(int pnum, int pidx)
{
	int v2; // edi
	int v3; // esi
	int *v4; // eax
	int v5; // eax
	HWND v6; // ST00_4

	v2 = pidx;
	v3 = pnum;
	InitLevelChange(pnum);
	if ( gbMaxPlayers != 1 )
	{
		v4 = &plr[v3].plrlevel;
		if ( *v4 )
			*v4 = 0;
		else
			*v4 = portal[v2].level;
	}
	if ( v3 == myplr )
	{
		SetCurrentPortal(v2);
		v5 = v3;
		plr[v5]._pmode = PM_NEWLVL;
		v6 = ghMainWnd;
		plr[v5]._pInvincible = 1;
		PostMessageA(v6, WM_DIABWARPLVL, 0, 0);
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (0044DB74) --------------------------------------------------------
int __fastcall PM_DoNothing(int pnum)
{
	return 0;
}

//----- (0044DB77) --------------------------------------------------------
int __fastcall PM_DoWalk(int pnum)
{
	int v1; // ebx
	int v2; // esi
	int v3; // eax
	int v4; // eax
	int v5; // ecx
	int v6; // eax
	int v7; // edx
	int v8; // eax
	bool v9; // zf
	int result; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoWalk: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pAnimFrame;
	if ( v3 == 3 )
		goto LABEL_8;
	if ( plr[v2]._pWFrames != 8 )
	{
		if ( v3 != 4 )
			goto LABEL_9;
		goto LABEL_8;
	}
	if ( v3 == 7 )
LABEL_8:
		PlaySfxLoc(0, plr[v2].WorldX, plr[v2].WorldY);
LABEL_9:
	v4 = 8;
	if ( currlevel )
		v4 = PWVel[3][SLOBYTE(plr[v2]._pClass)];
	if ( plr[v2]._pVar8 == v4 )
	{
		v5 = plr[v2].WorldX;
		v6 = plr[v2].WorldY;
		dPlayer[plr[v2].WorldX][v6] = 0;
		v7 = v5 + plr[v2]._pVar1;
		v8 = plr[v2]._pVar2 + v6;
		plr[v2].WorldX = v7;
		v9 = leveltype == 0;
		dPlayer[v7][v8] = v1 + 1;
		plr[v2].WorldY = v8;
		if ( !v9 )
		{
			ChangeLightXY(plr[v2]._plid, v7, v8);
			ChangeVisionXY(plr[v2]._pvid, plr[v2].WorldX, plr[v2].WorldY);
		}
		if ( v1 == myplr && ScrollInfo._sdir )
		{
			ViewX = plr[v2].WorldX - ScrollInfo._sdx;
			ViewY = plr[v2].WorldY - ScrollInfo._sdy;
		}
		if ( plr[v2].walkpath[0] == -1 )
			StartStand(v1, plr[v2]._pVar3);
		else
			StartWalkStand(v1);
		ClearPlrPVars(v1);
		if ( leveltype )
			ChangeLightOff(plr[v2]._plid, 0, 0);
		result = 1;
	}
	else
	{
		PM_ChangeOffset(v1);
		result = 0;
	}
	return result;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0044DCE5) --------------------------------------------------------
int __fastcall PM_DoWalk2(int pnum)
{
	int v1; // ebx
	int v2; // esi
	int v3; // eax
	int v4; // eax
	int result; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoWalk2: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pAnimFrame;
	if ( v3 == 3 )
		goto LABEL_8;
	if ( plr[v2]._pWFrames != 8 )
	{
		if ( v3 != 4 )
			goto LABEL_9;
		goto LABEL_8;
	}
	if ( v3 == 7 )
LABEL_8:
		PlaySfxLoc(0, plr[v2].WorldX, plr[v2].WorldY);
LABEL_9:
	v4 = 8;
	if ( currlevel )
		v4 = PWVel[3][SLOBYTE(plr[v2]._pClass)];
	if ( plr[v2]._pVar8 == v4 )
	{
		dPlayer[plr[v2]._pVar1][plr[v2]._pVar2] = 0;
		if ( leveltype )
		{
			ChangeLightXY(plr[v2]._plid, plr[v2].WorldX, plr[v2].WorldY);
			ChangeVisionXY(plr[v2]._pvid, plr[v2].WorldX, plr[v2].WorldY);
		}
		if ( v1 == myplr && ScrollInfo._sdir )
		{
			ViewX = plr[v2].WorldX - ScrollInfo._sdx;
			ViewY = plr[v2].WorldY - ScrollInfo._sdy;
		}
		if ( plr[v2].walkpath[0] == -1 )
			StartStand(v1, plr[v2]._pVar3);
		else
			StartWalkStand(v1);
		ClearPlrPVars(v1);
		if ( leveltype )
			ChangeLightOff(plr[v2]._plid, 0, 0);
		result = 1;
	}
	else
	{
		PM_ChangeOffset(v1);
		result = 0;
	}
	return result;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0044DE30) --------------------------------------------------------
int __fastcall PM_DoWalk3(int pnum)
{
	int v1; // ebx
	int v2; // esi
	int v3; // eax
	int v4; // eax
	int v5; // edx
	char *v6; // eax
	int v7; // eax
	bool v8; // zf
	int result; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoWalk3: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pAnimFrame;
	if ( v3 == 3 )
		goto LABEL_8;
	if ( plr[v2]._pWFrames != 8 )
	{
		if ( v3 != 4 )
			goto LABEL_9;
		goto LABEL_8;
	}
	if ( v3 == 7 )
LABEL_8:
		PlaySfxLoc(0, plr[v2].WorldX, plr[v2].WorldY);
LABEL_9:
	v4 = 8;
	if ( currlevel )
		v4 = PWVel[3][SLOBYTE(plr[v2]._pClass)];
	if ( plr[v2]._pVar8 == v4 )
	{
		v5 = plr[v2]._pVar1;
		dPlayer[plr[v2].WorldX][plr[v2].WorldY] = 0;
		v6 = &dFlags[plr[v2]._pVar4][plr[v2]._pVar5];
		plr[v2].WorldX = v5;
		*v6 &= 0xDFu;
		v7 = plr[v2]._pVar2;
		v8 = leveltype == 0;
		dPlayer[v5][v7] = v1 + 1;
		plr[v2].WorldY = v7;
		if ( !v8 )
		{
			ChangeLightXY(plr[v2]._plid, v5, v7);
			ChangeVisionXY(plr[v2]._pvid, plr[v2].WorldX, plr[v2].WorldY);
		}
		if ( v1 == myplr && ScrollInfo._sdir )
		{
			ViewX = plr[v2].WorldX - ScrollInfo._sdx;
			ViewY = plr[v2].WorldY - ScrollInfo._sdy;
		}
		if ( plr[v2].walkpath[0] == -1 )
			StartStand(v1, plr[v2]._pVar3);
		else
			StartWalkStand(v1);
		ClearPlrPVars(v1);
		if ( leveltype )
			ChangeLightOff(plr[v2]._plid, 0, 0);
		result = 1;
	}
	else
	{
		PM_ChangeOffset(v1);
		result = 0;
	}
	return result;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0044DFB1) --------------------------------------------------------
unsigned char __fastcall WeaponDur(int pnum, int durrnd)
{
	unsigned int v2; // edi
	unsigned int v3; // esi
	int v4; // ebp
	int v5; // ecx
	int v6; // ecx
	int v7; // ecx
	int v8; // ecx
	int v9; // ecx
	int v10; // ecx
	int v11; // ecx
	int v12; // ecx

	v2 = pnum;
	if ( pnum != myplr )
		return 0;
	_LOBYTE(pnum) = 3;
	if ( random(pnum, durrnd) )
		return 0;
	if ( v2 >= 4 )
		TermMsg("WeaponDur: illegal player %d", v2);
	v3 = v2;
	v4 = plr[v2].InvBody[4]._itype;
	if ( v4 != ITYPE_NONE && plr[v3].InvBody[4]._iClass == 1 )
	{
		v5 = plr[v3].InvBody[4]._iDurability;
		if ( v5 == 255 )
			return 0;
		v6 = v5 - 1;
		plr[v3].InvBody[4]._iDurability = v6;
		if ( !v6 )
		{
LABEL_22:
			NetSendCmdDelItem(1u, 4u);
			plr[v3].InvBody[4]._itype = -1;
			goto LABEL_23;
		}
	}
	if ( plr[v3].InvBody[5]._itype != -1 && plr[v3].InvBody[5]._iClass == 1 )
	{
		v7 = plr[v3].InvBody[5]._iDurability;
		if ( v7 == 255 )
			return 0;
		v8 = v7 - 1;
		plr[v3].InvBody[5]._iDurability = v8;
		if ( !v8 )
		{
LABEL_13:
			NetSendCmdDelItem(1u, 5u);
			plr[v3].InvBody[5]._itype = -1;
LABEL_23:
			CalcPlrInv(v2, 1u);
			return 1;
		}
	}
	if ( v4 == -1 && plr[v3].InvBody[5]._itype == ITYPE_SHIELD )
	{
		v9 = plr[v3].InvBody[5]._iDurability;
		if ( v9 == 255 )
			return 0;
		v10 = v9 - 1;
		plr[v3].InvBody[5]._iDurability = v10;
		if ( !v10 )
			goto LABEL_13;
	}
	if ( plr[v3].InvBody[5]._itype == -1 && v4 == 5 )
	{
		v11 = plr[v3].InvBody[4]._iDurability;
		if ( v11 != 255 )
		{
			v12 = v11 - 1;
			plr[v3].InvBody[4]._iDurability = v12;
			if ( !v12 )
				goto LABEL_22;
		}
	}
	return 0;
}

//----- (0044E0BC) --------------------------------------------------------
unsigned char __fastcall PlrHitMonst(int pnum, int m)
{
	int v2; // ebx
	unsigned int v3; // esi
	int v4; // ST04_4
	int v5; // ebx
	int v7; // ST04_4
	int v8; // eax
	unsigned int v9; // esi
	int v10; // ecx
	int v11; // eax
	int v12; // edi
	int v13; // edi
	int v14; // eax
	int v15; // ecx
	int v16; // edx
	int v17; // eax
	int v18; // ecx
	int v19; // edi
	int v20; // eax
	int v21; // eax
	char v22; // dl
	bool v23; // zf
	int v24; // eax
	int v25; // ecx
	int v26; // edi
	int v27; // eax
	int v28; // edx
	int *v29; // ecx
	int v30; // edx
	int *v31; // ecx
	int v32; // ecx
	int v33; // edx
	int *v34; // ecx
	int v35; // edx
	int *v36; // ecx
	int v37; // edx
	int *v38; // ecx
	int *v39; // ecx
	int v40; // esi
	unsigned char ret[4]; // [esp+Ch] [ebp-18h]
	int v42; // [esp+10h] [ebp-14h]
	int v43; // [esp+14h] [ebp-10h]
	int pnuma; // [esp+18h] [ebp-Ch]
	char arglist[4]; // [esp+1Ch] [ebp-8h]
	int v46; // [esp+20h] [ebp-4h]

	v2 = m;
	v3 = pnum;
	*(_DWORD *)arglist = m;
	pnuma = pnum;
	if ( (unsigned int)m >= 0xC8 )
	{
		TermMsg("PlrHitMonst: illegal monster %d", m);
		pnum = v4;
	}
	v5 = 228 * v2;
	v43 = v5;
	if ( (signed int)(*(int *)((_BYTE *)&monster[0]._mhitpoints + v5) & 0xFFFFFFC0) <= 0
	  || **(_BYTE **)((char *)&monster[0].MType + v5) == MON_SNEAKD && *((_BYTE *)&monster[0]._mgoal + v5) == 2
	  || *(MON_MODE *)((char *)&monster[0]._mmode + v5) == MM_CHARGE )
	{
		return 0;
	}
	if ( v3 >= 4 )
	{
		TermMsg("PlrHitMonst: illegal player %d", v3);
		pnum = v7;
	}
	v42 = 0;
	_LOBYTE(pnum) = 4;
	v8 = random(pnum, 100);
	v23 = *(MON_MODE *)((char *)&monster[0]._mmode + v5) == MM_STONE;
	v46 = v8;
	if ( v23 )
		v46 = 0;
	v9 = v3;
	v10 = plr[v9]._pLevel;
	v11 = plr[v9]._pIEnAc + (plr[v9]._pDexterity >> 1) - *((unsigned char *)&monster[0].mArmorClass + v5);
	v12 = v11 + v10 + 50;
	if ( !_LOBYTE(plr[v9]._pClass) )
		v12 = v11 + v10 + 70;
	v13 = plr[v9]._pIBonusToHit + v12;
	if ( v13 < 5 )
		v13 = 5;
	if ( v13 > 95 )
		v13 = 95;
	_LOBYTE(v14) = CheckMonsterHit(*(int *)arglist, ret);
	if ( v14 )
		return ret[0];
	if ( (signed int)v46 < v13 )
	{
		_LOBYTE(v15) = 5;
		v16 = plr[v9]._pIMaxDam - plr[v9]._pIMinDam + 1;
		v42 = plr[v9]._pIMinDam;
		v17 = random(v15, v16);
		v18 = 100;
		v19 = plr[v9]._pIBonusDamMod + plr[v9]._pDamageMod + (v42 + v17) * plr[v9]._pIBonusDam / 100 + v42 + v17;
		if ( !_LOBYTE(plr[v9]._pClass) )
		{
			_LOBYTE(v18) = 6;
			v42 = plr[v9]._pLevel;
			v20 = random(v18, 100);
			if ( v20 < v42 )
				v19 *= 2;
		}
		v21 = plr[v9].InvBody[4]._itype;
		v46 = -1;
		if ( v21 == 1 || plr[v9].InvBody[5]._itype == 1 )
			v46 = 1;
		if ( v21 == ITYPE_MACE || plr[v9].InvBody[5]._itype == ITYPE_MACE )
			v46 = ITYPE_MACE;
		v22 = (*(MonsterData **)((char *)&monster[0].MData + v5))->mMonstClass;
		if ( v22 )
		{
			if ( v22 != 2 )
				goto LABEL_40;
			if ( v46 == ITYPE_MACE )
				v19 -= v19 >> 1;
			v23 = v46 == 1;
		}
		else
		{
			if ( v46 == 1 )
				v19 -= v19 >> 1;
			v23 = v46 == ITYPE_MACE;
		}
		if ( v23 )
			v19 += v19 >> 1;
LABEL_40:
		v24 = plr[v9]._pIFlags;
		if ( v24 & 0x40000000 && v22 == 1 )
			v19 *= 3;
		v25 = pnuma;
		v26 = v19 << 6;
		if ( pnuma == myplr )
			*(int *)((char *)&monster[0]._mhitpoints + v5) -= v26;
		if ( v24 & 2 )
		{
			_LOBYTE(v25) = 7;
			v27 = random(v25, v26 >> 3);
			v28 = plr[v9]._pMaxHP;
			v29 = &plr[v9]._pHitPoints;
			*v29 += v27;
			if ( plr[v9]._pHitPoints > v28 )
				*v29 = v28;
			v30 = plr[v9]._pMaxHPBase;
			v31 = &plr[v9]._pHPBase;
			*v31 += v27;
			if ( plr[v9]._pHPBase > v30 )
				*v31 = v30;
			v5 = v43;
			drawhpflag = 1;
		}
		else
		{
			v27 = *(_DWORD *)ret;
		}
		v46 = plr[v9]._pIFlags;
		v32 = v46;
		if ( v32 & 0x6000 && !(v46 & 0x8000000) )
		{
			if ( v32 & 0x2000 )
				v27 = 3 * v26 / 100;
			if ( v32 & 0x4000 )
				v27 = 5 * v26 / 100;
			v33 = plr[v9]._pMaxMana;
			v34 = &plr[v9]._pMana;
			*v34 += v27;
			if ( plr[v9]._pMana > v33 )
				*v34 = v33;
			v35 = plr[v9]._pMaxManaBase;
			v36 = &plr[v9]._pManaBase;
			*v36 += v27;
			if ( plr[v9]._pManaBase > v35 )
				*v36 = v35;
			v5 = v43;
			v32 = v46;
			drawmanaflag = 1;
		}
		if ( v32 & 0x18000 )
		{
			if ( (v32 & 0x8000) != 0 )
				v27 = 3 * v26 / 100;
			if ( v32 & 0x10000 )
				v27 = 5 * v26 / 100;
			v37 = plr[v9]._pMaxHP;
			v38 = &plr[v9]._pHitPoints;
			*v38 += v27;
			if ( plr[v9]._pHitPoints > v37 )
				*v38 = v37;
			v39 = &plr[v9]._pHPBase;
			v40 = plr[v9]._pMaxHPBase;
			*v39 += v27;
			if ( *v39 > v40 )
				*v39 = v40;
			BYTE1(v32) = BYTE1(v46);
			v5 = v43;
			drawhpflag = 1;
		}
		if ( v32 & 0x100 )
			*(int *)((char *)&monster[0]._mFlags + v5) |= 8u;
		if ( (signed int)(*(int *)((_BYTE *)&monster[0]._mhitpoints + v5) & 0xFFFFFFC0) > 0 )
		{
			if ( *(MON_MODE *)((char *)&monster[0]._mmode + v5) != MM_STONE )
			{
				if ( v32 & 0x800 )
					M_GetKnockback(*(int *)arglist);
				M_StartHit(*(int *)arglist, pnuma, v26);
				goto LABEL_85;
			}
			M_StartHit(*(int *)arglist, pnuma, v26);
		}
		else
		{
			if ( *(MON_MODE *)((char *)&monster[0]._mmode + v5) != MM_STONE )
			{
				M_StartKill(*(int *)arglist, pnuma);
				goto LABEL_85;
			}
			M_StartKill(*(int *)arglist, pnuma);
		}
		*(MON_MODE *)((char *)&monster[0]._mmode + v5) = MM_STONE;
LABEL_85:
		v42 = 1;
	}
	return v42;
}

//----- (0044E442) --------------------------------------------------------
unsigned char __fastcall PlrHitPlr(int pnum, char p)
{
	char v2; // bl
	unsigned int v3; // esi
	int v4; // ST04_4
	int v5; // edi
	int v7; // ST04_4
	unsigned int v8; // esi
	int v9; // ecx
	int v10; // eax
	int v11; // ebx
	int v12; // ebx
	int v13; // eax
	int v14; // eax
	int v15; // ecx
	int v16; // eax
	int v17; // ebx
	int v18; // eax
	int v19; // ecx
	int v20; // edi
	int v21; // ebx
	signed __int32 v22; // edi
	int v23; // eax
	int v24; // edx
	int *v25; // ecx
	int *v26; // ecx
	int v27; // esi
	int v28; // [esp+Ch] [ebp-14h]
	int v29; // [esp+10h] [ebp-10h]
	unsigned char v30; // [esp+14h] [ebp-Ch]
	int arglist; // [esp+18h] [ebp-8h]
	char bPlr; // [esp+1Ch] [ebp-4h]

	v2 = p;
	v3 = pnum;
	bPlr = p;
	v28 = pnum;
	if ( (unsigned char)p >= 4u )
	{
		TermMsg("PlrHitPlr: illegal target player %d", p);
		pnum = v4;
	}
	arglist = v2;
	v5 = v2;
	v30 = 0;
	if ( plr[v5]._pInvincible || plr[v5]._pSpellFlags & 1 )
		return 0;
	if ( v3 >= 4 )
	{
		TermMsg("PlrHitPlr: illegal attacking player %d", v3);
		pnum = v7;
	}
	_LOBYTE(pnum) = 4;
	v8 = v3;
	v29 = random(pnum, 100);
	v9 = (plr[v8]._pDexterity >> 1) - plr[v5]._pIBonusAC - plr[v5]._pIAC - plr[v5]._pDexterity / 5;
	v10 = plr[v8]._pLevel;
	v11 = v9 + v10 + 50;
	if ( !_LOBYTE(plr[v8]._pClass) )
		v11 = v9 + v10 + 70;
	v12 = plr[v8]._pIBonusToHit + v11;
	if ( v12 < 5 )
		v12 = 5;
	if ( v12 > 95 )
		v12 = 95;
	v13 = plr[v5]._pmode;
	if ( v13 && v13 != 4 || !plr[v5]._pBlockFlag )
	{
		v14 = 100;
	}
	else
	{
		_LOBYTE(v9) = 5;
		v14 = random(v9, 100);
	}
	v15 = plr[v5]._pDexterity + plr[v5]._pBaseToBlk + 2 * plr[v5]._pLevel - 2 * plr[v8]._pLevel;
	if ( v15 < 0 )
		v15 = 0;
	if ( v15 > 100 )
		v15 = 100;
	if ( v29 < v12 )
	{
		if ( v14 >= v15 )
		{
			v17 = plr[v8]._pIMinDam;
			_LOBYTE(v15) = 5;
			v18 = random(v15, plr[v8]._pIMaxDam - v17 + 1);
			v19 = 100;
			v20 = plr[v8]._pIBonusDamMod + plr[v8]._pDamageMod + (v17 + v18) * plr[v8]._pIBonusDam / 100 + v17 + v18;
			if ( !_LOBYTE(plr[v8]._pClass) )
			{
				v21 = plr[v8]._pLevel;
				_LOBYTE(v19) = 6;
				if ( random(v19, 100) < v21 )
					v20 *= 2;
			}
			v22 = v20 << 6;
			if ( plr[v8]._pIFlags & 2 )
			{
				_LOBYTE(v19) = 7;
				v23 = random(v19, v22 >> 3);
				v24 = plr[v8]._pMaxHP;
				v25 = &plr[v8]._pHitPoints;
				*v25 += v23;
				if ( plr[v8]._pHitPoints > v24 )
					*v25 = v24;
				v26 = &plr[v8]._pHPBase;
				v27 = plr[v8]._pMaxHPBase;
				*v26 += v23;
				if ( *v26 > v27 )
					*v26 = v27;
				drawhpflag = 1;
			}
			if ( v28 == myplr )
				NetSendCmdDamage(1u, bPlr, v22);
			StartPlrHit(arglist, v22, 0);
		}
		else
		{
			v16 = GetDirection(plr[v5].WorldX, plr[v5].WorldY, plr[v8].WorldX, plr[v8].WorldY);
			StartPlrBlock(arglist, v16);
		}
		v30 = 1;
	}
	return v30;
}

//----- (0044E669) --------------------------------------------------------
unsigned char __fastcall PlrHitObj(int pnum, int mx, int my)
{
	char v3; // dl
	int v4; // edx

	v3 = dObject[mx][my];
	if ( v3 <= 0 )
		v4 = -1 - v3;
	else
		v4 = v3 - 1;
	if ( _LOBYTE(object[v4]._oBreak) != 1 )
		return 0;
	BreakObject(pnum, v4);
	return 1;
}

//----- (0044E6A6) --------------------------------------------------------
int __fastcall PM_DoAttack(int pnum)
{
	int v1; // esi
	int v2; // esi
	int v3; // ecx
	int v4; // eax
	int v5; // eax
	int v6; // ebx
	int v7; // edi
	int v8; // eax
	int v9; // edx
	int v10; // ecx
	int v11; // eax
	int v12; // edx
	int v13; // eax
	int v14; // eax
	int v15; // edx
	char v16; // al
	int v17; // eax
	int v19; // [esp+Ch] [ebp-8h]
	int arglist; // [esp+10h] [ebp-4h]

	v1 = pnum;
	arglist = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoAttack: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v2]._pIFlags;
	v4 = plr[v2]._pAnimFrame;
	if ( v3 & 0x20000 && v4 == 1 )
		plr[v2]._pAnimFrame = 2;
	if ( v3 & 0x40000 && (v4 == 1 || v4 == 3) )
		++plr[v2]._pAnimFrame;
	if ( v3 & 0x80000 && (v4 == 1 || v4 == 3 || v4 == 5) )
		++plr[v2]._pAnimFrame;
	if ( v3 & 0x100000 && (v4 == 1 || v4 == 4) )
		plr[v2]._pAnimFrame += 2;
	if ( plr[v2]._pAnimFrame == plr[v2]._pAFNum - 1 )
		PlaySfxLoc(PS_SWING, plr[v2].WorldX, plr[v2].WorldY);
	if ( plr[v2]._pAnimFrame != plr[v2]._pAFNum )
		goto LABEL_49;
	v5 = plr[v2]._pdir;
	v6 = plr[v2].WorldX + offset_x[v5];
	v7 = plr[v2].WorldY + offset_y[v5];
	v8 = v7 + 112 * v6;
	v19 = v8;
	v9 = dMonster[0][v8];
	if ( !v9 )
	{
LABEL_29:
		if ( plr[v2]._pIFlags & 0x10 )
		{
			AddMissile(v6, v7, 1, 0, 0, 64, 0, arglist, 0, 0);
			v8 = v19;
		}
		if ( plr[v2]._pIFlags & 0x20 )
		{
			AddMissile(v6, v7, 2, 0, 0, 64, 0, arglist, 0, 0);
			v8 = v19;
		}
		v12 = dMonster[0][v8];
		if ( v12 )
		{
			if ( v12 <= 0 )
				v13 = -1 - v12;
			else
				v13 = v12 - 1;
			_LOBYTE(v14) = PlrHitMonst(arglist, v13);
			goto LABEL_46;
		}
		v15 = (unsigned char)dPlayer[0][v8];
		if ( (_BYTE)v15 && !FriendlyMode )
		{
			if ( (char)v15 <= 0 )
				v16 = -1 - v15;
			else
				v16 = v15 - 1;
			_LOBYTE(v14) = PlrHitPlr(arglist, v16);
LABEL_46:
			if ( v14 )
			{
				_LOBYTE(v17) = WeaponDur(arglist, 30);
				if ( v17 )
					goto LABEL_48;
			}
			goto LABEL_49;
		}
		if ( dObject[0][v8] > 0 )
		{
			_LOBYTE(v14) = PlrHitObj(arglist, v6, v7);
			goto LABEL_46;
		}
LABEL_49:
		if ( plr[v2]._pAnimFrame != plr[v2]._pAFrames )
			return 0;
LABEL_48:
		StartStand(arglist, plr[v2]._pdir);
		ClearPlrPVars(arglist);
		return 1;
	}
	if ( v9 <= 0 )
		v10 = -1 - v9;
	else
		v10 = v9 - 1;
	_LOBYTE(v11) = CanTalkToMonst(v10);
	if ( !v11 )
	{
		v8 = v19;
		goto LABEL_29;
	}
	plr[v2]._pVar1 = 0;
	return 0;
}
// 484368: using guessed type int FriendlyMode;

//----- (0044E8B8) --------------------------------------------------------
int __fastcall PM_DoRangeAttack(int pnum)
{
	int v1; // edi
	int v2; // esi
	int v3; // ecx
	int v4; // eax
	int v5; // eax
	int v6; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoRangeAttack: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pIFlags;
	v4 = plr[v1]._pAnimFrame;
	if ( v3 & 0x20000 && v4 == 1 )
		plr[v2]._pAnimFrame = 2;
	if ( v3 & 0x40000 && (v4 == 1 || v4 == 3) )
		++plr[v2]._pAnimFrame;
	if ( plr[v2]._pAnimFrame != plr[v2]._pAFNum )
		goto LABEL_21;
	v5 = 0;
	if ( v3 & 8 )
		v5 = 27;
	if ( v3 & 0x2000000 )
		v5 = 56;
	AddMissile(plr[v2].WorldX, plr[v2].WorldY, plr[v2]._pVar1, plr[v2]._pVar2, plr[v2]._pdir, v5, 0, v1, 4, 0);
	PlaySfxLoc(PS_BFIRE, plr[v2].WorldX, plr[v2].WorldY);
	_LOBYTE(v6) = WeaponDur(v1, 40);
	if ( !v6 )
	{
LABEL_21:
		if ( plr[v2]._pAnimFrame < plr[v2]._pAFrames )
			return 0;
	}
	StartStand(v1, plr[v2]._pdir);
	ClearPlrPVars(v1);
	return 1;
}

//----- (0044E9AC) --------------------------------------------------------
void __fastcall ShieldDur(int pnum)
{
	int v1; // edi
	int v2; // esi
	int v3; // ecx
	int v4; // ecx
	int v5; // ecx
	int v6; // ecx

	v1 = pnum;
	if ( pnum == myplr )
	{
		if ( (unsigned int)pnum >= 4 )
			TermMsg("ShieldDur: illegal player %d", pnum);
		v2 = v1;
		if ( plr[v1].InvBody[4]._itype == ITYPE_SHIELD )
		{
			v3 = plr[v2].InvBody[4]._iDurability;
			if ( v3 == 255 )
				return;
			v4 = v3 - 1;
			plr[v2].InvBody[4]._iDurability = v4;
			if ( !v4 )
			{
				NetSendCmdDelItem(1u, 4u);
				plr[v2].InvBody[4]._itype = ITYPE_NONE;
				CalcPlrInv(v1, 1u);
			}
		}
		if ( plr[v2].InvBody[5]._itype == ITYPE_SHIELD )
		{
			v5 = plr[v2].InvBody[5]._iDurability;
			if ( v5 != 255 )
			{
				v6 = v5 - 1;
				plr[v2].InvBody[5]._iDurability = v6;
				if ( !v6 )
				{
					NetSendCmdDelItem(1u, 5u);
					plr[v2].InvBody[5]._itype = ITYPE_NONE;
					CalcPlrInv(v1, 1u);
				}
			}
		}
	}
}

//----- (0044EA4D) --------------------------------------------------------
int __fastcall PM_DoBlock(int pnum)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoBlock: illegal player %d", pnum);
	v2 = v1;
	if ( plr[v1]._pIFlags & 0x1000000 && plr[v2]._pAnimFrame != 1 )
		plr[v2]._pAnimFrame = plr[v2]._pBFrames;
	if ( plr[v2]._pAnimFrame < plr[v2]._pBFrames )
		return 0;
	StartStand(v1, plr[v2]._pdir);
	ClearPlrPVars(v1);
	_LOBYTE(v3) = 3;
	if ( !random(v3, 10) )
		ShieldDur(v1);
	return 1;
}

//----- (0044EAC6) --------------------------------------------------------
int __fastcall PM_DoSpell(int pnum)
{
	int v1; // edi
	int v2; // esi

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoSpell: illegal player %d", pnum);
	v2 = v1;
	if ( plr[v1]._pVar8 == plr[v1]._pSFNum )
	{
		CastSpell(
			v1,
			plr[v2]._pSpell,
			plr[v2].WorldX,
			plr[v2].WorldY,
			plr[v2]._pVar1,
			plr[v2]._pVar2,
			0,
			plr[v2]._pVar4);
		if ( !plr[v2]._pSplFrom )
		{
			if ( _LOBYTE(plr[v2]._pRSplType) == 2
			  && !(plr[v2]._pScrlSpells[1] & ((unsigned __int64)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1)) >> 32) | plr[v2]._pScrlSpells[0] & (unsigned int)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1))) )
			{
				plr[v2]._pRSpell = -1;
				_LOBYTE(plr[v2]._pRSplType) = 4;
				force_redraw = 255;
			}
			if ( _LOBYTE(plr[v2]._pRSplType) == 3
			  && !(plr[v2]._pISpells[1] & ((unsigned __int64)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1)) >> 32) | plr[v2]._pISpells[0] & (unsigned int)(1i64 << (_LOBYTE(plr[v2]._pRSpell) - 1))) )
			{
				plr[v2]._pRSpell = -1;
				_LOBYTE(plr[v2]._pRSplType) = 4;
				force_redraw = 255;
			}
		}
	}
	++plr[v2]._pVar8;
	if ( leveltype )
	{
		if ( plr[v2]._pAnimFrame == plr[v2]._pSFrames )
		{
			StartStand(v1, plr[v2]._pdir);
			goto LABEL_16;
		}
	}
	else if ( plr[v2]._pVar8 > plr[v2]._pSFrames )
	{
		StartWalkStand(v1);
LABEL_16:
		ClearPlrPVars(v1);
		return 1;
	}
	return 0;
}
// 52571C: using guessed type int force_redraw;
// 5BB1ED: using guessed type char leveltype;

//----- (0044EC06) --------------------------------------------------------
int __fastcall PM_DoGotHit(int pnum)
{
	int v1; // esi
	int v2; // eax
	int v3; // edx
	int v4; // ecx
	int v5; // ecx

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoGotHit: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pIFlags;
	v4 = plr[v1]._pAnimFrame;
	if ( v3 & 0x200000 && v4 == 3 )
		plr[v2]._pAnimFrame = 4;
	if ( v3 & 0x400000 && (v4 == 3 || v4 == 5) )
		++plr[v2]._pAnimFrame;
	if ( v3 & 0x800000 && (v4 == 1 || v4 == 3 || v4 == 5) )
		++plr[v2]._pAnimFrame;
	if ( plr[v2]._pAnimFrame < plr[v2]._pHFrames )
		return 0;
	StartStand(v1, plr[v2]._pdir);
	ClearPlrPVars(v1);
	_LOBYTE(v5) = 3;
	if ( random(v5, 4) )
		ArmorDur(v1);
	return 1;
}

//----- (0044ECBC) --------------------------------------------------------
void __fastcall ArmorDur(int pnum)
{
	int v1; // ebp
	int v2; // ST04_4
	PlayerStruct *v3; // esi
	int v4; // eax
	int v5; // edi
	int v6; // esi
	int v7; // ecx
	int v8; // ecx
	unsigned char v9; // dl

	v1 = pnum;
	if ( pnum == myplr )
	{
		if ( (unsigned int)pnum >= 4 )
		{
			TermMsg("ArmorDur: illegal player %d", pnum);
			pnum = v2;
		}
		v3 = &plr[v1];
		if ( v3->InvBody[6]._itype != -1 || v3->InvBody[0]._itype != -1 )
		{
			_LOBYTE(pnum) = 8;
			v4 = random(pnum, 3);
			v5 = v3->InvBody[6]._itype;
			if ( v5 == -1 )
				goto LABEL_23;
			if ( v3->InvBody[0]._itype == -1 )
				v4 = 1;
			if ( v5 == -1 )
			{
LABEL_23:
				if ( v3->InvBody[0]._itype != -1 )
					v4 = 0;
			}
			if ( v4 )
				v6 = (int)&v3->InvBody[6];
			else
				v6 = (int)v3->InvBody;
			v7 = *(_DWORD *)(v6 + 236);
			if ( v7 != 255 )
			{
				v8 = v7 - 1;
				*(_DWORD *)(v6 + 236) = v8;
				if ( !v8 )
				{
					if ( v4 )
						v9 = 6;
					else
						v9 = 0;
					NetSendCmdDelItem(1u, v9);
					*(_DWORD *)(v6 + 8) = -1;
					CalcPlrInv(v1, 1u);
				}
			}
		}
	}
}

//----- (0044ED7B) --------------------------------------------------------
int __fastcall PM_DoDeath(int pnum)
{
	int v1; // edi
	int v2; // esi
	int v3; // ecx
	int v4; // eax
	int v5; // eax

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PM_DoDeath: illegal player %d", pnum);
	v2 = v1;
	if ( plr[v1]._pVar8 >= 2 * plr[v1]._pDFrames )
	{
		if ( deathdelay > 1 && v1 == myplr && --deathdelay == 1 )
		{
			*(_DWORD *)&deathflag = 1;
			if ( gbMaxPlayers == 1 )
				gamemenu_previous();
		}
		v3 = plr[v2].WorldY;
		plr[v2]._pAnimFrame = plr[v2]._pAnimLen;
		v4 = plr[v2].WorldX;
		plr[v2]._pAnimDelay = 10000;
		dFlags[v4][v3] |= 4u;
	}
	v5 = plr[v2]._pVar8;
	if ( v5 < 100 )
		plr[v2]._pVar8 = v5 + 1;
	return 0;
}
// 679660: using guessed type char gbMaxPlayers;
// 69B7C4: using guessed type int deathdelay;

//----- (0044EE22) --------------------------------------------------------
void __fastcall CheckNewPath(int pnum)
{
	int v1; // edi
	int v2; // ebx
	int v3; // eax
	int v4; // ecx
	bool v5; // zf
	int v6; // eax
	int v7; // esi
	int v8; // eax
	int v9; // edx
	int v10; // esi
	int v11; // esi
	int v12; // eax
	int v13; // eax
	int v14; // ecx
	int v15; // edx
	int v16; // eax
	int v17; // eax
	int v18; // eax
	int v19; // ecx
	int v20; // eax
	int v21; // edi
	int v22; // esi
	int v23; // ST38_4
	int v24; // eax
	int v25; // esi
	int v26; // esi
	int v27; // ST38_4
	int v28; // eax
	int v29; // ecx
	int v30; // edx
	int v31; // ecx
	int *v32; // esi
	int *v33; // edi
	int v34; // esi
	int v35; // eax
	int v36; // ecx
	int v37; // eax
	int v38; // eax
	int v39; // eax
	int v40; // eax
	int v41; // eax
	int *v42; // esi
	int *v43; // edi
	int v44; // eax
	int v45; // eax
	int v46; // esi
	int v47; // esi
	int v48; // eax
	int v49; // ecx
	int v50; // esi
	int v51; // eax
	int v52; // ecx
	int v53; // edi
	int v54; // esi
	int v55; // ST38_4
	int v56; // eax
	int v57; // edi
	int v58; // esi
	int v59; // ST38_4
	int v60; // eax
	int v61; // eax
	int v62; // ecx
	int v63; // esi
	int v64; // ST38_4
	int v65; // eax
	int v66; // esi
	int v67; // edi
	int v68; // eax
	int v69; // esi
	int v70; // esi
	int v71; // eax
	int v72; // ecx
	int v73; // eax
	int v74; // eax
	int *v75; // esi
	int *v76; // edi
	int v77; // eax
	int v78; // eax
	int v79; // eax
	int v80; // eax
	int *v81; // esi
	int *v82; // edi
	int v83; // eax
	int v84; // eax
	int v85; // eax
	int v86; // [esp-18h] [ebp-34h]
	int v87; // [esp-10h] [ebp-2Ch]
	int v88; // [esp-10h] [ebp-2Ch]
	int v89; // [esp-Ch] [ebp-28h]
	int v90; // [esp-Ch] [ebp-28h]
	int v91; // [esp-8h] [ebp-24h]
	int v92; // [esp-8h] [ebp-24h]
	int v93; // [esp-8h] [ebp-24h]
	int v94; // [esp-4h] [ebp-20h]
	int v95; // [esp-4h] [ebp-20h]
	int v96; // [esp-4h] [ebp-20h]
	signed int v97; // [esp+Ch] [ebp-10h]
	int arglist; // [esp+10h] [ebp-Ch]
	int arglista; // [esp+10h] [ebp-Ch]
	int arglistb; // [esp+10h] [ebp-Ch]
	int v101; // [esp+14h] [ebp-8h]
	int v102; // [esp+14h] [ebp-8h]
	int v103; // [esp+14h] [ebp-8h]
	int v104; // [esp+14h] [ebp-8h]
	int p; // [esp+18h] [ebp-4h]

	v1 = pnum;
	p = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("CheckNewPath: illegal player %d", pnum);
	v2 = v1;
	if ( plr[v1].destAction == 20 )
		MakePlrPath(v1, monster[plr[v2].destParam1]._mfutx, monster[plr[v2].destParam1]._mfuty, 0);
	if ( plr[v2].destAction == 21 )
		MakePlrPath(v1, plr[plr[v2].destParam1]._px, plr[plr[v2].destParam1]._py, 0);
	if ( plr[v2].walkpath[0] == -1 )
	{
		v18 = plr[v2].destAction;
		if ( v18 == -1 )
			return;
		v19 = plr[v2]._pmode;
		if ( v19 == PM_STAND )
		{
			switch ( v18 )
			{
				case 9:
					v20 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, plr[v2].destParam1, plr[v2].destParam2);
					goto LABEL_52;
				case 10:
					v30 = plr[v2].WorldY;
					v31 = plr[v2].WorldX;
					v32 = &plr[v2].destParam2;
					v33 = &plr[v2].destParam1;
					goto LABEL_59;
				case 12:
					v39 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, plr[v2].destParam1, plr[v2].destParam2);
					StartSpell(p, v39, plr[v2].destParam1, plr[v2].destParam2);
					v40 = plr[v2].destParam3;
					goto LABEL_66;
				case 13:
					v46 = plr[v2].destParam1;
					arglista = v46;
					v47 = v46;
					v102 = abs(plr[v2].WorldX - object[v47]._ox);
					v48 = abs(plr[v2].WorldY - object[v47]._oy);
					if ( v48 > 1 )
					{
						v49 = object[v47]._oy;
						if ( dungeon[39][112 * object[v47]._ox + 39 + v49] == -1 - arglista )
							v48 = abs(plr[v2].WorldY - v49 + 1);
					}
					if ( v102 > 1 || v48 > 1 )
						break;
					if ( _LOBYTE(object[v47]._oBreak) != 1 )
						goto LABEL_73;
					goto LABEL_80;
				case 14:
					v50 = plr[v2].destParam1;
					arglista = v50;
					v47 = v50;
					v103 = abs(plr[v2].WorldX - object[v47]._ox);
					v51 = abs(plr[v2].WorldY - object[v47]._oy);
					if ( v51 > 1 )
					{
						v52 = object[v47]._oy;
						if ( dungeon[39][112 * object[v47]._ox + 39 + v52] == -1 - arglista )
							v51 = abs(plr[v2].WorldY - v52 + 1);
					}
					if ( v103 > 1 || v51 > 1 )
						break;
					if ( _LOBYTE(object[v47]._oBreak) == 1 )
					{
LABEL_80:
						v20 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, object[v47]._ox, object[v47]._oy);
LABEL_81:
						v29 = p;
LABEL_82:
						StartAttack(v29, v20);
					}
					else
					{
						TryDisarm(p, arglista);
LABEL_73:
						OperateObject(p, arglista, 0);
					}
					break;
				case 15:
					if ( v1 == myplr )
					{
						v53 = plr[v2].destParam1;
						v54 = plr[v2].destParam1;
						v55 = abs(plr[v2].WorldX - items[v54]._ix);
						v56 = abs(plr[v2].WorldY - items[v54]._iy);
						if ( v55 <= 1 && v56 <= 1 && pcurs == 1 && !items[v54]._iRequest )
						{
							NetSendCmdGItem(1u, CMD_REQUESTGITEM, myplr, myplr, v53);
							items[v54]._iRequest = 1;
						}
					}
					break;
				case 16:
					if ( v1 == myplr )
					{
						v57 = plr[v2].destParam1;
						v58 = plr[v2].destParam1;
						v59 = abs(plr[v2].WorldX - items[v58]._ix);
						v60 = abs(plr[v2].WorldY - items[v58]._iy);
						if ( v59 <= 1 && v60 <= 1 && pcurs == 1 )
							NetSendCmdGItem(1u, CMD_REQUESTAGITEM, myplr, myplr, v57);
					}
					break;
				case 17:
					if ( v1 == myplr )
						TalkToTowner(v1, plr[v2].destParam1);
					break;
				case 18:
					if ( _LOBYTE(object[plr[v2].destParam1]._oBreak) != 1 )
						OperateObject(v1, plr[v2].destParam1, 1u);
					break;
				case 20:
					v21 = plr[v2].destParam1;
					v22 = plr[v2].destParam1;
					v23 = abs(plr[v2].WorldX - monster[v22]._mfutx);
					v24 = abs(plr[v2].WorldY - monster[v22]._mfuty);
					if ( v23 > 1 || v24 > 1 )
						break;
					v20 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v22]._mfutx, monster[v22]._mfuty);
					v25 = monster[v22].mtalkmsg;
					if ( v25 && v25 != TEXT_LAZ1_2 )
						goto LABEL_56;
					goto LABEL_81;
				case 21:
					v26 = plr[v2].destParam1;
					v27 = abs(plr[v2].WorldX - plr[v26]._px);
					v28 = abs(plr[v2].WorldY - plr[v26]._py);
					if ( v27 > 1 || v28 > 1 )
						break;
					v20 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v26]._px, plr[v26]._py);
LABEL_52:
					v29 = v1;
					goto LABEL_82;
				case 22:
					v21 = plr[v2].destParam1;
					v34 = plr[v2].destParam1;
					v35 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v34]._mfutx, monster[v34]._mfuty);
					v36 = monster[v34].mtalkmsg;
					if ( v36 && v36 != TEXT_LAZ1_2 )
LABEL_56:
						TalktoMonster(v21);
					else
						StartRangeAttack(p, v35, monster[v34]._mfutx, monster[v34]._mfuty);
					break;
				case 23:
					v30 = plr[v2]._py;
					v37 = plr[v2].destParam1;
					v31 = plr[v2]._px;
					v32 = &plr[v37]._py;
					v33 = &plr[v37]._px;
LABEL_59:
					v38 = GetDirection(v31, v30, *v33, *v32);
					StartRangeAttack(p, v38, *v33, *v32);
					break;
				case 24:
					v41 = plr[v2].destParam1;
					v42 = &monster[v41]._mfuty;
					v43 = &monster[v41]._mfutx;
					goto LABEL_65;
				case 25:
					v44 = plr[v2].destParam1;
					v42 = &plr[v44]._py;
					v43 = &plr[v44]._px;
LABEL_65:
					v45 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v43, *v42);
					StartSpell(p, v45, *v43, *v42);
					v40 = plr[v2].destParam2;
					goto LABEL_66;
				case 26:
					StartSpell(v1, plr[v2].destParam3, plr[v2].destParam1, plr[v2].destParam2);
					plr[v2]._pVar3 = plr[v2].destParam3;
					v40 = plr[v2].destParam4;
LABEL_66:
					plr[v2]._pVar4 = v40;
					break;
				default:
					break;
			}
			FixPlayerLocation(p, plr[v2]._pdir);
			goto LABEL_143;
		}
		if ( v19 == 4 && plr[v2]._pAnimFrame > plr[myplr]._pAFNum )
		{
			switch ( v18 )
			{
				case 9:
					v61 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v2].destParam1, plr[v2].destParam2);
LABEL_105:
					v62 = v1;
LABEL_106:
					StartAttack(v62, v61);
LABEL_107:
					plr[v2].destAction = -1;
					break;
				case 20:
					v63 = plr[v2].destParam1;
					v64 = abs(plr[v2].WorldX - monster[v63]._mfutx);
					v65 = abs(plr[v2].WorldY - monster[v63]._mfuty);
					if ( v64 > 1 || v65 > 1 )
						goto LABEL_107;
					v61 = GetDirection(plr[v2]._px, plr[v2]._py, monster[v63]._mfutx, monster[v63]._mfuty);
					goto LABEL_105;
				case 21:
					v66 = plr[v2].destParam1;
					v67 = abs(plr[v2].WorldX - plr[v66]._px);
					v68 = abs(plr[v2].WorldY - plr[v66]._py);
					if ( v67 > 1 || v68 > 1 )
						goto LABEL_107;
					v61 = GetDirection(plr[v2]._px, plr[v2]._py, plr[v66]._px, plr[v66]._py);
					v62 = p;
					goto LABEL_106;
				case 13:
					v69 = plr[v2].destParam1;
					arglistb = v69;
					v70 = v69;
					v104 = abs(plr[v2].WorldX - object[v70]._ox);
					v71 = abs(plr[v2].WorldY - object[v70]._oy);
					if ( v71 > 1 )
					{
						v72 = object[v70]._oy;
						if ( dungeon[39][112 * object[v70]._ox + 39 + v72] == -1 - arglistb )
							v71 = abs(plr[v2].WorldY - v72 + 1);
					}
					if ( v104 <= 1 && v71 <= 1 )
					{
						if ( _LOBYTE(object[v70]._oBreak) == 1 )
						{
							v73 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, object[v70]._ox, object[v70]._oy);
							StartAttack(p, v73);
						}
						else
						{
							OperateObject(p, arglistb, 0);
						}
					}
					break;
			}
		}
		if ( plr[v2]._pmode == PM_RATTACK && plr[v2]._pAnimFrame > plr[myplr]._pAFNum )
		{
			v74 = plr[v2].destAction;
			switch ( v74 )
			{
				case 10:
					v75 = &plr[v2].destParam2;
					v76 = &plr[v2].destParam1;
LABEL_133:
					v79 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v76, *v75);
					StartRangeAttack(p, v79, *v76, *v75);
					plr[v2].destAction = -1;
					break;
				case 22:
					v77 = plr[v2].destParam1;
					v75 = &monster[v77]._mfuty;
					v76 = &monster[v77]._mfutx;
					goto LABEL_133;
				case 23:
					v78 = plr[v2].destParam1;
					v75 = &plr[v78]._py;
					v76 = &plr[v78]._px;
					goto LABEL_133;
			}
		}
		if ( plr[v2]._pmode == PM_SPELL && plr[v2]._pAnimFrame > plr[v2]._pSFNum )
		{
			v80 = plr[v2].destAction;
			switch ( v80 )
			{
				case 12:
					v81 = &plr[v2].destParam2;
					v82 = &plr[v2].destParam1;
					break;
				case 24:
					v83 = plr[v2].destParam1;
					v81 = &monster[v83]._mfuty;
					v82 = &monster[v83]._mfutx;
					break;
				case 25:
					v84 = plr[v2].destParam1;
					v81 = &plr[v84]._py;
					v82 = &plr[v84]._px;
					break;
				default:
					return;
			}
			v85 = GetDirection(plr[v2].WorldX, plr[v2].WorldY, *v82, *v81);
			StartSpell(p, v85, *v82, *v81);
			goto LABEL_143;
		}
		return;
	}
	if ( plr[v2]._pmode == PM_STAND )
	{
		if ( v1 == myplr )
		{
			v3 = plr[v2].destAction;
			if ( v3 == 20 || v3 == 21 )
			{
				v4 = plr[v2].destParam1;
				v5 = v3 == 20;
				v6 = plr[v2]._px;
				arglist = plr[v2].destParam1;
				if ( v5 )
				{
					v7 = v4;
					v101 = abs(v6 - monster[v4]._mfutx);
					v8 = abs(plr[v2]._py - monster[v7]._mfuty);
					v9 = plr[v2]._py;
					v94 = monster[v7]._mfuty;
					v91 = monster[v7]._mfutx;
				}
				else
				{
					v10 = v4;
					v101 = abs(v6 - plr[v4]._px);
					v8 = abs(plr[v2]._py - plr[v10]._py);
					v9 = plr[v2]._py;
					v94 = plr[v10]._py;
					v91 = plr[v10]._px;
				}
				v97 = v8;
				v11 = GetDirection(plr[v2]._px, v9, v91, v94);
				if ( v101 < 2 && v97 < 2 )
				{
					ClrPlrPath(p);
					v12 = monster[arglist].mtalkmsg;
					if ( v12 && v12 != TEXT_LAZ1_2 )
						TalktoMonster(arglist);
					else
						StartAttack(p, v11);
					plr[v2].destAction = -1;
				}
			}
		}
		if ( currlevel )
		{
			v13 = SLOBYTE(plr[v2]._pClass);
			v14 = PWVel[v13][0];
			v15 = PWVel[v13][1];
			v16 = PWVel[v13][2];
		}
		else
		{
			v14 = 2048;
			v15 = 1024;
			v16 = 512;
		}
		switch ( plr[v2].walkpath[0] )
		{
			case WALK_NE:
				v95 = 2;
				v92 = DIR_NE;
				v89 = -1;
				v87 = 0;
				v17 = -v16;
				goto LABEL_37;
			case WALK_NW:
				v95 = 8;
				v92 = DIR_NW;
				v89 = 0;
				v87 = -1;
				v17 = -v16;
				v15 = -v15;
LABEL_37:
				StartWalk(p, v15, v17, v87, v89, v92, v95);
				break;
			case WALK_SE:
				v96 = 4;
				v93 = DIR_SE;
				v90 = 0;
				v88 = 1;
				v86 = -32;
				goto LABEL_32;
			case WALK_SW:
				v96 = 6;
				v93 = DIR_SW;
				v90 = 1;
				v88 = 0;
				v86 = 32;
				v15 = -v15;
LABEL_32:
				StartWalk2(p, v15, v16, v86, -16, v88, v90, v93, v96);
				break;
			case WALK_N:
				StartWalk(p, 0, -v15, -1, -1, DIR_N, 1);
				break;
			case WALK_E:
				StartWalk3(p, v14, 0, -32, -16, 1, -1, 1, 0, DIR_E, 3);
				break;
			case WALK_S:
				StartWalk2(p, 0, v15, 0, -32, 1, 1, DIR_S, 5);
				break;
			case WALK_W:
				StartWalk3(p, -v14, 0, 32, -16, -1, 1, 0, 1, DIR_W, 7);
				break;
			default:
				break;
		}
		qmemcpy(plr[v2].walkpath, &plr[v2].walkpath[1], 0x18u);
		plr[v2].walkpath[24] = -1;
		if ( plr[v2]._pmode == PM_STAND )
		{
			StartStand(p, plr[v2]._pdir);
LABEL_143:
			plr[v2].destAction = -1;
			return;
		}
	}
}

//----- (0044F9BA) --------------------------------------------------------
unsigned char __fastcall PlrDeathModeOK(int pnum)
{
	int v1; // esi
	unsigned char result; // al
	int v3; // esi

	v1 = pnum;
	if ( pnum != myplr )
		goto LABEL_10;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("PlrDeathModeOK: illegal player %d", pnum);
	v3 = plr[v1]._pmode;
	if ( v3 == PM_DEATH || v3 == PM_QUIT )
LABEL_10:
		result = 1;
	else
		result = v3 == PM_NEWLVL;
	return result;
}

//----- (0044F9FC) --------------------------------------------------------
void __cdecl ValidatePlayer()
{
	int v0; // edi
	int v1; // esi
	char *v2; // eax
	int v3; // ecx
	int v4; // ecx
	int *v5; // eax
	int v6; // eax
	int v7; // edx
	int v8; // edx
	int v9; // edx
	int v10; // eax
	int *v11; // ebx
	signed int v12; // edi
	char *v13; // eax
	__int64 v14; // [esp+Ch] [ebp-8h]

	v0 = 0;
	v14 = 0i64;
	if ( (unsigned int)myplr >= 4 )
		TermMsg("ValidatePlayer: illegal player %d", myplr);
	v1 = myplr;
	v2 = &plr[myplr]._pLevel;
	if ( *v2 > 50 )
		*v2 = 50;
	v3 = plr[v1]._pNextExper;
	if ( plr[v1]._pExperience > v3 )
		plr[v1]._pExperience = v3;
	v4 = 0;
	if ( plr[v1]._pNumInv > 0 )
	{
		v5 = &plr[v1].InvList[0]._ivalue;
		do
		{
			if ( *(v5 - 47) == 11 )
			{
				if ( *v5 > 5000 )
					*v5 = 5000;
				v4 += *v5;
			}
			++v0;
			v5 += 92;
		}
		while ( v0 < plr[v1]._pNumInv );
	}
	if ( v4 != plr[v1]._pGold )
		plr[v1]._pGold = v4;
	v6 = SLOBYTE(plr[v1]._pClass);
	v7 = MaxStats[v6][0];
	if ( plr[v1]._pBaseStr > v7 )
		plr[v1]._pBaseStr = v7;
	v8 = MaxStats[v6][1];
	if ( plr[v1]._pBaseMag > v8 )
		plr[v1]._pBaseMag = v8;
	v9 = MaxStats[v6][2];
	if ( plr[v1]._pBaseDex > v9 )
		plr[v1]._pBaseDex = v9;
	v10 = MaxStats[v6][3];
	if ( plr[v1]._pBaseVit > v10 )
		plr[v1]._pBaseVit = v10;
	v11 = &spelldata[1].sBookLvl;
	v12 = 1;
	do
	{
		if ( *v11 != -1 )
		{
			v14 |= 1i64 << ((unsigned char)v12 - 1);
			v13 = &plr[v1]._pSplLvl[v12];
			if ( *v13 > 15 )
				*v13 = 15;
		}
		v11 += 14;
		++v12;
	}
	while ( (signed int)v11 < (signed int)"Blood Star" );
	*(_QWORD *)plr[v1]._pMemSpells &= v14;
}

//----- (0044FB32) --------------------------------------------------------
void __cdecl ProcessPlayers()
{
	int v0; // eax
	int v1; // eax
	char *v2; // ecx
	char v3; // al
	int v4; // ebp
	int *v5; // esi
	int v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // eax
	int v10; // eax
	int v11; // edi
	int v12; // eax
	char *v13; // eax
	char *v14; // eax

	v0 = myplr;
	if ( (unsigned int)myplr >= 4 )
	{
		TermMsg("ProcessPlayers: illegal player %d", myplr);
		v0 = myplr;
	}
	v1 = v0;
	v2 = &plr[v1].pLvlLoad;
	v3 = plr[v1].pLvlLoad;
	if ( v3 )
		*v2 = v3 - 1;
	v4 = 0;
	if ( sfxdelay > 0 && !--sfxdelay )
		PlaySFX(sfxdnum);
	ValidatePlayer();
	v5 = &plr[0]._pHitPoints;
	do
	{
		v6 = (int)(v5 - 89);
		if ( *((_BYTE *)v5 - 379) && currlevel == *(_DWORD *)v6 && (v4 == myplr || !*(_BYTE *)(v6 + 267)) )
		{
			CheckCheatStats(v4);
			_LOBYTE(v7) = PlrDeathModeOK(v4);
			if ( !v7 && (signed int)(*v5 & 0xFFFFFFC0) <= 0 )
				SyncPlrKill(v4, -1);
			if ( v4 == myplr )
			{
				if ( v5[5294] & 0x40 && currlevel )
				{
					*v5 -= 4;
					v8 = *v5;
					*(v5 - 2) -= 4;
					if ( (signed int)(v8 & 0xFFFFFFC0) <= 0 )
						SyncPlrKill(v4, 0);
					drawhpflag = 1;
				}
				if ( *((_BYTE *)v5 + 21179) & 8 )
				{
					v9 = v5[3];
					if ( v9 > 0 )
					{
						v10 = v9 - v5[5];
						v5[5] = 0;
						drawmanaflag = 1;
						v5[3] = v10;
					}
				}
			}
			v11 = 0;
			do
			{
				switch ( *(v5 - 102) )
				{
					case PM_STAND:
						v12 = PM_DoNothing(v4);
						goto LABEL_38;
					case PM_WALK:
						v12 = PM_DoWalk(v4);
						goto LABEL_38;
					case PM_WALK2:
						v12 = PM_DoWalk2(v4);
						goto LABEL_38;
					case PM_WALK3:
						v12 = PM_DoWalk3(v4);
						goto LABEL_38;
					case PM_ATTACK:
						v12 = PM_DoAttack(v4);
						goto LABEL_38;
					case PM_RATTACK:
						v12 = PM_DoRangeAttack(v4);
						goto LABEL_38;
					case PM_BLOCK:
						v12 = PM_DoBlock(v4);
						goto LABEL_38;
					case PM_GOTHIT:
						v12 = PM_DoGotHit(v4);
						goto LABEL_38;
					case PM_DEATH:
						v12 = PM_DoDeath(v4);
						goto LABEL_38;
					case PM_SPELL:
						v12 = PM_DoSpell(v4);
						goto LABEL_38;
					case PM_NEWLVL:
						v12 = PM_DoNothing(v4);
LABEL_38:
						v11 = v12;
						break;
					default:
						break;
				}
				CheckNewPath(v4);
			}
			while ( v11 );
			v13 = (char *)(v5 - 69);
			++*(_DWORD *)v13;
			if ( *(v5 - 69) > *(v5 - 70) )
			{
				*(_DWORD *)v13 = 0;
				v14 = (char *)(v5 - 67);
				++*(_DWORD *)v14;
				if ( *(v5 - 67) > *(v5 - 68) )
					*(_DWORD *)v14 = 1;
			}
		}
		v5 += 5430;
		++v4;
	}
	while ( (signed int)v5 < (signed int)&plr_msgs[2].msg[51] );
}
// 52A554: using guessed type int sfxdelay;

//----- (0044FD31) --------------------------------------------------------
void __fastcall CheckCheatStats(int pnum)
{
	int v1; // ecx
	int *v2; // ecx

	v1 = pnum;
	if ( plr[v1]._pStrength > 750 )
		plr[v1]._pStrength = 750;
	if ( plr[v1]._pDexterity > 750 )
		plr[v1]._pDexterity = 750;
	if ( plr[v1]._pMagic > 750 )
		plr[v1]._pMagic = 750;
	if ( plr[v1]._pVitality > 750 )
		plr[v1]._pVitality = 750;
	if ( plr[v1]._pHitPoints > 128000 )
		plr[v1]._pHitPoints = 128000;
	v2 = &plr[v1]._pMana;
	if ( *v2 > 128000 )
		*v2 = 128000;
}

//----- (0044FD8A) --------------------------------------------------------
void __fastcall ClrPlrPath(int pnum)
{
	int v1; // esi

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("ClrPlrPath: illegal player %d", pnum);
	memset(plr[v1].walkpath, -1, 0x19u);
}

//----- (0044FDBA) --------------------------------------------------------
int __fastcall PosOkPlayer(int pnum, int px, int py)
{
	int v3; // esi
	int v4; // edi
	int v5; // edx
	int v6; // eax
	int v7; // esi
	char v8; // cl
	unsigned int v9; // ecx
	int v10; // esi
	char v11; // al
	char v12; // cl
	int result; // eax

	v3 = px;
	v4 = pnum;
	result = 0;
	if ( px >= 0 && px < 112 && py >= 0 && py < 112 && !SolidLoc(px, py) )
	{
		v6 = v3;
		v7 = 112 * v3 + v5;
		if ( dPiece[0][v7] )
		{
			v8 = dPlayer[v6][v5];
			if ( !v8 || (v8 <= 0 ? (v9 = -1 - v8) : (v9 = v8 - 1), v9 == v4 || v9 >= 4 || !plr[v9]._pHitPoints) )
			{
				v10 = dMonster[0][v7];
				if ( !v10 || currlevel && v10 > 0 && (signed int)(monstactive[57 * v10 + 182] & 0xFFFFFFC0) <= 0 )
				{
					v11 = dObject[v6][v5];
					if ( !v11 || (v11 <= 0 ? (v12 = -1 - v11) : (v12 = v11 - 1), !object[v12]._oSolidFlag) )
						result = 1;
				}
			}
		}
	}
	return result;
}

//----- (0044FE9E) --------------------------------------------------------
void __fastcall MakePlrPath(int pnum, int xx, int yy, unsigned char endspace)
{
	int v4; // esi
	int v5; // ebx
	int v6; // esi
	int v7; // edi
	int v8; // eax
	int v9; // eax
	int v10; // ecx
	int a2; // [esp+Ch] [ebp-4h]

	v4 = pnum;
	v5 = xx;
	a2 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("MakePlrPath: illegal player %d", pnum);
	v6 = v4;
	v7 = yy;
	v8 = plr[v6]._px;
	plr[v6]._ptargx = v5;
	plr[v6]._ptargy = yy;
	if ( v8 != v5 || plr[v6]._py != yy )
	{
		v9 = FindPath(PosOkPlayer, a2, v8, plr[v6]._py, v5, yy, plr[v6].walkpath);
		if ( v9 )
		{
			if ( !endspace )
			{
				v10 = *((char *)&plr[v6]._pmode + v9-- + 3);
				switch ( v10 )
				{
					case PM_WALK:
						goto LABEL_12;
					case PM_WALK2:
						++v5;
						break;
					case PM_WALK3:
						--v5;
						break;
					case PM_ATTACK:
						goto LABEL_15;
					case PM_RATTACK:
						++v5;
						goto LABEL_12;
					case PM_BLOCK:
						--v5;
LABEL_12:
						v7 = yy + 1;
						break;
					case PM_GOTHIT:
						--v5;
						goto LABEL_15;
					case PM_DEATH:
						++v5;
LABEL_15:
						v7 = yy - 1;
						break;
					default:
						break;
				}
				plr[v6]._ptargx = v5;
				plr[v6]._ptargy = v7;
			}
			plr[v6].walkpath[v9] = -1;
		}
	}
}

//----- (0044FF6F) --------------------------------------------------------
void __fastcall CheckPlrSpell()
{
	int v0; // ecx
	int v1; // eax
	int v2; // edx
	char v3; // al
	int v4; // ecx
	char v5; // al
	int v6; // eax
	int v7; // edx
	int v8; // esi
	int v9; // ST10_4
	int v10; // eax
	int v11; // eax
	int v12; // eax
	int v13; // ST10_4
	int v14; // eax
	char v15; // al

	v0 = myplr;
	if ( (unsigned int)myplr >= 4 )
	{
		TermMsg("CheckPlrSpell: illegal player %d", myplr);
		v0 = myplr;
	}
	v1 = 21720 * v0;
	v2 = plr[v0]._pRSpell;
	if ( v2 != -1 )
	{
		if ( !leveltype && !*(_DWORD *)&spelldata[v2].sTownSpell )
		{
			v5 = *((_BYTE *)&plr[0]._pClass + v1);
			switch ( v5 )
			{
				case UI_WARRIOR:
					v4 = PS_WARR27;
					goto LABEL_53;
				case UI_ROGUE:
					v4 = PS_ROGUE27;
					goto LABEL_53;
				case UI_SORCERER:
					v4 = PS_MAGE27;
					goto LABEL_53;
			}
			return;
		}
		if ( pcurs != CURSOR_HAND
		  || MouseY >= 352
		  || (chrflag && MouseX < 320 || invflag && MouseX > 320)
		  && v2 != 2
		  && v2 != 5
		  && v2 != 26
		  && v2 != 9
		  && v2 != 27 )
		{
			return;
		}
		_LOBYTE(v1) = *((_BYTE *)&plr[0]._pRSplType + v1);
		if ( (v1 & 0x80u) != 0 )
			goto LABEL_46;
		if ( (char)v1 <= 1 )
		{
			_LOBYTE(v6) = CheckSpell(v0, v2, v1, 0);
		}
		else
		{
			if ( (_BYTE)v1 != 2 )
			{
				if ( (_BYTE)v1 == 3 )
				{
					UseStaff();
					goto LABEL_36;
				}
LABEL_46:
				if ( _LOBYTE(plr[v0]._pRSplType) == 1 )
				{
					v15 = plr[v0]._pClass;
					switch ( v15 )
					{
						case UI_WARRIOR:
							v4 = PS_WARR35;
							goto LABEL_53;
						case UI_ROGUE:
							v4 = PS_ROGUE35;
							goto LABEL_53;
						case UI_SORCERER:
							v4 = PS_MAGE35;
							goto LABEL_53;
					}
				}
				return;
			}
			UseScroll();
		}
LABEL_36:
		v0 = myplr;
		if ( v6 )
		{
			v7 = plr[myplr]._pRSpell;
			if ( v7 == 6 )
			{
				v8 = GetDirection(plr[myplr].WorldX, plr[myplr].WorldY, cursmx, cursmy);
				v9 = GetSpellLevel(myplr, plr[myplr]._pRSpell);
				v10 = 21720 * myplr;
				_LOWORD(v10) = plr[myplr]._pRSpell;
				NetSendCmdLocParam3(1u, CMD_SPELLXYD, cursmx, cursmy, v10, v8, v9);
			}
			else if ( *(_DWORD *)&pcursmonst == -1 )
			{
				if ( pcursplr == -1 )
				{
					v13 = GetSpellLevel(myplr, v7);
					v14 = 21720 * myplr;
					_LOWORD(v14) = plr[myplr]._pRSpell;
					NetSendCmdLocParam2(1u, CMD_SPELLXY, cursmx, cursmy, v14, v13);
				}
				else
				{
					v12 = GetSpellLevel(myplr, v7);
					NetSendCmdParam3(1u, CMD_SPELLPID, pcursplr, plr[myplr]._pRSpell, v12);
				}
			}
			else
			{
				v11 = GetSpellLevel(myplr, v7);
				NetSendCmdParam3(1u, CMD_SPELLID, pcursmonst, plr[myplr]._pRSpell, v11);
			}
			return;
		}
		goto LABEL_46;
	}
	v3 = *((_BYTE *)&plr[0]._pClass + v1);
	switch ( v3 )
	{
		case UI_WARRIOR:
			v4 = PS_WARR34;
LABEL_53:
			PlaySFX(v4);
			return;
		case UI_ROGUE:
			v4 = PS_ROGUE34;
			goto LABEL_53;
		case UI_SORCERER:
			v4 = PS_MAGE34;
			goto LABEL_53;
	}
}
// 4B8CC2: using guessed type char pcursplr;
// 5BB1ED: using guessed type char leveltype;

//----- (00450217) --------------------------------------------------------
void __fastcall SyncPlrAnim(int pnum)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	int v4; // ecx
	int v5; // edx

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SyncPlrAnim: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pdir;
	switch ( plr[v1]._pmode )
	{
		case PM_STAND:
		case PM_NEWLVL:
		case PM_QUIT:
			v4 = plr[0]._peqN[v3 + 5430 * v1];
			goto LABEL_19;
		case PM_WALK:
		case PM_WALK2:
		case PM_WALK3:
			v4 = plr[0]._peqW[v3 + 5430 * v1];
			goto LABEL_19;
		case PM_ATTACK:
		case PM_RATTACK:
			v4 = plr[0]._peqA[v3 + 5430 * v1];
			goto LABEL_19;
		case PM_BLOCK:
			v4 = plr[0]._peqB[v3 + 5430 * v1];
			goto LABEL_19;
		case PM_GOTHIT:
			v4 = plr[0]._peqH[v3 + 5430 * v1];
			goto LABEL_19;
		case PM_DEATH:
			v4 = plr[0]._peqD[v3 + 5430 * v1];
			goto LABEL_19;
		case PM_SPELL:
			if ( v1 == myplr )
				v5 = (unsigned char)spelldata[plr[v2]._pSpell].sType;
			else
				v5 = 0;
			if ( !v5 )
				plr[v2]._pAnimData = plr[0]._peqS1_FM[v3 + 5430 * v1];
			if ( v5 == STYPE_LIGHTNING )
				plr[v2]._pAnimData = plr[0]._peqS2_LM[v3 + 5430 * v1];
			if ( v5 == STYPE_MAGIC )
			{
				v4 = plr[0]._peqS3_QM[v3 + 5430 * v1];
LABEL_19:
				plr[v2]._pAnimData = v4;
			}
			break;
		default:
			TermMsg("SyncPlrAnim");
			break;
	}
}

//----- (0045036D) --------------------------------------------------------
void __fastcall SyncInitPlrPos(int pnum)
{
	int v1; // esi
	bool v2; // zf
	unsigned int v3; // eax
	int v4; // ebx
	int v5; // edi
	int v6; // eax
	signed int v7; // [esp+Ch] [ebp-18h]
	int p; // [esp+10h] [ebp-14h]
	int v9; // [esp+14h] [ebp-10h]
	signed int v10; // [esp+18h] [ebp-Ch]
	signed int v11; // [esp+1Ch] [ebp-8h]
	unsigned int i; // [esp+20h] [ebp-4h]
	signed int v13; // [esp+20h] [ebp-4h]

	p = pnum;
	v1 = pnum;
	v2 = gbMaxPlayers == 1;
	plr[v1]._ptargx = plr[pnum].WorldX;
	plr[v1]._ptargy = plr[pnum].WorldY;
	if ( !v2 && plr[v1].plrlevel == currlevel )
	{
		v3 = 0;
		for ( i = 0; ; v3 = i )
		{
			v4 = plr[v1].WorldX + *(int *)((char *)plrxoff2 + v3);
			v5 = plr[v1].WorldY + *(int *)((char *)plryoff2 + v3);
			if ( PosOkPlayer(p, v4, v5) )
				break;
			i += 4;
			if ( i >= 0x20 )
				break;
		}
		if ( !PosOkPlayer(p, v4, v5) )
		{
			v11 = 0;
			v6 = -1;
			v13 = 1;
			v7 = -1;
			do
			{
				if ( v11 )
					break;
				v9 = v6;
				while ( v6 <= v13 && !v11 )
				{
					v5 = v9 + plr[v1].WorldY;
					v10 = v7;
					do
					{
						if ( v11 )
							break;
						v4 = v10 + plr[v1].WorldX;
						if ( PosOkPlayer(p, v10 + plr[v1].WorldX, v5) && !portal_pos_ok(currlevel, v4, v5) )
							v11 = 1;
						++v10;
					}
					while ( v10 <= v13 );
					v6 = ++v9;
				}
				++v13;
				v6 = v7-- - 1;
			}
			while ( v7 > -50 );
		}
		plr[v1].WorldX = v4;
		v2 = p == myplr;
		plr[v1].WorldY = v5;
		dPlayer[v4][v5] = p + 1;
		if ( v2 )
		{
			plr[v1]._px = v4;
			plr[v1]._py = v5;
			plr[v1]._ptargx = v4;
			plr[v1]._ptargy = v5;
			ViewX = v4;
			ViewY = v5;
		}
	}
}
// 679660: using guessed type char gbMaxPlayers;

//----- (004504E4) --------------------------------------------------------
void __fastcall SyncInitPlr(int pnum)
{
	int v1; // esi

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SyncInitPlr: illegal player %d", pnum);
	SetPlrAnims(v1);
	SyncInitPlrPos(v1);
}

//----- (00450508) --------------------------------------------------------
void __fastcall CheckStats(int pnum)
{
	int v1; // esi
	int v2; // eax
	char v3; // cl
	signed int v4; // esi
	signed int v5; // edi
	int v6; // edx
	int v7; // ecx
	int v8; // edx
	int v9; // ecx
	int v10; // edx
	int v11; // ecx
	int v12; // edx
	int v13; // ecx
	signed int v14; // [esp+Ch] [ebp-4h]

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("CheckStats: illegal player %d", pnum);
	v2 = v1;
	v3 = plr[v1]._pClass;
	if ( v3 )
	{
		if ( v3 == 1 )
		{
			v4 = 1;
		}
		else if ( v3 == 2 )
		{
			v4 = 2;
		}
		else
		{
			v4 = v14;
		}
	}
	else
	{
		v4 = 0;
	}
	v5 = 0;
	do
	{
		if ( v5 )
		{
			switch ( v5 )
			{
				case ATTRIB_MAG:
					v10 = plr[v2]._pBaseMag;
					v11 = MaxStats[v4][1];
					if ( v10 <= v11 )
					{
						if ( v10 < 0 )
							plr[v2]._pBaseMag = 0;
					}
					else
					{
						plr[v2]._pBaseMag = v11;
					}
					break;
				case ATTRIB_DEX:
					v8 = plr[v2]._pBaseDex;
					v9 = MaxStats[v4][2];
					if ( v8 <= v9 )
					{
						if ( v8 < 0 )
							plr[v2]._pBaseDex = 0;
					}
					else
					{
						plr[v2]._pBaseDex = v9;
					}
					break;
				case ATTRIB_VIT:
					v6 = plr[v2]._pBaseVit;
					v7 = MaxStats[v4][3];
					if ( v6 <= v7 )
					{
						if ( v6 < 0 )
							plr[v2]._pBaseVit = 0;
					}
					else
					{
						plr[v2]._pBaseVit = v7;
					}
					break;
			}
		}
		else
		{
			v12 = plr[v2]._pBaseStr;
			v13 = MaxStats[v4][0];
			if ( v12 <= v13 )
			{
				if ( v12 < 0 )
					plr[v2]._pBaseStr = 0;
			}
			else
			{
				plr[v2]._pBaseStr = v13;
			}
		}
		++v5;
	}
	while ( v5 < 4 );
}

//----- (00450621) --------------------------------------------------------
void __fastcall ModifyPlrStr(int pnum, int l)
{
	int v2; // esi
	int v3; // edi
	int v4; // esi
	char v5; // dl
	int v6; // ecx
	int v7; // eax
	int v8; // ebx
	int v9; // eax
	signed int v10; // ecx
	int p; // [esp+8h] [ebp-4h]

	v2 = pnum;
	v3 = l;
	p = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("ModifyPlrStr: illegal player %d", pnum);
	v4 = v2;
	v5 = plr[v4]._pClass;
	v6 = plr[v4]._pBaseStr;
	v7 = MaxStats[v5][0];
	if ( v6 + v3 > v7 )
		v3 = v7 - v6;
	plr[v4]._pBaseStr = v3 + v6;
	plr[v4]._pStrength += v3;
	v8 = plr[v4]._pStrength;
	if ( v5 == 1 )
	{
		v9 = plr[v4]._pLevel * (v8 + plr[v4]._pDexterity);
		v10 = 200;
	}
	else
	{
		v9 = v8 * plr[v4]._pLevel;
		v10 = 100;
	}
	plr[v4]._pDamageMod = v9 / v10;
	CalcPlrInv(p, 1u);
	if ( p == myplr )
		NetSendCmdParam1(0, CMD_SETSTR, plr[v4]._pBaseStr);
}

//----- (004506DB) --------------------------------------------------------
void __fastcall ModifyPlrMag(int pnum, int l)
{
	int v2; // esi
	int v3; // edi
	int v4; // esi
	char v5; // dl
	int v6; // ecx
	int v7; // eax
	int v8; // eax
	int v9; // edi
	int p; // [esp+8h] [ebp-4h]

	v2 = pnum;
	v3 = l;
	p = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("ModifyPlrMag: illegal player %d", pnum);
	v4 = v2;
	v5 = plr[v4]._pClass;
	v6 = MaxStats[v5][1];
	v7 = plr[v4]._pBaseMag;
	if ( v7 + v3 > v6 )
		v3 = v6 - v7;
	plr[v4]._pMagic += v3;
	v8 = v3 + v7;
	v9 = v3 << 6;
	plr[v4]._pBaseMag = v8;
	if ( v5 == 2 )
		v9 *= 2;
	plr[v4]._pMaxManaBase += v9;
	plr[v4]._pMaxMana += v9;
	if ( !(plr[v4]._pIFlags & 0x8000000) )
	{
		plr[v4]._pManaBase += v9;
		plr[v4]._pMana += v9;
	}
	CalcPlrInv(p, 1u);
	if ( p == myplr )
		NetSendCmdParam1(0, CMD_SETMAG, plr[v4]._pBaseMag);
}

//----- (00450788) --------------------------------------------------------
void __fastcall ModifyPlrDex(int pnum, int l)
{
	int v2; // ebx
	int v3; // edi
	int v4; // esi
	int v5; // ecx
	int v6; // eax

	v2 = pnum;
	v3 = l;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("ModifyPlrDex: illegal player %d", pnum);
	v4 = v2;
	v5 = MaxStats[SLOBYTE(plr[v2]._pClass)][2];
	v6 = plr[v2]._pBaseDex;
	if ( v6 + v3 > v5 )
		v3 = v5 - v6;
	plr[v4]._pDexterity += v3;
	plr[v4]._pBaseDex = v3 + v6;
	CalcPlrInv(v2, 1u);
	if ( _LOBYTE(plr[v4]._pClass) == 1 )
		plr[v4]._pDamageMod = plr[v4]._pLevel * (plr[v4]._pDexterity + plr[v4]._pStrength) / 200;
	if ( v2 == myplr )
		NetSendCmdParam1(0, CMD_SETDEX, plr[v4]._pBaseDex);
}

//----- (0045082C) --------------------------------------------------------
void __fastcall ModifyPlrVit(int pnum, int l)
{
	int v2; // esi
	int v3; // edi
	int v4; // esi
	char v5; // dl
	int v6; // ecx
	int v7; // eax
	int v8; // eax
	int v9; // edi
	int p; // [esp+8h] [ebp-4h]

	v2 = pnum;
	v3 = l;
	p = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("ModifyPlrVit: illegal player %d", pnum);
	v4 = v2;
	v5 = plr[v4]._pClass;
	v6 = MaxStats[v5][3];
	v7 = plr[v4]._pBaseVit;
	if ( v7 + v3 > v6 )
		v3 = v6 - v7;
	plr[v4]._pVitality += v3;
	v8 = v3 + v7;
	v9 = v3 << 6;
	plr[v4]._pBaseVit = v8;
	if ( !v5 )
		v9 *= 2;
	plr[v4]._pHPBase += v9;
	plr[v4]._pMaxHPBase += v9;
	plr[v4]._pHitPoints += v9;
	plr[v4]._pMaxHP += v9;
	CalcPlrInv(p, 1u);
	if ( p == myplr )
		NetSendCmdParam1(0, CMD_SETVIT, plr[v4]._pBaseVit);
}

//----- (004508CF) --------------------------------------------------------
void __fastcall SetPlayerHitPoints(int pnum, int newhp)
{
	int v2; // esi
	int v3; // edi
	int v4; // eax
	int v5; // ecx
	bool v6; // zf

	v2 = pnum;
	v3 = newhp;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SetPlayerHitPoints: illegal player %d", pnum);
	v4 = v2;
	v5 = plr[v2]._pMaxHPBase;
	plr[v4]._pHitPoints = v3;
	v6 = v2 == myplr;
	plr[v4]._pHPBase = v3 + v5 - plr[v2]._pMaxHP;
	if ( v6 )
		drawhpflag = 1;
}

//----- (0045091E) --------------------------------------------------------
void __fastcall SetPlrStr(int pnum, int v)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // eax
	signed int v6; // ecx

	v2 = pnum;
	v3 = v;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SetPlrStr: illegal player %d", pnum);
	v4 = v2;
	plr[v2]._pBaseStr = v3;
	CalcPlrInv(v2, 1u);
	if ( _LOBYTE(plr[v2]._pClass) == 1 )
	{
		v5 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity);
		v6 = 200;
	}
	else
	{
		v5 = plr[v4]._pStrength * plr[v4]._pLevel;
		v6 = 100;
	}
	plr[v4]._pDamageMod = v5 / v6;
}

//----- (00450993) --------------------------------------------------------
void __fastcall SetPlrMag(int pnum, int v)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax
	int v5; // esi

	v2 = pnum;
	v3 = v;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SetPlrMag: illegal player %d", pnum);
	v4 = v2;
	plr[v2]._pBaseMag = v3;
	v5 = v3 << 6;
	if ( _LOBYTE(plr[v2]._pClass) == 2 )
		v5 *= 2;
	plr[v4]._pMaxManaBase = v5;
	plr[v4]._pMaxMana = v5;
	CalcPlrInv(v2, 1u);
}

//----- (004509DF) --------------------------------------------------------
void __fastcall SetPlrDex(int pnum, int v)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // eax
	signed int v6; // ecx

	v2 = pnum;
	v3 = v;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SetPlrDex: illegal player %d", pnum);
	v4 = v2;
	plr[v2]._pBaseDex = v3;
	CalcPlrInv(v2, 1u);
	if ( _LOBYTE(plr[v2]._pClass) == 1 )
	{
		v5 = plr[v4]._pLevel * (plr[v4]._pStrength + plr[v4]._pDexterity);
		v6 = 200;
	}
	else
	{
		v5 = plr[v4]._pStrength * plr[v4]._pLevel;
		v6 = 100;
	}
	plr[v4]._pDamageMod = v5 / v6;
}

//----- (00450A54) --------------------------------------------------------
void __fastcall SetPlrVit(int pnum, int v)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax
	int v5; // esi

	v2 = pnum;
	v3 = v;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("SetPlrVit: illegal player %d", pnum);
	v4 = v2;
	plr[v2]._pBaseVit = v3;
	v5 = v3 << 6;
	if ( !_LOBYTE(plr[v2]._pClass) )
		v5 *= 2;
	plr[v4]._pHPBase = v5;
	plr[v4]._pMaxHPBase = v5;
	CalcPlrInv(v2, 1u);
}

//----- (00450AA0) --------------------------------------------------------
void __fastcall InitDungMsgs(int pnum)
{
	int v1; // esi

	v1 = pnum;
	if ( (unsigned int)pnum >= 4 )
		TermMsg("InitDungMsgs: illegal player %d", pnum);
	plr[v1].pDungMsgs = 0;
}

//----- (00450AC4) --------------------------------------------------------
void __cdecl PlayDungMsgs()
{
	int v0; // eax
	int v1; // eax
	char v2; // cl
	char v3; // dl
	char v4; // cl
	char v5; // cl
	char v6; // dl
	char v7; // cl
	char v8; // dl
	char v9; // cl
	char v10; // dl
	char v11; // cl
	char v12; // dl

	v0 = myplr;
	if ( (unsigned int)myplr >= 4 )
	{
		TermMsg("PlayDungMsgs: illegal player %d", myplr);
		v0 = myplr;
	}
	switch ( currlevel )
	{
		case 1u:
			v1 = v0;
			if ( !plr[v1]._pLvlVisited[1] && gbMaxPlayers == currlevel )
			{
				v2 = plr[v1].pDungMsgs;
				if ( !(v2 & 1) )
				{
					v3 = plr[v1]._pClass;
					sfxdelay = 40;
					if ( v3 )
					{
						if ( v3 == 1 )
						{
							sfxdnum = PS_ROGUE97;
						}
						else if ( v3 == 2 )
						{
							sfxdnum = PS_MAGE97;
						}
					}
					else
					{
						sfxdnum = PS_WARR97;
					}
					v4 = v2 | 1;
LABEL_14:
					plr[v1].pDungMsgs = v4;
					return;
				}
			}
			break;
		case 5u:
			v1 = v0;
			if ( !plr[v1]._pLvlVisited[5] && gbMaxPlayers == 1 )
			{
				v5 = plr[v1].pDungMsgs;
				if ( !(v5 & 2) )
				{
					v6 = plr[v1]._pClass;
					sfxdelay = 40;
					if ( v6 )
					{
						if ( v6 == 1 )
						{
							sfxdnum = PS_ROGUE96;
						}
						else if ( v6 == 2 )
						{
							sfxdnum = PS_MAGE96;
						}
					}
					else
					{
						sfxdnum = PS_WARR96B;
					}
					v4 = v5 | 2;
					goto LABEL_14;
				}
			}
			break;
		case 9u:
			v1 = v0;
			if ( !plr[v1]._pLvlVisited[9] && gbMaxPlayers == 1 )
			{
				v7 = plr[v1].pDungMsgs;
				if ( !(v7 & 4) )
				{
					v8 = plr[v1]._pClass;
					sfxdelay = 40;
					if ( v8 )
					{
						if ( v8 == 1 )
						{
							sfxdnum = PS_ROGUE98;
						}
						else if ( v8 == 2 )
						{
							sfxdnum = PS_MAGE98;
						}
					}
					else
					{
						sfxdnum = PS_WARR98;
					}
					v4 = v7 | 4;
					goto LABEL_14;
				}
			}
			break;
		case 13u:
			v1 = v0;
			if ( !plr[v1]._pLvlVisited[13] && gbMaxPlayers == 1 )
			{
				v9 = plr[v1].pDungMsgs;
				if ( !(v9 & 8) )
				{
					v10 = plr[v1]._pClass;
					sfxdelay = 40;
					if ( v10 )
					{
						if ( v10 == 1 )
						{
							sfxdnum = PS_ROGUE99;
						}
						else if ( v10 == 2 )
						{
							sfxdnum = PS_MAGE99;
						}
					}
					else
					{
						sfxdnum = PS_WARR99;
					}
					v4 = v9 | 8;
					goto LABEL_14;
				}
			}
			break;
		case 16u:
			v1 = v0;
			if ( !plr[v1]._pLvlVisited[15] && gbMaxPlayers == 1 )
			{
				v11 = plr[v1].pDungMsgs;
				if ( !(v11 & 0x10) )
				{
					v12 = plr[v1]._pClass;
					sfxdelay = 40;
					if ( !v12 || v12 == 1 || v12 == 2 )
						sfxdnum = PS_DIABLVLINT;
					v4 = v11 | 0x10;
					goto LABEL_14;
				}
			}
			break;
	}
	sfxdelay = 0;
}
// 52A554: using guessed type int sfxdelay;
// 679660: using guessed type char gbMaxPlayers;

//----- (00450D33) --------------------------------------------------------
void __fastcall plrmsg_delay(int a1)
{
	_plrmsg *v1; // eax
	signed int v2; // ecx

	if ( a1 )
	{
		plrmsg_ticks = -GetTickCount();
	}
	else
	{
		plrmsg_ticks += GetTickCount();
		v1 = plr_msgs;
		v2 = 8;
		do
		{
			v1->time += plrmsg_ticks;
			++v1;
			--v2;
		}
		while ( v2 );
	}
}
// 69B7D0: using guessed type int plrmsg_ticks;

//----- (00450D6A) --------------------------------------------------------
char *__fastcall ErrorPlrMsg(char *a1)
{
	_plrmsg *v1; // esi
	char *v2; // edi
	char *result; // eax

	v1 = &plr_msgs[(unsigned char)plr_msg_slot];
	v2 = a1;
	plr_msg_slot = (plr_msg_slot + 1) & 7;
	v1->player = 4;
	v1->time = GetTickCount();
	result = strncpy(v1->msg, v2, 0x90u);
	v1->msg[143] = 0;
	return result;
}
// 69B7D4: using guessed type char plr_msg_slot;

//----- (00450DB3) --------------------------------------------------------
size_t EventPlrMsg(char *szMsg, ...)
{
	char *v1; // esi
	va_list va; // [esp+Ch] [ebp+8h]

	va_start(va, szMsg);
	v1 = (char *)&plr_msgs[(unsigned char)plr_msg_slot];
	plr_msg_slot = (plr_msg_slot + 1) & 7;
	v1[4] = 4;
	*(_DWORD *)v1 = GetTickCount();
	v1 += 5;
	vsprintf(v1, szMsg, va);
	return strlen(v1);
}
// 69B7D4: using guessed type char plr_msg_slot;

//----- (00450DFA) --------------------------------------------------------
void __fastcall SendPlrMsg(int pnum, const char *szMsg)
{
	_plrmsg *v2; // esi
	int v3; // ebx
	const char *v4; // ebp
	int v5; // edi
	const char *v6; // ebx

	v2 = &plr_msgs[(unsigned char)plr_msg_slot];
	v3 = pnum;
	v4 = szMsg;
	plr_msg_slot = (plr_msg_slot + 1) & 7;
	v2->player = pnum;
	v2->time = GetTickCount();
	v5 = v3;
	v6 = plr[v3]._pName;
	strlen(v6);
	strlen(v4);
	sprintf(v2->msg, "%s (lvl %d): %s", v6, plr[v5]._pLevel, v4);
}
// 69B7D4: using guessed type char plr_msg_slot;

//----- (00450E64) --------------------------------------------------------
void __cdecl ClearPlrMsg()
{
	_plrmsg *v0; // esi
	DWORD v1; // eax
	signed int v2; // ecx

	v0 = plr_msgs;
	v1 = GetTickCount();
	v2 = 8;
	do
	{
		if ( (signed int)(v1 - v0->time) > 10000 )
			v0->msg[0] = 0;
		++v0;
		--v2;
	}
	while ( v2 );
}

//----- (00450E8E) --------------------------------------------------------
void __cdecl InitPlrMsg()
{
	memset(plr_msgs, 0, 0x4C0u);
	plr_msg_slot = 0;
}
// 69B7D4: using guessed type char plr_msg_slot;

//----- (00450EAA) --------------------------------------------------------
void __cdecl DrawPlrMsg()
{
	int v0; // ebx
	int v1; // ebp
	int v2; // edi
	char *v3; // esi
	signed int v4; // [esp+Ch] [ebp-4h]

	v0 = 74;
	v1 = 230;
	v2 = 620;
	if ( chrflag || questlog )
	{
		if ( invflag || sbookflag )
			return;
		v0 = 394;
		goto LABEL_9;
	}
	if ( invflag || sbookflag )
LABEL_9:
		v2 = 300;
	v3 = plr_msgs[0].msg;
	v4 = 8;
	do
	{
		if ( *v3 )
			PrintPlrMsg(v0, v1, v2, v3, *((unsigned char *)text_color_from_player_num + (unsigned char)*(v3 - 1)));
		v3 += 152;
		v1 += 35;
		--v4;
	}
	while ( v4 );
}
// 4B8968: using guessed type int sbookflag;
// 69BD04: using guessed type int questlog;

//----- (00450F37) --------------------------------------------------------
void __fastcall PrintPlrMsg(int no, int x, int y, char *str, int just)
{
	char *v5; // edi
	int *v6; // edx
	int v7; // esi
	char *v8; // edx
	int v9; // esi
	unsigned int v10; // eax
	unsigned char v11; // cl
	unsigned char v12; // cl
	int v13; // eax
	unsigned char v14; // bl
	int v15; // [esp+Ch] [ebp-Ch]
	int *v16; // [esp+10h] [ebp-8h]
	int v17; // [esp+14h] [ebp-4h]
	char *stra; // [esp+24h] [ebp+Ch]

	v17 = 0;
	v5 = str;
	v15 = no;
	if ( *str )
	{
		v6 = &screen_y_times_768[x];
		v16 = v6;
		do
		{
			v7 = *v6;
			v8 = v5;
			v9 = v15 + v7;
			v10 = 0;
			stra = v5;
			while ( 1 )
			{
				v11 = *v8;
				if ( !*v8 )
					break;
				++v8;
				v12 = fontframe[fontidx[v11]];
				v10 += fontkern[v12] + 1;
				if ( v12 )
				{
					if ( v10 >= y )
						goto LABEL_13;
				}
				else
				{
					stra = v8;
				}
			}
			stra = v8;
LABEL_13:
			while ( v5 < stra )
			{
				v13 = (unsigned char)*v5++;
				v14 = fontframe[fontidx[v13]];
				if ( v14 )
					CPrintString(v9, (char *)v14, just);
				v9 += fontkern[v14] + 1;
			}
			v6 = v16 + 10;
			++v17;
			v16 += 10;
		}
		while ( v17 != 3 && *v5 );
	}
}

//----- (00450FFE) --------------------------------------------------------
void __cdecl InitPortals()
{
	int v0; // edi
	PortalStruct *v1; // esi
	int v2; // eax

	v0 = 0;
	v1 = portal;
	do
	{
		_LOBYTE(v2) = delta_portal_inited(v0);
		if ( v2 )
			v1->open = 0;
		++v1;
		++v0;
	}
	while ( (signed int)v1 < (signed int)&portalindex );
}

//----- (00451024) --------------------------------------------------------
void __fastcall SetPortalStats(int i, int o, int x, int y, int lvl, int lvltype)
{
	int v6; // eax

	v6 = i;
	portal[v6].x = x;
	portal[v6].setlvl = 0;
	portal[v6].y = y;
	portal[v6].open = o;
	portal[v6].level = lvl;
	portal[v6].ltype = lvltype;
}

//----- (00451062) --------------------------------------------------------
void __fastcall AddWarpMissile(int i, int x, int y)
{
	int v3; // eax
	int v4; // esi

	missiledata[10].mlSFX = -1;
	dMissile[x][y] = 0;
	v3 = AddMissile(0, 0, x, y, 0, 10, 0, i, 0, 0);
	v4 = v3;
	if ( v3 != -1 )
	{
		SetMissDir(v3, 1);
		if ( currlevel )
			missile[v4]._mlid = AddLight(missile[v4]._mix, missile[v4]._miy, 15);
		missiledata[10].mlSFX = 129;
	}
}

//----- (004510D6) --------------------------------------------------------
void __cdecl SyncPortals()
{
	int v0; // edi
	int *v1; // esi
	int v2; // eax

	v0 = 0;
	v1 = &portal[0].level;
	do
	{
		if ( *(v1 - 3) )
		{
			if ( currlevel )
			{
				v2 = currlevel;
				if ( setlevel )
					v2 = (unsigned char)setlvlnum;
				if ( *v1 == v2 )
					AddWarpMissile(v0, *(v1 - 2), *(v1 - 1));
			}
			else
			{
				AddWarpMissile(v0, WarpDropX[v0], WarpDropY[v0]);
			}
		}
		v1 += 6;
		++v0;
	}
	while ( (signed int)v1 < (signed int)&questlog );
}
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;
// 69BD04: using guessed type int questlog;

//----- (00451131) --------------------------------------------------------
void __fastcall AddInTownPortal(int i)
{
	AddWarpMissile(i, WarpDropX[i], WarpDropY[i]);
}

//----- (00451145) --------------------------------------------------------
void __fastcall ActivatePortal(int i, int x, int y, int lvl, int lvltype, int sp)
{
	int v6; // eax

	v6 = i;
	portal[i].open = 1;
	if ( lvl )
	{
		portal[v6].level = lvl;
		portal[v6].x = x;
		portal[v6].ltype = lvltype;
		portal[v6].y = y;
		portal[v6].setlvl = sp;
	}
}

//----- (0045118A) --------------------------------------------------------
void __fastcall DeactivatePortal(int i)
{
	portal[i].open = 0;
}

//----- (00451196) --------------------------------------------------------
int __fastcall PortalOnLevel(int i)
{
	int result; // eax

	if ( portal[i].level == currlevel )
		result = 1;
	else
		result = currlevel == 0;
	return result;
}

//----- (004511B8) --------------------------------------------------------
void __fastcall RemovePortalMissile(int id)
{
	int v1; // edi
	int i; // esi
	int v3; // ebx
	int v4; // eax
	int v5; // ecx

	v1 = 0;
	for ( i = id; v1 < nummissiles; ++v1 )
	{
		v3 = missileactive[v1];
		v4 = missileactive[v1];
		if ( missile[v4]._mitype == 10 && missile[v4]._misource == i )
		{
			v5 = missile[v4]._miy + 112 * missile[v4]._mix;
			dFlags[0][v5] &= 0xFEu;
			dMissile[0][v5] = 0;
			if ( portal[i].level )
				AddUnLight(missile[v4]._mlid);
			DeleteMissile(v3, v1);
		}
	}
}

//----- (00451234) --------------------------------------------------------
void __fastcall SetCurrentPortal(int p)
{
	portalindex = p;
}

//----- (0045123B) --------------------------------------------------------
void __cdecl GetPortalLevel()
{
	int v0; // eax
	unsigned char v1; // cl
	char v2; // al
	bool v3; // zf

	if ( currlevel )
	{
		setlevel = 0;
		currlevel = 0;
		leveltype = 0;
		plr[myplr].plrlevel = 0;
	}
	else
	{
		v0 = portalindex;
		if ( portal[portalindex].setlvl )
		{
			v1 = portal[v0].level;
			setlevel = 1;
			setlvlnum = v1;
		}
		else
		{
			setlevel = 0;
			v1 = portal[v0].level;
		}
		v2 = portal[v0].ltype;
		v3 = portalindex == myplr;
		currlevel = v1;
		leveltype = v2;
		plr[myplr].plrlevel = v1;
		if ( v3 )
		{
			NetSendCmd(1u, CMD_DEACTIVATEPORTAL);
			DeactivatePortal(portalindex);
		}
	}
}
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (004512E3) --------------------------------------------------------
void __cdecl GetPortalLvlPos()
{
	int v0; // eax
	int v1; // eax

	if ( currlevel )
	{
		v1 = portal[portalindex].y;
		ViewX = portal[portalindex].x;
		ViewY = v1;
		if ( portalindex != myplr )
		{
			++ViewX;
			++ViewY;
		}
	}
	else
	{
		v0 = WarpDropY[portalindex] + 1;
		ViewX = WarpDropX[portalindex] + 1;
		ViewY = v0;
	}
}

//----- (00451346) --------------------------------------------------------
int __fastcall portal_pos_ok(int level, int x, int y)
{
	int *v3; // eax

	v3 = &portal[0].x;
	while ( !*(v3 - 1) || v3[2] != level || (*v3 != x || v3[1] != y) && (*v3 != x - 1 || v3[1] != y - 1) )
	{
		v3 += 6;
		if ( (signed int)v3 >= (signed int)&END_portalstruct )
			return 0;
	}
	return 1;
}
// 69BCFC: using guessed type int END_portalstruct;

//----- (0045138E) --------------------------------------------------------
void __cdecl InitQuests()
{
	char v0; // dl
	char *v1; // esi
	char *v2; // eax
	char *v3; // ecx
	unsigned char *v4; // eax
	int v5; // ebp
	unsigned int v6; // edi
	int v7; // eax
	unsigned char v8; // al
	unsigned char v9; // al
	char v10; // al
	int v11; // ecx
	int v12; // ecx
	int v13; // eax
	int v14; // ecx
	int v15; // eax
	int v16; // ecx
	int v17; // eax
	int v18; // ecx
	int v19; // eax
	char v20; // [esp+8h] [ebp-4h]

	v0 = gbMaxPlayers;
	v1 = &quests[0]._qactive;
	if ( gbMaxPlayers == 1 )
	{
		v2 = &quests[0]._qactive;
		do
		{
			*v2 = 0;
			v2 += 24;
		}
		while ( (signed int)v2 < (signed int)&qline + 2 );
	}
	else
	{
		v3 = &quests[0]._qactive;
		v4 = &questlist[0]._qflags;
		do
		{
			if ( !(*v4 & 1) )
				*v3 = 0;
			v4 += 20;
			v3 += 24;
		}
		while ( (signed int)v4 < (signed int)questyoff );
	}
	v5 = 0;
	questlog = 0;
	ALLQUESTS = 1;
	WaterDone = 0;
	v20 = 0;
	v6 = 0;
	do
	{
		if ( (unsigned char)v0 <= 1u || questlist[v6]._qflags & 1 )
		{
			*(v1 - 1) = questlist[v6]._qdtype;
			if ( (unsigned char)v0 <= 1u )
			{
				v8 = questlist[v6]._qdlvl;
				*v1 = 1;
				*(v1 - 2) = v8;
				v1[13] = 0;
				*(_DWORD *)(v1 + 18) = 0;
			}
			else
			{
				*(v1 - 2) = questlist[v6]._qdmultlvl;
				_LOBYTE(v7) = delta_quest_inited(v5);
				if ( !v7 )
				{
					*v1 = 1;
					v1[13] = 0;
					*(_DWORD *)(v1 + 18) = 0;
				}
				v0 = gbMaxPlayers;
				++v5;
			}
			v9 = questlist[v6]._qslvl;
			*(_DWORD *)(v1 + 2) = 0;
			v1[10] = v9;
			v1[11] = v20;
			v1[1] = questlist[v6]._qlvlt;
			v10 = questlist[v6]._qdmsg;
			*(_DWORD *)(v1 + 6) = 0;
			v1[14] = 0;
			v1[12] = v10;
		}
		++v20;
		++v6;
		v1 += 24;
	}
	while ( v6 < 16 );
	if ( v0 == 1 )
	{
		SetRndSeed(glSeedTbl[15]);
		_LOBYTE(v11) = 0;
		if ( random(v11, 2) )
			quests[13]._qactive = 0;
		else
			quests[12]._qactive = 0;
		_LOBYTE(v12) = 0;
		v13 = random(v12, 3);
		_LOBYTE(v14) = 0;
		quests[QuestGroup1[v13]]._qactive = 0;
		v15 = random(v14, 3);
		_LOBYTE(v16) = 0;
		quests[QuestGroup2[v15]]._qactive = 0;
		v17 = random(v16, 3);
		_LOBYTE(v18) = 0;
		quests[QuestGroup3[v17]]._qactive = 0;
		v19 = random(v18, 2);
		v0 = gbMaxPlayers;
		quests[QuestGroup4[v19]]._qactive = 0;
	}
	if ( !quests[12]._qactive )
		quests[12]._qvar2 = 2;
	if ( !quests[0]._qactive )
		quests[0]._qvar2 = 2;
	quests[7]._qvar1 = 1;
	if ( v0 != 1 )
		quests[15]._qvar1 = 2;
}
// 679660: using guessed type char gbMaxPlayers;
// 69BD04: using guessed type int questlog;
// 69BE90: using guessed type int qline;

//----- (0045155C) --------------------------------------------------------
void __cdecl CheckQuests()
{
	int v0; // eax
	char *v1; // esi
	unsigned char v2; // cl

	_LOBYTE(v0) = QuestStatus(15);
	if ( v0 )
	{
		if ( gbMaxPlayers == 1 )
			goto LABEL_6;
		if ( quests[15]._qvar1 == 2 )
		{
			AddObject(83, 2 * setpc_x + 20, 2 * setpc_y + 22);
			quests[15]._qvar1 = 3;
			NetSendCmdQuest(1u, 0xFu);
		}
	}
	if ( gbMaxPlayers != 1 )
		return;
LABEL_6:
	if ( currlevel == quests[15]._qlevel && !setlevel && quests[15]._qvar1 >= 2u )
	{
		if ( quests[15]._qactive != 2 && quests[15]._qactive != 3 )
			goto LABEL_29;
		if ( !quests[15]._qvar2 || quests[15]._qvar2 == 2 )
		{
			quests[15]._qtx = 2 * quests[15]._qtx + 16;
			quests[15]._qty = 2 * quests[15]._qty + 16;
			AddMissile(quests[15]._qtx, quests[15]._qty, quests[15]._qtx, quests[15]._qty, 0, 65, 0, myplr, 0, 0);
			quests[15]._qvar2 = 1;
			if ( quests[15]._qactive == 2 )
				quests[15]._qvar1 = 3;
		}
	}
	if ( quests[15]._qactive == 3 )
	{
		if ( !setlevel )
			goto LABEL_29;
		if ( setlvlnum == SL_VILEBETRAYER && quests[15]._qvar2 == 4 )
		{
			AddMissile(35, 32, 35, 32, 0, 65, 0, myplr, 0, 0);
			quests[15]._qvar2 = 3;
		}
	}
	if ( setlevel )
	{
		if ( setlvlnum == quests[13]._qslvl
		  && quests[13]._qactive != 1
		  && leveltype == quests[13]._qlvltype
		  && nummonsters == 4
		  && quests[13]._qactive != 3 )
		{
			quests[13]._qactive = 3;
			PlaySfxLoc(IS_QUESTDN, plr[myplr].WorldX, plr[myplr].WorldY);
			LoadPalette("Levels\\L3Data\\L3pwater.pal");
			WaterDone = 32;
		}
		if ( WaterDone > 0 )
		{
			palette_update_quest_palette(WaterDone);
			--WaterDone;
		}
		return;
	}
LABEL_29:
	if ( plr[myplr]._pmode == PM_STAND )
	{
		v1 = &quests[0]._qactive;
		do
		{
			if ( currlevel == *(v1 - 2) )
			{
				v2 = v1[10];
				if ( v2 )
				{
					if ( *v1 && plr[myplr].WorldX == *(_DWORD *)(v1 + 2) && plr[myplr].WorldY == *(_DWORD *)(v1 + 6) )
					{
						if ( v1[1] != -1 )
							setlvltype = v1[1];
						StartNewLvl(myplr, WM_DIABSETLVL, v2);
					}
				}
			}
			v1 += 24;
		}
		while ( (signed int)v1 < (signed int)&qline + 2 );
	}
}
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31C: using guessed type char setlvltype;
// 5CF31D: using guessed type char setlevel;
// 679660: using guessed type char gbMaxPlayers;
// 69BE90: using guessed type int qline;

//----- (0045178F) --------------------------------------------------------
int __cdecl ForceQuests()
{
	QuestStruct *v0; // eax
	int v1; // esi
	int v2; // edi
	int v3; // edx

	if ( gbMaxPlayers != 1 )
		return 0;
	v0 = (QuestStruct *)((char *)quests + 12);
	while ( v0 == (QuestStruct *)&quests[15]._qslvl || currlevel != v0[-1]._qslvl || !v0->_qlevel )
	{
LABEL_10:
		++v0;
		if ( (signed int)v0 >= (signed int)&qlist[2] )
			return 0;
	}
	v1 = *(_DWORD *)&v0[-1]._qvar2;
	v2 = v0[-1]._qlog;
	v3 = 0;
	while ( v1 + (char)questxoff[v3] != cursmx || v2 + (char)questyoff[v3] != cursmy )
	{
		if ( ++v3 >= 7 )
			goto LABEL_10;
	}
	sprintf(infostr, "To %s", questtrigstr[(unsigned char)quests[(unsigned char)v0->_qtype]._qslvl - 1]);
	cursmx = v1;
	cursmy = v2;
	return 1;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00451831) --------------------------------------------------------
bool __fastcall QuestStatus(int i)
{
	bool result; // al

	if ( setlevel
	  || currlevel != quests[i]._qlevel
	  || !quests[i]._qactive
	  || (result = 1, gbMaxPlayers != 1) && !(questlist[i]._qflags & 1) )
	{
		result = 0;
	}
	return result;
}
// 5CF31D: using guessed type char setlevel;
// 679660: using guessed type char gbMaxPlayers;

//----- (00451871) --------------------------------------------------------
void __fastcall CheckQuestKill(int m, unsigned char sendmsg)
{
	int v2; // ecx
	char v3; // al
	char v4; // al
	unsigned char v5; // dl
	char v6; // al
	char *v7; // ecx
	char v8; // al
	char v9; // al
	int v10; // edi
	int (*v11)[112]; // esi
	signed int v12; // ecx
	int *v13; // eax
	int (*v14)[112]; // ebx
	char v15; // al
	char v16; // al
	char v17; // al

	v2 = m;
	v3 = monster[v2].MType->mtype;
	if ( v3 == MON_SKING )
	{
		quests[12]._qactive = 3;
		sfxdelay = 30;
		v4 = plr[myplr]._pClass;
		if ( v4 )
		{
			if ( v4 == 1 )
			{
				sfxdnum = PS_ROGUE82;
			}
			else if ( v4 == 2 )
			{
				sfxdnum = PS_MAGE82;
			}
		}
		else
		{
			sfxdnum = PS_WARR82;
		}
		if ( sendmsg )
		{
			v5 = 12;
LABEL_10:
			NetSendCmdQuest(1u, v5);
			return;
		}
	}
	else
	{
		if ( v3 != MON_BUTCH )
		{
			v7 = monster[v2].mName;
			if ( v7 == UniqMonst[0].mName )
			{
				quests[2]._qactive = 3;
				sfxdelay = 30;
				v8 = plr[myplr]._pClass;
				if ( v8 )
				{
					if ( v8 == 1 )
					{
						sfxdnum = PS_ROGUE61;
					}
					else if ( v8 == 2 )
					{
						sfxdnum = PS_MAGE61;
					}
				}
				else
				{
					sfxdnum = PS_WARR61;
				}
				return;
			}
			if ( v7 == UniqMonst[2].mName )
			{
				quests[3]._qactive = 3;
				sfxdelay = 30;
				v9 = plr[myplr]._pClass;
				if ( v9 )
				{
					if ( v9 == 1 )
					{
						sfxdnum = PS_ROGUE62;
					}
					else if ( v9 == 2 )
					{
						sfxdnum = PS_MAGE62;
					}
				}
				else
				{
					sfxdnum = PS_WARR62;
				}
				return;
			}
			if ( v7 == UniqMonst[4].mName )
			{
				if ( gbMaxPlayers != 1 )
				{
					quests[15]._qactive = 3;
					quests[15]._qvar1 = 7;
					sfxdelay = 30;
					quests[5]._qactive = 2;
					v10 = 0;
					v11 = dPiece;
					do
					{
						v12 = 0;
						v13 = &trigs[trigflag[4]]._ty;
						v14 = v11;
						do
						{
							if ( (*v14)[0] == 370 )
							{
								++trigflag[4];
								*(v13 - 1) = v12;
								*v13 = v10;
								v13[1] = 1026;
								v13 += 4;
							}
							++v12;
							++v14;
						}
						while ( v12 < 112 );
						v11 = (int (*)[112])((char *)v11 + 4);
						++v10;
					}
					while ( (signed int)v11 < (signed int)dPiece[1] );
					v15 = plr[myplr]._pClass;
					if ( v15 )
					{
						if ( v15 == 1 )
						{
							sfxdnum = PS_ROGUE83;
						}
						else if ( v15 == 2 )
						{
							sfxdnum = PS_MAGE83;
						}
					}
					else
					{
						sfxdnum = PS_WARR83;
					}
					if ( sendmsg )
					{
						NetSendCmdQuest(1u, 0xFu);
						v5 = 5;
						goto LABEL_10;
					}
					return;
				}
				if ( v7 == UniqMonst[4].mName && gbMaxPlayers == 1 )
				{
					quests[15]._qactive = 3;
					sfxdelay = 30;
					InitVPTriggers();
					quests[15]._qvar1 = 7;
					quests[15]._qvar2 = 4;
					quests[5]._qactive = 2;
					AddMissile(35, 32, 35, 32, 0, 65, 0, myplr, 0, 0);
					v16 = plr[myplr]._pClass;
					if ( v16 )
					{
						if ( v16 == 1 )
						{
							sfxdnum = PS_ROGUE83;
						}
						else if ( v16 == 2 )
						{
							sfxdnum = PS_MAGE83;
						}
					}
					else
					{
						sfxdnum = PS_WARR83;
					}
					return;
				}
			}
			if ( v7 == UniqMonst[8].mName )
			{
				quests[11]._qactive = 3;
				sfxdelay = 30;
				v17 = plr[myplr]._pClass;
				if ( v17 )
				{
					if ( v17 == 1 )
					{
						sfxdnum = PS_ROGUE94;
					}
					else if ( v17 == 2 )
					{
						sfxdnum = PS_MAGE94;
					}
				}
				else
				{
					sfxdnum = PS_WARR94;
				}
			}
			return;
		}
		quests[6]._qactive = 3;
		sfxdelay = 30;
		v6 = plr[myplr]._pClass;
		if ( v6 )
		{
			if ( v6 == 1 )
			{
				sfxdnum = PS_ROGUE80;
			}
			else if ( v6 == 2 )
			{
				sfxdnum = PS_MAGE80;
			}
		}
		else
		{
			sfxdnum = PS_WARR80;
		}
		if ( sendmsg )
		{
			v5 = 6;
			goto LABEL_10;
		}
	}
}
// 52A554: using guessed type int sfxdelay;
// 679660: using guessed type char gbMaxPlayers;

//----- (00451BEA) --------------------------------------------------------
void __cdecl DrawButcher()
{
	DRLG_RectTrans(2 * setpc_x + 19, 2 * setpc_y + 19, 2 * setpc_x + 26, 2 * setpc_y + 26);
}

//----- (00451C11) --------------------------------------------------------
void __fastcall DrawSkelKing(int quest_id, int xx, int yy)
{
	int v3; // eax

	v3 = quest_id;
	quests[v3]._qtx = 2 * xx + 28;
	quests[v3]._qty = 2 * yy + 23;
}

//----- (00451C32) --------------------------------------------------------
void __fastcall DrawWarLord(int xx, int yy)
{
	int v2; // esi
	int v3; // edi
	unsigned char *v4; // eax
	int v5; // ebx
	int v6; // edx
	int v7; // edx
	char *v8; // eax
	int v9; // ecx
	char *v10; // esi
	char v11; // bl
	unsigned char *ptr; // [esp+Ch] [ebp-Ch]
	int v13; // [esp+10h] [ebp-8h]
	int v14; // [esp+14h] [ebp-4h]

	v2 = yy;
	v3 = xx;
	v4 = LoadFileInMem("Levels\\L4Data\\Warlord2.DUN", 0);
	v5 = *v4;
	ptr = v4;
	v4 += 2;
	v14 = v2;
	v6 = *v4;
	setpc_h = v6;
	v7 = v2 + v6;
	v8 = (char *)(v4 + 2);
	setpc_w = v5;
	setpc_x = v3;
	setpc_y = v2;
	if ( v2 < v7 )
	{
		v13 = v3 + v5;
		do
		{
			if ( v3 < v13 )
			{
				v9 = v13 - v3;
				v10 = &dungeon[v3][v14];
				do
				{
					v11 = *v8;
					if ( !*v8 )
						v11 = 6;
					*v10 = v11;
					v8 += 2;
					v10 += 40;
					--v9;
				}
				while ( v9 );
			}
			++v14;
		}
		while ( v14 < v7 );
	}
	mem_free_dbg(ptr);
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00451CC2) --------------------------------------------------------
void __fastcall DrawSChamber(int quest_id, int xx, int yy)
{
	int v3; // esi
	unsigned char *v4; // eax
	int v5; // edi
	int v6; // ebx
	int v7; // eax
	char *v8; // ecx
	int v9; // eax
	char *v10; // edx
	char v11; // bl
	int v12; // edx
	unsigned char *ptr; // [esp+Ch] [ebp-10h]
	int v14; // [esp+10h] [ebp-Ch]
	int v15; // [esp+14h] [ebp-8h]
	int v16; // [esp+18h] [ebp-4h]

	v3 = xx;
	v14 = quest_id;
	v4 = LoadFileInMem("Levels\\L2Data\\Bonestr1.DUN", 0);
	v5 = yy;
	ptr = v4;
	v6 = yy;
	v7 = *v4;
	setpc_h = ptr[2];
	v8 = (char *)(ptr + 4);
	setpc_w = v7;
	setpc_x = v3;
	setpc_y = yy;
	v15 = yy + setpc_h;
	if ( yy < yy + setpc_h )
	{
		v16 = v3 + v7;
		do
		{
			if ( v3 < v16 )
			{
				v9 = v16 - v3;
				v10 = &dungeon[v3][v6];
				do
				{
					v11 = *v8;
					if ( !*v8 )
						v11 = 3;
					*v10 = v11;
					v8 += 2;
					v10 += 40;
					--v9;
				}
				while ( v9 );
			}
			v6 = yy++ + 1;
		}
		while ( yy < v15 );
	}
	v12 = v14;
	quests[v12]._qtx = 2 * v3 + 22;
	quests[v12]._qty = 2 * v5 + 23;
	mem_free_dbg(ptr);
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00451D7C) --------------------------------------------------------
void __fastcall DrawLTBanner(int xx, int yy)
{
	int v2; // ebx
	int v3; // esi
	unsigned char *v4; // eax
	unsigned char *v5; // ecx
	int v6; // edi
	int v7; // edx
	int v8; // eax
	char *v9; // edx
	char *v10; // ecx
	unsigned char *ptr; // [esp+Ch] [ebp-10h]
	int v12; // [esp+10h] [ebp-Ch]
	int v13; // [esp+14h] [ebp-8h]
	int v14; // [esp+18h] [ebp-4h]

	v2 = yy;
	v3 = xx;
	v12 = yy;
	v4 = LoadFileInMem("Levels\\L1Data\\Banner1.DUN", 0);
	v5 = v4;
	v14 = 0;
	ptr = v4;
	v6 = *v4;
	v7 = (int)(v4 + 2);
	v8 = v4[2];
	setpc_w = v6;
	v9 = (char *)(v7 + 2);
	setpc_h = v8;
	setpc_x = v3;
	setpc_y = v2;
	if ( v8 > 0 )
	{
		do
		{
			if ( v6 > 0 )
			{
				v13 = v6;
				v10 = &pdungeon[v3][v14 + v12];
				do
				{
					if ( *v9 )
						*v10 = *v9;
					v10 += 40;
					v9 += 2;
					--v13;
				}
				while ( v13 );
				v5 = ptr;
			}
			++v14;
		}
		while ( v14 < v8 );
	}
	mem_free_dbg(v5);
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00451E08) --------------------------------------------------------
void __fastcall DrawBlind(int xx, int yy)
{
	int v2; // ebx
	int v3; // esi
	unsigned char *v4; // eax
	unsigned char *v5; // ecx
	int v6; // edi
	int v7; // edx
	int v8; // eax
	char *v9; // edx
	char *v10; // ecx
	unsigned char *ptr; // [esp+Ch] [ebp-10h]
	int v12; // [esp+10h] [ebp-Ch]
	int v13; // [esp+14h] [ebp-8h]
	int v14; // [esp+18h] [ebp-4h]

	v2 = yy;
	v3 = xx;
	v12 = yy;
	v4 = LoadFileInMem("Levels\\L2Data\\Blind1.DUN", 0);
	v5 = v4;
	v14 = 0;
	ptr = v4;
	v6 = *v4;
	v7 = (int)(v4 + 2);
	v8 = v4[2];
	setpc_x = v3;
	v9 = (char *)(v7 + 2);
	setpc_y = v2;
	setpc_w = v6;
	setpc_h = v8;
	if ( v8 > 0 )
	{
		do
		{
			if ( v6 > 0 )
			{
				v13 = v6;
				v10 = &pdungeon[v3][v14 + v12];
				do
				{
					if ( *v9 )
						*v10 = *v9;
					v10 += 40;
					v9 += 2;
					--v13;
				}
				while ( v13 );
				v5 = ptr;
			}
			++v14;
		}
		while ( v14 < v8 );
	}
	mem_free_dbg(v5);
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00451E94) --------------------------------------------------------
void __fastcall DrawBlood(int xx, int yy)
{
	int v2; // ebx
	int v3; // esi
	unsigned char *v4; // eax
	unsigned char *v5; // ecx
	int v6; // edi
	int v7; // edx
	int v8; // eax
	char *v9; // edx
	char *v10; // ecx
	unsigned char *ptr; // [esp+Ch] [ebp-10h]
	int v12; // [esp+10h] [ebp-Ch]
	int v13; // [esp+14h] [ebp-8h]
	int v14; // [esp+18h] [ebp-4h]

	v2 = yy;
	v3 = xx;
	v12 = yy;
	v4 = LoadFileInMem("Levels\\L2Data\\Blood2.DUN", 0);
	v5 = v4;
	v14 = 0;
	ptr = v4;
	v6 = *v4;
	v7 = (int)(v4 + 2);
	v8 = v4[2];
	setpc_x = v3;
	v9 = (char *)(v7 + 2);
	setpc_y = v2;
	setpc_w = v6;
	setpc_h = v8;
	if ( v8 > 0 )
	{
		do
		{
			if ( v6 > 0 )
			{
				v13 = v6;
				v10 = &dungeon[v3][v14 + v12];
				do
				{
					if ( *v9 )
						*v10 = *v9;
					v10 += 40;
					v9 += 2;
					--v13;
				}
				while ( v13 );
				v5 = ptr;
			}
			++v14;
		}
		while ( v14 < v8 );
	}
	mem_free_dbg(v5);
}
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (00451F20) --------------------------------------------------------
void __fastcall DRLG_CheckQuests(int xx, int yy)
{
	int v2; // esi
	int v3; // edi
	int v4; // ebx
	char *v5; // ebp
	int v6; // eax

	v2 = yy;
	v3 = xx;
	v4 = 0;
	v5 = &quests[0]._qtype;
	do
	{
		_LOBYTE(v6) = QuestStatus(v4);
		if ( v6 )
		{
			switch ( *v5 )
			{
				case QTYPE_BUTCH:
					DrawButcher();
					break;
				case QTYPE_BOL:
					DrawLTBanner(v3, v2);
					break;
				case QTYPE_BLIND:
					DrawBlind(v3, v2);
					break;
				case QTYPE_BLOOD:
					DrawBlood(v3, v2);
					break;
				case QTYPE_WARLRD:
					DrawWarLord(v3, v2);
					break;
				case QTYPE_KING:
					DrawSkelKing(v4, v3, v2);
					break;
				case QTYPE_BONE:
					DrawSChamber(v4, v3, v2);
					break;
			}
		}
		v5 += 24;
		++v4;
	}
	while ( (signed int)v5 < (signed int)&qline + 1 );
}
// 69BE90: using guessed type int qline;

//----- (00451FB1) --------------------------------------------------------
void __cdecl SetReturnLvlPos()
{
	int v0; // eax

	switch ( setlvlnum )
	{
		case SL_SKELKING:
			ReturnLvlX = quests[12]._qtx + 1;
			ReturnLvlY = quests[12]._qty;
			v0 = (unsigned char)quests[12]._qlevel;
			goto LABEL_9;
		case SL_BONECHAMB:
			ReturnLvlT = 2;
			ReturnLvlX = quests[14]._qtx + 1;
			ReturnLvlY = quests[14]._qty;
			v0 = (unsigned char)quests[14]._qlevel;
			goto LABEL_10;
		case SL_POISONWATER:
			ReturnLvlX = quests[13]._qtx;
			ReturnLvlY = quests[13]._qty + 1;
			v0 = (unsigned char)quests[13]._qlevel;
LABEL_9:
			ReturnLvlT = 1;
			goto LABEL_10;
	}
	if ( setlvlnum != 5 )
		return;
	ReturnLvlT = 4;
	ReturnLvlX = quests[15]._qtx + 1;
	ReturnLvlY = quests[15]._qty - 1;
	v0 = (unsigned char)quests[15]._qlevel;
LABEL_10:
	ReturnLvl = v0;
}
// 5CCB10: using guessed type char setlvlnum;

//----- (00452064) --------------------------------------------------------
void __cdecl GetReturnLvlPos()
{
	if ( quests[15]._qactive == 3 )
		quests[15]._qvar2 = 2;
	ViewX = ReturnLvlX;
	ViewY = ReturnLvlY;
	currlevel = ReturnLvl;
	leveltype = ReturnLvlT;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045209D) --------------------------------------------------------
void __cdecl ResyncMPQuests()
{
	int v0; // eax

	if ( quests[12]._qactive == 1
	  && currlevel >= (unsigned char)quests[12]._qlevel - 1
	  && currlevel <= (unsigned char)quests[12]._qlevel + 1 )
	{
		quests[12]._qactive = 2;
		NetSendCmdQuest(1u, 0xCu);
	}
	if ( quests[6]._qactive == 1
	  && currlevel >= (unsigned char)quests[6]._qlevel - 1
	  && currlevel <= (unsigned char)quests[6]._qlevel + 1 )
	{
		quests[6]._qactive = 2;
		NetSendCmdQuest(1u, 6u);
	}
	if ( quests[15]._qactive == 1 && currlevel == (unsigned char)quests[15]._qlevel - 1 )
	{
		quests[15]._qactive = 2;
		NetSendCmdQuest(1u, 0xFu);
	}
	_LOBYTE(v0) = QuestStatus(15);
	if ( v0 )
		AddObject(83, 2 * setpc_x + 20, 2 * setpc_y + 22);
}

//----- (00452159) --------------------------------------------------------
void __cdecl ResyncQuests()
{
	char *v0; // ecx
	int v1; // esi
	int v2; // eax
	int i; // esi
	char v4; // bl
	int j; // esi
	char v6; // bl
	int k; // esi

	if ( setlevel && setlvlnum == quests[13]._qslvl && quests[13]._qactive != 1 && leveltype == quests[13]._qlvltype )
	{
		v0 = "Levels\\L3Data\\L3pwater.pal";
		if ( quests[13]._qactive != 3 )
			v0 = "Levels\\L3Data\\L3pfoul.pal";
		LoadPalette(v0);
		v1 = 0;
		do
			palette_update_quest_palette(v1++);
		while ( v1 <= 32 );
	}
	_LOBYTE(v2) = QuestStatus(7);
	if ( v2 )
	{
		if ( quests[7]._qvar1 == 1 )
			ObjChangeMapResync(
				setpc_w + setpc_x - 2,
				setpc_h + setpc_y - 2,
				setpc_w + setpc_x + 1,
				setpc_h + setpc_y + 1);
		if ( quests[7]._qvar1 == 2 )
		{
			ObjChangeMapResync(
				setpc_w + setpc_x - 2,
				setpc_h + setpc_y - 2,
				setpc_w + setpc_x + 1,
				setpc_h + setpc_y + 1);
			ObjChangeMapResync(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 2, (setpc_h >> 1) + setpc_y - 2);
			for ( i = 0; i < nobjects; ++i )
				SyncObjectAnim(objectactive[i]);
			v4 = TransVal;
			TransVal = 9;
			Make_RectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 4, setpc_y + (setpc_h >> 1));
			TransVal = v4;
		}
		if ( quests[7]._qvar1 == 3 )
		{
			ObjChangeMapResync(setpc_x, setpc_y, setpc_w + setpc_x + 1, setpc_h + setpc_y + 1);
			for ( j = 0; j < nobjects; ++j )
				SyncObjectAnim(objectactive[j]);
			v6 = TransVal;
			TransVal = 9;
			Make_RectTrans(setpc_x, setpc_y, (setpc_w >> 1) + setpc_x + 4, setpc_y + (setpc_h >> 1));
			TransVal = v6;
		}
	}
	if ( currlevel == quests[1]._qlevel )
	{
		if ( quests[1]._qactive == 1 )
		{
			if ( !quests[1]._qvar1 )
			{
				SpawnQuestItem(19, 0, 0, 5, 1);
				quests[1]._qvar1 = 1;
			}
		}
		else if ( quests[1]._qactive == 2 )
		{
			if ( quests[1]._qvar1 < 5u )
			{
				if ( quests[1]._qvar1 >= 7u )
					Qtalklist[1]._qblkm = -1;
			}
			else
			{
				Qtalklist[6]._qblkm = -1;
				Qtalklist[1]._qblkm = 123;
			}
		}
	}
	if ( currlevel == (unsigned char)quests[4]._qlevel + 1 && quests[4]._qactive == 2 && !quests[4]._qvar1 )
	{
		quests[4]._qvar1 = 1;
		SpawnQuestItem(15, 0, 0, 5, 1);
	}
	if ( setlevel && setlvlnum == 5 )
	{
		if ( quests[15]._qvar1 >= 4u )
			ObjChangeMapResync(1, 11, 20, 18);
		if ( quests[15]._qvar1 >= 6u )
			ObjChangeMapResync(1, 18, 20, 24);
		if ( quests[15]._qvar1 >= 7u )
			InitVPTriggers();
		for ( k = 0; k < nobjects; ++k )
			SyncObjectAnim(objectactive[k]);
	}
	if ( currlevel == quests[15]._qlevel
	  && !setlevel
	  && (quests[15]._qvar2 == 1 || quests[15]._qvar2 >= 3u)
	  && (quests[15]._qactive == 2 || quests[15]._qactive == 3) )
	{
		quests[15]._qvar2 = 2;
	}
}
// 5A5590: using guessed type char TransVal;
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;
// 5CF330: using guessed type int setpc_h;
// 5CF334: using guessed type int setpc_w;

//----- (0045247F) --------------------------------------------------------
void __fastcall PrintQLString(int x, int y, unsigned char cjustflag, char *str, int col)
{
	int v5; // ebx
	int v6; // edi
	size_t v7; // eax
	int v8; // esi
	signed int v9; // ecx
	signed int v10; // eax
	int v11; // edx
	int v12; // ecx
	signed int v13; // ecx
	unsigned char v14; // al
	int v15; // edi
	int v16; // ecx
	int v17; // [esp+Ch] [ebp-14h]
	int v18; // [esp+10h] [ebp-10h]
	signed int v19; // [esp+14h] [ebp-Ch]
	signed int v20; // [esp+18h] [ebp-8h]
	int width; // [esp+1Ch] [ebp-4h]

	v5 = SStringY[y];
	v6 = x;
	v18 = y;
	v17 = x;
	width = screen_y_times_768[v5 + 204] + x + 96;
	v7 = strlen(str);
	v8 = 0;
	v9 = 0;
	v20 = v7;
	if ( cjustflag )
	{
		v10 = 0;
		if ( v20 <= 0 )
			goto LABEL_24;
		do
		{
			v11 = (unsigned char)str[v9++];
			v10 += fontkern[fontframe[fontidx[v11]]] + 1;
		}
		while ( v9 < v20 );
		if ( v10 < 257 )
LABEL_24:
			v8 = (257 - v10) >> 1;
		width += v8;
	}
	if ( qline == v18 )
	{
		v12 = v8 + v6 + 76;
		if ( !cjustflag )
			v12 = v6 + 76;
		Cel_decode(v12, v5 + 205, pCelBuff, ALLQUESTS, 12);
	}
	v13 = 0;
	v19 = 0;
	if ( v20 > 0 )
	{
		do
		{
			v14 = fontframe[fontidx[(unsigned char)str[v13]]];
			v15 = v14;
			v8 += fontkern[v14] + 1;
			if ( v14 && v8 <= 257 )
			{
				CPrintString(width, (char *)v14, col);
				v13 = v19;
			}
			v19 = ++v13;
			width += fontkern[v15] + 1;
		}
		while ( v13 < v20 );
		v6 = v17;
	}
	if ( qline == v18 )
	{
		if ( cjustflag )
			v16 = v8 + v6 + 100;
		else
			v16 = 340 - v6;
		Cel_decode(v16, v5 + 205, pCelBuff, ALLQUESTS, 12);
	}
}
// 69BE90: using guessed type int qline;

//----- (004525CD) --------------------------------------------------------
void __cdecl DrawQuestLog()
{
	int v0; // edi
	int i; // esi

	PrintQLString(0, 2, 1u, "Quest Log", 3);
	Cel_decode(64, 511, pQLogCel, 1, 320);
	v0 = qtopline;
	for ( i = 0; i < numqlines; ++i )
	{
		PrintQLString(0, v0, 1u, questlist[qlist[i]]._qlstr, 0);
		v0 += 2;
	}
	PrintQLString(0, 22, 1u, "Close Quest Log", 0);
	ALLQUESTS = (ALLQUESTS & 7) + 1;
}
// 69BED4: using guessed type int numqlines;

//----- (00452659) --------------------------------------------------------
void __cdecl StartQuestlog()
{
	signed int v0; // eax
	int v1; // edx
	unsigned int v2; // ecx
	int v3; // ecx

	v0 = 0;
	v1 = 0;
	numqlines = 0;
	v2 = 0;
	do
	{
		if ( quests[v2]._qactive == 2 && quests[v2]._qlog )
			qlist[v0++] = v1;
		++v2;
		++v1;
	}
	while ( v2 < 16 );
	numqlines = v0;
	if ( v0 <= 5 )
		v3 = 8;
	else
		v3 = 5 - (v0 >> 1);
	qtopline = v3;
	qline = 22;
	if ( v0 )
		qline = v3;
	questlog = 1;
	ALLQUESTS = 1;
}
// 69BD04: using guessed type int questlog;
// 69BE90: using guessed type int qline;
// 69BED4: using guessed type int numqlines;

//----- (004526C9) --------------------------------------------------------
void __cdecl QuestlogUp()
{
	if ( numqlines )
	{
		if ( qline == qtopline )
		{
			qline = 22;
		}
		else if ( qline == 22 )
		{
			qline = qtopline + 2 * numqlines - 2;
		}
		else
		{
			qline -= 2;
		}
		PlaySFX(IS_TITLEMOV);
	}
}
// 69BE90: using guessed type int qline;
// 69BED4: using guessed type int numqlines;

//----- (00452710) --------------------------------------------------------
void __cdecl QuestlogDown()
{
	if ( numqlines )
	{
		if ( qline == 22 )
		{
			qline = qtopline;
		}
		else if ( qline == qtopline + 2 * numqlines - 2 )
		{
			qline = 22;
		}
		else
		{
			qline += 2;
		}
		PlaySFX(IS_TITLEMOV);
	}
}
// 69BE90: using guessed type int qline;
// 69BED4: using guessed type int numqlines;

//----- (0045275A) --------------------------------------------------------
void __cdecl QuestlogEnter()
{
	PlaySFX(IS_TITLSLCT);
	if ( numqlines && qline != 22 )
		InitQTextMsg((unsigned char)quests[qlist[(qline - qtopline) >> 1]]._qmsg);
	questlog = 0;
}
// 69BD04: using guessed type int questlog;
// 69BE90: using guessed type int qline;
// 69BED4: using guessed type int numqlines;

//----- (0045279C) --------------------------------------------------------
void __cdecl QuestlogESC()
{
	int v0; // esi
	int i; // edi

	v0 = (MouseY - 32) / 12;
	if ( numqlines )
	{
		for ( i = 0; i < numqlines; ++i )
		{
			if ( v0 == qtopline + 2 * i )
			{
				qline = v0;
				QuestlogEnter();
			}
		}
	}
	if ( v0 == 22 )
	{
		qline = 22;
		QuestlogEnter();
	}
}
// 69BE90: using guessed type int qline;
// 69BED4: using guessed type int numqlines;

//----- (004527F1) --------------------------------------------------------
void __fastcall SetMultiQuest(int q, int s, unsigned char l, int v1)
{
	int v4; // eax
	char *v5; // ecx
	char *v6; // eax

	v4 = q;
	v5 = &quests[q]._qactive;
	if ( *v5 != 3 )
	{
		if ( s > (unsigned char)*v5 )
			*v5 = s;
		quests[v4]._qlog |= l;
		v6 = &quests[v4]._qvar1;
		if ( v1 > (unsigned char)*v6 )
			*v6 = v1;
	}
}

//----- (00452831) --------------------------------------------------------
bool __cdecl SystemSupported()
{
	bool v0; // di
	struct _OSVERSIONINFOA VersionInformation; // [esp+4h] [ebp-94h]

	v0 = 0;
	memset(&VersionInformation, 0, 0x94u);
	VersionInformation.dwOSVersionInfoSize = 148;
	if ( GetVersionExA(&VersionInformation)
	  && VersionInformation.dwPlatformId == 2
	  && VersionInformation.dwMajorVersion >= 5 )
	{
		v0 = 1;
	}
	return v0;
}

//----- (00452885) --------------------------------------------------------
bool __cdecl RestrictedTest()
{
	bool v0; // si
	int v1; // eax
	FILE *v2; // eax
	char Buffer[260]; // [esp+4h] [ebp-104h]

	v0 = 0;
	_LOBYTE(v1) = SystemSupported();
	if ( v1 && GetWindowsDirectoryA(Buffer, 0x104u) )
	{
		strcat(Buffer, "\\Diablo1RestrictedTest.foo");
		v2 = fopen(Buffer, "wt");
		if ( v2 )
		{
			fclose(v2);
			remove(Buffer);
		}
		else
		{
			v0 = 1;
		}
	}
	return v0;
}

//----- (004528F7) --------------------------------------------------------
bool __cdecl ReadOnlyTest()
{
	bool v0; // si
	char *v1; // eax
	FILE *v2; // eax
	char Filename[260]; // [esp+4h] [ebp-104h]

	v0 = 0;
	if ( GetModuleFileNameA(hInstance, Filename, 0x104u) )
	{
		v1 = strrchr(Filename, 92);
		if ( v1 )
		{
			strcpy(v1 + 1, "Diablo1ReadOnlyTest.foo");
			v2 = fopen(Filename, "wt");
			if ( v2 )
			{
				fclose(v2);
				remove(Filename);
			}
			else
			{
				v0 = 1;
			}
		}
	}
	return v0;
}

//----- (0045297A) --------------------------------------------------------
void __cdecl scrollrt_cpp_init()
{
	scrollrt_cpp_init_value = scrollrt_inf;
}
// 47F238: using guessed type int scrollrt_inf;
// 69CEFC: using guessed type int scrollrt_cpp_init_value;

//----- (00452985) --------------------------------------------------------
void __cdecl ClearCursor()
{
	sgdwCursWdt = 0;
	sgdwCursWdtOld = 0;
}

//----- (00452994) --------------------------------------------------------
void __fastcall scrollrt_452994(int x, int y, int a3, int a4, int a5, int a6, int del_flag)
{
	int v7; // ebx
	char v8; // al
	int v9; // eax
	int v10; // eax
	MissileStruct *v11; // eax
	int *v12; // edi
	int v13; // edx
	int v14; // esi
	int v15; // ecx
	int *v16; // eax
	int *v17; // edi
	int v18; // edx
	int v19; // esi
	int v20; // ecx
	int v21; // [esp-10h] [ebp-28h]
	int v22; // [esp-10h] [ebp-28h]
	int v23; // [esp-Ch] [ebp-24h]
	int v24; // [esp-Ch] [ebp-24h]
	int v25; // [esp+Ch] [ebp-Ch]
	int v26; // [esp+10h] [ebp-8h]
	int i; // [esp+14h] [ebp-4h]

	v26 = x;
	v7 = y;
	v8 = dMissile[x][y];
	v25 = y;
	if ( v8 == -1 )
	{
		v9 = 0;
		for ( i = 0; i < nummissiles; v9 = i++ + 1 )
		{
			v10 = missileactive[v9];
			if ( v10 >= 125 )
				break;
			v11 = &missile[v10];
			if ( v11->_mix == v26 && v11->_miy == v7 && v11->_miPreFlag == del_flag && v11->_miDrawFlag )
			{
				v12 = (int *)v11->_miAnimCel;
				if ( !v12 )
					return;
				v13 = v11->_miAnimFrame;
				if ( v13 < 1 || (unsigned int)*v12 > 0x32 || v13 > *v12 )
					return;
				v14 = a4 + v11->_miyoff;
				v15 = a3 + v11->_mixoff - v11->_miAnimWidth2;
				if ( v11->_miUniqTrans )
				{
					engine_417981(v15, v14, v12, v13, v11->_miAnimWidth, a5, a6, _LOBYTE(v11->_miUniqTrans) + 3);
					v7 = v25;
				}
				else
				{
					v23 = v11->_miAnimWidth;
					v21 = v11->_miAnimFrame;
					if ( v11->_miLightFlag )
						engine_417AE9(v15, v14, v12, v21, v23, a5, a6);
					else
						engine_417745(v15, v14, v12, v21, v23, a5, a6);
				}
			}
		}
	}
	else
	{
		v16 = &missileavail[44 * v8 + 81];
		if ( v16[26] == del_flag )
		{
			if ( v16[24] )
			{
				v17 = (int *)v16[16];
				if ( v17 )
				{
					v18 = v16[23];
					if ( v18 >= 1 && (unsigned int)*v17 <= 0x32 && v18 <= *v17 )
					{
						v19 = a4 + v16[4];
						v20 = a3 + v16[3] - v16[20];
						if ( v16[27] )
						{
							engine_417981(v20, v19, v17, v18, v16[19], a5, a6, *((_BYTE *)v16 + 108) + 3);
						}
						else
						{
							v24 = v16[19];
							v22 = v16[23];
							if ( v16[25] )
								engine_417AE9(v20, v19, v17, v22, v24, a5, a6);
							else
								engine_417745(v20, v19, v17, v22, v24, a5, a6);
						}
					}
				}
			}
		}
	}
}

//----- (00452B2A) --------------------------------------------------------
void __fastcall scrollrt_452B2A(int x, int y, int sx, int sy, int a5, int a6, int a7)
{
	int v7; // ebx
	char v8; // al
	int v9; // eax
	int v10; // eax
	MissileStruct *v11; // eax
	int *v12; // edi
	int v13; // edx
	int v14; // esi
	int v15; // ecx
	int *v16; // eax
	int *v17; // edi
	int v18; // edx
	int v19; // esi
	int v20; // ecx
	int v21; // [esp-10h] [ebp-28h]
	int v22; // [esp-10h] [ebp-28h]
	int v23; // [esp-Ch] [ebp-24h]
	int v24; // [esp-Ch] [ebp-24h]
	int v25; // [esp+Ch] [ebp-Ch]
	int v26; // [esp+10h] [ebp-8h]
	int i; // [esp+14h] [ebp-4h]

	v26 = x;
	v7 = y;
	v8 = dMissile[x][y];
	v25 = y;
	if ( v8 == -1 )
	{
		v9 = 0;
		for ( i = 0; i < nummissiles; v9 = i++ + 1 )
		{
			v10 = missileactive[v9];
			if ( v10 >= 125 )
				break;
			v11 = &missile[v10];
			if ( v11->_mix == v26 && v11->_miy == v7 && v11->_miPreFlag == a7 && v11->_miDrawFlag )
			{
				v12 = (int *)v11->_miAnimCel;
				if ( !v12 )
					return;
				v13 = v11->_miAnimFrame;
				if ( v13 < 1 || (unsigned int)*v12 > 0x32 || v13 > *v12 )
					return;
				v14 = sy + v11->_miyoff;
				v15 = sx + v11->_mixoff - v11->_miAnimWidth2;
				if ( v11->_miUniqTrans )
				{
					engine_417DF8(v15, v14, v12, v13, v11->_miAnimWidth, a5, a6, _LOBYTE(v11->_miUniqTrans) + 3);
					v7 = v25;
				}
				else
				{
					v23 = v11->_miAnimWidth;
					v21 = v11->_miAnimFrame;
					if ( v11->_miLightFlag )
						engine_417F78(v15, v14, v12, v21, v23, a5, a6);
					else
						engine_417B83(v15, v14, v12, v21, v23, a5, a6);
				}
			}
		}
	}
	else
	{
		v16 = &missileavail[44 * v8 + 81];
		if ( v16[26] == a7 )
		{
			if ( v16[24] )
			{
				v17 = (int *)v16[16];
				if ( v17 )
				{
					v18 = v16[23];
					if ( v18 >= 1 && (unsigned int)*v17 <= 0x32 && v18 <= *v17 )
					{
						v19 = sy + v16[4];
						v20 = sx + v16[3] - v16[20];
						if ( v16[27] )
						{
							engine_417DF8(v20, v19, v17, v18, v16[19], a5, a6, *((_BYTE *)v16 + 108) + 3);
						}
						else
						{
							v24 = v16[19];
							v22 = v16[23];
							if ( v16[25] )
								engine_417F78(v20, v19, v17, v22, v24, a5, a6);
							else
								engine_417B83(v20, v19, v17, v22, v24, a5, a6);
						}
					}
				}
			}
		}
	}
}

//----- (00452CC0) --------------------------------------------------------
void __fastcall scrollrt_452CC0(int x, int y, int sx, int sy, int a5, int a6, int some_flag)
{
	int v7; // ebx
	int *v8; // esi
	char *v9; // edi
	int *v10; // eax
	int v11; // ecx
	int xa; // [esp+Ch] [ebp-4h]
	int player_num; // [esp+28h] [ebp+18h]

	v7 = y;
	xa = x;
	draw_player = (int (__fastcall *)(int, int, int, int, int, void *, int, int, int, int))scrollrt_draw_player_b;
	if ( !some_flag )
		draw_player = (int (__fastcall *)(int, int, int, int, int, void *, int, int, int, int))scrollrt_draw_player_a;
	v8 = &plr[0]._pHitPoints;
	v9 = &dFlags[x][y];
	*v9 &= 0xFBu;
	player_num = 0;
	do
	{
		if ( !*((_BYTE *)v8 - 379) || *v8 || *(v8 - 89) != currlevel || *(v8 - 88) != xa || *(v8 - 87) != v7 )
			goto LABEL_14;
		v10 = (int *)*(v8 - 71);
		if ( !v10 )
			break;
		v11 = *(v8 - 67);
		if ( v11 < 1 || (unsigned int)*v10 > 0x32 || v11 > *v10 )
			break;
		*v9 |= 4u;
		draw_player(player_num, xa, v7, sx + *(v8 - 78) - *(v8 - 65), sy + *(v8 - 77), v10, v11, *(v8 - 66), a5, a6);
LABEL_14:
		++player_num;
		v8 += 5430;
	}
	while ( (signed int)v8 < (signed int)&plr_msgs[2].msg[51] );
}

//----- (00452DA0) --------------------------------------------------------
void __fastcall scrollrt_draw_player_a(int pnum, int x, int y, int px, int py, int animdata, int animframe, int animwidth, int a9, int a10)
{
	char *v10; // edx
	int v11; // eax
	void *v12; // ecx
	int v13; // [esp+Ch] [ebp-4h]
	int ya; // [esp+18h] [ebp+8h]
	int animdataa; // [esp+24h] [ebp+14h]

	v10 = &dFlags[x][y];
	v11 = myplr;
	v13 = pnum;
	ya = (int)v10;
	if ( *v10 & 0x40 || plr[myplr]._pInfraFlag || !setlevel && !currlevel )
	{
		v12 = (void *)animdata;
		if ( animdata )
		{
			if ( animframe >= 1 && *(_DWORD *)animdata <= 0x32u && animframe <= *(_DWORD *)animdata )
			{
				if ( v13 == pcursplr )
				{
					engine_417847(165, px, py, (void *)animdata, animframe, animwidth, a9, a10);
					v11 = myplr;
					v12 = (void *)animdata;
					v10 = (char *)ya;
				}
				if ( v13 == v11 )
				{
					engine_417745(px, py, v12, animframe, animwidth, a9, a10);
					if ( plr[v13].pManaShield )
						engine_417745(
							px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0],
							py,
							(void *)misfiledata[9].mAnimCel[0],
							1,
							misfiledata[9].mAnimWidth[0],
							a9,
							a10);
				}
				else if ( !(*v10 & 0x40) || plr[v11]._pInfraFlag && light_table_index > 8 )
				{
					engine_417981(px, py, v12, animframe, animwidth, a9, a10, 1);
					if ( plr[v13].pManaShield )
						engine_417981(
							px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0],
							py,
							(void *)misfiledata[9].mAnimCel[0],
							1,
							misfiledata[9].mAnimWidth[0],
							a9,
							a10,
							1);
				}
				else
				{
					animdataa = light_table_index;
					if ( light_table_index >= 5 )
						light_table_index -= 5;
					else
						light_table_index = 0;
					engine_417AE9(px, py, v12, animframe, animwidth, a9, a10);
					if ( plr[v13].pManaShield )
						engine_417AE9(
							px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0],
							py,
							(void *)misfiledata[9].mAnimCel[0],
							1,
							misfiledata[9].mAnimWidth[0],
							a9,
							a10);
					light_table_index = animdataa;
				}
			}
		}
	}
}
// 4B8CC2: using guessed type char pcursplr;
// 5CF31D: using guessed type char setlevel;
// 69BEF8: using guessed type int light_table_index;

//----- (00452F8B) --------------------------------------------------------
void __fastcall scrollrt_draw_player_b(int pnum, int x, int y, int px, int py, int animdata, int animframe, int animwidth, int a9, int a10)
{
	char *v10; // edx
	int v11; // eax
	void *v12; // ecx
	int v13; // [esp+Ch] [ebp-4h]
	int ya; // [esp+18h] [ebp+8h]
	int animdataa; // [esp+24h] [ebp+14h]

	v10 = &dFlags[x][y];
	v11 = myplr;
	v13 = pnum;
	ya = (int)v10;
	if ( *v10 & 0x40 || plr[myplr]._pInfraFlag )
	{
		v12 = (void *)animdata;
		if ( animdata )
		{
			if ( animframe >= 1 && *(_DWORD *)animdata <= 0x32u && animframe <= *(_DWORD *)animdata )
			{
				if ( v13 == pcursplr )
				{
					engine_417C99(165, px, py, (void *)animdata, animframe, animwidth, a9, a10);
					v11 = myplr;
					v12 = (void *)animdata;
					v10 = (char *)ya;
				}
				if ( v13 == v11 )
				{
					engine_417B83(px, py, v12, animframe, animwidth, a9, a10);
					if ( plr[v13].pManaShield )
						engine_417B83(
							px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0],
							py,
							(void *)misfiledata[9].mAnimCel[0],
							1,
							misfiledata[9].mAnimWidth[0],
							a9,
							a10);
				}
				else if ( !(*v10 & 0x40) || plr[v11]._pInfraFlag && light_table_index > 8 )
				{
					engine_417DF8(px, py, v12, animframe, animwidth, a9, a10, 1);
					if ( plr[v13].pManaShield )
						engine_417DF8(
							px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0],
							py,
							(void *)misfiledata[9].mAnimCel[0],
							1,
							misfiledata[9].mAnimWidth[0],
							a9,
							a10,
							1);
				}
				else
				{
					animdataa = light_table_index;
					if ( light_table_index >= 5 )
						light_table_index -= 5;
					else
						light_table_index = 0;
					engine_417F78(px, py, v12, animframe, animwidth, a9, a10);
					if ( plr[v13].pManaShield )
						engine_417F78(
							px + plr[v13]._pAnimWidth2 - misfiledata[9].mAnimWidth2[0],
							py,
							(void *)misfiledata[9].mAnimCel[0],
							1,
							misfiledata[9].mAnimWidth[0],
							a9,
							a10);
					light_table_index = animdataa;
				}
			}
		}
	}
}
// 4B8CC2: using guessed type char pcursplr;
// 69BEF8: using guessed type int light_table_index;

//----- (00453160) --------------------------------------------------------
void __fastcall DrawView(int StartX, int StartY)
{
	if ( zoomflag )
		DrawGame(StartX, StartY);
	else
		DrawZoom(StartX, StartY);
	if ( *(_DWORD *)&automapflag )
		DrawAutomap();
	if ( invflag )
	{
		DrawInv();
	}
	else if ( sbookflag )
	{
		DrawSpellBook();
	}
	DrawDurIcon();
	if ( chrflag )
	{
		DrawChr();
	}
	else if ( questlog )
	{
		DrawQuestLog();
	}
	else if ( plr[myplr]._pStatPts && !spselflag )
	{
		DrawLevelUpIcon();
	}
	if ( uitemflag )
		DrawUniqueInfo();
	if ( qtextflag )
		DrawQText();
	if ( spselflag )
		DrawSpellList();
	if ( dropGoldFlag )
		DrawGoldSplit(dropGoldValue);
	if ( helpflag )
		DrawHelp();
	if ( msgflag )
		DrawDiabloMsg();
	if ( *(_DWORD *)&deathflag )
	{
		RedBack();
	}
	else if ( PauseMode )
	{
		gmenu_draw_pause();
	}
	DrawPlrMsg();
	gmenu_draw();
	doom_draw();
	DrawInfoBox();
	DrawLifeFlask();
	DrawManaFlask();
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8968: using guessed type int sbookflag;
// 4B8C98: using guessed type int spselflag;
// 52569C: using guessed type int zoomflag;
// 525740: using guessed type int PauseMode;
// 52B9F1: using guessed type char msgflag;
// 646D00: using guessed type char qtextflag;
// 69BD04: using guessed type int questlog;

//----- (00453272) --------------------------------------------------------
void __fastcall DrawGame(int x, int y)
{
	int v2; // esi
	int v3; // ebx
	int v4; // edi
	int v5; // edi
	int v6; // esi
	int v7; // edi
	int v8; // esi
	int v9; // edi
	int v10; // esi
	signed int v11; // [esp+Ch] [ebp-10h]
	signed int a6; // [esp+10h] [ebp-Ch]
	signed int a6a; // [esp+10h] [ebp-Ch]
	signed int a5; // [esp+14h] [ebp-8h]
	int ya; // [esp+18h] [ebp-4h]

	dword_5C2FF8 = 10;
	v2 = ScrollInfo._sxoff + 64;
	v3 = x - 10;
	ya = y - 1;
	a5 = 10;
	v4 = ScrollInfo._syoff + 175;
	scr_pix_width = 640;
	scr_pix_height = 352;
	dword_5C2FFC = 11;
	v11 = 8;
	if ( chrflag || questlog )
	{
		ya = y - 3;
		v3 += 2;
		v2 = ScrollInfo._sxoff + 352;
		a5 = 6;
	}
	if ( invflag || sbookflag )
	{
		ya -= 2;
		v3 += 2;
		v2 -= 32;
		a5 = 6;
	}
	switch ( ScrollInfo._sdir )
	{
		case DIR_SW:
			goto LABEL_9;
		case DIR_W:
			++a5;
LABEL_9:
			v4 = ScrollInfo._syoff + 143;
			--v3;
			--ya;
			goto LABEL_15;
		case DIR_NW:
			goto LABEL_13;
		case DIR_N:
			v11 = 9;
			goto LABEL_13;
		case DIR_NE:
			goto LABEL_15;
		case DIR_E:
			v11 = 9;
			goto LABEL_12;
		case DIR_SE:
LABEL_12:
			v2 -= 64;
			--v3;
			++ya;
LABEL_13:
			++a5;
			break;
		case DIR_OMNI:
			v2 -= 64;
			v4 = ScrollInfo._syoff + 143;
			v3 -= 2;
			++a5;
LABEL_15:
			v11 = 9;
			break;
		default:
			break;
	}
	a6 = 0;
	screen_buf_end = (int)gpBuffer + screen_y_times_768[160];
	do
	{
		scrollrt_454D9D(v3, ya++, v2, v4, a5, a6, 0);
		v5 = v4 + 16;
		v6 = v2 - 32;
		scrollrt_454D9D(v3++, ya, v6, v5, a5, a6, 1);
		v2 = v6 + 32;
		v4 = v5 + 16;
		++a6;
	}
	while ( a6 < 4 );
	screen_buf_end = (int)gpBuffer + screen_y_times_768[512];
	if ( v11 > 0 )
	{
		do
		{
			scrollrt_levels(v3, ya++, v2, v4, a5, 0);
			v7 = v4 + 16;
			v8 = v2 - 32;
			scrollrt_levels(v3++, ya, v8, v7, a5, 1);
			v2 = v8 + 32;
			v4 = v7 + 16;
			--v11;
		}
		while ( v11 );
	}
	arch_draw_type = 0;
	a6a = 0;
	do
	{
		scrollrt_454229(v3, ya++, v2, v4, a5, a6a, 0);
		v9 = v4 + 16;
		v10 = v2 - 32;
		scrollrt_454229(v3++, ya, v10, v9, a5, a6a, 1);
		v2 = v10 + 32;
		v4 = v9 + 16;
		++a6a;
	}
	while ( a6a < 4 );
}
// 4B8968: using guessed type int sbookflag;
// 5C2FF8: using guessed type int dword_5C2FF8;
// 5C2FFC: using guessed type int dword_5C2FFC;
// 5C3000: using guessed type int scr_pix_width;
// 5C3004: using guessed type int scr_pix_height;
// 69BD04: using guessed type int questlog;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF20: using guessed type char arch_draw_type;

//----- (00453477) --------------------------------------------------------
void __fastcall scrollrt_levels(int x, int y, int sx, int sy, int a5, int some_flag)
{
	unsigned int v6; // edi
	unsigned int v7; // ebx
	unsigned short *v8; // esi
	unsigned int v9; // ebx
	int v10; // eax
	int v11; // ecx
	int v12; // edx
	char *v13; // edx
	int v14; // edi
	int v15; // eax
	char *v16; // edi
	char *v17; // edi
	char *v18; // edi
	char *v19; // edi
	int v20; // eax
	int v21; // edi
	int v22; // ecx
	int v23; // ecx
	int v24; // eax
	int *v25; // ebx
	int v26; // ecx
	int v27; // eax
	int v28; // edi
	char *v29; // edi
	int v30; // eax
	int v31; // eax
	int v32; // eax
	int v33; // ecx
	int v34; // eax
	int *v35; // edi
	int v36; // ecx
	int v37; // eax
	char *v38; // edi
	char *v39; // edi
	int v40; // eax
	char *v41; // edi
	char *v42; // edi
	char *v43; // edi
	char *v44; // edi
	int v45; // eax
	int v46; // [esp+Ch] [ebp-10h]
	int v47; // [esp+10h] [ebp-Ch]
	signed int sya; // [esp+14h] [ebp-8h]
	unsigned int sxa; // [esp+18h] [ebp-4h]
	signed int i; // [esp+2Ch] [ebp+10h]
	int *v51; // [esp+2Ch] [ebp+10h]

	v6 = y;
	v7 = x;
	sya = y;
	sxa = x;
	v8 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y));
	if ( some_flag )
	{
		if ( v6 < 0x70 && v7 < 0x70 )
		{
			v9 = v7;
			v10 = dPiece[0][v9 * 112 + v6];
			light_table_index = dTransVal[v9][v6];
			level_piece_id = v10;
			if ( v10 )
			{
				v11 = (unsigned char)(nTransTable[v10] & TransList[dung_map[v9][v6]]);
				arch_draw_type = 2;
				v12 = screen_y_times_768[sy];
				cel_transparency_active = v11;
				v13 = (char *)gpBuffer + v12;
				level_cel_block = v8[1];
				v14 = (int)&v13[sx + 32];
				if ( level_cel_block )
					drawLowerScreen(&v13[sx + 32]);
				v15 = v8[3];
				arch_draw_type = 0;
				v16 = (char *)(v14 - 24576);
				level_cel_block = v15;
				if ( v15 )
					drawLowerScreen(v16);
				v17 = v16 - 24576;
				level_cel_block = v8[5];
				if ( level_cel_block )
					drawLowerScreen(v17);
				v18 = v17 - 24576;
				level_cel_block = v8[7];
				if ( level_cel_block )
					drawLowerScreen(v18);
				v19 = v18 - 24576;
				level_cel_block = v8[9];
				if ( level_cel_block )
					drawLowerScreen(v19);
				v20 = v8[11];
				level_cel_block = v8[11];
				if ( v20 && leveltype == 4 )
					drawLowerScreen(v19 - 24576);
				v21 = sy;
				scrollrt_dead((char *)gpBuffer + screen_y_times_768[sy] + sx, sxa, sya, sx, sy, 0);
				goto LABEL_21;
			}
			world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx);
		}
		v21 = sy;
LABEL_21:
		++sxa;
		--sya;
		sx += 64;
		v8 += 16;
		--a5;
		goto LABEL_23;
	}
	v21 = sy;
LABEL_23:
	v46 = a5;
	if ( a5 )
	{
		v22 = 112 * sxa;
		v47 = 112 * sxa;
		do
		{
			--v46;
			if ( sya < 0 || v22 >= 12544 )
				break;
			if ( sya < 112 && v22 >= 0 )
			{
				v23 = sya + v22;
				v24 = dPiece[0][v23];
				light_table_index = dTransVal[0][v23];
				level_piece_id = v24;
				if ( v24 )
				{
					v25 = &screen_y_times_768[v21];
					v26 = (unsigned char)(nTransTable[v24] & TransList[dung_map[0][v23]]);
					v27 = *v8;
					v28 = *v25;
					cel_transparency_active = v26;
					arch_draw_type = 1;
					level_cel_block = v27;
					v29 = (char *)gpBuffer + v28 + sx;
					if ( v27 )
						drawLowerScreen(v29);
					v30 = v8[1];
					arch_draw_type = 2;
					level_cel_block = v30;
					if ( v30 )
						drawLowerScreen(v29 + 32);
					arch_draw_type = 0;
					v31 = 2;
					for ( i = 2; i < dword_5A5594; i += 2 )
					{
						v29 -= 24576;
						level_cel_block = v8[v31];
						if ( level_cel_block )
							drawLowerScreen(v29);
						v32 = v8[i + 1];
						level_cel_block = v8[i + 1];
						if ( v32 )
							drawLowerScreen(v29 + 32);
						v31 = i + 2;
					}
					scrollrt_dead((char *)gpBuffer + *v25 + sx, sxa, sya, sx, sy, 1);
					v21 = sy;
				}
				else
				{
					world_levelrelated((char *)gpBuffer + screen_y_times_768[v21] + sx);
				}
				v22 = v47;
			}
			++sxa;
			sx += 64;
			v22 += 112;
			--sya;
			v8 += 16;
			v47 = v22;
		}
		while ( v46 );
	}
	if ( some_flag && (unsigned int)sya < 0x70 && sxa < 0x70 )
	{
		v33 = sya + 112 * sxa;
		v34 = dPiece[0][v33];
		light_table_index = dTransVal[0][v33];
		level_piece_id = v34;
		if ( v34 )
		{
			v35 = &screen_y_times_768[v21];
			v36 = (unsigned char)(nTransTable[v34] & TransList[dung_map[0][v33]]);
			v37 = *v8;
			v51 = v35;
			v38 = (char *)gpBuffer + *v35;
			cel_transparency_active = v36;
			arch_draw_type = 1;
			level_cel_block = v37;
			v39 = &v38[sx];
			if ( v37 )
				drawLowerScreen(v39);
			v40 = v8[2];
			arch_draw_type = 0;
			v41 = v39 - 24576;
			level_cel_block = v40;
			if ( v40 )
				drawLowerScreen(v41);
			v42 = v41 - 24576;
			level_cel_block = v8[4];
			if ( level_cel_block )
				drawLowerScreen(v42);
			v43 = v42 - 24576;
			level_cel_block = v8[6];
			if ( level_cel_block )
				drawLowerScreen(v43);
			v44 = v43 - 24576;
			level_cel_block = v8[8];
			if ( level_cel_block )
				drawLowerScreen(v44);
			v45 = v8[10];
			level_cel_block = v8[10];
			if ( v45 )
			{
				if ( leveltype == 4 )
					drawLowerScreen(v44 - 24576);
			}
			scrollrt_dead((char *)gpBuffer + *v51 + sx, sxa, sya, sx, sy, 0);
		}
		else
		{
			world_levelrelated((char *)gpBuffer + screen_y_times_768[v21] + sx);
		}
	}
}
// 5BB1ED: using guessed type char leveltype;
// 69BEF8: using guessed type int light_table_index;
// 69CF14: using guessed type int level_cel_block;
// 69CF20: using guessed type char arch_draw_type;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (004538E2) --------------------------------------------------------
void __fastcall scrollrt_dead(char *a1, int sx, int sy, int a4, int a5, int a6)
{
	int v6; // eax
	char v7; // bl
	char v8; // cl
	char v9; // dl
	int *v10; // eax
	void **v11; // eax
	int *v12; // esi
	int v13; // ecx
	int v14; // edx
	char v15; // bl
	ItemStruct *v16; // esi
	char *v17; // eax
	signed int v18; // ebx
	int v19; // ebx
	unsigned int v20; // ecx
	PlayerStruct *v21; // esi
	int v22; // esi
	int v23; // eax
	MonsterStruct *v24; // esi
	CMonster *v25; // ecx
	int v26; // ebx
	int v27; // edi
	unsigned int v28; // ecx
	PlayerStruct *v29; // esi
	int v30; // esi
	int v31; // eax
	MonsterStruct *v32; // esi
	CMonster *v33; // ecx
	int v34; // ebx
	int v35; // edi
	ItemStruct *v36; // esi
	char *v37; // ecx
	signed int v38; // ebx
	int v39; // ebx
	int v40; // [esp+Ch] [ebp-18h]
	int v41; // [esp+10h] [ebp-14h]
	char *dst_buf; // [esp+14h] [ebp-10h]
	int a1a; // [esp+18h] [ebp-Ch]
	char v44; // [esp+1Dh] [ebp-7h]
	char v45; // [esp+1Eh] [ebp-6h]
	char v46; // [esp+1Fh] [ebp-5h]
	char v47; // [esp+20h] [ebp-4h]
	char v48; // [esp+21h] [ebp-3h]
	char v49; // [esp+22h] [ebp-2h]
	char v50; // [esp+23h] [ebp-1h]

	a1a = sx;
	dst_buf = a1;
	v6 = 112 * sx + sy;
	v7 = dDead[0][v6];
	v50 = dFlags[0][v6];
	v47 = dObject[0][v6];
	v49 = dItem[0][v6];
	v8 = dPlayer[0][v6 - 1];
	v48 = dPlayer[0][v6];
	v46 = dArch[0][v6];
	v9 = dung_map[0][v6];
	v10 = (int *)((char *)dMonster + 4 * v6);
	v44 = v9;
	v45 = v8;
	v40 = *v10;
	v41 = *(v10 - 1);
	if ( visiondebug && v50 & 0x40 )
		Cel2_header_into_buf(dst_buf, (char *)pSquareCel, 1, 64, 0, 8);
	if ( MissilePreFlag && v50 & 1 )
		scrollrt_452B2A(a1a, sy, a4, a5, 0, 8, 1);
	if ( light_table_index < lightmax )
	{
		if ( v7 )
		{
			v11 = &pCursCels + 12 * (v7 & 0x1F);
			v12 = (int *)v11[(v7 >> 5) & 7];
			v13 = a4 - (_DWORD)v11[10];
			if ( v12 )
			{
				v14 = (int)v11[8];
				if ( v14 >= 1 && (unsigned int)*v12 <= 0x32 && v14 <= *v12 )
				{
					v15 = *((_BYTE *)v11 + 44);
					if ( v15 )
						engine_417DF8(v13, a5, v12, v14, (int)v11[9], 0, 8, v15);
					else
						engine_417F78(v13, a5, v12, v14, (int)v11[9], 0, 8);
				}
			}
		}
		if ( v47 )
			scrollrt_objects(a1a, sy, a4, a5, 1, 0, 8);
	}
	if ( v49 )
	{
		v16 = &item_stru_6358B8 + v49;
		if ( !v16->_iPostDraw && (unsigned char)v49 <= 0x7Fu )
		{
			v17 = (char *)v16->ItemFrame;
			if ( v17 )
			{
				v18 = v16->_iAnimFrame;
				if ( v18 >= 1 && *(_DWORD *)v17 <= 0x32u && v18 <= *(_DWORD *)v17 )
				{
					v19 = a4 - v16->_iAnimXOff;
					if ( v49 - 1 == pcursitem )
						Cel_header_and_colour_highlight(181, v19, a5, v17, v16->_iAnimFrame, v16->_iAnimWidth, 0, 8);
					Cel2_header_and_light(v19, a5, (char *)v16->ItemFrame, v16->_iAnimFrame, v16->_iAnimWidth, 0, 8);
				}
			}
		}
	}
	if ( v50 & 0x20 )
	{
		v20 = -1 - v45;
		if ( v20 < 4 )
		{
			v21 = &plr[v20];
			scrollrt_draw_player_b(
				v20,
				a1a,
				sy - 1,
				a4 + v21->_pxoff - v21->_pAnimWidth2,
				a5 + v21->_pyoff,
				v21->_pAnimData,
				v21->_pAnimFrame,
				v21->_pAnimWidth,
				0,
				8);
			if ( a6 )
			{
				v22 = v21->_peflag;
				if ( v22 )
				{
					if ( v22 == 2 )
						scrollrt_4540E5(dst_buf - 12384, a1a - 2, sy + 1, a4 - 96, a5 - 16);
					scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5);
				}
			}
		}
	}
	if ( v50 & 0x10 && (v50 & 0x40 || plr[myplr]._pInfraFlag) && v41 < 0 )
	{
		v23 = -1 - v41;
		draw_monster_num = -1 - v41;
		if ( (unsigned int)(-1 - v41) < 0xC8 )
		{
			v24 = &monster[v23];
			if ( !(v24->_mFlags & 1) )
			{
				v25 = v24->MType;
				if ( v25 )
				{
					v26 = a5 + v24->_myoff;
					v27 = a4 + v24->_mxoff - v25->flags_2;
					if ( v23 == *(_DWORD *)&pcursmonst )
					{
						engine_417C99(233, v27, v26, (void *)v24->_mAFNum, v24->_mAnimFrame, v25->flags_1, 0, 8);
						v23 = draw_monster_num;
					}
					scrollrt_monsters(a1a, sy, v27, v26, v23, 0, 8);
					if ( a6 && v24->_meflag )
						scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5);
				}
			}
		}
	}
	if ( v50 & 4 )
		scrollrt_452CC0(a1a, sy, a4, a5, 0, 8, 1);
	if ( v48 > 0 )
	{
		v28 = v48 - 1;
		if ( v28 < 4 )
		{
			v29 = &plr[v28];
			scrollrt_draw_player_b(
				v28,
				a1a,
				sy,
				a4 + v29->_pxoff - v29->_pAnimWidth2,
				a5 + v29->_pyoff,
				v29->_pAnimData,
				v29->_pAnimFrame,
				v29->_pAnimWidth,
				0,
				8);
			if ( a6 )
			{
				v30 = v29->_peflag;
				if ( v30 )
				{
					if ( v30 == 2 )
						scrollrt_4540E5(dst_buf - 12384, a1a - 2, sy + 1, a4 - 96, a5 - 16);
					scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5);
				}
			}
		}
	}
	if ( v40 > 0 && (v50 & 0x40 || plr[myplr]._pInfraFlag) )
	{
		v31 = v40 - 1;
		draw_monster_num = v40 - 1;
		if ( (unsigned int)(v40 - 1) < 0xC8 )
		{
			v32 = &monster[v31];
			if ( !(v32->_mFlags & 1) )
			{
				v33 = v32->MType;
				if ( v33 )
				{
					v34 = a5 + v32->_myoff;
					v35 = a4 + v32->_mxoff - v33->flags_2;
					if ( v31 == *(_DWORD *)&pcursmonst )
					{
						engine_417C99(233, v35, v34, (void *)v32->_mAFNum, v32->_mAnimFrame, v33->flags_1, 0, 8);
						v31 = draw_monster_num;
					}
					scrollrt_monsters(a1a, sy, v35, v34, v31, 0, 8);
					if ( a6 && v32->_meflag )
						scrollrt_4540E5(dst_buf - 64, a1a - 1, sy + 1, a4 - 64, a5);
				}
			}
		}
	}
	if ( v50 & 1 )
		scrollrt_452B2A(a1a, sy, a4, a5, 0, 8, 0);
	if ( v47 && light_table_index < lightmax )
		scrollrt_objects(a1a, sy, a4, a5, 0, 0, 8);
	if ( v49 )
	{
		v36 = &item_stru_6358B8 + v49;
		if ( v36->_iPostDraw )
		{
			if ( (unsigned char)v49 <= 0x7Fu )
			{
				v37 = (char *)v36->ItemFrame;
				if ( v37 )
				{
					v38 = v36->_iAnimFrame;
					if ( v38 >= 1 && *(_DWORD *)v37 <= 0x32u && v38 <= *(_DWORD *)v37 )
					{
						v39 = a4 - v36->_iAnimXOff;
						if ( v49 - 1 == pcursitem )
							Cel_header_and_colour_highlight(181, v39, a5, v37, v36->_iAnimFrame, v36->_iAnimWidth, 0, 8);
						Cel2_header_and_light(
							v39,
							a5,
							(char *)v36->ItemFrame,
							v36->_iAnimFrame,
							v36->_iAnimWidth,
							0,
							8);
					}
				}
			}
		}
	}
	if ( v46 )
	{
		cel_transparency_active = (unsigned char)TransList[v44];
		Cel2_header_light_and_trans_into_buf(dst_buf, (char *)level_special_cel, v46, 64, 0, 8);
	}
}
// 4B8CC0: using guessed type char pcursitem;
// 525720: using guessed type int visiondebug;
// 642A14: using guessed type char lightmax;
// 64CCD4: using guessed type int MissilePreFlag;
// 69BEF8: using guessed type int light_table_index;
// 69CF94: using guessed type int cel_transparency_active;
// 69EFA4: using guessed type int draw_monster_num;

//----- (00453ED9) --------------------------------------------------------
void __fastcall scrollrt_monsters(int x, int y, int a3, int a4, int mon_id, int a6, int a7)
{
	int v7; // eax
	signed int *v8; // esi
	signed int v9; // ebx
	char v10; // cl
	CMonster *v11; // eax
	char mon_ida; // [esp+1Ch] [ebp+10h]

	if ( (unsigned int)mon_id < 0xC8 )
	{
		v7 = mon_id;
		v8 = (signed int *)monster[mon_id]._mAFNum;
		if ( v8 )
		{
			v9 = monster[v7]._mAnimFrame;
			if ( v9 >= 1 && (unsigned int)*v8 <= 0x32 && v9 <= *v8 )
			{
				if ( dFlags[x][y] & 0x40 )
				{
					v10 = 0;
					mon_ida = 0;
					if ( monster[v7]._uniqtype )
					{
						v10 = monster[v7]._uniqtrans + 4;
						mon_ida = monster[v7]._uniqtrans + 4;
					}
					if ( monster[v7]._mmode == MM_STONE )
					{
						v10 = 2;
						mon_ida = 2;
					}
					if ( plr[myplr]._pInfraFlag && light_table_index > 8 )
					{
						v10 = 1;
						mon_ida = 1;
					}
					v11 = monster[v7].MType;
					if ( v10 )
						engine_417DF8(a3, a4, v8, v9, v11->flags_1, a6, a7, mon_ida);
					else
						engine_417F78(a3, a4, v8, v9, v11->flags_1, a6, a7);
				}
				else
				{
					engine_417DF8(a3, a4, v8, v9, monster[v7].MType->flags_1, a6, a7, 1);
				}
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00453FCC) --------------------------------------------------------
void __fastcall scrollrt_objects(int x, int y, int a3, int a4, int pre_flag, int a6, int dir)
{
	int v7; // edi
	char v8; // al
	unsigned char v9; // dl
	int v10; // esi
	int v11; // ebx
	int v12; // edi
	int v13; // eax
	int v14; // ecx
	char *v15; // eax
	signed int v16; // ecx
	char *v17; // [esp-14h] [ebp-24h]
	int v18; // [esp-10h] [ebp-20h]
	int v19; // [esp-Ch] [ebp-1Ch]
	char v20; // [esp+Fh] [ebp-1h]

	v7 = y;
	v8 = dObject[x][y];
	if ( v8 <= 0 )
	{
		v9 = -1 - v8;
		v10 = (char)(-1 - v8);
		v20 = -1 - v8;
		if ( object[v10]._oPreFlag != pre_flag )
			return;
		dir = 8;
		v13 = object[v10]._ox - x;
		v14 = object[v10]._oy - v7;
		v12 = a3 + 32 * v13 - object[v10]._oAnimWidth2 - 32 * v14;
		v11 = a4 + 16 * (v14 + v13);
		a6 = 0;
	}
	else
	{
		v9 = v8 - 1;
		v10 = (char)(v8 - 1);
		v20 = v8 - 1;
		if ( object[v10]._oPreFlag != pre_flag )
			return;
		v11 = a4;
		v12 = a3 - object[v10]._oAnimWidth2;
	}
	if ( v9 < 0x7Fu )
	{
		v15 = (char *)object[v10]._oAnimCel;
		if ( v15 )
		{
			v16 = object[v10]._oAnimFrame;
			if ( v16 >= 1 && *(_DWORD *)v15 <= 0x32u && v16 <= *(_DWORD *)v15 )
			{
				if ( v20 == pcursobj )
					Cel_header_and_colour_highlight(194, v12, v11, v15, v16, object[v10]._oAnimWidth, a6, dir);
				v19 = object[v10]._oAnimWidth;
				v18 = object[v10]._oAnimFrame;
				v17 = (char *)object[v10]._oAnimCel;
				if ( object[v10]._oLight )
					Cel2_header_and_light(v12, v11, v17, v18, v19, a6, dir);
				else
					Cel2_header(v12, v11, v17, v18, v19, a6, dir);
			}
		}
	}
}
// 4B8CC1: using guessed type char pcursobj;

//----- (004540E5) --------------------------------------------------------
void __fastcall scrollrt_4540E5(char *buffer, int x, int y, int a4, int a5)
{
	int v5; // eax
	int v6; // ebx
	int v7; // ecx
	int v8; // esi
	int v9; // eax
	int v10; // edi
	int v11; // eax
	int v12; // eax
	unsigned short *v13; // esi
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // eax
	int v18; // [esp+Ch] [ebp-14h]
	int xa; // [esp+10h] [ebp-10h]
	int i; // [esp+14h] [ebp-Ch]
	char *a1; // [esp+18h] [ebp-8h]
	char *v22; // [esp+1Ch] [ebp-4h]

	xa = x;
	v18 = level_piece_id;
	v5 = y + 112 * x;
	a1 = buffer;
	v6 = cel_transparency_active;
	v7 = dPiece[0][v5];
	v8 = dTransVal[0][v5];
	v9 = dung_map[0][v5];
	v10 = light_table_index;
	level_piece_id = v7;
	v11 = (unsigned char)(nTransTable[v7] & TransList[v9]);
	light_table_index = v8;
	cel_transparency_active = v11;
	v12 = gendung_41927A(x, y);
	arch_draw_type = 1;
	v13 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * v12);
	v14 = *v13;
	level_cel_block = *v13;
	if ( v14 )
		drawLowerScreen(a1);
	v15 = v13[1];
	arch_draw_type = 2;
	level_cel_block = v15;
	if ( v15 )
		drawLowerScreen(a1 + 32);
	arch_draw_type = 0;
	v22 = a1;
	v16 = 2;
	for ( i = 2; i < dword_5A5594; i += 2 )
	{
		v22 -= 24576;
		level_cel_block = v13[v16];
		if ( level_cel_block )
			drawLowerScreen(v22);
		v17 = v13[i + 1];
		level_cel_block = v13[i + 1];
		if ( v17 )
			drawLowerScreen(v22 + 32);
		v16 = i + 2;
	}
	scrollrt_dead(a1, xa, y, a4, a5, 0);
	light_table_index = v10;
	cel_transparency_active = v6;
	level_piece_id = v18;
}
// 69BEF8: using guessed type int light_table_index;
// 69CF14: using guessed type int level_cel_block;
// 69CF20: using guessed type char arch_draw_type;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (00454229) --------------------------------------------------------
void __fastcall scrollrt_454229(int x, int y, int sx, int sy, int a5, int a6, int some_flag)
{
	signed int v7; // ebx
	int v8; // edi
	int v9; // ecx
	int v10; // eax
	int v11; // eax
	int v12; // eax
	int v13; // ecx
	int v14; // ecx
	int v15; // eax
	char *v16; // ebx
	int v17; // eax
	int v18; // eax
	int v19; // ecx
	int v20; // eax
	int v21; // eax
	int v22; // eax
	int v23; // [esp+Ch] [ebp-14h]
	unsigned short *v24; // [esp+10h] [ebp-10h]
	int v25; // [esp+10h] [ebp-10h]
	int a1; // [esp+14h] [ebp-Ch]
	char *a1a; // [esp+14h] [ebp-Ch]
	char *a1b; // [esp+14h] [ebp-Ch]
	char *v29; // [esp+18h] [ebp-8h]
	signed int xa; // [esp+1Ch] [ebp-4h]
	int a6a; // [esp+28h] [ebp+8h]
	int a6b; // [esp+28h] [ebp+8h]
	int a6c; // [esp+28h] [ebp+8h]
	unsigned short *a5a; // [esp+30h] [ebp+10h]
	unsigned short *a5b; // [esp+30h] [ebp+10h]

	v7 = y;
	a1 = y;
	xa = x;
	v8 = sx;
	v29 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y);
	if ( some_flag )
	{
		if ( v7 >= 0 && v7 < 112 && xa >= 0 && xa < 112 )
		{
			v9 = 112 * xa + v7;
			v10 = dPiece[0][v9];
			light_table_index = dTransVal[0][v9];
			level_piece_id = v10;
			if ( v10 )
			{
				a6a = 0;
				cel_transparency_active = (unsigned char)(nTransTable[v10] & TransList[dung_map[0][v9]]);
				a1a = (char *)gpBuffer + screen_y_times_768[sy] + v8 - 24544;
				if ( (dword_5A5594 >> 1) - 1 > 0 )
				{
					v24 = (unsigned short *)(v29 + 6);
					do
					{
						if ( a6 <= a6a )
						{
							v11 = *v24;
							level_cel_block = *v24;
							if ( v11 )
								drawLowerScreen(a1a);
						}
						a1a -= 24576;
						++a6a;
						v24 += 2;
					}
					while ( a6a < (dword_5A5594 >> 1) - 1 );
				}
				v12 = 2 * a6 + 2;
				if ( v12 < 8 )
					scrollrt_4545D2(
						(char *)gpBuffer + screen_y_times_768[sy] - 12288 * v12 + v8,
						xa,
						v7,
						a6,
						2 * a6 + 2,
						v8,
						sy,
						0);
			}
		}
		++xa;
		--v7;
		v8 += 64;
		--a5;
		v29 += 32;
		a1 = v7;
	}
	v25 = a5;
	if ( a5 )
	{
		v13 = 112 * xa;
		v23 = 112 * xa;
		do
		{
			--v25;
			if ( v13 >= 12544 || v7 < 0 )
				break;
			if ( v7 < 112 && v13 >= 0 )
			{
				v14 = v7 + v13;
				v15 = dPiece[0][v14];
				light_table_index = dTransVal[0][v14];
				level_piece_id = v15;
				if ( v15 )
				{
					a6b = 0;
					cel_transparency_active = (unsigned char)(nTransTable[v15] & TransList[dung_map[0][v14]]);
					v16 = (char *)gpBuffer + screen_y_times_768[sy] + v8 - 24576;
					if ( (dword_5A5594 >> 1) - 1 > 0 )
					{
						a5a = (unsigned short *)(v29 + 6);
						do
						{
							if ( a6 <= a6b )
							{
								v17 = *(a5a - 1);
								level_cel_block = *(a5a - 1);
								if ( v17 )
									drawLowerScreen(v16);
								v18 = *a5a;
								level_cel_block = *a5a;
								if ( v18 )
									drawLowerScreen(v16 + 32);
							}
							++a6b;
							a5a += 2;
							v16 -= 24576;
						}
						while ( a6b < (dword_5A5594 >> 1) - 1 );
					}
					if ( 2 * a6 + 2 < 8 )
						scrollrt_4545D2(
							(char *)gpBuffer + screen_y_times_768[sy] - ((3 * a6 + 3) << 13) + v8,
							xa,
							a1,
							a6,
							2 * a6 + 2,
							v8,
							sy,
							1);
					v7 = a1;
				}
			}
			++xa;
			v29 += 32;
			v13 = v23 + 112;
			--v7;
			v8 += 64;
			v23 += 112;
			a1 = v7;
		}
		while ( v25 );
	}
	if ( some_flag )
	{
		if ( (unsigned int)v7 < 0x70 && (unsigned int)xa < 0x70 )
		{
			v19 = 112 * xa + v7;
			v20 = dPiece[0][v19];
			light_table_index = dTransVal[0][v19];
			level_piece_id = v20;
			if ( v20 )
			{
				a6c = 0;
				cel_transparency_active = (unsigned char)(nTransTable[v20] & TransList[dung_map[0][v19]]);
				a1b = (char *)gpBuffer + screen_y_times_768[sy] + v8 - 24576;
				if ( (dword_5A5594 >> 1) - 1 > 0 )
				{
					a5b = (unsigned short *)(v29 + 4);
					do
					{
						if ( a6 <= a6c )
						{
							v21 = *a5b;
							level_cel_block = *a5b;
							if ( v21 )
								drawLowerScreen(a1b);
						}
						a1b -= 24576;
						++a6c;
						a5b += 2;
					}
					while ( a6c < (dword_5A5594 >> 1) - 1 );
				}
				v22 = 2 * a6 + 2;
				if ( v22 < 8 )
					scrollrt_4545D2(
						(char *)gpBuffer + screen_y_times_768[sy] - 12288 * v22 + v8,
						xa,
						v7,
						a6,
						2 * a6 + 2,
						v8,
						sy,
						0);
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;
// 69CF14: using guessed type int level_cel_block;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (004545D2) --------------------------------------------------------
void __fastcall scrollrt_4545D2(char *buffer, int x, int y, int a4, int a5, int sx, int sy, int me_flag)
{
	int v8; // eax
	char v9; // bl
	char v10; // cl
	char v11; // dl
	int *v12; // eax
	int v13; // edi
	void **v14; // eax
	int *v15; // esi
	int v16; // ecx
	int v17; // edx
	char v18; // bl
	ItemStruct *v19; // esi
	char *v20; // eax
	signed int v21; // ebx
	int v22; // ebx
	unsigned int v23; // ecx
	PlayerStruct *v24; // esi
	int v25; // esi
	int v26; // eax
	MonsterStruct *v27; // esi
	CMonster *v28; // ecx
	int v29; // ebx
	int v30; // edi
	unsigned int v31; // ecx
	PlayerStruct *v32; // esi
	int v33; // esi
	int v34; // eax
	MonsterStruct *v35; // esi
	CMonster *v36; // ecx
	int v37; // ebx
	int v38; // edi
	ItemStruct *v39; // esi
	char *v40; // eax
	int v41; // ecx
	int v42; // edi
	int v43; // [esp+Ch] [ebp-18h]
	int v44; // [esp+10h] [ebp-14h]
	char *dst_buf; // [esp+14h] [ebp-10h]
	int a1; // [esp+18h] [ebp-Ch]
	char v47; // [esp+1Dh] [ebp-7h]
	char v48; // [esp+1Eh] [ebp-6h]
	char v49; // [esp+1Fh] [ebp-5h]
	char v50; // [esp+20h] [ebp-4h]
	char v51; // [esp+21h] [ebp-3h]
	char v52; // [esp+22h] [ebp-2h]
	char v53; // [esp+23h] [ebp-1h]

	a1 = x;
	dst_buf = buffer;
	v8 = 112 * x + y;
	v9 = dDead[0][v8];
	v53 = dFlags[0][v8];
	v50 = dObject[0][v8];
	v52 = dItem[0][v8];
	v10 = dPlayer[0][v8 - 1];
	v51 = dPlayer[0][v8];
	v49 = dArch[0][v8];
	v11 = dung_map[0][v8];
	v12 = (int *)((char *)dMonster + 4 * v8);
	v47 = v11;
	v48 = v10;
	v43 = *v12;
	v44 = *(v12 - 1);
	if ( visiondebug && v53 & 0x40 )
		Cel2_header_into_buf(dst_buf, (char *)pSquareCel, 1, 64, a5, 8);
	if ( MissilePreFlag && v53 & 1 )
	{
		v13 = sx;
		scrollrt_452B2A(a1, y, sx, sy, a5, 8, 1);
	}
	else
	{
		v13 = sx;
	}
	if ( light_table_index < lightmax )
	{
		if ( v9 )
		{
			v14 = &pCursCels + 12 * (v9 & 0x1F);
			v15 = (int *)v14[(v9 >> 5) & 7];
			v16 = v13 - (_DWORD)v14[10];
			if ( v15 )
			{
				v17 = (int)v14[8];
				if ( v17 >= 1 && (unsigned int)*v15 <= 0x32 && v17 <= *v15 )
				{
					v18 = *((_BYTE *)v14 + 44);
					if ( v18 )
						engine_417DF8(v16, sy, v15, v17, (int)v14[9], a5, 8, v18);
					else
						engine_417F78(v16, sy, v15, v17, (int)v14[9], a5, 8);
				}
			}
		}
		if ( v50 )
			scrollrt_objects(a1, y, v13, sy, 1, a5, 8);
	}
	if ( v52 )
	{
		v19 = &item_stru_6358B8 + v52;
		if ( !v19->_iPostDraw && (unsigned char)v52 <= 0x7Fu )
		{
			v20 = (char *)v19->ItemFrame;
			if ( v20 )
			{
				v21 = v19->_iAnimFrame;
				if ( v21 >= 1 && *(_DWORD *)v20 <= 0x32u && v21 <= *(_DWORD *)v20 )
				{
					v22 = v13 - v19->_iAnimXOff;
					if ( v52 - 1 == pcursitem )
						Cel_header_and_colour_highlight(181, v22, sy, v20, v19->_iAnimFrame, v19->_iAnimWidth, a5, 8);
					Cel2_header_and_light(v22, sy, (char *)v19->ItemFrame, v19->_iAnimFrame, v19->_iAnimWidth, a5, 8);
				}
			}
		}
	}
	if ( v53 & 0x20 )
	{
		v23 = -1 - v48;
		if ( v23 < 4 )
		{
			v24 = &plr[v23];
			scrollrt_draw_player_b(
				v23,
				a1,
				y - 1,
				v13 + v24->_pxoff - v24->_pAnimWidth2,
				sy + v24->_pyoff,
				v24->_pAnimData,
				v24->_pAnimFrame,
				v24->_pAnimWidth,
				a5,
				8);
			if ( me_flag )
			{
				v25 = v24->_peflag;
				if ( v25 )
				{
					if ( v25 == 2 )
						scrollrt_454C09(dst_buf - 12384, a1 - 2, y + 1, a4, a5, v13 - 96, sy - 16);
					scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, v13 - 64, sy);
				}
			}
		}
	}
	if ( v53 & 0x10 && (v53 & 0x40 || plr[myplr]._pInfraFlag) && v44 < 0 )
	{
		v26 = -1 - v44;
		draw_monster_num = -1 - v44;
		if ( (unsigned int)(-1 - v44) < 0xC8 )
		{
			v27 = &monster[v26];
			if ( !(v27->_mFlags & 1) )
			{
				v28 = v27->MType;
				if ( v28 )
				{
					v29 = sy + v27->_myoff;
					v30 = sx + v27->_mxoff - v28->flags_2;
					if ( v26 == *(_DWORD *)&pcursmonst )
					{
						engine_417C99(233, v30, v29, (void *)v27->_mAFNum, v27->_mAnimFrame, v28->flags_1, a5, 8);
						v26 = draw_monster_num;
					}
					scrollrt_monsters(a1, y, v30, v29, v26, a5, 8);
					if ( me_flag && !v27->_meflag )
						scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, sx - 64, sy);
					v13 = sx;
				}
			}
		}
	}
	if ( v53 & 4 )
		scrollrt_452CC0(a1, y, v13, sy, a5, 8, 1);
	if ( v51 > 0 )
	{
		v31 = v51 - 1;
		if ( v31 < 4 )
		{
			v32 = &plr[v31];
			scrollrt_draw_player_b(
				v31,
				a1,
				y,
				v13 + v32->_pxoff - v32->_pAnimWidth2,
				sy + v32->_pyoff,
				v32->_pAnimData,
				v32->_pAnimFrame,
				v32->_pAnimWidth,
				a5,
				8);
			if ( me_flag )
			{
				v33 = v32->_peflag;
				if ( v33 )
				{
					if ( v33 == 2 )
						scrollrt_454C09(dst_buf - 12384, a1 - 2, y + 1, a4, a5, v13 - 96, sy - 16);
					scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, v13 - 64, sy);
				}
			}
		}
	}
	if ( v43 > 0 && (v53 & 0x40 || plr[myplr]._pInfraFlag) )
	{
		v34 = v43 - 1;
		draw_monster_num = v43 - 1;
		if ( (unsigned int)(v43 - 1) < 0xC8 )
		{
			v35 = &monster[v34];
			if ( !(v35->_mFlags & 1) )
			{
				v36 = v35->MType;
				if ( v36 )
				{
					v37 = sy + v35->_myoff;
					v38 = sx + v35->_mxoff - v36->flags_2;
					if ( v34 == *(_DWORD *)&pcursmonst )
					{
						engine_417C99(233, v38, v37, (void *)v35->_mAFNum, v35->_mAnimFrame, v36->flags_1, a5, 8);
						v34 = draw_monster_num;
					}
					scrollrt_monsters(a1, y, v38, v37, v34, a5, 8);
					if ( me_flag && !v35->_meflag )
						scrollrt_454C09(dst_buf - 64, a1 - 1, y + 1, a4, a5, sx - 64, sy);
					v13 = sx;
				}
			}
		}
	}
	if ( v53 & 1 )
		scrollrt_452B2A(a1, y, v13, sy, a5, 8, 0);
	if ( v50 && light_table_index < lightmax )
		scrollrt_objects(a1, y, v13, sy, 0, a5, 8);
	if ( v52 )
	{
		v39 = &item_stru_6358B8 + v52;
		if ( v39->_iPostDraw )
		{
			if ( (unsigned char)v52 <= 0x7Fu )
			{
				v40 = (char *)v39->ItemFrame;
				if ( v40 )
				{
					v41 = v39->_iAnimFrame;
					if ( v41 >= 1 && *(_DWORD *)v40 <= 0x32u && v41 <= *(_DWORD *)v40 )
					{
						v42 = v13 - v39->_iAnimXOff;
						if ( v52 - 1 == pcursitem )
							Cel_header_and_colour_highlight(181, v42, sy, v40, v41, v39->_iAnimWidth, a5, 8);
						Cel2_header_and_light(
							v42,
							sy,
							(char *)v39->ItemFrame,
							v39->_iAnimFrame,
							v39->_iAnimWidth,
							a5,
							8);
					}
				}
			}
		}
	}
	if ( v49 )
	{
		cel_transparency_active = (unsigned char)TransList[v47];
		Cel2_header_light_and_trans_into_buf(dst_buf, (char *)level_special_cel, v49, 64, a5, 8);
	}
}
// 4B8CC0: using guessed type char pcursitem;
// 525720: using guessed type int visiondebug;
// 642A14: using guessed type char lightmax;
// 64CCD4: using guessed type int MissilePreFlag;
// 69BEF8: using guessed type int light_table_index;
// 69CF94: using guessed type int cel_transparency_active;
// 69EFA4: using guessed type int draw_monster_num;

//----- (00454C09) --------------------------------------------------------
int __fastcall scrollrt_454C09(char *buffer, int x, int y, int a4, signed int a5, int sx, int sy)
{
	int v7; // eax
	int v8; // ecx
	int v9; // esi
	int v10; // eax
	int v11; // edi
	int v12; // eax
	unsigned short *v13; // esi
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int v17; // eax
	int v18; // edi
	int v19; // eax
	int result; // eax
	int v21; // [esp+Ch] [ebp-14h]
	int v22; // [esp+10h] [ebp-10h]
	int v23; // [esp+14h] [ebp-Ch]
	char *a1; // [esp+18h] [ebp-8h]
	int xa; // [esp+1Ch] [ebp-4h]

	xa = x;
	v23 = light_table_index;
	v22 = cel_transparency_active;
	v21 = level_piece_id;
	v7 = y + 112 * x;
	a1 = buffer;
	v8 = dPiece[0][v7];
	v9 = dTransVal[0][v7];
	v10 = dung_map[0][v7];
	level_piece_id = v8;
	v11 = (int)&a1[24576 * a4];
	v12 = (unsigned char)(nTransTable[v8] & TransList[v10]);
	light_table_index = v9;
	cel_transparency_active = v12;
	v13 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y));
	if ( !a4 )
	{
		v14 = v13[2];
		level_cel_block = v13[2];
		if ( v14 )
			drawLowerScreen((void *)v11);
		v15 = v13[3];
		level_cel_block = v13[3];
		if ( v15 )
			drawLowerScreen((void *)(v11 + 32));
		goto LABEL_10;
	}
	if ( a4 == 1 )
	{
LABEL_10:
		v11 -= 24576;
		level_cel_block = v13[4];
		if ( level_cel_block )
			drawLowerScreen((void *)v11);
		v16 = v13[5];
		level_cel_block = v13[5];
		if ( v16 )
			drawLowerScreen((void *)(v11 + 32));
		goto LABEL_14;
	}
	if ( a4 != 2 )
	{
		if ( a4 != 3 )
			goto LABEL_22;
		goto LABEL_18;
	}
LABEL_14:
	v11 -= 24576;
	level_cel_block = v13[6];
	if ( level_cel_block )
		drawLowerScreen((void *)v11);
	v17 = v13[7];
	level_cel_block = v13[7];
	if ( v17 )
		drawLowerScreen((void *)(v11 + 32));
LABEL_18:
	v18 = v11 - 24576;
	level_cel_block = v13[8];
	if ( level_cel_block )
		drawLowerScreen((void *)v18);
	v19 = v13[9];
	level_cel_block = v13[9];
	if ( v19 )
		drawLowerScreen((void *)(v18 + 32));
LABEL_22:
	if ( a5 < 8 )
		scrollrt_4545D2(a1, xa, y, a4, a5, sx, sy, 0);
	light_table_index = v23;
	cel_transparency_active = v22;
	result = v21;
	level_piece_id = v21;
	return result;
}
// 69BEF8: using guessed type int light_table_index;
// 69CF14: using guessed type int level_cel_block;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (00454D9D) --------------------------------------------------------
void __fastcall scrollrt_454D9D(int x, int y, int sx, int sy, int a5, int a6, int some_flag)
{
	int v7; // edi
	int v8; // esi
	unsigned short *v9; // ebx
	int v10; // ecx
	int v11; // eax
	char *v12; // edx
	int v13; // edi
	int v14; // eax
	char *v15; // edi
	int v16; // eax
	char *v17; // edi
	int v18; // eax
	int v19; // eax
	int v20; // esi
	int v21; // eax
	int v22; // ecx
	int v23; // ecx
	int v24; // eax
	int v25; // esi
	char *v26; // esi
	int v27; // eax
	int v28; // eax
	int v29; // eax
	bool v30; // zf
	int v31; // ecx
	int v32; // eax
	char *v33; // esi
	int v34; // eax
	char *v35; // esi
	int v36; // eax
	char *v37; // esi
	int v38; // eax
	int v39; // eax
	int v40; // [esp+Ch] [ebp-14h]
	int v41; // [esp+10h] [ebp-10h]
	int a5a; // [esp+14h] [ebp-Ch]
	int ya; // [esp+18h] [ebp-8h]
	signed int xa; // [esp+1Ch] [ebp-4h]
	int i; // [esp+30h] [ebp+10h]

	v7 = y;
	v8 = x;
	ya = y;
	xa = x;
	v9 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y));
	a5a = 2 * a6 + 2;
	if ( a5a > 8 )
		a5a = 8;
	if ( some_flag )
	{
		if ( v7 >= 0 && v7 < 112 && v8 >= 0 && v8 < 112 )
		{
			v10 = 112 * v8 + v7;
			v11 = dPiece[0][v10];
			light_table_index = dTransVal[0][v10];
			level_piece_id = v11;
			if ( v11 )
			{
				cel_transparency_active = (unsigned char)(nTransTable[v11] & TransList[dung_map[0][v10]]);
				v12 = (char *)gpBuffer + screen_y_times_768[sy];
				v13 = (int)&v12[sx + 32];
				if ( a6 >= 0 )
				{
					v14 = v9[1];
					level_cel_block = v9[1];
					if ( v14 )
					{
						arch_draw_type = 2;
						drawUpperScreen(&v12[sx + 32]);
						arch_draw_type = 0;
					}
				}
				v15 = (char *)(v13 - 24576);
				if ( a6 >= 1 )
				{
					v16 = v9[3];
					level_cel_block = v9[3];
					if ( v16 )
						drawUpperScreen(v15);
				}
				v17 = v15 - 24576;
				if ( a6 >= 2 )
				{
					v18 = v9[5];
					level_cel_block = v9[5];
					if ( v18 )
						drawUpperScreen(v17);
				}
				if ( a6 >= 3 )
				{
					v19 = v9[7];
					level_cel_block = v9[7];
					if ( v19 )
						drawUpperScreen(v17 - 24576);
				}
				v7 = ya;
				scrollrt_dead2((char *)gpBuffer + screen_y_times_768[sy] + sx, xa, ya, a6, a5a, sx, sy, 0);
			}
			else
			{
				world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx);
			}
		}
		sx += 64;
		v8 = xa + 1;
		--v7;
		--a5;
		++xa;
		ya = v7;
		v9 += 16;
	}
	if ( a5 > 0 )
	{
		v20 = 112 * v8;
		v41 = v20;
		v40 = a5;
		do
		{
			if ( v7 >= 0 && v7 < 112 && v20 >= 0 && v20 < 12544 )
			{
				v21 = dPiece[0][v20 + v7];
				light_table_index = dTransVal[0][v20 + v7];
				level_piece_id = v21;
				if ( v21 )
				{
					v22 = dung_map[0][v20 + v7];
					arch_draw_type = 1;
					v23 = (unsigned char)(nTransTable[v21] & TransList[v22]);
					v24 = *v9;
					v25 = screen_y_times_768[sy];
					cel_transparency_active = v23;
					level_cel_block = v24;
					v26 = (char *)gpBuffer + v25 + sx;
					if ( v24 )
						drawUpperScreen(v26);
					v27 = v9[1];
					arch_draw_type = 2;
					level_cel_block = v27;
					if ( v27 )
						drawUpperScreen(v26 + 32);
					arch_draw_type = 0;
					for ( i = 1; i < (dword_5A5594 >> 1) - 1; ++i )
					{
						v26 -= 24576;
						if ( a6 >= i )
						{
							v28 = v9[2 * i];
							level_cel_block = v9[2 * i];
							if ( v28 )
								drawUpperScreen(v26);
							v29 = v9[2 * i + 1];
							level_cel_block = v9[2 * i + 1];
							if ( v29 )
								drawUpperScreen(v26 + 32);
						}
					}
					scrollrt_dead2((char *)gpBuffer + screen_y_times_768[sy] + sx, xa, ya, a6, a5a, sx, sy, 1);
					v7 = ya;
					v20 = v41;
				}
				else
				{
					world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx);
				}
			}
			++xa;
			sx += 64;
			v20 += 112;
			--v7;
			v9 += 16;
			v30 = v40-- == 1;
			v41 = v20;
			ya = v7;
		}
		while ( !v30 );
	}
	if ( some_flag && v7 >= 0 && v7 < 112 && xa >= 0 && xa < 112 )
	{
		v31 = 112 * xa + v7;
		v32 = dPiece[0][v31];
		light_table_index = dTransVal[0][v31];
		level_piece_id = v32;
		if ( v32 )
		{
			arch_draw_type = 1;
			cel_transparency_active = (unsigned char)(nTransTable[v32] & TransList[dung_map[0][v31]]);
			v33 = (char *)gpBuffer + screen_y_times_768[sy] + sx;
			if ( a6 >= 0 )
			{
				v34 = *v9;
				level_cel_block = *v9;
				if ( v34 )
					drawUpperScreen(v33);
			}
			arch_draw_type = 0;
			v35 = v33 - 24576;
			if ( a6 >= 1 )
			{
				v36 = v9[2];
				level_cel_block = v9[2];
				if ( v36 )
					drawUpperScreen(v35);
			}
			v37 = v35 - 24576;
			if ( a6 >= 2 )
			{
				v38 = v9[4];
				level_cel_block = v9[4];
				if ( v38 )
					drawUpperScreen(v37);
			}
			if ( a6 >= 3 )
			{
				v39 = v9[6];
				level_cel_block = v9[6];
				if ( v39 )
					drawUpperScreen(v37 - 24576);
			}
			scrollrt_dead2((char *)gpBuffer + screen_y_times_768[sy] + sx, xa, ya, a6, a5a, sx, sy, 0);
		}
		else
		{
			world_levelrelated((char *)gpBuffer + screen_y_times_768[sy] + sx);
		}
	}
}
// 69BEF8: using guessed type int light_table_index;
// 69CF14: using guessed type int level_cel_block;
// 69CF20: using guessed type char arch_draw_type;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (00455217) --------------------------------------------------------
void __fastcall scrollrt_dead2(char *buffer, int x, int y, int a4, int a5, int sx, int sy, int me_flag)
{
	int v8; // eax
	char v9; // bl
	char v10; // cl
	char v11; // dl
	int *v12; // eax
	void **v13; // eax
	int *v14; // esi
	int v15; // ecx
	int v16; // edx
	char v17; // bl
	ItemStruct *v18; // esi
	char *v19; // eax
	signed int v20; // ebx
	int v21; // ebx
	unsigned int v22; // ecx
	PlayerStruct *v23; // esi
	int v24; // esi
	int v25; // eax
	MonsterStruct *v26; // esi
	CMonster *v27; // ecx
	int v28; // ebx
	int v29; // edi
	unsigned int v30; // ecx
	PlayerStruct *v31; // esi
	int v32; // esi
	int v33; // eax
	MonsterStruct *v34; // esi
	CMonster *v35; // ecx
	int v36; // ebx
	int v37; // edi
	ItemStruct *v38; // esi
	char *v39; // ecx
	signed int v40; // ebx
	int v41; // ebx
	int v42; // [esp+Ch] [ebp-18h]
	int v43; // [esp+10h] [ebp-14h]
	char *dst_buf; // [esp+14h] [ebp-10h]
	int xa; // [esp+18h] [ebp-Ch]
	char v46; // [esp+1Dh] [ebp-7h]
	char v47; // [esp+1Eh] [ebp-6h]
	char v48; // [esp+1Fh] [ebp-5h]
	char v49; // [esp+20h] [ebp-4h]
	char v50; // [esp+21h] [ebp-3h]
	char v51; // [esp+22h] [ebp-2h]
	char v52; // [esp+23h] [ebp-1h]

	xa = x;
	dst_buf = buffer;
	v8 = 112 * x + y;
	v9 = dDead[0][v8];
	v52 = dFlags[0][v8];
	v49 = dObject[0][v8];
	v51 = dItem[0][v8];
	v10 = dPlayer[0][v8 - 1];
	v50 = dPlayer[0][v8];
	v48 = dArch[0][v8];
	v11 = dung_map[0][v8];
	v12 = (int *)((char *)dMonster + 4 * v8);
	v46 = v11;
	v47 = v10;
	v42 = *v12;
	v43 = *(v12 - 1);
	if ( visiondebug && v52 & 0x40 )
		Cel_header_into_buf(dst_buf, (char *)pSquareCel, 1, 64, 0, a5);
	if ( MissilePreFlag && v52 & 1 )
		scrollrt_452994(xa, y, sx, sy, 0, a5, 1);
	if ( light_table_index < lightmax )
	{
		if ( v9 )
		{
			v13 = &pCursCels + 12 * (v9 & 0x1F);
			v14 = (int *)v13[(v9 >> 5) & 7];
			v15 = sx - (_DWORD)v13[10];
			if ( v14 )
			{
				v16 = (int)v13[8];
				if ( v16 >= 1 && (unsigned int)*v14 <= 0x32 && v16 <= *v14 )
				{
					v17 = *((_BYTE *)v13 + 44);
					if ( v17 )
						engine_417981(v15, sy, v14, v16, (int)v13[9], 0, a5, v17);
					else
						engine_417AE9(v15, sy, v14, v16, (int)v13[9], 0, a5);
				}
			}
		}
		if ( v49 )
			scrollrt_objects2(xa, y, sx, sy, 1, 0, a5);
	}
	if ( v51 )
	{
		v18 = &item_stru_6358B8 + v51;
		if ( !v18->_iPostDraw && (unsigned char)v51 <= 0x7Fu )
		{
			v19 = (char *)v18->ItemFrame;
			if ( v19 )
			{
				v20 = v18->_iAnimFrame;
				if ( v20 >= 1 && *(_DWORD *)v19 <= 0x32u && v20 <= *(_DWORD *)v19 )
				{
					v21 = sx - v18->_iAnimXOff;
					if ( v51 - 1 == pcursitem )
						Cel_colour(181, v21, sy, v19, v18->_iAnimFrame, v18->_iAnimWidth, 0, a5);
					Cel_header_and_light(v21, sy, (char *)v18->ItemFrame, v18->_iAnimFrame, v18->_iAnimWidth, 0, a5);
				}
			}
		}
	}
	if ( v52 & 0x20 )
	{
		v22 = -1 - v47;
		if ( v22 < 4 )
		{
			v23 = &plr[v22];
			scrollrt_draw_player_a(
				v22,
				xa,
				y - 1,
				sx + v23->_pxoff - v23->_pAnimWidth2,
				sy + v23->_pyoff,
				v23->_pAnimData,
				v23->_pAnimFrame,
				v23->_pAnimWidth,
				0,
				a5);
			if ( me_flag )
			{
				v24 = v23->_peflag;
				if ( v24 )
				{
					if ( v24 == 2 )
						scrollrt_455A7D(dst_buf - 12384, xa - 2, y + 1, a4, a5, sx - 96, sy - 16);
					scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy);
				}
			}
		}
	}
	if ( v52 & 0x10 && (v52 & 0x40 || plr[myplr]._pInfraFlag) && v43 < 0 )
	{
		v25 = -1 - v43;
		draw_monster_num = -1 - v43;
		if ( (unsigned int)(-1 - v43) < 0xC8 )
		{
			v26 = &monster[v25];
			if ( !(v26->_mFlags & 1) )
			{
				v27 = v26->MType;
				if ( v27 )
				{
					v28 = sy + v26->_myoff;
					v29 = sx + v26->_mxoff - v27->flags_2;
					if ( v25 == *(_DWORD *)&pcursmonst )
					{
						engine_417847(233, v29, v28, (void *)v26->_mAFNum, v26->_mAnimFrame, v27->flags_1, 0, a5);
						v25 = draw_monster_num;
					}
					scrollrt_monsters2(xa, y, v29, v28, v25, 0, a5);
					if ( me_flag && !v26->_meflag )
						scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy);
				}
			}
		}
	}
	if ( v52 & 4 )
		scrollrt_452CC0(xa, y, sx, sy, 0, a5, 0);
	if ( v50 > 0 )
	{
		v30 = v50 - 1;
		if ( v30 < 4 )
		{
			v31 = &plr[v30];
			scrollrt_draw_player_a(
				v30,
				xa,
				y,
				sx + v31->_pxoff - v31->_pAnimWidth2,
				sy + v31->_pyoff,
				v31->_pAnimData,
				v31->_pAnimFrame,
				v31->_pAnimWidth,
				0,
				a5);
			if ( me_flag )
			{
				v32 = v31->_peflag;
				if ( v32 )
				{
					if ( v32 == 2 )
						scrollrt_455A7D(dst_buf - 12384, xa - 2, y + 1, a4, a5, sx - 96, sy - 16);
					scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy);
				}
			}
		}
	}
	if ( v42 > 0 && (v52 & 0x40 || plr[myplr]._pInfraFlag) )
	{
		v33 = v42 - 1;
		draw_monster_num = v42 - 1;
		if ( (unsigned int)(v42 - 1) < 0xC8 )
		{
			v34 = &monster[v33];
			if ( !(v34->_mFlags & 1) )
			{
				v35 = v34->MType;
				if ( v35 )
				{
					v36 = sy + v34->_myoff;
					v37 = sx + v34->_mxoff - v35->flags_2;
					if ( v33 == *(_DWORD *)&pcursmonst )
					{
						engine_417847(233, v37, v36, (void *)v34->_mAFNum, v34->_mAnimFrame, v35->flags_1, 0, a5);
						v33 = draw_monster_num;
					}
					scrollrt_monsters2(xa, y, v37, v36, v33, 0, a5);
					if ( me_flag && !v34->_meflag )
						scrollrt_455A7D(dst_buf - 64, xa - 1, y + 1, a4, a5, sx - 64, sy);
				}
			}
		}
	}
	if ( v52 & 1 )
		scrollrt_452994(xa, y, sx, sy, 0, a5, 0);
	if ( v49 && light_table_index < lightmax )
		scrollrt_objects2(xa, y, sx, sy, 0, 0, a5);
	if ( v51 )
	{
		v38 = &item_stru_6358B8 + v51;
		if ( v38->_iPostDraw )
		{
			if ( (unsigned char)v51 <= 0x7Fu )
			{
				v39 = (char *)v38->ItemFrame;
				if ( v39 )
				{
					v40 = v38->_iAnimFrame;
					if ( v40 >= 1 && *(_DWORD *)v39 <= 0x32u && v40 <= *(_DWORD *)v39 )
					{
						v41 = sx - v38->_iAnimXOff;
						if ( v51 - 1 == pcursitem )
							Cel_colour(181, v41, sy, v39, v38->_iAnimFrame, v38->_iAnimWidth, 0, a5);
						Cel_header_and_light(
							v41,
							sy,
							(char *)v38->ItemFrame,
							v38->_iAnimFrame,
							v38->_iAnimWidth,
							0,
							a5);
					}
				}
			}
		}
	}
	if ( v48 )
	{
		cel_transparency_active = (unsigned char)TransList[v46];
		Cel_header_light_and_trans_into_buf(dst_buf, (char *)level_special_cel, v48, 64, 0, a5);
	}
}
// 4B8CC0: using guessed type char pcursitem;
// 525720: using guessed type int visiondebug;
// 642A14: using guessed type char lightmax;
// 64CCD4: using guessed type int MissilePreFlag;
// 69BEF8: using guessed type int light_table_index;
// 69CF94: using guessed type int cel_transparency_active;
// 69EFA4: using guessed type int draw_monster_num;

//----- (00455844) --------------------------------------------------------
void __fastcall scrollrt_monsters2(int x, int y, int a3, int a4, int mon_id, int a6, int a7)
{
	int v7; // eax
	signed int *v8; // esi
	signed int v9; // ebx
	char v10; // cl
	CMonster *v11; // eax
	char mon_ida; // [esp+1Ch] [ebp+10h]

	if ( (unsigned int)mon_id < 0xC8 )
	{
		v7 = mon_id;
		v8 = (signed int *)monster[mon_id]._mAFNum;
		if ( v8 )
		{
			v9 = monster[v7]._mAnimFrame;
			if ( v9 >= 1 && (unsigned int)*v8 <= 0x32 && v9 <= *v8 )
			{
				if ( dFlags[x][y] & 0x40 )
				{
					v10 = 0;
					mon_ida = 0;
					if ( monster[v7]._uniqtype )
					{
						v10 = monster[v7]._uniqtrans + 4;
						mon_ida = monster[v7]._uniqtrans + 4;
					}
					if ( monster[v7]._mmode == MM_STONE )
					{
						v10 = 2;
						mon_ida = 2;
					}
					if ( plr[myplr]._pInfraFlag && light_table_index > 8 )
					{
						v10 = 1;
						mon_ida = 1;
					}
					v11 = monster[v7].MType;
					if ( v10 )
						engine_417981(a3, a4, v8, v9, v11->flags_1, a6, a7, mon_ida);
					else
						engine_417AE9(a3, a4, v8, v9, v11->flags_1, a6, a7);
				}
				else
				{
					engine_417981(a3, a4, v8, v9, monster[v7].MType->flags_1, a6, a7, 1);
				}
			}
		}
	}
}
// 69BEF8: using guessed type int light_table_index;

//----- (00455937) --------------------------------------------------------
void __fastcall scrollrt_objects2(int x, int y, int a3, int a4, int pre_flag, int a6, int dir)
{
	int v7; // edi
	char v8; // al
	unsigned char v9; // dl
	int v10; // esi
	int v11; // ebx
	int v12; // edi
	int v13; // eax
	int v14; // ecx
	char *v15; // eax
	signed int v16; // ecx
	char *v17; // eax
	char v18; // [esp+Fh] [ebp-1h]

	v7 = y;
	v8 = dObject[x][y];
	if ( v8 <= 0 )
	{
		v9 = -1 - v8;
		v10 = (char)(-1 - v8);
		v18 = -1 - v8;
		if ( object[v10]._oPreFlag != pre_flag )
			return;
		dir = 8;
		v13 = object[v10]._ox - x;
		v14 = object[v10]._oy - v7;
		v12 = a3 + 32 * v13 - object[v10]._oAnimWidth2 - 32 * v14;
		v11 = a4 + 16 * (v14 + v13);
		a6 = 0;
	}
	else
	{
		v9 = v8 - 1;
		v10 = (char)(v8 - 1);
		v18 = v8 - 1;
		if ( object[v10]._oPreFlag != pre_flag )
			return;
		v11 = a4;
		v12 = a3 - object[v10]._oAnimWidth2;
	}
	if ( v9 < 0x7Fu )
	{
		v15 = (char *)object[v10]._oAnimCel;
		if ( v15 )
		{
			v16 = object[v10]._oAnimFrame;
			if ( v16 >= 1 && *(_DWORD *)v15 <= 0x32u && v16 <= *(_DWORD *)v15 )
			{
				if ( v18 == pcursobj )
					Cel_colour(194, v12, v11, v15, v16, object[v10]._oAnimWidth, a6, dir);
				if ( object[v10]._oLight )
				{
					Cel_header_and_light(
						v12,
						v11,
						(char *)object[v10]._oAnimCel,
						object[v10]._oAnimFrame,
						object[v10]._oAnimWidth,
						a6,
						dir);
				}
				else
				{
					v17 = (char *)object[v10]._oAnimCel;
					if ( v17 )
						Cel_header(v12, v11, v17, object[v10]._oAnimFrame, object[v10]._oAnimWidth, a6, dir);
				}
			}
		}
	}
}
// 4B8CC1: using guessed type char pcursobj;

//----- (00455A7D) --------------------------------------------------------
void __fastcall scrollrt_455A7D(char *buffer, int x, int y, int a4, int a5, int sx, int sy)
{
	int v7; // eax
	char *v8; // esi
	int v9; // ecx
	int v10; // ebx
	int v11; // edx
	int v12; // eax
	int v13; // eax
	int v14; // ecx
	int v15; // edi
	int v16; // eax
	unsigned short *v17; // esi
	int v18; // eax
	int v19; // eax
	int v20; // eax
	int v21; // eax
	int v22; // [esp+Ch] [ebp-14h]
	int xa; // [esp+10h] [ebp-10h]
	int *a1; // [esp+14h] [ebp-Ch]
	char *v25; // [esp+18h] [ebp-8h]
	int i; // [esp+1Ch] [ebp-4h]

	xa = x;
	v22 = level_piece_id;
	v7 = 112 * x + y;
	v8 = buffer;
	v9 = dPiece[0][v7];
	v10 = cel_transparency_active;
	v11 = dTransVal[0][v7];
	v12 = dung_map[0][v7];
	level_piece_id = v9;
	v13 = (unsigned char)TransList[v12];
	v14 = (unsigned char)nTransTable[v9];
	v15 = light_table_index;
	light_table_index = v11;
	a1 = (int *)v8;
	v25 = v8;
	cel_transparency_active = v14 & v13;
	v16 = gendung_41927A(xa, y);
	arch_draw_type = 1;
	v17 = (unsigned short *)((char *)dpiece_defs_map_1 + 32 * v16);
	v18 = *v17;
	level_cel_block = *v17;
	if ( v18 )
		drawUpperScreen(a1);
	v19 = v17[1];
	arch_draw_type = 2;
	level_cel_block = v19;
	if ( v19 )
		drawUpperScreen(a1 + 8);
	arch_draw_type = 0;
	for ( i = 1; i < (dword_5A5594 >> 1) - 1; ++i )
	{
		v25 -= 24576;
		if ( a4 >= i )
		{
			v20 = v17[2 * i];
			level_cel_block = v17[2 * i];
			if ( v20 )
				drawUpperScreen(v25);
			v21 = v17[2 * i + 1];
			level_cel_block = v17[2 * i + 1];
			if ( v21 )
				drawUpperScreen(v25 + 32);
		}
	}
	scrollrt_dead2((char *)a1, xa, y, a4, a5, sx, sy, 0);
	light_table_index = v15;
	cel_transparency_active = v10;
	level_piece_id = v22;
}
// 69BEF8: using guessed type int light_table_index;
// 69CF14: using guessed type int level_cel_block;
// 69CF20: using guessed type char arch_draw_type;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (00455BD4) --------------------------------------------------------
void __fastcall DrawZoom(int x, int y)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // esi
	int v6; // edi
	int v7; // esi
	int v8; // edi
	int v9; // esi
	int v10; // edi
	_WORD *v11; // edi
	char *v12; // esi
	char *v13; // ebx
	signed int v14; // edx
	signed int v15; // ecx
	short v16; // ax
	int v17; // eax
	signed int v18; // [esp+Ch] [ebp-10h]
	signed int v19; // [esp+Ch] [ebp-10h]
	signed int a5; // [esp+10h] [ebp-Ch]
	int a5a; // [esp+10h] [ebp-Ch]
	signed int a6; // [esp+14h] [ebp-8h]
	signed int a6a; // [esp+14h] [ebp-8h]
	int a6b; // [esp+14h] [ebp-8h]
	int ya; // [esp+18h] [ebp-4h]

	v2 = ScrollInfo._sxoff + 64;
	dword_5C2FF8 = 6;
	dword_5C2FFC = 6;
	v3 = x - 6;
	ya = y - 1;
	a5 = 6;
	v4 = ScrollInfo._syoff + 143;
	scr_pix_width = 384;
	scr_pix_height = 192;
	v18 = 3;
	switch ( ScrollInfo._sdir )
	{
		case DIR_SW:
			goto LABEL_3;
		case DIR_W:
			a5 = 7;
LABEL_3:
			v4 = ScrollInfo._syoff + 111;
			v3 = x - 7;
			ya = y - 2;
			goto LABEL_9;
		case DIR_NW:
			goto LABEL_7;
		case DIR_N:
			v18 = 4;
			goto LABEL_7;
		case DIR_NE:
			goto LABEL_9;
		case DIR_E:
			v18 = 4;
			goto LABEL_6;
		case DIR_SE:
LABEL_6:
			v2 = ScrollInfo._sxoff;
			v3 = x - 7;
			ya = y;
LABEL_7:
			a5 = 7;
			break;
		case DIR_OMNI:
			v2 = ScrollInfo._sxoff;
			v4 = ScrollInfo._syoff + 111;
			a5 = 7;
			v3 = x - 8;
LABEL_9:
			v18 = 4;
			break;
		default:
			break;
	}
	a6 = 0;
	screen_buf_end = (int)gpBuffer + screen_y_times_768[143];
	do
	{
		scrollrt_454D9D(v3, ya++, v2, v4, a5, a6, 0);
		v5 = v4 + 16;
		v6 = v2 - 32;
		scrollrt_454D9D(v3++, ya, v6, v5, a5, a6, 1);
		v2 = v6 + 32;
		v4 = v5 + 16;
		++a6;
	}
	while ( a6 < 4 );
	screen_buf_end = (int)gpBuffer + screen_y_times_768[320];
	if ( v18 > 0 )
	{
		do
		{
			scrollrt_levels(v3, ya++, v2, v4, a5, 0);
			v7 = v4 + 16;
			v8 = v2 - 32;
			scrollrt_levels(v3++, ya, v8, v7, a5, 1);
			v2 = v8 + 32;
			v4 = v7 + 16;
			--v18;
		}
		while ( v18 );
	}
	arch_draw_type = 0;
	a6a = 0;
	do
	{
		scrollrt_454229(v3, ya++, v2, v4, a5, a6a, 0);
		v9 = v4 + 16;
		v10 = v2 - 32;
		scrollrt_454229(v3++, ya, v10, v9, a5, a6a, 1);
		v2 = v10 + 32;
		v4 = v9 + 16;
		++a6a;
	}
	while ( a6a < 4 );
	if ( chrflag || questlog )
	{
		a6b = 392064;
		goto LABEL_23;
	}
	if ( invflag || sbookflag )
	{
		a6b = 391744;
LABEL_23:
		a5a = 245168;
		v19 = 160;
		goto LABEL_24;
	}
	a5a = 245088;
	a6b = 391744;
	v19 = 320;
LABEL_24:
	v11 = (_WORD *)((char *)gpBuffer + a6b);
	v12 = (char *)gpBuffer + a5a;
	v13 = &gpBuffer->row_unused_1[1].col_unused_1[a6b];
	v14 = 176;
	do
	{
		v15 = v19;
		do
		{
			_LOBYTE(v16) = *v12++;
			_HIBYTE(v16) = v16;
			*v11 = v16;
			*(_WORD *)v13 = v16;
			++v11;
			v13 += 2;
			--v15;
		}
		while ( v15 );
		v12 += -v19 - 768;
		v17 = 2 * (v19 + 768);
		v13 -= v17;
		v11 = (_WORD *)((char *)v11 - v17);
		--v14;
	}
	while ( v14 );
}
// 4B8968: using guessed type int sbookflag;
// 5C2FF8: using guessed type int dword_5C2FF8;
// 5C2FFC: using guessed type int dword_5C2FFC;
// 5C3000: using guessed type int scr_pix_width;
// 5C3004: using guessed type int scr_pix_height;
// 69BD04: using guessed type int questlog;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF20: using guessed type char arch_draw_type;

//----- (00455E32) --------------------------------------------------------
void __cdecl ClearScreenBuffer()
{
	char *v0; // edi
	signed int v1; // edx

	dx_lock_mutex();
	v0 = gpBuffer->row[0].pixels;
	v1 = 480;
	do
	{
		memset(v0, 0, 0x280u);
		v0 += 768;
		--v1;
	}
	while ( v1 );
	dx_unlock_mutex();
}

//----- (00455E65) --------------------------------------------------------
void __fastcall scrollrt_455E65(int some_flag)
{
	int v1; // ebx
	int v2; // edi

	v1 = some_flag;
	if ( force_redraw == 255 )
	{
		force_redraw = 0;
		v2 = 480;
	}
	else
	{
		v2 = 0;
	}
	if ( some_flag )
	{
		dx_lock_mutex();
		scrollrt_455F56();
		dx_unlock_mutex();
	}
	scrollrt_main_stuff(v2, 0, 0, 0, 0, 0);
	if ( v1 )
	{
		dx_lock_mutex();
		scrollrt_455EC7();
		dx_unlock_mutex();
	}
}
// 52571C: using guessed type int force_redraw;

//----- (00455EC7) --------------------------------------------------------
void __cdecl scrollrt_455EC7()
{
	int v0; // edx
	int v1; // eax
	char *v2; // edi
	char *v3; // esi
	int v4; // ecx
	int v5; // ebx

	v0 = sgdwCursWdt;
	if ( sgdwCursWdt )
	{
		v1 = sgdwCursY;
		v2 = cursor_draw_back_buffer;
		v3 = &gpBuffer->row[sgdwCursY].pixels[sgdwCursX];
		v4 = sgdwCursHgt;
		if ( sgdwCursHgt )
		{
			v5 = sgdwCursHgt;
			do
			{
				memcpy(v3, v2, v0);
				v0 = sgdwCursWdt;
				v2 += sgdwCursWdt;
				v3 += 768;
				--v5;
			}
			while ( v5 );
			v1 = sgdwCursY;
			v4 = sgdwCursHgt;
		}
		sgdwCursWdt = 0;
		sgdwCursXOld = sgdwCursX;
		sgdwCursYOld = v1;
		sgdwCursWdtOld = v0;
		sgdwCursHgtOld = v4;
	}
}

//----- (00455F56) --------------------------------------------------------
void __cdecl scrollrt_455F56()
{
	int v0; // ebp
	int v1; // edx
	int v2; // edi
	int v3; // esi
	unsigned int v4; // eax
	unsigned int v5; // eax
	int v6; // eax
	char *v7; // ebx
	int v8; // ebp
	int v9; // edi
	int v10; // esi
	signed int v11; // ebx
	int v12; // edi
	int v13; // edx
	char *v14; // [esp+10h] [ebp-4h]

	if ( pcurs > 0 )
	{
		v0 = cursW;
		if ( cursW )
		{
			v1 = cursH;
			if ( cursH )
			{
				v2 = MouseX - 1;
				if ( MouseX - 1 >= 0 )
				{
					if ( v2 > 639 )
						return;
				}
				else
				{
					v2 = 0;
				}
				v3 = MouseY - 1;
				if ( MouseY - 1 >= 0 )
				{
					if ( v3 > 479 )
						return;
				}
				else
				{
					v3 = 0;
				}
				v4 = v2 + cursW + 1;
				if ( v4 > 0x27F )
					v4 = 639;
				_LOBYTE(v4) = v4 | 3;
				sgdwCursY = v3;
				sgdwCursX = v2 & 0xFFFFFFFC;
				sgdwCursWdt = v4 - (v2 & 0xFFFFFFFC) + 1;
				v5 = cursH + v3 + 1;
				if ( v5 > 0x1DF )
					v5 = 479;
				v14 = cursor_draw_back_buffer;
				v6 = 1 - v3 + v5;
				sgdwCursHgt = v6;
				v7 = &gpBuffer->row[v3].pixels[v2 & 0xFFFFFFFC];
				if ( v6 )
				{
					v8 = v6;
					do
					{
						memcpy(v14, v7, sgdwCursWdt);
						v14 += sgdwCursWdt;
						v7 += 768;
						--v8;
					}
					while ( v8 );
					v0 = cursW;
					v1 = cursH;
				}
				v9 = v2 + 1;
				v10 = v3 + 1;
				screen_buf_end = (int)gpBuffer + screen_y_times_768[640] - v0 - 2;
				if ( pcurs < 12 )
				{
					Cel2_header(v9 + 64, v1 + v10 + 159, (char *)pCursCels, pcurs, v0, 0, 8);
				}
				else
				{
					v11 = 197;
					if ( plr[myplr].HoldItem._iMagical )
						v11 = 181;
					if ( !plr[myplr].HoldItem._iStatFlag )
						v11 = 229;
					v12 = v9 + 64;
					Cel_header_and_colour_highlight(v11, v12, v1 + v10 + 159, (char *)pCursCels, pcurs, v0, 0, 8);
					v13 = cursH + v10 + 159;
					if ( v11 == 229 )
						Cel2_header_and_light_not_equipable(v12, v13, (char *)pCursCels, pcurs, cursW, 0, 8, 1);
					else
						Cel2_header(v12, v13, (char *)pCursCels, pcurs, cursW, 0, 8);
				}
			}
		}
	}
}
// 4B8C9C: using guessed type int cursH;
// 69CF0C: using guessed type int screen_buf_end;

//----- (00456124) --------------------------------------------------------
void __fastcall scrollrt_main_stuff(int dwHgt, int some_flag, int draw_hp, int draw_mana, int draw_sbar, int draw_btn)
{
	signed int v6; // ebp
	DWORD v7; // ebx
	int v8; // esi
	int v9; // eax
	signed int a4; // [esp+1Ch] [ebp-8h]
	int v11; // [esp+20h] [ebp-4h]

	v11 = some_flag;
	a4 = dwHgt;
	if ( window_activated && lpDDSPrimary )
	{
		if ( IDirectDrawSurface_IsLost(lpDDSPrimary) == 0x887601C2 )
		{
			if ( IDirectDrawSurface_Restore(lpDDSPrimary) )
				return;
			ResetPal();
			a4 = 480;
		}
		if ( !lpDDSBackBuf )
		{
			v6 = 1;
LABEL_8:
			v7 = GetTickCount();
			while ( 1 )
			{
				DDS_desc.dwSize = 108;
				v8 = IDirectDrawSurface_Lock(lpDDSPrimary, 0, &DDS_desc, 33, 0);
				if ( !v8 )
					break;
				if ( v7 - GetTickCount() > 5000 )
					goto LABEL_17;
				Sleep(1u);
				if ( v8 == 0x887601C2 )
					return;
				if ( v8 != 0x8876021C && v8 != 0x887601AE )
				{
					if ( v6 && v8 == 0x80004005 )
					{
						v6 = 0;
						dx_reinit();
						a4 = 480;
						goto LABEL_8;
					}
LABEL_17:
					if ( v8 != 0x887601C2 && v8 != 0x8876021C && v8 != 0x887601AE )
					{
						DDErrDlg(v8, 3707, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP");
						break;
					}
					return;
				}
			}
		}
		if ( a4 > 0 )
			scrollrt_draw_item(0, 0, 640, a4);
		if ( a4 < 480 )
		{
			if ( draw_sbar )
				scrollrt_draw_item(204, 357, 232, 28);
			if ( v11 )
				scrollrt_draw_item(176, 398, 288, 60);
			if ( draw_mana )
			{
				scrollrt_draw_item(460, 352, 88, 72);
				scrollrt_draw_item(564, 416, 56, 56);
			}
			if ( draw_hp )
				scrollrt_draw_item(96, 352, 88, 72);
			if ( draw_btn )
			{
				scrollrt_draw_item(8, 357, 72, 119);
				scrollrt_draw_item(556, 357, 72, 48);
				if ( (unsigned char)gbMaxPlayers > 1u )
				{
					scrollrt_draw_item(84, 443, 36, 32);
					scrollrt_draw_item(524, 443, 36, 32);
				}
			}
			if ( sgdwCursWdtOld )
				scrollrt_draw_item(sgdwCursXOld, sgdwCursYOld, sgdwCursWdtOld, sgdwCursHgtOld);
			if ( sgdwCursWdt )
				scrollrt_draw_item(sgdwCursX, sgdwCursY, sgdwCursWdt, sgdwCursHgt);
		}
		if ( !lpDDSBackBuf )
		{
			v9 = IDirectDrawSurface_Unlock(lpDDSPrimary, 0);
			if ( v9 != 0x887601C2 )
			{
				if ( v9 )
					DDErrDlg(v9, 3779, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP");
			}
		}
	}
}
// 634980: using guessed type int window_activated;
// 679660: using guessed type char gbMaxPlayers;

//----- (004563B3) --------------------------------------------------------
void __fastcall scrollrt_draw_item(int dwX, int dwY, int dwWdt, int dwHgt)
{
	int v4; // esi
	int v5; // edi
	int v6; // ecx
	char *v7; // esi
	char *v8; // edi
	int v9; // edx
	int v10; // [esp+Ch] [ebp-20h]
	int v11; // [esp+10h] [ebp-1Ch]
	int v12; // [esp+14h] [ebp-18h]
	int v13; // [esp+18h] [ebp-14h]
	int v14; // [esp+1Ch] [ebp-10h]
	LONG v15; // [esp+20h] [ebp-Ch]
	int v16; // [esp+24h] [ebp-8h]
	LONG v17; // [esp+28h] [ebp-4h]
	HRESULT error_code; // [esp+34h] [ebp+8h]
	int error_codea; // [esp+34h] [ebp+8h]
	int a4; // [esp+38h] [ebp+Ch]

	v4 = dwY;
	v5 = dwX;
	if ( lpDDSBackBuf )
	{
		v10 = dwX + 64;
		v12 = dwX + 64 + dwWdt - 1;
		v11 = dwY + 160;
		v13 = dwY + 160 + dwHgt - 1;
		a4 = GetTickCount();
		while ( 1 )
		{
			error_code = IDirectDrawSurface_BltFast(lpDDSPrimary, v5, v4, lpDDSBackBuf, (LPRECT)&v10, 16);
			if ( !error_code )
				break;
			if ( a4 - GetTickCount() <= 0x1388 )
			{
				Sleep(1u);
				if ( error_code == 0x887601C2 )
					return;
				if ( error_code == 0x8876021C || error_code == 0x887601AE )
					continue;
			}
			if ( error_code != 0x887601C2 && error_code != 0x8876021C && error_code != 0x887601AE )
				DDErrDlg(error_code, 3596, "C:\\Src\\Diablo\\Source\\SCROLLRT.CPP");
			return;
		}
	}
	else
	{
		v14 = 768 * dwY + dwX + 0x1E040;
		v17 = DDS_desc.lPitch - dwWdt;
		v15 = dwX + dwY * DDS_desc.lPitch;
		v6 = 768 - dwWdt;
		error_codea = (unsigned int)dwWdt >> 2;
		v16 = v6;
		dx_lock_mutex();
		v7 = (char *)gpBuffer + v14;
		v8 = (char *)DDS_desc.lpSurface + v15;
		v9 = dwHgt;
		do
		{
			qmemcpy(v8, v7, 4 * error_codea);
			v7 += 4 * error_codea + v16;
			v8 += 4 * error_codea + v17;
			--v9;
		}
		while ( v9 );
		dx_unlock_mutex();
	}
}

//----- (004564F9) --------------------------------------------------------
void __cdecl DrawAndBlit()
{
	int v0; // ebp
	signed int v1; // esi
	int v2; // edi

	if ( gbRunGame )
	{
		if ( force_redraw == 255 )
		{
			drawhpflag = 1;
			drawmanaflag = 1;
			drawbtnflag = 1;
			drawsbarflag = 1;
			v0 = 0;
			v1 = 1;
			v2 = 480;
		}
		else
		{
			if ( force_redraw != 1 )
				return;
			v0 = 1;
			v1 = 0;
			v2 = 352;
		}
		force_redraw = 0;
		dx_lock_mutex();
		if ( leveltype )
			DrawView(ViewX, ViewY);
		else
			T_DrawView(ViewX, ViewY);
		if ( v1 )
			ClearCtrlPan();
		if ( drawhpflag )
			UpdateLifeFlask();
		if ( drawmanaflag )
			UpdateManaFlask();
		if ( drawbtnflag )
			DrawCtrlPan();
		if ( drawsbarflag )
			DrawInvBelt();
		if ( talkflag )
		{
			DrawTalkPan();
			v2 = 480;
		}
		scrollrt_455F56();
		dx_unlock_mutex();
		scrollrt_main_stuff(v2, v0, drawhpflag, drawmanaflag, drawsbarflag, drawbtnflag);
		dx_lock_mutex();
		scrollrt_455EC7();
		dx_unlock_mutex();
		drawhpflag = 0;
		drawmanaflag = 0;
		drawbtnflag = 0;
		drawsbarflag = 0;
	}
}
// 4B8960: using guessed type int talkflag;
// 525650: using guessed type int gbRunGame;
// 52571C: using guessed type int force_redraw;
// 5BB1ED: using guessed type char leveltype;

//----- (00456625) --------------------------------------------------------
int __fastcall ObjIndex(int x, int y)
{
	int v2; // edi
	int result; // eax
	int v4; // esi

	v2 = 0;
	if ( nobjects <= 0 )
	{
LABEL_5:
		TermMsg("ObjIndex: Active object not found at (%d,%d)", x, y);
		result = -1;
	}
	else
	{
		while ( 1 )
		{
			result = objectactive[v2];
			v4 = objectactive[v2];
			if ( object[v4]._ox == x && object[v4]._oy == y )
				break;
			if ( ++v2 >= nobjects )
				goto LABEL_5;
		}
	}
	return result;
}

//----- (0045666B) --------------------------------------------------------
void __cdecl AddSKingObjs()
{
	int v0; // eax
	int v1; // eax
	int v2; // eax
	int v3; // eax
	int v4; // eax
	int v5; // eax

	v0 = ObjIndex(64, 34);
	SetObjMapRange(v0, 20, 7, 23, 10, 1);
	v1 = ObjIndex(64, 59);
	SetObjMapRange(v1, 20, 14, 21, 16, 2);
	v2 = ObjIndex(27, 37);
	SetObjMapRange(v2, 8, 1, 15, 11, 3);
	v3 = ObjIndex(46, 35);
	SetObjMapRange(v3, 8, 1, 15, 11, 3);
	v4 = ObjIndex(49, 53);
	SetObjMapRange(v4, 8, 1, 15, 11, 3);
	v5 = ObjIndex(27, 53);
	SetObjMapRange(v5, 8, 1, 15, 11, 3);
}

//----- (0045671A) --------------------------------------------------------
void __cdecl AddSChamObjs()
{
	int v0; // eax
	int v1; // eax

	v0 = ObjIndex(37, 30);
	SetObjMapRange(v0, 17, 0, 21, 5, 1);
	v1 = ObjIndex(37, 46);
	SetObjMapRange(v1, 13, 0, 16, 5, 2);
}

//----- (00456755) --------------------------------------------------------
void __cdecl AddVileObjs()
{
	int v0; // eax
	int v1; // eax
	int v2; // eax

	v0 = ObjIndex(26, 45);
	SetObjMapRange(v0, 1, 1, 9, 10, 1);
	v1 = ObjIndex(45, 46);
	SetObjMapRange(v1, 11, 1, 20, 10, 2);
	v2 = ObjIndex(35, 36);
	SetObjMapRange(v2, 7, 11, 13, 18, 3);
}

//----- (004567AD) --------------------------------------------------------
void __fastcall DRLG_SetMapTrans(char *dun_path)
{
	unsigned char *v1; // ecx
	int v2; // ebx
	int v3; // edi
	int v4; // eax
	int v5; // edi
	int v6; // eax
	int v7; // ebx
	char *v8; // esi
	char *v9; // eax
	int v10; // [esp+Ch] [ebp-8h]
	int v11; // [esp+10h] [ebp-4h]

	v1 = LoadFileInMem(dun_path, 0);
	v11 = 0;
	v2 = *v1;
	v3 = v1[2];
	v4 = v3;
	v5 = 2 * v3;
	v6 = v2 * v4;
	v7 = 2 * v2;
	v8 = (char *)&v1[6 * v7 * v5 + 4 + 2 * v6];
	if ( v5 > 0 )
	{
		do
		{
			if ( v7 > 0 )
			{
				v10 = v7;
				v9 = &dung_map[16][v11 + 16];
				do
				{
					*v9 = *v8;
					v8 += 2;
					v9 += 112;
					--v10;
				}
				while ( v10 );
			}
			++v11;
		}
		while ( v11 < v5 );
	}
	mem_free_dbg(v1);
}

//----- (00456819) --------------------------------------------------------
void __cdecl LoadSetMap()
{
	switch ( setlvlnum )
	{
		case SL_SKELKING:
			if ( quests[12]._qactive == 1 )
			{
				quests[12]._qactive = 2;
				quests[12]._qvar1 = 1;
			}
			LoadPreL1Dungeon("Levels\\L1Data\\SklKng1.DUN", 83, 45);
			LoadL1Dungeon("Levels\\L1Data\\SklKng2.DUN", 83, 45);
			LoadPalette("Levels\\L1Data\\L1_2.pal");
			DRLG_AreaTrans(2, (unsigned char *)QSRects);
			DRLG_ListTrans(2, (unsigned char *)&QSRects[2]);
			DRLG_AreaTrans(5, (unsigned char *)&QSRects[4]);
			DRLG_ListTrans(7, (unsigned char *)&QSRects[9]);
			AddL1Objs(0, 0, 112, 112);
			AddSKingObjs();
			InitSKingTriggers();
			break;
		case SL_BONECHAMB:
			LoadPreL2Dungeon("Levels\\L2Data\\Bonecha2.DUN", 69, 39);
			LoadL2Dungeon("Levels\\L2Data\\Bonecha1.DUN", 69, 39);
			LoadPalette("Levels\\L2Data\\L2_2.pal");
			DRLG_ListTrans(5, (unsigned char *)&QSRects[16]);
			DRLG_AreaTrans(2, (unsigned char *)&QSRects[21]);
			DRLG_ListTrans(9, (unsigned char *)&QSRects[23]);
			AddL2Objs(0, 0, 112, 112);
			AddSChamObjs();
			InitSChambTriggers();
			break;
		case SL_MAZE:
			LoadPreL1Dungeon("Levels\\L1Data\\Lv1MazeA.DUN", 20, 50);
			LoadL1Dungeon("Levels\\L1Data\\Lv1MazeB.DUN", 20, 50);
			LoadPalette("Levels\\L1Data\\L1_5.pal");
			AddL1Objs(0, 0, 112, 112);
			DRLG_SetMapTrans("Levels\\L1Data\\Lv1MazeA.DUN");
			break;
		case SL_POISONWATER:
			if ( quests[13]._qactive == 1 )
				quests[13]._qactive = 2;
			LoadPreL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 19, 50);
			LoadL3Dungeon("Levels\\L3Data\\Foulwatr.DUN", 20, 50);
			LoadPalette("Levels\\L3Data\\L3pfoul.pal");
			InitPWaterTriggers();
			break;
		case SL_VILEBETRAYER:
			if ( quests[15]._qactive == 3 )
			{
				quests[15]._qvar2 = 4;
			}
			else if ( quests[15]._qactive == 2 )
			{
				quests[15]._qvar2 = 3;
			}
			LoadPreL1Dungeon("Levels\\L1Data\\Vile1.DUN", 35, 36);
			LoadL1Dungeon("Levels\\L1Data\\Vile2.DUN", 35, 36);
			LoadPalette("Levels\\L1Data\\L1_2.pal");
			AddL1Objs(0, 0, 112, 112);
			AddVileObjs();
			DRLG_SetMapTrans("Levels\\L1Data\\Vile1.DUN");
			InitNoTriggers();
			break;
	}
}
// 5CCB10: using guessed type char setlvlnum;

//----- (00456A16) --------------------------------------------------------
void __cdecl sha1_reset()
{
	memset(sha1_contexts, 0, 0x114u);
}

//----- (00456A2B) --------------------------------------------------------
void __fastcall sha1_final(int ctx_id, char (*dst)[20])
{
	char (*v2)[20]; // eax
	SHA1Context *v3; // ecx
	signed int v4; // edx
	int v5; // esi

	v2 = dst;
	if ( dst )
	{
		v3 = &sha1_contexts[ctx_id];
		v4 = 5;
		do
		{
			v5 = v3->state[0];
			v3 = (SHA1Context *)((char *)v3 + 4);
			*(_DWORD *)v2 = v5;
			v2 = (char (*)[20])((char *)v2 + 4);
			--v4;
		}
		while ( v4 );
	}
}

//----- (00456A4D) --------------------------------------------------------
void __fastcall sha1(int ctx_id, const char *data, char (*dst)[20])
{
	int v3; // esi

	v3 = ctx_id;
	sha1_update(&sha1_contexts[ctx_id], data, 64);
	if ( dst )
		sha1_final(v3, dst);
}

//----- (00456A73) --------------------------------------------------------
void __fastcall sha1_update(SHA1Context *ctx, const char *data, int len)
{
	SHA1Context *v3; // esi
	const char *v4; // ebx
	int v5; // ecx
	int v6; // edx
	unsigned int v7; // ebp

	v3 = ctx;
	v4 = data;
	v5 = ctx->count[0];
	v6 = v5 + 8 * len;
	if ( v6 < v5 )
		++v3->count[1];
	v3->count[0] = v6;
	v3->count[1] += len >> 29;
	if ( len >= 64 )
	{
		v7 = (unsigned int)len >> 6;
		do
		{
			memcpy(v3->buffer, v4, 0x40u);
			sha1_transform(v3);
			v4 += 64;
			--v7;
		}
		while ( v7 );
	}
}

//----- (00456AC4) --------------------------------------------------------
void __fastcall sha1_transform(SHA1Context *ctx)
{
	SHA1Context *v1; // eax
	char *v2; // ecx
	signed int v3; // edx
	int v4; // esi
	int v5; // ecx
	int v6; // edx
	int v7; // edi
	int v8; // ecx
	int v9; // edx
	int v10; // esi
	int v11; // ebx
	int v12; // esi
	int v13; // ecx
	int v14; // esi
	int v15; // ecx
	char v16[320]; // [esp+Ch] [ebp-150h]
	int v17; // [esp+14Ch] [ebp-10h]
	int v18; // [esp+150h] [ebp-Ch]
	int v19; // [esp+154h] [ebp-8h]
	int v20; // [esp+158h] [ebp-4h]

	v1 = ctx;
	qmemcpy(v16, ctx->buffer, 0x40u);
	v2 = &v16[8];
	v3 = 64;
	do
	{
		v4 = *(_DWORD *)v2 ^ *((_DWORD *)v2 - 2) ^ *((_DWORD *)v2 + 6) ^ *((_DWORD *)v2 + 11);
		v2 += 4;
		--v3;
		*((_DWORD *)v2 + 13) = v4;
	}
	while ( v3 );
	v5 = v1->state[0];
	v6 = v1->state[3];
	v7 = v1->state[2];
	v20 = 0;
	v18 = v5;
	v8 = v1->state[1];
	v19 = v6;
	v9 = v1->state[4];
	v17 = v7;
	do
	{
		v10 = *(_DWORD *)&v16[4 * v20] + (32 * v18 | (v18 >> 27)) + (v8 & v7 | v19 & ~v8) + v9 + 0x5A827999;
		v9 = v19;
		v19 = v17;
		v7 = (v8 >> 2) | (v8 << 30);
		++v20;
		v8 = v18;
		v17 = v7;
		v18 = v10;
	}
	while ( v20 < 20 );
	v20 = 20;
	do
	{
		v10 = *(_DWORD *)&v16[4 * v20] + (v8 ^ v7 ^ v19) + (32 * v10 | (v10 >> 27)) + v9 + 0x6ED9EBA1;
		v9 = v19;
		v19 = v7;
		v7 = (v8 >> 2) | (v8 << 30);
		++v20;
		v8 = v18;
		v18 = v10;
	}
	while ( v20 < 40 );
	v17 = v7;
	v20 = 40;
	do
	{
		v10 = *(_DWORD *)&v16[4 * v20] + (32 * v10 | (v10 >> 27)) + (v8 & v7 | v19 & (v8 | v7)) + v9 - 0x70E44324;
		v9 = v19;
		v19 = v17;
		v7 = (v8 >> 2) | (v8 << 30);
		++v20;
		v8 = v18;
		v17 = v7;
		v18 = v10;
	}
	while ( v20 < 60 );
	v20 = 60;
	do
	{
		v10 = *(_DWORD *)&v16[4 * v20] + (v8 ^ v7 ^ v19) + (32 * v10 | (v10 >> 27)) + v9 - 0x359D3E2A;
		v9 = v19;
		v19 = v7;
		v7 = (v8 >> 2) | (v8 << 30);
		++v20;
		v8 = v18;
		v18 = v10;
	}
	while ( v20 < 80 );
	v11 = v10 + v1->state[0];
	v12 = v8 + v1->state[1];
	v13 = v7 + v1->state[2];
	v1->state[1] = v12;
	v14 = v19;
	v1->state[2] = v13;
	v15 = v14 + v1->state[3];
	v1->state[0] = v11;
	v1->state[3] = v15;
	v1->state[4] += v9;
}

//----- (00456C82) --------------------------------------------------------
void __fastcall sha1_init(int ctx_id)
{
	SHA1Context *v1; // ecx

	v1 = &sha1_contexts[ctx_id];
	v1->count[0] = 0;
	v1->count[1] = 0;
	v1->state[0] = 0x67452301;
	v1->state[1] = 0xEFCDAB89;
	v1->state[2] = 0x98BADCFE;
	v1->state[3] = 0x10325476;
	v1->state[4] = 0xC3D2E1F0;
}

//----- (00456CC0) --------------------------------------------------------
void __cdecl sound_cpp_init()
{
	LODWORD(sound_cpp_init_value) = sound_inf;
}
// 47F24C: using guessed type int sound_inf;

//----- (00456CCB) --------------------------------------------------------
void __fastcall snd_update(bool bStopAll)
{
	BOOL v1; // edi
	unsigned int v2; // esi
	IDirectSoundBuffer *v3; // eax
	int v4; // [esp+8h] [ebp-4h]

	v1 = bStopAll;
	v2 = 0;
	do
	{
		v3 = DSBs[v2];
		if ( v3 && (v1 || IDirectSoundBuffer_GetStatus(v3, (unsigned long *)&v4) || v4 != 1) )
		{
			IDirectSoundBuffer_Stop(DSBs[v2]);
			IDirectSoundBuffer_Release(DSBs[v2]);
			DSBs[v2] = 0;
		}
		++v2;
	}
	while ( v2 < 8 );
}

//----- (00456D22) --------------------------------------------------------
void __fastcall snd_stop_snd(TSnd *pSnd)
{
	IDirectSoundBuffer *v1; // eax

	if ( pSnd )
	{
		v1 = pSnd->DSB;
		if ( v1 )
			IDirectSoundBuffer_Stop(v1);
	}
}

//----- (00456D34) --------------------------------------------------------
bool __fastcall snd_playing(TSnd *pSnd)
{
	IDirectSoundBuffer *v1; // eax
	bool result; // al
	TSnd *v3; // [esp+0h] [ebp-4h]

	v3 = pSnd;
	if ( pSnd
	  && (v1 = pSnd->DSB) != 0
	  && !IDirectSoundBuffer_GetStatus(v1, (unsigned long *)&v3) )
	{
		result = v3 == (TSnd *)1;
	}
	else
	{
		result = 0;
	}
	return result;
}

//----- (00456D60) --------------------------------------------------------
void __fastcall snd_play_snd(TSnd *pSnd, int lVolume, int lPan)
{
	TSnd *v3; // edi
	int v4; // ebp
	IDirectSoundBuffer *v5; // esi
	int v6; // eax
	int v7; // ebp
	int v8; // eax
	int v9; // eax
	DWORD v10; // [esp+30h] [ebp-4h]

	v3 = pSnd;
	v4 = lVolume;
	if ( pSnd )
	{
		if ( gbSoundOn )
		{
			v5 = pSnd->DSB;
			if ( v5 )
			{
				v10 = GetTickCount();
				if ( v10 - v3->start_tc >= 0x50 )
				{
					_LOBYTE(v6) = snd_playing(v3);
					if ( !v6 || (v5 = sound_dup_channel(v3->DSB)) != 0 )
					{
						v7 = sglSoundVolume + v4;
						if ( v7 >= -1600 )
						{
							if ( v7 > 0 )
								v7 = 0;
						}
						else
						{
							v7 = -1600;
						}
						IDirectSoundBuffer_SetVolume(v5, v7);
						IDirectSoundBuffer_SetPan(v5, lPan);
						v8 = IDirectSoundBuffer_Play(
								 v5,
								 0,
								 0,
								 0);
						if ( v8 == 0x88780096 )
						{
							_LOBYTE(v9) = sound_file_reload(v3, v5);
							if ( v9 )
								IDirectSoundBuffer_Play(
									v5,
									0,
									0,
									0);
						}
						else if ( v8 )
						{
							DSErrDlg(v8, 261, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
						}
						v3->start_tc = v10;
					}
				}
				else
				{
					GetTickCount();
				}
			}
		}
	}
}
// 4A22D5: using guessed type char gbSoundOn;

//----- (00456E39) --------------------------------------------------------
IDirectSoundBuffer *__fastcall sound_dup_channel(IDirectSoundBuffer *DSB)
{
	IDirectSoundBuffer *result; // eax
	IDirectSoundBuffer **v2; // esi

	result = 0;
	if ( gbDupSounds )
	{
		while ( DSBs[(_DWORD)result] )
		{
			result = (IDirectSoundBuffer *)((char *)result + 1);
			if ( (unsigned int)result >= 8 )
				return 0;
		}
		v2 = &DSBs[(_DWORD)result];
		if ( IDirectSound_DuplicateSoundBuffer(
				 sglpDS,
				 DSB,
				 &DSBs[(_DWORD)result]) )
		{
			return 0;
		}
		result = *v2;
	}
	return result;
}
// 4A22D6: using guessed type char gbDupSounds;

//----- (00456E74) --------------------------------------------------------
bool __fastcall sound_file_reload(TSnd *sound_file, IDirectSoundBuffer *DSB)
{
	IDirectSoundBuffer *v2; // edi
	TSnd *v3; // esi
	LPARAM v5; // ecx
	int v6; // [esp+8h] [ebp-18h]
	int v7; // [esp+Ch] [ebp-14h]
	BOOL v8; // [esp+10h] [ebp-10h]
	char *a2; // [esp+14h] [ebp-Ch]
	int a3; // [esp+18h] [ebp-8h]
	void *a1; // [esp+1Ch] [ebp-4h]

	v2 = DSB;
	v3 = sound_file;
	if ( IDirectSoundBuffer_Restore(DSB) )
		return 0;
	v5 = v3->sound_path;
	v8 = 0;
	wave_open_file(v5, (DIABFILE *)&a1, 0);
	wave_file_pointer((int)a1, v3->offset, 0, 0);
	if ( !IDirectSoundBuffer_Lock(
			  v2,
			  0,
			  (unsigned long)v3->len,
			  (void **)&a2,
			  (unsigned long *)&a3,
			  (void **)&v6,
			  (unsigned long *)&v7,
			  0) )
	{
		wave_read_file((int)a1, a2, a3);
		if ( !IDirectSoundBuffer_Unlock(v2, a2, (unsigned long)a3, (void *)v6, v7) )
			v8 = 1;
	}
	wave_close_file(a1);
	return v8;
}

//----- (00456F07) --------------------------------------------------------
TSnd *__fastcall sound_file_load(char *path)
{
	int v1; // esi
	char *v2; // edi
	TSnd *v4; // esi
	int v5; // eax
	int v6; // eax
	int v7; // [esp-4h] [ebp-24h]
	int v8; // [esp+8h] [ebp-18h]
	int v9; // [esp+Ch] [ebp-14h]
	void *a1; // [esp+10h] [ebp-10h]
	void *ptr; // [esp+14h] [ebp-Ch]
	void *v12; // [esp+18h] [ebp-8h]
	size_t v13; // [esp+1Ch] [ebp-4h]

	v2 = path;
	if ( !sglpDS )
		return 0;
	v7 = v1;
	wave_open_file((LPARAM)path, (DIABFILE *)&a1, 0);
	v4 = (TSnd *)DiabloAllocPtr(40);
	memset(v4, 0, 0x28u);
	v4->sound_path = (int)v2;
	v4->start_tc = GetTickCount() - 81;
	ptr = (void *)wave_load_file((int)a1, v4, (int)&v4->len);
	if ( !ptr )
		TermMsg("Invalid sound format on file %s", v4->sound_path);
	sound_CreateSoundBuffer(v4);
	v5 = IDirectSoundBuffer_Lock(
			 v4->DSB,
			 0,
			 v4->len,
			 (void **)&v12,
			 (unsigned long *)&v13,
			 (void **)&v8,
			 (unsigned long *)&v9,
			 0);
			 //v7);
	if ( v5 )
		DSErrDlg(v5, 318, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
	memcpy(v12, (char *)ptr + v4->offset, v13);
	v6 = IDirectSoundBuffer_Unlock(v4->DSB, v12, v13, (void *)v8, 0);
	if ( v6 )
		DSErrDlg(v6, 325, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
	mem_free_dbg(ptr);
	wave_close_file(a1);
	return v4;
}
// 456F07: could not find valid save-restore pair for esi

//----- (00457003) --------------------------------------------------------
void __fastcall sound_CreateSoundBuffer(TSnd *sound_file)
{
	TSnd *v1; // esi
	int v2; // eax
	int v3; // [esp+4h] [ebp-14h]
	int v4; // [esp+8h] [ebp-10h]
	int v5; // [esp+Ch] [ebp-Ch]
	TSnd *v6; // [esp+14h] [ebp-4h]

	v1 = sound_file;
	memset(&v3, 0, 0x14u);
	v5 = v1->len;
	v6 = v1;
	v3 = 20;
	v4 = 194;
	v2 = IDirectSound_CreateSoundBuffer(
			 sglpDS,
			 (_DSBUFFERDESC *)&v3,
			 &v1->DSB,
			 0);
	if ( v2 )
		DSErrDlg(v2, 282, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
}

//----- (00457060) --------------------------------------------------------
void __fastcall sound_file_cleanup(TSnd *sound_file)
{
	TSnd *v1; // esi
	IDirectSoundBuffer *v2; // eax

	v1 = sound_file;
	if ( sound_file )
	{
		v2 = sound_file->DSB;
		if ( v2 )
		{
			IDirectSoundBuffer_Stop(sound_file->DSB);
			IDirectSoundBuffer_Release(v1->DSB);
			v1->DSB = 0;
		}
		mem_free_dbg(v1);
	}
}

//----- (0045708B) --------------------------------------------------------
void __fastcall snd_init(HWND hWnd)
{
	HWND v1; // edi

	v1 = hWnd;
	sound_load_volume("Sound Volume", &sglSoundVolume);
	gbSoundOn = sglSoundVolume > -1600;
	sound_load_volume("Music Volume", &sglMusicVolume);
	gbMusicOn = sglMusicVolume > -1600;
	if ( sound_DirectSoundCreate(0, &sglpDS, 0) )
		sglpDS = 0;
	if ( sglpDS && !IDirectSound_SetCooperativeLevel(sglpDS, v1, 3) )
		sound_create_primary_buffer(0);
	SVidInitialize(sglpDS);
	SFileDdaInitialize(sglpDS);
	gbSndInited = sglpDS != 0;
}
// 4A22D4: using guessed type char gbMusicOn;
// 4A22D5: using guessed type char gbSoundOn;

//----- (0045712B) --------------------------------------------------------
void __fastcall sound_load_volume(char *value_name, int *value)
{
	int *v2; // esi
	int v3; // eax
	int v4; // ecx
	int valuea; // [esp+8h] [ebp-4h]

	v2 = value;
	valuea = *value;
	_LOBYTE(v3) = SRegLoadValue("Diablo", value_name, 0, &valuea);
	if ( v3 )
		v4 = valuea;
	else
		v4 = 0;
	*v2 = v4;
	if ( v4 >= -1600 )
	{
		if ( v4 > 0 )
			*v2 = 0;
	}
	else
	{
		*v2 = -1600;
	}
	*v2 -= *v2 % 100;
}

//----- (0045717C) --------------------------------------------------------
void __fastcall sound_create_primary_buffer(int music_track)
{
	int v1; // eax
	int v2; // eax
	int v3[24]; // [esp+4h] [ebp-8Ch]
	int v4; // [esp+64h] [ebp-2Ch]
	int v5[4]; // [esp+68h] [ebp-28h]
	int a1; // [esp+78h] [ebp-18h]
	short v7; // [esp+7Ch] [ebp-14h]
	short v8; // [esp+7Eh] [ebp-12h]
	int v9; // [esp+80h] [ebp-10h]
	int v10; // [esp+84h] [ebp-Ch]
	unsigned short v11; // [esp+88h] [ebp-8h]
	unsigned short v12; // [esp+8Ah] [ebp-6h]
	int v13; // [esp+8Ch] [ebp-4h]

	a1 = music_track;
	if ( !music_track )
	{
		memset(&v4, 0, 0x14u);
		v4 = 20;
		v5[0] = 1;
		v1 = IDirectSound_CreateSoundBuffer(
				 sglpDS,
				 (_DSBUFFERDESC *)&v4,
				 (IDirectSoundBuffer **)&dword_69F100,
				 0);
		if ( v1 )
			DSErrDlg(v1, 375, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
	}
	if ( dword_69F100 )
	{
		v3[0] = 96;
		v2 = IDirectSound_GetCaps(sglpDS, (_DSCAPS *)v3);
		if ( v2 )
			DSErrDlg(v2, 383, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
		if ( !a1 || !wave_do_buffer(a1, (TSnd *)&v7) )
		{
			memset(&v7, 0, 0x12u);
			v7 = 1;
			v9 = 22050;
			v12 = 16;
			_LOWORD(v13) = 0;
		}
		v8 = 2;
		v11 = 2 * v12 / 8;
		v10 = v9 * v11;
		(*(void (__stdcall **)(int, short *))(*(_DWORD *)dword_69F100 + 56))(dword_69F100, &v7);
	}
}
// 69F100: using guessed type int dword_69F100;

//----- (0045727E) --------------------------------------------------------
int __fastcall sound_DirectSoundCreate(GUID *guid, IDirectSound **DS, int always_null)
{
	IDirectSound **v3; // ebp
	int v4; // eax
	FARPROC v5; // ebx
	int v6; // eax
	GUID *v8; // [esp+10h] [ebp-4h]

	v3 = DS;
	v8 = guid;
	if ( !hDsound_dll )
	{
		hDsound_dll = LoadLibraryA("dsound.dll");
		if ( !hDsound_dll )
		{
			v4 = GetLastError();
			TermDlg(108, v4, "C:\\Src\\Diablo\\Source\\SOUND.CPP", 422);
		}
	}
	v5 = GetProcAddress(hDsound_dll, "DirectSoundCreate");
	if ( !v5 )
	{
		v6 = GetLastError();
		TermDlg(108, v6, "C:\\Src\\Diablo\\Source\\SOUND.CPP", 427);
	}
	return ((int (__stdcall *)(GUID *, IDirectSound **, int))v5)(v8, v3, always_null);
}

//----- (004572FF) --------------------------------------------------------
void __cdecl sound_cleanup()
{
	snd_update(1);
	SVidDestroy();
	SFileDdaDestroy();
	if ( sglpDS )
	{
		IDirectSound_Release(sglpDS);
		sglpDS = 0;
	}
	if ( gbSndInited )
	{
		gbSndInited = 0;
		sound_store_volume("Sound Volume", sglSoundVolume);
		sound_store_volume("Music Volume", sglMusicVolume);
	}
}

//----- (00457358) --------------------------------------------------------
void __fastcall sound_store_volume(char *key, int value)
{
	SRegSaveValue("Diablo", key, 0, value);
}

//----- (00457367) --------------------------------------------------------
void __cdecl music_stop()
{
	if ( sgpMusicTrack )
	{
		SFileDdaEnd(sgpMusicTrack);
		SFileCloseFile(sgpMusicTrack);
		sgpMusicTrack = 0;
		sgnMusicTrack = 6;
	}
}

//----- (00457393) --------------------------------------------------------
void __fastcall music_start(int nTrack)
{
	int v1; // esi
	int v2; // eax
	int v3; // edi

	v1 = nTrack;
	music_stop();
	if ( sglpDS && gbMusicOn )
	{
		_LOBYTE(v2) = SFileOpenFile(sgszMusicTracks[v1], &sgpMusicTrack);
		v3 = v2;
		sound_create_primary_buffer((int)sgpMusicTrack);
		if ( v3 )
		{
			SFileDdaBeginEx(sgpMusicTrack, 0x40000, 0x40000, 0, sglMusicVolume, 0, 0);
			sgnMusicTrack = v1;
		}
		else
		{
			sgpMusicTrack = 0;
		}
	}
}
// 4A22D4: using guessed type char gbMusicOn;

//----- (004573FE) --------------------------------------------------------
void __fastcall sound_disable_music(bool disable)
{
	if ( disable )
	{
		music_stop();
	}
	else if ( sgnMusicTrack != 6 )
	{
		music_start(sgnMusicTrack);
	}
}

//----- (00457418) --------------------------------------------------------
int __fastcall sound_get_or_set_music_volume(int volume)
{
	if ( volume != 1 )
	{
		sglMusicVolume = volume;
		if ( sgpMusicTrack )
			SFileDdaSetVolume(sgpMusicTrack, volume, 0);
	}
	return sglMusicVolume;
}

//----- (0045743B) --------------------------------------------------------
int __fastcall sound_get_or_set_sound_volume(int volume)
{
	int result; // eax

	result = volume;
	if ( volume == 1 )
		return sglSoundVolume;
	sglSoundVolume = volume;
	return result;
}

//----- (0045744E) --------------------------------------------------------
int __fastcall GetManaAmount(int id, int sn)
{
	int v2; // eax
	int v3; // esi
	int v4; // ecx
	bool v5; // zf
	bool v6; // sf
	int v7; // ecx
	int v8; // ecx
	int v9; // edx

	v2 = id;
	v3 = 0;
	v4 = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd - 1;
	v5 = v4 == 0;
	v6 = v4 < 0;
	if ( v4 < 0 )
	{
		v4 = 0;
		v5 = 1;
		v6 = 0;
	}
	if ( !v6 && !v5 )
		v3 = v4 * spelldata[sn].sManaAdj;
	if ( sn == SPL_FIREBOLT )
		v3 >>= 1;
	if ( sn == SPL_RESURRECT && v4 > 0 )
		v3 = v4 * ((unsigned int)spelldata[32].sManaCost >> 3);
	_LOBYTE(v7) = spelldata[sn].sManaCost;
	if ( (_BYTE)v7 == -1 )
		v7 = _LOBYTE(plr[v2]._pMaxManaBase);
	else
		v7 = (unsigned char)v7;
	v8 = (v7 - v3) << 6;
	if ( sn == SPL_HEAL )
		v8 = (spelldata[2].sManaCost + 2 * plr[v2]._pLevel - v3) << 6;
	if ( sn == SPL_HEALOTHER )
		v8 = (spelldata[2].sManaCost + 2 * plr[v2]._pLevel - v3) << 6;
	if ( _LOBYTE(plr[v2]._pClass) == 1 )
		v8 -= v8 >> 2;
	v9 = spelldata[sn].sMinMana;
	if ( v9 > v8 >> 6 )
		v8 = v9 << 6;
	return v8 * (100 - plr[v2]._pISplCost) / 100;
}

//----- (0045753A) --------------------------------------------------------
void __fastcall UseMana(int id, int sn)
{
	int v2; // esi
	int v3; // eax

	if ( id == myplr )
	{
		v2 = id;
		switch ( plr[id]._pSplType )
		{
			case RSPLTYPE_SPELL:
				v3 = GetManaAmount(id, sn);
				plr[v2]._pMana -= v3;
				plr[v2]._pManaBase -= v3;
				drawmanaflag = 1;
				break;
			case RSPLTYPE_SCROLL:
				RemoveScroll(id);
				break;
			case RSPLTYPE_CHARGES:
				UseStaffCharge(id);
				break;
		}
	}
}

//----- (00457584) --------------------------------------------------------
bool __fastcall CheckSpell(int player_num, int spell_id, int spell_type, bool mana_only)
{
	bool result; // al
	int v5; // edi
	int v6; // esi

	result = 1;
	v5 = spell_id;
	v6 = player_num;
	if ( !mana_only && pcurs != 1 )
		return 0;
	if ( (_BYTE)spell_type )
	{
		if ( GetSpellLevel(player_num, spell_id) <= 0 )
			return 0;
		result = plr[v6]._pMana >= GetManaAmount(v6, v5);
	}
	return result;
}

//----- (004575D5) --------------------------------------------------------
void __fastcall CastSpell(int player_num, int spell_id, int x, int y, int target_x, int target_y, int target_num, int spell_lvl)
{
	int v8; // eax
	signed int v9; // edi
	char *v10; // esi
	int v11; // esi
	int midir; // [esp+8h] [ebp-8h]
	int id; // [esp+Ch] [ebp-4h]

	id = player_num;
	if ( target_num )
	{
		if ( target_num != 1 )
			goto LABEL_7;
		v8 = monster[player_num]._mdir;
	}
	else
	{
		target_num = 0;
		midir = plr[player_num]._pdir;
		if ( spell_id != 6 )
			goto LABEL_7;
		v8 = plr[player_num]._pVar3;
	}
	midir = v8;
LABEL_7:
	v9 = 0;
	v10 = spelldata[spell_id].sMissiles;
	if ( *v10 )
	{
		do
		{
			if ( v9 >= 3 )
				break;
			AddMissile(x, y, target_x, target_y, midir, (unsigned char)v10[v9++], target_num, id, 0, spell_lvl);
		}
		while ( v10[v9] );
	}
	if ( *v10 == 10 )
		UseMana(id, 7);
	if ( *v10 == 52 )
	{
		UseMana(id, 30);
		if ( (spell_lvl >> 1) + 3 > 0 )
		{
			v11 = (spell_lvl >> 1) + 3;
			do
			{
				AddMissile(x, y, target_x, target_y, midir, 52, target_num, id, 0, spell_lvl);
				--v11;
			}
			while ( v11 );
		}
	}
}

//----- (004576B1) --------------------------------------------------------
void __fastcall DoResurrect(int pnum, int rid)
{
	int v2; // ebx
	int v3; // esi
	int v4; // esi
	signed int v5; // edx
	int v6; // eax

	v2 = rid;
	v3 = pnum;
	if ( (_BYTE)rid != -1 )
		AddMissile(plr[rid].WorldX, plr[rid].WorldY, plr[rid].WorldX, plr[rid].WorldY, 0, 62, 0, pnum, 0, 0);
	if ( v3 == myplr )
		SetCursor(1);
	if ( (_BYTE)v2 != -1 )
	{
		v4 = v2;
		if ( !plr[v2]._pHitPoints )
		{
			if ( v2 == myplr )
			{
				*(_DWORD *)&deathflag = 0;
				gamemenu_off();
				drawhpflag = 1;
				drawmanaflag = 1;
			}
			ClrPlrPath(v2);
			plr[v4].destAction = -1;
			plr[v4]._pInvincible = 0;
			PlacePlayer(v2);
			v5 = 640;
			if ( plr[v4]._pMaxHPBase < 640 )
				v5 = plr[v4]._pMaxHPBase;
			SetPlayerHitPoints(v2, v5);
			v6 = plr[v4]._pMaxHPBase - plr[v4]._pMaxHP;
			plr[v4]._pMana = 0;
			plr[v4]._pHPBase = plr[v4]._pHitPoints + v6;
			plr[v4]._pManaBase = plr[v4]._pMaxManaBase - plr[v4]._pMaxMana;
			CalcPlrInv(v2, 1u);
			if ( plr[v4].plrlevel == currlevel )
				StartStand(v2, plr[v4]._pdir);
			else
				plr[v4]._pmode = 0;
		}
	}
}

//----- (004577CB) --------------------------------------------------------
void __fastcall PlacePlayer(int pnum)
{
	int v1; // ebx
	unsigned int v2; // eax
	int v3; // edi
	int v4; // esi
	int v5; // eax
	bool v6; // zf
	signed int v7; // [esp+Ch] [ebp-18h]
	int p; // [esp+10h] [ebp-14h]
	int v9; // [esp+14h] [ebp-10h]
	signed int v10; // [esp+18h] [ebp-Ch]
	signed int v11; // [esp+1Ch] [ebp-8h]
	unsigned int i; // [esp+20h] [ebp-4h]
	signed int v13; // [esp+20h] [ebp-4h]

	p = pnum;
	v1 = pnum;
	if ( plr[pnum].plrlevel == currlevel )
	{
		v2 = 0;
		for ( i = 0; ; v2 = i )
		{
			v3 = plr[v1].WorldX + *(int *)((char *)plrxoff2 + v2);
			v4 = plr[v1].WorldY + *(int *)((char *)plryoff2 + v2);
			if ( PosOkPlayer(p, v3, v4) )
				break;
			i += 4;
			if ( i >= 0x20 )
				break;
		}
		if ( !PosOkPlayer(p, v3, v4) )
		{
			v11 = 0;
			v5 = -1;
			v13 = 1;
			v7 = -1;
			do
			{
				if ( v11 )
					break;
				v9 = v5;
				while ( v5 <= v13 && !v11 )
				{
					v4 = v9 + plr[v1].WorldY;
					v10 = v7;
					do
					{
						if ( v11 )
							break;
						v3 = v10 + plr[v1].WorldX;
						if ( PosOkPlayer(p, v10 + plr[v1].WorldX, v4) )
							v11 = 1;
						++v10;
					}
					while ( v10 <= v13 );
					v5 = ++v9;
				}
				++v13;
				v5 = v7-- - 1;
			}
			while ( v7 > -50 );
		}
		plr[v1].WorldX = v3;
		v6 = p == myplr;
		plr[v1].WorldY = v4;
		dPlayer[v3][v4] = p + 1;
		if ( v6 )
		{
			ViewX = v3;
			ViewY = v4;
		}
	}
}

//----- (004578EE) --------------------------------------------------------
void __fastcall DoHealOther(int pnum, int rid)
{
	int v2; // ebx
	int v3; // esi
	int v4; // ebx
	int v5; // ecx
	int v6; // edi
	int v7; // ecx
	char v8; // bl
	int v9; // eax
	int *v10; // eax
	int v11; // esi
	int id; // [esp+8h] [ebp-8h]
	int v13; // [esp+Ch] [ebp-4h]
	signed int v14; // [esp+Ch] [ebp-4h]
	int i; // [esp+Ch] [ebp-4h]

	v2 = pnum;
	v13 = rid;
	id = pnum;
	if ( pnum == myplr )
		SetCursor(1);
	if ( (_BYTE)v13 != -1 )
	{
		v3 = v13;
		if ( (signed int)(plr[v13]._pHitPoints & 0xFFFFFFC0) > 0 )
		{
			_LOBYTE(pnum) = 57;
			v4 = v2;
			v14 = 0;
			v6 = (random(pnum, 10) + 1) << 6;
			if ( plr[v4]._pLevel > 0 )
			{
				do
				{
					_LOBYTE(v5) = 57;
					v6 += (random(v5, 4) + 1) << 6;
					++v14;
				}
				while ( v14 < plr[v4]._pLevel );
			}
			for ( i = 0; i < GetSpellLevel(id, 34); ++i )
			{
				_LOBYTE(v7) = 57;
				v6 += (random(v7, 6) + 1) << 6;
			}
			v8 = plr[v4]._pClass;
			if ( !v8 )
				v6 *= 2;
			if ( v8 == 1 )
				v6 += v6 >> 1;
			plr[v3]._pHitPoints += v6;
			v9 = plr[v3]._pMaxHP;
			if ( plr[v3]._pHitPoints > v9 )
				plr[v3]._pHitPoints = v9;
			v10 = &plr[v3]._pHPBase;
			v11 = plr[v3]._pMaxHPBase;
			*v10 += v6;
			if ( *v10 > v11 )
				*v10 = v11;
			drawhpflag = 1;
		}
	}
}

//----- (00457A01) --------------------------------------------------------
void __cdecl InitStores()
{
	int *v0; // eax

	pSTextBoxCels = LoadFileInMem("Data\\TextBox2.CEL", 0);
	pCelBuff = LoadFileInMem("Data\\PentSpn2.CEL", 0);
	pSTextSlidCels = LoadFileInMem("Data\\TextSlid.CEL", 0);
	ClearSText(0, 24);
	stextflag = 0;
	InStoreFlag = 1;
	premiumlevel = 1;
	stextsize = 0;
	stextscrl = 0;
	numpremium = 0;
	v0 = &premiumitem[0]._itype;
	do
	{
		*v0 = -1;
		v0 += 92;
	}
	while ( (signed int)v0 < (signed int)&talker );
	boyitem._itype = -1;
	boylevel = 0;
}
// 69FB38: using guessed type int talker;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;
// 6A8A3C: using guessed type int boylevel;
// 6AA705: using guessed type char stextflag;

//----- (00457A87) --------------------------------------------------------
void __cdecl SetupTownStores()
{
	DWORD v0; // eax
	int v1; // esi
	signed int v2; // eax
	int v3; // esi

	v0 = GetTickCount();
	SetRndSeed(glSeedTbl[currlevel] * v0);
	if ( gbMaxPlayers == 1 )
	{
		v1 = 0;
		v2 = 0;
		do
		{
			if ( plr[myplr]._pLvlVisited[v2] )
				v1 = v2;
			++v2;
		}
		while ( v2 < 17 );
	}
	else
	{
		v1 = plr[myplr]._pLevel >> 1;
	}
	v3 = v1 + 2;
	if ( v3 < 6 )
		v3 = 6;
	if ( v3 > 16 )
		v3 = 16;
	SpawnStoreGold();
	SpawnSmith(v3);
	SpawnWitch(v3);
	SpawnHealer(v3);
	SpawnBoy(plr[myplr]._pLevel);
	SpawnPremium(plr[myplr]._pLevel);
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00457B42) --------------------------------------------------------
void __cdecl FreeStoreMem()
{
	void *v0; // ecx
	void *v1; // ecx
	void *v2; // ecx

	v0 = pSTextBoxCels;
	pSTextBoxCels = 0;
	mem_free_dbg(v0);
	v1 = pCelBuff;
	pCelBuff = 0;
	mem_free_dbg(v1);
	v2 = pSTextSlidCels;
	pSTextSlidCels = 0;
	mem_free_dbg(v2);
}

//----- (00457B78) --------------------------------------------------------
void __cdecl DrawSTextBack()
{
	char *v0; // edi
	signed int v1; // edx
	signed int v2; // ecx
	int v3; // edi
	signed int v4; // ecx
	_BYTE *v5; // edi
	signed int v6; // ecx

	Cel_decode(408, 487, pSTextBoxCels, 1, 271);
	v0 = &gpBuffer->row[324].pixels[347];
	v1 = 148;
	do
	{
		v2 = 132;
		do
		{
			*v0 = 0;
			v0 += 2;
			--v2;
		}
		while ( v2 );
		*v0 = 0;
		v3 = (int)(v0 - 1032);
		v4 = 132;
		do
		{
			v5 = (_BYTE *)(v3 + 1);
			*v5 = 0;
			v3 = (int)(v5 + 1);
			--v4;
		}
		while ( v4 );
		v0 = (char *)(v3 - 1032);
		--v1;
	}
	while ( v1 );
	v6 = 132;
	do
	{
		*v0 = 0;
		v0 += 2;
		--v6;
	}
	while ( v6 );
	*v0 = 0;
}

//----- (00457BD6) --------------------------------------------------------
void __fastcall PrintSString(int x, int y, unsigned char cjustflag, char *str, int col, int val)
{
	int v6; // edi
	int v7; // eax
	int v8; // ebx
	int v9; // esi
	int v10; // esi
	int v11; // ecx
	int v12; // eax
	int v13; // edx
	int v14; // ecx
	unsigned char v15; // al
	int v16; // ebx
	int v17; // ecx
	int v18; // eax
	int v19; // esi
	size_t v20; // ebx
	char *v21; // edx
	int v22; // ecx
	char valstr[32]; // [esp+Ch] [ebp-3Ch]
	int v24; // [esp+2Ch] [ebp-1Ch]
	int v25; // [esp+30h] [ebp-18h]
	int v26; // [esp+34h] [ebp-14h]
	int v27; // [esp+38h] [ebp-10h]
	int v28; // [esp+3Ch] [ebp-Ch]
	int v29; // [esp+40h] [ebp-8h]
	int v30; // [esp+44h] [ebp-4h]

	v6 = SStringY[y] + stext[y]._syoff;
	v7 = -(stextsize != 0);
	v8 = x;
	v9 = screen_y_times_768[v6 + 204];
	_LOWORD(v7) = v7 & 0xFEC0;
	v24 = y;
	v26 = x;
	v27 = v7 + 416;
	v10 = x + v7 + 416 + v9;
	v28 = strlen(str);
	v11 = 0;
	v25 = stextsize != 0 ? 577 : 257;
	v30 = 0;
	if ( cjustflag )
	{
		v12 = 0;
		if ( v28 > 0 )
		{
			do
			{
				v13 = (unsigned char)str[v11++];
				v12 += fontkern[fontframe[fontidx[v13]]] + 1;
			}
			while ( v11 < v28 );
		}
		if ( v12 < v25 )
			v30 = (v25 - v12) >> 1;
		v10 += v30;
	}
	if ( stextsel == v24 )
	{
		if ( cjustflag )
			v14 = v27 + v30 + v8 - 20;
		else
			v14 = v27 + v8 - 20;
		Cel_decode(v14, v6 + 205, pCelBuff, InStoreFlag, 12);
	}
	v29 = 0;
	if ( v28 > 0 )
	{
		do
		{
			v15 = fontframe[fontidx[(unsigned char)str[v29]]];
			v16 = v15;
			v17 = v30 + fontkern[v15] + 1;
			v30 += fontkern[v15] + 1;
			if ( v15 && v17 <= v25 )
				CPrintString(v10, (char *)v15, col);
			v18 = fontkern[v16];
			++v29;
			v10 += v18 + 1;
		}
		while ( v29 < v28 );
		v8 = v26;
	}
	if ( !cjustflag && val >= 0 )
	{
		sprintf(valstr, "%i", val);
		v19 = screen_y_times_768[v6 + 204] - v8 + 656;
		v20 = strlen(valstr);
		while ( (--v20 & 0x80000000) == 0 )
		{
			v21 = (char *)fontframe[fontidx[(unsigned char)valstr[v20]]];
			v19 += -1 - fontkern[(_DWORD)v21];
			if ( fontframe[fontidx[(unsigned char)valstr[v20]]] )
				CPrintString(v19, v21, col);
		}
		v8 = v26;
	}
	if ( stextsel == v24 )
	{
		if ( cjustflag )
			v22 = v27 + v30 + v8 + 4;
		else
			v22 = 660 - v8;
		Cel_decode(v22, v6 + 205, pCelBuff, InStoreFlag, 12);
	}
}
// 6A09E0: using guessed type char stextsize;
// 6A8A28: using guessed type int stextsel;
// 457BD6: using guessed type char valstr[32];

//----- (00457DE2) --------------------------------------------------------
void __fastcall DrawSLine(int y)
{
	int v1; // eax
	int v2; // eax
	char *v3; // esi
	char *v4; // edi
	signed int v5; // edx
	char *v6; // edi
	char *v7; // esi
	signed int v8; // [esp+0h] [ebp-10h]
	signed int v9; // [esp+8h] [ebp-8h]
	signed int v10; // [esp+Ch] [ebp-4h]

	v1 = screen_y_times_768[SStringY[y] + 198];
	if ( stextsize == 1 )
	{
		v8 = 142170;
		v2 = v1 + 90;
		v10 = 146;
		v9 = 182;
	}
	else
	{
		v8 = 142490;
		v2 = v1 + 410;
		v10 = 66;
		v9 = 502;
	}
	v3 = (char *)gpBuffer + v8;
	v4 = (char *)gpBuffer + v2;
	v5 = 3;
	do
	{
		qmemcpy(v4, v3, 4 * v10);
		v7 = &v3[4 * v10];
		v6 = &v4[4 * v10];
		*(_WORD *)v6 = *(_WORD *)v7;
		v3 = &v7[v9 + 2];
		v4 = &v6[v9 + 2];
		--v5;
	}
	while ( v5 );
}
// 6A09E0: using guessed type char stextsize;

//----- (00457E62) --------------------------------------------------------
void __fastcall DrawSArrows(int a1, int a2)
{
	int *v2; // ebp
	int v3; // ebx
	int v4; // edi
	int v5; // esi
	int v6; // eax
	int v7; // eax

	v2 = &SStringY[a2];
	v3 = a1;
	v4 = SStringY[a1] + 204;
	v5 = *v2 + 204;
	if ( stextscrlubtn == -1 )
		Cel_decode(665, v4, pSTextSlidCels, 10, 12);
	else
		Cel_decode(665, v4, pSTextSlidCels, 12, 12);
	if ( stextscrldbtn == -1 )
		Cel_decode(665, v5, pSTextSlidCels, 9, 12);
	else
		Cel_decode(665, v5, pSTextSlidCels, 11, 12);
	while ( 1 )
	{
		v4 += 12;
		if ( v4 >= v5 )
			break;
		Cel_decode(665, v4, pSTextSlidCels, 14, 12);
	}
	v6 = stextsel;
	if ( stextsel == 22 )
		v6 = stextlhold;
	if ( storenumh <= 1 )
		v7 = 0;
	else
		v7 = (*v2 - SStringY[v3] - 24) * (1000 * (stextsval + ((v6 - stextup) >> 2)) / (storenumh - 1)) / 1000;
	Cel_decode(665, SStringY[v3 + 1] + v7 + 204, pSTextSlidCels, 13, 12);
}
// 69F108: using guessed type int stextup;
// 69F10C: using guessed type int storenumh;
// 69F110: using guessed type int stextlhold;
// 6A8A28: using guessed type int stextsel;
// 6A8A2C: using guessed type char stextscrldbtn;
// 6AA704: using guessed type char stextscrlubtn;

//----- (00457F52) --------------------------------------------------------
void __cdecl DrawSTextHelp()
{
	stextsel = -1;
	stextsize = 1;
}
// 6A09E0: using guessed type char stextsize;
// 6A8A28: using guessed type int stextsel;

//----- (00457F61) --------------------------------------------------------
void __fastcall ClearSText(int s, int e)
{
	int v2; // edx
	int *v3; // eax

	if ( s < e )
	{
		v2 = e - s;
		v3 = &stext[s]._syoff;
		do
		{
			v3[37] = -1;
			*(v3 - 1) = 0;
			*v3 = 0;
			*((_BYTE *)v3 + 4) = 0;
			v3[33] = 0;
			*((_BYTE *)v3 + 136) = 0;
			v3[35] = 0;
			v3[36] = 0;
			v3 += 39;
			--v2;
		}
		while ( v2 );
	}
}

//----- (00457FA6) --------------------------------------------------------
void __fastcall AddSLine(int y)
{
	int v1; // ecx

	v1 = y;
	stext[v1]._sx = 0;
	stext[v1]._syoff = 0;
	stext[v1]._sstr[0] = 0;
	stext[v1]._sline = 1;
}

//----- (00457FCB) --------------------------------------------------------
void __fastcall AddSTextVal(int y, int val)
{
	stext[y]._sval = val;
}

//----- (00457FD8) --------------------------------------------------------
void __fastcall OffsetSTextY(int y, int yo)
{
	stext[y]._syoff = yo;
}

//----- (00457FE5) --------------------------------------------------------
void __fastcall AddSText(int x, int y, unsigned char j, char *str, int clr, int sel)
{
	int v6; // esi

	v6 = y;
	stext[v6]._syoff = 0;
	stext[v6]._sx = x;
	strcpy(stext[y]._sstr, str);
	stext[v6]._sline = 0;
	stext[v6]._sjust = j;
	_LOBYTE(stext[v6]._sclr) = clr;
	stext[v6]._ssel = sel;
}

//----- (00458036) --------------------------------------------------------
unsigned char __cdecl StoreAutoPlace()
{
	int v0; // edi
	int v1; // eax
	int v2; // edx
	ItemStruct *v3; // ebp
	int v4; // esi
	int v5; // esi
	int v6; // esi
	int v7; // esi
	int v8; // esi
	int v9; // esi
	int v10; // esi
	int v11; // esi
	int *v12; // esi
	int v13; // esi
	int v14; // esi
	int v15; // esi
	int v16; // esi
	int v17; // esi
	signed int v19; // [esp+10h] [ebp-Ch]
	int v20; // [esp+14h] [ebp-8h]
	int v21; // [esp+18h] [ebp-4h]

	SetICursor(plr[myplr].HoldItem._iCurs + 12);
	v0 = icursH28;
	v1 = 0;
	v21 = icursW28;
	v20 = icursH28;
	if ( icursW28 == 1 )
	{
		if ( icursH28 == 1 )
		{
			v2 = myplr;
			if ( plr[myplr].HoldItem._iStatFlag && AllItemsList[plr[v2].HoldItem.IDidx].iUsable )
			{
				v19 = 0;
				v3 = plr[v2].SpdList;
				do
				{
					if ( v1 )
						break;
					if ( v3->_itype == -1 )
					{
						qmemcpy(v3, &plr[v2].HoldItem, sizeof(ItemStruct));
						v0 = v20;
						v1 = 1;
					}
					++v19;
					++v3;
				}
				while ( v19 < 8 );
			}
			v4 = 30;
			do
			{
				if ( v1 )
					break;
				v1 = AutoPlace(myplr, v4++, 1, 1, 1);
			}
			while ( v4 <= 39 );
			v5 = 20;
			do
			{
				if ( v1 )
					break;
				v1 = AutoPlace(myplr, v5++, 1, 1, 1);
			}
			while ( v5 <= 29 );
			v6 = 10;
			do
			{
				if ( v1 )
					break;
				v1 = AutoPlace(myplr, v6++, 1, 1, 1);
			}
			while ( v6 <= 19 );
			v7 = 0;
			while ( !v1 )
			{
				v1 = AutoPlace(myplr, v7++, 1, 1, 1);
				if ( v7 > 9 )
					goto LABEL_22;
			}
		}
		else
		{
LABEL_22:
			if ( v0 == 2 )
			{
				v8 = 29;
				do
				{
					if ( v1 )
						break;
					v1 = AutoPlace(myplr, v8--, 1, 2, 1);
				}
				while ( v8 >= 20 );
				v9 = 9;
				do
				{
					if ( v1 )
						break;
					v1 = AutoPlace(myplr, v9--, 1, 2, 1);
				}
				while ( v9 >= 0 );
				v10 = 19;
				while ( !v1 )
				{
					v1 = AutoPlace(myplr, v10--, 1, 2, 1);
					if ( v10 < 10 )
						goto LABEL_32;
				}
			}
			else
			{
LABEL_32:
				if ( v0 == 3 )
				{
					v11 = 0;
					while ( !v1 )
					{
						v1 = AutoPlace(myplr, v11++, 1, 3, 1);
						if ( v11 >= 20 )
							goto LABEL_36;
					}
				}
			}
		}
	}
	else
	{
LABEL_36:
		if ( v21 == 2 )
		{
			if ( v0 == 2 )
			{
				v12 = AP2x2Tbl;
				do
				{
					if ( v1 )
						break;
					v1 = AutoPlace(myplr, *v12, 2, 2, 1);
					++v12;
				}
				while ( (signed int)v12 < (signed int)"Data\\Inv\\Inv_Sor.CEL" );
				v13 = 21;
				do
				{
					if ( v1 )
						break;
					v1 = AutoPlace(myplr, v13, 2, 2, 1);
					v13 += 2;
				}
				while ( v13 < 29 );
				v14 = 1;
				do
				{
					if ( v1 )
						break;
					v1 = AutoPlace(myplr, v14, 2, 2, 1);
					v14 += 2;
				}
				while ( v14 < 9 );
				v15 = 10;
				while ( !v1 )
				{
					v1 = AutoPlace(myplr, v15++, 2, 2, 1);
					if ( v15 >= 19 )
						goto LABEL_50;
				}
			}
			else
			{
LABEL_50:
				if ( v0 == 3 )
				{
					v16 = 0;
					do
					{
						if ( v1 )
							break;
						v1 = AutoPlace(myplr, v16++, 2, 3, 1);
					}
					while ( v16 < 9 );
					v17 = 10;
					do
					{
						if ( v1 )
							break;
						v1 = AutoPlace(myplr, v17++, 2, 3, 1);
					}
					while ( v17 < 19 );
				}
			}
		}
	}
	return v1;
}
// 48E9A8: using guessed type int AP2x2Tbl[10];

//----- (004582B3) --------------------------------------------------------
void __cdecl S_StartSmith()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 1, 1u, "Welcome to the", COL_GOLD, 0);
	AddSText(0, 3, 1u, "Blacksmith's shop", COL_GOLD, 0);
	AddSText(0, 7, 1u, "Would you like to:", COL_GOLD, 0);
	AddSText(0, 10, 1u, "Talk to Griswold", 1, 1);
	AddSText(0, 12, 1u, "Buy basic items", 0, 1);
	AddSText(0, 14, 1u, "Buy premium items", 0, 1);
	AddSText(0, 16, 1u, "Sell items", 0, 1);
	AddSText(0, 18, 1u, "Repair items", 0, 1);
	AddSText(0, 20, 1u, "Leave the shop", 0, 1);
	AddSLine(5);
	storenumh = 20;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (0045837D) --------------------------------------------------------
void __fastcall S_ScrollSBuy(int idx)
{
	int v1; // esi
	int v2; // edi
	char *v3; // esi
	char *v4; // eax
	int iclr; // [esp+Ch] [ebp-4h]

	v1 = idx;
	v2 = 5;
	ClearSText(5, 21);
	v3 = &smithitem[v1]._iMagical;
	stextup = 5;
	do
	{
		if ( *((_DWORD *)v3 - 13) != -1 )
		{
			_LOBYTE(iclr) = 0;
			if ( *v3 )
				_LOBYTE(iclr) = COL_BLUE;
			if ( !*((_DWORD *)v3 + 74) )
				_LOBYTE(iclr) = COL_RED;
			v4 = v3 + 65;
			if ( !*v3 )
				v4 = v3 + 1;
			AddSText(20, v2, 0, v4, iclr, 1);
			AddSTextVal(v2, *((_DWORD *)v3 + 35));
			PrintStoreItem((ItemStruct *)(v3 - 60), v2 + 1, iclr);
			stextdown = v2;
			v3 += 368;
		}
		v2 += 4;
	}
	while ( v2 < 20 );
	if ( !stext[stextsel]._ssel && stextsel != 22 )
		stextsel = stextdown;
}
// 69F108: using guessed type int stextup;
// 6A8A28: using guessed type int stextsel;
// 6AA700: using guessed type int stextdown;

//----- (00458439) --------------------------------------------------------
void __fastcall PrintStoreItem(ItemStruct *x, int l, char iclr)
{
	ItemStruct *v3; // esi
	bool v4; // zf
	char v5; // cl
	char v6; // cl
	int v7; // eax
	char v8; // al
	unsigned char v9; // al
	char v10; // al
	int v11; // edi
	char v12[128]; // [esp+Ch] [ebp-84h]
	int y; // [esp+8Ch] [ebp-4h]

	v12[0] = 0;
	v3 = x;
	v4 = x->_iIdentified == 0;
	y = l;
	if ( !v4 )
	{
		if ( x->_iMagical != 2 )
		{
			v5 = x->_iPrePower;
			if ( v5 != -1 )
			{
				PrintItemPower(v5, v3);
				strcat(v12, tempstr);
			}
		}
		v6 = v3->_iSufPower;
		if ( v6 != -1 )
		{
			PrintItemPower(v6, v3);
			if ( v12[0] )
				strcat(v12, ",  ");
			strcat(v12, tempstr);
		}
	}
	if ( v3->_iMiscId == IMISC_STAFF && v3->_iMaxCharges )
	{
		sprintf(tempstr, "Charges: %i/%i", v3->_iCharges, v3->_iMaxCharges);
		if ( v12[0] )
			strcat(v12, ",  ");
		strcat(v12, tempstr);
	}
	if ( v12[0] )
		AddSText(40, y++, 0, v12, iclr, 0);
	v12[0] = 0;
	if ( v3->_iClass == 1 )
		sprintf(v12, "Damage: %i-%i  ", v3->_iMinDam, v3->_iMaxDam);
	if ( v3->_iClass == 2 )
		sprintf(v12, "Armor: %i  ", v3->_iAC);
	v7 = v3->_iMaxDur;
	if ( v7 != 255 && v7 )
	{
		sprintf(tempstr, "Dur: %i/%i,  ", v3->_iDurability, v3->_iMaxDur);
		strcat(v12, tempstr);
	}
	else
	{
		strcat(v12, "Indestructible,  ");
	}
	if ( !v3->_itype )
		v12[0] = 0;
	if ( v3->_iMinStr + (unsigned char)v3->_iMinMag + v3->_iMinDex )
	{
		strcpy(tempstr, "Required:");
		v8 = v3->_iMinStr;
		if ( v8 )
			sprintf(tempstr, "%s %i Str", tempstr, v8);
		v9 = v3->_iMinMag;
		if ( v9 )
			sprintf(tempstr, "%s %i Mag", tempstr, v9);
		v10 = v3->_iMinDex;
		if ( v10 )
			sprintf(tempstr, "%s %i Dex", tempstr, v10);
		strcat(v12, tempstr);
	}
	else
	{
		strcat(v12, "No required attributes");
	}
	v11 = y;
	AddSText(40, y, 0, v12, iclr, 0);
	if ( v3->_iMagical == 2 )
	{
		if ( v3->_iIdentified )
			AddSText(40, v11 + 1, 0, "Unique Item", iclr, 0);
	}
}

//----- (004586B3) --------------------------------------------------------
void __cdecl S_StartSBuy()
{
	int v0; // ST10_4
	int v1; // eax
	int *v2; // ecx

	v0 = plr[myplr]._pGold;
	stextsize = 1;
	stextscrl = 1;
	stextsval = 0;
	sprintf(tempstr, "I have these items for sale :		   Your gold : %i", v0);
	AddSText(0, 1, 1u, tempstr, COL_GOLD, 0);
	AddSLine(3);
	AddSLine(21);
	S_ScrollSBuy(stextsval);
	AddSText(0, 22, 1u, "Back", 0, 0);
	OffsetSTextY(22, 6);
	v1 = 0;
	storenumh = 0;
	if ( smithitem[0]._itype != -1 )
	{
		v2 = &smithitem[0]._itype;
		do
		{
			v2 += 92;
			++v1;
		}
		while ( *v2 != -1 );
		storenumh = v1;
	}
	stextsmax = v1 - 4;
	if ( v1 - 4 < 0 )
		stextsmax = 0;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00458773) --------------------------------------------------------
void __fastcall S_ScrollSPBuy(int idx)
{
	int v1; // esi
	int v2; // edi
	int v3; // eax
	int v4; // esi
	int *v5; // ecx
	char *v6; // esi
	int iclr; // [esp+Ch] [ebp-4h]

	v1 = idx;
	v2 = 5;
	ClearSText(5, 21);
	v3 = v1;
	v4 = 0;
	stextup = 5;
	if ( v3 )
	{
		v5 = &premiumitem[0]._itype;
		do
		{
			if ( *v5 != -1 )
				--v3;
			++v4;
			v5 += 92;
		}
		while ( v3 );
	}
	v6 = &premiumitem[v4]._iMagical;
	do
	{
		if ( (signed int)v6 >= (signed int)&stext[0]._sstr[36] )
			break;
		if ( *((_DWORD *)v6 - 13) == -1 )
		{
			v2 -= 4;
		}
		else
		{
			_LOBYTE(iclr) = 0;
			if ( *v6 )
				_LOBYTE(iclr) = 1;
			if ( !*((_DWORD *)v6 + 74) )
				_LOBYTE(iclr) = 2;
			AddSText(20, v2, 0, v6 + 65, iclr, 1);
			AddSTextVal(v2, *((_DWORD *)v6 + 35));
			PrintStoreItem((ItemStruct *)(v6 - 60), v2 + 1, iclr);
			stextdown = v2;
		}
		v2 += 4;
		v6 += 368;
	}
	while ( v2 < 20 );
	if ( !stext[stextsel]._ssel && stextsel != 22 )
		stextsel = stextdown;
}
// 69F108: using guessed type int stextup;
// 6A8A28: using guessed type int stextsel;
// 6AA700: using guessed type int stextdown;

//----- (00458851) --------------------------------------------------------
bool __cdecl S_StartSPBuy()
{
	int *v0; // eax
	bool result; // al
	int v2; // ST10_4

	storenumh = 0;
	v0 = &premiumitem[0]._itype;
	do
	{
		if ( *v0 != -1 )
			++storenumh;
		v0 += 92;
	}
	while ( (signed int)v0 < (signed int)&talker );
	if ( storenumh )
	{
		v2 = plr[myplr]._pGold;
		stextsval = 0;
		stextsize = 1;
		stextscrl = 1;
		sprintf(tempstr, "I have these premium items for sale :   Your gold : %i", v2);
		AddSText(0, 1, 1u, tempstr, 3, 0);
		AddSLine(3);
		AddSLine(21);
		AddSText(0, 22, 1u, "Back", 0, 0);
		OffsetSTextY(22, 6);
		stextsmax = storenumh - 4;
		if ( storenumh - 4 < 0 )
			stextsmax = 0;
		S_ScrollSPBuy(stextsval);
		result = 1;
	}
	else
	{
		StartStore(1);
		stextsel = 14;
		result = 0;
	}
	return result;
}
// 69F10C: using guessed type int storenumh;
// 69FB38: using guessed type int talker;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;
// 6A8A28: using guessed type int stextsel;

//----- (00458931) --------------------------------------------------------
bool __fastcall SmithSellOk(int inv_num)
{
	int v1; // ecx
	int v2; // eax
	BOOL v3; // eax

	v1 = 21720 * myplr + 368 * inv_num;
	v2 = *(int *)((char *)&plr[0].InvList[0]._itype + v1);
	if ( v2 != ITYPE_NONE && v2 && v2 != ITYPE_GOLD && v2 != ITYPE_0E && v2 != ITYPE_STAFF )
		v3 = *(int *)((char *)&plr[0].InvList[0].IDidx + v1) != IDI_LAZSTAFF;
	else
		_LOBYTE(v3) = 0;
	return v3;
}

//----- (00458972) --------------------------------------------------------
void __fastcall S_ScrollSSell(int idx)
{
	int v1; // esi
	int v2; // edi
	char *v3; // esi
	int v4; // edx
	int v5; // [esp+Ch] [ebp-8h]
	int iclr; // [esp+10h] [ebp-4h]

	v1 = idx;
	v5 = idx;
	v2 = 5;
	ClearSText(5, 21);
	v3 = &storehold[v1]._iMagical;
	stextup = 5;
	do
	{
		if ( v5 >= storenumh )
			break;
		if ( *((_DWORD *)v3 - 13) != -1 )
		{
			_LOBYTE(iclr) = 0;
			if ( *v3 )
				_LOBYTE(iclr) = 1;
			if ( !*((_DWORD *)v3 + 74) )
				_LOBYTE(iclr) = 2;
			if ( *v3 && *((_DWORD *)v3 - 1) )
			{
				AddSText(20, v2, 0, v3 + 65, iclr, 1);
				v4 = *((_DWORD *)v3 + 35);
			}
			else
			{
				AddSText(20, v2, 0, v3 + 1, iclr, 1);
				v4 = *((_DWORD *)v3 + 34);
			}
			AddSTextVal(v2, v4);
			PrintStoreItem((ItemStruct *)(v3 - 60), v2 + 1, iclr);
			stextdown = v2;
		}
		++v5;
		v2 += 4;
		v3 += 368;
	}
	while ( v2 < 20 );
	stextsmax = storenumh - 4;
	if ( storenumh - 4 < 0 )
		stextsmax = 0;
}
// 69F108: using guessed type int stextup;
// 69F10C: using guessed type int storenumh;
// 6A09E4: using guessed type int stextsmax;
// 6AA700: using guessed type int stextdown;

//----- (00458A59) --------------------------------------------------------
void __cdecl S_StartSSell()
{
	int *v0; // eax
	int v1; // edx
	int *v2; // ebp
	int v3; // eax
	bool v4; // zf
	int v5; // eax
	int v6; // ecx
	int v7; // ST10_4
	int v8; // ST10_4
	int inv_num; // [esp+Ch] [ebp-Ch]
	ItemStruct *v10; // [esp+10h] [ebp-8h]
	signed int v11; // [esp+14h] [ebp-4h]

	stextsize = 1;
	v11 = 0;
	storenumh = 0;
	v0 = &storehold[0]._itype;
	do
	{
		*v0 = -1;
		v0 += 92;
	}
	while ( (signed int)v0 < (signed int)witchitem );
	inv_num = 0;
	v1 = myplr;
	if ( plr[myplr]._pNumInv <= 0 )
		goto LABEL_18;
	v2 = &storehold[0]._ivalue;
	v10 = plr[v1].InvList;
	do
	{
		_LOBYTE(v3) = SmithSellOk(inv_num);
		if ( v3 )
		{
			v11 = 1;
			qmemcpy(v2 - 49, v10, 0x170u);
			if ( *((_BYTE *)v2 - 136) && *(v2 - 35) )
				*v2 = v2[1];
			v4 = *v2 >> 2 == 0;
			*v2 >>= 2;
			if ( v4 )
				*v2 = 1;
			v5 = *v2;
			v6 = storenumh++;
			v2[1] = v5;
			v2 += 92;
			storehidx[v6] = inv_num;
		}
		++inv_num;
		++v10;
	}
	while ( inv_num < plr[v1]._pNumInv );
	if ( v11 )
	{
		v8 = plr[v1]._pGold;
		stextsmax = plr[v1]._pNumInv;
		stextscrl = 1;
		stextsval = 0;
		sprintf(tempstr, "Which item is for sale?			Your gold : %i", v8);
		AddSText(0, 1, 1u, tempstr, 3, 0);
		AddSLine(3);
		AddSLine(21);
		S_ScrollSSell(stextsval);
		AddSText(0, 22, 1u, "Back", 0, 1);
		OffsetSTextY(22, 6);
	}
	else
	{
LABEL_18:
		v7 = plr[v1]._pGold;
		stextscrl = 0;
		sprintf(tempstr, "You have nothing I want.			Your gold : %i", v7);
		AddSText(0, 1, 1u, tempstr, 3, 0);
		AddSLine(3);
		AddSLine(21);
		AddSText(0, 22, 1u, "Back", 0, 1);
		OffsetSTextY(22, 6);
	}
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00458C0B) --------------------------------------------------------
bool __fastcall SmithRepairOk(int i)
{
	int v1; // eax
	int v2; // ecx
	bool result; // al

	v1 = 368 * i + 21720 * myplr;
	v2 = *(int *)((char *)&plr[0].InvList[0]._itype + v1);
	if ( v2 != ITYPE_NONE && v2 && v2 != ITYPE_GOLD && v2 != ITYPE_0E )
		result = *(int *)((char *)&plr[0].InvList[0]._iDurability + v1) != *(int *)((char *)&plr[0].InvList[0]._iMaxDur
																				  + v1);
	else
		result = 0;
	return result;
}

//----- (00458C4E) --------------------------------------------------------
void __cdecl S_StartSRepair()
{
	int v0; // ebp
	int *v1; // eax
	int v2; // esi
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // eax
	int v7; // edi
	int v8; // eax
	int v9; // esi
	int v10; // eax
	int v11; // [esp-4h] [ebp-1Ch]
	signed int v12; // [esp+10h] [ebp-8h]
	int v13; // [esp+14h] [ebp-4h]

	v0 = 0;
	stextsize = 1;
	v12 = 0;
	storenumh = 0;
	v1 = &storehold[0]._itype;
	do
	{
		*v1 = -1;
		v1 += 92;
	}
	while ( (signed int)v1 < (signed int)witchitem );
	v2 = myplr;
	v3 = myplr;
	if ( plr[myplr].InvBody[0]._itype != -1 && plr[v3].InvBody[0]._iDurability != plr[v3].InvBody[0]._iMaxDur )
	{
		v12 = 1;
		AddStoreHoldRepair(plr[v3].InvBody, -1);
		v2 = myplr;
	}
	v4 = v2;
	if ( plr[v2].InvBody[6]._itype != -1 && plr[v4].InvBody[6]._iDurability != plr[v4].InvBody[6]._iMaxDur )
	{
		v12 = 1;
		AddStoreHoldRepair(&plr[v4].InvBody[6], -2);
		v2 = myplr;
	}
	v5 = v2;
	if ( plr[v2].InvBody[4]._itype != -1 && plr[v5].InvBody[4]._iDurability != plr[v5].InvBody[4]._iMaxDur )
	{
		v12 = 1;
		AddStoreHoldRepair(&plr[v5].InvBody[4], -3);
		v2 = myplr;
	}
	v6 = v2;
	if ( plr[v2].InvBody[5]._itype != -1 && plr[v6].InvBody[5]._iDurability != plr[v6].InvBody[5]._iMaxDur )
	{
		v12 = 1;
		AddStoreHoldRepair(&plr[v6].InvBody[5], -4);
		v2 = myplr;
	}
	v7 = 21720 * v2;
	if ( plr[v2]._pNumInv > 0 )
	{
		v13 = 0;
		do
		{
			_LOBYTE(v8) = SmithRepairOk(v0);
			if ( v8 )
			{
				v12 = 1;
				AddStoreHoldRepair((ItemStruct *)((char *)&plr[0].InvList[v13] + v7), v0);
				v2 = myplr;
			}
			++v13;
			v7 = 21720 * v2;
			++v0;
		}
		while ( v0 < plr[v2]._pNumInv );
	}
	v9 = v2;
	v11 = plr[v9]._pGold;
	if ( v12 )
	{
		stextsval = 0;
		v10 = plr[v9]._pNumInv;
		stextscrl = 1;
		stextsmax = v10;
		sprintf(tempstr, "Repair which item?			Your gold : %i", v11);
		AddSText(0, 1, 1u, tempstr, COL_GOLD, 0);
		AddSLine(3);
		AddSLine(21);
		S_ScrollSSell(stextsval);
	}
	else
	{
		stextscrl = 0;
		sprintf(tempstr, "You have nothing to repair.			Your gold : %i", v11);
		AddSText(0, 1, 1u, tempstr, COL_GOLD, 0);
		AddSLine(3);
		AddSLine(21);
	}
	AddSText(0, 22, 1u, "Back", COL_WHITE, 1);
	OffsetSTextY(22, 6);
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00458E9A) --------------------------------------------------------
void __fastcall AddStoreHoldRepair(ItemStruct *itm, int i)
{
	int v2; // ebx
	ItemStruct *v3; // ebp
	int v4; // ecx
	int v5; // eax

	v2 = storenumh;
	v3 = &storehold[storenumh];
	qmemcpy(&storehold[storenumh], itm, sizeof(ItemStruct));
	v4 = (unsigned char)v3->_iMagical;
	if ( (_BYTE)v4 && v3->_iIdentified )
		v3->_ivalue = 30 * v3->_iIvalue / 100;
	v5 = v3->_ivalue * (100 * (v3->_iMaxDur - v3->_iDurability) / v3->_iMaxDur) / 100;
	if ( !v5 )
	{
		if ( (_BYTE)v4 && v3->_iIdentified )
			return;
		v5 = 1;
	}
	if ( v5 > 1 )
		v5 >>= 1;
	v3->_iIvalue = v5;
	v3->_ivalue = v5;
	storehidx[v2] = i;
	storenumh = v2 + 1;
}
// 69F10C: using guessed type int storenumh;

//----- (00458F3D) --------------------------------------------------------
void __cdecl S_StartWitch()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 2, 1u, "Witch's shack", COL_GOLD, 0);
	AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0);
	AddSText(0, 12, 1u, "Talk to Adria", 1, 1);
	AddSText(0, 14, 1u, "Buy items", 0, 1);
	AddSText(0, 16, 1u, "Sell items", 0, 1);
	AddSText(0, 18, 1u, "Recharge staves", 0, 1);
	AddSText(0, 20, 1u, "Leave the shack", 0, 1);
	AddSLine(5);
	storenumh = 20;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (00458FE3) --------------------------------------------------------
void __fastcall S_ScrollWBuy(int idx)
{
	int v1; // esi
	int v2; // edi
	char *v3; // esi
	char *v4; // eax
	int iclr; // [esp+Ch] [ebp-4h]

	v1 = idx;
	v2 = 5;
	ClearSText(5, 21);
	v3 = &witchitem[v1]._iMagical;
	stextup = 5;
	do
	{
		if ( *((_DWORD *)v3 - 13) != -1 )
		{
			_LOBYTE(iclr) = 0;
			if ( *v3 )
				_LOBYTE(iclr) = 1;
			if ( !*((_DWORD *)v3 + 74) )
				_LOBYTE(iclr) = 2;
			v4 = v3 + 65;
			if ( !*v3 )
				v4 = v3 + 1;
			AddSText(20, v2, 0, v4, iclr, 1);
			AddSTextVal(v2, *((_DWORD *)v3 + 35));
			PrintStoreItem((ItemStruct *)(v3 - 60), v2 + 1, iclr);
			stextdown = v2;
			v3 += 368;
		}
		v2 += 4;
	}
	while ( v2 < 20 );
	if ( !stext[stextsel]._ssel && stextsel != 22 )
		stextsel = stextdown;
}
// 69F108: using guessed type int stextup;
// 6A8A28: using guessed type int stextsel;
// 6AA700: using guessed type int stextdown;

//----- (0045909F) --------------------------------------------------------
void __cdecl S_StartWBuy()
{
	int v0; // ST10_4
	int v1; // eax
	int *v2; // ecx

	v0 = plr[myplr]._pGold;
	stextsize = 1;
	stextscrl = 1;
	stextsval = 0;
	stextsmax = 20;
	sprintf(tempstr, "I have these items for sale :		   Your gold : %i", v0);
	AddSText(0, 1, 1u, tempstr, 3, 0);
	AddSLine(3);
	AddSLine(21);
	S_ScrollWBuy(stextsval);
	AddSText(0, 22, 1u, "Back", 0, 0);
	OffsetSTextY(22, 6);
	v1 = 0;
	storenumh = 0;
	if ( witchitem[0]._itype != -1 )
	{
		v2 = &witchitem[0]._itype;
		do
		{
			v2 += 92;
			++v1;
		}
		while ( *v2 != -1 );
		storenumh = v1;
	}
	stextsmax = v1 - 4;
	if ( v1 - 4 < 0 )
		stextsmax = 0;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459169) --------------------------------------------------------
bool __fastcall WitchSellOk(int i)
{
	bool result; // al
	int v2; // edx
	ItemStruct *pI; // edx
	int v4; // ecx
	int v5; // edx

	result = 0;
	v2 = 21720 * myplr;
	if ( i < 0 )
		pI = (ItemStruct *)((char *)&plr[0].InvList[39] + v2 - 368 * i + 44);
	else
		pI = (ItemStruct *)((char *)&plr[0].InvList[i] + v2);
	v4 = pI->_itype;
	if ( !v4 )
		result = 1;
	if ( v4 == ITYPE_STAFF )
		result = 1;
	v5 = pI->IDidx;
	if ( v5 >= IDI_FIRSTQUEST && v5 <= IDI_LASTQUEST )
		result = 0;
	if ( v5 == IDI_LAZSTAFF )
		result = 0;
	return result;
}

//----- (004591C4) --------------------------------------------------------
void __cdecl S_StartWSell()
{
	int v0; // ebp
	int *v1; // eax
	int v2; // ebx
	int v3; // eax
	int v4; // eax
	int *v5; // ecx
	bool v6; // zf
	ItemStruct *v7; // esi
	int v8; // eax
	int v9; // eax
	int *v10; // ecx
	int v11; // eax
	int v12; // [esp-4h] [ebp-24h]
	int inv_or_belt_num; // [esp+10h] [ebp-10h]
	char inv_or_belt_numa; // [esp+10h] [ebp-10h]
	ItemStruct *i; // [esp+14h] [ebp-Ch]
	signed int ia; // [esp+14h] [ebp-Ch]
	signed int v17; // [esp+18h] [ebp-8h]
	ItemStruct *v18; // [esp+1Ch] [ebp-4h]

	v0 = 0;
	stextsize = 1;
	v17 = 0;
	storenumh = 0;
	v1 = &storehold[0]._itype;
	do
	{
		*v1 = -1;
		v1 += 92;
	}
	while ( (signed int)v1 < (signed int)witchitem );
	inv_or_belt_num = 0;
	v2 = myplr;
	if ( plr[myplr]._pNumInv > 0 )
	{
		i = plr[v2].InvList;
		do
		{
			_LOBYTE(v3) = WitchSellOk(inv_or_belt_num);
			if ( v3 )
			{
				v4 = v0;
				qmemcpy(&storehold[v0], i, sizeof(ItemStruct));
				v17 = 1;
				if ( storehold[v0]._iMagical && storehold[v4]._iIdentified )
					storehold[v4]._ivalue = storehold[v4]._iIvalue;
				v5 = &storehold[v4]._ivalue;
				v6 = storehold[v4]._ivalue >> 2 == 0;
				*v5 >>= 2;
				if ( v6 )
					*v5 = 1;
				++v0;
				storehold[v4]._iIvalue = *v5;
				*((_BYTE *)&golditem.inactive_16C + v0 + 3) = inv_or_belt_num;
				storenumh = v0;
			}
			++inv_or_belt_num;
			++i;
		}
		while ( inv_or_belt_num < plr[v2]._pNumInv );
	}
	ia = -1;
	v7 = plr[v2].SpdList;
	inv_or_belt_numa = 0;
	v18 = plr[v2].SpdList;
	do
	{
		if ( v7->_itype != -1 )
		{
			_LOBYTE(v8) = WitchSellOk(ia);
			if ( v8 )
			{
				v9 = v0;
				qmemcpy(&storehold[v0], v7, sizeof(ItemStruct));
				v17 = 1;
				if ( storehold[v0]._iMagical && storehold[v9]._iIdentified )
					storehold[v9]._ivalue = storehold[v9]._iIvalue;
				v10 = &storehold[v9]._ivalue;
				v6 = storehold[v9]._ivalue >> 2 == 0;
				*v10 >>= 2;
				if ( v6 )
					*v10 = 1;
				storehold[v9]._iIvalue = *v10;
				storenumh = ++v0;
				*((_BYTE *)&golditem.inactive_16C + v0 + 3) = -1 - inv_or_belt_numa;
			}
		}
		++inv_or_belt_numa;
		--ia;
		v7 = v18 + 1;
		++v18;
	}
	while ( ia > -9 );
	v12 = plr[v2]._pGold;
	if ( v17 )
	{
		v11 = plr[v2]._pNumInv;
		stextscrl = 1;
		stextsval = 0;
		stextsmax = v11;
		sprintf(tempstr, "Which item is for sale?			Your gold : %i", v12);
		AddSText(0, 1, 1u, tempstr, 3, 0);
		AddSLine(3);
		AddSLine(21);
		S_ScrollSSell(stextsval);
	}
	else
	{
		stextscrl = 0;
		sprintf(tempstr, "You have nothing I want.			Your gold : %i", v12);
		AddSText(0, 1, 1u, tempstr, COL_GOLD, 0);
		AddSLine(3);
		AddSLine(21);
	}
	AddSText(0, 22, 1u, "Back", 0, 1);
	OffsetSTextY(22, 6);
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459431) --------------------------------------------------------
unsigned char __fastcall WitchRechargeOk(int i)
{
	int v1; // ecx
	unsigned char result; // al

	v1 = 21720 * myplr + 368 * i;
	result = 0;
	if ( *(int *)((char *)&plr[0].InvList[0]._itype + v1) == ITYPE_STAFF
	  && *(int *)((char *)&plr[0].InvList[0]._iCharges + v1) != *(int *)((char *)&plr[0].InvList[0]._iMaxCharges + v1) )
	{
		result = 1;
	}
	return result;
}

//----- (00459460) --------------------------------------------------------
void __fastcall AddStoreHoldRecharge(ItemStruct itm, int i)
{
	int v2; // ebx
	int v3; // eax
	char v4; // ST10_1
	int v5; // ecx
	int v6; // eax

	v2 = storenumh;
	v3 = spelldata[itm._iSpell].sStaffCost;
	v4 = i;
	qmemcpy(&storehold[storenumh], &itm, sizeof(ItemStruct));
	storehold[v2]._ivalue += v3;
	v5 = storenumh;
	v6 = storehold[v2]._ivalue
	   * (100
		* (storehold[v2]._iMaxCharges - storehold[v2]._iCharges)
		/ storehold[v2]._iMaxCharges)
	   / 100 >> 1;
	++storenumh;
	storehold[v2]._ivalue = v6;
	storehold[v2]._iIvalue = v6;
	storehidx[v5] = v4;
}
// 69F108: using guessed type int stextup;
// 69F10C: using guessed type int storenumh;

//----- (004594E6) --------------------------------------------------------
void __cdecl S_StartWRecharge()
{
	int *v0; // eax
	int v1; // ebp
	int v2; // eax
	int v3; // eax
	ItemStruct v4; // [esp-170h] [ebp-18Ch]
	int v5; // [esp-4h] [ebp-20h]
	int inv_num; // [esp+10h] [ebp-Ch]
	ItemStruct *v7; // [esp+14h] [ebp-8h]
	int v8; // [esp+18h] [ebp-4h]

	stextsize = 1;
	v8 = 0;
	storenumh = 0;
	v0 = &storehold[0]._itype;
	do
	{
		*v0 = -1;
		v0 += 92;
	}
	while ( (signed int)v0 < (signed int)witchitem );
	v1 = myplr;
	if ( plr[myplr].InvBody[4]._itype == ITYPE_STAFF && plr[v1].InvBody[4]._iCharges != plr[v1].InvBody[4]._iMaxCharges )
	{
		v8 = 1;
		qmemcpy(&v4, &plr[v1].InvBody[4], sizeof(v4));
		AddStoreHoldRecharge(v4, -1);
	}
	v2 = plr[v1]._pNumInv;
	inv_num = 0;
	if ( v2 > 0 )
	{
		v7 = plr[v1].InvList;
		do
		{
			_LOBYTE(v3) = WitchRechargeOk(inv_num);
			if ( v3 )
			{
				v8 = 1;
				qmemcpy(&v4, v7, sizeof(v4));
				AddStoreHoldRecharge(v4, inv_num);
			}
			++inv_num;
			v2 = plr[v1]._pNumInv;
			++v7;
		}
		while ( inv_num < v2 );
	}
	v5 = plr[v1]._pGold;
	if ( v8 )
	{
		stextscrl = 1;
		stextsval = 0;
		stextsmax = v2;
		sprintf(tempstr, "Recharge which item?			Your gold : %i", v5);
		AddSText(0, 1, 1u, tempstr, 3, 0);
		AddSLine(3);
		AddSLine(21);
		S_ScrollSSell(stextsval);
	}
	else
	{
		stextscrl = 0;
		sprintf(tempstr, "You have nothing to recharge.			Your gold : %i", v5);
		AddSText(0, 1, 1u, tempstr, COL_GOLD, 0);
		AddSLine(3);
		AddSLine(21);
	}
	AddSText(0, 22, 1u, "Back", 0, 1);
	OffsetSTextY(22, 6);
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459693) --------------------------------------------------------
void __cdecl S_StartNoMoney()
{
	StartStore((unsigned char)stextshold);
	stextscrl = 0;
	stextsize = 1;
	ClearSText(5, 23);
	AddSText(0, 14, 1u, "You do not have enough gold", COL_WHITE, 1);
}
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (004596CD) --------------------------------------------------------
void __cdecl S_StartNoRoom()
{
	StartStore((unsigned char)stextshold);
	stextscrl = 0;
	ClearSText(5, 23);
	AddSText(0, 14, 1u, "You do not have enough room in inventory", COL_WHITE, 1);
}
// 6A6BB8: using guessed type int stextscrl;

//----- (00459700) --------------------------------------------------------
void __cdecl S_StartConfirm()
{
	int v0; // eax
	char v1; // dl
	BOOL v2; // esi
	char *v3; // eax
	int v4; // eax
	int iclr; // [esp+Ch] [ebp-4h]

	StartStore((unsigned char)stextshold);
	stextscrl = 0;
	ClearSText(5, 23);
	_LOBYTE(iclr) = 0;
	v0 = myplr;
	v1 = plr[myplr].HoldItem._iMagical;
	if ( v1 )
		_LOBYTE(iclr) = 1;
	if ( !plr[v0].HoldItem._iStatFlag )
		_LOBYTE(iclr) = 2;
	v2 = v1 != 0;
	if ( stextshold == STORE_SIDENTIFY )
		v2 = 0;
	if ( v1 && !plr[v0].HoldItem._iIdentified )
	{
		if ( stextshold == STORE_SSELL )
			v2 = 0;
		if ( stextshold == STORE_WSELL )
			v2 = 0;
		if ( stextshold == STORE_SREPAIR )
			v2 = 0;
		if ( stextshold == STORE_WRECHARGE )
			v2 = 0;
	}
	if ( v2 )
		v3 = plr[v0].HoldItem._iIName;
	else
		v3 = plr[v0].HoldItem._iName;
	AddSText(20, STORE_WRECHARGE, 0, v3, iclr, 0);
	AddSTextVal(STORE_WRECHARGE, plr[myplr].HoldItem._iIvalue);
	PrintStoreItem((ItemStruct *)((char *)&plr[0].HoldItem + v4), 9, iclr);
	if ( stextshold > STORE_WRECHARGE )
	{
		if ( stextshold == STORE_BBOY )
		{
			strcpy(tempstr, "Do we have a deal?");
			goto LABEL_37;
		}
		if ( stextshold != STORE_HBUY )
		{
			if ( stextshold == STORE_SIDENTIFY )
			{
				strcpy(tempstr, "Are you sure you want to identify this item?");
				goto LABEL_37;
			}
			if ( stextshold != 18 )
				goto LABEL_37;
		}
LABEL_34:
		strcpy(tempstr, "Are you sure you want to buy this item?");
		goto LABEL_37;
	}
	switch ( stextshold )
	{
		case STORE_WRECHARGE:
			strcpy(tempstr, "Are you sure you want to recharge this item?");
			break;
		case STORE_SBUY:
			goto LABEL_34;
		case STORE_SSELL:
LABEL_27:
			strcpy(tempstr, "Are you sure you want to sell this item?");
			break;
		case STORE_SREPAIR:
			strcpy(tempstr, "Are you sure you want to repair this item?");
			break;
		case STORE_WBUY:
			goto LABEL_34;
		case STORE_WSELL:
			goto LABEL_27;
	}
LABEL_37:
	AddSText(0, 15, 1u, tempstr, 0, 0);
	AddSText(0, 18, 1u, "Yes", 0, 1);
	AddSText(0, 20, 1u, "No", 0, 1);
}
// 6A6BB8: using guessed type int stextscrl;

//----- (00459873) --------------------------------------------------------
void __cdecl S_StartBoy()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 2, 1u, "Wirt the Peg-legged boy", COL_GOLD, 0);
	AddSLine(5);
	if ( boyitem._itype == -1 )
	{
		AddSText(0, 12, 1u, "Talk to Wirt", 1, 1);
		AddSText(0, 18, 1u, "Say goodbye", 0, 1);
	}
	else
	{
		AddSText(0, 8, 1u, "Talk to Wirt", 1, 1);
		AddSText(0, 12, 1u, "I have something for sale,", COL_GOLD, 0);
		AddSText(0, 14, 1u, "but it will cost 50 gold", COL_GOLD, 0);
		AddSText(0, 16, 1u, "just to take a look. ", COL_GOLD, 0);
		AddSText(0, 18, 1u, "What have you got?", 0, 1);
		AddSText(0, 20, 1u, "Say goodbye", 0, 1);
	}
}
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459930) --------------------------------------------------------
void __cdecl S_StartBBoy()
{
	int v0; // ST10_4
	signed int v1; // esi

	v0 = plr[myplr]._pGold;
	stextsize = 1;
	stextscrl = 0;
	sprintf(tempstr, "I have this item for sale :		   Your gold : %i", v0);
	AddSText(0, 1, 1u, tempstr, COL_GOLD, 0);
	AddSLine(3);
	AddSLine(21);
	v1 = 0;
	if ( boyitem._iMagical )
		v1 = 1;
	if ( !boyitem._iStatFlag )
		v1 = 2;
	if ( boyitem._iMagical )
		AddSText(20, 10, 0, boyitem._iIName, v1, 1);
	else
		AddSText(20, 10, 0, boyitem._iName, v1, 1);
	AddSTextVal(10, boyitem._iIvalue + (boyitem._iIvalue >> 1));
	PrintStoreItem(&boyitem, 11, v1);
	AddSText(0, 22, 1u, "Leave", 0, 1);
	OffsetSTextY(22, 6);
}
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (004599FD) --------------------------------------------------------
void __cdecl S_StartHealer()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 1, 1u, "Welcome to the", COL_GOLD, 0);
	AddSText(0, 3, 1u, "Healer's home", COL_GOLD, 0);
	AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0);
	AddSText(0, 12, 1u, "Talk to Pepin", 1, 1);
	AddSText(0, 14, 1u, "Receive healing", 0, 1);
	AddSText(0, 16, 1u, "Buy items", 0, 1);
	AddSText(0, 18, 1u, "Leave Healer's home", 0, 1);
	AddSLine(5);
	storenumh = 20;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459AA5) --------------------------------------------------------
void __fastcall S_ScrollHBuy(int idx)
{
	int v1; // esi
	int v2; // edi
	int *v3; // esi
	int iclr; // [esp+8h] [ebp-4h]

	v1 = idx;
	v2 = 5;
	ClearSText(5, 21);
	stextup = 5;
	v3 = &healitem[v1]._iStatFlag;
	do
	{
		if ( *(v3 - 87) != -1 )
		{
			_LOBYTE(iclr) = 0;
			if ( !*v3 )
				_LOBYTE(iclr) = 2;
			AddSText(20, v2, 0, (char *)v3 - 295, iclr, 1);
			AddSTextVal(v2, *(v3 - 39));
			PrintStoreItem((ItemStruct *)(v3 - 89), v2 + 1, iclr);
			stextdown = v2;
			v3 += 92;
		}
		v2 += 4;
	}
	while ( v2 < 20 );
	if ( !stext[stextsel]._ssel && stextsel != 22 )
		stextsel = stextdown;
}
// 69F108: using guessed type int stextup;
// 6A8A28: using guessed type int stextsel;
// 6AA700: using guessed type int stextdown;

//----- (00459B55) --------------------------------------------------------
void __cdecl S_StartHBuy()
{
	int v0; // ST10_4
	int v1; // eax
	int *v2; // ecx

	v0 = plr[myplr]._pGold;
	stextsize = 1;
	stextscrl = 1;
	stextsval = 0;
	sprintf(tempstr, "I have these items for sale :		   Your gold : %i", v0);
	AddSText(0, 1, 1u, tempstr, 3, 0);
	AddSLine(3);
	AddSLine(21);
	S_ScrollHBuy(stextsval);
	AddSText(0, 22, 1u, "Back", 0, 0);
	OffsetSTextY(22, 6);
	v1 = 0;
	storenumh = 0;
	if ( healitem[0]._itype != -1 )
	{
		v2 = &healitem[0]._itype;
		do
		{
			v2 += 92;
			++v1;
		}
		while ( *v2 != -1 );
		storenumh = v1;
	}
	stextsmax = v1 - 4;
	if ( v1 - 4 < 0 )
		stextsmax = 0;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459C15) --------------------------------------------------------
void __cdecl S_StartStory()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 2, 1u, "The Town Elder", COL_GOLD, 0);
	AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0);
	AddSText(0, 12, 1u, "Talk to Cain", 1, 1);
	AddSText(0, 14, 1u, "Identify an item", 0, 1);
	AddSText(0, 18, 1u, "Say goodbye", 0, 1);
	AddSLine(5);
}
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459C8E) --------------------------------------------------------
bool __fastcall IdItemOk(ItemStruct *item)
{
	bool result; // al

	result = 0;
	if ( item->_itype != -1 )
	{
		if ( item->_iMagical )
			result = item->_iIdentified == 0;
	}
	return result;
}

//----- (00459CA2) --------------------------------------------------------
void __fastcall AddStoreHoldId(ItemStruct itm, int i)
{
	int v2; // edx
	int v3; // eax

	v2 = storenumh;
	v3 = storenumh;
	qmemcpy(&storehold[storenumh], &itm, sizeof(ItemStruct));
	storehidx[v2] = i;
	storehold[v3]._ivalue = 100;
	storehold[v3]._iIvalue = 100;
	storenumh = v2 + 1;
}
// 69F108: using guessed type int stextup;
// 69F10C: using guessed type int storenumh;

//----- (00459CE6) --------------------------------------------------------
void __cdecl S_StartSIdentify()
{
	int *v0; // eax
	int v1; // ebp
	ItemStruct *v2; // esi
	int v3; // eax
	int v4; // eax
	int v5; // eax
	int v6; // eax
	int v7; // eax
	int v8; // eax
	int v9; // eax
	int v10; // eax
	ItemStruct *v11; // esi
	int v12; // eax
	ItemStruct v13; // [esp-170h] [ebp-18Ch]
	int v14; // [esp-4h] [ebp-20h]
	int v15; // [esp+10h] [ebp-Ch]
	int i; // [esp+14h] [ebp-8h]
	ItemStruct *v17; // [esp+18h] [ebp-4h]

	v15 = 0;
	storenumh = 0;
	stextsize = 1;
	v0 = &storehold[0]._itype;
	do
	{
		*v0 = -1;
		v0 += 92;
	}
	while ( (signed int)v0 < (signed int)witchitem );
	v1 = myplr;
	v2 = plr[myplr].InvBody;
	_LOBYTE(v3) = IdItemOk(plr[myplr].InvBody);
	if ( v3 )
	{
		v15 = 1;
		qmemcpy(&v13, v2, sizeof(v13));
		AddStoreHoldId(v13, -1);
	}
	_LOBYTE(v4) = IdItemOk(&plr[v1].InvBody[6]);
	if ( v4 )
	{
		v15 = 1;
		qmemcpy(&v13, &plr[v1].InvBody[6], sizeof(v13));
		AddStoreHoldId(v13, -2);
	}
	_LOBYTE(v5) = IdItemOk(&plr[v1].InvBody[4]);
	if ( v5 )
	{
		v15 = 1;
		qmemcpy(&v13, &plr[v1].InvBody[4], sizeof(v13));
		AddStoreHoldId(v13, -3);
	}
	_LOBYTE(v6) = IdItemOk(&plr[v1].InvBody[5]);
	if ( v6 )
	{
		v15 = 1;
		qmemcpy(&v13, &plr[v1].InvBody[5], sizeof(v13));
		AddStoreHoldId(v13, -4);
	}
	_LOBYTE(v7) = IdItemOk(&plr[v1].InvBody[1]);
	if ( v7 )
	{
		v15 = 1;
		qmemcpy(&v13, &plr[v1].InvBody[1], sizeof(v13));
		AddStoreHoldId(v13, -5);
	}
	_LOBYTE(v8) = IdItemOk(&plr[v1].InvBody[2]);
	if ( v8 )
	{
		v15 = 1;
		qmemcpy(&v13, &plr[v1].InvBody[2], sizeof(v13));
		AddStoreHoldId(v13, -6);
	}
	_LOBYTE(v9) = IdItemOk(&plr[v1].InvBody[3]);
	if ( v9 )
	{
		v15 = 1;
		qmemcpy(&v13, &plr[v1].InvBody[3], sizeof(v13));
		AddStoreHoldId(v13, -7);
	}
	v10 = plr[v1]._pNumInv;
	i = 0;
	if ( v10 > 0 )
	{
		v11 = plr[v1].InvList;
		v17 = plr[v1].InvList;
		do
		{
			_LOBYTE(v12) = IdItemOk(v11);
			if ( v12 )
			{
				v15 = 1;
				qmemcpy(&v13, v11, sizeof(v13));
				AddStoreHoldId(v13, i);
			}
			++i;
			v10 = plr[v1]._pNumInv;
			v11 = v17 + 1;
			++v17;
		}
		while ( i < v10 );
	}
	v14 = plr[v1]._pGold;
	if ( v15 )
	{
		stextscrl = 1;
		stextsval = 0;
		stextsmax = v10;
		sprintf(tempstr, "Identify which item?			Your gold : %i", v14);
		AddSText(0, 1, 1u, tempstr, 3, 0);
		AddSLine(3);
		AddSLine(21);
		S_ScrollSSell(stextsval);
	}
	else
	{
		stextscrl = 0;
		sprintf(tempstr, "You have nothing to identify.			Your gold : %i", v14);
		AddSText(0, 1, 1u, tempstr, COL_GOLD, 0);
		AddSLine(3);
		AddSLine(21);
	}
	AddSText(0, 22, 1u, "Back", 0, 1);
	OffsetSTextY(22, 6);
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;

//----- (00459F95) --------------------------------------------------------
void __cdecl S_StartIdShow()
{
	int iclr; // [esp+4h] [ebp-4h]

	StartStore((unsigned char)stextshold);
	stextscrl = 0;
	ClearSText(5, 23);
	_LOBYTE(iclr) = 0;
	if ( plr[myplr].HoldItem._iMagical )
		_LOBYTE(iclr) = COL_BLUE;
	if ( !plr[myplr].HoldItem._iStatFlag )
		_LOBYTE(iclr) = COL_RED;
	AddSText(0, 7, 1u, "This item is:", 0, 0);
	AddSText(20, 11, 0, plr[myplr].HoldItem._iIName, iclr, 0);
	PrintStoreItem(&plr[myplr].HoldItem, 12, iclr);
	AddSText(0, 18, 1u, "Done", 0, 1);
}
// 6A6BB8: using guessed type int stextscrl;

//----- (0045A046) --------------------------------------------------------
void __cdecl S_StartTalk()
{
	int *v0; // edi
	signed int v1; // eax
	int v2; // edx
	int *v3; // ecx
	char **v4; // ebp
	int v5; // esi
	int v6; // ebx
	signed int v7; // [esp-4h] [ebp-1Ch]
	signed int v8; // [esp+10h] [ebp-8h]
	int y; // [esp+14h] [ebp-4h]

	stextsize = 0;
	stextscrl = 0;
	sprintf(tempstr, "Talk to %s", talkname[talker]);
	AddSText(0, 2, 1u, tempstr, COL_GOLD, 0);
	AddSLine(5);
	v0 = &quests[0]._qlog;
	v1 = 0;
	v2 = 0;
	v3 = &quests[0]._qlog;
	do
	{
		if ( *((_BYTE *)v3 - 18) == 2 && *((_DWORD *)&Qtalklist[0]._qinfra + v2 + 16 * talker) != -1 && *v3 )
			++v1;
		v3 += 6;
		++v2;
	}
	while ( (signed int)v3 < (signed int)&qlist[4] );
	if ( v1 <= 6 )
	{
		v7 = 15;
		v8 = 2;
	}
	else
	{
		v1 >>= 1;
		v7 = 14;
		v8 = 1;
	}
	v4 = &questlist[0]._qlstr;
	v5 = v7 - v1;
	v6 = 0;
	y = v7 - v1 - 2;
	do
	{
		if ( *((_BYTE *)v0 - 18) == 2 && *((_DWORD *)&Qtalklist[0]._qinfra + v6 + 16 * talker) != -1 && *v0 )
		{
			AddSText(0, v5, 1u, *v4, COL_WHITE, 1);
			v5 += v8;
		}
		v0 += 6;
		++v6;
		v4 += 5;
	}
	while ( (signed int)v0 < (signed int)&qlist[4] );
	AddSText(0, y, 1u, "Gossip", 1, 1);
	AddSText(0, 22, 1u, "Back", COL_WHITE, 1);
}
// 69FB38: using guessed type int talker;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (0045A168) --------------------------------------------------------
void __cdecl S_StartTavern()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 1, 1u, "Welcome to the", COL_GOLD, 0);
	AddSText(0, 3, 1u, "Rising Sun", COL_GOLD, 0);
	AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0);
	AddSText(0, 12, 1u, "Talk to Ogden", 1, 1);
	AddSText(0, 18, 1u, "Leave the tavern", 0, 1);
	AddSLine(5);
	storenumh = 20;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (0045A1EC) --------------------------------------------------------
void __cdecl S_StartBarMaid()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 2, 1u, "Gillian", COL_GOLD, 0);
	AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0);
	AddSText(0, 12, 1u, "Talk to Gillian", 1, 1);
	AddSText(0, 18, 1u, "Say goodbye", 0, 1);
	AddSLine(5);
	storenumh = 20;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (0045A25E) --------------------------------------------------------
void __cdecl S_StartDrunk()
{
	stextsize = 0;
	stextscrl = 0;
	AddSText(0, 2, 1u, "Farnham the Drunk", COL_GOLD, 0);
	AddSText(0, 9, 1u, "Would you like to:", COL_GOLD, 0);
	AddSText(0, 12, 1u, "Talk to Farnham", 1, 1);
	AddSText(0, 18, 1u, "Say Goodbye", 0, 1);
	AddSLine(5);
	storenumh = 20;
}
// 69F10C: using guessed type int storenumh;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;

//----- (0045A2D0) --------------------------------------------------------
void __fastcall StartStore(int talk_id)
{
	char i; // bl
	int v2; // eax
	signed int v3; // ecx
	int *v4; // eax

	for ( i = talk_id; ; i = 1 )
	{
		sbookflag = 0;
		invflag = 0;
		chrflag = 0;
		questlog = 0;
		dropGoldFlag = 0;
		ClearSText(0, 24);
		ReleaseStoreBtn();
		switch ( i )
		{
			case STORE_SMITH:
				S_StartSmith();
				break;
			case STORE_SBUY:
				if ( storenumh > 0 )
					S_StartSBuy();
				break;
			case STORE_SSELL:
				S_StartSSell();
				break;
			case STORE_SREPAIR:
				S_StartSRepair();
				break;
			case STORE_WITCH:
				S_StartWitch();
				break;
			case STORE_WBUY:
				if ( storenumh > 0 )
					S_StartWBuy();
				break;
			case STORE_WSELL:
				S_StartWSell();
				break;
			case STORE_WRECHARGE:
				S_StartWRecharge();
				break;
			case STORE_NOMONEY:
				S_StartNoMoney();
				break;
			case STORE_NOROOM:
				S_StartNoRoom();
				break;
			case STORE_CONFIRM:
				S_StartConfirm();
				break;
			case STORE_BOY:
				S_StartBoy();
				break;
			case STORE_BBOY:
				S_StartBBoy();
				break;
			case STORE_HEALER:
				S_StartHealer();
				break;
			case STORE_STORY:
				S_StartStory();
				break;
			case STORE_HBUY:
				if ( storenumh > 0 )
					S_StartHBuy();
				break;
			case STORE_SIDENTIFY:
				S_StartSIdentify();
				break;
			case STORE_SPBUY:
				_LOBYTE(v2) = S_StartSPBuy();
				if ( !v2 )
					return;
				break;
			case STORE_GOSSIP:
				S_StartTalk();
				break;
			case STORE_IDSHOW:
				S_StartIdShow();
				break;
			case STORE_TAVERN:
				S_StartTavern();
				break;
			case STORE_DRUNK:
				S_StartDrunk();
				break;
			case STORE_BARMAID:
				S_StartBarMaid();
				break;
			default:
				break;
		}
		v3 = 0;
		v4 = &stext[0]._ssel;
		do
		{
			if ( *v4 )
				break;
			v4 += 39;
			++v3;
		}
		while ( (signed int)v4 < (signed int)&storehold[0]._iIName[7] );
		stextsel = v3 == 24 ? -1 : v3;
		stextflag = i;
		if ( i != 2 || storenumh )
			break;
	}
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8968: using guessed type int sbookflag;
// 69BD04: using guessed type int questlog;
// 69F10C: using guessed type int storenumh;
// 6A8A28: using guessed type int stextsel;
// 6AA705: using guessed type char stextflag;

//----- (0045A48F) --------------------------------------------------------
void __cdecl DrawSText()
{
	int v0; // ecx
	int v1; // edi
	int *v2; // esi

	if ( stextsize )
		DrawQTextBack();
	else
		DrawSTextBack();
	if ( !stextscrl )
		goto LABEL_19;
	if ( stextflag > (signed int)STORE_WRECHARGE )
	{
		switch ( stextflag )
		{
			case STORE_HBUY:
				S_ScrollHBuy(stextsval);
				break;
			case STORE_SIDENTIFY:
				goto LABEL_17;
			case STORE_SPBUY:
				S_ScrollSPBuy(stextsval);
				break;
		}
	}
	else
	{
		if ( stextflag >= (signed int)STORE_WSELL )
			goto LABEL_17;
		if ( stextflag == STORE_SBUY )
		{
			S_ScrollSBuy(stextsval);
			goto LABEL_19;
		}
		if ( stextflag > (signed int)STORE_SBUY )
		{
			if ( stextflag > (signed int)STORE_SREPAIR )
			{
				if ( stextflag == STORE_WBUY )
					S_ScrollWBuy(stextsval);
				goto LABEL_19;
			}
LABEL_17:
			S_ScrollSSell(stextsval);
			goto LABEL_19;
		}
	}
LABEL_19:
	v1 = 0;
	v2 = &stext[0]._sval;
	do
	{
		if ( *(v2 - 2) )
			DrawSLine(v1);
		if ( *((_BYTE *)v2 - 144) )
		{
			_LOBYTE(v0) = *((_BYTE *)v2 - 12);
			PrintSString(*(v2 - 38), v1, *(v2 - 4), (char *)v2 - 144, v0, *v2);
		}
		v2 += 39;
		++v1;
	}
	while ( (signed int)v2 < (signed int)&storehold[0]._iIName[11] );
	if ( stextscrl )
		DrawSArrows(4, 20);
	InStoreFlag = (InStoreFlag & 7) + 1;
}
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;
// 6AA705: using guessed type char stextflag;

//----- (0045A584) --------------------------------------------------------
void __cdecl STextESC()
{
	char v0; // cl
	char v1; // cl
	char v2; // cl

	if ( qtextflag )
	{
		qtextflag = 0;
		if ( !leveltype )
			sfx_stop();
	}
	else
	{
		switch ( stextflag )
		{
			case STORE_SMITH:
			case STORE_WITCH:
			case STORE_BOY:
			case STORE_BBOY:
			case STORE_HEALER:
			case STORE_STORY:
			case STORE_TAVERN:
			case STORE_DRUNK:
			case STORE_BARMAID:
				stextflag = 0;
				return;
			case STORE_SBUY:
				StartStore(1);
				stextsel = 12;
				return;
			case STORE_SSELL:
				v1 = 1;
				goto LABEL_16;
			case STORE_SREPAIR:
				v2 = 1;
				goto LABEL_14;
			case STORE_WBUY:
				v0 = 5;
				goto LABEL_18;
			case STORE_WSELL:
				v1 = 5;
				goto LABEL_16;
			case STORE_WRECHARGE:
				v2 = 5;
LABEL_14:
				StartStore(v2);
				stextsel = 18;
				return;
			case STORE_NOMONEY:
			case STORE_NOROOM:
			case STORE_CONFIRM:
				StartStore((unsigned char)stextshold);
				stextsel = stextlhold;
				stextsval = stextvhold;
				return;
			case STORE_HBUY:
				v1 = 14;
LABEL_16:
				StartStore(v1);
				stextsel = 16;
				return;
			case STORE_SIDENTIFY:
				v0 = 15;
				goto LABEL_18;
			case STORE_SPBUY:
				v0 = 1;
LABEL_18:
				StartStore(v0);
				stextsel = 14;
				break;
			case STORE_GOSSIP:
				StartStore((unsigned char)stextshold);
				stextsel = stextlhold;
				break;
			case STORE_IDSHOW:
				StartStore(17);
				break;
			default:
				return;
		}
	}
}
// 5BB1ED: using guessed type char leveltype;
// 646D00: using guessed type char qtextflag;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;
// 6AA705: using guessed type char stextflag;

//----- (0045A6AF) --------------------------------------------------------
void __cdecl STextUp()
{
	int v0; // eax

	PlaySFX(IS_TITLEMOV);
	if ( stextsel != -1 )
	{
		if ( stextscrl )
		{
			if ( stextsel == stextup )
			{
				if ( stextsval )
					--stextsval;
				return;
			}
			v0 = stextsel - 1;
			stextsel = v0;
			if ( stext[v0]._ssel )
				return;
			do
			{
				if ( v0 )
					--v0;
				else
					v0 = 23;
			}
			while ( !stext[v0]._ssel );
LABEL_20:
			stextsel = v0;
			return;
		}
		if ( stextsel )
			v0 = stextsel - 1;
		else
			v0 = 23;
		stextsel = v0;
		if ( !stext[v0]._ssel )
		{
			do
			{
				if ( v0 )
					--v0;
				else
					v0 = 23;
			}
			while ( !stext[v0]._ssel );
			goto LABEL_20;
		}
	}
}
// 69F108: using guessed type int stextup;
// 6A6BB8: using guessed type int stextscrl;
// 6A8A28: using guessed type int stextsel;

//----- (0045A757) --------------------------------------------------------
void __cdecl STextDown()
{
	int v0; // eax

	PlaySFX(IS_TITLEMOV);
	if ( stextsel != -1 )
	{
		if ( stextscrl )
		{
			if ( stextsel == stextdown )
			{
				if ( stextsval < stextsmax )
					++stextsval;
				return;
			}
			v0 = stextsel + 1;
			stextsel = v0;
			if ( stext[v0]._ssel )
				return;
			do
			{
				if ( v0 == 23 )
					v0 = 0;
				else
					++v0;
			}
			while ( !stext[v0]._ssel );
LABEL_20:
			stextsel = v0;
			return;
		}
		if ( stextsel == 23 )
			v0 = 0;
		else
			v0 = stextsel + 1;
		stextsel = v0;
		if ( !stext[v0]._ssel )
		{
			do
			{
				if ( v0 == 23 )
					v0 = 0;
				else
					++v0;
			}
			while ( !stext[v0]._ssel );
			goto LABEL_20;
		}
	}
}
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;
// 6A8A28: using guessed type int stextsel;
// 6AA700: using guessed type int stextdown;

//----- (0045A804) --------------------------------------------------------
void __cdecl STextPrior()
{
	PlaySFX(IS_TITLEMOV);
	if ( stextsel != -1 && stextscrl )
	{
		if ( stextsel == stextup )
		{
			if ( stextsval )
			{
				stextsval -= 4;
				if ( stextsval < 0 )
					stextsval = 0;
			}
		}
		else
		{
			stextsel = stextup;
		}
	}
}
// 69F108: using guessed type int stextup;
// 6A6BB8: using guessed type int stextscrl;
// 6A8A28: using guessed type int stextsel;

//----- (0045A84E) --------------------------------------------------------
void __cdecl STextNext()
{
	bool v0; // zf
	bool v1; // sf
	unsigned char v2; // of

	PlaySFX(IS_TITLEMOV);
	if ( stextsel != -1 && stextscrl )
	{
		if ( stextsel == stextdown )
		{
			v2 = __OFSUB__(stextsval, stextsmax);
			v0 = stextsval == stextsmax;
			v1 = stextsval - stextsmax < 0;
			if ( stextsval < stextsmax )
			{
				stextsval += 4;
				v2 = __OFSUB__(stextsval, stextsmax);
				v0 = stextsval == stextsmax;
				v1 = stextsval - stextsmax < 0;
			}
			if ( !((unsigned char)(v1 ^ v2) | v0) )
				stextsval = stextsmax;
		}
		else
		{
			stextsel = stextdown;
		}
	}
}
// 6A09E4: using guessed type int stextsmax;
// 6A6BB8: using guessed type int stextscrl;
// 6A8A28: using guessed type int stextsel;
// 6AA700: using guessed type int stextdown;

//----- (0045A89B) --------------------------------------------------------
void __cdecl S_SmithEnter()
{
	int v0; // ecx

	v0 = 10;
	if ( stextsel == 10 )
	{
		talker = 0;
		stextlhold = 10;
		stextshold = 1;
		gossipstart = 189;
		gossipend = 199;
		_LOBYTE(v0) = 19;
		goto LABEL_13;
	}
	v0 = 2;
	switch ( stextsel )
	{
		case 12:
LABEL_13:
			StartStore(v0);
			return;
		case 14:
			_LOBYTE(v0) = 18;
			goto LABEL_13;
		case 16:
			_LOBYTE(v0) = 3;
			goto LABEL_13;
		case 18:
			_LOBYTE(v0) = 4;
			goto LABEL_13;
		case 20:
			stextflag = 0;
			break;
	}
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045A904) --------------------------------------------------------
void __fastcall SetGoldCurs(int pnum, int i)
{
	int v2; // eax
	signed int v3; // ecx

	v2 = 21720 * pnum + 368 * i;
	v3 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v2);
	if ( v3 < 2500 )
	{
		if ( v3 > 1000 )
			*(int *)((char *)&plr[0].InvList[0]._iCurs + v2) = 5;
		else
			*(int *)((char *)&plr[0].InvList[0]._iCurs + v2) = 4;
	}
	else
	{
		*(int *)((char *)&plr[0].InvList[0]._iCurs + v2) = 6;
	}
}

//----- (0045A94A) --------------------------------------------------------
void __fastcall SetSpdbarGoldCurs(int pnum, int i)
{
	int v2; // eax
	signed int v3; // ecx

	v2 = 21720 * pnum + 368 * i;
	v3 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v2);
	if ( v3 < 2500 )
	{
		if ( v3 > 1000 )
			*(int *)((char *)&plr[0].SpdList[0]._iCurs + v2) = 5;
		else
			*(int *)((char *)&plr[0].SpdList[0]._iCurs + v2) = 4;
	}
	else
	{
		*(int *)((char *)&plr[0].SpdList[0]._iCurs + v2) = 6;
	}
}

//----- (0045A990) --------------------------------------------------------
void __fastcall TakePlrsMoney(int cost)
{
	int v1; // edi
	int v2; // eax
	int v3; // esi
	int v4; // ebx
	int v5; // eax
	_DWORD *v6; // ecx
	int v7; // eax
	int v8; // ebx
	int v9; // eax
	_DWORD *v10; // ecx
	int v11; // eax
	signed int v12; // ebx
	int v13; // eax
	int v14; // eax
	_DWORD *v15; // ecx
	int v16; // eax
	signed int v17; // ebx
	int v18; // eax
	int v19; // eax
	_DWORD *v20; // ecx
	int v21; // eax

	v1 = cost;
	v2 = CalculateGold(myplr);
	v3 = myplr;
	v4 = 0;
	plr[myplr]._pGold = v2 - v1;
	while ( v1 > 0 )
	{
		v5 = 368 * v4 + 21720 * v3;
		if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v5) == ITYPE_GOLD )
		{
			v6 = (unsigned int *)((char *)&plr[0].SpdList[0]._ivalue + v5);
			v7 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v5);
			if ( v7 != 5000 )
			{
				if ( v1 >= v7 )
				{
					v1 -= v7;
					RemoveSpdBarItem(v3, v4);
					v3 = myplr;
					v4 = -1;
				}
				else
				{
					*v6 = v7 - v1;
					SetSpdbarGoldCurs(v3, v4);
					v1 = 0;
				}
			}
		}
		if ( ++v4 >= 8 )
		{
			if ( v1 > 0 )
			{
				v8 = 0;
				do
				{
					if ( v1 <= 0 )
						break;
					v9 = 368 * v8 + 21720 * v3;
					if ( *(int *)((char *)&plr[0].SpdList[0]._itype + v9) == ITYPE_GOLD )
					{
						v10 = (unsigned int *)((char *)&plr[0].SpdList[0]._ivalue + v9);
						v11 = *(int *)((char *)&plr[0].SpdList[0]._ivalue + v9);
						if ( v1 >= v11 )
						{
							v1 -= v11;
							RemoveSpdBarItem(v3, v8);
							v3 = myplr;
							v8 = -1;
						}
						else
						{
							*v10 = v11 - v1;
							SetSpdbarGoldCurs(v3, v8);
							v1 = 0;
						}
					}
					++v8;
				}
				while ( v8 < 8 );
			}
			break;
		}
	}
	v12 = 0;
	force_redraw = 255;
	if ( v1 > 0 )
	{
		v13 = 21720 * v3;
		if ( plr[v3]._pNumInv <= 0 )
		{
LABEL_26:
			v17 = 0;
			if ( v1 > 0 )
			{
				v18 = 21720 * v3;
				if ( plr[v3]._pNumInv > 0 )
				{
					do
					{
						if ( v1 <= 0 )
							break;
						v19 = 368 * v17 + v18;
						if ( *(int *)((char *)&plr[0].InvList[0]._itype + v19) == ITYPE_GOLD )
						{
							v20 = (unsigned int *)((char *)&plr[0].InvList[0]._ivalue + v19);
							v21 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v19);
							if ( v1 >= v21 )
							{
								v1 -= v21;
								RemoveInvItem(v3, v17);
								v3 = myplr;
								v17 = -1;
							}
							else
							{
								*v20 = v21 - v1;
								SetGoldCurs(v3, v17);
								v1 = 0;
							}
						}
						++v17;
						v18 = 21720 * v3;
					}
					while ( v17 < plr[v3]._pNumInv );
				}
			}
		}
		else
		{
			while ( v1 > 0 )
			{
				v14 = 368 * v12 + v13;
				if ( *(int *)((char *)&plr[0].InvList[0]._itype + v14) == ITYPE_GOLD )
				{
					v15 = (unsigned int *)((char *)&plr[0].InvList[0]._ivalue + v14);
					v16 = *(int *)((char *)&plr[0].InvList[0]._ivalue + v14);
					if ( v16 != 5000 )
					{
						if ( v1 >= v16 )
						{
							v1 -= v16;
							RemoveInvItem(v3, v12);
							v3 = myplr;
							v12 = -1;
						}
						else
						{
							*v15 = v16 - v1;
							SetGoldCurs(v3, v12);
							v1 = 0;
						}
					}
				}
				++v12;
				v13 = 21720 * v3;
				if ( v12 >= plr[v3]._pNumInv )
					goto LABEL_26;
			}
		}
	}
}
// 52571C: using guessed type int force_redraw;

//----- (0045AB69) --------------------------------------------------------
void __cdecl SmithBuyItem()
{
	int v0; // eax
	ItemStruct *v1; // edx
	ItemStruct *v2; // edi
	bool v3; // zf

	TakePlrsMoney(plr[myplr].HoldItem._iIvalue);
	if ( !plr[myplr].HoldItem._iMagical )
		plr[myplr].HoldItem._iIdentified = 0;
	StoreAutoPlace();
	v0 = stextvhold + ((stextlhold - stextup) >> 2);
	if ( v0 == 19 )
	{
		smithitem[19]._itype = -1;
	}
	else
	{
		if ( smithitem[v0 + 1]._itype != -1 )
		{
			v1 = &smithitem[v0];
			do
			{
				v2 = v1;
				++v1;
				++v0;
				v3 = v1[1]._itype == -1;
				qmemcpy(v2, v1, sizeof(ItemStruct));
			}
			while ( !v3 );
		}
		smithitem[v0]._itype = -1;
	}
	CalcPlrInv(myplr, 1u);
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045AC14) --------------------------------------------------------
void __cdecl S_SBuyEnter()
{
	int v0; // eax
	int v1; // ecx
	int v2; // eax
	int v3; // esi
	char v4; // cl

	if ( stextsel == 22 )
	{
		StartStore(1);
		stextsel = 12;
	}
	else
	{
		stextlhold = stextsel;
		stextvhold = stextsval;
		stextshold = 2;
		v0 = myplr;
		v1 = stextsval + ((stextsel - stextup) >> 2);
		if ( plr[myplr]._pGold >= smithitem[v1]._iIvalue )
		{
			qmemcpy(&plr[v0].HoldItem, &smithitem[v1], sizeof(plr[v0].HoldItem));
			SetCursor(plr[v0].HoldItem._iCurs + 12);
			v2 = 0;
			v3 = 0;
			do
			{
				if ( v2 )
					goto LABEL_9;
				v2 = AutoPlace(myplr, v3++, cursW / 28, cursH / 28, 0);
			}
			while ( v3 < 40 );
			if ( v2 )
			{
LABEL_9:
				v4 = 11;
				goto LABEL_11;
			}
			v4 = 10;
LABEL_11:
			StartStore(v4);
			SetCursor(1);
		}
		else
		{
			StartStore(9);
		}
	}
}
// 4B8C9C: using guessed type int cursH;
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045ACE9) --------------------------------------------------------
void __cdecl SmithBuyPItem()
{
	int v0; // ecx
	int v1; // eax
	bool v2; // sf
	int v3; // eax
	int v4; // edx
	int *v5; // esi
	int v6; // eax

	TakePlrsMoney(plr[myplr].HoldItem._iIvalue);
	if ( !plr[myplr].HoldItem._iMagical )
		plr[myplr].HoldItem._iIdentified = 0;
	StoreAutoPlace();
	v0 = 0;
	v1 = (stextlhold - stextup) >> 2;
	v2 = stextvhold + v1 < 0;
	v3 = stextvhold + v1;
	v4 = 0;
	if ( !v2 )
	{
		v5 = &premiumitem[0]._itype;
		do
		{
			if ( *v5 != -1 )
			{
				--v3;
				v0 = v4;
			}
			++v4;
			v5 += 92;
		}
		while ( v3 >= 0 );
	}
	v6 = myplr;
	premiumitem[v0]._itype = -1;
	--numpremium;
	SpawnPremium(plr[v6]._pLevel);
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045AD7E) --------------------------------------------------------
void __cdecl S_SPBuyEnter()
{
	int v0; // eax
	bool v1; // sf
	int v2; // eax
	int v3; // ecx
	int v4; // edx
	int *v5; // esi
	int v6; // ecx
	int v7; // eax
	int v8; // eax
	int v9; // esi
	char v10; // cl

	if ( stextsel == 22 )
	{
		StartStore(1);
		stextsel = 14;
	}
	else
	{
		stextlhold = stextsel;
		stextshold = 18;
		stextvhold = stextsval;
		v0 = (stextsel - stextup) >> 2;
		v1 = stextsval + v0 < 0;
		v2 = stextsval + v0;
		v3 = 0;
		v4 = 0;
		if ( !v1 )
		{
			v5 = &premiumitem[0]._itype;
			do
			{
				if ( *v5 != -1 )
				{
					--v2;
					v3 = v4;
				}
				++v4;
				v5 += 92;
			}
			while ( v2 >= 0 );
		}
		v6 = v3;
		v7 = myplr;
		if ( plr[myplr]._pGold >= premiumitem[v6]._iIvalue )
		{
			qmemcpy(&plr[v7].HoldItem, &premiumitem[v6], sizeof(plr[v7].HoldItem));
			SetCursor(plr[v7].HoldItem._iCurs + 12);
			v8 = 0;
			v9 = 0;
			do
			{
				if ( v8 )
					goto LABEL_14;
				v8 = AutoPlace(myplr, v9++, cursW / 28, cursH / 28, 0);
			}
			while ( v9 < 40 );
			if ( v8 )
			{
LABEL_14:
				v10 = 11;
				goto LABEL_16;
			}
			v10 = 10;
LABEL_16:
			StartStore(v10);
			SetCursor(1);
		}
		else
		{
			StartStore(9);
		}
	}
}
// 4B8C9C: using guessed type int cursH;
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045AE72) --------------------------------------------------------
unsigned char __fastcall StoreGoldFit(int idx)
{
	int v1; // ecx
	int v2; // edi
	int v3; // ebx
	signed int v5; // ecx
	int v6; // eax
	int v7; // edx
	int *v8; // ecx
	int v9; // eax
	int v10; // eax
	int v11; // [esp+Ch] [ebp-4h]

	v1 = idx;
	v2 = storehold[v1]._iIvalue;
	v3 = storehold[v1]._iIvalue / 5000;
	if ( storehold[v1]._iIvalue % 5000 )
		++v3;
	SetCursor(storehold[v1]._iCurs + 12);
	v11 = cursW / 28 * (cursH / 28);
	SetCursor(1);
	if ( v11 >= v3 )
		return 1;
	v5 = 0;
	v6 = myplr;
	do
	{
		if ( !plr[v6].InvGrid[v5] )
			++v11;
		++v5;
	}
	while ( v5 < 40 );
	v7 = plr[v6]._pNumInv;
	if ( v7 > 0 )
	{
		v8 = &plr[v6].InvList[0]._ivalue;
		do
		{
			if ( *(v8 - 47) == 11 && *v8 != 5000 )
			{
				v9 = v2 + *v8;
				if ( v9 > 5000 )
					v2 = v9 - 5000;
				else
					v2 = 0;
			}
			v8 += 92;
			--v7;
		}
		while ( v7 );
	}
	v10 = v2 / 5000;
	if ( v2 % 5000 )
		++v10;
	return v11 >= v10;
}
// 4B8C9C: using guessed type int cursH;

//----- (0045AF48) --------------------------------------------------------
void __fastcall PlaceStoreGold(int v)
{
	int v1; // ebx
	signed int v2; // ecx
	int v3; // eax
	int v4; // ebp
	int v5; // esi
	int i; // ST20_4
	int v7; // eax
	int v8; // edx
	signed int v9; // [esp+10h] [ebp-10h]
	int v10; // [esp+18h] [ebp-8h]

	v1 = myplr;
	v10 = v;
	v2 = 0;
	v9 = 0;
	do
	{
		if ( v2 )
			break;
		v3 = v1;
		v4 = 10 * (v9 / 10);
		if ( !plr[v1].InvGrid[v9 % 10 + v4] )
		{
			v5 = plr[v3]._pNumInv;
			i = plr[v3]._pNumInv;
			GetGoldSeed(v1, &golditem._iSeed);
			v1 = myplr;
			v7 = myplr;
			v8 = 368 * v5 + 21720 * myplr;
			qmemcpy((char *)plr[0].InvList + v8, &golditem, 0x170u);
			++plr[v7]._pNumInv;
			plr[0].InvGrid[v9 % 10 + v7 * 21720 + v4] = plr[v7]._pNumInv;
			*(int *)((char *)&plr[0].InvList[0]._ivalue + v8) = v10;
			SetGoldCurs(v1, i);
			v2 = 1;
		}
		++v9;
	}
	while ( v9 < 40 );
}

//----- (0045B010) --------------------------------------------------------
void __cdecl StoreSellItem()
{
	int v0; // ebx
	char v1; // al
	int v2; // eax
	int v3; // ebp
	bool v4; // sf
	unsigned char v5; // of
	unsigned int v6; // eax
	int v7; // ebx
	int v8; // edx
	int v9; // esi
	int *v10; // edi
	int v11; // eax
	unsigned int v12; // esi
	int v13; // [esp+10h] [ebp-4h]

	v0 = stextvhold + ((stextlhold - stextup) >> 2);
	v1 = storehidx[v0];
	if ( v1 < 0 )
		RemoveSpdBarItem(myplr, -1 - v1);
	else
		RemoveInvItem(myplr, v1);
	v2 = storenumh - 1;
	v3 = storehold[v0]._iIvalue;
	v5 = __OFSUB__(v0, storenumh - 1);
	v4 = v0 - (storenumh-- - 1) < 0;
	if ( v4 ^ v5 )
	{
		v6 = v2 - v0;
		qmemcpy(&storehidx[v0], &storehidx[v0 + 1], v6);
		qmemcpy(&storehold[v0], &storehold[v0 + 1], 4 * (368 * v6 >> 2));
	}
	v7 = myplr;
	v8 = 0;
	v13 = 0;
	v9 = myplr;
	plr[v9]._pGold += v3;
	if ( plr[v9]._pNumInv <= 0 )
	{
LABEL_15:
		if ( v3 > 0 )
		{
			if ( v3 > 5000 )
			{
				v12 = (v3 - 5001) / 0x1388u + 1;
				v3 += -5000 * v12;
				do
				{
					PlaceStoreGold(5000);
					--v12;
				}
				while ( v12 );
			}
			PlaceStoreGold(v3);
		}
	}
	else
	{
		v10 = &plr[v9].InvList[0]._ivalue;
		while ( v3 > 0 )
		{
			if ( *(v10 - 47) == 11 && *v10 != 5000 )
			{
				v11 = v3 + *v10;
				if ( v11 > 5000 )
				{
					*v10 = 5000;
					v3 = v11 - 5000;
					SetGoldCurs(v7, v8);
				}
				else
				{
					*v10 = v11;
					SetGoldCurs(v7, v8);
					v3 = 0;
				}
			}
			v10 += 92;
			v8 = v13++ + 1;
			if ( v13 >= plr[v9]._pNumInv )
				goto LABEL_15;
		}
	}
}
// 69F108: using guessed type int stextup;
// 69F10C: using guessed type int storenumh;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045B160) --------------------------------------------------------
void __cdecl S_SSellEnter()
{
	int v0; // eax
	int v1; // eax
	char v2; // cl

	if ( stextsel == 22 )
	{
		StartStore(1);
		stextsel = 16;
	}
	else
	{
		stextlhold = stextsel;
		v0 = stextsval + ((stextsel - stextup) >> 2);
		stextshold = 3;
		stextvhold = stextsval;
		qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem));
		_LOBYTE(v1) = StoreGoldFit(v0);
		v2 = 11;
		if ( !v1 )
			v2 = 10;
		StartStore(v2);
	}
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045B1DF) --------------------------------------------------------
void __cdecl SmithRepairItem()
{
	int v0; // eax
	int v1; // edx

	TakePlrsMoney(plr[myplr].HoldItem._iIvalue);
	v0 = storehidx[stextvhold + ((stextlhold - stextup) >> 2)];
	storehold[stextvhold + ((stextlhold - stextup) >> 2)]._iDurability = storehold[stextvhold
																				 + ((stextlhold - stextup) >> 2)]._iMaxDur;
	if ( v0 >= 0 )
	{
		plr[myplr].InvList[v0]._iDurability = plr[myplr].InvList[v0]._iMaxDur;
	}
	else
	{
		v1 = myplr;
		if ( v0 == -1 )
			plr[myplr].InvBody[0]._iDurability = plr[myplr].InvBody[0]._iMaxDur;
		if ( v0 == -2 )
			plr[v1].InvBody[6]._iDurability = plr[v1].InvBody[6]._iMaxDur;
		if ( v0 == -3 )
			plr[v1].InvBody[4]._iDurability = plr[v1].InvBody[4]._iMaxDur;
		if ( v0 == -4 )
			plr[v1].InvBody[5]._iDurability = plr[v1].InvBody[5]._iMaxDur;
	}
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045B2B6) --------------------------------------------------------
void __cdecl S_SRepairEnter()
{
	int v0; // eax
	int v1; // edx
	int v2; // ecx
	bool v3; // sf
	unsigned char v4; // of
	char v5; // cl

	if ( stextsel == 22 )
	{
		StartStore(1);
		stextsel = 18;
	}
	else
	{
		stextlhold = stextsel;
		stextshold = 4;
		v0 = stextsval + ((stextsel - stextup) >> 2);
		v1 = myplr;
		stextvhold = stextsval;
		qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem));
		v2 = plr[v1]._pGold;
		v4 = __OFSUB__(v2, storehold[v0]._iIvalue);
		v3 = v2 - storehold[v0]._iIvalue < 0;
		v5 = 9;
		if ( !(v3 ^ v4) )
			v5 = 11;
		StartStore(v5);
	}
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045B337) --------------------------------------------------------
void __cdecl S_WitchEnter()
{
	int v0; // ecx

	v0 = 12;
	if ( stextsel == 12 )
	{
		stextlhold = 12;
		talker = 6;
		stextshold = 5;
		gossipstart = 213;
		gossipend = 223;
		_LOBYTE(v0) = 19;
		goto LABEL_12;
	}
	v0 = 2;
	switch ( stextsel )
	{
		case 14:
			_LOBYTE(v0) = 6;
			goto LABEL_12;
		case 16:
			_LOBYTE(v0) = 7;
			goto LABEL_12;
		case 18:
			_LOBYTE(v0) = 8;
LABEL_12:
			StartStore(v0);
			return;
		case 20:
			stextflag = 0;
			break;
	}
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045B39F) --------------------------------------------------------
void __cdecl WitchBuyItem()
{
	int v0; // ebx
	int v1; // eax
	int v2; // ecx
	ItemStruct *v3; // eax
	ItemStruct *v4; // edi
	bool v5; // zf

	v0 = stextvhold + ((stextlhold - stextup) >> 2);
	if ( v0 >= 3 )
	{
		v2 = myplr;
	}
	else
	{
		v1 = GetRndSeed();
		v2 = myplr;
		plr[myplr].HoldItem._iSeed = v1;
	}
	TakePlrsMoney(plr[v2].HoldItem._iIvalue);
	StoreAutoPlace();
	if ( v0 >= 3 )
	{
		if ( v0 == 19 )
		{
			witchitem[19]._itype = -1;
		}
		else
		{
			if ( witchitem[v0 + 1]._itype != -1 )
			{
				v3 = &witchitem[v0];
				do
				{
					v4 = v3;
					++v3;
					++v0;
					v5 = v3[1]._itype == -1;
					qmemcpy(v4, v3, sizeof(ItemStruct));
				}
				while ( !v5 );
			}
			witchitem[v0]._itype = -1;
		}
	}
	CalcPlrInv(myplr, 1u);
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045B457) --------------------------------------------------------
void __cdecl S_WBuyEnter()
{
	int v0; // eax
	int v1; // ecx
	int v2; // eax
	int v3; // esi
	char v4; // cl

	if ( stextsel == 22 )
	{
		StartStore(5);
		stextsel = 14;
	}
	else
	{
		stextlhold = stextsel;
		stextvhold = stextsval;
		stextshold = 6;
		v0 = myplr;
		v1 = stextsval + ((stextsel - stextup) >> 2);
		if ( plr[myplr]._pGold >= witchitem[v1]._iIvalue )
		{
			qmemcpy(&plr[v0].HoldItem, &witchitem[v1], sizeof(plr[v0].HoldItem));
			SetCursor(plr[v0].HoldItem._iCurs + 12);
			v2 = 0;
			v3 = 0;
			do
			{
				if ( v2 )
					goto LABEL_9;
				v2 = SpecialAutoPlace(myplr, v3++, cursW / 28, cursH / 28, 0);
			}
			while ( v3 < 40 );
			if ( v2 )
			{
LABEL_9:
				v4 = 11;
				goto LABEL_11;
			}
			v4 = 10;
LABEL_11:
			StartStore(v4);
			SetCursor(1);
		}
		else
		{
			StartStore(9);
		}
	}
}
// 4B8C9C: using guessed type int cursH;
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045B52C) --------------------------------------------------------
void __cdecl S_WSellEnter()
{
	int v0; // eax
	int v1; // eax
	char v2; // cl

	if ( stextsel == 22 )
	{
		StartStore(5);
		stextsel = 16;
	}
	else
	{
		stextlhold = stextsel;
		v0 = stextsval + ((stextsel - stextup) >> 2);
		stextshold = 7;
		stextvhold = stextsval;
		qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem));
		_LOBYTE(v1) = StoreGoldFit(v0);
		v2 = 11;
		if ( !v1 )
			v2 = 10;
		StartStore(v2);
	}
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045B5AB) --------------------------------------------------------
void __cdecl WitchRechargeItem()
{
	int v0; // eax
	int v1; // ecx

	TakePlrsMoney(plr[myplr].HoldItem._iIvalue);
	v0 = storehidx[stextvhold + ((stextlhold - stextup) >> 2)];
	storehold[stextvhold + ((stextlhold - stextup) >> 2)]._iCharges = storehold[stextvhold
																			  + ((stextlhold - stextup) >> 2)]._iMaxCharges;
	v1 = myplr;
	if ( v0 >= 0 )
		plr[myplr].InvList[v0]._iCharges = plr[myplr].InvList[v0]._iMaxCharges;
	else
		plr[myplr].InvBody[4]._iCharges = plr[myplr].InvBody[4]._iMaxCharges;
	CalcPlrInv(v1, 1u);
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045B634) --------------------------------------------------------
void __cdecl S_WRechargeEnter()
{
	int v0; // eax
	int v1; // edx
	int v2; // ecx
	bool v3; // sf
	unsigned char v4; // of
	char v5; // cl

	if ( stextsel == 22 )
	{
		StartStore(5);
		stextsel = 18;
	}
	else
	{
		stextlhold = stextsel;
		stextshold = 8;
		v0 = stextsval + ((stextsel - stextup) >> 2);
		v1 = myplr;
		stextvhold = stextsval;
		qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem));
		v2 = plr[v1]._pGold;
		v4 = __OFSUB__(v2, storehold[v0]._iIvalue);
		v3 = v2 - storehold[v0]._iIvalue < 0;
		v5 = 9;
		if ( !(v3 ^ v4) )
			v5 = 11;
		StartStore(v5);
	}
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045B6B5) --------------------------------------------------------
void __cdecl S_BoyEnter()
{
	signed int v0; // ecx

	v0 = boyitem._itype;
	if ( boyitem._itype != -1 && stextsel == 18 )
	{
		v0 = 50;
		if ( plr[myplr]._pGold >= 50 )
		{
			TakePlrsMoney(50);
			_LOBYTE(v0) = 13;
		}
		else
		{
			stextshold = 12;
			stextlhold = 18;
			stextvhold = stextsval;
			_LOBYTE(v0) = 9;
		}
		goto LABEL_5;
	}
	if ( stextsel == 8 && boyitem._itype != -1 || stextsel == 12 && boyitem._itype == -1 )
	{
		talker = 8;
		stextshold = 12;
		stextlhold = stextsel;
		gossipstart = 225;
		gossipend = 234;
		_LOBYTE(v0) = 19;
LABEL_5:
		StartStore(v0);
		return;
	}
	stextflag = 0;
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045B757) --------------------------------------------------------
void __cdecl BoyBuyItem()
{
	TakePlrsMoney(plr[myplr].HoldItem._iIvalue);
	StoreAutoPlace();
	boyitem._itype = -1;
	stextshold = 12;
	CalcPlrInv(myplr, 1u);
}

//----- (0045B791) --------------------------------------------------------
void __cdecl HealerBuyItem()
{
	int v0; // esi
	bool v1; // sf
	unsigned char v2; // of
	int v3; // eax
	int v4; // ecx
	bool v5; // sf
	unsigned char v6; // of
	int v7; // eax
	ItemStruct *v8; // edx
	ItemStruct *v9; // edi
	bool v10; // zf

	v0 = stextvhold + ((stextlhold - stextup) >> 2);
	if ( gbMaxPlayers == 1 )
	{
		v2 = __OFSUB__(v0, 2);
		v1 = v0 - 2 < 0;
	}
	else
	{
		v2 = __OFSUB__(v0, 3);
		v1 = v0 - 3 < 0;
	}
	if ( v1 ^ v2 )
	{
		v3 = GetRndSeed();
		v4 = myplr;
		plr[myplr].HoldItem._iSeed = v3;
	}
	else
	{
		v4 = myplr;
	}
	TakePlrsMoney(plr[v4].HoldItem._iIvalue);
	if ( !plr[myplr].HoldItem._iMagical )
		plr[myplr].HoldItem._iIdentified = 0;
	StoreAutoPlace();
	if ( gbMaxPlayers == 1 )
	{
		v6 = __OFSUB__(v0, 2);
		v5 = v0 - 2 < 0;
	}
	else
	{
		v6 = __OFSUB__(v0, 3);
		v5 = v0 - 3 < 0;
	}
	if ( !(v5 ^ v6) )
	{
		v7 = stextvhold + ((stextlhold - stextup) >> 2);
		if ( v7 == 19 )
		{
			healitem[19]._itype = -1;
		}
		else
		{
			if ( healitem[v7 + 1]._itype != -1 )
			{
				v8 = &healitem[v7];
				do
				{
					v9 = v8;
					++v8;
					++v7;
					v10 = v8[1]._itype == -1;
					qmemcpy(v9, v8, sizeof(ItemStruct));
				}
				while ( !v10 );
			}
			healitem[v7]._itype = -1;
		}
		CalcPlrInv(myplr, 1u);
	}
}
// 679660: using guessed type char gbMaxPlayers;
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045B895) --------------------------------------------------------
void __cdecl S_BBuyEnter()
{
	int v0; // ecx
	int v1; // eax
	int v2; // ecx
	int v3; // eax
	int v4; // esi

	if ( stextsel == 10 )
	{
		v0 = boyitem._iIvalue;
		stextvhold = stextsval;
		v1 = myplr;
		stextshold = 13;
		stextlhold = 10;
		if ( plr[myplr]._pGold >= boyitem._iIvalue + (boyitem._iIvalue >> 1) )
		{
			qmemcpy(&plr[v1].HoldItem, &boyitem, sizeof(plr[v1].HoldItem));
			plr[v1].HoldItem._iIvalue += plr[v1].HoldItem._iIvalue >> 1;
			SetCursor(plr[v1].HoldItem._iCurs + 12);
			v3 = 0;
			v4 = 0;
			do
			{
				if ( v3 )
					goto LABEL_8;
				v3 = AutoPlace(myplr, v4++, cursW / 28, cursH / 28, 0);
			}
			while ( v4 < 40 );
			if ( v3 )
			{
LABEL_8:
				_LOBYTE(v2) = 11;
				goto LABEL_10;
			}
			_LOBYTE(v2) = 10;
LABEL_10:
			StartStore(v2);
			SetCursor(1);
		}
		else
		{
			_LOBYTE(v0) = 9;
			StartStore(v0);
		}
	}
	else
	{
		stextflag = 0;
	}
}
// 4B8C9C: using guessed type int cursH;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;
// 6AA705: using guessed type char stextflag;

//----- (0045B968) --------------------------------------------------------
void __cdecl StoryIdItem()
{
	int v0; // ecx
	int v1; // eax
	int v2; // eax

	v0 = storehidx[((stextlhold - stextup) >> 2) + stextvhold];
	v1 = myplr;
	if ( v0 >= 0 )
	{
		plr[myplr].InvList[v0]._iIdentified = 1;
	}
	else
	{
		if ( v0 == -1 )
			plr[myplr].InvBody[0]._iIdentified = 1;
		if ( v0 == -2 )
			plr[v1].InvBody[6]._iIdentified = 1;
		if ( v0 == -3 )
			plr[v1].InvBody[4]._iIdentified = 1;
		if ( v0 == -4 )
			plr[v1].InvBody[5]._iIdentified = 1;
		if ( v0 == -5 )
			plr[v1].InvBody[1]._iIdentified = 1;
		if ( v0 == -6 )
			plr[v1].InvBody[2]._iIdentified = 1;
		if ( v0 == -7 )
			plr[v1].InvBody[3]._iIdentified = 1;
	}
	v2 = v1;
	plr[v2].HoldItem._iIdentified = 1;
	TakePlrsMoney(plr[v2].HoldItem._iIvalue);
	CalcPlrInv(myplr, 1u);
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;

//----- (0045BA57) --------------------------------------------------------
void __cdecl S_ConfirmEnter()
{
	char v0; // cl

	if ( stextsel == 18 )
	{
		if ( stextshold > STORE_WRECHARGE )
		{
			switch ( stextshold )
			{
				case STORE_BBOY:
					BoyBuyItem();
					break;
				case STORE_HBUY:
					HealerBuyItem();
					break;
				case STORE_SIDENTIFY:
					StoryIdItem();
					v0 = 20;
LABEL_20:
					StartStore(v0);
					return;
				case STORE_SPBUY:
					SmithBuyPItem();
					break;
			}
		}
		else
		{
			switch ( stextshold )
			{
				case STORE_WRECHARGE:
					WitchRechargeItem();
					break;
				case STORE_SBUY:
					SmithBuyItem();
					break;
				case STORE_SSELL:
					goto LABEL_27;
				case STORE_SREPAIR:
					SmithRepairItem();
					break;
				case STORE_WBUY:
					WitchBuyItem();
					break;
				case STORE_WSELL:
LABEL_27:
					StoreSellItem();
					break;
			}
		}
		v0 = stextshold;
		goto LABEL_20;
	}
	StartStore((unsigned char)stextshold);
	stextsel = stextlhold;
	stextsval = stextvhold;
}
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045BAF7) --------------------------------------------------------
void __cdecl S_HealerEnter()
{
	int v0; // ecx
	int v1; // eax

	v0 = 12;
	if ( stextsel == 12 )
	{
		stextlhold = 12;
		talker = 1;
		stextshold = 14;
		gossipstart = 170;
		gossipend = 178;
		_LOBYTE(v0) = 19;
		goto LABEL_12;
	}
	if ( stextsel != 14 )
	{
		if ( stextsel != 16 )
		{
			if ( stextsel == 18 )
				stextflag = 0;
			return;
		}
		_LOBYTE(v0) = 16;
LABEL_12:
		StartStore(v0);
		return;
	}
	if ( plr[myplr]._pHitPoints != plr[myplr]._pMaxHP )
		PlaySFX(IS_CAST8);
	drawhpflag = 1;
	v1 = myplr;
	plr[v1]._pHitPoints = plr[myplr]._pMaxHP;
	plr[v1]._pHPBase = plr[v1]._pMaxHPBase;
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045BB9F) --------------------------------------------------------
void __cdecl S_HBuyEnter()
{
	int v0; // eax
	int v1; // ecx
	int v2; // eax
	int v3; // esi
	char v4; // cl

	if ( stextsel == 22 )
	{
		StartStore(14);
		stextsel = 16;
	}
	else
	{
		stextlhold = stextsel;
		stextvhold = stextsval;
		stextshold = 16;
		v0 = myplr;
		v1 = stextsval + ((stextsel - stextup) >> 2);
		if ( plr[myplr]._pGold >= healitem[v1]._iIvalue )
		{
			qmemcpy(&plr[v0].HoldItem, &healitem[v1], sizeof(plr[v0].HoldItem));
			SetCursor(plr[v0].HoldItem._iCurs + 12);
			v2 = 0;
			v3 = 0;
			do
			{
				if ( v2 )
					goto LABEL_9;
				v2 = SpecialAutoPlace(myplr, v3++, cursW / 28, cursH / 28, 0);
			}
			while ( v3 < 40 );
			if ( v2 )
			{
LABEL_9:
				v4 = 11;
				goto LABEL_11;
			}
			v4 = 10;
LABEL_11:
			StartStore(v4);
			SetCursor(1);
		}
		else
		{
			StartStore(9);
		}
	}
}
// 4B8C9C: using guessed type int cursH;
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045BC74) --------------------------------------------------------
void __cdecl S_StoryEnter()
{
	int v0; // ecx

	v0 = 12;
	switch ( stextsel )
	{
		case 12:
			stextlhold = 12;
			talker = 4;
			stextshold = 15;
			gossipstart = 151;
			gossipend = 159;
			_LOBYTE(v0) = 19;
			goto LABEL_8;
		case 14:
			_LOBYTE(v0) = 17;
LABEL_8:
			StartStore(v0);
			return;
		case 18:
			stextflag = 0;
			break;
	}
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045BCCA) --------------------------------------------------------
void __cdecl S_SIDEnter()
{
	int v0; // eax
	int v1; // edx
	int v2; // ecx
	bool v3; // sf
	unsigned char v4; // of
	char v5; // cl

	if ( stextsel == 22 )
	{
		StartStore(15);
		stextsel = 14;
	}
	else
	{
		stextlhold = stextsel;
		stextshold = 17;
		v0 = stextsval + ((stextsel - stextup) >> 2);
		v1 = myplr;
		stextvhold = stextsval;
		qmemcpy(&plr[myplr].HoldItem, &storehold[v0], sizeof(plr[myplr].HoldItem));
		v2 = plr[v1]._pGold;
		v4 = __OFSUB__(v2, storehold[v0]._iIvalue);
		v3 = v2 - storehold[v0]._iIvalue < 0;
		v5 = 9;
		if ( !(v3 ^ v4) )
			v5 = 11;
		StartStore(v5);
	}
}
// 69F108: using guessed type int stextup;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;

//----- (0045BD4B) --------------------------------------------------------
void __cdecl S_TalkEnter()
{
	int v0; // edx
	int *v1; // edi
	signed int v2; // eax
	int v3; // esi
	int *v4; // ecx
	int v5; // esi
	signed int v6; // ebp
	int v7; // ecx
	int v8; // eax
	int v9; // ebx
	int v10; // ecx

	if ( stextsel == 22 )
	{
		StartStore((unsigned char)stextshold);
		stextsel = stextlhold;
	}
	else
	{
		v0 = talker;
		v1 = &quests[0]._qlog;
		v2 = 0;
		v3 = 0;
		v4 = &quests[0]._qlog;
		do
		{
			if ( *((_BYTE *)v4 - 18) == 2 && *((_DWORD *)&Qtalklist[0]._qinfra + v3 + 16 * talker) != -1 && *v4 )
				++v2;
			v4 += 6;
			++v3;
		}
		while ( (signed int)v4 < (signed int)&qlist[4] );
		if ( v2 <= 6 )
		{
			v5 = 15 - v2;
			v6 = 2;
		}
		else
		{
			v5 = 14 - (v2 >> 1);
			v6 = 1;
		}
		if ( stextsel == v5 - 2 )
		{
			SetRndSeed(towner[talker]._tSeed);
			_LOBYTE(v7) = 0;
			v8 = random(v7, gossipend - gossipstart + 1);
			InitQTextMsg(gossipstart + v8);
		}
		else
		{
			v9 = 0;
			do
			{
				if ( *((_BYTE *)v1 - 18) == 2 )
				{
					v10 = *((_DWORD *)&Qtalklist[0]._qinfra + v9 + 16 * v0);
					if ( v10 != -1 )
					{
						if ( *v1 )
						{
							if ( v5 == stextsel )
							{
								InitQTextMsg(v10);
								v0 = talker;
							}
							v5 += v6;
						}
					}
				}
				v1 += 6;
				++v9;
			}
			while ( (signed int)v1 < (signed int)&qlist[4] );
		}
	}
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;

//----- (0045BE4A) --------------------------------------------------------
void __cdecl S_TavernEnter()
{
	int v0; // ecx

	v0 = 12;
	if ( stextsel == 12 )
	{
		stextlhold = 12;
		talker = 3;
		stextshold = 21;
		gossipstart = 161;
		gossipend = 168;
		_LOBYTE(v0) = 19;
		StartStore(v0);
	}
	else if ( stextsel == 18 )
	{
		stextflag = 0;
	}
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045BE98) --------------------------------------------------------
void __cdecl S_BarmaidEnter()
{
	int v0; // ecx

	v0 = 12;
	if ( stextsel == 12 )
	{
		stextlhold = 12;
		talker = 7;
		stextshold = 23;
		gossipstart = 180;
		gossipend = 187;
		_LOBYTE(v0) = 19;
		StartStore(v0);
	}
	else if ( stextsel == 18 )
	{
		stextflag = 0;
	}
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045BEE6) --------------------------------------------------------
void __cdecl S_DrunkEnter()
{
	int v0; // ecx

	v0 = 12;
	if ( stextsel == 12 )
	{
		stextlhold = 12;
		talker = 5;
		stextshold = 22;
		gossipstart = 201;
		gossipend = 211;
		_LOBYTE(v0) = 19;
		StartStore(v0);
	}
	else if ( stextsel == 18 )
	{
		stextflag = 0;
	}
}
// 69F110: using guessed type int stextlhold;
// 69FB38: using guessed type int talker;
// 6A4EF0: using guessed type int gossipstart;
// 6A8A28: using guessed type int stextsel;
// 6A8A30: using guessed type int gossipend;
// 6AA705: using guessed type char stextflag;

//----- (0045BF34) --------------------------------------------------------
void __cdecl STextEnter()
{
	int v0; // ecx

	if ( qtextflag )
	{
		qtextflag = 0;
		if ( !leveltype )
			sfx_stop();
	}
	else
	{
		PlaySFX(IS_TITLSLCT);
		switch ( stextflag )
		{
			case STORE_SMITH:
				S_SmithEnter();
				break;
			case STORE_SBUY:
				S_SBuyEnter();
				break;
			case STORE_SSELL:
				S_SSellEnter();
				break;
			case STORE_SREPAIR:
				S_SRepairEnter();
				break;
			case STORE_WITCH:
				S_WitchEnter();
				break;
			case STORE_WBUY:
				S_WBuyEnter();
				break;
			case STORE_WSELL:
				S_WSellEnter();
				break;
			case STORE_WRECHARGE:
				S_WRechargeEnter();
				break;
			case STORE_NOMONEY:
			case STORE_NOROOM:
				_LOBYTE(v0) = stextshold;
				StartStore(v0);
				stextsel = stextlhold;
				stextsval = stextvhold;
				break;
			case STORE_CONFIRM:
				S_ConfirmEnter();
				break;
			case STORE_BOY:
				S_BoyEnter();
				break;
			case STORE_BBOY:
				S_BBuyEnter();
				break;
			case STORE_HEALER:
				S_HealerEnter();
				break;
			case STORE_STORY:
				S_StoryEnter();
				break;
			case STORE_HBUY:
				S_HBuyEnter();
				break;
			case STORE_SIDENTIFY:
				S_SIDEnter();
				break;
			case STORE_SPBUY:
				S_SPBuyEnter();
				break;
			case STORE_GOSSIP:
				S_TalkEnter();
				break;
			case STORE_IDSHOW:
				_LOBYTE(v0) = 17;
				StartStore(v0);
				break;
			case STORE_TAVERN:
				S_TavernEnter();
				break;
			case STORE_DRUNK:
				S_DrunkEnter();
				break;
			case STORE_BARMAID:
				S_BarmaidEnter();
				break;
			default:
				return;
		}
	}
}
// 5BB1ED: using guessed type char leveltype;
// 646D00: using guessed type char qtextflag;
// 69F110: using guessed type int stextlhold;
// 6A8A24: using guessed type int stextvhold;
// 6A8A28: using guessed type int stextsel;
// 6AA705: using guessed type char stextflag;

//----- (0045C053) --------------------------------------------------------
void __cdecl CheckStoreBtn()
{
	bool v0; // sf
	unsigned char v1; // of
	int v2; // eax
	int *v3; // ecx

	if ( qtextflag )
	{
		qtextflag = 0;
		if ( !leveltype )
			sfx_stop();
	}
	else if ( stextsel != -1 && MouseY >= 32 && MouseY <= 320 )
	{
		if ( stextsize )
		{
			v1 = __OFSUB__(MouseX, 24);
			v0 = MouseX - 24 < 0;
		}
		else
		{
			v1 = __OFSUB__(MouseX, 344);
			v0 = MouseX - 344 < 0;
		}
		if ( !(v0 ^ v1) && MouseX <= 616 )
		{
			v2 = (MouseY - 32) / 12;
			if ( stextscrl && MouseX > 600 )
			{
				if ( v2 == 4 )
				{
					if ( stextscrlubtn <= 0 )
					{
						STextUp();
						stextscrlubtn = 10;
						return;
					}
					--stextscrlubtn;
				}
				if ( v2 == 20 )
				{
					if ( stextscrldbtn > 0 )
					{
						--stextscrldbtn;
					}
					else
					{
						STextDown();
						stextscrldbtn = 10;
					}
				}
			}
			else if ( v2 >= 5 )
			{
				if ( v2 >= 23 )
					v2 = 22;
				if ( stextscrl )
				{
					if ( v2 < 21 )
					{
						v3 = &stext[v2]._ssel;
						if ( !*v3 )
						{
							if ( stext[v2 - 2]._ssel )
							{
								v2 -= 2;
							}
							else if ( *(v3 - 39) )
							{
								--v2;
							}
						}
					}
				}
				if ( stext[v2]._ssel || stextscrl && v2 == 22 )
				{
					stextsel = v2;
					STextEnter();
				}
			}
		}
	}
}
// 5BB1ED: using guessed type char leveltype;
// 646D00: using guessed type char qtextflag;
// 6A09E0: using guessed type char stextsize;
// 6A6BB8: using guessed type int stextscrl;
// 6A8A28: using guessed type int stextsel;
// 6A8A2C: using guessed type char stextscrldbtn;
// 6AA704: using guessed type char stextscrlubtn;

//----- (0045C18A) --------------------------------------------------------
void __cdecl ReleaseStoreBtn()
{
	stextscrlubtn = -1;
	stextscrldbtn = -1;
}
// 6A8A2C: using guessed type char stextscrldbtn;
// 6AA704: using guessed type char stextscrlubtn;

//----- (0045C199) --------------------------------------------------------
int __fastcall sync_all_monsters(TSyncHeader *packet, int size)
{
	int result; // eax
	TSyncHeader *v3; // esi
	int v4; // ebx
	TSyncMonster *v5; // edi
	unsigned int v6; // [esp+4h] [ebp-4h]

	result = size;
	if ( nummonsters >= 1 && (unsigned int)size >= 0x2B )
	{
		v3 = packet;
		v6 = size - 38;
		v4 = 0;
		packet->bCmd = CMD_SYNCDATA;
		v5 = (TSyncMonster *)(&packet->wPInvCI + 1);
		packet->bLevel = currlevel;
		packet->wLen = 0;
		SyncPlrInv(packet);
		sync_one_monster();
		if ( nummonsters > 0 )
		{
			do
			{
				if ( v6 < 5 || (v4 >= 2 || !sync_monster_active2(v5)) && !sync_monster_active(v5) )
					break;
				v3->wLen += 5;
				v6 -= 5;
				++v5;
				++v4;
			}
			while ( v4 < nummonsters );
		}
		result = v6;
	}
	return result;
}

//----- (0045C21E) --------------------------------------------------------
void __cdecl sync_one_monster()
{
	int i; // ebx
	int v1; // edi
	int v2; // esi
	short v3; // bp
	short v4; // ax
	bool v5; // zf
	short *v6; // edx
	short *v7; // eax

	for ( i = 0; i < nummonsters; ++i )
	{
		v1 = monstactive[i];
		v2 = monstactive[i];
		v3 = abs(plr[myplr].WorldY - monster[v2]._my);
		v4 = abs(plr[myplr].WorldX - monster[v2]._mx);
		v5 = _LOBYTE(monster[v2]._msquelch) == 0;
		v6 = &sync_word_6AA708[v1];
		*v6 = v4 + v3;
		if ( v5 )
		{
			*v6 = v4 + v3 + 4096;
		}
		else
		{
			v7 = &sync_word_6AA89C[v1];
			if ( *v7 )
				--*v7;
		}
	}
}

//----- (0045C2C4) --------------------------------------------------------
int __fastcall sync_monster_active(TSyncMonster *packet)
{
	unsigned int v1; // ebx
	int v2; // esi
	int v3; // edx
	int v4; // eax

	v1 = -1;
	v2 = 0;
	v3 = -1;
	if ( nummonsters <= 0 )
		return 0;
	do
	{
		v4 = monstactive[v2];
		if ( (unsigned short)sync_word_6AA708[v4] < v1 && (unsigned short)sync_word_6AA89C[v4] < 0xFFFEu )
		{
			v1 = (unsigned short)sync_word_6AA708[v4];
			v3 = monstactive[v2];
		}
		++v2;
	}
	while ( v2 < nummonsters );
	if ( v3 == -1 )
		return 0;
	sync_monster_pos(packet, v3);
	return 1;
}

//----- (0045C317) --------------------------------------------------------
int __fastcall sync_monster_pos(TSyncMonster *packet, int mon_id)
{
	int v2; // ebx
	TSyncMonster *v3; // esi
	int v4; // edi
	int result; // eax
	short v6; // cx
	char v7; // cl
	int v8; // [esp+0h] [ebp-Ch]

	v2 = mon_id;
	v3 = packet;
	v4 = mon_id;
	packet->_mndx = mon_id;
	packet->_mx = monster[mon_id]._mx;
	packet->_my = monster[mon_id]._my;
	packet->_menemy = encode_enemy(v8);
	result = v2;
	v6 = sync_word_6AA708[v2];
	if ( (unsigned short)v6 > 0xFFu )
		_LOBYTE(v6) = -1;
	v3->_mdelta = v6;
	v7 = monster[v4]._msquelch;
	sync_word_6AA708[result] = -1;
	sync_word_6AA89C[result] = -(v7 != 0) - 1;
	return result * 2;
}

//----- (0045C386) --------------------------------------------------------
int __fastcall sync_monster_active2(TSyncMonster *packet)
{
	int v1; // edx
	unsigned int v2; // ebp
	int v3; // eax
	int v4; // esi
	int v6; // [esp+8h] [ebp-4h]

	v1 = -1;
	v2 = 65534;
	if ( nummonsters <= 0 )
		return 0;
	v3 = dword_6AA898;
	v6 = nummonsters;
	do
	{
		if ( v3 >= nummonsters )
			v3 = 0;
		v4 = monstactive[v3];
		if ( (unsigned short)sync_word_6AA89C[v4] < v2 )
		{
			v2 = (unsigned short)sync_word_6AA89C[v4];
			v1 = monstactive[v3];
		}
		++v3;
		--v6;
	}
	while ( v6 );
	dword_6AA898 = v3;
	if ( v1 == -1 )
		return 0;
	sync_monster_pos(packet, v1);
	return 1;
}
// 6AA898: using guessed type int dword_6AA898;

//----- (0045C3E6) --------------------------------------------------------
char __fastcall SyncPlrInv(TSyncHeader *pItem)
{
	int v1; // edx
	int v2; // eax
	int v3; // eax
	short v4; // dx
	short v5; // bx
	ItemStruct *v6; // eax

	if ( numitems <= 0 )
	{
		pItem->bItemI = -1;
	}
	else
	{
		v1 = dword_6AAA2C[0];
		if ( dword_6AAA2C[0] >= numitems )
			v1 = 0;
		v2 = itemactive[v1];
		dword_6AAA2C[0] = v1 + 1;
		pItem->bItemI = v2;
		v3 = v2;
		pItem->bItemX = items[v3]._ix;
		pItem->bItemY = items[v3]._iy;
		*(_WORD *)(&pItem->bItemY + 1) = items[v3].IDidx;
		if ( items[v3].IDidx == IDI_EAR )
		{
			_LOBYTE(v4) = 0;
			_HIBYTE(v4) = items[v3]._iName[7];
			_LOBYTE(v5) = 0;
			*(unsigned short *)((char *)&pItem->wItemIndx + 1) = items[v3]._iName[8] | v4;
			*(_DWORD *)((char *)&pItem->wItemCI + 1) = items[v3]._iName[12] | ((items[v3]._iName[11] | ((items[v3]._iName[10] | (items[v3]._iName[9] << 8)) << 8)) << 8);
			BYTE1(pItem->dwItemSeed) = items[v3]._iName[13];
			BYTE2(pItem->dwItemSeed) = items[v3]._iName[14];
			_HIBYTE(pItem->dwItemSeed) = items[v3]._iName[15];
			pItem->bItemId = items[v3]._iName[16];
			pItem->bItemDur = items[v3]._iName[17];
			_HIBYTE(v5) = items[v3]._iName[18];
			*(_WORD *)&pItem->bItemMDur = _LOWORD(items[v3]._ivalue) | v5 | ((_LOWORD(items[v3]._iCurs) - 19) << 6);
			*(_DWORD *)&pItem->bItemMCh = items[v3]._iName[22] | ((items[v3]._iName[21] | ((items[v3]._iName[20] | (items[v3]._iName[19] << 8)) << 8)) << 8);
		}
		else
		{
			*(unsigned short *)((char *)&pItem->wItemIndx + 1) = items[v3]._iCreateInfo;
			*(_DWORD *)((char *)&pItem->wItemCI + 1) = items[v3]._iSeed;
			BYTE1(pItem->dwItemSeed) = items[v3]._iIdentified;
			BYTE2(pItem->dwItemSeed) = items[v3]._iDurability;
			_HIBYTE(pItem->dwItemSeed) = items[v3]._iMaxDur;
			pItem->bItemId = items[v3]._iCharges;
			pItem->bItemDur = items[v3]._iMaxCharges;
			if ( !items[v3].IDidx )
				*(_WORD *)&pItem->bItemMDur = items[v3]._ivalue;
		}
	}
	v6 = &plr[myplr].InvBody[sgnSyncPInv];
	if ( v6->_itype == -1 )
	{
		_LOBYTE(pItem->dwItemBuff) = -1;
	}
	else
	{
		_LOBYTE(pItem->dwItemBuff) = sgnSyncPInv;
		*(_WORD *)((char *)&pItem->dwItemBuff + 1) = v6->IDidx;
		*(_WORD *)((char *)&pItem->dwItemBuff + 3) = v6->_iCreateInfo;
		*(_DWORD *)(&pItem->bPInvLoc + 1) = v6->_iSeed;
		_LOBYTE(v6) = v6->_iIdentified;
		_HIBYTE(pItem->wPInvCI) = (_BYTE)v6;
	}
	if ( ++sgnSyncPInv >= 7 )
		sgnSyncPInv = 0;
	return (char)v6;
}
// 6AAA34: using guessed type int sgnSyncPInv;

//----- (0045C5C7) --------------------------------------------------------
int __fastcall SyncData(int pnum, TSyncHeader *packet)
{
	TSyncHeader *v2; // esi
	TSyncMonster *v3; // edi
	int v4; // ebp
	unsigned short v5; // ax
	unsigned int v6; // ebx

	v2 = packet;
	v3 = (TSyncMonster *)(&packet->wPInvCI + 1);
	v4 = pnum;
	if ( packet->bCmd != CMD_SYNCDATA )
		TermMsg("bad sync command");
	if ( gbBufferMsgs != 1 && v4 != myplr )
	{
		v5 = v2->wLen;
		if ( v5 >= 5u )
		{
			v6 = v5 / 5u;
			do
			{
				if ( currlevel == v2->bLevel )
					sync_monster_data(v4, v3);
				delta_sync_monster((TCmdLocParam1 *)v3, v2->bLevel);
				++v3;
				--v6;
			}
			while ( v6 );
		}
	}
	return v2->wLen + 38;
}
// 676194: using guessed type char gbBufferMsgs;

//----- (0045C63B) --------------------------------------------------------
void __fastcall sync_monster_data(int pnum, TSyncMonster *packet)
{
	TSyncMonster *v2; // edi
	int v3; // ecx
	int v4; // ebx
	int v5; // esi
	int v6; // ST18_4
	unsigned int v7; // ecx
	unsigned int v8; // eax
	int v9; // eax
	int v10; // ecx
	signed int v11; // ST14_4
	int v12; // eax
	int v13; // eax
	int v14; // eax
	int v15; // eax
	int v16; // eax
	int md; // [esp+Ch] [ebp-8h]
	int mda; // [esp+Ch] [ebp-8h]

	v2 = packet;
	md = pnum;
	v3 = 0;
	v4 = (unsigned char)packet->_mndx;
	v5 = v4;
	if ( monster[v5]._mhitpoints )
	{
		if ( nummonsters > 0 )
		{
			do
			{
				if ( monstactive[v3] == v4 )
					break;
				++v3;
			}
			while ( v3 < nummonsters );
		}
		v6 = abs(plr[myplr].WorldY - monster[v5]._my);
		v7 = abs(plr[myplr].WorldX - monster[v5]._mx) + v6;
		if ( v7 > 0xFF )
			v7 = 255;
		v8 = (unsigned char)v2->_mdelta;
		if ( v7 >= v8 && (v7 != v8 || md <= myplr) )
		{
			v9 = (unsigned char)v2->_mx;
			if ( monster[v5]._mfutx != v9 || monster[v5]._mfuty != (unsigned char)v2->_my )
			{
				v10 = monster[v5]._mmode;
				if ( v10 != MM_CHARGE && v10 != MM_STONE )
				{
					v11 = abs(monster[v5]._mx - v9);
					v12 = abs(monster[v5]._my - (unsigned char)v2->_my);
					if ( v11 > 2 || v12 > 2 )
					{
						if ( dMonster[0][(unsigned char)v2->_my + 112 * (unsigned char)v2->_mx] )
						{
LABEL_23:
							decode_enemy(v4, (unsigned char)v2->_menemy);
							return;
						}
						M_ClearSquares(v4);
						dMonster[0][(unsigned char)v2->_my + 112 * (unsigned char)v2->_mx] = v4 + 1;
						monster[v5]._mx = (unsigned char)v2->_mx;
						monster[v5]._my = (unsigned char)v2->_my;
						decode_enemy(v4, (unsigned char)v2->_menemy);
						v16 = GetDirection(
								  (unsigned char)v2->_mx,
								  (unsigned char)v2->_my,
								  (unsigned char)monster[v5]._menemyx,
								  (unsigned char)monster[v5]._menemyy);
						M_StartStand(v4, v16);
					}
					else
					{
						v13 = monster[v5]._mmode;
						if ( v13 >= MM_WALK && v13 <= MM_WALK3 )
							goto LABEL_23;
						v14 = GetDirection(
								  monster[v5]._mx,
								  monster[v5]._my,
								  (unsigned char)v2->_mx,
								  (unsigned char)v2->_my);
						mda = v14;
						_LOBYTE(v15) = DirOK(v4, v14);
						if ( !v15 )
							goto LABEL_23;
						M_ClearSquares(v4);
						dMonster[0][monster[v5]._my + 112 * monster[v5]._mx] = v4 + 1;
						M_WalkDir(v4, mda);
					}
					_LOBYTE(monster[v5]._msquelch) = -1;
					goto LABEL_23;
				}
			}
		}
	}
}

//----- (0045C84B) --------------------------------------------------------
void __cdecl sync_clear_pkt()
{
	dword_6AA898 = 16 * myplr;
	memset(sync_word_6AA89C, 255, 0x190u);
}
// 6AA898: using guessed type int dword_6AA898;

//----- (0045C870) --------------------------------------------------------
unsigned char __fastcall TFit_Shrine(int i)
{
	int v1; // ecx
	int v2; // esi
	int v3; // eax
	int v4; // edx
	signed int v6; // [esp+Ch] [ebp-8h]
	int v7; // [esp+10h] [ebp-4h]

	v1 = themes[i].ttval;
	v7 = 0;
	v2 = 0;
	v6 = 0;
	while ( 1 )
	{
		v3 = v2 + 112 * v7;
		if ( dung_map[0][v3] != v1 )
			goto LABEL_20;
		v4 = *(_DWORD *)&dflags[39][4 * v3 + 36];
		if ( nTrapTable[v4]
		  && !nSolidTable[*(_DWORD *)&dflags[28][4 * v3 + 32]]
		  && !nSolidTable[dPiece[1][v3]]
		  && block_lvid[v3 + 1940] == v1
		  && dung_map[1][v3] == v1
		  && !dungeon[37][v3 + 7]
		  && !dObject[0][v3 + 111] )
		{
			v6 = 1;
		}
		if ( v6 )
			break;
		if ( !nTrapTable[*(_DWORD *)&dflags[28][4 * v3 + 32]]
		  || nSolidTable[v4]
		  || nSolidTable[dPiece[0][v3 + 1]]
		  || *(&byte_5B78EB + v3) != v1
		  || dung_map[0][v3 + 1] != v1
		  || dungeon[37][v3 + 7]
		  || dungeon[37][v3 + 9] )
		{
			goto LABEL_21;
		}
		v6 = 2;
LABEL_20:
		if ( v6 )
			break;
LABEL_21:
		if ( ++v7 == 112 )
		{
			++v2;
			v7 = 0;
			if ( v2 == 112 )
				return 0;
		}
	}
	themey = v2;
	themex = v7;
	themeVar1 = v6;
	return 1;
}

//----- (0045C993) --------------------------------------------------------
bool __fastcall TFit_Obj5(int theme_num)
{
	int v1; // edi
	int v2; // ebx
	int v3; // esi
	int v4; // eax
	int v5; // edi
	int v6; // ecx
	signed int v7; // edx
	int v8; // ecx
	int v10; // [esp+Ch] [ebp-Ch]
	int v11; // [esp+10h] [ebp-8h]
	signed int v12; // [esp+14h] [ebp-4h]

	v1 = theme_num;
	_LOBYTE(theme_num) = 0;
	v2 = 0;
	v3 = 0;
	v4 = random(theme_num, 5) + 1;
	v10 = v4;
	if ( v4 <= 0 )
	{
LABEL_19:
		themex = v2;
		themey = v3;
		return 1;
	}
	v5 = themes[v1].ttval;
	v11 = v5;
	while ( 1 )
	{
		v6 = v3 + 112 * v2;
		if ( dung_map[0][v6] == v5 && !nSolidTable[dPiece[0][v6]] )
		{
			v12 = 1;
			v7 = 0;
			do
			{
				if ( v7 >= 25 )
					break;
				v8 = v3 + trm5y[v7] + 112 * (v2 + trm5x[v7]);
				if ( nSolidTable[dPiece[0][v8]] )
					v12 = 0;
				v5 = v11;
				if ( dung_map[0][v8] != v11 )
					v12 = 0;
				++v7;
			}
			while ( v12 );
			if ( v12 )
			{
				--v4;
				goto LABEL_18;
			}
		}
		if ( ++v2 != 112 )
			goto LABEL_18;
		v2 = 0;
		if ( ++v3 != 112 )
			goto LABEL_18;
		if ( v4 == v10 )
			return 0;
		v3 = 0;
LABEL_18:
		if ( v4 <= 0 )
			goto LABEL_19;
	}
}

//----- (0045CA72) --------------------------------------------------------
unsigned char __fastcall TFit_SkelRoom(int i)
{
	int v1; // ebx
	int v2; // esi
	CMonster *v3; // edi

	v1 = i;
	if ( leveltype != 1 && leveltype != 2 )
		return 0;
	v2 = 0;
	if ( nummtypes <= 0 )
		return 0;
	v3 = Monsters;
	while ( !IsSkel((unsigned char)v3->mtype) )
	{
		++v2;
		++v3;
		if ( v2 >= nummtypes )
			return 0;
	}
	themeVar1 = v2;
	return TFit_Obj5(v1);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045CAC4) --------------------------------------------------------
unsigned char __fastcall TFit_GoatShrine(int i)
{
	int v1; // esi
	int v2; // ebx
	CMonster *v3; // edi

	v1 = 0;
	v2 = i;
	if ( nummtypes <= 0 )
		return 0;
	v3 = Monsters;
	while ( !IsGoat((unsigned char)v3->mtype) )
	{
		++v1;
		++v3;
		if ( v1 >= nummtypes )
			return 0;
	}
	themeVar1 = v1;
	return TFit_Obj5(v2);
}

//----- (0045CB09) --------------------------------------------------------
unsigned char __fastcall CheckThemeObj3(int xp, int yp, int t, int f)
{
	int v4; // esi
	int v5; // ebx
	signed int v6; // edi
	int v7; // eax
	int v8; // ecx
	int v9; // eax
	int v10; // ecx

	v4 = yp;
	v5 = xp;
	v6 = 0;
	while ( 1 )
	{
		v7 = v5 + trm3x[v6];
		if ( v7 < 0 )
			break;
		v8 = trm3y[v6];
		if ( v8 + v4 < 0 )
			break;
		v9 = v4 + v8 + 112 * v7;
		if ( nSolidTable[dPiece[0][v9]] )
			break;
		v10 = dung_map[0][v9];
		if ( v10 != themes[t].ttval )
			break;
		if ( dObject[0][v9] )
			break;
		if ( f != -1 )
		{
			_LOBYTE(v10) = 0;
			if ( !random(v10, f) )
				break;
		}
		++v6;
		if ( v6 >= 9 )
			return 1;
	}
	return 0;
}

//----- (0045CB88) --------------------------------------------------------
bool __fastcall TFit_Obj3(int theme_num)
{
	int v1; // ebx
	int v2; // edi
	int v3; // esi
	BOOL v4; // eax
	char v6; // [esp+Bh] [ebp-5h]
	char v7; // [esp+Ch] [ebp-4h]
	char v8; // [esp+Dh] [ebp-3h]
	char v9; // [esp+Eh] [ebp-2h]
	char v10; // [esp+Fh] [ebp-1h]

	v1 = theme_num;
	v7 = 4;
	v8 = 4;
	v9 = 3;
	v10 = 5;
	v2 = 1;
	while ( 2 )
	{
		v3 = 1;
		do
		{
			_LOBYTE(v4) = CheckThemeObj3(v3, v2, v1, *(&v6 + (unsigned char)leveltype));
			if ( v4 )
			{
				themex = v3;
				themey = v2;
				_LOBYTE(v4) = 1;
				return v4;
			}
			++v3;
		}
		while ( v3 < 111 );
		if ( ++v2 < 111 )
			continue;
		break;
	}
	return v4;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045CBE4) --------------------------------------------------------
unsigned char __fastcall CheckThemeReqs(int t)
{
	unsigned char result; // al
	int v2; // ecx
	int v3; // ecx
	int v4; // ecx
	int v5; // ecx
	bool v6; // zf
	int v7; // ecx
	int v8; // ecx
	int v9; // ecx

	result = 1;
	if ( t <= 10 )
	{
		if ( t != 10 )
		{
			v2 = t - 1;
			if ( v2 )
			{
				v3 = v2 - 2;
				if ( v3 )
				{
					v4 = v3 - 2;
					if ( v4 )
					{
						v5 = v4 - 2;
						if ( v5 )
						{
							if ( v5 != 2 )
								return result;
							v6 = pFountainFlag == 0;
						}
						else
						{
							v6 = bFountainFlag == 0;
						}
LABEL_21:
						if ( !v6 )
							return result;
						return 0;
					}
				}
			}
			if ( leveltype != 3 )
			{
				v6 = leveltype == 4;
				goto LABEL_21;
			}
			return 0;
		}
LABEL_16:
		v6 = leveltype == 1;
		goto LABEL_21;
	}
	v7 = t - 12;
	if ( v7 )
	{
		v8 = v7 - 1;
		if ( !v8 )
		{
			v6 = mFountainFlag == 0;
			goto LABEL_21;
		}
		v9 = v8 - 1;
		if ( !v9 )
		{
			v6 = tFountainFlag == 0;
			goto LABEL_21;
		}
		if ( v9 != 2 )
			return result;
		goto LABEL_16;
	}
	if ( leveltype == 4 )
	{
		v6 = cauldronFlag == 0;
		goto LABEL_21;
	}
	return 0;
}
// 5BB1ED: using guessed type char leveltype;
// 6AAA58: using guessed type int mFountainFlag;
// 6AAA5C: using guessed type int cauldronFlag;
// 6AAA60: using guessed type int tFountainFlag;
// 6AAC08: using guessed type int pFountainFlag;
// 6AAC0C: using guessed type int bFountainFlag;

//----- (0045CC64) --------------------------------------------------------
unsigned char __fastcall SpecialThemeFit(int i, int t)
{
	int v2; // edi
	int v3; // esi
	int v4; // eax

	v2 = t;
	v3 = i;
	_LOBYTE(v4) = CheckThemeReqs(t);
	switch ( v2 )
	{
		case THEME_SHRINE:
		case THEME_LIBRARY:
			if ( v4 )
				_LOBYTE(v4) = TFit_Shrine(v3);
			break;
		case THEME_SKELROOM:
			if ( v4 )
				_LOBYTE(v4) = TFit_SkelRoom(v3);
			break;
		case THEME_TREASURE:
			_LOBYTE(v4) = treasureFlag;
			if ( treasureFlag )
				treasureFlag = 0;
			break;
		case THEME_TORTURE:
		case THEME_DECAPITATED:
		case THEME_ARMORSTAND:
		case THEME_BRNCROSS:
		case THEME_WEAPONRACK:
			if ( v4 )
				_LOBYTE(v4) = TFit_Obj3(v3);
			break;
		case THEME_BLOODFOUNTAIN:
			if ( v4 )
			{
				_LOBYTE(v4) = TFit_Obj5(v3);
				if ( v4 )
					bFountainFlag = 0;
			}
			break;
		case THEME_PURIFYINGFOUNTAIN:
			if ( v4 )
			{
				_LOBYTE(v4) = TFit_Obj5(v3);
				if ( v4 )
					pFountainFlag = 0;
			}
			break;
		case THEME_GOATSHRINE:
			if ( v4 )
				_LOBYTE(v4) = TFit_GoatShrine(v3);
			break;
		case THEME_CAULDRON:
			if ( v4 )
			{
				_LOBYTE(v4) = TFit_Obj5(v3);
				if ( v4 )
					cauldronFlag = 0;
			}
			break;
		case THEME_MURKYFOUNTAIN:
			if ( v4 )
			{
				_LOBYTE(v4) = TFit_Obj5(v3);
				if ( v4 )
					mFountainFlag = 0;
			}
			break;
		case THEME_TEARFOUNTAIN:
			if ( v4 )
			{
				_LOBYTE(v4) = TFit_Obj5(v3);
				if ( v4 )
					tFountainFlag = 0;
			}
			break;
		default:
			return v4;
	}
	return v4;
}
// 6AAA54: using guessed type int treasureFlag;
// 6AAA58: using guessed type int mFountainFlag;
// 6AAA5C: using guessed type int cauldronFlag;
// 6AAA60: using guessed type int tFountainFlag;
// 6AAC08: using guessed type int pFountainFlag;
// 6AAC0C: using guessed type int bFountainFlag;

//----- (0045CD9A) --------------------------------------------------------
unsigned char __fastcall CheckThemeRoom(int tv)
{
	int v1; // esi
	int *v2; // edx
	signed int v3; // edi
	signed int v4; // esi
	signed int v5; // edx
	signed int v6; // eax
	int v7; // edi
	int *v8; // esi
	char *v9; // eax
	int *v10; // edx
	signed int v12; // [esp+Ch] [ebp-8h]

	v1 = 0;
	if ( trigflag[4] <= 0 )
	{
LABEL_5:
		v3 = 0;
		v4 = 0;
		do
		{
			v5 = 0;
			v6 = v4;
			do
			{
				if ( dung_map[0][v6] == tv )
				{
					if ( dFlags[0][v6] & 8 )
						return 0;
					++v3;
				}
				++v5;
				v6 += 112;
			}
			while ( v5 < 112 );
			++v4;
		}
		while ( v4 < 112 );
		if ( leveltype != 1 || v3 >= 9 && v3 <= 100 )
		{
			v7 = 0;
			v8 = &dPiece[-1][111];
LABEL_16:
			v12 = 0;
			v9 = &dung_map[-1][v7 + 111];
			v10 = v8;
			while ( v9[1] != tv
				 || nSolidTable[v10[1]]
				 || (*(v9 - 111) == tv || nSolidTable[*(v10 - 111)])
				 && (v9[113] == tv || nSolidTable[v10[113]])
				 && (*v9 == tv || nSolidTable[*v10])
				 && (v9[2] == tv || nSolidTable[v10[2]]) )
			{
				++v12;
				v10 += 112;
				v9 += 112;
				if ( v12 >= 112 )
				{
					++v8;
					++v7;
					if ( (signed int)v8 < (signed int)&dPiece[0][111] )
						goto LABEL_16;
					return 1;
				}
			}
		}
	}
	else
	{
		v2 = &trigs[0]._ty;
		while ( dung_map[*(v2 - 1)][*v2] != tv )
		{
			++v1;
			v2 += 4;
			if ( v1 >= trigflag[4] )
				goto LABEL_5;
		}
	}
	return 0;
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045CED2) --------------------------------------------------------
void __cdecl InitThemes()
{
	int v0; // esi
	char v1; // bl
	int v2; // edi
	int v3; // eax
	int v4; // ecx
	int i; // ebx
	int v6; // eax
	int v7; // ecx
	int v8; // esi
	int v9; // ecx
	int j; // eax
	int v11; // eax
	int v12; // ecx
	int *v13; // edi
	int v14; // esi
	int *v15; // ebx
	int v16; // eax
	int v17; // eax
	int k; // esi
	int l; // ebx
	int v20; // eax

	zharlib = -1;
	v0 = 0;
	bCrossFlag = 0;
	numthemes = 0;
	armorFlag = 1;
	bFountainFlag = 1;
	cauldronFlag = 1;
	mFountainFlag = 1;
	pFountainFlag = 1;
	tFountainFlag = 1;
	treasureFlag = 1;
	weaponFlag = 1;
	if ( currlevel != 16 )
	{
		v1 = leveltype;
		if ( leveltype == 1 )
		{
			ThemeGoodIn[0] = 0;
			ThemeGoodIn[1] = 0;
			ThemeGoodIn[2] = 0;
			ThemeGoodIn[3] = 0;
			v2 = 0;
			do
			{
				if ( v0 >= 50 )
					break;
				_LOBYTE(v3) = CheckThemeRoom(v2);
				if ( v3 )
				{
					_LOBYTE(v4) = 0;
					themes[v0].ttval = v2;
					for ( i = ThemeGood[random(v4, 4)]; ; i = random(v7, 17) )
					{
						_LOBYTE(v6) = SpecialThemeFit(numthemes, i);
						if ( v6 )
							break;
						_LOBYTE(v7) = 0;
					}
					v8 = numthemes;
					_LOBYTE(themes[numthemes].ttype) = i;
					v1 = leveltype;
					v0 = v8 + 1;
					numthemes = v0;
				}
				++v2;
			}
			while ( v2 < 256 );
		}
		if ( v1 == 2 || v1 == 3 || v1 == 4 )
		{
			v9 = themeCount;
			for ( j = 0; j < v9; ++j )
				_LOBYTE(themes[j].ttype) = -1;
			_LOBYTE(v11) = QuestStatus(3);
			v13 = &themeLoc[0].ttval;
			if ( v11 )
			{
				v14 = 0;
				if ( themeCount > 0 )
				{
					v15 = &themeLoc[0].ttval;
					while ( 1 )
					{
						themes[v14].ttval = *v15;
						_LOBYTE(v16) = SpecialThemeFit(v14, 5);
						if ( v16 )
							break;
						++v14;
						v15 += 5;
						if ( v14 >= themeCount )
							goto LABEL_23;
					}
					_LOBYTE(themes[v14].ttype) = 5;
					zharlib = v14;
				}
			}
LABEL_23:
			v17 = themeCount;
			for ( k = 0; k < themeCount; v13 += 5 )
			{
				if ( _LOBYTE(themes[k].ttype) == -1 )
				{
					_LOBYTE(v12) = 0;
					themes[k].ttval = *v13;
					for ( l = ThemeGood[random(v12, 4)]; ; l = random(v12, 17) )
					{
						_LOBYTE(v20) = SpecialThemeFit(k, l);
						if ( v20 )
							break;
						_LOBYTE(v12) = 0;
					}
					_LOBYTE(themes[k].ttype) = l;
				}
				v17 = themeCount;
				++k;
			}
			numthemes += v17;
		}
	}
}
// 5BB1ED: using guessed type char leveltype;
// 6AAA3C: using guessed type int armorFlag;
// 6AAA50: using guessed type int weaponFlag;
// 6AAA54: using guessed type int treasureFlag;
// 6AAA58: using guessed type int mFountainFlag;
// 6AAA5C: using guessed type int cauldronFlag;
// 6AAA60: using guessed type int tFountainFlag;
// 6AAA64: using guessed type int zharlib;
// 6AAC08: using guessed type int pFountainFlag;
// 6AAC0C: using guessed type int bFountainFlag;
// 6AAC10: using guessed type int bCrossFlag;

//----- (0045D087) --------------------------------------------------------
void __cdecl HoldThemeRooms()
{
	int v0; // ebx
	int i; // esi
	char v2; // dl
	signed int v3; // ecx
	signed int v4; // eax
	signed int v5; // edi

	if ( currlevel != 16 )
	{
		if ( leveltype == 1 )
		{
			v0 = numthemes;
			for ( i = 0; i < v0; ++i )
			{
				v2 = themes[i].ttval;
				v3 = 0;
				do
				{
					v4 = v3;
					v5 = 112;
					do
					{
						if ( dung_map[0][v4] == v2 )
							dFlags[0][v4] |= 8u;
						v4 += 112;
						--v5;
					}
					while ( v5 );
					++v3;
				}
				while ( v3 < 112 );
			}
		}
		else
		{
			DRLG_HoldThemeRooms();
		}
	}
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D0E1) --------------------------------------------------------
void __fastcall PlaceThemeMonsts(int t, int f)
{
	int v2; // eax
	int v3; // esi
	int v4; // edx
	int v5; // ecx
	char *v6; // edi
	int v7; // ebx
	int v8; // edi
	int v9; // esi
	int v10; // ecx
	int v11; // ecx
	int v12; // ST04_4
	int v13; // eax
	int v14[111]; // [esp+Ch] [ebp-1D0h]
	int max; // [esp+1C8h] [ebp-14h]
	int mtype; // [esp+1CCh] [ebp-10h]
	int *v17; // [esp+1D0h] [ebp-Ch]
	int (*v18)[112]; // [esp+1D4h] [ebp-8h]
	int (*v19)[112]; // [esp+1D8h] [ebp-4h]

	v2 = nummtypes;
	max = f;
	v3 = t;
	v4 = 0;
	v5 = 0;
	if ( nummtypes > 0 )
	{
		v6 = &Monsters[0].mPlaceFlags;
		do
		{
			if ( *v6 & 1 )
				v14[v4++] = v5;
			++v5;
			v6 += 328;
		}
		while ( v5 < v2 );
	}
	_LOBYTE(v5) = 0;
	v7 = 0;
	mtype = v14[random(v5, v4)];
	v17 = &themes[v3].ttval;
	v19 = dPiece;
	do
	{
		v8 = 0;
		v18 = v19;
		v9 = v7;
		do
		{
			v10 = (int)v17;
			if ( dung_map[0][v9] == *v17 && !nSolidTable[(*v18)[0]] && !dItem[0][v9] && !dObject[0][v9] )
			{
				_LOBYTE(v10) = 0;
				if ( !random(v10, max) )
				{
					_LOBYTE(v11) = 0;
					v12 = mtype;
					v13 = random(v11, 8);
					AddMonster(v8, v7, v13, v12, 1);
				}
			}
			++v18;
			++v8;
			v9 += 112;
		}
		while ( v8 < 112 );
		v19 = (int (*)[112])((char *)v19 + 4);
		++v7;
	}
	while ( (signed int)v19 < (signed int)dPiece[1] );
}
// 45D0E1: using guessed type int var_1D0[111];

//----- (0045D1C2) --------------------------------------------------------
void __fastcall Theme_Barrel(int theme_num)
{
	int v1; // edi
	int v2; // ebx
	char *v3; // esi
	int v4; // ecx
	int v5; // ecx
	int v6; // eax
	char t[20]; // [esp+Ch] [ebp-14h]

	*(_DWORD *)t = theme_num;
	t[16] = 2;
	t[17] = 6;
	t[18] = 4;
	t[19] = 8;
	t[8] = 5;
	t[9] = 7;
	t[10] = 3;
	t[11] = 9;
	v1 = 0;
	*(_DWORD *)&t[12] = (unsigned int)dPiece;
	do
	{
		v2 = 0;
		v3 = (char *)dung_map + v1;
		*(_DWORD *)&t[4] = *(_DWORD *)&t[12];
		do
		{
			v4 = *(_DWORD *)t;
			if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] )
			{
				_LOBYTE(v4) = 0;
				if ( !random(v4, t[(unsigned char)leveltype + 15]) )
				{
					_LOBYTE(v5) = 0;
					v6 = random(v5, t[(unsigned char)leveltype + 15]);
					AddObject((v6 != 0) + 57, v2, v1);
				}
			}
			*(_DWORD *)&t[4] += 448;
			++v2;
			v3 += 112;
		}
		while ( v2 < 112 );
		*(_DWORD *)&t[12] += 4;
		++v1;
	}
	while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] );
	PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D29A) --------------------------------------------------------
void __fastcall Theme_Shrine(int theme_num)
{
	int v1; // esi
	char v2[5]; // [esp+3h] [ebp-5h]

	v1 = theme_num;
	v2[1] = 6;
	v2[2] = 6;
	v2[3] = 3;
	v2[4] = 9;
	TFit_Shrine(theme_num);
	if ( themeVar1 == 1 )
	{
		AddObject(9, themex - 1, themey);
		AddObject(60, themex, themey);
		AddObject(9, themex + 1, themey);
	}
	else
	{
		AddObject(9, themex, themey - 1);
		AddObject(59, themex, themey);
		AddObject(9, themex, themey + 1);
	}
	PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D34D) --------------------------------------------------------
void __fastcall Theme_MonstPit(int theme_num)
{
	int v1; // esi
	int v2; // eax
	int v3; // ecx
	int v4; // edx
	int v5; // edi
	int v6; // esi
	char t[8]; // [esp+4h] [ebp-8h]

	v1 = theme_num;
	_LOBYTE(theme_num) = 0;
	*(_DWORD *)t = v1;
	t[4] = 6;
	t[5] = 7;
	t[6] = 3;
	t[7] = 9;
	v2 = random(theme_num, 100) + 1;
	v3 = 0;
	v4 = 0;
	if ( v2 > 0 )
	{
		v5 = themes[v1].ttval;
		while ( 1 )
		{
			v6 = v4 + 112 * v3;
			if ( dung_map[0][v6] == v5 && !nSolidTable[dPiece[0][v6]] )
				--v2;
			if ( v2 <= 0 )
				break;
			if ( ++v3 == 112 )
			{
				v3 = 0;
				if ( ++v4 == 112 )
					v4 = 0;
			}
		}
	}
	CreateRndItem(v3, v4, 1u, 0, 1);
	ItemNoFlippy();
	PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 3]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D3E6) --------------------------------------------------------
void __fastcall Theme_SkelRoom(int theme_num)
{
	int v1; // esi
	int v2; // edi
	int v3; // ecx
	int v4; // eax
	int v5; // ebx
	int v6; // eax
	int v7; // ecx
	int v8; // eax
	int v9; // ecx
	int v10; // eax
	int v11; // ecx
	int v12; // eax
	int v13; // ecx
	int v14; // eax
	int v15; // ebx
	int v16; // eax
	int v17; // ecx
	int v18; // eax
	int v19; // ebx
	char v20[5]; // [esp+Bh] [ebp-5h]

	v20[1] = 6;
	v20[2] = 7;
	v20[3] = 3;
	v20[4] = 9;
	TFit_SkelRoom(theme_num);
	v1 = themey;
	v2 = themex;
	AddObject(3, themex, themey);
	_LOBYTE(v3) = 0;
	if ( random(v3, v20[(unsigned char)leveltype]) )
	{
		v4 = PreSpawnSkeleton();
		v5 = v1 - 1;
		SpawnSkeleton(v4, v2 - 1, v1 - 1);
	}
	else
	{
		v5 = v1 - 1;
		AddObject(11, v2 - 1, v1 - 1);
	}
	v6 = PreSpawnSkeleton();
	SpawnSkeleton(v6, v2, v5);
	_LOBYTE(v7) = 0;
	if ( random(v7, v20[(unsigned char)leveltype]) )
	{
		v8 = PreSpawnSkeleton();
		SpawnSkeleton(v8, v2 + 1, v5);
	}
	else
	{
		AddObject(13, v2 + 1, v5);
	}
	_LOBYTE(v9) = 0;
	if ( random(v9, v20[(unsigned char)leveltype]) )
	{
		v10 = PreSpawnSkeleton();
		SpawnSkeleton(v10, v2 - 1, v1);
	}
	else
	{
		AddObject(12, v2 - 1, v1);
	}
	_LOBYTE(v11) = 0;
	if ( random(v11, v20[(unsigned char)leveltype]) )
	{
		v12 = PreSpawnSkeleton();
		SpawnSkeleton(v12, v2 + 1, v1);
	}
	else
	{
		AddObject(12, v2 + 1, v1);
	}
	_LOBYTE(v13) = 0;
	if ( random(v13, v20[(unsigned char)leveltype]) )
	{
		v14 = PreSpawnSkeleton();
		v15 = v1 + 1;
		SpawnSkeleton(v14, v2 - 1, v1 + 1);
	}
	else
	{
		v15 = v1 + 1;
		AddObject(13, v2 - 1, v1 + 1);
	}
	v16 = PreSpawnSkeleton();
	SpawnSkeleton(v16, v2, v15);
	_LOBYTE(v17) = 0;
	if ( random(v17, v20[(unsigned char)leveltype]) )
	{
		v18 = PreSpawnSkeleton();
		SpawnSkeleton(v18, v2 + 1, v15);
	}
	else
	{
		AddObject(11, v2 + 1, v15);
	}
	v19 = 112 * v2 + v1;
	if ( !dungeon[39][v19 + 37] )
		AddObject(61, v2, v1 - 2);
	if ( !dObject[0][v19 + 3] )
		AddObject(61, v2, v1 + 2);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D5BC) --------------------------------------------------------
void __fastcall Theme_Treasure(int theme_num)
{
	int v1; // ecx
	int v2; // esi
	int v3; // edi
	char *v4; // ebx
	int v5; // eax
	int v6; // ecx
	int v7; // eax
	char t[24]; // [esp+Ch] [ebp-18h]

	*(_DWORD *)t = theme_num;
	t[20] = 4;
	t[21] = 9;
	t[22] = 7;
	t[23] = 10;
	t[12] = 6;
	t[13] = 8;
	t[14] = 3;
	t[15] = 7;
	GetRndSeed();
	_LOBYTE(v1) = leveltype;
	v2 = 0;
	*(_DWORD *)&t[16] = (unsigned int)dPiece;
	do
	{
		v3 = 0;
		v4 = (char *)dung_map + v2;
		*(_DWORD *)&t[4] = *(_DWORD *)&t[16];
		do
		{
			if ( *v4 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] )
			{
				v5 = (unsigned char)v1;
				_LOBYTE(v1) = 0;
				*(_DWORD *)&t[8] = random(v1, t[v5 + 19]);
				_LOBYTE(v6) = 0;
				if ( !(2 * random(v6, t[(unsigned char)leveltype + 19])) )
				{
					CreateTypeItem(v3, v2, 0, 11, 0, 0, 1);
					ItemNoFlippy();
				}
				if ( *(_DWORD *)&t[8] )
				{
					_LOBYTE(v1) = leveltype;
					if ( *(_DWORD *)&t[8] < t[(unsigned char)leveltype + 19] - 2 )
						goto LABEL_13;
				}
				else
				{
					CreateRndItem(v3, v2, 0, 0, 1);
					ItemNoFlippy();
				}
				ItemNoFlippy();
				_LOBYTE(v1) = leveltype;
				if ( *(_DWORD *)&t[8] >= t[(unsigned char)leveltype + 19] - 2 && leveltype != 1 )
					items[v7]._ivalue >>= 1;
			}
LABEL_13:
			*(_DWORD *)&t[4] += 448;
			++v3;
			v4 += 112;
		}
		while ( v3 < 112 );
		*(_DWORD *)&t[16] += 4;
		++v2;
	}
	while ( *(_DWORD *)&t[16] < (signed int)dPiece[1] );
	PlaceThemeMonsts(*(int *)t, t[(unsigned char)v1 + 11]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D707) --------------------------------------------------------
void __fastcall Theme_Library(int theme_num)
{
	int v1; // edi
	int v2; // ebx
	char *v3; // esi
	int v4; // eax
	int v5; // ecx
	int v6; // ecx
	int v7; // eax
	int v8; // eax
	char t[20]; // [esp+Ch] [ebp-14h]

	*(_DWORD *)t = theme_num;
	t[16] = 1;
	t[17] = 2;
	t[18] = 2;
	t[19] = 5;
	t[12] = 5;
	t[13] = 7;
	t[14] = 3;
	t[15] = 9;
	TFit_Shrine(theme_num);
	v1 = 1;
	if ( themeVar1 == 1 )
	{
		AddObject(65, themex - 1, themey);
		AddObject(63, themex, themey);
		AddObject(65, themex + 1, themey);
	}
	else
	{
		AddObject(65, themex, themey - 1);
		AddObject(62, themex, themey);
		AddObject(65, themex, themey + 1);
	}
	*(_DWORD *)&t[8] = (unsigned int)&dMonster[1][1];
	do
	{
		v2 = 1;
		v3 = &dObject[1][v1];
		*(_DWORD *)&t[4] = *(_DWORD *)&t[8];
		do
		{
			_LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1);
			if ( v4 )
			{
				if ( !**(_DWORD **)&t[4] )
				{
					_LOBYTE(v5) = 0;
					if ( !random(v5, t[(unsigned char)leveltype + 15]) )
					{
						AddObject(64, v2, v1);
						_LOBYTE(v6) = 0;
						if ( random(v6, 2 * t[(unsigned char)leveltype + 15]) )
						{
							v7 = *v3 - 1;
							_LOBYTE(object[v7]._oSelFlag) = 0;
							object[v7]._oAnimFrame += 2;
						}
					}
				}
			}
			*(_DWORD *)&t[4] += 448;
			++v2;
			v3 += 112;
		}
		while ( v2 < 111 );
		*(_DWORD *)&t[8] += 4;
		++v1;
	}
	while ( *(_DWORD *)&t[8] < (signed int)&dMonster[1][111] );
	_LOBYTE(v8) = QuestStatus(3);
	if ( !v8 || *(_DWORD *)t != zharlib )
		PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 12]);
}
// 5BB1ED: using guessed type char leveltype;
// 6AAA64: using guessed type int zharlib;

//----- (0045D88A) --------------------------------------------------------
void __fastcall Theme_Torture(int theme_num)
{
	int v1; // ebx
	int v2; // esi
	char *v3; // edi
	int v4; // eax
	int v5; // ecx
	char x[20]; // [esp+Ch] [ebp-14h]

	v1 = theme_num;
	x[12] = 6;
	x[13] = 8;
	x[14] = 3;
	x[15] = 8;
	x[4] = 6;
	x[5] = 8;
	x[6] = 3;
	x[7] = 9;
	v2 = 1;
	*(_DWORD *)&x[8] = (unsigned int)&dPiece[1][1];
	do
	{
		*(_DWORD *)&x[16] = 1;
		v3 = &dung_map[1][v2];
		*(_DWORD *)x = *(_DWORD *)&x[8];
		do
		{
			if ( *v3 == themes[v1].ttval && !nSolidTable[**(_DWORD **)x] )
			{
				_LOBYTE(v4) = CheckThemeObj3(*(int *)&x[16], v2, v1, -1);
				if ( v4 )
				{
					_LOBYTE(v5) = 0;
					if ( !random(v5, x[(unsigned char)leveltype + 11]) )
						AddObject(30, *(int *)&x[16], v2);
				}
			}
			++*(_DWORD *)&x[16];
			*(_DWORD *)x += 448;
			v3 += 112;
		}
		while ( *(_DWORD *)&x[16] < 111 );
		*(_DWORD *)&x[8] += 4;
		++v2;
	}
	while ( *(_DWORD *)&x[8] < (signed int)&dPiece[1][111] );
	PlaceThemeMonsts(v1, x[(unsigned char)leveltype + 3]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D95D) --------------------------------------------------------
void __fastcall Theme_BloodFountain(int theme_num)
{
	int v1; // esi
	char v2[5]; // [esp+3h] [ebp-5h]

	v1 = theme_num;
	v2[1] = 6;
	v2[2] = 8;
	v2[3] = 3;
	v2[4] = 9;
	TFit_Obj5(theme_num);
	AddObject(66, themex, themey);
	PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045D9A3) --------------------------------------------------------
void __fastcall Theme_Decap(int theme_num)
{
	int v1; // ebx
	int v2; // esi
	char *v3; // edi
	int v4; // eax
	int v5; // ecx
	char x[20]; // [esp+Ch] [ebp-14h]

	v1 = theme_num;
	x[12] = 6;
	x[13] = 8;
	x[14] = 3;
	x[15] = 8;
	x[4] = 6;
	x[5] = 8;
	x[6] = 3;
	x[7] = 9;
	v2 = 1;
	*(_DWORD *)&x[8] = (unsigned int)&dPiece[1][1];
	do
	{
		*(_DWORD *)&x[16] = 1;
		v3 = &dung_map[1][v2];
		*(_DWORD *)x = *(_DWORD *)&x[8];
		do
		{
			if ( *v3 == themes[v1].ttval && !nSolidTable[**(_DWORD **)x] )
			{
				_LOBYTE(v4) = CheckThemeObj3(*(int *)&x[16], v2, v1, -1);
				if ( v4 )
				{
					_LOBYTE(v5) = 0;
					if ( !random(v5, x[(unsigned char)leveltype + 11]) )
						AddObject(67, *(int *)&x[16], v2);
				}
			}
			++*(_DWORD *)&x[16];
			*(_DWORD *)x += 448;
			v3 += 112;
		}
		while ( *(_DWORD *)&x[16] < 111 );
		*(_DWORD *)&x[8] += 4;
		++v2;
	}
	while ( *(_DWORD *)&x[8] < (signed int)&dPiece[1][111] );
	PlaceThemeMonsts(v1, x[(unsigned char)leveltype + 3]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045DA76) --------------------------------------------------------
void __fastcall Theme_PurifyingFountain(int theme_num)
{
	int v1; // esi
	char v2[5]; // [esp+3h] [ebp-5h]

	v1 = theme_num;
	v2[1] = 6;
	v2[2] = 7;
	v2[3] = 3;
	v2[4] = 9;
	TFit_Obj5(theme_num);
	AddObject(76, themex, themey);
	PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045DABC) --------------------------------------------------------
void __fastcall Theme_ArmorStand(int theme_num)
{
	int v1; // esi
	int v2; // ebx
	char *v3; // edi
	int v4; // eax
	int v5; // ecx
	char t[20]; // [esp+Ch] [ebp-14h]

	v1 = 0;
	*(_DWORD *)t = theme_num;
	t[16] = 6;
	t[17] = 8;
	t[18] = 3;
	t[19] = 8;
	t[8] = 6;
	t[9] = 7;
	t[10] = 3;
	t[11] = 9;
	if ( armorFlag )
	{
		TFit_Obj3(theme_num);
		AddObject(77, themex, themey);
	}
	*(_DWORD *)&t[12] = (unsigned int)dPiece;
	do
	{
		v2 = 0;
		v3 = (char *)dung_map + v1;
		*(_DWORD *)&t[4] = *(_DWORD *)&t[12];
		do
		{
			if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] )
			{
				_LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1);
				if ( v4 )
				{
					_LOBYTE(v5) = 0;
					if ( !random(v5, t[(unsigned char)leveltype + 15]) )
						AddObject(78, v2, v1);
				}
			}
			*(_DWORD *)&t[4] += 448;
			++v2;
			v3 += 112;
		}
		while ( v2 < 112 );
		*(_DWORD *)&t[12] += 4;
		++v1;
	}
	while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] );
	PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]);
	armorFlag = 0;
}
// 5BB1ED: using guessed type char leveltype;
// 6AAA3C: using guessed type int armorFlag;

//----- (0045DBAD) --------------------------------------------------------
void __fastcall Theme_GoatShrine(int theme_num)
{
	int v1; // edx
	int v2; // esi
	int v3; // ecx
	int v4; // edi
	int v5; // eax
	char *v6; // ebx
	_DWORD *v7; // [esp+4h] [ebp-8h]
	int v8; // [esp+8h] [ebp-4h]

	v8 = theme_num;
	TFit_GoatShrine(theme_num);
	AddObject(79, themex, themey);
	v1 = themey;
	v2 = themey - 1;
	if ( themey - 1 <= themey + 1 )
	{
		v3 = themex;
		do
		{
			v4 = v3 - 1;
			if ( (unsigned char)(__OFSUB__(v3 - 1, v3 + 1) ^ 1) | (v3 - 1 == v3 + 1) )
			{
				v5 = v2 + 112 * v4;
				v6 = (char *)dung_map + v5;
				v7 = (_DWORD *)((char *)dPiece + 4 * v5);
				do
				{
					if ( *v6 == themes[v8].ttval && !nSolidTable[*v7] && (v4 != v3 || v2 != v1) )
					{
						AddMonster(v4, v2, 1, themeVar1, 1);
						v1 = themey;
						v3 = themex;
					}
					v7 += 112;
					++v4;
					v6 += 112;
				}
				while ( v4 <= v3 + 1 );
			}
			++v2;
		}
		while ( v2 <= v1 + 1 );
	}
}

//----- (0045DC7B) --------------------------------------------------------
void __fastcall Theme_Cauldron(int theme_num)
{
	int v1; // esi
	char v2[5]; // [esp+3h] [ebp-5h]

	v1 = theme_num;
	v2[1] = 6;
	v2[2] = 7;
	v2[3] = 3;
	v2[4] = 9;
	TFit_Obj5(theme_num);
	AddObject(80, themex, themey);
	PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045DCC1) --------------------------------------------------------
void __fastcall Theme_MurkyFountain(int theme_num)
{
	int v1; // esi
	char v2[5]; // [esp+3h] [ebp-5h]

	v1 = theme_num;
	v2[1] = 6;
	v2[2] = 7;
	v2[3] = 3;
	v2[4] = 9;
	TFit_Obj5(theme_num);
	AddObject(81, themex, themey);
	PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045DD07) --------------------------------------------------------
void __fastcall Theme_TearFountain(int theme_num)
{
	int v1; // esi
	char v2[5]; // [esp+3h] [ebp-5h]

	v1 = theme_num;
	v2[1] = 6;
	v2[2] = 7;
	v2[3] = 3;
	v2[4] = 9;
	TFit_Obj5(theme_num);
	AddObject(82, themex, themey);
	PlaceThemeMonsts(v1, v2[(unsigned char)leveltype]);
}
// 5BB1ED: using guessed type char leveltype;

//----- (0045DD4D) --------------------------------------------------------
void __fastcall Theme_BrnCross(int theme_num)
{
	int v1; // esi
	int v2; // ebx
	char *v3; // edi
	int v4; // eax
	int v5; // ecx
	char t[20]; // [esp+Ch] [ebp-14h]

	*(_DWORD *)t = theme_num;
	t[8] = 6;
	t[9] = 8;
	t[10] = 3;
	t[11] = 9;
	t[16] = 5;
	t[17] = 7;
	t[18] = 3;
	t[19] = 8;
	v1 = 0;
	*(_DWORD *)&t[12] = (unsigned int)dPiece;
	do
	{
		v2 = 0;
		v3 = (char *)dung_map + v1;
		*(_DWORD *)&t[4] = *(_DWORD *)&t[12];
		do
		{
			if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] )
			{
				_LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1);
				if ( v4 )
				{
					_LOBYTE(v5) = 0;
					if ( !random(v5, t[(unsigned char)leveltype + 15]) )
						AddObject(91, v2, v1);
				}
			}
			*(_DWORD *)&t[4] += 448;
			++v2;
			v3 += 112;
		}
		while ( v2 < 112 );
		*(_DWORD *)&t[12] += 4;
		++v1;
	}
	while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] );
	PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]);
	bCrossFlag = 1;
}
// 5BB1ED: using guessed type char leveltype;
// 6AAC10: using guessed type int bCrossFlag;

//----- (0045DE20) --------------------------------------------------------
void __fastcall Theme_WeaponRack(int theme_num)
{
	int v1; // esi
	int v2; // ebx
	char *v3; // edi
	int v4; // eax
	int v5; // ecx
	char t[20]; // [esp+Ch] [ebp-14h]

	v1 = 0;
	*(_DWORD *)t = theme_num;
	t[16] = 6;
	t[17] = 8;
	t[18] = 5;
	t[19] = 8;
	t[8] = 6;
	t[9] = 7;
	t[10] = 3;
	t[11] = 9;
	if ( weaponFlag )
	{
		TFit_Obj3(theme_num);
		AddObject(92, themex, themey);
	}
	*(_DWORD *)&t[12] = (unsigned int)dPiece;
	do
	{
		v2 = 0;
		v3 = (char *)dung_map + v1;
		*(_DWORD *)&t[4] = *(_DWORD *)&t[12];
		do
		{
			if ( *v3 == themes[*(_DWORD *)t].ttval && !nSolidTable[**(_DWORD **)&t[4]] )
			{
				_LOBYTE(v4) = CheckThemeObj3(v2, v1, *(int *)t, -1);
				if ( v4 )
				{
					_LOBYTE(v5) = 0;
					if ( !random(v5, t[(unsigned char)leveltype + 15]) )
						AddObject(93, v2, v1);
				}
			}
			*(_DWORD *)&t[4] += 448;
			++v2;
			v3 += 112;
		}
		while ( v2 < 112 );
		*(_DWORD *)&t[12] += 4;
		++v1;
	}
	while ( *(_DWORD *)&t[12] < (signed int)dPiece[1] );
	PlaceThemeMonsts(*(int *)t, t[(unsigned char)leveltype + 7]);
	weaponFlag = 0;
}
// 5BB1ED: using guessed type char leveltype;
// 6AAA50: using guessed type int weaponFlag;

//----- (0045DF11) --------------------------------------------------------
void __cdecl UpdateL4Trans()
{
	signed int v0; // ecx
	_BYTE *v1; // eax
	signed int v2; // edx

	v0 = 0;
	do
	{
		v1 = (unsigned char *)dung_map + v0;
		v2 = 112;
		do
		{
			if ( *v1 )
				*v1 = 1;
			v1 += 112;
			--v2;
		}
		while ( v2 );
		++v0;
	}
	while ( v0 < 112 );
}

//----- (0045DF31) --------------------------------------------------------
void __cdecl CreateThemeRooms()
{
	int v0; // esi
	int v1; // eax

	if ( currlevel != 16 )
	{
		v0 = 0;
		for ( InitObjFlag = 1; v0 < numthemes; ++v0 )
		{
			v1 = SLOBYTE(themes[v0].ttype);
			themex = 0;
			themey = 0;
			switch ( v1 )
			{
				case THEME_BARREL:
					Theme_Barrel(v0);
					break;
				case THEME_SHRINE:
					Theme_Shrine(v0);
					break;
				case THEME_MONSTPIT:
					Theme_MonstPit(v0);
					break;
				case THEME_SKELROOM:
					Theme_SkelRoom(v0);
					break;
				case THEME_TREASURE:
					Theme_Treasure(v0);
					break;
				case THEME_LIBRARY:
					Theme_Library(v0);
					break;
				case THEME_TORTURE:
					Theme_Torture(v0);
					break;
				case THEME_BLOODFOUNTAIN:
					Theme_BloodFountain(v0);
					break;
				case THEME_DECAPITATED:
					Theme_Decap(v0);
					break;
				case THEME_PURIFYINGFOUNTAIN:
					Theme_PurifyingFountain(v0);
					break;
				case THEME_ARMORSTAND:
					Theme_ArmorStand(v0);
					break;
				case THEME_GOATSHRINE:
					Theme_GoatShrine(v0);
					break;
				case THEME_CAULDRON:
					Theme_Cauldron(v0);
					break;
				case THEME_MURKYFOUNTAIN:
					Theme_MurkyFountain(v0);
					break;
				case THEME_TEARFOUNTAIN:
					Theme_TearFountain(v0);
					break;
				case THEME_BRNCROSS:
					Theme_BrnCross(v0);
					break;
				case THEME_WEAPONRACK:
					Theme_WeaponRack(v0);
					break;
				default:
					continue;
			}
		}
		InitObjFlag = 0;
		if ( leveltype == 4 && themeCount > 0 )
			UpdateL4Trans();
	}
}
// 5BB1ED: using guessed type char leveltype;
// 67D7C0: using guessed type int InitObjFlag;

//----- (0045E08C) --------------------------------------------------------
int __fastcall tmsg_get(char *data, int size)
{
	char *v2; // ebx
	DWORD v3; // eax
	TMsg v4; // esi
	size_t v6; // edi

	v2 = data;
	if ( !*(_DWORD *)&sgpTimedMsgHead )
		return 0;
	v3 = GetTickCount();
	v4 = sgpTimedMsgHead;
	if ( (signed int)(*(_DWORD *)(*(_DWORD *)&sgpTimedMsgHead + 4) - v3) >= 0 )
		return 0;
	sgpTimedMsgHead = **(TMsg **)&sgpTimedMsgHead;
	//v6 = v4[8];
	//memcpy(v2, v4 + 9, v6);
//	mem_free_dbg(v4);
	return v6;
}

//----- (0045E0D7) --------------------------------------------------------
void __fastcall tmsg_add(char *msg, char len)
{
	char v2; // bl
	char *v3; // ebp
	size_t v4; // edi
	_DWORD *v5; // eax
	_DWORD *v6; // esi
	DWORD v7; // eax
	TMsg v8; // ecx
	TMsg v9; // eax

	v2 = len;
	v3 = msg;
	v4 = (unsigned char)len;
	v5 = (unsigned int *)DiabloAllocPtr((unsigned char)len + 12);
	v6 = v5;
	*v5 = 0;
	v7 = GetTickCount();
	*((_BYTE *)v6 + 8) = v2;
	v6[1] = v7 + 500;
	memcpy((char *)v6 + 9, v3, v4);
	v8 = sgpTimedMsgHead;
	v9 = sgpTimedMsgHead;
/*	while ( *v8 )
	{
		v9 = v8;
		v8 = (TMsg *)*v8;
	}
	*v9 = (TMsg)v6;*/
}

//----- (0045E12A) --------------------------------------------------------
void __cdecl tmsg_cleanup()
{
	TMsg v0; // eax
	TMsg v1; // esi

	v0 = sgpTimedMsgHead;
/*	if ( sgpTimedMsgHead )
	{
		do
		{
			v1 = v0;
			sgpTimedMsgHead = 0;
			mem_free_dbg(v0);
			v0 = v1;
			sgpTimedMsgHead = v1;
		}
		while ( v1 );
	}*/
}

//----- (0045E151) --------------------------------------------------------
int __fastcall town_clear_upper_buf(int a1)
{
	unsigned int v1; // edi
	signed int v2; // edx
	signed int v3; // ebx
	int result; // eax
	char *v5; // edi
	signed int v6; // edx
	signed int v7; // ebx
	char *v8; // edi

	v1 = a1;
	v2 = 30;
	v3 = 1;
	result = 0;
	while ( v1 >= screen_buf_end )
	{
		v5 = (char *)(v2 + v1);
		memset(v5, 0, 4 * v3);
		v1 = (unsigned int)&v5[4 * v3 - 832 + v2];
		if ( !v2 )
		{
			v6 = 2;
			v7 = 15;
			do
			{
				if ( v1 < screen_buf_end )
					break;
				v8 = (char *)(v6 + v1);
				memset(v8, 0, 4 * v7);
				v1 = (unsigned int)&v8[4 * v7-- - 832 + v6];
				v6 += 2;
			}
			while ( v6 != 32 );
			return result;
		}
		v2 -= 2;
		++v3;
	}
	return result;
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (0045E1B7) --------------------------------------------------------
void __fastcall town_clear_low_buf(int y_related)
{
	unsigned int v1; // edi
	signed int v2; // edx
	signed int i; // ebx
	int v4; // edi
	char *v5; // edi
	signed int v6; // edx
	signed int v7; // ebx
	int v8; // edi
	char *v9; // edi

	v1 = y_related;
	v2 = 30;
	for ( i = 1; ; ++i )
	{
		if ( v1 < screen_buf_end )
		{
			v5 = (char *)(v2 + v1);
			memset(v5, 0, 4 * i);
			v4 = (int)&v5[4 * i + v2];
		}
		else
		{
			v4 = v1 + 64;
		}
		v1 = v4 - 832;
		if ( !v2 )
			break;
		v2 -= 2;
	}
	v6 = 2;
	v7 = 15;
	do
	{
		if ( v1 < screen_buf_end )
		{
			v9 = (char *)(v6 + v1);
			memset(v9, 0, 4 * v7);
			v8 = (int)&v9[4 * v7 + v6];
		}
		else
		{
			v8 = v1 + 64;
		}
		v1 = v8 - 832;
		--v7;
		v6 += 2;
	}
	while ( v6 != 32 );
}
// 69CF0C: using guessed type int screen_buf_end;

//----- (0045E226) --------------------------------------------------------
void __fastcall town_draw_low_somepiece(void *buffer, int x, int y, int sx, int sy)
{
	int v5; // ebx
	char *v6; // esi
	signed int v7; // edi
	int v8; // eax
	int v9; // eax
	void *unused; // [esp+Ch] [ebp-8h]
	char *a1; // [esp+10h] [ebp-4h]

	v5 = x;
	unused = buffer;
	a1 = (char *)buffer;
	v6 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y);
	v7 = 0;
	do
	{
		v8 = *(unsigned short *)&v6[2 * v7];
		level_cel_block = *(unsigned short *)&v6[2 * v7];
		if ( v8 )
			drawLowerScreen(a1);
		v9 = *(unsigned short *)&v6[2 * v7 + 2];
		level_cel_block = *(unsigned short *)&v6[2 * v7 + 2];
		if ( v9 )
			drawLowerScreen(a1 + 32);
		a1 -= 24576;
		v7 += 2;
	}
	while ( v7 < 12 );
	town_draw_low_something(unused, v5, y, sx, sy, 0);
}
// 69CF14: using guessed type int level_cel_block;

//----- (0045E2A5) --------------------------------------------------------
void __fastcall town_draw_low_something(void *unused, int x, int y, int sx, int sy, int some_flag)
{
	unsigned int v6; // edx
	int v7; // edi
	char v8; // al
	char v9; // al
	int v10; // esi
	int v11; // ebx
	int v12; // esi
	int v13; // ebx
	int v14; // eax
	int v15; // eax
	int v16; // esi
	int v17; // ebx
	char v18; // al
	int v19; // esi
	int v20; // ebx
	int v21; // edi
	char v22; // al
	char v23; // al
	int v24; // esi
	int v25; // ebx
	int v26; // edi
	char *v27; // [esp+Ch] [ebp-Ch]
	int xa; // [esp+10h] [ebp-8h]
	int v29; // [esp+14h] [ebp-4h]

	xa = x;
	v6 = 112 * x;
	v27 = (char *)gpBuffer + screen_y_times_768[sy] + sx;
	v7 = v6 + y;
	v29 = v6 + y;
	v8 = dItem[v6 / 0x70][y];
	if ( v8 )
	{
		v9 = v8 - 1;
		v10 = v9;
		v11 = sx - items[v10]._iAnimXOff;
		if ( v9 == pcursitem )
			Cel_header_and_colour_highlight(
				181,
				v11,
				sy,
				(char *)items[v10].ItemFrame,
				items[v10]._iAnimFrame,
				items[v10]._iAnimWidth,
				0,
				8);
		Cel2_header(v11, sy, (char *)items[v10].ItemFrame, items[v10]._iAnimFrame, items[v10]._iAnimWidth, 0, 8);
	}
	if ( dFlags[0][v7] & 0x10 )
	{
		v12 = -1 - *(&dword_52D204 + v7);
		v13 = sx - towner[v12]._tAnimWidth2;
		if ( -1 - *(&dword_52D204 + v7) == *(_DWORD *)&pcursmonst )
			Cel_header_and_colour_highlight(
				166,
				v13,
				sy,
				(char *)towner[v12]._tAnimCel,
				towner[v12]._tAnimFrame,
				towner[v12]._tAnimWidth,
				0,
				8);
		Cel2_header(v13, sy, (char *)towner[v12]._tAnimCel, towner[v12]._tAnimFrame, towner[v12]._tAnimWidth, 0, 8);
	}
	v14 = dMonster[0][v7];
	if ( v14 > 0 )
	{
		v15 = v14 - 1;
		v16 = v15;
		v17 = sx - towner[v15]._tAnimWidth2;
		if ( v15 == *(_DWORD *)&pcursmonst )
			Cel_header_and_colour_highlight(
				166,
				v17,
				sy,
				(char *)towner[v16]._tAnimCel,
				towner[v16]._tAnimFrame,
				towner[v16]._tAnimWidth,
				0,
				8);
		Cel2_header(v17, sy, (char *)towner[v16]._tAnimCel, towner[v16]._tAnimFrame, towner[v16]._tAnimWidth, 0, 8);
	}
	if ( dFlags[0][v7] & 0x20 )
	{
		v18 = -1 - *((_BYTE *)&themeLoc[49].height + v7 + 3);
		v19 = v18;
		v20 = sy + plr[v19]._pyoff;
		v21 = sx + plr[v19]._pxoff - plr[v19]._pAnimWidth2;
		if ( v18 == pcursplr )
			engine_417C99(165, v21, v20, (void *)plr[v19]._pAnimData, plr[v19]._pAnimFrame, plr[v19]._pAnimWidth, 0, 8);
		engine_417B83(v21, v20, (void *)plr[v19]._pAnimData, plr[v19]._pAnimFrame, plr[v19]._pAnimWidth, 0, 8);
		if ( some_flag && plr[v19]._peflag )
			town_draw_low_somepiece(v27 - 64, xa - 1, y + 1, sx - 64, sy);
		v7 = v29;
	}
	if ( dFlags[0][v7] & 4 )
		scrollrt_452CC0(xa, y, sx, sy, 0, 8, 1);
	v22 = dPlayer[0][v7];
	if ( v22 > 0 )
	{
		v23 = v22 - 1;
		v24 = v23;
		v25 = sy + plr[v24]._pyoff;
		v26 = sx + plr[v24]._pxoff - plr[v24]._pAnimWidth2;
		if ( v23 == pcursplr )
			engine_417C99(165, v26, v25, (void *)plr[v24]._pAnimData, plr[v24]._pAnimFrame, plr[v24]._pAnimWidth, 0, 8);
		engine_417B83(v26, v25, (void *)plr[v24]._pAnimData, plr[v24]._pAnimFrame, plr[v24]._pAnimWidth, 0, 8);
		if ( some_flag && plr[v24]._peflag )
			town_draw_low_somepiece(v27 - 64, xa - 1, y + 1, sx - 64, sy);
		v7 = v29;
	}
	if ( dFlags[0][v7] & 1 )
		scrollrt_452B2A(xa, y, sx, sy, 0, 8, 0);
}
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC2: using guessed type char pcursplr;

//----- (0045E5B0) --------------------------------------------------------
void __fastcall town_draw_low_pieces(int x, int y, int sx, int sy, int a5, int some_flag)
{
	int v6; // ebx
	int *v7; // edi
	char *v8; // esi
	int v9; // eax
	int v10; // eax
	int *v11; // ebx
	int v12; // esi
	char *v13; // esi
	char *v14; // edi
	int v15; // eax
	int v16; // eax
	bool v17; // zf
	int *v18; // ebx
	char *v19; // esi
	char *v20; // edi
	int v21; // eax
	char *a1; // [esp+Ch] [ebp-10h]
	int a1a; // [esp+Ch] [ebp-10h]
	int ya; // [esp+10h] [ebp-Ch]
	signed int v25; // [esp+14h] [ebp-8h]
	signed int v26; // [esp+14h] [ebp-8h]
	signed int v27; // [esp+14h] [ebp-8h]
	signed int xa; // [esp+18h] [ebp-4h]
	int a5a; // [esp+2Ch] [ebp+10h]

	ya = y;
	xa = x;
	if ( some_flag )
	{
		if ( y >= 0 && y < 112 && x >= 0 && x < 112 && (level_cel_block = dPiece[0][y + 112 * x]) != 0 )
		{
			v6 = sy;
			v7 = &screen_y_times_768[sy];
			a1 = &gpBuffer->row_unused_1[0].col_unused_1[*v7 + 32 + sx];
			v25 = 1;
			v8 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y);
			do
			{
				v9 = *(unsigned short *)&v8[2 * v25];
				level_cel_block = *(unsigned short *)&v8[2 * v25];
				if ( v9 )
					drawLowerScreen(a1);
				v25 += 2;
				a1 -= 24576;
			}
			while ( v25 < 17 );
			town_draw_low_something((char *)gpBuffer + *v7 + sx, xa, ya, sx, sy, 0);
		}
		else
		{
			town_clear_low_buf((int)gpBuffer + screen_y_times_768[sy] + sx);
			v6 = sy;
		}
		++xa;
		y = ya - 1;
		sx += 64;
		--ya;
	}
	else
	{
		v6 = sy;
	}
	v10 = a5 - some_flag;
	if ( a5 - some_flag > 0 )
	{
		v11 = &screen_y_times_768[v6];
		v12 = 112 * xa;
		a5a = 112 * xa;
		a1a = v10;
		do
		{
			if ( y >= 0 && y < 112 && v12 >= 0 && v12 < 12544 && (level_cel_block = dPiece[0][v12 + y]) != 0 )
			{
				v13 = (char *)gpBuffer + *v11 + sx;
				v14 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, ya);
				v26 = 0;
				do
				{
					v15 = *(unsigned short *)&v14[2 * v26];
					level_cel_block = *(unsigned short *)&v14[2 * v26];
					if ( v15 )
						drawLowerScreen(v13);
					v16 = *(unsigned short *)&v14[2 * v26 + 2];
					level_cel_block = *(unsigned short *)&v14[2 * v26 + 2];
					if ( v16 )
						drawLowerScreen(v13 + 32);
					v26 += 2;
					v13 -= 24576;
				}
				while ( v26 < 16 );
				town_draw_low_something((char *)gpBuffer + *v11 + sx, xa, ya, sx, sy, 1);
				v12 = a5a;
			}
			else
			{
				town_clear_low_buf((int)gpBuffer + *v11 + sx);
			}
			++xa;
			sx += 64;
			v12 += 112;
			y = ya - 1;
			v17 = a1a-- == 1;
			a5a = v12;
			--ya;
		}
		while ( !v17 );
		v6 = sy;
	}
	if ( some_flag )
	{
		if ( y >= 0 && y < 112 && xa >= 0 && xa < 112 && (level_cel_block = dPiece[0][y + 112 * xa]) != 0 )
		{
			v18 = &screen_y_times_768[v6];
			v19 = (char *)gpBuffer + *v18 + sx;
			v20 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, ya);
			v27 = 0;
			do
			{
				v21 = *(unsigned short *)&v20[2 * v27];
				level_cel_block = *(unsigned short *)&v20[2 * v27];
				if ( v21 )
					drawLowerScreen(v19);
				v27 += 2;
				v19 -= 24576;
			}
			while ( v27 < 16 );
			town_draw_low_something((char *)gpBuffer + *v18 + sx, xa, ya, sx, sy, 0);
		}
		else
		{
			town_clear_low_buf((int)gpBuffer + screen_y_times_768[v6] + sx);
		}
	}
}
// 69CF14: using guessed type int level_cel_block;

//----- (0045E898) --------------------------------------------------------
void __fastcall town_draw_lower_screen(void *buffer, int x, int y, int a4, int a5, int sx, int sy)
{
	int v7; // ebx
	char *v8; // edi
	short *v9; // esi
	int v10; // eax
	int v11; // eax
	void *v12; // [esp+8h] [ebp-8h]
	int xa; // [esp+Ch] [ebp-4h]
	int a4a; // [esp+1Ch] [ebp+Ch]

	v7 = a4;
	xa = x;
	v12 = buffer;
	if ( a4 )
		v8 = (char *)buffer + 24576 * a4;
	else
		v8 = (char *)buffer;
	a4a = 0;
	v9 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y) + 3];
	do
	{
		if ( v7 <= a4a )
		{
			v10 = (unsigned short)*(v9 - 1);
			level_cel_block = (unsigned short)*(v9 - 1);
			if ( v10 )
				drawLowerScreen(v8);
			v11 = (unsigned short)*v9;
			level_cel_block = (unsigned short)*v9;
			if ( v11 )
				drawLowerScreen(v8 + 32);
		}
		v8 -= 24576;
		++a4a;
		v9 += 2;
	}
	while ( a4a < 6 );
	if ( a5 < 8 )
		town_draw_low_towners((int)v12, xa, y, v7, a5, sx, sy, 0);
}
// 69CF14: using guessed type int level_cel_block;

//----- (0045E939) --------------------------------------------------------
void __fastcall town_draw_low_towners(int x, int y, int a3, int a4, int a5, int sx, int sy, int some_flag)
{
	unsigned int v8; // edx
	int v9; // ebx
	char v10; // al
	char v11; // al
	int v12; // esi
	int v13; // edi
	int v14; // esi
	int v15; // edi
	int v16; // eax
	int v17; // eax
	int v18; // esi
	int v19; // edi
	char v20; // al
	int v21; // esi
	int v22; // ebx
	int v23; // edi
	char v24; // al
	char v25; // al
	int v26; // esi
	int v27; // ebx
	int v28; // edi
	int v29; // [esp+Ch] [ebp-Ch]
	int xa; // [esp+10h] [ebp-8h]
	int v31; // [esp+14h] [ebp-4h]

	xa = y;
	v8 = 112 * y;
	v9 = v8 + a3;
	v29 = x;
	v31 = v8 + a3;
	v10 = dItem[v8 / 0x70][a3];
	if ( v10 )
	{
		v11 = v10 - 1;
		v12 = v11;
		v13 = sx - items[v12]._iAnimXOff;
		if ( v11 == pcursitem )
			Cel_header_and_colour_highlight(
				181,
				v13,
				sy,
				(char *)items[v12].ItemFrame,
				items[v12]._iAnimFrame,
				items[v12]._iAnimWidth,
				a5,
				8);
		Cel2_header(v13, sy, (char *)items[v12].ItemFrame, items[v12]._iAnimFrame, items[v12]._iAnimWidth, a5, 8);
	}
	if ( dFlags[0][v9] & 0x10 )
	{
		v14 = -1 - *(&dword_52D204 + v9);
		v15 = sx - towner[v14]._tAnimWidth2;
		if ( -1 - *(&dword_52D204 + v9) == *(_DWORD *)&pcursmonst )
			Cel_header_and_colour_highlight(
				166,
				v15,
				sy,
				(char *)towner[v14]._tAnimCel,
				towner[v14]._tAnimFrame,
				towner[v14]._tAnimWidth,
				a5,
				8);
		Cel2_header(v15, sy, (char *)towner[v14]._tAnimCel, towner[v14]._tAnimFrame, towner[v14]._tAnimWidth, a5, 8);
	}
	v16 = dMonster[0][v9];
	if ( v16 > 0 )
	{
		v17 = v16 - 1;
		v18 = v17;
		v19 = sx - towner[v17]._tAnimWidth2;
		if ( v17 == *(_DWORD *)&pcursmonst )
			Cel_header_and_colour_highlight(
				166,
				v19,
				sy,
				(char *)towner[v18]._tAnimCel,
				towner[v18]._tAnimFrame,
				towner[v18]._tAnimWidth,
				a5,
				8);
		Cel2_header(v19, sy, (char *)towner[v18]._tAnimCel, towner[v18]._tAnimFrame, towner[v18]._tAnimWidth, a5, 8);
	}
	if ( dFlags[0][v9] & 0x20 )
	{
		v20 = -1 - *((_BYTE *)&themeLoc[49].height + v9 + 3);
		v21 = v20;
		v22 = sy + plr[v21]._pyoff;
		v23 = sx + plr[v21]._pxoff - plr[v21]._pAnimWidth2;
		if ( v20 == pcursplr )
			engine_417C99(165, v23, v22, (void *)plr[v21]._pAnimData, plr[v21]._pAnimFrame, plr[v21]._pAnimWidth, a5, 8);
		engine_417B83(v23, v22, (void *)plr[v21]._pAnimData, plr[v21]._pAnimFrame, plr[v21]._pAnimWidth, a5, 8);
		if ( some_flag && plr[v21]._peflag )
			town_draw_lower_screen((void *)(v29 - 64), xa - 1, a3 + 1, a4, a5, sx - 64, sy);
		v9 = v31;
	}
	if ( dFlags[0][v9] & 4 )
		scrollrt_452CC0(xa, a3, sx, sy, a5, 8, 1);
	v24 = dPlayer[0][v9];
	if ( v24 > 0 )
	{
		v25 = v24 - 1;
		v26 = v25;
		v27 = sy + plr[v26]._pyoff;
		v28 = sx + plr[v26]._pxoff - plr[v26]._pAnimWidth2;
		if ( v25 == pcursplr )
			engine_417C99(165, v28, v27, (void *)plr[v26]._pAnimData, plr[v26]._pAnimFrame, plr[v26]._pAnimWidth, a5, 8);
		engine_417B83(v28, v27, (void *)plr[v26]._pAnimData, plr[v26]._pAnimFrame, plr[v26]._pAnimWidth, a5, 8);
		if ( some_flag && plr[v26]._peflag )
			town_draw_lower_screen((void *)(v29 - 64), xa - 1, a3 + 1, a4, a5, sx - 64, sy);
		v9 = v31;
	}
	if ( dFlags[0][v9] & 1 )
		scrollrt_452B2A(xa, a3, sx, sy, a5, 8, 0);
}
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC2: using guessed type char pcursplr;

//----- (0045EC49) --------------------------------------------------------
void __fastcall town_draw_lower(int x, int y, int sx, int sy, int a5, int a6, int some_flag)
{
	int v7; // esi
	int v8; // ebx
	int *v9; // edi
	short *v10; // eax
	int v11; // esi
	int v12; // eax
	int *v13; // ebx
	int v14; // edi
	short *v15; // edi
	int v16; // eax
	int v17; // eax
	int v18; // eax
	bool v19; // zf
	int *v20; // edi
	short *v21; // ebx
	int v22; // eax
	short *v23; // [esp+Ch] [ebp-10h]
	int v24; // [esp+Ch] [ebp-10h]
	char *a1; // [esp+10h] [ebp-Ch]
	char *a1a; // [esp+10h] [ebp-Ch]
	char *a1b; // [esp+10h] [ebp-Ch]
	signed int ya; // [esp+14h] [ebp-8h]
	signed int xa; // [esp+18h] [ebp-4h]
	signed int sxa; // [esp+24h] [ebp+8h]
	signed int sxb; // [esp+24h] [ebp+8h]
	signed int sxc; // [esp+24h] [ebp+8h]
	int a5a; // [esp+2Ch] [ebp+10h]

	ya = y;
	xa = x;
	if ( some_flag )
	{
		if ( y < 0 || y >= 112 || x < 0 || x >= 112 )
		{
			v7 = sx;
		}
		else
		{
			v7 = sx;
			level_cel_block = dPiece[0][y + 112 * x];
			if ( level_cel_block )
			{
				v8 = sy;
				v9 = &screen_y_times_768[sy];
				a1 = (char *)gpBuffer + *v9 + sx - 24544;
				sxa = 0;
				v10 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y) + 3];
				v23 = v10;
				do
				{
					if ( a6 <= sxa )
					{
						level_cel_block = (unsigned short)*v10;
						if ( level_cel_block )
							drawLowerScreen(a1);
					}
					a1 -= 24576;
					++sxa;
					v10 = v23 + 2;
					v23 += 2;
				}
				while ( sxa < 7 );
				if ( 2 * a6 + 2 < 8 )
					town_draw_low_towners((int)gpBuffer + *v9 + v7, xa, ya, a6, 2 * a6 + 2, v7, sy, 0);
				goto LABEL_16;
			}
		}
		town_clear_low_buf((int)gpBuffer + screen_y_times_768[sy] + v7);
		v8 = sy;
LABEL_16:
		++xa;
		--ya;
		v11 = v7 + 64;
		goto LABEL_18;
	}
	v11 = sx;
	v8 = sy;
LABEL_18:
	v12 = a5 - some_flag;
	if ( a5 - some_flag > 0 )
	{
		v13 = &screen_y_times_768[v8];
		v14 = 112 * xa;
		a5a = 112 * xa;
		v24 = v12;
		do
		{
			if ( ya >= 0 && ya < 112 && v14 >= 0 && v14 < 12544 && (level_cel_block = dPiece[0][v14 + ya]) != 0 )
			{
				a1a = (char *)gpBuffer + *v13 + v11 - 24576;
				sxb = 0;
				v15 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(xa, ya) + 3];
				do
				{
					if ( a6 <= sxb )
					{
						v16 = (unsigned short)*(v15 - 1);
						level_cel_block = (unsigned short)*(v15 - 1);
						if ( v16 )
							drawLowerScreen(a1a);
						v17 = (unsigned short)*v15;
						level_cel_block = (unsigned short)*v15;
						if ( v17 )
							drawLowerScreen(a1a + 32);
					}
					a1a -= 24576;
					++sxb;
					v15 += 2;
				}
				while ( sxb < 7 );
				v18 = 2 * a6 + 2;
				if ( v18 < 8 )
					town_draw_low_towners((int)gpBuffer + *v13 - 12288 * v18 + v11, xa, ya, a6, 2 * a6 + 2, v11, sy, 1);
				v14 = a5a;
			}
			else
			{
				town_clear_low_buf((int)gpBuffer + *v13 + v11);
			}
			++xa;
			v14 += 112;
			--ya;
			v11 += 64;
			v19 = v24-- == 1;
			a5a = v14;
		}
		while ( !v19 );
		v8 = sy;
	}
	if ( some_flag )
	{
		if ( ya >= 0 && ya < 112 && xa >= 0 && xa < 112 && (level_cel_block = dPiece[0][ya + 112 * xa]) != 0 )
		{
			v20 = &screen_y_times_768[v8];
			a1b = (char *)gpBuffer + *v20 + v11 - 24576;
			sxc = 0;
			v21 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(xa, ya) + 2];
			do
			{
				if ( a6 <= sxc )
				{
					v22 = (unsigned short)*v21;
					level_cel_block = (unsigned short)*v21;
					if ( v22 )
						drawLowerScreen(a1b);
				}
				a1b -= 24576;
				++sxc;
				v21 += 2;
			}
			while ( sxc < 7 );
			if ( 2 * a6 + 2 < 8 )
				town_draw_low_towners((int)gpBuffer + *v20 + v11, xa, ya, a6, 2 * a6 + 2, v11, sy, 0);
		}
		else
		{
			town_clear_low_buf((int)gpBuffer + screen_y_times_768[v8] + v11);
		}
	}
}
// 69CF14: using guessed type int level_cel_block;

//----- (0045EF8A) --------------------------------------------------------
void __fastcall town_draw_pieces(void *buffer, int x, int y, int a4, int dir, int sx, int sy)
{
	int v7; // ebx
	char *v8; // esi
	int v9; // edi
	int v10; // eax
	int v11; // eax
	void *buffera; // [esp+Ch] [ebp-8h]
	int *a1; // [esp+10h] [ebp-4h]

	v7 = x;
	buffera = buffer;
	a1 = (int *)buffer;
	v8 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(x, y);
	v9 = 0;
	do
	{
		if ( a4 >= v9 )
		{
			v10 = *(unsigned short *)&v8[4 * v9];
			level_cel_block = *(unsigned short *)&v8[4 * v9];
			if ( v10 )
				drawUpperScreen(a1);
			v11 = *(unsigned short *)&v8[4 * v9 + 2];
			level_cel_block = *(unsigned short *)&v8[4 * v9 + 2];
			if ( v11 )
				drawUpperScreen(a1 + 8);
		}
		a1 -= 6144;
		++v9;
	}
	while ( v9 < 7 );
	town_draw_towners(buffera, v7, y, a4, dir, sx, sy, 0);
}
// 69CF14: using guessed type int level_cel_block;

//----- (0045F013) --------------------------------------------------------
void __fastcall town_draw_towners(void *buffer, int x, int y, int a4, int dir, int sx, int sy, int some_flag)
{
	unsigned int v8; // edx
	int v9; // ebx
	char v10; // al
	char v11; // al
	int v12; // esi
	int v13; // edi
	int v14; // esi
	int v15; // edi
	int v16; // eax
	int v17; // eax
	int v18; // esi
	int v19; // edi
	char v20; // al
	int v21; // esi
	int v22; // ebx
	int v23; // edi
	char v24; // al
	char v25; // al
	int v26; // esi
	int v27; // ebx
	int v28; // edi
	char *v29; // [esp+Ch] [ebp-Ch]
	int xa; // [esp+10h] [ebp-8h]
	int v31; // [esp+14h] [ebp-4h]

	xa = x;
	v8 = 112 * x;
	v9 = v8 + y;
	v29 = (char *)buffer;
	v31 = v8 + y;
	v10 = dItem[v8 / 0x70][y];
	if ( v10 )
	{
		v11 = v10 - 1;
		v12 = v11;
		v13 = sx - items[v12]._iAnimXOff;
		if ( v11 == pcursitem )
			Cel_colour(
				181,
				v13,
				sy,
				(char *)items[v12].ItemFrame,
				items[v12]._iAnimFrame,
				items[v12]._iAnimWidth,
				0,
				dir);
		Cel_header(v13, sy, (char *)items[v12].ItemFrame, items[v12]._iAnimFrame, items[v12]._iAnimWidth, 0, dir);
	}
	if ( dFlags[0][v9] & 0x10 )
	{
		v14 = -1 - *(&dword_52D204 + v9);
		v15 = sx - towner[v14]._tAnimWidth2;
		if ( -1 - *(&dword_52D204 + v9) == *(_DWORD *)&pcursmonst )
			Cel_colour(
				166,
				v15,
				sy,
				(char *)towner[v14]._tAnimCel,
				towner[v14]._tAnimFrame,
				towner[v14]._tAnimWidth,
				0,
				dir);
		Cel_header(v15, sy, (char *)towner[v14]._tAnimCel, towner[v14]._tAnimFrame, towner[v14]._tAnimWidth, 0, dir);
	}
	v16 = dMonster[0][v9];
	if ( v16 > 0 )
	{
		v17 = v16 - 1;
		v18 = v17;
		v19 = sx - towner[v17]._tAnimWidth2;
		if ( v17 == *(_DWORD *)&pcursmonst )
			Cel_colour(
				166,
				v19,
				sy,
				(char *)towner[v18]._tAnimCel,
				towner[v18]._tAnimFrame,
				towner[v18]._tAnimWidth,
				0,
				dir);
		Cel_header(v19, sy, (char *)towner[v18]._tAnimCel, towner[v18]._tAnimFrame, towner[v18]._tAnimWidth, 0, dir);
	}
	if ( dFlags[0][v9] & 0x20 )
	{
		v20 = -1 - *((_BYTE *)&themeLoc[49].height + v9 + 3);
		v21 = v20;
		v22 = sy + plr[v21]._pyoff;
		v23 = sx + plr[v21]._pxoff - plr[v21]._pAnimWidth2;
		if ( v20 == pcursplr )
			engine_417847(
				165,
				v23,
				v22,
				(void *)plr[v21]._pAnimData,
				plr[v21]._pAnimFrame,
				plr[v21]._pAnimWidth,
				0,
				dir);
		engine_417745(v23, v22, (void *)plr[v21]._pAnimData, plr[v21]._pAnimFrame, plr[v21]._pAnimWidth, 0, dir);
		if ( some_flag && plr[v21]._peflag )
			town_draw_pieces(v29 - 64, xa - 1, y + 1, a4, dir, sx - 64, sy);
		v9 = v31;
	}
	if ( dFlags[0][v9] & 4 )
		scrollrt_452CC0(xa, y, sx, sy, 0, dir, 0);
	v24 = dPlayer[0][v9];
	if ( v24 > 0 )
	{
		v25 = v24 - 1;
		v26 = v25;
		v27 = sy + plr[v26]._pyoff;
		v28 = sx + plr[v26]._pxoff - plr[v26]._pAnimWidth2;
		if ( v25 == pcursplr )
			engine_417847(
				165,
				v28,
				v27,
				(void *)plr[v26]._pAnimData,
				plr[v26]._pAnimFrame,
				plr[v26]._pAnimWidth,
				0,
				dir);
		engine_417745(v28, v27, (void *)plr[v26]._pAnimData, plr[v26]._pAnimFrame, plr[v26]._pAnimWidth, 0, dir);
		if ( some_flag && plr[v26]._peflag )
			town_draw_pieces(v29 - 64, xa - 1, y + 1, a4, dir, sx - 64, sy);
		v9 = v31;
	}
	if ( dFlags[0][v9] & 1 )
		scrollrt_452994(xa, y, sx, sy, 0, dir, 0);
}
// 4B8CC0: using guessed type char pcursitem;
// 4B8CC2: using guessed type char pcursplr;

//----- (0045F323) --------------------------------------------------------
void __fastcall town_draw_screen(int x, int y, int sx, int sy, int a5, int a6, int some_flag)
{
	signed int v7; // ebx
	int v8; // esi
	int v9; // eax
	bool v10; // zf
	int v11; // eax
	short *v12; // ebx
	int v13; // eax
	int v14; // esi
	int v15; // edi
	int v16; // eax
	Screen *v17; // eax
	char *v18; // ebx
	char *v19; // edi
	int v20; // eax
	int v21; // eax
	int v22; // eax
	int v23; // eax
	char *v24; // edi
	char *v25; // ebx
	int v26; // eax
	int *a1; // [esp+Ch] [ebp-10h]
	int *a1a; // [esp+Ch] [ebp-10h]
	int dir; // [esp+10h] [ebp-Ch]
	int ya; // [esp+14h] [ebp-8h]
	signed int xa; // [esp+18h] [ebp-4h]
	signed int sxa; // [esp+24h] [ebp+8h]
	signed int sxb; // [esp+24h] [ebp+8h]
	signed int sxc; // [esp+24h] [ebp+8h]
	int a5a; // [esp+2Ch] [ebp+10h]

	xa = x;
	v7 = y;
	ya = y;
	dir = 2 * a6 + 2;
	if ( dir > 8 )
		dir = 8;
	if ( some_flag )
	{
		if ( y < 0 || y >= 112 || x < 0 || x >= 112 )
		{
			v11 = sy;
			v8 = sx;
		}
		else
		{
			v8 = sx;
			v9 = dPiece[0][y + 112 * x];
			level_cel_block = v9;
			v10 = v9 == 0;
			v11 = sy;
			if ( !v10 )
			{
				a1 = (int *)&gpBuffer->row_unused_1[0].col_unused_1[sx + 32 + screen_y_times_768[sy]];
				sxa = 0;
				v12 = &dpiece_defs_map_1[0][0][16 * gendung_41927A(x, y) + 1];
				do
				{
					if ( a6 >= sxa )
					{
						v13 = (unsigned short)*v12;
						level_cel_block = (unsigned short)*v12;
						if ( v13 )
							drawUpperScreen(a1);
					}
					a1 -= 6144;
					++sxa;
					v12 += 2;
				}
				while ( sxa < 7 );
				town_draw_towners((char *)gpBuffer + v8 + screen_y_times_768[sy], xa, ya, a6, dir, v8, sy, 0);
				v7 = ya;
				goto LABEL_17;
			}
		}
		town_clear_upper_buf((int)gpBuffer + screen_y_times_768[v11] + v8);
LABEL_17:
		++xa;
		ya = --v7;
		v14 = v8 + 64;
		goto LABEL_19;
	}
	v14 = sx;
LABEL_19:
	if ( a5 - some_flag > 0 )
	{
		a1a = (int *)(a5 - some_flag);
		v15 = 112 * xa;
		a5a = 112 * xa;
		do
		{
			if ( v7 < 0 || v7 >= 112 || v15 < 0 || v15 >= 12544 )
			{
				v17 = gpBuffer;
			}
			else
			{
				v16 = dPiece[0][v15 + v7];
				level_cel_block = v16;
				v10 = v16 == 0;
				v17 = gpBuffer;
				if ( !v10 )
				{
					v18 = (char *)gpBuffer + v14 + screen_y_times_768[sy];
					v19 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, ya);
					sxb = 0;
					do
					{
						if ( a6 >= sxb )
						{
							v20 = *(unsigned short *)&v19[4 * sxb];
							level_cel_block = *(unsigned short *)&v19[4 * sxb];
							if ( v20 )
								drawUpperScreen(v18);
							v21 = *(unsigned short *)&v19[4 * sxb + 2];
							level_cel_block = *(unsigned short *)&v19[4 * sxb + 2];
							if ( v21 )
								drawUpperScreen(v18 + 32);
						}
						v18 -= 24576;
						++sxb;
					}
					while ( sxb < 7 );
					town_draw_towners((char *)gpBuffer + v14 + screen_y_times_768[sy], xa, ya, a6, dir, v14, sy, 1);
					v15 = a5a;
					v7 = ya;
					goto LABEL_36;
				}
			}
			town_clear_upper_buf((int)v17 + v14 + screen_y_times_768[sy]);
LABEL_36:
			++xa;
			v15 += 112;
			--v7;
			v14 += 64;
			v10 = a1a == (int *)1;
			a1a = (int *)((char *)a1a - 1);
			a5a = v15;
			ya = v7;
		}
		while ( !v10 );
	}
	if ( some_flag )
	{
		if ( v7 < 0 || v7 >= 112 || xa < 0 || xa >= 112 )
		{
			v23 = sy;
		}
		else
		{
			v22 = dPiece[0][v7 + 112 * xa];
			level_cel_block = v22;
			v10 = v22 == 0;
			v23 = sy;
			if ( !v10 )
			{
				v24 = (char *)gpBuffer + v14 + screen_y_times_768[sy];
				v25 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(xa, v7);
				sxc = 0;
				do
				{
					if ( a6 >= sxc )
					{
						v26 = *(unsigned short *)&v25[4 * sxc];
						level_cel_block = *(unsigned short *)&v25[4 * sxc];
						if ( v26 )
							drawUpperScreen(v24);
					}
					v24 -= 24576;
					++sxc;
				}
				while ( sxc < 7 );
				town_draw_towners((char *)gpBuffer + v14 + screen_y_times_768[sy], xa, ya, a6, dir, v14, sy, 0);
				return;
			}
		}
		town_clear_upper_buf((int)gpBuffer + screen_y_times_768[v23] + v14);
	}
}
// 69CF14: using guessed type int level_cel_block;

//----- (0045F65D) --------------------------------------------------------
void __fastcall T_DrawGame(int x, int y)
{
	int v2; // esi
	int v3; // edi
	int v4; // ebx
	int v5; // ebx
	int v6; // esi
	int v7; // ebx
	int v8; // esi
	int v9; // ebx
	int v10; // esi
	signed int v11; // [esp+Ch] [ebp-10h]
	signed int a6; // [esp+10h] [ebp-Ch]
	signed int a6a; // [esp+10h] [ebp-Ch]
	signed int a5; // [esp+14h] [ebp-8h]
	int ya; // [esp+18h] [ebp-4h]

	v2 = ScrollInfo._sxoff + 64;
	v3 = x - 10;
	ya = y - 1;
	v4 = ScrollInfo._syoff + 175;
	dword_5C2FF8 = 10;
	a5 = 10;
	scr_pix_width = 640;
	scr_pix_height = 352;
	dword_5C2FFC = 11;
	v11 = 5;
	if ( chrflag || questlog )
	{
		ya = y - 3;
		v3 += 2;
		v2 = ScrollInfo._sxoff + 352;
		a5 = 6;
	}
	if ( invflag || sbookflag )
	{
		ya -= 2;
		v3 += 2;
		v2 -= 32;
		a5 = 6;
	}
	switch ( ScrollInfo._sdir )
	{
		case DIR_SW:
			v4 = ScrollInfo._syoff + 143;
			--v3;
			--ya;
			goto LABEL_15;
		case DIR_W:
			v4 = ScrollInfo._syoff + 143;
			--v3;
			--ya;
			goto LABEL_14;
		case DIR_NW:
			goto LABEL_12;
		case DIR_N:
			goto LABEL_14;
		case DIR_NE:
			goto LABEL_15;
		case DIR_E:
			v2 -= 64;
			--v3;
			++ya;
			goto LABEL_14;
		case DIR_SE:
			v2 -= 64;
			--v3;
			++ya;
LABEL_12:
			++a5;
			break;
		case DIR_OMNI:
			v2 -= 64;
			v4 = ScrollInfo._syoff + 143;
			v3 -= 2;
LABEL_14:
			++a5;
LABEL_15:
			v11 = 6;
			break;
		default:
			break;
	}
	a6 = 0;
	screen_buf_end = (int)gpBuffer + screen_y_times_768[160];
	do
	{
		town_draw_screen(v3, ya++, v2, v4, a5, a6, 0);
		v5 = v4 + 16;
		v6 = v2 - 32;
		town_draw_screen(v3++, ya, v6, v5, a5, a6, 1);
		v2 = v6 + 32;
		v4 = v5 + 16;
		++a6;
	}
	while ( a6 < 7 );
	screen_buf_end = (int)gpBuffer + screen_y_times_768[512];
	if ( v11 > 0 )
	{
		do
		{
			town_draw_low_pieces(v3, ya++, v2, v4, a5, 0);
			v7 = v4 + 16;
			v8 = v2 - 32;
			town_draw_low_pieces(v3++, ya, v8, v7, a5, 1);
			v2 = v8 + 32;
			v4 = v7 + 16;
			--v11;
		}
		while ( v11 );
	}
	a6a = 0;
	do
	{
		town_draw_lower(v3, ya++, v2, v4, a5, a6a, 0);
		v9 = v4 + 16;
		v10 = v2 - 32;
		town_draw_lower(v3++, ya, v10, v9, a5, a6a, 1);
		v2 = v10 + 32;
		v4 = v9 + 16;
		++a6a;
	}
	while ( a6a < 7 );
}
// 4B8968: using guessed type int sbookflag;
// 5C2FF8: using guessed type int dword_5C2FF8;
// 5C2FFC: using guessed type int dword_5C2FFC;
// 5C3000: using guessed type int scr_pix_width;
// 5C3004: using guessed type int scr_pix_height;
// 69BD04: using guessed type int questlog;
// 69CF0C: using guessed type int screen_buf_end;

//----- (0045F856) --------------------------------------------------------
void __fastcall T_DrawZoom(int x, int y)
{
	int v2; // edi
	int v3; // ebx
	int v4; // esi
	int v5; // esi
	int v6; // edi
	int v7; // esi
	int v8; // edi
	int v9; // esi
	int v10; // edi
	_WORD *v11; // edi
	char *v12; // esi
	char *v13; // ebx
	signed int v14; // edx
	signed int v15; // ecx
	short v16; // ax
	int v17; // eax
	signed int v18; // [esp+Ch] [ebp-10h]
	signed int v19; // [esp+Ch] [ebp-10h]
	signed int a6; // [esp+10h] [ebp-Ch]
	signed int a6a; // [esp+10h] [ebp-Ch]
	int a6b; // [esp+10h] [ebp-Ch]
	signed int a5; // [esp+14h] [ebp-8h]
	int a5a; // [esp+14h] [ebp-8h]
	int ya; // [esp+18h] [ebp-4h]

	v18 = 0;
	v2 = ScrollInfo._sxoff + 64;
	dword_5C2FF8 = 6;
	dword_5C2FFC = 6;
	v3 = x - 6;
	a5 = 6;
	v4 = ScrollInfo._syoff + 143;
	ya = y - 1;
	scr_pix_width = 384;
	scr_pix_height = 192;
	switch ( ScrollInfo._sdir )
	{
		case DIR_SW:
			v4 = ScrollInfo._syoff + 111;
			v3 = x - 7;
			ya = y - 2;
			goto LABEL_9;
		case DIR_W:
			v4 = ScrollInfo._syoff + 111;
			v3 = x - 7;
			ya = y - 2;
			goto LABEL_8;
		case DIR_NW:
			goto LABEL_6;
		case DIR_N:
			goto LABEL_8;
		case DIR_NE:
			goto LABEL_9;
		case DIR_E:
			v2 = ScrollInfo._sxoff;
			v3 = x - 7;
			ya = y;
			goto LABEL_8;
		case DIR_SE:
			v2 = ScrollInfo._sxoff;
			v3 = x - 7;
			ya = y;
LABEL_6:
			a5 = 7;
			break;
		case DIR_OMNI:
			v2 = ScrollInfo._sxoff;
			v4 = ScrollInfo._syoff + 111;
			v3 = x - 8;
LABEL_8:
			a5 = 7;
LABEL_9:
			v18 = 1;
			break;
		default:
			break;
	}
	a6 = 0;
	screen_buf_end = (int)gpBuffer + screen_y_times_768[143];
	do
	{
		town_draw_screen(v3, ya++, v2, v4, a5, a6, 0);
		v5 = v4 + 16;
		v6 = v2 - 32;
		town_draw_screen(v3++, ya, v6, v5, a5, a6, 1);
		v2 = v6 + 32;
		v4 = v5 + 16;
		++a6;
	}
	while ( a6 < 7 );
	screen_buf_end = (int)gpBuffer + screen_y_times_768[320];
	if ( v18 > 0 )
	{
		do
		{
			town_draw_low_pieces(v3, ya++, v2, v4, a5, 0);
			v7 = v4 + 16;
			v8 = v2 - 32;
			town_draw_low_pieces(v3++, ya, v8, v7, a5, 1);
			v2 = v8 + 32;
			v4 = v7 + 16;
			--v18;
		}
		while ( v18 );
	}
	a6a = 0;
	do
	{
		town_draw_lower(v3, ya++, v2, v4, a5, a6a, 0);
		v9 = v4 + 16;
		v10 = v2 - 32;
		town_draw_lower(v3++, ya, v10, v9, a5, a6a, 1);
		v2 = v10 + 32;
		v4 = v9 + 16;
		++a6a;
	}
	while ( a6a < 7 );
	if ( chrflag || questlog )
	{
		a5a = 392064;
		goto LABEL_23;
	}
	if ( invflag || sbookflag )
	{
		a5a = 391744;
LABEL_23:
		a6b = 245168;
		v19 = 160;
		goto LABEL_24;
	}
	a6b = 245088;
	a5a = 391744;
	v19 = 320;
LABEL_24:
	v11 = (_WORD *)((char *)gpBuffer + a5a);
	v12 = (char *)gpBuffer + a6b;
	v13 = &gpBuffer->row_unused_1[1].col_unused_1[a5a];
	v14 = 176;
	do
	{
		v15 = v19;
		do
		{
			_LOBYTE(v16) = *v12++;
			_HIBYTE(v16) = v16;
			*v11 = v16;
			*(_WORD *)v13 = v16;
			++v11;
			v13 += 2;
			--v15;
		}
		while ( v15 );
		v12 += -v19 - 768;
		v17 = 2 * (v19 + 768);
		v13 -= v17;
		v11 = (_WORD *)((char *)v11 - v17);
		--v14;
	}
	while ( v14 );
}
// 4B8968: using guessed type int sbookflag;
// 5C2FF8: using guessed type int dword_5C2FF8;
// 5C2FFC: using guessed type int dword_5C2FFC;
// 5C3000: using guessed type int scr_pix_width;
// 5C3004: using guessed type int scr_pix_height;
// 69BD04: using guessed type int questlog;
// 69CF0C: using guessed type int screen_buf_end;

//----- (0045FAAB) --------------------------------------------------------
void __fastcall T_DrawView(int StartX, int StartY)
{
	light_table_index = 0;
	cel_transparency_active = 0;
	if ( zoomflag )
		T_DrawGame(StartX, StartY);
	else
		T_DrawZoom(StartX, StartY);
	if ( *(_DWORD *)&automapflag )
		DrawAutomap();
	if ( stextflag && !qtextflag )
		DrawSText();
	if ( invflag )
	{
		DrawInv();
	}
	else if ( sbookflag )
	{
		DrawSpellBook();
	}
	DrawDurIcon();
	if ( chrflag )
	{
		DrawChr();
	}
	else if ( questlog )
	{
		DrawQuestLog();
	}
	else if ( plr[myplr]._pStatPts && !spselflag )
	{
		DrawLevelUpIcon();
	}
	if ( uitemflag )
		DrawUniqueInfo();
	if ( qtextflag )
		DrawQText();
	if ( spselflag )
		DrawSpellList();
	if ( dropGoldFlag )
		DrawGoldSplit(dropGoldValue);
	if ( helpflag )
		DrawHelp();
	if ( msgflag )
		DrawDiabloMsg();
	if ( PauseMode && !*(_DWORD *)&deathflag )
		gmenu_draw_pause();
	DrawPlrMsg();
	gmenu_draw();
	doom_draw();
	DrawInfoBox();
	DrawLifeFlask();
	DrawManaFlask();
}
// 4B84DC: using guessed type int dropGoldFlag;
// 4B8968: using guessed type int sbookflag;
// 4B8C98: using guessed type int spselflag;
// 52569C: using guessed type int zoomflag;
// 525740: using guessed type int PauseMode;
// 52B9F1: using guessed type char msgflag;
// 646D00: using guessed type char qtextflag;
// 69BD04: using guessed type int questlog;
// 69BEF8: using guessed type int light_table_index;
// 69CF94: using guessed type int cel_transparency_active;
// 6AA705: using guessed type char stextflag;

//----- (0045FBD7) --------------------------------------------------------
void __cdecl town_get_draw_size()
{
	int (*v0)[112]; // ebx
	int v1; // ebp
	int v2; // esi
	char *v3; // edi
	int v4; // ecx
	signed int v5; // eax
	int (*v6)[112]; // [esp+10h] [ebp-8h]
	int y; // [esp+14h] [ebp-4h]

	y = 0;
	v6 = dPiece;
	do
	{
		v0 = v6;
		v1 = 0;
		do
		{
			v2 = (*v0)[0];
			v3 = (char *)dpiece_defs_map_1 + 32 * gendung_41927A(v1, y);
			if ( v2 )
			{
				v4 = 32 * v2 + *(_DWORD *)&dpiece_defs[0].blocks - 32;
				v5 = 0;
				do
				{
					*(_WORD *)&v3[2 * v5] = *(_WORD *)(v4 + 2 * ((v5 & 1) - (v5 & 0xE)) + 28);
					++v5;
				}
				while ( v5 < 16 );
			}
			else
			{
				memset(v3, 0, 0x20u);
			}
			++v1;
			++v0;
		}
		while ( v1 < 112 );
		v6 = (int (*)[112])((char *)v6 + 4);
		++y;
	}
	while ( (signed int)v6 < (signed int)dPiece[1] );
	if ( zoomflag )
	{
		scr_pix_width = 640;
		scr_pix_height = 352;
		dword_5C2FF8 = 10;
		dword_5C2FFC = 11;
	}
	else
	{
		scr_pix_width = 384;
		scr_pix_height = 224;
		dword_5C2FF8 = 6;
		dword_5C2FFC = 7;
	}
}
// 52569C: using guessed type int zoomflag;
// 5C2FF8: using guessed type int dword_5C2FF8;
// 5C2FFC: using guessed type int dword_5C2FFC;
// 5C3000: using guessed type int scr_pix_width;
// 5C3004: using guessed type int scr_pix_height;

//----- (0045FCBF) --------------------------------------------------------
void __fastcall T_FillSector(unsigned char *P3Tiles, unsigned char *pSector, int xi, int yi, int w, int h, int AddSec)
{
	int v7; // ebx
	int v8; // edx
	int v9; // edi
	int *v10; // ecx
	int v11; // eax
	unsigned char *v12; // esi
	unsigned short v13; // ax
	int v14; // eax
	int v15; // [esp+4h] [ebp-14h]
	int v16; // [esp+8h] [ebp-10h]
	unsigned char *v17; // [esp+Ch] [ebp-Ch]
	unsigned char *v18; // [esp+10h] [ebp-8h]
	signed int v19; // [esp+14h] [ebp-4h]
	int a4; // [esp+24h] [ebp+Ch]
	int a6; // [esp+2Ch] [ebp+14h]

	v7 = h;
	v17 = pSector;
	v8 = yi;
	v18 = P3Tiles;
	v19 = 4;
	if ( h > 0 )
	{
		do
		{
			v9 = w;
			if ( w > 0 )
			{
				v10 = &dPiece[1][v8 + 112 * xi];
				do
				{
					v11 = *(unsigned short *)&v17[v19];
					if ( (_WORD)v11 )
					{
						v12 = &v18[8 * (v11 - 1)];
						v13 = *(_WORD *)v12;
						v12 += 2;
						v14 = v13 + 1;
						a4 = v14;
						_LOWORD(v14) = *(_WORD *)v12;
						v12 += 2;
						a6 = ++v14;
						_LOWORD(v14) = *(_WORD *)v12;
						v16 = ++v14;
						_LOWORD(v14) = *((_WORD *)v12 + 1);
						v15 = v14 + 1;
					}
					else
					{
						a4 = 0;
						a6 = 0;
						v16 = 0;
						v15 = 0;
					}
					v19 += 2;
					*(v10 - 112) = a4;
					*v10 = a6;
					*(v10 - 111) = v16;
					v10[1] = v15;
					v10 += 224;
					--v9;
				}
				while ( v9 );
			}
			v8 += 2;
			--v7;
		}
		while ( v7 );
	}
}

//----- (0045FD75) --------------------------------------------------------
void __fastcall T_FillTile(unsigned char *P3Tiles, int xx, int yy, int t)
{
	unsigned char *v4; // esi
	unsigned short v5; // ax
	int v6; // eax
	int v7; // ST10_4
	int v8; // ST0C_4
	int v9; // ST08_4
	int v10; // edx

	v4 = &P3Tiles[8 * (t - 1)];
	v5 = *(_WORD *)v4;
	v4 += 2;
	v6 = v5 + 1;
	v7 = v6;
	_LOWORD(v6) = *(_WORD *)v4;
	v4 += 2;
	v8 = ++v6;
	_LOWORD(v6) = *(_WORD *)v4;
	v9 = ++v6;
	_LOWORD(v6) = *((_WORD *)v4 + 1);
	v10 = yy + 112 * xx;
	dPiece[0][v10] = v7;
	dPiece[1][v10] = v8;
	dPiece[0][v10 + 1] = v9;
	dPiece[1][v10 + 1] = v6 + 1;
}

//----- (0045FDE6) --------------------------------------------------------
void __cdecl T_Pass3()
{
	int v0; // edi
	int *v1; // esi
	int *v2; // eax
	signed int v3; // ecx
	int v4; // ST10_4
	unsigned char *v5; // esi
	unsigned char *v6; // edi
	unsigned char *v7; // edi
	unsigned char *v8; // edi
	unsigned char *v9; // edi
	int v10; // eax
	int v11; // ecx
	unsigned char *v12; // ecx
	int v13; // edi
	int v14; // eax
	void *v15; // ecx
	int v16; // [esp-10h] [ebp-14h]
	int v17; // [esp-Ch] [ebp-10h]
	int v18; // [esp-8h] [ebp-Ch]

	v1 = dPiece[1];
	do
	{
		v2 = v1;
		v3 = 56;
		do
		{
			*(v2 - 112) = 0;
			*v2 = 0;
			*(v2 - 111) = 0;
			v2[1] = 0;
			v2 += 224;
			--v3;
		}
		while ( v3 );
		v1 += 2;
	}
	while ( (signed int)v1 < (signed int)dPiece[2] );
	v4 = v0;
	v5 = LoadFileInMem("Levels\\TownData\\Town.TIL", 0);
	v6 = LoadFileInMem("Levels\\TownData\\Sector1s.DUN", 0);
	T_FillSector(v5, v6, 46, 46, 25, 25, v4);
	mem_free_dbg(v6);
	v7 = LoadFileInMem("Levels\\TownData\\Sector2s.DUN", 0);
	T_FillSector(v5, v7, 46, 0, 25, 23, v16);
	mem_free_dbg(v7);
	v8 = LoadFileInMem("Levels\\TownData\\Sector3s.DUN", 0);
	T_FillSector(v5, v8, 0, 46, 23, 25, v17);
	mem_free_dbg(v8);
	v9 = LoadFileInMem("Levels\\TownData\\Sector4s.DUN", 0);
	T_FillSector(v5, v9, 0, 0, 23, 23, v18);
	mem_free_dbg(v9);
	if ( gbMaxPlayers == 1 )
	{
		v10 = myplr;
		if ( !(plr[myplr].pTownWarps & 1) )
		{
			T_FillTile(v5, 48, 20, 320);
			v10 = myplr;
		}
		v11 = 21720 * v10;
		if ( !(plr[v10].pTownWarps & 2) )
		{
			T_FillTile(v5, 16, 68, 332);
			T_FillTile(v12, 16, 70, 331);
			v10 = myplr;
		}
		if ( !(plr[v10].pTownWarps & 4) )
		{
			v13 = 36;
			do
			{
				_LOBYTE(v11) = 0;
				v14 = random(v11, 4);
				T_FillTile(v5, v13++, 78, v14 + 1);
			}
			while ( v13 < 46 );
		}
	}
	if ( quests[13]._qactive != 3 && quests[13]._qactive )
		T_FillTile(v5, 60, 70, 342);
	else
		T_FillTile(v5, 60, 70, 71);
	mem_free_dbg(v15);
}
// 45FDE6: could not find valid save-restore pair for edi
// 679660: using guessed type char gbMaxPlayers;

//----- (0045FF83) --------------------------------------------------------
void __fastcall CreateTown(int entry)
{
	int v1; // edi
	int (*v2)[112]; // esi
	_BYTE *v3; // eax
	int (*v4)[112]; // edx
	signed int v5; // ebp
	int v6; // ecx

	v1 = 0;
	dminx = 10;
	dminy = 10;
	dmaxx = 84;
	dmaxy = 84;
	if ( entry )
	{
		if ( entry == 1 )
		{
			ViewX = 25;
			ViewY = 31;
		}
		else if ( entry == 7 )
		{
			if ( TWarpFrom == 5 )
			{
				ViewX = 49;
				ViewY = 22;
			}
			if ( TWarpFrom == 9 )
			{
				ViewX = 18;
				ViewY = 69;
			}
			if ( TWarpFrom == 13 )
			{
				ViewX = 41;
				ViewY = 81;
			}
		}
	}
	else
	{
		ViewX = 75;
		ViewY = 68;
	}
	T_Pass3();
	memset(dTransVal, 0, 0x3100u);
	memset(dFlags, 0, 0x3100u);
	memset(dPlayer, 0, 0x3100u);
	memset(dMonster, 0, 0xC400u);
	memset(dObject, 0, 0x3100u);
	memset(dItem, 0, 0x3100u);
	memset(dArch, 0, 0x3100u);
	v2 = dPiece;
	do
	{
		v3 = (unsigned char *)dArch + v1;
		v4 = v2;
		v5 = 112;
		do
		{
			v6 = (*v4)[0];
			if ( (*v4)[0] == 360 )
			{
				*v3 = 1;
			}
			else
			{
				switch ( v6 )
				{
					case 358:
						*v3 = 2;
						break;
					case 129:
						*v3 = 6;
						break;
					case 130:
						*v3 = 7;
						break;
					case 128:
						*v3 = 8;
						break;
					case 117:
						*v3 = 9;
						break;
					case 157:
						*v3 = 10;
						break;
					case 158:
						*v3 = 11;
						break;
					case 156:
						*v3 = 12;
						break;
					case 162:
						*v3 = 13;
						break;
					case 160:
						*v3 = 14;
						break;
					case 214:
						*v3 = 15;
						break;
					case 212:
						*v3 = 16;
						break;
					case 217:
						*v3 = 17;
						break;
					case 216:
						*v3 = 18;
						break;
				}
			}
			++v4;
			v3 += 112;
			--v5;
		}
		while ( v5 );
		v2 = (int (*)[112])((char *)v2 + 4);
		++v1;
	}
	while ( (signed int)v2 < (signed int)dPiece[1] );
	town_get_draw_size();
}
// 5CF328: using guessed type int dmaxx;
// 5CF32C: using guessed type int dmaxy;
// 5D2458: using guessed type int dminx;
// 5D245C: using guessed type int dminy;
// 6ABB30: using guessed type int TWarpFrom;

//----- (0046019B) --------------------------------------------------------
int __fastcall GetActiveTowner(int towner_id)
{
	int result; // eax
	int *v2; // esi

	result = 0;
	if ( numtowners <= 0 )
		return -1;
	v2 = &towner[0]._ttype;
	while ( *v2 != towner_id )
	{
		++result;
		v2 += 58;
		if ( result >= numtowners )
			return -1;
	}
	return result;
}

//----- (004601C1) --------------------------------------------------------
void __fastcall SetTownerGPtrs(void *towner_cel, void **cel_from_direction)
{
	void **v2; // esi
	signed int v3; // edx
	char *v4; // eax
	signed int v5; // [esp+Ch] [ebp-4h]

	v5 = 0;
	v2 = cel_from_direction;
	do
	{
		v3 = v5;
		v4 = (char *)towner_cel + *((_DWORD *)towner_cel + v5++);
		v2[v3] = v4;
	}
	while ( v5 < 8 );
}

//----- (004601FB) --------------------------------------------------------
void __fastcall NewTownerAnim(int tnum, void *pAnim, int numFrames, int Delay)
{
	int v4; // ecx

	v4 = tnum;
	towner[v4]._tAnimCnt = 0;
	towner[v4]._tAnimLen = numFrames;
	towner[v4]._tAnimCel = pAnim;
	towner[v4]._tAnimFrame = 1;
	towner[v4]._tAnimDelay = Delay;
}

//----- (0046022F) --------------------------------------------------------
void __fastcall InitTownerInfo(int i, int w, bool sel, int t, int x, int y, int ao, int tp)
{
	int v8; // ebx
	int v9; // esi
	int v10; // edi

	v8 = i;
	v9 = i;
	v10 = w;
	memset(&towner[i], 0, 0xE8u);
	towner[v9]._tSelFlag = sel;
	towner[v9]._ttype = t;
	towner[v9]._tx = x;
	towner[v9]._tMsgSaid = 0;
	towner[v9]._tAnimWidth = v10;
	towner[v9]._tAnimWidth2 = (v10 - 64) >> 1;
	towner[v9]._ty = y;
	dMonster[0][y + 112 * x] = v8 + 1;
	_LOBYTE(towner[v9]._tAnimOrder) = ao;
	towner[v9]._tTenPer = tp;
	towner[v9]._tSeed = GetRndSeed();
}

//----- (004602C4) --------------------------------------------------------
void __fastcall InitQstSnds(int towner_num)
{
	int v1; // eax
	_BYTE *v2; // ecx
	char *v3; // esi
	QuestTalkData *v4; // eax
	bool v5; // zf

	v1 = towner_num;
	if ( boyloadflag )
		v1 = towner_num + 1;
	v2 = (unsigned char *)&towner[towner_num].qsts[0]._qstmsgact;
	v3 = &quests[0]._qtype;
	v4 = &Qtalklist[v1];
	do
	{
		v5 = v4->_qinfra == -1;
		*(v2 - 2) = *v3;
		*(v2 - 1) = v4->_qinfra;
		*v2 = !v5;
		v3 += 24;
		v4 = (QuestTalkData *)((char *)v4 + 4);
		v2 += 3;
	}
	while ( (signed int)v3 < (signed int)&qline + 1 );
}
// 69BE90: using guessed type int qline;
// 6AAC2C: using guessed type int boyloadflag;

//----- (00460311) --------------------------------------------------------
void __cdecl InitSmith()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // eax
	signed int v3; // ecx
	int v4; // ecx

	InitTownerInfo(numtowners, 96, 1, 0, 62, 63, 0, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Smith\\SmithN.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	v4 = numtowners;
	towner[v1]._tNFrames = 16;
	NewTownerAnim(v4, (void *)towner[v1]._tNAnim[1], 16, 3);
	strcpy(towner[v1]._tName, "Griswold the Blacksmith");
	++numtowners;
}

//----- (004603A0) --------------------------------------------------------
void __cdecl InitBarOwner()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // eax
	signed int v3; // ecx
	int v4; // ecx

	unused_6AAC28 = 0;
	InitTownerInfo(numtowners, 96, 1, 3, 55, 62, 3, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TwnF\\TwnFN.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	v4 = numtowners;
	towner[v1]._tNFrames = 16;
	NewTownerAnim(v4, (void *)towner[v1]._tNAnim[1], 16, 3);
	strcpy(towner[v1]._tName, "Ogden the Tavern owner");
	++numtowners;
}
// 6AAC28: using guessed type int unused_6AAC28;

//----- (00460436) --------------------------------------------------------
void __cdecl InitTownDead()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // eax
	signed int v3; // ecx
	int v4; // ecx

	InitTownerInfo(numtowners, 96, 1, 2, 24, 32, -1, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Butch\\Deadguy.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	v4 = numtowners;
	towner[v1]._tNFrames = 8;
	NewTownerAnim(v4, (void *)towner[v1]._tNAnim[4], 8, 6);
	strcpy(towner[v1]._tName, "Wounded Townsman");
	++numtowners;
}

//----- (004604C6) --------------------------------------------------------
void __cdecl InitWitch()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // ecx
	signed int v3; // edx

	InitTownerInfo(numtowners, 96, 1, 6, 80, 20, 5, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TownWmn1\\Witch.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	towner[v1]._tNFrames = 19;
	NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 19, 6);
	strcpy(towner[v1]._tName, "Adria the Witch");
	++numtowners;
}

//----- (00460555) --------------------------------------------------------
void __cdecl InitBarmaid()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // ecx
	signed int v3; // edx

	InitTownerInfo(numtowners, 96, 1, 7, 43, 66, -1, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TownWmn1\\WmnN.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	towner[v1]._tNFrames = 18;
	NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 18, 6);
	strcpy(towner[v1]._tName, "Gillian the Barmaid");
	++numtowners;
}

//----- (004605E4) --------------------------------------------------------
void __cdecl InitBoy()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // ecx
	signed int v3; // edx

	boyloadflag = 1;
	InitTownerInfo(numtowners, 96, 1, 8, 11, 53, -1, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\TownBoy\\PegKid1.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	towner[v1]._tNFrames = 20;
	NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 20, 6);
	strcpy(towner[v1]._tName, "Wirt the Peg-legged boy");
	++numtowners;
}
// 6AAC2C: using guessed type int boyloadflag;

//----- (0046067A) --------------------------------------------------------
void __cdecl InitHealer()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // eax
	signed int v3; // ecx
	int v4; // ecx

	InitTownerInfo(numtowners, 96, 1, 1, 55, 79, 1, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Healer\\Healer.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	v4 = numtowners;
	towner[v1]._tNFrames = 20;
	NewTownerAnim(v4, (void *)towner[v1]._tNAnim[7], 20, 6);
	strcpy(towner[v1]._tName, "Pepin the Healer");
	++numtowners;
}

//----- (00460709) --------------------------------------------------------
void __cdecl InitTeller()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // ecx
	signed int v3; // edx

	InitTownerInfo(numtowners, 96, 1, 4, 62, 71, 2, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Strytell\\Strytell.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	towner[v1]._tNFrames = 25;
	NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 25, 3);
	strcpy(towner[v1]._tName, "Cain the Elder");
	++numtowners;
}

//----- (00460798) --------------------------------------------------------
void __cdecl InitDrunk()
{
	int v0; // esi
	int v1; // esi
	_DWORD *v2; // ecx
	signed int v3; // edx

	InitTownerInfo(numtowners, 96, 1, 5, 71, 84, 4, 10);
	v0 = numtowners;
	InitQstSnds(numtowners);
	v1 = v0;
	towner[v1]._tNData = (char *)LoadFileInMem("Towners\\Drunk\\TwnDrunk.CEL", 0);
	v2 = (unsigned int *)towner[v1]._tNAnim;
	v3 = 8;
	do
	{
		*v2 = (unsigned int)towner[v1]._tNData;
		++v2;
		--v3;
	}
	while ( v3 );
	towner[v1]._tNFrames = 18;
	NewTownerAnim(numtowners, (void *)towner[v1]._tNAnim[0], 18, 3);
	strcpy(towner[v1]._tName, "Farnham the Drunk");
	++numtowners;
}

//----- (00460827) --------------------------------------------------------
void __cdecl InitCows()
{
	unsigned char *v0; // eax
	int v1; // ecx
	signed int v2; // ebx
	int v3; // esi
	int v4; // ebp
	int v5; // eax
	void **v6; // ecx
	int v7; // edi
	int v8; // ecx
	int v9; // edx
	int v10; // eax
	int v11; // ecx
	_DWORD *v12; // esi
	int v13; // edx
	_DWORD *v14; // esi
	_DWORD *v15; // eax
	int v16; // [esp+10h] [ebp-4h]

	v0 = LoadFileInMem("Towners\\Animals\\Cow.CEL", 0);
	v1 = numtowners;
	pCowCels = v0;
	v2 = 0;
	do
	{
		v3 = TownCowX[v2];
		v4 = TownCowDir[v2];
		v16 = TownCowY[v2];
		InitTownerInfo(v1, 128, 0, 9, TownCowX[v2], v16, -1, 10);
		v5 = numtowners;
		v6 = (void **)&towner[numtowners]._tNData;
		*v6 = pCowCels;
		SetTownerGPtrs(*v6, (void **)towner[v5]._tNAnim);
		v7 = numtowners;
		towner[numtowners]._tNFrames = 12;
		NewTownerAnim(v7, (void *)towner[0]._tNAnim[v4 + 58 * v7], 12, 3);
		v7 *= 232;
		_LOBYTE(v8) = 0;
		*(int *)((char *)&towner[0]._tAnimFrame + v7) = random(v8, 11) + 1;
		*(int *)((char *)&towner[0]._tSelFlag + v7) = 1;
		strcpy(&towner[0]._tName[v7], "Cow");
		v9 = v3 + cowoffx[v4];
		v10 = v16 + cowoffy[v4];
		v11 = numtowners;
		v12 = (_DWORD *)((char *)dMonster + 4 * (v10 + 112 * v3));
		if ( !*v12 )
			*v12 = -1 - numtowners;
		v13 = 112 * v9;
		v14 = (_DWORD *)((char *)dMonster + 4 * (v13 + v16));
		if ( !*v14 )
			*v14 = -1 - v11;
		v15 = (_DWORD *)((char *)dMonster + 4 * (v10 + v13));
		if ( !*v15 )
			*v15 = -1 - v11;
		++v2;
		v1 = v11 + 1;
		numtowners = v1;
	}
	while ( v2 < 3 );
}
// 6AAC2C: using guessed type int boyloadflag;

//----- (00460976) --------------------------------------------------------
void __cdecl InitTowners()
{
	numtowners = 0;
	boyloadflag = 0;
	InitSmith();
	InitHealer();
	if ( quests[6]._qactive && quests[6]._qactive != 3 )
		InitTownDead();
	InitBarOwner();
	InitTeller();
	InitDrunk();
	InitWitch();
	InitBarmaid();
	InitBoy();
	InitCows();
}
// 6AAC2C: using guessed type int boyloadflag;

//----- (004609C3) --------------------------------------------------------
void __cdecl FreeTownerGFX()
{
	void **v0; // esi
	void *v1; // ecx
	void *v2; // ecx

	v0 = (void **)&towner[0]._tNData;
	do
	{
		v1 = *v0;
		if ( *v0 == pCowCels )
		{
			*v0 = 0;
		}
		else if ( v1 )
		{
			*v0 = 0;
			mem_free_dbg(v1);
		}
		v0 += 58;
	}
	while ( (signed int)v0 < (signed int)&dword_6ABB9C );
	v2 = pCowCels;
	pCowCels = 0;
	mem_free_dbg(v2);
}
// 6ABB9C: using guessed type int dword_6ABB9C;

//----- (00460A05) --------------------------------------------------------
void __fastcall TownCtrlMsg(int towner_num)
{
	int v1; // esi
	int v2; // edi
	int v3; // ebx
	int v4; // eax

	v1 = towner_num;
	if ( towner[towner_num]._tbtcnt )
	{
		v2 = towner[v1]._tVar1;
		v3 = abs(towner[v1]._tx - plr[v2].WorldX);
		v4 = abs(towner[v1]._ty - plr[v2].WorldY);
		if ( v3 >= 2 || v4 >= 2 )
			towner[v1]._tbtcnt = 0;
		if ( !towner[v1]._tbtcnt )
		{
			qtextflag = 0;
			sfx_stop();
		}
	}
}
// 646D00: using guessed type char qtextflag;

//----- (00460A78) --------------------------------------------------------
void __cdecl TownBlackSmith()
{
	int v0; // eax

	v0 = GetActiveTowner(0);
	TownCtrlMsg(v0);
}

//----- (00460A86) --------------------------------------------------------
void __cdecl TownBarOwner()
{
	int v0; // eax

	v0 = GetActiveTowner(TOWN_TAVERN);
	TownCtrlMsg(v0);
}

//----- (00460A95) --------------------------------------------------------
void __cdecl TownDead()
{
	int v0; // esi
	int v1; // eax

	v0 = GetActiveTowner(TOWN_DEADGUY);
	TownCtrlMsg(v0);
	if ( qtextflag )
		goto LABEL_6;
	if ( (quests[6]._qactive != 2 || quests[6]._qlog) && quests[6]._qactive != 1 )
	{
		v1 = v0;
		towner[v1]._tAnimDelay = 1000;
		towner[v1]._tAnimFrame = 1;
		strcpy(towner[v0]._tName, "Slain Townsman");
LABEL_6:
		if ( quests[6]._qactive != 1 )
			towner[v0]._tAnimCnt = 0;
	}
}
// 646D00: using guessed type char qtextflag;

//----- (00460B0D) --------------------------------------------------------
void __cdecl TownHealer()
{
	int v0; // eax

	v0 = GetActiveTowner(1);
	TownCtrlMsg(v0);
}

//----- (00460B1C) --------------------------------------------------------
void __cdecl TownStory()
{
	int v0; // eax

	v0 = GetActiveTowner(TOWN_STORY);
	TownCtrlMsg(v0);
}

//----- (00460B2B) --------------------------------------------------------
void __cdecl TownDrunk()
{
	int v0; // eax

	v0 = GetActiveTowner(TOWN_DRUNK);
	TownCtrlMsg(v0);
}

//----- (00460B3A) --------------------------------------------------------
void __cdecl TownBoy()
{
	int v0; // eax

	v0 = GetActiveTowner(TOWN_PEGBOY);
	TownCtrlMsg(v0);
}

//----- (00460B49) --------------------------------------------------------
void __cdecl TownWitch()
{
	int v0; // eax

	v0 = GetActiveTowner(TOWN_WITCH);
	TownCtrlMsg(v0);
}

//----- (00460B58) --------------------------------------------------------
void __cdecl TownBarMaid()
{
	int v0; // eax

	v0 = GetActiveTowner(TOWN_BMAID);
	TownCtrlMsg(v0);
}

//----- (00460B67) --------------------------------------------------------
void __cdecl TownCow()
{
	int v0; // eax

	v0 = GetActiveTowner(TOWN_COW);
	TownCtrlMsg(v0);
}

//----- (00460B76) --------------------------------------------------------
void __cdecl ProcessTowners()
{
	int *v0; // esi
	char v1; // al
	int v2; // ecx
	_DWORD *v3; // eax

	v0 = &towner[0]._tAnimCnt;
	do
	{
		switch ( *(v0 - 10) )
		{
			case TOWN_SMITH:
				TownBlackSmith();
				break;
			case TOWN_HEALER:
				TownHealer();
				break;
			case TOWN_DEADGUY:
				TownDead();
				break;
			case TOWN_TAVERN:
				TownBarOwner();
				break;
			case TOWN_STORY:
				TownStory();
				break;
			case TOWN_DRUNK:
				TownDrunk();
				break;
			case TOWN_WITCH:
				TownWitch();
				break;
			case TOWN_BMAID:
				TownBarMaid();
				break;
			case TOWN_PEGBOY:
				TownBoy();
				break;
			case TOWN_COW:
				TownCow();
				break;
			default:
				break;
		}
		if ( ++*v0 >= *(v0 - 1) )
		{
			v1 = *((_BYTE *)v0 + 16);
			*v0 = 0;
			if ( v1 < 0 )
			{
				if ( ++v0[2] > v0[1] )
					v0[2] = 1;
			}
			else
			{
				v2 = 148 * v1;
				v3 = (unsigned int *)v0 + 3;
				++*v3;
				if ( AnimOrder[0][v0[3] + v2] == -1 )
					*v3 = 0;
				v0[2] = (char)AnimOrder[0][*v3 + v2];
			}
		}
		v0 += 58;
	}
	while ( (signed int)v0 < (signed int)&trigs[0]._ty );
}

//----- (00460C5C) --------------------------------------------------------
ItemStruct *__fastcall PlrHasItem(int pnum, int item, int *i)
{
	unsigned int v3; // eax
	int v4; // ecx

	v3 = 21720 * pnum;
	*i = 0;
	if ( plr[pnum]._pNumInv <= 0 )
		return 0;
	while ( *(int *)((char *)&plr[0].InvList[*i].IDidx + v3) != item )
	{
		v4 = *i + 1;
		*i = v4;
		if ( v4 >= plr[v3 / 0x54D8]._pNumInv )
			return 0;
	}
	return (ItemStruct *)((char *)&plr[0].InvList[*i] + v3);
}

//----- (00460CAC) --------------------------------------------------------
void __fastcall TownerTalk(int t)
{
	sgdwCowClicks = 0;
	sgnCowMsg = 0;
	storeflag = 1;
	InitQTextMsg(t);
}
// 6AAC18: using guessed type int storeflag;
// 6AAC1C: using guessed type int sgnCowMsg;
// 6AAC24: using guessed type int sgdwCowClicks;

//----- (00460CC9) --------------------------------------------------------
void __fastcall TalkToTowner(int p, int t)
{
	int v2; // ebx
	int v3; // edi
	int v4; // ecx
	int v5; // ecx
	int v6; // ebp
	int v7; // esi
	int v8; // eax
	int v9; // ecx
	char v10; // cl
	bool v11; // zf
	int v12; // edi
	int v13; // eax
	int v14; // eax
	int v15; // eax
	char v16; // cl
	_speech_id v17; // ecx
	ItemStruct *Item; // ebp
	unsigned char v19; // dl
	int inv_item_num; // [esp+10h] [ebp-8h]
	int v21; // [esp+14h] [ebp-4h]

	v2 = t;
	v3 = p;
	_LOBYTE(p) = 6;
	v21 = t;
	random(p, 3);
	_LOBYTE(v4) = 6;
	random(v4, 4);
	_LOBYTE(v5) = 6;
	random(v5, 5);
	v6 = v3;
	v7 = v2;
	inv_item_num = abs(plr[v3].WorldX - towner[v2]._tx);
	v8 = abs(plr[v3].WorldY - towner[v2]._ty);
	if ( inv_item_num >= 2 )
		return;
	if ( v8 >= 2 )
		return;
	if ( qtextflag )
		return;
	towner[v7]._tMsgSaid = 0;
	if ( pcurs >= CURSOR_FIRSTITEM && !DropItemBeforeTrig() )
		return;
	if ( v2 == GetActiveTowner(TOWN_TAVERN) )
	{
		if ( !plr[v6]._pLvlVisited[0] && !towner[v7]._tMsgSaid )
		{
			towner[v7]._tbtcnt = 150;
			towner[v7]._tVar1 = v3;
			InitQTextMsg(TEXT_TAVERN0);
			towner[v7]._tMsgSaid = 1;
		}
		if ( (plr[v6]._pLvlVisited[2] || plr[v6]._pLvlVisited[4]) && quests[12]._qactive )
		{
			if ( !quests[12]._qvar2 && !towner[v7]._tMsgSaid )
			{
				quests[12]._qvar2 = 1;
				quests[12]._qlog = 1;
				if ( quests[12]._qactive == 1 )
				{
					quests[12]._qactive = 2;
					quests[12]._qvar1 = 1;
				}
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(1);
				towner[v7]._tMsgSaid = 1;
				NetSendCmdQuest(1u, 0xCu);
			}
			if ( quests[12]._qactive == 3 && quests[12]._qvar2 == 1 && !towner[v7]._tMsgSaid )
			{
				quests[12]._qvar2 = 2;
				quests[12]._qvar1 = 2;
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_TAVERN23);
				towner[v7]._tMsgSaid = 1;
				NetSendCmdQuest(1u, 0xCu);
			}
		}
		if ( gbMaxPlayers == 1 && plr[v6]._pLvlVisited[3] && quests[7]._qactive )
		{
			if ( (quests[7]._qactive == 1 || quests[7]._qactive == 2) && !quests[7]._qvar2 )
			{
				if ( towner[v7]._tMsgSaid )
					goto LABEL_36;
				quests[7]._qvar2 = 1;
				if ( quests[7]._qactive == 1 )
				{
					quests[7]._qvar1 = 1;
					quests[7]._qactive = 2;
				}
				quests[7]._qlog = 1;
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_TAVERN24);
				towner[v7]._tMsgSaid = 1;
			}
			if ( quests[7]._qvar2 == 1 && PlrHasItem(v3, IDI_BANNER, &inv_item_num) && !towner[v7]._tMsgSaid )
			{
				quests[7]._qactive = 3;
				quests[7]._qvar1 = 3;
				RemoveInvItem(v3, inv_item_num);
				CreateItem(UITEM_HARCREST, towner[v7]._tx, towner[v7]._ty + 1);
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_TAVERN25);
				towner[v7]._tMsgSaid = 1;
			}
		}
LABEL_36:
		if ( !qtextflag )
		{
			TownerTalk(TEXT_TAVERN36);
			if ( storeflag )
			{
				_LOBYTE(v9) = STORE_TAVERN;
LABEL_39:
				StartStore(v9);
				return;
			}
		}
		return;
	}
	if ( v2 == GetActiveTowner(TOWN_DEADGUY) )
	{
		if ( quests[6]._qactive == v10 )
		{
			if ( quests[6]._qvar1 == 1 )
			{
				v11 = _LOBYTE(plr[v6]._pClass) == 0;
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				quests[6]._qvar1 = 1;
				if ( v11 && (v12 = PS_WARR8, _LOBYTE(v13) = effect_is_playing(PS_WARR8), !v13)
				  || _LOBYTE(plr[v6]._pClass) == 1 && (v12 = PS_ROGUE8, _LOBYTE(v14) = effect_is_playing(PS_ROGUE8), !v14)
				  || _LOBYTE(plr[v6]._pClass) == 2 && (v12 = PS_MAGE8, _LOBYTE(v15) = effect_is_playing(PS_MAGE8), !v15) )
				{
					PlaySFX(v12);
				}
LABEL_53:
				towner[v7]._tMsgSaid = 1;
				return;
			}
			if ( quests[6]._qvar1 )
				return;
		}
		else
		{
			if ( quests[6]._qactive == 3 )
			{
				if ( quests[6]._qvar1 != 1 )
					return;
				quests[6]._qvar1 = 1;
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				goto LABEL_53;
			}
			if ( quests[6]._qactive != 1 )
				return;
		}
		quests[6]._qactive = 2;
		quests[6]._qlog = 1;
		quests[6]._qmsg = TEXT_WOUND;
		quests[6]._qvar1 = 1;
		towner[v7]._tbtcnt = 50;
		towner[v7]._tVar1 = v3;
		towner[v7]._tVar2 = 3;
		InitQTextMsg(TEXT_WOUND);
		towner[v7]._tMsgSaid = 1;
		NetSendCmdQuest(1u, 6u);
		return;
	}
	if ( v2 != GetActiveTowner(0) )
	{
		if ( v2 == GetActiveTowner(TOWN_WITCH) )
		{
			if ( quests[1]._qactive == 1 )
			{
				if ( PlrHasItem(v3, IDI_FUNGALTM, &inv_item_num) )
				{
					RemoveInvItem(v3, inv_item_num);
					quests[1]._qactive = 2;
					quests[1]._qlog = 1;
					quests[1]._qvar1 = 2;
					v17 = TEXT_WITCH22;
LABEL_105:
					towner[v7]._tVar1 = v3;
					towner[v7]._tbtcnt = 150;
					InitQTextMsg(v17);
					towner[v7]._tMsgSaid = 1;
					goto LABEL_106;
				}
			}
			else if ( quests[1]._qactive == 2 )
			{
				if ( quests[1]._qvar1 >= 2u && quests[1]._qvar1 <= 4u )
				{
					if ( PlrHasItem(v3, IDI_MUSHROOM, &inv_item_num) )
					{
						RemoveInvItem(v3, inv_item_num);
						Qtalklist[6]._qblkm = -1;
						quests[1]._qvar1 = 5;
						Qtalklist[1]._qblkm = 123;
						v17 = TEXT_WITCH24;
					}
					else
					{
						v17 = TEXT_WITCH23;
						if ( quests[1]._qmsg == TEXT_WITCH23 )
							goto LABEL_106;
					}
					quests[1]._qmsg = v17;
					goto LABEL_105;
				}
				Item = PlrHasItem(v3, IDI_SPECELIX, &inv_item_num);
				if ( Item )
				{
					towner[v7]._tbtcnt = 150;
					towner[v7]._tVar1 = v3;
					InitQTextMsg(TEXT_WITCH26);
					quests[1]._qactive = 3;
					towner[v7]._tMsgSaid = 1;
					AllItemsList[Item->IDidx].iUsable = 1;
				}
				else if ( PlrHasItem(v3, IDI_BRAIN, &inv_item_num) )
				{
					v17 = TEXT_WITCH25;
					if ( quests[1]._qvar2 != TEXT_WITCH25 )
					{
						quests[1]._qvar2 = TEXT_WITCH25;
						goto LABEL_105;
					}
				}
			}
LABEL_106:
			if ( !qtextflag )
			{
				TownerTalk(TEXT_WITCH38);
				if ( storeflag )
				{
					_LOBYTE(v9) = STORE_WITCH;
					goto LABEL_39;
				}
			}
			return;
		}
		if ( v2 == GetActiveTowner(TOWN_BMAID) )
		{
			if ( !qtextflag )
			{
				TownerTalk(TEXT_BMAID31);
				if ( storeflag )
				{
					_LOBYTE(v9) = STORE_BARMAID;
					goto LABEL_39;
				}
			}
			return;
		}
		if ( v2 == GetActiveTowner(TOWN_DRUNK) )
		{
			if ( !qtextflag )
			{
				TownerTalk(TEXT_DRUNK27);
				if ( storeflag )
				{
					_LOBYTE(v9) = STORE_DRUNK;
					goto LABEL_39;
				}
			}
			return;
		}
		if ( v21 == GetActiveTowner(1) )
		{
			if ( gbMaxPlayers != 1 )
				goto LABEL_131;
			if ( plr[v6]._pLvlVisited[1] && !towner[v7]._tMsgSaid )
			{
				if ( quests[13]._qactive == 1 )
				{
					quests[13]._qactive = 2;
					quests[13]._qlog = 1;
					quests[13]._qmsg = TEXT_HEALER20;
					quests[13]._qvar1 = 1;
					towner[v7]._tbtcnt = 150;
					towner[v7]._tVar1 = v3;
					InitQTextMsg(TEXT_HEALER20);
LABEL_126:
					towner[v7]._tMsgSaid = 1;
					goto LABEL_127;
				}
				if ( quests[13]._qactive == 3 && quests[13]._qvar1 != 2 )
				{
					quests[13]._qvar1 = 2;
					towner[v7]._tbtcnt = 150;
					towner[v7]._tVar1 = v3;
					InitQTextMsg(TEXT_HEALER22);
					CreateItem(UITEM_TRING, towner[v7]._tx, towner[v7]._ty + 1);
					goto LABEL_126;
				}
			}
LABEL_127:
			if ( quests[1]._qactive == 2 && quests[1]._qmsg == TEXT_WITCH24 && PlrHasItem(v3, IDI_BRAIN, &inv_item_num) )
			{
				RemoveInvItem(v3, inv_item_num);
				SpawnQuestItem(IDI_SPECELIX, towner[v7]._tx, towner[v7]._ty + 1, 0, 0);
				InitQTextMsg(TEXT_HEALER27);
				Qtalklist[1]._qblkm = -1;
				quests[1]._qvar1 = 7;
			}
LABEL_131:
			if ( !qtextflag )
			{
				TownerTalk(TEXT_HEALER37);
				if ( storeflag )
				{
					_LOBYTE(v9) = STORE_HEALER;
					goto LABEL_39;
				}
			}
			return;
		}
		if ( v21 == GetActiveTowner(TOWN_PEGBOY) )
		{
			if ( !qtextflag )
			{
				TownerTalk(TEXT_PEGBOY32);
				if ( storeflag )
				{
					_LOBYTE(v9) = STORE_BOY;
					goto LABEL_39;
				}
			}
			return;
		}
		if ( v21 != GetActiveTowner(TOWN_STORY) )
		{
			if ( towner[v7]._ttype == 9 && !qtextflag )
				CowSFX(v3);
			return;
		}
		if ( gbMaxPlayers == 1 )
		{
			if ( quests[15]._qactive == 1 )
			{
				if ( !PlrHasItem(v3, IDI_LAZSTAFF, &inv_item_num) )
					goto LABEL_154;
				RemoveInvItem(v3, inv_item_num);
				quests[15]._qvar1 = 2;
				towner[v7]._tbtcnt = TEXT_STORY25;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_STORY36);
				quests[15]._qactive = 2;
				quests[15]._qlog = 1;
			}
			else
			{
				if ( quests[15]._qactive != 3 || quests[15]._qvar1 != 7 )
					goto LABEL_154;
				quests[15]._qvar1 = 8;
				towner[v7]._tbtcnt = TEXT_STORY25;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_STORY38_1);
				quests[5]._qlog = 1;
			}
			v11 = gbMaxPlayers == 1;
			towner[v7]._tMsgSaid = 1;
			if ( v11 )
				goto LABEL_154;
		}
		if ( quests[15]._qactive == 2 )
		{
			if ( !quests[15]._qlog )
			{
				towner[v7]._tbtcnt = TEXT_STORY25;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_STORY36);
				towner[v7]._tMsgSaid = 1;
				quests[15]._qlog = 1;
				v19 = 15;
LABEL_153:
				NetSendCmdQuest(1u, v19);
				goto LABEL_154;
			}
		}
		else if ( quests[15]._qactive == 3 && quests[15]._qvar1 == 7 )
		{
			quests[15]._qvar1 = 8;
			towner[v7]._tbtcnt = TEXT_STORY25;
			towner[v7]._tVar1 = v3;
			InitQTextMsg(TEXT_STORY38_1);
			towner[v7]._tMsgSaid = 1;
			NetSendCmdQuest(1u, 0xFu);
			quests[5]._qlog = 1;
			v19 = 5;
			goto LABEL_153;
		}
LABEL_154:
		if ( !qtextflag )
		{
			TownerTalk(TEXT_STORY25);
			if ( storeflag )
			{
				_LOBYTE(v9) = STORE_STORY;
				goto LABEL_39;
			}
		}
		return;
	}
	if ( gbMaxPlayers == 1 )
	{
		if ( plr[v6]._pLvlVisited[4] != v16 && quests[0]._qactive )
		{
			if ( quests[0]._qvar2 == v16 )
			{
				quests[0]._qvar2 = 1;
				quests[0]._qlog = 1;
				if ( quests[0]._qactive == 1 )
				{
					quests[0]._qactive = 2;
					quests[0]._qvar1 = 1;
				}
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_SMITH24);
				towner[v7]._tMsgSaid = 1;
			}
			if ( quests[0]._qvar2 == 1 && PlrHasItem(v3, IDI_ROCK, &inv_item_num) && !towner[v7]._tMsgSaid )
			{
				quests[0]._qactive = 3;
				quests[0]._qvar2 = 2;
				quests[0]._qvar1 = 2;
				RemoveInvItem(v3, inv_item_num);
				CreateItem(UITEM_INFRARING, towner[v7]._tx, towner[v7]._ty + 1);
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_SMITH26);
				towner[v7]._tMsgSaid = 1;
			}
		}
		if ( plr[v6]._pLvlVisited[9] && quests[10]._qactive )
		{
			if ( (quests[10]._qactive == 1 || quests[10]._qactive == 2) && !quests[10]._qvar2 )
			{
				if ( towner[v7]._tMsgSaid || quests[0]._qvar2 != 2 && (quests[0]._qactive != 2 || quests[0]._qvar2 != 1) )
					goto LABEL_86;
				quests[10]._qvar2 = 1;
				quests[10]._qlog = 1;
				if ( quests[10]._qactive == 1 )
				{
					quests[10]._qactive = 2;
					quests[10]._qvar1 = 1;
				}
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_SMITH21);
				towner[v7]._tMsgSaid = 1;
			}
			if ( quests[10]._qvar2 == 1 && PlrHasItem(v3, IDI_ANVIL, &inv_item_num) && !towner[v7]._tMsgSaid )
			{
				quests[10]._qactive = 3;
				quests[10]._qvar2 = 2;
				quests[10]._qvar1 = 2;
				RemoveInvItem(v3, inv_item_num);
				CreateItem(UITEM_GRISWOLD, towner[v7]._tx, towner[v7]._ty + 1);
				towner[v7]._tbtcnt = 150;
				towner[v7]._tVar1 = v3;
				InitQTextMsg(TEXT_SMITH23);
				towner[v7]._tMsgSaid = 1;
			}
		}
	}
LABEL_86:
	if ( !qtextflag )
	{
		TownerTalk(TEXT_SMITH44);
		if ( storeflag )
		{
			_LOBYTE(v9) = 1;
			goto LABEL_39;
		}
	}
}
// 646D00: using guessed type char qtextflag;
// 679660: using guessed type char gbMaxPlayers;
// 6AAC18: using guessed type int storeflag;

//----- (004617E8) --------------------------------------------------------
void __fastcall CowSFX(int pnum)
{
	int v1; // edi
	int v2; // eax
	int v3; // ecx
	bool v4; // sf
	unsigned char v5; // of
	int v6; // ecx

	v1 = pnum;
	if ( CowPlaying == -1 || (_LOBYTE(v2) = effect_is_playing(CowPlaying), !v2) )
	{
		if ( (unsigned int)++sgdwCowClicks < 8 )
		{
			v6 = (sgdwCowClicks == 4) + TSFX_COW1;
			CowPlaying = (sgdwCowClicks == 4) + TSFX_COW1;
		}
		else
		{
			PlaySfxLoc(TSFX_COW1, plr[v1].WorldX, plr[v1].WorldY + 5);
			sgdwCowClicks = 4;
			v3 = 3 * sgnCowMsg + SLOBYTE(plr[v1]._pClass);
			v5 = __OFSUB__(sgnCowMsg + 1, 3);
			v4 = sgnCowMsg++ - 2 < 0;
			v6 = snSFX[0][v3];
			CowPlaying = v6;
			if ( !(v4 ^ v5) )
				sgnCowMsg = 0;
		}
		PlaySfxLoc(v6, plr[v1].WorldX, plr[v1].WorldY);
	}
}
// 6AAC1C: using guessed type int sgnCowMsg;
// 6AAC24: using guessed type int sgdwCowClicks;

//----- (004618AA) --------------------------------------------------------
void __cdecl track_cpp_init()
{
	track_cpp_init_value = track_inf;
}
// 4802D0: using guessed type int track_inf;
// 6ABABC: using guessed type int track_cpp_init_value;

//----- (004618B5) --------------------------------------------------------
void __cdecl track_repeat_walk()
{
	int v0; // eax
	DWORD v1; // eax

	if ( dword_6ABAC4 )
	{
		if ( cursmx >= 0 && cursmx < 111 && cursmy >= 0 && cursmy < 111 )
		{
			v0 = myplr;
			if ( (plr[myplr]._pVar8 > 6 || plr[v0]._pmode == PM_STAND)
			  && (cursmx != plr[v0]._ptargx || cursmy != plr[v0]._ptargy) )
			{
				v1 = GetTickCount();
				if ( (signed int)(v1 - dword_6ABAC0) >= 300 )
				{
					dword_6ABAC0 = v1;
					NetSendCmdLoc(1u, CMD_WALKXY, cursmx, cursmy);
					if ( !byte_6ABAB8 )
						byte_6ABAB8 = 1;
				}
			}
		}
	}
}
// 6ABAB8: using guessed type char byte_6ABAB8;
// 6ABAC0: using guessed type int dword_6ABAC0;
// 6ABAC4: using guessed type int dword_6ABAC4;

//----- (00461953) --------------------------------------------------------
void __fastcall track_mouse_stance(int a1)
{
	if ( dword_6ABAC4 != a1 )
	{
		dword_6ABAC4 = a1;
		if ( a1 )
		{
			byte_6ABAB8 = 0;
			dword_6ABAC0 = GetTickCount() - 50;
			NetSendCmdLoc(1u, 1u, cursmx, cursmy);
		}
		else if ( byte_6ABAB8 )
		{
			byte_6ABAB8 = 0;
		}
	}
}
// 6ABAB8: using guessed type char byte_6ABAB8;
// 6ABAC0: using guessed type int dword_6ABAC0;
// 6ABAC4: using guessed type int dword_6ABAC4;

//----- (0046199F) --------------------------------------------------------
int __cdecl track_isscrolling()
{
	return (unsigned char)byte_6ABAB8;
}
// 6ABAB8: using guessed type char byte_6ABAB8;

//----- (004619A7) --------------------------------------------------------
void __cdecl InitNoTriggers()
{
	trigflag[4] = 0;
	trigflag[3] = 0;
}

//----- (004619B6) --------------------------------------------------------
void __cdecl InitTownTriggers()
{
	char v0; // bl
	int v1; // eax
	int v2; // eax

	trigs[0]._tx = 25;
	trigs[0]._ty = 29;
	trigs[0]._tmsg = 1026;
	trigflag[4] = 1;
	if ( gbMaxPlayers == 4 )
	{
		trigs[1]._tx = 49;
		trigflag[0] = 1;
		trigflag[1] = 1;
		trigflag[2] = 1;
		trigs[1]._ty = 21;
		trigs[1]._tmsg = 1031;
		trigs[1]._tlvl = 5;
		trigs[2]._tx = 17;
		trigs[2]._ty = 69;
		trigs[2]._tmsg = 1031;
		trigs[2]._tlvl = 9;
		trigs[3]._tx = 41;
		trigs[3]._ty = 80;
		trigs[3]._tmsg = 1031;
		trigs[3]._tlvl = 13;
		trigflag[4] = 4;
	}
	else
	{
		trigflag[0] = 0;
		trigflag[1] = 0;
		trigflag[2] = 0;
		v0 = plr[myplr].pTownWarps;
		if ( v0 & 1 )
		{
			trigs[1]._tx = 49;
			trigs[1]._ty = 21;
			trigs[1]._tmsg = 1031;
			trigs[1]._tlvl = 5;
			trigflag[4] = 2;
			trigflag[0] = 1;
		}
		if ( v0 & 2 )
		{
			trigflag[1] = 1;
			v1 = trigflag[4]++;
			trigs[v1]._tx = 17;
			trigs[v1]._ty = 69;
			trigs[v1]._tmsg = 1031;
			trigs[v1]._tlvl = 9;
		}
		if ( v0 & 4 )
		{
			trigflag[2] = 1;
			v2 = trigflag[4]++;
			trigs[v2]._tx = 41;
			trigs[v2]._ty = 80;
			trigs[v2]._tmsg = 1031;
			trigs[v2]._tlvl = 13;
		}
	}
	trigflag[3] = 0;
}
// 679660: using guessed type char gbMaxPlayers;

//----- (00461B45) --------------------------------------------------------
void __cdecl InitL1Triggers()
{
	int v0; // edi
	signed int v1; // esi
	int *v2; // edx
	int *v3; // ecx
	TriggerStruct *v4; // eax
	int (*v5)[112]; // [esp+Ch] [ebp-8h]
	int (*v6)[112]; // [esp+10h] [ebp-4h]

	v0 = 0;
	trigflag[4] = 0;
	v5 = dPiece;
	do
	{
		v1 = 0;
		v6 = v5;
		v2 = &trigs[trigflag[4]]._tmsg;
		v3 = &trigs[trigflag[4]]._ty;
		v4 = &trigs[trigflag[4]];
		do
		{
			if ( (*v6)[0] == 129 )
			{
				++trigflag[4];
				v4->_tx = v1;
				*v3 = v0;
				*v2 = 1027;
				++v4;
				v3 += 4;
				v2 += 4;
			}
			if ( (*v6)[0] == 115 )
			{
				++trigflag[4];
				v4->_tx = v1;
				*v3 = v0;
				*v2 = 1026;
				++v4;
				v3 += 4;
				v2 += 4;
			}
			++v6;
			++v1;
		}
		while ( v1 < 112 );
		v5 = (int (*)[112])((char *)v5 + 4);
		++v0;
	}
	while ( (signed int)v5 < (signed int)dPiece[1] );
	trigflag[3] = 0;
}

//----- (00461BEE) --------------------------------------------------------
void __cdecl InitL2Triggers()
{
	signed int v0; // edi
	int *v1; // esi
	int *v2; // edx
	TriggerStruct *v3; // ecx
	int *v4; // eax
	int (*v5)[112]; // [esp+Ch] [ebp-10h]
	int (*v6)[112]; // [esp+10h] [ebp-Ch]
	int v7; // [esp+14h] [ebp-8h]
	int *v8; // [esp+18h] [ebp-4h]

	trigflag[4] = 0;
	v7 = 0;
	v5 = dPiece;
	do
	{
		v0 = 0;
		v1 = &trigs[trigflag[4]]._tmsg;
		v2 = &trigs[trigflag[4]]._ty;
		v3 = &trigs[trigflag[4]];
		v8 = &trigs[trigflag[4]]._tlvl;
		v6 = v5;
		do
		{
			if ( (*v6)[0] == 267 && (v0 != quests[14]._qtx || v7 != quests[14]._qty) )
			{
				++trigflag[4];
				v8 += 4;
				v3->_tx = v0;
				*v2 = v7;
				*v1 = 1027;
				++v3;
				v2 += 4;
				v1 += 4;
			}
			if ( (*v6)[0] == 559 )
			{
				v3->_tx = v0;
				*v2 = v7;
				v4 = v8;
				v8 += 4;
				*v1 = 1032;
				*v4 = 0;
				++trigflag[4];
				++v3;
				v2 += 4;
				v1 += 4;
			}
			if ( (*v6)[0] == 271 )
			{
				++trigflag[4];
				v8 += 4;
				v3->_tx = v0;
				*v2 = v7;
				*v1 = 1026;
				++v3;
				v2 += 4;
				v1 += 4;
			}
			++v6;
			++v0;
		}
		while ( v0 < 112 );
		v5 = (int (*)[112])((char *)v5 + 4);
		++v7;
	}
	while ( (signed int)v5 < (signed int)dPiece[1] );
	trigflag[3] = 0;
}

//----- (00461CF6) --------------------------------------------------------
void __cdecl InitL3Triggers()
{
	int v0; // edi
	signed int v1; // esi
	int *v2; // edx
	int *v3; // ecx
	TriggerStruct *v4; // eax
	int (*v5)[112]; // [esp+Ch] [ebp-8h]
	int (*v6)[112]; // [esp+10h] [ebp-4h]

	v0 = 0;
	trigflag[4] = 0;
	v5 = dPiece;
	do
	{
		v1 = 0;
		v6 = v5;
		v2 = &trigs[trigflag[4]]._tmsg;
		v3 = &trigs[trigflag[4]]._ty;
		v4 = &trigs[trigflag[4]];
		do
		{
			if ( (*v6)[0] == 171 )
			{
				++trigflag[4];
				v4->_tx = v1;
				*v3 = v0;
				*v2 = 1027;
				++v4;
				v3 += 4;
				v2 += 4;
			}
			if ( (*v6)[0] == 168 )
			{
				++trigflag[4];
				v4->_tx = v1;
				*v3 = v0;
				*v2 = 1026;
				++v4;
				v3 += 4;
				v2 += 4;
			}
			if ( (*v6)[0] == 549 )
			{
				++trigflag[4];
				v4->_tx = v1;
				*v3 = v0;
				*v2 = 1032;
				++v4;
				v3 += 4;
				v2 += 4;
			}
			++v6;
			++v1;
		}
		while ( v1 < 112 );
		v5 = (int (*)[112])((char *)v5 + 4);
		++v0;
	}
	while ( (signed int)v5 < (signed int)dPiece[1] );
	trigflag[3] = 0;
}

//----- (00461DC6) --------------------------------------------------------
void __cdecl InitL4Triggers()
{
	signed int v0; // edi
	int *v1; // esi
	int *v2; // edx
	TriggerStruct *v3; // ecx
	int *v4; // eax
	int v5; // edx
	int (*v6)[112]; // edi
	signed int v7; // ecx
	int *v8; // eax
	int (*v9)[112]; // [esp+Ch] [ebp-Ch]
	int (*v10)[112]; // [esp+Ch] [ebp-Ch]
	int v11; // [esp+10h] [ebp-8h]
	int (*v12)[112]; // [esp+14h] [ebp-4h]

	trigflag[4] = 0;
	v11 = 0;
	v9 = dPiece;
	do
	{
		v0 = 0;
		v12 = v9;
		v1 = &trigs[trigflag[4]]._tmsg;
		v2 = &trigs[trigflag[4]]._ty;
		v3 = &trigs[trigflag[4]];
		v4 = &trigs[trigflag[4]]._tlvl;
		do
		{
			if ( (*v12)[0] == 83 )
			{
				++trigflag[4];
				v3->_tx = v0;
				*v2 = v11;
				*v1 = 1027;
				v4 += 4;
				++v3;
				v2 += 4;
				v1 += 4;
			}
			if ( (*v12)[0] == 422 )
			{
				v3->_tx = v0;
				*v2 = v11;
				*v1 = 1032;
				*v4 = 0;
				++trigflag[4];
				v4 += 4;
				++v3;
				v2 += 4;
				v1 += 4;
			}
			if ( (*v12)[0] == 120 )
			{
				++trigflag[4];
				v3->_tx = v0;
				*v2 = v11;
				*v1 = 1026;
				v4 += 4;
				++v3;
				v2 += 4;
				v1 += 4;
			}
			++v12;
			++v0;
		}
		while ( v0 < 112 );
		v9 = (int (*)[112])((char *)v9 + 4);
		++v11;
	}
	while ( (signed int)v9 < (signed int)dPiece[1] );
	v5 = 0;
	v10 = dPiece;
	do
	{
		v6 = v10;
		v7 = 0;
		v8 = &trigs[trigflag[4]]._ty;
		do
		{
			if ( (*v6)[0] == 370 && quests[15]._qactive == 3 )
			{
				++trigflag[4];
				*(v8 - 1) = v7;
				*v8 = v5;
				v8[1] = 1026;
				v8 += 4;
			}
			++v7;
			++v6;
		}
		while ( v7 < 112 );
		v10 = (int (*)[112])((char *)v10 + 4);
		++v5;
	}
	while ( (signed int)v10 < (signed int)dPiece[1] );
	trigflag[3] = 0;
}

//----- (00461F0A) --------------------------------------------------------
void __cdecl InitSKingTriggers()
{
	trigflag[3] = 0;
	trigflag[4] = 1;
	trigs[0]._tx = 82;
	trigs[0]._ty = 42;
	trigs[0]._tmsg = 1028;
}

//----- (00461F3A) --------------------------------------------------------
void __cdecl InitSChambTriggers()
{
	trigflag[3] = 0;
	trigflag[4] = 1;
	trigs[0]._tx = 70;
	trigs[0]._ty = 39;
	trigs[0]._tmsg = 1028;
}

//----- (00461F6A) --------------------------------------------------------
void __cdecl InitPWaterTriggers()
{
	trigflag[3] = 0;
	trigflag[4] = 1;
	trigs[0]._tx = 30;
	trigs[0]._ty = 83;
	trigs[0]._tmsg = 1028;
}

//----- (00461F9A) --------------------------------------------------------
void __cdecl InitVPTriggers()
{
	trigflag[3] = 0;
	trigflag[4] = 1;
	trigs[0]._tx = 35;
	trigs[0]._ty = 32;
	trigs[0]._tmsg = 1028;
}

//----- (00461FCA) --------------------------------------------------------
unsigned char __cdecl ForceTownTrig()
{
	int v0; // edx
	int *v1; // esi
	int v2; // edx
	int *v3; // esi
	signed int v4; // esi
	signed int v5; // edx

	v0 = TownDownList[0];
	if ( TownDownList[0] != -1 )
	{
		v1 = TownDownList;
		while ( dPiece[0][cursmy + 112 * cursmx] != v0 )
		{
			++v1;
			v0 = *v1;
			if ( *v1 == -1 )
				goto LABEL_5;
		}
		strcpy(infostr, "Down to dungeon");
		cursmx = 25;
		cursmy = 29;
		return 1;
	}
LABEL_5:
	if ( trigflag[0] )
	{
		v2 = TownWarp1List[0];
		if ( TownWarp1List[0] != -1 )
		{
			v3 = TownWarp1List;
			while ( dPiece[0][cursmy + 112 * cursmx] != v2 )
			{
				++v3;
				v2 = *v3;
				if ( *v3 == -1 )
					goto LABEL_13;
			}
			strcpy(infostr, "Down to catacombs");
			cursmx = 49;
			cursmy = 21;
			return 1;
		}
	}
LABEL_13:
	if ( trigflag[1] )
	{
		v4 = 1199;
		while ( dPiece[0][cursmy + 112 * cursmx] != v4 )
		{
			if ( ++v4 > 1220 )
				goto LABEL_17;
		}
		strcpy(infostr, "Down to caves");
		cursmx = 17;
		cursmy = 69;
		return 1;
	}
LABEL_17:
	if ( trigflag[2] )
	{
		v5 = 1240;
		while ( dPiece[0][cursmy + 112 * cursmx] != v5 )
		{
			if ( ++v5 > 1255 )
				return 0;
		}
		strcpy(infostr, "Down to hell");
		cursmx = 41;
		cursmy = 80;
		return 1;
	}
	return 0;
}

//----- (00462130) --------------------------------------------------------
unsigned char __cdecl ForceL1Trig()
{
	int *v0; // eax
	int *v1; // esi
	int v2; // eax
	int *v3; // edx
	int *v4; // eax
	int *v5; // esi
	int *v6; // edx
	int v8; // eax
	int v9; // ecx

	if ( L1UpList[0] == -1 )
	{
LABEL_12:
		if ( L1DownList[0] == -1 )
			return 0;
		v4 = L1DownList;
		v5 = L1DownList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v4 )
			{
				sprintf(infostr, "Down to level %i", currlevel + 1);
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_19:
			++v5;
			v4 = v5;
			if ( *v5 == -1 )
				return 0;
		}
		v6 = &trigs[0]._tmsg;
		while ( *v6 != 1026 )
		{
			++v2;
			v6 += 4;
			if ( v2 >= trigflag[4] )
				goto LABEL_19;
		}
	}
	else
	{
		v0 = L1UpList;
		v1 = L1UpList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v0 )
			{
				if ( currlevel <= 1u )
					strcpy(infostr, "Up to town");
				else
					sprintf(infostr, "Up to level %i", currlevel - 1);
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_11:
			++v1;
			v0 = v1;
			if ( *v1 == -1 )
				goto LABEL_12;
		}
		v3 = &trigs[0]._tmsg;
		while ( *v3 != 1027 )
		{
			++v2;
			v3 += 4;
			if ( v2 >= trigflag[4] )
				goto LABEL_11;
		}
	}
	v8 = v2;
	v9 = trigs[v8]._tx;
	cursmy = trigs[v8]._ty;
	cursmx = v9;
	return 1;
}

//----- (0046224C) --------------------------------------------------------
unsigned char __cdecl ForceL2Trig()
{
	int *v0; // eax
	int *v1; // ebp
	int v2; // edi
	TriggerStruct *v3; // esi
	int v4; // ebx
	int v5; // eax
	int *v6; // eax
	int *v7; // esi
	int v8; // eax
	int *v9; // ecx
	int v10; // eax
	int v11; // ecx
	int v12; // eax
	int *v13; // eax
	int *v14; // ebp
	TriggerStruct *v15; // esi
	int v16; // ebx
	int v17; // eax
	int v19; // edi

	if ( L2UpList[0] == -1 )
	{
LABEL_11:
		if ( L2DownList[0] != -1 )
		{
			v6 = L2DownList;
			v7 = L2DownList;
			while ( 1 )
			{
				if ( dPiece[0][cursmy + 112 * cursmx] == *v6 )
				{
					sprintf(infostr, "Down to level %i", currlevel + 1);
					v8 = 0;
					if ( trigflag[4] > 0 )
						break;
				}
LABEL_18:
				++v7;
				v6 = v7;
				if ( *v7 == -1 )
					goto LABEL_22;
			}
			v9 = &trigs[0]._tmsg;
			while ( *v9 != 1026 )
			{
				++v8;
				v9 += 4;
				if ( v8 >= trigflag[4] )
					goto LABEL_18;
			}
			v10 = v8;
			v11 = trigs[v10]._tx;
			v12 = trigs[v10]._ty;
			cursmx = v11;
			goto LABEL_37;
		}
LABEL_22:
		if ( currlevel != 5 || L2TWarpUpList[0] == -1 )
			return 0;
		v13 = L2TWarpUpList;
		v14 = L2TWarpUpList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v13 )
			{
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_32:
			++v14;
			v13 = v14;
			if ( *v14 == -1 )
				return 0;
		}
		v15 = trigs;
		while ( 1 )
		{
			if ( v15->_tmsg == 1032 )
			{
				v16 = abs(v15->_tx - cursmx);
				v17 = abs(v15->_ty - cursmy);
				if ( v16 < 4 && v17 < 4 )
					break;
			}
			++v2;
			++v15;
			if ( v2 >= trigflag[4] )
				goto LABEL_32;
		}
		strcpy(infostr, "Up to town");
	}
	else
	{
		v0 = L2UpList;
		v1 = L2UpList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v0 )
			{
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_10:
			++v1;
			v0 = v1;
			if ( *v1 == -1 )
				goto LABEL_11;
		}
		v3 = trigs;
		while ( 1 )
		{
			if ( v3->_tmsg == 1027 )
			{
				v4 = abs(v3->_tx - cursmx);
				v5 = abs(v3->_ty - cursmy);
				if ( v4 < 4 && v5 < 4 )
					break;
			}
			++v2;
			++v3;
			if ( v2 >= trigflag[4] )
				goto LABEL_10;
		}
		sprintf(infostr, "Up to level %i", currlevel - 1);
	}
	v19 = v2;
	cursmx = trigs[v19]._tx;
	v12 = trigs[v19]._ty;
LABEL_37:
	cursmy = v12;
	return 1;
}

//----- (0046244F) --------------------------------------------------------
unsigned char __cdecl ForceL3Trig()
{
	int *v0; // eax
	int *v1; // esi
	int v2; // eax
	int *v3; // ecx
	int *v4; // ecx
	int *v5; // esi
	int v6; // ecx
	int v7; // eax
	int *v8; // ecx
	int *v9; // eax
	int *v10; // ebp
	int v11; // edi
	TriggerStruct *v12; // esi
	int v13; // ebx
	int v14; // eax
	int v15; // eax
	int v16; // ecx
	int v17; // eax
	int v18; // edi

	if ( L3UpList[0] != -1 )
	{
		v0 = L3UpList;
		v1 = L3UpList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v0 )
			{
				sprintf(infostr, "Up to level %i", currlevel - 1);
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_8:
			++v1;
			v0 = v1;
			if ( *v1 == -1 )
				goto LABEL_9;
		}
		v3 = &trigs[0]._tmsg;
		while ( *v3 != 1027 )
		{
			++v2;
			v3 += 4;
			if ( v2 >= trigflag[4] )
				goto LABEL_8;
		}
		goto LABEL_31;
	}
LABEL_9:
	if ( L3DownList[0] != -1 )
	{
		v4 = L3DownList;
		v5 = L3DownList;
		while ( 1 )
		{
			v6 = *v4;
			v7 = cursmy + 112 * cursmx;
			if ( dPiece[0][v7] == v6 || dPiece[1][v7] == v6 || dPiece[2][v7] == v6 )
			{
				sprintf(infostr, "Down to level %i", currlevel + 1);
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_18:
			++v5;
			v4 = v5;
			if ( *v5 == -1 )
				goto LABEL_19;
		}
		v8 = &trigs[0]._tmsg;
		while ( *v8 != 1026 )
		{
			++v2;
			v8 += 4;
			if ( v2 >= trigflag[4] )
				goto LABEL_18;
		}
LABEL_31:
		v15 = v2;
		v16 = trigs[v15]._tx;
		v17 = trigs[v15]._ty;
		cursmx = v16;
LABEL_33:
		cursmy = v17;
		return 1;
	}
LABEL_19:
	if ( currlevel == 9 && L3TWarpUpList[0] != -1 )
	{
		v9 = L3TWarpUpList;
		v10 = L3TWarpUpList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v9 )
			{
				v11 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_29:
			++v10;
			v9 = v10;
			if ( *v10 == -1 )
				return 0;
		}
		v12 = trigs;
		while ( 1 )
		{
			if ( v12->_tmsg == 1032 )
			{
				v13 = abs(v12->_tx - cursmx);
				v14 = abs(v12->_ty - cursmy);
				if ( v13 < 4 && v14 < 4 )
					break;
			}
			++v11;
			++v12;
			if ( v11 >= trigflag[4] )
				goto LABEL_29;
		}
		strcpy(infostr, "Up to town");
		v18 = v11;
		cursmx = trigs[v18]._tx;
		v17 = trigs[v18]._ty;
		goto LABEL_33;
	}
	return 0;
}

//----- (0046262D) --------------------------------------------------------
unsigned char __cdecl ForceL4Trig()
{
	int *v0; // eax
	int *v1; // esi
	int v2; // eax
	int *v3; // ecx
	int *v4; // eax
	int *v5; // esi
	int *v6; // ecx
	int *v7; // eax
	int *v8; // ebp
	int v9; // edi
	TriggerStruct *v10; // esi
	int v11; // ebx
	int v12; // eax
	int *v13; // eax
	int *v14; // esi
	int *v15; // edx
	int v16; // edi
	int v17; // eax
	int v18; // eax
	int v19; // ecx

	if ( L4UpList[0] != -1 )
	{
		v0 = L4UpList;
		v1 = L4UpList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v0 )
			{
				sprintf(infostr, "Up to level %i", currlevel - 1);
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_8:
			++v1;
			v0 = v1;
			if ( *v1 == -1 )
				goto LABEL_9;
		}
		v3 = &trigs[0]._tmsg;
		while ( *v3 != 1027 )
		{
			++v2;
			v3 += 4;
			if ( v2 >= trigflag[4] )
				goto LABEL_8;
		}
		goto LABEL_39;
	}
LABEL_9:
	if ( L4DownList[0] != -1 )
	{
		v4 = L4DownList;
		v5 = L4DownList;
		while ( 1 )
		{
			if ( dPiece[0][cursmy + 112 * cursmx] == *v4 )
			{
				sprintf(infostr, "Down to level %i", currlevel + 1);
				v2 = 0;
				if ( trigflag[4] > 0 )
					break;
			}
LABEL_16:
			++v5;
			v4 = v5;
			if ( *v5 == -1 )
				goto LABEL_17;
		}
		v6 = &trigs[0]._tmsg;
		while ( *v6 != 1026 )
		{
			++v2;
			v6 += 4;
			if ( v2 >= trigflag[4] )
				goto LABEL_16;
		}
		goto LABEL_39;
	}
LABEL_17:
	if ( currlevel == 13 )
	{
		if ( L4TWarpUpList[0] != -1 )
		{
			v7 = L4TWarpUpList;
			v8 = L4TWarpUpList;
			while ( 1 )
			{
				if ( dPiece[0][cursmy + 112 * cursmx] == *v7 )
				{
					v9 = 0;
					if ( trigflag[4] > 0 )
						break;
				}
LABEL_27:
				++v8;
				v7 = v8;
				if ( *v8 == -1 )
					goto LABEL_28;
			}
			v10 = trigs;
			while ( 1 )
			{
				if ( v10->_tmsg == 1032 )
				{
					v11 = abs(v10->_tx - cursmx);
					v12 = abs(v10->_ty - cursmy);
					if ( v11 < 4 && v12 < 4 )
						break;
				}
				++v9;
				++v10;
				if ( v9 >= trigflag[4] )
					goto LABEL_27;
			}
			strcpy(infostr, "Up to town");
			v16 = v9;
			cursmx = trigs[v16]._tx;
			v17 = trigs[v16]._ty;
			goto LABEL_40;
		}
	}
	else
	{
LABEL_28:
		if ( currlevel == 15 && L4PentaList[0] != -1 )
		{
			v13 = L4PentaList;
			v14 = L4PentaList;
			while ( 1 )
			{
				if ( dPiece[0][cursmy + 112 * cursmx] == *v13 )
				{
					strcpy(infostr, "Down to Diablo");
					v2 = 0;
					if ( trigflag[4] > 0 )
						break;
				}
LABEL_36:
				++v14;
				v13 = v14;
				if ( *v14 == -1 )
					return 0;
			}
			v15 = &trigs[0]._tmsg;
			while ( *v15 != 1026 )
			{
				++v2;
				v15 += 4;
				if ( v2 >= trigflag[4] )
					goto LABEL_36;
			}
LABEL_39:
			v18 = v2;
			v19 = trigs[v18]._tx;
			v17 = trigs[v18]._ty;
			cursmx = v19;
LABEL_40:
			cursmy = v17;
			return 1;
		}
	}
	return 0;
}

//----- (00462876) --------------------------------------------------------
void __cdecl Freeupstairs()
{
	int *v0; // ecx
	int v1; // ebx
	char *v2; // eax
	signed int v3; // edi
	char *v4; // edx
	signed int v5; // esi

	if ( trigflag[4] > 0 )
	{
		v0 = &trigs[0]._ty;
		v1 = trigflag[4];
		do
		{
			v2 = &nBlockTable[112 * *(v0 - 1) + 1830 + *v0];
			v3 = 5;
			do
			{
				v4 = v2;
				v5 = 5;
				do
				{
					*v4 |= 8u;
					v4 += 112;
					--v5;
				}
				while ( v5 );
				++v2;
				--v3;
			}
			while ( v3 );
			v0 += 4;
			--v1;
		}
		while ( v1 );
	}
}

//----- (004628B7) --------------------------------------------------------
unsigned char __cdecl ForceSKingTrig()
{
	int v0; // eax
	int *v1; // ecx

	v0 = L1UpList[0];
	if ( L1UpList[0] == -1 )
		return 0;
	v1 = L1UpList;
	while ( dPiece[0][cursmy + 112 * cursmx] != v0 )
	{
		++v1;
		v0 = *v1;
		if ( *v1 == -1 )
			return 0;
	}
	sprintf(infostr, "Back to Level %i", (unsigned char)quests[12]._qlevel);
	cursmx = trigs[0]._tx;
	cursmy = trigs[0]._ty;
	return 1;
}

//----- (0046291F) --------------------------------------------------------
unsigned char __cdecl ForceSChambTrig()
{
	int v0; // eax
	int *v1; // ecx

	v0 = L2DownList[0];
	if ( L2DownList[0] == -1 )
		return 0;
	v1 = L2DownList;
	while ( dPiece[0][cursmy + 112 * cursmx] != v0 )
	{
		++v1;
		v0 = *v1;
		if ( *v1 == -1 )
			return 0;
	}
	sprintf(infostr, "Back to Level %i", (unsigned char)quests[14]._qlevel);
	cursmx = trigs[0]._tx;
	cursmy = trigs[0]._ty;
	return 1;
}

//----- (00462987) --------------------------------------------------------
unsigned char __cdecl ForcePWaterTrig()
{
	int v0; // eax
	int *v1; // ecx

	v0 = L3DownList[0];
	if ( L3DownList[0] == -1 )
		return 0;
	v1 = L3DownList;
	while ( dPiece[0][cursmy + 112 * cursmx] != v0 )
	{
		++v1;
		v0 = *v1;
		if ( *v1 == -1 )
			return 0;
	}
	sprintf(infostr, "Back to Level %i", (unsigned char)quests[13]._qlevel);
	cursmx = trigs[0]._tx;
	cursmy = trigs[0]._ty;
	return 1;
}

//----- (004629EF) --------------------------------------------------------
void __cdecl CheckTrigForce()
{
	int v0; // eax
	int v1; // eax

	trigflag[3] = 0;
	if ( MouseY <= 351 )
	{
		if ( setlevel )
		{
			switch ( setlvlnum )
			{
				case SL_SKELKING:
					_LOBYTE(v1) = ForceSKingTrig();
					break;
				case SL_BONECHAMB:
					_LOBYTE(v1) = ForceSChambTrig();
					break;
				case SL_POISONWATER:
					_LOBYTE(v1) = ForcePWaterTrig();
					break;
				default:
					return;
			}
			goto LABEL_23;
		}
		if ( leveltype )
		{
			switch ( leveltype )
			{
				case DTYPE_CATHEDRAL:
					_LOBYTE(v0) = ForceL1Trig();
					break;
				case DTYPE_CATACOMBS:
					_LOBYTE(v0) = ForceL2Trig();
					break;
				case DTYPE_CAVES:
					_LOBYTE(v0) = ForceL3Trig();
					break;
				case DTYPE_HELL:
					_LOBYTE(v0) = ForceL4Trig();
					break;
				default:
LABEL_14:
					if ( !leveltype )
						goto LABEL_24;
					if ( trigflag[3] )
					{
LABEL_25:
						ClearPanel();
						return;
					}
					v1 = ForceQuests();
LABEL_23:
					trigflag[3] = v1;
LABEL_24:
					if ( !trigflag[3] )
						return;
					goto LABEL_25;
			}
		}
		else
		{
			_LOBYTE(v0) = ForceTownTrig();
		}
		trigflag[3] = v0;
		goto LABEL_14;
	}
}
// 5BB1ED: using guessed type char leveltype;
// 5CCB10: using guessed type char setlvlnum;
// 5CF31D: using guessed type char setlevel;

//----- (00462A9D) --------------------------------------------------------
void __cdecl CheckTriggers()
{
	int *v0; // edi
	int v1; // esi
	int v2; // ecx
	int v3; // eax
	int v4; // edx
	signed int v5; // edx
	int v6; // eax
	char v7; // al
	int v8; // ecx
	int v9; // [esp-4h] [ebp-20h]
	int x; // [esp+Ch] [ebp-10h]
	int y; // [esp+10h] [ebp-Ch]
	int v12; // [esp+14h] [ebp-8h]
	int error_id; // [esp+1Bh] [ebp-1h]

	if ( plr[myplr]._pmode )
		return;
	v12 = 0;
	if ( trigflag[4] <= 0 )
		return;
	v0 = &trigs[0]._tmsg;
	while ( 1 )
	{
		v1 = myplr;
		v2 = plr[myplr].WorldX;
		if ( v2 != *(v0 - 2) )
			goto LABEL_34;
		v3 = plr[v1].WorldY;
		if ( v3 != *(v0 - 1) )
			goto LABEL_34;
		v4 = *v0;
		if ( *v0 == WM_DIABNEXTLVL )
		{
			if ( pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig() )
				return;
			v6 = currlevel + 1;
			goto LABEL_32;
		}
		if ( *v0 == 1027 )
		{
			if ( pcurs >= CURSOR_FIRSTITEM && DropItemBeforeTrig() )
				return;
			v6 = currlevel - 1;
LABEL_32:
			v9 = v6;
			goto LABEL_33;
		}
		if ( *v0 != 1028 )
			break;
		StartNewLvl(myplr, v4, ReturnLvl);
LABEL_34:
		++v12;
		v0 += 4;
		if ( v12 >= trigflag[4] )
			return;
	}
	if ( *v0 != 1031 )
	{
		if ( *v0 == 1032 )
		{
			TWarpFrom = currlevel;
			StartNewLvl(myplr, v4, 0);
		}
		else
		{
			TermMsg("Unknown trigger msg");
		}
		goto LABEL_34;
	}
	if ( gbMaxPlayers == 1 )
		goto LABEL_46;
	v5 = 0;
	if ( v0[1] == 5 && plr[v1]._pLevel < 8 )
	{
		v5 = 1;
		x = plr[myplr].WorldX;
		_LOBYTE(y) = v3 + 1;
		_LOBYTE(error_id) = 40;
	}
	if ( v0[1] == 9 && plr[v1]._pLevel < 13 )
	{
		v5 = 1;
		_LOBYTE(x) = v2 + 1;
		y = plr[v1].WorldY;
		_LOBYTE(error_id) = 41;
	}
	if ( v0[1] == 13 && plr[v1]._pLevel < 17 )
	{
		x = plr[myplr].WorldX;
		v5 = 1;
		_LOBYTE(y) = v3 + 1;
		_LOBYTE(error_id) = 42;
	}
	if ( !v5 )
	{
LABEL_46:
		v9 = v0[1];
LABEL_33:
		StartNewLvl(myplr, *v0, v9);
		goto LABEL_34;
	}
	v7 = plr[myplr]._pClass;
	switch ( v7 )
	{
		case UI_WARRIOR:
			v8 = PS_WARR43;
			goto LABEL_42;
		case UI_ROGUE:
			v8 = PS_ROGUE43;
			goto LABEL_42;
		case UI_SORCERER:
			v8 = PS_MAGE43;
LABEL_42:
			PlaySFX(v8);
			break;
	}
	_LOBYTE(v2) = error_id;
	InitDiabloMsg(v2);
	NetSendCmdLoc(1u, 1u, x, y);
}
// 679660: using guessed type char gbMaxPlayers;
// 6ABB30: using guessed type int TWarpFrom;

//----- (00462C72) --------------------------------------------------------
void __cdecl wave_cpp_init()
{
	wave_cpp_init_value = wave_inf;
}
// 4802D4: using guessed type int wave_inf;
// 6ABB34: using guessed type int wave_cpp_init_value;

//----- (00462C7D) --------------------------------------------------------
bool __fastcall wave_close_file(void *file)
{
	return SFileCloseFile(file);
}

//----- (00462C84) --------------------------------------------------------
int __fastcall wave_get_file_size(int *a1, int *a2)
{
	int *v2; // edi
	int *i; // esi
	int result; // eax
	int a2a; // [esp+8h] [ebp-4h]

	a2a = 0;
	v2 = a2;
	for ( i = a1; ; wave_get_file_archive((int)i, &a2a, 0) )
	{
		result = SFileGetFileSize(i, (unsigned long *)v2);
		if ( result )
			break;
	}
	return result;
}

//----- (00462CAF) --------------------------------------------------------
void __fastcall wave_get_file_archive(int a1, int *a2, char *dwInitParam)
{
	int *v3; // esi
	int v4; // edi
	int v5; // eax
	int v6; // eax
	int archive; // [esp+8h] [ebp-4h]

	v3 = a2;
	v4 = a1;
	if ( (unsigned int)*a2 >= 5 )
		FileErrDlg(dwInitParam);
	if ( v4 && (_LOBYTE(v5) = SFileGetFileArchive((void *)v4, &archive), v5) && (void *)archive != diabdat_mpq )
	{
		Sleep(0x14u);
		++*v3;
	}
	else
	{
		_LOBYTE(v6) = InsertCDDlg();
		if ( !v6 )
			FileErrDlg(dwInitParam);
	}
}

//----- (00462D06) --------------------------------------------------------
int __fastcall wave_open_file(LPARAM dwInitParam, DIABFILE *a2, int a3)
{
	DIABFILE *v3; // edi
	char *i; // esi
	int v5; // eax
	int a2a; // [esp+8h] [ebp-4h]

	a2a = 0;
	v3 = a2;
	for ( i = (char *)dwInitParam; ; wave_get_file_archive(0, &a2a, i) )
	{
		_LOBYTE(v5) = SFileOpenFile(i, (void **)v3);
		if ( v5 )
			return 1;
		if ( a3 && SErrGetLastError() == 2 )
			break;
	}
	return 0;
}

//----- (00462D48) --------------------------------------------------------
char __fastcall wave_read_file(int a1, char *a2, int a3)
{
	char *v3; // ebx
	void *v4; // edi
	int v5; // eax
	int nread; // [esp+Ch] [ebp-Ch]
	int offset; // [esp+10h] [ebp-8h]
	int a2a; // [esp+14h] [ebp-4h]

	v3 = a2;
	v4 = (void *)a1;
	a2a = 0;
	for ( offset = wave_file_pointer(a1, 0, 0, 1); ; wave_file_pointer((int)v4, offset, 0, 0) )
	{
		_LOBYTE(v5) = SFileReadFile(v4, v3, a3, (unsigned long *)&nread, 0);
		if ( v5 )
			break;
		wave_get_file_archive((int)v4, &a2a, 0);
	}
	return v5;
}

//----- (00462D9A) --------------------------------------------------------
int __fastcall wave_file_pointer(int file1, int offset, int file2, int whence)
{
	int v4; // edi
	int i; // esi
	int result; // eax
	int a2; // [esp+8h] [ebp-4h]

	a2 = 0;
	v4 = offset;
	for ( i = file1; ; wave_get_file_archive(i, &a2, 0) )
	{
		result = SFileSetFilePointer(i, v4, file2, whence);
		if ( result != -1 )
			break;
	}
	return result;
}

//----- (00462DCE) --------------------------------------------------------
int __fastcall wave_do_buffer(int a1, TSnd *a2)
{
	TSnd *v2; // esi
	int v3; // esi
	DIABFILE wave_file; // [esp+4h] [ebp-1Ch]

	v2 = a2;
	wave_alloc_buffer(a1, &wave_file, 0);
	v3 = wave_read_buffer(&wave_file, v2, 0);
	wave_free_buffer(&wave_file._cnt);
	return v3;
}

//----- (00462DFC) --------------------------------------------------------
void *__fastcall wave_alloc_buffer(int a1, DIABFILE *a2, unsigned int a3)
{
	DIABFILE *v3; // esi
	int *v4; // edi
	unsigned int v5; // eax
	unsigned int v6; // ecx
	void *result; // eax

	v3 = a2;
	v4 = (int *)a1;
	memset(a2, 0, 0x1Cu);
	v5 = wave_get_file_size(v4, 0);
	v6 = 4096;
	v3->_cnt = v5;
	if ( a3 > 0x1000 )
		v6 = a3;
	v3->_base = (char *)v6;
	if ( v6 >= v5 )
		v6 = v5;
	v3->_base = (char *)v6;
	result = DiabloAllocPtr(v6);
	v3->_name_to_remove = (char *)v4;
	v3->_file = (int)result;
	return result;
}

//----- (00462E45) --------------------------------------------------------
void __fastcall wave_free_buffer(int *a1)
{
	int *v1; // eax
	void *v2; // ecx

	v1 = a1;
	v2 = (void *)a1[5];
	v1[5] = 0;
	mem_free_dbg(v2);
}

//----- (00462E53) --------------------------------------------------------
int __fastcall wave_read_buffer(DIABFILE *wave_file, TSnd *a2, int *a3)
{
	TSnd *v3; // esi
	DIABFILE *v4; // edi
	WORD v5; // ax
	int result; // eax
	int a2a[5]; // [esp+8h] [ebp-2Ch]
	PCMWAVEFORMAT v8; // [esp+1Ch] [ebp-18h]
	int v9[2]; // [esp+2Ch] [ebp-8h]

	v3 = a2;
	v4 = wave_file;
	if ( !wave_seek_section(wave_file, a2a, 0xCu)
	  || a2a[0] != 'FFIR'
	  || a2a[2] != 'EVAW'
	  || !wave_get_section_data(v4, ' tmf', v9)
	  || v9[0] < 0x10u
	  || !wave_seek_section(v4, &v8, 0x10u)
	  || wave_seek_position(v4, v9[0] - 16, 1) == -1 )
	{
		return 0;
	}
	v5 = v8.wf.wFormatTag;
	v3->fmt.cbSize = 0;
	v3->fmt.wFormatTag = v5;
	v3->fmt.nChannels = v8.wf.nChannels;
	v3->fmt.nSamplesPerSec = v8.wf.nSamplesPerSec;
	v3->fmt.nAvgBytesPerSec = v8.wf.nAvgBytesPerSec;
	v3->fmt.nBlockAlign = v8.wf.nBlockAlign;
	v3->fmt.wBitsPerSample = v8.wBitsPerSample;
	if ( a3 )
		result = wave_get_section_data(v4, 'atad', a3);
	else
		result = 1;
	return result;
}

//----- (00462F1D) --------------------------------------------------------
int __fastcall wave_seek_section(DIABFILE *a1, void *a2, size_t a3)
{
	size_t v3; // ebx
	void *v4; // ebp
	DIABFILE *v5; // esi
	size_t v6; // edi

	v3 = a3;
	v4 = a2;
	v5 = a1;
	if ( !a3 )
		return 1;
	while ( 1 )
	{
		if ( !v5->_flag )
			wave_read_section(v5);
		v6 = v5->_flag;
		if ( v3 < v6 )
			v6 = v3;
		if ( !v6 )
			break;
		memcpy(v4, (const void *)(v5->_bufsiz + v5->_file), v6);
		v5->_ptr += v6;
		v5->_bufsiz += v6;
		v5->_flag -= v6;
		v3 -= v6;
		if ( !v3 )
			return 1;
	}
	return 0;
}

//----- (00462F73) --------------------------------------------------------
char __fastcall wave_read_section(DIABFILE *a1)
{
	DIABFILE *v1; // esi
	char *v2; // eax
	unsigned int v3; // edi

	v1 = a1;
	wave_file_pointer((int)a1->_name_to_remove, (int)a1->_ptr, 0, 0);
	v2 = v1->_base;
	v3 = v1->_cnt - (unsigned int)v1->_ptr;
	if ( (unsigned int)v2 < v3 )
		v3 = (unsigned int)v1->_base;
	if ( v3 )
		_LOBYTE(v2) = wave_read_file((int)v1->_name_to_remove, (char *)v1->_file, v3);
	v1->_bufsiz = 0;
	v1->_flag = v3;
	return (char)v2;
}

//----- (00462FAE) --------------------------------------------------------
int __fastcall wave_seek_position(DIABFILE *a1, unsigned int a2, int a3)
{
	unsigned int v3; // eax

	v3 = a1->_flag;
	if ( a2 >= v3 )
	{
		a1->_flag = 0;
	}
	else
	{
		a1->_bufsiz += a2;
		a1->_flag = v3 - a2;
	}
	a1->_ptr += a2;
	return (int)a1->_ptr;
}

//----- (00462FCC) --------------------------------------------------------
int __fastcall wave_get_section_data(DIABFILE *a1, int a2, int *a3)
{
	int v3; // esi
	DIABFILE *v4; // edi
	int v6; // eax
	int a2a; // [esp+8h] [ebp-8h]
	unsigned int v8; // [esp+Ch] [ebp-4h]

	v3 = a2;
	v4 = a1;
	while ( 1 )
	{
		if ( !wave_seek_section(v4, &a2a, 8u) )
			return 0;
		if ( a2a == v3 )
			break;
		if ( wave_seek_position(v4, v8, 1) == -1 )
			return 0;
	}
	*a3 = v8;
	v6 = wave_seek_position(v4, 0, 1);
	a3[1] = v6;
	return v6 != -1;
}

//----- (00463023) --------------------------------------------------------
int __fastcall wave_load_file(int a1, TSnd *a2, int a3)
{
	TSnd *v3; // esi
	DIABFILE wave_file; // [esp+4h] [ebp-1Ch]

	v3 = a2;
	wave_alloc_buffer(a1, &wave_file, 0xFFFFFFFF);
	if ( wave_read_buffer(&wave_file, v3, (int *)a3) )
		return wave_file._file;
	wave_free_buffer(&wave_file._cnt);
	return 0;
}

//----- (00463060) --------------------------------------------------------
void __fastcall drawTopArchesUpperScreen(void *a1)
{
	int v1; // edx
	unsigned int v2; // edi
	_BYTE *v3; // esi
	int v4; // ebx
	short v5; // ax
	char *v6; // esi
	short v7; // ax
	unsigned int v8; // eax
	unsigned char *v9; // esi
	unsigned int v10; // eax
	int v11; // eax
	signed int v12; // ebp
	signed int v13; // ecx
	unsigned int v14; // eax
	_BYTE *v15; // edi
	signed int v16; // ecx
	int v17; // eax
	signed int v18; // ebp
	signed int v19; // edx
	unsigned int v20; // eax
	int v21; // edx
	unsigned int v22; // ecx
	unsigned char v23; // cf
	unsigned int v24; // ecx
	unsigned int v25; // eax
	unsigned int v26; // ecx
	int v27; // eax
	unsigned int v28; // ecx
	unsigned int v29; // ecx
	int v30; // eax
	unsigned int v31; // ecx
	unsigned int v32; // eax
	signed int v33; // ebp
	_BYTE *v34; // edi
	unsigned int v35; // ecx
	int v36; // edx
	unsigned int v37; // ecx
	unsigned int v38; // ecx
	unsigned int v39; // eax
	unsigned int v40; // ecx
	int v41; // eax
	int v42; // edx
	unsigned int v43; // ecx
	unsigned int v44; // ecx
	int v45; // eax
	unsigned int v46; // ecx
	unsigned int v47; // eax
	unsigned char v48; // of
	signed int v49; // ebp
	_BYTE *v50; // edi
	unsigned int v51; // ecx
	int v52; // edx
	unsigned int v53; // ecx
	unsigned int v54; // ecx
	unsigned int v55; // eax
	unsigned int v56; // ecx
	int v57; // eax
	int v58; // edx
	unsigned int v59; // ecx
	unsigned int v60; // ecx
	int v61; // eax
	unsigned int v62; // ecx
	unsigned int v63; // eax
	signed int v64; // ebp
	unsigned int v65; // ecx
	unsigned int v66; // ecx
	unsigned int v67; // ecx
	unsigned int v68; // eax
	unsigned int v69; // ecx
	int v70; // eax
	unsigned int v71; // ecx
	unsigned int v72; // ecx
	int v73; // eax
	unsigned int v74; // ecx
	unsigned int v75; // eax
	signed int v76; // ebp
	unsigned int v77; // ecx
	unsigned int v78; // ecx
	unsigned int v79; // ecx
	unsigned int v80; // eax
	unsigned int v81; // ecx
	int v82; // eax
	unsigned int v83; // ecx
	unsigned int v84; // ecx
	int v85; // eax
	unsigned int v86; // ecx
	unsigned int v87; // eax
	signed int v88; // ebp
	_BYTE *v89; // edi
	unsigned int v90; // ecx
	int v91; // edx
	unsigned int v92; // ecx
	unsigned int v93; // ecx
	unsigned int v94; // eax
	unsigned int v95; // ecx
	int v96; // eax
	unsigned int v97; // ecx
	unsigned int v98; // ecx
	int v99; // eax
	unsigned int v100; // ecx
	unsigned int v101; // eax
	signed int v102; // ebp
	signed int v103; // ecx
	unsigned int v104; // eax
	_BYTE *v105; // edi
	signed int v106; // ecx
	int v107; // eax
	signed int v108; // ebp
	unsigned int v109; // ecx
	unsigned int v110; // ecx
	unsigned int v111; // ecx
	unsigned int v112; // eax
	unsigned int v113; // ecx
	int v114; // eax
	unsigned int v115; // ecx
	unsigned int v116; // ecx
	int v117; // eax
	unsigned int v118; // ecx
	unsigned int v119; // eax
	signed int v120; // ebp
	signed int v121; // ecx
	unsigned int v122; // eax
	_BYTE *v123; // edi
	signed int v124; // ecx
	int v125; // eax
	signed int v126; // edx
	signed int v127; // ecx
	int v128; // eax
	_BYTE *v129; // edi
	_BYTE *v130; // edi
	signed int v131; // ecx
	int v132; // eax
	_BYTE *v133; // edi
	signed int v134; // ebp
	signed int v135; // edx
	unsigned int v136; // eax
	unsigned int v137; // ecx
	unsigned int v138; // ecx
	char *v139; // esi
	_BYTE *v140; // edi
	char v141; // al
	int v142; // eax
	_BYTE *v143; // edi
	char v144; // al
	unsigned int v145; // ecx
	char v146; // al
	int v147; // eax
	_BYTE *v148; // edi
	signed int v149; // edx
	_BYTE *v150; // edi
	unsigned int v151; // ecx
	int v152; // eax
	unsigned int v153; // ecx
	_BYTE *v154; // edi
	int v155; // eax
	_BYTE *v156; // edi
	unsigned int v157; // ecx
	short v158; // ax
	int v159; // eax
	_BYTE *v160; // edi
	signed int v161; // edx
	_BYTE *v162; // edi
	unsigned int v163; // ecx
	int v164; // eax
	unsigned int v165; // ecx
	_BYTE *v166; // edi
	int v167; // eax
	_BYTE *v168; // edi
	unsigned int v169; // ecx
	short v170; // ax
	int v171; // eax
	_BYTE *v172; // edi
	signed int v173; // edx
	unsigned int v174; // ecx
	int v175; // eax
	char v176; // bp
	unsigned int i; // ecx
	int v178; // eax
	_BYTE *v179; // edi
	int v180; // ebp
	_BYTE *v181; // edi
	unsigned int j; // ecx
	int v183; // eax
	_BYTE *v184; // edi
	short v185; // ax
	signed int v186; // edx
	unsigned int v187; // ecx
	int v188; // eax
	unsigned int k; // ecx
	int v190; // eax
	_BYTE *v191; // edi
	_BYTE *v192; // edi
	unsigned int l; // ecx
	int v194; // eax
	_BYTE *v195; // edi
	short v196; // ax
	signed int v197; // edx
	_BYTE *v198; // edi
	unsigned int v199; // ecx
	int v200; // eax
	unsigned int v201; // ecx
	_BYTE *v202; // edi
	int v203; // eax
	_BYTE *v204; // edi
	unsigned int v205; // ecx
	short v206; // ax
	int v207; // eax
	_BYTE *v208; // edi
	signed int v209; // edx
	signed int v210; // ecx
	int v211; // eax
	_BYTE *v212; // edi
	_BYTE *v213; // edi
	signed int v214; // ecx
	int v215; // eax
	_BYTE *v216; // edi
	signed int v217; // edx
	unsigned int v218; // ecx
	int v219; // eax
	unsigned int m; // ecx
	int v221; // eax
	_BYTE *v222; // edi
	_BYTE *v223; // edi
	unsigned int n; // ecx
	int v225; // eax
	_BYTE *v226; // edi
	short v227; // ax
	signed int v228; // edx
	signed int v229; // ecx
	int v230; // eax
	_BYTE *v231; // edi
	_BYTE *v232; // edi
	signed int v233; // ecx
	int v234; // eax
	_BYTE *v235; // edi
	signed int v236; // edx
	signed int v237; // ecx
	_BYTE *v238; // edi
	signed int v239; // ecx
	signed int v240; // ebp
	signed int v241; // edx
	unsigned int v242; // eax
	unsigned int v243; // ecx
	unsigned int v244; // ecx
	_BYTE *v245; // edi
	unsigned int v246; // ecx
	signed int ii; // edx
	_BYTE *v248; // edi
	unsigned int v249; // ecx
	unsigned int v250; // ecx
	_BYTE *v251; // edi
	unsigned int v252; // ecx
	signed int v253; // edx
	_BYTE *v254; // edi
	unsigned int v255; // ecx
	unsigned int v256; // ecx
	_BYTE *v257; // edi
	unsigned int v258; // ecx
	signed int jj; // edx
	unsigned int v260; // ecx
	unsigned int v261; // ecx
	_BYTE *v262; // edi
	unsigned int v263; // ecx
	_BYTE *v264; // edi
	signed int v265; // edx
	unsigned int v266; // ecx
	unsigned int v267; // ecx
	_BYTE *v268; // edi
	unsigned int v269; // ecx
	signed int kk; // edx
	_BYTE *v271; // edi
	unsigned int v272; // ecx
	unsigned int v273; // ecx
	_BYTE *v274; // edi
	unsigned int v275; // ecx
	signed int v276; // edx
	signed int v277; // ecx
	_BYTE *v278; // edi
	signed int v279; // ecx
	signed int ll; // edx
	unsigned int v281; // ecx
	unsigned int v282; // ecx
	_BYTE *v283; // edi
	unsigned int v284; // ecx
	unsigned int v285; // edi
	signed int v286; // edx
	signed int v287; // ecx
	_BYTE *v288; // edi
	signed int v289; // ecx
	int v290; // [esp-14h] [ebp-18h]
	int v291; // [esp-14h] [ebp-18h]

	world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num;
	v2 = (unsigned int)a1;
	if ( !(_BYTE)light_table_index )
	{
		if ( level_cel_block & 0x8000 )
			level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
							+ (unsigned short)(level_cel_block & 0xF000);
		v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v8 = level_cel_block;
		_LOBYTE(v8) = BYTE1(v8);
		v7 = ((v8 >> 4) & 7) + 8;
		goto LABEL_11;
	}
	if ( (_BYTE)light_table_index != lightmax )
	{
		if ( !(level_cel_block & 0x8000) )
		{
			v3 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
			v4 = dword_646A20 + (light_table_index << 8);
			v5 = (unsigned char)(BYTE1(level_cel_block) >> 4);
			if ( BYTE1(level_cel_block) >> 4 )
			{
				switch ( v5 )
				{
					case 1:
						world_4B325C = (unsigned char)a1 & 1;
						v18 = 32;
						do
						{
							v19 = 32;
							do
							{
								while ( 1 )
								{
									v20 = (unsigned char)*v3++;
									if ( (v20 & 0x80u) == 0 )
										break;
									_LOBYTE(v20) = -(char)v20;
									v2 += v20;
									v19 -= v20;
									if ( !v19 )
										goto LABEL_67;
								}
								v21 = v19 - v20;
								if ( v2 < screen_buf_end )
									return;
								if ( (v2 & 1) == world_4B325C )
								{
									v290 = v21;
									v22 = v20 >> 1;
									if ( v20 & 1 )
									{
										++v3;
										++v2;
										v23 = v22 & 1;
										v26 = v20 >> 2;
										if ( v23 )
										{
											_LOBYTE(v21) = *v3;
											v3 += 2;
											*(_BYTE *)v2 = *(_BYTE *)(v4 + v21);
											v2 += 2;
										}
										if ( (_BYTE)v26 )
										{
											do
											{
												v27 = *(_DWORD *)v3;
												v3 += 4;
												_LOBYTE(v21) = v27;
												*(_BYTE *)v2 = *(_BYTE *)(v4 + v21);
												_LOBYTE(v21) = BYTE2(v27);
												v2 += 4;
												--v26;
												*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v21);
											}
											while ( v26 );
										}
									}
									else
									{
										v23 = v22 & 1;
										v24 = v20 >> 2;
										if ( v23 )
										{
											_LOBYTE(v21) = v3[1];
											v3 += 2;
											*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21);
											v2 += 2;
										}
										if ( (_BYTE)v24 )
										{
											do
											{
												v25 = *(_DWORD *)v3;
												v3 += 4;
												_LOBYTE(v21) = BYTE1(v25);
												v25 >>= 16;
												*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21);
												_LOBYTE(v21) = BYTE1(v25);
												v2 += 4;
												--v24;
												*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v21);
											}
											while ( v24 );
										}
									}
									v19 = v290;
								}
								else
								{
									v291 = v21;
									v28 = v20 >> 1;
									if ( v20 & 1 )
									{
										_LOBYTE(v21) = *v3++;
										*(_BYTE *)v2++ = *(_BYTE *)(v4 + v21);
										v23 = v28 & 1;
										v31 = v20 >> 2;
										if ( v23 )
										{
											_LOBYTE(v21) = v3[1];
											v3 += 2;
											*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21);
											v2 += 2;
										}
										if ( (_BYTE)v31 )
										{
											do
											{
												v32 = *(_DWORD *)v3;
												v3 += 4;
												_LOBYTE(v21) = BYTE1(v32);
												v32 >>= 16;
												*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v21);
												_LOBYTE(v21) = BYTE1(v32);
												v2 += 4;
												--v31;
												*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v21);
											}
											while ( v31 );
										}
									}
									else
									{
										v23 = v28 & 1;
										v29 = v20 >> 2;
										if ( v23 )
										{
											_LOBYTE(v21) = *v3;
											v3 += 2;
											*(_BYTE *)v2 = *(_BYTE *)(v4 + v21);
											v2 += 2;
										}
										if ( (_BYTE)v29 )
										{
											do
											{
												v30 = *(_DWORD *)v3;
												v3 += 4;
												_LOBYTE(v21) = v30;
												*(_BYTE *)v2 = *(_BYTE *)(v4 + v21);
												_LOBYTE(v21) = BYTE2(v30);
												v2 += 4;
												--v29;
												*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v21);
											}
											while ( v29 );
										}
									}
									v19 = v291;
								}
							}
							while ( v19 );
LABEL_67:
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							v2 -= 800;
							--v18;
						}
						while ( v18 );
						break;
					case 2:
						world_4B325C = 0;
						v33 = 30;
						while ( v2 >= screen_buf_end )
						{
							v34 = (_BYTE *)(v33 + v2);
							v35 = 32 - v33;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v36 = v35 & 2;
								v3 += v36;
								v23 = v35 & 1;
								v37 = v35 >> 1;
								if ( v23 )
								{
									++v3;
									++v34;
									v23 = v37 & 1;
									v40 = v37 >> 1;
									if ( v23 )
									{
										_LOBYTE(v36) = *v3;
										v3 += 2;
										*v34 = *(_BYTE *)(v4 + v36);
										v34 += 2;
									}
									if ( (_BYTE)v40 )
									{
										do
										{
											v41 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v36) = v41;
											*v34 = *(_BYTE *)(v4 + v36);
											_LOBYTE(v36) = BYTE2(v41);
											v34 += 4;
											--v40;
											*(v34 - 2) = *(_BYTE *)(v4 + v36);
										}
										while ( v40 );
									}
								}
								else
								{
									v23 = v37 & 1;
									v38 = v37 >> 1;
									if ( v23 )
									{
										_LOBYTE(v36) = v3[1];
										v3 += 2;
										v34[1] = *(_BYTE *)(v4 + v36);
										v34 += 2;
									}
									if ( (_BYTE)v38 )
									{
										do
										{
											v39 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v36) = BYTE1(v39);
											v39 >>= 16;
											v34[1] = *(_BYTE *)(v4 + v36);
											_LOBYTE(v36) = BYTE1(v39);
											v34 += 4;
											--v38;
											*(v34 - 1) = *(_BYTE *)(v4 + v36);
										}
										while ( v38 );
									}
								}
							}
							else
							{
								v42 = v35 & 2;
								v3 += v42;
								v23 = v35 & 1;
								v43 = v35 >> 1;
								if ( v23 )
								{
									_LOBYTE(v42) = *v3++;
									*v34++ = *(_BYTE *)(v4 + v42);
									v23 = v43 & 1;
									v46 = v43 >> 1;
									if ( v23 )
									{
										_LOBYTE(v42) = v3[1];
										v3 += 2;
										v34[1] = *(_BYTE *)(v4 + v42);
										v34 += 2;
									}
									if ( (_BYTE)v46 )
									{
										do
										{
											v47 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v42) = BYTE1(v47);
											v47 >>= 16;
											v34[1] = *(_BYTE *)(v4 + v42);
											_LOBYTE(v42) = BYTE1(v47);
											v34 += 4;
											--v46;
											*(v34 - 1) = *(_BYTE *)(v4 + v42);
										}
										while ( v46 );
									}
								}
								else
								{
									v23 = v43 & 1;
									v44 = v43 >> 1;
									if ( v23 )
									{
										_LOBYTE(v42) = *v3;
										v3 += 2;
										*v34 = *(_BYTE *)(v4 + v42);
										v34 += 2;
									}
									if ( (_BYTE)v44 )
									{
										do
										{
											v45 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v42) = v45;
											*v34 = *(_BYTE *)(v4 + v42);
											_LOBYTE(v42) = BYTE2(v45);
											v34 += 4;
											--v44;
											*(v34 - 2) = *(_BYTE *)(v4 + v42);
										}
										while ( v44 );
									}
								}
							}
							v2 = (unsigned int)(v34 - 800);
							v48 = __OFSUB__(v33, 2);
							v33 -= 2;
							if ( (v33 < 0) ^ v48 )
							{
								v49 = 2;
								do
								{
									if ( v2 < screen_buf_end )
										break;
									v50 = (_BYTE *)(v49 + v2);
									v51 = 32 - v49;
									world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
									if ( world_4B325C )
									{
										v52 = v51 & 2;
										v3 += v52;
										v23 = v51 & 1;
										v53 = v51 >> 1;
										if ( v23 )
										{
											++v3;
											++v50;
											v23 = v53 & 1;
											v56 = v53 >> 1;
											if ( v23 )
											{
												_LOBYTE(v52) = *v3;
												v3 += 2;
												*v50 = *(_BYTE *)(v4 + v52);
												v50 += 2;
											}
											if ( (_BYTE)v56 )
											{
												do
												{
													v57 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v52) = v57;
													*v50 = *(_BYTE *)(v4 + v52);
													_LOBYTE(v52) = BYTE2(v57);
													v50 += 4;
													--v56;
													*(v50 - 2) = *(_BYTE *)(v4 + v52);
												}
												while ( v56 );
											}
										}
										else
										{
											v23 = v53 & 1;
											v54 = v53 >> 1;
											if ( v23 )
											{
												_LOBYTE(v52) = v3[1];
												v3 += 2;
												v50[1] = *(_BYTE *)(v4 + v52);
												v50 += 2;
											}
											if ( (_BYTE)v54 )
											{
												do
												{
													v55 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v52) = BYTE1(v55);
													v55 >>= 16;
													v50[1] = *(_BYTE *)(v4 + v52);
													_LOBYTE(v52) = BYTE1(v55);
													v50 += 4;
													--v54;
													*(v50 - 1) = *(_BYTE *)(v4 + v52);
												}
												while ( v54 );
											}
										}
									}
									else
									{
										v58 = v51 & 2;
										v3 += v58;
										v23 = v51 & 1;
										v59 = v51 >> 1;
										if ( v23 )
										{
											_LOBYTE(v58) = *v3++;
											*v50++ = *(_BYTE *)(v4 + v58);
											v23 = v59 & 1;
											v62 = v59 >> 1;
											if ( v23 )
											{
												_LOBYTE(v58) = v3[1];
												v3 += 2;
												v50[1] = *(_BYTE *)(v4 + v58);
												v50 += 2;
											}
											if ( (_BYTE)v62 )
											{
												do
												{
													v63 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v58) = BYTE1(v63);
													v63 >>= 16;
													v50[1] = *(_BYTE *)(v4 + v58);
													_LOBYTE(v58) = BYTE1(v63);
													v50 += 4;
													--v62;
													*(v50 - 1) = *(_BYTE *)(v4 + v58);
												}
												while ( v62 );
											}
										}
										else
										{
											v23 = v59 & 1;
											v60 = v59 >> 1;
											if ( v23 )
											{
												_LOBYTE(v58) = *v3;
												v3 += 2;
												*v50 = *(_BYTE *)(v4 + v58);
												v50 += 2;
											}
											if ( (_BYTE)v60 )
											{
												do
												{
													v61 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v58) = v61;
													*v50 = *(_BYTE *)(v4 + v58);
													_LOBYTE(v58) = BYTE2(v61);
													v50 += 4;
													--v60;
													*(v50 - 2) = *(_BYTE *)(v4 + v58);
												}
												while ( v60 );
											}
										}
									}
									v2 = (unsigned int)(v50 - 800);
									v49 += 2;
								}
								while ( v49 != 32 );
								return;
							}
						}
						break;
					case 3:
						world_4B325C = 0;
						v64 = 30;
						while ( v2 >= screen_buf_end )
						{
							v65 = 32 - v64;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v23 = v65 & 1;
								v66 = v65 >> 1;
								if ( v23 )
								{
									++v3;
									++v2;
									v23 = v66 & 1;
									v69 = v66 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = *v3;
										v3 += 2;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v69 )
									{
										do
										{
											v70 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = v70;
											*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE2(v70);
											v2 += 4;
											--v69;
											*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
										}
										while ( v69 );
									}
								}
								else
								{
									v23 = v66 & 1;
									v67 = v66 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = v3[1];
										v3 += 2;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v67 )
									{
										do
										{
											v68 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = BYTE1(v68);
											v68 >>= 16;
											*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE1(v68);
											v2 += 4;
											--v67;
											*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
										}
										while ( v67 );
									}
								}
								v1 = (unsigned char)v3 & 2;
								v3 += v1;
							}
							else
							{
								v23 = v65 & 1;
								v71 = v65 >> 1;
								if ( v23 )
								{
									_LOBYTE(v1) = *v3++;
									*(_BYTE *)v2++ = *(_BYTE *)(v4 + v1);
									v23 = v71 & 1;
									v74 = v71 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = v3[1];
										v3 += 2;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v74 )
									{
										do
										{
											v75 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = BYTE1(v75);
											v75 >>= 16;
											*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE1(v75);
											v2 += 4;
											--v74;
											*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
										}
										while ( v74 );
									}
								}
								else
								{
									v23 = v71 & 1;
									v72 = v71 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = *v3;
										v3 += 2;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v72 )
									{
										do
										{
											v73 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = v73;
											*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE2(v73);
											v2 += 4;
											--v72;
											*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
										}
										while ( v72 );
									}
								}
								v1 = (unsigned char)v3 & 2;
								v3 += v1;
							}
							v2 = v64 + v2 - 800;
							v48 = __OFSUB__(v64, 2);
							v64 -= 2;
							if ( (v64 < 0) ^ v48 )
							{
								v76 = 2;
								do
								{
									if ( v2 < screen_buf_end )
										break;
									v77 = 32 - v76;
									world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
									if ( world_4B325C )
									{
										v23 = v77 & 1;
										v78 = v77 >> 1;
										if ( v23 )
										{
											++v3;
											++v2;
											v23 = v78 & 1;
											v81 = v78 >> 1;
											if ( v23 )
											{
												_LOBYTE(v1) = *v3;
												v3 += 2;
												*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
												v2 += 2;
											}
											if ( (_BYTE)v81 )
											{
												do
												{
													v82 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v1) = v82;
													*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
													_LOBYTE(v1) = BYTE2(v82);
													v2 += 4;
													--v81;
													*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
												}
												while ( v81 );
											}
										}
										else
										{
											v23 = v78 & 1;
											v79 = v78 >> 1;
											if ( v23 )
											{
												_LOBYTE(v1) = v3[1];
												v3 += 2;
												*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
												v2 += 2;
											}
											if ( (_BYTE)v79 )
											{
												do
												{
													v80 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v1) = BYTE1(v80);
													v80 >>= 16;
													*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
													_LOBYTE(v1) = BYTE1(v80);
													v2 += 4;
													--v79;
													*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
												}
												while ( v79 );
											}
										}
										v1 = (unsigned char)v3 & 2;
										v3 += v1;
									}
									else
									{
										v23 = v77 & 1;
										v83 = v77 >> 1;
										if ( v23 )
										{
											_LOBYTE(v1) = *v3++;
											*(_BYTE *)v2++ = *(_BYTE *)(v4 + v1);
											v23 = v83 & 1;
											v86 = v83 >> 1;
											if ( v23 )
											{
												_LOBYTE(v1) = v3[1];
												v3 += 2;
												*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
												v2 += 2;
											}
											if ( (_BYTE)v86 )
											{
												do
												{
													v87 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v1) = BYTE1(v87);
													v87 >>= 16;
													*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
													_LOBYTE(v1) = BYTE1(v87);
													v2 += 4;
													--v86;
													*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
												}
												while ( v86 );
											}
										}
										else
										{
											v23 = v83 & 1;
											v84 = v83 >> 1;
											if ( v23 )
											{
												_LOBYTE(v1) = *v3;
												v3 += 2;
												*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
												v2 += 2;
											}
											if ( (_BYTE)v84 )
											{
												do
												{
													v85 = *(_DWORD *)v3;
													v3 += 4;
													_LOBYTE(v1) = v85;
													*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
													_LOBYTE(v1) = BYTE2(v85);
													v2 += 4;
													--v84;
													*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
												}
												while ( v84 );
											}
										}
										v1 = (unsigned char)v3 & 2;
										v3 += v1;
									}
									v2 = v76 + v2 - 800;
									v76 += 2;
								}
								while ( v76 != 32 );
								return;
							}
						}
						break;
					case 4:
						world_4B325C = 0;
						v88 = 30;
						while ( v2 >= screen_buf_end )
						{
							v89 = (_BYTE *)(v88 + v2);
							v90 = 32 - v88;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v91 = v90 & 2;
								v3 += v91;
								v23 = v90 & 1;
								v92 = v90 >> 1;
								if ( v23 )
								{
									++v3;
									++v89;
									v23 = v92 & 1;
									v95 = v92 >> 1;
									if ( v23 )
									{
										_LOBYTE(v91) = *v3;
										v3 += 2;
										*v89 = *(_BYTE *)(v4 + v91);
										v89 += 2;
									}
									if ( (_BYTE)v95 )
									{
										do
										{
											v96 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v91) = v96;
											*v89 = *(_BYTE *)(v4 + v91);
											_LOBYTE(v91) = BYTE2(v96);
											v89 += 4;
											--v95;
											*(v89 - 2) = *(_BYTE *)(v4 + v91);
										}
										while ( v95 );
									}
								}
								else
								{
									v23 = v92 & 1;
									v93 = v92 >> 1;
									if ( v23 )
									{
										_LOBYTE(v91) = v3[1];
										v3 += 2;
										v89[1] = *(_BYTE *)(v4 + v91);
										v89 += 2;
									}
									if ( (_BYTE)v93 )
									{
										do
										{
											v94 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v91) = BYTE1(v94);
											v94 >>= 16;
											v89[1] = *(_BYTE *)(v4 + v91);
											_LOBYTE(v91) = BYTE1(v94);
											v89 += 4;
											--v93;
											*(v89 - 1) = *(_BYTE *)(v4 + v91);
										}
										while ( v93 );
									}
								}
							}
							else
							{
								v91 = v90 & 2;
								v3 += v91;
								v23 = v90 & 1;
								v97 = v90 >> 1;
								if ( v23 )
								{
									_LOBYTE(v91) = *v3++;
									*v89++ = *(_BYTE *)(v4 + v91);
									v23 = v97 & 1;
									v100 = v97 >> 1;
									if ( v23 )
									{
										_LOBYTE(v91) = v3[1];
										v3 += 2;
										v89[1] = *(_BYTE *)(v4 + v91);
										v89 += 2;
									}
									if ( (_BYTE)v100 )
									{
										do
										{
											v101 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v91) = BYTE1(v101);
											v101 >>= 16;
											v89[1] = *(_BYTE *)(v4 + v91);
											_LOBYTE(v91) = BYTE1(v101);
											v89 += 4;
											--v100;
											*(v89 - 1) = *(_BYTE *)(v4 + v91);
										}
										while ( v100 );
									}
								}
								else
								{
									v23 = v97 & 1;
									v98 = v97 >> 1;
									if ( v23 )
									{
										_LOBYTE(v91) = *v3;
										v3 += 2;
										*v89 = *(_BYTE *)(v4 + v91);
										v89 += 2;
									}
									if ( (_BYTE)v98 )
									{
										do
										{
											v99 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v91) = v99;
											*v89 = *(_BYTE *)(v4 + v91);
											_LOBYTE(v91) = BYTE2(v99);
											v89 += 4;
											--v98;
											*(v89 - 2) = *(_BYTE *)(v4 + v91);
										}
										while ( v98 );
									}
								}
							}
							v2 = (unsigned int)(v89 - 800);
							v48 = __OFSUB__(v88, 2);
							v88 -= 2;
							if ( (v88 < 0) ^ v48 )
							{
								v102 = 8;
								do
								{
									if ( v2 < screen_buf_end )
										break;
									v103 = 8;
									do
									{
										v104 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v91) = BYTE1(v104);
										v104 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v91);
										_LOBYTE(v91) = BYTE1(v104);
										v2 += 4;
										--v103;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v91);
									}
									while ( v103 );
									v105 = (_BYTE *)(v2 - 800);
									if ( (unsigned int)v105 < screen_buf_end )
										break;
									v106 = 8;
									do
									{
										v107 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v91) = v107;
										*v105 = *(_BYTE *)(v4 + v91);
										_LOBYTE(v91) = BYTE2(v107);
										v105 += 4;
										--v106;
										*(v105 - 2) = *(_BYTE *)(v4 + v91);
									}
									while ( v106 );
									v2 = (unsigned int)(v105 - 800);
									--v102;
								}
								while ( v102 );
								return;
							}
						}
						break;
					default:
						world_4B325C = 0;
						v108 = 30;
						while ( v2 >= screen_buf_end )
						{
							v109 = 32 - v108;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v23 = v109 & 1;
								v110 = v109 >> 1;
								if ( v23 )
								{
									++v3;
									++v2;
									v23 = v110 & 1;
									v113 = v110 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = *v3;
										v3 += 2;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v113 )
									{
										do
										{
											v114 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = v114;
											*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE2(v114);
											v2 += 4;
											--v113;
											*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
										}
										while ( v113 );
									}
								}
								else
								{
									v23 = v110 & 1;
									v111 = v110 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = v3[1];
										v3 += 2;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v111 )
									{
										do
										{
											v112 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = BYTE1(v112);
											v112 >>= 16;
											*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE1(v112);
											v2 += 4;
											--v111;
											*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
										}
										while ( v111 );
									}
								}
								v1 = (unsigned char)v3 & 2;
								v3 += v1;
							}
							else
							{
								v23 = v109 & 1;
								v115 = v109 >> 1;
								if ( v23 )
								{
									_LOBYTE(v1) = *v3++;
									*(_BYTE *)v2++ = *(_BYTE *)(v4 + v1);
									v23 = v115 & 1;
									v118 = v115 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = v3[1];
										v3 += 2;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v118 )
									{
										do
										{
											v119 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = BYTE1(v119);
											v119 >>= 16;
											*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE1(v119);
											v2 += 4;
											--v118;
											*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
										}
										while ( v118 );
									}
								}
								else
								{
									v23 = v115 & 1;
									v116 = v115 >> 1;
									if ( v23 )
									{
										_LOBYTE(v1) = *v3;
										v3 += 2;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										v2 += 2;
									}
									if ( (_BYTE)v116 )
									{
										do
										{
											v117 = *(_DWORD *)v3;
											v3 += 4;
											_LOBYTE(v1) = v117;
											*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
											_LOBYTE(v1) = BYTE2(v117);
											v2 += 4;
											--v116;
											*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
										}
										while ( v116 );
									}
								}
								v1 = (unsigned char)v3 & 2;
								v3 += v1;
							}
							v2 = v108 + v2 - 800;
							v48 = __OFSUB__(v108, 2);
							v108 -= 2;
							if ( (v108 < 0) ^ v48 )
							{
								v120 = 8;
								do
								{
									if ( v2 < screen_buf_end )
										break;
									v121 = 8;
									do
									{
										v122 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v122);
										v122 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v122);
										v2 += 4;
										--v121;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v121 );
									v123 = (_BYTE *)(v2 - 800);
									if ( (unsigned int)v123 < screen_buf_end )
										break;
									v124 = 8;
									do
									{
										v125 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v125;
										*v123 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v125);
										v123 += 4;
										--v124;
										*(v123 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v124 );
									v2 = (unsigned int)(v123 - 800);
									--v120;
								}
								while ( v120 );
								return;
							}
						}
						break;
				}
			}
			else
			{
				v12 = 16;
				do
				{
					if ( v2 < screen_buf_end )
						break;
					v13 = 8;
					do
					{
						v14 = *(_DWORD *)v3;
						v3 += 4;
						_LOBYTE(v1) = BYTE1(v14);
						v14 >>= 16;
						*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
						_LOBYTE(v1) = BYTE1(v14);
						v2 += 4;
						--v13;
						*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
					}
					while ( v13 );
					v15 = (_BYTE *)(v2 - 800);
					if ( (unsigned int)v15 < screen_buf_end )
						break;
					v16 = 8;
					do
					{
						v17 = *(_DWORD *)v3;
						v3 += 4;
						_LOBYTE(v1) = v17;
						*v15 = *(_BYTE *)(v4 + v1);
						_LOBYTE(v1) = BYTE2(v17);
						v15 += 4;
						--v16;
						*(v15 - 2) = *(_BYTE *)(v4 + v1);
					}
					while ( v16 );
					v2 = (unsigned int)(v15 - 800);
					--v12;
				}
				while ( v12 );
			}
			return;
		}
		v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265);
		v7 = (unsigned char)(BYTE1(level_cel_block) >> 4);
LABEL_11:
		if ( v7 == 8 )
		{
			v126 = 16;
			do
			{
				if ( v2 < screen_buf_end )
					break;
				v127 = 8;
				do
				{
					v128 = *(_DWORD *)v6;
					v6 += 4;
					v129 = (_BYTE *)(v2 + 1);
					v128 = __ROR4__(v128, 8);
					*v129 = v128;
					v129 += 2;
					*v129 = __ROR4__(v128, 16);
					v2 = (unsigned int)(v129 + 1);
					--v127;
				}
				while ( v127 );
				v130 = (_BYTE *)(v2 - 800);
				if ( (unsigned int)v130 < screen_buf_end )
					break;
				v131 = 8;
				do
				{
					v132 = *(_DWORD *)v6;
					v6 += 4;
					*v130 = v132;
					v133 = v130 + 2;
					*v133 = __ROR4__(v132, 16);
					v130 = v133 + 2;
					--v131;
				}
				while ( v131 );
				v2 = (unsigned int)(v130 - 800);
				--v126;
			}
			while ( v126 );
			return;
		}
		if ( v7 != 9 )
		{
			switch ( v7 )
			{
				case 10:
					world_4B325C = 0;
					v149 = 30;
					while ( v2 >= screen_buf_end )
					{
						v150 = (_BYTE *)(v149 + v2);
						v151 = 32 - v149;
						v152 = ((_BYTE)world_4B325C + 1) & 1;
						world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
						if ( world_4B325C )
						{
							v23 = __CFSHR__(v151, 2);
							v153 = v151 >> 2;
							if ( !v23
							  || (_LOWORD(v152) = *((_WORD *)v6 + 1),
								  v6 += 4,
								  v154 = v150 + 1,
								  *v154 = __ROR4__(v152, 8),
								  v150 = v154 + 1,
								  v153) )
							{
								do
								{
									v155 = *(_DWORD *)v6;
									v6 += 4;
									v156 = v150 + 1;
									v155 = __ROR4__(v155, 8);
									*v156 = v155;
									v156 += 2;
									*v156 = __ROR4__(v155, 16);
									v150 = v156 + 1;
									--v153;
								}
								while ( v153 );
							}
						}
						else
						{
							v23 = __CFSHR__(v151, 2);
							v157 = v151 >> 2;
							if ( !v23 || (v158 = *((_WORD *)v6 + 1), v6 += 4, *v150 = v158, v150 += 2, v157) )
							{
								do
								{
									v159 = *(_DWORD *)v6;
									v6 += 4;
									*v150 = v159;
									v160 = v150 + 2;
									*v160 = __ROR4__(v159, 16);
									v150 = v160 + 2;
									--v157;
								}
								while ( v157 );
							}
						}
						v2 = (unsigned int)(v150 - 800);
						v48 = __OFSUB__(v149, 2);
						v149 -= 2;
						if ( (v149 < 0) ^ v48 )
						{
							v161 = 2;
							do
							{
								if ( v2 < screen_buf_end )
									break;
								v162 = (_BYTE *)(v161 + v2);
								v163 = 32 - v161;
								v164 = ((_BYTE)world_4B325C + 1) & 1;
								world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
								if ( world_4B325C )
								{
									v23 = __CFSHR__(v163, 2);
									v165 = v163 >> 2;
									if ( !v23
									  || (_LOWORD(v164) = *((_WORD *)v6 + 1),
										  v6 += 4,
										  v166 = v162 + 1,
										  *v166 = __ROR4__(v164, 8),
										  v162 = v166 + 1,
										  v165) )
									{
										do
										{
											v167 = *(_DWORD *)v6;
											v6 += 4;
											v168 = v162 + 1;
											v167 = __ROR4__(v167, 8);
											*v168 = v167;
											v168 += 2;
											*v168 = __ROR4__(v167, 16);
											v162 = v168 + 1;
											--v165;
										}
										while ( v165 );
									}
								}
								else
								{
									v23 = __CFSHR__(v163, 2);
									v169 = v163 >> 2;
									if ( !v23 || (v170 = *((_WORD *)v6 + 1), v6 += 4, *v162 = v170, v162 += 2, v169) )
									{
										do
										{
											v171 = *(_DWORD *)v6;
											v6 += 4;
											*v162 = v171;
											v172 = v162 + 2;
											*v172 = __ROR4__(v171, 16);
											v162 = v172 + 2;
											--v169;
										}
										while ( v169 );
									}
								}
								v2 = (unsigned int)(v162 - 800);
								v161 += 2;
							}
							while ( v161 != 32 );
							return;
						}
					}
					break;
				case 11:
					world_4B325C = 0;
					v173 = 30;
					while ( v2 >= screen_buf_end )
					{
						v174 = 32 - v173;
						v175 = ((_BYTE)world_4B325C + 1) & 1;
						v176 = 32 - v173;
						world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
						if ( v175 )
						{
							for ( i = v174 >> 2; i; --i )
							{
								v178 = *(_DWORD *)v6;
								v6 += 4;
								v179 = (_BYTE *)(v2 + 1);
								v178 = __ROR4__(v178, 8);
								*v179 = v178;
								v179 += 2;
								v175 = __ROR4__(v178, 16);
								*v179 = v175;
								v2 = (unsigned int)(v179 + 1);
							}
							v180 = v176 & 2;
							if ( v180 )
							{
								_LOWORD(v175) = *(_WORD *)v6;
								v6 += 4;
								v181 = (_BYTE *)(v2 + 1);
								*v181 = __ROR4__(v175, 8);
								v2 = (unsigned int)(v181 + 1);
							}
						}
						else
						{
							for ( j = v174 >> 2; j; --j )
							{
								v183 = *(_DWORD *)v6;
								v6 += 4;
								*(_BYTE *)v2 = v183;
								v184 = (_BYTE *)(v2 + 2);
								*v184 = __ROR4__(v183, 16);
								v2 = (unsigned int)(v184 + 2);
							}
							v180 = v176 & 2;
							if ( v180 )
							{
								v185 = *(_WORD *)v6;
								v6 += 4;
								*(_BYTE *)v2 = v185;
								v2 += 2;
							}
						}
						v2 = v173 + v2 - 800;
						v48 = __OFSUB__(v173, 2);
						v173 -= 2;
						if ( (v173 < 0) ^ v48 )
						{
							v186 = 2;
							do
							{
								if ( v2 < screen_buf_end )
									break;
								v187 = 32 - v186;
								v188 = ((_BYTE)world_4B325C + 1) & 1;
								world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
								if ( world_4B325C )
								{
									for ( k = v187 >> 2; k; --k )
									{
										v190 = *(_DWORD *)v6;
										v6 += 4;
										v191 = (_BYTE *)(v2 + 1);
										v190 = __ROR4__(v190, 8);
										*v191 = v190;
										v191 += 2;
										v188 = __ROR4__(v190, 16);
										*v191 = v188;
										v2 = (unsigned int)(v191 + 1);
									}
									v180 &= 2u;
									if ( v180 )
									{
										_LOWORD(v188) = *(_WORD *)v6;
										v6 += 4;
										v192 = (_BYTE *)(v2 + 1);
										*v192 = __ROR4__(v188, 8);
										v2 = (unsigned int)(v192 + 1);
									}
								}
								else
								{
									for ( l = v187 >> 2; l; --l )
									{
										v194 = *(_DWORD *)v6;
										v6 += 4;
										*(_BYTE *)v2 = v194;
										v195 = (_BYTE *)(v2 + 2);
										*v195 = __ROR4__(v194, 16);
										v2 = (unsigned int)(v195 + 2);
									}
									v180 &= 2u;
									if ( v180 )
									{
										v196 = *(_WORD *)v6;
										v6 += 4;
										*(_BYTE *)v2 = v196;
										v2 += 2;
									}
								}
								v2 = v186 + v2 - 800;
								v186 += 2;
							}
							while ( v186 != 32 );
							return;
						}
					}
					break;
				case 12:
					world_4B325C = 0;
					v197 = 30;
					while ( v2 >= screen_buf_end )
					{
						v198 = (_BYTE *)(v197 + v2);
						v199 = 32 - v197;
						v200 = ((_BYTE)world_4B325C + 1) & 1;
						world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
						if ( world_4B325C )
						{
							v23 = __CFSHR__(v199, 2);
							v201 = v199 >> 2;
							if ( !v23
							  || (_LOWORD(v200) = *((_WORD *)v6 + 1),
								  v6 += 4,
								  v202 = v198 + 1,
								  *v202 = __ROR4__(v200, 8),
								  v198 = v202 + 1,
								  v201) )
							{
								do
								{
									v203 = *(_DWORD *)v6;
									v6 += 4;
									v204 = v198 + 1;
									v203 = __ROR4__(v203, 8);
									*v204 = v203;
									v204 += 2;
									*v204 = __ROR4__(v203, 16);
									v198 = v204 + 1;
									--v201;
								}
								while ( v201 );
							}
						}
						else
						{
							v23 = __CFSHR__(v199, 2);
							v205 = v199 >> 2;
							if ( !v23 || (v206 = *((_WORD *)v6 + 1), v6 += 4, *v198 = v206, v198 += 2, v205) )
							{
								do
								{
									v207 = *(_DWORD *)v6;
									v6 += 4;
									*v198 = v207;
									v208 = v198 + 2;
									*v208 = __ROR4__(v207, 16);
									v198 = v208 + 2;
									--v205;
								}
								while ( v205 );
							}
						}
						v2 = (unsigned int)(v198 - 800);
						v48 = __OFSUB__(v197, 2);
						v197 -= 2;
						if ( (v197 < 0) ^ v48 )
						{
							v209 = 8;
							do
							{
								if ( v2 < screen_buf_end )
									break;
								v210 = 8;
								do
								{
									v211 = *(_DWORD *)v6;
									v6 += 4;
									v212 = (_BYTE *)(v2 + 1);
									v211 = __ROR4__(v211, 8);
									*v212 = v211;
									v212 += 2;
									*v212 = __ROR4__(v211, 16);
									v2 = (unsigned int)(v212 + 1);
									--v210;
								}
								while ( v210 );
								v213 = (_BYTE *)(v2 - 800);
								if ( (unsigned int)v213 < screen_buf_end )
									break;
								v214 = 8;
								do
								{
									v215 = *(_DWORD *)v6;
									v6 += 4;
									*v213 = v215;
									v216 = v213 + 2;
									*v216 = __ROR4__(v215, 16);
									v213 = v216 + 2;
									--v214;
								}
								while ( v214 );
								v2 = (unsigned int)(v213 - 800);
								--v209;
							}
							while ( v209 );
							return;
						}
					}
					break;
				default:
					world_4B325C = 0;
					v217 = 30;
					while ( v2 >= screen_buf_end )
					{
						v218 = 32 - v217;
						v219 = ((_BYTE)world_4B325C + 1) & 1;
						world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
						if ( world_4B325C )
						{
							for ( m = v218 >> 2; m; --m )
							{
								v221 = *(_DWORD *)v6;
								v6 += 4;
								v222 = (_BYTE *)(v2 + 1);
								v221 = __ROR4__(v221, 8);
								*v222 = v221;
								v222 += 2;
								v219 = __ROR4__(v221, 16);
								*v222 = v219;
								v2 = (unsigned int)(v222 + 1);
							}
							if ( (32 - (_BYTE)v217) & 2 )
							{
								_LOWORD(v219) = *(_WORD *)v6;
								v6 += 4;
								v223 = (_BYTE *)(v2 + 1);
								*v223 = __ROR4__(v219, 8);
								v2 = (unsigned int)(v223 + 1);
							}
						}
						else
						{
							for ( n = v218 >> 2; n; --n )
							{
								v225 = *(_DWORD *)v6;
								v6 += 4;
								*(_BYTE *)v2 = v225;
								v226 = (_BYTE *)(v2 + 2);
								*v226 = __ROR4__(v225, 16);
								v2 = (unsigned int)(v226 + 2);
							}
							if ( (32 - (_BYTE)v217) & 2 )
							{
								v227 = *(_WORD *)v6;
								v6 += 4;
								*(_BYTE *)v2 = v227;
								v2 += 2;
							}
						}
						v2 = v217 + v2 - 800;
						v48 = __OFSUB__(v217, 2);
						v217 -= 2;
						if ( (v217 < 0) ^ v48 )
						{
							v228 = 8;
							do
							{
								if ( v2 < screen_buf_end )
									break;
								v229 = 8;
								do
								{
									v230 = *(_DWORD *)v6;
									v6 += 4;
									v231 = (_BYTE *)(v2 + 1);
									v230 = __ROR4__(v230, 8);
									*v231 = v230;
									v231 += 2;
									*v231 = __ROR4__(v230, 16);
									v2 = (unsigned int)(v231 + 1);
									--v229;
								}
								while ( v229 );
								v232 = (_BYTE *)(v2 - 800);
								if ( (unsigned int)v232 < screen_buf_end )
									break;
								v233 = 8;
								do
								{
									v234 = *(_DWORD *)v6;
									v6 += 4;
									*v232 = v234;
									v235 = v232 + 2;
									*v235 = __ROR4__(v234, 16);
									v232 = v235 + 2;
									--v233;
								}
								while ( v233 );
								v2 = (unsigned int)(v232 - 800);
								--v228;
							}
							while ( v228 );
							return;
						}
					}
					break;
			}
			return;
		}
		world_4B325C = (unsigned char)a1 & 1;
		v134 = 32;
LABEL_251:
		v135 = 32;
		while ( 1 )
		{
			while ( 1 )
			{
				v136 = (unsigned char)*v6++;
				if ( (v136 & 0x80u) == 0 )
					break;
				_LOBYTE(v136) = -(char)v136;
				v2 += v136;
				v135 -= v136;
				if ( !v135 )
				{
LABEL_271:
					world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
					v2 -= 800;
					if ( !--v134 )
						return;
					goto LABEL_251;
				}
			}
			v135 -= v136;
			if ( v2 < screen_buf_end )
				return;
			if ( (v2 & 1) == world_4B325C )
			{
				v137 = v136 >> 1;
				if ( !(v136 & 1) )
					goto LABEL_258;
				++v6;
				++v2;
				if ( v137 )
				{
LABEL_265:
					v23 = v137 & 1;
					v145 = v137 >> 1;
					if ( !v23 || (v146 = *v6, v6 += 2, *(_BYTE *)v2 = v146, v2 += 2, v145) )
					{
						do
						{
							v147 = *(_DWORD *)v6;
							v6 += 4;
							*(_BYTE *)v2 = v147;
							v148 = (_BYTE *)(v2 + 2);
							*v148 = __ROR4__(v147, 16);
							v2 = (unsigned int)(v148 + 2);
							--v145;
						}
						while ( v145 );
					}
					goto LABEL_268;
				}
			}
			else
			{
				v137 = v136 >> 1;
				if ( !(v136 & 1) )
					goto LABEL_265;
				v144 = *v6++;
				*(_BYTE *)v2++ = v144;
				if ( v137 )
				{
LABEL_258:
					v23 = v137 & 1;
					v138 = v137 >> 1;
					if ( !v23
					  || (v139 = v6 + 1,
						  v140 = (_BYTE *)(v2 + 1),
						  v141 = *v139,
						  v6 = v139 + 1,
						  *v140 = v141,
						  v2 = (unsigned int)(v140 + 1),
						  v138) )
					{
						do
						{
							v142 = *(_DWORD *)v6;
							v6 += 4;
							v143 = (_BYTE *)(v2 + 1);
							v142 = __ROR4__(v142, 8);
							*v143 = v142;
							v143 += 2;
							*v143 = __ROR4__(v142, 16);
							v2 = (unsigned int)(v143 + 1);
							--v138;
						}
						while ( v138 );
					}
					goto LABEL_268;
				}
			}
LABEL_268:
			if ( !v135 )
				goto LABEL_271;
		}
	}
	if ( level_cel_block & 0x8000 )
		level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
						+ (unsigned short)(level_cel_block & 0xF000);
	v9 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
	v10 = level_cel_block;
	_LOBYTE(v10) = BYTE1(v10);
	v11 = (v10 >> 4) & 7;
	if ( !v11 )
	{
		v236 = 16;
		do
		{
			if ( v2 < screen_buf_end )
				break;
			v237 = 8;
			do
			{
				*(_BYTE *)(v2 + 1) = 0;
				*(_BYTE *)(v2 + 3) = 0;
				v2 += 4;
				--v237;
			}
			while ( v237 );
			v238 = (_BYTE *)(v2 - 800);
			if ( (unsigned int)v238 < screen_buf_end )
				break;
			v239 = 8;
			do
			{
				*v238 = 0;
				v238[2] = 0;
				v238 += 4;
				--v239;
			}
			while ( v239 );
			v2 = (unsigned int)(v238 - 800);
			--v236;
		}
		while ( v236 );
		return;
	}
	switch ( (_WORD)v11 )
	{
		case 1:
			world_4B325C = (unsigned char)a1 & 1;
			v240 = 32;
			while ( 1 )
			{
				v241 = 32;
				do
				{
					while ( 1 )
					{
						v242 = *v9++;
						if ( (v242 & 0x80u) != 0 )
							break;
						v241 -= v242;
						if ( v2 < screen_buf_end )
							return;
						v9 += v242;
						if ( (v2 & 1) == world_4B325C )
						{
							v243 = v242 >> 1;
							if ( !(v242 & 1) )
								goto LABEL_378;
							++v2;
							if ( v243 )
							{
LABEL_385:
								v23 = v243 & 1;
								v246 = v243 >> 1;
								if ( !v23 || (*(_BYTE *)v2 = 0, v2 += 2, v246) )
								{
									do
									{
										*(_BYTE *)v2 = 0;
										*(_BYTE *)(v2 + 2) = 0;
										v2 += 4;
										--v246;
									}
									while ( v246 );
								}
								goto LABEL_388;
							}
						}
						else
						{
							v243 = v242 >> 1;
							if ( !(v242 & 1) )
								goto LABEL_385;
							*(_BYTE *)v2++ = 0;
							if ( v243 )
							{
LABEL_378:
								v23 = v243 & 1;
								v244 = v243 >> 1;
								if ( !v23 || (v245 = (_BYTE *)(v2 + 1), *v245 = 0, v2 = (unsigned int)(v245 + 1), v244) )
								{
									do
									{
										*(_BYTE *)(v2 + 1) = 0;
										*(_BYTE *)(v2 + 3) = 0;
										v2 += 4;
										--v244;
									}
									while ( v244 );
								}
								goto LABEL_388;
							}
						}
LABEL_388:
						if ( !v241 )
							goto LABEL_391;
					}
					_LOBYTE(v242) = -(char)v242;
					v2 += v242;
					v241 -= v242;
				}
				while ( v241 );
LABEL_391:
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				v2 -= 800;
				if ( !--v240 )
					return;
			}
		case 2:
			world_4B325C = 0;
			for ( ii = 30; ; ii -= 2 )
			{
				if ( v2 < screen_buf_end )
					return;
				v248 = (_BYTE *)(ii + v2);
				v249 = 32 - ii;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v23 = __CFSHR__(v249, 2);
					v250 = v249 >> 2;
					if ( !v23 || (v251 = v248 + 1, *v251 = 0, v248 = v251 + 1, v250) )
					{
						do
						{
							v248[1] = 0;
							v248[3] = 0;
							v248 += 4;
							--v250;
						}
						while ( v250 );
					}
				}
				else
				{
					v23 = __CFSHR__(v249, 2);
					v252 = v249 >> 2;
					if ( !v23 || (*v248 = 0, v248 += 2, v252) )
					{
						do
						{
							*v248 = 0;
							v248[2] = 0;
							v248 += 4;
							--v252;
						}
						while ( v252 );
					}
				}
				v2 = (unsigned int)(v248 - 800);
				if ( !ii )
					break;
			}
			v253 = 2;
			do
			{
				if ( v2 < screen_buf_end )
					break;
				v254 = (_BYTE *)(v253 + v2);
				v255 = 32 - v253;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v23 = __CFSHR__(v255, 2);
					v256 = v255 >> 2;
					if ( !v23 || (v257 = v254 + 1, *v257 = 0, v254 = v257 + 1, v256) )
					{
						do
						{
							v254[1] = 0;
							v254[3] = 0;
							v254 += 4;
							--v256;
						}
						while ( v256 );
					}
				}
				else
				{
					v23 = __CFSHR__(v255, 2);
					v258 = v255 >> 2;
					if ( !v23 || (*v254 = 0, v254 += 2, v258) )
					{
						do
						{
							*v254 = 0;
							v254[2] = 0;
							v254 += 4;
							--v258;
						}
						while ( v258 );
					}
				}
				v2 = (unsigned int)(v254 - 800);
				v253 += 2;
			}
			while ( v253 != 32 );
			break;
		case 3:
			world_4B325C = 0;
			for ( jj = 30; ; jj -= 2 )
			{
				if ( v2 < screen_buf_end )
					return;
				v260 = 32 - jj;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v23 = __CFSHR__(v260, 2);
					v261 = v260 >> 2;
					if ( !v23 || (v262 = (_BYTE *)(v2 + 1), *v262 = 0, v2 = (unsigned int)(v262 + 1), v261) )
					{
						do
						{
							*(_BYTE *)(v2 + 1) = 0;
							*(_BYTE *)(v2 + 3) = 0;
							v2 += 4;
							--v261;
						}
						while ( v261 );
					}
				}
				else
				{
					v23 = __CFSHR__(v260, 2);
					v263 = v260 >> 2;
					if ( !v23 || (*(_BYTE *)v2 = 0, v2 += 2, v263) )
					{
						do
						{
							*(_BYTE *)v2 = 0;
							*(_BYTE *)(v2 + 2) = 0;
							v2 += 4;
							--v263;
						}
						while ( v263 );
					}
				}
				v264 = (_BYTE *)(v2 - 800);
				if ( !jj )
					break;
				v2 = (unsigned int)&v264[jj];
			}
			v265 = 2;
			do
			{
				if ( (unsigned int)v264 < screen_buf_end )
					break;
				v266 = 32 - v265;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v23 = __CFSHR__(v266, 2);
					v267 = v266 >> 2;
					if ( !v23 || (v268 = v264 + 1, *v268 = 0, v264 = v268 + 1, v267) )
					{
						do
						{
							v264[1] = 0;
							v264[3] = 0;
							v264 += 4;
							--v267;
						}
						while ( v267 );
					}
				}
				else
				{
					v23 = __CFSHR__(v266, 2);
					v269 = v266 >> 2;
					if ( !v23 || (*v264 = 0, v264 += 2, v269) )
					{
						do
						{
							*v264 = 0;
							v264[2] = 0;
							v264 += 4;
							--v269;
						}
						while ( v269 );
					}
				}
				v264 = &v264[v265 - 800];
				v265 += 2;
			}
			while ( v265 != 32 );
			break;
		case 4:
			world_4B325C = 0;
			for ( kk = 30; ; kk -= 2 )
			{
				if ( v2 < screen_buf_end )
					return;
				v271 = (_BYTE *)(kk + v2);
				v272 = 32 - kk;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v23 = __CFSHR__(v272, 2);
					v273 = v272 >> 2;
					if ( !v23 || (v274 = v271 + 1, *v274 = 0, v271 = v274 + 1, v273) )
					{
						do
						{
							v271[1] = 0;
							v271[3] = 0;
							v271 += 4;
							--v273;
						}
						while ( v273 );
					}
				}
				else
				{
					v23 = __CFSHR__(v272, 2);
					v275 = v272 >> 2;
					if ( !v23 || (*v271 = 0, v271 += 2, v275) )
					{
						do
						{
							*v271 = 0;
							v271[2] = 0;
							v271 += 4;
							--v275;
						}
						while ( v275 );
					}
				}
				v2 = (unsigned int)(v271 - 800);
				if ( !kk )
					break;
			}
			v276 = 8;
			do
			{
				if ( v2 < screen_buf_end )
					break;
				v277 = 8;
				do
				{
					*(_BYTE *)(v2 + 1) = 0;
					*(_BYTE *)(v2 + 3) = 0;
					v2 += 4;
					--v277;
				}
				while ( v277 );
				v278 = (_BYTE *)(v2 - 800);
				if ( (unsigned int)v278 < screen_buf_end )
					break;
				v279 = 8;
				do
				{
					*v278 = 0;
					v278[2] = 0;
					v278 += 4;
					--v279;
				}
				while ( v279 );
				v2 = (unsigned int)(v278 - 800);
				--v276;
			}
			while ( v276 );
			break;
		default:
			world_4B325C = 0;
			for ( ll = 30; ; ll -= 2 )
			{
				if ( v2 < screen_buf_end )
					return;
				v281 = 32 - ll;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v23 = __CFSHR__(v281, 2);
					v282 = v281 >> 2;
					if ( !v23 || (v283 = (_BYTE *)(v2 + 1), *v283 = 0, v2 = (unsigned int)(v283 + 1), v282) )
					{
						do
						{
							*(_BYTE *)(v2 + 1) = 0;
							*(_BYTE *)(v2 + 3) = 0;
							v2 += 4;
							--v282;
						}
						while ( v282 );
					}
				}
				else
				{
					v23 = __CFSHR__(v281, 2);
					v284 = v281 >> 2;
					if ( !v23 || (*(_BYTE *)v2 = 0, v2 += 2, v284) )
					{
						do
						{
							*(_BYTE *)v2 = 0;
							*(_BYTE *)(v2 + 2) = 0;
							v2 += 4;
							--v284;
						}
						while ( v284 );
					}
				}
				v285 = v2 - 800;
				if ( !ll )
					break;
				v2 = ll + v285;
			}
			v286 = 8;
			do
			{
				if ( v285 < screen_buf_end )
					break;
				v287 = 8;
				do
				{
					*(_BYTE *)(v285 + 1) = 0;
					*(_BYTE *)(v285 + 3) = 0;
					v285 += 4;
					--v287;
				}
				while ( v287 );
				v288 = (_BYTE *)(v285 - 800);
				if ( (unsigned int)v288 < screen_buf_end )
					break;
				v289 = 8;
				do
				{
					*v288 = 0;
					v288[2] = 0;
					v288 += 4;
					--v289;
				}
				while ( v289 );
				v285 = (unsigned int)(v288 - 800);
				--v286;
			}
			while ( v286 );
			break;
	}
}
// 642A14: using guessed type char lightmax;
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF14: using guessed type int level_cel_block;

//----- (0046468D) --------------------------------------------------------
void __fastcall drawBottomArchesUpperScreen(void *a1, int a2)
{
	_BYTE *v2; // edi
	char *v3; // esi
	short v5; // ax
	char *v6; // esi
	short v7; // ax
	unsigned int v8; // eax
	unsigned char *v9; // esi
	unsigned int v10; // eax
	int v11; // eax
	int v12; // edx
	int v13; // edx
	signed int v14; // ecx
	unsigned char v16; // cf
	int v18; // ecx
	signed int v19; // edx
	int v20; // eax
	int v21; // edx
	int v22; // ecx
	int v23; // edx
	signed int v26; // edx
	_WORD *v27; // edi
	unsigned int v28; // ecx
	unsigned char v31; // of
	signed int v32; // edx
	_WORD *v33; // edi
	unsigned int v34; // ecx
	signed int v37; // edx
	unsigned int l; // ecx
	signed int v41; // edx
	unsigned int m; // ecx
	signed int v45; // edx
	_WORD *v46; // edi
	unsigned int v47; // ecx
	int v50; // edx
	int v51; // edx
	signed int v52; // ecx
	signed int v55; // edx
	unsigned int n; // ecx
	int v59; // edx
	int v60; // edx
	signed int v61; // ecx
	int v64; // edx
	int v65; // edx
	signed int v66; // ecx
	char v67; // al
	int v68; // ecx
	signed int v69; // edx
	int v70; // eax
	int v71; // edx
	int v72; // edx
	int v73; // ecx
	char v74; // al
	signed int v75; // edx
	_DWORD *v76; // edi
	unsigned int v77; // ecx
	short v78; // ax
	int v79; // eax
	signed int v80; // edx
	_WORD *v81; // edi
	unsigned int v82; // ecx
	short v83; // ax
	int v84; // eax
	signed int v85; // edx
	unsigned int i; // ecx
	int v87; // eax
	short v88; // ax
	signed int v89; // edx
	unsigned int j; // ecx
	int v91; // eax
	short v92; // ax
	signed int v93; // edx
	_DWORD *v94; // edi
	unsigned int v95; // ecx
	short v96; // ax
	int v97; // eax
	int v98; // edx
	int v99; // edx
	signed int v100; // ecx
	char v101; // al
	signed int v102; // edx
	unsigned int k; // ecx
	int v104; // eax
	short v105; // ax
	int v106; // edx
	int v107; // edx
	signed int v108; // ecx
	char v109; // al
	int v110; // edx
	int v111; // edx
	signed int v112; // ecx
	int v113; // ecx
	signed int v114; // edx
	int v115; // eax
	int v116; // edx
	int v117; // edx
	int v118; // ecx
	signed int v119; // edx
	_DWORD *v120; // edi
	unsigned int v121; // ecx
	signed int v122; // edx
	_WORD *v123; // edi
	unsigned int v124; // ecx
	signed int v125; // edx
	unsigned int v126; // ecx
	_WORD *v127; // edi
	signed int v128; // edx
	unsigned int v129; // ecx
	signed int v130; // edx
	_DWORD *v131; // edi
	unsigned int v132; // ecx
	int v133; // edx
	int v134; // edx
	signed int v135; // ecx
	signed int v136; // edx
	unsigned int v137; // ecx
	_BYTE *v138; // edi
	int v139; // edx
	int v140; // edx
	signed int v141; // ecx
	int v142; // [esp-8h] [ebp-14h]
	int v143; // [esp-8h] [ebp-14h]
	int v144; // [esp-8h] [ebp-14h]
	int v145; // [esp-8h] [ebp-14h]
	int v146; // [esp-8h] [ebp-14h]
	int v147; // [esp-4h] [ebp-10h]
	int v148; // [esp-4h] [ebp-10h]
	int v149; // [esp-4h] [ebp-10h]
	int v150; // [esp-4h] [ebp-10h]
	int v151; // [esp-4h] [ebp-10h]
	int v152; // [esp-4h] [ebp-10h]
	int v153; // [esp-4h] [ebp-10h]
	int v154; // [esp-4h] [ebp-10h]
	int v155; // [esp-4h] [ebp-10h]
	int v156; // [esp-4h] [ebp-10h]

	world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num;
	v2 = (unsigned char *)a1;
	world_4B3269[0] = a2;
	if ( !(_BYTE)light_table_index )
	{
		if ( level_cel_block & 0x8000 )
			level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
							+ (unsigned short)(level_cel_block & 0xF000);
		v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v8 = level_cel_block;
		_LOBYTE(v8) = BYTE1(v8);
		v7 = ((v8 >> 4) & 7) + 8;
LABEL_12:
		switch ( v7 )
		{
			case 8:
				v64 = 32;
				do
				{
					if ( (unsigned int)v2 < screen_buf_end )
						break;
					v150 = v64;
					v65 = *(_DWORD *)world_4B3269[0];
					v66 = 32;
					do
					{
						v67 = *v6++;
						v16 = __CFSHL__(v65, 1);
						v65 *= 2;
						if ( v16 )
							*v2 = v67;
						++v2;
						--v66;
					}
					while ( v66 );
					v2 -= 800;
					world_4B3269[0] -= 4;
					v64 = v150 - 1;
				}
				while ( v150 != 1 );
				break;
			case 9:
				v68 = 32;
				do
				{
					v151 = v68;
					*(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0];
					v69 = 32;
					do
					{
						while ( 1 )
						{
							v70 = (unsigned char)*v6++;
							if ( (v70 & 0x80u) == 0 )
								break;
							_LOBYTE(v70) = -(char)v70;
							v2 += v70;
							if ( v70 & 0x1F )
								*(_DWORD *)world_4B3260 <<= v70 & 0x1F;
							v69 -= v70;
							if ( !v69 )
								goto LABEL_129;
						}
						v71 = v69 - v70;
						if ( (unsigned int)v2 < screen_buf_end )
							return;
						v144 = v71;
						v72 = *(_DWORD *)world_4B3260;
						v73 = v70;
						do
						{
							v74 = *v6++;
							v16 = __CFSHL__(v72, 1);
							v72 *= 2;
							if ( v16 )
								*v2 = v74;
							++v2;
							--v73;
						}
						while ( v73 );
						*(_DWORD *)world_4B3260 = v72;
						v69 = v144;
					}
					while ( v144 );
LABEL_129:
					v2 -= 800;
					world_4B3269[0] -= 4;
					v68 = v151 - 1;
				}
				while ( v151 != 1 );
				break;
			case 10:
				v75 = 30;
				while ( (unsigned int)v2 >= screen_buf_end )
				{
					v76 = (unsigned int *)&v2[v75];
					v77 = (unsigned int)(32 - v75) >> 2;
					if ( !__CFSHR__(32 - v75, 2)
					  || (v78 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v76 = v78, v76 = (_DWORD *)((char *)v76 + 2), v77) )
					{
						do
						{
							v79 = *(_DWORD *)v6;
							v6 += 4;
							*v76 = v79;
							--v77;
							++v76;
						}
						while ( v77 );
					}
					v2 = (unsigned char *)v76 - 200;
					v31 = __OFSUB__(v75, 2);
					v75 -= 2;
					if ( (v75 < 0) ^ v31 )
					{
						v80 = 2;
						do
						{
							if ( (unsigned int)v2 < screen_buf_end )
								break;
							v81 = (unsigned short *)&v2[v80];
							v82 = (unsigned int)(32 - v80) >> 2;
							if ( __CFSHR__(32 - v80, 2) )
							{
								v83 = *((_WORD *)v6 + 1);
								v6 += 4;
								*v81 = v83;
								++v81;
								if ( !v82 )
									continue;
							}
							do
							{
								v84 = *(_DWORD *)v6;
								v6 += 4;
								*(_DWORD *)v81 = v84;
								v81 += 2;
								--v82;
							}
							while ( v82 );
							v2 = (unsigned char *)v81 - 400;
							v80 += 2;
						}
						while ( v80 != 32 );
						return;
					}
				}
				break;
			case 11:
				v85 = 30;
				while ( (unsigned int)v2 >= screen_buf_end )
				{
					for ( i = (unsigned int)(32 - v85) >> 2; i; --i )
					{
						v87 = *(_DWORD *)v6;
						v6 += 4;
						*(_DWORD *)v2 = v87;
						v2 += 4;
					}
					if ( (32 - (_BYTE)v85) & 2 )
					{
						v88 = *(_WORD *)v6;
						v6 += 4;
						*(_WORD *)v2 = v88;
						v2 += 2;
					}
					v2 = &v2[v85 - 800];
					v31 = __OFSUB__(v85, 2);
					v85 -= 2;
					if ( (v85 < 0) ^ v31 )
					{
						v89 = 2;
						do
						{
							if ( (unsigned int)v2 < screen_buf_end )
								break;
							for ( j = (unsigned int)(32 - v89) >> 2; j; --j )
							{
								v91 = *(_DWORD *)v6;
								v6 += 4;
								*(_DWORD *)v2 = v91;
								v2 += 4;
							}
							if ( (32 - (_BYTE)v89) & 2 )
							{
								v92 = *(_WORD *)v6;
								v6 += 4;
								*(_WORD *)v2 = v92;
								v2 += 2;
							}
							v2 = &v2[v89 - 800];
							v89 += 2;
						}
						while ( v89 != 32 );
						return;
					}
				}
				break;
			case 12:
				v93 = 30;
				while ( (unsigned int)v2 >= screen_buf_end )
				{
					v94 = (unsigned int *)&v2[v93];
					v95 = (unsigned int)(32 - v93) >> 2;
					if ( !__CFSHR__(32 - v93, 2)
					  || (v96 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v94 = v96, v94 = (_DWORD *)((char *)v94 + 2), v95) )
					{
						do
						{
							v97 = *(_DWORD *)v6;
							v6 += 4;
							*v94 = v97;
							++v94;
							--v95;
						}
						while ( v95 );
					}
					v2 = (unsigned char *)v94 - 200;
					v31 = __OFSUB__(v93, 2);
					v93 -= 2;
					if ( (v93 < 0) ^ v31 )
					{
						world_4B3269[0] -= 64;
						v98 = 16;
						do
						{
							if ( (unsigned int)v2 < screen_buf_end )
								break;
							v152 = v98;
							v99 = *(_DWORD *)world_4B3269[0];
							v100 = 32;
							do
							{
								v101 = *v6++;
								v16 = __CFSHL__(v99, 1);
								v99 *= 2;
								if ( v16 )
									*v2 = v101;
								++v2;
								--v100;
							}
							while ( v100 );
							v2 -= 800;
							world_4B3269[0] -= 4;
							v98 = v152 - 1;
						}
						while ( v152 != 1 );
						return;
					}
				}
				break;
			default:
				v102 = 30;
				while ( (unsigned int)v2 >= screen_buf_end )
				{
					for ( k = (unsigned int)(32 - v102) >> 2; k; --k )
					{
						v104 = *(_DWORD *)v6;
						v6 += 4;
						*(_DWORD *)v2 = v104;
						v2 += 4;
					}
					if ( (32 - (_BYTE)v102) & 2 )
					{
						v105 = *(_WORD *)v6;
						v6 += 4;
						*(_WORD *)v2 = v105;
						v2 += 2;
					}
					v2 = &v2[v102 - 800];
					v31 = __OFSUB__(v102, 2);
					v102 -= 2;
					if ( (v102 < 0) ^ v31 )
					{
						world_4B3269[0] -= 64;
						v106 = 16;
						do
						{
							if ( (unsigned int)v2 < screen_buf_end )
								break;
							v145 = v106;
							v107 = *(_DWORD *)world_4B3269[0];
							v108 = 32;
							do
							{
								v109 = *v6++;
								v16 = __CFSHL__(v107, 1);
								v107 *= 2;
								if ( v16 )
									*v2 = v109;
								++v2;
								--v108;
							}
							while ( v108 );
							v6 += (unsigned char)v6 & 2;
							v2 -= 800;
							world_4B3269[0] -= 4;
							v106 = v145 - 1;
						}
						while ( v145 != 1 );
						return;
					}
				}
				break;
		}
		return;
	}
	if ( (_BYTE)light_table_index != lightmax )
	{
		if ( !(level_cel_block & 0x8000) )
		{
			v3 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
/*			_EBX = dword_646A20 + (light_table_index << 8);
			v5 = (unsigned char)(BYTE1(level_cel_block) >> 4);
			if ( !(BYTE1(level_cel_block) >> 4) )
			{
				v12 = 32;
				do
				{
					if ( (unsigned int)v2 < screen_buf_end )
						break;
					v147 = v12;
					v13 = *(_DWORD *)world_4B3269[0];
					v14 = 32;
					do
					{
						_AL = *v3++;
						v16 = __CFSHL__(v13, 1);
						v13 *= 2;
						if ( v16 )
						{
							__asm { xlat }
							*v2 = _AL;
						}
						++v2;
						--v14;
					}
					while ( v14 );
					v2 -= 800;
					world_4B3269[0] -= 4;
					v12 = v147 - 1;
				}
				while ( v147 != 1 );
				return;
			}
			if ( BYTE1(level_cel_block) >> 4 )
			{
				switch ( v5 )
				{
					case 1:
						v18 = 32;
						do
						{
							v148 = v18;
							*(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0];
							v19 = 32;
							do
							{
								while ( 1 )
								{
									v20 = (unsigned char)*v3++;
									if ( (v20 & 0x80u) == 0 )
										break;
									_LOBYTE(v20) = -(char)v20;
									v2 += v20;
									if ( v20 & 0x1F )
										*(_DWORD *)world_4B3260 <<= v20 & 0x1F;
									v19 -= v20;
									if ( !v19 )
										goto LABEL_50;
								}
								v21 = v19 - v20;
								if ( (unsigned int)v2 < screen_buf_end )
									return;
								v22 = v20;
								v142 = v21;
								v23 = *(_DWORD *)world_4B3260;
								do
								{
									_AL = *v3++;
									v16 = __CFSHL__(v23, 1);
									v23 *= 2;
									if ( v16 )
									{
										__asm { xlat }
										*v2 = _AL;
									}
									++v2;
									--v22;
								}
								while ( v22 );
								*(_DWORD *)world_4B3260 = v23;
								v19 = v142;
							}
							while ( v142 );
LABEL_50:
							v2 -= 800;
							world_4B3269[0] -= 4;
							v18 = v148 - 1;
						}
						while ( v148 != 1 );
						break;
					case 2:
						v26 = 30;
						while ( (unsigned int)v2 >= screen_buf_end )
						{
							v27 = &v2[v26];
							v28 = (unsigned int)(32 - v26) >> 2;
							if ( !__CFSHR__(32 - v26, 2) )
								goto LABEL_268;
							_AX = *((_WORD *)v3 + 1);
							v3 += 4;
							__asm { xlat }
							_AX = __ROR2__(_AX, 8);
							__asm { xlat }
							*v27 = __ROR2__(_AX, 8);
							++v27;
							if ( v28 )
							{
LABEL_268:
								do
								{
									_EAX = *(_DWORD *)v3;
									v3 += 4;
									__asm { xlat }
									_EAX = __ROR4__(_EAX, 8);
									__asm { xlat }
									_EAX = __ROR4__(_EAX, 8);
									__asm { xlat }
									_EAX = __ROR4__(_EAX, 8);
									__asm { xlat }
									*(_DWORD *)v27 = __ROR4__(_EAX, 8);
									v27 += 2;
									--v28;
								}
								while ( v28 );
							}
							v2 = v27 - 400;
							v31 = __OFSUB__(v26, 2);
							v26 -= 2;
							if ( (v26 < 0) ^ v31 )
							{
								v32 = 2;
								do
								{
									if ( (unsigned int)v2 < screen_buf_end )
										break;
									v33 = &v2[v32];
									v34 = (unsigned int)(32 - v32) >> 2;
									if ( !__CFSHR__(32 - v32, 2) )
										goto LABEL_269;
									_AX = *((_WORD *)v3 + 1);
									v3 += 4;
									__asm { xlat }
									_AX = __ROR2__(_AX, 8);
									__asm { xlat }
									*v33 = __ROR2__(_AX, 8);
									++v33;
									if ( v34 )
									{
LABEL_269:
										do
										{
											_EAX = *(_DWORD *)v3;
											v3 += 4;
											__asm { xlat }
											_EAX = __ROR4__(_EAX, 8);
											__asm { xlat }
											_EAX = __ROR4__(_EAX, 8);
											__asm { xlat }
											_EAX = __ROR4__(_EAX, 8);
											__asm { xlat }
											*(_DWORD *)v33 = __ROR4__(_EAX, 8);
											v33 += 2;
											--v34;
										}
										while ( v34 );
									}
									v2 = v33 - 400;
									v32 += 2;
								}
								while ( v32 != 32 );
								return;
							}
						}
						break;
					case 3:
						v37 = 30;
						while ( (unsigned int)v2 >= screen_buf_end )
						{
							for ( l = (unsigned int)(32 - v37) >> 2; l; --l )
							{
								_EAX = *(_DWORD *)v3;
								v3 += 4;
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								*(_DWORD *)v2 = __ROR4__(_EAX, 8);
								v2 += 4;
							}
							if ( (32 - (_BYTE)v37) & 2 )
							{
								_AX = *(_WORD *)v3;
								v3 += 4;
								__asm { xlat }
								_AX = __ROR2__(_AX, 8);
								__asm { xlat }
								*(_WORD *)v2 = __ROR2__(_AX, 8);
								v2 += 2;
							}
							v2 = &v2[v37 - 800];
							v31 = __OFSUB__(v37, 2);
							v37 -= 2;
							if ( (v37 < 0) ^ v31 )
							{
								v41 = 2;
								do
								{
									if ( (unsigned int)v2 < screen_buf_end )
										break;
									for ( m = (unsigned int)(32 - v41) >> 2; m; --m )
									{
										_EAX = *(_DWORD *)v3;
										v3 += 4;
										__asm { xlat }
										_EAX = __ROR4__(_EAX, 8);
										__asm { xlat }
										_EAX = __ROR4__(_EAX, 8);
										__asm { xlat }
										_EAX = __ROR4__(_EAX, 8);
										__asm { xlat }
										*(_DWORD *)v2 = __ROR4__(_EAX, 8);
										v2 += 4;
									}
									if ( (32 - (_BYTE)v41) & 2 )
									{
										_AX = *(_WORD *)v3;
										v3 += 4;
										__asm { xlat }
										_AX = __ROR2__(_AX, 8);
										__asm { xlat }
										*(_WORD *)v2 = __ROR2__(_AX, 8);
										v2 += 2;
									}
									v2 = &v2[v41 - 800];
									v41 += 2;
								}
								while ( v41 != 32 );
								return;
							}
						}
						break;
					case 4:
						v45 = 30;
						while ( (unsigned int)v2 >= screen_buf_end )
						{
							v46 = &v2[v45];
							v47 = (unsigned int)(32 - v45) >> 2;
							if ( !__CFSHR__(32 - v45, 2) )
								goto LABEL_270;
							_AX = *((_WORD *)v3 + 1);
							v3 += 4;
							__asm { xlat }
							_AX = __ROR2__(_AX, 8);
							__asm { xlat }
							*v46 = __ROR2__(_AX, 8);
							++v46;
							if ( v47 )
							{
LABEL_270:
								do
								{
									_EAX = *(_DWORD *)v3;
									v3 += 4;
									__asm { xlat }
									_EAX = __ROR4__(_EAX, 8);
									__asm { xlat }
									_EAX = __ROR4__(_EAX, 8);
									__asm { xlat }
									_EAX = __ROR4__(_EAX, 8);
									__asm { xlat }
									*(_DWORD *)v46 = __ROR4__(_EAX, 8);
									v46 += 2;
									--v47;
								}
								while ( v47 );
							}
							v2 = v46 - 400;
							v31 = __OFSUB__(v45, 2);
							v45 -= 2;
							if ( (v45 < 0) ^ v31 )
							{
								world_4B3269[0] -= 64;
								v50 = 16;
								do
								{
									if ( (unsigned int)v2 < screen_buf_end )
										break;
									v149 = v50;
									v51 = *(_DWORD *)world_4B3269[0];
									v52 = 32;
									v3 += (unsigned char)v3 & 2;
									do
									{
										_AL = *v3++;
										v16 = __CFSHL__(v51, 1);
										v51 *= 2;
										if ( v16 )
										{
											__asm { xlat }
											*v2 = _AL;
										}
										++v2;
										--v52;
									}
									while ( v52 );
									v2 -= 800;
									world_4B3269[0] -= 4;
									v50 = v149 - 1;
								}
								while ( v149 != 1 );
								return;
							}
						}
						break;
					default:
						v55 = 30;
						while ( (unsigned int)v2 >= screen_buf_end )
						{
							for ( n = (unsigned int)(32 - v55) >> 2; n; --n )
							{
								_EAX = *(_DWORD *)v3;
								v3 += 4;
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								*(_DWORD *)v2 = __ROR4__(_EAX, 8);
								v2 += 4;
							}
							if ( (32 - (_BYTE)v55) & 2 )
							{
								_AX = *(_WORD *)v3;
								v3 += 4;
								__asm { xlat }
								_AX = __ROR2__(_AX, 8);
								__asm { xlat }
								*(_WORD *)v2 = __ROR2__(_AX, 8);
								v2 += 2;
							}
							v2 = &v2[v55 - 800];
							v31 = __OFSUB__(v55, 2);
							v55 -= 2;
							if ( (v55 < 0) ^ v31 )
							{
								world_4B3269[0] -= 64;
								v59 = 16;
								do
								{
									if ( (unsigned int)v2 < screen_buf_end )
										break;
									v143 = v59;
									v60 = *(_DWORD *)world_4B3269[0];
									v61 = 32;
									do
									{
										_AL = *v3++;
										v16 = __CFSHL__(v60, 1);
										v60 *= 2;
										if ( v16 )
										{
											__asm { xlat }
											*v2 = _AL;
										}
										++v2;
										--v61;
									}
									while ( v61 );
									v3 += (unsigned char)v3 & 2;
									v2 -= 800;
									world_4B3269[0] -= 4;
									v59 = v143 - 1;
								}
								while ( v143 != 1 );
								return;
							}
						}
						break;
				}
				return;
			}*/
LABEL_187:
			/*v110 = 32;
			do
			{
				if ( (unsigned int)v2 < screen_buf_end )
					break;
				v153 = v110;
				v111 = *(_DWORD *)world_4B3269[0];
				v112 = 32;
				do
				{
					v16 = __CFSHL__(v111, 1);
					v111 *= 2;
					if ( v16 )
						*v2 = 0;
					++v2;
					--v112;
				}
				while ( v112 );
				v2 -= 800;
				world_4B3269[0] -= 4;
				v110 = v153 - 1;
			}
			while ( v153 != 1 );*/
			return;
		}
		v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265);
		v7 = (unsigned char)(BYTE1(level_cel_block) >> 4);
		goto LABEL_12;
	}
	if ( level_cel_block & 0x8000 )
		level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
						+ (unsigned short)(level_cel_block & 0xF000);
	v9 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
	v10 = level_cel_block;
	_LOBYTE(v10) = BYTE1(v10);
	v11 = (v10 >> 4) & 7;
	if ( !v11 )
		goto LABEL_187;
	switch ( (_WORD)v11 )
	{
		case 1:
			v113 = 32;
			do
			{
				v154 = v113;
				*(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0];
				v114 = 32;
				do
				{
					while ( 1 )
					{
						v115 = *v9++;
						if ( (v115 & 0x80u) == 0 )
							break;
						_LOBYTE(v115) = -(char)v115;
						v2 += v115;
						if ( v115 & 0x1F )
							*(_DWORD *)world_4B3260 <<= v115 & 0x1F;
						v114 -= v115;
						if ( !v114 )
							goto LABEL_208;
					}
					v116 = v114 - v115;
					if ( (unsigned int)v2 < screen_buf_end )
						return;
					v146 = v116;
					v117 = *(_DWORD *)world_4B3260;
					v118 = v115;
					v9 += v115;
					do
					{
						v16 = __CFSHL__(v117, 1);
						v117 *= 2;
						if ( v16 )
							*v2 = 0;
						++v2;
						--v118;
					}
					while ( v118 );
					*(_DWORD *)world_4B3260 = v117;
					v114 = v146;
				}
				while ( v146 );
LABEL_208:
				v2 -= 800;
				world_4B3269[0] -= 4;
				v113 = v154 - 1;
			}
			while ( v154 != 1 );
			break;
		case 2:
			v119 = 30;
			while ( (unsigned int)v2 >= screen_buf_end )
			{
				v120 = (unsigned int *)&v2[v119];
				v121 = (unsigned int)(32 - v119) >> 2;
				if ( !__CFSHR__(32 - v119, 2) || (*(_WORD *)v120 = 0, v120 = (_DWORD *)((char *)v120 + 2), v121) )
				{
					do
					{
						*v120 = 0;
						++v120;
						--v121;
					}
					while ( v121 );
				}
				v2 = (unsigned char *)v120 - 200;
				if ( !v119 )
				{
					v122 = 2;
					do
					{
						if ( (unsigned int)v2 < screen_buf_end )
							break;
						v123 = (unsigned short *)&v2[v122];
						v124 = (unsigned int)(32 - v122) >> 2;
						if ( __CFSHR__(32 - v122, 2) )
						{
							*v123 = 0;
							++v123;
							if ( !v124 )
								continue;
						}
						do
						{
							*(_DWORD *)v123 = 0;
							v123 += 2;
							--v124;
						}
						while ( v124 );
						v2 = (unsigned char *)v123 - 400;
						v122 += 2;
					}
					while ( v122 != 32 );
					return;
				}
				v119 -= 2;
			}
			break;
		case 3:
			v125 = 30;
			while ( (unsigned int)v2 >= screen_buf_end )
			{
				v126 = (unsigned int)(32 - v125) >> 2;
				if ( !__CFSHR__(32 - v125, 2) || (*(_WORD *)v2 = 0, v2 += 2, v126) )
				{
					do
					{
						*(_DWORD *)v2 = 0;
						v2 += 4;
						--v126;
					}
					while ( v126 );
				}
				v127 = (unsigned short *)v2 - 800;
				if ( !v125 )
				{
					v128 = 1;
					do
					{
						if ( (unsigned int)v127 < screen_buf_end )
							break;
						v129 = (unsigned int)(32 - v128 * 2) >> 2;
						if ( __CFSHR__(32 - v128 * 2, 2) )
						{
							*v127 = 0;
							++v127;
							if ( !v129 )
								continue;
						}
						do
						{
							*(_DWORD *)v127 = 0;
							v127 += 2;
							--v129;
						}
						while ( v129 );
						v127 = &v127[v128 - 400];
						++v128;
					}
					while ( v128 != 16 );
					return;
				}
				v2 = (unsigned char *)&v127[v125 / 2u];
				v125 -= 2;
			}
			break;
		case 4:
			v130 = 30;
			while ( (unsigned int)v2 >= screen_buf_end )
			{
				v131 = (unsigned int *)&v2[v130];
				v132 = (unsigned int)(32 - v130) >> 2;
				if ( !__CFSHR__(32 - v130, 2) || (*(_WORD *)v131 = 0, v131 = (_DWORD *)((char *)v131 + 2), v132) )
				{
					do
					{
						*v131 = 0;
						++v131;
						--v132;
					}
					while ( v132 );
				}
				v2 = (unsigned char *)v131 - 200;
				if ( !v130 )
				{
					world_4B3269[0] -= 64;
					v133 = 16;
					do
					{
						if ( (unsigned int)v2 < screen_buf_end )
							break;
						v155 = v133;
						v134 = *(_DWORD *)world_4B3269[0];
						v135 = 32;
						do
						{
							v16 = __CFSHL__(v134, 1);
							v134 *= 2;
							if ( v16 )
								*v2 = 0;
							++v2;
							--v135;
						}
						while ( v135 );
						v2 -= 800;
						world_4B3269[0] -= 4;
						v133 = v155 - 1;
					}
					while ( v155 != 1 );
					return;
				}
				v130 -= 2;
			}
			break;
		default:
			v136 = 30;
			while ( (unsigned int)v2 >= screen_buf_end )
			{
				v137 = (unsigned int)(32 - v136) >> 2;
				if ( !__CFSHR__(32 - v136, 2) || (*(_WORD *)v2 = 0, v2 += 2, v137) )
				{
					do
					{
						*(_DWORD *)v2 = 0;
						v2 += 4;
						--v137;
					}
					while ( v137 );
				}
				v138 = v2 - 800;
				if ( !v136 )
				{
					world_4B3269[0] -= 64;
					v139 = 16;
					do
					{
						if ( (unsigned int)v138 < screen_buf_end )
							break;
						v156 = v139;
						v140 = *(_DWORD *)world_4B3269[0];
						v141 = 32;
						do
						{
							v16 = __CFSHL__(v140, 1);
							v140 *= 2;
							if ( v16 )
								*v138 = 0;
							++v138;
							--v141;
						}
						while ( v141 );
						v138 -= 800;
						world_4B3269[0] -= 4;
						v139 = v156 - 1;
					}
					while ( v156 != 1 );
					return;
				}
				v2 = &v138[v136];
				v136 -= 2;
			}
			break;
	}
}
// 642A14: using guessed type char lightmax;
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF14: using guessed type int level_cel_block;

//----- (004652C5) --------------------------------------------------------
void __fastcall drawUpperScreen(void *a1)
{
	int v1; // edx
	char v2; // al
	char v3; // al
	_BYTE *v4; // edi
	_BYTE *v5; // esi
	int v6; // ebx
	short v7; // ax
	char *v8; // esi
	short v9; // ax
	unsigned int v10; // eax
	unsigned char *v11; // esi
	unsigned int v12; // eax
	int v13; // edx
	char v14; // cl
	int v15; // eax
	char v16; // ch
	char v17; // ch
	char v18; // ch
	signed int v19; // ebp
	signed int v20; // edx
	int v21; // eax
	int v22; // edx
	char v23; // cl
	int v24; // eax
	char v25; // ch
	char v26; // ch
	char v27; // ch
	signed int v28; // ebp
	_BYTE *v29; // edi
	char v30; // cl
	int v31; // edx
	int v32; // eax
	char v33; // ch
	char v34; // ch
	char v35; // ch
	unsigned char v36; // of
	signed int v37; // ebp
	_BYTE *v38; // edi
	char v39; // cl
	int v40; // edx
	int v41; // eax
	char v42; // ch
	char v43; // ch
	char v44; // ch
	signed int v45; // ebp
	char m; // cl
	int v47; // eax
	char v48; // ch
	char v49; // ch
	char v50; // ch
	signed int v51; // ebp
	char n; // cl
	int v53; // eax
	char v54; // ch
	char v55; // ch
	char v56; // ch
	signed int v57; // ebp
	_BYTE *v58; // edi
	char v59; // cl
	int v60; // edx
	int v61; // eax
	char v62; // ch
	char v63; // ch
	char v64; // ch
	signed int v65; // ebp
	char v66; // cl
	int v67; // eax
	char v68; // ch
	char v69; // ch
	char v70; // ch
	signed int v71; // ebp
	char ii; // cl
	int v73; // eax
	char v74; // ch
	char v75; // ch
	char v76; // ch
	signed int v77; // ebp
	char v78; // cl
	int v79; // eax
	char v80; // ch
	char v81; // ch
	char v82; // ch
	signed int v83; // edx
	signed int v84; // ecx
	int v85; // eax
	signed int v86; // ebp
	signed int v87; // edx
	unsigned int v88; // eax
	unsigned int v89; // ecx
	char v90; // al
	char v91; // cf
	unsigned int v92; // ecx
	short v93; // ax
	int v94; // eax
	signed int v95; // edx
	_DWORD *v96; // edi
	unsigned int v97; // ecx
	short v98; // ax
	int v99; // eax
	signed int v100; // edx
	_WORD *v101; // edi
	unsigned int v102; // ecx
	short v103; // ax
	int v104; // eax
	signed int v105; // edx
	unsigned int i; // ecx
	int v107; // eax
	short v108; // ax
	signed int v109; // edx
	unsigned int j; // ecx
	int v111; // eax
	short v112; // ax
	signed int v113; // edx
	_DWORD *v114; // edi
	unsigned int v115; // ecx
	short v116; // ax
	int v117; // eax
	signed int v118; // edx
	signed int v119; // ecx
	int v120; // eax
	signed int v121; // edx
	unsigned int k; // ecx
	int v123; // eax
	short v124; // ax
	signed int v125; // edx
	signed int v126; // ecx
	int v127; // eax
	signed int v128; // edx
	signed int v129; // ecx
	signed int v130; // ebp
	signed int v131; // edx
	unsigned int v132; // eax
	unsigned int v133; // ecx
	unsigned int v134; // ecx
	signed int v135; // edx
	_DWORD *v136; // edi
	unsigned int v137; // ecx
	signed int v138; // edx
	_WORD *v139; // edi
	unsigned int v140; // ecx
	signed int v141; // edx
	unsigned int v142; // ecx
	_WORD *v143; // edi
	signed int v144; // edx
	unsigned int v145; // ecx
	signed int v146; // edx
	_DWORD *v147; // edi
	unsigned int v148; // ecx
	signed int v149; // edx
	signed int v150; // ecx
	signed int v151; // edx
	unsigned int v152; // ecx
	_DWORD *v153; // edi
	signed int v154; // edx
	signed int v155; // ecx
	int l; // [esp-14h] [ebp-18h]
	int v157; // [esp-10h] [ebp-14h]

	v1 = cel_transparency_active;
	if ( cel_transparency_active )
	{
		if ( !arch_draw_type )
		{
			drawTopArchesUpperScreen(a1);
			return;
		}
		if ( arch_draw_type == 1 )
		{
			v2 = block_lvid[level_piece_id];
			if ( v2 == 1 || v2 == 3 )
			{
				drawBottomArchesUpperScreen(a1, (int)&tile_draw_masks[63]);
				return;
			}
		}
		if ( arch_draw_type == 2 )
		{
			v3 = block_lvid[level_piece_id];
			if ( v3 == 2 || v3 == 3 )
			{
				drawBottomArchesUpperScreen(a1, (int)&tile_draw_masks[31]);
				return;
			}
		}
	}
	world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num;
	v4 = (unsigned char *)a1;
	if ( !(_BYTE)light_table_index )
	{
		if ( level_cel_block & 0x8000 )
			level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
							+ (unsigned short)(level_cel_block & 0xF000);
		v8 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v10 = level_cel_block;
		_LOBYTE(v10) = BYTE1(v10);
		v9 = ((v10 >> 4) & 7) + 8;
LABEL_22:
		switch ( v9 )
		{
			case 8:
				v83 = 32;
				do
				{
					if ( (unsigned int)v4 < screen_buf_end )
						break;
					v84 = 8;
					do
					{
						v85 = *(_DWORD *)v8;
						v8 += 4;
						*(_DWORD *)v4 = v85;
						v4 += 4;
						--v84;
					}
					while ( v84 );
					v4 -= 800;
					--v83;
				}
				while ( v83 );
				break;
			case 9:
				v86 = 32;
				do
				{
					v87 = 32;
					do
					{
						while ( 1 )
						{
							v88 = (unsigned char)*v8++;
							if ( (v88 & 0x80u) == 0 )
								break;
							_LOBYTE(v88) = -(char)v88;
							v4 += v88;
							v87 -= v88;
							if ( !v87 )
								goto LABEL_133;
						}
						v87 -= v88;
						if ( (unsigned int)v4 < screen_buf_end )
							return;
						v89 = v88 >> 1;
						if ( v88 & 1 )
						{
							v90 = *v8++;
							*v4++ = v90;
							if ( !v89 )
								continue;
						}
						v91 = v89 & 1;
						v92 = v89 >> 1;
						if ( v91 )
						{
							v93 = *(_WORD *)v8;
							v8 += 2;
							*(_WORD *)v4 = v93;
							v4 += 2;
							if ( !v92 )
								continue;
						}
						do
						{
							v94 = *(_DWORD *)v8;
							v8 += 4;
							*(_DWORD *)v4 = v94;
							v4 += 4;
							--v92;
						}
						while ( v92 );
					}
					while ( v87 );
LABEL_133:
					v4 -= 800;
					--v86;
				}
				while ( v86 );
				break;
			case 10:
				v95 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					v96 = (unsigned int *)&v4[v95];
					v97 = (unsigned int)(32 - v95) >> 2;
					if ( !__CFSHR__(32 - v95, 2)
					  || (v98 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v96 = v98, v96 = (_DWORD *)((char *)v96 + 2), v97) )
					{
						do
						{
							v99 = *(_DWORD *)v8;
							v8 += 4;
							*v96 = v99;
							++v96;
							--v97;
						}
						while ( v97 );
					}
					v4 = (unsigned char *)v96 - 200;
					v36 = __OFSUB__(v95, 2);
					v95 -= 2;
					if ( (v95 < 0) ^ v36 )
					{
						v100 = 2;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
								break;
							v101 = (unsigned short *)&v4[v100];
							v102 = (unsigned int)(32 - v100) >> 2;
							if ( __CFSHR__(32 - v100, 2) )
							{
								v103 = *((_WORD *)v8 + 1);
								v8 += 4;
								*v101 = v103;
								++v101;
								if ( !v102 )
									continue;
							}
							do
							{
								v104 = *(_DWORD *)v8;
								v8 += 4;
								*(_DWORD *)v101 = v104;
								v101 += 2;
								--v102;
							}
							while ( v102 );
							v4 = (unsigned char *)v101 - 400;
							v100 += 2;
						}
						while ( v100 != 32 );
						return;
					}
				}
				break;
			case 11:
				v105 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					for ( i = (unsigned int)(32 - v105) >> 2; i; --i )
					{
						v107 = *(_DWORD *)v8;
						v8 += 4;
						*(_DWORD *)v4 = v107;
						v4 += 4;
					}
					if ( (32 - (_BYTE)v105) & 2 )
					{
						v108 = *(_WORD *)v8;
						v8 += 4;
						*(_WORD *)v4 = v108;
						v4 += 2;
					}
					v4 = &v4[v105 - 800];
					v36 = __OFSUB__(v105, 2);
					v105 -= 2;
					if ( (v105 < 0) ^ v36 )
					{
						v109 = 2;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
								break;
							for ( j = (unsigned int)(32 - v109) >> 2; j; --j )
							{
								v111 = *(_DWORD *)v8;
								v8 += 4;
								*(_DWORD *)v4 = v111;
								v4 += 4;
							}
							if ( (32 - (_BYTE)v109) & 2 )
							{
								v112 = *(_WORD *)v8;
								v8 += 4;
								*(_WORD *)v4 = v112;
								v4 += 2;
							}
							v4 = &v4[v109 - 800];
							v109 += 2;
						}
						while ( v109 != 32 );
						return;
					}
				}
				break;
			case 12:
				v113 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					v114 = (unsigned int *)&v4[v113];
					v115 = (unsigned int)(32 - v113) >> 2;
					if ( !__CFSHR__(32 - v113, 2)
					  || (v116 = *((_WORD *)v8 + 1),
						  v8 += 4,
						  *(_WORD *)v114 = v116,
						  v114 = (_DWORD *)((char *)v114 + 2),
						  v115) )
					{
						do
						{
							v117 = *(_DWORD *)v8;
							v8 += 4;
							*v114 = v117;
							++v114;
							--v115;
						}
						while ( v115 );
					}
					v4 = (unsigned char *)v114 - 200;
					v36 = __OFSUB__(v113, 2);
					v113 -= 2;
					if ( (v113 < 0) ^ v36 )
					{
						v118 = 16;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
								break;
							v119 = 8;
							do
							{
								v120 = *(_DWORD *)v8;
								v8 += 4;
								*(_DWORD *)v4 = v120;
								v4 += 4;
								--v119;
							}
							while ( v119 );
							v4 -= 800;
							--v118;
						}
						while ( v118 );
						return;
					}
				}
				break;
			default:
				v121 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					for ( k = (unsigned int)(32 - v121) >> 2; k; --k )
					{
						v123 = *(_DWORD *)v8;
						v8 += 4;
						*(_DWORD *)v4 = v123;
						v4 += 4;
					}
					if ( (32 - (_BYTE)v121) & 2 )
					{
						v124 = *(_WORD *)v8;
						v8 += 4;
						*(_WORD *)v4 = v124;
						v4 += 2;
					}
					v4 = &v4[v121 - 800];
					v36 = __OFSUB__(v121, 2);
					v121 -= 2;
					if ( (v121 < 0) ^ v36 )
					{
						v125 = 16;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
								break;
							v126 = 8;
							do
							{
								v127 = *(_DWORD *)v8;
								v8 += 4;
								*(_DWORD *)v4 = v127;
								v4 += 4;
								--v126;
							}
							while ( v126 );
							v4 -= 800;
							--v125;
						}
						while ( v125 );
						return;
					}
				}
				break;
		}
		return;
	}
	if ( (_BYTE)light_table_index != lightmax )
	{
		if ( !(level_cel_block & 0x8000) )
		{
			v5 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
			v6 = dword_646A20 + (light_table_index << 8);
			v7 = (unsigned short)level_cel_block >> 12;
			if ( (unsigned short)level_cel_block >> 12 )
			{
				switch ( v7 )
				{
					case 1:
						v19 = 32;
						do
						{
							v20 = 32;
							do
							{
								while ( 1 )
								{
									v21 = (unsigned char)*v5++;
									if ( (v21 & 0x80u) == 0 )
										break;
									_LOBYTE(v21) = -(char)v21;
									v4 += v21;
									v20 -= v21;
									if ( !v20 )
										goto LABEL_58;
								}
								v22 = v20 - v21;
								if ( (unsigned int)v4 < screen_buf_end )
									return;
								v23 = v21;
								for ( l = v22; v23 >= 4; v23 -= 4 )
								{
									v24 = *(_DWORD *)v5;
									v5 += 4;
									_LOBYTE(v22) = v24;
									v25 = *(_BYTE *)(v6 + v22);
									_LOBYTE(v22) = BYTE1(v24);
									v24 = __ROR4__(v24, 16);
									*v4 = v25;
									v26 = *(_BYTE *)(v6 + v22);
									_LOBYTE(v22) = v24;
									v4[1] = v26;
									v27 = *(_BYTE *)(v6 + v22);
									_LOBYTE(v22) = BYTE1(v24);
									v4[2] = v27;
									v4[3] = *(_BYTE *)(v6 + v22);
									v4 += 4;
								}
								if ( v23 >= 2 )
								{
									_LOBYTE(v22) = *v5;
									*v4 = *(_BYTE *)(v6 + v22);
									_LOBYTE(v22) = v5[1];
									v4[1] = *(_BYTE *)(v6 + v22);
									v5 += 2;
									v4 += 2;
								}
								if ( v23 & 1 )
								{
									_LOBYTE(v22) = *v5++;
									*v4++ = *(_BYTE *)(v6 + v22);
								}
								v20 = l;
							}
							while ( l );
LABEL_58:
							v4 -= 800;
							--v19;
						}
						while ( v19 );
						break;
					case 2:
						v28 = 30;
						while ( (unsigned int)v4 >= screen_buf_end )
						{
							v29 = &v4[v28];
							v30 = 32 - v28;
							v31 = (32 - (_BYTE)v28) & 2;
							v5 += v31;
							if ( (char)(32 - v28) >= 4 )
							{
								do
								{
									v32 = *(_DWORD *)v5;
									v5 += 4;
									_LOBYTE(v31) = v32;
									v33 = *(_BYTE *)(v6 + v31);
									_LOBYTE(v31) = BYTE1(v32);
									v32 = __ROR4__(v32, 16);
									*v29 = v33;
									v34 = *(_BYTE *)(v6 + v31);
									_LOBYTE(v31) = v32;
									v29[1] = v34;
									v35 = *(_BYTE *)(v6 + v31);
									_LOBYTE(v31) = BYTE1(v32);
									v29[2] = v35;
									v29[3] = *(_BYTE *)(v6 + v31);
									v29 += 4;
									v30 -= 4;
								}
								while ( v30 >= 4 );
							}
							if ( v30 >= 2 )
							{
								_LOBYTE(v31) = *v5;
								*v29 = *(_BYTE *)(v6 + v31);
								_LOBYTE(v31) = v5[1];
								v29[1] = *(_BYTE *)(v6 + v31);
								v5 += 2;
								v29 += 2;
							}
							v4 = v29 - 800;
							v36 = __OFSUB__(v28, 2);
							v28 -= 2;
							if ( (v28 < 0) ^ v36 )
							{
								v37 = 2;
								do
								{
									if ( (unsigned int)v4 < screen_buf_end )
										break;
									v38 = &v4[v37];
									v39 = 32 - v37;
									v40 = (32 - (_BYTE)v37) & 2;
									v5 += v40;
									if ( (char)(32 - v37) >= 4 )
									{
										do
										{
											v41 = *(_DWORD *)v5;
											v5 += 4;
											_LOBYTE(v40) = v41;
											v42 = *(_BYTE *)(v6 + v40);
											_LOBYTE(v40) = BYTE1(v41);
											v41 = __ROR4__(v41, 16);
											*v38 = v42;
											v43 = *(_BYTE *)(v6 + v40);
											_LOBYTE(v40) = v41;
											v38[1] = v43;
											v44 = *(_BYTE *)(v6 + v40);
											_LOBYTE(v40) = BYTE1(v41);
											v38[2] = v44;
											v38[3] = *(_BYTE *)(v6 + v40);
											v38 += 4;
											v39 -= 4;
										}
										while ( v39 >= 4 );
									}
									if ( v39 >= 2 )
									{
										_LOBYTE(v40) = *v5;
										*v38 = *(_BYTE *)(v6 + v40);
										_LOBYTE(v40) = v5[1];
										v38[1] = *(_BYTE *)(v6 + v40);
										v5 += 2;
										v38 += 2;
									}
									v4 = v38 - 800;
									v37 += 2;
								}
								while ( v37 != 32 );
								return;
							}
						}
						break;
					case 3:
						v45 = 30;
						while ( (unsigned int)v4 >= screen_buf_end )
						{
							for ( m = 32 - v45; m >= 4; m -= 4 )
							{
								v47 = *(_DWORD *)v5;
								v5 += 4;
								_LOBYTE(v1) = v47;
								v48 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v47);
								v47 = __ROR4__(v47, 16);
								*v4 = v48;
								v49 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = v47;
								v4[1] = v49;
								v50 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v47);
								v4[2] = v50;
								v4[3] = *(_BYTE *)(v6 + v1);
								v4 += 4;
							}
							if ( m >= 2 )
							{
								_LOBYTE(v1) = *v5;
								*v4 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = v5[1];
								v4[1] = *(_BYTE *)(v6 + v1);
								v5 += 2;
								v4 += 2;
							}
							v1 = (unsigned char)v5 & 2;
							v5 += v1;
							v4 = &v4[v45 - 800];
							v36 = __OFSUB__(v45, 2);
							v45 -= 2;
							if ( (v45 < 0) ^ v36 )
							{
								v51 = 2;
								do
								{
									if ( (unsigned int)v4 < screen_buf_end )
										break;
									for ( n = 32 - v51; n >= 4; n -= 4 )
									{
										v53 = *(_DWORD *)v5;
										v5 += 4;
										_LOBYTE(v1) = v53;
										v54 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = BYTE1(v53);
										v53 = __ROR4__(v53, 16);
										*v4 = v54;
										v55 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = v53;
										v4[1] = v55;
										v56 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = BYTE1(v53);
										v4[2] = v56;
										v4[3] = *(_BYTE *)(v6 + v1);
										v4 += 4;
									}
									if ( n >= 2 )
									{
										_LOBYTE(v1) = *v5;
										*v4 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = v5[1];
										v4[1] = *(_BYTE *)(v6 + v1);
										v5 += 2;
										v4 += 2;
									}
									v1 = (unsigned char)v5 & 2;
									v5 += v1;
									v4 = &v4[v51 - 800];
									v51 += 2;
								}
								while ( v51 != 32 );
								return;
							}
						}
						break;
					case 4:
						v57 = 30;
						while ( (unsigned int)v4 >= screen_buf_end )
						{
							v58 = &v4[v57];
							v59 = 32 - v57;
							v60 = (32 - (_BYTE)v57) & 2;
							v5 += v60;
							if ( (char)(32 - v57) >= 4 )
							{
								do
								{
									v61 = *(_DWORD *)v5;
									v5 += 4;
									_LOBYTE(v60) = v61;
									v62 = *(_BYTE *)(v6 + v60);
									_LOBYTE(v60) = BYTE1(v61);
									v61 = __ROR4__(v61, 16);
									*v58 = v62;
									v63 = *(_BYTE *)(v6 + v60);
									_LOBYTE(v60) = v61;
									v58[1] = v63;
									v64 = *(_BYTE *)(v6 + v60);
									_LOBYTE(v60) = BYTE1(v61);
									v58[2] = v64;
									v58[3] = *(_BYTE *)(v6 + v60);
									v58 += 4;
									v59 -= 4;
								}
								while ( v59 >= 4 );
							}
							if ( v59 >= 2 )
							{
								_LOBYTE(v60) = *v5;
								*v58 = *(_BYTE *)(v6 + v60);
								_LOBYTE(v60) = v5[1];
								v58[1] = *(_BYTE *)(v6 + v60);
								v5 += 2;
								v58 += 2;
							}
							v4 = v58 - 800;
							v36 = __OFSUB__(v57, 2);
							v57 -= 2;
							if ( (v57 < 0) ^ v36 )
							{
								v65 = 16;
								do
								{
									if ( (unsigned int)v4 < screen_buf_end )
										break;
									v66 = 32;
									do
									{
										v67 = *(_DWORD *)v5;
										v5 += 4;
										_LOBYTE(v60) = v67;
										v68 = *(_BYTE *)(v6 + v60);
										_LOBYTE(v60) = BYTE1(v67);
										v67 = __ROR4__(v67, 16);
										*v4 = v68;
										v69 = *(_BYTE *)(v6 + v60);
										_LOBYTE(v60) = v67;
										v4[1] = v69;
										v70 = *(_BYTE *)(v6 + v60);
										_LOBYTE(v60) = BYTE1(v67);
										v4[2] = v70;
										v4[3] = *(_BYTE *)(v6 + v60);
										v4 += 4;
										v66 -= 4;
									}
									while ( v66 >= 4 );
									v4 -= 800;
									--v65;
								}
								while ( v65 );
								return;
							}
						}
						break;
					default:
						v71 = 30;
						while ( (unsigned int)v4 >= screen_buf_end )
						{
							for ( ii = 32 - v71; ii >= 4; ii -= 4 )
							{
								v73 = *(_DWORD *)v5;
								v5 += 4;
								_LOBYTE(v1) = v73;
								v74 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v73);
								v73 = __ROR4__(v73, 16);
								*v4 = v74;
								v75 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = v73;
								v4[1] = v75;
								v76 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v73);
								v4[2] = v76;
								v4[3] = *(_BYTE *)(v6 + v1);
								v4 += 4;
							}
							if ( ii >= 2 )
							{
								_LOBYTE(v1) = *v5;
								*v4 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = v5[1];
								v4[1] = *(_BYTE *)(v6 + v1);
								v5 += 2;
								v4 += 2;
							}
							v1 = (unsigned char)v5 & 2;
							v5 += v1;
							v4 = &v4[v71 - 800];
							v36 = __OFSUB__(v71, 2);
							v71 -= 2;
							if ( (v71 < 0) ^ v36 )
							{
								v77 = 16;
								do
								{
									if ( (unsigned int)v4 < screen_buf_end )
										break;
									v78 = 32;
									do
									{
										v79 = *(_DWORD *)v5;
										v5 += 4;
										_LOBYTE(v1) = v79;
										v80 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = BYTE1(v79);
										v79 = __ROR4__(v79, 16);
										*v4 = v80;
										v81 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = v79;
										v4[1] = v81;
										v82 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = BYTE1(v79);
										v4[2] = v82;
										v4[3] = *(_BYTE *)(v6 + v1);
										v4 += 4;
										v78 -= 4;
									}
									while ( v78 >= 4 );
									v4 -= 800;
									--v77;
								}
								while ( v77 );
								return;
							}
						}
						break;
				}
			}
			else
			{
				v13 = 32;
				do
				{
					if ( (unsigned int)v4 < screen_buf_end )
						break;
					v14 = 32;
					v157 = v13;
					do
					{
						v15 = *(_DWORD *)v5;
						v5 += 4;
						_LOBYTE(v13) = v15;
						v16 = *(_BYTE *)(v6 + v13);
						_LOBYTE(v13) = BYTE1(v15);
						v15 = __ROR4__(v15, 16);
						*v4 = v16;
						v17 = *(_BYTE *)(v6 + v13);
						_LOBYTE(v13) = v15;
						v4[1] = v17;
						v18 = *(_BYTE *)(v6 + v13);
						_LOBYTE(v13) = BYTE1(v15);
						v4[2] = v18;
						v4[3] = *(_BYTE *)(v6 + v13);
						v4 += 4;
						v14 -= 4;
					}
					while ( v14 >= 4 );
					v4 -= 800;
					v13 = v157 - 1;
				}
				while ( v157 != 1 );
			}
			return;
		}
		v8 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265);
		v9 = (unsigned short)level_cel_block >> 12;
		goto LABEL_22;
	}
	if ( level_cel_block & 0x8000 )
		level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
						+ (unsigned short)(level_cel_block & 0xF000);
	v11 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
	v12 = ((unsigned int)level_cel_block >> 12) & 7;
	if ( v12 )
	{
		switch ( (_WORD)v12 )
		{
			case 1:
				v130 = 32;
				do
				{
					v131 = 32;
					do
					{
						while ( 1 )
						{
							v132 = *v11++;
							if ( (v132 & 0x80u) == 0 )
								break;
							_LOBYTE(v132) = -(char)v132;
							v4 += v132;
							v131 -= v132;
							if ( !v131 )
								goto LABEL_205;
						}
						v131 -= v132;
						if ( (unsigned int)v4 < screen_buf_end )
							return;
						v11 += v132;
						v133 = v132 >> 1;
						if ( v132 & 1 )
						{
							*v4++ = 0;
							if ( !v133 )
								continue;
						}
						v91 = v133 & 1;
						v134 = v132 >> 2;
						if ( v91 )
						{
							*(_WORD *)v4 = 0;
							v4 += 2;
							if ( !v134 )
								continue;
						}
						do
						{
							*(_DWORD *)v4 = 0;
							v4 += 4;
							--v134;
						}
						while ( v134 );
					}
					while ( v131 );
LABEL_205:
					v4 -= 800;
					--v130;
				}
				while ( v130 );
				break;
			case 2:
				v135 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					v136 = (unsigned int *)&v4[v135];
					v137 = (unsigned int)(32 - v135) >> 2;
					if ( !__CFSHR__(32 - v135, 2) || (*(_WORD *)v136 = 0, v136 = (_DWORD *)((char *)v136 + 2), v137) )
					{
						do
						{
							*v136 = 0;
							++v136;
							--v137;
						}
						while ( v137 );
					}
					v4 = (unsigned char *)v136 - 200;
					if ( !v135 )
					{
						v138 = 2;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
								break;
							v139 = (unsigned short *)&v4[v138];
							v140 = (unsigned int)(32 - v138) >> 2;
							if ( __CFSHR__(32 - v138, 2) )
							{
								*v139 = 0;
								++v139;
								if ( !v140 )
									continue;
							}
							do
							{
								*(_DWORD *)v139 = 0;
								v139 += 2;
								--v140;
							}
							while ( v140 );
							v4 = (unsigned char *)v139 - 400;
							v138 += 2;
						}
						while ( v138 != 32 );
						return;
					}
					v135 -= 2;
				}
				break;
			case 3:
				v141 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					v142 = (unsigned int)(32 - v141) >> 2;
					if ( !__CFSHR__(32 - v141, 2) || (*(_WORD *)v4 = 0, v4 += 2, v142) )
					{
						do
						{
							*(_DWORD *)v4 = 0;
							v4 += 4;
							--v142;
						}
						while ( v142 );
					}
					v143 = (unsigned short *)v4 - 800;
					if ( !v141 )
					{
						v144 = 1;
						do
						{
							if ( (unsigned int)v143 < screen_buf_end )
								break;
							v145 = (unsigned int)(32 - v144 * 2) >> 2;
							if ( __CFSHR__(32 - v144 * 2, 2) )
							{
								*v143 = 0;
								++v143;
								if ( !v145 )
									continue;
							}
							do
							{
								*(_DWORD *)v143 = 0;
								v143 += 2;
								--v145;
							}
							while ( v145 );
							v143 = &v143[v144 - 400];
							++v144;
						}
						while ( v144 != 16 );
						return;
					}
					v4 = (unsigned char *)&v143[v141 / 2u];
					v141 -= 2;
				}
				break;
			case 4:
				v146 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					v147 = (unsigned int *)&v4[v146];
					v148 = (unsigned int)(32 - v146) >> 2;
					if ( !__CFSHR__(32 - v146, 2) || (*(_WORD *)v147 = 0, v147 = (_DWORD *)((char *)v147 + 2), v148) )
					{
						do
						{
							*v147 = 0;
							++v147;
							--v148;
						}
						while ( v148 );
					}
					v4 = (unsigned char *)v147 - 200;
					if ( !v146 )
					{
						v149 = 16;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
								break;
							v150 = 8;
							do
							{
								*(_DWORD *)v4 = 0;
								v4 += 4;
								--v150;
							}
							while ( v150 );
							v4 -= 800;
							--v149;
						}
						while ( v149 );
						return;
					}
					v146 -= 2;
				}
				break;
			default:
				v151 = 30;
				while ( (unsigned int)v4 >= screen_buf_end )
				{
					v152 = (unsigned int)(32 - v151) >> 2;
					if ( !__CFSHR__(32 - v151, 2) || (*(_WORD *)v4 = 0, v4 += 2, v152) )
					{
						do
						{
							*(_DWORD *)v4 = 0;
							v4 += 4;
							--v152;
						}
						while ( v152 );
					}
					v153 = (unsigned int *)v4 - 800;
					if ( !v151 )
					{
						v154 = 16;
						do
						{
							if ( (unsigned int)v153 < screen_buf_end )
								break;
							v155 = 8;
							do
							{
								*v153 = 0;
								++v153;
								--v155;
							}
							while ( v155 );
							v153 -= 200;
							--v154;
						}
						while ( v154 );
						return;
					}
					v4 = (unsigned char *)v153 + v151;
					v151 -= 2;
				}
				break;
		}
	}
	else
	{
		v128 = 32;
		do
		{
			if ( (unsigned int)v4 < screen_buf_end )
				break;
			v129 = 8;
			do
			{
				*(_DWORD *)v4 = 0;
				v4 += 4;
				--v129;
			}
			while ( v129 );
			v4 -= 800;
			--v128;
		}
		while ( v128 );
	}
}
// 642A14: using guessed type char lightmax;
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF14: using guessed type int level_cel_block;
// 69CF20: using guessed type char arch_draw_type;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (00465F38) --------------------------------------------------------
void __fastcall drawTopArchesLowerScreen(void *a1)
{
	int v1; // edx
	unsigned int v2; // edi
	_BYTE *v3; // esi
	int v4; // ebx
	short v5; // ax
	char *v6; // esi
	short v7; // ax
	unsigned int v8; // eax
	char *v9; // esi
	unsigned int v10; // eax
	int v11; // eax
	signed int v12; // ebp
	signed int v13; // ecx
	unsigned int v14; // eax
	_BYTE *v15; // edi
	signed int v16; // ecx
	int v17; // eax
	int v18; // ecx
	signed int v19; // ebp
	unsigned int v20; // eax
	unsigned int v21; // ecx
	unsigned char v22; // cf
	unsigned int v23; // ecx
	unsigned int v24; // eax
	unsigned int v25; // ecx
	int v26; // eax
	unsigned int v27; // ecx
	unsigned int v28; // ecx
	int v29; // eax
	unsigned int v30; // ecx
	unsigned int v31; // eax
	int v32; // ebp
	signed int v33; // eax
	unsigned int v34; // ecx
	int v35; // eax
	_BYTE *v36; // edi
	unsigned int v37; // ecx
	int v38; // edx
	unsigned int v39; // ecx
	unsigned int v40; // ecx
	unsigned int v41; // eax
	unsigned int v42; // ecx
	int v43; // eax
	int v44; // edx
	unsigned int v45; // ecx
	unsigned int v46; // ecx
	int v47; // eax
	unsigned int v48; // ecx
	unsigned int v49; // eax
	unsigned char v50; // of
	int v51; // ebp
	signed int v52; // eax
	unsigned int v53; // ecx
	int v54; // eax
	_BYTE *v55; // edi
	unsigned int v56; // ecx
	int v57; // edx
	unsigned int v58; // ecx
	unsigned int v59; // ecx
	unsigned int v60; // eax
	unsigned int v61; // ecx
	int v62; // eax
	int v63; // edx
	unsigned int v64; // ecx
	unsigned int v65; // ecx
	int v66; // eax
	unsigned int v67; // ecx
	unsigned int v68; // eax
	int v69; // ebp
	signed int v70; // eax
	unsigned int v71; // ecx
	int v72; // eax
	unsigned int v73; // ecx
	unsigned int v74; // ecx
	unsigned int v75; // ecx
	unsigned int v76; // eax
	unsigned int v77; // ecx
	int v78; // eax
	unsigned int v79; // ecx
	unsigned int v80; // ecx
	int v81; // eax
	unsigned int v82; // ecx
	unsigned int v83; // eax
	int v84; // ebp
	signed int v85; // eax
	unsigned int v86; // ecx
	int v87; // eax
	unsigned int v88; // ecx
	unsigned int v89; // ecx
	unsigned int v90; // ecx
	unsigned int v91; // eax
	unsigned int v92; // ecx
	int v93; // eax
	unsigned int v94; // ecx
	unsigned int v95; // ecx
	int v96; // eax
	unsigned int v97; // ecx
	unsigned int v98; // eax
	int v99; // ebp
	signed int v100; // eax
	unsigned int v101; // ecx
	int v102; // eax
	_BYTE *v103; // edi
	unsigned int v104; // ecx
	unsigned int v105; // ecx
	unsigned int v106; // ecx
	unsigned int v107; // eax
	unsigned int v108; // ecx
	int v109; // eax
	unsigned int v110; // ecx
	unsigned int v111; // ecx
	int v112; // eax
	unsigned int v113; // ecx
	unsigned int v114; // eax
	signed int v115; // ebp
	signed int v116; // ecx
	unsigned int v117; // eax
	_BYTE *v118; // edi
	signed int v119; // ecx
	int v120; // eax
	int v121; // ebp
	signed int v122; // eax
	unsigned int v123; // ecx
	int v124; // eax
	unsigned int v125; // ecx
	unsigned int v126; // ecx
	unsigned int v127; // ecx
	unsigned int v128; // eax
	unsigned int v129; // ecx
	int v130; // eax
	unsigned int v131; // ecx
	unsigned int v132; // ecx
	int v133; // eax
	unsigned int v134; // ecx
	unsigned int v135; // eax
	signed int v136; // ebp
	signed int v137; // ecx
	unsigned int v138; // eax
	_BYTE *v139; // edi
	signed int v140; // ecx
	int v141; // eax
	signed int v142; // edx
	signed int v143; // ecx
	int v144; // eax
	_BYTE *v145; // edi
	_BYTE *v146; // edi
	signed int v147; // ecx
	int v148; // eax
	_BYTE *v149; // edi
	int v150; // ecx
	signed int v151; // edx
	unsigned int v152; // eax
	unsigned int v153; // ecx
	unsigned int v154; // ecx
	char *v155; // esi
	_BYTE *v156; // edi
	char v157; // al
	int v158; // eax
	_BYTE *v159; // edi
	char v160; // al
	unsigned int v161; // ecx
	char v162; // al
	int v163; // eax
	_BYTE *v164; // edi
	int v165; // edx
	signed int v166; // eax
	unsigned int v167; // ecx
	int v168; // eax
	_BYTE *v169; // edi
	unsigned int v170; // ecx
	int v171; // eax
	unsigned int v172; // ecx
	_BYTE *v173; // edi
	int v174; // eax
	_BYTE *v175; // edi
	unsigned int v176; // ecx
	short v177; // ax
	int v178; // eax
	_BYTE *v179; // edi
	int v180; // edx
	signed int v181; // eax
	unsigned int v182; // ecx
	int v183; // eax
	_BYTE *v184; // edi
	unsigned int v185; // ecx
	int v186; // eax
	unsigned int v187; // ecx
	_BYTE *v188; // edi
	int v189; // eax
	_BYTE *v190; // edi
	unsigned int v191; // ecx
	short v192; // ax
	int v193; // eax
	_BYTE *v194; // edi
	int v195; // edx
	signed int v196; // eax
	unsigned int v197; // ecx
	int v198; // eax
	unsigned int v199; // ecx
	int v200; // eax
	unsigned int ii; // ecx
	int v202; // eax
	_BYTE *v203; // edi
	_BYTE *v204; // edi
	unsigned int jj; // ecx
	int v206; // eax
	_BYTE *v207; // edi
	short v208; // ax
	int v209; // edx
	signed int v210; // eax
	unsigned int v211; // ecx
	int v212; // eax
	unsigned int v213; // ecx
	int v214; // eax
	unsigned int kk; // ecx
	int v216; // eax
	_BYTE *v217; // edi
	_BYTE *v218; // edi
	unsigned int ll; // ecx
	int v220; // eax
	_BYTE *v221; // edi
	short v222; // ax
	int v223; // edx
	signed int v224; // eax
	unsigned int v225; // ecx
	int v226; // eax
	_BYTE *v227; // edi
	unsigned int v228; // ecx
	int v229; // eax
	unsigned int v230; // ecx
	_BYTE *v231; // edi
	int v232; // eax
	_BYTE *v233; // edi
	unsigned int v234; // ecx
	short v235; // ax
	int v236; // eax
	_BYTE *v237; // edi
	signed int v238; // edx
	signed int v239; // ecx
	int v240; // eax
	_BYTE *v241; // edi
	_BYTE *v242; // edi
	signed int v243; // ecx
	int v244; // eax
	_BYTE *v245; // edi
	int v246; // edx
	signed int v247; // eax
	unsigned int v248; // ecx
	int v249; // eax
	unsigned int v250; // ecx
	int v251; // eax
	unsigned int m; // ecx
	int v253; // eax
	_BYTE *v254; // edi
	_BYTE *v255; // edi
	unsigned int n; // ecx
	int v257; // eax
	_BYTE *v258; // edi
	short v259; // ax
	signed int v260; // edx
	signed int v261; // ecx
	int v262; // eax
	_BYTE *v263; // edi
	_BYTE *v264; // edi
	signed int v265; // ecx
	int v266; // eax
	_BYTE *v267; // edi
	signed int v268; // edx
	signed int v269; // ecx
	_BYTE *v270; // edi
	signed int v271; // ecx
	int v272; // ecx
	signed int v273; // edx
	unsigned int v274; // eax
	unsigned int v275; // ecx
	unsigned int v276; // ecx
	_BYTE *v277; // edi
	unsigned int v278; // ecx
	signed int i; // edx
	_BYTE *v280; // edi
	unsigned int v281; // ecx
	unsigned int v282; // ecx
	_BYTE *v283; // edi
	unsigned int v284; // ecx
	signed int v285; // edx
	_BYTE *v286; // edi
	unsigned int v287; // ecx
	unsigned int v288; // ecx
	_BYTE *v289; // edi
	unsigned int v290; // ecx
	signed int j; // edx
	unsigned int v292; // ecx
	unsigned int v293; // ecx
	_BYTE *v294; // edi
	unsigned int v295; // ecx
	_BYTE *v296; // edi
	signed int v297; // edx
	unsigned int v298; // ecx
	unsigned int v299; // ecx
	_BYTE *v300; // edi
	unsigned int v301; // ecx
	signed int k; // edx
	_BYTE *v303; // edi
	unsigned int v304; // ecx
	unsigned int v305; // ecx
	_BYTE *v306; // edi
	unsigned int v307; // ecx
	signed int v308; // edx
	signed int v309; // ecx
	_BYTE *v310; // edi
	signed int v311; // ecx
	signed int l; // edx
	unsigned int v313; // ecx
	unsigned int v314; // ecx
	_BYTE *v315; // edi
	unsigned int v316; // ecx
	unsigned int v317; // edi
	signed int v318; // edx
	signed int v319; // ecx
	_BYTE *v320; // edi
	signed int v321; // ecx
	int v322; // [esp-14h] [ebp-18h]
	int v323; // [esp-10h] [ebp-14h]
	int v324; // [esp-10h] [ebp-14h]

	world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num;
	v2 = (unsigned int)a1;
	if ( !(_BYTE)light_table_index )
	{
		if ( level_cel_block & 0x8000 )
			level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
							+ (unsigned short)(level_cel_block & 0xF000);
		v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v8 = level_cel_block;
		_LOBYTE(v8) = BYTE1(v8);
		v7 = ((v8 >> 4) & 7) + 8;
		goto LABEL_11;
	}
	if ( (_BYTE)light_table_index == lightmax )
	{
		if ( level_cel_block & 0x8000 )
			level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
							+ (unsigned short)(level_cel_block & 0xF000);
		v9 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v10 = level_cel_block;
		_LOBYTE(v10) = BYTE1(v10);
		v11 = (v10 >> 4) & 7;
		if ( !v11 )
		{
			v268 = 16;
			do
			{
				if ( v2 < screen_buf_end )
				{
					v269 = 8;
					do
					{
						*(_BYTE *)(v2 + 1) = 0;
						*(_BYTE *)(v2 + 3) = 0;
						v2 += 4;
						--v269;
					}
					while ( v269 );
				}
				else
				{
					v9 += 32;
					v2 += 32;
				}
				v270 = (_BYTE *)(v2 - 800);
				if ( (unsigned int)v270 < screen_buf_end )
				{
					v271 = 8;
					do
					{
						*v270 = 0;
						v270[2] = 0;
						v270 += 4;
						--v271;
					}
					while ( v271 );
				}
				else
				{
					v9 += 32;
					v270 += 32;
				}
				v2 = (unsigned int)(v270 - 800);
				--v268;
			}
			while ( v268 );
			return;
		}
		if ( (_WORD)v11 != 1 )
		{
			switch ( (_WORD)v11 )
			{
				case 2:
					world_4B325C = 0;
					for ( i = 30; ; i -= 2 )
					{
						if ( v2 < screen_buf_end )
						{
							v280 = (_BYTE *)(i + v2);
							v281 = 32 - i;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v22 = __CFSHR__(v281, 2);
								v282 = v281 >> 2;
								if ( !v22 || (v283 = v280 + 1, *v283 = 0, v280 = v283 + 1, v282) )
								{
									do
									{
										v280[1] = 0;
										v280[3] = 0;
										v280 += 4;
										--v282;
									}
									while ( v282 );
								}
							}
							else
							{
								v22 = __CFSHR__(v281, 2);
								v284 = v281 >> 2;
								if ( !v22 || (*v280 = 0, v280 += 2, v284) )
								{
									do
									{
										*v280 = 0;
										v280[2] = 0;
										v280 += 4;
										--v284;
									}
									while ( v284 );
								}
							}
						}
						else
						{
							v9 = &v9[-i + 32];
							v280 = (_BYTE *)(v2 + 32);
						}
						v2 = (unsigned int)(v280 - 800);
						if ( !i )
							break;
					}
					v285 = 2;
					do
					{
						if ( v2 < screen_buf_end )
						{
							v286 = (_BYTE *)(v285 + v2);
							v287 = 32 - v285;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v22 = __CFSHR__(v287, 2);
								v288 = v287 >> 2;
								if ( !v22 || (v289 = v286 + 1, *v289 = 0, v286 = v289 + 1, v288) )
								{
									do
									{
										v286[1] = 0;
										v286[3] = 0;
										v286 += 4;
										--v288;
									}
									while ( v288 );
								}
							}
							else
							{
								v22 = __CFSHR__(v287, 2);
								v290 = v287 >> 2;
								if ( !v22 || (*v286 = 0, v286 += 2, v290) )
								{
									do
									{
										*v286 = 0;
										v286[2] = 0;
										v286 += 4;
										--v290;
									}
									while ( v290 );
								}
							}
						}
						else
						{
							v9 = &v9[-v285 + 32];
							v286 = (_BYTE *)(v2 + 32);
						}
						v2 = (unsigned int)(v286 - 800);
						v285 += 2;
					}
					while ( v285 != 32 );
					break;
				case 3:
					world_4B325C = 0;
					for ( j = 30; ; j -= 2 )
					{
						if ( v2 < screen_buf_end )
						{
							v292 = 32 - j;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v22 = __CFSHR__(v292, 2);
								v293 = v292 >> 2;
								if ( !v22 || (v294 = (_BYTE *)(v2 + 1), *v294 = 0, v2 = (unsigned int)(v294 + 1), v293) )
								{
									do
									{
										*(_BYTE *)(v2 + 1) = 0;
										*(_BYTE *)(v2 + 3) = 0;
										v2 += 4;
										--v293;
									}
									while ( v293 );
								}
							}
							else
							{
								v22 = __CFSHR__(v292, 2);
								v295 = v292 >> 2;
								if ( !v22 || (*(_BYTE *)v2 = 0, v2 += 2, v295) )
								{
									do
									{
										*(_BYTE *)v2 = 0;
										*(_BYTE *)(v2 + 2) = 0;
										v2 += 4;
										--v295;
									}
									while ( v295 );
								}
							}
						}
						else
						{
							v9 = &v9[-j + 32];
							v2 = v2 + 32 - j;
						}
						v296 = (_BYTE *)(v2 - 800);
						if ( !j )
							break;
						v2 = (unsigned int)&v296[j];
					}
					v297 = 2;
					do
					{
						if ( (unsigned int)v296 < screen_buf_end )
						{
							v298 = 32 - v297;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v22 = __CFSHR__(v298, 2);
								v299 = v298 >> 2;
								if ( !v22 || (v300 = v296 + 1, *v300 = 0, v296 = v300 + 1, v299) )
								{
									do
									{
										v296[1] = 0;
										v296[3] = 0;
										v296 += 4;
										--v299;
									}
									while ( v299 );
								}
							}
							else
							{
								v22 = __CFSHR__(v298, 2);
								v301 = v298 >> 2;
								if ( !v22 || (*v296 = 0, v296 += 2, v301) )
								{
									do
									{
										*v296 = 0;
										v296[2] = 0;
										v296 += 4;
										--v301;
									}
									while ( v301 );
								}
							}
						}
						else
						{
							v9 = &v9[-v297 + 32];
							v296 = &v296[-v297 + 32];
						}
						v296 = &v296[v297 - 800];
						v297 += 2;
					}
					while ( v297 != 32 );
					break;
				case 4:
					world_4B325C = 0;
					for ( k = 30; ; k -= 2 )
					{
						if ( v2 < screen_buf_end )
						{
							v303 = (_BYTE *)(k + v2);
							v304 = 32 - k;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v22 = __CFSHR__(v304, 2);
								v305 = v304 >> 2;
								if ( !v22 || (v306 = v303 + 1, *v306 = 0, v303 = v306 + 1, v305) )
								{
									do
									{
										v303[1] = 0;
										v303[3] = 0;
										v303 += 4;
										--v305;
									}
									while ( v305 );
								}
							}
							else
							{
								v22 = __CFSHR__(v304, 2);
								v307 = v304 >> 2;
								if ( !v22 || (*v303 = 0, v303 += 2, v307) )
								{
									do
									{
										*v303 = 0;
										v303[2] = 0;
										v303 += 4;
										--v307;
									}
									while ( v307 );
								}
							}
						}
						else
						{
							v9 = &v9[-k + 32];
							v303 = (_BYTE *)(v2 + 32);
						}
						v2 = (unsigned int)(v303 - 800);
						if ( !k )
							break;
					}
					v308 = 8;
					do
					{
						if ( v2 < screen_buf_end )
						{
							v309 = 8;
							do
							{
								*(_BYTE *)(v2 + 1) = 0;
								*(_BYTE *)(v2 + 3) = 0;
								v2 += 4;
								--v309;
							}
							while ( v309 );
						}
						else
						{
							v9 += 32;
							v2 += 32;
						}
						v310 = (_BYTE *)(v2 - 800);
						if ( (unsigned int)v310 < screen_buf_end )
						{
							v311 = 8;
							do
							{
								*v310 = 0;
								v310[2] = 0;
								v310 += 4;
								--v311;
							}
							while ( v311 );
						}
						else
						{
							v9 += 32;
							v310 += 32;
						}
						v2 = (unsigned int)(v310 - 800);
						--v308;
					}
					while ( v308 );
					break;
				default:
					world_4B325C = 0;
					for ( l = 30; ; l -= 2 )
					{
						if ( v2 < screen_buf_end )
						{
							v313 = 32 - l;
							world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
							if ( world_4B325C )
							{
								v22 = __CFSHR__(v313, 2);
								v314 = v313 >> 2;
								if ( !v22 || (v315 = (_BYTE *)(v2 + 1), *v315 = 0, v2 = (unsigned int)(v315 + 1), v314) )
								{
									do
									{
										*(_BYTE *)(v2 + 1) = 0;
										*(_BYTE *)(v2 + 3) = 0;
										v2 += 4;
										--v314;
									}
									while ( v314 );
								}
							}
							else
							{
								v22 = __CFSHR__(v313, 2);
								v316 = v313 >> 2;
								if ( !v22 || (*(_BYTE *)v2 = 0, v2 += 2, v316) )
								{
									do
									{
										*(_BYTE *)v2 = 0;
										*(_BYTE *)(v2 + 2) = 0;
										v2 += 4;
										--v316;
									}
									while ( v316 );
								}
							}
						}
						else
						{
							v9 = &v9[-l + 32];
							v2 = v2 + 32 - l;
						}
						v317 = v2 - 800;
						if ( !l )
							break;
						v2 = l + v317;
					}
					v318 = 8;
					do
					{
						if ( v317 < screen_buf_end )
						{
							v319 = 8;
							do
							{
								*(_BYTE *)(v317 + 1) = 0;
								*(_BYTE *)(v317 + 3) = 0;
								v317 += 4;
								--v319;
							}
							while ( v319 );
						}
						else
						{
							v9 += 32;
							v317 += 32;
						}
						v320 = (_BYTE *)(v317 - 800);
						if ( (unsigned int)v320 < screen_buf_end )
						{
							v321 = 8;
							do
							{
								*v320 = 0;
								v320[2] = 0;
								v320 += 4;
								--v321;
							}
							while ( v321 );
						}
						else
						{
							v9 += 32;
							v320 += 32;
						}
						v317 = (unsigned int)(v320 - 800);
						--v318;
					}
					while ( v318 );
					break;
			}
			return;
		}
		world_4B325C = (unsigned char)a1 & 1;
		v272 = 32;
LABEL_412:
		v324 = v272;
		v273 = 32;
		while ( 1 )
		{
			while ( 1 )
			{
				v274 = (unsigned char)*v9++;
				if ( (v274 & 0x80u) == 0 )
					break;
				_LOBYTE(v274) = -(char)v274;
				v2 += v274;
				v273 -= v274;
				if ( !v273 )
				{
LABEL_433:
					world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
					v2 -= 800;
					v272 = v324 - 1;
					if ( v324 == 1 )
						return;
					goto LABEL_412;
				}
			}
			v273 -= v274;
			if ( v2 < screen_buf_end )
			{
				v9 += v274;
				if ( (v2 & 1) == world_4B325C )
				{
					v275 = v274 >> 1;
					if ( !(v274 & 1) )
						goto LABEL_420;
					++v2;
					if ( v275 )
					{
LABEL_427:
						v22 = v275 & 1;
						v278 = v275 >> 1;
						if ( !v22 || (*(_BYTE *)v2 = 0, v2 += 2, v278) )
						{
							do
							{
								*(_BYTE *)v2 = 0;
								*(_BYTE *)(v2 + 2) = 0;
								v2 += 4;
								--v278;
							}
							while ( v278 );
						}
						goto LABEL_430;
					}
				}
				else
				{
					v275 = v274 >> 1;
					if ( !(v274 & 1) )
						goto LABEL_427;
					*(_BYTE *)v2++ = 0;
					if ( v275 )
					{
LABEL_420:
						v22 = v275 & 1;
						v276 = v275 >> 1;
						if ( !v22 || (v277 = (_BYTE *)(v2 + 1), *v277 = 0, v2 = (unsigned int)(v277 + 1), v276) )
						{
							do
							{
								*(_BYTE *)(v2 + 1) = 0;
								*(_BYTE *)(v2 + 3) = 0;
								v2 += 4;
								--v276;
							}
							while ( v276 );
						}
						goto LABEL_430;
					}
				}
			}
			else
			{
				v9 += v274;
				v2 += v274;
			}
LABEL_430:
			if ( !v273 )
				goto LABEL_433;
		}
	}
	if ( !(level_cel_block & 0x8000) )
	{
		v3 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v4 = dword_646A20 + (light_table_index << 8);
		v5 = (unsigned char)(BYTE1(level_cel_block) >> 4);
		if ( !(BYTE1(level_cel_block) >> 4) )
		{
			v12 = 16;
			do
			{
				if ( v2 < screen_buf_end )
				{
					v13 = 8;
					do
					{
						v14 = *(_DWORD *)v3;
						v3 += 4;
						_LOBYTE(v1) = BYTE1(v14);
						v14 >>= 16;
						*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
						_LOBYTE(v1) = BYTE1(v14);
						v2 += 4;
						--v13;
						*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
					}
					while ( v13 );
				}
				else
				{
					v3 += 32;
					v2 += 32;
				}
				v15 = (_BYTE *)(v2 - 800);
				if ( (unsigned int)v15 < screen_buf_end )
				{
					v16 = 8;
					do
					{
						v17 = *(_DWORD *)v3;
						v3 += 4;
						_LOBYTE(v1) = v17;
						*v15 = *(_BYTE *)(v4 + v1);
						_LOBYTE(v1) = BYTE2(v17);
						v15 += 4;
						--v16;
						*(v15 - 2) = *(_BYTE *)(v4 + v1);
					}
					while ( v16 );
				}
				else
				{
					v3 += 32;
					v15 += 32;
				}
				v2 = (unsigned int)(v15 - 800);
				--v12;
			}
			while ( v12 );
			return;
		}
		if ( v5 == 1 )
		{
			world_4B325C = (unsigned char)a1 & 1;
			v18 = 32;
			do
			{
				v322 = v18;
				v19 = 32;
				do
				{
					while ( 1 )
					{
						v20 = (unsigned char)*v3++;
						if ( (v20 & 0x80u) == 0 )
							break;
						_LOBYTE(v20) = -(char)v20;
						v2 += v20;
						v19 -= v20;
						if ( !v19 )
							goto LABEL_69;
					}
					v19 -= v20;
					if ( v2 < screen_buf_end )
					{
						if ( (v2 & 1) == world_4B325C )
						{
							v21 = v20 >> 1;
							if ( v20 & 1 )
							{
								++v3;
								++v2;
								v22 = v21 & 1;
								v25 = v20 >> 2;
								if ( v22 )
								{
									_LOBYTE(v1) = *v3;
									v3 += 2;
									*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v25 )
								{
									do
									{
										v26 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v26;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v26);
										v2 += 4;
										--v25;
										*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v25 );
								}
							}
							else
							{
								v22 = v21 & 1;
								v23 = v20 >> 2;
								if ( v22 )
								{
									_LOBYTE(v1) = v3[1];
									v3 += 2;
									*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v23 )
								{
									do
									{
										v24 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v24);
										v24 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v24);
										v2 += 4;
										--v23;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v23 );
								}
							}
						}
						else
						{
							v27 = v20 >> 1;
							if ( v20 & 1 )
							{
								_LOBYTE(v1) = *v3++;
								*(_BYTE *)v2++ = *(_BYTE *)(v4 + v1);
								v22 = v27 & 1;
								v30 = v20 >> 2;
								if ( v22 )
								{
									_LOBYTE(v1) = v3[1];
									v3 += 2;
									*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v30 )
								{
									do
									{
										v31 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v31);
										v31 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v31);
										v2 += 4;
										--v30;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v30 );
								}
							}
							else
							{
								v22 = v27 & 1;
								v28 = v20 >> 2;
								if ( v22 )
								{
									_LOBYTE(v1) = *v3;
									v3 += 2;
									*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v28 )
								{
									do
									{
										v29 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v29;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v29);
										v2 += 4;
										--v28;
										*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v28 );
								}
							}
						}
					}
					else
					{
						v3 += v20;
						v2 += v20;
					}
				}
				while ( v19 );
LABEL_69:
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				v2 -= 800;
				v18 = v322 - 1;
			}
			while ( v322 != 1 );
			return;
		}
		if ( v5 != 2 )
		{
			if ( v5 != 3 )
			{
				if ( v5 != 4 )
				{
					world_4B325C = 0;
					v121 = 30;
					if ( (unsigned int)a1 >= screen_buf_end )
					{
						v122 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
						if ( v122 > 45 )
						{
							v2 = (unsigned int)a1 - 12288;
							v3 += 288;
LABEL_249:
							v136 = 8;
							do
							{
								if ( v2 < screen_buf_end )
								{
									v137 = 8;
									do
									{
										v138 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v138);
										v138 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v138);
										v2 += 4;
										--v137;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v137 );
								}
								else
								{
									v3 += 32;
									v2 += 32;
								}
								v139 = (_BYTE *)(v2 - 800);
								if ( (unsigned int)v139 < screen_buf_end )
								{
									v140 = 8;
									do
									{
										v141 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v141;
										*v139 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v141);
										v139 += 4;
										--v140;
										*(v139 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v140 );
								}
								else
								{
									v3 += 32;
									v139 += 32;
								}
								v2 = (unsigned int)(v139 - 800);
								--v136;
							}
							while ( v136 );
							return;
						}
						v123 = world_4B33FD[v122];
						v3 += *(int *)((char *)world_4B34BD + v123);
						v124 = 192 * v123;
						v123 >>= 1;
						v2 -= v124;
						v121 = 30 - v123;
						world_4B325C += v123 >> 1;
					}
					do
					{
						v125 = 32 - v121;
						world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
						if ( world_4B325C )
						{
							v22 = v125 & 1;
							v126 = v125 >> 1;
							if ( v22 )
							{
								++v3;
								++v2;
								v22 = v126 & 1;
								v129 = v126 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = *v3;
									v3 += 2;
									*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v129 )
								{
									do
									{
										v130 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v130;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v130);
										v2 += 4;
										--v129;
										*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v129 );
								}
							}
							else
							{
								v22 = v126 & 1;
								v127 = v126 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = v3[1];
									v3 += 2;
									*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v127 )
								{
									do
									{
										v128 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v128);
										v128 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v128);
										v2 += 4;
										--v127;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v127 );
								}
							}
							v1 = (unsigned char)v3 & 2;
							v3 += v1;
						}
						else
						{
							v22 = v125 & 1;
							v131 = v125 >> 1;
							if ( v22 )
							{
								_LOBYTE(v1) = *v3++;
								*(_BYTE *)v2++ = *(_BYTE *)(v4 + v1);
								v22 = v131 & 1;
								v134 = v131 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = v3[1];
									v3 += 2;
									*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v134 )
								{
									do
									{
										v135 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v135);
										v135 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v135);
										v2 += 4;
										--v134;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v134 );
								}
							}
							else
							{
								v22 = v131 & 1;
								v132 = v131 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = *v3;
									v3 += 2;
									*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v132 )
								{
									do
									{
										v133 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v133;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v133);
										v2 += 4;
										--v132;
										*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v132 );
								}
							}
							v1 = (unsigned char)v3 & 2;
							v3 += v1;
						}
						v2 = v121 + v2 - 800;
						v50 = __OFSUB__(v121, 2);
						v121 -= 2;
					}
					while ( !((v121 < 0) ^ v50) );
					goto LABEL_249;
				}
				world_4B325C = 0;
				v99 = 30;
				if ( (unsigned int)a1 >= screen_buf_end )
				{
					v100 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
					if ( v100 > 45 )
					{
						v2 = (unsigned int)a1 - 12288;
						v3 += 288;
LABEL_210:
						v115 = 8;
						do
						{
							if ( v2 < screen_buf_end )
							{
								v116 = 8;
								do
								{
									v117 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v1) = BYTE1(v117);
									v117 >>= 16;
									*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
									_LOBYTE(v1) = BYTE1(v117);
									v2 += 4;
									--v116;
									*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
								}
								while ( v116 );
							}
							else
							{
								v3 += 32;
								v2 += 32;
							}
							v118 = (_BYTE *)(v2 - 800);
							if ( (unsigned int)v118 < screen_buf_end )
							{
								v119 = 8;
								do
								{
									v120 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v1) = v120;
									*v118 = *(_BYTE *)(v4 + v1);
									_LOBYTE(v1) = BYTE2(v120);
									v118 += 4;
									--v119;
									*(v118 - 2) = *(_BYTE *)(v4 + v1);
								}
								while ( v119 );
							}
							else
							{
								v3 += 32;
								v118 += 32;
							}
							v2 = (unsigned int)(v118 - 800);
							--v115;
						}
						while ( v115 );
						return;
					}
					v101 = world_4B33FD[v100];
					v3 += *(int *)((char *)world_4B34BD + v101);
					v102 = 192 * v101;
					v101 >>= 1;
					v2 -= v102;
					v99 = 30 - v101;
					world_4B325C += v101 >> 1;
				}
				do
				{
					v103 = (_BYTE *)(v99 + v2);
					v104 = 32 - v99;
					world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
					if ( world_4B325C )
					{
						v1 = v104 & 2;
						v3 += v1;
						v22 = v104 & 1;
						v105 = v104 >> 1;
						if ( v22 )
						{
							++v3;
							++v103;
							v22 = v105 & 1;
							v108 = v105 >> 1;
							if ( v22 )
							{
								_LOBYTE(v1) = *v3;
								v3 += 2;
								*v103 = *(_BYTE *)(v4 + v1);
								v103 += 2;
							}
							if ( (_BYTE)v108 )
							{
								do
								{
									v109 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v1) = v109;
									*v103 = *(_BYTE *)(v4 + v1);
									_LOBYTE(v1) = BYTE2(v109);
									v103 += 4;
									--v108;
									*(v103 - 2) = *(_BYTE *)(v4 + v1);
								}
								while ( v108 );
							}
						}
						else
						{
							v22 = v105 & 1;
							v106 = v105 >> 1;
							if ( v22 )
							{
								_LOBYTE(v1) = v3[1];
								v3 += 2;
								v103[1] = *(_BYTE *)(v4 + v1);
								v103 += 2;
							}
							if ( (_BYTE)v106 )
							{
								do
								{
									v107 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v1) = BYTE1(v107);
									v107 >>= 16;
									v103[1] = *(_BYTE *)(v4 + v1);
									_LOBYTE(v1) = BYTE1(v107);
									v103 += 4;
									--v106;
									*(v103 - 1) = *(_BYTE *)(v4 + v1);
								}
								while ( v106 );
							}
						}
					}
					else
					{
						v1 = v104 & 2;
						v3 += v1;
						v22 = v104 & 1;
						v110 = v104 >> 1;
						if ( v22 )
						{
							_LOBYTE(v1) = *v3++;
							*v103++ = *(_BYTE *)(v4 + v1);
							v22 = v110 & 1;
							v113 = v110 >> 1;
							if ( v22 )
							{
								_LOBYTE(v1) = v3[1];
								v3 += 2;
								v103[1] = *(_BYTE *)(v4 + v1);
								v103 += 2;
							}
							if ( (_BYTE)v113 )
							{
								do
								{
									v114 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v1) = BYTE1(v114);
									v114 >>= 16;
									v103[1] = *(_BYTE *)(v4 + v1);
									_LOBYTE(v1) = BYTE1(v114);
									v103 += 4;
									--v113;
									*(v103 - 1) = *(_BYTE *)(v4 + v1);
								}
								while ( v113 );
							}
						}
						else
						{
							v22 = v110 & 1;
							v111 = v110 >> 1;
							if ( v22 )
							{
								_LOBYTE(v1) = *v3;
								v3 += 2;
								*v103 = *(_BYTE *)(v4 + v1);
								v103 += 2;
							}
							if ( (_BYTE)v111 )
							{
								do
								{
									v112 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v1) = v112;
									*v103 = *(_BYTE *)(v4 + v1);
									_LOBYTE(v1) = BYTE2(v112);
									v103 += 4;
									--v111;
									*(v103 - 2) = *(_BYTE *)(v4 + v1);
								}
								while ( v111 );
							}
						}
					}
					v2 = (unsigned int)(v103 - 800);
					v50 = __OFSUB__(v99, 2);
					v99 -= 2;
				}
				while ( !((v99 < 0) ^ v50) );
				goto LABEL_210;
			}
			world_4B325C = 0;
			v69 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v70 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v70 > 45 )
				{
					v2 = (unsigned int)a1 - 12288;
					v3 += 288;
LABEL_154:
					v84 = 2;
					if ( v2 >= screen_buf_end )
					{
						v85 = (v2 - screen_buf_end + 1023) >> 8;
						if ( v85 > 42 )
							return;
						v86 = world_4B33FD[v85];
						v3 += *(int *)((char *)world_4B3501 + v86);
						v87 = 192 * v86;
						v86 >>= 1;
						v2 -= v87;
						v84 = v86 + 2;
						world_4B325C += v86 >> 1;
					}
					do
					{
						v88 = 32 - v84;
						world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
						if ( world_4B325C )
						{
							v22 = v88 & 1;
							v89 = v88 >> 1;
							if ( v22 )
							{
								++v3;
								++v2;
								v22 = v89 & 1;
								v92 = v89 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = *v3;
									v3 += 2;
									*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v92 )
								{
									do
									{
										v93 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v93;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v93);
										v2 += 4;
										--v92;
										*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v92 );
								}
							}
							else
							{
								v22 = v89 & 1;
								v90 = v89 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = v3[1];
									v3 += 2;
									*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v90 )
								{
									do
									{
										v91 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v91);
										v91 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v91);
										v2 += 4;
										--v90;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v90 );
								}
							}
							v1 = (unsigned char)v3 & 2;
							v3 += v1;
						}
						else
						{
							v22 = v88 & 1;
							v94 = v88 >> 1;
							if ( v22 )
							{
								_LOBYTE(v1) = *v3++;
								*(_BYTE *)v2++ = *(_BYTE *)(v4 + v1);
								v22 = v94 & 1;
								v97 = v94 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = v3[1];
									v3 += 2;
									*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v97 )
								{
									do
									{
										v98 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = BYTE1(v98);
										v98 >>= 16;
										*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE1(v98);
										v2 += 4;
										--v97;
										*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
									}
									while ( v97 );
								}
							}
							else
							{
								v22 = v94 & 1;
								v95 = v94 >> 1;
								if ( v22 )
								{
									_LOBYTE(v1) = *v3;
									v3 += 2;
									*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
									v2 += 2;
								}
								if ( (_BYTE)v95 )
								{
									do
									{
										v96 = *(_DWORD *)v3;
										v3 += 4;
										_LOBYTE(v1) = v96;
										*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
										_LOBYTE(v1) = BYTE2(v96);
										v2 += 4;
										--v95;
										*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
									}
									while ( v95 );
								}
							}
							v1 = (unsigned char)v3 & 2;
							v3 += v1;
						}
						v2 = v84 + v2 - 800;
						v84 += 2;
					}
					while ( v84 != 32 );
					return;
				}
				v71 = world_4B33FD[v70];
				v3 += *(int *)((char *)world_4B34BD + v71);
				v72 = 192 * v71;
				v71 >>= 1;
				v2 -= v72;
				v69 = 30 - v71;
				world_4B325C += v71 >> 1;
			}
			do
			{
				v73 = 32 - v69;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v22 = v73 & 1;
					v74 = v73 >> 1;
					if ( v22 )
					{
						++v3;
						++v2;
						v22 = v74 & 1;
						v77 = v74 >> 1;
						if ( v22 )
						{
							_LOBYTE(v1) = *v3;
							v3 += 2;
							*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
							v2 += 2;
						}
						if ( (_BYTE)v77 )
						{
							do
							{
								v78 = *(_DWORD *)v3;
								v3 += 4;
								_LOBYTE(v1) = v78;
								*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
								_LOBYTE(v1) = BYTE2(v78);
								v2 += 4;
								--v77;
								*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
							}
							while ( v77 );
						}
					}
					else
					{
						v22 = v74 & 1;
						v75 = v74 >> 1;
						if ( v22 )
						{
							_LOBYTE(v1) = v3[1];
							v3 += 2;
							*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
							v2 += 2;
						}
						if ( (_BYTE)v75 )
						{
							do
							{
								v76 = *(_DWORD *)v3;
								v3 += 4;
								_LOBYTE(v1) = BYTE1(v76);
								v76 >>= 16;
								*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
								_LOBYTE(v1) = BYTE1(v76);
								v2 += 4;
								--v75;
								*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
							}
							while ( v75 );
						}
					}
					v1 = (unsigned char)v3 & 2;
					v3 += v1;
				}
				else
				{
					v22 = v73 & 1;
					v79 = v73 >> 1;
					if ( v22 )
					{
						_LOBYTE(v1) = *v3++;
						*(_BYTE *)v2++ = *(_BYTE *)(v4 + v1);
						v22 = v79 & 1;
						v82 = v79 >> 1;
						if ( v22 )
						{
							_LOBYTE(v1) = v3[1];
							v3 += 2;
							*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
							v2 += 2;
						}
						if ( (_BYTE)v82 )
						{
							do
							{
								v83 = *(_DWORD *)v3;
								v3 += 4;
								_LOBYTE(v1) = BYTE1(v83);
								v83 >>= 16;
								*(_BYTE *)(v2 + 1) = *(_BYTE *)(v4 + v1);
								_LOBYTE(v1) = BYTE1(v83);
								v2 += 4;
								--v82;
								*(_BYTE *)(v2 - 1) = *(_BYTE *)(v4 + v1);
							}
							while ( v82 );
						}
					}
					else
					{
						v22 = v79 & 1;
						v80 = v79 >> 1;
						if ( v22 )
						{
							_LOBYTE(v1) = *v3;
							v3 += 2;
							*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
							v2 += 2;
						}
						if ( (_BYTE)v80 )
						{
							do
							{
								v81 = *(_DWORD *)v3;
								v3 += 4;
								_LOBYTE(v1) = v81;
								*(_BYTE *)v2 = *(_BYTE *)(v4 + v1);
								_LOBYTE(v1) = BYTE2(v81);
								v2 += 4;
								--v80;
								*(_BYTE *)(v2 - 2) = *(_BYTE *)(v4 + v1);
							}
							while ( v80 );
						}
					}
					v1 = (unsigned char)v3 & 2;
					v3 += v1;
				}
				v2 = v69 + v2 - 800;
				v50 = __OFSUB__(v69, 2);
				v69 -= 2;
			}
			while ( !((v69 < 0) ^ v50) );
			goto LABEL_154;
		}
		world_4B325C = 0;
		v32 = 30;
		if ( (unsigned int)a1 >= screen_buf_end )
		{
			v33 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
			if ( v33 > 45 )
			{
				v2 = (unsigned int)a1 - 12288;
				v3 += 288;
LABEL_98:
				v51 = 2;
				if ( v2 >= screen_buf_end )
				{
					v52 = (v2 - screen_buf_end + 1023) >> 8;
					if ( v52 > 42 )
						return;
					v53 = world_4B33FD[v52];
					v3 += *(int *)((char *)world_4B3501 + v53);
					v54 = 192 * v53;
					v53 >>= 1;
					v2 -= v54;
					v51 = v53 + 2;
					world_4B325C += v53 >> 1;
				}
				do
				{
					v55 = (_BYTE *)(v51 + v2);
					v56 = 32 - v51;
					world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
					if ( world_4B325C )
					{
						v57 = v56 & 2;
						v3 += v57;
						v22 = v56 & 1;
						v58 = v56 >> 1;
						if ( v22 )
						{
							++v3;
							++v55;
							v22 = v58 & 1;
							v61 = v58 >> 1;
							if ( v22 )
							{
								_LOBYTE(v57) = *v3;
								v3 += 2;
								*v55 = *(_BYTE *)(v4 + v57);
								v55 += 2;
							}
							if ( (_BYTE)v61 )
							{
								do
								{
									v62 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v57) = v62;
									*v55 = *(_BYTE *)(v4 + v57);
									_LOBYTE(v57) = BYTE2(v62);
									v55 += 4;
									--v61;
									*(v55 - 2) = *(_BYTE *)(v4 + v57);
								}
								while ( v61 );
							}
						}
						else
						{
							v22 = v58 & 1;
							v59 = v58 >> 1;
							if ( v22 )
							{
								_LOBYTE(v57) = v3[1];
								v3 += 2;
								v55[1] = *(_BYTE *)(v4 + v57);
								v55 += 2;
							}
							if ( (_BYTE)v59 )
							{
								do
								{
									v60 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v57) = BYTE1(v60);
									v60 >>= 16;
									v55[1] = *(_BYTE *)(v4 + v57);
									_LOBYTE(v57) = BYTE1(v60);
									v55 += 4;
									--v59;
									*(v55 - 1) = *(_BYTE *)(v4 + v57);
								}
								while ( v59 );
							}
						}
					}
					else
					{
						v63 = v56 & 2;
						v3 += v63;
						v22 = v56 & 1;
						v64 = v56 >> 1;
						if ( v22 )
						{
							_LOBYTE(v63) = *v3++;
							*v55++ = *(_BYTE *)(v4 + v63);
							v22 = v64 & 1;
							v67 = v64 >> 1;
							if ( v22 )
							{
								_LOBYTE(v63) = v3[1];
								v3 += 2;
								v55[1] = *(_BYTE *)(v4 + v63);
								v55 += 2;
							}
							if ( (_BYTE)v67 )
							{
								do
								{
									v68 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v63) = BYTE1(v68);
									v68 >>= 16;
									v55[1] = *(_BYTE *)(v4 + v63);
									_LOBYTE(v63) = BYTE1(v68);
									v55 += 4;
									--v67;
									*(v55 - 1) = *(_BYTE *)(v4 + v63);
								}
								while ( v67 );
							}
						}
						else
						{
							v22 = v64 & 1;
							v65 = v64 >> 1;
							if ( v22 )
							{
								_LOBYTE(v63) = *v3;
								v3 += 2;
								*v55 = *(_BYTE *)(v4 + v63);
								v55 += 2;
							}
							if ( (_BYTE)v65 )
							{
								do
								{
									v66 = *(_DWORD *)v3;
									v3 += 4;
									_LOBYTE(v63) = v66;
									*v55 = *(_BYTE *)(v4 + v63);
									_LOBYTE(v63) = BYTE2(v66);
									v55 += 4;
									--v65;
									*(v55 - 2) = *(_BYTE *)(v4 + v63);
								}
								while ( v65 );
							}
						}
					}
					v2 = (unsigned int)(v55 - 800);
					v51 += 2;
				}
				while ( v51 != 32 );
				return;
			}
			v34 = world_4B33FD[v33];
			v3 += *(int *)((char *)world_4B34BD + v34);
			v35 = 192 * v34;
			v34 >>= 1;
			v2 -= v35;
			v32 = 30 - v34;
			world_4B325C += v34 >> 1;
		}
		do
		{
			v36 = (_BYTE *)(v32 + v2);
			v37 = 32 - v32;
			world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
			if ( world_4B325C )
			{
				v38 = v37 & 2;
				v3 += v38;
				v22 = v37 & 1;
				v39 = v37 >> 1;
				if ( v22 )
				{
					++v3;
					++v36;
					v22 = v39 & 1;
					v42 = v39 >> 1;
					if ( v22 )
					{
						_LOBYTE(v38) = *v3;
						v3 += 2;
						*v36 = *(_BYTE *)(v4 + v38);
						v36 += 2;
					}
					if ( (_BYTE)v42 )
					{
						do
						{
							v43 = *(_DWORD *)v3;
							v3 += 4;
							_LOBYTE(v38) = v43;
							*v36 = *(_BYTE *)(v4 + v38);
							_LOBYTE(v38) = BYTE2(v43);
							v36 += 4;
							--v42;
							*(v36 - 2) = *(_BYTE *)(v4 + v38);
						}
						while ( v42 );
					}
				}
				else
				{
					v22 = v39 & 1;
					v40 = v39 >> 1;
					if ( v22 )
					{
						_LOBYTE(v38) = v3[1];
						v3 += 2;
						v36[1] = *(_BYTE *)(v4 + v38);
						v36 += 2;
					}
					if ( (_BYTE)v40 )
					{
						do
						{
							v41 = *(_DWORD *)v3;
							v3 += 4;
							_LOBYTE(v38) = BYTE1(v41);
							v41 >>= 16;
							v36[1] = *(_BYTE *)(v4 + v38);
							_LOBYTE(v38) = BYTE1(v41);
							v36 += 4;
							--v40;
							*(v36 - 1) = *(_BYTE *)(v4 + v38);
						}
						while ( v40 );
					}
				}
			}
			else
			{
				v44 = v37 & 2;
				v3 += v44;
				v22 = v37 & 1;
				v45 = v37 >> 1;
				if ( v22 )
				{
					_LOBYTE(v44) = *v3++;
					*v36++ = *(_BYTE *)(v4 + v44);
					v22 = v45 & 1;
					v48 = v45 >> 1;
					if ( v22 )
					{
						_LOBYTE(v44) = v3[1];
						v3 += 2;
						v36[1] = *(_BYTE *)(v4 + v44);
						v36 += 2;
					}
					if ( (_BYTE)v48 )
					{
						do
						{
							v49 = *(_DWORD *)v3;
							v3 += 4;
							_LOBYTE(v44) = BYTE1(v49);
							v49 >>= 16;
							v36[1] = *(_BYTE *)(v4 + v44);
							_LOBYTE(v44) = BYTE1(v49);
							v36 += 4;
							--v48;
							*(v36 - 1) = *(_BYTE *)(v4 + v44);
						}
						while ( v48 );
					}
				}
				else
				{
					v22 = v45 & 1;
					v46 = v45 >> 1;
					if ( v22 )
					{
						_LOBYTE(v44) = *v3;
						v3 += 2;
						*v36 = *(_BYTE *)(v4 + v44);
						v36 += 2;
					}
					if ( (_BYTE)v46 )
					{
						do
						{
							v47 = *(_DWORD *)v3;
							v3 += 4;
							_LOBYTE(v44) = v47;
							*v36 = *(_BYTE *)(v4 + v44);
							_LOBYTE(v44) = BYTE2(v47);
							v36 += 4;
							--v46;
							*(v36 - 2) = *(_BYTE *)(v4 + v44);
						}
						while ( v46 );
					}
				}
			}
			v2 = (unsigned int)(v36 - 800);
			v50 = __OFSUB__(v32, 2);
			v32 -= 2;
		}
		while ( !((v32 < 0) ^ v50) );
		goto LABEL_98;
	}
	v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265);
	v7 = (unsigned char)(BYTE1(level_cel_block) >> 4);
LABEL_11:
	switch ( v7 )
	{
		case 8:
			v142 = 16;
			do
			{
				if ( v2 < screen_buf_end )
				{
					v143 = 8;
					do
					{
						v144 = *(_DWORD *)v6;
						v6 += 4;
						v145 = (_BYTE *)(v2 + 1);
						v144 = __ROR4__(v144, 8);
						*v145 = v144;
						v145 += 2;
						*v145 = __ROR4__(v144, 16);
						v2 = (unsigned int)(v145 + 1);
						--v143;
					}
					while ( v143 );
				}
				else
				{
					v6 += 32;
					v2 += 32;
				}
				v146 = (_BYTE *)(v2 - 800);
				if ( (unsigned int)v146 < screen_buf_end )
				{
					v147 = 8;
					do
					{
						v148 = *(_DWORD *)v6;
						v6 += 4;
						*v146 = v148;
						v149 = v146 + 2;
						*v149 = __ROR4__(v148, 16);
						v146 = v149 + 2;
						--v147;
					}
					while ( v147 );
				}
				else
				{
					v6 += 32;
					v146 += 32;
				}
				v2 = (unsigned int)(v146 - 800);
				--v142;
			}
			while ( v142 );
			return;
		case 9:
			world_4B325C = (unsigned char)a1 & 1;
			v150 = 32;
			while ( 1 )
			{
				v323 = v150;
				v151 = 32;
				do
				{
					while ( 1 )
					{
						v152 = (unsigned char)*v6++;
						if ( (v152 & 0x80u) != 0 )
							break;
						v151 -= v152;
						if ( v2 < screen_buf_end )
						{
							if ( (v2 & 1) == world_4B325C )
							{
								v153 = v152 >> 1;
								if ( !(v152 & 1) )
									goto LABEL_280;
								++v6;
								++v2;
								if ( v153 )
								{
LABEL_287:
									v22 = v153 & 1;
									v161 = v153 >> 1;
									if ( !v22 || (v162 = *v6, v6 += 2, *(_BYTE *)v2 = v162, v2 += 2, v161) )
									{
										do
										{
											v163 = *(_DWORD *)v6;
											v6 += 4;
											*(_BYTE *)v2 = v163;
											v164 = (_BYTE *)(v2 + 2);
											*v164 = __ROR4__(v163, 16);
											v2 = (unsigned int)(v164 + 2);
											--v161;
										}
										while ( v161 );
									}
									goto LABEL_290;
								}
							}
							else
							{
								v153 = v152 >> 1;
								if ( !(v152 & 1) )
									goto LABEL_287;
								v160 = *v6++;
								*(_BYTE *)v2++ = v160;
								if ( v153 )
								{
LABEL_280:
									v22 = v153 & 1;
									v154 = v153 >> 1;
									if ( !v22
									  || (v155 = v6 + 1,
										  v156 = (_BYTE *)(v2 + 1),
										  v157 = *v155,
										  v6 = v155 + 1,
										  *v156 = v157,
										  v2 = (unsigned int)(v156 + 1),
										  v154) )
									{
										do
										{
											v158 = *(_DWORD *)v6;
											v6 += 4;
											v159 = (_BYTE *)(v2 + 1);
											v158 = __ROR4__(v158, 8);
											*v159 = v158;
											v159 += 2;
											*v159 = __ROR4__(v158, 16);
											v2 = (unsigned int)(v159 + 1);
											--v154;
										}
										while ( v154 );
									}
									goto LABEL_290;
								}
							}
						}
						else
						{
							v6 += v152;
							v2 += v152;
						}
LABEL_290:
						if ( !v151 )
							goto LABEL_293;
					}
					_LOBYTE(v152) = -(char)v152;
					v2 += v152;
					v151 -= v152;
				}
				while ( v151 );
LABEL_293:
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				v2 -= 800;
				v150 = v323 - 1;
				if ( v323 == 1 )
					return;
			}
		case 10:
			world_4B325C = 0;
			v165 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v166 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v166 > 45 )
				{
					v2 = (unsigned int)a1 - 12288;
					v6 += 288;
LABEL_308:
					v180 = 2;
					if ( v2 >= screen_buf_end )
					{
						v181 = (v2 - screen_buf_end + 1023) >> 8;
						if ( v181 > 42 )
							return;
						v182 = world_4B33FD[v181];
						v6 += *(int *)((char *)world_4B3501 + v182);
						v183 = 192 * v182;
						v182 >>= 1;
						v2 -= v183;
						v180 = v182 + 2;
						world_4B325C += v182 >> 1;
					}
					do
					{
						v184 = (_BYTE *)(v180 + v2);
						v185 = 32 - v180;
						v186 = ((_BYTE)world_4B325C + 1) & 1;
						world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
						if ( world_4B325C )
						{
							v22 = __CFSHR__(v185, 2);
							v187 = v185 >> 2;
							if ( !v22
							  || (_LOWORD(v186) = *((_WORD *)v6 + 1),
								  v6 += 4,
								  v188 = v184 + 1,
								  *v188 = __ROR4__(v186, 8),
								  v184 = v188 + 1,
								  v187) )
							{
								do
								{
									v189 = *(_DWORD *)v6;
									v6 += 4;
									v190 = v184 + 1;
									v189 = __ROR4__(v189, 8);
									*v190 = v189;
									v190 += 2;
									*v190 = __ROR4__(v189, 16);
									v184 = v190 + 1;
									--v187;
								}
								while ( v187 );
							}
						}
						else
						{
							v22 = __CFSHR__(v185, 2);
							v191 = v185 >> 2;
							if ( !v22 || (v192 = *((_WORD *)v6 + 1), v6 += 4, *v184 = v192, v184 += 2, --v191, v191) )
							{
								do
								{
									v193 = *(_DWORD *)v6;
									v6 += 4;
									*v184 = v193;
									v194 = v184 + 2;
									*v194 = __ROR4__(v193, 16);
									v184 = v194 + 2;
									--v191;
								}
								while ( v191 );
							}
						}
						v2 = (unsigned int)(v184 - 800);
						v180 += 2;
					}
					while ( v180 != 32 );
					return;
				}
				v167 = world_4B33FD[v166];
				v6 += *(int *)((char *)world_4B34BD + v167);
				v168 = 192 * v167;
				v167 >>= 1;
				v2 -= v168;
				v165 = 30 - v167;
				world_4B325C += v167 >> 1;
			}
			do
			{
				v169 = (_BYTE *)(v165 + v2);
				v170 = 32 - v165;
				v171 = ((_BYTE)world_4B325C + 1) & 1;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					v22 = __CFSHR__(v170, 2);
					v172 = v170 >> 2;
					if ( !v22
					  || (_LOWORD(v171) = *((_WORD *)v6 + 1),
						  v6 += 4,
						  v173 = v169 + 1,
						  *v173 = __ROR4__(v171, 8),
						  v169 = v173 + 1,
						  v172) )
					{
						do
						{
							v174 = *(_DWORD *)v6;
							v6 += 4;
							v175 = v169 + 1;
							v174 = __ROR4__(v174, 8);
							*v175 = v174;
							v175 += 2;
							*v175 = __ROR4__(v174, 16);
							v169 = v175 + 1;
							--v172;
						}
						while ( v172 );
					}
				}
				else
				{
					v22 = __CFSHR__(v170, 2);
					v176 = v170 >> 2;
					if ( !v22 || (v177 = *((_WORD *)v6 + 1), v6 += 4, *v169 = v177, v169 += 2, v176) )
					{
						do
						{
							v178 = *(_DWORD *)v6;
							v6 += 4;
							*v169 = v178;
							v179 = v169 + 2;
							*v179 = __ROR4__(v178, 16);
							v169 = v179 + 2;
							--v176;
						}
						while ( v176 );
					}
				}
				v2 = (unsigned int)(v169 - 800);
				v50 = __OFSUB__(v165, 2);
				v165 -= 2;
			}
			while ( !((v165 < 0) ^ v50) );
			goto LABEL_308;
	}
	if ( v7 != 11 )
	{
		if ( v7 != 12 )
		{
			world_4B325C = 0;
			v246 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v247 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v247 > 45 )
				{
					v2 = (unsigned int)a1 - 12288;
					v6 += 288;
LABEL_389:
					v260 = 8;
					do
					{
						if ( v2 < screen_buf_end )
						{
							v261 = 8;
							do
							{
								v262 = *(_DWORD *)v6;
								v6 += 4;
								v263 = (_BYTE *)(v2 + 1);
								v262 = __ROR4__(v262, 8);
								*v263 = v262;
								v263 += 2;
								*v263 = __ROR4__(v262, 16);
								v2 = (unsigned int)(v263 + 1);
								--v261;
							}
							while ( v261 );
						}
						else
						{
							v6 += 32;
							v2 += 32;
						}
						v264 = (_BYTE *)(v2 - 800);
						if ( (unsigned int)v264 < screen_buf_end )
						{
							v265 = 8;
							do
							{
								v266 = *(_DWORD *)v6;
								v6 += 4;
								*v264 = v266;
								v267 = v264 + 2;
								*v267 = __ROR4__(v266, 16);
								v264 = v267 + 2;
								--v265;
							}
							while ( v265 );
						}
						else
						{
							v6 += 32;
							v264 += 32;
						}
						v2 = (unsigned int)(v264 - 800);
						--v260;
					}
					while ( v260 );
					return;
				}
				v248 = world_4B33FD[v247];
				v6 += *(int *)((char *)world_4B34BD + v248);
				v249 = 192 * v248;
				v248 >>= 1;
				v2 -= v249;
				v246 = 30 - v248;
				world_4B325C += v248 >> 1;
			}
			do
			{
				v250 = 32 - v246;
				v251 = ((_BYTE)world_4B325C + 1) & 1;
				world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
				if ( world_4B325C )
				{
					for ( m = v250 >> 2; m; --m )
					{
						v253 = *(_DWORD *)v6;
						v6 += 4;
						v254 = (_BYTE *)(v2 + 1);
						v253 = __ROR4__(v253, 8);
						*v254 = v253;
						v254 += 2;
						v251 = __ROR4__(v253, 16);
						*v254 = v251;
						v2 = (unsigned int)(v254 + 1);
					}
					if ( (32 - (_BYTE)v246) & 2 )
					{
						_LOWORD(v251) = *(_WORD *)v6;
						v6 += 4;
						v255 = (_BYTE *)(v2 + 1);
						*v255 = __ROR4__(v251, 8);
						v2 = (unsigned int)(v255 + 1);
					}
				}
				else
				{
					for ( n = v250 >> 2; n; --n )
					{
						v257 = *(_DWORD *)v6;
						v6 += 4;
						*(_BYTE *)v2 = v257;
						v258 = (_BYTE *)(v2 + 2);
						*v258 = __ROR4__(v257, 16);
						v2 = (unsigned int)(v258 + 2);
					}
					if ( (32 - (_BYTE)v246) & 2 )
					{
						v259 = *(_WORD *)v6;
						v6 += 4;
						*(_BYTE *)v2 = v259;
						v2 += 2;
					}
				}
				v2 = v246 + v2 - 800;
				v50 = __OFSUB__(v246, 2);
				v246 -= 2;
			}
			while ( !((v246 < 0) ^ v50) );
			goto LABEL_389;
		}
		world_4B325C = 0;
		v223 = 30;
		if ( (unsigned int)a1 >= screen_buf_end )
		{
			v224 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
			if ( v224 > 45 )
			{
				v2 = (unsigned int)a1 - 12288;
				v6 += 288;
LABEL_364:
				v238 = 8;
				do
				{
					if ( v2 < screen_buf_end )
					{
						v239 = 8;
						do
						{
							v240 = *(_DWORD *)v6;
							v6 += 4;
							v241 = (_BYTE *)(v2 + 1);
							v240 = __ROR4__(v240, 8);
							*v241 = v240;
							v241 += 2;
							*v241 = __ROR4__(v240, 16);
							v2 = (unsigned int)(v241 + 1);
							--v239;
						}
						while ( v239 );
					}
					else
					{
						v6 += 32;
						v2 += 32;
					}
					v242 = (_BYTE *)(v2 - 800);
					if ( (unsigned int)v242 < screen_buf_end )
					{
						v243 = 8;
						do
						{
							v244 = *(_DWORD *)v6;
							v6 += 4;
							*v242 = v244;
							v245 = v242 + 2;
							*v245 = __ROR4__(v244, 16);
							v242 = v245 + 2;
							--v243;
						}
						while ( v243 );
					}
					else
					{
						v6 += 32;
						v242 += 32;
					}
					v2 = (unsigned int)(v242 - 800);
					--v238;
				}
				while ( v238 );
				return;
			}
			v225 = world_4B33FD[v224];
			v6 += *(int *)((char *)world_4B34BD + v225);
			v226 = 192 * v225;
			v225 >>= 1;
			v2 -= v226;
			v223 = 30 - v225;
			world_4B325C += v225 >> 1;
		}
		do
		{
			v227 = (_BYTE *)(v223 + v2);
			v228 = 32 - v223;
			v229 = ((_BYTE)world_4B325C + 1) & 1;
			world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
			if ( world_4B325C )
			{
				v22 = __CFSHR__(v228, 2);
				v230 = v228 >> 2;
				if ( !v22
				  || (_LOWORD(v229) = *((_WORD *)v6 + 1),
					  v6 += 4,
					  v231 = v227 + 1,
					  *v231 = __ROR4__(v229, 8),
					  v227 = v231 + 1,
					  v230) )
				{
					do
					{
						v232 = *(_DWORD *)v6;
						v6 += 4;
						v233 = v227 + 1;
						v232 = __ROR4__(v232, 8);
						*v233 = v232;
						v233 += 2;
						*v233 = __ROR4__(v232, 16);
						v227 = v233 + 1;
						--v230;
					}
					while ( v230 );
				}
			}
			else
			{
				v22 = __CFSHR__(v228, 2);
				v234 = v228 >> 2;
				if ( !v22 || (v235 = *((_WORD *)v6 + 1), v6 += 4, *v227 = v235, v227 += 2, v234) )
				{
					do
					{
						v236 = *(_DWORD *)v6;
						v6 += 4;
						*v227 = v236;
						v237 = v227 + 2;
						*v237 = __ROR4__(v236, 16);
						--v234;
						v227 = v237 + 2;
					}
					while ( v234 );
				}
			}
			v2 = (unsigned int)(v227 - 800);
			v50 = __OFSUB__(v223, 2);
			v223 -= 2;
		}
		while ( !((v223 < 0) ^ v50) );
		goto LABEL_364;
	}
	world_4B325C = 0;
	v195 = 30;
	if ( (unsigned int)a1 < screen_buf_end )
		goto LABEL_326;
	v196 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
	if ( v196 <= 45 )
	{
		v197 = world_4B33FD[v196];
		v6 += *(int *)((char *)world_4B34BD + v197);
		v198 = 192 * v197;
		v197 >>= 1;
		v2 -= v198;
		v195 = 30 - v197;
		world_4B325C += v197 >> 1;
		do
		{
LABEL_326:
			v199 = 32 - v195;
			v200 = ((_BYTE)world_4B325C + 1) & 1;
			world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
			if ( world_4B325C )
			{
				for ( ii = v199 >> 2; ii; --ii )
				{
					v202 = *(_DWORD *)v6;
					v6 += 4;
					v203 = (_BYTE *)(v2 + 1);
					v202 = __ROR4__(v202, 8);
					*v203 = v202;
					v203 += 2;
					v200 = __ROR4__(v202, 16);
					*v203 = v200;
					v2 = (unsigned int)(v203 + 1);
				}
				if ( (32 - (_BYTE)v195) & 2 )
				{
					_LOWORD(v200) = *(_WORD *)v6;
					v6 += 4;
					v204 = (_BYTE *)(v2 + 1);
					*v204 = __ROR4__(v200, 8);
					v2 = (unsigned int)(v204 + 1);
				}
			}
			else
			{
				for ( jj = v199 >> 2; jj; --jj )
				{
					v206 = *(_DWORD *)v6;
					v6 += 4;
					*(_BYTE *)v2 = v206;
					v207 = (_BYTE *)(v2 + 2);
					*v207 = __ROR4__(v206, 16);
					v2 = (unsigned int)(v207 + 2);
				}
				if ( (32 - (_BYTE)v195) & 2 )
				{
					v208 = *(_WORD *)v6;
					v6 += 4;
					*(_BYTE *)v2 = v208;
					v2 += 2;
				}
			}
			v2 = v195 + v2 - 800;
			v50 = __OFSUB__(v195, 2);
			v195 -= 2;
		}
		while ( !((v195 < 0) ^ v50) );
		goto LABEL_336;
	}
	v2 = (unsigned int)a1 - 12288;
	v6 += 288;
LABEL_336:
	v209 = 2;
	if ( v2 >= screen_buf_end )
	{
		v210 = (v2 - screen_buf_end + 1023) >> 8;
		if ( v210 > 42 )
			return;
		v211 = world_4B33FD[v210];
		v6 += *(int *)((char *)world_4B3501 + v211);
		v212 = 192 * v211;
		v211 >>= 1;
		v2 -= v212;
		v209 = v211 + 2;
		world_4B325C += v211 >> 1;
	}
	do
	{
		v213 = 32 - v209;
		v214 = ((_BYTE)world_4B325C + 1) & 1;
		world_4B325C = ((_BYTE)world_4B325C + 1) & 1;
		if ( world_4B325C )
		{
			for ( kk = v213 >> 2; kk; --kk )
			{
				v216 = *(_DWORD *)v6;
				v6 += 4;
				v217 = (_BYTE *)(v2 + 1);
				v216 = __ROR4__(v216, 8);
				*v217 = v216;
				v217 += 2;
				v214 = __ROR4__(v216, 16);
				*v217 = v214;
				v2 = (unsigned int)(v217 + 1);
			}
			if ( (32 - (_BYTE)v209) & 2 )
			{
				_LOWORD(v214) = *(_WORD *)v6;
				v6 += 4;
				v218 = (_BYTE *)(v2 + 1);
				*v218 = __ROR4__(v214, 8);
				v2 = (unsigned int)(v218 + 1);
			}
		}
		else
		{
			for ( ll = v213 >> 2; ll; --ll )
			{
				v220 = *(_DWORD *)v6;
				v6 += 4;
				*(_BYTE *)v2 = v220;
				v221 = (_BYTE *)(v2 + 2);
				*v221 = __ROR4__(v220, 16);
				v2 = (unsigned int)(v221 + 2);
			}
			if ( (32 - (_BYTE)v209) & 2 )
			{
				v222 = *(_WORD *)v6;
				v6 += 4;
				*(_BYTE *)v2 = v222;
				v2 += 2;
			}
		}
		v2 = v209 + v2 - 800;
		v209 += 2;
	}
	while ( v209 != 32 );
}
// 642A14: using guessed type char lightmax;
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF14: using guessed type int level_cel_block;

//----- (00467949) --------------------------------------------------------
void __fastcall drawBottomArchesLowerScreen(void *a1, int a2)
{
	_BYTE *v2; // edi
	char *v3; // esi
	short v5; // ax
	char *v6; // esi
	short v7; // ax
	unsigned int v8; // eax
	char *v9; // esi
	unsigned int v10; // eax
	int v11; // eax
	signed int v12; // ebp
	int v13; // edx
	signed int v14; // ecx
	unsigned char v16; // cf
	int v18; // ecx
	signed int v19; // edx
	int v20; // eax
	int v21; // ecx
	int v22; // edx
	int v25; // edx
	signed int v26; // eax
	unsigned int v27; // ecx
	_WORD *v28; // edi
	unsigned int v29; // ecx
	unsigned char v32; // of
	int v33; // edx
	signed int v34; // eax
	unsigned int v35; // ecx
	_WORD *v36; // edi
	unsigned int v37; // ecx
	int v40; // edx
	signed int v41; // eax
	unsigned int v42; // ecx
	unsigned int ii; // ecx
	int v46; // edx
	signed int v47; // eax
	unsigned int v48; // ecx
	unsigned int n; // ecx
	int v52; // edx
	signed int v53; // eax
	unsigned int v54; // ecx
	_WORD *v55; // edi
	unsigned int v56; // ecx
	signed int v59; // edx
	int v60; // edx
	signed int v61; // ecx
	int v64; // edx
	signed int v65; // eax
	unsigned int v66; // ecx
	unsigned int m; // ecx
	signed int v70; // edx
	int v71; // edx
	signed int v72; // ecx
	signed int v75; // edx
	int v76; // edx
	signed int v77; // ecx
	char v78; // al
	int v79; // ecx
	signed int v80; // edx
	int v81; // eax
	int v82; // ecx
	int v83; // edx
	char v84; // al
	int v85; // edx
	signed int v86; // eax
	unsigned int v87; // ecx
	_DWORD *v88; // edi
	unsigned int v89; // ecx
	short v90; // ax
	int v91; // eax
	int v92; // edx
	signed int v93; // eax
	unsigned int v94; // ecx
	_DWORD *v95; // edi
	unsigned int v96; // ecx
	short v97; // ax
	int v98; // eax
	int v99; // edx
	signed int v100; // eax
	unsigned int v101; // ecx
	unsigned int kk; // ecx
	int v103; // eax
	short v104; // ax
	int v105; // edx
	signed int v106; // eax
	unsigned int v107; // ecx
	unsigned int ll; // ecx
	int v109; // eax
	short v110; // ax
	int v111; // edx
	signed int v112; // eax
	unsigned int v113; // ecx
	_DWORD *v114; // edi
	unsigned int v115; // ecx
	short v116; // ax
	int v117; // eax
	signed int v118; // edx
	int v119; // edx
	signed int v120; // ecx
	char v121; // al
	int v122; // edx
	signed int v123; // eax
	unsigned int v124; // ecx
	unsigned int jj; // ecx
	int v126; // eax
	short v127; // ax
	signed int v128; // edx
	int v129; // edx
	signed int v130; // ecx
	char v131; // al
	signed int v132; // edx
	int v133; // edx
	signed int v134; // ecx
	int v135; // ecx
	signed int v136; // edx
	int v137; // eax
	int v138; // ecx
	int v139; // edx
	signed int i; // edx
	_DWORD *v141; // edi
	unsigned int v142; // ecx
	signed int v143; // edx
	_DWORD *v144; // edi
	unsigned int v145; // ecx
	signed int j; // edx
	unsigned int v147; // ecx
	_DWORD *v148; // edi
	signed int v149; // edx
	unsigned int v150; // ecx
	signed int k; // edx
	_DWORD *v152; // edi
	unsigned int v153; // ecx
	signed int v154; // edx
	int v155; // edx
	signed int v156; // ecx
	signed int l; // edx
	unsigned int v158; // ecx
	_BYTE *v159; // edi
	signed int v160; // edx
	int v161; // edx
	signed int v162; // ecx
	signed int v163; // [esp-8h] [ebp-14h]
	signed int v164; // [esp-8h] [ebp-14h]
	signed int v165; // [esp-8h] [ebp-14h]
	signed int v166; // [esp-8h] [ebp-14h]
	signed int v167; // [esp-8h] [ebp-14h]
	int v168; // [esp-4h] [ebp-10h]
	signed int v169; // [esp-4h] [ebp-10h]
	signed int v170; // [esp-4h] [ebp-10h]
	int v171; // [esp-4h] [ebp-10h]
	signed int v172; // [esp-4h] [ebp-10h]
	signed int v173; // [esp-4h] [ebp-10h]
	int v174; // [esp-4h] [ebp-10h]
	signed int v175; // [esp-4h] [ebp-10h]
	signed int v176; // [esp-4h] [ebp-10h]

	world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num;
	v2 = (unsigned char *)a1;
	world_4B3269[0] = a2;
	if ( (_BYTE)light_table_index )
	{
		if ( (_BYTE)light_table_index == lightmax )
		{
			if ( level_cel_block & 0x8000 )
				level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
								+ (unsigned short)(level_cel_block & 0xF000);
			v9 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
			v10 = level_cel_block;
			_LOBYTE(v10) = BYTE1(v10);
			v11 = (v10 >> 4) & 7;
			if ( v11 )
			{
				switch ( (_WORD)v11 )
				{
					case 1:
						v135 = 32;
						do
						{
							v174 = v135;
							*(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0];
							v136 = 32;
							do
							{
								while ( 1 )
								{
									v137 = (unsigned char)*v9++;
									if ( (v137 & 0x80u) != 0 )
										break;
									v136 -= v137;
									if ( (unsigned int)v2 < screen_buf_end )
									{
										v138 = v137;
										v9 += v137;
										v167 = v136;
										v139 = *(_DWORD *)world_4B3260;
										do
										{
											v16 = __CFSHL__(v139, 1);
											v139 *= 2;
											if ( v16 )
												*v2 = 0;
											++v2;
											--v138;
										}
										while ( v138 );
										*(_DWORD *)world_4B3260 = v139;
										v136 = v167;
									}
									else
									{
										v9 += v137;
										v2 += v137;
									}
									if ( !v136 )
										goto LABEL_252;
								}
								_LOBYTE(v137) = -(char)v137;
								v2 += v137;
								if ( v137 & 0x1F )
									*(_DWORD *)world_4B3260 <<= v137 & 0x1F;
								v136 -= v137;
							}
							while ( v136 );
LABEL_252:
							v2 -= 800;
							world_4B3269[0] -= 4;
							v135 = v174 - 1;
						}
						while ( v174 != 1 );
						break;
					case 2:
						for ( i = 30; ; i -= 2 )
						{
							if ( (unsigned int)v2 < screen_buf_end )
							{
								v141 = (unsigned int *)&v2[i];
								v142 = (unsigned int)(32 - i) >> 2;
								if ( !__CFSHR__(32 - i, 2)
								  || (*(_WORD *)v141 = 0, v141 = (_DWORD *)((char *)v141 + 2), v142) )
								{
									do
									{
										*v141 = 0;
										++v141;
										--v142;
									}
									while ( v142 );
								}
							}
							else
							{
								v9 = &v9[-i + 32];
								v141 = (unsigned int *)v2 + 32;
							}
							v2 = (unsigned char *)v141 - 200;
							if ( !i )
								break;
						}
						v143 = 2;
						do
						{
							if ( (unsigned int)v2 < screen_buf_end )
							{
								v144 = (unsigned int *)&v2[v143];
								v145 = (unsigned int)(32 - v143) >> 2;
								if ( !__CFSHR__(32 - v143, 2)
								  || (*(_WORD *)v144 = 0, v144 = (_DWORD *)((char *)v144 + 2), v145) )
								{
									do
									{
										*v144 = 0;
										++v144;
										--v145;
									}
									while ( v145 );
								}
							}
							else
							{
								v9 = &v9[-v143 + 32];
								v144 = (unsigned int *)v2 + 32;
							}
							v2 = (unsigned char *)v144 - 200;
							v143 += 2;
						}
						while ( v143 != 32 );
						break;
					case 3:
						for ( j = 30; ; j -= 2 )
						{
							if ( (unsigned int)v2 < screen_buf_end )
							{
								v147 = (unsigned int)(32 - j) >> 2;
								if ( !__CFSHR__(32 - j, 2) || (*(_WORD *)v2 = 0, v2 += 2, v147) )
								{
									do
									{
										*(_DWORD *)v2 = 0;
										v2 += 4;
										--v147;
									}
									while ( v147 );
								}
							}
							else
							{
								v9 = &v9[-j + 32];
								v2 = &v2[-j + 32];
							}
							v148 = (unsigned int *)v2 - 800;
							if ( !j )
								break;
							v2 = (unsigned char *)v148 + j;
						}
						v149 = 2;
						do
						{
							if ( (unsigned int)v148 < screen_buf_end )
							{
								v150 = (unsigned int)(32 - v149) >> 2;
								if ( !__CFSHR__(32 - v149, 2)
								  || (*(_WORD *)v148 = 0, v148 = (_DWORD *)((char *)v148 + 2), v150) )
								{
									do
									{
										*v148 = 0;
										++v148;
										--v150;
									}
									while ( v150 );
								}
							}
							else
							{
								v9 = &v9[-v149 + 32];
								v148 = (_DWORD *)((char *)v148 - v149 + 32);
							}
							v148 = (_DWORD *)((char *)v148 + v149 - 800);
							v149 += 2;
						}
						while ( v149 != 32 );
						break;
					case 4:
						for ( k = 30; ; k -= 2 )
						{
							if ( (unsigned int)v2 < screen_buf_end )
							{
								v152 = (unsigned int *)&v2[k];
								v153 = (unsigned int)(32 - k) >> 2;
								if ( !__CFSHR__(32 - k, 2)
								  || (*(_WORD *)v152 = 0, v152 = (_DWORD *)((char *)v152 + 2), v153) )
								{
									do
									{
										*v152 = 0;
										++v152;
										--v153;
									}
									while ( v153 );
								}
							}
							else
							{
								v9 = &v9[-k + 32];
								v152 = (unsigned int *)v2 + 32;
							}
							v2 = (unsigned char *)v152 - 200;
							if ( !k )
								break;
						}
						world_4B3269[0] -= 64;
						v154 = 16;
						do
						{
							if ( (unsigned int)v2 < screen_buf_end )
							{
								v175 = v154;
								v155 = *(_DWORD *)world_4B3269[0];
								v156 = 32;
								do
								{
									v16 = __CFSHL__(v155, 1);
									v155 *= 2;
									if ( v16 )
										*v2 = 0;
									++v2;
									--v156;
								}
								while ( v156 );
								v154 = v175;
							}
							else
							{
								v9 += 32;
								v2 += 32;
							}
							v2 -= 800;
							world_4B3269[0] -= 4;
							--v154;
						}
						while ( v154 );
						break;
					default:
						for ( l = 30; ; l -= 2 )
						{
							if ( (unsigned int)v2 < screen_buf_end )
							{
								v158 = (unsigned int)(32 - l) >> 2;
								if ( !__CFSHR__(32 - l, 2) || (*(_WORD *)v2 = 0, v2 += 2, v158) )
								{
									do
									{
										*(_DWORD *)v2 = 0;
										v2 += 4;
										--v158;
									}
									while ( v158 );
								}
							}
							else
							{
								v9 = &v9[-l + 32];
								v2 = &v2[-l + 32];
							}
							v159 = v2 - 800;
							if ( !l )
								break;
							v2 = &v159[l];
						}
						world_4B3269[0] -= 64;
						v160 = 16;
						do
						{
							if ( (unsigned int)v159 < screen_buf_end )
							{
								v176 = v160;
								v161 = *(_DWORD *)world_4B3269[0];
								v162 = 32;
								do
								{
									v16 = __CFSHL__(v161, 1);
									v161 *= 2;
									if ( v16 )
										*v159 = 0;
									++v159;
									--v162;
								}
								while ( v162 );
								v160 = v176;
							}
							else
							{
								v9 += 32;
								v159 += 32;
							}
							v159 -= 800;
							world_4B3269[0] -= 4;
							--v160;
						}
						while ( v160 );
						break;
				}
			}
			else
			{
				v132 = 32;
				do
				{
					if ( (unsigned int)v2 < screen_buf_end )
					{
						v173 = v132;
						v133 = *(_DWORD *)world_4B3269[0];
						v134 = 32;
						do
						{
							v16 = __CFSHL__(v133, 1);
							v133 *= 2;
							if ( v16 )
								*v2 = 0;
							++v2;
							--v134;
						}
						while ( v134 );
						v132 = v173;
					}
					else
					{
						v9 += 32;
						v2 += 32;
					}
					v2 -= 800;
					world_4B3269[0] -= 4;
					--v132;
				}
				while ( v132 );
			}
			return;
		}
		if ( !(level_cel_block & 0x8000) )
		{
			v3 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
/*			_EBX = dword_646A20 + (light_table_index << 8);
			v5 = (unsigned char)(BYTE1(level_cel_block) >> 4);
			if ( !(BYTE1(level_cel_block) >> 4) )
			{
				v12 = 32;
				do
				{
					if ( (unsigned int)v2 < screen_buf_end )
					{
						v13 = *(_DWORD *)world_4B3269[0];
						v14 = 32;
						do
						{
							_AL = *v3++;
							v16 = __CFSHL__(v13, 1);
							v13 *= 2;
							if ( v16 )
							{
								__asm { xlat }
								*v2 = _AL;
							}
							++v2;
							--v14;
						}
						while ( v14 );
					}
					else
					{
						v3 += 32;
						v2 += 32;
					}
					v2 -= 800;
					world_4B3269[0] -= 4;
					--v12;
				}
				while ( v12 );
				return;
			}
			if ( v5 == 1 )
			{
				v18 = 32;
				do
				{
					v168 = v18;
					*(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0];
					v19 = 32;
					do
					{
						while ( 1 )
						{
							v20 = (unsigned char)*v3++;
							if ( (v20 & 0x80u) != 0 )
								break;
							v19 -= v20;
							if ( (unsigned int)v2 < screen_buf_end )
							{
								v21 = v20;
								v163 = v19;
								v22 = *(_DWORD *)world_4B3260;
								do
								{
									_AL = *v3++;
									v16 = __CFSHL__(v22, 1);
									v22 *= 2;
									if ( v16 )
									{
										__asm { xlat }
										*v2 = _AL;
									}
									++v2;
									--v21;
								}
								while ( v21 );
								*(_DWORD *)world_4B3260 = v22;
								v19 = v163;
							}
							else
							{
								v3 += v20;
								v2 += v20;
							}
							if ( !v19 )
								goto LABEL_52;
						}
						_LOBYTE(v20) = -(char)v20;
						v2 += v20;
						if ( v20 & 0x1F )
							*(_DWORD *)world_4B3260 <<= v20 & 0x1F;
						v19 -= v20;
					}
					while ( v19 );
LABEL_52:
					v2 -= 800;
					world_4B3269[0] -= 4;
					v18 = v168 - 1;
				}
				while ( v168 != 1 );
				return;
			}
			if ( v5 != 2 )
			{
				if ( v5 != 3 )
				{
					if ( v5 != 4 )
					{
						v64 = 30;
						if ( (unsigned int)a1 >= screen_buf_end )
						{
							v65 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
							if ( v65 > 45 )
							{
								v2 = (char *)a1 - 12288;
								v3 += 288;
LABEL_117:
								world_4B3269[0] -= 64;
								v70 = 16;
								do
								{
									if ( (unsigned int)v2 < screen_buf_end )
									{
										v164 = v70;
										v71 = *(_DWORD *)world_4B3269[0];
										v72 = 32;
										do
										{
											_AL = *v3++;
											v16 = __CFSHL__(v71, 1);
											v71 *= 2;
											if ( v16 )
											{
												__asm { xlat }
												*v2 = _AL;
											}
											++v2;
											--v72;
										}
										while ( v72 );
										v3 += (unsigned char)v3 & 2;
										v70 = v164;
									}
									else
									{
										v3 += 32;
										v2 += 32;
									}
									v2 -= 800;
									world_4B3269[0] -= 4;
									--v70;
								}
								while ( v70 );
								return;
							}
							v66 = world_4B33FD[v65];
							v3 += *(int *)((char *)world_4B34BD + v66);
							v2 -= 192 * v66;
							v64 = 30 - (v66 >> 1);
						}
						do
						{
							for ( m = (unsigned int)(32 - v64) >> 2; m; --m )
							{
								_EAX = *(_DWORD *)v3;
								v3 += 4;
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								*(_DWORD *)v2 = __ROR4__(_EAX, 8);
								v2 += 4;
							}
							if ( (32 - (_BYTE)v64) & 2 )
							{
								_AX = *(_WORD *)v3;
								v3 += 4;
								__asm { xlat }
								_AX = __ROR2__(_AX, 8);
								__asm { xlat }
								*(_WORD *)v2 = __ROR2__(_AX, 8);
								v2 += 2;
							}
							v2 = &v2[v64 - 800];
							v32 = __OFSUB__(v64, 2);
							v64 -= 2;
						}
						while ( !((v64 < 0) ^ v32) );
						goto LABEL_117;
					}
					v52 = 30;
					if ( (unsigned int)a1 >= screen_buf_end )
					{
						v53 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
						if ( v53 > 45 )
						{
							v2 = (char *)a1 - 12288;
							v3 += 288;
LABEL_98:
							world_4B3269[0] -= 64;
							v59 = 16;
							do
							{
								if ( (unsigned int)v2 < screen_buf_end )
								{
									v169 = v59;
									v60 = *(_DWORD *)world_4B3269[0];
									v61 = 32;
									do
									{
										_AL = *v3++;
										v16 = __CFSHL__(v60, 1);
										v60 *= 2;
										if ( v16 )
										{
											__asm { xlat }
											*v2 = _AL;
										}
										++v2;
										--v61;
									}
									while ( v61 );
									v59 = v169;
								}
								else
								{
									v3 += 32;
									v2 += 32;
								}
								v2 -= 800;
								world_4B3269[0] -= 4;
								--v59;
							}
							while ( v59 );
							return;
						}
						v54 = world_4B33FD[v53];
						v3 += *(int *)((char *)world_4B34BD + v54);
						v2 -= 192 * v54;
						v52 = 30 - (v54 >> 1);
					}
					do
					{
						v55 = &v2[v52];
						v56 = (unsigned int)(32 - v52) >> 2;
						if ( !__CFSHR__(32 - v52, 2) )
							goto LABEL_322;
						_AX = *((_WORD *)v3 + 1);
						v3 += 4;
						__asm { xlat }
						_AX = __ROR2__(_AX, 8);
						__asm { xlat }
						*v55 = __ROR2__(_AX, 8);
						++v55;
						if ( v56 )
						{
LABEL_322:
							do
							{
								_EAX = *(_DWORD *)v3;
								v3 += 4;
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								*(_DWORD *)v55 = __ROR4__(_EAX, 8);
								v55 += 2;
								--v56;
							}
							while ( v56 );
						}
						v2 = v55 - 400;
						v32 = __OFSUB__(v52, 2);
						v52 -= 2;
					}
					while ( !((v52 < 0) ^ v32) );
					goto LABEL_98;
				}
				v40 = 30;
				if ( (unsigned int)a1 >= screen_buf_end )
				{
					v41 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
					if ( v41 > 45 )
					{
						v2 = (char *)a1 - 12288;
						v3 += 288;
LABEL_80:
						v46 = 2;
						if ( (unsigned int)v2 >= screen_buf_end )
						{
							v47 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8;
							if ( v47 > 42 )
								return;
							v48 = world_4B33FD[v47];
							v3 += *(int *)((char *)world_4B3501 + v48);
							v2 -= 192 * v48;
							v46 = (v48 >> 1) + 2;
						}
						do
						{
							for ( n = (unsigned int)(32 - v46) >> 2; n; --n )
							{
								_EAX = *(_DWORD *)v3;
								v3 += 4;
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								*(_DWORD *)v2 = __ROR4__(_EAX, 8);
								v2 += 4;
							}
							if ( (32 - (_BYTE)v46) & 2 )
							{
								_AX = *(_WORD *)v3;
								v3 += 2;
								__asm { xlat }
								_AX = __ROR2__(_AX, 8);
								__asm { xlat }
								*(_WORD *)v2 = __ROR2__(_AX, 8);
								v2 += 2;
							}
							v2 = &v2[v46 - 800];
							v46 += 2;
						}
						while ( v46 != 32 );
						return;
					}
					v42 = world_4B33FD[v41];
					v3 += *(int *)((char *)world_4B34BD + v42);
					v2 -= 192 * v42;
					v40 = 30 - (v42 >> 1);
				}
				do
				{
					for ( ii = (unsigned int)(32 - v40) >> 2; ii; --ii )
					{
						_EAX = *(_DWORD *)v3;
						v3 += 4;
						__asm { xlat }
						_EAX = __ROR4__(_EAX, 8);
						__asm { xlat }
						_EAX = __ROR4__(_EAX, 8);
						__asm { xlat }
						_EAX = __ROR4__(_EAX, 8);
						__asm { xlat }
						*(_DWORD *)v2 = __ROR4__(_EAX, 8);
						v2 += 4;
					}
					if ( (32 - (_BYTE)v40) & 2 )
					{
						_AX = *(_WORD *)v3;
						v3 += 4;
						__asm { xlat }
						_AX = __ROR2__(_AX, 8);
						__asm { xlat }
						*(_WORD *)v2 = __ROR2__(_AX, 8);
						v2 += 2;
					}
					v2 = &v2[v40 - 800];
					v32 = __OFSUB__(v40, 2);
					v40 -= 2;
				}
				while ( !((v40 < 0) ^ v32) );
				goto LABEL_80;
			}
			v25 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v26 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v26 > 45 )
				{
					v2 = (char *)a1 - 12288;
					v3 += 288;
LABEL_62:
					v33 = 2;
					if ( (unsigned int)v2 >= screen_buf_end )
					{
						v34 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8;
						if ( v34 > 42 )
							return;
						v35 = world_4B33FD[v34];
						v3 += *(int *)((char *)world_4B3501 + v35);
						v2 -= 192 * v35;
						v33 = (v35 >> 1) + 2;
					}
					do
					{
						v36 = &v2[v33];
						v37 = (unsigned int)(32 - v33) >> 2;
						if ( !__CFSHR__(32 - v33, 2) )
							goto LABEL_323;
						_AX = *((_WORD *)v3 + 1);
						v3 += 4;
						__asm { xlat }
						_AX = __ROR2__(_AX, 8);
						__asm { xlat }
						*v36 = __ROR2__(_AX, 8);
						++v36;
						if ( v37 )
						{
LABEL_323:
							do
							{
								_EAX = *(_DWORD *)v3;
								v3 += 4;
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								_EAX = __ROR4__(_EAX, 8);
								__asm { xlat }
								*(_DWORD *)v36 = __ROR4__(_EAX, 8);
								v36 += 2;
								--v37;
							}
							while ( v37 );
						}
						v2 = v36 - 400;
						v33 += 2;
					}
					while ( v33 != 32 );
					return;
				}
				v27 = world_4B33FD[v26];
				v3 += *(int *)((char *)world_4B34BD + v27);
				v2 -= 192 * v27;
				v25 = 30 - (v27 >> 1);
			}
			do
			{
				v28 = &v2[v25];
				v29 = (unsigned int)(32 - v25) >> 2;
				if ( !__CFSHR__(32 - v25, 2) )
					goto LABEL_324;
				_AX = *((_WORD *)v3 + 1);
				v3 += 4;
				__asm { xlat }
				_AX = __ROR2__(_AX, 8);
				__asm { xlat }
				*v28 = __ROR2__(_AX, 8);
				++v28;
				if ( v29 )
				{
LABEL_324:
					do
					{
						_EAX = *(_DWORD *)v3;
						v3 += 4;
						__asm { xlat }
						_EAX = __ROR4__(_EAX, 8);
						__asm { xlat }
						_EAX = __ROR4__(_EAX, 8);
						__asm { xlat }
						_EAX = __ROR4__(_EAX, 8);
						__asm { xlat }
						*(_DWORD *)v28 = __ROR4__(_EAX, 8);
						v28 += 2;
						--v29;
					}
					while ( v29 );
				}
				v2 = v28 - 400;
				v32 = __OFSUB__(v25, 2);
				v25 -= 2;
			}
			while ( !((v25 < 0) ^ v32) );
			goto LABEL_62;*/
		}
		v6 = (char *)pSpeedCels + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265);
		v7 = (unsigned char)(BYTE1(level_cel_block) >> 4);
	}
	else
	{
		if ( level_cel_block & 0x8000 )
			level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
							+ (unsigned short)(level_cel_block & 0xF000);
		v6 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v8 = level_cel_block;
		_LOBYTE(v8) = BYTE1(v8);
		v7 = ((v8 >> 4) & 7) + 8;
	}
	switch ( v7 )
	{
		case 8:
			v75 = 32;
			do
			{
				if ( (unsigned int)v2 < screen_buf_end )
				{
					v170 = v75;
					v76 = *(_DWORD *)world_4B3269[0];
					v77 = 32;
					do
					{
						v78 = *v6++;
						v16 = __CFSHL__(v76, 1);
						v76 *= 2;
						if ( v16 )
							*v2 = v78;
						++v2;
						--v77;
					}
					while ( v77 );
					v75 = v170;
				}
				else
				{
					v6 += 32;
					v2 += 32;
				}
				v2 -= 800;
				world_4B3269[0] -= 4;
				--v75;
			}
			while ( v75 );
			return;
		case 9:
			v79 = 32;
			do
			{
				v171 = v79;
				*(_DWORD *)world_4B3260 = *(_DWORD *)world_4B3269[0];
				v80 = 32;
				do
				{
					while ( 1 )
					{
						v81 = (unsigned char)*v6++;
						if ( (v81 & 0x80u) != 0 )
							break;
						v80 -= v81;
						if ( (unsigned int)v2 < screen_buf_end )
						{
							v82 = v81;
							v165 = v80;
							v83 = *(_DWORD *)world_4B3260;
							do
							{
								v84 = *v6++;
								v16 = __CFSHL__(v83, 1);
								v83 *= 2;
								if ( v16 )
									*v2 = v84;
								++v2;
								--v82;
							}
							while ( v82 );
							*(_DWORD *)world_4B3260 = v83;
							v80 = v165;
						}
						else
						{
							v6 += v81;
							v2 += v81;
						}
						if ( !v80 )
							goto LABEL_152;
					}
					_LOBYTE(v81) = -(char)v81;
					v2 += v81;
					if ( v81 & 0x1F )
						*(_DWORD *)world_4B3260 <<= v81 & 0x1F;
					v80 -= v81;
				}
				while ( v80 );
LABEL_152:
				v2 -= 800;
				world_4B3269[0] -= 4;
				v79 = v171 - 1;
			}
			while ( v171 != 1 );
			return;
		case 10:
			v85 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v86 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v86 > 45 )
				{
					v2 = (unsigned char *)a1 - 12288;
					v6 += 288;
LABEL_162:
					v92 = 2;
					if ( (unsigned int)v2 >= screen_buf_end )
					{
						v93 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8;
						if ( v93 > 42 )
							return;
						v94 = world_4B33FD[v93];
						v6 += *(int *)((char *)world_4B3501 + v94);
						v2 -= 192 * v94;
						v92 = (v94 >> 1) + 2;
					}
					do
					{
						v95 = (unsigned int *)&v2[v92];
						v96 = (unsigned int)(32 - v92) >> 2;
						if ( !__CFSHR__(32 - v92, 2)
						  || (v97 = *((_WORD *)v6 + 1),
							  v6 += 4,
							  *(_WORD *)v95 = v97,
							  v95 = (_DWORD *)((char *)v95 + 2),
							  v96) )
						{
							do
							{
								v98 = *(_DWORD *)v6;
								v6 += 4;
								*v95 = v98;
								++v95;
								--v96;
							}
							while ( v96 );
						}
						v2 = (unsigned char *)v95 - 200;
						v92 += 2;
					}
					while ( v92 != 32 );
					return;
				}
				v87 = world_4B33FD[v86];
				v6 += *(int *)((char *)world_4B34BD + v87);
				v2 -= 192 * v87;
				v85 = 30 - (v87 >> 1);
			}
			do
			{
				v88 = (unsigned int *)&v2[v85];
				v89 = (unsigned int)(32 - v85) >> 2;
				if ( !__CFSHR__(32 - v85, 2)
				  || (v90 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v88 = v90, v88 = (_DWORD *)((char *)v88 + 2), v89) )
				{
					do
					{
						v91 = *(_DWORD *)v6;
						v6 += 4;
						*v88 = v91;
						++v88;
						--v89;
					}
					while ( v89 );
				}
				v2 = (unsigned char *)v88 - 200;
				v32 = __OFSUB__(v85, 2);
				v85 -= 2;
			}
			while ( !((v85 < 0) ^ v32) );
			goto LABEL_162;
	}
	if ( v7 != 11 )
	{
		if ( v7 != 12 )
		{
			v122 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v123 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v123 > 45 )
				{
					v2 = (unsigned char *)a1 - 12288;
					v6 += 288;
LABEL_217:
					world_4B3269[0] -= 64;
					v128 = 16;
					do
					{
						if ( (unsigned int)v2 < screen_buf_end )
						{
							v166 = v128;
							v129 = *(_DWORD *)world_4B3269[0];
							v130 = 32;
							do
							{
								v131 = *v6++;
								v16 = __CFSHL__(v129, 1);
								v129 *= 2;
								if ( v16 )
									*v2 = v131;
								++v2;
								--v130;
							}
							while ( v130 );
							v6 += (unsigned char)v6 & 2;
							v128 = v166;
						}
						else
						{
							v6 += 32;
							v2 += 32;
						}
						v2 -= 800;
						world_4B3269[0] -= 4;
						--v128;
					}
					while ( v128 );
					return;
				}
				v124 = world_4B33FD[v123];
				v6 += *(int *)((char *)world_4B34BD + v124);
				v2 -= 192 * v124;
				v122 = 30 - (v124 >> 1);
			}
			do
			{
				for ( jj = (unsigned int)(32 - v122) >> 2; jj; --jj )
				{
					v126 = *(_DWORD *)v6;
					v6 += 4;
					*(_DWORD *)v2 = v126;
					v2 += 4;
				}
				if ( (32 - (_BYTE)v122) & 2 )
				{
					v127 = *(_WORD *)v6;
					v6 += 4;
					*(_WORD *)v2 = v127;
					v2 += 2;
				}
				v2 = &v2[v122 - 800];
				v32 = __OFSUB__(v122, 2);
				v122 -= 2;
			}
			while ( !((v122 < 0) ^ v32) );
			goto LABEL_217;
		}
		v111 = 30;
		if ( (unsigned int)a1 >= screen_buf_end )
		{
			v112 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
			if ( v112 > 45 )
			{
				v2 = (unsigned char *)a1 - 12288;
				v6 += 288;
LABEL_198:
				world_4B3269[0] -= 64;
				v118 = 16;
				do
				{
					if ( (unsigned int)v2 < screen_buf_end )
					{
						v172 = v118;
						v119 = *(_DWORD *)world_4B3269[0];
						v120 = 32;
						do
						{
							v121 = *v6++;
							v16 = __CFSHL__(v119, 1);
							v119 *= 2;
							if ( v16 )
								*v2 = v121;
							++v2;
							--v120;
						}
						while ( v120 );
						v118 = v172;
					}
					else
					{
						v6 += 32;
						v2 += 32;
					}
					v2 -= 800;
					world_4B3269[0] -= 4;
					--v118;
				}
				while ( v118 );
				return;
			}
			v113 = world_4B33FD[v112];
			v6 += *(int *)((char *)world_4B34BD + v113);
			v2 -= 192 * v113;
			v111 = 30 - (v113 >> 1);
		}
		do
		{
			v114 = (unsigned int *)&v2[v111];
			v115 = (unsigned int)(32 - v111) >> 2;
			if ( !__CFSHR__(32 - v111, 2)
			  || (v116 = *((_WORD *)v6 + 1), v6 += 4, *(_WORD *)v114 = v116, v114 = (_DWORD *)((char *)v114 + 2), v115) )
			{
				do
				{
					v117 = *(_DWORD *)v6;
					v6 += 4;
					*v114 = v117;
					++v114;
					--v115;
				}
				while ( v115 );
			}
			v2 = (unsigned char *)v114 - 200;
			v32 = __OFSUB__(v111, 2);
			v111 -= 2;
		}
		while ( !((v111 < 0) ^ v32) );
		goto LABEL_198;
	}
	v99 = 30;
	if ( (unsigned int)a1 < screen_buf_end )
		goto LABEL_175;
	v100 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
	if ( v100 <= 45 )
	{
		v101 = world_4B33FD[v100];
		v6 += *(int *)((char *)world_4B34BD + v101);
		v2 -= 192 * v101;
		v99 = 30 - (v101 >> 1);
		do
		{
LABEL_175:
			for ( kk = (unsigned int)(32 - v99) >> 2; kk; --kk )
			{
				v103 = *(_DWORD *)v6;
				v6 += 4;
				*(_DWORD *)v2 = v103;
				v2 += 4;
			}
			if ( (32 - (_BYTE)v99) & 2 )
			{
				v104 = *(_WORD *)v6;
				v6 += 4;
				*(_WORD *)v2 = v104;
				v2 += 2;
			}
			v2 = &v2[v99 - 800];
			v32 = __OFSUB__(v99, 2);
			v99 -= 2;
		}
		while ( !((v99 < 0) ^ v32) );
		goto LABEL_180;
	}
	v2 = (unsigned char *)a1 - 12288;
	v6 += 288;
LABEL_180:
	v105 = 2;
	if ( (unsigned int)v2 >= screen_buf_end )
	{
		v106 = (unsigned int)&v2[-screen_buf_end + 1023] >> 8;
		if ( v106 > 42 )
			return;
		v107 = world_4B33FD[v106];
		v6 += *(int *)((char *)world_4B3501 + v107);
		v2 -= 192 * v107;
		v105 = (v107 >> 1) + 2;
	}
	do
	{
		for ( ll = (unsigned int)(32 - v105) >> 2; ll; --ll )
		{
			v109 = *(_DWORD *)v6;
			v6 += 4;
			*(_DWORD *)v2 = v109;
			v2 += 4;
		}
		if ( (32 - (_BYTE)v105) & 2 )
		{
			v110 = *(_WORD *)v6;
			v6 += 4;
			*(_WORD *)v2 = v110;
			v2 += 2;
		}
		v2 = &v2[v105 - 800];
		v105 += 2;
	}
	while ( v105 != 32 );
}
// 642A14: using guessed type char lightmax;
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF14: using guessed type int level_cel_block;

//----- (0046886B) --------------------------------------------------------
void __fastcall drawLowerScreen(void *a1)
{
	int v1; // edx
	char v2; // al
	char v3; // al
	char *v4; // edi
	_BYTE *v5; // esi
	int v6; // ebx
	short v7; // ax
	unsigned char *v8; // esi
	short v9; // ax
	char *v10; // esi
	unsigned int v11; // eax
	int v12; // eax
	int v13; // edx
	int v14; // edx
	signed int v15; // ebp
	int v16; // eax
	int v17; // ecx
	signed int v18; // ebp
	int v19; // eax
	char m; // cl
	int v21; // eax
	char v22; // ch
	char v23; // ch
	char v24; // ch
	int v25; // ebp
	signed int v26; // eax
	unsigned int v27; // ecx
	char *v28; // edi
	int v29; // ecx
	int v30; // edx
	unsigned char v31; // of
	int v32; // ebp
	signed int v33; // eax
	unsigned int v34; // ecx
	char *v35; // edi
	int v36; // ecx
	int v37; // edx
	int v38; // ebp
	signed int v39; // eax
	unsigned int v40; // ecx
	int v41; // ecx
	int v42; // ebp
	signed int v43; // eax
	unsigned int v44; // ecx
	int v45; // ecx
	int v46; // ebp
	signed int v47; // eax
	unsigned int v48; // ecx
	char *v49; // edi
	char v50; // cl
	int v51; // eax
	char v52; // ch
	char v53; // ch
	char v54; // ch
	signed int v55; // ebp
	char v56; // cl
	int v57; // eax
	char v58; // ch
	char v59; // ch
	char v60; // ch
	int v61; // ebp
	signed int v62; // eax
	unsigned int v63; // ecx
	char n; // cl
	int v65; // eax
	char v66; // ch
	char v67; // ch
	char v68; // ch
	signed int v69; // ebp
	char v70; // cl
	int v71; // eax
	char v72; // ch
	char v73; // ch
	char v74; // ch
	signed int v75; // edx
	signed int v76; // ecx
	int v77; // eax
	int v78; // ecx
	signed int v79; // edx
	unsigned int v80; // eax
	unsigned int v81; // ecx
	unsigned char v82; // al
	char v83; // cf
	unsigned int v84; // ecx
	short v85; // ax
	int v86; // eax
	int v87; // edx
	signed int v88; // eax
	unsigned int v89; // ecx
	char *v90; // edi
	unsigned int v91; // ecx
	short v92; // ax
	int v93; // eax
	int v94; // edx
	signed int v95; // eax
	unsigned int v96; // ecx
	char *v97; // edi
	unsigned int v98; // ecx
	short v99; // ax
	int v100; // eax
	int v101; // edx
	signed int v102; // eax
	unsigned int v103; // ecx
	unsigned int jj; // ecx
	int v105; // eax
	short v106; // ax
	int v107; // edx
	signed int v108; // eax
	unsigned int v109; // ecx
	unsigned int kk; // ecx
	int v111; // eax
	short v112; // ax
	int v113; // edi
	int v114; // edx
	signed int v115; // eax
	unsigned int v116; // ecx
	char *v117; // edi
	unsigned int v118; // ecx
	short v119; // ax
	int v120; // eax
	signed int v121; // edx
	signed int v122; // ecx
	int v123; // eax
	int v124; // edx
	signed int v125; // eax
	unsigned int v126; // ecx
	unsigned int ii; // ecx
	int v128; // eax
	short v129; // ax
	signed int v130; // edx
	signed int v131; // ecx
	int v132; // eax
	signed int v133; // edx
	signed int v134; // ecx
	int v135; // ecx
	signed int v136; // edx
	unsigned int v137; // eax
	unsigned int v138; // ecx
	unsigned int v139; // ecx
	signed int i; // edx
	char *v141; // edi
	unsigned int v142; // ecx
	signed int v143; // edx
	char *v144; // edi
	unsigned int v145; // ecx
	signed int j; // edx
	unsigned int v147; // ecx
	char *v148; // edi
	signed int v149; // edx
	unsigned int v150; // ecx
	signed int k; // edx
	char *v152; // edi
	unsigned int v153; // ecx
	signed int v154; // edx
	signed int v155; // ecx
	signed int l; // edx
	unsigned int v157; // ecx
	char *v158; // edi
	signed int v159; // edx
	signed int v160; // ecx
	int v161; // [esp-14h] [ebp-18h]
	int v162; // [esp-14h] [ebp-18h]
	int v163; // [esp-10h] [ebp-14h]
	int v164; // [esp-10h] [ebp-14h]

	v1 = cel_transparency_active;
	if ( cel_transparency_active )
	{
		if ( !arch_draw_type )
		{
			drawTopArchesLowerScreen(a1);
			return;
		}
		if ( arch_draw_type == 1 )
		{
			v2 = block_lvid[level_piece_id];
			if ( v2 == 1 || v2 == 3 )
			{
				drawBottomArchesLowerScreen(a1, (int)&tile_draw_masks[63]);
				return;
			}
		}
		if ( arch_draw_type == 2 )
		{
			v3 = block_lvid[level_piece_id];
			if ( v3 == 2 || v3 == 3 )
			{
				drawBottomArchesLowerScreen(a1, (int)&tile_draw_masks[31]);
				return;
			}
		}
	}
	world_4B3265 = (int)speed_cel_frame_num_from_light_index_frame_num;
	v4 = (char *)a1;
	if ( (_BYTE)light_table_index )
	{
		if ( (_BYTE)light_table_index == lightmax )
		{
			if ( level_cel_block & 0x8000 )
				level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
								+ (unsigned short)(level_cel_block & 0xF000);
			v10 = (char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
			v11 = level_cel_block;
			_LOBYTE(v11) = BYTE1(v11);
			v12 = (v11 >> 4) & 7;
			if ( v12 )
			{
				switch ( (_WORD)v12 )
				{
					case 1:
						v135 = 32;
						do
						{
							v164 = v135;
							v136 = 32;
							do
							{
								while ( 1 )
								{
									v137 = (unsigned char)*v10++;
									if ( (v137 & 0x80u) == 0 )
										break;
									_LOBYTE(v137) = -(char)v137;
									v4 += v137;
									v136 -= v137;
									if ( !v136 )
										goto LABEL_232;
								}
								v136 -= v137;
								if ( (unsigned int)v4 < screen_buf_end )
								{
									v10 += v137;
									v138 = v137 >> 1;
									if ( !(v137 & 1) || (*v4 = 0, ++v4, v138) )
									{
										v83 = v138 & 1;
										v139 = v137 >> 2;
										if ( !v83 || (*(_WORD *)v4 = 0, v4 += 2, v139) )
										{
											do
											{
												*(_DWORD *)v4 = 0;
												v4 += 4;
												--v139;
											}
											while ( v139 );
										}
									}
								}
								else
								{
									v10 += v137;
									v4 += v137;
								}
							}
							while ( v136 );
LABEL_232:
							v4 -= 800;
							v135 = v164 - 1;
						}
						while ( v164 != 1 );
						break;
					case 2:
						for ( i = 30; ; i -= 2 )
						{
							if ( (unsigned int)v4 < screen_buf_end )
							{
								v141 = &v4[i];
								v142 = (unsigned int)(32 - i) >> 2;
								if ( !__CFSHR__(32 - i, 2) || (*(_WORD *)v141 = 0, v141 += 2, v142) )
								{
									do
									{
										*(_DWORD *)v141 = 0;
										v141 += 4;
										--v142;
									}
									while ( v142 );
								}
							}
							else
							{
								v10 = &v10[-i + 32];
								v141 = v4 + 32;
							}
							v4 = v141 - 800;
							if ( !i )
								break;
						}
						v143 = 2;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
							{
								v144 = &v4[v143];
								v145 = (unsigned int)(32 - v143) >> 2;
								if ( !__CFSHR__(32 - v143, 2) || (*(_WORD *)v144 = 0, v144 += 2, v145) )
								{
									do
									{
										*(_DWORD *)v144 = 0;
										v144 += 4;
										--v145;
									}
									while ( v145 );
								}
							}
							else
							{
								v10 = &v10[-v143 + 32];
								v144 = v4 + 32;
							}
							v4 = v144 - 800;
							v143 += 2;
						}
						while ( v143 != 32 );
						break;
					case 3:
						for ( j = 30; ; j -= 2 )
						{
							if ( (unsigned int)v4 < screen_buf_end )
							{
								v147 = (unsigned int)(32 - j) >> 2;
								if ( !__CFSHR__(32 - j, 2) || (*(_WORD *)v4 = 0, v4 += 2, v147) )
								{
									do
									{
										*(_DWORD *)v4 = 0;
										v4 += 4;
										--v147;
									}
									while ( v147 );
								}
							}
							else
							{
								v10 = &v10[-j + 32];
								v4 = &v4[-j + 32];
							}
							v148 = v4 - 800;
							if ( !j )
								break;
							v4 = &v148[j];
						}
						v149 = 2;
						do
						{
							if ( (unsigned int)v148 < screen_buf_end )
							{
								v150 = (unsigned int)(32 - v149) >> 2;
								if ( !__CFSHR__(32 - v149, 2) || (*(_WORD *)v148 = 0, v148 += 2, v150) )
								{
									do
									{
										*(_DWORD *)v148 = 0;
										v148 += 4;
										--v150;
									}
									while ( v150 );
								}
							}
							else
							{
								v10 = &v10[-v149 + 32];
								v148 = &v148[-v149 + 32];
							}
							v148 = &v148[v149 - 800];
							v149 += 2;
						}
						while ( v149 != 32 );
						break;
					case 4:
						for ( k = 30; ; k -= 2 )
						{
							if ( (unsigned int)v4 < screen_buf_end )
							{
								v152 = &v4[k];
								v153 = (unsigned int)(32 - k) >> 2;
								if ( !__CFSHR__(32 - k, 2) || (*(_WORD *)v152 = 0, v152 += 2, v153) )
								{
									do
									{
										*(_DWORD *)v152 = 0;
										v152 += 4;
										--v153;
									}
									while ( v153 );
								}
							}
							else
							{
								v10 = &v10[-k + 32];
								v152 = v4 + 32;
							}
							v4 = v152 - 800;
							if ( !k )
								break;
						}
						v154 = 16;
						do
						{
							if ( (unsigned int)v4 < screen_buf_end )
							{
								v155 = 8;
								do
								{
									*(_DWORD *)v4 = 0;
									v4 += 4;
									--v155;
								}
								while ( v155 );
							}
							else
							{
								v10 += 32;
								v4 += 32;
							}
							v4 -= 800;
							--v154;
						}
						while ( v154 );
						break;
					default:
						for ( l = 30; ; l -= 2 )
						{
							if ( (unsigned int)v4 < screen_buf_end )
							{
								v157 = (unsigned int)(32 - l) >> 2;
								if ( !__CFSHR__(32 - l, 2) || (*(_WORD *)v4 = 0, v4 += 2, v157) )
								{
									do
									{
										*(_DWORD *)v4 = 0;
										v4 += 4;
										--v157;
									}
									while ( v157 );
								}
							}
							else
							{
								v10 = &v10[-l + 32];
								v4 = &v4[-l + 32];
							}
							v158 = v4 - 800;
							if ( !l )
								break;
							v4 = &v158[l];
						}
						v159 = 16;
						do
						{
							if ( (unsigned int)v158 < screen_buf_end )
							{
								v160 = 8;
								do
								{
									*(_DWORD *)v158 = 0;
									v158 += 4;
									--v160;
								}
								while ( v160 );
							}
							else
							{
								v10 += 32;
								v158 += 32;
							}
							v158 -= 800;
							--v159;
						}
						while ( v159 );
						break;
				}
			}
			else
			{
				v133 = 32;
				do
				{
					if ( (unsigned int)v4 < screen_buf_end )
					{
						v134 = 8;
						do
						{
							*(_DWORD *)v4 = 0;
							v4 += 4;
							--v134;
						}
						while ( v134 );
					}
					else
					{
						v10 += 32;
						v4 += 32;
					}
					v4 -= 800;
					--v133;
				}
				while ( v133 );
			}
			return;
		}
		if ( !(level_cel_block & 0x8000) )
		{
			v5 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
			v6 = dword_646A20 + (light_table_index << 8);
			v7 = (unsigned short)level_cel_block >> 12;
			if ( !((unsigned short)level_cel_block >> 12) )
			{
				v13 = 32;
				do
				{
					v161 = v13;
					if ( (unsigned int)v4 < screen_buf_end )
					{
						v14 = 0;
						v15 = 8;
						do
						{
							v16 = *(_DWORD *)v5;
							v5 += 4;
							v16 = __ROR4__(v16, 16);
							_LOBYTE(v14) = v16;
							_LOBYTE(a1) = *(_BYTE *)(v6 + v14);
							_LOBYTE(v14) = BYTE1(v16);
							BYTE1(a1) = *(_BYTE *)(v6 + v14);
							v16 = __ROR4__(v16, 16);
							a1 = (void *)((_DWORD)a1 << 16);
							_LOBYTE(v14) = v16;
							_LOBYTE(a1) = *(_BYTE *)(v6 + v14);
							_LOBYTE(v14) = BYTE1(v16);
							BYTE1(a1) = *(_BYTE *)(v6 + v14);
							*(_DWORD *)v4 = (unsigned int)a1;
							v4 += 4;
							--v15;
						}
						while ( v15 );
					}
					else
					{
						v5 += 32;
						v4 += 32;
					}
					v4 -= 800;
					v13 = v161 - 1;
				}
				while ( v161 != 1 );
				return;
			}
			if ( v7 == 1 )
			{
				v17 = 32;
				do
				{
					v162 = v17;
					v18 = 32;
					do
					{
						v19 = (unsigned char)*v5++;
						if ( (v19 & 0x80u) == 0 )
						{
							v18 -= v19;
							if ( (unsigned int)v4 < screen_buf_end )
							{
								for ( m = v19; m >= 4; m -= 4 )
								{
									v21 = *(_DWORD *)v5;
									v5 += 4;
									_LOBYTE(v1) = v21;
									v22 = *(_BYTE *)(v6 + v1);
									_LOBYTE(v1) = BYTE1(v21);
									v21 = __ROR4__(v21, 16);
									*v4 = v22;
									v23 = *(_BYTE *)(v6 + v1);
									_LOBYTE(v1) = v21;
									v4[1] = v23;
									v24 = *(_BYTE *)(v6 + v1);
									_LOBYTE(v1) = BYTE1(v21);
									v4[2] = v24;
									v4[3] = *(_BYTE *)(v6 + v1);
									v4 += 4;
								}
								if ( m >= 2 )
								{
									_LOBYTE(v1) = *v5;
									*v4 = *(_BYTE *)(v6 + v1);
									_LOBYTE(v1) = v5[1];
									v4[1] = *(_BYTE *)(v6 + v1);
									v5 += 2;
									v4 += 2;
								}
								if ( m & 1 )
								{
									_LOBYTE(v1) = *v5++;
									*v4++ = *(_BYTE *)(v6 + v1);
								}
							}
							else
							{
								v5 += v19;
								v4 += v19;
							}
						}
						else
						{
							_LOBYTE(v19) = -(char)v19;
							v4 += v19;
							v18 -= v19;
						}
					}
					while ( v18 );
					v4 -= 800;
					v17 = v162 - 1;
				}
				while ( v162 != 1 );
				return;
			}
			if ( v7 != 2 )
			{
				if ( v7 != 3 )
				{
					if ( v7 != 4 )
					{
						v61 = 30;
						if ( (unsigned int)a1 >= screen_buf_end )
						{
							v62 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
							if ( v62 > 45 )
							{
								v4 = (char *)a1 - 12288;
								v5 += 288;
LABEL_116:
								v69 = 16;
								do
								{
									if ( (unsigned int)v4 < screen_buf_end )
									{
										v70 = 32;
										do
										{
											v71 = *(_DWORD *)v5;
											v5 += 4;
											_LOBYTE(v1) = v71;
											v72 = *(_BYTE *)(v6 + v1);
											_LOBYTE(v1) = BYTE1(v71);
											v71 = __ROR4__(v71, 16);
											*v4 = v72;
											v73 = *(_BYTE *)(v6 + v1);
											_LOBYTE(v1) = v71;
											v4[1] = v73;
											v74 = *(_BYTE *)(v6 + v1);
											_LOBYTE(v1) = BYTE1(v71);
											v4[2] = v74;
											v4[3] = *(_BYTE *)(v6 + v1);
											v4 += 4;
											v70 -= 4;
										}
										while ( v70 >= 4 );
									}
									else
									{
										v5 += 32;
										v4 += 32;
									}
									v4 -= 800;
									--v69;
								}
								while ( v69 );
								return;
							}
							v63 = world_4B33FD[v62];
							v5 += *(int *)((char *)world_4B34BD + v63);
							v4 -= 192 * v63;
							v61 = 30 - (v63 >> 1);
						}
						do
						{
							for ( n = 32 - v61; n >= 4; n -= 4 )
							{
								v65 = *(_DWORD *)v5;
								v5 += 4;
								_LOBYTE(v1) = v65;
								v66 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v65);
								v65 = __ROR4__(v65, 16);
								*v4 = v66;
								v67 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = v65;
								v4[1] = v67;
								v68 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v65);
								v4[2] = v68;
								v4[3] = *(_BYTE *)(v6 + v1);
								v4 += 4;
							}
							if ( n >= 2 )
							{
								_LOBYTE(v1) = *v5;
								*v4 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = v5[1];
								v4[1] = *(_BYTE *)(v6 + v1);
								v5 += 2;
								v4 += 2;
							}
							v1 = (unsigned char)v5 & 2;
							v5 += v1;
							v4 = &v4[v61 - 800];
							v31 = __OFSUB__(v61, 2);
							v61 -= 2;
						}
						while ( !((v61 < 0) ^ v31) );
						goto LABEL_116;
					}
					v46 = 30;
					if ( (unsigned int)a1 >= screen_buf_end )
					{
						v47 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
						if ( v47 > 45 )
						{
							v4 = (char *)a1 - 12288;
							v5 += 288;
LABEL_100:
							v55 = 16;
							do
							{
								if ( (unsigned int)v4 < screen_buf_end )
								{
									v56 = 32;
									do
									{
										v57 = *(_DWORD *)v5;
										v5 += 4;
										_LOBYTE(v1) = v57;
										v58 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = BYTE1(v57);
										v57 = __ROR4__(v57, 16);
										*v4 = v58;
										v59 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = v57;
										v4[1] = v59;
										v60 = *(_BYTE *)(v6 + v1);
										_LOBYTE(v1) = BYTE1(v57);
										v4[2] = v60;
										v4[3] = *(_BYTE *)(v6 + v1);
										v4 += 4;
										v56 -= 4;
									}
									while ( v56 >= 4 );
								}
								else
								{
									v5 += 32;
									v4 += 32;
								}
								v4 -= 800;
								--v55;
							}
							while ( v55 );
							return;
						}
						v48 = world_4B33FD[v47];
						v5 += *(int *)((char *)world_4B34BD + v48);
						v4 -= 192 * v48;
						v46 = 30 - (v48 >> 1);
					}
					do
					{
						v49 = &v4[v46];
						v50 = 32 - v46;
						v1 = (32 - (_BYTE)v46) & 2;
						v5 += v1;
						if ( (char)(32 - v46) >= 4 )
						{
							do
							{
								v51 = *(_DWORD *)v5;
								v5 += 4;
								_LOBYTE(v1) = v51;
								v52 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v51);
								v51 = __ROR4__(v51, 16);
								*v49 = v52;
								v53 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = v51;
								v49[1] = v53;
								v54 = *(_BYTE *)(v6 + v1);
								_LOBYTE(v1) = BYTE1(v51);
								v49[2] = v54;
								v49[3] = *(_BYTE *)(v6 + v1);
								v49 += 4;
								v50 -= 4;
							}
							while ( v50 >= 4 );
						}
						if ( v50 >= 2 )
						{
							_LOBYTE(v1) = *v5;
							*v49 = *(_BYTE *)(v6 + v1);
							_LOBYTE(v1) = v5[1];
							v49[1] = *(_BYTE *)(v6 + v1);
							v5 += 2;
							v49 += 2;
						}
						v4 = v49 - 800;
						v31 = __OFSUB__(v46, 2);
						v46 -= 2;
					}
					while ( !((v46 < 0) ^ v31) );
					goto LABEL_100;
				}
				v38 = 30;
				if ( (unsigned int)a1 >= screen_buf_end )
				{
					v39 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
					if ( v39 > 45 )
					{
						v4 = (char *)a1 - 12288;
						v5 += 288;
LABEL_83:
						v42 = 2;
						if ( (unsigned int)v4 >= screen_buf_end )
						{
							v43 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8;
							if ( v43 > 42 )
								return;
							v44 = world_4B33FD[v43];
							v5 += *(int *)((char *)world_4B3501 + v44);
							v4 -= 192 * v44;
							v42 = (v44 >> 1) + 2;
						}
						do
						{
							v45 = 32 - v42;
							do
							{
								_LOBYTE(v1) = *v5++;
								*v4++ = *(_BYTE *)(v6 + v1);
								--v45;
							}
							while ( v45 );
							v1 = (unsigned char)v5 & 2;
							v5 += v1;
							v4 = &v4[v42 - 800];
							v42 += 2;
						}
						while ( v42 != 32 );
						return;
					}
					v40 = world_4B33FD[v39];
					v5 += *(int *)((char *)world_4B34BD + v40);
					v4 -= 192 * v40;
					v38 = 30 - (v40 >> 1);
				}
				do
				{
					v41 = 32 - v38;
					do
					{
						_LOBYTE(v1) = *v5++;
						*v4++ = *(_BYTE *)(v6 + v1);
						--v41;
					}
					while ( v41 );
					v1 = (unsigned char)v5 & 2;
					v5 += v1;
					v4 = &v4[v38 - 800];
					v31 = __OFSUB__(v38, 2);
					v38 -= 2;
				}
				while ( !((v38 < 0) ^ v31) );
				goto LABEL_83;
			}
			v25 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v26 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v26 > 45 )
				{
					v4 = (char *)a1 - 12288;
					v5 += 288;
LABEL_68:
					v32 = 2;
					if ( (unsigned int)v4 >= screen_buf_end )
					{
						v33 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8;
						if ( v33 > 42 )
							return;
						v34 = world_4B33FD[v33];
						v5 += *(int *)((char *)world_4B3501 + v34);
						v4 -= 192 * v34;
						v32 = (v34 >> 1) + 2;
					}
					do
					{
						v35 = &v4[v32];
						v36 = 32 - v32;
						v37 = (32 - (_BYTE)v32) & 2;
						v5 += v37;
						do
						{
							_LOBYTE(v37) = *v5++;
							*v35++ = *(_BYTE *)(v6 + v37);
							--v36;
						}
						while ( v36 );
						v32 += 2;
						v4 = v35 - 800;
					}
					while ( v32 != 32 );
					return;
				}
				v27 = world_4B33FD[v26];
				v5 += *(int *)((char *)world_4B34BD + v27);
				v4 -= 192 * v27;
				v25 = 30 - (v27 >> 1);
			}
			do
			{
				v28 = &v4[v25];
				v29 = 32 - v25;
				v30 = (32 - (_BYTE)v25) & 2;
				v5 += v30;
				do
				{
					_LOBYTE(v30) = *v5++;
					*v28++ = *(_BYTE *)(v6 + v30);
					--v29;
				}
				while ( v29 );
				v4 = v28 - 800;
				v31 = __OFSUB__(v25, 2);
				v25 -= 2;
			}
			while ( !((v25 < 0) ^ v31) );
			goto LABEL_68;
		}
		v8 = (unsigned char *)pSpeedCels
		   + *(_DWORD *)(4 * (light_table_index + 16 * (level_cel_block & 0xFFF)) + world_4B3265);
		v9 = (unsigned short)level_cel_block >> 12;
	}
	else
	{
		if ( level_cel_block & 0x8000 )
			level_cel_block = *(_DWORD *)(((level_cel_block & 0xFFF) << 6) + world_4B3265)
							+ (unsigned short)(level_cel_block & 0xF000);
		v8 = (unsigned char *)pDungeonCels + *((_DWORD *)pDungeonCels + (level_cel_block & 0xFFF));
		v9 = (((unsigned int)level_cel_block >> 12) & 7) + 8;
	}
	switch ( v9 )
	{
		case 8:
			v75 = 32;
			do
			{
				if ( (unsigned int)v4 < screen_buf_end )
				{
					v76 = 8;
					do
					{
						v77 = *(_DWORD *)v8;
						v8 += 4;
						*(_DWORD *)v4 = v77;
						v4 += 4;
						--v76;
					}
					while ( v76 );
				}
				else
				{
					v8 += 32;
					v4 += 32;
				}
				v4 -= 800;
				--v75;
			}
			while ( v75 );
			return;
		case 9:
			v78 = 32;
			do
			{
				v163 = v78;
				v79 = 32;
				do
				{
					while ( 1 )
					{
						v80 = *v8++;
						if ( (v80 & 0x80u) == 0 )
							break;
						_LOBYTE(v80) = -(char)v80;
						v4 += v80;
						v79 -= v80;
						if ( !v79 )
							goto LABEL_143;
					}
					v79 -= v80;
					if ( (unsigned int)v4 < screen_buf_end )
					{
						v81 = v80 >> 1;
						if ( !(v80 & 1) || (v82 = *v8, ++v8, *v4 = v82, ++v4, v81) )
						{
							v83 = v81 & 1;
							v84 = v81 >> 1;
							if ( !v83 || (v85 = *(_WORD *)v8, v8 += 2, *(_WORD *)v4 = v85, v4 += 2, v84) )
							{
								do
								{
									v86 = *(_DWORD *)v8;
									v8 += 4;
									*(_DWORD *)v4 = v86;
									v4 += 4;
									--v84;
								}
								while ( v84 );
							}
						}
					}
					else
					{
						v8 += v80;
						v4 += v80;
					}
				}
				while ( v79 );
LABEL_143:
				v4 -= 800;
				v78 = v163 - 1;
			}
			while ( v163 != 1 );
			return;
		case 10:
			v87 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v88 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v88 > 45 )
				{
					v4 = (char *)a1 - 12288;
					v8 += 288;
LABEL_153:
					v94 = 2;
					if ( (unsigned int)v4 >= screen_buf_end )
					{
						v95 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8;
						if ( v95 > 42 )
							return;
						v96 = world_4B33FD[v95];
						v8 += *(int *)((char *)world_4B3501 + v96);
						v4 -= 192 * v96;
						v94 = (v96 >> 1) + 2;
					}
					do
					{
						v97 = &v4[v94];
						v98 = (unsigned int)(32 - v94) >> 2;
						if ( !__CFSHR__(32 - v94, 2)
						  || (v99 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v97 = v99, v97 += 2, v98) )
						{
							do
							{
								v100 = *(_DWORD *)v8;
								v8 += 4;
								*(_DWORD *)v97 = v100;
								v97 += 4;
								--v98;
							}
							while ( v98 );
						}
						v94 += 2;
						v4 = v97 - 800;
					}
					while ( v94 < 32 );
					return;
				}
				v89 = world_4B33FD[v88];
				v8 += *(int *)((char *)world_4B34BD + v89);
				v4 -= 192 * v89;
				v87 = 30 - (v89 >> 1);
			}
			do
			{
				v90 = &v4[v87];
				v91 = (unsigned int)(32 - v87) >> 2;
				if ( !__CFSHR__(32 - v87, 2) || (v92 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v90 = v92, v90 += 2, v91) )
				{
					do
					{
						v93 = *(_DWORD *)v8;
						v8 += 4;
						*(_DWORD *)v90 = v93;
						v90 += 4;
						--v91;
					}
					while ( v91 );
				}
				v4 = v90 - 800;
				v31 = __OFSUB__(v87, 2);
				v87 -= 2;
			}
			while ( !((v87 < 0) ^ v31) );
			goto LABEL_153;
	}
	if ( v9 != 11 )
	{
		if ( v9 != 12 )
		{
			v124 = 30;
			if ( (unsigned int)a1 >= screen_buf_end )
			{
				v125 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
				if ( v125 > 45 )
				{
					v4 = (char *)a1 - 12288;
					v8 += 288;
LABEL_205:
					v130 = 16;
					do
					{
						if ( (unsigned int)v4 < screen_buf_end )
						{
							v131 = 8;
							do
							{
								v132 = *(_DWORD *)v8;
								v8 += 4;
								*(_DWORD *)v4 = v132;
								v4 += 4;
								--v131;
							}
							while ( v131 );
						}
						else
						{
							v8 += 32;
							v4 += 32;
						}
						v4 -= 800;
						--v130;
					}
					while ( v130 );
					return;
				}
				v126 = world_4B33FD[v125];
				v8 += *(int *)((char *)world_4B34BD + v126);
				v4 -= 192 * v126;
				v124 = 30 - (v126 >> 1);
			}
			do
			{
				for ( ii = (unsigned int)(32 - v124) >> 2; ii; --ii )
				{
					v128 = *(_DWORD *)v8;
					v8 += 4;
					*(_DWORD *)v4 = v128;
					v4 += 4;
				}
				if ( (32 - (_BYTE)v124) & 2 )
				{
					v129 = *(_WORD *)v8;
					v8 += 4;
					*(_WORD *)v4 = v129;
					v4 += 2;
				}
				v4 = &v4[v124 - 800];
				v31 = __OFSUB__(v124, 2);
				v124 -= 2;
			}
			while ( !((v124 < 0) ^ v31) );
			goto LABEL_205;
		}
		v114 = 30;
		if ( (unsigned int)a1 >= screen_buf_end )
		{
			v115 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
			if ( v115 > 45 )
			{
				v4 = (char *)a1 - 12288;
				v8 += 288;
LABEL_189:
				v121 = 16;
				do
				{
					if ( (unsigned int)v4 < screen_buf_end )
					{
						v122 = 8;
						do
						{
							v123 = *(_DWORD *)v8;
							v8 += 4;
							*(_DWORD *)v4 = v123;
							v4 += 4;
							--v122;
						}
						while ( v122 );
					}
					else
					{
						v8 += 32;
						v4 += 32;
					}
					v4 -= 800;
					--v121;
				}
				while ( v121 );
				return;
			}
			v116 = world_4B33FD[v115];
			v8 += *(int *)((char *)world_4B34BD + v116);
			v4 -= 192 * v116;
			v114 = 30 - (v116 >> 1);
		}
		do
		{
			v117 = &v4[v114];
			v118 = (unsigned int)(32 - v114) >> 2;
			if ( !__CFSHR__(32 - v114, 2)
			  || (v119 = *((_WORD *)v8 + 1), v8 += 4, *(_WORD *)v117 = v119, v117 += 2, v118) )
			{
				do
				{
					v120 = *(_DWORD *)v8;
					v8 += 4;
					*(_DWORD *)v117 = v120;
					v117 += 4;
					--v118;
				}
				while ( v118 );
			}
			v4 = v117 - 800;
			v31 = __OFSUB__(v114, 2);
			v114 -= 2;
		}
		while ( !((v114 < 0) ^ v31) );
		goto LABEL_189;
	}
	v101 = 30;
	if ( (unsigned int)a1 < screen_buf_end )
		goto LABEL_166;
	v102 = (unsigned int)((char *)a1 - screen_buf_end + 1023) >> 8;
	if ( v102 <= 45 )
	{
		v103 = world_4B33FD[v102];
		v8 += *(int *)((char *)world_4B34BD + v103);
		v4 -= 192 * v103;
		v101 = 30 - (v103 >> 1);
		do
		{
LABEL_166:
			for ( jj = (unsigned int)(32 - v101) >> 2; jj; --jj )
			{
				v105 = *(_DWORD *)v8;
				v8 += 4;
				*(_DWORD *)v4 = v105;
				v4 += 4;
			}
			if ( (32 - (_BYTE)v101) & 2 )
			{
				v106 = *(_WORD *)v8;
				v8 += 4;
				*(_WORD *)v4 = v106;
				v4 += 2;
			}
			v4 = &v4[v101 - 800];
			v31 = __OFSUB__(v101, 2);
			v101 -= 2;
		}
		while ( !((v101 < 0) ^ v31) );
		goto LABEL_171;
	}
	v4 = (char *)a1 - 12288;
	v8 += 288;
LABEL_171:
	v107 = 2;
	if ( (unsigned int)v4 >= screen_buf_end )
	{
		v108 = (unsigned int)&v4[-screen_buf_end + 1023] >> 8;
		if ( v108 > 42 )
			return;
		v109 = world_4B33FD[v108];
		v8 += *(int *)((char *)world_4B3501 + v109);
		v4 -= 192 * v109;
		v107 = (v109 >> 1) + 2;
	}
	do
	{
		for ( kk = (unsigned int)(32 - v107) >> 2; kk; --kk )
		{
			v111 = *(_DWORD *)v8;
			v8 += 4;
			*(_DWORD *)v4 = v111;
			v4 += 4;
		}
		if ( (32 - (_BYTE)v107) & 2 )
		{
			v112 = *(_WORD *)v8;
			v8 += 4;
			*(_WORD *)v4 = v112;
			v4 += 2;
		}
		v113 = (int)&v4[v107];
		v107 += 2;
		v4 = (char *)(v113 - 800);
	}
	while ( v107 < 32 );
}
// 642A14: using guessed type char lightmax;
// 69BEF8: using guessed type int light_table_index;
// 69CF0C: using guessed type int screen_buf_end;
// 69CF14: using guessed type int level_cel_block;
// 69CF20: using guessed type char arch_draw_type;
// 69CF94: using guessed type int cel_transparency_active;
// 69CF98: using guessed type int level_piece_id;

//----- (004696BE) --------------------------------------------------------
void __fastcall world_levelrelated(char *a1)
{
	char *v1; // edi
	signed int v2; // edx
	signed int i; // ebx
	char *v4; // edi
	signed int v5; // ecx
	signed int v6; // edx
	signed int v7; // ebx
	char *v8; // edi
	signed int v9; // ecx

	v1 = a1;
	v2 = 30;
	for ( i = 1; ; ++i )
	{
		v4 = &v1[v2];
		v5 = i;
		do
		{
			*(_DWORD *)v4 = 0;
			v4 += 4;
			--v5;
		}
		while ( v5 );
		v1 = &v4[v2 - 832];
		if ( !v2 )
			break;
		v2 -= 2;
	}
	v6 = 2;
	v7 = 15;
	do
	{
		v8 = &v1[v6];
		v9 = v7;
		do
		{
			*(_DWORD *)v8 = 0;
			v8 += 4;
			--v9;
		}
		while ( v9 );
		v1 = &v8[v6 - 832];
		--v7;
		v6 += 2;
	}
	while ( v6 != 32 );
}

// ALL OK, 1917 function(s) have been successfully decompiled
