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); }
private GameEntityTypeData InnerPickNextBuy(ArcenSimContext Context, List <BuildMenu> Menus) { bag.Clear(); for (int i = 0; i < Menus.Count; i++) { BuildMenu menu = Menus[i]; for (int j = 0; j < menu.List.Count; j++) { int timesToAdd = 0; GameEntityTypeData buyableType = menu.List[j]; if (buyableType.Balance_MarkLevel.RequiredAIPLevel > World_AIW2.Instance.AIProgress_Effective) { 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); } } GameEntityTypeData result = bag.PickRandomItemAndReplace(Context.QualityRandom); bag.Clear(); return(result); }
/// <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 int GetNumberOfNonControllerStrongAreas(ArcenSimContext Context, Planet ThisPlanet) { if (ThisPlanet.PopulationType == PlanetPopulationType.AIHomeworld) { return(0); } this.EnsureLoadedCustomData(ThisPlanet.AIDefensePlacer); Context.QualityRandom.ReinitializeWithSeed(ThisPlanet.PlanetIndex + 1); return(Context.QualityRandom.Next(this.MinimumNumberOfNonControllerStrongAreas, this.MaximumNumberOfNonControllerStrongAreas)); }
public ArcenPoint GetPointForController(ArcenSimContext Context, Planet ThisPlanet) { if (ThisPlanet.PopulationType == PlanetPopulationType.AIHomeworld) { return(Engine_AIW2.Instance.CombatCenter); } this.EnsureLoadedCustomData(ThisPlanet.AIDefensePlacer); Context.QualityRandom.ReinitializeWithSeed(ThisPlanet.PlanetIndex); return(Engine_AIW2.Instance.CombatCenter.GetRandomPointWithinDistance(Context.QualityRandom, this.MinimumControllerDistance, this.MaximumControllerDistance)); }
public void Execute(ArcenSimContext Context, GameEntity BuildingEntity) { List <GameEntityTypeData> turretTypes = new List <GameEntityTypeData>(); List <GameEntityTypeData> shieldTypes = 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; } List <GameEntityTypeData> listToAddTo = null; if (entityData.RollupLookup[EntityRollupType.Combatants]) { listToAddTo = turretTypes; } else if (entityData.RollupLookup[EntityRollupType.ProjectsShield]) { listToAddTo = shieldTypes; } if (listToAddTo == null) { continue; } ArcenRejectionReason rejectionReason = BuildingEntity.Side.GetCanBuildAnother(entityData); if (rejectionReason != ArcenRejectionReason.Unknown) { continue; } listToAddTo.Add(entityData); } } int remainingBudget = BuildingEntity.Side.NetPower; remainingBudget -= SpendBudgetOnItemsInList(Context, BuildingEntity.Side, BuildingEntity.WorldLocation, BuildingEntity.TypeData.Radius * 2, shieldTypes, (remainingBudget * 25) / 100); remainingBudget -= SpendBudgetOnItemsInList(Context, BuildingEntity.Side, BuildingEntity.WorldLocation, BuildingEntity.TypeData.Radius * 2, turretTypes, remainingBudget); }
public void CheckForSpendingUnlockPoints(ArcenSimContext Context) { while (true) { int availablePoints = World_AIW2.Instance.AIProgress_Effective.IntValue - World_AIW2.Instance.SpentAIUnlockPoints; if (availablePoints < World_AIW2.Instance.Setup.Difficulty.AIPNeededPerUnlock) { break; } List <GameEntityTypeData> eligibleUnlocks = new List <GameEntityTypeData>(); List <BuildMenu> menus = World_AIW2.Instance.Setup.MasterAIType.BudgetItems[AIBudgetType.Reinforcement].NormalMenusToBuyFrom; for (int i = 0; i < menus.Count; i++) { BuildMenu menu = menus[i]; for (int j = 0; j < menu.List.Count; j++) { GameEntityTypeData buyableType = menu.List[j]; if (buyableType.AICanUseThisWithoutUnlockingIt) { continue; } if (buyableType.CopiedFrom != null && buyableType.CopiedFrom != buyableType) { continue; } if (World_AIW2.Instance.CorruptedAIDesigns.Contains(buyableType)) { continue; } if (World_AIW2.Instance.UnlockedAIDesigns.Contains(buyableType)) { continue; } eligibleUnlocks.Add(buyableType); } } if (eligibleUnlocks.Count <= 0) { break; } GameEntityTypeData typeToUnlock = eligibleUnlocks[Context.QualityRandom.Next(0, eligibleUnlocks.Count)]; World_AIW2.Instance.UnlockEntityTypeForAI(typeToUnlock, Context); } }
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 override bool DoSuccessfulCompletionLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context) { if (Target.WarheadContents.Count <= 0) { return(false); } for (int i = 0; i < Target.WarheadContents.Count; i++) { EntityContentsRecord record = Target.WarheadContents[i]; Hacker.ChangeWarheadContents(record.ContainedType, record.NumberContained); Target.ChangeWarheadContents(record.ContainedType, -record.NumberContained); } Target.Die(Context); return(true); }
public override bool DoSuccessfulCompletionLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context) { if (World_AIW2.Instance.CorruptedAIDesigns.Contains(Target.StoredDesign)) { return(false); } World_AIW2.Instance.CorruptedAIDesigns.Add(Target.StoredDesign); Target.Die(Context); return(true); }
public Planet GetCurrentTargetPlanet(ArcenSimContext Context, GameEntity hideout, List <GameEntity> hideoutFleet) { #region Tracing bool tracing = SpecialForcesPlanning.tracing; ArcenCharacterBuffer tracingBuffer = SpecialForcesPlanning.tracingBuffer; #endregion Planet hideoutPlanet = World_AIW2.Instance.GetPlanetByIndex(hideout.LongRangePlanningData.CurrentPlanetIndex); Planet currentTargetPlanet = World_AIW2.Instance.GetPlanetByIndex(hideout.LongRangePlanningData.SpecialTargetPlanetIndex); FInt hideoutFleetStrength = FInt.Zero; hideoutFleet.Clear(); for (int i = 0; i < hideoutFleet.Count; i++) { GameEntity entity = hideoutFleet[i]; if (entity.LongRangePlanningData.CoordinatorID != hideout.PrimaryKeyID) { continue; } hideoutFleet.Add(entity); hideoutFleetStrength += entity.TypeData.BalanceStats.StrengthPerSquad + entity.LongRangePlanningData.StrengthOfContents; } #region Tracing if (tracing) { tracingBuffer.Add("\n").Add("SpecialForcesRouting considering hideout on ").Add(hideoutPlanet.Name).Add("; fleet strength = ").Add(hideoutFleetStrength.ReadableString); } #endregion bestTargetFound_Index = -1; bestTargetFound_Danger = FInt.Zero; hideoutPlanet.DoForPlanetsWithinXHops(Context, 3, delegate(Planet planet, int Distance) { FInt danger = planet.LongRangePlanningData.HumanTotalStrength - planet.LongRangePlanningData.AITotalStrength; if (danger < FInt.Zero && -danger < planet.LongRangePlanningData.AITotalStrength / 2) { #region Tracing if (tracing) { tracingBuffer.Add("\n").Add("rejecting target ").Add(planet.Name).Add(" because danger too low: ").Add(danger.ReadableString); } #endregion return(DelReturn.Continue); } if (bestTargetFound_Index >= 0 && bestTargetFound_Danger >= danger) { #region Tracing if (tracing) { tracingBuffer.Add("\n").Add("rejecting target ").Add(planet.Name).Add(" because danger lower than current best target: ").Add(danger.ReadableString); } #endregion return(DelReturn.Continue); } #region Tracing if (tracing) { tracingBuffer.Add("\n").Add("current best target = ").Add(planet.Name).Add("; danger: ").Add(danger.ReadableString); } #endregion bestTargetFound_Index = planet.PlanetIndex; bestTargetFound_Danger = danger; return(DelReturn.Continue); }, delegate(Planet planet) { if (planet.LongRangePlanningData.ControllingSide.Type != hideout.LongRangePlanningData.Side.WorldSide.Type) { #region Tracing if (tracing) { tracingBuffer.Add("\n").Add("Refusing to flood into ").Add(planet.Name).Add(" because not controlled by same side"); } #endregion return(PropogationEvaluation.No); } FInt danger = planet.LongRangePlanningData.HumanTotalStrength - planet.LongRangePlanningData.AITotalStrength; if (danger >= hideoutFleetStrength * 2) { #region Tracing if (tracing) { tracingBuffer.Add("\n").Add("Refusing to flood into ").Add(planet.Name).Add(" because too much danger: ").Add(danger.ReadableString); } #endregion return(PropogationEvaluation.No); } if (danger >= hideoutFleetStrength * 1) { #region Tracing if (tracing) { tracingBuffer.Add("\n").Add("Refusing to flood through ").Add(planet.Name).Add(" because too much danger: ").Add(danger.ReadableString); } #endregion return(PropogationEvaluation.SelfButNotNeighbors); } return(PropogationEvaluation.Yes); }); FInt currentTargetPlanetDanger = currentTargetPlanet.LongRangePlanningData.HumanTotalStrength - currentTargetPlanet.LongRangePlanningData.AITotalStrength; if (bestTargetFound_Index < 0 || bestTargetFound_Danger <= (currentTargetPlanetDanger * 2)) { bestTargetFound_Index = currentTargetPlanet.PlanetIndex; bestTargetFound_Danger = currentTargetPlanetDanger; } return(World_AIW2.Instance.GetPlanetByIndex(bestTargetFound_Index)); }
public override void DoPerSimStepLogic(WorldSide side, ArcenSimContext Context) { // do nothing, just example }
public GameEntityTypeData GetNextGuardianToBuy(ArcenSimContext Context, GameEntity Base, List <GameEntity> CurrentFleet, List <BuildMenu> Menus) { return(InnerPickNextBuy(Context, Menus)); }
public void HandleDeathWithEffectApplied(GameEntity Entity, int ThisDeathEffectDamageSustained, WorldSide SideThatDidTheKilling, WorldSide SideResponsibleForTheDeathEffect, ArcenSimContext Context) { if (SideResponsibleForTheDeathEffect == null) { return; } if (!Entity.GetMatches(EntityRollupType.MobileCombatants)) { return; } ISpecialFactionImplementation implementationToSearchFor = null; if (SideResponsibleForTheDeathEffect.Type == WorldSideType.AI) { implementationToSearchFor = SpecialFaction_AntiPlayerZombie.Instance; } else if (SideResponsibleForTheDeathEffect.Type == WorldSideType.Player) { implementationToSearchFor = SpecialFaction_AntiAIZombie.Instance; } else { implementationToSearchFor = SpecialFaction_AntiEveryoneZombie.Instance; } WorldSide destinationSide = World_AIW2.Instance.GetSideBySpecialFactionImplementation(implementationToSearchFor); if (destinationSide == null) { return; } CombatSide sideForNewEntity = Entity.Combat.GetSideForWorldSide(destinationSide); GameEntity zombie = GameEntity.CreateNew(sideForNewEntity, Entity.TypeData, Entity.WorldLocation, Context); zombie.EntitySpecificOrders.Behavior = EntityBehaviorType.Attacker; }
public void DoPerSimStepLogic(WorldSide side, ArcenSimContext Context) { //NOTE: this is not "real" logic, just a demo of how to use custom xml data; it will fire right after you start a new game, if you have the Devourer enabled //if ( World_AIW2.Instance.GameSecond <= 1 && World_AIW2.Instance.IsFirstFrameOfSecond ) //{ // //this just dumps all custom data attached to the external constants object, regardless of who put it there // //Useful if something isn't working right and you want to check to see if you have a typo in an attribute name, etc. // ArcenDebugging.ArcenDebugLogSingleLine( ExternalConstants.Instance.DebugCustomData_GetAllKeysInAllNamespaces(), Verbosity.ShowAsInfo ); // //this corresponds to the "custom_int_examplemod_test_custom_number" attribute in the external constants xml file; here are the pieces: // //"custom_" always have to have this prefix // //"int_" tells it this is a 32-bit int value; other valid options are bool, float, FInt, and string // //"examplemod_" is whatever you want to put in there, with no _ characters in the middle, and this functions as the "namespace" to differentiate the field from others in case some other modder has a "test_custom_number" // //"test_custom_number" is just the rest of the attribute name, and functions as the actual name of the field // CustomDataSet externalConstantsCustomData = ExternalConstants.Instance.GetCustomData( "examplemod" ); // int testCustomNumber = externalConstantsCustomData.GetInt( "test_custom_number" ); // ArcenDebugging.ArcenDebugLogSingleLine( testCustomNumber.ToString(), Verbosity.ShowAsInfo ); //} //NOTE: there's no "real" logic here, it's just a demo of how to use external data if (!DoomData.DoDebugTestingLogic) { return; } if (!World_AIW2.Instance.IsFirstFrameOfSecond) { return; } DoomData.Primitives doomDataPrimitives = World.Instance.GetDoomData_Primitives(); if (World.Instance.GetDoomData_DoomedPlanetIndices() == null) { World.Instance.SetDoomData_DoomedPlanetIndices(new List <int>()); } List <int> doomedPlanetIndices = World.Instance.GetDoomData_DoomedPlanetIndices(); if (doomDataPrimitives.SecondsUntilNextDoomPlanetPick == 0) { doomDataPrimitives.SecondsUntilNextDoomPlanetPick = 10; } doomDataPrimitives.SecondsUntilNextDoomPlanetPick--; if (doomDataPrimitives.SecondsUntilNextDoomPlanetPick <= 0) { ArcenDebugging.ArcenDebugLogSingleLine("Picking Planet To Doom", Verbosity.DoNotShow); doomDataPrimitives.SecondsUntilNextDoomPlanetPick = 5; List <Planet> candidates = new List <Planet>(); List <Planet> allPlanets = World_AIW2.Instance.SetOfGalaxies.Galaxies[0].Planets; for (int i = 0; i < allPlanets.Count; i++) { Planet planet = allPlanets[i]; if (doomedPlanetIndices.ContainsValueType(planet.PlanetIndex)) { continue; } candidates.Add(planet); } if (candidates.Count > 0) { Planet target = candidates[Context.QualityRandom.Next(0, candidates.Count)]; ArcenDebugging.ArcenDebugLogSingleLine("Dooming " + target.Name, Verbosity.DoNotShow); doomedPlanetIndices.Add(target.PlanetIndex); } } if (doomedPlanetIndices.Count > 0) { if (doomDataPrimitives.SecondsUntilNextDoomAttack == 0) { doomDataPrimitives.SecondsUntilNextDoomAttack = 11; } doomDataPrimitives.SecondsUntilNextDoomAttack--; if (doomDataPrimitives.SecondsUntilNextDoomAttack <= 0) { doomDataPrimitives.SecondsUntilNextDoomAttack = 6; int targetIndex = doomedPlanetIndices[Context.QualityRandom.Next(0, doomedPlanetIndices.Count)]; Planet target = World_AIW2.Instance.GetPlanetByIndex(targetIndex); // cause some entities to spawn on the target planet, or elsewhere and have them travel to the target, etc ArcenDebugging.ArcenDebugLogSingleLine("Doom attack against " + target.Name, Verbosity.DoNotShow); doomDataPrimitives.LastDoomAttackLaunchedAgainstPlayer = target.GetControllingSide().Type == WorldSideType.Player; } } }
public override bool DoSuccessfulCompletionLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context) { if (Target.StoredDesign != null) { TechTypeData tech = Target.StoredDesign.TechPrereq; if (!Hacker.Side.WorldSide.UnlockedTechs.Contains(tech)) { Hacker.Side.WorldSide.UnlockedTechs.Add(tech); return(true); } } else if (Target.TypeData.GrantsTemporarilyWhileOwned.Count > 0) { bool foundOne = false; for (int i = 0; i < Target.TypeData.GrantsTemporarilyWhileOwned.Count; i++) { TechTypeData tech = Target.TypeData.GrantsTemporarilyWhileOwned[i]; if (Hacker.Side.WorldSide.UnlockedTechs.Contains(tech)) { continue; } Hacker.Side.WorldSide.UnlockedTechs.Add(tech); foundOne = true; } if (foundOne) { return(true); } } return(false); }
public virtual void DoOneSecondOfHackingLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context) { if (Hacker.ActiveHack_DurationThusFar >= this.GetTotalSecondsToHack(Target, Hacker)) { WaveLogic.SendWave(Context, Target.Side.WorldSide, Target.Side.WorldSide.AITypeData.BudgetItems[AIBudgetType.Wave].NormalMenusToBuyFrom, Target.Side.WorldSide.GetSpecificBudgetThreshold(AIBudgetType.Wave) * 5, Target, null); if (DoSuccessfulCompletionLogic(Target, Hacker, Context)) { Hacker.Side.WorldSide.StoredHacking -= this.GetCostToHack(Target, Hacker); } } else { if (Hacker.ActiveHack_DurationThusFar % 10 == 0) { WaveLogic.SendWave(Context, Target.Side.WorldSide, Target.Side.WorldSide.AITypeData.BudgetItems[AIBudgetType.Wave].NormalMenusToBuyFrom, Target.Side.WorldSide.GetSpecificBudgetThreshold(AIBudgetType.Wave) * 1, Target, null); } } }
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); }
public void DoPerSimStepLogic(WorldSide side, ArcenSimContext Context) { bool haveHumanOccupiers = false; bool haveAIOccupiers = false; side.Entities.DoForEntities(GameEntityCategory.Ship, delegate(GameEntity entity) { if (entity.LongRangePlanningData == null) { return(DelReturn.Continue); // if created after the start of this planning cycle, skip } Planet planet = World_AIW2.Instance.GetPlanetByIndex(entity.LongRangePlanningData.CurrentPlanetIndex); if (!entity.TypeData.GetHasTag(DYSON_SPHERE_TAG)) { return(DelReturn.Continue); } if (planet.GetIsControlledBySideType(WorldSideType.Player)) { haveHumanOccupiers = true; } if (planet.GetIsControlledBySideType(WorldSideType.AI)) { haveAIOccupiers = true; } return(DelReturn.Continue); }); if (haveHumanOccupiers) { World_AIW2.Instance.DoForSides(delegate(WorldSide otherSide) { if (side == otherSide) { return(DelReturn.Continue); } switch (otherSide.Type) { case WorldSideType.NaturalObject: break; case WorldSideType.AI: if (side.GetIsFriendlyTowards(otherSide)) { break; } side.MakeFriendlyTo(otherSide); otherSide.MakeFriendlyTo(side); break; default: if (side.GetIsHostileTowards(otherSide)) { break; } side.MakeHostileTo(otherSide); otherSide.MakeHostileTo(side); break; } return(DelReturn.Continue); }); } else if (!haveAIOccupiers) { World_AIW2.Instance.DoForSides(delegate(WorldSide otherSide) { if (side == otherSide) { return(DelReturn.Continue); } switch (otherSide.Type) { case WorldSideType.NaturalObject: break; case WorldSideType.Player: if (side.GetIsFriendlyTowards(otherSide)) { break; } side.MakeFriendlyTo(otherSide); otherSide.MakeFriendlyTo(side); break; default: if (side.GetIsHostileTowards(otherSide)) { break; } side.MakeHostileTo(otherSide); otherSide.MakeHostileTo(side); break; } return(DelReturn.Continue); }); } else { World_AIW2.Instance.DoForSides(delegate(WorldSide otherSide) { if (side == otherSide) { return(DelReturn.Continue); } if (otherSide.Type == WorldSideType.NaturalObject) { return(DelReturn.Continue); } if (side.GetIsHostileTowards(otherSide)) { return(DelReturn.Continue); } side.MakeHostileTo(otherSide); otherSide.MakeHostileTo(side); return(DelReturn.Continue); }); } }
public FInt Reinforce(ArcenSimContext Context, Planet planet, WorldSide side, FInt budget, ReinforcementType reinforcementType) { ShortRangePlanning_StrengthData_CombatSide_Stance strengthData = planet.Combat.GetSideForWorldSide(side).DataByStance[SideStance.Self]; FInt strengthCap; FInt strengthPresent; switch (reinforcementType) { case ReinforcementType.FleetShip: strengthCap = planet.GetGuardingAIFleetShipStrengthCap(); strengthPresent = strengthData.GuardStrength - strengthData.TurretStrength - strengthData.ShieldStrength; break; case ReinforcementType.Turret: strengthCap = planet.GetGuardingAITurretStrengthCap(); strengthPresent = strengthData.TurretStrength; break; case ReinforcementType.Shield: strengthCap = planet.GetGuardingAIShieldStrengthCap(); strengthPresent = strengthData.ShieldStrength; break; default: return(FInt.Zero); } if (strengthPresent >= strengthCap) { return(FInt.Zero); } List <GameEntity> entitiesWeCanReinforce = new List <GameEntity>(); planet.Combat.GetSideForWorldSide(side).Entities.DoForEntities(EntityRollupType.ReinforcementLocations, delegate(GameEntity guardian) { switch (reinforcementType) { case ReinforcementType.Shield: case ReinforcementType.Turret: if (guardian.EntitySpecificOrders.Behavior != EntityBehaviorType.Guard_Guardian_Anchored) { return(DelReturn.Continue); } break; } entitiesWeCanReinforce.Add(guardian); guardian.Working_ReinforcementsOnly_ContentsStrength = guardian.GetStrengthOfContentsIfAny(); return(DelReturn.Continue); }); switch (reinforcementType) { case ReinforcementType.Turret: case ReinforcementType.Shield: GameEntity controller = planet.GetController(); if (controller.Side.WorldSide == side) { entitiesWeCanReinforce.Add(controller); } break; } FInt result = FInt.Zero; List <BuildMenu> buildMenus = null; bool atMostOnePerReinforceable = false; switch (reinforcementType) { case ReinforcementType.Shield: List <GameEntity> entitiesThatNeedMoreShieldCoverage = new List <GameEntity>(); for (int i = 0; i < entitiesWeCanReinforce.Count; i++) { GameEntity entity = entitiesWeCanReinforce[i]; if (entity.ProtectingShieldIDs.Count > 0) { continue; } entitiesThatNeedMoreShieldCoverage.Add(entity); } buildMenus = side.AITypeData.BudgetItems[AIBudgetType.Reinforcement].ShieldMenusToBuyFrom; entitiesWeCanReinforce = entitiesThatNeedMoreShieldCoverage; atMostOnePerReinforceable = true; break; case ReinforcementType.Turret: buildMenus = side.AITypeData.BudgetItems[AIBudgetType.Reinforcement].TurretMenusToBuyFrom; break; case ReinforcementType.FleetShip: buildMenus = side.AITypeData.BudgetItems[AIBudgetType.Reinforcement].NormalMenusToBuyFrom; break; } result += Inner_ReinforceWithFleetShipsOrTurrets(Context, planet, side, ref budget, reinforcementType, strengthCap, ref strengthPresent, buildMenus, entitiesWeCanReinforce, atMostOnePerReinforceable); return(result); }
public virtual void DoPreSortLogic(EntitySystem Weapon, List <GameEntity> Targets, ArcenCharacterBuffer TracingBuffer, ArcenSimContext Context) { tracing = TracingBuffer != null; TargetSorter_Base.TracingBuffer = TracingBuffer; if (tracing) { TracingBuffer.Add("FindTarget:").Add(Weapon.ParentEntity.TypeData.InternalName).Add(" : ").Add(Weapon.TypeData.InternalName); } if (SniperRange == null) { SniperRange = Balance_RangeTable.Instance.GetRowByName("Sniper", false, null); LongRange = Balance_RangeTable.Instance.GetRowByName("Long", false, null); MediumRange = Balance_RangeTable.Instance.GetRowByName("Medium", false, null); ShortRange = Balance_RangeTable.Instance.GetRowByName("Short", false, null); ShieldDefense = Balance_DefenseTable.Instance.GetRowByName("Shields", false, null); StructureDefense = Balance_DefenseTable.Instance.GetRowByName("Structure", false, null); } }
public override void DoOneSecondOfHackingLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context) { if (Hacker.ActiveHack_DurationThusFar >= this.GetTotalSecondsToHack(Target, Hacker)) { } else { if (Hacker.ActiveHack_DurationThusFar % 10 == 0) { FInt AIPPerTick = -(ExternalConstants.Instance.Balance_BaseAIPScale * FInt.FromParts(0, 100)); World_AIW2.Instance.ChangeAIP(AIPPerTick, AIPChangeReason.Hacking, Target.TypeData, Context); int ticksThusFar = Hacker.ActiveHack_DurationThusFar / 10; int totalWholeAIPReduced = (ticksThusFar * AIPPerTick).IntValue; FInt waveMultiplier = FInt.One; FInt multiplierMultiplierPerAIP = FInt.FromParts(1, 030); for (int i = 0; i < totalWholeAIPReduced; i++) { waveMultiplier *= multiplierMultiplierPerAIP; } WaveLogic.SendWave(Context, Target.Side.WorldSide, Target.Side.WorldSide.AITypeData.BudgetItems[AIBudgetType.Wave].NormalMenusToBuyFrom, Target.Side.WorldSide.GetSpecificBudgetThreshold(AIBudgetType.Wave) * waveMultiplier, Target, null); } } }
public virtual void DoPostSortLogic(EntitySystem Weapon, List <GameEntity> Targets, ArcenCharacterBuffer TracingBuffer, ArcenSimContext Context) { tracing = false; TracingBuffer = null; }
public override bool DoSuccessfulCompletionLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context) { return(true); }
public void SeedStartingEntities(WorldSide side, Galaxy galaxy, ArcenSimContext Context, MapTypeData mapType) { galaxy.Mapgen_SeedSpecialEntities(Context, side, DEVOURER_TAG, 1); }
public abstract bool DoSuccessfulCompletionLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context);
public override void DoPreSortLogic(EntitySystem Weapon, List <GameEntity> Targets, ArcenCharacterBuffer TracingBuffer, ArcenSimContext Context) { base.DoPreSortLogic(Weapon, Targets, TracingBuffer, Context); for (int i = 0; i < Targets.Count; i++) { GameEntity entity = Targets[i]; entity.Working_FindTargetOnly_Distance = Weapon.ParentEntity.GetDistanceTo(entity, false); AssignShotsToKillData(Weapon, entity); if (tracing) { if (entity.Working_FindTargetOnly_DebugBuffer == null) { entity.Working_FindTargetOnly_DebugBuffer = new ArcenCharacterBuffer(); } entity.Working_FindTargetOnly_DebugBuffer.Clear(); } } }
public void DoInitialOrReconquestDefenseSeeding(ArcenSimContext Context, Planet ThisPlanet) { GameEntity controller = ThisPlanet.GetController(); AIBudgetItem budgetItem = controller.Side.WorldSide.AITypeData.BudgetItems[AIBudgetType.Reinforcement]; int direGuardianCount = ThisPlanet.MarkLevel.PlanetDireGuardianCount; List <GameEntityTypeData> guardianTypes = new List <GameEntityTypeData>(); if (direGuardianCount > 0) { for (int j = 0; j < budgetItem.DireGuardianMenusToBuyFrom.Count; j++) { for (int i = 0; i < budgetItem.DireGuardianMenusToBuyFrom[j].List.Count; i++) { GameEntityTypeData entityType = budgetItem.DireGuardianMenusToBuyFrom[j].List[i]; guardianTypes.Add(entityType); } } Helper_SeedDireGuardians(Context, ThisPlanet, controller.WorldLocation, controller, guardianTypes, direGuardianCount, FInt.FromParts(0, 250), FInt.FromParts(0, 400), EntityBehaviorType.Guard_Guardian_Patrolling, true); } guardianTypes.Clear(); for (int j = 0; j < budgetItem.GuardianMenusToBuyFrom.Count; j++) { for (int i = 0; i < budgetItem.GuardianMenusToBuyFrom[j].List.Count; i++) { GameEntityTypeData entityType = budgetItem.GuardianMenusToBuyFrom[j].List[i]; if (entityType.Balance_MarkLevel.Ordinal > 0 && entityType.Balance_MarkLevel != ThisPlanet.MarkLevel) { continue; } if (World_AIW2.Instance.CorruptedAIDesigns.Contains(entityType)) { continue; } if (!entityType.AICanUseThisWithoutUnlockingIt && !World_AIW2.Instance.UnlockedAIDesigns.Contains(entityType)) { continue; } guardianTypes.Add(entityType); } } FInt turretStrengthBudget = ThisPlanet.GetGuardingAITurretStrengthCap() / 2; FInt shieldStrengthBudget = ThisPlanet.GetGuardingAIShieldStrengthCap() / 2; FInt guardianStrengthBudget = ThisPlanet.GetGuardingAIGuardianStrengthCap() / 2; FInt fleetShipStrengthBudget = ThisPlanet.GetGuardingAIFleetShipStrengthCap() / 2; int extraStrongPoints = this.GetNumberOfNonControllerStrongAreas(Context, ThisPlanet); // if seeding more than one strong point, seed half as many mobile patrollers, so we have enough for the static stuff FInt mobilePatrollingPortion = extraStrongPoints <= 0 ? FInt.FromParts(0, 400) : FInt.FromParts(0, 200); guardianStrengthBudget -= Helper_SeedGuardians(Context, ThisPlanet, Engine_AIW2.Instance.CombatCenter, controller, guardianTypes, guardianStrengthBudget * mobilePatrollingPortion, FInt.FromParts(0, 500), FInt.FromParts(0, 750), EntityBehaviorType.Guard_Guardian_Patrolling, true, 0); // if seeding more than one strong point, don't seed the stationary patrollers, so we have enough for the static stuff if (extraStrongPoints <= 0) { guardianStrengthBudget -= Helper_SeedGuardians(Context, ThisPlanet, controller.WorldLocation, controller, guardianTypes, guardianStrengthBudget * FInt.FromParts(0, 500), FInt.FromParts(0, 250), FInt.FromParts(0, 400), EntityBehaviorType.Guard_Guardian_Patrolling, false, 0); } FInt portionPerStrongPoint = FInt.One / (extraStrongPoints + 1); for (int i = -1; i < extraStrongPoints; i++) { ArcenPoint strongPointLocation; FInt maxDistance; int seedingsLeft = extraStrongPoints - i; FInt budgetPortion = FInt.One / seedingsLeft; if (i == -1) { strongPointLocation = controller.WorldLocation; maxDistance = FInt.FromParts(0, 150); //FInt portionNotSpending = FInt.One - budgetPortion; //budgetPortion = FInt.One - ( portionNotSpending / 2 ); // leave half as much as we normally would //budgetPortion = Mat.Max( budgetPortion * 2, FInt.One ); } else { strongPointLocation = this.GetPointForNonControllerStrongArea(Context, ThisPlanet, i); maxDistance = FInt.FromParts(0, 100); } guardianStrengthBudget -= Helper_SeedGuardians(Context, ThisPlanet, strongPointLocation, controller, guardianTypes, guardianStrengthBudget * budgetPortion, FInt.FromParts(0, 050), maxDistance, EntityBehaviorType.Guard_Guardian_Anchored, false, 0); } Reinforce(Context, ThisPlanet, controller.Side.WorldSide, shieldStrengthBudget, ReinforcementType.Shield); Reinforce(Context, ThisPlanet, controller.Side.WorldSide, turretStrengthBudget, ReinforcementType.Turret); Reinforce(Context, ThisPlanet, controller.Side.WorldSide, fleetShipStrengthBudget, ReinforcementType.FleetShip); }
public void DoPreSortLogic(EntitySystem Weapon, List <GameEntity> Target, ArcenCharacterBuffer TracingBuffer, ArcenSimContext Context) { }