Beispiel #1
0
        public static Fix16 calcFowardThrust(SeekingWeaponInfo skrinfo)
        {
            int   wpnskrspd = skrinfo.SeekerSpeed;
            int   hitpoints = skrinfo.SeekerDurability;
            Fix16 mass      = hitpoints * 0.1;

            return((Fix16)wpnskrspd * mass * (Fix16)10.0);
        }
Beispiel #2
0
        public static Compass calcRotate(SeekingWeaponInfo skrinfo)
        {
            int   wpnskrspd   = skrinfo.SeekerSpeed;
            int   hitpoints   = skrinfo.SeekerDurability;
            Fix16 mass        = hitpoints * 0.1;
            int   wpnskrEvade = Mod.Current.Settings.SeekerEvasion;

            return(new Compass((Fix16)wpnskrspd * mass * (Fix16)10 / ((Fix16)2.5 - (Fix16)wpnskrEvade * (Fix16)0.01), false));
        }
Beispiel #3
0
        public static Fix16 calcStrafeThrust(SeekingWeaponInfo skrinfo)
        {
            int   wpnskrspd   = skrinfo.SeekerSpeed;
            int   hitpoints   = skrinfo.SeekerDurability;
            Fix16 mass        = hitpoints * 0.1;
            int   wpnskrEvade = Mod.Current.Settings.SeekerEvasion;

            return((Fix16)wpnskrspd * mass * (Fix16)5.0 / ((Fix16)4 - (Fix16)wpnskrEvade * (Fix16)0.01));
        }
Beispiel #4
0
        public CombatSeeker(CombatObject attacker, CombatWeapon launcher, int ID)
            : base(null, new PointXd(attacker.cmbt_loc), new PointXd(attacker.cmbt_vel), ID, "SKR")
        {
            WorkingObject = this;
            SeekingWeaponInfo skrinfo = (SeekingWeaponInfo)launcher.weapon.Template.ComponentTemplate.WeaponInfo;

            Hitpoints = MaxHitpoints = skrinfo.SeekerDurability;
            cmbt_mass = (Fix16)Hitpoints * 0.1;//(Fix16)s.MaxHitpoints; // sure why not?


            maxfowardThrust = calcFowardThrust(skrinfo);
            maxStrafeThrust = calcStrafeThrust(skrinfo);
            maxRotate       = calcRotate(skrinfo);


            cmbt_thrust = new PointXd(0, 0, 0);
            cmbt_accel  = new PointXd(0, 0, 0);

            newDice(ID);
#if DEBUG
            Console.WriteLine("MaxAccel = " + maxfowardThrust / cmbt_mass);
#endif
            this.launcher = launcher;
        }
Beispiel #5
0
        public CombatWeapon(Component weapon)
        {
#if DEBUG
            Console.WriteLine("Creating New CombatWeapon");
#endif
            this.weapon = weapon;
#if DEBUG
            Console.WriteLine("Getting Weapon Template WeaponInfo");
#endif
            var wpninfo = weapon.Template.ComponentTemplate.WeaponInfo;
#if DEBUG
            Console.WriteLine("Done");
            Console.WriteLine("Getting Range info");
#endif
            int wpMaxR = wpninfo.MaxRange;
#if DEBUG
            Console.WriteLine("Done MaxRange");
#endif
            int wpMinR = wpninfo.MinRange;
#if DEBUG
            Console.WriteLine("Done MinRange");
#endif
#if DEBUG
            Console.WriteLine("done getting random info");
#endif
            if (wpninfo.DisplayEffect.GetType() == typeof(Combat.BeamWeaponDisplayEffect))
            {
                weaponType = "Beam";

                maxRange_distance = (Fix16)wpMaxR * Battle_Space.KilometersPerSquare;
                minRange          = (Fix16)wpMinR * Battle_Space.KilometersPerSquare;
            }
            else if (wpninfo.DisplayEffect.GetType() == typeof(Combat.ProjectileWeaponDisplayEffect))
            {
                weaponType = "Bolt";

                boltSpeed     = (Fix16)wpMaxR * Battle_Space.KilometersPerSquare;
                maxRange_time = (Fix16)1;                    // (maxTime for bolts) untill mod files can handle this, bolt weapons range is the distance it can go in 1 sec.
                minRange      = ((Fix16)wpMinR / boltSpeed); //(minTime for bolts) distance / speed = time
            }
            else if (wpninfo.DisplayEffect.GetType() == typeof(Combat.SeekerWeaponDisplayEffect))
            {
#if DEBUG
                Console.WriteLine("CombatWeapon is a Seeker");
#endif
                SeekingWeaponInfo seekerinfo = (SeekingWeaponInfo)weapon.Template.ComponentTemplate.WeaponInfo;
                weaponType = "Seeker";
                boltSpeed  = 0;                              //seekers get launched at 0 speed.
                int mass      = seekerinfo.SeekerDurability; // sure why not?
                int wpnskrspd = seekerinfo.SeekerSpeed;
                //Fix16 Thrust = (Fix16)wpnskrspd * mass * (Fix16)0.001;

                //boltSpeed = (Fix16)wpMaxR * (Fix16)1000 * (Fix16)(Battle_Space.TickLength); // convert from kilometers per second to meters per tick
                maxRange_time = (Fix16)wpMaxR / (Fix16)wpnskrspd; // (maxTime for Missiles) untill mod files can handle this, bolt weapons range is the distance it can go in 1 sec.
            }
            else //treat it like a beam I guess.
            {
                weaponType        = "Unknown";
                maxRange_distance = (Fix16)wpMaxR * Battle_Space.KilometersPerSquare;
                minRange          = (Fix16)wpMinR * Battle_Space.KilometersPerSquare;
            }
            double wpiReloadRate = wpninfo.ReloadRate;
            reloadRate = (Fix16)wpiReloadRate;
            nextReload = 1;
#if DEBUG
            Console.WriteLine("Done creating CombatWeapon");
#endif
        }
Beispiel #6
0
        public static Fix16 seekerTimeToTarget(CombatObject attacker, CombatObject target, SeekingWeaponInfo skrinfo)
        {
            //Fix16 distance_toTarget = Trig.distance(attacker.cmbt_loc, target.cmbt_loc);
            PointXd px = new PointXd(attacker.cmbt_loc - target.cmbt_loc);
            Fix16   distance_toTarget = px.Length;
            //SeekingWeaponInfo seekerinfo = (SeekingWeaponInfo)weapon.Template.ComponentTemplate.WeaponInfo;
            int   hitpoints    = skrinfo.SeekerDurability;
            Fix16 mass         = hitpoints * 0.1;
            int   wpnskrspd    = skrinfo.SeekerSpeed;
            Fix16 Thrust       = calcFowardThrust(skrinfo);
            Fix16 acceleration = Thrust / mass * -1; //*-1 because we should be accelerating towards the target, not away.
            Fix16 startV       = seekerClosingSpeed_base(attacker, target);
            //Fix16 endV = ???
            Fix16 baseTimetoTarget = distance_toTarget / startV;

            //Fix16 deltaV = baseTimetoTarget
            //Fix16[] ttt = NMath.quadratic(acceleration, startV, distance_toTarget);
            Fix64[] ttt2 = NMath.quadratic64(acceleration, startV, distance_toTarget);

            Fix16 TimetoTarget;

            if (ttt2[2] == 1)
            {
                TimetoTarget = Fix16.Max((Fix16)ttt2[0], (Fix16)ttt2[1]);
            }
            else
            {
                TimetoTarget = (Fix16)ttt2[0];
            }
#if DEBUG
            Console.WriteLine("SeekerTimeToTarget = " + TimetoTarget);
#endif
            return(TimetoTarget);
        }
Beispiel #7
0
        public override IEnumerable <IModObject> Load(Mod mod)
        {
            foreach (var rec in DataFile.Records)
            {
                var c = new ComponentTemplate();
                c.TemplateParameters = rec.Parameters;
                mod.ComponentTemplates.Add(c);

                int index = -1;

                c.ModID       = rec.Get <string>("ID", c);
                c.Name        = rec.Get <string>("Name", c);
                c.Description = rec.Get <string>("Description", c);

                var picfield = rec.FindField("Pic", ref index, false, 0, true);
                if (picfield != null)
                {
                    c.PictureName = picfield.CreateFormula <string>(c);
                }
                else
                {
                    c.PictureName = "Comp_" + rec.Get <int>("Pic Num", c).Value.ToString("000");                    // for compatibility with SE4
                }
                c.Size       = rec.Get <int>("Tonnage Space Taken", c);
                c.Durability = rec.Get <int>("Tonnage Structure", c);

                foreach (var costfield in rec.Fields.Where(cf => cf.Name.StartsWith("Cost ")))
                {
                    c.Cost[Resource.Find(costfield.Name.Substring("Cost ".Length))] = costfield.CreateFormula <int>(c);
                }

                var vtoverridefield = rec.FindField(new string[] { "Vehicle List Type Override", "Vechicle List Type Override" }, ref index, false, 0, true);                 // silly Aaron can't spell "vehicle"
                if (vtoverridefield != null)
                {
                    c.VehicleTypes = ParseVehicleTypes(vtoverridefield.Value, ",", rec);
                }
                else
                {
                    c.VehicleTypes = ParseVehicleTypes(rec.Get <string>("Vehicle Type", c), @"\", rec);
                }

                c.SupplyUsage = rec.Get <int>("Supply Amount Used", c);

                var restrictions = rec.Get <string>("Restrictions", c);
                if (!string.IsNullOrEmpty(restrictions) && restrictions != "None")
                {
                    var word = restrictions.Value.Split(' ').First();
                    int num;
                    if (numbers.Contains(word))
                    {
                        c.MaxPerVehicle = numbers.IndexOf(word);
                    }
                    else if (int.TryParse(word, out num))
                    {
                        c.MaxPerVehicle = num;
                    }
                    else
                    {
                        Mod.Errors.Add(new DataParsingException("Can't parse \"" + word + "\" as a max-per-vehicle restriction.", Mod.CurrentFileName, rec));
                    }
                }

                c.Group                    = rec.Get <string>("General Group", c);
                c.Family                   = rec.Get <string>("Family", c);
                c.RomanNumeral             = rec.Get <int>("Roman Numeral", c);
                c.StellarConstructionGroup = rec.Get <string>("Custom Group", c);

                foreach (var tr in RequirementLoader.LoadEmpireRequirements(rec, c, RequirementType.Unlock))
                {
                    c.UnlockRequirements.Add(tr);
                }

                // TODO - build and use requirements

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

                var wfield = rec.FindField("Weapon Type", ref index, false, 0, true);
                if (wfield != null)
                {
                    WeaponInfo w = null;
                    if (wfield.Value == "Seeking" || wfield.Value == "Seeking Point-Defense")
                    {
                        var sw = new SeekingWeaponInfo();
                        sw.SeekerSpeed      = rec.Get <int>("Weapon Seeker Speed", c);
                        sw.SeekerDurability = rec.Get <int>("Weapon Seeker Dmg Res", c);
                        w = sw;
                    }
                    else if (wfield.Value == "Direct Fire" || wfield.Value == "Point-Defense")
                    {
                        var dfw = new DirectFireWeaponInfo();
                        dfw.AccuracyModifier = rec.Get <int>("Weapon Modifier", c);
                        w = dfw;
                    }
                    else if (wfield.Value == "Warhead" || wfield.Value == "Warhead Point-Defense")
                    {
                        var ww = new WarheadWeaponInfo();
                        w = ww;
                    }
                    else if (string.IsNullOrEmpty(wfield.Value) || wfield.Value == "None")
                    {
                        w = null;
                    }
                    else
                    {
                        Mod.Errors.Add(new DataParsingException("Invalid weapon type \"" + wfield.Value + "\".", Mod.CurrentFileName, rec, wfield));
                    }
                    if (w != null)
                    {
                        if (wfield.Value.EndsWith("Point-Defense"))
                        {
                            w.IsPointDefense = true;
                        }

                        var wtoverridefield = rec.FindField("Weapon List Target Override", ref index, false, 0, true);
                        if (wtoverridefield != null)
                        {
                            w.Targets = ParseWeaponTargets(wtoverridefield.Value, ",", rec);
                        }
                        else
                        {
                            w.Targets = ParseWeaponTargets(rec.Get <string>("Weapon Target", c), @"\", rec);
                        }

                        w.MinRange = rec.Get <int>(new string[] { "Min Range", "Minimum Range", "Weapon Min Range", "Weapon Minimum Range" }, c) ?? 0;
                        w.MaxRange = rec.Get <int>(new string[] { "Max Range", "Maximum Range", "Weapon Max Range", "Weapon Maximum Range" }, c) ?? 20;
                        var dmgfield = rec.FindField(new string[] { "Damage", "Weapon Damage", "Damage At Rng", "Weapon Damage At Rng", "Damage At Range", "Weapon Damage At Range" }, ref index);
                        if (dmgfield.Value.StartsWith("="))
                        {
                            w.Damage = dmgfield.CreateFormula <int>(c);
                        }
                        else
                        {
                            string dmgstr = null;
                            try
                            {
                                var dict  = new SafeDictionary <int, int>();
                                var split = dmgfield.Value.Split(' ');
                                for (var i = 0; i < split.Length; i++)
                                {
                                    if (split[i].ToInt() == 0)
                                    {
                                        continue;
                                    }
                                    dict[i + 1] = split[i].ToInt();
                                }

                                // HACK - SE4 doesn't explicitly specify damage at range zero so copy the damage at range one value
                                if (dict[1] != 0)
                                {
                                    dict[0]    = dict[1];
                                    w.MinRange = 0;
                                }

                                w.MinRange = dict.Keys.Min();
                                w.MaxRange = dict.Keys.Max();

                                w.Damage = dict.BuildMultiConditionalLessThanOrEqual(c, "range", 0);
                            }
                            catch (Exception ex)
                            {
                                Mod.Errors.Add(new DataParsingException("Can't parse \"" + dmgstr + "\" as a damage string: " + ex.Message, Mod.CurrentFileName, rec));
                            }
                        }

                        var damTypeName = rec.Get <string>("Weapon Damage Type", c);
                        w.DamageType = Mod.Current.DamageTypes.FindByName(damTypeName);

                        if (w.DamageType == null)
                        {
                            // no valid damage type? then make it normal damage and log a warning
                            w.DamageType = DamageType.Normal;
                            Mod.Errors.Add(new DataParsingException("Unknown damage type \"" + damTypeName + "\"; setting " + c + "'s damage type to Normal.", Mod.CurrentFileName, rec));
                        }

                        w.ReloadRate = rec.Get <double>("Weapon Reload Rate", c);

                        var wdisptype = rec.Get <string>("Weapon Display Type", c);
                        var wdispname = rec.Get <string>("Weapon Display", c);
                        if (wdisptype == "Beam")
                        {
                            w.DisplayEffect = new BeamWeaponDisplayEffect(wdispname);
                        }
                        else if (wdisptype == "Torp" || wdisptype == "Torpedo" || wdisptype == "Projectile")
                        {
                            w.DisplayEffect = new ProjectileWeaponDisplayEffect(wdispname);
                        }
                        else if (wdisptype == "Seeker")
                        {
                            w.DisplayEffect = new SeekerWeaponDisplayEffect(wdispname);
                        }
                        else
                        {
                            Mod.Errors.Add(new DataParsingException("Invalid weapon display effect type \"" + wdisptype + "\".", Mod.CurrentFileName, rec));
                        }

                        // sanity check
                        if (wdisptype == "Beam" && w is SeekingWeaponInfo)
                        {
                            Mod.Errors.Add(new DataParsingException("A seeking weapon cannot use a beam display effect.", Mod.CurrentFileName, rec));
                        }

                        w.Sound  = rec.Get <string>("Weapon Sound", c);
                        w.Family = rec.Get <string>("Weapon Family", c);
                    }
                    c.WeaponInfo = w;

                    yield return(c);
                }
            }
        }