changeset 837:bebc19f3d2af

Save/load work with some problems
author Gloval
date Thu, 28 Mar 2013 00:37:27 +0400
parents 5e3f4bf3b8e6
children d061180f2b42
files Indoor.h LOD.cpp LOD.h SaveLoad.cpp SpriteObject.cpp mm7_2.cpp mm7_3.cpp mm7_5.cpp mm7_data.h
diffstat 9 files changed, 1196 insertions(+), 1394 deletions(-) [+]
line wrap: on
line diff
--- a/Indoor.h	Tue Mar 26 15:21:03 2013 +0000
+++ b/Indoor.h	Thu Mar 28 00:37:27 2013 +0400
@@ -470,7 +470,8 @@
   struct SpawnPointMM7 *pSpawnPoints;
   struct DDM_DLV_Header dlv;
   LocationTime_stru1 stru1;
-  char _visible_outlines[876];
+  char _visible_outlines[875];
+  char padding;
 };
 #pragma pack(pop)
 
--- a/LOD.cpp	Tue Mar 26 15:21:03 2013 +0000
+++ b/LOD.cpp	Thu Mar 28 00:37:27 2013 +0400
@@ -975,23 +975,16 @@
 //----- (00461431) --------------------------------------------------------
 void LOD::File::Close()
 {
-  LOD::File *v1; // esi@1
-  LOD::Directory **v2; // edi@2
-  FILE *v3; // ST00_4@2
-
-  v1 = this;
-  if ( this->isFileOpened )
+  if (isFileOpened )
   {
     this->pContainerName[0] = 0;
     this->uCurrentIndexDir = 0;
-    v2 = &this->pSubIndices;
-    pAllocator->FreeChunk(this->pSubIndices);
-    pAllocator->FreeChunk(v1->pRoot);
-    v3 = v1->pFile;
-    *v2 = 0;
-    v1->pRoot = 0;
-    fclose(v3);
-    v1->isFileOpened = 0;
+    pAllocator->FreeChunk(pSubIndices);
+    pAllocator->FreeChunk(pRoot);
+    pSubIndices = NULL;
+    pRoot = NULL;
+    fclose(pFile);
+    isFileOpened = 0;
     _6A0CA8_lod_unused = 0;
   }
 }
@@ -999,7 +992,7 @@
 
 
 //----- (00461492) --------------------------------------------------------
-int LODWriteableFile::_461492(LOD::FileHeader *pHeader, LOD::Directory *pDir, const char *Source)
+int LODWriteableFile::CreateNewLod(LOD::FileHeader *pHeader, LOD::Directory *pDir, const char *lod_name)
 {
   if (isFileOpened)
     return 1;
@@ -1011,14 +1004,13 @@
   pDir->pFilename[15] = 0;
   pDir->uDataSize = 0;
   pDir->uOfsetFromSubindicesStart = 288;
-  strcpy(pLODName, Source);
+  strcpy(pLODName, lod_name);
 
   pFile = fopen(pLODName, "wb+");
   if (!pFile)
     return 3;
-
-  fwrite(pHeader, 0x100, 1, pFile);
-  fwrite(pDir, 0x20, 1, pFile);
+  fwrite(pHeader,sizeof(LOD::FileHeader), 1, pFile);
+  fwrite(pDir, sizeof(LOD::Directory), 1, pFile);
   fclose(pFile);
   pFile = 0;
   return 0;
@@ -1027,29 +1019,18 @@
 //----- (0046153F) --------------------------------------------------------
 void LOD::File::ResetSubIndices()
 {
-  LOD::Directory **pSubIndices_dup2; // esi@2
-  LOD::Directory *pSubIndices_dup; // ST00_4@2
-
-  if ( this->isFileOpened )
+  if ( isFileOpened )
   {
-    pSubIndices_dup2 = &this->pSubIndices;
-    this->pContainerName[0] = 0;
-    this->uCurrentIndexDir = 0;
-    pSubIndices_dup = this->pSubIndices;
-    this->uOffsetToSubIndex = 0;
-    this->uNumSubIndices = 0;
-    this->uLODDataSize = 0;
-    pAllocator->FreeChunk(pSubIndices_dup);
-    *pSubIndices_dup2 = 0;
+    pContainerName[0] = 0;
+    uCurrentIndexDir = 0;
+    uOffsetToSubIndex = 0;
+    uNumSubDirs = 0;
+    uLODDataSize = 0;
+    pAllocator->FreeChunk(pSubIndices);
+    pSubIndices = NULL;
   }
 }
 
-
-
-
-
-
-
 //----- (00450C8B) --------------------------------------------------------
 void LODFile_Sprites::DeleteSomeSprites()
 {
@@ -1331,11 +1312,11 @@
   v1 = this;
   if ( !(HIBYTE(this->word_1A) & 4) )
   {
-    pAllocator->FreeChunk(this->pDecompressedBytes);
-    pAllocator->FreeChunk(v1->pSpriteLines);
+    pAllocator->FreeChunk(pDecompressedBytes);
+    pAllocator->FreeChunk(pSpriteLines);
   }
-  v1->pDecompressedBytes = 0;
-  v1->pSpriteLines = 0;
+  pDecompressedBytes = NULL;
+  pSpriteLines = NULL;
 }
 
 //----- (004623E5) --------------------------------------------------------
@@ -1447,169 +1428,109 @@
   return LoadFile(pLODName, 0);
 }
 
-
-//----- (00461FD4) --------------------------------------------------------
-int LODWriteableFile::Save()
-{
-  LODWriteableFile *v1; // esi@1
-  int v2; // edi@1
-  unsigned int v3; // edx@1
-  LOD::Directory *v4; // eax@2
-  unsigned int v5; // ecx@2
-  int v6; // eax@2
-  signed int v7; // ebx@5
-  int v8; // ecx@5
-  LOD::Directory **v9; // edi@6
-  int v10; // edx@6
-  LOD::Directory *v11; // eax@6
-  FILE *v12; // eax@9
-  FILE *v13; // ebx@9
-  signed int result; // eax@10
-  unsigned int v15; // eax@11
-  FILE *v16; // ST00_4@11
-  size_t v17; // edi@12
-  char OldFilename[256]; // [sp+Ch] [bp-228h]@9
-  char NewFilename[256]; // [sp+10Ch] [bp-128h]@15
-  //LOD::Directory v0; // [sp+20Ch] [bp-28h]@11
-  unsigned int v21; // [sp+22Ch] [bp-8h]@5
-  int v22; // [sp+230h] [bp-4h]@1
-
-  v1 = this;
-  v2 = 0;
-  v3 = this->uNumSubIndices;
-  v22 = 0;
-  if ( (signed int)v3 > 0 )
-  {
-    v4 = this->pSubIndices;
-    v5 = v3;
-    v6 = (int)&v4->uDataSize;
-    do
-    {
-      v2 += *(int *)v6;
-      v6 += 32;
-      --v5;
-    }
-    while ( v5 );
-    v22 = v2;
-  }
-  v7 = 0;
-  v21 = 32 * v3 + v2;
-  v8 = 32 * v3;
-  if ( (signed int)v3 > 0 )
-  {
-    v9 = &v1->pSubIndices;
-    v10 = 0;
-    v11 = v1->pSubIndices;
-    do
+//----- (00461FD4) ---LODFile_sub_461FD4---text:004632EA  --------------------------------------------------
+int LODWriteableFile::FixDirectoryOffsets()
     {
-      v11[v10].uOfsetFromSubindicesStart = v8;
-      v11 = *v9;
-      v8 += (*v9)[v10].uDataSize;
-      ++v7;
-      ++v10;
-    }
-    while ( v7 < (signed int)v1->uNumSubIndices );
-    v2 = v22;
-  }
-  strcpy(OldFilename, "lod.tmp");
-  v12 = fopen(OldFilename, "wb+");
-  v13 = v12;
-  if ( v12 )
-  {
-    fwrite(&v1->header, 0x100, 1, v12);
+     LOD::Directory Lindx; 
+    int total_size; // edi@1
+    int temp_offset; // ecx@5
+    FILE *tmp_file; // eax@9
+    size_t write_size; // edi@12
+    int result;
+    char Filename[256]; // [sp+Ch] [bp-228h]@9
+    char NewFilename[256]; // [sp+10Ch] [bp-128h]@15
+    int i;
 
-    LOD::Directory v0; // [sp+20Ch] [bp-28h]@11
-    //LOD::Directory::LOD::Directory(&v0);
+    total_size = 0;
+    for (i=0;i<uNumSubDirs;i++)
+         total_size+=pSubIndices[i].uDataSize;
+    //fix offsets
+     temp_offset = sizeof(LOD::Directory) * uNumSubDirs;
+     for (i=0;i<uNumSubDirs;i++)
+            {
+            pSubIndices[i].uOfsetFromSubindicesStart=temp_offset;
+            temp_offset+=pSubIndices[i].uDataSize;
+         }
+    strcpy(Filename, "lod.tmp");
+    tmp_file = fopen(Filename, "wb+");
 
-    strcpy((char *)&v0, "chapter");
-    v15 = v1->uOffsetToSubIndex;
-    v0.dword_000018 = 0;
-    v0.uOfsetFromSubindicesStart = v15;
-    v0.word_00001E = 0;
-    v0.uDataSize = v21;
-    v0.uNumSubIndices = LOWORD(v1->uNumSubIndices);
-    fwrite(&v0, 0x20, 1, v13);
-    fwrite(v1->pSubIndices, 0x20, v1->uNumSubIndices, v13);
-    v16 = v1->pOutputFileHandle;
-    v22 = v2;
-    fseek(v16, 0, 0);
-    if ( v2 > 0 )
-    {
-      do
-      {
-        v17 = v1->uIOBufferSize;
-        if ( v22 <= (signed int)v17 )
-          v17 = v22;
-        fread(v1->pIOBuffer, 1, v17, v1->pOutputFileHandle);
-        fwrite(v1->pIOBuffer, 1, v17, v13);
-        v22 -= v17;
-      }
-      while ( v22 > 0 );
+    if ( tmp_file )
+        {
+        fwrite((const void *)&header, sizeof(LOD::FileHeader), 1, tmp_file);
+        Lindx.Reset();
+        strcpy(Lindx.pFilename, "chapter");
+        Lindx.uOfsetFromSubindicesStart=uOffsetToSubIndex; //10h 16
+        Lindx.uDataSize=sizeof(LOD::Directory) * uNumSubDirs + total_size;		   //14h 20
+        Lindx.dword_000018=0;		   //18h 24 
+        Lindx.uNumSubIndices=uNumSubDirs;		   //1ch 28
+        Lindx.word_00001E=0;		   // 1Eh 30
+        fwrite(&Lindx, sizeof(LOD::Directory), 1, tmp_file);
+        fwrite(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, tmp_file);
+        fseek(pOutputFileHandle, 0, 0);
+        if ( total_size > 0 )
+            {
+            do
+                {
+                write_size = uIOBufferSize;
+                if ( total_size <= (signed int)uIOBufferSize )
+                    write_size =total_size;
+                fread(pIOBuffer, 1,  write_size,  pOutputFileHandle);
+                fwrite(pIOBuffer, 1,  write_size, tmp_file);
+                total_size -=  write_size;
+                }
+                while ( total_size > 0 );
+            }
+        strcpy(NewFilename, (const char *)&pLODName);
+        fclose(tmp_file);
+        fclose(pOutputFileHandle);
+        CloseWriteFile();
+        remove("lodapp.tmp");
+        remove(NewFilename);
+        rename(Filename, NewFilename);
+        CloseWriteFile();
+        LoadFile( (const char *)&pLODName, 0);
+        result = 0;
+        }
+    else
+        {
+        result = 5;
+        }
+    return result;
     }
-    strcpy(NewFilename, (const char *)v1->pLODName);
-    fclose(v13);
-    fclose(v1->pOutputFileHandle);
-    v1->CloseWriteFile();
-    remove("lodapp.tmp");
-    remove(NewFilename);
-    rename(OldFilename, NewFilename);
-    v1->CloseWriteFile();
-    v1->LoadFile(v1->pLODName, 0);
-    result = 0;
-  }
-  else
-  {
-    result = 5;
-  }
-  return result;
-}
-
 
 //----- (00461F71) --------------------------------------------------------
 bool LOD::File::AppendDirectory(LOD::Directory *pDir, const void *pData)
 {
-  unsigned int v3; // edi@1
-  bool result; // eax@2
-  FILE *v5; // ST0C_4@3
-
-  v3 = this->uNumSubIndices;
-  if ( (signed int)v3 < 299 )
+  if ( uNumSubDirs < 299 )
   {
-    memcpy(&this->pSubIndices[v3], pDir, sizeof(this->pSubIndices[v3]));
-    v5 = this->pOutputFileHandle;
-    ++this->uNumSubIndices;
-    fwrite(pData, 1u, pDir->uDataSize, v5);
-    result = 1;
+    memcpy(&pSubIndices[uNumSubDirs], pDir, sizeof(LOD::Directory));
+    ++uNumSubDirs;
+    fwrite(pData, 1u, pDir->uDataSize, pOutputFileHandle);
+    return true;
   }
   else
   {
     MessageBoxA(0, "Unable to append item!", "LOD::File", 0x30u);
-    result = 0;
+    return false;
   }
-  return result;
 }
 
 
 //----- (00461F1E) --------------------------------------------------------
 int LODWriteableFile::CreateTempFile()
 {
-  LODWriteableFile *v1; // esi@1
   int result; // eax@2
-  FILE *pFile; // eax@5
-  int v4; // eax@5
-
-  v1 = this;
-  if ( this->isFileOpened )
+  FILE *pFile; // eax@5;
+  if ( isFileOpened )
   {
-    if ( this->pIOBuffer && this->uIOBufferSize )
+    if (pIOBuffer && uIOBufferSize )
     {
-      this->uCurrentIndexDir = 0;
-      this->uNumSubIndices = 0;
+      uCurrentIndexDir = 0;
+      uNumSubDirs = 0;
       pFile = fopen("lodapp.tmp", "wb+");
-      v1->pOutputFileHandle = pFile;
-      v4 = -(pFile != 0);
-      LOBYTE(v4) = v4 & 0xF9;
-      result = v4 + 7;
+      pOutputFileHandle = pFile;
+      result =pFile? 1:7;
+      
     }
     else
     {
@@ -1645,264 +1566,202 @@
 
 //----- (00461B48) --------------------------------------------------------
 unsigned int LODWriteableFile::Write(const LOD::Directory *pDir, const void *pDirData, int a4)
-{
-  LODWriteableFile *v4; // ebx@1
-  int v5; // esi@1
-  unsigned __int8 v7; // zf@7
-  unsigned __int8 v8; // sf@7
-  const LOD::Directory *v9; // edi@9
-  int v10; // eax@9
-  unsigned __int8 v11; // of@15
-  unsigned __int16 v12; // dx@17
-  LOD::Directory *v13; // eax@17
-  unsigned __int16 v14; // cx@17
-  int v15; // edi@27
-  unsigned int v16; // eax@27
-  int v17; // eax@29
-  int v18; // edx@31
-  int v19; // eax@31
-  void *v20; // edi@32
-  LOD::Directory *v21; // edi@34
-  signed int v22; // esi@34
-  int v23; // eax@34
-  LOD::Directory *v24; // ecx@35
-  int v25; // edx@35
-  __int32 v26; // eax@37
-  int i; // esi@39
-  __int32 v28; // esi@46
-  char pFilename[256]; // [sp+Ch] [bp-230h]@22
-  char NewFilename[256]; // [sp+10Ch] [bp-130h]@51
-  //LOD::Directory Str; // [sp+20Ch] [bp-30h]@27
-  size_t v33; // [sp+22Ch] [bp-10h]@27
-  int v34; // [sp+230h] [bp-Ch]@7
-  __int32 v35; // [sp+234h] [bp-8h]@8
-  int v36; // [sp+238h] [bp-4h]@7
-  size_t Count; // [sp+244h] [bp+8h]@40
-  __int32 Countc; // [sp+244h] [bp+8h]@46
-  size_t Countb; // [sp+244h] [bp+8h]@47
-  FILE *pFile; // [sp+24Ch] [bp+10h]@22
+    {
+     LOD::Directory Lindx;
+    char Filename[256]; 
+    char NewFilename[256];
+    FILE *tmp_file; 
+    int comp_res;
+    bool bRewrite_data;
+    int offset_to_data;
+    int total_data_size;
+    int size_correction;
+    int to_copy_size;
+    int read_size;
+    int curr_position;
+    int insert_index;
+
+    //insert new data in sorted index lod file
+    bRewrite_data = false;
+    insert_index=0;
+    if (!isFileOpened)
+        return 1;
+    if ( !pSubIndices)
+        return 2;
+    if (!pIOBuffer||!uIOBufferSize)
+        return 3;
+
+        for (int i=0;i<uNumSubDirs; i++)
+            {
+            comp_res=_stricmp(pSubIndices[i].pFilename,pDir->pFilename);
+            if(comp_res==0)
+                {
+                insert_index=i;
+                if (a4==0)
+                    {
+                    bRewrite_data=true;
 
-  v4 = this;
-  v5 = 0;
-  if ( !this->isFileOpened )
-    return 1;
-  if ( !this->pSubIndices )
-    return 2;
-  if ( !this->pIOBuffer || !this->uIOBufferSize )
-    return 3;
-  v7 = this->uNumSubIndices == 0;
-  v8 = false;//this->uNumSubIndices != 0; // v8 = (this->uNumSubIndices & 0x80000000u) != 0;
-  v36 = 0;
-  v34 = 0;
-  if ( v8 | v7 )
-  {
-    v9 = pDir;
-    goto LABEL_22;
-  }
-  v35 = 0;
-  while ( 1 )
-  {
-    v9 = pDir;
-    v10 = _strcmpi(v4->pSubIndices[v5].pFilename + v35, pDir->pFilename);
-    if ( v10 )
-    {
-      if ( v10 > 0 )
-        goto LABEL_22;
-      goto LABEL_15;
+                    break;
+                    }
+                if (a4==1)
+                    { 
+                    if(pSubIndices[i].uNumSubIndices<pDir->uNumSubIndices)
+                        {
+                        if (pSubIndices[i].word_00001E<pDir->word_00001E)
+                            return 4;
+                        }
+                    else
+                        bRewrite_data=true;	  
+                    break;
+                    }
+                if (a4==2)
+                    return 4;
+                }
+            else if (comp_res>0)
+                {
+                if (insert_index==0)
+                     insert_index=i;
+                }
+            }
+    strcpy(Filename, "lod.tmp");
+    tmp_file = fopen(Filename, "wb+");
+    if ( !tmp_file )
+        return 5;
+    if (!bRewrite_data)
+        size_correction=0;
+    else
+        size_correction=pSubIndices[insert_index].uDataSize;
+    //create chapter index
+    Lindx.Reset();
+    strcpy(Lindx.pFilename, "chapter");
+    Lindx.dword_000018=0;
+    Lindx.word_00001E=0;
+    Lindx.uNumSubIndices= uNumSubDirs;
+    Lindx.uOfsetFromSubindicesStart=sizeof(LOD::FileHeader)+sizeof(LOD::Directory);
+    total_data_size=uLODDataSize+pDir->uDataSize-size_correction;
+    if (!bRewrite_data)
+        {
+        total_data_size+=sizeof(LOD::Directory);
+        Lindx.uNumSubIndices++;
+        }
+
+    Lindx.uDataSize=total_data_size;
+    uNumSubDirs= Lindx.uNumSubIndices;
+    //move indexes +1 after insert point
+    if  (!bRewrite_data&&(insert_index<uNumSubDirs))
+        {
+        for(int i=uNumSubDirs;i>insert_index; --i)
+            memcpy(&pSubIndices[i],&pSubIndices[i-1],sizeof(LOD::Directory));
+
+        }
+    //insert
+    memcpy(&pSubIndices[insert_index],pDir,sizeof(LOD::Directory));
+    //correct offsets to data
+    if (uNumSubDirs>0)
+        {
+        offset_to_data=sizeof(LOD::Directory)*uNumSubDirs;
+        for (int i=0;i<uNumSubDirs; i++)
+            {
+            pSubIndices[i].uOfsetFromSubindicesStart=offset_to_data;
+            offset_to_data+=pSubIndices[i].uDataSize;
+            }
+        }
+
+    //construct  lod file	with added data
+    fwrite( &header, sizeof(LOD::FileHeader), 1, tmp_file);
+    fwrite(&Lindx, sizeof(LOD::Directory), 1, tmp_file);
+    fseek(pFile,Lindx.uOfsetFromSubindicesStart, SEEK_SET);
+    fwrite(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, tmp_file);
+
+    offset_to_data = sizeof(LOD::Directory) * uNumSubDirs;
+    if ( !bRewrite_data )
+        offset_to_data -= sizeof(LOD::Directory);
+
+    fseek(pFile, offset_to_data, SEEK_CUR);
+    //copy from open lod to temp 	lod	  first half
+    to_copy_size=pSubIndices[insert_index].uOfsetFromSubindicesStart-pSubIndices[0].uOfsetFromSubindicesStart;
+    while(to_copy_size>0)
+        {
+        read_size = uIOBufferSize;
+        if ( to_copy_size <= uIOBufferSize )
+            read_size = to_copy_size;
+        fread(pIOBuffer, 1, read_size, pFile);
+        fwrite(pIOBuffer, 1, read_size, tmp_file);
+        to_copy_size-=read_size;
+        }
+    // add container data
+    fwrite(pDirData, 1, pDir->uDataSize, tmp_file);
+    if ( bRewrite_data )
+        fseek(pFile,size_correction , SEEK_CUR);
+
+    //add remainng data  last half
+    curr_position = ftell(pFile);
+    fseek(pFile, 0, SEEK_END);
+    to_copy_size = ftell(pFile) - curr_position;
+    fseek(pFile, curr_position, SEEK_SET);
+    while ( to_copy_size > 0 )
+        {
+        read_size = uIOBufferSize;
+        if ( to_copy_size <= uIOBufferSize )
+            read_size = to_copy_size;
+        fread(pIOBuffer, 1, read_size, pFile);
+        fwrite(pIOBuffer, 1, read_size, tmp_file);
+        to_copy_size-=read_size;
+        }
+    //replace	  old file by new with added  data
+    strcpy(NewFilename, pLODName);
+    fclose(tmp_file);
+    CloseWriteFile();
+    remove(NewFilename);
+    rename(Filename, NewFilename);
+    CloseWriteFile();
+    //reload new
+    LoadFile(pLODName, 0);
+    return 0;
     }
-    if ( !a4 )
-      goto LABEL_20;
-    if ( a4 == 1 )
-      break;
-    if ( a4 == 2 )
-      return 4;
-LABEL_15:
-    v35 += 32;
-    ++v5;
-    v11 = v5 >= v4->uNumSubIndices;
-    v8 = (v5 - v4->uNumSubIndices) != 0;//v8 = ((v5 - v4->uNumSubIndices) & 0x80000000u) != 0;
-    v34 = v5;
-    //if ( !(v8 ^ v11) )
-    if (v5 >= v4->uNumSubIndices)
-      goto LABEL_22;
-  }
-  v12 = pDir->uNumSubIndices;
-  v13 = &v4->pSubIndices[v5];
-  v14 = v13->uNumSubIndices;
-  if ( v14 >= v12 && (v14 != v12 || (unsigned __int16)v13->word_00001E >= pDir->word_00001E) )
-    return 4;
-LABEL_20:
-  v36 = 1;
-LABEL_22:
-  strcpy(pFilename, "lod.tmp");
-  pFile = fopen(pFilename, "wb+");
-  if ( !pFile )
-    return 5;
-  if ( v36 )
-    v35 = v4->pSubIndices[v5].uDataSize;
-  else
-    v35 = 0;
-  v33 = v9->uDataSize;
-  v15 = v33 - v35;
-
-  LOD::Directory Str; // [sp+20Ch] [bp-30h]@27
-  //LOD::Directory::LOD::Directory(&Str);
-
-  strcpy((char *)&Str, "chapter");
-  v16 = v4->uLODDataSize;
-  Str.uNumSubIndices = LOWORD(v4->uNumSubIndices);
-  Str.dword_000018 = 0;
-  Str.word_00001E = 0;
-  if ( !v36 )
-  {
-    ++Str.uNumSubIndices;
-    v15 += 32;
-  }
-  v7 = v36 == 0;
-  Str.uDataSize = v15 + v16;
-  Str.uOfsetFromSubindicesStart = 288;
-  v17 = (signed __int16)Str.uNumSubIndices;
-  v4->uNumSubIndices = (signed __int16)Str.uNumSubIndices;
-  if ( v7 && v17 > v5 )
-  {
-    v18 = v17;
-    v19 = v17 - v5;
-    do
-    {
-      v20 = &v4->pSubIndices[v18];
-      --v18;
-      --v19;
-      memcpy(v20, (char *)v20 - 32, 0x20u);
-    }
-    while ( v19 );
-    v5 = v34;
-  }
-  v21 = v4->pSubIndices;
-  v34 = 32 * v5;
-  memcpy(&v21[v5], pDir, sizeof(v21[v5]));
-  v22 = 0;
-  v23 = 32 * v4->uNumSubIndices;
-  if ( (signed int)v4->uNumSubIndices > 0 )
-  {
-    v24 = v4->pSubIndices;
-    v25 = 0;
-    do
-    {
-      v24[v25].uOfsetFromSubindicesStart = v23;
-      v24 = v4->pSubIndices;
-      v23 += v24[v25].uDataSize;
-      ++v22;
-      ++v25;
-    }
-    while ( v22 < (signed int)v4->uNumSubIndices );
-  }
-  fwrite(&v4->header, 0x100u, 1u, pFile);
-  fwrite(&Str, 0x20, 1, pFile);
-  fseek(v4->pFile, Str.uOfsetFromSubindicesStart, 0);
-  fwrite(v4->pSubIndices, 0x20u, v4->uNumSubIndices, pFile);
-  v26 = 32 * v4->uNumSubIndices;
-  if ( !v36 )
-    v26 -= 32;
-  fseek(v4->pFile, v26, 1);
-  for ( i = *(unsigned int *)((char *)&v4->pSubIndices->uOfsetFromSubindicesStart + v34)
-          - v4->pSubIndices->uOfsetFromSubindicesStart; i > 0; i -= Count )
-  {
-    Count = v4->uIOBufferSize;
-    if ( i <= (signed int)v4->uIOBufferSize )
-      Count = i;
-    fread(v4->pIOBuffer, 1u, Count, v4->pFile);
-    fwrite(v4->pIOBuffer, 1u, Count, pFile);
-  }
-  fwrite(pDirData, 1u, v33, pFile);
-  if ( v36 )
-    fseek(v4->pFile, v35, 1);
-  Countc = ftell(v4->pFile);
-  fseek(v4->pFile, 0, 2);
-  v28 = ftell(v4->pFile) - Countc;
-  fseek(v4->pFile, Countc, 0);
-  while ( v28 > 0 )
-  {
-    Countb = v4->uIOBufferSize;
-    if ( v28 <= (signed int)v4->uIOBufferSize )
-      Countb = v28;
-    fread(v4->pIOBuffer, 1u, Countb, v4->pFile);
-    fwrite(v4->pIOBuffer, 1u, Countb, pFile);
-    v28 -= Countb;
-  }
-  strcpy(NewFilename, (const char *)v4->pLODName);
-  fclose(pFile);
-  v4->CloseWriteFile();
-  remove(NewFilename);
-  rename(pFilename, NewFilename);
-  v4->CloseWriteFile();
-  v4->LoadFile(v4->pLODName, 0);
-  return 0;
-}
 
 
 //----- (00461A43) --------------------------------------------------------
 bool LODWriteableFile::LoadFile(const char *pFilename, bool bWriting)
-{
-  LODWriteableFile *v3; // esi@1
-  FILE *pFile_dup; // eax@4
-  unsigned int v5; // ecx@5
-  __int32 v6; // eax@5
-  FILE *v7; // ST00_4@5
-  size_t v8; // edi@5
-  const char *v10; // [sp-4h] [bp-30h]@2
+    {
+    LOD::Directory lod_indx ;
+
+    if (bWriting & 1)
+        pFile = fopen(pFilename, "rb");
+    else
+        pFile = fopen(pFilename, "rb+");
+    if (!pFile)
+        return false;
 
-  v3 = this;
-  if ( bWriting & 1 )
-    v10 = "rb";
-  else
-    v10 = "rb+";
-  pFile_dup = fopen(pFilename, v10);
-  v3->pFile = pFile_dup;
-  if ( !pFile_dup )
-  {
-    isFileOpened = false;
-    return 0;
-  }
-  strcpy(pLODName, pFilename);
-  fread(&header, 0x100u, 1u, v3->pFile);
-  
-  LOD::Directory dir; // [sp+Ch] [bp-20h]@5
-  //LOD::Directory::LOD::Directory(&dir);
+    strcpy(pLODName, pFilename);
+    fread(&header, sizeof(LOD::FileHeader), 1, pFile);
+    lod_indx.Reset();
+    fread( &lod_indx,sizeof(LOD::Directory), 1, pFile);
+    fseek(pFile, 0, SEEK_SET);
+    isFileOpened = true;
+    strcpy(pContainerName, "chapter");
+    uCurrentIndexDir = 0;
+    uLODDataSize = lod_indx.uDataSize;
+    uNumSubDirs = lod_indx.uNumSubIndices;
+    uOffsetToSubIndex = lod_indx.uOfsetFromSubindicesStart;
+    fseek(pFile, uOffsetToSubIndex, SEEK_SET);
 
-  fread(&dir, 0x20u, 1u, v3->pFile);
-  fseek(v3->pFile, 0, 0);
-  isFileOpened = 1;
-  strcpy((char *)v3->pContainerName, "chapter");
-  v5 = (signed __int16)dir.uNumSubIndices;
-  v6 = dir.uOfsetFromSubindicesStart;
-  v3->uCurrentIndexDir = 0;
-  v3->uOffsetToSubIndex = v6;
-  v7 = v3->pFile;
-  v3->uNumSubIndices = v5;
-  v3->uLODDataSize = dir.uDataSize;
-  fseek(v7, v6, SEEK_SET);
-  v8 = v3->uNumSubIndices;
-  if ( (signed int)v8 > 300 )
-  {
-    MessageBoxA(0, "LODchapterPages exceed 300", "LOD::File", MB_ICONEXCLAMATION);
-    fclose(v3->pFile);
-    return 0;
-  }
-  fread(pSubIndices, 0x20u, v8, v3->pFile);
-  return 1;
-}
+    if (uNumSubDirs > 300)
+        {
+        MessageBoxW(0, L"LODchapterPages exceed 300", L"LODFile", MB_ICONEXCLAMATION);
+        fclose(pFile);
+        return false;
+        }
+
+    fread(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, pFile);
+    return true;
+    }
 
 
 //----- (00461A11) --------------------------------------------------------
 void LOD::File::FreeSubIndexAndIO()
 {
-  void *v1; // edi@1
-  LOD::Directory **v2; // esi@1
-
-  v1 = this;
-  v2 = &this->pSubIndices;
-  pAllocator->FreeChunk(this->pSubIndices);
-  v1 = (char *)v1 + 264;
+  pAllocator->FreeChunk(pSubIndices);
   pAllocator->FreeChunk(pIOBuffer);// delete [] pIOBuffer;
   pIOBuffer = nullptr;
   pSubIndices = nullptr;
@@ -1912,28 +1771,18 @@
 //----- (00461954) --------------------------------------------------------
 void LOD::File::AllocSubIndicesAndIO(unsigned int uNumSubIndices, unsigned int uBufferSize)
 {
-  //LOD::File *v3; // esi@1
-  LOD::Directory *pSubIndices_dup; // eax@3
-  char v5; // zf@3
-
-  //v3 = this;
   if (pSubIndices)
   {
     MessageBoxA(0, "Attempt to reset a LOD subindex!", "MM6", MB_ICONEXCLAMATION);
     pAllocator->FreeChunk(pSubIndices);
     pSubIndices = nullptr;
   }
-  pSubIndices_dup = (LOD::Directory *)pAllocator->AllocNamedChunk(
-                                      pSubIndices,
-                                      32 * uNumSubIndices,
-                                      "LODsub");
-  v5 = pIOBuffer == 0;
-  pSubIndices = pSubIndices_dup;
-  if ( !v5 )
+  pSubIndices =(LOD::Directory *)pAllocator->AllocNamedChunk( pSubIndices, 32 * uNumSubIndices,"LODsub");
+  if (pIOBuffer)
   {
     MessageBoxA(0, "Attempt to reset a LOD IObuffer!", "MM6", MB_ICONEXCLAMATION);
     pAllocator->FreeChunk(pIOBuffer);
-    pIOBuffer = 0;
+    pIOBuffer = NULL;
     uIOBufferSize = 0;
   }
   if ( uBufferSize )
@@ -1952,69 +1801,57 @@
   unsigned int uDir; // edi@1
   LOD::Directory *curr_index; // eax@7
 
-
   ResetSubIndices();
   uDir = 0;
 
-  if ( header.uNumIndices <= 0)
-	  return 3;
-  else
-	  {
-	  while (stricmp(pContainer, pRoot[uDir].pFilename))
-		  {
-		  ++uDir;  
-		  if (uDir >=  header.uNumIndices )
-			  return 3;
-		  }
-	  strcpy( pContainerName, pContainer);
+  for (uDir=0; uDir <header.uNumIndices;++uDir)
+      {
+       if (!_stricmp(pContainer, pRoot[uDir].pFilename))
+       {
+       strcpy( pContainerName, pContainer);
 	  uCurrentIndexDir = uDir;
 	  curr_index=(LOD::Directory *)&pRoot[uDir];
 	  uOffsetToSubIndex =curr_index->uOfsetFromSubindicesStart ;
-	  uNumSubIndices =curr_index->uNumSubIndices;// *(_WORD *)(v8 + 28);
-	  fseek( pFile, uOffsetToSubIndex, 0);
-	  pSubIndices = (LOD::Directory *)pAllocator->AllocNamedChunk(pSubIndices, sizeof(LOD::Directory)*(uNumSubIndices + 5), "LOD Index");
+	  uNumSubDirs =curr_index->uNumSubIndices;// *(_WORD *)(v8 + 28);
+	  fseek( pFile, uOffsetToSubIndex, SEEK_SET);
+	  pSubIndices = (LOD::Directory *)pAllocator->AllocNamedChunk(pSubIndices, sizeof(LOD::Directory)*(uNumSubDirs + 5), "LOD Index");
 
 	  if ( pSubIndices)
-		  fread( pSubIndices, sizeof(LOD::Directory),  uNumSubIndices,  pFile);
+		  fread( pSubIndices, sizeof(LOD::Directory),  uNumSubDirs,  pFile);
 	  return 0;
-	  }
+       }
+      }
+ return 3;
 }
 
 //----- (004617D5) --------------------------------------------------------
 bool LOD::File::LoadHeader(const char *pFilename, bool bWriting)
 {
-  LOD::File *this_dup; // esi@1
-  FILE *pFile_dup; // eax@6
-  void *pRoot_dup; // eax@7
   const char *v6; // [sp-4h] [bp-Ch]@4
-  FILE *v7; // [sp-4h] [bp-Ch]@7
 
-  this_dup = this;
   if ( this->isFileOpened )
     Close();
   if ( bWriting & 1 )
     v6 = "rb";
   else
     v6 = "rb+";
-  pFile_dup = fopen(pFilename, v6);
-  this_dup->pFile = pFile_dup;
-  if ( pFile_dup )
+
+  pFile = fopen(pFilename, v6);
+  if ( pFile )
   {
-    strcpy(this_dup->pLODName, pFilename);
-    fread(&this_dup->header, 0x100u, 1u, this_dup->pFile);
-    pRoot_dup = pAllocator->AllocNamedChunk(this_dup->pRoot, 0xA0u, "LOD CArray");
-    this_dup->pRoot = (LOD::Directory *)pRoot_dup;
-    v7 = this_dup->pFile;
-    if ( pRoot_dup )
+    strcpy(pLODName, pFilename);
+    fread(&header, sizeof(LOD::FileHeader), 1u, pFile);
+    pRoot = (LOD::Directory *)pAllocator->AllocNamedChunk(pRoot, 160, "LOD CArray");
+    if ( pRoot )
     {
-      fread(pRoot_dup, 0x20u, this_dup->header.uNumIndices, v7);
-      fseek(this_dup->pFile, 0, 0);
-      this_dup->isFileOpened = 1;
+      fread(pRoot, sizeof(LOD::Directory), header.uNumIndices, pFile);
+      fseek(pFile, 0, SEEK_SET);
+      isFileOpened = 1;
       return false;
     }
     else
     {
-      fclose(v7);
+      fclose(pFile);
       return true;
     }
   }
@@ -2177,7 +2014,7 @@
   this_dup = this;
   i = 0;
   i_dup = 0;
-  if ( (signed int)this->uNumSubIndices <= 0 )
+  if ( (signed int)this->uNumSubDirs <= 0 )
   {
 LABEL_4:
     result = 0;
@@ -2188,7 +2025,7 @@
     {
       ++i_dup;
       ++i;
-      if ( i_dup >= (signed int)this_dup->uNumSubIndices )
+      if ( i_dup >= (signed int)this_dup->uNumSubDirs )
         goto LABEL_4;
     }
     result = 1;
@@ -2218,7 +2055,7 @@
 }
 
 //----- (00461580) --------------------------------------------------------
-FILE *LOD::File::FindContainer(const char *pContainerName, bool bLinearSearch)
+FILE *LOD::File::FindContainer(const char *pContainer_Name, bool bLinearSearch)
 {
   unsigned int v4; // eax@4
   if (!isFileOpened)
@@ -2227,8 +2064,8 @@
 
   if (bLinearSearch)
   {
-    for (uint i = 0; i < uNumSubIndices; ++i)
-      if (!strcmpi(pContainerName, pSubIndices[i].pFilename))
+    for (uint i = 0; i < uNumSubDirs; ++i)
+      if (!strcmpi(pContainer_Name, pSubIndices[i].pFilename))
       {
         v4 = pSubIndices[i].uOfsetFromSubindicesStart;
         fseek(pFile, uOffsetToSubIndex + v4, SEEK_SET);
@@ -2239,7 +2076,7 @@
   }
   else
   {
-    CalcIndexFast(0, uNumSubIndices, pContainerName);
+    CalcIndexFast(0, uNumSubDirs, pContainer_Name);
     if ( _6A0CA4_lod_binary_search < 0 )
       return 0;
     v4 = pSubIndices[_6A0CA4_lod_binary_search].uOfsetFromSubindicesStart;
--- a/LOD.h	Tue Mar 26 15:21:03 2013 +0000
+++ b/LOD.h	Thu Mar 28 00:37:27 2013 +0400
@@ -88,7 +88,7 @@
     char pContainerName[16];
     unsigned int uCurrentIndexDir;
     unsigned int uLODDataSize;
-    unsigned int uNumSubIndices;
+    unsigned int uNumSubDirs;
     struct Directory *pSubIndices;
     unsigned int uOffsetToSubIndex;
     FILE *pOutputFileHandle;
@@ -109,9 +109,9 @@
   unsigned int Write(const LOD::Directory *pDir, const void *pDirData, int a4);
   void CloseWriteFile();
   int CreateTempFile();
-  int Save();
+  int FixDirectoryOffsets();
   bool _4621A7();
-  int _461492(LOD::FileHeader *pHeader, LOD::Directory *pDir, const char *Source);
+  int CreateNewLod(LOD::FileHeader *pHeader, LOD::Directory *pDir, const char *Source);
 
   /*FILE *pFile;
   char pLODName[256];
--- a/SaveLoad.cpp	Tue Mar 26 15:21:03 2013 +0000
+++ b/SaveLoad.cpp	Thu Mar 28 00:37:27 2013 +0400
@@ -270,7 +270,7 @@
   CHAR Buffer; // [sp+Ch] [bp-264h]@59
   char Dir[255]; // [sp+8Ch] [bp-1E4h]@51
   char Drive[255]; // [sp+ACh] [bp-1C4h]@51
-  SavegameHeader header; // [sp+CCh] [bp-1A4h]@10
+  SavegameHeader save_header; // [sp+CCh] [bp-1A4h]@10
   //int v43; // [sp+CCh] [bp-1A4h]@10
   //char Dest[20]; // [sp+E0h] [bp-190h]@10
   //unsigned __int64 pTimePlayed; // [sp+F4h] [bp-17Ch]@10
@@ -283,7 +283,7 @@
   int pPositionX; // [sp+20Ch] [bp-64h]@2
   int v53; // [sp+210h] [bp-60h]@2
   int v54; // [sp+214h] [bp-5Ch]@2
-  ODMHeader Src; // [sp+218h] [bp-58h]@30
+  ODMHeader odm_data; // [sp+218h] [bp-58h]@30
   char v56; // [sp+21Ch] [bp-54h]@30
   char v57; // [sp+21Dh] [bp-53h]@30
   char v58; // [sp+21Eh] [bp-52h]@30
@@ -347,14 +347,14 @@
   }
 
   assert(sizeof(SavegameHeader) == 100);
-  memset(header.pName, 0, 20);
-  memset(header.pLocationName, 0, 20);
-  memset(header.field_30, 0, 52);
-  strcpy(header.pLocationName, pCurrentMapName);
-  header.uWordTime = pParty->uTimePlayed;
+  memset(save_header.pName, 0, 20);
+  memset(save_header.pLocationName, 0, 20);
+  memset(save_header.field_30, 0, 52);
+  strcpy(save_header.pLocationName, pCurrentMapName);
+  save_header.uWordTime = pParty->uTimePlayed;
   strcpy(pLodDirectory.pFilename, "header.bin");
   pLodDirectory.uDataSize = sizeof(SavegameHeader);
-  if (pNew_LOD->Write(&pLodDirectory, &header, 0))
+  if (pNew_LOD->Write(&pLodDirectory, &save_header, 0))
   {
     sprintf(Str, pGlobalTXT_LocalizationStrings[612], 201);
     MessageBoxA(nullptr, Str, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\LoadSave.cpp:784", 0);
@@ -426,23 +426,22 @@
     //__debugbreak();
     CompactLayingItemsList();
     compressed_buf = (char*)malloc(1000000);
-  //  v71 = (std::string *)compressed_buf;
-    Src.uVersion = 91969;
-    Src.pMagic[0] = 'm';
-    Src.pMagic[1] = 'v';
-    Src.pMagic[2] = 'i';
-    Src.pMagic[3] = 'i';
-    Src.uCompressedSize = 0;
-    Src.uDecompressedSize = 0;
+    odm_data.uVersion = 91969;
+    odm_data.pMagic[0] = 'm';
+    odm_data.pMagic[1] = 'v';
+    odm_data.pMagic[2] = 'i';
+    odm_data.pMagic[3] = 'i';
+    odm_data.uCompressedSize = 0;
+    odm_data.uDecompressedSize = 0;
     data_write_pos = uncompressed_buff;
-    memcpy((void *)compressed_buf, &Src, 0x10);
+    memcpy((void *)compressed_buf, &odm_data, 0x10);
     if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
     {
       pIndoor->dlv.uNumFacesInBModels = pIndoor->uNumFaces;
       pIndoor->dlv.uNumBModels = 0;
       pIndoor->dlv.uNumDecorations = uNumLevelDecorations;
-      memcpy(data_write_pos, &pIndoor->dlv, 0x28);
-      data_write_pos += 40;
+      memcpy(data_write_pos, &pIndoor->dlv,sizeof(DDM_DLV_Header) );//0x28
+      data_write_pos += sizeof(DDM_DLV_Header);
       memcpy(data_write_pos, pIndoor->_visible_outlines, 0x36B);
       data_write_pos += 875;
     
@@ -482,13 +481,11 @@
     }
     else
     {
-      v18 = 0;
       pOutdoor->ddm.uNumFacesInBModels = 0;
       for (int i=0; i<pOutdoor->uNumBModels;++i)
           {
-          v18 +=pOutdoor->pBModels[i].uNumFaces;
+          pOutdoor->ddm.uNumFacesInBModels +=pOutdoor->pBModels[i].uNumFaces;
           }
-      pOutdoor->ddm.uNumFacesInBModels = v18;
       pOutdoor->ddm.uNumBModels = pOutdoor->uNumBModels;
       pOutdoor->ddm.uNumDecorations = uNumLevelDecorations;
       memcpy(data_write_pos, &pOutdoor->ddm, sizeof(DDM_DLV_Header));//0x28
@@ -497,39 +494,18 @@
       data_write_pos += 968;
       memcpy(data_write_pos, pOutdoor->uDicovered_area, 0x3C8);
       data_write_pos += 968;
-      if ( (signed int)pOutdoor->uNumBModels > 0 )
-      {
-        v23 = pOutdoor->pBModels;
-        v24 = 76;
-		for (int i =  0; i < (signed int)pOutdoor->uNumBModels ; ++i)
-        {
-		  //v25 = v23[i].uNumFaces == 0;//*(int *)&v23->pModelName[v24] == 0;
-		 // v26 = v23[i].uNumFaces < 0;//*(int *)&v23->pModelName[v24] < 0;
-          if ( pOutdoor->pBModels[i].uNumFaces>0)
-          {
-            v68 = 0;
+		for (int i =  0; i < pOutdoor->uNumBModels ; ++i)  
 			for (int j =  0; j < pOutdoor->pBModels[i].uNumFaces;++j)//*(int *)&pOutdoor->pBModels->pModelName[v24]; ++j)
-            {
-			  v38 = &(v23[i].pFaces[j].uAttributes); //(char *)v68 + *(int *)&v23->pModelName[v24 + 8] + 28;				 
-              memcpy(data_write_pos, v38, 4);
-              v23 = pOutdoor->pBModels;
-              v68 += 154;
+            {		 
+              memcpy(data_write_pos, &(pOutdoor->pBModels[i].pFaces[j].uAttributes), 4);
               data_write_pos += 4;
             }
-           }
-          v24 += 188;
-        }
-      }
-      if ( (signed int)uNumLevelDecorations > 0 )
-      {
-        v66 = &pLevelDecorations[0].field_2;
+      
         for (int i = 0; i <= (signed int)uNumLevelDecorations; ++i)
         {
-          memcpy(data_write_pos, v66, 2);
-          v66 += 16;
+          memcpy(data_write_pos, &pLevelDecorations[i].field_2, 2);
           data_write_pos += 2;
         }
-      }
       memcpy(data_write_pos, &uNumActors, 4);
       data_write_pos += 4;
       memcpy(data_write_pos, pActors, 836 * uNumActors);
@@ -546,8 +522,6 @@
       data_write_pos += 200;
       memcpy(data_write_pos, &pOutdoor->loc_time, 0x38);
       data_write_pos += 56;
-
-      //compressed_buf = (int)v71;
     }
     strcpy(Source, pCurrentMapName);
     _splitpath(Source, Drive, Dir, Filename, Ext);
--- a/SpriteObject.cpp	Tue Mar 26 15:21:03 2013 +0000
+++ b/SpriteObject.cpp	Thu Mar 28 00:37:27 2013 +0400
@@ -1080,23 +1080,13 @@
 //----- (0042F933) --------------------------------------------------------
 void SpriteObject::OnInteraction(unsigned int uLayingItemID)
 {
-  unsigned int v1; // ecx@1
-  unsigned __int16 *pAttributes; // ecx@2
-  unsigned __int16 v3; // ax@2
-
-  //__debugbreak(); // find out what's going on
-
-  v1 = uLayingItemID;
-  pSpriteObjects[v1].uObjectDescID = 0;
+  pSpriteObjects[uLayingItemID].uObjectDescID = 0;
   if ( pParty->bTurnBasedModeOn == 1 )
   {
-    pAttributes = &pSpriteObjects[v1].uAttributes;
-    v3 = *pAttributes;
-    if ( *pAttributes & 4 )
+    if (pSpriteObjects[uLayingItemID].uAttributes & 4 )
     {
-      v3 = v3 & 0xFB;
+      pSpriteObjects[uLayingItemID].uAttributes &= 0xFB;
       --pTurnEngine->field_1C;
-      *pAttributes = v3;
     }
   }
 }
--- a/mm7_2.cpp	Tue Mar 26 15:21:03 2013 +0000
+++ b/mm7_2.cpp	Thu Mar 28 00:37:27 2013 +0400
@@ -6490,25 +6490,25 @@
   if (pGames_LOD->LoadFile("data\\games.lod", 1))
   {
     pNew_LOD = new LODWriteableFile;
-    pNew_LOD->AllocSubIndicesAndIO(300, 0x186A0u);
+    pNew_LOD->AllocSubIndicesAndIO(300, 100000);
     return true;
   }
   return false;
 }
 
 //----- (0046086A) --------------------------------------------------------
-void Autosave()
+void SaveNewGame()
 {
   FILE *v3; // eax@7
   LOD::FileHeader this_; // [sp+Ch] [bp-16Ch]@3
   LOD::Directory pDir; // [sp+10Ch] [bp-6Ch]@4
-  LOD::Directory v7; // [sp+12Ch] [bp-4Ch]@9
+  LOD::Directory save_game_dir; // [sp+12Ch] [bp-4Ch]@9
   LOD::Directory a3; // [sp+14Ch] [bp-2Ch]@3
   void *pSave; // [sp+170h] [bp-8h]@3
 
   if ( pVideoPlayer->AnyMovieLoaded() )
     pVideoPlayer->Unload();
-  pSave = pAllocator->AllocNamedChunk(0, 0xF4240, 0);
+  pSave = pAllocator->AllocNamedChunk(0, 1000000, 0);
   pNew_LOD->CloseWriteFile();
   remove("data\\new.lod");
   this_.Reset();
@@ -6519,26 +6519,26 @@
   a3.dword_000018 = 0;
   a3.word_00001E = 0;
   strcpy(a3.pFilename, "current");
-  pNew_LOD->_461492(&this_, &a3, "data\\new.lod");
+  pNew_LOD->CreateNewLod(&this_, &a3, "data\\new.lod");
   if ( pNew_LOD->LoadFile("data\\new.lod", 0) )
   {
     pNew_LOD->CreateTempFile();
-    pNew_LOD->uNumSubIndices = 0;
+    pNew_LOD->uNumSubDirs = 0;
     pDir.Reset();
 
-    for (int i = pGames_LOD->uNumSubIndices / 2; i < pGames_LOD->uNumSubIndices; ++i)
+    for (int i = pGames_LOD->uNumSubDirs / 2; i < pGames_LOD->uNumSubDirs; ++i)
     {
       memcpy(&pDir, &pGames_LOD->pSubIndices[i], sizeof(pDir));
       v3 = pGames_LOD->FindContainer(pGames_LOD->pSubIndices[i].pFilename, 1);
       fread(pSave, pGames_LOD->pSubIndices[i].uDataSize, 1, v3);
       pNew_LOD->AppendDirectory(&pDir, pSave);
     }
-    v7.Reset();
-    strcpy(pSavegameHeader->pLocationName, "out01.odm");
-    strcpy(v7.pFilename, "header.bin");
-    v7.uDataSize = 100;
-    pNew_LOD->AppendDirectory(&v7, &pSavegameHeader);
-    pNew_LOD->Save();
+    save_game_dir.Reset();
+    strcpy(pSavegameHeader[0].pLocationName, "out01.odm");
+    strcpy(save_game_dir.pFilename, "header.bin");
+    save_game_dir.uDataSize = 100;
+    pNew_LOD->AppendDirectory(&save_game_dir, &pSavegameHeader[0]);
+    pNew_LOD->FixDirectoryOffsets();
     pParty->vPrevPosition.y = 0;
     pParty->vPrevPosition.x = 12552;
     pParty->vPosition.x = 12552;
@@ -9056,7 +9056,7 @@
           DeleteCCharFont();
           bFlashQuestBook = true;
           pGame->pCShow->PlayMovie(MOVIE_Emerald, 0);
-          Autosave();
+          SaveNewGame();
           pGame->Loop();
           if ( uGameState == GAME_STATE_NEWGAME_OUT_GAMEMENU )
           {
--- a/mm7_3.cpp	Tue Mar 26 15:21:03 2013 +0000
+++ b/mm7_3.cpp	Thu Mar 28 00:37:27 2013 +0400
@@ -14931,834 +14931,834 @@
 // 4F75D8: using guessed type int ai_arrays_size;
 
 //----- (00401A91) --------------------------------------------------------
-void __cdecl UpdateActorAI()
-{
-	//unsigned int v0; // esi@4
-	int v1; // eax@7
-	int v2; // ecx@7
-	int v3; // eax@7
-	signed int v4; // edi@10
-	Actor *v5; // esi@12
-	signed int v6; // eax@14
-	__int16 v7; // cx@14
-	Player **v8; // esi@20
-	Player *pPlayer; // ecx@21
-	//Actor *pActor; // esi@34
-	//__int16 v11; // ax@34
-	//unsigned int v12; // eax@47
-	//signed int v13; // edi@47
-	//SpellBuff *v14; // ebx@47
-	//unsigned int v15; // edi@67
-	//char *v16; // eax@67
-	//unsigned int v17; // edx@67
-	//unsigned int v18; // ecx@67
-	//unsigned __int16 v19; // ax@72
-	//int *v20; // esi@80
-	Actor *v21; // ebx@80
-	unsigned __int16 v22; // ax@86
-	//signed int v23; // eax@94
-	//unsigned int v24; // eax@102
-	signed int v25; // edi@102
-	SpellBuff *v26; // esi@102
-	unsigned int v27; // ecx@123
-	unsigned int v28; // eax@123
-	unsigned int v29; // eax@127
-	AIDirection *v30; // eax@129
-	unsigned __int16 v31; // ax@132
-	unsigned int v32; // esi@142
-	int v33; // eax@144
-	int v34; // eax@147
-	char v35; // al@150
-	unsigned int v36; // edi@152
-	signed int v37; // eax@154
-	unsigned __int8 v38; // sf@158
-	unsigned __int8 v39; // of@158
-	signed int v40; // edx@166
-	unsigned int v41; // ecx@166
-	double v42; // st7@176
-	double v43; // st6@176
-	bool v44; // eax@189
-	bool v45; // eax@192
-	unsigned __int8 v46; // cl@197
-	double v47; // st7@206
-	double v48; // st7@207
-	char v49; // zf@208
-	char v50; // zf@214
-	signed int v51; // edx@219
-	unsigned int v52; // ecx@219
-	__int16 v53; // fps@224
-	unsigned __int8 v54; // c0@224
-	unsigned __int8 v55; // c3@224
-	double v56; // st7@226
-	AIDirection *v57; // eax@246
-	double v58; // st7@246
-	signed int v59; // [sp-18h] [bp-C8h]@213
-	int v60; // [sp-14h] [bp-C4h]@144
-	int v61; // [sp-14h] [bp-C4h]@168
-	AIDirection *v62; // [sp-14h] [bp-C4h]@213
-	signed int v63; // [sp-14h] [bp-C4h]@216
-	unsigned int v64; // [sp-14h] [bp-C4h]@219
-	unsigned int v65; // [sp-10h] [bp-C0h]@144
-	char v66; // [sp-10h] [bp-C0h]@147
-	AIDirection *v67; // [sp-10h] [bp-C0h]@167
-	int v68; // [sp-10h] [bp-C0h]@168
-	AIDirection *v69; // [sp-10h] [bp-C0h]@206
-	int v70; // [sp-10h] [bp-C0h]@213
-	AIDirection *v71; // [sp-10h] [bp-C0h]@216
-	AIDirection v72; // [sp+0h] [bp-B0h]@246
-	AIDirection a3; // [sp+1Ch] [bp-94h]@129
-	AIDirection v74; // [sp+38h] [bp-78h]@246
-	AIDirection v75; // [sp+54h] [bp-5Ch]@129
-	int v76; // [sp+70h] [bp-40h]@83
-	signed int a1; // [sp+74h] [bp-3Ch]@129
-	int v78; // [sp+78h] [bp-38h]@79
-	AIDirection pDir; // [sp+7Ch] [bp-34h]@129
-	float v80; // [sp+98h] [bp-18h]@33
-	int v81; // [sp+9Ch] [bp-14h]@100
-	int v82; // [sp+A0h] [bp-10h]@45
-	//unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
-	unsigned int v84; // [sp+A8h] [bp-8h]@11
-	signed int a2; // [sp+ACh] [bp-4h]@83
-	
-	if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
-	MakeActorAIList_ODM();
-	else
-	MakeActorAIList_BLV();
-	
-	//v0 = 0;
-	if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
-	{
-		if ( pParty->armageddon_timer > 417 )
-		{
-			pParty->armageddon_timer = 0;
-		}
-		else
-		{
-			pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
-			v1 = rand();
-			v2 = 128;
-			v3 = pParty->sRotationX + v1 % 16 - 8;
-			pParty->sRotationX = v3;
-			if ( v3 > 128 || (v2 = -128, v3 < -128) )
-			pParty->sRotationX = v2;
-			pParty->uFlags |= 2u;
-			pParty->armageddon_timer -= pMiscTimer->uTimeElapsed;
-			v4 = pParty->field_16140 + 50;
-			if ( pParty->armageddon_timer <= 0 )
-			{
-				pParty->armageddon_timer = 0;
-				v84 = 0;
-				if ( (signed int)uNumActors > 0 )
-				{
-					v5 = pActors;//[0].sCurrentHP;
-					do
-					{
-						if ( v5->CanAct() )
-						{
-							v6 = stru_50C198.CalcMagicalDamageToActor(v5, 5, v4);
-							v7 = v5->sCurrentHP - v6;
-							v5->sCurrentHP = v7;
-							if ( v6 )
-							{
-								if ( v7 >= 0 )
-								{
-									Actor::_4030AD(v84, 4, 0);
-								}
-								else
-								{
-									Actor::Die(v84);
-									if ( v5->pMonsterInfo.uExp )
-									GivePartyExp(pMonsterStats->pInfos[v5->pMonsterInfo.uID].uExp);
-								}
-							}
-						}
-						++v84;
-						++v5;
-					}
-					while ( (signed int)v84 < (signed int)uNumActors );
-				}
-				v8 = &pPlayers[1];
-				do
-				{
-					pPlayer = *v8;
-					if ( !(*v8)->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
-					pPlayer->ReceiveDamage(v4, 5);
-					++v8;
-				}
-				while ( (signed int)v8 <= (signed int)&pPlayers[4] );
-				//v0 = 0;
-			}
-			if (pTurnEngine->field_1C)
-			--pTurnEngine->field_1C;
-		}
-	}
-	
-	if (pParty->bTurnBasedModeOn)
-	{
-		pTurnEngine->_405E14();
-		return;
-	}
-	
-	
-	//uActorID = v0;
-	for (uint i = 0; i < uNumActors; ++i)
-	{
-		auto actor = pActors + i;
-		//LODWORD(v80) = (int)(char *)pActors + 176; // uAIState
-		//do
-		//{
-			//pActor = (Actor *)(LODWORD(v80) - 176);
-			//v11 = *(unsigned int *)LODWORD(v80);
-			//v49 = *(unsigned int *)LODWORD(v80) == 5;
-			ai_near_actors_targets_pid[i] = OBJECT_Player;
-			if (actor->uAIState == Dead || actor->uAIState == Removed || actor->uAIState == Disabled || actor->uAttributes & 0x0400)
-			continue;
-			
-			if (!actor->sCurrentHP && actor->uAIState != Dying)
-			Actor::Die(i);
-			
-			//v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
-			//v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
-			//v12 = 0;
-			//v13 = 0;
-			//v14 = (SpellBuff *)(LODWORD(v80) + 36);
-			for (uint j = 0; j < 22; ++j)
-			{
-				if (j != 10)
-				actor->pActorBuffs[j]._4585CA(pParty->uTimePlayed);
-			}
-			/*do
-			{
-				if ( v13 != 10 )
-				{
-					v14->_4585CA(pParty->uTimePlayed);
-					v12 = 0;
-				}
-				++v13;
-				++v14;
-			}
-			while ( v13 < 22 );*/
-			if (!actor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime)
-			//&& SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12 && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
-			// || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
-			actor->uActorHeight = pMonsterList->pMonsters[actor->pMonsterInfo.uID - 1].uMonsterHeight;
-			if (actor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime)
-			actor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-			else
-			actor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[actor->pMonsterInfo.uID].uHostilityType;
-			
-			if (actor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime ||
-			actor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime)
-			continue;
-			
-			//v15 = pMiscTimer->uTimeElapsed;
-			//v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
-			//v17 = pActor->uCurrentActionTime;
-			//v18 = pActor->pMonsterInfo.uRecoveryTime;
-			if (actor->pMonsterInfo.uRecoveryTime)
-			{
-				if (actor->pMonsterInfo.uRecoveryTime < pMiscTimer->uTimeElapsed)
-				actor->pMonsterInfo.uRecoveryTime = 0;
-				else actor->pMonsterInfo.uRecoveryTime -= pMiscTimer->uTimeElapsed;
-			}
-			
-			actor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
-			if (actor->uCurrentActionTime < actor->uCurrentActionLength)
-			continue;
-			
-			//v19 = actor->uAIState;
-			if (actor->uAIState == Dying)
-			actor->uAIState = Dead;
-			else
-			{
-				if (actor->uAIState != Summoned)
-				{
-					Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr);
-					continue;
-				}
-				actor->uAIState = Standing;
-			}
-			
-			actor->uCurrentActionTime = 0;
-			actor->uCurrentActionLength = 0;
-			actor->UpdateAnimation();
-			//LABEL_78:
-			//++uActorID;
-			//LODWORD(v80) += 836;
-		//}
-		//while ( (signed int)uActorID < (signed int)uNumActors );
-	}
-	
-	
-	v78 = 0;
-	int actor_id = -1;
-	if ( ai_arrays_size > 0 )
-	{
-		//while ( 1 )
-		for(v78 = 0; v78 < ai_arrays_size; ++v78)
-		{
-			actor_id = ai_near_actors_ids[v78];
-			assert(actor_id < uNumActors);
-			
-			//v20 = &ai_near_actors_targets_pid[actor_id];
-			v21 = &pActors[actor_id];
-			Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
-			if (v21->pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[actor_id])
-			v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-			a2 = ai_near_actors_targets_pid[actor_id];
-			v76 = a2 & 7;
-			if ( (a2 & 7) == OBJECT_Actor)
-			v80 = 0.5;
-			else
-			v80 = 1.0;
-			v22 = v21->uAIState;
-			if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
-			{
-				continue;
-			}
-			else
-			{
-				if ( !v21->sCurrentHP )
-				Actor::Die(actor_id);
-				v25 = 0;
-				v26 = v21->pActorBuffs;
-				do
-				{
-					if ( v25 != 10 )
-					{
-						v26->_4585CA(pParty->uTimePlayed);
-						//v24 = 0;
-					}
-					++v25;
-					++v26;
-				}
-				while ( v25 < 22 );
-				if ( (signed __int64)v21->pActorBuffs[3].uExpireTime > 0
-				&& SHIDWORD(v21->pActorBuffs[3].uExpireTime) <= 0
-				&& (SHIDWORD(v21->pActorBuffs[3].uExpireTime) < 0
-				|| LODWORD(v21->pActorBuffs[3].uExpireTime) <= 0) )
-				v21->uActorHeight = pMonsterList->pMonsters[v21->pMonsterInfo.uID - 1].uMonsterHeight;
-				if ( (signed __int64)v21->pActorBuffs[1].uExpireTime > 0 )
-				{
-					v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
-					if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) <= 0 )
-					{
-						if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) < 0
-						|| LODWORD(v21->pActorBuffs[1].uExpireTime) <= 0 )
-						v21->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[v21->pMonsterInfo.uID].uHostilityType;
-					}
-				}
-				if ( (signed __int64)v21->pActorBuffs[2].uExpireTime > 0
-				&& SHIDWORD(v21->pActorBuffs[2].uExpireTime) <= 0
-				&& (SHIDWORD(v21->pActorBuffs[2].uExpireTime) < 0
-				|| LODWORD(v21->pActorBuffs[2].uExpireTime) <= 0) )
-				{
-					v21->uAIState = Removed;
-					continue;
-				}
-				else if ( v21->pActorBuffs[5].uExpireTime || v21->pActorBuffs[6].uExpireTime )
-				{
-					continue;
-				}
-				else
-				{
-					v27 = pMiscTimer->uTimeElapsed;
-					v28 = v21->pMonsterInfo.uRecoveryTime;
-					v21->uCurrentActionTime += pMiscTimer->uTimeElapsed;
-					if ( (signed int)v28 > 0 )
-					v21->pMonsterInfo.uRecoveryTime = v28 - v27;
-					if ( v21->pMonsterInfo.uRecoveryTime< 0 )
-					v21->pMonsterInfo.uRecoveryTime = 0;
-					v29 = v21->uAttributes;
-					if ( !(v29 & 0x8000) )
-					v21->uAttributes = v29 | 0x8000;
-					a1 = 8 * actor_id | OBJECT_Actor;
-					v30 = Actor::GetDirectionInfo(8 * actor_id | OBJECT_Actor, a2, &a3, 0);
-					v49 = v21->pMonsterInfo.uHostilityType == 0;
-					memcpy(&v75, v30, sizeof(v75));
-					memcpy(&pDir, &v75, sizeof(pDir));
-					if ( !v49
-					&& (signed int)v21->pMonsterInfo.uRecoveryTime <= 0
-					&& v80 * 307.2 >= (double)(signed int)v75.uDistance
-					&& ((v31 = v21->uAIState, v31 == 6) || !v31 || v31 == 1 || v31 == 9)
-					|| v21->pMonsterInfo.uMissleAttack1Type && v21->uAIState == 8 )
-					{
-						v32 = actor_id;
-					}
-					else
-					{
-						if ( (signed int)v21->uCurrentActionTime < v21->uCurrentActionLength )
-						{
-							continue;
-						}
-						else if ( v21->uAIState == 2 )
-						{
-							v32 = actor_id;
-							v35 = stru_50C198.special_ability_use_check(v21, actor_id);
-							stru_50FE08.Add(
-							a1,
-							5120,
-							v21->vPosition.x,
-							v21->vPosition.y,
-							v21->vPosition.z + ((signed int)v21->uActorHeight >> 1),
-							v35,
-							1
-							);
-						}
-						else if ( v21->uAIState == 3 )
-						{
-							v34 = v21->pMonsterInfo.uMissleAttack1Type;
-							v66 = 0;
-							v32 = actor_id;
-							Actor::_404874(actor_id, &pDir, v34, v66);
-						}
-						else if ( v21->uAIState == 12 )
-						{
-							v34 = v21->pMonsterInfo.uMissleAttack2Type;
-							v66 = 1;
-							v32 = actor_id;
-							Actor::_404874(actor_id, &pDir, v34, v66);
-						}
-						else
-						{
-							v32 = actor_id;
-							if ( v21->uAIState == 13 )
-							{
-								v65 = v21->pMonsterInfo.uSpellSkillAndMastery1;
-								v60 = 2;
-								v33 = v21->pMonsterInfo.uSpell1ID;
-								Actor::_404AC7(actor_id, &pDir, v33, v60, v65);
-							}
-							else if ( v21->uAIState == 18 )
-							{
-								v65 = v21->pMonsterInfo.uSpellSkillAndMastery2;
-								v60 = 3;
-								v33 = v21->pMonsterInfo.uSpell2ID;
-								Actor::_404AC7(actor_id, &pDir, v33, v60, v65);
-							}
-						}
-					}
-				}
-			}
-			v36 = v75.uDistance;
-			if ( !v21->pMonsterInfo.uHostilityType )
-			{
-				if ( v76 == 3 )
-				{
-					v36 = v75.uDistance;
-					v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (v21->pMonsterInfo.uID - 1) / 3]
-					+ (pActors[a2 >> 3].pMonsterInfo.uID - 1) / 3);
-				}
-				else
-				{
-					v37 = 4;
-				}
-				if ( v37 == 2 )
-				{
-					v39 = __OFSUB__(v36, 1024);
-					v38 = ((v36 - 1024) & 0x80000000u) != 0;
-				}
-				else if ( v37 == 3 )
-				{
-					v39 = __OFSUB__(v36, 2560);
-					v38 = ((v36 - 2560) & 0x80000000u) != 0;
-				}
-				else if ( v37 == 4 )
-				{
-					v39 = __OFSUB__(v36, 5120);
-					v38 = ((v36 - 5120) & 0x80000000u) != 0;
-				}
-				if ( v37 >= 1 && v37 <= 4 && v38 ^ v39 || v37 == 1 )
-				v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
-			}
-			if ( (signed __int64)v21->pActorBuffs[4].uExpireTime > 0 )
-			{
-				v40 = a2;
-				v41 = v32;
-				if ( (signed int)v36 >= 10240 )
-				{
-					v68 = 0;
-					v61 = 1024;
-					Actor::_4032B2(v41, v40, v61, v68);
-					continue;
-				}
-				v67 = &pDir;
-				Actor::_402968(v41, v40, 0, v67);
-				continue;
-			}
-			if ( v21->pMonsterInfo.uHostilityType == 4 && a2 )
-			{
-				if ( !(v21->uAttributes & 0x020000) || v21->pMonsterInfo.uAIType == 1 )
-				{
-					if ( v21->pMonsterInfo.uAIType == 1 )
-					{
-						v67 = &pDir;
-						if ( v21->pMonsterInfo.uMovementType != 5 )
-						{
-							v40 = a2;
-							v41 = v32;
-							Actor::_402968(v41, v40, 0, v67);
-							continue;
-						}
-						Actor::AI_Stand(
-						v32,
-						a2,
-						(signed __int64)((double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333),
-						&pDir);
-					}
-					else
-					{
-						if ( v21->pMonsterInfo.uAIType == 2 )
-						{
-							v84 = v21->sCurrentHP;
-							v42 = (double)(signed int)v84;
-							v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.2;
-						}
-						else
-						{
-							v84 = v21->sCurrentHP;
-							v42 = (double)(signed int)v84;
-							v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.1;
-						}
-						if ( v21->pMonsterInfo.uAIType == 2 || v21->pMonsterInfo.uAIType == 3 )
-						if ( v43 > v42 && (signed int)v36 < 10240 )
-						{
-							v67 = &pDir;
-							v40 = a2;
-							v41 = v32;
-							Actor::_402968(v41, v40, 0, v67);
-							continue;
-						}
-					}
-				}
-				v81 = v36 - v21->uActorRadius;
-				if ( v76 == 3 )
-				v81 -= pActors[a2 >> 3].uActorRadius;
-				if ( v81 < 0 )
-				v81 = 0;
-				rand();
-				v44 = (signed int)v21->pMonsterInfo.uRecoveryTime <= 0;
-				v21->uAttributes &= 0xFBFFFF;
-				v82 = 0;
-				v49 = v21->pMonsterInfo.uMovementType == 5;
-				v84 = v44;
-				if ( v49 )
-				v82 = 1;
-				if ( v81 < 5120 )
-				{
-					v45 = stru_50C198.special_ability_use_check(v21, v32);
-					if ( !v45 )
-					{
-						if ( v21->pMonsterInfo.uMissleAttack1Type )
-						{
-							if ( v84 )
-							{
-								Actor::_403476(v32, a2, &pDir);
-								continue;
-								
-							}
-							if ( v82 )
-							{
-								v69 = &pDir;
-								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v51 = a2;
-								v64 = (signed __int64)v47;
-								v52 = v32;
-								Actor::AI_Stand(v52, v51, v64, v69);
-								continue;
-							}
-							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-							//UNDEF(v53);
-							v69 = &pDir;
-							if ( !(v54 | v55) )
-							{
-								v51 = a2;
-								v64 = (signed __int64)v47;
-								v52 = v32;
-								Actor::AI_Stand(v52, v51, v64, v69);
-								continue;
-							}
-							Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
-							continue;
-						}
-						v56 = v80 * 307.2;
-						if ( (double)v81 >= v56 )
-						{
-							if ( v81 >= 1024 )
-							{
-								if ( v82 )
-								{
-									v69 = &pDir;
-									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-									v51 = a2;
-									v64 = (signed __int64)v47;
-									v52 = v32;
-									Actor::AI_Stand(v52, v51, v64, v69);
-									continue;
-								}
-								v71 = &pDir;
-								v63 = 0;
-								
-								Actor::_402686(v32, a2, v63, v71);
-								continue;
-							}
-							if ( v82 )
-							{
-								v69 = &pDir;
-								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v51 = a2;
-								v64 = (signed __int64)v47;
-								v52 = v32;
-								Actor::AI_Stand(v52, v51, v64, v69);
-								continue;
-							}
-							v70 = (signed __int64)v56;
-							v62 = &pDir;
-							v59 = 0;
-							Actor::_40281C(v32, a2, v59, v62, v70);
-							continue;
-						}
-						v49 = v84 == 0;
-						v69 = &pDir;
-						if ( v49 )
-						{
-							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-							v51 = a2;
-							v64 = (signed __int64)v47;
-							v52 = v32;
-							Actor::AI_Stand(v52, v51, v64, v69);
-							continue;
-						}
-						Actor::_403C6C(v32, a2, &pDir);
-						continue;
-					}
-					if ( v45 != 1 )
-					{
-						if ( v45 > 1 && v45 <= 3 )
-						{
-							if ( v45 == 2 )
-							v46 = v21->pMonsterInfo.uSpell1ID;
-							else
-							v46 = v21->pMonsterInfo.uSpell2ID;
-							if ( v46 )
-							{
-								if ( v84 )
-								{
-									if ( v45 == 2 )
-									Actor::_403854(v32, a2, &pDir);
-									else
-									Actor::_403A60(v32, a2, &pDir);
-									continue;
-								}
-								if ( v80 * 307.2 > (double)v81 || v82 )
-								{
-									v69 = &pDir;
-									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-									v51 = a2;
-									v64 = (signed __int64)v47;
-									v52 = v32;
-									Actor::AI_Stand(v52, v51, v64, v69);
-									continue;
-									
-								}
-								v69 = &pDir;
-								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
-								continue;
-							}
-							v48 = v80 * 307.2;
-							if ( (double)v81 >= v48 )
-							{
-								if ( v81 >= 1024 )
-								{
-									v50 = v82 == 0;
-									if ( !v50 )
-									{
-										v69 = &pDir;
-										v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-										v51 = a2;
-										v64 = (signed __int64)v47;
-										v52 = v32;
-										Actor::AI_Stand(v52, v51, v64, v69);
-										continue;
-									}
-									v71 = &pDir;
-									v63 = 256;
-									Actor::_402686(v32, a2, v63, v71);
-									continue;
-									
-								}
-								if ( v82 )
-								{
-									v69 = &pDir;
-									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-									v51 = a2;
-									v64 = (signed __int64)v47;
-									v52 = v32;
-									Actor::AI_Stand(v52, v51, v64, v69);
-									continue;
-								}
-								v70 = (signed __int64)v48;
-								v62 = &pDir;
-								v59 = 0;
-								Actor::_40281C(v32, a2, v59, v62, v70);
-								continue;
-							}
-							v49 = v84 == 0;
-							v69 = &pDir;
-							if ( v49 )
-							{
-								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-								v51 = a2;
-								v64 = (signed __int64)v47;
-								v52 = v32;
-								Actor::AI_Stand(v52, v51, v64, v69);
-								continue;
-							}
-							Actor::_403C6C(v32, a2, &pDir);
-							continue;
-						}
-					}
-				}
-			}
-			if ( v21->pMonsterInfo.uHostilityType != 4 || !a2 || v81 >= 5120 || v45 != 1 )
-			{
-				if ( !v21->pMonsterInfo.uMovementType )
-				{
-					v68 = 0;
-					v61 = 1024;
-					v41 = v32;
-					v40 = 4;
-					Actor::_4032B2(v41, v40, v61, v68);
-					continue;
-					
-				}
-				if ( v21->pMonsterInfo.uMovementType == 1 )
-				{
-					v68 = 0;
-					v61 = 2560;
-					v41 = v32;
-					v40 = 4;
-					Actor::_4032B2(v41, v40, v61, v68);
-					continue;
-				}
-				if ( v21->pMonsterInfo.uMovementType == 2 )
-				{
-					v68 = 0;
-					v61 = 5120;
-					v41 = v32;
-					v40 = 4;
-					Actor::_4032B2(v41, v40, v61, v68);
-					continue;
-				}
-				if ( v21->pMonsterInfo.uMovementType == 4 )
-				{
-					v68 = 0;
-					v61 = 10240;
-					v41 = v32;
-					v40 = 4;
-					Actor::_4032B2(v41, v40, v61, v68);
-					continue;
-				}
-				if ( v21->pMonsterInfo.uMovementType == 5 )
-				{
-					v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
-					v58 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-					memcpy(&v74, v57, sizeof(v74));
-					memcpy(&pDir, &v74, sizeof(pDir));
-					v69 = &pDir;
-					v52 = actor_id;
-					v64 = (signed __int64)v58;
-					v51 = 4;
-					Actor::AI_Stand(v52, v51, v64, v69);
-					continue;
-				}
-				continue;
-				
-			}
-			if ( !v21->pMonsterInfo.uMissleAttack2Type )
-			{
-				v56 = v80 * 307.2;
-				if ( (double)v81 >= v56 )
-				{
-					if ( v81 >= 1024 )
-					{
-						v50 = v82 == 0;
-						if ( !v50 )
-						{
-							v69 = &pDir;
-							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-							v51 = a2;
-							v64 = (signed __int64)v47;
-							v52 = v32;
-							Actor::AI_Stand(v52, v51, v64, v69);
-							continue;
-						}
-						v71 = &pDir;
-						v63 = 256;
-						Actor::_402686(v32, a2, v63, v71);
-						continue;
-					}
-					if ( v82 )
-					{
-						v69 = &pDir;
-						v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-						v51 = a2;
-						v64 = (signed __int64)v47;
-						v52 = v32;
-						Actor::AI_Stand(v52, v51, v64, v69);
-						continue;
-					}
-					v70 = (signed __int64)v56;
-					v62 = &pDir;
-					v59 = 0;
-					Actor::_40281C(v32, a2, v59, v62, v70);
-					continue;
-					
-				}
-				v49 = v84 == 0;
-				v69 = &pDir;
-				if ( v49 )
-				{
-					v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-					v51 = a2;
-					v64 = (signed __int64)v47;
-					v52 = v32;
-					Actor::AI_Stand(v52, v51, v64, v69);
-					continue;
-				}
-				Actor::_403C6C(v32, a2, &pDir);
-				continue;
-			}
-			if ( !v84 )
-			{
-				if ( v82 )
-				{
-					v69 = &pDir;
-					v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-					v51 = a2;
-					v64 = (signed __int64)v47;
-					v52 = v32;
-					Actor::AI_Stand(v52, v51, v64, v69);
-					continue;
-				}
-				v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
-				//UNDEF(v53);
-				v69 = &pDir;
-				if ( !(v54 | v55) )
-				{
-					v51 = a2;
-					v64 = (signed __int64)v47;
-					v52 = v32;
-					Actor::AI_Stand(v52, v51, v64, v69);
-					continue;
-				}
-				Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
-				continue;
-			}
-			Actor::_40368B(v32, a2, &pDir);
-		}
-	}
+void __cdecl UpdateActorAI()
+{
+	//unsigned int v0; // esi@4
+	int v1; // eax@7
+	int v2; // ecx@7
+	int v3; // eax@7
+	signed int v4; // edi@10
+	Actor *v5; // esi@12
+	signed int v6; // eax@14
+	__int16 v7; // cx@14
+	Player **v8; // esi@20
+	Player *pPlayer; // ecx@21
+	//Actor *pActor; // esi@34
+	//__int16 v11; // ax@34
+	//unsigned int v12; // eax@47
+	//signed int v13; // edi@47
+	//SpellBuff *v14; // ebx@47
+	//unsigned int v15; // edi@67
+	//char *v16; // eax@67
+	//unsigned int v17; // edx@67
+	//unsigned int v18; // ecx@67
+	//unsigned __int16 v19; // ax@72
+	//int *v20; // esi@80
+	Actor *v21; // ebx@80
+	unsigned __int16 v22; // ax@86
+	//signed int v23; // eax@94
+	//unsigned int v24; // eax@102
+	signed int v25; // edi@102
+	SpellBuff *v26; // esi@102
+	unsigned int v27; // ecx@123
+	unsigned int v28; // eax@123
+	unsigned int v29; // eax@127
+	AIDirection *v30; // eax@129
+	unsigned __int16 v31; // ax@132
+	unsigned int v32; // esi@142
+	int v33; // eax@144
+	int v34; // eax@147
+	char v35; // al@150
+	unsigned int v36; // edi@152
+	signed int v37; // eax@154
+	unsigned __int8 v38; // sf@158
+	unsigned __int8 v39; // of@158
+	signed int v40; // edx@166
+	unsigned int v41; // ecx@166
+	double v42; // st7@176
+	double v43; // st6@176
+	bool v44; // eax@189
+	bool v45; // eax@192
+	unsigned __int8 v46; // cl@197
+	double v47; // st7@206
+	double v48; // st7@207
+	char v49; // zf@208
+	char v50; // zf@214
+	signed int v51; // edx@219
+	unsigned int v52; // ecx@219
+	__int16 v53; // fps@224
+	unsigned __int8 v54; // c0@224
+	unsigned __int8 v55; // c3@224
+	double v56; // st7@226
+	AIDirection *v57; // eax@246
+	double v58; // st7@246
+	signed int v59; // [sp-18h] [bp-C8h]@213
+	int v60; // [sp-14h] [bp-C4h]@144
+	int v61; // [sp-14h] [bp-C4h]@168
+	AIDirection *v62; // [sp-14h] [bp-C4h]@213
+	signed int v63; // [sp-14h] [bp-C4h]@216
+	unsigned int v64; // [sp-14h] [bp-C4h]@219
+	unsigned int v65; // [sp-10h] [bp-C0h]@144
+	char v66; // [sp-10h] [bp-C0h]@147
+	AIDirection *v67; // [sp-10h] [bp-C0h]@167
+	int v68; // [sp-10h] [bp-C0h]@168
+	AIDirection *v69; // [sp-10h] [bp-C0h]@206
+	int v70; // [sp-10h] [bp-C0h]@213
+	AIDirection *v71; // [sp-10h] [bp-C0h]@216
+	AIDirection v72; // [sp+0h] [bp-B0h]@246
+	AIDirection a3; // [sp+1Ch] [bp-94h]@129
+	AIDirection v74; // [sp+38h] [bp-78h]@246
+	AIDirection v75; // [sp+54h] [bp-5Ch]@129
+	int v76; // [sp+70h] [bp-40h]@83
+	signed int a1; // [sp+74h] [bp-3Ch]@129
+	int v78; // [sp+78h] [bp-38h]@79
+	AIDirection pDir; // [sp+7Ch] [bp-34h]@129
+	float v80; // [sp+98h] [bp-18h]@33
+	int v81; // [sp+9Ch] [bp-14h]@100
+	int v82; // [sp+A0h] [bp-10h]@45
+	//unsigned int uActorID; // [sp+A4h] [bp-Ch]@32
+	unsigned int v84; // [sp+A8h] [bp-8h]@11
+	signed int a2; // [sp+ACh] [bp-4h]@83
+	
+	if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor)
+	MakeActorAIList_ODM();
+	else
+	MakeActorAIList_BLV();
+	
+	//v0 = 0;
+	if ( uCurrentlyLoadedLevelType != LEVEL_Indoor && pParty->armageddon_timer > 0 )
+	{
+		if ( pParty->armageddon_timer > 417 )
+		{
+			pParty->armageddon_timer = 0;
+		}
+		else
+		{
+			pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (pParty->sRotationY + rand() % 16 - 8);
+			v1 = rand();
+			v2 = 128;
+			v3 = pParty->sRotationX + v1 % 16 - 8;
+			pParty->sRotationX = v3;
+			if ( v3 > 128 || (v2 = -128, v3 < -128) )
+			pParty->sRotationX = v2;
+			pParty->uFlags |= 2u;
+			pParty->armageddon_timer -= pMiscTimer->uTimeElapsed;
+			v4 = pParty->field_16140 + 50;
+			if ( pParty->armageddon_timer <= 0 )
+			{
+				pParty->armageddon_timer = 0;
+				v84 = 0;
+				if ( (signed int)uNumActors > 0 )
+				{
+					v5 = pActors;//[0].sCurrentHP;
+					do
+					{
+						if ( v5->CanAct() )
+						{
+							v6 = stru_50C198.CalcMagicalDamageToActor(v5, 5, v4);
+							v7 = v5->sCurrentHP - v6;
+							v5->sCurrentHP = v7;
+							if ( v6 )
+							{
+								if ( v7 >= 0 )
+								{
+									Actor::_4030AD(v84, 4, 0);
+								}
+								else
+								{
+									Actor::Die(v84);
+									if ( v5->pMonsterInfo.uExp )
+									GivePartyExp(pMonsterStats->pInfos[v5->pMonsterInfo.uID].uExp);
+								}
+							}
+						}
+						++v84;
+						++v5;
+					}
+					while ( (signed int)v84 < (signed int)uNumActors );
+				}
+				v8 = &pPlayers[1];
+				do
+				{
+					pPlayer = *v8;
+					if ( !(*v8)->pConditions[14] && !pPlayer->pConditions[15] && !pPlayer->pConditions[16] )
+					pPlayer->ReceiveDamage(v4, 5);
+					++v8;
+				}
+				while ( (signed int)v8 <= (signed int)&pPlayers[4] );
+				//v0 = 0;
+			}
+			if (pTurnEngine->field_1C)
+			--pTurnEngine->field_1C;
+		}
+	}
+	
+	if (pParty->bTurnBasedModeOn)
+	{
+		pTurnEngine->_405E14();
+		return;
+	}
+	
+	
+	//uActorID = v0;
+	for (uint i = 0; i < uNumActors; ++i)
+	{
+		auto actor = pActors + i;
+		//LODWORD(v80) = (int)(char *)pActors + 176; // uAIState
+		//do
+		//{
+			//pActor = (Actor *)(LODWORD(v80) - 176);
+			//v11 = *(unsigned int *)LODWORD(v80);
+			//v49 = *(unsigned int *)LODWORD(v80) == 5;
+			ai_near_actors_targets_pid[i] = OBJECT_Player;
+			if (actor->uAIState == Dead || actor->uAIState == Removed || actor->uAIState == Disabled || actor->uAttributes & 0x0400)
+			continue;
+			
+			if (!actor->sCurrentHP && actor->uAIState != Dying)
+			Actor::Die(i);
+			
+			//v84 = *(_QWORD *)(LODWORD(v80) + 84) <= 0i64 ? 0 : 1;
+			//v82 = *(_QWORD *)(LODWORD(v80) + 52) <= 0i64 ? 0 : 1;
+			//v12 = 0;
+			//v13 = 0;
+			//v14 = (SpellBuff *)(LODWORD(v80) + 36);
+			for (uint j = 0; j < 22; ++j)
+			{
+				if (j != 10)
+				actor->pActorBuffs[j]._4585CA(pParty->uTimePlayed);
+			}
+			/*do
+			{
+				if ( v13 != 10 )
+				{
+					v14->_4585CA(pParty->uTimePlayed);
+					v12 = 0;
+				}
+				++v13;
+				++v14;
+			}
+			while ( v13 < 22 );*/
+			if (!actor->pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime)
+			//&& SHIDWORD(pActor->pActorBuffs[3].uExpireTime) <= (signed int)v12 && (SHIDWORD(pActor->pActorBuffs[3].uExpireTime) < (signed int)v12
+			// || LODWORD(pActor->pActorBuffs[3].uExpireTime) <= v12) )
+			actor->uActorHeight = pMonsterList->pMonsters[actor->pMonsterInfo.uID - 1].uMonsterHeight;
+			if (actor->pActorBuffs[ACTOR_BUFF_CHARM].uExpireTime)
+			actor->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			else
+			actor->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[actor->pMonsterInfo.uID].uHostilityType;
+			
+			if (actor->pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime ||
+			actor->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime)
+			continue;
+			
+			//v15 = pMiscTimer->uTimeElapsed;
+			//v16 = (char *)&pActor->pMonsterInfo.uRecoveryTime;
+			//v17 = pActor->uCurrentActionTime;
+			//v18 = pActor->pMonsterInfo.uRecoveryTime;
+			if (actor->pMonsterInfo.uRecoveryTime)
+			{
+				if (actor->pMonsterInfo.uRecoveryTime < pMiscTimer->uTimeElapsed)
+				actor->pMonsterInfo.uRecoveryTime = 0;
+				else actor->pMonsterInfo.uRecoveryTime -= pMiscTimer->uTimeElapsed;
+			}
+			
+			actor->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+			if (actor->uCurrentActionTime < actor->uCurrentActionLength)
+			continue;
+			
+			//v19 = actor->uAIState;
+			if (actor->uAIState == Dying)
+			actor->uAIState = Dead;
+			else
+			{
+				if (actor->uAIState != Summoned)
+				{
+					Actor::AI_StandOrBored(i, OBJECT_Player, 256, nullptr);
+					continue;
+				}
+				actor->uAIState = Standing;
+			}
+			
+			actor->uCurrentActionTime = 0;
+			actor->uCurrentActionLength = 0;
+			actor->UpdateAnimation();
+			//LABEL_78:
+			//++uActorID;
+			//LODWORD(v80) += 836;
+		//}
+		//while ( (signed int)uActorID < (signed int)uNumActors );
+	}
+	
+	
+	v78 = 0;
+	int actor_id = -1;
+	if ( ai_arrays_size > 0 )
+	{
+		//while ( 1 )
+		for(v78 = 0; v78 < ai_arrays_size; ++v78)
+		{
+			actor_id = ai_near_actors_ids[v78];
+			assert(actor_id < uNumActors);
+			
+			//v20 = &ai_near_actors_targets_pid[actor_id];
+			v21 = &pActors[actor_id];
+			Actor::_SelectTarget(actor_id, &ai_near_actors_targets_pid[actor_id], true);
+			if (v21->pMonsterInfo.uHostilityType && !ai_near_actors_targets_pid[actor_id])
+			v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+			a2 = ai_near_actors_targets_pid[actor_id];
+			v76 = a2 & 7;
+			if ( (a2 & 7) == OBJECT_Actor)
+			v80 = 0.5;
+			else
+			v80 = 1.0;
+			v22 = v21->uAIState;
+			if ( v22 == Dying || v22 == Dead || v22 == Removed || v22 == Disabled || v22 == Summoned)
+			{
+				continue;
+			}
+			else
+			{
+				if ( !v21->sCurrentHP )
+				Actor::Die(actor_id);
+				v25 = 0;
+				v26 = v21->pActorBuffs;
+				do
+				{
+					if ( v25 != 10 )
+					{
+						v26->_4585CA(pParty->uTimePlayed);
+						//v24 = 0;
+					}
+					++v25;
+					++v26;
+				}
+				while ( v25 < 22 );
+				if ( (signed __int64)v21->pActorBuffs[3].uExpireTime > 0
+				&& SHIDWORD(v21->pActorBuffs[3].uExpireTime) <= 0
+				&& (SHIDWORD(v21->pActorBuffs[3].uExpireTime) < 0
+				|| LODWORD(v21->pActorBuffs[3].uExpireTime) <= 0) )
+				v21->uActorHeight = pMonsterList->pMonsters[v21->pMonsterInfo.uID - 1].uMonsterHeight;
+				if ( (signed __int64)v21->pActorBuffs[1].uExpireTime > 0 )
+				{
+					v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly;
+					if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) <= 0 )
+					{
+						if ( SHIDWORD(v21->pActorBuffs[1].uExpireTime) < 0
+						|| LODWORD(v21->pActorBuffs[1].uExpireTime) <= 0 )
+						v21->pMonsterInfo.uHostilityType = pMonsterStats->pInfos[v21->pMonsterInfo.uID].uHostilityType;
+					}
+				}
+				if ( (signed __int64)v21->pActorBuffs[2].uExpireTime > 0
+				&& SHIDWORD(v21->pActorBuffs[2].uExpireTime) <= 0
+				&& (SHIDWORD(v21->pActorBuffs[2].uExpireTime) < 0
+				|| LODWORD(v21->pActorBuffs[2].uExpireTime) <= 0) )
+				{
+					v21->uAIState = Removed;
+					continue;
+				}
+				else if ( v21->pActorBuffs[5].uExpireTime || v21->pActorBuffs[6].uExpireTime )
+				{
+					continue;
+				}
+				else
+				{
+					v27 = pMiscTimer->uTimeElapsed;
+					v28 = v21->pMonsterInfo.uRecoveryTime;
+					v21->uCurrentActionTime += pMiscTimer->uTimeElapsed;
+					if ( (signed int)v28 > 0 )
+					v21->pMonsterInfo.uRecoveryTime = v28 - v27;
+					if ( v21->pMonsterInfo.uRecoveryTime< 0 )
+					v21->pMonsterInfo.uRecoveryTime = 0;
+					v29 = v21->uAttributes;
+					if ( !(v29 & 0x8000) )
+					v21->uAttributes = v29 | 0x8000;
+					a1 = 8 * actor_id | OBJECT_Actor;
+					v30 = Actor::GetDirectionInfo(8 * actor_id | OBJECT_Actor, a2, &a3, 0);
+					v49 = v21->pMonsterInfo.uHostilityType == 0;
+					memcpy(&v75, v30, sizeof(v75));
+					memcpy(&pDir, &v75, sizeof(pDir));
+					if ( !v49
+					&& (signed int)v21->pMonsterInfo.uRecoveryTime <= 0
+					&& v80 * 307.2 >= (double)(signed int)v75.uDistance
+					&& ((v31 = v21->uAIState, v31 == 6) || !v31 || v31 == 1 || v31 == 9)
+					|| v21->pMonsterInfo.uMissleAttack1Type && v21->uAIState == 8 )
+					{
+						v32 = actor_id;
+					}
+					else
+					{
+						if ( (signed int)v21->uCurrentActionTime < v21->uCurrentActionLength )
+						{
+							continue;
+						}
+						else if ( v21->uAIState == 2 )
+						{
+							v32 = actor_id;
+							v35 = stru_50C198.special_ability_use_check(v21, actor_id);
+							stru_50FE08.Add(
+							a1,
+							5120,
+							v21->vPosition.x,
+							v21->vPosition.y,
+							v21->vPosition.z + ((signed int)v21->uActorHeight >> 1),
+							v35,
+							1
+							);
+						}
+						else if ( v21->uAIState == 3 )
+						{
+							v34 = v21->pMonsterInfo.uMissleAttack1Type;
+							v66 = 0;
+							v32 = actor_id;
+							Actor::_404874(actor_id, &pDir, v34, v66);
+						}
+						else if ( v21->uAIState == 12 )
+						{
+							v34 = v21->pMonsterInfo.uMissleAttack2Type;
+							v66 = 1;
+							v32 = actor_id;
+							Actor::_404874(actor_id, &pDir, v34, v66);
+						}
+						else
+						{
+							v32 = actor_id;
+							if ( v21->uAIState == 13 )
+							{
+								v65 = v21->pMonsterInfo.uSpellSkillAndMastery1;
+								v60 = 2;
+								v33 = v21->pMonsterInfo.uSpell1ID;
+								Actor::_404AC7(actor_id, &pDir, v33, v60, v65);
+							}
+							else if ( v21->uAIState == 18 )
+							{
+								v65 = v21->pMonsterInfo.uSpellSkillAndMastery2;
+								v60 = 3;
+								v33 = v21->pMonsterInfo.uSpell2ID;
+								Actor::_404AC7(actor_id, &pDir, v33, v60, v65);
+							}
+						}
+					}
+				}
+			}
+			v36 = v75.uDistance;
+			if ( !v21->pMonsterInfo.uHostilityType )
+			{
+				if ( v76 == 3 )
+				{
+					v36 = v75.uDistance;
+					v37 = (unsigned __int8)*(&byte_5C8D1A[89 * (v21->pMonsterInfo.uID - 1) / 3]
+					+ (pActors[a2 >> 3].pMonsterInfo.uID - 1) / 3);
+				}
+				else
+				{
+					v37 = 4;
+				}
+				if ( v37 == 2 )
+				{
+					v39 = __OFSUB__(v36, 1024);
+					v38 = ((v36 - 1024) & 0x80000000u) != 0;
+				}
+				else if ( v37 == 3 )
+				{
+					v39 = __OFSUB__(v36, 2560);
+					v38 = ((v36 - 2560) & 0x80000000u) != 0;
+				}
+				else if ( v37 == 4 )
+				{
+					v39 = __OFSUB__(v36, 5120);
+					v38 = ((v36 - 5120) & 0x80000000u) != 0;
+				}
+				if ( v37 >= 1 && v37 <= 4 && v38 ^ v39 || v37 == 1 )
+				v21->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long;
+			}
+			if ( (signed __int64)v21->pActorBuffs[4].uExpireTime > 0 )
+			{
+				v40 = a2;
+				v41 = v32;
+				if ( (signed int)v36 >= 10240 )
+				{
+					v68 = 0;
+					v61 = 1024;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				v67 = &pDir;
+				Actor::_402968(v41, v40, 0, v67);
+				continue;
+			}
+			if ( v21->pMonsterInfo.uHostilityType == 4 && a2 )
+			{
+				if ( !(v21->uAttributes & 0x020000) || v21->pMonsterInfo.uAIType == 1 )
+				{
+					if ( v21->pMonsterInfo.uAIType == 1 )
+					{
+						v67 = &pDir;
+						if ( v21->pMonsterInfo.uMovementType != 5 )
+						{
+							v40 = a2;
+							v41 = v32;
+							Actor::_402968(v41, v40, 0, v67);
+							continue;
+						}
+						Actor::AI_Stand(
+						v32,
+						a2,
+						(signed __int64)((double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333),
+						&pDir);
+					}
+					else
+					{
+						if ( v21->pMonsterInfo.uAIType == 2 )
+						{
+							v84 = v21->sCurrentHP;
+							v42 = (double)(signed int)v84;
+							v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.2;
+						}
+						else
+						{
+							v84 = v21->sCurrentHP;
+							v42 = (double)(signed int)v84;
+							v43 = (double)(signed int)v21->pMonsterInfo.uHP * 0.1;
+						}
+						if ( v21->pMonsterInfo.uAIType == 2 || v21->pMonsterInfo.uAIType == 3 )
+						if ( v43 > v42 && (signed int)v36 < 10240 )
+						{
+							v67 = &pDir;
+							v40 = a2;
+							v41 = v32;
+							Actor::_402968(v41, v40, 0, v67);
+							continue;
+						}
+					}
+				}
+				v81 = v36 - v21->uActorRadius;
+				if ( v76 == 3 )
+				v81 -= pActors[a2 >> 3].uActorRadius;
+				if ( v81 < 0 )
+				v81 = 0;
+				rand();
+				v44 = (signed int)v21->pMonsterInfo.uRecoveryTime <= 0;
+				v21->uAttributes &= 0xFBFFFF;
+				v82 = 0;
+				v49 = v21->pMonsterInfo.uMovementType == 5;
+				v84 = v44;
+				if ( v49 )
+				v82 = 1;
+				if ( v81 < 5120 )
+				{
+					v45 = stru_50C198.special_ability_use_check(v21, v32);
+					if ( !v45 )
+					{
+						if ( v21->pMonsterInfo.uMissleAttack1Type )
+						{
+							if ( v84 )
+							{
+								Actor::_403476(v32, a2, &pDir);
+								continue;
+								
+							}
+							if ( v82 )
+							{
+								v69 = &pDir;
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							//UNDEF(v53);
+							v69 = &pDir;
+							if ( !(v54 | v55) )
+							{
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
+							continue;
+						}
+						v56 = v80 * 307.2;
+						if ( (double)v81 >= v56 )
+						{
+							if ( v81 >= 1024 )
+							{
+								if ( v82 )
+								{
+									v69 = &pDir;
+									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v51 = a2;
+									v64 = (signed __int64)v47;
+									v52 = v32;
+									Actor::AI_Stand(v52, v51, v64, v69);
+									continue;
+								}
+								v71 = &pDir;
+								v63 = 0;
+								
+								Actor::_402686(v32, a2, v63, v71);
+								continue;
+							}
+							if ( v82 )
+							{
+								v69 = &pDir;
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							v70 = (signed __int64)v56;
+							v62 = &pDir;
+							v59 = 0;
+							Actor::_40281C(v32, a2, v59, v62, v70);
+							continue;
+						}
+						v49 = v84 == 0;
+						v69 = &pDir;
+						if ( v49 )
+						{
+							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							v51 = a2;
+							v64 = (signed __int64)v47;
+							v52 = v32;
+							Actor::AI_Stand(v52, v51, v64, v69);
+							continue;
+						}
+						Actor::_403C6C(v32, a2, &pDir);
+						continue;
+					}
+					if ( v45 != 1 )
+					{
+						if ( v45 > 1 && v45 <= 3 )
+						{
+							if ( v45 == 2 )
+							v46 = v21->pMonsterInfo.uSpell1ID;
+							else
+							v46 = v21->pMonsterInfo.uSpell2ID;
+							if ( v46 )
+							{
+								if ( v84 )
+								{
+									if ( v45 == 2 )
+									Actor::_403854(v32, a2, &pDir);
+									else
+									Actor::_403A60(v32, a2, &pDir);
+									continue;
+								}
+								if ( v80 * 307.2 > (double)v81 || v82 )
+								{
+									v69 = &pDir;
+									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v51 = a2;
+									v64 = (signed __int64)v47;
+									v52 = v32;
+									Actor::AI_Stand(v52, v51, v64, v69);
+									continue;
+									
+								}
+								v69 = &pDir;
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
+								continue;
+							}
+							v48 = v80 * 307.2;
+							if ( (double)v81 >= v48 )
+							{
+								if ( v81 >= 1024 )
+								{
+									v50 = v82 == 0;
+									if ( !v50 )
+									{
+										v69 = &pDir;
+										v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+										v51 = a2;
+										v64 = (signed __int64)v47;
+										v52 = v32;
+										Actor::AI_Stand(v52, v51, v64, v69);
+										continue;
+									}
+									v71 = &pDir;
+									v63 = 256;
+									Actor::_402686(v32, a2, v63, v71);
+									continue;
+									
+								}
+								if ( v82 )
+								{
+									v69 = &pDir;
+									v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+									v51 = a2;
+									v64 = (signed __int64)v47;
+									v52 = v32;
+									Actor::AI_Stand(v52, v51, v64, v69);
+									continue;
+								}
+								v70 = (signed __int64)v48;
+								v62 = &pDir;
+								v59 = 0;
+								Actor::_40281C(v32, a2, v59, v62, v70);
+								continue;
+							}
+							v49 = v84 == 0;
+							v69 = &pDir;
+							if ( v49 )
+							{
+								v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+								v51 = a2;
+								v64 = (signed __int64)v47;
+								v52 = v32;
+								Actor::AI_Stand(v52, v51, v64, v69);
+								continue;
+							}
+							Actor::_403C6C(v32, a2, &pDir);
+							continue;
+						}
+					}
+				}
+			}
+			if ( v21->pMonsterInfo.uHostilityType != 4 || !a2 || v81 >= 5120 || v45 != 1 )
+			{
+				if ( !v21->pMonsterInfo.uMovementType )
+				{
+					v68 = 0;
+					v61 = 1024;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+					
+				}
+				if ( v21->pMonsterInfo.uMovementType == 1 )
+				{
+					v68 = 0;
+					v61 = 2560;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				if ( v21->pMonsterInfo.uMovementType == 2 )
+				{
+					v68 = 0;
+					v61 = 5120;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				if ( v21->pMonsterInfo.uMovementType == 4 )
+				{
+					v68 = 0;
+					v61 = 10240;
+					v41 = v32;
+					v40 = 4;
+					Actor::_4032B2(v41, v40, v61, v68);
+					continue;
+				}
+				if ( v21->pMonsterInfo.uMovementType == 5 )
+				{
+					v57 = Actor::GetDirectionInfo(a1, 4u, &v72, 0);
+					v58 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					memcpy(&v74, v57, sizeof(v74));
+					memcpy(&pDir, &v74, sizeof(pDir));
+					v69 = &pDir;
+					v52 = actor_id;
+					v64 = (signed __int64)v58;
+					v51 = 4;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				continue;
+				
+			}
+			if ( !v21->pMonsterInfo.uMissleAttack2Type )
+			{
+				v56 = v80 * 307.2;
+				if ( (double)v81 >= v56 )
+				{
+					if ( v81 >= 1024 )
+					{
+						v50 = v82 == 0;
+						if ( !v50 )
+						{
+							v69 = &pDir;
+							v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+							v51 = a2;
+							v64 = (signed __int64)v47;
+							v52 = v32;
+							Actor::AI_Stand(v52, v51, v64, v69);
+							continue;
+						}
+						v71 = &pDir;
+						v63 = 256;
+						Actor::_402686(v32, a2, v63, v71);
+						continue;
+					}
+					if ( v82 )
+					{
+						v69 = &pDir;
+						v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+						v51 = a2;
+						v64 = (signed __int64)v47;
+						v52 = v32;
+						Actor::AI_Stand(v52, v51, v64, v69);
+						continue;
+					}
+					v70 = (signed __int64)v56;
+					v62 = &pDir;
+					v59 = 0;
+					Actor::_40281C(v32, a2, v59, v62, v70);
+					continue;
+					
+				}
+				v49 = v84 == 0;
+				v69 = &pDir;
+				if ( v49 )
+				{
+					v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					v51 = a2;
+					v64 = (signed __int64)v47;
+					v52 = v32;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				Actor::_403C6C(v32, a2, &pDir);
+				continue;
+			}
+			if ( !v84 )
+			{
+				if ( v82 )
+				{
+					v69 = &pDir;
+					v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+					v51 = a2;
+					v64 = (signed __int64)v47;
+					v52 = v32;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				v47 = (double)(signed int)v21->pMonsterInfo.uRecoveryTime * 2.133333333333333;
+				//UNDEF(v53);
+				v69 = &pDir;
+				if ( !(v54 | v55) )
+				{
+					v51 = a2;
+					v64 = (signed __int64)v47;
+					v52 = v32;
+					Actor::AI_Stand(v52, v51, v64, v69);
+					continue;
+				}
+				Actor::_402AD7(v32, a2, v32, (signed __int64)v47, v69);
+				continue;
+			}
+			Actor::_40368B(v32, a2, &pDir);
+		}
+	}
 }
 
 //----- (0040261D) --------------------------------------------------------
--- a/mm7_5.cpp	Tue Mar 26 15:21:03 2013 +0000
+++ b/mm7_5.cpp	Thu Mar 28 00:37:27 2013 +0400
@@ -517,7 +517,7 @@
           if ( pGUIWindow_CurrentMenu->field_40 == v0 )
           {
             pKeyActionMap->_459ED1(0);
-            strcpy((char *)&pSavegameHeader + 100 * uLoadGameUI_SelectedSlot, (const char *)pKeyActionMap->pPressedKeysBuffer);
+            strcpy((char *)&pSavegameHeader[uLoadGameUI_SelectedSlot], (const char *)pKeyActionMap->pPressedKeysBuffer);
           }
           DoSavegame(uLoadGameUI_SelectedSlot);
           stru_506E40.Release();
@@ -2051,14 +2051,14 @@
             pNPCData2->rep = pParty->vPosition.z;
             LOWORD(pNPCData2->Location2D) = LOWORD(pParty->sRotationY);
             HIWORD(pNPCData2->Location2D) = LOWORD(pParty->sRotationX);
-            if ( (signed int)pGames_LOD->uNumSubIndices / 2 <= 0 )
+            if ( (signed int)pGames_LOD->uNumSubDirs / 2 <= 0 )
               continue;
             uAction = 0;
             while ( _strcmpi((const char *)pGames_LOD->pSubIndices + uAction, pCurrentMapName) )
             {
               ++thisg;
               uAction += 32;
-              if ( thisg >= (signed int)pGames_LOD->uNumSubIndices / 2 )
+              if ( thisg >= (signed int)pGames_LOD->uNumSubDirs / 2 )
                 continue;
             }
             HIWORD(pNPCData4->uProfession) = thisg;
@@ -2266,7 +2266,7 @@
           memcpy(&v216, txt_file_frametable_parser((const char *)pKeyActionMap->pPressedKeysBuffer, &v218), sizeof(v216));
           if ( v216.uPropCount == 1 )
           {
-            pNPCData4 = (NPCData *)((signed int)pGames_LOD->uNumSubIndices / 2);
+            pNPCData4 = (NPCData *)((signed int)pGames_LOD->uNumSubDirs / 2);
             v70 = atoi(v216.pProperties[0]);
             if ( v70 <= 0 || v70 >= 77 )
             {
--- a/mm7_data.h	Tue Mar 26 15:21:03 2013 +0000
+++ b/mm7_data.h	Thu Mar 28 00:37:27 2013 +0400
@@ -1885,7 +1885,7 @@
 void __cdecl TryLoadLevelFromLOD();
 void __cdecl sub_46080D();
 bool __cdecl Initialize_GamesLOD_NewLOD();
-void Autosave();
+void SaveNewGame();
 void __thiscall PrepareToLoadBLV(unsigned int bLoading);
 void __fastcall PrepareToLoadODM(unsigned int bLoading, struct OutdoorCamera *a2);
 void __cdecl sub_461103();