Mercurial > mm7
diff GUI/UI/UiGame.cpp @ 2501:0ff6a9e9bf7f
GUI folger
author | Ritor1 |
---|---|
date | Fri, 19 Sep 2014 04:21:12 +0600 |
parents | |
children | a77c34acdbc9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GUI/UI/UiGame.cpp Fri Sep 19 04:21:12 2014 +0600 @@ -0,0 +1,2260 @@ +#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> + +#define _CRT_SECURE_NO_WARNINGS +#include "..\../Engine/Events.h" +#include "..\../Engine/Graphics/Texture.h" +#include "..\../Engine/MM7.h" +#include "..\../Engine/ErrorHandling.h" + +#include "..\../Mouse.h" +#include "..\../Keyboard.h" +#include "..\../Engine/mm7_data.h" + +#include "..\../Engine/Graphics/Vis.h" +#include "..\../Engine/MapInfo.h" +#include "..\../Engine/Game.h" +#include "..\../GUIWindow.h" +#include "..\../GUIFont.h" +#include "..\../Engine/Party.h" +#include "..\../AudioPlayer.h" +#include "..\../Engine/Graphics/Outdoor.h" +#include "..\../Engine/LOD.h" +#include "..\../Engine/Objects/Actor.h" +#include "..\../Engine/Graphics/Viewport.h" +#include "..\../Engine/Objects/SpriteObject.h" +#include "..\../Engine/Objects/ObjectList.h" +#include "..\../Engine/Graphics/DecorationList.h" +#include "..\../Engine/Tables/PlayerFrameTable.h" +#include "..\../Engine/stru123.h" +#include "..\../Engine/Timer.h" +#include "..\../Engine/Tables/IconFrameTable.h" +#include "..\../Engine/TurnEngine/TurnEngine.h" +#include "..\../Engine/texts.h" +#include "UIHouses.h" +#include "..\../Engine/Graphics/BSPModel.h" +#include "..\../Engine/OurMath.h" +#include "..\../Engine/Graphics/Level/Decoration.h" +#include "..\../Engine/Objects/Chest.h" +#include "UIGame.h" + +#include "..\../Engine/Graphics/Overlays.h" + +#include "..\../Engine/Graphics/Sprites.h" +#include "..\../Engine/Graphics/PaletteManager.h" + +int uTextureID_GameUI_CharSelectionFrame; // 50C98C + +//----- (00421D00) -------------------------------------------------------- +void __fastcall GameUI_OnPlayerPortraitLeftClick(unsigned int uPlayerID) +{ + Player* player = &pParty->pPlayers[uPlayerID - 1]; + if (pParty->pPickedItem.uItemID) + { + if (int slot = player->AddItem(-1, pParty->pPickedItem.uItemID)) + { + memcpy(&player->pInventoryItemList[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); + } + + if (pCurrentScreen == SCREEN_GAME) + { + viewparams->bRedrawGameUI = true; + if ( uActiveCharacter != uPlayerID ) + { + if ( pPlayers[uPlayerID]->uTimeToRecovery ) + return; + + uActiveCharacter = uPlayerID; + return; + } + pGUIWindow_CurrentMenu = CharacterUI_Initialize(7); + return; + } + if ( pCurrentScreen == SCREEN_SPELL_BOOK ) + return; + if ( pCurrentScreen == SCREEN_CHEST ) + { + viewparams->bRedrawGameUI = true; + if ( uActiveCharacter == uPlayerID ) + { + pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103; + pCurrentScreen = SCREEN_CHEST_INVENTORY; + uActiveCharacter = uPlayerID; + return; + } + if ( pPlayers[uPlayerID]->uTimeToRecovery ) + return; + uActiveCharacter = uPlayerID; + return; + } + if ( pCurrentScreen != SCREEN_HOUSE ) + { + if ( pCurrentScreen == SCREEN_E ) + { + 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; + } + viewparams->bRedrawGameUI = true; + if ( uActiveCharacter == uPlayerID ) + { + pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103; + pCurrentScreen = SCREEN_CHEST_INVENTORY; + uActiveCharacter = uPlayerID; + return; + } + if ( pPlayers[uPlayerID]->uTimeToRecovery ) + return; + uActiveCharacter = uPlayerID; + return; + } + if ( window_SpeakInHouse->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS) + return; + viewparams->bRedrawGameUI = true; + if ( uActiveCharacter != uPlayerID ) + { + 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; + pGUIWindow_CurrentMenu = CharacterUI_Initialize(14); + 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 + NPCData *pNPC; // eax@16 + const CHAR *pText; // eax@18 + char *v11; // esi@26 + GUIWindow popup_window; // [sp+Ch] [bp-60h]@23 + int a2; // [sp+60h] [bp-Ch]@16 + LPCSTR lpsz; // [sp+68h] [bp-4h]@6 + + if ( bNoNPCHiring != 1 ) + { + v1 = 0; + /*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 ( uint 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 *)_this + pParty->hirelingScrollPosition) < v1 ) + { + sDialogue_SpeakingActorNPC_ID = -1 - pParty->hirelingScrollPosition - (int)_this; + pNPC = GetNewNPCData(sDialogue_SpeakingActorNPC_ID, &a2); + if ( pNPC ) + { + if ( a2 == 57 ) + pText = pNPCTopics[512].pText; // Baby dragon + else + pText = (const CHAR *)pNPCStats->pProfessions[pNPC->uProfession].pBenefits; + lpsz = pText; + if ( !pText ) + { + lpsz = (LPCSTR)pNPCStats->pProfessions[pNPC->uProfession].pJoinText; + if ( !lpsz ) + lpsz = ""; + } + popup_window.Hint = nullptr; + popup_window.uFrameX = 38; + popup_window.uFrameY = 60; + popup_window.uFrameWidth = 276; + popup_window.uFrameZ = 313; + popup_window.uFrameHeight = pFontArrus->CalcTextHeight(lpsz, &popup_window, 0, 0) + 2 * LOBYTE(pFontArrus->uFontHeight) + 24; + if ( (signed int)popup_window.uFrameHeight < 130 ) + popup_window.uFrameHeight = 130; + popup_window.uFrameWidth = 400; + popup_window.uFrameZ = popup_window.uFrameX + 399; + popup_window.DrawMessageBox(0); + sprintfex(pTmpBuf2.data(), "NPC%03d", pNPC->uPortraitID); + pRenderer->DrawTextureIndexed(popup_window.uFrameX + 22, popup_window.uFrameY + 36, + (Texture *)(pIcons_LOD->LoadTexture(pTmpBuf2.data(), TEXTURE_16BIT_PALETTE) != -1 + ? &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture(pTmpBuf2.data(), TEXTURE_16BIT_PALETTE)] : 0)); + if ( pNPC->uProfession ) + { + v11 = pTmpBuf.data(); + sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], pNPC->pName, aNPCProfessionNames[pNPC->uProfession]); + } + else + { + v11 = pTmpBuf.data(); + strcpy(pTmpBuf.data(), pNPC->pName); + } + popup_window.DrawTitleText(pFontArrus, 0, 12, Color16(0xFFu, 0xFFu, 0x9Bu), v11, 3); + popup_window.uFrameWidth -= 24; + popup_window.uFrameZ = popup_window.uFrameX + popup_window.uFrameWidth - 1; + popup_window.DrawText(pFontArrus, 100, 36, 0, BuildDialogueString((char *)lpsz, uActiveCharacter - 1, 0, 0, 0, 0), 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; + pNPCStats->dword_AE336C_LastMispronouncedNameFirstLetter = -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, window->GetWidth(), window->GetHeight(), WINDOW_Dialogue, 3, 0);//pNumberContacts = 1, v9 = 0; pNumberContacts = 2, v9 = 3; + if (pNPCInfo->Hired() && !pNPCInfo->bHasUsedTheAbility) + { + if (pNPCInfo->uProfession == 10 || //Healer + pNPCInfo->uProfession == 11 || //Expert Healer + pNPCInfo->uProfession == 12 || //Master Healer + pNPCInfo->uProfession == 33 || //Cook + pNPCInfo->uProfession == 34 || //Chef + pNPCInfo->uProfession == 39 || //Wind Master + pNPCInfo->uProfession == 40 || //Water Master + pNPCInfo->uProfession == 41 || //Gate Master + pNPCInfo->uProfession == 42 || //Chaplain + pNPCInfo->uProfession == 43 || //Piper + pNPCInfo->uProfession == 52 //Fallen Wizard + ) + { + 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 + int pTextHeight; // esi@39 + GUIButton *pButton; // eax@43 + int all_text_height; // ebx@93 + signed int index; // esi@99 + int v42; // edi@102 + int v45; + unsigned __int16 pTextColor; // ax@104 + GUIWindow window; // [sp+ACh] [bp-68h]@42 +// GUIFont *pOutString; // [sp+10Ch] [bp-8h]@39 + const char *pInString=nullptr; // [sp+110h] [bp-4h]@32 + + if ( !pDialogueWindow ) + return; + + // Window title(Заголовок окна)---- + memcpy(&window, pDialogueWindow, sizeof(window)); + pNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID); + pGreetType = GetGreetType(sDialogue_SpeakingActorNPC_ID); + window.uFrameWidth -= 10; + window.uFrameZ -= 10; + 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.data())); // sometimes buffer overflows; errors emerge both here and in dialogue text + sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429], pNPC->pName, aNPCProfessionNames[pNPC->uProfession]);//^Pi[%s] %s + } + else if (pNPC->pName) + strcpy(pTmpBuf.data(), pNPC->pName); + + window.DrawTitleText(pFontArrus, 483, 112, ui_game_dialogue_npc_name_color, pTmpBuf.data(), 3); + pParty->GetPartyFame(); + + pInString = nullptr; + switch (uDialogueType) + { + case DIALOGUE_13: + pInString = BuildDialogueString(pNPCStats->pProfessions[pNPC->uProfession].pJoinText, uActiveCharacter - 1, 0, 0, 0, 0); + break; + + case DIALOGUE_PROFESSION_DETAILS: + { + //auto prof = pNPCStats->pProfessions[pNPC->uProfession]; + + if (dialogue_show_profession_details) + pInString = BuildDialogueString(pNPCStats->pProfessions[pNPC->uProfession].pBenefits, uActiveCharacter - 1, 0, 0, 0, 0); + else if (pNPC->Hired()) + pInString = BuildDialogueString(pNPCStats->pProfessions[pNPC->uProfession].pDismissText, uActiveCharacter - 1, 0, 0, 0, 0); + else + pInString = BuildDialogueString(pNPCStats->pProfessions[pNPC->uProfession].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.data(), pGlobalTXT_LocalizationStrings[576], gold_transaction_amount);// "Congratulations on your win: here's your stuff: %u gold." + pInString = pTmpBuf.data(); + 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_EVT_E && !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].pGreeting2; + else + pInString = pNPCStats->pNPCGreetings[pNPC->greet].pGreeting1; + } + } + else if (pGreetType == 2)//HiredNPC_greet + { + NPCProfession* prof = &pNPCStats->pProfessions[pNPC->uProfession]; + + if (pNPC->Hired()) + pInString = BuildDialogueString(prof->pDismissText, uActiveCharacter - 1, 0, 0, 0, 0); + else + pInString = BuildDialogueString(prof->pJoinText, uActiveCharacter - 1, 0, 0, 0, 0); + } + break; + } + + // Message window(Окно сообщения)---- + if (pInString) + { + window.uFrameWidth = game_viewport_width; + window.uFrameZ = 452; + GUIFont* font = pFontArrus; + pTextHeight = pFontArrus->CalcTextHeight(pInString, &window, 13, 0) + 7; + if ( 352 - pTextHeight < 8 ) + { + font = pFontCreate; + pTextHeight = pFontCreate->CalcTextHeight(pInString, &window, 13, 0) + 7; + } + if (uTextureID_Leather != -1) + pRenderer->GetLeather(8, 352 - pTextHeight, &pIcons_LOD->pTextures[uTextureID_Leather], pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - pTextHeight); + pRenderer->DrawTextureIndexed(8, 347 - pTextHeight, pTexture_591428); + pDialogueWindow->DrawText(font, 13, 354 - pTextHeight, 0, FitTextInAWindow(pInString, font, &window, 13, 0), 0, 0, 0); + } + // Right panel(Правая панель)------- + memcpy(&window, pDialogueWindow, sizeof(window)); + window.uFrameX = 483; + window.uFrameWidth = 148; + window.uFrameZ = 334; + for (int i = window.pStartingPosActiveItem; i < window.pStartingPosActiveItem + window.pNumPresenceButton; ++i) + { + pButton = window.GetControl(i); + if ( !pButton ) + break; + + if ( pButton->msg_param > 88 ) + pButton->pButtonName[0] = 0; + else if (pButton->msg_param == 88) + strcpy(pButton->pButtonName, pGlobalTXT_LocalizationStrings[581]); // Lord + else if (pButton->msg_param == 87) + strcpy(pButton->pButtonName, pGlobalTXT_LocalizationStrings[580]); // Knight + else if (pButton->msg_param == 86) + strcpy(pButton->pButtonName, pGlobalTXT_LocalizationStrings[579]); // Squire + else if (pButton->msg_param == 85) + strcpy(pButton->pButtonName, pGlobalTXT_LocalizationStrings[578]); // Page + else if (pButton->msg_param == 77) + strcpy(pButton->pButtonName, pGlobalTXT_LocalizationStrings[407]); // Details + else if (pButton->msg_param == 76) + { + if (pNPC->Hired()) + sprintf(pButton->pButtonName, (const char*)pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s + else + strcpy(pButton->pButtonName, pGlobalTXT_LocalizationStrings[406]); // Hire + } + else if (pButton->msg_param == 24) + { + __debugbreak(); // learn conditions of this event + if (!pNPC->evt_F) + { + pButton->pButtonName[0] = 0; + pButton->msg_param = 0; + } + else + strcpy(pButton->pButtonName, pNPCTopics[pNPC->evt_F].pTopic); + } + else if (pButton->msg_param == 9) + strcpy(pButton->pButtonName, GetProfessionActionText(pNPC->uProfession)); + else if (pButton->msg_param == 19) // Scavenger Hunt + { + if (!pNPC->evt_A) + { + pButton->pButtonName[0] = 0; + pButton->msg_param = 0; + } + else + strcpy(pButton->pButtonName, pNPCTopics[pNPC->evt_A].pTopic); + } + else if (pButton->msg_param == 20) // Scavenger Hunt + { + if (!pNPC->evt_B) + { + pButton->pButtonName[0] = 0; + pButton->msg_param = 0; + } + else strcpy(pButton->pButtonName, pNPCTopics[pNPC->evt_B].pTopic); + } + else if (pButton->msg_param == 21) + { + //__debugbreak(); // learn conditions of this event + if (!pNPC->evt_C) + { + pButton->pButtonName[0] = 0; + pButton->msg_param = 0; + } + else strcpy(pButton->pButtonName, pNPCTopics[pNPC->evt_C].pTopic); + } + else if (pButton->msg_param == 22) + { + //__debugbreak(); // learn conditions of this event + if (!pNPC->evt_D) + { + pButton->pButtonName[0] = 0; + pButton->msg_param = 0; + } + else strcpy(pButton->pButtonName, pNPCTopics[pNPC->evt_D].pTopic); + } + else if (pButton->msg_param == 23) + { + //__debugbreak(); // learn conditions of this event + if (!pNPC->evt_E) + { + pButton->pButtonName[0] = 0; + pButton->msg_param = 0; + } + else strcpy(pButton->pButtonName, pNPCTopics[pNPC->evt_E].pTopic); + } + else if (pButton->msg_param == 13) + { + if (pNPC->Hired()) + sprintf(pButton->pButtonName, pGlobalTXT_LocalizationStrings[408], pNPC->pName); // Release %s + else + strcpy(pButton->pButtonName, pGlobalTXT_LocalizationStrings[122]); // Join + } + else + pButton->pButtonName[0] = 0; + + if (pParty->field_7B5_in_arena_quest && pParty->field_7B5_in_arena_quest != -1) + { + int num_dead_actors = 0; + pInString = nullptr; + 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(pButton->pButtonName, pGlobalTXT_LocalizationStrings[658]); // Collect Prize + } + } + + // Install Buttons(Установка кнопок)-------- + index = 0; + all_text_height = 0; + for ( int i = pDialogueWindow->pStartingPosActiveItem; + i < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++i ) + { + pButton = pDialogueWindow->GetControl(i); + if ( !pButton ) + break; + all_text_height += pFontArrus->CalcTextHeight(pButton->pButtonName, &window, 0, 0); + index++; + } + if ( index ) + { + v45 = (174 - all_text_height) / index; + if ( v45 > 32 ) + v45 = 32; + v42 = (174 - v45 * index - all_text_height)/ 2 - v45 / 2 + 138; + for ( int i = pDialogueWindow->pStartingPosActiveItem; + i < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++i ) + { + pButton = pDialogueWindow->GetControl(i); + if ( !pButton ) + break; + pButton->uY = (unsigned int)(v45 + v42); + pTextHeight = pFontArrus->CalcTextHeight(pButton->pButtonName, &window, 0, 0); + pButton->uHeight = pTextHeight; + v42 = pButton->uY + pTextHeight - 1; + pButton->uW = v42; + pTextColor = ui_game_dialogue_option_normal_color; + if ( pDialogueWindow->pCurrentPosActiveItem == i ) + pTextColor = ui_game_dialogue_option_highlight_color; + window.DrawTitleText(pFontArrus, 0, pButton->uY, pTextColor, pButton->pButtonName, 3); + } + } + pRenderer->DrawTextureIndexed(471, 445, pIcons_LOD->GetTexture(uExitCancelTextureId)); +} + +//----- (00444FBE) -------------------------------------------------------- +void GameUI_DrawBranchlessDialogue() +{ + int pTextHeight; // esi@4 + char Str[200]; // [sp+Ch] [bp-120h]@12 + GUIWindow BranchlessDlg_window; // [sp+D4h] [bp-58h]@4 + GUIFont *pFont; // [sp+128h] [bp-4h]@1 + + pFont = pFontArrus; + if ( current_npc_text && !byte_5B0938[0] ) + strcpy(byte_5B0938.data(), current_npc_text); + BranchlessDlg_window.uFrameWidth = game_viewport_width; + BranchlessDlg_window.uFrameZ = 452; + pTextHeight = pFontArrus->CalcTextHeight(byte_5B0938.data(), &BranchlessDlg_window, 12, 0) + 7; + if ( 352 - pTextHeight < 8 ) + { + pFont = pFontCreate; + pTextHeight = pFontCreate->CalcTextHeight(byte_5B0938.data(), &BranchlessDlg_window, 12, 0) + 7; + } + pRenderer->GetLeather(8, 352 - pTextHeight, pIcons_LOD->GetTexture(uTextureID_Leather), pIcons_LOD->GetTexture(uTextureID_Leather)->uTextureHeight - pTextHeight); + pRenderer->DrawTextureIndexed(8, 347 - pTextHeight, pTexture_591428); + pGUIWindow2->DrawText(pFont, 12, 354 - pTextHeight, 0, FitTextInAWindow(byte_5B0938.data(), pFont, &BranchlessDlg_window, 12, 0), 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.data(), pKeyActionMap->pPressedKeysBuffer); + sub_4452BB(); + return; + } + if ( pGUIWindow2->receives_keyboard_input_2 != WINDOW_INPUT_CANCELLED) + return; + pGUIWindow2->receives_keyboard_input_2 = WINDOW_INPUT_NONE; + memset(GameUI_Footer_TimedString.data(), 0, 0xC8u); + sub_4452BB(); + return; + } + if ( pGUIWindow2->ptr_1C == (void *)26 ) + { + sprintf(Str, "%s %s", GameUI_Footer_TimedString, pKeyActionMap->pPressedKeysBuffer); + pGUIWindow2->DrawText(pFontLucida, 13, 357, 0, Str, 0, 0, 0); + pGUIWindow2->DrawFlashingInputCursor(pFontLucida->GetLineWidth(Str) + 13, 357, pFontLucida); + return; + } + if ( pKeyActionMap->pPressedKeysBuffer[0] ) + { + pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_NONE); + memset(GameUI_Footer_TimedString.data(), 0, 0xC8u); + sub_4452BB(); + return; + } +} + +//----- (004443D5) -------------------------------------------------------- +const char *GameUI_GetMinimapHintText() +{ + double v3; // st7@1 + int v7; // eax@4 + const char *v14; // eax@8 + char *result; // eax@12 + unsigned int pMapID; // eax@14 + int global_coord_X; // [sp+10h] [bp-1Ch]@1 + int global_coord_Y; // [sp+14h] [bp-18h]@1 + unsigned int pY; // [sp+1Ch] [bp-10h]@1 + unsigned int pX; // [sp+28h] [bp-4h]@1 + + result = 0; + pMouse->GetClickPos(&pX, &pY); + v3 = 1.0 / (float)((signed int)viewparams->uMinimapZoom * 0.000015258789); + global_coord_X = (signed __int64)((double)(pX - 557) * v3 + (double)pParty->vPosition.x); + global_coord_Y = (signed __int64)((double)pParty->vPosition.y - (double)(pY - 74) * v3); + if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor || pOutdoor->uNumBModels <= 0 ) + { + pMapID = pMapStats->GetMapInfo(pCurrentMapName); + if ( pMapID == 0 ) + result = "No Maze Info for this maze on file!"; + else + result = pMapStats->pInfos[pMapID].pName; + } + else + { + for ( uint j = 0; j < (uint)pOutdoor->uNumBModels; ++j ) + { + v7 = int_get_vector_length(abs((signed)pOutdoor->pBModels[j].vBoundingCenter.x - global_coord_X), + abs((signed)pOutdoor->pBModels[j].vBoundingCenter.y - global_coord_Y), 0); + if ( v7 < 2 * pOutdoor->pBModels[j].sBoundingRadius ) + { + if ( pOutdoor->pBModels[j].uNumFaces ) + { + for ( uint i = 0; i < (uint)pOutdoor->pBModels[j].uNumFaces; ++i ) + { + if ( pOutdoor->pBModels[j].pFaces[i].sCogTriggeredID ) + { + if ( !(pOutdoor->pBModels[j].pFaces[i].uAttributes & FACE_HAS_EVENT) ) + { + v14 = GetEventHintString(pOutdoor->pBModels[j].pFaces[i].sCogTriggeredID); + if ( v14 ) + { + if ( _stricmp(v14, "") ) + result = (char *)v14; + } + } + } + } + } + if ( result ) + return result; + } + } + pMapID = pMapStats->GetMapInfo(pCurrentMapName); + if ( pMapID == 0 ) + result = "No Maze Info for this maze on file!"; + else + result = pMapStats->pInfos[pMapID].pName; + return result; + } + return result; +} + +//----- (0041D3B7) -------------------------------------------------------- +void GameUI_CharacterQuickRecord_Draw(GUIWindow *window, Player *player) +{ + Texture *v13; // eax@6 + PlayerFrame *v15; // eax@12 + unsigned int pTextColor; // eax@15 + const char *v29; // eax@16 + int v36; // esi@22 + const 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; + + window->uFrameHeight = ((pFontArrus->uFontHeight + 162) + ((numActivePlayerBuffs - 1) * pFontArrus->uFontHeight)); + window->uFrameZ = window->uFrameWidth + window->uFrameX - 1; + window->uFrameW = ((pFontArrus->uFontHeight + 162) + ((numActivePlayerBuffs - 1) * pFontArrus->uFontHeight)) + window->uFrameY - 1; + window->DrawMessageBox(0); + + if (player->IsEradicated()) + v13 = pTexture_PlayerFaceEradicated; + else if (player->IsDead()) + 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 + v15 = pPlayerFrameTable->GetFrameBy_x(uFramesetID, pMiscTimer->Time()); + 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.data(), "\f%05d", ui_character_header_text_color); + sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[429], player->pName, pClassNames[player->classType]); // "%s the %s" + strcat(pTmpBuf.data(), pTmpBuf2.data()); + strcat(pTmpBuf.data(), "\f00000\n"); + + pTextColor = UI_GetHealthManaAndOtherQualitiesStringColor(player->sHealth, player->GetMaxHealth()); + sprintfex(pTmpBuf2.data(), "%s : \f%05u%d\f00000 / %d\n", pGlobalTXT_LocalizationStrings[108], // "Hit Points" + pTextColor, player->sHealth, player->GetMaxHealth()); + strcat(pTmpBuf.data(), pTmpBuf2.data()); + + pTextColor = UI_GetHealthManaAndOtherQualitiesStringColor(player->sMana, player->GetMaxMana()); + sprintfex(pTmpBuf2.data(), "%s : \f%05u%d\f00000 / %d\n", pGlobalTXT_LocalizationStrings[212], // "Spell Points" + pTextColor, player->sMana, player->GetMaxMana()); + strcat(pTmpBuf.data(), pTmpBuf2.data()); + + pTextColor = player->GetMajorConditionIdx(); + sprintfex(pTmpBuf2.data(), "%s: \f%05d%s\f00000\n", pGlobalTXT_LocalizationStrings[47], // "Condition + GetConditionDrawColor(pTextColor), aCharacterConditionNames[pTextColor]); + strcat(pTmpBuf.data(), pTmpBuf2.data()); + + if ( player->uQuickSpell ) + v29 = pSpellStats->pInfos[player->uQuickSpell].pShortName; + else + v29 = pGlobalTXT_LocalizationStrings[153]; + sprintfex(pTmpBuf2.data(), "%s: %s", pGlobalTXT_LocalizationStrings[172], v29); // "Quick Spell" + strcat(pTmpBuf.data(), pTmpBuf2.data()); + + window->DrawText(pFontArrus, 120, 22, 0, pTmpBuf.data(), 0, 0, 0); + + uFramesetIDa = 0; + for (uint i = 0; i < 24; ++i) + { + SpellBuff* buff = &player->pPlayerBuffs[i]; + if (buff->uExpireTime > 0) + { + v36 = uFramesetIDa++ * pFontComic->uFontHeight + 134; + window->DrawText(pFontComic, 52, v36, ui_game_character_record_playerbuff_colors[i], aSpellNames[20 + i], 0, 0, 0); + DrawBuff_remaining_time_string(v36, window, buff->uExpireTime - pParty->uTimePlayed, pFontComic); + } + } + + v39 = ""; + if ( uFramesetIDa == 0 ) + v39 = pGlobalTXT_LocalizationStrings[153]; // "None" + sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[450], v39); // "Active Spells: %s" + window->DrawText(pFontArrus, 14, 114, 0, pTmpBuf.data(), 0, 0, 0); +} + +//----- (0041A57E) -------------------------------------------------------- +void GameUI_QuickRef_Draw() +{ + unsigned int pTextColor; // eax@7 + unsigned int pX; // [sp+14h] [bp-18h]@2 + unsigned int pY; // edi@9 + int pSkillsCount; // ecx@27 + const char *pText; // eax@38 + int pFontHeight; // [sp+18h] [bp-14h]@1 + + pRenderer->DrawTextureIndexed(8, 8, pIcons_LOD->LoadTexturePtr("quikref", TEXTURE_16BIT_PALETTE)); + pFontHeight = LOBYTE(pFontArrus->uFontHeight) + 1; + for ( uint i = 0; i < 4; ++i ) + { + Player* player = &pParty->pPlayers[i]; + pX = 94 * i + 89; + if ( i == 0 ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, 18, 0, pGlobalTXT_LocalizationStrings[149], 60, 0);//Name + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 94 * i + 89, 18, ui_character_header_text_color, player->pName, 84, 0); + if ( i == 0 ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, 47, 0, pGlobalTXT_LocalizationStrings[131], 60, 0); //Уров. + sprintf(pTmpBuf.data(), "%lu", player->GetActualLevel()); + if ( player->GetActualLevel() <= player->GetBaseLevel()) + pTextColor = player->GetExperienceDisplayColor(); + else + pTextColor = ui_character_bonus_text_color; + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, 47, pTextColor, pTmpBuf.data(), 84, 0); + pY = pFontHeight + 47; + if ( i == 0 ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pFontHeight + 47, 0, pGlobalTXT_LocalizationStrings[41], 60, 0);//Класс + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, 0, pClassNames[player->classType], 84, 0); + pY = pFontHeight + pY; + if ( i == 0 ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[107], 60, 0);//Здор. + sprintf(pTmpBuf.data(), "%d", player->sHealth); + pTextColor = UI_GetHealthManaAndOtherQualitiesStringColor(player->sHealth, player->GetMaxHealth()); + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, pTextColor, pTmpBuf.data(), 84, 0); + pY = pFontHeight + pY; + if ( i == 0 ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[209], 60, 0);//Мана + sprintf(pTmpBuf.data(), "%d", player->sMana); + pTextColor = UI_GetHealthManaAndOtherQualitiesStringColor(player->sMana, player->GetMaxMana()); + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, pTextColor, pTmpBuf.data(), 84, 0); + pY = pFontHeight + pY; + if ( i == 0 ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[0], 60, 0);//Класс брони + sprintf(pTmpBuf.data(), "%d", player->GetActualAC()); + pTextColor = UI_GetHealthManaAndOtherQualitiesStringColor(player->GetActualAC(), player->GetBaseAC()); + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, pTextColor, pTmpBuf.data(), 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[18], 60, 0);//Атака + sprintf(pTmpBuf.data(), "%+d", player->GetActualAttack(false)); + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, 0, pTmpBuf.data(), 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[66], 60, 0);//Повр. + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, 0, player->GetMeleeDamageString(), 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[203], 60, 0);// Стрелять + sprintf(pTmpBuf.data(), "%+d", player->GetRangedAttack()); + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, 0, pTmpBuf.data(), 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[66], 60, 0);//Повр. + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, 0, player->GetRangedDamageString(), 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[205], 60, 0);//Навыки + pSkillsCount = 0; + for ( uint j = 0; j <= 36; ++j ) + { + if ( player->pActiveSkills[j] ) + ++pSkillsCount; + } + sprintf(pTmpBuf.data(), "%lu", pSkillsCount); + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, 0, pTmpBuf.data(), 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[168], 60, 0);//Очки + sprintf(pTmpBuf.data(), "%lu", player->uSkillPoints); + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, player->uSkillPoints ? ui_character_bonus_text_color : ui_character_default_text_color, pTmpBuf.data(), 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[45], 60, 0);//Сост. + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, pTextColor, aCharacterConditionNames[player->GetMajorConditionIdx()], 84, 0); + pY = pFontHeight + pY; + if ( !i ) + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 22, pY, 0, pGlobalTXT_LocalizationStrings[170], 60, 0);//Б.Прим. + if (player->uQuickSpell) + pText = pSpellStats->pInfos[player->uQuickSpell].pShortName; + else + pText = pGlobalTXT_LocalizationStrings[153];//Нет + pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, pX, pY, 0, pText, 84, 0); + } + + if ( pParty->GetPartyReputation() >= 0 ) + { + if ( pParty->GetPartyReputation() <= 5 ) + pTextColor = ui_character_default_text_color; + else + pTextColor = ui_character_bonus_text_color_neg; + } + else + pTextColor = ui_character_bonus_text_color; + + sprintf(pTmpBuf.data(), "%s: \f%05d%s\f00000", pGlobalTXT_LocalizationStrings[180], pTextColor, GetReputationString(pParty->GetPartyReputation()));//Reputation + pGUIWindow_CurrentMenu->DrawText(pFontArrus, 22, 323, 0, pTmpBuf.data(), 0, 0, 0); + sprintf(pTmpBuf.data(), "\r261%s: %d", pGlobalTXT_LocalizationStrings[84], pParty->GetPartyFame());// Fame Слава + pGUIWindow_CurrentMenu->DrawText(pFontArrus, 0, 323, 0, pTmpBuf.data(), 0, 0, 0); +} + +//----- (0041AD6E) -------------------------------------------------------- +void GameUI_DrawRightPanelItems() +{ + if ( (unsigned long long)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 text_y; // esi@2 + + if ( uGameState != GAME_STATE_FINAL_WINDOW ) + { + text_y = _44100D_should_alter_right_panel() != 0 ? 381 : 322; + sprintf(pTmpBuf.data(), "\r087%lu", pParty->uNumFoodRations); + pPrimaryWindow->DrawText(pFontSmallnum, 0, text_y, uGameUIFontMain, pTmpBuf.data(), 0, 0, uGameUIFontShadow); + sprintf(pTmpBuf.data(), "\r028%lu", pParty->uNumGold); + pPrimaryWindow->DrawText(pFontSmallnum, 0, text_y, uGameUIFontMain, pTmpBuf.data(), 0, 0, uGameUIFontShadow); + } +} + +//----- (0041B0C9) -------------------------------------------------------- +void GameUI_DrawLifeManaBars() +{ + double v3; // st7@3 + double v7; // st7@25 + Texture *pTextureHealth; // [sp-4h] [bp-30h]@10 + Texture *pTextureMana; // [sp+Ch] [bp-20h]@1 + + pTextureMana = pIcons_LOD->GetTexture(uTextureID_BarBlue); + for (uint i = 0; i < 4; ++i) + { + if (pParty->pPlayers[i].sHealth > 0) + { + int v17 = 0; + if (i == 2 || i == 3) + v17 = 2; + v3 = (double)pParty->pPlayers[i].sHealth / (double)pParty->pPlayers[i].GetMaxHealth(); + if( v3 > 0.5 ) + { + if ( v3 > 1.0 ) + v3 = 1.0; + pTextureHealth = pIcons_LOD->GetTexture(uTextureID_BarGreen); + } + else if ( v3 > 0.25 ) + pTextureHealth = pIcons_LOD->GetTexture(uTextureID_BarYellow); + else if ( v3 > 0.0 ) + pTextureHealth = pIcons_LOD->GetTexture(uTextureID_BarRed); + if( v3 > 0.0 ) + { + pRenderer->SetTextureClipRect(v17 + pHealthBarPos[i], (signed __int64)((1.0 - v3) * pTextureHealth->uTextureHeight) + 402, + v17 + pHealthBarPos[i] + pTextureHealth->uTextureWidth, pTextureHealth->uTextureHeight + 402); + pRenderer->DrawTextureIndexed(v17 + pHealthBarPos[i], 402, pTextureHealth); + pRenderer->ResetTextureClipRect(); + } + } + if (pParty->pPlayers[i].sMana > 0) + { + v7 = pParty->pPlayers[i].sMana / (double)pParty->pPlayers[i].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) * pTextureMana->uTextureHeight) + 402, + v17 + pManaBarPos[i] + pTextureMana->uTextureWidth, pTextureMana->uTextureHeight + 402); + pRenderer->DrawTextureIndexed(v17 + pManaBarPos[i], 402, pTextureMana); + 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.data(); + else + { + if (!pFooterString[0]) + return; + v1 = pFooterString.data(); + } + + 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 + + v1 = pStr; + if ( pStr && strcmp(pStr, "test") && !IsBadStringPtrA(pStr, 1) && (*v1 || GameUI_Footer_TimeLeft) ) + { + if ( GameUI_Footer_TimeLeft ) + { + for ( int i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()); i > 450; i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()) ) + GameUI_Footer_TimedString[strlen(GameUI_Footer_TimedString.data()) - 1] = 0; + } + else + { + strcpy(pFooterString.data(), v1); + for ( int j = pFontLucida->GetLineWidth(pFooterString.data()); j > 450; j = pFontLucida->GetLineWidth(pFooterString.data()) ) + pFooterString[strlen(pFooterString.data()) - 1] = 0; + } + } +} + +//----- (0041C179) -------------------------------------------------------- +void GameUI_Footer() +{ + char *v1; // edi@5 + int v2; // eax@5 + int v6; // eax@9 + char v9; // zf@12 + + if ( pFooterString[0] || GameUI_Footer_TimeLeft || bForceDrawFooter ) + { + pRenderer->DrawTextureRGB(0, 352, pTexture_StatusBar); + if ( GameUI_Footer_TimeLeft ) + { + v1 = GameUI_Footer_TimedString.data(); + v2 = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()); + while ( v2 > 450 ) + { + GameUI_Footer_TimedString[strlen(GameUI_Footer_TimedString.data()) - 1] = 0; + v2 = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()); + } + } + else + { + v1 = pFooterString.data(); + v6 = pFontLucida->GetLineWidth(pFooterString.data()); + while ( v6 > 450 ) + { + pFooterString[strlen(pFooterString.data()) - 1] = 0; + v6 = pFontLucida->GetLineWidth(pFooterString.data()); + } + } + v9 = *v1 == 0; + bForceDrawFooter = 0; + if ( !v9 ) + pPrimaryWindow->DrawText(pFontLucida, pFontLucida->AlignText_Center(450, v1) + 11, 357, uGameUIFontMain, v1, 0, 0, uGameUIFontShadow); + } +} +// 5C35BC: using guessed type int bForceDrawFooter; +//----- (00420EFF) -------------------------------------------------------- +void GameUI_WritePointedObjectStatusString() +{ + GUIWindow *pWindow; // edi@7 + GUIButton *pButton; // ecx@11 + int requiredSkillpoints; // ecx@19 + enum UIMessageType pMessageType1; // esi@24 + int v14; // eax@41 + ItemGen *pItemGen; // ecx@44 + int v16; // ecx@46 + signed int pickedObjectPID; // eax@55 + signed int v18b; + signed int pickedObjectID; // ecx@63 + BLVFace *pFace; // eax@69 + const char *pText; // ecx@79 + enum UIMessageType pMessageType2; // esi@110 + enum UIMessageType pMessageType3; // edx@117 + char Str1[200]; // [sp+Ch] [bp-D4h]@129 + unsigned int pX; // [sp+D4h] [bp-Ch]@1 + unsigned int pY; // [sp+D8h] [bp-8h]@1 + + pMouse->uPointingObjectID = 0; + pMouse->GetClickPos(&pX, &pY); + if ( pX < 0 || pX > window->GetWidth() - 1 || pY < 0 || pY > window->GetHeight() - 1 ) + return; + if ( pCurrentScreen == SCREEN_GAME ) + { + if ( pX <= (window->GetWidth() - 1) * 0.73125 && pY <= (window->GetHeight() - 1) * 0.73125 ) + { + //if ( pRenderer->pRenderD3D ) // inlined mm8::4C1E01 + { + pickedObjectPID = pGame->pVisInstance->get_picked_object_zbuf_val(); + if ( pX < (unsigned int)pViewport->uScreen_TL_X || pX > (unsigned int)pViewport->uScreen_BR_X + || pY < (unsigned int)pViewport->uScreen_TL_Y || pY > (unsigned int)pViewport->uScreen_BR_Y ) + pickedObjectPID = -1; + if ( pickedObjectPID == -1 ) + { + if ( uLastPointedObjectID != 0 ) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + uLastPointedObjectID = 0; + return; + } + } + /*else + { + v18 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]]; + }*/ + pMouse->uPointingObjectID = (unsigned __int16)pickedObjectPID; + pickedObjectID = (signed)PID_ID(pickedObjectPID); + if ( PID_TYPE(pickedObjectPID) == OBJECT_Item ) + { + if ( pObjectList->pObjects[pSpriteObjects[pickedObjectID].uObjectDescID].uFlags & 0x10 ) + { + pMouse->uPointingObjectID = 0; + pFooterString[0] = 0; + bForceDrawFooter = 1; + uLastPointedObjectID = 0; + return; + } + if ( pickedObjectPID >= 0x2000000u || pParty->pPickedItem.uItemID ) + { + GameUI_SetFooterString(pSpriteObjects[pickedObjectID].stru_24.GetDisplayName()); + } + else + { + sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[470], pSpriteObjects[pickedObjectID].stru_24.GetDisplayName());// "Get %s" + GameUI_SetFooterString(pTmpBuf.data()); + } //intentional fallthrough + } + else if ( PID_TYPE(pickedObjectPID) == OBJECT_Decoration ) + { + if ( !pLevelDecorations[pickedObjectID].uEventID ) + { + if ( pLevelDecorations[pickedObjectID].IsInteractive() ) + pText = pNPCTopics[stru_5E4C90_MapPersistVars._decor_events[pLevelDecorations[pickedObjectID]._idx_in_stru123 - 75] + 380].pTopic;//неверно для костра + else + pText = pDecorationList->pDecorations[pLevelDecorations[pickedObjectID].uDecorationDescID].field_20; + GameUI_SetFooterString(pText); + } + else + { + char* hintString = GetEventHintString(pLevelDecorations[pickedObjectID].uEventID); + if ( hintString != '\0' ) + { + GameUI_SetFooterString(hintString); + } + } //intentional fallthrough + } + else if ( PID_TYPE(pickedObjectPID) == OBJECT_BModel ) + { + if ( pickedObjectPID < 0x2000000u ) + { + char* newString = nullptr; + if ( uCurrentlyLoadedLevelType != LEVEL_Indoor ) + { + v18b = (signed int)(unsigned __int16)pickedObjectPID >> 9; + short triggeredId = pOutdoor->pBModels[v18b].pFaces[pickedObjectID & 0x3F].sCogTriggeredID; + if (triggeredId != 0) + { + newString = GetEventHintString(pOutdoor->pBModels[v18b].pFaces[pickedObjectID & 0x3F].sCogTriggeredID); + } + } + else + { + pFace = &pIndoor->pFaces[pickedObjectID]; + if ( pFace->uAttributes & FACE_INDICATE ) + { + unsigned short eventId = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID; + if (eventId != 0) + { + newString = GetEventHintString(pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID); + } + } + } + if (newString) + { + GameUI_SetFooterString(newString); + if ( pMouse->uPointingObjectID == 0 && uLastPointedObjectID != 0) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + uLastPointedObjectID = pMouse->uPointingObjectID; + return; + } + } + pMouse->uPointingObjectID = 0; + pFooterString[0] = 0; + bForceDrawFooter = 1; + uLastPointedObjectID = 0; + return; + } + else if ( PID_TYPE(pickedObjectPID) == OBJECT_Actor ) + { + if ( pickedObjectPID >= 0x2000000 ) + { + pMouse->uPointingObjectID = 0; + if ( uLastPointedObjectID != 0 ) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + uLastPointedObjectID = 0; + return; + } + if ( pActors[pickedObjectID].dword_000334_unique_name ) + pText = pMonsterStats->pPlaceStrings[pActors[pickedObjectID].dword_000334_unique_name]; + else + pText = pMonsterStats->pInfos[pActors[pickedObjectID].pMonsterInfo.uID].pName; + GameUI_SetFooterString(pText); //intentional fallthrough + } + if ( pMouse->uPointingObjectID == 0 && uLastPointedObjectID != 0) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + uLastPointedObjectID = pMouse->uPointingObjectID; + return; + } + } + else + { + for (int i = uNumVisibleWindows; i > 0; --i) + { + pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 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 != nullptr; pButton = pButton->pNext ) + { + switch ( pButton->uButtonType ) + { + case 1://for dialogue window + 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 ) + { + pMessageType1 = (UIMessageType)pButton->field_1C; + if ( pMessageType1 ) + pMessageQueue_50CBD0->AddGUIMessage(pMessageType1, pButton->msg_param, 0); + GameUI_SetFooterString(pButton->pButtonName); + uLastPointedObjectID = 1; + return; + } + break; + case 2://hovering over portraits + if (pButton->uWidth != 0 && pButton->uHeight != 0) + { + uint distW = pX - pButton->uX; + uint distY = pY - pButton->uY; + + double ratioX = 1.0 * (distW*distW) / (pButton->uWidth*pButton->uWidth); + double ratioY = 1.0 * (distY*distY) / (pButton->uHeight*pButton->uHeight); + + if (ratioX + ratioY < 1.0) + { + pMessageType2 = (UIMessageType)pButton->field_1C; + if ( pMessageType2 != 0 ) + pMessageQueue_50CBD0->AddGUIMessage(pMessageType2, pButton->msg_param, 0); + GameUI_SetFooterString(pButton->pButtonName); // for character name + uLastPointedObjectID = 1; + return; + } + } + break; + case 3:// click on skill + if ( pX >= pButton->uX && pX <= pButton->uZ + && pY >= pButton->uY && pY <= pButton->uW ) + { + requiredSkillpoints = (LOBYTE(pPlayers[uActiveCharacter]->pActiveSkills[pButton->msg_param]) & 0x3F) + 1; + if ( pPlayers[uActiveCharacter]->uSkillPoints < requiredSkillpoints ) + sprintf(Str1, pGlobalTXT_LocalizationStrings[469], requiredSkillpoints - pPlayers[uActiveCharacter]->uSkillPoints);// "You need %d more Skill Points to advance here" + else + sprintf(Str1, pGlobalTXT_LocalizationStrings[468], requiredSkillpoints);// "Clicking here will spend %d Skill Points" + GameUI_SetFooterString(Str1); + uLastPointedObjectID = 1; + return; + } + break; + } + } + } + if ( pWindow->uFrameHeight == 480 ) + { + //DebugBreak(); //Why is this condition here (in the original too)? Might check fullscreen windows. Let Silvo know if you find out + return; + } + } + //The game never gets to this point even in the original. It's also bugged(neither branch displays anything). + //TODO fix these and move them up before the window check loop. + if ( pCurrentScreen == SCREEN_CHEST ) + { + Chest::ChestUI_WritePointedObjectStatusString(); + if ( uLastPointedObjectID != 0 ) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + uLastPointedObjectID = 0; + return; + } + else if ( pCurrentScreen == SCREEN_HOUSE ) + { + if ( dialog_menu_id != HOUSE_DIALOGUE_SHOP_BUY_STANDARD + || (v16 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]], v16 == 0) + || v16 == -65536 ) + { + if ( uLastPointedObjectID != 0 ) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + uLastPointedObjectID = 0; + return; + } + pItemGen = (ItemGen *)((char *)&pParty->pPickedItem + 36 * (v16 + 12 * (unsigned int)window_SpeakInHouse->ptr_1C) + 4); + GameUI_SetFooterString(pItemGen->GetDisplayName()); + pFooterString[0] = 0; + bForceDrawFooter = 1; + uLastPointedObjectID = 0; + return; + } + if ( pY < 350 ) + { + v14 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]]; + if ( v14 == 0 || v14 == -65536 || v14 >= 5000 ) + { + if ( pMouse->uPointingObjectID == 0 ) + { + if ( uLastPointedObjectID != 0 ) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + } + uLastPointedObjectID = pMouse->uPointingObjectID; + return; + } + pItemGen = (ItemGen *)&pPlayers[uActiveCharacter]->pInventoryItemList[v14-1]; + GameUI_SetFooterString(pItemGen->GetDisplayName()); + pFooterString[0] = 0; + bForceDrawFooter = 1; + uLastPointedObjectID = 0; + return; + } + } + 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 != nullptr; pButton = pButton->pNext ) + { + switch (pButton->uButtonType) + { + case 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 + { + GameUI_SetFooterString(pButton->pButtonName); + } + else + { + pMessageQueue_50CBD0->AddGUIMessage(pMessageType3, pButton->msg_param, 0); + } + uLastPointedObjectID = 1; + return; + } + break; + case 2://hovering over portraits + if (pButton->uWidth != 0 && pButton->uHeight != 0) + { + uint distW = pX - pButton->uX; + uint distY = pY - pButton->uY; + + double ratioX = 1.0 * (distW*distW) / (pButton->uWidth*pButton->uWidth); + double ratioY = 1.0 * (distY*distY) / (pButton->uHeight*pButton->uHeight); + + if (ratioX + ratioY < 1.0) + { + pMessageType2 = (UIMessageType)pButton->field_1C; + if ( pMessageType2 != 0 ) + pMessageQueue_50CBD0->AddGUIMessage(pMessageType2, pButton->msg_param, 0); + GameUI_SetFooterString(pButton->pButtonName); // for character name + uLastPointedObjectID = 1; + return; + } + } + break; + case 3: + if ( pX >= pButton->uX && pX <= pButton->uZ + && pY >= pButton->uY && pY <= pButton->uW ) + { + requiredSkillpoints = (LOBYTE(pPlayers[uActiveCharacter]->pActiveSkills[pButton->msg_param]) & 0x3F) + 1; + if ( pPlayers[uActiveCharacter]->uSkillPoints < requiredSkillpoints ) + sprintf(Str1, pGlobalTXT_LocalizationStrings[469], requiredSkillpoints - pPlayers[uActiveCharacter]->uSkillPoints);// "You need %d more Skill Points to advance here" + else + sprintf(Str1, pGlobalTXT_LocalizationStrings[468], requiredSkillpoints);// "Clicking here will spend %d Skill Points" + GameUI_SetFooterString(Str1); + uLastPointedObjectID = 1; + return; + } + break; + } + } + } + //pMouse->uPointingObjectID = sub_46A99B(); //for software + if ( uLastPointedObjectID != 0 ) + { + pFooterString[0] = 0; + bForceDrawFooter = 1; + } + uLastPointedObjectID = 0; + 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 + Texture *spell_texture; // [sp-4h] [bp-1Ch]@12 + //Texture *v9; // [sp-4h] [bp-1Ch]@21 + + 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) + { + Texture* 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 ) + spell_texture = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, v0)->uTextureID); + else + spell_texture = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_FlySpell, 0)->uTextureID); + //if ( pRenderer->pRenderD3D ) + pRenderer->DrawTextureIndexed(8, 8, spell_texture); + /*else + pRenderer->DrawTextureTransparent(8, 8, v7);*/ + } + if ( pParty->WaterWalkActive() ) + { + if ( pParty->uFlags & PARTY_FLAGS_1_STANDING_ON_WATER ) + spell_texture = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, v0)->uTextureID); + else + spell_texture = pIcons_LOD->GetTexture(pIconsFrameTable->GetFrame(uIconIdx_WaterWalk, 0)->uTextureID); + //if ( pRenderer->pRenderD3D ) + pRenderer->DrawTextureIndexed(396, 8, spell_texture); + /*else + pRenderer->DrawTextureTransparent(396, 8, v9);*/ + } + } + for (uint i = 0; i < 4; ++i) + { + if ( pParty->pPlayers[i].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime ) + pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 427, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Hammerhands)); + if ( pParty->pPlayers[i].pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime ) + pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 393, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Bless)); + if ( pParty->pPlayers[i].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].uExpireTime ) + pRenderer->DrawTextureIndexed(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 72, 410, pIcons_LOD->GetTexture(uTextureID_PlayerBuff_Preservation)); + if ( pParty->pPlayers[i].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) +{ + unsigned int face_expression_ID; // eax@17 + PlayerFrame *pFrame; // eax@21 + int pTextureID; // eax@57 + Texture *pPortrait; // [sp-4h] [bp-1Ch]@27 + + if ( _A750D8_player_speech_timer ) + { + _A750D8_player_speech_timer -= (signed int)pMiscTimer->uTimeElapsed; + if ( _A750D8_player_speech_timer <= 0 ) + { + if ( pPlayers[uSpeakingCharacter]->CanAct() ) + pPlayers[uSpeakingCharacter]->PlaySound(PlayerSpeechID, 0); + _A750D8_player_speech_timer = 0i64; + } + } + + for (uint i = 0; i < 4; ++i) + { + Player* pPlayer = &pParty->pPlayers[i]; + if ( pPlayer->IsEradicated() ) + { + pPortrait = pTexture_PlayerFaceEradicated; + if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime ) + pRenderer->DrawTranslucent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait); + else + pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait); + if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime + | pPlayer->pPlayerBuffs[PLAYER_BUFF_HEROISM].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_SHIELD].uExpireTime + | pPlayer->pPlayerBuffs[PLAYER_BUFF_STONESKIN].uExpireTime ) + sub_441A4E(i); + continue; + } + if (pPlayer->IsDead()) + { + pPortrait = pTexture_PlayerFaceDead; + if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime ) + pRenderer->DrawTranslucent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait); + else + pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait); + if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime + | pPlayer->pPlayerBuffs[PLAYER_BUFF_HEROISM].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_SHIELD].uExpireTime + | pPlayer->pPlayerBuffs[PLAYER_BUFF_STONESKIN].uExpireTime ) + sub_441A4E(i); + continue; + } + face_expression_ID = 0; + for ( uint j = 0; j < pPlayerFrameTable->uNumFrames; ++j ) + if ( pPlayerFrameTable->pFrames[j].expression == pPlayer->expression ) + { + face_expression_ID = j; + break; + } + if ( face_expression_ID == 0 ) + face_expression_ID = 1; + if (pPlayer->expression == CHARACTER_EXPRESSION_21) + pFrame = pPlayerFrameTable->GetFrameBy_y(&pPlayer->_expression21_frameset, &pPlayer->_expression21_animtime, pMiscTimer->uTimeElapsed); + else + pFrame = pPlayerFrameTable->GetFrameBy_x(face_expression_ID, pPlayer->uExpressionTimePassed); + if (pPlayer->field_1AA2 != pFrame->uTextureID - 1 || _this ) + { + pPlayer->field_1AA2 = pFrame->uTextureID - 1; + pPortrait = (Texture *)pTextures_PlayerFaces[i][pPlayer->field_1AA2];//pFace = (Texture *)pTextures_PlayerFaces[i][pFrame->uTextureID]; + if ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime ) + pRenderer->DrawTranslucent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i], 388, pPortrait); + else + pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] + 1, 388, pPortrait); + if ( pPlayer->pPlayerBuffs[PLAYER_BUFF_BLESS].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_HASTE].uExpireTime + | pPlayer->pPlayerBuffs[PLAYER_BUFF_HEROISM].uExpireTime | pPlayer->pPlayerBuffs[PLAYER_BUFF_SHIELD].uExpireTime + | pPlayer->pPlayerBuffs[PLAYER_BUFF_STONESKIN].uExpireTime ) + sub_441A4E(i); + continue; + } + } + if ( pParty->bTurnBasedModeOn == 1 ) + { + if ( pTurnEngine->turn_stage != TE_WAIT ) + { + if (PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player) + { + if ( pTurnEngine->uActorQueueSize > 0 ) + { + for (uint i = 0; i < (uint)pTurnEngine->uActorQueueSize; ++i) + { + if (PID_TYPE(pTurnEngine->pQueue[i].uPackedID) != OBJECT_Player) + break; + pTextureID = dword_5079D0; + if ( pParty->uFlags & 0x10 ) + pTextureID = dword_5079CC; + else + { + if ( pParty->uFlags & 0x20 ) + pTextureID = dword_5079C8; + } + pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[PID_ID(pTurnEngine->pQueue[i].uPackedID)] - 4, 385, pIcons_LOD->GetTexture(pTextureID)); + } + } + } + } + } + else + { + for (uint i = 0; i < 4; ++i) + { + if (pParty->pPlayers[i].CanAct() && !pParty->pPlayers[i].uTimeToRecovery) + { + pTextureID = dword_5079D0; + if ( pParty->uFlags & 0x10 ) + pTextureID = dword_5079CC; + else + { + if ( pParty->uFlags & 0x20 ) + pTextureID = dword_5079C8; + } + pRenderer->DrawTextureTransparent(pPlayerPortraitsXCoords_For_PlayerBuffAnimsDrawing[i] - 4, 385, pIcons_LOD->GetTexture(pTextureID)); + } + } + } +} + +//----- (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 + signed int pW; // ebx@23 + int v15; // eax@23 + double v20; // st7@30 + signed int v27; // eax@37 + //unsigned __int16 *v28; // ecx@37 + signed int v29; // edi@40 + int pPoint_X; // edi@72 + int pPoint_Y; // ebx@72 + unsigned int lPitch; // [sp+20h] [bp-34h]@1 + signed int pY; // [sp+20h] [bp-34h]@23 + signed int pX; // [sp+24h] [bp-30h]@23 + signed int v70; // [sp+24h] [bp-30h]@37 + signed int uBluea; // [sp+28h] [bp-2Ch]@37 + int v73; // [sp+2Ch] [bp-28h]@30 + 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 pZ; // [sp+60h] [bp+Ch]@23 + float uWb; // [sp+60h] [bp+Ch]@30 + unsigned int pColor; + + uCenterX = (uX + uZ) / 2; + uCenterY = (uY + uW) / 2; + lPitch = pRenderer->uTargetSurfacePitch; + bool bWizardEyeActive = pParty->WizardEyeActive(); + int uWizardEyeSkillLevel = pParty->WizardEyeSkillLevel(); + if ( CheckHiredNPCSpeciality(Cartographer) ) + { + bWizardEyeActive = true; + uWizardEyeSkillLevel = 2; + } + + if ( wizard_eye ) + { + bWizardEyeActive = true; + uWizardEyeSkillLevel = 3; + } + pRenderer->SetRasterClipRect(uX, uY, uZ - 1, uW - 1); + uHeight = uW - uY; + uWidth = uZ - uX; + + if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) + { + uchar* pMapLod0 = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pLevelOfDetail0_prolly_alpha_mask; + ushort* pPal = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].pPalette16; + v73 = (1 << (pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2 + 16)) / (signed int)uZoom; + v20 = (double)(pParty->vPosition.x + 32768) / (double)(1 << (16 - pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2)); + uWb = (double)(32768 - pParty->vPosition.y) / (double)(1 << (16 - pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uWidthLn2)); + switch (uZoom) + { + case 512: + { + v20 = v20 - (double)(uWidth / 2); + uWb = uWb - (double)(uHeight / 2); + } + break; + case 1024: + { + v20 = v20 - (double)(uWidth / 4); + uWb = uWb - (double)(uHeight / 4); + } + break; + case 2048: + { + v20 = v20 - (double)(uWidth / 8); + uWb = uWb - (double)(uHeight / 8); + } + break; + default: assert(false); + } + + static unsigned __int16 pOdmMinimap[117][137]; + 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; + + ushort mapWidth = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uTextureWidth; + + v29 = v70 >> 16; + for (int y = 0; y < uHeight; ++y) + { + uchar* pMapLod0Line = &pMapLod0[v27 * mapWidth]; + for (int x = 0; x < uWidth; ++x) + { + //*pMinimap++ = pPal[pMapLod0Line[v29]]; + pRenderer->WritePixel16(uX + x, uY + y, pPal[pMapLod0Line[v29]]); + v29 = (v70 + x * v73) >> 16; + } + uBluea += v73; + v27 = uBluea >> 16; + } + + /*v29 = v70 >> 16; + for (int y = 0; y < uHeight; ++y) + { + uchar* 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// uCurrentlyLoadedLevelType == LEVEL_Indoor + { + pRenderer->FillRectFast(uX, uY, uZ - uX, uHeight, 0xF); + uNumBlueFacesInBLVMinimap = 0; + + for (uint i = 0; i < (uint)pIndoor->pMapOutlines->uNumOutlines; ++i) + { + BLVMapOutline* pOutline = &pIndoor->pMapOutlines->pOutlines[i]; + //BLVFace* pFace1 = &pIndoor->pFaces[pOutline->uFace1ID]; + //BLVFace* pFace2 = &pIndoor->pFaces[pOutline->uFace2ID]; + if (pIndoor->pFaces[pOutline->uFace1ID].Visible() && pIndoor->pFaces[pOutline->uFace2ID].Visible()) + { + if ( pOutline->uFlags & 1 ) + { + if (bWizardEyeActive && uWizardEyeSkillLevel >= 3 && + (pIndoor->pFaces[pOutline->uFace1ID].Clickable() || pIndoor->pFaces[pOutline->uFace2ID].Clickable()) && + (pIndoor->pFaceExtras[pIndoor->pFaces[pOutline->uFace1ID].uFaceExtraID].uEventID || pIndoor->pFaceExtras[pIndoor->pFaces[pOutline->uFace2ID].uFaceExtraID].uEventID)) + { + if (uNumBlueFacesInBLVMinimap < 49) + pBlueFacesInBLVMinimapIDs[uNumBlueFacesInBLVMinimap++] = i; + } + else + { + pX = uCenterX + ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex1ID].x)) << 16) - uZoom * pParty->vPosition.x) >> 16); + pY = uCenterY - ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex1ID].y)) << 16) - uZoom * pParty->vPosition.y) >> 16); + pZ = uCenterX + ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex2ID].x)) << 16) - uZoom * pParty->vPosition.x) >> 16); + pW = uCenterY - ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex2ID].y)) << 16) - uZoom * pParty->vPosition.y) >> 16); + v15 = abs(pOutline->sZ - pParty->vPosition.z) / 8; + if ( v15 > 100 ) + v15 = 100; + pRenderer->RasterLine2D(pX, pY, pZ, pW, viewparams->pPalette[-v15 + 200]); + } + continue; + } + if (pIndoor->pFaces[pOutline->uFace1ID].uAttributes & FACE_UNKNOW4 || pIndoor->pFaces[pOutline->uFace2ID].uAttributes & FACE_UNKNOW4) + { + pOutline->uFlags = pOutline->uFlags | 1; + pIndoor->_visible_outlines[i >> 3] |= 1 << (7 - i % 8); + if (bWizardEyeActive && uWizardEyeSkillLevel >= 3 && + (pIndoor->pFaces[pOutline->uFace1ID].Clickable() || pIndoor->pFaces[pOutline->uFace2ID].Clickable()) && + (pIndoor->pFaceExtras[pIndoor->pFaces[pOutline->uFace1ID].uFaceExtraID].uEventID || pIndoor->pFaceExtras[pIndoor->pFaces[pOutline->uFace2ID].uFaceExtraID].uEventID)) + { + if (uNumBlueFacesInBLVMinimap < 49) + pBlueFacesInBLVMinimapIDs[uNumBlueFacesInBLVMinimap++] = i; + } + else + { + pX = uCenterX + ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex1ID].x)) << 16) - uZoom * pParty->vPosition.x) >> 16); + pY = uCenterY - ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex1ID].y)) << 16) - uZoom * pParty->vPosition.y) >> 16); + pZ = uCenterX + ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex2ID].x)) << 16) - uZoom * pParty->vPosition.x) >> 16); + pW = uCenterY - ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pIndoor->pMapOutlines->pOutlines[i].uVertex2ID].y)) << 16) - uZoom * pParty->vPosition.y) >> 16); + v15 = abs(pOutline->sZ - pParty->vPosition.z) / 8; + if ( v15 > 100 ) + v15 = 100; + pRenderer->RasterLine2D(pX, pY, pZ, pW, viewparams->pPalette[-v15 + 200]); + } + continue; + } + } + } + + for (uint i = 0; i < uNumBlueFacesInBLVMinimap; ++i) + { + BLVMapOutline* pOutline = &pIndoor->pMapOutlines->pOutlines[pBlueFacesInBLVMinimapIDs[i]]; + pX = uCenterX + ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pOutline->uVertex1ID].x)) << 16) - uZoom * pParty->vPosition.x) >> 16); + pY = uCenterY - ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pOutline->uVertex1ID].y)) << 16) - uZoom * pParty->vPosition.y) >> 16); + pZ = uCenterX + ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pOutline->uVertex2ID].x)) << 16) - uZoom * pParty->vPosition.x) >> 16); + pW = uCenterY - ((signed int)(((unsigned int)(fixpoint_mul(uZoom, pIndoor->pVertices[pOutline->uVertex2ID].y)) << 16) - uZoom * pParty->vPosition.y) >> 16); + pRenderer->RasterLine2D(pX, pY, pZ, pW, ui_game_minimap_outline_color); + } + } + + //draw arrow on the minimap(include. Ritor1) + uint arrow_idx; + unsigned int rotate = pParty->sRotationY & stru_5C6E00->uDoublePiMask; + if ( (signed int)rotate <= 1920 ) + arrow_idx = 6; + if ( (signed int)rotate < 1664 ) + arrow_idx = 5; + if ( (signed int)rotate <= 1408 ) + arrow_idx = 4; + if ( (signed int)rotate < 1152 ) + arrow_idx = 3; + if ( (signed int)rotate <= 896 ) + arrow_idx = 2; + if ( (signed int)rotate < 640 ) + arrow_idx = 1; + if ( (signed int)rotate <= 384 ) + arrow_idx = 0; + if ( (signed int)rotate < 128 || (signed int)rotate > 1920 ) + arrow_idx = 7; + pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[arrow_idx]));//стрелка + + //draw objects on the minimap + if ( bWizardEyeActive ) + { + if ( uWizardEyeSkillLevel >= 2 ) + { + for ( uint i = 0; i < uNumSpriteObjects; ++i ) + { + if ( !pSpriteObjects[i].uType || !pSpriteObjects[i].uObjectDescID ) + continue; + //if (uWizardEyeSkillLevel == 1 + pPoint_X = uCenterX + fixpoint_mul((pSpriteObjects[i].vPosition.x - pParty->vPosition.x), uZoom); + pPoint_Y = uCenterY - fixpoint_mul((pSpriteObjects[i].vPosition.y - pParty->vPosition.y), uZoom); + //if ( pPoint_X >= pRenderer->raster_clip_x && pPoint_X <= pRenderer->raster_clip_z && + // pPoint_Y >= pRenderer->raster_clip_y && pPoint_Y <= pRenderer->raster_clip_w) + { + if (pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & OBJECT_DESC_UNPICKABLE) + { + pRenderer->RasterLine2D(pPoint_X, pPoint_Y, pPoint_X, pPoint_Y, ui_game_minimap_projectile_color); + } + else if ( uZoom > 512 ) + { + pRenderer->RasterLine2D(pPoint_X - 2, pPoint_Y, pPoint_X - 2, pPoint_Y + 1, ui_game_minimap_treasure_color); + pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y + 1, ui_game_minimap_treasure_color); + pRenderer->RasterLine2D(pPoint_X, pPoint_Y - 2, pPoint_X, pPoint_Y + 1, ui_game_minimap_treasure_color); + pRenderer->RasterLine2D(pPoint_X + 1, pPoint_Y - 1, pPoint_X + 1, pPoint_Y + 1, ui_game_minimap_treasure_color); + pRenderer->RasterLine2D(pPoint_X + 2, pPoint_Y, pPoint_X + 2, pPoint_Y + 1, ui_game_minimap_treasure_color); + } + else + { + pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y, ui_game_minimap_treasure_color); + pRenderer->RasterLine2D(pPoint_X, pPoint_Y - 1, pPoint_X, pPoint_Y, ui_game_minimap_treasure_color); + } + } + } + } + for ( uint i = 0; i < uNumActors; ++i )//draw actors(отрисовка монстров и нпс) + { + if ( pActors[i].uAIState != Removed && pActors[i].uAIState != Disabled + && (pActors[i].uAIState == Dead || pActors[i].ActorNearby()) ) + { + pPoint_X = uCenterX + (fixpoint_mul((pActors[i].vPosition.x - pParty->vPosition.x), uZoom)); + pPoint_Y = uCenterY - (fixpoint_mul((pActors[i].vPosition.y - pParty->vPosition.y), uZoom)); + //if ( pPoint_X >= pRenderer->raster_clip_x && pPoint_X <= pRenderer->raster_clip_z + // && pPoint_Y >= pRenderer->raster_clip_y && pPoint_Y <= pRenderer->raster_clip_w ) + { + pColor = ui_game_minimap_actor_friendly_color; + if ( pActors[i].uAttributes & ACTOR_HOSTILE ) + pColor = ui_game_minimap_actor_hostile_color; + if ( pActors[i].uAIState == Dead) + pColor = ui_game_minimap_actor_corpse_color; + if ( uZoom > 1024 ) + { + pRenderer->RasterLine2D(pPoint_X - 2, pPoint_Y - 1, pPoint_X - 2, pPoint_Y + 1, pColor); + pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 2, pPoint_X - 1, pPoint_Y + 2, pColor); + pRenderer->RasterLine2D(pPoint_X, pPoint_Y - 2, pPoint_X, pPoint_Y + 2, pColor); + pRenderer->RasterLine2D(pPoint_X + 1, pPoint_Y - 2, pPoint_X + 1, pPoint_Y + 2, pColor); + pRenderer->RasterLine2D(pPoint_X + 2, pPoint_Y - 1, pPoint_X + 2, pPoint_Y + 1, pColor); + } + else + { + pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y, pColor); + pRenderer->RasterLine2D(pPoint_X, pPoint_Y - 1, pPoint_X, pPoint_Y, pColor); + } + } + } + } + for ( uint i = 0; i < (signed int)uNumLevelDecorations; ++i )//draw items(отрисовка предметов) + { + if ( pLevelDecorations[i].uFlags & 8 ) + { + pPoint_X = uCenterX + (fixpoint_mul((pLevelDecorations[i].vPosition.x - pParty->vPosition.x), uZoom)); + pPoint_Y = uCenterY - (fixpoint_mul((pLevelDecorations[i].vPosition.y - pParty->vPosition.y), uZoom)); + //if ( pPoint_X >= pRenderer->raster_clip_x && pPoint_X <= pRenderer->raster_clip_z + // && pPoint_Y >= pRenderer->raster_clip_y && pPoint_Y <= pRenderer->raster_clip_w ) + { + if ( (signed int)uZoom > 512 ) + { + pRenderer->RasterLine2D(pPoint_X - 1, pPoint_Y - 1, pPoint_X - 1, pPoint_Y + 1, ui_game_minimap_decoration_color_1); + pRenderer->RasterLine2D(pPoint_X, pPoint_Y - 1, pPoint_X, pPoint_Y + 1, ui_game_minimap_decoration_color_1); + pRenderer->RasterLine2D(pPoint_X + 1, pPoint_Y - 1, pPoint_X + 1, pPoint_Y + 1, ui_game_minimap_decoration_color_1); + } + else + pRenderer->RasterLine2D(pPoint_X, pPoint_Y, pPoint_X, pPoint_Y, ui_game_minimap_decoration_color_1); + } + } + } + } + pRenderer->DrawTextureTransparent(468, 0, pIcons_LOD->GetTexture(uTextureID_Minimap_Loop));//draw minimap_loop + pRenderer->SetTextureClipRect(541, 0, 567, 480); + pRenderer->DrawTextureIndexed(floorf(((double)pParty->sRotationY * 0.1171875) + 0.5f) + 285, 136, pIcons_LOD->GetTexture(uTextureID_Compas));//draw compas + pRenderer->ResetTextureClipRect(); +} + +//----- (00441498) -------------------------------------------------------- +void 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()) + { + IconFrame* 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()) + { + IconFrame* 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() +{ + unsigned int v13; // eax@23 + char pContainer[20]; // [sp+Ch] [bp-30h]@18 + signed int uFrameID; // [sp+24h] [bp-18h]@19 + int v22; // [sp+34h] [bp-8h]@2 + unsigned __int8 pNPC_limit_ID; // [sp+3Bh] [bp-1h]@2 + + if ( bNoNPCHiring != 1 ) + { + pNPC_limit_ID = 0; + v22 = 0; + 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; + } + } + } + + for ( int i = pParty->hirelingScrollPosition; i < v22 && pNPC_limit_ID < 2; i++ ) + { + if ( (unsigned __int8)pTmpBuf[i] >= 2 ) + { + sprintf(pContainer, "NPC%03d", pNPCStats->pNPCData[(unsigned __int8)pTmpBuf[i] + 499].uPortraitID); + pRenderer->DrawTextureIndexed(pHiredNPCsIconsOffsetsX[pNPC_limit_ID], pHiredNPCsIconsOffsetsY[pNPC_limit_ID], + pIcons_LOD->GetTexture(pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE))); + } + else + { + sprintf(pContainer, "NPC%03d", pParty->pHirelings[(unsigned __int8)pTmpBuf[i]].uPortraitID); + pRenderer->DrawTextureIndexed(pHiredNPCsIconsOffsetsX[pNPC_limit_ID], pHiredNPCsIconsOffsetsY[pNPC_limit_ID], + pIcons_LOD->GetTexture(pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE))); + if ( pParty->pHirelings[(unsigned __int8)pTmpBuf[i]].evt_A == 1 ) + { + uFrameID = pParty->pHirelings[(unsigned __int8)pTmpBuf[i]].evt_B; + v13 = 0; + if (pIconsFrameTable->uNumIcons) + { + for ( v13 = 0; v13 < pIconsFrameTable->uNumIcons; ++v13 ) + { + if ( !_stricmp("spell96", pIconsFrameTable->pIcons[v13].pAnimationName) ) + break; + } + } + pRenderer->DrawTextureTransparent(pHiredNPCsIconsOffsetsX[pNPC_limit_ID], pHiredNPCsIconsOffsetsY[pNPC_limit_ID], + &pIcons_LOD->pTextures[pIconsFrameTable->GetFrame(v13, uFrameID)->uTextureID]); + } + } + ++pNPC_limit_ID; + } + } +} + +//----- (004178FE) -------------------------------------------------------- +unsigned int UI_GetHealthManaAndOtherQualitiesStringColor(signed int current_pos, signed int base_pos) +{ + unsigned __int16 R, G, B; + + if ( current_pos <= base_pos ) + { + if ( current_pos == base_pos )//White + return 0; + if ( 100 * current_pos / base_pos >= 25 )//Yellow( current_pos > 1/4 ) + R = 255, G = 255, B = 100; + else//Red( current_pos < 1/4 ) + R = 255, G = 0, B = 0; + } + else//Green + R = 0, G = 255, B = 0; + return Color16(R, G, B); +} + +//----- (00417939) -------------------------------------------------------- +int GetConditionDrawColor(unsigned int uConditionIdx) +{ + switch (uConditionIdx) + { + case Condition_Zombie: + case Condition_Good: + return ui_character_condition_normal_color; + + case Condition_Cursed: + case Condition_Weak: + case Condition_Fear: + case Condition_Drunk: + case Condition_Insane: + case Condition_Poison_Weak: + case Condition_Disease_Weak: + return ui_character_condition_light_color; + + case Condition_Sleep: + case Condition_Poison_Medium: + case Condition_Disease_Medium: + case Condition_Paralyzed: + case Condition_Unconcious: + return ui_character_condition_moderate_color; + + case Condition_Poison_Severe: + case Condition_Disease_Severe: + case Condition_Dead: + case Condition_Pertified: + case Condition_Eradicated: + return ui_character_condition_severe_color; + } + Error("Invalid condition (%u)", uConditionIdx); +} + +//----- (00495430) -------------------------------------------------------- +const char * GetReputationString(signed int a1) +{ + if (a1 >= 25) + return pGlobalTXT_LocalizationStrings[379]; // Hated + else if (a1 >= 6) + return pGlobalTXT_LocalizationStrings[392]; // Unfriendly + else if (a1 >= -5) + return pGlobalTXT_LocalizationStrings[399]; // Neutral; + else if (a1 >= -24) + return pGlobalTXT_LocalizationStrings[402]; // Friendly + else + return pGlobalTXT_LocalizationStrings[434]; // Respected; +} + +//----- (00441A4E) -------------------------------------------------------- +__int16 __fastcall sub_441A4E(int a1)//for blessing +{ + __int16 result; // ax@1 + int v2; // ebx@1 + // char *v3; // esi@1 + // int v4; // edi@4 + bool v5; // ecx@4 + SpriteFrame *pFrame; // eax@6 + //SpriteFrame *v7; // edi@6 + int v8; // eax@6 + // unsigned __int16 v9; // ax@6 + RenderBillboardTransform_local0 v10; // [sp+Ch] [bp-5Ch]@1 + int v11; // [sp+5Ch] [bp-Ch]@6 + int v12; // [sp+60h] [bp-8h]@1 + //int v13; // [sp+64h] [bp-4h]@6 + + v10.sParentBillboardID = -1; + v10.pTarget = pRenderer->pTargetSurface; + v10.pTargetZ = pRenderer->pActiveZBuffer; + v10.uTargetPitch = pRenderer->GetRenderWidth(); + result = 0; + v2 = a1; + v10.uViewportX = 0; + v10.uViewportY = 0; + v10.uViewportZ = window->GetWidth() - 1; + v10.uViewportW = window->GetHeight() - 1; + v12 = 0; + //v3 = (char *)&pOtherOverlayList->pOverlays[0].field_C; + //do + for (uint i = 0; i < 50; ++i) + { + if (pOtherOverlayList->pOverlays[i].field_6 > 0) + { + result = pOtherOverlayList->pOverlays[i].field_0; + if (pOtherOverlayList->pOverlays[i].field_0 >= 300) + { + //v4 = result; + v5 = pOtherOverlayList->pOverlays[i].field_0 == v2 + 320 + || pOtherOverlayList->pOverlays[i].field_0 == v2 + 330 + || pOtherOverlayList->pOverlays[i].field_0 == v2 + 340 + || pOtherOverlayList->pOverlays[i].field_0 == v2 + 350; + pOtherOverlayList->pOverlays[i].field_0 = v2 + 310; + if (pOtherOverlayList->pOverlays[i].field_0 == v2 + 310 || v5) + { + if (!pOtherOverlayList->pOverlays[i].field_0) + { + pFrame = pSpriteFrameTable->GetFrame(pOverlayList->pOverlays[pOtherOverlayList->pOverlays[i].field_2].uSpriteFramesetID, + pOtherOverlayList->pOverlays[i].field_4); + //v7 = v6; + v11 = pOtherOverlayList->pOverlays[i].field_E; + //v13 = pFrame->scale; + //v13 = fixpoint_mul(v11, pFrame->scale); + v10.uScreenSpaceX = pOtherOverlayList->pOverlays[i].field_8; + v10.uScreenSpaceY = pOtherOverlayList->pOverlays[i].field_A; + v10._screenspace_x_scaler_packedfloat = fixpoint_mul(v11, pFrame->scale); + v10._screenspace_y_scaler_packedfloat = fixpoint_mul(v11, pFrame->scale); + v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(pFrame->uPaletteIndex, 0, 1); + v8 = pOtherOverlayList->pOverlays[i].field_2; + v10.sZValue = 0; + v10.uFlags = 0; + //v9 = pOverlayList->pOverlays[v8].uOverlayType; + if (!pOverlayList->pOverlays[v8].uOverlayType || pOverlayList->pOverlays[v8].uOverlayType == 2) + v10.uScreenSpaceY += pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]].uHeight / 2; + result = pSprites_LOD->pSpriteHeaders[pFrame->pHwSpriteIDs[0]]._4AD2D1(&v10, 0); + ++v12; + if (v12 == 5) + break; + } + } + } + } + //v3 += 20; + } + //while ( (signed int)v3 < (signed int)&pOverlayList->pOverlays ); + return result; +}