changeset 1615:89dec2be255f

AI visibility issue temporarily fixed
author zipi
date Sat, 14 Sep 2013 22:02:56 +0100
parents 85a099ea7975
children de6e646822a6
files Math.h mm7_1.cpp mm7_5.cpp mm7_data.cpp mm7_data.h
diffstat 5 files changed, 239 insertions(+), 218 deletions(-) [+]
line wrap: on
line diff
--- a/Math.h	Sun Sep 15 00:46:00 2013 +0600
+++ b/Math.h	Sat Sep 14 22:02:56 2013 +0100
@@ -25,6 +25,7 @@
 #pragma pack(pop)
 
 __int64 fixpoint_sub0(int, int);
+__int64 fixpoint_sub2(int, int);
 __int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2);
 __int64 fixpoint_div(int, int);
 __int64 fixpoint_mul(int, int);
--- a/mm7_1.cpp	Sun Sep 15 00:46:00 2013 +0600
+++ b/mm7_1.cpp	Sat Sep 14 22:02:56 2013 +0100
@@ -65,6 +65,14 @@
 {
   return ((__int64)a1 * (__int64)a2) >> 16;
 }
+__int64 fixpoint_sub2(int a1, int a2)
+{
+  signed __int64 v3; // qtt@1
+
+  LODWORD(v3) = a1 << 16;
+  HIDWORD(v3) = a1 >> 16;
+  return v3 / a2;
+}
 
 __int64 fixpoint_dot(int x1, int x2, int y1, int y2, int z1, int z2)
 {
--- a/mm7_5.cpp	Sun Sep 15 00:46:00 2013 +0600
+++ b/mm7_5.cpp	Sat Sep 14 22:02:56 2013 +0100
@@ -4302,258 +4302,270 @@
 bool __fastcall sub_4070EF_prolly_detect_player(unsigned int uObjID, unsigned int uObj2ID)
 {
   signed int v2; // eax@1
-  //unsigned int v3; // ecx@1
-  //signed int v4; // esi@1
   int v5; // ecx@2
-  signed int v6; // eax@4
-  int object1_sector; // eax@4
+  int obj1_sector; // eax@4
   float v8; // ST24_4@5
   double v9; // ST18_8@5
-  signed int v10; // eax@6
   int v11; // ecx@6
   signed int v12; // eax@7
   int v13; // esi@7
   int v14; // esi@8
   int v15; // esi@9
-  signed int v16; // eax@11
   int obj2_z; // edi@11
   int obj2_x; // esi@11
   int obj2_sector; // eax@13
   float v20; // ST24_4@14
   double v21; // ST18_8@14
-  signed int v22; // eax@15
-  int dist2_x; // ebx@16
-  signed int v24; // ecx@16
+  int dist_x; // ebx@16
+  signed int dist_3d; // ecx@16
   int v25; // eax@18
-  //int v26; // eax@28
-  //BLVSector *v27; // edx@31
-  //int v28; // ecx@31
   BLVFace *v29; // ebx@32
   Vec3_short_ *v30; // esi@32
   int v31; // eax@32
   int v32; // ST50_4@44
   int v33; // ST54_4@44
   int v34; // eax@44
-  char v35; // zf@44
-  int v36; // edi@44
-  int v37; // eax@45
   signed int v38; // esi@45
-  int v39; // ST4C_4@49
   signed __int64 v40; // qtt@50
-  __int16 v42; // bx@58
+  __int16 next_sector; // bx@58
   int v43; // [sp-8h] [bp-70h]@11
   int v44; // [sp-4h] [bp-6Ch]@11
-  //int v45; // [sp+Ch] [bp-5Ch]@32
-  //__int16 v46; // [sp+10h] [bp-58h]@32
   int v47; // [sp+18h] [bp-50h]@20
   int v48; // [sp+1Ch] [bp-4Ch]@20
   int v49; // [sp+20h] [bp-48h]@20
-  int dist2_z; // [sp+24h] [bp-44h]@16
-  signed int v51; // [sp+24h] [bp-44h]@27
-  signed int v52; // [sp+28h] [bp-40h]@26
-  signed int v53; // [sp+2Ch] [bp-3Ch]@23
-  signed int v54; // [sp+30h] [bp-38h]@22
-  signed int v55; // [sp+34h] [bp-34h]@21
-  signed int v56; // [sp+38h] [bp-30h]@20
-  signed int v57; // [sp+3Ch] [bp-2Ch]@28
+  int dist_z; // [sp+24h] [bp-44h]@16
+  signed int higher_z; // [sp+24h] [bp-44h]@27
+  signed int lower_z; // [sp+28h] [bp-40h]@26
+  signed int higher_y; // [sp+2Ch] [bp-3Ch]@23
+  signed int lower_y; // [sp+30h] [bp-38h]@22
+  signed int higher_x; // [sp+34h] [bp-34h]@21
+  signed int lower_x; // [sp+38h] [bp-30h]@20
+  signed int sectors_visited; // [sp+3Ch] [bp-2Ch]@28
   int v58; // [sp+44h] [bp-24h]@50
   int v59; // [sp+48h] [bp-20h]@44
   int obj2_y; // [sp+50h] [bp-18h]@11
-  signed int v61; // [sp+50h] [bp-18h]@31
-  //int v62; // [sp+54h] [bp-14h]@16
-  int obj_x; // [sp+58h] [bp-10h]@4
-  int obj_y; // [sp+5Ch] [bp-Ch]@4
-  int obj_z; // [sp+60h] [bp-8h]@4
-  int v66; // [sp+64h] [bp-4h]@7
+  int obj1_x; // [sp+58h] [bp-10h]@4
+  int obj1_y; // [sp+5Ch] [bp-Ch]@4
+  int obj1_z; // [sp+60h] [bp-8h]@4
+  int current_sector; // [sp+64h] [bp-4h]@7
+  int dist_y;
+  int v70;
 
   v2 = PID_ID(uObjID);
-  if ( PID_TYPE(uObjID) == 5 )
+  switch( PID_TYPE(uObjID) )
   {
-      v6 = v2;
-      obj_x = pLevelDecorations[v6].vPosition.x;
-      obj_y = pLevelDecorations[v6].vPosition.y;
-      obj_z = pLevelDecorations[v6].vPosition.z;
-      object1_sector = pIndoor->GetSector(obj_x, obj_y, obj_z);
-  }
-  else if ( PID_TYPE(uObjID) == 3 )
-  {
-      obj_x = pActors[v2].vPosition.x;
-      obj_y = pActors[v2].vPosition.y;
+	case OBJECT_Decoration:
+      obj1_x = pLevelDecorations[v2].vPosition.x;
+      obj1_y = pLevelDecorations[v2].vPosition.y;
+      obj1_z = pLevelDecorations[v2].vPosition.z;
+      obj1_sector = pIndoor->GetSector(obj1_x, obj1_y, obj1_z);
+	  break;
+	case OBJECT_Actor:
+      obj1_x = pActors[v2].vPosition.x;
+      obj1_y = pActors[v2].vPosition.y;
       v8 = (double)pActors[v2].uActorHeight * 0.69999999;
       //v9 = v8 + 6.7553994e15;
-      //obj_z = LODWORD(v9) + pActors[v2].vPosition.z;
-	  obj_z = (int)v8 + pActors[v2].vPosition.z;
-      object1_sector = pActors[v2].uSectorID;
+      //obj1_z = LODWORD(v9) + pActors[v2].vPosition.z;
+	  obj1_z = (int)v8 + pActors[v2].vPosition.z;
+      obj1_sector = pActors[v2].uSectorID;
+	  break;
+	case OBJECT_Item:
+      obj1_x = pSpriteObjects[v2].vPosition.x;
+      obj1_y = pSpriteObjects[v2].vPosition.y;
+      obj1_z = pSpriteObjects[v2].vPosition.z;
+      obj1_sector = pSpriteObjects[v2].uSectorID;
+	  break;
+	default:
+	  return 0;
   }
-  else if ( PID_TYPE(uObjID) == 2 )
-  {
-    v10 = v2;
-    obj_x = pSpriteObjects[v10].vPosition.x;
-    obj_y = pSpriteObjects[v10].vPosition.y;
-    obj_z = pSpriteObjects[v10].vPosition.z;
-    object1_sector = pSpriteObjects[v10].uSectorID;
-  }
-  else
-	  return 0;
-  v66 = object1_sector;
   v12 = PID_ID(uObj2ID);
-  if ( PID_TYPE(uObj2ID) == 5)
+  switch( PID_TYPE(uObj2ID) )
   {
-	v16 = v12;
-    obj2_z = pLevelDecorations[v16].vPosition.z;
-    obj2_x = pLevelDecorations[v16].vPosition.x;
-    obj2_y = pLevelDecorations[v16].vPosition.y;
-	obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
-   }
-   else if ( PID_TYPE(uObj2ID) == 4)
-   {
-     obj2_x = pParty->vPosition.x;
-     obj2_z = pParty->sEyelevel + pParty->vPosition.z;
-     obj2_y = pParty->vPosition.y;
-	 obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
-    }
-  
-  else if( PID_TYPE(uObj2ID) == 3)
-  {
-    obj2_y = pActors[v12].vPosition.y;
-    obj2_x = pActors[v12].vPosition.x;
-    v20 = (double)pActors[v12].uActorHeight * 0.69999999;
-    //v21 = v20 + 6.7553994e15;
-    //obj2_z = LODWORD(v21) + pActors[v12].vPosition.z;
-	obj2_z = (int)v20 + pActors[v12].vPosition.z;
-    obj2_sector = pActors[v12].uSectorID;
+    case OBJECT_Decoration:
+      obj2_z = pLevelDecorations[v12].vPosition.z;
+      obj2_x = pLevelDecorations[v12].vPosition.x;
+      obj2_y = pLevelDecorations[v12].vPosition.y;
+	  obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
+	  break;
+	case OBJECT_Player:
+      obj2_x = pParty->vPosition.x;
+      obj2_z = pParty->sEyelevel + pParty->vPosition.z;
+      obj2_y = pParty->vPosition.y;
+	  obj2_sector = pIndoor->GetSector(obj2_x, obj2_y, obj2_z);
+      break;
+	case OBJECT_Actor:
+      obj2_y = pActors[v12].vPosition.y;
+      obj2_x = pActors[v12].vPosition.x;
+      v20 = (double)pActors[v12].uActorHeight * 0.69999999;
+      //v21 = v20 + 6.7553994e15;
+      //obj2_z = LODWORD(v21) + pActors[v12].vPosition.z;
+	  obj2_z = (int)v20 + pActors[v12].vPosition.z;
+      obj2_sector = pActors[v12].uSectorID;
+	  break;
+	case OBJECT_Item:
+      obj2_x = pSpriteObjects[v12].vPosition.x;
+      obj2_z = pSpriteObjects[v12].vPosition.z;
+      obj2_y = pSpriteObjects[v12].vPosition.y;
+      obj2_sector = pSpriteObjects[v12].uSectorID;
+	  break;
+	default:
+	  return 0;
   }
-  
-  else if ( PID_TYPE(uObj2ID) == 2)
-  {
-    v22 = v12;
-    obj2_x = pSpriteObjects[v22].vPosition.x;
-    obj2_z = pSpriteObjects[v22].vPosition.z;
-    obj2_y = pSpriteObjects[v22].vPosition.y;
-    obj2_sector = pSpriteObjects[v22].uSectorID;
-  }
-  else
-	  return 0;
-  dist2_x = obj2_x - obj_x;
-  dist2_z = obj2_z - obj_z;
-  v24 = integer_sqrt(dist2_x * dist2_x + (obj2_y - obj_y) * (obj2_y - obj_y) + dist2_z * dist2_z);
-  if ( v24 > 5120 )
+  dist_x = obj2_x - obj1_x;
+  dist_z = obj2_z - obj1_z;
+  dist_y = obj2_y - obj1_y;
+  dist_3d = integer_sqrt(dist_x * dist_x + dist_y * dist_y + dist_z * dist_z);
+  //range check
+  if ( dist_3d > 5120 )
     return 0;
   if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
     return 1;
   v25 = 65536;
-  if ( v24 )
-    v25 = 65536 / v24;
-  v49 = dist2_x * v25;
-  v47 = dist2_z * v25;
-  v48 = (obj2_y - obj_y) * v25;
-  if ( obj_x < obj2_x )
+  if ( dist_3d )
+    v25 = 65536 / dist_3d;
+  v49 = dist_x * v25;
+  v47 = dist_z * v25;
+  v48 = dist_y * v25;
+  if ( obj1_x < obj2_x )
   {
-	v56 = obj_x;
-    v55 = obj2_x;
+	lower_x = obj1_x;
+    higher_x = obj2_x;
   }
   else
   {
-    v56 = obj2_x;
-    v55 = obj_x;
+    lower_x = obj2_x;
+    higher_x = obj1_x;
   }
-  if ( obj_y < obj2_y )
+  if ( obj1_y < obj2_y )
   {
-	v54 = obj_y;
-    v53 = obj2_y;
+	lower_y = obj1_y;
+    higher_y = obj2_y;
   }
   else
   {
-    v54 = obj2_y;
-    v53 = obj_y;
+    lower_y = obj2_y;
+    higher_y = obj1_y;
   }
-  if ( obj_z < obj2_z )
+  if ( obj1_z < obj2_z )
   {
-	v52 = obj_z;
-    v51 = obj2_z;
+	lower_z = obj1_z;
+    higher_z = obj2_z;
   }
   else
   {
-    v52 = obj2_z;
-    v51 = obj_z;
+    lower_z = obj2_z;
+    higher_z = obj1_z;
   }
-  v57 = 0;
-  if ( v66 == obj2_sector )
+  sectors_visited = 0;
+  //monster in same sector with player
+  if ( obj1_sector == obj2_sector )
       return 1;
-  //for ( v57 = 0; v57 < 30; v57++ )
-  if ( v57 < 30 && !(v61 = 0, pIndoor->pSectors[v66].uNumPortals <= 0) )
-	for( int v61 = 0; v61 < pIndoor->pSectors[v66].uNumPortals; v61++ )
+  //search starts from monster
+  current_sector = obj1_sector;
+  for( int current_portal = 0; current_portal < pIndoor->pSectors[current_sector].uNumPortals; current_portal++ )
+  {
+	v29 = &pIndoor->pFaces[pIndoor->pSectors[current_sector].pPortals[current_portal]];
+	v30 = &pIndoor->pVertices[*v29->pVertexIDs];
+	v31 = v29->pFacePlane_old.vNormal.z * (v30->z - obj1_z)
+		+ v29->pFacePlane_old.vNormal.y * (v30->y - obj1_y)
+		+ v29->pFacePlane_old.vNormal.x * (v30->x - obj1_x);
+
+	if ( current_sector != v29->uSectorID )
+		v31 = -v31;
+
+	if ( v31 >= 0 && v30->x != obj1_x && v30->y != obj1_y && v30->z != obj1_z)
+		continue;
+
+	if(	lower_x > v29->pBounding.x2
+		|| higher_x < v29->pBounding.x1
+		|| lower_y > v29->pBounding.y2
+		|| higher_y < v29->pBounding.y1
+		|| lower_z > v29->pBounding.z2
+		|| higher_z < v29->pBounding.z1 )
+	{
+		continue;
+	}
+	  
+	v32 = fixpoint_mul(v29->pFacePlane_old.vNormal.x,v49);
+	v33 = fixpoint_mul(v29->pFacePlane_old.vNormal.z,v47);
+	v34 = fixpoint_mul(v29->pFacePlane_old.vNormal.y,v48);
+	v59 = v32 + v33 + v34;
+	if ( v59 )
 	{
-      v29 = &pIndoor->pFaces[pIndoor->pSectors[v66].pPortals[v61]];
-      v30 = &pIndoor->pVertices[*v29->pVertexIDs];
-      //v45 = *(int *)&v30->x;
-      //v46 = v30->z;
-      //v31 = v29->pFacePlane_old.vNormal.z * (v46 - obj_z)
-	  v31 = v29->pFacePlane_old.vNormal.z * (v30->z - obj_z)
-          //+ v29->pFacePlane_old.vNormal.y * (SHIWORD(v45) - obj_y)
-		  + v29->pFacePlane_old.vNormal.y * (v30->y - obj_y)
-          //+ v29->pFacePlane_old.vNormal.x * ((signed __int16)v45 - obj_x);
-		  + v29->pFacePlane_old.vNormal.x * (v30->x - obj_x);
-      if ( v66 != v29->uSectorID )
-        v31 = -v31;
-      //if (!( v31 >= 0 && (signed __int16)v45 != obj_x && SHIWORD(v45) != obj_y && v46 != obj_z
-	  if (!( v31 >= 0 && v30->x != obj_x && v30->y != obj_y && v30->z != obj_z
-        || v56 > v29->pBounding.x2
-        || v55 < v29->pBounding.x1
-        || v54 > v29->pBounding.y2
-        || v53 < v29->pBounding.y1
-        || v52 > v29->pBounding.z2
-        || v51 < v29->pBounding.z1 ) )
-	  {
-		  v32 = (unsigned __int64)(v49 * (signed __int64)v29->pFacePlane_old.vNormal.x) >> 16;
-		  v33 = (unsigned __int64)(v47 * (signed __int64)v29->pFacePlane_old.vNormal.z) >> 16;
-		  v34 = (unsigned __int64)(v48 * (signed __int64)v29->pFacePlane_old.vNormal.y) >> 16;
-		  v35 = v32 + v33 + v34 == 0;
-		  v36 = v32 + v33 + v34;
-		  v59 = v32 + v33 + v34;
-		  if ( !v35 )
-		  {
-			  v37 = obj_z * v29->pFacePlane_old.vNormal.z;
-			  v38 = -(v29->pFacePlane_old.dist + v37 + obj_x * v29->pFacePlane_old.vNormal.x + obj_y * v29->pFacePlane_old.vNormal.y);
-			  if ( v36 <= 0 ^ v29->pFacePlane_old.dist + v37 + obj_x * v29->pFacePlane_old.vNormal.x + obj_y * v29->pFacePlane_old.vNormal.y <= 0)
-			  {
-				v39 = abs(-(v29->pFacePlane_old.dist
-						  + v37
-						  + obj_x * v29->pFacePlane_old.vNormal.x
-						  + obj_y * v29->pFacePlane_old.vNormal.y)) >> 14;
-				if ( v39 > abs(v36)
-				  || (LODWORD(v40) = v38 << 16, HIDWORD(v40) = v38 >> 16, v58 = v40 / v59, (signed int)(v40 / v59) < 0)
-				  || !sub_4075DB(
-						obj_x + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v49) >> 16) + 32768) >> 16),
-						obj_y + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v48) >> 16) + 32768) >> 16),
-						obj_z + ((signed int)(((unsigned __int64)(v58 * (signed __int64)v47) >> 16) + 32768) >> 16),
-						v29) )
-				{
-				  continue;
-				}
-				if ( v29->uSectorID == v66 )
-				  v42 = v29->uBackSectorID;
-				else
-				  v42 = v29->uSectorID;
-				if ( v42 != v66 )
-				{
-				  ++v57;
-				  v66 = v42;
-				  if ( v42 == obj2_sector )
-					return 1;
-				  if ( v57 < 30 && pIndoor->pSectors[v66].uNumPortals > 0)
-				  {
-					  v61=-1;
-					  continue;
-				  }
+		v70 = v29->pFacePlane_old.dist 
+			+ obj1_z * v29->pFacePlane_old.vNormal.z 
+			+ obj1_x * v29->pFacePlane_old.vNormal.x 
+			+ obj1_y * v29->pFacePlane_old.vNormal.y;
+		v38 = -v70;
+
+		// if ( v59 <= 0 ^ v70 <= 0 )
+		
+		/* TEMPORARY
+		if ( v59 <= 0 && v70 <= 0 )
+		{
+			continue;
+		}
+		if ( !(v59 <= 0 && v70 <= 0) )
+		{
+			continue;
+		}
+		*/
+
+		if( abs(v38) >> 14 > abs(v59) )
+			continue;
+
+		v58 = fixpoint_sub2(v38,v59);
+
+		if( v58 < 0 )
+		{
+			//TEMPORARY
+			//continue;
+		}
 
-				}
-				break;
-			  }
-		  }
-	  }
-    }
-  if ( v66 != obj2_sector )
+		if(!sub_4075DB(
+				obj1_x + ((fixpoint_mul(v49,v58) + 32768) >> 16),
+				obj1_y + ((fixpoint_mul(v48,v58) + 32768) >> 16),
+				obj1_z + ((fixpoint_mul(v47,v58) + 32768) >> 16),
+				v29) )
+		{
+			//TEMPORARY
+			//continue;
+		}
+
+		//if there is no next sector turn back
+		if ( v29->uSectorID == current_sector )
+			next_sector = v29->uBackSectorID;
+		else
+			next_sector = v29->uSectorID;
+
+		//no more portals, quit
+		if ( next_sector == current_sector )
+		{
+			break;
+		}
+
+		++sectors_visited;
+		current_sector = next_sector;
+
+		//found player, quit
+		if ( next_sector == obj2_sector )
+			return 1;
+
+		current_sector = next_sector;
+
+		//did we hit limit for portals?
+		//does the next room have portals?
+		if ( sectors_visited < 30 && pIndoor->pSectors[current_sector].uNumPortals > 0)
+		{
+				current_portal=-1;
+				continue;
+		}
+		else
+			break;
+	}
+  }
+  //did we stop in the sector where player is?
+  if ( current_sector != obj2_sector )
     return 0;
   return 1;
 }
@@ -4595,7 +4607,7 @@
     for(int i = 0; i < a4->uNumVertices; i++)
 	{
         dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].x;
-        dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].y;
+        dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].y;
 	}
   }
   else
@@ -4607,7 +4619,7 @@
       for(int i = 0; i < a4->uNumVertices; i++)
 	  {
 		dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].x;
-		dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].z;
+		dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].z;
 	  }
     }
     else
@@ -4616,31 +4628,31 @@
       for(int i = 0; i < a4->uNumVertices; i++)
 	  {
 		dword_4F5D98_xs[i] = v9[a4->pVertexIDs[i]].y;
-		dword_4F5CC4_ys[i+1] = v9[a4->pVertexIDs[i]].z;
+		dword_4F5CC8_ys[i] = v9[a4->pVertexIDs[i]].z;
 	  }
     }
   }
   a3a = 0;
   dword_4F5D98_xs[a4->uNumVertices] = dword_4F5D98_xs[0];
-  dword_4F5CC4_ys[a4->uNumVertices + 1] = dword_4F5CC4_ys[1];
-  for(int i = 0; i < a4->uNumVertices; i++)
+  dword_4F5CC8_ys[a4->uNumVertices] = dword_4F5CC8_ys[0];
+  for(int i = 0; i < a4->uNumVertices && a3a < 2; i++)
   {
-    if ( a3a >= 2 )
-      break;
-    if ( dword_4F5CC4_ys[i + 1] >= v8 ^ (dword_4F5CC4_ys[i + 2] >= v8) )
+    if ( dword_4F5CC8_ys[i] >= v8 ^ (dword_4F5CC8_ys[i + 1] >= v8) )
     {
-	  if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a)
+	  //if( dword_4F5D98_xs[i + 1] >= a4a || dword_4F5D98_xs[i] >= a4a)
+	  if( !(dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] < a4a))
       {
-		  if ( (dword_4F5D98_xs[i + 1] >= a4a && dword_4F5D98_xs[i] >= a4a)
-          || (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],
-              LODWORD(v26) = v25 << 16,
-              HIDWORD(v26) = v25 >> 16,
-              dword_4F5D98_xs[i]
-            + ((signed int)(((unsigned __int64)(v26
-                                              / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])
-                                              * ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16)
-                          + 32768) >> 16) >= a4a) )
-          ++a3a;
+		  if ( (dword_4F5D98_xs[i + 1] < a4a && dword_4F5D98_xs[i] >= a4a) )
+			  ++a3a;
+		  //|| (v25 = dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i],LODWORD(v26) = v25 << 16, HIDWORD(v26) = v25 >> 16, 
+		  //dword_4F5D98_xs[i] + ((signed int)(((unsigned __int64)(v26 / (dword_4F5CC4_ys[i + 2] - dword_4F5CC4_ys[i + 1])* ((v8 - dword_4F5CC4_ys[i + 1]) << 16)) >> 16)
+          //                + 32768) >> 16) >= a4a) )
+		  else
+		  {
+			v25 = fixpoint_sub2(dword_4F5D98_xs[i + 1] - dword_4F5D98_xs[i], dword_4F5CC8_ys[i + 1] - dword_4F5CC8_ys[i]);
+			if( dword_4F5D98_xs[i] + (fixpoint_mul(v25, (v8 - dword_4F5CC8_ys[i]) << 16) + 32768 >> 16) >= a4a)
+				++a3a;
+		  }
       }
     }
   }
--- a/mm7_data.cpp	Sun Sep 15 00:46:00 2013 +0600
+++ b/mm7_data.cpp	Sat Sep 14 22:02:56 2013 +0100
@@ -860,10 +860,10 @@
 int dword_4F5428[777]; // weak
 int dword_4F542C[777]; // weak
 _UNKNOWN crtunk_4F54B8; // weak
-std::array<int, 777> dword_4F5B24_ys; // idb
-std::array<int, 777> dword_4F5BF4_xs; // idb
-std::array<int, 777> dword_4F5CC4_ys; // idb
-std::array<int, 777> dword_4F5D98_xs; // idb
+std::array<int, 52> dword_4F5B24_ys; // idb
+std::array<int, 52> dword_4F5BF4_xs; // idb
+std::array<int, 52> dword_4F5CC8_ys; // idb
+std::array<int, 52> dword_4F5D98_xs; // idb
 std::array<int, 500> ai_array_4F5E68;
 std::array<int, 500> ai_array_4F6638_actor_ids;
 std::array<int, 500> ai_near_actors_targets_pid;
--- a/mm7_data.h	Sun Sep 15 00:46:00 2013 +0600
+++ b/mm7_data.h	Sat Sep 14 22:02:56 2013 +0100
@@ -509,10 +509,10 @@
 extern int dword_4F5428[]; // weak
 extern int dword_4F542C[]; // weak
 extern _UNKNOWN crtunk_4F54B8; // weak
-extern std::array<int, 777> dword_4F5B24_ys; // idb
-extern std::array<int, 777> dword_4F5BF4_xs; // idb
-extern std::array<int, 777> dword_4F5CC4_ys; // idb
-extern std::array<int, 777> dword_4F5D98_xs; // idb
+extern std::array<int, 52> dword_4F5B24_ys; // idb
+extern std::array<int, 52> dword_4F5BF4_xs; // idb
+extern std::array<int, 52> dword_4F5CC8_ys; // idb
+extern std::array<int, 52> dword_4F5D98_xs; // idb
 extern std::array<int, 500> ai_array_4F5E68;
 extern std::array<int, 500> ai_array_4F6638_actor_ids;
 extern std::array<int, 500> ai_near_actors_targets_pid;