public VMFStructure(String type, StreamReader reader) { if (stTypeDict.ContainsKey(type)) { Type = stTypeDict[type]; } else { Type = VMFStructureType.Unknown; } Properties = new List <KeyValuePair <String, VMFValue> >(); Structures = new List <VMFStructure>(); myIDIndex = -1; String line; while (!reader.EndOfStream && (line = reader.ReadLine().Trim()) != "}") { if (line == "{" || line.Length == 0) { continue; } if (line[0] == '"') { String[] pair = line.Trim('"').Split(new String[] { "\" \"" }, StringSplitOptions.None); if (pair.Length != 2) { continue; } KeyValuePair <String, VMFValue> keyVal; if (Type == VMFStructureType.Normals || Type == VMFStructureType.Offsets || Type == VMFStructureType.Offset_Normals) { keyVal = new KeyValuePair <string, VMFValue>(pair[0], new VMFVector3ArrayValue() { String = pair[1] }); } else { keyVal = new KeyValuePair <string, VMFValue>(pair[0], VMFValue.Parse(pair[1])); } if (keyVal.Key == "id" && keyVal.Value is VMFNumberValue) { myIDIndex = Properties.Count; } Properties.Add(keyVal); } else { Structures.Add(new VMFStructure(line, reader)); } } }
public static VMFValue Parse(String str) { foreach (Tuple <ConstructorInfo, Regex, int> type in stTypes) { if (type.Item2.IsMatch(str)) { VMFValue val = (VMFValue)type.Item1.Invoke(new object[0]); try { val.String = str; } catch { Console.WriteLine("Error while parsing \"" + str + "\"!"); } return(val); } } return(new VMFStringValue { String = str }); }
public void ResolveInstances() { Console.WriteLine("Resolving instances for " + OriginalPath + "..."); List <VMFStructure> structures = Root.Structures; int autoName = 0; for (int i = structures.Count - 1; i >= 0; --i) { VMFStructure structure = structures[i]; if (structure.Type == VMFStructureType.Entity) { VMFValue classnameVal = structure["classname"]; if (classnameVal != null) { switch (classnameVal.String) { case "func_instance": structures.RemoveAt(i); VMFStringValue fileVal = structure["file"] as VMFStringValue; VMFVector3Value originVal = (structure["origin"] as VMFVector3Value) ?? new VMFVector3Value { X = 0, Y = 0, Z = 0 }; VMFVector3Value anglesVal = (structure["angles"] as VMFVector3Value) ?? new VMFVector3Value { Pitch = 0, Roll = 0, Yaw = 0 }; VMFNumberValue fixup_styleVal = (structure["fixup_style"] as VMFNumberValue) ?? new VMFNumberValue { Value = 0 }; VMFValue targetnameVal = structure["targetname"]; Regex pattern = new Regex("^replace[0-9]*$"); List <KeyValuePair <String, String> > replacements = new List <KeyValuePair <String, String> >(); List <KeyValuePair <String, String> > matReplacements = new List <KeyValuePair <String, String> >(); foreach (KeyValuePair <String, VMFValue> keyVal in structure.Properties) { if (pattern.IsMatch(keyVal.Key)) { String[] split = keyVal.Value.String.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (split.Length < 1) { continue; } if (split[0].StartsWith("#")) { matReplacements.Add(new KeyValuePair <String, String>(split[0].Substring(1).Trim(), keyVal.Value.String.Substring(split[0].Length + 1).Trim())); continue; } if (!split[0].StartsWith("$")) { Console.WriteLine("Invalid property replacement name \"{0}\" - needs to begin with a $", split[0]); continue; } replacements.Add(new KeyValuePair <String, String>(split[0].Trim(), keyVal.Value.String.Substring(split[0].Length + 1).Trim())); } } replacements = replacements.OrderByDescending(x => x.Key.Length).ToList(); matReplacements = matReplacements.OrderByDescending(x => x.Key.Length).ToList(); TargetNameFixupStyle fixupStyle = (TargetNameFixupStyle)fixup_styleVal.Value; String targetName = (targetnameVal != null ? targetnameVal.String : null); if (fixupStyle != TargetNameFixupStyle.None && targetName == null) { targetName = "AutoInstance" + (autoName++); } if (fileVal == null) { Console.WriteLine("Invalid instance at (" + originVal.String + ")"); continue; } Console.WriteLine("Inserting instance of {0} at ({1}), ({2})", fileVal.String, originVal.String, anglesVal.String); String file = fileVal.String; VMFFile vmf = null; if (stVMFCache.ContainsKey(file)) { vmf = stVMFCache[file]; } else { vmf = new VMFFile(file, Path.GetDirectoryName(OriginalPath)); if (vmf.Root != null) { vmf.ResolveInstances(); } } if (vmf.Root == null) { Console.WriteLine("Could not insert!"); continue; } foreach (VMFStructure worldStruct in vmf.World) { if (worldStruct.Type == VMFStructureType.Group || worldStruct.Type == VMFStructureType.Solid) { VMFStructure clone = worldStruct.Clone(LastID, LastNodeID, fixupStyle, targetName, replacements, matReplacements); clone.Transform(originVal, anglesVal); World.Structures.Add(clone); } } int index = i; foreach (VMFStructure rootStruct in vmf.Root) { if (rootStruct.Type == VMFStructureType.Entity) { VMFStructure clone = rootStruct.Clone(LastID, LastNodeID, fixupStyle, targetName, replacements, matReplacements); clone.Transform(originVal, anglesVal); Root.Structures.Insert(index++, clone); } } LastID = Root.GetLastID(); LastNodeID = Root.GetLastNodeID(); break; case "func_instance_parms": structures.RemoveAt(i); break; } } } } Console.WriteLine("Instances resolved."); }
private VMFStructure(VMFStructure clone, int idOffset, int nodeOffset, TargetNameFixupStyle fixupStyle, String targetName, List <KeyValuePair <String, String> > replacements, List <KeyValuePair <String, String> > matReplacements) { Type = clone.Type; Properties = new List <KeyValuePair <string, VMFValue> >(); Structures = new List <VMFStructure>(); myIDIndex = clone.myIDIndex; Dictionary <String, TransformType> entDict = stDefaultEntDict; if (Type == VMFStructureType.Entity) { String className = clone["classname"].String; if (className != null && stEntitiesDict.ContainsKey(className)) { entDict = stEntitiesDict[className]; } } foreach (KeyValuePair <String, VMFValue> keyVal in clone.Properties) { String str = keyVal.Value.String; bool fixup = true; if (replacements != null && str.Contains("$")) { fixup = false; foreach (KeyValuePair <String, String> repKeyVal in replacements) { str = str.Replace(repKeyVal.Key, repKeyVal.Value); } } KeyValuePair <String, VMFValue> kvClone; if (keyVal.Value is VMFVector3ArrayValue) { kvClone = new KeyValuePair <string, VMFValue>(keyVal.Key, new VMFVector3ArrayValue() { String = str }); } else { kvClone = new KeyValuePair <string, VMFValue>(keyVal.Key, VMFValue.Parse(str)); } if (Type == VMFStructureType.Connections) { if (fixupStyle != TargetNameFixupStyle.None && targetName != null) { String[] split = kvClone.Value.String.Split(','); split[0] = FixupName(split[0], fixupStyle, targetName); if (stInputsDict.ContainsKey(split[1])) { switch (stInputsDict[split[1]]) { case TransformType.EntityName: split[2] = FixupName(split[2], fixupStyle, targetName); break; // add more later } } kvClone.Value.String = String.Join(",", split); } } else { if (Type == VMFStructureType.Side && matReplacements != null && kvClone.Key == "material") { var material = kvClone.Value.String; foreach (KeyValuePair <String, String> repKeyVal in matReplacements) { if (material == repKeyVal.Key) { ((VMFStringValue)kvClone.Value).String = repKeyVal.Value; break; } } } else if (kvClone.Key == "groupid") { ((VMFNumberValue)kvClone.Value).Value += idOffset; } else if (kvClone.Key == "nodeid") { ((VMFNumberValue)kvClone.Value).Value += nodeOffset; } else if (Type == VMFStructureType.Entity) { TransformType trans = entDict.ContainsKey(kvClone.Key) ? entDict[kvClone.Key] : TransformType.None; if (trans == TransformType.Identifier) { kvClone.Value.OffsetIdentifiers(idOffset); } else if (fixup && (kvClone.Key == "targetname" || trans == TransformType.EntityName) && fixupStyle != TargetNameFixupStyle.None && targetName != null) { kvClone = new KeyValuePair <string, VMFValue>(kvClone.Key, new VMFStringValue { String = FixupName(kvClone.Value.String, fixupStyle, targetName) }); } } } Properties.Add(kvClone); } foreach (VMFStructure structure in clone.Structures) { Structures.Add(new VMFStructure(structure, idOffset, nodeOffset, fixupStyle, targetName, replacements, matReplacements)); } ID += idOffset; }