changeset 1867:eb580660bbbb

Merge
author Nomad
date Wed, 16 Oct 2013 13:34:49 +0200
parents 41cc4dd3c122 (current diff) e622546c8f0c (diff)
children 661ea35def76 b3009adc0e2f 781522bf1a07
files
diffstat 16 files changed, 697 insertions(+), 1384 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/Actor.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -54,23 +54,26 @@
   unsigned int v9; // [sp+14h] [bp-Ch]@4
   unsigned int v10; // [sp+1Ch] [bp-4h]@4
 
-  bar_length = 25;
-  if ( actor->pMonsterInfo.uHP > 25 )
-  {
+  if (actor->pMonsterInfo.uHP <= 25)
+    bar_length = 25;
+  else if ( actor->pMonsterInfo.uHP < 200 )
+    bar_length = actor->pMonsterInfo.uHP;
+  else
     bar_length = 200;
-    if ( actor->pMonsterInfo.uHP < 200 )
-      bar_length = actor->pMonsterInfo.uHP;
-  }
+
   v10 = bar_length;
-  v9 = uTextureID_mhp_grn;
-  if ( actor->sCurrentHP < actor->pMonsterInfo.uHP )
+  if ( actor->sCurrentHP <= (0.34 * actor->pMonsterInfo.uHP) )
+    v9 = uTextureID_mhp_red;
+  else if ( actor->sCurrentHP <= ( 0.67 * actor->pMonsterInfo.uHP) )
+    v9 = uTextureID_mhp_yel;
+  else
+    v9 = uTextureID_mhp_grn;
+
+  if ( actor->sCurrentHP < (int)actor->pMonsterInfo.uHP )
   {
     v10 = bar_length / actor->pMonsterInfo.uHP * actor->sCurrentHP;
-    if ( actor->sCurrentHP <= (signed int)(signed __int64)(0.34 * (double)(signed int)actor->pMonsterInfo.uHP) )
-      v9 = uTextureID_mhp_red;
-    else if ( actor->sCurrentHP <= (signed int)(signed __int64)((double)(signed int)actor->pMonsterInfo.uHP * 0.67) )
-      v9 = uTextureID_mhp_yel;
   }
+
   uX = window->uFrameX + (signed int)(window->uFrameWidth - bar_length) / 2;
 
   pRenderer->SetTextureClipRect(uX, window->uFrameY + 32, uX + bar_length, window->uFrameY + 52);
@@ -107,59 +110,11 @@
 //----- (00448518) --------------------------------------------------------
 void __fastcall sub_448518_npc_set_item(int npc, unsigned int item, int a3)
 {
-  signed int v3; // eax@1
-  int *v4; // edi@2
-  signed int v5; // eax@6
-  char *v6; // ecx@6
-  char *v7; // eax@11
-  ItemGen *v8; // ecx@15
-
-  v3 = 0;
-  if ( (signed int)uNumActors > 0 )
+  for (uint i = 0; i < uNumActors; i++)
   {
-    v4 = (int *)&pActors[0].sNPC_ID;
-    while ( *(short *)v4 != npc )
-    {
-      ++v3;
-      v4 += 209;
-      if ( v3 >= (signed int)uNumActors )
-        return;
-    }
-    v5 = v3;
-    v6 = (char *)&pActors[v5].uCarriedItemID;
-    if ( a3 )
+    if (pActors[uNumActors].sNPC_ID == npc)
     {
-      if ( *(short *)v6 )
-      {
-        if ( pActors[v5].array_000234[0].uItemID )
-        {
-          v7 = (char *)&pActors[v5].array_000234[1];
-          if ( !*(int *)v7 )
-            *(int *)v7 = item;
-        }
-        else
-        {
-          pActors[v5].array_000234[0].uItemID = item;
-        }
-      }
-      else
-      {
-        *(short *)v6 = item;
-      }
-    }
-    else
-    {
-      if ( *(short *)v6 == item )
-      {
-        *(short *)v6 = 0;
-      }
-      else
-      {
-        v8 = pActors[v5].array_000234;
-        if ( pActors[v5].array_000234[0].uItemID == item
-          || (v8 = &pActors[v5].array_000234[1], pActors[v5].array_000234[1].uItemID == item) )
-          v8->Reset();
-      }
+      Actor::GiveItem(i, item, a3);
     }
   }
 }
@@ -167,48 +122,26 @@
 //----- (004485A7) --------------------------------------------------------
 void Actor::GiveItem(signed int uActorID, unsigned int uItemID, unsigned int bGive)
 {
-  unsigned int v3; // eax@3
-  char *v4; // ecx@3
-  int *v5; // eax@8
-  ItemGen *v6; // ecx@12
-
   if ( (uActorID >= 0) && (signed int)uActorID <= (signed int)(uNumActors - 1) )
   {
-    v3 = uActorID;
-    v4 = (char *)&pActors[uActorID].uCarriedItemID;
+    Actor* currActor = &pActors[uActorID];
     if ( bGive )
     {
-      if ( *(short *)v4 )
-      {
-        if ( pActors[v3].array_000234[0].uItemID )
-        {
-          v5 = &pActors[v3].array_000234[1].uItemID;
-          if ( !*v5 )
-            *v5 = uItemID;
-        }
-        else
-        {
-          pActors[v3].array_000234[0].uItemID = uItemID;
-        }
-      }
-      else
-      {
-        *(short *)v4 = uItemID;
-      }
+      if ( currActor->uCarriedItemID == 0)
+        currActor->uCarriedItemID = uItemID;
+      else if ( currActor->array_000234[0].uItemID == 0)
+        currActor->array_000234[0].uItemID = uItemID;
+      else if ( currActor->array_000234[1].uItemID == 0)
+        currActor->array_000234[1].uItemID = uItemID;
     }
     else
     {
-      if ( *(short *)v4 == uItemID )
-      {
-        *(short *)v4 = 0;
-      }
-      else
-      {
-        v6 = pActors[v3].array_000234;
-        if ( pActors[v3].array_000234[0].uItemID == uItemID
-          || (v6 = &pActors[v3].array_000234[1], pActors[v3].array_000234[1].uItemID == uItemID) )
-          v6->Reset();
-      }
+      if ( currActor->uCarriedItemID == uItemID )
+        currActor->uCarriedItemID = 0;
+      else if ( currActor->array_000234[0].uItemID == uItemID )
+        currActor->array_000234[0].Reset();
+      else if ( currActor->array_000234[1].uItemID == uItemID )
+        currActor->array_000234[1].Reset();
     }
   }
 }
@@ -218,7 +151,7 @@
 {
   bool isparalyzed; // esi@1
   bool isstoned; // edi@2
-  unsigned __int16 v3; // ax@6
+  AIState v3; // ax@6
 
   isstoned = (signed __int64)this->pActorBuffs[5].uExpireTime > 0;// stoned
   isparalyzed = (signed __int64)this->pActorBuffs[6].uExpireTime > 0;// paralyzed
@@ -230,1096 +163,584 @@
 bool Actor::IsNotAlive()
 {
   bool isstoned; // esi@1
-  //unsigned __int16 v2; // ax@3
 
   isstoned = (signed __int64)this->pActorBuffs[5].uExpireTime > 0;// stoned
-  //v2 = this->uAIState;
   return (isstoned || (uAIState == Dying) || (uAIState == Dead) || (uAIState == Removed) || (uAIState == Summoned) || (uAIState == Disabled));
 }
 
 //----- (004086E9) --------------------------------------------------------
 void Actor::SetRandomGoldIfTheresNoItem()
 {
-  Actor *v1; // esi@1
   int v2; // edi@1
-  signed int v3; // ebx@2
   unsigned __int8 v4; // al@7
 
-  v1 = this;
   v2 = 0;
   if ( !this->array_000234[3].uItemID )
   {
-    v3 = 0;
     if ( this->pMonsterInfo.uTreasureDiceRolls )
     {
-      do
+      for (int i = 0; i < this->pMonsterInfo.uTreasureDiceRolls; i++)
       {
-        ++v3;
-        v2 += rand() % v1->pMonsterInfo.uTreasureDiceSides + 1;
+        v2 += rand() % this->pMonsterInfo.uTreasureDiceSides + 1;
       }
-      while ( v3 < v1->pMonsterInfo.uTreasureDiceRolls );
       if ( v2 )
       {
-        v1->array_000234[3].uItemID = 197;
-        v1->array_000234[3].uSpecEnchantmentType = v2;
+        this->array_000234[3].uItemID = 197;
+        this->array_000234[3].uSpecEnchantmentType = v2;    //actual gold amount
       }
     }
   }
-  if ( rand() % 100 < v1->pMonsterInfo.uTreasureDropChance )
+  if ( rand() % 100 < this->pMonsterInfo.uTreasureDropChance )
   {
-    v4 = v1->pMonsterInfo.uTreasureLevel;
+    v4 = this->pMonsterInfo.uTreasureLevel;
     if ( v4 )
-      pItemsTable->GenerateItem(v4, v1->pMonsterInfo.uTreasureType, &v1->array_000234[2]);
+      pItemsTable->GenerateItem(v4, this->pMonsterInfo.uTreasureType, &this->array_000234[2]);
   }
-  v1->uAttributes |= 0x800000;
+  this->uAttributes |= 0x800000;
 }
 
 //----- (00404AC7) --------------------------------------------------------
-void __fastcall Actor::AI_SpellAttack(unsigned int uActorID, AIDirection *pDir, int uSpellID, int a4, unsigned int uSkillLevel)
+void Actor::AI_SpellAttack(unsigned int uActorID, AIDirection *pDir, int uSpellID, int a4, unsigned int uSkillLevel)
 {
-  Actor *v5; // esi@1
-  unsigned int v6; // edi@1
-  unsigned int v7; // eax@1
+  Actor *actorPtr; // esi@1
+  unsigned int realPoints; // edi@1
+  unsigned int masteryLevel; // eax@1
   int v8; // edi@16
-  int v9; // edi@17
   signed int v10; // ecx@22
-  signed int v11; // eax@29
-  __int16 *v12; // edi@30
-  int v13; // ecx@34
-  int v14; // edx@34
-  int v15; // eax@34
-  AIDirection *v16; // esi@34
-  unsigned __int16 v17; // di@34
-  //int v18; // eax@34
   int v19; // edi@34
   int v20; // eax@35
-  int v21; // eax@39
-  SoundID v22; // eax@39
   signed int v23; // eax@41
-  double v24; // st7@49
-  float v25; // ST5C_4@50
-  int v26; // eax@50
-  double v27; // st7@50
-  double v28; // st6@50
-  float v29; // ST4C_4@51
+  int v28; // st6@50
   int v30; // esi@50
   int v31; // ST3C_4@51
   unsigned int v32; // edi@51
-  char *v33; // eax@54
-  unsigned __int16 v34; // ax@57
-  signed int v35; // ecx@58
   signed int v36; // eax@67
-  signed int v37; // eax@68
-  signed __int64 v38; // qtt@69
   int v39; // ecx@75
-  int v40; // eax@79
-  int v41; // ecx@90
   int v42; // ecx@91
-  int v43; // eax@95
   int v44; // ecx@100
-  int v45; // ecx@101
-  int v46; // eax@105
-  unsigned int v47; // ebx@106
   int v48; // ecx@110
-  char v49; // zf@123
-  int v50; // eax@127
   int v51; // ecx@130
-  int v52; // eax@132
-  int v53; // ecx@137
   int v54; // ecx@138
-  int v55; // eax@142
-  SpellBuff *v56; // esi@143
-  Player **v57; // esi@145
+  Player *v57; // esi@145
   int v58; // eax@146
   int v59; // edi@146
   int v60; // eax@146
   int v61; // edi@146
   int v62; // eax@146
   signed int v63; // edi@146
-  signed int v64; // edi@147
-  int v65; // eax@151
-  char *v66; // eax@160
-  int v67; // edi@167
   int v68; // edi@168
-  int v69; // eax@171
   signed int v70; // ecx@172
-  signed int v71; // eax@179
-  __int16 *v72; // edi@180
-  int v73; // ecx@184
-  int v74; // edx@184
-  int v75; // eax@184
-  AIDirection *v76; // esi@184
-  unsigned __int16 v77; // di@184
-  //int v78; // eax@184
   int v79; // edx@185
   int v80; // eax@185
-  int v81; // eax@189
-  unsigned __int16 v82; // ax@190
-  int v83; // ecx@192
-  int v84; // edx@192
-  int v85; // eax@192
-  AIDirection *v86; // esi@192
-  unsigned __int16 v87; // di@192
-  __int16 v88; // ax@192
   signed int v89; // ecx@192
-  //int v90; // eax@192
   signed int v91; // eax@200
-  int v92; // eax@201
-  int v93; // ecx@207
   int v94; // ecx@208
-  int v95; // eax@212
   int v96; // ecx@217
-  int v97; // eax@221
-  SoundID v98; // [sp-18h] [bp-E8h]@79
-  signed int v99; // [sp-14h] [bp-E4h]@39
-  unsigned int v100; // [sp-10h] [bp-E0h]@39
-  signed int v101; // [sp-Ch] [bp-DCh]@39
-  signed int v102; // [sp-8h] [bp-D8h]@39
-  int v103; // [sp-4h] [bp-D4h]@39
-  unsigned int v104; // [sp+0h] [bp-D0h]@39
-  signed int v105; // [sp+4h] [bp-CCh]@23
-  int v106; // [sp+4h] [bp-CCh]@39
-  signed int v107; // [sp+4h] [bp-CCh]@42
-  signed int v108; // [sp+4h] [bp-CCh]@173
   int pitch; // [sp+2Ch] [bp-A4h]@51
-  float v110; // [sp+30h] [bp-A0h]@50
-  int v111; // [sp+38h] [bp-98h]@41
-  float v112; // [sp+3Ch] [bp-94h]@49
-  int v113; // [sp+40h] [bp-90h]@41
   int v114; // [sp+48h] [bp-88h]@41
   SpriteObject a1; // [sp+4Ch] [bp-84h]@1
   int v116; // [sp+BCh] [bp-14h]@49
-  AIDirection *v117; // [sp+C0h] [bp-10h]@1
   int v118; // [sp+C4h] [bp-Ch]@29
-  float v119; // [sp+C8h] [bp-8h]@48
-  float v120; // [sp+CCh] [bp-4h]@1
+  int v119; // [sp+C8h] [bp-8h]@48
+  int v120; // [sp+CCh] [bp-4h]@1
   int spellnuma; // [sp+D8h] [bp+8h]@29
   int spellnumb; // [sp+D8h] [bp+8h]@48
-  float spellnumc; // [sp+D8h] [bp+8h]@50
-  signed int spellnumd; // [sp+D8h] [bp+8h]@53
+  int spellnumc; // [sp+D8h] [bp+8h]@50
   int spellnume; // [sp+D8h] [bp+8h]@179
   int a1a; // [sp+E0h] [bp+10h]@34
-  signed int a1b; // [sp+E0h] [bp+10h]@145
   int a1c; // [sp+E0h] [bp+10h]@184
 
-  LODWORD(v120) = uActorID;
-  v5 = &pActors[uActorID];
-  v117 = pDir;
-  v6 = uSkillLevel & 0x3F;
-  v7 = SkillToMastery(uSkillLevel);
-  if ( uSpellID <= 47 )
+
+  actorPtr = &pActors[uActorID];
+  realPoints = uSkillLevel & 0x3F;
+  masteryLevel = SkillToMastery(uSkillLevel);
+  
+  switch (uSpellID)
   {
-    if ( uSpellID != 47 )
-    {
-      if ( uSpellID <= 18 )
+    case SPELL_FIRE_FIRE_BOLT:
+    case SPELL_FIRE_FIREBALL:
+    case SPELL_FIRE_INCINERATE:
+    case SPELL_AIR_LIGHNING_BOLT:
+    case SPELL_WATER_ICE_BOLT:
+    case SPELL_WATER_ACID_BURST:
+    case SPELL_EARTH_BLADES:
+    case SPELL_EARTH_ROCK_BLAST:
+    case SPELL_MIND_MIND_BLAST:
+    case SPELL_MIND_PSYCHIC_SHOCK:
+    case SPELL_BODY_HARM:
+    case SPELL_LIGHT_LIGHT_BOLT:
+    case SPELL_DARK_TOXIC_CLOUD:
+    case SPELL_DARK_DRAGON_BREATH:
+      a1.uType = stru_4E3ACC[uSpellID].uType;
+      a1.uObjectDescID = GetObjDescId(uSpellID);
+      a1.stru_24.Reset();
+      a1.spell_id = uSpellID;
+      a1.spell_level = uSkillLevel;
+      a1.vPosition.x = actorPtr->vPosition.x;
+      a1.spell_skill = 0;
+      a1.vPosition.y = actorPtr->vPosition.y;
+      a1.vPosition.z = actorPtr->vPosition.z + ((signed int)actorPtr->uActorHeight >> 1);
+      a1.uFacing = LOWORD(pDir->uYawAngle);
+      a1.uSoundID = 0;
+      a1.uAttributes = 0;
+      v89 = pDir->uDistance;
+      a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
+      a1.uSpriteFrameID = 0;
+      a1.spell_caster_pid = PID(OBJECT_Actor, uActorID);
+      a1.spell_target_pid = 0;
+      if ((double)v89 < 307.2 )
+        a1.field_60_distance_related_prolly_lod = 0;
+      else if ( v89 < 1024 )
+        a1.field_60_distance_related_prolly_lod = 1;
+      else if ( v89 < 2560 )
+        a1.field_60_distance_related_prolly_lod = 2;
+      else 
+        a1.field_60_distance_related_prolly_lod = 3;
+
+      a1.field_61 = 2;
+      v91 = a1.Create(
+        pDir->uYawAngle,
+        pDir->uPitchAngle,
+        pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
+        0);
+      if ( v91 != -1 )
       {
-        if ( uSpellID == 18 || uSpellID == 2 )
-          goto LABEL_159;
-        if ( uSpellID != 5 )
+        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[uSpellID], PID(OBJECT_Item, v91), 0, -1, 0, 0, 0, 0);
+        return;
+      }
+      return;
+      break;
+
+    case SPELL_FIRE_HASTE: 
+      if (masteryLevel == 1 || masteryLevel == 2)
+        v39 = 60 * (realPoints + 60);
+      else if (masteryLevel == 3 )
+        v39 = 180 * (realPoints + 20);
+      else if (masteryLevel == 4 ) 
+        v39 = 240 * (realPoints + 15);
+      else
+        v39 = 0;
+      actorPtr->pActorBuffs[19].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v39 << 7) * 0.033333335),
+        masteryLevel,
+        0,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr, 0xFF3C1Eu);
+      pAudioPlayer->PlaySound((SoundID)10040, PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_FIRE_METEOR_SHOWER:
+      if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+        return;
+      v114 = pParty->vPosition.z + 2500;
+      v23 = 8;
+      if (masteryLevel == 2)
+        v23 = 10;
+      else if (masteryLevel == 3)
+        v23 = 12;
+      else if (masteryLevel == 4)
+        v23 = 14;
+      spellnumb = 0;
+      for ( int i = 0; i < v23; i++)
+      {
+        v28 = spellnumb;
+        v30 = rand() % 1000;
+        spellnumc = v30 - 2500;
+        v120 = v28 * v28;
+        v119 = spellnumb * spellnumb;
+        if ( sqrt((float)(spellnumc * spellnumc + v119 + v120)) <= 1.0 )
         {
-          if ( uSpellID == 6 )
-            goto LABEL_159;
-          if ( uSpellID != 9 )
-          {
-            if ( uSpellID != 11 )
-            {
-              if ( uSpellID != 15 )
-              {
-                if ( uSpellID != 17 )
-                  return;
-                if ( (signed int)v7 <= 0 )
-                  goto LABEL_20;
-                if ( (signed int)v7 <= 2 )
-                {
-                  v9 = 300 * v6;
-                }
-                else
-                {
-                  if ( v7 != 3 )
-                  {
-                    if ( v7 == 4 )
-                    {
-                      v8 = 3600 * (v6 + 64);
-LABEL_21:
-                      v5->pActorBuffs[15].Apply(
-                        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v8 << 7) * 0.033333335),
-                        v7,
-                        0,
-                        0,
-                        0);
-                      return;
-                    }
-LABEL_20:
-                    v8 = 0;
-                    goto LABEL_21;
-                  }
-                  v9 = 900 * v6;
-                }
-                v8 = v9 + 3840;
-                goto LABEL_21;
-              }
-              v10 = 3;
-              if ( uSkillLevel & 0x0100 )
-              {
-                v105 = 9;
-              }
-              else
-              {
-                if ( (uSkillLevel & 0x80u) == 0 )
-                {
-                  if ( !(uSkillLevel & 0x40) )
-                    goto LABEL_29;
-                  v105 = 5;
-                }
-                else
-                {
-                  v105 = 7;
-                }
-              }
-              v10 = v105;
-LABEL_29:
-              spellnuma = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-              a1.uType = stru_4E3ACC[15].uType;
-              v118 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v10 - 1);
-              v11 = 0;
-              if ( (signed int)pObjectList->uNumObjects <= 0 )
-              {
-LABEL_33:
-                LOWORD(v11) = 0;
-              }
-              else
-              {
-                v12 = &pObjectList->pObjects->uObjectID;
-                while ( stru_4E3ACC[15].uType != *v12 )
-                {
-                  ++v11;
-                  v12 += 28;
-                  if ( v11 >= (signed int)pObjectList->uNumObjects )
-                    goto LABEL_33;
-                }
-              }
-              a1.uObjectDescID = v11;
-              a1.stru_24.Reset();
-              a1.spell_id = SPELL_AIR_SPARKS;
-              v13 = v5->vPosition.x;
-              v14 = v5->vPosition.y;
-              a1.spell_level = uSkillLevel;
-              a1.vPosition.x = v13;
-              v15 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
-              v16 = v117;
-              v17 = LOWORD(v117->uYawAngle);
-              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);
-              a1.spell_caster_pid = PID(OBJECT_Actor, LODWORD(v120));
-              a1.uSpriteFrameID = 0;
-              a1.spell_target_pid = 0;
-              a1.field_60_distance_related_prolly_lod = 3;
-              v19 = spellnuma / -2;
-              a1a = spellnuma / 2;
-              if ( spellnuma / -2 > spellnuma / 2 )
-              {
-                v20 = spellnuma / 2;
-              }
-              else
-              {
-                do
-                {
-                  a1.uFacing = v19 + LOWORD(v16->uYawAngle);
-                  v20 = a1.Create(
-                          (signed __int16)a1.uFacing,
-                          v16->uPitchAngle,
-                          pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
-                          0);
-                  v19 += v118;
-                }
-                while ( v19 <= a1a );
-              }
-              if ( v20 != -1 )
-              {
-                v106 = 0;
-                v104 = 0;
-                v103 = 0;
-                v102 = 0;
-                v21 = 8 * v20;
-                v101 = -1;
-                LOBYTE(v21) = v21 | 2;
-                v100 = 0;
-                v99 = v21;
-                v22 = (SoundID)word_4EE088_sound_ids[15];
-LABEL_202:
-                v98 = v22;
-                goto LABEL_222;
-              }
-              return;
-            }
-LABEL_159:
-            a1.uType = stru_4E3ACC[uSpellID].uType;
-            v119 = 0.0;
-            if ( (signed int)pObjectList->uNumObjects <= 0 )
-            {
-LABEL_191:
-              v82 = 0;
-            }
-            else
-            {
-              v66 = (char *)&pObjectList->pObjects->uObjectID;
-              while ( (short)a1.uType != *(short *)v66 )
-              {
-                ++LODWORD(v119);
-                v66 += 56;
-                if ( SLODWORD(v119) >= (signed int)pObjectList->uNumObjects )
-                  goto LABEL_191;
-              }
-              v82 = LOWORD(v119);
-            }
-            a1.uObjectDescID = v82;
-            a1.stru_24.Reset();
-            a1.spell_id = uSpellID;
-            v83 = v5->vPosition.x;
-            v84 = v5->vPosition.y;
-            a1.spell_level = uSkillLevel;
-            a1.vPosition.x = v83;
-            v85 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
-            v86 = v117;
-            v87 = LOWORD(v117->uYawAngle);
-            a1.spell_skill = 0;
-            a1.vPosition.y = v84;
-            a1.vPosition.z = v85;
-            a1.uFacing = v87;
-            a1.uSoundID = 0;
-            a1.uAttributes = 0;
-            v88 = pIndoor->GetSector(v83, v84, v85);
-            v89 = v86->uDistance;
-            a1.uSectorID = v88;
-            LODWORD(v119) = v89;
-            a1.uSpriteFrameID = 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 )
-            {
-              if ( v89 >= 1024 )
-              {
-                if ( v89 >= 2560 )
-                {
-                  if ( v89 < 5120 )
-                    a1.field_60_distance_related_prolly_lod = 3;
-                }
-                else
-                {
-                  a1.field_60_distance_related_prolly_lod = 2;
-                }
-              }
-              else
-              {
-                a1.field_60_distance_related_prolly_lod = 1;
-              }
-            }
-            else
-            {
-              a1.field_60_distance_related_prolly_lod = 0;
-            }
-            a1.field_61 = 2;
-            v91 = a1.Create(
-                    v86->uYawAngle,
-                    v86->uPitchAngle,
-                    pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
-                    0);
-            if ( v91 != -1 )
-            {
-              v106 = 0;
-              v104 = 0;
-              v103 = 0;
-              v102 = 0;
-              v92 = 8 * v91;
-              v101 = -1;
-              LOBYTE(v92) = v92 | 2;
-              v100 = 0;
-              v99 = v92;
-              v22 = (SoundID)word_4EE088_sound_ids[uSpellID];
-              goto LABEL_202;
-            }
-            return;
-          }
-          if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-            return;
-          v118 = pParty->vPosition.z;
-          v111 = pParty->vPosition.x;
-          v114 = pParty->vPosition.z + 2500;
-          v113 = pParty->vPosition.y;
-          v23 = 8;
-          if ( uSkillLevel & 0x0100 )
-          {
-            v107 = 14;
-          }
-          else
-          {
-            if ( (uSkillLevel & 0x80u) == 0 )
-            {
-              if ( !(uSkillLevel & 0x40) )
-                goto LABEL_48;
-              v107 = 10;
-            }
-            else
-            {
-              v107 = 12;
-            }
-          }
-          v23 = v107;
-LABEL_48:
-          v119 = 0.0;
-          spellnumb = 0;
-          if ( v23 > 0 )
-          {
-            v24 = (double)v118;
-            v118 = v23;
-            v112 = v24;
-            v116 = PID(OBJECT_Actor,LODWORD(v120));
-            do
-            {
-              v26 = rand();
-              v27 = (double)spellnumb;
-              v110 = v27;
-              v28 = (double)SLODWORD(v119);
-              v30 = v26 % 1000;
-              v25 = (double)v114;
-              spellnumc = (double)(v26 % 1000) + v112 - v25;
-              v120 = v28 * v28;
-              v119 = v27 * v27;
-              if ( sqrt(spellnumc * spellnumc + v119 + v120) <= 1.0 )
-              {
-                v32 = 0;
-                pitch = 0;
-              }
-              else
-              {
-                v31 = (signed __int64)sqrt(v119 + v120);
-                v29 = v28;
-                v32 = stru_5C6E00->Atan2((signed __int64)v110, (signed __int64)v29);
-                pitch = stru_5C6E00->Atan2(v31, (signed __int64)spellnumc);
-              }
-              a1.stru_24.Reset();
-              a1.uType = stru_4E3ACC[9].uType;
-              spellnumd = 0;
-              if ( (signed int)pObjectList->uNumObjects <= 0 )
-              {
-LABEL_57:
-                v34 = 0;
-              }
-              else
-              {
-                v33 = (char *)&pObjectList->pObjects->uObjectID;
-                while ( (short)a1.uType != *(short *)v33 )
-                {
-                  ++spellnumd;
-                  v33 += 56;
-                  if ( spellnumd >= (signed int)pObjectList->uNumObjects )
-                    goto LABEL_57;
-                }
-                v34 = spellnumd;
-              }
-              a1.uObjectDescID = v34;
-              a1.spell_level = uSkillLevel;
-              a1.vPosition.x = v111;
-              a1.vPosition.y = v113;
-              a1.vPosition.z = v30 + v114;
-              a1.spell_id = SPELL_FIRE_METEOR_SHOWER;
-              a1.spell_skill = 0;
-              a1.uAttributes = 0;
-              a1.uSectorID = 0;
-              a1.uSpriteFrameID = 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;
-              v35 = v117->uDistance;
-              LODWORD(v119) = v117->uDistance;
-              if ( (double)SLODWORD(v119) >= 307.2 )
-              {
-                if ( v35 >= 1024 )
-                {
-                  if ( v35 >= 2560 )
-                  {
-                    if ( v35 < 5120 )
-                      a1.field_60_distance_related_prolly_lod = 3;
-                  }
-                  else
-                  {
-                    a1.field_60_distance_related_prolly_lod = 2;
-                  }
-                }
-                else
-                {
-                  a1.field_60_distance_related_prolly_lod = 1;
-                }
-              }
-              else
-              {
-                a1.field_60_distance_related_prolly_lod = 0;
-              }
-              a1.field_61 = 2;
-              v36 = a1.Create(
-                      v32,
-                      pitch,
-                      pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
-                      0);
-              if ( v36 != -1 )
-              {
-                v37 = 8 * v36;
-                LOBYTE(v37) = v37 | 2;
-                pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[9], v37, 0, -1, 0, 0, 0, 0);
-              }
-              spellnumb = rand() % 1024 - 512;
-              v38 = rand();
-              v49 = v118-- == 1;
-              LODWORD(v119) = (unsigned __int64)(v38 % 1024) - 512;
-            }
-            while ( !v49 );
-          }
-          return;
+          v32 = 0;
+          pitch = 0;
+        }
+        else
+        {
+          v31 = (signed __int64)sqrt((float)(v119 + v120));
+          v32 = stru_5C6E00->Atan2(spellnumb, (int)v28);
+          pitch = stru_5C6E00->Atan2(v31, (int)spellnumc);
         }
-        if ( (signed int)v7 > 0 )
+        a1.stru_24.Reset();
+        a1.uType = stru_4E3ACC[uSpellID].uType;
+        a1.uObjectDescID = GetObjDescId(uSpellID);
+        a1.spell_level = uSkillLevel;
+        a1.vPosition.x = pParty->vPosition.x;
+        a1.vPosition.y = pParty->vPosition.y;
+        a1.vPosition.z = v30 + v114;
+        a1.spell_id = SPELL_FIRE_METEOR_SHOWER;
+        a1.spell_skill = 0;
+        a1.uAttributes = 0;
+        a1.uSectorID = 0;
+        a1.uSpriteFrameID = 0;
+        a1.spell_caster_pid = PID(OBJECT_Actor, uActorID);
+        a1.spell_target_pid = 0;
+        a1.field_60_distance_related_prolly_lod = stru_50C198._427546(v30 + 2500);
+        a1.uFacing = v32;
+        a1.uSoundID = 0;
+        if (pDir->uDistance < 307.2 )
+          a1.field_60_distance_related_prolly_lod = 0;
+        else if ( pDir->uDistance < 1024 )
+          a1.field_60_distance_related_prolly_lod = 1;
+        else if ( pDir->uDistance < 2560 )
+          a1.field_60_distance_related_prolly_lod = 2;
+        else 
+          a1.field_60_distance_related_prolly_lod = 3;
+        a1.field_61 = 2;
+        v36 = a1.Create(
+          v32,
+          pitch,
+          pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
+          0);
+        if ( v36 != -1 )
         {
-          if ( (signed int)v7 <= 2 )
-          {
-            v39 = 60 * (v6 + 60);
-            goto LABEL_79;
-          }
-          if ( v7 == 3 )
-          {
-            v39 = 180 * (v6 + 20);
-            goto LABEL_79;
-          }
-          if ( v7 == 4 )
-          {
-            v39 = 240 * (v6 + 15);
-LABEL_79:
-            v5->pActorBuffs[19].Apply(
-              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v39 << 7) * 0.033333335),
-              v7,
-              0,
-              0,
-              0);
-            pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5, 0xFF3C1Eu);
-            v106 = 0;
-            v104 = 0;
-            v103 = 0;
-            v102 = 0;
-            v40 = 8 * LODWORD(v120);
-            v101 = -1;
-            LOBYTE(v40) = PID(OBJECT_Actor,LOBYTE(v120));
-            v100 = 0;
-            v99 = v40;
-            v98 = (SoundID)10040;
-LABEL_222:
-            pAudioPlayer->PlaySound(v98, v99, v100, v101, v102, v103, v104, v106);
-            return;
-          }
+          pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[9], PID(OBJECT_Item, v36), 0, -1, 0, 0, 0, 0);
         }
-        v39 = 0;
-        goto LABEL_79;
+        spellnumb = rand() % 1024 - 512;
       }
-      if ( uSpellID == 26 || uSpellID == 29 )
-        goto LABEL_159;
-      if ( uSpellID != 38 )
+      return;
+      break;
+
+    case SPELL_AIR_SPARKS:
+      if (masteryLevel == 2 )
+        v10 = 5;
+      else if (masteryLevel == 3 )
+        v10 = 7;
+      else if (masteryLevel == 4 ) 
+        v10 = 9;
+      else 
+        v10 = 3;
+      spellnuma = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+      a1.uType = stru_4E3ACC[uSpellID].uType;
+      v118 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v10 - 1);
+      a1.uObjectDescID = GetObjDescId(uSpellID);
+
+      a1.stru_24.Reset();
+      a1.spell_id = SPELL_AIR_SPARKS;
+      a1.spell_level = uSkillLevel;
+      a1.vPosition.x = actorPtr->vPosition.x;
+      a1.spell_skill = 0;
+      a1.vPosition.y = actorPtr->vPosition.y;
+      a1.vPosition.z = actorPtr->vPosition.z + ((signed int)actorPtr->uActorHeight >> 1);
+      a1.uFacing = pDir->uYawAngle;
+      a1.uSoundID = 0;
+      a1.uAttributes = 0;
+      a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
+      a1.spell_caster_pid = PID(OBJECT_Actor, uActorID);
+      a1.uSpriteFrameID = 0;
+      a1.spell_target_pid = 0;
+      a1.field_60_distance_related_prolly_lod = 3;
+      v19 = spellnuma / -2;
+      a1a = spellnuma / 2;
+      if ( spellnuma / -2 > spellnuma / 2 )
       {
-        if ( uSpellID == 39 || uSpellID == 41 )
-          goto LABEL_159;
-        if ( uSpellID != 46 )
-          return;
-        if ( (signed int)v7 > 0 )
-        {
-          if ( (signed int)v7 <= 2 )
-          {
-            v41 = 300 * v6;
-            goto LABEL_91;
-          }
-          if ( v7 == 3 )
-          {
-            v41 = 900 * v6;
-            goto LABEL_91;
-          }
-          if ( v7 == 4 )
-          {
-            v41 = 1200 * v6;
-LABEL_91:
-            v42 = v41 + 3840;
-LABEL_95:
-            v5->pActorBuffs[17].Apply(
-              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v42 << 7) * 0.033333335),
-              v7,
-              v6 + 5,
-              0,
-              0);
-            pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5,0xC8C805u);
-            v106 = 0;
-            v104 = 0;
-            v103 = 0;
-            v102 = 0;
-            v43 = 8 * LODWORD(v120);
-            v101 = -1;
-            LOBYTE(v43) = PID(OBJECT_Actor,LOBYTE(v120));
-            v100 = 0;
-            v99 = v43;
-            v98 = (SoundID)14010;
-            goto LABEL_222;
-          }
-        }
-        v42 = 0;
-        goto LABEL_95;
-      }
-      if ( (signed int)v7 <= 0 )
-        goto LABEL_104;
-      if ( (signed int)v7 <= 2 )
-      {
-        v45 = 300 * v6;
+        v20 = spellnuma / 2;
       }
       else
       {
-        if ( v7 != 3 )
+        do
         {
-          if ( v7 == 4 )
-          {
-            v44 = 3600 * (v6 + 64);
-LABEL_105:
-            v5->pActorBuffs[16].Apply(
-              pParty->uTimePlayed + (signed int)(signed __int64)((double)(v44 << 7) * 0.033333335),
-              v7,
-              v6 + 5,
-              0,
-              0);
-            pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5,0x5C310Eu);
-            v106 = 0;
-            v104 = 0;
-            v103 = 0;
-            v102 = 0;
-            v46 = 8 * LODWORD(v120);
-            v101 = -1;
-            LOBYTE(v46) = PID(OBJECT_Actor,LOBYTE(v120));
-            v100 = 0;
-            v99 = v46;
-            v98 = (SoundID)13040;
-            goto LABEL_222;
-          }
-LABEL_104:
-          v44 = 0;
-          goto LABEL_105;
+          a1.uFacing = v19 + LOWORD(pDir->uYawAngle);
+          v20 = a1.Create(
+            (signed __int16)a1.uFacing,
+            pDir->uPitchAngle,
+            pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
+            0);
+          v19 += v118;
         }
-        v45 = 900 * v6;
+        while ( v19 <= a1a );
       }
-      v44 = v45 + 3840;
-      goto LABEL_105;
-    }
-    v47 = 0;
-    if ( (signed int)v7 > 0 )
-    {
-      if ( (signed int)v7 <= 2 )
-      {
-        v48 = 2 * v6 + 40;
-        goto LABEL_114;
-      }
-      if ( v7 == 3 )
+      if ( v20 != -1 )
       {
-        v48 = 3 * v6 + 60;
-        goto LABEL_114;
-      }
-      if ( v7 == 4 )
-      {
-        LOWORD(v48) = 2 * (3 * v6 + 60);
-LABEL_114:
-        v5->pActorBuffs[11].Apply(pParty->uTimePlayed + 1280, v7, v48, 0, 0);
-        pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5,0xC8C805u);
-LABEL_127:
-        v106 = v47;
-        v104 = v47;
-        v103 = v47;
-        v50 = 8 * LODWORD(v120);
-        v102 = v47;
-        v101 = -1;
-        LOBYTE(v50) = PID(OBJECT_Actor,LOBYTE(v120));
-        v100 = v47;
-        v99 = v50;
-        v98 = (SoundID)14020;
-        goto LABEL_222;
+        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[15], PID(OBJECT_Item, v20), 0, -1, 0, 0, 0, 0);
+        return;
       }
-    }
-    LOWORD(v48) = 0;
-    goto LABEL_114;
-  }
-  if ( uSpellID <= 80 )
-  {
-    if ( uSpellID == 80 )
-    {
-      v56 = pParty->pPartyBuffs;
-      do
+      return;
+      break;
+
+    case SPELL_AIR_SHIELD:
+      if (masteryLevel == 1 || masteryLevel == 2)
+        v8 = 300 * realPoints + 3840;
+      else if (masteryLevel == 3 )
+        v8 = 900 * realPoints + 3840;
+      else if (masteryLevel == 4 ) 
+        v8 = 3600 * (realPoints + 64);
+      else
+        v8 = 0;
+      actorPtr->pActorBuffs[15].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v8 << 7) * 0.033333335),
+        masteryLevel,
+        0,
+        0,
+        0);
+      return;
+
+    case SPELL_EARTH_STONESKIN:
+      if (masteryLevel == 1 || masteryLevel == 2)
+        v44 = 300 * realPoints + 3840;
+      else if (masteryLevel == 3 )
+        v44 = 900 * realPoints + 3840;
+      else if (masteryLevel == 4 ) 
+        v44 = 3600 * (realPoints + 64);
+      else
+          v44 = 0;
+      actorPtr->pActorBuffs[16].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v44 << 7) * 0.033333335),
+        masteryLevel,
+        realPoints + 5,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr,0x5C310Eu);
+      pAudioPlayer->PlaySound((SoundID)13040, PID(OBJECT_Actor,uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_SPIRIT_BLESS:
+      if (masteryLevel == 1 || masteryLevel == 2)
+        v42 = 300 * realPoints + 3840;
+      else if (masteryLevel == 3 )
+        v42 = 900 * realPoints + 3840;
+      else if (masteryLevel == 4 ) 
+        v42 = 1200 * realPoints + 3840;
+      else
+        v42 = 0;
+      actorPtr->pActorBuffs[17].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v42 << 7) * 0.033333335),
+        masteryLevel,
+        realPoints + 5,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr,0xC8C805u);
+      pAudioPlayer->PlaySound((SoundID)14010, PID(OBJECT_Actor,uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+      break;
+
+    case SPELL_SPIRIT_FATE:
+      if (masteryLevel == 1 || masteryLevel == 2)
+        v48 = 2 * realPoints + 40;
+      else if (masteryLevel == 3 )
+        v48 = 3 * realPoints + 60;
+      else if (masteryLevel == 4 ) 
+        v48 = 2 * (3 * realPoints + 60);
+      else
+        v48 = 0;
+      actorPtr->pActorBuffs[11].Apply(pParty->uTimePlayed + 1280, masteryLevel, v48, 0, 0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr,0xC8C805u);
+      pAudioPlayer->PlaySound((SoundID)14020, PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_SPIRIT_HEROISM:
+      if (masteryLevel == 1 || masteryLevel == 2)
+        v54 = 300 * realPoints + 3840;
+      else if (masteryLevel == 3 )
+        v54 = 900 * realPoints + 3840;
+      else if (masteryLevel == 4 ) 
+        v54 = 1200 * realPoints + 3840;
+      else
+        v54 = 0;
+      actorPtr->pActorBuffs[18].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v54 << 7) * 0.033333335),
+        masteryLevel,
+        realPoints + 5,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr,0xC8C805u);
+      pAudioPlayer->PlaySound((SoundID)14060, PID(OBJECT_Actor,uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_BODY_HAMMERHANDS:
+      if ( (signed int)masteryLevel <= 0 || (signed int)masteryLevel > 4 )
+        v51 = 0;
+      else
+        v51 = 3600 * realPoints;
+      actorPtr->pActorBuffs[21].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v51 << 7) * 0.033333335),
+        masteryLevel,
+        realPoints,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr, 0xA81376u);
+      pAudioPlayer->PlaySound((SoundID)16060, PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_BODY_POWER_CURE:
+      actorPtr->sCurrentHP += 5 * realPoints + 10;
+      if ( actorPtr->sCurrentHP >= (signed int)actorPtr->pMonsterInfo.uHP )
+        actorPtr->sCurrentHP = LOWORD(actorPtr->pMonsterInfo.uHP);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr, 0xA81376u);
+      pAudioPlayer->PlaySound((SoundID)14020, PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_LIGHT_DISPEL_MAGIC:
+      for (int i = 0; i < 20; i++ )
       {
-        v56->Reset();
-        ++v56;
+        pParty->pPartyBuffs[i].Reset();
       }
-      while ( (signed int)v56 < (signed int)pParty->pPlayers );
-      a1b = 1;
-      v57 = &pPlayers[1];
-      do
+      for (int i = 1; i <= 4; i++)
       {
-        v58 = (*v57)->GetActualWillpower();
-        v59 = (*v57)->GetParameterBonus(v58);
-        v60 = (*v57)->GetActualIntelligence();
-        v61 = ((*v57)->GetParameterBonus(v60) + v59) >> 1;
-        v62 = (*v57)->GetActualLuck();
-        v63 = v61 + (*v57)->GetParameterBonus(v62) + 30;
+        v57 = pPlayers[i];
+        v58 = v57->GetActualWillpower();
+        v59 = v57->GetParameterBonus(v58);
+        v60 = v57->GetActualIntelligence();
+        v61 = (v57->GetParameterBonus(v60) + v59) / 2;
+        v62 = v57->GetActualLuck();
+        v63 = v61 + v57->GetParameterBonus(v62) + 30;
         if ( rand() % v63 < 30 )
         {
-          v64 = 6048;
-          do
+          for (uint k = 0; k < v57->pPlayerBuffs.size(); k++)
           {
-            ((SpellBuff *)((char *)*v57 + v64))->Reset();
-            v64 += 16;
+            v57->pPlayerBuffs[k].Reset();
           }
-          while ( v64 < 6432 );
-          pOtherOverlayList->_4418B1(11210, a1b + 99, 0, 65536);
+          pOtherOverlayList->_4418B1(11210, i + 99, 0, 65536);
         }
-        ++a1b;
-        ++v57;
-      }
-      while ( (signed int)v57 <= (signed int)&pPlayers[4] );
-      v106 = 0;
-      v104 = 0;
-      v103 = 0;
-      v65 = 8 * LODWORD(v120);
-      v102 = 0;
-      v101 = -1;
-      LOBYTE(v65) = PID(OBJECT_Actor,LOBYTE(v120));
-      v100 = 0;
-      v99 = v65;
-      v22 = (SoundID)word_4EE088_sound_ids[80];
-      goto LABEL_202;
-    }
-    if ( uSpellID != 51 )
-    {
-      if ( uSpellID == 57 || uSpellID == 65 || uSpellID == 70 )
-        goto LABEL_159;
-      if ( uSpellID == 73 )
-      {
-        if ( (signed int)v7 <= 0 || (signed int)v7 > 4 )
-          v51 = 0;
-        else
-          v51 = 3600 * v6;
-        v5->pActorBuffs[21].Apply(
-          pParty->uTimePlayed + (signed int)(signed __int64)((double)(v51 << 7) * 0.033333335),
-          v7,
-          v6,
-          0,
-          0);
-        pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5, 0xA81376u);
-        v106 = 0;
-        v104 = 0;
-        v103 = 0;
-        v102 = 0;
-        v52 = 8 * LODWORD(v120);
-        v101 = -1;
-        LOBYTE(v52) = PID(OBJECT_Actor,LOBYTE(v120));
-        v100 = 0;
-        v99 = v52;
-        v98 = (SoundID)16060;
-        goto LABEL_222;
-      }
-      if ( uSpellID == 77 )
-      {
-        v5->sCurrentHP += 5 * v6 + 10;
-        if ( v5->sCurrentHP >= (signed int)v5->pMonsterInfo.uHP )
-          v5->sCurrentHP = LOWORD(v5->pMonsterInfo.uHP);
-        pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5, 0xA81376u);
-        v47 = 0;
-        goto LABEL_127;
       }
-      v49 = uSpellID == 78;
-LABEL_158:
-      if ( !v49 )
-        return;
-      goto LABEL_159;
-    }
-    if ( (signed int)v7 > 0 )
-    {
-      if ( (signed int)v7 <= 2 )
+      pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[80], PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_LIGHT_DAY_OF_PROTECTION:
+       if (masteryLevel == 1 || masteryLevel == 2)
       {
-        v53 = 300 * v6;
-        goto LABEL_138;
+        v96 = 300 * realPoints + 3840;
       }
-      if ( v7 == 3 )
-      {
-        v53 = 900 * v6;
-        goto LABEL_138;
-      }
-      if ( v7 == 4 )
+      else if (masteryLevel == 3 )
       {
-        v53 = 1200 * v6;
-LABEL_138:
-        v54 = v53 + 3840;
-LABEL_142:
-        v5->pActorBuffs[18].Apply(
-          pParty->uTimePlayed + (signed int)(signed __int64)((double)(v54 << 7) * 0.033333335),
-          v7,
-          v6 + 5,
-          0,
-          0);
-        pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5,0xC8C805u);
-        v106 = 0;
-        v104 = 0;
-        v103 = 0;
-        v102 = 0;
-        v55 = 8 * LODWORD(v120);
-        v101 = -1;
-        LOBYTE(v55) = PID(OBJECT_Actor,LOBYTE(v120));
-        v100 = 0;
-        v99 = v55;
-        v98 = (SoundID)14060;
-        goto LABEL_222;
+        LOWORD(realPoints) = 3 * realPoints;
+        v96 = 900 * (uSkillLevel & 0x3F) + 3840;
       }
-    }
-    v54 = 0;
-    goto LABEL_142;
-  }
-  if ( uSpellID == 85 )
-  {
-    if ( (signed int)v7 > 0 )
-    {
-      if ( (signed int)v7 <= 2 )
+      else if (masteryLevel == 4 ) 
       {
-        v96 = 300 * v6 + 3840;
-        goto LABEL_221;
+        v96 = 1200 * realPoints + 3840;
+        LOWORD(realPoints) = 4 * realPoints;
       }
-      if ( v7 == 3 )
-      {
-        LOWORD(v6) = 3 * v6;
-        v96 = 900 * (uSkillLevel & 0x3F) + 3840;
-        goto LABEL_221;
-      }
-      if ( v7 == 4 )
+      else
       {
-        v96 = 1200 * v6 + 3840;
-        LOWORD(v6) = 4 * v6;
-LABEL_221:
-        v5->pActorBuffs[13].Apply(
-          pParty->uTimePlayed + (signed int)(signed __int64)((double)(v96 << 7) * 0.033333335),
-          v7,
-          v6,
-          0,
-          0);
-        pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5, 0xFFFFFFu);
-        v106 = 0;
-        v104 = 0;
-        v103 = 0;
-        v102 = 0;
-        v97 = 8 * LODWORD(v120);
-        v101 = -1;
-        LOBYTE(v97) = PID(OBJECT_Actor,LOBYTE(v120));
-        v100 = 0;
-        v99 = v97;
-        v98 = (SoundID)17070;
-        goto LABEL_222;
-      }
-    }
-    LOWORD(v6) = uSkillLevel;
-    v96 = 0;
-    goto LABEL_221;
-  }
-  if ( uSpellID == 86 )
-  {
-    if ( (signed int)v7 > 0 )
-    {
-      if ( (signed int)v7 <= 2 )
-      {
-        v93 = 300 * v6;
-        goto LABEL_208;
-      }
-      if ( v7 == 3 )
-      {
-        v93 = 900 * v6;
-        goto LABEL_208;
-      }
-      if ( v7 == 4 )
-      {
-        v93 = 1200 * v6;
-LABEL_208:
-        v94 = v93 + 3840;
-LABEL_212:
-        v5->pActorBuffs[14].Apply(
-          pParty->uTimePlayed + (signed int)(signed __int64)((double)(v94 << 7) * 0.033333335),
-          v7,
-          v6 + 5,
-          0,
-          0);
-        pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5, 0xFFFFFFu);
-        v106 = 0;
-        v104 = 0;
-        v103 = 0;
-        v102 = 0;
-        v95 = 8 * LODWORD(v120);
-        v101 = -1;
-        LOBYTE(v95) = PID(OBJECT_Actor,LOBYTE(v120));
-        v100 = 0;
-        v99 = v95;
-        v98 = (SoundID)17080;
-        goto LABEL_222;
+        LOWORD(realPoints) = uSkillLevel;
+        v96 = 0;
       }
-    }
-    v94 = 0;
-    goto LABEL_212;
-  }
-  if ( uSpellID == 90 )
-    goto LABEL_159;
-  if ( uSpellID != 93 )
-  {
-    if ( uSpellID != 95 )
-    {
-      v49 = uSpellID == 97;
-      goto LABEL_158;
-    }
-    if ( (signed int)v7 > 0 )
-    {
-      if ( (signed int)v7 <= 3 )
-      {
-        v67 = 300 * v6;
-        goto LABEL_168;
-      }
-      if ( v7 == 4 )
+      actorPtr->pActorBuffs[13].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v96 << 7) * 0.033333335),
+        masteryLevel,
+        realPoints,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr, 0xFFFFFFu);
+      pAudioPlayer->PlaySound((SoundID)17070, PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_LIGHT_HOUR_OF_POWER:
+      if (masteryLevel == 1 || masteryLevel == 2)
+        v94 = 300 * realPoints + 3840;
+      else if (masteryLevel == 3)
+        v94 = 900 * realPoints + 3840;
+      else if (masteryLevel == 4)
+        v94 = 1200 * realPoints + 3840;
+      else
+        v94 = 0;
+      actorPtr->pActorBuffs[14].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v94 << 7) * 0.033333335),
+        masteryLevel,
+        realPoints + 5,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr, 0xFFFFFFu);
+      pAudioPlayer->PlaySound((SoundID)17080, PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
+
+    case SPELL_DARK_SHARPMETAL:
+      if (masteryLevel == 2)
+        v70 = 5;
+      else if (masteryLevel == 3)
+        v70 = 7;
+      else if (masteryLevel == 4)
+        v70 = 9;
+      else
+        v70 = 3;
+
+      spellnume = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
+      a1.uType = stru_4E3ACC[uSpellID].uType;
+      v116 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v70 - 1);
+      a1.uObjectDescID = GetObjDescId(uSpellID);
+      a1.stru_24.Reset();
+      a1.spell_id = uSpellID;
+      a1.spell_level = uSkillLevel;
+      a1.vPosition.x = actorPtr->vPosition.x;
+      a1.spell_skill = 0;
+      a1.vPosition.y = actorPtr->vPosition.y;
+      a1.vPosition.z = actorPtr->vPosition.z + ((signed int)actorPtr->uActorHeight >> 1);
+      a1.uFacing = pDir->uYawAngle;
+      a1.uSoundID = 0;
+      a1.uAttributes = 0;
+      a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
+      a1.spell_caster_pid = PID(OBJECT_Actor, uActorID);
+      a1.uSpriteFrameID = 0;
+      a1.spell_target_pid = 0;
+      a1.field_60_distance_related_prolly_lod = 3;
+      a1c = spellnume / -2;
+      if ( spellnume / -2 > spellnume / 2 )
       {
-        v67 = 900 * v6;
-LABEL_168:
-        v68 = v67 + 3840;
-LABEL_171:
-        v5->pActorBuffs[20].Apply(
-          pParty->uTimePlayed + (signed int)(signed __int64)((double)(v68 << 7) * 0.033333335),
-          v7,
-          0,
-          0,
-          0);
-        pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(v5,0x7E7E7Eu);
-        v106 = 0;
-        v104 = 0;
-        v103 = 0;
-        v102 = 0;
-        v69 = 8 * LODWORD(v120);
-        v101 = -1;
-        LOBYTE(v69) = PID(OBJECT_Actor,LOBYTE(v120));
-        v100 = 0;
-        v99 = v69;
-        v98 = (SoundID)18060;
-        goto LABEL_222;
+        v80 = spellnume / -2;
+      }
+      else
+      {
+        do
+        {
+          v79 = pDir->uYawAngle;
+          a1.uFacing = a1c + LOWORD(pDir->uYawAngle);
+          v80 = a1.Create(
+            v79,
+            pDir->uPitchAngle,
+            pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
+            0);
+          a1c += v116;
+        }
+        while ( a1c <= spellnume / 2 );
+      }
+      if ( v80 != -1 )
+      {
+        pAudioPlayer->PlaySound((SoundID)word_4EE088_sound_ids[93], PID(OBJECT_Item, v80), 0, -1, 0, 0, 0, 0);
+        return;
       }
-    }
-    v68 = 0;
-    goto LABEL_171;
-  }
-  v70 = 3;
-  if ( uSkillLevel & 0x100 )
-  {
-    v108 = 9;
+      return;
+      break;
+
+    case SPELL_DARK_PAIN_REFLECTION:
+      if (masteryLevel == 0)
+        v68 = 0;
+      else if (masteryLevel == 1 || (masteryLevel == 2) || (masteryLevel == 3))
+        v68 = 300 * realPoints + 3840;
+      else
+        v68 = 900 * realPoints + 3840;
+      actorPtr->pActorBuffs[20].Apply(
+        pParty->uTimePlayed + (signed int)(signed __int64)((double)(v68 << 7) * 0.033333335),
+        masteryLevel,
+        0,
+        0,
+        0);
+      pGame->pStru6Instance->_4A7E89_sparkles_on_actor_after_it_casts_buff(actorPtr,0x7E7E7Eu);
+      pAudioPlayer->PlaySound((SoundID)18060, PID(OBJECT_Actor, uActorID), 0, -1, 0, 0, 0, 0);
+      return;
   }
-  else
+}
+
+
+//----- (new func) --------------------------------------------------------
+unsigned short Actor::GetObjDescId( int spellId )
+{
+  for (unsigned int i = 0; i < pObjectList->uNumObjects; i++)
   {
-    if ( (uSkillLevel & 0x80u) == 0 )
+    if (stru_4E3ACC[spellId].uType == pObjectList->pObjects[i].uObjectID)
     {
-      if ( !(uSkillLevel & 0x40) )
-        goto LABEL_179;
-      v108 = 5;
-    }
-    else
-    {
-      v108 = 7;
+      return i;
+      break;
     }
   }
-  v70 = v108;
-LABEL_179:
-  spellnume = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360;
-  a1.uType = stru_4E3ACC[SPELL_DARK_SHARPMETAL].uType;
-  v116 = (signed int)(60 * stru_5C6E00->uIntegerDoublePi) / 360 / (v70 - 1);
-  v71 = 0;
-  if ( (signed int)pObjectList->uNumObjects <= 0 )
-  {
-LABEL_183:
-    LOWORD(v71) = 0;
-  }
-  else
-  {
-    v72 = &pObjectList->pObjects->uObjectID;
-    while ( stru_4E3ACC[SPELL_DARK_SHARPMETAL].uType != *v72 )
-    {
-      ++v71;
-      v72 += 28;
-      if ( v71 >= (signed int)pObjectList->uNumObjects )
-        goto LABEL_183;
-    }
-  }
-  a1.uObjectDescID = v71;
-  a1.stru_24.Reset();
-  a1.spell_id = SPELL_DARK_SHARPMETAL;
-  v73 = v5->vPosition.x;
-  v74 = v5->vPosition.y;
-  a1.spell_level = uSkillLevel;
-  a1.vPosition.x = v73;
-  v75 = v5->vPosition.z + ((signed int)v5->uActorHeight >> 1);
-  v76 = v117;
-  v77 = LOWORD(v117->uYawAngle);
-  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);
-  a1.spell_caster_pid = PID(OBJECT_Actor, LODWORD(v120));
-  a1.uSpriteFrameID = 0;
-  a1.spell_target_pid = 0;
-  a1.field_60_distance_related_prolly_lod = 3;
-  a1c = spellnume / -2;
-  if ( spellnume / -2 > spellnume / 2 )
-  {
-    v80 = spellnume / -2;
-  }
-  else
-  {
-    do
-    {
-      v79 = v76->uYawAngle;
-      a1.uFacing = a1c + LOWORD(v76->uYawAngle);
-      v80 = a1.Create(
-              v79,
-              v76->uPitchAngle,
-              pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
-              0);
-      a1c += v116;
-    }
-    while ( a1c <= spellnume / 2 );
-  }
-  if ( v80 != -1 )
-  {
-    v106 = 0;
-    v104 = 0;
-    v103 = 0;
-    v102 = 0;
-    v81 = 8 * v80;
-    v101 = -1;
-    LOBYTE(v81) = v81 | 2;
-    v100 = 0;
-    v99 = v81;
-    v22 = (SoundID)word_4EE088_sound_ids[93];
-    goto LABEL_202;
-  }
+  return 0;
 }
 
+
 //----- (0043ABB0) --------------------------------------------------------
 bool Actor::ArePeasantsOfSameFaction(Actor *a1, Actor *a2)
 {
   unsigned int v2; // esi@1
   unsigned int v3; // edi@1
-  bool result; // eax@9
 
   v2 = a1->uAlly;
   v3 = a2->uAlly;
@@ -1327,14 +748,15 @@
     v2 = (a1->pMonsterInfo.uID - 1) / 3 + 1;
   if ( !v3 )
     v3 = (a2->pMonsterInfo.uID - 1) / 3 + 1;
-  if ( (signed int)v2 >= 39 && (signed int)v2 <= 44 && (signed int)v3 >= 39 && (signed int)v3 <= 44
-    || (signed int)v2 >= 45 && (signed int)v2 <= 50 && (signed int)v3 >= 45 && (signed int)v3 <= 50
-    || (signed int)v2 >= 51 && (signed int)v2 <= 62 && (signed int)v3 >= 51 && (signed int)v3 <= 62
-    || (signed int)v2 >= 78 && (signed int)v2 <= 83 && (signed int)v3 >= 78 && (signed int)v3 <= 83 )
-    result = 1;
+  if ( v2 >= 39 && v2 <= 44 && v3 >= 39 && v3 <= 44
+    || v2 >= 45 && v2 <= 50 && v3 >= 45 && v3 <= 50
+    || v2 >= 51 && v2 <= 62 && v3 >= 51 && v3 <= 62
+    || v2 >= 78 && v2 <= 83 && v3 >= 78 && v3 <= 83 
+    || v2 == v3
+    )
+    return true;
   else
-    result = v2 == v3;
-  return result;
+    return false;
 }
 
 //----- (0043AC45) --------------------------------------------------------
@@ -1344,13 +766,15 @@
   int v5; // ST1C_4@8
   int v6; // eax@8
 
-  auto victim = &pActors[uActorID];
+  int x = 0; BYTE2(x) |= 8u;
+  int y = 0; y |= 0x80000;
+  Actor* victim = &pActors[uActorID];
   if ( a2 == 1 )
-    BYTE2(victim->uAttributes) |= 8u;
+    victim->uAttributes |= 0x80000;
 
   for (uint i = 0; i < uNumActors; ++i)
   {
-    auto actor = &pActors[i];
+    Actor* actor = &pActors[i];
     if (!actor->CanAct() || i == uActorID)
       continue;
 
@@ -1363,223 +787,150 @@
       {
         actor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
         if ( a2 == 1 )
-          BYTE2(actor->uAttributes) |= 8u;
+          actor->uAttributes |= 0x80000;
+
       }
     }
   }
 }
 
 //----- (00404874) --------------------------------------------------------
-char __fastcall Actor::AI_RangedAttack(unsigned int uActorID, AIDirection *a2, int a3, char a4)
+void Actor::AI_RangedAttack( unsigned int uActorID, struct AIDirection *pDir, int type, char a4 )
 {
-  AIDirection *v4; // edi@1
-  Actor *v5; // esi@1
-  char result; // al@1
-  char *v7; // eax@15
-  unsigned __int16 v8; // ax@18
-  unsigned __int16 v9; // ax@19
-  __int16 v10; // ax@19
-  signed int v11; // ecx@19
-  //int v12; // eax@19
+  Actor *actPtr; // esi@1
+  char specAb; // al@1
   int v13; // edx@28
-  //SpriteObject a1; // [sp+Ch] [bp-74h]@1
-  unsigned int v15; // [sp+7Ch] [bp-4h]@1
-  signed int v16; // [sp+88h] [bp+8h]@14
-  signed int v17; // [sp+88h] [bp+8h]@19
 
-  v15 = uActorID;
-  v4 = a2;
-  v5 = &pActors[uActorID];
+  actPtr = &pActors[uActorID];
 
   SpriteObject a1; // [sp+Ch] [bp-74h]@1
-  //SpriteObject::SpriteObject(&a1);
 
-  result = a3 - 1;
-  switch ( a3 )
+  switch ( type )
   {
     case 1:
       a1.uType = 545;
-      goto LABEL_14;
+      break;
     case 2:
       a1.uType = 550;
-      goto LABEL_14;
+      break;
     case 3:
       a1.uType = 510;
-      goto LABEL_14;
+      break;
     case 4:
       a1.uType = 500;
-      goto LABEL_14;
+      break;
     case 5:
       a1.uType = 515;
-      goto LABEL_14;
+      break;
     case 6:
       a1.uType = 505;
-      goto LABEL_14;
+      break;
     case 7:
       a1.uType = 530;
-      goto LABEL_14;
+      break;
     case 8:
       a1.uType = 525;
-      goto LABEL_14;
+      break;
     case 9:
       a1.uType = 520;
-      goto LABEL_14;
+      break;
     case 10:
       a1.uType = 535;
-      goto LABEL_14;
+      break;
     case 11:
       a1.uType = 540;
-      goto LABEL_14;
+      break;
     case 13:
       a1.uType = 555;
-LABEL_14:
-      v16 = 0;
-      if ( (signed int)pObjectList->uNumObjects <= 0 )
-        goto LABEL_18;
-      v7 = (char *)&pObjectList->pObjects->uObjectID;
       break;
     default:
-      return result;
-  }
-  while ( (short)a1.uType != *(short *)v7 )
-  {
-    ++v16;
-    v7 += 56;
-    if ( v16 >= (signed int)pObjectList->uNumObjects )
-    {
-LABEL_18:
-      v8 = 0;
-      goto LABEL_19;
-    }
+      return;
   }
-  v8 = v16;
-LABEL_19:
-  a1.uObjectDescID = v8;
+  a1.uObjectDescID = GetObjDescId(a1.uType);
   a1.stru_24.Reset();
-  a1.vPosition.x = v5->vPosition.x;
+  a1.vPosition.x = actPtr->vPosition.x;
   a1.spell_id = 0;
-  a1.vPosition.y = v5->vPosition.y;
+  a1.vPosition.y = actPtr->vPosition.y;
   a1.spell_level = 0;
-  v17 = v5->uActorHeight;
   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;
+  a1.vPosition.z = actPtr->vPosition.z - (unsigned int)(actPtr->uActorHeight * -0.75);
+  a1.uFacing = pDir->uYawAngle;
   a1.uSoundID = 0;
   a1.uAttributes = 0;
-  v10 = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
-  v11 = v4->uDistance;
-  a1.uSectorID = v10;
+  a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
   a1.uSpriteFrameID = 0;
-  a1.spell_caster_pid = PID(OBJECT_Actor, v15);
+  a1.spell_caster_pid = PID(OBJECT_Actor, uActorID);
   a1.spell_target_pid = 0;
-  if ( (double)v11 >= 307.2 )
+  if (pDir->uDistance < 307.2 )
+    a1.field_60_distance_related_prolly_lod = 0;
+  else if ( pDir->uDistance < 1024 )
+    a1.field_60_distance_related_prolly_lod = 1;
+  else if ( pDir->uDistance < 2560 )
+    a1.field_60_distance_related_prolly_lod = 2;
+  else 
+    a1.field_60_distance_related_prolly_lod = 3;
+
+  a1.field_61 = a4;
+  a1.Create(
+             pDir->uYawAngle,
+             pDir->uPitchAngle,
+             pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
+             0);
+  if ( actPtr->pMonsterInfo.uSpecialAbilityType == 1 )
   {
-    if ( v11 >= 1024 )
+    specAb = actPtr->pMonsterInfo.uSpecialAbilityDamageDiceBonus;
+    if ( specAb == 2 )
     {
-      a1.field_60_distance_related_prolly_lod = 2;
-      if ( v11 >= 2560 )
-        a1.field_60_distance_related_prolly_lod = 3;
+      a1.vPosition.z += 40;      
+      v13 = pDir->uYawAngle;
     }
     else
     {
-      a1.field_60_distance_related_prolly_lod = 1;
-    }
-  }
-  else
-  {
-    a1.field_60_distance_related_prolly_lod = 0;
-  }
-  a1.field_61 = a4;
-  result = a1.Create(
-             v4->uYawAngle,
-             v4->uPitchAngle,
-             pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
-             0);
-  if ( v5->pMonsterInfo.uSpecialAbilityType == 1 )
-  {
-    result = v5->pMonsterInfo.uSpecialAbilityDamageDiceBonus;
-    if ( result == 2 )
-    {
-      a1.vPosition.z += 40;
-      v13 = v4->uYawAngle;
-    }
-    else
-    {
-      if ( result != 3 )
-        return result;
+      if ( specAb != 3 )
+        return;
       a1.Create(
-        v4->uYawAngle + 30,
-        v4->uPitchAngle,
+        pDir->uYawAngle + 30,      //TODO find out why the YawAngle change
+        pDir->uPitchAngle,
         pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
         0);
-      v13 = v4->uYawAngle - 30;
+      v13 = pDir->uYawAngle - 30;
     }
-    result = a1.Create(
+    a1.Create(
                v13,
-               v4->uPitchAngle,
+               pDir->uPitchAngle,
                pObjectList->pObjects[(signed __int16)a1.uObjectDescID].uSpeed,
                0);
   }
-  return result;
+  return;
 }
 
 //----- (00404736) --------------------------------------------------------
-signed int __fastcall Actor::Explode(unsigned int uActorID)
+void Actor::Explode( unsigned int uActorID )
 {
   Actor *v1; // esi@1
-  signed int v2; // edx@1
-  char *v3; // ecx@2
-  unsigned __int16 v4; // ax@5
-  int v5; // ebx@6
-  int v6; // ecx@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
 
-  v10 = uActorID;
   v1 = &pActors[uActorID];
-  v2 = 0;
   a1.uType = 600;
-  if ( (signed int)pObjectList->uNumObjects <= 0 )
-  {
-LABEL_5:
-    v4 = 0;
-  }
-  else
-  {
-    v3 = (char *)&pObjectList->pObjects->uObjectID;
-    while ( *(short *)v3 != 600 )
-    {
-      ++v2;
-      v3 += 56;
-      if ( v2 >= (signed int)pObjectList->uNumObjects )
-        goto LABEL_5;
-    }
-    v4 = v2;
-  }
-  a1.uObjectDescID = v4;
+  a1.uObjectDescID = GetObjDescId(a1.uType);
   a1.stru_24.Reset();
   a1.vPosition.y = v1->vPosition.y;
   a1.spell_id = 0;
-  v5 = v1->vPosition.x;
-  v11 = v1->uActorHeight;
   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.vPosition.x = v1->vPosition.x;
   a1.uFacing = 0;
-  a1.vPosition.z = v6;
+  a1.vPosition.z = v1->vPosition.z - (unsigned int)(v1->uActorHeight * -0.75);
   a1.uSoundID = 0;
   a1.uAttributes = 0;
-  a1.uSectorID = pIndoor->GetSector(v5, a1.vPosition.y, v6);
+  a1.uSectorID = pIndoor->GetSector(a1.vPosition.x, a1.vPosition.y, a1.vPosition.z);
   a1.uSpriteFrameID = 0;
-  a1.spell_caster_pid = PID(OBJECT_Actor, v10);
+  a1.spell_caster_pid = PID(OBJECT_Actor, uActorID);
   a1.spell_target_pid = 0;
   a1.field_60_distance_related_prolly_lod = 3;
   a1.field_61 = 4;
-  return a1.Create(0, 0, 0, 0);
+  a1.Create(0, 0, 0, 0);
+  return;
 }
 
 //----- (004040E9) --------------------------------------------------------
@@ -1596,48 +947,17 @@
 // // originally this function had following prototype:
 // // struct DirectionInfo GetDirectionInfo(signed int object1, signed int object2, signed int a4)
 // // but compiler converts functions returning structures by value in the such way
-AIDirection *__fastcall Actor::GetDirectionInfo(unsigned int uObj1ID, unsigned int uObj2ID, AIDirection *pOut, int a4)
+struct AIDirection * Actor::GetDirectionInfo( unsigned int uObj1ID, unsigned int uObj2ID, struct AIDirection *pOut, int a4 )
 {
   signed int v4; // eax@1
   signed int v5; // ecx@1
-  //unsigned int v6; // ebx@1
-  int v7; // ecx@2
-  int v8; // ecx@3
-  int v9; // ecx@4
-  //BLVFace *v10; // eax@8
-  //unsigned int v11; // ecx@8
-  //signed int v12; // eax@9
-  //int v13; // ecx@9
-  //int v14; // eax@9
-  int v15; // eax@11
-  int v16; // eax@12
-  int v17; // eax@13
   int v18; // edx@15
-  //signed int v19; // eax@25
-  //signed int v20; // eax@28
-  //int v21; // ebx@28
-  //signed int v22; // eax@28
-  //BLVFace *v23; // eax@35
-  //int v24; // edx@35
-  //unsigned int v25; // ecx@35
-  //signed int v26; // eax@36
-  //int v27; // ecx@36
-  //int v28; // eax@36
-  //int v29; // eax@37
-  //signed int v30; // eax@42
-  double v31; // st7@45
-  double v32; // st6@45
-  double v33; // st7@45
+  float v31; // st7@45
+  float v32; // st6@45
+  float v33; // st7@45
   AIDirection *result; // eax@48
-  //int v35; // [sp-18h] [bp-64h]@17
-  //int v36; // [sp-14h] [bp-60h]@17
   Vec3_int_ v37; // [sp-10h] [bp-5Ch]@15
-  //int *v38; // [sp-4h] [bp-50h]@15
-  //int *v39; // [sp+0h] [bp-4Ch]@15
-  //int *v40; // [sp+4h] [bp-48h]@15
   AIDirection v41; // [sp+14h] [bp-38h]@46
-  float v42; // [sp+30h] [bp-1Ch]@23
-  float v43; // [sp+34h] [bp-18h]@45
   float outy2; // [sp+38h] [bp-14h]@33
   float outx2; // [sp+3Ch] [bp-10h]@33
   int outz; // [sp+40h] [bp-Ch]@6
@@ -1677,7 +997,8 @@
       {
         v18 = pParty->sRotationY - stru_5C6E00->uIntegerHalfPi;
         v37.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        *(_QWORD *)&v37 = *(_QWORD *)&pParty->vPosition.x;
+        v37.x = pParty->vPosition.x;
+        v37.y = pParty->vPosition.y;
         Vec3_int_::Rotate(24, v18, 0, v37, &outx, &outy, &outz);
         break;
       }
@@ -1685,7 +1006,8 @@
       {
         v18 = pParty->sRotationY - stru_5C6E00->uIntegerHalfPi;
         v37.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
-        *(_QWORD *)&v37.x = *(_QWORD *)&pParty->vPosition.x;
+        v37.x = pParty->vPosition.x;
+        v37.y = pParty->vPosition.y;
         Vec3_int_::Rotate(8, v18, 0, v37, &outx, &outy, &outz);
         break;
       }
@@ -1693,7 +1015,8 @@
       {
         v37.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
         v18 = stru_5C6E00->uIntegerHalfPi + pParty->sRotationY;
-        *(_QWORD *)&v37.x = *(_QWORD *)&pParty->vPosition.x;
+        v37.x = pParty->vPosition.x;
+        v37.y = pParty->vPosition.y;
         Vec3_int_::Rotate(8, v18, 0, v37, &outx, &outy, &outz);
         break;
       }
@@ -1701,7 +1024,8 @@
       {
         v37.z = pParty->vPosition.z + (signed int)pParty->uPartyHeight / 3;
         v18 = stru_5C6E00->uIntegerHalfPi + pParty->sRotationY;
-        *(_QWORD *)&v37 = *(_QWORD *)&pParty->vPosition.x;
+        v37.x = pParty->vPosition.x;
+        v37.y = pParty->vPosition.y;
         Vec3_int_::Rotate(24, v18, 0, v37, &outx, &outy, &outz);
         break;
       }
@@ -1736,22 +1060,22 @@
   {
     case OBJECT_Item:
     {
-      outx2 = pSpriteObjects[v5].vPosition.x;
-      outy2 = pSpriteObjects[v5].vPosition.y;
+      outx2 = (float)pSpriteObjects[v5].vPosition.x;
+      outy2 =(float) pSpriteObjects[v5].vPosition.y;
       a4 = pSpriteObjects[v5].vPosition.z;
       break;
     }
     case OBJECT_Actor:
     {
-      outx2 = pActors[v5].vPosition.x;
-      outy2 = pActors[v5].vPosition.y;
+      outx2 = (float)pActors[v5].vPosition.x;
+      outy2 = (float)pActors[v5].vPosition.y;
       a4 = pActors[v5].vPosition.z - (unsigned int)(signed __int64)((double)pActors[v5].uActorHeight * -0.75);
       break;
     }
     case OBJECT_Player:
     {
-      outx2 = pParty->vPosition.x;
-      outy2 = pParty->vPosition.y;
+      outx2 = (float)pParty->vPosition.x;
+      outy2 = (float)pParty->vPosition.y;
       if ( !a4 )
         a4 = pParty->sEyelevel;
       a4 = pParty->vPosition.z + a4;
@@ -1759,8 +1083,8 @@
     }
     case OBJECT_Decoration:
     {
-      outx2 = pLevelDecorations[v5].vPosition.x;
-      outy2 = pLevelDecorations[v5].vPosition.y;
+      outx2 = (float)pLevelDecorations[v5].vPosition.x;
+      outy2 = (float)pLevelDecorations[v5].vPosition.y;
       a4 = pLevelDecorations[v5].vPosition.z;
       break;
     }
@@ -1775,19 +1099,17 @@
     {
       if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
       {
-        outx2 = (pIndoor->pFaces[v5].pBounding.x1 + pIndoor->pFaces[v5].pBounding.x2) >> 1;
-        outy2 = (pIndoor->pFaces[v5].pBounding.y1 + pIndoor->pFaces[v5].pBounding.y2) >> 1;
+        outx2 = (float)((pIndoor->pFaces[v5].pBounding.x1 + pIndoor->pFaces[v5].pBounding.x2) >> 1);
+        outy2 = (float)((pIndoor->pFaces[v5].pBounding.y1 + pIndoor->pFaces[v5].pBounding.y2) >> 1);
         a4 = (pIndoor->pFaces[v5].pBounding.z1 + pIndoor->pFaces[v5].pBounding.z2) >> 1;
       }
       break;
     }
   }
   
-  v31 = (double)outx2 - (double)outx;
-  v42 = v31;
-  v32 = (double)outy2 - (double)outy;
-  v43 = v32;
-  a4a = (double)a4 - (double)outz;
+  v31 = (float)outx2 - (float)outx;
+  v32 = (float)outy2 - (float)outy;
+  a4a = (float)a4 - (float)outz;
   outx2 = v32 * v32;
   outy2 = v31 * v31;
   v33 = sqrt(a4a * a4a + outy2 + outx2);
@@ -1803,12 +1125,12 @@
   }
   else
   {
-    v41.vDirection.x = (signed __int64)(1.0 / v33 * v42 * 65536.0);
-    v41.vDirection.y = (signed __int64)(1.0 / v33 * v43 * 65536.0);
-    v41.vDirection.z = (signed __int64)(1.0 / v33 * a4a * 65536.0);
-    v41.uDistance = (signed __int64)v33;
-    v41.uDistanceXZ = sqrt(outy2 + outx2);
-    v41.uYawAngle = stru_5C6E00->Atan2((signed __int64)v42, (signed __int64)v43);
+    v41.vDirection.x = (int32_t)(1.0 / v33 * v31 * 65536.0);
+    v41.vDirection.y = (int32_t)(1.0 / v33 * v32 * 65536.0);
+    v41.vDirection.z = (int32_t)(1.0 / v33 * a4a * 65536.0);
+    v41.uDistance = (uint)v33;
+    v41.uDistanceXZ = (uint)sqrt(outy2 + outx2);
+    v41.uYawAngle = stru_5C6E00->Atan2((signed __int64)v31, (signed __int64)v32);
     v41.uPitchAngle = stru_5C6E00->Atan2(v41.uDistanceXZ, (signed __int64)a4a);
   }
   result = pOut;
@@ -1819,44 +1141,33 @@
 //----- (00404030) --------------------------------------------------------
 void Actor::AI_FaceObject(unsigned int uActorID, unsigned int uObjID, int _48, AIDirection *a4)
 {
-  unsigned int v4; // edi@1
-  unsigned int v5; // esi@1
-  //unsigned int result; // eax@2
   AIDirection *v7; // eax@3
-  unsigned int v8; // ecx@3
   Actor *v9; // ebx@3
-  AIDirection *v10; // esi@4
-  unsigned __int16 v11; // ax@5
   AIDirection a3; // [sp+8h] [bp-38h]@4
-  AIDirection v13; // [sp+24h] [bp-1Ch]@4
 
-  v4 = uObjID;
-  v5 = uActorID;
   if ( rand() % 100 >= 5 )
   {
-    v7 = a4;
-    v8 = 0;
-    v9 = &pActors[v5];
+    v9 = &pActors[uActorID];
     if ( !a4 )
     {
-      v10 = Actor::GetDirectionInfo(PID(OBJECT_Actor, v5), v4, &a3, 0);
-      v7 = &v13;
-      memcpy(&v13, v10, sizeof(v13));
-      v8 = 0;
+      v7 = Actor::GetDirectionInfo(PID(OBJECT_Actor, uActorID), uObjID, &a3, 0);
+    }
+    else
+    {
+      v7 = a4;
     }
-    v9->uYawAngle = LOWORD(v7->uYawAngle);
-    v11 = LOWORD(v7->uPitchAngle);
-    v9->uCurrentActionTime = v8;
-    v9->vVelocity.z = v8;
-    v9->vVelocity.y = v8;
-    v9->vVelocity.x = v8;
-    v9->uPitchAngle = v11;
+    v9->uYawAngle = v7->uYawAngle;
+    v9->uCurrentActionTime = 0;
+    v9->vVelocity.z = 0;
+    v9->vVelocity.y = 0;
+    v9->vVelocity.x = 0;
+    v9->uPitchAngle = v7->uPitchAngle;
     v9->uCurrentActionLength = 256;
     v9->uAIState = Interacting;
     v9->UpdateAnimation();
   }
   else
-    Actor::AI_Bored(v5, v4, a4);
+    Actor::AI_Bored(uActorID, uObjID, a4);
 }
 
 //----- (00403F58) --------------------------------------------------------
--- a/Actor.h	Wed Oct 16 13:34:26 2013 +0200
+++ b/Actor.h	Wed Oct 16 13:34:49 2013 +0200
@@ -227,10 +227,13 @@
   static void AI_Stand(unsigned int uActorID, unsigned int object_to_face_pid, unsigned int uActionLength, struct AIDirection *a4);
   static void AI_StandOrBored(unsigned int uActorID, signed int uObjID, int uActionLength, struct AIDirection *a4);
   static void AI_FaceObject(unsigned int uActorID, unsigned int uObjID, int _48, struct AIDirection *a4);
-  static struct AIDirection *__fastcall GetDirectionInfo(unsigned int uObj1ID, unsigned int uObj2ID, struct AIDirection *pOut, int a4);
-  static signed int __fastcall Explode(unsigned int uActorID);
-  static char __fastcall AI_RangedAttack(unsigned int uActorID, struct AIDirection *a2, int type, char a4);
-  static void __fastcall AI_SpellAttack(unsigned int uActorID, struct AIDirection *pDir, int uSpellID, int a4, unsigned int uSkillLevel);
+  static struct AIDirection * GetDirectionInfo(unsigned int uObj1ID, unsigned int uObj2ID, struct AIDirection *pOut, int a4);
+  static void Explode(unsigned int uActorID);
+  static void AI_RangedAttack(unsigned int uActorID, struct AIDirection *a2, int type, char a4);
+  static void AI_SpellAttack(unsigned int uActorID, struct AIDirection *pDir, int uSpellID, int a4, unsigned int uSkillLevel);
+
+  static unsigned short GetObjDescId( int spellId );
+
   static void AggroSurroundingPeasants(unsigned int uActorID, int a2);
   static bool ArePeasantsOfSameFaction(Actor *a1, Actor *a2);
   static bool StealFrom(unsigned int uActorID);
--- a/CastSpellInfo.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/CastSpellInfo.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -1115,7 +1115,7 @@
 			}
 			if ( pPlayer->CanCastSpell(uRequiredMana) )
 			{
-				v92 = pParty->pPlayers;//[0].pConditions[1];
+				v92 = pParty->pPlayers.data();//[0].pConditions[1];
 				LODWORD(v727) = 1;
 				do
 				{
@@ -1174,7 +1174,7 @@
 			}
 			v105 = 0;
 			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			v730b = pParty->pPlayers;//[0].pPlayerBuffs[1];
+			v730b = pParty->pPlayers.data();//[0].pPlayerBuffs[1];
 			do
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, v105);
@@ -2373,7 +2373,7 @@
 			}
 			a2 = 0;
 			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			v357 = pParty->pPlayers;//[0].pPlayerBuffs[11];
+			v357 = pParty->pPlayers.data();//[0].pPlayerBuffs[11];
 			do
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
@@ -3232,7 +3232,7 @@
 			amount = 5 * v2 + 10;
 			if ( !pPlayer->CanCastSpell(uRequiredMana) )
 				break;
-			v501 = pParty->pPlayers;
+			v501 = pParty->pPlayers.data();
 			int v1 = 0;
 			do
 			{
@@ -3241,7 +3241,7 @@
 				++v501;
 				++v1;
 			}
-			while ( (signed int)v501 < (signed int)pParty->pHirelings );
+			while ( (signed int)v501 < (signed int)pParty->pHirelings.data() );
 			LODWORD(v727) = 1;
 			break;
 		}
@@ -3468,7 +3468,7 @@
 			v732 = (300 * amount * v2 + 60) << 7;
 			v730 = v2 + 5;
 			int _v726 = 0;
-			v553 = pParty->pPlayers;//[0].pConditions[1];
+			v553 = pParty->pPlayers.data();//[0].pConditions[1];
 			*((float *)&v733) = (double)v732 * 0.033333335;
 			do
 			{
@@ -3799,7 +3799,7 @@
 			int _v733 = 0;
 			memset(&achieved_awards, 0, 4000);
 			int i = 0;
-			pNPCData = pParty->pHirelings;
+			pNPCData = pParty->pHirelings.data();
 			do
 			{
 				if ( pNPCData->pName != 0)
@@ -3851,7 +3851,7 @@
 			//*(int *)((char *)&pParty->pPlayers[3].pInstalledBeacons[3].field_18 + v610) = 1;
 			pParty->pHirelings[v609-1].evt_A = 1;
 
-			v612 = pParty->pPlayers;
+			v612 = pParty->pPlayers.data();
 			do
 			{
 				v612->sHealth = v612->GetMaxHealth();
@@ -3891,7 +3891,7 @@
 			}
 			a2 = 0;
 			v717 = (signed int)(signed __int64)((double)(signed int)((int)v733 << 7) * 0.033333335);
-			v619 = pParty->pPlayers;//[0].pPlayerBuffs[10];
+			v619 = pParty->pPlayers.data();//[0].pPlayerBuffs[10];
 			do
 			{
 				pGame->GetStru6()->SetPlayerBuffAnim(pCastSpell->uSpellID, a2);
--- a/Events.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/Events.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -1188,13 +1188,13 @@
           //v7 = "";
           break;
           }
-        v87 = pParty->pPlayers;
+        v87 = pParty->pPlayers.data();
         do
           {
           v87->ReceiveDamage(v85, (DAMAGE_TYPE)_evt->v6);
           ++v87;
           }
-          while ( (signed int)v87 < (signed int)pParty->pHirelings );
+          while ( (signed int)v87 < (signed int)pParty->pHirelings.data() );
           ++curr_seq_num;
           v4 = v124;
 
--- a/Game.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/Game.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -450,19 +450,19 @@
         pVideoPlayer->Unload();
       SaveGame(0, 0);
       ++pParty->uNumDeaths;
-      pPlayer = pParty->pPlayers;
+      pPlayer = pParty->pPlayers.data();
       do
       {
         pPlayer->SetVariable(VAR_Award, 85);
         ++pPlayer;
       }
-      while ( (signed int)pPlayer < (signed int)pParty->pHirelings );
+      while ( (signed int)pPlayer < (signed int)pParty->pHirelings.data() );
       pParty->days_played_without_rest = 0;
       pParty->uTimePlayed += 0x276000ui64;
       LOWORD(pParty->uFlags) &= ~0x204;
       pParty->SetGold(0);
       pOtherOverlayList->Reset();
-      memset(pParty->pPartyBuffs, 0, 0x140u);
+      memset(pParty->pPartyBuffs.data(), 0, 0x140u);
 
       if ( pParty->bTurnBasedModeOn == 1 )
       {
--- a/NPC.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/NPC.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -1438,13 +1438,13 @@
         if ( uMessageParam == 82 && contract_approved ) //join guild
         {
           Party::TakeGold(gold_transaction_amount);
-          v4 = pParty->pPlayers;
+          v4 = pParty->pPlayers.data();
           do
           {
             v4->SetVariable(VAR_Award, dword_F8B1AC_award_bit_number);
             ++v4;
           }
-          while ( (signed int)v4 < (signed int)pParty->pHirelings );
+          while ( (signed int)v4 < (signed int)pParty->pHirelings.data() );
           switch ( dword_F8B1D8 )
           {
             case 19:
@@ -1531,7 +1531,7 @@
   }
   else
   {
-    memcpy(pParty->pHirelings, pCurrentNPCInfo, 0x4Cu);
+    memcpy(pParty->pHirelings.data(), pCurrentNPCInfo, 0x4Cu);
     v24 = pCurrentNPCInfo->pName;
     v22 = pParty->pHireling1Name;
   }
@@ -1834,7 +1834,7 @@
   v3 = abs((int)sDialogue_SpeakingActorNPC_ID) - 1;
   v4 = 0;
   v5 = 0;
-  v6 = pParty->pHirelings;
+  v6 = pParty->pHirelings.data();
   do
   {
     if ( v6->pName )
--- a/Party.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/Party.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -99,10 +99,10 @@
     uNumDeaths = 0;
     uNumPrisonTerms = 0;
     uNumBountiesCollected = 0;
-    memset(monster_for_hunting_killed, 5, sizeof(__int16));
-    memset(monster_id_for_hunting, 5, sizeof(__int16));
+    memset(monster_for_hunting_killed.data(), 5, sizeof(__int16));
+    memset(monster_id_for_hunting.data(), 5, sizeof(__int16));
     memset(_quest_bits, 64, sizeof(__int8));
-    memset(pArcomageWins, 16, sizeof(__int8));
+    memset(pArcomageWins.data(), 16, sizeof(__int8));
     uNumArenaPageWins = 0;
     uNumArenaSquireWins = 0;
     uNumArenaKnightWins = 0;
@@ -293,7 +293,7 @@
   pHireling1Name[0] = 0;
   pHireling2Name[0] = 0;
   this->hirelingScrollPosition = 0;
-  memset(pHirelings, 0, 2 * sizeof(*pHirelings));
+  memset(pHirelings.data(), 0, 2 * sizeof(NPCData));
 
   strcpy(this->pPlayers[0].pName, pGlobalTXT_LocalizationStrings[509]); //Zoltan
   this->pPlayers[0].uPrevFace = 17;
@@ -492,7 +492,7 @@
   bTurnBasedModeOn = false;
 
   uActiveCharacter = 1;
-  ::pPlayers.ZerothIndex() = pPlayers;
+  ::pPlayers.ZerothIndex() = &pPlayers[0];
   for (uint i = 0; i < 4; ++i)
     ::pPlayers[i + 1] = &pPlayers[i];
 
@@ -554,7 +554,7 @@
   uFlags = 0;
   memset(_autonote_bits, 0, 26);
   memset(_quest_bits, 0, 64);
-  memset(pIsArtifactFound, 0, 29);
+  memset(pIsArtifactFound.data(), 0, 29);
   _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_RED_POTION_ACTIVE, 1);
   _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_SEASHELL_ACTIVE, 1);
   _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_LONGBOW_ACTIVE, 1);
@@ -562,7 +562,7 @@
   _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_LUTE_ACTIVE, 1);
   _449B7E_toggle_bit(_quest_bits, PARTY_QUEST_EMERALD_HAT_ACTIVE, 1);
 
-  memset(PartyTimes._shop_ban_times,0,53*sizeof(__int64));
+  memset(PartyTimes._shop_ban_times.data(),0,53*sizeof(__int64));
 
   memcpy(pNPCStats->pNewNPCData, pNPCStats->pNPCData, 0x94BCu);
   memcpy(pNPCStats->pGroups_copy, pNPCStats->pGroups, 0x66u);
--- a/Party.h	Wed Oct 16 13:34:26 2013 +0200
+++ b/Party.h	Wed Oct 16 13:34:49 2013 +0200
@@ -2,6 +2,7 @@
 #include "Player.h"
 #include "NPC.h"
 #include "mm7_data.h"
+#include <array>
 
 
 
@@ -150,14 +151,12 @@
 #pragma pack(push, 1)
 struct PartyTimeStruct
 {
-  //__int64 field_0[10];
-  __int64 bountyHunting_next_generation_time[10];
- // int field_50[170];
-  __int64 Shops_next_generation_time[85];//field_50
-  __int64 _shop_ban_times[53];      
-  unsigned __int64 CounterEventValues[10];  // (0xACD314h in Silvo's binary)
-  __int64 HistoryEventTimes[29];   // (0xACD364h in Silvo's binary)
-  unsigned __int64 _s_times[20]; //5d8 440h+8*51     //(0xACD44Ch in Silvo's binary)
+  std::array<__int64, 10> bountyHunting_next_generation_time;
+  std::array<__int64, 85> Shops_next_generation_time;//field_50
+  std::array<__int64, 53> _shop_ban_times;      
+  std::array<unsigned __int64, 10> CounterEventValues;  // (0xACD314h in Silvo's binary)
+  std::array<__int64, 29> HistoryEventTimes;   // (0xACD364h in Silvo's binary)
+  std::array<unsigned __int64, 20> _s_times; //5d8 440h+8*51     //(0xACD44Ch in Silvo's binary)
 };
 #pragma pack(pop)
 
@@ -269,42 +268,42 @@
   int uNumPrisonTerms;
   unsigned int uNumBountiesCollected;
   int field_74C;
-  __int16 monster_id_for_hunting[5];
-  __int16 monster_for_hunting_killed[5];
+  std::array<__int16, 5> monster_id_for_hunting;
+  std::array<__int16, 5> monster_for_hunting_killed;
   unsigned char   days_played_without_rest;
   unsigned __int8 _quest_bits[64];
-  unsigned __int8 pArcomageWins[16];
+  std::array<unsigned __int8, 16> pArcomageWins;
   char field_7B5_in_arena_quest;
   char uNumArenaPageWins;
   char uNumArenaSquireWins;
   char uNumArenaKnightWins;
   char uNumArenaLordWins;
-  char pIsArtifactFound[29];  //7ba
-  char field_7d7[39];
+  std::array<char, 29> pIsArtifactFound;  //7ba
+  std::array<char, 39> field_7d7;
   unsigned char _autonote_bits[26];
-  char field_818[60];
-  char field_854[32];
+  std::array<char, 60> field_818;
+  std::array<char, 32> field_854;
   int uNumArcomageWins;
   int uNumArcomageLoses;
   unsigned int bTurnBasedModeOn;
   int field_880;
   int uFlags2;
   PartyAlignment alignment;
-  SpellBuff pPartyBuffs[20];
-  Player pPlayers[4];
-  NPCData pHirelings[2];
+  std::array<SpellBuff, 20> pPartyBuffs;
+  std::array<Player, 4> pPlayers;
+  std::array<NPCData, 2> pHirelings;
   ItemGen pPickedItem;
   unsigned int uFlags;
-  ItemGen StandartItemsInShops[53][12];
-  ItemGen SpecialItemsInShops[53][12];   //D0EC
-  ItemGen SpellBooksInGuilds[32][12];
-  char field_1605C[24];
+  std::array<std::array<ItemGen, 12>, 53> StandartItemsInShops;
+  std::array<std::array<ItemGen, 12>, 53> SpecialItemsInShops;   //D0EC
+  std::array<std::array<ItemGen, 12>, 32> SpellBooksInGuilds;
+  std::array<char, 24> field_1605C;
   char pHireling1Name[100];
   char pHireling2Name[100];
   int armageddon_timer;
   int field_16140;
-  int pTurnBasedPlayerRecoveryTimes[4];
-  int InTheShopFlags[53];
+  std::array<int, 4> pTurnBasedPlayerRecoveryTimes;
+  std::array<int, 53> InTheShopFlags;
   int uFine;
   float flt_TorchlightColorR;
   float flt_TorchlightColorG;
--- a/Player.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/Player.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -7026,7 +7026,7 @@
         }
       }
       if ( pParty->pHirelings[0].uProfession == pValue )
-        memset(pParty->pHirelings, 0, sizeof(NPCData));
+        memset(pParty->pHirelings.data(), 0, sizeof(NPCData));
       if ( pParty->pHirelings[1].uProfession == pValue )
         memset(&pParty->pHirelings[1], 0, sizeof(NPCData));
       pParty->hirelingScrollPosition = 0;
--- a/TurnEngine.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/TurnEngine.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -135,7 +135,7 @@
     pEventTimer->TrackGameTime();
     pAudioPlayer->StopChannels(-1, -1);
     pAudioPlayer->PlaySound(SOUND_207, 0, 0, -1, 0, 0, 0, 0);
-    pPlayer = pParty->pPlayers;
+    pPlayer = pParty->pPlayers.data();
     dword_50C998_turnbased_icon_1A = 8 * pIconsFrameTable->pIcons[uIconID_TurnStart].uAnimLength;
     dword_50C994 = 0;
 
--- a/UI/UICharacter.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/UI/UICharacter.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -1767,7 +1767,7 @@
   memset(byte_5111F6.data(), 0, sizeof(byte_5111F6));
   for (uint i = 0; i < 4; ++i)
   {
-    auto player = pParty->pPlayers + i;
+    auto player = &pParty->pPlayers[i];
 
     if (player->HasItem(ITEM_ARTIFACT_GOVERNORS_ARMOR, 1))    byte_5111F6[0] = 1;
     if (player->HasItem(ITEM_ARTIFACT_YORUBA, 1))             byte_5111F6[1] = 1;
--- a/mm7_2.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/mm7_2.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -310,14 +310,14 @@
       if ( v0 >= (signed int)uNumActors || (signed int)uNumActors <= 0)
       {
         uDialogueType = 91;
-        v4 = pParty->pPlayers;
+        v4 = pParty->pPlayers.data();
         ++*((char *)&pParty->monster_for_hunting_killed[3] + (unsigned __int8)pParty->field_7B5_in_arena_quest + 1);
         do
         {
           v4->SetVariable(VAR_Award, (unsigned __int8)pParty->field_7B5_in_arena_quest + 3);
           ++v4;
         }
-        while ( (signed int)v4 < (signed int)pParty->pHirelings );
+        while ( (signed int)v4 < (signed int)pParty->pHirelings.data() );
         pParty->PartyFindsGold(gold_transaction_amount, 0);
         pAudioPlayer->PlaySound((SoundID)14060, 0, 0, -1, 0, 0, 0, 0);
         pParty->field_7B5_in_arena_quest = -1;
@@ -442,7 +442,7 @@
     ++pMessageQueue_50CBD0->uNumMessages;
   }*/
   pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, 1, 0);
-  v2 = pParty->pPlayers;
+  v2 = pParty->pPlayers.data();
   do
   {
     v3 = v2->GetActualLevel();
@@ -454,7 +454,7 @@
     }
     ++v2;
   }
-  while ( (signed int)v2 < (signed int)pParty->pHirelings );
+  while ( (signed int)v2 < (signed int)pParty->pHirelings.data() );
   if ( uDialogueType == 85 )
   {
     num_monsters = v4;
@@ -734,11 +734,11 @@
     v19 = 1;
   pRenderer->BeginScene();
   pWindow.DrawTitleText(pFont, 1u, 0x23u, 1u, pGlobalTXT_LocalizationStrings[9], 3u);
-  v3 = pParty->pPlayers;//[0].pName;
+  v3 = pParty->pPlayers.data();//[0].pName;
   v23 = 0i64;
   v20 = 0;
   //for ( i = (int)pParty->pPlayers[0].pName; ; v3 = (char *)i )
-  for ( i = pParty->pPlayers; ; v3 = i )
+  for ( i = pParty->pPlayers.data(); ; v3 = i )
   {
 	v4 = pClassNames[v3->classType];
     v5 = v3->GetBaseLevel();
--- a/mm7_3.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/mm7_3.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -1611,7 +1611,7 @@
       pParty->uFlags &= ~PARTY_FLAGS_1_LANDING;
     else for (uint i = 0; i < 4; ++i)
     {                                      // receive falling damage
-      auto player = pParty->pPlayers + i;
+      auto player = &pParty->pPlayers[i];
       if (!player->HasEnchantedItemEquipped(72) && !player->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS))
       {
         player->ReceiveDamage((pParty->uFallStartY - party_z) * (0.1f * player->GetMaxHealth()) / 256, DMGT_PHISYCAL);
@@ -2205,7 +2205,7 @@
     }
     else for (int _i = 0; _i < 4; ++_i)     // receive falling damage
     {
-      auto player = pParty->pPlayers + _i;
+      auto player = &pParty->pPlayers[_i];
 
       if ( !player->HasEnchantedItemEquipped(72) && !player->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) )
       {
@@ -2637,7 +2637,7 @@
 		{ // falling scream
 		  for (int i = 0; i < 4; ++i)
 		  {
-			auto player = pParty->pPlayers + i;
+			auto player = &pParty->pPlayers[i];
 			if (!player->HasEnchantedItemEquipped(72) && !player->WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) && player->CanAct())
 			  player->PlaySound(SPEECH_66, 0);
 		  }
--- a/mm7_4.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/mm7_4.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -454,7 +454,7 @@
   struct IDirectDrawSurface *v11; // eax@23
   int v12; // eax@26
 
-  v0 = pParty->pPlayers;
+  v0 = pParty->pPlayers.data();
   do
   {
     if (SoundSetAction[24][0])
@@ -499,7 +499,7 @@
     }
     ++v0;
   }
-  while ( (signed int)v0 < (signed int)pParty->pHirelings );
+  while ( (signed int)v0 < (signed int)pParty->pHirelings.data() );
   v6 = pIcons_LOD->uNumLoadedFiles - 1;
   if ( v6 >= pIcons_LOD->pFacesLock )
   {
@@ -1043,7 +1043,7 @@
       if (pParty->days_played_without_rest > 3)
         for (uint i = 0; i < 4; ++i)
         {
-          Player* player = pParty->pPlayers + i;
+          Player* player = &pParty->pPlayers[i];
 
           player->Zero();
 
@@ -2870,7 +2870,7 @@
     if ( (unsigned __int16)_449B57_test_bit(pParty->_quest_bits, *v0) )
     {
       v1 = 0;
-      v2 = pParty->pPlayers;
+      v2 = pParty->pPlayers.data();
       do
       {
         LOBYTE(v3) = v2->CompareVariable(VAR_PlayerItemInHands, *(v0+1));
@@ -2879,7 +2879,7 @@
         ++v2;
         ++v1;
       }
-      while ( (signed int)v2 < (signed int)pParty->pHirelings );
+      while ( (signed int)v2 < (signed int)pParty->pHirelings.data() );
       if ( v1 == 4 )
         break;
     }
@@ -2898,14 +2898,14 @@
   if ( contract_approved == 601 )
   {
     v5 = 0;
-    v12 = pParty->pPlayers;//[0].uClass;
+    v12 = pParty->pPlayers.data();//[0].uClass;
     v9 = 0;
     while ( 1 )
     {
       if ( v12->classType == PLAYER_CLASS_LICH )
       {
         v10 = 0;
-        v6 = pParty->pPlayers;//[0].pInventoryItems[0].field_1A;
+        v6 = pParty->pPlayers.data();//[0].pInventoryItems[0].field_1A;
         do
         {
 		  v7 = v6->pInventoryItemList.data();
@@ -3438,7 +3438,7 @@
 			}
 			if ( pParty->pHirelings[0].pName && !_stricmp(pParty->pHirelings[0].pName, speakingNPC->pName) )
 			{
-				v11 = pParty->pHirelings;
+				v11 = pParty->pHirelings.data();
 				memset(v11, 0, sizeof(NPCData));
 			}
 			else if ( pParty->pHirelings[1].pName && !_stricmp(pParty->pHirelings[1].pName, speakingNPC->pName) )
@@ -3489,7 +3489,7 @@
 			}
 			else
 			{
-				memcpy(pParty->pHirelings, speakingNPC, 0x4Cu);
+				memcpy(pParty->pHirelings.data(), speakingNPC, 0x4Cu);
 				v15 = speakingNPC->pName;
 				v13 = pParty->pHireling1Name;
 			}
@@ -3547,7 +3547,7 @@
 			}
 			if ( pParty->pHirelings[0].pName && !_stricmp(pParty->pHirelings[0].pName, speakingNPC->pName) )
 			{
-				v11 = pParty->pHirelings;
+				v11 = pParty->pHirelings.data();
 				memset(v11, 0, sizeof(NPCData));
 			}
 			else if ( pParty->pHirelings[1].pName && !_stricmp(pParty->pHirelings[1].pName, speakingNPC->pName) )
--- a/mm7_5.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/mm7_5.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -1704,26 +1704,26 @@
               pParty->RestAndHeal();
               if ( ((pParty->uNumFoodRations - (signed int)GetTravelTime()) & 0x80000000u) != 0 )
               {
-                pPlayer7 = pParty->pPlayers;
+                pPlayer7 = pParty->pPlayers.data();
                 do
                 {
                   pPlayer7->SetCondition(1, 0);
                   ++pPlayer7;
                 }
-                while ( (signed int)pPlayer7 < (signed int)pParty->pHirelings );
+                while ( (signed int)pPlayer7 < (signed int)pParty->pHirelings.data() );
                 ++pParty->days_played_without_rest;
               }
               Party::TakeFood((unsigned int)GetTravelTime());
             }
             else
             {
-              pPlayer8 = pParty->pPlayers;
+              pPlayer8 = pParty->pPlayers.data();
               do
               {
                 pPlayer8->SetCondition(1, 0);
                 ++pPlayer8;
               }
-              while ( (signed int)pPlayer8 < (signed int)pParty->pHirelings );
+              while ( (signed int)pPlayer8 < (signed int)pParty->pHirelings.data() );
               ++pParty->days_played_without_rest;
             }
             pPaletteManager->ResetNonLocked();
@@ -3279,7 +3279,7 @@
 
   if ( pMessageQueue_50CBD0->uNumMessages )
   {
-    pPlayer = pParty->pPlayers;
+    pPlayer = pParty->pPlayers.data();
     do
     {
       int param2;
@@ -3748,7 +3748,7 @@
           if ( sub_407A1C(pParty->vPosition.x, pParty->vPosition.y, pParty->vPosition.z + pParty->sEyelevel, v25) )
           {
             v26 = 0;
-            v27 = pParty->pPlayers;//[0].pConditions[15];
+            v27 = pParty->pPlayers.data();//[0].pConditions[15];
             do
             {
 				if ( !(HIDWORD(v27->pConditions[14]) | LODWORD(v27->pConditions[14])) && !v27->pConditions[15] && !v27->pConditions[16] )
--- a/mm7_6.cpp	Wed Oct 16 13:34:26 2013 +0200
+++ b/mm7_6.cpp	Wed Oct 16 13:34:49 2013 +0200
@@ -429,13 +429,13 @@
 		}
 	case 80:
 		{
-		v6 = pParty->pPartyBuffs;
+		v6 = pParty->pPartyBuffs.data();
 		while ( (signed __int64)v6->uExpireTime <= 0 )
 		{
 			++v6;
 			if ( v6 > &pParty->pPartyBuffs[PARTY_BUFF_WIZARD_EYE] )
 			{
-				v7 = pParty->pPlayers;//[0].pPlayerBuffs;
+				v7 = pParty->pPlayers.data();//[0].pPlayerBuffs;
 				v8 = 0;
 				v9 = v7->pPlayerBuffs.data();
 				while ( v9->uExpireTime <= 0i64 )