changeset 838:d061180f2b42

Merge
author Gloval
date Thu, 28 Mar 2013 00:37:58 +0400
parents bebc19f3d2af (current diff) b66abf8b7d50 (diff)
children ae8f83e1b0cf 6dd2b94efce7 710cf848ad24
files GUIButton.h SpriteObject.cpp mm7_2.cpp mm7_3.cpp mm7_5.cpp mm7_data.h
diffstat 44 files changed, 2748 insertions(+), 2627 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Actor.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -21,6 +21,14 @@
 #include "GUIWindow.h"
 #include "GUIFont.h"
 
+#include "MM7.h"
+
+
+
+
+
+
+
 Actor pActors[500];
 int uNumActors;
 
@@ -280,7 +288,7 @@
             LOBYTE(pFontArrus->uFontHeight) - 3,
             1,
             0,
-            0x88u,
+            UIMSG_SelectNPCDialogueOption,
             9u,
             0,
             "",
@@ -290,10 +298,10 @@
       }
     }
   }
-  pDialogueWindow->CreateButton(61u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-  pDialogueWindow->CreateButton(177u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-  pDialogueWindow->CreateButton(292u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-  pDialogueWindow->CreateButton(407u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
+  pDialogueWindow->CreateButton(61u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+  pDialogueWindow->CreateButton(177u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+  pDialogueWindow->CreateButton(292u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+  pDialogueWindow->CreateButton(407u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
   if (v17 && uActiveCharacter && !v5->Hired())
   {
     if (pParty->uCurrentHour < 5 || pParty->uCurrentHour > 21)
@@ -384,7 +392,7 @@
   int v15; // eax@34
   AIDirection *v16; // esi@34
   unsigned __int16 v17; // di@34
-  int v18; // eax@34
+  //int v18; // eax@34
   int v19; // edi@34
   int v20; // eax@35
   int v21; // eax@39
@@ -444,7 +452,7 @@
   int v75; // eax@184
   AIDirection *v76; // esi@184
   unsigned __int16 v77; // di@184
-  int v78; // eax@184
+  //int v78; // eax@184
   int v79; // edx@185
   int v80; // eax@185
   int v81; // eax@189
@@ -456,7 +464,7 @@
   unsigned __int16 v87; // di@192
   __int16 v88; // ax@192
   signed int v89; // ecx@192
-  int v90; // eax@192
+  //int v90; // eax@192
   signed int v91; // eax@200
   int v92; // eax@201
   int v93; // ecx@207
@@ -594,26 +602,24 @@
               }
               a1.uObjectDescID = v11;
               a1.stru_24.Reset();
-              a1.field_48 = 15;
+              a1.spell_id = SPELL_AIR_SPARKS;
               v13 = v5->vPosition.x;
               v14 = v5->vPosition.y;
-              a1.field_4C = uSkillLevel;
+              a1.spell_level = uSkillLevel;
               a1.vPosition.x = v13;
               v15 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
               v16 = v117;
               v17 = LOWORD(v117->uYawAngle);
-              a1.field_50 = 0;
+              a1.spell_skill = 0;
               a1.vPosition.y = v14;
               a1.vPosition.z = v15;
               a1.uFacing = v17;
               a1.uSoundID = 0;
               a1.uAttributes = 0;
               a1.uSectorID = pIndoor->GetSector(v13, v14, v15);
-              v18 = 8 * LODWORD(v120);
-              LOBYTE(v18) = 8 * LOBYTE(v120) | AI_OBJECT_ACTOR;
-              a1.field_58_pid = v18;
+              a1.spell_caster_pid = PID(OBJECT_Actor, LODWORD(v120));
               a1.uSpriteFrameID = 0;
-              a1.field_5C = 0;
+              a1.spell_target_pid = 0;
               a1.field_60_distance_related_prolly_lod = 3;
               v19 = spellnuma / -2;
               a1a = spellnuma / 2;
@@ -675,15 +681,15 @@
             }
             a1.uObjectDescID = v82;
             a1.stru_24.Reset();
-            a1.field_48 = spellnum;
+            a1.spell_id = spellnum;
             v83 = v5->vPosition.x;
             v84 = v5->vPosition.y;
-            a1.field_4C = uSkillLevel;
+            a1.spell_level = uSkillLevel;
             a1.vPosition.x = v83;
             v85 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
             v86 = v117;
             v87 = LOWORD(v117->uYawAngle);
-            a1.field_50 = 0;
+            a1.spell_skill = 0;
             a1.vPosition.y = v84;
             a1.vPosition.z = v85;
             a1.uFacing = v87;
@@ -693,11 +699,9 @@
             v89 = v86->uDistance;
             a1.uSectorID = v88;
             LODWORD(v119) = v89;
-            v90 = 8 * LODWORD(v120);
-            LOBYTE(v90) = 8 * LOBYTE(v120) | OBJECT_Actor;
             a1.uSpriteFrameID = 0;
-            a1.field_58_pid = v90;
-            a1.field_5C = 0;
+            a1.spell_caster_pid = PID(OBJECT_Actor, LODWORD(v120));
+            a1.spell_target_pid = 0;
             a1.field_60_distance_related_prolly_lod = 3;
             if ( (double)v89 >= 307.2 )
             {
@@ -822,17 +826,17 @@
                 v34 = spellnumd;
               }
               a1.uObjectDescID = v34;
-              a1.field_4C = uSkillLevel;
+              a1.spell_level = uSkillLevel;
               a1.vPosition.x = v111;
               a1.vPosition.y = v113;
               a1.vPosition.z = v30 + v114;
-              a1.field_48 = 9;
-              a1.field_50 = 0;
+              a1.spell_id = SPELL_FIRE_METEOR_SHOWER;
+              a1.spell_skill = 0;
               a1.uAttributes = 0;
               a1.uSectorID = 0;
               a1.uSpriteFrameID = 0;
-              a1.field_58_pid = v116;
-              a1.field_5C = 0;
+              a1.spell_caster_pid = v116;
+              a1.spell_target_pid = 0;
               a1.field_60_distance_related_prolly_lod = stru_50C198._427546(v30 + 2500);
               a1.uFacing = v32;
               a1.uSoundID = 0;
@@ -1367,26 +1371,24 @@
   }
   a1.uObjectDescID = v71;
   a1.stru_24.Reset();
-  a1.field_48 = 93;
+  a1.spell_id = SPELL_DARK_SHARPMETAL;
   v73 = v5->vPosition.x;
   v74 = v5->vPosition.y;
-  a1.field_4C = uSkillLevel;
+  a1.spell_level = uSkillLevel;
   a1.vPosition.x = v73;
   v75 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
   v76 = v117;
   v77 = LOWORD(v117->uYawAngle);
-  a1.field_50 = 0;
+  a1.spell_skill = 0;
   a1.vPosition.y = v74;
   a1.vPosition.z = v75;
   a1.uFacing = v77;
   a1.uSoundID = 0;
   a1.uAttributes = 0;
   a1.uSectorID = pIndoor->GetSector(v73, v74, v75);
-  v78 = 8 * LODWORD(v120);
-  LOBYTE(v78) = 8 * LOBYTE(v120) | OBJECT_Actor;
-  a1.field_58_pid = v78;
+  a1.spell_caster_pid = PID(OBJECT_Actor, LODWORD(v120));
   a1.uSpriteFrameID = 0;
-  a1.field_5C = 0;
+  a1.spell_target_pid = 0;
   a1.field_60_distance_related_prolly_lod = 3;
   a1c = spellnume / -2;
   if ( spellnume / -2 > spellnume / 2 )
@@ -1490,7 +1492,7 @@
   unsigned __int16 v9; // ax@19
   __int16 v10; // ax@19
   signed int v11; // ecx@19
-  int v12; // eax@19
+  //int v12; // eax@19
   int v13; // edx@28
   //SpriteObject a1; // [sp+Ch] [bp-74h]@1
   unsigned int v15; // [sp+7Ch] [bp-4h]@1
@@ -1567,11 +1569,11 @@
   a1.uObjectDescID = v8;
   a1.stru_24.Reset();
   a1.vPosition.x = v5->vPosition.x;
-  a1.field_48 = 0;
+  a1.spell_id = 0;
   a1.vPosition.y = v5->vPosition.y;
-  a1.field_4C = 0;
+  a1.spell_level = 0;
   v17 = v5->uActorHeight;
-  a1.field_50 = 0;
+  a1.spell_skill = 0;
   v9 = LOWORD(v4->uYawAngle);
   a1.vPosition.z = v5->vPosition.z - (unsigned int)(signed __int64)((double)v17 * -0.75);
   a1.uFacing = v9;
@@ -1580,11 +1582,9 @@
   v10 = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
   v11 = v4->uDistance;
   a1.uSectorID = v10;
-  v12 = 8 * v15;
-  LOBYTE(v12) = 8 * v15 | AI_OBJECT_ACTOR;
   a1.uSpriteFrameID = 0;
-  a1.field_58_pid = v12;
-  a1.field_5C = 0;
+  a1.spell_caster_pid = PID(OBJECT_Actor, v15);
+  a1.spell_target_pid = 0;
   if ( (double)v11 >= 307.2 )
   {
     if ( v11 >= 1024 )
@@ -1645,7 +1645,7 @@
   unsigned __int16 v4; // ax@5
   int v5; // ebx@6
   int v6; // ecx@6
-  int v7; // eax@6
+  //int v7; // eax@6
   SpriteObject a1; // [sp+Ch] [bp-78h]@1
   unsigned int v10; // [sp+7Ch] [bp-8h]@1
   int v11; // [sp+80h] [bp-4h]@6
@@ -1674,11 +1674,11 @@
   a1.uObjectDescID = v4;
   a1.stru_24.Reset();
   a1.vPosition.y = v1->vPosition.y;
-  a1.field_48 = 0;
+  a1.spell_id = 0;
   v5 = v1->vPosition.x;
   v11 = v1->uActorHeight;
-  a1.field_4C = 0;
-  a1.field_50 = 0;
+  a1.spell_level = 0;
+  a1.spell_skill = 0;
   a1.vPosition.x = v5;
   v6 = v1->vPosition.z - (unsigned int)(signed __int64)((double)v11 * -0.75);
   a1.uFacing = 0;
@@ -1686,11 +1686,9 @@
   a1.uSoundID = 0;
   a1.uAttributes = 0;
   a1.uSectorID = pIndoor->GetSector(v5, a1.vPosition.y, v6);
-  v7 = 8 * v10;
-  LOBYTE(v7) = 8 * v10 | OBJECT_Actor;
   a1.uSpriteFrameID = 0;
-  a1.field_58_pid = v7;
-  a1.field_5C = 0;
+  a1.spell_caster_pid = PID(OBJECT_Actor, v10);
+  a1.spell_target_pid = 0;
   a1.field_60_distance_related_prolly_lod = 3;
   a1.field_61 = 4;
   return a1.Create(0, 0, 0, 0);
@@ -1983,7 +1981,7 @@
     v9 = &pActors[v5];
     if ( !a4 )
     {
-      v10 = Actor::GetDirectionInfo(8 * v5 | AI_OBJECT_ACTOR, v4, &a3, 0);
+      v10 = Actor::GetDirectionInfo(PID(OBJECT_Actor, v5), v4, &a3, 0);
       v7 = &v13;
       memcpy(&v13, v10, sizeof(v13));
       v8 = 0;
@@ -2020,7 +2018,7 @@
   
   AIDirection a3;
   if (!a4)
-    a4 = Actor::GetDirectionInfo(8 * uActorID | 3, object_to_face_pid, &a3, 0);
+    a4 = Actor::GetDirectionInfo(PID(OBJECT_Actor, uActorID), object_to_face_pid, &a3, 0);
 
   actor->uAIState = Standing;
   if (!uActionLength)
@@ -2121,7 +2119,7 @@
       v13 = 0;
       if ( !arg0 )
       {
-        v14 = Actor::GetDirectionInfo(8 * v24 | OBJECT_Actor, a2, &a3, 0);
+        v14 = Actor::GetDirectionInfo(PID(OBJECT_Actor, v24), a2, &a3, 0);
         v12 = &v20;
         memcpy(&v20, v14, sizeof(v20));
         v13 = 0;
@@ -3173,7 +3171,7 @@
   int v4; // eax@3
   int v5; // eax@4
   unsigned int v6; // eax@6
-  signed int v7; // eax@12
+  //signed int v7; // eax@12
   signed int v8; // [sp-18h] [bp-1Ch]@10
   signed int v9; // [sp-14h] [bp-18h]@10
   int v10; // [sp-10h] [bp-14h]@10
@@ -3220,9 +3218,7 @@
       v9 = 0;
       v8 = 0;
     }
-    v7 = 8 * uActorID;
-    LOBYTE(v7) = 8 * uActorID | OBJECT_Actor;
-    pAudioPlayer->PlaySound((SoundID)(signed __int16)v3, v7, 0, v8, v9, v10, v11, v12);
+    pAudioPlayer->PlaySound((SoundID)(signed __int16)v3, PID(OBJECT_Actor, uActorID), 0, v8, v9, v10, v11, v12);
   }
 }
 
@@ -3628,7 +3624,7 @@
 		if ( v23 <= v11
 		  && v27 <= v11
 		  && v12 <= v11
-		  && sub_4070EF_prolly_collide_objects(8 * i | OBJECT_Actor, 8 * uActorID | OBJECT_Actor)
+		  && sub_4070EF_prolly_collide_objects(PID(OBJECT_Actor, i), PID(OBJECT_Actor, uActorID))
 		  && v23 * v23 + v27 * v27 + v19 * v19 < (unsigned int)v25 )
 		{
 		  v25 = v23 * v23 + v27 * v27 + v19 * v19;
@@ -3645,7 +3641,7 @@
 	  {
 		//v13 = 8 * v21;
 		//LOBYTE(v13) = 8 * v21 | OBJECT_Actor;
-		*a2 = 8 * v21 | OBJECT_Actor;
+		*a2 = PID(OBJECT_Actor, v21);
 	  }
 
   if (pParty->Invisible())
--- a/Actor.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/Actor.h	Thu Mar 28 00:37:58 2013 +0400
@@ -68,15 +68,6 @@
 
 
 
-/*  337 */
-enum AI_OBJECT_TYPE
-{
-  AI_OBJECT_LAYING_ITEM = 0x2,
-  AI_OBJECT_ACTOR = 0x3,
-  AI_OBJECT_PARTY = 0x4,
-  AI_OBJECT_DECORATION = 0x5,
-};
-
 /*  264 */
 enum AIState : unsigned __int16
 {
--- a/Chest.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Chest.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -37,7 +37,7 @@
 
 //----- (0042041E) --------------------------------------------------------
 bool Chest::Open( signed int uChestID )
-    {
+{
   //char *v1; // edi@5
   unsigned int v2; // eax@8
   GUIWindow *v3; // eax@15
@@ -180,9 +180,9 @@
     a1.stru_24.Reset();
     v24 = *(short *)v23;
     v25 = 0;
-    a1.field_50 = 0;
-    a1.field_4C = 0;
-    a1.field_48 = 0;
+    a1.spell_skill = 0;
+    a1.spell_level = 0;
+    a1.spell_id = 0;
     a1.field_54 = 0;
     a1.uType = v24;
     if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -210,8 +210,8 @@
     a1.uAttributes = 48;
     a1.uSectorID = pIndoor->GetSector(pOut.x, pOut.z, pOut.y);
     a1.uSpriteFrameID = 0;
-    a1.field_58_pid = 0;
-    a1.field_5C = 0;
+    a1.spell_caster_pid = 0;
+    a1.spell_target_pid = 0;
     a1.uFacing = 0;
     a1.Create(0, 0, 0, 0);
     pAudioPlayer->PlaySound(SOUND_8, 0, 0, -1, 0, 0, 0, 0);
@@ -241,9 +241,9 @@
 
   pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640u, 480u, WINDOW_Chest, uChestID, 0);
   pChestWindow = pGUIWindow_CurrentMenu;
-  pBtn_ExitCancel = pChestWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1,  0,  0x71u,  0, 0,  pGlobalTXT_LocalizationStrings[79],// Exit
+  pBtn_ExitCancel = pChestWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1,  0,  UIMSG_Escape,  0, 0,  pGlobalTXT_LocalizationStrings[79],// Exit
                  (Texture *)(uExitCancelTextureId != -1 ? (int)&pIcons_LOD->pTextures[uExitCancelTextureId] : 0),   0);
-  pChestWindow->CreateButton(7u, 8u, 460u, 343u, 1, 0, 0xCu, 0, 0, "", 0);
+  pChestWindow->CreateButton(7u, 8u, 460u, 343u, 1, 0, UIMSG_C, 0, 0, "", 0);
   pCurrentScreen = SCREEN_CHEST;
   pEventTimer->Pause();
   return 1;
--- a/Events.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Events.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -5,7 +5,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Chest.h"
 #include "stru176.h"
@@ -197,11 +196,11 @@
 	LevelDecoration *v26; // eax@55
 	int v27; // eax@57
 	int v28; // ecx@57
-	int v29; // edx@58
-	int v30; // eax@58
-	int v31; // ecx@58
-	int v32; // esi@58
-	NPCData *v33; // ecx@58
+	//int v29; // edx@58
+	int pEventID; // eax@58
+	int pNPC_ID; // ecx@58
+	int pIndex; // esi@58
+	NPCData *pNPC; // ecx@58
 	int v34; // esi@59
 	int v35; // esi@60
 	int v36; // esi@61
@@ -571,82 +570,49 @@
 				//v6 = v123;
 				//v7 = "";
 				break;
-			case EVENT_SetNPCTopic:
-				{
-			
-				v29 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
-				v30 = _evt->v10 + ((_evt->v11 + ((_evt->v12 + ((uint)_evt->v13 << 8)) << 8)) << 8);
-				v31 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
-				v32 = _evt->v9;
-				v33 = &pNPCStats->pNewNPCData[v31];
-				if ( v32 )
-					{
-					v34 = v32 - 1;
-					if ( v34 )
-						{
-						v35 = v34 - 1;
-						if ( v35 )
-							{
-							v36 = v35 - 1;
-							if ( v36 )
-								{
-								v37 = v36 - 1;
-								if ( v37 )
-									{
-									if ( v37 == 1 )
-										v33->evt_F = v30;
-									}
-								else
-									{
-									v33->evt_E = v30;
-									}
-								}
-							else
-								{
-								v33->evt_D = v30;
-								}
-							}
-						else
-							{
-							v33->evt_C = v30;
-							}
-						}
-					else
-						{
-						v33->evt_B = v30;
-						}
-					}
-				else
-					{
-					v33->evt_A = v30;
-					}
-				if ( v29 == 8 )
-					{
-					if ( v30 == 78 )
-						{
-						sub_4BD8B5();
-						window_SpeakInHouse->Release();
-						pParty->uFlags &= ~2;
-						if ( EnterHouse(HOUSE_DARK_GUILD_PIT) )
-							{
-							pAudioPlayer->StopChannels(-1, -1);
-							window_SpeakInHouse = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, 170, 0);
-							window_SpeakInHouse->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-							window_SpeakInHouse->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-							window_SpeakInHouse->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-							window_SpeakInHouse->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
-							window_SpeakInHouse->CreateButton(0, 0, 0, 0, 1, 0, 0xB0u, 0, 9u, "", 0);
-							ptr_F8B1E8 = pNPCTopics[90].pText;
-							}
-						}
-					}
-				++curr_seq_num;
-				}
-				v4 = v124;
-				
-				//v6 = v123;
-				//v7 = "";
-				break;
+            case EVENT_SetNPCTopic:
+            {
+              //v29 = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
+              pEventID = _evt->v10 + ((_evt->v11 + ((_evt->v12 + ((uint)_evt->v13 << 8)) << 8)) << 8);
+              pNPC_ID = _evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8);
+              pIndex = _evt->v9;
+              pNPC = &pNPCStats->pNewNPCData[pNPC_ID];
+              if ( pIndex == 0 )
+                pNPC->evt_A = pEventID;
+              if ( pIndex == 1 )
+                pNPC->evt_B = pEventID;
+              if ( pIndex == 2 )
+                pNPC->evt_C = pEventID;
+              if ( pIndex == 3 )
+                pNPC->evt_D = pEventID;
+              if ( pIndex == 4 )
+                pNPC->evt_E = pEventID;
+              if ( pIndex == 5 )
+                pNPC->evt_F = pEventID;
+              if ( pNPC_ID == 8 )
+              {
+                if ( pEventID == 78 )
+                {
+                  sub_4BD8B5();
+                  window_SpeakInHouse->Release();
+                  pParty->uFlags &= ~2;
+                  if ( EnterHouse(HOUSE_DARK_GUILD_PIT) )
+                  {
+                    pAudioPlayer->StopChannels(-1, -1);
+                    window_SpeakInHouse = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, 170, 0);
+                    window_SpeakInHouse->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+                    window_SpeakInHouse->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+                    window_SpeakInHouse->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+                    window_SpeakInHouse->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
+                    window_SpeakInHouse->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, 9u, "", 0);
+                    current_npc_text = pNPCTopics[90].pText;
+                  }
+                }
+              }
+              ++curr_seq_num;
+            }
+            v4 = v124;
+            break;
 			case EVENT_NPCSetItem:
 				sub_448518_npc_set_item(EVT_DWORD(_evt->v5),EVT_DWORD(_evt->v9), _evt->v13);
 				++curr_seq_num;
@@ -1180,7 +1146,7 @@
 					{
 					if ( activeLevelDecoration == (LevelDecoration*)1 )
 						{
-						ptr_F8B1E8 = pNPCTopics[v90-1].pText;//(&dword_721664)[8 * v90];
+						current_npc_text = pNPCTopics[v90-1].pText;//(&dword_721664)[8 * v90];
 						}
 					if ( canShowMessages == 1 )
 						{
@@ -1209,7 +1175,7 @@
 					{
 					v93 = (char *)pNPCTopics[v92-1].pText;//(&dword_721664)[8 * v92];
 					byte_5B0938[0] = 0;
-					ptr_F8B1E8 = v93;
+					current_npc_text = v93;
 					}
 				else
 					{
@@ -1222,13 +1188,12 @@
 				//v7 = "";
 				break;
 			case EVENT_CastSpell:
-				sub_448DF8_cast_spell(_evt->v5, _evt->v6, _evt->v7, EVT_DWORD(_evt->v8 ),
+              EventCastSpell(_evt->v5, _evt->v6, _evt->v7, EVT_DWORD(_evt->v8 ),
                     EVT_DWORD(_evt->v12 ), EVT_DWORD(_evt->v16 ), EVT_DWORD(_evt->v20 ),
                     EVT_DWORD(_evt->v24 ), EVT_DWORD(_evt->v28 ));
-				++curr_seq_num;
-				v4 = v124;
-			
-				break;
+              ++curr_seq_num;
+              v4 = v124;
+              break;
 			case EVENT_SetTexture:
 				sub_44861E_set_texture(EVT_DWORD(_evt->v5 ), (char *)&_evt->v9);
 				++curr_seq_num;
@@ -1419,11 +1384,11 @@
 					if ( uCurrentHouse_Animation != 167 )
 						v104 = EVT_DWORD(_evt->v5);
 					window_SpeakInHouse = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, v104, 0);
-					window_SpeakInHouse->CreateButton( 61, 424, 31, 0, 2, 94, 0x6Eu, 1, 49, "", 0);
-					window_SpeakInHouse->CreateButton(177, 424, 31, 0, 2, 94, 0x6Eu, 2, 50, "", 0);
-					window_SpeakInHouse->CreateButton(292, 424, 31, 0, 2, 94, 0x6Eu, 3, 51, "", 0);
-					window_SpeakInHouse->CreateButton(407, 424, 31, 0, 2, 94, 0x6Eu, 4, 52, "", 0);
-					window_SpeakInHouse->CreateButton(  0,   0,  0, 0, 1,  0, 0xB0u, 0, 9u, "", 0);
+					window_SpeakInHouse->CreateButton( 61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, 49, "", 0);
+					window_SpeakInHouse->CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, 50, "", 0);
+					window_SpeakInHouse->CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, 51, "", 0);
+					window_SpeakInHouse->CreateButton(407, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 4, 52, "", 0);
+					window_SpeakInHouse->CreateButton(  0,   0,  0, 0, 1,  0, UIMSG_CycleCharacters, 0, 9u, "", 0);
 					}
 				++curr_seq_num;
 				v4 = v124;
--- a/GUIButton.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/GUIButton.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -1,4 +1,3 @@
-#include "GUIButton.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
 #include "Allocator.h"
--- a/GUIButton.h	Thu Mar 28 00:37:27 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-#pragma once
-
-
-/*  156 */
-#pragma pack(push, 1)
-struct GUIButton
-{
-  char DrawLabel(const char *edx0, struct GUIFont *pFont, int a5, int *a9);
-
-  void Release();
-
-
-  unsigned int uX;
-  unsigned int uY;
-  unsigned int uWidth;
-  unsigned int uHeight;
-  unsigned int uZ;
-  unsigned int uW;
-  int uButtonType;
-  int field_1C;//may be pMessageType
-  unsigned int uControlID;
-  unsigned int uControlParam;
-  int field_28;
-  int field_2C_is_pushed;
-  GUIButton *pPrev;
-  GUIButton *pNext;
-  struct GUIWindow *pParent;
-  struct Texture *pTextures[5];
-  unsigned int uNumTextures;
-  unsigned __int8 uHotkey;
-  char pButtonName[32];
-  char field_75[71];
-};
-#pragma pack(pop)
-
-
-
-
-extern struct GUIButton *pBtn_CloseBook;
-extern struct GUIButton *pBtn_InstallRemoveSpell;
-extern struct GUIButton *pBtn_Autonotes_Instructors;
-extern struct GUIButton *pBtn_Autonotes_Misc;
-extern struct GUIButton *pBtn_Book_6;
-extern struct GUIButton *pBtn_Book_5;
-extern struct GUIButton *pBtn_Book_4;
-extern struct GUIButton *pBtn_Book_3;
-extern struct GUIButton *pBtn_Book_2;
-extern struct GUIButton *pBtn_Book_1;
-
-
-extern struct GUIButton *pPlayerCreationUI_BtnReset;
-extern struct GUIButton *pPlayerCreationUI_BtnOK;
-extern struct GUIButton *pBtn_ExitCancel;
-extern struct GUIButton *pBtn_YES;
-extern struct GUIButton *pPlayerCreationUI_BtnPlus;
-extern struct GUIButton *pPlayerCreationUI_BtnMinus;
-
-
-extern struct GUIButton *pButton_RestUI_Main;
-extern struct GUIButton *pButton_RestUI_Exit;
-extern struct GUIButton *pButton_RestUI_Wait5Minutes;
-extern struct GUIButton *pButton_RestUI_WaitUntilDawn;
-extern struct GUIButton *pButton_RestUI_Wait1Hour;
-
-
-extern struct GUIButton *pCharacterScreen_ExitBtn;
-extern struct GUIButton *pCharacterScreen_AwardsBtn;
-extern struct GUIButton *pCharacterScreen_InventoryBtn;
-extern struct GUIButton *pCharacterScreen_SkillsBtn;
-extern struct GUIButton *pCharacterScreen_StatsBtn;
-extern struct GUIButton *pCharacterScreen_DollBtn;
-extern struct GUIButton *pCharacterScreen_DetalizBtn;
-
-
-extern struct GUIButton *pBtn_NPCRight;
-extern struct GUIButton *pBtn_NPCLeft;
-extern struct GUIButton *pBtn_GameSettings;
-extern struct GUIButton *pBtn_QuickReference;
-extern struct GUIButton *pBtn_CastSpell;
-extern struct GUIButton *pBtn_Rest;
-extern struct GUIButton *pBtn_History;
-extern struct GUIButton *pBtn_Calendar;
-extern struct GUIButton *pBtn_Maps;
-extern struct GUIButton *pBtn_Autonotes;
-extern struct GUIButton *pBtn_Quests;
-
-
-extern struct GUIButton *pMainMenu_BtnExit;
-extern struct GUIButton *pMainMenu_BtnCredits;
-extern struct GUIButton *pMainMenu_BtnLoad;
-extern struct GUIButton *pMainMenu_BtnNew;
-
-
-extern struct GUIButton *pBtn_Up;
-extern struct GUIButton *pBtn_Down;
-extern struct GUIButton *ptr_507BA4;
-
-
-extern struct GUIWindow *pPrimaryWindow;
-extern struct GUIWindow *pChestWindow;
-extern struct GUIWindow *pDialogueWindow;
-extern struct GUIWindow *window_SpeakInHouse;
-extern struct GUIWindow *pGUIWindow_ScrollWindow;
-extern struct GUIWindow *ptr_507BC8;
-extern struct GUIWindow *pGUIWindow_CurrentMenu;
-extern struct GUIWindow *ptr_507BD0;
-extern struct GUIWindow *pGUIWindow_Settings;
-extern struct GUIWindow *ptr_507BDC;
-extern struct GUIWindow *pGUIWindow_EscMessageWindow;
-extern struct GUIWindow *pBooksWindow;
-extern struct GUIWindow *pGUIWindow2;
-
-
-extern struct GUIButton *pBtn_Resume;
-extern struct GUIButton *pBtn_QuitGame;
-extern struct GUIButton *pBtn_GameControls;
-extern struct GUIButton *pBtn_LoadGame;
-extern struct GUIButton *pBtn_SaveGame;
-extern struct GUIButton *pBtn_NewGame;
-
-extern struct GUIButton *pBtn_SliderRight;
-extern struct GUIButton *pBtn_SliderLeft;
-
-
-extern struct GUIButton *pBtnDownArrow;
-extern struct GUIButton *pBtnArrowUp;
-extern struct GUIButton *pBtnCancel;
-extern struct GUIButton *pBtnLoadSlot;
-
-
-extern GUIButton *pCreationUI_BtnPressRight2[4];
-extern GUIButton *pCreationUI_BtnPressLeft2[4];
-extern GUIButton *pCreationUI_BtnPressLeft[4];
-extern GUIButton *pCreationUI_BtnPressRight[4];
\ No newline at end of file
--- a/GUIWindow.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/GUIWindow.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -1,5 +1,4 @@
 #include "GUIWindow.h"
-#include "GUIButton.h"
 #include "GUIFont.h"
 #include "Party.h"
 #include "LOD.h"
@@ -469,7 +468,7 @@
   v1 = this;
   pAudioPlayer->StopChannels(-1, -1);
   InitializeBookFonts();
-  v1->CreateButton(0x1DBu, 0x1BDu, 0x9Eu, 0x22u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], 0); // Close
+  v1->CreateButton(0x1DBu, 0x1BDu, 0x9Eu, 0x22u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], 0); // Close
   pCurrentScreen = SCREEN_BOOKS;
   awards_count2 = 0;
   dword_506528 = 0;
@@ -484,8 +483,8 @@
       pTexture_50635C = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("sbmap", TEXTURE_16BIT_PALETTE)];
       pTex_tab_an_6b__zoom_on  = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tab-an-6b", TEXTURE_16BIT_PALETTE)];
       pTex_tab_an_6a__zoom_off = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tab-an-6a", TEXTURE_16BIT_PALETTE)];
-      pBtn_Book_1 = v1->CreateButton(415, 13, 39, 36, 1, 0, 0xB2u, 0, 0, pGlobalTXT_LocalizationStrings[375], 0);
-      pBtn_Book_2 = v1->CreateButton(415, 48, 39, 36, 1, 0, 0xB2u, 1, 0, pGlobalTXT_LocalizationStrings[523], 0);
+      pBtn_Book_1 = v1->CreateButton(415, 13, 39, 36, 1, 0, UIMSG_B2, 0, 0, pGlobalTXT_LocalizationStrings[375], 0);
+      pBtn_Book_2 = v1->CreateButton(415, 48, 39, 36, 1, 0, UIMSG_B2, 1, 0, pGlobalTXT_LocalizationStrings[523], 0);
       v17 = &pParty->pPlayers[_506348_current_lloyd_playerid];
       v23 = 1;
       v18 = v17->pActiveSkills[14];
@@ -503,7 +502,7 @@
           {
           do
               {
-              v1->CreateButton(pLloydsBeaconsPreviewXs[v19], pLloydsBeaconsPreviewYs[v19], 0x5Cu, 0x44u, 1, 180, 0xB3u, v19, 0, "", 0);
+              v1->CreateButton(pLloydsBeaconsPreviewXs[v19], pLloydsBeaconsPreviewYs[v19], 0x5Cu, 0x44u, 1, 180, UIMSG_B3, v19, 0, "", 0);
               ++v19;
               }
               while ( (signed int)v19 < v23 );
@@ -535,7 +534,7 @@
       pTexture_TownPortalIcons[5] = pIcons_LOD->LoadTexturePtr("tphell", TEXTURE_16BIT_PALETTE);
 
       for (uint i = 0; i < 6; ++i)
-        v1->CreateButton(pTownPortalBook_xs[i], pTownPortalBook_ys[i], pTownPortalBook_ws[i], pTownPortalBook_hs[i], 1, 182, 183, i, 0, "", nullptr);
+        v1->CreateButton(pTownPortalBook_xs[i], pTownPortalBook_ys[i], pTownPortalBook_ws[i], pTownPortalBook_hs[i], 1, 182, UIMSG_B7, i, 0, "", nullptr);
       /*v16 = 0;
       do
           {
@@ -555,10 +554,10 @@
       pTex_tab_an_6a__zoom_off = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tab-an-6a", TEXTURE_16BIT_PALETTE)];
       pTex_tab_an_7a__zoot_off = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tab-an-7a", TEXTURE_16BIT_PALETTE)];
       pBtn_Book_1 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1, pTex_tab_an_6b__zoom_on->uTextureWidth,
-          pTex_tab_an_6b__zoom_on->uTextureHeight, 1, 0, 0x47u, 0xBu, 0, pGlobalTXT_LocalizationStrings[192],// "Scroll Up"
+          pTex_tab_an_6b__zoom_on->uTextureHeight, 1, 0, UIMSG_AutonotesBook, 0xBu, 0, pGlobalTXT_LocalizationStrings[192],// "Scroll Up"
           pTex_tab_an_6b__zoom_on, 0);
       pBtn_Book_2 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38, pTex_tab_an_7b__zoot_on->uTextureHeight,
-          pTex_tab_an_7b__zoot_on->uTextureHeight, 1, 0, 0x47u, 0xAu, 0, pGlobalTXT_LocalizationStrings[193],// "Scroll Down"
+          pTex_tab_an_7b__zoot_on->uTextureHeight, 1, 0, UIMSG_AutonotesBook, 0xAu, 0, pGlobalTXT_LocalizationStrings[193],// "Scroll Down"
           pTex_tab_an_7b__zoot_on, 0);
       awards_count = 0;
       memset(&achievedAwardsIndex, 0, 4000);
@@ -596,21 +595,21 @@
       pTexture_506370 = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tab-an-4a", TEXTURE_16BIT_PALETTE)];
       pTexture_50636C = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tab-an-8b", TEXTURE_16BIT_PALETTE)];
       pTexture_506368 = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tab-an-8a", TEXTURE_16BIT_PALETTE)];
-      pBtn_Book_1 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1, 0x32u, 0x22u, 1, 0, 0x47u, 0xBu, 0,
+      pBtn_Book_1 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 0xBu, 0,
           pGlobalTXT_LocalizationStrings[193], pTex_tab_an_6b__zoom_on, 0);
-      pBtn_Book_2 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38, 0x32u, 0x22u, 1, 0, 0x47u, 0xAu, 0,
+      pBtn_Book_2 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 0xAu, 0,
           pGlobalTXT_LocalizationStrings[192], pTex_tab_an_7b__zoot_on, 0);
-      pBtn_Book_3 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 113, 0x32u, 0x22u, 1, 0, 0x47u, 2u, 0,
+      pBtn_Book_3 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 113, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 2u, 0,
           pGlobalTXT_LocalizationStrings[85], pTexture_506394, 0);// "Potion Notes"
-      pBtn_Book_4 = v1->CreateButton(pViewport->uViewportTL_X + 399, pViewport->uViewportTL_Y + 150, 0x32u, 0x22u, 1, 0, 0x47u, 3u, 0,
+      pBtn_Book_4 = v1->CreateButton(pViewport->uViewportTL_X + 399, pViewport->uViewportTL_Y + 150, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 3u, 0,
           pGlobalTXT_LocalizationStrings[137], pTexture_50638C, 0);// "Fountain Notes"
-      pBtn_Book_5 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 0x32u, 0x22u, 1, 0, 0x47u, 4u, 0,
+      pBtn_Book_5 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 4u, 0,
           pGlobalTXT_LocalizationStrings[8], pTexture_506384, 0);// "Obelisk Notes"
-      pBtn_Book_6 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 0x32u, 0x22u, 1, 0, 0x47u, 5u, 0,
+      pBtn_Book_6 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 5u, 0,
           pGlobalTXT_LocalizationStrings[141], pTexture_50637C, 0);// "Seer Notes"
-      pBtn_Autonotes_Misc = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 264, 0x32u, 0x22u, 1, 0, 0x47u, 6u, 0,
+      pBtn_Autonotes_Misc = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 264, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 6u, 0,
           pGlobalTXT_LocalizationStrings[123], pTexture_506374, 0);// "Miscellaneous Notes"
-      v9 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 302, 0x32u, 0x22u, 1, 0, 0x47u, 7u, 0,
+      v9 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 302, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 7u, 0,
           pGlobalTXT_LocalizationStrings[662], pTexture_50636C, 0);// "Instructors"
       v10 = dword_506528;
       pBtn_Autonotes_Instructors = v9;
@@ -650,17 +649,17 @@
       pTexture_506380 = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tabEoff", TEXTURE_16BIT_PALETTE)];
       pTexture_50637C = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tabWon", TEXTURE_16BIT_PALETTE)];
       pTexture_506378 = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture("tabWoff", TEXTURE_16BIT_PALETTE)];
-      pBtn_Book_1 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1, 0x32u, 0x22u, 1, 0, 0x47u, 0, 0,
+      pBtn_Book_1 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 0, 0,
           pGlobalTXT_LocalizationStrings[251], pTex_tab_an_6b__zoom_on, 0);// "Zoom In"
-      pBtn_Book_2 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38, 0x32u, 0x22u, 1, 0, 0x47u, 1, 0,
+      pBtn_Book_2 = v1->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 1, 0,
           pGlobalTXT_LocalizationStrings[252], pTex_tab_an_7b__zoot_on, 0);// "Zoom Out"
-      pBtn_Book_3 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 113, 0x32u, 0x22u, 1, 0, 0x47u, 2, 0,
+      pBtn_Book_3 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 113, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 2, 0,
           pGlobalTXT_LocalizationStrings[192], (Texture *)"", 0);// Scroll Up
-      pBtn_Book_4 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 150, 0x32u, 0x22u, 1, 0, 0x47u, 3, 0,
+      pBtn_Book_4 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 150, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 3, 0,
           pGlobalTXT_LocalizationStrings[193], (Texture *)"", 0);// Scroll Down
-      pBtn_Book_5 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 0x32u, 0x22u, 1, 0, 0x47u, 4, 0,
+      pBtn_Book_5 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 4, 0,
           pGlobalTXT_LocalizationStrings[573], (Texture *)"", 0);// "Scroll Right"
-      pBtn_Book_6 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 0x32u, 0x22u, 1, 0, 0x47u, 5, 0,
+      pBtn_Book_6 = v1->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 0x32u, 0x22u, 1, 0, UIMSG_AutonotesBook, 5, 0,
           pGlobalTXT_LocalizationStrings[572], (Texture *)"", 0);// "Scroll Left"
       }
       break;
@@ -687,7 +686,7 @@
           pTex_tab_an_6b__zoom_on->uTextureHeight,
           1,
           0,
-          0x47u,
+          UIMSG_AutonotesBook,
           0xBu,
           0,
           pGlobalTXT_LocalizationStrings[192],
@@ -700,7 +699,7 @@
           pTex_tab_an_7b__zoot_on->uTextureHeight,
           1,
           0,
-          0x47u,
+          UIMSG_AutonotesBook,
           0xAu,
           0,
           pGlobalTXT_LocalizationStrings[193],
@@ -982,37 +981,37 @@
                    pViewport->uViewportTL_Y +  pIconPos[v4][pSpellbookSpellIndices[v4][i+1]].Ypos,  //dword_4E20D0
                    dword_506408[i + 1]->uTextureWidth,
                    dword_506408[i + 1]->uTextureHeight,
-                   1, 79, 0x56u, i, 0, "", 0);
+                   1, 79, UIMSG_SelectSpell, i, 0, "", 0);
       ++a2;
     //++v3;
   }
   //while ( (signed int)v3 < 11 );
 
-  CreateButton(0, 0, 0, 0, 1, 0, 0x33u, 0, 9u, "", 0);
+  CreateButton(0, 0, 0, 0, 1, 0, UIMSG_33, 0, 9u, "", 0);
   if ( a2 )
     _41D08F(a2, 0, 0, 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_FIRE])
-    CreateButton(0x18Fu, 0xAu, 0x32u, 0x24u, 1, 0, 0x57u, 0, 0, aSpellSchoolNames[0], 0);
+    CreateButton(0x18Fu, 0xAu, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 0, 0, aSpellSchoolNames[0], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_AIR])
-    CreateButton(0x18Fu, 0x2Eu, 0x32u, 0x24u, 1, 0, 0x57u, 1u, 0, aSpellSchoolNames[1], 0);
+    CreateButton(0x18Fu, 0x2Eu, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 1u, 0, aSpellSchoolNames[1], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_WATER])
-    CreateButton(0x18Fu, 0x53u, 0x32u, 0x24u, 1, 0, 0x57u, 2u, 0, aSpellSchoolNames[2], 0);
+    CreateButton(0x18Fu, 0x53u, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 2u, 0, aSpellSchoolNames[2], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_EARTH])
-    CreateButton(0x18Fu, 0x79u, 0x32u, 0x24u, 1, 0, 0x57u, 3u, 0, aSpellSchoolNames[3], 0);
+    CreateButton(0x18Fu, 0x79u, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 3u, 0, aSpellSchoolNames[3], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_SPIRIT])
-    CreateButton(0x18Fu, 0x9Eu, 0x32u, 0x24u, 1, 0, 0x57u, 4u, 0, aSpellSchoolNames[4], 0);
+    CreateButton(0x18Fu, 0x9Eu, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 4u, 0, aSpellSchoolNames[4], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_MIND])
-    CreateButton(0x190u, 0xC4u, 0x32u, 0x24u, 1, 0, 0x57u, 5u, 0, aSpellSchoolNames[5], 0);
+    CreateButton(0x190u, 0xC4u, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 5u, 0, aSpellSchoolNames[5], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_BODY])
-    CreateButton(0x190u, 0xEAu, 0x32u, 0x24u, 1, 0, 0x57u, 6u, 0, aSpellSchoolNames[6], 0);
+    CreateButton(0x190u, 0xEAu, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 6u, 0, aSpellSchoolNames[6], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_LIGHT])
-    CreateButton(0x190u, 0x10Fu, 0x32u, 0x24u, 1, 0, 0x57u, 7u, 0, aSpellSchoolNames[7], 0);
+    CreateButton(0x190u, 0x10Fu, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 7u, 0, aSpellSchoolNames[7], 0);
   if (pPlayer->pActiveSkills[PLAYER_SKILL_DARK])
-    CreateButton(0x190u, 0x133u, 0x32u, 0x24u, 1, 0, 0x57u, 8u, 0, aSpellSchoolNames[8], 0);
-  CreateButton(0x1DCu, 0x1C2u, pTexture_506444->uTextureWidth, pTexture_506444->uTextureHeight, 1, 78, 0x58u, 0, 0, "", 0);
-  pBtn_InstallRemoveSpell = CreateButton(0x1DCu, 0x1C2u, 0x30u, 0x20u, 1, 78, 0x58u, 0, 0, "", pTexture_506444, 0);
-  CreateButton(0x231u, 0x1C2u, ptr_506440->uTextureWidth, ptr_506440->uTextureHeight, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], 0);
-  pBtn_CloseBook = CreateButton(0x231u, 0x1C2u, 0x30u, 0x20u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], ptr_506440, 0);
+    CreateButton(0x190u, 0x133u, 0x32u, 0x24u, 1, 0, UIMSG_OpenSpellbookPage, 8u, 0, aSpellSchoolNames[8], 0);
+  CreateButton(0x1DCu, 0x1C2u, pTexture_506444->uTextureWidth, pTexture_506444->uTextureHeight, 1, 78, UIMSG_58, 0, 0, "", 0);
+  pBtn_InstallRemoveSpell = CreateButton(0x1DCu, 0x1C2u, 0x30u, 0x20u, 1, 78, UIMSG_58, 0, 0, "", pTexture_506444, 0);
+  CreateButton(0x231u, 0x1C2u, ptr_506440->uTextureWidth, ptr_506440->uTextureHeight, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], 0);
+  pBtn_CloseBook = CreateButton(0x231u, 0x1C2u, 0x30u, 0x20u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], ptr_506440, 0);
 }
 // 50640C: using guessed type int dword_50640C[];
 
@@ -1075,15 +1074,15 @@
       JailDialog();
       goto LABEL_58;
     }
-    if ( ptr_F8B1E8 )
+    if ( current_npc_text )
     {
       w.uFrameWidth = 458;
       w.uFrameZ = 457;
-      v5 = pFontArrus->CalcTextHeight(ptr_F8B1E8, &w, 13, 0);
+      v5 = pFontArrus->CalcTextHeight(current_npc_text, &w, 13, 0);
       v6 = v5 + 7;
       pRenderer->_4A6A68(8, 352 - (v5 + 7), &pIcons_LOD->pTextures[uTextureID_Leather], pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - (v5 + 7));
       pRenderer->DrawTextureIndexed(8u, 347 - v6, pTexture_591428);
-      v7 = FitTextInAWindow(ptr_F8B1E8, pFontArrus, &w, 0xDu, 0);
+      v7 = FitTextInAWindow(current_npc_text, pFontArrus, &w, 0xDu, 0);
       window_SpeakInHouse->DrawText(pFontArrus, 13, 354 - v6, 0, v7, 0, 0, 0);
     }
     v8 = 0;
@@ -1666,7 +1665,7 @@
 
 //----- (0041D12F) --------------------------------------------------------
 GUIButton *GUIWindow::CreateButton(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, 
-	int a6, int a7, unsigned int uControlID, unsigned int uControlParam, unsigned __int8 uHotkey, const char *pName, Texture *pTextures, ...)
+	int a6, int a7, UIMessageType msg, unsigned int msg_param, unsigned __int8 uHotkey, const char *pName, Texture *pTextures, ...)
 {
   GUIButton *pButton; // esi@1
   unsigned int v13; // eax@1
@@ -1697,8 +1696,8 @@
   pButton->field_2C_is_pushed = 0;
   pButton->uW = v17 + uHeight - 1;
   pButton->field_1C = a7;
-  pButton->uControlID = uControlID;
-  pButton->uControlParam = uControlParam;
+  pButton->msg = msg;
+  pButton->msg_param = msg_param;
   pButton->uHotkey = uHotkey;
   strlen(pName);
   strcpy(pButton->pButtonName, pName);
@@ -1790,18 +1789,18 @@
         case WINDOW_Dialogue:
           pMainScreenNum = pCurrentScreen;
           pCurrentScreen = SCREEN_NPC_DIALOGUE;
-          pBtn_ExitCancel = pWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], //"Exit"
+          pBtn_ExitCancel = pWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], //"Exit"
                          pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
           if ( pWindow->par1C != 1 )
           {
             num_menu_buttons = 0;
             v11 = LOBYTE(pFontArrus->uFontHeight) - 3;
             speakingNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
-            if ( sub_445C8B(sDialogue_SpeakingActorNPC_ID) == 1 )
+            if ( GetGreetType(sDialogue_SpeakingActorNPC_ID) == 1 )//QuestsNPC_greet
             {
               if ( speakingNPC->joins )
               {
-                pWindow->CreateButton(480, 130, 140, v11, 1, 0, 0x88u, 0xDu, 0, "", 0);
+                pWindow->CreateButton(480, 130, 140, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0xDu, 0, "", 0);
                 num_menu_buttons = 1;
               }
               if ( speakingNPC->evt_A )
@@ -1810,7 +1809,7 @@
                 {
                   v14 = NPC_EventProcessor(speakingNPC->evt_A);
                   if ( v14 == 1 || v14 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x13u, 0, "", 0);
+                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x13u, 0, "", 0);
                 }
               }
               if ( speakingNPC->evt_B )
@@ -1819,7 +1818,7 @@
                 {
                   v16 = NPC_EventProcessor(speakingNPC->evt_B);
                   if ( v16 == 1 || v16 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x14u, 0, "", 0);
+                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x14u, 0, "", 0);
                 }
               }
               if ( speakingNPC->evt_C )
@@ -1828,7 +1827,7 @@
                 {
                   v18 = NPC_EventProcessor(speakingNPC->evt_C);
                   if ( v18 == 1 || v18 == 2 )
-                    pWindow->CreateButton( 0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x15u, 0, "", 0);
+                    pWindow->CreateButton( 0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x15u, 0, "", 0);
                 }
               }
               if ( speakingNPC->evt_D )
@@ -1837,7 +1836,7 @@
                 {
                   v20 = NPC_EventProcessor(speakingNPC->evt_D);
                   if ( v20 == 1 || v20 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x16u, 0, "", 0);
+                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x16u, 0, "", 0);
                 }
               }
               if ( speakingNPC->evt_E )
@@ -1846,7 +1845,7 @@
                 {
                   v22 = NPC_EventProcessor(speakingNPC->evt_E);
                   if ( v22 == 1 || v22 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x17u, 0, "", 0);
+                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x17u, 0, "", 0);
                 }
               }
               if (speakingNPC->evt_F )
@@ -1855,7 +1854,7 @@
                 {
                   v24 = NPC_EventProcessor(speakingNPC->evt_F);
                   if ( v24 == 1 || v24 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x18u, 0, "", 0);
+                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x18u, 0, "", 0);
                 }
               }
             }
@@ -1863,15 +1862,15 @@
             {
               if ( speakingNPC->joins )
               {
-                pWindow->CreateButton(0x1E0u, 0x82u, 0x8Cu, v11, 1, 0, 0x88u, 0x4Du, 0, pGlobalTXT_LocalizationStrings[407], 0);//Ïîäðîáíåå
+                pWindow->CreateButton(0x1E0u, 0x82u, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Du, 0, pGlobalTXT_LocalizationStrings[407], 0);//Ïîäðîáíåå
                 if (speakingNPC->Hired())
                 {
                   sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[408], speakingNPC->pName); //Îòïóñòèòü
-                  pWindow->CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x4Cu, 0, pTmpBuf, 0);
+                  pWindow->CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Cu, 0, pTmpBuf, 0);
                 }
                 else
                 {
-                  pWindow->CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x4Cu, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
+                  pWindow->CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Cu, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
                 }
                 num_menu_buttons = 2;
               }
@@ -1882,12 +1881,12 @@
         case WINDOW_ChangeLocation:
           pMainScreenNum = pCurrentScreen;
           pCurrentScreen = SCREEN_CHANGE_LOCATION;
-          pBtn_ExitCancel = pWindow->CreateButton(0x236u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, 0x5Bu, 0, 0x4Eu, pGlobalTXT_LocalizationStrings[156],//Îñòàòüñÿ â ýòîé îáëàñòè
+          pBtn_ExitCancel = pWindow->CreateButton(0x236u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_5B, 0, 0x4Eu, pGlobalTXT_LocalizationStrings[156],//Îñòàòüñÿ â ýòîé îáëàñòè
                          pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
-          pBtn_YES = pWindow->CreateButton(0x1E6u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, 0x5Au, 0, 0x59u, pWindow->Hint,
+          pBtn_YES = pWindow->CreateButton(0x1E6u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_OnTravelByFoot, 0, 0x59u, pWindow->Hint,
                          pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
-          pWindow->CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 0x3Fu, 0x49u, 1, 0, 0x5Au, 1u, 0x20u, pWindow->Hint, 0, 0, 0);
-          pWindow->CreateButton(8u, 8u, 0x1CCu, 0x158u, 1, 0, 0x5Au, 1u, 0, pWindow->Hint, 0);
+          pWindow->CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 0x3Fu, 0x49u, 1, 0, UIMSG_OnTravelByFoot, 1u, 0x20u, pWindow->Hint, 0, 0, 0);
+          pWindow->CreateButton(8u, 8u, 0x1CCu, 0x158u, 1, 0, UIMSG_OnTravelByFoot, 1u, 0, pWindow->Hint, 0);
           break;
         case WINDOW_SpellBook: // îêíî êíèãè çàêëîâ
           InitializeBookTextures();
@@ -1902,17 +1901,17 @@
       return pWindow;
     }
 //LABEL_62:
-    pWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-    pWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-    pWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-    pWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
-    pWindow->CreateButton(0, 0, 0, 0, 1, 0, 0xB0u, 0, 9u, "", 0);
+    pWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+    pWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+    pWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+    pWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
+    pWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, 9u, "", 0);
     return pWindow;
   }
   if (eWindowType == WINDOW_HouseInterior)
   {
     pCurrentScreen = SCREEN_HOUSE;
-    pBtn_ExitCancel = pWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[80],//Âûéòè èç çäàíèÿ
+    pBtn_ExitCancel = pWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[80],//Âûéòè èç çäàíèÿ
                    pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
     v25 = uNumDialogueNPCPortraits;
     v26 = 0;
@@ -1939,7 +1938,7 @@
         sprintfex(byte_591180[v26], v29, v30);
         HouseNPCData[v26 + 7] = (NPCData *)pWindow->CreateButton(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v26],
                                                                  pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v26],
-                                             0x3Fu, 0x49u, 1, 0, 0x19Au, v26, 0, byte_591180[v26], 0, 0, 0);
+                                             0x3Fu, 0x49u, 1, 0, UIMSG_19A, v26, 0, byte_591180[v26], 0, 0, 0);
         ++v26;
         v25 = uNumDialogueNPCPortraits;
       }
@@ -1957,12 +1956,12 @@
     {
       pMainScreenNum = pCurrentScreen;
       pCurrentScreen = SCREEN_INPUT_BLV;
-      pBtn_ExitCancel = pWindow->CreateButton(0x236u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, 0x19Cu, 0, 0x4Eu, pGlobalTXT_LocalizationStrings[34],//Îòìåíà
-                     (Texture *)(uTextureID_BUTTDESC2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTDESC2] : 0), 0);
-      pBtn_YES = pWindow->CreateButton(0x1E6u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, 0x19Bu, 0, 0x59u, pWindow->Hint,
-                     (Texture *)(uTextureID_BUTTYES2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTYES2] : 0), 0);
-      pWindow->CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 0x3Fu, 0x49u, 1, 0, 0x19Bu, 1, 0x20u, pWindow->Hint, 0);
-      pWindow->CreateButton(8u, 8u, 0x1CCu, 0x158u, 1, 0, 0x19Bu, 1u, 0, pWindow->Hint, 0);
+      pBtn_ExitCancel = pWindow->CreateButton(0x236u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_19C, 0, 0x4Eu, pGlobalTXT_LocalizationStrings[34],//Îòìåíà
+                     pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
+      pBtn_YES = pWindow->CreateButton(0x1E6u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_TransitionUI_Confirm, 0, 0x59u, pWindow->Hint,
+                     pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
+      pWindow->CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 0x3Fu, 0x49u, 1, 0, UIMSG_TransitionUI_Confirm, 1, 0x20u, pWindow->Hint, 0);
+      pWindow->CreateButton(8u, 8u, 0x1CCu, 0x158u, 1, 0, UIMSG_TransitionUI_Confirm, 1u, 0, pWindow->Hint, 0);
       return pWindow;
     }
     if (eWindowType == WINDOW_1B)
@@ -1976,17 +1975,17 @@
     if (eWindowType == WINDOW_Scroll)
       //goto LABEL_62;
     {
-      pWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-      pWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-      pWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-      pWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
-      pWindow->CreateButton(0, 0, 0, 0, 1, 0, 0xB0u, 0, 9u, "", 0);
+      pWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+      pWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+      pWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+      pWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
+      pWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, 9u, "", 0);
       return pWindow;
     }
     if (eWindowType == WINDOW_1F)
     {
       pMouse->SetCursorBitmap("MICON2");
-      pBtn_ExitCancel = pWindow->CreateButton(0x188u, 0x13Eu, 0x4Bu, 0x21u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[34],//Îòìåíà
+      pBtn_ExitCancel = pWindow->CreateButton(0x188u, 0x13Eu, 0x4Bu, 0x21u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[34],//Îòìåíà
                      (Texture *)(uTextureID_BUTTDESC2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTDESC2] : 0), 0);
       ShowStatusBarString(pGlobalTXT_LocalizationStrings[39], 2);//Âûáðàòü öåëü
       ++pIcons_LOD->uTexturePacksCount;
--- a/GUIWindow.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/GUIWindow.h	Thu Mar 28 00:37:58 2013 +0400
@@ -1,5 +1,4 @@
 #pragma once
-#include "GUIButton.h"
 #include "Items.h"
 #include "Player.h"
 
@@ -7,6 +6,209 @@
 
 
 
+enum UIMessageType: unsigned __int32
+{
+  UIMSG_0 = 0,
+
+  UIMSG_ChangeGameState = 5,
+
+  UIMSG_A = 10,
+
+  UIMSG_C = 12,
+
+  UIMSG_E = 14,
+  UIMSG_F = 15,
+
+  UIMSG_11 = 17,
+
+  UIMSG_Attack = 23,
+
+  UIMSG_19 = 25,
+
+  UIMSG_1B = 27,
+  UIMSG_1C = 28,
+  UIMSG_PlayArcomage = 29,
+
+  UIMSG_31 = 49,
+  UIMSG_32 = 50,
+  UIMSG_33 = 51,
+  UIMSG_34 = 52,
+  UIMSG_35 = 53,
+  UIMSG_MainMenu_ShowPartyCreationWnd = 54,
+  UIMSG_MainMenu_ShowLoadWindow = 55,
+  UIMSG_ShowCredits = 56,
+  UIMSG_ExitToWindows = 57,
+  UIMSG_3A = 58,
+
+  UIMSG_PlayerCreationChangeName = 60,
+
+  UIMSG_PlayerCreationClickPlus = 62,
+  UIMSG_PlayerCreationClickMinus = 63,
+  UIMSG_PlayerCreationSelectActiveSkill = 64,
+  UIMSG_PlayerCreationSelectClass = 65,
+  UIMSG_PlayerCreationClickOK = 66,
+  UIMSG_PlayerCreationClickReset = 67,
+  UIMSG_44 = 68,
+  UIMSG_45 = 69,
+  UIMSG_46 = 70,
+  UIMSG_AutonotesBook = 71,
+  UIMSG_48 = 72,
+  UIMSG_49 = 73,
+  UIMSG_PlayerCreationRemoveUpSkill = 74,
+  UIMSG_PlayerCreationRemoveDownSkill = 75,
+
+  UIMSG_4E = 78,
+  UIMSG_SPellbook_ShowHightlightedSpellInfo = 79,
+
+  UIMSG_BuyInShop_Identify_Repair = 81,
+  UIMSG_LoadGame = 82,
+  UIMSG_SaveGame = 83,
+  UIMSG_54 = 84,
+  UIMSG_55 = 85,
+  UIMSG_SelectSpell = 86,
+  UIMSG_OpenSpellbookPage = 87,
+  UIMSG_58 = 88,
+
+  UIMSG_OnTravelByFoot = 90,
+  UIMSG_5B = 91,
+  UIMSG_ShowStatus_DateTime = 92,
+  UIMSG_ShowStatus_ManaHP = 93,
+  UIMSG_ShowStatus_Player = 94,
+  UIMSG_Wait5Minutes  = 95,
+  UIMSG_Wait1Hour = 96,
+  UIMSG_61 = 97,
+
+  UIMSG_ShowStatus_Food = 100,
+  UIMSG_ShowStatus_Funds = 101,
+
+  UIMSG_68 = 104,
+  UIMSG_69 = 105,
+  UIMSG_QuickReference = 106,
+  UIMSG_GameMenuButton = 107,
+
+  UIMSG_AlreadyResting = 109,
+  UIMSG_SelectCharacter = 110,
+  UIMSG_ChangeSoundVolume = 111,
+  UIMSG_ChangeMusicVolume = 112,
+  UIMSG_Escape = 113,
+  UIMSG_72 = 114,
+  UIMSG_73 = 115,
+  UIMSG_74 = 116,
+  UIMSG_75 = 117,
+  UIMSG_PlayerCreation_SelectAttribute = 118,
+
+  UIMSG_InventoryLeftClick = 120,
+  UIMSG_SkillUp = 121,
+  UIMSG_7A = 122,
+  UIMSG_GameMenu_ReturnToGame = 123,
+  UIMSG_StartNewGame = 124,
+  UIMSG_Game_OpenLoadGameDialog = 125,
+  UIMSG_Game_OpenSaveGameDialog = 126,
+  UIMSG_Game_OpenOptionsDialog = 127,
+  UIMSG_80 = 128,
+
+  UIMSG_SetGraphicsMode = 131,
+  UIMSG_Quit = 132,
+  UIMSG_85 = 133,
+  UIMSG_StartHireling1Dialogue = 134,
+  UIMSG_StartHireling2Dialogue = 135,
+  UIMSG_SelectNPCDialogueOption = 136,
+
+  UIMSG_8C = 140,
+  UIMSG_8D = 141,
+  UIMSG_CastSpellFromBook = 142,
+  UIMSG_8F = 143,
+  UIMSG_PlayerCreation_VoicePrev = 144,
+  UIMSG_PlayerCreation_VoiceNext = 145,
+  UIMSG_92 = 146,
+
+  UIMSG_StartNPCDialogue = 161,
+  UIMSG_ArrowUp = 162,
+  UIMSG_DownArrow = 163,
+  UIMSG_LoadSlot = 164,
+  UIMSG_SelectLoadSlot = 165,
+  UIMSG_Cancel = 166,
+  UIMSG_ExitRest = 167,
+  UIMSG_A8 = 168,
+  UIMSG_A9 = 169,
+  UIMSG_AA = 170,
+  UIMSG_PlayerCreation_FacePrev = 171,
+  UIMSG_PlayerCreation_FaceNext = 172,
+  UIMSG_AD = 173,
+  UIMSG_AE = 174,
+  UIMSG_ClickNPCTopic = 175,
+  UIMSG_CycleCharacters = 176,
+  UIMSG_B1 = 177,
+  UIMSG_B2 = 178,
+  UIMSG_B3 = 179,
+  UIMSG_B4 = 180,
+  UIMSG_B5 = 181,
+  UIMSG_B6 = 182,
+  UIMSG_B7 = 183,
+  UIMSG_SetTurnSpeed = 184,
+  UIMSG_ToggleWalkSound = 185,
+  UIMSG_ChangeVoiceVolume = 186,
+  UIMSG_ToggleShowDamage = 187,
+  UIMSG_ScrollNPCPanel = 188,
+  UIMSG_BD = 189,
+  UIMSG_BE = 190,
+  UIMSG_BF = 191,
+  UIMSG_C0 = 192,
+  UIMSG_C1 = 192,
+  UIMSG_C2 = 192,
+
+  UIMSG_OnCastTownPortal = 195,
+  UIMSG_C4 = 196,
+  UIMSG_ShowFinalWindow = 197,
+  UIMSG_C6 = 198,
+  UIMSG_C7 = 199,
+  UIMSG_OpenQuestBook = 200,
+  UIMSG_OpenAutonotes = 201,
+  UIMSG_OpenMapBook = 202,
+  UIMSG_OpenCalendar = 203,
+  UIMSG_CC = 204,
+  UIMSG_CD = 205,
+  UIMSG_CE = 206,
+  UIMSG_CF = 207,
+  UIMSG_D0 = 208,
+  UIMSG_D1 = 209,
+  UIMSG_D2 = 210,
+  UIMSG_D3 = 211,
+  UIMSG_D4 = 212,
+  UIMSG_D5 = 213,
+  UIMSG_D6 = 214,
+
+  UIMSG_DD = 221,
+
+  UIMSG_OpenHistoryBook = 224,
+  UIMSG_ToggleAlwaysRun = 225,
+  UIMSG_ToggleFlipOnExit = 226,
+
+  UIMSG_16F = 367,
+  UIMSG_170 = 368,
+
+  UIMSG_Game_Action = 404,
+  UIMSG_SelectShopDialogueOption = 405,
+
+  UIMSG_OpenRestUI = 409,
+  UIMSG_19A = 410,
+  UIMSG_TransitionUI_Confirm = 411,
+  UIMSG_19C = 412,
+
+  UIMSG_OpenKeyMappingOptions = 415,
+  UIMSG_SelectKeyPage1 = 416,
+  UIMSG_SelectKeyPage2 = 417,
+  UIMSG_ResetKeyMapping = 418,
+  UIMSG_ChangeKeyButton = 419,
+
+  UIMSG_OpenVideoOptions = 421,
+  UIMSG_ToggleBloodsplats = 422,
+  UIMSG_ToggleColoredLights = 423,
+  UIMSG_ToggleTint = 424,
+  UIMSG_1A9 = 425,
+};
+
+
 /*  251 */
 enum MENU_STATE : __int32
 {
@@ -101,6 +303,9 @@
   WINDOW_HistoryBook = 0xE0,
 };
 
+struct GUIButton;
+struct Texture;
+
 /*  155 */
 #pragma pack(push, 1)
 struct GUIWindow
@@ -112,7 +317,7 @@
   }
 
   GUIButton *CreateButton(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, int a6, int a7, 
-	         unsigned int uControlID, unsigned int uControlParam, unsigned __int8 uHotkey, const char *pName, Texture *pTextures, ...);
+	                      UIMessageType msg, unsigned int msg_param, unsigned __int8 uHotkey, const char *pName, Texture *pTextures, ...);
   void DrawFlashingInputCursor(signed int a3, int a4, struct GUIFont *a2);
   int DrawTextInRect(GUIFont *a2, unsigned int uX, unsigned int uY, unsigned int uColor, const char *Str1, int Source, int a8);
   char DrawText(GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, unsigned int uFontShadowColor);
@@ -163,171 +368,6 @@
 
 
 
-enum UIMessageType
-{
-  UIMSG_00 = 0x0,
-  UIMSG_ChangeGameState = 0x5,
-  UIMSG_A = 0xA,
-  UIMSG_C = 0xC,
-  UIMSG_E = 0xE,
-  UIMSG_F = 0xF,
-  UIMSG_11 = 0x11,
-  UIMSG_Attack = 23,
-  UIMSG_19 = 0x19,
-  UIMSG_1B = 0x1B,
-  UIMSG_1C = 0x1C,
-  UIMSG_PlayArcomage = 0x1D,
-  UIMSG_33 = 0x33,
-  UIMSG_MainMenu_ShowPartyCreationWnd = 0x36,
-  UIMSG_MainMenu_ShowLoadWindow = 0x37,
-  UIMSG_ShowCredits = 0x38,
-  UIMSG_ExitToWindows = 0x39,
-  UIMSG_3A = 0x3A,
-  UIMSG_PlayerCreationChangeName = 0x3C,
-  UIMSG_PlayerCreationClickPlus = 0x3E,
-  UIMSG_PlayerCreationClickMinus = 0x3F,
-  UIMSG_PlayerCreationSelectActiveSkill = 0x40,
-  UIMSG_PlayerCreationSelectClass = 0x41,
-  UIMSG_PlayerCreationClickOK = 0x42,
-  UIMSG_PlayerCreationClickReset = 0x43,
-  UIMSG_45 = 0x45,
-  UIMSG_46 = 0x46,
-  UIMSG_AutonotesBook = 0x47,
-  UIMSG_PlayerCreationRemoveUpSkill = 0x4A,
-  UIMSG_PlayerCreationRemoveDownSkill = 0x4B,
-  UIMSG_4E = 0x4E,
-  UIMSG_SPellbook_ShowHightlightedSpellInfo = 0x4F,
-  UIMSG_BuyInShop_Identify_Repair = 0x51,
-  UIMSG_LoadGame = 0x52,
-  UIMSG_SaveGame = 0x53,
-  UIMSG_54 = 0x54,
-  UIMSG_55 = 0x55,
-  UIMSG_SelectSpell = 0x56,
-  UIMSG_57 = 0x57,
-  UIMSG_58 = 0x58,
-  UIMSG_OnTravelByFoot = 0x5A,
-  UIMSG_5B = 0x5B,
-  UIMSG_ShowStatus_DateTime = 0x5C,
-  UIMSG_ShowStatus_ManaHP = 0x5D,
-  UIMSG_ShowStatus_Player = 0x5E,
-  UIMSG_Wait5Minutes  = 0x5F,
-  UIMSG_Wait1Hour = 0x60,
-  UIMSG_61 = 0x61,
-  UIMSG_ShowStatus_Food = 0x64,
-  UIMSG_ShowStatus_Funds = 0x65,
-  UIMSG_68 = 0x68,
-  UIMSG_69 = 0x69,
-  UIMSG_QuickReference = 0x6A,
-  UIMSG_GameMenuButton = 0x6B,
-  UIMSG_AlreadyResting = 0x6D,
-  UIMSG_SelectCharacter = 0x6E,
-  UIMSG_ChangeSoundVolume = 0x6F,
-  UIMSG_ChangeMusicVolume = 0x70,
-  UIMSG_Escape = 0x71,
-  UIMSG_72 = 0x72,
-  UIMSG_73 = 0x73,
-  UIMSG_74 = 0x74,
-  UIMSG_75 = 0x75,
-  UIMSG_PlayerCreation_SelectAttribute = 0x76,
-  UIMSG_InventoryLeftClick = 0x78,
-  UIMSG_SkillUp = 0x79,
-  UIMSG_7A = 0x7A,
-  UIMSG_GameMenu_ReturnToGame = 0x7B,
-  UIMSG_StartNewGame = 0x7C,
-  UIMSG_Game_OpenLoadGameDialog = 0x7D,
-  UIMSG_Game_OpenSaveGameDialog = 0x7E,
-  UIMSG_Game_OpenOptionsDialog = 0x7F,
-  UIMSG_80 = 0x80,
-  UIMSG_SetGraphicsMode = 0x83,
-  UIMSG_Quit = 0x84,
-  UIMSG_85 = 0x85,
-  UIMSG_StartHireling1Dialogue = 0x86,
-  UIMSG_StartHireling2Dialogue = 0x87,
-  UIMSG_SelectNPCDialogueOption = 0x88,
-  UIMSG_8C = 0x8C,
-  UIMSG_8D = 0x8D,
-  UIMSG_CastSpellFromBook = 0x8E,
-  UIMSG_8F = 0x8F,
-  UIMSG_PlayerCreation_VoicePrev = 0x90,
-  UIMSG_PlayerCreation_VoiceNext = 0x91,
-  UIMSG_92 = 0x92,
-  UIMSG_StartNPCDialogue = 0xA1,
-  UIMSG_ArrowUp = 0xA2,
-  UIMSG_DownArrow = 0xA3,
-  UIMSG_LoadSlot = 0xA4,
-  UIMSG_SelectLoadSlot = 0xA5,
-  UIMSG_Cancel = 0xA6,
-  UIMSG_ExitRest = 0xA7,
-  UIMSG_A8 = 0xA8,
-  UIMSG_A9 = 0xA9,
-  UIMSG_AA = 0xAA,
-  UIMSG_PlayerCreation_FacePrev = 0xAB,
-  UIMSG_PlayerCreation_FaceNext = 0xAC,
-  UIMSG_AD = 0xAD,
-  UIMSG_AE = 0xAE,
-  UIMSG_ClickNPCTopic = 0xAF,
-  UIMSG_CycleCharacters = 0xB0,
-  UIMSG_B1 = 0xB1,
-  UIMSG_B2 = 0xB2,
-  UIMSG_B3 = 0xB3,
-  UIMSG_B4 = 0xB4,
-  UIMSG_B5 = 0xB5,
-  UIMSG_B6 = 0xB6,
-  UIMSG_B7 = 0xB7,
-  UIMSG_SetTurnSpeed = 0xB8,
-  UIMSG_ToggleWalkSound = 0xB9,
-  UIMSG_ChangeVoiceVolume = 0xBA,
-  UIMSG_ToggleShowDamage = 0xBB,
-  UIMSG_ScrollNPCPanel = 0xBC,
-  UIMSG_BD = 0xBD,
-  UIMSG_BE = 0xBE,
-  UIMSG_BF = 0xBF,
-  UIMSG_C0 = 0xC0,
-  UIMSG_C1 = 0xC1,
-  UIMSG_C2 = 0xC2,
-  UIMSG_OnCastTownPortal = 0xC3,
-  UIMSG_C4 = 0xC4,
-  UIMSG_ShowFinalWindow = 0xC5,
-  UIMSG_C6 = 0xC6,
-  UIMSG_C7 = 0xC7,
-  UIMSG_OpenQuestBook = 0xC8,
-  UIMSG_OpenAutonotes = 0xC9,
-  UIMSG_OpenMapBook = 0xCA,
-  UIMSG_OpenCalendar = 0xCB,
-  UIMSG_CC = 0xCC,
-  UIMSG_CD = 0xCD,
-  UIMSG_CE = 0xCE,
-  UIMSG_CF = 0xCF,
-  UIMSG_D0 = 0xD0,
-  UIMSG_D1 = 0xD1,
-  UIMSG_D2 = 0xD2,
-  UIMSG_D3 = 0xD3,
-  UIMSG_D4 = 0xD4,
-  UIMSG_D5 = 0xD5,
-  UIMSG_D6 = 0xD6,
-  UIMSG_DD = 0xDD,
-  UIMSG_OpenHistoryBook = 0xE0,
-  UIMSG_ToggleAlwaysRun = 0xE1,
-  UIMSG_ToggleFlipOnExit = 0xE2,
-  UIMSG_16F = 0x16F,
-  UIMSG_170 = 0x170,
-  UIMSG_Game_Action = 0x194,
-  UIMSG_SelectShopDialogueOption = 0x195,
-  UIMSG_OpenRestUI = 0x199,
-  UIMSG_19A = 0x19A,
-  UIMSG_TransitionUI_Confirm = 0x19B,
-  UIMSG_19C = 0x19C,
-  UIMSG_OpenKeyMappingOptions = 0x19F,
-  UIMSG_SelectKeyPage1 = 0x1A0,
-  UIMSG_SelectKeyPage2 = 0x1A1,
-  UIMSG_ResetKeyMapping = 0x1A2,
-  UIMSG_ChangeKeyButton = 0x1A3,
-  UIMSG_OpenVideoOptions = 0x1A5,
-  UIMSG_ToggleBloodsplats = 0x1A6,
-  UIMSG_ToggleColoredLights = 0x1A7,
-  UIMSG_ToggleTint = 0x1A8,
-  UIMSG_1A9 = 0x1A9,
-};
 
 enum CURRENT_SCREEN
 {
@@ -435,4 +475,166 @@
 const char *__fastcall CharacterUI_GetSkillDescText(unsigned int uPlayerID, PLAYER_SKILL_TYPE uPlayerSkillType);
 char __cdecl CharacterUI_SkillsTab_ShowHint();
 char __cdecl CharacterUI_StatsTab_ShowHint();
-char __fastcall CharacterUI_StatsTab_Draw(unsigned int uPlayerID); // idb
\ No newline at end of file
+char __fastcall CharacterUI_StatsTab_Draw(unsigned int uPlayerID); // idb
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#pragma pack(push, 1)
+struct GUIButton
+{
+  char DrawLabel(const char *edx0, struct GUIFont *pFont, int a5, int *a9);
+
+  void Release();
+
+
+  unsigned int uX;
+  unsigned int uY;
+  unsigned int uWidth;
+  unsigned int uHeight;
+  unsigned int uZ;
+  unsigned int uW;
+  int uButtonType;
+  int field_1C;//may be pMessageType
+  UIMessageType msg;
+  unsigned int  msg_param;
+  int field_28;
+  int field_2C_is_pushed;
+  GUIButton *pPrev;
+  GUIButton *pNext;
+  struct GUIWindow *pParent;
+  struct Texture *pTextures[5];
+  unsigned int uNumTextures;
+  unsigned __int8 uHotkey;
+  char pButtonName[32];
+  char field_75[71];
+};
+#pragma pack(pop)
+
+
+
+
+extern struct GUIButton *pBtn_CloseBook;
+extern struct GUIButton *pBtn_InstallRemoveSpell;
+extern struct GUIButton *pBtn_Autonotes_Instructors;
+extern struct GUIButton *pBtn_Autonotes_Misc;
+extern struct GUIButton *pBtn_Book_6;
+extern struct GUIButton *pBtn_Book_5;
+extern struct GUIButton *pBtn_Book_4;
+extern struct GUIButton *pBtn_Book_3;
+extern struct GUIButton *pBtn_Book_2;
+extern struct GUIButton *pBtn_Book_1;
+
+
+extern struct GUIButton *pPlayerCreationUI_BtnReset;
+extern struct GUIButton *pPlayerCreationUI_BtnOK;
+extern struct GUIButton *pBtn_ExitCancel;
+extern struct GUIButton *pBtn_YES;
+extern struct GUIButton *pPlayerCreationUI_BtnPlus;
+extern struct GUIButton *pPlayerCreationUI_BtnMinus;
+
+
+extern struct GUIButton *pButton_RestUI_Main;
+extern struct GUIButton *pButton_RestUI_Exit;
+extern struct GUIButton *pButton_RestUI_Wait5Minutes;
+extern struct GUIButton *pButton_RestUI_WaitUntilDawn;
+extern struct GUIButton *pButton_RestUI_Wait1Hour;
+
+
+extern struct GUIButton *pCharacterScreen_ExitBtn;
+extern struct GUIButton *pCharacterScreen_AwardsBtn;
+extern struct GUIButton *pCharacterScreen_InventoryBtn;
+extern struct GUIButton *pCharacterScreen_SkillsBtn;
+extern struct GUIButton *pCharacterScreen_StatsBtn;
+extern struct GUIButton *pCharacterScreen_DollBtn;
+extern struct GUIButton *pCharacterScreen_DetalizBtn;
+
+
+extern struct GUIButton *pBtn_NPCRight;
+extern struct GUIButton *pBtn_NPCLeft;
+extern struct GUIButton *pBtn_GameSettings;
+extern struct GUIButton *pBtn_QuickReference;
+extern struct GUIButton *pBtn_CastSpell;
+extern struct GUIButton *pBtn_Rest;
+extern struct GUIButton *pBtn_History;
+extern struct GUIButton *pBtn_Calendar;
+extern struct GUIButton *pBtn_Maps;
+extern struct GUIButton *pBtn_Autonotes;
+extern struct GUIButton *pBtn_Quests;
+
+
+extern struct GUIButton *pMainMenu_BtnExit;
+extern struct GUIButton *pMainMenu_BtnCredits;
+extern struct GUIButton *pMainMenu_BtnLoad;
+extern struct GUIButton *pMainMenu_BtnNew;
+
+
+extern struct GUIButton *pBtn_Up;
+extern struct GUIButton *pBtn_Down;
+extern struct GUIButton *ptr_507BA4;
+
+
+extern struct GUIWindow *pPrimaryWindow;
+extern struct GUIWindow *pChestWindow;
+extern struct GUIWindow *pDialogueWindow;
+extern struct GUIWindow *window_SpeakInHouse;
+extern struct GUIWindow *pGUIWindow_ScrollWindow;
+extern struct GUIWindow *ptr_507BC8;
+extern struct GUIWindow *pGUIWindow_CurrentMenu;
+extern struct GUIWindow *ptr_507BD0;
+extern struct GUIWindow *pGUIWindow_Settings;
+extern struct GUIWindow *ptr_507BDC;
+extern struct GUIWindow *pGUIWindow_EscMessageWindow;
+extern struct GUIWindow *pBooksWindow;
+extern struct GUIWindow *pGUIWindow2;
+
+
+extern struct GUIButton *pBtn_Resume;
+extern struct GUIButton *pBtn_QuitGame;
+extern struct GUIButton *pBtn_GameControls;
+extern struct GUIButton *pBtn_LoadGame;
+extern struct GUIButton *pBtn_SaveGame;
+extern struct GUIButton *pBtn_NewGame;
+
+extern struct GUIButton *pBtn_SliderRight;
+extern struct GUIButton *pBtn_SliderLeft;
+
+
+extern struct GUIButton *pBtnDownArrow;
+extern struct GUIButton *pBtnArrowUp;
+extern struct GUIButton *pBtnCancel;
+extern struct GUIButton *pBtnLoadSlot;
+
+
+extern GUIButton *pCreationUI_BtnPressRight2[4];
+extern GUIButton *pCreationUI_BtnPressLeft2[4];
+extern GUIButton *pCreationUI_BtnPressLeft[4];
+extern GUIButton *pCreationUI_BtnPressRight[4];
\ No newline at end of file
--- a/Game.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Game.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -204,7 +204,8 @@
 
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
   {
-    sprintf(pTmpBuf, "Party Sector ID:        %u/%u\n", pBLVRenderParams->uPartySectorID, pIndoor->uNumSectors);
+    auto sector_id = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+    sprintf(pTmpBuf, "Party Sector ID:        %u/%u\n", sector_id, pIndoor->uNumSectors);
     pPrimaryWindow->DrawText(pFontArrus, 16, 16, GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 255), pTmpBuf, 0, 0, 0xFFFFFFFF);
   }
   sprintf(pTmpBuf, "Party Position:         % d % d % d", pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
@@ -213,7 +214,8 @@
   if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
   {
     uint uFaceID;
-    auto floor_level = BLV_GetFloorLevel(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z, pBLVRenderParams->uPartySectorID, &uFaceID);
+    auto sector_id = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
+    auto floor_level = BLV_GetFloorLevel(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + 40, sector_id, &uFaceID);
     sprintf(pTmpBuf, "BLV_GetFloorLevel: %d   face_id %d\n", floor_level, uFaceID);
   }
   else
--- a/GameUIs.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/GameUIs.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -122,21 +122,21 @@
   }
   uTextureID_AR_UP_DN = pIcons_LOD->LoadTexture("AR_UP_DN", TEXTURE_16BIT_PALETTE);
   uTextureID_AR_DN_DN = pIcons_LOD->LoadTexture("AR_DN_DN", TEXTURE_16BIT_PALETTE);
-  pGUIWindow_CurrentMenu->CreateButton(21, 198, 191, 18, 1, 0, 0xA5, 0, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21, 219, 191, 18, 1, 0, 0xA5, 1, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21, 240, 191, 18, 1, 0, 0xA5, 2, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21, 261, 191, 18, 1, 0, 0xA5, 3, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21, 282, 191, 18, 1, 0, 0xA5, 4, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21, 303, 191, 18, 1, 0, 0xA5, 5, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21, 324, 191, 18, 1, 0, 0xA5, 6, 0, "", 0);
-  pBtnLoadSlot = pGUIWindow_CurrentMenu->CreateButton(241, 302, 105, 40, 1, 0, 0xA4, 0, 0, "",
-                 (Texture *)(uTextureID_LS_ != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_LS_] : 0), 0);
-  pBtnCancel = pGUIWindow_CurrentMenu->CreateButton(350, 302, 105, 40, 1, 0, 0xA6, 0, 0, "",
-                 (Texture *)(uTextureID_x_d != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_x_d] : 0), 0);
-  pBtnArrowUp = pGUIWindow_CurrentMenu->CreateButton(215, 199, 17, 17, 1, 0, 0xA2, 0, 0, "",
-                 (Texture *)(uTextureID_AR_UP_DN != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_AR_UP_DN] : 0), 0);
-  pBtnDownArrow = pGUIWindow_CurrentMenu->CreateButton(215, 0x143, 0x11, 0x11, 1, 0, 0xA3, uNumSavegameFiles, 0, "",
-         (Texture *)(uTextureID_AR_DN_DN != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_AR_DN_DN] : 0), 0);
+  pGUIWindow_CurrentMenu->CreateButton(21, 198, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 0, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21, 219, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 1, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21, 240, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 2, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21, 261, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 3, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21, 282, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 4, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21, 303, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 5, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21, 324, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 6, 0, "", 0);
+  pBtnLoadSlot = pGUIWindow_CurrentMenu->CreateButton(241, 302, 105, 40, 1, 0, UIMSG_LoadSlot, 0, 0, "",
+                 pIcons_LOD->GetTexture(uTextureID_LS_), 0);
+  pBtnCancel = pGUIWindow_CurrentMenu->CreateButton(350, 302, 105, 40, 1, 0, UIMSG_Cancel, 0, 0, "",
+                 pIcons_LOD->GetTexture(uTextureID_x_d), 0);
+  pBtnArrowUp = pGUIWindow_CurrentMenu->CreateButton(215, 199, 17, 17, 1, 0, UIMSG_ArrowUp, 0, 0, "",
+                 pIcons_LOD->GetTexture(uTextureID_AR_UP_DN), 0);
+  pBtnDownArrow = pGUIWindow_CurrentMenu->CreateButton(215, 0x143, 0x11, 0x11, 1, 0, UIMSG_DownArrow, uNumSavegameFiles, 0, "",
+         pIcons_LOD->GetTexture(uTextureID_AR_DN_DN), 0);
 
 }
 
@@ -222,19 +222,19 @@
   uTextureID_AR_UP_DN = pIcons_LOD->LoadTexture("AR_UP_DN", TEXTURE_16BIT_PALETTE);
   uTextureID_AR_DN_DN = pIcons_LOD->LoadTexture("AR_DN_DN", TEXTURE_16BIT_PALETTE);
   pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_17, 0, 0);
-  pGUIWindow_CurrentMenu->CreateButton(21u, 198u, 0xBFu, 0x12u, 1, 0, 0xA5u, 0, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21u, 218u, 0xBFu, 0x12u, 1, 0, 0xA5u, 1u, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21u, 238u, 0xBFu, 0x12u, 1, 0, 0xA5u, 2u, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21u, 258u, 0xBFu, 0x12u, 1, 0, 0xA5u, 3u, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21u, 278u, 0xBFu, 0x12u, 1, 0, 0xA5u, 4u, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21u, 298u, 0xBFu, 0x12u, 1, 0, 0xA5u, 5u, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(21u, 318u, 0xBFu, 0x12u, 1, 0, 0xA5u, 6u, 0, "", 0);
-  pBtnLoadSlot = pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0x69u, 0x28u, 1, 0, 0xA4u, 0, 0, "",
+  pGUIWindow_CurrentMenu->CreateButton(21u, 198u, 0xBFu, 0x12u, 1, 0, UIMSG_SelectLoadSlot, 0, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21u, 218u, 0xBFu, 0x12u, 1, 0, UIMSG_SelectLoadSlot, 1u, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21u, 238u, 0xBFu, 0x12u, 1, 0, UIMSG_SelectLoadSlot, 2u, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21u, 258u, 0xBFu, 0x12u, 1, 0, UIMSG_SelectLoadSlot, 3u, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21u, 278u, 0xBFu, 0x12u, 1, 0, UIMSG_SelectLoadSlot, 4u, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21u, 298u, 0xBFu, 0x12u, 1, 0, UIMSG_SelectLoadSlot, 5u, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(21u, 318u, 0xBFu, 0x12u, 1, 0, UIMSG_SelectLoadSlot, 6u, 0, "", 0);
+  pBtnLoadSlot = pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0x69u, 0x28u, 1, 0, UIMSG_LoadSlot, 0, 0, "",
                  (Texture *)(uTextureID_LS_ != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_LS_] : 0), 0);
-  pBtnCancel = pGUIWindow_CurrentMenu->CreateButton(0x15Eu, 0x12Eu, 0x69u, 0x28u, 1, 0, 0xA6u, 0, 0, "",
+  pBtnCancel = pGUIWindow_CurrentMenu->CreateButton(0x15Eu, 0x12Eu, 0x69u, 0x28u, 1, 0, UIMSG_Cancel, 0, 0, "",
                  (Texture *)(uTextureID_x_d != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_x_d] : 0), 0);
-  pBtnArrowUp = pGUIWindow_CurrentMenu->CreateButton( 0xD7u, 0xC7u, 0x11u, 0x11u, 1, 0, 0xA2u, 0, 0, "",
+  pBtnArrowUp = pGUIWindow_CurrentMenu->CreateButton( 0xD7u, 0xC7u, 0x11u, 0x11u, 1, 0, UIMSG_ArrowUp, 0, 0, "",
          (Texture *)(uTextureID_AR_UP_DN != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_AR_UP_DN] : 0), 0);
-  pBtnDownArrow = pGUIWindow_CurrentMenu->CreateButton( 0xD7u, 0x143u, 0x11u, 0x11u, 1, 0, 0xA3u, 0x22u, 0, "",
+  pBtnDownArrow = pGUIWindow_CurrentMenu->CreateButton( 0xD7u, 0x143u, 0x11u, 0x11u, 1, 0, UIMSG_DownArrow, 0x22u, 0, "",
          (Texture *)(uTextureID_AR_DN_DN != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_AR_DN_DN] : 0), 0);
 }
\ No newline at end of file
--- a/Indoor.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Indoor.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -24,10 +24,10 @@
 #include "MapInfo.h"
 #include "IndoorCamera.h"
 #include "GUIWindow.h"
-#include "GUIButton.h"
 #include "GUIFont.h"
 
 #include "mm7_data.h"
+#include "MM7.h"
 
 
 
@@ -533,54 +533,45 @@
         if (pDecalBuilder->uNumDecals > 0)
           pDecalBuilder->ApplyDecals(a4a, 1, &stru_F7B60C, uNumVerticesa, array_507D30, pVertices, 0, pFace->uSectorID);
 
-        if (pFace->Fluid() &&
-            pFace->uBitmapID == pRenderer->hd_water_tile_id )
-        {
-          v23 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
-          v27 = pBitmaps_LOD->pHardwareTextures[v23];
-          if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
-            _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
-          else
-            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-          return;
-        }
         if (pFace->Fluid())
         {
-          //auto v24 = GetTickCount() / 4;
-          //auto v25 = v24 - stru_5C6E00->uIntegerHalfPi;
-          uint eightSeconds = GetTickCount() % 8000;
-          float angle = (eightSeconds / 8000.0f) * 2 * 3.1415f;
-
-          //animte lava back and forth
-          for (uint i = 0; i < uNumVerticesa; ++i)
-            //array_507D30[i].v += (double)(pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 & (unsigned int)(stru_5C6E00->SinCos(v25) >> 8));
-            array_507D30[i].v += pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 * cosf(angle);
-          v23 = pFace->uBitmapID;
-          v27 = pBitmaps_LOD->pHardwareTextures[v23];
-          if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
-            _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
+          if (pFace->uBitmapID == pRenderer->hd_water_tile_id)
+          {
+            v23 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
+            v27 = pBitmaps_LOD->pHardwareTextures[v23];
+          }
           else
-            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-          return;
+          {
+            //auto v24 = GetTickCount() / 4;
+            //auto v25 = v24 - stru_5C6E00->uIntegerHalfPi;
+            uint eightSeconds = GetTickCount() % 8000;
+            float angle = (eightSeconds / 8000.0f) * 2 * 3.1415f;
+
+            //animte lava back and forth
+            for (uint i = 0; i < uNumVerticesa; ++i)
+              //array_507D30[i].v += (double)(pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 & (unsigned int)(stru_5C6E00->SinCos(v25) >> 8));
+              array_507D30[i].v += pBitmaps_LOD->pTextures[pFace->uBitmapID].uHeightMinus1 * cosf(angle);
+            v23 = pFace->uBitmapID;
+            v27 = pBitmaps_LOD->pHardwareTextures[v23];
+          }
         }
         else if (pFace->uAttributes & 0x4000)
         {
           v23 = pTextureFrameTable->GetFrameTexture(pFace->uBitmapID, pBLVRenderParams->field_0_timer_);
           v27 = pBitmaps_LOD->pHardwareTextures[v23];
-          if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
-            _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
-          else
-            pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-          return;
         }
-        v17 = 0xFFFFFFFF;
-        v23 = pFace->uBitmapID;
-        v27 = pBitmaps_LOD->pHardwareTextures[v23];
+        else
+        {
+          v17 = 0xFFD0D0D0;
+          v23 = pFace->uBitmapID;
+          v27 = pBitmaps_LOD->pHardwareTextures[v23];
+        }
+
         if (pFace->uAttributes & FACE_DO_NOT_LIGHT)
           _479A53_draw_some_blv_poly(uNumVerticesa, uFaceID);
         else
-          pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, 8 * uFaceID | OBJECT_BModel, v17, 0);
-        return;;
+          pRenderer->DrawIndoorPolygon(uNumVerticesa, pFace, v27, v28, PID(OBJECT_BModel, uFaceID), v17, 0);
+        return;
       }
     }
   }
@@ -1291,6 +1282,7 @@
   //v39 = &pIndoor->pFaces[uFaceID];
 
   auto pFace = &pIndoor->pFaces[uFaceID];
+  auto p = &nodes[node_id];
 
   if (!pFace->Portal())
   {
@@ -1302,9 +1294,8 @@
     return;
   }
 
-    auto p = &nodes[node_id];
-    //v6 = (int)((char *)this + 2252 * a2);
-    //a0 = v6;
+
+
     if (p->uFaceID == uFaceID)
       return;
     if (!node_id &&
@@ -1316,8 +1307,8 @@
         pBLVRenderParams->vPartyPos.z <= pFace->pBounding.z2 + 16 )
     {
       if ( abs(pFace->pFacePlane_old.dist + pBLVRenderParams->vPartyPos.x * pFace->pFacePlane_old.vNormal.x
-                                       + pBLVRenderParams->vPartyPos.y * pFace->pFacePlane_old.vNormal.y
-                                       + pBLVRenderParams->vPartyPos.z * pFace->pFacePlane_old.vNormal.z) <= 589824 ) // we sure are standing at the portal plane
+                                          + pBLVRenderParams->vPartyPos.y * pFace->pFacePlane_old.vNormal.y
+                                          + pBLVRenderParams->vPartyPos.z * pFace->pFacePlane_old.vNormal.z) <= 589824 ) // we sure are standing at the portal plane
       {
         v7 = pFace->uSectorID;
         if ( nodes[0].uSectorID == v7 )  // draw back sector
@@ -1328,11 +1319,11 @@
         nodes[num_nodes].uViewportZ = pBLVRenderParams->uViewportZ;
         nodes[num_nodes].uViewportY = pBLVRenderParams->uViewportY;
         nodes[num_nodes].uViewportW = pBLVRenderParams->uViewportW;
-        nodes[num_nodes++].field_C._43F9E1(pBLVRenderParams->uViewportX,
-                                           pBLVRenderParams->uViewportY,
-                                           pBLVRenderParams->uViewportZ,
-                                           pBLVRenderParams->uViewportW);
-        AddBspNodeToRenderList(num_nodes - 1);
+        nodes[num_nodes].field_C._43F9E1(pBLVRenderParams->uViewportX,
+                                         pBLVRenderParams->uViewportY,
+                                         pBLVRenderParams->uViewportZ,
+                                         pBLVRenderParams->uViewportW);
+        AddBspNodeToRenderList(++num_nodes - 1);
         return;
       }
       //v5 = v39;
@@ -1368,40 +1359,7 @@
       if (face_max_screenspace_y < _50B9D8_screen_space_y[i])
         face_max_screenspace_y = _50B9D8_screen_space_y[i];
     }
-      //v10 = sub_423B5D(uFaceID);
-      //v34 = v10;
-      //if ( v10 )
-      //{
-       /* v11 = _50BAC8_screen_space_x[0];
-        v12 = _50B9D8_screen_space_y[0];
-        a2 = _50BAC8_screen_space_x[0];
-        v13 = 1;
-        v37 = _50B9D8_screen_space_y[0];
-        if ( v10 > 1 )
-        {
-          do
-          {
-            v14 = _50BAC8_screen_space_x[v13];
-            if ( v14 < a2 )
-              a2 = _50BAC8_screen_space_x[v13];
-            if ( v14 > v11 )
-              v11 = v14;
-            v15 = _50B9D8_screen_space_y[v13];
-            if ( v15 < v37 )
-              v37 = _50B9D8_screen_space_y[v13];
-            if ( v15 > v12 )
-              v12 = _50B9D8_screen_space_y[v13];
-            v10 = v34;
-            ++v13;
-          }
-          while ( v13 < v34 );
-        }
-        //v16 = a0;
-        if (v11 >= p->uViewportX &&
-            a2 <= p->uViewportZ &&
-            v12 >= p->uViewportY &&
-            v37 <= p->uViewportW &&
-            sub_424829(v10, &nodes[num_nodes].field_C, &p->field_C, uFaceID))*/
+
       if (face_max_screenspace_x >= p->uViewportX &&
           face_min_screenspace_x <= p->uViewportZ &&
           face_max_screenspace_y >= p->uViewportY &&
--- a/Items.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/Items.h	Thu Mar 28 00:37:58 2013 +0400
@@ -74,10 +74,12 @@
   ITEM_RILIC_TITANS_BELT = 524,//20C
   ITEM_RELIC_TWILIGHT = 525,//20D
   ITEM_RELIC_MEKORIGS_HAMMER = 0x210,
+  ITEM_ARTIFACT_HERMES_SANDALS = 529,
   ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP = 530,//212
   ITEM_ARTIFACT_MINDS_EYE = 532,//214
   ITEM_ELVEN_CHAINMAIL = 533,//215
-  ITEM_ARTIFAT_HEROS_BELT = 535,//217
+  ITEM_ARTIFACT_HEROS_BELT = 535,//217
+  ITEM_ARTIFACT_LADYS_ESCORT = 536,
   ITEM_RARE_SHADOWS_MASK = 544,//220
   ITEM_RARE_SUN_CLOAK = 547,//223
   ITEM_RARE_MOON_CLOAK = 548,//224
@@ -157,6 +159,8 @@
                             // 64  Double Damage vs. Undead.
                             // 67  Adds 5 points of Body damage and +2 Disarm skill.
                             // 68  Adds 6-8 points of Cold damage and +5 Armor Class.
+                            // 71  Prevents drowning damage.
+                            // 72  Prevents falling damage.
   int uNumCharges;
   unsigned int uAttributes;
   unsigned __int8 uBodyAnchor;
--- a/MM7.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/MM7.h	Thu Mar 28 00:37:58 2013 +0400
@@ -21,6 +21,10 @@
 #define BYTE2(a) (*((unsigned char *)&a + 2))
 #define BYTE3(a) (*((unsigned char *)&a + 3))
 
+#define PID(type, id) (unsigned int)((((8 * (id))) | (type)) & 0xFFFF)  // packed id
+#define PID_TYPE(pid) (unsigned int)((pid) & 7)                         // extract type
+#define PID_ID(pid)   (unsigned int)(((pid) & 0xFFFF) >> 3)             // extract value
+
 
 typedef unsigned __int16 _WORD;
 typedef unsigned __int64 _QWORD;
--- a/NPC.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/NPC.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -385,10 +385,10 @@
 			} while ((decode_step<78)&&!break_loop);
 		}
 
-	for (i=0; i<78; ++i)
+	for ( i = 0; i < 77; ++i )
 		{
 		pProfessionChance[i].uTotalprofChance=0;
-		for (int ii=1; ii<59; ++ii)
+		for ( int ii = 1; ii < 59; ++ii )
 			{
 			pProfessionChance[i].uTotalprofChance+=pProfessionChance[i].professionChancePerArea[ii];
 			}
--- a/Outdoor.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Outdoor.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -24,7 +24,7 @@
 #include "Events.h"
 
 #include "mm7_data.h"
-//#include "MM7.h"
+#include "MM7.h"
 
 
 
@@ -2949,8 +2949,8 @@
 	  y = actor->vPosition.y;
       if (actor->uAIState == Summoned)
       {
-		if ((actor->uSummonerID & 7) != OBJECT_Actor ||
-             pActors[actor->uSummonerID >> 3].pMonsterInfo.uSpecialAbilityDamageDiceSides != 1 )
+		if (PID_TYPE(actor->uSummonerID) != OBJECT_Actor ||
+             pActors[PID_ID(actor->uSummonerID)].pMonsterInfo.uSpecialAbilityDamageDiceSides != 1 )
         {
           z += floorf(actor->uActorHeight * 0.5f + 0.5f);
         }
@@ -3115,7 +3115,7 @@
         HIWORD(v34) = HIWORD(X);
         LOWORD(v34) = 0;
         v28->dimming_level = 0;
-        v28->sZValue = v34 + (8 * i | OBJECT_Actor);
+        v28->sZValue = v34 + PID(OBJECT_Actor, i);
         v28->field_14_actor_id = i;
         v35 = pMonsterList->pMonsters;
 		v36 = actor->pMonsterInfo.uID;
--- a/Party.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Party.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -15,6 +15,7 @@
 #include "texts.h"
 
 #include "mm7_data.h"
+#include "MM7.h"
 
 
 
@@ -139,7 +140,7 @@
   v12 = 0;
   if ( pParty->bTurnBasedModeOn == 1 )
   {
-    if ( pTurnEngine->field_4 != 2 || (pTurnEngine->pQueue[0].uPackedID & 7) != OBJECT_Player)
+    if ( pTurnEngine->field_4 != 2 || PID_TYPE(pTurnEngine->pQueue[0].uPackedID) != OBJECT_Player)
       return 0;
     v2 = pTurnEngine->pQueue[0].uPackedID >> 3;
     return v2 + 1;
--- a/Party.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/Party.h	Thu Mar 28 00:37:58 2013 +0400
@@ -211,8 +211,8 @@
   int uFallSpeed;
   int field_6EC;
   int field_6F0;
-  int field_6F4_packedid;
-  int field_6F8;
+  int floor_face_pid; // face we are standing at
+  int walk_sound_timer;
   int field_6FC;
   int uFallStartY;
   unsigned int bFlying;
--- a/Player.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Player.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Texture.h"
 #include "AudioPlayer.h"
 #include "Party.h"
-#include "GUIButton.h"
 #include "Log.h"
 #include "LOD.h"
 #include "Monsters.h" 
@@ -25,6 +24,7 @@
 #include "texts.h"
 
 #include "mm7_data.h"
+#include "MM7.h"
 
 
 
@@ -582,7 +582,7 @@
   int v9; // eax@10
   //unsigned int pVoiceID; // ecx@10
   int v11; // esi@10
-  signed int v12; // eax@11
+  //signed int v12; // eax@11
   signed int v13; // esi@12
   int v14; // eax@12
   //int v15; // eax@17
@@ -629,8 +629,7 @@
       if (int _v1 = byte_4ECF08[v11 - 1][uVoiceID])
       {
         pSoundId = rand() % _v1 + 2 * (v11 + 50 * uVoiceID) + 4998;
-        v12 = (8 * pPlayerNum + 312) | OBJECT_Player;
-        pAudioPlayer->PlaySound((SoundID)pSoundId, v12, 0, -1, 0, 0, pSoundVolumeLevels[uVoicesVolumeMultiplier] * 128.0f, 0);
+        pAudioPlayer->PlaySound((SoundID)pSoundId, PID(OBJECT_Player, pPlayerNum + 39), 0, -1, 0, 0, pSoundVolumeLevels[uVoicesVolumeMultiplier] * 128.0f, 0);
       }
     }
   }
@@ -4549,7 +4548,7 @@
 //----- (0048E96A) --------------------------------------------------------
 void Player::SetRecoveryTime(signed int rec)
 {
-  assert(rec > 0);
+  assert(rec >= 0);
 
   if (rec > uTimeToRecovery)
     uTimeToRecovery = rec;
--- a/Player.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/Player.h	Thu Mar 28 00:37:58 2013 +0400
@@ -401,7 +401,7 @@
   
   // ?
 
-  CHARACTER_EXPRESSION_46 = 46,
+  CHARACTER_EXPRESSION_SCARED = 46, // like falling
 
   CHARACTER_EXPRESSION_54 = 54,
   CHARACTER_EXPRESSION_55 = 55,
--- a/SpriteObject.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/SpriteObject.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -14,7 +14,16 @@
 #include "LOD.h"
 #include "Actor.h"
 #include "Events.h"
+
 #include "mm7_data.h"
+#include "MM7.h"
+
+
+
+
+
+
+
 
 size_t uNumSpriteObjects;
 SpriteObject pSpriteObjects[MAX_SPRITE_OBJECTS];
@@ -34,9 +43,9 @@
   field_60_distance_related_prolly_lod = 0;
   field_20 = 0;
   uSpriteFrameID = 0;
-  field_50 = 0;
-  field_4C = 0;
-  field_48 = 0;
+  spell_skill = 0;
+  spell_level = 0;
+  spell_id = 0;
   field_54 = 0;
 }
 
@@ -408,11 +417,11 @@
       v58 = v16;
       v18 = WorldPosToGridCellX(v17);
       _46E26D_collide_against_sprites(v18, v58);
-      if ( (v1->field_58_pid & 7) != OBJECT_Player)
+      if (PID_TYPE(v1->spell_caster_pid) != OBJECT_Player)
         _46EF01_collision_chech_player(0);
-      if ( (v1->field_58_pid & 7) == OBJECT_Actor)
+      if (PID_TYPE(v1->spell_caster_pid) == OBJECT_Actor)
       {
-        v19 = v1->field_58_pid >> 3;
+        v19 = PID_ID(v1->spell_caster_pid);
         if ( v19 >= 0 )
         {
           if ( v19 < (signed int)(uNumActors - 1) )
@@ -514,10 +523,10 @@
         if ( !_46BFFA_check_object_intercept(uLayingItemID_, stru_721530.uFaceID) )
           return;
       }
-      v30 = (signed int)stru_721530.uFaceID >> 3;
-      if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
+      v30 = (signed int)PID_ID(stru_721530.uFaceID);
+      if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)
         break;
-      if ( (stru_721530.uFaceID & 7) == OBJECT_BModel)
+      if (PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel)
       {
         v31 = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9];
         v32 = &v31->pFaces[v30 & 0x3F];
@@ -698,11 +707,11 @@
       {
         _46E44E_collide_against_faces_and_portals(0);
         _46E0B2_collide_against_decorations();
-        if ( (pSpriteObject->field_58_pid & 7) != OBJECT_Player)
+        if (PID_TYPE(pSpriteObject->spell_caster_pid) != OBJECT_Player)
           _46EF01_collision_chech_player(1);
-        v13 = pSpriteObject->field_58_pid;
+        v13 = pSpriteObject->spell_caster_pid;
         v42 = v8;
-        if ( (v13 & 7) == OBJECT_Actor)
+        if (PID_TYPE(v13) == OBJECT_Actor)
         {
           if ( (signed int)uNumActors > v8 )
           {
@@ -713,7 +722,7 @@
               //v14 = (signed __int64)((double)v41 * 0.3333333333333333);
               //v41 = *(short *)(v39 - 38) - 1;
               //if ( v14 != (unsigned int)(signed __int64)((double)v41 * 0.3333333333333333) )
-				if( pActors[pSpriteObject->field_58_pid >> 3].pMonsterInfo.uID != v39b->pMonsterInfo.uID )
+				if( pActors[pSpriteObject->spell_caster_pid >> 3].pMonsterInfo.uID != v39b->pMonsterInfo.uID )
 					//not sure: pMonsterList->pMonsters[v39b->word_000086_some_monster_id-1].uToHitRadius
 					_46DF1A_collide_against_actor(v42, *((short *)&pMonsterList->pMonsters[v39b->word_000086_some_monster_id] - 73));
               ++v42;
@@ -800,7 +809,7 @@
       if ( pObject->uFlags & 0x40 && !_46BFFA_check_object_intercept(uLayingItemID, stru_721530.uFaceID) )
         return;
       v15 = (signed int)stru_721530.uFaceID >> 3;
-      if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
+      if (PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration)
       {
         v40 = integer_sqrt(pSpriteObject->vVelocity.x * pSpriteObject->vVelocity.x + pSpriteObject->vVelocity.y * pSpriteObject->vVelocity.y);
         v23 = stru_5C6E00->Atan2(pSpriteObject->vPosition.x - pLevelDecorations[v15].vPosition.x,
@@ -817,9 +826,9 @@
       }
       else
       {
-        if ( (stru_721530.uFaceID & 7) != OBJECT_BModel)
+        if (PID_TYPE(stru_721530.uFaceID) != OBJECT_BModel)
           goto LABEL_64;
-        stru_721530.field_84 = (signed int)stru_721530.uFaceID >> 3;
+        stru_721530.field_84 = (signed int)PID_ID(stru_721530.uFaceID);
         v16 = &pIndoor->pFaces[v15];
         if ( v16->uPolygonType != 3 )
         {
--- a/SpriteObject.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/SpriteObject.h	Thu Mar 28 00:37:58 2013 +0400
@@ -36,12 +36,12 @@
   __int16 field_20;
   __int16 field_22_glow_radius_multiplier;
   struct ItemGen stru_24;
-  int field_48;
-  int field_4C;
-  int field_50;
+  int spell_id;
+  int spell_level;
+  int spell_skill;
   int field_54;
-  int field_58_pid;
-  int field_5C;
+  int spell_caster_pid;
+  int spell_target_pid;
   char field_60_distance_related_prolly_lod;
   char field_61;
   char field_62[2];
--- a/UIBooks.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UIBooks.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
--- a/UICharacter.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UICharacter.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -3392,8 +3391,7 @@
                 ptr_50C9A4 = 0;
                 }
             v32 = (double)GetTickCount() * 0.1;
-            pRenderer->_4A63E6(0x24Au, 0x58u, (Texture *)(v28 != -1 ? (int)&pIcons_LOD->pTextures[v28] : 0),
-                v31, (signed __int64)v32, 0, 255);
+            pRenderer->_4A63E6(0x24Au, 0x58u, pIcons_LOD->GetTexture(v28), v31, (signed __int64)v32, 0, 255);
         }
 
 //----- (0043BCA7) --------------------------------------------------------
@@ -3553,7 +3551,7 @@
     if (sub_43EE15_player_has_item(ITEM_ARTIFACT_MINDS_EYE, player, 1))          byte_5111F6[7] = 1;
     if (sub_43EE15_player_has_item(ITEM_RARE_SHADOWS_MASK, player, 1))           byte_5111F6[8] = 1;
     if (sub_43EE15_player_has_item(ITEM_RILIC_TITANS_BELT, player, 1))           byte_5111F6[9] = 1;
-    if (sub_43EE15_player_has_item(ITEM_ARTIFAT_HEROS_BELT, player, 1))          byte_5111F6[10] = 1;
+    if (sub_43EE15_player_has_item(ITEM_ARTIFACT_HEROS_BELT, player, 1))         byte_5111F6[10] = 1;
     if (sub_43EE15_player_has_item(ITEM_RELIC_TWILIGHT, player, 1))              byte_5111F6[11] = 1;
     if (sub_43EE15_player_has_item(ITEM_ARTIFACT_CLOAK_OF_THE_SHEEP, player, 1)) byte_5111F6[12] = 1;
     if (sub_43EE15_player_has_item(ITEM_RARE_SUN_CLOAK, player, 1))              byte_5111F6[13] = 1;
@@ -3760,9 +3758,9 @@
     v0 = uActiveCharacter;
     dword_507CC0 = uActiveCharacter;
     for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
+    {
+        if ( pButton->msg == UIMSG_InventoryLeftClick )
         {
-        if ( pButton->uControlID == 120 )
-            {
             dword_50698C = pButton->uX;
             dword_506988 = pButton->uY;
             dword_506984 = pButton->uZ;
@@ -3788,7 +3786,7 @@
             v3 = v3 + v4 - 3;
             ++a2;
             ++v12;
-            pGUIWindow_CurrentMenu->CreateButton(0x18u, v3, 0xCCu, v4 - 3, 3, *v14 | 0x8000, 0x79u, *v14, 0, "", 0, 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x18u, v3, 0xCCu, v4 - 3, 3, *v14 | 0x8000, UIMSG_SkillUp, *v14, 0, "", 0, 0);
             v2 = pFontLucida;
             }
         ++v14;
@@ -3805,7 +3803,7 @@
                 v6 = LOBYTE(v2->uFontHeight);
                 v5 = v5 + v6 - 3;
                 ++a2;
-                pGUIWindow_CurrentMenu->CreateButton(0x18u, v5, 0xCCu, v6 - 3, 3, *v15 | 0x8000, 0x79u, *v15, 0, "", 0, 0);
+                pGUIWindow_CurrentMenu->CreateButton(0x18u, v5, 0xCCu, v6 - 3, 3, *v15 | 0x8000, UIMSG_SkillUp, *v15, 0, "", 0, 0);
                 v2 = pFontLucida;
                 }
             ++v15;
@@ -3822,7 +3820,7 @@
                     v7 = v7 + v8 - 3;
                     ++a2;
                     ++v13;
-                    pGUIWindow_CurrentMenu->CreateButton(0xF6u, v7, 0xCCu, v8 - 3, 3, *v16 | 0x8000, 0x79u, *v16, 0, "", 0, 0);
+                    pGUIWindow_CurrentMenu->CreateButton(0xF6u, v7, 0xCCu, v8 - 3, 3, *v16 | 0x8000, UIMSG_SkillUp, *v16, 0, "", 0, 0);
                     v2 = pFontLucida;
                     }
                 ++v16;
@@ -3839,7 +3837,7 @@
                         v10 = LOBYTE(v2->uFontHeight);
                         v9 = v9 + v10 - 3;
                         ++a2;
-                        pGUIWindow_CurrentMenu->CreateButton(0xF6u, v9, 0xCCu, v10 - 3, 3, *v17 | 0x8000, 0x79u, *v17, 0, "", 0, 0);
+                        pGUIWindow_CurrentMenu->CreateButton(0xF6u, v9, 0xCCu, v10 - 3, 3, *v17 | 0x8000, UIMSG_SkillUp, *v17, 0, "", 0, 0);
                         v2 = pFontLucida;
                         }
                     ++v17;
--- a/UIHouses.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UIHouses.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -7,7 +7,6 @@
 #include "LOD.h"
 #include "Mouse.h"
 #include "GUIWindow.h"
-#include "GUIButton.h"
 #include "GUIFont.h"
 #include "Events2D.h"
 #include "Overlays.h"
@@ -484,7 +483,7 @@
 		}
 	uOpenTime = p2DEvents[uHouseID - 1].uOpenTime;
 	uCloseTime = p2DEvents[uHouseID - 1].uCloseTime;
-	ptr_F8B1E8 = 0;
+	current_npc_text = 0;
 	dword_F8B1E4 = 0;
 	dword_F8B1F4 = 0;
 	memset(byte_F8B1F0, 0, 4);
@@ -724,9 +723,9 @@
 		}
 		pDialogueWindow->Release();
 		pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
-		pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
+		pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
 					                                    pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
-		pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, 0x51u, 0, 0, "", nullptr);
+		pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
 //	LABEL_10:
 		//v3 = dword_F8B198;
 		v8 = window_SpeakInHouse;
@@ -742,9 +741,9 @@
 		//LABEL_9:
 			pDialogueWindow->Release();
 			pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
-			pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
+			pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
 						                                    pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
-			pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, 0x51u, 0, 0, "", nullptr);
+			pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
 	//	LABEL_10:
 			//v3 = dword_F8B198;
 			v8 = window_SpeakInHouse;
@@ -2147,7 +2146,7 @@
 		v8 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
 		sprintf(pTmpBuf, &byte_4F0F98, v8, v7, v6);
 		sprintf(pTmpBuf2, dword_F8B1A4, pTmpBuf, 100 * v5->uLevel);
-		ptr_F8B1E8 = pTmpBuf2;
+		current_npc_text = pTmpBuf2;
 		memcpy(&a1, pDialogueWindow, sizeof(a1));
 		w.uFrameWidth = 458;
 		w.uFrameZ = 457;
@@ -2156,13 +2155,13 @@
 		if ( 352 - v9 < 8 )
 		{
 			pOutString = pFontCreate;
-			v9 = pFontCreate->CalcTextHeight(ptr_F8B1E8, &w, 13, 0) + 7;
+			v9 = pFontCreate->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
 		}
 
 		auto pTex = (uTextureID_Leather != -1 ? &pIcons_LOD->pTextures[uTextureID_Leather] : 0);
 		pRenderer->_4A6A68(8u, 352 - v9, pTex, (pTex ? pTex->uTextureHeight : 26) - v9);
 		pRenderer->DrawTextureIndexed(8u, 347 - v9, pTexture_591428);
-		v10 = FitTextInAWindow(ptr_F8B1E8, pOutString, &w, 0xDu, 0);
+		v10 = FitTextInAWindow(current_npc_text, pOutString, &w, 0xDu, 0);
 		a1.DrawText(pOutString, 13, 354 - v9, 0, v10, 0, 0, 0);
 		break;
 		}
@@ -2546,7 +2545,7 @@
       while ( 1 )
       {
         pButton = pDialogueWindow->GetControl(pNumActiveItem);
-        if ( pButton->uControlParam == 15 )
+        if ( pButton->msg_param == 15 )
         {
           v46 = pTextHeight;
           pButton->uHeight = pTextHeight;
@@ -2554,7 +2553,7 @@
           v41 = v46 + 145;
           pButton->uW = v41;
         }
-        else if ( pButton->uControlParam == 16 )
+        else if ( pButton->msg_param == 16 )
         {
           v44 = v88;
           v45 = pTextHeight + v36 + 146;
@@ -2563,7 +2562,7 @@
           v41 = v45 + v44 - 1;
           pButton->uW = v41;
         }
-        else if ( pButton->uControlParam == 96 )
+        else if ( pButton->msg_param == 96 )
         {
           v42 = pTextHeight + v88 + 2 * v36 + 146;
           v43 = v82;
@@ -2572,7 +2571,7 @@
           v41 = v43 + v42 - 1;
           pButton->uW = v41;
         }
-        else if ( pButton->uControlParam == 101 )
+        else if ( pButton->msg_param == 101 )
         {
           v39 = pTextHeight + 3 * v36 + pTextHeight + v88 + 146;
           v40 = v87;
@@ -2690,7 +2689,7 @@
       {
         do
         {
-          v12 = pDialogueWindow->GetControl(pNumActiveItem)->uControlParam - 36;
+          v12 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
           if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v12] && !pPlayer->pActiveSkills[v12] )
           {
             all_text_height = pFontArrus->CalcTextHeight(pSkillNames[v12], &dialog_window, 0, 0);
@@ -2714,7 +2713,7 @@
             do
             {
               pButton = pDialogueWindow->GetControl(pItemNum);
-              v17 = pButton->uControlParam - 36;
+              v17 = pButton->msg_param - 36;
               if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v17] || pPlayer->pActiveSkills[v17] )
               {
                 pButton->uW = 0;
@@ -3283,7 +3282,7 @@
       }
       do
       {
-        v35 = pDialogueWindow->GetControl(pNumActiveItem)->uControlParam - 36;
+        v35 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
         if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v35] && !pPlayer->pActiveSkills[v35] )
         {
           all_text_height += pFontArrus->CalcTextHeight(pSkillNames[v35], &dialog_window, 0, 0);
@@ -3314,7 +3313,7 @@
         do
         {
           pButton = pDialogueWindow->GetControl(pItemNum);
-          v40 = pButton->uControlParam - 36;
+          v40 = pButton->msg_param - 36;
           if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v40] || pPlayer->pActiveSkills[v40] )
           {
             pButton->uW = 0;
@@ -3852,7 +3851,7 @@
       }
       do
       {
-        v8 = pDialogueWindow->GetControl(pNumActiveItem)->uControlParam - 36;
+        v8 = pDialogueWindow->GetControl(pNumActiveItem)->msg_param - 36;
         if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v8] && !pPlayer->pActiveSkills[v8] )
         {
           all_text_height = pFontArrus->CalcTextHeight(pSkillNames[v8], &dialog_window, 0, 0);
@@ -3885,7 +3884,7 @@
           do
           {
             pButton = pDialogueWindow->GetControl(pItemNum);
-            v13 = pButton->uControlParam - 36;
+            v13 = pButton->msg_param - 36;
             if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayer->classType][v13] || pPlayer->pActiveSkills[v13] )
             {
               pButton->uW = 0;
@@ -4523,7 +4522,7 @@
             {
             do
                 {
-                v41 = v37->GetControl(v39)->uControlParam - 36;
+                v41 = v37->GetControl(v39)->msg_param - 36;
                 if ( byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v41] && !v0->pActiveSkills[v41] )
                     {
                     v42 = pFontArrus->CalcTextHeight(pSkillNames[v41], &dialog_window, 0, 0);
@@ -4550,7 +4549,7 @@
                             {
                             v44 = v37->GetControl(v152);
                             v45 = v44;
-                            v46 = v44->uControlParam - 36;
+                            v46 = v44->msg_param - 36;
                             if ( !byte_4ED970_skill_learn_ability_by_class_table[v0->classType][v46] || v0->pActiveSkills[v46] )
                                 {
                                 v45->uW = 0;
@@ -4830,7 +4829,7 @@
             }
         do
             {
-            v23 = v20->GetControl(v21)->uControlParam;
+            v23 = v20->GetControl(v21)->msg_param;
             if ( v23 == 18 )
                 {
                 v25 = pFontArrus->CalcTextHeight(pGlobalTXT_LocalizationStrings[400], &working_window, 0, 0); //"Buy Spells"
@@ -4881,7 +4880,7 @@
                     {
                     v27 = v20->GetControl(v62);
                     v28 = v27;
-                    v29 = v27->uControlParam;
+                    v29 = v27->msg_param;
                     if ( v29 == 18 )
                         break;
 
@@ -5040,7 +5039,7 @@
                             goto LABEL_78;
                         do
                             {
-                            v9 = v4->GetControl(v62)->uControlParam - 36;
+                            v9 = v4->GetControl(v62)->msg_param - 36;
                             if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v9] && !v1->pActiveSkills[v9] )
                                 {
                                 v10 = pFontArrus->CalcTextHeight(pSkillNames[v9], &v57, 0, 0);
@@ -5070,7 +5069,7 @@
                                         {
                                         v14 = v12->GetControl(v62);
                                         v15 = v14;
-                                        v16 = v14->uControlParam - 36;
+                                        v16 = v14->msg_param - 36;
                                         if ( !byte_4ED970_skill_learn_ability_by_class_table[v1->classType][v16] || v1->pActiveSkills[v16] )
                                             {
                                             v15->uW = 0;
@@ -5441,7 +5440,7 @@
               goto LABEL_76;
             do
             {
-              v17 = v13->GetControl(v15)->uControlParam - 36;
+              v17 = v13->GetControl(v15)->msg_param - 36;
               if ( byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v17] && !pPlayers[uActiveCharacter]->pActiveSkills[v17] )
               {
                 v18 = pFontArrus->CalcTextHeight(pSkillNames[v17], &v65, 0, 0);
@@ -5469,7 +5468,7 @@
                 {
                   v20 = v13->GetControl(_v1);
                   v21 = v20;
-                  v22 = v20->uControlParam - 36;
+                  v22 = v20->msg_param - 36;
                   if ( !byte_4ED970_skill_learn_ability_by_class_table[pPlayers[uActiveCharacter]->classType][v22] || pPlayers[uActiveCharacter]->pActiveSkills[v22] )
                   {
                     v21->uW = 0;
@@ -5619,7 +5618,7 @@
         v45 = pShopOptions;
         do
         {
-          if ( v43->GetControl(v73)->uControlParam == HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
+          if ( v43->GetControl(v73)->msg_param == HOUSE_DIALOGUE_TRAININGHALL_TRAIN )
           {
             //v46 = pPlayers[uActiveCharacter]->uLevel;
             if (pPlayers[uActiveCharacter]->uLevel >= v68)
@@ -5899,7 +5898,7 @@
             goto LABEL_140;
           do
           {
-            v36 = v31->GetControl(v34)->uControlParam - 36;
+            v36 = v31->GetControl(v34)->msg_param - 36;
             if ( byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v36] && !_this->pActiveSkills[v36] )
             {
               v37 = pFontArrus->CalcTextHeight(pSkillNames[v36], &dialog_window, 0, 0);
@@ -5941,7 +5940,7 @@
             {
               v39 = v31->GetControl(v118);
               v40 = v39;
-              v41 = v39->uControlParam - 36;
+              v41 = v39->msg_param - 36;
               if ( !byte_4ED970_skill_learn_ability_by_class_table[_this->classType][v41] || _this->pActiveSkills[v41] )
               {
                 v40->uW = 0;
--- a/UIMainMenu.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UIMainMenu.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -155,39 +154,39 @@
     uTextureID_BUTTMAKE2 = pIcons_LOD->LoadTexture("BUTTMAKE2", TEXTURE_16BIT_PALETTE);
 
     pPrimaryWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, 0);
-    pPrimaryWindow->CreateButton(7u, 8u, 0x1CCu, 0x157u, 1, 0, 0xAu, 0, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-    pPrimaryWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-    pPrimaryWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-    pPrimaryWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
-    pPrimaryWindow->CreateButton(0x18u, 0x194u, 5u, 0x31u, 1, 93, 0, 1u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x8Bu, 0x194u, 5u, 0x31u, 1, 93, 0, 2u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0xFFu, 0x194u, 5u, 0x31u, 1, 93, 0, 3u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x172u, 0x194u, 5u, 0x31u, 1, 93, 0, 4u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x61u, 0x194u, 5u, 0x31u, 1, 93, 0, 1u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0xD4u, 0x194u, 5u, 0x31u, 1, 93, 0, 2u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x148u, 0x194u, 5u, 0x31u, 1, 93, 0, 3u, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x1BBu, 0x194u, 5u, 0x31u, 1, 93, 0, 4u, 0, "", 0);
+    pPrimaryWindow->CreateButton(7u, 8u, 0x1CCu, 0x157u, 1, 0, UIMSG_A, 0, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 1, 0x31u, "", 0);
+    pPrimaryWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 2, 0x32u, "", 0);
+    pPrimaryWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 3, 0x33u, "", 0);
+    pPrimaryWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 4, 0x34u, "", 0);
+    pPrimaryWindow->CreateButton(0x18u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x8Bu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0xFFu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x172u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x61u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 1u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0xD4u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 2u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x148u, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 3u, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x1BBu, 0x194u, 5u, 0x31u, 1, 93, UIMSG_0, 4u, 0, "", 0);
 
     uTextureID_ib_td1_A = pIcons_LOD->LoadTexture("ib-td1-A", TEXTURE_16BIT_PALETTE);
     v6 = (Texture *)(uTextureID_ib_td1_A != -1 ? &pIcons_LOD->pTextures[uTextureID_ib_td1_A] : 0);
     v8 = pKeyActionMap->GetActionVKey(INPUT_Quest);
-    pBtn_Quests = pPrimaryWindow->CreateButton(0x1EBu, 0x161u, v6->uTextureWidth, v6->uTextureHeight, 1, 0, 0xC8u, 0, v8, pGlobalTXT_LocalizationStrings[174], v6, 0); //Quests
+    pBtn_Quests = pPrimaryWindow->CreateButton(0x1EBu, 0x161u, v6->uTextureWidth, v6->uTextureHeight, 1, 0, UIMSG_OpenQuestBook, 0, v8, pGlobalTXT_LocalizationStrings[174], v6, 0); //Quests
 
     uTextureID_ib_td2_A = pIcons_LOD->LoadTexture("ib-td2-A", TEXTURE_16BIT_PALETTE);
     v10 = (Texture *)(uTextureID_ib_td2_A != -1 ? &pIcons_LOD->pTextures[uTextureID_ib_td2_A] : 0);
     v12 = pKeyActionMap->GetActionVKey(INPUT_Autonotes);
-    pBtn_Autonotes = pPrimaryWindow->CreateButton(0x20Fu, 0x161u, v10->uTextureWidth, v10->uTextureHeight, 1, 0, 0xC9u, 0, v12, pGlobalTXT_LocalizationStrings[154], v10, 0);//Autonotes
+    pBtn_Autonotes = pPrimaryWindow->CreateButton(0x20Fu, 0x161u, v10->uTextureWidth, v10->uTextureHeight, 1, 0, UIMSG_OpenAutonotes, 0, v12, pGlobalTXT_LocalizationStrings[154], v10, 0);//Autonotes
 
     v14 = pIcons_LOD->LoadTexture("ib-td3-A", TEXTURE_16BIT_PALETTE);
     v15 = (Texture *)(v14 != -1 ? &pIcons_LOD->pTextures[v14] : 0);
     v17 = pKeyActionMap->GetActionVKey(INPUT_Mapbook);
-    pBtn_Maps = pPrimaryWindow->CreateButton(0x222u, 0x161u, v15->uTextureWidth, v15->uTextureHeight, 1, 0, 0xCAu, 0, v17, pGlobalTXT_LocalizationStrings[139], v15, 0); //Maps
+    pBtn_Maps = pPrimaryWindow->CreateButton(0x222u, 0x161u, v15->uTextureWidth, v15->uTextureHeight, 1, 0, UIMSG_OpenMapBook, 0, v17, pGlobalTXT_LocalizationStrings[139], v15, 0); //Maps
 
     uTextureID_ib_td4_A = pIcons_LOD->LoadTexture("ib-td4-A", TEXTURE_16BIT_PALETTE);
     v20 = (Texture *)(uTextureID_ib_td4_A != -1 ? &pIcons_LOD->pTextures[uTextureID_ib_td4_A] : 0);
     v22 = pKeyActionMap->GetActionVKey(INPUT_TimeCal);
-    pBtn_Calendar = pPrimaryWindow->CreateButton(0x23Au, 0x161u, v20->uTextureWidth, v20->uTextureHeight, 1, 0, 0xCBu, 0, v22,
+    pBtn_Calendar = pPrimaryWindow->CreateButton(0x23Au, 0x161u, v20->uTextureWidth, v20->uTextureHeight, 1, 0, UIMSG_OpenCalendar, 0, v22,
         pGlobalTXT_LocalizationStrings[78],//Calendar
         v20, 0);
 
@@ -195,7 +194,7 @@
     pBtn_History = pPrimaryWindow->CreateButton(0x258u, 0x169u,
         (uTextureID_ib_td5_A != -1 ? pIcons_LOD->pTextures[uTextureID_ib_td5_A].uTextureWidth : 24),
         (uTextureID_ib_td5_A != -1 ? pIcons_LOD->pTextures[uTextureID_ib_td5_A].uTextureHeight : 26),
-        1, 0, 0xE0u, 0, 0x48u, pGlobalTXT_LocalizationStrings[602],//History
+        1, 0, UIMSG_OpenHistoryBook, 0, 0x48u, pGlobalTXT_LocalizationStrings[602],//History
         (Texture *)(uTextureID_ib_td5_A != -1 ? &pIcons_LOD->pTextures[uTextureID_ib_td5_A] : 0), 0);
 
     bFlashAutonotesBook = 0;
@@ -204,54 +203,54 @@
 
     v24 = &pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn];
     v28 = pKeyActionMap->GetActionVKey(INPUT_ZoomIn);
-    pBtn_ZoomIn = pPrimaryWindow->CreateButton(574, 136, v24->uTextureWidth, v24->uTextureHeight, 2, 0, 0x170u, 0, v28, pGlobalTXT_LocalizationStrings[252], // Zoom In
+    pBtn_ZoomIn = pPrimaryWindow->CreateButton(574, 136, v24->uTextureWidth, v24->uTextureHeight, 2, 0, UIMSG_170, 0, v28, pGlobalTXT_LocalizationStrings[252], // Zoom In
         v24, 0);
     v29 = &pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut];
     v33 = pKeyActionMap->GetActionVKey(INPUT_ZoomOut);
-    pBtn_ZoomOut = pPrimaryWindow->CreateButton(519, 136, v29->uTextureWidth, v29->uTextureHeight, 2, 0, 0x16Fu, 0, v33, pGlobalTXT_LocalizationStrings[251], // Zoom Out
+    pBtn_ZoomOut = pPrimaryWindow->CreateButton(519, 136, v29->uTextureWidth, v29->uTextureHeight, 2, 0, UIMSG_16F, 0, v33, pGlobalTXT_LocalizationStrings[251], // Zoom Out
         v29, 0);
-    pPrimaryWindow->CreateButton(0x1E1u, 0, 0x99u, 0x43u, 1, 92, 0, 0, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x1EBu, 0x95u, 0x40u, 0x4Au, 1, 0, 0x86u, 0, 0x35u, "", 0);
-    pPrimaryWindow->CreateButton(0x231u, 0x95u, 0x40u, 0x4Au, 1, 0, 0x87u, 0, 0x36u, "", 0);
-    pPrimaryWindow->CreateButton(0x1DCu, 0x142u, 0x4Du, 0x11u, 1, 100, 0, 0, 0, "", 0);
-    pPrimaryWindow->CreateButton(0x22Bu, 0x142u, 0x4Du, 0x11u, 1, 101, 0, 0, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x1E1u, 0, 0x99u, 0x43u, 1, 92, UIMSG_0, 0, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x1EBu, 0x95u, 0x40u, 0x4Au, 1, 0, UIMSG_StartHireling1Dialogue, 0, 0x35u, "", 0);
+    pPrimaryWindow->CreateButton(0x231u, 0x95u, 0x40u, 0x4Au, 1, 0, UIMSG_StartHireling2Dialogue, 0, 0x36u, "", 0);
+    pPrimaryWindow->CreateButton(0x1DCu, 0x142u, 0x4Du, 0x11u, 1, 100, UIMSG_0, 0, 0, "", 0);
+    pPrimaryWindow->CreateButton(0x22Bu, 0x142u, 0x4Du, 0x11u, 1, 101, UIMSG_0, 0, 0, "", 0);
     pBtn_CastSpell = pPrimaryWindow->CreateButton(0x1DCu, 0x1C2u,
         (uTextureID_Btn_CastSpell != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_CastSpell].uTextureWidth : 24),
         (uTextureID_Btn_CastSpell != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_CastSpell].uTextureHeight : 26),
-        1, 0, 0x69u, 0, 0x43u, pGlobalTXT_LocalizationStrings[38],
+        1, 0, UIMSG_69, 0, 0x43u, pGlobalTXT_LocalizationStrings[38],
         (Texture *)(uTextureID_Btn_CastSpell != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_CastSpell] : 0),
         0);
     pBtn_Rest = pPrimaryWindow->CreateButton(0x206u, 0x1C2u,
         (uTextureID_Btn_Rest != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_Rest].uTextureWidth : 24),
         (uTextureID_Btn_Rest != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_Rest].uTextureHeight : 26),
-        1, 0, 0x68u, 0, 0x52u, pGlobalTXT_LocalizationStrings[182],
+        1, 0, UIMSG_68, 0, 0x52u, pGlobalTXT_LocalizationStrings[182],
         (Texture *)(uTextureID_Btn_Rest != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_Rest] : 0), 0);
     pBtn_QuickReference = pPrimaryWindow->CreateButton(0x230u, 0x1C2u,
         (uTextureID_Btn_QuickReference != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_QuickReference].uTextureWidth : 24),
         (uTextureID_Btn_QuickReference != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_QuickReference].uTextureHeight : 26),
-        1, 0, 0x6Au, 0, 0x5Au, pGlobalTXT_LocalizationStrings[173],
+        1, 0, UIMSG_QuickReference, 0, 0x5Au, pGlobalTXT_LocalizationStrings[173],
         (Texture *)(uTextureID_Btn_QuickReference != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_QuickReference] : 0), 0);
     pBtn_GameSettings = pPrimaryWindow->CreateButton(0x25Au, 0x1C2u,
         (uTextureID_Btn_GameSettings != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_GameSettings].uTextureWidth : 24),
         (uTextureID_Btn_GameSettings != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_GameSettings].uTextureHeight : 26),
-        1, 0, 0x6Bu, 0, 0, pGlobalTXT_LocalizationStrings[93],
+        1, 0, UIMSG_GameMenuButton, 0, 0, pGlobalTXT_LocalizationStrings[93],
         (Texture *)(uTextureID_Btn_GameSettings != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_GameSettings] : 0), 0);
     pBtn_NPCLeft = pPrimaryWindow->CreateButton(0x1D5u, 0xB2u,
         (uTextureID_Btn_NPCLeft != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft].uTextureWidth : 24),
         (uTextureID_Btn_NPCLeft != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft].uTextureHeight : 26),
-        1, 0, 0xBCu, 0, 0, "",
-        (Texture *)(uTextureID_Btn_NPCLeft != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft] : 0), 0);
+        1, 0, UIMSG_ScrollNPCPanel, 0, 0, "",
+        pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft), 0);
     pBtn_NPCRight = pPrimaryWindow->CreateButton(0x272u, 0xB2u,
         (uTextureID_Btn_NPCRight != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCRight].uTextureWidth : 24),
         (uTextureID_Btn_NPCRight != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCRight].uTextureHeight : 26),
-        1, 0, 0xBCu, 1u, 0, "",
-        (Texture *)(uTextureID_Btn_NPCRight != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_NPCRight] : 0), 0);
+        1, 0, UIMSG_ScrollNPCPanel, 1u, 0, "",
+        pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight), 0);
     LoadPartyBuffIcons();
-    }
+}
 
-    //----- (004979D2) --------------------------------------------------------
-    MENU_STATE __cdecl CreditsMenu__Loop()
-        {
+//----- (004979D2) --------------------------------------------------------
+MENU_STATE __cdecl CreditsMenu__Loop()
+{
         char *v0; // eax@5
         char *v1; // edi@5
         FILE *pFile; // eax@5
@@ -330,7 +329,7 @@
             pColor2, pString, pTexture2.pPixels, (signed __int16)pTexture2.uWidth);
         free(pString);
         pWindow_MainMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, (int)ptr);
-        pWindow_MainMenu->CreateButton(0, 0, 0, 0, 1, 0, 0x71u, 0, 0x1Bu, "", 0);
+        pWindow_MainMenu->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_Escape, 0, 0x1Bu, "", 0);
         pCurrentScreen = SCREEN_CREATORS;
         SetCurrentMenuID(MENU_CREDITSPROC);
         do
--- a/UIOptions.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UIOptions.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
--- a/UIPartyCreation.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UIPartyCreation.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -630,85 +629,85 @@
   uXa = 8;
   do
   {
-    pGUIWindow_CurrentMenu->CreateButton(uXa, 120u, 145u, 25u, 1, 0, 0x3Cu, uControlParama, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXa, 120u, 145u, 25u, 1, 0, UIMSG_PlayerCreationChangeName, uControlParama, 0, "", 0);
     uXa += 158;
     ++uControlParama;
   }
   while ( (signed int)uXa < 640 );
-  pCreationUI_BtnPressLeft[0] = pGUIWindow_CurrentMenu->CreateButton(10, 32, 11, 13, 1, 0, 0xABu, 0, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressLeft[1] = pGUIWindow_CurrentMenu->CreateButton(169, 32, 11, 13, 1, 0, 0xABu, 1, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressLeft[2] = pGUIWindow_CurrentMenu->CreateButton(327, 32, 11, 13, 1, 0, 0xABu, 2, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressLeft[3] = pGUIWindow_CurrentMenu->CreateButton(486, 32, 11, 13, 1, 0, 0xABu, 3, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressRight[0] = pGUIWindow_CurrentMenu->CreateButton(74, 32, 11, 13, 1, 0, 0xACu, 0, 0, "", pTexture_pressrigh, 0);
-  pCreationUI_BtnPressRight[1] = pGUIWindow_CurrentMenu->CreateButton(233, 32, 11, 13, 1, 0, 0xACu, 1, 0, "", pTexture_pressrigh, 0);
-  pCreationUI_BtnPressRight[2] = pGUIWindow_CurrentMenu->CreateButton(391, 32, 11, 13, 1, 0, 0xACu, 2, 0, "", pTexture_pressrigh, 0);
-  pCreationUI_BtnPressRight[3] = pGUIWindow_CurrentMenu->CreateButton(549, 32, 11, 13, 1, 0, 0xACu, 3, 0, "", pTexture_pressrigh, 0);
-  pCreationUI_BtnPressLeft2[0] = pGUIWindow_CurrentMenu->CreateButton(10, 103, 11, 13, 1, 0, 0x90u, 0, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressLeft2[1] = pGUIWindow_CurrentMenu->CreateButton(169, 103, 11, 13, 1, 0, 0x90u, 1, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressLeft2[2] = pGUIWindow_CurrentMenu->CreateButton(327, 103, 11, 13, 1, 0, 0x90u, 2, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressLeft2[3] = pGUIWindow_CurrentMenu->CreateButton(486, 103, 11, 13, 1, 0, 0x90u, 3, 0, "", pTexture_presleft, 0);
-  pCreationUI_BtnPressRight2[0] = pGUIWindow_CurrentMenu->CreateButton(74, 103, 11, 13, 1, 0, 0x91u, 0, 0, "", pTexture_pressrigh, 0);
-  pCreationUI_BtnPressRight2[1] = pGUIWindow_CurrentMenu->CreateButton(233, 103, 11, 13, 1, 0, 0x91u, 1, 0, "", pTexture_pressrigh, 0);
-  pCreationUI_BtnPressRight2[2] = pGUIWindow_CurrentMenu->CreateButton(391, 103, 11, 13, 1, 0, 0x91u, 2, 0, "", pTexture_pressrigh, 0);
-  pCreationUI_BtnPressRight2[3] = pGUIWindow_CurrentMenu->CreateButton(549, 103, 11, 13, 1, 0, 0x91u, 3, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressLeft[0] = pGUIWindow_CurrentMenu->CreateButton(10, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev, 0, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft[1] = pGUIWindow_CurrentMenu->CreateButton(169, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev, 1, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft[2] = pGUIWindow_CurrentMenu->CreateButton(327, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev, 2, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft[3] = pGUIWindow_CurrentMenu->CreateButton(486, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FacePrev, 3, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressRight[0] = pGUIWindow_CurrentMenu->CreateButton(74, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext, 0, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight[1] = pGUIWindow_CurrentMenu->CreateButton(233, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext, 1, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight[2] = pGUIWindow_CurrentMenu->CreateButton(391, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext, 2, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight[3] = pGUIWindow_CurrentMenu->CreateButton(549, 32, 11, 13, 1, 0, UIMSG_PlayerCreation_FaceNext, 3, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressLeft2[0] = pGUIWindow_CurrentMenu->CreateButton(10, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 0, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft2[1] = pGUIWindow_CurrentMenu->CreateButton(169, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 1, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft2[2] = pGUIWindow_CurrentMenu->CreateButton(327, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 2, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressLeft2[3] = pGUIWindow_CurrentMenu->CreateButton(486, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoicePrev, 3, 0, "", pTexture_presleft, 0);
+  pCreationUI_BtnPressRight2[0] = pGUIWindow_CurrentMenu->CreateButton(74, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 0, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight2[1] = pGUIWindow_CurrentMenu->CreateButton(233, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 1, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight2[2] = pGUIWindow_CurrentMenu->CreateButton(391, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 2, 0, "", pTexture_pressrigh, 0);
+  pCreationUI_BtnPressRight2[3] = pGUIWindow_CurrentMenu->CreateButton(549, 103, 11, 13, 1, 0, UIMSG_PlayerCreation_VoiceNext, 3, 0, "", pTexture_pressrigh, 0);
   uControlParamb = 0;
   uXb = 8;
   do
   {
-    pGUIWindow_CurrentMenu->CreateButton(uXb, 308, 150, v0, 1, 0, 0x48u, uControlParamb, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXb, v0 + 308, 150, v0, 1, 0, 0x49u, uControlParamb, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXb, 2 * v0 + 308, 150u, v0, 1, 0, 0x4Au, uControlParamb, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXb, 3 * v0 + 308, 150u, v0, 1, 0, 0x4Bu, uControlParamb, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXb, 308, 150, v0, 1, 0, UIMSG_48, uControlParamb, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXb, v0 + 308, 150, v0, 1, 0, UIMSG_49, uControlParamb, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXb, 2 * v0 + 308, 150u, v0, 1, 0, UIMSG_PlayerCreationRemoveUpSkill, uControlParamb, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXb, 3 * v0 + 308, 150u, v0, 1, 0, UIMSG_PlayerCreationRemoveDownSkill, uControlParamb, 0, "", 0);
     uXb += 158;
     ++uControlParamb;
   }
   while ( (signed int)uXb < 640 );
-  pGUIWindow_CurrentMenu->CreateButton(5u, 21u, 0x99u, 0x16Du, 1, 0, 0x76u, 0, 0x31u, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(163u, 21u, 0x99u, 0x16Du, 1, 0, 0x76u, 1u, 0x32u, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(321u, 21u, 0x99u, 0x16Du, 1, 0, 0x76u, 2u, 0x33u, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(479u, 21u, 0x99u, 0x16Du, 1, 0, 0x76u, 3u, 0x34u, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(5u, 21u, 0x99u, 0x16Du, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 0, 0x31u, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(163u, 21u, 0x99u, 0x16Du, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 1u, 0x32u, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(321u, 21u, 0x99u, 0x16Du, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 2u, 0x33u, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(479u, 21u, 0x99u, 0x16Du, 1, 0, UIMSG_PlayerCreation_SelectAttribute, 3u, 0x34u, "", 0);
   uXc = 23;
   uControlParamc = 2;
   do
   {
-    pGUIWindow_CurrentMenu->CreateButton(uXc, 169, 120, 20, 1, 0, 0, uControlParamc - 2, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXc, v0 + 169, 120, 20, 1, 0, 0, uControlParamc - 1, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXc, 2 * v0 + 169, 120, 20, 1, 0, 0, uControlParamc, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXc, 3 * v0 + 169, 120, 20, 1, 0, 0, uControlParamc + 1, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXc, 4 * v0 + 169, 120, 20, 1, 0, 0, uControlParamc + 2, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXc, 5 * v0 + 169, 120, 20, 1, 0, 0, uControlParamc + 3, 0, "", 0);
-    pGUIWindow_CurrentMenu->CreateButton(uXc, 6 * v0 + 169, 120, 20, 1, 0, 0, uControlParamc + 4, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 169, 120, 20, 1, 0, UIMSG_0, uControlParamc - 2, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc - 1, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 2 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 3 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 1, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 4 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 2, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 5 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 3, 0, "", 0);
+    pGUIWindow_CurrentMenu->CreateButton(uXc, 6 * v0 + 169, 120, 20, 1, 0, UIMSG_0, uControlParamc + 4, 0, "", 0);
     uControlParamc += 7;
     uXc += 158;
   }
   while ( (signed int)uControlParamc < 30 );
   pGUIWindow_CurrentMenu->_41D08F(28, 0, 7, 40);
-  pGUIWindow_CurrentMenu->CreateButton(323, 417, 65, v0, 1, 0, 0x41, 0, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(323, v0 + 417, 65, v0, 1, 0, 0x41, 0xC, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(323, 2 * v0 + 417, 65, v0, 1, 0, 0x41, 0x14, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(388, 417, 65, v0, 1, 0, 0x41, 0x18, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(388, v0 + 417, 65, v0, 1, 0, 0x41, 0x1C, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(388, 2 * v0 + 417, 65, v0, 1, 0, 0x41, 0x20, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(453, 417, 65, v0, 1, 0, 0x41, 0x10, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(453, v0 + 417, 65, v0, 1, 0, 0x41, 8, 0, "", 0);
-  pGUIWindow_CurrentMenu->CreateButton(453, 2 * v0 + 417, 65, v0, 1, 0, 0x41, 4, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(323, 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(323, v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0xC, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(323, 2 * v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x14, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(388, 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x18, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(388, v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x1C, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(388, 2 * v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x20, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(453, 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 0x10, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(453, v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 8, 0, "", 0);
+  pGUIWindow_CurrentMenu->CreateButton(453, 2 * v0 + 417, 65, v0, 1, 0, UIMSG_PlayerCreationSelectClass, 4, 0, "", 0);
   uControlParamd = 0;
   do
   {
     uXd = -5;
     if ( uControlParamd <= 3 )
       uXd = 0;
-    pGUIWindow_CurrentMenu->CreateButton(100 * (uControlParamd / 3) + uXd + 17, v0 * (uControlParamd % 3) + 417, 100, v0, 1, 0, 0x40,
+    pGUIWindow_CurrentMenu->CreateButton(100 * (uControlParamd / 3) + uXd + 17, v0 * (uControlParamd % 3) + 417, 100, v0, 1, 0, UIMSG_PlayerCreationSelectActiveSkill,
       uControlParamd, 0, "", 0);
     ++uControlParamd;
   }
   while ( uControlParamd < 9 );
-  pPlayerCreationUI_BtnOK = pGUIWindow_CurrentMenu->CreateButton(580, 431, 51, 39, 1, 0, 0x42, 0, 0xD, "",
+  pPlayerCreationUI_BtnOK = pGUIWindow_CurrentMenu->CreateButton(580, 431, 51, 39, 1, 0, UIMSG_PlayerCreationClickOK, 0, 0xD, "",
                               (Texture *)(uTextureID_BUTTMAKE != -1 ? &pIcons_LOD->pTextures[uTextureID_BUTTMAKE] : 0), 0);
-  pPlayerCreationUI_BtnReset = pGUIWindow_CurrentMenu->CreateButton(527, 431, 51, 39, 1, 0, 0x43, 0, 0x43, "",
+  pPlayerCreationUI_BtnReset = pGUIWindow_CurrentMenu->CreateButton(527, 431, 51, 39, 1, 0, UIMSG_PlayerCreationClickReset, 0, 0x43, "",
                                  (Texture *)(uTextureID_BUTTMAKE2 != -1 ? &pIcons_LOD->pTextures[uTextureID_BUTTMAKE2] : 0), 0);
-  pPlayerCreationUI_BtnMinus = pGUIWindow_CurrentMenu->CreateButton(523, 393, 20, 35, 1, 0, 0x3F, 0, 0x2D, "", pTexture_buttminu, 0);
-  pPlayerCreationUI_BtnPlus = pGUIWindow_CurrentMenu->CreateButton(613, 393, 20, 35, 1, 0, 0x3E, 1, 0x2B, "", pTexture_buttplus, 0);
+  pPlayerCreationUI_BtnMinus = pGUIWindow_CurrentMenu->CreateButton(523, 393, 20, 35, 1, 0, UIMSG_PlayerCreationClickMinus, 0, 0x2D, "", pTexture_buttminu, 0);
+  pPlayerCreationUI_BtnPlus = pGUIWindow_CurrentMenu->CreateButton(613, 393, 20, 35, 1, 0, UIMSG_PlayerCreationClickPlus, 1, 0x2B, "", pTexture_buttplus, 0);
   pFontCChar = LoadFont("cchar.fnt", "FONTPAL", NULL);
 }
 // 4E28F8: using guessed type int pCurrentScreen;
--- a/UIPopup.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UIPopup.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -1594,14 +1593,14 @@
         {
         for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = i->pNext )
             {
-            if ( i->uControlID == 121
+            if ( i->msg == UIMSG_SkillUp
                 && (signed int)v0 >= (signed int)i->uX
                 && (signed int)v0 <= (signed int)i->uZ
                 && (signed int)v1 >= (signed int)i->uY
                 && (signed int)v1 <= (signed int)i->uW )
                 {
-                v3 = CharacterUI_GetSkillDescText(uActiveCharacter - 1, (PLAYER_SKILL_TYPE)i->uControlParam);
-                sub_4179BC_draw_tooltip(pSkillNames[i->uControlParam], v3);
+                v3 = CharacterUI_GetSkillDescText(uActiveCharacter - 1, (PLAYER_SKILL_TYPE)i->msg_param);
+                sub_4179BC_draw_tooltip(pSkillNames[i->msg_param], v3);
                 v1 = pY;
                 v0 = pX;
                 }
@@ -1928,9 +1927,14 @@
         dword_507B00_spell_info_to_draw_in_popup = 0;
         }
     // 507B00: using guessed type int dword_507B00_spell_info_to_draw_in_popup;
-    //----- (00416D62) --------------------------------------------------------
-    void sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(Vec2_int_ *_this)
-        {
+
+
+
+
+
+//----- (00416D62) --------------------------------------------------------
+void sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(Vec2_int_ *_this)
+{
         signed int pPlayerNum; // eax@12
         char *v2; // eax@32
         void *v3; // ecx@52
@@ -1945,7 +1949,7 @@
         GUIButton *pButton; // esi@84
         unsigned int v13; // ecx@85
         char *pStr; // edi@85
-        signed int pControlID; // eax@92
+        //signed int pControlID; // eax@92
         int v16; // eax@95
         int v17; // eax@96
         PLAYER_SKILL_TYPE v18; // eax@98
@@ -2120,9 +2124,9 @@
                 else
                     v5 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
                 v6 = (unsigned __int16)v5;
-                if ( (v6 & 7) != OBJECT_Item)
+                if (PID_TYPE(v6) != OBJECT_Item)
                     {
-                    if ( (v6 & 7) == OBJECT_Actor)
+                    if (PID_TYPE(v6) == OBJECT_Actor)
                         {
                         if ( pRenderer->uNumSceneBegins )
                             {
@@ -2218,50 +2222,49 @@
                 if ( pButton->uButtonType == 1 && pButton->uButtonType != 3 && (signed int)pX > (signed int)pButton->uX && (signed int)pX < (signed int)pButton->uZ
                     && (signed int)pY > (signed int)pButton->uY && (signed int)pY < (signed int)pButton->uW )
                     {
-                    pControlID = pButton->uControlID;
-                    switch ( pControlID )
-                        {
-                    case 0: //stats info
-                        pWindow.Hint = pAttributeDescriptions[(signed int)pButton->uControlParam % 7];
-                        pStr = aAttributeNames[(signed int)pButton->uControlParam % 7];
+                    switch ( pButton->msg )
+                    {
+                    case UIMSG_0: //stats info
+                        pWindow.Hint = pAttributeDescriptions[(signed int)pButton->msg_param % 7];
+                        pStr = aAttributeNames[(signed int)pButton->msg_param % 7];
                         break;
-                    case 62: //Plus button info 
+                    case UIMSG_PlayerCreationClickPlus: //Plus button info 
                         pStr = pGlobalTXT_LocalizationStrings[670];//Äîáàâèòü
                         pWindow.Hint = pGlobalTXT_LocalizationStrings[671];//"Äîáàâëÿåò î÷êî ê âûäåëåííîìó íàâûêó, çàáèðàÿ åãî èç íàêîïèòåëÿ î÷êîâ"
                         break;
-                    case 63: //Minus button info
+                    case UIMSG_PlayerCreationClickMinus: //Minus button info
                         pStr = pGlobalTXT_LocalizationStrings[668];//Âû÷åñòü
                         pWindow.Hint = pGlobalTXT_LocalizationStrings[669];//"Âû÷èòàåò î÷êî èç âûäåëåííîãî íàâûêà, âîçâðàùàÿ åãî â íàêîïèòåëü î÷êîâ"
                         break;
-                    case 64: //Available skill button info
-                        v18 = pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].GetSkillIdxByOrder(pButton->uControlParam + 4);
+                    case UIMSG_PlayerCreationSelectActiveSkill: //Available skill button info
+                        v18 = pParty->pPlayers[uPlayerCreationUI_SelectedCharacter].GetSkillIdxByOrder(pButton->msg_param + 4);
                         pStr = pSkillNames[v18];
                         pWindow.Hint = pSkillDesc[v18];
                         break;
-                    case 65: //Available Class Info
-                        pWindow.Hint = pClassDescriptions[pButton->uControlParam];
-                        pStr = pClassNames[pButton->uControlParam];
+                    case UIMSG_PlayerCreationSelectClass: //Available Class Info
+                        pWindow.Hint = pClassDescriptions[pButton->msg_param];
+                        pStr = pClassNames[pButton->msg_param];
                         break;
-                    case 66: //OK Info
+                    case UIMSG_PlayerCreationClickOK: //OK Info
                         pWindow.Hint = pGlobalTXT_LocalizationStrings[664];//Ùåëêíèòå çäåñü äëÿ óòâåðæäåíèÿ ñîñòàâà îòðÿäà è ïðîäîëæåíèÿ èãðû.
                         pStr = pGlobalTXT_LocalizationStrings[665];//Êíîïêà ÎÊ
                         break;
-                    case 67: //Clear info
+                    case UIMSG_PlayerCreationClickReset: //Clear info
                         pWindow.Hint = pGlobalTXT_LocalizationStrings[666];//Ñáðàñûâàåò âñå ïàðàìåòðû è íàâûêè îòðÿäà.
                         pStr = pGlobalTXT_LocalizationStrings[667];//Êíîïêà Î÷èñòèòü
                         break;
-                    case 118: // Character info
-                        pStr = pParty->pPlayers[pButton->uControlParam].pName;
-                        pWindow.Hint = pClassDescriptions[pParty->pPlayers[pButton->uControlParam].classType];
+                    case UIMSG_PlayerCreation_SelectAttribute: // Character info
+                        pStr = pParty->pPlayers[pButton->msg_param].pName;
+                        pWindow.Hint = pClassDescriptions[pParty->pPlayers[pButton->msg_param].classType];
                         break;
                         }
-                    if ( pControlID > 68 && pControlID <= 75 ) //Sellected skills info
+                    if ( pButton->msg > UIMSG_44 && pButton->msg <= UIMSG_PlayerCreationRemoveDownSkill ) //Sellected skills info
                         {
-                        pSkillId = pParty->pPlayers[pButton->uControlParam].GetSkillIdxByOrder(pControlID - 72);
+                        pSkillId = pParty->pPlayers[pButton->msg_param].GetSkillIdxByOrder(pButton->msg - UIMSG_48);
                         pY = 0;
                         if ( (signed int)pSkillId < 37 )
                             {
-                            pSkillInfo = CharacterUI_GetSkillDescText(pButton->uControlParam, (PLAYER_SKILL_TYPE)pSkillId);
+                            pSkillInfo = CharacterUI_GetSkillDescText(pButton->msg_param, (PLAYER_SKILL_TYPE)pSkillId);
                             strcpy(pTmpBuf2, pSkillInfo);
                             pWindow.Hint = pTmpBuf2;
                             pStr = pSkillNames[pSkillId];
--- a/UIRest.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UIRest.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -115,7 +114,7 @@
         37u,
         1,
         0,
-        0xA7u,
+        UIMSG_ExitRest,
         0,
         0,
         "",
@@ -128,7 +127,7 @@
         37u,
         1,
         0,
-        0x61u,
+        UIMSG_61,
         0,
         0x52u,
         "",
@@ -141,7 +140,7 @@
         33u,
         1,
         0,
-        0x6Du,
+        UIMSG_AlreadyResting,
         0,
         0x44u,
         "",
@@ -154,7 +153,7 @@
         33u,
         1,
         0,
-        0x60u,
+        UIMSG_Wait1Hour,
         0,
         0x48u,
         "",
@@ -167,7 +166,7 @@
         33u,
         1,
         0,
-        0x5Fu,
+        UIMSG_Wait5Minutes,
         0,
         0x4Du,
         "",
--- a/UISaveLoad.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UISaveLoad.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
--- a/UiGame.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/UiGame.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -292,7 +291,7 @@
   char v3; // dl@1
   GUIWindow *v4; // ecx@2
   GUIButton *result; // eax@2
-  int v6; // edx@12
+  //int v6; // edx@12
 
   v1 = toupper(uHotkey);
   v2 = uNumVisibleWindows;
@@ -306,8 +305,7 @@
       {
         if ( result->uHotkey == v3 )
         {
-          v6 = result->uControlParam;
-          pMessageQueue_50CBD0->AddMessage((UIMessageType)result->uControlID, v6, 0);
+          pMessageQueue_50CBD0->AddMessage(result->msg, result->msg_param, 0);
           /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
           {
             pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = (UIMessageType)result->uControlID;
@@ -511,7 +509,7 @@
   unsigned __int8 v9; // c0@23
   unsigned __int8 v10; // c3@23
   enum UIMessageType pMessageType1; // esi@24
-  int v12; // edx@25
+  //int v12; // edx@25
   char *v13; // ecx@28
   int v14; // eax@41
   ItemGen *pItemGen; // ecx@44
@@ -535,9 +533,9 @@
   //unsigned __int8 v33; // c0@109
   //unsigned __int8 v34; // c3@109
   enum UIMessageType pMessageType2; // esi@110
-  int v36; // edx@111
+  //int v36; // edx@111
   enum UIMessageType pMessageType3; // edx@117
-  int v38; // ecx@118
+  //int v38; // ecx@118
   const char *v39; // [sp-8h] [bp-E8h]@20
   char *v40; // [sp-8h] [bp-E8h]@83
   int v41; // [sp-4h] [bp-E4h]@20
@@ -585,8 +583,8 @@
       v18 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
     }
     pMouse->uPointingObjectID = (unsigned __int16)v18;
-    v19 = (signed int)(unsigned __int16)v18 >> 3;
-    if ( (v18 & 7) == OBJECT_Item )
+    v19 = (signed)PID_ID(v18);
+    if (PID_TYPE(v18) == OBJECT_Item)
     {
       v30 = v19;
       if ( pObjectList->pObjects[pSpriteObjects[v30].uObjectDescID].uFlags & 0x10 )
@@ -630,9 +628,9 @@
     }
     else
     {
-      if ( (v18 & 7) != OBJECT_Actor )
+      if (PID_TYPE(v18) != OBJECT_Actor)
       {
-        if ( (v18 & 7) == OBJECT_Decoration )
+        if (PID_TYPE(v18) == OBJECT_Decoration)
         {
           v23 = &pLevelDecorations[v19];
           v24 = v23;
@@ -686,7 +684,7 @@
           uLastPointedObjectID = pMouse->uPointingObjectID;
           return;
         }
-        if ( (v18 & 7) == OBJECT_BModel)
+        if (PID_TYPE(v18) == OBJECT_BModel)
         {
           if ( v18 < (signed int)0x2000000u )
           {
@@ -858,16 +856,7 @@
 				pMessageType1 = (UIMessageType)pButton->field_1C;
 				if ( pMessageType1 )
 				{
-				  v12 = pButton->uControlParam;
-				  pMessageQueue_50CBD0->AddMessage(pMessageType1, v12, 0);
-				  /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-				  {
-					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = pMessageType1;
-					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v12;
-					*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-	//LABEL_27:
-					++pMessageQueue_50CBD0->uNumMessages;
-				  }*/
+				  pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
 				}
 	//LABEL_28:
 				v13 = pButton->pButtonName;
@@ -888,22 +877,10 @@
 				{
 				  if ( (double)(signed int)pButton->uHeight != 0.0 )
 				  {
-					//UNDEF(v8);
-					//if ( v9 | v10 )
-					  //goto LABEL_24;
-					//{
 					  pMessageType1 = (UIMessageType)pButton->field_1C;
 					  if ( pMessageType1 )
 					  {
-						v12 = pButton->uControlParam;
-						pMessageQueue_50CBD0->AddMessage(pMessageType1, v12, 0);
-						/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-						{
-						  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = pMessageType1;
-						  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v12;
-						  *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-						  ++pMessageQueue_50CBD0->uNumMessages;
-						}*/
+						pMessageQueue_50CBD0->AddMessage(pMessageType1, pButton->msg_param, 0);
 					  }
 					  v13 = pButton->pButtonName;
 					  sub_41C0B8_set_status_string(v13);
@@ -923,7 +900,7 @@
 				{
 	//LABEL_19:
 				  pPlayer = pPlayers[uActiveCharacter];
-				  v5 = LOBYTE(pPlayer->pActiveSkills[pButton->uControlParam]);
+				  v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
 				  v6 = pPlayer->uSkillPoints;
 				  v7 = (v5 & 0x3F) + 1;
 				  if ( v6 < v7 )
@@ -1066,15 +1043,8 @@
               uLastPointedObjectID = 1;
               return;
             }
-            v38 = pButton->uControlParam;
-            /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-            {
-              pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = pMessageType3;
-              pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v38;
-              *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-              ++pMessageQueue_50CBD0->uNumMessages;
-            }*/
-            pMessageQueue_50CBD0->AddMessage(pMessageType3, v38, 0);
+
+            pMessageQueue_50CBD0->AddMessage(pMessageType3, pButton->msg_param, 0);
             //goto LABEL_131;
             uLastPointedObjectID = 1;
             return;
@@ -1098,22 +1068,8 @@
                 //{
                   pMessageType2 = (UIMessageType)pButton->field_1C;
                   if ( pMessageType2 != 0 )
-                  {
-                    v36 = pButton->uControlParam;
-                    if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-                    {
-                      pMessageQueue_50CBD0->AddMessage(pMessageType2, v36, 0);
-                      /*pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = pMessageType2;
-                      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v36;
-                      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-                      //goto LABEL_27;
-                      ++pMessageQueue_50CBD0->uNumMessages;*/
-                      v13 = pButton->pButtonName;
-                      sub_41C0B8_set_status_string(v13);
-                      uLastPointedObjectID = 1;
-                      return;
-                    }
-                  }
+                      pMessageQueue_50CBD0->AddMessage(pMessageType2, pButton->msg_param, 0);
+
                   //goto LABEL_28;
                   v13 = pButton->pButtonName;
                   sub_41C0B8_set_status_string(v13);
@@ -1133,7 +1089,7 @@
               //goto LABEL_19;
             {
               pPlayer = pPlayers[uActiveCharacter];
-              v5 = LOBYTE(pPlayer->pActiveSkills[pButton->uControlParam]);
+              v5 = LOBYTE(pPlayer->pActiveSkills[pButton->msg_param]);
               v6 = pPlayer->uSkillPoints;
               v7 = (v5 & 0x3F) + 1;
               if ( v6 < v7 )
@@ -1291,41 +1247,41 @@
   pCharacterScreen_StatsBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 12, pViewport->uViewportTL_Y + 308,
                                 (papredoll_dbrds[9] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[9]].uTextureWidth : 24),
                                 (papredoll_dbrds[9] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[9]].uTextureHeight : 26),
-                                1, 0, 0x73u, 0, 0x53u, pGlobalTXT_LocalizationStrings[216],// Stats
+                                1, 0, UIMSG_73, 0, 0x53u, pGlobalTXT_LocalizationStrings[216],// Stats
                                 (Texture *)(papredoll_dbrds[10] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[10]] : 0),
                                 papredoll_dbrds[9] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[9]] : 0, 0);
   pCharacterScreen_SkillsBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 102, pViewport->uViewportTL_Y + 308,
                                  (papredoll_dbrds[7] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[7]].uTextureWidth : 24),
                                  (papredoll_dbrds[7] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[7]].uTextureHeight : 26),
-                                 1, 0, 0x72u, 0, 0x4Bu, pGlobalTXT_LocalizationStrings[205],//Skills
+                                 1, 0, UIMSG_72, 0, 0x4Bu, pGlobalTXT_LocalizationStrings[205],//Skills
                                  (Texture *)(papredoll_dbrds[8] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[8]] : 0),
                                  papredoll_dbrds[7] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[7]] : 0, 0);
   pCharacterScreen_InventoryBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 192, pViewport->uViewportTL_Y + 308,
                                     (papredoll_dbrds[5] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[5]].uTextureWidth : 24),
                                     (papredoll_dbrds[5] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[5]].uTextureHeight : 26),
-                                    1, 0, 0x74u, 0, 0x49u, pGlobalTXT_LocalizationStrings[120], //Inventory
+                                    1, 0, UIMSG_74, 0, 0x49u, pGlobalTXT_LocalizationStrings[120], //Inventory
                                     (Texture *)(papredoll_dbrds[6] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[6]] : 0),
                                     papredoll_dbrds[5] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[5]] : 0, 0);
   pCharacterScreen_AwardsBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 282, pViewport->uViewportTL_Y + 308,
                                  (papredoll_dbrds[3] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[3]].uTextureWidth : 24),
                                  (papredoll_dbrds[3] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[3]].uTextureHeight : 26),
-                                 1, 0, 0x75u, 0, 0x41u, pGlobalTXT_LocalizationStrings[22], //Awards
+                                 1, 0, UIMSG_75, 0, 0x41u, pGlobalTXT_LocalizationStrings[22], //Awards
                                  (Texture *)(papredoll_dbrds[4] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[4]] : 0),
                                  papredoll_dbrds[3] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[3]] : 0, 0);
   pCharacterScreen_ExitBtn = pWindow->CreateButton(pViewport->uViewportTL_X + 371, pViewport->uViewportTL_Y + 308,
                  (papredoll_dbrds[1] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[1]].uTextureWidth : 24),
                  (papredoll_dbrds[1] != -1 ? pIcons_LOD->pTextures[papredoll_dbrds[1]].uTextureHeight : 26),
-                 1, 0, 0xA8u, 0, 0, pGlobalTXT_LocalizationStrings[79],//Exit
+                 1, 0, UIMSG_A8, 0, 0, pGlobalTXT_LocalizationStrings[79],//Exit
                  (Texture *)(papredoll_dbrds[2] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[2]] : 0),
                  papredoll_dbrds[1] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[1]] : 0, 0);
-  pWindow->CreateButton(0, 0, 0x1DCu, 0x159u, 1, 122, 0x78u, 0, 0, "", 0);
-  pCharacterScreen_DetalizBtn = pWindow->CreateButton(0x258u, 0x12Cu, 0x1Eu, 0x1Eu, 1, 0, 0x55u, 0, 0, pGlobalTXT_LocalizationStrings[64], 0);
-  pCharacterScreen_DollBtn = pWindow->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, 0x85u, 0, 0, "", 0);
-  pWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-  pWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-  pWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-  pWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
-  pWindow->CreateButton(0, 0, 0, 0, 1, 0, 0xB0u, 0, 9u, "", 0);
+  pWindow->CreateButton(0, 0, 0x1DCu, 0x159u, 1, 122, UIMSG_InventoryLeftClick, 0, 0, "", 0);
+  pCharacterScreen_DetalizBtn = pWindow->CreateButton(0x258u, 0x12Cu, 0x1Eu, 0x1Eu, 1, 0, UIMSG_MainMenu_ShowLoadWindow, 0, 0, pGlobalTXT_LocalizationStrings[64], 0);
+  pCharacterScreen_DollBtn = pWindow->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_85, 0, 0, "", 0);
+  pWindow->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+  pWindow->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+  pWindow->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+  pWindow->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
+  pWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, 9u, "", 0);
   FillAwardsData();
   return pWindow;
 }
@@ -1333,7 +1289,7 @@
 
 //----- (004921C1) --------------------------------------------------------
 void GameUI_DrawPortraits(unsigned int _this)
-    {
+{
     Texture *pFace; // eax@10
     unsigned int v7; // eax@17
     PlayerFrame *pFrame; // eax@21
@@ -1442,7 +1398,7 @@
         {
         if ( pTurnEngine->field_4 != 1 )
             {
-            if ( (pTurnEngine->pQueue[0].uPackedID & 7) == OBJECT_Player)
+            if (PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
                 {
                 //v14 = 0;
                 if ( pTurnEngine->uActorQueueSize > 0 )
@@ -1452,7 +1408,7 @@
                         {
                         auto pElem = pTurnEngine->pQueue + i;
 
-                        if ( (pElem->uPackedID & 7) != OBJECT_Player)
+                        if (PID_TYPE(pElem->uPackedID) != OBJECT_Player)
                             break;
                         v16 = dword_5079D0;
                         if ( pParty->uFlags & 0x10 )
--- a/VideoPlayer.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/VideoPlayer.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -1130,10 +1130,10 @@
     {
       pAudioPlayer->PlaySound(SOUND_Invalid, 0, 0, -1, 0, 0, 0, 0);
       window_SpeakInHouse = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, 165, 0);
-      window_SpeakInHouse->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-      window_SpeakInHouse->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-      window_SpeakInHouse->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-      window_SpeakInHouse->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
+      window_SpeakInHouse->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+      window_SpeakInHouse->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+      window_SpeakInHouse->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+      window_SpeakInHouse->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
     }
     bGameoverLoop = 0;
   }
--- a/Viewport.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/Viewport.h	Thu Mar 28 00:37:58 2013 +0400
@@ -39,6 +39,7 @@
   {
     draw_sw_outlines = false;
     draw_d3d_outlines = false;
+    field_4C = 0;
   }
 
   void CenterOnParty2();
--- a/Vis.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/Vis.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -9,7 +9,7 @@
 #include "Log.h"
 
 #include "mm7_data.h"
-//#include "MM7.h"
+#include "MM7.h"
 
 
 static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8;
@@ -377,7 +377,7 @@
         {
           pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1u);
           int v13 = _48B561_mess_with_scaling_along_z(/*v12, */intersection.vWorldViewPosition.x);
-          v13 += (8 * (j | (i << 6)) | OBJECT_BModel);
+          v13 += PID(OBJECT_BModel, j | (i << 6));
 
           list->AddObject(face, VisObjectType_Face, v13);
         }
@@ -1802,7 +1802,7 @@
   int result; // eax@1
   signed int pFaceID; // esi@2
   BLVFace *pFace; // edi@4
-  unsigned int v7; // eax@6
+  //unsigned int v7; // eax@6
   Vis_ObjectInfo *v8; // eax@6
   signed int i; // [sp+18h] [bp-8h]@1
 
@@ -1819,9 +1819,7 @@
         {
           if ( is_part_of_selection(pFace, filter) )
           {
-            v7 = 8 * pFaceID;
-            LOBYTE(v7) = 8 * pFaceID | OBJECT_BModel;
-            v8 = _4C1026(pFace, v7, pick_depth);
+            v8 = _4C1026(pFace, PID(OBJECT_BModel, pFaceID), pick_depth);
             if ( v8 )
               list->AddObject(v8->object, v8->object_type, v8->sZValue);
           }
@@ -1853,7 +1851,7 @@
         BLVFace blv_face;
         blv_face.FromODM(face);
 
-        int pid = 8 * (j | (i << 6)) | OBJECT_BModel;
+        int pid = PID(OBJECT_BModel, j | (i << 6));
         if (auto object_info = _4C1026(&blv_face, pid, pick_depth))
           list->AddObject(object_info->object, object_info->object_type, object_info->sZValue);
       }
--- a/mm7_1.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_1.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -12,7 +12,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -92,7 +91,7 @@
     }
     for ( j = pGUIWindow_CurrentMenu->pControlsHead; j; j = j->pNext )
     {
-      if ( j->uControlID == 120 )
+      if ( j->msg == UIMSG_InventoryLeftClick)
       {
         j->uX = dword_50698C;
         j->uY = dword_506988;
@@ -103,20 +102,6 @@
     }
   }
 }
-// 506980: using guessed type int dword_506980;
-// 506984: using guessed type int dword_506984;
-// 506988: using guessed type int dword_506988;
-// 50698C: using guessed type int dword_50698C;
-// 507CC0: using guessed type int dword_507CC0;
-// 50651C: using guessed type int dword_50651C;
-// 506520: using guessed type int dword_506520;
-// 506524: using guessed type int dword_506524;
-// 506528: using guessed type int dword_506528;
-// 506544: using guessed type int dword_506544;
-// 506548: using guessed type int dword_506548;
-// 723E80: using guessed type int dword_723E80_award_related[];
-// 723E84: using guessed type int dword_723E84[];
-// 5075E0: using guessed type int pVisibleWindowsIdxs[20];
 
 //----- (0041CD4F) --------------------------------------------------------
 bool __thiscall sub_41CD4F(unsigned int _this)
@@ -131,7 +116,7 @@
   char v8; // zf@21
   GUIButton *v9; // ecx@24
   int v10; // esi@24
-  int v11; // edx@26
+  //int v11; // edx@26
   int v12; // edx@28
   int v13; // esi@32
   GUIButton *v14; // eax@37
@@ -140,7 +125,7 @@
   int v18; // edx@50
   GUIButton *v19; // ecx@54
   int v20; // esi@54
-  int v21; // edx@56
+  //int v21; // edx@56
   int v22; // ecx@59
   int v23; // edx@59
   int v24; // ecx@60
@@ -193,16 +178,8 @@
 				  }
 				  while ( v13 );
 				}
-				v11 = v9->uControlParam;
-				/*if ( (signed int)v2 < 40 )
-				{
-				  pMessageQueue_50CBD0->pMessages[v2].eType = (UIMessageType)v9->uControlID;
-				  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v11;
-				  *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = v1;
-				  v2 = pMessageQueue_50CBD0->uNumMessages + 1;
-				  ++pMessageQueue_50CBD0->uNumMessages;
-				}*/
-				pMessageQueue_50CBD0->AddMessage((UIMessageType)v9->uControlID, v11, v1);
+
+                pMessageQueue_50CBD0->AddMessage(v9->msg, v9->msg_param, v1);
 				break;
 				}
 			case VK_RIGHT:
@@ -233,8 +210,7 @@
 					}
 					while ( v10 );
 				}
-				v11 = v9->uControlParam;
-				pMessageQueue_50CBD0->AddMessage((UIMessageType)v9->uControlID, v11, v1);
+				pMessageQueue_50CBD0->AddMessage(v9->msg, v9->msg_param, v1);
 				break;				
 				}
 			case VK_DOWN:
@@ -258,8 +234,7 @@
 					}
 					while ( v20 );
 				}
-				v21 = v19->uControlParam;
-				pMessageQueue_50CBD0->AddMessage((UIMessageType)v19->uControlID, v21, v1);
+				pMessageQueue_50CBD0->AddMessage(v19->msg, v19->msg_param, v1);
 				return 1;
 				}
 			case VK_SELECT:
@@ -327,15 +302,8 @@
 					}
 					while ( v25 );
 				}
-				v21 = v19->uControlParam;
-				/*if ( (signed int)v2 < 40 )
-				{
-				pMessageQueue_50CBD0->pMessages[v2].eType = (UIMessageType)v19->uControlID;
-				pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v21;
-				*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = v1;
-				++pMessageQueue_50CBD0->uNumMessages;
-				}*/
-				pMessageQueue_50CBD0->AddMessage((UIMessageType)v19->uControlID, v21, v1);
+
+				pMessageQueue_50CBD0->AddMessage(v19->msg, v19->msg_param, v1);
 				return 1;
 				}
 			case VK_NEXT:
@@ -729,19 +697,19 @@
                  33u,
                  1,
                  0,
-                 0xA8u,
+                 UIMSG_A8,
                  0,
                  0,
                  pGlobalTXT_LocalizationStrings[79], // Close
                  (Texture *)(papredoll_dbrds[2] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[2]] : 0),
                  papredoll_dbrds[1] != -1 ? (int)&pIcons_LOD->pTextures[papredoll_dbrds[1]] : 0,
                  0);
-  v2->CreateButton(0, 0, 0x1DCu, 0x159u, 1, 122, 0x78u, 0, 0, "", 0);
-  pCharacterScreen_DollBtn = v2->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, 0x85u, 0, 0, "", 0);
-  v2->CreateButton(61u, 424u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-  v2->CreateButton(177u, 424u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-  v2->CreateButton(292u, 424u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-  v2->CreateButton(407u, 424u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
+  v2->CreateButton(0, 0, 0x1DCu, 0x159u, 1, 122, UIMSG_InventoryLeftClick, 0, 0, "", 0);
+  pCharacterScreen_DollBtn = v2->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, 1, 0, UIMSG_85, 0, 0, "", 0);
+  v2->CreateButton(61u, 424u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+  v2->CreateButton(177u, 424u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+  v2->CreateButton(292u, 424u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+  v2->CreateButton(407u, 424u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
   return v2;
 }
 
@@ -813,7 +781,7 @@
 			}
 		  }
 		}
-		a1.field_58_pid = OBJECT_Player;
+		a1.spell_caster_pid = OBJECT_Player;
 		a1.uObjectDescID = v6;
 		a1.vPosition.y = pParty->vPosition.y;
 		a1.vPosition.x = pParty->vPosition.x;
@@ -1217,7 +1185,7 @@
 			}
 			a1.uObjectDescID = v6;
 			a1.vPosition.y = pParty->vPosition.y;
-			a1.field_58_pid = OBJECT_Player;
+			a1.spell_caster_pid = OBJECT_Player;
 			a1.vPosition.x = pParty->vPosition.x;
 			a1.vPosition.z = pParty->sEyelevel + pParty->vPosition.z;
 			a1.uSoundID = 0;
--- a/mm7_2.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_2.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -5,7 +5,6 @@
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
-#include "GUIButton.h"
 #include "GUIFont.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -293,10 +292,10 @@
   uDialogueType = 83;
   pDialogueWindow->Release();
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 350, WINDOW_MainMenu, 0, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton(471u, 445u, 169u, 35u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[34],// "Cancel"
+  pBtn_ExitCancel = pDialogueWindow->CreateButton(471u, 445u, 169u, 35u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[34],// "Cancel"
                  (Texture *)(uExitCancelTextureId != -1 ? &pIcons_LOD->pTextures[uExitCancelTextureId] : 0), 0);
-  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, 0x51u, 0, 0, "", 0);
-  pDialogueWindow->CreateButton(480u, 160u, 140u, 30u, 1, 0, 0, 0x53u, 0, "", 0);
+  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
+  pDialogueWindow->CreateButton(480u, 160u, 140u, 30u, 1, 0, UIMSG_0, 0x53u, 0, "", 0);
   pDialogueWindow->_41D08F(1, 1, 0, 2);
   dialog_menu_id = HOUSE_DIALOGUE_OTHER;
   v0 = (int)((char *)window_SpeakInHouse->ptr_1C - 102);
@@ -436,12 +435,12 @@
     pDialogueWindow->pControlsHead = 0;
     pDialogueWindow->pControlsTail = 0;
     pDialogueWindow->uNumControls = 0;
-    pBtn_ExitCancel = pDialogueWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79],
+    pBtn_ExitCancel = pDialogueWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79],
                    (Texture *)(uExitCancelTextureId != -1 ? (int)&pIcons_LOD->pTextures[uExitCancelTextureId] : 0), 0);
-    pDialogueWindow->CreateButton(0x1E0u, 0xA0u, 0x8Cu, 0x1Eu, 1, 0, 0x88u, 0x55u, 0, "", 0);
-    pDialogueWindow->CreateButton(0x1E0u, 0xBEu, 0x8Cu, 0x1Eu, 1, 0, 0x88u, 0x56u, 0, "", 0);
-    pDialogueWindow->CreateButton(0x1E0u, 0xDCu, 0x8Cu, 0x1Eu, 1, 0, 0x88u, 0x57u, 0, "", 0);
-    pDialogueWindow->CreateButton(0x1E0u, 0xFAu, 0x8Cu, 0x1Eu, 1, 0, 0x88u, 0x58u, 0, "", 0);
+    pDialogueWindow->CreateButton(0x1E0u, 0xA0u, 0x8Cu, 0x1Eu, 1, 0, UIMSG_SelectNPCDialogueOption, 0x55u, 0, "", 0);
+    pDialogueWindow->CreateButton(0x1E0u, 0xBEu, 0x8Cu, 0x1Eu, 1, 0, UIMSG_SelectNPCDialogueOption, 0x56u, 0, "", 0);
+    pDialogueWindow->CreateButton(0x1E0u, 0xDCu, 0x8Cu, 0x1Eu, 1, 0, UIMSG_SelectNPCDialogueOption, 0x57u, 0, "", 0);
+    pDialogueWindow->CreateButton(0x1E0u, 0xFAu, 0x8Cu, 0x1Eu, 1, 0, UIMSG_SelectNPCDialogueOption, 0x58u, 0, "", 0);
     pDialogueWindow->_41D08F(4, 1, 0, 1);
   }
 }
@@ -808,10 +807,10 @@
 {
   pDialogueWindow->Release();
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 345, WINDOW_MainMenu, 0, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton( 471, 445,  169, 35, 1, 0,  0x71u,  0,  0,
+  pBtn_ExitCancel = pDialogueWindow->CreateButton( 471, 445,  169, 35, 1, 0, UIMSG_Escape,  0,  0,
                  pGlobalTXT_LocalizationStrings[74],  //"End Conversation"
                  pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
-  pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, 0x51u, 0, 0, "", 0);
+  pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
 }
 
 //----- (004BD8B5) --------------------------------------------------------
@@ -827,7 +826,7 @@
   pKeyActionMap->_459ED1(3);
   pKeyActionMap->ResetKeys();
   activeLevelDecoration = NULL;
-  ptr_F8B1E8 = 0;
+  current_npc_text = 0;
   if ( pDialogueNPCCount )
   {
     v0 = dialog_menu_id;
@@ -898,7 +897,7 @@
         do
         {
           HouseNPCData[v2 + 7] = (NPCData *)window_SpeakInHouse->CreateButton(pNPCPortraits_x[v1 - 1][v2], pNPCPortraits_y[v1 - 1][v2],
-                                              0x3Fu, 0x49u, 1, 0, 0x19Au, v2, 0, byte_591180[v2], 0, 0, 0);
+                                              0x3Fu, 0x49u, 1, 0, UIMSG_19A, v2, 0, byte_591180[v2], 0, 0, 0);
           v1 = uNumDialogueNPCPortraits;
           ++v2;
           //v3 += 100;
@@ -1162,7 +1161,6 @@
 		break;
 		}
 
-
 	case HOUSE_DIALOGUE_SHOP_REPAIR:
 		{
 		v1 = pMouse->GetCursorPos(&a2)->x - 14;
@@ -4303,11 +4301,11 @@
   a1a.uFacing = 0;
   a1a.vPosition.z = a2->vPosition.z;
   a1a.vPosition.x = a2->vPosition.x;
-  a1a.field_50 = 0;
-  a1a.field_4C = 0;
-  a1a.field_48 = 0;
-  a1a.field_5C = 0;
-  a1a.field_58_pid = 0;
+  a1a.spell_skill = 0;
+  a1a.spell_level = 0;
+  a1a.spell_id = 0;
+  a1a.spell_target_pid = 0;
+  a1a.spell_caster_pid = 0;
   a1a.uSpriteFrameID = 0;
   a1a.uSectorID = pIndoor->GetSector(a2->vPosition.x, a2->vPosition.y, a2->vPosition.z);;
   return a1a.Create(0, 0, 0, 0);
@@ -6941,7 +6939,7 @@
                 && pt.y >= (signed int)pButton->uY && pt.y <= (signed int)pButton->uW
                 && pWindow == pWindow_MainMenu )
            {
-            pControlParam = pButton->uControlParam;
+            pControlParam = pButton->msg_param;
             switch (pControlParam) // ïîäñâåòêà êíîïîê
             {
               case 0:
@@ -6988,7 +6986,7 @@
 //----- (004637EB) --------------------------------------------------------
 int __stdcall aWinProc(HWND hWnd, UINT Msg, WPARAM wParam, unsigned int lParam)
 {
-  unsigned int v4; // esi@1
+  //unsigned int v4; // esi@1
   Render *v5; // ecx@14
   HANDLE v6; // eax@32
   Keyboard *v7; // eax@33
@@ -7029,10 +7027,15 @@
   switch (Msg)
   {
     case WM_SETTEXT: return DefWindowProcW(hWnd, Msg, wParam, lParam);
+    case WM_CHAR:
+    {
+      if (!pKeyActionMap->_459F10(wParam) && !viewparams->field_4C)
+        GUI_HandleHotkey(wParam);
+    }
+    return DefWindowProcA(hWnd, Msg, wParam, lParam);
   };
   
 
-  v4 = lParam;
   if ( Msg > WM_SYSCOMMAND )
   {
     switch ( Msg )
@@ -7090,7 +7093,7 @@
           if ( pAsyncMouse != v32 )
             goto _def_wnd_proc;
           back_to_game();
-          return DefWindowProcA(hWnd, Msg, wParam, v4);
+          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
         if (pAsyncMouse)
           goto _def_wnd_proc;
@@ -7104,7 +7107,7 @@
           if (pAsyncMouse)
             goto _def_wnd_proc;
           pArcomageGame->stru1.field_0 = 7;
-          return DefWindowProcA(hWnd, Msg, wParam, v4);
+          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
         if ( pVideoPlayer->pVideoFrame.pPixels )
           pVideoPlayer->bStopBeforeSchedule = 1;
@@ -7129,7 +7132,7 @@
         if ( pAsyncMouse == (void *)v28 )
         {
           UI_OnMouseLeftClick(0);
-          return DefWindowProcA(hWnd, Msg, wParam, v4);
+          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
         goto _def_wnd_proc;
       case WM_RBUTTONDBLCLK:
@@ -7151,14 +7154,14 @@
           if (!pAsyncMouse)
           {
             sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
-            return DefWindowProcA(hWnd, Msg, wParam, v4);
+            return DefWindowProcA(hWnd, Msg, wParam, lParam);
           }
           goto _def_wnd_proc;
         }
         if (pAsyncMouse)
           goto _def_wnd_proc;
         pArcomageGame->stru1.field_0 = 8;
-        return DefWindowProcA(hWnd, Msg, wParam, v4);
+        return DefWindowProcA(hWnd, Msg, wParam, lParam);
       case WM_MBUTTONDOWN:
         if ( pRenderer->pRenderD3D )
         {
@@ -7166,14 +7169,14 @@
           {
             v34 = GetPickDepth();
             pGame->PickMouse(v34, (unsigned __int16)lParam, lParam >> 16, 1, &vis_sprite_filter_3, &vis_face_filter);
-            return DefWindowProcA(hWnd, Msg, wParam, v4);
+            return DefWindowProcA(hWnd, Msg, wParam, lParam);
           }
           goto _def_wnd_proc;
         }
         if ( !pGame )
           goto _def_wnd_proc;
         sub_417871(0);
-        return DefWindowProcA(hWnd, Msg, wParam, v4);
+        return DefWindowProcA(hWnd, Msg, wParam, lParam);
       case WM_MOUSEMOVE:
         if ( pArcomageGame->bGameInProgress )
         {
@@ -7195,7 +7198,7 @@
             goto _def_wnd_proc;
           pMouse->SetMouseClick((unsigned __int16)lParam, lParam >> 16);
         }
-        return DefWindowProcA(hWnd, Msg, wParam, v4);
+        return DefWindowProcA(hWnd, Msg, wParam, lParam);
     }
   }
   if ( Msg == WM_SYSCOMMAND )
@@ -7213,7 +7216,7 @@
         if (pVideoPlayer->AnyMovieLoaded() && pVideoPlayer->pBinkBuffer)
         {
           BinkBufferSetOffset(pVideoPlayer->pBinkBuffer, 0, 0);
-          return DefWindowProcA(hWnd, Msg, wParam, v4);
+          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
       }
       goto _def_wnd_proc;
@@ -7225,16 +7228,7 @@
         if ( wParam == VK_CONTROL )
         {
           dword_507B98_ctrl_pressed = 0;
-          return DefWindowProcA(hWnd, Msg, wParam, v4);
-        }
-        goto _def_wnd_proc;
-      }
-      if ( Msg == WM_CHAR )
-      {
-        if ( !pKeyActionMap->_459F10(wParam) && !viewparams->field_4C )
-        {
-          GUI_HandleHotkey(wParam);
-          return DefWindowProcA(hWnd, Msg, wParam, v4);
+          return DefWindowProcA(hWnd, Msg, wParam, lParam);
         }
         goto _def_wnd_proc;
       }
@@ -7255,7 +7249,7 @@
           return 0;
         }
         if ( wParam != 40001 )
-          return DefWindowProcA(hWnd, Msg, wParam, v4);
+          return DefWindowProcA(hWnd, Msg, wParam, lParam);
       }
       v38 = 0;
       v37 = 0;
@@ -7268,7 +7262,7 @@
     if ( dword_506E68 != -1 )
     {
       pKeyActionMap->_459F10(wParam);
-      return DefWindowProcA(hWnd, Msg, wParam, v4);
+      return DefWindowProcA(hWnd, Msg, wParam, lParam);
     }
     if ( !pArcomageGame->bGameInProgress )
     {
@@ -7598,12 +7592,11 @@
       if (pAsyncMouse)
       {
         pAsyncMouse->Suspend();
-        return DefWindowProcA(hWnd, Msg, wParam, v4);
+        return DefWindowProcA(hWnd, Msg, wParam, lParam);
       }
     }
 _def_wnd_proc:
-    v4 = lParam;
-    return DefWindowProcA(hWnd, Msg, wParam, v4);
+    return DefWindowProcA(hWnd, Msg, wParam, lParam);
   }
   if ( Msg != WM_KILLFOCUS )
   {
@@ -7631,12 +7624,12 @@
     goto _def_wnd_proc;
   }
   if ( ::hWnd != (HWND)wParam || (dword_4E98BC_bApplicationActive = 1, pRenderer->bWindowMode) || !pAsyncMouse )
-    return DefWindowProcA(hWnd, Msg, wParam, v4);
+    return DefWindowProcA(hWnd, Msg, wParam, lParam);
   pAsyncMouse->Resume();
   if ( !pAsyncMouse )
     goto _def_wnd_proc;
   pAsyncMouse->Clip();
-  return DefWindowProcA(hWnd, Msg, wParam, v4);
+  return DefWindowProcA(hWnd, Msg, wParam, lParam);
 }
 
 //----- (00464479) --------------------------------------------------------
@@ -7777,7 +7770,7 @@
     bUnderwater = 1;
     pGame->uFlags2 |= 8u;
   }
-  pParty->field_6F4_packedid = 0;
+  pParty->floor_face_pid = 0;
   if ( _strcmpi(Str1, "blv") )
     PrepareToLoadODM(v9, 0);
   else
@@ -10991,9 +10984,9 @@
         {
           if ( stru_50C198.GetMagicalResistance(v2, 0xAu) )
           {
-			  v2->pActorBuffs[v1->field_48].Apply(
-              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v1->field_4C << 7) * 0.033333335),
-              v1->field_50,
+			  v2->pActorBuffs[v1->spell_id].Apply(
+              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v1->spell_level << 7) * 0.033333335),
+              v1->spell_skill,
               4u,
               0,
               0);
@@ -11170,12 +11163,12 @@
   v151 = a2 & 7;
   if ( (a2 & 7) == OBJECT_Actor)
   {
-    if ( (v2->field_58_pid & 7) == OBJECT_Actor && !pActors[v2->field_58_pid >> 3].GetActorsRelation(&pActors[a2 >> 3]) )
+    if ( (v2->spell_caster_pid & 7) == OBJECT_Actor && !pActors[v2->spell_caster_pid >> 3].GetActorsRelation(&pActors[a2 >> 3]) )
       return 1;
   }
   else
   {
-    if ( (a2 & 7) == OBJECT_Player && (v2->field_58_pid & 7) == OBJECT_Player)
+    if ( (a2 & 7) == OBJECT_Player && (v2->spell_caster_pid & 7) == OBJECT_Player)
       return 1;
   }
   if ( pParty->bTurnBasedModeOn == 1 )
@@ -11187,8 +11180,8 @@
       v2->uAttributes = v5 & 0xFFFB;
     }
   }
-  if ( v151 == OBJECT_BModel && (v2->field_58_pid & 7) != OBJECT_Player)
-    BYTE2(pActors[v2->field_58_pid >> 3].uAttributes) |= 4u;
+  if ( v151 == OBJECT_BModel && (v2->spell_caster_pid & 7) != OBJECT_Player)
+    BYTE2(pActors[v2->spell_caster_pid >> 3].uAttributes) |= 4u;
   v6 = v2->uType;
   v7 = v2->uType;
   if ( v7 > 3060 )
@@ -11246,7 +11239,7 @@
         v138 = 1;
         if ( v151 != OBJECT_Actor)
         {
-          if ( v6 != 9030 || v2->field_50 != 4 )
+          if ( v6 != 9030 || v2->spell_skill != 4 )
             goto LABEL_246;
           v2->_46BEF1_apply_spells();
 LABEL_233:
@@ -11303,9 +11296,9 @@
         v106 = v145;
         v150 = 0;
         v139 = v106 >> 3;
-        v137 = v2->field_4C;
-        v152 = v2->field_50;
-        v136 = v2->field_48;
+        v137 = v2->spell_level;
+        v152 = v2->spell_skill;
+        v136 = v2->spell_id;
         if ( v6 == 9030 )
         {
           v150 = 2;
@@ -11359,9 +11352,9 @@
               {
                 v2->_46BEF1_apply_spells();
               }
-              v2->field_4C = 0;
-              v2->field_50 = 0;
-              v2->field_48 = 0;
+              v2->spell_level = 0;
+              v2->spell_skill = 0;
+              v2->spell_id = 0;
               goto LABEL_233;
             }
             v135 = 10;
@@ -11469,7 +11462,7 @@
             v127 = v9;
             v126 = v124;
 LABEL_268:
-            v116 = word_4EE088_sound_ids[v2->field_48];
+            v116 = word_4EE088_sound_ids[v2->spell_id];
 LABEL_269:
             v125 = v116 + 1;
             goto LABEL_29;
@@ -11502,7 +11495,7 @@
           if ( !v63 )
             SpriteObject::OnInteraction(v153);
           v64 = v2->uFacing - stru_5C6E00->uIntegerDoublePi;
-          v44 = v2->field_50 == 4;
+          v44 = v2->spell_skill == 4;
           v2->vVelocity.z = 0;
           v2->vVelocity.y = 0;
           v2->vVelocity.x = 0;
--- a/mm7_3.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_3.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -4,7 +4,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -43,6 +42,8 @@
 #include "stru298.h"
 #include "texts.h"
 #include "Log.h"
+
+#include "MM7.h"
 #include "mm7_data.h"
 
 //----- (0046E44E) --------------------------------------------------------
@@ -1390,7 +1391,7 @@
       v4 = &pObjectList->pObjects[item->uObjectDescID];
       if (item->AttachedToActor())
       {
-          v5 = item->field_5C >> 3;
+          v5 = item->spell_target_pid >> 3;
           *(int *)(v2 - 26) = pActors[v5].vPosition.x;
           *(int *)(v2 - 22) = pActors[v5].vPosition.y;
           *(int *)(v2 - 18) = pActors[v5].vPosition.z + pActors[v5].uActorHeight;
@@ -1479,7 +1480,7 @@
 }
 
 //----- (0047272C) --------------------------------------------------------
-int _47272C_collide_agains_some_secotors_floors(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
+int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID)
 {
   signed int v5; // ebx@1
   int result; // eax@1
@@ -1519,15 +1520,15 @@
 {
   int v1; // ebx@1
   int v2; // edi@1
-  int v6; // eax@18
-  signed __int64 v8; // qax@27
-  int v9; // eax@27
+  //int v6; // eax@18
+  //signed __int64 v8; // qax@27
+  //int v9; // eax@27
   double v10; // st7@27
   unsigned int v12; // eax@49
   double v13; // st7@50
-  int v14; // eax@51
-  signed __int64 v15; // qax@53
-  double v16; // st7@54
+  //int v14; // eax@51
+  //signed __int64 v15; // qax@53
+  //double v16; // st7@54
   int v17; // eax@62
   double v18; // st7@62
   int v19; // ST40_4@62
@@ -1572,10 +1573,10 @@
   unsigned int v64; // [sp-8h] [bp-68h]@161
   int v65; // [sp-4h] [bp-64h]@75
   int v66; // [sp-4h] [bp-64h]@161
-  int v68; // [sp+10h] [bp-50h]@45
+  //int v68; // [sp+10h] [bp-50h]@45
   int v69; // [sp+10h] [bp-50h]@140
   unsigned int uFaceEvent; // [sp+14h] [bp-4Ch]@1
-  signed int v71; // [sp+18h] [bp-48h]@1
+  //signed int v71; // [sp+18h] [bp-48h]@1
   signed int v72; // [sp+1Ch] [bp-44h]@1
   signed int v73; // [sp+20h] [bp-40h]@100
   int v74; // [sp+20h] [bp-40h]@140
@@ -1604,29 +1605,24 @@
   uSectorID = pIndoor->GetSector(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z);
   v72 = 0;
   v78 = 0;
-  v71 = 0;
   bJumping = 0;
 
   uFaceID = -1;
-  v80 = collide_against_floor(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
-  assert(uFaceID != -1);
-
-  for (uint i = 0; i < pIndoor->uNumFaces; ++i)
-    pIndoor->pFaces[i].uAttributes &= ~FACE_OUTLINED;
-  pIndoor->pFaces[uFaceID].uAttributes |= FACE_OUTLINED;
+  auto floor_level = collide_against_floor(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
 
   if ( pParty->bFlying )
   {
     pParty->bFlying = false;
     if (pParty->FlyActive())
       pOtherOverlayList->pOverlays[pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID - 1].field_E |= 1;
-      //stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1u;// 005E4D58 pOtherOverlayList [negindexing]
-  }
-  if ( v80 == -30000 )
-  {
-    v80 = _47272C_collide_agains_some_secotors_floors(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
-    if ( v80 == -30000 )
-    {
+  }
+
+  if ( floor_level == -30000  || uFaceID == -1)
+  {
+    floor_level = collide_against_floor_approximate(new_party_x, new_party_y, party_z + 40, &uSectorID, &uFaceID);
+    if ( floor_level == -30000 || uFaceID == -1)
+    {
+      __debugbreak(); // level built with errors 
       pParty->vPosition.x = blv_prev_party_x;
       pParty->vPosition.y = blv_prev_party_z;
       pParty->vPosition.z = blv_prev_party_y;
@@ -1634,6 +1630,11 @@
       return;
     }
   }
+
+  for (uint i = 0; i < pIndoor->uNumFaces; ++i)
+    pIndoor->pFaces[i].uAttributes &= ~FACE_OUTLINED;
+  pIndoor->pFaces[uFaceID].uAttributes |= FACE_OUTLINED;
+
   blv_prev_party_x = pParty->vPosition.x;
   blv_prev_party_z = pParty->vPosition.y;
   blv_prev_party_y = pParty->vPosition.z;
@@ -1650,84 +1651,86 @@
     }
     dword_720CDC = v67;
   }
+
+  uint fall_start;
   if (!pParty->FeatherFallActive())
   {
     bFeatherFall = false;
-    if (!pParty->pPlayers[0].WearsItem(536, 16) &&
-        !pParty->pPlayers[1].WearsItem(536, 16) &&
-        !pParty->pPlayers[2].WearsItem(536, 16) &&
-        !pParty->pPlayers[3].WearsItem(536, 16))
-    {
-      v6 = pParty->uFallStartY;
-    }
-  }
-  else
-  {
-    v6 = v80;
+    if (!pParty->pPlayers[0].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16) &&  // grants feather fall
+        !pParty->pPlayers[1].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16) &&
+        !pParty->pPlayers[2].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16) &&
+        !pParty->pPlayers[3].WearsItem(ITEM_ARTIFACT_LADYS_ESCORT, 16))
+    {
+      fall_start = pParty->uFallStartY;
+    }
+  }
+  else
+  {
+    fall_start = floor_level;
     bFeatherFall = true;
-    pParty->uFallStartY = v80;
-  }
-LABEL_20:
-  if ( v6 - party_z > 512 && !bFeatherFall && party_z <= v80 + 1 )
-  {
+    pParty->uFallStartY = floor_level;
+  }
+
+
+  if (fall_start - party_z > 512 && !bFeatherFall && party_z <= floor_level + 1)
+  {
+    assert(~pParty->uFlags & PARTY_FLAGS_1_LANDING); // why land in indoor?
     if (pParty->uFlags & PARTY_FLAGS_1_LANDING)
-    {
       pParty->uFlags &= ~PARTY_FLAGS_1_LANDING;
-    }
     else for (uint i = 0; i < 4; ++i)
     {                                      // receive falling damage
-      auto pPlayer = pParty->pPlayers + i;
-           
-      if (!pPlayer->HasEnchantedItemEquipped(72) &&
-          !pPlayer->WearsItem(529, 8))
-      {
-        v8 = (signed __int64)((double)pPlayer->GetMaxHealth() * 0.1);
-        pPlayer->ReceiveDamage((pParty->uFallStartY - party_z) * (signed int)v8 / 256, 4);
-        v9 = pPlayer->GetActualEndurance();
-        v10 = (double)(20 - pPlayer->_48EA1B_get_static_effect(v9)) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
-        pPlayer->SetRecoveryTime((signed __int64)v10);
-      }
-    }
-  }
-  if ( party_z > v80 + 1 )
+      auto player = pParty->pPlayers + i;
+      if (!player->HasEnchantedItemEquipped(72) && !player->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, 8))
+      {
+        player->ReceiveDamage((pParty->uFallStartY - party_z) * (0.1f * player->GetMaxHealth()) / 256, 4);
+        v10 = (double)(20 - player->_48EA1B_get_static_effect(player->GetActualEndurance())) * flt_6BE3A4_debug_recmod1 * 2.133333333333333;
+        player->SetRecoveryTime((signed __int64)v10);
+      }
+    }
+  }
+
+  if ( party_z > floor_level + 1 )
     bJumping = 1;
-  bFeatherFall = party_z - v80 <= 32;
-  if ( party_z - v80 <= 32 )
+
+  bool jumping_up = false;
+
+  if ( party_z - floor_level <= 32 )
+  {
     pParty->uFallStartY = party_z;
-  if ( bWalkSound && pParty->field_6F8 > 0 )
-    pParty->field_6F8 -= pEventTimer->uTimeElapsed;
-  if ( party_z > v80 + 1 )
-  {
-    if ( bJumping )
-      goto LABEL_45;
-    goto LABEL_44;
-  }
-  party_z = v80 + 1;
-  pParty->uFallStartY = v80 + 1;
-  if ( bJumping )
-    goto LABEL_45;
-  if (pParty->field_6F4_packedid != uFaceID)
-  {
-    auto pFace = &pIndoor->pFaces[uFaceID];
-    if (pFace->uAttributes & 0x04000000 )
-    {
-      uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
-      if ( bJumping )
-        goto LABEL_45;
-      goto LABEL_44;
-    }
-  }
-LABEL_44:
-  pParty->field_6F4_packedid = uFaceID;
-LABEL_45:
-  v68 = uFaceID;
-  if ( pIndoor->pFaces[uFaceID].uAttributes & 0x10 )
-    v71 = 1;
+    jumping_up = true;
+  }
+
+  if (bWalkSound && pParty->walk_sound_timer)
+  {
+    if (pParty->walk_sound_timer > pEventTimer->uTimeElapsed)
+      pParty->walk_sound_timer -= pEventTimer->uTimeElapsed;
+    else pParty->walk_sound_timer = 0;
+  }
+
+
+  if (party_z <= floor_level + 1)
+  {
+    party_z = floor_level + 1;
+    pParty->uFallStartY = floor_level + 1;
+
+    if (!bJumping && pParty->floor_face_pid != uFaceID)
+    {
+      auto pFace = &pIndoor->pFaces[uFaceID];
+      if (pFace->uAttributes & FACE_PRESSURE_PLATE)
+        uFaceEvent = pIndoor->pFaceExtras[pFace->uFaceExtraID].uEventID;
+    }
+  }
+  if (!bJumping)
+    pParty->floor_face_pid = uFaceID;
+
+  bool on_water = false;
+  if ( pIndoor->pFaces[uFaceID].Fluid())
+    on_water = true;
+
   v81 = pParty->uWalkSpeed;
   angle = pParty->sRotationY;
   _view_angle = pParty->sRotationX;
-  v82 = (unsigned __int64)(pEventTimer->dt_in_some_format
-                         * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi)
+  v82 = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi)
                                           / 180)) >> 16;
 //LABEL_87:
   while ( pPartyActionQueue->uNumActions )
@@ -1735,43 +1738,32 @@
     switch ( pPartyActionQueue->Next() )
     {
       case PARTY_TurnLeft:
-        if ( uTurnSpeed )
-        {
-          v14 = angle + uTurnSpeed;
-          angle = stru_5C6E00->uDoublePiMask & v14;
-          break;
-        }
-        v14 = angle + (unsigned __int64)(signed __int64)(double)v82 * fTurnSpeedMultiplier;
-        angle = stru_5C6E00->uDoublePiMask & v14;
+        if (uTurnSpeed)
+          angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed);
+        else
+          angle = stru_5C6E00->uDoublePiMask & (angle + (int)(v82 * fTurnSpeedMultiplier));
         break;
       case PARTY_TurnRight:
-        if ( uTurnSpeed )
-        {
+        if (uTurnSpeed)
           angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed);
-          break;
-        }
-        v16 = (double)v82 * fTurnSpeedMultiplier;
-        angle = stru_5C6E00->uDoublePiMask & (angle - (signed __int64)v16);
+        else
+          angle = stru_5C6E00->uDoublePiMask & (angle - (int)(v82 * fTurnSpeedMultiplier));
         break;
+
       case PARTY_FastTurnLeft:
-        if ( uTurnSpeed )
-        {
-          v14 = angle + uTurnSpeed;
-        }
+        if (uTurnSpeed)
+          angle = stru_5C6E00->uDoublePiMask & (angle + uTurnSpeed);
         else
-        {
-          v14 = angle + (unsigned __int64)(signed __int64)(fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)v82;
-        }
-        angle = stru_5C6E00->uDoublePiMask & v14;
+          angle = stru_5C6E00->uDoublePiMask & (angle + (int)(2.0f * fTurnSpeedMultiplier * (double)v82));
         break;
+
       case PARTY_FastTurnRight:
-        LODWORD(v15) = uTurnSpeed;
-        if ( !uTurnSpeed )
-        {
-          v15 = (signed __int64)(fTurnSpeedMultiplier + fTurnSpeedMultiplier) * (double)v82;
-        }
-        angle = stru_5C6E00->uDoublePiMask & (angle - v15);
+        if (uTurnSpeed)
+          angle = stru_5C6E00->uDoublePiMask & (angle - uTurnSpeed);
+        else
+          angle = stru_5C6E00->uDoublePiMask & (angle - (int)(2.0f * fTurnSpeedMultiplier * (double)v82));
         break;
+
       case PARTY_StrafeLeft:
         v2 -= (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
         v1 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)((signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier) >> 1)) >> 16;
@@ -1783,8 +1775,8 @@
         v78 = 1;
         break;
       case PARTY_WalkForward:
-        v2 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier)) >> 16;
-        v1 += (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(signed __int64)((double)v81 * fWalkSpeedMultiplier)) >> 16;
+        v2 += (unsigned __int64)(stru_5C6E00->Cos(angle) * (signed __int64)(signed int)(signed __int64)(5 * (double)v81 * fWalkSpeedMultiplier)) >> 16;
+        v1 += (unsigned __int64)(stru_5C6E00->Sin(angle) * (signed __int64)(signed int)(signed __int64)(5 * (double)v81 * fWalkSpeedMultiplier)) >> 16;
         v78 = 1;
         break;
       case PARTY_WalkBackward:
@@ -1826,7 +1818,7 @@
         _view_angle = 0;
         break;
       case PARTY_Jump:
-        if ( (!bJumping || party_z <= v80 + 6 && pParty->uFallSpeed <= 0) && pParty->field_24 )
+        if ( (!bJumping || party_z <= floor_level + 6 && pParty->uFallSpeed <= 0) && pParty->field_24 )
         {
           bJumping = 1;
           pParty->uFallSpeed = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)pParty->uFallSpeed);
@@ -1845,7 +1837,7 @@
   }
   else
   {
-    if ( pIndoor->pFaces[v68].pFacePlane_old.vNormal.z < 32768 )
+    if ( pIndoor->pFaces[uFaceID].pFacePlane_old.vNormal.z < 32768 )
     {
       pParty->uFallSpeed -= pEventTimer->uTimeElapsed * GetGravityStrength();
       goto LABEL_92;
@@ -1861,8 +1853,8 @@
       v41 = &pPlayers[1];
       do
       {
-        if ( !(*v41)->HasEnchantedItemEquipped(72) && !(*v41)->WearsItem(529, 8) )
-          (*v41)->PlayEmotion(CHARACTER_EXPRESSION_46, 0);
+        if ( !(*v41)->HasEnchantedItemEquipped(72) && !(*v41)->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, 8) )
+          (*v41)->PlayEmotion(CHARACTER_EXPRESSION_SCARED, 0);
         ++v41;
       }
       while ( (signed int)v41 <= (signed int)&pPlayers[4] );
@@ -1978,7 +1970,7 @@
             v1 = 0;
             v2 = 0;
           }
-          if ( pParty->field_6F4_packedid != v43 >> 3 && BYTE3(v44->uAttributes) & 4 )
+          if ( pParty->floor_face_pid != PID_ID(v43) && BYTE3(v44->uAttributes) & 4 )
             uFaceEvent = pIndoor->pFaceExtras[v44->uFaceExtraID].uEventID;
           goto LABEL_152;
         }
@@ -2010,7 +2002,7 @@
             v87 += v52 * v74 >> 16;
           }
           v43 = stru_721530.uFaceID;
-          if ( pParty->field_6F4_packedid != v43 >> 3 && BYTE3(v44->uAttributes) & 4 )
+          if ( pParty->floor_face_pid != PID_ID(v43) && BYTE3(v44->uAttributes) & 4 )
             uFaceEvent = pIndoor->pFaceExtras[v44->uFaceExtraID].uEventID;
           goto LABEL_152;
         }
@@ -2028,7 +2020,7 @@
         if ( v2 * v2 + v1 * v1 >= 400 )
         {
           v43 = stru_721530.uFaceID;
-          if ( pParty->field_6F4_packedid != v43 >> 3 && BYTE3(v44->uAttributes) & 4 )
+          if ( pParty->floor_face_pid != PID_ID(v43) && BYTE3(v44->uAttributes) & 4 )
             uFaceEvent = pIndoor->pFaceExtras[v44->uFaceExtraID].uEventID;
           goto LABEL_152;
         }
@@ -2048,13 +2040,13 @@
       break;
     }
   }
-  if ( bWalkSound && pParty->field_6F8 <= 0 )
+  if ( bWalkSound && !pParty->walk_sound_timer)
   {
     if ( integer_sqrt((pParty->vPosition.x - new_party_x) * (pParty->vPosition.x - new_party_x) + (pParty->vPosition.y - new_party_y)
          * (pParty->vPosition.y - new_party_y) + (pParty->vPosition.z - new_party_z)
          * (pParty->vPosition.z - new_party_z)) <= 16 )
       goto LABEL_188;
-    if ( v72 && (!bJumping || bFeatherFall) )
+    if ( v72 && (!bJumping || jumping_up) )
     {
       v66 = 0;
       v64 = 0;
@@ -2063,7 +2055,7 @@
       v60 = -1;
       v59 = 1;
       v58 = 804;
-      if ( !v71 )
+      if ( !on_water )
       {
         v56 = pAudioPlayer;
         if ( BYTE2(pIndoor->pFaces[uFaceID].uAttributes) & 0x20 )
@@ -2076,7 +2068,7 @@
       v56 = pAudioPlayer;
       goto LABEL_175;
     }
-    if ( v78 && (!bJumping || bFeatherFall) )
+    if ( v78 && (!bJumping || jumping_up) )
     {
       v66 = 0;
       v64 = 0;
@@ -2085,7 +2077,7 @@
       v60 = -1;
       v59 = 1;
       v58 = 804;
-      if ( v71 )
+      if ( on_water )
       {
         v57 = (SoundID)102;
         v56 = pAudioPlayer;
@@ -2103,10 +2095,10 @@
     {
 LABEL_188:
       pAudioPlayer->_4AA258(804);
-      pParty->field_6F8 = 64;
-    }
-  }
-  if ( !bJumping || bFeatherFall )
+      pParty->walk_sound_timer = 64;
+    }
+  }
+  if ( !bJumping || jumping_up )
     pParty->uFlags &= ~PARTY_FLAGS_1_FALLING;
   else
     pParty->uFlags |= PARTY_FLAGS_1_FALLING;
@@ -2349,15 +2341,19 @@
     bJumping = 1;
   }
   v101 = pZ - v111 <= 32;
-  if ( bWalkSound && pParty->field_6F8 > 0 )
-    pParty->field_6F8 -= pEventTimer->uTimeElapsed;
+  if ( bWalkSound && pParty->walk_sound_timer)
+  {
+    if (pParty->walk_sound_timer >= pEventTimer->uTimeElapsed)
+      pParty->walk_sound_timer -= pEventTimer->uTimeElapsed;
+    else pParty->walk_sound_timer = 0;
+  }
   if (!bUnderwater
     && SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0
     && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) < 0 || LODWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0) )
     pParty->bFlying = false;
   if (!bJumping)
   {
-    if ( pParty->field_6F4_packedid != (8 * v108 | OBJECT_BModel) )
+    if ( pParty->floor_face_pid != PID(OBJECT_BModel, v108) )
     {
       if (v108)
       {
@@ -2372,13 +2368,13 @@
           }*/
 		  if ( BYTE3(v7[v6].uAttributes) & 4 )
           {
-            pParty->field_6F4_packedid = 8 * v108 | OBJECT_BModel;
+            pParty->floor_face_pid = PID(OBJECT_BModel, v108);
             v103 = v7[v6].sCogTriggeredID;
           }
         }
       }
     }
-    pParty->field_6F4_packedid = 8 * v108 | OBJECT_BModel;
+    pParty->floor_face_pid = PID(OBJECT_BModel, v108);
   }
   _walk_speed = pParty->uWalkSpeed;
   _angle_y = pParty->sRotationY;
@@ -2953,9 +2949,9 @@
 LABEL_220:
           v45 = stru_721530.uFaceID;
 LABEL_221:
-          if ( pParty->field_6F4_packedid != v45 && BYTE3(v47->uAttributes) & 4 )
-          {
-            pParty->field_6F4_packedid = v45;
+          if ( pParty->floor_face_pid != v45 && BYTE3(v47->uAttributes) & 4 )
+          {
+            pParty->floor_face_pid = v45;
             v103 = v47->sCogTriggeredID;
           }
           goto LABEL_234;
@@ -2988,7 +2984,7 @@
     v121 = (unsigned __int64)(58500i64 * v121) >> 16;
   }
   while ( v126 < 100 );
-  if ( bWalkSound && pParty->field_6F8 <= 0 )
+  if ( bWalkSound && pParty->walk_sound_timer <= 0 )
   {
     v122 = abs(pParty->vPosition.x - pX);
     v126 = abs(pParty->vPosition.y - pY);
@@ -2998,7 +2994,7 @@
     if ( v114 && (!bJumping || v101) )
     {
       if ( !v107
-        && !(BYTE1(pOutdoor->pBModels[pParty->field_6F4_packedid >> 9].pFaces[(pParty->field_6F4_packedid >> 3) & 0x3F].uAttributes) & 0x20) )
+        && !(BYTE1(pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].uAttributes) & 0x20) )
       {
         
         v90 = -1;
@@ -3021,7 +3017,7 @@
     if ( v124 && (!bJumping || v101) )
     {
       if ( v107
-        || BYTE1(pOutdoor->pBModels[pParty->field_6F4_packedid >> 9].pFaces[(pParty->field_6F4_packedid >> 3) & 0x3F].uAttributes) & 0x20 )
+        || BYTE1(pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].uAttributes) & 0x20 )
       {
         
         v90 = -1;
@@ -3041,7 +3037,7 @@
     {
 LABEL_344:
       pAudioPlayer->_4AA258(804);
-      pParty->field_6F8 = 64;
+      pParty->walk_sound_timer = 64;
     }
   }
   if ( !bJumping || v101 )
@@ -3175,10 +3171,10 @@
     }
     goto LABEL_318;
   }
-  if ( bWalkSound && pParty->field_6F8 <= 0 )
+  if ( bWalkSound && pParty->walk_sound_timer <= 0 )
   {
     pAudioPlayer->_4AA258(804);
-    pParty->field_6F8 = 64;
+    pParty->walk_sound_timer = 64;
   }
 LABEL_318:
   v81 = pZ;
@@ -12426,8 +12422,8 @@
 
   v0 = pFontArrus;
   pFont = pFontArrus;
-  if ( ptr_F8B1E8 && !byte_5B0938[0] )
-    strcpy(byte_5B0938, ptr_F8B1E8);
+  if ( current_npc_text && !byte_5B0938[0] )
+    strcpy(byte_5B0938, current_npc_text);
   v5.uFrameWidth = game_viewport_width;
   v5.uFrameZ = 452;
   v1 = pFontArrus->CalcTextHeight(byte_5B0938, &v5, 12, 0) + 7;
@@ -12497,10 +12493,10 @@
     dword_5C341C = v3;
     _591094_decoration = activeLevelDecoration;
     pGUIWindow2 = GUIWindow::Create(0, 0, 640u, 480u, WINDOW_GreetingNPC, a4, 0);
-    pGUIWindow2->CreateButton(61u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 1u, 0x31u, "", 0);
-    pGUIWindow2->CreateButton(177u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 2u, 0x32u, "", 0);
-    pGUIWindow2->CreateButton(292u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 3u, 0x33u, "", 0);
-    pGUIWindow2->CreateButton(407u, 424u, 0x1Fu, 0x28u, 2, 94, 0x6Eu, 4u, 0x34u, "", 0);
+    pGUIWindow2->CreateButton(61u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 1u, 0x31u, "", 0);
+    pGUIWindow2->CreateButton(177u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 2u, 0x32u, "", 0);
+    pGUIWindow2->CreateButton(292u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 3u, 0x33u, "", 0);
+    pGUIWindow2->CreateButton(407u, 424u, 0x1Fu, 0x28u, 2, 94, UIMSG_SelectCharacter, 4u, 0x34u, "", 0);
   }
 }
 
@@ -12540,7 +12536,7 @@
 void __cdecl DrawDialogueUI()
 {
   NPCData *pNPC; // ebx@2
-  int v1; // eax@2
+  int pGreetType; // eax@2
   unsigned __int16 v2; // di@2
   //unsigned int v3; // eax@2
   char *v4; // esi@3
@@ -12591,7 +12587,7 @@
     return;
   memcpy(&v51, pDialogueWindow, sizeof(v51));
   pNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
-  v1 = sub_445C8B(sDialogue_SpeakingActorNPC_ID);
+  pGreetType = GetGreetType(sDialogue_SpeakingActorNPC_ID);
   v51.uFrameWidth -= 10;
   v51.uFrameZ -= 10;
   //v54 = v1;
@@ -12655,9 +12651,9 @@
     default:
       if (uDialogueType > DIALOGUE_18 && uDialogueType < DIALOGUE_23 && !byte_5B0938[0])
       {
-        pInString = (char *)ptr_F8B1E8;
-      }
-      else if (v1 == 1)
+        pInString = (char *)current_npc_text;
+      }
+      else if (pGreetType == 1)//QuestNPC_greet
       {
         if (pNPC->greet)
         {
@@ -12667,7 +12663,7 @@
             pInString = pNPCStats->pNPCGreetings[pNPC->greet - 1].pGreeting1;
         }
       }
-      else if (v1 == 2)
+      else if (pGreetType == 2)//HiredNPC_greet
       {
         auto prof = pNPCStats->pProfessions + pNPC->uProfession - 1;
 
@@ -12709,7 +12705,7 @@
     //v15 = v14;
     if ( !v14 )
       break;
-    v16 = v14->uControlParam;
+    v16 = v14->msg_param;
 
     if ( v16 > 88 )
       v14->pButtonName[0] = 0;
@@ -12737,7 +12733,7 @@
       if (!topic)
       {
         v14->pButtonName[0] = 0;
-        v14->uControlParam = 0;
+        v14->msg_param = 0;
       }
       else
         strcpy(v14->pButtonName, topic);
@@ -12751,7 +12747,7 @@
       if (!topic)
       {
         v14->pButtonName[0] = 0;
-        v14->uControlParam = 0;
+        v14->msg_param = 0;
       }
       else strcpy(v14->pButtonName, topic);
 	}
@@ -12762,7 +12758,7 @@
       if (!topic)
       {
         v14->pButtonName[0] = 0;
-        v14->uControlParam = 0;
+        v14->msg_param = 0;
       }
       else strcpy(v14->pButtonName, topic);
 	}
@@ -12773,7 +12769,7 @@
       if (!topic)
       {
         v14->pButtonName[0] = 0;
-        v14->uControlParam = 0;
+        v14->msg_param = 0;
       }
       else strcpy(v14->pButtonName, topic);
 	}
@@ -12784,7 +12780,7 @@
       if (!topic)
       {
         v14->pButtonName[0] = 0;
-        v14->uControlParam = 0;
+        v14->msg_param = 0;
       }
       else strcpy(v14->pButtonName, topic);
 	}
@@ -12795,7 +12791,7 @@
       if (!topic)
       {
         v14->pButtonName[0] = 0;
-        v14->uControlParam = 0;
+        v14->msg_param = 0;
       }
       else strcpy(v14->pButtonName, topic);
 	}
@@ -12891,7 +12887,7 @@
 }
 
 //----- (00445C8B) --------------------------------------------------------
-int __fastcall sub_445C8B(signed int a1)
+int __fastcall GetGreetType(signed int SpeakingNPC_ID)
 {
   signed int v1; // ebx@1
   int v3; // edi@6
@@ -12902,13 +12898,13 @@
   NPCData *v8; // esi@11
 
   v1 = 0;
-  if ( a1 >= 0 )
-  {
-    if ( a1 < 5000 )
-      return 1;
-    return 2;
-  }
-  if ( a1 >= 5000 )
+  if ( SpeakingNPC_ID >= 0 )
+  {
+    if ( SpeakingNPC_ID < 5000 )
+      return 1;//QuestNPC_greet
+    return 2;//HiredNPC_greet
+  }
+  if ( SpeakingNPC_ID >= 5000 )
     return 2;
   v3 = abs((int)sDialogue_SpeakingActorNPC_ID) - 1;
   v4 = 0;
@@ -12938,7 +12934,7 @@
     }
     while ( v1 < (signed int)pNPCStats->uNumNewNPCs );
   }
-  return ((unsigned __int8)pTmpBuf[v3] < 2u) + 1;
+  return ((unsigned __int8)pTmpBuf[v3] < 2) + 1;
 }
 
 //----- (0044603D) --------------------------------------------------------
@@ -13603,7 +13599,7 @@
   {
     v11 = uNumActors;
     SpawnEncounter((MapInfo *)&pMapStats->pInfos[v10], &v16, 0, count, 0);
-    memcpy(&v15, Actor::GetDirectionInfo(8 * v11 | AI_OBJECT_ACTOR, 4u, &a3, 1), sizeof(v15));
+    memcpy(&v15, Actor::GetDirectionInfo(PID(OBJECT_Actor, v11), 4u, &a3, 1), sizeof(v15));
     v12 = v11;
     if ( (signed int)v11 < (signed int)uNumActors )
     {
@@ -13619,7 +13615,7 @@
 }
 
 //----- (00448DF8) --------------------------------------------------------
-void __fastcall sub_448DF8_cast_spell(int spellnum, int rank, int level, int fromx, int fromy, int fromz, int tox, int toy, int toz)
+void __fastcall EventCastSpell(int spellnum, 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
@@ -13686,7 +13682,7 @@
   float toza; // [sp+D4h] [bp+20h]@6
 
   v9 = 0;
-  v59 = rank + 1;
+  v59 = uSkillLevel + 1;
   //spellnum_ = spellnum;
   v60 = 0;
   if ( tox || toy || toz )
@@ -13743,34 +13739,43 @@
       v41 = v40 - 1;
       if ( !v41 )
       {
-        v42 = 14400 * level;
-        v43 = 4 * level + 10;
-        goto LABEL_114;
+        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[2];
+        v36 = pParty->uTimePlayed + v39;
+        v37->Apply(v36, a7b, v43, 0, 0);
+        goto LABEL_139;
       }
       if ( v41 == 1 )
       {
-        v42 = 18000 * level;
-        v43 = 5 * level + 10;
-        goto LABEL_114;
-      }
-    }
-    v42 = 10800 * level;
-    v43 = 3 * level + 10;
-LABEL_114:
+        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[2];
+       v36 = pParty->uTimePlayed + v39;
+       v37->Apply(v36, a7b, v43, 0, 0);
+       goto LABEL_139;
+      }
+    }
+    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);
-    v52 = 0;
-    v50 = 0;
-    v48 = v43;
-    v46 = a7b;
     v39 = (signed __int64)((double)(v42 << 7) * 0.033333335);
     v37 = &pParty->pPartyBuffs[2];
-LABEL_115:
     v36 = pParty->uTimePlayed + v39;
-LABEL_116:
-    v37->Apply(v36, v46, v48, v50, v52);
+    v37->Apply(v36, a7b, v43, 0, 0);
     goto LABEL_139;
   }
   if ( spellnum != 58 )
@@ -13787,22 +13792,69 @@
       case 41:
         a1.stru_24.Reset();
         v16 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
-          goto LABEL_34;
+        {
+          v18 = 0;
+          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;
+          v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+          a1.Create(v20, pitch, v49, 0);
+          goto LABEL_139;
+        }
         v17 = (char *)&pObjectList->pObjects->uObjectID;
         while ( (short)a1.uType != *(short *)v17 )
         {
           ++v16;
           v17 += 56;
           if ( v16 >= (signed int)pObjectList->uNumObjects )
-            goto LABEL_34;
-        }
-LABEL_20:
+          {
+            v18 = 0;
+            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;
+            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+            a1.Create(v20, pitch, v49, 0);
+            goto LABEL_139;
+          }
+        }
         v18 = v16;
-        goto LABEL_35;
+        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;
+        v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+        a1.Create(v20, pitch, v49, 0);
+        goto LABEL_139;
       case 24:
         switch ( v15 )
         {
@@ -13825,12 +13877,11 @@
           a8b = a7c / (v60 - 1);
           a1.stru_24.Reset();
           v21 = 0;
-          a1.field_48 = spellnum;
-          a1.field_4C = level;
-          a1.field_50 = v15;
+          a1.spell_id = spellnum;
+          a1.spell_level = uSkill;
+          a1.spell_skill = v15;
           if ( (signed int)pObjectList->uNumObjects <= 0 )
           {
-LABEL_41:
             v23 = 0;
           }
           else
@@ -13841,7 +13892,25 @@
               ++v21;
               v22 += 56;
               if ( v21 >= (signed int)pObjectList->uNumObjects )
-                goto LABEL_41;
+              {
+                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);
+                }
+                goto LABEL_139;
+              }
             }
             v23 = v21;
           }
@@ -13852,39 +13921,71 @@
           a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
           a1.field_60_distance_related_prolly_lod = v55;
           a1.uSpriteFrameID = 0;
-          a1.field_58_pid = 8000 | OBJECT_Item;
-          a1.field_5C = 4;
+          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);
+            a1.Create((signed __int16)(i + (short)yaw), pitch, pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed, 0);
           }
           goto LABEL_139;
         }
         a1.stru_24.Reset();
         v16 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
-          goto LABEL_34;
+       {
+         v18 = 0;
+         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;
+         v51 = 0;
+         v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+         v47 = pitch;
+         a1.Create(v20, v47, v49, v51);
+         goto LABEL_139;
+       }
         v19 = (char *)&pObjectList->pObjects->uObjectID;
         do
         {
           if ( (short)a1.uType == *(short *)v19 )
-            goto LABEL_20;
+          {
+            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;
+            v51 = 0;
+            v49 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+            v47 = pitch;
+            a1.Create(v20, v47, v49, v51);
+            goto LABEL_139;
+          }
           ++v16;
           v19 += 56;
         }
         while ( v16 < (signed int)pObjectList->uNumObjects );
-LABEL_34:
         v18 = 0;
-LABEL_35:
         a1.uObjectDescID = v18;
         *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
         a1.vPosition.x = fromx;
@@ -13893,14 +13994,15 @@
         a1.field_60_distance_related_prolly_lod = v55;
         v20 = yaw;
         a1.uSpriteFrameID = 0;
-        a1.field_58_pid = 8000 | OBJECT_Item;
-        a1.field_5C = 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;
-        goto LABEL_36;
+        a1.Create(v20, v47, v49, v51);
+        goto LABEL_139;
       case 15:
         switch ( v15 )
         {
@@ -13921,11 +14023,29 @@
         a8c = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v60 - 1);
         a1.stru_24.Reset();
         v25 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
-          goto LABEL_59;
+        {
+          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);
+          }
+          goto LABEL_139;
+        }
         v26 = (char *)&pObjectList->pObjects->uObjectID;
         while ( (short)a1.uType != *(short *)v26 )
         {
@@ -13933,13 +14053,26 @@
           v26 += 56;
           if ( v25 >= (signed int)pObjectList->uNumObjects )
           {
-LABEL_59:
             v27 = 0;
-            goto LABEL_60;
+            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);
+            }
+            goto LABEL_139;
           }
         }
         v27 = v25;
-LABEL_60:
         a1.uObjectDescID = v27;
         *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
         a1.vPosition.x = fromx;
@@ -13947,8 +14080,8 @@
         a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
         a1.field_60_distance_related_prolly_lod = v55;
         a1.uSpriteFrameID = 0;
-        a1.field_58_pid = 8000 | OBJECT_Item;
-        a1.field_5C = 4;
+        a1.spell_caster_pid = 8000 | OBJECT_Item;
+        a1.spell_target_pid = 4;
         a1.uSoundID = 0;
         for ( j = a7d / -2; j <= a7d / 2; j += a8c )
         {
@@ -13965,11 +14098,29 @@
           return;
         a1.stru_24.Reset();
         v29 = 0;
-        a1.field_48 = spellnum;
-        a1.field_4C = level;
-        a1.field_50 = v15;
+        a1.spell_id = spellnum;
+        a1.spell_level = uSkill;
+        a1.spell_skill = v15;
         if ( (signed int)pObjectList->uNumObjects <= 0 )
-          goto LABEL_70;
+        {
+          v31 = 0;
+          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(v20, v47, v49, v51);
+          goto LABEL_139;
+        }
         v30 = (char *)&pObjectList->pObjects->uObjectID;
         break;
 
@@ -13978,18 +14129,18 @@
         {
           if ( v15 <= 2 )
           {
-            v9 = 60 * (level + 60);
+            v9 = 60 * (uSkill + 60);
           }
           else
           {
             if ( v15 == 3 )
             {
-              v9 = 180 * (level + 20);
+              v9 = 180 * (uSkill + 20);
             }
             else
             {
               if ( v15 == 4 )
-                v9 = 240 * (level + 15);
+                v9 = 240 * (uSkill + 15);
             }
           }
         }
@@ -14020,29 +14171,29 @@
         {
           case 1:
           case 2:
-            v9 = 300 * (level + 12);
+            v9 = 300 * (uSkill + 12);
             break;
           case 3:
-            v9 = 900 * (level + 4);
+            v9 = 900 * (uSkill + 4);
             break;
           case 4:
-            v9 = 3600 * (level + 1);
+            v9 = 3600 * (uSkill + 1);
             break;
         }
         switch ( spellnum )
         {
           case 17:
             v60 = 0;
-            level = 14;
+            uSkill = 14;
             break;
           case 38:
-            v35 = level + 5;
-            level = 15;
+            v35 = uSkill + 5;
+            uSkill = 15;
             v60 = v35;
             break;
           case 51:
-            v34 = level + 5;
-            level = 9;
+            v34 = uSkill + 5;
+            uSkill = 9;
             v60 = v34;
             break;
         }
@@ -14055,24 +14206,27 @@
         v48 = v60;
         v46 = v15;
         v36 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(v9 << 7) * 0.033333335);
-        v37 = &pParty->pPartyBuffs[level];
-        goto LABEL_116;
+        v37 = &pParty->pPartyBuffs[uSkill];
+        v37->Apply(v36, v46, v48, v50, v52);
+        goto LABEL_139;;
       case 8:
         if ( v15 == 2 || v15 == 3 || v15 != 4 )
-          v38 = 60 * level;
+          v38 = 60 * uSkill;
         else
-          v38 = 600 * level;
+          v38 = 600 * uSkill;
         pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 0);
         pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
         pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
         pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
         v52 = 0;
         v50 = 0;
-        v48 = level;
+        v48 = uSkill;
         v46 = v15;
         v39 = (signed __int64)((double)(v38 << 7) * 0.033333335);
         v37 = &pParty->pPartyBuffs[10];
-        goto LABEL_115;
+        v36 = pParty->uTimePlayed + v39;
+        v37->Apply(v36, v46, v48, v50, v52);
+        goto LABEL_139;
       case 3:
       case 14:
       case 25:
@@ -14087,13 +14241,26 @@
       v30 += 56;
       if ( v29 >= (signed int)pObjectList->uNumObjects )
       {
-LABEL_70:
         v31 = 0;
-        goto LABEL_71;
+        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(v20, v47, v49, v51);
+        goto LABEL_139;
       }
     }
     v31 = v29;
-LABEL_71:
     a1.uObjectDescID = v31;
     *(_QWORD *)&a1.vPosition.y = __PAIR__(fromz, fromy);
     a1.vPosition.x = fromx;
@@ -14101,61 +14268,62 @@
     a1.uSectorID = pIndoor->GetSector(fromx, fromy, fromz);
     a1.field_60_distance_related_prolly_lod = v55;
     a1.uSpriteFrameID = 0;
-    a1.field_58_pid = 8000 | OBJECT_Item;
-    a1.field_5C = 4;
+    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;
-LABEL_36:
     a1.Create(v20, v47, v49, v51);
     goto LABEL_139;
   }
 LABEL_117:
-  v44 = level;
-  a6_4 = 3600 * level;
+  v44 = uSkill;
+  a6_4 = 3600 * uSkill;
   if ( v15 == 1 )
   {
-LABEL_124:
     v60 = v44;
     goto LABEL_125;
   }
   if ( v15 == 2 )
   {
-    v44 = 2 * level;
-    goto LABEL_124;
+    v44 = 2 * uSkill;
+    v60 = v44;
+    goto LABEL_125;
   }
   if ( v15 == 3 )
   {
-    v44 = 3 * level;
-    goto LABEL_124;
+    v44 = 3 * uSkill;
+    v60 = v44;
+    goto LABEL_125;
   }
   if ( v15 == 4 )
   {
-    v44 = 4 * level;
-    goto LABEL_124;
+    v44 = 4 * uSkill;
+    v60 = v44;
+    goto LABEL_125;
   }
 LABEL_125:
   switch ( spellnum )
   {
     case 3:
-      level = 6;
+      uSkill = 6;
       break;
     case 14:
-      level = 0;
+      uSkill = 0;
       break;
     case 25:
-      level = 17;
+      uSkill = 17;
       break;
     case 36:
-      level = 4;
+      uSkill = 4;
       break;
     case 58:
-      level = 12;
+      uSkill = 12;
       break;
     case 69:
-      level = 1;
+      uSkill = 1;
       break;
   }
   //v45 = spellnum_;
@@ -14163,12 +14331,7 @@
   pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 1);
   pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 2);
   pGame->pStru6Instance->SetPlayerBuffAnim(spellnum, 3);
-  pParty->pPartyBuffs[level].Apply(
-    pParty->uTimePlayed + (signed int)(signed __int64)((double)a6_4 * 4.2666669),
-    v15,
-    v60,
-    0,
-    0);
+  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 )
--- a/mm7_4.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_4.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -6,7 +6,6 @@
 #include "MapInfo.h"
 #include "Game.h"
 #include "GUIWindow.h"
-#include "GUIButton.h"
 #include "GUIFont.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -236,12 +235,12 @@
   signed int v28; // eax@45
   int v29; // ebx@47
   int v30; // edx@49
-  int v31; // ST10_4@49
-  signed int v32; // edx@49
+  //int v31; // ST10_4@49
+  //signed int v32; // edx@49
   signed __int64 v33; // qtt@49
-  signed int v34; // eax@54
-  signed int v35; // esi@56
-  int result; // eax@57
+  //signed int v34; // eax@54
+  //signed int v35; // esi@56
+  //int result; // eax@57
   int v38; // edx@62
   //int v44; // [sp+20h] [bp-20h]@10
   bool v47; // [sp+24h] [bp-1Ch]@43
@@ -343,6 +342,9 @@
       if (portal->uPolygonType != POLYGON_Floor)
         continue;
 
+      if (!portal->uNumVertices)
+        continue;
+
       if (x <= portal->pBounding.x2 && x >= portal->pBounding.x1 &&
           y <= portal->pBounding.y2 && y >= portal->pBounding.y1 )
       {
@@ -356,45 +358,40 @@
         word_721460_xs[2 * portal->uNumVertices] = word_721460_xs[0];
         word_721390_ys[2 * portal->uNumVertices] = word_721390_ys[0];
         v54 = 0;
-        v49 = word_721390_ys[0] >= y;
-        if ( portal->uNumVertices > 0 )
-        {
-          for ( int i = 0; i < 2 * portal->uNumVertices; ++i )
+        v47 = word_721390_ys[0] >= y;
+
+          for (uint j = 0; j < 2 * portal->uNumVertices; ++j)
           {
+            v49 = v47;
             if ( v54 >= 2 )
               break;
-            v47 = word_721390_ys[i + 1] >= y;
+            v47 = word_721390_ys[j + 1] >= y;
             if ( v49 != v47 )
             {
-              v28 = word_721460_xs[i + 1] >= x ? 0 : 2;
-              v29 = v28 | word_721460_xs[i] < x;
+              v28 = word_721460_xs[j + 1] >= x ? 0 : 2;
+              v29 = v28 | (word_721460_xs[j] < x);
               if ( v29 != 3 )
               {
                 if ( !v29 )
                   ++v54;
                 else
                 {
-                  //v30 = word_721390_ys[v27];
-                  v31 = word_721390_ys[i + 1] - word_721390_ys[i];
-                  v32 = y - word_721390_ys[i];
-                  LODWORD(v33) = v32 << 16;
-                  HIDWORD(v33) = v32 >> 16;
-                  if ((signed int)(((unsigned __int64)(((signed int)word_721460_xs[i + 1] - (signed int)word_721460_xs[i]) * v33 / v31) >> 16) + word_721460_xs[i]) >= x)
+                  auto a_div_b = fixpoint_div(y - word_721390_ys[j], word_721390_ys[j + 1] - word_721390_ys[j]);
+                  auto res = fixpoint_mul(word_721460_xs[j + 1] - word_721460_xs[j], a_div_b);
+                  if (res + word_721460_xs[j] >= x)
                     ++v54;
                 }
               }
             }
-            v49 = v47;
           }
           if ( v54 == 1 )
           {
             if ( v55 >= 50 )
               break;
-            v34 = v55++;
-            blv_floor_level[v34] = -29000;
-            blv_floor_id[v34] = pSector->pPortals[i];
+            blv_floor_level[v55] = -29000;
+            blv_floor_id[v55] = pSector->pPortals[i];
+            v55++;
           }
-        }
       }
     }
   }
@@ -407,9 +404,8 @@
     return -30000;
   *pFaceID = blv_floor_id[0];
   //result = blv_floor_level[0];
-  if ( v55 > 1 )
-  {
-    for ( v35 = 1; v35 < v55; ++v35 )
+
+    /*for ( v35 = 1; v35 < v55; ++v35 )
     {
       if ( blv_floor_level[0] <= z + 5 )
       {
@@ -424,9 +420,29 @@
         blv_floor_level[0] = blv_floor_level[v35];
         *pFaceID = blv_floor_id[v35];
       }
-    }
-  }
-  return blv_floor_level[0];
+    }*/
+
+    
+  int result = blv_floor_level[0];
+  for (uint i = 1; i < v55; ++i)
+  {
+      v38 = blv_floor_level[i];
+      if ( result <= z + 5 )
+      {
+        if ( v38 > result && v38 <= z + 5 )
+        {
+          result = blv_floor_level[i];
+          *pFaceID = blv_floor_id[i];
+        }
+      }
+      else if ( v38 < result )
+      {
+        result = blv_floor_level[i];
+        *pFaceID = blv_floor_id[i];
+      }
+  }
+
+  return result;
 }
 
 //----- (0046D49E) --------------------------------------------------------
@@ -2074,11 +2090,11 @@
       a3.y = 0;
       a3.x = 0;
       a1.stru_24.Reset();
-      a1.field_4C = pParty->pPartyBuffs[10].uPower;
-      a1.field_50 = pParty->ImmolationSkillLevel();
+      a1.spell_level = pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].uPower;
+      a1.spell_skill = pParty->ImmolationSkillLevel();
       v10 = 0;
       a1.uType = 1070;
-      a1.field_48 = 8;
+      a1.spell_id = SPELL_FIRE_IMMOLATION;
       if ( (signed int)pObjectList->uNumObjects <= 0 )
       {
 LABEL_19:
@@ -2102,7 +2118,7 @@
       a1.uAttributes = 0;
       a1.uSectorID = 0;
       a1.uSpriteFrameID = 0;
-      a1.field_58_pid = v12;
+      a1.spell_caster_pid = v12;
       a1.uFacing = 0;
       a1.uSoundID = 0;
       v13 = sub_46A89E((int)v41, 100, 307);
@@ -2119,7 +2135,7 @@
           v18 = 8 * v15;
           LOBYTE(v18) = 8 * v15 | 3;
           a1.vPosition.y = v17;
-          a1.field_5C = v18;
+          a1.spell_target_pid = v18;
           v19 = a1.Create(0, 0, 0, 0);
           DamageMonsterFromParty(8 * v19 | 2, *v14, &a3);
           ++v9;
@@ -6472,7 +6488,7 @@
   contract_approved = 0;
   v11 = 0;
   uDialogueType = 84;
-  ptr_F8B1E8 = (char *)pNPCTopics[667].pText;
+  current_npc_text = (char *)pNPCTopics[667].pText;
   v0 = _4F0882_evt_VAR_PlayerItemInHands_vals;
   while ( 1 )
   {
@@ -6499,7 +6515,7 @@
   }
   if ( v0 <= &_4F0882_evt_VAR_PlayerItemInHands_vals[53] )
   {
-	  ptr_F8B1E8 = (char *)pNPCTopics[666].pText; // Here's %s that you lost. Be careful
+	  current_npc_text = (char *)pNPCTopics[666].pText; // Here's %s that you lost. Be careful
 	  v4 = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
 	  contract_approved = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
 	  pParty->pPlayers[0].AddVariable(VAR_PlayerItemInHands, v4);
@@ -6587,8 +6603,8 @@
   switch ( uMessageParam )
   {
     case 13:
-      ptr_F8B1E8 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;//(char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
-      ptr_F8B1E8 = BuilDialogueString((char *)ptr_F8B1E8, uActiveCharacter - 1, 0, 0, 0, 0);
+      current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;//(char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
+      current_npc_text = BuilDialogueString((char *)current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
       NPCHireableDialogPrepare();
       dialogue_show_profession_details = false;
       goto _return;
@@ -6638,7 +6654,7 @@
           }
           else
           {
-            ptr_F8B1E8 = 0;
+            current_npc_text = 0;
             activeLevelDecoration = (LevelDecoration*)1;
             EventProcessor(pEventNumber, 0, 1);
             activeLevelDecoration = NULL;
@@ -6666,10 +6682,10 @@
         v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pJoinText;
       else
         v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pBenefits;
-      ptr_F8B1E8 = v17;
+      current_npc_text = v17;
       v18 = BuilDialogueString(v17, uActiveCharacter - 1, 0, 0, 0, 0);
       dialogue_show_profession_details = ~dialogue_show_profession_details;
-      ptr_F8B1E8 = v18;
+      current_npc_text = v18;
     }
     else
     {
@@ -6786,8 +6802,8 @@
       ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
       dialogue_show_profession_details = false;
       uDialogueType = 13;
-      ptr_F8B1E8 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pJoinText;
-      ptr_F8B1E8 = BuilDialogueString((char *)ptr_F8B1E8, uActiveCharacter - 1, 0, 0, 0, 0);
+      current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession - 1].pJoinText;
+      current_npc_text = BuilDialogueString((char *)current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
       if ( uActiveCharacter )
         pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
       ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
@@ -7324,7 +7340,7 @@
     while ( 1 )
     {
       v16 = v52.GetControl(v56);
-      v17 = v16->uControlParam;
+      v17 = v16->msg_param;
       pInString = (char *)v16;
       if ( (signed int)v17 > 24 )
       {
@@ -7365,7 +7381,7 @@
           v32 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
           sprintf(pTmpBuf, &byte_4F0F98, v32, v31, v30);
           sprintf(pTmpBuf2, dword_F8B1A4, pTmpBuf, 100 * (unsigned __int8)v29[8]);
-          ptr_F8B1E8 = pTmpBuf2;
+          current_npc_text = pTmpBuf2;
           v15 = "";
           goto LABEL_45;
         }
@@ -7381,7 +7397,7 @@
           v15 = (char *)pNPCTopics[v23-1].pTopic;//(&dword_721660)[8 * v23];
           if ( !v15 )
           {
-            v16->uControlParam = 0;
+            v16->msg_param = 0;
             v15 = "";
           }
           goto LABEL_49;
@@ -7401,14 +7417,14 @@
             v15 = (char *)pNPCTopics[v58->evt_B-1].pTopic;//(&dword_721660)[8 * v58->evtb];
             if ( !v15 )
             {
-              v16->uControlParam = 0;
+              v16->msg_param = 0;
               v15 = "";
             }
             if ( uDialogueType != 84 )
               goto LABEL_49;
             sprintf(pTmpBuf, format_4E2D80, v55, pItemsTable->pItems[contract_approved].pUnidentifiedName);
-            sprintf(pTmpBuf2, ptr_F8B1E8, pTmpBuf);
-            ptr_F8B1E8 = pTmpBuf2;
+            sprintf(pTmpBuf2, current_npc_text, pTmpBuf);
+            current_npc_text = pTmpBuf2;
             goto LABEL_45;
           }
           v21 = v20 - 1;
@@ -7495,16 +7511,16 @@
       }
     }
   }
-  if ( ptr_F8B1E8 )
+  if ( current_npc_text )
   {
     w.uFrameWidth = 458;
     w.uFrameZ = 457;
     v47 = pFontArrus;
-    v48 = pFontArrus->CalcTextHeight(ptr_F8B1E8, &w, 13, 0) + 7;
+    v48 = pFontArrus->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
     if ( 352 - v48 < 8 )
     {
       v47 = pFontCreate;
-      v48 = pFontCreate->CalcTextHeight(ptr_F8B1E8, &w, 13, 0) + 7;
+      v48 = pFontCreate->CalcTextHeight(current_npc_text, &w, 13, 0) + 7;
     }
     pRenderer->_4A6A68(
       8u,
@@ -7512,7 +7528,7 @@
       (Texture *)(uTextureID_Leather != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_Leather] : 0),
       (uTextureID_Leather != -1 ? pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight : 26) - v48);
     pRenderer->DrawTextureIndexed(8u, 347 - v48, pTexture_591428);
-    v49 = FitTextInAWindow(ptr_F8B1E8, v47, &w, 0xDu, 0);
+    v49 = FitTextInAWindow(current_npc_text, v47, &w, 0xDu, 0);
     a1.DrawText(v47, 13, 354 - v48, 0, v49, 0, 0, 0);
   }
 }
@@ -7520,7 +7536,7 @@
 //----- (004B36CC) --------------------------------------------------------
 void CreateButtonInColumn( int column_pos, unsigned int control_id )
 {
-     pDialogueWindow->CreateButton( 480, 30 * column_pos + 146, 140, 30,  1,  0, 0x195u,  control_id,  0,   "",   0);
+     pDialogueWindow->CreateButton( 480, 30 * column_pos + 146, 140, 30,  1,  0, UIMSG_SelectShopDialogueOption,  control_id,  0,   "",   0);
 }
 
 //----- (004B3A72) --------------------------------------------------------
@@ -7781,10 +7797,10 @@
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Dialogue, 1, 0);
   if ( pNPCStats->pProfessions[v0->uProfession].pBenefits)//*(&pNPCStats->field_13A5C + 5 * v0->uProfession) )
   {
-    pDialogueWindow->CreateButton(480, 160, 140, 28, 1, 0, 136, 77, 0, pGlobalTXT_LocalizationStrings[407], 0);
+    pDialogueWindow->CreateButton(480, 160, 140, 28, 1, 0, UIMSG_SelectNPCDialogueOption, 77, 0, pGlobalTXT_LocalizationStrings[407], 0);
     v1 = 1;
   }
-  pDialogueWindow->CreateButton(480, 30 * v1 + 160, 140, 30, 1, 0, 136, 76, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
+  pDialogueWindow->CreateButton(480, 30 * v1 + 160, 140, 30, 1, 0, UIMSG_SelectNPCDialogueOption, 76, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
   pDialogueWindow->_41D08F(v1 + 1, 1, 0, 1);
 }
 
@@ -7792,14 +7808,14 @@
 void DrawJoinGuildWindow( int pEventCode )
 {
   uDialogueType = 81;//enum JoinGuildDialog
-  ptr_F8B1E8 = (char *)pNPCTopics[pEventCode + 99].pText;
+  current_npc_text = (char *)pNPCTopics[pEventCode + 99].pText;
   ContractSelectText(pEventCode);
   pDialogueWindow->Release();
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x15E, WINDOW_MainMenu, pEventCode, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton(0x1D7, 0x1BD, 0xA9, 0x23, 1, 0, 0x71, 0, 0, pGlobalTXT_LocalizationStrings[34],
-                 (Texture *)(uExitCancelTextureId != -1 ? &pIcons_LOD->pTextures[uExitCancelTextureId] : 0), 0);
-  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, 0x51u, 0, 0, "", 0);
-  pDialogueWindow->CreateButton(0x1E0u, 0xA0u, 0x8Cu, 0x1Eu, 1, 0, 0xAFu, 0x52u, 0, pGlobalTXT_LocalizationStrings[122], 0);
+  pBtn_ExitCancel = pDialogueWindow->CreateButton(0x1D7, 0x1BD, 0xA9, 0x23, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[34], // Cancel
+                 pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
+  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
+  pDialogueWindow->CreateButton(0x1E0u, 0xA0u, 0x8Cu, 0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x52u, 0, pGlobalTXT_LocalizationStrings[122], 0);
   pDialogueWindow->_41D08F(1, 1, 0, 2);
   dialog_menu_id = HOUSE_DIALOGUE_OTHER;
 }
@@ -7813,19 +7829,19 @@
 
   v1 = a4;
   uDialogueType = 78;
-  ptr_F8B1E8 = (char *)pNPCTopics[a4 + 168].pText;
+  current_npc_text = (char *)pNPCTopics[a4 + 168].pText;
   _4B254D_SkillMasteryTeacher(a4);
   pDialogueWindow->Release();
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x15Eu, WINDOW_MainMenu, v1, 0);
   v2 = "";
-  pBtn_ExitCancel = pDialogueWindow->CreateButton( 0x1D7u, 0x1BDu, 0xA9u,  0x23u,   1,  0, 0x71u, 0,   0,
+  pBtn_ExitCancel = pDialogueWindow->CreateButton( 0x1D7u, 0x1BDu, 0xA9u,  0x23u,   1,  0, UIMSG_Escape, 0,   0,
                  pGlobalTXT_LocalizationStrings[34],
                  (Texture *)(uExitCancelTextureId != -1 ? (int)&pIcons_LOD->pTextures[uExitCancelTextureId] : 0),
                  0);
-  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, 0x51u, 0, 0, "", 0);
+  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
   if ( contract_approved )
     v2 = pGlobalTXT_LocalizationStrings[535];
-  pDialogueWindow->CreateButton(0x1E0u, 0xA0u, 0x8Cu, 0x1Eu, 1, 0, 0xAFu, 0x4Fu, 0, v2, 0);
+  pDialogueWindow->CreateButton(0x1E0u, 0xA0u, 0x8Cu, 0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x4Fu, 0, v2, 0);
   pDialogueWindow->_41D08F(1, 1, 0, 2);
   dialog_menu_id = HOUSE_DIALOGUE_OTHER;
 }
@@ -7842,18 +7858,18 @@
   v1 = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) - 1)];
   pDialogueWindow->Release();
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x15Eu, WINDOW_MainMenu, 0, 0);
-  pBtn_ExitCancel = pDialogueWindow->CreateButton( 0x1D7u, 0x1BDu,  0xA9u,   0x23u,  1,  0,  0x71u,  0,   0,
+  pBtn_ExitCancel = pDialogueWindow->CreateButton( 0x1D7u, 0x1BDu,  0xA9u,   0x23u,  1,  0,  UIMSG_Escape,  0,   0,
                  pGlobalTXT_LocalizationStrings[34], //"Cancel"
                  (Texture *)(uExitCancelTextureId != -1 ? (int)&pIcons_LOD->pTextures[uExitCancelTextureId] : 0),
                  0);
-  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, 0x51u, 0, 0, "", 0);
+  pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
   if ( pNPCStats->pProfessions[v1->uProfession].pBenefits)//*(&pNPCStats->field_13A5C + 5 * v1->uProfession) )
   {
-    pDialogueWindow->CreateButton( 0x1E0u,  0xA0u,  0x8Cu,  0x1Eu,   1,  0,  0xAFu,  0x4Du,   0,
+    pDialogueWindow->CreateButton( 0x1E0u,  0xA0u,  0x8Cu,  0x1Eu,   1,  0,  UIMSG_ClickNPCTopic,  0x4Du,   0,
       pGlobalTXT_LocalizationStrings[407], 0);//"More Information"   
     v0 = 1;
   }
-  pDialogueWindow->CreateButton(  0x1E0u,  30 * v0 + 160,  0x8Cu,  0x1Eu,  1,  0,  0xAFu,  0x4Cu,  0,
+  pDialogueWindow->CreateButton(  0x1E0u,  30 * v0 + 160,  0x8Cu,  0x1Eu,  1,  0,  UIMSG_ClickNPCTopic,  0x4Cu,  0,
     pGlobalTXT_LocalizationStrings[406],  0); //"Hire"
   pDialogueWindow->_41D08F(v0 + 1, 1, 0, 2);
   dialog_menu_id = HOUSE_DIALOGUE_OTHER;
@@ -7880,14 +7896,14 @@
     pDialogueWindow->Release();
     pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_MainMenu, 0, 0);
     sprintfex(sHouseName, pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S], pMapStats->pInfos[uHouse_ExitPic].pName);
-    pBtn_ExitCancel = pDialogueWindow->CreateButton( 566, 445, 75, 33, 1, 0, 0x71u, 0, 0x4Eu,
+    pBtn_ExitCancel = pDialogueWindow->CreateButton( 566, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0x4Eu,
                    pGlobalTXT_LocalizationStrings[34],// "Cancel"
                    (Texture *)(uTextureID_BUTTDESC2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTDESC2] : 0),0);
-    pBtn_YES = pDialogueWindow->CreateButton( 486u, 445u,  75u, 33u, 1, 0,  0xBFu,  1u,  0x59u,
+    pBtn_YES = pDialogueWindow->CreateButton( 486u, 445u,  75u, 33u, 1, 0,  UIMSG_BF,  1u,  0x59u,
                    sHouseName,
                    (Texture *)(uTextureID_BUTTYES2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTYES2] : 0), 0);
-    pDialogueWindow->CreateButton( pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 63u, 73u, 1, 0,  0xBFu, 1u, 0x20u,  sHouseName, 0);
-    pDialogueWindow->CreateButton(8u, 8u, 460u, 344u, 1, 0, 0xBFu, 1u, 0x59u, sHouseName, 0);
+    pDialogueWindow->CreateButton( pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 63u, 73u, 1, 0,  UIMSG_BF, 1u, 0x20u,  sHouseName, 0);
+    pDialogueWindow->CreateButton(8u, 8u, 460u, 344u, 1, 0, UIMSG_BF, 1u, 0x59u, sHouseName, 0);
   }
   else
   {
@@ -7902,10 +7918,10 @@
         ((GUIButton *)HouseNPCData[i + 7])->Release();
     }
     pDialogueWindow = GUIWindow::Create(0, 0, 640, 0x159u, WINDOW_MainMenu, 0, 0);
-    pBtn_ExitCancel = pDialogueWindow->CreateButton(  471u,  445u,  169u, 35u,  1,   0, 0x71u,  0,  0,
+    pBtn_ExitCancel = pDialogueWindow->CreateButton(  471u,  445u,  169u, 35u,  1,   0, UIMSG_Escape,  0,  0,
                    pGlobalTXT_LocalizationStrings[74],// "End Conversation"
                    (Texture *)(uExitCancelTextureId != -1 ? (int)&pIcons_LOD->pTextures[uExitCancelTextureId] : 0),   0);
-    pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, 0x51u, 0, 0, "", 0);
+    pDialogueWindow->CreateButton(8u, 8u, 0x1C2u, 0x140u, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
     if ( pDialogueNPCCount == 1 && dword_591080 )
     {
       sub_4B3B42(in_current_building_type);
@@ -7915,7 +7931,7 @@
       if ( v17->joins )
       {
         num_menu_buttons = 1;
-        pDialogueWindow->CreateButton(480u, 160u, 140u, 30u, 1, 0, 0xAFu, 0xDu, 0, "", 0);
+        pDialogueWindow->CreateButton(480u, 160u, 140u, 30u, 1, 0, UIMSG_ClickNPCTopic, 0xDu, 0, "", 0);
       }
       if ( v17->evt_A)
       {
@@ -7923,7 +7939,7 @@
         {
           v6 = NPC_EventProcessor(v17->evt_A);
           if ( v6 == 1 || v6 == 2 )
-            pDialogueWindow->CreateButton(  480u, 30 * num_menu_buttons++ + 160,  140u, 30u, 1, 0, 0xAFu, 0x13u,  0, "",  0);
+            pDialogueWindow->CreateButton(  480u, 30 * num_menu_buttons++ + 160,  140u, 30u, 1, 0, UIMSG_ClickNPCTopic, 0x13u,  0, "",  0);
         }
       }
       if ( v17->evt_B )
@@ -7932,7 +7948,7 @@
         {
           v8 = NPC_EventProcessor(v17->evt_B);
           if ( v8 == 1 || v8 == 2 )
-            pDialogueWindow->CreateButton( 480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1, 0,  0xAFu,  0x14u,  0, "",  0);
+            pDialogueWindow->CreateButton( 480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1, 0,  UIMSG_ClickNPCTopic,  0x14u,  0, "",  0);
         }
       }
       if ( v17->evt_C )
@@ -7941,7 +7957,7 @@
         {
           v10 = NPC_EventProcessor(v17->evt_C);
           if ( v10 == 1 || v10 == 2 )
-            pDialogueWindow->CreateButton(  480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1,  0, 0xAFu, 0x15u, 0, "",  0);
+            pDialogueWindow->CreateButton(  480u,  30 * num_menu_buttons++ + 160,  140u, 30u,  1,  0, UIMSG_ClickNPCTopic, 0x15u, 0, "",  0);
         }
       }
  
@@ -7951,7 +7967,7 @@
         {
           v12 = NPC_EventProcessor(v17->evt_D);
           if ( v12 == 1 || v12 == 2 )
-            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu, 0x1Eu, 1, 0, 0xAFu, 0x16u,  0, "",  0);
+            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu, 0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x16u,  0, "",  0);
         }
       }
       if ( v17->evt_E )
@@ -7960,7 +7976,7 @@
         {
           v14 = NPC_EventProcessor(v17->evt_E);
           if ( v14 == 1 || v14 == 2 )
-            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu,  1,  0,  0xAFu, 0x17u,  0, "",  0);
+            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu,  1,  0,  UIMSG_ClickNPCTopic, 0x17u,  0, "",  0);
         }
       }
       if ( v17->evt_F )
@@ -7969,7 +7985,7 @@
         {
           v16 = NPC_EventProcessor(v17->evt_F);
           if ( v16 == 1 || v16 == 2 )
-            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu, 1, 0, 0xAFu, 0x18u, 0, "",  0);
+            pDialogueWindow->CreateButton( 0x1E0u, 30 * num_menu_buttons++ + 160,  0x8Cu,  0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x18u, 0, "",  0);
         }
       }
       pDialogueWindow->_41D08F(num_menu_buttons, 1, 0, 2);
@@ -8214,7 +8230,7 @@
 					break;
 				default:
 					activeLevelDecoration = (LevelDecoration*)1;
-					ptr_F8B1E8 = 0;
+					current_npc_text = 0;
 					EventProcessor(npc_event_id, 0, 1);
 					activeLevelDecoration = NULL;
 					break;
@@ -8464,7 +8480,7 @@
     goto LABEL_40;
   do
   {
-    v11 = v8->GetControl(v35)->uControlParam - 36;
+    v11 = v8->GetControl(v35)->msg_param - 36;
     if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType / 3][v11] && !v1->pActiveSkills[v11] )
     {
       v12 = pFontArrus->CalcTextHeight(pSkillNames[v11], &v28, 0, 0);
@@ -8500,7 +8516,7 @@
     do
     {
       v14 = v8->GetControl(v35);
-      v15 = v14->uControlParam - 36;
+      v15 = v14->msg_param - 36;
       if ( byte_4ED970_skill_learn_ability_by_class_table[v1->classType / 3][v15] )
       {
         v16 = 0;
--- a/mm7_5.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_5.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -5,7 +5,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -554,54 +553,56 @@
           uTextureID_ControlBG[22] = pIcons_LOD->LoadTexture("option02", TEXTURE_16BIT_PALETTE);
           uTextureID_ControlBG[21] = pIcons_LOD->LoadTexture("option01", TEXTURE_16BIT_PALETTE);
           pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_Options, 0, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0x16u, 0x10Eu,
-            (uTextureID_ControlBG[3] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[3]].uTextureWidth : 24),
-            (uTextureID_ControlBG[3] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[3]].uTextureHeight : 26),
-            v0, 0, 0xB8u, 0x80u, 0, v1, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0x5Du, 0x10Eu,
-            (uTextureID_ControlBG[2] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[2]].uTextureWidth : 24),
-            (uTextureID_ControlBG[2] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[2]].uTextureHeight : 26),
-            v0, 0, 0xB8u, 0x40u, 0, v1, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0xA4u, 0x10Eu,
-            (uTextureID_ControlBG[1] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[1]].uTextureWidth : 24),
-            (uTextureID_ControlBG[1] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[1]].uTextureHeight : 26),
-            v0, 0, 0xB8u, 0, 0, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(22, 270,
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[3])->uTextureWidth,
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[3])->uTextureHeight,
+                                               v0, 0,
+                                               UIMSG_SetTurnSpeed, 0x80,
+                                               0, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(0x5Du, 270,
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[2])->uTextureWidth,
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[2])->uTextureHeight,
+                                               v0, 0, UIMSG_SetTurnSpeed, 0x40u, 0, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(0xA4u, 270,
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[1])->uTextureWidth,
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[1])->uTextureHeight,
+                                               v0, 0, UIMSG_SetTurnSpeed, 0, 0, v1, 0);
           pGUIWindow_CurrentMenu->CreateButton(0x14u, 0x12Fu,
-            (uTextureID_ControlBG[21] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[21]].uTextureWidth : 24),
-            (uTextureID_ControlBG[21] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[21]].uTextureHeight : 26),
-            v0, 0, 0xB9u, 0, 0, v1, 0);
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[21])->uTextureWidth,
+                                               pIcons_LOD->GetTexture(uTextureID_ControlBG[21])->uTextureHeight,
+                                               v0, 0, UIMSG_ToggleWalkSound, 0, 0, v1, 0);
           pGUIWindow_CurrentMenu->CreateButton(0x80u, 0x12Fu,
             (uTextureID_ControlBG[22] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[22]].uTextureWidth : 24),
             (uTextureID_ControlBG[22] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[22]].uTextureHeight : 26),
-            v0, 0, 0xBBu, 0, 0, v1, 0);
+            v0, 0, UIMSG_ToggleShowDamage, 0, 0, v1, 0);
           pGUIWindow_CurrentMenu->CreateButton(0x14u, 0x145u,
             (uTextureID_ControlBG[20] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[20]].uTextureWidth : 24),
             (uTextureID_ControlBG[20] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[20]].uTextureHeight : 26),
-            v0, 0, 0xE1u, 0, 0, v1, 0);
+            v0, 0, UIMSG_ToggleAlwaysRun, 0, 0, v1, 0);
           pGUIWindow_CurrentMenu->CreateButton(0x80u, 0x145u,
             (uTextureID_ControlBG[9] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[9]].uTextureWidth : 24),
             (uTextureID_ControlBG[9] != -1 ? pIcons_LOD->pTextures[uTextureID_ControlBG[9]].uTextureHeight : 26),
-            v0, 0, 0xE2u, 0, 0, v1, 0);
-          pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(243, 162, 16, 16, v0, 0, 111, 4, 0, v1,
+            v0, 0, UIMSG_ToggleFlipOnExit, 0, 0, v1, 0);
+          pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(243, 162, 16, 16, v0, 0, UIMSG_ChangeSoundVolume, 4, 0, v1,
                          &pIcons_LOD->pTextures[uTextureID_ControlBG[4]], 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0x1B3u, 0xA2u, 0x10u, 0x10u, v0, 0, 0x6Fu, 5, 0, v1,
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0x1B3u, 0xA2u, 0x10u, 0x10u, v0, 0, UIMSG_ChangeSoundVolume, 5, 0, v1,
                          &pIcons_LOD->pTextures[uTextureID_ControlBG[5]], 0);
-          pGUIWindow_CurrentMenu->CreateButton(0x107u, 0xA2u, 0xACu, 0x11u, v0, 0, 0x6Fu, 0, 0, v1, 0);
-          pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0xF3u, 0xD8u, 0x10u, 0x10u, v0, 0, 0x70u, 4, 0, v1,
+          pGUIWindow_CurrentMenu->CreateButton(0x107u, 0xA2u, 0xACu, 0x11u, v0, 0, UIMSG_ChangeSoundVolume, 0, 0, v1, 0);
+          pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0xF3u, 0xD8u, 0x10u, 0x10u, v0, 0, UIMSG_ChangeMusicVolume, 4, 0, v1,
                          &pIcons_LOD->pTextures[uTextureID_ControlBG[4]], 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0x1B3u, 0xD8u, 0x10u, 0x10u, v0, 0, 0x70u, 5, 0, v1,
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0x1B3u, 0xD8u, 0x10u, 0x10u, v0, 0, UIMSG_ChangeMusicVolume, 5, 0, v1,
                          &pIcons_LOD->pTextures[uTextureID_ControlBG[5]], 0);
-          pGUIWindow_CurrentMenu->CreateButton(0x107u, 0xD8u, 0xACu, 0x11u, v0, 0, 0x70u, 0, 0, v1, 0);
-          pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0xF3u, 0x10Eu, 0x10u, 0x10u, v0, 0, 0xBAu, 4, 0, v1,
+          pGUIWindow_CurrentMenu->CreateButton(0x107u, 0xD8u, 0xACu, 0x11u, v0, 0, UIMSG_ChangeMusicVolume, 0, 0, v1, 0);
+          pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0xF3u, 0x10Eu, 0x10u, 0x10u, v0, 0, UIMSG_ChangeVoiceVolume, 4, 0, v1,
                          &pIcons_LOD->pTextures[uTextureID_ControlBG[4]], 0);
-          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0x1B3u, 0x10Eu, 0x10u, 0x10u, v0, 0, 0xBAu, 5u, 0, v1,
+          pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0x1B3u, 0x10Eu, 0x10u, 0x10u, v0, 0, UIMSG_ChangeVoiceVolume, 5u, 0, v1,
                          &pIcons_LOD->pTextures[uTextureID_ControlBG[5]], 0);
-          pGUIWindow_CurrentMenu->CreateButton(0x107u, 0x10Eu, 0xACu, 0x11u, v0, 0, 0xBAu, 0, 0, v1, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, v0, 0, 0x71u, 0, 0,
+          pGUIWindow_CurrentMenu->CreateButton(0x107u, 0x10Eu, 0xACu, 0x11u, v0, 0, UIMSG_ChangeVoiceVolume, 0, 0, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, v0, 0, UIMSG_Escape, 0, 0,
             pGlobalTXT_LocalizationStrings[619],// "Return to Game"
             0);
-          pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x8Cu, 0xD6u, 0x28u, v0, 0, 0x19Fu, 0, 0x4Bu, v1, 0);
-          pGUIWindow_CurrentMenu->CreateButton(19, 194, 214, 40, v0, 0, 421, 0, 86, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x8Cu, 0xD6u, 0x28u, v0, 0, UIMSG_OpenKeyMappingOptions, 0, 0x4Bu, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(19, 194, 214, 40, v0, 0, UIMSG_OpenVideoOptions, 0, 86, v1, 0);
           continue;
         case UIMSG_OpenKeyMappingOptions://Open
           if ( pMessageQueue_50CBD0->uNumMessages )
@@ -615,25 +616,25 @@
           uTextureID_Optkb[3] = pIcons_LOD->LoadTexture("optkb_1", TEXTURE_16BIT_PALETTE);
           uTextureID_Optkb[4] = pIcons_LOD->LoadTexture("optkb_2", TEXTURE_16BIT_PALETTE);
           pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_KeyMappingOptions, 0, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, 1, 0, 0x71u, 0, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(19u, 0x12Eu, 0x6Cu, 0x14u, 1, 0, 0x1A0u, 0, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(127u, 0x12Eu, 0x6Cu, 0x14u, 1, 0, 0x1A1u, 0, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(127u, 0x144u, 0x6Cu, 0x14u, 1, 0, 0x1A2u, 0, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(19u, 0x144u, 0x6Cu, 0x14u, 1, 0, 0x7Fu, 0, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(129u, 0x94u, 0x46u, 0x13u, 1, 0, 0x1A3u, 0, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(129u, 0xA7u, 0x46u, 0x13u, 1, 0, 0x1A3u, 1u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(129u, 0xBAu, 0x46u, 0x13u, 1, 0, 0x1A3u, 2u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(129u, 0xCDu, 0x46u, 0x13u, 1, 0, 0x1A3u, 3u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(129u, 224u, 70u, 19u, 1, 0, 0x1A3u, 4u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(129u, 243u, 70u, 0x13u, 1, 0, 0x1A3u, 5u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(129u, 262u, 70u, 0x13u, 1, 0, 0x1A3u, 6u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(350u, 148u, 70u, 0x13u, 1, 0, 0x1A3u, 7u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(350u, 167u, 70u, 0x13u, 1, 0, 0x1A3u, 8u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(350u, 186u, 70u, 0x13u, 1, 0, 0x1A3u, 9u, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(350u, 205u, 70u, 0x13u, 1, 0, 0x1A3u, 0xAu, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(350u, 224u, 70u, 0x13u, 1, 0, 0x1A3u, 0xBu, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(350u, 243u, 70u, 0x13u, 1, 0, 0x1A3u, 0xCu, 0, "", 0);
-          pGUIWindow_CurrentMenu->CreateButton(350u, 262u, 70u, 0x13u, 1, 0, 0x1A3u, 0xDu, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, 1, 0, UIMSG_Escape, 0, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(19u, 0x12Eu, 0x6Cu, 0x14u, 1, 0, UIMSG_SelectKeyPage1, 0, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(127u, 0x12Eu, 0x6Cu, 0x14u, 1, 0, UIMSG_SelectKeyPage2, 0, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(127u, 0x144u, 0x6Cu, 0x14u, 1, 0, UIMSG_ResetKeyMapping, 0, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(19u, 0x144u, 0x6Cu, 0x14u, 1, 0, UIMSG_Game_OpenOptionsDialog, 0, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(129u, 0x94u, 0x46u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(129u, 0xA7u, 0x46u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 1u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(129u, 0xBAu, 0x46u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 2u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(129u, 0xCDu, 0x46u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 3u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(129u, 224u, 70u, 19u, 1, 0, UIMSG_ChangeKeyButton, 4u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(129u, 243u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 5u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(129u, 262u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 6u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(350u, 148u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 7u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(350u, 167u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 8u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(350u, 186u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 9u, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(350u, 205u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0xAu, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(350u, 224u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0xBu, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(350u, 243u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0xCu, 0, "", 0);
+          pGUIWindow_CurrentMenu->CreateButton(350u, 262u, 70u, 0x13u, 1, 0, UIMSG_ChangeKeyButton, 0xDu, 0, "", 0);
           dword_506E68 = -1;
           KeyboardPageNum = 1;
           memset(KeyButtonFlagChangesArray, 0, sizeof(KeyButtonFlagChangesArray));
@@ -716,23 +717,21 @@
           uTextureID_507C54 = pIcons_LOD->LoadTexture("opvdG-cl", TEXTURE_16BIT_PALETTE);
           uTextureID_507C58 = pIcons_LOD->LoadTexture("opvdG-tn", TEXTURE_16BIT_PALETTE);
           pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_VideoOptions, 0, 0);
-          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, v0, 0, 0x71u, 0, 0, v1, 0);
+          pGUIWindow_CurrentMenu->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, v0, 0, UIMSG_Escape, 0, 0, v1, 0);
           if ( pRenderer->pRenderD3D )
           {
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x118u, 0xD6u, 0x12u, v0, 0, 0x1A6u, 0, 0, v1, 0);
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x12Eu, 0xD6u, 0x12u, v0, 0, 0x1A7u, 0, 0, v1, 0);
-            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x144u, 0xD6u, 0x12u, v0, 0, 0x1A8u, 0, 0, v1, 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x118u, 0xD6u, 0x12u, v0, 0, UIMSG_ToggleBloodsplats, 0, 0, v1, 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x12Eu, 0xD6u, 0x12u, v0, 0, UIMSG_ToggleColoredLights, 0, 0, v1, 0);
+            pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x144u, 0xD6u, 0x12u, v0, 0, UIMSG_ToggleTint, 0, 0, v1, 0);
           }
           if ( !pRenderer->bWindowMode )
           {
             v0 = 1;
             if ( GammaController::IsGammaSupported() )
             {
-              pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0x15u, 0xA1u, 0x10u, 0x10u, 1, 0, 0x1A9u, 4u, 0, v1,
-                             &pIcons_LOD->pTextures[uTextureID_507C20], 0);
-              pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0xD5u, 0xA1u, 0x10u, 0x10u, 1, 0, 0x1A9u, 5u, 0, v1,
-                             &pIcons_LOD->pTextures[uTextureID_507C24], 0);
-              pGUIWindow_CurrentMenu->CreateButton(42, 162, 170, 18, 1, 0, 425, 0, 0, v1, 0);
+              pBtn_SliderLeft = pGUIWindow_CurrentMenu->CreateButton(0x15u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 4u, 0, v1, pIcons_LOD->GetTexture(uTextureID_507C20), 0);
+              pBtn_SliderRight = pGUIWindow_CurrentMenu->CreateButton(0xD5u, 0xA1u, 0x10u, 0x10u, 1, 0, UIMSG_1A9, 5u, 0, v1, pIcons_LOD->GetTexture(uTextureID_507C24), 0);
+              pGUIWindow_CurrentMenu->CreateButton(42, 162, 170, 18, 1, 0, UIMSG_1A9, 0, 0, v1, 0);
             }
           }
           continue;
@@ -1496,22 +1495,22 @@
               uTextureID_Controls1 = pIcons_LOD->LoadTexture("controls1", TEXTURE_16BIT_PALETTE);
               uTextureID_Resume1 = pIcons_LOD->LoadTexture("resume1", TEXTURE_16BIT_PALETTE);
               uTextureID_Quit1 = pIcons_LOD->LoadTexture("quit1", TEXTURE_16BIT_PALETTE);
-              pBtn_NewGame = pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x9Bu, 0xD6u, 0x28u, v0, 0, 0x7Cu, 0, 0x4Eu,
+              pBtn_NewGame = pGUIWindow_CurrentMenu->CreateButton(0x13u, 0x9Bu, 0xD6u, 0x28u, v0, 0, UIMSG_StartNewGame, 0, 0x4Eu,
                              pGlobalTXT_LocalizationStrings[614],// "New Game"
                              pIcons_LOD->GetTexture(uTextureID_New1), 0);
-              pBtn_SaveGame = pGUIWindow_CurrentMenu->CreateButton(0x13u, 0xD1u, 0xD6u, 0x28u, v0, 0, 0x7Eu, 0, 0x53u,
+              pBtn_SaveGame = pGUIWindow_CurrentMenu->CreateButton(0x13u, 0xD1u, 0xD6u, 0x28u, v0, 0, UIMSG_Game_OpenSaveGameDialog, 0, 0x53u,
                              pGlobalTXT_LocalizationStrings[615],// "Save Game"
                              pIcons_LOD->GetTexture(uTextureID_Save1), 0);
-              pBtn_LoadGame = pGUIWindow_CurrentMenu->CreateButton(19, 263, 0xD6u, 0x28u, v0, 0, 0x7Du, 0, 0x4Cu,
+              pBtn_LoadGame = pGUIWindow_CurrentMenu->CreateButton(19, 263, 0xD6u, 0x28u, v0, 0, UIMSG_Game_OpenLoadGameDialog, 0, 0x4Cu,
                              pGlobalTXT_LocalizationStrings[616],// "Load Game"
                              pIcons_LOD->GetTexture(uTextureID_Load1), 0);
-              pBtn_GameControls = pGUIWindow_CurrentMenu->CreateButton(241, 155, 214, 40, v0, 0, 0x7Fu, 0, 0x43u,
+              pBtn_GameControls = pGUIWindow_CurrentMenu->CreateButton(241, 155, 214, 40, v0, 0, UIMSG_Game_OpenOptionsDialog, 0, 0x43u,
                              pGlobalTXT_LocalizationStrings[617],// ""Sound, Keyboard, Game Options:""
                              pIcons_LOD->GetTexture(uTextureID_Controls1), 0);
-              pBtn_QuitGame = pGUIWindow_CurrentMenu->CreateButton(241, 209, 214, 40, v0, 0, 0x84u, 0, 0x51u,
+              pBtn_QuitGame = pGUIWindow_CurrentMenu->CreateButton(241, 209, 214, 40, v0, 0, UIMSG_Quit, 0, 0x51u,
                              pGlobalTXT_LocalizationStrings[618],// "Quit"
                              pIcons_LOD->GetTexture(uTextureID_Quit1), 0);
-              pBtn_Resume = pGUIWindow_CurrentMenu->CreateButton(241, 263, 214, 40, v0, 0, 0x7Bu, 0, 0x52u,
+              pBtn_Resume = pGUIWindow_CurrentMenu->CreateButton(241, 263, 214, 40, v0, 0, UIMSG_GameMenu_ReturnToGame, 0, 0x52u,
                              pGlobalTXT_LocalizationStrings[619],// "Return to Game"
                              pIcons_LOD->GetTexture(uTextureID_Resume1), 0);
               pGUIWindow_CurrentMenu->_41D08F(6, v0, 0, 0);
@@ -2845,7 +2844,7 @@
           v130 = 0;
           v127 = rand() % 2 + 204;
           goto _play_sound_and_continue;
-        case UIMSG_57:
+        case UIMSG_OpenSpellbookPage:
           if ( pTurnEngine->field_4 == 3 || !uActiveCharacter || uMessageParam == pPlayers[uActiveCharacter]->lastOpenedSpellbookPage )
             continue;
           sub_41140B();
@@ -2982,7 +2981,7 @@
           pCurrentScreen = SCREEN_QUICK_REFERENCE;
           pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, 640, 480, WINDOW_QuickReference, 5, 0);
           papredoll_dbrds[2] = pIcons_LOD->LoadTexture("BUTTEXI1", TEXTURE_16BIT_PALETTE);
-          pBtn_ExitCancel = pGUIWindow_CurrentMenu->CreateButton(0x187u, 0x13Cu, 0x4Bu, 0x21u, v0, 0, 0x71u, 0, 0,
+          pBtn_ExitCancel = pGUIWindow_CurrentMenu->CreateButton(0x187u, 0x13Cu, 0x4Bu, 0x21u, v0, 0, UIMSG_Escape, 0, 0,
                          pGlobalTXT_LocalizationStrings[79],// "Exit"
                          (Texture *)(uTextureID_BUTTDESC2 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_BUTTDESC2] : 0), 0); //, v179);
           continue;
@@ -3044,10 +3043,10 @@
             v123 = 300;
             v121 = 600;
           }
-          pCharacterScreen_DetalizBtn = pGUIWindow_CurrentMenu->CreateButton(v121, v123, v125, v128, v0, 0, 0x55u, 0, 0,
+          pCharacterScreen_DetalizBtn = pGUIWindow_CurrentMenu->CreateButton(v121, v123, v125, v128, v0, 0, UIMSG_MainMenu_ShowLoadWindow, 0, 0,
                          pGlobalTXT_LocalizationStrings[64],// "Detail Toggle"
                          0);
-          pCharacterScreen_DollBtn = pGUIWindow_CurrentMenu->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, v0, 0, 0x85u, 0, 0, v1, 0);
+          pCharacterScreen_DollBtn = pGUIWindow_CurrentMenu->CreateButton(0x1DCu, 0, 0xA4u, 0x159u, v0, 0, UIMSG_85, 0, 0, v1, 0);
           goto LABEL_422;
         case UIMSG_85:
           OnPaperdollLeftClick();
@@ -4540,7 +4539,7 @@
       {
         v4 = &pSpriteObjects[v3];
         v36 = v4;
-        v5 = v4->field_58_pid;
+        v5 = v4->spell_caster_pid;
         v2 = v5 & 7;
         v3 = v5 >> 3;
       }
@@ -4781,7 +4780,7 @@
     v4 = &pSpriteObjects[a1 >> 3];
     //uDamageAmount = (int)v4;
     v61 = v4->field_60_distance_related_prolly_lod;
-    a1 = v4->field_58_pid;
+    a1 = v4->spell_caster_pid;
     //v54 = v4->field_58_pid;
   }
   //v5 = a1 & 7;
@@ -4850,7 +4849,7 @@
   }
 
 
-  v19 = v4->field_48 == 99;
+  v19 = v4->spell_id == SPELL_DARK_SOULDRINKER;
   v61 = v4->field_60_distance_related_prolly_lod;
   if ( !v19 )
   {
@@ -4897,8 +4896,8 @@
     v4 = (SpriteObject *)uDamageAmount;
   }
 
-  v15 = v4->field_48;
-  if ( v15 == 102 )
+  v15 = v4->spell_id;
+  if ( v15 == SPELL_LASER_PROJECTILE )
   {
     v16 = player->pActiveSkills[7];
     v61 = 1;
@@ -4908,9 +4907,9 @@
     uDamageAmount = player->CalculateMeleeDamageTo(1, 1, 0);
     goto LABEL_67;
   }
-  if ( v15 != 100 )
-  {
-    if ( v15 == 101 )
+  if ( v15 != SPELL_BOW_ARROW )
+  {
+    if ( v15 == SPELL_101 )
     {
       a2 = 0;
       v18 = player->CalculateRangedDamageTo(0);
@@ -4922,14 +4921,14 @@
       v59 = 1;
       goto LABEL_67;
     }
-    if ( v15 == 39 )
-    {
-      a4 = 5 * v4->field_4C;
+    if ( v15 == SPELL_EARTH_BLADES )
+    {
+      a4 = 5 * v4->spell_level;
       a2 = player->GetSpellSchool(0x27u);
-      v21 = v4->field_4C;
+      v21 = v4->spell_level;
       v50 = pMonster->sCurrentHP;
-      pMonsterName = (char *)v4->field_50;
-      v22 = _43AFE3_calc_spell_damage(39, v21, (signed int)pMonsterName, v50);
+      pMonsterName = (char *)v4->spell_skill;
+      v22 = _43AFE3_calc_spell_damage(39, v21, v4->spell_skill, v50);
       v23 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
       v24 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
       uDamageAmount = v22;
@@ -4945,24 +4944,23 @@
       }
       goto LABEL_69;
     }
-    if ( v15 == 34 )
+    if ( v15 == SPELL_EARTH_STUN )
     {
       uDamageAmount = 0;
       a2 = 4;
       hit_will_stun = 1;
       goto LABEL_67;
     }
-    v50 = v4->field_48;
-    a2 = player->GetSpellSchool(v50);
-    v25 = v4->field_4C;
-    v26 = v4->field_48;
+    a2 = player->GetSpellSchool(v4->spell_id);
+    v25 = v4->spell_level;
+    v26 = v4->spell_id;
     v50 = pMonster->sCurrentHP;
-    pMonsterName = (char *)v4->field_50;
+    pMonsterName = (char *)v4->spell_skill;
     //v27 = _43AFE3_calc_spell_damage(v26, v25, (signed int)pMonsterName, v50);
     v59 = 0;
     //v57 = (PlayerEquipment *)1;
 //LABEL_65:
-    uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, (signed int)pMonsterName, v50);
+    uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, v4->spell_skill, v50);
     //if ( !v57 )
     //  goto LABEL_67;
     goto LABEL_69;
@@ -5450,10 +5448,10 @@
     return;
   }
   v37 = &pSpriteObjects[uActorID];
-  v38 = v37->field_58_pid & 7;
-  v39 = v37->field_58_pid >> 3;
-  v40 = v37->field_58_pid & 7;
-  uActorID = v37->field_58_pid >> 3;
+  v38 = v37->spell_caster_pid & 7;
+  v39 = v37->spell_caster_pid >> 3;
+  v40 = v37->spell_caster_pid & 7;
+  uActorID = v37->spell_caster_pid >> 3;
   v41 = v40 - 2;
   if ( !v41 )
     goto LABEL_80;
@@ -5639,11 +5637,11 @@
     v43 = &pParty->pPlayers[a4];
 LABEL_168:
     a4b = v43;
-    if ( v38 != OBJECT_Player || v37->field_48 != 100 )
+    if ( v38 != OBJECT_Player || v37->spell_id != SPELL_BOW_ARROW)
     {
       v70 = v43->GetMaxHealth();
-      v68 = _43AFE3_calc_spell_damage(v37->field_48, v37->field_4C, v37->field_50, v70);
-      v69 = LOBYTE(pSpellStats->pInfos[v37->field_48].uSchool);
+      v68 = _43AFE3_calc_spell_damage(v37->spell_id, v37->spell_level, v37->spell_skill, v70);
+      v69 = LOBYTE(pSpellStats->pInfos[v37->spell_id].uSchool);
     }
     else
     {
@@ -5681,44 +5679,32 @@
 //----- (0043A97E) --------------------------------------------------------
 void __fastcall sub_43A97E(unsigned int uLayingItemID, signed int a2)
 {
-  unsigned int v2; // esi@1
-  unsigned int v3; // ebx@1
-  int v4; // edi@1
-  int v5; // edx@1
-  unsigned int v6; // [sp+10h] [bp-4h]@1
-
-  v6 = uLayingItemID;
-  v2 = uLayingItemID;
-  v3 = a2 >> 3;
-  v4 = pSpriteObjects[uLayingItemID].field_58_pid & 7;
-  v5 = (a2 & 7) - 3;
-  if ( v5 )
-  {
-    if ( v5 == 1 )
-    {
-      layingitem_vel_50FDFC.x = pSpriteObjects[v2].vVelocity.x;
-      layingitem_vel_50FDFC.y = pSpriteObjects[v2].vVelocity.y;
-      layingitem_vel_50FDFC.z = pSpriteObjects[v2].vVelocity.z;
-      Vec3_int_::Normalize(&layingitem_vel_50FDFC.x, &layingitem_vel_50FDFC.y, &layingitem_vel_50FDFC.z);
-      DamagePlayerFromMonster(8 * v6 | 2, pSpriteObjects[v2].field_61, &layingitem_vel_50FDFC, 0xFFFFFFFFu);
-    }
-  }
-  else
-  {
-    layingitem_vel_50FDFC.x = pSpriteObjects[v2].vVelocity.x;
-    layingitem_vel_50FDFC.y = pSpriteObjects[v2].vVelocity.y;
-    layingitem_vel_50FDFC.z = pSpriteObjects[v2].vVelocity.z;
+  if ( PID_TYPE(a2) == OBJECT_BLVDoor)
+  {
+    layingitem_vel_50FDFC.x = pSpriteObjects[uLayingItemID].vVelocity.x;
+    layingitem_vel_50FDFC.y = pSpriteObjects[uLayingItemID].vVelocity.y;
+    layingitem_vel_50FDFC.z = pSpriteObjects[uLayingItemID].vVelocity.z;
+
     Vec3_int_::Normalize(&layingitem_vel_50FDFC.x, &layingitem_vel_50FDFC.y, &layingitem_vel_50FDFC.z);
-    switch ( v4 )
+    DamagePlayerFromMonster(PID(OBJECT_Item, uLayingItemID), pSpriteObjects[uLayingItemID].field_61, &layingitem_vel_50FDFC, 0xFFFFFFFFu);
+  }
+  else if (PID_TYPE(a2) == OBJECT_Actor)
+  {
+    layingitem_vel_50FDFC.x = pSpriteObjects[uLayingItemID].vVelocity.x;
+    layingitem_vel_50FDFC.y = pSpriteObjects[uLayingItemID].vVelocity.y;
+    layingitem_vel_50FDFC.z = pSpriteObjects[uLayingItemID].vVelocity.z;
+
+    Vec3_int_::Normalize(&layingitem_vel_50FDFC.x, &layingitem_vel_50FDFC.y, &layingitem_vel_50FDFC.z);
+    switch (PID_TYPE(pSpriteObjects[uLayingItemID].spell_caster_pid))
     {
       case OBJECT_Actor:
-        sub_43B1B0(8 * v6 | AI_OBJECT_LAYING_ITEM, v3, &layingitem_vel_50FDFC, pSpriteObjects[v2].field_61);
+        sub_43B1B0(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC, pSpriteObjects[uLayingItemID].field_61);
         break;
       case OBJECT_Player:
-        DamageMonsterFromParty(8 * v6 | AI_OBJECT_LAYING_ITEM, v3, &layingitem_vel_50FDFC);
+        DamageMonsterFromParty(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC);
         break;
       case OBJECT_Item:
-        sub_43B057(8 * v6 | AI_OBJECT_LAYING_ITEM, v3, &layingitem_vel_50FDFC);
+        sub_43B057(PID(OBJECT_Item, uLayingItemID), PID_ID(a2), &layingitem_vel_50FDFC);
         break;
     }
   }
@@ -5864,10 +5850,10 @@
     if ( (a2 & 7) == OBJECT_Item)
     {
       v4 = &pSpriteObjects[(signed int)a2 >> 3];
-      v5 = v4->field_48;
+      v5 = v4->spell_id;
       if ( v5 )
       {
-        v6 = _43AFE3_calc_spell_damage(v5, v4->field_4C, v4->field_50, pActor->sCurrentHP);
+        v6 = _43AFE3_calc_spell_damage(v5, v4->spell_level, v4->spell_skill, pActor->sCurrentHP);
         v7 = stru_50C198.CalcMagicalDamageToActor(pActor, 0, v6);
         pActor->sCurrentHP -= v7;
         if ( v7 )
@@ -5924,7 +5910,7 @@
   {
     v5 = &pSpriteObjects[a1 >> 3];
     v4 = v5->field_60_distance_related_prolly_lod;
-    v17 = v5->field_58_pid;
+    v17 = v5->spell_caster_pid;
   }
   LOWORD(v6) = v17 & 7;
   if ( v6 == OBJECT_Actor)
@@ -6895,8 +6881,8 @@
   _404544();
   v2 = v1->pQueue;
   v3 = 0;
-  if ( (v1->pQueue[0].uPackedID & 7) == OBJECT_Player)
-    uActiveCharacter = (v1->pQueue[0].uPackedID >> 3) + 1;
+  if (PID_TYPE(v1->pQueue[0].uPackedID) == OBJECT_Player)
+    uActiveCharacter = PID_ID(v1->pQueue[0].uPackedID) + 1;
   else
     uActiveCharacter = 0;
   viewparams->bRedrawGameUI = 1;
@@ -6914,9 +6900,9 @@
     goto LABEL_27;
   do
   {
-    if ( (v2->uPackedID & 7) != OBJECT_Player)
-    {
-      v5 = &pActors[v2->uPackedID >> 3];
+    if (PID_TYPE(v2->uPackedID) != OBJECT_Player)
+    {
+      v5 = &pActors[PID_ID(v2->uPackedID)];
       LOWORD(v6) = v5->uAIState;
       if ( (short)v6 == 4
         || (short)v6 == 8
@@ -6972,9 +6958,9 @@
     v9 = v1->pQueue;
     do
     {
-      if ( (v9->uPackedID & 7) != OBJECT_Player)
-      {
-        v10 = v9->uPackedID >> 3;
+      if (PID_TYPE(v9->uPackedID) != OBJECT_Player)
+      {
+        v10 = PID_ID(v9->uPackedID);
         v11 = pActors[v10].uAIState;
         if ( v11 != 5 )
         {
@@ -7024,7 +7010,7 @@
   v4 = v1->pQueue[0].field_4;
   if ( v4 )
   {
-    if ( (v1->pQueue[0].uPackedID & 7) == OBJECT_Player)
+    if (PID_TYPE(v1->pQueue[0].uPackedID) == OBJECT_Player)
     {
       v5 = v1->uActorQueueSize;
       while ( 1 )
@@ -7123,8 +7109,8 @@
   }
   v2->pQueue[a2].field_4 = v6;
   v2->_404544();
-  if ( (v2->pQueue[0].uPackedID & 7) == OBJECT_Player)
-    uActiveCharacter = (v2->pQueue[0].uPackedID >> 3) + 1;
+  if (PID_TYPE(v2->pQueue[0].uPackedID) == OBJECT_Player)
+    uActiveCharacter = PID_ID(v2->pQueue[0].uPackedID) + 1;
   else
     uActiveCharacter = 0;
   result = (int)&v2->pQueue[0].field_4;
@@ -7202,7 +7188,7 @@
   v1 = this;
   LOWORD(v2) = _404544();
   if ( v1->pQueue[0].field_4 <= 0
-    || ((_4063A1(), v2 = v1->pQueue[0].uPackedID, (v1->pQueue[0].uPackedID & 7) != OBJECT_Player) ? (uActiveCharacter = 0) : (v2 = (v2 >> 3) + 1, uActiveCharacter = v2),
+    || ((_4063A1(), v2 = v1->pQueue[0].uPackedID, PID_TYPE(v1->pQueue[0].uPackedID) != OBJECT_Player) ? (uActiveCharacter = 0) : (v2 = (v2 >> 3) + 1, uActiveCharacter = v2),
         viewparams->bRedrawGameUI = 1,
         v1->pQueue[0].field_4 <= 0) )
   {
@@ -7270,13 +7256,13 @@
   v1 = (TurnBased_QueueElem *)((char *)this + 16 * (a2 + 2));
   v28 = v1;
   v3 = v1->uPackedID;
-  if ( (v1->uPackedID & 7) != OBJECT_Player)
-  {
-    v4 = v3 >> 3;                               // turn based only stuff
-    a2a = ai_near_actors_targets_pid[v3 >> 3];
-    memcpy(&a3, Actor::GetDirectionInfo(v1->uPackedID, ai_near_actors_targets_pid[v3 >> 3], &a3, 0), sizeof(a3));
+  if (PID_TYPE(v1->uPackedID) != OBJECT_Player)
+  {
+    v4 = PID_ID(v3);
+    a2a = ai_near_actors_targets_pid[PID_ID(v3)];
+    memcpy(&a3, Actor::GetDirectionInfo(v1->uPackedID, ai_near_actors_targets_pid[PID_ID(v3)], &a3, 0), sizeof(a3));
     memcpy(&a4, &a3, sizeof(a4));
-    v5 = &pActors[v3 >> 3];
+    v5 = &pActors[PID_ID(v3 >> 3)];
     LOWORD(v3) = v5->uAIState;
     if ( (short)v3 != Dead )
     {
@@ -7434,11 +7420,8 @@
           v9 = 0;
           v20 = 0;
         }
-        if ( (v22 & 7) == OBJECT_Actor)
-          v10 = (unsigned __int8)*(&byte_5C8D1A[89
-                                              * (pMonsterStats->pInfos[pActors[v22 >> 3].pMonsterInfo.uID].uID - 1)
-                                              / 3]
-                                 + (v5->pMonsterInfo.uID - 1) / 3);
+        if (PID_TYPE(v22) == OBJECT_Actor)
+          v10 = (unsigned __int8)*(&byte_5C8D1A[89 * (pMonsterStats->pInfos[pActors[v22 >> 3].pMonsterInfo.uID].uID - 1) / 3] + (v5->pMonsterInfo.uID - 1) / 3);
         else
           v10 = 4;
         if ( v10 == 1 )
@@ -7567,9 +7550,9 @@
     while ( 1 )
     {
       v5 = v10->uPackedID;
-      if ( (v10->uPackedID & 7) == OBJECT_Actor)
-      {
-        v8 = ai_near_actors_targets_pid[v5 >> 3];
+      if (PID_TYPE(v10->uPackedID) == OBJECT_Actor)
+      {
+        v8 = ai_near_actors_targets_pid[PID_ID(v5)];
         memcpy(&v7, Actor::GetDirectionInfo(v5, v8, &a3, v2), sizeof(v7));
         if ( !v1->_406D10(a2) )
           Actor::AI_Stand(v10->uPackedID >> 3, v8, 0x20u, &v7);
@@ -7606,9 +7589,9 @@
     v2 = this->pQueue;
     do
     {
-      if ( (v2->uPackedID & 7) == OBJECT_Actor)
-      {
-        v3 = v2->uPackedID >> 3;
+      if (PID_TYPE(v2->uPackedID) == OBJECT_Actor)
+      {
+        v3 = PID_ID(v2->uPackedID);
         v8 = v3;
         if ( pActors[v3].CanAct() )
         {
@@ -7661,7 +7644,7 @@
     {
       v4 = v14->uPackedID;
       a1 = v14->uPackedID;
-      if ( (a1 & 7) != OBJECT_Player)
+      if (PID_TYPE(a1) != OBJECT_Player)
       {
         v5 = v4 >> 3;
         v12 = v5;
@@ -7744,10 +7727,11 @@
   unsigned int uActorID; // [sp+50h] [bp-4h]@2
   unsigned int a2a; // [sp+5Ch] [bp+8h]@7
 
+  __debugbreak();
   v2 = *(&this->field_0 + 4 * (a2 + 2));
-  if ( (v2 & 7) == OBJECT_Player)
+  if (PID_TYPE(v2) == OBJECT_Player)
     return 0;
-  v3 = v2 >> 3;
+  v3 = PID_ID(v2);
   uActorID = v3;
   v4 = &pActors[v3];
   v5 = v4->uAIState;
@@ -7939,9 +7923,9 @@
     v14 = this->pQueue;
     do
     {
-      if ( (v3->uPackedID & 7) != OBJECT_Player)
-      {
-        v4 = v3->uPackedID >> 3;
+      if (PID_TYPE(v3->uPackedID) != OBJECT_Player)
+      {
+        v4 = PID_ID(v3->uPackedID);
         uActorID = v4;
         v5 = &pActors[v4];
         v6 = v5->uAIState;
@@ -11608,7 +11592,7 @@
         pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
       }
       //v11 = i->uControlParam;
-      pMessageQueue_50CBD0->AddMessage((UIMessageType)i->uControlID, i->uControlParam, 0);
+      pMessageQueue_50CBD0->AddMessage(i->msg, i->msg_param, 0);
       return;
     }
     goto LABEL_45;
@@ -11621,9 +11605,9 @@
   else
     v5 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];
   v6 = (unsigned __int16)v5;
-  if ( (v5 & 7) == OBJECT_Actor
+  if (PID_TYPE(v5) == OBJECT_Actor
     && uActiveCharacter
-    && v5 < 33554432
+    && v5 < 0x2000000
     && pPlayers[uActiveCharacter]->CanAct()
     && pPlayers[uActiveCharacter]->CanSteal() )
   {
@@ -11634,7 +11618,7 @@
       *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
       ++pMessageQueue_50CBD0->uNumMessages;
     }*/
-    pMessageQueue_50CBD0->AddMessage(UIMSG_1B, v6 >> 3, 0);
+    pMessageQueue_50CBD0->AddMessage(UIMSG_1B, PID_ID(v6), 0);
 
     if ( pParty->bTurnBasedModeOn == 1 )
     {
@@ -11857,7 +11841,7 @@
     dword_507CBC = 1;
     for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = i->pNext )
     {
-      if ( i->uControlID == 120 )
+      if ( i->msg == UIMSG_InventoryLeftClick )
       {
         dword_50698C = i->uX;
         dword_506988 = i->uY;
@@ -11876,8 +11860,7 @@
                    (uTextureID_ar_up_up != -1 ? pIcons_LOD->pTextures[uTextureID_ar_up_up].uTextureHeight : 26),
                    1,
                    0,
-                   0xA9u,
-                   0,
+                   UIMSG_A9, 0,
                    0,
                    "",
                    (Texture *)(uTextureID_ar_up_up != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_ar_up_up] : 0),
@@ -11890,8 +11873,7 @@
                    (uTextureID_ar_dn_up != -1 ? pIcons_LOD->pTextures[uTextureID_ar_dn_up].uTextureHeight : 26),
                    1,
                    0,
-                   0xAAu,
-                   0,
+                   UIMSG_AA, 0,
                    0,
                    "",
                    (Texture *)(uTextureID_ar_dn_up != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_ar_dn_up] : 0),
@@ -11904,8 +11886,7 @@
                    0xE8u,
                    1,
                    0,
-                   0xC0u,
-                   0,
+                   UIMSG_C0, 0,
                    0,
                    "",
                    0);
@@ -11929,7 +11910,7 @@
     pBtn_Up = 0;
     for ( i = pGUIWindow_CurrentMenu->pControlsHead; i; i = i->pNext )
     {
-      if ( i->uControlID == 120 )
+      if ( i->msg == UIMSG_InventoryLeftClick )
       {
         i->uX = dword_50698C;
         i->uY = dword_506988;
--- a/mm7_6.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_6.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -4,7 +4,6 @@
 #include "Game.h"
 #include "GUIWindow.h"
 #include "GUIFont.h"
-#include "GUIButton.h"
 #include "GUIProgressBar.h"
 #include "Party.h"
 #include "AudioPlayer.h"
@@ -2094,19 +2093,19 @@
   unsigned int v14; // eax@23
   //stru277 *v15; // esi@27
   //stru277 *v16; // eax@28
-  GUIWindow *v17; // eax@43
-  GUIWindow *v18; // [sp-30h] [bp-48h]@44
-  unsigned int v19; // [sp-2Ch] [bp-44h]@44
-  unsigned int v20; // [sp-28h] [bp-40h]@44
-  unsigned int v21; // [sp-24h] [bp-3Ch]@44
-  unsigned int v22; // [sp-20h] [bp-38h]@44
-  int v23; // [sp-1Ch] [bp-34h]@44
-  int v24; // [sp-18h] [bp-30h]@44
-  unsigned int v25; // [sp-14h] [bp-2Ch]@43
-  unsigned int v26; // [sp-10h] [bp-28h]@43
-  unsigned __int8 v27; // [sp-Ch] [bp-24h]@43
-  char *v28; // [sp-8h] [bp-20h]@43
-  Texture *v29; // [sp-4h] [bp-1Ch]@43
+  //GUIWindow *v17; // eax@43
+  //GUIWindow *v18; // [sp-30h] [bp-48h]@44
+  //unsigned int v19; // [sp-2Ch] [bp-44h]@44
+  //unsigned int v20; // [sp-28h] [bp-40h]@44
+  //unsigned int v21; // [sp-24h] [bp-3Ch]@44
+  //unsigned int v22; // [sp-20h] [bp-38h]@44
+  //int v23; // [sp-1Ch] [bp-34h]@44
+  //int v24; // [sp-18h] [bp-30h]@44
+  //unsigned int v25; // [sp-14h] [bp-2Ch]@43
+  //unsigned int v26; // [sp-10h] [bp-28h]@43
+  //unsigned __int8 v27; // [sp-Ch] [bp-24h]@43
+  //char *v28; // [sp-8h] [bp-20h]@43
+  //Texture *v29; // [sp-4h] [bp-1Ch]@43
   //__int16 a3a; // [sp+10h] [bp-8h]@1
   //__int16 a2a; // [sp+14h] [bp-4h]@1
 
@@ -2288,10 +2287,10 @@
         if ( pGUIWindow_Settings )
           return;
         pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, (WindowType)(WINDOW_HouseInterior|0x2), (int)&pStru277[result], 0);
-        pGUIWindow_Settings->CreateButton(0x34u, 0x1A6u, 0x23u, 0, 2, 0, 0x45u, 0, 0x31u, "", 0);
-        pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, 0x45u, 1u, 0x32u, "", 0);
-        pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, 0x45u, 2u, 0x33u, "", 0);
-        pGUIWindow_Settings->CreateButton(0x186u, 0x1A6u, 0x23u, 0, 2, 0, 0x45u, 3u, 0x34u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x34u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_45, 0, 0x31u, "", 0);
+        pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_45, 1u, 0x32u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_45, 2u, 0x33u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x186u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_45, 3u, 0x34u, "", 0);
         sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
@@ -2299,23 +2298,9 @@
       {
         if ( pGUIWindow_Settings )
           return;
-        v17 = GUIWindow::Create(0, 0, 640, 480, (WindowType)(WINDOW_HouseInterior|0x2), (int)&pStru277[result], 0);
-        v29 = 0;
-        v28 = "";
-        v27 = 0;
-        v26 = 0;
-        v25 = 70;
-LABEL_44:
-        v24 = 0;
-        v23 = 1;
-        v22 = 344;
-        v21 = game_viewport_width;
-        v20 = 8;
-        v19 = 8;
-        pGUIWindow_Settings = v17;
-        v18 = v17;
-LABEL_56:
-        v18->CreateButton(v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29);
+
+        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, (WindowType)(WINDOW_HouseInterior|0x2), (int)&pStru277[result], 0);
+        pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_46, 0, 0, "", 0);
         sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
       }
@@ -2323,13 +2308,11 @@
       {
         if ( pGUIWindow_Settings )
           return;
-        v17 = GUIWindow::Create(0, 0, 640, 480, (WindowType)(WINDOW_HouseInterior|0x2), (int)&pStru277[result], 0);
-        v29 = 0;
-        v28 = "";
-        v27 = 0;
-        v26 = 0;
-        v25 = 190;
-        goto LABEL_44;
+
+        pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, (WindowType)(WINDOW_HouseInterior|0x2), (int)&pStru277[result], 0);
+        pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_BE, 0, 0, "", 0);
+        sub_421B2C_PlaceInInventory_or_DropPickedItem();
+        return;
       }
       if ( (char)a5 < 0 )
       {
@@ -2349,44 +2332,36 @@
         if ( pGUIWindow_Settings )
           return;
         pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, (WindowType)(WINDOW_HouseInterior|0x2), (int)&pStru277[result], 0);
-        pGUIWindow_Settings->CreateButton(0x34u, 0x1A6u, 0x23u, 0, 2, 0, 0x8Du, 0, 0x31u, "", 0);
-        pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, 0x8Du, 1u, 0x32u, "", 0);
-        pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, 0x8Du, 2u, 0x33u, "", 0);
-        pGUIWindow_Settings->CreateButton(0x186u, 0x1A6u, 0x23u, 0, 2, 0, 0x8Du, 3u, 0x34u, "", 0);
-		pGUIWindow_Settings->CreateButton(8, 8, game_viewport_width, 344, 1, 0, 140, 0, 0, "", NULL);
+        pGUIWindow_Settings->CreateButton(0x34u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_8D, 0, 0x31u, "", 0);
+        pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_8D, 1, 0x32u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_8D, 2, 0x33u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x186u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_8D, 3, 0x34u, "", 0);
+		pGUIWindow_Settings->CreateButton(8, 8, game_viewport_width, game_viewport_height, 1, 0, UIMSG_8C, 0, 0, "", NULL);
 		sub_421B2C_PlaceInInventory_or_DropPickedItem();
       }
       if ( HIBYTE(a5) & 2 && !pGUIWindow_Settings )
       {
         pGUIWindow_Settings = GUIWindow::Create(0, 0, 640, 480, (WindowType)(WINDOW_HouseInterior|0x2), (int)&pStru277[result], 0);
-        pBtn_NPCLeft = pGUIWindow_Settings->CreateButton(
-                       0x1D5u,
-                       0xB2u,
-                       (uTextureID_Btn_NPCLeft != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft].uTextureWidth : 24),
-                       (uTextureID_Btn_NPCLeft != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft].uTextureHeight : 26),
+        pBtn_NPCLeft = pGUIWindow_Settings->CreateButton(469, 178,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureWidth,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureHeight,
                        1,
                        0,
-                       0xBCu,
-                       0,
+                       UIMSG_ScrollNPCPanel, 0,
                        0,
                        "",
-                       (Texture *)(uTextureID_Btn_NPCLeft != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft] : 0),
-                       0);
-        pBtn_NPCRight = pGUIWindow_Settings->CreateButton(
-                       0x272u,
-                       0xB2u,
-                       (uTextureID_Btn_NPCRight != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCRight].uTextureWidth : 24),
-                       (uTextureID_Btn_NPCRight != -1 ? pIcons_LOD->pTextures[uTextureID_Btn_NPCRight].uTextureHeight : 26),
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft), 0);
+        pBtn_NPCRight = pGUIWindow_Settings->CreateButton(626, 178,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureWidth,
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight)->uTextureHeight,
                        1,
                        0,
-                       0xBCu,
-                       1u,
+                       UIMSG_ScrollNPCPanel, 1,
                        0,
                        "",
-                       (Texture *)(uTextureID_Btn_NPCRight != -1 ? &pIcons_LOD->pTextures[uTextureID_Btn_NPCRight] : 0),
-                       0);
-        pGUIWindow_Settings->CreateButton(0x1EBu, 0x95u, 0x40u, 0x4Au, 1, 0, 0x8Fu, 4u, 0x35u, "", 0);
-        pGUIWindow_Settings->CreateButton(0x231u, 0x95u, 0x40u, 0x4Au, 1, 0, 0x8Fu, 5u, 0x36u, "", 0);
+                       pIcons_LOD->GetTexture(uTextureID_Btn_NPCRight), 0);
+        pGUIWindow_Settings->CreateButton(0x1EBu, 149, 64, 74, 1, 0, UIMSG_8F, 4, 0x35u, "", 0);
+        pGUIWindow_Settings->CreateButton(0x231u, 149, 64, 74, 1, 0, UIMSG_8F, 5, 0x36u, "", 0);
       }
     }
 }
@@ -2421,7 +2396,7 @@
 }
 
 //----- (00427DA0) --------------------------------------------------------
-unsigned int stru277::PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int a6)
+unsigned int stru277::PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int spell_sound_id)
 {
   unsigned int result; // eax@1
   stru277 *v7; // edx@1
@@ -2445,7 +2420,7 @@
   v8->spell_target_pid = 0;
   v8->field_8 = a5;
   v8->forced_spell_skill_level = skill_level;
-  v8->field_10 = a6;
+  v8->sound_id = spell_sound_id;
 LABEL_8:
   if ( result == 10 )
     result = -1;
@@ -2466,17 +2441,17 @@
   //char v9; // al@44
   //int v10; // eax@45
   unsigned __int16 v11; // cx@45
-  signed int v12; // ecx@48
+  //signed int v12; // ecx@48
   //int v13; // eax@53
   unsigned __int8 v14; // zf@53
   //unsigned int v15; // edx@53
   //signed int v16; // eax@53
   Player *v17; // esi@70
-  int v18; // eax@72
-  int v19; // eax@74
+  //int v18; // eax@72
+  //int v19; // eax@74
   char *v20; // eax@74
   signed int i; // esi@76
-  int v22; // eax@88
+  //int v22; // eax@88
   __int16 v23; // ax@88
   //int v24; // ecx@93
   //int v25; // ecx@94
@@ -2488,26 +2463,26 @@
   //int v31; // eax@112
   //int v32; // eax@112
   //char *v33; // edx@113
-  int v34; // eax@121
-  int v35; // eax@123
-  int v36; // edx@125
-  int v37; // eax@129
-  signed int v38; // edi@129
-  signed int v39; // eax@129
-  int v40; // ecx@129
-  int v41; // eax@129
-  signed int v42; // eax@129
-  int *v43; // ecx@129
-  int v44; // eax@132
-  int v45; // ecx@132
+  //int v34; // eax@121
+  //int v35; // eax@123
+  //int v36; // edx@125
+  //int v37; // eax@129
+  //signed int v38; // edi@129
+  //signed int v39; // eax@129
+  //int v40; // ecx@129
+  //int v41; // eax@129
+  //signed int v42; // eax@129
+  //int *v43; // ecx@129
+  //int v44; // eax@132
+  //int v45; // ecx@132
   int v46; // eax@132
-  unsigned int v47; // edx@133
-  int v48; // eax@137
-  int v49; // eax@137
-  int v50; // eax@141
+  //unsigned int v47; // edx@133
+  //int v48; // eax@137
+  //int v49; // eax@137
+  //int v50; // eax@141
   int v51; // eax@146
   __int16 v52; // ax@153
-  int v53; // eax@153
+  //int v53; // eax@153
   signed __int64 v54; // qax@164
   int v55; // edi@164
   //stru6 *v56; // eax@165
@@ -2516,7 +2491,7 @@
   int v59; // edi@177
   unsigned __int16 v60; // ax@184
   int v61; // ecx@184
-  int v62; // eax@186
+  //int v62; // eax@186
   int v63; // ecx@187
   int v64; // ecx@188
   int v65; // ecx@189
@@ -2537,7 +2512,7 @@
   //int v80; // eax@232
   //__int16 v81; // ST18_2@245
   //stru6 *v82; // eax@245
-  signed int v83; // edi@245
+  //signed int v83; // edi@245
   //__int16 v84; // ST18_2@245
   //stru6 *v85; // eax@245
   //__int16 v86; // ST18_2@245
@@ -2574,8 +2549,8 @@
   int v117; // edx@281
   int v118; // edx@283
   int v119; // edi@286
-  int v120; // eax@286
-  int v121; // eax@286
+  //int v120; // eax@286
+  //int v121; // eax@286
   signed int v122; // eax@286
   int v123; // ecx@288
   int v124; // ecx@289
@@ -2606,7 +2581,7 @@
   int v149; // ecx@312
   int v150; // ecx@313
   int v151; // ecx@314
-  signed int v152; // eax@322
+  //signed int v152; // eax@322
   int v153; // ecx@322
   int v154; // eax@322
   int v155; // eax@323
@@ -2615,9 +2590,9 @@
   double v158; // st7@326
   double v159; // st6@326
   signed __int64 v160; // qtt@334
-  int v161; // eax@339
+  //int v161; // eax@339
   int v162; // edi@340
-  int v163; // eax@340
+  //int v163; // eax@340
   signed int v164; // eax@340
   signed int v165; // edi@340
   //stru6 *v166; // eax@340
@@ -2641,7 +2616,7 @@
   int v184; // ecx@358
   int v185; // ecx@359
   int v186; // ecx@360
-  int v187; // eax@367
+  //int v187; // eax@367
   int v188; // esi@369
   int v189; // edi@369
   //const char *v190; // ecx@377
@@ -2680,7 +2655,7 @@
   char v223; // al@438
   int v224; // ecx@442
   int v225; // ecx@443
-  int v226; // eax@451
+  //int v226; // eax@451
   int v227; // esi@453
   unsigned int v228; // edi@454
   int v229; // edi@466
@@ -2693,7 +2668,7 @@
   //stru6 *v236; // eax@469
   //__int16 v237; // ST18_2@469
   //stru6 *v238; // eax@469
-  __int16 v239; // ST1C_2@469
+  //__int16 v239; // ST1C_2@469
   char *v240; // ecx@472
   double v241; // st7@478
   signed __int64 v242; // qax@484
@@ -2780,8 +2755,8 @@
   int v323; // edi@635
   char *v324; // eax@635
   Player *v325; // ecx@640
-  int v326; // eax@643
-  int v327; // eax@648
+  //int v326; // eax@643
+  //int v327; // eax@648
   int v328; // ecx@651
   int v329; // ecx@652
   int v330; // edi@654
@@ -2822,9 +2797,9 @@
   int v365; // ecx@699
   int v366; // eax@701
   //stru6 *v367; // eax@704
-  int v368; // eax@704
+  //int v368; // eax@704
   Actor *v369; // edi@705
-  int v370; // eax@706
+  //int v370; // eax@706
   int v371; // ecx@709
   int v372; // ecx@710
   int v373; // eax@715
@@ -2839,9 +2814,9 @@
   int v382; // ecx@727
   Player *v383; // eax@728
   int v384; // eax@733
-  int v385; // edi@736
-  signed int v386; // eax@736
-  Player *v387; // edi@738
+  //int v385; // edi@736
+  //signed int v386; // eax@736
+  //Player *v387; // edi@738
   int v388; // edi@740
   //unsigned __int16 v389; // ST1C_2@740
   //__int16 v390; // ST18_2@740
@@ -2881,14 +2856,14 @@
   int v424; // ecx@809
   int v425; // eax@811
   signed int v426; // eax@815
-  signed int v427; // eax@820
+  //signed int v427; // eax@820
   int v428; // ecx@825
   int v429; // ecx@826
   int v430; // eax@828
   //stru6 *v431; // eax@831
-  int v432; // eax@831
+  //int v432; // eax@831
   Actor *v433; // edi@832
-  int v434; // eax@833
+  //int v434; // eax@833
   int v435; // ecx@837
   int v436; // ecx@838
   //__int16 v437; // ST1C_2@843
@@ -2960,18 +2935,18 @@
   //stru6 *v503; // eax@940
   //stru6 *v504; // eax@943
   int v505; // eax@943
-  int v506; // eax@943
+  //int v506; // eax@943
   int v507; // edi@944
-  int v508; // eax@944
+  //int v508; // eax@944
   signed int v509; // eax@944
   signed int v510; // edi@944
   Actor *v511; // edi@946
-  int v512; // eax@946
+  //int v512; // eax@946
   SpellBuff *v513; // edi@946
   int v514; // ecx@950
   int v515; // ecx@951
   int v516; // eax@953
-  int v517; // eax@956
+  //int v517; // eax@956
   Actor *v518; // edx@957
   __int16 v519; // cx@958
   int v520; // ecx@968
@@ -2986,9 +2961,9 @@
   //__int16 v529; // ST18_2@975
   //stru6 *v530; // eax@975
   int v531; // eax@982
-  int v532; // eax@982
+  //int v532; // eax@982
   int v533; // edi@983
-  int v534; // eax@983
+  //int v534; // eax@983
   signed int v535; // eax@983
   signed int v536; // edi@983
   stru6 *v537; // eax@984
@@ -3034,9 +3009,9 @@
   Player *v577; // eax@1026
   int v578; // eax@1028
   __int16 v579; // ax@1029
-  int v580; // eax@1031
+  //int v580; // eax@1031
   int v581; // edi@1031
-  int v582; // eax@1031
+  //int v582; // eax@1031
   //__int16 v583; // ST1C_2@1034
   //__int16 v584; // ST18_2@1034
   char *v585; // esi@1034
@@ -3049,16 +3024,16 @@
   int v592; // esi@1052
   int v593; // ecx@1057
   int v594; // ecx@1058
-  int v595; // eax@1064
+  //int v595; // eax@1064
   int v596; // esi@1066
   unsigned int v597; // edi@1067
   int v598; // eax@1079
-  signed int v599; // eax@1082
+  //signed int v599; // eax@1082
   int v600; // edi@1086
   int v601; // edx@1086
   int v602; // eax@1086
   int v603; // ecx@1086
-  int v604; // eax@1087
+  //int v604; // eax@1087
   char *v605; // eax@1089
   int v606; // edx@1091
   int v607; // ecx@1100
@@ -3078,17 +3053,17 @@
   //__int16 v621; // ST18_2@1124
   //stru6 *v622; // eax@1124
   signed __int64 v623; // qax@1127
-  int v624; // eax@1127
+  //int v624; // eax@1127
   int v625; // edi@1129
-  int v626; // eax@1129
+  //int v626; // eax@1129
   signed int v627; // eax@1129
   signed int v628; // edi@1129
   int v629; // ecx@1130
   Player *v630; // eax@1131
   int v631; // eax@1137
-  int v632; // edi@1140
-  Player *v633; // eax@1140
-  signed int v634; // eax@1140
+  //int v632; // edi@1140
+  //Player *v633; // eax@1140
+  //signed int v634; // eax@1140
   int v635; // edi@1142
   //unsigned __int16 v636; // ST1C_2@1142
   //__int16 v637; // ST18_2@1142
@@ -3108,7 +3083,7 @@
   //unsigned __int16 v651; // [sp-8h] [bp-E8Ch]@100
   //unsigned __int16 v652; // [sp-8h] [bp-E8Ch]@304
   //unsigned __int16 v653; // [sp-4h] [bp-E88h]@100
-  int v654; // [sp-4h] [bp-E88h]@124
+  //int v654; // [sp-4h] [bp-E88h]@124
   //unsigned __int16 v655; // [sp-4h] [bp-E88h]@304
   unsigned int v656; // [sp-4h] [bp-E88h]@639
   int v657; // [sp-4h] [bp-E88h]@807
@@ -3123,12 +3098,12 @@
   int v666; // [sp+4h] [bp-E80h]@12
   PLAYER_SKILL_TYPE v667; // [sp+4h] [bp-E80h]@25
   //unsigned __int8 v668; // [sp+4h] [bp-E80h]@100
-  int v669; // [sp+4h] [bp-E80h]@123
-  Vec3_int_ *v670; // [sp+4h] [bp-E80h]@133
+  //int v669; // [sp+4h] [bp-E80h]@123
+  //Vec3_int_ *v670; // [sp+4h] [bp-E80h]@133
   int v671; // [sp+4h] [bp-E80h]@146
   unsigned int v672; // [sp+4h] [bp-E80h]@164
   //unsigned __int8 v673; // [sp+4h] [bp-E80h]@304
-  __int16 v674; // [sp+4h] [bp-E80h]@684
+  //__int16 v674; // [sp+4h] [bp-E80h]@684
   const char *v675; // [sp+4h] [bp-E80h]@800
   int v676; // [sp+4h] [bp-E80h]@807
   int v677; // [sp+4h] [bp-E80h]@861
@@ -3142,28 +3117,28 @@
   unsigned __int64 v685; // [sp+D08h] [bp-17Ch]@416
   int x; // [sp+D20h] [bp-164h]@327
   unsigned __int64 v687; // [sp+D24h] [bp-160h]@327
-  int v688; // [sp+D2Ch] [bp-158h]@943
-  int v689; // [sp+D30h] [bp-154h]@943
-  int v690; // [sp+D34h] [bp-150h]@943
-  int v691; // [sp+D38h] [bp-14Ch]@137
-  int v692; // [sp+D3Ch] [bp-148h]@137
-  int v693; // [sp+D40h] [bp-144h]@137
-  int v694; // [sp+D44h] [bp-140h]@982
-  int v695; // [sp+D48h] [bp-13Ch]@982
-  int v696; // [sp+D4Ch] [bp-138h]@982
-  int v697; // [sp+D50h] [bp-134h]@129
-  int v698; // [sp+D54h] [bp-130h]@129
-  int v699; // [sp+D58h] [bp-12Ch]@129
+  Vec3_int_ v688; // [sp+D2Ch] [bp-158h]@943
+  //int v689; // [sp+D30h] [bp-154h]@943
+  //int v690; // [sp+D34h] [bp-150h]@943
+  Vec3_int_ v691; // [sp+D38h] [bp-14Ch]@137
+  //int v692; // [sp+D3Ch] [bp-148h]@137
+  //int v693; // [sp+D40h] [bp-144h]@137
+  Vec3_int_ v694; // [sp+D44h] [bp-140h]@982
+  //int v695; // [sp+D48h] [bp-13Ch]@982
+  //int v696; // [sp+D4Ch] [bp-138h]@982
+  Vec3_int_ v697; // [sp+D50h] [bp-134h]@129
+  //int v698; // [sp+D54h] [bp-130h]@129
+  //int v699; // [sp+D58h] [bp-12Ch]@129
   Vec3_int_ v700; // [sp+D5Ch] [bp-128h]@339
-  int v701; // [sp+D68h] [bp-11Ch]@286
-  int v702; // [sp+D6Ch] [bp-118h]@286
-  int v703; // [sp+D70h] [bp-114h]@286
-  int v704; // [sp+D74h] [bp-110h]@132
-  int v705; // [sp+D78h] [bp-10Ch]@132
-  int v706; // [sp+D7Ch] [bp-108h]@132
-  int v707; // [sp+D80h] [bp-104h]@1127
-  int v708; // [sp+D84h] [bp-100h]@1127
-  int v709; // [sp+D88h] [bp-FCh]@1127
+  Vec3_int_ v701; // [sp+D68h] [bp-11Ch]@286
+  //int v702; // [sp+D6Ch] [bp-118h]@286
+  //int v703; // [sp+D70h] [bp-114h]@286
+  Vec3_int_ v704; // [sp+D74h] [bp-110h]@132
+  //int v705; // [sp+D78h] [bp-10Ch]@132
+  //int v706; // [sp+D7Ch] [bp-108h]@132
+  Vec3_int_ v707; // [sp+D80h] [bp-104h]@1127
+  //int v708; // [sp+D84h] [bp-100h]@1127
+  //int v709; // [sp+D88h] [bp-FCh]@1127
   char v710; // [sp+D8Ch] [bp-F8h]@1156
   stru277 *v711; // [sp+D90h] [bp-F4h]@1
   __int64 v712; // [sp+D94h] [bp-F0h]@991
@@ -3181,7 +3156,7 @@
   ItemGen *_this; // [sp+E50h] [bp-34h]@23
   float v725; // [sp+E54h] [bp-30h]@23
   Player *v726; // [sp+E58h] [bp-2Ch]@131
-  int v726b;
+  //int v726b;
   float v727; // [sp+E5Ch] [bp-28h]@1
   unsigned int uRequiredMana; // [sp+E60h] [bp-24h]@53
   Player *pPlayer; // [sp+E64h] [bp-20h]@8
@@ -3238,7 +3213,7 @@
 
       a2 = stru_50C198.FindClosestActor(5120, 1, v666);
       v6 = pMouse->uPointingObjectID;
-      if ( pMouse->uPointingObjectID && (v6 & 7) == OBJECT_Actor && pActors[v6 >> 3].CanAct() )
+      if ( pMouse->uPointingObjectID && PID_TYPE(v6) == OBJECT_Actor && pActors[PID_ID(v6)].CanAct() )
         a2 = pMouse->uPointingObjectID;
     }
 
@@ -3246,9 +3221,9 @@
     a1.uType = stru_4E3ACC[v3->spellnum].field_0;
     if (a1.uType)
     {
-      if ( (a2 & 7) == OBJECT_Actor)
+      if (PID_TYPE(a2) == OBJECT_Actor)
       {
-        memcpy(&v715, Actor::GetDirectionInfo((8 * v3->uPlayerID + 8) | OBJECT_Player, a2, &a3, 0), sizeof(v715));
+        memcpy(&v715, Actor::GetDirectionInfo(PID(OBJECT_Player, v3->uPlayerID + 1), a2, &a3, 0), sizeof(v715));
         v2 = v723;
       }
       else
@@ -3299,7 +3274,6 @@
 
     if ( HIBYTE(v11) & 1 )
     {
-      v12 = 4;
       v731 = 4;
     }
     else
@@ -3312,15 +3286,13 @@
       {
         v731 = 3;
       }
-      v12 = v731;
     }
 
-    v730 = v3->spellnum;
     if (v3->forced_spell_skill_level)
       uRequiredMana = 0;
     else 
-      uRequiredMana = pSpellDatas[v3->spellnum].mana_per_skill[v12 - 1];
-    sRecoveryTime = pSpellDatas[v3->spellnum].recovery_per_skill[v12 - 1];
+      uRequiredMana = pSpellDatas[v3->spellnum].mana_per_skill[v731 - 1];
+    sRecoveryTime = pSpellDatas[v3->spellnum].recovery_per_skill[v731 - 1];
 
     if (LODWORD(v725) == PLAYER_SKILL_DARK && pParty->uCurrentHour == 0 && pParty->uCurrentMinute == 0 ||
         LODWORD(v725) == PLAYER_SKILL_LIGHT && pParty->uCurrentHour == 12 && pParty->uCurrentMinute == 0)
@@ -3330,7 +3302,6 @@
       break;
 
     ShowStatusBarString(pGlobalTXT_LocalizationStrings[586], 2u); // "Not enough spell points"
-LABEL_203:
     v3->spellnum = 0;
 LABEL_1166:
     ++n;
@@ -3338,10 +3309,11 @@
       return;
   }
   
-  if (pPlayer->Cursed() && v730 < SPELL_BOW_ARROW)
+  v730 = v3->spellnum;
+  if (pPlayer->Cursed() && v3->spellnum < SPELL_BOW_ARROW)
     if (rand() % 100 < 50)
     {
-      if ( pParty->bTurnBasedModeOn == 0 )
+      if (!pParty->bTurnBasedModeOn)
       {
         //v646 = pPlayer;
         pPlayer->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * 213.3333333333333));
@@ -3376,10 +3348,9 @@
           _this = (ItemGen *)2;
         sRecoveryTime = v17->GetAttackRecoveryTime(true);
         a1.stru_24.Reset();
-        v18 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_48 = v18;
-        a1.field_50 = v731;
+        a1.spell_level = v2;
+        a1.spell_id = v3->spellnum;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         if ( v17->WearsItem(510, 2) )
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(0xBD6u);
@@ -3388,13 +3359,11 @@
         a1.uAttributes = 0;
         a1.uSpriteFrameID = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        v19 = 8 * v3->uPlayerID;
-        LOBYTE(v19) = v19 | OBJECT_Player;
-        a1.field_58_pid = v19;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         v20 = (char *)&pParty->pPlayers[v3->uPlayerID];
         memcpy(&a1.stru_24, &v20[36 * *((int *)v20 + 1620) + 496], sizeof(a1.stru_24));
         a1.uAttributes = 256;
@@ -3418,22 +3387,20 @@
       case SPELL_LASER_PROJECTILE:
         sRecoveryTime = pPlayer->GetAttackRecoveryTime(0);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v723;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v723;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = pParty->vPosition.x;
         a1.vPosition.y = pParty->vPosition.y;
         a1.uAttributes = 0;
         a1.uSpriteFrameID = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
-        v22 = 8 * v3->uPlayerID;
-        LOBYTE(v22) = v22 | OBJECT_Player;
-        a1.field_58_pid = v22;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         memcpy(
           &a1.stru_24,
           &pParty->pPlayers[v3->uPlayerID].spellbook.pDarkSpellbook.bIsSpellAvailable[36
@@ -3457,7 +3424,7 @@
       case SPELL_FIRE_TORCH_LIGHT:
         LODWORD(v733) = 3600 * v2;
 
-        switch (v12)
+        switch (v731)
         {
           case 1: amount = 2; break;
           case 2: amount = 3; break;
@@ -3471,10 +3438,12 @@
           goto play_sound_and_continue;
 
         pParty->pPartyBuffs[PARTY_BUFF_TORCHLIGHT].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)3600 * v2 * 4.2666669), v731, amount, 0, 0);
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case SPELL_FIRE_FIRE_SPIKE:
-        v29 = v12 - 2;
+      {
+        v29 = v731 - 2;
         if ( v29 )
         {
           v30 = v29 - 1;
@@ -3499,12 +3468,12 @@
         //LOBYTE(v32) = v32 | OBJECT_Player;
 
         //if ( (signed int)uNumSpriteObjects > 0 )
-        HIDWORD(v733) = 0;
+        int _v733 = 0;
         for (uint i = 0; i < uNumSpriteObjects; ++i)
         {
           auto object = pSpriteObjects + i;
-          if (object->uType && object->field_48 == 7 && object->field_58_pid == 8 * (int)v3->uPlayerID | OBJECT_Player)
-            ++HIDWORD(v733);
+          if (object->uType && object->spell_id == SPELL_FIRE_FIRE_SPIKE && object->spell_caster_pid == PID(OBJECT_Player, v3->uPlayerID))
+            ++_v733;
           /*v33 = (char *)&pSpriteObjects[0].field_48;
           v730 = uNumSpriteObjects;
           do
@@ -3516,19 +3485,20 @@
           }
           while ( v730 );*/
         }
-        if ( SHIDWORD(v733) > amount )
+        if (_v733 > amount)
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
 
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
@@ -3539,185 +3509,189 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         a1.uSpriteFrameID = 0;
-        v34 = 8 * v3->uPlayerID;
-        LOBYTE(v34) = v34 | OBJECT_Player;
-        a1.field_58_pid = v34;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
-        v669 = v3->uPlayerID + 1;
         v659 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        v35 = pParty->sRotationX + 10;
-        goto LABEL_124;
+          if ( a1.Create(pParty->sRotationY, pParty->sRotationX + 10, v659, v3->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->field_1C;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
 
       case 20:
+      {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         if (!a2)
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
-        }
-        if ( (a2 & 7) != OBJECT_Actor)
-          goto LABEL_1056;
-        v699 = 0;
-        v698 = 0;
-        v697 = 0;
+          v3->spellnum = 0;
+          goto LABEL_1166;
+        }
+        if (PID_TYPE(a2) != OBJECT_Actor)
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
+        v697.x = 0;
+        v697.y = 0;
+        v697.z = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v37 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
-        v37 *= 8;
-        LOBYTE(v37) = v37 | OBJECT_Player;
         a1.uFacing = 0;
-        a1.field_58_pid = v37;
-        v38 = a2 >> 3;
-        a1.uSoundID = LOWORD(v3->field_10);
-        v39 = a2 >> 3;
-        a1.vPosition.x = pActors[v39].vPosition.x;
-        v40 = pActors[v39].vPosition.y;
-        a1.vPosition.z = pActors[v39].vPosition.z;
-        v41 = 8 * (a2 >> 3);
-        a1.vPosition.y = v40;
-        LOBYTE(v41) = v41 | OBJECT_Actor;
-        a1.field_5C = v41;
-        v42 = a1.Create(0, 0, 0, 0);
-        v43 = &v697;
-        goto LABEL_133;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
+        a1.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+        a1.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+        a1.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+        a1.spell_target_pid = PID(OBJECT_Actor, a2 >> 3);
+        auto obj_id = a1.Create(0, 0, 0, 0);
+        DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v697);
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
+
       case 44:
+      {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v726 = (Player *)(a2 >> 3);
-        HIDWORD(v733) = 836 * (a2 >> 3);
+
         if ( !stru_50C198.GetMagicalResistance(&pActors[a2 >> 3], 3u) )
-          goto LABEL_1056;
-        pActors[a2 >> 3].pActorBuffs[10].Apply(
-          pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
-        v706 = 0;
-        v705 = 0;
-        v704 = 0;
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
+        pActors[a2 >> 3].pActorBuffs[10].Apply(pMiscTimer->uTotalGameTimeElapsed + 128, 0, 0, 0, 0);
+        v704.x = 0;
+        v704.y = 0;
+        v704.z = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v44 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v44 *= 8;
-        LOBYTE(v44) = v44 | OBJECT_Player;
-        v38 = (signed int)v726;
-        a1.field_58_pid = v44;
-        a1.uSoundID = LOWORD(v3->field_10);
-        a1.vPosition.x = *(__int16 *)((char *)&pActors[0].vPosition.x + HIDWORD(v733));
-        v45 = *(__int16 *)((char *)&pActors[0].vPosition.y + HIDWORD(v733));
-        a1.vPosition.z = *(__int16 *)((char *)&pActors[0].vPosition.z + HIDWORD(v733));
-        v46 = 8 * (int)v726;
-        a1.vPosition.y = v45;
-        LOBYTE(v46) = 8 * (char)v726 | OBJECT_Actor;
-        a1.field_5C = v46;
-        v42 = a1.Create(0, 0, 0, 0);
-        v43 = &v704;
-LABEL_133:
-        v670 = (Vec3_int_ *)v43;
-        v47 = v38;
-        goto LABEL_139;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
+        a1.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+        a1.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+        a1.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
+        a1.spell_target_pid = PID(OBJECT_Actor, (int)v726);
+
+        auto obj_id = a1.Create(0, 0, 0, 0);
+        DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v704);
+
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
+
       case 79:
-        if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || (a2 & 7) != OBJECT_Actor)
-          goto play_sound_and_continue;
-        v730 = a2 >> 3;
-        v693 = 0;
-        HIDWORD(v733) = (int)&pActors[a2 >> 3];
-        v692 = 0;
-        v691 = 0;
+      {
+        if ( !pPlayer->CanCastSpell(uRequiredMana) || !a2 || PID_TYPE(a2) != OBJECT_Actor)
+          goto play_sound_and_continue;
+        //v730 = a2 >> 3;
+        //HIDWORD(v733) = (int)&pActors[PID_ID(a2)];
+        v691.x = 0;
+        v691.y = 0;
+        v691.z = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
-        a1.vPosition.x = *(short *)(HIDWORD(v733) + 142);
-        a1.vPosition.y = *(short *)(HIDWORD(v733) + 144);
-        v48 = *(short *)(HIDWORD(v733) + 138);
-        a1.vPosition.z = *(short *)(HIDWORD(v733) + 138);
+        a1.vPosition.x = pActors[PID_ID(a2)].vPosition.x;
+        a1.vPosition.y = pActors[PID_ID(a2)].vPosition.y;
+        a1.vPosition.z = pActors[PID_ID(a2)].vPosition.z;
         a1.uAttributes = 0;
-        a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, v48);
+        a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
         a1.uSpriteFrameID = 0;
-        v49 = 8 * v3->uPlayerID;
-        LOBYTE(v49) = v49 | OBJECT_Player;
-        a1.field_58_pid = v49;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        LOWORD(v49) = LOWORD(v3->field_10);
-        LOBYTE(a1.uAttributes) |= 0x80u;
-        a1.uSoundID = v49;
-        v726 = (Player *)a1.Create(0, 0, 0, 0);
+        a1.uAttributes |= 0x80u;
+        a1.uSoundID = LOWORD(v3->sound_id);
+
+        auto obj_id = a1.Create(0, 0, 0, 0);
         if ( !MonsterStats::BelongsToSupertype(*(short *)(HIDWORD(v733) + 96), MONSTER_SUPERTYPE_UNDEAD) )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
-        }
-        v47 = v730;
-        v670 = (Vec3_int_ *)&v691;
-        v42 = (signed int)v726;
-LABEL_139:
-        DamageMonsterFromParty(8 * v42 | 2, v47, v670);
-        goto LABEL_1056;
+          v3->spellnum = 0;
+          goto LABEL_1166;
+        }
+        DamageMonsterFromParty(PID(OBJECT_Item, obj_id), PID_ID(a2), &v691);
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
+
+
       case SPELL_FIRE_FIRE_BOLT:
-      case 6:
-      case 11:
-      case 18:
-      case 26:
-      case 32:
-      case 34:
-      case 37:
-      case 57:
-      case 65:
-      case 70:
-      case 78:
-      case 97:
+      case SPELL_FIRE_FIREBALL:
+      case SPELL_FIRE_INCINERATE:
+      case SPELL_AIR_LIGHNING_BOLT:
+      case SPELL_WATER_ICE_BOLT:
+      case SPELL_WATER_ICE_BLAST:
+      case SPELL_EARTH_STUN:
+      case SPELL_EARTH_DEADLY_SWARM:
+      case SPELL_MIND_MIND_BLAST:
+      case SPELL_MIND_PSYCHIC_SHOCK:
+      case SPELL_BODY_HARM:
+      case SPELL_LIGHT_LIGHT_BOLT:
+      case SPELL_DARK_DRAGON_BREATH:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
         a1.uAttributes = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        a1.uSectorID = pIndoor->GetSector(
-                         pParty->vPosition.x,
-                         pParty->vPosition.y,
-                         pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+        if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
+          a1.uSectorID = pIndoor->GetSector(pParty->vPosition.x,
+                                            pParty->vPosition.y,
+                                            pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
+        else a1.uSectorID = 0;
+
         a1.uSpriteFrameID = 0;
-        v50 = 8 * v3->uPlayerID;
-        LOBYTE(v50) = v50 | OBJECT_Player;
-        a1.field_58_pid = v50;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
-        if ( v3->spellnum == 18 )
+        if ( v3->spellnum == SPELL_AIR_LIGHNING_BOLT )
           LOBYTE(a1.uAttributes) |= 0x40u;
-        goto LABEL_156;
+
+          v659 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+          if ( a1.Create(v715.uYawAngle, v715.uPitchAngle, v659, v3->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->field_1C;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
+
+
       case 29:
       case 39:
       case 76:
@@ -3725,9 +3699,9 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2;
         a1.vPosition.y = pParty->vPosition.y;
@@ -3740,22 +3714,28 @@
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( pPlayer->CanCastSpell(uRequiredMana) )
           goto LABEL_152;
         goto play_sound_and_continue;
+
+
       case 81:
+      {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        if ( !a2
-          || (a2 & 7) != OBJECT_Actor
-          || (v730 = a2 >> 3,
-              v721 = (int)&pActors[a2 >> 3],
+
+        if (PID_TYPE(a2) != OBJECT_Actor ||
+            (v730 = PID_ID(a2),
+              v721 = (int)&pActors[PID_ID(a2)],
               !stru_50C198.GetMagicalResistance(&pActors[a2 >> 3], 9u)) )
-          goto LABEL_1056;
-        Actor::AI_Stand(v730, 4u, 0x80u, 0);
-        v726 = (Player *)(23040 * v2);
+        {
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+        }
+        Actor::AI_Stand(PID_ID(a2), 4u, 0x80u, 0);
         v54 = (signed __int64)((double)(23040 * v2) * 0.033333335);
         v55 = v721;
         ((SpellBuff *)(v721 + 308))->Apply(pParty->uTimePlayed + (signed int)v54, v731, 0, 0, 0);
@@ -3765,20 +3745,22 @@
         *(short *)(v55 + 150) = 0;
         v661 = (Actor *)v55;
         goto LABEL_165;
+      }
+
       case 35:
-        if ( v12 == 2 )
+        if ( v731 == 2 )
         {
           v57 = 300 * v2;
         }
         else
         {
-          if ( v12 == 3 )
+          if ( v731 == 3 )
           {
             amount = 4;
             v57 = 300 * v2;
             goto LABEL_174;
           }
-          if ( v12 == 4 )
+          if ( v731 == 4 )
           {
             v57 = 300 * v2;
             amount = 8;
@@ -3791,17 +3773,18 @@
         LODWORD(v733) = v57;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        if ( (a2 & 7) != OBJECT_Actor
-          || (v721 = 836 * (a2 >> 3),
-              LODWORD(v718) = (int)&pActors[a2 >> 3],
-              !stru_50C198.GetMagicalResistance(&pActors[a2 >> 3], 3u)) )
-          goto LABEL_1056;
-        v726 = (Player *)(23040 * v2);
+        if (PID_TYPE(a2) != OBJECT_Actor
+          || (v721 = 836 * PID_ID(a2),
+              LODWORD(v718) = (int)&pActors[PID_ID(a2)],
+              !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 3u)) )
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         v58 = (signed __int64)((double)(23040 * v2) * 0.033333335);
         v59 = v721;
         //((SpellBuff *)((char *)&pActors[0].pActorBuffs[7] + v721))->Apply(
-		pActors[a2 >> 3].pActorBuffs[7].Apply(
-		  pParty->uTimePlayed + (signed int)v58,
+		pActors[a2 >> 3].pActorBuffs[7].Apply(pParty->uTimePlayed + (signed int)v58,
           v731,
           amount,
           0,
@@ -3810,38 +3793,43 @@
         v672 = 0;
         v661 = (Actor *)LODWORD(v718);
         goto LABEL_165;
+
+
       case 60:
+      {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v730 = 836 * (a2 >> 3);
-        if ( !stru_50C198.GetMagicalResistance(&pActors[a2>>3], 7u) )
-          goto LABEL_1056;
-        LODWORD(v733) = 300 * v2;
+
+        if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 7u) )
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
+
+        uint power = 300 * v2;
         if ( v731 == 2 )
         {
-          LODWORD(v733) = 600 * v2;
-        }
-        else
-        {
-          if ( v731 == 3 )
-            LODWORD(v733) = 29030400;
-        }
+          power = 600 * v2;
+        }
+        else if ( v731 == 3 )
+            power  = 29030400;
+
         //((SpellBuff *)((char *)&pActors[0].pActorBuffs[9] + v730))->Reset();
-		pActors[a2 >> 3].pActorBuffs[9].Reset();
+		pActors[PID_ID(a2)].pActorBuffs[9].Reset();
         //((SpellBuff *)((char *)&pActors[0].pActorBuffs[12] + v730))->Reset();
-        pActors[a2 >> 3].pActorBuffs[12].Reset();
-		v726 = (Player *)((int)v733 << 7);
+        pActors[PID_ID(a2)].pActorBuffs[12].Reset();
         //((SpellBuff *)((char *)&pActors[0].pActorBuffs[1] + v730))->Apply(
-		pActors[a2 >> 3].pActorBuffs[1].Apply(
-          pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
+		pActors[PID_ID(a2)].pActorBuffs[1].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(power << 7) * 0.033333335),
           v731, 0, 0, 0);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
         v61 = a2 >> 3;
         goto LABEL_1086;
+      }
+
       case 92:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
@@ -3856,19 +3844,27 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         a1.uSpriteFrameID = 0;
-        v62 = 8 * v3->uPlayerID;
-        LOBYTE(v62) = v62 | OBJECT_Player;
-        a1.field_58_pid = v62;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        a1.uSoundID = LOWORD(v3->field_10);
-        a1.field_50 = v731;
-        a1.field_48 = 3;
-        a1.field_4C = 300 * v2;
-        goto LABEL_154;
+        a1.uSoundID = LOWORD(v3->sound_id);
+        a1.spell_skill = v731;
+        a1.spell_id = SPELL_FIRE_PROTECTION_FROM_FIRE;
+        a1.spell_level = 300 * v2;
+          if ( pParty->bTurnBasedModeOn == 1 )
+            LOBYTE(a1.uAttributes) |= 4u;
+
+          v659 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
+
+          if ( a1.Create(v715.uYawAngle, v715.uPitchAngle, v659, v3->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->field_1C;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 4:
-        v63 = v12 - 1;
+      {
+        v63 = v731 - 1;
         if ( !v63 )
         {
           amount = 10;
@@ -3897,7 +3893,7 @@
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         v730c = &pParty->pPlayers[v3->uPlayerID_2].pInventoryItems[a2];
-        v726 = (Player *)&pItemsTable->pItems[v730c->uItemID].pIconName;
+        auto _itm = &pItemsTable->pItems[v730c->uItemID];
         v730c->UpdateTempBonus(pParty->uTimePlayed);
         if ( v730c->uItemID < 64 || v730c->uItemID > 65 )
         {
@@ -3907,7 +3903,7 @@
             {
               if (!v730c->uEnchantmentType)
               {
-                v68 = BYTE4(v726->pConditions[3]);
+                v68 = _itm->uEquipType;
                 if ( !v68 || v68 == 1 || v68 == 2 )
                 {
                   if ( !pItemsTable->IsMaterialNonCommon(v730c) )
@@ -3917,21 +3913,17 @@
                     *(int *)(v730 + 12) = amount;
                     if ( !v14 )
                     {
-                      v726 = (Player *)((int)v733 << 7);
                       *(_QWORD *)(v69 + 28) = pParty->uTimePlayed
                                             + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7)
                                                                          * 0.033333335);
                       *(int *)(v69 + 20) |= 8u;
                     }
                     *(int *)(v69 + 20) |= 0x10u;
-LABEL_1055:
                     dword_50C9A8 = 256;
-LABEL_1056:
                     LODWORD(v727) = 1;
 play_sound_and_continue:
                     if ( v3->field_8 & 0x20 )
                     {
-LABEL_1162:
                       if ( v727 != 0.0 )
                         pAudioPlayer->PlaySound(
                           (SoundID)word_4EE088_sound_ids[v3->spellnum],
@@ -3939,7 +3931,7 @@
                           0,
                           -1,
                           0,
-                          v3->field_10,
+                          v3->sound_id,
                           0,
                           0);
                     }
@@ -3963,12 +3955,23 @@
                       if ( v727 != 0.0 )
                       {
                         pPlayer->PlaySound(SPEECH_49, 0);
-                        goto LABEL_1162;
+                        if ( v727 != 0.0 )
+                          pAudioPlayer->PlaySound(
+                          (SoundID)word_4EE088_sound_ids[v3->spellnum],
+                          0,
+                          0,
+                          -1,
+                          0,
+                          v3->sound_id,
+                          0,
+                          0);
+
+                        v3->spellnum = 0;
+                        v2 = v723;
+                        goto LABEL_1166;
                       }
                     }
                     v3->spellnum = 0;
-                    //v1 = 0;
-LABEL_1165:
                     v2 = v723;
                     goto LABEL_1166;
                   }
@@ -3984,10 +3987,13 @@
 
         ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
         pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-        goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
+     }
 
       case SPELL_BODY_REGENERATION:
-        v70 = v12 - 1;
+      {
+        v70 = v731 - 1;
         LODWORD(v733) = 3600 * v2;
         if ( v70 && (v71 = v70 - 1) != 0 )
         {
@@ -4012,7 +4018,9 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
 
         pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_REGENERATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)v733 * 4.2666669), v731, amount, 0, 0);
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
 
       case SPELL_FIRE_PROTECTION_FROM_FIRE:
       case SPELL_AIR_PROTECTION_FROM_AIR:
@@ -4020,7 +4028,7 @@
       case SPELL_EARTH_PROTECTION_FROM_EARTH:
       case SPELL_MIND_PROTECTION_FROM_MIND:
       case SPELL_BODY_PROTECTION_FROM_BODY:
-        v76 = v12 - 1;
+        v76 = v731 - 1;
         LODWORD(v733) = 3600 * v2;
         if ( v76 )
         {
@@ -4082,29 +4090,28 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
-        v83 = 1;
 
         v90 = (double)(signed int)v733 * 4.2666669;
         pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
-          LODWORD(v727) = 1;
+        LODWORD(v727) = 1;
         goto play_sound_and_continue;
 
       case SPELL_FIRE_HASTE:
-        if ( v12 <= 0 )
+        if ( v731 <= 0 )
           goto LABEL_254;
-        if ( v12 <= 2 )
+        if ( v731 <= 2 )
         {
           v91 = 60 * (v2 + 60);
         }
         else
         {
-          if ( v12 == 3 )
+          if ( v731 == 3 )
           {
             v91 = 180 * (v2 + 20);
           }
           else
           {
-            if ( v12 != 4 )
+            if ( v731 != 4 )
               goto LABEL_254;
             v91 = 240 * (v2 + 15);
           }
@@ -4124,7 +4131,6 @@
           while ( v92 <= &pParty->pPlayers[3] );
           if (LODWORD(v727))
           {
-            v726 = (Player *)((int)v733 << 7);
             pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
 
             pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 0);
@@ -4136,7 +4142,7 @@
         goto play_sound_and_continue;
 
       case SPELL_SPIRIT_BLESS:
-        v101 = v12 - 1;
+        v101 = v731 - 1;
         if ( v101 && (v102 = v101 - 1) != 0 )
         {
           v103 = v102 - 1;
@@ -4171,7 +4177,6 @@
           v716 = v111;
           //v658 = v111;
           //v653 = amount;
-          v726 = (Player *)((int)v733 << 7);
           //v651 = 1;
           //v28 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
           //v27 = (char *)&pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS];
@@ -4180,10 +4185,10 @@
 //LABEL_104:
         //LODWORD(v650) = v28;
         pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_BLESS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), 1, amount, v111, 0);
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
         }
         v105 = 0;
-        v726 = (Player *)((int)v733 << 7);
         v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
         v730b = pParty->pPlayers;//[0].pPlayerBuffs[1];
         do
@@ -4195,29 +4200,30 @@
           ++v105;
         }
 		while ( v730b <= &pParty->pPlayers[3] );
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case 52:
-        if ( pPlayer->CanCastSpell(uRequiredMana) && a2 && (a2 & 7) == OBJECT_Actor)
-        {
-          v730 = a2 >> 3;
-          v112 = &pActors[a2 >> 3];
-          v726 = (Player *)abs(v112->vPosition.z - pParty->vPosition.z);
+        if ( pPlayer->CanCastSpell(uRequiredMana) && a2 && PID_TYPE(a2) == OBJECT_Actor)
+        {
+          //v730 = a2 >> 3;
+          v112 = &pActors[PID_ID(a2)];
+          //v726 = (Player *)abs(v112->vPosition.z - pParty->vPosition.z);
           v721 = abs(v112->vPosition.y - pParty->vPosition.y);
           v113 = abs(v112->vPosition.x - pParty->vPosition.x);
           _this = (ItemGen *)v113;
           v114 = v721;
-          v115 = (unsigned int)v726;
+          v115 = (unsigned int)abs(v112->vPosition.z - pParty->vPosition.z);
           if ( v113 < v721 )
           {
             v116 = v113;
             v113 = v721;
             v114 = v116;
           }
-          if ( v113 < (signed int)v726 )
+          if ( v113 < (signed int)v115 )
           {
             v117 = v113;
-            v113 = (int)v726;
+            v113 = (int)v115;
             v115 = v117;
           }
           if ( v114 < (signed int)v115 )
@@ -4229,33 +4235,28 @@
           _this = (ItemGen *)(((unsigned int)(11 * v114) >> 5) + (v115 >> 2) + v113);
           if ( (double)(signed int)this <= 307.2 )
           {
-            v703 = 0;
-            v702 = 0;
-            v701 = 0;
+            v701.x = 0;
+            v701.y = 0;
+            v701.z = 0;
             a1.stru_24.Reset();
             v119 = HIDWORD(v733);
-            a1.field_48 = *(int *)HIDWORD(v733);
-            a1.field_4C = v723;
-            a1.field_50 = v731;
+            a1.spell_id = *(int *)HIDWORD(v733);
+            a1.spell_level = v723;
+            a1.spell_skill = v731;
             a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
             a1.uAttributes = 0;
             a1.uSectorID = 0;
             a1.uSpriteFrameID = 0;
-            v120 = 8 * *(short *)(v119 + 2);
-            LOBYTE(v120) = v120 | OBJECT_Player;
             a1.field_60_distance_related_prolly_lod = 0;
-            a1.field_58_pid = v120;
+            a1.spell_caster_pid = PID(OBJECT_Player, *(short *)(v119 + 2));
             a1.uFacing = 0;
             a1.uSoundID = *(short *)(v119 + 16);
             a1.vPosition.x = v112->vPosition.x;
             a1.vPosition.y = v112->vPosition.y;
-            v726 = (Player *)v112->uActorHeight;
-            v121 = 8 * a2;
-            a1.vPosition.z = v112->vPosition.z - (unsigned int)(signed __int64)((double)(signed int)v726 * unk_4D8548);
-            LOBYTE(v121) = 8 * a2 | 3;
-            a1.field_5C = v121;
+            a1.vPosition.z = v112->vPosition.z - (unsigned int)(signed __int64)((double)(signed int)v112->uActorHeight * unk_4D8548);
+            a1.spell_target_pid = PID(OBJECT_Actor, a2);
             v122 = a1.Create(0, 0, 0, 0);
-            DamageMonsterFromParty(8 * v122 | 2, v730, (Vec3_int_ *)&v701);
+            DamageMonsterFromParty(PID(OBJECT_Item, v122), PID_ID(a2), &v701);
             LODWORD(v727) = 1;
           }
           else
@@ -4271,7 +4272,7 @@
       case SPELL_AIR_SHIELD:
       case SPELL_EARTH_STONESKIN:
       case SPELL_SPIRIT_HEROISM:
-        v123 = v12 - 1;
+        v123 = v731 - 1;
         if ( v123 && (v124 = v123 - 1) != 0 )
         {
           v125 = v124 - 1;
@@ -4319,16 +4320,14 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
-        v83 = 1;
-        v726 = (Player *)((int)v733 << 7);
         v90 = (double)(signed int)((int)v733 << 7) * 0.033333335;
 //LABEL_304:
         pParty->pPartyBuffs[LODWORD(v725)].Apply(pParty->uTimePlayed + (signed int)(signed __int64)v90, v731, amount, 0, 0);
-          LODWORD(v727) = v83;
+        LODWORD(v727) = 1;
         goto play_sound_and_continue;
 
       case SPELL_FIRE_IMMOLATION:
-        v138 = v12 - 2;
+        v138 = v731 - 2;
         if ( v138 && (v139 = v138 - 1) != 0 && v139 == 1 )
           v140 = 600 * v2;
         else
@@ -4342,13 +4341,12 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
 
-        v726 = (Player *)((int)v733 << 7);
-
         pParty->pPartyBuffs[PARTY_BUFF_IMMOLATION].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case 9:
-        v149 = v12 - 1;
+        v149 = v731 - 1;
         if ( v149 && (v150 = v149 - 1) != 0 && (v151 = v150 - 1) != 0 )
         {
           if ( v151 == 1 )
@@ -4362,17 +4360,17 @@
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[491], 2);  // Can't cast Meteor Shower indoors!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         LODWORD(v725) = a2 & 7;
-        if ( (a2 & 7) == OBJECT_Actor)
-        {
-          v152 = a2 >> 3;
-          uRequiredMana = pActors[v152].vPosition.x;
-          v153 = pActors[v152].vPosition.y;
-          v154 = pActors[v152].vPosition.z;
+        if (PID_TYPE(a2) == OBJECT_Actor)
+        {
+          uRequiredMana = pActors[PID_ID(a2)].vPosition.x;
+          v153 = pActors[PID_ID(a2)].vPosition.y;
+          v154 = pActors[PID_ID(a2)].vPosition.z;
           LODWORD(v727) = v153;
         }
         else
@@ -4387,12 +4385,12 @@
         v713 = v154 + 2500;
         v721 = 0;
         LODWORD(v718) = 0;
-        if ( (signed int)this > 0 )
+        if ( (signed int)_this > 0 )
         {
           *(float *)&y = (double)SHIDWORD(v733);
           *(float *)&v732 = (double)v713;
           v730 = LODWORD(v725) == 3 ? a2 : 0;
-          v726 = (Player *)this;
+          auto _this_cpy = (int)_this;
           do
           {
             v157 = rand();
@@ -4417,9 +4415,9 @@
                        stru_5C6E00->Atan2((signed __int64)v718, (signed __int64)*(float *)&v721));
             }
             a1.stru_24.Reset();
-            a1.field_48 = v3->spellnum;
-            a1.field_4C = v2;
-            a1.field_50 = v731;
+            a1.spell_id = v3->spellnum;
+            a1.spell_level = v2;
+            a1.spell_skill = v731;
             a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
             a1.uAttributes = 0;
             a1.vPosition.x = uRequiredMana;
@@ -4427,11 +4425,11 @@
             a1.uSectorID = 0;
             a1.vPosition.z = a2 + v713;
             a1.uSpriteFrameID = 0;
-            a1.field_58_pid = 8 * v3->uPlayerID | OBJECT_Player;
-            a1.field_5C = v730;
+            a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+            a1.spell_target_pid = v730;
             a1.field_60_distance_related_prolly_lod = stru_50C198._427546(a2 + 2500);
             a1.uFacing = v687;
-            a1.uSoundID = LOWORD(v3->field_10);
+            a1.uSoundID = LOWORD(v3->sound_id);
             if ( pParty->bTurnBasedModeOn == 1 )
               a1.uAttributes = 4;
             if ( a1.Create(
@@ -4443,65 +4441,64 @@
               ++pTurnEngine->field_1C;
             LODWORD(v718) = rand() % 1024 - 512;
             v160 = rand();
-            v14 = v726 == (Player *)1;
-            v726 = (Player *)((char *)v726 - 1);
+            v14 = _this_cpy-- == 1;
             v721 = (unsigned __int64)(v160 % 1024) - 512;
           }
           while ( !v14 );
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 10:
+      {
         //v67 = 2;
         if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[492], 2); // Can't cast Inferno outdoors!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v726 = (Player *)sub_46A6AC((int)dword_50BF30, 100, 4096);
+        auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
         v700.z = 0;
         v700.y = 0;
         v700.x = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v161 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v161 *= 8;
-        LOBYTE(v161) = v161 | OBJECT_Player;
-        a1.field_58_pid = v161;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
-        if ( (signed int)v726 > 0 )
+        if ( (signed int)_v726 > 0 )
         {
           do
           {
             v162 = dword_50BF30[a2];
             a1.vPosition.x = pActors[v162].vPosition.x;
             a1.vPosition.y = pActors[v162].vPosition.y;
-            v732 = pActors[v162].uActorHeight;
-            a1.vPosition.z = pActors[v162].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-            v163 = 8 * dword_50BF30[a2];
-            LOBYTE(v163) = v163 | OBJECT_Actor;
-            a1.field_5C = v163;
+            a1.vPosition.z = pActors[v162].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v162].uActorHeight * unk_4D8548);
+            a1.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
             v164 = a1.Create(0, 0, 0, 0);
             v165 = a2;
-            DamageMonsterFromParty(8 * v164 | AI_OBJECT_LAYING_ITEM, dword_50BF30[a2], &v700);
+            DamageMonsterFromParty(PID(OBJECT_Item, v164), dword_50BF30[a2], &v700);
             pGame->GetStru6()->_4A81CA(&a1);
             pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFF3C1Eu, 0x40u);
             a2 = v165 + 1;
           }
-          while ( v165 + 1 < (signed int)v726 );
-        }
-        goto LABEL_1056;
+          while ( v165 + 1 < (signed int)_v726 );
+        }
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
 
       case SPELL_AIR_WIZARD_EYE:
         LODWORD(v733) = 3600 * v2;
@@ -4515,13 +4512,12 @@
         }
         while ( v168 < 4 );
 
-        v732 = (int)v733 << 7;
-
         pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case SPELL_AIR_FEATHER_FALL:
-        v170 = v12 - 1;
+        v170 = v731 - 1;
         if ( !v170 )
         {
           v173 = 300 * v2;
@@ -4550,14 +4546,14 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
-        v83 = 1;
-        v732 = (int)v733 << 7;
-          pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-          LODWORD(v727) = v83;
+
+        pParty->pPartyBuffs[PARTY_BUFF_FEATHER_FALL].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
+        LODWORD(v727) = 1;
         goto play_sound_and_continue;
 
       case SPELL_AIR_SPARKS:
-        v184 = v12 - 1;
+      {
+        v184 = v731 - 1;
         if ( v184 )
         {
           v185 = v184 - 1;
@@ -4585,12 +4581,11 @@
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v726 = (Player *)((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
-        v732 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (amount - 1);
+        auto _v726 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
@@ -4601,16 +4596,14 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         a1.uSpriteFrameID = 0;
-        v187 = 8 * v3->uPlayerID;
-        LOBYTE(v187) = v187 | OBJECT_Player;
-        a1.field_58_pid = v187;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
-        v188 = (signed int)v726 / -2;
-        v189 = (signed int)v726 / 2;
+        v188 = (signed int)_v726 / -2;
+        v189 = (signed int)_v726 / 2;
         while ( v188 <= v189 )
         {
           a1.uFacing = v188 + LOWORD(v715.uYawAngle);
@@ -4621,9 +4614,12 @@
                  v3->uPlayerID + 1) != -1
             && pParty->bTurnBasedModeOn == 1 )
             ++pTurnEngine->field_1C;
-          v188 += v732;
-        }
-        goto LABEL_1056;
+          v188 += _v726 / (amount - 1);
+        }
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
+
       case 16:
         if ( pParty->uFlags & PARTY_FLAGS_1_FALLING)
         {
@@ -4639,10 +4635,11 @@
         while ( v191 < 4 );
         BYTE1(pParty->uFlags) |= 1u;
         pParty->uFallSpeed = 1000;
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case SPELL_AIR_INVISIBILITY:
-        v192 = v12 - 1;
+        v192 = v731 - 1;
         if ( !v192 )
         {
           amount = v2;
@@ -4675,7 +4672,8 @@
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[638], 2);  // There are hostile creatures nearby!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( pPlayer->CanCastSpell(uRequiredMana) )
         {
@@ -4683,15 +4681,14 @@
           pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
           pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
           pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
-          v83 = 1;
-          v732 = (int)v733 << 7;
 
           pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
-          LODWORD(v727) = v83;
+          LODWORD(v727) = 1;
         }
         goto play_sound_and_continue;
 
       case 21:
+      {
         if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[494], 2);  // Can not cast Fly indoors!
@@ -4717,18 +4714,20 @@
         v207 = v3->uPlayerID + 1;
         v716 = v206;
 
-        v732 = (int)v733 << 7;
-
         pParty->pPartyBuffs[PARTY_BUFF_FLY].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, v206, v207);
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
 
       case 22:
+      {
         //v67 = 2;
         if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[495], 2);  // Can't cast Starburst indoors!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
@@ -4752,7 +4751,6 @@
           v713 = pParty->vPosition.y + v214;
           v208 = LODWORD(v725);
         }
-        v726 = (Player *)v211;
         HIDWORD(v733) = 0;
         *(float *)&v732 = (double)v211;
         LODWORD(v725) = v211 + 2500;
@@ -4764,29 +4762,28 @@
         {
           v215 = rand();
           v216 = (double)v721;
-          v727 = v216;
           v217 = (double)SHIDWORD(v733);
           *(float *)&uRequiredMana = v217;
           _this = (ItemGen *)(v215 % 1000);
           *((float *)&v733 + 1) = (double)(v215 % 1000) + *(float *)&v732 - *(float *)&y;
           *(float *)&v721 = v217 * v217;
-          *(float *)&v726 = v216 * v216;
-          if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + *(float *)&v726 + *(float *)&v721) <= 1.0 )
+          //*(float *)&v726 = v216 * v216;
+          if ( sqrt(*((float *)&v733 + 1) * *((float *)&v733 + 1) + v216 * v216 + *(float *)&v721) <= 1.0 )
           {
             LODWORD(v685) = 0;
             HIDWORD(v685) = 0;
           }
           else
           {
-            v684 = (signed __int64)sqrt(*(float *)&v726 + *(float *)&v721);
+            v684 = (signed __int64)sqrt(v216 * v216 + *(float *)&v721);
             v685 = __PAIR__(
                      stru_5C6E00->Atan2(v684, (signed __int64)*((float *)&v733 + 1)),
-                     stru_5C6E00->Atan2((signed __int64)v727, (signed __int64)*(float *)&uRequiredMana));
+                     stru_5C6E00->Atan2((signed __int64)v216, (signed __int64)*(float *)&uRequiredMana));
           }
           a1.stru_24.Reset();
-          a1.field_48 = v3->spellnum;
-          a1.field_4C = v2;
-          a1.field_50 = v731;
+          a1.spell_id = v3->spellnum;
+          a1.spell_level = v2;
+          a1.spell_skill = v731;
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
           a1.uAttributes = 0;
           a1.vPosition.x = LODWORD(v718);
@@ -4794,11 +4791,12 @@
           a1.uSectorID = 0;
           a1.vPosition.z = (int)((char *)_this + LODWORD(v725));
           a1.uSpriteFrameID = 0;
-          a1.field_58_pid = 8 * v3->uPlayerID | OBJECT_Player;
-          a1.field_5C = v730;
+          a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+          a1.spell_target_pid = v730;
+          __debugbreak();
           a1.field_60_distance_related_prolly_lod = stru_50C198._427546((int)&_this[69].uNumCharges);
           a1.uFacing = v685;
-          a1.uSoundID = LOWORD(v3->field_10);
+          a1.uSoundID = LOWORD(v3->sound_id);
           if ( pParty->bTurnBasedModeOn == 1 )
             a1.uAttributes = 4;
           if ( a1.Create(
@@ -4814,9 +4812,12 @@
           HIDWORD(v733) = (unsigned __int64)(v218 % 1024) - 512;
         }
         while ( !v14 );
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
+
       case 23:
-        v219 = v12 - 2;
+        v219 = v731 - 2;
         if ( v219 )
         {
           v220 = v219 - 1;
@@ -4846,7 +4847,7 @@
         HIDWORD(v733) = (int)(char *)&pParty + 2508;
         break;
       case 24:
-        v224 = v12 - 2;
+        v224 = v731 - 2;
         if ( v224 )
         {
           v225 = v224 - 1;
@@ -4873,9 +4874,9 @@
         {
 LABEL_152:
           a1.stru_24.Reset();
-          a1.field_48 = v3->spellnum;
-          a1.field_50 = v731;
-          a1.field_4C = v2;
+          a1.spell_id = v3->spellnum;
+          a1.spell_skill = v731;
+          a1.spell_level = v2;
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
           a1.vPosition.y = pParty->vPosition.y;
           v51 = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
@@ -4888,32 +4889,26 @@
           v52 = pIndoor->GetSector(pParty->vPosition.x, v660, v671);
           a1.uSpriteFrameID = 0;
           a1.uSectorID = v52;
-          v53 = 8 * v3->uPlayerID;
-          LOBYTE(v53) = v53 | OBJECT_Player;
-          a1.field_58_pid = v53;
-          a1.field_5C = a2;
+          a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+          a1.spell_target_pid = a2;
           a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
           a1.uFacing = LOWORD(v715.uYawAngle);
-          a1.uSoundID = LOWORD(v3->field_10);
-LABEL_154:
+          a1.uSoundID = LOWORD(v3->sound_id);
+
           if ( pParty->bTurnBasedModeOn == 1 )
             LOBYTE(a1.uAttributes) |= 4u;
-LABEL_156:
-          v669 = v3->uPlayerID + 1;
-          v36 = v715.uYawAngle;
+
           v659 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-          v654 = v715.uPitchAngle;
-LABEL_157:
-          if ( a1.Create(v36, v654, v659, v669) != -1 && pParty->bTurnBasedModeOn == 1 )
+
+          if ( a1.Create(v715.uYawAngle, v715.uPitchAngle, v659, v3->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
             ++pTurnEngine->field_1C;
         }
         else
         {
-          v732 = SHIDWORD(v733) / (amount - 1);
           a1.stru_24.Reset();
-          a1.field_48 = v3->spellnum;
-          a1.field_4C = v2;
-          a1.field_50 = v731;
+          a1.spell_id = v3->spellnum;
+          a1.spell_level = v2;
+          a1.spell_skill = v731;
           a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
           a1.vPosition.y = pParty->vPosition.y;
           a1.vPosition.x = pParty->vPosition.x;
@@ -4924,12 +4919,10 @@
                            pParty->vPosition.y,
                            pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
           a1.uSpriteFrameID = 0;
-          v226 = 8 * v3->uPlayerID;
-          LOBYTE(v226) = v226 | OBJECT_Player;
-          a1.field_58_pid = v226;
-          a1.field_5C = a2;
+          a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+          a1.spell_target_pid = a2;
           a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-          a1.uSoundID = LOWORD(v3->field_10);
+          a1.uSoundID = LOWORD(v3->sound_id);
           if ( pParty->bTurnBasedModeOn == 1 )
             LOBYTE(a1.uAttributes) |= 4u;
           v227 = SHIDWORD(v733) / -2;
@@ -4947,12 +4940,14 @@
                      v3->uPlayerID + 1) != -1
                 && pParty->bTurnBasedModeOn == 1 )
                 ++pTurnEngine->field_1C;
-              v227 += v732;
+              v227 += SHIDWORD(v733) / (amount - 1);
             }
             while ( v227 <= (signed int)y );
           }
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 27:
         if ( !pPlayers[v3->uPlayerID + 1]->GetMaxMana() )
         {
@@ -4972,16 +4967,15 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
-        v239 = v3->uPlayerID + 1;
-        v732 = v229 << 7;
-        pParty->pPartyBuffs[18].Apply(
+
+        pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].Apply(
           pParty->uTimePlayed + (signed int)(signed __int64)((double)(v229 << 7) * 0.033333335),
           v731,
           amount,
           v716,
-          v239);
+          v3->uPlayerID + 1);
         if ( v731 == 4 )
-          pParty->pPartyBuffs[18].uFlags = 1;
+          pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags = 1;
         LODWORD(v727) = 1;
         goto play_sound_and_continue;
 
@@ -4998,7 +4992,8 @@
 
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2);  // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( v731 == 1 || v731 == 2 )
         {
@@ -5037,10 +5032,14 @@
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2u);
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
           v3->spellnum = 0;
-          goto LABEL_1165;
+          v2 = v723;
+          goto LABEL_1166;
         }
         *((int *)v243 + 5) |= 0x40u;
-        goto LABEL_1055;
+                    dword_50C9A8 = 256;
+                    LODWORD(v727) = 1;
+                    goto play_sound_and_continue;
+
       case 30:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
@@ -5048,7 +5047,6 @@
         HIDWORD(v733) = 10 * v2;
         v730 = 1;
         v244 = (char *)&pParty->pPlayers[v3->uPlayerID_2];
-        v726 = &pParty->pPlayers[v3->uPlayerID_2];
         if ( v731 == 1 )
         {
           v245 = (int)&v244[36 * a2 + 532];
@@ -5106,7 +5104,10 @@
                               *(int *)(v245 + 8) = v256 + v254 % (v255 - v256 + 1);
 LABEL_612:
                               _this->uItemID |= 0x20u;
-                              goto LABEL_1055;
+
+                              dword_50C9A8 = 256;
+                              LODWORD(v727) = 1;
+                              goto play_sound_and_continue;
                             }
                             goto LABEL_615;
                           }
@@ -5133,7 +5134,8 @@
               v317 = pGlobalTXT_LocalizationStrings[585];
             ShowStatusBarString(v317, 2u);
             pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-            v318 = v726;
+            __debugbreak(); // decompilation error;  most probably v318 is the caster, filled in case 54
+            //v318 = v726;
             v3->spellnum = 0;
             v318->PlaySound(SPEECH_43, 0);
           }
@@ -5242,6 +5244,7 @@
           }
           else
           {
+            __debugbreak(); // v726 is most probably the caster, filled in case 54
             if ( v731 != 4
               || (v245 = (int)&v726->pInventoryItems[a2], v246 = *(int *)v245, *(int *)v245 > 134)
               || v726->pInventoryItems[a2].uSpecEnchantmentType != 0
@@ -5369,7 +5372,8 @@
 
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         v292 = *(char *)(LODWORD(v725) + 28);
         if ( !(v292 == 3 | v292 == 4 | v292 == 5 | v292 == 6 | v292 == 7 | v292 == 8 | v292 == 9 | v292 == 10 | v292 == 11) )
@@ -5383,7 +5387,8 @@
 
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( rand() % 100 >= 80 )
         {
@@ -5454,27 +5459,33 @@
                                 + rand() % 10;//(pItemsTable->field_116D8[19] - pItemsTable->field_116D8[18] + 1);
         }
         v294->uAttributes |= 0x20u;
-        goto LABEL_1055;
+        dword_50C9A8 = 256;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case SPELL_WATER_TOWN_PORTAL:
         amount = 10 * v2;
         if ( pPlayer->sMana < (signed int)uRequiredMana )
           goto play_sound_and_continue;
-        if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v12 != 4 || rand() % 100 >= amount && v731 != 4 )
+        if ( pParty->uFlags & (PARTY_FLAGS_1_ALERT_RED | PARTY_FLAGS_1_ALERT_YELLOW) && v731 != 4 || rand() % 100 >= amount && v731 != 4 )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         town_portal_caster_id = LOBYTE(v3->uPlayerID);
         pMessageQueue_50CBD0->AddMessage(UIMSG_OnCastTownPortal, 0, 0);
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
       case 33:
         LODWORD(v733) = 604800 * v2;
         if ( !_strcmpi(pCurrentMapName, "d05.blv") )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         v319 = uRequiredMana;
         if ( pPlayer->sMana >= (signed int)uRequiredMana )
@@ -5485,13 +5496,13 @@
           _506348_current_lloyd_playerid = v3->uPlayerID;
           ::uRequiredMana = v319;
           ::sRecoveryTime = sRecoveryTime;
-          dword_50633C = v3->field_10;
+          dword_50633C = v3->sound_id;
           dword_506338 = v3->spellnum;
           LOBYTE(v3->field_8) |= 0x20u;
         }
         goto play_sound_and_continue;
       case 40:
-        v320 = v12 - 2;
+        v320 = v731 - 2;
         if ( !v320 )
           goto LABEL_632;
         v321 = v320 - 1;
@@ -5513,20 +5524,29 @@
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[15];
         if ( !pParty->pPlayers[v323].pConditions[15] )
-          goto LABEL_1056;
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         if ( v731 == 4 )
-          goto LABEL_637;
+        {
+          *(int *)v324 = 0;
+          *((int *)v324 + 1) = 0;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         v732 = amount << 7;
         v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
         v656 = 15;
         goto LABEL_640;
+
       case 41:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.y = pParty->vPosition.y;
         a1.vPosition.x = pParty->vPosition.x;
@@ -5537,33 +5557,35 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3);
         a1.uSpriteFrameID = 0;
-        v326 = 8 * v3->uPlayerID;
-        LOBYTE(v326) = v326 | OBJECT_Player;
-        a1.field_58_pid = v326;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(pParty->sRotationY);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
-        v669 = v3->uPlayerID + 1;
+
         v659 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        v654 = pParty->sRotationX;
-        goto LABEL_125;
+          if ( a1.Create(pParty->sRotationY, pParty->sRotationX, v659, v3->uPlayerID + 1) != -1 && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->field_1C;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 43:
         if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         a1.uType = 4090;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = pParty->vPosition.x;
         a1.vPosition.y = pParty->vPosition.y;
@@ -5571,26 +5593,22 @@
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
         a1.vPosition.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        v327 = 8 * v3->uPlayerID;
-        LOBYTE(v327) = v327 | OBJECT_Player;
         a1.field_60_distance_related_prolly_lod = 0;
-        a1.field_58_pid = v327;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.uFacing = LOWORD(pParty->sRotationY);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           a1.uAttributes = 4;
-        v669 = 0;
+
         v659 = pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed;
-        v35 = (signed int)stru_5C6E00->uIntegerHalfPi / 2;
-LABEL_124:
-        v654 = v35;
-LABEL_125:
-        v36 = pParty->sRotationY;
-        goto LABEL_157;
+          if ( a1.Create(pParty->sRotationY, stru_5C6E00->uIntegerHalfPi / 2, v659, 0) != -1 && pParty->bTurnBasedModeOn == 1 )
+            ++pTurnEngine->field_1C;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case SPELL_SPIRIT_DETECT_LIFE:
-        v328 = v12 - 2;
+        v328 = v731 - 2;
         if ( v328 )
         {
           v329 = v328 - 1;
@@ -5610,18 +5628,14 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
-        v83 = 1;
-
-        v732 = (int)v733 << 7;
 
          pParty->pPartyBuffs[PARTY_BUFF_DETECT_LIFE].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-          LODWORD(v727) = v83;
-
+       LODWORD(v727) = 1;
         goto play_sound_and_continue;
 
       case SPELL_SPIRIT_FATE:
         LODWORD(v733) = 300;
-        v339 = v12 - 2;
+        v339 = v731 - 2;
         if ( v339 )
         {
           v340 = v339 - 1;
@@ -5653,9 +5667,10 @@
           pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
 
           pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_FATE].Apply(pParty->uTimePlayed + 1280, v731, amount, 0, 0);
-          goto LABEL_1056;
-        }
-        if ( (v342 & 7) == OBJECT_Actor)
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
+        if (PID_TYPE(v342) == OBJECT_Actor)
         {
           v343 = v342 >> 3;
           HIDWORD(v344) = 0 + ((pParty->uTimePlayed + 1280) >> 32);
@@ -5667,10 +5682,11 @@
 LABEL_165:
           pGame->GetStru6()->_4A7E89_sparkles_on_actor_after_it_casts_buff(v661, v672);
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case 49:
-        v348 = v12 - 2;
+        v348 = v731 - 2;
         if ( !v348 )
           goto LABEL_677;
         v349 = v348 - 1;
@@ -5694,23 +5710,31 @@
           goto play_sound_and_continue;
         v351 = &pParty->pPlayers[v3->uPlayerID_2];
         if ( !v351->pConditions[0] )
-          goto LABEL_1056;
+        {
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+        }
         if ( v731 == 4 )
         {
           LODWORD(v351->pConditions[0]) = 0;
           HIDWORD(v351->pConditions[0]) = 0;
-          goto LABEL_904;
-        }
-        v732 = amount << 7;
-        v351->DiscardConditionIfLastsLongerThan(
-          0,
-          (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
-        if ( HIDWORD(pParty->pPlayers[v3->uPlayerID_2].pConditions[0]) | LODWORD(pParty->pPlayers[v3->uPlayerID_2].pConditions[0]) )
-          goto LABEL_1056;
-        v674 = v3->uPlayerID_2;
-        goto LABEL_685;
+        }
+        else
+        {
+          v732 = amount << 7;
+          v351->DiscardConditionIfLastsLongerThan(0, (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
+          if ( HIDWORD(pParty->pPlayers[v3->uPlayerID_2].pConditions[0]) | LODWORD(pParty->pPlayers[v3->uPlayerID_2].pConditions[0]) )
+          {
+            LODWORD(v727) = 1;
+            goto play_sound_and_continue;
+          }
+        }
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case SPELL_SPIRIT_PRESERVATION:
-        v354 = v12 - 2;
+        v354 = v731 - 2;
         if ( v354 && (v355 = v354 - 1) != 0 && v355 == 1 )
           v356 = 900 * (v2 + 4);
         else
@@ -5722,13 +5746,11 @@
         {
           pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
 
-          v732 = (int)v733 << 7;
-
           pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PRESERVATION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, 0, 0, 0);
-          goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
         }
         a2 = 0;
-        v732 = (int)v733 << 7;
         v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
         v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
         do
@@ -5739,9 +5761,12 @@
           ++v357;// = (SpellBuff *)((char *)v357 + 6972);
         }
         while ( v357 <= &pParty->pPlayers[3] );
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 48:
-        v364 = v12 - 2;
+      {
+        v364 = v731 - 2;
         if ( !v364 || (v365 = v364 - 1) != 0 && v365 != 1 )
           v366 = 60 * (v2 + 3);
         else
@@ -5749,46 +5774,43 @@
         LODWORD(v733) = v366;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v726 = (Player *)sub_46A6AC((int)dword_50BF30, 100, 4096);
+        auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xFFFFFFu, 0xC0u);
         ++a1.uType;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v368 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v368 *= 8;
-        LOBYTE(v368) = v368 | OBJECT_Player;
-        a1.field_58_pid = v368;
-        a1.uSoundID = LOWORD(v3->field_10);
-        for ( a2 = 0; a2 < (signed int)v726; ++a2 )
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
+        for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
         {
           v369 = &pActors[dword_50BF30[a2]];
           if ( MonsterStats::BelongsToSupertype(v369->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
           {
             a1.vPosition.x = v369->vPosition.x;
             a1.vPosition.y = v369->vPosition.y;
-            v732 = v369->uActorHeight;
-            a1.vPosition.z = v369->vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-            v370 = 8 * dword_50BF30[a2];
-            LOBYTE(v370) = v370 | OBJECT_Actor;
-            a1.field_5C = v370;
+            a1.vPosition.z = v369->vPosition.z - (unsigned int)(signed __int64)((double)v369->uActorHeight * unk_4D8548);
+
+            a1.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
             a1.Create(0, 0, 0, 0);
-            v732 = (int)v733 << 7;
             v369->pActorBuffs[4].Apply(
               pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
               v731, 0, 0, 0);
           }
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+      }
+        goto play_sound_and_continue;
+
       case 53:
-        v371 = v12 - 2;
+        v371 = v731 - 2;
         if ( v371 && (v372 = v371 - 1) != 0 && v372 == 1 )
           amount = 0;
         else
@@ -5798,7 +5820,10 @@
         pOtherOverlayList->_4418B1(5080, v3->uPlayerID_2 + 100, 0, 65536);
         v373 = v3->uPlayerID_2;
         if ( !(HIDWORD(pParty->pPlayers[v373].pConditions[14]) | LODWORD(pParty->pPlayers[v373].pConditions[14])) )
-          goto LABEL_1056;
+        {
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+        }
         v14 = v731 == 4;
         pParty->pPlayers[v373].sHealth = 1;
         if ( v14 )
@@ -5812,7 +5837,6 @@
         }
         else
         {
-          v732 = amount << 7;
           *(float *)&a2 = (double)(amount << 7) * 0.033333335;
           pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan(
             0xEu,
@@ -5824,7 +5848,7 @@
         v377 = &pParty->pPlayers[v3->uPlayerID_2];
         goto LABEL_720;
       case 54:
-        v378 = v12 - 2;
+        v378 = v731 - 2;
         if ( v378 && (v379 = v378 - 1) != 0 && v379 == 1 )
           v380 = 4 * v2;
         else
@@ -5858,17 +5882,15 @@
         {
           do
           {
-            v385 = 4 * v682[HIDWORD(v733)] + 10965188;
-            pPlayers[v682[HIDWORD(v733)]]->sHealth = v732;
-            v726 = *(Player **)v385;
-            v386 = v726->GetMaxHealth();
-            if ( v726->sHealth > v386 )
-              *(int *)(*(int *)v385 + 6460) = v726->GetMaxHealth();
-            v387 = *(Player **)v385;
-            if ( v387->sHealth > 0 )
+            //v385 = (ItemGen **)&pPlayers[v682[HIDWORD(v733)]];
+            v726 = pPlayers[v682[HIDWORD(v733)]];
+            v726->sHealth = v732;
+            //v386 = v726->GetMaxHealth();
+            if ( v726->sHealth > v726->GetMaxHealth())
+              v726->sHealth = v726->GetMaxHealth();
+            if ( v726->sHealth > 0 )
             {
-              LODWORD(v387->pConditions[13]) = 0;
-              HIDWORD(v387->pConditions[13]) = 0;
+              v726->pConditions[Player::Condition_Unconcious] = 0;
             }
             v388 = HIDWORD(v733);
 
@@ -5877,10 +5899,11 @@
           }
           while ( v388 + 1 < v730 );
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
 
       case 55:
-        v392 = v12 - 1;
+        v392 = v731 - 1;
         if ( !v392 )
         {
           v395 = 180 * v2;
@@ -5925,34 +5948,25 @@
           }
           else
           {
-            v732 = amount << 7;
             *(float *)&a2 = (double)(amount << 7) * 0.033333335;
-            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-              0x10u,
+            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0x10u,
               (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-              0xEu,
+            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xEu,
               (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
-            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-              0xDu,
+            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan( 0xDu,
               (signed __int64)((double)(signed __int64)pParty->uTimePlayed - *(float *)&a2));
           }
-          v83 = 1;
           pParty->pPlayers[v3->uPlayerID_2].SetCondition(1u, 1);
 
           pParty->pPlayers[v3->uPlayerID_2].sHealth = 1;
 
           pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         }
-        else
-        {
-          v83 = 1;
-        }
-          LODWORD(v727) = v83;
+        LODWORD(v727) = 1;
         goto play_sound_and_continue;
 
       case 61:
-        v405 = v12 - 2;
+        v405 = v731 - 2;
         if ( !v405 )
           goto LABEL_766;
         v406 = v405 - 1;
@@ -5979,15 +5993,24 @@
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[12];
         if ( !pParty->pPlayers[v323].pConditions[12] )
-          goto LABEL_1056;
+        {
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+        }
         if ( v731 == 4 )
-          goto LABEL_637;
-        v732 = amount << 7;
+        {
+          *(int *)v324 = 0;
+          *((int *)v324 + 1) = 0;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
         v656 = 12;
         goto LABEL_640;
+
+
       case 56:
-        v411 = v12 - 2;
+        v411 = v731 - 2;
         if ( v411 )
         {
           v412 = v411 - 1;
@@ -6018,19 +6041,30 @@
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[3];
         if ( !pParty->pPlayers[v323].pConditions[3] )
-          goto LABEL_1056;
+        {
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+        }
         if ( v731 == 4 )
-          goto LABEL_637;
-        v732 = amount << 7;
+        {
+          *(int *)v324 = 0;
+          *((int *)v324 + 1) = 0;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
         v656 = 3;
         goto LABEL_640;
+
       case 59:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        if ( a2 == 0 || (a2 & 7) != OBJECT_Actor)
-          goto LABEL_1056;
-        v417 = (int)&pActors[a2 >> 3];
+        if (PID_TYPE(a2) != OBJECT_Actor)
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
+        v417 = (int)&pActors[PID_ID(a2)];
         v730 = v417;
         if ( !(*(char *)(v417 + 38) & 0x80) )
         {
@@ -6088,9 +6122,9 @@
 LABEL_807:
         ShowStatusBarString(pTmpBuf2, 2u);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = *(short *)(v730 + 142);
         a1.vPosition.y = *(short *)(v730 + 144);
@@ -6100,7 +6134,7 @@
         v657 = a1.vPosition.x;
         goto LABEL_1087;
       case 62:
-        v423 = v12 - 2;
+        v423 = v731 - 2;
         if ( !v423 )
           goto LABEL_813;
         v424 = v423 - 1;
@@ -6119,55 +6153,61 @@
         amount = v425;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v426 = a2 >> 3;
-        if ( (a2 & 7) != OBJECT_Actor)
-          goto LABEL_1056;
+        v426 = PID_ID(a2);
+        if (PID_TYPE(a2) != OBJECT_Actor)
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         v730 = 836 * v426;
         if ( stru_50C198.GetMagicalResistance(&pActors[v426], 7u) )
         {
           pActors[v426].pActorBuffs[1].Reset();
           pActors[v426].pActorBuffs[12].Reset();
-          v732 = amount << 7;
           pActors[v426].pActorBuffs[9].Apply(
             pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
             v731, 0, 0, 0);
           pActors[v426].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
         }
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
         v61 = v426;
         goto LABEL_1086;
+
+
       case 66:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         amount = 600 * v2;
-        v427 = a2 >> 3;
-        if ( (a2 & 7) != OBJECT_Actor)
-          goto LABEL_1056;
-        v730 = 836 * v427;
-        if ( MonsterStats::BelongsToSupertype(pActors[v427].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-          goto play_sound_and_continue;
-        if ( stru_50C198.GetMagicalResistance(&pActors[v427], 7u) )
-        {
-          pActors[v427].pActorBuffs[9].Reset();
-          pActors[v427].pActorBuffs[1].Reset();
-          v732 = amount << 7;
-          pActors[v427].pActorBuffs[12].Apply(
-            pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
+        if (PID_TYPE(a2) != OBJECT_Actor)
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
+        v730 = 836 * PID_ID(a2);
+        if ( MonsterStats::BelongsToSupertype(pActors[PID_ID(a2)].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+          goto play_sound_and_continue;
+        if ( stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 7u) )
+        {
+          pActors[PID_ID(a2)].pActorBuffs[9].Reset();
+          pActors[PID_ID(a2)].pActorBuffs[1].Reset();
+          pActors[PID_ID(a2)].pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
             v731, 0, 0, 0);
         }
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
-        v61 = v427;
+        v61 = PID_ID(a2);
         goto LABEL_1086;
+
       case 63:
-        v428 = v12 - 2;
+      {
+        v428 = v731 - 2;
         if ( v428 && (v429 = v428 - 1) != 0 && v429 == 1 )
           v430 = 300 * v2;
         else
@@ -6175,48 +6215,44 @@
         amount = v430;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v726 = (Player *)sub_46A6AC((int)dword_50BF30, 100, 4096);
+        auto _v726 = sub_46A6AC((int)dword_50BF30, 100, 4096);
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0xA0A0Au, 0xC0u);
         ++a1.uType;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v432 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v432 *= 8;
-        LOBYTE(v432) = v432 | OBJECT_Player;
-        a1.field_58_pid = v432;
-        a1.uSoundID = LOWORD(v3->field_10);
-        for ( a2 = 0; a2 < (signed int)v726; ++a2 )
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
+        for ( a2 = 0; a2 < (signed int)_v726; ++a2 )
         {
           v433 = &pActors[dword_50BF30[a2]];
           if ( MonsterStats::BelongsToSupertype(v433->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
             break;
           a1.vPosition.x = v433->vPosition.x;
           a1.vPosition.y = v433->vPosition.y;
-          v732 = v433->uActorHeight;
-          a1.vPosition.z = v433->vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-          v434 = 8 * dword_50BF30[a2];
-          LOBYTE(v434) = v434 | OBJECT_Actor;
-          a1.field_5C = v434;
+          a1.vPosition.z = v433->vPosition.z - (unsigned int)(signed __int64)((double)v433->uActorHeight * unk_4D8548);
+
+          a1.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
           a1.Create(0, 0, 0, 0);
           if ( stru_50C198.GetMagicalResistance(v433, 7u) )
           {
-            v732 = amount << 7;
-            v433->pActorBuffs[4].Apply(
-              pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
+            v433->pActorBuffs[4].Apply(pParty->uTimePlayed + (signed __int64)((double)(amount << 7) * 0.033333335),
               v731, 0, 0, 0);
           }
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+      }
+
       case 64:
-        v435 = v12 - 2;
+        v435 = v731 - 2;
         if ( v435 && (v436 = v435 - 1) != 0 && v436 == 1 )
           amount = 0;
         else
@@ -6238,18 +6274,18 @@
           }
           else
           {
-            v732 = amount << 7;
-            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan(
-              5u,
+            pParty->pPlayers[v3->uPlayerID_2].DiscardConditionIfLastsLongerThan(5u,
               (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335));
           }
           v377 = &pParty->pPlayers[v3->uPlayerID_2];
 LABEL_720:
           v377->SetCondition(1, 0);
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 42:
-        v442 = v12 - 2;
+        v442 = v731 - 2;
         if ( !v442 )
           goto LABEL_855;
         v443 = v442 - 1;
@@ -6268,8 +6304,8 @@
         amount = v444;
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v445 = a2 >> 3;
-        if ( (a2 & 7) == OBJECT_Item)
+        v445 = PID_ID(a2);
+        if (PID_TYPE(a2) == OBJECT_Item)
         {
           v449 = (char *)&pSpriteObjects[v445].stru_24;
           v450 = *(int *)v449;
@@ -6280,7 +6316,7 @@
           }
           else
           {
-            sprintfex(pTmpBuf2, (char*)pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v450].pUnidentifiedName);
+            sprintfex(pTmpBuf2, pGlobalTXT_LocalizationStrings[471], pItemsTable->pItems[v450].pUnidentifiedName);
             ShowStatusBarString(pTmpBuf2, 2u);
             if ( !pParty->AddItem(&pSpriteObjects[v445].stru_24) )
               pParty->SetHoldingItem(&pSpriteObjects[v445].stru_24);
@@ -6289,23 +6325,29 @@
         }
         else
         {
-          if ( (a2 & 7) == OBJECT_Actor)
+          if (PID_TYPE(a2) == OBJECT_Actor)
           {
             stru_50C198.LootActor(&pActors[v445]);
           }
           else
           {
-            if ( (a2 & 7) != OBJECT_Decoration)
+            if (PID_TYPE(a2) != OBJECT_Decoration)
             {
-              if ( (a2 & 7) != OBJECT_BModel)
-                goto LABEL_1056;
+              if (PID_TYPE(a2) != OBJECT_BModel)
+              {
+                LODWORD(v727) = 1;
+                goto play_sound_and_continue;
+              }
               dword_507CD8 = 1;
               v677 = 1;
               if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
                 v446 = pIndoor->pFaceExtras[pIndoor->pFaces[v445].uFaceExtraID].uEventID;
               else
                 v446 = pOutdoor->pBModels[a2 >> 9].pFaces[v445 & 0x3F].sCogTriggeredID;
-              goto LABEL_866;
+
+              EventProcessor(v446, a2, v677);
+              LODWORD(v727) = 1;
+              goto play_sound_and_continue;
             }
             v447 = &pLevelDecorations[v445];
             dword_507CD8 = 1;
@@ -6314,9 +6356,9 @@
             {
               v677 = 1;
               v446 = v448;
-LABEL_866:
               EventProcessor(v446, a2, v677);
-              goto LABEL_1056;
+              LODWORD(v727) = 1;
+              goto play_sound_and_continue;
             }
             if ( v447->IsInteractive() )
             {
@@ -6326,9 +6368,11 @@
             }
           }
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 67:
-        v451 = v12 - 2;
+        v451 = v731 - 2;
         if ( v451 )
         {
           v452 = v451 - 1;
@@ -6359,22 +6403,25 @@
         v323 = v3->uPlayerID_2;
         v324 = (char *)&pParty->pPlayers[v323].pConditions[1];
         if ( !pParty->pPlayers[v323].pConditions[1] )
-          goto LABEL_1056;
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         if ( v731 == 4 )
         {
-LABEL_637:
           *(int *)v324 = 0;
           *((int *)v324 + 1) = 0;
-          goto LABEL_1056;
-        }
-        v732 = amount << 7;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         v663 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed - (double)(amount << 7) * 0.033333335);
         v656 = 1;
 LABEL_640:
         v325 = &pParty->pPlayers[v323];
         goto LABEL_641;
+
       case 68:
-        v457 = v12 - 2;
+        v457 = v731 - 2;
         if ( v457 )
         {
           v458 = v457 - 1;
@@ -6401,16 +6448,13 @@
         if (!v460)
         {
           pParty->pPlayers[v3->uPlayerID_2].Heal(amount);
-LABEL_904:
-          v674 = v3->uPlayerID_2;
-LABEL_685:
-          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v674);
+          pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
         }
         else
         {
-          if ( (v460 & 7) == OBJECT_Actor)
+          if (PID_TYPE(v460) == OBJECT_Actor)
           {
-            v461 = &pActors[v460 >> 3];
+            v461 = &pActors[PID_ID(v460)];
             v462 = v461->uAIState;
             v463 = v461->pMonsterInfo.uHP;
             if ( v462 != 5 )
@@ -6430,9 +6474,11 @@
             }
           }
         }
-        goto LABEL_1056;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 72:
-        v464 = v12 - 2;
+        v464 = v731 - 2;
         if ( !v464 )
           goto LABEL_910;
         v465 = v464 - 1;
@@ -6460,7 +6506,10 @@
         if ( !(HIDWORD(pParty->pPlayers[v470].pConditions[6]) | LODWORD(pParty->pPlayers[v470].pConditions[6]))
           && !(HIDWORD(pParty->pPlayers[v470].pConditions[8]) | LODWORD(pParty->pPlayers[v470].pConditions[8]))
           && !(HIDWORD(pParty->pPlayers[v470].pConditions[10]) | LODWORD(pParty->pPlayers[v470].pConditions[10])) )
-          goto LABEL_1056;
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         if ( v731 == 4 )
         {
           LODWORD(pParty->pPlayers[v470].pConditions[6]) = 0;
@@ -6471,9 +6520,9 @@
           v472 = v3->uPlayerID_2;
           LODWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
           HIDWORD(pParty->pPlayers[v472].pConditions[10]) = 0;
-          goto LABEL_1056;
-        }
-        v732 = amount << 7;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         *(float *)&a2 = (double)(amount << 7) * 0.033333335;
         pParty->pPlayers[v470].DiscardConditionIfLastsLongerThan(
           6u,
@@ -6497,10 +6546,9 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
 
-        v732 = (int)v733 << 7;
-
         pParty->pPartyBuffs[PARTY_BUFF_PROTECTION_FROM_MAGIC].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, 0, 0);
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
 
       case 73:
         LODWORD(v733) = 3600 * v2;
@@ -6520,17 +6568,17 @@
           pParty->pPlayers[2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4u, v2, v2, 0);
 
           pParty->pPlayers[3].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + v717, 4, v2, v2, 0);
-          goto LABEL_1056;
-          //goto LABEL_104;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
         }
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
 
-        v732 = (int)v733 << 7;
-
         pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v2, v2, 0);
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 74:
-        v493 = v12 - 2;
+        v493 = v731 - 2;
         if ( v493 && (v494 = v493 - 1) != 0 && v494 == 1 )
           amount = 0;
         else
@@ -6543,7 +6591,10 @@
         if ( !(HIDWORD(pParty->pPlayers[v498].pConditions[7]) | LODWORD(pParty->pPlayers[v498].pConditions[7]))
           && !(HIDWORD(pParty->pPlayers[v498].pConditions[9]) | LODWORD(pParty->pPlayers[v498].pConditions[9]))
           && !(HIDWORD(pParty->pPlayers[v498].pConditions[11]) | LODWORD(pParty->pPlayers[v498].pConditions[11])) )
-          goto LABEL_1056;
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
         if ( v731 == 4 )
         {
           LODWORD(pParty->pPlayers[v498].pConditions[7]) = 0;
@@ -6557,7 +6608,6 @@
         }
         else
         {
-          v732 = amount << 7;
           *(float *)&a2 = (double)(amount << 7) * 0.033333335;
           pParty->pPlayers[v498].DiscardConditionIfLastsLongerThan(
             7u,
@@ -6572,7 +6622,9 @@
 LABEL_641:
           v325->DiscardConditionIfLastsLongerThan(v656, v663);
         }
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 77:
       {
         amount = 5 * v2 + 10;
@@ -6588,7 +6640,8 @@
           ++v1;
         }
         while ( (signed int)v501 < (signed int)pParty->pHirelings );
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
       }
       case 80:
         sRecoveryTime -= v2;
@@ -6599,24 +6652,21 @@
         v505 = sub_46A6AC((int)dword_50BF30, 100, 4096);
         ++a1.uType;
         HIDWORD(v733) = v505;
-        v690 = 0;
-        v689 = 0;
-        v688 = 0;
+        v688.x = 0;
+        v688.y = 0;
+        v688.z = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v506 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v506 *= 8;
-        LOBYTE(v506) = v506 | OBJECT_Player;
-        a1.field_58_pid = v506;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
         if ( SHIDWORD(v733) > 0 )
         {
@@ -6625,14 +6675,11 @@
             v507 = dword_50BF30[a2];
             a1.vPosition.x = pActors[v507].vPosition.x;
             a1.vPosition.y = pActors[v507].vPosition.y;
-            v732 = pActors[v507].uActorHeight;
-            a1.vPosition.z = pActors[v507].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-            v508 = 8 * dword_50BF30[a2];
-            LOBYTE(v508) = v508 | OBJECT_Actor;
-            a1.field_5C = v508;
+            a1.vPosition.z = pActors[v507].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v507].uActorHeight * unk_4D8548);
+            a1.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
             v509 = a1.Create(0, 0, 0, 0);
             v510 = a2;
-            DamageMonsterFromParty(8 * v509 | OBJECT_Item, dword_50BF30[a2], (Vec3_int_ *)&v688);
+            DamageMonsterFromParty(PID(OBJECT_Item, v509), dword_50BF30[a2], (Vec3_int_ *)&v688);
             a2 = v510 + 1;
           }
           while ( v510 + 1 < SHIDWORD(v733) );
@@ -6642,25 +6689,21 @@
           v511 = &pActors[dword_50BF30[a2]];
           a1.vPosition.x = v511->vPosition.x;
           a1.vPosition.y = v511->vPosition.y;
-          v732 = v511->uActorHeight;
-          a1.vPosition.z = v511->vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-          v512 = 8 * dword_50BF30[a2];
-          LOBYTE(v512) = v512 | OBJECT_Actor;
-          a1.field_5C = v512;
+          a1.vPosition.z = v511->vPosition.z - (unsigned int)(signed __int64)((double)v511->uActorHeight * unk_4D8548);
+          a1.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
           a1.Create(0, 0, 0, 0);
           v513 = v511->pActorBuffs;
-          v726 = (Player *)22;
-          do
+          for (int _v726 = 22; _v726 != 0; --_v726)
           {
             v513->Reset();
             ++v513;
-            v726 = (Player *)((char *)v726 - 1);
           }
-          while ( *(float *)&v726 != 0.0 );
-        }
-        goto LABEL_1056;
+        }
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 82:
-        v514 = v12 - 2;
+        v514 = v731 - 2;
         if ( !v514 )
           goto LABEL_955;
         v515 = v514 - 1;
@@ -6684,34 +6727,36 @@
           amount = 3;
         }
         v733 = __PAIR__(0, v516);
-        v517 = 8 * v3->uPlayerID;
-        LOBYTE(v517) = v517 | 4;
+
         if ( (signed int)uNumActors > 0 )
         {
           v518 = pActors;//[0].uAIState;
-          v726b = uNumActors;
+          auto _v726 = uNumActors;
           do
           {
 			v519 = v518->uAIState;
-			if ( v518->uAIState != 5 && v519 != 11 && v519 != 19 && v517 == v518->uSummonerID )
+			if ( v518->uAIState != 5 && v519 != 11 && v519 != 19 && PID(OBJECT_Player, v3->uPlayerID) == v518->uSummonerID )
               ++HIDWORD(v733);
             ++v518;
-            --v726;
+            --_v726;
           }
-          while ( v726 != 0 );
+          while ( _v726 != 0 );
         }
         if ( SHIDWORD(v733) >= amount )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[648], 2);  // This character can't summon any more monsters!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         sub_44FA4C_spawn_light_elemental(v3->uPlayerID, v731, v733);
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 83:
-        v520 = v12 - 2;
+        v520 = v731 - 2;
         if ( !v520 )
           goto LABEL_973;
         v521 = v520 - 1;
@@ -6742,13 +6787,9 @@
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 1);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 2);
         pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, 3);
-        v83 = 1;
-
-        v732 = (int)v733 << 7;
 
         pParty->pPartyBuffs[PARTY_BUFF_DAY_OF_GODS].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, amount, 0, 0);
-          LODWORD(v727) = v83;
-
+        LODWORD(v727) = 1;
         goto play_sound_and_continue;
 
       case 84:
@@ -6757,57 +6798,53 @@
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[497], 2);  // Can't cast Prismatic Light outdoors!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
         v531 = sub_46A6AC((int)dword_50BF30, 100, 4096);
         ++a1.uType;
-        v726 = (Player *)v531;
-        v696 = 0;
-        v695 = 0;
-        v694 = 0;
+        v694.x = 0;
+        v694.y = 0;
+        v694.z = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v532 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v532 *= 8;
-        LOBYTE(v532) = v532 | OBJECT_Player;
-        a1.field_58_pid = v532;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
-        if ( (signed int)v726 > 0 )
+        if ( (signed int)v531 > 0 )
         {
           do
           {
             v533 = dword_50BF30[a2];
             a1.vPosition.x = pActors[v533].vPosition.x;
             a1.vPosition.y = pActors[v533].vPosition.y;
-            v732 = pActors[v533].uActorHeight;
-            a1.vPosition.z = pActors[v533].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-            v534 = 8 * dword_50BF30[a2];
-            LOBYTE(v534) = v534 | OBJECT_Actor;
-            a1.field_5C = v534;
+            a1.vPosition.z = pActors[v533].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v533].uActorHeight * unk_4D8548);
+            a1.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
             v535 = a1.Create(0, 0, 0, 0);
             v536 = a2;
-            DamageMonsterFromParty(8 * v535 | OBJECT_Item, dword_50BF30[a2], (Vec3_int_ *)&v694);
+            DamageMonsterFromParty(PID(OBJECT_Item, v535), dword_50BF30[a2], &v694);
             a2 = v536 + 1;
           }
-          while ( v536 + 1 < (signed int)v726 );
+          while ( v536 + 1 < (signed int)v531 );
         }
         v537 = pGame->GetStru6();
         pGame->GetStru6()->_4A8BFC();
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
 
       case SPELL_LIGHT_DAY_OF_PROTECTION:
-        v538 = v12 - 2;
+      {
+        v538 = v731 - 2;
         if ( v538 && (v539 = v538 - 1) != 0 && v539 == 1 )
         {
           amount = 5 * v2;
@@ -6845,9 +6882,13 @@
           v550, 0, 0);
 
         pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v550, 0, 0);
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+      }
+
       case 86:
-        v551 = v12 - 2;
+      {
+        v551 = v731 - 2;
         if ( !v551 )
           goto LABEL_998;
         v552 = v551 - 1;
@@ -6874,7 +6915,7 @@
         y = (char *)(60 * (v2 * HIDWORD(v733) + 60));
         v732 = (300 * amount * v2 + 60) << 7;
         v730 = v2 + 5;
-        v726 = 0;
+        int _v726 = 0;
         v553 = pParty->pPlayers;//[0].pConditions[1];
         *((float *)&v733 + 1) = (double)v732 * 0.033333335;
         do
@@ -6887,7 +6928,7 @@
           //((SpellBuff *)(v553 + 6056))->Apply(
 		  v553->pPlayerBuffs[4].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v730, 0, 0);
           if ( *(_QWORD *)v553 )
-            v726 = (Player *)1;
+            _v726 = 1;
           ++v553;
         }
         while ( v553 <= &pParty->pPlayers[3] );
@@ -6895,18 +6936,23 @@
         pParty->pPartyBuffs[PARTY_BUFF_HEROISM].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v731, v730, 0, 0);
         pParty->pPartyBuffs[PARTY_BUFF_SHIELD].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v562, 0, 0, 0);
         pParty->pPartyBuffs[PARTY_BUFF_STONE_SKIN].Apply((signed __int64)((double)(signed __int64)pParty->uTimePlayed + *((float *)&v733 + 1)), v562, v730, 0, 0);
-        if (v726)
-          goto LABEL_1056;
-        v732 = (int)y << 7;
-        pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply((signed __int64)((double)(signed int)((int)y << 7) * 0.033333335 + (double)(signed __int64)pParty->uTimePlayed), v562, v730, 0, 0);
-        goto LABEL_1056;
+        if (!_v726)
+        {
+          pParty->pPartyBuffs[PARTY_BUFF_HASTE].Apply((signed __int64)((double)(signed int)((int)y << 7) * 0.033333335 + (double)(signed __int64)pParty->uTimePlayed), v562, v730, 0, 0);
+        }
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+      }
+
+
       case 88:
         amount = 3;
         if ( pPlayer->uNumDivineInterventionCastsThisDay >= 3u )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
@@ -6941,9 +6987,11 @@
           *(short *)v572 = pPlayer->sAgeModifier + 10;
         sRecoveryTime += -5 * v2;
         ++v571->uNumDivineInterventionCastsThisDay;
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 89:
-        v573 = v12 - 2;
+        v573 = v731 - 2;
         if ( v573 )
         {
           v574 = v573 - 1;
@@ -6981,12 +7029,13 @@
           goto play_sound_and_continue;
         }
         v577 = (Player *)(v576 >> 3);
-        v726 = v577;
+        //v726 = v577;
         if ( v577 == (Player *)-1 )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[496], 2);  // No valid target exists!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         v578 = (int)&pActors[(int)v577];
         v721 = v578;
@@ -6994,36 +7043,32 @@
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         ++a1.uType;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v580 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         v581 = v721;
-        v580 *= 8;
-        LOBYTE(v580) = v580 | OBJECT_Player;
         a1.uFacing = 0;
-        a1.field_58_pid = v580;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a1.vPosition.x = *(short *)(v721 + 142);
         a1.vPosition.y = *(short *)(v721 + 144);
         v732 = *(short *)(v721 + 138);
-        v582 = 8 * (int)v726;
         a1.vPosition.z = *(short *)(v721 + 146) - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-        LOBYTE(v582) = 8 * (char)v726 | OBJECT_Actor;
-        a1.field_5C = v582;
+        a1.spell_target_pid = PID(OBJECT_Actor, (int)v577);
         a1.Create(0, 0, 0, 0);
         if ( *(char *)(v581 + 52) > amount )
           goto play_sound_and_continue;
-        Actor::Resurrect((unsigned int)v726);
+        Actor::Resurrect((unsigned int)v577);
         *(char *)(v581 + 61) = 0;
         *(char *)(v581 + 53) = 0;
         *(char *)(v581 + 54) = 0;
@@ -7038,9 +7083,11 @@
         ((SpellBuff *)(v581 + 404))->Reset();
         if ( *(short *)(v581 + 40) > 10 * amount )
           *(short *)(v581 + 40) = 10 * amount;
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 91:
-        v588 = v12 - 1;
+        v588 = v731 - 1;
         amount = 16;
         if ( v588 && (v589 = v588 - 1) != 0 && (v590 = v589 - 1) != 0 )
         {
@@ -7053,6 +7100,7 @@
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
+        __debugbreak();
         HIDWORD(v733) = (int)(char *)&pParty + 6972 * v3->uPlayerID_2 + 36 * a2 + 3040;
         v732 = (signed int)&pItemsTable->pItems[*(int *)HIDWORD(v733)].pIconName;
         ((ItemGen *)HIDWORD(v733))->UpdateTempBonus(pParty->uTimePlayed);
@@ -7069,7 +7117,8 @@
 
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         v592 = HIDWORD(v733);
         v14 = v731 == 4;
@@ -7077,14 +7126,17 @@
         if ( !v14 )
         {
           v732 = (int)v733 << 7;
-          *(_QWORD *)(v592 + 28) = pParty->uTimePlayed
-                                 + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
+          *(_QWORD *)(v592 + 28) = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
           *(int *)(v592 + 20) |= 8u;
         }
         *(char *)(v592 + 20) |= 0x80u;
-        goto LABEL_1055;
+        dword_50C9A8 = 256;
+        LODWORD(v727) = 1;
+        goto play_sound_and_continue;
+
       case 93:
-        v593 = v12 - 2;
+      {
+        v593 = v731 - 2;
         if ( !v593 )
           goto LABEL_1062;
         v594 = v593 - 1;
@@ -7102,12 +7154,11 @@
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v726 = (Player *)((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
-        v732 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (amount - 1);
+        auto _v726 = ((signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.vPosition.x = pParty->vPosition.x;
         a1.vPosition.y = pParty->vPosition.y;
@@ -7118,17 +7169,15 @@
                          pParty->vPosition.y,
                          pParty->vPosition.z + (signed int)pParty->uPartyHeight / 2);
         a1.uSpriteFrameID = 0;
-        v595 = 8 * v3->uPlayerID;
-        LOBYTE(v595) = v595 | OBJECT_Player;
-        a1.field_58_pid = v595;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.uSoundID = LOWORD(v3->sound_id);
         if ( pParty->bTurnBasedModeOn == 1 )
           LOBYTE(a1.uAttributes) |= 4u;
-        v596 = (signed int)v726 / -2;
-        y = (char *)((signed int)v726 / 2);
-        if ( (signed int)v726 / -2 <= (signed int)v726 / 2 )
+        v596 = (signed int)_v726 / -2;
+        y = (char *)((signed int)_v726 / 2);
+        if ( (signed int)_v726 / -2 <= (signed int)_v726 / 2 )
         {
           v597 = v715.uYawAngle;
           do
@@ -7141,11 +7190,14 @@
                    v3->uPlayerID + 1) != -1
               && pParty->bTurnBasedModeOn == 1 )
               ++pTurnEngine->field_1C;
-            v596 += v732;
+            v596 += _v726 / (amount - 1);
           }
           while ( v596 <= (signed int)y );
         }
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+      }
+
       case 94:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
@@ -7164,30 +7216,31 @@
         if ( v731 == 4 )
           LODWORD(v733) = 29030400;
 LABEL_1082:
-        v599 = a2 >> 3;
-        if ( (a2 & 7) != OBJECT_Actor)
-          goto LABEL_1056;
-        v730 = 836 * v599;
-        if ( !MonsterStats::BelongsToSupertype(pActors[v599].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
-          goto play_sound_and_continue;
-        if ( !stru_50C198.GetMagicalResistance(&pActors[v599], 0xAu) )
+        if (PID_TYPE(a2) != OBJECT_Actor)
+        {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+        }
+        v730 = 836 * PID_ID(a2);
+        if ( !MonsterStats::BelongsToSupertype(pActors[PID_ID(a2)].pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD) )
+          goto play_sound_and_continue;
+        if ( !stru_50C198.GetMagicalResistance(&pActors[PID_ID(a2)], 0xAu) )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
-        }
-        pActors[v599].pActorBuffs[9].Reset();
-        pActors[v599].pActorBuffs[1].Reset();
-        v732 = (int)v733 << 7;
-        pActors[v599].pActorBuffs[12].Apply(
-          pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
+          v3->spellnum = 0;
+          goto LABEL_1166;
+        }
+        pActors[PID_ID(a2)].pActorBuffs[9].Reset();
+        pActors[PID_ID(a2)].pActorBuffs[1].Reset();
+        pActors[PID_ID(a2)].pActorBuffs[12].Apply(pParty->uTimePlayed + (signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335),
           v731, 0, 0, 0);
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         v60 = pObjectList->ObjectIDByItemID(a1.uType);
-        v61 = v599;
+        v61 = PID_ID(a2);
 LABEL_1086:
         v600 = pActors[v61].vPosition.y;
         v601 = pActors[v61].vPosition.x;
@@ -7204,17 +7257,16 @@
         a1.uAttributes = 0;
         a1.uSectorID = pIndoor->GetSector(v657, v665, v676);
         a1.uSpriteFrameID = 0;
-        v604 = 8 * v3->uPlayerID;
-        LOBYTE(v604) = v604 | OBJECT_Player;
-        a1.field_58_pid = v604;
-        a1.field_5C = a2;
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.spell_target_pid = a2;
         a1.field_60_distance_related_prolly_lod = LOBYTE(v715.uDistance);
         a1.uFacing = LOWORD(v715.uYawAngle);
-        LOWORD(v604) = LOWORD(v3->field_10);
         LOBYTE(a1.uAttributes) |= 0x80u;
-        a1.uSoundID = v604;
+        a1.uSoundID = LOWORD(v3->sound_id);
         a1.Create(0, 0, 0, v3->uPlayerID + 1);
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 96:
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
@@ -7260,7 +7312,8 @@
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         v610 = 76 * v609;
         *((int *)&pParty->pPlayers[3].pInstalledBeacons[4].uBeaconTime + 19 * v609) = 0;
@@ -7284,15 +7337,15 @@
         LODWORD(v727) = 1;
         goto play_sound_and_continue;
       case 95:
-        if ( v12 <= 0 )
+        if ( v731 <= 0 )
           goto LABEL_1119;
-        if ( v12 <= 3 )
+        if ( v731 <= 3 )
         {
           v614 = 300 * (v2 + 12);
         }
         else
         {
-          if ( v12 != 4 )
+          if ( v731 != 4 )
             goto LABEL_1119;
           v614 = 900 * (v2 + 4);
         }
@@ -7306,13 +7359,11 @@
         {
           pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, v3->uPlayerID_2);
 
-          v732 = (int)v733 << 7;
-
           pParty->pPlayers[v3->uPlayerID_2].pPlayerBuffs[PLAYER_BUFF_PAIN_REFLECTION].Apply(pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335), v731, v615, v716, 0);
-          goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
         }
         a2 = 0;
-        v732 = (int)v733 << 7;
         v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
         v619 = pParty->pPlayers;//[0].pPlayerBuffs[10];
         do
@@ -7323,49 +7374,47 @@
           ++v619;
         }
         while ( v619 <= &pParty->pPlayers[3] );
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+
       case 99:
+      {
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
-        v726 = 0;
         pGame->GetIndoorCamera();
         v623 = (signed __int64)GetPickDepth();
         HIDWORD(v733) = sub_46A6AC((int)dword_50BF30, 100, v623);
-        v709 = 0;
-        v708 = 0;
-        v707 = 0;
+        v707.x = 0;
+        v707.y = 0;
+        v707.z = 0;
         a1.stru_24.Reset();
-        a1.field_48 = v3->spellnum;
-        a1.field_4C = v2;
-        a1.field_50 = v731;
+        a1.spell_id = v3->spellnum;
+        a1.spell_level = v2;
+        a1.spell_skill = v731;
         a1.uObjectDescID = pObjectList->ObjectIDByItemID(a1.uType);
         a1.uAttributes = 0;
         a1.uSectorID = 0;
         a1.uSpriteFrameID = 0;
-        v624 = v3->uPlayerID;
         a1.field_60_distance_related_prolly_lod = 0;
         a1.uFacing = 0;
-        v624 *= 8;
-        LOBYTE(v624) = v624 | OBJECT_Player;
-        a1.field_58_pid = v624;
-        a1.uSoundID = LOWORD(v3->field_10);
+        a1.spell_caster_pid = PID(OBJECT_Player, v3->uPlayerID);
+        a1.uSoundID = LOWORD(v3->sound_id);
         a2 = 0;
+        int _v726 = 0;
         if ( SHIDWORD(v733) > 0 )
         {
-          v726 = (Player *)(HIDWORD(v733) * (7 * v2 + 25));
+          _v726 = (HIDWORD(v733) * (7 * v2 + 25));
           do
           {
             v625 = dword_50BF30[a2];
             a1.vPosition.x = pActors[v625].vPosition.x;
             a1.vPosition.y = pActors[v625].vPosition.y;
-            v732 = pActors[v625].uActorHeight;
-            a1.vPosition.z = pActors[v625].vPosition.z - (unsigned int)(signed __int64)((double)v732 * unk_4D8548);
-            v626 = 8 * dword_50BF30[a2];
-            LOBYTE(v626) = v626 | OBJECT_Actor;
-            a1.field_5C = v626;
+            //v732 = pActors[v625].uActorHeight;
+            a1.vPosition.z = pActors[v625].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v625].uActorHeight * unk_4D8548);
+            a1.spell_target_pid = PID(OBJECT_Actor, dword_50BF30[a2]);
             v627 = a1.Create(0, 0, 0, 0);
             v628 = a2;
-            DamageMonsterFromParty(8 * v627 | 2, dword_50BF30[a2], (Vec3_int_ *)&v707);
+            DamageMonsterFromParty(PID(OBJECT_Item, v627), dword_50BF30[a2], &v707);
             a2 = v628 + 1;
           }
           while ( v628 + 1 < SHIDWORD(v733) );
@@ -7388,19 +7437,20 @@
           ++v629;
         }
         while ( v629 <= 4 );
-        v732 = (signed __int64)((double)(signed int)v726 / (double)v730);
+        v732 = (signed __int64)((double)(signed int)_v726 / (double)v730);
         HIDWORD(v733) = 0;
         if ( v730 > 0 )
         {
           do
           {
-            v632 = 4 * v681[HIDWORD(v733)] + 10965188;
-            v633 = pPlayers[v681[HIDWORD(v733)]];
-            v633->sHealth += v732;
-            v726 = *(Player **)v632;
-            v634 = v726->GetMaxHealth();
-            if ( v726->sHealth > v634 )
-              *(int *)(*(int *)v632 + 6460) = v726->GetMaxHealth();
+            //v632 = 4 * v681[HIDWORD(v733)] + 10965188;
+            v726 = pPlayers[v681[HIDWORD(v733)]];
+            //v633 = pPlayers[v681[HIDWORD(v733)]];
+            v726->sHealth += v732;
+            //v726 = *(Player **)v632;
+            //v634 = v726->GetMaxHealth();
+            if ( v726->sHealth > v726->GetMaxHealth())
+              v726->sHealth = v726->GetMaxHealth();
             v635 = HIDWORD(v733);
 
             pGame->GetStru6()->SetPlayerBuffAnim(v3->spellnum, WORD2(v733));
@@ -7409,22 +7459,28 @@
           while ( v635 + 1 < v730 );
         }
         pGame->GetStru6()->FadeScreen__like_Turn_Undead_and_mb_Armageddon(0, 0x40u);
-        goto LABEL_1056;
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+      }
+
       case 98:
+      {
         if ( uCurrentlyLoadedLevelType == LEVEL_Indoor)
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[499], 2);  // Can't cast Armageddon indoors!
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
-        }
-        v640 = v12 - 2;
+          v3->spellnum = 0;
+          goto LABEL_1166;
+        }
+        v640 = v731 - 2;
         if ( !v640 || (v641 = v640 - 1) == 0 || (amount = 4, v641 != 1) )
           amount = 3;
         if ( pPlayer->uNumArmageddonCasts >= amount || pParty->armageddon_timer > 0 )
         {
           ShowStatusBarString(pGlobalTXT_LocalizationStrings[428], 2); // Spell failed
           pAudioPlayer->PlaySound(SOUND_PlayerCantCastSpell, 0, 0, -1, 0, 0, 0, 0);
-          goto LABEL_203;
+          v3->spellnum = 0;
+          goto LABEL_1166;
         }
         if ( !pPlayer->CanCastSpell(uRequiredMana) )
           goto play_sound_and_continue;
@@ -7433,7 +7489,7 @@
         ++pPlayer->uNumArmageddonCasts;
         if ( pParty->bTurnBasedModeOn == 1 )
           ++pTurnEngine->field_1C;
-        v726 = (Player *)50;
+        auto _v726 = 50;
         do
         {
           v642 = rand() % 4096 - 2048;
@@ -7443,10 +7499,13 @@
           v732 = GetTerrainHeightsAroundParty2(v642 + pParty->vPosition.x, (int)y, (int *)&v710, 0);
           v644 = rand();
           sub_42F7EB_DropItemAt(0xFE6u, v721, (int)y, v732 + 16, v644 % 500 + 500, 1, 0, 0, 0);
-          v726 = (Player *)((char *)v726 - 1);
-        }
-        while ( *(float *)&v726 != 0.0 );
-        goto LABEL_1056;
+          --_v726;
+        }
+        while ( _v726 != 0 );
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+      }
+
       default:
         goto play_sound_and_continue;
     }
@@ -7463,7 +7522,6 @@
       }
       else
       {
-        v732 = amount << 7;
         v223 = ((Player *)v222)->DiscardConditionIfLastsLongerThan(
                  2u,
                  pParty->uTimePlayed - (signed int)(signed __int64)((double)(amount << 7) * 0.033333335));
@@ -7475,7 +7533,10 @@
       v222 += 6972;
       HIDWORD(v733) = (int)v222;
       if ( (signed int)v222 >= (signed int)pParty->pHirelings )
-        goto LABEL_1056;
+      {
+          LODWORD(v727) = 1;
+          goto play_sound_and_continue;
+      }
       continue;
     }
 }
@@ -7780,7 +7841,7 @@
     a3.z = actor->vPosition.z - pParty->vPosition.z;
     Vec3_int_::Normalize(&a3.x, &a3.y, &a3.z);
 
-    DamageMonsterFromParty((8 * (uActiveCharacter - 1)) | OBJECT_Player, target_id, &a3);
+    DamageMonsterFromParty(PID(OBJECT_Player, uActiveCharacter - 1), target_id, &a3);
     if (player->WearsItem(ITEM_ARTIFACT_SPLITTER, 1) || player->WearsItem(ITEM_ARTIFACT_SPLITTER, 0))
           _42FA66_do_explosive_impact(
             actor->vPosition.x,
@@ -7908,9 +7969,9 @@
             {
               v22 = *v28;
               v11 = *v28 & 0xFFFF;
-              if ( (*(char *)v28 & 7) == OBJECT_Actor)
+              if (PID_TYPE(v11) == OBJECT_Actor)
               {
-                v12 = &pActors[(unsigned int)v11 >> 3];
+                v12 = &pActors[PID_ID(v11)];
                 v13 = v12->uAIState;
                 if ( v13 != 5 )
                 {
@@ -7918,7 +7979,7 @@
                     && v13 != 11
                     && v13 != 19
                     && v13 != 17
-                    && (!a3 || pActors[(unsigned int)v11 >> 3].GetActorsRelation(0)) )
+                    && (!a3 || pActors[PID_ID(v11)].GetActorsRelation(0)) )
                   {
                     if ( (!a4 || MonsterStats::BelongsToSupertype(v12->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD))
                       && v22 <= pick_depth << 16 )
@@ -8147,9 +8208,9 @@
     v9 = v22;
   }
   v10 = 0;
-  a1a.field_50 = 0;
-  a1a.field_4C = 0;
-  a1a.field_48 = 0;
+  a1a.spell_skill = 0;
+  a1a.spell_level = 0;
+  a1a.spell_id = 0;
   a1a.field_54 = 0;
   a1a.uType = v9;
   if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -8177,8 +8238,8 @@
   a1a.uAttributes = attributes;
   a1a.uSectorID = pIndoor->GetSector(v21, y, z);
   a1a.uSpriteFrameID = 0;
-  a1a.field_58_pid = 0;
-  a1a.field_5C = 0;
+  a1a.spell_caster_pid = 0;
+  a1a.spell_target_pid = 0;
   if ( !(a1a.uAttributes & 0x10) )
   {
     v13 = 0;
@@ -8253,9 +8314,9 @@
   a1.stru_24.Reset();
 
   v5 = 0;
-  a1.field_50 = 0;
-  a1.field_4C = 0;
-  a1.field_48 = 0;
+  a1.spell_skill = 0;
+  a1.spell_level = 0;
+  a1.spell_id = 0;
   a1.field_54 = 0;
   a1.uType = 800;
   if ( (signed int)pObjectList->uNumObjects <= 0 )
@@ -8283,8 +8344,8 @@
   a1.uAttributes = 0;
   a1.uSectorID = pIndoor->GetSector(v3, v4, z);
   a1.uSpriteFrameID = 0;
-  a1.field_58_pid = 0;
-  a1.field_5C = 0;
+  a1.spell_caster_pid = 0;
+  a1.spell_target_pid = 0;
   v8 = a1.Create(0, 0, 0, 0);
   if ( v8 != -1 )
   {
@@ -8303,9 +8364,9 @@
   int v7; // esi@1
   char *v8; // ecx@2
   unsigned __int16 v9; // ax@5
-  int v10; // eax@10
+  //int v10; // eax@10
   signed int result; // eax@11
-  __int16 v12; // ax@12
+  //__int16 v12; // ax@12
   //SpriteObject a1a; // [sp+Ch] [bp-74h]@1
   int v14; // [sp+7Ch] [bp-4h]@1
 
@@ -8316,9 +8377,9 @@
   a1a.uType = 600;
   a1a.stru_24.Reset();
 
-  a1a.field_48 = 6;
-  a1a.field_4C = 8;
-  a1a.field_50 = 3;
+  a1a.spell_id = SPELL_FIRE_FIREBALL;
+  a1a.spell_level = 8;
+  a1a.spell_skill = 3;
   v14 = 0;
   if ( (signed int)pObjectList->uNumObjects <= 0 )
   {
@@ -8344,27 +8405,22 @@
   a1a.uAttributes = 0;
   a1a.uSectorID = pIndoor->GetSector(v6, v7, a3);
   a1a.uSpriteFrameID = 0;
-  a1a.field_5C = 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 )
   {
-    v10 = 8 * a6 - 8;
-    LOBYTE(v10) = v10 | OBJECT_Player;
-    a1a.field_58_pid = v10;
+    a1a.spell_caster_pid = PID(OBJECT_Player, a6 - 1);
   }
   else
   {
-    a1a.field_58_pid = 0;
+    a1a.spell_caster_pid = 0;
   }
   result = a1a.Create(0, 0, 0, 0);
   if ( result != -1 )
   {
-    v12 = 8 * result;
-    LOBYTE(v12) = v12 | 2;
-    result = stru_50FE08.Add(
-               v12,
+    result = stru_50FE08.Add(PID(OBJECT_Item, result),
                a5,
                SLOWORD(a1a.vPosition.x),
                SLOWORD(a1a.vPosition.y),
@@ -8455,7 +8511,7 @@
 void __cdecl ProcessInputActions()
 {
   ActionQueue *pActionQueue; // esi@7
-  Keyboard *v3; // ecx@8
+  //Keyboard *v3; // ecx@8
   char v4; // al@9
   ActionQueue *v5; // ecx@19
   Player *v6; // ecx@86
@@ -8503,12 +8559,11 @@
     pActionQueue = pPartyActionQueue;
     while ( 1 )
     {
-      v3 = pGame->pKeyboardInstance;
       v17 = pKeyActionMap->pVirtualKeyCodesMapping[inputAction];
       if ( pKeyActionMap->pToggleTypes[inputAction] )
-        v4 = v3->WasKeyPressed(v17);
+        v4 = pKeyboard->WasKeyPressed(v17);
       else
-        v4 = v3->IsKeyBeingHeld(v17);
+        v4 = pKeyboard->IsKeyBeingHeld(v17);
       if ( v4 )
       {
         switch ( inputAction )
@@ -8701,8 +8756,7 @@
               {
                 v24 = v6->GetAttackRecoveryTime(false);
                 if ( !pParty->bTurnBasedModeOn )
-                  pPlayers[uActiveCharacter]->SetRecoveryTime(
-                    (signed __int64)(flt_6BE3A4_debug_recmod1 * (double)v24 * 2.133333333333333));
+                  pPlayers[uActiveCharacter]->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)v24 * 2.133333333333333));
                 pStru277->_427D48(uActiveCharacter);
                 pTurnEngine->_40471C();
               }
@@ -8714,7 +8768,7 @@
             {
               if (pParty->bTurnBasedModeOn)
               {
-                if ( pTurnEngine->field_4 == OBJECT_Actor || (pTurnEngine->pQueue[0].uPackedID & 7) == OBJECT_Player)
+                if (pTurnEngine->field_4 == OBJECT_Actor || PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
                 {
                   pParty->bTurnBasedModeOn = 0;
                   pTurnEngine->End(true);
--- a/mm7_data.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_data.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -1402,7 +1402,7 @@
 int ai_arrays_size; // weak
 int ai_near_actors_distances[500];
 unsigned int ai_near_actors_ids[500];
-int dword_4F8580[182]; // weak
+int dword_4F8580[121]; // weak
 int dword_4FA9B0[777]; // weak
 int dword_4FA9B4[777]; // weak
 char byte_4FAA00; // weak
@@ -1990,7 +1990,7 @@
 int dword_F8B1DC; // weak
 int dword_F8B1E0; // weak
 int dword_F8B1E4; // weak
-const char *ptr_F8B1E8; // idb
+const char *current_npc_text; // idb
 char dialogue_show_profession_details = false; // F8B1EC
 char byte_F8B1EF[777]; // weak
 char byte_F8B1F0[4];
--- a/mm7_data.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/mm7_data.h	Thu Mar 28 00:37:58 2013 +0400
@@ -1503,7 +1503,7 @@
 extern int dword_F8B1DC; // weak
 extern int dword_F8B1E0; // weak
 extern int dword_F8B1E4; // weak
-extern const char *ptr_F8B1E8; // idb
+extern const char *current_npc_text; // 0xF8B1E8
 extern char dialogue_show_profession_details; // weak
 extern char byte_F8B1EF[]; // weak
 extern char byte_F8B1F0[4];
@@ -1818,7 +1818,7 @@
 void __cdecl DrawDialogueUI();
 struct NPCData *__fastcall GetNPCData(signed int npcid);
 struct NPCData *__fastcall GetNewNPCData(signed int npcid, int a2);
-int __fastcall sub_445C8B(signed int a1);
+int __fastcall GetGreetType(signed int SpeakingNPC_ID);
 void __cdecl sub_44603D();
 void PrepareHouse(enum HOUSE_ID house); // idb
 bool  EnterHouse(enum HOUSE_ID uHouseID);
@@ -1835,7 +1835,7 @@
 void __thiscall GameUI_StatusBar_UpdateTimedString(unsigned int bForceHide); // idb
 void OnTimer(int);
 void __fastcall sub_448CF4_spawn_monsters(__int16 typeindex, __int16 level, int count, int x, int y, int z, int group, unsigned int uUniqueName);
-void __fastcall sub_448DF8_cast_spell(int spellnum, int rank, int level, int fromx, int fromy, int fromz, int tox, int toy, int toz);
+void __fastcall EventCastSpell(int spellnum, int uSkillLevel, int uSkill, int fromx, int fromy, int fromz, int tox, int toy, int toz);//sub_448DF8
 __int16 __fastcall sub_449A49_door_switch_animation(unsigned int uDoorID, int a2); // idb
 bool _449B57_test_bit(unsigned __int8 *a1, __int16 a2);
 void _449B7E_toggle_bit(unsigned char *pArray, __int16 a2, unsigned __int16 bToggle); // idb
@@ -1962,7 +1962,7 @@
 void __cdecl UpdateActors_BLV();
 void __cdecl UpdateActors_ODM();
 void __cdecl UpdateObjects();
-int _47272C_collide_agains_some_secotors_floors(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb
+int collide_against_floor_approximate(int x, int y, int z, unsigned int *pSectorID, unsigned int *pFaceID); // idb
 void __cdecl BLV_ProcessPartyActions();
 void __cdecl ODM_ProcessPartyActions();
 bool __fastcall sub_47531C(int a1, int *a2, int a3, int a4, int a5, int a6, int a7, int a8, BLVFace *a9, int a10);
--- a/stru277.h	Thu Mar 28 00:37:27 2013 +0400
+++ b/stru277.h	Thu Mar 28 00:37:58 2013 +0400
@@ -9,16 +9,16 @@
   //----- (00426987) --------------------------------------------------------
   inline stru277()
   {
-  this->field_8 = 0;
-  this->spellnum = 0;
-  this->field_6 = 0;
-  this->uPlayerID_2 = 0;
-  this->uPlayerID = 0;
-  this->field_10 = 0;
+    field_8 = 0;
+    spellnum = 0;
+    field_6 = 0;
+    uPlayerID_2 = 0;
+    uPlayerID = 0;
+    sound_id = 0;
   }
 
   void _427D48(unsigned int uPlayerID);
-  unsigned int PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int a6);
+  unsigned int PushStru277(__int16 a2, __int16 uPlayerID, __int16 skill_level, __int16 a5, int sound_id);
   struct GUIWindow *sub_4219BE();
   void _427E01_cast_spell();
 
@@ -29,7 +29,7 @@
   __int16 field_8;
   __int16 forced_spell_skill_level;
   int spell_target_pid;
-  int field_10;
+  int sound_id;
 };
 #pragma pack(pop)
 
--- a/stru6.cpp	Thu Mar 28 00:37:27 2013 +0400
+++ b/stru6.cpp	Thu Mar 28 00:37:58 2013 +0400
@@ -17,6 +17,8 @@
 #include "Overlays.h"
 #include "stru160.h"
 
+#include "MM7.h"
+
 
 
 
@@ -830,9 +832,9 @@
       AddMobileLight(a2, 0xFF3C1E, 256);
       if (pRenderer->pRenderD3D)
       {
-        result = a2->field_58_pid & 7;
-        if ((a2->field_58_pid & 7) != OBJECT_Actor &&
-            (a2->field_58_pid & 7) != OBJECT_Item)
+        result = a2->spell_caster_pid & 7;
+        if (PID_TYPE(a2->spell_caster_pid) != OBJECT_Actor &&
+            PID_TYPE(a2->spell_caster_pid) != OBJECT_Item)
         {
           if (field_204 != 4)
           {