changeset 831:9c3f28b31b4a

Party actions in blv
author Nomad
date Wed, 27 Mar 2013 15:04:59 +0200
parents 08d90b633131
children dfd683c4f538 95d9727412c9
files Game.cpp Indoor.cpp Items.h Party.h Player.h UICharacter.cpp mm7_2.cpp mm7_3.cpp mm7_data.cpp mm7_data.h
diffstat 10 files changed, 188 insertions(+), 196 deletions(-) [+]
line wrap: on
line diff
--- a/Game.cpp	Wed Mar 27 11:59:37 2013 +0200
+++ b/Game.cpp	Wed Mar 27 15:04:59 2013 +0200
@@ -204,7 +204,8 @@
 
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
   {
-    sprintf(pTmpBuf, "Party Sector ID:        %u/%u\n", pBLVRenderParams->uPartySectorID, pIndoor->uNumSectors);
+    auto sector_id = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+    sprintf(pTmpBuf, "Party Sector ID:        %u/%u\n", sector_id, pIndoor->uNumSectors);
     pPrimaryWindow->DrawText(pFontArrus, 16, 16, GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 255), pTmpBuf, 0, 0, 0xFFFFFFFF);
   }
   sprintf(pTmpBuf, "Party Position:         % d % d % d", pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
@@ -213,7 +214,8 @@
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
   {
     uint uFaceID;
-    auto floor_level = BLV_GetFloorLevel(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z, pBLVRenderParams->uPartySectorID, &uFaceID);
+    auto sector_id = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+    auto floor_level = BLV_GetFloorLevel(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + 40, sector_id, &uFaceID);
     sprintf(pTmpBuf, "BLV_GetFloorLevel: %d   face_id %d\n", floor_level, uFaceID);
   }
   else
--- a/Indoor.cpp	Wed Mar 27 11:59:37 2013 +0200
+++ b/Indoor.cpp	Wed Mar 27 15:04:59 2013 +0200
@@ -28,6 +28,7 @@
 #include "GUIFont.h"
 
 #include "mm7_data.h"
+#include "MM7.h"
 
 
 
@@ -533,54 +534,45 @@
         if (pDecalBuilder->uNumDecals > 0)
           pDecalBuilder->ApplyDecals(a4a, 1, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0, pFace->uSectorID);
 
-        if (pFace->Fluid() &&
-            pFace->uBitmapID == pRenderer->hd_water_tile_id )
-        {
-          v23 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
-          v27 = pBitmaps_LOD->pHardwareTextures[v23];
-          if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
-            _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
-          else
-            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-          return;
-        }
         if (pFace->Fluid())
         {
-          //auto v24 = GetTickCount() / 4;
-          //auto v25 = v24 - stru_5C6E00->uIntegerHalfPi;
-          uint eightSeconds = GetTickCount() % 8000;
-          float angle = (eightSeconds / 8000.0f) * 2 * 3.1415f;
-
-          //animte lava back and forth
-          for (uint i = 0; i < uNumVerticesa; ++i)
-            //array_507D30[i].v += (double)(pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 & (unsigned int)(stru_5C6E00->SinCos(v25) >> 8));
-            array_507D30[i].v += pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 * cosf(angle);
-          v23 = pFace->uBitmapID;
-          v27 = pBitmaps_LOD->pHardwareTextures[v23];
-          if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
-            _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
+          if (pFace->uBitmapID == pRenderer->hd_water_tile_id)
+          {
+            v23 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
+            v27 = pBitmaps_LOD->pHardwareTextures[v23];
+          }
           else
-            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-          return;
+          {
+            //auto v24 = GetTickCount() / 4;
+            //auto v25 = v24 - stru_5C6E00->uIntegerHalfPi;
+            uint eightSeconds = GetTickCount() % 8000;
+            float angle = (eightSeconds / 8000.0f) * 2 * 3.1415f;
+
+            //animte lava back and forth
+            for (uint i = 0; i < uNumVerticesa; ++i)
+              //array_507D30[i].v += (double)(pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 & (unsigned int)(stru_5C6E00->SinCos(v25) >> 8));
+              array_507D30[i].v += pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 * cosf(angle);
+            v23 = pFace->uBitmapID;
+            v27 = pBitmaps_LOD->pHardwareTextures[v23];
+          }
         }
         else if (pFace->uAttributes & 0x4000)
         {
           v23 = pTextureFrameTable->GetFrameTexture(pFace->uBitmapID, pBLVRenderParams->field_0_timer_);
           v27 = pBitmaps_LOD->pHardwareTextures[v23];
-          if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
-            _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
-          else
-            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-          return;
         }
-        v17 = 0xFFFFFFFF;
-        v23 = pFace->uBitmapID;
-        v27 = pBitmaps_LOD->pHardwareTextures[v23];
+        else
+        {
+          v17 = 0xFFD0D0D0;
+          v23 = pFace->uBitmapID;
+          v27 = pBitmaps_LOD->pHardwareTextures[v23];
+        }
+
         if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
           _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
         else
-          pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-        return;;
+          pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, PID(OBJECT_BModel, uFaceID), v17, 0);
+        return;
       }
     }
   }
--- a/Items.h	Wed Mar 27 11:59:37 2013 +0200
+++ b/Items.h	Wed Mar 27 15:04:59 2013 +0200
@@ -74,10 +74,12 @@
   ITEM_RILIC_TITANS_BELT = 524,//20C
   ITEM_RELIC_TWILIGHT = 525,//20D
   ITEM_RELIC_MEKORIGS_HAMMER = 0x210,
+  ITEM_ARTIFACT_HERMES_SANDALS = 529,
   ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP = 530,//212
   ITEM_ARTIFACT_MINDS_EYE = 532,//214
   ITEM_ELVEN_CHAINMAIL = 533,//215
-  ITEM_ARTIFAT_HEROS_BELT = 535,//217
+  ITEM_ARTIFACT_HEROS_BELT = 535,//217
+  ITEM_ARTIFACT_LADYS_ESCORT = 536,
   ITEM_RARE_SHADOWS_MASK = 544,//220
   ITEM_RARE_SUN_CLOAK = 547,//223
   ITEM_RARE_MOON_CLOAK = 548,//224
@@ -157,6 +159,8 @@
                             // 64  Double Damage vs. Undead.
                             // 67  Adds 5 points of Body damage and +2 Disarm skill.
                             // 68  Adds 6-8 points of Cold damage and +5 Armor Class.
+                            // 71  Prevents drowning damage.
+                            // 72  Prevents falling damage.
   int uNumCharges;
   unsigned int uAttributes;
   unsigned __int8 uBodyAnchor;
--- a/Party.h	Wed Mar 27 11:59:37 2013 +0200
+++ b/Party.h	Wed Mar 27 15:04:59 2013 +0200
@@ -211,8 +211,8 @@
   int uFallSpeed;
   int field_6EC;
   int field_6F0;
-  int field_6F4_packedid;
-  int field_6F8;
+  int floor_face_pid; // face we are standing at
+  int walk_sound_timer;
   int field_6FC;
   int uFallStartY;
   unsigned int bFlying;
--- a/Player.h	Wed Mar 27 11:59:37 2013 +0200
+++ b/Player.h	Wed Mar 27 15:04:59 2013 +0200
@@ -401,7 +401,7 @@
   
   // ?
 
-  CHARACTER_EXPRESSION_46 = 46,
+  CHARACTER_EXPRESSION_SCARED = 46, // like falling
 
   CHARACTER_EXPRESSION_54 = 54,
   CHARACTER_EXPRESSION_55 = 55,
--- a/UICharacter.cpp	Wed Mar 27 11:59:37 2013 +0200
+++ b/UICharacter.cpp	Wed Mar 27 15:04:59 2013 +0200
@@ -3392,8 +3392,7 @@
                 ptr_50C9A4 = 0;
                 }
             v32 = (double)GetTickCount() * 0.1;
-            pRenderer->_4A63E6(0x24Au, 0x58u, (Texture *)(v28 != -1 ? (int)&pIcons_LOD->pTextures[v28] : 0),
-                v31, (signed __int64)v32, 0, 255);
+            pRenderer->_4A63E6(0x24Au, 0x58u, pIcons_LOD->GetTexture(v28), v31, (signed __int64)v32, 0, 255);
         }
 
 //----- (0043BCA7) --------------------------------------------------------
@@ -3553,7 +3552,7 @@
     if (sub_43EE15_player_has_item(ITEM_ARTIFACT_MINDS_EYE, player, 1))          byte_5111F6[7] = 1;
     if (sub_43EE15_player_has_item(ITEM_RARE_SHADOWS_MASK, player, 1))           byte_5111F6[8] = 1;
     if (sub_43EE15_player_has_item(ITEM_RILIC_TITANS_BELT, player, 1))           byte_5111F6[9] = 1;
-    if (sub_43EE15_player_has_item(ITEM_ARTIFAT_HEROS_BELT, player, 1))          byte_5111F6[10] = 1;
+    if (sub_43EE15_player_has_item(ITEM_ARTIFACT_HEROS_BELT, player, 1))         byte_5111F6[10] = 1;
     if (sub_43EE15_player_has_item(ITEM_RELIC_TWILIGHT, player, 1))              byte_5111F6[11] = 1;
     if (sub_43EE15_player_has_item(ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP, player, 1)) byte_5111F6[12] = 1;
     if (sub_43EE15_player_has_item(ITEM_RARE_SUN_CLOAK, player, 1))              byte_5111F6[13] = 1;
--- a/mm7_2.cpp	Wed Mar 27 11:59:37 2013 +0200
+++ b/mm7_2.cpp	Wed Mar 27 15:04:59 2013 +0200
@@ -7777,7 +7777,7 @@
     bUnderwater = 1;
     pGame->uFlags2 |= 8u;
   }
-  pParty->field_6F4_packedid = 0;
+  pParty->floor_face_pid = 0;
   if ( _strcmpi(Str1, "blv") )
     PrepareToLoadODM(v9, 0);
   else
--- a/mm7_3.cpp	Wed Mar 27 11:59:37 2013 +0200
+++ b/mm7_3.cpp	Wed Mar 27 15:04:59 2013 +0200
@@ -1481,7 +1481,7 @@
 }
 
 //----- (0047272C) --------------------------------------------------------
-int _47272C_collide_agains_some_secotors_floors(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
+int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
 {
   signed int v5; // ebx@1
   int result; // eax@1
@@ -1521,15 +1521,15 @@
 {
   int v1; // ebx@1
   int v2; // edi@1
-  int v6; // eax@18
-  signed __int64 v8; // qax@27
-  int v9; // eax@27
+  //int v6; // eax@18
+  //signed __int64 v8; // qax@27
+  //int v9; // eax@27
   double v10; // st7@27
   unsigned int v12; // eax@49
   double v13; // st7@50
-  int v14; // eax@51
-  signed __int64 v15; // qax@53
-  double v16; // st7@54
+  //int v14; // eax@51
+  //signed __int64 v15; // qax@53
+  //double v16; // st7@54
   int v17; // eax@62
   double v18; // st7@62
   int v19; // ST40_4@62
@@ -1574,10 +1574,10 @@
   unsigned int v64; // [sp-8h] [bp-68h]@161
   int v65; // [sp-4h] [bp-64h]@75
   int v66; // [sp-4h] [bp-64h]@161
-  int v68; // [sp+10h] [bp-50h]@45
+  //int v68; // [sp+10h] [bp-50h]@45
   int v69; // [sp+10h] [bp-50h]@140
   unsigned int uFaceEvent; // [sp+14h] [bp-4Ch]@1
-  signed int v71; // [sp+18h] [bp-48h]@1
+  //signed int v71; // [sp+18h] [bp-48h]@1
   signed int v72; // [sp+1Ch] [bp-44h]@1
   signed int v73; // [sp+20h] [bp-40h]@100
   int v74; // [sp+20h] [bp-40h]@140
@@ -1606,29 +1606,24 @@
   uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
   v72 = 0;
   v78 = 0;
-  v71 = 0;
   bJumping = 0;
 
   uFaceID = -1;
-  v80 = collide_against_floor(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
-  assert(uFaceID != -1);
-
-  for (uint i = 0; i < pIndoor->uNumFaces; ++i)
-    pIndoor->pFaces[i].uAttributes &= ~FACE_OUTLINED;
-  pIndoor->pFaces[uFaceID].uAttributes |= FACE_OUTLINED;
+  auto floor_level = collide_against_floor(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
 
   if ( pParty->bFlying )
   {
     pParty->bFlying = false;
     if (pParty->FlyActive())
       pOtherOverlayList->pOverlays[pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID - 1].field_E |= 1;
-      //stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1u;// 005E4D58 pOtherOverlayList [negindexing]
-  }
-  if ( v80 == -30000 )
-  {
-    v80 = _47272C_collide_agains_some_secotors_floors(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
-    if ( v80 == -30000 )
-    {
+  }
+
+  if ( floor_level == -30000  || uFaceID == -1)
+  {
+    floor_level = collide_against_floor_approximate(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
+    if ( floor_level == -30000 || uFaceID == -1)
+    {
+      __debugbreak(); // level built with errors 
       pParty->vPosition.x = blv_prev_party_x;
       pParty->vPosition.y = blv_prev_party_z;
       pParty->vPosition.z = blv_prev_party_y;
@@ -1636,6 +1631,11 @@
       return;
     }
   }
+
+  for (uint i = 0; i < pIndoor->uNumFaces; ++i)
+    pIndoor->pFaces[i].uAttributes &= ~FACE_OUTLINED;
+  pIndoor->pFaces[uFaceID].uAttributes |= FACE_OUTLINED;
+
   blv_prev_party_x = pParty->vPosition.x;
   blv_prev_party_z = pParty->vPosition.y;
   blv_prev_party_y = pParty->vPosition.z;
@@ -1652,84 +1652,86 @@
     }
     dword_720CDC = v67;
   }
+
+  uint fall_start;
   if (!pParty->FeatherFallActive())
   {
     bFeatherFall = false;
-    if (!pParty->pPlayers[0].WearsItem(536, 16) &&
-        !pParty->pPlayers[1].WearsItem(536, 16) &&
-        !pParty->pPlayers[2].WearsItem(536, 16) &&
-        !pParty->pPlayers[3].WearsItem(536, 16))
-    {
-      v6 = pParty->uFallStartY;
-    }
-  }
-  else
-  {
-    v6 = v80;
+    if (!pParty->pPlayers[0].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16) &&  // grants feather fall
+        !pParty->pPlayers[1].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16) &&
+        !pParty->pPlayers[2].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16) &&
+        !pParty->pPlayers[3].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16))
+    {
+      fall_start = pParty->uFallStartY;
+    }
+  }
+  else
+  {
+    fall_start = floor_level;
     bFeatherFall = true;
-    pParty->uFallStartY = v80;
-  }
-LABEL_20:
-  if ( v6 - party_z > 512 && !bFeatherFall && party_z <= v80 + 1 )
-  {
+    pParty->uFallStartY = floor_level;
+  }
+
+
+  if (fall_start - party_z > 512 && !bFeatherFall && party_z <= floor_level + 1)
+  {
+    assert(~pParty->uFlags & PARTY_FLAGS_1_LANDING); // why land in indoor?
     if (pParty->uFlags & PARTY_FLAGS_1_LANDING)
-    {
       pParty->uFlags &= ~PARTY_FLAGS_1_LANDING;
-    }
     else for (uint i = 0; i < 4; ++i)
     {                                      // receive falling damage
-      auto pPlayer = pParty->pPlayers + i;
-           
-      if (!pPlayer->HasEnchantedItemEquipped(72) &&
-          !pPlayer->WearsItem(529, 8))
-      {
-        v8 = (signed __int64)((double)pPlayer->GetMaxHealth() * 0.1);
-        pPlayer->ReceiveDamage((pParty->uFallStartY - party_z) * (signed int)v8 / 256, 4);
-        v9 = pPlayer->GetActualEndurance();
-        v10 = (double)(20 - pPlayer->_48EA1B_get_static_effect(v9)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
-        pPlayer->SetRecoveryTime((signed __int64)v10);
-      }
-    }
-  }
-  if ( party_z > v80 + 1 )
+      auto player = pParty->pPlayers + i;
+      if (!player->HasEnchantedItemEquipped(72) && !player->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, 8))
+      {
+        player->ReceiveDamage((pParty->uFallStartY - party_z) * (0.1f * player->GetMaxHealth()) / 256, 4);
+        v10 = (double)(20 - player->_48EA1B_get_static_effect(player->GetActualEndurance())) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
+        player->SetRecoveryTime((signed __int64)v10);
+      }
+    }
+  }
+
+  if ( party_z > floor_level + 1 )
     bJumping = 1;
-  bFeatherFall = party_z - v80 <= 32;
-  if ( party_z - v80 <= 32 )
+
+  bool jumping_up = false;
+
+  if ( party_z - floor_level <= 32 )
+  {
     pParty->uFallStartY = party_z;
-  if ( bWalkSound && pParty->field_6F8 > 0 )
-    pParty->field_6F8 -= pEventTimer->uTimeElapsed;
-  if ( party_z > v80 + 1 )
-  {
-    if ( bJumping )
-      goto LABEL_45;
-    goto LABEL_44;
-  }
-  party_z = v80 + 1;
-  pParty->uFallStartY = v80 + 1;
-  if ( bJumping )
-    goto LABEL_45;
-  if (pParty->field_6F4_packedid != uFaceID)
-  {
-    auto pFace = &pIndoor->pFaces[uFaceID];
-    if (pFace->uAttributes & 0x04000000 )
-    {
-      uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
-      if ( bJumping )
-        goto LABEL_45;
-      goto LABEL_44;
-    }
-  }
-LABEL_44:
-  pParty->field_6F4_packedid = uFaceID;
-LABEL_45:
-  v68 = uFaceID;
-  if ( pIndoor->pFaces[uFaceID].uAttributes & 0x10 )
-    v71 = 1;
+    jumping_up = true;
+  }
+
+  if (bWalkSound && pParty->walk_sound_timer)
+  {
+    if (pParty->walk_sound_timer > pEventTimer->uTimeElapsed)
+      pParty->walk_sound_timer -= pEventTimer->uTimeElapsed;
+    else pParty->walk_sound_timer = 0;
+  }
+
+
+  if (party_z <= floor_level + 1)
+  {
+    party_z = floor_level + 1;
+    pParty->uFallStartY = floor_level + 1;
+
+    if (!bJumping && pParty->floor_face_pid != uFaceID)
+    {
+      auto pFace = &pIndoor->pFaces[uFaceID];
+      if (pFace->uAttributes & FACE_PRESSURE_PLATE)
+        uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
+    }
+  }
+  if (!bJumping)
+    pParty->floor_face_pid = uFaceID;
+
+  bool on_water = false;
+  if ( pIndoor->pFaces[uFaceID].Fluid())
+    on_water = true;
+
   v81 = pParty->uWalkSpeed;
   angle = pParty->sRotationY;
   _view_angle = pParty->sRotationX;
-  v82 = (unsigned __int64)(pEventTimer->dt_in_some_format
-                         * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi)
+  v82 = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi)
                                           / 180)) >> 16;
 //LABEL_87:
   while ( pPartyActionQueue->uNumActions )
@@ -1737,43 +1739,32 @@
     switch ( pPartyActionQueue->Next() )
     {
       case PARTY_TurnLeft:
-        if ( uTurnSpeed )
-        {
-          v14 = angle + uTurnSpeed;
-          angle = stru_5C6E00->uDoublePiMask & v14;
-          break;
-        }
-        v14 = angle + (unsigned __int64)(signed __int64)(double)v82 * fTurnSpeedMultiplier;
-        angle = stru_5C6E00->uDoublePiMask & v14;
+        if (uTurnSpeed)
+          angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed);
+        else
+          angle = stru_5C6E00->uDoublePiMask & (angle + (int)(v82 * fTurnSpeedMultiplier));
         break;
       case PARTY_TurnRight:
-        if ( uTurnSpeed )
-        {
+        if (uTurnSpeed)
           angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed);
-          break;
-        }
-        v16 = (double)v82 * fTurnSpeedMultiplier;
-        angle = stru_5C6E00->uDoublePiMask & (angle - (signed __int64)v16);
+        else
+          angle = stru_5C6E00->uDoublePiMask & (angle - (int)(v82 * fTurnSpeedMultiplier));
         break;
+
       case PARTY_FastTurnLeft:
-        if ( uTurnSpeed )
-        {
-          v14 = angle + uTurnSpeed;
-        }
+        if (uTurnSpeed)
+          angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed);
         else
-        {
-          v14 = angle + (unsigned __int64)(signed __int64)(fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)v82;
-        }
-        angle = stru_5C6E00->uDoublePiMask & v14;
+          angle = stru_5C6E00->uDoublePiMask & (angle + (int)(2.0f * fTurnSpeedMultiplier * (double)v82));
         break;
+
       case PARTY_FastTurnRight:
-        LODWORD(v15) = uTurnSpeed;
-        if ( !uTurnSpeed )
-        {
-          v15 = (signed __int64)(fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)v82;
-        }
-        angle = stru_5C6E00->uDoublePiMask & (angle - v15);
+        if (uTurnSpeed)
+          angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed);
+        else
+          angle = stru_5C6E00->uDoublePiMask & (angle - (int)(2.0f * fTurnSpeedMultiplier * (double)v82));
         break;
+
       case PARTY_StrafeLeft:
         v2 -= (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
         v1 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
@@ -1785,8 +1776,8 @@
         v78 = 1;
         break;
       case PARTY_WalkForward:
-        v2 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier)) >> 16;
-        v1 += (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier)) >> 16;
+        v2 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(signed __int64)(5 * (double)v81 * fWalkSpeedMultiplier)) >> 16;
+        v1 += (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(signed __int64)(5 * (double)v81 * fWalkSpeedMultiplier)) >> 16;
         v78 = 1;
         break;
       case PARTY_WalkBackward:
@@ -1828,7 +1819,7 @@
         _view_angle = 0;
         break;
       case PARTY_Jump:
-        if ( (!bJumping || party_z <= v80 + 6 && pParty->uFallSpeed <= 0) && pParty->field_24 )
+        if ( (!bJumping || party_z <= floor_level + 6 && pParty->uFallSpeed <= 0) && pParty->field_24 )
         {
           bJumping = 1;
           pParty->uFallSpeed = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)pParty->uFallSpeed);
@@ -1847,7 +1838,7 @@
   }
   else
   {
-    if ( pIndoor->pFaces[v68].pFacePlane_old.vNormal.z < 32768 )
+    if ( pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 32768 )
     {
       pParty->uFallSpeed -= pEventTimer->uTimeElapsed * GetGravityStrength();
       goto LABEL_92;
@@ -1863,8 +1854,8 @@
       v41 = &pPlayers[1];
       do
       {
-        if ( !(*v41)->HasEnchantedItemEquipped(72) && !(*v41)->WearsItem(529, 8) )
-          (*v41)->PlayEmotion(CHARACTER_EXPRESSION_46, 0);
+        if ( !(*v41)->HasEnchantedItemEquipped(72) && !(*v41)->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, 8) )
+          (*v41)->PlayEmotion(CHARACTER_EXPRESSION_SCARED, 0);
         ++v41;
       }
       while ( (signed int)v41 <= (signed int)&pPlayers[4] );
@@ -1980,7 +1971,7 @@
             v1 = 0;
             v2 = 0;
           }
-          if ( pParty->field_6F4_packedid != v43 >> 3 && BYTE3(v44->uAttributes) & 4 )
+          if ( pParty->floor_face_pid != PID_ID(v43) && BYTE3(v44->uAttributes) & 4 )
             uFaceEvent = pIndoor->pFaceExtras[v44->uFaceExtraID].uEventID;
           goto LABEL_152;
         }
@@ -2012,7 +2003,7 @@
             v87 += v52 * v74 >> 16;
           }
           v43 = stru_721530.uFaceID;
-          if ( pParty->field_6F4_packedid != v43 >> 3 && BYTE3(v44->uAttributes) & 4 )
+          if ( pParty->floor_face_pid != PID_ID(v43) && BYTE3(v44->uAttributes) & 4 )
             uFaceEvent = pIndoor->pFaceExtras[v44->uFaceExtraID].uEventID;
           goto LABEL_152;
         }
@@ -2030,7 +2021,7 @@
         if ( v2 * v2 + v1 * v1 >= 400 )
         {
           v43 = stru_721530.uFaceID;
-          if ( pParty->field_6F4_packedid != v43 >> 3 && BYTE3(v44->uAttributes) & 4 )
+          if ( pParty->floor_face_pid != PID_ID(v43) && BYTE3(v44->uAttributes) & 4 )
             uFaceEvent = pIndoor->pFaceExtras[v44->uFaceExtraID].uEventID;
           goto LABEL_152;
         }
@@ -2050,13 +2041,13 @@
       break;
     }
   }
-  if ( bWalkSound && pParty->field_6F8 <= 0 )
+  if ( bWalkSound && !pParty->walk_sound_timer)
   {
     if ( integer_sqrt((pParty->vPosition.x - new_party_x) * (pParty->vPosition.x - new_party_x) + (pParty->vPosition.y - new_party_y)
          * (pParty->vPosition.y - new_party_y) + (pParty->vPosition.z - new_party_z)
          * (pParty->vPosition.z - new_party_z)) <= 16 )
       goto LABEL_188;
-    if ( v72 && (!bJumping || bFeatherFall) )
+    if ( v72 && (!bJumping || jumping_up) )
     {
       v66 = 0;
       v64 = 0;
@@ -2065,7 +2056,7 @@
       v60 = -1;
       v59 = 1;
       v58 = 804;
-      if ( !v71 )
+      if ( !on_water )
       {
         v56 = pAudioPlayer;
         if ( BYTE2(pIndoor->pFaces[uFaceID].uAttributes) & 0x20 )
@@ -2078,7 +2069,7 @@
       v56 = pAudioPlayer;
       goto LABEL_175;
     }
-    if ( v78 && (!bJumping || bFeatherFall) )
+    if ( v78 && (!bJumping || jumping_up) )
     {
       v66 = 0;
       v64 = 0;
@@ -2087,7 +2078,7 @@
       v60 = -1;
       v59 = 1;
       v58 = 804;
-      if ( v71 )
+      if ( on_water )
       {
         v57 = (SoundID)102;
         v56 = pAudioPlayer;
@@ -2105,10 +2096,10 @@
     {
 LABEL_188:
       pAudioPlayer->_4AA258(804);
-      pParty->field_6F8 = 64;
-    }
-  }
-  if ( !bJumping || bFeatherFall )
+      pParty->walk_sound_timer = 64;
+    }
+  }
+  if ( !bJumping || jumping_up )
     pParty->uFlags &= ~PARTY_FLAGS_1_FALLING;
   else
     pParty->uFlags |= PARTY_FLAGS_1_FALLING;
@@ -2351,15 +2342,19 @@
     bJumping = 1;
   }
   v101 = pZ - v111 <= 32;
-  if ( bWalkSound && pParty->field_6F8 > 0 )
-    pParty->field_6F8 -= pEventTimer->uTimeElapsed;
+  if ( bWalkSound && pParty->walk_sound_timer)
+  {
+    if (pParty->walk_sound_timer >= pEventTimer->uTimeElapsed)
+      pParty->walk_sound_timer -= pEventTimer->uTimeElapsed;
+    else pParty->walk_sound_timer = 0;
+  }
   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 ( pParty->floor_face_pid != PID(OBJECT_BModel, v108) )
     {
       if (v108)
       {
@@ -2374,13 +2369,13 @@
           }*/
 		  if ( BYTE3(v7[v6].uAttributes) & 4 )
           {
-            pParty->field_6F4_packedid = 8 * v108 | OBJECT_BModel;
+            pParty->floor_face_pid = PID(OBJECT_BModel, v108);
             v103 = v7[v6].sCogTriggeredID;
           }
         }
       }
     }
-    pParty->field_6F4_packedid = 8 * v108 | OBJECT_BModel;
+    pParty->floor_face_pid = PID(OBJECT_BModel, v108);
   }
   _walk_speed = pParty->uWalkSpeed;
   _angle_y = pParty->sRotationY;
@@ -2955,9 +2950,9 @@
 LABEL_220:
           v45 = stru_721530.uFaceID;
 LABEL_221:
-          if ( pParty->field_6F4_packedid != v45 && BYTE3(v47->uAttributes) & 4 )
-          {
-            pParty->field_6F4_packedid = v45;
+          if ( pParty->floor_face_pid != v45 && BYTE3(v47->uAttributes) & 4 )
+          {
+            pParty->floor_face_pid = v45;
             v103 = v47->sCogTriggeredID;
           }
           goto LABEL_234;
@@ -2990,7 +2985,7 @@
     v121 = (unsigned __int64)(58500i64 * v121) >> 16;
   }
   while ( v126 < 100 );
-  if ( bWalkSound && pParty->field_6F8 <= 0 )
+  if ( bWalkSound && pParty->walk_sound_timer <= 0 )
   {
     v122 = abs(pParty->vPosition.x - pX);
     v126 = abs(pParty->vPosition.y - pY);
@@ -3000,7 +2995,7 @@
     if ( v114 && (!bJumping || v101) )
     {
       if ( !v107
-        && !(BYTE1(pOutdoor->pBModels[pParty->field_6F4_packedid >> 9].pFaces[(pParty->field_6F4_packedid >> 3) & 0x3F].uAttributes) & 0x20) )
+        && !(BYTE1(pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].uAttributes) & 0x20) )
       {
         
         v90 = -1;
@@ -3023,7 +3018,7 @@
     if ( v124 && (!bJumping || v101) )
     {
       if ( v107
-        || BYTE1(pOutdoor->pBModels[pParty->field_6F4_packedid >> 9].pFaces[(pParty->field_6F4_packedid >> 3) & 0x3F].uAttributes) & 0x20 )
+        || BYTE1(pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].uAttributes) & 0x20 )
       {
         
         v90 = -1;
@@ -3043,7 +3038,7 @@
     {
 LABEL_344:
       pAudioPlayer->_4AA258(804);
-      pParty->field_6F8 = 64;
+      pParty->walk_sound_timer = 64;
     }
   }
   if ( !bJumping || v101 )
@@ -3177,10 +3172,10 @@
     }
     goto LABEL_318;
   }
-  if ( bWalkSound && pParty->field_6F8 <= 0 )
+  if ( bWalkSound && pParty->walk_sound_timer <= 0 )
   {
     pAudioPlayer->_4AA258(804);
-    pParty->field_6F8 = 64;
+    pParty->walk_sound_timer = 64;
   }
 LABEL_318:
   v81 = pZ;
--- a/mm7_data.cpp	Wed Mar 27 11:59:37 2013 +0200
+++ b/mm7_data.cpp	Wed Mar 27 15:04:59 2013 +0200
@@ -1402,7 +1402,7 @@
 int ai_arrays_size; // weak
 int ai_near_actors_distances[500];
 unsigned int ai_near_actors_ids[500];
-int dword_4F8580[182]; // weak
+int dword_4F8580[121]; // weak
 int dword_4FA9B0[777]; // weak
 int dword_4FA9B4[777]; // weak
 char byte_4FAA00; // weak
--- a/mm7_data.h	Wed Mar 27 11:59:37 2013 +0200
+++ b/mm7_data.h	Wed Mar 27 15:04:59 2013 +0200
@@ -1962,7 +1962,7 @@
 void __cdecl UpdateActors_BLV();
 void __cdecl UpdateActors_ODM();
 void __cdecl UpdateObjects();
-int _47272C_collide_agains_some_secotors_floors(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb
+int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb
 void __cdecl BLV_ProcessPartyActions();
 void __cdecl ODM_ProcessPartyActions();
 bool __fastcall sub_47531C(int a1, int *a2, int a3, int a4, int a5, int a6, int a7, int a8, BLVFace *a9, int a10);