private Dictionary <int, List <PlanetFaction> > GetPlanetFactions(IDbConnection connection, IReadOnlyDictionary <int, Faction> factionMap) { Dictionary <int, List <PlanetFaction> > planetPlanetFactionMap = new Dictionary <int, List <PlanetFaction> >(); IDbCommand command = connection.CreateCommand(); command.CommandText = "SELECT * FROM PlanetFaction"; var reader = command.ExecuteReader(); while (reader.Read()) { int planetId = reader.GetInt32(0); int factionId = reader.GetInt32(1); bool isPublic = reader.GetBoolean(2); int population = reader.GetInt32(3); int pdfMembers = reader.GetInt32(4); float playerReputation = (float)reader[5]; PlanetFaction planetFaction = new PlanetFaction(factionMap[factionId]) { IsPublic = isPublic, Population = population, PDFMembers = pdfMembers, PlayerReputation = playerReputation }; if (!planetPlanetFactionMap.ContainsKey(planetId)) { planetPlanetFactionMap[planetId] = new List <PlanetFaction>(); } planetPlanetFactionMap[planetId].Add(planetFaction); } return(planetPlanetFactionMap); }
private void HandlePlanetaryAssaults() { foreach (Planet planet in GameSettings.Galaxy.Planets) { if (planet.IsUnderAssault) { PlanetFaction controllingForce = planet.PlanetFactionMap[planet.ControllingFaction.Id]; foreach (PlanetFaction planetFaction in planet.PlanetFactionMap.Values) { if (planetFaction != controllingForce && planetFaction.IsPublic) { // this is a revolting force long attackPower = planetFaction.Population * 3 / 4; long defensePower = controllingForce.PDFMembers; // revolting PDF members count triple for their ability to wreck defensive forces attackPower += planetFaction.PDFMembers * 2; double attackMultiplier = (RNG.GetLinearDouble() / 25.0) + 0.01; double defenseMultiplier = (RNG.GetLinearDouble() / 25.0) + 0.01; if (planetFaction.PDFMembers > 0) { // having PDF members means it's the first round of revolt, triple defensive casualties attackMultiplier *= 3; planetFaction.PDFMembers = 0; } int defendCasualties = defensePower == 0 ? (int)(attackPower * attackMultiplier * 1000) : (int)(attackPower * attackMultiplier / defensePower); int attackCasualties = (int)(defensePower * defenseMultiplier / attackPower); planetFaction.Population -= attackCasualties; if (planetFaction.Population <= 100) { planet.IsUnderAssault = false; planetFaction.IsPublic = false; } controllingForce.PDFMembers -= defendCasualties; controllingForce.Population -= defendCasualties; if (controllingForce.PDFMembers <= 0) { controllingForce.Population += controllingForce.PDFMembers; controllingForce.PDFMembers = 0; planet.ControllingFaction = planetFaction.Faction; } } } } } }
public Planet GenerateNewPlanet(IReadOnlyDictionary <int, PlanetTemplate> planetTemplateMap, Vector2 position, Faction controllingFaction, Faction infiltratingFaction) { PlanetTemplate template = DeterminePlanetTemplate(planetTemplateMap); int nameIndex = RNG.GetIntBelowMax(0, TempPlanetList.PlanetNames.Length); while (_usedPlanetNameIndexes.Contains(nameIndex)) { nameIndex = RNG.GetIntBelowMax(0, TempPlanetList.PlanetNames.Length); } _usedPlanetNameIndexes.Add(nameIndex); int importance = (int)(template.ImportanceRange.BaseValue) + (int)(RNG.NextGaussianDouble() * template.ImportanceRange.StandardDeviation); int taxLevel = RNG.GetIntBelowMax(template.TaxRange.MinValue, template.TaxRange.MaxValue + 1); Planet planet = new Planet(_nextId, TempPlanetList.PlanetNames[nameIndex], position, template, importance, taxLevel); _nextId++; int popToDistribute = (int)(template.PopulationRange.BaseValue) + (int)(Mathf.Pow(10, (float)RNG.NextGaussianDouble()) * template.PopulationRange.StandardDeviation); // determine if this planet starts with a genestealer cult in place // TODO: make this configurable if (infiltratingFaction != null) { double infiltrationRate = RNG.GetLinearDouble() / 2.0; PlanetFaction infiltration = new PlanetFaction(infiltratingFaction); infiltration.PlayerReputation = 0; infiltration.IsPublic = false; infiltration.Population = (int)(popToDistribute * infiltrationRate); infiltration.PDFMembers = (int)(infiltration.Population / 33); planet.PlanetFactionMap[infiltratingFaction.Id] = infiltration; } PlanetFaction planetFaction = new PlanetFaction(controllingFaction); planetFaction.PlayerReputation = 0; planetFaction.IsPublic = true; planetFaction.Population = popToDistribute; planetFaction.PDFMembers = popToDistribute / 33; planet.PlanetFactionMap[controllingFaction.Id] = planetFaction; planet.ControllingFaction = controllingFaction; return(planet); }
private static Unit GenerateNewArmy(PlanetFaction planetFaction, Planet planet) { int factionId = planetFaction.Faction.Id; // if we got here, the assaulting force doesn't have an army generated // generate an army (and decrement it from the population Unit newArmy = TempArmyBuilder.GenerateArmyFromPlanetFaction(planetFaction); if (!planet.FactionSquadListMap.ContainsKey(factionId)) { planet.FactionSquadListMap[factionId] = new List <Squad>(); } // add unit to faction planetFaction.Faction.Units.Add(newArmy); // add unit to planet foreach (Squad squad in newArmy.GetAllSquads()) { squad.IsInReserve = false; squad.Location = planet; planet.FactionSquadListMap[factionId].Add(squad); } // modify planetFaction based on new unit int headcount = newArmy.GetAllMembers().Count(); float ratio = ((float)planetFaction.PDFMembers) / (planetFaction.Population + planetFaction.PDFMembers); int pdfHeadcount = (int)(headcount * ratio); headcount -= pdfHeadcount; planetFaction.PDFMembers -= pdfHeadcount; if (planetFaction.PDFMembers < 0) { headcount -= planetFaction.PDFMembers; planetFaction.PDFMembers = 0; } planetFaction.Population -= headcount; if (planetFaction.Population < 0) { planetFaction.Population = 0; // TODO: remove this planetFaction from the planet? } return(newArmy); }
public static List <Faction> GetContestingFactions(Planet p1) { List <Faction> l = new List <Faction>(); foreach (Link link in p1.LinksByPlanetID1.Union(p1.LinksByPlanetID2).ToList()) { Planet otherPlanet = link.PlanetID1 == p1.PlanetID ? link.PlanetByPlanetID2 : link.PlanetByPlanetID1; if (otherPlanet.PlanetFactions.FirstOrDefault().Influence == GlobalConst.PlanetWarsMaximumIP && !l.Contains(otherPlanet.PlanetFactions.FirstOrDefault().Faction)) { l.Add(otherPlanet.PlanetFactions.FirstOrDefault().Faction); } } PlanetFaction currentDominant = p1.PlanetFactions.FirstOrDefault(); if (!l.Contains(currentDominant.Faction) && currentDominant.Influence > 0) { l.Add(currentDominant.Faction); } return(l); }
/// <summary> /// Updates shadow influence and new owners /// </summary> /// <param name="db"></param> /// <param name="sb">optional spring batle that caused this change (for event logging)</param> public static void SetPlanetOwners(IPlanetwarsEventCreator eventCreator, ZkDataContext db = null, SpringBattle sb = null) { if (db == null) { db = new ZkDataContext(); } Galaxy gal = db.Galaxies.Single(x => x.IsDefault); foreach (Planet planet in gal.Planets) { if (planet.OwnerAccountID != null) { foreach (var ps in planet.PlanetStructures.Where(x => x.OwnerAccountID == null)) { ps.OwnerAccountID = planet.OwnerAccountID; ps.ReactivateAfterBuild(); } } PlanetFaction best = planet.PlanetFactions.OrderByDescending(x => x.Influence).FirstOrDefault(); Faction newFaction = planet.Faction; Account newAccount = planet.Account; if (best == null || best.Influence < GlobalConst.InfluenceToCapturePlanet) { // planet not capture if (planet.Faction != null) { var curFacInfluence = planet.PlanetFactions.Where(x => x.FactionID == planet.OwnerFactionID).Select(x => x.Influence).FirstOrDefault(); if (curFacInfluence <= GlobalConst.InfluenceToLosePlanet) { // owners have too small influence, planet belong to nobody newFaction = null; newAccount = null; } } } else { if (best.Faction != planet.Faction) { newFaction = best.Faction; // best attacker without planets Account candidate = planet.AccountPlanets.Where( x => x.Account.FactionID == newFaction.FactionID && x.AttackPoints > 0 && !x.Account.Planets.Any()).OrderByDescending( x => x.AttackPoints).Select(x => x.Account).FirstOrDefault(); if (candidate == null) { // best attacker candidate = planet.AccountPlanets.Where(x => x.Account.FactionID == newFaction.FactionID && x.AttackPoints > 0).OrderByDescending( x => x.AttackPoints).ThenBy(x => x.Account.Planets.Count()).Select(x => x.Account).FirstOrDefault(); } // best player without planets if (candidate == null) { candidate = newFaction.Accounts.Where(x => !x.Planets.Any()).OrderByDescending(x => x.AccountPlanets.Sum(y => y.AttackPoints)). FirstOrDefault(); } // best with planets if (candidate == null) { candidate = newFaction.Accounts.OrderByDescending(x => x.AccountPlanets.Sum(y => y.AttackPoints)). FirstOrDefault(); } newAccount = candidate; } } // change has occured if (newFaction != planet.Faction) { // disable structures foreach (PlanetStructure structure in planet.PlanetStructures.Where(x => x.StructureType.OwnerChangeDisablesThis)) { structure.ReactivateAfterBuild(); structure.Account = newAccount; } // delete structures being lost on planet change foreach (PlanetStructure structure in planet.PlanetStructures.Where(structure => structure.StructureType.OwnerChangeDeletesThis).ToList()) { db.PlanetStructures.DeleteOnSubmit(structure); } // reset attack points memory foreach (AccountPlanet acp in planet.AccountPlanets) { acp.AttackPoints = 0; } if (newFaction == null) { Account account = planet.Account; Clan clan = null; if (account != null) { clan = planet.Account != null ? planet.Account.Clan : null; } db.Events.InsertOnSubmit(eventCreator.CreateEvent("{0} planet {1} owned by {2} {3} was abandoned. {4}", planet.Faction, planet, account, clan, sb)); if (account != null) { eventCreator.GhostPm(planet.Account.Name, string.Format( "Warning, you just lost planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } } else { // new real owner // log messages if (planet.OwnerAccountID == null) // no previous owner { db.Events.InsertOnSubmit(eventCreator.CreateEvent("{0} has claimed planet {1} for {2} {3}. {4}", newAccount, planet, newFaction, newAccount.Clan, sb)); eventCreator.GhostPm(newAccount.Name, string.Format( "Congratulations, you now own planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } else { db.Events.InsertOnSubmit(eventCreator.CreateEvent("{0} of {1} {2} has captured planet {3} from {4} of {5} {6}. {7}", newAccount, newFaction, newAccount.Clan, planet, planet.Account, planet.Faction, planet.Account.Clan, sb)); eventCreator.GhostPm(newAccount.Name, string.Format( "Congratulations, you now own planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); eventCreator.GhostPm(planet.Account.Name, string.Format( "Warning, you just lost planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } if (planet.PlanetStructures.Any(x => x.StructureType.OwnerChangeWinsGame)) { WinGame(db, gal, newFaction, eventCreator.CreateEvent("CONGRATULATIONS!! {0} has won the PlanetWars by capturing {1} planet {2}!", newFaction, planet.Faction, planet)); } } planet.Faction = newFaction; planet.Account = newAccount; } ReturnPeacefulDropshipsHome(db, planet); } db.SaveChanges(); }
/// <summary> /// Process planet wars turn /// </summary> /// <param name="mapName"></param> /// <param name="extraData"></param> /// <param name="db"></param> /// <param name="winnerSide">0 = first team wins, 1 = second team wins</param> /// <param name="players"></param> /// <param name="text"></param> /// <param name="sb"></param> /// public static void ResolveBattleOutcome(string mapName, List <string> extraData, ZkDataContext db, int?winnerSide, List <Account> players, List <Account> firstSidePlayers, StringBuilder text, SpringBattle sb, IPlanetwarsEventCreator eventCreator, ZkLobbyServer.ZkLobbyServer server) { if (extraData == null) { extraData = new List <string>(); } Galaxy gal = db.Galaxies.Single(x => x.IsDefault); Planet planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); var hqStructure = db.StructureTypes.FirstOrDefault(x => x.EffectDisconnectedMetalMalus != null || x.EffectDistanceMetalBonusMax != null); text.AppendFormat("Battle on {1}/PlanetWars/Planet/{0} has ended\n", planet.PlanetID, GlobalConst.BaseSiteUrl); bool firstFactionWon; bool wasFirstCcDestroyed = false; bool wasSecondCcDestroyed = false; if (winnerSide != null) { if (winnerSide == 0) { firstFactionWon = true; } else { firstFactionWon = false; } wasFirstCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,0")); wasSecondCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,1")); } else { text.AppendFormat("No winner on this battle!"); Trace.TraceError("PW battle without a winner {0}", sb != null ? sb.SpringBattleID : (int?)null); return; } Faction firstFaction = firstSidePlayers.Where(x => x.Faction != null).Select(x => x.Faction).First(); var secondSidePlayers = players.Where(x => x.FactionID != firstFaction.FactionID && x.FactionID != null).ToList(); Faction secondFaction = null; if (secondSidePlayers.Any()) { secondFaction = secondSidePlayers.Where(x => x.Faction != null).Select(x => x.Faction).First(); } Faction winningFaction; Faction losingFaction; bool ccDestroyed = false; if (firstFactionWon) { winningFaction = firstFaction; losingFaction = secondFaction; ccDestroyed = wasFirstCcDestroyed; } else { winningFaction = secondFaction; losingFaction = firstFaction; ccDestroyed = wasSecondCcDestroyed; } if (winningFaction == null) { text.AppendFormat("Winning team had no players!"); Trace.TraceError("PW battle where the winner had no players!", sb != null ? sb.SpringBattleID : (int?)null); return; } double baseInfluence = GlobalConst.BaseInfluencePerBattle; double influenceChange = baseInfluence; double loserInfluence = 0; double ipMultiplier = 1; string influenceReport = ""; string ipReason; bool reducedEnemyInfluence = false; bool flippedDominance = false; bool planetConquered = false; if (ccDestroyed) { ipMultiplier = GlobalConst.PlanetWarsLostCcMultiplier; ipReason = "due to winning but losing Command Centre"; } else { ipReason = "due to winning flawlessly"; } influenceChange = (influenceChange) * ipMultiplier; if (influenceChange < 0) { influenceChange = 0; } influenceChange = Math.Floor(influenceChange * 100) / 100; PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(); if (entry == null) { entry = new PlanetFaction { Faction = winningFaction, Planet = planet, }; planet.PlanetFactions.Add(entry); } // if non-winner currently dominates planet if (entry.Faction != winningFaction) { loserInfluence = entry.Influence; // if win is insufficient to change this if (loserInfluence >= influenceChange) { reducedEnemyInfluence = true; entry.Influence -= influenceChange; } else // flip dominance { flippedDominance = true; planet.PlanetFactions.Remove(entry); entry = new PlanetFaction { Faction = winningFaction, Planet = planet, }; planet.PlanetFactions.Add(entry); entry.Influence += (influenceChange - loserInfluence); if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } else // increase winner's existing dominance { if (entry.Influence < GlobalConst.PlanetWarsMaximumIP) { entry.Influence += influenceChange; if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } string contestReport = ""; int newContested = 0; if (planetConquered) { foreach (Link link in planet.LinksByPlanetID1.Union(planet.LinksByPlanetID2).ToList()) { Planet otherPlanet = link.PlanetID1 == planet.PlanetID ? link.PlanetByPlanetID2 : link.PlanetByPlanetID1; PlanetFaction otherPlanetFaction = otherPlanet.PlanetFactions.FirstOrDefault(); if (otherPlanetFaction.Faction != winningFaction && otherPlanetFaction.Influence > GlobalConst.BreakthroughInfluence) { otherPlanetFaction.Influence = GlobalConst.BreakthroughInfluence; if (newContested > 0) { contestReport += ", "; } contestReport += otherPlanet.Name; newContested++; } } } if (newContested > 0) { contestReport = "Adjacent planets now contested: " + contestReport + "."; } // Check all planets to see if they are contested by a single faction string controlReport = ""; int newControlled = 0; foreach (Planet p1 in gal.Planets) { List <Faction> l = GetContestingFactions(p1); if (l.Count() == 1) { Faction f = l.FirstOrDefault(); // this faction should be made dominant if it is not already PlanetFaction cEntry = p1.PlanetFactions.FirstOrDefault(); if (cEntry.Faction != f) { p1.PlanetFactions.Remove(cEntry); cEntry = new PlanetFaction { Faction = f, Planet = p1, Influence = 0 }; p1.PlanetFactions.Add(cEntry); } if (cEntry.Influence != GlobalConst.PlanetWarsMaximumIP) { cEntry.Influence = GlobalConst.PlanetWarsMaximumIP; if (newControlled > 0) { controlReport += ", "; } controlReport += p1.Name; newControlled++; } } } if (newControlled > 0) { controlReport = "Planets automatically controlled: " + controlReport + "."; } // Update actual *control* of all planets PlanetWarsTurnHandler.SetPlanetOwners(eventCreator, db, sb); try { if (planetConquered) { influenceReport = String.Format("{0} conquered the planet, gained {1} influence ({2}% {3} of {4})", winningFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base"); } else { if (reducedEnemyInfluence) { influenceReport = String.Format("{0} reduced influence of {1} by {2} ({3}% {4} of {5}); {6} has {7} influence remaining on {8}", winningFaction.Shortcut, (losingFaction == null) ? "opposing faction" : losingFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", entry.Faction, entry.Influence, entry.Planet); } else { if (flippedDominance) { influenceReport = String.Format("{0} took dominance from {1} and gained {2} influence ({3}% {4} of {5}); {6} now has {7} influence on {8}", winningFaction.Shortcut, (losingFaction == null) ? "opposing faction" : losingFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", entry.Faction, entry.Influence, entry.Planet); } else { influenceReport = String.Format("{0} gained {1} influence ({2}% {3} of {4}); {5} now has {6} influence on {7} ", winningFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", entry.Faction, entry.Influence, entry.Planet); } } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // paranoia! try { var mainEvent = eventCreator.CreateEvent("{0} defeated {1} on {2} in {3}. {4}. {5} {6}", winningFaction, (losingFaction == null) ? "opposing faction" : losingFaction.Shortcut, planet, (sb == null) ? "no battle" : string.Format("B{0}", sb.SpringBattleID), influenceReport, contestReport, controlReport ); db.Events.InsertOnSubmit(mainEvent); text.AppendLine(mainEvent.PlainText); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } db.SaveChanges(); /*gal.Turn++; * db.SaveChanges(); * * db = new ZkDataContext(); // is this needed - attempt to fix setplanetownersbeing buggy * SetPlanetOwners(eventCreator, db, sb != null ? db.SpringBattles.Find(sb.SpringBattleID) : null); * gal = db.Galaxies.Single(x => x.IsDefault);*/ }
public static void EndTurn(string mapName, List <string> extraData, ZkDataContext db, int?winNum, List <Account> players, StringBuilder text, SpringBattle sb, List <Account> attackers, IPlanetwarsEventCreator eventCreator, ZkLobbyServer.ZkLobbyServer server) { if (extraData == null) { extraData = new List <string>(); } Galaxy gal = db.Galaxies.Single(x => x.IsDefault); Planet planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); var hqStructure = db.StructureTypes.FirstOrDefault(x => x.EffectDisconnectedMetalMalus != null || x.EffectDistanceMetalBonusMax != null); text.AppendFormat("Battle on {1}/PlanetWars/Planet/{0} has ended\n", planet.PlanetID, GlobalConst.BaseSiteUrl); Faction attacker = attackers.Where(x => x.Faction != null).Select(x => x.Faction).First(); var defenders = players.Where(x => x.FactionID != attacker.FactionID && x.FactionID != null).ToList(); bool isAttackerWinner; bool wasAttackerCcDestroyed = false; bool wasDefenderCcDestroyed = false; if (winNum != null) { if (winNum == 0) { isAttackerWinner = true; } else { isAttackerWinner = false; } wasAttackerCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,0")); wasDefenderCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,1")); } else { text.AppendFormat("No winner on this battle!"); Trace.TraceError("PW battle without a winner {0}", sb != null ? sb.SpringBattleID : (int?)null); return; } var evacuatedStructureTypeIDs = GetEvacuatedStructureTypes(extraData, db); string influenceReport = ""; // distribute influence // save influence gains // give influence to main attackers double planetIpDefs = planet.GetEffectiveIpDefense(); double baseInfluence = GlobalConst.BaseInfluencePerBattle; double influenceChange = baseInfluence; double loserInfluence = 0; Faction loserFaction = attacker; // TODO make this less awful bool reducedEnemyInfluence = false; bool flippedDominance = false; bool planetConquered = false; double shipBonus = planet.GetEffectiveShipIpBonus(attacker); double defenseBonus = -planetIpDefs; double techBonus = attacker.GetFactionUnlocks().Count() * GlobalConst.InfluencePerTech; double ipMultiplier = 1; string ipReason; if (!isAttackerWinner) { if (wasDefenderCcDestroyed) { ipMultiplier = GlobalConst.PlanetWarsDefenderWinKillCcMultiplier; ipReason = "from losing but killing defender's CC"; } else { ipMultiplier = 0; ipReason = "from losing horribly"; } } else { if (wasAttackerCcDestroyed) { ipReason = "from losing own CC"; ipMultiplier = GlobalConst.PlanetWarsAttackerWinLoseCcMultiplier; } else { ipReason = "from winning flawlessly"; } } influenceChange = (influenceChange + shipBonus + techBonus + defenseBonus) * ipMultiplier; if (influenceChange < 0) { influenceChange = 0; } influenceChange = Math.Floor(influenceChange * 100) / 100; // main winner influence // PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(x => x.Faction == attacker); PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(); if (entry == null) { entry = new PlanetFaction { Faction = attacker, Planet = planet, }; planet.PlanetFactions.Add(entry); } // if non-winner currently dominates planet if (entry.Faction != attacker) { loserFaction = entry.Faction; loserInfluence = entry.Influence; // if win is insufficient to change this if (loserInfluence >= influenceChange) { reducedEnemyInfluence = true; entry.Influence -= influenceChange; } else // flip dominance { flippedDominance = true; planet.PlanetFactions.Remove(entry); entry = new PlanetFaction { Faction = attacker, Planet = planet, }; planet.PlanetFactions.Add(entry); entry.Influence += (influenceChange - loserInfluence); if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } else // increase winner's existing dominance { if (entry.Influence < GlobalConst.PlanetWarsMaximumIP) { entry.Influence += influenceChange; if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } // TODO remove dependence on attacker if (planetConquered) { // Contest Adjacent Planets // GlobalConst.PlanetWarsBreakthroughIP } // Check all planets to see if they are contested by a single faction try { if (reducedEnemyInfluence) { influenceReport = String.Format("{0} reduced influence of {1} by {2} ({3}% {4} of {5}{6}{7}{8})", attacker.Shortcut, loserFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", techBonus > 0 ? " +" + techBonus + " from techs" : "", shipBonus > 0 ? " +" + shipBonus + " from dropships" : "", defenseBonus != 0 ? " -" + -defenseBonus + " from defenses" : ""); } else { if (flippedDominance) { influenceReport = String.Format("{0} took dominance from {1} and gained {2} influence ({3}% {4} of {5}{6}{7}{8})", attacker.Shortcut, loserFaction.Shortcut, influenceChange - loserInfluence, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", techBonus > 0 ? " +" + techBonus + " from techs" : "", shipBonus > 0 ? " +" + shipBonus + " from dropships" : "", defenseBonus != 0 ? " -" + -defenseBonus + " from defenses" : ""); } else { influenceReport = String.Format("{0} gained {1} influence ({2}% {3} of {4}{5}{6}{7})", attacker.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", techBonus > 0 ? " +" + techBonus + " from techs" : "", shipBonus > 0 ? " +" + shipBonus + " from dropships" : "", defenseBonus != 0 ? " -" + -defenseBonus + " from defenses" : ""); } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // distribute metal var attackersTotalMetal = CalculateFactionMetalGain(planet, hqStructure, attacker, GlobalConst.PlanetWarsAttackerMetal, eventCreator, db, text, sb); var attackerMetal = Math.Floor(attackersTotalMetal / attackers.Count); foreach (Account w in attackers) { w.ProduceMetal(attackerMetal); var ev = eventCreator.CreateEvent("{0} gained {1} metal from battle {2}", w, attackerMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } var defendersTotalMetal = planet.OwnerFactionID == null?Math.Floor(GlobalConst.PlanetWarsDefenderMetal) : CalculateFactionMetalGain(planet, hqStructure, planet.Faction, GlobalConst.PlanetWarsDefenderMetal, eventCreator, db, text, sb); if (defenders.Count > 0) { var defenderMetal = Math.Floor(defendersTotalMetal / defenders.Count); foreach (Account w in defenders) { w.ProduceMetal(defenderMetal); var ev = eventCreator.CreateEvent("{0} gained {1} metal from battle {2}", w, defenderMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } } else { // planet had no defenders, give metal to owner's faction if (planet.OwnerFactionID != null) { planet.Faction.ProduceMetal(defendersTotalMetal); var ev = eventCreator.CreateEvent("{0} gained {1} metal from battle {2}", planet.Faction, defendersTotalMetal, sb); db.Events.InsertOnSubmit(ev); } } // remove attacker's dropships foreach (var pf in planet.PlanetFactions.Where(x => x.Faction == attacker)) { pf.Dropships = 0; } // remove dropships staying for too long (return to faction pool) foreach (var pf in planet.PlanetFactions.Where(x => x.Faction != attacker && x.Dropships > 0 && x.DropshipsLastAdded != null)) { if (DateTime.UtcNow.Subtract(pf.DropshipsLastAdded.Value).TotalMinutes > GlobalConst.PlanetWarsDropshipsStayForMinutes) { pf.Faction.ProduceDropships(pf.Dropships); pf.Dropships = 0; } } // add attack points foreach (Account acc in players) { int ap = acc.Faction == attacker ? GlobalConst.AttackPointsForVictory : GlobalConst.AttackPointsForDefeat; if (acc.Faction != null) { AccountPlanet apentry = planet.AccountPlanets.SingleOrDefault(x => x.AccountID == acc.AccountID); if (apentry == null) { apentry = new AccountPlanet { AccountID = acc.AccountID, PlanetID = planet.PlanetID }; db.AccountPlanets.InsertOnSubmit(apentry); } apentry.AttackPoints += ap; } acc.PwAttackPoints += ap; } // paranoia! try { var mainEvent = eventCreator.CreateEvent("{0} attacked {1} {2} in {3} and {4}. {5}", attacker, planet.Faction, planet, sb, isAttackerWinner ? "won" : "lost", influenceReport ); db.Events.InsertOnSubmit(mainEvent); text.AppendLine(mainEvent.PlainText); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // destroy pw structures killed ingame if (!isAttackerWinner) { var handled = new List <string>(); foreach (string line in extraData.Where(x => x.StartsWith("structurekilled", StringComparison.InvariantCulture))) { string[] data = line.Substring(16).Split(','); string unitName = data[0]; if (handled.Contains(unitName)) { continue; } handled.Add(unitName); foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.IngameUnitName == unitName)) { if (s.StructureType.IsIngameDestructible) { s.ReactivateAfterDestruction(); var ev = eventCreator.CreateEvent("{0} has been disabled on {1} planet {2}. {3}", s.StructureType.Name, planet.Faction, planet, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } } } } else { // attacker won disable all but evacuated foreach (var s in planet.PlanetStructures.Where(x => x.StructureType.IsIngameDestructible)) { if (evacuatedStructureTypeIDs.Contains(s.StructureTypeID)) { var evSaved = eventCreator.CreateEvent("{0} structure {1} on planet {2} has been saved by evacuation. {3}", planet.Faction, s.StructureType, planet, sb); db.Events.InsertOnSubmit(evSaved); text.AppendLine(evSaved.PlainText); } else { s.ReactivateAfterDestruction(); } } // destroy structures by battle (usually defenses) foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.BattleDeletesThis).ToList()) { if (evacuatedStructureTypeIDs.Contains(s.StructureTypeID)) { var evSaved = eventCreator.CreateEvent("{0} structure {1} on planet {2} has been saved by evacuation. {3}", planet.Faction, s.StructureType, planet, sb); db.Events.InsertOnSubmit(evSaved); text.AppendLine(evSaved.PlainText); } else { planet.PlanetStructures.Remove(s); } } var ev = eventCreator.CreateEvent("All non-evacuated structures have been disabled on {0} planet {1}. {2}", planet.Faction, planet, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } db.SaveChanges(); // no longer used? //gal.DecayInfluence(); //gal.SpreadInfluence(); // process faction energies foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { fac.ProcessEnergy(gal.Turn); } // process production (incl. victory points) gal.ProcessProduction(); db.SaveChanges(); var vpFacs = db.Factions.Where(x => x.VictoryPoints > 0); if (vpFacs.Count() > 1) { foreach (var fac in vpFacs) { fac.VictoryPoints -= Math.Min(fac.VictoryPoints, GlobalConst.VictoryPointDecay); } } // delete one time activated structures gal.DeleteOneTimeActivated(eventCreator, db); db.SaveChanges(); // process treaties foreach (var tr in db.FactionTreaties.Where(x => x.TreatyState == TreatyState.Accepted || x.TreatyState == TreatyState.Suspended)) { var failedTradeFaction = tr.ProcessTrade(false); if (failedTradeFaction == null) { tr.TreatyState = TreatyState.Accepted; if (tr.TurnsTotal != null) { tr.TurnsRemaining--; if (tr.TurnsRemaining <= 0) // treaty expired { tr.TreatyState = TreatyState.Ended; tr.FactionByAcceptingFactionID.ProduceMetal(tr.AcceptingFactionGuarantee ?? 0); tr.FactionByProposingFactionID.ProduceMetal(tr.ProposingFactionGuarantee ?? 0); } } } else { // failed to perform trade if (tr.TreatyUnableToTradeMode == TreatyUnableToTradeMode.Suspend) { tr.TreatyState = TreatyState.Suspended; } else { // forced cancel tr.CancelTreaty(failedTradeFaction); db.Events.InsertOnSubmit(server.PlanetWarsEventCreator.CreateEvent("Treaty {0} between {1} and {2} cancelled by {3} because it failed to trade", tr, tr.FactionByProposingFactionID, tr.FactionByAcceptingFactionID, failedTradeFaction)); } } } // burn extra energy foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { fac.ConvertExcessEnergyToMetal(); } int?oldOwner = planet.OwnerAccountID; gal.Turn++; db.SaveChanges(); db = new ZkDataContext(); // is this needed - attempt to fix setplanetownersbeing buggy SetPlanetOwners(eventCreator, db, sb != null ? db.SpringBattles.Find(sb.SpringBattleID) : null); gal = db.Galaxies.Single(x => x.IsDefault); var winByVictoryPoints = db.Factions.FirstOrDefault(x => !x.IsDeleted && x.VictoryPoints >= GlobalConst.PlanetWarsVictoryPointsToWin); if (winByVictoryPoints != null) { WinGame(db, gal, winByVictoryPoints, eventCreator.CreateEvent("CONGRATULATIONS!! {0} has won the PlanetWars by getting enough victory points!", winByVictoryPoints)); db.SaveChanges(); } planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); if (planet.OwnerAccountID != oldOwner && planet.OwnerAccountID != null) { text.AppendFormat("Congratulations!! Planet {0} was conquered by {1} !! {3}/PlanetWars/Planet/{2}\n", planet.Name, planet.Account.Name, planet.PlanetID, GlobalConst.BaseSiteUrl); } server.PublishUserProfilePlanetwarsPlayers(); try { // store history foreach (Planet p in gal.Planets) { var hist = db.PlanetOwnerHistories.FirstOrDefault(x => x.PlanetID == p.PlanetID && x.Turn == gal.Turn); if (hist == null) { hist = new PlanetOwnerHistory() { PlanetID = p.PlanetID, Turn = gal.Turn }; db.PlanetOwnerHistories.Add(hist); } hist.OwnerAccountID = p.OwnerAccountID; hist.OwnerClanID = p.OwnerAccountID != null ? p.Account.ClanID : null; hist.OwnerFactionID = p.OwnerFactionID; } db.SaveChanges(); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.AppendLine("error saving history: " + ex); } //rotate map if (GlobalConst.RotatePWMaps) { db = new ZkDataContext(); gal = db.Galaxies.Single(x => x.IsDefault); planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); var mapList = db.Resources.Where(x => x.MapPlanetWarsIcon != null && x.Planets.Where(p => p.GalaxyID == gal.GalaxyID).Count() == 0 && x.MapSupportLevel >= MapSupportLevel.Featured && x.ResourceID != planet.MapResourceID && x.MapWaterLevel == planet.Resource.MapWaterLevel).ToList(); if (mapList.Count > 0) { int r = new Random().Next(mapList.Count); int resourceID = mapList[r].ResourceID; Resource newMap = db.Resources.Single(x => x.ResourceID == resourceID); text.AppendLine(String.Format("Map cycler - {0} maps found, selected map {1} to replace map {2}", mapList.Count, newMap.InternalName, planet.Resource.InternalName)); planet.Resource = newMap; gal.IsDirty = true; } else { text.AppendLine("Map cycler - no maps found"); } db.SaveChanges(); } }
public static MvcHtmlString PrintInfluence(this HtmlHelper helper, PlanetFaction planetFaction) { return(PrintInfluence(helper, planetFaction.Faction, planetFaction.Influence)); }
/// <summary> /// Process planet wars turn /// </summary> /// <param name="mapName"></param> /// <param name="extraData"></param> /// <param name="db"></param> /// <param name="winNum">0 = attacker wins, 1 = defender wins</param> /// <param name="players"></param> /// <param name="text"></param> /// <param name="sb"></param> public static void EndTurn(string mapName, List <string> extraData, ZkDataContext db, int?winNum, List <Account> players, StringBuilder text, SpringBattle sb, List <Account> attackers) { if (extraData == null) { extraData = new List <string>(); } Galaxy gal = db.Galaxies.Single(x => x.IsDefault); Planet planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); text.AppendFormat("Battle on http://zero-k.info/PlanetWars/Planet/{0} has ended\n", planet.PlanetID); Faction attacker = attackers.Where(x => x.Faction != null).Select(x => x.Faction).First(); var defenders = players.Where(x => x.FactionID != attacker.FactionID && x.FactionID != null).ToList(); bool isAttackerWinner; bool wasAttackerCcDestroyed = false; bool wasDefenderCcDestroyed = false; if (winNum != null) { if (winNum == 0) { isAttackerWinner = true; } else { isAttackerWinner = false; } wasAttackerCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,0")); wasDefenderCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,1")); } else { text.AppendFormat("No winner on this battle!"); Trace.TraceError("PW battle without a winner {0}", sb != null ? sb.SpringBattleID : (int?)null); return; } int dropshipsSent = (planet.PlanetFactions.Where(x => x.Faction == attacker).Sum(x => (int?)x.Dropships) ?? 0); bool isLinked = planet.CanDropshipsAttack(attacker); string influenceReport = ""; // distribute influence // save influence gains // give influence to main attackers double planetDropshipDefs = (planet.PlanetStructures.Where(x => x.IsActive).Sum(x => x.StructureType.EffectDropshipDefense) ?? 0); double planetIpDefs = (planet.PlanetStructures.Where(x => x.IsActive).Sum(x => x.StructureType.EffectReduceBattleInfluenceGain) ?? 0); double baseInfluence = GlobalConst.BaseInfluencePerBattle; double influence = baseInfluence; double effectiveShips = Math.Max(0, (dropshipsSent - planetDropshipDefs)); double shipBonus = effectiveShips * GlobalConst.InfluencePerShip; double defenseBonus = -planetIpDefs; double techBonus = attacker.GetFactionUnlocks().Count() * GlobalConst.InfluencePerTech; double ipMultiplier = 1; string ipReason; if (!isAttackerWinner) { if (wasDefenderCcDestroyed) { ipMultiplier = 0.2; ipReason = "from losing but killing defender's CC"; } else { ipMultiplier = 0; ipReason = "from losing horribly"; } } else { if (wasAttackerCcDestroyed) { ipReason = "from losing own CC"; ipMultiplier = 0.5; } else { ipReason = "from winning flawlessly"; } } if (!isLinked && effectiveShips < GlobalConst.DropshipsForFullWarpIPGain) { var newMult = effectiveShips / GlobalConst.DropshipsForFullWarpIPGain; ipMultiplier *= newMult; ipReason = ipReason + string.Format(" and reduced to {0}% because only {1} of {2} ships needed for warp attack got past defenses", (int)(newMult * 100.0), (int)effectiveShips, GlobalConst.DropshipsForFullWarpIPGain); } influence = (influence + shipBonus + techBonus) * ipMultiplier + defenseBonus; if (influence < 0) { influence = 0; } influence = Math.Floor(influence * 100) / 100; // main winner influence PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(x => x.Faction == attacker); if (entry == null) { entry = new PlanetFaction { Faction = attacker, Planet = planet, }; planet.PlanetFactions.Add(entry); } entry.Influence += influence; // clamping of influence // gained over 100, sole owner if (entry.Influence >= 100) { entry.Influence = 100; foreach (var pf in planet.PlanetFactions.Where(x => x.Faction != attacker)) { pf.Influence = 0; } } else { var sumOthers = planet.PlanetFactions.Where(x => x.Faction != attacker).Sum(x => (double?)x.Influence) ?? 0; if (sumOthers + entry.Influence > 100) { var excess = sumOthers + entry.Influence - 100; foreach (var pf in planet.PlanetFactions.Where(x => x.Faction != attacker)) { pf.Influence -= pf.Influence / sumOthers * excess; } } } try { influenceReport = String.Format("{0} gained {1} influence ({2}% {3} of {4}{5}{6}{7})", attacker.Shortcut, influence, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", techBonus > 0 ? " +" + techBonus + " from techs" : "", shipBonus > 0 ? " +" + shipBonus + " from dropships" : "", defenseBonus != 0 ? " -" + -defenseBonus + " from defenses" : ""); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // distribute metal var attackersTotalMetal = Math.Floor(GlobalConst.PlanetWarsAttackerMetal); var defendersTotalMetal = Math.Floor(GlobalConst.PlanetWarsDefenderMetal); var attackerMetal = Math.Floor(attackersTotalMetal / attackers.Count); var defenderMetal = Math.Floor(defendersTotalMetal / defenders.Count); foreach (Account w in attackers) { w.ProduceMetal(attackerMetal); var ev = Global.CreateEvent("{0} gained {1} metal from battle {2}", w, attackerMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } foreach (Account w in defenders) { w.ProduceMetal(defenderMetal); var ev = Global.CreateEvent("{0} gained {1} metal from battle {2}", w, defenderMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } // remove dropships foreach (var pf in planet.PlanetFactions.Where(x => x.Faction == attacker)) { pf.Dropships = 0; } // add attack points foreach (Account acc in players) { int ap = acc.Faction == attacker ? GlobalConst.AttackPointsForVictory : GlobalConst.AttackPointsForDefeat; if (acc.Faction != null) { AccountPlanet apentry = planet.AccountPlanets.SingleOrDefault(x => x.AccountID == acc.AccountID); if (apentry == null) { apentry = new AccountPlanet { AccountID = acc.AccountID, PlanetID = planet.PlanetID }; db.AccountPlanets.InsertOnSubmit(apentry); } apentry.AttackPoints += ap; } acc.PwAttackPoints += ap; } // paranoia! try { var mainEvent = Global.CreateEvent("{0} attacked {1} {2} in {3} and {4}. {5}", attacker, planet.Faction, planet, sb, isAttackerWinner ? "won. " : "lost. ", influenceReport ); db.Events.InsertOnSubmit(mainEvent); text.AppendLine(mainEvent.PlainText); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // destroy pw structures killed ingame if (!isAttackerWinner) { var handled = new List <string>(); foreach (string line in extraData.Where(x => x.StartsWith("structurekilled"))) { string[] data = line.Substring(16).Split(','); string unitName = data[0]; if (handled.Contains(unitName)) { continue; } handled.Add(unitName); foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.IngameUnitName == unitName)) { if (s.StructureType.IsIngameDestructible) { s.IsActive = false; s.ActivatedOnTurn = gal.Turn + (int)(s.StructureType.TurnsToActivate * (GlobalConst.StructureIngameDisableTimeMult - 1)); var ev = Global.CreateEvent("{0} has been disabled on {1} planet {2}. {3}", s.StructureType.Name, planet.Faction, planet, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } } } } else { // attacker won disable all foreach (var s in planet.PlanetStructures.Where(x => x.StructureType.IsIngameDestructible)) { s.IsActive = false; s.ActivatedOnTurn = gal.Turn + (int)(s.StructureType.TurnsToActivate * (GlobalConst.StructureIngameDisableTimeMult - 1)); } // destroy structures by battle (usually defenses) foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.BattleDeletesThis).ToList()) { planet.PlanetStructures.Remove(s); } var ev = Global.CreateEvent("All structures have been disabled on {0} planet {1}. {2}", planet.Faction, planet, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } db.SubmitAndMergeChanges(); gal.DecayInfluence(); gal.SpreadInfluence(); // process faction energies foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { fac.ProcessEnergy(gal.Turn); } // process production gal.ProcessProduction(); // process treaties foreach (var tr in db.FactionTreaties.Where(x => x.TreatyState == TreatyState.Accepted || x.TreatyState == TreatyState.Suspended)) { if (tr.ProcessTrade(false)) { tr.TreatyState = TreatyState.Accepted; if (tr.TurnsTotal != null) { tr.TurnsRemaining--; if (tr.TurnsRemaining <= 0) { tr.TreatyState = TreatyState.Invalid; db.FactionTreaties.DeleteOnSubmit(tr); } } } else { tr.TreatyState = TreatyState.Suspended; } } // burn extra energy foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { fac.ConvertExcessEnergyToMetal(); } int?oldOwner = planet.OwnerAccountID; gal.Turn++; db.SubmitAndMergeChanges(); db = new ZkDataContext(); // is this needed - attempt to fix setplanetownersbeing buggy PlanetwarsController.SetPlanetOwners(db, sb); gal = db.Galaxies.Single(x => x.IsDefault); planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); if (planet.OwnerAccountID != oldOwner && planet.OwnerAccountID != null) { text.AppendFormat("Congratulations!! Planet {0} was conquered by {1} !! http://zero-k.info/PlanetWars/Planet/{2}\n", planet.Name, planet.Account.Name, planet.PlanetID); } try { // store history foreach (Planet p in gal.Planets) { db.PlanetOwnerHistories.InsertOnSubmit(new PlanetOwnerHistory { PlanetID = p.PlanetID, OwnerAccountID = p.OwnerAccountID, OwnerClanID = p.OwnerAccountID != null ? p.Account.ClanID : null, OwnerFactionID = p.OwnerFactionID, Turn = gal.Turn }); } db.SubmitChanges(); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.AppendLine("error saving history: " + ex); } //rotate map if (GlobalConst.RotatePWMaps) { db = new ZkDataContext(); gal = db.Galaxies.Single(x => x.IsDefault); planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); var mapList = db.Resources.Where(x => x.MapPlanetWarsIcon != null && x.Planets.Where(p => p.GalaxyID == gal.GalaxyID).Count() == 0 && x.FeaturedOrder != null && x.ResourceID != planet.MapResourceID && x.MapWaterLevel == planet.Resource.MapWaterLevel).ToList(); if (mapList.Count > 0) { int r = new Random().Next(mapList.Count); int resourceID = mapList[r].ResourceID; Resource newMap = db.Resources.Single(x => x.ResourceID == resourceID); text.AppendLine(String.Format("Map cycler - {0} maps found, selected map {1} to replace map {2}", mapList.Count, newMap.InternalName, planet.Resource.InternalName)); planet.Resource = newMap; gal.IsDirty = true; } else { text.AppendLine("Map cycler - no maps found"); } db.SubmitAndMergeChanges(); } }
public ActionResult SendDropships(int planetID, int count, bool?useWarp) { var db = new ZkDataContext(); Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); if (acc.Faction == null) { return(Content("Join a faction first")); } Planet planet = db.Planets.SingleOrDefault(x => x.PlanetID == planetID); int there = planet.PlanetFactions.Where(x => x.FactionID == acc.FactionID).Sum(x => (int?)x.Dropships) ?? 0; bool accessible = useWarp == true?planet.CanDropshipsWarp(acc.Faction) : planet.CanDropshipsAttack(acc.Faction); if (!accessible) { return(Content(string.Format("That planet cannot be attacked"))); } if (Global.Server.GetPlanetBattles(planet).Any(x => x.IsInGame)) { return(Content("Battle in progress on the planet, cannot send ships")); } int cnt = Math.Max(count, 0); int capa = acc.GetDropshipCapacity(); if (cnt + there > capa) { return(Content("Too many dropships on planet - the fleet limit is " + capa)); } cnt = Math.Min(cnt, (int)acc.GetDropshipsAvailable()); if (useWarp == true) { cnt = Math.Min(cnt, (int)acc.GetWarpAvailable()); } if (cnt > 0) { acc.SpendDropships(cnt); if (useWarp == true) { acc.SpendWarps(cnt); if (cnt < GlobalConst.DropshipsForFullWarpIPGain) { return(Content($"You must send at least {GlobalConst.DropshipsForFullWarpIPGain} dropships when warping")); } } if (planet.Account != null) { Global.Server.GhostPm(planet.Account.Name, string.Format( "Warning: long range scanners detected fleet of {0} ships inbound to your planet {1} {3}/Planetwars/Planet/{2}", cnt, planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } PlanetFaction pac = planet.PlanetFactions.SingleOrDefault(x => x.FactionID == acc.FactionID); if (pac == null) { pac = new PlanetFaction { FactionID = Global.FactionID, PlanetID = planetID }; db.PlanetFactions.InsertOnSubmit(pac); } pac.Dropships += cnt; pac.DropshipsLastAdded = DateTime.UtcNow; if (cnt > 0) { db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} sends {1} {2} dropships to {3} {4} {5}", acc, cnt, acc.Faction, planet.Faction, planet, useWarp == true ? "using warp drives" : "")); } db.SaveChanges(); } return(RedirectToAction("Planet", new { id = planetID })); }
public static Unit GenerateArmyFromPlanetFaction(PlanetFaction planetFaction) { return(GenerateArmy(0, planetFaction.Faction)); }
private void EndOfTurnPlanetUpdate(Planet planet) { // increase the population of the planet float pdfRatio = ((float)planet.PlanetaryDefenseForces) / planet.Population; foreach (PlanetFaction planetFaction in planet.PlanetFactionMap.Values) { float newPop = 0; switch (planetFaction.Faction.GrowthType) { case GrowthType.Logistic: newPop = planetFaction.Population * 1.00015f; break; case GrowthType.Conversion: PlanetFaction defaultFaction = planet.PlanetFactionMap .Values .First(pf => pf.Faction.IsDefaultFaction); // converting factions always convert one new member per week if (defaultFaction?.Population > 0) { defaultFaction.Population--; planetFaction.Population++; float pdfChance = (float)(defaultFaction.PDFMembers) / defaultFaction.Population; if (RNG.GetLinearDouble() < pdfChance) { defaultFaction.PDFMembers--; planetFaction.PDFMembers++; } if (planetFaction.Population > 100) { // at larger sizes, converting factions // also grow organically // at a much faster rate than a normal population newPop = planetFaction.Population * 1.002f; } // if the converting population is larger than // the non-converted PDF force, they start their revolt if (newPop > (planet.PlanetaryDefenseForces - planetFaction.PDFMembers) && !planet.IsUnderAssault) { planetFaction.IsPublic = true; planet.IsUnderAssault = true; } } break; default: newPop = planetFaction.Population; break; } planetFaction.Population = (int)newPop; if (RNG.GetLinearDouble() < newPop % 1) { planetFaction.Population++; } // if the pdf is less than three percent of the population, more people are drafted // additionally, secret factions love to infiltrate the PDF if (pdfRatio < 0.03f || !planetFaction.IsPublic) { planetFaction.PDFMembers += (int)(newPop * 0.05f); } else if (planetFaction.Faction == planet.ControllingFaction || !planetFaction.IsPublic) { planetFaction.PDFMembers += (int)(newPop * 0.03f); } } // see if the planet is called to tithe a regiment //tax level / 50 if (RNG.GetLinearDouble() < planet.TaxLevel / 50f) { GenerateNewRegiment(planet); } }