Exemplo n.º 1
0
        public bool HandleMovementOrder(ControlGroup Group, ArcenPoint MoveOrderPoint, bool isQueuedCommand)
        {
            ArcenSparseLookup <GameEntity, ArcenPoint> entitiesToPlace;
            GameEntity     coreUnit;
            int            shieldCoverageRadiusOrEquivalent, paddingAroundEachUnit;
            ArcenRectangle firstUnitRect;

            UtilityFunctions_Formation.Helper_FindAndPlaceCoreUnit(Group, MoveOrderPoint, out entitiesToPlace, out coreUnit, out shieldCoverageRadiusOrEquivalent, out paddingAroundEachUnit, out firstUnitRect);

            List <GameEntity> foreZoneEntities, aftZoneEntities;

            UtilityFunctions_Formation.Helper_GetForeAndAftZoneEntities(entitiesToPlace, out foreZoneEntities, out aftZoneEntities);

            int occupiedRadius = coreUnit.TypeData.Radius + paddingAroundEachUnit;

            int degreeBufferOnEachEndOfEachArc = 15;
            int arcWidth           = 180 - (degreeBufferOnEachEndOfEachArc * 2);
            int foreArcCenterAngle = 0;
            int aftArcCenterAngle  = foreArcCenterAngle + 180;

            if (Reverse)
            {
                List <GameEntity> temp = foreZoneEntities;
                foreZoneEntities = aftZoneEntities;
                aftZoneEntities  = temp;
            }

            occupiedRadius = Helper_PlaceRings(foreZoneEntities, entitiesToPlace, isQueuedCommand, paddingAroundEachUnit, MoveOrderPoint, occupiedRadius,
                                               NonSimAngleDegrees.Create(foreArcCenterAngle - (arcWidth / 2)), NonSimAngleDegrees.Create(arcWidth));

            // resetting this for the aft arc
            occupiedRadius = coreUnit.TypeData.Radius + paddingAroundEachUnit;

            occupiedRadius = Helper_PlaceRings(aftZoneEntities, entitiesToPlace, isQueuedCommand, paddingAroundEachUnit, MoveOrderPoint, occupiedRadius,
                                               NonSimAngleDegrees.Create(aftArcCenterAngle - (arcWidth / 2)), NonSimAngleDegrees.Create(arcWidth));

            UtilityFunctions_Formation.Helper_RotatePointsAccordingToAngleFromCoreUnit(MoveOrderPoint, isQueuedCommand, entitiesToPlace, coreUnit);

            UtilityFunctions_Formation.Helper_ActuallyIssueMoveOrders(isQueuedCommand, entitiesToPlace);

            return(true);
        }
Exemplo n.º 2
0
        public static void Helper_RotatePointsAccordingToAngleFromCoreUnit(ArcenPoint MoveOrderPoint, bool isQueuedCommand, ArcenSparseLookup <GameEntity, ArcenPoint> entitiesToPlace, GameEntity coreUnit)
        {
            // rotate points according to angle from first unit to target
            Vector2 originPoint = coreUnit.WorldLocation.ToVector2();

            if (isQueuedCommand)
            {
                for (int i = 0; i < coreUnit.EntitySpecificOrders.QueuedOrders.Count; i++)
                {
                    EntityOrder order = coreUnit.EntitySpecificOrders.QueuedOrders[i];
                    if (order.TypeData.Type != EntityOrderType.Move)
                    {
                        continue;
                    }
                    originPoint = order.RelatedPoint.ToVector2();
                }
            }

            Vector2 moveOrderVectorPoint = MoveOrderPoint.ToVector2();

            NonSimAngleDegrees angle         = originPoint.GetAngleToDegrees(moveOrderVectorPoint);
            NonSimAngleDegrees baseAngle     = NonSimAngleDegrees.Create(0);
            NonSimAngleDegrees rotationAngle = angle.Add(baseAngle);

            for (int i = 0; i < entitiesToPlace.GetPairCount(); i++)
            {
                ArcenSparseLookupPair <GameEntity, ArcenPoint> pair = entitiesToPlace.GetPairByIndex(i);
                Vector2            destinationPoint = pair.Value.ToVector2();
                NonSimAngleDegrees subAngle         = moveOrderVectorPoint.GetAngleToDegrees(destinationPoint);
                Vector2            movementVector   = destinationPoint - moveOrderVectorPoint;
                float distance = movementVector.magnitude;//involves sqrt, is awful, but in interface code of this kind it's probably fine
                NonSimAngleDegrees finalAngle   = rotationAngle.Add(subAngle);
                Vector2            rotatedPoint = moveOrderVectorPoint;
                rotatedPoint.x           += (float)(distance * finalAngle.Cos());
                rotatedPoint.y           += (float)(distance * finalAngle.Sin());
                entitiesToPlace[pair.Key] = rotatedPoint.ToArcenPoint();
            }
        }
Exemplo n.º 3
0
        private static int Helper_PlaceRings(List <GameEntity> entitiesToPlaceWithinZone, ArcenSparseLookup <GameEntity, ArcenPoint> overallEntitySet, bool isQueuedCommand, int paddingAroundEachUnit, ArcenPoint Center, int CurrentOccupiedRadius, NonSimAngleDegrees StartingAngle, NonSimAngleDegrees ArcWidth)
        {
            NonSimAngleRadians arcWidthRadians = ArcWidth.ToRadians();
            int unitIndex = 0;

            while (unitIndex < entitiesToPlaceWithinZone.Count)
            {
                GameEntity firstEntityOnRing = entitiesToPlaceWithinZone[unitIndex];
                int        firstUnitRadius   = firstEntityOnRing.TypeData.Radius + paddingAroundEachUnit;

                int radiusOfNewRing = CurrentOccupiedRadius + firstUnitRadius;

                NonSimAngleRadians workingAngle      = StartingAngle.ToRadians();
                NonSimAngleRadians sumOfArcIncreases = NonSimAngleRadians.Create(0);
                int        lastUnitRadius            = 0;
                ArcenPoint firstPointFound           = ArcenPoint.OutOfRange;
                for ( ; unitIndex < entitiesToPlaceWithinZone.Count; unitIndex++)
                {
                    GameEntity entity = entitiesToPlaceWithinZone[unitIndex];

                    int thisUnitRadius = entity.TypeData.Radius + paddingAroundEachUnit;

                    int distanceNeededFromPreviousPoint = 0;
                    if (lastUnitRadius > 0)
                    {
                        distanceNeededFromPreviousPoint = lastUnitRadius + thisUnitRadius;
                    }
                    lastUnitRadius = thisUnitRadius;

                    if (distanceNeededFromPreviousPoint > 0)
                    {
                        if (distanceNeededFromPreviousPoint > radiusOfNewRing)
                        {
                            break;
                        }
                        if (radiusOfNewRing <= 0)
                        {
                            break;
                        }
                        float unitDistanceNeeded = (float)distanceNeededFromPreviousPoint / (float)radiusOfNewRing; //translating this to "distance" on the unit circle

                        //Given point A at angle M on a circle, increasing the angle by N results in another point at a distance of 2*sin(N/2) from point A
                        //D=2*sin(N/2)
                        //D/2=sin(N/2)
                        //arcsin(D/2)=N/2
                        //2*arcsin(D/2)=N
                        NonSimAngleRadians angleChangeNeeded = NonSimAngleRadians.Create(2 * Mathf.Asin(unitDistanceNeeded / 2));
                        sumOfArcIncreases = sumOfArcIncreases.Add(angleChangeNeeded);
                        if (sumOfArcIncreases.Raw_GetIsGreaterThan(arcWidthRadians))
                        {
                            break; // if this would bring us past the ending angle, stop and go to next "ring" in arc
                        }
                        workingAngle = workingAngle.Add(angleChangeNeeded);
                    }

                    Vector2 pointOnCircle = Center.ToVector2();
                    pointOnCircle.x += (float)(radiusOfNewRing * workingAngle.Cos());
                    pointOnCircle.y += (float)(radiusOfNewRing * workingAngle.Sin());

                    ArcenPoint pointOnCircleAsArcenPoint = pointOnCircle.ToArcenPoint();

                    if (firstPointFound == ArcenPoint.OutOfRange)
                    {
                        firstPointFound = pointOnCircleAsArcenPoint;
                    }
                    else if (firstPointFound.GetDistanceTo(pointOnCircleAsArcenPoint, false) < (firstUnitRadius + thisUnitRadius))
                    {
                        break; // we've come full circle, and don't want to overlap
                    }
                    overallEntitySet[entity] = pointOnCircleAsArcenPoint;
                }

                CurrentOccupiedRadius = radiusOfNewRing + firstUnitRadius;
            }

            return(CurrentOccupiedRadius);
        }