public void LoadIni(Ini ini) { // General Ini.Section secGen = ini["General"]; m_strTitle = secGen["Title"].Value; m_nPlayersMin = int.Parse(secGen["MinPlayers"].Value); m_nPlayersMax = int.Parse(secGen["MaxPlayers"].Value); // SideInfo for (Side side = Side.side1; side <= Side.side4; side++) { Ini.Section sec = ini[side.ToString()]; if (sec == null) { continue; } SideInfo sidi = new SideInfo(side); string s = sec["InitialView"].Value; Regex re = new Regex(@"^(?<tx>(-)?\d+),(?<ty>(-)?\d+)$"); Match m = re.Match(s); int tx = int.Parse(m.Groups["tx"].Value); int ty = int.Parse(m.Groups["ty"].Value); Point ptInitialView = new Point(tx + Bounds.Left, ty + Bounds.Top); if (ptInitialView.X < Bounds.Left) { ptInitialView.X = Bounds.Left; } if (ptInitialView.Y < Bounds.Top) { ptInitialView.Y = Bounds.Top; } sidi.InitialView = ptInitialView; sidi.InitialCredits = int.Parse(sec["InitialCredits"].Value); sidi.Intelligence = (Intelligence)int.Parse(sec["Intelligence"].Value); m_alsidi.Add(sidi); } // Misc MapItems. Areas must come before GameObjects because GameObjects // can refer to Areas by index in UnitActions. string[] secNames = { "Galaxite", "Areas", "GameObjects" }; foreach (string secName in secNames) { Ini.Section sec = ini[secName]; ArrayList alsMapItems = new ArrayList(); foreach (Ini.Property prop in sec) { IMapItem mi = CreateGameObject(secName, prop.Name, prop.Value); if (mi != null) { alsMapItems.Add(mi); } } // Sometimes Areas are given the same name. Then on export the sort order // doesn't match the original, which is a problem since in the game, area // creation order is important. if (secName == "Areas") { for (int i = 0; i < alsMapItems.Count; i++) { Area ar = (Area)alsMapItems[i]; ar.BonusSortKey = i; } } AddMapItems((IMapItem[])alsMapItems.ToArray(typeof(IMapItem))); } // Switches (must be before triggers). foreach (Ini.Property prop in ini["Switches"]) { m_swm.AddSwitch(new Switch(prop.Name)); } // UnitGroups (must be before triggers). m_ugm.LoadIni(ini); // Triggers m_tgrm.LoadIni(ini); // Clear out __cuaa UnitGroups now that triggers have been loaded // (CreateUnitAtAreaTrigger loads state from __cuaa triggers). ArrayList alsRemove = new ArrayList(); for (int i = 0; i < m_ugm.Items.Count; i++) { UnitGroup ug = (UnitGroup)m_ugm.Items[i]; if (ug.Name.StartsWith("__cuaa")) { alsRemove.Add(ug); } } foreach (UnitGroup ug in alsRemove) { m_ugm.RemoveUnitGroup(ug); } // TODO: remove the demo check trigger }
public void SaveIni(Stream stm, int nVersion, string strFileTmap, string strFileTrmap, string strFilePalette, bool fDemoCheckTrigger) { Ini ini = new Ini(); Ini.Section sec; // [Intro] sec = new Ini.Section("Intro"); sec.Add(new Ini.Property("String", "This is a test level!")); ini.Add(sec); // [Side1-n] int txOrigin = Bounds.X; int tyOrigin = Bounds.Y; // Hack - there should be a real "neutral" side ArrayList alsidiT = (ArrayList)m_alsidi.Clone(); SideInfo sidiNeutral = new SideInfo(Side.sideNeutral); sidiNeutral.Intelligence = Intelligence.ComputerNeutral; sidiNeutral.InitialCredits = 0; sidiNeutral.InitialView = new Point(0, 0); alsidiT.Add(sidiNeutral); foreach (SideInfo sidi in alsidiT) { sec = new Ini.Section(sidi.Side.ToString()); sec.Add(new Ini.Property("InitialView", String.Format("{0},{1}", sidi.InitialView.X - txOrigin, sidi.InitialView.Y - tyOrigin))); sec.Add(new Ini.Property("InitialCredits", sidi.InitialCredits.ToString())); sec.Add(new Ini.Property("Intelligence", "knIntelligence" + sidi.Intelligence.ToString())); // How many units for this side? int cStructures = 0; int cMobileUnits = 0; foreach (IMapItem mi in m_alsmi) { if (mi is Unit) { Unit unt = (Unit)mi; if (unt.Side == sidi.Side) { if (mi is MobileUnit) { cMobileUnits++; } if (mi is Structure) { cStructures++; } } } } sec.Add(new Ini.Property("InitialMobileUnitCount", cMobileUnits.ToString())); sec.Add(new Ini.Property("InitialStructureCount", cStructures.ToString())); ini.Add(sec); } // [GameObjects] sec = new Ini.Section("GameObjects"); foreach (IMapItem mi in m_alsmi) { if (mi is Galaxite) continue; if (mi is Area) continue; if (mi is Wall) continue; if (mi is Tile) continue; Ini.Property prop = mi.GetIniProperty(txOrigin, tyOrigin); if (prop == null) continue; // Skip Gobs that are out of bounds // UNDONE: can't do the right thing to make sure Gob's right/bottom // edges aren't out of bounds because M doesn't know the true // width and height of Gobs. if (!Bounds.Contains(new Rectangle((int)mi.tx, (int)mi.ty, mi.ctx, mi.cty))) { Console.WriteLine("{0} out of bounds", mi); continue; } sec.Add(prop); } ini.Add(sec); // [Galaxite] sec = new Ini.Section("Galaxite"); foreach (IMapItem mi in m_alsmi) { if (!(mi is Galaxite)) continue; Ini.Property prop = mi.GetIniProperty(txOrigin, tyOrigin); if (prop == null) continue; // Skip Galaxite that is out of bounds if (!Bounds.Contains((int)mi.tx, (int)mi.ty)) { Console.WriteLine("{0} out of bounds", mi); continue; } sec.Add(prop); } ini.Add(sec); #if false // In terrain now // [Walls] sec = new Ini.Section("Walls"); foreach (IMapItem mi in m_alsmi) { if (!(mi is Wall)) continue; Ini.Property prop = mi.GetIniProperty(txOrigin, tyOrigin); if (prop == null) continue; // Skip Walls that are out of bounds if (!Bounds.Contains((int)mi.tx, (int)mi.ty)) { Console.WriteLine("{0} out of bounds", mi); continue; } sec.Add(prop); } ini.Add(sec); #endif // [Areas] ArrayList alT = new ArrayList(); foreach (IMapItem mi in m_alsmi) { if (!(mi is Area)) continue; alT.Add(mi); } alT.Sort(); sec = new Ini.Section("Areas"); foreach (IMapItem mi in alT) { Ini.Property prop = mi.GetIniProperty(txOrigin, tyOrigin); if (prop == null) continue; Area area = (Area)mi; if (!Bounds.Contains(new Rectangle((int)mi.tx, (int)mi.ty, mi.ctx, mi.cty))) { MessageBox.Show(String.Format("The area \"{0}\" lies outside of the map's bounds", area.Name), "Error Compiling Level"); } sec.Add(prop); } ini.Add(sec); // [Triggers] // NOTE: Triggers must be written before UnitGroups because some trigger actions // e.g., CreateUnitAtArea will dynamically create UnitGroups and add them to the UnitGroup list ini.Add(m_tgrm.GetIniSection(fDemoCheckTrigger)); // [UnitGroup 0-n] m_ugm.SaveIni(ini); // [Switches] sec = new Ini.Section("Switches"); foreach (Switch sw in SwitchManager.Items) sec.Add(new Ini.Property(sw.Name, "")); ini.Add(sec); // [General] // This section is written last in case any of the values are modified by // the process of writing out the prior sections (e.g., CreateUnitAtArea actions add UnitGroups) sec = new Ini.Section("General", null); sec.Add(new Ini.Property("Title", Title)); sec.Add(new Ini.Property("TileMap", strFileTmap)); sec.Add(new Ini.Property("TerrainMap", strFileTrmap)); sec.Add(new Ini.Property("Palette", strFilePalette)); sec.Add(new Ini.Property("MinPlayers", m_nPlayersMin.ToString())); sec.Add(new Ini.Property("MaxPlayers", m_nPlayersMax.ToString())); sec.Add(new Ini.Property("UnitGroupCount", m_ugm.Items.Count.ToString())); // < 0 means use the current version, otherwise use the passed version // This is the "level file format" version if (nVersion < 0) nVersion = 1; sec.Add(new Ini.Property("Version", nVersion.ToString())); // Add a random number for the revision #. This # is used to determine if saved games are // based on older versions of a mission. if (nVersion > 0) { Random rand = new Random(); uint dwRevision = (uint)rand.Next(); sec.Add(new Ini.Property("Revision", dwRevision.ToString())); } ini.Add(sec); // Done ini.Save(stm); // Mostly Done. // Clean out the "__cuaa" unit groups created by CreateUnitAtAreaTriggerAction ArrayList alsRemove = new ArrayList(); UnitGroup[] aug = (UnitGroup[])m_ugm.Items.ToArray(typeof(UnitGroup)); for (int i = 0; i < m_ugm.Items.Count; i++) { if (((UnitGroup)m_ugm.Items[i]).Name.StartsWith("__cuaa")) { alsRemove.Add(m_ugm.Items[i]); } } foreach (UnitGroup ug in alsRemove) { m_ugm.RemoveUnitGroup(ug); } }
public SideInfo GetSideInfo(Side side) { foreach (SideInfo sidi in m_alsidi) { if (sidi.Side == side) return sidi; } SideInfo sidiNew = new SideInfo(side); m_alsidi.Add(sidiNew); SetModified(true); return sidiNew; }