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); }
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); }
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; } } }
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); }
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); }
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); }
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; }
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); }
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; } } }