changeset 1940:a50511e4f3c6

Слияние
author Ritor1
date Thu, 24 Oct 2013 15:31:22 +0600
parents 027ed24b8017 (current diff) 1cbfb6e50e48 (diff)
children b0d96beedc80
files Actor.cpp Actor.h mm7_data.h
diffstat 5 files changed, 144 insertions(+), 275 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Thu Oct 24 15:28:33 2013 +0600
+++ b/Actor.cpp	Thu Oct 24 15:31:22 2013 +0600
@@ -848,7 +848,21 @@
     default:
       return;
   }
-  a1.uObjectDescID = GetObjDescId(a1.uType);
+  bool found = false;
+  for ( uint i = 0; i < pObjectList->uNumObjects; i++)
+  {
+    if (pObjectList->pObjects[i].uObjectID == a1.uType)
+    {
+      a1.uObjectDescID = i;
+      found = true;
+      break;
+    }
+  }
+  if (!found)
+  {
+    Error("Item not found");
+    return;
+  }
   a1.stru_24.Reset();
   a1.vPosition.x = actPtr->vPosition.x;
   a1.spell_id = 0;
@@ -3559,91 +3573,42 @@
 //----- (00439474) --------------------------------------------------------
 void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, Vec3_int_ *pVelocity)
 {
-  //signed int v3; // eax@1
-  SpriteObject *v4; // ebx@1
-  //int v5; // edx@3
-  //bool uPlayerID; // eax@3
-  //Player *pPlayer; // edi@4
+  SpriteObject *projectileSprite; // ebx@1
   Actor *pMonster; // esi@7
-  //SpriteObject *v9; // ebx@12
-  int v10; // eax@12
-  int v11; // ebx@12
-  unsigned int v12; // ecx@12
-  int v13; // edx@15
-  int v14; // edx@17
-  int v15; // eax@24
   unsigned __int16 v16; // cx@25
-  int v17; // eax@29
-  int v18; // eax@38
-  unsigned __int8 v19; // zf@38
-  unsigned __int8 v20; // sf@38
-  int v21; // edx@44
-  int v22; // eax@44
-  unsigned __int8 v23; // zf@44
-  unsigned __int8 v24; // sf@44
-  int v25; // edx@51
-  int v26; // ecx@51
-  //signed int v27; // eax@51
-  //int v28; // eax@53
-  signed int v29; // eax@76
-  signed int v30; // eax@84
-  signed int v31; // eax@92
-  int v32; // eax@94
   int v33; // eax@100
-  int v34; // eax@104
-  signed int v35; // eax@104
-  double v36; // st7@104
-  float v37; // ST08_4@104
-  float v38; // ST04_4@104
-  float v39; // ST00_4@104
   int v40; // ebx@107
-  unsigned int v41; // ebx@109
-  signed __int64 v42; // qax@125
+  int extraRecoveryTime; // qax@125
   unsigned __int16 v43; // ax@132
-  char v44; // bl@132
   unsigned __int16 v45; // ax@132
   unsigned __int64 v46; // [sp+Ch] [bp-60h]@6
-  const char *v47; // [sp+14h] [bp-58h]@104
   char *pPlayerName; // [sp+18h] [bp-54h]@12
   char *pMonsterName; // [sp+1Ch] [bp-50h]@6
-  int v50; // [sp+20h] [bp-4Ch]@6
-  //unsigned __int64 *v51; // [sp+30h] [bp-3Ch]@6
-  int v52; // [sp+34h] [bp-38h]@12
-  //int v53; // [sp+38h] [bp-34h]@10
-  //int v54; // [sp+3Ch] [bp-30h]@1
-  //int v55; // [sp+40h] [bp-2Ch]@12
   signed int a4; // [sp+44h] [bp-28h]@1
-  PlayerEquipment *v57; // [sp+48h] [bp-24h]@10
-  //int v58; // [sp+4Ch] [bp-20h]@10
-  int v59; // [sp+50h] [bp-1Ch]@1
-  unsigned int uActorID_Monster_; // [sp+54h] [bp-18h]@1
+  bool IsAdditionalDamagePossible; // [sp+50h] [bp-1Ch]@1
   int v61; // [sp+58h] [bp-14h]@1
-  bool v62; // [sp+5Ch] [bp-10h]@1
+  bool isLifeStealing; // [sp+5Ch] [bp-10h]@1
   int uDamageAmount; // [sp+60h] [bp-Ch]@1
-  int a2; // [sp+64h] [bp-8h]@27
-  int a3; // [sp+6Bh] [bp-1h]@6
+  DAMAGE_TYPE attackElement; // [sp+64h] [bp-8h]@27
 
-  //v3 = a1;
-  v4 = 0;
-  uActorID_Monster_ = uActorID_Monster;
-  //v54 = a1;
+  projectileSprite = 0;
   uDamageAmount = 0;
   a4 = 0;
   v61 = 0;
-  v59 = 0;
-  v62 = 0;
+  IsAdditionalDamagePossible = false;
+  isLifeStealing = 0;
   if ( PID_TYPE(a1) == OBJECT_Item)
   {
-    v4 = &pSpriteObjects[PID_ID(a1)];
-    v61 = v4->field_60_distance_related_prolly_lod;
-    a1 = v4->spell_caster_pid;
+    projectileSprite = &pSpriteObjects[PID_ID(a1)];
+    v61 = projectileSprite->field_60_distance_related_prolly_lod;
+    a1 = projectileSprite->spell_caster_pid;
   }
   if (PID_TYPE(a1) != OBJECT_Player)
     return;
 
   assert(PID_ID(abs(a1)) < 4);
-  auto player = &pParty->pPlayers[PID_ID(a1)];
-  pMonster = &pActors[uActorID_Monster_];
+  Player* player = &pParty->pPlayers[PID_ID(a1)];
+  pMonster = &pActors[uActorID_Monster];
   if (pMonster->IsNotAlive())
     return;
 
@@ -3652,14 +3617,14 @@
     pMonster->uAttributes |= 0x20000u;
   bool hit_will_stun = false,
        hit_will_paralyze = false;
-  if ( !v4 )
+  if ( !projectileSprite )
   {
     int main_hand_idx = player->pEquipment.uMainHand;
-    v59 = 1;
+    IsAdditionalDamagePossible = true;
     if ( player->HasItemEquipped(EQUIP_MAIN_HAND) )
     {
-      auto main_hand_skill = player->GetMainHandItem()->GetPlayerSkillType();
-      auto main_hand_mastery = SkillToMastery(player->pActiveSkills[main_hand_skill]);
+      uint main_hand_skill = player->GetMainHandItem()->GetPlayerSkillType();
+      uint main_hand_mastery = SkillToMastery(player->pActiveSkills[main_hand_skill]);
       switch (main_hand_skill)
       {
         case PLAYER_SKILL_STAFF:
@@ -3684,9 +3649,8 @@
         break;
       }
     }
-    v50 = pMonster->pMonsterInfo.uID;
-    a2 = 4;
-    uDamageAmount = player->CalculateMeleeDamageTo(false, false, v50);
+    attackElement = DMGT_PHISYCAL;
+    uDamageAmount = player->CalculateMeleeDamageTo(false, false, pMonster->pMonsterInfo.uID);
     if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
     {
       player->PlaySound(SPEECH_52, 0);
@@ -3695,40 +3659,22 @@
   }
   else
   {
-    v19 = v4->spell_id == SPELL_DARK_SOULDRINKER;
-    v61 = v4->field_60_distance_related_prolly_lod;
-    if ( !v19 )
+    v61 = projectileSprite->field_60_distance_related_prolly_lod;
+    if ( projectileSprite->spell_id != SPELL_DARK_SOULDRINKER )
     {
-	    v50 = pParty->vPosition.x - v4->vPosition.x;
-      pMonsterName = (char *)(pParty->vPosition.y - v4->vPosition.y);
-      pPlayerName = (char *)(pParty->vPosition.z - v4->vPosition.z);
-      v52 = abs((int)pPlayerName);
-      v61 = abs(v50);
-      v10 = abs(v50);
-      v11 = (int)abs((int)pMonsterName);
-      v12 = v52;
-      if ( v10 < v11)
+      std::array<int, 3> distances;
+      distances[0] = abs(pParty->vPosition.x - projectileSprite->vPosition.x);
+      distances[1] = abs(pParty->vPosition.y - projectileSprite->vPosition.y);
+      distances[2] = abs(pParty->vPosition.z - projectileSprite->vPosition.z);
+      std::sort(distances.begin(), distances.end());
+      v61 = ((unsigned int)(11 * distances[1]) >> 5) + (distances[0] >> 2) + distances[2];
+
+      if ( v61 >= 5120 && !(BYTE1(pMonster->uAttributes) & 4) )
       {
-        v10 = (int)v11;
-        v11 = v10;
+        return;
       }
-      if ( v10 < v52 )
-      {
-        v13 = v10;
-        v10 = v52;
-        v12 = v13;
-      }
-      if ( v11 < (signed int)v12 )
+      else if ( v61 >= 2560 )
       {
-        v14 = v12;
-        v12 = v11;
-        v11 = v14;
-      }
-      v61 = ((unsigned int)(11 * v11) >> 5) + (v12 >> 2) + v10;
-      if ( v61 >= 2560 )
-      {
-        if ( v61 >= 5120 && !(BYTE1(pMonster->uAttributes) & 4) )
-          return;
         v61 = 2;
       }
       else
@@ -3737,14 +3683,14 @@
       }
     }
 
-    switch (v4->spell_id)
+    switch (projectileSprite->spell_id)
     {
       case SPELL_LASER_PROJECTILE:
-        v16 = player->pActiveSkills[7];
+        v16 = player->pActiveSkills[PLAYER_SKILL_BLASTER];
         v61 = 1;
         if ( (signed int)SkillToMastery(v16) >= 3 )
-          a4 = player->pActiveSkills[7] & 0x3F;
-        a2 = 4;
+          a4 = player->pActiveSkills[PLAYER_SKILL_BLASTER] & 0x3F;
+        attackElement = DMGT_PHISYCAL;
         uDamageAmount = player->CalculateMeleeDamageTo(true, true, 0);
         if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
         {
@@ -3753,14 +3699,11 @@
         }
         break;
       case SPELL_101:
-        a2 = 0;
-        v18 = player->CalculateRangedDamageTo(0);
-        v19 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
-        v20 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
-        uDamageAmount = v18;
-        if ( !v20 && (!(v20 | v19) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
+        attackElement = DMGT_FIRE;
+        uDamageAmount = player->CalculateRangedDamageTo(0);
+        if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 )
           uDamageAmount >>= 1;
-        v59 = 1;
+        IsAdditionalDamagePossible = true;
         if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
         {
           player->PlaySound(SPEECH_52, 0);
@@ -3768,18 +3711,12 @@
         }
         break;
       case SPELL_EARTH_BLADES:
-        a4 = 5 * v4->spell_level;
-        a2 = player->GetSpellSchool(0x27u);
-        v21 = v4->spell_level;
-        v50 = pMonster->sCurrentHP;
-        pMonsterName = (char *)v4->spell_skill;
-        v22 = _43AFE3_calc_spell_damage(39, v21, v4->spell_skill, v50);
-        v23 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0;
-        v24 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0;
-        uDamageAmount = v22;
-        if ( !v24 && (!(v24 | v23) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) )
+        a4 = 5 * projectileSprite->spell_level;
+        attackElement = (DAMAGE_TYPE)player->GetSpellSchool(SPELL_EARTH_BLADES);
+        uDamageAmount = _43AFE3_calc_spell_damage(39, projectileSprite->spell_level, projectileSprite->spell_skill, pMonster->sCurrentHP);
+        if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 )
           uDamageAmount >>= 1;
-        v59 = 0;
+        IsAdditionalDamagePossible = false;
         if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
         {
           player->PlaySound(SPEECH_52, 0);
@@ -3788,7 +3725,7 @@
         break;
       case SPELL_EARTH_STUN:
         uDamageAmount = 0;
-        a2 = 4;
+        attackElement = DMGT_PHISYCAL;
         hit_will_stun = 1;
         if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
         {
@@ -3797,15 +3734,14 @@
         }
         break;
       case SPELL_BOW_ARROW:
-        v50 = pMonster->word_000086_some_monster_id;
-        a2 = 4;
-        uDamageAmount = player->CalculateRangedDamageTo(v50);
+        attackElement = DMGT_PHISYCAL;
+        uDamageAmount = player->CalculateRangedDamageTo(pMonster->word_000086_some_monster_id);
         if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 )
           uDamageAmount /= 2;
-        v59 = 1;
-        if ( v4->stru_24.uItemID != 0 && v4->stru_24.uSpecEnchantmentType == 3 )  //of carnage
+        IsAdditionalDamagePossible = true;
+        if ( projectileSprite->stru_24.uItemID != 0 && projectileSprite->stru_24.uSpecEnchantmentType == 3 )  //of carnage
         {
-          a2 = 0;
+          attackElement = DMGT_FIRE;
         }
         else if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) )
         {
@@ -3815,13 +3751,9 @@
         break;
 
       default:
-        a2 = player->GetSpellSchool(v4->spell_id);
-        v25 = v4->spell_level;
-        v26 = v4->spell_id;
-        v50 = pMonster->sCurrentHP;
-        pMonsterName = (char *)v4->spell_skill;
-        v59 = 0;
-        uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, v4->spell_skill, v50);
+        attackElement = (DAMAGE_TYPE)player->GetSpellSchool(projectileSprite->spell_id);
+        IsAdditionalDamagePossible = false;
+        uDamageAmount = _43AFE3_calc_spell_damage(projectileSprite->spell_id, projectileSprite->spell_level, projectileSprite->spell_skill, pMonster->sCurrentHP);
         break;
     }
   }
@@ -3830,232 +3762,169 @@
     uDamageAmount /= 2;
   if ( pMonster->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 )
     uDamageAmount = 0;
-  v61 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, uDamageAmount);
-  if ( !v4 && player->IsUnarmed() && player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime > 0 )
+  v61 = stru_50C198.CalcMagicalDamageToActor(pMonster, attackElement, uDamageAmount);
+  if ( !projectileSprite && player->IsUnarmed() && player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime > 0 )
   {
-    v50 = player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uPower;
-    v29 = stru_50C198.CalcMagicalDamageToActor(pMonster, 8, v50);
-    v61 += v29;
+    v61 += stru_50C198.CalcMagicalDamageToActor(pMonster, 8, player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uPower);
   }
   uDamageAmount = v61;
-  if ( v59 )
+  if ( IsAdditionalDamagePossible )
   {
-    if ( v4 )
+    if ( projectileSprite )
     {
-      a4 = v4->stru_24._439DF3_get_additional_damage(&a2, &v62);
-      if ( v62 && pMonster->sCurrentHP > 0 )
+      a4 = projectileSprite->stru_24._439DF3_get_additional_damage((int*)&attackElement, &isLifeStealing);
+      if ( isLifeStealing && pMonster->sCurrentHP > 0 )
       {
         player->sHealth += v61 / 5;
         if ( player->sHealth > player->GetMaxHealth() )
           player->sHealth = player->GetMaxHealth();
-        v62 = 0;
       }
-      v30 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4);
-      uDamageAmount = v61 + v30;
+      uDamageAmount += stru_50C198.CalcMagicalDamageToActor(pMonster, attackElement, a4);
     }
     else
     {
-      v59 = 0;
-      v57 = &player->pEquipment;
-      do
+      for (int i = 0; i < 2; i++)
       {
-        if ( player->HasItemEquipped((ITEM_EQUIP_TYPE)v59) )
+        if ( player->HasItemEquipped((ITEM_EQUIP_TYPE)i) )
         {
-          auto _s = (ItemGen *)&player->pInventoryItemList[v57->uShield - 1];
-          a4 = _s->_439DF3_get_additional_damage(&a2, &v62);
-          if ( v62 && pMonster->sCurrentHP > 0 )
+          ItemGen* item;
+          if (i == 0)
+            item = player->GetMainHandItem();
+          else
+            item = player->GetOffHandItem();
+          a4 = item->_439DF3_get_additional_damage((int*)&attackElement, &isLifeStealing);
+          if ( isLifeStealing && pMonster->sCurrentHP > 0 )
           {
             player->sHealth += v61 / 5;
             if ( player->sHealth > player->GetMaxHealth() )
               player->sHealth = player->GetMaxHealth();
-            v62 = 0;
           }
-          v31 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4);
-          uDamageAmount += v31;
+          uDamageAmount += stru_50C198.CalcMagicalDamageToActor(pMonster, attackElement, a4);
         }
-        ++v59;
-        v57 = (PlayerEquipment *)((char *)v57 + 4);
       }
-      while ( v59 <= 1 );
     }
   }
-  v32 = uDamageAmount;
   pMonster->sCurrentHP -= uDamageAmount;
-  if ( !v32 && !hit_will_stun )
+  if ( uDamageAmount == 0 && !hit_will_stun )
   {
     player->PlaySound(SPEECH_52, 0);
     return;
   }
   if ( pMonster->sCurrentHP > 0 )
   {
-    Actor::AI_Stun(uActorID_Monster_, a1, 0);
-    Actor::AggroSurroundingPeasants(uActorID_Monster_, 1);
+    Actor::AI_Stun(uActorID_Monster, a1, 0);
+    Actor::AggroSurroundingPeasants(uActorID_Monster, 1);
     if ( bShowDamage )
     {
-      v50 = uDamageAmount;
-      pMonsterName = (char *)pMonster;
-      pPlayerName = player->pName;
-      if ( v4 )
-        v47 = pGlobalTXT_LocalizationStrings[189];// "%s shoots %s for %lu points"
+      if ( projectileSprite )
+        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[189], player->pName, pMonster->pActorName, uDamageAmount);// "%s shoots %s for %lu points"
       else
-        v47 = pGlobalTXT_LocalizationStrings[164];// "%s hits %s for %lu damage"
-      sprintfex(pTmpBuf.data(), v47, pPlayerName, pMonsterName, v50);
+        sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[164], player->pName, pMonster->pActorName, uDamageAmount);// "%s hits %s for %lu damage"
       ShowStatusBarString(pTmpBuf.data(), 2u);
     }
-    v41 = 0;
   }
   else
   {
     if ( pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].bQuestMonster & 1 )
     {
-      v33 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * pMonster->uActorRadius : pMonster->uActorRadius;
-      //v55 = v33;
-      if ( pRenderer->pRenderD3D )
+      if ( pRenderer->pRenderD3D && pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
       {
-        if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS )
-        {
-          v50 = 0;
-          pMonsterName = 0;
-          v34 = pMonster->vPosition.z;
-          *(float *)&pPlayerName = (double)v33;
-          //v51 = (unsigned __int64 *)v34;
-          *(float *)&v47 = 0.0;
-          v35 = pMonster->vPosition.y;
-          *((float *)&v46 + 1) = 0.0;
-          *(float *)&v46 = 1.0;
-          v36 = (double)(signed int)pMonster->vPosition.z;
-          //v51 = (unsigned __int64 *)v35;
-          v37 = v36;
-          //v51 = (unsigned __int64 *)pMonster->vPosition.x;
-          v38 = (double)v35;
-          v39 = (double)(signed int)pMonster->vPosition.x;
-          pDecalBuilder->AddBloodsplat(v39, v38, v37, 1.0, 0.0, 0.0, *(float *)&pPlayerName, 0, 0);
-        }
+        v33 = byte_4D864C && pGame->uFlags & 80000 ? 10 * pMonster->uActorRadius : pMonster->uActorRadius;
+        pDecalBuilder->AddBloodsplat((float)pMonster->vPosition.x, (float)pMonster->vPosition.y, (float)pMonster->vPosition.z, 1.0, 0.0, 0.0, (float)v33, 0, 0);
       }
     }
-    Actor::Die(uActorID_Monster_);
-    Actor::ApplyFineForKillingPeasant(uActorID_Monster_);
-    Actor::AggroSurroundingPeasants(uActorID_Monster_, 1);
+    Actor::Die(uActorID_Monster);
+    Actor::ApplyFineForKillingPeasant(uActorID_Monster);
+    Actor::AggroSurroundingPeasants(uActorID_Monster, 1);
     if ( pMonster->pMonsterInfo.uExp )
       pParty->GivePartyExp(pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].uExp);
     v40 = SPEECH_51;
     if ( rand() % 100 < 20 )
       v40 = ((signed int)pMonster->pMonsterInfo.uHP >= 100) + 1;
     player->PlaySound((PlayerSpeech)v40, 0);
-    v41 = 0;
     if ( bShowDamage )
     {
-      v50 = (int)pMonster;
       pMonsterName = (char *)uDamageAmount;
       pPlayerName = player->pName;             // "%s inflicts %lu points killing %s"
       sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[175], player->pName, uDamageAmount, pMonster);
       ShowStatusBarString(pTmpBuf.data(), 2u);
     }
   }
-  if ( SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) >= (signed int)v41
-    && (SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) > (signed int)v41
-     || LODWORD(pMonster->pActorBuffs[20].uExpireTime) > v41)
-    && uDamageAmount != v41 )
-    player->ReceiveDamage(uDamageAmount, (DAMAGE_TYPE)a2);
-  v50 = 24;
-  v59 = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP;
-  if ( (player->GetSpecialItemBonus(24) || hit_will_stun != v41)
-    && stru_50C198.GetMagicalResistance(pMonster, 3u) )
+  if ( pMonster->pActorBuffs[ACTOR_BUFF_PAIN_REFLECTION].uExpireTime > 0
+    && uDamageAmount != 0 )
+    player->ReceiveDamage(uDamageAmount, attackElement);
+  int knockbackValue = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP;
+  if ( (player->GetSpecialItemBonus(24) || hit_will_stun) && stru_50C198.GetMagicalResistance(pMonster, DMGT_EARTH) )
   {
-    LODWORD(v42) = 20;
-    v59 = 10;
-    if ( pParty->bTurnBasedModeOn == v41 )
-      v42 = (signed __int64)(flt_6BE3A8_debug_recmod2 * 42.66666666666666);
-    pMonster->pMonsterInfo.uRecoveryTime += v42;
-    if ( bShowDamage != v41 )
+    extraRecoveryTime = 20;
+    knockbackValue = 10;
+    if ( !pParty->bTurnBasedModeOn )
+      extraRecoveryTime = (int)(flt_6BE3A8_debug_recmod2 * 42.66666666666666);
+    pMonster->pMonsterInfo.uRecoveryTime += extraRecoveryTime;
+    if ( bShowDamage  )
     {
-      v50 = (int)pMonster;
       pMonsterName = player->pName;            // "%s stuns %s"
       sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[635], player->pName, pMonster);
       ShowStatusBarString(pTmpBuf.data(), 2u);
     }
   }
-  if ( hit_will_paralyze != v41 )
+  if ( hit_will_paralyze && pMonster->CanAct() && stru_50C198.GetMagicalResistance(pMonster, DMGT_EARTH))
   {
-    if ( pMonster->CanAct() )
+    v43 = player->GetActualSkillLevel(PLAYER_SKILL_MACE);
+    v45 = SkillToMastery(v43);
+    v46 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(7680 * (v43 & 0x3F)) * 0.033333335);
+    pMonster->pActorBuffs[ACTOR_BUFF_PARALYZED].Apply(v46, v45, 0, 0, 0);
+    if ( bShowDamage )
     {
-      if ( stru_50C198.GetMagicalResistance(pMonster, 3) )
-      {
-        LOBYTE(v43) = player->GetActualSkillLevel(PLAYER_SKILL_MACE);
-        v44 = v43;
-        v45 = SkillToMastery(v43);
-        //v51 = (unsigned __int64 *)(7680 * (v44 & 0x3F));
-        v46 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(7680 * (v44 & 0x3F)) * 0.033333335);
-        pMonster->pActorBuffs[6].Apply(v46, v45, 0, 0, 0);
-        if ( bShowDamage )
-        {
-          v50 = (int)pMonster;
-          pMonsterName = player->pName;        // "%s paralyzes %s"
-          sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[636], player->pName, pMonster);
-          ShowStatusBarString(pTmpBuf.data(), 2u);
-        }
-      }
+      pMonsterName = player->pName;        // "%s paralyzes %s"
+      sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[636], player->pName, pMonster);
+      ShowStatusBarString(pTmpBuf.data(), 2u);
     }
   }
-  if ( v59 > 10 )
-    v59 = 10;
+  if ( knockbackValue > 10 )
+    knockbackValue = 10;
   if ( !MonsterStats::BelongsToSupertype(pMonster->pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT) )
   {
-    pVelocity->x = (unsigned __int64)(v59 * (signed __int64)pVelocity->x) >> 16;
-    pVelocity->y = (unsigned __int64)(v59 * (signed __int64)pVelocity->y) >> 16;
-    pVelocity->z = (unsigned __int64)(v59 * (signed __int64)pVelocity->z) >> 16;
+    pVelocity->x = (unsigned __int64)(knockbackValue * (signed __int64)pVelocity->x) >> 16;
+    pVelocity->y = (unsigned __int64)(knockbackValue * (signed __int64)pVelocity->y) >> 16;
+    pVelocity->z = (unsigned __int64)(knockbackValue * (signed __int64)pVelocity->z) >> 16;
     pMonster->vVelocity.x = 50 * LOWORD(pVelocity->x);
     pMonster->vVelocity.y = 50 * LOWORD(pVelocity->y);
     pMonster->vVelocity.z = 50 * LOWORD(pVelocity->z);
   }
-  Actor::AddBloodsplatOnDamageOverlay(uActorID_Monster_, 1, v61);
+  Actor::AddBloodsplatOnDamageOverlay(uActorID_Monster, 1, v61);
 }
 //----- (004BBF61) --------------------------------------------------------
-void __fastcall _4BBF61_summon_actor(int a1, __int16 x, int y, int z)
+void Actor::_4BBF61_summon_actor( int a1, __int16 x, int y, int z )
 {
-  size_t v4; // esi@1
-  int monster_id; // edi@1
-  __int16 v6; // ax@4
   Actor *v7; // esi@5
-  int v8; // eax@5
   MonsterInfo *v9; // edi@5
   MonsterDesc *v10; // ebx@5
-  unsigned __int16 *v11; // ebx@5
   int v12; // ebx@7
   int v13; // eax@8
-  __int16 x_; // [sp+8h] [bp-Ch]@1
-  __int16 v15; // [sp+Ch] [bp-8h]@1
   __int16 v16; // [sp+10h] [bp-4h]@3
-  signed int ya; // [sp+1Ch] [bp+8h]@5
 
-  v4 = uNumActors;
-  monster_id = a1;
-  x_ = x;
-  v15 = a1;
   if (uNumActors < 500)
   {
     v16 = 0;
     if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
     {
-      v6 = pIndoor->GetSector(x, y, z);
-      v4 = uNumActors;
-      v16 = v6;
+      v16 = pIndoor->GetSector(x, y, z);
     }
-    v7 = &pActors[v4];
+    v7 = &pActors[uNumActors];
     v7->Reset();
-    v8 = monster_id;
-    v9 = &pMonsterStats->pInfos[monster_id];
-    v10 = &pMonsterList->pMonsters[v8 - 1];
+    v9 = &pMonsterStats->pInfos[a1];
+    v10 = &pMonsterList->pMonsters[a1 - 1];
     strcpy(v7->pActorName, v9->pName);
     v7->sCurrentHP = LOWORD(v9->uHP);
     memcpy(&v7->pMonsterInfo, v9, 0x58u);
-    v7->word_000086_some_monster_id = v15;
+    v7->word_000086_some_monster_id = a1;
     v7->uActorRadius = v10->uMonsterRadius;
     v7->uActorHeight = v10->uMonsterHeight;
     v7->uMovementSpeed = v10->uMovementSpeed;
-    v7->vInitialPosition.x = x_;
-    v7->vPosition.x = x_;
-    BYTE2(v7->uAttributes) |= 8u;
+    v7->vInitialPosition.x = x;
+    v7->vPosition.x = x;
+    v7->uAttributes |= 80000;
     v7->pMonsterInfo.uTreasureType = 0;
     v7->pMonsterInfo.uTreasureLevel = 0;
     v7->pMonsterInfo.uTreasureDiceSides = 0;
@@ -4070,18 +3939,16 @@
     v7->uGroup = 1;
     v7->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
     v7->PrepareSprites(0);
-    v11 = v10->pSoundSampleIDs;
-    ya = 4;
+    for ( int i = 0; i < 4; i++)
+    {
+      pSoundList->LoadSound(v10->pSoundSampleIDs[i], 0);
+    }
+    v12 = 0;
     do
     {
-      pSoundList->LoadSound((signed __int16)*v11, 0);
-      ++v11;
-      --ya;
+      LOWORD(v13) = pSoundList->LoadSound(v12 + word_4EE088_sound_ids[v9->uSpell1ID], 1u);
+      v12++;
     }
-    while ( ya );
-    v12 = 0;
-    do
-      LOWORD(v13) = pSoundList->LoadSound(v12++ + word_4EE088_sound_ids[v9->uSpell1ID], 1u);
     while ( v13 );
     ++uNumActors;
   }
--- a/Actor.h	Thu Oct 24 15:28:33 2013 +0600
+++ b/Actor.h	Thu Oct 24 15:31:22 2013 +0600
@@ -246,6 +246,7 @@
   static void AddBloodsplatOnDamageOverlay(unsigned int uActorID, int a2, signed int a3);
 
   static bool _46DF1A_collide_against_actor(int a1, int a2);
+  static void _4BBF61_summon_actor(int a1, __int16 x, int y, int z); // idb
 
   char pActorName[32];
   signed __int16 sNPC_ID;
--- a/Items.cpp	Thu Oct 24 15:28:33 2013 +0600
+++ b/Items.cpp	Thu Oct 24 15:31:22 2013 +0600
@@ -154,6 +154,7 @@
 //----- (00439DF3) --------------------------------------------------------
 int ItemGen::_439DF3_get_additional_damage(int *damage_type, bool *draintargetHP)
 	{
+    *draintargetHP = false;
 	*damage_type = 0;
 	if ( !uItemID )
 		return 0;
--- a/mm7_2.cpp	Thu Oct 24 15:28:33 2013 +0600
+++ b/mm7_2.cpp	Thu Oct 24 15:31:22 2013 +0600
@@ -22,6 +22,7 @@
 #include "GammaControl.h"
 #include "stru6.h"
 
+#include "Actor.h"
 #include "Vis.h"
 #include "MapInfo.h"
 #include "Game.h"
@@ -600,7 +601,7 @@
   {
     monster_y = pMonsterArenaPlacements[i].y;
     v21 = rand();
-    _4BBF61_summon_actor((unsigned __int16)monster_ids[v21 % num_monsters], pMonsterArenaPlacements[i].x, monster_y, 1);
+    Actor::_4BBF61_summon_actor((unsigned __int16)monster_ids[v21 % num_monsters], pMonsterArenaPlacements[i].x, monster_y, 1);
   }
   pAudioPlayer->PlaySound((SoundID)14060, 0, 0, -1, 0, 0, 0, 0);
 }
--- a/mm7_data.h	Thu Oct 24 15:28:33 2013 +0600
+++ b/mm7_data.h	Thu Oct 24 15:31:22 2013 +0600
@@ -1202,7 +1202,6 @@
 __int64 GetExperienceRequiredForLevel(int a1);
 void CheckBountyRespawnAndAward();
 void Arena_SelectionFightLevel();
-void __fastcall _4BBF61_summon_actor(int a1, __int16 x, int y, int z); // idb
 void ArenaFight();
 void SpellBookGenerator();
 void UI_CreateEndConversationButton();