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