Beispiel #1
0
        public void AbilitiesFromIdenticalComponents()
        {
            // create engine component template
            ComponentTemplate engineTemplate = new()
            {
                Name = "Ion Engine"
            };

            engineTemplate.Abilities.Add(new Ability(
                                             engineTemplate,
                                             AbilityRule.Find("Standard Ship Movement"),
                                             null,
                                             1));

            // add some engines
            int numEngines = 6;

            for (var i = 0; i < numEngines; i++)
            {
                design.AddComponent(engineTemplate);
            }

            // test thrust
            Assert.AreEqual(numEngines, design.StrategicSpeed);
        }
    }
Beispiel #2
0
        public static Ability AddAbility(this IAbilityContainer obj, AbilityRule rule, params object[] vals)
        {
            var a = new Ability(obj, rule, null, vals);

            obj.Abilities.Add(a);
            return(a);
        }
Beispiel #3
0
 public ShareAbilityClause(Empire giver, Empire receiver, AbilityRule rule, SharingPriority priority)
     : base(giver, receiver)
 {
     AbilityRule = rule;
     Priority    = priority;
 }
Beispiel #4
0
        public override IEnumerable <IModObject> Load(Mod mod)
        {
            foreach (var rec in DataFile.Records)
            {
                var sst = new StarSystemTemplate(null);
                sst.TemplateParameters = rec.Parameters;
                string temp;
                int    index = -1;

                sst.ModID = rec.Get <string>("ID", sst);
                rec.TryFindFieldValue("Name", out temp, ref index, Mod.Errors, 0, true);
                sst.Name = temp;
                mod.StarSystemTemplates.Add(sst);

                rec.TryFindFieldValue("Description", out temp, ref index, Mod.Errors, 0, true);
                sst.Description = temp;

                sst.Radius = rec.Get <int>("Radius") ?? 6;

                rec.TryFindFieldValue("Background Bitmap", out temp, ref index, Mod.Errors, 0, true);
                sst.BackgroundImagePath = Path.GetFileNameWithoutExtension(temp);                 // so we can use PNG when SE4 specifies BMP files

                rec.TryFindFieldValue("Empires Can Start In", out temp, ref index, Mod.Errors, 0, true);
                sst.EmpiresCanStartIn = bool.Parse(temp);

                rec.TryFindFieldValue("Non-Tiled Center Pic", out temp, ref index, Mod.Errors, 0, true);
                sst.NonTiledCenterCombatImage = bool.Parse(temp);

                foreach (var abil in AbilityLoader.Load(Filename, rec, sst))
                {
                    sst.Abilities.Add(abil);
                }

                sst.WarpPointAbilities = Mod.Current.StellarAbilityTemplates.FindByName(rec.Get <string>("WP Stellar Abil Type", sst));

                int count = 0;
                int start = 0;
                while (true)
                {
                    count++;
                    string sobjtype;
                    string pos;

                    if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Physical Type", "Obj Physical Type" }, out temp, ref start, null, start, true))
                    {
                        break;                         // couldn't load next stellar object template
                    }
                    else
                    {
                        sobjtype = temp;
                    }
                    start++;

                    if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Position", "Obj Position" }, out temp, ref start, null, start))
                    {
                        Mod.Errors.Add(new DataParsingException("Could not find \"Obj Position\" field.", Mod.CurrentFileName, rec));
                        continue;                         // skip this stellar object
                    }
                    else
                    {
                        pos = temp;
                    }
                    start++;

                    ITemplate <StellarObject> sobjTemplate;
                    if (sobjtype == "Star" || sobjtype == "Destroyed Star")
                    {
                        var template = new StarTemplate();

                        if (sobjtype == "DestroyedStar")
                        {
                            template.IsDestroyed = true;
                        }

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Stellar Abil Type", "Obj Stellar Abil Type" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Stellar Abil Type\" field for star.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Abilities = mod.StellarAbilityTemplates.FindByName(temp);
                            if (template.Abilities == null)
                            {
                                template.Abilities = new RandomAbilityTemplate();
                                yield return(template.Abilities);

                                Mod.Errors.Add(new DataParsingException("Could not find stellar ability type \"" + temp + "\" in StellarAbilityTypes.txt.", Mod.CurrentFileName, rec));
                            }
                        }

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Size", "Obj Size" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Size\" field for star.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            if (temp == "Any")
                            {
                                template.StellarSize = null;
                            }
                            else
                            {
                                try
                                {
                                    template.StellarSize = temp.ParseEnum <StellarSize>();
                                }
                                catch (ArgumentException ex)
                                {
                                    Mod.Errors.Add(new DataParsingException("Invalid stellar object size \"" + temp + "\". Must be Tiny, Small, Medium, Large, Huge, or Any.", ex, Mod.CurrentFileName, rec));
                                    continue;                                     // skip this stellar object
                                }
                            }
                        }
                        start++;

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Age", "Obj Age" }, out temp, ref start, null, start))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Age\" field for star.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Age = temp == "Any" ? null : temp;
                        }
                        start++;

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Color", "Obj Color" }, out temp, ref start, null, start))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Color\" field for star.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Color = temp == "Any" ? null : temp;
                        }
                        start++;

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Luminosity", "Obj Luminosity" }, out temp, ref start, null, start))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Luminosity\" field for star.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Brightness = temp == "Any" ? null : temp;
                        }
                        start++;

                        sobjTemplate = template;
                    }
                    else if (sobjtype == "Planet")
                    {
                        var template = new PlanetTemplate();

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Stellar Abil Type", "Obj Stellar Abil Type" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Stellar Abil Type\" field for planet.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Abilities = mod.StellarAbilityTemplates.FindByName(temp);
                            if (template.Abilities == null)
                            {
                                template.Abilities = new RandomAbilityTemplate();
                                yield return(template.Abilities);

                                Mod.Errors.Add(new DataParsingException("Could not find stellar ability type \"" + temp + "\" in StellarAbilityTypes.txt.", Mod.CurrentFileName, rec));
                            }
                        }

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Size", "Obj Size" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Size\" field for planet.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            if (temp == "Any")
                            {
                                template.StellarSize = null;
                            }
                            else
                            {
                                try
                                {
                                    template.StellarSize = temp.ParseEnum <Size>();
                                }
                                catch (ArgumentException ex)
                                {
                                    Mod.Errors.Add(new DataParsingException("Invalid stellar object size \"" + temp + "\". Must be Tiny, Small, Medium, Large, Huge, or Any.", ex, Mod.CurrentFileName, rec));
                                    continue;                                     // skip this stellar object
                                }
                            }
                        }
                        start++;

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Atmosphere", "Obj Atmosphere" }, out temp, ref start, null, start))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Atmosphere\" field for planet.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Atmosphere = temp == "Any" ? null : temp;
                        }
                        start++;

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Composition", "Obj Composition" }, out temp, ref start, null, start))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Composition\" field for planet.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Surface = temp == "Any" ? null : temp;
                        }
                        start++;

                        sobjTemplate = template;
                    }
                    else if (sobjtype == "Asteroids")
                    {
                        var template = new AsteroidFieldTemplate();

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Stellar Abil Type", "Obj Stellar Abil Type" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Stellar Abil Type\" field for asteroid field.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Abilities = mod.StellarAbilityTemplates.FindByName(temp);
                            if (template.Abilities == null)
                            {
                                template.Abilities = new RandomAbilityTemplate();
                                yield return(template.Abilities);

                                Mod.Errors.Add(new DataParsingException("Could not find stellar ability type \"" + temp + "\" in StellarAbilityTypes.txt.", Mod.CurrentFileName, rec));
                            }
                        }

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Size", "Obj Size" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Size\" field for asteroid field.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            if (temp == "Any")
                            {
                                template.StellarSize = null;
                            }
                            else
                            {
                                try
                                {
                                    template.StellarSize = (StellarSize)Enum.Parse(typeof(Size), temp);
                                }
                                catch (ArgumentException ex)
                                {
                                    Mod.Errors.Add(new DataParsingException("Invalid stellar object size \"" + temp + "\". Must be Tiny, Small, Medium, Large, Huge, or Any.", ex, Mod.CurrentFileName, rec));
                                    continue;                                     // skip this stellar object
                                }
                            }
                        }
                        start++;

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Atmosphere", "Obj Atmosphere" }, out temp, ref start, null, start))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Atmosphere\" field for asteroid field.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Atmosphere = temp == "Any" ? null : temp;
                        }
                        start++;

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Composition", "Obj Composition" }, out temp, ref start, null, start))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Composition\" field for asteroid field.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Surface = temp == "Any" ? null : temp;
                        }
                        start++;

                        sobjTemplate = template;
                    }
                    else if (sobjtype == "Storm")
                    {
                        var template = new StormTemplate();

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Stellar Abil Type", "Obj Stellar Abil Type" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Stellar Abil Type\" field for storm.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            template.Abilities = mod.StellarAbilityTemplates.FindByName(temp);
                            if (template.Abilities == null)
                            {
                                template.Abilities = new RandomAbilityTemplate();
                                yield return(template.Abilities);

                                Mod.Errors.Add(new DataParsingException("Could not find stellar ability type \"" + temp + "\" in StellarAbilityTypes.txt.", Mod.CurrentFileName, rec));
                            }
                        }

                        if (!rec.TryFindFieldValue(new string[] { "Obj " + count + " Size", "Obj Size" }, out temp, ref start, null, start, true))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not find \"Obj Size\" field for storm.", Mod.CurrentFileName, rec));
                            continue;                             // skip this stellar object
                        }
                        else
                        {
                            if (temp == "Any")
                            {
                                template.Size = null;
                            }
                            else
                            {
                                try
                                {
                                    template.Size = temp.ParseEnum <Size>();
                                }
                                catch (ArgumentException ex)
                                {
                                    Mod.Errors.Add(new DataParsingException("Invalid stellar object size \"" + temp + "\". Must be Tiny, Small, Medium, Large, Huge, or Any.", ex, Mod.CurrentFileName, rec));
                                    continue;                                     // skip this stellar object
                                }
                            }
                        }
                        start++;

                        sobjTemplate = template;
                    }
                    else
                    {
                        Mod.Errors.Add(new DataParsingException("Invalid stellar object type \"" + sobjtype + "\". Must be Star, Planet, Asteroids, or Storm.", Mod.CurrentFileName, rec));
                        continue;
                    }

                    if (pos.StartsWith("Ring "))
                    {
                        int ring;
                        if (!int.TryParse(pos.Substring("Ring ".Length), out ring))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not parse stellar object location \"" + pos + "\". Expected integer after Ring.", Mod.CurrentFileName, rec));
                            continue;
                        }
                        sst.StellarObjectLocations.Add(new RingStellarObjectLocation {
                            Ring = ring, StellarObjectTemplate = sobjTemplate
                        });
                    }
                    else if (pos.StartsWith("Coord ") || pos.StartsWith("Centered Coord "))
                    {
                        int    x, y;
                        string coordsData;
                        bool   isCentered = pos.StartsWith("Centered Coord ");
                        if (isCentered)
                        {
                            coordsData = pos.Substring("Centered Coord ".Length);
                        }
                        else
                        {
                            coordsData = pos.Substring("Coord ".Length);
                        }
                        var splitData = coordsData.Split(',');
                        if (splitData.Length < 2)
                        {
                            Mod.Errors.Add(new DataParsingException("Could not parse stellar object location \"" + pos + "\". Expected two comma separated integers after Coord.", Mod.CurrentFileName, rec));
                            continue;
                        }
                        if (!int.TryParse(splitData[0].Trim(), out x))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not parse stellar object location \"" + pos + "\". Expected two comma separated integers after Coord.", Mod.CurrentFileName, rec));
                            continue;
                        }
                        if (!int.TryParse(splitData[1].Trim(), out y))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not parse stellar object location \"" + pos + "\". Expected two comma separated integers after Coord.", Mod.CurrentFileName, rec));
                            continue;
                        }
                        sst.StellarObjectLocations.Add(new CoordStellarObjectLocation {
                            Coordinates = new Point(x, y), UseCenteredCoordinates = isCentered, StellarObjectTemplate = sobjTemplate
                        });
                    }
                    else if (pos.StartsWith("Same As"))
                    {
                        int idx;
                        if (!int.TryParse(pos.Substring("Same As ".Length), out idx))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not parse stellar object location \"" + pos + "\". Expected integer after Same As.", Mod.CurrentFileName, rec));
                            continue;
                        }
                        if (idx > sst.StellarObjectLocations.Count)
                        {
                            Mod.Errors.Add(new DataParsingException("A \"Same As\" stellar object location can reference only previously defined locations.", Mod.CurrentFileName, rec));
                            continue;
                        }
                        sst.StellarObjectLocations.Add(new SameAsStellarObjectLocation {
                            StarSystemTemplate = sst, TargetIndex = idx, StellarObjectTemplate = sobjTemplate
                        });
                    }
                    else if (pos.StartsWith("Circle Radius "))
                    {
                        int radius;
                        if (!int.TryParse(pos.Substring("Circle Radius ".Length), out radius))
                        {
                            Mod.Errors.Add(new DataParsingException("Could not parse stellar object location \"" + pos + "\". Expected integer after Circle Radius.", Mod.CurrentFileName, rec));
                            continue;
                        }
                        sst.StellarObjectLocations.Add(new CircleRadiusStellarObjectLocation {
                            Radius = radius, StellarObjectTemplate = sobjTemplate
                        });
                    }
                }

                // replace sight obscuration and other abilities that really should belong to sectors but Aaron reused for star systems
                // so we don't get them using the same ability and systems inheriting abilities from storms etc. thus affecting the entire system!
                sst.Abilities.Where(a => a.Rule.Matches("Sector - Sight Obscuration")).SafeForeach(a => a.Rule   = AbilityRule.Find("System - Sight Obscuration"));
                sst.Abilities.Where(a => a.Rule.Matches("Sector - Sensor Interference")).SafeForeach(a => a.Rule = AbilityRule.Find("System - Sensor Interference"));
                sst.Abilities.Where(a => a.Rule.Matches("Sector - Shield Disruption")).SafeForeach(a => a.Rule   = AbilityRule.Find("System - Shield Disruption"));
                sst.Abilities.Where(a => a.Rule.Matches("Sector - Damage")).SafeForeach(a => a.Rule = AbilityRule.Find("System - Damage"));

                yield return(sst);
            }
        }
Beispiel #5
0
        public override IEnumerable <IModObject> Load(Mod mod)
        {
            foreach (var rec in DataFile.Records)
            {
                var r = new AbilityRule();
                r.TemplateParameters = rec.Parameters;
                mod.AbilityRules.Add(r);

                int index = -1;

                r.ModID       = rec.Get <string>("ID", r);
                r.Name        = rec.Get <string>("Name", r, false);
                r.Aliases     = rec.GetMany <string>("Alias", r).Select(f => f.Value).ToList();
                r.Targets     = rec.Get <AbilityTargets>("Targets", r) ?? AbilityTargets.All;
                r.Description = rec.Get <string>("Description", r);
                for (int i = 1; i <= 2; i++)
                {
                    var f = rec.FindField("Value " + i + " Rule", ref index, false, 0, true);
                    if (f == null)
                    {
                        r.ValueRules.Add(AbilityValueRule.None);
                    }
                    else
                    {
                        r.ValueRules.Add(f.CreateFormula <AbilityValueRule>(r));
                    }
                    f = rec.FindField("Value " + i + " Group Rule", ref index, false, 0, true);
                    if (f == null)
                    {
                        r.GroupRules.Add(AbilityValueRule.None);
                    }
                    else
                    {
                        r.GroupRules.Add(f.CreateFormula <AbilityValueRule>(r));
                    }
                }
                int j = 3;
                while (true)
                {
                    var f = rec.FindField("Value " + j + " Rule", ref index, false, 0, true);
                    if (f == null)
                    {
                        break;
                    }
                    else
                    {
                        r.ValueRules.Add(f.CreateFormula <AbilityValueRule>(r));
                    }
                    f = rec.FindField("Value " + j + " Group Rule", ref index, false, 0, true);
                    if (f == null)
                    {
                        r.GroupRules.Add(AbilityValueRule.None);
                    }
                    else
                    {
                        r.GroupRules.Add(f.CreateFormula <AbilityValueRule>(r));
                    }
                }

                yield return(r);
            }
        }