public FrameworkMod()
 {
     Utils.ErrorTexture = ModTextures.Find(x => x.name.Equals("error.png"));
 }
    public static string ProcessModXml(Stream stream, string dir)
    {
        XElement root = XElement.Load(stream);

        foreach (var elem in root.Elements("Ground"))
        {
            short  type = 0x3000;
            string id   = elem.Attribute("id").Value;

            if (!ItemIds.ContainsKey(id))
            {
                for (var i = 0x3001; i < 0xffff; i++)
                {
                    if (!UsedIds.Contains((short)i))
                    {
                        ItemIds.Add(id, (short)i);
                        UsedIds.Add((short)i);
                    }
                }
            }
            type = ItemIds[id];

            elem.SetAttributeValue("type", type);

            TypeToId[type]      = id;
            IdToType[id]        = type;
            TypeToElement[type] = elem;

            TileDescs[type] = new TileDesc(elem);
        }
        foreach (var elem in root.Elements("Object"))
        {
            if (elem.Element("Class") == null)
            {
                continue;
            }
            string cls  = elem.Element("Class").Value;
            short  type = 0x4000;
            string id   = elem.Attribute("id").Value;

            if (!ItemIds.ContainsKey(id))
            {
                for (var i = 0x4001; i < 0xffff; i++)
                {
                    if (!UsedIds.Contains((short)i))
                    {
                        ItemIds.Add(id, (short)i);
                        UsedIds.Add((short)i);
                        break;
                    }
                }
            }
            type = ItemIds[id];

            Console.Out.WriteLine("(" + new DirectoryInfo(dir).Name + ") Adding mod object: " + id + " (" + type.ToString() + ")");
            if (File.Exists(dir + ds + id + ".png"))
            {
                Console.Out.WriteLine("(" + new DirectoryInfo(dir).Name + ") Adding mod texture: " + id);

                if (elem.Element("RemoteTexture") != null)
                {
                    elem.Element("RemoteTexture").Remove();
                }
                if (elem.Element("Texture") != null)
                {
                    elem.Element("Texture").Remove();
                }

                XElement texElem = new XElement("RemoteTexture",
                                                new XElement("Instance",
                                                             new XText("production")
                                                             ),
                                                new XElement("Id",
                                                             new XText("mod:" + id)
                                                             )
                                                );

                elem.Add(texElem);

                try
                {
                    ModTextures.Add(id, File.ReadAllBytes(dir + ds + id + ".png"));
                }
                catch { Console.Out.WriteLine("(" + new DirectoryInfo(dir).Name + ") Error adding texture: " + id); }
            }

            elem.SetAttributeValue("type", type);

            TypeToId[type]      = id;
            IdToType[id]        = type;
            TypeToElement[type] = elem;

            if (cls == "Equipment" || cls == "Dye" || cls == "Pet")
            {
                ItemDescs[type] = new Item(elem);
                if (elem.Element("Shop") != null)
                {
                    XElement shop = elem.Element("Shop");
                    ItemShops[type]  = shop.Element("Name").Value;
                    ItemPrices[type] = Utils.FromString(shop.Element("Price").Value);
                }
            }
            if (cls == "Character" || cls == "GameObject" || cls == "Wall" ||
                cls == "ConnectedWall" || cls == "CaveWall" || cls == "Portal")
            {
                ObjectDescs[type] = new ObjectDesc(elem);
            }
            if (cls == "Portal")
            {
                try
                {
                    PortalDescs[type] = new PortalDesc(elem);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error for portal: " + type + " id: " + id);

                    /*3392,1792,1795,1796,1805,1806,1810,1825 -- no location, assume nexus?*
                     *  Tomb Portal of Cowardice,  Dungeon Portal,  Portal of Cowardice,  Realm Portal,  Glowing Portal of Cowardice,  Glowing Realm Portal,  Nexus Portal,  Locked Wine Cellar Portal*/
                }
            }

            XElement key = elem.Element("Key");
            if (key != null)
            {
                Keys.Add(type);
                KeyPrices[type] = Utils.FromString(key.Value);
            }
        }
        foreach (var elem in root.Elements("Dungeon"))
        {
            string name     = elem.Attribute("name").Value;
            short  portalid = (short)Utils.FromString(elem.Attribute("type").Value);

            IdToDungeon[portalid] = name;
            DungeonDescs[name]    = new DungeonDesc(elem);
        }
        using (StringWriter sw = new StringWriter())
        {
            root.Save(sw);
            return(sw.ToString());
        }
    }
        public override void Init()
        {
            if (XmlTechnologies != null)
            {
                Techs = new List <Tech>(XmlTechnologies.Length);

                Debug.Log("Attempting to load " + XmlTechnologies.Length + " new technologies");

                foreach (Technology technology in XmlTechnologies)
                {
                    Tech newTech;

                    try
                    {
                        newTech = Builder.CreateTechObject(technology.ClassName);
                    }
                    catch (Exception e)
                    {
                        Debug.Log("Error creating Tech with classname \"" + technology.ClassName + "\"");
                        Utils.LogException(e);
                        continue;
                    }

                    newTech.mName = technology.Name ?? technology.ClassName;

                    if (StringList.exists(newTech.mName))
                    {
                        newTech.mName = StringList.get(newTech.mName).Trim();
                    }

                    newTech.mValue = technology.Cost;

                    MerchantCategory category;

                    try
                    {
                        category = (MerchantCategory)Enum.Parse(typeof(MerchantCategory), technology.MerchantCategory);
                    }
                    catch (Exception e)
                    {
                        Debug.Log("\"" + technology.MerchantCategory + "\" category for \"" + technology.ClassName +
                                  "\" tech in mod \"" + ModName +
                                  "\" does not match any values for the MerchantCategory enum.");
                        Utils.LogException(e);
                        continue;
                    }

                    newTech.mMerchantCategory = category;

                    newTech.mDescription = technology.Description;

                    if (StringList.exists(newTech.mDescription))
                    {
                        newTech.mDescription = StringList.get(newTech.mDescription).Trim();
                    }

                    newTech.mIcon = technology.Icon == null ? Utils.ErrorTexture : ModTextures.FindTextureWithName(technology.Icon.FileName);

                    TypeList <Tech, TechList> .getInstance().add(newTech);

                    Techs.Add(newTech);

                    Debug.Log("Successfully loaded new technology \"" + newTech.getName() + "\"");
                }

                Debug.Log("Loaded " + Techs.Count + " new technologies successfully");
            }

            if (XmlBuildings != null)
            {
                Buildings = new List <ModuleType>(XmlBuildings.Length);

                Debug.Log("Attempting to load " + XmlBuildings.Length + " new buildings");

                foreach (Building xmlBuilding in XmlBuildings)
                {
                    try
                    {
                        BuildingModuleType newBuilding;

                        try
                        {
                            newBuilding = Builder.CreateBuildingModuleTypeObject(xmlBuilding.ClassName);
                        }
                        catch (Exception e)
                        {
                            {
                                Debug.Log("Error creating Building with classname \"" + xmlBuilding.ClassName + "\"");
                                Utils.LogException(e);
                                continue;
                            }
                        }

                        newBuilding.mName = xmlBuilding.DisplayName ?? xmlBuilding.ClassName;

                        if (StringList.exists(newBuilding.mName))
                        {
                            newBuilding.mName = StringList.get(newBuilding.mName).Trim();
                        }

                        newBuilding.ModuleObjects = new GameObject[xmlBuilding.Models.Length];

                        for (int i = 0; i < xmlBuilding.Models.Length; i++)
                        {
                            GameObject modelRootObject = new GameObject {
                                name = newBuilding.mName + " root gameobject"
                            };

                            foreach (Obj xmlGameObject in xmlBuilding.Models[i].GameObjects)
                            {
                                GameObject template = ModObjects.FindObjectByFilename(xmlGameObject.MeshFileName);

                                if (template != null)
                                {
                                    GameObject clone = GameObject.Instantiate(template);

                                    clone.tag = xmlGameObject.Tag == GameObjectTags.UNDEFINED ?
                                                GameObjectTags.Untagged.ToString() : xmlGameObject.Tag.ToString();

                                    clone.transform.SetParent(modelRootObject.transform, false);
                                }
                                else
                                {
                                    Debug.Log("Couldn't find a file named \"" + xmlGameObject.MeshFileName + "\" in the mod's assets\\obj folder.");
                                }
                            }

                            modelRootObject.SetActive(true);

                            newBuilding.ModuleObjects[i] = modelRootObject;
                        }

                        newBuilding.mMaxSize = xmlBuilding.Models.Length - 1;

                        newBuilding.mDefaultSize = (int)Math.Floor((decimal)newBuilding.mMaxSize / 2);

                        newBuilding.mIcon = xmlBuilding.Icon == null ? Utils.ErrorTexture : ModTextures.FindTextureWithName(xmlBuilding.Icon.FileName);

                        if (xmlBuilding.Configuration != null)
                        {
                            if (xmlBuilding.Configuration.BaseResources != null)
                            {
                                newBuilding.BaseResourceCosts = new ResourceAmount[xmlBuilding.Configuration.BaseResources.Length];

                                for (int i = 0; i < xmlBuilding.Configuration.BaseResources.Length; i++)
                                {
                                    ResourceType type =
                                        TypeList <ResourceType, ResourceTypeList> .find(xmlBuilding.Configuration.BaseResources[i].XmlResourceType);

                                    newBuilding.BaseResourceCosts[i] = new ResourceAmount(type, xmlBuilding.Configuration.BaseResources[i].Amount);
                                }
                            }

                            if (xmlBuilding.Configuration.Properties != null)
                            {
                                if (xmlBuilding.Configuration.Properties.Flags != null)
                                {
                                    newBuilding.mFlags = xmlBuilding.Configuration.Properties.Flags.BitField;
                                }

                                if (xmlBuilding.Configuration.Properties.MaxUsers != null)
                                {
                                    newBuilding.mMaxUsers = (int)xmlBuilding.Configuration.Properties.MaxUsers.Value;
                                }

                                if (xmlBuilding.Configuration.Properties.Panel != null)
                                {
                                    try
                                    {
                                        ModuleType.Panel parsedEnumValue = (ModuleType.Panel)Enum.Parse(typeof(ModuleType.Panel),
                                                                                                        xmlBuilding.Configuration.Properties.Panel.Value);

                                        newBuilding.mRelatedPanel = parsedEnumValue;
                                    }
                                    catch (Exception e)
                                    {
                                        Debug.Log("Exception thrown while converting \"" + xmlBuilding.Configuration.Properties.Panel + "\" to enum of type \"ModuleType.Panel\"");
                                        Debug.Log(e);
                                    }
                                }

                                if (xmlBuilding.Configuration.Properties.Layout != null)
                                {
                                    try
                                    {
                                        ModuleType.LayoutType parsedEnumValue = (ModuleType.LayoutType)Enum.Parse(typeof(ModuleType.LayoutType),
                                                                                                                  xmlBuilding.Configuration.Properties.Layout.Value);

                                        newBuilding.mLayoutType = parsedEnumValue;
                                    }
                                    catch (Exception e)
                                    {
                                        Debug.Log("Exception thrown while converting \"" + xmlBuilding.Configuration.Properties.Layout + "\" to enum of type \"ModuleType.LayoutType\"");
                                        Debug.Log(e);
                                    }
                                }


                                if (xmlBuilding.Configuration.Properties.XmlExtraSizeTech != null &&
                                    TypeList <Tech, TechList> .find(xmlBuilding.Configuration.Properties.XmlExtraSizeTech.Value) != null)
                                {
                                    newBuilding.mExtraSizeTech =
                                        TypeList <Tech, TechList> .find(xmlBuilding.Configuration.Properties.XmlExtraSizeTech.Value);

                                    newBuilding.mExtraSize = newBuilding.mMaxSize;
                                    newBuilding.mMaxSize--;
                                }

                                if (xmlBuilding.Configuration.Properties.PowerStorageCapacity != null)
                                {
                                    newBuilding.mPowerStorageCapacity = xmlBuilding.Configuration.Properties.PowerStorageCapacity.Value;
                                }

                                if (xmlBuilding.Configuration.Properties.WaterStorageCapacity != null)
                                {
                                    newBuilding.mWaterStorageCapacity = xmlBuilding.Configuration.Properties.WaterStorageCapacity.Value;
                                }

                                if (xmlBuilding.Configuration.Properties.PowerGenerationRate != null)
                                {
                                    newBuilding.mPowerGeneration = xmlBuilding.Configuration.Properties.PowerGenerationRate.Value;
                                }

                                if (xmlBuilding.Configuration.Properties.WaterGenerationRate != null)
                                {
                                    newBuilding.mWaterStorageCapacity = xmlBuilding.Configuration.Properties.WaterGenerationRate.Value;
                                }

                                if (xmlBuilding.Configuration.Properties.IsExterior != null)
                                {
                                    newBuilding.mExterior = xmlBuilding.Configuration.Properties.IsExterior.Value;
                                }

                                if (xmlBuilding.Configuration.Properties.XmlComponents != null)
                                {
                                    List <ComponentType> validComponents = new List <ComponentType>(xmlBuilding.Configuration.Properties.XmlComponents.Length);

                                    foreach (AttributeClassName <string> componentTypeName in xmlBuilding.Configuration.Properties.XmlComponents)
                                    {
                                        ComponentType foundType =
                                            TypeList <ComponentType, ComponentTypeList> .find(componentTypeName.Value);

                                        if (foundType != null)
                                        {
                                            validComponents.Add(foundType);
                                        }
                                    }

                                    newBuilding.mComponentTypes = validComponents.ToArray();
                                }

                                if (xmlBuilding.Configuration.Properties.ToolTip != null)
                                {
                                    newBuilding.mTooltip = xmlBuilding.Configuration.Properties.ToolTip.Value;

                                    if (StringList.exists(newBuilding.mTooltip))
                                    {
                                        newBuilding.mTooltip = StringList.get(newBuilding.mTooltip).Trim();
                                    }
                                }

                                if (xmlBuilding.Configuration.Properties.Decay != null)
                                {
                                    ResourceType foundResource =
                                        TypeList <ResourceType, ResourceTypeList> .find(xmlBuilding.Configuration.Properties.Decay
                                                                                        .RepairResource);

                                    if (foundResource != null)
                                    {
                                        newBuilding.mCondicionDecayTime = xmlBuilding.Configuration.Properties.Decay.Time;
                                        newBuilding.mRepairResource     = foundResource;
                                    }
                                    else
                                    {
                                        Debug.Log("Cound not find a loaded resource matching \"" + xmlBuilding.Configuration.Properties.Decay.RepairResource + "\"");
                                    }
                                }

                                if (xmlBuilding.Configuration.Properties.Prestige != null)
                                {
                                    newBuilding.mPrestige = xmlBuilding.Configuration.Properties.Prestige.Value;
                                }
                            }
                        }

                        TypeList <ModuleType, ModuleTypeList> .getInstance().add(newBuilding);

                        Buildings.Add(newBuilding);

                        Debug.Log("Successfully loaded new building \"" + newBuilding.getName() + "\"");
                    }
                    catch (Exception e)
                    {
                        Debug.Log("Failed to load new building. Exception thrown: ");
                        Utils.LogException(e);
                    }
                }

                Debug.Log("Successfully loaded " + Buildings.Count + " new buildings");
            }
        }