changeset 1621:25d3f9e43634

Merge
author Grumpy7
date Sun, 15 Sep 2013 02:21:26 +0200
parents 61ea994a1812 (current diff) de6e646822a6 (diff)
children a6642179aa33 511cd6dd1048
files mm7_data.h
diffstat 7 files changed, 577 insertions(+), 646 deletions(-) [+]
line wrap: on
line diff
--- a/Math.h	Sun Sep 15 02:20:06 2013 +0200
+++ b/Math.h	Sun Sep 15 02:21:26 2013 +0200
@@ -25,6 +25,7 @@
 #pragma pack(pop)
 
 __int64 fixpoint_sub0(int, int);
+__int64 fixpoint_sub2(int, int);
 __int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2);
 __int64 fixpoint_div(int, int);
 __int64 fixpoint_mul(int, int);
--- a/UI/UIHouses.cpp	Sun Sep 15 02:20:06 2013 +0200
+++ b/UI/UIHouses.cpp	Sun Sep 15 02:21:26 2013 +0200
@@ -91,19 +91,19 @@
   {  2,   3,   4,   5},  // HOUSE_STABLES_STEADWICK
   {  6,   7,   8,   8},  // HOUSE_STABLES_TULAREAN_FOREST
   {  9,  10,  10,  10},  // HOUSE_STABLES_DEYJA
-  { 11,  11,  12,  12},  // HOUSE_STABLES_58
-  { 13,  13,  13,  13},  // HOUSE_STABLES_59
-  { 14,  14,  15,  15},  // HOUSE_STABLES_60
+  { 11,  11,  12,  12},  // HOUSE_STABLES_BRACADA_DESERT
+  { 13,  13,  13,  13},  // HOUSE_STABLES_TATALIA
+  { 14,  14,  15,  15},  // HOUSE_STABLES_AVLEE
   {255, 255, 255, 255},  // HOUSE_STABLES_61
   {255, 255, 255, 255},  // HOUSE_STABLES_62
-  {255, 255, 255, 255},  // HOUSE_BOATS_63
-  { 16,  17,  18,  19},  // HOUSE_BOATS_64
-  { 18,  20,  21,  21},  // HOUSE_BOATS_65
-  { 22,  23,  24,  25},  // HOUSE_BOATS_66
-  { 22,  22,  23,  23},  // HOUSE_BOATS_67
+  {255, 255, 255, 255},  // HOUSE_BOATS_EMERALD_ISLE
+  { 16,  17,  18,  19},  // HOUSE_BOATS_ERATHIA
+  { 18,  20,  21,  21},  // HOUSE_BOATS_TULAREAN_FOREST
+  { 22,  23,  24,  25},  // HOUSE_BOATS_BRACADA_DESERT
+  { 22,  22,  23,  23},  // HOUSE_BOATS_EVENMORN_ISLAND
   {255, 255, 255, 255},  // HOUSE_BOATS_68
-  { 27,  28,  29,  30},  // HOUSE_BOATS_69
-  { 31,  32,  33,  33},  // HOUSE_BOATS_70
+  { 27,  28,  29,  30},  // HOUSE_BOATS_TATALIA
+  { 31,  32,  33,  33},  // HOUSE_BOATS_AVLEE
   { 24,  24,  24,  24},  // HOUSE_BOATS_71
   {255, 255, 255, 255},  // HOUSE_BOATS_72
   {255, 255, 255, 255}   // HOUSE_BOATS_73
@@ -1925,9 +1925,7 @@
   char pTopicArray[5][100]; // [sp+14h] [bp-27Ch]@37
   GUIWindow travel_window; // [sp+208h] [bp-88h]@1
   int pPrimaryTextHeight; // [sp+260h] [bp-30h]@36
-  //unsigned int v60; // [sp+274h] [bp-1Ch]@36
   int index; // [sp+27Ch] [bp-14h]@36
-  //char *a1; // [sp+284h] [bp-Ch]@37
   unsigned int pPrice; // [sp+288h] [bp-8h]@1
   int travel_time; // [sp+28Ch] [bp-4h]@48
   enum PlayerSpeech pSpeech;
@@ -1962,8 +1960,8 @@
 
         if (schedule_id != 255)
         {
-          if (schedule_id >= 25)
-            Log::Warning(L"Transport UI: scedule overflow");
+          //if (schedule_id >= 25)
+            //Log::Warning(L"Transport UI: schedule overflow");
           if ( pCurrentButton >= 6 )
             v25 = true;
           else
@@ -1973,7 +1971,7 @@
         if (schedule_id != 255 && v25 && (!transport_schedule[schedule_id].uQuestBit
            || _449B57_test_bit(pParty->_quest_bits, transport_schedule[schedule_id].uQuestBit)) )
         {
-//get color for current string(определение цвета текущей строки)------------
+  //get color for current string(определение цвета текущей строки)----------
           if ( pDialogueWindow->pCurrentPosActiveItem == pCurrentButton )
             sprintf(pTopicArray[index], "\f%05d", TargetColor(255, 255, 155));
           else
@@ -2408,8 +2406,6 @@
   unsigned int v12; // eax@19
   int v13; // eax@21
   int v14; // ecx@26
-  //GUIButton *v15; // eax@28
-  //GUIButton *v16; // esi@28
   int v17; // eax@28
   char *v18; // eax@30
   int v19; // eax@30
@@ -2423,11 +2419,9 @@
   int v27; // edi@46
   unsigned int pColorText; // eax@57
   signed int v31; // eax@59
-  //GUIWindow *v33; // edi@64
   int v34; // eax@64
   int v35; // ecx@64
   int v36; // esi@64
-  char v37; // sf@64
   GUIButton *pButton; // eax@65
   int v39; // edx@69
   int v40; // ecx@69
@@ -2441,15 +2435,12 @@
   signed int v48; // edi@77
   signed int i; // esi@79
   int v50; // eax@80
-  //GUIWindow *v51; // ecx@81
   _QWORD v52; // qax@81
   signed int v53; // edi@81
   int v54; // edi@81
-  //GUIButton *v55; // esi@83
   const char **v56; // eax@83
   int v57; // eax@83
   unsigned int v58; // ecx@83
-  //Player *v59; // edx@83
   unsigned __int16 v60; // ax@83
   int v61; // eax@99
   char *v63; // eax@99
@@ -2467,14 +2458,10 @@
   char pTopic4[100]; // [sp+70h] [bp-204h]@59
   char pTopic2[100]; // [sp+D4h] [bp-1A0h]@57
   char pTopic3[100]; // [sp+138h] [bp-13Ch]@59
-  //GUIWindow v78; // [sp+19Ch] [bp-D8h]@99
   GUIWindow dialog_window; // [sp+1F0h] [bp-84h]@1
   char *Str[2]; // [sp+244h] [bp-30h]@30
-  unsigned int pColorWhite; // [sp+24Ch] [bp-28h]@1
   unsigned __int8 pTopic3Height; // [sp+253h] [bp-21h]@59
   int v83; // [sp+254h] [bp-20h]@1
-  int pColorYellow; // [sp+258h] [bp-1Ch]@1
-  Player *pPlayer; // [sp+25Ch] [bp-18h]@1
   int all_text_height; // [sp+260h] [bp-14h]@18
   unsigned __int8 v87; // [sp+266h] [bp-Eh]@59
   unsigned __int8 pTopic2Height; // [sp+267h] [bp-Dh]@57
@@ -2485,18 +2472,15 @@
   unsigned __int8 pTopic4Height;
   int pTextHeight;
 
-  pPlayer = pPlayers[uActiveCharacter];
   memcpy(&dialog_window, window_SpeakInHouse, sizeof(dialog_window));
   dialog_window.uFrameX = 483;
   dialog_window.uFrameWidth = 148;
   dialog_window.uFrameZ = 334;
-  pColorWhite = TargetColor(0xFFu, 0xFFu, 0xFFu);
-  pColorYellow = TargetColor(0xFFu, 0xFFu, 0x9Bu);
   v2 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
   *(float *)&v83 = v2;
   *(float *)&v89 = v2 * v2;
   v3 = (signed __int64)(*(float *)&v89 * 0.1);
-  pItemNum = v3 * (100 - pPlayer->GetMerchant()) / 100;
+  pItemNum = v3 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
   if ( pItemNum < v3 / 3 )
     pItemNum = v3 / 3;
   v5 = 1;
@@ -2504,7 +2488,7 @@
   if ( pItemNum <= 0 )
     pOutString = (GUIFont *)1;
   v6 = (signed __int64)(*(float *)&v89 * *(float *)&v83 * 0.0099999998);
-  v7 = v6 * (100 - pPlayer->GetMerchant()) / 100;
+  v7 = v6 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
   if ( v7 < v6 / 3 )
   v7 = v6 / 3;
   v83 = v7;
@@ -2521,36 +2505,36 @@
       if ( !HouseUI_CheckIfPlayerCanInteract() )
           return;
 
-      sprintf(pTopic1, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 2 ? pColorYellow : pColorWhite);
+      sprintf(pTopic1, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 2 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
       sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[178], pOutString); // Rent room for %d gold
       strcat(pTopic1, pTmpBuf2.data());
       pTopic1Height = pFontArrus->CalcTextHeight(pTopic1, &dialog_window, 0, 0);
       strcat(pTopic1, "\n \n");
 
-      sprintf(pTopic2, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 3 ? pColorYellow : pColorWhite);
+      sprintf(pTopic2, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 3 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
       sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[86], // Buy food for %d days for %d gold
         (unsigned int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier, v83);
       strcat(pTopic2, pTmpBuf2.data());
       pTopic2Height = pFontArrus->CalcTextHeight(pTopic2, &dialog_window, 0, 0);
       strcat(pTopic2, "\n \n");
 
-      sprintf(pTopic3, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 4 ? pColorYellow : pColorWhite);
+      sprintf(pTopic3, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 4 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
       strcat(pTopic3, pGlobalTXT_LocalizationStrings[160]); // Learn Skills
       pTopic3Height = pFontArrus->CalcTextHeight(pTopic3, &dialog_window, 0, 0);
       strcat(pTopic3, "\n \n");
       pTopic4[0] = 0;
       if ( (signed int)window_SpeakInHouse->par1C >= 108 && (signed int)window_SpeakInHouse->par1C <= 120 )
       {
-        sprintf(pTopic4, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 5 ? pColorYellow : pColorWhite);
+        sprintf(pTopic4, "\f%05d", pDialogueWindow->pCurrentPosActiveItem == 5 ? TargetColor(0xFFu, 0xFFu, 0x9Bu) : TargetColor(0xFFu, 0xFFu, 0xFFu));
         strcat(pTopic4, pGlobalTXT_LocalizationStrings[611]); // Play Arcomage
         pTopic4Height = pFontArrus->CalcTextHeight(pTopic4, &dialog_window, 0, 0);
       }
-      pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+
       v36 = LOBYTE(pFontArrus->uFontHeight) - 3;
-      v37 = -pDialogueWindow->pNumPresenceButton < 0;
-      if ( !(v37 ^ (pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton)) )
+      if ( pDialogueWindow->pNumPresenceButton )
       {
-        do
+        for ( pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
+              pNumActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++pNumActiveItem )
         {
           pButton = pDialogueWindow->GetControl(pNumActiveItem);
           if ( pButton->msg_param == 15 )
@@ -2588,14 +2572,9 @@
             v41 = v39 + v40 - 1;
             pButton->uW = v41;
           }
-          pNumActiveItem++;
-          if ( pNumActiveItem >= pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
-          {
-            sprintfex(pTmpBuf.data(), "%s%s%s%s", pTopic1, pTopic2, pTopic3, pTopic4);
-            dialog_window.DrawTitleText(pFontArrus, 0, 146, 0, pTmpBuf.data(), 3);
-          }
         }
-        while ( pNumActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton );
+        sprintfex(pTmpBuf.data(), "%s%s%s%s", pTopic1, pTopic2, pTopic3, pTopic4);
+        dialog_window.DrawTitleText(pFontArrus, 0, 146, 0, pTmpBuf.data(), 3);
       }
       break;
     }
@@ -2649,7 +2628,7 @@
       }
       strcpy(pTmpBuf.data(), v72);
       v66 = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, v66, pColorYellow, pTmpBuf.data(), 3);
+      dialog_window.DrawTitleText(pFontArrus, 0, v66, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
       break;
     }
     case HOUSE_DIALOGUE_TAVERN_REST:
@@ -2685,7 +2664,7 @@
         return;
       v0 = 0;
       v9 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-      pItemNum = v9 * (100 - pPlayer->GetMerchant()) / 100;
+      pItemNum = v9 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
       if ( pItemNum < v9 / 3 )
         pItemNum = v9 / 3;
       pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
@@ -2695,7 +2674,8 @@
         do
         {
           v12 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
-          if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v12] && !pPlayer->pActiveSkills[v12] )
+          if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v12]
+              && !pPlayers[uActiveCharacter]->pActiveSkills[v12] )
           {
             all_text_height = pFontArrus->CalcTextHeight(pSkillNames[v12], &dialog_window, 0, 0);
             v0++;
@@ -2719,7 +2699,8 @@
             {
               pButton = pDialogueWindow->GetControl(pItemNum);
               v17 = pButton->msg_param - 36;
-              if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v17] || pPlayer->pActiveSkills[v17] )
+              if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v17]
+                 || pPlayers[uActiveCharacter]->pActiveSkills[v17] )
               {
                 pButton->uW = 0;
                 pButton->uHeight = 0;
@@ -2732,9 +2713,9 @@
                 pButton->uHeight = pTextHeight;
                 v14 = pTextHeight + pButton->uY - 1;
                 pButton->uW = v14;
-                pColorText = pColorYellow;
+                pColorText = TargetColor(0xFFu, 0xFFu, 0x9Bu);
                 if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-                  pColorText = pColorWhite;
+                  pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
                 dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, pSkillNames[v17], 3);
               }
               pNumActiveItem = pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton;
@@ -2745,11 +2726,12 @@
           return;
         }
       }
-      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayer->pName, pClassNames[pPlayer->classType]);
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName,
+              pClassNames[pPlayers[uActiveCharacter]->classType]);
       strcat(pTmpBuf.data(), "\n \n");
       strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
       pTextHeight = (174 - pFontArrus->CalcTextHeight(pTmpBuf.data(), &dialog_window, 0, 0)) / 2 + 138;
-      dialog_window.DrawTitleText(pFontArrus, 0, pTextHeight, pColorYellow, pTmpBuf.data(), 3);
+      dialog_window.DrawTitleText(pFontArrus, 0, pTextHeight, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
       return;
     }
 
@@ -2798,7 +2780,7 @@
         all_text_height = (174 - all_text_height) / v48;
         pNumActiveItem = pDialogueWindow->pStartingPosActiveItem;
         v54 = (174 - v48 * (174 - all_text_height) / v48 - all_text_height) / 2 - (174 - all_text_height) / v48 / 2 + 138;
-        v37 = -pDialogueWindow->pNumPresenceButton < 0;
+        //v37 = -pDialogueWindow->pNumPresenceButton < 0;
         if ( pNumActiveItem < pNumActiveItem + pDialogueWindow->pNumPresenceButton )
         {
           pItemNum = 2;
@@ -2811,9 +2793,9 @@
             pButton->uHeight = pTextHeight;
             v54 = pButton->uY + pTextHeight - 1;
             pButton->uW = v54;
-            pColorText = pColorYellow;
+            pColorText = TargetColor(0xFFu, 0xFFu, 0x9Bu);
             if ( pDialogueWindow->pCurrentPosActiveItem != pItemNum )
-              pColorText = pColorWhite;
+              pColorText = TargetColor(0xFFu, 0xFFu, 0xFFu);
             dialog_window.DrawTitleText(pFontArrus, 0, pButton->uY, pColorText, (const char *)pShopOptions[pNumString], 3);
             pItemNum++;
             ++pNumString;
@@ -2833,37 +2815,25 @@
 
 //----- (004B705E) --------------------------------------------------------
 void TempleDialog()
-    {
-    GUIWindow *v0; // ebx@1
-    Player *v1; // esi@1
-    int v2; // edi@1
+{
+    int pPrice; // edi@1
     int result; // eax@4
-    GUIWindow *v4; // edi@6
-    void *v5; // eax@6
-    int v6; // eax@6
-    unsigned int v7; // eax@8
-    int v8; // ecx@8
     unsigned int v9; // eax@9
-    int v10; // eax@11
+    int pTextHeight; // eax@11
     int v11; // eax@12
     GUIWindow *v12; // ecx@16
     int v13; // edx@16
     GUIButton *v14; // eax@19
     GUIButton *v15; // edi@19
     int v16; // eax@19
-    const char *v17; // eax@21
-    int v18; // eax@21
     unsigned int v19; // ecx@21
     int v20; // eax@21
-    unsigned __int16 v21; // ax@21
-    unsigned __int16 v22; // ST14_2@27
-    int v23; // eax@27
+    unsigned __int16 pTextColor; // ax@21
     double v24; // st7@28
     unsigned int v25; // ebx@28
     DDM_DLV_Header *v26; // edi@29
     int v27; // eax@31
     int v28; // eax@32
-    //unsigned int v29; // ecx@34
     unsigned int v30; // edx@36
     unsigned int v31; // edx@38
     unsigned int v32; // edx@40
@@ -2875,343 +2845,294 @@
     int v38; // ecx@54
     GUIWindow *v39; // eax@56
     unsigned __int8 v40; // al@61
-    GUIButton *v41; // edi@64
-    int v42; // esi@66
-    GUIWindow *v43; // ecx@66
-    int v44; // edi@66
-    int v45; // eax@68
-    signed int v46; // edi@69
+    GUIButton *pButton; // edi@64
     int v47; // edi@71
-    GUIButton *v48; // eax@73
-    const char *v49; // edx@73
-    GUIButton *v50; // esi@73
-    int v51; // eax@73
     unsigned int v52; // ecx@73
-    unsigned __int16 v53; // ax@73
-    char a1[300]; // [sp+10h] [bp-1B4h]@64
-    GUIWindow v57; // [sp+13Ch] [bp-88h]@1
-    __int64 v58; // [sp+190h] [bp-34h]@1
-    __int64 v59; // [sp+198h] [bp-2Ch]@1
-    __int64 v60; // [sp+1A0h] [bp-24h]@1
-    GUIWindow *v61; // [sp+1ACh] [bp-18h]@6
+    GUIWindow tample_window; // [sp+13Ch] [bp-88h]@1
     unsigned int v62; // [sp+1B0h] [bp-14h]@8
-    unsigned __int8 v63; // [sp+1B7h] [bp-Dh]@64
+    unsigned __int8 index; // [sp+1B7h] [bp-Dh]@64
     int v64; // [sp+1B8h] [bp-Ch]@6
-    unsigned int v65; // [sp+1BCh] [bp-8h]@6
-    DDM_DLV_Header *v66; // [sp+1C0h] [bp-4h]@6
+    unsigned int pCurrentItem; // [sp+1BCh] [bp-8h]@6
+    int all_text_height; // [sp+1C0h] [bp-4h]@6
 
-    v0 = window_SpeakInHouse;
-    memcpy(&v57, window_SpeakInHouse, sizeof(v57));
-    v57.uFrameX = 483;
-    v57.uFrameWidth = 148;
-    v57.uFrameZ = 334;
-    HIDWORD(v58) = TargetColor(0xFFu, 0xFFu, 0xFFu);
-    HIDWORD(v59) = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-    v1 = pPlayers[uActiveCharacter];
-    //v2 = pPlayers[uActiveCharacter]->_4B807C(p2DEvents_minus1__20[13 * (unsigned int)v0->ptr_1C]);
-    v2 = pPlayers[uActiveCharacter]->GetTempleHealCostModifier(p2DEvents[v0->par1C - 1].fPriceMultiplier);
-    HIDWORD(v60) = v2;
-    if ( dialog_menu_id != HOUSE_DIALOGUE_MAIN )
+  memcpy(&tample_window, window_SpeakInHouse, sizeof(tample_window));
+  tample_window.uFrameX = 483;
+  tample_window.uFrameWidth = 148;
+  tample_window.uFrameZ = 334;
+  pPrice = pPlayers[uActiveCharacter]->GetTempleHealCostModifier(p2DEvents[window_SpeakInHouse->par1C - 1].fPriceMultiplier);
+  if ( dialog_menu_id == HOUSE_DIALOGUE_MAIN )
+  {
+    index = 1;
+    pButton = pDialogueWindow->GetControl(pDialogueWindow->pStartingPosActiveItem);
+    pButton->uHeight = 0;
+    pButton->uY = 0;
+    if ( pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
     {
-      if ( dialog_menu_id != HOUSE_DIALOGUE_TEMPLE_HEAL )
+      sprintfex(pTmpBuf.data(), "%s %d %s", pGlobalTXT_LocalizationStrings[104], pPrice, pGlobalTXT_LocalizationStrings[97]);//"Лечить" "Золото"
+      pShopOptions[0] = pTmpBuf.data();
+      index = 0;
+    }
+    pShopOptions[1] = pGlobalTXT_LocalizationStrings[68];//"Пожертвовать"
+    pShopOptions[2] = pGlobalTXT_LocalizationStrings[160];//"Обучиться навыкам"
+    all_text_height = 0;
+    if ( index < pDialogueWindow->pNumPresenceButton )
+    {
+      uint i = index;
+      for ( uint j = index; j < pDialogueWindow->pNumPresenceButton; ++j )
+      {
+        all_text_height += pFontArrus->CalcTextHeight(pShopOptions[1 * i], &tample_window, 0, 0);
+        i++;
+      }
+    }
+    v64 = (174 - (signed int)all_text_height) / (pDialogueWindow->pNumPresenceButton - index);
+    if ( v64 > 32 )
+      v64 = 32;
+    v47 = (174 - v64 * (pDialogueWindow->pNumPresenceButton - index) - (signed int)all_text_height) / 2 - v64 / 2 + 138;
+    if ( index + pDialogueWindow->pStartingPosActiveItem < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton )
+    {
+      uint i = index;
+      for ( pCurrentItem = index + pDialogueWindow->pStartingPosActiveItem;
+          (signed int)pCurrentItem < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++pCurrentItem )
       {
-        if ( dialog_menu_id != HOUSE_DIALOGUE_TEMPLE_DONATE )
-        {
-          if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
-          {
-            if ( HouseUI_CheckIfPlayerCanInteract() )
-            {
-              v4 = pDialogueWindow;
-              v61 = pDialogueWindow;
-              v5 = window_SpeakInHouse->ptr_1C;
-              v66 = 0;
-              //v65 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (signed int)v5] * 500.0);
-              v65 = (signed __int64)(p2DEvents[(signed int)v5 - 1].flt_24 * 500.0);
-              v6 = v1->GetMerchant();
-              v64 = (signed int)(v65 * (100 - v6)) / 100;
-              if ( v64 < (signed int)v65 / 3 )
-                v64 = (signed int)v65 / 3;
-              v7 = v4->pStartingPosActiveItem;
-              v8 = v7 + v4->pNumPresenceButton;
-              v65 = 0;
-              v62 = v7;
-              if ( (signed int)v7 >= v8 )
-                goto LABEL_78;
-              do
-              {
-                v9 = v4->GetControl(v62)->msg_param - 36;
-                if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v9] && !v1->pActiveSkills[v9] )
-                {
-                  v10 = pFontArrus->CalcTextHeight(pSkillNames[v9], &v57, 0, 0);
-                  v66 = (DDM_DLV_Header *)((char *)v66 + v10);
-                  ++v65;
-                }
-                v11 = v4->pStartingPosActiveItem;
-                ++v62;
-              }
-              while ( (signed int)v62 < v4->pNumPresenceButton + v11 );
-              if ( v65 )
-              {
-                sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v64);
-                v57.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3u);
-                v64 = (149 - (signed int)v66) / (signed int)v65;
-                if ( v64 > 32 )
-                  v64 = 32;
-                v65 = (signed int)(149 - v65 * v64 - (int)v66) / 2 - v64 / 2 + 162;
-                v12 = v61;
-                result = v61->pStartingPosActiveItem;
-                v13 = result + v61->pNumPresenceButton;
-                v62 = v61->pStartingPosActiveItem;
-                if ( result < v13 )
-                {
-                  v66 = (DDM_DLV_Header *)2;
-                  while ( 1 )
-                  {
-                    v14 = v12->GetControl(v62);
-                    v15 = v14;
-                    v16 = v14->msg_param - 36;
-                    if ( !byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v16] || v1->pActiveSkills[v16] )
-                    {
-                      v15->uW = 0;
-                      v15->uHeight = 0;
-                      v15->uY = 0;
-                    }
-                    else
-                    {
-                      v17 = pSkillNames[v16];
-                      v15->uY = v64 + v65;
-                      HIDWORD(v60) = (uint32)v17;
-                      v18 = pFontArrus->CalcTextHeight(v17, &v57, 0, 0);
-                      v19 = v15->uY;
-                      v15->uHeight = v18;
-                      v20 = v19 + v18 - 1;
-                      v15->uW = v20;
-                      v65 = v20;
-                      v21 = WORD2(v59);
-                      if ( (DDM_DLV_Header *)pDialogueWindow->pCurrentPosActiveItem != v66 )
-                        v21 = WORD2(v58);
-                      v57.DrawTitleText(pFontArrus, 0, v19, v21, (const char *)HIDWORD(v60), 3u);
-                    }
-                    result = (int)v61;
-                    ++v62;
-                    v66 = (DDM_DLV_Header *)((char *)v66 + 1);
-                    if ( (signed int)v62 >= v61->pNumPresenceButton + v61->pStartingPosActiveItem )
-                      break;
-                    v12 = v61;
-                  }
-                }
-              }
-              else
-              {
-LABEL_78:
-                sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], v1->pName, pClassNames[v1->classType]);
-                strcat(pTmpBuf.data(), "\n \n");
-                strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
-                v22 = WORD2(v59);
-                v23 = pFontArrus->CalcTextHeight(pTmpBuf.data(), &v57, 0, 0);
-                v57.DrawTitleText(pFontArrus, 0, (174 - v23) / 2 + 138, v22, pTmpBuf.data(), 3u);
-              }
-            }
-          }
-          return;
-        }
-        // DONATION
-        //v24 = p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C];
-        v24 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
-        v25 = 0;
-        if ( pParty->uNumGold >= (unsigned int)(signed __int64)v24 )
-        {
-                Party::TakeGold((signed __int64)v24);
-                v26 = &pOutdoor->ddm;
-                if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-                    v26 = &pIndoor->dlv;
-                v27 = v26->uReputation;
-                v66 = v26;
-                if ( v27 > -5 )
-                    {
-                    v28 = v27 - 1;
-                    v26->uReputation = v28;
-                    if ( v28 < -5 )
-                        v26->uReputation = -5;
-                    }
-                if ( (unsigned __int8)byte_F8B1EF[uActiveCharacter] == pParty->uDaysPlayed % 7 )
-                    {
-                    if ( v26->uReputation <= -5 )
-                        {
-                        v30 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v30) = v30 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_AIR_WIZARD_EYE, uActiveCharacter - 1, v30, 48, 0);
-                        }
-                    if ( v26->uReputation <= -10 )
-                        {
-                        v31 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v31) = v31 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_SPIRIT_PRESERVATION, uActiveCharacter - 1, v31, 48, 0);
-                        v26 = v66;
-                        }
-                    if ( v26->uReputation <= -15 )
-                        {
-                        v32 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v32) = v32 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_BODY_PROTECTION_FROM_MAGIC, uActiveCharacter - 1, v32, 48, 0);
-                        v26 = v66;
-                        }
-                    if ( v26->uReputation <= -20 )
-                        {
-                        v33 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v33) = v33 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_HOUR_OF_POWER, uActiveCharacter - 1, v33, 48, 0);
-                        v26 = v66;
-                        }
-                    if ( v26->uReputation <= -25 )
-                        {
-                        v34 = pParty->uDaysPlayed % 7 + 1;
-                        LOBYTE(v34) = v34 | 0x80;
-                        _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_DAY_OF_PROTECTION, uActiveCharacter - 1, v34, 48, 0);
-                        }
-                    }
-                ++byte_F8B1EF[uActiveCharacter];
-                v1->PlaySound(SPEECH_83, 0);
-                ShowStatusBarString(pGlobalTXT_LocalizationStrings[527], 2u); // "Thank You!"
-                pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-                return;
-          }
-          ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
-          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-          return;
-        }
-        if ( !v1->IsPlayerHealableByTemple() )
-            return;
-        v25 = 0;
-        if ( pParty->uNumGold < v2 )
-        {
-          ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
-          PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-          return;
-        }
-        Party::TakeGold(v2);
-        v35 = LODWORD(v1->pConditions[17]);
-        v59 = v1->pConditions[14];
-        v58 = v1->pConditions[15];
-        v60 = v1->pConditions[16];
-        v61 = (GUIWindow *)HIDWORD(v1->pConditions[17]);
-        memset(v1, 0, 0xA0u);
-        v1->sHealth = v1->GetMaxHealth();
-        v1->sMana = v1->GetMaxMana();
-        v36 = (signed int)window_SpeakInHouse->ptr_1C;
-        if ( v36 != 78 && (v36 <= 80 || v36 > 82) )
-            {
-            if ( (unsigned int)v61 | v35 )
-                {
-                v37 = LOBYTE(v1->uPrevFace);
-                v38 = v1->uPrevVoiceID;
-                v1->uCurrentFace = v37;
-                v1->uVoiceID = v38;
-                ReloadPlayerPortraits(uActiveCharacter - 1, (char)v37);
-                }
-            pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
-            v1->PlaySound(SPEECH_82, 0);
-            pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
-            pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-            return;
-            }
-        v39 = v61;
-        if ( (unsigned int)v61 | v35 )
-            {
-            LODWORD(v1->pConditions[17]) = v35;
-            }
-        else
-            {
-            if ( !v60 && !v58 && !v59 )
-            {
-              pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
-              v1->PlaySound(SPEECH_82, 0);
-              pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
-              pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-              return;
-            }
-            v1->uPrevFace = v1->uCurrentFace;
-            v1->uPrevVoiceID = v1->uVoiceID;
-            v1->SetCondition(0x11u, 1);
-            v1->uVoiceID = (v1->GetSexByVoice() != 0) + 23;
-            v40 = (v1->GetSexByVoice() != 0) + 23;
-            v1->uCurrentFace = v40;
-            ReloadPlayerPortraits(uActiveCharacter - 1, (char)v40);
-            LODWORD(v1->pConditions[17]) = LODWORD(pParty->uTimePlayed);
-            v39 = (GUIWindow *)HIDWORD(pParty->uTimePlayed);
-            }
-        HIDWORD(v1->pConditions[17]) = (int)v39;
+        pButton = pDialogueWindow->GetControl(pCurrentItem);
+        pButton->uY = v64 + v47;
+        pTextHeight = pFontArrus->CalcTextHeight(pShopOptions[1 * i], &tample_window, 0, 0);
+        v52 = pButton->uY;
+        pButton->uHeight = pTextHeight;
+        v47 = v52 + pTextHeight - 1;
+        pButton->uW = v47;
+        pTextColor = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+        if ( pDialogueWindow->pCurrentPosActiveItem != index + 2 )
+          pTextColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
+        tample_window.DrawTitleText(pFontArrus, 0, v52, pTextColor, pShopOptions[1 * i], 3);
+        i++;
+        index++;
+      }
+    }
+    return;
+  }
+  //-------------------------------------------------
+  if ( dialog_menu_id == HOUSE_DIALOGUE_TEMPLE_HEAL )
+  {
+    if ( !pPlayers[uActiveCharacter]->IsPlayerHealableByTemple() )
+      return;
+    v25 = 0;
+    if ( pParty->uNumGold < pPrice )
+    {
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+      PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
+      return;
+    }
+    Party::TakeGold(pPrice);
+    v35 = LODWORD(pPlayers[uActiveCharacter]->pConditions[17]);
+    memset(pPlayers[uActiveCharacter], 0, 0xA0u);
+    pPlayers[uActiveCharacter]->sHealth = pPlayers[uActiveCharacter]->GetMaxHealth();
+    pPlayers[uActiveCharacter]->sMana = pPlayers[uActiveCharacter]->GetMaxMana();
+    v36 = (signed int)window_SpeakInHouse->ptr_1C;
+    if ( v36 != 78 && (v36 <= 80 || v36 > 82) )
+    {
+      if ( (unsigned int)pPlayers[uActiveCharacter]->pConditions[17] | v35 )
+      {
+        v37 = LOBYTE(pPlayers[uActiveCharacter]->uPrevFace);
+        v38 = pPlayers[uActiveCharacter]->uPrevVoiceID;
+        pPlayers[uActiveCharacter]->uCurrentFace = v37;
+        pPlayers[uActiveCharacter]->uVoiceID = v38;
+        ReloadPlayerPortraits(uActiveCharacter - 1, (char)v37);
+      }
+      pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
+      pPlayers[uActiveCharacter]->PlaySound(SPEECH_82, 0);
+      pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
+      return;
+    }
+    if ( (unsigned int)pPlayers[uActiveCharacter]->pConditions[17] | v35 )
+    {
+      LODWORD(pPlayers[uActiveCharacter]->pConditions[17]) = v35;
+    }
+    else
+    {
+      if ( !pPlayers[uActiveCharacter]->pConditions[16]
+        && !pPlayers[uActiveCharacter]->pConditions[15] && !pPlayers[uActiveCharacter]->pConditions[14] )
+      {
         pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
-        v1->PlaySound(SPEECH_82, 0);
+        pPlayers[uActiveCharacter]->PlaySound(SPEECH_82, 0);
         pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
         pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
-        return; // void func
-        }
-    v63 = 1;
-    v41 = pDialogueWindow->GetControl(pDialogueWindow->pStartingPosActiveItem);
-    strcpy(a1, "");
-    v41->uHeight = 0;
-    v41->uY = 0;
-    if ( v1->IsPlayerHealableByTemple() )
+        return;
+      }
+      pPlayers[uActiveCharacter]->uPrevFace = pPlayers[uActiveCharacter]->uCurrentFace;
+      pPlayers[uActiveCharacter]->uPrevVoiceID = pPlayers[uActiveCharacter]->uVoiceID;
+      pPlayers[uActiveCharacter]->SetCondition(0x11u, 1);
+      pPlayers[uActiveCharacter]->uVoiceID = (pPlayers[uActiveCharacter]->GetSexByVoice() != 0) + 23;
+      v40 = (pPlayers[uActiveCharacter]->GetSexByVoice() != 0) + 23;
+      pPlayers[uActiveCharacter]->uCurrentFace = v40;
+      ReloadPlayerPortraits(uActiveCharacter - 1, (char)v40);
+      LODWORD(pPlayers[uActiveCharacter]->pConditions[17]) = LODWORD(pParty->uTimePlayed);
+      v39 = (GUIWindow *)HIDWORD(pParty->uTimePlayed);
+    }
+    HIDWORD(pPlayers[uActiveCharacter]->pConditions[17]) = (int)v39;
+    pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x2), -1, 0, -1, 0, 0, 0, 0);
+    pPlayers[uActiveCharacter]->PlaySound(SPEECH_82, 0);
+    pOtherOverlayList->_4418B1(20, uActiveCharacter + 99, 0, 65536);
+    pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
+    return;
+  }
+  //---------------------------------------------------
+  if ( dialog_menu_id == HOUSE_DIALOGUE_TEMPLE_DONATE )
+  {
+      v24 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
+      v25 = 0;
+      if ( pParty->uNumGold >= (unsigned int)(signed __int64)v24 )
+      {
+        Party::TakeGold((signed __int64)v24);
+        v26 = &pOutdoor->ddm;
+        if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
+          v26 = &pIndoor->dlv;
+        v27 = v26->uReputation;
+        //v66 = v26;
+        if ( v27 > -5 )
         {
-        sprintf(a1, "%s %d %s", pGlobalTXT_LocalizationStrings[104], HIDWORD(v60), pGlobalTXT_LocalizationStrings[97]);
-        v63 = 0;
+          v28 = v27 - 1;
+          v26->uReputation = v28;
+          if ( v28 < -5 )
+            v26->uReputation = -5;
         }
-    strcpy(&a1[100], pGlobalTXT_LocalizationStrings[68]);
-    strcpy(&a1[200], pGlobalTXT_LocalizationStrings[160]);
-    v42 = v63;
-    v43 = pDialogueWindow;
-    v44 = v63;
-    v66 = 0;
-    if ( v63 < pDialogueWindow->pNumPresenceButton )
+        if ( (unsigned __int8)byte_F8B1EF[uActiveCharacter] == pParty->uDaysPlayed % 7 )
         {
-        v61 = (GUIWindow *)&a1[100 * v63];
-        do
-            {
-            v45 = pFontArrus->CalcTextHeight((const char *)v61, &v57, 0, 0);
-            v66 = (DDM_DLV_Header *)((char *)v66 + v45);
-            v43 = pDialogueWindow;
-            v61 = (GUIWindow *)((char *)v61 + 100);
-            ++v44;
-            }
-            while ( v44 < pDialogueWindow->pNumPresenceButton );
+          if ( v26->uReputation <= -5 )
+          {
+            v30 = pParty->uDaysPlayed % 7 + 1;
+            LOBYTE(v30) = v30 | 0x80;
+            _42777D_CastSpell_UseWand_ShootArrow(SPELL_AIR_WIZARD_EYE, uActiveCharacter - 1, v30, 48, 0);
+          }
+          if ( v26->uReputation <= -10 )
+          {
+            v31 = pParty->uDaysPlayed % 7 + 1;
+            LOBYTE(v31) = v31 | 0x80;
+            _42777D_CastSpell_UseWand_ShootArrow(SPELL_SPIRIT_PRESERVATION, uActiveCharacter - 1, v31, 48, 0);
+            //v26 = v66;
+          }
+          if ( v26->uReputation <= -15 )
+          {
+            v32 = pParty->uDaysPlayed % 7 + 1;
+            LOBYTE(v32) = v32 | 0x80;
+            _42777D_CastSpell_UseWand_ShootArrow(SPELL_BODY_PROTECTION_FROM_MAGIC, uActiveCharacter - 1, v32, 48, 0);
+            //v26 = v66;
+          }
+          if ( v26->uReputation <= -20 )
+          {
+            v33 = pParty->uDaysPlayed % 7 + 1;
+            LOBYTE(v33) = v33 | 0x80;
+            _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_HOUR_OF_POWER, uActiveCharacter - 1, v33, 48, 0);
+            //v26 = v66;
+          }
+          if ( v26->uReputation <= -25 )
+          {
+            v34 = pParty->uDaysPlayed % 7 + 1;
+            LOBYTE(v34) = v34 | 0x80;
+            _42777D_CastSpell_UseWand_ShootArrow(SPELL_LIGHT_DAY_OF_PROTECTION, uActiveCharacter - 1, v34, 48, 0);
+          }
         }
-    v46 = v43->pNumPresenceButton - v42;
-    v64 = (174 - (signed int)v66) / v46;
-    if ( v64 > 32 )
-        v64 = 32;
-    v47 = (174 - v64 * v46 - (signed int)v66) / 2 - v64 / 2 + 138;
-    v65 = v42 + v43->pStartingPosActiveItem;
-    if ( v42 + v43->pStartingPosActiveItem < v43->pStartingPosActiveItem + v43->pNumPresenceButton )
+        ++byte_F8B1EF[uActiveCharacter];
+        pPlayers[uActiveCharacter]->PlaySound(SPEECH_83, 0);
+        ShowStatusBarString(pGlobalTXT_LocalizationStrings[527], 2); // "Thank You!"
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
+        return;
+      }
+      ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+      PlayHouseSound((unsigned int)window_SpeakInHouse->ptr_1C, HouseSound_NotEnoughMoney_TrainingSuccessful);
+      pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, v25);
+      return;
+  }
+  //------------------------------------------------
+  if ( dialog_menu_id == HOUSE_DIALOGUE_LEARN_SKILLS )
+  {
+    if ( HouseUI_CheckIfPlayerCanInteract() )
+    {
+      //v61 = pDialogueWindow;
+      all_text_height = 0;
+      pCurrentItem = (signed __int64)(p2DEvents[(signed int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+      v64 = (signed int)(pCurrentItem * (100 - pPlayers[uActiveCharacter]->GetMerchant())) / 100;
+      if ( v64 < (signed int)pCurrentItem / 3 )
+        v64 = (signed int)pCurrentItem / 3;
+      pCurrentItem = 0;
+      //if ( (signed int)pDialogueWindow->pStartingPosActiveItem >= v8 )
+      //goto LABEL_78;
+      for ( v62 = pDialogueWindow->pStartingPosActiveItem; (signed int)v62 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++v62 )
+      {
+        v9 = pDialogueWindow->GetControl(v62)->msg_param - 36;
+        if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v9] && !pPlayers[uActiveCharacter]->pActiveSkills[v9] )
         {
-        v61 = (GUIWindow *)(v42 + 2);
-        v66 = (DDM_DLV_Header *)&a1[100 * v42];
-        do
+          all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v9], &tample_window, 0, 0);
+          //v66 = (DDM_DLV_Header *)((char *)v66 + pTextHeight);
+          ++pCurrentItem;
+        }
+        v11 = pDialogueWindow->pStartingPosActiveItem;
+      }
+      if ( pCurrentItem )
+      {
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[401], v64);
+        tample_window.DrawTitleText(pFontArrus, 0, 0x92u, 0, pTmpBuf.data(), 3);
+        v64 = (149 - (signed int)all_text_height) / (signed int)pCurrentItem;
+        if ( v64 > 32 )
+          v64 = 32;
+        pCurrentItem = (signed int)(149 - pCurrentItem * v64 - (int)all_text_height) / 2 - v64 / 2 + 162;
+        v12 = pDialogueWindow;
+        result = pDialogueWindow->pStartingPosActiveItem;
+        v13 = result + pDialogueWindow->pNumPresenceButton;
+        v62 = pDialogueWindow->pStartingPosActiveItem;
+        if ( result < v13 )
+        {
+          all_text_height = 2;
+          while ( 1 )
+          {
+            v14 = v12->GetControl(v62);
+            v15 = v14;
+            v16 = v14->msg_param - 36;
+            if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v16] || pPlayers[uActiveCharacter]->pActiveSkills[v16] )
             {
-            v48 = v43->GetControl(v65);
-            v49 = (const char *)v66;
-            v50 = v48;
-            v48->uY = v64 + v47;
-            v51 = pFontArrus->CalcTextHeight(v49, &v57, 0, 0);
-            v52 = v50->uY;
-            v50->uHeight = v51;
-            v47 = v52 + v51 - 1;
-            v50->uW = v47;
-            v53 = WORD2(v59);
-            if ( (GUIWindow *)pDialogueWindow->pCurrentPosActiveItem != v61 )
-                v53 = WORD2(v58);
-            v57.DrawTitleText(pFontArrus, 0, v52, v53, (const char *)v66, 3u);
-            v43 = pDialogueWindow;
-            v66 = (DDM_DLV_Header *)((char *)v66 + 100);
-            v61 = (GUIWindow *)((char *)v61 + 1);
-            ++v65;
+              v15->uW = 0;
+              v15->uHeight = 0;
+              v15->uY = 0;
+            }
+            else
+            {
+              v15->uY = v64 + pCurrentItem;
+              pTextHeight = pFontArrus->CalcTextHeight(pSkillNames[v16], &tample_window, 0, 0);
+              v19 = v15->uY;
+              v15->uHeight = pTextHeight;
+              v20 = v19 + pTextHeight - 1;
+              v15->uW = v20;
+              pCurrentItem = v20;
+              pTextColor = TargetColor(0xFFu, 0xFFu, 0x9Bu);
+              if ( pDialogueWindow->pCurrentPosActiveItem != all_text_height )
+                pTextColor = TargetColor(0xFFu, 0xFFu, 0xFFu);
+              tample_window.DrawTitleText(pFontArrus, 0, v19, pTextColor, pSkillNames[v16], 3);
             }
-            while ( (signed int)v65 < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem );
+            result = (int)pDialogueWindow;
+            ++v62;
+            //v66 = (DDM_DLV_Header *)((char *)v66 + 1);
+	        all_text_height++;
+            if ( (signed int)v62 >= pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
+              break;
+            v12 = pDialogueWindow;
+          }
         }
-    return;
+      }
+      else
+      {
+LABEL_78:
+        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[544], pPlayers[uActiveCharacter]->pName, pClassNames[pPlayers[uActiveCharacter]->classType]);
+        strcat(pTmpBuf.data(), "\n \n");
+        strcat(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[528]);
+        pTextHeight = pFontArrus->CalcTextHeight(pTmpBuf.data(), &tample_window, 0, 0);
+        tample_window.DrawTitleText(pFontArrus, 0, (174 - pTextHeight) / 2 + 138, TargetColor(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
+      }
     }
+  }
+  return;
+}
 
 //----- (004B4710) --------------------------------------------------------
 void TrainingDialog()
@@ -3811,8 +3732,6 @@
   int v38; // eax@52
   signed int v39; // ecx@54
   int v40; // edi@57
-  GUIButton *v41; // eax@60
-  GUIButton *v42; // esi@60
   const char *v43; // ebx@60
   int v44; // eax@60
   unsigned int v45; // ecx@60
@@ -4025,15 +3944,15 @@
     v40 = (174 - (signed int)pNPC * v39 - v34) / 2 - (signed int)pNPC / 2 + 138;
     for ( i = pDialogueWindow->pStartingPosActiveItem; i < pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem; ++i )
     {
-      v41 = pDialogueWindow->GetControl(i);
-      v42 = v41;
-      v43 = v41->pButtonName;
-      v41->uY = (unsigned int)((char *)pNPC + v40);
-      v44 = pFontArrus->CalcTextHeight(v41->pButtonName, &v52, 0, 0);
-      v45 = v42->uY;
-      v42->uHeight = v44;
+      pButton = pDialogueWindow->GetControl(i);
+      //v42 = v41;
+      v43 = pButton->pButtonName;
+      pButton->uY = (unsigned int)((char *)pNPC + v40);
+      v44 = pFontArrus->CalcTextHeight(pButton->pButtonName, &v52, 0, 0);
+      v45 = pButton->uY;
+      pButton->uHeight = v44;
       v40 = v45 + v44 - 1;
-      v42->uW = v40;
+      pButton->uW = v40;
       v46 = TargetColor(0xE1u, 0xCDu, 0x23u);
       if ( (char *)pDialogueWindow->pCurrentPosActiveItem != pInString )
         v46 = TargetColor(0xFFu, 0xFFu, 0xFFu);
@@ -4061,19 +3980,12 @@
 //----- (004B4F4F) --------------------------------------------------------
 void JailDialog()
 {
-  const char *v0; // esi@1
-  const char *v1; // ST10_4@1
-  unsigned __int16 v2; // ST0C_2@1
-  int v3; // eax@1
-  GUIWindow v5; // [sp+8h] [bp-54h]@1
+  GUIWindow jail_dialogue_window; // [sp+8h] [bp-54h]@1
 
-  memcpy(&v5, window_SpeakInHouse, sizeof(v5));
-  v0 = pGlobalTXT_LocalizationStrings[672];
-  v1 = pGlobalTXT_LocalizationStrings[672];
-  v5.uFrameX = 483;
-  v5.uFrameWidth = 148;
-  v5.uFrameZ = 334;
-  v2 = TargetColor(0xFFu, 0xFFu, 0x9Bu);
-  v3 = pFontArrus->CalcTextHeight(v0, &v5, 0, 0);
-  v5.DrawTitleText(pFontArrus, 0, (310 - v3) / 2 + 18, v2, v1, 3u);
+  memcpy(&jail_dialogue_window, window_SpeakInHouse, sizeof(jail_dialogue_window));
+  jail_dialogue_window.uFrameX = 483;
+  jail_dialogue_window.uFrameWidth = 148;
+  jail_dialogue_window.uFrameZ = 334;
+  jail_dialogue_window.DrawTitleText(pFontArrus, 0, (310 - pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[672], &jail_dialogue_window, 0, 0)) / 2 + 18,
+     TargetColor(0xFFu, 0xFFu, 0x9Bu), pGlobalTXT_LocalizationStrings[672], 3);
 }
\ No newline at end of file
--- a/UI/UiGame.cpp	Sun Sep 15 02:20:06 2013 +0200
+++ b/UI/UiGame.cpp	Sun Sep 15 02:21:26 2013 +0200
@@ -348,7 +348,7 @@
   int pTextHeight; // esi@39
   GUIButton *pButton; // eax@43
   int v32; // ebx@93
-  uint v35; // esi@93
+  //uint v35; // esi@93
   int v38; // eax@95
   signed int v39; // esi@99
   signed int v40; // eax@102
@@ -599,15 +599,15 @@
 
   // Install Buttons(Установка кнопок)-------- 
   v32 = 0;
-  v35 = (uint)pDialogueWindow->pStartingPosActiveItem;
-  for ( uint i = v35 + pDialogueWindow->pNumPresenceButton; v35 < i; i = pDialogueWindow->pNumPresenceButton + pDialogueWindow->pStartingPosActiveItem )
+  //v35 = (uint)pDialogueWindow->pStartingPosActiveItem;
+  for ( int i = pDialogueWindow->pStartingPosActiveItem; i < pDialogueWindow->pStartingPosActiveItem + pDialogueWindow->pNumPresenceButton; ++i )
   {
-    pButton = pDialogueWindow->GetControl(v35);
+    pButton = pDialogueWindow->GetControl(i);
     if ( !pButton )
       break;
     v38 = pFontArrus->CalcTextHeight(pButton->pButtonName, &window, 0, 0);
     v32 += v38;
-    ++v35;
+    //++v35;
   }
   v39 = pDialogueWindow->pNumPresenceButton;
   if ( v39 )
--- a/mm7_1.cpp	Sun Sep 15 02:20:06 2013 +0200
+++ b/mm7_1.cpp	Sun Sep 15 02:21:26 2013 +0200
@@ -65,6 +65,14 @@
 {
   return ((__int64)a1 * (__int64)a2) >> 16;
 }
+__int64 fixpoint_sub2(int a1, int a2)
+{
+  signed __int64 v3; // qtt@1
+
+  LODWORD(v3) = a1 << 16;
+  HIDWORD(v3) = a1 >> 16;
+  return v3 / a2;
+}
 
 __int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2)
 {
--- a/mm7_5.cpp	Sun Sep 15 02:20:06 2013 +0200
+++ b/mm7_5.cpp	Sun Sep 15 02:21:26 2013 +0200
@@ -4302,264 +4302,274 @@
 bool __fastcall sub_4070EF_prolly_detect_player(unsigned int uObjID, unsigned int uObj2ID)
 {
   signed int v2; // eax@1
-  //unsigned int v3; // ecx@1
-  //signed int v4; // esi@1
   int v5; // ecx@2
-  signed int v6; // eax@4
-  int object1_sector; // eax@4
+  int obj1_sector; // eax@4
   float v8; // ST24_4@5
   double v9; // ST18_8@5
-  signed int v10; // eax@6
   int v11; // ecx@6
   signed int v12; // eax@7
   int v13; // esi@7
   int v14; // esi@8
   int v15; // esi@9
-  signed int v16; // eax@11
   int obj2_z; // edi@11
   int obj2_x; // esi@11
   int obj2_sector; // eax@13
   float v20; // ST24_4@14
   double v21; // ST18_8@14
-  signed int v22; // eax@15
-  int dist2_x; // ebx@16
-  signed int v24; // ecx@16
+  int dist_x; // ebx@16
+  signed int dist_3d; // ecx@16
   int v25; // eax@18
-  //int v26; // eax@28
-  //BLVSector *v27; // edx@31
-  //int v28; // ecx@31
   BLVFace *v29; // ebx@32
   Vec3_short_ *v30; // esi@32
   int v31; // eax@32
   int v32; // ST50_4@44
   int v33; // ST54_4@44
   int v34; // eax@44
-  char v35; // zf@44
-  int v36; // edi@44
-  int v37; // eax@45
   signed int v38; // esi@45
-  int v39; // ST4C_4@49
   signed __int64 v40; // qtt@50
-  __int16 v42; // bx@58
+  __int16 next_sector; // bx@58
   int v43; // [sp-8h] [bp-70h]@11
   int v44; // [sp-4h] [bp-6Ch]@11
-  //int v45; // [sp+Ch] [bp-5Ch]@32
-  //__int16 v46; // [sp+10h] [bp-58h]@32
   int v47; // [sp+18h] [bp-50h]@20
   int v48; // [sp+1Ch] [bp-4Ch]@20
   int v49; // [sp+20h] [bp-48h]@20
-  int dist2_z; // [sp+24h] [bp-44h]@16
-  signed int v51; // [sp+24h] [bp-44h]@27
-  signed int v52; // [sp+28h] [bp-40h]@26
-  signed int v53; // [sp+2Ch] [bp-3Ch]@23
-  signed int v54; // [sp+30h] [bp-38h]@22
-  signed int v55; // [sp+34h] [bp-34h]@21
-  signed int v56; // [sp+38h] [bp-30h]@20
-  signed int v57; // [sp+3Ch] [bp-2Ch]@28
+  int dist_z; // [sp+24h] [bp-44h]@16
+  signed int higher_z; // [sp+24h] [bp-44h]@27
+  signed int lower_z; // [sp+28h] [bp-40h]@26
+  signed int higher_y; // [sp+2Ch] [bp-3Ch]@23
+  signed int lower_y; // [sp+30h] [bp-38h]@22
+  signed int higher_x; // [sp+34h] [bp-34h]@21
+  signed int lower_x; // [sp+38h] [bp-30h]@20
+  signed int sectors_visited; // [sp+3Ch] [bp-2Ch]@28
   int v58; // [sp+44h] [bp-24h]@50
   int v59; // [sp+48h] [bp-20h]@44
   int obj2_y; // [sp+50h] [bp-18h]@11
-  signed int v61; // [sp+50h] [bp-18h]@31
-  //int v62; // [sp+54h] [bp-14h]@16
-  int obj_x; // [sp+58h] [bp-10h]@4
-  int obj_y; // [sp+5Ch] [bp-Ch]@4
-  int obj_z; // [sp+60h] [bp-8h]@4
-  int v66; // [sp+64h] [bp-4h]@7
+  int obj1_x; // [sp+58h] [bp-10h]@4
+  int obj1_y; // [sp+5Ch] [bp-Ch]@4
+  int obj1_z; // [sp+60h] [bp-8h]@4
+  int current_sector; // [sp+64h] [bp-4h]@7
+  int dist_y;
+  int v70;
 
   v2 = PID_ID(uObjID);
-  if ( PID_TYPE(uObjID) == 5 )
+  switch( PID_TYPE(uObjID) )
   {
-      v6 = v2;
-      obj_x = pLevelDecorations[v6].vPosition.x;
-      obj_y = pLevelDecorations[v6].vPosition.y;
-      obj_z = pLevelDecorations[v6].vPosition.z;
-      object1_sector = pIndoor->GetSector(obj_x, obj_y, obj_z);
-  }
-  else if ( PID_TYPE(uObjID) == 3 )
-  {
-      obj_x = pActors[v2].vPosition.x;
-      obj_y = pActors[v2].vPosition.y;
+	case OBJECT_Decoration:
+      obj1_x = pLevelDecorations[v2].vPosition.x;
+      obj1_y = pLevelDecorations[v2].vPosition.y;
+      obj1_z = pLevelDecorations[v2].vPosition.z;
+      obj1_sector = pIndoor->GetSector(obj1_x, obj1_y, obj1_z);
+	  break;
+	case OBJECT_Actor:
+      obj1_x = pActors[v2].vPosition.x;
+      obj1_y = pActors[v2].vPosition.y;
       v8 = (double)pActors[v2].uActorHeight * 0.69999999;
       //v9 = v8 + 6.7553994e15;
-      //obj_z = LODWORD(v9) + pActors[v2].vPosition.z;
-	  obj_z = (int)v8 + pActors[v2].vPosition.z;
-      object1_sector = pActors[v2].uSectorID;
+      //obj1_z = LODWORD(v9) + pActors[v2].vPosition.z;
+	  obj1_z = (int)v8 + pActors[v2].vPosition.z;
+      obj1_sector = pActors[v2].uSectorID;
+	  break;
+	case OBJECT_Item:
+      obj1_x = pSpriteObjects[v2].vPosition.x;
+      obj1_y = pSpriteObjects[v2].vPosition.y;
+      obj1_z = pSpriteObjects[v2].vPosition.z;
+      obj1_sector = pSpriteObjects[v2].uSectorID;
+	  break;
+	default:
+	  return 0;
   }
-  else if ( PID_TYPE(uObjID) == 2 )
-  {
-    v10 = v2;
-    obj_x = pSpriteObjects[v10].vPosition.x;
-    obj_y = pSpriteObjects[v10].vPosition.y;
-    obj_z = pSpriteObjects[v10].vPosition.z;
-    object1_sector = pSpriteObjects[v10].uSectorID;
-  }
-  else
-	  return 0;
-  v66 = object1_sector;
   v12 = PID_ID(uObj2ID);
-  if ( PID_TYPE(uObj2ID) == 5)
+  switch( PID_TYPE(uObj2ID) )
   {
-	v16 = v12;
-    obj2_z = pLevelDecorations[v16].vPosition.z;
-    obj2_x = pLevelDecorations[v16].vPosition.x;
-    obj2_y = pLevelDecorations[v16].vPosition.y;
-	obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
-   }
-   else if ( PID_TYPE(uObj2ID) == 4)
-   {
-     obj2_x = pParty->vPosition.x;
-     obj2_z = pParty->sEyelevel + pParty->vPosition.z;
-     obj2_y = pParty->vPosition.y;
-	 obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
-    }
-  
-  else if( PID_TYPE(uObj2ID) == 3)
-  {
-    obj2_y = pActors[v12].vPosition.y;
-    obj2_x = pActors[v12].vPosition.x;
-    v20 = (double)pActors[v12].uActorHeight * 0.69999999;
-    //v21 = v20 + 6.7553994e15;
-    //obj2_z = LODWORD(v21) + pActors[v12].vPosition.z;
-	obj2_z = (int)v20 + pActors[v12].vPosition.z;
-    obj2_sector = pActors[v12].uSectorID;
+    case OBJECT_Decoration:
+      obj2_z = pLevelDecorations[v12].vPosition.z;
+      obj2_x = pLevelDecorations[v12].vPosition.x;
+      obj2_y = pLevelDecorations[v12].vPosition.y;
+	  obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
+	  break;
+	case OBJECT_Player:
+      obj2_x = pParty->vPosition.x;
+      obj2_z = pParty->sEyelevel + pParty->vPosition.z;
+      obj2_y = pParty->vPosition.y;
+	  obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
+      break;
+	case OBJECT_Actor:
+      obj2_y = pActors[v12].vPosition.y;
+      obj2_x = pActors[v12].vPosition.x;
+      v20 = (double)pActors[v12].uActorHeight * 0.69999999;
+      //v21 = v20 + 6.7553994e15;
+      //obj2_z = LODWORD(v21) + pActors[v12].vPosition.z;
+	  obj2_z = (int)v20 + pActors[v12].vPosition.z;
+      obj2_sector = pActors[v12].uSectorID;
+	  break;
+	case OBJECT_Item:
+      obj2_x = pSpriteObjects[v12].vPosition.x;
+      obj2_z = pSpriteObjects[v12].vPosition.z;
+      obj2_y = pSpriteObjects[v12].vPosition.y;
+      obj2_sector = pSpriteObjects[v12].uSectorID;
+	  break;
+	default:
+	  return 0;
   }
-  
-  else if ( PID_TYPE(uObj2ID) == 2)
-  {
-    v22 = v12;
-    obj2_x = pSpriteObjects[v22].vPosition.x;
-    obj2_z = pSpriteObjects[v22].vPosition.z;
-    obj2_y = pSpriteObjects[v22].vPosition.y;
-    obj2_sector = pSpriteObjects[v22].uSectorID;
-  }
-  else
-	  return 0;
-  dist2_x = obj2_x - obj_x;
-  dist2_z = obj2_z - obj_z;
-  v24 = integer_sqrt(dist2_x * dist2_x + (obj2_y - obj_y) * (obj2_y - obj_y) + dist2_z * dist2_z);
-  if ( v24 > 5120 )
+  dist_x = obj2_x - obj1_x;
+  dist_z = obj2_z - obj1_z;
+  dist_y = obj2_y - obj1_y;
+  dist_3d = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
+  //range check
+  if ( dist_3d > 5120 )
     return 0;
   if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
     return 1;
   v25 = 65536;
-  if ( v24 )
-    v25 = 65536 / v24;
-  v49 = dist2_x * v25;
-  v47 = dist2_z * v25;
-  v48 = (obj2_y - obj_y) * v25;
-  if ( obj_x < obj2_x )
+  if ( dist_3d )
+    v25 = 65536 / dist_3d;
+  v49 = dist_x * v25;
+  v47 = dist_z * v25;
+  v48 = dist_y * v25;
+  if ( obj1_x < obj2_x )
   {
-	v56 = obj_x;
-    v55 = obj2_x;
+	lower_x = obj1_x;
+    higher_x = obj2_x;
   }
   else
   {
-    v56 = obj2_x;
-    v55 = obj_x;
+    lower_x = obj2_x;
+    higher_x = obj1_x;
   }
-  if ( obj_y < obj2_y )
+  if ( obj1_y < obj2_y )
   {
-	v54 = obj_y;
-    v53 = obj2_y;
+	lower_y = obj1_y;
+    higher_y = obj2_y;
   }
   else
   {
-    v54 = obj2_y;
-    v53 = obj_y;
+    lower_y = obj2_y;
+    higher_y = obj1_y;
   }
-  if ( obj_z < obj2_z )
+  if ( obj1_z < obj2_z )
   {
-	v52 = obj_z;
-    v51 = obj2_z;
+	lower_z = obj1_z;
+    higher_z = obj2_z;
   }
   else
   {
-    v52 = obj2_z;
-    v51 = obj_z;
+    lower_z = obj2_z;
+    higher_z = obj1_z;
   }
-  v57 = 0;
-  if ( v66 == obj2_sector )
+  sectors_visited = 0;
+  //monster in same sector with player
+  if ( obj1_sector == obj2_sector )
       return 1;
-  //for ( v57 = 0; v57 < 30; v57++ )
-  if ( v57 < 30 && !(v61 = 0, pIndoor->pSectors[v66].uNumPortals <= 0) )
-	for( int v61 = 0; v61 < pIndoor->pSectors[v66].uNumPortals; v61++ )
+  //search starts from monster
+  current_sector = obj1_sector;
+  for( int current_portal = 0; current_portal < pIndoor->pSectors[current_sector].uNumPortals; current_portal++ )
+  {
+	v29 = &pIndoor->pFaces[pIndoor->pSectors[current_sector].pPortals[current_portal]];
+	v30 = &pIndoor->pVertices[*v29->pVertexIDs];
+	v31 = v29->pFacePlane_old.vNormal.z * (v30->z - obj1_z)
+		+ v29->pFacePlane_old.vNormal.y * (v30->y - obj1_y)
+		+ v29->pFacePlane_old.vNormal.x * (v30->x - obj1_x);
+
+	if ( current_sector != v29->uSectorID )
+		v31 = -v31;
+
+	if ( v31 >= 0 && v30->x != obj1_x && v30->y != obj1_y && v30->z != obj1_z)
+		continue;
+
+	if(	lower_x > v29->pBounding.x2
+		|| higher_x < v29->pBounding.x1
+		|| lower_y > v29->pBounding.y2
+		|| higher_y < v29->pBounding.y1
+		|| lower_z > v29->pBounding.z2
+		|| higher_z < v29->pBounding.z1 )
+	{
+		continue;
+	}
+	  
+	v32 = fixpoint_sub0(v29->pFacePlane_old.vNormal.x,v49);
+	v33 = fixpoint_sub0(v29->pFacePlane_old.vNormal.z,v47);
+	v34 = fixpoint_sub0(v29->pFacePlane_old.vNormal.y,v48);
+	v59 = v32 + v33 + v34;
+	if ( v59 )
 	{
-      v29 = &pIndoor->pFaces[pIndoor->pSectors[v66].pPortals[v61]];
-      v30 = &pIndoor->pVertices[*v29->pVertexIDs];
-      //v45 = *(int *)&v30->x;
-      //v46 = v30->z;
-      //v31 = v29->pFacePlane_old.vNormal.z * (v46 - obj_z)
-	  v31 = v29->pFacePlane_old.vNormal.z * (v30->z - obj_z)
-          //+ v29->pFacePlane_old.vNormal.y * (SHIWORD(v45) - obj_y)
-		  + v29->pFacePlane_old.vNormal.y * (v30->y - obj_y)
-          //+ v29->pFacePlane_old.vNormal.x * ((signed __int16)v45 - obj_x);
-		  + v29->pFacePlane_old.vNormal.x * (v30->x - obj_x);
-      if ( v66 != v29->uSectorID )
-        v31 = -v31;
-      //if (!( v31 >= 0 && (signed __int16)v45 != obj_x && SHIWORD(v45) != obj_y && v46 != obj_z
-	  if (!( v31 >= 0 && v30->x != obj_x && v30->y != obj_y && v30->z != obj_z
-        || v56 > v29->pBounding.x2
-        || v55 < v29->pBounding.x1
-        || v54 > v29->pBounding.y2
-        || v53 < v29->pBounding.y1
-        || v52 > v29->pBounding.z2
-        || v51 < v29->pBounding.z1 ) )
-	  {
-		  v32 = (unsigned __int64)(v49 * (signed __int64)v29->pFacePlane_old.vNormal.x) >> 16;
-		  v33 = (unsigned __int64)(v47 * (signed __int64)v29->pFacePlane_old.vNormal.z) >> 16;
-		  v34 = (unsigned __int64)(v48 * (signed __int64)v29->pFacePlane_old.vNormal.y) >> 16;
-		  v35 = v32 + v33 + v34 == 0;
-		  v36 = v32 + v33 + v34;
-		  v59 = v32 + v33 + v34;
-		  if ( !v35 )
-		  {
-			  v37 = obj_z * v29->pFacePlane_old.vNormal.z;
-			  v38 = -(v29->pFacePlane_old.dist + v37 + obj_x * v29->pFacePlane_old.vNormal.x + obj_y * v29->pFacePlane_old.vNormal.y);
-			  if ( v36 <= 0 ^ v29->pFacePlane_old.dist + v37 + obj_x * v29->pFacePlane_old.vNormal.x + obj_y * v29->pFacePlane_old.vNormal.y <= 0)
-			  {
-				v39 = abs(-(v29->pFacePlane_old.dist
-						  + v37
-						  + obj_x * v29->pFacePlane_old.vNormal.x
-						  + obj_y * v29->pFacePlane_old.vNormal.y)) >> 14;
-				if ( v39 > abs(v36)
-				  || (LODWORD(v40) = v38 << 16, HIDWORD(v40) = v38 >> 16, v58 = v40 / v59, (signed int)(v40 / v59) < 0)
-				  || !sub_4075DB(
-						obj_x + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v49) >> 16) + 32768) >> 16),
-						obj_y + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v48) >> 16) + 32768) >> 16),
-						obj_z + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v47) >> 16) + 32768) >> 16),
-						v29) )
-				{
-				  continue;
-				}
-				if ( v29->uSectorID == v66 )
-				  v42 = v29->uBackSectorID;
-				else
-				  v42 = v29->uSectorID;
-				if ( v42 != v66 )
-				{
-				  ++v57;
-				  v66 = v42;
-				  if ( v42 == obj2_sector )
-					return 1;
-				  if ( v57 < 30 && pIndoor->pSectors[v66].uNumPortals > 0)
-				  {
-					  v61=-1;
-					  continue;
-				  }
+		v70 = v29->pFacePlane_old.dist 
+			+ obj1_z * v29->pFacePlane_old.vNormal.z 
+			+ obj1_x * v29->pFacePlane_old.vNormal.x 
+			+ obj1_y * v29->pFacePlane_old.vNormal.y;
+		v38 = -v70;
+
+		// if ( v59 <= 0 ^ v70 <= 0 )
+		
+		/* TEMPORARY
+		if ( v59 <= 0 && v70 <= 0 )
+		{
+			continue;
+		}
+		if ( !(v59 <= 0 && v70 <= 0) )
+		{
+			continue;
+		}
+		*/
+
+		if( abs(v38) >> 14 > abs(v59) )
+			continue;
+
+		v58 = fixpoint_sub2(v38,v59);
+
+		if( v58 < 0 )
+		{
+			continue;
+		}
 
-				}
-				break;
-			  }
-		  }
-	  }
-    }
-  if ( v66 != obj2_sector )
+		if(!sub_4075DB(
+				obj1_x + ((fixpoint_sub0(v49,v58) + 32768) >> 16),
+				obj1_y + ((fixpoint_sub0(v48,v58) + 32768) >> 16),
+				obj1_z + ((fixpoint_sub0(v47,v58) + 32768) >> 16),
+				v29) )
+		{
+			continue;
+		}
+
+		//if there is no next sector turn back
+		if ( v29->uSectorID == current_sector )
+			next_sector = v29->uBackSectorID;
+		else
+			next_sector = v29->uSectorID;
+
+		//no more portals, quit
+		if ( next_sector == current_sector )
+		{
+			break;
+		}
+
+		++sectors_visited;
+		current_sector = next_sector;
+
+		//found player, quit
+		if ( next_sector == obj2_sector )
+			return 1;
+
+		current_sector = next_sector;
+
+		//did we hit limit for portals?
+		//does the next room have portals?
+		if ( sectors_visited < 30 && pIndoor->pSectors[current_sector].uNumPortals > 0)
+		{
+				current_portal=-1;
+				continue;
+		}
+		else
+			break;
+	}
+  }
+  //did we stop in the sector where player is?
+  if ( current_sector != obj2_sector )
     return 0;
   return 1;
 }
 
 //----- (004075DB) --------------------------------------------------------
-bool __fastcall sub_4075DB(int a1, int a2, int a3, BLVFace *a4)
+bool __fastcall sub_4075DB(int x, int y, int z, BLVFace *a4)
 {
   unsigned int v5; // esi@1
   char v7; // zf@2
@@ -4590,57 +4600,57 @@
   v9 = pIndoor->pVertices;
   if ( v5 & FACE_XY_PLANE )
   {
-    a4a = a1;
-    v8 = a2;
+    a4a = x;
+    v8 = y;
     for(int i = 0; i < a4->uNumVertices; i++)
 	{
         dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].x;
-        dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].y;
+        dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].y;
 	}
   }
   else
   {
-    v8 = a3;
-    if ( v5 & FACE_XY_PLANE )
+    v8 = z;
+    if ( v5 & FACE_XZ_PLANE )
     {
-      a4a = a1;
+      a4a = x;
       for(int i = 0; i < a4->uNumVertices; i++)
 	  {
 		dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].x;
-		dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].z;
+		dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].z;
 	  }
     }
     else
     {
-      a4a = a2;
+      a4a = y;
       for(int i = 0; i < a4->uNumVertices; i++)
 	  {
 		dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].y;
-		dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].z;
+		dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].z;
 	  }
     }
   }
   a3a = 0;
   dword_4F5D98_xs[a4->uNumVertices] = dword_4F5D98_xs[0];
-  dword_4F5CC4_ys[a4->uNumVertices + 1] = dword_4F5CC4_ys[1];
-  for(int i = 0; i < a4->uNumVertices; i++)
+  dword_4F5CC8_ys[a4->uNumVertices] = dword_4F5CC8_ys[0];
+  for(int i = 0; i < a4->uNumVertices && a3a < 2; i++)
   {
-    if ( a3a >= 2 )
-      break;
-    if ( dword_4F5CC4_ys[i + 1] >= v8 ^ (dword_4F5CC4_ys[i + 2] >= v8) )
+    if ( dword_4F5CC8_ys[i] >= v8 ^ (dword_4F5CC8_ys[i + 1] >= v8) )
     {
-	  if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a)
+	  //if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a)
+	  if( !(dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] < a4a))
       {
-		  if ( (dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] >= a4a)
-          || (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],
-              LODWORD(v26) = v25 << 16,
-              HIDWORD(v26) = v25 >> 16,
-              dword_4F5D98_xs[i]
-            + ((signed int)(((unsigned __int64)(v26
-                                              / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])
-                                              * ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16)
-                          + 32768) >> 16) >= a4a) )
-          ++a3a;
+		  if ( (dword_4F5D98_xs[i + 1] < a4a && dword_4F5D98_xs[i] >= a4a) )
+			  ++a3a;
+		  //|| (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],LODWORD(v26) = v25 << 16, HIDWORD(v26) = v25 >> 16, 
+		  //dword_4F5D98_xs[i] + ((signed int)(((unsigned __int64)(v26 / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])* ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16)
+          //                + 32768) >> 16) >= a4a) )
+		  else
+		  {
+			v25 = fixpoint_sub2(dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i], dword_4F5CC8_ys[i + 1] - dword_4F5CC8_ys[i]);
+			if( dword_4F5D98_xs[i] + (fixpoint_sub0(v25, (v8 - dword_4F5CC8_ys[i]) << 16) + 32768 >> 16) >= a4a)
+				++a3a;
+		  }
       }
     }
   }
@@ -4966,12 +4976,12 @@
   if (no_rightlick_in_inventory)
     return;
 
+  pMouse->GetCursorPos(&a2);
   if (a2.x <= 13 || a2.x >= 462)
     return;
 
   auto player = pPlayers[uActiveCharacter];
 
-  pMouse->GetCursorPos(&a2);
   int item_pid = pRenderer->pActiveZBuffer[a2.x + pSRZBufferLineOffsets[a2.y]] & 0xFFFF;
   //pMouse->GetClickPos(&pX, &pY);
   if (!item_pid)
--- a/mm7_data.cpp	Sun Sep 15 02:20:06 2013 +0200
+++ b/mm7_data.cpp	Sun Sep 15 02:21:26 2013 +0200
@@ -860,10 +860,10 @@
 int dword_4F5428[777]; // weak
 int dword_4F542C[777]; // weak
 _UNKNOWN crtunk_4F54B8; // weak
-std::array<int, 777> dword_4F5B24_ys; // idb
-std::array<int, 777> dword_4F5BF4_xs; // idb
-std::array<int, 777> dword_4F5CC4_ys; // idb
-std::array<int, 777> dword_4F5D98_xs; // idb
+std::array<int, 52> dword_4F5B24_ys; // idb
+std::array<int, 52> dword_4F5BF4_xs; // idb
+std::array<int, 52> dword_4F5CC8_ys; // idb
+std::array<int, 52> dword_4F5D98_xs; // idb
 std::array<int, 500> ai_array_4F5E68;
 std::array<int, 500> ai_array_4F6638_actor_ids;
 std::array<int, 500> ai_near_actors_targets_pid;
--- a/mm7_data.h	Sun Sep 15 02:20:06 2013 +0200
+++ b/mm7_data.h	Sun Sep 15 02:21:26 2013 +0200
@@ -509,10 +509,10 @@
 extern int dword_4F5428[]; // weak
 extern int dword_4F542C[]; // weak
 extern _UNKNOWN crtunk_4F54B8; // weak
-extern std::array<int, 777> dword_4F5B24_ys; // idb
-extern std::array<int, 777> dword_4F5BF4_xs; // idb
-extern std::array<int, 777> dword_4F5CC4_ys; // idb
-extern std::array<int, 777> dword_4F5D98_xs; // idb
+extern std::array<int, 52> dword_4F5B24_ys; // idb
+extern std::array<int, 52> dword_4F5BF4_xs; // idb
+extern std::array<int, 52> dword_4F5CC8_ys; // idb
+extern std::array<int, 52> dword_4F5D98_xs; // idb
 extern std::array<int, 500> ai_array_4F5E68;
 extern std::array<int, 500> ai_array_4F6638_actor_ids;
 extern std::array<int, 500> ai_near_actors_targets_pid;