void CMFXParticleEffect::LoadParamsFromXml(const XmlNodeRef& paramsNode)
{
	// Xml data format
	/*
	<Particle>
		<Name userdata="..." scale="..." maxdist="..." minscale="..." maxscale="..." maxscaledist="..." attach="...">particle.name</Name>
		<Direction>DirectionType</Direction>
	</Particle>
	*/

  for (int i=0; i<paramsNode->getChildCount(); ++i)
  {
    XmlNodeRef child = paramsNode->getChild(i);
    if (!strcmp(child->getTag(), "Name"))
    {
      SMFXParticleEntry entry;            
      entry.name = child->getContent();

			if (child->haveAttr("userdata"))
				entry.userdata = child->getAttr("userdata");
	      
			if (child->haveAttr("scale"))
				child->getAttr("scale", entry.scale);

			if (child->haveAttr("maxdist"))
				child->getAttr("maxdist", entry.maxdist);

			if (child->haveAttr("minscale"))
				child->getAttr("minscale", entry.minscale);

			if (child->haveAttr("maxscale"))
				child->getAttr("maxscale", entry.maxscale);

			if (child->haveAttr("maxscaledist"))
				child->getAttr("maxscaledist", entry.maxscaledist);

			if (child->haveAttr("attach"))
				child->getAttr("attach", entry.attachToTarget);
	      
			m_particleParams.m_entries.push_back(entry);
    }
  }
  
  SMFXParticleParams::EDirectionType directionType = SMFXParticleParams::eDT_Normal;
	XmlNodeRef dirType = paramsNode->findChild("Direction");
	if (dirType)
	{
		const char *val = dirType->getContent();
		if (!strcmp(val, "Normal"))
		{
			directionType = SMFXParticleParams::eDT_Normal;
		}
		else if (!strcmp(val, "Ricochet"))
		{
			directionType = SMFXParticleParams::eDT_Ricochet;
		}
	}
	m_particleParams.directionType = directionType;
	
}
bool CEntityPoolSignature::CompareNodes(const XmlNodeRef &a, const XmlNodeRef &b, bool bRecursive)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_ENTITY);

	assert(bool(a));
	assert(bool(b));

	bool bResult = (a && b && a->isTag(b->getTag()));

	// Check value
	bResult &= (bResult && 0 == strcmp(a->getContent(), b->getContent()));

	// Check attributes
	bResult &= (bResult && CompareNodeAttributes(a, b));

	// Check children if recursive
	if (bResult && bRecursive)
	{
		const int childCount_a = a->getChildCount();
		const int childCount_b = b->getChildCount();
		bResult &= (childCount_a == childCount_b);

		if (bResult)
		{
			for (int child = 0; bResult && child < childCount_a; ++child)
			{
				XmlNodeRef child_a = a->getChild(child);
				XmlNodeRef child_b = b->getChild(child);
				if (child_a && child_b)
				{
					bResult &= CompareNodes(child_a, child_b, true);
				}
			}
		}
	}

	return bResult;
}
Beispiel #3
0
void FillMapping(XmlNodeRef row, unsigned char* pIndexToAttrMap)
{
	int nCellIndex = 0;
	int nNewIndex = 0;
	for (int cell=0; cell<row->getChildCount(); ++cell)
	{
		if (cell >= MAX_CELL_COUNT)
			continue;

		XmlNodeRef nodeCell = row->getChild(cell);
		if (!nodeCell->isTag("Cell"))
			continue;

		if (nodeCell->getAttr("ss:Index",nNewIndex))
		{
			// Check if some cells are skipped.
			nCellIndex = nNewIndex-1;
		}

		XmlNodeRef nodeCellData = nodeCell->findChild("Data");
		if (!nodeCellData)
		{
			++nCellIndex;
			continue;
		}

		const char *sCellContent = nodeCellData->getContent();

		for (int i = 0; i < sizeof(sColumnNames)/sizeof(*sColumnNames); ++i)
		{
			// this is a begins-with-check!
			if (CryStringUtils::stristr(sCellContent, sColumnNames[i]) == sCellContent)
			{
				pIndexToAttrMap[nCellIndex] = i;
				break;
			}
		}
		++nCellIndex;
	}
}
bool ModInfo_FetchContent(CryFixedStringT<Size>* str, const XmlNodeRef& pRoot, const char* pNodeName)
{
	if (!str)
		return false;

	XmlNodeRef pNode = pRoot->findChild(pNodeName);
	if (!pNode)
		return false;

	const char* pContent = pNode->getContent();
	if (!pContent)
		return false;

	size_t attrLen = strlen(pContent);
	if (attrLen >= Size)
		str->assign(pContent, pContent + Size - 1);
	else
		str->assign(pContent, pContent + attrLen);

	str->replace("\\n", "\n");

	return true;
}
bool CommunicationVoiceLibrary::LoadFromFile(const char* fileName)
{
	MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "Communication Voice Library" );
	MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Other, 0, "Voice Lib: %s",fileName );

	XmlNodeRef root = GetISystem()->LoadXmlFromFile(fileName);
	if (!root)
		return false;

	XmlNodeRef nodeWorksheet = root->findChild("Worksheet");
	if (!nodeWorksheet)
		return false;

	XmlNodeRef nodeTable = nodeWorksheet->findChild("Table");
	if (!nodeTable)
		return false;

	stack_string libName(PathUtil::GetFileName(fileName));

	VoiceLibraryID libraryID = GetVoiceLibraryID(libName.c_str());

	std::pair<VoiceLibraries::iterator, bool> iresult = m_libraries.insert(
		VoiceLibraries::value_type(libraryID, VoiceLibrary()));

	if (!iresult.second)
	{
		if (iresult.first->second.name == libName.c_str())
		{
			AIWarningID("<AICommunicationVoiceLibrary::LoadFromFile> ", 
				"Duplicate voice library '%s'!", libName.c_str());

			return false;
		}
		else
		{
			AIWarningID("<AICommunicationVoiceLibrary::LoadFromFile> ", 
				"Hash collision for voice library name '%s' and '%s'!", libName.c_str(), iresult.first->second.name.c_str());

			return false;
		}
	}

	VoiceLibrary& library = iresult.first->second;
	library.name = string(libName);
	
	VoiceGroup* voiceGroup = 0;
		
	string signalName;
	string lastSignalName;
	string voiceName;

	for (int rowCntr = 0, childN = 0; childN < nodeTable->getChildCount(); ++childN)
	{
		XmlNodeRef nodeRow = nodeTable->getChild(childN);
		if (!nodeRow->isTag("Row"))
			continue;

		++rowCntr;
		if (rowCntr == 1) // skip language
			continue;

		if (rowCntr == 2) // path
		{
			int cellN = 0;
			for (int childrenCntr = 0; childrenCntr < nodeRow->getChildCount(); ++childrenCntr)
			{
				XmlNodeRef nodeCell = nodeRow->getChild(childrenCntr);
				if (!nodeCell->isTag("Cell"))
					continue;

				++cellN;
				if (cellN == 2)
				{
					XmlNodeRef nodeCellData = nodeCell->findChild("Data");
					if (!nodeCellData)
						break;

					library.base = PathUtil::GetLocalizationFolder() + nodeCellData->getContent();
					if (!library.base.empty())
					{
						library.base.replace("\\", "/");
						if (library.base[library.base.length()-1] != '/')
							library.base.append("/");
					}
					break;
				}
			}
			continue;
		}

		if (rowCntr == 3) // headers
			continue;

		signalName.clear();
		voiceName.clear();
		
		for (int childrenCntr = 0, cellIndex = 1; childrenCntr < nodeRow->getChildCount(); ++childrenCntr, ++cellIndex)
		{
			XmlNodeRef nodeCell = nodeRow->getChild(childrenCntr);
			if (!nodeCell->isTag("Cell"))
				continue;

			if (nodeCell->haveAttr("ss:Index"))
			{
				const char* strIdx = nodeCell->getAttr("ss:Index");
				if (sscanf(strIdx, "%d", &cellIndex) != 1)
					continue;
			}

			XmlNodeRef nodeCellData = nodeCell->findChild("Data");
			if (!nodeCellData)
				continue;

			switch (cellIndex)
			{
			case 1:
				signalName = nodeCellData->getContent();
				break;
			case 2:
				voiceName = nodeCellData->getContent();
				break;
			}
		}

		if (!signalName.empty())
		{
			signalName.MakeLower();
			std::pair<VoiceGroups::iterator, bool> itresult = library.voiceGroups.insert(
				VoiceGroups::value_type(signalName, VoiceGroup()));

			voiceGroup = &itresult.first->second;
			// The 20 here comes from inspection of the resulting contents in memreplay
			voiceGroup->variations.reserve(20);

			if (!itresult.second)
			{
				if (lastSignalName != signalName)
					AIWarningID("<AICommunicationVoiceLibrary::LoadFromFile> ", 
						"Duplicate voice signal '%s' in file '%s'.", signalName.c_str(), libName.c_str());
			}

			lastSignalName = signalName;
		}

		if (!voiceGroup || voiceName.empty())
			continue;

		if ((library.base.find_first_of(':') == string::npos) && (voiceName.find_first_of(':') == string::npos))
			voiceName.append(".wav");

		if (voiceGroup->variations.size() < MaxVariationCount)
			voiceGroup->variations.push_back(voiceName);
		else
			AIWarningID("<AICommunicationVoiceLibrary::LoadFromFile> ", 
			"Too many voice variations for signal '%s' in file '%s'. Limit is 32.", signalName.c_str(), libName.c_str());
	}

	return true;
}
Beispiel #6
0
int CDialogLoader::LoadFromTable(XmlNodeRef tableNode, const string& groupName, TDialogScriptMap& outScriptMap)
{
	unsigned char nCellIndexToType[MAX_CELL_COUNT];
	memset(nCellIndexToType, ATTR_SKIP, sizeof(nCellIndexToType) );

	IMScript theScript;

	int nNumGoodScripts = 0;
 	int nRowIndex = 0;
	int nChilds = tableNode->getChildCount();
	for (int i=0; i<nChilds; ++i)
	{
		XmlNodeRef rowNode = tableNode->getChild(i);
		if (!rowNode || !rowNode->isTag("Row"))
			continue;

		++nRowIndex;

		// skip first row as it should only contain column description
		if (nRowIndex == 1)
		{
			FillMapping(rowNode, nCellIndexToType);
			continue;
		}

		IMScriptLine scriptLine;

		bool bLineValid = false;
		int nColCount = rowNode->getChildCount();
		int nCellIndex = 0;
		for (int j=0; j<nColCount; ++j)
		{
			XmlNodeRef cellNode = rowNode->getChild(j);
			if (!cellNode || !cellNode->isTag("Cell"))
				continue;

			int tmpIndex = 0;
			if (cellNode->getAttr("ss:Index", tmpIndex))
			{
				nCellIndex = tmpIndex-1;
			}

			if (nCellIndex < 0 || nCellIndex >= MAX_CELL_COUNT)
				break;

			XmlNodeRef cellDataNode = cellNode->findChild("Data");
			if (!cellDataNode)
			{
				++nCellIndex;
				continue;
			}

			unsigned char nCellType = nCellIndexToType[nCellIndex];

			const char* content = cellDataNode->getContent();

			// nRowIndex and nCellIndex should be correct now [1-based, not 0-based!]
			switch (nCellType)
			{
			case ATTR_SKIP:
				break;
			case ATTR_DIALOG:
				if (theScript.IsValid())
				{
					const bool ok = ProcessScript(theScript, groupName, outScriptMap);
					if (ok)
						++nNumGoodScripts;
					theScript.Reset();
				}
				theScript.name = content;
				break;
			case ATTR_ACTOR:
				scriptLine.actor = content;
				bLineValid = true;
				break;
			case ATTR_AUDIO:
				if (bLineValid)
				{
					if(content == 0)
						scriptLine.audioID = INVALID_AUDIO_CONTROL_ID;
					else
						gEnv->pAudioSystem->GetAudioTriggerID(content, scriptLine.audioID);
				}
				break;
			case ATTR_ANIM:
				if (bLineValid)
					scriptLine.anim = content;
				break;
			case ATTR_FACIAL:
				if (bLineValid)
				{
					size_t n = strcspn(content, ":; ");
					if (n == strlen(content))
					{
						scriptLine.facial = content;
						scriptLine.facialWeight = 0.5f;
						scriptLine.facialFadeTime = 0.5f;
					}
					else
					{
						scriptLine.facial.assign ( content, n );
						float w = 0.5f;
						float t = 0.5f;
						int nGood = sscanf(content+n+1, "%f%*[:; ]%f",&w,&t);
						if (nGood != 1 && nGood != 2)
						{
							GameWarning("[DIALOG] CDialogLoader::LoadFromTable: DialogScript '%s' has invalid Facial Expression Content '%s'. Using weight=%f fadetime=%f.", groupName.c_str(), content,w,t);
						}
						scriptLine.facialWeight = w;
						scriptLine.facialFadeTime = t;
					}
				}
				break;
			case ATTR_LOOKAT:
				if (bLineValid)
					scriptLine.lookat = content;
				break;
			case ATTR_DELAY:
				if (bLineValid)
				{
					float val = 0.0f;
					int n = sscanf(content,"%f", &val);
					if (n == 1)
					{
						scriptLine.delay = val;
					}
				}
				break;
			default:
				break;
			}

			++nCellIndex;
		}
		if (scriptLine.IsValid())
		{
			theScript.lines.push_back(scriptLine);
		}	
	}
	if (theScript.IsValid())
	{
		const bool ok = ProcessScript(theScript, groupName, outScriptMap);
		if (ok)
			++nNumGoodScripts;
	}

	return nNumGoodScripts;
}