static int CollapseInstances(VMF vmf)
        {
            #region Identify useable IDs
            int usableID = vmf.Body.GetHighestID() + 1;
            #endregion

            var world = vmf.Body.Where(node => node.Name == "world").Where(node => node is VBlock).Cast <VBlock>().FirstOrDefault();
            if (world == null)
            {
                Console.WriteLine("Can't find \"world\"");
                return(-1);
            }

            int lastEntityLocation = 0;
            lastEntityLocation = vmf.Body.IndexOf(world) + vmf.Body.Where(node => node.Name == "entity").Count();

            int autoInstance = 0;

            var entities  = vmf.Body.Where(item => item.Name == "entity").Select(item => item as VBlock).ToList();
            var instances = entities.Where(entity => entity.Body.Where(item => item.Name == "classname" && (item as VProperty).Value == "func_instance").Count() > 0).ToList();
            foreach (var instance in instances)
            {
                // Get instance targetname
                string instanceTargetName         = "";
                var    instanceTargetNameProperty = instance.Body.Where(node => node.Name == "targetname" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault();
                if ((instanceTargetNameProperty?.Value ?? "") == "")
                {
                    instanceTargetName = String.Format("AutoInstance{0}", autoInstance++);
                }


                // TODO: Give it a default name if unnamed (or not?).

                // Load the instance vmf
                var fileProp = instance.Body.Where(node => node.Name == "file" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault();
                if (fileProp == null || string.IsNullOrEmpty(fileProp.Value.Trim()))
                {
                    // Looks like there is no file property, or its empty
                    continue;
                }
                if (!File.Exists(fileProp.Value))
                {
                    // TODO: What do you do when the file doesn't exist? Probably should throw up some sort of error.
                    // Just skip it for now.
                    continue;
                }
                var instanceVMF = new VMF(File.ReadAllLines(fileProp.Value));

                // Clone the important parts
                // TODO: think about collapsing groups
                // TODO: only grab visible entities
                var instanceVisibleEntities = instanceVMF.Body.Where(node => node.Name == "entity").Where(node => node is VBlock).Cast <VBlock>();
                var instanceVisibleSolids   = instanceVMF.Body.Where(node => node.Name == "world").Where(node => node is VBlock).Cast <VBlock>()
                                              .SelectMany(node => node.Body.Where(worldNode => worldNode.Name == "solid").Where(worldNode => worldNode is VBlock).Cast <VBlock>()
                                                          );

                // Update each entity into the map with relative offsets and angles from the instance point, and the instance origin (defaults at 0 0 0)
                // angles and origin
                var instanceOriginProperty = instance.Body.Where(node => node.Name == "origin" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault();
                var instanceAnglesProperty = instance.Body.Where(node => node.Name == "angles" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault();

                var instanceOrigin = new Vector3(instanceOriginProperty?.Value ?? "0 0 0");
                var instanceAngles = new Vector3(instanceAnglesProperty?.Value ?? "0 0 0");

                var fixupStyle = int.Parse(instance.Body.Where(node => node.Name == "fixup_style" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault()?.Value ?? "0");


                foreach (var entity in instanceVisibleEntities)
                {
                    VBlock collapsedEntity = CollapseEntity(entity, fixupStyle, instanceTargetName, instanceOrigin, instanceAngles, ref usableID);
                    vmf.Body.Insert(lastEntityLocation++, collapsedEntity);
                }

                foreach (var solid in instanceVisibleSolids)
                {
                    VBlock collapsedSolid = CollapseSolid(solid, ref usableID);
                    world.Body.Add(collapsedSolid);
                }


                // Rename all internal communication
                // Link external IO
                // Replace replaceable parameters
                // Replace replaceable materials
                // Insert into actual map

                // Remove instance from map
                vmf.Body.Remove(instance);
            }


            return(0);
        }
Ejemplo n.º 2
0
 private void AddItemToScope(VBlock vBlock)
 {
     vBlock.ScopeControl?.UpdateScope();
     GlobalScope.Scope.Items.Enqueue(vBlock.VCode);
 }
        static VBlock CollapseSolid(VBlock solid, ref int highID)
        {
            // TODO: transform solid

            return(solid.DeepClone());
        }