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.");
}
public void VMMCollapse(string output) { Console.WriteLine("collapsing VMM"); // find the topLevel vmf List <Dictionary <string, string> > topLevels = vmfs.FindAll(dic => dic.Keys.Contains("TopLevel")); if (topLevels.Count == 0) { TopLevelVmf = vmfs.First(); } else { TopLevelVmf = topLevels.Aggregate((curMin, x) => (curMin == null || int.Parse(x["TopLevel"]) < int.Parse(curMin["topLevel"]) ? x : curMin)); } vmfs.Remove(TopLevelVmf); //start file VMFFile topmap = new VMFFile(vmfdir + "/" + TopLevelVmf["File"]); VMFVector3Value originVal = new VMFVector3Value { X = 0, Y = 0, Z = 0 }; VMFVector3Value anglesVal = new VMFVector3Value { Pitch = 0, Roll = 0, Yaw = 0 }; VMFNumberValue fixup_styleVal = new VMFNumberValue { Value = 0 }; foreach (Dictionary <string, string> vmf in vmfs) { Console.WriteLine("Inserting submap of {0}", vmfdir + "/" + vmf["File"]); VMFFile submap = new VMFFile(vmfdir + "/" + vmf["File"]); foreach (VMFStructure worldStruct in submap.World) { if (worldStruct.Type == VMFStructureType.Group || worldStruct.Type == VMFStructureType.Solid) { VMFStructure clone = worldStruct.Clone(topmap.LastID, topmap.LastNodeID); clone.Transform(originVal, anglesVal); topmap.World.Structures.Add(clone); } } foreach (VMFStructure rootStruct in submap.Root) { if (rootStruct.Type == VMFStructureType.Entity) { VMFStructure clone = rootStruct.Clone(topmap.LastID, topmap.LastNodeID); clone.Transform(originVal, anglesVal); topmap.Root.Structures.Add(clone); } } topmap.updateIds(); } topmap.ResolveInstances(); topmap.Save(vmfdir + ".vmf"); }