changeset 295:640a176c030f

sub_42ECB5
author Nomad
date Tue, 19 Feb 2013 13:29:02 +0200
parents 250e49fef6f6
children af7e848d6def
files AudioPlayer.h Indoor.cpp Items.cpp Items.h Vis.cpp Vis.h mm7_2.cpp mm7_3.cpp mm7_4.cpp mm7_5.cpp mm7_6.cpp mm7_data.h
diffstat 12 files changed, 189 insertions(+), 258 deletions(-) [+]
line wrap: on
line diff
--- a/AudioPlayer.h	Mon Feb 18 16:39:49 2013 +0600
+++ b/AudioPlayer.h	Tue Feb 19 13:29:02 2013 +0200
@@ -78,6 +78,14 @@
   SOUND_8 = 0x8,
   SOUND_27 = 0x1B,
   SOUND_Button = 66,
+  SOUND_67 = 67,
+  SOUND_71 = 71,
+  SOUND_78 = 78,
+  SOUND_80 = 80,
+  SOUND_81 = 81,
+  SOUND_83 = 83,
+  SOUND_84 = 84,
+  SOUND_85 = 85,
   SOUND_Arcomage_LoseResources = 0x78,
   SOUND_Arcomage_AddResources = 0x79,
   SOUND_Arcomage_TowerWallDamage = 0x7A,
--- a/Indoor.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/Indoor.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -4226,7 +4226,7 @@
               {
                 if ( (v36 & 7) == OBJECT_Decoration)
                 {
-                  _this = sub_452A9E(v0->vVelocity.x * v0->vVelocity.x + v0->vVelocity.y * v0->vVelocity.y);
+                  _this = integer_sqrt(v0->vVelocity.x * v0->vVelocity.x + v0->vVelocity.y * v0->vVelocity.y);
                   v45 = stru_5C6E00->Atan2(
                           v0->vPosition.x - pLevelDecorations[v37].vPosition.x,
                           v0->vPosition.y - pLevelDecorations[v37].vPosition.y);
--- a/Items.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/Items.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -1616,7 +1616,7 @@
       case 39: requested_equip = EQUIP_BOOTS; break;
       case 40: requested_equip = EQUIP_RING; break;
       case 41: requested_equip = EQUIP_AMULET; break;
-      case 42: requested_equip = EQUIP_C; break;
+      case 42: requested_equip = EQUIP_WAND; break;
       case 43: requested_equip = EQUIP_F; break;
       case 44: requested_equip = EQUIP_POTION; break;
       case 45: requested_equip = EQUIP_REAGENT; break;
@@ -1757,7 +1757,7 @@
   {
     if ( v20 > EQUIP_AMULET )
     {
-      if ( v20 == EQUIP_C )
+      if ( v20 == EQUIP_WAND )
       {
         v21 = rand() % 6 + pItemsTable->pItems[v4->uItemID].uDamageMod + 1;
         v4->uNumCharges = v21;
--- a/Items.h	Mon Feb 18 16:39:49 2013 +0600
+++ b/Items.h	Tue Feb 19 13:29:02 2013 +0200
@@ -74,7 +74,7 @@
   EQUIP_BOOTS = 0x9,
   EQUIP_RING = 0xA,
   EQUIP_AMULET = 0xB,
-  EQUIP_C = 0xC,
+  EQUIP_WAND = 12,
   EQUIP_REAGENT = 0xD,
   EQUIP_POTION = 0xE,
   EQUIP_F = 0xF,
--- a/Vis.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/Vis.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -428,37 +428,34 @@
 //{return DoesRayIntersectBillboard(fDepth, uD3DBillboardIdx);}
 
 //----- (004C1944) --------------------------------------------------------
-int Vis::_4C1944(int object_id, unsigned int a3, int a4, int a5, int a6)
+int Vis::PickClosestActor(int object_id, unsigned int pick_depth, int a4, int a5, int a6)
 {
-  float v6; // ST00_4@3
-  int result; // eax@4
+  //float v6; // ST00_4@3
+  //int result; // eax@4
   Vis_SelectionFilter v8; // [sp+18h] [bp-20h]@3
-  __int64 v9; // [sp+2Ch] [bp-Ch]@3
-  Vis *v14; // [sp+34h] [bp-4h]@1
+  //__int64 v9; // [sp+2Ch] [bp-Ch]@3
+  //Vis *v14; // [sp+34h] [bp-4h]@1
 
-  v14 = this;
+  //v14 = this;
 
   static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8;
-
+  
+  v8.object_type = VisObjectType_Sprite;
   v8.object_id = object_id;
   v8.field_8 = a6;
   v8.field_C = a5;
   v8.field_10 = a4;
-  v9 = a3;
   Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers = 0;
-  v6 = (double)a3;
-  v8.object_type = VisObjectType_Sprite;
-  PickBillboards_Keyboard(v6, &Vis_static_sub_4C1944_stru_F8BDE8, &v8);
+  PickBillboards_Keyboard(pick_depth, &Vis_static_sub_4C1944_stru_F8BDE8, &v8);
   Vis_static_sub_4C1944_stru_F8BDE8.create_object_pointers(Vis_SelectionList::Unique);
   sort_object_pointers(
     Vis_static_sub_4C1944_stru_F8BDE8.object_pointers,
     0,
     Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers - 1);
-  if ( (signed int)Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers <= 0 )
-    result = -1;
-  else
-    result = Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[0]->sZValue;
-  return result;
+
+  if (!Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers)
+    return -1;
+  return Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[0]->sZValue;
 }
 
 //----- (004C1A02) --------------------------------------------------------
--- a/Vis.h	Mon Feb 18 16:39:49 2013 +0600
+++ b/Vis.h	Tue Feb 19 13:29:02 2013 +0200
@@ -105,7 +105,7 @@
   void GetPolygonCenter(struct RenderVertexD3D3 *pVertices, unsigned int uNumVertices, float *pCenterX, float *pCenterY);
   void GetPolygonScreenSpaceCenter(struct RenderVertexSoft *vertices, int num_vertices, float *out_center_x, float *out_center_y);
   bool IsPointInsideD3DBillboard(struct RenderBillboardD3D *a1, float x, float y);
-  int _4C1944(int object_id, unsigned int a3, int a4, int a5, int a6);
+  int PickClosestActor(int object_id, unsigned int pick_depth, int a4, int a5, int a6);
   void _4C1A02();
   bool SortVectors_x(RenderVertexSoft *a2, int a3, int a4);
   int get_object_zbuf_val(Vis_ObjectInfo *info);
--- a/mm7_2.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/mm7_2.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -9124,20 +9124,20 @@
 }
 
 //----- (00452A9E) --------------------------------------------------------
-int sub_452A9E(int square_distance)
+int integer_sqrt(int val)
 {
   signed int result; // eax@2
-  int v2; // edx@3
+  unsigned int v2; // edx@3
   unsigned int v3; // edi@3
   //signed int v4; // ebx@3
   int v5; // esi@4
 
-  if (square_distance < 1)
-    return square_distance;
+  if (val < 1)
+    return val;
 
 
     v2 = 0;
-    v3 = square_distance;
+    v3 = val;
     result = 0;
     //v4 = 16;
   for (uint i = 0; i < 16; ++i)
@@ -9146,7 +9146,7 @@
       v2 = (v3 >> 30) | 4 * v2;
       v5 = 2 * result + 1;
       v3 *= 4;
-      if ( v2 >= (unsigned int)v5 )
+      if ( v2 >= v5 )
       {
         ++result;
         v2 -= v5;
@@ -9154,8 +9154,9 @@
       //--v4;
   }
     //while ( v4 );
-    if ( square_distance - result * result >= (unsigned int)(result - 1) )
+    if ( val - result * result >= (unsigned int)(result - 1) )
       ++result;
+    return result;
 }
 
 //----- (00452AE2) --------------------------------------------------------
--- a/mm7_3.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/mm7_3.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -680,7 +680,7 @@
                     result = v9 + pParty->vPosition.z;
                     if ( v6 <= (signed int)(v9 + pParty->vPosition.z) || v8 )
                     {
-                      result = sub_452A9E(v3 * v3 - v4 * v4);
+                      result = integer_sqrt(v3 * v3 - v4 * v4);
                       v7 = v5 - result;
                       if ( v7 < 0 )
                         v7 = 0;
@@ -820,7 +820,7 @@
   int v28; // [sp+14h] [bp+8h]@5
 
   v2 = this;
-  v3 = sub_452A9E(this->field_24 * this->field_24 + this->field_20 * this->field_20 + this->field_1C * this->field_1C);
+  v3 = integer_sqrt(this->field_24 * this->field_24 + this->field_20 * this->field_20 + this->field_1C * this->field_1C);
   v4 = v3 | 1;
   v5 = v2->field_1C;
   v2->field_64 = v3 | 1;
@@ -1260,7 +1260,7 @@
           viewparams->bRedrawGameUI = 1;
           break;
         case 5:
-          v47 = sub_452A9E(v0->vVelocity.x * v0->vVelocity.x + v0->vVelocity.y * v0->vVelocity.y);
+          v47 = integer_sqrt(v0->vVelocity.x * v0->vVelocity.x + v0->vVelocity.y * v0->vVelocity.y);
           v48 = stru_5C6E00->Atan2(
                   v0->vPosition.x - pLevelDecorations[v39].vPosition.x,
                   v0->vPosition.y - pLevelDecorations[v39].vPosition.y);
@@ -1578,7 +1578,7 @@
       v15 = (signed int)stru_721530.uFaceID >> 3;
       if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
       {
-        v40 = sub_452A9E(v1->vVelocity.x * v1->vVelocity.x + v1->vVelocity.y * v1->vVelocity.y);
+        v40 = integer_sqrt(v1->vVelocity.x * v1->vVelocity.x + v1->vVelocity.y * v1->vVelocity.y);
         v23 = stru_5C6E00->Atan2(
                 v1->vPosition.x - pLevelDecorations[v15].vPosition.x,
                 v1->vPosition.y - pLevelDecorations[v15].vPosition.y);
@@ -2161,7 +2161,7 @@
       if ( !(v42 ^ v43) )
         return;
     }
-    v57 = sub_452A9E(v1->vVelocity.y * v1->vVelocity.y + v1->vVelocity.x * v1->vVelocity.x);
+    v57 = integer_sqrt(v1->vVelocity.y * v1->vVelocity.y + v1->vVelocity.x * v1->vVelocity.x);
     v38 = stru_5C6E00->Atan2(
             v1->vPosition.x - pLevelDecorations[v30].vPosition.x,
             v1->vPosition.y - pLevelDecorations[v30].vPosition.y);
@@ -2825,7 +2825,7 @@
     }
     if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
     {
-      v53 = sub_452A9E(v2 * v2 + v1 * v1);
+      v53 = integer_sqrt(v2 * v2 + v1 * v1);
       v80 = v53;
       v54 = stru_5C6E00->Atan2(
               new_party_x - pLevelDecorations[stru_721530.uFaceID >> 3].vPosition.x,
@@ -2919,7 +2919,7 @@
   }
   if ( bWalkSound && pParty->field_6F8 <= 0 )
   {
-    if ( sub_452A9E((pParty->vPosition.x - new_party_x) * (pParty->vPosition.x - new_party_x) + (pParty->vPosition.y - new_party_y)
+    if ( integer_sqrt((pParty->vPosition.x - new_party_x) * (pParty->vPosition.x - new_party_x) + (pParty->vPosition.y - new_party_y)
                                                                             * (pParty->vPosition.y - new_party_y)
                                                                             + (pParty->vPosition.z - new_party_z)
                                                                             * (pParty->vPosition.z - new_party_z)) <= 16 )
@@ -3756,7 +3756,7 @@
     }
     if ( (stru_721530.uFaceID & 7) == OBJECT_Decoration)
     {
-      v56 = sub_452A9E(v2 * v2 + v128 * v128);
+      v56 = integer_sqrt(v2 * v2 + v128 * v128);
       v118 = v56;
       v57 = stru_5C6E00->Atan2(
               _angle_x - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.x,
@@ -3877,7 +3877,7 @@
     v122 = abs(pParty->vPosition.x - v116);
     v126 = abs(pParty->vPosition.y - v117);
     v62 = abs(pParty->vPosition.z - v123);
-    if ( sub_452A9E(v122 * v122 + v126 * v126 + v62 * v62) < 8 )
+    if ( integer_sqrt(v122 * v122 + v126 * v126 + v62 * v62) < 8 )
       goto LABEL_344;
     if ( v114 && (!bJumping || v101) )
     {
--- a/mm7_4.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/mm7_4.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -1117,7 +1117,7 @@
   }
   else
   {
-    v13 = v12 - sub_452A9E(v17 * v17 - v11 * v11);
+    v13 = v12 - integer_sqrt(v17 * v17 - v11 * v11);
     if ( v13 < 0 )
       v13 = 0;
     if ( v13 < stru_721530.field_7C )
@@ -1200,7 +1200,7 @@
                         {
                           if ( v11 <= v18 + v10 )
                           {
-                            v12 = v9 - sub_452A9E(v8 * v8 - v17 * v17);
+                            v12 = v9 - integer_sqrt(v8 * v8 - v17 * v17);
                             if ( v12 < 0 )
                               v12 = 0;
                             if ( v12 < stru_721530.field_7C )
@@ -1309,7 +1309,7 @@
                                     {
                                       if ( v16 <= v22 + v15 )
                                       {
-                                        v17 = v14 - sub_452A9E(v13 * v13 - v21 * v21);
+                                        v17 = v14 - integer_sqrt(v13 * v13 - v21 * v21);
                                         if ( v17 < 0 )
                                           v17 = 0;
                                         if ( v17 < stru_721530.field_7C )
@@ -8716,7 +8716,7 @@
   }
   v64 = v62 * v62 + v60;
   if ( v64 )
-    stru_F8AD28.field_34 = sub_452A9E(v64) << 16;
+    stru_F8AD28.field_34 = integer_sqrt(v64) << 16;
   else
     stru_F8AD28.field_34 = 0;
   v68 = (BLVFaceExtra *)abs(stru_F8AD28.rotated_normal.y);
--- a/mm7_5.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/mm7_5.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -6196,7 +6196,7 @@
 
   v3 = x;
   v4 = y;
-  v5 = sub_452A9E(*y * *y + *z * *z + *x * *x);
+  v5 = integer_sqrt(*y * *y + *z * *z + *x * *x);
   *v3 *= 65536 / (v5 | 1);
   *v4 *= 65536 / (v5 | 1);
   *z *= 65536 / (v5 | 1);
@@ -10814,7 +10814,7 @@
   v62 = v19;
   v23 = v18 - v63;
   v50 = v17 - v65;
-  v24 = sub_452A9E(v23 * v23 + (v60 - v64) * (v60 - v64) + v50 * v50);
+  v24 = integer_sqrt(v23 * v23 + (v60 - v64) * (v60 - v64) + v50 * v50);
   if ( v24 > 5120 )
     return 0;
   if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
@@ -11410,7 +11410,7 @@
     v46 = outy - pOut.y;
     v47 = v163 - outz;
     v48 = outx - pOut.x;
-    v49 = sub_452A9E(v48 * v48 + v46 * v46 + v47 * v47);
+    v49 = integer_sqrt(v48 * v48 + v46 * v46 + v47 * v47);
     v50 = 65536;
     if ( v49 )
       v50 = 65536 / v49;
@@ -11562,7 +11562,7 @@
     v74 = outy - pOut.y;
     v75 = v163 - outz;
     v76 = outx - pOut.x;
-    v77 = sub_452A9E(v76 * v76 + v74 * v74 + v75 * v75);
+    v77 = integer_sqrt(v76 * v76 + v74 * v74 + v75 * v75);
     v78 = 65536;
     if ( v77 )
       v78 = 65536 / v77;
@@ -11721,7 +11721,7 @@
   v6 = outy - pOut.y;
   v7 = v163 - outz;
   v8 = outx - pOut.x;
-  v9 = sub_452A9E(v8 * v8 + v6 * v6 + v7 * v7);
+  v9 = integer_sqrt(v8 * v8 + v6 * v6 + v7 * v7);
   v10 = 65536;
   if ( v9 )
     v10 = 65536 / v9;
@@ -11852,7 +11852,7 @@
   v29 = outy - pOut.y;
   v30 = v163 - outz;
   v31 = outx - pOut.x;
-  v32 = sub_452A9E(v31 * v31 + v29 * v29 + v30 * v30);
+  v32 = integer_sqrt(v31 * v31 + v29 * v29 + v30 * v30);
   v33 = 65536;
   if ( v32 )
     v33 = 65536 / v32;
@@ -12055,7 +12055,7 @@
   v7 = a3 - a1;
   v11 = abs(a3 - a1);
   v8 = abs(a4 - v10);
-  result = sub_452A9E(v11 * v11 + v8 * v8);
+  result = integer_sqrt(v11 * v11 + v8 * v8);
   if ( result )
     result = abs((v7 * (v10 - a6) - (a4 - v10) * (v6 - a5)) / result);
   return result;
--- a/mm7_6.cpp	Mon Feb 18 16:39:49 2013 +0600
+++ b/mm7_6.cpp	Tue Feb 19 13:29:02 2013 +0200
@@ -7837,39 +7837,39 @@
   //unsigned int v0; // ebx@1
   //Player *v1; // esi@1
   //bool result; // eax@1
-  int v3; // edi@2
+  //int v3; // edi@2
   //unsigned int v4; // eax@7
   char *v5; // eax@8
   //int v6; // ecx@9
   //signed int v7; // eax@16
-  Actor *v8; // edi@20
+  //Actor *v8; // edi@20
   unsigned int v9; // ecx@21
-  char *v10; // eax@26
+  //char *v10; // eax@26
   char *v11; // eax@26
   unsigned int v12; // eax@47
-  char *v13; // eax@47
-  char *v14; // eax@47
-  unsigned int v15; // ebx@54
-  int v16; // [sp-10h] [bp-4Ch]@24
-  int v17; // [sp-10h] [bp-4Ch]@44
-  unsigned int v18; // [sp-Ch] [bp-48h]@24
-  unsigned int v19; // [sp-Ch] [bp-48h]@44
-  __int16 v20; // [sp-8h] [bp-44h]@24
-  __int16 v21; // [sp-8h] [bp-44h]@44
-  int v22; // [sp-4h] [bp-40h]@24
-  int v23; // [sp-4h] [bp-40h]@44
+  //char *v13; // eax@47
+  //char *v14; // eax@47
+  //unsigned int v15; // ebx@54
+  //int v16; // [sp-10h] [bp-4Ch]@24
+  //int v17; // [sp-10h] [bp-4Ch]@44
+  //unsigned int v18; // [sp-Ch] [bp-48h]@24
+  //unsigned int v19; // [sp-Ch] [bp-48h]@44
+  //__int16 v20; // [sp-8h] [bp-44h]@24
+  //__int16 v21; // [sp-8h] [bp-44h]@44
+  //int v22; // [sp-4h] [bp-40h]@24
+  //int v23; // [sp-4h] [bp-40h]@44
   SoundID v24; // [sp-4h] [bp-40h]@58
-  Vec3_int_ a3; // [sp+Ch] [bp-30h]@19
+  //Vec3_int_ a3; // [sp+Ch] [bp-30h]@19
   //unsigned int a2; // [sp+18h] [bp-24h]@20
   //unsigned int v27; // [sp+1Ch] [bp-20h]@1
-  int v28; // [sp+20h] [bp-1Ch]@9
+  //int v28; // [sp+20h] [bp-1Ch]@9
   //unsigned int *v28b;
-  int v29; // [sp+24h] [bp-18h]@16
-  int v30; // [sp+28h] [bp-14h]@16
+  //int v29; // [sp+24h] [bp-18h]@16
+  //int v30; // [sp+28h] [bp-14h]@16
   //int v31; // [sp+2Ch] [bp-10h]@4
-  int v32; // [sp+30h] [bp-Ch]@7
+  //int v32; // [sp+30h] [bp-Ch]@7
   //int v33; // [sp+34h] [bp-8h]@7
-  int v34; // [sp+38h] [bp-4h]@17
+  //int v34; // [sp+38h] [bp-4h]@17
 
   //v0 = uActiveCharacter;
   //v27 = 6972 * uActiveCharacter;
@@ -7880,7 +7880,7 @@
     return;
 
   pStru277->_427D48(uActiveCharacter);
-    v3 = 0;
+    //v3 = 0;
   if (pParty->Invisible())
     pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset();
 
@@ -7889,7 +7889,8 @@
   if (bow_idx && player->pInventoryItems[bow_idx - 1].Broken())
     bow_idx = 0;
 
-    v32 = 0;
+    //v32 = 0;
+  int wand_item_id = 0;
     //v33 = 0;
     //v4 = v1->pEquipment.uMainHand;
   int laser_weapon_item_id = 0;
@@ -7903,21 +7904,21 @@
     {
 		//v28b = &v1->pInventoryItems[v4].uItemID;
         //v6 = v1->pInventoryItems[v4].uItemID;//*((int *)v5 + 124);
-      if (pItemsTable->pItems[item->uItemID].uEquipType == EQUIP_C)
+      if (pItemsTable->pItems[item->uItemID].uEquipType == EQUIP_WAND)
       {
-        if (item->_bonus_type <= 0)
-          player->pEquipment.uMainHand = 0;
+        if (item->uNumCharges <= 0)
+          player->pEquipment.uMainHand = 0; // wand discharged - unequip
         else
-          v32 = item->uItemID;//*((int *)v5 + 124);
+          wand_item_id = item->uItemID;//*((int *)v5 + 124);
       }
       else if (item->uItemID == ITEM_BLASTER || item->uItemID == ITEM_LASER_RIFLE)
         laser_weapon_item_id = item->uItemID;//*((int *)v5 + 124);
     }
   }
 
-    v30 = 0;
-    v29 = 0;
-    v28 = 0;
+    //v30 = 0;
+    //v29 = 0;
+    //v28 = 0;
     //v7 = pMouse->uPointingObjectID;
 
   int target_pid = pMouse->uPointingObjectID;
@@ -7929,199 +7930,122 @@
     target_type = target_pid & 7;
     target_id = target_pid >> 3;
   }
-  
-
-    a3.z = 0;
-    a3.y = 0;
-    a3.x = 0;
+
+  auto actor = &pActors[target_id];
+  int actor_distance = 0;
   if (target_type == OBJECT_Actor)
   {
-      //a2 = target_id;
-    v8 = &pActors[target_id];
-    int distance_x = v8->vPosition.x - pParty->vPosition.x,
-        distance_y = v8->vPosition.y - pParty->vPosition.y,
-        distance_z = v8->vPosition.z - pParty->vPosition.z;
-      v34 = sub_452A9E(distance_x * distance_x + distance_y * distance_y + distance_z * distance_z) - v8->uActorRadius;
-      if ( v34 >= 0 )
-      {
-        v9 = 0;
-      }
-      else
-      {
-        v9 = 0;
-        v34 = 0;
-      }
-      if ( laser_weapon_item_id != v9 )
-      {
-        v28 = 1;
-        v22 = uActiveCharacter + 8;
-        v20 = v9;
-        v18 = v9;
-        v16 = 102;
-LABEL_34:
-        _42777D_CastSpell_UseWand_ShootArrow(v16, uActiveCharacter - 1, v18, v20, v22);
-LABEL_28:
-        v3 = 0;
-        goto LABEL_29;
-      }
-      if ( v32 != v9 )
+    int distance_x = actor->vPosition.x - pParty->vPosition.x,
+        distance_y = actor->vPosition.y - pParty->vPosition.y,
+        distance_z = actor->vPosition.z - pParty->vPosition.z;
+    actor_distance = integer_sqrt(distance_x * distance_x + distance_y * distance_y + distance_z * distance_z) - actor->uActorRadius;
+    if (actor_distance < 0)
+      actor_distance = 0;
+  }
+
+  bool shooting_bow = false,
+       shotting_laser = false,
+       shooting_wand = false;
+  if (laser_weapon_item_id)
+  {
+    shotting_laser = true;
+    _42777D_CastSpell_UseWand_ShootArrow(102, uActiveCharacter - 1, 0, 0, uActiveCharacter + 8);
+  }
+  else if (wand_item_id)
+  {
+    shooting_wand = true;
+
+    int main_hand_idx = player->pEquipment.uMainHand;
+    _42777D_CastSpell_UseWand_ShootArrow(*((int *)&pSpellDatas[66].field_8 + player->pInventoryItems[main_hand_idx - 1].uItemID), uActiveCharacter - 1, 8, 0, uActiveCharacter + 8);
+
+    if (!--player->pInventoryItems[main_hand_idx - 1].uNumCharges)
+      player->pEquipment.uMainHand = 0;
+  }
+  else if (target_type == OBJECT_Actor)
+  {
+    if (actor_distance <= 407.2)
+    {
+      Vec3_int_ a3;
+      a3.x = actor->vPosition.x - pParty->vPosition.x;
+      a3.y = actor->vPosition.y - pParty->vPosition.y;
+      a3.z = actor->vPosition.z - pParty->vPosition.z;
+      Vec3_int_::Normalize(&a3.x, &a3.y, &a3.z);
+
+      DamageMonsterFromParty((8 * uActiveCharacter - 8) | OBJECT_Player, target_id, &a3);
+      if (player->WearsItem(506, 1) || player->WearsItem(506, 0))
+          _42FA66_do_explosive_impact(
+            actor->vPosition.x,
+            actor->vPosition.y,
+            actor->vPosition.z + actor->uActorHeight / 2,
+            0, 512, uActiveCharacter);
+    }
+    else if (bow_idx)
+    {
+      shooting_bow = true;
+
+      _42777D_CastSpell_UseWand_ShootArrow(100, uActiveCharacter - 1, 0, 0, 0);
+      if (!pParty->bTurnBasedModeOn)
       {
-        v29 = 1;
-        _42777D_CastSpell_UseWand_ShootArrow(
-          *((int *)&pSpellDatas[66].field_8
-          + *(int *)(&stru_AA1058[3].pSounds[36 * *(int *)&pParty->pArtifactsFound[6972 * uActiveCharacter + 22] + 41048] + 6972 * uActiveCharacter)),
-          uActiveCharacter - 1,
-          8u,
-          v9,
-          uActiveCharacter + 8);
-        v10 = &player->field_1F5[36 * player->pEquipment.uMainHand + 11];
-        --*(int *)v10;
-        v11 = (char *)player + 36 * player->pEquipment.uMainHand;
-        if ( *((int *)v11 + 128) <= 0 )
-        {
-          *((int *)v11 + 124) = 0;
-          player->pEquipment.uMainHand = 0;
-        }
-        goto LABEL_28;
+        int recovery = player->GetAttackRecoveryTime(0);
+        if (recovery < 30)
+          recovery = 30;
+        player->SetRecoveryTime(flt_6BE3A4_debug_recmod1 * (double)recovery * 2.133333333333333);
       }
-      if ( (double)v34 <= 407.2 )
-      {
-        a3.x = v8->vPosition.x - pParty->vPosition.x;
-        a3.y = v8->vPosition.y - pParty->vPosition.y;
-        a3.z = v8->vPosition.z - pParty->vPosition.z;
-        Vec3_int_::Normalize(&a3.x, &a3.y, &a3.z);
-        DamageMonsterFromParty((8 * uActiveCharacter - 8) | OBJECT_Player, target_id, &a3);
-        if ( player->WearsItem(506, 1) || player->WearsItem(506, 0) )
-          _42FA66_do_explosive_impact(
-            v8->vPosition.x,
-            v8->vPosition.y,
-            v8->vPosition.z + v8->uActorHeight / 2,
-            0,
-            512,
-            uActiveCharacter);
-      }
-      else
-      {
-        if ( bow_idx != v9 )
-        {
-          v30 = 1;
-          v22 = 0;
-          v20 = 0;
-          v18 = 0;
-          v16 = 100;
-          goto LABEL_34;
-        }
-      }
-      v3 = 0;
-      goto LABEL_39;
     }
-
-    if ( laser_weapon_item_id )
+  }
+  else
+  {
+    if (bow_idx)
     {
-      v28 = 1;
-      v23 = uActiveCharacter + 8;
-      v21 = 0;
-      v19 = 0;
-      v17 = 102;
+      shooting_bow = true;
+      _42777D_CastSpell_UseWand_ShootArrow(100, uActiveCharacter - 1, 0, 0, 0);
     }
     else
     {
-      if ( v32 )
+      if (!pParty->bTurnBasedModeOn)
       {
-        v12 = player->pEquipment.uMainHand;
-        v29 = 1;
-        _42777D_CastSpell_UseWand_ShootArrow(
-          *((int *)&pSpellDatas[66].field_8 + *(int *)&player->pInventoryItems[v12-1]),
-          uActiveCharacter - 1,
-          8u,
-          0,
-          uActiveCharacter + 8);
-        v13 = &player->field_1F5[36 * player->pEquipment.uMainHand + 11];
-        --*(int *)v13;
-        v14 = (char *)player + 36 * player->pEquipment.uMainHand;
-        if ( *((int *)v14 + 128) <= 0 )
-        {
-          *((int *)v14 + 124) = 0;
-          player->pEquipment.uMainHand = 0;
-        }
-LABEL_29:
-        v34 = v3;
-        if ( v30 == v3 )
-        {
-          if ( v29 != v3 )
-            return;
-          if ( v28 == v3 )
-          {
-            v15 = player->pEquipment.uMainHand;
-            if ( player->HasItemEquipped(EQUIP_TWO_HANDED) )
-              v34 = pItemsTable->pItems[*(int *)&player->pInventoryItems[v15-1]].uSkillType;
-            pTurnEngine->_40471C();
-          }
-          else
-          {
-            v34 = 7;
-          }
-        }
-        else
-        {
-          v34 = 5;
-          player->PlaySound(SPEECH_50, v3);
-        }
-        switch ( v34 )
-        {
-          case 0:
-            v24 = (SoundID)81;
-            goto LABEL_66;
-          case 1:
-            v24 = (SoundID)84;
-            goto LABEL_66;
-          case 2:
-            v24 = (SoundID)85;
-            goto LABEL_66;
-          case 3:
-            v24 = (SoundID)78;
-            goto LABEL_66;
-          case 4:
-            v24 = (SoundID)80;
-            goto LABEL_66;
-          case 5:
-            v24 = (SoundID)71;
-            goto LABEL_66;
-          case 6:
-            v24 = (SoundID)83;
-            goto LABEL_66;
-          case 7:
-            v24 = (SoundID)67;
-LABEL_66:
-            pAudioPlayer->PlaySound(v24, v3, v3, -1, v3, v3, v3, v3);
-            break;
-          default:
-            return;
-        }
-        return;
+        int recovery = player->GetAttackRecoveryTime(0);
+        if (recovery < 30 )
+          recovery = 30;
+        player->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)recovery * 2.133333333333333));
       }
-      if ( !bow_idx )
-      {
-LABEL_39:
-        int  v31 = player->GetAttackRecoveryTime(v3);
-        if ( v31 < 30 )
-          v31 = 30;
-        if ( pParty->bTurnBasedModeOn == v3 )
-          player->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)v31 * 2.133333333333333));
-        goto LABEL_29;
-      }
-      v23 = 0;
-      v21 = 0;
-      v19 = 0;
-      v30 = 1;
-      v17 = 100;
     }
-    _42777D_CastSpell_UseWand_ShootArrow(v17, uActiveCharacter - 1, v19, v21, v23);
-    goto LABEL_29;
+  }
+
+  
+  int v34 = 0;
+  if (shooting_wand)
+    return;
+  else if (shooting_bow)
+  {
+    v34 = 5;
+    player->PlaySound(SPEECH_50, 0);
+  }
+  if (shotting_laser)
+    v34 = 7;
+  else
+  {
+    int main_hand_idx = player->pEquipment.uMainHand;
+    if (player->HasItemEquipped(EQUIP_TWO_HANDED))
+      v34 = pItemsTable->pItems[*(int *)&player->pInventoryItems[main_hand_idx - 1]].uSkillType;
+    pTurnEngine->_40471C();
+  }
+
+  switch (v34)
+  {
+    case 0: pAudioPlayer->PlaySound(SOUND_81, 0, 0, -1, 0, 0, 0, 0); break;
+    case 1: pAudioPlayer->PlaySound(SOUND_84, 0, 0, -1, 0, 0, 0, 0); break;
+    case 2: pAudioPlayer->PlaySound(SOUND_85, 0, 0, -1, 0, 0, 0, 0); break;
+    case 3: pAudioPlayer->PlaySound(SOUND_78, 0, 0, -1, 0, 0, 0, 0); break;
+    case 4: pAudioPlayer->PlaySound(SOUND_80, 0, 0, -1, 0, 0, 0, 0); break;
+    case 5: pAudioPlayer->PlaySound(SOUND_71, 0, 0, -1, 0, 0, 0, 0); break;
+    case 6: pAudioPlayer->PlaySound(SOUND_83, 0, 0, -1, 0, 0, 0, 0); break;
+    case 7: pAudioPlayer->PlaySound(SOUND_67, 0, 0, -1, 0, 0, 0, 0); break;
+  }
 }
 
 //----- (0042F184) --------------------------------------------------------
-int stru319::FindClosestActor(int a2, int a3, int a4)
+int stru319::FindClosestActor(int pick_depth, int a3, int a4)
 {
   int v4; // edi@1
   stru319 *v5; // esi@1
@@ -8161,9 +8085,10 @@
     v6 = a3 != 0;
     if ( a4 )
       LOBYTE(v6) = v6 | 8;
-    v7 = pGame->pVisInstance->_4C1944(OBJECT_Actor, a2, v6, 657456, -1);
+    v7 = pGame->pVisInstance->PickClosestActor(OBJECT_Actor, pick_depth, v6, 657456, -1);
     if ( v7 != -1 )
       return (unsigned __int16)v7;
+    else return 0;
   }
   else
   {
@@ -8201,7 +8126,7 @@
                     && (!a3 || pActors[(unsigned int)v11 >> 3].GetActorsRelation(0)) )
                   {
                     if ( (!a4 || MonsterStats::BelongsToSupertype(v12->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD))
-                      && v22 <= a2 << 16 )
+                      && v22 <= pick_depth << 16 )
                     {
                       v14 = 0;
                       if ( v10 > 0 )
--- a/mm7_data.h	Mon Feb 18 16:39:49 2013 +0600
+++ b/mm7_data.h	Tue Feb 19 13:29:02 2013 +0200
@@ -2061,7 +2061,7 @@
 bool __fastcall SpawnActor(unsigned int uMonsterID);
 int __cdecl GetAlertStatus();
 unsigned int __fastcall sub_452442(unsigned __int16 a1, unsigned __int16 a2, int a3, int a4);
-int sub_452A9E(int a1);
+int integer_sqrt(int val);
 int __fastcall MakeColorMaskFromBitDepth(int a1);
 void __fastcall fill_pixels_fast(unsigned int a1, unsigned __int16 *pPixels, unsigned int uNumPixels);
 int __fastcall GetDiceResult(unsigned int uNumDice, unsigned int uDiceSides); // idb