changeset 1803:9f93b5700e2d

Merge
author Nomad
date Mon, 07 Oct 2013 11:55:35 +0200
parents 633f81bb3ae7 (current diff) 3a41be960164 (diff)
children 92ab1b3cc95a
files Render.cpp Render.h UI/UiGame.cpp mm7_2.cpp mm7_data.cpp mm7_data.h
diffstat 20 files changed, 1995 insertions(+), 2107 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/Actor.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -46,55 +46,40 @@
 
 
 //----- (0041AF52) --------------------------------------------------------
-void Actor::DrawHealthBar(Actor *a1, GUIWindow *a2)
+void Actor::DrawHealthBar(Actor *actor, GUIWindow *window)
 {
-  unsigned int v2; // eax@1
-  GUIWindow *v3; // edi@1
-  unsigned int v4; // esi@1
-  signed int v5; // ebx@4
-  double v6; // st7@5
-  unsigned int v7; // eax@6
-  unsigned int v8; // ebx@10
+  unsigned int bar_length; // esi@1
+  unsigned int uX; // ebx@10
   unsigned int v9; // [sp+14h] [bp-Ch]@4
   unsigned int v10; // [sp+1Ch] [bp-4h]@4
 
-  v2 = a1->pMonsterInfo.uHP;
-  v3 = a2;
-  v4 = 25;
-  if ( (signed int)v2 > 25 )
+  bar_length = 25;
+  if ( actor->pMonsterInfo.uHP > 25 )
   {
-    v4 = 200;
-    if ( (signed int)v2 < 200 )
-      v4 = a1->pMonsterInfo.uHP;
+    bar_length = 200;
+    if ( actor->pMonsterInfo.uHP < 200 )
+      bar_length = actor->pMonsterInfo.uHP;
   }
-  v5 = a1->sCurrentHP;
-  v10 = v4;
+  v10 = bar_length;
   v9 = uTextureID_mhp_grn;
-  if ( v5 < (signed int)v2 )
+  if ( actor->sCurrentHP < actor->pMonsterInfo.uHP )
   {
-    v6 = (double)(signed int)v2;
-    v10 = (signed __int64)((double)(signed int)v4 / (double)(signed int)v2 * (double)a1->sCurrentHP);
-    if ( v5 <= (signed int)(signed __int64)(0.34 * v6) )
-    {
-      v7 = uTextureID_mhp_red;
-      v9 = v7;
-    }
-    else if ( v5 <= (signed int)(signed __int64)(v6 * 0.67) )
-    {
-      v7 = uTextureID_mhp_yel;
-      v9 = v7;
-    }
+    v10 = bar_length / actor->pMonsterInfo.uHP * actor->sCurrentHP;
+    if ( actor->sCurrentHP <= (signed int)(signed __int64)(0.34 * (double)(signed int)actor->pMonsterInfo.uHP) )
+      v9 = uTextureID_mhp_red;
+    else if ( actor->sCurrentHP <= (signed int)(signed __int64)((double)(signed int)actor->pMonsterInfo.uHP * 0.67) )
+      v9 = uTextureID_mhp_yel;
   }
-  v8 = a2->uFrameX + (signed int)(a2->uFrameWidth - v4) / 2;
+  uX = window->uFrameX + (signed int)(window->uFrameWidth - bar_length) / 2;
 
-  pRenderer->SetTextureClipRect(v8, a2->uFrameY + 32, v8 + v4, a2->uFrameY + 52);
-  pRenderer->DrawTextureIndexed(v8, v3->uFrameY + 32, pIcons_LOD->GetTexture(uTextureID_mhp_bd));
-  pRenderer->SetTextureClipRect(v8, v3->uFrameY + 32, v8 + v10, v3->uFrameY + 52);
-  pRenderer->DrawTextureIndexed(v8, v3->uFrameY + 34, pIcons_LOD->GetTexture(v9));
+  pRenderer->SetTextureClipRect(uX, window->uFrameY + 32, uX + bar_length, window->uFrameY + 52);
+  pRenderer->DrawTextureIndexed(uX, window->uFrameY + 32, pIcons_LOD->GetTexture(uTextureID_mhp_bd));
+  pRenderer->SetTextureClipRect(uX, window->uFrameY + 32, uX + v10, window->uFrameY + 52);
+  pRenderer->DrawTextureIndexed(uX, window->uFrameY + 34, pIcons_LOD->GetTexture(v9));
 
   pRenderer->ResetTextureClipRect();
-  pRenderer->DrawTextureIndexed(v8 - 5, v3->uFrameY + 32, pIcons_LOD->GetTexture(uTextureID_mhp_capl));
-  pRenderer->DrawTextureIndexed(v8 + v4, v3->uFrameY + 32, pIcons_LOD->GetTexture(uTextureID_mhp_capr));
+  pRenderer->DrawTextureIndexed(uX - 5, window->uFrameY + 32, pIcons_LOD->GetTexture(uTextureID_mhp_capl));
+  pRenderer->DrawTextureIndexed(uX + bar_length, window->uFrameY + 32, pIcons_LOD->GetTexture(uTextureID_mhp_capr));
 }
 
 //----- (00448A40) --------------------------------------------------------
@@ -227,7 +212,6 @@
   }
 }
 
-  
 //----- (0040894B) --------------------------------------------------------
 bool Actor::CanAct()
 {
@@ -1910,16 +1894,13 @@
 //----- (00403E61) --------------------------------------------------------
 void __fastcall Actor::StandAwhile(unsigned int uActorID)
 {
-  Actor *v1; // esi@1
-
-  v1 = &pActors[uActorID];
-  v1->uCurrentActionLength = rand() % 128 + 128;
-  v1->uCurrentActionTime = 0;
-  v1->uAIState = Standing;
-  v1->vVelocity.z = 0;
-  v1->vVelocity.y = 0;
-  v1->vVelocity.x = 0;
-  v1->UpdateAnimation();
+  pActors[uActorID].uCurrentActionLength = rand() % 128 + 128;
+  pActors[uActorID].uCurrentActionTime = 0;
+  pActors[uActorID].uAIState = Standing;
+  pActors[uActorID].vVelocity.z = 0;
+  pActors[uActorID].vVelocity.y = 0;
+  pActors[uActorID].vVelocity.x = 0;
+  pActors[uActorID].UpdateAnimation();
 }
 
 //----- (00403C6C) --------------------------------------------------------
--- a/Actor.h	Mon Oct 07 11:52:33 2013 +0200
+++ b/Actor.h	Mon Oct 07 11:55:35 2013 +0200
@@ -237,7 +237,7 @@
   static void GiveItem(signed int uActorID, unsigned int uItemID, unsigned int bGive);
   static void ToggleFlag(signed int uActorID, unsigned int uFlag, int bToggle);
   static void ApplyFineForKillingPeasant(unsigned int uActorID);
-  static void DrawHealthBar(Actor *a1, struct GUIWindow *a2);
+  static void DrawHealthBar(Actor *actor, struct GUIWindow *window);
   static int _43B3E0_CalcDamage(Actor *a1, signed int a2);
   static void AddBloodsplatOnDamageOverlay(unsigned int uActorID, int a2, signed int a3);
 
--- a/CastSpellInfo.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/CastSpellInfo.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -3833,7 +3833,7 @@
 			}
 			v608 = pCastSpell->uPlayerID_2;
 			if ( v608 != 4 && v608 != 5
-				|| (v609 = (signed int)*(&pFontCChar + v608 + (unsigned __int8)pParty->field_709), v609 <= 0)
+				|| (v609 = (signed int)*(&pFontCChar + v608 + pParty->hirelingScrollPosition), v609 <= 0)
 				|| v609 >= 3 )
 			{
 				ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
--- a/Indoor.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/Indoor.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -6477,6 +6477,7 @@
   signed int depth_num_vertices; // [sp+1Ch] [bp-Ch]@9
   int v80; // [sp+1Ch] [bp-Ch]@76
   bool next_vertices_flag; // [sp+20h] [bp-8h]@10
+  //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910
 
   pFace = &pIndoor->pFaces[uFaceID];
   memset(&PortalFace, 0, sizeof(stru367));
--- a/Items.h	Mon Oct 07 11:52:33 2013 +0200
+++ b/Items.h	Mon Oct 07 11:55:35 2013 +0200
@@ -192,13 +192,13 @@
 
 typedef struct CEnchantment
 {
+  unsigned __int16 Player::* statPtr;
+  int statBonus;
   CEnchantment(int bonus, unsigned __int16 Player::* skillPtr = NULL):
-statBonus(bonus),
+  statBonus(bonus),
   statPtr(skillPtr)
-{
-}
-int statBonus;
-unsigned __int16 Player::* statPtr;
+  {
+  }
 } CEnchantment;
 
 /*   64 */
--- a/NPC.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/NPC.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -1520,7 +1520,7 @@
   }
   //LOBYTE(v2->uFlags) |= 0x80u;
   pCurrentNPCInfo->uFlags |= 128;
-  pParty->field_709 = 0;
+  pParty->hirelingScrollPosition = 0;
   pParty->CountHirelings();
   if ( pParty->pHirelings[0].pName )
   {
@@ -1535,7 +1535,7 @@
     v22 = pParty->pHireling1Name;
   }
   strcpy(v22, v24);
-  pParty->field_709 = 0;
+  pParty->hirelingScrollPosition = 0;
   pParty->CountHirelings();
   PrepareHouse((HOUSE_ID)(int)window_SpeakInHouse->ptr_1C);
   dialog_menu_id = HOUSE_DIALOGUE_MAIN;
--- a/Party.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/Party.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -355,7 +355,7 @@
 
   pHireling1Name[0] = 0;
   pHireling2Name[0] = 0;
-  pParty->field_709 = 0;
+  pParty->hirelingScrollPosition = 0;
   memset(pHirelings, 0, 2 * sizeof(*pHirelings));
 
   strcpy(this->pPlayers[0].pName, pGlobalTXT_LocalizationStrings[509]); //Zoltan
@@ -1042,7 +1042,7 @@
       Assert(sizeof(NPCData) == 0x4C);
       memset(hireling, 0, sizeof(*hireling));
 
-      pParty->field_709 = 0;
+      pParty->hirelingScrollPosition = 0;
       pParty->CountHirelings();
       viewparams->bRedrawGameUI = true;
     }
--- a/Party.h	Mon Oct 07 11:52:33 2013 +0200
+++ b/Party.h	Mon Oct 07 11:55:35 2013 +0200
@@ -242,7 +242,7 @@
   int uFallStartY;
   unsigned int bFlying;
   char field_708;
-  char field_709;
+  unsigned __int8 hirelingScrollPosition;
   char field_70A;
   char field_70B;
   unsigned int uCurrentYear;
--- a/Player.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/Player.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -297,7 +297,7 @@
     {
       baseConditionMultiplier = 5;
     }
-    if ( conditionIdx == 16 )
+    else //if ( conditionIdx == 16 )
     {
       baseConditionMultiplier = 10;
     }
@@ -900,8 +900,6 @@
 //----- (004927A8) --------------------------------------------------------
 int Player::AddItem(int index, unsigned int uItemID)
 {
-  int xStartValue = 0;
-
   if ( index == -1 )
   {
       for (int xcoord = 0; xcoord < INVETORYSLOTSWIDTH; xcoord++)
@@ -1142,7 +1140,6 @@
 {
   unsigned __int16 v2; // ax@1
   int v5; // edi@7
-  return true;
   if (CheckHiredNPCSpeciality(Scholar))
     return true;
 
@@ -2098,7 +2095,7 @@
   fineIfFailed = actroPtr->pMonsterInfo.uLevel + 100 * (_steal_perm + reputation);
   currMaxItemValue = v29 + v7 * v30;
   pGlobalTXT_LocalizationStrings[200];
-  if ( false && (rand() % 100 < 5 || fineIfFailed > currMaxItemValue || BYTE2(actroPtr->uAttributes) & 8) )
+  if ( rand() % 100 < 5 || fineIfFailed > currMaxItemValue || BYTE2(actroPtr->uAttributes) & 8 )
   {
     Actor::AggroSurroundingPeasants(uActorID, 1);
     sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[376], this->pName);
@@ -2279,6 +2276,7 @@
 
   v4 = 0;
   v47 = 0;
+  v48 = nullptr;
   switch ( attTypeCast )
   {
     case SPECIAL_ATTACK_CURSE:
@@ -2873,6 +2871,8 @@
       if (IsRaceHuman())
         racialBonus = 5;
       break;
+    default:
+      Error("Unknown attribute");
   }
   v7 = GetItemsBonus(a2) + racialBonus;
   return v7 + *resStat;
@@ -2899,25 +2899,26 @@
     v10 += leatherArmorSkillLevel & 0x3F;
   switch (a2)
   {
-  case CHARACTER_ATTRIBUTE_RESIST_FIRE:
-    resStat = &sResFireBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_RESIST_AIR:
-    resStat = &sResAirBonus;
-    break;
-  case  CHARACTER_ATTRIBUTE_RESIST_WATER:
-    resStat = &sResWaterBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_RESIST_EARTH:
-    resStat = &sResEarthBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_RESIST_MIND:
-    resStat = &sResMindBonus;
-    break;
-  case CHARACTER_ATTRIBUTE_RESIST_BODY:
-  case CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
-    resStat = &sResBodyBonus;
-    break;
+    case CHARACTER_ATTRIBUTE_RESIST_FIRE:
+      resStat = &sResFireBonus;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_AIR:
+      resStat = &sResAirBonus;
+      break;
+    case  CHARACTER_ATTRIBUTE_RESIST_WATER:
+      resStat = &sResWaterBonus;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_EARTH:
+      resStat = &sResEarthBonus;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_MIND:
+      resStat = &sResMindBonus;
+      break;
+    case CHARACTER_ATTRIBUTE_RESIST_BODY:
+    case CHARACTER_ATTRIBUTE_RESIST_SPIRIT:
+      resStat = &sResBodyBonus;
+      break;
+    default: Error("Unexpected attribute");
   }
   baseRes = GetBaseResistance(a2);
   result = v10 + GetMagicalBonus(a2) + baseRes + *(resStat);
@@ -4295,6 +4296,7 @@
     case 4:  attribute_value = uAccuracy;     break;
     case 5:  attribute_value = uSpeed;        break;
     case 6:  attribute_value = uLuck;         break;
+    default: Error("Unexpected attribute");
   };
 
   if (attribute_value == base_attribute_value)
@@ -4911,6 +4913,8 @@
                 playerAffected->sResBodyBase += thisa;
                 v13 = pGlobalTXT_LocalizationStrings[29];
                 break;
+            default: ("Unexpected attribute");
+              return;
             }
             sprintf(pTmpBuf.data(), "+%u %s %s", thisa, v13, pGlobalTXT_LocalizationStrings[121]);
             break;
@@ -5008,140 +5012,14 @@
   int actStat; // ebx@161
   int baseStat; // eax@161
 
-  if ( VarNum > VAR_AutoNotes )
-  {
-    switch ( VarNum )
-    {
-      case VAR_AutoNotes :  //TODO: find out why the double subtraction. or whether this is even used
-        test_bit_value = 0x80u >> (pValue - 2) % 8;
-        byteWithRequestedBit = pParty->_autonote_bits[(pValue - 2) /8];
-        return (test_bit_value & byteWithRequestedBit) != 0;
-      case VAR_IsMightMoreThanBase:
-        actStat = GetActualMight();
-        baseStat = GetBaseStrength();
-        return (actStat >= baseStat);
-      case VAR_IsIntellectMoreThanBase:
-        actStat = GetActualIntelligence();
-        baseStat = GetBaseIntelligence();
-        return (actStat >= baseStat);
-      case VAR_IsPersonalityMoreThanBase:
-        actStat = GetActualWillpower();
-        baseStat = GetBaseWillpower();
-        return (actStat >= baseStat);
-      case VAR_IsEnduranceMoreThanBase:
-        actStat = GetActualEndurance();
-        baseStat = GetBaseEndurance();
-        return (actStat >= baseStat);
-      case VAR_IsSpeedMoreThanBase:
-        actStat = GetActualSpeed();
-        baseStat = GetBaseSpeed();
-        return (actStat >= baseStat);
-      case VAR_IsAccuracyMoreThanBase:
-        actStat = GetActualAccuracy();
-        baseStat = GetBaseAccuracy();
-        return (actStat >= baseStat);
-      case VAR_IsLuckMoreThanBase:
-        actStat = GetActualLuck();
-        baseStat = GetBaseLuck();
-        return (actStat >= baseStat);
-      case VAR_PlayerBits:
-        test_bit_value = 0x80u >> ((signed __int16)pValue - 1) % 8;
-        byteWithRequestedBit = this->field_1A50[((signed __int16)pValue - 1)/8];
-        return ( test_bit_value & byteWithRequestedBit ) != 0;
-      case VAR_NPCs2:
-        return pNPCStats->pNewNPCData[pValue].Hired();
-      case VAR_IsFlying:
-        if ( pParty->bFlying
-          && (pParty->pPartyBuffs[PARTY_BUFF_FLY].uExpireTime> 0) )
-          return true;
-        return false;
-      case VAR_HiredNPCHasSpeciality:
-        return CheckHiredNPCSpeciality(pValue);
-      case VAR_CircusPrises:    //isn't used in MM6 since 0x1D6u is a book of regeneration
-        v4 = 0;
-        for (int playerNum = 0; playerNum < 4; playerNum++)
-        {
-          for (int invPos = 0; invPos < 138; invPos++)
-          {
-            int itemId = pParty->pPlayers[playerNum].pInventoryItemList[invPos].uItemID;
-            switch ( itemId )
-            {
-            case 0x1D6u:
-              ++v4;
-              break;
-            case 0x1D7u:
-              v4 += 3;
-              break;
-            case 0x1DDu:
-              v4 += 5;
-              break;
-            }
-          }
-        }
-        return v4 >= pValue;
-      case VAR_NumSkillPoints:
-        return this->uSkillPoints >= (unsigned int)pValue;
-      case VAR_MonthIs:
-        return (pParty->uCurrentMonth == (unsigned int)pValue);
-      case VAR_Counter1:
-      case VAR_Counter2:
-      case VAR_Counter3:
-      case VAR_Counter4:
-      case VAR_Counter5:
-      case VAR_Counter6:
-      case VAR_Counter7:
-      case VAR_Counter8:
-      case VAR_Counter9:
-      case VAR_Counter10:
-        if (pParty->PartyTimes.CounterEventValues[VarNum - VAR_Counter1])         //originally (signed __int64)(__PAIR__(*(int *)&stru_AA1058[3].pSounds[8 * VarNum + 44304], *(int *)&stru_AA1058[3].pSounds[8 * VarNum + 44300])
-        {
-          return (pParty->PartyTimes.CounterEventValues[VarNum - VAR_Counter1] + 460800 * pValue * 0.033333335) <= pParty->uTimePlayed ;
-        }
-      case VAR_ReputationInCurrentLocation:
-        v19 = &pOutdoor->ddm;
-        if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-          v19 = &pIndoor->dlv;
-        return (v19->uReputation >= pValue);
-      case VAR_Unknown1:
-        v21 = &pOutdoor->ddm;
-        if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-          v21 = &pIndoor->dlv;
-        return (v21->field_C_alert == pValue);        //yes, equality, not >=
-      case VAR_GoldInBank:
-        return pParty->uNumGoldInBank >= (unsigned int)pValue;
-      case VAR_NumDeaths:
-        return pParty->uNumDeaths >= (unsigned int)pValue;
-      case VAR_NumBounties:
-        return pParty->uNumBountiesCollected >= (unsigned int)pValue;
-      case VAR_PrisonTerms:
-        return pParty->uNumPrisonTerms >= pValue;
-      case VAR_ArenaWinsPage:
-        return (unsigned __int8)pParty->uNumArenaPageWins >= pValue;
-      case VAR_ArenaWinsSquire:
-        return (unsigned __int8)pParty->uNumArenaSquireWins >= pValue;
-      case VAR_ArenaWinsKnight:
-        return (unsigned __int8)pParty->uNumArenaKnightWins >= pValue;
-      case VAR_ArenaWinsLord:
-        return pParty->uNumArenaLordWins >= pValue;
-      case VAR_Invisible:
-        return ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime > 0 );
-      case VAR_ItemEquipped:
-        for (int i = 0; i < 16; i++)
-        {
-          if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) && GetNthEquippedIndexItem(i)->uItemID == pValue )
-          {
-            return true;
-          }
-        }
-        return false;
-      default:
-        return false;
-    }
-  }
-  if ( VarNum <= VAR_MajorCondition )
-  {
-    switch ( VarNum )
-    {
+
+  if ( (signed int)VarNum >= VAR_MapPersistentVariable_0 && VarNum <= VAR_MapPersistentVariable_74 )
+    return (unsigned __int8)stru_5E4C90_MapPersistVars.field_0[VarNum - VAR_MapPersistentVariable_0] > 0;  // originally (unsigned __int8)byte_5E4C15[VarNum];
+  if ( (signed int)VarNum >= VAR_MapPersistentVariable_75 && VarNum <= VAR_MapPersistentVariable_99 )
+    return (unsigned __int8)stru_5E4C90_MapPersistVars._decor_events[VarNum - VAR_MapPersistentVariable_75] > 0;      //not really sure whether the number gets up to 99, but can't ignore the possibility
+
+  switch ( VarNum )
+  {
     case VAR_Sex:
       return ( pValue == this->uSex );
     case VAR_Class:
@@ -5167,15 +5045,11 @@
     case VAR_Age:
       return GetActualAge() >= (unsigned int)pValue;
     case VAR_Award:
-      test_bit_value = 0x80u >> (pValue - 1) % 8;
-      byteWithRequestedBit = this->_achieved_awards_bits[(pValue - 1) /8];
-      return ( test_bit_value & byteWithRequestedBit ) != 0;
+      return _449B57_test_bit(this->_achieved_awards_bits, pValue);
     case VAR_Experience:
       return this->uExperience >= pValue;       //TODO change pValue to long long
     case VAR_QBits_QuestsDone:
-      test_bit_value = 0x80u >> (pValue - 1) % 8;
-      byteWithRequestedBit = pParty->_quest_bits[(pValue - 1)/8];
-      return ( test_bit_value & byteWithRequestedBit ) != 0;
+      return _449B57_test_bit(pParty->_quest_bits, pValue);
     case VAR_PlayerItemInHands:
       for (int i = 0; i < 138; i++)
       {
@@ -5402,13 +5276,130 @@
         return v4 >= pValue;
       }
       return true;
-    }
-  }
-  if ( (signed int)VarNum >= VAR_MapPersistentVariable_0 && VarNum <= VAR_MapPersistentVariable_74 )
-    return (unsigned __int8)stru_5E4C90_MapPersistVars.field_0[VarNum - VAR_MapPersistentVariable_0] > 0;  // originally (unsigned __int8)byte_5E4C15[VarNum];
-  if ( (signed int)VarNum >= VAR_MapPersistentVariable_75 && VarNum <= VAR_MapPersistentVariable_99 )
-    return (unsigned __int8)stru_5E4C90_MapPersistVars._decor_events[VarNum - VAR_MapPersistentVariable_75] > 0;      //not really sure whether the number gets up to 99, but can't ignore the possibility
-
+    case VAR_AutoNotes :  //TODO: find out why the double subtraction. or whether this is even used
+      test_bit_value = 0x80u >> (pValue - 2) % 8;
+      byteWithRequestedBit = pParty->_autonote_bits[(pValue - 2) /8];
+      return (test_bit_value & byteWithRequestedBit) != 0;
+    case VAR_IsMightMoreThanBase:
+      actStat = GetActualMight();
+      baseStat = GetBaseStrength();
+      return (actStat >= baseStat);
+    case VAR_IsIntellectMoreThanBase:
+      actStat = GetActualIntelligence();
+      baseStat = GetBaseIntelligence();
+      return (actStat >= baseStat);
+    case VAR_IsPersonalityMoreThanBase:
+      actStat = GetActualWillpower();
+      baseStat = GetBaseWillpower();
+      return (actStat >= baseStat);
+    case VAR_IsEnduranceMoreThanBase:
+      actStat = GetActualEndurance();
+      baseStat = GetBaseEndurance();
+      return (actStat >= baseStat);
+    case VAR_IsSpeedMoreThanBase:
+      actStat = GetActualSpeed();
+      baseStat = GetBaseSpeed();
+      return (actStat >= baseStat);
+    case VAR_IsAccuracyMoreThanBase:
+      actStat = GetActualAccuracy();
+      baseStat = GetBaseAccuracy();
+      return (actStat >= baseStat);
+    case VAR_IsLuckMoreThanBase:
+      actStat = GetActualLuck();
+      baseStat = GetBaseLuck();
+      return (actStat >= baseStat);
+    case VAR_PlayerBits:
+      test_bit_value = 0x80u >> ((signed __int16)pValue - 1) % 8;
+      byteWithRequestedBit = this->field_1A50[((signed __int16)pValue - 1)/8];
+      return ( test_bit_value & byteWithRequestedBit ) != 0;
+    case VAR_NPCs2:
+      return pNPCStats->pNewNPCData[pValue].Hired();
+    case VAR_IsFlying:
+      if ( pParty->bFlying
+        && (pParty->pPartyBuffs[PARTY_BUFF_FLY].uExpireTime> 0) )
+        return true;
+      return false;
+    case VAR_HiredNPCHasSpeciality:
+      return CheckHiredNPCSpeciality(pValue);
+    case VAR_CircusPrises:    //isn't used in MM6 since 0x1D6u is a book of regeneration
+      v4 = 0;
+      for (int playerNum = 0; playerNum < 4; playerNum++)
+      {
+        for (int invPos = 0; invPos < 138; invPos++)
+        {
+          int itemId = pParty->pPlayers[playerNum].pInventoryItemList[invPos].uItemID;
+          switch ( itemId )
+          {
+          case 0x1D6u:
+            ++v4;
+            break;
+          case 0x1D7u:
+            v4 += 3;
+            break;
+          case 0x1DDu:
+            v4 += 5;
+            break;
+          }
+        }
+      }
+      return v4 >= pValue;
+    case VAR_NumSkillPoints:
+      return this->uSkillPoints >= (unsigned int)pValue;
+    case VAR_MonthIs:
+      return (pParty->uCurrentMonth == (unsigned int)pValue);
+    case VAR_Counter1:
+    case VAR_Counter2:
+    case VAR_Counter3:
+    case VAR_Counter4:
+    case VAR_Counter5:
+    case VAR_Counter6:
+    case VAR_Counter7:
+    case VAR_Counter8:
+    case VAR_Counter9:
+    case VAR_Counter10:
+      if (pParty->PartyTimes.CounterEventValues[VarNum - VAR_Counter1])         //originally (signed __int64)(__PAIR__(*(int *)&stru_AA1058[3].pSounds[8 * VarNum + 44304], *(int *)&stru_AA1058[3].pSounds[8 * VarNum + 44300])
+      {
+        return (pParty->PartyTimes.CounterEventValues[VarNum - VAR_Counter1] + 460800 * pValue * 0.033333335) <= pParty->uTimePlayed ;
+      }
+    case VAR_ReputationInCurrentLocation:
+      v19 = &pOutdoor->ddm;
+      if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
+        v19 = &pIndoor->dlv;
+      return (v19->uReputation >= pValue);
+    case VAR_Unknown1:
+      v21 = &pOutdoor->ddm;
+      if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
+        v21 = &pIndoor->dlv;
+      return (v21->field_C_alert == pValue);        //yes, equality, not >=
+    case VAR_GoldInBank:
+      return pParty->uNumGoldInBank >= (unsigned int)pValue;
+    case VAR_NumDeaths:
+      return pParty->uNumDeaths >= (unsigned int)pValue;
+    case VAR_NumBounties:
+      return pParty->uNumBountiesCollected >= (unsigned int)pValue;
+    case VAR_PrisonTerms:
+      return pParty->uNumPrisonTerms >= pValue;
+    case VAR_ArenaWinsPage:
+      return (unsigned __int8)pParty->uNumArenaPageWins >= pValue;
+    case VAR_ArenaWinsSquire:
+      return (unsigned __int8)pParty->uNumArenaSquireWins >= pValue;
+    case VAR_ArenaWinsKnight:
+      return (unsigned __int8)pParty->uNumArenaKnightWins >= pValue;
+    case VAR_ArenaWinsLord:
+      return pParty->uNumArenaLordWins >= pValue;
+    case VAR_Invisible:
+      return ( pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime > 0 );
+    case VAR_ItemEquipped:
+      for (int i = 0; i < 16; i++)
+      {
+        if ( HasItemEquipped((ITEM_EQUIP_TYPE)i) && GetNthEquippedIndexItem(i)->uItemID == pValue )
+        {
+          return true;
+        }
+      }
+      return false;
+  }
+  
   return false;
 }
 
@@ -5417,513 +5408,576 @@
 void Player::SetVariable(enum VariableType var_type, signed int var_value)
 {
   signed int currPlayerId; // ebx@1
-  Player *v4_unused; // esi@1
-  unsigned int v5_unused; // edi@1
   unsigned int v6; // esi@13
   unsigned int v7; // esi@14
-  signed int v8_unused; // eax@17
-  ItemGen *v9; // ecx@17
-  int v10; // eax@21
   signed int v11; // eax@30
-  Player *unused12; // ecx@44
-  char *v13; // ecx@45
-  Player *v14; // ecx@49
-  int v15; // ecx@86
-  int v16; // esi@106
-  char v17; // al@106
-  int v18; // eax@107
-  Player *v19; // ecx@112
-  Player *v20; // ecx@127
-  int v21; // eax@127
-  int v22; // eax@145
-  char v23; // zf@146
   DDM_DLV_Header *v24; // ecx@148
-  signed int v25; // eax@172
-  int v26; // [sp-8h] [bp-3Ch]@84
-  signed int unused27; // [sp-4h] [bp-38h]@4
-  int v28_unused; // [sp-4h] [bp-38h]@84
   ItemGen item; // [sp+Ch] [bp-28h]@52
-  char v30_unused; // [sp+32h] [bp-2h]@1
-  char v31_unused; // [sp+33h] [bp-1h]@1
-  
-  currPlayerId = -1;
-  for (int i = 1; i <= 4; i++)  //TODO: add a member variable for playerid in the future
-  {
-    if ( this == pPlayers[i] )
+
+  currPlayerId = 0;
+  if ( this == pPlayers[2] )
+    currPlayerId = 1;
+  else if ( this == pPlayers[3] )
+    currPlayerId = 2;
+  else if ( this == pPlayers[4] )
+     currPlayerId  = 3;
+
+
+  if ( var_type >= VAR_History_0 && var_type <= VAR_History_28)
+  {
+    if (!pParty->PartyTimes.HistoryEventTimes[var_type - VAR_History_0])
     {
-      currPlayerId = i - 1;
-      break;
+      pParty->PartyTimes.HistoryEventTimes[var_type - VAR_History_0] = pParty->uTimePlayed;
+      if (pStorylineText->StoreLine[var_type - VAR_History_0].pText)
+      {
+        bFlashHistoryBook = 1;
+        PlayAwardSound(currPlayerId);
+      }
     }
-  }
-
-  Assert(currPlayerId != -1);
-  if ( var_type > VAR_AutoNotes )
-  {
-    if ( var_type <= VAR_GoldInBank )
-    {
-      if ( var_type == VAR_GoldInBank )
+    return;
+  }
+
+  if ( var_type >= VAR_MapPersistentVariable_0 && var_type <= VAR_MapPersistentVariable_99 )
+  {
+    byte_5E4C15[var_type] = var_value;
+    return;
+  }
+
+  if ( var_type >= VAR_UnknownTimeEvent0 && var_type <= VAR_UnknownTimeEvent19 )
+  {
+    pParty->PartyTimes._s_times[var_type - VAR_UnknownTimeEvent0] = pParty->uTimePlayed;    //*(int *)&stru_AA1058[3].pSounds[8 * var_type + 44532] = LODWORD(pParty->uTimePlayed);, *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44536] = HIDWORD(pParty->uTimePlayed
+    PlayAwardSound(currPlayerId);
+    return;
+  }
+
+  switch ( var_type )
+  {
+    case VAR_Sex:
+      this->uSex = (PLAYER_SEX)var_value;
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Class:
+      this->classType = (PLAYER_CLASS_TYPE)var_value;
+      if ( (PLAYER_CLASS_TYPE)var_value == PLAYER_CLASS_LICH )
       {
-        pParty->uNumGoldInBank = var_value;
-        return;
-      }
-      if ( var_type <= VAR_Counter10 )
-      {
-        if ( (signed int)var_type >= 0xF5 )
+        for (int i = 0; i < 138; i++)
         {
-          pParty->PartyTimes.CounterEventValues[var_type - VAR_Counter1] = pParty->uTimePlayed; //           *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44300] = LODWORD(pParty->uTimePlayed);*(int *)&stru_AA1058[3].pSounds[8 * var_type + 44304] = HIDWORD(pParty->uTimePlayed);
+          if (this->pOwnItems[i].uItemID == ITEM_LICH_JAR_EMPTY)
+          {
+            this->pOwnItems[i].uItemID = ITEM_LICH_JAR_FULL;
+            this->pOwnItems[i].uHolderPlayer = currPlayerId + 1;
+          }
+        }
+        if ( this->sResFireBase < 20 )
+          this->sResFireBase = 20;
+        if ( this->sResAirBase < 20 )
+          this->sResAirBase = 20;
+        if ( this->sResWaterBase < 20 )
+          this->sResWaterBase = 20;
+        if ( this->sResEarthBase < 20 )
+          this->sResEarthBase = 20;
+        this->sResMindBase = 200;
+        this->sResBodyBase = 200;
+        v11 = this->GetSexByVoice();
+        this->uPrevVoiceID = this->uVoiceID;
+        this->uPrevFace = this->uCurrentFace;
+        if ( v11 )
+        {
+          this->uCurrentFace = 21;
+          this->uVoiceID = 21;
         }
         else
         {
-          switch ( var_type )
-          {
-            case VAR_PlayerBits:
-              _449B7E_toggle_bit((unsigned char *)field_1A50, var_value, 1u);
-              break;
-            case VAR_NPCs2:
-              pParty->field_709 = 0;
-              LOBYTE(pNPCStats->pNewNPCData[var_value].uFlags) |= 0x80u;
-              pParty->CountHirelings();
-              viewparams->bRedrawGameUI = true;
-              break;
-            case VAR_NumSkillPoints:
-              this->uSkillPoints = var_value;
-              break;
-          }
+          this->uCurrentFace = 20;
+          this->uVoiceID = 20;
         }
-        return;
+        ReloadPlayerPortraits(currPlayerId, this->uCurrentFace);
       }
-      if ( var_type <= VAR_Counter10 )
-        return;
-      if ( (signed int)var_type <= VAR_UnknownTimeEvent19 )
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_CurrentHP:
+      this->sHealth = var_value;
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_MaxHP:
+      this->sHealth = GetMaxHealth();
+      return;
+    case VAR_CurrentSP:
+      this->sMana = var_value;
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_MaxSP:
+      this->sMana = GetMaxMana();
+      return;
+    case VAR_ACModifier:
+      this->sACModifier = (unsigned __int8)var_value;
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_BaseLevel:
+      this->uLevel = (unsigned __int8)var_value;
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_LevelModifier:
+      this->sLevelModifier = (unsigned __int8)var_value;
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Age:
+      this->sAgeModifier = var_value;
+      return;
+    case VAR_Award:
+      if ( !_449B57_test_bit(this->_achieved_awards_bits, var_value) && pAwards[var_value].pText )
       {
-        pParty->PartyTimes._s_times[var_type - VAR_UnknownTimeEvent0] = pParty->uTimePlayed;    //*(int *)&stru_AA1058[3].pSounds[8 * var_type + 44532] = LODWORD(pParty->uTimePlayed);, *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44536] = HIDWORD(pParty->uTimePlayed);
+        PlayAwardSound_Anim(currPlayerId);
+        this->PlaySound(SPEECH_96, 0);
       }
-      else
+      _449B7E_toggle_bit(this->_achieved_awards_bits, var_value, 1u);
+      return;
+    case VAR_Experience:
+      this->uExperience = var_value;
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_QBits_QuestsDone:
+      if ( !_449B57_test_bit(pParty->_quest_bits, var_value) && pQuestTable[var_value-1] )
       {
-        if ( var_type == VAR_ReputationInCurrentLocation )
-        {
-          v24 = &pOutdoor->ddm;
-          if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-            v24 = &pIndoor->dlv;
-          v24->uReputation = var_value;
-          if ( var_value > 10000 )
-            v24->uReputation = 10000;
-          return;
-        }
-        if ( var_type <= VAR_ReputationInCurrentLocation
-          || var_type > VAR_History_28
-          || (v22 = var_type - VAR_History_0, pParty->PartyTimes.HistoryEventTimes[v22])
-          || (pParty->PartyTimes.HistoryEventTimes[v22] = pParty->uTimePlayed,
-              pStorylineText->StoreLine[v22].pText == 0) )//*(&pStorylineText->field_0 + 3 * v22) == 0,
-          return;
-        bFlashHistoryBook = 1;
+        bFlashQuestBook = 1;
+        pGame->pStru6Instance->SetPlayerBuffAnim(0x96u, currPlayerId);
+        PlayAwardSound(currPlayerId);
+        this->PlaySound(SPEECH_93, 0);
       }
-      v25 = 8 * currPlayerId + 400;
-      LOBYTE(v25) = PID(OBJECT_Player,currPlayerId - 112);
-      pAudioPlayer->PlaySound(SOUND_20001, v25, 0, -1, 0, 0, 0, 0);
-      return;
-    }
-    switch ( var_type )
-    {
+      _449B7E_toggle_bit(pParty->_quest_bits, var_value, 1u);
+      return;
+    case VAR_PlayerItemInHands:
+      item.Reset();
+      item.uItemID = var_value;
+      item.uAttributes = 1;
+      pParty->SetHoldingItem(&item);
+      if ( var_value >= ITEM_ARTIFACT_PUCK && var_value <= ITEM_RELIC_MEKORIGS_HAMMER )
+        pParty->pIsArtifactFound[var_value-500] = 1;
+      return;
+    case VAR_FixedGold:
+      Party::SetGold(var_value);
+      return;
+    case VAR_RandomGold:
+      v6 = rand() % var_value + 1;
+      Party::SetGold(v6);
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[500], v6);// You have %lu gold
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+      GameUI_DrawFoodAndGold();
+      return;
+    case VAR_FixedFood:
+      Party::SetFood(var_value);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_RandomFood:
+      v7 = rand() % var_value + 1;
+      Party::SetFood(v7);
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[501], v7);// You have %lu food
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+      GameUI_DrawFoodAndGold();
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_BaseMight:
+      this->uMight = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_BaseIntellect:
+      this->uIntelligence = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_BasePersonality:
+      this->uWillpower = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_BaseEndurance:
+      this->uEndurance = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_BaseSpeed:
+      this->uSpeed = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_BaseAccuracy:
+      this->uAccuracy = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_BaseLuck:
+      this->uLuck = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_MightBonus:
+    case VAR_ActualMight:
+      this->uMightBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_IntellectBonus:
+    case VAR_ActualIntellect:
+      this->uIntelligenceBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_PersonalityBonus:
+    case VAR_ActualPersonality:
+      this->uWillpowerBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_EnduranceBonus:
+    case VAR_ActualEndurance:
+      this->uEnduranceBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_SpeedBonus:
+    case VAR_ActualSpeed:
+      this->uSpeedBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_AccuracyBonus:
+    case VAR_ActualAccuracy:
+      this->uAccuracyBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_LuckBonus:
+    case VAR_ActualLuck:
+      this->uLuckBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_FireResistance:
+      this->sResFireBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_AirResistance:
+      this->sResAirBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_WaterResistance:
+      this->sResWaterBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_EarthResistance:
+      this->sResEarthBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_SpiritResistance:
+      this->sResSpiritBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_MindResistance:
+      this->sResMindBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_BodyResistance:
+      this->sResBodyBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_LightResistance:
+      this->sResLightBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_DarkResistance:
+      this->sResDarkBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_MagicResistance:
+      this->sResMagicBase = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_92);
+      return;
+    case VAR_FireResistanceBonus:
+      this->sResFireBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_AirResistanceBonus:
+      this->sResAirBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_WaterResistanceBonus:
+      this->sResWaterBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_EarthResistanceBonus:
+      this->sResEarthBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_SpiritResistanceBonus:
+      this->sResSpiritBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_MindResistanceBonus:
+      this->sResMindBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_BodyResistanceBonus:
+      this->sResBodyBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_LightResistanceBonus:
+      this->sResLightBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_DarkResistanceBonus:
+      this->sResDarkBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_PhysicalResistanceBonus:
+      Error("Physical res. bonus not used");
+      return;
+    case VAR_MagicResistanceBonus:
+      this->sResMagicBonus = (unsigned __int8)var_value;
+      PlayAwardSound_Anim_Face(currPlayerId, SPEECH_91);
+      return;
+    case VAR_Cursed:
+      this->SetCondition(Condition_Cursed, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Weak:
+      this->SetCondition(Condition_Weak, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Asleep:
+      this->SetCondition(Condition_Sleep, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Afraid:
+      this->SetCondition(Condition_Fear, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Drunk:
+      this->SetCondition(Condition_Drunk, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Insane:
+      this->SetCondition(Condition_Insane, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_PoisonedGreen:
+      this->SetCondition(Condition_Poison1, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_DiseasedGreen:
+      this->SetCondition(Condition_Disease1, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_PoisonedYellow:
+      this->SetCondition(Condition_Poison2, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_DiseasedYellow:
+      this->SetCondition(Condition_Disease2, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_PoisonedRed:
+      this->SetCondition(Condition_Poison3, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_DiseasedRed:
+      this->SetCondition(Condition_Disease3, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Paralyzed:
+      this->SetCondition(Condition_Paralyzed, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Unconsious:
+      this->SetCondition(Condition_Unconcious, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Dead:
+      this->SetCondition(Condition_Dead, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Stoned:
+      this->SetCondition(Condition_Pertified, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_Eradicated:
+      this->SetCondition(Condition_Eradicated, 1);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_MajorCondition:
+      memset(this, 0, 0xA0u);
+      PlayAwardSound_Anim(currPlayerId);
+      return;
+    case VAR_AutoNotes:
+      if ( !_449B57_test_bit(pParty->_autonote_bits, var_value) && pAutonoteTxt[var_value-1].pText )
+      {
+        pGame->pStru6Instance->SetPlayerBuffAnim(0x96u, currPlayerId);
+        this->PlaySound(SPEECH_96, 0);
+        bFlashAutonotesBook = 1;
+        _506568_autonote_type = pAutonoteTxt[var_value-1].eType;// dword_72371C[2 * a3];
+      }
+      _449B7E_toggle_bit(pParty->_autonote_bits, var_value, 1u);
+      PlayAwardSound(currPlayerId);
+      return;
+    case VAR_PlayerBits:
+      _449B7E_toggle_bit((unsigned char *)field_1A50, var_value, 1u);
+      return;
+    case VAR_NPCs2:
+      pParty->hirelingScrollPosition = 0;
+      LOBYTE(pNPCStats->pNewNPCData[var_value].uFlags) |= 0x80u;
+      pParty->CountHirelings();
+      viewparams->bRedrawGameUI = true;
+      return;
+    case VAR_NumSkillPoints:
+      this->uSkillPoints = var_value;
+      return;
+    case VAR_Counter1:
+    case VAR_Counter2:
+    case VAR_Counter3:
+    case VAR_Counter4:
+    case VAR_Counter5:
+    case VAR_Counter6:
+    case VAR_Counter7:
+    case VAR_Counter8:
+    case VAR_Counter9:
+    case VAR_Counter10:
+      pParty->PartyTimes.CounterEventValues[var_type - VAR_Counter1] = pParty->uTimePlayed; //           *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44300] = LODWORD(pParty->uTimePlayed);*(int *)&stru_AA1058[3].pSounds[8 * var_type + 44304] = HIDWORD(pParty->uTimePlayed);
+      return;
+    case VAR_ReputationInCurrentLocation:
+      v24 = &pOutdoor->ddm;
+      if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
+        v24 = &pIndoor->dlv;
+      v24->uReputation = var_value;
+      if ( var_value > 10000 )
+        v24->uReputation = 10000;
+      return;
+    case VAR_GoldInBank:
+      pParty->uNumGoldInBank = var_value;
+      return;
     case VAR_NumDeaths:
       pParty->uNumDeaths = var_value;
-      break;
+      return;
     case VAR_NumBounties:
       pParty->uNumBountiesCollected = var_value;
-      break;
+      return;
     case VAR_PrisonTerms:
       pParty->uNumPrisonTerms = var_value;
-      break;
+      return;
     case VAR_ArenaWinsPage:
       pParty->uNumArenaPageWins = var_value;
-      break;
+      return;
     case VAR_ArenaWinsSquire:
       pParty->uNumArenaSquireWins = var_value;
-      break;
+      return;
     case VAR_ArenaWinsKnight:
       pParty->uNumArenaKnightWins = var_value;
-      break;
+      return;
     case VAR_ArenaWinsLord:
       pParty->uNumArenaLordWins = var_value;
-      break;
-    }
-    return;
-  }
-  if ( var_type == VAR_AutoNotes )
-  {
-    if ( !((unsigned __int8)(0x80u >> ((signed __int16)var_value - 1) % 8) & pParty->_autonote_bits[((signed __int16)var_value - 1) >> 3])
-      //&& (&dword_723718_autonote_related)[8 * a3] )
-	  && pAutonoteTxt[var_value].pText )
-    {
-      v20 = pPlayers[currPlayerId + 1];
-      v20->PlaySound(SPEECH_96, 0);
-	  //v21 = pAutonoteTxt[var_value].eType;// dword_72371C[2 * a3];
-      bFlashAutonotesBook = 1;
-      _506568_autonote_type = pAutonoteTxt[var_value].eType;
-      DrawPlayerBuffAnimBasedOnCondition(currPlayerId);
-    }
-    _449B7E_toggle_bit(pParty->_autonote_bits, var_value, 1);
-    PlaySoundBasedOnCondition(currPlayerId);
-    return;
-  }
-  if ( var_type <= VAR_BaseLuck )
-  {
-    switch ( var_type )
-    {
-      case VAR_Sex:
-        this->uSex = (PLAYER_SEX)var_value;
-        goto LABEL_124;
-      case VAR_Class:
-        this->classType = (PLAYER_CLASS_TYPE)var_value;
-        if ( (char)var_value == PLAYER_CLASS_LICH )
-        {
-          for (int i = 0; i < 138; i++)
-          {
-            v9 = &this->pInventoryItemList[i];
-            if (v9->uItemID == ITEM_LICH_JAR_EMPTY)
-            {
-              v9->uItemID = ITEM_LICH_JAR_FULL;
-              v9->uHolderPlayer = currPlayerId + 1;
-              v10 = (int)((char *)this + 36 * 138);
-              *(int *)(v10 + 532) = 601;
-              *(char *)(v10 + 558) = currPlayerId + 1;
-              break;
-            }
-          }
-          if ( this->sResFireBase < 20 )
-            this->sResFireBase = 20;
-          if ( this->sResAirBase < 20 )
-            this->sResAirBase = 20;
-          if ( this->sResWaterBase < 20 )
-            this->sResWaterBase = 20;
-          if ( this->sResEarthBase < 20 )
-            this->sResEarthBase = 20;
-          this->sResMindBase = 200;
-          this->sResBodyBase = 200;
-          this->uPrevVoiceID = this->uVoiceID;
-          this->uPrevFace = this->uCurrentFace;
-          if ( IsFemale() )
-          {
-            this->uCurrentFace = 21;
-            this->uVoiceID = 21;
-          }
-          else
-          {
-            this->uCurrentFace = 20;
-            this->uVoiceID = 20;
-          }
-          ReloadPlayerPortraits(currPlayerId, this->uCurrentFace);
-        }
-        goto LABEL_124;
-      case VAR_CurrentHP:
-        this->sHealth = var_value;
-        goto LABEL_124;
-      case VAR_MaxHP:
-        this->sHealth = GetMaxHealth();
-        return;
-      case VAR_CurrentSP:
-        this->sMana = var_value;
-        goto LABEL_124;
-      case VAR_MaxSP:
-        this->sMana = GetMaxMana();
-        return;
-      case VAR_ACModifier:
-        this->sACModifier = (unsigned __int8)var_value;
-        goto LABEL_124;
-      case VAR_BaseLevel:
-        this->uLevel = (unsigned __int8)var_value;
-        goto LABEL_124;
-      case VAR_LevelModifier:
-        this->sLevelModifier = (unsigned __int8)var_value;
-        goto LABEL_124;
-      case VAR_Age:
-        this->sAgeModifier = var_value;
-        return;
-      case VAR_Award:
-        if ( !((unsigned __int8)(0x80u >> ((signed __int16)var_value - 1) % 8) & 
-			  pPlayers[currPlayerId + 1]->_achieved_awards_bits[((signed __int16)var_value - 1)/ 8])
-              //&& dword_723E80_award_related[2 * a3] )
-		    && pAwards[var_value].pText )
-        {
-          pPlayers[currPlayerId + 1]->PlaySound(SPEECH_96, 0);
-          DrawPlayerBuffAnimBasedOnCondition(currPlayerId);
-          PlaySoundBasedOnCondition(currPlayerId);
-        }
-        _449B7E_toggle_bit((unsigned char *)this->_achieved_awards_bits, var_value, 1u);
-        return;
-      case VAR_Experience:
-        this->uExperience = var_value;
-        goto LABEL_124;
-      case VAR_QBits_QuestsDone:
-        if ( !((unsigned __int8)(0x80u >> ((signed __int16)var_value - 1) % 8) & pParty->_quest_bits[((signed __int16)var_value - 1) >> 3])
-          // && (&dword_722F10)[4 * a3] )
-		    && pQuestTable[var_value] )
-          {
-          v14 = pPlayers[currPlayerId + 1];
-          bFlashQuestBook = 1;
-          v14->PlaySound(SPEECH_93, 0);
-          DrawPlayerBuffAnimBasedOnCondition(currPlayerId);
-          PlaySoundBasedOnCondition(currPlayerId);
-        }
-        v13 = (char *)pParty->_quest_bits;
-        _449B7E_toggle_bit((unsigned char *)v13, var_value, 1u);
-        return;
-      case VAR_PlayerItemInHands:
-        item.Reset();
-        item.Reset();
-        item.uItemID = var_value;
-        item.uAttributes = 1;
-        pParty->SetHoldingItem(&item);
-        if ( var_value >= ITEM_ARTIFACT_PUCK && var_value <= ITEM_RELIC_MEKORIGS_HAMMER )
-          pParty->pIsArtifactFound[var_value-500] = 1;
-        return;
-      case VAR_FixedGold:
-        Party::SetGold(var_value);
-        return;
-      case VAR_RandomGold:
-        v6 = rand() % var_value + 1;
-        Party::SetGold(v6);
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[500], v6);// You have %lu gold
-        ShowStatusBarString(pTmpBuf.data(), 2u);
-        GameUI_DrawFoodAndGold();
-        return;
-      case VAR_FixedFood:
-        Party::SetFood(var_value);
-        goto LABEL_124;
-      case VAR_RandomFood:
-        v7 = rand() % var_value + 1;
-        Party::SetFood(v7);
-        sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[501], v7);// You have %lu food
-        ShowStatusBarString(pTmpBuf.data(), 2u);
-        GameUI_DrawFoodAndGold();
-        goto LABEL_124;
-      case VAR_MightBonus:
-        goto LABEL_64;
-      case VAR_IntellectBonus:
-        goto LABEL_68;
-      case VAR_PersonalityBonus:
-        goto LABEL_69;
-      case VAR_EnduranceBonus:
-        goto LABEL_70;
-      case VAR_SpeedBonus:
-        goto LABEL_71;
-      case VAR_AccuracyBonus:
-        goto LABEL_72;
-      case VAR_LuckBonus:
-        goto LABEL_73;
-      case VAR_BaseMight:
-        this->uMight = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_BaseIntellect:
-        this->uIntelligence = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_BasePersonality:
-        this->uWillpower = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_BaseEndurance:
-        this->uEndurance = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_BaseSpeed:
-        this->uSpeed = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_BaseAccuracy:
-        this->uAccuracy = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_BaseLuck:
-        this->uLuck = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      default:
-        return;
-    }
-LABEL_111:
-    v26 = SPEECH_91;
-LABEL_112:
-    v19 = pPlayers[currPlayerId + 1];
-    v19->PlaySound((PlayerSpeech)v26, 0);
-    DrawPlayerBuffAnimBasedOnCondition(currPlayerId);
-    PlaySoundBasedOnCondition(currPlayerId);
-    return;
-  }
-  if ( var_type <= VAR_MagicResistance )
-  {
-    switch ( var_type )
-    {
-      case VAR_ActualMight:
-LABEL_64:
-        this->uMightBonus = (unsigned __int8)var_value;
-        goto LABEL_111;
-      case VAR_ActualIntellect:
-LABEL_68:
-        this->uIntelligenceBonus = (unsigned __int8)var_value;
-        goto LABEL_111;
-      case VAR_ActualPersonality:
-LABEL_69:
-        this->uWillpowerBonus = (unsigned __int8)var_value;
-        goto LABEL_111;
-      case VAR_ActualEndurance:
-LABEL_70:
-        this->uEnduranceBonus = (unsigned __int8)var_value;
-        goto LABEL_111;
-      case VAR_ActualSpeed:
-LABEL_71:
-        this->uSpeedBonus = (unsigned __int8)var_value;
-        goto LABEL_111;
-      case VAR_ActualAccuracy:
-LABEL_72:
-        this->uAccuracyBonus = (unsigned __int8)var_value;
-        goto LABEL_111;
-      case VAR_ActualLuck:
-LABEL_73:
-        this->uLuckBonus = (unsigned __int8)var_value;
-        goto LABEL_111;
-      case VAR_FireResistance:
-        this->sResFireBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_AirResistance:
-        this->sResAirBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_WaterResistance:
-        this->sResWaterBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_EarthResistance:
-        this->sResEarthBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_SpiritResistance:
-        this->sResSpiritBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_MindResistance:
-        this->sResMindBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_BodyResistance:
-        this->sResBodyBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_LightResistance:
-        this->sResLightBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_DarkResistance:
-        this->sResDarkBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      case VAR_MagicResistance:
-        this->sResMagicBase = (unsigned __int8)var_value;
-        v26 = 92;
-        goto LABEL_112;
-      default:
-        return;
-    }
-    return;
-  }
-  HIWORD(v15) = 0;
-  if ( var_type > VAR_DisarmTrapSkill )
-  {
-    if ( var_type != VAR_LearningSkill )
-    {
-      if ( var_type <= VAR_LearningSkill )
-        return;
-      if ( var_type <= VAR_Eradicated )
-      {
-        this->SetCondition(var_type - 105, 1);
-      }
-      else
-      {
-        if ( var_type != VAR_MajorCondition )
-        {
-          if ( var_type > VAR_MajorCondition && var_type <= VAR_MapPersistentVariable_99 )
-            byte_5E4C15[var_type] = var_value;
-          return;
-        }
-        memset(this, 0, 0xA0u);
-      }
-    }
-    else
-    {
-      v16 = (int)((char *)&this->pConditions[16] + 2 * var_type);
-      v17 = *(char *)v16;
-      if ( var_value <= 63 )
-      {
-        LOWORD(v15) = (unsigned __int8)var_value;
-        v18 = v15 | v17 & 63;
-      }
-      else
-      {
-        LOWORD(v18) = (unsigned __int8)(var_value | v17 & 0xC0);
-      }
-      *(short *)v16 = v18;
-    }
-LABEL_124:
-    DrawPlayerBuffAnimBasedOnCondition(currPlayerId);
-    PlaySoundBasedOnCondition(currPlayerId);
-    return;
-  }
-  if ( var_type <= VAR_MagicResistanceBonus )
-  {
-    switch ( var_type )
-    {
-      case VAR_FireResistanceBonus:
-        this->sResFireBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_AirResistanceBonus:
-        this->sResAirBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_WaterResistanceBonus:
-        this->sResWaterBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_EarthResistanceBonus:
-        this->sResEarthBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_SpiritResistanceBonus:
-        this->sResSpiritBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_MindResistanceBonus:
-        this->sResMindBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_BodyResistanceBonus:
-        this->sResBodyBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_LightResistanceBonus:
-        this->sResLightBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_DarkResistanceBonus:
-        this->sResDarkBonus = (unsigned __int8)var_value;
-        break;
-      case VAR_PhysicalResistanceBonus:
-        Assert("VAR_PhysicalResistanceBonus variable unsupported" && false);
-        return;
-        break;
-      case VAR_MagicResistanceBonus:
-        this->sResMagicBonus = (unsigned __int8)var_value;
-        break;
-      default:
-          Error("Unexpected var_type: %u", var_type);
-          return;
-        break;
-    }
-    goto LABEL_111;
-  }
-  if ( var_type > VAR_MagicResistanceBonus && var_type <= VAR_DiplomacySkill || var_type == VAR_DisarmTrapSkill)  //VAR_ThieverySkill wasn't present in the original function
-  {
-    return;
+      return;
+    case VAR_StaffSkill:
+      SetSkillByEvent(&Player::skillStaff, var_type, currPlayerId);
+      return;
+    case VAR_SwordSkill:
+      SetSkillByEvent(&Player::skillSword, var_type, currPlayerId);
+      return;
+    case VAR_DaggerSkill:
+      SetSkillByEvent(&Player::skillDagger, var_type, currPlayerId);
+      return;
+    case VAR_AxeSkill:
+      SetSkillByEvent(&Player::skillAxe, var_type, currPlayerId);
+      return;
+    case VAR_SpearSkill:
+      SetSkillByEvent(&Player::skillSpear, var_type, currPlayerId);
+      return;
+    case VAR_BowSkill:
+      SetSkillByEvent(&Player::skillBow, var_type, currPlayerId);
+      return;
+    case VAR_MaceSkill:
+      SetSkillByEvent(&Player::skillMace, var_type, currPlayerId);
+      return;
+    case VAR_BlasterSkill:
+      SetSkillByEvent(&Player::skillBlaster, var_type, currPlayerId);
+      return;
+    case VAR_ShieldSkill:
+      SetSkillByEvent(&Player::skillShield, var_type, currPlayerId);
+      return;
+    case VAR_LeatherSkill:
+      SetSkillByEvent(&Player::skillLeather, var_type, currPlayerId);
+      return;
+    case VAR_SkillChain:
+      SetSkillByEvent(&Player::skillChain, var_type, currPlayerId);
+      return;
+    case VAR_PlateSkill:
+      SetSkillByEvent(&Player::skillPlate, var_type, currPlayerId);
+      return;
+    case VAR_FireSkill:
+      SetSkillByEvent(&Player::skillFire, var_type, currPlayerId);
+      return;
+    case VAR_AirSkill:
+      SetSkillByEvent(&Player::skillAir, var_type, currPlayerId);
+      return;
+    case VAR_WaterSkill:
+      SetSkillByEvent(&Player::skillWater, var_type, currPlayerId);
+      return;
+    case VAR_EarthSkill:
+      SetSkillByEvent(&Player::skillEarth, var_type, currPlayerId);
+      return;
+    case VAR_SpiritSkill:
+      SetSkillByEvent(&Player::skillSpirit, var_type, currPlayerId);
+      return;
+    case VAR_MindSkill:
+      SetSkillByEvent(&Player::skillMind, var_type, currPlayerId);
+      return;
+    case VAR_BodySkill:
+      SetSkillByEvent(&Player::skillBody, var_type, currPlayerId);
+      return;
+    case VAR_LightSkill:
+      SetSkillByEvent(&Player::skillLight, var_type, currPlayerId);
+      return;
+    case VAR_DarkSkill:
+      SetSkillByEvent(&Player::skillDark, var_type, currPlayerId);
+      return;
+    case VAR_IdentifyItemSkill:
+      SetSkillByEvent(&Player::skillItemId, var_type, currPlayerId);
+      return;
+    case VAR_MerchantSkill:
+      SetSkillByEvent(&Player::skillMerchant, var_type, currPlayerId);
+      return;
+    case VAR_RepairSkill:
+      SetSkillByEvent(&Player::skillRepair, var_type, currPlayerId);
+      return;
+    case VAR_BodybuildingSkill:
+      SetSkillByEvent(&Player::skillBodybuilding, var_type, currPlayerId);
+      return;
+    case VAR_MeditationSkill:
+      SetSkillByEvent(&Player::skillMeditation, var_type, currPlayerId);
+      return;
+    case VAR_PerceptionSkill:
+      SetSkillByEvent(&Player::skillPerception, var_type, currPlayerId);
+      return;
+    case VAR_DiplomacySkill:
+      SetSkillByEvent(&Player::skillDiplomacy, var_type, currPlayerId);
+      return;
+    case VAR_ThieverySkill:
+      Error ("Thieving unsupported");
+      return;
+    case VAR_DisarmTrapSkill:
+      SetSkillByEvent(&Player::skillDisarmTrap, var_type, currPlayerId);
+      return;
+    case VAR_DodgeSkill:
+      SetSkillByEvent(&Player::skillDodge, var_type, currPlayerId);
+      return;
+    case VAR_UnarmedSkill:
+      SetSkillByEvent(&Player::skillUnarmed, var_type, currPlayerId);
+      return;
+    case VAR_IdentifyMonsterSkill:
+      SetSkillByEvent(&Player::skillMonsterId, var_type, currPlayerId);
+      return;
+    case VAR_ArmsmasterSkill:
+      SetSkillByEvent(&Player::skillArmsmaster, var_type, currPlayerId);
+      return;
+    case VAR_StealingSkill:
+      SetSkillByEvent(&Player::skillStealing, var_type, currPlayerId);
+      return;
+    case VAR_AlchemySkill:
+      SetSkillByEvent(&Player::skillAlchemy, var_type, currPlayerId);
+      return;
+    case VAR_LearningSkill:
+      SetSkillByEvent(&Player::skillLearning, var_type, currPlayerId);
+      return;
   }
 }
 
 
 //----- (new function) --------------------------------------------------------
-void Player::PlaySoundBasedOnCondition(int currPlayerId)
+void Player::PlayAwardSound(int currPlayerId)
 {
   signed int v25 = 8 * currPlayerId + 400;
   LOBYTE(v25) = PID(OBJECT_Player,currPlayerId - 112);
@@ -5931,571 +5985,605 @@
 }
 
 //----- (new function) --------------------------------------------------------
-void Player::DrawPlayerBuffAnimBasedOnCondition(int currPlayerId)
+void Player::PlayAwardSound_Anim(int currPlayerId)
 {
   pGame->pStru6Instance->SetPlayerBuffAnim(0x96u, currPlayerId);
+  PlayAwardSound(currPlayerId);
+}
+
+//----- (new function) --------------------------------------------------------
+void Player::PlayAwardSound_Anim_Face(int currPlayerId, PlayerSpeech speech)
+{
+  this->PlaySound(speech, 0);
+  PlayAwardSound_Anim(currPlayerId);
+}
+
+//----- (new function) --------------------------------------------------------
+void Player::SetSkillByEvent( unsigned __int16 Player::* skillToSet, unsigned __int16 newSkillValue, int currPlayerId )
+{
+  unsigned __int16 currSkillValue = this->*skillToSet;
+  if ( newSkillValue > 63 )         //the original had the condition reversed which was probably wrong
+  {
+    this->*skillToSet = newSkillValue | currSkillValue & 63;
+  }
+  else
+  {
+    this->*skillToSet = newSkillValue | currSkillValue & 0xC0;
+  }
+  pGame->pStru6Instance->SetPlayerBuffAnim(0x96u, currPlayerId);
+  PlayAwardSound(currPlayerId);
 }
 
 //----- (0044AFFB) --------------------------------------------------------
 void Player::AddVariable(enum VariableType var_type, signed int val)
 {
-  char v3; // bl@1
-  Player *v4; // esi@1
   signed int uPlayerIdx; // edi@1
   int v6; // eax@15
   unsigned int v7; // esi@18
-  int *v8; // ebx@21
-  int v9; // eax@22
-  signed int v10; // eax@24
-  int v11; // eax@27
-  __int16 *v12; // esi@28
-  Player *v13; // ecx@34
-  Player *v14; // ecx@36
-  char *v15; // ecx@37
-  unsigned __int8 v16; // cf@38
-  Player *v17; // ecx@42
-  __int16 *v18; // esi@53
-  __int16 *v19; // esi@62
-  char *v20; // esi@107
-  __int16 v21; // dx@107
-  int v22; // ecx@107
-  Player *v23; // ecx@132
-  int v24; // eax@132
-  int v25; // eax@150
-  char v26; // zf@151
   DDM_DLV_Header *v27; // eax@153
-  signed int v28; // eax@176
-  int v29; // [sp-8h] [bp-40h]@84
- // signed int v30; // [sp-4h] [bp-3Ch]@4
-  int v31; // [sp-4h] [bp-3Ch]@84
   ItemGen item; // [sp+Ch] [bp-2Ch]@45
-  unsigned int v33; // [sp+30h] [bp-8h]@34
-  char v34; // [sp+37h] [bp-1h]@1
-
-  auto Dst = this;
-  v3 = 0;
-  v34 = 0;
-  v4 = Dst;
+
   uPlayerIdx = 0;
-  if ( Dst == pPlayers[2] )
+  if ( this == pPlayers[2] )
     uPlayerIdx = 1;
-  else if ( Dst == pPlayers[3] )
+  else if ( this == pPlayers[3] )
     uPlayerIdx = 2;
-  else if ( Dst == pPlayers[4] )  
+  else if ( this == pPlayers[4] )  
     uPlayerIdx = 3;
  
-  if ( var_type <= VAR_AutoNotes )
-  {
-    if ( var_type != VAR_AutoNotes )
+  if ( var_type >= VAR_Counter1 && var_type <= VAR_Counter10)
+  {
+    pParty->PartyTimes.CounterEventValues[var_type - VAR_Counter1] = pParty->uTimePlayed;
+    return;
+  }
+
+  if ( var_type >= VAR_UnknownTimeEvent0 && var_type <= VAR_UnknownTimeEvent19 )
+  {
+    pParty->PartyTimes._s_times[var_type - VAR_UnknownTimeEvent0] = pParty->uTimePlayed;
+    PlayAwardSound(uPlayerIdx);
+    return;
+  }
+
+  if ( var_type >= VAR_MapPersistentVariable_0 && var_type <= VAR_MapPersistentVariable_99 )
+  {
+    if ( (unsigned __int8)val + (unsigned __int8)byte_5E4C15[var_type] <= 255 )
+      byte_5E4C15[var_type] += val;
+    else
+      byte_5E4C15[var_type] = -1;
+    return;
+  }
+
+  if ( var_type >= VAR_History_0 && var_type <= VAR_History_28)
+  {
+    if (!pParty->PartyTimes.HistoryEventTimes[var_type - VAR_History_0])
     {
-      if ( var_type <= VAR_ActualMight )
+      pParty->PartyTimes.HistoryEventTimes[var_type - VAR_History_0] = pParty->uTimePlayed;
+      if (pStorylineText->StoreLine[var_type - VAR_History_0].pText = 0)
+      {
+        bFlashHistoryBook = 1;
+        PlayAwardSound(uPlayerIdx);
+      }
+    }
+    return;
+  }
+
+  switch ( var_type )
+  {
+    case VAR_RandomGold:
+      if ( val == 0 )
+        val = 1;
+      v6 = rand();
+      party_finds_gold(v6 % val + 1, 1);
+      GameUI_DrawFoodAndGold();
+      return;
+    case VAR_RandomFood:
+      if ( val == 0 )
+        val = 1;
+      v7 = rand() % val + 1;
+      Party::GiveFood(v7);
+      sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[502], v7);// You find %lu food
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+      GameUI_DrawFoodAndGold();
+      PlayAwardSound(uPlayerIdx);
+      return;
+    case VAR_Sex:
+      this->uSex = (PLAYER_SEX)val;
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Class:
+      this->classType = (PLAYER_CLASS_TYPE)val;
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_CurrentHP:
+      this->sHealth = min(this->sHealth + val, this->GetMaxHealth() );
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_MaxHP:
+      this->_health_related = 0;
+      this->uFullHealthBonus = 0;
+      this->sHealth = this->GetMaxHealth();
+      return;
+    case VAR_CurrentSP:
+      this->sMana = min(this->sMana + val, this->GetMaxMana() );
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_MaxSP:
+      this->_mana_related = 0;
+      this->uFullManaBonus = 0;
+      this->sMana = GetMaxMana();
+      return;
+    case VAR_ACModifier:
+      this->sACModifier = min(this->sACModifier + val, 255);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_BaseLevel:
+      this->uLevel = min(this->uLevel + val, 255);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_LevelModifier:
+      this->sLevelModifier = min(this->sLevelModifier + val, 255);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Age:
+      this->sAgeModifier += val;
+      return;
+    case VAR_Award:
+      if (_449B57_test_bit(this->_achieved_awards_bits, val) && pAwards[val].pText )
+      {
+        PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_96);
+      }
+      _449B7E_toggle_bit(this->_achieved_awards_bits, val, 1);
+      return;
+    case VAR_Experience:
+      this->uExperience = min(this->uExperience + val, 4000000000i64);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_QBits_QuestsDone:
+      if ( !_449B57_test_bit(pParty->_quest_bits, val) && pQuestTable[val] )
+      {
+        bFlashQuestBook = 1;
+        PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_93);
+      }
+      _449B7E_toggle_bit(pParty->_quest_bits, val, 1);
+      return;
+    case VAR_PlayerItemInHands:
+      item.Reset();
+      item.uAttributes = 1;
+      item.uItemID = val;
+      if ( val >= ITEM_ARTIFACT_PUCK && val <= ITEM_RELIC_MEKORIGS_HAMMER )
+        pParty->pIsArtifactFound[val-500] = 1;
+      else if ( val >= ITEM_WAND_FIRE && val <= ITEM_WAND_INCENERATION )
       {
-        if ( var_type != VAR_ActualMight )
-        {
-          switch ( var_type )
-          {
-            case VAR_RandomGold:
-              if ( !val )
-                val = 1;
-              v6 = rand();
-              party_finds_gold(v6 % val + 1, 1);
-              GameUI_DrawFoodAndGold();
-              return;
-            case VAR_RandomFood:
-              if ( !val )
-                val = 1;
-              v7 = rand() % val + 1;
-              Party::GiveFood(v7);
-              sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[502], v7);// You find %lu food
-              ShowStatusBarString(pTmpBuf.data(), 2u);
-              GameUI_DrawFoodAndGold();
-              goto _play_sound;
-            case VAR_Sex:
-              Dst->uSex = (PLAYER_SEX)val;
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              goto _play_sound;
-            case VAR_Class:
-              Dst->classType = (PLAYER_CLASS_TYPE)val;
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              goto _play_sound;
-            case VAR_CurrentHP:
-              v8 = &Dst->sHealth;
-              *v8 += val;
-              if ( Dst->sHealth <= Dst->GetMaxHealth() )
-              {
-                pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-                goto _play_sound;
-              }
-              v9 = v4->GetMaxHealth();
-              goto LABEL_23;
-            case VAR_MaxHP:
-              v10 = Dst->GetMaxHealth();
-              v4->_health_related = 0;
-              v4->uFullHealthBonus = 0;
-              v4->sHealth = v10;
-              return;
-            case VAR_CurrentSP:
-              v8 = &Dst->sMana;
-              *v8 += val;
-              if ( Dst->sMana > GetMaxMana() )
-              {
-                v9 = v4->GetMaxMana();
-LABEL_23:
-                *v8 = v9;
-              }
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              goto _play_sound;
-            case VAR_MaxSP:
-              v11 = GetMaxMana();
-              v4->_mana_related = 0;
-              v4->uFullManaBonus = 0;
-              v4->sMana = v11;
-              return;
-            case VAR_ACModifier:
-              v12 = &Dst->sACModifier;
-              goto LABEL_29;
-            case VAR_BaseLevel:
-              v12 = (__int16 *)&Dst->uLevel;
-              goto LABEL_29;
-            case VAR_LevelModifier:
-              v12 = &Dst->sLevelModifier;
-LABEL_29:
-              *v12 += val;
-              if ( *v12 > 255 )
-                *v12 = 255;
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              goto _play_sound;
-            case VAR_Age:
-              Dst->sAgeModifier += val;
-              return;
-            case VAR_Award:
-              v13 = pPlayers[uPlayerIdx + 1];
-              if (_449B57_test_bit((unsigned __int8 *)pPlayers[uPlayerIdx + 1]->_achieved_awards_bits, val) 
-             
-				&& pAwards[val].pText )
-              {
-                v14 = pPlayers[uPlayerIdx + 1];
-                v34 = 1;
-                v3 = 1;
-                v14->PlaySound(SPEECH_96, 0);
-              }
-              v15 = (char *)v4->_achieved_awards_bits;
-              _449B7E_toggle_bit((unsigned char *)v15, val, 1);
-              if ( v34 != 1 )
-              {
-                if ( v3 != 1 )
-                  return;
-                goto _play_sound;
-              }
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              if ( v3 != 1 )
-                return;
-              goto _play_sound;
-            case VAR_Experience:
-              v16 = __CFADD__(val, LODWORD(Dst->uExperience));
-              LODWORD(Dst->uExperience) += val;
-              HIDWORD(Dst->uExperience) += ((unsigned __int64)val >> 32) + v16;
-              if ( (signed __int64)Dst->uExperience > 4000000000i64 )
-                Dst->uExperience = 4000000000i64;
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              goto _play_sound;
-            case VAR_QBits_QuestsDone:
-              if ( !((unsigned __int8)(0x80u >> ((signed __int16)val - 1) % 8) & pParty->_quest_bits[((signed __int16)val - 1) >> 3])
-                //&& (&dword_722F10)[4 * val] )
-				&& pQuestTable[val] )
-              {
-                //v17 = pPlayers[uPlayerIdx + 1];
-                bFlashQuestBook = 1;
-                v34 = 1;
-                v3 = 1;
-                pPlayers[uPlayerIdx + 1]->PlaySound(SPEECH_93, 0);
-              }
-              v15 = (char *)pParty->_quest_bits;
-              _449B7E_toggle_bit((unsigned char *)v15, val, 1);
-              if ( v34 != 1 )
-              {
-                if ( v3 != 1 )
-                  return;
-                goto _play_sound;
-              }
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              if ( v3 != 1 )
-                return;
-              goto _play_sound;
-            case VAR_PlayerItemInHands:
-              item.Reset();
-              item.Reset();
-              item.uAttributes = 1;
-              item.uItemID = val;
-              if ( val >= ITEM_ARTIFACT_PUCK && val <= ITEM_RELIC_MEKORIGS_HAMMER )
-                pParty->pIsArtifactFound[val-500] = 1;
-              if ( val >= ITEM_WAND_FIRE && val <= ITEM_WAND_INCENERATION )
-              {
-                item.uNumCharges = rand() % 6 + item.GetDamageMod() + 1;
-                item.uMaxCharges = LOBYTE(item.uNumCharges);
-              }
-              pParty->SetHoldingItem(&item);
-              return;
-            case VAR_FixedGold:
-              party_finds_gold(val, 1);
-              return;
-            case VAR_BaseMight:
-              v18 = (__int16 *)&Dst->uMight;
-              goto LABEL_82;
-            case VAR_BaseIntellect:
-              v18 = (__int16 *)&Dst->uIntelligence;
-              goto LABEL_82;
-            case VAR_BasePersonality:
-              v18 = (__int16 *)&Dst->uWillpower;
-              goto LABEL_82;
-            case VAR_BaseEndurance:
-              v18 = (__int16 *)&Dst->uEndurance;
-              goto LABEL_82;
-            case VAR_BaseSpeed:
-              v18 = (__int16 *)&Dst->uSpeed;
-              goto LABEL_82;
-            case VAR_BaseAccuracy:
-              v18 = (__int16 *)&Dst->uAccuracy;
-              goto LABEL_82;
-            case VAR_BaseLuck:
-              v18 = (__int16 *)&Dst->uLuck;
-              goto LABEL_82;
-            case VAR_FixedFood:
-              Party::GiveFood(val);
-              sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[502], val);
-              ShowStatusBarString(pTmpBuf.data(), 2u);
-              if ( pParty->uNumFoodRations > 0xFFFF )
-                Party::SetFood(0xFFFFu);
-              goto _play_sound;
-            case VAR_MightBonus:
-              goto LABEL_62;
-            case VAR_IntellectBonus:
-              goto LABEL_66;
-            case VAR_PersonalityBonus:
-              goto LABEL_67;
-            case VAR_EnduranceBonus:
-              goto LABEL_68;
-            case VAR_SpeedBonus:
-              goto LABEL_69;
-            case VAR_AccuracyBonus:
-              goto LABEL_70;
-            case VAR_LuckBonus:
-              goto LABEL_71;
-            default:
-              return;
-          }
-          return;
-        }
-LABEL_62:
-        v19 = (__int16 *)&Dst->uMightBonus;
-        goto LABEL_113;
+        item.uNumCharges = rand() % 6 + item.GetDamageMod() + 1;
+        item.uMaxCharges = LOBYTE(item.uNumCharges);
       }
-      if ( var_type <= VAR_FireResistanceBonus )
-      {
-        if ( var_type != VAR_FireResistanceBonus )
+      pParty->SetHoldingItem(&item);
+      return;
+    case VAR_FixedGold:
+      party_finds_gold(val, 1);
+      return;
+    case VAR_BaseMight:
+      this->uMight = min(this->uMight + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_BaseIntellect:
+      this->uIntelligence = min(this->uIntelligence + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_BasePersonality:
+      this->uWillpower = min(this->uWillpower + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_BaseEndurance:
+      this->uEndurance = min(this->uEndurance + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_BaseSpeed:
+      this->uSpeed = min(this->uSpeed + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_BaseAccuracy:
+      this->uAccuracy = min(this->uAccuracy + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_BaseLuck:
+      this->uLuck = min(this->uLuck + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_FixedFood:
+      Party::GiveFood(val);
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[502], val);
+      ShowStatusBarString(pTmpBuf.data(), 2u);
+      if ( pParty->uNumFoodRations > 0xFFFF )
+        Party::SetFood(0xFFFFu);
+      PlayAwardSound(uPlayerIdx);
+      return;
+    case VAR_MightBonus:
+    case VAR_ActualMight:
+      this->uMightBonus = min(this->uMightBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_IntellectBonus:
+    case VAR_ActualIntellect:
+      this->uIntelligenceBonus = min(this->uIntelligenceBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_PersonalityBonus:
+    case VAR_ActualPersonality:
+      this->uWillpowerBonus = min(this->uWillpowerBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_EnduranceBonus:
+    case VAR_ActualEndurance:
+      this->uEnduranceBonus = min(this->uEnduranceBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_SpeedBonus:
+    case VAR_ActualSpeed:
+      this->uSpeedBonus = min(this->uSpeedBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_AccuracyBonus:
+    case VAR_ActualAccuracy:
+      this->uAccuracyBonus = min(this->uAccuracyBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_LuckBonus:
+    case VAR_ActualLuck:
+      this->uLuckBonus = min(this->uLuckBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_FireResistance:
+      this->sResFireBase = min(this->sResFireBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_AirResistance:
+      this->sResAirBase = min(this->sResAirBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_WaterResistance:
+      this->sResWaterBase = min(this->sResWaterBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_EarthResistance:
+      this->sResEarthBase = min(this->sResEarthBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_SpiritResistance:
+      this->sResSpiritBase = min(this->sResSpiritBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_MindResistance:
+      this->sResMindBase = min(this->sResMindBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_BodyResistance:
+      this->sResBodyBase = min(this->sResBodyBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_LightResistance:
+      this->sResLightBase = min(this->sResLightBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_DarkResistance:
+      this->sResDarkBase = min(this->sResDarkBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_MagicResistance:
+      this->sResMagicBase = min(this->sResMagicBase + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_92);
+      return;
+    case VAR_FireResistanceBonus:
+      this->sResFireBonus = min(this->sResFireBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_AirResistanceBonus:
+      this->sResAirBonus = min(this->sResAirBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_WaterResistanceBonus:
+      this->sResWaterBonus = min(this->sResWaterBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_EarthResistanceBonus:
+      this->sResEarthBonus = min(this->sResEarthBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_SpiritResistanceBonus:
+      this->sResSpiritBonus = min(this->sResSpiritBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_MindResistanceBonus:
+      this->sResMindBonus = min(this->sResMindBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_BodyResistanceBonus:
+      this->sResBodyBonus = min(this->sResBodyBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_LightResistanceBonus:
+      this->sResLightBonus = min(this->sResLightBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_DarkResistanceBonus:
+      this->sResDarkBonus = min(this->sResDarkBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_MagicResistanceBonus:
+      this->sResMagicBonus = min(this->sResMagicBonus + val, 255);
+      PlayAwardSound_Anim97_Face(uPlayerIdx, SPEECH_91);
+      return;
+    case VAR_Cursed:
+      this->SetCondition(Condition_Cursed, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Weak:
+      this->SetCondition(Condition_Weak, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Asleep:
+      this->SetCondition(Condition_Sleep, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Afraid:
+      this->SetCondition(Condition_Fear, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Drunk:
+      this->SetCondition(Condition_Drunk, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Insane:
+      this->SetCondition(Condition_Insane, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_PoisonedGreen:
+      this->SetCondition(Condition_Poison1, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_DiseasedGreen:
+      this->SetCondition(Condition_Disease1, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_PoisonedYellow:
+      this->SetCondition(Condition_Poison2, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_DiseasedYellow:
+      this->SetCondition(Condition_Disease2, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_PoisonedRed:
+      this->SetCondition(Condition_Poison3, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_DiseasedRed:
+      this->SetCondition(Condition_Disease3, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Paralyzed:
+      this->SetCondition(Condition_Paralyzed, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Unconsious:
+      this->SetCondition(Condition_Unconcious, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Dead:
+      this->SetCondition(Condition_Dead, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Stoned:
+      this->SetCondition(Condition_Pertified, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_Eradicated:
+      this->SetCondition(Condition_Eradicated, 1);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_MajorCondition :
+      memset(this, 0, 0xA0u);
+      PlayAwardSound_Anim97(uPlayerIdx);
+      return;
+    case VAR_AutoNotes:
+        if ( !_449B57_test_bit(pParty->_autonote_bits, val) && pAutonoteTxt[val].pText )
         {
-          switch ( var_type )
-          {
-            case VAR_ActualIntellect:
-LABEL_66:
-              v19 = (__int16 *)&Dst->uIntelligenceBonus;
-              goto LABEL_113;
-            case VAR_ActualPersonality:
-LABEL_67:
-              v19 = (__int16 *)&Dst->uWillpowerBonus;
-              goto LABEL_113;
-            case VAR_ActualEndurance:
-LABEL_68:
-              v19 = (__int16 *)&Dst->uEnduranceBonus;
-              goto LABEL_113;
-            case VAR_ActualSpeed:
-LABEL_69:
-              v19 = (__int16 *)&Dst->uSpeedBonus;
-              goto LABEL_113;
-            case VAR_ActualAccuracy:
-LABEL_70:
-              v19 = (__int16 *)&Dst->uAccuracyBonus;
-              goto LABEL_113;
-            case VAR_ActualLuck:
-LABEL_71:
-              v19 = (__int16 *)&Dst->uLuckBonus;
-              goto LABEL_113;
-            case VAR_FireResistance:
-              v18 = &Dst->sResFireBase;
-              goto LABEL_82;
-            case VAR_AirResistance:
-              v18 = &Dst->sResAirBase;
-              goto LABEL_82;
-            case VAR_WaterResistance:
-              v18 = &Dst->sResWaterBase;
-              goto LABEL_82;
-            case VAR_EarthResistance:
-              v18 = &Dst->sResEarthBase;
-              goto LABEL_82;
-            case VAR_SpiritResistance:
-              v18 = &Dst->sResSpiritBase;
-              goto LABEL_82;
-            case VAR_MindResistance:
-              v18 = &Dst->sResMindBase;
-              goto LABEL_82;
-            case VAR_BodyResistance:
-              v18 = &Dst->sResBodyBase;
-              goto LABEL_82;
-            case VAR_LightResistance:
-              v18 = &Dst->sResLightBase;
-              goto LABEL_82;
-            case VAR_DarkResistance:
-              v18 = &Dst->sResDarkBase;
-              goto LABEL_82;
-            case VAR_MagicResistance:
-              v18 = &Dst->sResMagicBase;
-LABEL_82:
-              *v18 += val;
-              if ( *v18 > 255 )
-                *v18 = 255;
-              pPlayers[uPlayerIdx + 1]->PlaySound(SPEECH_92, 0);
-              pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-              goto _play_sound;
-            default:
-              return;
-          }
-          return;
+          this->PlaySound(SPEECH_96, 0);
+          bFlashAutonotesBook = 1;
+          _506568_autonote_type = pAutonoteTxt[val].eType;
+          pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
         }
-        v19 = &Dst->sResFireBonus;
-LABEL_113:
-        *v19 += val;
-        if ( *v19 > 255 )
-          *v19 = 255;
-        v31 = 0;
-        v29 = SPEECH_91;
-        pPlayers[uPlayerIdx + 1]->PlaySound((PlayerSpeech)v29, v31);
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-        goto _play_sound;
-      }
-      if ( var_type <= VAR_DisarmTrapSkill )
-      {
-        if ( var_type != VAR_DisarmTrapSkill )
-        {
-          if ( var_type <= VAR_BodyResistanceBonus )
-          {
-            switch ( var_type )
-            {
-              case VAR_BodyResistanceBonus:
-                v19 = &Dst->sResBodyBonus;
-                break;
-              case VAR_AirResistanceBonus:
-                v19 = &Dst->sResAirBonus;
-                break;
-              case VAR_WaterResistanceBonus:
-                v19 = &Dst->sResWaterBonus;
-                break;
-              case VAR_EarthResistanceBonus:
-                v19 = &Dst->sResEarthBonus;
-                break;
-              case VAR_SpiritResistanceBonus:
-                v19 = &Dst->sResSpiritBonus;
-                break;
-              default:
-                if ( var_type != 62 )
-                  return;
-                v19 = &Dst->sResMindBonus;
-                break;
-            }
-            goto LABEL_113;
-          }
-          if ( var_type == VAR_LightResistanceBonus )
-          {
-            v19 = &Dst->sResLightBonus;
-            goto LABEL_113;
-          }
-          if ( var_type == VAR_DarkResistanceBonus )
-          {
-            v19 = &Dst->sResDarkBonus;
-            goto LABEL_113;
-          }
-          if ( var_type == VAR_MagicResistanceBonus )
-          {
-            v19 = &Dst->sResMagicBonus;
-            goto LABEL_113;
-          }
-          if ( var_type <= VAR_MagicResistanceBonus || var_type > VAR_DiplomacySkill )
-            return;
-        }
-        goto LABEL_106;
-      }
-      if ( var_type == VAR_LearningSkill )
-      {
-LABEL_106:
-        if ( val <= VAR_BodyResistanceBonus )
-        {
-          *((short *)&Dst->pConditions[16] + var_type) = (unsigned __int8)val | *((char *)&Dst->pConditions[16] + 2 * var_type) & VAR_BodyResistanceBonus;
-        }
-        else
-        {
-          v20 = (char *)&Dst->pConditions[16] + 2 * var_type;
-          v21 = *(short *)v20;
-          v22 = (unsigned __int8)val + (v21 & VAR_BodyResistanceBonus);
-          if ( v22 > 60 )
-            LOWORD(v22) = 60;
-          LOBYTE(v21) = v21 & 0xC0;
-          *(short *)v20 = v22 | v21;
-        }
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-        goto _play_sound;
-      }
-      if ( var_type <= VAR_LearningSkill )
+        _449B7E_toggle_bit(pParty->_autonote_bits, val, 1);
+        PlayAwardSound(uPlayerIdx);
         return;
-      if ( var_type <= VAR_Eradicated )
-      {
-        Dst->SetCondition(var_type - 105, 0);
-      }
-      else
-      {
-        if ( var_type != VAR_MajorCondition )
-        {
-          if ( var_type > VAR_MajorCondition && var_type <= VAR_MapPersistentVariable_99 )
-          {
-            if ( (unsigned __int8)val + (unsigned __int8)byte_5E4C15[var_type] <= 255 )
-              byte_5E4C15[var_type] += val;
-            else
-              byte_5E4C15[var_type] = -1;
-          }
-          return;
-        }
-        memset(Dst, 0, 0xA0u);
-      }
-      pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-      goto _play_sound;
-    }
-    if ( !((unsigned __int8)(0x80u >> ((signed __int16)val - 1) % 8) & pParty->_autonote_bits[((signed __int16)val - 1) >> 3])
-      //&& (&dword_723718_autonote_related)[8 * val] )
-	  && pAutonoteTxt[val].pText )
-    {
-      v23 = pPlayers[uPlayerIdx + 1];
-      v34 = 1;
-      v23->PlaySound(SPEECH_96, 0);
-	  //v24 = pAutonoteTxt[val].eType;//dword_72371C[2 * val];
-      bFlashAutonotesBook = 1;
-      _506568_autonote_type = pAutonoteTxt[val].eType;
-    }
-    _449B7E_toggle_bit(pParty->_autonote_bits, val, 1);
-    v3 = 1;
-    if ( v34 != 1 )
-    {
-      if ( v3 != 1 )
-        return;
-      goto _play_sound;
-    }
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-    if ( v3 != 1 )
-      return;
-    goto _play_sound;
-  }
-  if ( var_type > VAR_GoldInBank )
-  {
-    if ( var_type == 307 )
-    {
+    case VAR_PlayerBits:
+      _449B7E_toggle_bit((unsigned char *)this->field_1A50, val, 1u);
+      return;
+    case VAR_NPCs2:
+      pParty->hirelingScrollPosition = 0;
+      LOBYTE(pNPCStats->pNewNPCData[val].uFlags) |= 0x80u;
+      pParty->CountHirelings();
+      viewparams->bRedrawGameUI = true;
+      return;
+    case VAR_NumSkillPoints:
+      this->uSkillPoints += val;
+      return;
+    case VAR_ReputationInCurrentLocation:
+      v27 = &pOutdoor->ddm;
+      if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
+        v27 = &pIndoor->dlv;
+      v27->uReputation += val;
+      if ( v27->uReputation > 10000 )
+        v27->uReputation = 10000;
+      return;
+    case VAR_GoldInBank:
+      pParty->uNumGoldInBank += val;
+      return;
+    case VAR_NumDeaths:
       pParty->uNumDeaths += val;
-      if ( v34 != 1 )
-      {
-        if ( v3 != 1 )
-          return;
-        goto _play_sound;
-      }
-      pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, uPlayerIdx);
-      if ( v3 != 1 )
-        return;
-      goto _play_sound;
-    }
-    switch ( var_type )
-    {
-      case 308:
-        pParty->uNumBountiesCollected += val;
-        break;
-      case 309:
-        pParty->uNumPrisonTerms += val;
-        break;
-      case 310:
-        pParty->uNumArenaPageWins += val;
-        break;
-      case 311:
-        pParty->uNumArenaSquireWins += val;
-        break;
-      case 312:
-        pParty->uNumArenaKnightWins += val;
-        break;
-      case 313:
-        pParty->uNumArenaLordWins += val;
-        break;
-    }
+      return;
+    case VAR_NumBounties:
+      pParty->uNumBountiesCollected += val;
+      return;
+    case VAR_PrisonTerms:
+      pParty->uNumPrisonTerms += val;
+      return;
+    case VAR_ArenaWinsPage:
+      pParty->uNumArenaPageWins += val;
+      return;
+    case VAR_ArenaWinsSquire:
+      pParty->uNumArenaSquireWins += val;
+      return;
+    case VAR_ArenaWinsKnight:
+      pParty->uNumArenaKnightWins += val;
+      return;
+    case VAR_ArenaWinsLord:
+      pParty->uNumArenaLordWins += val;
+      return;
+    case VAR_StaffSkill:
+      AddSkillByEvent(&Player::skillStaff, val, uPlayerIdx);
+      return;
+    case VAR_SwordSkill:
+      AddSkillByEvent(&Player::skillSword, val, uPlayerIdx);
+      return;
+    case VAR_DaggerSkill:
+      AddSkillByEvent(&Player::skillDagger, val, uPlayerIdx);
+      return;
+    case VAR_AxeSkill:
+      AddSkillByEvent(&Player::skillAxe, val, uPlayerIdx);
+      return;
+    case VAR_SpearSkill:
+      AddSkillByEvent(&Player::skillSpear, val, uPlayerIdx);
+      return;
+    case VAR_BowSkill:
+      AddSkillByEvent(&Player::skillBow, val, uPlayerIdx);
+      return;
+    case VAR_MaceSkill:
+      AddSkillByEvent(&Player::skillMace, val, uPlayerIdx);
+      return;
+    case VAR_BlasterSkill:
+      AddSkillByEvent(&Player::skillBlaster, val, uPlayerIdx);
+      return;
+    case VAR_ShieldSkill:
+      AddSkillByEvent(&Player::skillShield, val, uPlayerIdx);
+      return;
+    case VAR_LeatherSkill:
+      AddSkillByEvent(&Player::skillLeather, val, uPlayerIdx);
+      return;
+    case VAR_SkillChain:
+      AddSkillByEvent(&Player::skillChain, val, uPlayerIdx);
+      return;
+    case VAR_PlateSkill:
+      AddSkillByEvent(&Player::skillPlate, val, uPlayerIdx);
+      return;
+    case VAR_FireSkill:
+      AddSkillByEvent(&Player::skillFire, val, uPlayerIdx);
+      return;
+    case VAR_AirSkill:
+      AddSkillByEvent(&Player::skillAir, val, uPlayerIdx);
+      return;
+    case VAR_WaterSkill:
+      AddSkillByEvent(&Player::skillWater, val, uPlayerIdx);
+      return;
+    case VAR_EarthSkill:
+      AddSkillByEvent(&Player::skillEarth, val, uPlayerIdx);
+      return;
+    case VAR_SpiritSkill:
+      AddSkillByEvent(&Player::skillSpirit, val, uPlayerIdx);
+      return;
+    case VAR_MindSkill:
+      AddSkillByEvent(&Player::skillMind, val, uPlayerIdx);
+      return;
+    case VAR_BodySkill:
+      AddSkillByEvent(&Player::skillBody, val, uPlayerIdx);
+      return;
+    case VAR_LightSkill:
+      AddSkillByEvent(&Player::skillLight, val, uPlayerIdx);
+      return;
+    case VAR_DarkSkill:
+      AddSkillByEvent(&Player::skillDark, val, uPlayerIdx);
+      return;
+    case VAR_IdentifyItemSkill:
+      AddSkillByEvent(&Player::skillItemId, val, uPlayerIdx);
+      return;
+    case VAR_MerchantSkill:
+      AddSkillByEvent(&Player::skillMerchant, val, uPlayerIdx);
+      return;
+    case VAR_RepairSkill:
+      AddSkillByEvent(&Player::skillRepair, val, uPlayerIdx);
+      return;
+    case VAR_BodybuildingSkill:
+      AddSkillByEvent(&Player::skillBodybuilding, val, uPlayerIdx);
+      return;
+    case VAR_MeditationSkill:
+      AddSkillByEvent(&Player::skillMeditation, val, uPlayerIdx);
+      return;
+    case VAR_PerceptionSkill:
+      AddSkillByEvent(&Player::skillPerception, val, uPlayerIdx);
+      return;
+    case VAR_DiplomacySkill:
+      AddSkillByEvent(&Player::skillDiplomacy, val, uPlayerIdx);
+      return;
+    case VAR_ThieverySkill:
+      Error ("Thieving unsupported");
+      return;
+    case VAR_DisarmTrapSkill:
+      AddSkillByEvent(&Player::skillDisarmTrap, val, uPlayerIdx);
+      return;
+    case VAR_DodgeSkill:
+      AddSkillByEvent(&Player::skillDodge, val, uPlayerIdx);
+      return;
+    case VAR_UnarmedSkill:
+      AddSkillByEvent(&Player::skillUnarmed, val, uPlayerIdx);
+      return;
+    case VAR_IdentifyMonsterSkill:
+      AddSkillByEvent(&Player::skillMonsterId, val, uPlayerIdx);
+      return;
+    case VAR_ArmsmasterSkill:
+      AddSkillByEvent(&Player::skillArmsmaster, val, uPlayerIdx);
+      return;
+    case VAR_StealingSkill:
+      AddSkillByEvent(&Player::skillStealing, val, uPlayerIdx);
+      return;
+    case VAR_AlchemySkill:
+      AddSkillByEvent(&Player::skillAlchemy, val, uPlayerIdx);
+      return;
+    case VAR_LearningSkill:
+      AddSkillByEvent(&Player::skillLearning, val, uPlayerIdx);
+      return;
+    default:
+      return;
+  }
+}
+
+//----- (new function) --------------------------------------------------------
+void Player::PlayAwardSound_Anim97(int currPlayerId)
+{
+  pGame->pStru6Instance->SetPlayerBuffAnim(0x97u, currPlayerId);
+  PlayAwardSound(currPlayerId);
+}
+
+//----- (new function) --------------------------------------------------------
+void Player::PlayAwardSound_Anim97_Face(int currPlayerId, PlayerSpeech speech)
+{
+  this->PlaySound(speech, 0);
+  PlayAwardSound_Anim97(currPlayerId);
+}
+
+//----- (new function) --------------------------------------------------------
+void Player::AddSkillByEvent( unsigned __int16 Player::* skillToSet, unsigned __int16 addSkillValue, int currPlayerId )
+{
+  if ( addSkillValue > 63 )
+  {
+    this->*skillToSet = (unsigned __int8)addSkillValue | this->*skillToSet & 63;
   }
   else
   {
-    if ( var_type == VAR_GoldInBank )
-    {
-      pParty->uNumGoldInBank += val;
-      return;
-    }
-    if ( var_type <= VAR_Counter8 )
-    {
-      if ( (signed int)var_type >= 245 )
-      {
-        *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44300] = LODWORD(pParty->uTimePlayed);
-        *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44304] = HIDWORD(pParty->uTimePlayed);
-      }
-      else
-      {
-        switch ( var_type )
-        {
-          case VAR_PlayerBits:
-            _449B7E_toggle_bit((unsigned char *)Dst->field_1A50, val, 1u);
-            break;
-          case VAR_NPCs2:
-            pParty->field_709 = 0;
-            LOBYTE(pNPCStats->pNewNPCData[val].uFlags) |= 0x80u;
-            pParty->CountHirelings();
-            viewparams->bRedrawGameUI = true;
-            break;
-          case VAR_NumSkillPoints:
-            Dst->uSkillPoints += val;
-            break;
-        }
-      }
-      return;
-    }
-    if ( var_type < VAR_Counter9 )
-      return;
-    if ( (signed int)var_type <= 274 )
-    {
-      *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44532] = LODWORD(pParty->uTimePlayed);
-      *(int *)&stru_AA1058[3].pSounds[8 * var_type + 44536] = HIDWORD(pParty->uTimePlayed);
-      goto _play_sound;
-    }
-    if ( var_type != VAR_ReputationInCurrentLocation )
-    {
-      if ( var_type <= VAR_ReputationInCurrentLocation
-        || var_type > VAR_History_28
-        || (v25 = var_type - 276, pParty->PartyTimes.HistoryEventTimes[v25])
-        || (pParty->PartyTimes.HistoryEventTimes[var_type - 276] = pParty->uTimePlayed,
-            v26 = pStorylineText->StoreLine[v25].pText==0,//*(&pStorylineText->field_0 + 3 * v25) == 0,
-            v26) )
-        return;
-      bFlashHistoryBook = 1;
-_play_sound:
-      v28 = 8 * uPlayerIdx + 400;
-      LOBYTE(v28) = PID(OBJECT_Player,uPlayerIdx - 112);
-      pAudioPlayer->PlaySound(SOUND_20001, v28, 0, -1, 0, 0, 0, 0);
-      return;
-    }
-    v27 = &pOutdoor->ddm;
-    if ( uCurrentlyLoadedLevelType != LEVEL_Outdoor )
-      v27 = &pIndoor->dlv;
-    v27->uReputation += val;
-    if ( v27->uReputation > 10000 )
-      v27->uReputation = 10000;
-  }
-}
-
+    this->*skillToSet = min(this->*skillToSet + addSkillValue, 60) | this->*skillToSet & 0xC0;
+  }
+  PlayAwardSound_Anim97(currPlayerId);
+  return;
+}
 
 //----- (0044B9C4) --------------------------------------------------------
 bool Player::SubtractVariable(enum VariableType VarNum, signed int pValue)
@@ -6551,14 +6639,14 @@
               VarNum = (VariableType)0;
               GetNewNPCData(sDialogue_SpeakingActorNPC_ID, (int*)&VarNum);
               result = (bool) pValue;
-			  dword_5B65CC = 0;
+			  npcIdToDismissAfterDialogue = 0;
               if ( (int)VarNum == pValue )
               {
-                dword_5B65CC = (int)pValue;
+                npcIdToDismissAfterDialogue = (int)pValue;
               }
               else
               {
-                pParty->field_709 = 0;
+                pParty->hirelingScrollPosition = 0;
                 LOBYTE(pNPCStats->pNewNPCData[(int)pValue].uFlags) &= 0x7Fu;
                 pParty->CountHirelings();
                 viewparams->bRedrawGameUI = true;
@@ -6586,7 +6674,7 @@
                 memset(pParty->pHirelings, 0, 0x4Cu);
               if ( pParty->pHirelings[1].uProfession == pValue )
                 memset(&pParty->pHirelings[1], 0, 0x4Cu);
-              pParty->field_709 = 0;
+              pParty->hirelingScrollPosition = 0;
               pParty->CountHirelings();
               break;
             case 243:
@@ -7309,6 +7397,7 @@
         case 1 : soundToPlay = (SoundID)109; break;
         case 2 : soundToPlay = (SoundID)110; break;
         case 3 : soundToPlay = (SoundID)44; break;
+        default: Error("Unexpected sound value");
       }
     }
     else
@@ -7320,6 +7409,7 @@
         case 1 : soundToPlay = (SoundID)106; break;
         case 2 : soundToPlay = (SoundID)107; break;
         case 3 : soundToPlay = (SoundID)45; break;
+        default: Error("Unexpected sound value");
       }
     }
     pAudioPlayer->PlaySound(soundToPlay, PID(OBJECT_Player,a4 + 80), 0, -1, 0, 0, 0, 0);
--- a/Player.h	Mon Oct 07 11:52:33 2013 +0200
+++ b/Player.h	Mon Oct 07 11:55:35 2013 +0200
@@ -592,8 +592,7 @@
   void SalesProcess(unsigned int inventory_idnx, int item_index, int _2devent_idx);//0x4BE2DD
   bool Recover(signed int a2);
   bool CanCastSpell(unsigned int uRequiredMana);
-  void PlaySoundBasedOnCondition(int currPlayerId);
-  void DrawPlayerBuffAnimBasedOnCondition(int currPlayerId);
+  void PlayAwardSound(int currPlayerId);
   void EquipBody(ITEM_EQUIP_TYPE uEquipType);
   bool HasUnderwaterSuitEquipped();
   bool HasItem(unsigned int uItemID, char a3);
@@ -603,6 +602,12 @@
   int CalculateMeleeDmgToEnemyWithWeapon( ItemGen * weapon, unsigned int uTargetActorID , bool addOneDice);
   bool WearsItemAnyWhere(int item_id);
   float GetArmorRecoveryMultiplierFromSkillLevel( unsigned char armour_skill_type, float param2, float param3, float param4, float param5 );
+  void SetSkillByEvent(unsigned __int16 Player::* skillToSet, unsigned __int16 skillValue, int currPlayerId);
+  void AddSkillByEvent( unsigned __int16 Player::* skillToSet, unsigned __int16 addSkillValue, int currPlayerId );
+  void PlayAwardSound_Anim(int currPlayerId);
+  void PlayAwardSound_Anim_Face(int currPlayerId, PlayerSpeech speech);
+  void PlayAwardSound_Anim97(int currPlayerId);
+  void PlayAwardSound_Anim97_Face(int currPlayerId, PlayerSpeech speech);
 
   bool IsWeak();
   bool IsDead();
--- a/Render.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/Render.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -8723,4 +8723,270 @@
       assert(false);
     break;
   }
+}
+
+//----- (00424EE0) --------------------------------------------------------
+int BuildingVerticesClipping(unsigned int uNumVertices)
+{
+  signed int previous_vertices_flag; // edi@1
+  double t; // st6@10
+  bool current_vertices_flag; // [sp+Ch] [bp-28h]@6
+  signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1
+  int pNextVertices;
+  //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910
+
+  memcpy(&array_50AC10[uNumVertices], array_50AC10, sizeof(array_50AC10[uNumVertices]));
+  depth_num_vertices = 0;
+  previous_vertices_flag = 0;
+  if ( array_50AC10[0].vWorldViewPosition.x <= pODMRenderParams->shading_dist_mist )
+    previous_vertices_flag = 1;//предыдущая грань меньше границы видимости
+  if ( (signed int)uNumVertices <= 0 )
+    return 0;
+  for ( uint i = 1; i <= uNumVertices; ++i )
+  {
+    current_vertices_flag = pODMRenderParams->shading_dist_mist >= array_50AC10[i].vWorldViewPosition.x;
+    if ( previous_vertices_flag != current_vertices_flag )//одна из граней за границей видимости
+    {
+      if ( current_vertices_flag )//текущая грань меньше границы видимости(предыдущая грань за пределами видимости)
+      {
+        //t = far_clip - v0.x / v1.x - v0.x    (формула получения точки пересечения отрезка с плоскостью)
+        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i - 1].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i - 1].vWorldViewPosition.x);
+        array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i - 1].vWorldViewPosition.y) * t + array_50AC10[i - 1].vWorldViewPosition.y;
+        array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i - 1].vWorldViewPosition.z) * t + array_50AC10[i - 1].vWorldViewPosition.z;
+        array_507D30[depth_num_vertices].u = (array_50AC10[i].u - array_50AC10[i - 1].u) * t + array_50AC10[i - 1].u;
+        array_507D30[depth_num_vertices].v = (array_50AC10[i].v - array_50AC10[i - 1].v) * t + array_50AC10[i - 1].v;
+      }
+      else//предыдущая грань меньше границы видимости(текущая грань вышла за пределы видимости)
+      {
+        //t = far_clip - v1.x / v0.x - v1.x
+        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i - 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x);
+        array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i - 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t + array_50AC10[i].vWorldViewPosition.y;
+        array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i - 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t + array_50AC10[i].vWorldViewPosition.z;
+        array_507D30[depth_num_vertices].u = (array_50AC10[i - 1].u - array_50AC10[i].u) * t + array_50AC10[i].u;
+        array_507D30[depth_num_vertices].v = (array_50AC10[i - 1].v - array_50AC10[i].v) * t + array_50AC10[i].v;
+      }
+      array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist;
+      array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist;
+      ++depth_num_vertices;
+    }
+    if ( current_vertices_flag )//оба в границе видимости
+    {
+      pNextVertices = depth_num_vertices++;
+      memcpy(&array_507D30[pNextVertices], &array_50AC10[i], 0x30);
+      //array_507D30[pNextVertices]._rhw = 1.0 / (array_50AC10[i].vWorldViewPosition.x + 0.0000001);
+      //array_507D30[pNextVertices].flt_2C = array_50AC10[i].flt_2C;
+    }
+    previous_vertices_flag = current_vertices_flag;
+  }
+  if ( depth_num_vertices < 3 )
+    return 0;
+  return depth_num_vertices;
+}
+
+//----- (0047840D) --------------------------------------------------------
+void Render::DrawBuildingsD3D()
+{
+  int v9; // ecx@8
+  Texture *pFaceTexture; // eax@10
+  unsigned int v16; // edi@22
+  int v27; // eax@57
+  int vertex_id; // eax@58
+  unsigned int v34; // eax@80
+  int v40; // [sp-4h] [bp-5Ch]@2
+  int v49; // [sp+2Ch] [bp-2Ch]@10
+  int v50; // [sp+30h] [bp-28h]@34
+  int v51; // [sp+34h] [bp-24h]@35
+  int v52; // [sp+38h] [bp-20h]@36
+  int v53; // [sp+3Ch] [bp-1Ch]@8
+  int uNumVertices; // [sp+4Ch] [bp-Ch]@34
+  int unused; // [sp+50h] [bp-8h]@3
+
+  if ( !pRenderer->pRenderD3D )
+  {
+    MessageBoxW(nullptr, L"D3D version of RenderBuildings called in software!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odbuild.cpp:73", 0);
+  }
+
+  unused = 0;
+  if ( (signed int)pOutdoor->uNumBModels > 0 )
+  {
+    for ( uint model_id = 0; model_id < pOutdoor->uNumBModels; model_id++ )
+    {
+      if ( IsBModelVisible(model_id, &unused) )
+      {
+        pOutdoor->pBModels[model_id].field_40 |= 1;
+        if ( pOutdoor->pBModels[model_id].uNumFaces > 0 )
+        {
+          for ( int face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; face_id++ )
+          {
+            if (!pOutdoor->pBModels[model_id].pFaces[face_id].Invisible())
+            {
+            v53 = 0;
+            array_77EC08[pODMRenderParams->uNumPolygons].flags = 0;
+            array_77EC08[pODMRenderParams->uNumPolygons].field_32 = 0;
+            v9 = pOutdoor->pBModels[model_id].pFaces[face_id].uTextureID;
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_TEXTURE_FRAME)
+              v9 = pTextureFrameTable->GetFrameTexture(v9, pEventTimer->uTotalGameTimeElapsed);
+            pFaceTexture = pBitmaps_LOD->GetTexture(v9);
+            array_77EC08[pODMRenderParams->uNumPolygons].pTexture = pFaceTexture;
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLUID)
+              array_77EC08[pODMRenderParams->uNumPolygons].flags |= 2;
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_DO_NOT_LIGHT )
+              HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4;
+            if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & 4 )
+              HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4;
+            else
+            {
+              if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & 0x20 )
+                HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 8;
+            }
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & 0x0800)
+              array_77EC08[pODMRenderParams->uNumPolygons].flags |= 0x2000;
+            else
+            {
+              if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_DONT_CACHE_TEXTURE)
+                HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 0x10u;
+            }
+            array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaU;
+            array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaV;
+            v16 = GetTickCount() >> 4;
+            if ( pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z && abs(pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z) >= 59082 )
+            {
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+            }
+            else
+            {
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+            }
+            if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x10 )
+              array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1;
+            else
+            {
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x20 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1;
+            }
+            v50 = 0;
+            v49 = 0;
+            uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices;
+            if ( pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices > 0 )
+            {
+              for ( uint vertex_id = 1; vertex_id <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; vertex_id++ )
+              {
+                array_73D150[vertex_id - 1].vWorldPosition.x = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].x;
+                array_73D150[vertex_id - 1].vWorldPosition.y = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].y;
+                array_73D150[vertex_id - 1].vWorldPosition.z = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].z;
+                array_73D150[vertex_id - 1].u = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureUIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureWidth);
+                array_73D150[vertex_id - 1].v = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureVIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureHeight);
+              }
+              for ( uint i = 1; i <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; i++ )
+              {
+                if ( pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[0]].z == array_73D150[i - 1].vWorldPosition.z )
+                  ++v53;
+                pGame->pIndoorCameraD3D->ViewTransform(&array_73D150[i - 1], 1);
+                if ( array_73D150[i - 1].vWorldViewPosition.x < 8.0 || array_73D150[i - 1].vWorldViewPosition.x > pODMRenderParams->shading_dist_mist )
+                {
+                  if ( array_73D150[i - 1].vWorldViewPosition.x >= 8.0 )
+                    v49 = 1;
+                  else
+                    v50 = 1;
+                }
+                else
+                  pGame->pIndoorCameraD3D->Project(&array_73D150[i - 1], 1, 0);
+              }
+            }
+            if ( v53 == pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices )
+              LOBYTE(array_77EC08[pODMRenderParams->uNumPolygons].field_32) |= 1;
+            array_77EC08[pODMRenderParams->uNumPolygons].pODMFace = &pOutdoor->pBModels[model_id].pFaces[face_id];
+            array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices;
+            array_77EC08[pODMRenderParams->uNumPolygons].field_59 = 5;
+            v51 = (unsigned __int64)(-pOutdoor->vSunlight.x * (signed __int64)pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.x) >> 16;
+            v53 = (unsigned __int64)(-pOutdoor->vSunlight.y * (signed __int64)pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.y) >> 16;
+            v52 = (unsigned __int64)(-pOutdoor->vSunlight.z * (signed __int64)pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z) >> 16;
+            array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 20 - (20 * (signed int)(v51 + v53 + v52) >> 16);
+            if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level < 0 )
+              array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 0;
+            if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level > 31 )
+              array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 31;
+            if ( pODMRenderParams->uNumPolygons >= 1999 + 5000)
+              return;
+            if ( ODMFace::IsBackfaceCulled(&pOutdoor->pBModels[model_id].pFaces[face_id], array_73D150, &array_77EC08[pODMRenderParams->uNumPolygons]) )
+            {
+              pOutdoor->pBModels[model_id].pFaces[face_id].bVisible = 1;
+              array_77EC08[pODMRenderParams->uNumPolygons].uBModelFaceID = face_id;
+              array_77EC08[pODMRenderParams->uNumPolygons].uBModelID = model_id;
+              v27 = 8 * (face_id | (model_id << 6));
+              LOBYTE(v27) = v27 | 6;
+              array_77EC08[pODMRenderParams->uNumPolygons].field_50 = v27;
+              for ( int vertex_id = 0; vertex_id < pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; ++vertex_id)
+              {
+                memcpy(&array_50AC10[vertex_id], &array_73D150[vertex_id], sizeof(array_50AC10[vertex_id]));
+                array_50AC10[vertex_id]._rhw = 1.0 / (array_73D150[vertex_id].vWorldViewPosition.x + 0.0000001);
+              }
+              static stru154 static_RenderBuildingsD3D_stru_73C834;
+              /*static bool __init_flag = false;
+              if (!__init_flag)
+              {
+                __init_flag = true;
+                static_RenderBuildingsD3D_byte_73C84C_init_flag |= 1u;
+                stru154::stru154(&static_RenderBuildingsD3D_stru_73C834);
+                atexit(loc_4789D4);
+              }*/
+
+              v40 = (int)&pOutdoor->pBModels[model_id].pFaces[face_id];
+              pGame->pLightmapBuilder->ApplyLights_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]);
+              pDecalBuilder->ApplyDecals_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]);
+              pGame->pLightmapBuilder->std__vector_000004_size = 0;
+              int v31 = 0;
+              if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
+              {
+                v31 = v50 ? 3 : v49 != 0 ? 5 : 0;
+                static_RenderBuildingsD3D_stru_73C834.GetFacePlaneAndClassify(&pOutdoor->pBModels[model_id].pFaces[face_id], &pOutdoor->pBModels[model_id].pVertices);
+                if ( pDecalBuilder->uNumDecals > 0 )
+                {
+                  v40 = -1;
+                  pDecalBuilder->ApplyDecals(31 - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level, 2, &static_RenderBuildingsD3D_stru_73C834,
+                                       pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices, array_50AC10, 0, (char)v31, -1);
+                }
+              }
+              if ( stru_F8AD28.uNumLightsApplied > 0 )
+                pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_RenderBuildingsD3D_stru_73C834, uNumVertices, array_50AC10, 0, (char)v31);
+              if ( v50 )
+              {
+                array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = sr_424CD7(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices);
+                uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices;
+                ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices);
+              }
+              if ( v49 )
+              {
+                array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = BuildingVerticesClipping(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices);
+                uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices;
+                ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices);
+              }
+              if ( uNumVertices )
+              {
+                if ( array_77EC08[pODMRenderParams->uNumPolygons].flags & 2 )
+                {
+                  if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x3C )
+                    v34 = pRenderer->pHDWaterBitmapIDs[0];
+                  else
+                    v34 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
+                  v40 = (int)pBitmaps_LOD->pHardwareTextures[v34];
+                }
+                else
+                  v40 = (int)pBitmaps_LOD->pHardwareTextures[v9];
+                pRenderer->DrawPolygon(uNumVertices, &array_77EC08[pODMRenderParams->uNumPolygons], &pOutdoor->pBModels[model_id].pFaces[face_id], (IDirect3DTexture2 *)v40);
+              }
+            }
+          }
+          }
+        }
+      }
+    }
+  }
+  return;
 }
\ No newline at end of file
--- a/Render.h	Mon Oct 07 11:52:33 2013 +0200
+++ b/Render.h	Mon Oct 07 11:55:35 2013 +0200
@@ -354,7 +354,7 @@
   void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16);
   int _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, unsigned __int16 *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7);
   void _4A6E7E(unsigned int a2, unsigned int a3, struct Texture *a4);
-  char DrawBuildingsD3D();
+  void DrawBuildingsD3D();
   //struct BSPModel *DrawBuildingsSW();
   //int OnOutdoorRedrawSW();
   void DrawSkyD3D();
--- a/UI/UiGame.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/UI/UiGame.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -187,9 +187,9 @@
         }
       }
     }
-    if ( (signed int)((char *)_this + (unsigned __int8)pParty->field_709) < v1 )
+    if ( (signed int)((char *)_this + pParty->hirelingScrollPosition) < v1 )
     {
-      sDialogue_SpeakingActorNPC_ID = -1 - (unsigned __int8)pParty->field_709 - (int)_this;
+      sDialogue_SpeakingActorNPC_ID = -1 - pParty->hirelingScrollPosition - (int)_this;
       pNPC = GetNewNPCData(sDialogue_SpeakingActorNPC_ID, &a2);
       if ( pNPC )
       {
@@ -2161,7 +2161,7 @@
       }
     }
 
-    for ( int i = (unsigned __int8)pParty->field_709; i < v22 && pNPC_limit_ID < 2; i++ )
+    for ( int i = pParty->hirelingScrollPosition; i < v22 && pNPC_limit_ID < 2; i++ )
     {
       if ( (unsigned __int8)pTmpBuf[i] >= 2 )
       {
--- a/mm7_2.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/mm7_2.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -2736,7 +2736,7 @@
 }
 
 //----- (00458244) --------------------------------------------------------
-int SkillToMastery( unsigned int skill_value )
+unsigned int SkillToMastery( unsigned int skill_value )
 {
   switch (skill_value & 0x1C0)
   {
@@ -2752,124 +2752,26 @@
 //----- (0045828B) --------------------------------------------------------
 unsigned int __fastcall GetSpellColor(signed int a1)
 {
-  unsigned __int16 v1; // dx@3
-  unsigned __int16 v2; // cx@6
-  unsigned __int16 v4; // [sp-4h] [bp-4h]@3
-
-  if ( a1 < 1 )
-  {
-    if ( a1 < 12 )
-    {
-      if ( a1 < 23 )
-      {
-        if ( a1 < 34 )
-        {
-          if ( a1 < 45 )
-          {
-            if ( a1 < 56 )
-            {
-              if ( a1 < 67 )
-              {
-                if ( a1 < 78 )
-                {
-                  if ( a1 < 89 )
-				  {
-					v4 = 0;
-					v1 = 0;
-					v2 = 0;
-					return TargetColor(v2, v1, v4);
-				  }
-                }
-				else
-				{
-LABEL_25:
-					if ( a1 < 89 )
-					{
-					  v4 = 155;
-					  v2 = 255;
-					  v1 = v2;
-					  return TargetColor(v2, v1, v4);
-					}
-				}
-                if ( a1 < 100 )
-                {
-                  v4 = 240;
-                  v2 = 192;
-				  v1 = v2;
-				  return TargetColor(v2, v1, v4);
-                }
-                v4 = 0;
-                v1 = 0;
-				v2 = 0;
-				return TargetColor(v2, v1, v4);
-              }
-LABEL_21:
-              if ( a1 < 78 )
-              {
-                v4 = 0;
-                v1 = 128;
-			    v2 = 255;
-			    return TargetColor(v2, v1, v4);
-              }
-              goto LABEL_25;
-            }
-LABEL_18:
-            if ( a1 < 67 )
-            {
-              v4 = 255;
-              v1 = 15;
-              v2 = 235;
-              return TargetColor(v2, v1, v4);
-            }
-            goto LABEL_21;
-          }
-LABEL_15:
-          if ( a1 < 56 )
-          {
-            v2 = 225;
-            v4 = v2;
-            v1 = v2;
-            return TargetColor(v2, v1, v4);
-          }
-          goto LABEL_18;
-        }
-LABEL_11:
-        if ( a1 < 45 )
-        {
-          v2 = 128;
-          v4 = v2;
-          v1 = v2;
-          return TargetColor(v2, v1, v4);
-        }
-        goto LABEL_15;
-      }
-LABEL_8:
-      if ( a1 < 34 )
-      {
-        v4 = 255;
-        v1 = 128;
-        v2 = 0;
-        return TargetColor(v2, v1, v4);
-      }
-      goto LABEL_11;
-    }
-  }
-  else
-  {
-    if ( a1 < 12 )
-    {
-      v4 = 0;
-      v1 = 85;
-      v2 = 255;
-      return TargetColor(v2, v1, v4);
-    }
-  }
-  if ( a1 >= 23 )
-    goto LABEL_8;
-  v4 = 255;
-  v1 = 212;
-  v2 = 150;
-  return TargetColor(v2, v1, v4);
+  if ( a1 == 0 )
+    return TargetColor(0, 0, 0);
+  if ( a1 < 12 )
+    return TargetColor(255, 85, 0);
+  if ( a1 < 23 )
+    return TargetColor(150, 212, 255);
+  if ( a1 < 34 )
+    return TargetColor(0, 128, 255);
+  if ( a1 < 45 )
+    return TargetColor(128, 128, 128);
+  if ( a1 < 56 )
+    return TargetColor(225, 225, 225);
+  if ( a1 < 67 )
+    return TargetColor(235, 15, 255);
+  if ( a1 < 78 )
+    return TargetColor(255, 128, 0);
+  if ( a1 < 89 )
+    return TargetColor(255, 255, 155);
+  if ( a1 < 100 )
+    return TargetColor(192, 192, 240);
 }
 
 //----- (004610AA) --------------------------------------------------------
@@ -2937,7 +2839,8 @@
     //{
       v3 = pActor->pMonsterInfo.uID;
       v17 = 0;
-      if ( v3 >= 115 && v3 <= 186 || v3 >= 232 && v3 <= 249 )
+      if ( pActor->pMonsterInfo.uID >= 115 && pActor->pMonsterInfo.uID <= 186
+        || pActor->pMonsterInfo.uID >= 232 && pActor->pMonsterInfo.uID <= 249 )
         v17 = 1;
       //v1 = 0;
       v4 = (v3 - 1) % 3;
@@ -4357,6 +4260,7 @@
 }
 
 bool new_sky = false;
+bool new_draw_object_dist = true;
 bool change_seasons = false;
 bool all_magic = true;
 bool wizard_eye = false;
@@ -4651,7 +4555,12 @@
   mipmapping_building_mm3 = GetPrivateProfileIntW(L"mipmapping", L"bld_mm3", 4096, pIniFilename);
   pODMRenderParams->shading_dist_shade     = GetPrivateProfileIntW(L"shading", L"dist_shade", 2048, pIniFilename);
   pODMRenderParams->shading_dist_shademist = GetPrivateProfileIntW(L"shading", L"dist_shademist", 4096, pIniFilename);
-  pODMRenderParams->shading_dist_mist      = GetPrivateProfileIntW(L"shading", L"dist_mist", 8192, pIniFilename);
+
+  int dist = 0x2000;
+  extern bool new_draw_object_dist;
+  if ( new_draw_object_dist )
+      dist = 0x6000;
+  pODMRenderParams->shading_dist_mist      = GetPrivateProfileIntW(L"shading", L"dist_mist", dist, pIniFilename);
 
   wchar_t pDefaultSkyTextureW[1024];
   GetPrivateProfileStringW(L"textures", L"sky", L"plansky1", pDefaultSkyTextureW, 0x10u, pIniFilename);
--- a/mm7_3.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/mm7_3.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -751,102 +751,102 @@
 //----- (0047050A) --------------------------------------------------------
 int stru141_actor_collision_object::_47050A(int dt)
 {
-  stru141_actor_collision_object *v2; // esi@1
+  //stru141_actor_collision_object *v2; // esi@1
   //signed int v3; // eax@1
   //int v4; // ecx@1
   //int v5; // edx@1
   //int v6; // edx@1
   int v7; // eax@1
-  int v8; // eax@3
+  //int v8; // eax@3
   signed int result; // eax@4
-  int v10; // eax@5
-  int v11; // eax@5
-  int v12; // ebx@5
-  int v13; // edx@5
-  int v14; // edi@5
-  int v15; // ecx@5
-  int v16; // eax@5
+  //int v10; // eax@5
+  //int v11; // eax@5
+  //int v12; // ebx@5
+  //int v13; // edx@5
+  //int v14; // edi@5
+  //int v15; // ecx@5
+  //int v16; // eax@5
   int v17; // eax@5
   int v18; // eax@7
-  int v19; // edx@9
-  int v20; // edi@9
+  //int v19; // edx@9
+  //int v20; // edi@9
   int v21; // eax@9
   int v22; // eax@11
-  int v23; // edx@13
-  int v24; // eax@13
-  int v25; // eax@14
-  int v26; // eax@16
-  int v27; // eax@17
-  int v28; // [sp+14h] [bp+8h]@5
-
-  v2 = this;
+  //int v23; // edx@13
+  //int v24; // eax@13
+  //int v25; // eax@14
+  //int v26; // eax@16
+  //int v27; // eax@17
+  //int v28; // [sp+14h] [bp+8h]@5
+
+  //v2 = this;
   int speed = 1 | integer_sqrt(this->velocity.z * this->velocity.z + this->velocity.y * this->velocity.y + this->velocity.x * this->velocity.x);
 
-  v2->direction.x = 65536 / speed * v2->velocity.x;
-  v2->direction.y = 65536 / speed * v2->velocity.y;
-  v2->direction.z = 65536 / speed * v2->velocity.z;
-
-  v2->speed = speed;
-  v2->inv_speed = 65536 / speed;
+  this->direction.x = 65536 / speed * this->velocity.x;
+  this->direction.y = 65536 / speed * this->velocity.y;
+  this->direction.z = 65536 / speed * this->velocity.z;
+
+  this->speed = speed;
+  this->inv_speed = 65536 / speed;
 
   if (dt)
     v7 = dt;
   else
     v7 = pEventTimer->dt_in_some_format;
 
-  v8 = fixpoint_mul(v7, speed) - v2->field_70; // speed * dt - something
-  v2->field_6C = v8;
-  if ( v8 > 0 )
-  {
-    v10 = fixpoint_mul(v8, v2->direction.x) + v2->normal.x;
-    v2->field_4C = v10;
-    v2->normal2.x = v10;
-    v11 = fixpoint_mul(v2->field_6C, v2->direction.y) + v2->normal.y;
-    v2->field_50 = v11;
-    v2->normal2.y = v11;
-    v2->normal2.z = fixpoint_mul(v2->field_6C, v2->direction.z) + v2->normal.z;
-    v12 = v2->position.z;
-    v13 = v2->normal.x;
-    v14 = v2->normal2.x;
-    v15 = v2->prolly_normal_d;
-    v16 = v12 + fixpoint_mul(v2->field_6C, v2->direction.z);
-    v28 = v16;
-    v2->field_54 = v16;
-    v17 = v13;
-    if ( v13 >= v14 )
-      v17 = v14;
-    v2->sMaxX = v17 - v15;
-    v18 = v15 + v13;
-    if ( v13 <= v14 )
-      v18 = v15 + v14;
-    v19 = v2->normal.y;
-    v20 = v2->normal2.y;
-    v2->sMinX = v18;
-    v21 = v19;
-    if ( v19 >= v20 )
-      v21 = v20;
-    v2->sMaxY = v21 - v15;
-    v22 = v15 + v19;
-    if ( v19 <= v20 )
-      v22 = v20 + v15;
-    v23 = v2->normal2.z;
-    v2->sMinY = v22;
-    v24 = v2->normal.z;
-    if ( v24 >= v23 )
-      v25 = v23 - v15;
+  //v8 = fixpoint_mul(v7, speed) - this->field_70; // speed * dt - something
+  this->field_6C = fixpoint_mul(v7, speed) - this->field_70;
+  if ( this->field_6C > 0 )
+  {
+    //v10 = fixpoint_mul(v8, this->direction.x) + this->normal.x;
+    this->field_4C = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x;
+    this->normal2.x = fixpoint_mul(this->field_6C, this->direction.x) + this->normal.x;
+    //v11 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y;
+    this->field_50 = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y;
+    this->normal2.y = fixpoint_mul(this->field_6C, this->direction.y) + this->normal.y;
+    this->normal2.z = fixpoint_mul(this->field_6C, this->direction.z) + this->normal.z;
+    //v12 = this->position.z;
+    //v13 = this->normal.x;
+    //v14 = this->normal2.x;
+    //v15 = this->prolly_normal_d;
+    //v16 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z);
+    //v28 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z);
+    this->field_54 = this->position.z + fixpoint_mul(this->field_6C, this->direction.z);
+    v17 = this->normal.x;
+    if ( v17 >= this->normal2.x )
+      v17 = this->normal2.x;
+    this->sMaxX = v17 - this->prolly_normal_d;
+    v18 = this->prolly_normal_d + this->normal.x;
+    if ( this->normal.x <= this->normal2.x )
+      v18 = this->prolly_normal_d + this->normal2.x;
+    //v19 = this->normal.y;
+    //v20 = this->normal2.y;
+    this->sMinX = v18;
+    v21 = this->normal.y;
+    if ( v21 >= this->normal2.y )
+      v21 = this->normal2.y;
+    this->sMaxY = v21 - this->prolly_normal_d;
+    v22 = this->prolly_normal_d + this->normal.y;
+    if ( this->normal.y <= this->normal2.y )
+      v22 = this->normal2.y + this->prolly_normal_d;
+    //v23 = this->normal2.z;
+    this->sMinY = v22;
+    //v24 = this->normal.z;
+    if ( this->normal.z >= this->normal2.z )
+      this->sMaxZ = this->normal2.z - this->prolly_normal_d;
     else
-      v25 = v24 - v15;
-    v2->sMaxZ = v25;
-    v26 = v2->field_8_radius;
-    if ( v12 <= v28 )
-      v27 = v28 + v26;
+      this->sMaxZ = this->normal.z - this->prolly_normal_d;
+    //this->sMaxZ = v25;
+    //v26 = this->field_8_radius;
+    if ( this->position.z <= this->position.z + fixpoint_mul(this->field_6C, this->direction.z) )
+      this->sMinZ = (this->position.z + fixpoint_mul(this->field_6C, this->direction.z)) + this->field_8_radius;
     else
-      v27 = v12 + v26;
-    v2->uFaceID = 0;
-    v2->field_80 = -1;
-    v2->field_88 = -1;
-    v2->sMinZ = v27;
-    v2->field_7C = 0xFFFFFFu;
+      this->sMinZ = this->position.z + this->field_8_radius;
+    this->uFaceID = 0;
+    this->field_80 = -1;
+    this->field_88 = -1;
+    //this->sMinZ = v27;
+    this->field_7C = 0xFFFFFFu;
     result = 0;
   }
   else
@@ -4282,405 +4282,8 @@
   return v16;
 }
 
-//----- (0047840D) --------------------------------------------------------
-char Render::DrawBuildingsD3D()
-{
-  //IndoorCameraD3D *v0; // eax@3
-  char result; // al@3
-  BSPModel *v2; // ebx@4
-  int v3; // eax@6
-  ODMFace *pFace; // esi@6
-  //Vec3_int_ *v5; // ecx@8
-  int v6; // eax@8
-  struct Polygon *v7; // ebx@8
-  //LightmapBuilder *v8; // eax@8
-  int v9; // ecx@8
-  //char v10; // zf@8
-  Texture *pFaceTexture; // eax@10
-  signed int v12; // ecx@10
-  //unsigned int v13; // eax@14
-  //unsigned int v14; // eax@18
-  unsigned int v15; // eax@22
-  unsigned int v16; // edi@22
-  int v17; // eax@24
-  int v18; // edi@34
-  RenderVertexSoft *v19; // eax@35
-  unsigned short *v20; // ecx@35
-  unsigned short *v20b; // ecx@35
-  unsigned short *v20c; // ecx@35
-  Vec3_int_ *v21; // edx@36
-  int v22; // edx@36
-  RenderVertexSoft *v23; // edi@37
-  int v24; // eax@50
-  int v25; // ecx@55
-  int v26; // eax@57
-  int v27; // eax@57
-  int v28; // eax@58
-  //int v29; // edx@58
-  //double v30; // st7@59
-  //LightmapBuilder *v31; // edi@63
-  signed int v32; // eax@73
-  int v33; // eax@78
-  unsigned int v34; // eax@80
-  std::string v35; // [sp-18h] [bp-70h]@2
-  int v36; // [sp-14h] [bp-6Ch]@69
-  RenderVertexSoft *v37; // [sp-10h] [bp-68h]@69
-  int v38; // [sp-Ch] [bp-64h]@69
-  //LightmapBuilder *v39; // [sp-8h] [bp-60h]@2
-  int v40; // [sp-4h] [bp-5Ch]@2
-  //std::string *v41; // [sp+Ch] [bp-4Ch]@2
-  int v41b;
-  int v42; // [sp+10h] [bp-48h]@6
-  LightmapBuilder *pLightmapBuilder; // [sp+14h] [bp-44h]@8
-  float v44; // [sp+18h] [bp-40h]@10
-  float v45; // [sp+1Ch] [bp-3Ch]@10
-  ODMFace *v46; // [sp+20h] [bp-38h]@6
-  //IndoorCameraD3D *v47; // [sp+24h] [bp-34h]@3
-  //unsigned int v48; // [sp+28h] [bp-30h]@8
-  int v49; // [sp+2Ch] [bp-2Ch]@10
-  int v50; // [sp+30h] [bp-28h]@34
-  int v51; // [sp+34h] [bp-24h]@35
-  int v52; // [sp+38h] [bp-20h]@36
-  int v53; // [sp+3Ch] [bp-1Ch]@8
-  Vec3_int_ *v54; // [sp+40h] [bp-18h]@6
-  int a1; // [sp+44h] [bp-14h]@3
-  BSPModel *v56; // [sp+48h] [bp-10h]@4
-  int uNumVertices; // [sp+4Ch] [bp-Ch]@34
-  int unused; // [sp+50h] [bp-8h]@3
-  int a3; // [sp+57h] [bp-1h]@2
-
-  if ( !pRenderer->pRenderD3D )
-  {
-    MessageBoxW(nullptr, L"D3D version of RenderBuildings called in software!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odbuild.cpp:73", 0);
-  }
-
-  unused = 0;
-  a1 = 0;
-  result = LOBYTE(pOutdoor->pBModels);
-  v41b = pOutdoor->uNumBModels;
-  if ( (signed int)pOutdoor->uNumBModels > 0 )
-  {
-    v2 = pOutdoor->pBModels;
-    v56 = pOutdoor->pBModels;
-    while ( 1 )
-    {
-      if ( IsBModelVisible(a1, &unused) )
-      {
-		v2->field_40 |= 1u;
-        v3 = v2->uNumFaces;
-        pFace = v2->pFaces;
-        v54 = 0;
-        v46 = pFace;
-        v42 = v3;
-        if ( v3 > 0 )
-          break;
-      }
-LABEL_86:
-      ++a1;
-      ++v2;// += 47;
-      result = a1;
-      v56 = v2;
-      if ( a1 >= v41b )
-        return result;
-    }
-    while ( 1 )
-    {
-      if (pFace->Invisible())
-        goto LABEL_85;
-      //v5 = (int)*(v2 - 1);
-      v6 = pFace->pVertexIDs[0];
-      v53 = 0;
-      v7 = &array_77EC08[pODMRenderParams->uNumPolygons];
-      v7->flags = 0;
-      v7->field_32 = 0;
-      pLightmapBuilder = (LightmapBuilder *)v2->pVertices.pVertices[v6].z;
-      v9 = pFace->uTextureID;
-      if (pFace->uAttributes & FACE_TEXTURE_FRAME)
-      {
-        v9 = pTextureFrameTable->GetFrameTexture(v9, pEventTimer->uTotalGameTimeElapsed);
-      }
-      pFaceTexture = pBitmaps_LOD->GetTexture(v9);
-      v7->pTexture = pFaceTexture;
-      v12 = pFaceTexture->uTextureWidth;
-      v49 = v12;
-      v49 = pFaceTexture->uTextureHeight;
-      v45 = 1.0 / (double)v12;
-      v44 = 1.0 / (double)v49;
-      if (pFace->uAttributes & FACE_FLUID)
-        *(int *)&v7->flags |= 2u;
-      if (pFace->uAttributes & FACE_DO_NOT_LIGHT )
-        HIBYTE(v7->flags) |= 4u;
-      if ( pFace->uAttributes & 4 )
-      {
-        HIBYTE(v7->flags) |= 4u;
-      }
-      else
-      {
-        if ( pFace->uAttributes & 0x20 )
-          HIBYTE(v7->flags) |= 8u;
-      }
-      if (pFace->uAttributes & 0x0800)
-      {
-        *(int *)&v7->flags |= 0x2000u;
-      }
-      else
-      {
-        if (pFace->uAttributes & FACE_DONT_CACHE_TEXTURE)
-          HIBYTE(v7->flags) |= 0x10u;
-      }
-      v15 = GetTickCount();
-      v7->sTextureDeltaU = pFace->sTextureDeltaU;
-      v7->sTextureDeltaV = pFace->sTextureDeltaV;
-      v16 = v15 >> 4;
-      if ( pFace->pFacePlane.vNormal.z && (v40 = pFace->pFacePlane.vNormal.z, abs(v40) >= 59082) )
-      {
-        v17 = *(int *)&v7->flags;
-        if ( BYTE1(v17) & 4 )
-          goto LABEL_29;
-        if ( BYTE1(v17) & 8 )
-        {
-LABEL_26:
-          v7->sTextureDeltaV -= v16 & v7->pTexture->uHeightMinus1;
-          goto LABEL_30;
-        }
-      }
-      else
-      {
-        v17 = *(int *)&v7->flags;
-        if ( BYTE1(v17) & 4 )
-          goto LABEL_26;
-        if ( BYTE1(v17) & 8 )
-        {
-LABEL_29:
-          v7->sTextureDeltaV += v16 & v7->pTexture->uHeightMinus1;
-          goto LABEL_30;
-        }
-      }
-LABEL_30:
-      if ( BYTE1(v17) & 0x10 )
-      {
-        v7->sTextureDeltaU -= v16 & v7->pTexture->uWidthMinus1;
-      }
-      else
-      {
-        if ( BYTE1(v17) & 0x20 )
-          v7->sTextureDeltaU += v16 & v7->pTexture->uWidthMinus1;
-      }
-      v18 = pFace->uNumVertices;
-      v50 = 0;
-      v49 = 0;
-      uNumVertices = v18;
-      if ( v18 > 0 )
-      {
-        //v19 = (char *)&array_73D150[0].vWorldPosition.z;
-        //v20 = (char *)pFace->pTextureUIDs;
-		v19 = array_73D150;
-        v20 = pFace->pTextureUIDs;
-		v20b = pFace->pVertexIDs;
-		v20c = pFace->pTextureVIDs;
-        v51 = v18;
-        do
-        {
-/*          v21 = &(*(v56 - 1))[*((short *)v20 - 20)];
-          *((float *)v19 - 2) = (double)v21->x;
-          *((float *)v19 - 1) = (double)v21->y;
-          *(float *)v19 = (double)v21->z;
-          v19 += 48;
-          v52 = v7->sTextureDeltaU + *(short *)v20;
-          *((float *)v19 - 5) = (double)v52 * v45;
-          v22 = v7->sTextureDeltaV + *((short *)v20 + 20);
-          v20 += 2;
-          v10 = v51-- == 1;
-          v52 = v22;
-          *((float *)v19 - 4) = (double)v22 * v44;*/
-          
-		  //v21 = (BSPVertexBuffer *)(*((_DWORD *)v56 - 1) + 12 * *(v20 - 20));
-		  v21 = &v56->pVertices.pVertices[*v20b];
-          //*((float *)v19 - 2) = (double)v21->x;
-          //*((float *)v19 - 1) = (double)v21->y;
-		  v19->vWorldPosition.x = (double)v21->x;
-		  v19->vWorldPosition.y = (double)v21->y;
-          v19->vWorldPosition.z = (double)v21->z;
-          ++v19;
-          v52 = v7->sTextureDeltaU + (signed __int16)*v20;
-          //*((float *)v19 - 5) = (double)v52 * v45;
-		  (v19-1)->u = (double)v52 * v45;
-          v22 = v7->sTextureDeltaV + (signed __int16)*v20c;
-          ++v20;
-		  ++v20b;
-		  ++v20c;
-          v52 = v22;
-          //*((float *)v19 - 4) = (double)v22 * v44;
-		  (v19-1)->v = (double)v22 * v44;
-        }
-        while ( !(v51-- == 1) );
-        //v23 = (char *)&array_73D150[0].vWorldViewPosition;
-		v23 = array_73D150;
-        v51 = uNumVertices;
-        *(float *)&pLightmapBuilder = (double)(signed int)pLightmapBuilder;
-        do
-        {
-          //if ( *(float *)&pLightmapBuilder == *((float *)v23 - 1) )
-		  if ( *(float *)&pLightmapBuilder == v23->vWorldPosition.z )
-            ++v53;
-          //v47->ViewTransform((RenderVertexSoft *)(v23 - 12), 1u);
-		  pGame->pIndoorCameraD3D->ViewTransform(v23, 1u);
-		  if ( v23->vWorldViewPosition.x < 8.0 || (double)pODMRenderParams->shading_dist_mist < v23->vWorldViewPosition.x )
-          {
-            if ( v23->vWorldViewPosition.x >= 8.0 )
-              v49 = 1;
-            else
-              v50 = 1;
-          }
-          else
-          {
-            pGame->pIndoorCameraD3D->Project(v23, 1u, 0);
-          }
-          ++v23;// += 48;
-          --v51;
-        }
-        while ( v51 );
-        v18 = uNumVertices;
-      }
-      if ( v53 == v18 )
-        LOBYTE(v7->field_32) |= 1u;
-      v24 = pOutdoor->vSunlight.x;
-      v7->pODMFace = pFace;
-      v7->uNumVertices = v18;
-      v7->field_59 = 5;
-      pLightmapBuilder = (LightmapBuilder *)-v24;
-      v51 = pFace->pFacePlane.vNormal.x;
-      v51 = (unsigned __int64)(-v24 * (signed __int64)v51) >> 16;
-      v53 = pFace->pFacePlane.vNormal.y;
-      pLightmapBuilder = (LightmapBuilder *)-pOutdoor->vSunlight.y;
-      v53 = (unsigned __int64)(-pOutdoor->vSunlight.y * (signed __int64)v53) >> 16;
-      v52 = pFace->pFacePlane.vNormal.z;
-      v52 = (unsigned __int64)(-pOutdoor->vSunlight.z * (signed __int64)v52) >> 16;
-      pLightmapBuilder = (LightmapBuilder *)(v51 + v53 + v52);
-      v51 = 20 * (int)pLightmapBuilder;
-      result = 20 - (20 * (signed int)pLightmapBuilder >> 16);
-      v7->dimming_level = result;
-      if ( result < 0 )
-        v7->dimming_level = 0;
-      if ( v7->dimming_level > 31 )
-        v7->dimming_level = 31;
-      if ( pODMRenderParams->uNumPolygons >= 1999 + 5000)
-        return result;
-      ++pODMRenderParams->uNumPolygons;
-      ++pODMRenderParams->field_44;
-      if ( ODMFace::IsBackfaceCulled(pFace, array_73D150, v7) )
-      {
-        LOBYTE(v25) = (char)v54;
-        v26 = a1;
-        pFace->bVisible = 1;
-        v7->uBModelFaceID = v25;
-        LOWORD(v25) = (unsigned __int8)v25;
-        v7->uBModelID = v26;
-        v27 = 8 * (v25 | (v26 << 6));
-        LOBYTE(v27) = v27 | 6;
-        v7->field_50 = v27;
-
-        for (v28 = 0; v28 < v18; ++v28)
-        {
-            memcpy(&array_50AC10[v28], &array_73D150[v28], sizeof(array_50AC10[v28]));
-            array_50AC10[v28]._rhw = 1.0 / (array_73D150[v28].vWorldViewPosition.x + 0.0000001);
-
-          pFace = v46;
-        }
-
-        static stru154 static_RenderBuildingsD3D_stru_73C834;
-        /*static bool __init_flag = false;
-        if (!__init_flag)
-        {
-          __init_flag = true;
-
-          static_RenderBuildingsD3D_byte_73C84C_init_flag |= 1u;
-          stru154::stru154(&static_RenderBuildingsD3D_stru_73C834);
-          atexit(loc_4789D4);
-        }*/
-
-        v40 = (int)pFace;
-        pGame->pLightmapBuilder->ApplyLights_OutdoorFace(pFace);
-        pDecalBuilder->ApplyDecals_OutdoorFace(pFace);
-        pGame->pLightmapBuilder->std__vector_000004_size = 0;
-
-        int v31 = 0;
-        if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
-        {
-          v31 = v50 ? 3 : v49 != 0 ? 5 : 0;
-		  static_RenderBuildingsD3D_stru_73C834.GetFacePlaneAndClassify(pFace, &v56->pVertices);
-          if ( pDecalBuilder->uNumDecals > 0 )
-          {
-            v40 = -1;
-            v38 = 0;
-            v37 = array_50AC10;
-            v36 = uNumVertices;
-            pDecalBuilder->ApplyDecals(31 - v7->dimming_level,
-              2,
-              &static_RenderBuildingsD3D_stru_73C834,
-              uNumVertices,
-              array_50AC10,
-              0,
-              (char)v31,
-              -1);
-          }
-        }
-        if ( stru_F8AD28.uNumLightsApplied > 0 )
-          pGame->pLightmapBuilder->ApplyLights(
-            &stru_F8AD28,
-            &static_RenderBuildingsD3D_stru_73C834,
-            uNumVertices,
-            array_50AC10,
-            0,
-            (char)v31);
-        if ( v50 )
-        {
-          v32 = sr_424CD7(uNumVertices);
-          goto LABEL_76;
-        }
-        if ( v49 )
-        {
-          v32 = sr_424EE0_MakeFanFromTriangle(uNumVertices);
-LABEL_76:
-          v7->uNumVertices = v32;
-          uNumVertices = v32;
-          ODM_Project(v32);
-        }
-        if ( uNumVertices )
-        {
-          v33 = *(int *)&v7->flags;
-          if ( v33 & 2 )
-          {
-            if ( BYTE1(v33) & 0x3C )
-              v34 = pRenderer->pHDWaterBitmapIDs[0];
-            else
-              v34 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
-            v40 = (int)pBitmaps_LOD->pHardwareTextures[v34];
-          }
-          else
-          {
-            v40 = (int)pBitmaps_LOD->pHardwareTextures[v9];
-          }
-          pRenderer->DrawPolygon(uNumVertices, v7, pFace, (IDirect3DTexture2 *)v40);
-        }
-        goto LABEL_85;
-      }
-      --pODMRenderParams->uNumPolygons;
-      --pODMRenderParams->field_44;
-LABEL_85:
-      v54 = (Vec3_int_ *)((char *)v54 + 1);
-      v2 = v56;
-      ++pFace;
-      v46 = pFace;
-      if ( (signed int)v54 >= (signed int)v42 )
-        goto LABEL_86;
-    }
-  }
-  return result;
-}
 // 73C84C: using guessed type char static_RenderBuildingsD3D_byte_73C84C_init_flag;
 
-
 //----- (00479089) --------------------------------------------------------
 bool __fastcall IsBModelVisible(unsigned int uModelID, int *reachable)
 {
@@ -5297,10 +4900,13 @@
   int v35; // [sp+148h] [bp-1Ch]@4
   int screen_center_x; // [sp+14Ch] [bp-18h]@2
   int v37; // [sp+154h] [bp-10h]@8
-  int v38; // [sp+158h] [bp-Ch]@1
+  int pViewportBR_Y; // [sp+158h] [bp-Ch]@1
   int v39; // [sp+15Ch] [bp-8h]@4
   //int v40; // [sp+160h] [bp-4h]@7
-  
+
+//Хотя сами двухмерные изображения основаны на системе координат XY, накладываются  текстуры  на объект, основанный на
+//осях координат U (горизонталь) и V (вертикаль), обхватывающих поверхность объекта.
+
   extern bool new_sky;
   if (new_sky)
   {
@@ -5310,7 +4916,7 @@
 
   v30 = ((double)(pODMRenderParams->int_fov_rad * pGame->pIndoorCameraD3D->vPartyPos.z)
         / ((double)pODMRenderParams->int_fov_rad + 8192.0) + pViewport->uScreenCenterY);//184 изменяется при подъёме на высоту
-  v38 = pViewport->uScreenCenterY - pODMRenderParams->int_fov_rad /
+  pViewportBR_Y = pViewport->uScreenCenterY - pODMRenderParams->int_fov_rad /
        (pODMRenderParams->shading_dist_mist *  cos(pGame->pIndoorCameraD3D->sRotationX * 0.003066406352445483) + 0.0000001000000011686097) *
        (pODMRenderParams->shading_dist_mist * -sin(pGame->pIndoorCameraD3D->sRotationX * 0.003066406352445483) - pGame->pIndoorCameraD3D->vPartyPos.z);//61 / 184 / 310 изменяется при наклоне камеры
 
@@ -5335,7 +4941,7 @@
   pSkyPolygon.sTextureDeltaU = 224 * pMiscTimer->uTotalGameTimeElapsed;//60928
   pSkyPolygon.sTextureDeltaV = 224 * pMiscTimer->uTotalGameTimeElapsed;
   
-  //sky position(положение неба)----------------------------------------------
+  //sky wiew position(положение неба)------------------------------------------
   //                X
   // 0._____________________________.3
   //  |8,8                    468,8 |
@@ -5343,7 +4949,7 @@
   //  |                             |
   // Y|                             |
   //  |                             |
-  //  |8,?                    468,? |
+  //  |8,351                468,351 |
   // 1._____________________________.2
   // 
 
@@ -5351,10 +4957,10 @@
   array_50AC10[0].vWorldViewProjY = pViewport->uViewportTL_Y;//8
 
   array_50AC10[1].vWorldViewProjX = pViewport->uViewportTL_X;//8
-  array_50AC10[1].vWorldViewProjY = v38;//61 / 184 / 310
+  array_50AC10[1].vWorldViewProjY = pViewportBR_Y;//61 / 184 / 310
 
   array_50AC10[2].vWorldViewProjX = pViewport->uViewportBR_X;//468
-  array_50AC10[2].vWorldViewProjY = v38;//61 / 184 / 310
+  array_50AC10[2].vWorldViewProjY = pViewportBR_Y;//61 / 184 / 310
 
   array_50AC10[3].vWorldViewProjX = pViewport->uViewportBR_X;//468
   array_50AC10[3].vWorldViewProjY = pViewport->uViewportTL_Y;//8
@@ -5386,9 +4992,9 @@
   v33 = 65536 / (signed int)(screen_center_x / tan(0.6457717418670654) + 0.5);//360 : (расстояние от экрана до камеры в пикселях) = 214
   //--------------------------------------------------------------------------
 
-  for (uint i = 0; i < pSkyPolygon.uNumVertices; ++i)
-  {
-    v29 = floorf(array_50AC10[i].vWorldViewProjY + 0.5f);//8
+  for ( uint vertex_id = 0; vertex_id < pSkyPolygon.uNumVertices; ++vertex_id )
+  {
+    v29 = floorf(array_50AC10[vertex_id].vWorldViewProjY + 0.5f);//8
     v39 = (unsigned __int64)(pSkyPolygon.ptr_38->field_14 * v33 * (v30 - v29)) / 65536;//0
     v8 = v39 + pSkyPolygon.ptr_38->field_C;//0
 
@@ -5404,11 +5010,11 @@
       v39 = 0;
     }
     //v11 = (signed __int64)array_50AC10[i].vWorldViewProjX;
-    v38 = v10;
+    pViewportBR_Y = v10;
     //v12 = array_50AC10[i].vWorldViewProjY - 1.0;
-    v13 = v33 * (pViewport->uScreenCenterX - (signed __int64)array_50AC10[i].vWorldViewProjX);
+    v13 = v33 * (pViewport->uScreenCenterX - (signed __int64)array_50AC10[vertex_id].vWorldViewProjX);
     v34 = -pSkyPolygon.field_24;
-    v32 = (signed __int64)array_50AC10[i].vWorldViewProjY - 1.0;
+    v32 = (signed __int64)array_50AC10[vertex_id].vWorldViewProjY - 1.0;
     v14 = v33 * (v30 - v32);
 
     while ( 1 )
@@ -5422,7 +5028,7 @@
         v14 += v33;
         v10 = pSkyPolygon.v_18.x + v16;
         v39 = pSkyPolygon.v_18.x + v16;
-        v38 = pSkyPolygon.v_18.x + v16;
+        pViewportBR_Y = pSkyPolygon.v_18.x + v16;
         break;
       }
       v37 = abs(v34 >> 14);//2048
@@ -5438,42 +5044,243 @@
       v14 += v33;
       v10 = pSkyPolygon.v_18.x + v16;
       v39 = pSkyPolygon.v_18.x + v16;
-      v38 = pSkyPolygon.v_18.x + v16;
+      pViewportBR_Y = pSkyPolygon.v_18.x + v16;
       break;
     }
 
-    pShading = fixpoint_div(v34, v38);
+    pShading = fixpoint_div(v34, pViewportBR_Y);//53570690 = -33554432 / -41049
     if ( pShading < 0 )
       pShading = pODMRenderParams->shading_dist_mist;
-
+	int a = ((unsigned __int64)(pSkyPolygon.ptr_38->field_10 * v13) >> 16);//16316
     v37 += ((unsigned __int64)(pSkyPolygon.ptr_38->field_10 * v13) >> 16);
+	int b = ((unsigned __int64)(pSkyPolygon.ptr_38->field_1C * v13) >> 16);
     screen_center_x += ((unsigned __int64)(pSkyPolygon.ptr_38->field_1C * v13) >> 16);
-    v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + fixpoint_mul(v37, pShading) / 8;
+    v35 = 224 * pMiscTimer->uTotalGameTimeElapsed + fixpoint_mul(v37, pShading) / 8;// Медленно вращаем небесный купол
     screen_center_x = 224 * pMiscTimer->uTotalGameTimeElapsed + fixpoint_mul(screen_center_x, pShading) / 8;
 
-    //array_50AC10[i].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist;
-    //array_50AC10[i].vWorldPosition.x = v36 / (pSky.pTexture->uTextureHeight * 65536.0);
-    //array_50AC10[i].vWorldPosition.y = 1.0 / (pODMRenderParams->shading_dist_mist >> 16);
-    //array_50AC10[i].vWorldPosition.z = v35 / (pSky.pTexture->uTextureWidth * 65536.0);
-    //array_50AC10[i]._rhw = 1.0f / (pShading >> 16);
-    //array_50AC10[i].u = (double)v35 / (65536.0 * pSkyPolygon.pTexture->uTextureWidth);
-    //array_50AC10[i].v = (double)screen_center_x / (65536.0 * pSkyPolygon.pTexture->uTextureHeight);
+    array_50AC10[vertex_id].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist;
+    //array_50AC10[vertex_id].vWorldPosition.x = v36 / (pSkyPolygon.pTexture->uTextureHeight * 65536.0);
+    //array_50AC10[vertex_id].vWorldPosition.y = 1.0 / (pODMRenderParams->shading_dist_mist >> 16);
+    //array_50AC10[vertex_id].vWorldPosition.z = v35 / (pSkyPolygon.pTexture->uTextureWidth * 65536.0);
+    //array_50AC10[vertex_id]._rhw = 1.0f / (pShading >> 16);//1.0 / (array_50AC10[vertex_id].vWorldViewPosition.x + 0.0000001);
+    //array_50AC10[vertex_id].u = (double)v35 / (65536.0 * pSkyPolygon.pTexture->uTextureWidth);//t - pParty->sRotationY / 1024.0f
+    //array_50AC10[vertex_id].v = (double)screen_center_x / (65536.0 * pSkyPolygon.pTexture->uTextureHeight);
   //-----------------------------------------------------------------------------------------
 
-    array_50AC10[i]._rhw = 1.0f;
+    array_50AC10[vertex_id]._rhw = 1.0f;
   }
   //if ( i  == _this.uNumVertices - 1 )
   //{
     pRenderer->DrawSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[pSkyPolygon.uTileBitmapID]);
 
-    array_50AC10[0].vWorldViewProjY = v38;
+    array_50AC10[0].vWorldViewProjY = pViewportBR_Y;
     array_50AC10[1].vWorldViewProjY = array_50AC10[1].vWorldViewProjY + 30.0;
     array_50AC10[2].vWorldViewProjY = array_50AC10[2].vWorldViewProjY + 30.0;
-    array_50AC10[3].vWorldViewProjY = v38;
+    array_50AC10[3].vWorldViewProjY = pViewportBR_Y;
 
     pRenderer->DrawSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[pSkyPolygon.uTileBitmapID]);
   //}
 }
+/*void Render::DrawSkyD3D()
+{
+  int v0; // esi@2
+  int v1; // eax@2
+  double v2; // st7@2
+  double v3; // st6@2
+  double v4; // st5@2
+  double v5; // st4@2
+  double v6; // st7@2
+  char *v7; // esi@3
+  int v8; // eax@4
+  int v9; // eax@4
+  int v10; // ebx@4
+  signed __int64 v11; // qax@6
+  double v12; // st7@6
+  int v13; // edi@6
+  int v14; // ecx@6
+  int v15; // eax@8
+  int v16; // eax@12
+  signed __int64 v17; // qtt@13
+  signed int v18; // ecx@13
+  Texture *v19; // eax@15
+  double v20; // st6@15
+  double v21; // st7@15
+  double v22; // st6@15
+  unsigned __int8 v23; // sf@15
+  unsigned __int8 v24; // of@15
+  struct Polygon pSkyPolygon; // [sp+14h] [bp-150h]@1
+  double v26; // [sp+120h] [bp-44h]@4
+  float v27; // [sp+128h] [bp-3Ch]@4
+  float v28; // [sp+12Ch] [bp-38h]@2
+  int v29; // [sp+130h] [bp-34h]@4
+  int v30; // [sp+134h] [bp-30h]@1
+  int v31; // [sp+138h] [bp-2Ch]@2
+  int v32; // [sp+13Ch] [bp-28h]@6
+  int v33; // [sp+140h] [bp-24h]@2
+  signed __int64 v34; // [sp+144h] [bp-20h]@1
+  int v35; // [sp+148h] [bp-1Ch]@4
+  double v36; // [sp+14Ch] [bp-18h]@2
+  int v37; // [sp+154h] [bp-10h]@8
+  int v38; // [sp+158h] [bp-Ch]@1
+  int v39; // [sp+15Ch] [bp-8h]@4
+  int v40; // [sp+160h] [bp-4h]@7
+
+  v30 = (signed __int64)((double)(pODMRenderParams->int_fov_rad * pGame->pIndoorCameraD3D->vPartyPos.z)
+                       / ((double)pODMRenderParams->int_fov_rad + 8192.0)
+                       + (double)(pViewport->uScreenCenterY + 7));//include "+ 7"
+  //v34 = cos((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) * (double)pODMRenderParams->shading_dist_mist;
+  /*v38 = (signed __int64)((double)(pViewport->uScreenCenterY + 7)
+                       - (double)pODMRenderParams->int_fov_rad
+                       / (v34 + 0.0000001)
+                       * (sin((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064)
+                        * (double)-pODMRenderParams->shading_dist_mist
+                        - (double)pGame->pIndoorCameraD3D->vPartyPos.z));*/
+  /*v34 = cos((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064) * 0x2000;
+  v38 = (signed __int64)((double)(pViewport->uScreenCenterY + 7)
+                       - (double)pODMRenderParams->int_fov_rad
+                       / (v34 + 0.0000001)
+                       * (sin((double)pGame->pIndoorCameraD3D->sRotationX * 0.0030664064)
+                        * (double)-0x2000
+                        - (double)pGame->pIndoorCameraD3D->vPartyPos.z));
+  pSkyPolygon.Create_48607B(&stru_8019C8);//заполняется ptr_38
+  pSkyPolygon.ptr_38->_48694B_frustum_sky();
+  pSkyPolygon.uTileBitmapID = pOutdoor->uSky_TextureID;//179(original 166)
+  pSkyPolygon.pTexture = (Texture *)(SLOWORD(pOutdoor->uSky_TextureID) != -1 ? (int)&pBitmaps_LOD->pTextures[SLOWORD(pOutdoor->uSky_TextureID)] : 0);
+  if ( pSkyPolygon.pTexture )
+  {
+    v0 = pGame->pIndoorCameraD3D->sRotationX;
+    pSkyPolygon.dimming_level = 0;
+    pSkyPolygon.uNumVertices = 4;
+    pSkyPolygon.v_18.x = -stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX + 16);
+    pSkyPolygon.v_18.y = 0;
+    v1 = stru_5C6E00->Cos(v0 + 16);
+    v2 = (double)(signed int)pViewport->uViewportTL_X;
+    pSkyPolygon.v_18.z = -v1;
+    array_50AC10[0].vWorldViewProjX = v2;
+    v3 = (double)(signed int)pViewport->uViewportTL_Y;
+    array_50AC10[0].vWorldViewProjY = v3;
+    array_50AC10[1].vWorldViewProjX = v2;
+    v4 = (double)v38;
+    pSkyPolygon.sTextureDeltaU = 224 * pMiscTimer->uTotalGameTimeElapsed;
+    pSkyPolygon.sTextureDeltaV = 224 * pMiscTimer->uTotalGameTimeElapsed;
+    v28 = v4;
+    array_50AC10[1].vWorldViewProjY = v4;
+    v5 = (double)(signed int)pViewport->uViewportBR_X;
+    array_50AC10[2].vWorldViewProjX = v5;
+    v38 = pViewport->uViewportBR_X - pViewport->uViewportTL_X;
+    pSkyPolygon.field_24 = 0x2000000u;
+    array_50AC10[2].vWorldViewProjY = v4;
+    array_50AC10[3].vWorldViewProjX = v5;
+    array_50AC10[3].vWorldViewProjY = v3;
+    v36 = (double)(pViewport->uViewportBR_X - pViewport->uViewportTL_X) * 0.5;
+    v6 = tan(0.6457717418670654);
+    v31 = 0;
+    v33 = 65536 / (signed int)(signed __int64)(v36 / v6 + 0.5);
+    if ( (signed int)pSkyPolygon.uNumVertices <= 0 )
+      goto LABEL_16;
+    v7 = (char *)&array_50AC10[0].vWorldViewProjY;
+    while ( 1 )
+    {
+      LODWORD(v27) = *(_DWORD *)v7;
+      v26 = v27 + 6.7553994e15;
+      v29 = v27;
+      v38 = pSkyPolygon.ptr_38->field_14;
+      v39 = (unsigned __int64)(v38 * (signed __int64)(v33 * (v30 - v27))) >> 16;
+      v8 = v39 + pSkyPolygon.ptr_38->field_C;
+      v39 = v33 * (v30 - v27);
+      v35 = v8;
+      v38 = pSkyPolygon.ptr_38->field_20;
+      v39 = (unsigned __int64)(v38 * (signed __int64)(v33 * (v30 - v27))) >> 16;
+      v36 = v39 + pSkyPolygon.ptr_38->field_18;
+      v38 = pSkyPolygon.v_18.z;
+      v9 = (unsigned __int64)(pSkyPolygon.v_18.z * (signed __int64)(v33 * (v30 - v27))) >> 16;
+      v10 = pSkyPolygon.v_18.x + v9;
+      v39 = pSkyPolygon.v_18.x + v9;
+      if ( pSkyPolygon.v_18.x + v9 > 0 )
+      {
+        v10 = 0;
+        v39 = 0;
+      }
+      v11 = (signed __int64)*((float *)v7 - 1);
+      v38 = v10;
+      v12 = *(float *)v7 - 1.0;
+      v13 = v33 * (pViewport->uScreenCenterX - v11);
+      v34 = -pSkyPolygon.field_24;
+      v32 = (signed __int64)v12;
+      v14 = v33 * (v30 - v32);
+      while ( 1 )
+      {
+        v40 = v14;
+        if ( !v10 )
+          goto LABEL_12;
+        v37 = abs((int)v34 >> 14);
+        v15 = abs(v10);
+        if ( v37 <= v15 || v32 <= (signed int)pViewport->uViewportTL_Y )
+        {
+          if ( v39 <= 0 )
+            break;
+        }
+        v14 = v40;
+LABEL_12:
+        v37 = pSkyPolygon.v_18.z;
+        v16 = (unsigned __int64)(pSkyPolygon.v_18.z * (signed __int64)v14) >> 16;
+        --v32;
+        v14 += v33;
+        v10 = pSkyPolygon.v_18.x + v16;
+        v39 = pSkyPolygon.v_18.x + v16;
+        v38 = pSkyPolygon.v_18.x + v16;
+      }
+      LODWORD(v17) = LODWORD(v34) << 16;
+      //HIDWORD(v17) = LODWORD(v34) >> 16;
+      HIDWORD(v17) = v34 >> 16;
+	  //v17 = (int)v34 >> 16;
+	  //v17 = v17 << 16;
+      v40 = v17 / v38;//v38 = -42331
+      v18 = v17 / v38;
+      if ( v18 < 0 )
+        v18 = pODMRenderParams->shading_dist_mist;
+      v40 = v13;
+      v37 = pSkyPolygon.ptr_38->field_10;
+      v40 = v13;
+      v37 = v35 + ((unsigned __int64)(v37 * (signed __int64)v13) >> 16);
+      v35 = pSkyPolygon.ptr_38->field_1C;
+      v36 += (unsigned __int64)(v35 * (signed __int64)v13) >> 16;
+      v35 = 224 * pMiscTimer->uTotalGameTimeElapsed
+          + ((signed int)((unsigned __int64)(v37 * (signed __int64)v18) >> 16) >> 3);
+      v40 = (unsigned __int64)(v36 * (signed __int64)v18) >> 16;
+      v19 = pSkyPolygon.pTexture;
+      v36 = pSkyPolygon.pTexture->uTextureWidth;
+      v7 += 48;
+      v20 = (double)v36 * 65536.0;
+      HIDWORD(v36) = 224 * pMiscTimer->uTotalGameTimeElapsed + (v40 >> 3);
+      ++v31;
+      array_50AC10[v31 - 1].u = (double)v35 / v20;
+      v21 = (double)SHIDWORD(v36);
+      HIDWORD(v36) = v19->uTextureHeight;
+      v22 = (double)SHIDWORD(v36);
+      HIDWORD(v36) = v18 >> 16;
+      //v24 = __OFSUB__(v31, pSkyPolygon.uNumVertices);
+      //v23 = ((v31 - pSkyPolygon.uNumVertices) & 0x80000000u) != 0;
+      array_50AC10[v31 - 1].v = v21 / (v22 * 65536.0);
+      //array_50AC10[v31 - 1].vWorldViewPosition.x = (double)pODMRenderParams->shading_dist_mist;
+	  array_50AC10[v31 - 1].vWorldViewPosition.x = (double)0x2000;
+      array_50AC10[v31 - 1]._rhw = 1.0 / (double)SHIDWORD(v36);
+      //if ( !(v23 ^ v24) )
+      if ( v31 == pSkyPolygon.uNumVertices )
+      {
+LABEL_16:
+        pRenderer->DrawSkyPolygon(pSkyPolygon.uNumVertices,
+          &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]);
+        array_50AC10[0].vWorldViewProjY = v28;
+        array_50AC10[1].vWorldViewProjY = array_50AC10[1].vWorldViewProjY + 30.0;
+        array_50AC10[2].vWorldViewProjY = array_50AC10[2].vWorldViewProjY + 30.0;
+        array_50AC10[3].vWorldViewProjY = v28;
+        pRenderer->DrawSkyPolygon(pSkyPolygon.uNumVertices, &pSkyPolygon, pBitmaps_LOD->pHardwareTextures[(signed __int16)pSkyPolygon.uTileBitmapID]);
+        return;
+      }
+    }
+  }
+}*/
 
 //----- (0047A384) --------------------------------------------------------
 void ODM_LoadAndInitialize(const char *pLevelFilename, ODMRenderParams *thisa)
--- a/mm7_4.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/mm7_4.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -1405,7 +1405,7 @@
   int v8; // [sp+Ch] [bp-8h]@3
   int v9; // [sp+10h] [bp-4h]@2
   int a2a; // [sp+1Ch] [bp+8h]@1
-
+  return 0;
   v3 = 0;
   result = word_4EE088_sound_ids[uSoundID];
   v5 = this;
@@ -3446,7 +3446,7 @@
 				v11 = &pParty->pHirelings[1];
 				memset(v11, 0, sizeof(NPCData));
 			}
-			pParty->field_709 = 0;
+			pParty->hirelingScrollPosition = 0;
 			pParty->CountHirelings();
 			dword_591084 = 0;
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
@@ -3494,7 +3494,7 @@
 				v13 = pParty->pHireling1Name;
 			}
 			strcpy(v13, v15);
-			pParty->field_709 = 0;
+			pParty->hirelingScrollPosition = 0;
 			pParty->CountHirelings();
 
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
@@ -3555,7 +3555,7 @@
 				v11 = &pParty->pHirelings[1];
 				memset(v11, 0, sizeof(NPCData));
 			}
-			pParty->field_709 = 0;
+			pParty->hirelingScrollPosition = 0;
 			pParty->CountHirelings();
 			dword_591084 = 0;
 			pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
--- a/mm7_5.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/mm7_5.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -357,11 +357,11 @@
               //while ( _this < (signed int)pNPCStats->uNumNewNPCs );
             }
 
-            if ( (signed int)(hireling_idx + (unsigned __int8)pParty->field_709) < uAction )
+            if ( (signed int)(hireling_idx + pParty->hirelingScrollPosition) < uAction )
             {
               //Actor::Actor(&actor);
               memset(&actor, 0, 0x344u);
-              actor.sNPC_ID += -1 - (unsigned __int8)pParty->field_709 - hireling_idx;
+              actor.sNPC_ID += -1 - pParty->hirelingScrollPosition - hireling_idx;
               pActor = &actor;
               GameUI_InitializeDialogue(&actor, true);
             }
@@ -1343,26 +1343,26 @@
                       if ( uCurrentHouse_Animation == 153 )
                         PlayHouseSound(0x99u, HouseSound_Greeting_2);
                       pVideoPlayer->Unload();
-                      if ( dword_5B65CC )
+                      if ( npcIdToDismissAfterDialogue )
                       {
-                        pParty->field_709 = 0;
-                        LOBYTE(pNPCStats->pNewNPCData[dword_5B65CC].uFlags) &= 0x7Fu;
+                        pParty->hirelingScrollPosition = 0;
+                        LOBYTE(pNPCStats->pNewNPCData[npcIdToDismissAfterDialogue].uFlags) &= 0x7Fu;
                         pParty->CountHirelings();
                         viewparams->bRedrawGameUI = true;
-                        dword_5B65CC = 0;
+                        npcIdToDismissAfterDialogue = 0;
                       }
                       DialogueEnding();
                       pCurrentScreen = SCREEN_GAME;
                       viewparams->bRedrawGameUI = true;
                       continue;
                     case SCREEN_NPC_DIALOGUE://click escape
-                      if ( dword_5B65CC )
+                      if ( npcIdToDismissAfterDialogue )
                       {
-                        pParty->field_709 = 0;
-                        LOBYTE(pNPCStats->pNewNPCData[dword_5B65CC].uFlags) &= 0x7Fu;
+                        pParty->hirelingScrollPosition = 0;
+                        LOBYTE(pNPCStats->pNewNPCData[npcIdToDismissAfterDialogue].uFlags) &= 0x7Fu;
                         pParty->CountHirelings();
                         viewparams->bRedrawGameUI = true;
-                        dword_5B65CC = 0;
+                        npcIdToDismissAfterDialogue = 0;
                       }
                       //goto LABEL_317;
                       DialogueEnding();
@@ -1574,22 +1574,22 @@
           {
             GUIWindow::Create(626, 179, 0, 0, WINDOW_PressedButton2, (int)pBtn_NPCRight, 0);
             v37 = (pParty->pHirelings[0].pName != 0) + (pParty->pHirelings[1].pName != 0) + (unsigned __int8)pParty->field_70A - 2;
-            if ( (unsigned __int8)pParty->field_709 < v37 )
+            if ( pParty->hirelingScrollPosition < v37 )
             {
-              ++pParty->field_709;//??? maybe number of the first cell???
-              if ( (unsigned __int8)pParty->field_709 >= v37 )
-                pParty->field_709 = (pParty->pHirelings[0].pName != 0) + (pParty->pHirelings[1].pName != 0) + pParty->field_70A - 2;
+              ++pParty->hirelingScrollPosition;//??? maybe number of the first cell???
+              if ( pParty->hirelingScrollPosition >= v37 )
+                pParty->hirelingScrollPosition = (pParty->pHirelings[0].pName != 0) + (pParty->pHirelings[1].pName != 0) + pParty->field_70A - 2;
             }
           }
           else
           {
             GUIWindow::Create(469, 179, 0, 0, WINDOW_PressedButton2, (int)pBtn_NPCLeft, 0);
-            if ( pParty->field_709 )
+            /*if ( pParty->field_709 )
             {
               --pParty->field_709;
               if ( pParty->field_709 < 1 )
                 pParty->field_709 = 0;
-            }
+            }*/
           }
           GameUI_DrawHiredNPCs();
           continue;
--- a/mm7_6.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/mm7_6.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -42,173 +42,6 @@
 
 
 
-//----- (00424EE0) --------------------------------------------------------
-int __fastcall sr_424EE0_MakeFanFromTriangle(unsigned int uVertexID)
-{
-  unsigned int v1; // edx@1
-  double v2; // st7@1
-  signed int v3; // edi@1
-  char *v4; // esi@4
-  char *v5; // ecx@4
-  unsigned int v6; // eax@4
-  char *v7; // edx@4
-  double v8; // st6@10
-  double v9; // st5@10
-  double v10; // st6@11
-  unsigned __int8 v11; // c2@15
-  unsigned __int8 v12; // c3@15
-  void *v13; // edi@22
-  char *v14; // eax@22
-  double v15; // st6@22
-  char *v16; // ecx@22
-  signed int result; // eax@24
-  unsigned int v18; // [sp+8h] [bp-2Ch]@4
-  bool v19; // [sp+Ch] [bp-28h]@6
-  char *v20; // [sp+10h] [bp-24h]@4
-  char *v21; // [sp+14h] [bp-20h]@4
-  signed int v22; // [sp+18h] [bp-1Ch]@1
-  char *v23; // [sp+1Ch] [bp-18h]@4
-  RenderVertexSoft *v24; // [sp+20h] [bp-14h]@4
-  char *v25; // [sp+24h] [bp-10h]@4
-  char *v26; // [sp+28h] [bp-Ch]@4
-  char *v27; // [sp+2Ch] [bp-8h]@4
-  char *v28; // [sp+30h] [bp-4h]@4
-
-  v1 = uVertexID;
-  v2 = (double)pODMRenderParams->shading_dist_mist;
-  memcpy(&array_50AC10[uVertexID], array_50AC10, sizeof(array_50AC10[uVertexID]));
-  v3 = 0;
-  v22 = 0;
-  if ( array_50AC10[0].vWorldViewPosition.x <= v2 )
-    v3 = 1;
-  if ( (signed int)(uVertexID + 1) <= 1 )
-    return 0;
-  v4 = (char *)&array_507D30[0].vWorldViewPosition.z;
-  v5 = (char *)&array_507D30[0].vWorldViewPosition.y;
-  v6 = v1;
-  v23 = (char *)&array_507D30[0].flt_2C;
-  v26 = (char *)&array_507D30[0]._rhw;
-  v24 = array_507D30;
-  v20 = (char *)&array_507D30[0].vWorldViewPosition.z;
-  v21 = (char *)&array_507D30[0].vWorldViewPosition.y;
-  v25 = (char *)&array_507D30[0].vWorldViewPosition;
-  v27 = (char *)&array_507D30[0].v;
-  v28 = (char *)&array_507D30[0].u;
-  v7 = (char *)&array_50AC10[0].v;
-  v18 = v6;
-  do
-  {
-    v19 = v2 >= *((float *)v7 + 5);
-    if ( v3 != v19 )
-    {
-      if ( v19 )
-      {
-        v8 = (v2 - *((float *)v7 - 7)) / (*((float *)v7 + 5) - *((float *)v7 - 7));
-        *(float *)v5 = (*((float *)v7 + 6) - *((float *)v7 - 6)) * v8 + *((float *)v7 - 6);
-        *(float *)v4 = (*((float *)v7 + 7) - *((float *)v7 - 5)) * v8 + *((float *)v7 - 5);
-        *(float *)v28 = (*((float *)v7 + 11) - *((float *)v7 - 1)) * v8 + *((float *)v7 - 1);
-        v9 = (*((float *)v7 + 12) - *(float *)v7) * v8 + *(float *)v7;
-      }
-      else
-      {
-        v10 = (v2 - *((float *)v7 + 5)) / (*((float *)v7 - 7) - *((float *)v7 + 5));
-        *(float *)v5 = (*((float *)v7 - 6) - *((float *)v7 + 6)) * v10 + *((float *)v7 + 6);
-        *(float *)v4 = (*((float *)v7 - 5) - *((float *)v7 + 7)) * v10 + *((float *)v7 + 7);
-        *(float *)v28 = (*((float *)v7 - 1) - *((float *)v7 + 11)) * v10 + *((float *)v7 + 11);
-        v9 = (*(float *)v7 - *((float *)v7 + 12)) * v10 + *((float *)v7 + 12);
-      }
-      *(float *)v27 = v9;
-      *(float *)v25 = v2;
-      *(float *)v26 = 1.0 / v2;
-      if ( v3 )
-      {
-        if ( v2 == *((float *)v7 - 7) && *(float *)v5 == *((float *)v7 - 6) )
-        {
-          v11 = 0;
-          v12 = *(float *)v4 == *((float *)v7 - 5);
-          if ( ! (v12 | v11) )
-		  {
-			  v26 += 48;
-			  ++v24;
-			  v25 += 48;
-			  v27 += 48;
-			  v28 += 48;
-			  v5 += 48;
-			  v4 += 48;
-			  ++v22;
-			  v23 += 48;
-			  v21 = v5;
-			  v20 = v4;
-		  }
-        }
-      }
-      else
-      {
-        if ( v2 == *((float *)v7 + 5) && *(float *)v5 == *((float *)v7 + 6) )
-        {
-          v11 = 0;
-          v12 = *(float *)v4 == *((float *)v7 + 7);
-          if ( !(v12 | v11) )
-		  {
-			  v26 += 48;
-			  ++v24;
-			  v25 += 48;
-			  v27 += 48;
-			  v28 += 48;
-			  v5 += 48;
-			  v4 += 48;
-			  ++v22;
-			  v23 += 48;
-			  v21 = v5;
-			  v20 = v4;
-		  }
-        }
-      }
-      v26 += 48;
-      ++v24;
-      v25 += 48;
-      v27 += 48;
-      v28 += 48;
-      v5 += 48;
-      v4 += 48;
-      ++v22;
-      v23 += 48;
-      v21 = v5;
-      v20 = v4;
-    }
-    if ( v19 )
-    {
-      v13 = v24;
-      v14 = v26;
-      v21 += 48;
-      v15 = 1.0 / (*((float *)v7 + 5) + 0.0000001);
-      v20 += 48;
-      ++v22;
-      v28 += 48;
-      v27 += 48;
-      v25 += 48;
-      ++v24;
-      v26 += 48;
-      memcpy(v13, v7 + 8, 0x30u);
-      v16 = v23;
-      v23 += 48;
-      v4 = v20;
-      *(float *)v14 = v15;
-      *(int *)v16 = *((int *)v7 + 13);
-      v5 = v21;
-    }
-    v3 = v19;
-    v7 += 48;
-    --v18;
-  }
-  while ( v18 );
-  result = v22;
-  if ( v22 < 3 )
-    return 0;
-  return result;
-}
-
-
 //----- (00426A5A) --------------------------------------------------------
 void stru319::LootActor(Actor *pActor)
 {
@@ -235,7 +68,7 @@
   if ( v3 )
   {
     if ( pActor->pMonsterInfo.uTreasureDiceRolls )
-	{
+    {
 		do
 		{
 		  ++v2;
@@ -325,21 +158,21 @@
         pParty->SetHoldingItem(&Dst);
       v13 = 1;
     }
-    goto LABEL_44;
+    v8 = pParty;
+    goto LABEL_45;
   }
   if ( rand() % 100 >= pActor->pMonsterInfo.uTreasureDropChance || (v7 = pActor->pMonsterInfo.uTreasureLevel) == 0 )
   {
-LABEL_44:
     v8 = pParty;
     goto LABEL_45;
   }
   pItemsTable->GenerateItem(v7, pActor->pMonsterInfo.uTreasureType, &Dst);
   v10 = pItemsTable->pItems[Dst.uItemID].pUnidentifiedName;
   if ( v14 )
-    sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[490], v14, v10);
+    sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[490], v14, v10);//Вы нашли ^I[%d] золот^L[ой;ых;ых] и предмет (%s)!
   else
-    sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], v10);
-  ShowStatusBarString(pTmpBuf2.data(), 2u);
+    sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[471], v10);//Вы нашли ^Pv[%s]!
+  ShowStatusBarString(pTmpBuf2.data(), 2);
   v8 = pParty;
   if ( !pParty->AddItemToParty(&Dst) )
     pParty->SetHoldingItem(&Dst);
@@ -891,9 +724,6 @@
     v5 = pActor->pActorBuffs[14].uPower;
   switch ( a2 )
   {
-    case 4:
-      v6 = pActor->pMonsterInfo.uResPhysical;
-      break;
     case 0:
       v6 = pActor->pMonsterInfo.uResFire;
       v4 = v5;
@@ -910,6 +740,9 @@
       v6 = pActor->pMonsterInfo.uResEarth;
       v4 = v5;
       break;
+    case 4:
+      v6 = pActor->pMonsterInfo.uResPhysical;
+      break;
     case 6:
       v6 = pActor->pMonsterInfo.uResSpirit;
       break;
@@ -960,50 +793,47 @@
 //----- (00427662) --------------------------------------------------------
 bool stru319::GetMagicalResistance(Actor *pActor, unsigned int uType)
 {
-  Actor *v3; // edi@2
-  signed int v4; // esi@2
+  signed int resist; // esi@2
   bool result; // eax@13
 
   switch ( uType )
   {
-    case 0u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResFire;
-    case 1u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResAir;
-    case 2u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResWater;
-    case 3u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResEarth;
-    case 7u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResMind;
-    case 6u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResSpirit;
-    case 8u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResBody;
-    case 9u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResLight;
-    case 0xAu:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResDark;
-    case 4u:
-      v3 = pActor;
-      v4 = pActor->pMonsterInfo.uResPhysical;
+    case 0:
+      resist = pActor->pMonsterInfo.uResFire;
+      break;
+    case 1:
+      resist = pActor->pMonsterInfo.uResAir;
+      break;
+    case 2:
+      resist = pActor->pMonsterInfo.uResWater;
+      break;
+    case 3:
+      resist = pActor->pMonsterInfo.uResEarth;
+      break;
+    case 4:
+      resist = pActor->pMonsterInfo.uResPhysical;
+      break;
+    case 6:
+      resist = pActor->pMonsterInfo.uResSpirit;
+      break;
+    case 7:
+      resist = pActor->pMonsterInfo.uResMind;
+    case 8:
+      resist = pActor->pMonsterInfo.uResBody;
+      break;
+    case 9:
+      resist = pActor->pMonsterInfo.uResLight;
+      break;
+    case 10:
+      resist = pActor->pMonsterInfo.uResDark;
       break;
     default:
       return 1;
   }
-  if ( v4 < 200 )
-	result = rand() % (signed int)(((unsigned int)v3->pMonsterInfo.uLevel >> 2) + v4 + 30) < 30;
+  if ( resist < 200 )
+    result = rand() % (signed int)(((unsigned int)pActor->pMonsterInfo.uLevel >> 2) + resist + 30) < 30;
   else
-	result = 0;
+    result = 0;
   return result;
 }
 
--- a/mm7_data.cpp	Mon Oct 07 11:52:33 2013 +0200
+++ b/mm7_data.cpp	Mon Oct 07 11:55:35 2013 +0200
@@ -1054,7 +1054,7 @@
 int dword_5B65C0; // weak
 int dword_5B65C4; // weak
 int dword_5B65C8_timers_count; // weak
-int dword_5B65CC; // weak
+int npcIdToDismissAfterDialogue; // weak
 signed int dword_5B65D0_dialogue_actor_npc_id; // weak
 int dword_5C3418; // weak
 int dword_5C341C; // weak
@@ -1348,7 +1348,6 @@
 int dword_F8B1F4; // weak
 
 
-
 //_UNKNOWN unk_F8BA50; // weak
 char byte_F8BC0C; // weak
 int bGameoverLoop = 0; // weak
--- a/mm7_data.h	Mon Oct 07 11:52:33 2013 +0200
+++ b/mm7_data.h	Mon Oct 07 11:55:35 2013 +0200
@@ -702,7 +702,7 @@
 extern int dword_5B65C0; // weak
 extern int dword_5B65C4; // weak
 extern int dword_5B65C8_timers_count; // weak
-extern int dword_5B65CC; // weak
+extern int npcIdToDismissAfterDialogue; // weak
 extern int dword_5B65D0_dialogue_actor_npc_id; // weak
 extern int dword_5C3418; // weak
 extern int dword_5C341C; // weak
@@ -1099,7 +1099,7 @@
 int __fastcall GetPortalScreenCoord(unsigned int uFaceID);
 bool PortalFrustrum(int pNumVertices, struct BspRenderer_PortalViewportData *a2, struct BspRenderer_PortalViewportData *near_portal, int uFaceID);
 int sr_424CD7(unsigned int uVertexID); // idb
-int __fastcall sr_424EE0_MakeFanFromTriangle(unsigned int uVertexID); // idb
+int BuildingVerticesClipping(unsigned int uNumVertices);
 void __fastcall GivePartyExp(unsigned int pEXPNum);
 bool __fastcall sub_427769_spell(unsigned int uSpellID);
 void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6);
@@ -1154,7 +1154,7 @@
 char *GetEventHintString(unsigned int uEventID); // idb
 int GetTravelTime();
 void __fastcall sub_4451A8_press_any_key(int a1, int a2, int a4);
-int SkillToMastery(unsigned int skill_value);
+unsigned int SkillToMastery(unsigned int skill_value);
 unsigned int __fastcall GetSpellColor(signed int a1);
 unsigned short * MakeScreenshot(signed int width, signed int height);
 void SaveScreenshot(const char *pFilename);