Example #1
0
        public void UpdateDistance(GameFormation source, GameFormation target, int rangeShift)
        {
            (var rangeBetweenFormations, var rangeReciprocal) = this.UpdateDistance(source.FormationId, target.FormationId, rangeShift);

            // var consoleTail = $"{Math.Abs(rangeShift)} [{rangeBetweenFormations.Value - rangeShift} >> {rangeBetweenFormations.Value}]";
            // Console.WriteLine($"-- Range {(rangeShift == 0 ? "unchanged" : (rangeShift < 0 ? "decreases by " : "increases by ") + consoleTail)}");
        }
Example #2
0
        private FormationDistance AddEdge(GameFormation nodeA, GameFormation nodeB, int edgeWeight)
        {
            var newEdge = new FormationDistance(nodeA, nodeB, edgeWeight);

            this.edges.Add(newEdge);

            return(newEdge);
        }
Example #3
0
 public FormationDistance(GameFormation source, GameFormation target, int value)
 {
     this.SourceFormationId   = source.FormationId;
     this.SourceFormationName = source.FormationName;
     this.TargetFormationId   = target.FormationId;
     this.TargetFormationName = target.FormationName;
     this.Value = value;
 }
Example #4
0
        public FormationDistance SetDistance(GameFormation nodeA, GameFormation nodeB, int distance)
        {
            var edge           = this.GetOrEstablishDistance(nodeA.FormationId, nodeB.FormationId, distance);
            var edgeReciprocal = this.GetOrEstablishDistance(nodeB.FormationId, nodeA.FormationId, distance);

            edge.Value           = distance;
            edgeReciprocal.Value = distance;

            return(edge);
        }
Example #5
0
        private Tuple <FormationDistance, FormationDistance> GetGraphState(GameFormation nodeA, GameFormation nodeB)
        {
            // No edges can exist between a Formation and itself
            if (nodeA.FormationId == nodeB.FormationId)
            {
                throw new InvalidOperationException($"Cannot get distance-graph data between a formation ([ID {nodeA.FormationId}] {nodeA.FormationName}) and itself ([ID {nodeB.FormationId})] {nodeB.FormationName}");
            }

            var edge           = this.GetOrEstablishDistance(nodeA, nodeB);
            var edgeReciprocal = this.GetOrEstablishDistance(nodeB, nodeA);

            return(new Tuple <FormationDistance, FormationDistance>(edge, edgeReciprocal));
        }
Example #6
0
        // TODO: Move this to the distanceGraph class
        public int CalculateRangeShift(int currentVolley, GameFormation source, int sourceSpeed, GameFormation target)
        {
            var type     = this.ManeuverType;
            var priority = this.Priority;
            var speed    = Math.Max(0, sourceSpeed + GetManeuverModifier(this.Priority));

            var log = $"   --- Execute [{source.FormationId}]{source.FormationName} : {priority} {type} ({speed}s)";

            var targetOrders = target.Orders
                               .Where(tO => tO.Volley == currentVolley)
                               .FirstOrDefault() ?? Constants.DefaultVolleyOrders;
            var targetManeuver = targetOrders.ManeuveringOrders
                                 .Where(tRO => tRO.TargetID == source.FormationId)
                                 .FirstOrDefault() ?? Constants.DefaultManeuverOrder;

            var opposingPriority = targetManeuver.Priority;
            var opposingType     = targetManeuver.ManeuverType;
            var opposingSpeed    = Math.Max(0, targetOrders.SpeedSuccesses + GetManeuverModifier(targetManeuver.Priority));

            log += $" vs [{target.FormationId}]{target.FormationName} : {opposingPriority} {opposingType} ({opposingSpeed}s) ";

            var margin          = speed - opposingSpeed;
            var rangeShift      = 0;
            var successDistance = this.ManeuverType == "Close" ? -Constants.RangeShiftPerSuccess : Constants.RangeShiftPerSuccess;

            var maneuverTypePair = new Tuple <string, string>(this.ManeuverType, targetManeuver.ManeuverType);

            // Unopposed auto-successes
            if (maneuverTypePair.Equals(Constants.CloseVersusClose) || maneuverTypePair.Equals(Constants.WithdrawVersusWithdraw))
            {
                // Ignore opponent's Speed successes, they will be resolved separately
                rangeShift = successDistance * speed;
            }

            // "True" versus test -- if active F got more successes, distance changes; otherwise not.
            if (maneuverTypePair.Equals(Constants.CloseVersusMaintain) || maneuverTypePair.Equals(Constants.CloseVersusWithdraw) || maneuverTypePair.Equals(Constants.WithdrawVersusClose) || maneuverTypePair.Equals(Constants.WithdrawVersusMaintain))
            {
                rangeShift = successDistance * Math.Max(0, margin);

                // Ignore cases where opponent's successes were higher, they will be resolved separately (if not a Maintain already)
            }

            // Console.WriteLine(log);
            return(rangeShift);
        }
Example #7
0
        public FormationDistance GetOrEstablishDistance(int sourceId, int targetId, int establishDistance)
        {
            // Ensure valid inputs
            GameFormation nodeA = this.GetNodeById(sourceId);
            GameFormation nodeB = this.GetNodeById(targetId);

            if (establishDistance < 0)
            {
                throw new InvalidOperationException($"Invalid starting distance {establishDistance}: Formation distances must always be nonnegative.");
            }

            FormationDistance edge           = this.GetEdge(nodeA, nodeB);
            FormationDistance edgeReciprocal = this.GetEdge(nodeB, nodeA);

            // edge-weight is equal to the edge-weight of the existing edge(s) or else the specified "establishDistance"
            var edgeWeight = edge != null ? edge.Value : edgeReciprocal != null ? edgeReciprocal.Value : establishDistance;

            // ensure both edge and its reciprocal exist
            edge           = edge ?? this.AddEdge(nodeA, nodeB, edgeWeight);
            edgeReciprocal = edgeReciprocal ?? this.AddEdge(nodeB, nodeA, edgeWeight);

            return(edge);
        }
 public GameUnitFormationInfo(List <GameUnit> units, int unitId, List <GameFormation> formations, int formationId)
 {
     this.unitReference      = GetUnitById(units, unitId);
     this.formationReference = GetFormationById(formations, formationId);
     this.Refresh();
 }
 public GameUnitFormationInfo(List <GameUnit> units, int unitId, GameFormation formation)
 {
     this.unitReference      = GetUnitById(units, unitId);
     this.formationReference = formation;
     this.Refresh();
 }
 public GameUnitFormationInfo(GameUnit unit, GameFormation formation)
 {
     this.unitReference      = unit;
     this.formationReference = formation;
     this.Refresh();
 }
 public GameUnitFormationInfo()
 {
     this.unitReference      = new GameUnit();
     this.formationReference = new GameFormation();
     this.Refresh();
 }
Example #12
0
 /// <summary>
 /// Gets the current <see cref="FormationDistance" edge between two <see cref="GameFormation"/>s;
 ///  if one does not exist, establishes a new entry of distance <see cref="Constants.DefaultStartingRange"/>/>
 /// </summary>
 /// <param name="source">A <see cref="GameFormation"/></param>
 /// <param name="target">A second <see cref="GameFormation"/></param>
 /// <returns><see cref="FormationDistance"/> between two <see cref="GameFormation"/>s specified.</returns>
 public FormationDistance GetOrEstablishDistance(GameFormation source, GameFormation target)
 {
     return(this.GetOrEstablishDistance(source.FormationId, target.FormationId));
 }
Example #13
0
 private void SyncGraphState(FormationDistance edge, FormationDistance edgeReciprocal, GameFormation nodeA, GameFormation nodeB)
 {
     // If neither the source -> target nor target -> source distances are in the Distances graph, create them at default starting range
     if (edge is null && edgeReciprocal is null)
     {
         edge           = this.AddEdge(nodeA, nodeB, Constants.DefaultStartingRange);
         edgeReciprocal = this.AddEdge(nodeB, nodeA, Constants.DefaultStartingRange);
     }
Example #14
0
 /// <summary>
 /// Find one existing <see cref="GameFormation"/> edge between two specified <see cref="GameFormation"/>s.
 /// </summary>
 /// <param name="nodeA">Desired "source" node.</param>
 /// <param name="nodeB">Desired "target" node.</param>
 /// <returns>
 /// The existing <see cref="FormationDistance"/> edge from <paramref name="nodeA"/> to <paramref name="nodeB"/>, or null if none exists
 /// </returns>
 /// <remarks>
 /// Note that this method will *not* return the reciprocal edge if one exists (although one shouldn't, if the specified edge does not).
 /// </remarks>
 private FormationDistance GetEdge(GameFormation nodeA, GameFormation nodeB)
 {
     return(this.edges.Where(e => e.SourceFormationId == nodeA.FormationId && e.TargetFormationId == nodeB.FormationId).FirstOrDefault());
 }