예제 #1
0
        public override void DoPreSortLogic(EntitySystem Weapon, List <GameEntity> Targets, ArcenCharacterBuffer TracingBuffer, ArcenSimContext Context)
        {
            base.DoPreSortLogic(Weapon, Targets, TracingBuffer, Context);

            MyLowestSpeedMultiplier = (FInt)999;
            MyPrimaryUnitLocation   = ArcenPoint.ZeroZeroPoint;
            ControlGroup group = Weapon.ParentEntity.EntitySpecificOrders.ControlGroup;

            if (group != null)
            {
                for (int i = 0; i < group.EntityIDs.Count; i++)
                {
                    GameEntity entity = World_AIW2.Instance.GetEntityByID(group.EntityIDs[i]);
                    if (entity == null)
                    {
                        continue;
                    }
                    FInt thisMultiplier = entity.TypeData.Balance_Speed.SpeedMultiplier;
                    if (thisMultiplier <= FInt.Zero)
                    {
                        continue;
                    }
                    MyLowestSpeedMultiplier = Mat.Min(MyLowestSpeedMultiplier, thisMultiplier);
                }

                GameEntity primaryEntity = group.GetPrimaryEntity();
                if (primaryEntity != null)
                {
                    MyPrimaryUnitLocation = primaryEntity.WorldLocation;
                }
            }
        }
        public ArcenPoint GetPointForNonControllerStrongArea(ArcenSimContext Context, Planet ThisPlanet, int StrongAreaIndex)
        {
            this.EnsureLoadedCustomData(ThisPlanet.AIDefensePlacer);
            Context.QualityRandom.ReinitializeWithSeed(ThisPlanet.PlanetIndex + 2 + StrongAreaIndex);

            ArcenPoint controllerLocation = ThisPlanet.GetController().WorldLocation;

            int        triesLeft          = 100;
            ArcenPoint strongAreaLocation = ArcenPoint.ZeroZeroPoint;

            while (true)
            {
                triesLeft--;
                strongAreaLocation = controllerLocation.GetRandomPointWithinDistance(Context.QualityRandom, this.MinimumDistanceOfStrongAreaFromController, this.MaximumDistanceOfStrongAreaFromController);
                if (!Engine_AIW2.Instance.FastGetIsPointOutsideGravWell(strongAreaLocation))
                {
                    break;
                }
                if (triesLeft <= 0)
                {
                    strongAreaLocation = controllerLocation;
                }
            }

            return(strongAreaLocation);
        }
예제 #3
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);

            bool quadrantExpandsOnXAxis             = false;
            bool quadrantExpandsInPositiveDirection = false;
            int  quadrantMainAxisStart  = firstUnitRect.Top;
            int  quadrantOtherAxisStart = firstUnitRect.CenterX - shieldCoverageRadiusOrEquivalent;
            int  quadrantOtherAxisEnd   = firstUnitRect.CenterX + shieldCoverageRadiusOrEquivalent;

            Helper_DoPlacementWithinProjectedZone(foreZoneEntities, entitiesToPlace, isQueuedCommand, paddingAroundEachUnit,
                                                  quadrantExpandsOnXAxis, quadrantExpandsInPositiveDirection, quadrantMainAxisStart, quadrantOtherAxisStart, quadrantOtherAxisEnd);

            quadrantExpandsInPositiveDirection = true;
            quadrantMainAxisStart = firstUnitRect.Bottom;

            Helper_DoPlacementWithinProjectedZone(aftZoneEntities, entitiesToPlace, isQueuedCommand, paddingAroundEachUnit,
                                                  quadrantExpandsOnXAxis, quadrantExpandsInPositiveDirection, quadrantMainAxisStart, quadrantOtherAxisStart, quadrantOtherAxisEnd);

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

            UtilityFunctions_Formation.Helper_ActuallyIssueMoveOrders(isQueuedCommand, entitiesToPlace);

            return(true);
        }
        /// <summary>
        /// returns amount spent on guardians
        /// </summary>
        private FInt Helper_SeedGuardians(ArcenSimContext Context, Planet ThisPlanet, ArcenPoint centerPoint, GameEntity entityToGuard, List <GameEntityTypeData> guardianTypes, FInt budget, FInt minDistanceFactor, FInt maxDistanceFactor, EntityBehaviorType behavior, Boolean isMobilePatrol, int MaxCountToSeed)
        {
            int minDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * minDistanceFactor).IntValue;
            int maxDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * maxDistanceFactor).IntValue;

            FInt result = FInt.Zero;

            while (budget > FInt.Zero)
            {
                GameEntityTypeData guardianData = guardianTypes[Context.QualityRandom.Next(0, guardianTypes.Count)];

                budget -= guardianData.BalanceStats.StrengthPerSquad;

                ArcenPoint point = ThisPlanet.Combat.GetSafePlacementPoint(Context, guardianData, centerPoint, minDistance, maxDistance);
                if (point == ArcenPoint.ZeroZeroPoint)
                {
                    continue;
                }

                result += guardianData.BalanceStats.StrengthPerSquad;

                GameEntity newEntity = GameEntity.CreateNew(entityToGuard.Side, guardianData, point, Context);
                newEntity.EntitySpecificOrders.Behavior = behavior;
                newEntity.GuardedObject = entityToGuard;
                switch (behavior)
                {
                case EntityBehaviorType.Guard_Guardian_Anchored:
                    break;

                case EntityBehaviorType.Guard_Guardian_Patrolling:
                    newEntity.GuardingOffsets.Add(newEntity.WorldLocation - newEntity.GuardedObject.WorldLocation);
                    if (isMobilePatrol)
                    {
                        AngleDegrees initialAngle    = centerPoint.GetAngleToDegrees(newEntity.WorldLocation);
                        int          initialDistance = centerPoint.GetDistanceTo(newEntity.WorldLocation, false);
                        int          step            = (AngleDegrees.MaxValue / 6).IntValue;
                        for (int i = step; i < AngleDegrees.MaxValue; i += step)
                        {
                            AngleDegrees angleToThisPoint = initialAngle.Add(AngleDegrees.Create((FInt)i));
                            ArcenPoint   thisPoint        = centerPoint.GetPointAtAngleAndDistance(angleToThisPoint, initialDistance);
                            newEntity.GuardingOffsets.Add(thisPoint - newEntity.GuardedObject.WorldLocation);
                        }
                    }
                    break;
                }

                if (MaxCountToSeed > 0)
                {
                    MaxCountToSeed--;
                    if (MaxCountToSeed == 0)
                    {
                        break;
                    }
                }
            }

            return(result);
        }
        public ArcenPoint GetPointForWormhole(ArcenSimContext Context, Planet ThisPlanet, Planet PlanetThatWormholeWillGoTo)
        {
            int wormholeRadius = Context.QualityRandom.Next(this.MinimumWormholeDistance, this.MaximumWormholeDistance);

            AngleDegrees angleToNeighbor = ThisPlanet.GalaxyLocation.GetAngleToDegrees(PlanetThatWormholeWillGoTo.GalaxyLocation);
            ArcenPoint   wormholePoint   = Engine_AIW2.Instance.CombatCenter.GetPointAtAngleAndDistance(angleToNeighbor, wormholeRadius);

            return(wormholePoint);
        }
예제 #6
0
        public static void Helper_SendMoveCommand(GameEntity entity, ArcenPoint Destination, bool isQueuedCommand)
        {
            GameCommand command = GameCommand.Create(GameCommandType.Move);

            command.ToBeQueued   = isQueuedCommand;
            command.RelatedPoint = Destination;
            command.RelatedEntityIDs.Add(entity.PrimaryKeyID);
            World_AIW2.Instance.QueueGameCommand(command, true);
        }
        public override bool DoSuccessfulCompletionLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context)
        {
            GameEntityTypeData hackedHiveData = GameEntityTypeDataTable.Instance.GetRowByName("NanobotCenter_Hacked_Hive", true, null);

            //Planet hackingPlanet = SpecialFaction_Nanocaust.Instance.mgr.hivePlanet;
            CombatSide cside = Target.Side;

            //I don't see a great way to figure out the ArcenPoint of the soon-to-die target; maybe a GameEntity has an ArcenPoint? check this

            ArcenPoint placementPoint = Target.neverWriteDirectly_worldLocation;

            Target.Die(Context);
            GameEntity.CreateNew(cside, hackedHiveData, placementPoint, Context);
            return(true);
        }
        private void Helper_SeedDireGuardians(ArcenSimContext Context, Planet ThisPlanet, ArcenPoint centerPoint, GameEntity controller, List <GameEntityTypeData> guardianTypes, int Count, FInt minDistanceFactor, FInt maxDistanceFactor, EntityBehaviorType behavior, Boolean isMobilePatrol)
        {
            int minDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * minDistanceFactor).IntValue;
            int maxDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * maxDistanceFactor).IntValue;

            while (Count > 0)
            {
                Count--;

                GameEntityTypeData guardianData = guardianTypes[Context.QualityRandom.Next(0, guardianTypes.Count)];

                ArcenPoint point = ThisPlanet.Combat.GetSafePlacementPoint(Context, guardianData, centerPoint, minDistance, maxDistance);
                if (point == ArcenPoint.ZeroZeroPoint)
                {
                    continue;
                }

                GameEntity newEntity = GameEntity.CreateNew(controller.Side, guardianData, point, Context);
                newEntity.EntitySpecificOrders.Behavior = behavior;
                newEntity.GuardedObject = controller;
                switch (behavior)
                {
                case EntityBehaviorType.Guard_Guardian_Anchored:
                    break;

                case EntityBehaviorType.Guard_Guardian_Patrolling:
                    newEntity.GuardingOffsets.Add(newEntity.WorldLocation - newEntity.GuardedObject.WorldLocation);
                    if (isMobilePatrol)
                    {
                        AngleDegrees initialAngle    = newEntity.GuardedObject.WorldLocation.GetAngleToDegrees(newEntity.WorldLocation);
                        int          initialDistance = newEntity.GuardedObject.WorldLocation.GetDistanceTo(newEntity.WorldLocation, false);
                        int          step            = (AngleDegrees.MaxValue / 6).IntValue;
                        for (int i = step; i < AngleDegrees.MaxValue; i += step)
                        {
                            AngleDegrees angleToThisPoint = initialAngle.Add(AngleDegrees.Create((FInt)i));
                            ArcenPoint   thisPoint        = newEntity.GuardedObject.WorldLocation.GetPointAtAngleAndDistance(angleToThisPoint, initialDistance);
                            newEntity.GuardingOffsets.Add(thisPoint - newEntity.GuardedObject.WorldLocation);
                        }
                    }
                    break;
                }
            }
        }
예제 #9
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);
        }
예제 #10
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();
            }
        }
        public override void  DoOneSecondOfHackingLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context)
        {
            GameEntityTypeData aberrationData  = GameEntityTypeDataTable.Instance.GetRowByName("Aberration", true, null);
            GameEntityTypeData abominationData = GameEntityTypeDataTable.Instance.GetRowByName("Abomination", true, null);

            CombatSide cside = Target.Side;
//          ArcenPoint center = Engine_AIW2.Instance.CombatCenter;
            ArcenPoint placementPoint = Target.neverWriteDirectly_worldLocation;
            int        numToCreate    = 1;

            /* How many ships to create? */
            if (Hacker.ActiveHack_DurationThusFar >= this.GetTotalSecondsToHack(Target, Hacker))
            {
                if (DoSuccessfulCompletionLogic(Target, Hacker, Context))
                {
                    //Set the toggle in NanocaustMgr

                    //it should probably cost hacking points. It does hurt the AI.
                    //Lore can claim that the AI is monitoring the Nanobot network and
                    //notices the trick you just used to get access to the Nanobots
                    SpecialFaction_Nanocaust.Instance.mgr.hasBeenHacked = true;
                    Hacker.Side.WorldSide.StoredHacking -= this.GetCostToHack(Target, Hacker);
                }
            }
            else
            {
                if (Hacker.ActiveHack_DurationThusFar % 10 == 0)
                {
                    numToCreate = 3;
                }
            }
            /* Create ships to fight hackers */
            for (int i = 0; i < numToCreate; i += 2)
            {
                GameEntity.CreateNew(cside, aberrationData, placementPoint, Context);
                GameEntity.CreateNew(cside, abominationData, placementPoint, Context);
            }
        }
        private FInt Inner_ReinforceWithFleetShipsOrTurrets(ArcenSimContext Context, Planet planet, WorldSide side, ref FInt budget, ReinforcementType reinforcementType, FInt strengthCap, ref FInt strengthPresent, List <BuildMenu> buildMenus, List <GameEntity> entitiesWeCanReinforce, bool atMostOnePerReinforceable)
        {
            if (entitiesWeCanReinforce.Count <= 0)
            {
                return(FInt.Zero);
            }

            ArcenRandomDrawBag <GameEntityTypeData> bag = new ArcenRandomDrawBag <GameEntityTypeData>();

            for (int i = 0; i < buildMenus.Count; i++)
            {
                BuildMenu menu = buildMenus[i];
                for (int j = 0; j < menu.List.Count; j++)
                {
                    int timesToAdd = 0;
                    GameEntityTypeData buyableType = menu.List[j];
                    if (buyableType.Balance_MarkLevel.Ordinal > 0 && buyableType.Balance_MarkLevel != planet.MarkLevel)
                    {
                        continue;
                    }
                    if (World_AIW2.Instance.CorruptedAIDesigns.Contains(buyableType))
                    {
                        continue;
                    }
                    if (!buyableType.AICanUseThisWithoutUnlockingIt && !World_AIW2.Instance.UnlockedAIDesigns.Contains(buyableType))
                    {
                        continue;
                    }
                    timesToAdd = 1;
                    if (timesToAdd <= 0)
                    {
                        continue;
                    }
                    bag.AddItem(buyableType, timesToAdd);
                }
            }

            if (!bag.GetHasItems())
            {
                return(FInt.Zero);
            }

            entitiesWeCanReinforce.Sort(delegate(GameEntity Left, GameEntity Right)
            {
                return(Left.Working_ReinforcementsOnly_ContentsStrength.CompareTo(Right.Working_ReinforcementsOnly_ContentsStrength));
            });

            FInt result = FInt.Zero;

            while (budget > FInt.Zero && strengthPresent < strengthCap && entitiesWeCanReinforce.Count > 0)
            {
                int index = 0;
                switch (reinforcementType)
                {
                case ReinforcementType.Turret:
                case ReinforcementType.Shield:
                    index = Context.QualityRandom.Next(0, entitiesWeCanReinforce.Count);
                    break;
                }
                GameEntity         entityToReinforce = entitiesWeCanReinforce[index];
                GameEntityTypeData typeToBuy         = bag.PickRandomItemAndReplace(Context.QualityRandom);
                budget          -= typeToBuy.BalanceStats.StrengthPerSquad;
                result          += typeToBuy.BalanceStats.StrengthPerSquad;
                strengthPresent += typeToBuy.BalanceStats.StrengthPerSquad;

                switch (reinforcementType)
                {
                case ReinforcementType.Turret:
                case ReinforcementType.Shield:
                {
                    int        minDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 050)).IntValue;
                    int        maxDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 150)).IntValue;
                    ArcenPoint point       = planet.Combat.GetSafePlacementPoint(Context, typeToBuy, entityToReinforce.WorldLocation, minDistance, maxDistance);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }

                    result += typeToBuy.BalanceStats.StrengthPerSquad;

                    GameEntity newEntity = GameEntity.CreateNew(planet.Combat.GetSideForWorldSide(side), typeToBuy, point, Context);
                    newEntity.EntitySpecificOrders.Behavior = EntityBehaviorType.Stationary;
                }
                break;

                case ReinforcementType.FleetShip:
                {
                    entityToReinforce.ChangeContents(typeToBuy, 1);
                    entityToReinforce.Working_ReinforcementsOnly_ContentsStrength += typeToBuy.BalanceStats.StrengthPerSquad;

                    for (int i = 1; i < entitiesWeCanReinforce.Count; i++)
                    {
                        GameEntity otherReinforceable = entitiesWeCanReinforce[i];
                        if (entityToReinforce.Working_ReinforcementsOnly_ContentsStrength <= otherReinforceable.Working_ReinforcementsOnly_ContentsStrength)
                        {
                            break;
                        }
                        entitiesWeCanReinforce[i - 1] = otherReinforceable;
                        entitiesWeCanReinforce[i]     = entityToReinforce;
                    }
                }
                break;
                }

                if (atMostOnePerReinforceable)
                {
                    entitiesWeCanReinforce.Remove(entityToReinforce);
                }
            }

            return(result);
        }
예제 #13
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);
        }
예제 #14
0
        public static void Helper_FindAndPlaceCoreUnit(ControlGroup Group, ArcenPoint MoveOrderPoint, out ArcenSparseLookup <GameEntity, ArcenPoint> _entitiesToPlace, out GameEntity coreUnit, out int shieldCoverageRadiusOrEquivalent, out int paddingAroundEachUnit, out ArcenRectangle firstUnitRect)
        {
            Planet localPlanet = Engine_AIW2.Instance.NonSim_GetPlanetBeingCurrentlyViewed();

            ArcenSparseLookup <GameEntity, ArcenPoint> entitiesToPlace = _entitiesToPlace = new ArcenSparseLookup <GameEntity, ArcenPoint>();

            Group.DoForEntities(delegate(GameEntity entity)
            {
                if (entity.Combat.Planet != localPlanet)
                {
                    return(DelReturn.Continue);
                }
                entitiesToPlace[entity] = ArcenPoint.OutOfRange;
                return(DelReturn.Continue);
            });

            coreUnit = null;
            GameEntity backupCoreUnit = null;

            for (int i = 0; i < entitiesToPlace.GetPairCount(); i++)
            {
                GameEntity entity = entitiesToPlace.GetPairByIndex(i).Key;
                if (entity.TypeData.ShieldRadius <= 0)
                {
                    if (coreUnit == null)
                    {
                        if (backupCoreUnit != null)
                        {
                            if (entity.TypeData.BalanceStats.StrengthPerSquad <= backupCoreUnit.TypeData.BalanceStats.StrengthPerSquad)
                            {
                                continue;
                            }
                        }
                        backupCoreUnit = entity;
                    }
                    continue;
                }
                if (coreUnit != null)
                {
                    if (entity.TypeData.ShieldRadius < coreUnit.TypeData.ShieldRadius)
                    {
                        continue;
                    }
                    if (entity.TypeData.ShieldRadius == coreUnit.TypeData.ShieldRadius &&
                        entity.TypeData.BalanceStats.ShieldPoints <= coreUnit.TypeData.BalanceStats.ShieldPoints)
                    {
                        continue;
                    }
                }
                coreUnit = entity;
            }

            if (coreUnit == null)
            {
                backupCoreUnit = coreUnit;
            }

            int initialCoreRadius = 4;

            shieldCoverageRadiusOrEquivalent = initialCoreRadius;
            if (coreUnit != null)
            {
                entitiesToPlace[coreUnit]        = MoveOrderPoint;
                initialCoreRadius                = coreUnit.TypeData.Radius;
                shieldCoverageRadiusOrEquivalent = Math.Max(initialCoreRadius, coreUnit.GetCurrentShieldRadius());
            }

            paddingAroundEachUnit = 20;
            firstUnitRect.Width   = initialCoreRadius + initialCoreRadius + paddingAroundEachUnit;
            firstUnitRect.Height  = firstUnitRect.Width;
            firstUnitRect.X       = MoveOrderPoint.X - initialCoreRadius;
            firstUnitRect.Y       = MoveOrderPoint.Y - initialCoreRadius;
        }
예제 #15
0
        private static int SpendBudgetOnItemsInList(ArcenSimContext Context, CombatSide Side, ArcenPoint CenterLocation, int MinimumDistanceFromCenter, List <GameEntityTypeData> listToBuyFrom, int budget)
        {
            if (listToBuyFrom.Count <= 0)
            {
                return(0);
            }
            if (budget <= 0)
            {
                return(0);
            }

            int remainingBudget = budget;

            int budgetPerType = remainingBudget / listToBuyFrom.Count;

            ArcenPoint formationCenterPoint = CenterLocation;

            listToBuyFrom.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                int leftValue = 0;
                if (Left.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Left.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        leftValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                int rightValue = 0;
                if (Right.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Right.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        rightValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                return(rightValue.CompareTo(leftValue));
            });

            int innerRingDistance = MinimumDistanceFromCenter;
            int outerRingDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 100)).IntValue;

            int distanceBetweenRings = (outerRingDistance - innerRingDistance) / listToBuyFrom.Count;

            for (int i = 0; i < listToBuyFrom.Count; i++)
            {
                GameEntityTypeData entityType = listToBuyFrom[i];
                int numberToPlace             = budgetPerType / entityType.BalanceStats.SquadPowerConsumption;
                numberToPlace = Math.Min(Side.GetRemainingCap(entityType), numberToPlace);
                if (numberToPlace <= 0)
                {
                    continue;
                }
                int          ringDistance       = innerRingDistance + (distanceBetweenRings * i);
                AngleDegrees startingAngle      = AngleDegrees.Create((FInt)Context.QualityRandom.Next(0, AngleDegrees.MaxValue.IntValue));
                AngleDegrees angleChangePerItem = AngleDegrees.MaxAngle / numberToPlace;
                for (int j = 0; j < numberToPlace; j++)
                {
                    if (Side.GetCanBuildAnother(entityType) != ArcenRejectionReason.Unknown)
                    {
                        break;
                    }
                    AngleDegrees angle = startingAngle + (angleChangePerItem * j);
                    ArcenPoint   point = formationCenterPoint.GetPointAtAngleAndDistance(angle, ringDistance);
                    point = Side.Combat.GetSafePlacementPoint(Context, entityType, point, 0, distanceBetweenRings / 2);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(Side, entityType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)entityType.BalanceStats.SquadMetalCost;
                    remainingBudget -= entityType.BalanceStats.SquadPowerConsumption;
                }
            }

            // fill in the corners of the budget
            listToBuyFrom.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                return(Right.BalanceStats.SquadPowerConsumption.CompareTo(Left.BalanceStats.SquadPowerConsumption));
            });

            bool checkAgain = true;

            while (remainingBudget > 0 && checkAgain)
            {
                checkAgain = false;
                for (int i = 0; i < listToBuyFrom.Count; i++)
                {
                    GameEntityTypeData entityType = listToBuyFrom[i];
                    if (remainingBudget < entityType.BalanceStats.SquadPowerConsumption)
                    {
                        continue;
                    }
                    if (Side.GetCanBuildAnother(entityType) != ArcenRejectionReason.Unknown)
                    {
                        continue;
                    }
                    ArcenPoint point = Side.Combat.GetSafePlacementPoint(Context, entityType, formationCenterPoint, innerRingDistance, outerRingDistance);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(Side, entityType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)entityType.BalanceStats.SquadMetalCost;
                    remainingBudget -= entityType.BalanceStats.SquadPowerConsumption;
                    checkAgain       = true;
                }
            }

            return(budget - remainingBudget);
        }
예제 #16
0
        public void Execute(ArcenSimContext Context, GameEntity BuildingEntity)
        {
            List <GameEntityTypeData> turretTypes = new List <GameEntityTypeData>();

            for (int menuIndex = 0; menuIndex < BuildingEntity.TypeData.BuildMenus.Count; menuIndex++)
            {
                BuildMenu menu = BuildingEntity.TypeData.BuildMenus[menuIndex];
                for (int i = 0; i < menu.List.Count; i++)
                {
                    GameEntityTypeData entityData = menu.List[i];
                    if (entityData.Balance_FuelCost.FuelMultiplier > 0)
                    {
                        continue;
                    }
                    if (entityData.Balance_PowerCost.PowerMultiplier <= 0)
                    {
                        continue;
                    }
                    if (!entityData.CapIsPerPlanet)
                    {
                        continue;
                    }
                    if (!EntityRollupType.Combatants.Matches(entityData))     //&& !EntityRollupType.ProjectsShield.Matches( entityData )
                    {
                        continue;
                    }
                    if (BuildingEntity.Side.GetCanBuildAnother(entityData) != ArcenRejectionReason.Unknown)
                    {
                        continue;
                    }
                    turretTypes.Add(entityData);
                }
            }

            if (turretTypes.Count <= 0)
            {
                return;
            }

            int powerBudget = BuildingEntity.Side.NetPower;

            int budgetPerType = powerBudget / turretTypes.Count;

            ArcenPoint formationCenterPoint = BuildingEntity.WorldLocation;

            turretTypes.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                int leftValue = 0;
                if (Left.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Left.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        leftValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                int rightValue = 0;
                if (Right.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Right.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        rightValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                return(rightValue.CompareTo(leftValue));
            });

            int innerRingDistance = BuildingEntity.TypeData.Radius * 2;
            int outerRingDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 100)).IntValue;

            int distanceBetweenRings = (outerRingDistance - innerRingDistance) / turretTypes.Count;

            for (int i = 0; i < turretTypes.Count; i++)
            {
                GameEntityTypeData turretType = turretTypes[i];
                int numberToPlace             = budgetPerType / turretType.BalanceStats.SquadPowerConsumption;
                numberToPlace = Math.Min(BuildingEntity.Side.GetRemainingCap(turretType), numberToPlace);
                if (numberToPlace <= 0)
                {
                    continue;
                }
                int          ringDistance       = innerRingDistance + (distanceBetweenRings * i);
                AngleDegrees startingAngle      = AngleDegrees.Create((FInt)Context.QualityRandom.Next(0, AngleDegrees.MaxValue.IntValue));
                AngleDegrees angleChangePerItem = AngleDegrees.MaxAngle / numberToPlace;
                for (int j = 0; j < numberToPlace; j++)
                {
                    if (BuildingEntity.Side.GetCanBuildAnother(turretType) != ArcenRejectionReason.Unknown)
                    {
                        break;
                    }
                    AngleDegrees angle = startingAngle + (angleChangePerItem * j);
                    ArcenPoint   point = formationCenterPoint.GetPointAtAngleAndDistance(angle, ringDistance);
                    point = BuildingEntity.Combat.GetSafePlacementPoint(Context, turretType, point, 0, distanceBetweenRings / 2);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(BuildingEntity.Side, turretType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)turretType.BalanceStats.SquadMetalCost;
                    powerBudget -= turretType.BalanceStats.SquadPowerConsumption;
                }
            }

            // fill in the corners of the budget
            turretTypes.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                return(Right.BalanceStats.SquadPowerConsumption.CompareTo(Left.BalanceStats.SquadPowerConsumption));
            });

            bool checkAgain = true;

            while (powerBudget > 0 && checkAgain)
            {
                checkAgain = false;
                for (int i = 0; i < turretTypes.Count; i++)
                {
                    GameEntityTypeData turretType = turretTypes[i];
                    if (powerBudget < turretType.BalanceStats.SquadPowerConsumption)
                    {
                        continue;
                    }
                    if (BuildingEntity.Side.GetCanBuildAnother(turretType) != ArcenRejectionReason.Unknown)
                    {
                        continue;
                    }
                    ArcenPoint point = BuildingEntity.Combat.GetSafePlacementPoint(Context, turretType, formationCenterPoint, innerRingDistance, outerRingDistance);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(BuildingEntity.Side, turretType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)turretType.BalanceStats.SquadMetalCost;
                    powerBudget -= turretType.BalanceStats.SquadPowerConsumption;
                    checkAgain   = true;
                }
            }
        }