changeset 263:8cf4fe6b4941

Слияние
author Ritor1
date Mon, 18 Feb 2013 12:38:38 +0600
parents 2d6dda2e0405 (current diff) 96f3a1177b37 (diff)
children fb890fb66cad
files mm7_1.cpp mm7_2.cpp mm7_3.cpp mm7_4.cpp mm7_5.cpp
diffstat 14 files changed, 1521 insertions(+), 1456 deletions(-) [+]
line wrap: on
line diff
--- a/CShow.h	Mon Feb 18 12:38:07 2013 +0600
+++ b/CShow.h	Mon Feb 18 12:38:38 2013 +0600
@@ -41,6 +41,9 @@
   //char v10; // [sp+4h] [bp-8h]@4
   //int a3; // [sp+Bh] [bp-1h]@14
 
+  if (bNoVideo)
+    return;
+
   if (pAsyncMouse)
     pAsyncMouse->Suspend();
   switch ( eVideo )
--- a/GUIWindow.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/GUIWindow.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -729,7 +729,7 @@
               {
                 if ( v4 )
                 {
-                  v5 = sub_495461(v4, uActiveCharacter - 1, 0, 0, 0, v3);
+                  v5 = BuilDialogueString(v4, uActiveCharacter - 1, 0, 0, 0, v3);
                   v6 = pAutonoteFont->CalcTextHeight(v5, &v26, 1, 0);
                   v7 = (v6 - 3) / (signed int)v26.uFrameHeight;
                   v8 = v7 + 1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NPC.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -0,0 +1,1202 @@
+#include <string.h>
+#include <stdlib.h>
+
+#include "Allocator.h"
+#include "texts.h"
+#include "Party.h"
+#include "LOD.h"
+#include "Autonotes.h"
+#include "Awards.h"
+#include "mm7_data.h"
+#include "MM7.h"
+#include "NPC.h"
+
+
+void  InitializeAwards();
+void  InitializeScrolls();
+void  InitializeMerchants();
+void  InitializeTransitions();
+void  InitializeAutonotes();
+void  InitializeQuests();
+
+
+//----- (00476977) --------------------------------------------------------
+void NPCStats::Initialize2()
+	{
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+
+	if (pNPCTextTXT_Raw)
+		pAllocator->FreeChunk(pNPCTextTXT_Raw);
+	pNPCTextTXT_Raw =NULL;
+	pNPCTextTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctext.txt", 0);
+	strtok(pNPCTextTXT_Raw, "\r");
+
+	for (i=0; i<789; ++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)
+				{
+				if ( decode_step == 1)
+					pNPCTopics[i].pText =RemoveQuotes(test_string);
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<2)&&!break_loop);
+		}
+
+	if (pNPCTopicTXT_Raw)
+		pAllocator->FreeChunk(pNPCTopicTXT_Raw);
+	pNPCTopicTXT_Raw =NULL;
+	pNPCTopicTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctopic.txt", 0);
+	strtok(pNPCTopicTXT_Raw, "\r");
+
+	for (i=0; i<579; ++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)
+				{
+				if ( decode_step == 1)
+					pNPCTopics[i].pTopic = RemoveQuotes(test_string);
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<2)&&!break_loop);
+		}
+
+	if (pNPCDistTXT_Raw)
+		pAllocator->FreeChunk(pNPCDistTXT_Raw);
+	pNPCDistTXT_Raw = NULL;
+	pNPCDistTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcdist.txt", 0);
+	strtok(pNPCDistTXT_Raw, "\r");
+	strtok(NULL, "\r");
+
+	for (i=1; i<59; ++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)
+				{
+				if ((decode_step>0)&&(decode_step<77))
+					{
+					array_16544[decode_step].field_4[i]=atoi(test_string);
+					}
+				else if (decode_step==0)
+					{
+					array_16544[0].field_4[i]=10;
+					}
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<78)&&!break_loop);
+		}
+
+	for (i=0; i<78; ++i)
+		{
+		array_16544[i].field_0=0;
+		for (int ii=1; ii<59; ++ii)
+			{
+			array_16544[i].field_0+=array_16544[i].field_4[ii];
+			}
+		}
+
+	if (pNPCDistTXT_Raw)
+		{
+		pAllocator->FreeChunk(pNPCDistTXT_Raw);
+		pNPCDistTXT_Raw = NULL;
+		}
+	}
+
+//----- (00476C60) --------------------------------------------------------
+void NPCStats::_476C60()
+	{
+	for (unsigned int i = 1; i < uNumNewNPCs; ++i)
+		pNewNPCData[i].pName = pNPCNames2[i - 1];
+
+	if (pParty->pHirelings[0].pName)
+		pParty->pHirelings[0].pName = pParty->pHireling1Name;
+	if (pParty->pHirelings[1].pName)
+		pParty->pHirelings[1].pName = pParty->pHireling2Name;
+	}
+
+//----- (00476CB5) --------------------------------------------------------
+void NPCStats::Initialize1()
+	{
+	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
+
+	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
+		{
+		v32 = 0;
+		v4 = strtok(0, "\r") + 1;
+		v36 = -1;
+		do
+			{
+			v5 = *v4;
+			v6 = 0;
+			while ( v5 != 9 && v5 )
+				{
+				++v6;
+				v5 = v4[v6];
+				}
+			v23 = (int)&v4[v6];
+			if ( !v4[v6] )
+				v32 = 1;
+			v4[v6] = 0;
+			if ( v6 )
+				{
+				switch ( v36 )
+					{
+				case 0:
+					v7 = RemoveQuotes(v4);
+					*((int *)pHouse - 5) = (int)v7;
+					*(int *)Str = (int)v7;
+					break;
+				case 1:
+					*((int *)pHouse - 4) = atoi(v4);
+					break;
+				case 5:
+					*(int *)pHouse = atoi(v4);
+					break;
+				case 6:
+					*((int *)pHouse + 1) = atoi(v4);
+					break;
+				case 7:
+					*((int *)pHouse + 2) = atoi(v4);
+					break;
+				case 8:
+					*((int *)pHouse + 3) = *v4 == 121;
+					break;
+				case 9:
+					*((int *)pHouse + 5) = atoi(v4);
+					break;
+				case 10:
+					*((int *)pHouse + 6) = atoi(v4);
+					break;
+				case 11:
+					*((int *)pHouse + 7) = atoi(v4);
+					break;
+				case 12:
+					*((int *)pHouse + 8) = atoi(v4);
+					break;
+				case 13:
+					*((int *)pHouse + 9) = atoi(v4);
+					break;
+				case 14:
+					*((int *)pHouse + 10) = atoi(v4);
+					break;
+				default:
+					break;
+					}
+				}
+			++v36;
+			v4 = (char *)(v23 + 1);
+			}
+			while ( v36 + 1 <= 15 && !v32 );
+			Str += 4;
+			pHouse += 76;
+			--v24;
+		}
+		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
+			{
+			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
+				{
+				v14 = strtok(0, "\r") + 1;
+				v38 = 0;
+				v34 = 0;
+				do
+					{
+					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);
+					}
+					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
+					{
+					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;
+					}
+					while ( v27 );
+	}
+
+//----- (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;
+
+	Initialize1();
+	Initialize2();
+
+	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
+			{
+			v5 = *v4;
+			v6 = 0;
+			v14 = 0;
+			if ( *v4 == 9 )
+				goto LABEL_45;
+			do
+				{
+				if ( !v5 )
+					break;
+				if ( v5 == 10 )
+					break;
+				++v6;
+				v14 = v6;
+				v5 = v4[v6];
+				}
+				while ( v5 != 9 );
+				if ( v6 )
+					{
+					v4[v6] = 0;
+					if ( v20 )
+						{
+						if ( v20 == 1 )
+							*((int *)v16 + 1) = (int)RemoveQuotes(v4);
+						}
+					else
+						{
+						*(int *)v16 = (int)RemoveQuotes(v4);
+						}
+					}
+				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 ( v10 != 9 );
+					v8 = v19;
+				}
+			v15 = (int)&v9[v11];
+			if ( !v9[v11] )
+				v17 = 1;
+			*(char *)v15 = 0;
+			if ( v11 )
+				{
+				switch ( v21 )
+					{
+				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;
+					}
+				}
+			else
+				{
+				if ( !v21 )
+					v17 = 1;
+				}
+			++v21;
+			v9 = (char *)(v15 + 1);
+			}
+			while ( v21 <= 6 && !v17 );
+			v8 += 20;
+			v12 = v13-- == 1;
+			v19 = v8;
+		}
+		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;
+	}
+
+//----- (0047730C) --------------------------------------------------------
+int __fastcall const_1(int a1, int)
+	{
+	return 1;
+	}
+// 47730C: using guessed type int __stdcall const_1(int);
+
+//----- (0047732C) --------------------------------------------------------
+bool NPCStats::InitializeAdditionalNPCs(NPCData *a2, int a3, int a4, int a5)
+	{
+	//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
+	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
+
+
+	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;
+
+	while ( 1 )
+		{
+		if ( v20 == v10 )
+			{
+			if ( v7 == v10 )
+				{
+				v23 = 2;
+				a2 = (NPCData *)100;
+				}
+			else
+				{
+				if ( v7 - v10 == 1 )
+					{
+					v23 = 201;
+					a2 = (NPCData *)250;
+					}
+				}
+			}
+		else
+			{
+			switch ( v20 - v10 )
+				{
+			case 1:
+				if ( v7 == v10 )
+					{
+					v23 = 400;
+					a2 = (NPCData *)430;
+					}
+				else
+					{
+					if ( v7 - v10 == 1 )
+						{
+						v23 = 460;
+						a2 = (NPCData *)490;
+						}
+					}
+				break;
+			case 2:
+				if ( v7 == v10 )
+					{
+					v23 = 500;
+					a2 = (NPCData *)520;
+					}
+				else
+					{
+					if ( v7 - v10 == 1 )
+						{
+						v23 = 530;
+						a2 = (NPCData *)550;
+						}
+					}
+				break;
+			case 3:
+				if ( v7 == v10 )
+					{
+					v23 = 300;
+					a2 = (NPCData *)330;
+					}
+				else
+					{
+					if ( v7 - v10 == 1 )
+						{
+						v23 = 360;
+						a2 = (NPCData *)387;
+						}
+					}
+				break;
+				}
+			}
+		v12 = v23 + rand() % ((int)a2 - v23 + 1);
+		if ( const_1(v12, v7) == 1 )
+			v21 = 1;
+		++v22;
+		if ( v22 >= 4 )
+			{
+			v12 = v23;
+			v21 = 1;
+			}
+		if ( v21 )
+			break;
+		v10 = 0;
+		}
+
+	v9->uPortraitID = v12;
+	v9->uFlags = 0;
+	v9->fame = 0;
+	v13 = rand() % 100 + 1;
+
+	if ( v13 >= 60 )
+		{
+		if ( v13 >= 90 )
+			{
+			if ( v13 >= 95 )
+				{
+				if ( v13 >= 98 )
+					v9->rep = -600;
+				else
+					v9->rep = 400;
+				}
+			else
+				{
+				v9->rep = -300;
+				}
+			}
+		else
+			{
+			v9->rep = 200;
+			}
+		}
+	else
+		{
+		v9->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;
+
+	if ( v18 > 0 )
+		{
+		do
+		//v14 += *(char *)(v14 + v17++ + 0x16548);
+		v16 += array_16544[a5].field_4[v17++];
+		while ( v16 < v18 );
+		}
+	v9->uProfession = v17 - 1;
+	v9->house = a4;
+	v9->field_24 = 1;
+	v9->joins = 1;
+	return true;
+	}
+
+
+//----- (00476387) --------------------------------------------------------
+bool PartyHasDragon()
+{
+  return pNPCStats->pNewNPCData[57].Hired();
+}
+
+//----- (00476395) --------------------------------------------------------
+//0x26 Wizard eye at skill level 2
+bool __thiscall CheckHiredNPCSpeciality(unsigned int uProfession)
+	{
+	bool result; // eax@2
+	signed int v2; // esi@3
+	char *v3; // eax@4
+
+	if ( bNoNPCHiring == 1 )
+		return 0;
+	v2 = 0;
+	if ( (signed int)pNPCStats->uNumNewNPCs <= 0 )
+		{
+LABEL_8:
+		result = 0;
+		if ( pParty->pHirelings[0].uProfession != uProfession )
+			{
+			LOBYTE(result) = pParty->pHirelings[1].uProfession == uProfession;
+			return result;
+			}
+		}
+	else
+		{
+		v3 = (char *)&pNPCStats->pNewNPCData[0].uFlags;
+		while ( *((int *)v3 + 4) != uProfession || !(*v3 & 0x80) )
+			{
+			++v2;
+			v3 += 76;
+			if ( v2 >= (signed int)pNPCStats->uNumNewNPCs )
+				goto LABEL_8;
+			}
+		result = 0;
+		}
+	++result;
+	return result;
+	}
+// 6BE3C5: using guessed type char bNoNPCHiring;
+
+//----- (004763E0) --------------------------------------------------------
+void  InitializeAwards()
+	{
+
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+	int item_counter;
+
+	if ( pAwardsTXT_Raw )
+		pAllocator->FreeChunk(pAwardsTXT_Raw);
+	pAwardsTXT_Raw = NULL;
+	pAwardsTXT_Raw = (char *)pEvents_LOD->LoadRaw("awards.txt", 0);
+	strtok(pAwardsTXT_Raw, "\r");
+
+	for (i=1; i<104; ++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)
+				{
+				if (decode_step==1)
+					pAwards[i].pText=RemoveQuotes(test_string);
+				else if (decode_step==2)
+					pAwards[i].uSort=atoi(test_string);
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<3)&&!break_loop);
+		}
+
+	}
+// 7241C8: using guessed type int dword_7241C8;
+
+//----- (004764C2) --------------------------------------------------------
+void  InitializeScrolls()
+	{
+
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+	int item_counter;
+
+	if ( pScrollsTXT_Raw )
+		pAllocator->FreeChunk(pScrollsTXT_Raw);
+	pScrollsTXT_Raw = NULL;
+	pScrollsTXT_Raw = (char *)pEvents_LOD->LoadRaw("scroll.txt", 0);
+	strtok(pScrollsTXT_Raw, "\r");
+	for (i=0; i<82; ++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)
+				{
+				if ( decode_step == 1)
+					pScrolls[i]=RemoveQuotes(test_string);
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<2)&&!break_loop);
+		}
+	}
+
+
+//----- (00476590) --------------------------------------------------------
+void  InitializeMerchants()
+	{
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+	int item_counter;
+
+	if ( pMerchantsTXT_Raw )
+		pAllocator->FreeChunk(pMerchantsTXT_Raw);
+	pMerchantsTXT_Raw = NULL;
+	pMerchantsTXT_Raw = (char *)pEvents_LOD->LoadRaw("merchant.txt", 0);
+	strtok(pMerchantsTXT_Raw, "\r");
+
+	for (i=0; i<7; ++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)
+				{
+				switch (decode_step)
+					{
+				case 1:
+					pMerchantsBuyPhrases[i]=RemoveQuotes(test_string);
+					break;
+				case 2:
+					pMerchantsSellPhrases[i]=RemoveQuotes(test_string);
+					break;
+				case 3:
+					pMerchantsRepairPhrases[i]=RemoveQuotes(test_string); 
+					break;
+				case 4:
+					pMerchantsIdentifyPhrases[i]=RemoveQuotes(test_string); 
+					break;
+					}
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<5)&&!break_loop);
+		}
+
+	}
+
+//----- (00476682) --------------------------------------------------------
+void InitializeTransitions()
+	{
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+	int item_counter;
+
+	if ( pTransitionsTXT_Raw )
+		pAllocator->FreeChunk(pTransitionsTXT_Raw);
+	pTransitionsTXT_Raw = NULL;
+	pTransitionsTXT_Raw = (char *)pEvents_LOD->LoadRaw("trans.txt", 0);
+	strtok(pTransitionsTXT_Raw, "\r");
+
+	for (i=0; i<464; ++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)
+				{
+				if ( decode_step == 1)
+					pTransitionStrings[i]=RemoveQuotes(test_string);
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<2)&&!break_loop);
+		}
+	}
+
+//----- (00476750) --------------------------------------------------------
+void __cdecl InitializeAutonotes()
+	{
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+	int item_counter;
+
+	if ( pAutonoteTXT_Raw )
+		pAllocator->FreeChunk(pAutonoteTXT_Raw);
+	pAutonoteTXT_Raw = 0;
+	pAutonoteTXT_Raw = (char *)pEvents_LOD->LoadRaw("autonote.txt", 0);
+	strtok(pAutonoteTXT_Raw, "\r");
+
+	for (i=0; i<195; ++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)
+				{
+				switch (decode_step)
+					{
+				case  1:
+					pAutonoteTxt[i].pText=RemoveQuotes(test_string);
+					break;
+				case  2:
+					{
+					if ( !_strcmpi(test_string, "potion"))
+						{
+						pAutonoteTxt[i].eType = AUTONOTE_POTION_RECEPIE;
+						break;
+						}
+					if ( !_strcmpi(test_string, "stat") )
+						{
+						pAutonoteTxt[i].eType = AUTONOTE_STAT_HINT;
+						break;
+						}
+					if ( !_strcmpi(test_string, "seer") )
+						{
+						pAutonoteTxt[i].eType = AUTONOTE_SEER;
+						break;
+						}
+					if ( !_strcmpi(test_string, "obelisk") )
+						{
+						pAutonoteTxt[i].eType = AUTONOTE_OBELISK;
+						break;
+						}
+					if ( !_strcmpi(test_string, "teacher") )
+						{
+						pAutonoteTxt[i].eType = AUTONOTE_TEACHER;
+						break;
+						}
+					pAutonoteTxt[i].eType =AUTONOTE_MISC;
+					break;
+					}
+					}
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<3)&&!break_loop);
+		}
+	}
+
+
+//----- (004768A9) --------------------------------------------------------
+void __cdecl InitializeQuests()
+	{
+	int i;
+	char* test_string;
+	unsigned char c;
+	bool break_loop;
+	unsigned int temp_str_len;
+	char* tmp_pos;
+	int decode_step;
+	int item_counter;
+
+	if ( pQuestsTXT_Raw )
+		pAllocator->FreeChunk(pQuestsTXT_Raw);
+	pQuestsTXT_Raw = NULL;
+	pQuestsTXT_Raw = (char *)pEvents_LOD->LoadRaw("quests.txt", 0);
+	strtok(pQuestsTXT_Raw, "\r");
+
+	for (i=0; i<512; ++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)
+				{
+				if ( decode_step == 1)
+					pQuestTable[i] =RemoveQuotes(test_string);
+				}
+			else
+				{ 
+				break_loop = true;
+				}
+			++decode_step;
+			test_string=tmp_pos+1;
+			} while ((decode_step<2)&&!break_loop);
+		}
+	}
+
--- a/NPC.h	Mon Feb 18 12:38:07 2013 +0600
+++ b/NPC.h	Mon Feb 18 12:38:38 2013 +0600
@@ -128,3 +128,5 @@
 };
 #pragma pack(pop)
 
+bool PartyHasDragon();
+bool CheckHiredNPCSpeciality(unsigned int uProfession);
--- a/Player.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/Player.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -5758,7 +5758,7 @@
         }
         if ( CheckHiredNPCSpeciality(v5) )
           v2 += 4;
-        if ( v9->classType == PLAYER_CLASS_31 && PartyHasDragon() )
+        if ( v9->classType == PLAYER_CLASS_WARLOCK && PartyHasDragon() )
           v2 += 3;
 LABEL_86:
         if ( uSkillType <= PLAYER_SKILL_DARK )
--- a/Player.h	Mon Feb 18 12:38:07 2013 +0600
+++ b/Player.h	Mon Feb 18 12:38:38 2013 +0600
@@ -223,18 +223,41 @@
 enum PLAYER_CLASS_TYPE: unsigned __int8
 {
   PLAYER_CLASS_KNIGHT = 0,
+  PLAYER_CLASS_CHEVALIER = 1,
+  PLAYER_CLASS_CHAMPION = 2,
+  PLAYER_CLASS_BLACK_KNIGHT = 3,
   PLAYER_CLASS_THEIF = 4,
-  PLAYER_CLASS_BOUNTY_HUNTER = 0x7,
-  PLAYER_CLASS_MONK = 0x8,
-  PLAYER_CLASS_PALADIN = 0xC,
-  PLAYER_CLASS_SHOOTER = 0x10,
-  PLAYER_CLASS_RANGER = 0x14,
+  PLAYER_CLASS_ROGUE = 5,
+  PLAYER_CLASS_SPY = 6,
+  PLAYER_CLASS_ASSASSIN = 7,
+  PLAYER_CLASS_MONK = 8,
+  PLAYER_CLASS_INITIATE = 9,
+  PLAYER_CLASS_MASTER = 10,
+  PLAYER_CLASS_NINJA = 11,
+  PLAYER_CLASS_PALADIN = 12,
+  PLAYER_CLASS_CRUSADER = 13,
+  PLAYER_CLASS_HERO = 14,
+  PLAYER_CLASS_VILLIAN = 15,
+  PLAYER_CLASS_ARCHER = 16,
+  PLAYER_CLASS_WARRIOR_MAGE = 17,
+  PLAYER_CLASS_MASTER_ARCHER = 18,
+  PLAYER_CLASS_SNIPER = 19,
+  PLAYER_CLASS_RANGER = 20,
+  PLAYER_CLASS_HUNTER = 21,
+  PLAYER_CLASS_RANGER_LORD = 22,
+  PLAYER_CLASS_BOUNTY_HUNTER = 23,
   PLAYER_CLASS_CLERIC = 24,
-  PLAYER_CLASS_PRIEST_OF_MOON = 0x1B,
+  PLAYER_CLASS_PRIEST = 25,
+  PLAYER_CLASS_PRIEST_OF_SUN = 26,
+  PLAYER_CLASS_PRIEST_OF_MOON = 27,
   PLAYER_CLASS_DRUID = 28,
-  PLAYER_CLASS_31 = 31,
+  PLAYER_CLASS_GREAT_DRUID = 29,
+  PLAYER_CLASS_ARCH_DRUID = 30,
+  PLAYER_CLASS_WARLOCK = 31,
   PLAYER_CLASS_SORCERER = 32,
-  PLAYER_CLASS_LICH = 35,
+  PLAYER_CLASS_WIZARD = 33,
+  PLAYER_CLASS_ARCHMAGE = 34,
+  PLAYER_CLASS_LICH = 35
 };
 
 
--- a/VideoPlayer.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/VideoPlayer.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -295,9 +295,8 @@
   pVideoPlayer->bStopBeforeSchedule = false;
   pVideoPlayer->pResetflag = 0;
   bGameoverLoop = 1;
-  if ( !bNoVideo )
+  if (!bNoVideo)
   {
-    bNoVideo = 0;
     pRenderer->PresentBlackScreen();
     pGame->pCShow->PlayMovie(MOVIE_3DOLogo, 1);
     if ( !pVideoPlayer->bStopBeforeSchedule )
--- a/mm7_1.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/mm7_1.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -611,7 +611,7 @@
 //----- (0041A000) --------------------------------------------------------
 unsigned int __fastcall CharacterUI_AwardsTab_Draw(unsigned int uPlayerID)
 {
-  unsigned int v1; // esi@1
+  //unsigned int v1; // esi@1
   unsigned int v2; // ebx@1
   unsigned int v3; // eax@1
   unsigned int result; // eax@1
@@ -634,12 +634,13 @@
   int v21; // [sp+C8h] [bp-8h]@14
   int v22; // [sp+CCh] [bp-4h]@40
 
-  v1 = uPlayerID;
+  auto player = pParty->pPlayers + uPlayerID - 1;
+  //v1 = uPlayerID;
   v2 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0xFFu, 0x9Bu);
   v3 = pIcons_LOD->LoadTexture("fr_award", TEXTURE_16BIT_PALETTE);
-  pRenderer->DrawTextureIndexed(8u, 8u, (Texture *)(v3 != -1 ? (int)&pIcons_LOD->pTextures[v3] : 0));
-  sprintf(pTmpBuf, "%s \f%05d", pGlobalTXT_LocalizationStrings[23], v2);// TODO check args
-  sprintf(Source, pGlobalTXT_LocalizationStrings[429], &pParty->pPlayers[v1-1].pName, pClassNames[pParty->pPlayers[v1-1].classType]);
+  pRenderer->DrawTextureIndexed(8u, 8u, (Texture *)(v3 != -1 ? &pIcons_LOD->pTextures[v3] : 0));
+  sprintfex(pTmpBuf, "%s\xC" "%05d", pGlobalTXT_LocalizationStrings[23], v2);
+  sprintfex(Source, pGlobalTXT_LocalizationStrings[429], player->pName, pClassNames[player->classType]);
   strcat(pTmpBuf, Source);
   strcat(pTmpBuf, "\xC" "00000");
   pGUIWindow_CurrentMenu->DrawText(pFontArrus, 24, 18, 0, pTmpBuf, 0, 0, 0);
@@ -1054,7 +1055,7 @@
   v49 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0xFFu, 0, 0);
   v46 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(0, 0xFFu, 0);
   v1 = pIcons_LOD->LoadTexture("quikref", TEXTURE_16BIT_PALETTE);
-  pRenderer->DrawTextureIndexed(8u, 8u, (Texture *)(v1 != -1 ? (int)&pIcons_LOD->pTextures[v1] : 0));
+  pRenderer->DrawTextureIndexed(8u, 8u, (Texture *)(v1 != -1 ? &pIcons_LOD->pTextures[v1] : 0));
   v43 = 0;
   v45 = LOBYTE(pFontArrus->uFontHeight) + 1;
   do
@@ -3153,7 +3154,7 @@
     v37 = v112[6];
     if ( v37 )
     {
-      sprintfex(pTmpBuf, pGlobalTXT_LocalizationStrings[429], *v112, aNPCProfessionNames[(signed int)v37]);
+      sprintf(pTmpBuf, pGlobalTXT_LocalizationStrings[429], *v112, aNPCProfessionNames[(signed int)v37]);
     }
 	else
 	{
@@ -3467,10 +3468,21 @@
     a4 = &a4[LOBYTE(v56->uFontHeight) - 3];
     v57 = v121->pMonsterInfo.uAttack1DamageBonus;
     if ( v57 )
-      sprintf(pTmpBuf, "%s\f%05u\t080%dd%d+%d\n", pGlobalTXT_LocalizationStrings[53], 0, v121->pMonsterInfo.uAttack1DamageDiceRolls,
-        v121->pMonsterInfo.uAttack1DamageDiceSides, v57);
+      sprintf(
+        pTmpBuf,
+        "%s\f%05u\t080%dd%d+%d\n",
+        pGlobalTXT_LocalizationStrings[53],
+        0,
+        v121->pMonsterInfo.uAttack1DamageDiceRolls,
+        v121->pMonsterInfo.uAttack1DamageDiceSides,
+        v57);
     else
-      sprintf(pTmpBuf, "%s\f%05u\t080%dd%d\n", pGlobalTXT_LocalizationStrings[53], 0, v121->pMonsterInfo.uAttack1DamageDiceRolls,
+      sprintf(
+        pTmpBuf,
+        "%s\f%05u\t080%dd%d\n",
+        pGlobalTXT_LocalizationStrings[53],
+        0,
+        v121->pMonsterInfo.uAttack1DamageDiceRolls,
         v121->pMonsterInfo.uAttack1DamageDiceSides);
   }
   else
@@ -3696,7 +3708,7 @@
       if ( v0 > &pParty->pPlayers[3] )
         break;
     }
-	if(v0->classType == PLAYER_CLASS_31)
+	if(v0->classType == PLAYER_CLASS_WARLOCK)
 		++uRestUI_FoodRequiredToRest;
   }
   if ( CheckHiredNPCSpeciality(0x1Du) )
--- a/mm7_2.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/mm7_2.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -1463,7 +1463,7 @@
 LABEL_13:
                   v6 = uActiveCharacter - 1;
 LABEL_14:
-                  v7 = sub_495461(v5, v6, v79, (char *)v81, v83, v85);
+                  v7 = BuilDialogueString(v5, v6, v79, (char *)v81, v83, v85);
                   v86 = 3;
                   v84 = v7;
                   v82 = v105;
@@ -1862,7 +1862,7 @@
 LABEL_44:
         v39 = uActiveCharacter - 1;
 LABEL_45:
-        v21 = sub_495461(v38, v39, v87, (char *)v89, v91, v93);
+        v21 = BuilDialogueString(v38, v39, v87, (char *)v89, v91, v93);
         v92 = 3;
         v90 = v21;
         v88 = v108;
@@ -2429,7 +2429,7 @@
                   2,
                   (int)ptr_507BC0->ptr_1C,
                   2);
-          v100 = sub_495461((char *)pMerchantsBuyPhrases[v99], v97, v98, (char *)v96, 2, 0);
+          v100 = BuilDialogueString((char *)pMerchantsBuyPhrases[v99], v97, v98, (char *)v96, 2, 0);
           v101 = v100;
           v102 = v148;
           v103 = pFontArrus->CalcTextHeight(v100, &v144, 0, 0);
@@ -2759,7 +2759,7 @@
         v14 = uActiveCharacter - 1;
       }
 LABEL_36:
-      v36 = sub_495461(v15, v14, v116, (char *)v120, v122, v124);
+      v36 = BuilDialogueString(v15, v14, v116, (char *)v120, v122, v124);
       v123 = 3;
       v121 = v36;
       v119 = v148;
@@ -2911,7 +2911,7 @@
               v4 = uPlayerID;
               v5 = (char *)pMerchantsIdentifyPhrases[v8];
             }
-            v6 = sub_495461(v5, v4, v114, (char *)v118, 4, 0);
+            v6 = BuilDialogueString(v5, v4, v114, (char *)v118, 4, 0);
             v123 = 3;
             v121 = v6;
             v119 = v148;
@@ -13392,7 +13392,7 @@
   int a2[4]; // [sp+1Ch] [bp-10h]@15
 
   char test[1024];
-  sprintfex(test, "^Pi[%s]: ^R[;;]", "");
+  //sprintfex(test, "^Pi[%s]: ^R[;;]", "");
 
   if (pCmdLine && *pCmdLine)
   {
@@ -13411,7 +13411,7 @@
     bWalkSound = ReadWindowsRegistryInt("WalkSound", 1) != 0;
     if (wcsstr(pCmdLine, L"-nowalksound"))
       bWalkSound = false;//dword_6BE364_game_settings_1 |= 0x20;
-    if (wcsstr(pCmdLine, L"-noanim"))
+    if (wcsstr(pCmdLine, L"-novideo"))
     {
       dword_6BE364_game_settings_1 |= 0x40;
       bNoVideo = true;
--- a/mm7_3.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/mm7_3.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -4703,1188 +4703,9 @@
   return result;
 }
 
-//----- (00476387) --------------------------------------------------------
-bool PartyHasDragon()
-{
-  return pNPCStats->pNewNPCData[57].Hired();
-}
-
-//----- (00476395) --------------------------------------------------------
-//0x26 Wizard eye at skill level 2
-bool __thiscall CheckHiredNPCSpeciality(unsigned int uProfession)
-{
-  bool result; // eax@2
-  signed int v2; // esi@3
-  char *v3; // eax@4
-
-  if ( bNoNPCHiring == 1 )
-    return 0;
-  v2 = 0;
-  if ( (signed int)pNPCStats->uNumNewNPCs <= 0 )
-  {
-LABEL_8:
-    result = 0;
-    if ( pParty->pHirelings[0].uProfession != uProfession )
-    {
-      LOBYTE(result) = pParty->pHirelings[1].uProfession == uProfession;
-      return result;
-    }
-  }
-  else
-  {
-    v3 = (char *)&pNPCStats->pNewNPCData[0].uFlags;
-    while ( *((int *)v3 + 4) != uProfession || !(*v3 & 0x80) )
-    {
-      ++v2;
-      v3 += 76;
-      if ( v2 >= (signed int)pNPCStats->uNumNewNPCs )
-        goto LABEL_8;
-    }
-    result = 0;
-  }
-  ++result;
-  return result;
-}
-// 6BE3C5: using guessed type char bNoNPCHiring;
-
-//----- (004763E0) --------------------------------------------------------
-void  InitializeAwards()
-{
-  
-  int i;
-  char* test_string;
-  unsigned char c;
-  bool break_loop;
-  unsigned int temp_str_len;
-  char* tmp_pos;
-  int decode_step;
-  int item_counter;
-
-  if ( pAwardsTXT_Raw )
-    pAllocator->FreeChunk(pAwardsTXT_Raw);
-  pAwardsTXT_Raw = NULL;
-  pAwardsTXT_Raw = (char *)pEvents_LOD->LoadRaw("awards.txt", 0);
-  strtok(pAwardsTXT_Raw, "\r");
-
-  for (i=1; i<104; ++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)
-			  {
-			   if (decode_step==1)
-				  pAwards[i].pText=RemoveQuotes(test_string);
-			   else if (decode_step==2)
-				  pAwards[i].uSort=atoi(test_string);
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<3)&&!break_loop);
-	  }
-
-}
-// 7241C8: using guessed type int dword_7241C8;
-
-//----- (004764C2) --------------------------------------------------------
-void  InitializeScrolls()
-{
-  
-  int i;
-  char* test_string;
-  unsigned char c;
-  bool break_loop;
-  unsigned int temp_str_len;
-  char* tmp_pos;
-  int decode_step;
-  int item_counter;
-
-  if ( pScrollsTXT_Raw )
-    pAllocator->FreeChunk(pScrollsTXT_Raw);
-  pScrollsTXT_Raw = NULL;
-  pScrollsTXT_Raw = (char *)pEvents_LOD->LoadRaw("scroll.txt", 0);
-  strtok(pScrollsTXT_Raw, "\r");
-  for (i=0; i<82; ++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)
-			  {
-			  if ( decode_step == 1)
-				 pScrolls[i]=RemoveQuotes(test_string);
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<2)&&!break_loop);
-	  }
-}
-
-
-//----- (00476590) --------------------------------------------------------
-void  InitializeMerchants()
-{
-  int i;
-  char* test_string;
-  unsigned char c;
-  bool break_loop;
-  unsigned int temp_str_len;
-  char* tmp_pos;
-  int decode_step;
-  int item_counter;
-
-  if ( pMerchantsTXT_Raw )
-    pAllocator->FreeChunk(pMerchantsTXT_Raw);
-  pMerchantsTXT_Raw = NULL;
-  pMerchantsTXT_Raw = (char *)pEvents_LOD->LoadRaw("merchant.txt", 0);
-  strtok(pMerchantsTXT_Raw, "\r");
-
-  for (i=0; i<7; ++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)
-			  {
-				switch (decode_step)
-					{
-					case 1:
-						pMerchantsBuyPhrases[i]=RemoveQuotes(test_string);
-						break;
-					case 2:
-						pMerchantsSellPhrases[i]=RemoveQuotes(test_string);
-						break;
-					case 3:
-						pMerchantsRepairPhrases[i]=RemoveQuotes(test_string); 
-						break;
-					case 4:
-						pMerchantsIdentifyPhrases[i]=RemoveQuotes(test_string); 
-						break;
-					}
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<5)&&!break_loop);
-	  }
-
-}
-
-//----- (00476682) --------------------------------------------------------
-void InitializeTransitions()
-{
-  int i;
-  char* test_string;
-  unsigned char c;
-  bool break_loop;
-  unsigned int temp_str_len;
-  char* tmp_pos;
-  int decode_step;
-  int item_counter;
-
-  if ( pTransitionsTXT_Raw )
-    pAllocator->FreeChunk(pTransitionsTXT_Raw);
-  pTransitionsTXT_Raw = NULL;
-  pTransitionsTXT_Raw = (char *)pEvents_LOD->LoadRaw("trans.txt", 0);
-  strtok(pTransitionsTXT_Raw, "\r");
-
-  for (i=0; i<464; ++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)
-			  {
-			  if ( decode_step == 1)
-				 pTransitionStrings[i]=RemoveQuotes(test_string);
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<2)&&!break_loop);
-	  }
-}
-
-//----- (00476750) --------------------------------------------------------
-void __cdecl InitializeAutonotes()
-{
-  int i;
-  char* test_string;
-  unsigned char c;
-  bool break_loop;
-  unsigned int temp_str_len;
-  char* tmp_pos;
-  int decode_step;
-  int item_counter;
-
-  if ( pAutonoteTXT_Raw )
-    pAllocator->FreeChunk(pAutonoteTXT_Raw);
-  pAutonoteTXT_Raw = 0;
-  pAutonoteTXT_Raw = (char *)pEvents_LOD->LoadRaw("autonote.txt", 0);
-  strtok(pAutonoteTXT_Raw, "\r");
-
-  for (i=0; i<195; ++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)
-			  {
-			  switch (decode_step)
-				  {
-			  case  1:
-				  pAutonoteTxt[i].pText=RemoveQuotes(test_string);
-				  break;
-			  case  2:
-				  {
-				  if ( !_strcmpi(test_string, "potion"))
-					  {
-					  pAutonoteTxt[i].eType = AUTONOTE_POTION_RECEPIE;
-					  break;
-					  }
-				  if ( !_strcmpi(test_string, "stat") )
-					  {
-					  pAutonoteTxt[i].eType = AUTONOTE_STAT_HINT;
-					  break;
-					  }
-				  if ( !_strcmpi(test_string, "seer") )
-					  {
-					  pAutonoteTxt[i].eType = AUTONOTE_SEER;
-					  break;
-					  }
-				  if ( !_strcmpi(test_string, "obelisk") )
-					  {
-					  pAutonoteTxt[i].eType = AUTONOTE_OBELISK;
-					  break;
-					  }
-				  if ( !_strcmpi(test_string, "teacher") )
-					  {
-					  pAutonoteTxt[i].eType = AUTONOTE_TEACHER;
-					  break;
-					  }
-				  pAutonoteTxt[i].eType =AUTONOTE_MISC;
-				  break;
-				  }
-				  }
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<3)&&!break_loop);
-	  }
-}
-
-
-//----- (004768A9) --------------------------------------------------------
-void __cdecl InitializeQuests()
-{
-   int i;
-  char* test_string;
-  unsigned char c;
-  bool break_loop;
-  unsigned int temp_str_len;
-  char* tmp_pos;
-  int decode_step;
-  int item_counter;
-
-  if ( pQuestsTXT_Raw )
-    pAllocator->FreeChunk(pQuestsTXT_Raw);
-  pQuestsTXT_Raw = NULL;
-  pQuestsTXT_Raw = (char *)pEvents_LOD->LoadRaw("quests.txt", 0);
-  strtok(pQuestsTXT_Raw, "\r");
-
-  for (i=0; i<512; ++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)
-			  {
-			  if ( decode_step == 1)
-				 pQuestTable[i] =RemoveQuotes(test_string);
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<2)&&!break_loop);
-	  }
-}
-
-
-
-//----- (00476977) --------------------------------------------------------
-void NPCStats::Initialize2()
-{
-  int i;
-  char* test_string;
-  unsigned char c;
-  bool break_loop;
-  unsigned int temp_str_len;
-  char* tmp_pos;
-  int decode_step;
-  int item_counter;
-
-
-  if (pNPCTextTXT_Raw)
-    pAllocator->FreeChunk(pNPCTextTXT_Raw);
-  pNPCTextTXT_Raw =NULL;
-  pNPCTextTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctext.txt", 0);
-  strtok(pNPCTextTXT_Raw, "\r");
-
-  for (i=0; i<789; ++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)
-			  {
-			  if ( decode_step == 1)
-				 pNPCTopics[i].pText =RemoveQuotes(test_string);
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<2)&&!break_loop);
-	  }
-
-  if (pNPCTopicTXT_Raw)
-    pAllocator->FreeChunk(pNPCTopicTXT_Raw);
-  pNPCTopicTXT_Raw =NULL;
-  pNPCTopicTXT_Raw = (char *)pEvents_LOD->LoadRaw("npctopic.txt", 0);
-  strtok(pNPCTopicTXT_Raw, "\r");
-
-   for (i=0; i<579; ++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)
-			  {
-			  if ( decode_step == 1)
-				 pNPCTopics[i].pTopic = RemoveQuotes(test_string);
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<2)&&!break_loop);
-	  }
-
-  if (pNPCDistTXT_Raw)
-    pAllocator->FreeChunk(pNPCDistTXT_Raw);
-  pNPCDistTXT_Raw = NULL;
-  pNPCDistTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcdist.txt", 0);
-  strtok(pNPCDistTXT_Raw, "\r");
-  strtok(NULL, "\r");
-
-   for (i=1; i<59; ++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)
-			  {
-			   if ((decode_step>0)&&(decode_step<77))
-				   {
-				   array_16544[decode_step].field_4[i]=atoi(test_string);
-				   }
-			   else if (decode_step==0)
-				   {
-				  array_16544[0].field_4[i]=10;
-				   }
-			  }
-		  else
-			  { 
-			  break_loop = true;
-			  }
-		  ++decode_step;
-		  test_string=tmp_pos+1;
-		  } while ((decode_step<78)&&!break_loop);
-	  }
-
-  for (i=0; i<78; ++i)
-	  {
-	  array_16544[i].field_0=0;
-	  for (int ii=1; ii<59; ++ii)
-		  {
-		  array_16544[i].field_0+=array_16544[i].field_4[ii];
-		  }
-	  }
-
-  if (pNPCDistTXT_Raw)
-  {
-    pAllocator->FreeChunk(pNPCDistTXT_Raw);
-    pNPCDistTXT_Raw = NULL;
-  }
-}
-
-//----- (00476C60) --------------------------------------------------------
-void NPCStats::_476C60()
-{
-  for (uint i = 1; i < uNumNewNPCs; ++i)
-    pNewNPCData[i].pName = pNPCNames2[i - 1];
-
-  if (pParty->pHirelings[0].pName)
-    pParty->pHirelings[0].pName = pParty->pHireling1Name;
-  if (pParty->pHirelings[1].pName)
-    pParty->pHirelings[1].pName = pParty->pHireling2Name;
-}
-
-//----- (00476CB5) --------------------------------------------------------
-void NPCStats::Initialize1()
-{
-  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
-
-  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
-  {
-    v32 = 0;
-    v4 = strtok(0, "\r") + 1;
-    v36 = -1;
-    do
-    {
-      v5 = *v4;
-      v6 = 0;
-      while ( v5 != 9 && v5 )
-      {
-        ++v6;
-        v5 = v4[v6];
-      }
-      v23 = (int)&v4[v6];
-      if ( !v4[v6] )
-        v32 = 1;
-      v4[v6] = 0;
-      if ( v6 )
-      {
-        switch ( v36 )
-        {
-          case 0:
-            v7 = RemoveQuotes(v4);
-            *((int *)pHouse - 5) = (int)v7;
-            *(int *)Str = (int)v7;
-            break;
-          case 1:
-            *((int *)pHouse - 4) = atoi(v4);
-            break;
-          case 5:
-            *(int *)pHouse = atoi(v4);
-            break;
-          case 6:
-            *((int *)pHouse + 1) = atoi(v4);
-            break;
-          case 7:
-            *((int *)pHouse + 2) = atoi(v4);
-            break;
-          case 8:
-            *((int *)pHouse + 3) = *v4 == 121;
-            break;
-          case 9:
-            *((int *)pHouse + 5) = atoi(v4);
-            break;
-          case 10:
-            *((int *)pHouse + 6) = atoi(v4);
-            break;
-          case 11:
-            *((int *)pHouse + 7) = atoi(v4);
-            break;
-          case 12:
-            *((int *)pHouse + 8) = atoi(v4);
-            break;
-          case 13:
-            *((int *)pHouse + 9) = atoi(v4);
-            break;
-          case 14:
-            *((int *)pHouse + 10) = atoi(v4);
-            break;
-          default:
-            break;
-        }
-      }
-      ++v36;
-      v4 = (char *)(v23 + 1);
-    }
-    while ( v36 + 1 <= 15 && !v32 );
-    Str += 4;
-    pHouse += 76;
-    --v24;
-  }
-  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
-  {
-    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
-  {
-    v14 = strtok(0, "\r") + 1;
-    v38 = 0;
-    v34 = 0;
-    do
-    {
-      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);
-    }
-    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
-  {
-    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;
-  }
-  while ( v27 );
-}
-
-//----- (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;
-
-  Initialize1();
-  Initialize2();
-
-  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
-    {
-      v5 = *v4;
-      v6 = 0;
-      v14 = 0;
-      if ( *v4 == 9 )
-        goto LABEL_45;
-      do
-      {
-        if ( !v5 )
-          break;
-        if ( v5 == 10 )
-          break;
-        ++v6;
-        v14 = v6;
-        v5 = v4[v6];
-      }
-      while ( v5 != 9 );
-      if ( v6 )
-      {
-        v4[v6] = 0;
-        if ( v20 )
-        {
-          if ( v20 == 1 )
-            *((int *)v16 + 1) = (int)RemoveQuotes(v4);
-        }
-        else
-        {
-          *(int *)v16 = (int)RemoveQuotes(v4);
-        }
-      }
-      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 ( v10 != 9 );
-        v8 = v19;
-      }
-      v15 = (int)&v9[v11];
-      if ( !v9[v11] )
-        v17 = 1;
-      *(char *)v15 = 0;
-      if ( v11 )
-      {
-        switch ( v21 )
-        {
-          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;
-        }
-      }
-      else
-      {
-        if ( !v21 )
-          v17 = 1;
-      }
-      ++v21;
-      v9 = (char *)(v15 + 1);
-    }
-    while ( v21 <= 6 && !v17 );
-    v8 += 20;
-    v12 = v13-- == 1;
-    v19 = v8;
-  }
-  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;
-}
-
-//----- (0047730C) --------------------------------------------------------
-int __fastcall const_1(int a1, int)
-{
-  return 1;
-}
-// 47730C: using guessed type int __stdcall const_1(int);
-
-//----- (0047732C) --------------------------------------------------------
-bool NPCStats::InitializeAdditionalNPCs(NPCData *a2, int a3, int a4, int a5)
-{
-  //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
-  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
-
-
-  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;
-
-  while ( 1 )
-  {
-    if ( v20 == v10 )
-    {
-      if ( v7 == v10 )
-      {
-        v23 = 2;
-        a2 = (NPCData *)100;
-      }
-      else
-      {
-        if ( v7 - v10 == 1 )
-        {
-          v23 = 201;
-          a2 = (NPCData *)250;
-        }
-      }
-    }
-    else
-    {
-      switch ( v20 - v10 )
-      {
-        case 1:
-          if ( v7 == v10 )
-          {
-            v23 = 400;
-            a2 = (NPCData *)430;
-          }
-          else
-          {
-            if ( v7 - v10 == 1 )
-            {
-              v23 = 460;
-              a2 = (NPCData *)490;
-            }
-          }
-          break;
-        case 2:
-          if ( v7 == v10 )
-          {
-            v23 = 500;
-            a2 = (NPCData *)520;
-          }
-          else
-          {
-            if ( v7 - v10 == 1 )
-            {
-              v23 = 530;
-              a2 = (NPCData *)550;
-            }
-          }
-          break;
-        case 3:
-          if ( v7 == v10 )
-          {
-            v23 = 300;
-            a2 = (NPCData *)330;
-          }
-          else
-          {
-            if ( v7 - v10 == 1 )
-            {
-              v23 = 360;
-              a2 = (NPCData *)387;
-            }
-          }
-          break;
-      }
-    }
-    v12 = v23 + rand() % ((int)a2 - v23 + 1);
-    if ( const_1(v12, v7) == 1 )
-      v21 = 1;
-    ++v22;
-    if ( v22 >= 4 )
-    {
-      v12 = v23;
-      v21 = 1;
-    }
-    if ( v21 )
-      break;
-    v10 = 0;
-  }
-
-  v9->uPortraitID = v12;
-  v9->uFlags = 0;
-  v9->fame = 0;
-  v13 = rand() % 100 + 1;
-
-  if ( v13 >= 60 )
-  {
-    if ( v13 >= 90 )
-    {
-      if ( v13 >= 95 )
-      {
-        if ( v13 >= 98 )
-          v9->rep = -600;
-        else
-          v9->rep = 400;
-      }
-      else
-      {
-        v9->rep = -300;
-      }
-    }
-    else
-    {
-      v9->rep = 200;
-    }
-  }
-  else
-  {
-    v9->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;
-  
-  if ( v18 > 0 )
-  {
-    do
-      //v14 += *(char *)(v14 + v17++ + 0x16548);
-      v16 += array_16544[a5].field_4[v17++];
-    while ( v16 < v18 );
-  }
-  v9->uProfession = v17 - 1;
-  v9->house = a4;
-  v9->field_24 = 1;
-  v9->joins = 1;
-  return true;
-}
+
+
+
 // 47730C: using guessed type int __stdcall const_1(int);
 
 //----- (0047752B) --------------------------------------------------------
@@ -16297,7 +15118,7 @@
           if (dialogue_show_profession_details)
           {
             v6 = pNPCStats->pProfessions[pNPC->uProfession - 1].pBenefits;
-            v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
+            v7 = BuilDialogueString(v6, uActiveCharacter - 1, 0, 0, 0, 0);
             pInString = v7;
             pWindow.uFrameWidth = 460;
             pWindow.uFrameZ = 452;
@@ -16317,7 +15138,7 @@
           else if (pNPC->Hired())
           {
             v6 = pNPCStats->pProfessions[pNPC->uProfession - 1].pDismissText;
-            v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
+            v7 = BuilDialogueString(v6, uActiveCharacter - 1, 0, 0, 0, 0);
             pInString = v7;
             pWindow.uFrameWidth = 460;
             pWindow.uFrameZ = 452;
@@ -16337,7 +15158,7 @@
 		  else
 		  {
             v6 = pNPCStats->pProfessions[pNPC->uProfession - 1].pJoinText;
-			v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
+			v7 = BuilDialogueString(v6, uActiveCharacter - 1, 0, 0, 0, 0);
 			pInString = v7;
 			pWindow.uFrameWidth = 460;
 			pWindow.uFrameZ = 452;
@@ -16439,7 +15260,7 @@
     else if ( uDialogueType == DIALOGUE_13 )
     {
       v6 = pNPCStats->pProfessions[pNPC->uProfession - 1].pJoinText;
-      v7 = sub_495461(v6, uActiveCharacter - 1, 0, 0, 0, 0);
+      v7 = BuilDialogueString(v6, uActiveCharacter - 1, 0, 0, 0, 0);
       pInString = v7;
       pWindow.uFrameWidth = 460;
       pWindow.uFrameZ = 452;
@@ -16514,7 +15335,7 @@
 					v9 = pNPCStats->pProfessions[pNPC->uProfession].pDismissText;
 				else
 					v9 = pNPCStats->pProfessions[pNPC->uProfession].pJoinText; //"Invalid String Passed"
-				pInString = sub_495461(v9, uActiveCharacter - 1, 0, 0, 0, 0);
+				pInString = BuilDialogueString(v9, uActiveCharacter - 1, 0, 0, 0, 0);
 				if (  pInString != NULL )
 				{
 					pWindow.uFrameWidth = 460;
--- a/mm7_4.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/mm7_4.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -3530,7 +3530,7 @@
     v45 = 0;
     v48 = 0;
     v46 = 0;
-    if ( v44 && v21->classType == PLAYER_CLASS_31 )
+    if ( v44 && v21->classType == PLAYER_CLASS_WARLOCK )
       v50 = 1;
     if ( v21->classType == PLAYER_CLASS_LICH )
       v48 = 1;
@@ -4836,18 +4836,18 @@
 }
 
 //----- (00495461) --------------------------------------------------------
-char *__fastcall sub_495461(char *lpsz, unsigned __int8 uPlayerID, ItemGen *a3, char *a4, int a5, __int64 *a6)
+char *BuilDialogueString(char *lpsz, unsigned __int8 uPlayerID, ItemGen *a3, char *a4, int a5, __int64 *a6)
 {
   unsigned __int8 v6; // bl@1
   Player *pPlayer; // ebx@3
-  NPCData *v9; // eax@4
+  //NPCData *v9; // eax@4
   //size_t v10; // eax@6
   char *v11; // esi@7
-  int v12; // edx@7
-  ItemGen *v13; // edi@7
-  char v14; // cl@8
-  char *v15; // ecx@10
-  int v16; // edx@10
+  //int v12; // edx@7
+  //ItemGen *v13; // edi@7
+  //char v14; // cl@8
+  //char *v15; // ecx@10
+  //int v16; // edx@10
   int v17; // eax@10
   signed __int64 v18; // qax@18
   unsigned int v19; // edi@32
@@ -4891,76 +4891,74 @@
   stru351 v57; // [sp+9Ch] [bp-9Ch]@115
   char a1[100]; // [sp+B8h] [bp-80h]@3
   unsigned int v59; // [sp+11Ch] [bp-1Ch]@3
-  size_t v60; // [sp+120h] [bp-18h]@3
+  //size_t v60; // [sp+120h] [bp-18h]@3
   //Player *v61; // [sp+124h] [bp-14h]@3
   //char *Str; // [sp+128h] [bp-10h]@1
   int v63; // [sp+12Ch] [bp-Ch]@32
-  int v64; // [sp+130h] [bp-8h]@6
-  NPCData *v65; // [sp+134h] [bp-4h]@6
+  //int v64; // [sp+130h] [bp-8h]@6
+  //NPCData *v65; // [sp+134h] [bp-4h]@6
+  //int packed;
+
+
 
   v6 = uPlayerID;
   //Str = lpsz;
   if ( IsBadStringPtrA(lpsz, 1u) )
     return "Invalid String Passed";
-  v60 = strlen(lpsz);
+
   a1[0] = 0;
   pPlayer = &pParty->pPlayers[v6];
   v59 = GenerateColorAsCloseAsPossibleToR8G8B8InTargetFormat(255, 255, 155);
   //v61 = pPlayer;
-  memset(pTmpBuf2, 0, 0x7D0u);
+  memset(pTmpBuf2, 0, sizeof(pTmpBuf2));
+
+  NPCData *npc = nullptr;
   if ( dword_5C35D4 )
   {
     __debugbreak(); // fix
-    v9 = array_5913D8[(unsigned int)((char *)array_5913D8[6] + -(dword_591080 != 0) - 1)];
-  }
-  else
-    v9 = GetNPCData(uDialogue_SpeakingActorNPC_ID);
-  v65 = v9;
+    npc = array_5913D8[(unsigned int)((char *)array_5913D8[6] + -(dword_591080 != 0) - 1)];
+  }
+  else
+    npc = GetNPCData(uDialogue_SpeakingActorNPC_ID);
+  //v65 = v9;
   //v10 = 0;
-  v64 = 0;
-
-  int i = 0;
-  if ( (signed int)v60 > 0 )
-  {
-    v11 = a4;
-    v12 = v64;
-    v13 = a3;
-    while ( 1 )
-    {
-      v14 = lpsz[v12];
-      if ( v14 == '%' )
-        break;
-      pTmpBuf2[i++] = v14;
-LABEL_119:
-      ++v12;
-      v64 = v12;
-      if ( v12 >= (signed int)v60 )
-        return pTmpBuf2;
-    }
-    v15 = &lpsz[v12 + 1];
-    v16 = (unsigned __int8)lpsz[v12 + 2];
-    v17 = v16 + 10 * (unsigned __int8)*v15 - 528;
-
-    if ( v17 <= 15 )
-    {
-      if ( v17 != 15 )
-      {
-        switch ( v16 + 10 * (unsigned __int8)*v15 )
-        {
-          case 0x211:
-            v11 = v65->pName;
-            goto LABEL_118;
-          case 0x212:
+  //v64 = 0;
+
+  //int i = 0;
+  //if ( (signed int)v60 > 0 )
+  v11 = a4;
+
+  auto len = strlen(lpsz);
+  for (int i = 0, dst = 0; i < len; ++i)
+  {
+    //v12 = v64;
+    //v13 = a3;
+    //while ( 1 )
+    //{
+    char c = lpsz[i];
+    if (c != '%')
+      pTmpBuf2[dst++] = c;
+    else
+    {
+        //v15 = &lpsz[v12 + 1];
+        //v16 = (unsigned __int8)lpsz[v12 + 2];
+        //packed = 10 * (int)lpsz[v12 + 1] + lpsz[v12 + 2];
+        //v17 = packed - 528;// 10 * '0' + '0'
+      v17 = 10 * (int)(lpsz[i + 1] - '0') + lpsz[i + 2] - '0';
+
+      switch ( v17 )
+      {
+        case 1:
+          v11 = npc->pName;
+        goto _continue_strcat;
+          case 2:
             v11 = pPlayer->pName;
-            goto LABEL_118;
-          case 0x213:
-          case 0x219:
-            if ( v65->uSex )
-              v11 = pGlobalTXT_LocalizationStrings[384];// "her"
-            else
-              v11 = pGlobalTXT_LocalizationStrings[383];// "his"
-            goto LABEL_118;
-          case 0x215:
+            goto _continue_strcat;
+          case 3:
+          case 4:
+            v11 = a1;
+            goto _continue_strcat;
+          case 5:
             v18 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 60 / 60 % 24;
             v11 = pGlobalTXT_LocalizationStrings[397];// "evening"
             if ( SHIDWORD(v18) <= 0 && SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 5 && SHIDWORD(v18) <= 0 )
@@ -4975,19 +4973,20 @@
                 v11 = pGlobalTXT_LocalizationStrings[395];// "morning"
               }
             }
-            goto LABEL_118;
-          case 0x216:
+            goto _continue_strcat;
+          case 6:
             if ( pPlayer->uSex )
               v11 = pGlobalTXT_LocalizationStrings[387];// "lady"
             else
               v11 = pGlobalTXT_LocalizationStrings[385];// "sir"
-            goto LABEL_118;
-          case 0x217:
+            goto _continue_strcat;
+          case 7:
             if ( pPlayer->uSex )
-              goto LABEL_43;
-            v11 = pGlobalTXT_LocalizationStrings[386];// "Sir"
-            goto LABEL_118;
-          case 0x218:
+              v11 = pGlobalTXT_LocalizationStrings[389];// "Lady"
+            else
+              v11 = pGlobalTXT_LocalizationStrings[386];// "Sir"
+            goto _continue_strcat;
+          case 8:
             v19 = 0;
             v63 = 0;
             v20 = (unsigned __int8 *)pPlayer->field_152;
@@ -5019,20 +5018,25 @@
               v11 = (char *)pNPCTopics[55].pText;
             }
             //pPlayer = v61;
-            v13 = a3;
-            goto LABEL_118;
-          case 0x21A:
+            //v13 = a3;
+            goto _continue_strcat;
+          case 9:
+            if ( npc->uSex )
+              v11 = pGlobalTXT_LocalizationStrings[384];// "her"
+            else
+              v11 = pGlobalTXT_LocalizationStrings[383];// "his"
+            goto _continue_strcat;
+          case 10:
             if ( pPlayer->uSex )
-LABEL_43:
               v11 = pGlobalTXT_LocalizationStrings[389];// "Lady"
             else
               v11 = pGlobalTXT_LocalizationStrings[388];// "Lord"
-            goto LABEL_118;
-          case 0x21B:
+            goto _continue_strcat;
+          case 11:
             v25 = GetPartyReputation();
             goto LABEL_46;
-          case 0x21C:
-            v25 = v65->rep;
+          case 12:
+            v25 = npc->rep;
 LABEL_46:
             if ( v25 >= 25 )
             {
@@ -5059,79 +5063,91 @@
                 v11 = pGlobalTXT_LocalizationStrings[392];
               }
             }
-            goto LABEL_118;
-          case 0x21D:
+            goto _continue_strcat;
+          case 13:
             v11 = sub_495366(pPlayer->pName[0], pPlayer->uSex);
-            goto LABEL_118;
-          case 0x21E:
-            goto LABEL_93;
-          case 0x214:
+            goto _continue_strcat;
+          case 14:
+            {
+              if ( npc->uSex )
+                v11 = pGlobalTXT_LocalizationStrings[391];// "sister"
+              else
+                v11 = pGlobalTXT_LocalizationStrings[390];// "brother"
+              goto _continue_strcat;
+            }
+
+          case 15:
+          {
+            v11 = pGlobalTXT_LocalizationStrings[393];// "daughter"
+_continue_strcat:
+            strcat(pTmpBuf2, v11);
+            dst = strlen(pTmpBuf2);
+            //v64 += 2;
+            i += 2;
+          }
+          break;
+
+          case 16:
+          {
+            if ( npc->uSex )
+              v11 = pGlobalTXT_LocalizationStrings[391];// "sister"
+            else
+              v11 = pGlobalTXT_LocalizationStrings[390];// "brother"
+            goto _continue_strcat;
+          }
+          case 17:
+          {
+            auto pay_percentage = pNPCStats->pProfessions[npc->uProfession - 1].uHirePrice / 100;
+            if (!pay_percentage)
+              pay_percentage = 1;
+
+            sprintf(a1, "%lu", pay_percentage);
             v11 = a1;
-            goto LABEL_118;
-          default:
-            goto LABEL_108;
-        }
-        goto LABEL_108;
-      }
-      v11 = pGlobalTXT_LocalizationStrings[393];// "daughter"
-LABEL_118:
-      strcat(pTmpBuf2, v11);
-      i = strlen(pTmpBuf2);
-      v64 += 2;
-      v12 = v64;
-      goto LABEL_119;
-    }
-    if ( v17 <= 29 )
-    {
-      if ( v17 == 29 )
-      {
-        //v34 = p2DEvents_minus1__20[13 * (signed int)a4];
-        v34 = p2DEvents[(signed int)a4 - 1].fPriceMultiplier;
-      }
-      else
-      {
-        if ( v16 + 10 * (unsigned __int8)*v15 == 544 )
-        {
-LABEL_93:
-          if ( v65->uSex )
-            v11 = pGlobalTXT_LocalizationStrings[391];// "sister"
-          else
-            v11 = pGlobalTXT_LocalizationStrings[390];// "brother"
-          goto LABEL_118;
-        }
-        if ( v16 + 10 * (unsigned __int8)*v15 == 545 )
-        {
-          v29 = *(&pNPCStats->field_13A58 + 5 * v65->uProfession) / 100;
-          goto LABEL_91;
-        }
-        if ( v16 + 10 * (unsigned __int8)*v15 == 551 )
-        {
-          v47 = pMapStats->GetMapInfo(pCurrentMapName);
-          if ( v47 )
-            v11 = pMapStats->pInfos[v47].pName;
-          else
-            v11 = pGlobalTXT_LocalizationStrings[394];// "Unknown"
-          goto LABEL_118;
-        }
-        if ( v16 + 10 * (unsigned __int8)*v15 == 552 )
-        {
-          v46 = v13->GetDisplayName();
-          sprintf(a1, format_4E2D80, v59, v46);
+            goto _continue_strcat;
+          }
+
+          case 18:
+          case 19:
+          case 20:
+          case 21:
+          case 22:
+          case 26:
+_continue_strncpy:
+            strncpy(a1, lpsz + i + 1, 2);
+          v51 = atoi(a1);
+          sprintf(a1, "%lu", v51);
           v11 = a1;
-          goto LABEL_118;
-        }
-        if ( v16 + 10 * (unsigned __int8)*v15 == 553 )
-        {
-          //v37 = &p2DEvents_minus1__20[13 * (signed int)a4];
-          v37 = &p2DEvents[(signed int)a4 - 1].fPriceMultiplier;
-          v38 = *v37;
-          v39 = v13->GetValue();
-          v29 = pPlayer->_4B8233(v39, v38);
+          goto _continue_strcat;
+
+          case 23:
+          {
+            v47 = pMapStats->GetMapInfo(pCurrentMapName);
+            if ( v47 )
+              v11 = pMapStats->pInfos[v47].pName;
+            else
+              v11 = pGlobalTXT_LocalizationStrings[394];// "Unknown"
+            goto _continue_strcat;
+          }
+          case 24:
+          {
+            v46 = a3->GetDisplayName();
+            sprintf(a1, format_4E2D80, v59, v46);
+            v11 = a1;
+            goto _continue_strcat;
+          }
+
+
+          case 25:
+          {
+            v37 = &p2DEvents[(signed int)a4 - 1].fPriceMultiplier;
+            v38 = *v37;
+            v39 = a3->GetValue();
+            v29 = pPlayer->_4B8233(v39, v38);
           switch ( a5 )
           {
             case 3:
               v44 = *v37;
-              v45 = v13->GetValue();
+              v45 = a3->GetValue();
               v29 = pPlayer->_4B8213(v45, v44);
               break;
             case 4:
@@ -5139,55 +5155,39 @@
               break;
             case 5:
               v42 = *v37;
-              v43 = v13->GetValue();
+              v43 = a3->GetValue();
               v29 = pPlayer->_4B8265(v43, v42);
               break;
             case 6:
               v40 = *v37;
-              v41 = v13->GetValue();
+              v41 = a3->GetValue();
               v29 = pPlayer->_4B8213(v41, v40) / 2;
               break;
-          }
-          goto LABEL_98;
-        }
-        if ( v16 + 10 * (unsigned __int8)*v15 != 555 )
-        {
-          if ( v16 + 10 * (unsigned __int8)*v15 == 556 )
-          {
-            //v11 = (char *)p2DEvents_minus1__10[13 * (signed int)a4];
-            v11 = (char *)p2DEvents[(signed int)a4 - 1].pProprieterTitle;
-            goto LABEL_118;
-          }
-LABEL_108:
-          strncpy(a1, v15, 2u);
-          v51 = atoi(a1);
-          sprintf(a1, "%lu", v51);
-          v11 = a1;
-          goto LABEL_118;
-        }
-        v26 = &p2DEvents[(signed int)a4 - 1].fPriceMultiplier;
+            }
+            goto _continue_sprintf;
+          }
+
+          case 27:
+          {
+                    v26 = &p2DEvents[(signed int)a4 - 1].fPriceMultiplier;
         v27 = *v26;
-        v28 = v13->GetValue();
+        v28 = a3->GetValue();
         v29 = pPlayer->_4B8142(v28, v27);
         if ( a5 == 3 )
         {
           v35 = *v26;
-          v36 = v13->GetValue();
+          v36 = a3->GetValue();
           v29 = pPlayer->_4B8102(v36, v35);
-          if ( v13->uAttributes & 2 )
-          {
-LABEL_77:
+          if ( a3->uAttributes & 2 )
             v29 = 1;
-            goto LABEL_98;
-          }
-          goto LABEL_98;
+          goto _continue_sprintf;
         }
         if ( a5 != 4 )
         {
           if ( a5 == 5 )
           {
             v32 = *v26;
-            v33 = v13->GetValue();
+            v33 = a3->GetValue();
             v29 = pPlayer->_4B81C3(v33, v32);
           }
           else
@@ -5195,47 +5195,69 @@
             if ( a5 == 6 )
             {
               v30 = *v26;
-              v31 = v13->GetValue();
+              v31 = a3->GetValue();
               v29 = pPlayer->_4B8102(v31, v30) / 2;
-              if ( v13->uAttributes & 2 )
+              if ( a3->uAttributes & 2 )
                 v29 = 1;
-LABEL_91:
-              if ( v29 >= 1 )
-                goto LABEL_98;
-              goto LABEL_77;
+              if (!v29)
+                v29 = 1;
+              goto _continue_sprintf;
             }
           }
-LABEL_98:
+_continue_sprintf:
           sprintf(a1, "%lu", v29);
           v11 = a1;
-          goto LABEL_118;
+          goto _continue_strcat;
         }
         v34 = *v26;
-      }
+
       v48 = v34;
       v29 = pPlayer->_4B8179(v48);
-      goto LABEL_98;
-    }
-    if ( v17 != 30 )
-    {
-      switch ( v17 )
-      {
-        case 31:
-          v52 = pPlayers[1];
-          break;
-        case 32:
-          v52 = pPlayers[2];
-          break;
-        case 33:
-          v52 = pPlayers[3];
-          break;
-        default:
-          if ( v17 != 34 )
-          {
+      goto _continue_sprintf;
+          }
+
+          case 28:
+          {
+            //v11 = (char *)p2DEvents_minus1__10[13 * (signed int)a4];
+            v11 = (char *)p2DEvents[(signed int)a4 - 1].pProprieterTitle;
+            goto _continue_strcat;
+          }
+
+          case 29:
+          {
+            //v34 = p2DEvents_minus1__20[13 * (signed int)a4];
+            v34 = p2DEvents[(signed int)a4 - 1].fPriceMultiplier;
+            v48 = v34;
+            v29 = pPlayer->_4B8179(v48);
+            goto _continue_sprintf;
+          }
+
+          case 30:
+          {
+                if ( !a6 )
+      goto _continue_strcat;
+    sub_493F79(&v57, *a6);
+    v54 = v57.field_18;
+    v53 = v57.field_C + 1;
+    v50 = v57.field_14;
+    sprintf(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v50], v53, v54);
+    v11 = a1;
+    goto _continue_strcat;
+          }
+
+          case 31:
+          case 32:
+          case 33:
+          case 34:
+            v52 = &pParty->pPlayers[v17 - 31];
+            v11 = v52->pName;
+            goto _continue_strcat;
+
+          default:
             if ( v17 <= 50 || v17 > 70 )
-              goto LABEL_108;
-            if ( v16 + 10 * (unsigned __int8)*v15 - 579 >= 20 )
-              goto LABEL_118;
+              goto _continue_strncpy;
+            if ( v17 - 51 >= 20 )
+              goto _continue_strcat;
             HIDWORD(v49) = pParty->field_3C.field_440[2 * v17 + 1];
             LODWORD(v49) = pParty->field_3C.field_440[2 * v17];
             sub_493F79(&v56, v49);
@@ -5244,23 +5266,9 @@
             v50 = v56.field_14;
             sprintf(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v50], v53, v54);
             v11 = a1;
-            goto LABEL_118;
-          }
-          v52 = pPlayers[4];
-          break;
-      }
-      v11 = v52->pName;
-      goto LABEL_118;
-    }
-    if ( !a6 )
-      goto LABEL_118;
-    sub_493F79(&v57, *a6);
-    v54 = v57.field_18;
-    v53 = v57.field_C + 1;
-    v50 = v57.field_14;
-    sprintf(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v50], v53, v54);
-    v11 = a1;
-    goto LABEL_118;
+            goto _continue_strcat;
+        }
+      }
   }
   return pTmpBuf2;
 }
@@ -5617,7 +5625,7 @@
   pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[32]);
   pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 388, 2 * v128 + 417, v80, pClassNames[32], 0, 0, 0);
   v85 = uColorTeal;
-  if ( uClassType != PLAYER_CLASS_SHOOTER )
+  if ( uClassType != PLAYER_CLASS_ARCHER )
     v85 = uColorWhite;
   pTextCenter = pFontCreate->AlignText_Center(65, pClassNames[16]);
   pGUIWindow_CurrentMenu->DrawText(pFontCreate, pTextCenter + 453, 417, v85, pClassNames[16], 0, 0, 0);
@@ -9415,7 +9423,7 @@
       if ( a1 == 13 )
       {
         ptr_F8B1E8 = (char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
-        ptr_F8B1E8 = sub_495461((char *)ptr_F8B1E8, uActiveCharacter - 1, 0, 0, 0, 0);
+        ptr_F8B1E8 = BuilDialogueString((char *)ptr_F8B1E8, uActiveCharacter - 1, 0, 0, 0, 0);
         sub_4B40E6();
         dialogue_show_profession_details = false;
         goto _return;
@@ -9489,7 +9497,7 @@
       else
         v17 = pNPCStats->pProfessions[v2->uProfession - 1].pBenefits;
       ptr_F8B1E8 = v17;
-      v18 = sub_495461(v17, uActiveCharacter - 1, 0, 0, 0, 0);
+      v18 = BuilDialogueString(v17, uActiveCharacter - 1, 0, 0, 0, 0);
       dialogue_show_profession_details = ~dialogue_show_profession_details;
       ptr_F8B1E8 = v18;
     }
@@ -9616,7 +9624,7 @@
       dialogue_show_profession_details = false;
       uDialogueType = 13;
       ptr_F8B1E8 = pNPCStats->pProfessions[v2->uProfession - 1].pJoinText;
-      ptr_F8B1E8 = sub_495461((char *)ptr_F8B1E8, uActiveCharacter - 1, 0, 0, 0, 0);
+      ptr_F8B1E8 = BuilDialogueString((char *)ptr_F8B1E8, uActiveCharacter - 1, 0, 0, 0, 0);
       if ( uActiveCharacter )
         pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
       v19 = pGlobalTXT_LocalizationStrings[155];
@@ -12259,7 +12267,7 @@
                   v4 = (char *)&_this->pInventoryItems[result-1];
                   if ( v4[20] & 1 )
                   {
-                    v5 = sub_495461("%24", uActiveCharacter - 1, (ItemGen *)v4, (char *)ptr_507BC0->ptr_1C, 4, 0);
+                    v5 = BuilDialogueString("%24", uActiveCharacter - 1, (ItemGen *)v4, (char *)ptr_507BC0->ptr_1C, 4, 0);
                     v97 = 3;
                     v95 = v5;
                     v92 = white;
@@ -12303,7 +12311,7 @@
       v9 = uPlayerID;
       v10 = (char *)pMerchantsSellPhrases[v13];
 LABEL_35:
-      v30 = sub_495461(v10, v9, v90, (char *)v93, v94, v96);
+      v30 = BuilDialogueString(v10, v9, v90, (char *)v93, v94, v96);
       v97 = 3;
       v95 = v30;
       v92 = white;
@@ -13052,7 +13060,7 @@
                 3,
                 v16,
                 2);
-        v18 = sub_495461((char *)pMerchantsBuyPhrases[v17], uPlayerID, v15, (char *)v14, 2, 0);
+        v18 = BuilDialogueString((char *)pMerchantsBuyPhrases[v17], uPlayerID, v15, (char *)v14, 2, 0);
         v44 = 3;
         v43 = v18;
         v42 = v56;
--- a/mm7_5.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/mm7_5.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -13570,7 +13570,7 @@
   dword_506548 = 0;
   dword_506520 = 0;
   v7 = *pStorylineText->StoreLine[v6].pText;//*(&pStorylineText->field_0 + 3 * v6);
-  v8 = sub_495461(
+  v8 = BuilDialogueString(
          pStorylineText->StoreLine[v6].pText,
          uActiveCharacter - 1,
          0,
@@ -16108,7 +16108,7 @@
         a1.DrawTitleText(pFontArrus, 0, 0xCu, v13, v11, 3u);
         a1.uFrameWidth -= 24;
         a1.uFrameZ = a1.uFrameX + a1.uFrameWidth - 1;
-        v14 = sub_495461((char *)lpsz, uActiveCharacter - 1, 0, 0, 0, 0);
+        v14 = BuilDialogueString((char *)lpsz, uActiveCharacter - 1, 0, 0, 0, 0);
         a1.DrawText(pFontArrus, 100, 36, 0, v14, 0, 0, 0);
       }
     }
--- a/mm7_data.h	Mon Feb 18 12:38:07 2013 +0600
+++ b/mm7_data.h	Mon Feb 18 12:38:38 2013 +0600
@@ -2183,14 +2183,6 @@
 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);
-bool PartyHasDragon();
-bool __thiscall CheckHiredNPCSpeciality(unsigned int uProfession);
-void __cdecl InitializeAwards();
-void __cdecl InitializeScrolls();
-void __cdecl InitializeMerchants();
-void __cdecl InitializeTransitions();
-void __cdecl InitializeAutonotes();
-void __cdecl InitializeQuests();
 int __fastcall const_1(int, int); // weak
 int __cdecl GetPartyReputation();
 void __cdecl sub_4783FA_construct_global_73D150();
@@ -2265,7 +2257,7 @@
 unsigned int __fastcall sub_494820(unsigned int a1);
 char *__fastcall sub_495366(unsigned __int8 a1, unsigned __int8 a2);
 char *__fastcall GetReputationString(signed int a1);
-char *__fastcall sub_495461(char *lpsz, unsigned __int8 uPlayerID, struct ItemGen *a3, char *a4, int a5, __int64 *a6);
+char *BuilDialogueString(char *lpsz, unsigned __int8 uPlayerID, struct ItemGen *a3, char *a4, int a5, __int64 *a6);
 void __cdecl PlayerCreationUI_Draw();
 void __cdecl PlayerCreationUI_Initialize();
 void __cdecl DeleteCCharFont();
--- a/mm7text_ru.cpp	Mon Feb 18 12:38:07 2013 +0600
+++ b/mm7text_ru.cpp	Mon Feb 18 12:38:38 2013 +0600
@@ -24,6 +24,7 @@
   {"", 0},
   {"", 0},
   {"", 0},
+  {"", 1},
   {"", 0},
   {"", 0},
   {"", 1},
@@ -745,6 +746,7 @@
   {"", 1},
   {"", 0},
   {"", 0},
+  {"", 0},
   {"", 0},
   {"", 1},
   {"", 1},
@@ -795,6 +797,7 @@
   {"", 1},
   {"", 1},
   {"", 0},
+  {"", 1},
   {"", 0},
   {"", 0},
   {"", 0},
@@ -1082,7 +1085,7 @@
   int left = 0,
       right = table_size - 1,
       match = 0;
-  while (left <= right)
+  while (left < right - 1)
   {
     match = left + (right - left) / 2;
     int rval = _mbsncmp(name, (unsigned char *)table[match].name, name_len);