view NPC.cpp @ 776:3dc4a9b13c1b

travel struct fixed
author Gloval
date Sun, 24 Mar 2013 00:50:35 +0400
parents 8c6c41037c39
children d170f23f70d1
line wrap: on
line source

#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"


int pDialogueNPCCount;
struct Texture *pDialogueNPCPortraits[6];
int uNumDialogueNPCPortraits; // weak
struct NPCStats *pNPCStats = nullptr;

void  InitializeAwards();
void  InitializeScrolls();
void  InitializeMerchants();
void  InitializeTransitions();
void  InitializeAutonotes();
void  InitializeQuests();
bool   CheckPortretAgainstSex(int portret_num, int sex); 

//----- (00476977) --------------------------------------------------------
void NPCStats::InitializeNPCText()
	{
	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))
					{
					pProfessionChance[decode_step].professionChancePerArea[i]=atoi(test_string);
					}
				else if (decode_step==0)
					{
					pProfessionChance[0].professionChancePerArea[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)
		{
		pProfessionChance[i].uTotalprofChance=0;
		for (int ii=1; ii<59; ++ii)
			{
			pProfessionChance[i].uTotalprofChance+=pProfessionChance[i].professionChancePerArea[ii];
			}
		pProfessionChance[i].professionChancePerArea[0]=0;
		pProfessionChance[i].professionChancePerArea[59]=0;
		}

	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 = pNPCUnicNames[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::InitializeNPCData()
	{
	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");

	for (i=0; i<500; ++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
				switch (decode_step)
					{
				case 1:
					pNPCUnicNames[i] = RemoveQuotes(test_string);
					pNPCData[i+1].pName=pNPCUnicNames[i];
					break;
				case 2:
					pNPCData[i+1].uPortraitID = atoi(test_string);
					break;
				case 6:
					pNPCData[i+1].Location2D = atoi(test_string);
					break;
				case 7:
					pNPCData[i+1].uProfession = atoi(test_string);
					break;
				case 8:
					pNPCData[i+1].greet = atoi(test_string);
					break;
				case 9:
					pNPCData[i+1].joins = (*test_string == 'y')?1:0;
					break;
				case 10:
					pNPCData[i+1].evt_A = atoi(test_string);
					break;
				case 11:
					pNPCData[i+1].evt_B = atoi(test_string);
					break;
				case 12:
					pNPCData[i+1].evt_C = atoi(test_string);
					break;
				case 13:
					pNPCData[i+1].evt_D = atoi(test_string);
					break;
				case 14:
					pNPCData[i+1].evt_E = atoi(test_string);
					break;
				case 15:
					pNPCData[i+1].evt_F = atoi(test_string);
					break;
					}
				}
			++decode_step;
			test_string=tmp_pos+1;
			} while ((decode_step<16)&&!break_loop);
		}
	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 
			{
			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
				switch (decode_step)
					{
				case 1:
					pNPCGreetings[i].pGreeting1 = RemoveQuotes(test_string);
					break;
				case 2:
					pNPCGreetings[i].pGreeting2 = RemoveQuotes(test_string);
					break;
					}
				}
			++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)
					{
					pGroups[i] = atoi(test_string);
					}
				}
			++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()
		{
		int i;
		char* test_string;
		unsigned char c;
		bool break_loop;
		unsigned int temp_str_len;
		char* tmp_pos;
		int decode_step;

		InitializeNPCData();
		InitializeNPCText();
		InitializeQuests();
		InitializeAutonotes();
		InitializeAwards();
		InitializeTransitions();
		InitializeMerchants();
		InitializeScrolls();

		pNPCNamesTXT_Raw = NULL;
		pNPCNamesTXT_Raw = (char *)pEvents_LOD->LoadRaw("npcnames.txt", 0);
		strtok(pNPCNamesTXT_Raw, "\r");

		uNewlNPCBufPos = 0;

		for (i=0; i<540; ++i)
			{
			test_string = strtok(NULL, "\r") + 1;
			break_loop = false;
			decode_step=0;
			do 
				{
				c = *(unsigned char*)test_string;
				temp_str_len = 0;
				if (c=='\t')
					{
					if ( (decode_step == 1)&&(!uNumNPCNames[1]))
						uNumNPCNames[1]=i;
					}
				else
					{
					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;
						}
					}
				++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 
				{
                //while (*test_string == '\t')  // some steps are separated by multiple \t's
                  //++test_string;
                
				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 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 (!decode_step)
						break_loop = true;
					}
				++decode_step;
				test_string=tmp_pos+1;
				} while ((decode_step<7)&&!break_loop);
			}
		uNumNPCProfessions = 59;
		}

//----- (00477266) --------------------------------------------------------
void NPCStats::Release()
	{
	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) --------------------------------------------------------
bool  CheckPortretAgainstSex(int a1, int)
	{
	return true;
	}
// 47730C: using guessed type int __stdcall const_1(int);

//----- (0047732C) --------------------------------------------------------
void NPCStats::InitializeAdditionalNPCs(NPCData *pNPCDataBuff, int npc_uid, int uLocation2D, int uMapId)
	{
	int rep_gen;
	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 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, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0};

	unsigned __int8 seed = (unsigned __int8)((double)(npc_uid - 1)/3.0);
	uNPCSex = NPCSexGenTable[seed];
	uRace = NPCRaceGenTable[seed];
	pNPCDataBuff->uSex = uNPCSex;
	pNPCDataBuff->pName = pNPCNames[rand() % uNumNPCNames[uNPCSex]][uNPCSex];

	gen_attempts = 0;
	break_gen = false;

	do
		{
		switch ( uRace )
			{
		case 0:
			if ( uNPCSex == 0 )
				{
				uPortretMin = 2;
				uPortretMax = 100;
				}
			else
				{
				uPortretMin = 201;
				uPortretMax =  250;
				}
		case 1:
			if ( uNPCSex == 0 )
				{
				uPortretMin = 400;
				uPortretMax = 430;
				}
			else
				{
				uPortretMin = 460;
				uPortretMax =  490;
				}
			break;
		case 2:
			if ( uNPCSex == 0 )
				{
				uPortretMin = 500;
				uPortretMax =  520;
				}
			else
				{
				uPortretMin = 530;
				uPortretMax = 550;	
				}
			break;
		case 3:
			if ( uNPCSex == 0 )
				{
				uPortretMin = 300;
				uPortretMax = 330;
				}
			else
				{
				uPortretMin = 360;
				uPortretMax = 387;
				}

			break;
			}

		uGeneratedPortret = uPortretMin + rand() % (uPortretMax - uPortretMin + 1);
		if ( CheckPortretAgainstSex(uGeneratedPortret, uNPCSex))
			break_gen = true;
		++gen_attempts;
		if ( gen_attempts >= 4 )
			{
			uGeneratedPortret = uPortretMin;
			break_gen = true;
			}
		}
		while(!break_gen);

		pNPCDataBuff->uPortraitID = uGeneratedPortret;
		pNPCDataBuff->uFlags = 0;
		pNPCDataBuff->fame = 0;
		//generate reputation
		rep_gen = rand() % 100 + 1;

		if ( rep_gen >= 60 )
			{
			if ( rep_gen >= 90 )
				{
				if ( rep_gen >= 95 )
					{
					if ( rep_gen >= 98 )
						pNPCDataBuff->rep = -600;
					else
						pNPCDataBuff->rep = 400;
					}
				else
					pNPCDataBuff->rep = -300;
				}
			else
				pNPCDataBuff->rep = 200;
			}
		else
			pNPCDataBuff->rep = 0;

		max_prof_cap = rand() % pProfessionChance[uMapId].uTotalprofChance+1;
		test_prof_summ = 0;
		gen_profession = 0;

		if ( max_prof_cap > 0 )
			{
			do
				test_prof_summ += pProfessionChance[uMapId].professionChancePerArea[gen_profession++];
			while ( test_prof_summ < max_prof_cap );
			}
		pNPCDataBuff->uProfession = gen_profession - 1;
		pNPCDataBuff->Location2D = uLocation2D;
		pNPCDataBuff->field_24 = 1;
		pNPCDataBuff->joins = 1;
		pNPCDataBuff->evt_A = 0;
		pNPCDataBuff->evt_B = 0;
		pNPCDataBuff->evt_C = 0;
		pNPCDataBuff->evt_D = 0;
		pNPCDataBuff->evt_E = 0;
		pNPCDataBuff->evt_F = 0;
	}

//----- (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;

	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;

	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;

	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;

	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 + 1]=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;

	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;

	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);
		}
	}