view UiGame.cpp @ 1111:044d65e41250

Merge
author Grumpy7
date Mon, 27 May 2013 23:07:13 +0200
parents 4339bb88c4f5
children 29a8defbad9e
line wrap: on
line source

#include <assert.h>

#include "MM7.h"

#include "BSPModel.h"
#include "LightmapBuilder.h"
#include "DecalBuilder.h"
#include "ParticleEngine.h"
#include "Mouse.h"
#include "Keyboard.h"
#include "IndoorCameraD3D.h"
#include "CShow.h"
#include "GammaControl.h"
#include "stru6.h"
#include "stru9.h"
#include "stru10.h"
#include "stru11.h"
#include "stru12.h"

#include "Vis.h"
#include "MapInfo.h"
#include "Game.h"
#include "GUIWindow.h"
#include "GUIFont.h"
#include "GUIProgressBar.h"
#include "Party.h"
#include "AudioPlayer.h"
#include "Outdoor.h"
#include "IndoorCamera.h"
#include "Overlays.h"
#include "Monsters.h"
#include "Arcomage.h"
#include "LOD.h"
#include "Actor.h"
#include "Allocator.h"
#include "Events.h"
#include "Viewport.h"
#include "FrameTableInc.h"
#include "Math.h"
#include "SpriteObject.h"
#include "ObjectList.h"
#include "Chest.h"
#include "PaletteManager.h"
#include "DecorationList.h"
#include "PlayerFrameTable.h"
#include "SaveLoad.h"
#include "stru123.h"
#include "Time.h"
#include "IconFrameTable.h"
#include "Awards.h"
#include "Autonotes.h"
#include "stru160.h"
#include "TurnEngine.h"
#include "CastSpellInfo.h"
#include "Weather.h"
#include "stru298.h"
#include "StorylineTextTable.h"
#include "Events2D.h"
#include "texts.h"
#include "UIHouses.h"

#include "mm7_data.h"




int uTextureID_GameUI_CharSelectionFrame; // 50C98C





//----- (00421D00) --------------------------------------------------------
void __fastcall GameUI_OnPlayerPortraitLeftClick(unsigned int uPlayerID)
{
  //unsigned int v1; // esi@1
  //int v2; // eax@2
  //Player *v3; // ecx@2
  //Player *v4; // ecx@5
  unsigned int v5; // [sp-4h] [bp-10h]@21

  //v1 = uPlayerID;
  auto player = &pParty->pPlayers[uPlayerID - 1];
  if (pParty->pPickedItem.uItemID)
  {
    //v3 = player;
    if (auto slot = player->AddItem(-1, pParty->pPickedItem.uItemID))
    {
      memcpy(&player->pInventoryItems[slot-1], &pParty->pPickedItem, 0x24u);
      viewparams->bRedrawGameUI = true;
      pMouse->RemoveHoldingItem();
      return;
    }

    if (!player->CanAct())
    {
      player = pPlayers[uActiveCharacter];
    }
    if(player->CanAct() || !pPlayers[uActiveCharacter]->CanAct())
		player->PlaySound(SPEECH_NoRoom, 0);
  }

//LABEL_9:
  if (pCurrentScreen == SCREEN_GAME)
  {
    viewparams->bRedrawGameUI = true;
    if ( uActiveCharacter != uPlayerID )
      //goto LABEL_27;
    {
      if ( pPlayers[uPlayerID]->uTimeToRecovery )
        return;

      uActiveCharacter = uPlayerID;
      return;
    }
    v5 = 7;
//LABEL_22:
    pGUIWindow_CurrentMenu = CharacterUI_Initialize(v5);
    return;
  }
  if ( pCurrentScreen == SCREEN_SPELL_BOOK )
    return;
  if ( pCurrentScreen == SCREEN_CHEST )
  {
//LABEL_23:
    viewparams->bRedrawGameUI = true;
    if ( uActiveCharacter == uPlayerID )
    {
      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
      pCurrentScreen = SCREEN_CHEST_INVENTORY;
      //goto LABEL_28;
      uActiveCharacter = uPlayerID;
      return;
    }
//LABEL_27:
    if ( pPlayers[uPlayerID]->uTimeToRecovery )
      return;
    //goto LABEL_28;
    uActiveCharacter = uPlayerID;
    return;
  }
  if ( pCurrentScreen != SCREEN_HOUSE )
  {
    if ( pCurrentScreen == SCREEN_E )
    {
//LABEL_28:
      uActiveCharacter = uPlayerID;
      return;
    }
    if ( pCurrentScreen != SCREEN_CHEST_INVENTORY )
    {
      viewparams->bRedrawGameUI = true;
      uActiveCharacter = uPlayerID;
      if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 102 )
        FillAwardsData();
      return;
    }
    //goto LABEL_23;
    viewparams->bRedrawGameUI = true;
    if ( uActiveCharacter == uPlayerID )
    {
      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
      pCurrentScreen = SCREEN_CHEST_INVENTORY;
      //goto LABEL_28;
      uActiveCharacter = uPlayerID;
      return;
    }
//LABEL_27:
    if ( pPlayers[uPlayerID]->uTimeToRecovery )
      return;
    //goto LABEL_28;
    uActiveCharacter = uPlayerID;
    return;
  }
  if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
    return;
  viewparams->bRedrawGameUI = true;
  if ( uActiveCharacter != uPlayerID )
    //goto LABEL_28;
    uActiveCharacter = uPlayerID;
    return;
  if (dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD || dialog_menu_id == HOUSE_DIALOGUE_SHOP_6)
  {
    __debugbreak(); // fix indexing
    pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
    v5 = 14;
    //goto LABEL_22;
    pGUIWindow_CurrentMenu = CharacterUI_Initialize(v5);
    return;
  }
}
// 4E28F8: using guessed type int pCurrentScreen;
// F8B19C: using guessed type int dword_F8B19C;

//----- (00416B01) --------------------------------------------------------
void GameUI_DrawNPCPopup(void *_this)//PopupWindowForBenefitAndJoinText
{
  int v1; // edi@2
  int v2; // ecx@2
  NPCData *v3; // eax@2
  NPCData *v4; // esi@7
  NPCData *v5; // eax@16
  NPCData *v6; // esi@16
  const CHAR *v7; // eax@18
  unsigned int v8; // eax@25
  unsigned int v9; // eax@25
  const char *v10; // ST14_4@26
  char *v11; // esi@26
  const char *v12; // ST18_4@27
  unsigned __int16 v13; // ax@28
  char *v14; // eax@28
  GUIWindow a1; // [sp+Ch] [bp-60h]@23
  int a2; // [sp+60h] [bp-Ch]@16
  void *v17; // [sp+64h] [bp-8h]@1
  LPCSTR lpsz; // [sp+68h] [bp-4h]@6

  v17 = _this;
  if ( bNoNPCHiring != 1 )
  {
    v1 = 0;
    v2 = 0;
    v3 = pParty->pHirelings;
    /*do
    {
      if ( v3->pName )
        pTmpBuf[v1++] = v2;
      ++v3;
      ++v2;
    }
    while ( (signed int)v3 < (signed int)&pParty->pPickedItem );*/
    for (int i = 0; i < 2; ++i)
    {
     if (pParty->pHirelings[i].pName)
        pTmpBuf[v1++] = i;
    }
    lpsz = 0;
    if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
    {
      /*v4 = pNPCStats->pNewNPCData;
      do
      {
        if ( v4->uFlags & 0x80
          && (!pParty->pHirelings[0].pName || strcmp(v4->pName, pParty->pHirelings[0].pName))
          && (!pParty->pHirelings[1].pName || strcmp(v4->pName, pParty->pHirelings[1].pName)) )
          pTmpBuf[v1++] = (char)lpsz + 2;
        ++lpsz;
        ++v4;
      }
      while ( (signed int)lpsz < (signed int)pNPCStats->uNumNewNPCs );*/
      for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
      {
        if (pNPCStats->pNewNPCData[i].Hired())
        {
          if (!pParty->pHirelings[0].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[0].pName))
          {
            if (!pParty->pHirelings[1].pName || strcmp((char *)pNPCStats->pNewNPCData[i].pName, (char *)pParty->pHirelings[1].pName))
              pTmpBuf[v1++] = i + 2;
          }
        }
      }
    }
    if ( (signed int)((char *)v17 + (unsigned __int8)pParty->field_709) < v1 )
    {
      sDialogue_SpeakingActorNPC_ID = -1 - (unsigned __int8)pParty->field_709 - (int)v17;
      v5 = GetNewNPCData(sDialogue_SpeakingActorNPC_ID, &a2);
      v6 = v5;
      if ( v5 )
      {
        if ( a2 == 57 )
          v7 = pNPCTopics[512].pText; // Baby dragon
        else
          v7 = (const CHAR *)pNPCStats->pProfessions[v5->uProfession].pBenefits;
        lpsz = v7;
        if ( !v7 )
        {
          lpsz = (LPCSTR)pNPCStats->pProfessions[v5->uProfession].pJoinText;
          if ( !lpsz )
            lpsz = "";
        }
        a1.Hint = 0;
        a1.uFrameX = 38;
        a1.uFrameY = 60;
        a1.uFrameWidth = 276;
        a1.uFrameZ = 313;
        a1.uFrameHeight = pFontArrus->CalcTextHeight(lpsz, &a1, 0, 0)
                        + 2 * LOBYTE(pFontArrus->uFontHeight)
                        + 24;
        if ( (signed int)a1.uFrameHeight < 130 )
          a1.uFrameHeight = 130;
        a1.uFrameWidth = 400;
        a1.uFrameZ = a1.uFrameX + 399;
        a1.DrawMessageBox(0);
        sprintfex(pTmpBuf2, "NPC%03d", v6->uPortraitID);
        v8 = pIcons_LOD->LoadTexture(pTmpBuf2, TEXTURE_16BIT_PALETTE);
        pRenderer->DrawTextureIndexed(
          a1.uFrameX + 22,
          a1.uFrameY + 36,
          (Texture *)(v8 != -1 ? &pIcons_LOD->pTextures[v8] : 0));
        v9 = v6->uProfession;
        if ( v9 )
        {
          v10 = v6->pName;
          v11 = pTmpBuf;
          sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[429], v10, aNPCProfessionNames[v9]);
        }
        else
        {
          v12 = v6->pName;
          v11 = pTmpBuf;
          strcpy(pTmpBuf, v12);
        }
        v13 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
        a1.DrawTitleText(pFontArrus, 0, 0xCu, v13, v11, 3u);
        a1.uFrameWidth -= 24;
        a1.uFrameZ = a1.uFrameX + a1.uFrameWidth - 1;
        v14 = BuilDialogueString((char *)lpsz, uActiveCharacter - 1, 0, 0, 0, 0);
        a1.DrawText(pFontArrus, 100, 36, 0, v14, 0, 0, 0);
      }
    }
  }
}



//----- (00445D4A) --------------------------------------------------------
void GameUI_InitializeDialogue(Actor *actor, int bPlayerSaysHello)
{
  NPCData *pNPCInfo; // ebp@1
  int v9; // esi@8
  int pNumberContacts; // eax@11
  char pContainer[32]; // [sp+14h] [bp-28h]@3

  dword_A74CDC = -1;
  dword_AE336C = -1;
  pEventTimer->Pause();
  pMiscTimer->Pause();
  pAudioPlayer->StopChannels(-1, -1);
  uDialogueType = 0;
  sDialogue_SpeakingActorNPC_ID = actor->sNPC_ID;
  pDialogue_SpeakingActor = actor;
  pNPCInfo = GetNPCData(actor->sNPC_ID);
  if ( (pNPCInfo->uFlags & 3) != 2 )
    pNPCInfo->uFlags = pNPCInfo->uFlags + 1;

  switch (pParty->alignment)
  {
    case PartyAlignment_Good:    sprintfex(pContainer, "evt%02d-b", const_2()); break;
    case PartyAlignment_Neutral: sprintfex(pContainer, "evt%02d", const_2());   break;
    case PartyAlignment_Evil:    sprintfex(pContainer, "evt%02d-c", const_2()); break;
  }

  pDialogueNPCCount = 0;
  uNumDialogueNPCPortraits = 1;
  pTexture_Dialogue_Background = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
  sprintfex(pContainer, "npc%03u", pNPCInfo->uPortraitID);
  v9 = 0;
  pDialogueNPCPortraits[0] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
  dword_591084 = areWeLoadingTexture;
  uTextureID_right_panel_loop = uTextureID_right_panel;
  if ( !pNPCInfo->Hired() && pNPCInfo->Location2D >= 0 )
  {
    if ( (signed int)pParty->GetPartyFame() <= pNPCInfo->fame
      || (pNumberContacts = pNPCInfo->uFlags & 0xFFFFFF7F, (pNumberContacts & 0x80000000u) != 0) )
    {
      v9 = 1;
    }
	else
	{
		if ( pNumberContacts > 1 )
		{
		  if ( pNumberContacts == 2 )
		  {
			v9 = 3;
		  }
		  else
		  {
			  if ( pNumberContacts != 3 )
			  {
				if ( pNumberContacts != 4 )
				  v9 = 1;
			  }
			  else
			  {
				v9 = 2;
			  }
		  }
		}
		else if ( pNPCInfo->rep )
		{
		  v9 = 2;
		}
	}
  }
  if (sDialogue_SpeakingActorNPC_ID < 0)
    v9 = 4;
  pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Dialogue, v9, 0);//pNumberContacts = 1, v9 = 0; pNumberContacts = 2, v9 = 3;
  if (pNPCInfo->Hired())
  {
    if ( !pNPCInfo->bHasUsedTheAbility )
    {
      if ( pNPCInfo->uProfession >= 10 )
      {
        if ( pNPCInfo->uProfession <= 12 || pNPCInfo->uProfession > 32 && (pNPCInfo->uProfession <= 34 
             || pNPCInfo->uProfession > 38 && (pNPCInfo->uProfession <= 43 || pNPCInfo->uProfession == 52)) )
        {
          pDialogueWindow->CreateButton(480, 250, 140, LOBYTE(pFontArrus->uFontHeight) - 3, 1, 0, UIMSG_SelectNPCDialogueOption, 9, 0, "", 0);
          pDialogueWindow->_41D08F_set_keyboard_control_group(4, 1, 0, 1);
        }
      }
    }
  }

  pDialogueWindow->CreateButton( 61, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
  pDialogueWindow->CreateButton(177, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
  pDialogueWindow->CreateButton(292, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
  pDialogueWindow->CreateButton(407, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);

  if (bPlayerSaysHello && uActiveCharacter && !pNPCInfo->Hired())
  {
    if (pParty->uCurrentHour < 5 || pParty->uCurrentHour > 21)
      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodEvening, 0);
    else
      pPlayers[uActiveCharacter]->PlaySound(SPEECH_GoodDay, 0);
  }
}

//----- (00445350) --------------------------------------------------------
void GameUI_DrawDialogue()
{
  NPCData *pNPC; // ebx@2
  int pGreetType; // eax@2
  unsigned __int16 v2; // di@2
  //unsigned int v3; // eax@2
  char *v4; // esi@3
  //int v5; // eax@11
  //char *v6; // ecx@13
  //char *v7; // eax@16
  //unsigned int v8; // edi@19
  //char *v9; // ecx@27
  char *v10; // eax@29
  //int v11; // eax@30
  int v12; // esi@39
  char *v13; // eax@41
  GUIButton *v14; // eax@43
  //GUIButton *v15; // edi@43
  signed int v16; // eax@44
  //unsigned int v23; // eax@53
  //const char *v24; // eax@59
  //unsigned __int16 v30; // cx@83
  int v31; // ecx@86
  int v32; // ebx@93
  unsigned int v33; // eax@93
  GUIWindow *v34; // ecx@93
  int v35; // esi@93
  int i; // eax@93
  GUIButton *v37; // eax@94
  int v38; // eax@95
  signed int v39; // esi@99
  signed int v40; // eax@102
  unsigned int v41; // ebx@102
  int v42; // edi@102
  GUIButton *v43; // esi@103
  int v44; // eax@104
  unsigned int v45; // ecx@104
  unsigned __int16 *v46; // edx@104
  unsigned __int16 v47; // ax@104
  GUIWindow pWindow; // [sp+4h] [bp-110h]@39
  int v49; // [sp+Ch] [bp-108h]@39
  int v50; // [sp+14h] [bp-100h]@39
  GUIWindow v51; // [sp+58h] [bp-BCh]@2
  GUIWindow v52; // [sp+ACh] [bp-68h]@42
  char *Str; // [sp+100h] [bp-14h]@104
  //int v54; // [sp+104h] [bp-10h]@2
  //unsigned __int16 *v55; // [sp+108h] [bp-Ch]@82
  GUIFont *pOutString; // [sp+10Ch] [bp-8h]@39
  char *pInString=NULL; // [sp+110h] [bp-4h]@32

  if ( !pDialogueWindow )
    return;

  memcpy(&v51, pDialogueWindow, sizeof(v51));
  pNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
  pGreetType = GetGreetType(sDialogue_SpeakingActorNPC_ID);
  v51.uFrameWidth -= 10;
  v51.uFrameZ -= 10;
  //v54 = v1;
  TargetColor(0xFFu, 0xFFu, 0xFFu);
  TargetColor(0xE1u, 0xCDu, 0x23u);
  v2 = TargetColor(0x15u, 0x99u, 0xE9u);
  pRenderer->DrawTextureIndexed(477, 0, pTexture_Dialogue_Background);
  pRenderer->DrawTextureTransparent(468, 0, (Texture *)(uTextureID_right_panel_loop != -1 ? &pIcons_LOD->pTextures[uTextureID_right_panel_loop] : 0));
  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, (Texture *)(uTextureID_50795C != -1 ? &pIcons_LOD->pTextures[uTextureID_50795C] : 0));
  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pDialogueNPCPortraits[0]);

  if (pNPC->uProfession)
  {
    assert(pNPC->uProfession < sizeof(aNPCProfessionNames) / sizeof(*aNPCProfessionNames)); // sometimes buffer overflows; errors emerge both here and in dialogue text
    sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[429], pNPC->pName, aNPCProfessionNames[pNPC->uProfession]);//^Pi[%s] %s
  }
  else
    strcpy(pTmpBuf, pNPC->pName);

  v51.DrawTitleText(pFontArrus, 483, 112, v2, pTmpBuf, 3);
  pParty->GetPartyFame();

  pInString = nullptr;
  switch (uDialogueType)
  {
    case DIALOGUE_13:
      pInString = BuilDialogueString(pNPCStats->pProfessions[pNPC->uProfession - 1].pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
    break;

    case DIALOGUE_PROFESSION_DETAILS:
    {
      auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;

      if (dialogue_show_profession_details)
        pInString = BuilDialogueString(prof->pBenefits, uActiveCharacter - 1, 0, 0, 0, 0);
      else if (pNPC->Hired())
        pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
      else
        pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
    }
    break;


    case DIALOGUE_ARENA_WELCOME:
      pInString = pGlobalTXT_LocalizationStrings[574]; // "Welcome to the Arena of Life and Death.  Remember, you are only allowed one arena combat per visit.  To fight an arena battle, select the option that best describes your abilities and return to me- if you survive:"
    break;

    case DIALOGUE_ARENA_FIGHT_NOT_OVER_YET:
      pInString = pGlobalTXT_LocalizationStrings[577]; //"Get back in there you wimps:"
    break;

    case DIALOGUE_ARENA_REWARD:
      sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[576], gold_transaction_amount);// "Congratulations on your win: here's your stuff: %u gold."
      pInString = pTmpBuf;
    break;

    case DIALOGUE_ARENA_ALREADY_WON:
      pInString = pGlobalTXT_LocalizationStrings[582]; // "You already won this trip to the Arena:"
    break;

    default:
      if (uDialogueType > DIALOGUE_18 && uDialogueType < DIALOGUE_23 && !byte_5B0938[0])
      {
        pInString = (char *)current_npc_text;
      }
      else if (pGreetType == 1)//QuestNPC_greet
      {
        if (pNPC->greet)
        {
          if ((pNPC->uFlags & 3) == 2)
            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting2;
          else
            pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting1;
        }
      }
      else if (pGreetType == 2)//HiredNPC_greet
      {
        auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;

        if (pNPC->Hired())
          pInString = BuilDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0);
        else
          pInString = BuilDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0);
      }
    break;
  }

  if (pInString)
  {
    pWindow.uFrameWidth = game_viewport_width;
    pWindow.uFrameZ = 452;
    auto font = pFontArrus;
    v12 = pFontArrus->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
    if ( 352 - v12 < 8 )
    {
      font = pFontCreate;
       v12 = pFontCreate->CalcTextHeight(pInString, &pWindow, 13, 0) + 7;
    }
    if (uTextureID_Leather != -1)
      pRenderer->_4A6A68(8, 352 - v12, &pIcons_LOD->pTextures[uTextureID_Leather], pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - v12);
    pRenderer->DrawTextureIndexed(8u, 347 - v12, pTexture_591428);
    v13 = FitTextInAWindow(pInString, font,  &pWindow, 0xDu, 0);
    pDialogueWindow->DrawText(font, 13, 354 - v12, 0, v13, 0, 0, 0);
  }


  memcpy(&v52, pDialogueWindow, sizeof(v52));
  v52.uFrameX = 483;
  v52.uFrameWidth = 148;
  v52.uFrameZ = 334;
  for (int i = v52.pStartingPosActiveItem;
       i < v52.pStartingPosActiveItem + v52.pNumPresenceButton; ++i)
  {
    v14 = v52.GetControl(i);
    //v15 = v14;
    if ( !v14 )
      break;
    v16 = v14->msg_param;

    if ( v16 > 88 )
      v14->pButtonName[0] = 0;
	else if (v16 == 88)
      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[581]); // Lord
    else if (v16 == 87)
      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[580]); // Knight
    else if (v16 == 86)
      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[579]); // Squire
    else if (v16 == 85)
      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[578]); // Page
    else if (v16 == 77)
      strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[407]); // Details
    else if (v16 == 76)
    {
      if (pNPC->Hired())
        sprintf(v14->pButtonName, (const char*)pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
      else
        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[406]); // Hire
    }
	else if (v16 == 24)
    {
      __debugbreak(); // learn conditions of this event
      auto topic = pNPCTopics[pNPC->evt_F - 1].pTopic;//(&dword_721660)[8 * v23];
      if (!topic)
      {
        v14->pButtonName[0] = 0;
        v14->msg_param = 0;
      }
      else
        strcpy(v14->pButtonName, topic);
    }
	else if (v16 == 9)
      strcpy(v14->pButtonName, GetProfessionActionText(pNPC->uProfession));
	else if (v16 == 19)
	{
     // __debugbreak(); // learn conditions of this event Scavenger Hunt
      auto topic = pNPCTopics[pNPC->evt_A - 1].pTopic;//(&dword_721660)[8 * v23];
      if (!topic)
      {
        v14->pButtonName[0] = 0;
        v14->msg_param = 0;
      }
      else strcpy(v14->pButtonName, topic);
	}
	else if (v16 == 20)
	{
      //__debugbreak(); // learn conditions of this event instruments
      auto topic = pNPCTopics[pNPC->evt_B - 1].pTopic;//(&dword_721660)[8 * v23];
      if (!topic)
      {
        v14->pButtonName[0] = 0;
        v14->msg_param = 0;
      }
      else strcpy(v14->pButtonName, topic);
	}
	else if (v16 == 21)
	{
      //__debugbreak(); // learn conditions of this event
      auto topic = pNPCTopics[pNPC->evt_C - 1].pTopic;//(&dword_721660)[8 * v23];
      if (!topic)
      {
        v14->pButtonName[0] = 0;
        v14->msg_param = 0;
      }
      else strcpy(v14->pButtonName, topic);
	}
	else if (v16 == 22)
	{
      //__debugbreak(); // learn conditions of this event
      auto topic = pNPCTopics[pNPC->evt_D - 1].pTopic;//(&dword_721660)[8 * v23];
      if (!topic)
      {
        v14->pButtonName[0] = 0;
        v14->msg_param = 0;
      }
      else strcpy(v14->pButtonName, topic);
	}
	else if (v16 == 23)
	{
      //__debugbreak(); // learn conditions of this event
      auto topic = pNPCTopics[pNPC->evt_E - 1].pTopic;//(&dword_721660)[8 * v23];
      if (!topic)
      {
        v14->pButtonName[0] = 0;
        v14->msg_param = 0;
      }
      else strcpy(v14->pButtonName, topic);
	}
	else if (v16 == 13)
	{
      if (pNPC->Hired())
        sprintf(v14->pButtonName, pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s
      else
        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[122]); // Join
	}
	else
      v14->pButtonName[0] = 0;
	

    if (pParty->field_7B5_in_arena_quest && pParty->field_7B5_in_arena_quest != -1)
    {
      int num_dead_actors = 0;
      pInString = 0;
      for (uint i = 0; i < uNumActors; ++i)
      {
        if (pActors[i].uAIState == Dead || pActors[i].uAIState == Removed ||
            pActors[i].uAIState  == Disabled)
          ++num_dead_actors;
        else
        {
          int sumonner_type = PID_TYPE(pActors[i].uSummonerID);
          if (sumonner_type == OBJECT_Player)
            ++num_dead_actors;
        }
      }
      if (num_dead_actors == uNumActors)
        strcpy(v14->pButtonName, pGlobalTXT_LocalizationStrings[658]); // Collect Prize
    }
  }


  v32 = 0;
  //pInString = (char *)TargetColor(0xFFu, 0xFFu, 0xFFu);
  v33 = TargetColor(0xE1u, 0xCDu, 0x23u);
  v34 = pDialogueWindow;
  //v54 = v33;
  v35 = pDialogueWindow->pStartingPosActiveItem;
  for ( i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
  {
    v37 = v34->GetControl(v35);
    if ( !v37 )
    {
      v34 = pDialogueWindow;
      break;
    }
    v38 = pFontArrus->CalcTextHeight(v37->pButtonName, &v52, 0, 0);
    v34 = pDialogueWindow;
    v32 += v38;
    ++v35;
  }
  v39 = v34->pNumPresenceButton;
  if ( v39 )
  {
    pOutString = (GUIFont *)((174 - v32) / v39);
    if ( (174 - v32) / v39 > 32 )
      pOutString = (GUIFont *)32;
    int v55 = 1;
    v40 = 174 - (int)pOutString * v39 - v32;
    v41 = v34->pStartingPosActiveItem;
    v42 = v40 / 2 - (signed int)pOutString / 2 + 138;
    if ( (signed int)v41 < (signed int)(v41 + v39) )
    {
      do
      {
        v43 = v34->GetControl(v41);
        if ( !v43 )
          break;
        v43->uY = (unsigned int)((char *)pOutString + v42);
        Str = v43->pButtonName;
        v44 = pFontArrus->CalcTextHeight(v43->pButtonName, &v52, 0, 0);
        v45 = v43->uY;
        v46 = (unsigned short *)v55;
        v43->uHeight = v44;
        v42 = v45 + v44 - 1;
        v43->uW = v42;
        v47 = v33;
        if ( (unsigned __int16 *)pDialogueWindow->pCurrentPosActiveItem != v46 )
          v47 = TargetColor(0xFFu, 0xFFu, 0xFFu);
        v52.DrawTitleText(pFontArrus, 0, v45, v47, Str, 3u);
        v34 = pDialogueWindow;
        ++v55;
        ++v41;
      }
      while ( (signed int)v41 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
    }
  }
  pRenderer->DrawTextureIndexed(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId));
}



//----- (00444FBE) --------------------------------------------------------
void GameUI_DrawBranchlessDialogue()
{
  //GUIFont *v0; // esi@1
  int v1; // esi@4
  char *v2; // eax@6
  int v3; // edi@12
  char Str[200]; // [sp+Ch] [bp-120h]@12
  GUIWindow v5; // [sp+D4h] [bp-58h]@4
  GUIFont *pFont; // [sp+128h] [bp-4h]@1

  pFont = pFontArrus;
  if ( current_npc_text && !byte_5B0938[0] )
    strcpy(byte_5B0938, current_npc_text);
  v5.uFrameWidth = game_viewport_width;
  v5.uFrameZ = 452;
  v1 = pFontArrus->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
  if ( 352 - v1 < 8 )
  {
    pFont = pFontCreate;
    v1 = pFontCreate->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
  }
  pRenderer->_4A6A68(8, 352 - v1,
    pIcons_LOD->GetTexture(uTextureID_Leather),
    pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - v1);
  pRenderer->DrawTextureIndexed(8, 347 - v1, pTexture_591428);
  v2 = FitTextInAWindow(byte_5B0938, pFont, &v5, 0xCu, 0);
  pGUIWindow2->DrawText(pFont, 12, 354 - v1, 0, v2, 0, 0, 0);
  pRenderer->DrawTextureRGB(0, 0x160u, pTexture_StatusBar);
  if ( pGUIWindow2->receives_keyboard_input_2 != WINDOW_INPUT_IN_PROGRESS)
  {
    if ( pGUIWindow2->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
    {
      pGUIWindow2->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
      strcpy(GameUI_Footer_TimedString, (const char *)pKeyActionMap->pPressedKeysBuffer);
LABEL_16:
      sub_4452BB();
      return;
    }
    if ( pGUIWindow2->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED)
      return;
    pGUIWindow2->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
LABEL_15:
    memset(GameUI_Footer_TimedString, 0, 0xC8u);
    goto LABEL_16;
  }
  if ( pGUIWindow2->ptr_1C == (void *)26 )
  {
    sprintf(Str, "%s %s", GameUI_Footer_TimedString, pKeyActionMap->pPressedKeysBuffer);
    v3 = pFontLucida->GetLineWidth(Str);
    pGUIWindow2->DrawText(pFontLucida, 13, 357, 0, Str, 0, 0, 0);
    pGUIWindow2->DrawFlashingInputCursor(v3 + 13, 357, pFontLucida);
    return;
  }
  if ( pKeyActionMap->pPressedKeysBuffer[0] )
  {
    pKeyActionMap->SetWindowInputStatus(0);
    goto LABEL_15;
  }
}


//----- (004443D5) --------------------------------------------------------
const char *GameUI_GetMinimapHintText()
{
  int v0; // ST20_4@1
  unsigned int v1; // esi@1
  signed int v2; // ebx@1
  double v3; // st7@1
  int v4; // esi@3
  int v5; // edi@4
  int v6; // eax@4
  int v7; // eax@4
  BSPModel *v8; // ecx@4
  unsigned __int8 v9; // zf@5
  char v10; // sf@5
  unsigned __int8 v11; // of@5
  ODMFace *v12; // eax@6
  __int16 v13; // cx@6
  const char *v14; // eax@8
  const char *v15; // edi@8
  char *result; // eax@12
  unsigned int v17; // eax@14
  unsigned int v18; // [sp+Ch] [bp-20h]@1
  int v19; // [sp+10h] [bp-1Ch]@1
  int v20; // [sp+14h] [bp-18h]@1
  char *v21; // [sp+18h] [bp-14h]@1
  unsigned int pY; // [sp+1Ch] [bp-10h]@1
  int v23; // [sp+20h] [bp-Ch]@1
  int v24; // [sp+24h] [bp-8h]@1
  int pX; // [sp+28h] [bp-4h]@1

  v24 = pParty->vPosition.x;
  v0 = pParty->vPosition.y;
  v1 = pOutdoor->uNumBModels;
  *(float *)&v23 = (double)(signed int)viewparams->uMinimapZoom * 0.000015258789;
  v2 = 0;
  v18 = pOutdoor->uNumBModels;
  v21 = 0;
  pMouse->GetClickPos((unsigned int *)&pX, &pY);
  v3 = 1.0 / *(float *)&v23;
  v23 = pX - 557;
  v19 = (signed __int64)((double)(pX - 557) * v3 + (double)v24);
  v20 = (signed __int64)((double)v0 - (double)(signed int)(pY - 74) * v3);
  if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor || (*(float *)&v23 = 0.0, (signed int)v1 <= 0) )
  {
LABEL_14:
    v17 = pMapStats->GetMapInfo(pCurrentMapName);
    if ( v17 == v2 )
      result = "No Maze Info for this maze on file!";
    else
      result = pMapStats->pInfos[v17].pName;
  }
  else
  {
    v4 = 0;
    while ( 1 )
    {
      pX = pOutdoor->pBModels[v4].vBoundingCenter.x - v19;
      pY = pOutdoor->pBModels[v4].vBoundingCenter.y - v20;
      v5 = abs((signed)pY);
      v6 = abs((signed)pX);
      v7 = int_get_vector_length(v6, v5, v2);
      v8 = &pOutdoor->pBModels[0];
      if ( v7 < 2 * pOutdoor->pBModels[v4].sBoundingRadius )
      {
        v11 = __OFSUB__(pOutdoor->pBModels[v4].uNumFaces, v2);
        v9 = pOutdoor->pBModels[v4].uNumFaces == v2;
        v10 = ((pOutdoor->pBModels[v4].uNumFaces - v2) & 0x80000000u) != 0;
        v24 = v2;
        if ( !((unsigned __int8)(v10 ^ v11) | v9) )
        {
          do
          {
            v12 = &v8[v4].pFaces[v2 / 0x134u];
            v13 = v12->sCogTriggeredID;
            if ( v13 )
            {
              if ( !(BYTE2(v12->uAttributes) & 0x10) )
              {
                v14 = GetEventHintString(v13);
                v15 = v14;
                if ( v14 )
                {
                  if ( _stricmp(v14, "") )
                    v21 = (char *)v15;
                }
              }
            }
            ++v24;
            v8 = pOutdoor->pBModels;
            v2 += 308;
          }
          while ( v24 < (signed int)pOutdoor->pBModels[v4].uNumFaces );
        }
        result = v21;
        v2 = 0;
        if ( v21 )
          break;
      }
      ++v23;
      ++v4;
      if ( v23 >= (signed int)v18 )
        goto LABEL_14;
    }
  }
  return result;
}





//----- (0041D3B7) --------------------------------------------------------
void GameUI_CharacterQuickRecord_Draw(GUIWindow *window, Player *player)
{
  //Player *pPlayer; // esi@1
  int v6; // eax@5
  int v7; // ebx@5
  //unsigned int v8; // ecx@5
  int v9; // ebx@5
  //unsigned int v10; // eax@5
  //int v11; // eax@5
  //unsigned int v12; // ecx@5
  Texture *v13; // eax@6
  unsigned int v14; // eax@12
  PlayerFrame *v15; // eax@12
  //unsigned int v16; // eax@15
  unsigned int v20; // eax@15
  unsigned int v24; // eax@15
  unsigned int v25; // eax@15
  unsigned __int8 v28; // al@15
  char *v29; // eax@16
  __int64 v35; // ST38_8@22
  int v36; // esi@22
  unsigned int v38; // eax@22
  char *v39; // eax@24
  signed int uFramesetID; // [sp+20h] [bp-8h]@9
  int uFramesetIDa; // [sp+20h] [bp-8h]@18

  uint numActivePlayerBuffs = 0;
  for (uint i = 0; i < 24; ++i)
    if (player->pPlayerBuffs[i].uExpireTime > 0)
      ++numActivePlayerBuffs;

  v6 = pFontArrus->uFontHeight + 162;
  v7 = (numActivePlayerBuffs - 1) * pFontArrus->uFontHeight;
  v9 = v6 + v7;
  window->uFrameHeight = v9;
  window->uFrameZ = window->uFrameWidth + window->uFrameX - 1;
  window->uFrameW = v9 + window->uFrameY - 1;
  window->DrawMessageBox(0);

  if (player->Eradicated())
    v13 = pTexture_PlayerFaceEradicated;
  else if (player->Dead())
    v13 = pTexture_PlayerFaceDead;
  else
  {
      uFramesetID = pPlayerFrameTable->GetFrameIdByExpression(player->expression);
      if ( !uFramesetID )
        uFramesetID = 1;
      if ( player->expression == CHARACTER_EXPRESSION_21)
      {
        v15 = pPlayerFrameTable->GetFrameBy_y(&player->_expression21_frameset, &player->_expression21_animtime, pMiscTimer->uTimeElapsed);
      }
      else
      {
        v14 = pMiscTimer->Time();
        v15 = pPlayerFrameTable->GetFrameBy_x(uFramesetID, v14);
      }
      player->field_1AA2 = v15->uTextureID - 1;
      v13 = pTextures_PlayerFaces[(unsigned int)window->ptr_1C][v15->uTextureID - 1];
  }

  pRenderer->DrawTextureTransparent(window->uFrameX + 24, window->uFrameY + 24, v13);

  sprintfex(pTmpBuf, "\f%05d", ui_character_header_text_color);
  sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], player->pName, pClassNames[player->classType]); // "%s the %s"
  strcat(pTmpBuf, pTmpBuf2);
  strcat(pTmpBuf, "\f00000\n");

  v20 = UI_GetHealthManaStringColor(player->sHealth, player->GetMaxHealth());
  sprintf(pTmpBuf2, "%s : \f%05u%d\f00000 / %d\n",
          pGlobalTXT_LocalizationStrings[108], // "Hit Points"
          v20, player->sHealth, player->GetMaxHealth());
  strcat(pTmpBuf, pTmpBuf2);

  v24 = UI_GetHealthManaStringColor(player->sMana, player->GetMaxMana());
  sprintf(pTmpBuf2, "%s : \f%05u%d\f00000 / %d\n",
          pGlobalTXT_LocalizationStrings[212], // "Spell Points"
          v24, player->sMana, player->GetMaxMana());
  strcat(pTmpBuf, pTmpBuf2);

  v25 = player->GetMajorConditionIdx();
  sprintf(pTmpBuf2, "%s: \f%05d%s\f00000\n",
          pGlobalTXT_LocalizationStrings[47], // "Condition
          GetConditionDrawColor(v25), aCharacterConditionNames[v25]);
  strcat(pTmpBuf, pTmpBuf2);

  v28 = player->uQuickSpell;
  if ( v28 )
    v29 = pSpellStats->pInfos[v28].pShortName;
  else
    v29 = pGlobalTXT_LocalizationStrings[153];
  sprintfex(pTmpBuf2, "%s: %s", pGlobalTXT_LocalizationStrings[172], v29); // "Quick Spell"
  strcat(pTmpBuf, pTmpBuf2);

  window->DrawText(pFontArrus, 120, 22, 0, pTmpBuf, 0, 0, 0);

  uFramesetIDa = 0;
  for (uint i = 0; i < 24; ++i)
  {
    auto buff = player->pPlayerBuffs + i;
    if (buff->uExpireTime > 0)
    {
      v35 = buff->uExpireTime - pParty->uTimePlayed;
      v36 = uFramesetIDa++ * pFontComic->uFontHeight + 134;
      v38 = ui_game_character_record_playerbuff_colors[i];
      window->DrawText(pFontComic, 52, v36, v38, aSpellNames[20 + i], 0, 0, 0);
      sub_41D20D_buff_remaining_time_string(v36, window, v35, pFontComic);
    }
  }

  v39 = "";
  if ( uFramesetIDa == 0 )
    v39 = pGlobalTXT_LocalizationStrings[153]; // "None"
  sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[450], v39); // "Active Spells: %s"
  window->DrawText(pFontArrus, 14, 114, 0, pTmpBuf, 0, 0, 0);
}



//----- (0041A57E) --------------------------------------------------------
void GameUI_QuickRef_Draw()
{
        //unsigned int v0; // ebx@1
        //unsigned int v1; // eax@1
        //Player *pPlayer; // ebp@2
        //int v3; // eax@6
        //int v4; // edi@6
        unsigned int v5; // eax@7
        unsigned int v6; // edi@9
        unsigned int v7; // edi@11
        //signed int v8; // eax@13
        unsigned int v9; // eax@13
        unsigned int v10; // edi@13
        //int v11; // eax@15
        unsigned int v12; // eax@15
        unsigned int v13; // edi@15
        //int v14; // eax@17
        //int v15; // ST18_4@17
        //int v16; // ebx@17
        //int v17; // eax@17
        unsigned int v18; // eax@17
        unsigned int v19; // edi@17
        //int v20; // eax@19
        unsigned int v21; // edi@19
        char *v22; // eax@21
        unsigned int v23; // edi@21
        //int v24; // eax@23
        unsigned int v25; // edi@23
        char *v26; // eax@25
        unsigned int v27; // edi@25
        int v28; // ecx@27
        char *v29; // eax@27
        signed int v30; // edx@27
        unsigned int v31; // edi@31
        unsigned int v32; // edi@33
        const char *v33; // ST10_4@35
        unsigned int v34; // eax@35
        unsigned int v35; // edi@35
        //unsigned __int8 v36; // al@37
        char *v37; // eax@38
        int v38; // eax@41
        signed int v39; // edi@42
        //char *v40; // eax@45
        //unsigned int v41; // eax@45
        signed int v43; // [sp+10h] [bp-1Ch]@1
        unsigned int v44; // [sp+14h] [bp-18h]@2
        int v45; // [sp+18h] [bp-14h]@1
        //unsigned int v46; // [sp+1Ch] [bp-10h]@1
        //unsigned int v47; // [sp+20h] [bp-Ch]@1
        unsigned int v48; // [sp+24h] [bp-8h]@33
        //unsigned int v49; // [sp+28h] [bp-4h]@1

        //v0 = 0;
        //v47 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
        //v49 = TargetColor(0xFFu, 0, 0);
        //v46 = TargetColor(0, 0xFFu, 0);
        //v1 = pIcons_LOD->LoadTexture("quikref", TEXTURE_16BIT_PALETTE);
  pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->LoadTexturePtr("quikref", TEXTURE_16BIT_PALETTE));
        v43 = 0;
        v45 = LOBYTE(pFontArrus->uFontHeight) + 1;
        do
        {
            auto player = &pParty->pPlayers[v43];
            v44 = 94 * v43 + 89;
            if ( v43 == 0 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, 0x12u, 0, pGlobalTXT_LocalizationStrings[149], 60, 0);//Name
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 94 * v43 + 89, 0x12u, ui_character_header_text_color, player->pName, 84, 0);
            if ( v43 == 0 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, 0x2Fu, 0, pGlobalTXT_LocalizationStrings[131], 60, 0); //Óðîâ.
            sprintf(pTmpBuf, "%lu", player->GetActualLevel());
            if ( player->GetActualLevel() <= player->GetBaseLevel())
                v5 = player->GetExperienceDisplayColor();
            else
              v5 = ui_character_bonus_text_color;
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, 0x2Fu, v5, pTmpBuf, 84, 0);
            v6 = v45 + 47;
            if ( v43 == 0 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v45 + 47, 0, pGlobalTXT_LocalizationStrings[41], 60, 0);//Êëàññ
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v6, 0, pClassNames[player->classType], 84, 0);
            v7 = v45 + v6;
            if ( v43 == 0 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v7, 0, pGlobalTXT_LocalizationStrings[107], 60, 0);//Çäîð.
            sprintf(pTmpBuf, "%d", player->sHealth);
            v9 = UI_GetHealthManaStringColor(player->sHealth, player->GetMaxHealth());
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v7, v9, pTmpBuf, 84, 0);
            v10 = v45 + v7;
            if ( v43 == 0 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v10, 0, pGlobalTXT_LocalizationStrings[209], 60, 0);//Ìàíà
            sprintf(pTmpBuf, "%d", player->sMana);
            v12 = UI_GetHealthManaStringColor(player->sMana, player->GetMaxMana());
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v10, v12, pTmpBuf, 84, 0);
            v13 = v45 + v10;
            if ( v43 == 0 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v13, 0, pGlobalTXT_LocalizationStrings[0], 60, 0);//Êëàññ áðîíè
            sprintf(pTmpBuf, "%d", player->GetActualAC());
            v18 = UI_GetHealthManaStringColor(player->GetActualAC(), player->GetBaseAC());
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v13, v18, pTmpBuf, 84, 0);
            v19 = v45 + v13;
            if ( !v43 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v19, 0, pGlobalTXT_LocalizationStrings[18], 60, 0);//Àòàêà
            sprintf(pTmpBuf, "%+d", player->GetActualAttack(0));
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v19, 0, pTmpBuf, 84, 0);
            v21 = v45 + v19;
            if ( !v43 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v21, 0, pGlobalTXT_LocalizationStrings[66], 60, 0);//Ïîâð.
            v22 = player->GetMeleeDamageString();
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v21, 0, v22, 84, 0);
            v23 = v45 + v21;
            if ( !v43 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v23, 0, pGlobalTXT_LocalizationStrings[203], 60, 0);// Ñòðåëÿòü
            sprintf(pTmpBuf, "%+d", player->GetRangedAttack());
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v23, 0, pTmpBuf, 84, 0);
            v25 = v45 + v23;
            if ( !v43 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v25, 0, pGlobalTXT_LocalizationStrings[66], 60, 0);//Ïîâð.
            v26 = player->GetRangedDamageString();
            pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v25, 0, v26, 84, 0);
            v27 = v45 + v25;
            if ( !v43 )
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v27, 0, pGlobalTXT_LocalizationStrings[205], 60, 0);//Íàâûêè
            v28 = 0;
            v29 = (char *)player->pActiveSkills;
            v30 = 36;
            do
                {
                if ( *(short *)v29 )
                    ++v28;
                v29 += 2;
                --v30;
                }
                while ( v30 );
                sprintf(pTmpBuf, "%lu", v28);
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v27, 0, pTmpBuf, 84, 0);
                v31 = v45 + v27;
                if ( !v43 )
                    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v31, 0, pGlobalTXT_LocalizationStrings[168], 60, 0);//Î÷êè
                sprintf(pTmpBuf, "%lu", player->uSkillPoints);
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v31, player->uSkillPoints ? ui_character_bonus_text_color : ui_character_default_text_color, pTmpBuf, 84, 0);
                v32 = v45 + v31;
                v48 = player->GetMajorConditionIdx();
                if ( !v43 )
                    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v32, 0, pGlobalTXT_LocalizationStrings[45], 60, 0);//Ñîñò.
                v33 = aCharacterConditionNames[v48];
                v34 = GetConditionDrawColor(v48);
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v32, v34, v33, 84, 0);
                v35 = v45 + v32;
                if ( !v43 )
                    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v35, 0, pGlobalTXT_LocalizationStrings[170], 60, 0);//Á.Ïðèì.
                if (player->uQuickSpell)
                    v37 = pSpellStats->pInfos[player->uQuickSpell].pShortName;
                else
                    v37 = pGlobalTXT_LocalizationStrings[153];//Íåò
                pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v35, 0, v37, 84, 0);
                ++v43;
            }
            while ( v43 < 4 );

            v38 = GetPartyReputation();
            if ( v38 >= 0 )
                {
                if ( v38 <= 5 )
                  v39 = ui_character_default_text_color;
                else
                  v39 = ui_character_bonus_text_color_neg;
                }
            else
              v39 = ui_character_bonus_text_color;

            sprintf(pTmpBuf, "%s: \f%05d%s\f00000", pGlobalTXT_LocalizationStrings[180], v39, GetReputationString(v38));//Reputation
            pGUIWindow_CurrentMenu->DrawText(pFontArrus, 22, 323, 0, pTmpBuf, 0, 0, 0);

            sprintf(pTmpBuf, "\r261%s: %d", pGlobalTXT_LocalizationStrings[84], pParty->GetPartyFame());// Fame Ñëàâà
            pGUIWindow_CurrentMenu->DrawText(pFontArrus, 0, 323, 0, pTmpBuf, 0, 0, 0);
}



//----- (0041AD6E) --------------------------------------------------------
void GameUI_DrawRightPanelItems()
{
  if (GameUI_RightPanel_BookFlashTimer > pParty->uTimePlayed)
    GameUI_RightPanel_BookFlashTimer = 0;

  if (pParty->uTimePlayed - GameUI_RightPanel_BookFlashTimer > 128)
  {
    GameUI_RightPanel_BookFlashTimer = pParty->uTimePlayed;
    
    static bool byte_50697C = false; // 50697C
    byte_50697C = !byte_50697C;
    if ( byte_50697C && pCurrentScreen != SCREEN_REST )
    {
      if (bFlashQuestBook)     pRenderer->DrawTextureTransparent(493, 355, pIcons_LOD->GetTexture(uTextureID_ib_td1_A));
      if (bFlashAutonotesBook) pRenderer->DrawTextureTransparent(527, 353, pIcons_LOD->GetTexture(uTextureID_ib_td2_A));
      if (bFlashHistoryBook)   pRenderer->DrawTextureTransparent(600, 361, pIcons_LOD->GetTexture(uTextureID_ib_td5_A));
    }
    else
    {
      pRenderer->DrawTextureRGB(468, 0, pTexture_RightFrame);
      GameUI_DrawHiredNPCs();
    }
  }
}

//----- (0041AEBB) --------------------------------------------------------
void GameUI_DrawFoodAndGold()
{
  int v2; // esi@2

  if ( uGameState != GAME_STATE_FINAL_WINDOW )
  {
    v2 = sub_44100D() != 0 ? 381 : 322;
    sprintf(pTmpBuf, "\r087%lu", pParty->uNumFoodRations);
    pPrimaryWindow->DrawText(pFontSmallnum, 0, v2, uGameUIFontMain, pTmpBuf, 0, 0, uGameUIFontShadow);
    sprintf(pTmpBuf, "\r028%lu", pParty->uNumGold);
    pPrimaryWindow->DrawText(pFontSmallnum, 0, v2, uGameUIFontMain, pTmpBuf, 0, 0, uGameUIFontShadow);
  }
}


//----- (0041B0C9) --------------------------------------------------------
void GameUI_DrawLifeManaBars()
{
  double v3; // st7@3
  double v7; // st7@25
  Texture *v9; // [sp-4h] [bp-30h]@10
  Texture *v10; // [sp+Ch] [bp-20h]@1


  v10 = pIcons_LOD->GetTexture(uTextureID_BarBlue);

  for (uint i = 0; i < 4; ++i)
  {
    auto player = pParty->pPlayers + i;

    if (player->sHealth > 0)
	{
      int v17 = 0;
      if (i == 2 || i == 3)
        v17 = 2;

      v3 = (double)player->sHealth / (double)player->GetMaxHealth();
      if( v3 > 0.5 )
      {
        if ( v3 > 1.0 )
          v3 = 1.0;
		v9 = pIcons_LOD->GetTexture(uTextureID_BarGreen);
      }
      else if ( v3 > 0.25 )
        v9 = pIcons_LOD->GetTexture(uTextureID_BarYellow);
      else if ( v3 > 0.0 )
        v9 = pIcons_LOD->GetTexture(uTextureID_BarRed);


		if( v3 > 0.0 )
		{
			pRenderer->SetTextureClipRect(v17 + pHealthBarPos[i],
                                          (signed __int64)((1.0 - v3) * v9->uTextureHeight) + 402,
                                          v17 + pHealthBarPos[i] + v9->uTextureWidth,
                                          v9->uTextureHeight + 402);

		  pRenderer->DrawTextureIndexed(v17 + pHealthBarPos[i], 402, v9);
		  pRenderer->ResetTextureClipRect();
		}
	}


    if (player->sMana > 0)
    {
      v7 = player->sMana / (double)player->GetMaxMana();
      if ( v7 > 1.0 )
        v7 = 1.0;

      int v17 = 0;
      if (i == 2)
        v17 = 1;

      pRenderer->SetTextureClipRect(v17 + pManaBarPos[i],
                                   (signed __int64)((1.0 - v7) * v10->uTextureHeight) + 402,
                                   v17 + pManaBarPos[i] + v10->uTextureWidth,
                                   v10->uTextureHeight + 402);
      pRenderer->DrawTextureIndexed(v17 + pManaBarPos[i], 402, v10);
      pRenderer->ResetTextureClipRect();
    }
  }
}

//----- (0041B3B6) --------------------------------------------------------
void GameUI_DrawRightPanel()
{
  pRenderer->DrawTextureTransparent(pViewport->uViewportBR_X, 0,
                                    pIcons_LOD->GetTexture(uTextureID_right_panel));
}

//----- (0041B3E2) --------------------------------------------------------
void GameUI_DrawRightPanelFrames()
{
  pRenderer->DrawTextureRGB(0,   0,   pTexture_TopFrame);
  pRenderer->DrawTextureRGB(0,   8,   pTexture_LeftFrame);
  pRenderer->DrawTextureRGB(468, 0,   pTexture_RightFrame);
  pRenderer->DrawTextureRGB(0,   352, pTexture_BottomFrame);
  GameUI_DrawFoodAndGold();
  GameUI_DrawRightPanelItems();
}


//----- (0041C047) --------------------------------------------------------
void GameUI_Footer_2()
{
    char *v1; // edx@2
    int v5; // eax@5

  pRenderer->DrawTextureRGB(0, 352, pTexture_StatusBar);
  if (GameUI_Footer_TimeLeft)
    v1 = GameUI_Footer_TimedString;
  else
  {
    if (!pFooterString[0])
      return;
    v1 = pFooterString;
  }

  v5 = pFontLucida->AlignText_Center(450, v1);
  pPrimaryWindow->DrawText(pFontLucida, v5 + 11, 357, uGameUIFontMain, v1, 0, 0, uGameUIFontShadow);
}

//----- (0041C0B8) --------------------------------------------------------
void GameUI_SetFooterString(const char *pStr)
{
    const char *v1; // esi@1
    int i; // eax@7
    int j; // eax@11

    v1 = pStr;
    if ( pStr && strcmp(pStr, "test") && !IsBadStringPtrA(v1, 1) && (*v1 || GameUI_Footer_TimeLeft) )
        {
        if ( GameUI_Footer_TimeLeft )
            {
            for ( i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString);
                i > 450;
                i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString) )
                byte_5C3427[strlen(GameUI_Footer_TimedString)] = 0;
            }
        else
            {
            strcpy(pFooterString, v1);
            for ( j = pFontLucida->GetLineWidth(pFooterString);
                j > 450;
                j = pFontLucida->GetLineWidth(pFooterString) )
                GameUI_Footer_TimedString[strlen(pFooterString) + 199] = 0;
            }
        }
    }

//----- (0041C179) --------------------------------------------------------
void GameUI_Footer()
{
    //unsigned int v0; // ebp@1
    char *v1; // edi@5
    int v2; // eax@5
    unsigned int v3; // esi@5
    size_t v4; // eax@6
    GUIFont *v5; // ecx@6
    int v6; // eax@9
    size_t v7; // eax@10
    GUIFont *v8; // ecx@10
    char v9; // zf@12
    //unsigned int v10; // ST08_4@13
    int v11; // eax@13

    if ( pFooterString[0] || GameUI_Footer_TimeLeft || bForceDrawFooter )
        {
        pRenderer->DrawTextureRGB(0, 352u, pTexture_StatusBar);
        if ( GameUI_Footer_TimeLeft )
            {
            v1 = GameUI_Footer_TimedString;
            v2 = pFontLucida->GetLineWidth(GameUI_Footer_TimedString);
            v3 = 450;
            while ( v2 > 450 )
                {
                v4 = strlen(GameUI_Footer_TimedString);
                v5 = pFontLucida;
                byte_5C3427[v4] = 0;
                v2 = pFontLucida->GetLineWidth(GameUI_Footer_TimedString);
                }
            }
        else
            {
            v1 = pFooterString;
            v6 = pFontLucida->GetLineWidth(pFooterString);
            v3 = 450;
            while ( v6 > 450 )
                {
                v7 = strlen(pFooterString);
                v8 = pFontLucida;
                GameUI_Footer_TimedString[v7 + 199] = 0;
                v6 = pFontLucida->GetLineWidth(pFooterString);
                }
            }
        v9 = *v1 == 0;
        bForceDrawFooter = 0;
        if ( !v9 )
            {
            v11 = pFontLucida->AlignText_Center(v3, v1);
            pPrimaryWindow->DrawText(pFontLucida, v11 + 11, 357, uGameUIFontMain, v1, 0, 0, uGameUIFontShadow);
            }
        }
    }
// 5C35BC: using guessed type int bForceDrawFooter;


//----- (00420EFF) --------------------------------------------------------
void __cdecl GameUI_WritePointedObjectStatusString()
{
  int v1; // ebx@6
  GUIWindow *pWindow; // edi@7
  GUIButton *pButton; // ecx@11
  Player *pPlayer; // eax@19
  char v5; // cl@19
  unsigned int v6; // eax@19
  int v7; // ecx@19
  __int16 v8; // fps@23
  unsigned __int8 v9; // c0@23
  unsigned __int8 v10; // c3@23
  enum UIMessageType pMessageType1; // esi@24
  //int v12; // edx@25
  char *v13; // ecx@28
  int v14; // eax@41
  ItemGen *pItemGen; // ecx@44
  int v16; // ecx@46
  const char *v17; // eax@49
  signed int v18; // eax@55
  signed int v18b;
  signed int v19; // ecx@63
  BLVFace *pFace; // eax@69
  __int16 v21; // ax@70
  const char *v22; // eax@72
  LevelDecoration *v23; // ecx@75
  LevelDecoration *v24; // esi@75
  __int16 v25; // ax@75
  const char *v26; // ecx@79
  Actor *pActor; // ecx@82
  char *v28; // esi@82
  int v29; // eax@82
  signed int v30; // ecx@88
  const char *v31; // eax@91
  __int16 v32; // fps@109
  //unsigned __int8 v33; // c0@109
  //unsigned __int8 v34; // c3@109
  enum UIMessageType pMessageType2; // esi@110
  //int v36; // edx@111
  enum UIMessageType pMessageType3; // edx@117
  //int v38; // ecx@118
  const char *v39; // [sp-8h] [bp-E8h]@20
  char *v40; // [sp-8h] [bp-E8h]@83
  int v41; // [sp-4h] [bp-E4h]@20
  char Str1[200]; // [sp+Ch] [bp-D4h]@129
  unsigned int pX; // [sp+D4h] [bp-Ch]@1
  unsigned int pY; // [sp+D8h] [bp-8h]@1
  unsigned int v45; // [sp+DCh] [bp-4h]@21

  v13 = nullptr;

  pMouse->uPointingObjectID = 0;
  pMouse->GetClickPos(&pX, &pY);
  if ( pX < 0 || (signed int)pX > 639 || pY < 0 || (signed int)pY > 479 )//( (pX & 0x80000000u) != 0 || (signed int)pX > 639 || (pY & 0x80000000u) != 0 || (signed int)pY > 479 )
    return;
  if (pCurrentScreen == SCREEN_GAME)
  {
    if ( (signed int)pX > 467 || (signed int)pY > 351 )
      goto _click_on_game_ui;
    if ( pRenderer->pRenderD3D )  // inlined mm8::4C1E01
    {
      v18 = pGame->pVisInstance->get_picked_object_zbuf_val();
      if ( (signed int)pX < (signed int)pViewport->uScreen_TL_X
        || (signed int)pX > (signed int)pViewport->uScreen_BR_X
        || (signed int)pY < (signed int)pViewport->uScreen_TL_Y
        || (signed int)pY > (signed int)pViewport->uScreen_BR_Y )
        v18 = -1;
      if ( v18 == -1 )
        //goto LABEL_61;
      {
        pMouse->uPointingObjectID = 0;
        if ( pMouse->uPointingObjectID == 0 )
        {
          if ( uLastPointedObjectID != 0 )
          {
            pFooterString[0] = 0;
            bForceDrawFooter = 1;
          }
        }
        uLastPointedObjectID = pMouse->uPointingObjectID;
        return;
      }
    }
    else
    {
      v18 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
    }
    pMouse->uPointingObjectID = (unsigned __int16)v18;
    v19 = (signed)PID_ID(v18);
    if (PID_TYPE(v18) == OBJECT_Item)
    {
      v30 = v19;
      if ( pObjectList->pObjects[pSpriteObjects[v30].uObjectDescID].uFlags & 0x10 )
        //goto LABEL_73;
      {
        pMouse->uPointingObjectID = 0;
        //goto LABEL_50;
        uLastPointedObjectID = 1;
        if ( pMouse->uPointingObjectID == 0 )
        {
          if ( uLastPointedObjectID != 0 )
          {
            pFooterString[0] = 0;
            bForceDrawFooter = 1;
          }
        }
        uLastPointedObjectID = pMouse->uPointingObjectID;
        return;
      }
      if ( v18 >= (signed int)0x2000000u || pParty->pPickedItem.uItemID )
      {
        v22 = pSpriteObjects[v30].stru_24.GetDisplayName();
//LABEL_93:
        v26 = v22;
        //goto LABEL_87;
        GameUI_SetFooterString(v26);
        if ( pMouse->uPointingObjectID == 0 )
        {
          if ( uLastPointedObjectID != 0 )
          {
            pFooterString[0] = 0;
            bForceDrawFooter = 1;
          }
        }
        uLastPointedObjectID = pMouse->uPointingObjectID;
        return;
      }
      v31 = pSpriteObjects[v30].stru_24.GetDisplayName();
      v28 = pTmpBuf;
      sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[470], v31);// "Get %s"
    }
    else
    {
      if (PID_TYPE(v18) != OBJECT_Actor)
      {
        if (PID_TYPE(v18) == OBJECT_Decoration)
        {
          v23 = &pLevelDecorations[v19];
          v24 = v23;
          v25 = v23->field_16_event_id;
          if ( !v25 )
          {
            if ( v23->IsInteractive() )
              v26 = pNPCTopics[stru_5E4C90._decor_events[v24->_idx_in_stru123 - 75] + 379].pTopic;
            else
              v26 = pDecorationList->pDecorations[v24->uDecorationDescID].field_20;
            //goto LABEL_87;
            GameUI_SetFooterString(v26);
            if ( pMouse->uPointingObjectID == 0 )
            {
              if ( uLastPointedObjectID != 0 )
              {
                pFooterString[0] = 0;
                bForceDrawFooter = 1;
              }
            }
            uLastPointedObjectID = pMouse->uPointingObjectID;
            return;
          }
          v22 = GetEventHintString(v25);
          if ( !v22 )
            //goto _return;
          {
            if ( pMouse->uPointingObjectID == 0 )
            {
              if ( uLastPointedObjectID != 0 )
              {
                pFooterString[0] = 0;
                bForceDrawFooter = 1;
              }
            }
            uLastPointedObjectID = pMouse->uPointingObjectID;
            return;
          }
          //goto LABEL_93;
          v26 = v22;
          //goto LABEL_87;
          GameUI_SetFooterString(v26);
          if ( pMouse->uPointingObjectID == 0 )
          {
            if ( uLastPointedObjectID != 0 )
            {
              pFooterString[0] = 0;
              bForceDrawFooter = 1;
            }
          }
          uLastPointedObjectID = pMouse->uPointingObjectID;
          return;
        }
        if (PID_TYPE(v18) == OBJECT_BModel)
        {
          if ( HIWORD(v18) < 512)
          {
            if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
            {
			  v18b = (signed int)(unsigned __int16)v18 >> 9;
              v21 = pOutdoor->pBModels[v18b].pFaces[v19 & 0x3F].sCogTriggeredID;
              //goto LABEL_71;
              if ( !v21 || (v22 = GetEventHintString(v21)) == 0 )
                //goto LABEL_73;
              {
                pMouse->uPointingObjectID = 0;
                //goto LABEL_50;
                uLastPointedObjectID = 1;
                if ( pMouse->uPointingObjectID == 0 )
                {
                  if ( uLastPointedObjectID != 0 )
                  {
                    pFooterString[0] = 0;
                    bForceDrawFooter = 1;
                  }
                }
                uLastPointedObjectID = pMouse->uPointingObjectID;
                return;
              }
              //goto LABEL_93;
              v26 = v22;
              //goto LABEL_87;
              GameUI_SetFooterString(v26);
              if ( pMouse->uPointingObjectID == 0 )
              {
                if ( uLastPointedObjectID != 0 )
                {
                  pFooterString[0] = 0;
                  bForceDrawFooter = 1;
                }
              }
              uLastPointedObjectID = pMouse->uPointingObjectID;
              return;
            }
            pFace = &pIndoor->pFaces[v19];
            if ( BYTE3(pFace->uAttributes) & 6 )
            {
              v21 = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
//LABEL_71:
              if ( !v21 || (v22 = GetEventHintString(v21)) == 0 )
                //goto LABEL_73;
              {
                pMouse->uPointingObjectID = 0;
                //goto LABEL_50;
                uLastPointedObjectID = 1;
                if ( pMouse->uPointingObjectID == 0 )
                {
                  if ( uLastPointedObjectID != 0 )
                  {
                    pFooterString[0] = 0;
                    bForceDrawFooter = 1;
                  }
                }
                uLastPointedObjectID = pMouse->uPointingObjectID;
                return;
              }
              //goto LABEL_93;
              v26 = v22;
              //goto LABEL_87;
              GameUI_SetFooterString(v26);
              if ( pMouse->uPointingObjectID == 0 )
              {
                if ( uLastPointedObjectID != 0 )
                {
                  pFooterString[0] = 0;
                  bForceDrawFooter = 1;
                }
              }
              uLastPointedObjectID = pMouse->uPointingObjectID;
              return;
            }
          }
//LABEL_73:
          pMouse->uPointingObjectID = 0;
          //goto LABEL_50;
          uLastPointedObjectID = 1;
          if ( pMouse->uPointingObjectID == 0 )
          {
            if ( uLastPointedObjectID != 0 )
            {
              pFooterString[0] = 0;
              bForceDrawFooter = 1;
            }
          }
          uLastPointedObjectID = pMouse->uPointingObjectID;
          return;
        }
//LABEL_61:
        pMouse->uPointingObjectID = 0;
        //goto _return;
        if ( pMouse->uPointingObjectID == 0 )
        {
          if ( uLastPointedObjectID != 0 )
          {
            pFooterString[0] = 0;
            bForceDrawFooter = 1;
          }
        }
        uLastPointedObjectID = pMouse->uPointingObjectID;
        return;
      }
      if ( v18 >= 335544320 )
        //goto LABEL_61;
      {
        pMouse->uPointingObjectID = 0;
        if ( pMouse->uPointingObjectID == 0 )
        {
          if ( uLastPointedObjectID != 0 )
          {
            pFooterString[0] = 0;
            bForceDrawFooter = 1;
          }
        }
        uLastPointedObjectID = pMouse->uPointingObjectID;
        return;
      }
      pActor = &pActors[v19];
      v28 = pTmpBuf;
      v29 = pActor->dword_000334_unique_name;
      if ( v29 )
        v40 = pMonsterStats->pPlaceStrings[v29];
      else
        v40 = pMonsterStats->pInfos[pActor->pMonsterInfo.uID].pName;
      strncpy(pTmpBuf, v40, 0x7D0u);
    }
    v26 = v28;
//LABEL_87:
    GameUI_SetFooterString(v26);
    //goto _return;
    if ( pMouse->uPointingObjectID == 0 )
    {
      if ( uLastPointedObjectID != 0 )
      {
        pFooterString[0] = 0;
        bForceDrawFooter = 1;
      }
    }
    uLastPointedObjectID = pMouse->uPointingObjectID;
    return;
  }
  v1 = uNumVisibleWindows;
  if ( uNumVisibleWindows > 0 )
  {
	  while ( 1 )                                   // some other fullscreen ui
	  {
		pWindow = &pWindowList[pVisibleWindowsIdxs[v1] - 1];
		if ( (signed int)pX >= (signed int)pWindow->uFrameX
		  && (signed int)pX <= (signed int)pWindow->uFrameZ
		  && (signed int)pY >= (signed int)pWindow->uFrameY
		  && (signed int)pY <= (signed int)pWindow->uFrameW )
		{
		  for ( pButton = pWindow->pControlsHead; ; pButton = pButton->pNext )
		  {
			if ( !pButton )
			  break;
			if ( pButton->uButtonType == 1 )
			{
			  if ( (signed int)pX >= (signed int)pButton->uX
				&& (signed int)pX <= (signed int)pButton->uZ
				&& (signed int)pY >= (signed int)pButton->uY
				&& (signed int)pY <= (signed int)pButton->uW )
			  {
	//LABEL_24:
				pMessageType1 = (UIMessageType)pButton->field_1C;
				if ( pMessageType1 )
				{
				  pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
				}
	//LABEL_28:
				v13 = pButton->pButtonName;
	//_set_status_and_ret:
				GameUI_SetFooterString(v13);
	//LABEL_131:
				uLastPointedObjectID = 1;
				return;
			  }
			}
			else
			{
			  if ( pButton->uButtonType == 2 )
			  {
				v45 = pX - pButton->uX;
				v45 = pY - pButton->uY;
				if ( (double)(signed int)pButton->uWidth != 0.0 )
				{
				  if ( (double)(signed int)pButton->uHeight != 0.0 )
				  {
					  pMessageType1 = (UIMessageType)pButton->field_1C;
					  if ( pMessageType1 )
					  {
						pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
					  }
					  v13 = pButton->pButtonName;
					  GameUI_SetFooterString(v13);
					  uLastPointedObjectID = 1;
					  return;
					//}
				  }
				}
			  }
			  else                                  // click on skill
			  {
				if ( pButton->uButtonType == 3
				  && (signed int)pX >= (signed int)pButton->uX
				  && (signed int)pX <= (signed int)pButton->uZ
				  && (signed int)pY >= (signed int)pButton->uY
				  && (signed int)pY <= (signed int)pButton->uW )
				{
	//LABEL_19:
				  pPlayer = pPlayers[uActiveCharacter];
				  v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
				  v6 = pPlayer->uSkillPoints;
				  v7 = (v5 & 0x3F) + 1;
				  if ( v6 < v7 )
				  {
					v41 = v7 - v6;
					v39 = pGlobalTXT_LocalizationStrings[469];// "You need %d more Skill Points to advance here"
				  }
				  else
				  {
					v41 = v7;
					v39 = pGlobalTXT_LocalizationStrings[468];// "Clicking here will spend %d Skill Points"
				  }
				  sprintf(Str1, v39, v41);
				  v13 = Str1;
				  //goto _set_status_and_ret;
				  GameUI_SetFooterString(v13);
				  uLastPointedObjectID = 1;
				  return;
				}
			  }
			}
		  }
		}
		if ( pWindow->uFrameHeight == 480 )
		  break;
		--v1;
		if ( v1 <= 0 )
		{
		  break;
		}
	  }
  }
  if ( uNumVisibleWindows <= 0 || (uNumVisibleWindows > 0 && pWindow->uFrameHeight != 480 && v1 <= 0))
  {
    if ( pCurrentScreen == SCREEN_CHEST )
    {
      sub_42038D();
      //goto _return;
      if ( pMouse->uPointingObjectID == 0 )
      {
        if ( uLastPointedObjectID != 0 )
        {
          pFooterString[0] = 0;
          bForceDrawFooter = 1;
        }
      }
      uLastPointedObjectID = pMouse->uPointingObjectID;
      return;
    }
    if ( pCurrentScreen == SCREEN_HOUSE )
    {
      if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD
        || (v16 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]], v16 == 0)
        || v16 == -65536 )
        //goto _return;
      {
        if ( pMouse->uPointingObjectID == 0 )
        {
          if ( uLastPointedObjectID != 0 )
          {
            pFooterString[0] = 0;
            bForceDrawFooter = 1;
          }
        }
        uLastPointedObjectID = pMouse->uPointingObjectID;
        return;
       }
      pItemGen = (ItemGen *)((char *)&pParty->pPickedItem + 36 * (v16 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 4);
//LABEL_49:
      v17 = pItemGen->GetDisplayName();
      GameUI_SetFooterString(v17);
//LABEL_50:
      uLastPointedObjectID = 1;
//_return:
      if ( pMouse->uPointingObjectID == 0 )
      {
        if ( uLastPointedObjectID != 0 )
        {
          pFooterString[0] = 0;
          bForceDrawFooter = 1;
        }
      }
      uLastPointedObjectID = pMouse->uPointingObjectID;
      return;
    }
    if ( (signed int)pY < 350 )
    {
      v14 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
      if ( v14 == 0 || v14 == -65536 || (unsigned int)v14 >= 0x1388 )
        //goto _return;
      {
        if ( pMouse->uPointingObjectID == 0 )
        {
          if ( uLastPointedObjectID != 0 )
          {
            pFooterString[0] = 0;
            bForceDrawFooter = 1;
          }
        }
        uLastPointedObjectID = pMouse->uPointingObjectID;
        return;
      }
      pItemGen = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItems[v14-1];
      //goto LABEL_49;
      v17 = pItemGen->GetDisplayName();
      GameUI_SetFooterString(v17);
      uLastPointedObjectID = 1;
      if ( pMouse->uPointingObjectID == 0 )
      {
        if ( uLastPointedObjectID != 0 )
        {
          pFooterString[0] = 0;
          bForceDrawFooter = 1;
        }
      }
      uLastPointedObjectID = pMouse->uPointingObjectID;
      return;
    }
_click_on_game_ui:
    if ( (signed int)pX >= (signed int)pWindowList[0].uFrameX
      && (signed int)pX <= (signed int)pWindowList[0].uFrameZ
      && (signed int)pY >= (signed int)pWindowList[0].uFrameY
      && (signed int)pY <= (signed int)pWindowList[0].uFrameW )
    {
      for ( pButton = pWindowList[0].pControlsHead; pButton != (GUIButton *)0; pButton = pButton->pNext )
      {
        if ( pButton->uButtonType == 1 )
        {
          if ( (signed int)pX >= (signed int)pButton->uX
            && (signed int)pX <= (signed int)pButton->uZ
            && (signed int)pY >= (signed int)pButton->uY
            && (signed int)pY <= (signed int)pButton->uW )
          {
            pMessageType3 = (UIMessageType)pButton->field_1C;
            if ( pMessageType3 == 0 ) // For books
              //goto LABEL_28;
            {
              v13 = pButton->pButtonName;
              GameUI_SetFooterString(v13);
              uLastPointedObjectID = 1;
              return;
            }

            pMessageQueue_50CBD0->AddMessage(pMessageType3, pButton->msg_param, 0);
            //goto LABEL_131;
            uLastPointedObjectID = 1;
            return;
          }
        }
        else
        {
          if ( pButton->uButtonType == 2 )
          {
            v45 = pX - pButton->uX;
            v45 = pY - pButton->uY;

            if (pX >= pButton->uX && pX <= pButton->uZ &&
                pY >= pButton->uY && pY <= pButton->uW)
            if ( (double)(signed int)pButton->uWidth != 0.0 )
            {
              if ( (double)(signed int)pButton->uHeight != 0.0 )
              {
                 //UNDEF(v32);
                //if ( v33 | v34 )
                //{
                  pMessageType2 = (UIMessageType)pButton->field_1C;
                  if ( pMessageType2 != 0 )
                      pMessageQueue_50CBD0->AddMessage(pMessageType2, pButton->msg_param, 0);

                  //goto LABEL_28;
                  v13 = pButton->pButtonName;
                  GameUI_SetFooterString(v13);
                  uLastPointedObjectID = 1;
                  return;
                //}
              }
            }
          }
          else
          {
            if ( pButton->uButtonType == 3
              && (signed int)pX >= (signed int)pButton->uX
              && (signed int)pX <= (signed int)pButton->uZ
              && (signed int)pY >= (signed int)pButton->uY
              && (signed int)pY <= (signed int)pButton->uW )
              //goto LABEL_19;
            {
              pPlayer = pPlayers[uActiveCharacter];
              v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
              v6 = pPlayer->uSkillPoints;
              v7 = (v5 & 0x3F) + 1;
              if ( v6 < v7 )
              {
                v41 = v7 - v6;
                v39 = pGlobalTXT_LocalizationStrings[469];// "You need %d more Skill Points to advance here"
              }
              else
              {
                v41 = v7;
                v39 = pGlobalTXT_LocalizationStrings[468];// "Clicking here will spend %d Skill Points"
              }
              sprintf(Str1, v39, v41);
              v13 = Str1;
              //goto _set_status_and_ret;
              GameUI_SetFooterString(v13);
              uLastPointedObjectID = 1;
              return;
            }
          }
        }
      }
    }
    pMouse->uPointingObjectID = sub_46A99B();
    //goto _return;
    if ( pMouse->uPointingObjectID == 0 )
    {
      if ( uLastPointedObjectID != 0 )
      {
        pFooterString[0] = 0;
        bForceDrawFooter = 1;
      }
    }
    uLastPointedObjectID = pMouse->uPointingObjectID;
    return;
  }
}


//----- (0044158F) --------------------------------------------------------
void GameUI_DrawCharacterSelectionFrame()
{
  if ( uActiveCharacter )
    pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[uActiveCharacter - 1] - 9, 380,
                                      pIcons_LOD->GetTexture(uTextureID_GameUI_CharSelectionFrame));
}



//----- (0044162D) --------------------------------------------------------
void GameUI_DrawPartySpells()
{
    unsigned int v0; // ebp@1
    //signed int v1; // edi@1
    //int v2; // eax@2
    //int v3; // ecx@5
    //__int16 *v4; // ebx@25
    //Player *v5; // edi@26
    //unsigned int v6; // [sp-4h] [bp-1Ch]@11
    Texture *v7; // [sp-4h] [bp-1Ch]@12
    //unsigned int v8; // [sp-4h] [bp-1Ch]@20
    Texture *v9; // [sp-4h] [bp-1Ch]@21
    //Player **v10; // [sp+10h] [bp-8h]@25

    v0 = (signed __int64)((double)GetTickCount() * 0.050000001);
    //v1 = 0;
    for (uint i = 0; i < 14; ++i)
        {
        //v2 =  byte_4E5DD8[v1];
        if (pParty->pPartyBuffs[byte_4E5DD8[i]].uExpireTime)
            {
            auto tex = pIcons_LOD->GetTexture(pTextureIDs_PartyBuffIcons[i]);
            //v3 = pTextureIDs_PartyBuffIcons[i];
                pRenderer->_4A65CC(pPartySpellbuffsUI_XYs[i][0],
                pPartySpellbuffsUI_XYs[i][1], tex, tex,
                v0 + 20 * pPartySpellbuffsUI_smthns[i], 0, 63);
            }
        //++v1;
        }
    //while ( v1 < 14 );

    if (pCurrentScreen == SCREEN_GAME || pCurrentScreen == SCREEN_NPC_DIALOGUE)
        {
        if (pParty->FlyActive())
            {
            if ( pParty->bFlying )
                v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, v0)->uTextureID);
            else
                v7 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, 0)->uTextureID);
            if ( pRenderer->pRenderD3D )
                pRenderer->DrawTextureIndexed(8, 8, v7);
            else
                pRenderer->DrawTextureTransparent(8, 8, v7);
            }
        if (pParty->WaterWalkActive())
            {
            if ( pParty->uFlags & PARTY_FLAGS_1_STANDING_ON_WATER)
                v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, v0)->uTextureID);
            else
                v9 = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, 0)->uTextureID);
            if ( pRenderer->pRenderD3D )
                pRenderer->DrawTextureIndexed(396u, 8u, v9);
            else
                pRenderer->DrawTextureTransparent(396u, 8u, v9);
            }
        }

    for (uint i = 0; i < 4; ++i)
        {
        auto player = pParty->pPlayers + i;

        if (player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime)
            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 427, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Hammerhands));
        if (player->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime)
            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 393, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Bless));
        if (player->pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime)
            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 410, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Preservation));
        if (player->pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].uExpireTime)
            pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 444, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_PainReflection));
        }
    }



//----- (004921C1) --------------------------------------------------------
void GameUI_DrawPortraits(unsigned int _this)
{
    Texture *pFace; // eax@10
    unsigned int v7; // eax@17
    PlayerFrame *pFrame; // eax@21
    unsigned int v9; // eax@27
    bool v10; // eax@33
    bool v11; // edi@40
    bool v12; // edx@43
    bool v13; // ecx@46
    int v16; // eax@57
    int v19; // eax@62
    Texture *pPortrait; // [sp-4h] [bp-1Ch]@27
    unsigned int v22; // [sp+14h] [bp-4h]@1

    v22 = _this;
    if ( qword_A750D8 )
        {
        qword_A750D8 -= (signed int)pMiscTimer->uTimeElapsed;
        if ( qword_A750D8 <= 0 )
            {
            if ( pPlayers[word_A750E2]->CanAct() )
                pPlayers[word_A750E2]->PlaySound((PlayerSpeech)word_A750E0, 0);
            qword_A750D8 = 0i64;
            }
        }

    for (uint i = 0; i < 4; ++i)
        {
        auto pPlayer = pParty->pPlayers + i;

        if (pPlayer->Eradicated())
            {
            pFace = pTexture_PlayerFaceEradicated;
            pPortrait = pFace;
            v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
            if ( pParty->pPartyBuffs[11].uExpireTime )
                pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
            else
                pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
            auto _v1 = 0;
            v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
            if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
                _v1 = 1;
            v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
            v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
            v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
            if ( v13 | v12 | v11 | _v1 | v10 )
                sub_441A4E(i);
            continue;
            }
        if (pPlayer->Dead())
            {
            pFace = pTexture_PlayerFaceDead;
            pPortrait = pFace;
            v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
            if ( pParty->pPartyBuffs[11].uExpireTime )
                pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
            else
                pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
            auto _v1 = 0;
            v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
            if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
                _v1 = 1;
            v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
            v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
            v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
            if ( v13 | v12 | v11 | _v1 | v10 )
                sub_441A4E(i);
            continue;
            }
        v7 = 0;
        for (uint j = 0; j < pPlayerFrameTable->uNumFrames; ++j)
            if (pPlayerFrameTable->pFrames[j].expression == pPlayer->expression)
                {
                v7 = j;
                break;
                }
            if ( v7 == 0 )
                v7 = 1;
            if (pPlayer->expression == CHARACTER_EXPRESSION_21)
                pFrame = pPlayerFrameTable->GetFrameBy_y(&pPlayer->_expression21_frameset, &pPlayer->_expression21_animtime, pMiscTimer->uTimeElapsed);
            else
                pFrame = pPlayerFrameTable->GetFrameBy_x(v7, pPlayer->uExpressionTimePassed);
            if (pPlayer->field_1AA2 != pFrame->uTextureID - 1 || v22 )
                {
                pPlayer->field_1AA2 = pFrame->uTextureID - 1;
                pFace = (Texture *)pTextures_PlayerFaces[i][pPlayer->field_1AA2];//pFace = (Texture *)pTextures_PlayerFaces[i][pFrame->uTextureID];
                pPortrait = pFace;
                v9 = pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i];
                if ( pParty->pPartyBuffs[11].uExpireTime )
                    pRenderer->_4A6E7E(v9, 0x183u, pPortrait);
                else
                    pRenderer->DrawTextureTransparent(v9 + 1, 0x184u, pPortrait);
                auto _v1 = 0;
                v10 = pPlayer->pPlayerBuffs[14].uExpireTime > 0;
                if (pPlayer->pPlayerBuffs[1].uExpireTime > 0)
                    _v1 = 1;
                v11 = pPlayer->pPlayerBuffs[8].uExpireTime > 0;
                v12 = pPlayer->pPlayerBuffs[7].uExpireTime > 0;
                v13 = pPlayer->pPlayerBuffs[13].uExpireTime > 0;
                if ( v13 | v12 | v11 | _v1 | v10 )
                    sub_441A4E(i);
                continue;
                }
        }
    if ( pParty->bTurnBasedModeOn == 1 )
        {
        if ( pTurnEngine->field_4 != 1 )
            {
            if (PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
                {
                //v14 = 0;
                if ( pTurnEngine->uActorQueueSize > 0 )
                    {
                    //v15 = (char *)pTurnEngine->pQueue;
                    for (uint i = 0; i < pTurnEngine->uActorQueueSize; ++i)
                        {
                        auto pElem = pTurnEngine->pQueue + i;

                        if (PID_TYPE(pElem->uPackedID) != OBJECT_Player)
                            break;
                        v16 = dword_5079D0;
                        if ( pParty->uFlags & 0x10 )
                            {
                            v16 = dword_5079CC;
                            }
                        else
                            {
                            if ( pParty->uFlags & 0x20 )
                                v16 = dword_5079C8;
                            }
                        pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[PID_ID(pElem->uPackedID)] - 4, 0x181u, pIcons_LOD->GetTexture(v16));
                        }
                    }
                }
            }
        }
    else
        {
        for (uint i = 0; i < 4; ++i)
            {
            auto pPlayer = pParty->pPlayers + i;
            if (pPlayer->CanAct() && !pPlayer->uTimeToRecovery)
                {
                v19 = dword_5079D0;
                if ( pParty->uFlags & 0x10 )
                    {
                    v19 = dword_5079CC;
                    }
                else
                    {
                    if ( pParty->uFlags & 0x20 )
                        v19 = dword_5079C8;
                    }
                pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] - 4, 0x181u, pIcons_LOD->GetTexture(v19));
                }
            }
        }
    }

//----- (00441D38) --------------------------------------------------------
void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap)
{
  int uHeight; // ebx@6
  __int16 v11; // cx@11
  unsigned int v14; // ebx@23
  int v15; // eax@23
  __int16 v17; // di@30
  double v18; // st7@30
  float v19; // ST38_4@30
  double v20; // st7@30
  double v21; // st6@30
  double v22; // st5@33
  signed int v27; // eax@37
  unsigned __int16 *v28; // ecx@37
  signed int v29; // edi@40
  //signed int v33; // ebx@50
  //unsigned int v34; // eax@50
  //signed int v35; // ecx@50
  //unsigned __int16 v36; // di@66
  int v37; // edi@72
  int v38; // ebx@72
  __int16 v39; // ax@87
  int v40; // edi@91
  int v41; // ebx@91
  unsigned int v42; // eax@101
  unsigned int v43; // ebx@101
  unsigned int v44; // ST30_4@101
  char *v45; // ebx@106
  int v46; // edi@108
  int v47; // eax@108
  unsigned int v48; // ebx@114
  unsigned int v49; // ST64_4@114
  //unsigned int v51; // [sp-10h] [bp-64h]@79
  unsigned int v52; // [sp-10h] [bp-64h]@100
  //unsigned int v53; // [sp-Ch] [bp-60h]@79
  unsigned int v54; // [sp-Ch] [bp-60h]@100
  //unsigned int v55; // [sp-8h] [bp-5Ch]@77
  unsigned int v56; // [sp-8h] [bp-5Ch]@100
  //signed int v57; // [sp-4h] [bp-58h]@54
  //unsigned __int16 v58; // [sp-4h] [bp-58h]@77
  unsigned __int16 v59; // [sp-4h] [bp-58h]@100
  //unsigned __int16 v60; // [sp+10h] [bp-44h]@66
  //unsigned int v61; // [sp+10h] [bp-44h]@85
  //unsigned int v63; // [sp+14h] [bp-40h]@85
  //unsigned int v65; // [sp+18h] [bp-3Ch]@85
  unsigned int lPitch; // [sp+20h] [bp-34h]@1
  unsigned int lPitcha; // [sp+20h] [bp-34h]@23
  char *lPitchb; // [sp+20h] [bp-34h]@106
  unsigned int v69; // [sp+24h] [bp-30h]@23
  signed int v70; // [sp+24h] [bp-30h]@37
  //unsigned __int16 uBlue; // [sp+28h] [bp-2Ch]@1
  signed int uBluea; // [sp+28h] [bp-2Ch]@37
  int v73; // [sp+2Ch] [bp-28h]@30
  int v76; // [sp+34h] [bp-20h]@91
  int v77; // [sp+34h] [bp-20h]@108
  //int v79; // [sp+38h] [bp-1Ch]@72
  //char *a2c; // [sp+40h] [bp-14h]@68
  signed int uCenterY; // [sp+48h] [bp-Ch]@1
  signed int uCenterX; // [sp+4Ch] [bp-8h]@1
  signed int uWidth; // [sp+5Ch] [bp+8h]@30
  //signed int uZe; // [sp+5Ch] [bp+8h]@67
  signed int uZf; // [sp+5Ch] [bp+8h]@85
  signed int uZg; // [sp+5Ch] [bp+8h]@105
  unsigned int uWa; // [sp+60h] [bp+Ch]@23
  float uWb; // [sp+60h] [bp+Ch]@30
  unsigned int uWd; // [sp+60h] [bp+Ch]@95
  float uZooma; // [sp+64h] [bp+10h]@117
  //unsigned int flagsb; // [sp+68h] [bp+14h]@66
  Actor *flagsc; // [sp+68h] [bp+14h]@86
  //unsigned int flagsd; // [sp+68h] [bp+14h]@105

  uCenterX = (uX + uZ) / 2;
  uCenterY = (uY + uW) / 2;
  lPitch = pRenderer->uTargetSurfacePitch;
  //TargetColor(0, 0, 0);
  //uBlue = TargetColor(0, 0, 0xFFu);
  auto bWizardEyeActive = pParty->WizardEyeActive();
  auto uWizardEyeSkillLevel = pParty->WizardEyeSkillLevel();
  if (CheckHiredNPCSpeciality(Cartographer))
  {
    bWizardEyeActive = true;
    uWizardEyeSkillLevel = 2;
  }
    bWizardEyeActive = true;
    uWizardEyeSkillLevel = 3;
  pRenderer->SetRasterClipRect(uX, uY, uZ - 1, uW - 1);
  uHeight = uW - uY;
  uWidth = uZ - uX;

  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor)
  {
    v17 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2;
    auto pMapLod0 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pLevelOfDetail0_prolly_alpha_mask;
    auto pPal = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pPalette16;
    v73 = (1 << (v17 + 16)) / (signed int)uZoom;
    v18 = (double)(1 << (16 - v17));
    v19 = v18;
    v20 = (double)(pParty->vPosition.x + 32768) / v18;
    v21 = (double)(32768 - pParty->vPosition.y) / v19;
    uWb = v21;
    switch (uZoom)
    {
      case 512:
      {
        v20 = v20 - (double)(uWidth / 2);
        v22 = (double)(uHeight / 2);
        uWb = v21 - v22;
      }
      break;

      case 1024:
      {
        v20 = v20 - (double)(uWidth / 4);
        v22 = (double)(uHeight / 4);
        uWb = v21 - v22;
      }
      break;

      case 2048:
      {
        v20 = v20 - (double)(uWidth / 8);
        v22 = (double)(uHeight / 8);
        uWb = v21 - v22;
      }
      break;

      default: assert(false);
    }
    assert(sizeof(pOdmMinimap) == 137 * 117 * sizeof(short));

    v70 = floorf(v20 * 65536.0 + 0.5f);//LODWORD(v24);
    uBluea = floorf(uWb * 65536.0 + 0.5f);//LODWORD(v25);
    v27 = uBluea >> 16;
    v28 = &pRenderer->pTargetSurface[uX + uY * lPitch];
    if (pMapLod0 && bRedrawOdmMinimap)
    {
      assert(uWidth == 137 && uHeight == 117);
      //auto pMinimap = (unsigned __int16 *)pOdmMinimap;

        auto mapWidth = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uTextureWidth;

          v29 = v70 >> 16;

          for (int y = 0; y < uHeight; ++y)
          {
              auto pMapLod0Line = &pMapLod0[v27 * mapWidth];
              for (int x = 0; x < uWidth; ++x)
              {
                //*pMinimap++ = pPal[pMapLod0Line[v29]];
                pOdmMinimap[y][x] = pPal[pMapLod0Line[v29]];
                v29 = (v70 + x * v73) >> 16;
              }

            v29 = v70 >> 16;
            v28 += 137 - uWidth;
            uBluea += v73;
            v27 = uBluea >> 16;
          }
    }

    for (int y = 0; y < 117; ++y)
    {
      for (int x = 0; x < 137; ++x)
      {
        *v28++ = pOdmMinimap[y][x];
      }
      v28 += lPitch - 137;
    }
    uNumBlueFacesInBLVMinimap = 0;
  }
  else
  {
    pRenderer->FillRectFast(uX, uY, uZ - uX, uHeight, 0xF);
    uNumBlueFacesInBLVMinimap = 0;

    for (uint i = 0; i < pIndoor->pMapOutlines->uNumOutlines; ++i)
    {
      auto pOutline = &pIndoor->pMapOutlines->pOutlines[i];

      auto pFace1 = pIndoor->pFaces + pOutline->uFace1ID;
      auto pFace2 = pIndoor->pFaces + pOutline->uFace2ID;
      //v9 = pIndoor->pFaces[pMapVertex->uFace1ID].uAttributes;
        //v10 = pIndoor->pFaces[pMapVertex->uFace2ID].uAttributes;
      if (pFace1->Visible() && pFace2->Visible())
      {
        v11 = pOutline->uFlags;
        if ( v11 & 1 )
          goto LABEL_15;
        if (pFace1->uAttributes & 0x80 || pFace2->uAttributes & 0x80)
          goto LABEL_ABC;

      }
      continue;

LABEL_ABC:
    pOutline->uFlags = v11 | 1;
    pIndoor->_visible_outlines[i >> 3] |= 1 << (7 - i % 8);

LABEL_15:
    //v12 = &pIndoor->pFaces[pOutline->uFace1ID];
    if (bWizardEyeActive && uWizardEyeSkillLevel >= 3 &&
        (pFace1->uAttributes & 0x2000 || pFace2->uAttributes & 0x2000) &&
        (pIndoor->pFaceExtras[pFace1->uFaceExtraID].uEventID || pIndoor->pFaceExtras[pFace2->uFaceExtraID].uEventID))
    {
      if (uNumBlueFacesInBLVMinimap < 49)
        pBlueFacesInBLVMinimapIDs[uNumBlueFacesInBLVMinimap++] = i;
    }
    else
    {
      auto _a = (uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x);
      auto _b = ((unsigned int)((unsigned __int64)_a >> 16) << 16);
      auto _c = ((signed int)(_b - uZoom * pParty->vPosition.x) >> 16);
      v69 =     uCenterX + _c;
      v69 =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
      lPitcha = uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
      uWa =     uCenterX + ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16) - uZoom * pParty->vPosition.x) >> 16);
      v14 =     uCenterY - ((signed int)(((unsigned int)((unsigned __int64)(uZoom * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16) - uZoom * pParty->vPosition.y) >> 16);
      v15 = abs(pOutline->sZ - pParty->vPosition.z) / 8;
      if ( v15 > 100 )
        v15 = 100;
      pRenderer->RasterLine2D(v69, lPitcha, uWa, v14, viewparams->pPalette[-v15 + 200]);
    }
  }


  for (uint i = 0; i < uNumBlueFacesInBLVMinimap; ++i)
  {
    //v16 = (uint *)&pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[uZb]];
    auto pOutline = &pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[i]];
    pRenderer->RasterLine2D(uCenterX + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].x) >> 16) << 16)
                  - uZoom * pParty->vPosition.x) >> 16),
      uCenterY
    - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex1ID].y) >> 16) << 16)
                  - uZoom * pParty->vPosition.y) >> 16),
      uCenterX
    + ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].x) >> 16) << 16)
                  - uZoom * pParty->vPosition.x) >> 16),
      uCenterY
    - ((signed int)(((unsigned int)((unsigned __int64)((signed int)uZoom
                                                     * (signed __int64)pIndoor->pVertices[pOutline->uVertex2ID].y) >> 16) << 16)
                  - uZoom * pParty->vPosition.y) >> 16),
      ui_game_minimap_outline_color);
  }
  }


  assert(pParty->sRotationY >= 0);
  float angle = (pParty->sRotationY % 2048) / 2048.0f;
  const float two_pi = 2.0f * 3.14159f;

  uint arrow_idx = floorf(0.5f + 7 * angle);
  pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[arrow_idx]));

  //flagsb = TargetColor(0, 0, 255);
  //v60 = TargetColor(255, 0, 0);
  if (bWizardEyeActive)
  {
    //uZe = 0;
    if (uWizardEyeSkillLevel >= 2)
      for (uint i = 0; i < uNumSpriteObjects; ++i)
    //if (uNumSpriteObjects > 0)
      {
        auto object = pSpriteObjects + i;

      //a2c = (char *)&pSpriteObjects[0].uObjectDescID;
      //while ( 1 )
      //{
      if (!object->uType || !object->uObjectDescID)
        continue;
      //if (uWizardEyeSkillLevel == 1
      v37 = uCenterX + ((unsigned __int64)((object->vPosition.x - pParty->vPosition.x) * (signed __int64)uZoom) >> 16);
      //v79 = (unsigned __int64)((object->vPosition.y - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16;
      //v38 = uCenterY - v79;
      v38 = uCenterY - ((signed __int64)((object->vPosition.y - pParty->vPosition.y) * (signed __int64)uZoom) >> 16);
      if (v37 < pRenderer->raster_clip_x || v37 > pRenderer->raster_clip_z ||
          v38 < pRenderer->raster_clip_y || v38 > pRenderer->raster_clip_w)
        continue;

      assert(uZoom >= 512);
      if (pObjectList->pObjects[object->uObjectDescID].uFlags & OBJECT_DESC_UNPICKABLE)
      {
        pRenderer->RasterLine2D(v37, v38, v37, v38, ui_game_minimap_projectile_color);
      }
      else if (uZoom > 512)
      {
        pRenderer->RasterLine2D(v37 - 1, v38 - 1, v37 - 1, v38 + 1, ui_game_minimap_treasure_color);
        pRenderer->RasterLine2D(v37, v38 - 2, v37, v38 + 1, ui_game_minimap_treasure_color);
        pRenderer->RasterLine2D(v37 + 1, v38 - 1, v37 + 1, v38 + 1, ui_game_minimap_treasure_color);
        pRenderer->RasterLine2D(v37 - 2, v38, v37 - 2, v38 + 1, ui_game_minimap_treasure_color);
        pRenderer->RasterLine2D(v37 + 2, v38,
                                v37 + 2, v38 + 1, ui_game_minimap_treasure_color);
      }
      else
      {
        pRenderer->RasterLine2D(v37 - 1, v38 - 1,
                                v37 - 1, v38, ui_game_minimap_treasure_color);
        pRenderer->RasterLine2D(v37, v38 - 1,
                                v37, v38, ui_game_minimap_treasure_color);
      }
//LABEL_82:
//LABEL_83:
        //++uZe;
        //a2c += 112;
        //if ( uZe >= (signed int)uNumSpriteObjects )
        //{
          //goto LABEL_85;
        //}
      //}
    }


LABEL_85:
    //v63 = TargetColor(255, 0, 0);
    //v61 = TargetColor(0, 255, 0);
    //v65 = TargetColor(255, 255, 0);
    uZf = 0;
    if ( (signed int)uNumActors > 0 )
    {
      flagsc = pActors;//[0].uAIState;
      do
      {
		v39 = flagsc->uAIState;
		if ( flagsc->uAIState != 11 && v39 != 19 && (v39 == 5 || BYTE1(flagsc->uAttributes) & 0x80) )
        {
		  v40 = ((unsigned __int64)(( flagsc->vPosition.x - pParty->vPosition.x)
                                  * (signed __int64)(signed int)uZoom) >> 16)
              + uCenterX;
          v76 = (unsigned __int64)(( flagsc->vPosition.y - pParty->vPosition.y)
                                 * (signed __int64)(signed int)uZoom) >> 16;
          v41 = uCenterY - v76;
          if ( v40 >= pRenderer->raster_clip_x )
          {
            if ( v40 <= pRenderer->raster_clip_z && v41 >= pRenderer->raster_clip_y && v41 <= pRenderer->raster_clip_w )
            {
              uWd = ui_game_minimap_actor_friendly_color;
			  if ( BYTE3(flagsc->uAttributes) & 1 )
                uWd = ui_game_minimap_actor_hostile_color;
              if ( flagsc->uAIState == Dead)
                uWd = ui_game_minimap_actor_corpse_color;
              if ( (signed int)uZoom > 1024 )
              {
                pRenderer->RasterLine2D(v40 - 1, v41 - 2, v40 - 1, v41 + 2, uWd);
                pRenderer->RasterLine2D(v40, v41 - 2, v40, v41 + 2, uWd);
                pRenderer->RasterLine2D(v40 + 1, v41 - 2, v40 + 1, v41 + 2, uWd);
                v42 = v41 + 1;
                v43 = v41 - 1;
                v44 = v42;
                pRenderer->RasterLine2D(v40 - 2, v43, v40 - 2, v42, uWd);
                v40 += 2;
                v59 = uWd;
                v56 = v44;
                v54 = v40;
                v52 = v43;
              }
              else
              {
                pRenderer->RasterLine2D(v40 - 1, v41 - 1, v40 - 1, uCenterY - v76, uWd);
                v59 = uWd;
                v56 = uCenterY - v76;
                v54 = v40;
                v52 = v41 - 1;
              }
              pRenderer->RasterLine2D(v40, v52, v54, v56, v59);
            }
          }
        }
        ++uZf;
        ++flagsc;
      }
      while ( uZf < (signed int)uNumActors );
    }
  }


  //flagsd = TargetColor(255, 255, 255);
  uZg = 0;
  if ( (signed int)uNumLevelDecorations > 0 )
  {
    v45 = (char *)&pLevelDecorations[0].vPosition;
    lPitchb = (char *)&pLevelDecorations[0].vPosition;
    do
    {
      if ( *(v45 - 2) & 8 )
      {
        v46 = ((unsigned __int64)((*(int *)v45 - pParty->vPosition.x) * (signed __int64)(signed int)uZoom) >> 16)
            + uCenterX;
        v77 = (unsigned __int64)((*((int *)v45 + 1) - pParty->vPosition.y) * (signed __int64)(signed int)uZoom) >> 16;
        v47 = uCenterY - v77;
        if ( v46 >= pRenderer->raster_clip_x )
        {
          if ( v46 <= pRenderer->raster_clip_z && v47 >= pRenderer->raster_clip_y && v47 <= pRenderer->raster_clip_w )
          {
            if ( (signed int)uZoom > 512 )
            {
              v48 = v47 + 1;
              v49 = v47 - 1;
              pRenderer->RasterLine2D(v46 - 1, v47 - 1, v46 - 1, v47 + 1, ui_game_minimap_decoration_color_1);
              pRenderer->RasterLine2D(v46, v49, v46, v48, ui_game_minimap_decoration_color_1);
              pRenderer->RasterLine2D(v46 + 1, v49, v46 + 1, v48, ui_game_minimap_decoration_color_1);
              v45 = lPitchb;
            }
            else
            {
              pRenderer->RasterLine2D(v46, uCenterY - v77, v46, uCenterY - v77, ui_game_minimap_decoration_color_1);
            }
          }
        }
      }
      ++uZg;
      v45 += 32;
      lPitchb = v45;
    }
    while ( uZg < (signed int)uNumLevelDecorations );
  }
  pRenderer->DrawTextureTransparent(0x1D4u, 0, pIcons_LOD->GetTexture(dword_5079D8));
  uZooma = (double)pParty->sRotationY * 0.1171875;
  //v50 = uZooma + 6.7553994e15;
  pRenderer->SetTextureClipRect(541, 0, 567, 480);
  pRenderer->DrawTextureIndexed(floorf(uZooma + 0.5f) + 285, 136, pIcons_LOD->GetTexture(dword_5079B4));
  pRenderer->ResetTextureClipRect();
}

//----- (00441498) --------------------------------------------------------
void __cdecl GameUI_DrawTorchlightAndWizardEye()
    {
    if (pCurrentScreen == SCREEN_GAME
        || pCurrentScreen == SCREEN_MENU
        || pCurrentScreen == SCREEN_OPTIONS
        || pCurrentScreen == SCREEN_REST
        || pCurrentScreen == SCREEN_SPELL_BOOK
        || pCurrentScreen == SCREEN_CHEST
        || pCurrentScreen == SCREEN_SAVEGAME
        || pCurrentScreen == SCREEN_LOADGAME
        || pCurrentScreen == SCREEN_CHEST_INVENTORY
        || pCurrentScreen == SCREEN_BOOKS
        || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
        {
        if (pParty->TorchlightActive())
            {
            auto icon = pIconsFrameTable->GetFrame((signed __int16)pUIAnum_Torchlight->uIconID, pEventTimer->Time());
            pRenderer->DrawTextureTransparent(pUIAnum_Torchlight->x, pUIAnum_Torchlight->y, pIcons_LOD->GetTexture(icon->uTextureID));
            }
        if (pParty->WizardEyeActive())
            {
            auto icon = pIconsFrameTable->GetFrame((signed __int16)pUIAnim_WizardEye->uIconID, pEventTimer->Time());
            pRenderer->DrawTextureTransparent(pUIAnim_WizardEye->x, pUIAnim_WizardEye->y, pIcons_LOD->GetTexture(icon->uTextureID));
            }
        }
    }
// 4E28F8: using guessed type int pCurrentScreen;


//----- (00491F87) --------------------------------------------------------
void GameUI_DrawHiredNPCs()
{
  //int v6; // eax@15
  char v7; // al@17
  unsigned int v8; // eax@18
  int v9; // esi@18
  int v10; // eax@18
  unsigned int v11; // eax@19
  unsigned int v12; // esi@19
  unsigned int v13; // eax@23
  IconFrame *v14; // eax@24
  unsigned int v15; // eax@26
  char pContainer[20]; // [sp+Ch] [bp-30h]@18
  unsigned int v17; // [sp+20h] [bp-1Ch]@19
  signed int uFrameID; // [sp+24h] [bp-18h]@19
  //int i; // [sp+28h] [bp-14h]@15
  unsigned int v20; // [sp+2Ch] [bp-10h]@20
  unsigned int v21; // [sp+30h] [bp-Ch]@19
  int v22; // [sp+34h] [bp-8h]@2
  unsigned __int8 v23; // [sp+3Bh] [bp-1h]@2

  if ( bNoNPCHiring != 1 )
  {
    v23 = 0;
    v22 = 0;
    /*for (uint i = 0; i < 2; ++i)
    { 
      if (pParty->pHirelings[i].pName)
        pTmpBuf[v22++] = i;
    }*/
    if (pParty->pHirelings[0].pName)
      pTmpBuf[v22++] = 0;
    if (pParty->pHirelings[1].pName)
      pTmpBuf[v22++] = 1;

    for (uint i = 0; i < pNPCStats->uNumNewNPCs; ++i)
    {
      if (pNPCStats->pNewNPCData[i].uFlags & 128)
      {
        if (!pParty->pHirelings[0].pName || strcmp(pNPCStats->pNewNPCData[i].pName, pParty->pHirelings[0].pName))
        {
          if (!pParty->pHirelings[1].pName || strcmp(pNPCStats->pNewNPCData[i].pName, pParty->pHirelings[1].pName))
            pTmpBuf[v22++] = i + 2;
        }
      }
    }

    //v6 = (unsigned __int8)pParty->field_709;
	for ( int i = (unsigned __int8)pParty->field_709; i < v22 && v23 < 2; i++ )
    {
      v7 = pTmpBuf[i];
      if ( (unsigned __int8)v7 >= 2 )
      {
        sprintf(pContainer, "NPC%03d", pNPCStats->pNPCData[(unsigned __int8)v7 + 499].uPortraitID);
        v15 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
        pRenderer->DrawTextureIndexed(pHiredNPCsIconsOffsetsX[v23], pHiredNPCsIconsOffsetsY[v23], pIcons_LOD->GetTexture(v15));
      }
      else
      {
        sprintf(pContainer, "NPC%03d", pParty->pHirelings[(unsigned __int8)v7].uPortraitID);
        v8 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
        v9 = v23;
        pRenderer->DrawTextureIndexed(pHiredNPCsIconsOffsetsX[v9], pHiredNPCsIconsOffsetsY[v9], pIcons_LOD->GetTexture(v8));
        v10 = (unsigned __int8)pTmpBuf[i];
        if ( pParty->pHirelings[v10].evt_A == 1 )
        {
          uFrameID = pParty->pHirelings[v10].evt_B;
          v11 = pHiredNPCsIconsOffsetsX[v9];
          v12 = pHiredNPCsIconsOffsetsY[v9];
          v17 = v11;
          v21 = 0;
          if ( (signed int)pIconsFrameTable->uNumIcons <= 0 )
          {
LABEL_23:
            v13 = 0;
          }
          else
          {
            v20 = 0;
            while ( _stricmp("spell96", pIconsFrameTable->pIcons[v20 / 0x20].pAnimationName) )
            {
              ++v21;
              v20 += 32;
              if ( (signed int)v21 >= (signed int)pIconsFrameTable->uNumIcons )
                goto LABEL_23;
            }
            v13 = v21;
          }
          v14 = pIconsFrameTable->GetFrame(v13, uFrameID);
          pRenderer->DrawTextureTransparent(v17, v12, &pIcons_LOD->pTextures[v14->uTextureID]);
        }
      }
      ++v23;
    }
  }
}
// 6BE3C5: using guessed type char bNoNPCHiring;