Esempio n. 1
0
//----------------------------------------------------------------------------
// CStaticItems::buildOntItem use faber system for make an item
// 
//----------------------------------------------------------------------------
CGameItemPtr CStaticItems::buildOnetItem( CSheetId sheet )
{
	const CStaticItem * staticItem = CSheets::getForm( sheet );
	if( staticItem != 0 )
	{	
		if( staticItem->Family != ITEMFAMILY::AMMO &&
			staticItem->Family != ITEMFAMILY::ARMOR  &&
			staticItem->Family != ITEMFAMILY::JEWELRY &&
			staticItem->Family != ITEMFAMILY::MELEE_WEAPON &&
			staticItem->Family != ITEMFAMILY::RANGE_WEAPON &&
			staticItem->Family != ITEMFAMILY::SHIELD )
			return 0;

		if( staticItem->CraftPlan == CSheetId::Unknown )
		{
			nlwarning("SI: Item %s have an unknown plan", sheet.toString().c_str() );
			return 0;
		}

		if( staticItem->Family == ITEMFAMILY::MELEE_WEAPON ||
			staticItem->Family == ITEMFAMILY::RANGE_WEAPON ||
			staticItem->Family == ITEMFAMILY::AMMO ||
			staticItem->Family == ITEMFAMILY::ARMOR ||
			staticItem->Family == ITEMFAMILY::SHIELD ||
			staticItem->Family == ITEMFAMILY::JEWELRY )
		{
			CFaberPhrase phrase;
			vector< CSheetId > Rm;
			vector< CSheetId > RmFormula;

			// select raw material used for craft item
			selectRmForCraft( staticItem->CraftPlan, Rm, RmFormula );
			
			// craft item and return it's pointer
			return phrase.systemCraftItem( staticItem->CraftPlan, Rm, RmFormula );
		}
		else
		{
			nlwarning("SI: Item %s has not a good family to be sell family='%s'", sheet.toString().c_str(), ITEMFAMILY::toString(staticItem->Family).c_str() );
			return 0;
		}
	}
	else
	{
		nlwarning("SI: Can't found static form for item %s", sheet.toString().c_str() );
		return 0;
	}
}
//-----------------------------------------------
//	operator<
//
//-----------------------------------------------
bool CSheetId::operator < (const CSheetId& sheetRef ) const
{
	if (!_Initialised) init(false);

	if (_Id.Id < sheetRef.asInt())
	{
		return true;
	}

	return false;

} // operator< //
// ***************************************************************************
static DECLARE_INTERFACE_USER_FCT(getBotChatItemSheetForItemType)
{
	if(args.size()!=1)
	{
		nlwarning("<getBotChatItemSheetForItemType> requires 1 arg");
		return false;
	}

	// get arg
	uint	a0= (uint)args[0].getInteger();
	clamp(a0,(uint)0,uint(ITEM_TYPE::UNDEFINED));

	// get sheet name
	string	name= CBotChatPageTrade::getItemSheetNameForItemType((ITEM_TYPE::TItemType)a0);

	// result
	CSheetId	sheetId;
	sheetId.buildSheetId(name);
	result.setInteger(sheetId.asInt());

	return true;
}
Esempio n. 4
0
	bool	operator()(const CSheetId &a, const CSheetId &b)
	{
		return a.toString()<b.toString();
	}
Esempio n. 5
0
//---------------------------------------------------
// createItem :
//
//---------------------------------------------------
//CGameItemPtr CGameItemManager::createItem( CEntityId& id, CSheetId& sheetId, uint16 quality, sint16 slot, bool destroyable, bool dropable , const CEntityId &creatorId )
CGameItemPtr CGameItemManager::createItem( const CSheetId& sheetId, uint16 quality, bool destroyable, bool dropable , const CEntityId &creatorId )
{
	H_AUTO(GIM_createItem1);
	
	// test if the item already exists
//	map<CEntityId,CGameItemPtr>::iterator itIt = _Items.find( id );
//	if( itIt != _Items.end() )
//	{
//		nlwarning("<CGameItemManager::createItem> The item %s already exists",id.toString().c_str());
//		return NULL;
//	}

// MALKAV 22/01/03 :  get owner, if owner not found, returns before creating the item and display a simple warning
//	CGameItemPtr ownerItem = NULL;
//	if( owner != CEntityId::Unknown )
//	{
//		ownerItem = getItem( owner );
//		BOMB_IF(ownerItem == NULL ,"Bad owner found for item",return NULL);
//	}
//
	// create a new item
//	CGameItemPtr item = getNewItem( id, sheetId, quality, destroyable, dropable );
	CGameItemPtr item = getNewItem(sheetId, quality, destroyable, dropable );
	if( item != NULL )
	{
//		nldebug("<CGameItemManager::createItem> create item %s with owner %s",id.toString().c_str(), owner.toString().c_str());

//		(*item)->Owner = owner;
		(*item)->setCreator( creatorId );
		
		// insert the item in the map
//		_Items.insert( make_pair(id,item) );
//		_Items.insert( item );

		// insert the item in the children of the owner
// MALKAV 22/01/03 : test the owner existence sooner and use a warning instead of an nlerror to keep going
//		if( owner != CEntityId::Unknown )
//		{
//		 	CGameItemPtr ownerItem = getItem( owner );
//			if( ownerItem!=NULL )
//			{
//				(*ownerItem)->addChild( item, slot );
//			}
//			else
//			{				
//				nlerror("<CGameItemManager::createItem> Can't find the owner item %s",owner.toString().c_str());
//			}
//		}
	}
	else
	{
//		nlwarning("<CGameItemManager::createItem> Can't create the item %s with invalid sheet '%s'", id.toString().c_str(), sheetId.toString().c_str());
		nlwarning("<CGameItemManager::createItem> Can't create an item with invalid sheet '%s'", sheetId.toString().c_str());
	}

	log_Item_Create(item->getItemId(), item->getSheetId(), item->getStackSize(), item->quality());

	return item;

} // createItem //
Esempio n. 6
0
void	CPrimitivePlugin::drawPrimitive(const NLLIGO::IPrimitive *primitive, const TRenderContext &ctx)
{
//	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	static const float POINT_ARROW_LINE_SIZE = 20.f;
	static const float POINT_ARROW_HEAD_SIZE = 8.f;
	static const float POINT_DOT_SIZE = 3.f;

	static const uint CIRCLE_SEGMENT_SIZE = 20;
	static const uint CIRCLE_MIN_SEGMENT_COUNT = 8;

	std::string *sheetName;
	primitive->getPropertyByName("sheet_client", sheetName);

	TCreatureInfo *info = NULL;
	if (!sheetName->empty())
	{
		// two step init of id to remove a flooding NeL warning
		CSheetId id;
		id.buildSheetId(*sheetName+".creature");
		std::map<NLMISC::CSheetId, TCreatureInfo>::iterator it(_CreatureInfos.find(id));
		if (it != _CreatureInfos.end())
		{
			info = &(it->second);
		}
	}


	const CPrimPoint *point = dynamic_cast<const CPrimPoint *>(primitive);
	if (point)
	{
		// Clip ?
		if (!ctx.Display->isClipped (&point->Point, 1))
		{
			// Position in world
			CVector center = point->Point;
			ctx.Display->worldToPixel (center);

			// Dot
			CVector dot0, dot1, dot2, dot3;
			dot0 = center;
			dot0.x += POINT_DOT_SIZE;
			dot0.y += POINT_DOT_SIZE;
			dot1 = center;
			dot1.x -= POINT_DOT_SIZE;
			dot1.y += POINT_DOT_SIZE;
			dot2 = center;
			dot2.x -= POINT_DOT_SIZE;
			dot2.y -= POINT_DOT_SIZE;
			dot3 = center;
			dot3.x += POINT_DOT_SIZE;
			dot3.y -= POINT_DOT_SIZE;

			// Transform primitive
			transformVector (dot0, point->Angle, center);
			transformVector (dot1, point->Angle, center);
			transformVector (dot2, point->Angle, center);
			transformVector (dot3, point->Angle, center);

			// In world space
			ctx.Display->pixelToWorld (center);
			ctx.Display->pixelToWorld (dot0);
			ctx.Display->pixelToWorld (dot1);
			ctx.Display->pixelToWorld (dot2);
			ctx.Display->pixelToWorld (dot3);

			// Draw it
			ctx.Display->triRenderProxy (ctx.MainColor, dot0, dot1, dot2, ctx.Selected?2:0);
			ctx.Display->triRenderProxy (ctx.MainColor, dot2, dot3, dot0, ctx.Selected?2:0);

			// Need detail?
			if (ctx.ShowDetail)
			{
				// Prim class available ?
				const CPrimitiveClass *primClass = ctx.PrimitiveClass;
				if (primClass != NULL)
				{
					// Draw an arraow ?
					if (primClass->ShowArrow)
					{
						// Position in world
						center = point->Point;
						ctx.Display->worldToPixel (center);
						CVector arrow = center;
						CVector arrow0 = center;
						arrow.x += POINT_ARROW_LINE_SIZE;
						CVector arrow1 = arrow;
						CVector arrow2 = arrow;
						arrow0.x += POINT_ARROW_LINE_SIZE + POINT_ARROW_HEAD_SIZE;
						arrow1.y += POINT_ARROW_HEAD_SIZE;
						arrow2.y -= POINT_ARROW_HEAD_SIZE;

						// Transform primitive
						transformVector (arrow, point->Angle, center);
						transformVector (arrow0, point->Angle, center);
						transformVector (arrow1, point->Angle, center);
						transformVector (arrow2, point->Angle, center);

						// In world space
						ctx.Display->pixelToWorld (center);
						ctx.Display->pixelToWorld (arrow);
						ctx.Display->pixelToWorld (arrow0);
						ctx.Display->pixelToWorld (arrow1);
						ctx.Display->pixelToWorld (arrow2);

						// Draw it
						ctx.Display->lineRenderProxy (ctx.MainColor, center, arrow, ctx.Selected?2:0);
						ctx.Display->triRenderProxy (ctx.ArrowColor, arrow0, arrow1, arrow2, ctx.Selected?2:0);
					}
				}

				// Have bounding info ?
				if (info != NULL)
				{
					if (info->HaveRadius)
					{
						// Get it
						float fRadius = info->Radius;

						// Get the perimeter
						float perimeter = 2.f*(float)Pi*fRadius;

						// Get the perimeter on the screen
						perimeter *= (float)ctx.Display->getWidth() / (ctx.Display->_CurViewMax.x - ctx.Display->_CurViewMin.x);
						
						// Get the segement count
						perimeter /= (float)CIRCLE_SEGMENT_SIZE;
						
						// Clamp
						if (perimeter < CIRCLE_MIN_SEGMENT_COUNT)
							perimeter = CIRCLE_MIN_SEGMENT_COUNT;

						// Segment count
						uint segmentCount = (uint)perimeter;

						// Draw a circle
						CVector posInit = center;
						posInit.x += fRadius;
						CVector posPrevious = posInit;
						for (uint i=1; i<segmentCount+1; i++)
						{
							CVector pos = posInit;
							transformVector (pos, (float)i*2.f*(float)Pi/(float)segmentCount, center);
							ctx.Display->lineRenderProxy (ctx.MainColor, pos, posPrevious, ctx.Selected?2:0);
							posPrevious = pos;
						}
					}
					if (info->HaveBox)
					{
						CVector center = point->Point;
//						ctx.Display->worldToPixel (center);

						// Dot
						CVector dot0, dot1, dot2, dot3;
						dot0 = center;
						dot0.x += info->Length/2;
						dot0.y += info->Width/2;
						dot1 = center;
						dot1.x -= info->Length/2;
						dot1.y += info->Width/2;
						dot2 = center;
						dot2.x -= info->Length/2;
						dot2.y -= info->Width/2;
						dot3 = center;
						dot3.x += info->Length/2;
						dot3.y -= info->Width/2;

						// Transform primitive
						transformVector (dot0, point->Angle, center);
						transformVector (dot1, point->Angle, center);
						transformVector (dot2, point->Angle, center);
						transformVector (dot3, point->Angle, center);

						// In world space
/*						ctx.Display->pixelToWorld (center);
						ctx.Display->pixelToWorld (dot0);
						ctx.Display->pixelToWorld (dot1);
						ctx.Display->pixelToWorld (dot2);
						ctx.Display->pixelToWorld (dot3);
*/
						// Draw it
						ctx.Display->lineRenderProxy (ctx.MainColor, dot0, dot1, ctx.Selected?2:0);
						ctx.Display->lineRenderProxy (ctx.MainColor, dot1, dot2, ctx.Selected?2:0);
						ctx.Display->lineRenderProxy (ctx.MainColor, dot2, dot3, ctx.Selected?2:0);
						ctx.Display->lineRenderProxy (ctx.MainColor, dot3, dot0, ctx.Selected?2:0);
					}
				}
			}
		}
	}
	
}
Esempio n. 7
0
// ***************************************************************************
void CSBrickSheet::build (const NLGEORGES::UFormElm &root)
{
	string		sTmp;
	uint		i;

	// read the array of skills
	string	skillUseStr;
	TRANSLATE_VAL(skillUseStr, "Basics.Skill");
	while(strFindReplace(skillUseStr, ":", " "));
	std::vector<string>		listSkill;
	splitString(skillUseStr," ",listSkill);
	// build the req skill array
	UsedSkills.clear();
	UsedSkills.reserve(listSkill.size());
	for(i=0;i<listSkill.size();i++)
	{
		SKILLS::ESkills	skill= SKILLS::toSkill(listSkill[i]);
		// Yoyo: patch to read auto generated bricks
		if(skill==SKILLS::unknown)
		{
			skill = (SKILLS::ESkills)SKILLS::toSkill("S" + listSkill[i]);
		}
		// keep only whats work
		if(skill!=SKILLS::unknown)
		{
			UsedSkills.push_back(skill);
		}
	}
	// if empty, fill at least with unknown
	if(UsedSkills.empty())
		UsedSkills.push_back(SKILLS::unknown);

	// get family id
	root.getValueByName (sTmp, "Basics.FamilyId" );
	BrickFamily = BRICK_FAMILIES::toSBrickFamily (sTmp);
	if(BrickFamily==BRICK_FAMILIES::Unknown)
		nlwarning("CSBrickSheet:build: BrickFamily Unknown '%s'.", sTmp.c_str());
/*
	// Yoyo: patch to read auto generated bricks
	if(BrickFamily==BRICK_FAMILIES::Unknown)
	{
		string	sheetName= Id.toString();
		std::string::size_type	end= sheetName.find(".sbrick")-2;
		BrickFamily = BRICK_FAMILIES::toSBrickFamily ( NLMISC::toUpper(sheetName.substr(0,end)) );
		if(BrickFamily==BRICK_FAMILIES::Unknown)
			nlwarning("Unknown Family for SBrick: %s", sheetName.c_str());
	}
*/
	root.getValueByName (IndexInFamily, "Basics.IndexInFamily" );
	root.getValueByName (Level, "Basics.Level" );
	// read icons
	string Icon;
	root.getValueByName (Icon, "Client.Icon" );
	Icon = strlwr(Icon);
	IdIcon = ClientSheetsStrings.add(Icon);

	string IconBack;
	root.getValueByName (IconBack, "Client.IconBack" );
	IconBack = strlwr(IconBack);
	IdIconBack = ClientSheetsStrings.add(IconBack);

	string IconOver;
	root.getValueByName (IconOver, "Client.IconOver" );
	IconOver = strlwr(IconOver);
	IdIconOver = ClientSheetsStrings.add(IconOver);

	string IconOver2;
	root.getValueByName (IconOver2, "Client.IconOver2" );
	IconOver2 = strlwr(IconOver2);
	IdIconOver2 = ClientSheetsStrings.add(IconOver2);

	root.getValueByName (IconColor, "Client.IconColor" );
	root.getValueByName (IconBackColor, "Client.IconBackColor");
	root.getValueByName (IconOverColor, "Client.IconOverColor");
	root.getValueByName (IconOver2Color, "Client.IconOver2Color");
	root.getValueByName (SabrinaCost, "Basics.SabrinaCost" );
	root.getValueByName (SabrinaRelativeCost, "Basics.SabrinaRelativeValue" );

	// mandatory families
	MandatoryFamilies.clear();
	char	tmp[256];
	for(i=0;i<SBRICK_MAX_MANDATORY;i++)
	{
		sprintf(tmp, "Mandatory.f%d", i);
		root.getValueByName (sTmp, tmp);
		if (!sTmp.empty())
		{
			BRICK_FAMILIES::TBrickFamily	bf= BRICK_FAMILIES::toSBrickFamily(sTmp);
			if(bf != BRICK_FAMILIES::Unknown)
				MandatoryFamilies.push_back( bf );
			else
				nlwarning("Unknown Mandatory family %s",sTmp.c_str());
		}
	}

	// Optional families
	OptionalFamilies.clear();
	for(i=0;i<SBRICK_MAX_OPTIONAL;i++)
	{
		sprintf(tmp, "Optional.f%d", i);
		root.getValueByName (sTmp, tmp);
		if (!sTmp.empty())
		{
			BRICK_FAMILIES::TBrickFamily	bf= BRICK_FAMILIES::toSBrickFamily(sTmp);
			if(bf != BRICK_FAMILIES::Unknown)
				OptionalFamilies.push_back( bf );
			else
				nlwarning("Unknown optional family %s",sTmp.c_str());
		}
	}

	// Parameter families
	ParameterFamilies.clear();
	for(i=0;i<SBRICK_MAX_PARAMETER;i++)
	{
		sprintf(tmp, "Parameter.f%d", i);
		root.getValueByName (sTmp, tmp);
		if (!sTmp.empty())
		{
			BRICK_FAMILIES::TBrickFamily	bf= BRICK_FAMILIES::toSBrickFamily(sTmp);
			if(bf != BRICK_FAMILIES::Unknown)
				ParameterFamilies.push_back( bf );
			else
				nlwarning("Unknown Parameter family %s",sTmp.c_str());
		}
	}

	// Credit families
	CreditFamilies.clear();
	for(i=0;i<SBRICK_MAX_CREDIT;i++)
	{
		sprintf(tmp, "Credit.f%d", i);
		root.getValueByName (sTmp, tmp);
		BRICK_FAMILIES::TBrickFamily	bf= BRICK_FAMILIES::toSBrickFamily(sTmp);
		if(bf != BRICK_FAMILIES::Unknown)
			CreditFamilies.push_back( bf );
	}

	string ForbiddenDef;
	root.getValueByName (ForbiddenDef, "Basics.ForbiddenDef" );
	IdForbiddenDef = ClientSheetsStrings.add(ForbiddenDef);

	string ForbiddenExclude;
	root.getValueByName (ForbiddenExclude, "Basics.ForbiddenExclude" );
	IdForbiddenExclude = ClientSheetsStrings.add(ForbiddenExclude);

	// **** Properties
	Properties.clear();
	for(i=0;i<MaxProperties;i++)
	{
		string	val;
		root.getValueByName(val, toString("Basics.Property %d", i).c_str() );
		if(!val.empty() && val!="NULL")
		{
			CProperty	prop;
			prop.Text= val;
			Properties.push_back(prop);
		}
	}

	// **** Faber
	// The FaberPlan are stored in Mandatory only, but the tool filter is in root
	if( isFaber() && (isMandatory() || isRoot()) )
	{
		string	val;

		FaberPlan.ItemPartMps.clear();
		FaberPlan.FormulaMps.clear();

		// Get Item Built
		TRANSLATE_VAL(val, "faber.Create.Crafted Item");
		FaberPlan.ItemBuilt.buildSheetId(val);

		// Get Skill Filters
		TRANSLATE_ENUM ( FaberPlan.ToolType, TOOL_TYPE::Unknown, TOOL_TYPE::toToolType, "faber.Tool type");

		// Get NB item built (for ammo)
		TRANSLATE_VAL( FaberPlan.NbItemBuilt, "faber.Create.Nb built items");

		// MPs. Try all MP1 .. 5 slots. Stop when not valid
		for (uint k=0; k< MAX_FABER_REQ_MP; ++k)
		{
			sint32	mpQuantity= 0;
			root.getValueByName(mpQuantity, toString("faber.Create.Quantity %d", k+1).c_str() );
			// if the req quantity is not 0
			if ( mpQuantity>0 )
			{
				CFaberPlan::CItemPartMP	mpVal;
				mpVal.Quantity= mpQuantity;
				// No error if unknown: filter not used (all MPs match)
				TRANSLATE_ENUM_NODB( mpVal.FaberTypeFilter, RM_FABER_TYPE::Unknown, RM_FABER_TYPE::toFaberType,
					toString("faber.Create.MP %d", k+1).c_str() );

				// Add this req MP.
				FaberPlan.ItemPartMps.push_back(mpVal);
			}
			// else subsequents MP slots are not used
			else
				break;
		}

		// Formula MPs. Try all MP1 .. 5 slots. Stop when not valid
		for (uint k=0; k< MAX_FABER_REQ_MP; ++k)
		{
			sint32	mpQuantity= 0;
			root.getValueByName(mpQuantity, toString("faber.Create.Quantity formula %d", k+1).c_str() );
			// if the req quantity is not 0
			if ( mpQuantity>0 )
			{
				CFaberPlan::CFormulaMP	mpVal;
				mpVal.Quantity= mpQuantity;
				// No error if unknown: filter not used (all MPs match)
				TRANSLATE_VAL(val, toString("faber.Create.MP formula %d", k+1).c_str());
				mpVal.ItemRequired.buildSheetId(val);

				// Add this req MP.
				FaberPlan.FormulaMps.push_back(mpVal);
			}
			// else subsequents MP slots are not used
			else
				break;
		}
	}


	// read minmax range/cast time when guigui ready
	TRANSLATE_VAL(MinCastTime, "Basics.MinCastTime");
	TRANSLATE_VAL(MaxCastTime, "Basics.MaxCastTime");
	TRANSLATE_VAL(MinRange, "Basics.MinRange");
	TRANSLATE_VAL(MaxRange, "Basics.MaxRange");

	// Read SPCost
	TRANSLATE_VAL(SPCost, "Basics.SPCost");

	// Read AvoidCyclic
	TRANSLATE_VAL(AvoidCyclic, "Basics.AvoidCyclic");

	// Read UsableWithEmptyHands
	TRANSLATE_VAL(UsableWithEmptyHands, "Basics.UsableWithEmptyHands");

	// Read Action Nature
	string	val;
	TRANSLATE_ENUM(ActionNature, ACTNATURE::UNKNOWN, ACTNATURE::toActionNature, "Basics.Action Nature");

	// Read CivRestriction
	TRANSLATE_ENUM(CivRestriction, EGSPD::CPeople::Common, EGSPD::CPeople::fromString, "Basics.CivRestriction");


	// **** parse properties, to precompute the Bricks Flags.
	BrickRequiredFlags= 0;
	for(i=0;i<Properties.size();i++)
	{
		string text= NLMISC::toLower(Properties[i].Text);

		// If the property is an opening property
		const	string	openingProp[]= { "opening_1:", "opening_2:", "opening_3:" };
		// or if the property is a general brick flag
		const	string	neededBrickFlag= "needed_brick_flag";
		const	uint	nOpeningProp= sizeof(openingProp) / sizeof(openingProp[0]);
		for(uint j=0;j<nOpeningProp;j++)
		{
			const string &prop= openingProp[j];
			// if found this property
			if( text.compare(0, prop.size(), prop)==0 ||
				(j==0 && text.compare(0, neededBrickFlag.size(), neededBrickFlag)==0)
			  )
			{
				// get all the opening requirement
				vector<string>	strList;
				strList.reserve(10);
				splitString(text, ":", strList);
				for(uint k=1;k<strList.size();k++)
				{
					// remove empty space, and convert to a bit
					strRemoveChar(strList[k], ' ');
					BRICK_FLAGS::TBrickFlag	evFlag;
					evFlag= BRICK_FLAGS::toBrickFlag(strList[k]);
					if(evFlag!=BRICK_FLAGS::UnknownFlag)
						BrickRequiredFlags|= (uint64(1)<<(uint)evFlag);
				}
				break;
			}
		}
	}

	// **** parse required skills
	// parse the sheet str
	string	skillReqStr;
	TRANSLATE_VAL(skillReqStr, "Basics.LearnRequiresOneOfSkills");
	while(strFindReplace(skillReqStr, ":", " "));
	listSkill.clear();
	splitString(skillReqStr," ",listSkill);
	// build the req skill array
	RequiredSkills.clear();
	RequiredSkills.reserve(listSkill.size()/2);
	for(i=0;i<listSkill.size()/2;i++)
	{
		CSkillValue		sv;
		sv.Skill= SKILLS::toSkill(listSkill[i*2]);
		fromString(listSkill[i*2+1], sv.Value);
		// keep only whats work
		if(sv.Skill!=SKILLS::unknown)
		{
			RequiredSkills.push_back(sv);
		}
	}

	// **** parse required bricks
	// parse the sheet str
	string	brickReqStr;
	TRANSLATE_VAL(brickReqStr, "Basics.LearnRequiresBricks");
	while(strFindReplace(brickReqStr, ":", " "));
	std::vector<string>		listBrick;
	listBrick.clear();
	splitString(brickReqStr," ",listBrick);
	// build the req skill array
	RequiredBricks.clear();
	RequiredBricks.reserve(listBrick.size());
	for(i=0;i<listBrick.size();i++)
	{
		CSheetId	sheetId;
		string	str= listBrick[i];
		strlwr(str);
		if(str.find(".sbrick")==string::npos)
			str+= ".sbrick";
		sheetId.buildSheetId(str);
		if(sheetId!=CSheetId::Unknown)
		{
			RequiredBricks.push_back(sheetId);
		}
	}

	// faction index
	string faction;
	root.getValueByName (faction, "Basics.Faction" );
	FactionIndex = CStaticFames::getInstance().getFactionIndex( faction );

	// min fame value
	TRANSLATE_VAL(MinFameValue, "Basics.Minimum fame");

	// **** Magic only: try to get a ResistType against this brick
	for(i=0;i<Properties.size();i++)
	{
		string text= toLower(Properties[i].Text);

		// *** If the property is a DamageType
		const string	dmgTypeProp= "ma_dmg_type:";
		if( text.compare(0, dmgTypeProp.size(), dmgTypeProp)==0 )
		{
			// extract the dmg type
			string	dtStr= text.substr(dmgTypeProp.size());
			strRemoveChar(dtStr, ' ');
			DMGTYPE::EDamageType	dt= DMGTYPE::stringToDamageType(dtStr);
			if(dt!=DMGTYPE::UNDEFINED)
			{
				// Convert to a resist type
				RESISTANCE_TYPE::TResistanceType	rt= DMGTYPE::getAssociatedResistanceType(dt);
				if(rt!=RESISTANCE_TYPE::None)
					MagicResistType= rt;
			}
		}

		// *** Do the same if the property is an effect family (affliction spells)
		const string	effectFamProp= "ma_effect:";
		if( text.compare(0, effectFamProp.size(), effectFamProp)==0 )
		{
			// extract the effect family
			string	efStr= text.substr(effectFamProp.size());
			strRemoveChar(efStr, ' ');
			EFFECT_FAMILIES::TEffectFamily	ef= EFFECT_FAMILIES::toEffectFamily(efStr);
			if(ef!=EFFECT_FAMILIES::Unknown)
			{
				// Convert to a resist type
				RESISTANCE_TYPE::TResistanceType	rt= EFFECT_FAMILIES::getAssociatedResistanceType(ef);
				if(rt!=RESISTANCE_TYPE::None)
					MagicResistType= rt;
			}
		}

	}

}