changeset 2333:82851980e3d8

Слияние
author Ritor1
date Wed, 02 Apr 2014 20:53:47 +0600
parents defd2526c94c (current diff) 9551756f46c4 (diff)
children ddb803517a48
files Render.cpp
diffstat 28 files changed, 1472 insertions(+), 1831 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Actor.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -1999,7 +1999,7 @@
 
   if (rand() % 100 < 20 && drop.uItemID != 0)
   {
-    sub_42F7EB_DropItemAt(pItemsTable->pItems[drop.uItemID].uSpriteID,
+    SpriteObject::sub_42F7EB_DropItemAt(pItemsTable->pItems[drop.uItemID].uSpriteID,
       actor->vPosition.x,
       actor->vPosition.y,
       actor->vPosition.z + 16,
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Wed Apr 02 20:53:35 2014 +0600
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Wed Apr 02 20:53:47 2014 +0600
@@ -202,6 +202,7 @@
     <ClCompile Include="..\..\ObjectList.cpp" />
     <ClCompile Include="..\..\OSAPI.cpp" />
     <ClCompile Include="..\..\OSWindow.cpp" />
+    <ClCompile Include="..\..\OurMath.cpp" />
     <ClCompile Include="..\..\Outdoor.cpp" />
     <ClCompile Include="..\..\Overlays.cpp" />
     <ClCompile Include="..\..\PaletteManager.cpp" />
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Wed Apr 02 20:53:35 2014 +0600
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Wed Apr 02 20:53:47 2014 +0600
@@ -385,6 +385,7 @@
       <Filter>lib\libpng</Filter>
     </ClCompile>
     <ClCompile Include="..\..\MediaPlayer.cpp" />
+    <ClCompile Include="..\..\OurMath.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\Level\Decoration.h" />
--- a/CastSpellInfo.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/CastSpellInfo.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -3212,7 +3212,7 @@
           v642 = rand() % 4096 - 2048;
           v643 = rand();
           v732 = GetTerrainHeightsAroundParty2(v642 + pParty->vPosition.x, pParty->vPosition.y + (v643 % 4096 - 2048), &v710, 0);
-          sub_42F7EB_DropItemAt(4070, v642 + pParty->vPosition.x, pParty->vPosition.y + (v643 % 4096 - 2048), v732 + 16, rand() % 500 + 500, 1, 0, 0, 0);
+          SpriteObject::sub_42F7EB_DropItemAt(4070, v642 + pParty->vPosition.x, pParty->vPosition.y + (v643 % 4096 - 2048), v732 + 16, rand() % 500 + 500, 1, 0, 0, 0);
         }
         spell_sound_flag = true;
         break;
--- a/Chest.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Chest.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -132,7 +132,7 @@
       v.y = pObjectY;
       v.z = pObjectZ;
       Vec3_int_::Rotate(pDepth, sRotX, sRotY, v, &pOut.x, &pOut.z, &pOut.y);
-      sub_42F7EB_DropItemAt(pSpriteID[pRandom], pOut.x, pOut.z, pOut.y, 0, 1, 0, 48, 0);
+      SpriteObject::sub_42F7EB_DropItemAt(pSpriteID[pRandom], pOut.x, pOut.z, pOut.y, 0, 1, 0, 48, 0);
 
       pSpellObject.stru_24.Reset();
       pSpellObject.spell_skill = 0;
--- a/DecalBuilder.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/DecalBuilder.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -244,7 +244,7 @@
 {
   //DecalBuilder *v12; // esi@1
   Decal *v13; // edi@2
-  int *v14; // eax@2
+  //int *v14; // eax@2
   //double v15; // st7@4
   //double v16; // st7@4
   //int v17; // eax@4
@@ -280,11 +280,11 @@
   if ( a6 == 0.0 )
     return 1;
   v13 = &this->std__vector_pDecals[this->field_308008];
-  v14 = &this->std__vector_pDecals[this->field_308008].field_C1C;
+  //v14 = &this->std__vector_pDecals[this->field_308008].field_C1C;
   this->std__vector_pDecals[this->field_308008].field_C18 = (DecalBuilder_stru0 *)a4;
-  *v14 = 0;
+  this->std__vector_pDecals[this->field_308008].field_C1C = 0;
   if ( a3 & 2 )
-    *v14 = 1;
+    this->std__vector_pDecals[this->field_308008].field_C1C = 1;
   //v15 = a6 - a8;
   this->field_30C028 = a6 - a8;
   //v16 = sqrt((a6 + a6 - this->field_30C028) * this->field_30C028);
--- a/Events.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Events.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -12,6 +12,7 @@
 #include "Render.h"
 #include "GUIWindow.h"
 #include "GUIProgressBar.h"
+#include "SpriteObject.h"
 #include "Chest.h"
 #include "stru176.h"
 #include "LOD.h"
@@ -758,7 +759,7 @@
         ++curr_seq_num;
         break;
       case EVENT_SummonItem:
-        sub_42F7EB_DropItemAt(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
+        SpriteObject::sub_42F7EB_DropItemAt(_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8),
           _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8),
           _evt->v13 + ((_evt->v14 + ((_evt->v15 + ((uint)_evt->v16 << 8)) << 8)) << 8),
           _evt->v17 + ((_evt->v18 + ((_evt->v19 + ((uint)_evt->v20 << 8)) << 8)) << 8),
--- a/GUIWindow.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/GUIWindow.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -2537,4 +2537,20 @@
     strcat(pTmpBuf.data(), pTmpBuf2.data());
   }
   window->DrawText(Font, 32, uY, 0, pTmpBuf.data(), 0, 0, 0);
+}
+
+
+//----- (0042EB8D) --------------------------------------------------------
+void GUIMessageQueue::AddMessageImpl(UIMessageType msg, int param, unsigned int a4, const char *file, int line)
+{
+  //Log::Warning(L"%s @ (%S %u)", UIMessage2String(msg), file, line);
+  if (uNumMessages < 40)
+  {
+    files[uNumMessages] = file;
+    lines[uNumMessages] = line;
+
+    pMessages[uNumMessages].eType = msg;
+    pMessages[uNumMessages].param = param;
+    pMessages[uNumMessages++].field_8 = a4;
+  }
 }
\ No newline at end of file
--- a/Game.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Game.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -333,7 +333,7 @@
       }
       pGame->_44EEA7();
       GameUI_WritePointedObjectStatusString();
-      ProcessInputActions();
+      Keyboard::ProcessInputActions();
       GameUI_MsgProc();
       if ( pArcomageGame->bGameInProgress )
       {
@@ -3441,13 +3441,13 @@
             continue;
           if ( pParty->bTurnBasedModeOn != 1 )
           {
-            _42ECB5_PlayerAttacksActor();
+            Player::_42ECB5_PlayerAttacksActor();
             continue;
           }
           if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_MOVEMENT )
             continue;
           if ( !(pTurnEngine->field_18 & TE_HAVE_PENDING_ACTIONS) )
-            _42ECB5_PlayerAttacksActor();
+            Player::_42ECB5_PlayerAttacksActor();
           continue;
         case UIMSG_ExitRest:
           GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn, (int)pButton_RestUI_Exit, pGlobalTXT_LocalizationStrings[81]);// "Exit Rest"
@@ -4560,4 +4560,22 @@
     }
     while ( pMessageQueue_50CBD0->uNumMessages );
   }
+}
+
+
+
+//----- (0042FBDD) --------------------------------------------------------
+void  sub_42FBDD()
+{
+  pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
+  pRenderer->DrawTextureTransparent(pBtn_YES->uX, pBtn_YES->uY, pBtn_YES->pTextures[0]);
+  pRenderer->Present();
+}
+
+//----- (0042FC15) --------------------------------------------------------
+void  CloseWindowBackground()
+{
+  pAudioPlayer->PlaySound(SOUND_Button2, -2, 0, -1, 0, 0, 0, 0);
+  pRenderer->DrawTextureTransparent(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pBtn_ExitCancel->pTextures[0]);
+  pRenderer->Present();
 }
\ No newline at end of file
--- a/Indoor.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Indoor.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -516,7 +516,7 @@
         if (stru_F8AD28.uNumLightsApplied > 0 && !pFace->Indoor_sky())
           pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0);
 
-        if (pDecalBuilder->uNumDecals > 0)
+        if (pDecalBuilder->uNumDecals > 0)//  
           pDecalBuilder->ApplyDecals(a4a, 1, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0, pFace->uSectorID);
 
         if (pFace->Fluid())
--- a/Keyboard.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Keyboard.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -8,6 +8,11 @@
 #include "Vis.h"
 #include "MM7.h"
 #include "Actor.h"
+#include "Party.h"
+#include "Timer.h"
+#include "TurnEngine.h"
+#include "Weather.h"
+#include "CastSpellInfo.h"
 #include "DecorationList.h"
 #include "Indoor.h"
 #include "viewport.h"
@@ -478,3 +483,382 @@
       break;
   }*/
 }
+
+
+//----- (0042FC4E) --------------------------------------------------------
+void Keyboard::ProcessInputActions()
+{
+  char v4; // al@9
+  //char v8; // bl@100
+  unsigned __int16 v9; // ax@102
+  int spell_price; // eax@103
+  char v14; // al@159
+  unsigned int v15; // eax@168
+  PartyAction partyAction; // [sp-14h] [bp-1Ch]@20
+  InputAction inputAction; // [sp+0h] [bp-8h]@7
+  //int v24; // [sp+4h] [bp-4h]@87
+
+  pGame->pKeyboardInstance->EnterCriticalSection();
+  Keyboard* pKeyboard = pGame->pKeyboardInstance;
+  if (!bAlwaysRun)
+  {
+    if (pKeyboard->IsShiftHeld())
+      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
+    else
+      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
+   }
+  else
+  {
+    if (pKeyboard->IsShiftHeld())
+      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
+    else
+      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
+  }
+
+  //pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
+
+
+    //  WUT? double event trigger
+  /*for ( uint i = 0; i < 30; ++i )
+  {
+    if ( pKeyActionMap->pToggleTypes[i] )
+      v14 = pGame->pKeyboardInstance->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[i]);
+    else
+      v14 = pGame->pKeyboardInstance->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[i]);
+    if ( v14 )
+    {
+      if (pCurrentScreen == SCREEN_GAME)
+      {
+        pMessageQueue_50CBD0->AddMessage(UIMSG_Game_Action, 0, 0);
+        continue;
+      }
+      if ( pCurrentScreen == SCREEN_NPC_DIALOGUE || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
+      {
+        v15 = pMessageQueue_50CBD0->uNumMessages;
+        if ( pMessageQueue_50CBD0->uNumMessages )
+        {
+          v15 = 0;
+          if ( pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 )
+          {
+            v15 = 1;
+            pMessageQueue_50CBD0->uNumMessages = 0;
+            pMessageQueue_50CBD0->pMessages[v15].eType = UIMSG_Escape;
+            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
+            *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+            ++pMessageQueue_50CBD0->uNumMessages;
+            continue;
+          }
+          pMessageQueue_50CBD0->uNumMessages = 0;
+        }
+        //pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+      }
+    }
+  }*/
+  if ( !pEventTimer->bPaused )
+  {
+    for ( uint i = 0; i < 30; ++i )
+    {
+      inputAction = (InputAction)i;
+      if ( pKeyActionMap->pToggleTypes[inputAction] )
+        v4 = pKeyboard->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
+      else
+        v4 = pKeyboard->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
+      if ( v4 )
+      {
+        switch ( inputAction )
+        {
+          case INPUT_MoveForward:
+            if (pCurrentScreen  != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
+                partyAction = PARTY_RunForward;
+              else
+                partyAction = PARTY_WalkForward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if (pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
+            {
+              pTurnEngine->uActionPointsLeft -= 26;
+              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
+                partyAction = PARTY_RunForward;
+              else
+                partyAction = PARTY_WalkForward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            break;
+          case INPUT_MoveBackwards:
+            if (pCurrentScreen  != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_RunBackward;
+              else
+                partyAction = PARTY_WalkBackward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if ( pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
+            {
+              pTurnEngine->uActionPointsLeft -= 26;
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_RunBackward;
+              else
+                partyAction = PARTY_WalkBackward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            break;
+          case INPUT_StrafeLeft:
+            if (pCurrentScreen  != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              partyAction = PARTY_StrafeLeft;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+              break;
+            pTurnEngine->uActionPointsLeft -= 26;
+            partyAction = PARTY_StrafeLeft;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_StrafeRight:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              partyAction = PARTY_StrafeRight;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+              break;
+            pTurnEngine->uActionPointsLeft -= 26;
+            partyAction = PARTY_StrafeRight;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_TurnLeft:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if ( GetAsyncKeyState(VK_CONTROL) ) // strafing
+            {
+              if (pParty->bTurnBasedModeOn)
+              {
+                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+                  break;
+                pTurnEngine->uActionPointsLeft -= 26;
+              }
+              partyAction = PARTY_StrafeLeft;
+            }
+            else
+            {
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_FastTurnLeft;
+              else
+                partyAction = PARTY_TurnLeft;
+            }
+            pPartyActionQueue->Add(partyAction);
+            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
+              pWeather->OnPlayerTurn(10);
+            break;
+          case INPUT_TurnRight:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if ( GetAsyncKeyState(17) )         // strafing
+            {
+              if (pParty->bTurnBasedModeOn)
+              {
+                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+                  break;
+                pTurnEngine->uActionPointsLeft -= 26;
+              }
+              partyAction = PARTY_StrafeRight;
+            }
+            else
+            {
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_FastTurnRight;
+              else
+                partyAction = PARTY_TurnRight;
+            }
+            pPartyActionQueue->Add(partyAction);
+            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
+              pWeather->OnPlayerTurn(-10);
+            break;
+          case INPUT_Jump:
+            if (pCurrentScreen != SCREEN_GAME || pParty->bTurnBasedModeOn)
+              break;
+            partyAction = (PartyAction)12;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_Yell:
+            if (!pCurrentScreen && uActiveCharacter)
+            {
+              pParty->Yell();
+              pPlayers[uActiveCharacter]->PlaySound(SPEECH_Yell, 0);
+            }
+          break;
+          case INPUT_Pass:
+            if ( pCurrentScreen )
+              break;
+            if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
+            {
+              pTurnEngine->field_18 |= TE_FLAG_8;
+              break;
+            }
+            if ( uActiveCharacter )
+            {
+              if ( !pPlayers[uActiveCharacter]->uTimeToRecovery )
+              {
+                if ( !pParty->bTurnBasedModeOn )
+                  pPlayers[uActiveCharacter]->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)pPlayers[uActiveCharacter]->GetAttackRecoveryTime(false) * 2.133333333333333));
+                CastSpellInfoHelpers::_427D48();
+                pTurnEngine->ApplyPlayerAction();
+              }
+            }
+            break;
+          case INPUT_Combat://if press ENTER
+            if (pCurrentScreen == SCREEN_GAME)
+            {
+              if (pParty->bTurnBasedModeOn)
+              {
+                if (pTurnEngine->turn_stage == TE_MOVEMENT || PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
+                {
+                  pParty->bTurnBasedModeOn = 0;
+                  pTurnEngine->End(true);
+                }
+              }
+              else
+              {
+                pTurnEngine->Start();
+                pParty->bTurnBasedModeOn = true;
+              }
+            }
+            break;
+          case INPUT_CastReady:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
+            {
+              pTurnEngine->field_18 |= TE_FLAG_8;
+              break;
+            }
+            if ( !uActiveCharacter )
+              break;
+            v9 = pPlayers[uActiveCharacter]->pActiveSkills[(unsigned __int8)pPlayers[uActiveCharacter]->uQuickSpell / 11 + 12];
+            if ( !pPlayers[uActiveCharacter]->uQuickSpell || bUnderwater
+              || (( !(HIBYTE(v9) & 1)) ? 
+                 ((v9 & 0x80) == 0 ? 
+                 ((v9 & 0x40) == 0 ? spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uNormalLevelMana : spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uExpertLevelMana) : 
+                 spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uMasterLevelMana) : 
+                 spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uMagisterLevelMana,
+                 spell_price > pPlayers[uActiveCharacter]->sMana) )
+            {
+              pPartyActionQueue = pPartyActionQueue;
+              pMessageQueue_50CBD0->AddMessage(UIMSG_Attack, 0, 0);
+              break;
+            }
+            else
+              pMessageQueue_50C9E8->AddMessage(UIMSG_CastQuickSpell, 0, 0);
+            break;
+          case INPUT_Attack:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT)
+            {
+              pTurnEngine->field_18 |= TE_FLAG_8;
+              break;
+            }
+            pMessageQueue_50CBD0->AddMessage(UIMSG_Attack, 0, 0);
+            break;
+          case INPUT_EventTrigger:
+            if (pCurrentScreen == SCREEN_GAME)
+            {
+              pMessageQueue_50CBD0->AddMessage(UIMSG_Game_Action, 0, 0);
+              break;
+            }
+            if ( pCurrentScreen == SCREEN_NPC_DIALOGUE )
+            {
+              if ( pMessageQueue_50CBD0->uNumMessages )
+              {
+                pMessageQueue_50CBD0->uNumMessages = 0;
+                if ( pMessageQueue_50CBD0->pMessages[0].field_8 )
+                {
+                  pMessageQueue_50CBD0->uNumMessages = 1;
+                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
+                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
+                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 = 0;
+                  ++pMessageQueue_50CBD0->uNumMessages;
+                  break;
+                }
+                break;
+              }
+              pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
+            }
+            break;
+          case INPUT_CharCycle:
+            if ( pCurrentScreen == SCREEN_SPELL_BOOK  )
+              break;
+
+            pMessageQueue_50C9E8->AddMessage(UIMSG_CycleCharacters, 0, 0);
+            break;
+          case INPUT_LookUp:
+            if ( pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)7;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_CenterView:
+            if ( pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)9;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_LookDown:
+            if ( pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)8;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_FlyUp:
+            if ( pCurrentScreen || pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)13;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_Land:
+            if ( pCurrentScreen || pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)15;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_FlyDown:
+            if ( !pCurrentScreen
+              && !pEventTimer->bPaused )
+            {
+              partyAction = (PartyAction)14;
+              pPartyActionQueue->Add(partyAction);
+            }
+            break;
+          case INPUT_ZoomIn:
+              pMessageQueue_50C9E8->AddMessage(UIMSG_ClickZoomOutBtn, 0, 0);
+            break;
+          case INPUT_ZoomOut:
+              pMessageQueue_50C9E8->AddMessage(UIMSG_ClickZoomInBtn, 0, 0);
+            break;
+          case INPUT_AlwaysRun:
+            bAlwaysRun = bAlwaysRun == 0;
+            break;
+          default:
+            break;
+        }
+      }
+    }
+  }
+}
--- a/Keyboard.h	Wed Apr 02 20:53:35 2014 +0600
+++ b/Keyboard.h	Wed Apr 02 20:53:47 2014 +0600
@@ -85,6 +85,7 @@
   {}
   bool WasKeyPressed(int vKey);
   static bool IsKeyBeingHeld(int vKey);
+  static void ProcessInputActions();
   bool IsShiftHeld();
   void EnterCriticalSection();
 
--- a/LightmapBuilder.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/LightmapBuilder.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -240,7 +240,7 @@
   if (!v11->uNumVertices)
     return true;
 
-  v45 = _45C6D6(uNumVertices, a9, v11);//  ( )
+  v45 = _45C6D6(uNumVertices, a9, v11);
   if ( v45 != uNumVertices && v45 > 0 )
     _45C4B9(uNumVertices, a9, v11);
   //v59 = v11->uNumVertices;
@@ -340,7 +340,7 @@
   char v26; // [sp+1Eh] [bp-2h]@17
   char v27; // [sp+1Fh] [bp-1h]@17
 
-  __debugbreak();//Ritor1: needed cleaning
+  //__debugbreak();//Ritor1: needed cleaning
 
   v4 = pLightmap;
   v5 = 0;
@@ -487,7 +487,7 @@
                   : pLightmap->pVertices[i].vWorldPosition.z - a3[j].vWorldPosition.z;
               if ( v11 < 2.0 )
               {
-                v12 = v9 + v11 + v10;//Ritor1: :         ,    ,   
+                v12 = v9 + v11 + v10;
                 if ( v12 < v16 )
                 {
                   v16 = v12;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OurMath.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -0,0 +1,201 @@
+#include "OurMath.h"
+#include "MM7_data.h"
+
+//----- (00452969) --------------------------------------------------------
+stru193_math::stru193_math()
+{
+  double v3; // ST18_8@2
+
+  this->pTanTable[0] = 0;
+  this->pCosTable[0] = 65536;
+  this->pInvCosTable[0] = 65536;
+  for(int i = 1; i < (signed int)this->uIntegerHalfPi; i++)
+  {
+    v3 = (double)i * 3.141592653589793 / (double)uIntegerPi;
+    pTanTable[i] = (signed __int64)(tan(v3) * (double)this->pCosTable[0] + 0.5);
+    pCosTable[i] = (signed __int64)(cos(v3) * (double)this->pCosTable[0] + 0.5);
+    pInvCosTable[i] = (signed __int64)(1.0 / cos(v3) * (double)this->pCosTable[0] + 0.5);
+  }
+  for(int i = this->uIntegerHalfPi; i < 520; i++)
+  {
+    this->pTanTable[i] = 0xEFFFFFFFu;
+    this->pCosTable[i] = 0;
+    this->pInvCosTable[i] = 0xEFFFFFFFu;
+  }
+}
+
+
+//----- (00402CAE) --------------------------------------------------------
+int stru193_math::Cos(int angle)
+{
+  int v2; // eax@1
+
+  //a2: (angle - uIntegerHalfPi)    for  sin(angle)
+  //    (angle)                     for  cos(angle)
+
+  v2 = uDoublePiMask & angle;
+
+  if ( v2 > uIntegerPi )
+    v2 = uIntegerDoublePi - v2;
+  if ( v2 >= uIntegerHalfPi )
+    return -pCosTable[uIntegerPi - v2];
+  else
+    return pCosTable[v2];
+}
+
+
+//----- (0045281E) --------------------------------------------------------
+//    Calculates atan2(y/x)
+// return value: angle in integer format (multiplier of Pi/1024)  
+unsigned int stru193_math::Atan2(int x, int y)
+{
+  signed int quadrant;
+  __int64 dividend;
+  int quotient;
+  int lowIdx;
+  int highIdx;
+  int angle;
+
+  int X = x;
+  int Y = y;
+
+  if ( abs(X) < 65536 )
+  {
+    if ( (abs(Y) >> 15) >= abs(X) )
+      X = 0;
+  }
+
+  if ( !X )
+  {
+    if ( Y > 0 )
+    {
+      return uIntegerHalfPi;   //Pi/2
+    }
+    else
+    {
+      return uIntegerHalfPi + uIntegerPi; //3*(Pi/2)
+    }
+  }
+
+  if ( Y )
+  {
+    if ( X < 0 )
+    {
+      X = -X;
+      if ( Y > 0 )
+      {
+        quadrant = 4;        
+      }
+      else
+      {
+        quadrant = 3;        
+      }      
+    }
+    else
+    {
+      if ( Y > 0 )
+      {
+        quadrant = 1;       
+      }
+      else
+      {
+        quadrant = 2;
+      }      
+    }
+
+    if ( Y < 0 )
+      Y = -Y;
+
+    LODWORD(dividend) = Y << 16;
+    HIDWORD(dividend) = Y >> 16;
+    quotient = dividend / X;        
+
+    //looks like binary search
+    {
+      int i;
+      highIdx = uIntegerHalfPi;
+      lowIdx = 0;
+
+      for (i = 0; i < 6; ++i)
+      {        
+        if (quotient <= pTanTable[(lowIdx + highIdx) / 2])      
+          highIdx = (lowIdx + highIdx) / 2;
+        else
+          lowIdx = (lowIdx + highIdx) / 2;    
+      }
+    }
+
+    angle = lowIdx + 1;
+    while ( angle < (highIdx - 1) && quotient >= pTanTable[angle] )
+      ++angle;
+
+    switch (quadrant)
+    {
+    case 1: //X > 0, Y > 0
+      return angle;        
+
+    case 2: //X > 0, Y < 0
+      return uIntegerDoublePi - angle;   //2*Pi - angle
+
+    case 3: //X > 0, Y < 0
+      return uIntegerPi + angle;        //Pi + angle 
+
+    case 4: //X < 0, Y > 0
+      return uIntegerPi - angle;        //Pi - angle  
+    }
+
+    //should newer get here
+    return 0;
+  }
+
+  if ( X < 0 )    //Y == 0, X < 0
+    return uIntegerPi;  
+
+  return 0;
+}
+
+//----- (0042EBDB) --------------------------------------------------------
+int stru193_math::Sin(int angle)
+{
+  return Cos(angle - this->uIntegerHalfPi);
+}
+
+//----- (0042EBBE) --------------------------------------------------------
+//----- (004453C0) mm6-----------------------------------------------------
+//----- (004A1760) mm6_chinese---------------------------------------------
+__int64 fixpoint_mul(int a1, int a2)
+{
+  return ((__int64)a1 * (__int64)a2) >> 16;
+}
+
+__int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2)
+{
+  return fixpoint_mul(x1, x2) +
+    fixpoint_mul(y1, y2) +
+    fixpoint_mul(z1, z2);
+}
+
+//----- (004A1780) mm6_chinese---------------------------------------------
+__int64 fixpoint_div(int a1, int a2)
+{
+  return ((__int64)a1 << 16) / a2;
+}
+
+__int64 fixpoint_sub_unknown(int a1, int a2)
+{
+  return (((__int64)a1 << 16) * a2) >> 16;
+}
+
+//----- (0048B561) --------------------------------------------------------
+int fixpoint_from_float(float val)
+{
+  //  float X.Yf -> int XXXX YYYY
+  int left = floorf((val - 0.5f) + 0.5f);
+  int right = floorf((val - left) * 65536.0f);
+  return (left << 16) | right;
+}
+
+int fixpoint_from_int(int lhv, int rhv)
+{
+  return (lhv << 16) | rhv;
+}
\ No newline at end of file
--- a/Outdoor.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Outdoor.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -3858,7 +3858,7 @@
   else if ( pZ < v111 )//   
   {
     if ( is_on_water && fall_speed )
-      sub_42F960_create_object(pX, pY, v111);
+      SpriteObject::sub_42F960_create_object(pX, pY, v111);
     fall_speed = 0;
     pZ = v111;
     pParty->uFallStartY = v111;
--- a/Player.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Player.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -22,6 +22,8 @@
 #include "texts.h"
 
 #include "stru123.h"
+#include "stru298.h"
+#include "ObjectList.h"
 #include "mm7_data.h"
 #include "MM7.h"
 #include "SpriteObject.h"
@@ -7957,4 +7959,208 @@
     attNegativeMod = effectiveActorArmor + 15;
   }
   return (attPositiveMod > attNegativeMod);
+}
+
+
+//----- (0042ECB5) --------------------------------------------------------
+void Player::_42ECB5_PlayerAttacksActor()
+{
+  char *v5; // eax@8
+  unsigned int v9; // ecx@21
+  char *v11; // eax@26
+  unsigned int v12; // eax@47
+  SoundID v24; // [sp-4h] [bp-40h]@58
+
+  //result = pParty->pPlayers[uActiveCharacter-1].CanAct();
+  Player* player = &pParty->pPlayers[uActiveCharacter - 1];
+  if (!player->CanAct())
+    return;
+
+  CastSpellInfoHelpers::_427D48();
+    //v3 = 0;
+  if (pParty->Invisible())
+    pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
+
+    //v31 = player->pEquipment.uBow;
+  int bow_idx = player->pEquipment.uBow;
+  if (bow_idx && player->pInventoryItemList[bow_idx - 1].IsBroken())
+    bow_idx = 0;
+
+    //v32 = 0;
+  int wand_item_id = 0;
+    //v33 = 0;
+    //v4 = v1->pEquipment.uMainHand;
+  int laser_weapon_item_id = 0;
+
+  int main_hand_idx = player->pEquipment.uMainHand;
+  if (main_hand_idx)
+  {
+    ItemGen* item = &player->pInventoryItemList[main_hand_idx - 1];
+      //v5 = (char *)v1 + 36 * v4;
+    if (!item->IsBroken())
+    {
+		//v28b = &v1->pInventoryItems[v4].uItemID;
+        //v6 = v1->pInventoryItems[v4].uItemID;//*((int *)v5 + 124);
+      if (item->GetItemEquipType() == EQUIP_WAND)
+      {
+        if (item->uNumCharges <= 0)
+          player->pEquipment.uMainHand = 0; // wand discharged - unequip
+        else
+          wand_item_id = item->uItemID;//*((int *)v5 + 124);
+      }
+      else if (item->uItemID == ITEM_BLASTER || item->uItemID == ITEM_LASER_RIFLE)
+        laser_weapon_item_id = item->uItemID;//*((int *)v5 + 124);
+    }
+  }
+
+    //v30 = 0;
+    //v29 = 0;
+    //v28 = 0;
+    //v7 = pMouse->uPointingObjectID;
+
+  int target_pid = pMouse->uPointingObjectID;
+  int target_type = PID_TYPE(target_pid),
+      target_id = PID_ID(target_pid);
+  if (target_type != OBJECT_Actor || !pActors[target_id].CanAct())
+  {
+    target_pid = stru_50C198.FindClosestActor(5120, 0, 0);
+    target_type = PID_TYPE(target_pid);
+    target_id = PID_ID(target_pid);
+  }
+
+  Actor* actor = &pActors[target_id];
+  int actor_distance = 0;
+  if (target_type == OBJECT_Actor)
+  {
+    int distance_x = actor->vPosition.x - pParty->vPosition.x,
+        distance_y = actor->vPosition.y - pParty->vPosition.y,
+        distance_z = actor->vPosition.z - pParty->vPosition.z;
+    actor_distance = integer_sqrt(distance_x * distance_x + distance_y * distance_y + distance_z * distance_z) - actor->uActorRadius;
+    if (actor_distance < 0)
+      actor_distance = 0;
+  }
+
+  bool shooting_bow = false,
+       shotting_laser = false,
+       shooting_wand = false,
+       melee_attack = false;
+  if (laser_weapon_item_id)
+  {
+    shotting_laser = true;
+    _42777D_CastSpell_UseWand_ShootArrow(SPELL_LASER_PROJECTILE, uActiveCharacter - 1, 0, 0, uActiveCharacter + 8);
+  }
+  else if (wand_item_id)
+  {
+    shooting_wand = true;
+
+    int main_hand_idx = player->pEquipment.uMainHand;
+    _42777D_CastSpell_UseWand_ShootArrow(wand_spell_ids[player->pInventoryItemList[main_hand_idx - 1].uItemID - ITEM_WAND_FIRE], uActiveCharacter - 1, 8, 0, uActiveCharacter + 8);
+
+    if (!--player->pInventoryItemList[main_hand_idx - 1].uNumCharges)
+      player->pEquipment.uMainHand = 0;
+  }
+  else if (target_type == OBJECT_Actor && actor_distance <= 407.2)
+  {
+    melee_attack = true;
+
+    Vec3_int_ a3;
+    a3.x = actor->vPosition.x - pParty->vPosition.x;
+    a3.y = actor->vPosition.y - pParty->vPosition.y;
+    a3.z = actor->vPosition.z - pParty->vPosition.z;
+    Vec3_int_::Normalize(&a3.x, &a3.y, &a3.z);
+
+    DamageMonsterFromParty(PID(OBJECT_Player, uActiveCharacter - 1), target_id, &a3);
+    if (player->WearsItem(ITEM_ARTIFACT_SPLITTER, EQUIP_TWO_HANDED) || player->WearsItem(ITEM_ARTIFACT_SPLITTER, EQUIP_SINGLE_HANDED))
+          _42FA66_do_explosive_impact(actor->vPosition.x, actor->vPosition.y, actor->vPosition.z + actor->uActorHeight / 2, 0, 512, uActiveCharacter);
+  }
+  else if (bow_idx)
+  {
+    shooting_bow = true;
+    _42777D_CastSpell_UseWand_ShootArrow(SPELL_BOW_ARROW, uActiveCharacter - 1, 0, 0, 0);
+  }
+  else
+  {
+    melee_attack = true;
+    ; // actor out of range or no actor; no ranged weapon so melee attacking air
+  }
+
+  if (!pParty->bTurnBasedModeOn && melee_attack) // wands, bows & lasers will add recovery while shooting spell effect
+  {
+    int recovery = player->GetAttackRecoveryTime(false);
+    if (recovery < 30 )
+      recovery = 30;
+    player->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * (double)recovery * 2.133333333333333);
+  }
+
+  int v34 = 0;
+  if (shooting_wand)
+    return;
+  else if (shooting_bow)
+  {
+    v34 = 5;
+    player->PlaySound(SPEECH_50, 0);
+  }
+  if (shotting_laser)
+    v34 = 7;
+  else
+  {
+    int main_hand_idx = player->pEquipment.uMainHand;
+    if (player->HasItemEquipped(EQUIP_TWO_HANDED))
+      v34 = player->pInventoryItemList[main_hand_idx - 1].GetPlayerSkillType();
+    pTurnEngine->ApplyPlayerAction();
+  }
+
+  switch (v34)
+  {
+    case 0: pAudioPlayer->PlaySound(SOUND_81, 0, 0, -1, 0, 0, 0, 0); break;
+    case 1: pAudioPlayer->PlaySound(SOUND_84, 0, 0, -1, 0, 0, 0, 0); break;
+    case 2: pAudioPlayer->PlaySound(SOUND_85, 0, 0, -1, 0, 0, 0, 0); break;
+    case 3: pAudioPlayer->PlaySound(SOUND_78, 0, 0, -1, 0, 0, 0, 0); break;
+    case 4: pAudioPlayer->PlaySound(SOUND_80, 0, 0, -1, 0, 0, 0, 0); break;
+    case 5: pAudioPlayer->PlaySound(SOUND_71, 0, 0, -1, 0, 0, 0, 0); break;
+    case 6: pAudioPlayer->PlaySound(SOUND_83, 0, 0, -1, 0, 0, 0, 0); break;
+    case 7: pAudioPlayer->PlaySound(SOUND_67, 0, 0, -1, 0, 0, 0, 0); break;
+  }
+}
+
+
+//----- (0042FA66) --------------------------------------------------------
+void Player::_42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6)
+{
+  unsigned __int16 v9; // ax@5
+
+  SpriteObject a1a; // [sp+Ch] [bp-74h]@1
+  //SpriteObject::SpriteObject(&a1a);
+  a1a.uType = 600;
+  a1a.stru_24.Reset();
+
+  a1a.spell_id = SPELL_FIRE_FIREBALL;
+  a1a.spell_level = 8;
+  a1a.spell_skill = 3;
+  v9 = 0;
+  for ( uint i = 0; i < pObjectList->uNumObjects; ++i )
+  {
+    if ( a1a.uType == pObjectList->pObjects[i].uObjectID )
+      v9 = i;
+  }
+  a1a.uObjectDescID = v9;
+  a1a.vPosition.x = a1;
+  a1a.vPosition.y = a2;
+  a1a.vPosition.z = a3;
+  a1a.uAttributes = 0;
+  a1a.uSectorID = pIndoor->GetSector(a1, a2, a3);
+  a1a.uSpriteFrameID = 0;
+  a1a.spell_target_pid = 0;
+  a1a.field_60_distance_related_prolly_lod = 0;
+  a1a.uFacing = 0;
+  a1a.uSoundID = 0;
+  if ( a6 >= 1 || a6 <= 4 )
+    a1a.spell_caster_pid = PID(OBJECT_Player, a6 - 1);
+  else
+    a1a.spell_caster_pid = 0;
+
+  int id = a1a.Create(0, 0, 0, 0);
+  if (id != -1)
+    AttackerInfo.Add(PID(OBJECT_Item, id), a5, SLOWORD(a1a.vPosition.x), SLOWORD(a1a.vPosition.y),
+    SLOWORD(a1a.vPosition.z), 0, 0);
 }
\ No newline at end of file
--- a/Player.h	Wed Apr 02 20:53:35 2014 +0600
+++ b/Player.h	Wed Apr 02 20:53:47 2014 +0600
@@ -675,6 +675,9 @@
   ItemGen* GetItem(unsigned int PlayerEquipment::* itemPos);
   int GetPlayerIndex();
 
+  static void _42ECB5_PlayerAttacksActor();
+  static void _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6);
+
   std::array<__int64, 20> pConditions;
   unsigned __int64 uExperience;
   char pName[16];
--- a/Render.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Render.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -7331,17 +7331,11 @@
 //----- (004A68EF) --------------------------------------------------------
 void Render::DrawMasked(signed int a2, signed int a3, Texture *pTexture, unsigned __int16 mask)
 {
-  Texture *v4; // edi@2
   unsigned int v5; // ebx@4
-  //unsigned __int16 *v6; // eax@4
-  signed int v7; // edx@5
-  int v8; // edx@6
-  signed int v9; // edx@7
   int v10; // edx@8
   signed int v11; // edx@9
   signed int v12; // esi@12
   signed int v13; // esi@15
-  unsigned int v14; // edx@17
   signed int v15; // esi@18
   unsigned __int8 *v16; // ebx@22
   char v17; // zf@28
@@ -7350,65 +7344,54 @@
   int v20; // [sp+1Ch] [bp-4h]@4
   int v21; // [sp+28h] [bp+8h]@24
   unsigned int v22; // [sp+2Ch] [bp+Ch]@22
-  unsigned int pTexturea; // [sp+30h] [bp+10h]@11
 
   if (!uNumSceneBegins || !pTexture)
     return;
 
-    v4 = pTexture;
-
-      if ( pTexture->pPalette16 )
-      {
-        v5 = pTexture->uTextureHeight;
-        //v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
-        v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask;
-        v20 = pTexture->uTextureWidth;
-        v18 = pTexture->uTextureWidth;
-        int clipped_out_x = a2;
-        int clipped_out_y = a3;
-        if ( this->bClip )
-        {
-          v7 = this->uClipX;
-          if ( a2 < v7 )
-          {
-            v8 = v7 - a2;
-            v19 += v8;
-            v20 += a2 - this->uClipX;
-            //v6 += v8;
-            clipped_out_x = uClipX;
-          }
-          v9 = this->uClipY;
-          v5 = pTexture->uTextureHeight;
-          if ( a3 < v9 )
-          {
-            v10 = v9 - a3;
-            v19 += v18 * v10;
-            v5 = a3 - this->uClipY + pTexture->uTextureHeight;
-            v4 = pTexture;
-            //v6 += this->uTargetSurfacePitch * v10;
-            clipped_out_y = uClipY;
-          }
-          v11 = this->uClipX;
-          if ( v11 < a2 )
-            v11 = a2;
-          pTexturea = this->uClipZ;
-          if ( v11 + v20 > (signed int)pTexturea )
-          {
-            v12 = this->uClipX;
-            if ( v12 < a2 )
-              v12 = a2;
-            v20 = pTexturea - v12;
+  if ( pTexture->pPalette16 )
+  {
+    v5 = pTexture->uTextureHeight;
+    //v6 = &this->pTargetSurface[a2 + a3 * this->uTargetSurfacePitch];
+    v19 = pTexture->pLevelOfDetail0_prolly_alpha_mask;
+    v20 = pTexture->uTextureWidth;
+    v18 = pTexture->uTextureWidth;
+    int clipped_out_x = a2;
+    int clipped_out_y = a3;
+    if ( this->bClip )
+    {
+      if ( a2 < this->uClipX )
+      {
+        v19 += this->uClipX - a2;
+        v20 += a2 - this->uClipX;
+        clipped_out_x = uClipX;
+      }
+      v5 = pTexture->uTextureHeight;
+      if ( a3 < this->uClipY )
+      {
+        v10 = this->uClipY - a3;
+        v19 += v18 * v10;
+        v5 = a3 - this->uClipY + pTexture->uTextureHeight;
+        clipped_out_y = uClipY;
+      }
+      v11 = this->uClipX;
+      if ( this->uClipX < a2 )
+        v11 = a2;
+      if ( v11 + v20 > (signed int)this->uClipZ )
+      {
+        v12 = this->uClipX;
+        if ( v12 < a2 )
+          v12 = a2;
+            v20 = this->uClipZ - v12;
           }
           v13 = this->uClipY;
-          if ( v13 < a3 )
+          if ( this->uClipY < a3 )
             v13 = a3;
-          v14 = this->uClipW;
-          if ( (signed int)(v5 + v13) > (signed int)v14 )
+          if ( (signed int)(v5 + v13) > (signed int)this->uClipW )
           {
             v15 = this->uClipY;
-            if ( v15 < a3 )
+            if ( this->uClipY < a3 )
               v15 = a3;
-            v5 = v14 - v15;
+            v5 = this->uClipW - v15;
           }
         }
         
@@ -7418,7 +7401,7 @@
           for (int x = 0; x < v20; ++x)
           {
                 if ( *v16 )
-                  WritePixel16(clipped_out_x + x, clipped_out_y + y, v4->pPalette16[*v16] & mask);
+                  WritePixel16(clipped_out_x + x, clipped_out_y + y, pTexture->pPalette16[*v16] & mask);
                 ++v16;
           }
             v16 += v18 - v20;
--- a/Spells.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/Spells.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -47,120 +47,140 @@
   {545, 0},
   {555, 0}
 }};
+
+
+
+SpellData::SpellData( __int16 innormalMana, __int16 inExpertLevelMana, __int16 inMasterLevelMana, __int16 inMagisterLevelMana,
+                     __int16 inNormalLevelRecovery, __int16 inExpertLevelRecovery, __int16 inMasterLevelRecovery, __int16 inMagisterLevelRecovery,
+                     __int8 inbaseDamage, __int8 inbonusSkillDamage, __int16 instats ):
+uNormalLevelMana(innormalMana),
+uExpertLevelMana(inExpertLevelMana),
+uMasterLevelMana(inMasterLevelMana),
+uMagisterLevelMana(inMagisterLevelMana),
+uNormalLevelRecovery(inNormalLevelRecovery),
+uExpertLevelRecovery(inExpertLevelRecovery),
+uMasterLevelRecovery(inMasterLevelRecovery),
+uMagisterLevelRecovery(inMagisterLevelRecovery),
+baseDamage(inbaseDamage),
+bonusSkillDamage(inbonusSkillDamage),
+stats(instats)
+{
+
+}
+
  //9 spellbook pages  11 spells per page 9*11 =99 +1 zero struct at 0. It counted from 1!
 std::array<SpellData, 100> pSpellDatas={{
-					 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+					 SpellData(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
 
-					 {1, 1, 1, 1, 60, 60, 60, 40, 0, 0},//0
-	                 {2, 2, 2, 2, 110, 110, 100, 90, 768, 0},
-	                 {3, 3, 3, 3, 120, 120, 120, 120, 0, 0},
-	                 {4, 4, 4, 4, 120, 120, 120, 120, 0, 0},
-	                 {5, 5, 5, 5, 120, 120, 120, 120, 0, 0},
-	                 {8, 8, 8, 8, 100, 100, 90, 80, 1536, 0},
-	                 {10, 10, 10, 10, 150, 150, 150, 150, 1536, 0},
-	                 {15, 15, 15, 15, 120, 120, 120, 120, 1536, 0},
-	                 {20, 20, 20, 20, 100, 100, 100, 90, 264, 0},
-	                 {25, 25, 25, 25, 100, 100, 100, 90, 268, 0},
-	                 {30, 30, 30, 30, 90, 90, 90, 90, 3855, 0},
+             SpellData(1, 1, 1, 1, 60, 60, 60, 40, 0, 0, 0),//0 fire
+	           SpellData(2, 2, 2, 2, 110, 110, 100, 90, 3, 3, 0),
+	           SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(4, 4, 4, 4, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(8, 8, 8, 8, 100, 100, 90, 80, 0, 6, 0),
+	           SpellData(10, 10, 10, 10, 150, 150, 150, 150, 0, 6, 0),
+	           SpellData(15, 15, 15, 15, 120, 120, 120, 120, 0, 6, 0),
+	           SpellData(20, 20, 20, 20, 100, 100, 100, 90, 8, 1, 0),
+	           SpellData(25, 25, 25, 25, 100, 100, 100, 90, 12, 1, 0),
+	           SpellData(30, 30, 30, 30, 90, 90, 90, 90, 15, 15, 0),
 
-	                 {1, 1, 1, 0, 60, 60, 60, 60, 0, 0},  //1
-	                 {2, 2, 2, 2, 120, 120, 120, 100, 0, 0},
-	                 {3, 3, 3, 3, 120, 120, 120, 120, 0, 0},
-	                 {4, 4, 4, 4, 110, 100, 90, 80, 258, 0},
-	                 {5, 5, 5, 5,  90, 90,  70, 50, 0, 0},
-	                 {8, 8, 8, 8, 120, 120, 120, 120, 0, 0},
-	                 {10, 10, 10, 10, 100, 100, 90, 70, 2048, 0},
-	                 {15, 15, 15, 15, 200, 200, 200, 200, 0, 0},
-	                 {20, 20, 20, 20, 100, 100, 100, 90, 2570, 0},
-	                 {25, 25, 25, 25, 250, 250, 250, 250, 0, 0},
-	                 {30, 30, 30, 30, 90, 90, 90, 90, 276, 0},
+	           SpellData(1, 1, 1, 0, 60, 60, 60, 60, 0, 0, 0),  //1 air
+	           SpellData(2, 2, 2, 2, 120, 120, 120, 100, 0, 0, 0),
+	           SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(4, 4, 4, 4, 110, 100, 90, 80, 2, 1, 0),
+	           SpellData(5, 5, 5, 5,  90, 90,  70, 50, 0, 0, 0),
+	           SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(10, 10, 10, 10, 100, 100, 90, 70, 0, 8, 0),
+	           SpellData(15, 15, 15, 15, 200, 200, 200, 200, 0, 0, 0),
+	           SpellData(20, 20, 20, 20, 100, 100, 100, 90, 10, 10, 0),
+	           SpellData(25, 25, 25, 25, 250, 250, 250, 250, 0, 0, 0),
+	           SpellData(30, 30, 30, 30, 90, 90, 90, 90, 20, 1, 0),
 
-	                 {1, 1, 1, 1, 60, 60, 60, 20, 0, 0},  //2
-	                 {2, 2, 2, 2, 110, 100, 90, 70, 514, 0},
-	                 {3, 3, 3, 3, 120, 120, 120, 120, 0, 0},
-	                 {4, 4, 4, 4, 110, 100, 90, 80, 1024, 0},
-	                 {5, 5, 5, 5, 150, 150, 150, 150, 0, 0},
-	                 {8, 8, 8, 8, 200, 200, 200, 200, 0, 0},
-	                 {10, 10, 10, 10, 100, 100, 90, 80, 2313, 0},
-	                 {15, 15, 15, 15, 140, 140, 140, 140, 0, 0},
-	                 {20, 20, 20, 20, 200, 200, 200, 200, 0, 0},
-	                 {25, 25, 25, 25, 80, 80, 80, 80, 780, 0},
-	                 {30, 30, 30, 30, 250, 250, 250, 250, 0, 0},
+	           SpellData(1, 1, 1, 1, 60, 60, 60, 20, 0, 0, 0),  //2 water
+	           SpellData(2, 2, 2, 2, 110, 100, 90, 70, 2, 2, 0),
+	           SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(4, 4, 4, 4, 110, 100, 90, 80, 0, 4, 0),
+	           SpellData(5, 5, 5, 5, 150, 150, 150, 150, 0, 0, 0),
+	           SpellData(8, 8, 8, 8, 200, 200, 200, 200, 0, 0, 0),
+	           SpellData(10, 10, 10, 10, 100, 100, 90, 80, 9, 9, 0),
+	           SpellData(15, 15, 15, 15, 140, 140, 140, 140, 0, 0, 0),
+	           SpellData(20, 20, 20, 20, 200, 200, 200, 200, 0, 0, 0),
+	           SpellData(25, 25, 25, 25, 80, 80, 80, 80, 12, 3, 0),
+	           SpellData(30, 30, 30, 30, 250, 250, 250, 250, 0, 0, 0),
 
-	                 {1, 1, 1, 1, 80, 80, 80, 80, 0, 0},  //3
-	                 {2, 2, 2, 2, 100, 100, 100, 100, 0, 0},
-	                 {3, 3, 3, 3, 120, 120, 120, 120, 0, 0},
-	                 {4, 4, 4, 4, 110, 100, 90, 80, 773, 0},
-	                 {5, 5, 5, 5, 120, 120, 120, 120, 0, 0},
-	                 {8, 8, 8, 8, 100, 100, 90, 80, 2304, 0},
-	                 {10, 10, 10, 10, 140, 140, 140, 140, 0, 0},
-	                 {15, 15, 15, 15, 90, 90, 90, 80, 2048, 0},
-	                 {20, 20, 20, 20, 150, 150, 150, 150, 0, 0},
-	                 {25, 25, 25, 25, 100, 100, 100, 90, 276, 0},
-	                 {30, 30, 30, 30, 90, 90, 90, 90, 25, 0},
+	           SpellData(1, 1, 1, 1, 80, 80, 80, 80, 0, 0, 0),  //3 earth
+	           SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0),
+	           SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(4, 4, 4, 4, 110, 100, 90, 80, 5, 3, 0),
+	           SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(8, 8, 8, 8, 100, 100, 90, 80, 0, 9, 0),
+	           SpellData(10, 10, 10, 10, 140, 140, 140, 140, 0, 0, 0),
+	           SpellData(15, 15, 15, 15, 90, 90, 90, 80, 0, 8, 0),
+	           SpellData(20, 20, 20, 20, 150, 150, 150, 150, 0, 0, 0),
+	           SpellData(25, 25, 25, 25, 100, 100, 100, 90, 20, 1, 0),
+	           SpellData(30, 30, 30, 30, 90, 90, 90, 90, 25, 0, 0),
 
-	                 {1, 1, 1, 1, 100, 100, 100, 100, 0, 0},  //4
-	                 {2, 2, 2, 2, 100, 100, 100, 100, 0, 0},
-	                 {3, 3, 3, 3, 90, 90, 90, 90, 0, 0},
-	                 {4, 4, 4, 4, 120, 120, 120, 120, 0, 0},
-	                 {5, 5, 5, 5, 120, 120, 120, 120, 0, 0},
-	                 {8, 8, 8, 8, 120, 120, 120, 120, 0, 0},
-	                 {10, 10, 10, 10, 120, 120, 120, 120, 0, 0},
-	                 {15, 15, 15, 15, 100, 100, 100, 100, 2058, 0},
-	                 {20, 20, 20, 20, 240, 240, 240, 240, 0, 0},
-	                 {25, 25, 25, 25, 150, 150, 150, 150, 0, 0},
-	                 {30, 30, 30, 30, 1000, 1000, 1000, 1000, 0, 0},
+	           SpellData(1, 1, 1, 1, 100, 100, 100, 100, 0, 0, 0),  //4 spirit
+	           SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0),
+	           SpellData(3, 3, 3, 3, 90, 90, 90, 90, 0, 0, 0),
+	           SpellData(4, 4, 4, 4, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(5, 5, 5, 5, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(15, 15, 15, 15, 100, 100, 100, 100, 10, 8, 0),
+	           SpellData(20, 20, 20, 20, 240, 240, 240, 240, 0, 0, 0),
+	           SpellData(25, 25, 25, 25, 150, 150, 150, 150, 0, 0, 0),
+	           SpellData(30, 30, 30, 30, 1000, 1000, 1000, 1000, 0, 0, 0),
 
-	                 {1, 1, 1, 1, 120, 120, 120, 120, 0, 0},  //5
-	                 {2, 2, 2, 2, 110, 110, 110, 110, 771, 0},
-	                 {3, 3, 3, 3, 120, 120, 120, 120, 0, 0},
-	                 {4, 4, 4, 4, 110, 100, 90, 80, 0, 0},
-	                 {5, 5, 5, 5, 100, 100, 100, 100, 0, 0},
-	                 {8, 8, 8, 8, 120, 120, 120, 120, 0, 0},
-	                 {10, 10, 10, 10, 120, 120, 120, 120, 0, 0},
-	                 {15, 15, 15, 15, 80, 80, 80, 80, 0, 0},
-	                 {20, 20, 20, 20, 120, 120, 120, 120, 0, 0},
-	                 {25, 25, 25, 25, 110, 110, 110, 100, 268, 0},
-	                 {30, 30, 30, 30, 120, 120, 120, 120, 0, 0},
+	           SpellData(1, 1, 1, 1, 120, 120, 120, 120, 0, 0, 0),  //5 mind
+	           SpellData(2, 2, 2, 2, 110, 110, 110, 110, 3, 3, 0),
+	           SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(4, 4, 4, 4, 110, 100, 90, 80, 0, 0, 0),
+	           SpellData(5, 5, 5, 5, 100, 100, 100, 100, 0, 0, 0),
+	           SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(15, 15, 15, 15, 80, 80, 80, 80, 0, 0, 0),
+	           SpellData(20, 20, 20, 20, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(25, 25, 25, 25, 110, 110, 110, 100, 12, 12, 0),
+	           SpellData(30, 30, 30, 30, 120, 120, 120, 120, 0, 0, 0),
 
-	                 {1, 1, 1, 1, 120, 120, 120, 120, 0, 0},  //6
-	                 {2, 2, 2, 2, 100, 100, 100, 100, 0, 0},
-	                 {3, 3, 3, 3, 120, 120, 120, 120, 0, 0},
-	                 {4, 4, 4, 4, 110, 100, 90, 80, 520, 0},
-	                 {5, 5, 5, 5, 110, 110, 110, 110, 0, 0},
-	                 {8, 8, 8, 8, 120, 120, 120, 120, 0, 0},
-	                 {10, 10, 10, 10, 120, 120, 120, 120, 0, 0},
-	                 {15, 15, 15, 15, 120, 120, 120, 120, 0, 0},
-	                 {20, 20, 20, 20, 120, 120, 120, 120, 0, 0},
-	                 {25, 25, 25, 25, 110, 110, 110, 100, 1310, 0},
-	                 {30, 30, 30, 30, 100, 100, 100, 100, 0, 0},
+	           SpellData(1, 1, 1, 1, 120, 120, 120, 120, 0, 0, 0),  //6 body
+	           SpellData(2, 2, 2, 2, 100, 100, 100, 100, 0, 0, 0),
+	           SpellData(3, 3, 3, 3, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(4, 4, 4, 4, 110, 100, 90, 80, 8, 2, 0),
+	           SpellData(5, 5, 5, 5, 110, 110, 110, 110, 0, 0, 0),
+	           SpellData(8, 8, 8, 8, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(10, 10, 10, 10, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(15, 15, 15, 15, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(20, 20, 20, 20, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(25, 25, 25, 25, 110, 110, 110, 100, 30, 5, 0),
+	           SpellData(30, 30, 30, 30, 100, 100, 100, 100, 0, 0, 0),
 
-	                 {5, 5, 5, 5, 110, 100, 90, 80, 1024, 0},   //7
-	                 {10, 10, 10, 10, 120, 110, 100, 90, 4112, 0},
-	                 {15, 15, 15, 15, 120, 110, 100, 90, 0, 0},
-	                 {20, 20, 20, 20, 160, 140, 120, 100, 0, 0},
-	                 {25, 25, 25, 25, 140, 140, 140, 140, 0, 0},
-	                 {30, 30, 30, 30, 500, 500, 500, 500, 0, 0},
-	                 {35, 35, 35, 35, 135, 135, 120, 100, 281, 0},
-	                 {40, 40, 40, 40, 500, 500, 500, 500, 0, 0},
-	                 {45, 45, 45, 45, 250, 250, 250, 250, 0, 0},
-	                 {50, 50, 50, 50, 150, 150, 150, 135, 5140, 0},
-	                 {55, 55, 55, 55, 300, 300, 300, 300, 0, 0},
+	           SpellData(5, 5, 5, 5, 110, 100, 90, 80, 0, 4, 0),   //7 light
+	           SpellData(10, 10, 10, 10, 120, 110, 100, 90, 16, 16, 0),
+	           SpellData(15, 15, 15, 15, 120, 110, 100, 90, 0, 0, 0),
+	           SpellData(20, 20, 20, 20, 160, 140, 120, 100, 0, 0, 0),
+	           SpellData(25, 25, 25, 25, 140, 140, 140, 140, 0, 0, 0),
+	           SpellData(30, 30, 30, 30, 500, 500, 500, 500, 0, 0, 0),
+	           SpellData(35, 35, 35, 35, 135, 135, 120, 100, 25, 1, 0),
+	           SpellData(40, 40, 40, 40, 500, 500, 500, 500, 0, 0, 0),
+	           SpellData(45, 45, 45, 45, 250, 250, 250, 250, 0, 0, 0),
+	           SpellData(50, 50, 50, 50, 150, 150, 150, 135, 20, 20, 0),
+	           SpellData(55, 55, 55, 55, 300, 300, 300, 300, 0, 0, 0),
 
-	                 {10, 10, 10, 10, 140, 140, 140, 140, 0, 0},  //8
-	                 {15, 15, 15, 15, 120, 110, 100, 90, 2585, 0},
-	                 {20, 20, 20, 20, 120, 100, 90, 120, 0, 0},
-	                 {25, 25, 25, 25, 120, 120, 120, 120, 0, 0},
-	                 {30, 30, 30, 30, 90, 90, 80, 70, 1542, 0},
-	                 {35, 35, 35, 35, 120, 120, 100, 80, 0, 0},
-	                 {40, 40, 40, 40, 110, 110, 110, 110, 0, 0},
-	                 {45, 45, 45, 45, 200, 200, 200, 150, 0, 0},
-	                 {50, 50, 50, 50, 120, 120, 120, 100, 6400, 0},
-	                 {55, 55, 55, 55, 250, 250, 250, 250, 306, 0},
-	                 {60, 60, 60, 60, 300, 300, 300, 300, 2073, 0}
+	           SpellData(10, 10, 10, 10, 140, 140, 140, 140, 0, 0, 0),  //8 dark
+	           SpellData(15, 15, 15, 15, 120, 110, 100, 90, 25, 10, 0),
+	           SpellData(20, 20, 20, 20, 120, 100, 90, 120, 0, 0, 0),
+	           SpellData(25, 25, 25, 25, 120, 120, 120, 120, 0, 0, 0),
+	           SpellData(30, 30, 30, 30, 90, 90, 80, 70, 6, 6, 0),
+	           SpellData(35, 35, 35, 35, 120, 120, 100, 80, 0, 0, 0),
+	           SpellData(40, 40, 40, 40, 110, 110, 110, 110, 0, 0, 0),
+	           SpellData(45, 45, 45, 45, 200, 200, 200, 150, 0, 0, 0),
+	           SpellData(50, 50, 50, 50, 120, 120, 120, 100, 0, 25, 0),
+	           SpellData(55, 55, 55, 55, 250, 250, 250, 250, 50, 1, 0),
+	           SpellData(60, 60, 60, 60, 300, 300, 300, 300, 25, 8, 0)
   }};
 
-
 std::array<unsigned int, 25> wand_spell_ids =
 {
 // 135 Wand of Fire               136 Wand of Sparks             137 Wand of Poison             138 Wand of Stunning           139 Wand of Harm
@@ -330,773 +350,391 @@
     if ((i % 11)==0)
       strtok(NULL, "\r");
   }
-
 }
 //----- (00448DF8) --------------------------------------------------------
 void __fastcall EventCastSpell(int uSpellID, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz)//sub_448DF8
 {
   int v9; // esi@1
-  double v10; // st7@4
-  double v11; // st6@4
-  double v12; // st5@4
+  signed __int64 v10; // st7@4
+  signed __int64 v11; // st6@4
+  signed __int64 v12; // st5@4
   double v13; // st7@6
   int v14; // ST44_4@7
-  signed int v15; // ebx@9
-  signed int v16; // edx@15
-  char *v17; // ecx@16
-  unsigned __int16 v18; // ax@20
-  char *v19; // ecx@31
-  int v20; // edx@35
-  signed int v21; // edx@37
-  char *v22; // ecx@38
-  unsigned __int16 v23; // ax@41
+  uint skillMasteryPlusOne; // ebx@9
+  uint v16; // edx@15
   int i; // esi@42
-  signed int v25; // edx@55
-  char *v26; // ecx@56
-  unsigned __int16 v27; // ax@59
   int j; // esi@60
-  signed int v29; // edx@66
-  char *v30; // ecx@67
-  unsigned __int16 v31; // ax@70
-  //Player *v32; // eax@80
-  //unsigned __int16 v33; // si@85
-  int v34; // eax@96
-  int v35; // eax@97
   unsigned __int64 v36; // qax@99
   SpellBuff *v37; // ecx@99
   int v38; // esi@103
   signed __int64 v39; // qax@105
-  int v40; // ebx@108
-  int v41; // ebx@109
   int v42; // esi@111
   int v43; // ebx@111
-  int v44; // eax@117
-  //unsigned __int16 v45; // si@137
-  unsigned __int16 v46; // [sp-8h] [bp-BCh]@99
   int v47; // [sp-4h] [bp-B8h]@35
-  unsigned __int16 v48; // [sp-4h] [bp-B8h]@99
   int v49; // [sp+0h] [bp-B4h]@35
-  int v50; // [sp+0h] [bp-B4h]@99
-  int v51; // [sp+4h] [bp-B0h]@35
-  unsigned __int8 v52; // [sp+4h] [bp-B0h]@99
-  float v53; // [sp+14h] [bp-A0h]@4
-  float v54; // [sp+18h] [bp-9Ch]@4
   int v55; // [sp+28h] [bp-8Ch]@7
   unsigned int yaw; // [sp+30h] [bp-84h]@7
   int pitch; // [sp+34h] [bp-80h]@7
-  //SpriteObject a1; // [sp+38h] [bp-7Ch]@12
-  int v59; // [sp+A8h] [bp-Ch]@1
   int v60; // [sp+ACh] [bp-8h]@1
-  //int spellnum_; // [sp+B0h] [bp-4h]@1
-  //signed int levela; // [sp+BCh] [bp+8h]@80
   int a6_4; // [sp+C8h] [bp+14h]@117
-  float a7a; // [sp+CCh] [bp+18h]@6
-  signed int a7b; // [sp+CCh] [bp+18h]@12
   int a7c; // [sp+CCh] [bp+18h]@29
   int a7d; // [sp+CCh] [bp+18h]@55
-  float a8a; // [sp+D0h] [bp+1Ch]@6
+  signed __int64 xSquared; // [sp+D0h] [bp+1Ch]@6
   int a8b; // [sp+D0h] [bp+1Ch]@37
   int a8c; // [sp+D0h] [bp+1Ch]@55
-  float toza; // [sp+D4h] [bp+20h]@6
+  signed __int64 ySquared; // [sp+D4h] [bp+20h]@6
 
   v9 = 0;
-  v59 = uSkillLevel + 1;
+  skillMasteryPlusOne = uSkillLevel + 1;
   //spellnum_ = uSpellID;
   v60 = 0;
   if ( tox || toy || toz )
   {
-    v10 = (double)tox - (double)fromx;
-    v53 = v10;
-    v11 = (double)toy - (double)fromy;
-    v54 = v11;
-    v12 = (double)toz;
+    v10 = tox - fromx;
+    v11 = toy - fromy;
+    v12 = toz - fromz;
   }
   else
   {
-    v10 = (double)pParty->vPosition.x - (double)fromx;
-    v53 = v10;
-    v11 = (double)pParty->vPosition.y - (double)fromy;
-    v54 = v11;
-    v12 = (double)(pParty->vPosition.z + pParty->sEyelevel);
+    v10 = pParty->vPosition.x - fromx;
+    v11 = pParty->vPosition.y - fromy;
+    v12 = (pParty->vPosition.z + pParty->sEyelevel) - fromz;
   }
-  a7a = v12 - (double)fromz;
-  toza = v11 * v11;
-  a8a = v10 * v10;
-  v13 = sqrt(a7a * a7a + a8a + toza);
+  v13 = sqrt(v10 * v10 + v11 * v11 + v12 * v12);
   if ( v13 <= 1.0 )
   {
-    LOBYTE(v55) = 1;
+    v55 = 1;
     yaw = 0;
     pitch = 0;
   }
   else
   {
-    v55 = (signed __int64)v13;
-    v14 = (signed __int64)sqrt(a8a + toza);
-    yaw = stru_5C6E00->Atan2((signed __int64)v53, (signed __int64)v54);
-    pitch = stru_5C6E00->Atan2(v14, (signed __int64)a7a);
+    v55 = (int)v13;
+    ySquared = v11 * v11;
+    xSquared = v10 * v10;
+    v14 = (int)sqrt(xSquared + ySquared);
+    yaw = stru_5C6E00->Atan2((int)v10, (int)v11);
+    pitch = stru_5C6E00->Atan2(v14, (int)v12);
   }
-  v15 = v59;
-  if ( v59 <= 0 || v59 > 4 )
-    v15 = 1;
-  a7b = v15;
+  Assert(skillMasteryPlusOne > 0 && skillMasteryPlusOne <= 4, "Invalid mastery level");
 
   SpriteObject a1; // [sp+38h] [bp-7Ch]@12
   //SpriteObject::SpriteObject(&a1);
 
-  a1.uType = stru_4E3ACC[uSpellID].uType;
-  if ( uSpellID > 58 )
-  {
-    if ( uSpellID == SPELL_BODY_PROTECTION_FROM_BODY )
-      goto LABEL_117;
-    if ( uSpellID != SPELL_LIGHT_DAY_OF_THE_GODS )
-      return;
-    v40 = v15 - 2;
-    if ( v40 )
-    {
-      v41 = v40 - 1;
-      if ( !v41 )
-      {
-        v42 = 14400 * uSkill;
-        v43 = 4 * uSkill + 10;
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
-        pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
-        v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
-        v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
-        v36 = pParty->uTimePlayed + v39;
-        v37->Apply(v36, a7b, v43, 0, 0);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-        return;
-      }
-      if ( v41 == 1 )
-      {
-        v42 = 18000 * uSkill;
-        v43 = 5 * uSkill + 10;
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
-       pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
-       v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
-       v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
-       v36 = pParty->uTimePlayed + v39;
-       v37->Apply(v36, a7b, v43, 0, 0);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-        return;
-      }
-    }
-    v42 = 10800 * uSkill;
-    v43 = 3 * uSkill + 10;
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 0);
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 1u);
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 2u);
-    pGame->pStru6Instance->SetPlayerBuffAnim(0x53u, 3u);
-    v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
-    v37 = &pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS];
-    v36 = pParty->uTimePlayed + v39;
-    v37->Apply(v36, a7b, v43, 0, 0);
-    pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-    return;
-  }
-  if ( uSpellID != 58 )
+  switch ( uSpellID )
   {
-    switch ( uSpellID )
-    {
-      case SPELL_FIRE_FIRE_BOLT:
-      case SPELL_FIRE_FIREBALL:
-      case SPELL_AIR_LIGHNING_BOLT:
-      case SPELL_WATER_ICE_BOLT:
-      case SPELL_WATER_ACID_BURST:
-      case SPELL_WATER_ICE_BLAST:
-      case SPELL_EARTH_BLADES:
-      case SPELL_EARTH_ROCK_BLAST:
-        a1.stru_24.Reset();
-        v16 = 0;
-        a1.spell_id = uSpellID;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
+    case SPELL_FIRE_FIRE_BOLT:
+    case SPELL_FIRE_FIREBALL:
+    case SPELL_AIR_LIGHNING_BOLT:
+    case SPELL_WATER_ICE_BOLT:
+    case SPELL_WATER_ACID_BURST:
+    case SPELL_WATER_ICE_BLAST:
+    case SPELL_EARTH_BLADES:
+    case SPELL_EARTH_ROCK_BLAST:
+    case SPELL_WATER_POISON_SPRAY:
+    case SPELL_AIR_SPARKS:
+    case SPELL_EARTH_DEATH_BLOSSOM:
+      a1.uType = stru_4E3ACC[uSpellID].uType;
+      a1.stru_24.Reset();
+      a1.spell_id = uSpellID;
+      a1.spell_level = uSkill;
+      a1.spell_skill = skillMasteryPlusOne;
+      v16 = 0;
+      while (v16 < pObjectList->uNumObjects)
+      {
+        if ( a1.uType == pObjectList->pObjects[v16].uObjectID)
         {
-          //v18 = 0;
-          a1.uObjectDescID = 0;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          //v20 = yaw;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 0;
-          a1.uFacing = yaw;
-          a1.uSoundID = 0;
-          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-          a1.Create(yaw, pitch, v49, 0);
-          pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-          return;
+          break;
         }
-        v17 = (char *)&pObjectList->pObjects->uObjectID;
-        while ( (short)a1.uType != *(short *)v17 )
-        {
-          ++v16;
-          v17 += 56;
-          if ( v16 >= (signed int)pObjectList->uNumObjects )
-          {
-            //v18 = 0;
-            a1.uObjectDescID = 0;
-            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-            a1.vPosition.x = fromx;
-            a1.uAttributes = 16;
-            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-            a1.field_60_distance_related_prolly_lod = v55;
-            //v20 = yaw;
-            a1.uSpriteFrameID = 0;
-            a1.spell_caster_pid = 8000 | OBJECT_Item;
-            a1.spell_target_pid = 0;
-            a1.uFacing = yaw;
-            a1.uSoundID = 0;
-            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-            a1.Create(yaw, pitch, v49, 0);
-            pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-            return;
-          }
-        }
-        v18 = v16;
-        a1.uObjectDescID = v18;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        //v20 = yaw;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 0;
-        a1.uFacing = yaw;
-        a1.uSoundID = 0;
+        v16++;
+      }
+      a1.uObjectDescID = v16;
+      a1.vPosition.x = fromx;
+      a1.vPosition.y = fromy;
+      a1.vPosition.z = fromz;
+      a1.uAttributes = 16;
+      a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
+      a1.field_60_distance_related_prolly_lod = v55;
+      a1.uSpriteFrameID = 0;
+      a1.spell_caster_pid = 8000 | OBJECT_Item;
+      a1.uSoundID = 0;
+      break;
+  }
+
+  switch ( uSpellID )
+  {
+    case SPELL_FIRE_FIRE_BOLT:
+    case SPELL_FIRE_FIREBALL:
+    case SPELL_AIR_LIGHNING_BOLT:
+    case SPELL_WATER_ICE_BOLT:
+    case SPELL_WATER_ACID_BURST:
+    case SPELL_WATER_ICE_BLAST:
+    case SPELL_EARTH_BLADES:
+    case SPELL_EARTH_ROCK_BLAST:
+      //v20 = yaw;
+      a1.spell_target_pid = 0;
+      a1.uFacing = yaw;
+      a1.uSoundID = 0;
+      v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+      a1.Create(yaw, pitch, v49, 0);
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+    case SPELL_WATER_POISON_SPRAY:
+      switch ( skillMasteryPlusOne )
+      {
+        case 1:
+          v60 = 1;
+          break;
+        case 2:
+          v60 = 3;
+          break;
+        case 3:
+          v60 = 5;
+          break;
+        case 4:
+          v60 = 7;
+          break;
+      }
+      a1.spell_target_pid = 0;
+      a1.uFacing = yaw;
+      if ( v60 == 1 )
+      {
         v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
         a1.Create(yaw, pitch, v49, 0);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-        return;
-      case SPELL_WATER_POISON_SPRAY:
-        switch ( v15 )
-        {
-          case 1:
-            v60 = 1;
-            break;
-          case 2:
-            v60 = 3;
-            break;
-          case 3:
-            v60 = 5;
-            break;
-          case 4:
-            v60 = 7;
-            break;
-        }
+      }
+      else
+      {
         a7c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-        if ( v60 != 1 )
-        {
-          a8b = a7c / (v60 - 1);
-          a1.stru_24.Reset();
-          v21 = 0;
-          a1.spell_id = uSpellID;
-          a1.spell_level = uSkill;
-          a1.spell_skill = v15;
-          if ( (signed int)pObjectList->uNumObjects <= 0 )
-            v23 = 0;
-          else
-          {
-            v22 = (char *)&pObjectList->pObjects->uObjectID;
-            while ( (short)a1.uType != *(short *)v22 )
-            {
-              ++v21;
-              v22 += 56;
-              if ( v21 >= (signed int)pObjectList->uNumObjects )
-              {
-                v23 = 0;
-                a1.uObjectDescID = v23;
-                *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-                a1.vPosition.x = fromx;
-                a1.uAttributes = 16;
-                a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-                a1.field_60_distance_related_prolly_lod = v55;
-                a1.uSpriteFrameID = 0;
-                a1.spell_caster_pid = 8000 | OBJECT_Item;
-                a1.spell_target_pid = 4;
-                a1.uSoundID = 0;
-                for ( i = a7c / -2; i <= a7c / 2; i += a8b )
-                {
-                  a1.uFacing = i + yaw;
-                  a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-                }
-                pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-                return;
-              }
-            }
-            v23 = v21;
-          }
-          a1.uObjectDescID = v23;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 4;
-          a1.uSoundID = 0;
-          for ( i = a7c / -2; i <= a7c / 2; i += a8b )
-          {
-            a1.uFacing = i + yaw;
-            a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-          }
-          pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-          return;
-        }
-        a1.stru_24.Reset();
-        a1.spell_id = uSpellID;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-        {
-          //v18 = 0;
-          a1.uObjectDescID = 0;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          //v20 = yaw;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 0;
-          a1.uFacing = yaw;
-          a1.uSoundID = 0;
-          //v51 = 0;
-          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-          //v47 = pitch;
-          a1.Create(yaw, pitch, v49, 0);
-          pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-          return;
-        }
-        //v19 = (char *)&pObjectList->pObjects->uObjectID;
-        for ( v16 = 0; v16 < (signed int)pObjectList->uNumObjects; ++v16 )
+        a8b = a7c / (v60 - 1);
+        for ( i = a7c / -2; i <= a7c / 2; i += a8b )
         {
-          if ( (short)a1.uType == pObjectList->pObjects[v16].uObjectID )
-          {
-            //v18 = v16;
-            a1.uObjectDescID = v16;
-            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-            a1.vPosition.x = fromx;
-            a1.uAttributes = 16;
-            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-            a1.field_60_distance_related_prolly_lod = v55;
-            //v20 = yaw;
-            a1.uSpriteFrameID = 0;
-            a1.spell_caster_pid = 8000 | OBJECT_Item;
-            a1.spell_target_pid = 0;
-            a1.uFacing = yaw;
-            a1.uSoundID = 0;
-            //v51 = 0;
-            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-            //v47 = pitch;
-            a1.Create(yaw, pitch, v49, 0);
-            pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-            return;
-          }
-          //v19 += 56;
-        }
-        //v18 = 0;
-        a1.uObjectDescID = 0;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        //v20 = yaw;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 0;
-        a1.uFacing = yaw;
-        a1.uSoundID = 0;
-        //v51 = 0;
-        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        //v47 = pitch;
-        a1.Create(yaw, pitch, v49, 0);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-        return;
-      case SPELL_AIR_SPARKS:
-        switch ( v15 )
-        {
-          case 1:
-            v60 = 3;
-            break;
-          case 2:
-            v60 = 5;
-            break;
-          case 3:
-            v60 = 7;
-            break;
-          case 4:
-            v60 = 9;
-            break;
-        }
-        a7d = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-        a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
-        a1.stru_24.Reset();
-        v25 = 0;
-        a1.spell_id = uSpellID;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-        {
-          //v27 = 0;
-          a1.uObjectDescID = 0;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 4;
-          a1.uSoundID = 0;
-          for ( j = a7d / -2; j <= a7d / 2; j += a8c )
-          {
-            a1.uFacing = j + yaw;
-            a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-          }
-          pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-          return;
-        }
-        v26 = (char *)&pObjectList->pObjects->uObjectID;
-        while ( (short)a1.uType != *(short *)v26 )
-        {
-          ++v25;
-          v26 += 56;
-          if ( v25 >= (signed int)pObjectList->uNumObjects )
-          {
-            v27 = 0;
-            a1.uObjectDescID = v27;
-            *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-            a1.vPosition.x = fromx;
-            a1.uAttributes = 16;
-            a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-            a1.field_60_distance_related_prolly_lod = v55;
-            a1.uSpriteFrameID = 0;
-            a1.spell_caster_pid = 8000 | OBJECT_Item;
-            a1.spell_target_pid = 4;
-            a1.uSoundID = 0;
-            for ( j = a7d / -2; j <= a7d / 2; j += a8c )
-            {
-              a1.uFacing = j + yaw;
-              a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
-            }
-            pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-            return;
-          }
-        }
-        v27 = v25;
-        a1.uObjectDescID = v27;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 4;
-        a1.uSoundID = 0;
-        for ( j = a7d / -2; j <= a7d / 2; j += a8c )
-        {
-          a1.uFacing = j + yaw;
-          a1.Create((signed __int16)(j + (short)yaw), pitch,
-            pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
+          a1.uFacing = i + yaw;
+          a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
         }
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-        return;
-      case SPELL_EARTH_DEATH_BLOSSOM:
-        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-          return;
-        a1.stru_24.Reset();
-        v29 = 0;
-        a1.spell_id = uSpellID;
-        a1.spell_level = uSkill;
-        a1.spell_skill = v15;
-        if ( (signed int)pObjectList->uNumObjects <= 0 )
-        {
-          //v31 = 0;
-          a1.uObjectDescID = 0;
-          *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-          a1.vPosition.x = fromx;
-          a1.uAttributes = 16;
-          a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-          a1.field_60_distance_related_prolly_lod = v55;
-          a1.uSpriteFrameID = 0;
-          a1.spell_caster_pid = 8000 | OBJECT_Item;
-          a1.spell_target_pid = 4;
-          a1.uSoundID = 0;
-          //v51 = 0;
-          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-          //v20 = yaw;
-          v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
-          a1.Create(yaw, v47, v49, 0);
-          pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-          return;
-        }
-        v30 = (char *)&pObjectList->pObjects->uObjectID;
-        break;
-
-      case SPELL_FIRE_HASTE:
-        if ( v15 > 0 )
-        {
-          if ( v15 <= 2 )
-            v9 = 60 * (uSkill + 60);
-          else if ( v15 == 3 )
-            v9 = 180 * (uSkill + 20);
-          else if ( v15 == 4 )
-            v9 = 240 * (uSkill + 15);
-        }
-        //levela = 1;
-        //v32 = pParty->pPlayers;//[0].pConditions[1];
-        //do
-        for (uint i = 0; i < 4; ++i)
-          if (pParty->pPlayers[i].IsWeak())
-            return;
-		//while ( v32 <= &pParty->pPlayers[3] );
-        //if ( !levela )
-        //  return;
-        pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 * 128) * 0.033333335),
-          v15, 0, 0, 0);
-        //v33 = spellnum_;
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);// 
-        return;
-      case SPELL_AIR_SHIELD:
-      case SPELL_EARTH_STONESKIN:
-      case SPELL_SPIRIT_HEROISM:
-        switch ( v15 )
-        {
-          case 1:
-          case 2:
-            v9 = 300 * (uSkill + 12);
-            break;
-          case 3:
-            v9 = 900 * (uSkill + 4);
-            break;
-          case 4:
-            v9 = 3600 * (uSkill + 1);
-            break;
-        }
-        switch ( uSpellID )
-        {
-          case 17:
-            v60 = 0;
-            uSkill = 14;
-            break;
-          case 38:
-            v35 = uSkill + 5;
-            uSkill = 15;
-            v60 = v35;
-            break;
-          case 51:
-            v34 = uSkill + 5;
-            uSkill = 9;
-            v60 = v34;
-            break;
-        }
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
-        //v52 = 0;
-        //v50 = 0;
-        //v48 = v60;
-        //v46 = v15;
-        v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335);
-        //v37 = &pParty->pPartyBuffs[uSkill];
-        pParty->pPartyBuffs[uSkill].Apply(v36, v15, v60, 0, 0);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      }
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+    case SPELL_AIR_SPARKS:
+      switch ( skillMasteryPlusOne )
+      {
+        case 1:
+          v60 = 3;
+          break;
+        case 2:
+          v60 = 5;
+          break;
+        case 3:
+          v60 = 7;
+          break;
+        case 4:
+          v60 = 9;
+          break;
+      }
+      a7d = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+      a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
+      a1.spell_target_pid = 4;
+      for ( j = a7d / -2; j <= a7d / 2; j += a8c )
+      {
+        a1.uFacing = j + yaw;
+        a1.Create((signed __int16)(j + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
+      }
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+    case SPELL_EARTH_DEATH_BLOSSOM:
+      if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
         return;
-      case SPELL_FIRE_IMMOLATION:
-        if ( v15 == 2 || v15 == 3 || v15 != 4 )
-          v38 = 60 * uSkill;
-        else
-          v38 = 600 * uSkill;
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
-        pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
-        v52 = 0;
-        v50 = 0;
-        v48 = uSkill;
-        v46 = v15;
-        v39 = (signed __int64)((double)(v38 << 7) * 0.033333335);
-        v37 = &pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION];
-        v36 = pParty->uTimePlayed + v39;
-        v37->Apply(v36, v46, v48, v50, v52);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-        return;
-      case SPELL_FIRE_PROTECTION_FROM_FIRE:
-      case SPELL_AIR_PROTECTION_FROM_AIR:
-      case SPELL_WATER_PROTECTION_FROM_WATER:
-      case SPELL_EARTH_PROTECTION_FROM_EARTH:
-        goto LABEL_117;
-      default:
-        return;
-    }
-    while ( (short)a1.uType != *(short *)v30 )
-    {
-      ++v29;
-      v30 += 56;
-      if ( v29 >= (signed int)pObjectList->uNumObjects )
+      a1.spell_target_pid = 4;
+      v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+      v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
+      a1.Create(yaw, v47, v49, 0);
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+
+    case SPELL_FIRE_HASTE:
+      if ( skillMasteryPlusOne > 0 )
       {
-        //v31 = 0;
-        a1.uObjectDescID = 0;
-        *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-        a1.vPosition.x = fromx;
-        a1.uAttributes = 16;
-        a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-        a1.field_60_distance_related_prolly_lod = v55;
-        a1.uSpriteFrameID = 0;
-        a1.spell_caster_pid = 8000 | OBJECT_Item;
-        a1.spell_target_pid = 4;
-        a1.uSoundID = 0;
-        //v51 = 0;
-        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        //v20 = yaw;
-        v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
-        a1.Create(yaw, v47, v49, 0);
-        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-        return;
+        if ( skillMasteryPlusOne <= 2 )
+          v9 = 60 * (uSkill + 60);
+        else if ( skillMasteryPlusOne == 3 )
+          v9 = 180 * (uSkill + 20);
+        else if ( skillMasteryPlusOne == 4 )
+          v9 = 240 * (uSkill + 15);
+      }
+      for (uint i = 0; i < 4; ++i)
+        if (pParty->pPlayers[i].IsWeak())
+          return;
+      pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 * 128) * 0.033333335), skillMasteryPlusOne, 0, 0, 0);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);// 
+      return;
+    case SPELL_AIR_SHIELD:
+    case SPELL_EARTH_STONESKIN:
+    case SPELL_SPIRIT_HEROISM:
+      switch ( skillMasteryPlusOne )
+      {
+        case 1:
+        case 2:
+          v9 = 300 * (uSkill + 12);
+          break;
+        case 3:
+          v9 = 900 * (uSkill + 4);
+          break;
+        case 4:
+          v9 = 3600 * (uSkill + 1);
+          break;
+      }
+      switch ( uSpellID )
+      {
+        case SPELL_AIR_SHIELD:
+          v60 = 0;
+          uSkill = 14;
+          break;
+        case SPELL_EARTH_STONESKIN:
+          v60 = uSkill + 5;
+          uSkill = 15;
+          break;
+        case SPELL_SPIRIT_HEROISM:
+          v60 = uSkill + 5;
+          uSkill = 9;
+          break;
       }
-    }
-    v31 = v29;
-    a1.uObjectDescID = v31;
-    *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
-    a1.vPosition.x = fromx;
-    a1.uAttributes = 16;
-    a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
-    a1.field_60_distance_related_prolly_lod = v55;
-    a1.uSpriteFrameID = 0;
-    a1.spell_caster_pid = 8000 | OBJECT_Item;
-    a1.spell_target_pid = 4;
-    a1.uSoundID = 0;
-    //v51 = 0;
-    v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-    //v20 = yaw;
-    v47 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
-    a1.Create(yaw, v47, v49, 0);
-    pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
-    return;
-  }
-LABEL_117:
-  v44 = uSkill;
-  a6_4 = 3600 * uSkill;
-  if ( v15 == 1 )
-  {
-    v60 = v44;
-    goto LABEL_125;
-  }
-  if ( v15 == 2 )
-  {
-    v44 = 2 * uSkill;
-    v60 = v44;
-    goto LABEL_125;
-  }
-  if ( v15 == 3 )
-  {
-    v44 = 3 * uSkill;
-    v60 = v44;
-    goto LABEL_125;
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
+      v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335);
+      pParty->pPartyBuffs[uSkill].Apply(v36, skillMasteryPlusOne, v60, 0, 0);
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+    case SPELL_FIRE_IMMOLATION:
+      if (skillMasteryPlusOne == 4)
+        v38 = 600 * uSkill;
+      else
+        v38 = 60 * uSkill;
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
+      v39 = (signed __int64)((double)(v38 << 7) * 0.033333335);
+      v36 = pParty->uTimePlayed + v39;
+      pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(v36, skillMasteryPlusOne, uSkill, 0, 0);
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+    case SPELL_FIRE_PROTECTION_FROM_FIRE:
+    case SPELL_AIR_PROTECTION_FROM_AIR:
+    case SPELL_WATER_PROTECTION_FROM_WATER:
+    case SPELL_EARTH_PROTECTION_FROM_EARTH:
+    case SPELL_MIND_PROTECTION_FROM_MIND:
+    case SPELL_BODY_PROTECTION_FROM_BODY:
+      a6_4 = 3600 * uSkill;
+      switch (skillMasteryPlusOne)
+      {
+      case 1:
+        v60 = uSkill;
+        break;
+      case 2:
+        v60 = 2 * uSkill;
+        break;
+      case 3:
+        v60 = 3 * uSkill;
+        break;
+      case 4:
+        v60 = 4 * uSkill;
+        break;
+      }
+      switch ( uSpellID )
+      {
+      case SPELL_FIRE_PROTECTION_FROM_FIRE:
+        uSkill = PARTY_BUFF_RESIST_FIRE;
+        break;
+      case SPELL_AIR_PROTECTION_FROM_AIR:
+        uSkill = PARTY_BUFF_RESIST_AIR;
+        break;
+      case SPELL_WATER_PROTECTION_FROM_WATER:
+        uSkill = PARTY_BUFF_RESIST_WATER;
+        break;
+      case SPELL_EARTH_PROTECTION_FROM_EARTH:
+        uSkill = PARTY_BUFF_RESIST_EARTH;
+        break;
+      case SPELL_MIND_PROTECTION_FROM_MIND:
+        uSkill = PARTY_BUFF_RESIST_MIND;
+        break;
+      case SPELL_BODY_PROTECTION_FROM_BODY:
+        uSkill = PARTY_BUFF_RESIST_BODY;
+        break;
+      }
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
+      pParty->pPartyBuffs[uSkill].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669), skillMasteryPlusOne, v60, 0, 0);
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+    case SPELL_LIGHT_DAY_OF_THE_GODS :
+      switch (skillMasteryPlusOne)
+      {
+      case 2:
+        v42 = 10800 * uSkill;
+        v43 = 3 * uSkill + 10;
+        break;
+      case 3:
+        v42 = 18000 * uSkill;
+        v43 = 5 * uSkill + 10;
+        break;
+      case 4:
+        v42 = 14400 * uSkill;
+        v43 = 4 * uSkill + 10;
+        break;
+      }
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
+      pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
+      v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
+      v36 = pParty->uTimePlayed + v39;
+      pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(v36, skillMasteryPlusOne, v43, 0, 0);
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
+      return;
+    default:
+      return;
   }
-  if ( v15 == 4 )
-  {
-    v44 = 4 * uSkill;
-    v60 = v44;
-    goto LABEL_125;
-  }
-LABEL_125:
-  switch ( uSpellID )
-  {
-    case 3:
-      uSkill = 6;
-      break;
-    case 14:
-      uSkill = 0;
-      break;
-    case 25:
-      uSkill = 17;
-      break;
-    case 36:
-      uSkill = 4;
-      break;
-    case 58:
-      uSkill = 12;
-      break;
-    case 69:
-      uSkill = 1;
-      break;
-  }
-  //v45 = spellnum_;
-  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 0);
-  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 1);
-  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 2);
-  pGame->pStru6Instance->SetPlayerBuffAnim(uSpellID, 3);
-  pParty->pPartyBuffs[uSkill].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669), v15, v60, 0, 0);
-  //levela = 1;
-//LABEL_138:
-  //if ( levela )
-//LABEL_139:
-    pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], 0, 0, fromx, fromy, 0, 0, 0);
 }
 //----- (00427769) --------------------------------------------------------
 bool sub_427769_isSpellQuickCastableOnShiftClick(unsigned int uSpellID)
 {
-  return ( pSpellDatas[uSpellID].stats & 0xC );
+  return ( pSpellDatas[uSpellID].stats & 0xC ) != 0;
 }
 //----- (0043AFE3) --------------------------------------------------------
-int __fastcall _43AFE3_calc_spell_damage(int a1, int a2, signed int a3, int a4)
+int _43AFE3_calc_spell_damage(int spellId, int spellLevel, signed int skillMastery, int currentHp)
 {
   int result; // eax@1
   unsigned int v5; // [sp-4h] [bp-8h]@9
 
   result = 0;
-  if ( a1 == 7 )
+  if ( spellId == SPELL_FIRE_FIRE_SPIKE )
   {
-    if ( a3 <= 0 )
-      return result;
-    if ( a3 <= 2 )
-    {
-      v5 = 6;
-    }
-    else
+    switch (skillMastery)
     {
-      if ( a3 == 3 )
-      {
-        v5 = 8;
-      }
-      else
-      {
-        if ( a3 != 4 )
-          return result;
-        v5 = 10;
-      }
+    case 1:
+    case 2:
+      v5 = 6;
+    case 3:
+      v5 = 8;
+    case 4:
+      v5 = 10;
+    default:
+      return 0;
     }
-    result = GetDiceResult(a2, v5);
+    result = GetDiceResult(spellLevel, v5);
   }
+  else if ( spellId == SPELL_EARTH_MASS_DISTORTION )
+    result = currentHp * (pSpellDatas[SPELL_EARTH_MASS_DISTORTION].baseDamage + 2 * spellLevel) / 100;
   else
-  {
-    if ( a1 == 44 )
-      result = a4 * (LOBYTE(pSpellDatas[40].field_10) + 2 * a2) / 100;
-    else
-      result = *((char *)&pSpellDatas[0].field_10 + 20 * a1)
-             + GetDiceResult(a2, *((char *)&pSpellDatas[0].field_10 + 20 * a1 + 1));
-  }
+    result = pSpellDatas[spellId].baseDamage 
+    + GetDiceResult(spellLevel, pSpellDatas[spellId].bonusSkillDamage);
+
   return result;
 }
\ No newline at end of file
--- a/Spells.h	Wed Apr 02 20:53:35 2014 +0600
+++ b/Spells.h	Wed Apr 02 20:53:47 2014 +0600
@@ -217,8 +217,12 @@
 
 /*  151 */
 #pragma pack(push, 1)
-struct SpellData
+class SpellData
 {
+public:
+  SpellData(__int16 innormalMana, __int16 inExpertLevelMana, __int16 inMasterLevelMana, __int16 inMagisterLevelMana,
+            __int16 inNormalLevelRecovery, __int16 inExpertLevelRecovery, __int16 inMasterLevelRecovery, __int16 inMagisterLevelRecovery,
+            __int8 inbaseDamage, __int8 inbonusSkillDamage, __int16 instats);
   union
   {
     unsigned __int16 mana_per_skill[4];
@@ -241,7 +245,8 @@
       unsigned __int16 uMagisterLevelRecovery;
     };
   };
-  __int16 field_10;
+  __int8 baseDamage;
+  __int8 bonusSkillDamage;
   __int16 stats;
  // char field_12;
  // char field_13;
@@ -278,4 +283,6 @@
 
 extern std::array<stru324_spell, 103> stru_4E3ACC;
 extern std::array<SpellData, 100> pSpellDatas;
-extern std::array<unsigned int, 25> wand_spell_ids;
\ No newline at end of file
+extern std::array<unsigned int, 25> wand_spell_ids;
+
+int _43AFE3_calc_spell_damage(int spellId, int spellLevel, signed int skillMastery, int currentHp);
--- a/SpriteObject.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/SpriteObject.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -14,6 +14,7 @@
 #include "LOD.h"
 #include "Actor.h"
 #include "Events.h"
+#include "AudioPlayer.h"
 #include "Level/Decoration.h"
 
 #include "mm7_data.h"
@@ -1042,4 +1043,114 @@
       }
     }
   }
+}
+
+
+//----- (0042F7EB) --------------------------------------------------------
+bool SpriteObject::sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9)
+{
+  unsigned __int16 pObjectDescID; // ax@7
+  SpriteObject pSpellObject; // [sp+Ch] [bp-78h]@1
+
+  pSpellObject.stru_24.Reset();
+  if ( a9 )
+    memcpy(&pSpellObject.stru_24, a9, sizeof(pSpellObject.stru_24));
+  pSpellObject.spell_skill = 0;
+  pSpellObject.spell_level = 0;
+  pSpellObject.spell_id = 0;
+  pSpellObject.field_54 = 0;
+  pSpellObject.uType = uSpriteID;
+  pObjectDescID = 0;
+  for ( uint i = 0; i < (signed int)pObjectList->uNumObjects; ++i )
+  {
+    if ( (short)uSpriteID == pObjectList->pObjects[i].uObjectID )
+      pObjectDescID = i;
+  }
+  pSpellObject.uObjectDescID = pObjectDescID;
+  pSpellObject.vPosition.x = x;
+  pSpellObject.vPosition.y = y;
+  pSpellObject.vPosition.z = z;
+  pSpellObject.uSoundID = 0;
+  pSpellObject.uAttributes = attributes;
+  pSpellObject.uSectorID = pIndoor->GetSector(x, y, z);
+  pSpellObject.uSpriteFrameID = 0;
+  pSpellObject.spell_caster_pid = 0;
+  pSpellObject.spell_target_pid = 0;
+  if ( !(pSpellObject.uAttributes & 0x10) )
+  {
+    if ( pItemsTable->uAllItemsCount )
+    {
+      for ( uint i = 1; i < pItemsTable->uAllItemsCount; ++i )
+      {
+        if ( pItemsTable->pItems[i].uSpriteID == uSpriteID )
+          pSpellObject.stru_24.uItemID = i;
+      }
+    }
+  }
+  if ( a7 )
+  {
+    if ( count > 0 )
+    {
+      for ( uint i = count; i; --i )
+      {
+        pSpellObject.uFacing = rand() % (signed int)stru_5C6E00->uIntegerDoublePi;
+        pSpellObject.Create((signed __int16)pSpellObject.uFacing,
+          ((signed int)stru_5C6E00->uIntegerHalfPi / 2) + (rand() % ((signed int)stru_5C6E00->uIntegerHalfPi / 2)), a4, 0);
+
+      }
+    }
+  }
+  else
+  {
+    pSpellObject.uFacing = 0;
+    if ( count > 0 )
+    {
+      for ( uint i = count; i; --i )
+      {
+        pSpellObject.Create((signed __int16)pSpellObject.uFacing, stru_5C6E00->uIntegerHalfPi, a4, 0);
+      }
+    }
+  }
+  return true;
+}
+
+//----- (0042F960) --------------------------------------------------------
+void SpriteObject::sub_42F960_create_object(int x, int y, int z)
+{
+  unsigned __int16 v7; // ax@5
+  signed int v8; // eax@6
+  signed int v9; // eax@7
+
+  SpriteObject a1; // [sp+Ch] [bp-70h]@1
+  //SpriteObject::SpriteObject(&a1);
+  a1.stru_24.Reset();
+
+  a1.spell_skill = 0;
+  a1.spell_level = 0;
+  a1.spell_id = 0;
+  a1.field_54 = 0;
+  a1.uType = 800;
+  v7 = 0;
+  for ( uint i = 0; i < (signed int)pObjectList->uNumObjects; ++i )
+  {
+    if ( a1.uType == pObjectList->pObjects[i].uObjectID  )
+      v7 = i;
+  }
+  a1.uObjectDescID = v7;
+  a1.vPosition.x = x;
+  a1.vPosition.y = y;
+  a1.vPosition.z = z;
+  a1.uSoundID = 0;
+  a1.uAttributes = 0;
+  a1.uSectorID = pIndoor->GetSector(x, y, z);
+  a1.uSpriteFrameID = 0;
+  a1.spell_caster_pid = 0;
+  a1.spell_target_pid = 0;
+  v8 = a1.Create(0, 0, 0, 0);
+  if ( v8 != -1 )
+  {
+    v9 = 8 * v8;
+    LOBYTE(v9) = v9 | 2;
+    pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x14), v9, 0, -1, 0, 0, 0, 0);
+  }
 }
\ No newline at end of file
--- a/SpriteObject.h	Wed Apr 02 20:53:35 2014 +0600
+++ b/SpriteObject.h	Wed Apr 02 20:53:47 2014 +0600
@@ -22,6 +22,8 @@
   static void UpdateObject_fn0_BLV(unsigned int uLayingItemID);
   static void UpdateObject_fn0_ODM(unsigned int uLayingItemID);
   static void OnInteraction(unsigned int uLayingItemID);
+  static bool sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9);
+  static void sub_42F960_create_object(int x, int y, int z);
 
 
   unsigned __int16 uType;
--- a/UI/UIPopup.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/UI/UIPopup.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -1869,7 +1869,7 @@
 
       int rot_x, rot_y, rot_z;
       Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
+      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
       if ( dword_4E455C )
       {
         if ( pPlayers[uActiveCharacter]->CanAct() )
@@ -1895,7 +1895,7 @@
 
       int rot_x, rot_y, rot_z;
       Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
+      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
       if ( dword_4E455C )
       {
         if ( pPlayers[uActiveCharacter]->CanAct() )
@@ -1922,7 +1922,7 @@
 
       int rot_x, rot_y, rot_z;
       Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
+      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
       if ( dword_4E455C )
       {
         if ( pPlayers[uActiveCharacter]->CanAct() )
@@ -1949,7 +1949,7 @@
 
       int rot_x, rot_y, rot_z;
       Vec3_int_::Rotate(64, pParty->sRotationY, pParty->sRotationX, v39, &rot_x, &rot_y, &rot_z);
-      sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
+      SpriteObject::sub_42F7EB_DropItemAt(0x41Bu, rot_x, rot_y, rot_z, 0, 1, 0, 0, 0);
       if ( dword_4E455C )
       {
         if ( pPlayers[uActiveCharacter]->CanAct() )
--- a/mm7_2.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/mm7_2.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -75,31 +75,6 @@
 bool __fastcall FindMM7CD(HWND hWnd, char *pCDDrive);
 bool __fastcall Initialize(HINSTANCE hInst, char *pCmdLine);
 
-//----- (004A1780) mm6_chinese---------------------------------------------
-__int64 fixpoint_div(int a1, int a2)
-{
-  return ((__int64)a1 << 16) / a2;
-}
-
-__int64 fixpoint_sub_unknown(int a1, int a2)
-{
-  return (((__int64)a1 << 16) * a2) >> 16;
-}
-
-//----- (0042EBBE) --------------------------------------------------------
-//----- (004453C0) mm6-----------------------------------------------------
-//----- (004A1760) mm6_chinese---------------------------------------------
-__int64 fixpoint_mul(int a1, int a2)
-{
-  return ((__int64)a1 * (__int64)a2) >> 16;
-}
-
-__int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2)
-{
-  return fixpoint_mul(x1, x2) +
-         fixpoint_mul(y1, y2) +
-         fixpoint_mul(z1, z2);
-}
 
 //----- (004BB756) --------------------------------------------------------
 int UseNPCSkill(NPCProf profession)
@@ -1909,139 +1884,6 @@
                                                                     + (__PAIR__(v10, (unsigned __int16)a4 >> 2) & 0x1C00));
 }
 
-//----- (0045281E) --------------------------------------------------------
-//    Calculates atan2(y/x)
-// return value: angle in integer format (multiplier of Pi/1024)  
-unsigned int stru193_math::Atan2(int x, int y)
-{
-  signed int quadrant;
-  __int64 dividend;
-  int quotient;
-  int lowIdx;
-  int highIdx;
-  int angle;
-
-  int X = x;
-  int Y = y;
-
-  if ( abs(X) < 65536 )
-  {
-    if ( (abs(Y) >> 15) >= abs(X) )
-      X = 0;
-  }
-
-  if ( !X )
-  {
-    if ( Y > 0 )
-    {
-      return uIntegerHalfPi;   //Pi/2
-    }
-    else
-    {
-      return uIntegerHalfPi + uIntegerPi; //3*(Pi/2)
-    }
-  }
-
-  if ( Y )
-  {
-    if ( X < 0 )
-    {
-      X = -X;
-      if ( Y > 0 )
-      {
-        quadrant = 4;        
-      }
-      else
-      {
-        quadrant = 3;        
-      }      
-    }
-    else
-    {
-      if ( Y > 0 )
-      {
-        quadrant = 1;       
-      }
-      else
-      {
-        quadrant = 2;
-      }      
-    }
-
-    if ( Y < 0 )
-      Y = -Y;
-
-    LODWORD(dividend) = Y << 16;
-    HIDWORD(dividend) = Y >> 16;
-    quotient = dividend / X;        
-
-    //looks like binary search
-    {
-      int i;
-      highIdx = uIntegerHalfPi;
-      lowIdx = 0;
-
-      for (i = 0; i < 6; ++i)
-      {        
-        if (quotient <= pTanTable[(lowIdx + highIdx) / 2])      
-          highIdx = (lowIdx + highIdx) / 2;
-        else
-          lowIdx = (lowIdx + highIdx) / 2;    
-      }
-    }
-
-    angle = lowIdx + 1;
-    while ( angle < (highIdx - 1) && quotient >= pTanTable[angle] )
-      ++angle;
-
-    switch (quadrant)
-    {
-    case 1: //X > 0, Y > 0
-      return angle;        
-
-    case 2: //X > 0, Y < 0
-      return uIntegerDoublePi - angle;   //2*Pi - angle
-
-    case 3: //X > 0, Y < 0
-      return uIntegerPi + angle;        //Pi + angle 
-
-    case 4: //X < 0, Y > 0
-      return uIntegerPi - angle;        //Pi - angle  
-    }
-
-    //should newer get here
-    return 0;
-  }
-
-  if ( X < 0 )    //Y == 0, X < 0
-    return uIntegerPi;  
-
-  return 0;
-}
-
-//----- (00452969) --------------------------------------------------------
-stru193_math::stru193_math()
-{
-  double v3; // ST18_8@2
-
-  this->pTanTable[0] = 0;
-  this->pCosTable[0] = 65536;
-  this->pInvCosTable[0] = 65536;
-  for(int i = 1; i < (signed int)this->uIntegerHalfPi; i++)
-  {
-    v3 = (double)i * 3.141592653589793 / (double)uIntegerPi;
-    pTanTable[i] = (signed __int64)(tan(v3) * (double)this->pCosTable[0] + 0.5);
-    pCosTable[i] = (signed __int64)(cos(v3) * (double)this->pCosTable[0] + 0.5);
-    pInvCosTable[i] = (signed __int64)(1.0 / cos(v3) * (double)this->pCosTable[0] + 0.5);
-  }
-  for(int i = this->uIntegerHalfPi; i < 520; i++)
-  {
-    this->pTanTable[i] = 0xEFFFFFFFu;
-    this->pCosTable[i] = 0;
-    this->pInvCosTable[i] = 0xEFFFFFFFu;
-  }
-}
-
 //----- (00452A9E) --------------------------------------------------------
 int integer_sqrt(int val)
 {
@@ -2573,6 +2415,30 @@
 }
 // 6BE3A0: using guessed type float flt_6BE3A0;
 
+
+//----- (0042F3D6) --------------------------------------------------------
+void InitializeTurnBasedAnimations(void *_this)
+{
+  for (unsigned int i = 0; i < pIconIDs_Turn.size(); ++i)
+  {
+    char icon_name[32];
+    sprintf(icon_name, "turn%u", i);
+    pIconIDs_Turn[i] = pIconsFrameTable->FindIcon(icon_name);
+    pIconsFrameTable->InitializeAnimation(pIconIDs_Turn[i]);
+  }
+
+  uIconID_TurnStop = pIconsFrameTable->FindIcon("turnstop");
+  uIconID_TurnHour = pIconsFrameTable->FindIcon("turnhour");
+  uIconID_TurnStart = pIconsFrameTable->FindIcon("turnstart");
+  uIconID_CharacterFrame = pIconsFrameTable->FindIcon("aframe1");
+  uSpriteID_Spell11 = pSpriteFrameTable->FastFindSprite("spell11");
+
+  pIconsFrameTable->InitializeAnimation(uIconID_TurnHour);
+  pIconsFrameTable->InitializeAnimation(uIconID_TurnStop);
+  pIconsFrameTable->InitializeAnimation(uIconID_TurnStart);
+  pIconsFrameTable->InitializeAnimation(uIconID_CharacterFrame);
+}
+
 //----- (00464839) --------------------------------------------------------
 char Is_out15odm_underwater()
 {
--- a/mm7_3.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/mm7_3.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -827,7 +827,7 @@
               v61 = v36 + 30;
             else
               v61 = v5 + 60;
-            sub_42F960_create_object(pActors[v75].vPosition.x, pActors[v75].vPosition.y, v61);
+            SpriteObject::sub_42F960_create_object(pActors[v75].vPosition.x, pActors[v75].vPosition.y, v61);
             pActors[v75].uAIState = Removed;
             return;
           }
@@ -4320,21 +4320,4 @@
   }
 }
 
-//----- (00402CAE) --------------------------------------------------------
-int stru193_math::Cos(int angle)
-{
-  int v2; // eax@1
-
-  //a2: (angle - uIntegerHalfPi)    for  sin(angle)
-  //    (angle)                     for  cos(angle)
-
-  v2 = uDoublePiMask & angle;
-  
-  if ( v2 > uIntegerPi )
-    v2 = uIntegerDoublePi - v2;
-  if ( v2 >= uIntegerHalfPi )
-    return -pCosTable[uIntegerPi - v2];
-  else
-    return pCosTable[v2];
-}
-
+
--- a/mm7_4.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/mm7_4.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -175,19 +175,6 @@
          (((uint)round_to_int(b * 255.0f) & 0xFF));
 }
 
-//----- (0048B561) --------------------------------------------------------
-int fixpoint_from_float(float val)
-{
-  //  float X.Yf -> int XXXX YYYY
-  int left = floorf((val - 0.5f) + 0.5f);
-  int right = floorf((val - left) * 65536.0f);
-  return (left << 16) | right;
-}
-
-int fixpoint_from_int(int lhv, int rhv)
-{
-  return (lhv << 16) | rhv;
-}
 
 //----- (00491E3A) --------------------------------------------------------
 void sub_491E3A()
--- a/mm7_6.cpp	Wed Apr 02 20:53:35 2014 +0600
+++ b/mm7_6.cpp	Wed Apr 02 20:53:47 2014 +0600
@@ -1,27 +1,9 @@
 #define _CRT_SECURE_NO_WARNINGS
-#include "MM7.h"
-
-#include "Weather.h"
-#include "Sprites.h"
-#include "Mouse.h"
-#include "Keyboard.h"
 
 #include "Vis.h"
 #include "Game.h"
-#include "GUIWindow.h"
-#include "Party.h"
-#include "AudioPlayer.h"
-#include "Outdoor.h"
+#include "MM7_data.h"
 #include "Actor.h"
-#include "Viewport.h"
-#include "OurMath.h"
-#include "SpriteObject.h"
-#include "ObjectList.h"
-#include "Timer.h"
-#include "IconFrameTable.h"
-#include "TurnEngine.h"
-#include "CastSpellInfo.h"
-#include "stru298.h"
 
 
 
@@ -48,187 +30,7 @@
   return result;
 }
 
-//----- (0042EB8D) --------------------------------------------------------
-void GUIMessageQueue::AddMessageImpl(UIMessageType msg, int param, unsigned int a4, const char *file, int line)
-{
-  //Log::Warning(L"%s @ (%S %u)", UIMessage2String(msg), file, line);
-  if (uNumMessages < 40)
-  {
-    files[uNumMessages] = file;
-    lines[uNumMessages] = line;
 
-    pMessages[uNumMessages].eType = msg;
-    pMessages[uNumMessages].param = param;
-    pMessages[uNumMessages++].field_8 = a4;
-  }
-}
-
-//----- (0042EBDB) --------------------------------------------------------
-int stru193_math::Sin(int angle)
-{
-  return Cos(angle - this->uIntegerHalfPi);
-}
-
-//----- (0042ECB5) --------------------------------------------------------
-void _42ECB5_PlayerAttacksActor()
-{
-  char *v5; // eax@8
-  unsigned int v9; // ecx@21
-  char *v11; // eax@26
-  unsigned int v12; // eax@47
-  SoundID v24; // [sp-4h] [bp-40h]@58
-
-  //result = pParty->pPlayers[uActiveCharacter-1].CanAct();
-  Player* player = &pParty->pPlayers[uActiveCharacter - 1];
-  if (!player->CanAct())
-    return;
-
-  CastSpellInfoHelpers::_427D48();
-    //v3 = 0;
-  if (pParty->Invisible())
-    pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
-
-    //v31 = player->pEquipment.uBow;
-  int bow_idx = player->pEquipment.uBow;
-  if (bow_idx && player->pInventoryItemList[bow_idx - 1].IsBroken())
-    bow_idx = 0;
-
-    //v32 = 0;
-  int wand_item_id = 0;
-    //v33 = 0;
-    //v4 = v1->pEquipment.uMainHand;
-  int laser_weapon_item_id = 0;
-
-  int main_hand_idx = player->pEquipment.uMainHand;
-  if (main_hand_idx)
-  {
-    ItemGen* item = &player->pInventoryItemList[main_hand_idx - 1];
-      //v5 = (char *)v1 + 36 * v4;
-    if (!item->IsBroken())
-    {
-		//v28b = &v1->pInventoryItems[v4].uItemID;
-        //v6 = v1->pInventoryItems[v4].uItemID;//*((int *)v5 + 124);
-      if (item->GetItemEquipType() == EQUIP_WAND)
-      {
-        if (item->uNumCharges <= 0)
-          player->pEquipment.uMainHand = 0; // wand discharged - unequip
-        else
-          wand_item_id = item->uItemID;//*((int *)v5 + 124);
-      }
-      else if (item->uItemID == ITEM_BLASTER || item->uItemID == ITEM_LASER_RIFLE)
-        laser_weapon_item_id = item->uItemID;//*((int *)v5 + 124);
-    }
-  }
-
-    //v30 = 0;
-    //v29 = 0;
-    //v28 = 0;
-    //v7 = pMouse->uPointingObjectID;
-
-  int target_pid = pMouse->uPointingObjectID;
-  int target_type = PID_TYPE(target_pid),
-      target_id = PID_ID(target_pid);
-  if (target_type != OBJECT_Actor || !pActors[target_id].CanAct())
-  {
-    target_pid = stru_50C198.FindClosestActor(5120, 0, 0);
-    target_type = PID_TYPE(target_pid);
-    target_id = PID_ID(target_pid);
-  }
-
-  Actor* actor = &pActors[target_id];
-  int actor_distance = 0;
-  if (target_type == OBJECT_Actor)
-  {
-    int distance_x = actor->vPosition.x - pParty->vPosition.x,
-        distance_y = actor->vPosition.y - pParty->vPosition.y,
-        distance_z = actor->vPosition.z - pParty->vPosition.z;
-    actor_distance = integer_sqrt(distance_x * distance_x + distance_y * distance_y + distance_z * distance_z) - actor->uActorRadius;
-    if (actor_distance < 0)
-      actor_distance = 0;
-  }
-
-  bool shooting_bow = false,
-       shotting_laser = false,
-       shooting_wand = false,
-       melee_attack = false;
-  if (laser_weapon_item_id)
-  {
-    shotting_laser = true;
-    _42777D_CastSpell_UseWand_ShootArrow(SPELL_LASER_PROJECTILE, uActiveCharacter - 1, 0, 0, uActiveCharacter + 8);
-  }
-  else if (wand_item_id)
-  {
-    shooting_wand = true;
-
-    int main_hand_idx = player->pEquipment.uMainHand;
-    _42777D_CastSpell_UseWand_ShootArrow(wand_spell_ids[player->pInventoryItemList[main_hand_idx - 1].uItemID - ITEM_WAND_FIRE], uActiveCharacter - 1, 8, 0, uActiveCharacter + 8);
-
-    if (!--player->pInventoryItemList[main_hand_idx - 1].uNumCharges)
-      player->pEquipment.uMainHand = 0;
-  }
-  else if (target_type == OBJECT_Actor && actor_distance <= 407.2)
-  {
-    melee_attack = true;
-
-    Vec3_int_ a3;
-    a3.x = actor->vPosition.x - pParty->vPosition.x;
-    a3.y = actor->vPosition.y - pParty->vPosition.y;
-    a3.z = actor->vPosition.z - pParty->vPosition.z;
-    Vec3_int_::Normalize(&a3.x, &a3.y, &a3.z);
-
-    DamageMonsterFromParty(PID(OBJECT_Player, uActiveCharacter - 1), target_id, &a3);
-    if (player->WearsItem(ITEM_ARTIFACT_SPLITTER, EQUIP_TWO_HANDED) || player->WearsItem(ITEM_ARTIFACT_SPLITTER, EQUIP_SINGLE_HANDED))
-          _42FA66_do_explosive_impact(actor->vPosition.x, actor->vPosition.y, actor->vPosition.z + actor->uActorHeight / 2, 0, 512, uActiveCharacter);
-  }
-  else if (bow_idx)
-  {
-    shooting_bow = true;
-    _42777D_CastSpell_UseWand_ShootArrow(SPELL_BOW_ARROW, uActiveCharacter - 1, 0, 0, 0);
-  }
-  else
-  {
-    melee_attack = true;
-    ; // actor out of range or no actor; no ranged weapon so melee attacking air
-  }
-
-  if (!pParty->bTurnBasedModeOn && melee_attack) // wands, bows & lasers will add recovery while shooting spell effect
-  {
-    int recovery = player->GetAttackRecoveryTime(false);
-    if (recovery < 30 )
-      recovery = 30;
-    player->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * (double)recovery * 2.133333333333333);
-  }
-
-  int v34 = 0;
-  if (shooting_wand)
-    return;
-  else if (shooting_bow)
-  {
-    v34 = 5;
-    player->PlaySound(SPEECH_50, 0);
-  }
-  if (shotting_laser)
-    v34 = 7;
-  else
-  {
-    int main_hand_idx = player->pEquipment.uMainHand;
-    if (player->HasItemEquipped(EQUIP_TWO_HANDED))
-      v34 = player->pInventoryItemList[main_hand_idx - 1].GetPlayerSkillType();
-    pTurnEngine->ApplyPlayerAction();
-  }
-
-  switch (v34)
-  {
-    case 0: pAudioPlayer->PlaySound(SOUND_81, 0, 0, -1, 0, 0, 0, 0); break;
-    case 1: pAudioPlayer->PlaySound(SOUND_84, 0, 0, -1, 0, 0, 0, 0); break;
-    case 2: pAudioPlayer->PlaySound(SOUND_85, 0, 0, -1, 0, 0, 0, 0); break;
-    case 3: pAudioPlayer->PlaySound(SOUND_78, 0, 0, -1, 0, 0, 0, 0); break;
-    case 4: pAudioPlayer->PlaySound(SOUND_80, 0, 0, -1, 0, 0, 0, 0); break;
-    case 5: pAudioPlayer->PlaySound(SOUND_71, 0, 0, -1, 0, 0, 0, 0); break;
-    case 6: pAudioPlayer->PlaySound(SOUND_83, 0, 0, -1, 0, 0, 0, 0); break;
-    case 7: pAudioPlayer->PlaySound(SOUND_67, 0, 0, -1, 0, 0, 0, 0); break;
-  }
-}
 
 //----- (0042F184) --------------------------------------------------------
 int stru319::FindClosestActor(int pick_depth, int a3, int a4)
@@ -380,569 +182,5 @@
   return 0;*/
 }
 
-//----- (0042F3D6) --------------------------------------------------------
-void InitializeTurnBasedAnimations(void *_this)
-{
-  for (unsigned int i = 0; i < pIconIDs_Turn.size(); ++i)
-  {
-    char icon_name[32];
-    sprintf(icon_name, "turn%u", i);
-    pIconIDs_Turn[i] = pIconsFrameTable->FindIcon(icon_name);
-    pIconsFrameTable->InitializeAnimation(pIconIDs_Turn[i]);
-  }
-
-  uIconID_TurnStop = pIconsFrameTable->FindIcon("turnstop");
-  uIconID_TurnHour = pIconsFrameTable->FindIcon("turnhour");
-  uIconID_TurnStart = pIconsFrameTable->FindIcon("turnstart");
-  uIconID_CharacterFrame = pIconsFrameTable->FindIcon("aframe1");
-  uSpriteID_Spell11 = pSpriteFrameTable->FastFindSprite("spell11");
-
-  pIconsFrameTable->InitializeAnimation(uIconID_TurnHour);
-  pIconsFrameTable->InitializeAnimation(uIconID_TurnStop);
-  pIconsFrameTable->InitializeAnimation(uIconID_TurnStart);
-  pIconsFrameTable->InitializeAnimation(uIconID_CharacterFrame);
-}
-
-//----- (0042F7EB) --------------------------------------------------------
-bool __fastcall sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9)
-{
-  unsigned __int16 pObjectDescID; // ax@7
-  SpriteObject pSpellObject; // [sp+Ch] [bp-78h]@1
-
-  pSpellObject.stru_24.Reset();
-  if ( a9 )
-    memcpy(&pSpellObject.stru_24, a9, sizeof(pSpellObject.stru_24));
-  pSpellObject.spell_skill = 0;
-  pSpellObject.spell_level = 0;
-  pSpellObject.spell_id = 0;
-  pSpellObject.field_54 = 0;
-  pSpellObject.uType = uSpriteID;
-  pObjectDescID = 0;
-  for ( uint i = 0; i < (signed int)pObjectList->uNumObjects; ++i )
-  {
-    if ( (short)uSpriteID == pObjectList->pObjects[i].uObjectID )
-      pObjectDescID = i;
-  }
-  pSpellObject.uObjectDescID = pObjectDescID;
-  pSpellObject.vPosition.x = x;
-  pSpellObject.vPosition.y = y;
-  pSpellObject.vPosition.z = z;
-  pSpellObject.uSoundID = 0;
-  pSpellObject.uAttributes = attributes;
-  pSpellObject.uSectorID = pIndoor->GetSector(x, y, z);
-  pSpellObject.uSpriteFrameID = 0;
-  pSpellObject.spell_caster_pid = 0;
-  pSpellObject.spell_target_pid = 0;
-  if ( !(pSpellObject.uAttributes & 0x10) )
-  {
-    if ( pItemsTable->uAllItemsCount )
-    {
-      for ( uint i = 1; i < pItemsTable->uAllItemsCount; ++i )
-      {
-        if ( pItemsTable->pItems[i].uSpriteID == uSpriteID )
-          pSpellObject.stru_24.uItemID = i;
-      }
-    }
-  }
-  if ( a7 )
-  {
-    if ( count > 0 )
-    {
-      for ( uint i = count; i; --i )
-      {
-        pSpellObject.uFacing = rand() % (signed int)stru_5C6E00->uIntegerDoublePi;
-        pSpellObject.Create((signed __int16)pSpellObject.uFacing,
-          ((signed int)stru_5C6E00->uIntegerHalfPi / 2) + (rand() % ((signed int)stru_5C6E00->uIntegerHalfPi / 2)), a4, 0);
-        
-      }
-    }
-  }
-  else
-  {
-    pSpellObject.uFacing = 0;
-    if ( count > 0 )
-    {
-      for ( uint i = count; i; --i )
-      {
-        pSpellObject.Create((signed __int16)pSpellObject.uFacing, stru_5C6E00->uIntegerHalfPi, a4, 0);
-      }
-    }
-  }
-  return true;
-}
-
-//----- (0042F960) --------------------------------------------------------
-void __fastcall sub_42F960_create_object(int x, int y, int z)
-{
-  unsigned __int16 v7; // ax@5
-  signed int v8; // eax@6
-  signed int v9; // eax@7
-
-  SpriteObject a1; // [sp+Ch] [bp-70h]@1
-  //SpriteObject::SpriteObject(&a1);
-  a1.stru_24.Reset();
-
-  a1.spell_skill = 0;
-  a1.spell_level = 0;
-  a1.spell_id = 0;
-  a1.field_54 = 0;
-  a1.uType = 800;
-  v7 = 0;
-  for ( uint i = 0; i < (signed int)pObjectList->uNumObjects; ++i )
-  {
-    if ( a1.uType == pObjectList->pObjects[i].uObjectID  )
-      v7 = i;
-  }
-  a1.uObjectDescID = v7;
-  a1.vPosition.x = x;
-  a1.vPosition.y = y;
-  a1.vPosition.z = z;
-  a1.uSoundID = 0;
-  a1.uAttributes = 0;
-  a1.uSectorID = pIndoor->GetSector(x, y, z);
-  a1.uSpriteFrameID = 0;
-  a1.spell_caster_pid = 0;
-  a1.spell_target_pid = 0;
-  v8 = a1.Create(0, 0, 0, 0);
-  if ( v8 != -1 )
-  {
-    v9 = 8 * v8;
-    LOBYTE(v9) = v9 | 2;
-    pAudioPlayer->PlaySound((SoundID)(SOUND_GoldReceived|0x14), v9, 0, -1, 0, 0, 0, 0);
-  }
-}
-
-//----- (0042FA66) --------------------------------------------------------
-void _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6)
-{
-  unsigned __int16 v9; // ax@5
-
-  SpriteObject a1a; // [sp+Ch] [bp-74h]@1
-  //SpriteObject::SpriteObject(&a1a);
-  a1a.uType = 600;
-  a1a.stru_24.Reset();
-
-  a1a.spell_id = SPELL_FIRE_FIREBALL;
-  a1a.spell_level = 8;
-  a1a.spell_skill = 3;
-  v9 = 0;
-  for ( uint i = 0; i < pObjectList->uNumObjects; ++i )
-  {
-    if ( a1a.uType == pObjectList->pObjects[i].uObjectID )
-      v9 = i;
-  }
-  a1a.uObjectDescID = v9;
-  a1a.vPosition.x = a1;
-  a1a.vPosition.y = a2;
-  a1a.vPosition.z = a3;
-  a1a.uAttributes = 0;
-  a1a.uSectorID = pIndoor->GetSector(a1, a2, a3);
-  a1a.uSpriteFrameID = 0;
-  a1a.spell_target_pid = 0;
-  a1a.field_60_distance_related_prolly_lod = 0;
-  a1a.uFacing = 0;
-  a1a.uSoundID = 0;
-  if ( a6 >= 1 || a6 <= 4 )
-    a1a.spell_caster_pid = PID(OBJECT_Player, a6 - 1);
-  else
-    a1a.spell_caster_pid = 0;
-
-  int id = a1a.Create(0, 0, 0, 0);
-  if (id != -1)
-    AttackerInfo.Add(PID(OBJECT_Item, id), a5, SLOWORD(a1a.vPosition.x), SLOWORD(a1a.vPosition.y),
-               SLOWORD(a1a.vPosition.z), 0, 0);
-}
-
-//----- (0042FBDD) --------------------------------------------------------
-void  sub_42FBDD()
-{
-  pAudioPlayer->PlaySound(SOUND_Button2, 0, 0, -1, 0, 0, 0, 0);
-  pRenderer->DrawTextureTransparent(pBtn_YES->uX, pBtn_YES->uY, pBtn_YES->pTextures[0]);
-  pRenderer->Present();
-}
-
-//----- (0042FC15) --------------------------------------------------------
-void  CloseWindowBackground()
-{
-  pAudioPlayer->PlaySound(SOUND_Button2, -2, 0, -1, 0, 0, 0, 0);
-  pRenderer->DrawTextureTransparent(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pBtn_ExitCancel->pTextures[0]);
-  pRenderer->Present();
-}
-
-//----- (0042FC4E) --------------------------------------------------------
-void ProcessInputActions()
-{
-  char v4; // al@9
-  //char v8; // bl@100
-  unsigned __int16 v9; // ax@102
-  int spell_price; // eax@103
-  char v14; // al@159
-  unsigned int v15; // eax@168
-  PartyAction partyAction; // [sp-14h] [bp-1Ch]@20
-  InputAction inputAction; // [sp+0h] [bp-8h]@7
-  //int v24; // [sp+4h] [bp-4h]@87
-
-  pGame->pKeyboardInstance->EnterCriticalSection();
-  Keyboard* pKeyboard = pGame->pKeyboardInstance;
-  if (!bAlwaysRun)
-  {
-    if (pKeyboard->IsShiftHeld())
-      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
-    else
-      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
-   }
-  else
-  {
-    if (pKeyboard->IsShiftHeld())
-      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
-    else
-      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
-  }
-
-  //pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
 
 
-    //  WUT? double event trigger
-  /*for ( uint i = 0; i < 30; ++i )
-  {
-    if ( pKeyActionMap->pToggleTypes[i] )
-      v14 = pGame->pKeyboardInstance->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[i]);
-    else
-      v14 = pGame->pKeyboardInstance->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[i]);
-    if ( v14 )
-    {
-      if (pCurrentScreen == SCREEN_GAME)
-      {
-        pMessageQueue_50CBD0->AddMessage(UIMSG_Game_Action, 0, 0);
-        continue;
-      }
-      if ( pCurrentScreen == SCREEN_NPC_DIALOGUE || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
-      {
-        v15 = pMessageQueue_50CBD0->uNumMessages;
-        if ( pMessageQueue_50CBD0->uNumMessages )
-        {
-          v15 = 0;
-          if ( pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 )
-          {
-            v15 = 1;
-            pMessageQueue_50CBD0->uNumMessages = 0;
-            pMessageQueue_50CBD0->pMessages[v15].eType = UIMSG_Escape;
-            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-            *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-            ++pMessageQueue_50CBD0->uNumMessages;
-            continue;
-          }
-          pMessageQueue_50CBD0->uNumMessages = 0;
-        }
-        //pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-      }
-    }
-  }*/
-  if ( !pEventTimer->bPaused )
-  {
-    for ( uint i = 0; i < 30; ++i )
-    {
-      inputAction = (InputAction)i;
-      if ( pKeyActionMap->pToggleTypes[inputAction] )
-        v4 = pKeyboard->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
-      else
-        v4 = pKeyboard->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
-      if ( v4 )
-      {
-        switch ( inputAction )
-        {
-          case INPUT_MoveForward:
-            if (pCurrentScreen  != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
-                partyAction = PARTY_RunForward;
-              else
-                partyAction = PARTY_WalkForward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if (pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
-            {
-              pTurnEngine->uActionPointsLeft -= 26;
-              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
-                partyAction = PARTY_RunForward;
-              else
-                partyAction = PARTY_WalkForward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            break;
-          case INPUT_MoveBackwards:
-            if (pCurrentScreen  != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_RunBackward;
-              else
-                partyAction = PARTY_WalkBackward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if ( pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
-            {
-              pTurnEngine->uActionPointsLeft -= 26;
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_RunBackward;
-              else
-                partyAction = PARTY_WalkBackward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            break;
-          case INPUT_StrafeLeft:
-            if (pCurrentScreen  != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              partyAction = PARTY_StrafeLeft;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-              break;
-            pTurnEngine->uActionPointsLeft -= 26;
-            partyAction = PARTY_StrafeLeft;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_StrafeRight:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              partyAction = PARTY_StrafeRight;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-              break;
-            pTurnEngine->uActionPointsLeft -= 26;
-            partyAction = PARTY_StrafeRight;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_TurnLeft:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if ( GetAsyncKeyState(VK_CONTROL) ) // strafing
-            {
-              if (pParty->bTurnBasedModeOn)
-              {
-                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-                  break;
-                pTurnEngine->uActionPointsLeft -= 26;
-              }
-              partyAction = PARTY_StrafeLeft;
-            }
-            else
-            {
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_FastTurnLeft;
-              else
-                partyAction = PARTY_TurnLeft;
-            }
-            pPartyActionQueue->Add(partyAction);
-            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
-              pWeather->OnPlayerTurn(10);
-            break;
-          case INPUT_TurnRight:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if ( GetAsyncKeyState(17) )         // strafing
-            {
-              if (pParty->bTurnBasedModeOn)
-              {
-                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-                  break;
-                pTurnEngine->uActionPointsLeft -= 26;
-              }
-              partyAction = PARTY_StrafeRight;
-            }
-            else
-            {
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_FastTurnRight;
-              else
-                partyAction = PARTY_TurnRight;
-            }
-            pPartyActionQueue->Add(partyAction);
-            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
-              pWeather->OnPlayerTurn(-10);
-            break;
-          case INPUT_Jump:
-            if (pCurrentScreen != SCREEN_GAME || pParty->bTurnBasedModeOn)
-              break;
-            partyAction = (PartyAction)12;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_Yell:
-            if (!pCurrentScreen && uActiveCharacter)
-            {
-              pParty->Yell();
-              pPlayers[uActiveCharacter]->PlaySound(SPEECH_Yell, 0);
-            }
-          break;
-          case INPUT_Pass:
-            if ( pCurrentScreen )
-              break;
-            if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
-            {
-              pTurnEngine->field_18 |= TE_FLAG_8;
-              break;
-            }
-            if ( uActiveCharacter )
-            {
-              if ( !pPlayers[uActiveCharacter]->uTimeToRecovery )
-              {
-                if ( !pParty->bTurnBasedModeOn )
-                  pPlayers[uActiveCharacter]->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)pPlayers[uActiveCharacter]->GetAttackRecoveryTime(false) * 2.133333333333333));
-                CastSpellInfoHelpers::_427D48();
-                pTurnEngine->ApplyPlayerAction();
-              }
-            }
-            break;
-          case INPUT_Combat://if press ENTER
-            if (pCurrentScreen == SCREEN_GAME)
-            {
-              if (pParty->bTurnBasedModeOn)
-              {
-                if (pTurnEngine->turn_stage == TE_MOVEMENT || PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
-                {
-                  pParty->bTurnBasedModeOn = 0;
-                  pTurnEngine->End(true);
-                }
-              }
-              else
-              {
-                pTurnEngine->Start();
-                pParty->bTurnBasedModeOn = true;
-              }
-            }
-            break;
-          case INPUT_CastReady:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
-            {
-              pTurnEngine->field_18 |= TE_FLAG_8;
-              break;
-            }
-            if ( !uActiveCharacter )
-              break;
-            v9 = pPlayers[uActiveCharacter]->pActiveSkills[(unsigned __int8)pPlayers[uActiveCharacter]->uQuickSpell / 11 + 12];
-            if ( !pPlayers[uActiveCharacter]->uQuickSpell || bUnderwater
-              || (( !(HIBYTE(v9) & 1)) ? 
-                 ((v9 & 0x80) == 0 ? 
-                 ((v9 & 0x40) == 0 ? spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uNormalLevelMana : spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uExpertLevelMana) : 
-                 spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uMasterLevelMana) : 
-                 spell_price = pSpellDatas[pPlayers[uActiveCharacter]->uQuickSpell].uMagisterLevelMana,
-                 spell_price > pPlayers[uActiveCharacter]->sMana) )
-            {
-              pPartyActionQueue = pPartyActionQueue;
-              pMessageQueue_50CBD0->AddMessage(UIMSG_Attack, 0, 0);
-              break;
-            }
-            else
-              pMessageQueue_50C9E8->AddMessage(UIMSG_CastQuickSpell, 0, 0);
-            break;
-          case INPUT_Attack:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT)
-            {
-              pTurnEngine->field_18 |= TE_FLAG_8;
-              break;
-            }
-            pMessageQueue_50CBD0->AddMessage(UIMSG_Attack, 0, 0);
-            break;
-          case INPUT_EventTrigger:
-            if (pCurrentScreen == SCREEN_GAME)
-            {
-              pMessageQueue_50CBD0->AddMessage(UIMSG_Game_Action, 0, 0);
-              break;
-            }
-            if ( pCurrentScreen == SCREEN_NPC_DIALOGUE )
-            {
-              if ( pMessageQueue_50CBD0->uNumMessages )
-              {
-                pMessageQueue_50CBD0->uNumMessages = 0;
-                if ( pMessageQueue_50CBD0->pMessages[0].field_8 )
-                {
-                  pMessageQueue_50CBD0->uNumMessages = 1;
-                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 = 0;
-                  ++pMessageQueue_50CBD0->uNumMessages;
-                  break;
-                }
-                break;
-              }
-              pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 0, 0);
-            }
-            break;
-          case INPUT_CharCycle:
-            if ( pCurrentScreen == SCREEN_SPELL_BOOK  )
-              break;
-
-            pMessageQueue_50C9E8->AddMessage(UIMSG_CycleCharacters, 0, 0);
-            break;
-          case INPUT_LookUp:
-            if ( pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)7;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_CenterView:
-            if ( pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)9;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_LookDown:
-            if ( pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)8;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_FlyUp:
-            if ( pCurrentScreen || pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)13;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_Land:
-            if ( pCurrentScreen || pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)15;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_FlyDown:
-            if ( !pCurrentScreen
-              && !pEventTimer->bPaused )
-            {
-              partyAction = (PartyAction)14;
-              pPartyActionQueue->Add(partyAction);
-            }
-            break;
-          case INPUT_ZoomIn:
-              pMessageQueue_50C9E8->AddMessage(UIMSG_ClickZoomOutBtn, 0, 0);
-            break;
-          case INPUT_ZoomOut:
-              pMessageQueue_50C9E8->AddMessage(UIMSG_ClickZoomInBtn, 0, 0);
-            break;
-          case INPUT_AlwaysRun:
-            bAlwaysRun = bAlwaysRun == 0;
-            break;
-          default:
-            break;
-        }
-      }
-    }
-  }
-}
--- a/mm7_unsorted_subs.h	Wed Apr 02 20:53:35 2014 +0600
+++ b/mm7_unsorted_subs.h	Wed Apr 02 20:53:47 2014 +0600
@@ -66,15 +66,10 @@
 int ODM_FarClip(unsigned int uNumVertices);
 bool sub_427769_isSpellQuickCastableOnShiftClick(unsigned int uSpellID);
 void _42777D_CastSpell_UseWand_ShootArrow(int a1, unsigned int uPlayerID, unsigned int a4, __int16 a5, int a6);
-void _42ECB5_PlayerAttacksActor();
 void  InitializeTurnBasedAnimations(void *);
-bool __fastcall sub_42F7EB_DropItemAt(unsigned int uSpriteID, int x, int y, int z, int a4, int count, int a7, unsigned __int16 attributes, ItemGen *a9);
-void __fastcall sub_42F960_create_object(int x, int y, int z); // idb
 void CompactLayingItemsList();
-void _42FA66_do_explosive_impact(int a1, int a2, int a3, int a4, __int16 a5, signed int a6);
 void sub_42FBDD();
 void CloseWindowBackground();
-void ProcessInputActions();
 void GameUI_MsgProc();
 void back_to_game();
 void GUI_MainMenuMessageProc();
@@ -83,7 +78,6 @@
 void __fastcall DamagePlayerFromMonster(unsigned int uObjID, int a2, struct Vec3_int_ *pPos, signed int a4);
 void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2); // idb
 double __fastcall sub_43AE12(signed int a1);
-int __fastcall _43AFE3_calc_spell_damage(int a1, int a2, signed int a3, int a4);
 void ItemDamageFromActor(unsigned int uObjID, unsigned int uActorID, struct Vec3_int_ *pVelocity);
 void CharacterUI_LoadPaperdollTextures();
 int GetItemTextureFilename(char *pOut, signed int item_id, int index, int shoulder);