diff mm7_3.cpp @ 157:8e0e2991f9d1

Слияние
author Ritor1
date Tue, 12 Feb 2013 18:16:34 +0600
parents c49af6426e37 86a2637ba125
children 933e2655c33d a0e7ad5425d4
line wrap: on
line diff
--- a/mm7_3.cpp	Tue Feb 12 18:16:18 2013 +0600
+++ b/mm7_3.cpp	Tue Feb 12 18:16:34 2013 +0600
@@ -959,7 +959,7 @@
   signed int v60; // eax@107
   int v61; // eax@124
   Vec3_int_ v62; // [sp+Ch] [bp-44h]@42
-  char v63; // [sp+18h] [bp-38h]@64
+  int v63; // [sp+18h] [bp-38h]@64
   int v64; // [sp+1Ch] [bp-34h]@64
   int v65; // [sp+20h] [bp-30h]@2
   int v66; // [sp+24h] [bp-2Ch]@2
@@ -995,7 +995,7 @@
     v74 = v4;
     if ( !v0->CanAct() )
       v74 = 0;
-    v70 = GetTerrainHeightsAroundParty(v0->vPosition.x, v0->vPosition.y);
+    v70 = IsTerrainSlopeTooHigh(v0->vPosition.x, v0->vPosition.y);
     v5 = sub_46D49E_prolly_get_world_y_under_party(
            v0->vPosition.x,
            v0->vPosition.y,
@@ -1088,7 +1088,7 @@
         v18 = v0->vPosition.y;
         v19 = v0->vPosition.x;
         v0->vPosition.z = v7;
-        _46DCC8_get_gravity_direction_outdoor(v19, v18, &v62);
+        ODM_GetTerrainNormalAt(v19, v18, &v62);
         v20 = GetGravityStrength();
         v21 = v62.y;
         v22 = v62.z;
@@ -1337,8 +1337,8 @@
       v70 = v0->vVelocity.z;
       v70 = (unsigned __int64)(v71 * (signed __int64)(signed int)v70) >> 16;
       ++v69;
-      v54 = __OFSUB__(v69, 100);
-      v10 = ((v69 - 100) & 0x80000000u) != 0;
+      v54 = v69 < 100;
+      v10 = (v69 - 100) < 0;
       v0->vVelocity.z = v70;
       if ( !(v10 ^ v54) )
         break;
@@ -1483,11 +1483,11 @@
       {
         _46E44E_collide_against_faces_and_portals(0);
         _46E0B2_collide_against_decorations();
-        if ( (v1->field_58 & 7) != 4 )
+        if ( (v1->field_58 & 7) != OBJECT_Player)
           _46EF01_collision_chech_player(1);
         v13 = v1->field_58;
         v42 = v8;
-        if ( (v13 & 7) == 3 )
+        if ( (v13 & 7) == OBJECT_Actor)
         {
           if ( (signed int)uNumActors > v8 )
           {
@@ -1575,7 +1575,7 @@
       if ( v2->uFlags & 0x40 && !_46BFFA_check_object_intercept(uLayingItemID_, stru_721530.uFaceID) )
         return;
       v15 = (signed int)stru_721530.uFaceID >> 3;
-      if ( (stru_721530.uFaceID & 7) == 5 )
+      if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
       {
         v40 = sub_452A9E(v1->vVelocity.x * v1->vVelocity.x + v1->vVelocity.y * v1->vVelocity.y);
         v23 = stru_5C6E00->Atan2(
@@ -1593,7 +1593,7 @@
       }
       else
       {
-        if ( (stru_721530.uFaceID & 7) != 6 )
+        if ( (stru_721530.uFaceID & 7) != OBJECT_BModel)
           goto LABEL_64;
         stru_721530.field_84 = (signed int)stru_721530.uFaceID >> 3;
         v16 = &pIndoor->pFaces[v15];
@@ -1826,7 +1826,7 @@
   v1 = &pLayingItems[uLayingItemID];
   v58 = 0;
   v2 = &pObjectList->pObjects[v1->uObjectDescID];
-  v57 = GetTerrainHeightsAroundParty(v1->vPosition.x, v1->vPosition.y);
+  v57 = IsTerrainSlopeTooHigh(v1->vPosition.x, v1->vPosition.y);
   v3 = v1->vPosition.y;
   v4 = v1->vPosition.x;
   v5 = v2->uHeight;
@@ -1864,7 +1864,7 @@
       v11 = v1->vPosition.y;
       v12 = v1->vPosition.x;
       v1->vPosition.z = v8;
-      _46DCC8_get_gravity_direction_outdoor(v12, v11, &v51);
+      ODM_GetTerrainNormalAt(v12, v11, &v51);
       v1->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength();
       v56 = abs(v51.y * v1->vVelocity.y + v51.z * v1->vVelocity.z + v51.x * v1->vVelocity.x) >> 16;
       v60 = (Actor *)((unsigned __int64)(v56 * (signed __int64)v51.x) >> 16);
@@ -1987,9 +1987,9 @@
       v58 = v16;
       v18 = WorldPosToGridCellX(v17);
       _46E26D_collide_against_sprites(v18, v58);
-      if ( (v1->field_58 & 7) != 4 )
+      if ( (v1->field_58 & 7) != OBJECT_Player)
         _46EF01_collision_chech_player(0);
-      if ( (v1->field_58 & 7) == 3 )
+      if ( (v1->field_58 & 7) == OBJECT_Actor)
       {
         v19 = v1->field_58 >> 3;
         if ( v19 >= 0 )
@@ -2094,9 +2094,9 @@
           return;
       }
       v30 = (signed int)stru_721530.uFaceID >> 3;
-      if ( (stru_721530.uFaceID & 7) == 5 )
+      if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
         break;
-      if ( (stru_721530.uFaceID & 7) == 6 )
+      if ( (stru_721530.uFaceID & 7) == OBJECT_BModel)
       {
         v31 = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9];
         v32 = &v31->pFaces[v30 & 0x3F];
@@ -2814,7 +2814,7 @@
     uSectorID = stru_721530.uSectorID;
     stru_721530.field_70 += stru_721530.field_7C;
     auto v87 = ((unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16) + new_party_z;
-    if ( (stru_721530.uFaceID & 7) == 3 )
+    if ( (stru_721530.uFaceID & 7) == OBJECT_Actor)
     {
       if ( SHIDWORD(pParty->pPartyBuffs[11].uExpireTime) >= 0
         && (SHIDWORD(pParty->pPartyBuffs[11].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[11].uExpireTime)) )
@@ -2822,7 +2822,7 @@
       viewparams->bRedrawGameUI = 1;
       goto LABEL_152;
     }
-    if ( (stru_721530.uFaceID & 7) == 5 )
+    if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
     {
       v53 = sub_452A9E(v2 * v2 + v1 * v1);
       v80 = v53;
@@ -2835,7 +2835,7 @@
     }
     else
     {
-      if ( (stru_721530.uFaceID & 7) == 6 )
+      if ( (stru_721530.uFaceID & 7) == OBJECT_BModel)
       {
         v44 = &pIndoor->pFaces[(signed int)stru_721530.uFaceID >> 3];
         v45 = v44->uPolygonType;
@@ -2994,48 +2994,48 @@
 //----- (00473893) --------------------------------------------------------
 void __cdecl ODM_ProcessPartyActions()
 {
-  int _zero; // esi@1
+  //int _zero; // esi@1
   int v1; // edi@1
   int v2; // ebx@1
   int v3; // eax@14
-  Player **v4; // esi@21
-  int v5; // eax@24
+  //Player **v4; // esi@21
+  //int v5; // eax@24
   int v6; // esi@45
   ODMFace *v7; // ecx@45
   //unsigned int v8; // eax@71
-  double v9; // st7@72
+  //double v9; // st7@72
   //signed __int64 v10; // qax@74
-  double v11; // st7@75
-  int v12; // ecx@77
-  int v13; // eax@84
-  double v14; // st7@84
-  int v15; // eax@87
-  double v16; // st7@87
-  int v17; // eax@88
-  double v18; // st7@88
-  int v19; // eax@89
-  double v20; // st7@89
-  int v21; // eax@92
-  double v22; // st7@92
-  int v23; // eax@96
-  double v24; // st7@96
-  int v25; // eax@97
-  double v26; // st7@97
-  int v27; // eax@98
-  double v28; // st7@98
-  signed __int64 v29; // qax@98
-  unsigned int v30; // eax@103
+  //double v11; // st7@75
+  //int v12; // ecx@77
+  //int v13; // eax@84
+  //double v14; // st7@84
+  //int v15; // eax@87
+  //double v16; // st7@87
+  //int v17; // eax@88
+  //double v18; // st7@88
+  //int v19; // eax@89
+  //double v20; // st7@89
+  //int v21; // eax@92
+  //double v22; // st7@92
+  //int v23; // eax@96
+  //double v24; // st7@96
+  //int v25; // eax@97
+  //double v26; // st7@97
+  //int v27; // eax@98
+  //double v28; // st7@98
+  //signed __int64 v29; // qax@98
+  //unsigned int v30; // eax@103
   int v31; // eax@130
-  int v32; // ecx@141
+  //int v32; // ecx@141
   signed int v33; // eax@143
   int v34; // esi@143
-  unsigned int v35; // esi@147
+  int v35; // esi@147
   int v36; // eax@155
   signed int v37; // esi@159
   signed int v38; // eax@159
   signed int i; // esi@159
   int v40; // esi@162
-  Player **v41; // esi@172
+  //Player **v41; // esi@172
   bool v42; // eax@180
   signed int v43; // ecx@184
   signed int v44; // edx@184
@@ -3087,14 +3087,15 @@
   signed int v90; // [sp-14h] [bp-A8h]@246
   signed int v91; // [sp-10h] [bp-A4h]@246
   int v92; // [sp-Ch] [bp-A0h]@246
-  int v93; // [sp-8h] [bp-9Ch]@104
+  //int v93; // [sp-8h] [bp-9Ch]@104
   unsigned int v94; // [sp-8h] [bp-9Ch]@246
-  int v95; // [sp-4h] [bp-98h]@104
+  //int v95; // [sp-4h] [bp-98h]@104
   int v96; // [sp-4h] [bp-98h]@246
   int v97; // [sp+Ch] [bp-88h]@180
-  int v98; // [sp+10h] [bp-84h]@147
-  int v99; // [sp+14h] [bp-80h]@147
-  int v100; // [sp+18h] [bp-7Ch]@147
+  Vec3_int_ v98;
+  //int v98; // [sp+10h] [bp-84h]@147
+  //int v99; // [sp+14h] [bp-80h]@147
+  //int v100; // [sp+18h] [bp-7Ch]@147
   bool v101; // [sp+1Ch] [bp-78h]@33
   int v102; // [sp+20h] [bp-74h]@1
   int v103; // [sp+24h] [bp-70h]@1
@@ -3128,7 +3129,6 @@
 
   v121 = pParty->uFallSpeed;
   v123 = pParty->vPosition.z;
-  _zero = 0;
   v1 = 0;
   v103 = 0;
   v2 = 0;
@@ -3137,7 +3137,7 @@
   v117 = pParty->vPosition.y;
   v113 = pParty->field_6F0;
   bJumping = 0;
-  v118 = GetTerrainHeightsAroundParty(pParty->vPosition.x, pParty->vPosition.y);
+  auto partyAtHighSlope = IsTerrainSlopeTooHigh(pParty->vPosition.x, pParty->vPosition.y);
   v114 = 0;
   v124 = 0;
   v108 = 0;
@@ -3183,57 +3183,52 @@
     v3 = pParty->uFallStartY;
   if ( v3 - v123 > 512 && !bFeatherFall && v123 <= v111 + 1 )
   {
-    if ( BYTE1(pParty->uFlags) & 1 )
-    {
-      BYTE1(pParty->uFlags) &= 0xFEu;
-    }
-    else
-    {
-      v4 = &pPlayers[1];                        // receive falling damage
-      do
-      {
-        if ( !(*v4)->HasEnchantedItemEquipped(72) && !(*v4)->WearsItem(529, 8) )
-        {
-          v105 = (*v4)->GetMaxHealth();
-          (*v4)->ReceiveDamage(
-            (signed int)((pParty->uFallStartY - v123) * (unsigned __int64)(signed __int64)((double)v105 * 0.1)) / 256,
+    if (pParty->uFlags & PARTY_FLAGS_1_LANDING)
+    {
+      pParty->uFlags &= ~PARTY_FLAGS_1_LANDING;
+    }
+    else for (int _i = 0; _i < 4; ++_i)     // receive falling damage
+    {
+      auto player = pParty->pPlayers + _i;
+
+      if ( !player->HasEnchantedItemEquipped(72) && !player->WearsItem(529, 8) )
+      {
+        player->ReceiveDamage(
+            (signed int)((pParty->uFallStartY - v123) * (unsigned __int64)(player->GetMaxHealth() / 10)) / 256,
             4);
-          v5 = (*v4)->GetActualEndurance();
-          v105 = 20 - (*v4)->_48EA1B_get_static_effect(v5);
-          (*v4)->SetRecoveryTime((signed __int64)((double)v105 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
-        }
-        ++v4;
-      }
-      while ( (signed int)v4 <= (signed int)&pPlayers[4] );
-      _zero = 0;
+        v105 = 20 - player->_48EA1B_get_static_effect(player->GetActualEndurance());
+        player->SetRecoveryTime((signed __int64)((double)v105 * flt_6BE3A4_debug_recmod1 * 2.133333333333333));
+      }
+      //}
+      //while ( (signed int)v4 <= (signed int)&pPlayers[4] );
     }
   }
   v109 = -1;
-  if ( pParty->bFlying != _zero )
+  if ( pParty->bFlying )
     v109 = sub_46D8E3(v116, v117, v123 + pParty->uPartyHeight, (int)&v102);
-  v107 = v108 == _zero;
+  v107 = v108 == 0;
   v105 = v111 + 1;
   if ( v123 <= v111 + 1 )
   {
     v109 = -1;
-    pParty->bFlying = _zero;
+    pParty->bFlying = false;
   }
   else
   {
     bJumping = 1;
   }
   v101 = v123 - v111 <= 32;
-  if ( bWalkSound != _zero && pParty->field_6F8 > _zero )
+  if ( bWalkSound && pParty->field_6F8 > 0 )
     pParty->field_6F8 -= pEventTimer->uTimeElapsed;
-  if ( !bUnderwater
-    && SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) <= _zero
-    && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) < _zero || LODWORD(pParty->pPartyBuffs[7].uExpireTime) <= _zero) )
-    pParty->bFlying = _zero;
-  if ( bJumping == _zero )
+  if (!bUnderwater
+    && SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0
+    && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) < 0 || LODWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0) )
+    pParty->bFlying = false;
+  if (!bJumping)
   {
     if ( pParty->field_6F4_packedid != (8 * v108 | OBJECT_BModel) )
     {
-      if ( v108 != _zero )
+      if (v108)
       {
         if ( v108 >> 6 < pOutdoor->uNumBModels )
         {
@@ -3263,18 +3258,19 @@
                                                                     * stru_5C6E00->uIntegerPi)
                                                        / 180)) >> 16);*/
   __int64 dturn = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi) / 180)) >> 16;
-LABEL_118:
-  while ( pPartyActionQueue->uNumActions )
-  {
-    switch ( pPartyActionQueue->Next() )
+  while (pPartyActionQueue->uNumActions)
+  {
+    switch (pPartyActionQueue->Next())
     {
       case PARTY_FlyUp:
-        if ( (signed __int64)pParty->pPartyBuffs[7].uExpireTime > 0 || bUnderwater == 1 )
-        {
-          pParty->bFlying = 0;
-          if ( bUnderwater
-            || pParty->pPartyBuffs[7].uFlags & 1
-            || pParty->pPlayers[pParty->pPartyBuffs[7].uCaster-1].sMana <= 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[7].uCaster + 10] > 0 )
+      {
+        if (!pParty->FlyActive() && !bUnderwater)
+          break;
+
+        pParty->bFlying = false;
+        if (bUnderwater ||
+            pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 ||
+            pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana <= 0 )
           {
             if ( pParty->vPosition.z < 4000 || bJumping )
             {
@@ -3306,10 +3302,11 @@
               v127 = (BSPModel *)1;
             }
           }
-        }
-        goto LABEL_118;
+      }
+      break;
+
       case PARTY_FlyDown:
-        if ( (signed __int64)pParty->pPartyBuffs[7].uExpireTime > 0 || bUnderwater == 1 )
+        if (pParty->FlyActive() || bUnderwater)
         {
           pParty->bFlying = 0;
           if ( bUnderwater
@@ -3329,245 +3326,222 @@
             }
           }
         }
-        goto LABEL_118;
+        break;
+
       case PARTY_TurnLeft:
-        //v8 = uTurnSpeed;
-        if ( uTurnSpeed )
-        {
-          v12 = uTurnSpeed + _angle_y;
-          _angle_y = stru_5C6E00->uDoublePiMask & v12;
-        }
-        else
-        {
-          v9 = (double)dturn * fTurnSpeedMultiplier;
-          _angle_y = stru_5C6E00->uDoublePiMask & (_angle_y + (unsigned __int64)(signed __int64)v9);
-        }
-        break;
+        if (uTurnSpeed)
+          _angle_y += uTurnSpeed;   //descrete turn
+        else
+          _angle_y += dturn * fTurnSpeedMultiplier;  // time-based smooth turn
+
+        _angle_y &= stru_5C6E00->uDoublePiMask;
+      break;
 
       case PARTY_TurnRight:
-        //LODWORD(v10) = uTurnSpeed;
-        if ( uTurnSpeed )
-        {
-          v12 = _angle_y - uTurnSpeed;
-          _angle_y = stru_5C6E00->uDoublePiMask & v12;
-        }
-        else
-        {
-          v11 = (double)dturn * fTurnSpeedMultiplier;
-          v12 = _angle_y - (signed __int64)v11;
-          _angle_y = stru_5C6E00->uDoublePiMask & v12;
-        }
-        break;
+        if (uTurnSpeed)
+          _angle_y -= uTurnSpeed;
+        else
+          _angle_y -= dturn * fTurnSpeedMultiplier;
+
+        _angle_y &= stru_5C6E00->uDoublePiMask;
+      break;
 
       case PARTY_FastTurnLeft:
-        if ( uTurnSpeed )
-        {
-          v12 = uTurnSpeed + _angle_y;
-          _angle_y = stru_5C6E00->uDoublePiMask & v12;
-        }
-        else
-        {
-          v9 = (fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)dturn;
-          _angle_y = stru_5C6E00->uDoublePiMask & (_angle_y + (unsigned __int64)(signed __int64)v9);
-        }
-        break;
+        if (uTurnSpeed)
+          _angle_y += uTurnSpeed;
+        else
+          _angle_y += 2.0f * fTurnSpeedMultiplier * (double)dturn;
+
+        _angle_y &= stru_5C6E00->uDoublePiMask;
+      break;
 
       case PARTY_FastTurnRight:
-        if ( !uTurnSpeed )
-        {
-          v11 = (fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)dturn;
-          v12 = _angle_y - (signed __int64)v11;
-          _angle_y = stru_5C6E00->uDoublePiMask & v12;
-        }
-        else
-        {
-          v12 = _angle_y - uTurnSpeed;
-          _angle_y = stru_5C6E00->uDoublePiMask & v12;
-        }
-        break;
+        if (!uTurnSpeed)
+          _angle_y -= 2.0f * fTurnSpeedMultiplier * (double)dturn;
+        else
+          _angle_y -= uTurnSpeed;
+
+        _angle_y &= stru_5C6E00->uDoublePiMask;
+      break;
 
       case PARTY_StrafeLeft:
-        v13 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-        v14 = (double)_walk_speed;
-        v126 = v13;
-        *(float *)&v128 = v14;
-        v124 = (unsigned __int64)(v13 * (signed __int64)((signed int)(signed __int64)(v14 * fWalkSpeedMultiplier) >> 1)) >> 16;
-        v2 -= v124;
-        v126 = stru_5C6E00->SinCos(_angle_y);
-        v124 = (unsigned __int64)(v126
-                                * (signed __int64)((signed int)(signed __int64)(*(float *)&v128 * fWalkSpeedMultiplier) >> 1)) >> 16;
-        goto LABEL_85;
+      {
+        *(float *)&v128 = pParty->uWalkSpeed;
+
+        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0);
+        int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
+        v2 -= 3 * dx / 4;
+        
+        float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
+        int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
+        v1 += 3 * dy / 4;
+
+        v128 = v1;
+        v124 = 1;
+      }
+      break;
+
       case PARTY_StrafeRight:
-        v15 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-        v16 = (double)_walk_speed;
-        v126 = v15;
-        *(float *)&v128 = v16;
-        v124 = (unsigned __int64)(v15 * (signed __int64)((signed int)(signed __int64)(v16 * fWalkSpeedMultiplier) >> 1)) >> 16;
-        v2 += v124;
-        v126 = stru_5C6E00->SinCos(_angle_y);
-        v124 = (unsigned __int64)(v126
-                                * (signed __int64)((signed int)(signed __int64)(*(float *)&v128 * fWalkSpeedMultiplier) >> 1)) >> 16;
-        goto LABEL_90;
+      {
+        *(float *)&v128 = pParty->uWalkSpeed;
+
+        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0);
+        int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
+        v2 += 3 * dx / 4;
+        
+        float cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
+        int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
+        v1 -= 3 * dy / 4;
+
+        v128 = v1;
+        v124 = 1;
+      }
+      break;
+
       case PARTY_WalkForward:
-        v17 = stru_5C6E00->SinCos(_angle_y);
-        v18 = (double)_walk_speed;
-        v126 = v17;
-        *(float *)&v128 = v18;
-        v124 = (unsigned __int64)(v17 * (signed __int64)(signed int)(signed __int64)(v18 * fWalkSpeedMultiplier)) >> 16;
-        v2 += v124;
-        v126 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-        v124 = (unsigned __int64)(v126
-                                * (signed __int64)(signed int)(signed __int64)(*(float *)&v128 * fWalkSpeedMultiplier)) >> 16;
-LABEL_85:
-        v1 += v124;
-        goto LABEL_86;
-      case PARTY_WalkBackward:
-        v19 = stru_5C6E00->SinCos(_angle_y);
-        v20 = (double)_walk_speed;
-        v126 = v19;
-        *(float *)&v128 = v20;
-        v124 = (unsigned __int64)(v19
-                                * (signed __int64)(signed int)(signed __int64)(v20 * fBackwardWalkSpeedMultiplier)) >> 16;
-        v2 -= v124;
-        v126 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-        v124 = (unsigned __int64)(v126
-                                * (signed __int64)(signed int)(signed __int64)(*(float *)&v128
-                                                                             * fBackwardWalkSpeedMultiplier)) >> 16;
-LABEL_90:
-        v1 -= v124;
-        goto LABEL_86;
+      {
+        *(float *)&v128 = _walk_speed;
+
+        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
+              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
+
+        int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
+        v2 += dx;
+        
+        int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
+        v1 += dy;
+
+        v128 = v1;
+        v124 = 1;
+      }
+      break;
+
       case PARTY_RunForward:
-        if ( pParty->bFlying )
-        {
-          v21 = stru_5C6E00->SinCos(_angle_y);
-          v22 = (double)_walk_speed;
-          v126 = v21;
-          *(float *)&v128 = v22;
-          v129 = (unsigned __int64)(v21
-                                  * (signed __int64)(signed int)(4
-                                                               * (unsigned __int64)(signed __int64)(v22
-                                                                                                  * fWalkSpeedMultiplier))) >> 16;
-          v2 += v129;
-          v126 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-          v129 = (unsigned __int64)(v126
-                                  * (signed __int64)(signed int)(4
-                                                               * (unsigned __int64)(signed __int64)(*(float *)&v128
-                                                                                                  * fWalkSpeedMultiplier))) >> 16;
-          v1 += v129;
-          goto LABEL_93;
-        }
-        if ( v118 && !v108 )
-        {
-          v23 = stru_5C6E00->SinCos(_angle_y);
-          v24 = (double)_walk_speed;
-          v126 = v23;
-          *(float *)&v128 = v24;
-          v129 = (unsigned __int64)(v23 * (signed __int64)(signed int)(signed __int64)(v24 * fWalkSpeedMultiplier)) >> 16;
-          v2 += v129;
-          v126 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-          v129 = (unsigned __int64)(v126
-                                  * (signed __int64)(signed int)(signed __int64)(*(float *)&v128 * fWalkSpeedMultiplier)) >> 16;
-          v1 += v129;
-          goto LABEL_86;
-        }
-        v25 = stru_5C6E00->SinCos(_angle_y);
-        v26 = (double)_walk_speed;
-        v114 = v25;
-        *(float *)&v128 = v26;
-        v129 = (unsigned __int64)(v25
-                                * (signed __int64)(signed int)(2
-                                                             * (unsigned __int64)(signed __int64)(v26
-                                                                                                * fWalkSpeedMultiplier))) >> 16;
-        v2 += v129;
-        v114 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-        v129 = (unsigned __int64)((signed int)v114
-                                * (signed __int64)(signed int)(2
-                                                             * (unsigned __int64)(signed __int64)(*(float *)&v128
-                                                                                                * fWalkSpeedMultiplier))) >> 16;
-        v1 += v129;
-        v114 = 1;
-        v128 = v1;
-        break;
-      case PARTY_RunBackward:
-        v27 = stru_5C6E00->SinCos(_angle_y);
-        v28 = (double)_walk_speed;
-        v126 = v27;
-        *(float *)&v128 = v28;
-        v29 = (signed __int64)(v28 * fBackwardWalkSpeedMultiplier);
-        if ( pParty->bFlying )
-        {
-          v129 = (unsigned __int64)(v126 * (signed __int64)(4 * (signed int)v29)) >> 16;
-          v2 -= v129;
-          v126 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-          v129 = (unsigned __int64)(v126
-                                  * (signed __int64)(signed int)(4
-                                                               * (unsigned __int64)(signed __int64)(*(float *)&v128
-                                                                                                  * fBackwardWalkSpeedMultiplier))) >> 16;
-          v1 -= v129;
-LABEL_93:
+      {
+        *(float *)&v128 = _walk_speed;
+
+        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
+              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
+
+        int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;        
+        int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier;
+
+        if (pParty->bFlying)
+        {
+          v2 += 4 * dx;
+          v1 += 4 * dy;
+
           v128 = v1;
         }
-        else
-        {
-          v129 = (unsigned __int64)(v126 * (signed __int64)(signed int)v29) >> 16;
-          v2 -= v129;
-          v126 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
-          v129 = (unsigned __int64)(v126
-                                  * (signed __int64)(signed int)(signed __int64)(*(float *)&v128
-                                                                               * fBackwardWalkSpeedMultiplier)) >> 16;
-          v1 -= v129;
-LABEL_86:
+        else if (partyAtHighSlope && !v108)
+        {
+          v2 += dx;
+          v1 += dy;
+
           v128 = v1;
           v124 = 1;
         }
-        break;
+        else
+        {
+          v2 += 2 * dx;
+          v1 += 2 * dy;
+          
+          v128 = v1;
+          v114 = 1;
+        }
+      }
+      break;
+
+
+      case PARTY_WalkBackward:
+      {
+        *(float *)&v128 = _walk_speed;
+
+        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
+              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
+
+        int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;
+        v2 -= dx;
+        
+        int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;
+        v1 -= dy;
+
+        v128 = v1;
+        v124 = 1;
+      }
+      break;
+
+
+      case PARTY_RunBackward:
+      {
+        float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0),
+              cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0);
+
+        int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;        
+        int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier;
+
+        if (pParty->bFlying)
+        {
+          v2 -= 4 * dx;
+          v1 -= 4 * dy;
+          v128 = v1;
+        }
+        else
+        {
+          v2 -= dx;
+          v1 -= dy;
+
+          v128 = v1;
+          v124 = 1;
+        }
+      }
+      break;
+
+      
+      case PARTY_CenterView:
+        _angle_x = 0;
+      break;
+
       case PARTY_LookUp:
         _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0);
         if ( _angle_x > 128 )
           _angle_x = 128;
-        v30 = uActiveCharacter;
-        if ( !uActiveCharacter )
-          goto LABEL_118;
-        v95 = 0;
-        v93 = 63;
-        goto _play_player_sound;
+        if (uActiveCharacter)
+          pPlayers[uActiveCharacter]->PlaySound(63, 0);
+      break;
+
       case PARTY_LookDown:
         _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0);
         if ( _angle_x < -128 )
           _angle_x = -128;
-        v30 = uActiveCharacter;
-        if ( uActiveCharacter )
-        {
-          v95 = 0;
-          v93 = 64;
-_play_player_sound:
-          pPlayers[v30]->PlaySound(v93, v95);
-        }
-        goto LABEL_118;
-      case PARTY_CenterView:
-        _angle_x = 0;
-        goto LABEL_118;
+        if (uActiveCharacter)
+          pPlayers[uActiveCharacter]->PlaySound(64, 0);
+      break;
+
       case PARTY_Jump:
-        if ( (!v118 || v108) && !bJumping && pParty->field_24 && !(pParty->uFlags & 4) && !(BYTE1(pParty->uFlags) & 2) )
+        if ( (!partyAtHighSlope || v108) && !bJumping && pParty->field_24 && !(pParty->uFlags & 4) && !(BYTE1(pParty->uFlags) & 2) )
         {
           v126 = pParty->field_24 << 6;
           bJumping = 1;
           v121 = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)v121);
         }
-        goto LABEL_118;
+      break;
+
       default:
-        goto LABEL_118;
+        assert(false);
+
       case PARTY_Land:
-        if ( pParty->bFlying )
-        {
-          BYTE1(pParty->uFlags) |= 1u;
+        if (pParty->bFlying)
+        {
+          pParty->uFlags |= PARTY_FLAGS_1_LANDING;
           pParty->uFallSpeed = 0;
         }
-        pParty->bFlying = 0;
+        pParty->bFlying = false;
         pPartyActionQueue->uNumActions = 0;
-        goto LABEL_123;
-    }
-  }
+      break;
+    }
+  }
+
 LABEL_123:
   pParty->sRotationY = _angle_y;
   pParty->sRotationX = _angle_x;
@@ -3582,8 +3556,7 @@
       v123 = v113 + v129;
       if ( v127 )
         v123 = v113;
-      if ( SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) >= 0
-        && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[7].uExpireTime)) )
+      if (pParty->FlyActive())
         stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[7].uOverlayID + 119] &= 0xFEu;
       pParty->uFallStartY = v123;
       goto LABEL_141;
@@ -3597,70 +3570,70 @@
   if ( pParty->bFlying )
     goto LABEL_130;
   v113 = v123;
-  if ( SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) >= 0
-    && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[7].uExpireTime)) )
+  if (pParty->FlyActive())
     stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[7].uOverlayID + 119] |= 1u;
+
 LABEL_141:
-  v32 = 0;
-  if ( bJumping && !pParty->bFlying )
+  if (bJumping && !pParty->bFlying)
   {
     v33 = -(pEventTimer->uTimeElapsed * GetGravityStrength());
     v34 = v121 + 2 * v33;
     v121 += 2 * v33;
-    goto LABEL_149;
-  }
-  if ( !v118 )
+    goto LABEL_164;
+  }
+  if (!partyAtHighSlope)
   {
     v34 = v121;
-LABEL_149:
-    if ( bJumping == v32 )
+    if (!bJumping)
       goto LABEL_150;
     goto LABEL_164;
   }
-  if ( !bJumping )
+  if (!bJumping)
   {
     if ( v108 )
       goto LABEL_150;
+
+    // rolling down the hill
+    // how it's done: you get a little bit pushed in the air along terrain normal, getting in the air
+    // and falling to the gravity, gradually sliding downwards. nice trick
     v123 = v111;
-    _46DCC8_get_gravity_direction_outdoor(v116, v117, (Vec3_int_ *)&v98);
+    ODM_GetTerrainNormalAt(v116, v117, &v98);
     v35 = v121 + -8 * pEventTimer->uTimeElapsed * GetGravityStrength();
-    v129 = abs((signed __int64)v2 * (signed __int64)v98 + (signed __int64)v1 * (signed __int64)v99 + (signed __int64)v35 * (signed __int64)v100) >> 16;
-    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98) >> 16);
-    v2 += (int)v127;
-    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v99) >> 16);
-    v1 += (int)v127;
+    v129 = abs((signed __int64)v2 * v98.x + (signed __int64)v1 * v98.y + (signed __int64)v35 * v98.z) >> 16;
+    v2 += (unsigned __int64)(v129 * (signed __int64)v98.x) >> 16;
+    v1 += (unsigned __int64)(v129 * (signed __int64)v98.y) >> 16;
+    v34 = v35 + ((unsigned __int64)(v129 * (signed __int64)v98.z) >> 16);
     v128 = v1;
-    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v100) >> 16);
-    v34 = (int)((char *)v127 + v35);
-    v32 = 0;
     v121 = v34;
-    goto LABEL_149;
+    if (!bJumping)
+      goto LABEL_150;
+    goto LABEL_164;
   }
   v34 = v121;
+
 LABEL_164:
-  if ( !bUnderwater && v34 <= v32 )
+  if ( !bUnderwater && v34 <= 0)
   {
     if ( v34 < -500
       && !pParty->bFlying
       && pParty->vPosition.z - v111 > 1000
-      && SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) <= 0
-      && (SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) < 0 || !LODWORD(pParty->pPartyBuffs[5].uExpireTime)) )
-    {
-      v41 = &pPlayers[1];
-      do
-      {
-        if ( !(*v41)->HasEnchantedItemEquipped(72) && !(*v41)->WearsItem(529, 8) && (*v41)->CanAct() )
-          (*v41)->PlaySound(66, 0);
-        ++v41;
-      }
-      while ( (signed int)v41 <= (signed int)&pPlayers[4] );
-    }
-    goto LABEL_151;
-  }
+      && !pParty->FeatherFallActive())
+    { // falling scream
+      for (int i = 0; i < 4; ++i)
+      {
+        auto player = pParty->pPlayers + i;
+        if (!player->HasEnchantedItemEquipped(72) && !player->WearsItem(529, 8) && player->CanAct())
+          player->PlaySound(66, 0);
+      }
+    }
+  }
+  else
+  {
 LABEL_150:
   pParty->uFallStartY = v123;
-LABEL_151:
-  if ( v2 * v2 + v1 * v1 < 400 && !v118 )
+  }
+
+  if ( v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope )
   {
     *(float *)&v128 = 0.0;
     v2 = 0;
@@ -3720,8 +3693,8 @@
                         &v130,
                         &v110,
                         0);
-    v127 = (BSPModel *)GetTerrainHeightsAroundParty(_angle_x, v117);
-    v42 = GetTerrainHeightsAroundParty(v116, _angle_y);
+    v127 = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, v117);
+    v42 = IsTerrainSlopeTooHigh(v116, _angle_y);
     v107 = 0;
     v118 = v42;
     if ( !v97 && !v110 && !v108 )
@@ -3746,7 +3719,7 @@
                          &v130,
                          &v108,
                          0);
-    if ( GetTerrainHeightsAroundParty(_angle_x, _angle_y) && (signed int)v127 <= v123 )
+    if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && (signed int)v127 <= v123 )
     {
       v43 = 1;
 LABEL_197:
@@ -3772,15 +3745,15 @@
     v117 = _angle_y;
     v45 = stru_721530.uFaceID;
     v123 = v40;
-    if ( (stru_721530.uFaceID & 7) == 3 )
-    {
-      if ( SHIDWORD(pParty->pPartyBuffs[11].uExpireTime) >= 0
-        && (SHIDWORD(pParty->pPartyBuffs[11].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[11].uExpireTime)) )
-        pParty->pPartyBuffs[11].Reset();
+    if ( (stru_721530.uFaceID & 7) == OBJECT_Actor)
+    {
+      if (pParty->Invisible())
+        pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
+
       viewparams->bRedrawGameUI = 1;
       goto LABEL_234;
     }
-    if ( (stru_721530.uFaceID & 7) == 5 )
+    if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
     {
       v56 = sub_452A9E(v2 * v2 + v128 * v128);
       v118 = v56;
@@ -3801,7 +3774,7 @@
     }
     else
     {
-      if ( (stru_721530.uFaceID & 7) == 6 )
+      if ( (stru_721530.uFaceID & 7) == OBJECT_BModel)
       {
         pParty->bFlying = 0;
         v46 = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9];
@@ -9430,77 +9403,95 @@
 
 
 //----- (004823F4) --------------------------------------------------------
-bool __fastcall GetTerrainHeightsAroundParty(int a1, int a2)
-{
-  unsigned int v2; // ebx@1
-  unsigned int v3; // edi@1
-  int v4; // eax@1
-  int v6; // esi@5
-  int v7; // ecx@6
-  int v8; // edx@6
-  int v9; // eax@6
-  int v10; // esi@10
-  int v11; // [sp+14h] [bp-8h]@1
-  int v12; // [sp+18h] [bp-4h]@1
-
-  v12 = a1;
-  v11 = a2;
-  v2 = WorldPosToGridCellX(a1);
-  v3 = WorldPosToGridCellZ(v11) - 1;
-  dword_76D568_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2);
-  dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2 + 1);
-  dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2 + 1);
-  dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2);
-  dword_76D558_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3);
-  dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3);
-  dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3 + 1);
-  dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3 + 1);
-  dword_76D548_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v2, v3);
-  dword_76D54C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v2 + 1, v3);
-  dword_76D550_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v2 + 1, v3 + 1);
-  v4 = pOutdoor->DoGetHeightOnTerrain(v2, v3 + 1);
-  dword_76D554_terrain_cell_world_pos_around_party_y = v4;
-  if ( dword_76D548_terrain_cell_world_pos_around_party_y == dword_76D54C_terrain_cell_world_pos_around_party_y
-    && dword_76D54C_terrain_cell_world_pos_around_party_y == dword_76D550_terrain_cell_world_pos_around_party_y
-    && dword_76D550_terrain_cell_world_pos_around_party_y == v4 )
-    return 0;
-  v6 = abs(v12 - dword_76D568_terrain_cell_world_pos_around_party_x);
-  if ( abs(dword_76D558_terrain_cell_world_pos_around_party_z - v11) >= v6 )
-  {
-    v7 = dword_76D554_terrain_cell_world_pos_around_party_y;
-    v8 = dword_76D550_terrain_cell_world_pos_around_party_y;
-    v9 = dword_76D548_terrain_cell_world_pos_around_party_y;
-  }
-  else
-  {
-    v7 = dword_76D54C_terrain_cell_world_pos_around_party_y;
-    v8 = dword_76D548_terrain_cell_world_pos_around_party_y;
-    v9 = dword_76D550_terrain_cell_world_pos_around_party_y;
-  }
-  if ( v7 >= v8 )
-  {
-    v10 = v8;
-    if ( v8 < v9 )
+bool IsTerrainSlopeTooHigh(int pos_x, int pos_z)
+{
+  //unsigned int v2; // ebx@1
+  //unsigned int v3; // edi@1
+  //int v4; // eax@1
+  //int v6; // esi@5
+  //int v7; // ecx@6
+  //int v8; // edx@6
+  //int v9; // eax@6
+  //int v10; // esi@10
+  //int v11; // [sp+14h] [bp-8h]@1
+  //int v12; // [sp+18h] [bp-4h]@1
+
+  //v12 = a1;
+  //v11 = a2;
+  auto grid_x = WorldPosToGridCellX(pos_x);
+  auto grid_z = WorldPosToGridCellZ(pos_z) - 1;
+
+  auto party_grid_x1 = GridCellToWorldPosX(grid_x);
+  //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1);
+  //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1);
+  //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x);
+  auto party_grid_z1 = GridCellToWorldPosZ(grid_z);
+  //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z);
+  //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1);
+  //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1);
+  auto party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
+  auto party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
+  auto party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
+  auto party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
+  //dword_76D554_terrain_cell_world_pos_around_party_y = v4;
+  if (party_x1z1_y == party_x2z1_y &&
+      party_x2z1_y == party_x2z2_y &&
+      party_x2z2_y == party_x1z2_y )
+    return false;
+
+  auto dx = abs(pos_x - party_grid_x1),
+       dz = abs(party_grid_z1 - pos_z);
+
+  int y1, y2, y3;
+  if (dz >= dx)
+  {
+    y1 = party_x1z2_y;  //  lower-left triangle
+    y2 = party_x2z2_y;  //  y3 | \ 
+    y3 = party_x1z1_y;  //     |   \ 
+                        /*     |     \ 
+                               |______ \
+                            y1           y2   */
+  }
+  else
+  {
+    y1 = party_x2z1_y;  // upper-right
+    y2 = party_x1z1_y;  //  y2_______ y1
+    y3 = party_x2z2_y;  //    \     |
+                        /*      \   |
+                                  \ |
+                                    y3     */
+  }
+
+  int y_min = min(y1, min(y2, y3)),
+      y_max = max(y1, max(y2, y3));
+  return y_max - y_min > 512;
+
+  /*if ( y1 >= y2 )
+  {
+    y_min = y2;
+    if ( y2 < y3 )
       goto LABEL_13;
 LABEL_12:
-    v10 = v9;
+    y_min = y3;
     goto LABEL_13;
   }
-  if ( v7 >= v9 )
+  else if ( y1 >= y3 )
     goto LABEL_12;
-  v10 = v7;
+  else
+  y_min = y1;
+
 LABEL_13:
-  if ( v7 <= v8 )
-  {
-    if ( v8 > v9 )
-      v9 = v8;
-  }
-  else
-  {
-    if ( v7 > v9 )
-      v9 = v7;
-  }
-  return v9 - v10 > 512;
+  if ( y1 <= y2 )
+  {
+    if ( y2 > y3 )
+      y3 = y2;
+  }
+  else
+  {
+    if ( y1 > y3 )
+      y3 = y1;
+  }
+  return y3 - v10 > 512;*/
 }
 
 
@@ -12928,7 +12919,7 @@
                 v37 = v21 / x;
                 LODWORD(v31) = v12->scale;
                 v37 = v21 / x;
-                v15->field_0 = (unsigned __int64)(SLODWORD(v31) * v21 / x) >> 16;
+                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(SLODWORD(v31) * v21 / x) >> 16;
                 v37 = (unsigned __int64)(v12->scale * (signed __int64)v37) >> 16;
               }
               else
@@ -12945,7 +12936,7 @@
                 v37 = v20 / x;
                 LODWORD(v31) = v12->scale;
                 v37 = (unsigned __int64)(SLODWORD(v31) * v20 / x) >> 16;
-                v15->field_0 = (unsigned __int64)(SLODWORD(v31) * v20 / x) >> 16;
+                v15->_screenspace_x_scaler_packedfloat = (unsigned __int64)(SLODWORD(v31) * v20 / x) >> 16;
                 v31 = v15->fov_y;
                 v25 = v31 + 6.7553994e15;
                 LODWORD(v20) = 0;
@@ -12954,7 +12945,7 @@
                 v37 = (unsigned __int64)(v12->scale * v20 / x) >> 16;
               }
               HIWORD(v22) = HIWORD(x);
-              v15->field_4 = v37;
+              v15->_screenspace_y_scaler_packedfloat = v37;
               v15->field_1E = v30;
               v15->some_x = a1;
               v15->some_y = a2;
@@ -13113,7 +13104,7 @@
                 LODWORD(v19) = pBLVRenderParams->field_40 << 16;
                 HIDWORD(v19) = pBLVRenderParams->field_40 >> 16;
                 v20 = v19 / x;
-                v3->field_0 = (unsigned __int64)(v24->scale * v19 / x) >> 16;
+                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * v19 / x) >> 16;
                 v31 = (unsigned __int64)(v24->scale * (signed __int64)v20) >> 16;
               }
               else
@@ -13121,11 +13112,11 @@
                 v3->fov_x = pGame->pIndoorCameraD3D->fov_x;
                 v3->fov_y = pGame->pIndoorCameraD3D->fov_y;
                 v18 = (int)floorf(v3->fov_x + 0.5f) / x;
-                v3->field_0 = (unsigned __int64)(v24->scale * (__int64)v18) >> 16;
+                v3->_screenspace_x_scaler_packedfloat = (unsigned __int64)(v24->scale * (__int64)v18) >> 16;
                 v31 = (unsigned __int64)(v24->scale * (__int64)v18) >> 16;
               }
               HIWORD(v21) = HIWORD(x);
-              v3->field_4 = v31;
+              v3->_screenspace_y_scaler_packedfloat = v31;
               v3->field_1E = v34;
               v3->some_x = a1;
               v3->some_y = a2;
@@ -13302,13 +13293,13 @@
 //----- (0044100D) --------------------------------------------------------
 bool __cdecl sub_44100D()
 {
-  return pCurrentScreen == 4
-      || pCurrentScreen == 7
-      || pCurrentScreen > 12
-      && (pCurrentScreen <= 14
-       || pCurrentScreen > 16
-       && (pCurrentScreen <= 18
-        || pCurrentScreen == 23));
+  return pCurrentScreen == SCREEN_NPC_DIALOGUE
+      || pCurrentScreen == SCREEN_CHARACTERS
+      || pCurrentScreen > SCREEN_LOADGAME
+      && (pCurrentScreen <= SCREEN_E
+       || pCurrentScreen > SCREEN_VIDEO
+       && (pCurrentScreen <= SCREEN_INPUT_BLV
+        || pCurrentScreen == SCREEN_CASTING));
 }
 // 4E28F8: using guessed type int pCurrentScreen;
 
@@ -13321,16 +13312,16 @@
   IconFrame *v3; // eax@19
 
   if ( !pCurrentScreen
-    || pCurrentScreen == 1
-    || pCurrentScreen == 2
-    || pCurrentScreen == 5
-    || pCurrentScreen == 8
-    || pCurrentScreen == 10
-    || pCurrentScreen == 11
-    || pCurrentScreen == 12
-    || pCurrentScreen == 15
-    || pCurrentScreen == 3
-    || pCurrentScreen == 19 )
+    || pCurrentScreen == SCREEN_MENU
+    || pCurrentScreen == SCREEN_OPTIONS
+    || pCurrentScreen == SCREEN_REST
+    || pCurrentScreen == SCREEN_SPELL_BOOK
+    || pCurrentScreen == SCREEN_CHEST
+    || pCurrentScreen == SCREEN_SAVEGAME
+    || pCurrentScreen == SCREEN_LOADGAME
+    || pCurrentScreen == SCREEN_F
+    || pCurrentScreen == SCREEN_BOOKS
+    || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
   {
     if ( SHIDWORD(pParty->pPartyBuffs[16].uExpireTime) >= 0
       && (SHIDWORD(pParty->pPartyBuffs[16].uExpireTime) > 0 || LODWORD(pParty->pPartyBuffs[16].uExpireTime)) )
@@ -13421,7 +13412,7 @@
   }
   while ( v1 < 14 );
   if ( !pCurrentScreen
-    || pCurrentScreen == 4 )
+    || pCurrentScreen == SCREEN_NPC_DIALOGUE )
   {
     if ( (signed __int64)pParty->pPartyBuffs[7].uExpireTime > 0 )
     {
@@ -13536,8 +13527,8 @@
             v13 = (unsigned __int64)(v11 * (signed __int64)v13) >> 16;
             v10.uScreenSpaceX = *((short *)v3 - 2);
             v10.uScreenSpaceY = *((short *)v3 - 1);
-            v10.field_10 = v13;
-            v10.field_14 = v13;
+            v10._screenspace_x_scaler_packedfloat = v13;
+            v10._screenspace_y_scaler_packedfloat = v13;
             v10.pPalette = PaletteManager::Get_Dark_or_Red_LUT(v6->uPaletteIndex, 0, 1);
             v8 = *((short *)v3 - 5);
             v10.sZValue = 0;
@@ -13562,30 +13553,21 @@
 
 
 //----- (00441D38) --------------------------------------------------------
-void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int flags)
+void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap)
 {
   int uHeight; // ebx@6
-  //unsigned int v9; // edx@9
-  //unsigned int v10; // ebx@10
   __int16 v11; // cx@11
-  //BLVFace *v12; // ecx@17
-  //unsigned int v13; // ecx@21
   unsigned int v14; // ebx@23
   int v15; // eax@23
-  //unsigned int *v16; // ecx@28
   __int16 v17; // di@30
   double v18; // st7@30
   float v19; // ST38_4@30
   double v20; // st7@30
   double v21; // st6@30
   double v22; // st5@33
-  //unsigned __int16 *v26; // edx@37
   signed int v27; // eax@37
   unsigned __int16 *v28; // ecx@37
   signed int v29; // edi@40
-  //int v30; // eax@42
-  //unsigned __int16 *v31; // ebx@43
-  //signed int v32; // edi@46
   signed int v33; // ebx@50
   unsigned int v34; // eax@50
   signed int v35; // ecx@50
@@ -13603,7 +13585,6 @@
   int v47; // eax@108
   unsigned int v48; // ebx@114
   unsigned int v49; // ST64_4@114
-  //double v50; // ST20_8@117
   unsigned int v51; // [sp-10h] [bp-64h]@79
   unsigned int v52; // [sp-10h] [bp-64h]@100
   unsigned int v53; // [sp-Ch] [bp-60h]@79
@@ -13615,9 +13596,7 @@
   unsigned __int16 v59; // [sp-4h] [bp-58h]@100
   unsigned __int16 v60; // [sp+10h] [bp-44h]@66
   unsigned int v61; // [sp+10h] [bp-44h]@85
-  //unsigned __int16 *v62; // [sp+14h] [bp-40h]@30
   unsigned int v63; // [sp+14h] [bp-40h]@85
-  //int v64; // [sp+18h] [bp-3Ch]@39
   unsigned int v65; // [sp+18h] [bp-3Ch]@85
   unsigned int lPitch; // [sp+20h] [bp-34h]@1
   unsigned int lPitcha; // [sp+20h] [bp-34h]@23
@@ -13627,34 +13606,24 @@
   unsigned __int16 uBlue; // [sp+28h] [bp-2Ch]@1
   signed int uBluea; // [sp+28h] [bp-2Ch]@37
   int v73; // [sp+2Ch] [bp-28h]@30
-  //unsigned __int8 *v74; // [sp+30h] [bp-24h]@30
   int v76; // [sp+34h] [bp-20h]@91
   int v77; // [sp+34h] [bp-20h]@108
-  //signed int v78; // [sp+38h] [bp-1Ch]@37
   int v79; // [sp+38h] [bp-1Ch]@72
-  //signed int a2b; // [sp+40h] [bp-14h]@41
   char *a2c; // [sp+40h] [bp-14h]@68
-  //int a3a; // [sp+44h] [bp-10h]@40
   signed int uCenterY; // [sp+48h] [bp-Ch]@1
   signed int uCenterX; // [sp+4Ch] [bp-8h]@1
-  //signed int uZb; // [sp+5Ch] [bp+8h]@27
   signed int uWidth; // [sp+5Ch] [bp+8h]@30
-  //signed int uZd; // [sp+5Ch] [bp+8h]@45
   signed int uZe; // [sp+5Ch] [bp+8h]@67
   signed int uZf; // [sp+5Ch] [bp+8h]@85
   signed int uZg; // [sp+5Ch] [bp+8h]@105
   unsigned int uWa; // [sp+60h] [bp+Ch]@23
   float uWb; // [sp+60h] [bp+Ch]@30
-  //unsigned __int16 *uWc; // [sp+60h] [bp+Ch]@37
   unsigned int uWd; // [sp+60h] [bp+Ch]@95
   float uZooma; // [sp+64h] [bp+10h]@117
-  //signed int flagsa; // [sp+68h] [bp+14h]@42
   unsigned int flagsb; // [sp+68h] [bp+14h]@66
   Actor *flagsc; // [sp+68h] [bp+14h]@86
   unsigned int flagsd; // [sp+68h] [bp+14h]@105
 
-  //a3 = uY;
-  //a2 = uX;
   uCenterX = (uX + uZ) / 2;
   uCenterY = (uY + uW) / 2;
   lPitch = pRenderer->uTargetSurfacePitch;
@@ -13710,78 +13679,46 @@
 
       default: assert(false);
     }
-//LABEL_37:
-    //v23 = v20 * 65536.0;
-    //v24 = v23 + 6.7553994e15;
+    assert(sizeof(pOdmMinimap) == 137 * 117 * sizeof(short));
+
     v70 = floorf(v20 * 65536.0 + 0.5f);//LODWORD(v24);
-    //uWe = uWb * 65536.0;
-    //v25 = uWe + 6.7553994e15;
-    //v78 = v70;
     uBluea = floorf(uWb * 65536.0 + 0.5f);//LODWORD(v25);
     v27 = uBluea >> 16;
     v28 = &pRenderer->pTargetSurface[uX + uY * lPitch];
-    if ( flags && pMapLod0)
-    {
-      auto pMinimap = (unsigned __int16 *)_56EFD8_minimap;
-      //if ( v74 )
-      //{
+    if (pMapLod0 && bRedrawOdmMinimap)
+    {
+      assert(uWidth == 137 && uHeight == 117);
+      //auto pMinimap = (unsigned __int16 *)pOdmMinimap;
+
         auto mapWidth = pIcons_LOD->pTextures[viewparams->uTextureID_LocationMap].uTextureWidth;
-        //if ( uHeight > 0 )
-        //{
-          //a3a = uHeight;
+
           v29 = v70 >> 16;
-          //do
+
           for (int y = 0; y < uHeight; ++y)
           {
-            //a2b = 0;
-            //if ( uWidth > 0 )
-            //{
               auto pMapLod0Line = &pMapLod0[v27 * mapWidth];
-              //flagsa = uWidth;
-              //a2b = uWidth;
               for (int x = 0; x < uWidth; ++x)
-              //do
-              {
-                //v31 = uWc;
-                //++uWc;
-                *pMinimap++ = pPal[pMapLod0Line[v29]];
-                //v78 += v73;
+              {
+                //*pMinimap++ = pPal[pMapLod0Line[v29]];
+                pOdmMinimap[y][x] = pPal[pMapLod0Line[v29]];
                 v29 = (v70 + x * v73) >> 16;
-                //--flagsa;
-              }
-              //while ( flagsa );
-            //}
-            //v78 = v70;
+              }
+
             v29 = v70 >> 16;
             v28 += 137 - uWidth;
             uBluea += v73;
             v27 = uBluea >> 16;
-            //--a3a;
-          }
-          //while ( a3a );
-        //}
-      //}
-    }
-
-    auto pMinimap = (unsigned __int16 *)_56EFD8_minimap;
-    //uZd = 117;
-    //do
+          }
+    }
+
     for (int y = 0; y < 117; ++y)
     {
-      //v32 = 137;
-      //do
       for (int x = 0; x < 137; ++x)
       {
-        *v28++ = *pMinimap++;
-        //++v28;
-        //++v26;
-        //--v32;
-      }
-      //while ( v32 );
+        *v28++ = pOdmMinimap[y][x];
+      }
       v28 += lPitch - 137;
-      //--uZd;
-    }
-    //while ( uZd );
+    }
     uNumBlueFacesInBLVMinimap = 0;
   }
   else
@@ -13919,7 +13856,7 @@
   v36 = 255;
   flagsb = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0, 0xFFu);
   v60 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0, 0);
-  if ( bWizardEyeActive )
+  if ( bWizardEyeActive = true)
   {
     uZe = 0;
     //for (uint i = 0; i < uNumLayingItems; ++i)
@@ -16342,7 +16279,7 @@
         do
         {
           v30 = *v55;
-          if ( *v55 == 5 || v30 == 11 || v30 == 19 || (v31 = *((int *)v55 + 159)) != 0 && (v31 & 7) == 4 )
+          if ( *v55 == Dead || v30 == Removed || v30 == Disabled || (v31 = *((int *)v55 + 159)) != 0 && (v31 & 7) == OBJECT_Player)
             ++pInString;
           v55 += 418;
           --*(int *)v54;
@@ -17997,7 +17934,7 @@
               pGameLoadingUI_ProgressBar->uType = (GUIProgressBar::Type)((_5C3420_pDecoration == 0) + 1);
               sub_44987B(v99, 0);
               v133 = 1;
-              if ( pCurrentScreen == 13 )
+              if ( pCurrentScreen == SCREEN_HOUSE )
               {
                 if ( uGameState == 2 )
                 {
@@ -18010,7 +17947,7 @@
                   ptr_507BC0 = 0;
                   if ( pMessageQueue_50CBD0->uNumMessages )
                     pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-                  pCurrentScreen = 0;
+                  pCurrentScreen = SCREEN_GAME;
                   viewparams->bRedrawGameUI = 1;
                   array_5913D8[6] = 0;
                   pDialogueWindow->Release();
@@ -19500,7 +19437,7 @@
     dword_5B65C0 = 0;
     pGameLoadingUI_ProgressBar->uType = GUIProgressBar::TYPE_Fullscreen;
     sub_44987B("nwc.blv", 0);
-    pCurrentScreen = 0;
+    pCurrentScreen = SCREEN_GAME;
     result = 1;
   }
   return result;
@@ -20442,12 +20379,12 @@
         v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
       a2 = *v20;
       v76 = a2 & 7;
-      if ( (a2 & 7) == 3 )
+      if ( (a2 & 7) == OBJECT_Actor)
         v80 = 0.5;
       else
         v80 = 1.0;
       v22 = v21->uAIState;
-      if ( v22 == 4 || v22 == 5 || v22 == 11 || v22 == 19 || v22 == 17 )
+      if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
         goto LABEL_254;
       if ( !v21->sCurrentHP )
         Actor::Die(uActorID);
@@ -20965,7 +20902,7 @@
     v2 = this->pQueue;
     do
     {
-      if ( (v2->uPackedID & 7) == 3 )
+      if ( (v2->uPackedID & 7) == OBJECT_Actor )
       {
         v3 = &pActors[v2->uPackedID >> 3];
         v4 = &pActors[v2->uPackedID >> 3];
@@ -20977,7 +20914,7 @@
           LOBYTE(v3->uAttributes) &= 0x7Fu;
         }
       }
-      if ( (v2->uPackedID & 7) == 4 )
+      if ( (v2->uPackedID & 7) == OBJECT_Player)
       {
         v5 = &pParty->pPlayers[v2->uPackedID >> 3];
         if ( v5->pConditions[14]
@@ -21013,7 +20950,7 @@
           v10 = v7->field_4;
           if ( v9 < v10
             || v9 == v10
-            && ((v11 = v8->uPackedID & 7, v11 == 4) && (v7->uPackedID & 7) == 3
+            && ((v11 = v8->uPackedID & 7, v11 == OBJECT_Player) && (v7->uPackedID & 7) == OBJECT_Actor
              || v11 == (v7->uPackedID & 7) && (v8->uPackedID & 0xFFFFFFF8) < (v7->uPackedID & 0xFFFFFFF8)) )
           {
             v12 = v7->uPackedID;
@@ -21042,7 +20979,7 @@
   }
   v1->uActorQueueSize = v19;
   result = v1->pQueue[0].uPackedID;
-  if ( (v1->pQueue[0].uPackedID & 7) == 4 )
+  if ( (v1->pQueue[0].uPackedID & 7) == OBJECT_Player)
   {
     result = (result >> 3) + 1;
     uActiveCharacter = result;
@@ -21059,7 +20996,7 @@
     v17 = v1->pQueue;
     do
     {
-      if ( (v17->uPackedID & 7) == 4 )
+      if ( (v17->uPackedID & 7) == OBJECT_Player)
         pParty->pPlayers[v17->uPackedID >> 3].uTimeToRecovery = (signed __int64)((double)v17->field_4 * 0.46875);
       ++v22;
       ++v17;