예제 #1
0
        /// <summary>
        /// Attempt an attack.
        /// </summary>
        /// <param name="allAttacks">A list of WeaponDetails representing a round of attacks.</param>
        private bool ProcessAttack(WeaponDetails attack)
        {
            // First, check that the target stack we originally identified has not
            // been destroyed (actually, the stack still exists at this point but
            // it may have no ship tokens left). In which case, don't bother trying to
            // fire this weapon system (we'll wait until the next battle clock
            // "tick" and re-target then).
            if (attack.TargetStack == null || attack.TargetStack.IsDestroyed)
            {
                return(false);
            }

            if (attack.SourceStack == null || attack.SourceStack.IsDestroyed)
            {
                // Report.Error("attacking stack no longer exists");
                return(false);
            }

            // If the target stack is not within the range of this weapon system
            // then there is no point in trying to fire it.
            if (PointUtilities.Distance(attack.SourceStack.Position, attack.TargetStack.Position) > attack.Weapon.Range)
            {
                return(false);
            }

            // Target is valid; execute attack.
            ExecuteAttack(attack);

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Check if the fleet hits the minefiled.
        /// </summary>
        /// <remarks>
        /// The probability of hitting a mine is 0.3% per light year traveled for each
        /// warp over the safe speed.
        /// TODO (priority 3) - reference required.
        ///
        /// Example: A fleet traveling at Warp 9 has a 1.5% chance per light year
        /// traveled in a turn.  Traveling 10 light years through the Minefield that
        /// turn, the fleet has a 10.5% chance of triggering a mine.
        /// </remarks>
        /// <param name="fleet">The moving fleet.</param>
        /// <param name="minefield">The minefield being traversed.</param>
        /// <returns>true if the minefield is hit.</returns>
        private bool CheckForHit(Fleet fleet, Minefield minefield)
        {
            // Calculate how long we are going to be in the Minefield. This is the
            // lesser of the distance to the next waypoint and the radius of the
            // field.

            NovaPoint currentPosition = fleet.Position;
            Waypoint  targetWaypoint  = fleet.Waypoints[0];
            NovaPoint targetPosition  = targetWaypoint.Position;

            double travelDistance = PointUtilities.Distance(currentPosition, targetPosition);

            if (minefield.Radius > (int)travelDistance)
            {
                travelDistance = minefield.Radius;
            }

            double speeding    = fleet.Speed - minefield.SafeSpeed;
            double probability = (0.03 * travelDistance * speeding) * 100;
            double dice        = random.Next(0, 100);

            if (dice < probability)
            {
                return(true);
            }

            return(false);
        }
예제 #3
0
        public void Test5PositionStacks()
        {
            battleEngine.PositionStacks(zoneStacks);

            double distance = 0;

            Fleet stackA = zoneStacks[0] as Fleet;
            Fleet stackB = zoneStacks[1] as Fleet;

            distance = PointUtilities.Distance(stackA.Position, stackB.Position);
            Assert.Greater((int)distance, 3); // changed from Global.MaxRange -1 to 3 due to reduction in battle board size from Ken's 20x20 to Stars! 10x10 - Dan 07 Jul 11
        }
예제 #4
0
        /// <summary>
        /// Determine if a fleet is within a Minefield. The fleet is inside the
        /// circle if the distance between the field and the center of the field is
        /// less than the radius of the field.
        /// </summary>
        private bool IsInField(Fleet fleet, Minefield minefield)
        {
            // If we are travelling at a "safe" speed we can just pretend we are
            // not in a Minefield.

            if (fleet.Speed <= minefield.SafeSpeed)
            {
                return(false);
            }

            double distance = PointUtilities.Distance(fleet.Position, minefield.Position);

            if (distance < minefield.Radius)
            {
                return(true);
            }

            return(false);
        }
예제 #5
0
        public void Test6DoBattle()
        {
            Fleet        stackA         = zoneStacks[0] as Fleet;
            Fleet        stackB         = zoneStacks[1] as Fleet;
            List <Fleet> battlingFleets = new List <Fleet>();

            battlingFleets.Add(stackA);
            battlingFleets.Add(stackB);

            double distanceS, distanceE;

            distanceS = PointUtilities.Distance(stackA.Position, stackB.Position);

            battleEngine.DoBattle(zoneStacks);

            distanceE = PointUtilities.Distance(stackA.Position, stackB.Position);

            // Check that the fleets have moved towards each other.

            Assert.Greater(distanceS, distanceE);
        }
예제 #6
0
        /// <Summary>
        /// If there is another waypoint before the selected one, display the fuel,
        /// time, etc. required for this leg.
        /// </Summary>
        /// <param name="index">Index of the waypoint to display.</param>
        private void DisplayLegDetails(int index)
        {
            Waypoint thisWaypoint = selectedFleet.Waypoints[index];

            WaypointTasks.Text = thisWaypoint.Task.Name;

            if (selectedFleet.Waypoints.Count == 1)
            {
                thisWaypoint.WarpFactor = 0;
            }

            selectedFleet.Waypoints[index] = thisWaypoint;
            warpFactor.Value = thisWaypoint.WarpFactor;
            warpText.Text    = "Warp " + thisWaypoint.WarpFactor;

            if (index > 0 && thisWaypoint.WarpFactor > 0)
            {
                Waypoint from     = selectedFleet.Waypoints[index - 1];
                Waypoint to       = selectedFleet.Waypoints[index];
                double   distance = PointUtilities.Distance(from.Position, to.Position);

                double time = distance / (to.WarpFactor * to.WarpFactor);

                double fuelUsed = selectedFleet.FuelConsumption(to.WarpFactor, empireState.Race)

                                  * time;

                legDistance.Text = string.Format("{0}", distance.ToString("f1"));
                legFuel.Text     = string.Format("{0}", fuelUsed.ToString("f1"));
                legTime.Text     = string.Format("{0}", time.ToString("f1"));
            }
            else
            {
                legDistance.Text = "0";
                legFuel.Text     = "0";
                legTime.Text     = "0";
            }

            Waypoint previous     = null;
            double   fuelRequired = 0;

            // Sum up the total fuel required for all waypoints in the current
            // route (as long as there is more than one waypoint).

            foreach (Waypoint waypoint in selectedFleet.Waypoints)
            {
                if (previous != null && waypoint.WarpFactor > 0)
                {
                    double distance   = PointUtilities.Distance(waypoint.Position, previous.Position);
                    int    warp       = waypoint.WarpFactor;
                    double speed      = warp * warp;
                    double travelTime = distance / speed;

                    fuelRequired += selectedFleet.FuelConsumption(warp, empireState.Race) * travelTime;
                }
                previous = waypoint;
            }

            System.Drawing.Color color = fuelRequired > selectedFleet.FuelAvailable ? System.Drawing.Color.Red : System.Drawing.Color.Black;
            routeFuelUse.ForeColor = color;
            label3.ForeColor       = color;
            label5.ForeColor       = color;

            routeFuelUse.Text = fuelRequired.ToString("f1");
        }
예제 #7
0
        /// ----------------------------------------------------------------------------
        /// <Summary>
        /// Populate the display. We use unbound population because some of the fields
        /// need a little logic to decode (we don't just have a bunch of strings).
        /// </Summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">A <see cref="EventArgs"/> that contains the event data.</param>
        /// ----------------------------------------------------------------------------
        private void OnLoad(object sender, EventArgs e)
        {
            const int NumColumns = 11;

            this.fleetGridView.Columns[6].Name = "Cargo";
            this.fleetGridView.AutoSize        = true;

            foreach (Fleet fleet in empireState.OwnedFleets.Values)
            {
                if (fleet.Owner == empireState.Id)
                {
                    if (fleet.Type == ItemType.Starbase)
                    {
                        continue;
                    }

                    string location;
                    if (fleet.InOrbit != null)
                    {
                        location = fleet.InOrbit.Name;
                    }
                    else
                    {
                        location = "Space at " + fleet.Position.ToString();
                    }

                    string destination = "-";
                    string eta         = "-";
                    string task        = "-";

                    if (fleet.Waypoints.Count > 1)
                    {
                        Waypoint waypoint = fleet.Waypoints[1];

                        destination = waypoint.Destination;
                        if (!(waypoint.Task is NoTask))
                        {
                            task = waypoint.Task.Name;
                        }

                        double distance = PointUtilities.Distance(
                            waypoint.Position, fleet.Position);

                        double speed = waypoint.WarpFactor * waypoint.WarpFactor;
                        double time  = distance / speed;

                        eta = time.ToString("F1");
                    }

                    Cargo         cargo     = fleet.Cargo;
                    StringBuilder cargoText = new StringBuilder();

                    cargoText.AppendFormat(
                        "{0} {1} {2} {3}",
                        cargo.Ironium,
                        cargo.Boranium,
                        cargo.Germanium,
                        cargo.ColonistsInKilotons);

                    int      i   = 0;
                    string[] row = new string[NumColumns];

                    row[i++] = fleet.Name;
                    row[i++] = location;
                    row[i++] = destination;
                    row[i++] = eta;
                    row[i++] = task;
                    row[i++] = fleet.FuelAvailable.ToString("f1");
                    row[i++] = cargoText.ToString();
                    row[i++] = fleet.Composition.Count.ToString(System.Globalization.CultureInfo.InvariantCulture);
                    row[i++] = "-";
                    row[i++] = fleet.BattlePlan;
                    row[i++] = fleet.Mass.ToString(System.Globalization.CultureInfo.InvariantCulture);

                    this.fleetGridView.Rows.Add(row);
                }
            }

            this.fleetGridView.AutoResizeColumns();
        }
예제 #8
0
        private void Scan(EmpireData empire)
        {
            foreach (Mappable scanner in empire.IterateAllMappables())
            {
                int scanRange    = 0;
                int penScanRange = 0;

                //Do some self scanning (Update reports) and set ranges..
                if (scanner is Star)
                {
                    scanRange    = (scanner as Star).ScanRange;
                    penScanRange = (scanner as Star).ScanRange; // TODO:(priority 6) Planetary Pen-Scan not implemented yet.
                    empire.StarReports[scanner.Name].Update(scanner as Star, ScanLevel.Owned, serverState.TurnYear);
                }
                else
                {
                    scanRange    = (scanner as Fleet).ScanRange;
                    penScanRange = (scanner as Fleet).PenScanRange;
                    empire.FleetReports[scanner.Key].Update(scanner as Fleet, ScanLevel.Owned, empire.TurnYear);
                }

                // Scan everything
                foreach (Mappable scanned in serverState.IterateAllMappables())
                {
                    // ...That isn't ours!
                    if (scanned.Owner == empire.Id)
                    {
                        continue;
                    }

                    ScanLevel scanLevel = ScanLevel.None;
                    double    range     = 0;
                    range = PointUtilities.Distance(scanner.Position, scanned.Position);

                    if (scanned is Star)
                    {
                        Star star = scanned as Star;

                        // There are two ways to get information from a Star:
                        // 1. In orbit with a fleet,
                        // 2. Not in orbit with a Pen Scan (fleet or star).
                        // Non penetrating distance scans won't tell anything about it.
                        if ((scanner is Fleet) && range == 0)
                        {
                            scanLevel = (scanner as Fleet).CanScan ? ScanLevel.InDeepScan : ScanLevel.InPlace;
                        }
                        else // scanner is Star or non orbiting Fleet
                        {
                            scanLevel = (range <= penScanRange) ? ScanLevel.InDeepScan : ScanLevel.None;
                        }

                        // Dont update if we didn't scan to allow report to age.
                        if (scanLevel == ScanLevel.None)
                        {
                            continue;
                        }

                        if (empire.StarReports.ContainsKey(scanned.Name))
                        {
                            empire.StarReports[scanned.Name].Update((scanned as Star), scanLevel, serverState.TurnYear);
                        }
                        else
                        {
                            empire.StarReports.Add(scanned.Name, (scanned as Star).GenerateReport(scanLevel, serverState.TurnYear));
                        }
                    }
                    else // scanned is Fleet
                    {
                        // Fleets are simple as scan levels (PenScan for example) won't affect them. We only
                        // care for non penetrating distance scans.
                        if (range > scanRange)
                        {
                            continue;
                        }

                        // Check if we have a record of this design(s).
                        foreach (ShipToken token in (scanned as Fleet).Composition.Values)
                        {
                            if (empire.EmpireReports[scanned.Owner].Designs.ContainsKey(token.Design.Key))
                            {
                                continue;
                            }

                            // If not, add just the empty Hull.
                            ShipDesign newDesign = new ShipDesign(token.Design);
                            newDesign.Key = token.Design.Key;
                            newDesign.ClearAllocated();
                            empire.EmpireReports[scanned.Owner].Designs.Add(newDesign.Key, newDesign);
                        }

                        if (!empire.FleetReports.ContainsKey(scanned.Key))
                        {
                            empire.FleetReports.Add(scanned.Key, (scanned as Fleet).GenerateReport(ScanLevel.InScan, serverState.TurnYear));
                        }
                        else
                        {
                            empire.FleetReports[scanned.Key].Update((scanned as Fleet), ScanLevel.InScan, serverState.TurnYear);
                        }
                    }
                }
            }
        }