changeset 684:08b6d89d6a10

Слияние
author Ritor1
date Fri, 15 Mar 2013 18:29:06 +0600
parents d4497b76a863 (current diff) 551f74425b17 (diff)
children 483fa38be9a6
files Indoor.cpp UIHouses.cpp stru10.cpp
diffstat 26 files changed, 1792 insertions(+), 1432 deletions(-) [+]
line wrap: on
line diff
--- a/Game.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/Game.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -631,7 +631,7 @@
   if (!_44F07B())
     return false;
 
-    if ( uFlags & 8 )
+    if ( uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
       LOBYTE(pStru10Instance->field_4) = 0;
     if ( pRenderer->pRenderD3D && uCurrentlyLoadedLevelType == LEVEL_Outdoor)
     {
--- a/Game.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/Game.h	Fri Mar 15 18:29:06 2013 +0600
@@ -16,6 +16,7 @@
 
 
 
+#define GAME_FLAGS_1_DRAW_BLV_DEBUGS    0x08
 #define GAME_FLAGS_2_SATURATE_LIGHTMAPS 0x02
 #define GAME_FLAGS_2_ALTER_GRAVITY      0x08
 #define GAME_FLAGS_2_TARGETING_MODE     0x10
--- a/Indoor.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/Indoor.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -272,28 +272,28 @@
   if (bD3D)
   {
     pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
-    for (uint i = 0; i < pBspRenderer->uNumFaceIDs; ++i)
+    for (uint i = 0; i < pBspRenderer->num_faces; ++i)
     {
-      v2 = pBspRenderer->pFaceIDs[2 * i + 1];
-      if ( pBspRenderer->pSectors[v2].std__vector_0007A8 == -1 )
+      v2 = pBspRenderer->faces[i].uNodeID;
+      if ( pBspRenderer->nodes[v2].std__vector_0007A8 == -1 )
       {
         v6 = 0;
         v3 = 0;
       }
       else
       {
-        v3 = pBspRenderer->pSectors[v2].std__vector_0007AC;
-        v6 = pBspRenderer->pSectors[v2].pVertices;
+        v3 = pBspRenderer->nodes[v2].std__vector_0007AC;
+        v6 = pBspRenderer->nodes[v2].pVertices;
       }
-      IndoorLocation::ExecDraw_d3d(pBspRenderer->pFaceIDs[2 * i], v3, 4, v6);
+      IndoorLocation::ExecDraw_d3d(pBspRenderer->faces[i].uFaceID, v3, 4, v6);
     }
   }
   else
   {
-    for (uint j = 0; j < pBspRenderer->uNumFaceIDs; ++j )
+    for (uint j = 0; j < pBspRenderer->num_faces; ++j )
     {
-      v5 = pBspRenderer->pFaceIDs[2 * j];
-      pBLVRenderParams->field_7C = &pBspRenderer->pSectors[pBspRenderer->pFaceIDs[2 * j + 1]].field_C;
+      v5 = pBspRenderer->faces[j].uFaceID;
+      pBLVRenderParams->field_7C = &pBspRenderer->nodes[pBspRenderer->faces[j].uNodeID].field_C;
       IndoorLocation::ExecDraw_sw(v5);
     }
   }
@@ -314,6 +314,7 @@
   if (pBLVRenderParams->uPartySectorID)
     IndoorLocation::ExecDraw(pRenderer->pRenderD3D != 0);
   pRenderer->DrawBillboardList_BLV();
+
   if ( !pRenderer->pRenderD3D )
   {
     if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_D3D_OUTLINES)
@@ -322,17 +323,17 @@
     {
       v1 = pBLVRenderParams->pRenderTarget;
       v6 = 0;
-      if ( (signed int)pBspRenderer->pNumSectors > 0 )
+      if ( (signed int)pBspRenderer->num_nodes > 0 )
       {
         v7 = 0;
-        v2 = (char *)&pBspRenderer->pSectors[0].field_C._viewport_space_w;
+        v2 = (char *)&pBspRenderer->nodes[0].field_C._viewport_space_w;
         do
         {
           v3 = *((int *)v2 - 1);
           v4 = pRenderer->uTargetSurfacePitch * *((int *)v2 - 1);
           if ( v3 <= *(int *)v2 )
           {
-            v5 = (char *)&pBspRenderer->pSectors[0].field_C.array_3D8[v3 + v7];
+            v5 = (char *)&pBspRenderer->nodes[0].field_C.array_3D8[v3 + v7];
             do
             {
               v1[v4 + *((short *)v5 - 480)] = 255;
@@ -347,7 +348,7 @@
           v7 += 1126;
           v2 += 2252;
         }
-        while ( v6 < (signed int)pBspRenderer->pNumSectors );
+        while ( v6 < (signed int)pBspRenderer->num_nodes );
       }
     }
   }
@@ -527,7 +528,7 @@
           stru_F7B60C.face_plane.dist = pFace->pFacePlane.dist;
         }
 
-        if (stru_F8AD28.uNumLightsApplied > 0 && !(pFace->uAttributes & 0x400000))
+        if (stru_F8AD28.uNumLightsApplied > 0 && !(pFace->uAttributes & FACE_DO_NOT_LIGHT))
           pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0);
 
         if (pDecalBuilder->uNumDecals > 0)
@@ -564,7 +565,7 @@
           if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
             _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
           else
-            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | 6, v17, 0);
+            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
           return;
         }
         //v17 = 0xFFFFFFFF;
@@ -1233,7 +1234,7 @@
 }
 
 //----- (004B0EA8) --------------------------------------------------------
-void BspRenderer::AddFaceToRenderList_d3d(int a2, unsigned int uFaceID)
+void BspRenderer::AddFaceToRenderList_d3d(unsigned int node_id, unsigned int uFaceID)
 {
   //unsigned int v3; // edx@1
   //stru170 *v4; // ebx@1
@@ -1242,10 +1243,10 @@
   unsigned __int16 v7; // ax@11
   Vec3_short_ *v8; // esi@15
   int v9; // edx@15
-  signed int v10; // eax@18
-  signed int v11; // edi@19
-  signed int v12; // ecx@19
-  signed int v13; // esi@19
+  //signed int v10; // eax@18
+  //signed int v11; // edi@19
+  //signed int v12; // ecx@19
+  //signed int v13; // esi@19
   signed int v14; // edx@20
   int v15; // edx@24
   //int v16; // esi@29
@@ -1263,33 +1264,41 @@
   //signed int v28; // ST28_4@47
   char v29; // al@48
   signed int v30; // eax@51
-  int v31; // eax@52
+  //int v31; // eax@52
   //unsigned int v32; // eax@55
   //__int16 v33; // cx@56
-  signed int v34; // [sp+Ch] [bp-14h]@18
+  //signed int v34; // [sp+Ch] [bp-14h]@18
   //int a0; // [sp+14h] [bp-Ch]@2
   //IndoorCameraD3D *a0a; // [sp+14h] [bp-Ch]@36
-  signed int v37; // [sp+18h] [bp-8h]@19
+  //signed int v37; // [sp+18h] [bp-8h]@19
   //stru10 *v38; // [sp+18h] [bp-8h]@36
   //BLVFace *v39; // [sp+1Ch] [bp-4h]@1
 
   //v3 = uFaceID;
   //v4 = this;
   //v5 = &pIndoor->pFaces[uFaceID];
-  pSectors[pNumSectors].std__vector_0007A8 = -1;
+  nodes[num_nodes].std__vector_0007A8 = -1;
   //v39 = &pIndoor->pFaces[uFaceID];
 
   auto pFace = &pIndoor->pFaces[uFaceID];
 
-  if (pFace->TwoSided())
+  if (!pFace->Portal())
   {
-    auto p = &pSectors[a2];
+    if (num_faces < 1000)
+    {
+      faces[num_faces].uFaceID = uFaceID;
+      faces[num_faces++].uNodeID = node_id;
+    }
+    return;
+  }
+
+    auto p = &nodes[node_id];
     //v6 = (int)((char *)this + 2252 * a2);
     //a0 = v6;
     if (p->uFaceID == uFaceID)
       return;
-    if (!a2 &&
-        pBLVRenderParams->vPartyPos.x >= pFace->pBounding.x1 - 16 &&
+    if (!node_id &&
+        pBLVRenderParams->vPartyPos.x >= pFace->pBounding.x1 - 16 &&  // we are probably standing at the portal plane
         pBLVRenderParams->vPartyPos.x <= pFace->pBounding.x2 + 16 &&
         pBLVRenderParams->vPartyPos.y >= pFace->pBounding.y1 - 16 &&
         pBLVRenderParams->vPartyPos.y <= pFace->pBounding.y2 + 16 &&
@@ -1298,59 +1307,80 @@
     {
       if ( abs(pFace->pFacePlane_old.dist + pBLVRenderParams->vPartyPos.x * pFace->pFacePlane_old.vNormal.x
                                        + pBLVRenderParams->vPartyPos.y * pFace->pFacePlane_old.vNormal.y
-                                       + pBLVRenderParams->vPartyPos.z * pFace->pFacePlane_old.vNormal.z) <= 589824 )
+                                       + pBLVRenderParams->vPartyPos.z * pFace->pFacePlane_old.vNormal.z) <= 589824 ) // we sure are standing at the portal plane
       {
         v7 = pFace->uSectorID;
-        if ( pSectors[0].uSectorID == v7 )
+        if ( nodes[0].uSectorID == v7 )  // draw back sector
           v7 = pFace->uBackSectorID;
-        pSectors[pNumSectors].uSectorID = v7;
-        pSectors[pNumSectors].uFaceID = uFaceID;
-        pSectors[pNumSectors].uViewportX = pBLVRenderParams->uViewportX;
-        pSectors[pNumSectors].uViewportZ = pBLVRenderParams->uViewportZ;
-        pSectors[pNumSectors].uViewportY = pBLVRenderParams->uViewportY;
-        pSectors[pNumSectors].uViewportW = pBLVRenderParams->uViewportW;
-        pSectors[pNumSectors++].field_C._43F9E1(
-          pBLVRenderParams->uViewportX,
-          pBLVRenderParams->uViewportY,
-          pBLVRenderParams->uViewportZ,
-          pBLVRenderParams->uViewportW);
-        sub_440639(pNumSectors - 1);
+        nodes[num_nodes].uSectorID = v7;
+        nodes[num_nodes].uFaceID = uFaceID;
+        nodes[num_nodes].uViewportX = pBLVRenderParams->uViewportX;
+        nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ;
+        nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY;
+        nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW;
+        nodes[num_nodes++].field_C._43F9E1(pBLVRenderParams->uViewportX,
+                                             pBLVRenderParams->uViewportY,
+                                             pBLVRenderParams->uViewportZ,
+                                             pBLVRenderParams->uViewportW);
+        AddBspNodeToRenderList(num_nodes - 1);
         return;
       }
       //v5 = v39;
       //v6 = a0;
     }
+
     v8 = &pIndoor->pVertices[pFace->pVertexIDs[0]];
     v9 = pFace->pFacePlane_old.vNormal.x * (v8->x - pBLVRenderParams->vPartyPos.x)
        + pFace->pFacePlane_old.vNormal.y * (v8->y - pBLVRenderParams->vPartyPos.y)
        + pFace->pFacePlane_old.vNormal.z * (v8->z - pBLVRenderParams->vPartyPos.z);
     if (p->uSectorID != pFace->uSectorID)
       v9 = -v9;
-    if ( v9 < 0 )
+    if (v9 >= 0)
+      return;
+
+    auto num_vertices = sub_423B5D(uFaceID);
+    if (num_vertices < 2)
+      return;
+
+    auto face_min_screenspace_x = _50BAC8_screen_space_x[0],
+         face_max_screenspace_x = _50BAC8_screen_space_x[0];
+    auto face_min_screenspace_y = _50B9D8_screen_space_y[0],
+         face_max_screenspace_y = _50B9D8_screen_space_y[0];
+    for (uint i = 1; i < num_vertices; ++i)
     {
-      v10 = sub_423B5D(uFaceID);
-      v34 = v10;
-      if ( v10 )
-      {
-        v11 = dword_50BAC8[0];
-        v12 = dword_50B9D8_ys[0];
-        a2 = dword_50BAC8[0];
+      if (face_min_screenspace_x > _50BAC8_screen_space_x[i])
+        face_min_screenspace_x = _50BAC8_screen_space_x[i];
+      if (face_max_screenspace_x < _50BAC8_screen_space_x[i])
+        face_max_screenspace_x = _50BAC8_screen_space_x[i];
+
+      if (face_min_screenspace_y > _50B9D8_screen_space_y[i])
+        face_min_screenspace_y = _50B9D8_screen_space_y[i];
+      if (face_max_screenspace_y < _50B9D8_screen_space_y[i])
+        face_max_screenspace_y = _50B9D8_screen_space_y[i];
+    }
+      //v10 = sub_423B5D(uFaceID);
+      //v34 = v10;
+      //if ( v10 )
+      //{
+       /* v11 = _50BAC8_screen_space_x[0];
+        v12 = _50B9D8_screen_space_y[0];
+        a2 = _50BAC8_screen_space_x[0];
         v13 = 1;
-        v37 = dword_50B9D8_ys[0];
+        v37 = _50B9D8_screen_space_y[0];
         if ( v10 > 1 )
         {
           do
           {
-            v14 = dword_50BAC8[v13];
+            v14 = _50BAC8_screen_space_x[v13];
             if ( v14 < a2 )
-              a2 = dword_50BAC8[v13];
+              a2 = _50BAC8_screen_space_x[v13];
             if ( v14 > v11 )
               v11 = v14;
-            v15 = dword_50B9D8_ys[v13];
+            v15 = _50B9D8_screen_space_y[v13];
             if ( v15 < v37 )
-              v37 = dword_50B9D8_ys[v13];
+              v37 = _50B9D8_screen_space_y[v13];
             if ( v15 > v12 )
-              v12 = dword_50B9D8_ys[v13];
+              v12 = _50B9D8_screen_space_y[v13];
             v10 = v34;
             ++v13;
           }
@@ -1361,24 +1391,28 @@
             a2 <= p->uViewportZ &&
             v12 >= p->uViewportY &&
             v37 <= p->uViewportW &&
-            sub_424829(v10, &pSectors[pNumSectors].field_C, &p->field_C, uFaceID))
+            sub_424829(v10, &nodes[num_nodes].field_C, &p->field_C, uFaceID))*/
+      if (face_max_screenspace_x >= p->uViewportX &&
+          face_min_screenspace_x <= p->uViewportZ &&
+          face_max_screenspace_y >= p->uViewportY &&
+          face_min_screenspace_y <= p->uViewportW &&
+          sub_424829(num_vertices, &nodes[num_nodes].field_C, &p->field_C, uFaceID))
         {
           //v17 = v39;
           v18 = pFace->uSectorID;
           if (p->uSectorID == v18 )
             v18 = pFace->uBackSectorID;
-          pSectors[pNumSectors].uSectorID = v18;
-          pSectors[pNumSectors].uFaceID = uFaceID;
-          pSectors[pNumSectors].uViewportX = pBLVRenderParams->uViewportX;
-          pSectors[pNumSectors].uViewportZ = pBLVRenderParams->uViewportZ;
-          pSectors[pNumSectors].uViewportY = pBLVRenderParams->uViewportY;
-          pSectors[pNumSectors].uViewportW = pBLVRenderParams->uViewportW;
+          nodes[num_nodes].uSectorID = v18;
+          nodes[num_nodes].uFaceID = uFaceID;
+          nodes[num_nodes].uViewportX = pBLVRenderParams->uViewportX;
+          nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ;
+          nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY;
+          nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW;
           //v38 = pGame->pStru10Instance;
           //a0a = pGame->pIndoorCameraD3D;
           if (p->std__vector_0007A8 == -1 )
           {
-            v29 = pGame->pStru10Instance->_49C681_DrawDebugStuff(pFace, pSectors[pNumSectors].std__vector_0007AC,
-                    pSectors[pNumSectors].pVertices);
+            v29 = pGame->pStru10Instance->_49C681_DrawDebugStuff(pFace, nodes[num_nodes].std__vector_0007AC, nodes[num_nodes].pVertices);
           }
           else
           {
@@ -1386,7 +1420,7 @@
             static RenderVertexSoft static_subAddFaceToRenderList_d3d_stru_F79E08[64];
 
             //v23 = 0;
-            a2 = pFace->uNumVertices;
+            unsigned int a2 = pFace->uNumVertices;
             for (uint k = 0; k < pFace->uNumVertices; ++k)
             {
               //v24 = (char *)&static_subAddFaceToRenderList_d3d_stru_F7AA08[0].vWorldPosition.z;
@@ -1405,40 +1439,37 @@
               //}
               //while ( v23 < a2 );
             }
-            pGame->pIndoorCameraD3D->_437285_prolly_colide_vertices_against_frustrum(static_subAddFaceToRenderList_d3d_stru_F7AA08,
-              (unsigned int *)&a2, static_subAddFaceToRenderList_d3d_stru_F79E08, p->std__vector_0007AC, 4, 0, 0);
-            v29 = pGame->pStru10Instance->_49C5DA(pFace, static_subAddFaceToRenderList_d3d_stru_F79E08, &a2, pSectors[pNumSectors].std__vector_0007AC,
-                    pSectors[pNumSectors].pVertices);
+            pGame->pIndoorCameraD3D->_437285_prolly_colide_vertices_against_frustrum(
+              static_subAddFaceToRenderList_d3d_stru_F7AA08,
+              &a2,
+              static_subAddFaceToRenderList_d3d_stru_F79E08,
+              p->std__vector_0007AC,
+              4,
+              0,
+              0);
+            v29 = pGame->pStru10Instance->_49C5DA(pFace, static_subAddFaceToRenderList_d3d_stru_F79E08, (int *)&a2,
+                    nodes[num_nodes].std__vector_0007AC,
+                    nodes[num_nodes].pVertices);
           }
           if ( v29 )
           {
-            pSectors[pNumSectors].std__vector_0007A8 = uFaceID;
-            v30 = pNumSectors;
+            nodes[num_nodes].std__vector_0007A8 = uFaceID;
+            v30 = num_nodes;
             if ( v30 < 150 )
             {
-              v31 = v30 + 1;
-              pNumSectors = v31;
-              sub_440639(v31 - 1);
+              //v31 = v30 + 1;
+              num_nodes = v30 + 1;
+              AddBspNodeToRenderList(v30);
             }
           }
           if (pBLVRenderParams->uFlags & INDOOR_CAMERA_DRAW_SW_OUTLINES)
             pGame->pIndoorCameraD3D->PrepareAndDrawDebugOutline(pFace, 0x1E1EFF);
         }
-      }
-    }
-  }
-  else
-  {
-    if (uNumFaceIDs < 1000 )
-    {
-      pFaceIDs[2 * uNumFaceIDs] = uFaceID;
-      pFaceIDs[2 * uNumFaceIDs++ + 1] = a2;
-    }
-  }
 }
 
+
 //----- (004AFB86) --------------------------------------------------------
-void BspRenderer::AddFaceToRenderList_sw(int a2, unsigned int uFaceID)
+void BspRenderer::AddFaceToRenderList_sw(unsigned int node_id, unsigned int uFaceID)
 {
   BspRenderer *v3; // ebx@1
   BLVFace *v4; // eax@1
@@ -1465,13 +1496,13 @@
   v3 = this;
   v4 = &pIndoor->pFaces[uFaceID];
   v21 = v4;
-  if (v4->TwoSided())
+  if (v4->Portal())
   {
-    v5 = (char *)this + 2252 * a2;
+    v5 = (char *)this + 2252 * node_id;
     v20 = v5;
     if ( uFaceID == *((short *)v5 + 2982) )
       return;
-    if ( !a2
+    if (!node_id
       && pBLVRenderParams->vPartyPos.x >= v4->pBounding.x1 - 16
       && pBLVRenderParams->vPartyPos.x <= v4->pBounding.x2 + 16
       && pBLVRenderParams->vPartyPos.y >= v4->pBounding.y1 - 16
@@ -1484,20 +1515,20 @@
                                        + pBLVRenderParams->vPartyPos.z * v4->pFacePlane_old.vNormal.z) <= 589824 )
       {
         v6 = v21->uSectorID;
-        if ( v3->pSectors[0].uSectorID == v6 )
+        if ( v3->nodes[0].uSectorID == v6 )
           v6 = v21->uBackSectorID;
-        v3->pSectors[v3->pNumSectors].uSectorID = v6;
-        v3->pSectors[v3->pNumSectors].uFaceID = uFaceID;
-        v3->pSectors[v3->pNumSectors].uViewportX = LOWORD(pBLVRenderParams->uViewportX);
-        v3->pSectors[v3->pNumSectors].uViewportZ = LOWORD(pBLVRenderParams->uViewportZ);
-        v3->pSectors[v3->pNumSectors].uViewportY = LOWORD(pBLVRenderParams->uViewportY);
-        v3->pSectors[v3->pNumSectors].uViewportW = LOWORD(pBLVRenderParams->uViewportW);
-        v3->pSectors[v3->pNumSectors++].field_C._43F9E1(
+        v3->nodes[v3->num_nodes].uSectorID = v6;
+        v3->nodes[v3->num_nodes].uFaceID = uFaceID;
+        v3->nodes[v3->num_nodes].uViewportX = LOWORD(pBLVRenderParams->uViewportX);
+        v3->nodes[v3->num_nodes].uViewportZ = LOWORD(pBLVRenderParams->uViewportZ);
+        v3->nodes[v3->num_nodes].uViewportY = LOWORD(pBLVRenderParams->uViewportY);
+        v3->nodes[v3->num_nodes].uViewportW = LOWORD(pBLVRenderParams->uViewportW);
+        v3->nodes[v3->num_nodes++].field_C._43F9E1(
           SLOWORD(pBLVRenderParams->uViewportX),
           pBLVRenderParams->uViewportY,
           SLOWORD(pBLVRenderParams->uViewportZ),
           pBLVRenderParams->uViewportW);
-        v7 = v3->pNumSectors - 1;
+        v7 = v3->num_nodes - 1;
         goto LABEL_14;
       }
       v4 = v21;
@@ -1515,25 +1546,25 @@
       v19 = v10;
       if ( v10 )
       {
-        v11 = dword_50BAC8[0];
-        v12 = dword_50B9D8_ys[0];
-        v23 = dword_50BAC8[0];
+        v11 = _50BAC8_screen_space_x[0];
+        v12 = _50B9D8_screen_space_y[0];
+        v23 = _50BAC8_screen_space_x[0];
         v13 = 1;
-        v22 = dword_50B9D8_ys[0];
+        v22 = _50B9D8_screen_space_y[0];
         if ( v10 > 1 )
         {
           do
           {
-            v14 = dword_50BAC8[v13];
+            v14 = _50BAC8_screen_space_x[v13];
             if ( v14 < v23 )
-              v23 = dword_50BAC8[v13];
+              v23 = _50BAC8_screen_space_x[v13];
             if ( v14 > v11 )
-              v11 = dword_50BAC8[v13];
-            v15 = dword_50B9D8_ys[v13];
+              v11 = _50BAC8_screen_space_x[v13];
+            v15 = _50B9D8_screen_space_y[v13];
             if ( v15 < v22 )
-              v22 = dword_50B9D8_ys[v13];
+              v22 = _50B9D8_screen_space_y[v13];
             if ( v15 > v12 )
-              v12 = dword_50B9D8_ys[v13];
+              v12 = _50B9D8_screen_space_y[v13];
             v10 = v19;
             ++v13;
           }
@@ -1543,25 +1574,25 @@
           && v23 <= *((short *)v20 + 2007)
           && v12 >= *((short *)v20 + 2006)
           && v22 <= *((short *)v20 + 2008)
-          && sub_424829(v10, &v3->pSectors[v3->pNumSectors].field_C, (BspRenderer_stru2 *)(v20 + 4020), uFaceID) )
+          && sub_424829(v10, &v3->nodes[v3->num_nodes].field_C, (BspRenderer_stru2 *)(v20 + 4020), uFaceID) )
         {
           v16 = v21->uSectorID;
           if ( *((short *)v20 + 2004) == v16 )
             v16 = v21->uBackSectorID;
-          v3->pSectors[v3->pNumSectors].uSectorID = v16;
-          v3->pSectors[v3->pNumSectors].uFaceID = uFaceID;
-          v3->pSectors[v3->pNumSectors].uViewportX = LOWORD(pBLVRenderParams->uViewportX);
-          v3->pSectors[v3->pNumSectors].uViewportZ = LOWORD(pBLVRenderParams->uViewportZ);
-          v3->pSectors[v3->pNumSectors].uViewportY = LOWORD(pBLVRenderParams->uViewportY);
-          v3->pSectors[v3->pNumSectors].uViewportW = LOWORD(pBLVRenderParams->uViewportW);
-          v17 = v3->pNumSectors;
+          v3->nodes[v3->num_nodes].uSectorID = v16;
+          v3->nodes[v3->num_nodes].uFaceID = uFaceID;
+          v3->nodes[v3->num_nodes].uViewportX = LOWORD(pBLVRenderParams->uViewportX);
+          v3->nodes[v3->num_nodes].uViewportZ = LOWORD(pBLVRenderParams->uViewportZ);
+          v3->nodes[v3->num_nodes].uViewportY = LOWORD(pBLVRenderParams->uViewportY);
+          v3->nodes[v3->num_nodes].uViewportW = LOWORD(pBLVRenderParams->uViewportW);
+          v17 = v3->num_nodes;
           if ( v17 < 150 )
           {
             v18 = v17 + 1;
-            v3->pNumSectors = v18;
+            v3->num_nodes = v18;
             v7 = v18 - 1;
 LABEL_14:
-            sub_440639(v7);
+            AddBspNodeToRenderList(v7);
             return;
           }
         }
@@ -1570,10 +1601,10 @@
   }
   else
   {
-    if ( (signed int)this->uNumFaceIDs < 1000 )
+    if (num_faces < 1000)
     {
-      this->pFaceIDs[2 * this->uNumFaceIDs] = uFaceID;
-      this->pFaceIDs[2 * this->uNumFaceIDs++ + 1] = a2;
+      faces[num_faces].uFaceID = uFaceID;
+      faces[num_faces++].uNodeID = node_id;
     }
   }
 }
@@ -1590,15 +1621,15 @@
   int v6; // ecx@7
   int v7; // esi@8
 
-  for ( i = 0; i < (signed int)pBspRenderer->uNumFaceIDs; ++i )
+  for ( i = 0; i < (signed int)pBspRenderer->num_faces; ++i )
   {
-    v1 = pBspRenderer->pFaceIDs[2 * i];
+    v1 = pBspRenderer->faces[i].uFaceID;
     if ( v1 >= 0 )
     {
       if ( v1 < (signed int)pIndoor->uNumFaces )
       {
-        v2 = pBspRenderer->pFaceIDs[2 * i];
-        pBLVRenderParams->field_7C = &pBspRenderer->pSectors[pBspRenderer->pFaceIDs[2 * i + 1]].field_C;
+        v2 = pBspRenderer->faces[i].uFaceID;
+        pBLVRenderParams->field_7C = &pBspRenderer->nodes[pBspRenderer->faces[i].uNodeID].field_C;
         v3 = sub_423B5D(v2);
         if ( v3 )
         {
@@ -2471,21 +2502,6 @@
     MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Polydata.cpp:803", 0);
     return 0;
   }
-
-  assert(sizeof(Vec3_short_) == 6);
-  assert(sizeof(BLVFace) == 96);
-  assert(sizeof(BLVFaceExtra) == 36);
-  assert(sizeof(BLVSector) == 116);
-  assert(sizeof(LevelDecoration) == 32);
-  assert(sizeof(BLVLightMM7) == 16);
-  assert(sizeof(BSPNode) == 8);
-  assert(sizeof(SpawnPointMM7) == 24);
-  assert(sizeof(DDM_DLV_Header) == 40);
-  assert(sizeof(Actor) == 836);
-  assert(sizeof(SpriteObject) == 112);
-  assert(sizeof(Chest) == 5324);
-  assert(sizeof(stru123) == 0xC8);
-  assert(sizeof(BLVMapOutline) == 12);
   
   bLoaded = true;
 
@@ -2515,13 +2531,13 @@
     pFace->pVertexIDs = ptr_2AC + j;
     
     j += pFace->uNumVertices + 1;
-    pFace->pXInterceptDisplacements = ptr_2AC + j;
+    pFace->pXInterceptDisplacements = (short *)(ptr_2AC + j);
 
     j += pFace->uNumVertices + 1;
-    pFace->pYInterceptDisplacements = ptr_2AC + j;
+    pFace->pYInterceptDisplacements = (short *)(ptr_2AC + j);
 
     j += pFace->uNumVertices + 1;
-    pFace->pZInterceptDisplacements = ptr_2AC + j;
+    pFace->pZInterceptDisplacements = (short *)(ptr_2AC + j);
 
     j += pFace->uNumVertices + 1;
     pFace->pVertexUIDs = (__int16 *)(ptr_2AC + j);
--- a/Indoor.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/Indoor.h	Fri Mar 15 18:29:06 2013 +0600
@@ -250,7 +250,7 @@
 #pragma pack(pop)
 
 
-#define FACE_TWO_SIDED          0x00000001 // portal/two-sided
+#define FACE_PORTAL             0x00000001 // portal/two-sided
 #define FACE_CAN_SATURATE_COLOR 0x00000002
 #define FACE_TEXTURE_ANIMATED   0x00000010 // like wavy water
 #define FACE_INVISIBLE          0x00002000
@@ -284,7 +284,7 @@
 
   inline bool Invisible() const {return uAttributes & FACE_INVISIBLE;}
   inline bool Visible() const   {return !Invisible();}
-  inline bool TwoSided() const  {return uAttributes & FACE_TWO_SIDED;}
+  inline bool Portal() const    {return uAttributes & FACE_PORTAL;}
   inline bool Animated() const  {return uAttributes & FACE_TEXTURE_ANIMATED;}
   inline bool Clickable() const {return uAttributes & FACE_CLICKABLE;}
 
@@ -296,9 +296,9 @@
   int zCalc3;
   unsigned int uAttributes;
   unsigned __int16 *pVertexIDs;
-  unsigned __int16 *pXInterceptDisplacements;
-  unsigned __int16 *pYInterceptDisplacements;
-  unsigned __int16 *pZInterceptDisplacements;
+  signed __int16 *pXInterceptDisplacements;
+  signed __int16 *pYInterceptDisplacements;
+  signed __int16 *pZInterceptDisplacements;
   signed __int16   *pVertexUIDs;
   signed __int16   *pVertexVIDs;
   unsigned __int16  uFaceExtraID;
--- a/IndoorCameraD3D.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/IndoorCameraD3D.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -396,7 +396,7 @@
 //----- (00438258) --------------------------------------------------------
 bool IndoorCameraD3D::is_face_faced_to_camera(BLVFace *pFace, RenderVertexSoft *a2)
 {
-  if (pFace->TwoSided())
+  if (pFace->Portal())
     return false;
 
   //really strange cull; dot(to_cam, normal) < 0 means we see the BACK face, not font %_%
--- a/Indoor_stuff.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/Indoor_stuff.h	Fri Mar 15 18:29:06 2013 +0600
@@ -63,6 +63,14 @@
 
 
 
+#pragma pack(push, 1)
+struct BspFace
+{
+  unsigned __int16 uFaceID;
+  unsigned __int16 uNodeID;
+};
+#pragma pack(pop)
+
 
 /*  163 */
 #pragma pack(push, 1)
@@ -74,21 +82,22 @@
    // _eh_vector_constructor_iterator_(field_FA8, 2252, 150,
    //    (void (__thiscall *)(void *))stru170_stru0::stru170_stru0,
    //    (void (__thiscall *)(void *))stru170_stru0::dtor);
-    uNumFaceIDs = 0;
-    pNumSectors = 0;
+    num_faces = 0;
+    num_nodes = 0;
     uNumVisibleNotEmptySectors = 0;
   }
 
-  void AddFaceToRenderList_sw(int a2, unsigned int uFaceID);
-  void AddFaceToRenderList_d3d(signed int a2, unsigned int uFaceID);
+  void AddFaceToRenderList_sw(unsigned int node_id, unsigned int uFaceID);
+  void AddFaceToRenderList_d3d(unsigned int node_id, unsigned int uFaceID);
   void MakeVisibleSectorList();
   void DrawFaceOutlines();
 
-  unsigned int uNumFaceIDs;
-  __int16 pFaceIDs[2000];
+  unsigned int num_faces;
+  //__int16 pFaceIDs[2000];
+  BspFace faces[1000];
   //char field_130[3700];
-  unsigned int pNumSectors;
-  BspRenderer_stru0 pSectors[150];
+  unsigned int num_nodes;
+  BspRenderer_stru0 nodes[150];
   unsigned int uNumVisibleNotEmptySectors;
   unsigned __int16 pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[6];
 };
--- a/LOD.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/LOD.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -227,140 +227,98 @@
 
 //----- (004AC7C0) --------------------------------------------------------
 int LODFile_Sprites::LoadSprite(const char *pContainerName, unsigned int uPaletteID)
-{  signed int v3; // edi@1
-  LODFile_Sprites *v4; // esi@1
-  unsigned int v5; // eax@6
-  signed int v6; // ecx@10
-  Sprite *v7; // eax@11
-  FILE *v8; // eax@12
-  Sprite *v10; // edx@21
-  int v11; // eax@21
-  int v12; // eax@22
-  unsigned __int8 v13; // zf@23
-  unsigned __int8 v14; // sf@23
-  LODSprite DstBuf; // [sp+Ch] [bp-3Ch]@12
-  char *Str1; // [sp+34h] [bp-14h]@24
-  LODSprite *v17; // [sp+38h] [bp-10h]@3
-  int v18; // [sp+44h] [bp-4h]@12
+    {  
+
+    FILE *sprite_file; // eax@12
+    LODSprite temp_sprite_hdr; // [sp+Ch] [bp-3Ch]@12
+    int i, sprite_indx;
+
+    //find if already loaded
+    if ( pRenderer->pRenderD3D )
+        {
+        for (i=0; i<uNumLoadedSprites;++i)
+            {
+            if (!(_strcmpi(pHardwareSprites[i].pName, pContainerName)))
+                return i;
+            } 
+        }
+    else
+        {
+        for (i=0; i<uNumLoadedSprites;++i)
+            {
+            if (!(_strcmpi(pSpriteHeaders[i].pName, pContainerName)))
+                return i;
+            } 
+        }
+
+    if (uNumLoadedSprites == 1500 )
+        return -1;
+    //if not loaded - load from file   
 
-  auto a3 = uPaletteID;
-  v3 = 0;
-  v4 = this;
-  if ( pRenderer->pRenderD3D )
-  {
-    if ( (signed int)this->uNumLoadedSprites > 0 )
-    {
-      v17 = 0;
-      while ( _strcmpi(*(const char **)&v17->pName[(unsigned int)v4->pHardwareSprites], pContainerName) )
-      {
-        ++v17;
-        ++v3;
-        if ( v3 >= (signed int)v4->uNumLoadedSprites )
-          goto LABEL_6;
-      }
-      return v3;
-    }
-  }
-  else
-  {
-    if ( (signed int)this->uNumLoadedSprites > 0 )
-    {
-      v17 = this->pSpriteHeaders;
-      while ( _strcmpi(v17->pName, pContainerName) )
-      {
-        ++v17;
-        ++v3;
-        if ( v3 >= (signed int)v4->uNumLoadedSprites )
-          goto LABEL_6;
-      }
-      return v3;
-    }
-  }
-LABEL_6:
-  v5 = v4->uNumLoadedSprites;
-  if ( v5 == 1500 )
-    return -1;
-  if ( pRenderer->pRenderD3D && v4->field_ECAC )
-  {
-    if ( !v4->pHardwareSprites )
-    {
-      v4->pHardwareSprites = (Sprite *)pAllocator->AllocNamedChunk(0, 0xEA60u, "hardSprites");
-      v6 = 0;
-      do
-      {
-        v7 = &v4->pHardwareSprites[v6];
-        ++v6;
-        v7->pName = 0;
-        v7->pTextureSurface = 0;
-        v7->pTexture = 0;
-      }
-      while ( v6 < 1500 );
-    }
-    DstBuf.uHeight = 0;
-    DstBuf.uPaletteId = 0;
-    DstBuf.word_1A = 0;
-    DstBuf.pSpriteLines = 0;
-    DstBuf.pDecompressedBytes = 0;
-    v18 = 0;
-    v8 = FindContainer(pContainerName, 0);
-    if ( !v8 )
-    {
-      v18 = -1;
-      //LODSprite::dtor(&DstBuf);
-      return -1;
-    }
-    fread(&DstBuf, 1u, 0x20u, v8);
-    v10 = v4->pHardwareSprites;
-    v11 = 5 * v4->uNumLoadedSprites;
-    v18 = -1;
-    pHardwareSprites[uNumLoadedSprites].uBufferWidth = DstBuf.uWidth;
-    pHardwareSprites[uNumLoadedSprites].uBufferHeight = DstBuf.uHeight;
-    pSpriteHeaders[uNumLoadedSprites].uWidth = DstBuf.uWidth;
-    pSpriteHeaders[uNumLoadedSprites].uHeight = DstBuf.uHeight;
-    //LODSprite::dtor(&DstBuf);
-    goto LABEL_29;
-  }
-  v12 = LoadSpriteFromFile( &v4->pSpriteHeaders[v5], pContainerName);
-  v4->pSpriteHeaders[v4->uNumLoadedSprites].word_1A = 0;
-  if ( v12 != -1 )
-  {
-LABEL_28:
-    v4->pSpriteHeaders[v4->uNumLoadedSprites].uPaletteId = pPaletteManager->LoadPalette(
-                                                             v4->pSpriteHeaders[v4->uNumLoadedSprites].uPaletteId);
-LABEL_29:
+    if ( pRenderer->pRenderD3D && field_ECAC )
+        {
+        if ( !pHardwareSprites )
+            {
+            pHardwareSprites = (Sprite *)pAllocator->AllocNamedChunk(0, 1500*sizeof(Sprite) , "hardSprites");//0xEA60u
+            for (i=0; i<1500;++i)
+                {
+                pHardwareSprites[i].pName=NULL;
+                pHardwareSprites[i].pTextureSurface=NULL;
+                pHardwareSprites[i].pTexture=NULL;
+                } 
+            }
+        temp_sprite_hdr.uHeight = 0;
+        temp_sprite_hdr.uPaletteId = 0;
+        temp_sprite_hdr.word_1A = 0;
+        temp_sprite_hdr.pSpriteLines = 0;
+        temp_sprite_hdr.pDecompressedBytes = 0;
+        sprite_file = FindContainer(pContainerName, 0);
+        if ( !sprite_file )
+            return -1;
+        fread(&temp_sprite_hdr, 1, sizeof(LODSprite), sprite_file);
+        pHardwareSprites[uNumLoadedSprites].uBufferWidth = temp_sprite_hdr.uWidth;
+        pHardwareSprites[uNumLoadedSprites].uBufferHeight = temp_sprite_hdr.uHeight;
+        pSpriteHeaders[uNumLoadedSprites].uWidth = temp_sprite_hdr.uWidth;
+        pSpriteHeaders[uNumLoadedSprites].uHeight = temp_sprite_hdr.uHeight;
+        }
+    else
+        {
+        sprite_indx = LoadSpriteFromFile( &pSpriteHeaders[uNumLoadedSprites], pContainerName);
+        pSpriteHeaders[uNumLoadedSprites].word_1A = 0;
+
+        if ( sprite_indx != -1 )
+            {
+            pSpriteHeaders[uNumLoadedSprites].uPaletteId = pPaletteManager->LoadPalette(pSpriteHeaders[uNumLoadedSprites].uPaletteId);
+            }
+        else
+            {
+            if ( uNumLoadedSprites<=0 )
+                uNumLoadedSprites=0;
+            else
+                {
+                for (i=0; i<uNumLoadedSprites;++i)
+                    {
+                    if (!(_strcmpi(pSpriteHeaders[i].pName, "pending")))
+                        return i;
+                    } 
+                }
+            if ( LoadSpriteFromFile(&pSpriteHeaders[uNumLoadedSprites], "pending") == -1 )
+                return -1;
+            pSpriteHeaders[uNumLoadedSprites].uPaletteId = pPaletteManager->LoadPalette(pSpriteHeaders[uNumLoadedSprites].uPaletteId);
+            }
+        }
+
     if ( pRenderer->pRenderD3D )
-    {
-      v4->pHardwareSprites[v4->uNumLoadedSprites].pName = (const char *)pAllocator->AllocNamedChunk(
-                                                                          v4->pHardwareSprites[v4->uNumLoadedSprites].pName,
-                                                                          0x14u,
-                                                                          pContainerName);
-      strcpy((char *)pHardwareSprites[uNumLoadedSprites].pName, pContainerName);
-      v4->pHardwareSprites[v4->uNumLoadedSprites].uPaletteID = uPaletteID;
-      pRenderer->MoveSpriteToDevice(&pHardwareSprites[uNumLoadedSprites]);
-    }
-    ++v4->uNumLoadedSprites;
-    return v4->uNumLoadedSprites - 1;
-  }
-  v13 = v4->uNumLoadedSprites == 0;
-  v14 = (v4->uNumLoadedSprites & 0x80000000u) != 0;
-  v17 = 0;
-  if ( v14 | v13 )
-  {
-LABEL_27:
-    if ( LoadSpriteFromFile(&v4->pSpriteHeaders[v4->uNumLoadedSprites], "pending") == -1 )
-      return -1;
-    goto LABEL_28;
-  }
-  Str1 = (char *)v4->pSpriteHeaders;
-  while ( _strcmpi(Str1, "pending") )
-  {
-    v17 = (LODSprite *)((char *)v17 + 1);
-    Str1 += 40;
-    if ( (signed int)v17 >= (signed int)v4->uNumLoadedSprites )
-      goto LABEL_27;
-  }
-  return (int)v17;
-}
+        {
+        pHardwareSprites[uNumLoadedSprites].pName = (const char *)pAllocator->AllocNamedChunk(pHardwareSprites[uNumLoadedSprites].pName, 20, pContainerName);
+        strcpy((char *)pHardwareSprites[uNumLoadedSprites].pName, pContainerName);
+        pHardwareSprites[uNumLoadedSprites].uPaletteID = uPaletteID;
+        pRenderer->MoveSpriteToDevice(&pHardwareSprites[uNumLoadedSprites]);
+        }
+    ++uNumLoadedSprites;
+    return uNumLoadedSprites - 1;
+
+   }
 
 //----- (004ACADA) --------------------------------------------------------
 void LODFile_Sprites::ReleaseLostHardwareSprites()
--- a/LOD.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/LOD.h	Fri Mar 15 18:29:06 2013 +0600
@@ -224,17 +224,17 @@
   int _4ACC38(struct RenderBillboardTransform_local0 *a2, char a3);
   int _4AD2D1(struct RenderBillboardTransform_local0 *a2, int a3);
   
-  char pName[12];
-  int uSpriteSize;
-  __int16 uWidth;
-  __int16 uHeight;
-  __int16 uPaletteId;
-  __int16 word_16;
-  __int16 uTexturePitch;
-  __int16 word_1A;
-  int uDecompressedSize;
-  struct LODSprite_stru0 *pSpriteLines;
-  void *pDecompressedBytes;
+  char pName[12]; //0
+  int uSpriteSize; //C
+  __int16 uWidth; //10
+  __int16 uHeight; //12
+  __int16 uPaletteId; //14
+  __int16 word_16;  //16
+  __int16 uTexturePitch; //18
+  __int16 word_1A; //1a
+  int uDecompressedSize;  //1c
+  struct LODSprite_stru0 *pSpriteLines; //20
+  void *pDecompressedBytes;  //24
 };
 #pragma pack(pop)
 
@@ -272,7 +272,7 @@
   unsigned int uOffsetToSubIndex;
   FILE *pOutputFileHandle;*/
   struct LODSprite pSpriteHeaders[1500];
-  unsigned int uNumLoadedSprites;
+  signed int uNumLoadedSprites;
   int field_ECA0;
   int field_ECA4;
   int field_ECA8;
--- a/NPC.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/NPC.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -456,8 +456,8 @@
 			decode_step=0;
 			do 
 				{
-                while (*test_string == '\t')  // some steps are separated by multiple \t's
-                  ++test_string;
+                //while (*test_string == '\t')  // some steps are separated by multiple \t's
+                  //++test_string;
                 
 				c = *(unsigned char*)test_string;
 				temp_str_len = 0;
@@ -492,7 +492,7 @@
 					}
 				else
 					{ 
-					if (decode_step)
+					if (!decode_step)
 						break_loop = true;
 					}
 				++decode_step;
--- a/Outdoor.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/Outdoor.h	Fri Mar 15 18:29:06 2013 +0600
@@ -80,7 +80,7 @@
   
   inline bool Invisible() const {return uAttributes & FACE_INVISIBLE;}
   inline bool Visible() const   {return !Invisible();}
-  inline bool TwoSided() const  {return uAttributes & FACE_TWO_SIDED;}
+  inline bool TwoSided() const  {return uAttributes & FACE_PORTAL;}
 
   struct Plane_int_ pFacePlane;
   int zCalc1;
@@ -90,9 +90,9 @@
   unsigned __int16 pVertexIDs[20];
   unsigned __int16 pTextureUIDs[20];
   unsigned __int16 pTextureVIDs[20];
-  unsigned __int16 pXInterceptDisplacements[20];
-  unsigned __int16 pYInterceptDisplacements[20];
-  unsigned __int16 pZInterceptDisplacements[20];
+  signed __int16 pXInterceptDisplacements[20];
+  signed __int16 pYInterceptDisplacements[20];
+  signed __int16 pZInterceptDisplacements[20];
   unsigned __int16 uTextureID;
   __int16 sTextureDeltaU;
   __int16 sTextureDeltaV;
--- a/PaletteManager.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/PaletteManager.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -582,7 +582,7 @@
 
 //----- (0048A300) --------------------------------------------------------
 PaletteManager::PaletteManager():
-  uNumTargetRBits(0), uNumTargetGBits(0),uNumTargetBBits(0)
+  uNumTargetRBits(0), uNumTargetGBits(0),uNumTargetBBits(0),_num_locked(0)
 {
   for (uint i = 0; i < 256; ++i)
   {
--- a/Player.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/Player.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -3391,7 +3391,7 @@
     return 1;
   }
   if ( HasItemEquipped((ITEM_EQUIP_TYPE)a2)
-    && *(int *)&this->pInventoryItems[*(&v4->pEquipment.uOffHand + v3)-1] == a1 )
+    && *(int *)&this->pInventoryItems[*(&this->pEquipment.uOffHand + v3)-1] == a1 )
     return 1;
   return 0;
 }
--- a/Render.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/Render.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -9044,80 +9044,54 @@
 }
 
 //----- (004A5048) --------------------------------------------------------
-HWLTexture *Render::MoveSpriteToDevice(Sprite *pSprite)
-{
-  Sprite *v2; // edi@1
-  Render *v3; // ebx@1
-  HWLTexture *result; // eax@1
-  HWLTexture *v5; // esi@1
-  //unsigned int v6; // ST18_4@2
-  //RenderD3D *v7; // ecx@2
-  Sprite *v8; // ebx@4
+bool Render::MoveSpriteToDevice( Sprite *pSprite )
+    {
+
+  HWLTexture *sprite_texture; // eax@1
   unsigned __int16 *v9; // edx@5
   LPVOID v10; // eax@5
-  signed int v11; // ebx@5
-  signed int v12; // ecx@6
-  signed int v13; // edi@7
-  HRESULT v14; // eax@10
   DDSURFACEDESC2 Dst; // [sp+Ch] [bp-7Ch]@4
 
-  v2 = pSprite;
-  v3 = this;
-  result = pD3DSprites.LoadTexture(pSprite->pName, pSprite->uPaletteID);
-  v5 = result;
-  if ( result )
-  {
-    v3->_gpu_memory_used += 2 * result->uWidth * result->uHeight;
-    v2->uAreaX = result->field_30;
-    v2->uAreaY = result->field_34;
-    v2->uBufferWidth = result->field_18;
-    v2->uBufferHeight = result->field_1C;
-    v2->uAreaWidth = result->field_20;
-    v2->uAreaHeight = result->field_24;
+  sprite_texture = pD3DSprites.LoadTexture(pSprite->pName, pSprite->uPaletteID);
+  if ( sprite_texture )
+  {
+    _gpu_memory_used += 2 * sprite_texture->uWidth * sprite_texture->uHeight;
+    pSprite->uAreaX = sprite_texture->uAreaX;
+    pSprite->uAreaY = sprite_texture->uAreaY;
+    pSprite->uBufferWidth = sprite_texture->uBufferWidth;
+    pSprite->uBufferHeight = sprite_texture->uBufferHeight;
+    pSprite->uAreaWidth = sprite_texture->uAreaWidth;
+    pSprite->uAreaHeight = sprite_texture->uAreaHeigth;
     //v6 = v3->uMinDeviceTextureDim;
     //v7 = v3->pRenderD3D;
-    if (!pRenderD3D->CreateTexture(result->uWidth, result->uHeight, &v2->pTextureSurface, &v2->pTexture, 1u, 0, uMinDeviceTextureDim))
+    if (!pRenderD3D->CreateTexture(sprite_texture->uWidth, sprite_texture->uHeight, &pSprite->pTextureSurface, &pSprite->pTexture, 1u, 0, uMinDeviceTextureDim))
       Abortf("HiScreen16::LoadTexture - D3Drend->CreateTexture() failed: %x", 0);
     //pSprite = v2->pTextureSurface;
     //pSprite = (Sprite *)pSprite->pName;
     //v8 = pSprite;
-    memset(&Dst, 0, 0x7Cu);
+    memset(&Dst, 0, sizeof(DDSURFACEDESC2));
     Dst.dwSize = 124;
-    if ( LockSurface_DDraw4((IDirectDrawSurface4 *)v2->pTextureSurface, &Dst, DDLOCK_WAIT | DDLOCK_WRITEONLY) )
-    {
-      v9 = v5->pPixels;
-      v10 = Dst.lpSurface;
-      v11 = 0;
-      if ( (signed int)v5->uHeight > 0 )
-      {
-        v12 = (signed int)v5->uWidth >> 1;
-        do
-        {
-          v13 = 0;
-          if ( v12 > 0 )
+    if ( LockSurface_DDraw4((IDirectDrawSurface4 *)pSprite->pTextureSurface, &Dst, DDLOCK_WAIT | DDLOCK_WRITEONLY) )
+    {
+    v9 = sprite_texture->pPixels;
+    v10 = Dst.lpSurface;
+      for (int i=0; i<sprite_texture->uHeight; ++i)
           {
-            do
-            {
-              ++v13;
+          for (int j=0; j<sprite_texture->uWidth/2; ++j)
+              {
               *(int *)v10 = *(int *)v9;
               v9 += 2;
               v10 = (char *)v10 + 4;
-            }
-            while ( v13 < (signed int)v5->uWidth >> 1 );
+              }
+          v10 = (char *)v10+Dst.lPitch-sprite_texture->uWidth*2;
           }
-          v12 = (signed int)v5->uWidth >> 1;
-          ++v11;
-          v10 = (char *)v10 + 4 * ((Dst.lPitch >> 2) - v12);
-        }
-        while ( v11 < (signed int)v5->uHeight );
-      }
-      ErrD3D(v2->pTextureSurface->Unlock(0));
-    }
-    free(v5->pPixels);
-    free(v5);
-    result = (HWLTexture *)1;
-  }
-  return result;
+      ErrD3D(pSprite->pTextureSurface->Unlock(0));
+    }
+    free(sprite_texture->pPixels);
+    free(sprite_texture);
+    return true;
+  }
+  return false;
 }
 
 //----- (004A51CB) --------------------------------------------------------
@@ -11222,14 +11196,14 @@
   fread(&uCompressedSize, 4, 1, pFile);
 
     auto pTex = new HWLTexture;
-    fread(&pTex->field_18, 4, 1, pFile);
-    fread(&pTex->field_1C, 4, 1, pFile);
-    fread(&pTex->field_20, 4, 1, pFile);
-    fread(&pTex->field_24, 4, 1, pFile);
+    fread(&pTex->uBufferWidth, 4, 1, pFile);
+    fread(&pTex->uBufferHeight, 4, 1, pFile);
+    fread(&pTex->uAreaWidth, 4, 1, pFile);
+    fread(&pTex->uAreaHeigth, 4, 1, pFile);
     fread(&pTex->uWidth, 4, 1, pFile);
     fread(&pTex->uHeight, 4, 1, pFile);
-    fread(&pTex->field_30, 4, 1, pFile);
-    fread(&pTex->field_34, 4, 1, pFile);
+    fread(&pTex->uAreaX, 4, 1, pFile);
+    fread(&pTex->uAreaY, 4, 1, pFile);
 
     pTex->pPixels = new unsigned __int16[pTex->uWidth * pTex->uHeight];
     if (uCompressedSize)
--- a/Render.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/Render.h	Fri Mar 15 18:29:06 2013 +0600
@@ -144,14 +144,14 @@
   int field_C;
   int field_10;
   int field_14;
-  int field_18;
-  int field_1C;
-  int field_20;
-  int field_24;
+  int uBufferWidth;
+  int uBufferHeight;
+  int uAreaWidth;
+  int uAreaHeigth;
   unsigned int uWidth;
   unsigned int uHeight;
-  int field_30;
-  int field_34;
+  int uAreaX;
+  int uAreaY;
   unsigned __int16 *pPixels;
 };
 #pragma pack(pop)
@@ -334,7 +334,7 @@
   void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9);
   void _4A4CC9(struct stru6_stru1_indoor_sw_billboard *a1, int a2);
   bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture);
-  HWLTexture *MoveSpriteToDevice(Sprite *pSprite);
+  bool MoveSpriteToDevice(Sprite *pSprite);
   void BeginScene();
   void EndScene();
   unsigned int _4A52F1(unsigned int this_, float a3);
--- a/Sprites.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/Sprites.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -47,217 +47,180 @@
 }
 
 //----- (0044D513) --------------------------------------------------------
-void SpriteFrameTable::InitializeSprite(unsigned int uSpriteID)
-{
-  //SpriteFrameTable *v2; // esi@1
-  unsigned int v3; // ebx@3
-  //char *v4; // edx@3
-  //int v5; // eax@3
-  SpriteFrame *v6; // ecx@5
-  int v7; // eax@5
-  __int16 v8; // ax@6
-  //signed int v9; // edx@6
-  //int v10; // ecx@6
-  signed int v11; // edi@10
-  __int16 v12; // ax@16
-  int v13; // ecx@16
-  size_t v14; // eax@19
-  signed int v15; // edi@19
-  __int16 v16; // ax@27
-  int v17; // ecx@27
-  signed int v18; // edi@29
-  SpriteFrame *v19; // eax@30
-  __int16 v20; // ax@45
-  int v21; // ecx@45
-  const char *v22; // [sp-8h] [bp-50h]@12
-  const char *v23; // [sp-8h] [bp-50h]@21
-  const char *v24; // [sp-8h] [bp-50h]@37
-  const char *v25; // [sp-4h] [bp-4Ch]@12
-  char *v26; // [sp-4h] [bp-4Ch]@21
-  const char *v27; // [sp-4h] [bp-4Ch]@37
-  char v28[3]; // [sp+9h] [bp-3Fh]@19
-  char Str; // [sp+Ch] [bp-3Ch]@19
-  char Size[20]; // [sp+2Ch] [bp-1Ch]@15
-  char Source[4]; // [sp+40h] [bp-8h]@19
-  int v32; // [sp+44h] [bp-4h]@19
-  unsigned int uSpriteIDa; // [sp+50h] [bp+8h]@4
+void SpriteFrameTable::InitializeSprite( signed int uSpriteID )
+    {
+    //SpriteFrameTable *v2; // esi@1
+    unsigned int v3; // ebx@3
+    //char *v4; // edx@3
+    //int v5; // eax@3
+    SpriteFrame *v6; // ecx@5
+    int v7; // eax@5
+    __int16 v8; // ax@6
+    //signed int v9; // edx@6
+    //int v10; // ecx@6
+    signed int v11; // edi@10
+    __int16 v12; // ax@16
+    int v13; // ecx@16
+    size_t v14; // eax@19
+    signed int v15; // edi@19
+    __int16 v16; // ax@27
+    int v17; // ecx@27
+    signed int v18; // edi@29
+    SpriteFrame *v19; // eax@30
+    __int16 v20; // ax@45
+    int v21; // ecx@45
 
-  //v2 = this;
-  if ( (signed int)uSpriteID <= (signed int)this->uNumSpriteFrames )
-  {
-    if ( (uSpriteID & 0x80000000u) == 0 )
-    {
-      v3 = uSpriteID;
+    char Str[32]; // [sp+Ch] [bp-3Ch]@19
+    char sprite_name[20]; // [sp+2Ch] [bp-1Ch]@15
+    char Source[4]; // [sp+40h] [bp-8h]@19
 
-      auto uFlags = pSpriteSFrames[uSpriteID].uFlags;
-      if (uFlags & 0x7F)
-      {
-        pSpriteSFrames[uSpriteID].uFlags |= 0x80;
 
-        uSpriteIDa = 30 * uSpriteID + 12;
-        while ( 1 )
+    //v2 = this;
+    if ( uSpriteID <= this->uNumSpriteFrames )
         {
-          pSpriteSFrames[v3].uPaletteIndex = pPaletteManager->LoadPalette(pSpriteSFrames[uSpriteID].uPaletteID);
-          v6 = &pSpriteSFrames[uSpriteID];
-          v7 = v6->uFlags;
-          if ( v7 & 0x10 )
-          {
-            v8 = pSprites_LOD->LoadSprite(v6->pTextureName, v6->uPaletteID);
-
-            for (uint i = 0; i < 8; ++i)
-              pSpriteSFrames[v3].pHwSpriteIDs[i] = v8;
-            goto LABEL_46;
-          }
-          if ( v7 & 0x10000 )
-          {
-            v11 = 0;
-            do
+        if ( uSpriteID >= 0 )
             {
-              switch ( v11 )
-              {
-                case 3:
-                case 4:
-                case 5:
-                  v25 = pSpriteSFrames[v3].pTextureName;
-                  v22 = "%s4";
-                  goto LABEL_15;
-                case 2:
-                case 6:
-                  v25 = pSpriteSFrames[v3].pTextureName;
-                  v22 = "%s2";
-                  goto LABEL_15;
-                case 0:
-                case 1:
-                case 7:
-                  v25 = pSpriteSFrames[v3].pTextureName;
-                  v22 = "%s0";
-LABEL_15:
-                  sprintf(Size, v22, v25);
-                  break;
-                default:
-                  break;
-              }
-              v12 = pSprites_LOD->LoadSprite(Size, pSpriteSFrames[v3].uPaletteID);
-              v13 = v11++ + uSpriteIDa;
-              *(short *)&pSpriteSFrames->pIconName[2 * v13] = v12;
-            }
-            while ( v11 < 8 );
-            goto LABEL_46;
-          }
-          if ( !(v7 & 0x40) )
-            break;
-          strcpy(Source, "stA");
-          v32 = 0;
-          strcpy(&Str, v6->pTextureName);
-          v14 = strlen(&Str);
-          strcpy(&v28[v14], Source);
-          v15 = 0;
-          do
-          {
-            switch ( v15 )
-            {
-              case 0:
-                v26 = pSpriteSFrames[v3].pTextureName;
-                v23 = "%s0";
-                goto LABEL_26;
-              case 4:
-                v26 = &Str;
-                v23 = "%s4";
-                goto LABEL_26;
-              case 3:
-              case 5:
-                v26 = &Str;
-                v23 = "%s3";
-                goto LABEL_26;
-              case 2:
-              case 6:
-                v26 = pSpriteSFrames[v3].pTextureName;
-                v23 = "%s2";
-                goto LABEL_26;
-              case 1:
-              case 7:
-                v26 = pSpriteSFrames[v3].pTextureName;
-                v23 = "%s1";
-LABEL_26:
-                sprintf(Size, v23, v26);
-                break;
-              default:
-                break;
-            }
-            v16 = pSprites_LOD->LoadSprite(Size, pSpriteSFrames[v3].uPaletteID);
-            v17 = v15++ + uSpriteIDa;
-            *(short *)&pSpriteSFrames->pIconName[2 * v17] = v16;
-          }
-          while ( v15 < 8 );
-LABEL_46:
-          if ( !(pSpriteSFrames[v3].uFlags & 1) )
-            return;
-          uSpriteIDa += 30;
-          ++v3;
+            v3 = uSpriteID;
+
+            auto uFlags = pSpriteSFrames[v3].uFlags;
+            if (!(uFlags & 0x0080))  //not loaded
+                {
+                pSpriteSFrames[v3].uFlags |= 0x80; //set loaded
+                while ( 1 )
+                    {
+                    pSpriteSFrames[v3].uPaletteIndex = pPaletteManager->LoadPalette(pSpriteSFrames[v3].uPaletteID);
+                    if ( uFlags & 0x10 )  //single frame per frame sequence
+                        {
+                        v8 = pSprites_LOD->LoadSprite(pSpriteSFrames[v3].pTextureName, pSpriteSFrames[v3].uPaletteID);
+                        for (uint i = 0; i < 8; ++i)
+                            {
+
+                            pSpriteSFrames[v3].pHwSpriteIDs[i] = v8;
+                            }
+                            
+                        }
+                    else if ( uFlags & 0x10000 )
+                        {
+                        for (uint i = 0; i < 8; ++i)
+                            {
+                            switch ( i )
+                                {
+                            case 3:
+                            case 4:
+                            case 5:
+                                sprintf(sprite_name, "%s4", pSpriteSFrames[v3].pTextureName);
+                                break;
+                            case 2:
+                            case 6:
+                                sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName);
+                                break;
+                            case 0:
+                            case 1:
+                            case 7:
+                                sprintf(sprite_name, "%s0", pSpriteSFrames[v3].pTextureName);
+                                break;
+                                }
+                            v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID);
+
+                            pSpriteSFrames[v3].pHwSpriteIDs[i]=v12;
+                            }
+
+                        }
+                    else if ( uFlags & 0x40 ) //part of monster fidgeting seq
+                        {
+                        strcpy(Source, "stA");
+                        strcpy(Str, pSpriteSFrames[v3].pTextureName);
+                        v14 = strlen(Str);
+                        strcpy(&Str[v14-3], Source);
+                        for (uint i = 0; i < 8; ++i)
+                            {
+                            switch ( i )
+                                {
+                            case 0:
+                                sprintf(sprite_name, "%s0", pSpriteSFrames[v3].pTextureName);
+                                break;
+                            case 4:
+                                sprintf(sprite_name, "%s4",&Str );
+                                break;
+                            case 3:
+                            case 5:
+                                sprintf(sprite_name, "%s3",&Str );
+                                break;
+                            case 2:
+                            case 6:
+                                sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName);
+                                break;
+                            case 1:
+                            case 7:
+                                sprintf(sprite_name, "%s1", pSpriteSFrames[v3].pTextureName);
+                                break;
+                                }
+                            v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID);
+                            pSpriteSFrames[v3].pHwSpriteIDs[i]=v12;
+                            }
+                        }
+
+                    else
+                        {
+                        for (uint i = 0; i < 8; ++i)
+
+                            {
+
+                            if (((0x0100 << i) & pSpriteSFrames[v3].uFlags) ) //mirrors
+                                {
+                                switch ( i )
+                                    {
+                                case 1:
+                                    sprintf(sprite_name, "%s7", pSpriteSFrames[v3].pTextureName);
+                                    break;
+                                case 2:
+                                    sprintf(sprite_name, "%s6", pSpriteSFrames[v3].pTextureName);
+                                    break;
+                                case 3:
+                                    sprintf(sprite_name, "%s5", pSpriteSFrames[v3].pTextureName);
+                                    break;
+                                case 4:
+                                    sprintf(sprite_name, "%s4", pSpriteSFrames[v3].pTextureName);
+                                    break;
+
+                                case 5:
+                                    sprintf(sprite_name, "%s3", pSpriteSFrames[v3].pTextureName);
+                                    break;
+
+                                case 6:
+                                    sprintf(sprite_name, "%s2", pSpriteSFrames[v3].pTextureName);
+                                    break;
+                                case 7:
+                                    sprintf(sprite_name, "%s1", pSpriteSFrames[v3].pTextureName);
+                                    break;
+                                    }
+                                }
+                            else
+                                {
+                                sprintf(sprite_name, "%s%i", pSpriteSFrames[v3].pTextureName, i);
+
+                                }
+                            v12 = pSprites_LOD->LoadSprite(sprite_name, pSpriteSFrames[v3].uPaletteID);
+                            pSpriteSFrames[v3].pHwSpriteIDs[i]=v12;
+
+                            }
+                        }
+
+                    if ( !(pSpriteSFrames[v3].uFlags & 1) )
+                        return;
+                    ++v3;
+                    }
+                }
+            } 
         }
-        v18 = 0;
-        while ( 1 )
-        {
-          v19 = &pSpriteSFrames[v3];
-          if ( !((256 << v18) & v19->uFlags) )
-          {
-            sprintf(Size, "%s%i", v19->pTextureName, v18);
-            goto LABEL_45;
-          }
-          if ( v18 == 1 )
-          {
-            v27 = v19->pTextureName;
-            v24 = "%s7";
-            goto LABEL_42;
-          }
-          if ( v18 == 2 )
-          {
-            v27 = v19->pTextureName;
-            v24 = "%s6";
-            goto LABEL_42;
-          }
-          if ( v18 == 3 )
-          {
-            v27 = v19->pTextureName;
-            v24 = "%s5";
-            goto LABEL_42;
-          }
-          if ( v18 == 5 )
-          {
-            v27 = v19->pTextureName;
-            v24 = "%s3";
-            goto LABEL_42;
-          }
-          if ( v18 == 6 )
-            break;
-          if ( v18 == 7 )
-          {
-            v27 = v19->pTextureName;
-            v24 = "%s1";
-LABEL_42:
-            sprintf(Size, v24, v27);
-          }
-LABEL_45:
-          v20 = pSprites_LOD->LoadSprite(Size, pSpriteSFrames[v3].uPaletteID);
-          v21 = v18++ + uSpriteIDa;
-          *(short *)&pSpriteSFrames->pIconName[2 * v21] = v20;
-          if ( v18 >= 8 )
-            goto LABEL_46;
-        }
-        v27 = v19->pTextureName;
-        v24 = "%s2";
-        goto LABEL_42;
-      }
     }
-  }
-}
 
 //----- (0044D813) --------------------------------------------------------
-unsigned int SpriteFrameTable::FastFindSprite(char *pSpriteName)
-{
+signed int SpriteFrameTable::FastFindSprite( char *pSpriteName )
+    {
   SpriteFrameTable *v2; // esi@1
   int v3; // eax@1
-  unsigned int result; // eax@2
+  signed int result; // eax@2
 
   v2 = this;
   BinarySearch(0, this->uNumEFrames, pSpriteName);
@@ -511,14 +474,8 @@
   }
   v2->uNumSpriteFrames = v4;
   v2->pSpriteSFrames = (SpriteFrame *)pAllocator->AllocNamedChunk(v2->pSpriteSFrames, 60 * v4, "S Frames");
-  v2->pSpriteEFrames = (__int16 *)pAllocator->AllocNamedChunk(
-                                    v2->pSpriteEFrames,
-                                    2 * v2->uNumSpriteFrames,
-                                    "E Frames");
-  v2->pSpritePFrames = (SpriteFrame **)pAllocator->AllocNamedChunk(
-                                         v2->pSpritePFrames,
-                                         4 * v2->uNumSpriteFrames,
-                                         "P Frames");
+  v2->pSpriteEFrames = (__int16 *)pAllocator->AllocNamedChunk(  v2->pSpriteEFrames, 2 * v2->uNumSpriteFrames,   "E Frames");
+  v2->pSpritePFrames = (SpriteFrame **)pAllocator->AllocNamedChunk(  v2->pSpritePFrames, 4 * v2->uNumSpriteFrames, "P Frames");
   if ( v2->pSpriteSFrames )
   {
     v6 = File;
--- a/Sprites.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/Sprites.h	Fri Mar 15 18:29:06 2013 +0600
@@ -3,20 +3,20 @@
 
 /*   18 */
 #pragma pack(push, 1)
-struct Sprite
+struct Sprite  //28h
 {
   void Release();
 
-  const char *pName;
-  int uPaletteID;
-  struct IDirectDrawSurface4 *pTextureSurface;
-  struct IDirect3DTexture2 *pTexture;
-  int uAreaX;
-  int uAreaY;
-  int uBufferWidth;
-  int uBufferHeight;
-  int uAreaWidth;
-  int uAreaHeight;
+  const char *pName;  //0
+  int uPaletteID; //4
+  struct IDirectDrawSurface4 *pTextureSurface;  //8
+  struct IDirect3DTexture2 *pTexture;   //ch
+  int uAreaX;  //10h
+  int uAreaY;  //14h
+  int uBufferWidth;  //18h
+  int uBufferHeight;  //1ch
+  int uAreaWidth;  //20h
+  int uAreaHeight; //24h
 };
 #pragma pack(pop)
 
@@ -25,13 +25,13 @@
 #pragma pack(push, 1)
 struct SpriteFrame
 {
-  char pIconName[12];
-  char pTextureName[12];
-  __int16 pHwSpriteIDs[8];
-  int scale;
-  int uFlags;
-  __int16 uGlowRadius;
-  __int16 uPaletteID;
+  char pIconName[12]; 
+  char pTextureName[12]; //c
+  __int16 pHwSpriteIDs[8]; //18h
+  int scale; //28h
+  int uFlags; //2c
+  __int16 uGlowRadius; //30
+  __int16 uPaletteID;  //32
   __int16 uPaletteIndex;
   __int16 uAnimTime;
   __int16 uAnimLength;
@@ -56,18 +56,18 @@
   bool FromFileTxt(const char *Args);
   void ReleaseSFrames();
   void ResetSomeSpriteFlags();
-  void InitializeSprite(unsigned int uSpriteID);
-  unsigned int FastFindSprite(char *pSpriteName);
+  void InitializeSprite(signed int uSpriteID);
+  signed int FastFindSprite(char *pSpriteName);
   void BinarySearch(int a2, int a3, const char *pSpriteName);
   SpriteFrame *GetFrame(unsigned int uSpriteID, unsigned int uTime);
   SpriteFrame *GetFrameBy_x(unsigned int uSpriteID, signed int a3);
 
-  unsigned int uNumSpriteFrames;
+  signed int uNumSpriteFrames;
   unsigned int uNumEFrames;//field_4;
   int field_8;
-  struct SpriteFrame *pSpriteSFrames;
-  struct SpriteFrame **pSpritePFrames;
-  __int16 *pSpriteEFrames;
+  struct SpriteFrame *pSpriteSFrames;  //0c
+  struct SpriteFrame **pSpritePFrames; //10h
+  __int16 *pSpriteEFrames; //14h
 };
 #pragma pack(pop)
 
--- a/UIHouses.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/UIHouses.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -1513,7 +1513,7 @@
       do
       {
         //  if ( pParty->field_777C[9 * (int)&v48[3 * (unsigned int)window_SpeakInHouse->ptr_1C]] )
-        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(int)v48].uItemID);
+        if ( pParty->StandartItemsInShops[(unsigned int)window_SpeakInHouse->ptr_1C][(int)v48].uItemID)
         {
           v49 = word_F8B158[(signed int)v48];
           v50 = ItemsInShopTexture[(signed int)v48];
--- a/Vis.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/Vis.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -349,9 +349,9 @@
   v5 = 0;
   thisa = this;
   v17 = 0;
-  for ( a1.flt_2C = 0.0; v17 < (signed int)pBspRenderer->uNumFaceIDs; ++v17 )
+  for ( a1.flt_2C = 0.0; v17 < (signed int)pBspRenderer->num_faces; ++v17 )
   {
-    v6 = pBspRenderer->pFaceIDs[2 * v5];
+    v6 = pBspRenderer->faces[v5].uFaceID;
     if ( v6 >= 0 )
     {
       if ( v6 < (signed int)pIndoor->uNumFaces )
@@ -611,7 +611,7 @@
   //float a5a; // [sp+30h] [bp+18h]@10
   //float a5b; // [sp+30h] [bp+18h]@13
 
-  if (a5->TwoSided() || a5->Invisible())
+  if (a5->Portal() || a5->Invisible())
     return false;
 
   
@@ -1849,9 +1849,9 @@
 
   result = 0;
   thisa = this;
-  for ( i = 0; i < (signed int)pBspRenderer->uNumFaceIDs; ++i )
+  for ( i = 0; i < (signed int)pBspRenderer->num_faces; ++i )
   {
-    v5 = pBspRenderer->pFaceIDs[2 * result];
+    v5 = pBspRenderer->faces[result].uFaceID;
     if ( v5 >= 0 )
     {
       if ( v5 < (signed int)pIndoor->uNumFaces )
--- a/mm7_1.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/mm7_1.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -5826,7 +5826,7 @@
   else
   {
     dword_50B700 = 0;
-    if ( !v1->TwoSided() )
+    if ( !v1->Portal() )
       return 0;
   }
   //v66 = v1->uNumVertices;
@@ -6122,15 +6122,15 @@
         v70 = (signed int)(v56 - v58) * (signed __int64)(dword_50BAD4[v57 - 1] - dword_50BAD4[v57]) / (dword_50B9E4[v57 - 1] - v58);
         v59 = dword_50BAD4[v57];
       }
-      dword_50BAC8[v55] = v70 + v59;
+      _50BAC8_screen_space_x[v55] = v70 + v59;
       v56 = pBLVRenderParams->uViewportW;
-      dword_50B9D8_ys[v55] = pBLVRenderParams->uViewportW;
+      _50B9D8_screen_space_y[v55] = pBLVRenderParams->uViewportW;
       ++v55;
     }
     if ( v85 )
     {
-      dword_50BAC8[v55] = dword_50BAD4[v57];
-      dword_50B9D8_ys[v55++] = dword_50B9E4[v57];
+      _50BAC8_screen_space_x[v55] = dword_50BAD4[v57];
+      _50B9D8_screen_space_y[v55++] = dword_50B9E4[v57];
     }
     ++ie;
     thise = v85;
@@ -6140,12 +6140,12 @@
   if ( !v55 )
     return 0;
   v61 = pRenderer->pRenderD3D == 0;
-  dword_50BAC8[v55] = dword_50BAC8[0];
-  dword_50B9D8_ys[v55] = dword_50B9D8_ys[0];
+  _50BAC8_screen_space_x[v55] = _50BAC8_screen_space_x[0];
+  _50B9D8_screen_space_y[v55] = _50B9D8_screen_space_y[0];
   if ( v61 && v55 > 3 )
   {
-    dword_50BAC8[v55 + 1] = dword_50BAC8[1];
-    dword_50B9D8_ys[v55 + 1] = dword_50B9D8_ys[1];
+    _50BAC8_screen_space_x[v55 + 1] = _50BAC8_screen_space_x[1];
+    _50B9D8_screen_space_y[v55 + 1] = _50B9D8_screen_space_y[1];
     thisf = 2 * (dword_50B700 != 0) - 1;
     if ( v55 > 0 )
     {
@@ -6163,8 +6163,8 @@
         if ( v64 >= v55 )
           v64 -= v55;
         if ( thisf
-           * ((dword_50B9D8_ys[v64] - dword_50B9D8_ys[v63]) * (dword_50BAC8[v62] - dword_50BAC8[v63])
-            - (dword_50B9D8_ys[v62] - dword_50B9D8_ys[v63]) * (dword_50BAC8[v64] - dword_50BAC8[v63])) < 0 )
+           * ((_50B9D8_screen_space_y[v64] - _50B9D8_screen_space_y[v63]) * (_50BAC8_screen_space_x[v62] - _50BAC8_screen_space_x[v63])
+            - (_50B9D8_screen_space_y[v62] - _50B9D8_screen_space_y[v63]) * (_50BAC8_screen_space_x[v64] - _50BAC8_screen_space_x[v63])) < 0 )
         {
           v62 = v80;
           v71 = v80;
@@ -6175,16 +6175,16 @@
           v65 = v71;
           if ( v71 < v55 || (v65 = v71 - v55, v71 - v55 < v55) )
           {
-            memcpy(&dword_50B9D8_ys[v65], &dword_50B9D8_ys[v65 + 1], 4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
-            memcpy(&dword_50BAC8[v65], &dword_50BAC8[v65 + 1], 4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
+            memcpy(&_50B9D8_screen_space_y[v65], &_50B9D8_screen_space_y[v65 + 1], 4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
+            memcpy(&_50BAC8_screen_space_x[v65], &_50BAC8_screen_space_x[v65 + 1], 4 * ((unsigned int)(4 * (v55 - v65)) >> 2));
           }
           --v55;
         }
       }
       while ( v62 - 1 < v55 );
     }
-    dword_50BAC8[v55] = dword_50BAC8[0];
-    dword_50B9D8_ys[v55] = dword_50B9D8_ys[0];
+    _50BAC8_screen_space_x[v55] = _50BAC8_screen_space_x[0];
+    _50B9D8_screen_space_y[v55] = _50B9D8_screen_space_y[0];
   }
   return v55;
 }
@@ -6544,23 +6544,23 @@
   v60 = a2;
   if ( !a1
     || (!dword_50B700 ? (v64 = -1, v6 = 1, v63 = 1) : (v6 = 1, v63 = -1, v64 = 1),
-        v7 = dword_50B9D8_ys[0],
+        v7 = _50B9D8_screen_space_y[0],
         v65 = 0,
-        v8 = dword_50B9D8_ys[0],
+        v8 = _50B9D8_screen_space_y[0],
         a1 <= v6) )
     return 0;
   do
   {
-    v9 = dword_50B9D8_ys[v6];
+    v9 = _50B9D8_screen_space_y[v6];
     if ( v9 >= v7 )
     {
       if ( v9 > v8 )
-        v8 = dword_50B9D8_ys[v6];
+        v8 = _50B9D8_screen_space_y[v6];
     }
     else
     {
       v65 = v6;
-      v7 = dword_50B9D8_ys[v6];
+      v7 = _50B9D8_screen_space_y[v6];
     }
     ++v6;
   }
@@ -6588,8 +6588,8 @@
       {
         v10 -= v74;
       }
-      v12 = dword_50B9D8_ys[v10];
-      if ( v12 <= dword_50B9D8_ys[v11] )
+      v12 = _50B9D8_screen_space_y[v10];
+      if ( v12 <= _50B9D8_screen_space_y[v11] )
       {
         v55 = v10;
         v11 = v10;
@@ -6614,12 +6614,12 @@
   }
   v67 = v13;
 LABEL_27:
-  if ( dword_50B9D8_ys[v13] != dword_50B9D8_ys[v55] )
+  if ( _50B9D8_screen_space_y[v13] != _50B9D8_screen_space_y[v55] )
   {
-    v14 = dword_50BAC8[v55];
+    v14 = _50BAC8_screen_space_x[v55];
     v62 = v14 << 16;
-    v54 = ((dword_50BAC8[v13] - v14) << 16) / (dword_50B9D8_ys[v13] - dword_50B9D8_ys[v55]);
-    v5->array_18[v7] = LOWORD(dword_50BAC8[v55]);
+    v54 = ((_50BAC8_screen_space_x[v13] - v14) << 16) / (_50B9D8_screen_space_y[v13] - _50B9D8_screen_space_y[v55]);
+    v5->array_18[v7] = LOWORD(_50BAC8_screen_space_x[v55]);
   }
   v15 = v65;
   v69 = 0;
@@ -6639,8 +6639,8 @@
       {
         v15 -= v74;
       }
-      v17 = dword_50B9D8_ys[v15];
-      if ( v17 <= dword_50B9D8_ys[v16] )
+      v17 = _50B9D8_screen_space_y[v15];
+      if ( v17 <= _50B9D8_screen_space_y[v16] )
       {
         v61 = v15;
         v16 = v15;
@@ -6667,14 +6667,14 @@
 LABEL_44:
   v19 = v18;
   v20 = v61;
-  v53 = dword_50B9D8_ys[v19] - dword_50B9D8_ys[v61];
-  if ( dword_50B9D8_ys[v19] != dword_50B9D8_ys[v61] )
+  v53 = _50B9D8_screen_space_y[v19] - _50B9D8_screen_space_y[v61];
+  if ( _50B9D8_screen_space_y[v19] != _50B9D8_screen_space_y[v61] )
   {
-    v21 = dword_50BAC8[v20];
+    v21 = _50BAC8_screen_space_x[v20];
     v5 = v60;
     v61 = v21 << 16;
-    v53 = ((dword_50BAC8[v19] - v21) << 16) / v53;
-    v60->array_3D8[v73] = LOWORD(dword_50BAC8[v20]);
+    v53 = ((_50BAC8_screen_space_x[v19] - v21) << 16) / v53;
+    v60->array_3D8[v73] = LOWORD(_50BAC8_screen_space_x[v20]);
   }
   v22 = v7;
   v70 = v7;
@@ -6685,7 +6685,7 @@
     do
     {
       v24 = v67;
-      if ( v22 < dword_50B9D8_ys[v67] || v22 == v73 )
+      if ( v22 < _50B9D8_screen_space_y[v67] || v22 == v73 )
         goto LABEL_57;
       v25 = v64 + v67;
       v67 = v25;
@@ -6702,16 +6702,16 @@
       v67 = v25;
 LABEL_55:
       v26 = v25;
-      v27 = dword_50B9D8_ys[v26] - dword_50B9D8_ys[v24];
-      if ( dword_50B9D8_ys[v26] - dword_50B9D8_ys[v24] > 0 )
+      v27 = _50B9D8_screen_space_y[v26] - _50B9D8_screen_space_y[v24];
+      if ( _50B9D8_screen_space_y[v26] - _50B9D8_screen_space_y[v24] > 0 )
       {
-        v28 = dword_50BAC8[v24];
-        v54 = ((dword_50BAC8[v26] - v28) << 16) / v27;
+        v28 = _50BAC8_screen_space_x[v24];
+        v54 = ((_50BAC8_screen_space_x[v26] - v28) << 16) / v27;
         v62 = v28 << 16;
       }
 LABEL_57:
       v29 = v66;
-      if ( v70 >= dword_50B9D8_ys[v66] && v70 != v73 )
+      if ( v70 >= _50B9D8_screen_space_y[v66] && v70 != v73 )
       {
         v30 = v63 + v66;
         v66 += v63;
@@ -6727,11 +6727,11 @@
           v66 = v30;
         }
         v31 = v30;
-        v32 = dword_50B9D8_ys[v31] - dword_50B9D8_ys[v29];
-        if ( dword_50B9D8_ys[v31] - dword_50B9D8_ys[v29] > 0 )
+        v32 = _50B9D8_screen_space_y[v31] - _50B9D8_screen_space_y[v29];
+        if ( _50B9D8_screen_space_y[v31] - _50B9D8_screen_space_y[v29] > 0 )
         {
-          v33 = dword_50BAC8[v29];
-          v53 = ((dword_50BAC8[v31] - v33) << 16) / v32;
+          v33 = _50BAC8_screen_space_x[v29];
+          v53 = ((_50BAC8_screen_space_x[v31] - v33) << 16) / v32;
           v61 = v33 << 16;
         }
       }
--- a/mm7_2.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/mm7_2.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -894,7 +894,8 @@
   {
 	v8 = window_SpeakInHouse;
   }
-  else
+  //else
+  if ( dialog_menu_id == 1 )
   {
 	  if ( in_current_building_type == BildingType_Training )
 	  {
@@ -923,7 +924,8 @@
 		//v3 = dword_F8B198;
 		v8 = window_SpeakInHouse;
 	  }
-	  else
+	  //else
+	  if ( in_current_building_type != BildingType_Training )
 	  {
 		  v8 = window_SpeakInHouse;
 		  if ( (in_current_building_type == BildingType_Stables || in_current_building_type == BildingType_Boats)
@@ -958,6 +960,287 @@
 		v8 = window_SpeakInHouse;
 	  }
   }
+  
+  //NEW
+  switch(in_current_building_type)
+  {
+	case 5:
+	case 6:
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+	case 11:
+	case 12:
+	case 13:
+	case 14:
+	case 15:
+	case 16:
+		{
+        if ( (signed __int64)__PAIR__(
+                                *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)v8->ptr_1C + 44472],
+                                *(int *)&stru_AA1058[3].pSounds[8 * (unsigned int)v8->ptr_1C + 44468]) >= (signed __int64)pParty->uTimePlayed )
+        {
+			v32 = 0;
+			do
+			{
+				//v33 = *(&pParty->pPlayers[1].pInstalledBeacons[0].field_18 + 9 * (v32 + 12 * (unsigned int)v8->ptr_1C));
+				v33 = pParty->SpellBooksInGuilds[v8->par1C-139][v32].uItemID;
+				if ( v33 )
+				{
+				v34 = pIcons_LOD->LoadTexture(pItemsTable->pItems[v33].pIconName, TEXTURE_16BIT_PALETTE);
+				v8 = window_SpeakInHouse;
+				ItemsInShopTexture[v32] = &pIcons_LOD->pTextures[v34];
+				}
+				++v32;
+			}
+			while ( v32 < 12 );
+        }
+        else
+        {
+			SpellBookGenerator();
+			v30 = window_SpeakInHouse->ptr_1C;
+			v31 = pParty->uTimePlayed
+				+ (signed __int64)((double)(0xA8C000
+											//* (signed int)p2DEvents_minus1[26 * (unsigned int)ptr_507BC0->ptr_1C])
+											* (signed int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].field_1C)
+									* 0.033333335);
+			*(int *)&stru_AA1058[3].pSounds[8 * (int)v30 + 44468] = v31;
+			*(int *)&stru_AA1058[3].pSounds[8 * (int)v30 + 44472] = HIDWORD(v31);
+        }
+        return;
+		break;
+		}
+	case 17:
+		{
+		if ( uMessageParam == 99 )
+		{
+			v10 = (int)((char *)v8->ptr_1C - 102);
+			v56 = v10;
+			v11 = 8 * v10 + 11325428;
+			if ( (signed __int64)__PAIR__(pParty->field_3C.field_0[2 * v10 + 1], pParty->field_3C.field_0[2 * v10]) >= (signed __int64)pParty->uTimePlayed )
+			{
+				v13 = 0;
+			}
+			else
+			{
+				v12 = v10;
+				v13 = 0;
+				pParty->field_75A[v12] = 0;
+				*(_QWORD *)v11 = (signed __int64)((double)(309657600 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
+				v14 = rand() % 258;
+				v15 = window_SpeakInHouse;
+				pParty->field_750[v12] = v14 + 1;
+				v16 = (int)((char *)v15->ptr_1C - 102);
+				if ( v16 )
+				{
+					v17 = v16 - 1;
+					if ( v17 )
+					{
+						v18 = v17 - 1;
+						if ( v18 )
+						{
+							v19 = v18 - 1;
+							if ( v19 )
+							{
+								if ( v19 == 1 )
+								{
+									while ( 1 )
+									{
+										v20 = pParty->field_750[v12];
+										if ( (unsigned __int16)v20 < 0x73u || (unsigned __int16)v20 > 0x84u )
+										{
+											if ( ((unsigned __int16)v20 < 0xE8u || (unsigned __int16)v20 > 0xF9u)
+											&& ((unsigned __int16)v20 < 0x85u || (unsigned __int16)v20 > 0x96u)
+											&& ((unsigned __int16)v20 < 0x97u || (unsigned __int16)v20 > 0xBAu)
+											&& ((unsigned __int16)v20 < 0xBEu || (unsigned __int16)v20 > 0xC0u)
+											&& ((unsigned __int16)v20 < 0xC4u || (unsigned __int16)v20 > 0xC6u)
+											&& ((unsigned __int16)v20 < 0x2Bu || (unsigned __int16)v20 > 0x2Du)
+											&& ((unsigned __int16)v20 < 0x6Du || (unsigned __int16)v20 > 0x6Fu)
+											&& ((unsigned __int16)v20 < 0x46u || (unsigned __int16)v20 > 0x48u)
+											&& ((unsigned __int16)v20 < 0x100u || (unsigned __int16)v20 > 0x102u)
+											&& ((unsigned __int16)v20 < 0xD9u || (unsigned __int16)v20 > 0xDBu)
+											&& ((unsigned __int16)v20 < 0xC7u || (unsigned __int16)v20 > 0xC9u)
+											&& ((unsigned __int16)v20 < 0xE5u || (unsigned __int16)v20 > 0xE7u)
+											&& ((unsigned __int16)v20 < 0xDFu || (unsigned __int16)v20 > 0xE1u)
+											&& ((unsigned __int16)v20 < 0x5Bu || (unsigned __int16)v20 > 0x5Du)
+											&& ((unsigned __int16)v20 < 0x49u || (unsigned __int16)v20 > 0x4Bu)
+											&& ((unsigned __int16)v20 < 0xFDu || (unsigned __int16)v20 > 0xFFu)
+											&& ((unsigned __int16)v20 < 0x61u || (unsigned __int16)v20 > 0x63u)
+											&& ((unsigned __int16)v20 < 0x10u || (unsigned __int16)v20 > 0x12u) )
+												break;
+										}
+										pParty->field_750[v12] = rand() % 258 + 1;
+									}
+								}
+							}
+							else
+							{
+								while ( 1 )
+								{
+									v21 = pParty->field_750[v12];
+									if ( (unsigned __int16)v21 < 0x73u || (unsigned __int16)v21 > 0x84u )
+									{
+									if ( ((unsigned __int16)v21 < 0xE8u || (unsigned __int16)v21 > 0xF9u)
+										&& ((unsigned __int16)v21 < 0x85u || (unsigned __int16)v21 > 0x96u)
+										&& ((unsigned __int16)v21 < 0x97u || (unsigned __int16)v21 > 0xBAu)
+										&& ((unsigned __int16)v21 < 0xBEu || (unsigned __int16)v21 > 0xC0u)
+										&& ((unsigned __int16)v21 < 0xC4u || (unsigned __int16)v21 > 0xC6u)
+										&& ((unsigned __int16)v21 < 0x2Bu || (unsigned __int16)v21 > 0x2Du)
+										&& ((unsigned __int16)v21 < 0x5Eu || (unsigned __int16)v21 > 0x60u)
+										&& ((unsigned __int16)v21 < 0x43u || (unsigned __int16)v21 > 0x45u)
+										&& ((unsigned __int16)v21 < 0x4Fu || (unsigned __int16)v21 > 0x51u)
+										&& ((unsigned __int16)v21 < 0xC1u || (unsigned __int16)v21 > 0xC3u)
+										&& ((unsigned __int16)v21 < 0x13u || (unsigned __int16)v21 > 0x15u)
+										&& ((unsigned __int16)v21 < 0xFDu || (unsigned __int16)v21 > 0xFFu)
+										&& ((unsigned __int16)v21 < 0x61u || (unsigned __int16)v21 > 0x63u)
+										&& ((unsigned __int16)v21 < 0x6Au || (unsigned __int16)v21 > 0x6Cu) )
+											break;
+									}
+									pParty->field_750[v12] = rand() % 258 + 1;
+								}
+							}
+						}
+						else
+						{
+							while ( 1 )
+							{
+								v22 = pParty->field_750[v12];
+								if ( (unsigned __int16)v22 < 0x73u || (unsigned __int16)v22 > 0x84u )
+								{
+									if ( ((unsigned __int16)v22 < 0xE8u || (unsigned __int16)v22 > 0xF9u)
+									&& ((unsigned __int16)v22 < 0x85u || (unsigned __int16)v22 > 0x96u)
+									&& ((unsigned __int16)v22 < 0x97u || (unsigned __int16)v22 > 0xBAu)
+									&& ((unsigned __int16)v22 < 0xBEu || (unsigned __int16)v22 > 0xC0u)
+									&& ((unsigned __int16)v22 < 0xC4u || (unsigned __int16)v22 > 0xC6u)
+									&& ((unsigned __int16)v22 < 0x2Bu || (unsigned __int16)v22 > 0x2Du)
+									&& ((unsigned __int16)v22 < 0x31u || (unsigned __int16)v22 > 0x33u)
+									&& ((unsigned __int16)v22 < 0x34u || (unsigned __int16)v22 > 0x36u)
+									&& ((unsigned __int16)v22 < 0xFDu || (unsigned __int16)v22 > 0xFFu)
+									&& ((unsigned __int16)v22 < 0x61u || (unsigned __int16)v22 > 0x63u)
+									&& ((unsigned __int16)v22 < 0x1Cu || (unsigned __int16)v22 > 0x1Eu) )
+									break;
+								}
+								pParty->field_750[v12] = rand() % 258 + 1;
+							}
+						}
+					}
+					else
+					{
+						while ( 1 )
+						{
+							v23 = pParty->field_750[v12];
+							if ( (unsigned __int16)v23 < 0x73u || (unsigned __int16)v23 > 0x84u )
+							{
+							if ( ((unsigned __int16)v23 < 0xE8u || (unsigned __int16)v23 > 0xF9u)
+								&& ((unsigned __int16)v23 < 0x85u || (unsigned __int16)v23 > 0x96u)
+								&& ((unsigned __int16)v23 < 0x97u || (unsigned __int16)v23 > 0xBAu)
+								&& ((unsigned __int16)v23 < 0xBEu || (unsigned __int16)v23 > 0xC0u)
+								&& ((unsigned __int16)v23 < 0xC4u || (unsigned __int16)v23 > 0xC6u)
+								&& ((unsigned __int16)v23 < 0x2Bu || (unsigned __int16)v23 > 0x2Du)
+								&& ((unsigned __int16)v23 < 0x52u || (unsigned __int16)v23 > 0x54u)
+								&& ((unsigned __int16)v23 < 4u || (unsigned __int16)v23 > 6u)
+								&& ((unsigned __int16)v23 < 0x37u || (unsigned __int16)v23 > 0x39u)
+								&& ((unsigned __int16)v23 < 0x3Au || (unsigned __int16)v23 > 0x3Cu)
+								&& ((unsigned __int16)v23 < 0x3Du || (unsigned __int16)v23 > 0x3Fu)
+								&& ((unsigned __int16)v23 < 0xFDu || (unsigned __int16)v23 > 0xFFu)
+								&& ((unsigned __int16)v23 < 0x61u || (unsigned __int16)v23 > 0x63u)
+								&& ((unsigned __int16)v23 < 0xCDu || (unsigned __int16)v23 > 0xCFu) )
+									break;
+							}
+							pParty->field_750[v12] = rand() % 258 + 1;
+						}
+					}
+				}
+				else
+				{
+					while ( 1 )
+					{
+						v24 = pParty->field_750[v12];
+						if ( (unsigned __int16)v24 < 0x73u || (unsigned __int16)v24 > 0x84u )
+						{
+							if ( ((unsigned __int16)v24 < 0xEBu || (unsigned __int16)v24 > 0xFCu)
+							&& ((unsigned __int16)v24 < 0x85u || (unsigned __int16)v24 > 0x96u)
+							&& ((unsigned __int16)v24 < 0x97u || (unsigned __int16)v24 > 0xBAu)
+							&& ((unsigned __int16)v24 < 0xBEu || (unsigned __int16)v24 > 0xC0u)
+							&& ((unsigned __int16)v24 < 0xC4u || (unsigned __int16)v24 > 0xC6u)
+							&& ((unsigned __int16)v24 < 0x2Bu || (unsigned __int16)v24 > 0x2Du)
+							&& ((unsigned __int16)v24 < 0xCDu || (unsigned __int16)v24 > 0xCFu)
+							&& ((unsigned __int16)v24 < 0x5Eu || (unsigned __int16)v24 > 0x60u)
+							&& ((unsigned __int16)v24 < 0xFDu || (unsigned __int16)v24 > 0xFFu)
+							&& ((unsigned __int16)v24 < 0x6Du || (unsigned __int16)v24 > 0x6Fu)
+							&& ((unsigned __int16)v24 < 0x61u || (unsigned __int16)v24 > 0x63u) )
+								break;
+						}
+						pParty->field_750[v12] = rand() % 258 + 1;
+					}
+				}
+				v10 = v56;
+			}
+			v25 = v10;
+			v26 = pParty->field_750[v25];
+			v27 = pParty->field_75A[v25] == v13;
+			word_F8B1A0 = pParty->field_750[v25];
+			if ( v27 )
+			{
+				//v1 = 0;
+				v27 = v26 == v13;
+				v29 = (int)pNPCTopics[351].pText;
+				if ( v27 )
+					v29 = (int)pNPCTopics[353].pText;
+				dword_F8B1A4 = (char *)v29;
+			}
+			else
+			{
+				if ( v26 != v13 )
+				{
+					party_finds_gold(100 * pMonsterStats->pInfos[(unsigned __int16)v26].uLevel, 0);
+					v28 = pParty->pPlayers;
+					do
+					{
+						v28->SetVariable(VAR_Award, 86);
+						++v28;
+					}
+					while ( (signed int)v28 < (signed int)pParty->pHirelings );
+					pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->field_750[v25]].uLevel;
+					pParty->field_750[v25] = v13;
+					pParty->field_75A[v25] = v13;
+				}
+				//v1 = 0;
+				dword_F8B1A4 = pNPCTopics[352].pText;
+			}
+		}
+		else if ( uMessageParam == 100 )
+		{
+			pKeyActionMap->EnterText(1, 10, v8);
+		}
+		break;
+		}
+	case 22:
+		{
+		if ( dialog_menu_id >= 7 && dialog_menu_id <= 8 )
+			pKeyActionMap->EnterText(1, 10, v8);
+		return;
+		break;
+		}
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 21:
+	case 23:
+	case 30:
+		{
+		break;
+		}
+	default:
+		{
+		return;
+		break;
+		}
+  }
+
+  /*
   if ( in_current_building_type > BildingType_Tavern )
   {
     if ( in_current_building_type == BildingType_Bank )
@@ -969,10 +1252,9 @@
     if ( in_current_building_type != BildingType_Temple && in_current_building_type != BildingType_Training )
       return;
   }
-  else
-  {
-    if ( in_current_building_type != BildingType_Tavern )
-    {
+  //else
+  if ( in_current_building_type < BildingType_Tavern )
+  {
       if (in_current_building_type <= 0)
         return;
       if ( in_current_building_type > BildingType_AlchemistShop )
@@ -1014,232 +1296,240 @@
         }
         if ( in_current_building_type != BildingType_TownHall )
           return;
-        if ( uMessageParam == 99 )
-        {
-          v10 = (int)((char *)v8->ptr_1C - 102);
-          v56 = v10;
-          v11 = 8 * v10 + 11325428;
-          if ( (signed __int64)__PAIR__(pParty->field_3C.field_0[2 * v10 + 1], pParty->field_3C.field_0[2 * v10]) >= (signed __int64)pParty->uTimePlayed )
-          {
-            v13 = 0;
-          }
-          else
-          {
-            v12 = v10;
-            v13 = 0;
-            pParty->field_75A[v12] = 0;
-            *(_QWORD *)v11 = (signed __int64)((double)(309657600 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
-            v14 = rand() % 258;
-            v15 = window_SpeakInHouse;
-            pParty->field_750[v12] = v14 + 1;
-            v16 = (int)((char *)v15->ptr_1C - 102);
-            if ( v16 )
-            {
-              v17 = v16 - 1;
-              if ( v17 )
-              {
-                v18 = v17 - 1;
-                if ( v18 )
-                {
-                  v19 = v18 - 1;
-                  if ( v19 )
-                  {
-                    if ( v19 == 1 )
-                    {
-                      while ( 1 )
-                      {
-                        v20 = pParty->field_750[v12];
-                        if ( (unsigned __int16)v20 < 0x73u || (unsigned __int16)v20 > 0x84u )
-                        {
-                          if ( ((unsigned __int16)v20 < 0xE8u || (unsigned __int16)v20 > 0xF9u)
-                            && ((unsigned __int16)v20 < 0x85u || (unsigned __int16)v20 > 0x96u)
-                            && ((unsigned __int16)v20 < 0x97u || (unsigned __int16)v20 > 0xBAu)
-                            && ((unsigned __int16)v20 < 0xBEu || (unsigned __int16)v20 > 0xC0u)
-                            && ((unsigned __int16)v20 < 0xC4u || (unsigned __int16)v20 > 0xC6u)
-                            && ((unsigned __int16)v20 < 0x2Bu || (unsigned __int16)v20 > 0x2Du)
-                            && ((unsigned __int16)v20 < 0x6Du || (unsigned __int16)v20 > 0x6Fu)
-                            && ((unsigned __int16)v20 < 0x46u || (unsigned __int16)v20 > 0x48u)
-                            && ((unsigned __int16)v20 < 0x100u || (unsigned __int16)v20 > 0x102u)
-                            && ((unsigned __int16)v20 < 0xD9u || (unsigned __int16)v20 > 0xDBu)
-                            && ((unsigned __int16)v20 < 0xC7u || (unsigned __int16)v20 > 0xC9u)
-                            && ((unsigned __int16)v20 < 0xE5u || (unsigned __int16)v20 > 0xE7u)
-                            && ((unsigned __int16)v20 < 0xDFu || (unsigned __int16)v20 > 0xE1u)
-                            && ((unsigned __int16)v20 < 0x5Bu || (unsigned __int16)v20 > 0x5Du)
-                            && ((unsigned __int16)v20 < 0x49u || (unsigned __int16)v20 > 0x4Bu)
-                            && ((unsigned __int16)v20 < 0xFDu || (unsigned __int16)v20 > 0xFFu)
-                            && ((unsigned __int16)v20 < 0x61u || (unsigned __int16)v20 > 0x63u)
-                            && ((unsigned __int16)v20 < 0x10u || (unsigned __int16)v20 > 0x12u) )
-                            break;
-                        }
-                        pParty->field_750[v12] = rand() % 258 + 1;
-                      }
-                    }
-                  }
-                  else
-                  {
-                    while ( 1 )
-                    {
-                      v21 = pParty->field_750[v12];
-                      if ( (unsigned __int16)v21 < 0x73u || (unsigned __int16)v21 > 0x84u )
-                      {
-                        if ( ((unsigned __int16)v21 < 0xE8u || (unsigned __int16)v21 > 0xF9u)
-                          && ((unsigned __int16)v21 < 0x85u || (unsigned __int16)v21 > 0x96u)
-                          && ((unsigned __int16)v21 < 0x97u || (unsigned __int16)v21 > 0xBAu)
-                          && ((unsigned __int16)v21 < 0xBEu || (unsigned __int16)v21 > 0xC0u)
-                          && ((unsigned __int16)v21 < 0xC4u || (unsigned __int16)v21 > 0xC6u)
-                          && ((unsigned __int16)v21 < 0x2Bu || (unsigned __int16)v21 > 0x2Du)
-                          && ((unsigned __int16)v21 < 0x5Eu || (unsigned __int16)v21 > 0x60u)
-                          && ((unsigned __int16)v21 < 0x43u || (unsigned __int16)v21 > 0x45u)
-                          && ((unsigned __int16)v21 < 0x4Fu || (unsigned __int16)v21 > 0x51u)
-                          && ((unsigned __int16)v21 < 0xC1u || (unsigned __int16)v21 > 0xC3u)
-                          && ((unsigned __int16)v21 < 0x13u || (unsigned __int16)v21 > 0x15u)
-                          && ((unsigned __int16)v21 < 0xFDu || (unsigned __int16)v21 > 0xFFu)
-                          && ((unsigned __int16)v21 < 0x61u || (unsigned __int16)v21 > 0x63u)
-                          && ((unsigned __int16)v21 < 0x6Au || (unsigned __int16)v21 > 0x6Cu) )
-                          break;
-                      }
-                      pParty->field_750[v12] = rand() % 258 + 1;
-                    }
-                  }
-                }
-                else
-                {
-                  while ( 1 )
-                  {
-                    v22 = pParty->field_750[v12];
-                    if ( (unsigned __int16)v22 < 0x73u || (unsigned __int16)v22 > 0x84u )
-                    {
-                      if ( ((unsigned __int16)v22 < 0xE8u || (unsigned __int16)v22 > 0xF9u)
-                        && ((unsigned __int16)v22 < 0x85u || (unsigned __int16)v22 > 0x96u)
-                        && ((unsigned __int16)v22 < 0x97u || (unsigned __int16)v22 > 0xBAu)
-                        && ((unsigned __int16)v22 < 0xBEu || (unsigned __int16)v22 > 0xC0u)
-                        && ((unsigned __int16)v22 < 0xC4u || (unsigned __int16)v22 > 0xC6u)
-                        && ((unsigned __int16)v22 < 0x2Bu || (unsigned __int16)v22 > 0x2Du)
-                        && ((unsigned __int16)v22 < 0x31u || (unsigned __int16)v22 > 0x33u)
-                        && ((unsigned __int16)v22 < 0x34u || (unsigned __int16)v22 > 0x36u)
-                        && ((unsigned __int16)v22 < 0xFDu || (unsigned __int16)v22 > 0xFFu)
-                        && ((unsigned __int16)v22 < 0x61u || (unsigned __int16)v22 > 0x63u)
-                        && ((unsigned __int16)v22 < 0x1Cu || (unsigned __int16)v22 > 0x1Eu) )
-                        break;
-                    }
-                    pParty->field_750[v12] = rand() % 258 + 1;
-                  }
-                }
-              }
-              else
-              {
-                while ( 1 )
-                {
-                  v23 = pParty->field_750[v12];
-                  if ( (unsigned __int16)v23 < 0x73u || (unsigned __int16)v23 > 0x84u )
-                  {
-                    if ( ((unsigned __int16)v23 < 0xE8u || (unsigned __int16)v23 > 0xF9u)
-                      && ((unsigned __int16)v23 < 0x85u || (unsigned __int16)v23 > 0x96u)
-                      && ((unsigned __int16)v23 < 0x97u || (unsigned __int16)v23 > 0xBAu)
-                      && ((unsigned __int16)v23 < 0xBEu || (unsigned __int16)v23 > 0xC0u)
-                      && ((unsigned __int16)v23 < 0xC4u || (unsigned __int16)v23 > 0xC6u)
-                      && ((unsigned __int16)v23 < 0x2Bu || (unsigned __int16)v23 > 0x2Du)
-                      && ((unsigned __int16)v23 < 0x52u || (unsigned __int16)v23 > 0x54u)
-                      && ((unsigned __int16)v23 < 4u || (unsigned __int16)v23 > 6u)
-                      && ((unsigned __int16)v23 < 0x37u || (unsigned __int16)v23 > 0x39u)
-                      && ((unsigned __int16)v23 < 0x3Au || (unsigned __int16)v23 > 0x3Cu)
-                      && ((unsigned __int16)v23 < 0x3Du || (unsigned __int16)v23 > 0x3Fu)
-                      && ((unsigned __int16)v23 < 0xFDu || (unsigned __int16)v23 > 0xFFu)
-                      && ((unsigned __int16)v23 < 0x61u || (unsigned __int16)v23 > 0x63u)
-                      && ((unsigned __int16)v23 < 0xCDu || (unsigned __int16)v23 > 0xCFu) )
-                      break;
-                  }
-                  pParty->field_750[v12] = rand() % 258 + 1;
-                }
-              }
-            }
-            else
-            {
-              while ( 1 )
-              {
-                v24 = pParty->field_750[v12];
-                if ( (unsigned __int16)v24 < 0x73u || (unsigned __int16)v24 > 0x84u )
-                {
-                  if ( ((unsigned __int16)v24 < 0xEBu || (unsigned __int16)v24 > 0xFCu)
-                    && ((unsigned __int16)v24 < 0x85u || (unsigned __int16)v24 > 0x96u)
-                    && ((unsigned __int16)v24 < 0x97u || (unsigned __int16)v24 > 0xBAu)
-                    && ((unsigned __int16)v24 < 0xBEu || (unsigned __int16)v24 > 0xC0u)
-                    && ((unsigned __int16)v24 < 0xC4u || (unsigned __int16)v24 > 0xC6u)
-                    && ((unsigned __int16)v24 < 0x2Bu || (unsigned __int16)v24 > 0x2Du)
-                    && ((unsigned __int16)v24 < 0xCDu || (unsigned __int16)v24 > 0xCFu)
-                    && ((unsigned __int16)v24 < 0x5Eu || (unsigned __int16)v24 > 0x60u)
-                    && ((unsigned __int16)v24 < 0xFDu || (unsigned __int16)v24 > 0xFFu)
-                    && ((unsigned __int16)v24 < 0x6Du || (unsigned __int16)v24 > 0x6Fu)
-                    && ((unsigned __int16)v24 < 0x61u || (unsigned __int16)v24 > 0x63u) )
-                    break;
-                }
-                pParty->field_750[v12] = rand() % 258 + 1;
-              }
-            }
-            v10 = v56;
-          }
-          v25 = v10;
-          v26 = pParty->field_750[v25];
-          v27 = pParty->field_75A[v25] == v13;
-          word_F8B1A0 = pParty->field_750[v25];
-          if ( v27 )
-          {
-            //v1 = 0;
-            v27 = v26 == v13;
-            v29 = (int)pNPCTopics[351].pText;
-            if ( v27 )
-              v29 = (int)pNPCTopics[353].pText;
-            dword_F8B1A4 = (char *)v29;
-          }
-          else
-          {
-            if ( v26 != v13 )
-            {
-              party_finds_gold(100 * pMonsterStats->pInfos[(unsigned __int16)v26].uLevel, 0);
-              v28 = pParty->pPlayers;
-              do
-              {
-                v28->SetVariable(VAR_Award, 86);
-                ++v28;
-              }
-              while ( (signed int)v28 < (signed int)pParty->pHirelings );
-              pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->field_750[v25]].uLevel;
-              pParty->field_750[v25] = v13;
-              pParty->field_75A[v25] = v13;
-            }
-            //v1 = 0;
-            dword_F8B1A4 = pNPCTopics[352].pText;
-          }
-        }
-        else if ( uMessageParam == 100 )
-        {
-          pKeyActionMap->EnterText(1, 10, v8);
-        }
-      }
-    }
-  }
-  if ( uMessageParam > 95 )
-  {
-LABEL_196:
-    switch ( uMessageParam )
-    {
-      case 96:
+		if ( in_current_building_type == BildingType_TownHall )
+		{
+			if ( uMessageParam == 99 )
+			{
+			  v10 = (int)((char *)v8->ptr_1C - 102);
+			  v56 = v10;
+			  v11 = 8 * v10 + 11325428;
+			  if ( (signed __int64)__PAIR__(pParty->field_3C.field_0[2 * v10 + 1], pParty->field_3C.field_0[2 * v10]) >= (signed __int64)pParty->uTimePlayed )
+			  {
+				v13 = 0;
+			  }
+			  else
+			  {
+				v12 = v10;
+				v13 = 0;
+				pParty->field_75A[v12] = 0;
+				*(_QWORD *)v11 = (signed __int64)((double)(309657600 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
+				v14 = rand() % 258;
+				v15 = window_SpeakInHouse;
+				pParty->field_750[v12] = v14 + 1;
+				v16 = (int)((char *)v15->ptr_1C - 102);
+				if ( v16 )
+				{
+				  v17 = v16 - 1;
+				  if ( v17 )
+				  {
+					v18 = v17 - 1;
+					if ( v18 )
+					{
+					  v19 = v18 - 1;
+					  if ( v19 )
+					  {
+						if ( v19 == 1 )
+						{
+						  while ( 1 )
+						  {
+							v20 = pParty->field_750[v12];
+							if ( (unsigned __int16)v20 < 0x73u || (unsigned __int16)v20 > 0x84u )
+							{
+							  if ( ((unsigned __int16)v20 < 0xE8u || (unsigned __int16)v20 > 0xF9u)
+								&& ((unsigned __int16)v20 < 0x85u || (unsigned __int16)v20 > 0x96u)
+								&& ((unsigned __int16)v20 < 0x97u || (unsigned __int16)v20 > 0xBAu)
+								&& ((unsigned __int16)v20 < 0xBEu || (unsigned __int16)v20 > 0xC0u)
+								&& ((unsigned __int16)v20 < 0xC4u || (unsigned __int16)v20 > 0xC6u)
+								&& ((unsigned __int16)v20 < 0x2Bu || (unsigned __int16)v20 > 0x2Du)
+								&& ((unsigned __int16)v20 < 0x6Du || (unsigned __int16)v20 > 0x6Fu)
+								&& ((unsigned __int16)v20 < 0x46u || (unsigned __int16)v20 > 0x48u)
+								&& ((unsigned __int16)v20 < 0x100u || (unsigned __int16)v20 > 0x102u)
+								&& ((unsigned __int16)v20 < 0xD9u || (unsigned __int16)v20 > 0xDBu)
+								&& ((unsigned __int16)v20 < 0xC7u || (unsigned __int16)v20 > 0xC9u)
+								&& ((unsigned __int16)v20 < 0xE5u || (unsigned __int16)v20 > 0xE7u)
+								&& ((unsigned __int16)v20 < 0xDFu || (unsigned __int16)v20 > 0xE1u)
+								&& ((unsigned __int16)v20 < 0x5Bu || (unsigned __int16)v20 > 0x5Du)
+								&& ((unsigned __int16)v20 < 0x49u || (unsigned __int16)v20 > 0x4Bu)
+								&& ((unsigned __int16)v20 < 0xFDu || (unsigned __int16)v20 > 0xFFu)
+								&& ((unsigned __int16)v20 < 0x61u || (unsigned __int16)v20 > 0x63u)
+								&& ((unsigned __int16)v20 < 0x10u || (unsigned __int16)v20 > 0x12u) )
+								break;
+							}
+							pParty->field_750[v12] = rand() % 258 + 1;
+						  }
+						}
+					  }
+					  else
+					  {
+						while ( 1 )
+						{
+						  v21 = pParty->field_750[v12];
+						  if ( (unsigned __int16)v21 < 0x73u || (unsigned __int16)v21 > 0x84u )
+						  {
+							if ( ((unsigned __int16)v21 < 0xE8u || (unsigned __int16)v21 > 0xF9u)
+							  && ((unsigned __int16)v21 < 0x85u || (unsigned __int16)v21 > 0x96u)
+							  && ((unsigned __int16)v21 < 0x97u || (unsigned __int16)v21 > 0xBAu)
+							  && ((unsigned __int16)v21 < 0xBEu || (unsigned __int16)v21 > 0xC0u)
+							  && ((unsigned __int16)v21 < 0xC4u || (unsigned __int16)v21 > 0xC6u)
+							  && ((unsigned __int16)v21 < 0x2Bu || (unsigned __int16)v21 > 0x2Du)
+							  && ((unsigned __int16)v21 < 0x5Eu || (unsigned __int16)v21 > 0x60u)
+							  && ((unsigned __int16)v21 < 0x43u || (unsigned __int16)v21 > 0x45u)
+							  && ((unsigned __int16)v21 < 0x4Fu || (unsigned __int16)v21 > 0x51u)
+							  && ((unsigned __int16)v21 < 0xC1u || (unsigned __int16)v21 > 0xC3u)
+							  && ((unsigned __int16)v21 < 0x13u || (unsigned __int16)v21 > 0x15u)
+							  && ((unsigned __int16)v21 < 0xFDu || (unsigned __int16)v21 > 0xFFu)
+							  && ((unsigned __int16)v21 < 0x61u || (unsigned __int16)v21 > 0x63u)
+							  && ((unsigned __int16)v21 < 0x6Au || (unsigned __int16)v21 > 0x6Cu) )
+							  break;
+						  }
+						  pParty->field_750[v12] = rand() % 258 + 1;
+						}
+					  }
+					}
+					else
+					{
+					  while ( 1 )
+					  {
+						v22 = pParty->field_750[v12];
+						if ( (unsigned __int16)v22 < 0x73u || (unsigned __int16)v22 > 0x84u )
+						{
+						  if ( ((unsigned __int16)v22 < 0xE8u || (unsigned __int16)v22 > 0xF9u)
+							&& ((unsigned __int16)v22 < 0x85u || (unsigned __int16)v22 > 0x96u)
+							&& ((unsigned __int16)v22 < 0x97u || (unsigned __int16)v22 > 0xBAu)
+							&& ((unsigned __int16)v22 < 0xBEu || (unsigned __int16)v22 > 0xC0u)
+							&& ((unsigned __int16)v22 < 0xC4u || (unsigned __int16)v22 > 0xC6u)
+							&& ((unsigned __int16)v22 < 0x2Bu || (unsigned __int16)v22 > 0x2Du)
+							&& ((unsigned __int16)v22 < 0x31u || (unsigned __int16)v22 > 0x33u)
+							&& ((unsigned __int16)v22 < 0x34u || (unsigned __int16)v22 > 0x36u)
+							&& ((unsigned __int16)v22 < 0xFDu || (unsigned __int16)v22 > 0xFFu)
+							&& ((unsigned __int16)v22 < 0x61u || (unsigned __int16)v22 > 0x63u)
+							&& ((unsigned __int16)v22 < 0x1Cu || (unsigned __int16)v22 > 0x1Eu) )
+							break;
+						}
+						pParty->field_750[v12] = rand() % 258 + 1;
+					  }
+					}
+				  }
+				  else
+				  {
+					while ( 1 )
+					{
+					  v23 = pParty->field_750[v12];
+					  if ( (unsigned __int16)v23 < 0x73u || (unsigned __int16)v23 > 0x84u )
+					  {
+						if ( ((unsigned __int16)v23 < 0xE8u || (unsigned __int16)v23 > 0xF9u)
+						  && ((unsigned __int16)v23 < 0x85u || (unsigned __int16)v23 > 0x96u)
+						  && ((unsigned __int16)v23 < 0x97u || (unsigned __int16)v23 > 0xBAu)
+						  && ((unsigned __int16)v23 < 0xBEu || (unsigned __int16)v23 > 0xC0u)
+						  && ((unsigned __int16)v23 < 0xC4u || (unsigned __int16)v23 > 0xC6u)
+						  && ((unsigned __int16)v23 < 0x2Bu || (unsigned __int16)v23 > 0x2Du)
+						  && ((unsigned __int16)v23 < 0x52u || (unsigned __int16)v23 > 0x54u)
+						  && ((unsigned __int16)v23 < 4u || (unsigned __int16)v23 > 6u)
+						  && ((unsigned __int16)v23 < 0x37u || (unsigned __int16)v23 > 0x39u)
+						  && ((unsigned __int16)v23 < 0x3Au || (unsigned __int16)v23 > 0x3Cu)
+						  && ((unsigned __int16)v23 < 0x3Du || (unsigned __int16)v23 > 0x3Fu)
+						  && ((unsigned __int16)v23 < 0xFDu || (unsigned __int16)v23 > 0xFFu)
+						  && ((unsigned __int16)v23 < 0x61u || (unsigned __int16)v23 > 0x63u)
+						  && ((unsigned __int16)v23 < 0xCDu || (unsigned __int16)v23 > 0xCFu) )
+						  break;
+					  }
+					  pParty->field_750[v12] = rand() % 258 + 1;
+					}
+				  }
+				}
+				else
+				{
+				  while ( 1 )
+				  {
+					v24 = pParty->field_750[v12];
+					if ( (unsigned __int16)v24 < 0x73u || (unsigned __int16)v24 > 0x84u )
+					{
+					  if ( ((unsigned __int16)v24 < 0xEBu || (unsigned __int16)v24 > 0xFCu)
+						&& ((unsigned __int16)v24 < 0x85u || (unsigned __int16)v24 > 0x96u)
+						&& ((unsigned __int16)v24 < 0x97u || (unsigned __int16)v24 > 0xBAu)
+						&& ((unsigned __int16)v24 < 0xBEu || (unsigned __int16)v24 > 0xC0u)
+						&& ((unsigned __int16)v24 < 0xC4u || (unsigned __int16)v24 > 0xC6u)
+						&& ((unsigned __int16)v24 < 0x2Bu || (unsigned __int16)v24 > 0x2Du)
+						&& ((unsigned __int16)v24 < 0xCDu || (unsigned __int16)v24 > 0xCFu)
+						&& ((unsigned __int16)v24 < 0x5Eu || (unsigned __int16)v24 > 0x60u)
+						&& ((unsigned __int16)v24 < 0xFDu || (unsigned __int16)v24 > 0xFFu)
+						&& ((unsigned __int16)v24 < 0x6Du || (unsigned __int16)v24 > 0x6Fu)
+						&& ((unsigned __int16)v24 < 0x61u || (unsigned __int16)v24 > 0x63u) )
+						break;
+					}
+					pParty->field_750[v12] = rand() % 258 + 1;
+				  }
+				}
+				v10 = v56;
+			  }
+			  v25 = v10;
+			  v26 = pParty->field_750[v25];
+			  v27 = pParty->field_75A[v25] == v13;
+			  word_F8B1A0 = pParty->field_750[v25];
+			  if ( v27 )
+			  {
+				//v1 = 0;
+				v27 = v26 == v13;
+				v29 = (int)pNPCTopics[351].pText;
+				if ( v27 )
+				  v29 = (int)pNPCTopics[353].pText;
+				dword_F8B1A4 = (char *)v29;
+			  }
+			  else
+			  {
+				if ( v26 != v13 )
+				{
+				  party_finds_gold(100 * pMonsterStats->pInfos[(unsigned __int16)v26].uLevel, 0);
+				  v28 = pParty->pPlayers;
+				  do
+				  {
+					v28->SetVariable(VAR_Award, 86);
+					++v28;
+				  }
+				  while ( (signed int)v28 < (signed int)pParty->pHirelings );
+				  pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->field_750[v25]].uLevel;
+				  pParty->field_750[v25] = v13;
+				  pParty->field_75A[v25] = v13;
+				}
+				//v1 = 0;
+				dword_F8B1A4 = pNPCTopics[352].pText;
+			  }
+			}
+			else if ( uMessageParam == 100 )
+			{
+			  pKeyActionMap->EnterText(1, 10, v8);
+			}
+		}
+	  }
+  }
+  */
+  
+
+//LABEL_196:
+  switch ( uMessageParam )
+  {
+    case 96:
+		{
         pDialogueWindow->eWindowType = WINDOW_MainMenu;
         UI_CreateEndConversationButton();
         FillAviableSkillsToTeach(in_current_building_type);
         break;
-      case 101:
+		}
+    case 101:
+		{
         pDialogueWindow->eWindowType = WINDOW_MainMenu;
         UI_CreateEndConversationButton();
         sub_4B3A72(in_current_building_type);
         break;
-      case 102:
-        dialog_menu_id = 102;
+		}
+    case 102:
+    case 103:
+		{
+        dialog_menu_id = uMessageParam;
         break;
-      case 103:
-        dialog_menu_id = 103;
-        break;
-      case 104:
+		}
+    case 104:
+		{
         /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
         {
           pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = (UIMessageType)29;
@@ -1250,9 +1540,181 @@
         pMessageQueue_50CBD0->AddMessage(UIMSG_PlayArcomage, 0, 0);
         dialog_menu_id = 104;
         break;
-    }
-    return;
-  }
+		}
+	case 2:
+	case 95:
+		{
+		if ( pParty->field_3C.field_50[(unsigned int)v8->ptr_1C] < (signed __int64)pParty->uTimePlayed )
+		{
+			GenerateStandartShopItems();
+			GenerateSpecialShopItems();
+			v8 = window_SpeakInHouse;
+			v40 = window_SpeakInHouse->par1C;
+			//v3 = dword_F8B198;
+			v41 = pParty->uTimePlayed
+				//+ (signed __int64)((double)(11059200 * (signed int)p2DEvents_minus1[26 * (unsigned int)ptr_507BC0->ptr_1C])
+				+ (signed __int64)((double)(11059200 * (signed int)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].field_1C)
+									* 0.033333335);
+			pParty->field_3C.field_50[v40] = v41;
+   		}
+		v42 = v8->ptr_1C;
+		v43 = 0;
+		//v44 = p2DEvents_minus1___00[26 * (unsigned int)v8->ptr_1C];
+		v44 = p2DEvents[(unsigned int)v8->ptr_1C - 1].uType;
+		if ( uMessageParam == 2 )
+		{
+			if ( uItemsAmountPerShopType[v44] )
+			{
+				do
+				{
+					v45 = pParty->StandartItemsInShops[(int)v42][v43].uItemID;
+					if ( v45 )
+					{
+						v46 = pIcons_LOD->LoadTexture(pItemsTable->pItems[v45].pIconName, TEXTURE_16BIT_PALETTE);
+						//v3 = dword_F8B198;
+						v8 = window_SpeakInHouse;
+						ItemsInShopTexture[v43] = &pIcons_LOD->pTextures[v46];
+					}
+					v42 = v8->ptr_1C;
+					++v43;
+				}
+				//while ( v43 < (unsigned __int8)_4F063C_smthn_by_2da_uType[p2DEvents_minus1___00[26 * (unsigned int)v8->ptr_1C]] );
+				while ( v43 < (unsigned __int8)uItemsAmountPerShopType[p2DEvents[(unsigned int)v8->ptr_1C - 1].uType] );
+			}
+			if ( in_current_building_type == BildingType_WeaponShop )
+			{
+				v47 = v8->ptr_1C;
+				v48 = 0;
+				//if ( _4F063C_smthn_by_2da_uType[p2DEvents_minus1___00[26 * (unsigned int)v8->ptr_1C]] )
+				if ( uItemsAmountPerShopType[p2DEvents[(unsigned int)v8->ptr_1C - 1].uType] )
+				{
+					do
+					{
+						// if ( pParty->field_777C[9 * (v48 + 12 * (int)v47)] )
+						if ( pParty->StandartItemsInShops[(int)v47][v48].uItemID);
+						{
+							v49 = rand();
+							v8 = window_SpeakInHouse;
+							word_F8B158[v48] = v49 % (300 - ItemsInShopTexture[v48]->uTextureHeight);
+						}
+						v47 = v8->ptr_1C;
+						++v48;
+					}
+					//while ( v48 < (unsigned __int8)_4F063C_smthn_by_2da_uType[p2DEvents_minus1___00[26 * (unsigned int)v8->ptr_1C]] );
+					while ( v48 < (unsigned __int8)uItemsAmountPerShopType[p2DEvents[(unsigned int)v8->ptr_1C - 1].uType] );
+				}
+			}
+		}
+		if ( uMessageParam == 95 )
+		{
+			if ( uItemsAmountPerShopType[v44] )
+			{
+				do
+				{
+					//v50 = pParty->field_C59C[9 * (v43 + 12 * (int)v42) + 724];
+					v50=pParty->SpecialItemsInShops[(unsigned int)v42][(signed int)v43].uItemID;
+					if ( v50 )
+					{
+						v51 = pIcons_LOD->LoadTexture(pItemsTable->pItems[v50].pIconName, TEXTURE_16BIT_PALETTE);
+						//v3 = dword_F8B198;
+						v8 = window_SpeakInHouse;
+						ItemsInShopTexture[v43] = &pIcons_LOD->pTextures[v51];
+					}
+					v42 = v8->ptr_1C;
+					++v43;
+				}
+				//while ( v43 < (unsigned __int8)_4F063C_smthn_by_2da_uType[p2DEvents_minus1___00[26 * (unsigned int)v8->ptr_1C]] );
+				while ( v43 < (unsigned __int8)uItemsAmountPerShopType[p2DEvents[(unsigned int)v8->ptr_1C - 1].uType] );
+			}
+			if ( in_current_building_type == BildingType_WeaponShop )
+			{
+				v52 = v8->ptr_1C;
+				v53 = 0;
+				//if ( _4F063C_smthn_by_2da_uType[p2DEvents_minus1___00[26 * (unsigned int)v8->ptr_1C]] )
+				if ( uItemsAmountPerShopType[p2DEvents[(unsigned int)v8->ptr_1C - 1].uType] )
+				{
+					do
+					{
+						// if ( pParty->field_C59C[9 * (v53 + 12 * (int)v52) + 724] )
+						if (pParty->SpecialItemsInShops[(unsigned int)v52][v53].uItemID)
+						{
+							v54 = rand();
+							v8 = window_SpeakInHouse;
+							word_F8B158[v53] = v54 % (300 - ItemsInShopTexture[v53]->uTextureHeight);
+						}
+						v52 = v8->ptr_1C;
+						++v53;
+					}
+					//while ( v53 < (unsigned __int8)_4F063C_smthn_by_2da_uType[p2DEvents_minus1___00[26 * (unsigned int)v8->ptr_1C]] );
+					while ( v53 < (unsigned __int8)uItemsAmountPerShopType[p2DEvents[(unsigned int)v8->ptr_1C - 1].uType ] );
+				}
+			}
+		}
+		break;
+		}
+	case 3:
+	case 4:
+	case 5:
+		{
+		dialog_menu_id = uMessageParam;
+		sub_421B2C_PlaceInInventory_or_DropPickedItem();
+		break;
+		}
+	case 94:
+		{
+        pDialogueWindow->eWindowType = WINDOW_MainMenu;
+        UI_CreateEndConversationButton();
+        sub_4B3AD4(in_current_building_type);
+		break;
+		}
+	default:
+		{
+		if( uMessageParam >= 36 && uMessageParam <= 72 )
+		{
+			v35 = pPlayers[uActiveCharacter];
+			//v36 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)v8->ptr_1C] * 500.0);
+			v36 = (signed __int64)(p2DEvents[(unsigned int)v8->ptr_1C - 1].flt_24 * 500.0);
+			v37 = v36 * (100 - pPlayers[uActiveCharacter]->GetMerchant()) / 100;
+			if ( v37 < v36 / 3 )
+			v37 = v36 / 3;
+              
+			__debugbreak();
+			//pSkillAvailabilityPerClass[8 + v58->uClass][4 + v23]
+			// or
+			//byte_4ED970_skill_learn_ability_by_class_table[v58->uClass][v23 - 36]
+			// or
+			//byte_4ED970_skill_learn_ability_by_class_table[v58->uClass - 1][v23 + 1]
+
+			//if (false)
+			if(byte_4ED970_skill_learn_ability_by_class_table[v35->classType][uMessageParam-36])
+			//if ( *(&byte_4ED94C[37 * v35->uClass] + v55) )
+			{
+			v38 = (int)(&v35->uIntelligence + uMessageParam);
+			if ( !*(short *)v38 )
+			{
+				if ( pParty->uNumGold < v37 )
+				{
+				ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);
+				if ( in_current_building_type == BildingType_Training || in_current_building_type == BildingType_Tavern )
+					v39 = 4;
+				else
+					v39 = 2;
+				HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, v39);
+				}
+				else
+				{
+				Party::TakeGold(v37);
+				dword_F8B1E4 = 1;
+				*(short *)v38 = 1;
+				v35->PlaySound(SPEECH_78, 0);
+				}
+			}
+			}
+		}
+		break;
+		}
+  }
+  /*
   if ( uMessageParam != 95 && uMessageParam != 2 )
   {
     if ( uMessageParam == 3 )
@@ -1392,7 +1854,7 @@
       }
     }
   }
-  else
+  if ( uMessageParam == 95 )
   {
     if ( uItemsAmountPerShopType[v44] )
     {
@@ -1437,6 +1899,7 @@
       }
     }
   }
+*/
 }
 
 //----- (004BD8B5) --------------------------------------------------------
@@ -1646,367 +2109,365 @@
     pAudioPlayer->PlaySound(SOUND_27, v46, v47, v48, v49, v50, v52, v56);
     return;
   }
-  if ( dialog_menu_id > 18 )
-  {
-    if ( dialog_menu_id < 36 )
-      return;
-    if ( dialog_menu_id <= 72 )
-    {
-      v42 = dialog_menu_id - 36;
-      //v43 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)ptr_507BC0->ptr_1C] * 500.0);
-      v43 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
-      v44 = v43 * (100 - v0->GetMerchant()) / 100;
-      if ( v44 < v43 / 3 )
-        v44 = v43 / 3;
-      if ( byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v42] )
-      {
-        pSkill = &v0->pActiveSkills[v42];
-        if ( !*pSkill )
-        {
-          if ( pParty->uNumGold < v44 )
-          {
-            ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);// "You don't have enough gold"
-            v13 = window_SpeakInHouse->ptr_1C;
-            if ( in_current_building_type == BildingType_Training )
-              v55 = 4;
-            else
-              v55 = 2;
-            HousePlaySomeSound((unsigned int)v13, v55);
-            return;
-          }
-          Party::TakeGold(v44);
-          v53 = 0;
-          dword_F8B1E4 = 1;
-          *pSkill = 1;
-          v51 = 78;
-          v27 = v0;
-		  v27->PlaySound((PlayerSpeech)v51, v53);
-		  return;
-        }
-      }
-      return;
-    }
-    if ( dialog_menu_id != 94 )
-    {
-      if ( dialog_menu_id != 95 )
-        return;
-      goto LABEL_49;
-    }
-    pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
-//LABEL_73:
-    sub_421EA6_OnInventoryLeftClick();
-    return;
-  }
-  if ( dialog_menu_id == 18 )
-  {
-    v17 = pMouse->GetCursorPos(&v63);
-    v18 = pRenderer->pActiveZBuffer[v17->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v61)->y]] & 0xFFFF;
-    if ( !v18 )
-      return;
-    v19 = window_SpeakInHouse->ptr_1C;
-    v20 = (ItemGen *)(&pParty->pPlayers[1].uExpressionTimeLength + 18 * (v18 + 12 * (int)v19));
-    //v21 = p2DEvents_minus1__20[13 * (signed int)v19];
-    v21 = p2DEvents[(signed int)v19 - 1].fPriceMultiplier;
-    _this = v20;
-    v22 = v20->GetValue();
-    v23 = v0->_4B8142(v22, v21);
-    v80 = v23;
-    GetAsyncKeyState(VK_CONTROL);
-    if ( pParty->uNumGold < v23 )
-    {
-      v24 = 2;
-//LABEL_62:
-      HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, v24);
-      v9 = pGlobalTXT_LocalizationStrings[155];
-      v54 = 2;
-      ShowStatusBarString(v9, v54);
-      return;
-    }
-    v25 = v0->AddItem(0xFFFFFFFFu, v20->uItemID);
-    if ( v25 )
-    {
-      v26 = 1;
-      v20->SetIdentified();
-      memcpy(&v0->pInventoryItems[v25-1], v20, 0x24u);
-      dword_F8B1E4 = v26;
-      Party::TakeGold(v80);
-      viewparams->bRedrawGameUI = v26;
-      _this->Reset();
-      pRenderer->ClearZBuffer(0, 479);
-      v27 = v77;
-      v53 = 0;
-      v51 = SPEECH_75;
-      v27->PlaySound((PlayerSpeech)v51, v53);
-      return;
-    }
-    v0->PlaySound(SPEECH_NoRoom, 0);
-    v54 = 5;
-//LABEL_70:
-    v9 = pGlobalTXT_LocalizationStrings[563];   // "Pack is Full!"
-    ShowStatusBarString(v9, v54);
-    return;
-  }
-  if ( dialog_menu_id == 2 )
-  {
-LABEL_49:
-    v28 = pMouse->GetCursorPos(&v59);
-    v29 = pRenderer->pActiveZBuffer[v28->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v57)->y]] & 0xFFFF;
-    if ( !v29 )
-      return;
-    v30 = window_SpeakInHouse->ptr_1C;
-   // v31 = 9 * (v29 - 1 + 12 * (int)v30);
-    if ( dialog_menu_id == 2 )
-    {
-      v32 = (ItemGen *)&pParty->StandartItemsInShops[(int)v30][v29];
-      _this = (ItemGen *)&pParty->StandartItemsInShops[(int)v30][v29];
-    }
-    else
-    {
-      _this =&pParty->SpecialItemsInShops[(int)v30][v29-1]; //(ItemGen *)&pParty->field_C59C[v31 + 724];
-      v32 = &pParty->SpecialItemsInShops[(int)v30][v29-1];//(ItemGen *)&pParty->field_C59C[v31 + 724];
-    }
-    //v33 = p2DEvents_minus1__20[13 * (signed int)v30];
-    v33 = p2DEvents[(signed int)v30 - 1].fPriceMultiplier;
-    v34 = v32->GetValue();
-    v80 = v0->_4B8142(v34, v33);
-    LOWORD(v35) = GetAsyncKeyState(VK_CONTROL);
-    v74 = v35;
-    v36 = v0->CanSteal();
-    uNumSeconds = 0;
-    a3 = 0;
-    v73 = v36;
-    v37 = pMapStats->GetMapInfo(pCurrentMapName);
-    if ( v37 )
-      a3 = pMapStats->pInfos[v37]._steal_perm;
-    v38 = GetPartyReputation();
-    v26 = 1;
-    if ( v73 == 1 )
-    {
-      if ( (short)v74 )
-      {
-        uNumSeconds = v0->StealFromShop(v32, a3, v38, 0, &a6);
-        if ( !uNumSeconds )
-        {
-          sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, 0, a6);
-          return;
-        }
-      }
-    }
-    if ( pParty->uNumGold < v80 )
-    {
-      v24 = 2;
-      if ( uNumSeconds != 2 )
-      {
-        if ( uNumSeconds != 1 )
+  switch(dialog_menu_id)
+  {
+	case 94:
+		{
+			pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+			sub_421EA6_OnInventoryLeftClick();
+			break;
+		}
+	case 18:
+		{
+		v17 = pMouse->GetCursorPos(&v63);
+		v18 = pRenderer->pActiveZBuffer[v17->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v61)->y]] & 0xFFFF;
+		if ( !v18 )
+			return;
+		v19 = window_SpeakInHouse->ptr_1C;
+		v20 = (ItemGen *)(&pParty->pPlayers[1].uExpressionTimeLength + 18 * (v18 + 12 * (int)v19));
+		//v21 = p2DEvents_minus1__20[13 * (signed int)v19];
+		v21 = p2DEvents[(signed int)v19 - 1].fPriceMultiplier;
+		_this = v20;
+		v22 = v20->GetValue();
+		v23 = v0->_4B8142(v22, v21);
+		v80 = v23;
+		GetAsyncKeyState(VK_CONTROL);
+		if ( pParty->uNumGold < v23 )
+		{
+			v24 = 2;
+	//LABEL_62:
+			HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, v24);
+			v9 = pGlobalTXT_LocalizationStrings[155];
+			v54 = 2;
+			ShowStatusBarString(v9, v54);
+			return;
+		}
+		v25 = v0->AddItem(0xFFFFFFFFu, v20->uItemID);
+		if ( v25 )
+		{
+			v26 = 1;
+			v20->SetIdentified();
+			memcpy(&v0->pInventoryItems[v25-1], v20, 0x24u);
+			dword_F8B1E4 = v26;
+			Party::TakeGold(v80);
+			viewparams->bRedrawGameUI = v26;
+			_this->Reset();
+			pRenderer->ClearZBuffer(0, 479);
+			v27 = v77;
+			v53 = 0;
+			v51 = SPEECH_75;
+			v27->PlaySound((PlayerSpeech)v51, v53);
+			return;
+		}
+		v0->PlaySound(SPEECH_NoRoom, 0);
+		v54 = 5;
+	//LABEL_70:
+		v9 = pGlobalTXT_LocalizationStrings[563];   // "Pack is Full!"
+		ShowStatusBarString(v9, v54);
+		break;
+		}
+	case 3:
+		{
+		v14 = pMouse->GetCursorPos(&v71)->x - 14;
+		v79 = (v14 >> 5) + 14 * ((pMouse->GetCursorPos(&v69)->y - 17) >> 5);
+		if ( pMouse->GetCursorPos(&v67)->x <= 13
+			|| pMouse->GetCursorPos(&v65)->x >= 462
+			|| (v15 = v0->GetItemIDAtInventoryIndex((int *)&v79), (v77 = (Player *)v15) == 0) )
+			return;
+		v16 = window_SpeakInHouse;
+		if ( sub_4BDAAF((ItemGen *)&v0->pInventoryItems[v15-1], (int)window_SpeakInHouse->ptr_1C) )
 		{
-		  HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, v24);
-		  v9 = pGlobalTXT_LocalizationStrings[155];
-		  v54 = 2;
-          ShowStatusBarString(v9, v54);
-          return;
+			dword_F8B1E4 = 1;
+			v0->_4BE2DD(v79, (int)((char *)v77 - 1), (int)v16->ptr_1C);
+			viewparams->bRedrawGameUI = 1;
+			pRenderer->ClearZBuffer(0, 479);
+			v53 = 0;
+			v51 = 77;
+			v27 = v0;
+			v27->PlaySound((PlayerSpeech)v51, v53);
+			return;
+		}
+		v0->PlaySound(SPEECH_79, 0);
+		v56 = 0;
+		v52 = 0;
+		v50 = 0;
+		v49 = 0;
+		v48 = -1;
+		v47 = 0;
+		v46 = 0;
+		//LABEL_87:
+		pAudioPlayer->PlaySound(SOUND_27, v46, v47, v48, v49, v50, v52, v56);
+		break;
+		}
+	case 4:
+		{
+		v10 = pMouse->GetCursorPos(&v62)->x - 14;
+		v79 = (v10 >> 5) + 14 * ((pMouse->GetCursorPos(&v66)->y - 17) >> 5);
+		if ( pMouse->GetCursorPos(&v58)->x > 13 )
+		{
+			if ( pMouse->GetCursorPos(&v64)->x < 462 )
+			{
+			v11 = v0->GetItemIDAtInventoryIndex((int *)&v79);
+			if ( v11 )
+			{
+				//v80 = v0->_4B8179(p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C]);
+				v80 = v0->_4B8179(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier);
+				v12 = (int)&v0->pInventoryItems[v11-1];
+				if ( !(*(char *)(v12 + 20) & 1) )
+				{
+				_this = (ItemGen *)window_SpeakInHouse->ptr_1C;
+				if ( sub_4BDAAF((ItemGen *)v12, (int)_this) )
+				{
+					if ( pParty->uNumGold >= v80 )
+					{
+					dword_F8B1E4 = 1;
+					Party::TakeGold(v80);
+					*(int *)(v12 + 20) |= 1u;
+					v0->PlaySound(SPEECH_73, 0);
+					v9 = pGlobalTXT_LocalizationStrings[569];
+					v54 = 2;
+					ShowStatusBarString(v9, v54);
+					return;
+					}
+					v13 = _this;
+					v55 = 2;
+					HousePlaySomeSound((unsigned int)v13, v55);
+					return;
+				}
+				pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+				v53 = 0;
+				v51 = 79;
+				v27 = v0;
+				v27->PlaySound((PlayerSpeech)v51, v53);
+				return;
+				}
+				v53 = 0;
+	//LABEL_30:
+				v51 = 76;
+				v27 = v0;
+				v27->PlaySound((PlayerSpeech)v51, v53);
+				return;
+			}
+			}
+		}
+		break;
 		}
-      }
-    }
-    v39 = v0->AddItem(0xFFFFFFFFu, v32->uItemID);
-    if ( v39 )
-    {
-      v32->SetIdentified();
-      v7 = v73 == 1;
-      v40 = (int)((char *)v0 + 36 * v39);
-      memcpy((void *)(v40 + 496), v32, 0x24u);
-      if ( v7 )
-      {
-        if ( (short)v74 )
-        {
-          v41 = uNumSeconds;
-          if ( uNumSeconds == 1 || uNumSeconds == 2 )
-          {
-            *(char *)(v40 + 517) |= 1u;
-            sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, v41, a6);
-		    viewparams->bRedrawGameUI = v26;
-		    _this->Reset();
-		    pRenderer->ClearZBuffer(0, 479);
-		    v27 = v77;
-		    v53 = 0;
-		    v51 = SPEECH_75;
-		    v27->PlaySound((PlayerSpeech)v51, v53);
-		    return;
-          }
-        }
-      }
-//LABEL_42:
-      dword_F8B1E4 = v26;
-      Party::TakeGold(v80);
-//LABEL_43:
-      viewparams->bRedrawGameUI = v26;
-      _this->Reset();
-      pRenderer->ClearZBuffer(0, 479);
-      v27 = v77;
-      v53 = 0;
-      v51 = SPEECH_75;
-//LABEL_81:
-      v27->PlaySound((PlayerSpeech)v51, v53);
-      return;
-    }
-    v0->PlaySound(SPEECH_NoRoom, 0);
-    v54 = 2;
-    v9 = pGlobalTXT_LocalizationStrings[563];   // "Pack is Full!"
-    ShowStatusBarString(v9, v54);
-    return;
-  }
-  if ( dialog_menu_id == 3 )
-  {
-    v14 = pMouse->GetCursorPos(&v71)->x - 14;
-    v79 = (v14 >> 5) + 14 * ((pMouse->GetCursorPos(&v69)->y - 17) >> 5);
-    if ( pMouse->GetCursorPos(&v67)->x <= 13
-      || pMouse->GetCursorPos(&v65)->x >= 462
-      || (v15 = v0->GetItemIDAtInventoryIndex((int *)&v79), (v77 = (Player *)v15) == 0) )
-      return;
-    v16 = window_SpeakInHouse;
-    if ( sub_4BDAAF((ItemGen *)&v0->pInventoryItems[v15-1], (int)window_SpeakInHouse->ptr_1C) )
-    {
-      dword_F8B1E4 = 1;
-      v0->_4BE2DD(v79, (int)((char *)v77 - 1), (int)v16->ptr_1C);
-      viewparams->bRedrawGameUI = 1;
-      pRenderer->ClearZBuffer(0, 479);
-      v53 = 0;
-      v51 = 77;
-      v27 = v0;
-      v27->PlaySound((PlayerSpeech)v51, v53);
-      return;
-	}
-    v0->PlaySound(SPEECH_79, 0);
-    v56 = 0;
-    v52 = 0;
-    v50 = 0;
-    v49 = 0;
-    v48 = -1;
-    v47 = 0;
-    v46 = 0;
-//LABEL_87:
-    pAudioPlayer->PlaySound(SOUND_27, v46, v47, v48, v49, v50, v52, v56);
-    return;
-  }
-  if ( dialog_menu_id == 4 )
-  {
-    v10 = pMouse->GetCursorPos(&v62)->x - 14;
-    v79 = (v10 >> 5) + 14 * ((pMouse->GetCursorPos(&v66)->y - 17) >> 5);
-    if ( pMouse->GetCursorPos(&v58)->x > 13 )
-    {
-      if ( pMouse->GetCursorPos(&v64)->x < 462 )
-      {
-        v11 = v0->GetItemIDAtInventoryIndex((int *)&v79);
-        if ( v11 )
-        {
-          //v80 = v0->_4B8179(p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C]);
-          v80 = v0->_4B8179(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier);
-          v12 = (int)&v0->pInventoryItems[v11-1];
-          if ( !(*(char *)(v12 + 20) & 1) )
-          {
-            _this = (ItemGen *)window_SpeakInHouse->ptr_1C;
-            if ( sub_4BDAAF((ItemGen *)v12, (int)_this) )
-            {
-              if ( pParty->uNumGold >= v80 )
-              {
-                dword_F8B1E4 = 1;
-                Party::TakeGold(v80);
-                *(int *)(v12 + 20) |= 1u;
-                v0->PlaySound(SPEECH_73, 0);
-                v9 = pGlobalTXT_LocalizationStrings[569];
-                v54 = 2;
-                ShowStatusBarString(v9, v54);
-                return;
-              }
-              v13 = _this;
-              v55 = 2;
-              HousePlaySomeSound((unsigned int)v13, v55);
-              return;
-            }
-            pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-            v53 = 0;
-            v51 = 79;
-            v27 = v0;
-	        v27->PlaySound((PlayerSpeech)v51, v53);
-		    return;
-          }
-          v53 = 0;
-//LABEL_30:
-          v51 = 76;
-          v27 = v0;
-	      v27->PlaySound((PlayerSpeech)v51, v53);
-		  return;
+	case 5:
+		{
+		v1 = pMouse->GetCursorPos(&a2)->x - 14;
+		v79 = (v1 >> 5) + 14 * ((pMouse->GetCursorPos(&v70)->y - 17) >> 5);
+		if ( pMouse->GetCursorPos(&v60)->x > 13 )
+		{
+			if ( pMouse->GetCursorPos(&v72)->x < 462 )
+			{
+				v2 = v0->GetItemIDAtInventoryIndex((int *)&v79);
+				if ( v2 )
+				{
+					v3 = (int)&v0->pInventoryItems[v2-1];
+					//v4 = p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C];
+					v4 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
+
+					auto _v = (ItemGen *)&v0->pInventoryItems[v2-1];
+					v5 = _v->GetValue();
+
+					v6 = v0->_4B81C3(v5, v4);
+					v7 = (*(char *)(v3 + 20) & 2) == 0;
+					v80 = v6;
+					if ( !v7 )
+					{
+						_this = (ItemGen *)window_SpeakInHouse->ptr_1C;
+						if ( sub_4BDAAF((ItemGen *)v3, (int)_this) )
+						{
+						if ( pParty->uNumGold >= v80 )
+						{
+							dword_F8B1E4 = 1;
+							Party::TakeGold(v80);
+							v8 = *(int *)(v3 + 20);
+							LOBYTE(v8) = v8 & 0xFD;
+							*(int *)(v3 + 20) = v8 | 1;
+							v0->PlaySound(SPEECH_74, 0);
+							v9 = pGlobalTXT_LocalizationStrings[570];
+			//LABEL_25:
+							v54 = 2;
+			//LABEL_71:
+							ShowStatusBarString(v9, v54);
+							return;
+						}
+			//LABEL_26:
+						v13 = _this;
+						v55 = 2;
+			//LABEL_84:
+						HousePlaySomeSound((unsigned int)v13, v55);
+						return;
+						}
+						pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
+						v53 = 0;
+			//LABEL_28:
+						v51 = 79;
+			//LABEL_80:
+						v27 = v0;
+						v27->PlaySound((PlayerSpeech)v51, v53);
+					return;
+					}
+					v53 = 0;
+					v51 = 76;
+					v27 = v0;
+					v27->PlaySound((PlayerSpeech)v51, v53);
+					return;          
+				}
+			}
+		}
+		break;
+		}
+	case 2:
+	case 95:
+		{
+	//LABEL_49:
+		v28 = pMouse->GetCursorPos(&v59);
+		v29 = pRenderer->pActiveZBuffer[v28->x + pSRZBufferLineOffsets[pMouse->GetCursorPos(&v57)->y]] & 0xFFFF;
+		if ( !v29 )
+			return;
+		v30 = window_SpeakInHouse->ptr_1C;
+		// v31 = 9 * (v29 - 1 + 12 * (int)v30);
+		if ( dialog_menu_id == 2 )
+		{
+			v32 = (ItemGen *)&pParty->StandartItemsInShops[(int)v30][v29-1];
+			_this = (ItemGen *)&pParty->StandartItemsInShops[(int)v30][v29-1];
+		}
+		else
+		{
+			_this =&pParty->SpecialItemsInShops[(int)v30][v29-1]; //(ItemGen *)&pParty->field_C59C[v31 + 724];
+			v32 = &pParty->SpecialItemsInShops[(int)v30][v29-1];//(ItemGen *)&pParty->field_C59C[v31 + 724];
 		}
-      }
-    }
-  }
-  else
-  {
-    if ( dialog_menu_id == 5 )
-    {
-      v1 = pMouse->GetCursorPos(&a2)->x - 14;
-      v79 = (v1 >> 5) + 14 * ((pMouse->GetCursorPos(&v70)->y - 17) >> 5);
-      if ( pMouse->GetCursorPos(&v60)->x > 13 )
-      {
-        if ( pMouse->GetCursorPos(&v72)->x < 462 )
-        {
-          v2 = v0->GetItemIDAtInventoryIndex((int *)&v79);
-          if ( v2 )
-          {
-            v3 = (int)&v0->pInventoryItems[v2-1];
-            //v4 = p2DEvents_minus1__20[13 * (unsigned int)ptr_507BC0->ptr_1C];
-            v4 = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].fPriceMultiplier;
-
-            auto _v = (ItemGen *)&v0->pInventoryItems[v2-1];
-            v5 = _v->GetValue();
-
-            v6 = v0->_4B81C3(v5, v4);
-            v7 = (*(char *)(v3 + 20) & 2) == 0;
-            v80 = v6;
-            if ( !v7 )
-            {
-              _this = (ItemGen *)window_SpeakInHouse->ptr_1C;
-              if ( sub_4BDAAF((ItemGen *)v3, (int)_this) )
-              {
-                if ( pParty->uNumGold >= v80 )
-                {
-                  dword_F8B1E4 = 1;
-                  Party::TakeGold(v80);
-                  v8 = *(int *)(v3 + 20);
-                  LOBYTE(v8) = v8 & 0xFD;
-                  *(int *)(v3 + 20) = v8 | 1;
-                  v0->PlaySound(SPEECH_74, 0);
-                  v9 = pGlobalTXT_LocalizationStrings[570];
-//LABEL_25:
-                  v54 = 2;
-//LABEL_71:
-                  ShowStatusBarString(v9, v54);
-                  return;
-                }
-//LABEL_26:
-                v13 = _this;
-                v55 = 2;
-//LABEL_84:
-                HousePlaySomeSound((unsigned int)v13, v55);
-                return;
-              }
-              pAudioPlayer->PlaySound(SOUND_27, 0, 0, -1, 0, 0, 0, 0);
-              v53 = 0;
-//LABEL_28:
-              v51 = 79;
-//LABEL_80:
-              v27 = v0;
-			  v27->PlaySound((PlayerSpeech)v51, v53);
+		//v33 = p2DEvents_minus1__20[13 * (signed int)v30];
+		v33 = p2DEvents[(signed int)v30 - 1].fPriceMultiplier;
+		v34 = v32->GetValue();
+		v80 = v0->_4B8142(v34, v33);
+		LOWORD(v35) = GetAsyncKeyState(VK_CONTROL);
+		v74 = v35;
+		v36 = v0->CanSteal();
+		uNumSeconds = 0;
+		a3 = 0;
+		v73 = v36;
+		v37 = pMapStats->GetMapInfo(pCurrentMapName);
+		if ( v37 )
+			a3 = pMapStats->pInfos[v37]._steal_perm;
+		v38 = GetPartyReputation();
+		v26 = 1;
+		if ( v73 == 1 )
+		{
+			if ( (short)v74 )
+			{
+			uNumSeconds = v0->StealFromShop(v32, a3, v38, 0, &a6);
+			if ( !uNumSeconds )
+			{
+				sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, 0, a6);
+				return;
+			}
+			}
+		}
+		if ( pParty->uNumGold < v80 )
+		{
+			v24 = 2;
+			if ( uNumSeconds != 2 )
+			{
+				if ( uNumSeconds != 1 )
+				{
+					HousePlaySomeSound((unsigned int)window_SpeakInHouse->ptr_1C, v24);
+					v9 = pGlobalTXT_LocalizationStrings[155];
+					v54 = 2;
+					ShowStatusBarString(v9, v54);
+					return;
+				}
+			}
+		}
+		v39 = v0->AddItem(0xFFFFFFFFu, v32->uItemID);
+		if ( v39 )
+		{
+			v32->SetIdentified();
+			v7 = v73 == 1;
+			v40 = (int)((char *)v0 + 36 * v39);
+			memcpy((void *)(v40 + 496), v32, 0x24u);
+			if ( v7 )
+			{
+				if ( (short)v74 )
+				{
+					v41 = uNumSeconds;
+					if ( uNumSeconds == 1 || uNumSeconds == 2 )
+					{
+						*(char *)(v40 + 517) |= 1u;
+						sub_4B1447_party_fine((int)window_SpeakInHouse->ptr_1C, v41, a6);
+						viewparams->bRedrawGameUI = v26;
+						_this->Reset();
+						pRenderer->ClearZBuffer(0, 479);
+						v27 = v77;
+						v53 = 0;
+						v51 = SPEECH_75;
+						v27->PlaySound((PlayerSpeech)v51, v53);
+						return;
+					}
+				}
+			}
+	//LABEL_42:
+			dword_F8B1E4 = v26;
+			Party::TakeGold(v80);
+	//LABEL_43:
+			viewparams->bRedrawGameUI = v26;
+			_this->Reset();
+			pRenderer->ClearZBuffer(0, 479);
+			v27 = v77;
+			v53 = 0;
+			v51 = SPEECH_75;
+	//LABEL_81:
+			v27->PlaySound((PlayerSpeech)v51, v53);
 			return;
-            }
-            v53 = 0;
-            v51 = 76;
-            v27 = v0;
-	        v27->PlaySound((PlayerSpeech)v51, v53);
-		    return;          
-		  }
-        }
-      }
-    }
+		}
+		v0->PlaySound(SPEECH_NoRoom, 0);
+		v54 = 2;
+		v9 = pGlobalTXT_LocalizationStrings[563];   // "Pack is Full!"
+		ShowStatusBarString(v9, v54);
+		break;
+		}
+
+	default:
+		{
+		if( dialog_menu_id >= 36 && dialog_menu_id <= 72 )
+		{
+			v42 = dialog_menu_id - 36;
+			//v43 = (signed __int64)(*(float *)&p2DEvents_minus1__24[13 * (unsigned int)ptr_507BC0->ptr_1C] * 500.0);
+			v43 = (signed __int64)(p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].flt_24 * 500.0);
+			v44 = v43 * (100 - v0->GetMerchant()) / 100;
+			if ( v44 < v43 / 3 )
+			v44 = v43 / 3;
+			if ( byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v42] )
+			{
+				pSkill = &v0->pActiveSkills[v42];
+				if ( !*pSkill )
+				{
+					if ( pParty->uNumGold < v44 )
+					{
+						ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2u);// "You don't have enough gold"
+						v13 = window_SpeakInHouse->ptr_1C;
+						if ( in_current_building_type == BildingType_Training )
+							v55 = 4;
+						else
+							v55 = 2;
+						HousePlaySomeSound((unsigned int)v13, v55);
+						return;
+					}
+					Party::TakeGold(v44);
+					v53 = 0;
+					dword_F8B1E4 = 1;
+					*pSkill = 1;
+					v51 = 78;
+					v27 = v0;
+					v27->PlaySound((PlayerSpeech)v51, v53);
+					return;
+				}
+			}
+		}
+		break;
+		}
   }
 }
 
@@ -10443,10 +10904,24 @@
   assert(sizeof(stru320) == 0x3FC);
   assert(sizeof(TravelInfo) == 0x20);
   assert(sizeof(stru336) == 0x798);
+  assert(sizeof(Vec3_short_) == 6);
+  assert(sizeof(BLVFace) == 96);
+  assert(sizeof(BLVFaceExtra) == 36);
+  assert(sizeof(BLVSector) == 116);
+  assert(sizeof(LevelDecoration) == 32);
+  assert(sizeof(BLVLightMM7) == 16);
+  assert(sizeof(BSPNode) == 8);
+  assert(sizeof(SpawnPointMM7) == 24);
+  assert(sizeof(DDM_DLV_Header) == 40);
+  assert(sizeof(Actor) == 836);
+  assert(sizeof(SpriteObject) == 112);
+  assert(sizeof(Chest) == 5324);
+  assert(sizeof(stru123) == 0xC8);
+  assert(sizeof(BLVMapOutline) == 12);
 }
 
 bool new_sky = false;
-bool change_seasons = true;
+bool change_seasons = false;
 
 //----- (00462C94) --------------------------------------------------------
 bool MM_Main(const wchar_t *pCmdLine)
--- a/mm7_3.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/mm7_3.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -138,7 +138,7 @@
     {
       v11 = v9->pFloors[v10];
       v12 = &pIndoor->pFaces[v11];
-      if ( v12->TwoSided()
+      if ( v12->Portal()
         || stru_721530.sMaxX > v12->pBounding.x2
         || stru_721530.sMinX < v12->pBounding.x1
         || stru_721530.sMaxY > v12->pBounding.y2
@@ -3795,7 +3795,7 @@
         v6 = (unsigned __int64)(a2->z * (signed __int64)v4->pFacePlane_old.vNormal.z) >> 16,
         v7 = v5 + v6 + a4b,
         (v16 = v5 + v6 + a4b) == 0)
-    || v7 > 0 && !v4->TwoSided())
+    || v7 > 0 && !v4->Portal())
     return 0;
   v8 = v4->pFacePlane_old.vNormal.z * a1->z;
   v9 = -(v4->pFacePlane_old.dist + v8 + a1->y * v4->pFacePlane_old.vNormal.y + a1->x * v4->pFacePlane_old.vNormal.x);
@@ -3855,7 +3855,7 @@
         v14 = v10 + v12 + v11,
         v22 = v10 + v12 + v11,
         v13)
-    || v14 > 0 && !a2->TwoSided())
+    || v14 > 0 && !a2->Portal())
     return 0;
   v15 = a4 * a2->pFacePlane_old.vNormal.y;
   v16 = -(a2->pFacePlane_old.dist + v15 + a3 * a2->pFacePlane_old.vNormal.x + a5 * a2->pFacePlane_old.vNormal.z);
@@ -11144,24 +11144,23 @@
 //----- (0043F953) --------------------------------------------------------
 void PrepareBspRenderList_BLV()
 {
-  pBspRenderer->uNumFaceIDs = 0;
+  pBspRenderer->num_faces = 0;
 
   if (pBLVRenderParams->uPartySectorID)
   {
-    pBspRenderer->pSectors[0].uSectorID = pBLVRenderParams->uPartySectorID;
-    pBspRenderer->pSectors[0].uViewportW = pBLVRenderParams->uViewportW;
-    pBspRenderer->pSectors[0].uViewportZ = pBLVRenderParams->uViewportZ;
-    pBspRenderer->pSectors[0].uViewportY = pBLVRenderParams->uViewportY;
-    pBspRenderer->pSectors[0].uViewportX = pBLVRenderParams->uViewportX;
-    pBspRenderer->pSectors[0].field_C._43F9E1(
-      pBLVRenderParams->uViewportX,
-      pBLVRenderParams->uViewportY,
-      pBLVRenderParams->uViewportZ,
-      pBLVRenderParams->uViewportW);
-    pBspRenderer->pSectors[0].uFaceID = -1;
-    pBspRenderer->pSectors[0].std__vector_0007A8 = -1;
-    pBspRenderer->pNumSectors = 1;
-    sub_440639(0);
+    pBspRenderer->nodes[0].uSectorID = pBLVRenderParams->uPartySectorID;
+    pBspRenderer->nodes[0].uViewportW = pBLVRenderParams->uViewportW;
+    pBspRenderer->nodes[0].uViewportZ = pBLVRenderParams->uViewportZ;
+    pBspRenderer->nodes[0].uViewportY = pBLVRenderParams->uViewportY;
+    pBspRenderer->nodes[0].uViewportX = pBLVRenderParams->uViewportX;
+    pBspRenderer->nodes[0].field_C._43F9E1(pBLVRenderParams->uViewportX,
+                                           pBLVRenderParams->uViewportY,
+                                           pBLVRenderParams->uViewportZ,
+                                           pBLVRenderParams->uViewportW);
+    pBspRenderer->nodes[0].uFaceID = -1;
+    pBspRenderer->nodes[0].std__vector_0007A8 = -1;
+    pBspRenderer->num_nodes = 1;
+    AddBspNodeToRenderList(0);
   }
 
   pBspRenderer->MakeVisibleSectorList();
@@ -11177,8 +11176,8 @@
   {
     if ( i < y || i > w )
     {
+      array_18[i] = 640;
       array_3D8[i] = -1;
-      array_18[i] = 640;
     }
     else
     {
@@ -11516,36 +11515,36 @@
 
 
 //----- (00440639) --------------------------------------------------------
-void __fastcall sub_440639(int a1)
-{
-  int v1; // ebx@1
+void AddBspNodeToRenderList(unsigned int node_id)
+{
+  //int v1; // ebx@1
   signed int v2; // edi@1
   BLVSector *v3; // esi@1
 
-  v1 = a1;
+  //v1 = sector_id;
   v2 = 0;
-  v3 = &pIndoor->pSectors[pBspRenderer->pSectors[a1].uSectorID];
+  v3 = &pIndoor->pSectors[pBspRenderer->nodes[node_id].uSectorID];
   if ( pRenderer->pRenderD3D )
   {
     for (uint i = 0; i < v3->uNumNonBSPFaces; ++i)
       //Log::Warning(L"Non-BSP face: %X", v3->pFaceIDs[v2]);
-      pBspRenderer->AddFaceToRenderList_d3d(v1, v3->pFaceIDs[i]);
+      pBspRenderer->AddFaceToRenderList_d3d(node_id, v3->pFaceIDs[i]);
   }
   else
   {
     if ( v3->uNumNonBSPFaces > 0 )
     {
       do
-        pBspRenderer->AddFaceToRenderList_sw(v1, v3->pFaceIDs[v2++]);
+        pBspRenderer->AddFaceToRenderList_sw(node_id, v3->pFaceIDs[v2++]);
       while ( v2 < v3->uNumNonBSPFaces );
     }
   }
   if ( v3->field_0 & 0x10 )
-    sub_4406BC(v1, v3->uFirstBSPNode);
+    sub_4406BC(node_id, v3->uFirstBSPNode);
 }
 
 //----- (004406BC) --------------------------------------------------------
-void __fastcall sub_4406BC(int a1, unsigned int uFirstNode)
+void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode)
 {
   BLVSector *v2; // esi@2
   BSPNode *v3; // edi@2
@@ -11555,14 +11554,14 @@
   int v7; // ebp@10
   int v8; // ebx@10
   __int16 v9; // di@18
-  int v10; // [sp+10h] [bp-Ch]@1
+  //int v10; // [sp+10h] [bp-Ch]@1
   bool v11; // [sp+14h] [bp-8h]@5
   BspRenderer_stru0 *v12; // [sp+18h] [bp-4h]@1
 
   //Log::Warning(L"sub_4406BC(%u, %u)", a1, uFirstNode);
 
-  v10 = a1;
-  v12 = &pBspRenderer->pSectors[a1];
+  //v10 = a1;
+  v12 = &pBspRenderer->nodes[node_id];
   while ( 1 )
   {
     v2 = &pIndoor->pSectors[v12->uSectorID];
@@ -11572,7 +11571,7 @@
        + pBLVRenderParams->vPartyPos.x * v4->pFacePlane_old.vNormal.x
        + pBLVRenderParams->vPartyPos.y * v4->pFacePlane_old.vNormal.y
        + pBLVRenderParams->vPartyPos.z * v4->pFacePlane_old.vNormal.z;
-    if (v4->TwoSided() && v4->uSectorID != v12->uSectorID )
+    if (v4->Portal() && v4->uSectorID != v12->uSectorID )
       v5 = -v5;
     v11 = v5 > 0;
     if ( v5 <= 0 )
@@ -11580,7 +11579,7 @@
     else
       v6 = v3->uBack;
     if ( v6 != -1 )
-      sub_4406BC(v10, v6);
+      sub_4406BC(node_id, v6);
     v7 = v3->uCoplanarOffset;
     v8 = v7 + v3->uCoplanarSize;
 
@@ -11589,12 +11588,12 @@
     if ( pRenderer->pRenderD3D )
     {
       while ( v7 < v8 )
-        pBspRenderer->AddFaceToRenderList_d3d(v10, v2->pFaceIDs[v7++]);
+        pBspRenderer->AddFaceToRenderList_d3d(node_id, v2->pFaceIDs[v7++]);
     }
     else
     {
       while ( v7 < v8 )
-        pBspRenderer->AddFaceToRenderList_sw(v10, v2->pFaceIDs[v7++]);
+        pBspRenderer->AddFaceToRenderList_sw(node_id, v2->pFaceIDs[v7++]);
     }
     v9 = v11 ? v3->uFront : v3->uBack;
     if ( v9 == -1 )
@@ -11883,10 +11882,10 @@
   signed int v27; // eax@37
   unsigned __int16 *v28; // ecx@37
   signed int v29; // edi@40
-  signed int v33; // ebx@50
-  unsigned int v34; // eax@50
-  signed int v35; // ecx@50
-  unsigned __int16 v36; // di@66
+  //signed int v33; // ebx@50
+  //unsigned int v34; // eax@50
+  //signed int v35; // ecx@50
+  //unsigned __int16 v36; // di@66
   int v37; // edi@72
   int v38; // ebx@72
   __int16 v39; // ax@87
@@ -11906,7 +11905,7 @@
   unsigned int v54; // [sp-Ch] [bp-60h]@100
   unsigned int v55; // [sp-8h] [bp-5Ch]@77
   unsigned int v56; // [sp-8h] [bp-5Ch]@100
-  signed int v57; // [sp-4h] [bp-58h]@54
+  //signed int v57; // [sp-4h] [bp-58h]@54
   unsigned __int16 v58; // [sp-4h] [bp-58h]@77
   unsigned __int16 v59; // [sp-4h] [bp-58h]@100
   unsigned __int16 v60; // [sp+10h] [bp-44h]@66
@@ -12115,63 +12114,16 @@
   }
 
 
-//_draw_party_arrow:
-  v33 = 0;
-  v34 = pParty->sRotationY & stru_5C6E00->uDoublePiMask;
-  v35 = 0;
-  if ( (signed int)(pParty->sRotationY & stru_5C6E00->uDoublePiMask) < 128 )
-    goto LABEL_66;
-  if ( (signed int)v34 <= 384 )
-  {
-    v35 = 1;
-    goto LABEL_66;
-  }
-  if ( (signed int)v34 >= 640 )
-  {
-    if ( (signed int)v34 > 896 )
-    {
-      if ( (signed int)v34 >= 1152 )
-      {
-        if ( (signed int)v34 > 1408 )
-        {
-          if ( (signed int)v34 >= 1664 )
-          {
-            if ( (signed int)v34 > 1920 )
-              goto LABEL_66;
-            v57 = 7;
-          }
-          else
-          {
-            v57 = 6;
-          }
-        }
-        else
-        {
-          v57 = 5;
-        }
-      }
-      else
-      {
-        v57 = 4;
-      }
-    }
-    else
-    {
-      v57 = 3;
-    }
-  }
-  else
-  {
-    v57 = 2;
-  }
-  v35 = v57;
-LABEL_66:
-  pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3,
-    (Texture *)(pTextureIDs_pMapDirs[v35] != -1 ? &pIcons_LOD->pTextures[pTextureIDs_pMapDirs[v35]] : 0));
-  v36 = 255;
+  assert(pParty->sRotationY >= 0);
+  float angle = (pParty->sRotationY % 2048) / 2048.0f;
+  const float two_pi = 2.0f * 3.14159f;
+
+  uint arrow_idx = floorf(0.5f + 7 * angle);
+  pRenderer->DrawTextureTransparent(uCenterX - 3, uCenterY - 3, pIcons_LOD->GetTexture(pTextureIDs_pMapDirs[arrow_idx]));
+
   flagsb = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0xFFu);
   v60 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0, 0);
-  if ( bWizardEyeActive = true)
+  if (bWizardEyeActive)
   {
     uZe = 0;
     //for (uint i = 0; i < uNumSpriteObjects; ++i)
@@ -12217,8 +12169,6 @@
         a2c += 112;
         if ( uZe >= (signed int)uNumSpriteObjects )
         {
-          v36 = 255;
-          v33 = 0;
           goto LABEL_85;
         }
       }
@@ -12230,11 +12180,11 @@
       goto LABEL_82;
     }
 LABEL_85:
-    v63 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(v36, 0, v33);
-    v61 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, v36, v33);
-    v65 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(v36, v36, v33);
-    uZf = v33;
-    if ( (signed int)uNumActors > v33 )
+    v63 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 0, 0);
+    v61 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 255, 0);
+    v65 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 0);
+    uZf = 0;
+    if ( (signed int)uNumActors > 0 )
     {
       flagsc = pActors;//[0].uAIState;
       do
@@ -12288,13 +12238,11 @@
         ++flagsc;
       }
       while ( uZf < (signed int)uNumActors );
-      v36 = 255;
-      v33 = 0;
-    }
-  }
-  flagsd = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(v36, v36, v36);
-  uZg = v33;
-  if ( (signed int)uNumLevelDecorations > v33 )
+    }
+  }
+  flagsd = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 255);
+  uZg = 0;
+  if ( (signed int)uNumLevelDecorations > 0 )
   {
     v45 = (char *)&pLevelDecorations[0].vPosition;
     lPitchb = (char *)&pLevelDecorations[0].vPosition;
@@ -12331,13 +12279,12 @@
       lPitchb = v45;
     }
     while ( uZg < (signed int)uNumLevelDecorations );
-    v33 = 0;
-  }
-  pRenderer->DrawTextureTransparent(0x1D4u, v33, (Texture *)(dword_5079D8 != -1 ? &pIcons_LOD->pTextures[dword_5079D8] : 0));
+  }
+  pRenderer->DrawTextureTransparent(0x1D4u, 0, (Texture *)(dword_5079D8 != -1 ? &pIcons_LOD->pTextures[dword_5079D8] : 0));
   uZooma = (double)pParty->sRotationY * 0.1171875;
   //v50 = uZooma + 6.7553994e15;
-  pRenderer->Clip(0x21Du, v33, 0x237u, 0x1E0u);
-  pRenderer->DrawTextureIndexed(floorf(uZooma + 0.5f) + 285, 0x88u, (Texture *)(dword_5079B4 != -1 ? &pIcons_LOD->pTextures[dword_5079B4] : 0));
+  pRenderer->Clip(541, 0, 567, 480);
+  pRenderer->DrawTextureIndexed(floorf(uZooma + 0.5f) + 285, 136, (Texture *)(dword_5079B4 != -1 ? &pIcons_LOD->pTextures[dword_5079B4] : 0));
   pRenderer->ResetClip();
 }
 
--- a/mm7_4.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/mm7_4.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -778,7 +778,7 @@
   BSPModel *v6; // edi@3
   ODMFace *v7; // esi@10
   unsigned __int8 v8; // al@10
-  unsigned __int16 *v9; // eax@18
+  signed __int16 *v9; // eax@18
   int v10; // edx@19
   int v11; // ecx@21
   int v12; // ecx@23
--- a/mm7_5.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/mm7_5.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -9251,25 +9251,24 @@
   int v6; // ebx@3
 
   uNumVisibleNotEmptySectors = 0;
-  for (uint i = 0; i < pNumSectors; ++i)
-  {
-      v6 = 0;
+  for (uint i = 0; i < num_nodes; ++i)
+  {
       if (!uNumVisibleNotEmptySectors)
       {
-        pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = pSectors[i].uSectorID;
-      }
-      else
-      {
-        while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] != pSectors[i].uSectorID )
+        pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
+        continue;
+      }
+      
+      v6 = 0;
+        while (pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[v6] != nodes[i].uSectorID )
         {
           ++v6;
           if ( v6 >= uNumVisibleNotEmptySectors)
           {
-            pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = pSectors[i].uSectorID;
-            continue;
-          }
-        }
-      }
+            pVisibleSectorIDs_toDrawDecorsActorsEtcFrom[uNumVisibleNotEmptySectors++] = nodes[i].uSectorID;
+          }
+        }
+
   }
 }
 
@@ -11566,7 +11565,7 @@
             ++sDepthb )
       {
         v62 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v60->pWalls + v61))[sDepthb]];
-        if ( v62->TwoSided()
+        if ( v62->Portal()
           || v119 > v62->pBounding.x2
           || v123 < v62->pBounding.x1
           || v127 > v62->pBounding.y2
@@ -11732,7 +11731,7 @@
     while ( 1 )
     {
       v90 = &pIndoor->pFaces[(*(unsigned __int16 **)((char *)&v88->pWalls + v89))[v162]];
-      if ( v90->TwoSided()
+      if ( v90->Portal()
         || v120 > v90->pBounding.x2
         || v124 < v90->pBounding.x1
         || v128 > v90->pBounding.y2
--- a/mm7_data.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/mm7_data.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -1718,7 +1718,7 @@
 int dword_50B918[777];
 int _50B924_view_transformed_xs[45];
 //int unk_50B9D4[777]; // idb
-int dword_50B9D8_ys[777];
+int _50B9D8_screen_space_y[777];
 int dword_50B9E4[777];
 //int dword_50B9E0_ys[777]; // idb
 //int dword_50B9EC[777]; // idb
@@ -1729,7 +1729,7 @@
 int dword_50B9FC_ys[3 + 45];
 int dword_50BA08_ys[48]; // idb
 //int dword_50BAC4[777]; // weak
-int dword_50BAC8[777]; // idb
+int _50BAC8_screen_space_x[777]; // idb
 //int dword_50BAD0[777]; // weak
 int dword_50BAD4[777]; // weak
 //int dword_50BADC_xs[777]; // weak
--- a/mm7_data.h	Fri Mar 15 18:28:37 2013 +0600
+++ b/mm7_data.h	Fri Mar 15 18:29:06 2013 +0600
@@ -1232,7 +1232,7 @@
 extern int dword_50B918[];
 extern int _50B924_view_transformed_xs[];
 //extern int unk_50B9D4[]; // idb
-extern int dword_50B9D8_ys[];
+extern int _50B9D8_screen_space_y[];
 extern int dword_50B9E4[];
 //extern int dword_50B9E0_ys[]; // idb
 //extern int dword_50B9EC[]; // idb
@@ -1243,7 +1243,7 @@
 extern int dword_50B9FC_ys[];
 extern int dword_50BA08_ys[]; // idb
 //extern int dword_50BAC4[]; // weak
-extern int dword_50BAC8[]; // idb
+extern int _50BAC8_screen_space_x[]; // idb
 //extern int dword_50BAD0[]; // weak
 extern int dword_50BAD4[]; // weak
 //extern int dword_50BADC_xs[]; // weak
@@ -1988,8 +1988,8 @@
 void __fastcall PrepareDecorationsRenderList_BLV(unsigned int uDecorationID, unsigned int uSectorID);
 void PrepareActorRenderList_BLV();
 void PrepareItemsRenderList_BLV();
-void __fastcall sub_440639(int a1);
-void __fastcall sub_4406BC(int a1, unsigned int uFirstNode); // idb
+void AddBspNodeToRenderList(unsigned int node_id);
+void __fastcall sub_4406BC(unsigned int node_id, unsigned int uFirstNode); // idb
 void __fastcall sub_440BED(struct IndoorLocation_drawstru *_this);
 bool sub_44100D();
 void GameUI_DrawTorchlightAndWizardEye();
--- a/stru10.cpp	Fri Mar 15 18:28:37 2013 +0600
+++ b/stru10.cpp	Fri Mar 15 18:29:06 2013 +0600
@@ -1,3 +1,5 @@
+#include <assert.h>
+
 #include "stru10.h"
 #include "Render.h"
 #include "Indoor.h"
@@ -440,7 +442,7 @@
     for (uint i = 0; i < pFace->uNumVertices; ++i)
     {
       v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pXInterceptDisplacements[i];
-      v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pZInterceptDisplacements[i];
+      v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].z + pFace->pZInterceptDisplacements[i];
       v46[i].c = i;
     }
   }
@@ -448,8 +450,8 @@
   {
     for (uint i = 0; i < pFace->uNumVertices; ++i)
     {
-      v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].x + pFace->pYInterceptDisplacements[i];
-      v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pZInterceptDisplacements[i];
+      v46[i].x = pIndoor->pVertices[pFace->pVertexIDs[i]].y + pFace->pYInterceptDisplacements[i];
+      v46[i].y = pIndoor->pVertices[pFace->pVertexIDs[i]].z + pFace->pZInterceptDisplacements[i];
       v46[i].c = i;
     }
   }
@@ -583,6 +585,7 @@
     var_28 = 1;
     var_24 = 0;
   }
+  else assert(false);
 
 
   float arg_4;
@@ -595,6 +598,25 @@
   //__asm { fld     0.5 }
   if (pFace->uAttributes & 0x0100)
   {
+    /*arg_4 = ([2].x + [0].x) * flt_4D84F0
+    var_18 = ([3].y + [1].y) * flt_4D84F0
+
+      fld     dword ptr [ecx+94h]
+      fadd    dword ptr [ecx+34h]
+      fmul    st, st(1)
+      fstp    [ebp+var_18]
+      fld     dword ptr [ecx+68h]
+      fadd    dword ptr [ecx+8]
+      fmul    st, st(1)
+      fstp    [ebp+var_4]
+      fld     [ebp+arg4]
+      fsub    dword ptr [ecx]
+      fstp    [ebp+a3]
+      fld     [ebp+var_18]
+      fsub    dword ptr [ecx+34h]
+      fstp    [ebp+var_8]*/
+
+
     arg_4 = (pFaceBounding[0].vWorldPosition.x + pFaceBounding[2].vWorldPosition.x) / 2;
     var_18 = (pFaceBounding[3].vWorldPosition.y + pFaceBounding[1].vWorldPosition.y) / 2;
     var_4 = (pFaceBounding[0].vWorldPosition.z + pFaceBounding[2].vWorldPosition.z) / 2;
@@ -631,7 +653,7 @@
   }
 
 
-  if ( byte_4D864C && pGame->uFlags & 8 )
+  if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
   {
     RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
     v26.vWorldPosition.x = arg_4;
@@ -674,7 +696,7 @@
 
   if ( byte_4D864C )
   {
-      if ( pGame->uFlags & 8 )
+      if ( pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
       {
         RenderVertexSoft v25; // [sp+10h] [bp-90h]@20
         RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
@@ -705,7 +727,7 @@
     memcpy(arg0 + 3, &v25, sizeof(RenderVertexSoft));
   }
 
-    if ( byte_4D864C && pGame->uFlags & 8 )
+    if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
     {
       RenderVertexSoft v26; // [sp+40h] [bp-60h]@20
       if ( !LOBYTE(field_4) )
@@ -741,27 +763,27 @@
 //----- (0049C5DA) --------------------------------------------------------
 char stru10::_49C5DA(BLVFace *a2, RenderVertexSoft *a3, int *a4, IndoorCameraD3D_Vec4 *a5, RenderVertexSoft *a6)
 {
-  stru10 *v6; // edi@1
-  float *v7; // eax@1
-  signed int v8; // ecx@1
-  IndoorCameraD3D *pIndoorCamera; // esi@3
+  //stru10 *v6; // edi@1
+  //char *v7; // eax@1
+  //signed int v8; // ecx@1
+  //IndoorCameraD3D *v9; // esi@3
   char result; // al@6
   RenderVertexSoft a4a[4]; // [sp+Ch] [bp-C0h]@1
 
-  v6 = this;
-  v7 = &a4a[0].flt_2C;
+  /*v6 = this;
+  v7 = (char *)&a4a[0].flt_2C;
   v8 = 4;
   do
   {
-    *v7 = 0.0;
-    v7 += 12;
+    *(float *)v7 = 0.0;
+    v7 += 48;
     --v8;
   }
   while ( v8 );
-  //pIndoorCamera = pGame->pIndoorCameraD3D;
+  v9 = pGame->pIndoorCameraD3D;*/
   _49CE9E(a2, a3, *a4, a4a);
-  if ( byte_4D864C && pGame->uFlags & 8 )
-    pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4, 0xFF1E1Eu, 0.00009999999747378752);
+  if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
+    pGame->pIndoorCameraD3D->debug_outline_sw(a4a, 4u, 0xFF1E1Eu, 0.000099999997);
   result = _49C9E3(a2, a4a, 4u, a6);
   if ( result )
     result = _49C720(a6, a5);
@@ -775,7 +797,7 @@
   RenderVertexSoft pBounding[4]; // [sp+Ch] [bp-C0h]@1
 
   CalcPolygonBoundingBox(pFace, pBounding);
-  if ( byte_4D864C && pGame->uFlags & 8 )
+  if ( byte_4D864C && pGame->uFlags & GAME_FLAGS_1_DRAW_BLV_DEBUGS)
     pGame->pIndoorCameraD3D->debug_outline_sw(pBounding, 4, 0xFF1E1E, 0.000099999997);
   if (_49C9E3(pFace, pBounding, 4, pArrayOf4))
     return _49C720(pArrayOf4, a3);
@@ -877,9 +899,9 @@
 //----- (0049C8DC) --------------------------------------------------------
 bool stru10::_49C8DC(RenderVertexSoft *arg0, Vec3_float_ *a2, float *a3)
 {
-  double v4; // st7@1
-  double v5; // st6@1
-  double v6; // st5@1
+  //double v4; // st7@1
+  //double v5; // st6@1
+  //double v6; // st5@1
   Vec3_float_ *result; // eax@1
   __int16 v8; // fps@3
   char v9; // c0@3
@@ -890,31 +912,33 @@
   double v14; // st6@5
   Vec3_float_ v1; // [sp+8h] [bp-3Ch]@1
   Vec3_float_ v2; // [sp+14h] [bp-30h]@1
-  float v17; // [sp+24h] [bp-20h]@1
-  float v18; // [sp+28h] [bp-1Ch]@1
-  float v19; // [sp+2Ch] [bp-18h]@1
-  float v20; // [sp+30h] [bp-14h]@1
-  float v21; // [sp+34h] [bp-10h]@1
+  //float v17; // [sp+24h] [bp-20h]@1
+  //float v18; // [sp+28h] [bp-1Ch]@1
+  //float v19; // [sp+2Ch] [bp-18h]@1
+  //float v20; // [sp+30h] [bp-14h]@1
+  //float v21; // [sp+34h] [bp-10h]@1
   Vec3_float_ a1; // [sp+38h] [bp-Ch]@1
 
-  v19 = arg0->vWorldPosition.x;
-  v20 = arg0->vWorldPosition.y;
-  v21 = arg0->vWorldPosition.z;
-  v4 = arg0[1].vWorldPosition.x;
-  v5 = arg0[1].vWorldPosition.y;
-  v2.z = arg0[1].vWorldPosition.z;
-  v6 = arg0[2].vWorldPosition.x;
-  v17 = arg0[2].vWorldPosition.y;
-  v18 = arg0[2].vWorldPosition.z;
-  a1.x = v4 - v19;
-  a1.y = v5 - v20;
-  a1.z = v2.z - v21;
-  LODWORD(v1.x) = (int)a1.x;
-  v1.y = a1.y;
-  v1.z = a1.z;
-  a1.x = v6 - v4;
-  a1.y = v17 - v5;
-  a1.z = v18 - v2.z;
+  //v19 = arg0->vWorldPosition.x;
+  //v20 = arg0->vWorldPosition.y;
+  //v21 = arg0->vWorldPosition.z;
+  //v4 = arg0[1].vWorldPosition.x;
+  //v5 = arg0[1].vWorldPosition.y;
+  //v2.z = arg0[1].vWorldPosition.z;
+  //v6 = arg0[2].vWorldPosition.x;
+  //v17 = arg0[2].vWorldPosition.y;
+  //v18 = arg0[2].vWorldPosition.z;
+  //a1.x = v4 - v19;
+  //a1.y = v5 - v20;
+  //a1.z = v2.z - v21;
+  v1.x = arg0[1].vWorldPosition.x - arg0[0].vWorldPosition.x;
+  v1.y = arg0[1].vWorldPosition.y - arg0[0].vWorldPosition.y;
+  v1.z = arg0[1].vWorldPosition.z - arg0[0].vWorldPosition.z;
+
+  a1.x = arg0[2].vWorldPosition.x - arg0[1].vWorldPosition.x;
+  a1.y = arg0[2].vWorldPosition.y - arg0[1].vWorldPosition.y;
+  a1.z = arg0[2].vWorldPosition.z - arg0[1].vWorldPosition.z;
+
   result = Vec3_float_::Cross(&v1, &v2, a1.x, a1.y, a1.z);
   a1.x = result->x;
   a1.y = result->y;
@@ -926,12 +950,12 @@
     a1.Normalize();
     v12 = a1.y;
     a2->x = a1.x;
-    v13 = v21 * a1.z;
-    v14 = v20 * a1.y;
+    v13 = arg0[0].vWorldPosition.z * a1.z;
+    v14 = arg0[0].vWorldPosition.y * a1.y;
     a2->y = v12;
     a2->z = a1.z;
     result = (Vec3_float_ *)a3;
-    *a3 = -(v13 + v14 + v19 * a1.x);
+    *a3 = -(v13 + v14 + arg0[0].vWorldPosition.x * a1.x);
     return true;
   }
   return false;