예제 #1
0
        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
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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;
        }