diff mm7_3.cpp @ 838:d061180f2b42

Merge
author Gloval
date Thu, 28 Mar 2013 00:37:58 +0400
parents bebc19f3d2af b66abf8b7d50
children 6dd2b94efce7 710cf848ad24
line wrap: on
line diff
--- 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 )