changeset 148:77ad59c17864

Слияние
author Ritor1
date Tue, 12 Feb 2013 09:11:19 +0600
parents c70fea5013aa (current diff) 7eeea515f5ff (diff)
children 2b0c652cc165
files Game.cpp Render.cpp mm7_1.cpp mm7_2.cpp mm7_4.cpp mm7_5.cpp
diffstat 23 files changed, 855 insertions(+), 855 deletions(-) [+]
line wrap: on
line diff
--- a/GUIWindow.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/GUIWindow.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -198,10 +198,10 @@
     v13 = pTexture_PlayerFaceDead;
   else
   {
-      uFramesetID = pPlayerFrameTable->GetFrameIdBy_field0(pPlayer->uExpressionID);
+      uFramesetID = pPlayerFrameTable->GetFrameIdByExpression(pPlayer->expression);
       if ( !uFramesetID )
         uFramesetID = 1;
-      if ( pPlayer->uExpressionID == 21 )
+      if ( pPlayer->expression == CHARACTER_EXPRESSION_21)
       {
         v15 = pPlayerFrameTable->GetFrameBy_y(
                 &pPlayer->field_1AA8,
@@ -220,7 +220,7 @@
   pRenderer->DrawTextureTransparent(uFrameX + 24, uFrameY + 24, v13);
   v16 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
   sprintf(pTmpBuf, "\xC%05d", v16);
-  sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], pPlayer->pName, pClassNames[pPlayer->uClass]);
+  sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], pPlayer->pName, pClassNames[pPlayer->classType]);
   strcat(pTmpBuf, pTmpBuf2);
   strcat(pTmpBuf, "\xC" "00000\n");
   v20 = UI_GetHealthManaStringColor(pPlayer->sHealth, pPlayer->GetMaxHealth());
@@ -1884,7 +1884,7 @@
                     pWindow->CreateButton(0x1E0u, a4a++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x13u, 0, "", 0);
                 }
               }
-              v15 = (void *)v12->evtb;
+              v15 = (void *)v12->_anim_current_time;
               if ( v15 )
               {
                 if ( a4a < 4 )
@@ -1894,7 +1894,7 @@
                     pWindow->CreateButton(0x1E0u, a4a++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x14u, 0, "", 0);
                 }
               }
-              v17 = (void *)v12->evtc;
+              v17 = (void *)v12->_anim_end_time;
               if ( v17 )
               {
                 if ( a4a < 4 )
--- a/Game.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/Game.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -1,3 +1,5 @@
+#include <assert.h>
+
 #include "Game.h"
 #include "Party.h"
 #include "IndoorCamera.h"
@@ -104,6 +106,7 @@
         pIndoor->Draw();
       else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
         pOutdoor->Draw();
+      else assert(false);
 
       if (pRenderer->pRenderD3D)
       {
@@ -147,8 +150,8 @@
   pOtherOverlayList->field_3EC = 0;
   viewparams->bRedrawGameUI = v5;
   GameUI_DrawPartySpells();
-  if (v4 || pParty->pHirelings[0].evtc || pParty->pHirelings[1].evtc )
-    DrawHiredNPCs();//Ritor1: it's temporarily
+  if (v4 || pParty->pHirelings[0]._anim_end_time || pParty->pHirelings[1]._anim_end_time )
+    DrawHiredNPCs();
   GameUI_DrawPortraits(v4);
   GameUI_DrawLifeManaBars();
   GameUI_DrawCharacterSelectionFrame();
@@ -161,7 +164,7 @@
     GameUI_DrawTorchlightAndWizardEye();
   }
   GUI_UpdateWindows();
-  pParty->_4909F4();
+  pParty->UpdatePlayersAndHirelingsEmotions();
   ++stru_51076C.field_8;
   dword_5B5924 = 0;
   if (v4)
@@ -1076,7 +1079,7 @@
 {
   if ( !pCurrentScreen && pVisInstance && pRenderer->pRenderD3D )
   {
-    bool r = pVisInstance->_4C05CC(&pVisInstance->stru1, a3, a4);
+    bool r = pVisInstance->PickKeyboard(&pVisInstance->stru1, a3, a4);
 
     if (bOutline)
       OutlineSelection();
@@ -1084,6 +1087,18 @@
   }
   return false;
 }
+/*
+Result::Code Game::PickKeyboard(bool bOutline, struct unnamed_F93E6C *a3, struct unnamed_F93E6C *a4)
+{
+ if (dword_4E28F8_PartyCantJumpIfTrue)
+   return Result::Generic;
+
+ pVis->PickKeyboard(a3, a4);
+ if (bOutline)
+   Game_outline_selection((int)this);
+ return Result::Success;
+}
+*/
 // 4E28F8: using guessed type int pCurrentScreen;
 
 //----- (0044EB5A) --------------------------------------------------------
--- a/NPC.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/NPC.h	Tue Feb 12 09:11:19 2013 +0600
@@ -28,8 +28,8 @@
   int joins;
   int field_24;
   unsigned int bDrawSomeAnim;
-  int evtb;
-  int evtc;
+  int _anim_current_time; //evtb
+  int _anim_end_time; //evtc
   int evtd;
   int evte;
   int evtf;
--- a/Outdoor.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/Outdoor.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -47,13 +47,13 @@
 void OutdoorLocation::ExecDraw(unsigned int bRedraw)
 {
   int v1; // edi@1
-  unsigned int v2; // ebx@1
+  //unsigned int v2; // ebx@1
   int v3; // ST18_4@3
   int v4; // ST04_4@19
   int v5; // eax@19
 
   v1 = 0;
-  v2 = bRedraw;
+  //v2 = bRedraw;
   if ( viewparams->field_54 )
     v1 = 2;
   pIndoorCamera->sRotationX = pParty->sRotationX;
@@ -65,7 +65,7 @@
   pIndoorCamera->field_4C = v1;
   pIndoorCamera->pos.y = pParty->vPosition.y - pParty->y_rotation_granularity * ((stru_5C6E00->SinCos(pParty->sRotationY)) >> 16);
   pIndoorCamera->pos.z = pParty->vPosition.z + pParty->sEyelevel;
-  if ( v2 || pRenderer->pRenderD3D )
+  if (bRedraw || pRenderer->pRenderD3D)
   {
     ResetStru148s();
     pOutdoorCamera->RotationToInts();
@@ -73,7 +73,7 @@
   }
   pIndoorCamera->uMapGridCellX = WorldPosToGridCellX(pParty->vPosition.x);
   pIndoorCamera->uMapGridCellZ = WorldPosToGridCellZ(pParty->vPosition.y);
-  if ( v2 )
+  if (bRedraw)
   {
     Software_ResetNewEdges();
     sub_487DA9();
@@ -84,7 +84,7 @@
     pOutdoor->UpdateSunlightVectors();
   pOutdoor->UpdateFog();
   pGame->pIndoorCameraD3D->Reset_list_0037C();
-  if ( !v2 )
+  if (!bRedraw)
   {
     if ( !pRenderer->pRenderD3D )
     {
@@ -97,7 +97,7 @@
 		pRenderer->RenderTerrainD3D();//pRenderer->DrawBezierTerrain();// Ritor1: temporarily lag
 	}
   }
-  else if ( pRenderer->pRenderD3D )
+  else if (pRenderer->pRenderD3D)
   {
     pRenderer->DrawSkyD3D();
     pRenderer->DrawBuildingsD3D();
@@ -119,7 +119,7 @@
   }
   pGame->PushStationaryLights(-1);
   pGame->PrepareBloodsplats();
-  if ( v2 )
+  if (bRedraw)
   {
     v4 = WorldPosToGridCellZ(pParty->vPosition.y);
     v5 = WorldPosToGridCellX(pParty->vPosition.x);
@@ -147,12 +147,11 @@
 //----- (00441CFF) --------------------------------------------------------
 void OutdoorLocation::Draw()
 {
-  unsigned int v0; // ecx@1
+  bool redrawWorld = true;
+  if ( !(pParty->uFlags & 2) && !(pGame->uFlags2 & 1) )
+    redrawWorld = false;
+  pOutdoor->ExecDraw(redrawWorld);
 
-  v0 = 1;
-  if ( !(pParty->uFlags & 2) && !(pGame->uFlags2 & 1) )
-    v0 = 0;
-  pOutdoor->ExecDraw(v0);
   pGame->DrawParticles();
   pWeather->Draw();
   array_5118E8._440F07();
@@ -316,7 +315,7 @@
   signed int v11; // eax@23
   int v12; // ST14_4@25
   signed int v14; // [sp-4h] [bp-84h]@6
-  char Str; // [sp+8h] [bp-78h]@3
+  char Str[140]; // [sp+8h] [bp-78h]@3
   int a5a; // [sp+94h] [bp+14h]@3
 
   auto Source = this;
@@ -324,9 +323,9 @@
   v5 = Source;
   if ( a5 < 10
     || strlen(Source->pLevelFilename) != 9
-    || (strcpy(&Str, v5->pLevelFilename),
-        _strlwr(&Str),
-        v6 = strtok(&Str, "out"),
+    || (strcpy(Str, v5->pLevelFilename),
+        _strlwr(Str),
+        v6 = strtok(Str, "out"),
         v6[2] = 0,
         v7 = atoi(v6),
         v8 = v7,
--- a/Party.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/Party.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -1,3 +1,5 @@
+#include <assert.h>
+
 #include "Party.h"
 #include "MapInfo.h"
 #include "Time.h"
@@ -278,7 +280,7 @@
 {
   Party *pParty; // esi@1
   signed __int16 v3; // ax@1
-  int pResMagicBase; // ecx@1
+  //int pResMagicBase; // ecx@1
   Player *pCharacter; // esi@3
   signed int uSpellBookPageCount; // edx@5
   int pMagicSkills; // eax@5
@@ -296,7 +298,14 @@
   signed int uNumPlayers; // [sp+18h] [bp-28h]@1
   ItemGen Dst; // [sp+1Ch] [bp-24h]@10
 
+
   pParty = this;
+
+  pHireling1Name[0] = 0;
+  pHireling2Name[0] = 0;
+  pParty->field_709 = 0;
+  memset(pHirelings, 0, 2 * sizeof(*pHirelings));
+
   strcpy(this->pPlayers[0].pName, pGlobalTXT_LocalizationStrings[509]); //Zoltan
   pParty->pPlayers[0].field_1928 = 17;
   pParty->pPlayers[0].uFace = 17;
@@ -309,10 +318,10 @@
   pParty->pPlayers[0].uAccuracy = 13;
   pParty->pPlayers[0].uSpeed = 14;
   pParty->pPlayers[0].uLuck = 7;
-  pParty->pPlayers[0].pActiveSkills[9] = 1;         // leather
-  pParty->pPlayers[0].pActiveSkills[33] = 1;        // armsmaster
-  pParty->pPlayers[0].pActiveSkills[5] = 1;         // bow
-  pParty->pPlayers[0].pActiveSkills[1] = 1;         // sword
+  pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_LEATHER] = 1;         // leather
+  pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_ARMSMASTER] = 1;        // armsmaster
+  pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_BOW] = 1;         // bow
+  pParty->pPlayers[0].pActiveSkills[PLAYER_SKILL_SWORD] = 1;         // sword
   pParty->pPlayers[1].field_1928 = 3;
   pParty->pPlayers[1].uFace = 3;
   pParty->pPlayers[1].field_1924 = 3;
@@ -325,10 +334,10 @@
   pParty->pPlayers[1].uAccuracy = 13;
   pParty->pPlayers[1].uSpeed = 13;
   pParty->pPlayers[1].uLuck = 13;
-  pParty->pPlayers[1].pActiveSkills[9] = 1;         // leather
-  pParty->pPlayers[1].pActiveSkills[34] = 1;        // stealing
-  pParty->pPlayers[1].pActiveSkills[2] = 1;         // dagger
-  pParty->pPlayers[1].pActiveSkills[29] = 1;        // disarm trap
+  pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_LEATHER] = 1;         // leather
+  pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_STEALING] = 1;        // stealing
+  pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_DAGGER] = 1;         // dagger
+  pParty->pPlayers[1].pActiveSkills[PLAYER_SKILL_TRAP_DISARM] = 1;        // disarm trap
   pParty->pPlayers[2].field_1928 = 14;
   pParty->pPlayers[2].uFace = 14;
   pParty->pPlayers[2].field_1924 = 14;
@@ -341,15 +350,15 @@
   pParty->pPlayers[2].uAccuracy = 7;
   pParty->pPlayers[2].uSpeed = 13;
   pParty->pPlayers[2].uLuck = 7;
-  pParty->pPlayers[2].pActiveSkills[35] = 1;        // alchemy
-  pParty->pPlayers[2].pActiveSkills[9] = 1;         // leather
-  pParty->pPlayers[2].pActiveSkills[18] = 1;        // body
-  pParty->pPlayers[2].pActiveSkills[6] = 1;         // mace
+  pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_ALCHEMY] = 1;        // alchemy
+  pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_LEATHER] = 1;         // leather
+  pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_BODY] = 1;        // body
+  pParty->pPlayers[2].pActiveSkills[PLAYER_SKILL_MACE] = 1;         // mace
   strcpy(pParty->pPlayers[3].pName, pGlobalTXT_LocalizationStrings[507]); // Alexis
   v3 = 10;
   pParty->pPlayers[3].field_1928 = 10;
   pParty->pPlayers[3].uFace = 10;
-  pResMagicBase = (int)&pParty->pPlayers[0].sResMagicBase;
+  //pResMagicBase = (int)&pParty->pPlayers[0].sResMagicBase;
   pParty->pPlayers[3].uEndurance = 13;
   pParty->pPlayers[3].uAccuracy = 13;
   pParty->pPlayers[3].uSpeed = 13;
@@ -359,17 +368,17 @@
   pParty->pPlayers[3].uIntelligence = 30;
   pParty->pPlayers[3].uWillpower = 9;
   pParty->pPlayers[3].uLuck = 7;
-  pParty->pPlayers[3].pActiveSkills[9] = 1;         // leather
-  pParty->pPlayers[3].pActiveSkills[13] = 1;        // air
-  pParty->pPlayers[3].pActiveSkills[12] = 1;        // fire
-  pParty->pPlayers[3].pActiveSkills[0] = 1;         // staff
-  pCharacter = &pParty->pPlayers[0];
+  pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_LEATHER] = 1;         // leather
+  pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_AIR] = 1;        // air
+  pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_FIRE] = 1;        // fire
+  pParty->pPlayers[3].pActiveSkills[PLAYER_SKILL_STAFF] = 1;         // staff
   //uNumPlayers = 4;
   //while ( 1 )
   for (uNumPlayers = 0; uNumPlayers < 4; uNumPlayers++)
   {
-    if ( !pCharacter->uClass )
-      *(short *)pResMagicBase = v3; //player[i].pResMagicBase
+    pCharacter = &pParty->pPlayers[uNumPlayers];
+    if (pCharacter->classType == PLAYER_CLASS_KNIGHT)
+      pCharacter->sResMagicBase = v3; //player[i].pResMagicBase
     uSpellBookPageCount = 0;
     //pMagicSkills = pPlayers[uNumPlayers].pActiveSkills[12];// Skills
     //while ( !*(short *)pMagicSkills )         //player[i].skillFire
@@ -513,11 +522,11 @@
     }
     pCharacter->sHealth = pCharacter->GetMaxHealth();
     pCharacter->sMana = pCharacter->GetMaxMana();
-    pCharacter++;
+    //pCharacter++;
     //uNumPlayers--;
     //if (!uNumPlayers)
       //break;
-    pResMagicBase = (int)pCharacter;
+    //pResMagicBase = (int)pCharacter;
     v3 = 10;
   }
 }
@@ -559,10 +568,10 @@
   for (uint i = 0; i < 4; ++i)
     ::pPlayers[i + 1] = &pPlayers[i];
 
-  pPlayers[0].Reset(0);
-  pPlayers[1].Reset(4);
-  pPlayers[2].Reset(24);
-  pPlayers[3].Reset(32);
+  pPlayers[0].Reset(PLAYER_CLASS_KNIGHT);
+  pPlayers[1].Reset(PLAYER_CLASS_THEIF);
+  pPlayers[2].Reset(PLAYER_CLASS_CLERIC);
+  pPlayers[3].Reset(PLAYER_CLASS_SORCERER);
   pPlayers[0].uFace = 17;
   pPlayers[0].field_1924 = 17;
   pPlayers[0].uVoiceID = 17;
@@ -740,7 +749,7 @@
     for (uint j = 0; j < 24; ++j)
       pPlayers[i].pPlayerBuffs[j].Reset();
 
-    pPlayers[i].uExpressionID = 1;
+    pPlayers[i].expression = CHARACTER_EXPRESSION_1;
     pPlayers[i].uExpressionTimePassed = 0;
     pPlayers[i].uExpressionTimeLength = rand() % 256 + 128;
   }
@@ -830,7 +839,7 @@
   this->field_14 = 37;
   this->y_rotation_granularity = 25;
   this->uWalkSpeed = 384;
-  this->field_20_prolly_turn_speed = 90;
+  this->y_rotation_speed = 90;
   this->field_24 = 5;
   this->field_6FC = 0;
   this->field_708 = 15;
@@ -864,239 +873,128 @@
 }
 
 //----- (004909F4) --------------------------------------------------------
-void Party::_4909F4()
+void Party::UpdatePlayersAndHirelingsEmotions()
 {
-  Player *v1; // esi@2
-  unsigned int v2; // eax@3
-  __int16 v3; // cx@5
+  //Player *v1; // esi@2
+  //unsigned int v2; // eax@3
+  //__int16 v3; // cx@5
   int v4; // edx@27
-  signed int v5; // eax@52
-  PlayerFrame *v6; // edx@53
-  NPCData *v7; // esi@60
-  signed int v8; // ebp@61
-  int v9; // ebx@62
-  unsigned int v10; // edi@62
-  signed int v11; // [sp+0h] [bp-4h]@2
+  //signed int v5; // eax@52
+  //PlayerFrame *v6; // edx@53
+  //NPCData *v7; // esi@60
+  //signed int v8; // ebp@61
+  //int v9; // ebx@62
+  //unsigned int v10; // edi@62
+  //signed int v11; // [sp+0h] [bp-4h]@2
+
+  if (dword_A75070 == stru_51076C.field_8)
+    return;
 
-  if ( dword_A75070 != stru_51076C.field_8 )
+  dword_A75070 = stru_51076C.field_8;
+  //v1 = this->pPlayers;//(char *)&this->pPlayers[0].uExpressionID;
+  for (int i = 0; i < 4; ++i)
   {
-    dword_A75070 = stru_51076C.field_8;
-	v1 = this->pPlayers;//(char *)&this->pPlayers[0].uExpressionID;
-    v11 = 4;
-    do
+    auto player = pPlayers + i;
+    player->uExpressionTimePassed += (unsigned short)pMiscTimer->uTimeElapsed;
+
+
+    auto condition = player->GetMajorConditionIdx();
+    if (condition == Player::Condition_Good || condition == Player::Condition_Zombie)
     {
-      v2 = v1->GetMajorConditionIdx();
-      if ( v2 == 18 || v2 == 17 )
+      if (player->uExpressionTimePassed < player->uExpressionTimeLength)
+        continue;
+        
+      player->uExpressionTimePassed = 0;
+      if (player->expression != 1 || rand() % 5)
       {
-        v1->uExpressionTimePassed += LOWORD(pMiscTimer->uTimeElapsed);
-        if ( (unsigned __int16)v1->uExpressionTimePassed >= v1->uExpressionTimeLength )
-        {
-          if ( v1->uExpressionID != 1 || rand() % 5 )
-          {
-            v1->uExpressionTimePassed = 0;
-            v1->uExpressionID = 1;
-            v1->uExpressionTimeLength = rand() % 256 + 32;
-          }
-          else
-          {
-            v4 = rand() % 100;
-            if ( v4 >= 25 )
-            {
-              if ( v4 >= 31 )
-              {
-                if ( v4 >= 37 )
-                {
-                  if ( v4 >= 43 )
-                  {
-                    if ( v4 >= 46 )
-                    {
-                      if ( v4 >= 52 )
-                      {
-                        if ( v4 >= 58 )
-                        {
-                          if ( v4 >= 64 )
-                          {
-                            if ( v4 >= 70 )
-                            {
-                              if ( v4 >= 76 )
-                              {
-                                if ( v4 >= 82 )
-                                {
-                                  if ( v4 >= 88 )
-                                    v1->uExpressionID = (v4 >= 94) + 29;
-                                  else
-                                    v1->uExpressionID = 57;
-                                }
-                                else
-                                {
-                                  v1->uExpressionID = 56;
-                                }
-                              }
-                              else
-                              {
-                                v1->uExpressionID = 55;
-                              }
-                            }
-                            else
-                            {
-                              v1->uExpressionID = 54;
-                            }
-                          }
-                          else
-                          {
-                            v1->uExpressionID = 20;
-                          }
-                        }
-                        else
-                        {
-                          v1->uExpressionID = 19;
-                        }
-                      }
-                      else
-                      {
-                        v1->uExpressionID = 18;
-                      }
-                    }
-                    else
-                    {
-                      v1->uExpressionID = 17;
-                    }
-                  }
-                  else
-                  {
-                    v1->uExpressionID = 16;
-                  }
-                }
-                else
-                {
-                  v1->uExpressionID = 15;
-                }
-              }
-              else
-              {
-                v1->uExpressionID = 14;
-              }
-            }
-            else
-            {
-              v1->uExpressionID = 13;
-            }
-            v5 = 0;
-            v1->uExpressionTimePassed = 0;
-			if ( (signed int)pPlayerFrameTable->uNumFrames <= 0 )
-            {
-LABEL_56:
-              v5 = 0;
-            }
-            else
-            {
-              v6 = pPlayerFrameTable->pFrames;
-              while ( v6->uSequenceID != v1->uExpressionID )
-              {
-                ++v5;
-                ++v6;
-                if ( v5 >= (signed int)pPlayerFrameTable->uNumFrames )
-                  goto LABEL_56;
-              }
-            }
-            v1->uExpressionTimeLength = 8 * pPlayerFrameTable->pFrames[v5].uAnimLength;
-          }
-        }
+        player->expression = CHARACTER_EXPRESSION_1;
+        player->uExpressionTimeLength = rand() % 256 + 32;
       }
       else
       {
-       v3 = v1->uExpressionID;
-        if ( v1->uExpressionID != 34 && v3 != 35 && v3 != 36
-          || (signed int)(pMiscTimer->uTimeElapsed + v1->uExpressionTimePassed) >= v1->uExpressionTimeLength )
+        v4 = rand() % 100;
+        if (v4 < 25)      player->expression = CHARACTER_EXPRESSION_13;
+        else if (v4 < 31) player->expression = CHARACTER_EXPRESSION_14;
+        else if (v4 < 37) player->expression = CHARACTER_EXPRESSION_15;
+        else if (v4 < 43) player->expression = CHARACTER_EXPRESSION_16;
+        else if (v4 < 46) player->expression = CHARACTER_EXPRESSION_17;
+        else if (v4 < 52) player->expression = CHARACTER_EXPRESSION_18;
+        else if (v4 < 58) player->expression = CHARACTER_EXPRESSION_19;
+        else if (v4 < 64) player->expression = CHARACTER_EXPRESSION_20;
+        else if (v4 < 70) player->expression = CHARACTER_EXPRESSION_54;
+        else if (v4 < 76) player->expression = CHARACTER_EXPRESSION_55;
+        else if (v4 < 82) player->expression = CHARACTER_EXPRESSION_56;
+        else if (v4 < 88) player->expression = CHARACTER_EXPRESSION_57;
+        else if (v4 < 94) player->expression = CHARACTER_EXPRESSION_29;
+        else              player->expression = CHARACTER_EXPRESSION_30;
+      }
+
+      for (int j = 0; j < pPlayerFrameTable->uNumFrames; ++j)
+      {
+        auto frame = pPlayerFrameTable->pFrames + j;
+        if (frame->expression == player->expression)
         {
-          v1->uExpressionTimeLength = 0;
-          v1->uExpressionTimePassed = 0;
-          switch ( v2 )
-          {
-            case 0xEu:
-              v1->uExpressionID = 98;
-              break;
-            case 0xFu:
-              v1->uExpressionID = 12;
-              break;
-            case 0x10u:
-              v1->uExpressionID = 99;
-              break;
-            case 0u:
-              v1->uExpressionID = 2;
-              break;
-            case 1u:
-              v1->uExpressionID = 3;
-              break;
-            case 2u:
-              v1->uExpressionID = 4;
-              break;
-            case 3u:
-              v1->uExpressionID = 5;
-              break;
-            case 4u:
-              v1->uExpressionID = 6;
-              break;
-            case 5u:
-              v1->uExpressionID = 7;
-              break;
-            case 6u:
-            case 8u:
-            case 0xAu:
-              v1->uExpressionID = 8;
-              break;
-            case 7u:
-            case 9u:
-            case 0xBu:
-              v1->uExpressionID = 9;
-              break;
-            case 0xCu:
-              v1->uExpressionID = 10;
-              break;
-            case 0xDu:
-              v1->uExpressionID = 11;
-              break;
-            default:
-              break;
-          }
+          player->uExpressionTimeLength = 8 * pPlayerFrameTable->pFrames[j].uAnimLength;
+          break;
         }
-        else
-        {
-          v1->uExpressionTimePassed += LOWORD(pMiscTimer->uTimeElapsed);        
-		}
       }
-      ++v1;
-      --v11;
     }
-    while ( v11 );
-	v7 = pParty->pHirelings;//(char *)&pParty->pHirelings[0].evtb;
-    do
+    else if (player->expression != 34 &&
+             player->expression != 35 &&
+             player->expression != 36 ||
+             player->uExpressionTimePassed >= player->uExpressionTimeLength)
     {
-	  v8 = v7->evtc;
-      if ( v8 )
+      player->uExpressionTimeLength = 0;
+      player->uExpressionTimePassed = 0;
+
+      switch (condition)
       {
-		v9 = v7->bDrawSomeAnim;
-		v10 = pMiscTimer->uTimeElapsed + v7->evtb;
-        if ( (signed int)v10 >= v8 )
-        {
-          v9 = 0;
-          v8 = 0;
-          v10 = 0;
-          memset(v7, 0, 0x4Cu);
-          pParty->field_709 = 0;
-          //sub_44A56A();Ritor1: it's temporarily
-          viewparams->bRedrawGameUI = 1;
-        }
-		v7->evtb = v10;
-		v7->evtc = v8;
-		v7->bDrawSomeAnim = v9;
+        case Player::Condition_Dead:        player->expression = CHARACTER_EXPRESSION_DEAD;      break;
+        case Player::Condition_Pertified:   player->expression = CHARACTER_EXPRESSION_PERTIFIED; break;
+        case Player::Condition_Eradicated:  player->expression = CHARACTER_EXPRESSION_ERADICATED; break;
+        case Player::Condition_Cursed:      player->expression = CHARACTER_EXPRESSION_CURSED; break;
+        case Player::Condition_Weak:        player->expression = CHARACTER_EXPRESSION_WEAK; break;
+        case Player::Condition_Sleep:       player->expression = CHARACTER_EXPRESSION_SLEEP; break;
+        case Player::Condition_Fear:        player->expression = CHARACTER_EXPRESSION_FEAR; break;
+        case Player::Condition_Drunk:       player->expression = CHARACTER_EXPRESSION_DRUNK; break;
+        case Player::Condition_Insane:      player->expression = CHARACTER_EXPRESSION_INSANE; break;
+        case Player::Condition_Poison1:
+        case Player::Condition_Poison2:
+        case Player::Condition_Poison3:     player->expression = CHARACTER_EXPRESSION_POISONED; break;
+        case Player::Condition_Disease1:
+        case Player::Condition_Disease2:
+        case Player::Condition_Disease3:    player->expression = CHARACTER_EXPRESSION_DISEASED; break;
+        case Player::Condition_Paralyzed:   player->expression = CHARACTER_EXPRESSION_PARALYZED; break;
+        case Player::Condition_Unconcious:  player->expression = CHARACTER_EXPRESSION_UNCONCIOUS; break;
+        default:
+          assert(false);
       }
-      ++v7;
     }
-	while ( v7 <= &pParty->pHirelings[1] );
+  }
+
+
+  for (int i = 0; i < 2; ++i)
+  {
+    auto hireling = pParty->pHirelings + i;
+    if (!hireling->_anim_end_time)
+      continue;
+
+    hireling->_anim_current_time += pMiscTimer->uTimeElapsed;
+    if (hireling->_anim_current_time >= hireling->_anim_end_time)
+    {
+      hireling->bDrawSomeAnim = false;
+      hireling->_anim_current_time = 0;
+      hireling->_anim_end_time = 0;
+
+      assert(sizeof(NPCData) == 0x4C);
+      memset(hireling, 0, sizeof(*hireling));
+
+      pParty->field_709 = 0;
+      sub_44A56A();
+      viewparams->bRedrawGameUI = 1;
+    }
   }
 }
-// A75070: using guessed type int dword_A75070;
 
 //----- (00490D02) --------------------------------------------------------
 void Party::RestAndHeal()
@@ -1154,7 +1052,7 @@
     v2->uTimeToRecovery = 0;
     v2->sHealth = v2->GetMaxHealth();
     v5 = v2->GetMaxMana();
-    v6 = v2->uClass == 35;
+    v6 = v2->classType == PLAYER_CLASS_LICH;
     v2->sMana = v5;
     if ( v6 )
     {
@@ -1207,7 +1105,7 @@
 LABEL_30:
     if ( v2->pConditions[5] )
       v2->sMana = 0;
-    _4909F4();
+    UpdatePlayersAndHirelingsEmotions();
 LABEL_33:
     ++v15;
   }
--- a/Party.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/Party.h	Tue Feb 12 09:11:19 2013 +0600
@@ -128,10 +128,26 @@
     field_6FC = 0;
     field_764 = 0;
 
-    y_rotation_granularity = 1;
+    vPosition.y = 0;
+    vPosition.z = 0;
+    vPosition.x = 0;
+    uFallStartY = 0;
+    sRotationY = 0;
+    sRotationX = 0;
+    uFallSpeed = 0;
+    field_28 = 0;
+    uDefaultPartyHeight = 120;
+    field_14 = 37;
+    y_rotation_granularity = 25;
+    uWalkSpeed = 384;
+    y_rotation_speed = 90;
+    field_24 = 5;
+    field_6FC = 0;
+    field_708 = 15;
+    field_0 = 25;
   }
 
-  void _4909F4();
+  void UpdatePlayersAndHirelingsEmotions();
   void RestAndHeal();
   unsigned int GetPartyFame();
   void CreateDefaultParty(char bGiveItems);
@@ -168,7 +184,7 @@
   int field_14;
   int y_rotation_granularity;
   unsigned int uWalkSpeed;
-  int field_20_prolly_turn_speed;
+  int y_rotation_speed;  // deg/s
   int field_24;
   int field_28;
   unsigned __int64 uTimePlayed;
--- a/Player.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/Player.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -669,24 +669,24 @@
       if ( pSoundList->pSounds[v17].pSoundData[0] )
         pPlayerNum = (sLastTrackLengthMS << 7) / 1000;
     }
-    LOWORD(v14) = pPlayer2->PlayEmotion(pExpression, pPlayerNum);
+    LOWORD(v14) = pPlayer2->PlayEmotion((CHARACTER_EXPRESSION_ID)pExpression, pPlayerNum);
   }
   return v14;
 }
 // 4948B1: using guessed type int var_1C[5];
 
 //----- (00494A25) --------------------------------------------------------
-__int16 Player::PlayEmotion(int a2, int a3)
+__int16 Player::PlayEmotion(CHARACTER_EXPRESSION_ID expr, int a3)
 {
   signed int v3; // eax@1
-  unsigned __int16 v4; // dx@1
+  CHARACTER_EXPRESSION_ID v4; // dx@1
   signed int v5; // edi@15
   PlayerFrame *v6; // esi@17
   signed int v7; // eax@20
 
-  LOWORD(v3) = this->uExpressionID;
-  v4 = a2;
-  if ( (short)v3 != 4 && (short)v3 != 12 || a2 != 58 )
+  LOWORD(v3) = this->expression;
+  v4 = expr;
+  if ( (short)v3 != 4 && (short)v3 != 12 || expr != 58 )
   {
     v3 = (unsigned __int16)v3;
     if ( (signed int)(unsigned __int16)v3 >= 2 )
@@ -702,7 +702,7 @@
           goto LABEL_15;
         }
 LABEL_12:
-        if ( a2 != 34 && a2 != 35 && a2 != 36 )
+        if ( expr != 34 && expr != 35 && expr != 36 )
           return v3;
         goto LABEL_15;
       }
@@ -723,7 +723,7 @@
     else
     {
       v6 = pPlayerFrameTable->pFrames;
-      while ( v6->uSequenceID != a2 )
+      while ( v6->expression != expr )
       {
         ++v5;
         ++v6;
@@ -732,11 +732,11 @@
       }
       v7 = v5;
     }
-    v4 = a2;
+    v4 = expr;
     LOWORD(v3) = 8 * pPlayerFrameTable->pFrames[v3].uAnimLength;
     this->uExpressionTimeLength = v3;
   }
-  this->uExpressionID = v4;
+  this->expression = v4;
   viewparams->bRedrawGameUI = 1;
   return v3;
 }
@@ -752,7 +752,7 @@
   int v8; // [sp-4h] [bp-Ch]@3
 
   v3 = this;
-  if ( this->uClass == uClass )
+  if ( this->classType == uClass )
   {
 LABEL_84:
     result = 1;
@@ -1300,7 +1300,8 @@
         result = 1;
         break;
       case 0x11u:
-        if ( v3->uClass == 35 || v3->pConditions[16] || v3->pConditions[17] || !v3->pConditions[14] )
+        if ( v3->classType == PLAYER_CLASS_LICH || v3->Eradicated() ||
+            v3->Zombie() || !v3->Dead())
           goto LABEL_76;
         memset(v3, 0, 0xA0u);
         v3->sHealth = v3->GetMaxHealth();
@@ -2279,7 +2280,7 @@
   _ranged_dmg_bonus = 0;
   field_1A97 = 0;
 
-  uExpressionID = 0;
+  expression = CHARACTER_EXPRESSION_INVALID;
   uExpressionTimePassed = 0;
   uExpressionTimeLength = 0;
 
@@ -3276,7 +3277,7 @@
   v4 = 0;
 LABEL_17:
   v18 = type;
-  if ( v3->uClass == 35 && v4 >= 200 )
+  if ( v3->classType == PLAYER_CLASS_LICH && v4 >= 200 )
     return 0;
   if ( v4 )
   {
@@ -4276,9 +4277,9 @@
   int v6; // esi@1
 
   v3 = _48EA1B_get_static_effect(GetActualEndurance());
-  v4 = pBaseHealthPerLevelByClass[uClass] * (GetActualLevel() + v3);
+  v4 = pBaseHealthPerLevelByClass[classType] * (GetActualLevel() + v3);
   v6 = uFullHealthBonus
-     + pBaseHealthByClass[uClass / 4]
+     + pBaseHealthByClass[classType / 4]
      + GetSkillBonus(CHARACTER_ATTRIBUTE_HEALTH)
      + GetItemsBonus(CHARACTER_ATTRIBUTE_HEALTH, 0) + v4;
   if (v6 <= 0)
@@ -4299,7 +4300,7 @@
   int v9; // esi@6
   int result; // eax@7
 
-  switch (uClass)
+  switch (classType)
   {
     case 5u:
     case 6u:
@@ -4341,10 +4342,10 @@
       v6 = GetActualIntelligence();
       v3 = _48EA1B_get_static_effect(v6) + v5;
 LABEL_6:
-      v7 = pBaseManaPerLevelByClass[uClass] * (GetActualLevel() + v3);
+      v7 = pBaseManaPerLevelByClass[classType] * (GetActualLevel() + v3);
       v8 = GetItemsBonus(CHARACTER_ATTRIBUTE_MANA, 0) + v7;
       v9 = uFullManaBonus
-         + pBaseManaByClass[uClass / 4]
+         + pBaseManaByClass[classType / 4]
          + GetSkillBonus(CHARACTER_ATTRIBUTE_MANA)
          + v8;
       if ( v9 < 1 )
@@ -4480,7 +4481,7 @@
   v5 = 0;
 LABEL_20:
   v7 = GetItemsBonus(a2, 0) + v3;
-  if ( v2->uClass != 35 || (result = 200, v7 + *(&v2->sResFireBase + v5) <= 200) )
+  if ( v2->classType != PLAYER_CLASS_LICH || (result = 200, v7 + *(&v2->sResFireBase + v5) <= 200) )
     result = v7 + *(&v2->sResFireBase + v5);
   return result;
 }
@@ -4554,7 +4555,7 @@
 LABEL_28:
   v7 = GetItemsBonus(a2, 0);
   result = v10 + GetMagicalBonus(a2) + v7 + v9 + *(&v3->sResFireBonus + v2) + *(&v3->sResFireBase + v2);
-  if ( v3->uClass == 35 )
+  if ( v3->classType == PLAYER_CLASS_LICH )
   {
     if ( result > 200 )
       result = 200;
@@ -5741,7 +5742,7 @@
         }
         if ( CheckHiredNPCSpeciality(v5) )
           v2 += 4;
-        if ( v9->uClass == 31 && sub_476387() )
+        if ( v9->classType == PLAYER_CLASS_31 && sub_476387() )
           v2 += 3;
 LABEL_86:
         if ( uSkillType <= PLAYER_SKILL_DARK )
@@ -6016,13 +6017,13 @@
 LABEL_12:
   if ( a2 == CHARACTER_ATTRIBUTE_HEALTH )
   {
-    v60 = pBaseHealthPerLevelByClass[v2->uClass];
+    v60 = pBaseHealthPerLevelByClass[v2->classType];
     v61 = v2->GetBodybuilding();
     return v60 * v61;
   }
   if ( a2 == CHARACTER_ATTRIBUTE_MANA )
   {
-    v60 = pBaseManaPerLevelByClass[v2->uClass];
+    v60 = pBaseManaPerLevelByClass[v2->classType];
     v61 = v2->GetMediatation();
     return v60 * v61;
   }
@@ -6491,12 +6492,12 @@
 }
 
 //----- (0049024A) --------------------------------------------------------
-void Player::Reset(unsigned __int8 classID)
+void Player::Reset(PLAYER_CLASS_TYPE cls)
 {
   sLevelModifier = 0;
   sAgeModifier = 0;
 
-  uClass = classID;
+  classType = cls;
   uLuckBonus = 0;
   uSpeedBonus = 0;
   uAccuracyBonus = 0;
@@ -6513,7 +6514,7 @@
 
   for (uint i = 0; i < 37; ++i)
   {
-    if (pSkillAvailabilityPerClass[uClass / 4][i] != 2)
+    if (pSkillAvailabilityPerClass[classType / 4][i] != 2)
       continue;
 
     pActiveSkills[i] = 1;
@@ -6556,7 +6557,7 @@
       pActiveSkill = this->pActiveSkills;
       do
       {
-        if ( *pActiveSkill && pSkillAvailabilityPerClass[uClass / 4][result] == 2 )
+        if ( *pActiveSkill && pSkillAvailabilityPerClass[classType / 4][result] == 2 )
         {
           if ( v7 == order )
             return result;
@@ -6576,7 +6577,7 @@
         pActiveSkill = this->pActiveSkills;
         do
         {
-          if ( *pActiveSkill && pSkillAvailabilityPerClass[uClass / 4][result] == 1 )
+          if ( *pActiveSkill && pSkillAvailabilityPerClass[classType / 4][result] == 1 )
           {
             if ( v5 == order - 2 )
               return result;
@@ -6593,7 +6594,7 @@
         {
           result = (PLAYER_SKILL_TYPE)0;
           v3 = 0;
-          v4 = (char *)pSkillAvailabilityPerClass[uClass / 4];
+          v4 = (char *)pSkillAvailabilityPerClass[classType / 4];
           do
           {
             if ( *v4 == 1 )
@@ -7973,7 +7974,7 @@
           v7 = (CHARACTER_RACE)this->uSex;
           goto _cmp_against_arg2;
         case VAR_Class:
-          v7 = (CHARACTER_RACE)this->uClass;
+          v7 = (CHARACTER_RACE)this->classType;
           goto _cmp_against_arg2;
         case VAR_Race:
           v7 = GetRace();
@@ -8453,7 +8454,7 @@
           this->uSex = (PLAYER_SEX)a3;
           goto LABEL_124;
         case VAR_Class:
-          this->uClass = a3;
+          this->classType = (PLAYER_CLASS_TYPE)a3;
           if ( (char)a3 != 35 )
             goto LABEL_124;
           v8 = 0;
@@ -8863,7 +8864,7 @@
               Dst->uSex = (PLAYER_SEX)val;
               goto _play_anim_and_exit;
             case VAR_Class:
-              Dst->uClass = val;
+              Dst->classType = (PLAYER_CLASS_TYPE)val;
               goto _play_anim_and_exit;
             case VAR_CurrentHP:
               v8 = &Dst->sHealth;
--- a/Player.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/Player.h	Tue Feb 12 09:11:19 2013 +0600
@@ -25,6 +25,8 @@
   CHARACTER_LUCK = 0x6,
 };
 
+
+
 /*  332 */
 enum CHARACTER_ATTRIBUTE_TYPE
 {
@@ -58,25 +60,25 @@
 /*  328 */
 enum PLAYER_SKILL_TYPE
 {
-  PLAYER_SKILL_STAFF = 0x0,
-  PLAYER_SKILL_SWORD = 0x1,
-  PLAYER_SKILL_DAGGER = 0x2,
-  PLAYER_SKILL_AXE = 0x3,
-  PLAYER_SKILL_SPEAR = 0x4,
-  PLAYER_SKILL_BOW = 0x5,
-  PLAYER_SKILL_MACE = 0x6,
-  PLAYER_SKILL_BLASTER = 0x7,
-  PLAYER_SKILL_SHIELD = 0x8,
-  PLAYER_SKILL_LEATHER = 0x9,
-  PLAYER_SKILL_CHAIN = 0xA,
-  PLAYER_SKILL_PLATE = 0xB,
-  PLAYER_SKILL_FIRE = 0xC,
-  PLAYER_SKILL_AIR = 0xD,
-  PLAYER_SKILL_WATER = 0xE,
-  PLAYER_SKILL_EARTH = 0xF,
-  PLAYER_SKILL_SPIRIT = 0x10,
+  PLAYER_SKILL_STAFF = 0,
+  PLAYER_SKILL_SWORD = 1,
+  PLAYER_SKILL_DAGGER = 2,
+  PLAYER_SKILL_AXE = 3,
+  PLAYER_SKILL_SPEAR = 4,
+  PLAYER_SKILL_BOW = 5,
+  PLAYER_SKILL_MACE = 6,
+  PLAYER_SKILL_BLASTER = 7,
+  PLAYER_SKILL_SHIELD = 8,
+  PLAYER_SKILL_LEATHER = 9,
+  PLAYER_SKILL_CHAIN = 10,
+  PLAYER_SKILL_PLATE = 11,
+  PLAYER_SKILL_FIRE = 12,
+  PLAYER_SKILL_AIR = 13,
+  PLAYER_SKILL_WATER = 14,
+  PLAYER_SKILL_EARTH = 15,
+  PLAYER_SKILL_SPIRIT = 16,
   PLAYER_SKILL_MIND = 0x11,
-  PLAYER_SKILL_BODY = 0x12,
+  PLAYER_SKILL_BODY = 18,
   PLAYER_SKILL_LIGHT = 0x13,
   PLAYER_SKILL_DARK = 0x14,
   PLAYER_SKILL_ITEM_ID = 0x15,
@@ -87,31 +89,32 @@
   PLAYER_SKILL_PERCEPTION = 0x1A,
   PLAYER_SKILL_DIPLOMACY = 0x1B,
   PLAYER_SKILL_TIEVERY = 0x1C,
-  PLAYER_SKILL_TRAP_DISARM = 0x1D,
+  PLAYER_SKILL_TRAP_DISARM = 29,
   PLAYER_SKILL_DODGE = 0x1E,
   PLAYER_SKILL_UNARMED = 0x1F,
   PLAYER_SKILL_MONSTER_ID = 0x20,
-  PLAYER_SKILL_ARMSMASTER = 0x21,
-  PLAYER_SKILL_STEALING = 0x22,
-  PLAYER_SKILL_ALCHEMY = 0x23,
+  PLAYER_SKILL_ARMSMASTER = 33,
+  PLAYER_SKILL_STEALING = 34,
+  PLAYER_SKILL_ALCHEMY = 35,
   PLAYER_SKILL_LEARNING = 0x24,
 };
 
 /*  329 */
-enum PLAYER_CLASS_TYPE
+enum PLAYER_CLASS_TYPE: unsigned __int8
 {
-  PLAYER_CLASS_KNIGHT = 0x0,
-  PLAYER_CLASS_THEIF = 0x4,
+  PLAYER_CLASS_KNIGHT = 0,
+  PLAYER_CLASS_THEIF = 4,
   PLAYER_CLASS_BOUNTY_HUNTER = 0x7,
   PLAYER_CLASS_MONK = 0x8,
   PLAYER_CLASS_PALADIN = 0xC,
   PLAYER_CLASS_SHOOTER = 0x10,
   PLAYER_CLASS_RANGER = 0x14,
-  PLAYER_CLASS_CLERIC = 0x18,
+  PLAYER_CLASS_CLERIC = 24,
   PLAYER_CLASS_PRIEST_OF_MOON = 0x1B,
-  PLAYER_CLASS_DRUID = 0x1C,
-  PLAYER_CLASS_SORCERER = 0x20,
-  PLAYER_CLASS_LICH = 0x23,
+  PLAYER_CLASS_DRUID = 28,
+  PLAYER_CLASS_31 = 31,
+  PLAYER_CLASS_SORCERER = 32,
+  PLAYER_CLASS_LICH = 35,
 };
 
 
@@ -201,6 +204,65 @@
 
 
 
+enum CHARACTER_EXPRESSION_ID: unsigned __int16
+{
+  CHARACTER_EXPRESSION_INVALID = 0,
+  CHARACTER_EXPRESSION_1 = 1,
+  CHARACTER_EXPRESSION_CURSED = 2,
+  CHARACTER_EXPRESSION_WEAK = 3,
+  CHARACTER_EXPRESSION_SLEEP = 4,
+  CHARACTER_EXPRESSION_FEAR = 5,
+  CHARACTER_EXPRESSION_DRUNK = 6,
+  CHARACTER_EXPRESSION_INSANE = 7,
+  CHARACTER_EXPRESSION_POISONED = 8,
+  CHARACTER_EXPRESSION_DISEASED = 9,
+  CHARACTER_EXPRESSION_PARALYZED = 10,
+  CHARACTER_EXPRESSION_UNCONCIOUS = 11,
+  CHARACTER_EXPRESSION_PERTIFIED = 12,
+  CHARACTER_EXPRESSION_13 = 13,
+  CHARACTER_EXPRESSION_14 = 14,
+  CHARACTER_EXPRESSION_15 = 15,
+  CHARACTER_EXPRESSION_16 = 16,
+  CHARACTER_EXPRESSION_17 = 17,
+  CHARACTER_EXPRESSION_18 = 18,
+  CHARACTER_EXPRESSION_19 = 19,
+  CHARACTER_EXPRESSION_20 = 20,
+  CHARACTER_EXPRESSION_21 = 21,
+  CHARACTER_EXPRESSION_22 = 22,
+  CHARACTER_EXPRESSION_23 = 23,
+  CHARACTER_EXPRESSION_24 = 24,
+  CHARACTER_EXPRESSION_25 = 25,
+  CHARACTER_EXPRESSION_26 = 26,
+  CHARACTER_EXPRESSION_27 = 27,
+  CHARACTER_EXPRESSION_28 = 28,
+  CHARACTER_EXPRESSION_29 = 29,
+  CHARACTER_EXPRESSION_30 = 30,
+  CHARACTER_EXPRESSION_31 = 31,
+  CHARACTER_EXPRESSION_32 = 32,
+  CHARACTER_EXPRESSION_33 = 33,
+  CHARACTER_EXPRESSION_34 = 34,
+  CHARACTER_EXPRESSION_35 = 35,
+  CHARACTER_EXPRESSION_36 = 36,
+  CHARACTER_EXPRESSION_37 = 37,
+  CHARACTER_EXPRESSION_38 = 38,
+  CHARACTER_EXPRESSION_39 = 39,
+  
+  // ?
+
+  CHARACTER_EXPRESSION_46 = 46,
+
+  CHARACTER_EXPRESSION_54 = 54,
+  CHARACTER_EXPRESSION_55 = 55,
+  CHARACTER_EXPRESSION_56 = 56,
+  CHARACTER_EXPRESSION_57 = 57,
+
+  // ?
+
+  CHARACTER_EXPRESSION_DEAD = 98,
+  CHARACTER_EXPRESSION_ERADICATED = 99,
+};
+
+
 enum PLAYER_SEX: unsigned __int8
 {
   SEX_MALE = 0,
@@ -220,7 +282,7 @@
     Condition_Insane = 5,
     Condition_Poison1 = 6,
     Condition_Disease1 = 7,
-    Condition_Posion2 = 8,
+    Condition_Poison2 = 8,
     Condition_Disease2 = 9,
     Condition_Poison3 = 10,
     Condition_Disease3 = 11,
@@ -304,7 +366,7 @@
   int GetSexByVoice();
   void SetInitialStats();
   int SetSexByVoice();
-  void Reset(unsigned __int8 uClass);
+  void Reset(PLAYER_CLASS_TYPE classType);
   enum PLAYER_SKILL_TYPE GetSkillIdxByOrder(signed int order);
   void DecreaseAttribute(int eAttribute);
   int IncreaseAttribute(int eAttribute);
@@ -336,7 +398,7 @@
   int SetCondition(unsigned int uConditionIdx, int a3);
   int _49327B(unsigned int uClass, int a3);
   __int16 PlaySound(int a2, int a3);
-  __int16 PlayEmotion(int a2, int a3);
+  __int16 PlayEmotion(CHARACTER_EXPRESSION_ID expression, int a3);
   char _4160CA(int a2);
   unsigned int GetItemIDAtInventoryIndex(int *a2);
   int _4B6FF9();
@@ -357,6 +419,7 @@
 
   inline bool Dead()       {return pConditions[Condition::Condition_Dead] != 0;}
   inline bool Eradicated() {return pConditions[Condition::Condition_Eradicated] != 0;}
+  inline bool Zombie()     {return pConditions[Condition::Condition_Zombie] != 0;}
 
 
 
@@ -364,7 +427,7 @@
   unsigned __int64 uExperience;
   char pName[16];
   PLAYER_SEX uSex;
-  unsigned __int8 uClass;
+  PLAYER_CLASS_TYPE classType;
   unsigned __int8 uFace;
   char field_BB;
   unsigned __int16 uMight;
@@ -499,7 +562,7 @@
   char _health_related;
   char uFullManaBonus;
   char _mana_related;
-  unsigned __int16 uExpressionID;
+  CHARACTER_EXPRESSION_ID expression;
   unsigned __int16 uExpressionTimePassed;
   unsigned __int16 uExpressionTimeLength;
   __int16 field_1AA2;
--- a/PlayerFrameTable.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/PlayerFrameTable.h	Tue Feb 12 09:11:19 2013 +0600
@@ -1,12 +1,12 @@
 #pragma once
-
+#include "Player.h"
 
 
 /*   46 */
 #pragma pack(push, 1)
 struct PlayerFrame
 {
-  __int16 uSequenceID;
+  CHARACTER_EXPRESSION_ID expression;
   unsigned __int16 uTextureID;
   __int16 uAnimTime;
   __int16 uAnimLength;
@@ -23,7 +23,7 @@
     uNumFrames(0), pFrames(nullptr)
   {}
 
-  unsigned int GetFrameIdBy_field0(int uField0);
+  unsigned int GetFrameIdByExpression(CHARACTER_EXPRESSION_ID expression);
   PlayerFrame *GetFrameBy_x(unsigned int uFramesetID, unsigned int uFrameID);
   PlayerFrame *GetFrameBy_y(int *a2, int *a3, int a4);
   void ToFile();
--- a/Render.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/Render.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -1735,7 +1735,7 @@
   int v63; // [sp+50h] [bp-8h]@3
   int v64; // [sp+57h] [bp-1h]@2
   int v62;
-  struct IndoorCameraD3D *pIndoorCameraD3D;
+  //struct IndoorCameraD3D *pIndoorCameraD3D;
 
   v63 = 0;
   // basic optimizations
@@ -1771,9 +1771,9 @@
       pTerrainVertices[z * 128 + x].vWorldPosition.x = (-64 + (signed)x) * 512;
       pTerrainVertices[z * 128 + x].vWorldPosition.y = (64 - (signed)z) * 512;
       pTerrainVertices[z * 128 + x].vWorldPosition.z = 32 * pOutdoor->pTerrain.pHeightmap[z * 128 + x];
-      pIndoorCameraD3D = pGame->pIndoorCameraD3D;
-      pIndoorCameraD3D->ViewTransform(&pTerrainVertices[z * 128 + x], 1);
-      pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0);
+      //pIndoorCameraD3D = pGame->pIndoorCameraD3D;
+      pGame->pIndoorCameraD3D->ViewTransform(&pTerrainVertices[z * 128 + x], 1);
+      pGame->pIndoorCameraD3D->Project(&pTerrainVertices[z * 128 + x], 1, 0);
     }
   }
   for (unsigned int z = uStartZ; z < uEndZ - 1; ++z)
--- a/Texture.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/Texture.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -107,7 +107,7 @@
 unsigned int uTextureID_BUTTYES2;
 unsigned int uTextureID_x_ok_u;
 Texture *pPlayerPortraits[22];
-Texture *pTexture_IC_KNIGHT[8];
+Texture *pTexture_IC_KNIGHT[9];
 Texture *pTexture_MAKESKY;
 Texture *pTexture_MAKETOP;
 Texture *pTextures_arrowr[20];
--- a/Texture.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/Texture.h	Tue Feb 12 09:11:19 2013 +0600
@@ -209,7 +209,7 @@
 extern unsigned int uTextureID_BUTTYES2;
 extern unsigned int uTextureID_x_ok_u;
 extern Texture *pPlayerPortraits[22];
-extern Texture *pTexture_IC_KNIGHT[8];
+extern Texture *pTexture_IC_KNIGHT[];
 extern Texture *pTexture_MAKESKY;
 extern Texture *pTexture_MAKETOP;
 extern Texture *pTextures_arrowr[20];
--- a/Vis.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/Vis.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -1433,7 +1433,7 @@
   Vis *thisa; // [sp+68h] [bp-8h]@1
   RenderVertexSoft *v16; // [sp+6Ch] [bp-4h]@2
 
-  __debugbreak();
+  //__debugbreak();
 
   result = sRight;
   thisa = this;
@@ -1586,7 +1586,7 @@
 
 
 //----- (004C05CC) --------------------------------------------------------
-bool Vis::_4C05CC(Vis_stru1 *a2, stru157 *a3, stru157 *a4)
+bool Vis::PickKeyboard(Vis_stru1 *a2, stru157 *a3, stru157 *a4)
 {
   Vis_stru1 *v4; // esi@1
   Vis *v5; // ebx@1
--- a/Vis.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/Vis.h	Tue Feb 12 09:11:19 2013 +0600
@@ -42,7 +42,7 @@
   //virtual ~Vis() {}
   //----- (004C05BE) --------------------------------------------------------
   ~Vis() {}
-  bool _4C05CC(Vis_stru1 *a2, struct stru157 *a3, struct stru157 *a4);
+  bool PickKeyboard(Vis_stru1 *a2, struct stru157 *a3, struct stru157 *a4);
   bool PickMouse(float fDepth, float fMouseX, float fMouseY, struct stru157 *a5, struct stru157 *a6);
   void _4C06F8(float arg0, Vis_stru1 *a3, struct stru157 *a2);
   bool is_part_of_selection(struct BLVFace *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, struct stru157 *a2);
--- a/mm7_1.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_1.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -638,11 +638,10 @@
   v3 = pIcons_LOD->LoadTexture("fr_award", TEXTURE_16BIT_PALETTE);
   pRenderer->DrawTextureIndexed(8u, 8u, (Texture *)(v3 != -1 ? (int)&pIcons_LOD->pTextures[v3] : 0));
   sprintf(pTmpBuf, "%s \f%05d", pGlobalTXT_LocalizationStrings[23], v2);// TODO check args
-  sprintf(
-    Source,
+  sprintf(Source,
     pGlobalTXT_LocalizationStrings[429],
 	&pParty->pPlayers[v1-1].pName,//&stru_AA1058[3].pSounds[6972 * v1 + 40720],
-	pClassNames[pParty->pPlayers[v1-1].uClass]);//&pClassNames[stru_AA1058[3].pSounds[6972 * v1 + 40737]]);
+	pClassNames[pParty->pPlayers[v1-1].classType]);//&pClassNames[stru_AA1058[3].pSounds[6972 * v1 + 40737]]);
   strcat(pTmpBuf, Source);
   strcat(pTmpBuf, "\xC" "00000");
   pGUIWindow_CurrentMenu->DrawText(pFontArrus, 24, 18, 0, pTmpBuf, 0, 0, 0);
@@ -1080,7 +1079,7 @@
     v6 = v45 + 47;
     if ( v43 == v0 )
       pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v45 + 47, v0, pGlobalTXT_LocalizationStrings[41], 60, v0);//
-    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v6, v0, pClassNames[pPlayer->uClass], 84, v0);
+    pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, v44, v6, v0, pClassNames[pPlayer->classType], 84, v0);
     v7 = v45 + v6;
     if ( v43 == v0 )
       pGUIWindow_CurrentMenu->DrawTextInRect(pFontArrus, 0x16u, v7, v0, pGlobalTXT_LocalizationStrings[107], 60, v0);//.
@@ -3714,7 +3713,7 @@
       if ( v0 > &pParty->pPlayers[3] )
         break;
     }
-	if(v0->uClass == 31)
+	if(v0->classType == PLAYER_CLASS_31)
 		++uRestUI_FoodRequiredToRest;
   }
   if ( CheckHiredNPCSpeciality(0x1Du) )
--- a/mm7_2.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_2.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -671,7 +671,7 @@
             do
             {
               v12 = v8->GetControl(v10)->uControlParam - 36;
-              if ( byte_4ED970_skill_learn_ability_by_class_table[v85->uClass][v12] && !v85->pActiveSkills[v12] )
+              if ( byte_4ED970_skill_learn_ability_by_class_table[v85->classType][v12] && !v85->pActiveSkills[v12] )
               {
                 v13 = pFontArrus->CalcTextHeight(pSkillNames[v12], &v79, 0, 0);
                 v89 += v13;
@@ -698,7 +698,7 @@
                   v15 = v8->GetControl(v89);
                   v16 = v15;
                   v17 = v15->uControlParam - 36;
-                  if ( !byte_4ED970_skill_learn_ability_by_class_table[v85->uClass][v17] || v85->pActiveSkills[v17] )
+                  if ( !byte_4ED970_skill_learn_ability_by_class_table[v85->classType][v17] || v85->pActiveSkills[v17] )
                   {
                     v16->uW = 0;
                     v16->uHeight = 0;
@@ -732,7 +732,7 @@
             }
           }
           v26 = pTmpBuf;
-          sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v85->pName, pClassNames[v85->uClass]);
+          sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v85->pName, pClassNames[v85->classType]);
           strcat(pTmpBuf, "\n \n");
           strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
           goto LABEL_97;
@@ -1206,7 +1206,7 @@
           do
           {
             v35 = v30->GetControl(v33)->uControlParam - 36;
-            if ( byte_4ED970_skill_learn_ability_by_class_table[_this->uClass][v35] && !_this->pActiveSkills[v35] )
+            if ( byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v35] && !_this->pActiveSkills[v35] )
             {
               v36 = pFontArrus->CalcTextHeight(pSkillNames[v35], &v101, 0, 0);
               v106.y += v36;
@@ -1218,7 +1218,7 @@
           if ( !v109 )
           {
 LABEL_105:
-            sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], _this->pName, pClassNames[_this->uClass]);
+            sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], _this->pName, pClassNames[_this->classType]);
             strcat(pTmpBuf, "\n \n");
             strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
             v7 = pTmpBuf;
@@ -1247,7 +1247,7 @@
               v38 = v30->GetControl(v106.y);
               v39 = v38;
               v40 = v38->uControlParam - 36;
-              if ( !byte_4ED970_skill_learn_ability_by_class_table[_this->uClass][v40] || _this->pActiveSkills[v40] )
+              if ( !byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v40] || _this->pActiveSkills[v40] )
               {
                 v39->uW = 0;
                 v39->uHeight = 0;
@@ -1946,7 +1946,7 @@
           do
           {
             v8 = v2->GetControl(v6)->uControlParam - 36;
-            if ( byte_4ED970_skill_learn_ability_by_class_table[_this->uClass][v8] && !_this->pActiveSkills[v8] )
+            if ( byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v8] && !_this->pActiveSkills[v8] )
             {
               v9 = pFontArrus->CalcTextHeight(pSkillNames[v8], &v104, 0, 0);
               v112 += v9;
@@ -1974,7 +1974,7 @@
                 v11 = v2->GetControl(v112);
                 v12 = v11;
                 v13 = v11->uControlParam - 36;
-                if ( !byte_4ED970_skill_learn_ability_by_class_table[_this->uClass][v13] || _this->pActiveSkills[v13] )
+                if ( !byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v13] || _this->pActiveSkills[v13] )
                 {
                   v12->uW = 0;
                   v12->uHeight = 0;
@@ -2007,7 +2007,7 @@
             return result;
           }
         }
-        sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], _this->pName, pClassNames[_this->uClass]);
+        sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], _this->pName, pClassNames[_this->classType]);
         strcat(pTmpBuf, "\n \n");
         strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
         v21 = pTmpBuf;
@@ -2540,7 +2540,7 @@
         do
         {
           v41 = v37->GetControl(v39)->uControlParam - 36;
-          if ( byte_4ED970_skill_learn_ability_by_class_table[v0->uClass][v41] && !v0->pActiveSkills[v41] )
+          if ( byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v41] && !v0->pActiveSkills[v41] )
           {
             v42 = pFontArrus->CalcTextHeight(pSkillNames[v41], &v144, 0, 0);
             v152 += v42;
@@ -2567,7 +2567,7 @@
               v44 = v37->GetControl(v152);
               v45 = v44;
               v46 = v44->uControlParam - 36;
-              if ( !byte_4ED970_skill_learn_ability_by_class_table[v0->uClass][v46] || v0->pActiveSkills[v46] )
+              if ( !byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v46] || v0->pActiveSkills[v46] )
               {
                 v45->uW = 0;
                 v45->uHeight = 0;
@@ -2600,7 +2600,7 @@
           return;
         }
       }
-      sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v0->pName, pClassNames[v0->uClass]);
+      sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v0->pName, pClassNames[v0->classType]);
       strcat(pTmpBuf, "\n \n");
       strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
       v11 = 0;
@@ -4543,7 +4543,7 @@
       v44 = v43 * (100 - v0->GetMerchant()) / 100;
       if ( v44 < v43 / 3 )
         v44 = v43 / 3;
-      if ( byte_4ED970_skill_learn_ability_by_class_table[v0->uClass][v42] )
+      if ( byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v42] )
       {
         pSkill = &v0->pActiveSkills[v42];
         if ( !*pSkill )
@@ -5144,7 +5144,7 @@
   //for ( i = (int)pParty->pPlayers[0].pName; ; v3 = (char *)i )
   for ( i = pParty->pPlayers; ; v3 = i )
   {
-	v4 = pClassNames[v3->uClass];
+	v4 = pClassNames[v3->classType];
     v5 = v3->GetBaseLevel();
 	sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[129], i->pName, v5, v4);
     pWindow.DrawTitleText(
--- a/mm7_3.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_3.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -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;
@@ -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);
@@ -2553,7 +2553,7 @@
   angle = pParty->sRotationY;
   _view_angle = pParty->sRotationX;
   v82 = (unsigned __int64)(pEventTimer->dt_in_some_format
-                         * (signed __int64)((signed int)(pParty->field_20_prolly_turn_speed * stru_5C6E00->uIntegerPi)
+                         * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi)
                                           / 180)) >> 16;
 LABEL_87:
   while ( pPartyActionQueue->uNumActions )
@@ -2734,7 +2734,7 @@
       do
       {
         if ( !(*v41)->HasEnchantedItemEquipped(72) && !(*v41)->WearsItem(529, 8) )
-          (*v41)->PlayEmotion(46, 0);
+          (*v41)->PlayEmotion(CHARACTER_EXPRESSION_46, 0);
         ++v41;
       }
       while ( (signed int)v41 <= (signed int)&pPlayers[4] );
@@ -2994,7 +2994,7 @@
 //----- (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
@@ -3002,15 +3002,15 @@
   int v5; // eax@24
   int v6; // esi@45
   ODMFace *v7; // ecx@45
-  unsigned int v8; // eax@71
-  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
+  //unsigned int v8; // eax@71
+  //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
@@ -3092,9 +3092,10 @@
   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
@@ -3113,7 +3114,7 @@
   int v116; // [sp+58h] [bp-3Ch]@1
   int v117; // [sp+5Ch] [bp-38h]@1
   int v118; // [sp+60h] [bp-34h]@1
-  Player **v119; // [sp+64h] [bp-30h]@4
+  //Player **v119; // [sp+64h] [bp-30h]@4
   int _angle_x; // [sp+68h] [bp-2Ch]@48
   int v121; // [sp+6Ch] [bp-28h]@1
   unsigned int v122; // [sp+70h] [bp-24h]@180
@@ -3128,7 +3129,6 @@
 
   v121 = pParty->uFallSpeed;
   v123 = pParty->vPosition.z;
-  _zero = 0;
   v1 = 0;
   v103 = 0;
   v2 = 0;
@@ -3137,38 +3137,42 @@
   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;
   v102 = 0;
   v127 = 0;
   bWaterWalk = 0;
-  if ( SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) < 0
-    || SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) <= 0 && LODWORD(pParty->pPartyBuffs[5].uExpireTime) <= 0 )
+  if (!pParty->FeatherFallActive())
+      //SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) < 0
+      //|| SHIDWORD(pParty->pPartyBuffs[5].uExpireTime) <= 0 && LODWORD(pParty->pPartyBuffs[5].uExpireTime) <= 0 )
   {
     bFeatherFall = 0;
-    v119 = &pPlayers[1];
+    /*v119 = &pPlayers[1];
     while ( !(*v119)->WearsItem(536, 16) )
     {
       ++v119;
       if ( (signed int)v119 > (signed int)&pPlayers[4] )
         goto LABEL_9;
-    }
-  }
-  bFeatherFall = 1;
-LABEL_9:
-  if ( (signed __int64)pParty->pPartyBuffs[18].uExpireTime <= 0 )
-  {
-    LOBYTE(pParty->uFlags) &= 0x7Fu;
-  }
-  else
-  {
-    LOBYTE(pParty->uFlags) &= 0x7Fu;
+    }*/
+    for (int i = 0; i < 4; ++i)
+      if (pParty->pPlayers[i].WearsItem(536, 16))  // seems like flying boots
+      {
+        bFeatherFall = 1;
+        break;
+      }
+  }
+//  bFeatherFall = 1;
+//LABEL_9:
+  LOBYTE(pParty->uFlags) &= 0x7Fu;
+  if (pParty->WaterWalkActive())
+  {
+    //LOBYTE(pParty->uFlags) &= 0x7Fu;
     bWaterWalk = 1;
     *(short *)&stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[18].uOverlayID + 119] |= 1u;
-    if ( !(pParty->pPartyBuffs[18].uFlags & 1)
-		&& pParty->pPlayers[pParty->pPartyBuffs[18].uCaster-1].sMana <= 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[18].uCaster + 10] <= 0 )
+    if (!(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1) &&
+		pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster-1].sMana <= 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[18].uCaster + 10] <= 0 )
       bWaterWalk = 0;
   }
   v3 = sub_46D49E_prolly_get_world_y_under_party(v116, v117, v123, pParty->uPartyHeight, &v130, &v108, bWaterWalk);
@@ -3201,35 +3205,34 @@
         ++v4;
       }
       while ( (signed int)v4 <= (signed int)&pPlayers[4] );
-      _zero = 0;
     }
   }
   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 )
+    && 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 )
         {
@@ -3254,22 +3257,25 @@
   _angle_y = pParty->sRotationY;
   _angle_x = pParty->sRotationX;
   v126 = pEventTimer->dt_in_some_format;
-  v119 = (Player **)((unsigned __int64)(pEventTimer->dt_in_some_format
+  /*v119 = (Player **)((unsigned __int64)(pEventTimer->dt_in_some_format
                                       * (signed __int64)((signed int)(pParty->field_20_prolly_turn_speed
                                                                     * stru_5C6E00->uIntegerPi)
-                                                       / 180)) >> 16);
+                                                       / 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() )
     {
       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 )
             {
@@ -3301,10 +3307,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
@@ -3324,68 +3331,86 @@
             }
           }
         }
-        goto LABEL_118;
+        break;
+
       case PARTY_TurnLeft:
-        v8 = uTurnSpeed;
-        if ( uTurnSpeed )
-          goto LABEL_80;
-        v9 = (double)(signed int)v119 * fTurnSpeedMultiplier;
-        goto LABEL_73;
+        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 )
-          goto LABEL_77;
-        v11 = (double)(signed int)v119 * fTurnSpeedMultiplier;
-        goto LABEL_76;
+        if (uTurnSpeed)
+          _angle_y -= uTurnSpeed;
+        else
+          _angle_y -= dturn * fTurnSpeedMultiplier;
+
+        _angle_y &= stru_5C6E00->uDoublePiMask;
+      break;
+
       case PARTY_FastTurnLeft:
-        v8 = uTurnSpeed;
-        if ( uTurnSpeed )
-        {
-LABEL_80:
-          v12 = v8 + _angle_y;
-LABEL_78:
-          _angle_y = stru_5C6E00->uDoublePiMask & v12;
-        }
-        else
-        {
-          v9 = (fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)(signed int)v119;
-LABEL_73:
-          _angle_y = stru_5C6E00->uDoublePiMask & (_angle_y + (unsigned __int64)(signed __int64)v9);
-        }
-        goto LABEL_118;
+        if (uTurnSpeed)
+          _angle_y += uTurnSpeed;
+        else
+          _angle_y += 2.0f * fTurnSpeedMultiplier * (double)dturn;
+
+        _angle_y &= stru_5C6E00->uDoublePiMask;
+      break;
+
       case PARTY_FastTurnRight:
-        LODWORD(v10) = uTurnSpeed;
-        if ( !uTurnSpeed )
-        {
-          v11 = (fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)(signed int)v119;
-LABEL_76:
-          v10 = (signed __int64)v11;
-        }
-LABEL_77:
-        v12 = _angle_y - v10;
-        goto LABEL_78;
+        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;
+      {
+        //v13 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
+        //v14 = (double)_walk_speed;
+        *(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;
+      {
+        //v126 = stru_5C6E00->SinCos(_angle_y - stru_5C6E00->uIntegerHalfPi);
+        *(float *)&v128 = pParty->uWalkSpeed;
+        /*v124 = (unsigned __int64)(v126 * (signed __int64)((signed int)(signed __int64)(pParty->uWalkSpeed * 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;
+        v1 -= v124;*/
+        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;
@@ -3396,9 +3421,11 @@
         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;
+        v128 = v1;
+        v124 = 1;
+      break;
+
       case PARTY_WalkBackward:
         v19 = stru_5C6E00->SinCos(_angle_y);
         v20 = (double)_walk_speed;
@@ -3411,9 +3438,11 @@
         v124 = (unsigned __int64)(v126
                                 * (signed __int64)(signed int)(signed __int64)(*(float *)&v128
                                                                              * fBackwardWalkSpeedMultiplier)) >> 16;
-LABEL_90:
         v1 -= v124;
-        goto LABEL_86;
+        v128 = v1;
+        v124 = 1;
+      break;
+
       case PARTY_RunForward:
         if ( pParty->bFlying )
         {
@@ -3434,7 +3463,7 @@
           v1 += v129;
           goto LABEL_93;
         }
-        if ( v118 && !v108 )
+        if ( partyAtHighSlope && !v108 )
         {
           v23 = stru_5C6E00->SinCos(_angle_y);
           v24 = (double)_walk_speed;
@@ -3446,7 +3475,9 @@
           v129 = (unsigned __int64)(v126
                                   * (signed __int64)(signed int)(signed __int64)(*(float *)&v128 * fWalkSpeedMultiplier)) >> 16;
           v1 += v129;
-          goto LABEL_86;
+          v128 = v1;
+          v124 = 1;
+          break;
         }
         v25 = stru_5C6E00->SinCos(_angle_y);
         v26 = (double)_walk_speed;
@@ -3466,6 +3497,7 @@
         v114 = 1;
         v128 = v1;
         break;
+
       case PARTY_RunBackward:
         v27 = stru_5C6E00->SinCos(_angle_y);
         v28 = (double)_walk_speed;
@@ -3494,7 +3526,7 @@
                                   * (signed __int64)(signed int)(signed __int64)(*(float *)&v128
                                                                                * fBackwardWalkSpeedMultiplier)) >> 16;
           v1 -= v129;
-LABEL_86:
+//LABEL_86:
           v128 = v1;
           v124 = 1;
         }
@@ -3526,7 +3558,7 @@
         _angle_x = 0;
         goto LABEL_118;
       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;
@@ -3587,7 +3619,7 @@
     v121 += 2 * v33;
     goto LABEL_149;
   }
-  if ( !v118 )
+  if ( !partyAtHighSlope )
   {
     v34 = v121;
 LABEL_149:
@@ -3599,16 +3631,20 @@
   {
     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);
+    v129 = abs((signed __int64)v2 * v98.x + (signed __int64)v1 * v98.y + (signed __int64)v35 * v98.z) >> 16;
+    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98.x) >> 16);
     v2 += (int)v127;
-    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v99) >> 16);
+    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98.y) >> 16);
     v1 += (int)v127;
     v128 = v1;
-    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v100) >> 16);
+    v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98.z) >> 16);
     v34 = (int)((char *)v127 + v35);
     v32 = 0;
     v121 = v34;
@@ -3638,7 +3674,7 @@
 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;
@@ -3690,7 +3726,7 @@
     v122 = v40;
     sub_46D49E_prolly_get_world_y_under_party(_angle_x, _angle_y, v40, pParty->uPartyHeight, &v130, &v108, 0);
     v129 = sub_46D49E_prolly_get_world_y_under_party(_angle_x, v117, v40, pParty->uPartyHeight, &v130, &v97, 0);
-    v119 = (Player **)sub_46D49E_prolly_get_world_y_under_party(
+    auto v119 = sub_46D49E_prolly_get_world_y_under_party(
                         v116,
                         _angle_y,
                         v40,
@@ -3698,8 +3734,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 )
@@ -3710,7 +3746,7 @@
       goto LABEL_197;
     if ( v127 && v129 > v123 )
       v44 = 0;
-    if ( v118 && (signed int)v119 > v123 )
+    if ( v118 && v119 > v123 )
       v43 = 0;
     if ( v44 )
       goto LABEL_197;
@@ -3724,7 +3760,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:
@@ -3791,7 +3827,7 @@
         v50 = v48 - 32 < 0;
         v52 = v47->pFacePlane.vNormal.z;
         v129 = (unsigned __int8)(v50 ^ v51 | v49);
-        v119 = (Player **)(v52 < 46378);
+        v119 = v52 < 46378;
         if ( bUnderwater == 1 )
           v119 = 0;
         v53 = v47->uPolygonType;
@@ -9412,77 +9448,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;*/
 }
 
 
@@ -16285,13 +16339,13 @@
         v20 = v19 - 1;
         if ( !v20 )
         {
-          v23 = v0->evtb;
+          v23 = v0->_anim_current_time;
           goto LABEL_63;
         }
         v21 = v20 - 1;
         if ( !v21 )
         {
-          v23 = v0->evtc;
+          v23 = v0->_anim_end_time;
           goto LABEL_63;
         }
         v22 = v21 - 1;
@@ -17209,12 +17263,12 @@
                 }
                 else
                 {
-                  v33->evtc = v30;
+                  v33->_anim_end_time = v30;
                 }
               }
               else
               {
-                v33->evtb = v30;
+                v33->_anim_current_time = v30;
               }
             }
             else
@@ -17366,13 +17420,13 @@
 LABEL_108:
               v52 = &pParty->pPlayers[v53];
 LABEL_109:
-              v52->PlayEmotion(v113, v117);
+              v52->PlayEmotion((CHARACTER_EXPRESSION_ID)v113, v117);
               goto LABEL_291;
             }
             v51 = pParty->pPlayers;
             do
             {
-              v51->PlayEmotion(_evt->v6, 0);
+              v51->PlayEmotion((CHARACTER_EXPRESSION_ID)_evt->v6, 0);
               ++v51;
             }
             while ( (signed int)v51 < (signed int)pParty->pHirelings );
@@ -19421,25 +19475,17 @@
 //----- (0044A56A) --------------------------------------------------------
 void __cdecl sub_44A56A()
 {
-  signed int v0; // edi@1
-  NPCData *v1; // esi@2
-
   pParty->field_70A = 0;
-  v0 = 0;
-  if ( (signed int)pNPCStats->uNumNewNPCs > 0 )
-  {
-    v1 = pNPCStats->pNewNPCData;
-    do
-    {
-      if ( v1->uFlags & 0x80 && (!pParty->pHirelings[0].pName || strcmp(v1->pName, pParty->pHirelings[0].pName)) )
-      {
-        if ( !pParty->pHirelings[1].pName || strcmp(v1->pName, pParty->pHirelings[1].pName) )
-          ++pParty->field_70A;
-      }
-      ++v0;
-      ++v1;
-    }
-    while ( v0 < (signed int)pNPCStats->uNumNewNPCs );
+
+  for (int i = 0; i < pNPCStats->uNumNewNPCs; ++i)
+  {
+    auto npc = pNPCStats->pNewNPCData + i;
+    if (npc->uFlags & 0x80 &&
+        (!pParty->pHirelings[0].pName || strcmp(npc->pName, pParty->pHirelings[0].pName)))
+    {
+      if (!pParty->pHirelings[1].pName || strcmp(npc->pName, pParty->pHirelings[1].pName))
+        ++pParty->field_70A;
+    }
   }
 }
 
--- a/mm7_4.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_4.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -977,118 +977,80 @@
   return dword_720F20[v22];
 }
 
+
+//not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal
+// for a right-handed system, that would be an inverse normal
 //----- (0046DCC8) --------------------------------------------------------
-signed __int64 __fastcall _46DCC8_get_gravity_direction_outdoor(int a1, int a2, Vec3_int_ *a3)
-{
-  int v3; // ebx@1
-  int v4; // ST4C_4@1
-  unsigned int v5; // ST54_4@1
-  unsigned int v6; // edi@1
-  unsigned int v7; // ST50_4@1
-  int v8; // edi@1
-  int v9; // esi@1
-  int v10; // ebx@1
-  int v11; // ecx@2
-  int v12; // eax@2
-  int v13; // edx@2
-  int v14; // ebx@2
-  double v15; // st7@4
-  double v16; // st6@4
-  double v17; // st5@4
-  float v18; // ST44_4@4
-  float v19; // ST54_4@4
-  double v20; // st4@4
-  double v21; // st5@4
-  float v22; // ST44_4@6
-  double v23; // st7@4
-  double v24; // st7@6
-  signed __int64 result; // qax@6
-  int v26; // [sp+14h] [bp-44h]@1
-  int v27; // [sp+18h] [bp-40h]@1
-  int v28; // [sp+20h] [bp-38h]@1
-  int v29; // [sp+24h] [bp-34h]@1
-  int v30; // [sp+28h] [bp-30h]@1
-  int v31; // [sp+2Ch] [bp-2Ch]@1
-  int v32; // [sp+30h] [bp-28h]@1
-  int v33; // [sp+34h] [bp-24h]@1
-  int v34; // [sp+38h] [bp-20h]@1
-  int v35; // [sp+3Ch] [bp-1Ch]@1
-  int v36; // [sp+40h] [bp-18h]@1
-  int v37; // [sp+4Ch] [bp-Ch]@2
-  float v38; // [sp+4Ch] [bp-Ch]@4
-  int v39; // [sp+50h] [bp-8h]@2
-  float v40; // [sp+50h] [bp-8h]@4
-  int v41; // [sp+54h] [bp-4h]@2
-
-  v3 = a1;
-  v4 = a2;
-  v5 = WorldPosToGridCellX(a1);
-  v6 = WorldPosToGridCellZ(v4) - 1;
-  v33 = GridCellToWorldPosX(v5);
-  v34 = GridCellToWorldPosX(v5 + 1);
-  v35 = GridCellToWorldPosX(v5 + 1);
-  v36 = GridCellToWorldPosX(v5);
-  v29 = GridCellToWorldPosZ(v6);
-  v30 = GridCellToWorldPosZ(v6);
-  v7 = v6 + 1;
-  v31 = GridCellToWorldPosZ(v6 + 1);
-  v32 = GridCellToWorldPosZ(v6 + 1);
-  v26 = pOutdoor->DoGetHeightOnTerrain(v5, v6);
-  v27 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6);
-  v8 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6 + 1);
-  v28 = pOutdoor->DoGetHeightOnTerrain(v5, v7);
-  v9 = v29;
-  v10 = abs(v3 - v33);
-  if ( abs(v29 - v4) >= v10 )
-  {
-    v11 = v33;
-    v37 = v28;
-    v39 = v36;
-    v12 = v35;
-    v41 = v32;
-    v13 = v31;
-    v14 = v8;
-    v8 = v26;
-  }
-  else
-  {
-    v11 = v35;
-    v41 = v30;
-    v39 = v34;
-    v12 = v33;
-    v13 = v29;
-    v9 = v31;
-    v37 = v27;
-    v14 = v26;
-  }
-  v15 = (double)(v12 - v39);
-  v16 = (double)(v13 - v41);
-  v17 = (double)(v14 - v37);
-  v18 = (double)(v11 - v39);
-  v19 = (double)(v9 - v41);
-  v20 = (double)(v8 - v37);
-  v38 = v20 * v16 - v19 * v17;
-  v40 = v18 * v17 - v20 * v15;
-  v21 = v19 * v15 - v18 * v16;
-  v23 = sqrt(v21 * v21 + v40 * v40 + v38 * v38);
-  if ( v23 == 0.0 )
-  {
-    a3->y = 0;
-    a3->x = 0;
-    a3->z = 65536;
-  }
-  v24 = 1.0 / v23;
-  a3->x = (signed __int64)(v24 * v38 * 65536.0);
-  a3->y = (signed __int64)(v24 * v40 * 65536.0);
-  v22 = v21;
-  result = (signed __int64)(v24 * v22 * 65536.0);
-  a3->z = result;
-  return result;
-}
-// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int);
-// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int);
-// 47F469: using guessed type int __stdcall GridCellToWorldPosX(int);
-// 47F476: using guessed type int __stdcall GridCellToWorldPosZ(int);
+void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out)
+{
+  auto grid_x = WorldPosToGridCellX(pos_x);
+  auto grid_z = WorldPosToGridCellZ(pos_z) - 1;
+
+  auto grid_pos_x1 = GridCellToWorldPosX(grid_x);
+  auto grid_pos_x2 = GridCellToWorldPosX(grid_x + 1);
+  auto grid_pos_z1 = GridCellToWorldPosZ(grid_z);
+  auto grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1);
+
+  auto x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
+  auto x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
+  auto x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
+  auto x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
+
+  float side1_dx, side1_dy, side1_dz,
+        side2_dx, side2_dy, side2_dz;
+
+  auto dx = abs(pos_x - grid_pos_x1),
+       dz = abs(grid_pos_z1 - pos_z);
+  if (dz >= dx)
+  {
+    side1_dy = (double)(x1z1_y - x1z2_y);
+    side2_dy = (double)(x2z2_y - x1z2_y);
+    side2_dx = (double)(grid_pos_x2 - grid_pos_x1);
+    side1_dx = (double)(grid_pos_x1 - grid_pos_x1);
+    side2_dz = (double)(grid_pos_z2 - grid_pos_z2);  // bug?  z2 - z2
+    side1_dz = (double)(grid_pos_z2 - grid_pos_z2);  //       z1 - z2
+    Log::Warning(L"%s %s %u\n", __FILE__, __FUNCTION__, __LINE__);
+    /*       |\
+       side1 |  \
+             |____\
+             side 2      */
+  }
+  else
+  {
+    side1_dy = (double)(x2z2_y - x2z1_y);
+    side2_dy = (double)(x1z1_y - x2z1_y);
+    side2_dx = (double)(grid_pos_x1 - grid_pos_x2);
+    side1_dx = (double)(grid_pos_x2 - grid_pos_x2);
+    side2_dz = (double)(grid_pos_z1 - grid_pos_z1);
+    side1_dz = (double)(grid_pos_z2 - grid_pos_z1);
+
+    /*   side 2
+         _____
+         \    |
+           \  | side 1
+             \|       */
+  }
+  
+  float nx = side1_dy * side2_dz - side1_dz * side2_dy;
+  float ny = side1_dx * side2_dy - side1_dy * side2_dx;
+  float nz = side1_dz * side2_dx - side1_dx * side2_dz;
+
+  float mag = sqrt(nx * nx + ny * ny + nz * nz);
+  if (fabsf(mag) < 1e-6f)
+  {
+    out->y = 0;
+    out->x = 0;
+    out->z = 65536;
+  }
+  else
+  {
+    float invmag = 1.0 / mag;
+    out->x = invmag * nx * 65536.0;
+    out->y = invmag * ny * 65536.0;
+    out->z = invmag * nz * 65536.0;
+  }
+}
+
 
 //----- (0046DEF2) --------------------------------------------------------
 unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID)
@@ -3128,7 +3090,7 @@
         v10 = (unsigned __int8)pTmpBuf[i];
         if ( pParty->pHirelings[v10].bDrawSomeAnim == 1 )
         {
-          uFrameID = pParty->pHirelings[v10].evtb;
+          uFrameID = pParty->pHirelings[v10]._anim_current_time;
           v11 = pHiredNPCsIconsOffsetsX[v9];
           v12 = pHiredNPCsIconsOffsetsY[v9];
           v17 = v11;
@@ -3236,14 +3198,14 @@
     }
       v7 = 0;
       for (uint j = 0; j < pPlayerFrameTable->uNumFrames; ++j)
-        if (pPlayerFrameTable->pFrames[j].uSequenceID == pPlayer->uExpressionID)
+        if (pPlayerFrameTable->pFrames[j].expression == pPlayer->expression)
         {
           v7 = j;
           break;
         }
     if ( v7 == 0 )
       v7 = 1;
-    if (pPlayer->uExpressionID == 21 )
+    if (pPlayer->expression == CHARACTER_EXPRESSION_21)
       pFrame = pPlayerFrameTable->GetFrameBy_y(&pPlayer->field_1AA8, &pPlayer->field_1AA4, pMiscTimer->uTimeElapsed);
     else
       pFrame = pPlayerFrameTable->GetFrameBy_x(v7, pPlayer->uExpressionTimePassed);
@@ -3567,9 +3529,9 @@
     v45 = 0;
     v48 = 0;
     v46 = 0;
-    if ( v44 && v21->uClass == 31 )
+    if ( v44 && v21->classType == PLAYER_CLASS_31 )
       v50 = 1;
-    if ( v21->uClass == 35 )
+    if ( v21->classType == PLAYER_CLASS_LICH )
       v48 = 1;
     v22 = (ITEM_EQUIP_TYPE)0;
     while ( 1 )
@@ -3968,7 +3930,7 @@
         }
         v13 = pPlayers[v12];
       }
-      v13->PlayEmotion(37, v58);
+      v13->PlayEmotion(CHARACTER_EXPRESSION_37, v58);
 LABEL_39:
       ++v12;
       if ( v12 > 4 )
@@ -4309,7 +4271,7 @@
 
 
 //----- (00494AED) --------------------------------------------------------
-unsigned int PlayerFrameTable::GetFrameIdBy_field0(int uField0)
+unsigned int PlayerFrameTable::GetFrameIdByExpression(CHARACTER_EXPRESSION_ID expression)
 {
   unsigned int _uNumFrames; // edx@1
   unsigned int result; // eax@1
@@ -4325,7 +4287,7 @@
   else
   {
     v4 = this->pFrames;
-    while ( v4->uSequenceID != uField0 )
+    while ( v4->expression != expression )
     {
       ++result;
       ++v4;
@@ -4492,7 +4454,7 @@
     {
       v8 = atoi(v24.pProperties[0]);
       v9 = v24.pProperties[1];
-      v2->pFrames[v2->uNumFrames].uSequenceID = v8;
+      v2->pFrames[v2->uNumFrames].expression = (CHARACTER_EXPRESSION_ID)v8;
       v10 = atoi(v9);
       v11 = v24.pProperties[2];
       v2->pFrames[v2->uNumFrames].uTextureID = v10;
@@ -5312,7 +5274,7 @@
   char *v15; // ST14_4@24
   size_t v16; // eax@28
   int v17; // eax@33
-  enum CHARACTER_RACE uNumRace; // eax@35
+  //enum CHARACTER_RACE uNumRace; // eax@35
   int v19; // eax@36
   int v20; // eax@37
   int uNumMight; // eax@44
@@ -5342,7 +5304,7 @@
   int v51; // eax@49
   char *v52; // edi@52
   char v53; // al@52
-  int uClassType; // edi@53
+  PLAYER_CLASS_TYPE uClassType; // edi@53
   int v55; // ST0C_4@53
   int v57; // eax@53
   int v61; // ecx@55
@@ -5382,8 +5344,8 @@
   int uX; // [sp+160h] [bp-10h]@18
   unsigned int v133; // [sp+164h] [bp-Ch]@25
   int pOrder; // [sp+168h] [bp-8h]@14
-  char *Str; // [sp+16Ch] [bp-4h]@18
-  Player *pPlayer;
+  //char *Str; // [sp+16Ch] [bp-4h]@18
+  //Player *pPlayer;
   const char *pSkillName;
 
   uColor1 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xD1, 0xBB, 0x61);
@@ -5466,11 +5428,15 @@
   //pPlayer = pParty->pPlayers;
   v119 = 6 * v6 + 169;
   //do
-  for ( pPlayer = pParty->pPlayers; (signed int)pPlayer->pName < (signed int)&pParty->pPickedItem.uNumCharges; pPlayer++)
-  {
-    Str = pPlayer->pName;
-	pGUIWindow_CurrentMenu->DrawText(pFontCreate, pOrder + 73, 100, 0, pClassNames[(unsigned __int8)pPlayer->uClass], 0, 0, 0);
-    pRenderer->DrawTextureTransparent(pOrder + 77, 50, pTexture_IC_KNIGHT[pPlayer->uClass/4]);
+
+  //for ( pPlayer = pParty->pPlayers; (signed int)pPlayer->pName < (signed int)&pParty->pPickedItem.uNumCharges; pPlayer++)
+  for (int i = 0; i < 4; ++i)
+  {
+    auto player = pParty->pPlayers + i;
+
+    //Str = pPlayer->pName;
+	pGUIWindow_CurrentMenu->DrawText(pFontCreate, pOrder + 73, 100, 0, pClassNames[player->classType], 0, 0, 0);
+    pRenderer->DrawTextureTransparent(pOrder + 77, 50, pTexture_IC_KNIGHT[player->classType / 4]);
     v11 = pGUIWindow_CurrentMenu->field_40;
     if ( v11 && (v12 = pGUIWindow_CurrentMenu->ptr_1C, v12 == v124) )
     {
@@ -5483,7 +5449,7 @@
           if ( v14 == 1 )
           {
             pGUIWindow_CurrentMenu->field_40 = 0;
-            pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pOrder, 124, 0, Str, 130, 0);
+            pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pOrder, 124, 0, player->pName, 130, 0);
             SetCurrentMenuID(MENU_7);
           }
         }
@@ -5505,9 +5471,9 @@
             while ( v133 < v16 );
           }
           if ( v120 && v126 != v120 )
-            strcpy(Str, (const char *)pKeyActionMap->pPressedKeysBuffer);
-          pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pOrder, 0x7C, 0, Str, 130, 0);
-          *((short *)pPlayer->pName + 3323) = 1; //
+            strcpy(player->pName, (const char *)pKeyActionMap->pPressedKeysBuffer);
+          pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pOrder, 0x7C, 0, player->pName, 130, 0);
+          *(short *)&player->field_1988[27] = 1; //
         }
       }
       else
@@ -5518,10 +5484,9 @@
     }
     else
     {
-      pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pOrder, 0x7C, 0, pPlayer->pName, 130, 0);
-    }
-    uNumRace = pPlayer->GetRace();
-     switch (uNumRace)
+      pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pOrder, 0x7C, 0, player->pName, 130, 0);
+    }
+    switch (player->GetRace())
     {
       case 0:  uRaceName = pGlobalTXT_LocalizationStrings[99]; break; // "Human"       
       case 1:  uRaceName = pGlobalTXT_LocalizationStrings[103]; break; // "Dwarf"
@@ -5532,50 +5497,50 @@
     pGUIWindow_CurrentMenu->DrawTextInRect(pFontCreate, pOrder + 72, v128 + 12, 0, pTmpBuf, 130, 0);
     pTextCenter = pFontCreate->AlignText_Center(0x96, pText);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + uX - 24, 291, uColor1, pText, 0, 0, 0);
-    uNumMight = pPlayer->GetActualMight();
+    uNumMight = player->GetActualMight();
     sprintf(pTmpBuf, "%s\r%03d%d", pGlobalTXT_LocalizationStrings[144], v129, uNumMight);// "Might"
-    LOWORD(v24) = pPlayer->GetStatColor(0);
+    LOWORD(v24) = player->GetStatColor(0);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 169, v24, pTmpBuf, 0, 0, 0);
-    v25 = pPlayer->GetActualIntelligence();
+    v25 = player->GetActualIntelligence();
     sprintf(pTmpBuf, "%s\r%03d%d", pGlobalTXT_LocalizationStrings[116], v129, v25);// "Intellect"
-    LOWORD(v26) = pPlayer->GetStatColor(1);
+    LOWORD(v26) = player->GetStatColor(1);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, v128 + 169, v26, pTmpBuf, 0, 0, 0);
-    v27 = pPlayer->GetActualWillpower();
+    v27 = player->GetActualWillpower();
     sprintf(pTmpBuf, "%s\r%03d%d", pGlobalTXT_LocalizationStrings[163], v129, v27);// "Personality"
-    LOWORD(v28) = pPlayer->GetStatColor(2);
+    LOWORD(v28) = player->GetStatColor(2);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 2 * v128 + 169, v28, pTmpBuf, 0, 0, 0);
-    v29 = pPlayer->GetActualEndurance();
+    v29 = player->GetActualEndurance();
     sprintf(pTmpBuf, "%s\r%03d%d", pGlobalTXT_LocalizationStrings[75], v129, v29);// "Endurance"
-    LOWORD(v30) = pPlayer->GetStatColor(3);
+    LOWORD(v30) = player->GetStatColor(3);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, uY, v30, pTmpBuf, 0, 0, 0);
-    v31 = pPlayer->GetActualAccuracy();
+    v31 = player->GetActualAccuracy();
     sprintf(pTmpBuf, "%s\r%03d%d", pGlobalTXT_LocalizationStrings[1], v129, v31);// "Accuracy"
-    LOWORD(v32) = pPlayer->GetStatColor(4);
+    LOWORD(v32) = player->GetStatColor(4);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, 4 * v128 + 169, v32, pTmpBuf, 0, 0, 0);
-    v33 = pPlayer->GetActualSpeed();
+    v33 = player->GetActualSpeed();
     sprintf(pTmpBuf, "%s\r%03d%d", pGlobalTXT_LocalizationStrings[211], v129, v33);// "Speed"
-    LOWORD(v34) = pPlayer->GetStatColor(5);
+    LOWORD(v34) = player->GetStatColor(5);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, v122, v34, pTmpBuf, 0, 0, 0);
-    v35 = pPlayer->GetActualLuck();
+    v35 = player->GetActualLuck();
     sprintf(pTmpBuf, "%s\r%03d%d", pGlobalTXT_LocalizationStrings[136], v129, v35);// "Luck"
-    LOWORD(v36) = pPlayer->GetStatColor(6u);
+    LOWORD(v36) = player->GetStatColor(6u);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX, v119, v36, pTmpBuf, 0, 0, 0);
-    v37 = pPlayer->GetSkillIdxByOrder(0);
+    v37 = player->GetSkillIdxByOrder(0);
     pTextCenter = pFontCreate->AlignText_Center(0x96u, pSkillNames[v37]);
     sprintf(pTmpBuf, "\t%03u%s", pTextCenter, pSkillNames[v37]);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX - 24, 311, uColorWhite, pTmpBuf, 0, 0, 0);
-    v39 = pPlayer->GetSkillIdxByOrder(1);
+    v39 = player->GetSkillIdxByOrder(1);
     pTextCenter = pFontCreate->AlignText_Center(0x96u, pSkillNames[v39]);
     sprintf(pTmpBuf, "\t%03u%s", pTextCenter, pSkillNames[v39]);
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX - 24, v128 + 311, uColorWhite, pTmpBuf, 0, 0, 0);
-    v41 = pPlayer->GetSkillIdxByOrder(2);
+    v41 = player->GetSkillIdxByOrder(2);
     pTextCenter = pFontCreate->AlignText_Center(150u, pSkillNames[v41]);
     sprintf(pTmpBuf, "\t%03u%s", pTextCenter, pSkillNames[v41]);
     v45 = uColorGreen;
     if ( (signed int)v41 >= 37 )
       v45 = uColorTeal;
     pGUIWindow_CurrentMenu->DrawText(pFontCreate, uX - 24, 2 * v128 + 311, v45, pTmpBuf, 0, 0, 0);
-    v46 = pPlayer->GetSkillIdxByOrder(3);
+    v46 = player->GetSkillIdxByOrder(3);
     pTextCenter = pFontCreate->AlignText_Center(150u, pSkillNames[v46]);
     sprintf(pTmpBuf, "\t%03u%s", pTextCenter, pSkillNames[v46]);
     v50 = uColorGreen;
@@ -5588,6 +5553,7 @@
     v129 -= 158;
     uX += 158;
   }
+
   //while ( (signed int)pPlayer->pName < (signed int)&pParty->pPickedItem.uNumCharges );
   strcpy(pText, pGlobalTXT_LocalizationStrings[41]);// "Class"
   v51 = strlen(pText) - 1;
@@ -5605,7 +5571,7 @@
       v51 = pOrder;
     }
   }
-  uClassType = pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].uClass;
+  uClassType = pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].classType;
   pTextCenter = pFontCreate->AlignText_Center(193u, pText);
   pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 324, 395, uColor1, pText, 0, 0, 0);
   v57 = uColorTeal;
@@ -5630,7 +5596,7 @@
   pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[24]);
   pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 388, 417, v71, pClassNames[24], 0, 0, 0);
   v75 = uColorTeal;
-  if ( uClassType != 28 )
+  if ( uClassType != PLAYER_CLASS_DRUID)
     v75 = uColorWhite;
   pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[28]);
   pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 388, uColorGreen, v75, pClassNames[28], 0, 0, 0);
@@ -5744,18 +5710,18 @@
   uPlayerCreationUI_SkySliderPos = 0;
   uPlayerCreationUI_SelectedCharacter = 0;
   v0 = LOBYTE(pFontCreate->uFontHeight) - 2;
-  pTexture_IC_KNIGHT[0] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_KNIGHT", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[1] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_THIEF", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[2] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_MONK", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[3] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_PALAD", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[4] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_ARCH", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[5] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_RANGER", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[6] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_CLER", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[7] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_DRUID", TEXTURE_16BIT_PALETTE)];
-  pTexture_IC_KNIGHT[8] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("IC_SORC", TEXTURE_16BIT_PALETTE)];
-  pTexture_MAKETOP   = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("MAKETOP", TEXTURE_16BIT_PALETTE)];
+  pTexture_IC_KNIGHT[0] = pIcons_LOD->LoadTexturePtr("IC_KNIGHT", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[1] = pIcons_LOD->LoadTexturePtr("IC_THIEF", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[2] = pIcons_LOD->LoadTexturePtr("IC_MONK", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[3] = pIcons_LOD->LoadTexturePtr("IC_PALAD", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[4] = pIcons_LOD->LoadTexturePtr("IC_ARCH", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[5] = pIcons_LOD->LoadTexturePtr("IC_RANGER", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[6] = pIcons_LOD->LoadTexturePtr("IC_CLER", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[7] = pIcons_LOD->LoadTexturePtr("IC_DRUID", TEXTURE_16BIT_PALETTE);
+  pTexture_IC_KNIGHT[8] = pIcons_LOD->LoadTexturePtr("IC_SORC", TEXTURE_16BIT_PALETTE);
+  pTexture_MAKETOP = pIcons_LOD->LoadTexturePtr("MAKETOP", TEXTURE_16BIT_PALETTE);
+  pTexture_MAKESKY = pIcons_LOD->LoadTexturePtr("MAKESKY", TEXTURE_16BIT_PALETTE);
   uX = 0;
-  pTexture_MAKESKY = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("MAKESKY", TEXTURE_16BIT_PALETTE)];
   do // load PlayerPortraits texture
   {
     sprintf(pTmpBuf, "%s01", pPlayerPortraitsNames[uX]);
@@ -5860,9 +5826,9 @@
   }
   while ( uControlParamd < 9 );
   pPlayerCreationUI_BtnOK = pGUIWindow_CurrentMenu->CreateButton(580, 431, 51, 39, 1, 0, 0x42, 0, 0xD, "",
-                              (Texture *)(uTextureID_BUTTMAKE != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTMAKE] : 0), 0);
+                              (Texture *)(uTextureID_BUTTMAKE != -1 ? &pIcons_LOD->pTextures[uTextureID_BUTTMAKE] : 0), 0);
   pPlayerCreationUI_BtnReset = pGUIWindow_CurrentMenu->CreateButton(527, 431, 51, 39, 1, 0, 0x43, 0, 0x43, "",
-                                 (Texture *)(uTextureID_BUTTMAKE2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTMAKE2] : 0), 0);
+                                 (Texture *)(uTextureID_BUTTMAKE2 != -1 ? &pIcons_LOD->pTextures[uTextureID_BUTTMAKE2] : 0), 0);
   pPlayerCreationUI_BtnMinus = pGUIWindow_CurrentMenu->CreateButton(523, 393, 20, 35, 1, 0, 0x3F, 0, 0x2D, "", pTexture_buttminu, 0);
   pPlayerCreationUI_BtnPlus = pGUIWindow_CurrentMenu->CreateButton(613, 393, 20, 35, 1, 0, 0x3E, 1, 0x2B, "", pTexture_buttplus, 0);
   pFontCChar = LoadFont("cchar.fnt", "FONTPAL", 0);
@@ -6023,7 +5989,7 @@
   for ( pPlayer = &pParty->pPlayers[0];  pPlayer < &pParty->pPlayers[4]; pPlayer++)
   {
     //v11 = pPlayer;
-    if ( !pPlayer->uClass )
+    if (pPlayer->classType == PLAYER_CLASS_KNIGHT)
       pPlayer->sResMagicBase = 10;
     //*((short *)v10 + 400) = 0;
     pPlayer->pPlayerBuffs[22].uExpireTime = 0;
@@ -6827,7 +6793,7 @@
                  pSrc + 8 + 460/*462*/ + y * 640, 174/*172*/ * sizeof(__int16));
         }
 
-        for (uint y = 351/*352*/; y < 480; ++y)
+        for (uint y = 352; y < 480; ++y)
           memcpy(pDst + y * Dst.lPitch / 2,
                  pSrc + y * 640, 640 * sizeof(__int16));
 
@@ -6841,7 +6807,7 @@
         v22 = 4 * ((Dst.lPitch / 4) + v9);
         v21 = 4 * v9 + 1280;
 
-        auto uNumLines = pViewport->uViewportW - pViewport->uViewportY + 1;
+        //auto uNumLines = pViewport->uViewportW - pViewport->uViewportY + 1;
         //v26 = (LPVOID)(pViewport->uViewportW - pViewport->uViewportY + 1);
         v10 = (int)pSrc_x1y1;
         v11 = (int)pDst_x1y1;
@@ -9241,7 +9207,7 @@
     ++v6;
   }
   while ( v6 <= &pParty->pPlayers[3] );
-  pParty->_4909F4();
+  pParty->UpdatePlayersAndHirelingsEmotions();
 }
 // 507B94: using guessed type int dword_507B94;
 
@@ -9411,7 +9377,7 @@
     v9 = 0;
     while ( 1 )
     {
-	  if ( v12->uClass == 35 )
+      if ( v12->classType == PLAYER_CLASS_LICH )
       {
         v10 = 0;
         v6 = pParty->pPlayers;//[0].pInventoryItems[0].field_1A;
@@ -9506,10 +9472,10 @@
           v3 = v2->bDrawSomeAnim;
           break;
         case 20:
-          v3 = v2->evtb;
+          v3 = v2->_anim_current_time;
           break;
         case 21:
-          v3 = v2->evtc;
+          v3 = v2->_anim_end_time;
           break;
         default:
           if ( a1 != 22 )
@@ -9630,14 +9596,14 @@
                 v2->bDrawSomeAnim = 0;
               break;
             case 20:
-              v9 = v2->evtb;
+              v9 = v2->_anim_current_time;
               if ( v9 >= 400 && v9 <= 416 )
-                v2->evtb = 0;
+                v2->_anim_current_time = 0;
               break;
             case 21:
-              v8 = v2->evtc;
+              v8 = v2->_anim_end_time;
               if ( v8 >= 400 && v8 <= 416 )
-                v2->evtc = 0;
+                v2->_anim_end_time = 0;
               break;
             case 22:
               v7 = v2->evtd;
@@ -9810,7 +9776,7 @@
     dword_F8B1B4 = 2000;
     dword_F8B1B0 = 2;
   }
-  v5 = v1->uClass;
+  v5 = v1->classType;
   v33 = v5;
   v6 = byte_4ED970_skill_learn_ability_by_class_table[v5][v3];
   *(int *)a1 = v1->pActiveSkills[v3];
@@ -10322,7 +10288,7 @@
           v20 = v19 - 1;
           if ( !v20 )
           {
-			v15 = (char *)pNPCTopics[v58->evtb-1].pTopic;//(&dword_721660)[8 * v58->evtb];
+            v15 = (char *)pNPCTopics[v58->_anim_current_time-1].pTopic;//(&dword_721660)[8 * v58->evtb];
             if ( !v15 )
             {
               v16->uControlParam = 0;
@@ -10338,7 +10304,7 @@
           v21 = v20 - 1;
           if ( !v21 )
           {
-            v23 = v58->evtc;
+            v23 = v58->_anim_end_time;
             goto LABEL_33;
           }
           v22 = v21 - 1;
@@ -11418,7 +11384,7 @@
               0);
         }
       }
-      v7 = (void *)v17->evtb;
+      v7 = (void *)v17->_anim_current_time;
       if ( v7 )
       {
         if ( v1 < 4 )
@@ -11439,7 +11405,7 @@
               0);
         }
       }
-      v9 = (void *)v17->evtc;
+      v9 = (void *)v17->_anim_end_time;
       if ( v9 )
       {
         if ( v1 < 4 )
@@ -11659,7 +11625,7 @@
   v66 = 1000 * v3;
   if ( (signed __int64)__PAIR__(v6, LODWORD(v0->uExperience)) >= v66 )
   {
-    v8 = v0->uClass % 4 + 1;
+    v8 = v0->classType % 4 + 1;
     if ( v8 == 4 )
       v8 = 3;
     v9 = (double)(signed int)i;
@@ -11700,7 +11666,7 @@
             do
             {
               v17 = v13->GetControl(v15)->uControlParam - 36;
-              if ( byte_4ED970_skill_learn_ability_by_class_table[v0->uClass][v17] && !v0->pActiveSkills[v17] )
+              if ( byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v17] && !v0->pActiveSkills[v17] )
               {
                 v18 = pFontArrus->CalcTextHeight(pSkillNames[v17], &v65, 0, 0);
                 i += v18;
@@ -11728,7 +11694,7 @@
                   v20 = v13->GetControl(i);
                   v21 = v20;
                   v22 = v20->uControlParam - 36;
-                  if ( !byte_4ED970_skill_learn_ability_by_class_table[v0->uClass][v22] || v0->pActiveSkills[v22] )
+                  if ( !byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v22] || v0->pActiveSkills[v22] )
                   {
                     v21->uW = 0;
                     v21->uHeight = 0;
@@ -11761,7 +11727,7 @@
             else
             {
 LABEL_76:
-              sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v0->pName, pClassNames[v0->uClass]);// 
+              sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v0->pName, pClassNames[v0->classType]);// 
                                                 // "Seek knowledge elsewhere %s the %s"
               strcat(pTmpBuf, "\n \n");
               strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
@@ -12171,7 +12137,7 @@
           do
           {
             v36 = v31->GetControl(v34)->uControlParam - 36;
-            if ( byte_4ED970_skill_learn_ability_by_class_table[_this->uClass][v36] && !_this->pActiveSkills[v36] )
+            if ( byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v36] && !_this->pActiveSkills[v36] )
             {
               v37 = pFontArrus->CalcTextHeight(pSkillNames[v36], &v112, 0, 0);
               v118 += v37;
@@ -12183,7 +12149,7 @@
           if ( !v122 )
           {
 LABEL_140:
-            sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], _this->pName, pClassNames[_this->uClass]);// 
+            sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], _this->pName, pClassNames[_this->classType]);// 
                                                 // "Seek knowledge elsewhere %s the %s"
             strcat(pTmpBuf, "\n \n");
             strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);// "I can offer you nothing further."
@@ -12213,7 +12179,7 @@
               v39 = v31->GetControl(v118);
               v40 = v39;
               v41 = v39->uControlParam - 36;
-              if ( !byte_4ED970_skill_learn_ability_by_class_table[_this->uClass][v41] || _this->pActiveSkills[v41] )
+              if ( !byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v41] || _this->pActiveSkills[v41] )
               {
                 v40->uW = 0;
                 v40->uHeight = 0;
@@ -12838,12 +12804,12 @@
   }
   if ( v3 == 20 )
   {
-    v4 = v2->evtb;
+    v4 = v2->_anim_current_time;
     goto LABEL_74;
   }
   if ( v3 == 21 )
   {
-    v4 = v2->evtc;
+    v4 = v2->_anim_end_time;
 LABEL_74:
     if ( v4 < 200 || v4 > 310 )
     {
@@ -13224,7 +13190,7 @@
   if ( !v61 )
   {
 LABEL_64:
-    sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v58->pName, pClassNames[v58->uClass]);
+    sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v58->pName, pClassNames[v58->classType]);
     strcat(pTmpBuf, "\n \n");
     strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
     v18 = pTmpBuf;
@@ -13416,7 +13382,7 @@
             do
             {
               v9 = v4->GetControl(v62)->uControlParam - 36;
-              if ( byte_4ED970_skill_learn_ability_by_class_table[v1->uClass][v9] && !v1->pActiveSkills[v9] )
+              if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v9] && !v1->pActiveSkills[v9] )
               {
                 v10 = pFontArrus->CalcTextHeight(pSkillNames[v9], &v57, 0, 0);
                 v66 = (DDM_DLV_Header *)((char *)v66 + v10);
@@ -13446,7 +13412,7 @@
                   v14 = v12->GetControl(v62);
                   v15 = v14;
                   v16 = v14->uControlParam - 36;
-                  if ( !byte_4ED970_skill_learn_ability_by_class_table[v1->uClass][v16] || v1->pActiveSkills[v16] )
+                  if ( !byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v16] || v1->pActiveSkills[v16] )
                   {
                     v15->uW = 0;
                     v15->uHeight = 0;
@@ -13480,7 +13446,7 @@
             else
             {
 LABEL_78:
-              sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v1->pName, pClassNames[v1->uClass]);
+              sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v1->pName, pClassNames[v1->classType]);
               strcat(pTmpBuf, "\n \n");
               strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
               v22 = WORD2(v59);
@@ -13916,7 +13882,7 @@
   do
   {
     v11 = v8->GetControl(v35)->uControlParam - 36;
-    if ( byte_4ED970_skill_learn_ability_by_class_table[v1->uClass / 3][v11] && !v1->pActiveSkills[v11] )
+    if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType / 3][v11] && !v1->pActiveSkills[v11] )
     {
       v12 = pFontArrus->CalcTextHeight(pSkillNames[v11], &v28, 0, 0);
       v33 += v12;
@@ -13929,7 +13895,7 @@
   if ( !v34 )
   {
 LABEL_40:
-    sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v1->pName, pClassNames[v1->uClass]);
+    sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[544], v1->pName, pClassNames[v1->classType]);
     strcat(pTmpBuf, "\n \n");
     strcat(pTmpBuf, pGlobalTXT_LocalizationStrings[528]);
     v22 = v31;
@@ -13951,7 +13917,7 @@
     {
       v14 = v8->GetControl(v35);
       v15 = v14->uControlParam - 36;
-      if ( byte_4ED970_skill_learn_ability_by_class_table[v1->uClass / 3][v15] )
+      if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType / 3][v15] )
       {
         v16 = 0;
         if ( !v1->pActiveSkills[v15] )
--- a/mm7_5.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_5.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -3498,7 +3498,7 @@
           goto _sprintex_2args_draw_status_and_continue;
         case UIMSG_ShowStatus_Player:
           pPlayer5 = pPlayers[uMessageParam];
-          sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[429], pPlayer5->pName, pClassNames[pPlayer5->uClass]);// "%s the %s"
+          sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[429], pPlayer5->pName, pClassNames[pPlayer5->classType]);// "%s the %s"
           strcat(pTmpBuf, ": ");
           v107 = pPlayer5->GetMajorConditionIdx();
           strcat(pTmpBuf, aCharacterConditionNames[v107]);
@@ -4149,7 +4149,7 @@
           }
           if ( pUIMessageType == UIMSG_PlayerCreationSelectClass )
           {
-            (&pPlayer[uPlayerCreationUI_SelectedCharacter])->Reset(uNum);
+            pPlayer[uPlayerCreationUI_SelectedCharacter].Reset((PLAYER_CLASS_TYPE)uNum);
             pAudioPlayer->PlaySound((SoundID)66, 0, 0, -1, 0, 0, 0, 0);
             continue;
           }
@@ -8643,10 +8643,8 @@
   v47 = pPlayers[uPlayerID];
   pIcons_LOD->LoadTexture("sptext01", TEXTURE_16BIT_PALETTE);
   CharacterUI_DrawPaperdoll(v1);
-  pRenderer->DrawTextureTransparent(0x1D9u, 0,
-    (Texture *)(uTextureID_BACKHAND != -1 ? &pIcons_LOD->pTextures[uTextureID_BACKHAND] : 0));
-  pRenderer->DrawTextureTransparent(0x1D4u, 0,
-    (Texture *)(uTextureID_507B04 != -1 ? &pIcons_LOD->pTextures[uTextureID_507B04] : 0));
+  pRenderer->DrawTextureTransparent(0x1D9u, 0, (Texture *)(uTextureID_BACKHAND != -1 ? &pIcons_LOD->pTextures[uTextureID_BACKHAND] : 0));
+  pRenderer->DrawTextureTransparent(0x1D4u, 0, (Texture *)(uTextureID_507B04 != -1 ? &pIcons_LOD->pTextures[uTextureID_507B04] : 0));
   pRenderer->DrawTextureIndexed(pCharacterScreen_DetalizBtn->uX, pCharacterScreen_DetalizBtn->uY,
     (Texture *)(uTextureID_5118C8 != -1 ? &pIcons_LOD->pTextures[uTextureID_5118C8] : 0));
   v3 = 0;
@@ -8658,8 +8656,8 @@
       goto LABEL_24;
     v39 = *(int *)v46;
     v4 = (int)&pPlayer->spellbook.pDarkSpellbook.bIsSpellAvailable[36 * *(int *)v46 + 5];
-    a3 = *(int *)((char *)dword_4E5C34 + v3);
-    a2 = *(int *)((char *)dword_4E5C1C + v3);
+    a3 = pPaperdollRingsY[v3];
+    a2 = pPaperdollRingsX[v3];
     v5 = pIcons_LOD->LoadTexture(pItemsTable->pItems[*(int *)v4].pIconName, TEXTURE_16BIT_PALETTE);
     v6 = *(int *)(v4 + 20);
     if ( *(int *)(v4 + 20) & 0xF0 )
@@ -8891,7 +8889,6 @@
     v31, (signed __int64)v32, 0, 255);
 }
 
-
 //----- (0043ED6F) --------------------------------------------------------
 bool _43ED6F_check_party_races(bool a1)
 {
@@ -16450,7 +16447,7 @@
       break;
 	 case 118: // Character info
       pStr = pParty->pPlayers[pButton->uControlParam].pName;
-      pWindow.Hint = pClassDescriptions[pParty->pPlayers[pButton->uControlParam].uClass];
+      pWindow.Hint = pClassDescriptions[pParty->pPlayers[pButton->uControlParam].classType];
       break;
      }
      if ( pControlID > 68 && pControlID <= 75 ) //Sellected skills info
@@ -16908,19 +16905,19 @@
   if ( (v8 & 0x3F) == (v7 & 0x3F) )
   {
     strcpy(a2, "%s\n\n");
-    v24 = sub_417AD4(pPlayer->uClass, v2, 1);
+    v24 = sub_417AD4(pPlayer->classType, v2, 1);
     sprintf(Source, format_4E2DC8, v24);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
-    v25 = sub_417AD4(pPlayer->uClass, v36, 2);
+    v25 = sub_417AD4(pPlayer->classType, v36, 2);
     sprintf(Source, format_4E2DC8, v25);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
-    v26 = sub_417AD4(pPlayer->uClass, v36, 3);
+    v26 = sub_417AD4(pPlayer->classType, v36, 3);
     sprintf(Source, format_4E2DC8, v26);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
-    v27 = pPlayer->uClass;
+    v27 = pPlayer->classType;
     v28 = v36;
     v29 = sub_417AD4(v27, v36, 4);
     sprintf(Source, format_4E2DC8, v29);
@@ -16952,20 +16949,20 @@
   else
   {
     strcpy(a2, "%s\n\n");
-    v9 = sub_417AD4(pPlayer->uClass, v2, 1);
+    v9 = sub_417AD4(pPlayer->classType, v2, 1);
     sprintf(Source, format_4E2DC8, v9);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
-    v10 = sub_417AD4(pPlayer->uClass, v36, 2);
+    v10 = sub_417AD4(pPlayer->classType, v36, 2);
     sprintf(Source, format_4E2DC8, v10);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
-    v11 = sub_417AD4(pPlayer->uClass, v36, 3);
+    v11 = sub_417AD4(pPlayer->classType, v36, 3);
     sprintf(Source, format_4E2DC8, v11);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n");
     v12 = v36;
-    v13 = sub_417AD4(pPlayer->uClass, v36, 4);
+    v13 = sub_417AD4(pPlayer->classType, v36, 4);
     sprintf(Source, format_4E2DC8, v13);
     strcat(a2, Source);
     strcat(a2, "%s\t%03d:\t%03d%s\t000\n\n");
@@ -17262,7 +17259,7 @@
       v24 = pGlobalTXT_LocalizationStrings[207];
       goto LABEL_47;
     case 26:
-      _y = (Player *)(4 * pPlayers[uActiveCharacter]->uClass);
+      _y = (Player *)(4 * pPlayers[uActiveCharacter]->classType);
       v6 = *(char **)((char *)_y->pConditions + (int)pClassNames);
       v7 = *(char **)((char *)_y->pConditions + (int)pClassDescriptions);
 LABEL_46:
@@ -17423,7 +17420,7 @@
   pRenderer->DrawTextureIndexed(8, 8, (Texture *)(v2 != -1 ? (int)&pIcons_LOD->pTextures[v2] : 0));
   v3 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
   sprintf(pTmpBuf, format_4E2DC8, v3);
-  sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], pPlayer->pName, pClassNames[pPlayer->uClass]);//^Pi[%s] %s
+  sprintf(pTmpBuf2, pGlobalTXT_LocalizationStrings[429], pPlayer->pName, pClassNames[pPlayer->classType]);//^Pi[%s] %s
   strcat(pTmpBuf, pTmpBuf2);
   if ( pPlayer->uSkillPoints )
     v4 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0xFFu, 0);
@@ -17623,7 +17620,7 @@
   v103 = v102;
   v104 = UI_GetHealthManaStringColor(v135, v102);
   sprintf(pTmpBuf, a2g, pGlobalTXT_LocalizationStrings[142], v104, v135, v103);
-  if ( pPlayer->uClass == 35 && v137 == 200 )
+  if ( pPlayer->classType == PLAYER_CLASS_LICH && v137 == 200 )
   {
     v105 = pGlobalTXT_LocalizationStrings[625];
     v106 = UI_GetHealthManaStringColor(v135, 200);
@@ -17640,7 +17637,7 @@
   v108 = v107;
   v109 = UI_GetHealthManaStringColor(v136, v107);
   sprintf(pTmpBuf, a2h, pGlobalTXT_LocalizationStrings[29], v109, v136, v108);
-  if ( pPlayer->uClass == 35 && v138 == 200 )
+  if ( pPlayer->classType == PLAYER_CLASS_LICH && v138 == 200 )
   {
     v110 = pGlobalTXT_LocalizationStrings[625];
     v111 = UI_GetHealthManaStringColor(v136, 200);
--- a/mm7_6.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_6.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -1655,7 +1655,7 @@
         while ( 1 )
         {
           v14 = 0;
-          if ( v27 != -1 && v27 == pPlayers[v13 + 1]->uClass )
+          if ( v27 != -1 && v27 == pPlayers[v13 + 1]->classType )
             v14 = v4;
           if ( v25 != -1 && v25 == pPlayers[v13 + 1]->uSex )
             v14 = v4;
--- a/mm7_data.cpp	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_data.cpp	Tue Feb 12 09:11:19 2013 +0600
@@ -701,8 +701,8 @@
   0x1F, 0xB8,
 };
 int pPaperdollLeftEmptyHand[8];
-int dword_4E5C1C[6];
-int dword_4E5C34[6];
+int pPaperdollRingsX[6] = {0x1EA, 0x21A, 0x248, 0x1EA, 0x21A, 0x248};
+int pPaperdollRingsY[6] = {0x0CA, 0x0CA, 0x0CA, 0x0FA, 0x0FA, 0x0FA};
 char aItem092v3[777]; // idb
 char aIbCd5D[777]; // idb
 char aAr_dn_dn[777]; // idb
@@ -1763,18 +1763,18 @@
 int dword_76D53C_terrain_cell_world_pos_around_party_x; // weak
 int dword_76D540_terrain_cell_world_pos_around_party_x; // weak
 int dword_76D544_terrain_cell_world_pos_around_party_x; // weak
-int dword_76D548_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D550_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D554_terrain_cell_world_pos_around_party_y; // weak
-int dword_76D558_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D560_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D564_terrain_cell_world_pos_around_party_z; // weak
-int dword_76D568_terrain_cell_world_pos_around_party_x; // weak
-int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak
-int dword_76D570_terrain_cell_world_pos_around_party_x; // weak
-int dword_76D574_terrain_cell_world_pos_around_party_x; // weak
+//int dword_76D548_terrain_cell_world_pos_around_party_y; // weak
+//int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak
+//int dword_76D550_terrain_cell_world_pos_around_party_y; // weak
+//int dword_76D554_terrain_cell_world_pos_around_party_y; // weak
+//int dword_76D558_terrain_cell_world_pos_around_party_z; // weak
+//int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak
+//int dword_76D560_terrain_cell_world_pos_around_party_z; // weak
+//int dword_76D564_terrain_cell_world_pos_around_party_z; // weak
+//int dword_76D568_terrain_cell_world_pos_around_party_x; // weak
+//int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak
+//int dword_76D570_terrain_cell_world_pos_around_party_x; // weak
+//int dword_76D574_terrain_cell_world_pos_around_party_x; // weak
 struct unk_F7B60C stru_76D578; // struct @ MM7.exe::0076D578
 struct unk_F7B60C stru_76D590; // struct @ MM7.exe::0076D590
 struct unk_F7B60C stru_76D5A8; // struct @ MM7.exe::0076D5A8
--- a/mm7_data.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/mm7_data.h	Tue Feb 12 09:11:19 2013 +0600
@@ -648,8 +648,8 @@
 extern int pPaperdoll_SecondLeftHand[8];
 extern int pPaperdoll_RightHand[8];
 extern int pPaperdollLeftEmptyHand[8];
-extern int dword_4E5C1C[6];
-extern int dword_4E5C34[6];
+extern int pPaperdollRingsX[6];
+extern int pPaperdollRingsY[6];
 extern char aItem092v3[]; // idb
 extern char aIbCd5D[]; // idb
 extern char aAr_dn_dn[]; // idb
@@ -1608,18 +1608,18 @@
 extern int dword_76D53C_terrain_cell_world_pos_around_party_x; // weak
 extern int dword_76D540_terrain_cell_world_pos_around_party_x; // weak
 extern int dword_76D544_terrain_cell_world_pos_around_party_x; // weak
-extern int dword_76D548_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D550_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D554_terrain_cell_world_pos_around_party_y; // weak
-extern int dword_76D558_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D560_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D564_terrain_cell_world_pos_around_party_z; // weak
-extern int dword_76D568_terrain_cell_world_pos_around_party_x; // weak
-extern int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak
-extern int dword_76D570_terrain_cell_world_pos_around_party_x; // weak
-extern int dword_76D574_terrain_cell_world_pos_around_party_x; // weak
+//extern int dword_76D548_terrain_cell_world_pos_around_party_y; // weak
+//extern int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak
+//extern int dword_76D550_terrain_cell_world_pos_around_party_y; // weak
+//extern int dword_76D554_terrain_cell_world_pos_around_party_y; // weak
+//extern int dword_76D558_terrain_cell_world_pos_around_party_z; // weak
+//extern int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak
+//extern int dword_76D560_terrain_cell_world_pos_around_party_z; // weak
+//extern int dword_76D564_terrain_cell_world_pos_around_party_z; // weak
+//extern int dword_76D568_terrain_cell_world_pos_around_party_x; // weak
+//extern int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak
+//extern int dword_76D570_terrain_cell_world_pos_around_party_x; // weak
+//extern int dword_76D574_terrain_cell_world_pos_around_party_x; // weak
 extern char byte_76D5C0;
 extern struct unk_F7B60C stru_76D578;
 extern struct unk_F7B60C stru_76D590;
@@ -2163,7 +2163,7 @@
 int _46CEC3_get_floor_level(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID);
 int __fastcall sub_46D49E_prolly_get_world_y_under_party(int a1, signed int a2, int a3, int a4, int *a5, int *a6, int a7);
 int __fastcall sub_46D8E3(int a1, signed int a2, int a3, int a4);
-signed __int64 __fastcall _46DCC8_get_gravity_direction_outdoor(int a1, int a2, Vec3_int_ *a3);
+void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out);
 unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID);
 int __fastcall _46DF1A_collide_against_actor(int, int); // weak
 void __cdecl _46E0B2_collide_against_decorations();
@@ -2225,7 +2225,7 @@
 void __cdecl sub_481ED9_MessWithOutdoorCamera();
 bool __fastcall sub_481EFA(RenderVertexSoft *a1, RenderVertexSoft *a2, RenderVertexSoft *a3, RenderVertexSoft *a4, int a5);
 signed int __fastcall sub_481FC9(RenderVertexSoft *_ECX, RenderVertexSoft *a2, RenderVertexSoft *a3, stru148 *a4);
-bool __fastcall GetTerrainHeightsAroundParty(int a1, int a2);
+bool IsTerrainSlopeTooHigh(int pos_x, int pos_y);
 int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4);
 struct stru148 *__fastcall sr_sub_4829B9(RenderVertexSoft *a1, RenderVertexSoft *a2, RenderVertexSoft *a3, stru148 *a4, int a5);
 signed int __cdecl const_1_0();
--- a/stru279.h	Tue Feb 12 09:11:03 2013 +0600
+++ b/stru279.h	Tue Feb 12 09:11:19 2013 +0600
@@ -8,12 +8,12 @@
   //----- (0043B506) --------------------------------------------------------
   stru279()
   {
-  this->field_4 = 0;
-  this->field_8 = 0;
-  this->field_C = 0;
-  this->field_10 = 0;
-  this->field_14 = 0;
-  this->registry_debug_flags = 0;
+    this->field_4 = 0;
+    this->field_8 = 0;
+    this->field_C = 0;
+    this->field_10 = 0;
+    this->field_14 = 0;
+    this->registry_debug_flags = 0;
   }