changeset 291:0ea5fbd16edb

NPC mostly done
author Gloval
date Tue, 19 Feb 2013 00:34:15 +0400
parents 4776715a964b
children 5586bb4e8395
files Actor.cpp GUIWindow.cpp Game.cpp NPC.cpp NPC.h Party.cpp mm7_1.cpp mm7_2.cpp mm7_3.cpp mm7_4.cpp mm7_5.cpp mm7_data.h
diffstat 12 files changed, 488 insertions(+), 626 deletions(-) [+]
line wrap: on
line diff
--- a/Actor.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/Actor.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -200,7 +200,7 @@
   pDialogueNPCPortraits[0] = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE)];
   dword_591084 = areWeLoadingTexture;
   uTextureID_507B04 = uTextureID_right_panel;
-  if ( !v5->Hired() && v5->house >= 0 )
+  if ( !v5->Hired() && v5->Location2D >= 0 )
   {
     if ( (signed int)pParty->GetPartyFame() <= v5->fame
       || (v10 = v5->uFlags & 0xFFFFFF7F, (v5->uFlags & 0xFFFFFF7F & 0x80000000u) != 0) )
--- a/GUIWindow.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/GUIWindow.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -1843,7 +1843,7 @@
                 pWindow->CreateButton(480, 130, 140, v11, 1, 0, 0x88u, 0xDu, 0, "", 0);
                 a4a = 1;
               }
-              v13 = (void *)v12->bDrawSomeAnim;
+              v13 = (void *)v12->evt_A;
               if ( v13 )
               {
                 if ( a4a < 4 )
@@ -1853,7 +1853,7 @@
                     pWindow->CreateButton(0x1E0u, a4a++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x13u, 0, "", 0);
                 }
               }
-              v15 = (void *)v12->_anim_current_time;
+              v15 = (void *)v12->evt_B;
               if ( v15 )
               {
                 if ( a4a < 4 )
@@ -1863,7 +1863,7 @@
                     pWindow->CreateButton(0x1E0u, a4a++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x14u, 0, "", 0);
                 }
               }
-              v17 = (void *)v12->_anim_end_time;
+              v17 = (void *)v12->evt_C;
               if ( v17 )
               {
                 if ( a4a < 4 )
@@ -1873,7 +1873,7 @@
                     pWindow->CreateButton( 0x1E0u, a4a++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x15u, 0, "", 0);
                 }
               }
-              v19 = (void *)v12->evtd;
+              v19 = (void *)v12->evt_D;
               if ( v19 )
               {
                 if ( a4a < 4 )
@@ -1883,7 +1883,7 @@
                     pWindow->CreateButton(0x1E0u, a4a++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x16u, 0, "", 0);
                 }
               }
-              v21 = (void *)v12->evte;
+              v21 = (void *)v12->evt_E;
               if ( v21 )
               {
                 if ( a4a < 4 )
@@ -1893,7 +1893,7 @@
                     pWindow->CreateButton(0x1E0u, a4a++ * v11 + 130, 0x8Cu, v11, 1, 0, 0x88u, 0x17u, 0, "", 0);
                 }
               }
-              v23 = (void *)v12->evtf;
+              v23 = (void *)v12->evt_F;
               if ( v23 )
               {
                 if ( a4a < 4 )
--- a/Game.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/Game.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -154,7 +154,7 @@
   pOtherOverlayList->bRedraw = 0;
 
   GameUI_DrawPartySpells();
-  if (v4 || pParty->pHirelings[0]._anim_end_time || pParty->pHirelings[1]._anim_end_time )
+  if (v4 || pParty->pHirelings[0].evt_C || pParty->pHirelings[1].evt_C )
     DrawHiredNPCs();
   GameUI_DrawPortraits(v4);
   GameUI_DrawLifeManaBars();
--- a/NPC.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/NPC.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -18,10 +18,10 @@
 void  InitializeTransitions();
 void  InitializeAutonotes();
 void  InitializeQuests();
-
+bool   CheckPortretAgainsSex(int portret_num, int sex); 
 
 //----- (00476977) --------------------------------------------------------
-void NPCStats::Initialize2()
+void NPCStats::InitializeNPCText()
 	{
 	int i;
 	char* test_string;
@@ -136,11 +136,11 @@
 				{
 				if ((decode_step>0)&&(decode_step<77))
 					{
-					array_16544[decode_step].field_4[i]=atoi(test_string);
+					pProfessionChance[decode_step].professionChancePerArea[i]=atoi(test_string);
 					}
 				else if (decode_step==0)
 					{
-					array_16544[0].field_4[i]=10;
+					pProfessionChance[0].professionChancePerArea[i]=10;
 					}
 				}
 			else
@@ -154,10 +154,10 @@
 
 	for (i=0; i<78; ++i)
 		{
-		array_16544[i].field_0=0;
+		pProfessionChance[i].uTotalprofChance=0;
 		for (int ii=1; ii<59; ++ii)
 			{
-			array_16544[i].field_0+=array_16544[i].field_4[ii];
+			pProfessionChance[i].uTotalprofChance+=pProfessionChance[i].professionChancePerArea[ii];
 			}
 		}
 
@@ -172,7 +172,7 @@
 void NPCStats::_476C60()
 	{
 	for (unsigned int i = 1; i < uNumNewNPCs; ++i)
-		pNewNPCData[i].pName = pNPCNames2[i - 1];
+		pNewNPCData[i].pName = pNPCUnicNames[i - 1];
 
 	if (pParty->pHirelings[0].pName)
 		pParty->pHirelings[0].pName = pParty->pHireling1Name;
@@ -181,570 +181,457 @@
 	}
 
 //----- (00476CB5) --------------------------------------------------------
-void NPCStats::Initialize1()
+void NPCStats::InitializeNPCData()
 	{
-	NPCStats *pNPCStats; // esi@1
-	char *pRaw; // eax@1
-	char *pHouse; // edi@1
-	char *v4; // eax@2
-	char v5; // dl@3
-	int v6; // ecx@3
-	char *v7; // eax@11
-	char *v8; // eax@26
-	char *v9; // ecx@27
-	char v10; // dl@28
-	int v11; // eax@28
-	int v12; // edi@32
-	char *v13; // eax@42
-	char *v14; // eax@43
-	char v15; // dl@44
-	int v16; // ecx@44
-	int v17; // edi@48
-	char *v18; // eax@56
-	char *v19; // eax@57
-	char v20; // cl@58
-	int v21; // edi@58
-	int v22; // esi@62
-	int v23; // [sp+Ch] [bp-14h]@7
-	signed int v24; // [sp+10h] [bp-10h]@1
-	signed int v25; // [sp+10h] [bp-10h]@26
-	signed int v26; // [sp+10h] [bp-10h]@42
-	signed int v27; // [sp+10h] [bp-10h]@56
-	char *Str; // [sp+14h] [bp-Ch]@1
-	NPCGreeting *pGreetings; // [sp+14h] [bp-Ch]@26
-	unsigned __int16 *pGroups; // [sp+14h] [bp-Ch]@42
-	char **pCatchPhrase; // [sp+14h] [bp-Ch]@56
-	signed int v32; // [sp+18h] [bp-8h]@2
-	signed int v33; // [sp+18h] [bp-8h]@27
-	signed int v34; // [sp+18h] [bp-8h]@43
-	signed int v35; // [sp+18h] [bp-8h]@57
-	signed int v36; // [sp+1Ch] [bp-4h]@2
-	signed int v37; // [sp+1Ch] [bp-4h]@27
-	signed int v38; // [sp+1Ch] [bp-4h]@43
-	signed int v39; // [sp+1Ch] [bp-4h]@57
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+
+	pNPCDataTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcdata.txt", 0);
+	strtok(pNPCDataTXT_Raw, "\r");
+	strtok(NULL, "\r");
 
-	pNPCStats = this;
-	pRaw = (char *)pEvents_LOD->LoadRaw("npcdata.txt", 0);
-	pNPCStats->pNPCDataTXT_Raw = pRaw;
-	strtok(pRaw, "\r");
-	strtok(0, "\r");
-	pHouse = (char *)&pNPCStats->pNPCData[1].house;
-	Str = (char *)pNPCStats->pNPCNames2;
-	v24 = 500;
-	do
+	for (i=0; i<500; ++i)
 		{
-		v32 = 0;
-		v4 = strtok(0, "\r") + 1;
-		v36 = -1;
-		do
+		test_string = strtok(NULL, "\r") + 1;
+		break_loop = false;
+		decode_step=0;
+		do 
 			{
-			v5 = *v4;
-			v6 = 0;
-			while ( v5 != 9 && v5 )
+			c = *(unsigned char*)test_string;
+			temp_str_len = 0;
+			while((c!='\t')&&(c>0))
 				{
-				++v6;
-				v5 = v4[v6];
-				}
-			v23 = (int)&v4[v6];
-			if ( !v4[v6] )
-				v32 = 1;
-			v4[v6] = 0;
-			if ( v6 )
-				{
-				switch ( v36 )
+				++temp_str_len;
+				c=test_string[temp_str_len];
+				}		
+			tmp_pos=test_string+temp_str_len;
+			if (*tmp_pos == 0)
+				break_loop = true;
+			*tmp_pos = 0;
+			if (temp_str_len)
+				{  //i+1
+				switch (decode_step)
 					{
-				case 0:
-					v7 = RemoveQuotes(v4);
-					*((int *)pHouse - 5) = (int)v7;
-					*(int *)Str = (int)v7;
+				case 1:
+					pNPCUnicNames[i] = RemoveQuotes(test_string);
+					pNPCData[i+1].pName=pNPCUnicNames[i];
 					break;
-				case 1:
-					*((int *)pHouse - 4) = atoi(v4);
-					break;
-				case 5:
-					*(int *)pHouse = atoi(v4);
+				case 2:
+					pNPCData[i+1].uPortraitID = atoi(test_string);
 					break;
 				case 6:
-					*((int *)pHouse + 1) = atoi(v4);
+					pNPCData[i+1].Location2D = atoi(test_string);
 					break;
 				case 7:
-					*((int *)pHouse + 2) = atoi(v4);
+					pNPCData[i+1].uProfession = atoi(test_string);
 					break;
 				case 8:
-					*((int *)pHouse + 3) = *v4 == 121;
+					pNPCData[i+1].greet = atoi(test_string);
 					break;
 				case 9:
-					*((int *)pHouse + 5) = atoi(v4);
+					pNPCData[i+1].joins = (*test_string == 'y')?1:0;
 					break;
 				case 10:
-					*((int *)pHouse + 6) = atoi(v4);
+					pNPCData[i+1].evt_A = atoi(test_string);
 					break;
 				case 11:
-					*((int *)pHouse + 7) = atoi(v4);
+					pNPCData[i+1].evt_B = atoi(test_string);
 					break;
 				case 12:
-					*((int *)pHouse + 8) = atoi(v4);
+					pNPCData[i+1].evt_C = atoi(test_string);
 					break;
 				case 13:
-					*((int *)pHouse + 9) = atoi(v4);
+					pNPCData[i+1].evt_D = atoi(test_string);
 					break;
 				case 14:
-					*((int *)pHouse + 10) = atoi(v4);
+					pNPCData[i+1].evt_E = atoi(test_string);
 					break;
-				default:
+				case 15:
+					pNPCData[i+1].evt_F = atoi(test_string);
 					break;
 					}
 				}
-			++v36;
-			v4 = (char *)(v23 + 1);
-			}
-			while ( v36 + 1 <= 15 && !v32 );
-			Str += 4;
-			pHouse += 76;
-			--v24;
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<16)&&!break_loop);
 		}
-		while ( v24 );
-		pNPCStats->uNumNewNPCs = 501;
-		v8 = (char *)pEvents_LOD->LoadRaw("npcgreet.txt", 0);
-		pNPCStats->pNPCGreetTXT_Raw = v8;
-		strtok(v8, "\r");
-		pGreetings = pNPCStats->pNPCGreetings;
-		v25 = 205;
-		do
+	uNumNewNPCs = 501;
+	pNPCGreetTXT_Raw = (char*)pEvents_LOD->LoadRaw("npcgreet.txt", 0);
+	strtok(pNPCGreetTXT_Raw, "\r");
+	for (i=0; i<205; ++i)
+		{
+		test_string = strtok(NULL, "\r") + 1;
+		break_loop = false;
+		decode_step=0;
+		do 
 			{
-			v37 = 0;
-			v33 = 0;
-			v9 = strtok(0, "\r") + 1;
-			do
-				{
-				v10 = *v9;
-				v11 = 0;
-				while ( v10 != 9 && v10 )
-					{
-					++v11;
-					v10 = v9[v11];
-					}
-				v12 = (int)&v9[v11];
-				if ( !v9[v11] )
-					v33 = 1;
-				*(char *)v12 = 0;
-				if ( v11 )
-					{
-					if ( v37 == 1 )
-						{
-						pGreetings->pGreeting1 = (char *)RemoveQuotes(v9);
-						}
-					else
-						{
-						if ( v37 == 2 )
-							pGreetings->pGreeting2 = (char *)RemoveQuotes(v9);
-						}
-					}
-				++v37;
-				v9 = (char *)(v12 + 1);
-				}
-				while ( v37 <= 2 && !v33 );
-				++pGreetings;
-				--v25;
-			}
-			while ( v25 );
-			v13 = (char *)pEvents_LOD->LoadRaw("npcgroup.txt", 0);
-			pNPCStats->pNCPGroupTXT_Raw = v13;
-			strtok(v13, "\r");
-			pGroups = pNPCStats->pGroups;
-			v26 = 51;
-			do
+			c = *(unsigned char*)test_string;
+			temp_str_len = 0;
+			while((c!='\t')&&(c>0))
 				{
-				v14 = strtok(0, "\r") + 1;
-				v38 = 0;
-				v34 = 0;
-				do
+				++temp_str_len;
+				c=test_string[temp_str_len];
+				}		
+			tmp_pos=test_string+temp_str_len;
+			if (*tmp_pos == 0)
+				break_loop = true;
+			*tmp_pos = 0;
+			if (temp_str_len)
+				{  //i+1
+				switch (decode_step)
 					{
-					v15 = *v14;
-					v16 = 0;
-					while ( v15 != 9 && v15 )
-						{
-						++v16;
-						v15 = v14[v16];
-						}
-					v17 = (int)&v14[v16];
-					if ( !v14[v16] )
-						v34 = 1;
-					*(char *)v17 = 0;
-					if ( v16 && v38 == 1 )
-						*pGroups = atoi(v14);
-					++v38;
-					v14 = (char *)(v17 + 1);
+				case 1:
+					pNPCGreetings[i].pGreeting1 = RemoveQuotes(test_string);
+					break;
+				case 2:
+					pNPCGreetings[i].pGreeting2 = RemoveQuotes(test_string);
+					break;
 					}
-					while ( v38 <= 1 && !v34 );
-					++pGroups;
-					--v26;
 				}
-				while ( v26 );
-				v18 = (char *)pEvents_LOD->LoadRaw("npcnews.txt", 0);
-				pNPCStats->pNPCNewsTXT_Raw = v18;
-				strtok(v18, "\r");
-				pCatchPhrase = pNPCStats->pCatchPhrases;
-				v27 = 51;
-				do
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<3)&&!break_loop);
+		}
+
+	pNCPGroupTXT_Raw = (char*)pEvents_LOD->LoadRaw("npcgroup.txt", 0);
+	strtok(pNCPGroupTXT_Raw, "\r");
+
+	for (i=0; i<51; ++i)
+		{
+		test_string = strtok(NULL, "\r") + 1;
+		break_loop = false;
+		decode_step=0;
+		do 
+			{
+			c = *(unsigned char*)test_string;
+			temp_str_len = 0;
+			while((c!='\t')&&(c>0))
+				{
+				++temp_str_len;
+				c=test_string[temp_str_len];
+				}		
+			tmp_pos=test_string+temp_str_len;
+			if (*tmp_pos == 0)
+				break_loop = true;
+			*tmp_pos = 0;
+			if (temp_str_len)
+				{  //i+1
+				if (decode_step==1)
 					{
-					v19 = strtok(0, "\r") + 1;
-					v39 = 0;
-					v35 = 0;
-					do
-						{
-						v20 = *v19;
-						v21 = 0;
-						while ( v20 != 9 && v20 )
-							{
-							++v21;
-							v20 = v19[v21];
-							}
-						v22 = (int)&v19[v21];
-						if ( !v19[v21] )
-							v35 = 1;
-						*(char *)v22 = 0;
-						if ( v21 && v39 == 1 )
-							*pCatchPhrase = (char *)RemoveQuotes(v19);
-						++v39;
-						v19 = (char *)(v22 + 1);
-						}
-						while ( v39 <= 1 && !v35 );
-						++pCatchPhrase;
-						--v27;
+					pGroups[i] = atoi(test_string);
 					}
-					while ( v27 );
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<2)&&!break_loop);
+		}
+
+	pNPCNewsTXT_Raw = (char*)pEvents_LOD->LoadRaw("npcnews.txt", 0);
+	strtok(pNPCNewsTXT_Raw, "\r");
+
+
+	for (i=0; i<51; ++i)
+		{
+		test_string = strtok(NULL, "\r") + 1;
+		break_loop = false;
+		decode_step=0;
+		do 
+			{
+			c = *(unsigned char*)test_string;
+			temp_str_len = 0;
+			while((c!='\t')&&(c>0))
+				{
+				++temp_str_len;
+				c=test_string[temp_str_len];
+				}		
+			tmp_pos=test_string+temp_str_len;
+			if (*tmp_pos == 0)
+				break_loop = true;
+			*tmp_pos = 0;
+			if (temp_str_len)
+				{  //i+1
+				if (decode_step==1)
+					pCatchPhrases[i] = RemoveQuotes(test_string);
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<2)&&!break_loop);
+		}
 	}
 
 //----- (0047702F) --------------------------------------------------------
 void NPCStats::Initialize()
-	{
-	//NPCStats *v1; // edi@1
-	char *v2; // ebx@1
-	//char *v3; // eax@1
-	char *v4; // ebx@3
-	char v5; // al@4
-	int v6; // ecx@4
-	//char *v7; // eax@18
-	char *v8; // ebx@18
-	char *v9; // ecx@19
-	char v10; // dl@20
-	int v11; // eax@20
-	char v12; // zf@41
-	signed int v13; // [sp+Ch] [bp-14h]@18
-	int v14; // [sp+10h] [bp-10h]@4
-	int v15; // [sp+10h] [bp-10h]@24
-	char *v16; // [sp+14h] [bp-Ch]@1
-	signed int v17; // [sp+14h] [bp-Ch]@19
-	unsigned int v18; // [sp+18h] [bp-8h]@1
-	char *v19; // [sp+18h] [bp-8h]@18
-	signed int v20; // [sp+1Ch] [bp-4h]@3
-	signed int v21; // [sp+1Ch] [bp-4h]@19
-	//v1 = this;
+		{
+		int i;
+		char* test_string;
+		unsigned char c;
+		bool break_loop;
+		unsigned int temp_str_len;
+		char* tmp_pos;
+		int decode_step;
 
-	Initialize1();
-	Initialize2();
+		InitializeNPCData();
+		InitializeNPCText();
+		InitializeQuests();
+		InitializeAutonotes();
+		InitializeAwards();
+		InitializeTransitions();
+		InitializeMerchants();
+		InitializeScrolls();
 
-	InitializeQuests();
-	InitializeAutonotes();
-	InitializeAwards();
-	InitializeTransitions();
-	InitializeMerchants();
-	InitializeScrolls();
-	v2 = 0;
-	field_17FC0 = 0;
-	pNPCNamesTXT_Raw = 0;
-	//v3 = (char *)pEvents_LOD->LoadRaw("npcnames.txt", 0);
-	pNPCNamesTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcnames.txt", 0);
-	strtok(pNPCNamesTXT_Raw, "\r");
-	v18 = 0;
-	v16 = (char *)pNPCNames;
-	while ( 1 )
-		{
-		v4 = strtok(v2, "\r") + 1;
-		v20 = 0;
-		do
+		pNPCNamesTXT_Raw = NULL;
+		pNPCNamesTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcnames.txt", 0);
+		strtok(pNPCNamesTXT_Raw, "\r");
+
+		uNewlNPCBufPos = 0;
+
+		for (i=0; i<540; ++i)
 			{
-			v5 = *v4;
-			v6 = 0;
-			v14 = 0;
-			if ( *v4 == 9 )
-				goto LABEL_45;
-			do
+			test_string = strtok(NULL, "\r") + 1;
+			break_loop = false;
+			decode_step=0;
+			do 
 				{
-				if ( !v5 )
-					break;
-				if ( v5 == 10 )
-					break;
-				++v6;
-				v14 = v6;
-				v5 = v4[v6];
-				}
-				while ( v5 != 9 );
-				if ( v6 )
+				c = *(unsigned char*)test_string;
+				temp_str_len = 0;
+				if (c=='\t')
 					{
-					v4[v6] = 0;
-					if ( v20 )
-						{
-						if ( v20 == 1 )
-							*((int *)v16 + 1) = (int)RemoveQuotes(v4);
-						}
-					else
-						{
-						*(int *)v16 = (int)RemoveQuotes(v4);
-						}
+					if ( (decode_step == 1)&&(!uNumNPCNames[1]))
+						uNumNPCNames[1]=i;
 					}
 				else
 					{
-LABEL_45:
-					if ( v20 == 1 && !uNumNPCNames[1] )
-						uNumNPCNames[1] = v18;
-					}
-				++v20;
-				v4 += v14 + 1;
-			}
-			while ( v20 <= 1 );
-			++v18;
-			v16 += 8;
-			if ( (signed int)v18 >= 540 )
-				break;
-			v2 = 0;
-		}
-	pNPCProfTXT_Raw = 0;
-	uNumNPCNames[0] = v18;
-	//v7 = (char *)pEvents_LOD->LoadRaw("npcprof.txt", 0);
-	pNPCProfTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcprof.txt", 0);
-	strtok(pNPCProfTXT_Raw, "\r");
-	strtok(0, "\r");
-	strtok(0, "\r");
-	strtok(0, "\r");
-	v8 = (char *)&pProfessions[0].pJoinText;
-	v19 = (char *)&pProfessions[0].pJoinText;
-	v13 = 58;
-	do
-		{
-		v21 = 0;
-		v9 = strtok(0, "\r") + 1;
-		v17 = 0;
-		do
-			{
-			v10 = *v9;
-			v11 = 0;
-			if ( *v9 != 9 )
-				{
-				do
-					{
-					if ( !v10 )
-						break;
-					++v11;
-					v10 = v9[v11];
+					while((c!='\n')&&(c!='\t')&&(c>0))
+						{
+						++temp_str_len;
+						c=test_string[temp_str_len];
+						}		
+					tmp_pos=test_string+temp_str_len;
+					if (*tmp_pos == 0)
+						break_loop = true;
+
+					if (temp_str_len)
+						{
+						*tmp_pos = 0;
+						if ( decode_step == 0)
+							pNPCNames[i][0] =RemoveQuotes(test_string);
+						else if ( decode_step == 1)
+							pNPCNames[i][1] =RemoveQuotes(test_string);
+						}
+					else
+						{ 
+						if ( (decode_step == 1)&&(!uNumNPCNames[1]))
+							uNumNPCNames[1]=i;
+						}
 					}
-					while ( v10 != 9 );
-					v8 = v19;
-				}
-			v15 = (int)&v9[v11];
-			if ( !v9[v11] )
-				v17 = 1;
-			*(char *)v15 = 0;
-			if ( v11 )
+				++decode_step;
+				test_string=tmp_pos+1;
+				} while ((decode_step<2)&&!break_loop);
+			}
+		uNumNPCNames[0] = i;
+
+		pNPCProfTXT_Raw = NULL;
+		pNPCProfTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcprof.txt", 0);
+		strtok(pNPCProfTXT_Raw, "\r");
+		strtok(NULL, "\r");
+		strtok(NULL, "\r");
+		strtok(NULL, "\r");
+
+		for (i=1; i<59; ++i)
+			{
+			test_string = strtok(NULL, "\r") + 1;
+			break_loop = false;
+			decode_step=0;
+			do 
 				{
-				switch ( v21 )
+				c = *(unsigned char*)test_string;
+				temp_str_len = 0;
+				while((c!='\t')&&(c>0))
 					{
-				case 2:
-					*((int *)v8 - 3) = atoi(v9);
-					break;
-				case 3:
-					*((int *)v8 - 1) = (int)RemoveQuotes(v9);
-					break;
-				case 4:
-					*((int *)v8 - 2) = (int)RemoveQuotes(v9);
-					break;
-				case 5:
-					*(int *)v8 = (int)RemoveQuotes(v9);
-					break;
-				case 6:
-					*((int *)v8 + 1) = (int)RemoveQuotes(v9);
-					break;
+					++temp_str_len;
+					c=test_string[temp_str_len];
+					}		
+				tmp_pos=test_string+temp_str_len;
+				if (*tmp_pos == 0)
+					break_loop = true;
+				*tmp_pos = 0;
+				if (temp_str_len)
+					{
+					switch(decode_step)
+						{
+					case 2:
+						pProfessions[i].uHirePrice = atoi(test_string);
+						break;
+					case 3:
+						pProfessions[i].pActionText = RemoveQuotes(test_string);
+						break;
+					case 4:
+						pProfessions[i].pBenefits= RemoveQuotes(test_string);
+						break;
+					case 5:
+						pProfessions[i].pJoinText = RemoveQuotes(test_string);
+						break;
+					case 6:
+						pProfessions[i].pDismissText = RemoveQuotes(test_string);
+						}
 					}
-				}
-			else
-				{
-				if ( !v21 )
-					v17 = 1;
-				}
-			++v21;
-			v9 = (char *)(v15 + 1);
+				else
+					{ 
+					if (!decode_step)
+						break_loop = true;
+					}
+				++decode_step;
+				test_string=tmp_pos+1;
+				} while ((decode_step<7)&&!break_loop);
 			}
-			while ( v21 <= 6 && !v17 );
-			v8 += 20;
-			v12 = v13-- == 1;
-			v19 = v8;
+		uNumNPCProfessions = 59;
 		}
-		while ( !v12 );
-		uNumNPCProfessions = 59;
-	}
 
 //----- (00477266) --------------------------------------------------------
 void NPCStats::Release()
 	{
-	NPCStats *v1; // esi@1
-	void *v2; // ST00_4@1
-	int v3; // ebx@1
-
-	v1 = this;
-	pAllocator->FreeChunk(this->pNPCTopicTXT_Raw);
-	v2 = v1->pNPCTextTXT_Raw;
-	v1->pNPCNewsTXT_Raw = 0;
-	pAllocator->FreeChunk(v2);
-	v1->pNPCNewsTXT_Raw = 0;
-	pAllocator->FreeChunk(0);
-	v1->pNPCNewsTXT_Raw = 0;
-	pAllocator->FreeChunk(v1->pNPCProfTXT_Raw);
-	v1->pNPCProfTXT_Raw = 0;
-	pAllocator->FreeChunk(v1->pNPCNamesTXT_Raw);
-	v1->pNPCNamesTXT_Raw = 0;
-	pAllocator->FreeChunk(v1->pNPCDataTXT_Raw);
-	v1->pNPCDataTXT_Raw = 0;
-	pAllocator->FreeChunk(v1->pNPCDistTXT_Raw);
-	v1->pNPCDistTXT_Raw = 0;
-	v3 = (int)&v1->pNPCGreetTXT_Raw;
-	pAllocator->FreeChunk(v1->pNPCGreetTXT_Raw);
-	v1 = (NPCStats *)((char *)v1 + 98296);
-	*(int *)v3 = 0;
-	pAllocator->FreeChunk(v1->pNPCData[0].pName);
-	v1->pNPCData[0].pName = 0;
+	pAllocator->FreeChunk(pNPCTopicTXT_Raw);
+	pNPCTopicTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNPCTextTXT_Raw);
+	pNPCTextTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNPCNewsTXT_Raw);
+	pNPCNewsTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNPCProfTXT_Raw);
+	pNPCProfTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNPCNamesTXT_Raw);
+	pNPCNamesTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNPCDataTXT_Raw);
+	pNPCDataTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNPCDistTXT_Raw);
+	pNPCDistTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNPCGreetTXT_Raw);
+	pNPCGreetTXT_Raw = NULL;
+	pAllocator->FreeChunk(pNCPGroupTXT_Raw);
+	pNCPGroupTXT_Raw = NULL;
 	}
 
 //----- (0047730C) --------------------------------------------------------
-int __fastcall const_1(int a1, int)
+bool  CheckPortretAgainsSex(int a1, int)
 	{
-	return 1;
+	return true;
 	}
 // 47730C: using guessed type int __stdcall const_1(int);
 
 //----- (0047732C) --------------------------------------------------------
-bool NPCStats::InitializeAdditionalNPCs(NPCData *a2, int a3, int a4, int a5)
+void NPCStats::InitializeAdditionalNPCs(NPCData *pNPCDataBuff, int npc_uid, int uLocation2D, int uMapId)
 	{
-	//NPCStats *v5; // ebx@1
-	signed __int64 v6; // qax@1
-	int v7; // esi@1
-	int v8; // edx@1
-	NPCData *v9; // edi@1
-	int v10; // eax@1
-	//int v11; // eax@23
-	int v12; // ecx@23
-	int v13; // edx@28
-	int v14; // esi@37
-	int v15; // edx@37
-	int v16; // ecx@37
-	int v17; // eax@37
-	int v18; // edx@37
+	
+	int uNPCSex; // esi@1
+	int uGeneratedPortret; // ecx@23
+	int test_prof_summ; // ecx@37
+	int gen_profession; // eax@37
+	int max_prof_cap; // edx@37
 	signed int result; // eax@39
-	int v20; // [sp+Ch] [bp-Ch]@1
-	signed int v21; // [sp+10h] [bp-8h]@1
-	signed int v22; // [sp+14h] [bp-4h]@1
-	int v23; // [sp+24h] [bp+Ch]@1
+	int uRace; // [sp+Ch] [bp-Ch]@1
+	bool break_gen; // [sp+10h] [bp-8h]@1
+	signed int gen_attempts; // [sp+14h] [bp-4h]@1
+	int uPortretMin; // [sp+24h] [bp+Ch]@1
+	int uPortretMax;
+
+	static const unsigned __int8 NPCSexGenTable[86] ={
+		                              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                          
+                                      1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+	                                  1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0,
+	                                  0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+									  0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
+   static const unsigned __int8 NPCRaceGenTable[86] ={
+									    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 1,
+										0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+										0, 0, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+										0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+										, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0};
 
 
-	v23 = a3 - 1;
-	//v5 = this;
-	v6 = (signed __int64)((double)v23 * -0.33333334);
-	v7 = (unsigned __int8)byte_4E8394[-(_DWORD)v6 + 28];
-	v20 = (unsigned __int8)byte_4E8394[-(_DWORD)v6 + 116];
-	v8 = rand() % uNumNPCNames[v7];
-	v9 = a2;
-	a2->uSex = v7;
-	a2->pName = pNPCNames[v8][v7];
-	v10 = 0;
-	v22 = 0;
-	v21 = 0;
+	unsigned __int8 seed = (unsigned __int8)((double)(npc_uid - 1) * 0.33333334);
+	uNPCSex = NPCSexGenTable[seed];
+	uRace = NPCRaceGenTable[seed];
+	pNPCDataBuff->uSex = uNPCSex;
+	pNPCDataBuff->pName = pNPCNames[rand() % uNumNPCNames[uNPCSex]][uNPCSex];
+
+	gen_attempts = 0;
+	break_gen = false;
 
-	while ( 1 )
+	do
 		{
-		if ( v20 == v10 )
-			{
-			if ( v7 == v10 )
+	    	switch ( uRace )
 				{
-				v23 = 2;
-				a2 = (NPCData *)100;
+			case 0:
+				if ( uNPCSex == 0 )
+				{
+				uPortretMin = 2;
+				uPortretMax = 100;
 				}
 			else
 				{
-				if ( v7 - v10 == 1 )
-					{
-					v23 = 201;
-					a2 = (NPCData *)250;
-					}
+					uPortretMin = 201;
+					uPortretMax =  250;
 				}
-			}
-		else
-			{
-			switch ( v20 - v10 )
-				{
+
 			case 1:
-				if ( v7 == v10 )
+				if ( uNPCSex == 0 )
 					{
-					v23 = 400;
-					a2 = (NPCData *)430;
+					uPortretMin = 400;
+					uPortretMax = 430;
 					}
 				else
 					{
-					if ( v7 - v10 == 1 )
-						{
-						v23 = 460;
-						a2 = (NPCData *)490;
-						}
+						uPortretMin = 460;
+						uPortretMax =  490;
 					}
 				break;
 			case 2:
-				if ( v7 == v10 )
+				if ( uNPCSex == 0 )
 					{
-					v23 = 500;
-					a2 = (NPCData *)520;
+					uPortretMin = 500;
+					uPortretMax =  520;
 					}
 				else
 					{
-					if ( v7 - v10 == 1 )
-						{
-						v23 = 530;
-						a2 = (NPCData *)550;
-						}
+						uPortretMin = 530;
+						uPortretMax = 550;	
 					}
 				break;
 			case 3:
-				if ( v7 == v10 )
+				if ( uNPCSex == 0 )
 					{
-					v23 = 300;
-					a2 = (NPCData *)330;
+					uPortretMin = 300;
+					uPortretMax = 330;
 					}
 				else
-					{
-					if ( v7 - v10 == 1 )
 						{
-						v23 = 360;
-						a2 = (NPCData *)387;
+						uPortretMin = 360;
+						uPortretMax = 387;
 						}
-					}
+					
 				break;
 				}
-			}
-		v12 = v23 + rand() % ((int)a2 - v23 + 1);
-		if ( const_1(v12, v7) == 1 )
-			v21 = 1;
-		++v22;
-		if ( v22 >= 4 )
+			
+		uGeneratedPortret = uPortretMin + rand() % (uPortretMax - uPortretMin + 1);
+		if ( CheckPortretAgainsSex(uGeneratedPortret, uNPCSex))
+			break_gen = true;
+		++gen_attempts;
+		if ( gen_attempts >= 4 )
 			{
-			v12 = v23;
-			v21 = 1;
+			uGeneratedPortret = uPortretMin;
+			break_gen = true;
 			}
-		if ( v21 )
-			break;
-		v10 = 0;
 		}
+		while(!break_gen);
 
-	v9->uPortraitID = v12;
-	v9->uFlags = 0;
-	v9->fame = 0;
+	pNPCDataBuff->uPortraitID = uGeneratedPortret;
+	pNPCDataBuff->uFlags = 0;
+	pNPCDataBuff->fame = 0;
+	//generate reputation
 	v13 = rand() % 100 + 1;
 
 	if ( v13 >= 60 )
@@ -754,44 +641,34 @@
 			if ( v13 >= 95 )
 				{
 				if ( v13 >= 98 )
-					v9->rep = -600;
+					pNPCDataBuff->rep = -600;
 				else
-					v9->rep = 400;
+					pNPCDataBuff->rep = 400;
 				}
 			else
-				{
-				v9->rep = -300;
-				}
+				pNPCDataBuff->rep = -300;
 			}
 		else
-			{
-			v9->rep = 200;
-			}
+			pNPCDataBuff->rep = 200;
+
 		}
 	else
-		{
-		v9->rep = 0;
-		}
+		pNPCDataBuff->rep = 0;
 
-	//v14 = (int)((char *)v5 + 64 * a5);
-	//v15 = rand() % *(_DWORD *)(v14 + 91460);
-	v15 = rand() % array_16544[a5].field_0;
-	v16 = 0;
-	v17 = 0;
-	v18 = v15 + 1;
+	max_prof_cap = rand() % pProfessionChance[uMapId].uTotalprofChance+1;
+	test_prof_summ = 0;
+	gen_profession = 0;
 
-	if ( v18 > 0 )
+	if ( max_prof_cap > 0 )
 		{
 		do
-		//v14 += *(char *)(v14 + v17++ + 0x16548);
-		v16 += array_16544[a5].field_4[v17++];
-		while ( v16 < v18 );
+		  test_prof_summ += pProfessionChance[uMapId].professionChancePerArea[gen_profession++];
+		while ( test_prof_summ < max_prof_cap );
 		}
-	v9->uProfession = v17 - 1;
-	v9->house = a4;
-	v9->field_24 = 1;
-	v9->joins = 1;
-	return true;
+	pNPCDataBuff->uProfession = gen_profession - 1;
+	pNPCDataBuff->Location2D = uLocation2D;
+	pNPCDataBuff->field_24 = 1;
+	pNPCDataBuff->joins = 1;
 	}
 
 
@@ -850,7 +727,6 @@
 	unsigned int temp_str_len;
 	char* tmp_pos;
 	int decode_step;
-	int item_counter;
 
 	if ( pAwardsTXT_Raw )
 		pAllocator->FreeChunk(pAwardsTXT_Raw);
@@ -906,7 +782,6 @@
 	unsigned int temp_str_len;
 	char* tmp_pos;
 	int decode_step;
-	int item_counter;
 
 	if ( pScrollsTXT_Raw )
 		pAllocator->FreeChunk(pScrollsTXT_Raw);
@@ -957,7 +832,6 @@
 	unsigned int temp_str_len;
 	char* tmp_pos;
 	int decode_step;
-	int item_counter;
 
 	if ( pMerchantsTXT_Raw )
 		pAllocator->FreeChunk(pMerchantsTXT_Raw);
@@ -1022,7 +896,6 @@
 	unsigned int temp_str_len;
 	char* tmp_pos;
 	int decode_step;
-	int item_counter;
 
 	if ( pTransitionsTXT_Raw )
 		pAllocator->FreeChunk(pTransitionsTXT_Raw);
@@ -1073,7 +946,6 @@
 	unsigned int temp_str_len;
 	char* tmp_pos;
 	int decode_step;
-	int item_counter;
 
 	if ( pAutonoteTXT_Raw )
 		pAllocator->FreeChunk(pAutonoteTXT_Raw);
@@ -1159,7 +1031,6 @@
 	unsigned int temp_str_len;
 	char* tmp_pos;
 	int decode_step;
-	int item_counter;
 
 	if ( pQuestsTXT_Raw )
 		pAllocator->FreeChunk(pQuestsTXT_Raw);
--- a/NPC.h	Mon Feb 18 20:47:41 2013 +0600
+++ b/NPC.h	Tue Feb 19 00:34:15 2013 +0400
@@ -10,34 +10,31 @@
 extern NPCTopic pNPCTopics[789];
 
 
-
-
-
 /*  136 */
 #pragma pack(push, 1)
-struct NPCData
+struct NPCData  //4Ch
 {
   inline bool Hired() {return uFlags & 0x80;}
 
-  char *pName;
-  unsigned int uPortraitID;
-  unsigned int uFlags;         // & 0x80    no greeting on dialogue start; looks like hired
-  int fame;
-  int rep;
-  int house;
-  unsigned int uProfession;
-  int greet;
-  int joins;
+  char *pName;  //0
+  unsigned int uPortraitID;  //4
+  unsigned int uFlags;     //8    // & 0x80    no greeting on dialogue start; looks like hired
+  int fame;  //c
+  int rep;  //10
+  unsigned int Location2D;  //14
+  unsigned int uProfession; //18
+  int greet;  //1c
+  int joins;  //20
   int field_24;
-  unsigned int bDrawSomeAnim;
-  int _anim_current_time; //evtb
-  int _anim_end_time; //evtc
-  int evtd;
-  int evte;
-  int evtf;
-  int uSex;
-  int bHasUsedTheAbility;
-  int news_topic;
+  unsigned int evt_A; //28
+  unsigned int evt_B; //2c evtb
+  unsigned int evt_C; //  30 evtc
+  unsigned int evt_D;  //34
+  unsigned int evt_E;  //38
+  unsigned int evt_F;  //3c
+  unsigned int uSex;  //40
+  int bHasUsedTheAbility; //44
+  int news_topic;  //48
 };
 #pragma pack(pop)
 
@@ -57,10 +54,10 @@
 
 /*  139 */
 #pragma pack(push, 1)
-struct NPCStats_stru0
+struct NPCProfessionChance
 {
-  int field_0;  //summ 
-  char field_4[60]; //prof position
+  unsigned int uTotalprofChance;  //summ 
+  char professionChancePerArea[60]; //prof position
 };
 #pragma pack(pop)
 
@@ -74,7 +71,6 @@
 #pragma pack(pop)
 
 
-
 /*  137 */
 #pragma pack(push, 1)
 struct NPCStats
@@ -85,37 +81,32 @@
     uNumNPCNames[0] = uNumNPCNames[1] = 0;
   }
 
-  void Initialize2();
-  void Initialize1();
+  void InitializeNPCText();
+  void InitializeNPCData();
   void Initialize();
   void Release();
-  bool InitializeAdditionalNPCs(NPCData *a2, int a3, int a4, int a5);
+  void InitializeAdditionalNPCs(NPCData *pNPCDataBuff, int npc_uid, int uLocation2D, int uMapId);
   void _476C60();
 
   
-  NPCData pNPCData[501];
-  NPCData pNewNPCData[501];
+  NPCData pNPCData[501]; //0 - 94BCh count from 1 
+  NPCData pNewNPCData[501]; //94BCh- 12978h count from 1
   char *pNPCNames[540][2];
-  int field_13A58;
-  int field_13A5C;
-  int field_13A60;
-  int field_13A64;
-  int field_13A68;
-  NPCProfession pProfessions[58];
-  NPCData array_13EF4[100];
-  char *pCatchPhrases[52];
-  char *pNPCNames2[500];
-  NPCStats_stru0 array_16544[77]; //16544h proffesion position in area
+  NPCProfession pProfessions[59];  //count from 1
+  NPCData pAdditionalNPC[100];
+  char *pCatchPhrases[52];  //15CA4h
+  char *pNPCUnicNames[500];  //from first batch
+  NPCProfessionChance pProfessionChance[77]; //16544h profession chance in each area
   int field_17884;
   int field_17888;
   NPCGreeting pNPCGreetings[205];
   unsigned __int16 pGroups[51];
   unsigned __int16 pGroups_copy[51];
-  int field_17FC0;
+  unsigned int uNewlNPCBufPos;
   unsigned int uNumNewNPCs;
   int field_17FC8;
   unsigned int uNumNPCProfessions;
-  unsigned int uNumNPCNames[2];
+  unsigned int uNumNPCNames[2]; //0 male 1 female
   char *pNPCDataTXT_Raw;
   char *pNPCNamesTXT_Raw;
   char *pNPCProfTXT_Raw;
--- a/Party.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/Party.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -974,15 +974,15 @@
   for (int i = 0; i < 2; ++i)
   {
     auto hireling = pParty->pHirelings + i;
-    if (!hireling->_anim_end_time)
+    if (!hireling->evt_C)
       continue;
 
-    hireling->_anim_current_time += pMiscTimer->uTimeElapsed;
-    if (hireling->_anim_current_time >= hireling->_anim_end_time)
+    hireling->evt_B += pMiscTimer->uTimeElapsed;
+    if (hireling->evt_B >= hireling->evt_C)
     {
-      hireling->bDrawSomeAnim = false;
-      hireling->_anim_current_time = 0;
-      hireling->_anim_end_time = 0;
+      hireling->evt_A = 0;
+      hireling->evt_B = 0;
+      hireling->evt_C = 0;
 
       assert(sizeof(NPCData) == 0x4C);
       memset(hireling, 0, sizeof(*hireling));
--- a/mm7_1.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/mm7_1.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -4778,7 +4778,7 @@
           v12 = &pParty->pHirelings[v11];
         v13 = v12->uProfession;
         if ( v13 )
-          v3 += *(&pNPCStats->field_13A58 + 5 * v13);
+          v3 += pNPCStats->pProfessions[v13].uHirePrice;//*(&pNPCStats->field_13A58 + 5 * v13);
         ++v2;
       }
       while ( (signed int)v2 < v14 );
--- a/mm7_2.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/mm7_2.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -11275,7 +11275,7 @@
   pParty->field_7B5_in_arena_quest = 0;
   //v1 = 0;
   dword_5C6DF8 = 1;
-  pNPCStats->field_17FC0 = 0;
+  pNPCStats->uNewlNPCBufPos = 0;
   v19 = pMapStats->GetMapInfo(pCurrentMapName);
 
   //v15 = 0;
@@ -11310,9 +11310,9 @@
         continue;
       if ( v17 )
       {
-        pNPCStats->InitializeAdditionalNPCs(&pNPCStats->array_13EF4[pNPCStats->field_17FC0], v3, 0, v19);
-        v14 = LOWORD(pNPCStats->field_17FC0) + 5000;
-        ++pNPCStats->field_17FC0;
+        pNPCStats->InitializeAdditionalNPCs(&pNPCStats->pAdditionalNPC[pNPCStats->uNewlNPCBufPos], v3, 0, v19);
+        v14 = LOWORD(pNPCStats->uNewlNPCBufPos) + 5000;
+        ++pNPCStats->uNewlNPCBufPos;
         pActor->uNPC_ID = v14;
         continue;
       }
--- a/mm7_3.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/mm7_3.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -15230,7 +15230,7 @@
 	else if (v16 == 24)
     {
       __debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->evtf - 1].pTopic;//(&dword_721660)[8 * v23];
+      auto topic = pNPCTopics[pNPC->evt_F - 1].pTopic;//(&dword_721660)[8 * v23];
       if (!topic)
       {
         v14->pButtonName[0] = 0;
@@ -15244,7 +15244,7 @@
 	else if (v16 == 19)
 	{
       __debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->bDrawSomeAnim - 1].pTopic;//(&dword_721660)[8 * v23];
+      auto topic = pNPCTopics[pNPC->evt_A - 1].pTopic;//(&dword_721660)[8 * v23];
       if (!topic)
       {
         v14->pButtonName[0] = 0;
@@ -15255,7 +15255,7 @@
 	else if (v16 == 20)
 	{
       __debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->_anim_current_time - 1].pTopic;//(&dword_721660)[8 * v23];
+      auto topic = pNPCTopics[pNPC->evt_B - 1].pTopic;//(&dword_721660)[8 * v23];
       if (!topic)
       {
         v14->pButtonName[0] = 0;
@@ -15266,7 +15266,7 @@
 	else if (v16 == 21)
 	{
       __debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->_anim_end_time - 1].pTopic;//(&dword_721660)[8 * v23];
+      auto topic = pNPCTopics[pNPC->evt_C - 1].pTopic;//(&dword_721660)[8 * v23];
       if (!topic)
       {
         v14->pButtonName[0] = 0;
@@ -15277,7 +15277,7 @@
 	else if (v16 == 22)
 	{
       __debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->evtd - 1].pTopic;//(&dword_721660)[8 * v23];
+      auto topic = pNPCTopics[pNPC->evt_D - 1].pTopic;//(&dword_721660)[8 * v23];
       if (!topic)
       {
         v14->pButtonName[0] = 0;
@@ -15288,7 +15288,7 @@
 	else if (v16 == 23)
 	{
       __debugbreak(); // learn conditions of this event
-      auto topic = pNPCTopics[pNPC->evte - 1].pTopic;//(&dword_721660)[8 * v23];
+      auto topic = pNPCTopics[pNPC->evt_E - 1].pTopic;//(&dword_721660)[8 * v23];
       if (!topic)
       {
         v14->pButtonName[0] = 0;
@@ -15477,12 +15477,12 @@
       }
       return &pNPCStats->pNewNPCData[v1];// - 1];
     }
-    return &pNPCStats->array_13EF4[npcid - 5000];
+    return &pNPCStats->pAdditionalNPC[npcid - 5000];
   }
 
 
   if ( npcid >= 5000 )
-    return &pNPCStats->array_13EF4[npcid - 5000];
+    return &pNPCStats->pAdditionalNPC[npcid - 5000];
   if (uDialogue_SpeakingActorNPC_ID >= 0)
   {
     result = 0;
@@ -15558,7 +15558,7 @@
     }
 LABEL_7:
     *(int *)a2 = npcid - 5000;
-    return &pNPCStats->array_13EF4[npcid - 5000];
+    return &pNPCStats->pAdditionalNPC[npcid - 5000];
   }
   if ( npcid >= 5000 )
     goto LABEL_7;
@@ -16314,31 +16314,31 @@
                     if ( v37 )
                     {
                       if ( v37 == 1 )
-                        v33->evtf = v30;
+                        v33->evt_F = v30;
                     }
                     else
                     {
-                      v33->evte = v30;
+                      v33->evt_E = v30;
                     }
                   }
                   else
                   {
-                    v33->evtd = v30;
+                    v33->evt_D = v30;
                   }
                 }
                 else
                 {
-                  v33->_anim_end_time = v30;
+                  v33->evt_C = v30;
                 }
               }
               else
               {
-                v33->_anim_current_time = v30;
+                v33->evt_B = v30;
               }
             }
             else
             {
-              v33->bDrawSomeAnim = v30;
+              v33->evt_A = v30;
             }
             if ( v29 == 8 )
             {
@@ -16448,7 +16448,7 @@
             //v7 = "";
             break;
           case EVENT_MoveNPC:
-            pNPCStats->pNewNPCData[_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8)].house = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
+            pNPCStats->pNewNPCData[_evt->v5 + ((_evt->v6 + ((_evt->v7 + ((uint)_evt->v8 << 8)) << 8)) << 8)].Location2D = _evt->v9 + ((_evt->v10 + ((_evt->v11 + ((uint)_evt->v12 << 8)) << 8)) << 8);
             if ( ptr_507BC0 )
             {
               v46 = ptr_507BC0->ptr_1C;
--- a/mm7_4.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/mm7_4.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -3089,9 +3089,9 @@
         v9 = v23;
         pRenderer->DrawTextureIndexed(pHiredNPCsIconsOffsetsX[v9], pHiredNPCsIconsOffsetsY[v9], (Texture *)(v8 != -1 ? &pIcons_LOD->pTextures[v8] : 0));
         v10 = (unsigned __int8)pTmpBuf[i];
-        if ( pParty->pHirelings[v10].bDrawSomeAnim == 1 )
-        {
-          uFrameID = pParty->pHirelings[v10]._anim_current_time;
+        if ( pParty->pHirelings[v10].evt_A == 1 )
+        {
+          uFrameID = pParty->pHirelings[v10].evt_B;
           v11 = pHiredNPCsIconsOffsetsX[v9];
           v12 = pHiredNPCsIconsOffsetsY[v9];
           v17 = v11;
@@ -9416,13 +9416,13 @@
   {
     if ( a1 == 23 )
     {
-      v3 = v2->evte;
+      v3 = v2->evt_E;
     }
     else
     {
       if ( a1 == 13 )
       {
-        ptr_F8B1E8 = (char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
+        ptr_F8B1E8 = pNPCStats->pProfessions[v2->uProfession].pJoinText;//(char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
         ptr_F8B1E8 = BuilDialogueString((char *)ptr_F8B1E8, uActiveCharacter - 1, 0, 0, 0, 0);
         sub_4B40E6();
         dialogue_show_profession_details = false;
@@ -9431,18 +9431,18 @@
       switch ( a1 )
       {
         case 19:
-          v3 = v2->bDrawSomeAnim;
+          v3 = v2->evt_A;
           break;
         case 20:
-          v3 = v2->_anim_current_time;
+          v3 = v2->evt_B;
           break;
         case 21:
-          v3 = v2->_anim_end_time;
+          v3 = v2->evt_C;
           break;
         default:
           if ( a1 != 22 )
             goto _return;
-          v3 = v2->evtd;
+          v3 = v2->evt_D;
           break;
       }
     }
@@ -9450,7 +9450,7 @@
   }
   if ( a1 == 24 )
   {
-    v3 = v2->evtf;
+    v3 = v2->evt_F;
 LABEL_84:
     if ( v3 < 200 || v3 > 310 )
     {
@@ -9553,36 +9553,36 @@
           switch ( dword_F8B1D8 )
           {
             case 19:
-              v10 = v2->bDrawSomeAnim;
+              v10 = v2->evt_A;
               if ( (signed int)v10 >= 400 && (signed int)v10 <= 416 )
-                v2->bDrawSomeAnim = 0;
+                v2->evt_A = 0;
               break;
             case 20:
-              v9 = v2->_anim_current_time;
+              v9 = v2->evt_B;
               if ( v9 >= 400 && v9 <= 416 )
-                v2->_anim_current_time = 0;
+                v2->evt_B = 0;
               break;
             case 21:
-              v8 = v2->_anim_end_time;
+              v8 = v2->evt_C;
               if ( v8 >= 400 && v8 <= 416 )
-                v2->_anim_end_time = 0;
+                v2->evt_C = 0;
               break;
             case 22:
-              v7 = v2->evtd;
+              v7 = v2->evt_D;
               if ( v7 >= 400 && v7 <= 416 )
-                v2->evtd = 0;
+                v2->evt_D = 0;
               break;
             case 23:
-              v6 = v2->evte;
+              v6 = v2->evt_E;
               if ( v6 >= 400 && v6 <= 416 )
-                v2->evte = 0;
+                v2->evt_E = 0;
               break;
             case 24:
-              v5 = v2->evtf;
+              v5 = v2->evt_F;
               if ( v5 >= 400 )
               {
                 if ( v5 <= 416 )
-                  v2->evtf = 0;
+                  v2->evt_F = 0;
               }
               break;
           }
@@ -10228,7 +10228,7 @@
       {
         if ( v17 == 24 )
         {
-          v23 = v58->evtf;
+          v23 = v58->evt_F;
 LABEL_33:
           v15 = (char *)pNPCTopics[v23-1].pTopic;//(&dword_721660)[8 * v23];
           if ( !v15 )
@@ -10244,13 +10244,13 @@
           v19 = v18 - 6;
           if ( !v19 )
           {
-            v23 = v58->bDrawSomeAnim;
+            v23 = v58->evt_A;
             goto LABEL_33;
           }
           v20 = v19 - 1;
           if ( !v20 )
           {
-            v15 = (char *)pNPCTopics[v58->_anim_current_time-1].pTopic;//(&dword_721660)[8 * v58->evtb];
+            v15 = (char *)pNPCTopics[v58->evt_B-1].pTopic;//(&dword_721660)[8 * v58->evtb];
             if ( !v15 )
             {
               v16->uControlParam = 0;
@@ -10266,18 +10266,18 @@
           v21 = v20 - 1;
           if ( !v21 )
           {
-            v23 = v58->_anim_end_time;
+            v23 = v58->evt_C;
             goto LABEL_33;
           }
           v22 = v21 - 1;
           if ( !v22 )
           {
-            v23 = v58->evtd;
+            v23 = v58->evt_D;
             goto LABEL_33;
           }
           if ( v22 == 1 )
           {
-            v23 = v58->evte;
+            v23 = v58->evt_E;
             goto LABEL_33;
           }
 LABEL_41:
@@ -11052,7 +11052,7 @@
   pDialogueWindow->eWindowType = WINDOW_MainMenu;
   pDialogueWindow->Release();
   pDialogueWindow = GUIWindow::Create(0, 0, 640, 480, WINDOW_Dialogue, 1, 0);
-  if ( *(&pNPCStats->field_13A5C + 5 * v0->uProfession) )
+  if ( pNPCStats->pProfessions[v0->uProfession].pBenefits)//*(&pNPCStats->field_13A5C + 5 * v0->uProfession) )
   {
     pDialogueWindow->CreateButton(480, 160, 140, 28, 1, 0, 136, 77, 0, pGlobalTXT_LocalizationStrings[407], 0);
     v1 = 1;
@@ -11163,7 +11163,7 @@
                  (Texture *)(uTextureID_506438 != -1 ? (int)&pIcons_LOD->pTextures[uTextureID_506438] : 0),
                  0);
   pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, 0x51u, 0, 0, "", 0);
-  if ( *(&pNPCStats->field_13A5C + 5 * v1->uProfession) )
+  if ( pNPCStats->pProfessions[v1->uProfession].pBenefits)//*(&pNPCStats->field_13A5C + 5 * v1->uProfession) )
   {
     pDialogueWindow->CreateButton(
       0x1E0u,
@@ -11303,7 +11303,7 @@
         v1 = 1;
         pDialogueWindow->CreateButton(480u, 160u, 140u, 30u, 1, 0, 0xAFu, 0xDu, 0, "", 0);
       }
-      v5 = (void *)v17->bDrawSomeAnim;
+      v5 = (void *)v17->evt_A;
       if ( v5 )
       {
         if ( v1 < 4 )
@@ -11324,7 +11324,7 @@
               0);
         }
       }
-      v7 = (void *)v17->_anim_current_time;
+      v7 = (void *)v17->evt_B;
       if ( v7 )
       {
         if ( v1 < 4 )
@@ -11345,7 +11345,7 @@
               0);
         }
       }
-      v9 = (void *)v17->_anim_end_time;
+      v9 = (void *)v17->evt_C;
       if ( v9 )
       {
         if ( v1 < 4 )
@@ -11366,7 +11366,7 @@
               0);
         }
       }
-      v11 = (void *)v17->evtd;
+      v11 = (void *)v17->evt_D;
       if ( v11 )
       {
         if ( v1 < 4 )
@@ -11387,7 +11387,7 @@
               0);
         }
       }
-      v13 = (void *)v17->evte;
+      v13 = (void *)v17->evt_E;
       if ( v13 )
       {
         if ( v1 < 4 )
@@ -11408,7 +11408,7 @@
               0);
         }
       }
-      v15 = (void *)v17->evtf;
+      v15 = (void *)v17->evt_F;
       if ( v15 )
       {
         if ( v1 < 4 )
@@ -12567,12 +12567,12 @@
   {
     if ( newDialogueType == DIALOGUE_23 )
     {
-      v4 = v2->evte;
+      v4 = v2->evt_E;
       goto LABEL_74;
     }
     if (newDialogueType == DIALOGUE_24)
     {
-      v4 = v2->evtf;
+      v4 = v2->evt_F;
       goto LABEL_74;
     }
     if (newDialogueType != DIALOGUE_76)
@@ -12691,7 +12691,7 @@
   }
   if (newDialogueType == DIALOGUE_22)
   {
-    v4 = v2->evtd;
+    v4 = v2->evt_D;
     goto LABEL_74;
   }
   if (newDialogueType == DIALOGUE_9)
@@ -12739,17 +12739,17 @@
   }
   if (newDialogueType == DIALOGUE_19)
   {
-    v4 = v2->bDrawSomeAnim;
+    v4 = v2->evt_A;
     goto LABEL_74;
   }
   if (newDialogueType == DIALOGUE_20)
   {
-    v4 = v2->_anim_current_time;
+    v4 = v2->evt_B;
     goto LABEL_74;
   }
   if (newDialogueType == DIALOGUE_21)
   {
-    v4 = v2->_anim_end_time;
+    v4 = v2->evt_C;
 LABEL_74:
     if ( v4 < 200 || v4 > 310 )
     {
--- a/mm7_5.cpp	Mon Feb 18 20:47:41 2013 +0600
+++ b/mm7_5.cpp	Tue Feb 19 00:34:15 2013 +0400
@@ -2263,8 +2263,8 @@
               _5B65A8_npcdata_uflags_or_other = pNPCData4->uFlags;
               _5B65AC_npcdata_fame_or_other = pNPCData4->fame;
               _5B65B0_npcdata_rep_or_other = pNPCData4->rep;
-              _5B65B4_npcdata_loword_house_or_other = LOWORD(pNPCData4->house);
-              _5B65B8_npcdata_hiword_house_or_other = HIWORD(pNPCData4->house);
+              _5B65B4_npcdata_loword_house_or_other = LOWORD(pNPCData4->Location2D);
+              _5B65B8_npcdata_hiword_house_or_other = HIWORD(pNPCData4->Location2D);
               dword_5B65C0 = v0;
             }
             else
@@ -2273,8 +2273,8 @@
               pParty->vPosition.y = pNPCData4->fame;
               pParty->vPosition.z = pNPCData4->rep;
               pParty->uFallStartY = pParty->vPosition.z;
-              pParty->sRotationY = LOWORD(pNPCData4->house);
-              pParty->sRotationX = HIWORD(pNPCData4->house);
+              pParty->sRotationY = LOWORD(pNPCData4->Location2D);
+              pParty->sRotationX = HIWORD(pNPCData4->Location2D);
             }
             if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
             {
@@ -2303,8 +2303,8 @@
             pNPCData2->uFlags = pParty->vPosition.x;
             pNPCData2->fame = pParty->vPosition.y;
             pNPCData2->rep = pParty->vPosition.z;
-            LOWORD(pNPCData2->house) = LOWORD(pParty->sRotationY);
-            HIWORD(pNPCData2->house) = LOWORD(pParty->sRotationX);
+            LOWORD(pNPCData2->Location2D) = LOWORD(pParty->sRotationY);
+            HIWORD(pNPCData2->Location2D) = LOWORD(pParty->sRotationX);
             if ( (signed int)pGames_LOD->uNumSubIndices / 2 <= 0 )
               continue;
             uAction = 0;
--- a/mm7_data.h	Mon Feb 18 20:47:41 2013 +0600
+++ b/mm7_data.h	Tue Feb 19 00:34:15 2013 +0400
@@ -2181,7 +2181,7 @@
 bool __fastcall sub_4759C9(BLVFace *a1, int a2, int a3, __int16 a4);
 bool __fastcall sub_475D85(Vec3_int_ *a1, Vec3_int_ *a2, int *a3, BLVFace *a4);
 bool __fastcall sub_475F30(int *a1, BLVFace *a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9);
-int __fastcall const_1(int, int); // weak
+
 int __cdecl GetPartyReputation();
 void __cdecl sub_4783FA_construct_global_73D150();
 void __cdecl loc_4789D4(); // idb