public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { //GetInCell checks if a cell name starts with the argument string: https://cs.elderscrolls.com/index.php?title=GetInCell //The below will probably not always work. TES4FunctionArguments functionArguments = function.Arguments; ITES4StringValue apiToken = functionArguments[0]; string cellName = apiToken.StringValue; TES5ObjectCall getParentCell = this.objectCallFactory.CreateObjectCall(calledOn, "GetParentCell", multipleScriptsScope); TES5ObjectCall getParentCellName = this.objectCallFactory.CreateObjectCall(getParentCell, "GetName", multipleScriptsScope); int length = cellName.Length; TES5ObjectCallArguments substringArguments = new TES5ObjectCallArguments() { getParentCellName, new TES5Integer(0), new TES5Integer(length) }; TES5ObjectCall substring = this.objectCallFactory.CreateObjectCall(TES5StaticReference.StringUtil, "Substring", multipleScriptsScope, substringArguments); TES4LoadedRecord cellRecord = ESMAnalyzer._instance().FindInTES4Collection(cellName, false); string cellNameWithSpaces = cellRecord.GetSubrecordTrim("FULL"); if (cellNameWithSpaces == null) { cellNameWithSpaces = cellName; } TES5String cellNameTES5String = new TES5String(cellNameWithSpaces); return(TES5ExpressionFactory.CreateComparisonExpression(substring, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, cellNameTES5String)); }
/* * Add value to the trie * * string The key * mixed The value * Overwrite existing value */ public void Add(string str, TES4LoadedRecord value, bool overWrite = true) { if (str == "") { if (this.value == null || overWrite) { this.value = value; } return; } foreach (var kvp in this.trie) { var prefix = kvp.Key; var trie = kvp.Value; int prefixLength = prefix.Length; string head = PHPFunction.Substr(str, prefixLength); int headLength = head.Length; bool equals = true; string equalPrefix = ""; for (int i = 0; i < prefixLength; ++i) { //Split if (i >= headLength) { Trie equalTrie = new Trie(value); this.trie.Add(equalPrefix, equalTrie); equalTrie.trie.Add(prefix.Substring(i), trie); this.trie.Remove(prefix); return; } else if (prefix[i] != head[i]) { if (i > 0) { Trie equalTrie = new Trie(); this.trie.Add(equalPrefix, equalTrie); equalTrie.trie.Add(prefix.Substring(i), trie); equalTrie.trie.Add(str.Substring(i), new Trie(value)); this.trie.Remove(prefix); return; } equals = false; break; } equalPrefix += head[i]; } if (equals) { trie.Add(str.Substring(prefixLength), value, overWrite); return; } } this.trie.Add(str, new Trie(value)); }
/* * @throws ConversionException */ public ITES5Type GetFormTypeByEDID(string edid) { TES4LoadedRecord record = FindInTES4Collection(edid, false); if (record == null) { //WTM: Change: These EDIDs can't be found, so I've written them into the code. if (edid == "SE02FIN") { return(TES5BasicType.T_QUEST); } if (edid == "LvlSpell") { return(TES5BasicType.T_SPELL); } throw new ConversionException("Cannot find type for EDID " + edid); } return(TypeMapper.Map(record.RecordType)); }
/* * @todo REFACTOR, it"s really ugly! * @throws ConversionException */ public ITES5Type ResolveScriptTypeByItsAttachedName(string attachedName) { string attachedNameLower = attachedName.ToLower(); ITES5Type value; if (this.attachedNameCache.TryGetValue(attachedNameLower, out value)) { return(value); } TES4LoadedRecord attachedNameRecord = FindInTES4Collection(attachedName, false); if (attachedNameRecord == null) { throw new ConversionException("Cannot resolve script type by searching its base form edid - no record found, " + attachedName); } TES4RecordType attachedNameRecordType = attachedNameRecord.RecordType; if (attachedNameRecordType == TES4RecordType.REFR || attachedNameRecordType == TES4RecordType.ACRE || attachedNameRecordType == TES4RecordType.ACHR) { //Resolve the reference Nullable <int> baseFormid = attachedNameRecord.GetSubrecordAsFormid("NAME"); attachedNameRecord = esm.FindByFormid(baseFormid.Value); } Nullable <int> scriptFormid = attachedNameRecord.GetSubrecordAsFormid("SCRI"); if (scriptFormid == null) { throw new ConversionException("Cannot resolve script type for " + attachedName + " - Asked base record has no script bound."); } TES4LoadedRecord scriptRecord = esm.FindByFormid(scriptFormid.Value); ITES5Type customType = TES5TypeFactory.MemberByValue(scriptRecord.GetSubrecordTrim("EDID")); this.attachedNameCache.Add(attachedNameLower, customType); return(customType); }
/* * Trie constructor * * This is for internal use */ public Trie(TES4LoadedRecord value = null) { this.value = value; }