private static String FixupName(String name, TargetNameFixupStyle fixupStyle, String targetName)
        {
            if (fixupStyle == TargetNameFixupStyle.None || targetName == null || name.StartsWith("@") || name.StartsWith("!"))
            {
                return(name);
            }

            switch (fixupStyle)
            {
            case TargetNameFixupStyle.Postfix:
                return(name + targetName);

            case TargetNameFixupStyle.Prefix:
                return(targetName + name);

            default:
                return(name);
            }
        }
        private static String FixupName(String name, TargetNameFixupStyle fixupStyle, String targetName)
        {
            if (targetName == null || name.StartsWith("!"))
            {
                return(name);
            }
            else if (name.StartsWith("@"))
            {
                return(name.Substring(1));
            }
            switch (fixupStyle)
            {
            case TargetNameFixupStyle.Postfix:
                return(name + '-' + targetName);

            case TargetNameFixupStyle.Prefix:
                return(targetName + '-' + name);

            default:
                return(name);
            }
        }
        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 VMFStructure Clone(int idOffset      = 0, int nodeOffset = 0, TargetNameFixupStyle fixupStyle = TargetNameFixupStyle.None,
                           String targetName = null, List <KeyValuePair <String, String> > replacements = null, List <KeyValuePair <String, String> > matReplacements = null)
 {
     return(new VMFStructure(this, idOffset, nodeOffset, fixupStyle, targetName, replacements, matReplacements));
 }
        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;
        }