float getThreatFactor(PlanetData planet, TactileInformation info) { // = Ship difference enemy and this planet if an enemy attacks float threat = NO_POINTS; foreach(TactilePlanet enemy in info.enemies) { if(enemy.planetData.Owner == null) { continue; } threat = Math.Max(threat, getAttackPoints(enemy.planetData, planet, enemy.distance)); } return threat; }
// Sums up points for all kinds of movement and does one of them bool PerformMovementOnPlanet(TactileInformation planetInfo) { if(planetInfo.origin.Ships <= 1) { return false; } // Get points for doing nothing... float shouldWaitForProductionPoints = getShouldWaitForProductionPoints(planetInfo.origin); // Get highest attack points... float shouldAttackPoints = NO_POINTS; TactilePlanet shouldAttackPlanet = null; foreach (TactilePlanet enemy in planetInfo.enemies) { Debug.Assert(planetInfo.origin.Owner == playerData); float points = getAttackPoints(planetInfo.origin, enemy.planetData, enemy.distance); if(shouldAttackPlanet == null || shouldAttackPoints < points) { shouldAttackPoints = points; shouldAttackPlanet = enemy; } } // Get points for supporting friends... float shouldSupportPoints = NO_POINTS; PlanetData shouldSupportPlanet = null; foreach (TactileInformation friend in tactileInfo) { if (friend == planetInfo) { continue; } float points = getSupportPoints(planetInfo, friend, TroopData.GetTravelTime(planetInfo.origin, friend.origin)); if (shouldSupportPlanet == null || shouldSupportPoints < points) { shouldSupportPoints = points; shouldSupportPlanet = friend.origin; } } float factoryUpgradePoints = getFactoryUpgradePoints(planetInfo.origin); float hangarUpgradePoints = getHangarUpgradePoints(planetInfo.origin); float upgradePoints = Math.Max(factoryUpgradePoints, hangarUpgradePoints); if (shouldWaitForProductionPoints > shouldAttackPoints && shouldWaitForProductionPoints > shouldSupportPoints && shouldWaitForProductionPoints > upgradePoints) { //Wait for production Debug.Log("AI '" + playerData.Name + "', Planet '" + planetInfo.origin.Name + "': Doing nothing."); return false; } if (upgradePoints > shouldAttackPoints && upgradePoints > shouldSupportPoints) { //Upgrade if(factoryUpgradePoints >= hangarUpgradePoints) { Debug.Log("AI '" + playerData.Name + "', Planet '" + planetInfo.origin.Name + "': Upgrading Factory."); return planetInfo.origin.UpgradeFactory(); } Debug.Log("AI '" + playerData.Name + "', Planet '" + planetInfo.origin.Name + "': Upgrading Hangar."); return planetInfo.origin.UpgradeHangar(); } if (shouldAttackPoints >= shouldSupportPoints && shouldAttackPlanet != null) { float shipsForAttack = planetInfo.origin.Ships; if (shouldAttackPoints >= 25) { // Don't send all ships shipsForAttack = shouldAttackPoints * 1.2f; shipsForAttack = Mathf.Min(shipsForAttack, planetInfo.origin.Ships); } if(shipsForAttack <= 0) { return false; } todaysAtk.Add(planetInfo.origin, shouldAttackPlanet.planetData); MessageHub.Publish(new NewTroopMovementEvent(this, space.getPlanet(planetInfo.origin), space.getPlanet(shouldAttackPlanet.planetData), (int)shipsForAttack)); return true; // Make another movement if possible } else if(shouldSupportPlanet != null) { float shipsForSupport = shouldSupportPoints + Math.Abs(shouldAttackPoints * 1.2f); shipsForSupport = Mathf.Min(shipsForSupport, planetInfo.origin.Ships); if (shipsForSupport <= 0) { return false; } MessageHub.Publish(new NewTroopMovementEvent(this, space.getPlanet(planetInfo.origin), space.getPlanet(shouldSupportPlanet), (int)shipsForSupport)); return true; // Make another movement if possible } return false; }
float getSupportPoints(TactileInformation origin, TactileInformation friend, int distanceInDays) { if(friend.threatFactor - origin.threatFactor < distanceInDays * 30) { return NO_POINTS; } float points = friend.threatFactor - origin.threatFactor; float helpfulFactor = 1f - (distanceInDays * distanceInDays * 0.02f); // exp. curve helpfulFactor = Math.Min(helpfulFactor, 0); // [0..1] 1 day: 0.98, 2 days: 0.92, 3 days: 0.82 ... 7 days: 0.02; 8 days: 0 points = points * helpfulFactor; //TODO: only help planet if it makes sense! (Give up if there is no hope) return points; }