private static void ProcessPlanetWars(SpringBattleContext result, ZkLobbyServer.ZkLobbyServer server, SpringBattle sb, ZkDataContext db, StringBuilder text) { if (result.LobbyStartContext.Mode != AutohostMode.Planetwars || sb.PlayerCount < 2 || sb.Duration < GlobalConst.MinDurationForPlanetwars) { return; } List <int> winnerTeams = sb.SpringBattlePlayers.Where(x => x.IsInVictoryTeam && !x.IsSpectator).Select(x => x.AllyNumber).Distinct().ToList(); int? winNum = null; if (winnerTeams.Count == 1) { winNum = winnerTeams[0]; if (winNum > 1) { winNum = null; } } PlanetWarsTurnHandler.EndTurn(result.LobbyStartContext.Map, result.OutputExtras, db, winNum, sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account).ToList(), text, sb, sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.AllyNumber == 0).Select(x => x.Account).ToList(), server.PlanetWarsEventCreator, server); server.PlanetWarsMatchMaker.RemoveFromRunningBattles(result.LobbyStartContext.BattleID); }
public ActionResult KickPlayerFromClan(int accountID) { var db = new ZkDataContext(); var kickee_acc = db.Accounts.SingleOrDefault(x => x.AccountID == accountID); if (kickee_acc == null) { return(Content("No such person")); } if (!kickee_acc.ClanID.HasValue) { return(Content(kickee_acc.Name + " not in a clan")); } int clanID = kickee_acc.ClanID.Value; if (!Global.IsModerator) { if (kickee_acc.ClanID != Global.Account.ClanID) { return(Content("Target not in your clan")); } if (!Global.Account.HasClanRight(x => x.RightKickPeople)) { return(Content("You have no kicking rights")); // unclanned people get handled here } } PerformLeaveClan(accountID); db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator()); Global.Server.PublishAccountUpdate(kickee_acc); return(RedirectToAction("Detail", new { id = clanID })); }
public ActionResult ActivateTargetedStructure(int planetID, int structureTypeID) { //This call is never to be called before/outside of SetStructureTarget var db = new ZkDataContext(); //Get the pre-set target planet ID PlanetStructure structure = db.PlanetStructures.FirstOrDefault(x => x.PlanetID == planetID && x.StructureTypeID == structureTypeID); int targetID = structure.TargetPlanetID ?? -1; if (targetID == -1) { return(Content("Structure has no target")); } if (!structure.IsActive) { return(Content(String.Format("Structure {0} is inactive", structure.StructureType.Name))); } ActionResult ret = null; if (structure.StructureType.EffectCreateLink == true) { ret = CreateLink(planetID, structureTypeID, targetID); } if (ret != null) { return(ret); // exit with message if error occurs } if (structure.StructureType.EffectChangePlanetMap == true) { ret = ChangePlanetMap(planetID, structureTypeID, targetID, null); } if (ret != null) { return(ret); // exit with message if error occurs } if (structure.StructureType.EffectPlanetBuster == true) { ret = FirePlanetBuster(planetID, structureTypeID, targetID); } if (ret != null) { return(ret); // exit with message if error occurs } if (structure.StructureType.IsSingleUse) // single-use structure, remove { db.PlanetStructures.DeleteOnSubmit(structure); } db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); //this is needed for the buster to update ownership after planet destruction if (ret != null) { return(ret); } return(RedirectToAction("Planet", new { id = planetID })); }
public ActionResult DestroyStructure(int planetID, int structureTypeID) { using (var db = new ZkDataContext()) { Planet planet = db.Planets.Single(p => p.PlanetID == planetID); if (Global.Server.GetPlanetBattles(planet).Any(x => x.IsInGame)) { return(Content("Battle in progress on the planet, cannot destroy structures")); } Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); StructureType structureType = db.StructureTypes.SingleOrDefault(s => s.StructureTypeID == structureTypeID); Faction faction = planet.Faction; if (structureType == null) { return(Content("Structure type does not exist.")); } if (!structureType.IsBuildable) { return(Content("Structure is not buildable.")); } // assumes you can only build level 1 structures! if higher level structures can be built directly, we should check down the upgrade chain too if (!planet.PlanetStructures.Any(x => x.StructureTypeID == structureTypeID)) { return(Content("Structure or its upgrades not present")); } List <PlanetStructure> list = planet.PlanetStructures.Where(x => x.StructureTypeID == structureTypeID).ToList(); PlanetStructure toDestroy = list[0]; if (!toDestroy.IsActive) { return(Content("Structure is currently disabled")); } var canDestroy = toDestroy.OwnerAccountID == acc.AccountID || planet.OwnerAccountID == acc.AccountID; if (!canDestroy) { return(Content("Structure is not under your control.")); } var refund = toDestroy.StructureType.Cost * GlobalConst.SelfDestructRefund; if (toDestroy.Account != null) { toDestroy.Account.ProduceMetal(refund); } else { faction?.ProduceMetal(refund); } db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} has demolished a {1} on {2}.", acc, toDestroy.StructureType, planet)); db.PlanetStructures.DeleteOnSubmit(toDestroy); db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); } return(RedirectToAction("Planet", new { id = planetID })); }
private void RecordPlanetwarsLoss(AttackOption option) { if (option.OwnerFactionID != null) { if (option.OwnerFactionID == missedDefenseFactionID) { missedDefenseCount++; } else { missedDefenseCount = 0; missedDefenseFactionID = option.OwnerFactionID.Value; } } var message = string.Format("{0} won because nobody tried to defend", AttackingFaction.Name); foreach (var fac in factions) { server.GhostChanSay(fac.Shortcut, message); } var text = new StringBuilder(); try { var db = new ZkDataContext(); var playerIds = option.Attackers.Select(x => x).Union(option.Defenders.Select(x => x)).ToList(); /*PlanetWarsTurnHandler.EndTurn(option.Map, * null, * db, * 0, * db.Accounts.Where(x => playerIds.Contains(x.Name) && (x.Faction != null)).ToList(), * text, * null, * db.Accounts.Where(x => option.Attackers.Contains(x.Name) && (x.Faction != null)).ToList(), * server.PlanetWarsEventCreator, server);*/ PlanetWarsTurnHandler.ResolveBattleOutcome(option.Map, null, db, 0, db.Accounts.Where(x => playerIds.Contains(x.Name) && (x.Faction != null)).ToList(), db.Accounts.Where(x => option.Attackers.Contains(x.Name) && (x.Faction != null)).ToList(), text, null, server.PlanetWarsEventCreator, server); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.Append(ex); } }
public ActionResult LeaveClan() { var clan = PerformLeaveClan(Global.AccountID); if (clan == null) { return(Content("This clan is too big to leave")); } PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator()); return(RedirectToAction("Index", new { id = clan.ClanID })); }
public ActionResult BuildStructure(int planetID, int structureTypeID) { using (var db = new ZkDataContext()) { Planet planet = db.Planets.Single(p => p.PlanetID == planetID); if (Global.Server.GetPlanetBattles(planet).Any(x => x.IsInGame)) { return(Content("Battle in progress on the planet, cannot build structures")); } Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); if (acc.FactionID != planet.OwnerFactionID) { return(Content("Planet is not under your control.")); } StructureType structureType = db.StructureTypes.SingleOrDefault(s => s.StructureTypeID == structureTypeID); if (structureType == null) { return(Content("Structure type does not exist.")); } if (!structureType.IsBuildable) { return(Content("Structure is not buildable.")); } if (acc.GetMetalAvailable() < structureType.Cost) { return(Content("Insufficient metal")); } acc.SpendMetal(structureType.Cost); var newBuilding = new PlanetStructure { StructureTypeID = structureTypeID, StructureType = structureType, PlanetID = planetID, OwnerAccountID = acc.AccountID, }; newBuilding.ReactivateAfterBuild(); db.PlanetStructures.InsertOnSubmit(newBuilding); db.SaveChanges(); db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} has built a {1} on {2} planet {3}.", acc, newBuilding.StructureType, planet.Faction, planet)); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); } return(RedirectToAction("Planet", new { id = planetID })); }
public static Faction PerformLeaveFaction(int accountID, bool keepClan = false, ZkDataContext db = null) { if (db == null) { db = new ZkDataContext(); } Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); Faction faction = acc.Faction; if (!keepClan && acc.Clan != null) { ClansController.PerformLeaveClan(Global.AccountID); } db.AccountRoles.DeleteAllOnSubmit(acc.AccountRolesByAccountID.Where(x => !keepClan || x.ClanID == null).ToList()); acc.ResetQuotas(); foreach (var ps in acc.PlanetStructures) { ps.OwnerAccountID = null; } foreach (var planet in acc.Planets) { planet.OwnerAccountID = null; } db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} leaves faction {1}", acc, acc.Faction)); db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); using (var db2 = new ZkDataContext()) { Account acc2 = db2.Accounts.Single(x => x.AccountID == Global.AccountID); acc2.FactionID = null; db2.SaveChanges(); Global.Server.PublishAccountUpdate(acc2); Global.Server.PublishUserProfileUpdate(acc2); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db2); } return(faction); }
public async Task <ActionResult> KickPlayerFromClan(int accountID) { var db = new ZkDataContext(); var kickee_acc = db.Accounts.SingleOrDefault(x => x.AccountID == accountID); if (kickee_acc == null) { return(Content("No such person")); } if (!kickee_acc.ClanID.HasValue) { return(Content(kickee_acc.Name + " not in a clan")); } int clanID = kickee_acc.ClanID.Value; if (!Global.IsModerator) { if (kickee_acc.ClanID != Global.Account.ClanID) { return(Content("Target not in your clan")); } if (!Global.Account.HasClanRight(x => x.RightKickPeople)) { return(Content("You have no kicking rights")); // unclanned people get handled here } } else { await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("{0} kicked {1} from clan {2}", Global.Account.Name, kickee_acc.Name, db.Clans.Single(x => x.ClanID == clanID).ClanName)); } PerformLeaveClan(accountID); db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator()); await Global.Server.PublishAccountUpdate(kickee_acc); return(RedirectToAction("Detail", new { id = clanID })); }
public ActionResult AcceptTreaty(int id) { var db = new ZkDataContext(); var treaty = db.FactionTreaties.Single(x => x.FactionTreatyID == id); var acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); if (!treaty.CanAccept(acc)) { return(Content("You do not have rights to accept treaties")); } // note: we don't actually need to make sure trade can be executed before storing guarantee, // because if either fails we just don't save the changes to database var isOneTimeOnly = treaty.TreatyEffects.All(x => x.TreatyEffectType.IsOneTimeOnly); if (treaty.ProcessTrade(true) == null && (isOneTimeOnly || treaty.StoreGuarantee())) { treaty.AcceptedAccountID = acc.AccountID; treaty.TreatyState = TreatyState.Accepted; db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("Treaty {0} between {1} and {2} accepted by {3}", treaty, treaty.FactionByProposingFactionID, treaty.FactionByAcceptingFactionID, acc)); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); db.SaveChanges(); if (isOneTimeOnly) { treaty.TreatyState = TreatyState.Invalid; db.SaveChanges(); } return(RedirectToAction("Detail", new { id = Global.FactionID })); } return(Content("One or both parties are unable to meet treaty conditions")); }
/// <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);*/ }
List <Faction> GetDefendingFactions(AttackOption target) { if (target.OwnerFactionID != null) { return new List <Faction> { factions.Find(x => x.FactionID == target.OwnerFactionID) } } ; return(factions.Where(x => x != AttackingFaction).ToList()); } void JoinPlanetAttack(int targetPlanetId, string userName) { AttackOption attackOption = AttackOptions.Find(x => x.PlanetID == targetPlanetId); if (attackOption != null) { User user; if (tas.ExistingUsers.TryGetValue(userName, out user)) { var db = new ZkDataContext(); Account account = Account.AccountByLobbyID(db, user.LobbyID); if (account != null && account.FactionID == AttackingFaction.FactionID && account.CanPlayerPlanetWars()) { // remove existing user from other options foreach (AttackOption aop in AttackOptions) { aop.Attackers.RemoveAll(x => x == userName); } // add user to this option if (attackOption.Attackers.Count < attackOption.TeamSize) { attackOption.Attackers.Add(user.Name); tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins attack on {1}", userName, attackOption.Name), true); if (attackOption.Attackers.Count == attackOption.TeamSize) { StartChallenge(attackOption); } else { UpdateLobby(); } } } } } } void JoinPlanetDefense(int targetPlanetID, string userName) { if (Challenge != null && Challenge.PlanetID == targetPlanetID && Challenge.Defenders.Count < Challenge.TeamSize) { User user; if (tas.ExistingUsers.TryGetValue(userName, out user)) { var db = new ZkDataContext(); Account account = Account.AccountByLobbyID(db, user.LobbyID); if (account != null && GetDefendingFactions(Challenge).Any(y => y.FactionID == account.FactionID) && account.CanPlayerPlanetWars()) { if (!Challenge.Defenders.Any(y => y == user.Name)) { Challenge.Defenders.Add(user.Name); tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins defense of {1}", userName, Challenge.Name), true); if (Challenge.Defenders.Count == Challenge.TeamSize) { AcceptChallenge(); } else { UpdateLobby(); } } } } } } void RecordPlanetwarsLoss(AttackOption option) { if (option.OwnerFactionID != null) { if (option.OwnerFactionID == missedDefenseFactionID) { missedDefenseCount++; } else { missedDefenseCount = 0; missedDefenseFactionID = option.OwnerFactionID.Value; } } var message = string.Format("{0} won because nobody tried to defend", AttackingFaction.Name); foreach (var fac in factions) { tas.Say(TasClient.SayPlace.Channel, fac.Shortcut, message, true); } var text = new StringBuilder(); try { var db = new ZkDataContext(); List <string> playerIds = option.Attackers.Select(x => x).Union(option.Defenders.Select(x => x)).ToList(); PlanetWarsTurnHandler.EndTurn(option.Map, null, db, 0, db.Accounts.Where(x => playerIds.Contains(x.Name) && x.Faction != null).ToList(), text, null, db.Accounts.Where(x => option.Attackers.Contains(x.Name) && x.Faction != null).ToList()); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.Append(ex); } } void ResetAttackOptions() { AttackOptions.Clear(); AttackerSideChangeTime = DateTime.UtcNow; Challenge = null; ChallengeTime = null; using (var db = new ZkDataContext()) { var gal = db.Galaxies.First(x => x.IsDefault); int cnt = 2; var attacker = db.Factions.Single(x => x.FactionID == AttackingFaction.FactionID); var planets = gal.Planets.Where(x => x.OwnerFactionID != AttackingFaction.FactionID).OrderByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Dropships)).ThenByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Influence)).ToList(); // list of planets by attacker's influence foreach (var planet in planets) { if (planet.CanMatchMakerPlay(attacker)) { // pick only those where you can actually attack atm InternalAddOption(planet); cnt--; } if (cnt == 0) { break; } } if (!AttackOptions.Any(y => y.TeamSize == 2)) { var planet = planets.FirstOrDefault(x => x.TeamSize == 2 && x.CanMatchMakerPlay(attacker)); if (planet != null) { InternalAddOption(planet); } } } UpdateLobby(); tas.Say(TasClient.SayPlace.Channel, AttackingFaction.Shortcut, "It's your turn! Select a planet to attack", true); } void InternalAddOption(Planet planet) { AttackOptions.Add(new AttackOption { PlanetID = planet.PlanetID, Map = planet.Resource.InternalName, OwnerFactionID = planet.OwnerFactionID, Name = planet.Name, TeamSize = planet.TeamSize, }); } void SaveStateToDb() { var db = new ZkDataContext(); Galaxy gal = db.Galaxies.First(x => x.IsDefault); gal.MatchMakerState = JsonConvert.SerializeObject((MatchMakerState)this); gal.AttackerSideCounter = AttackerSideCounter; gal.AttackerSideChangeTime = AttackerSideChangeTime; db.SubmitAndMergeChanges(); } void StartChallenge(AttackOption attackOption) { Challenge = attackOption; ChallengeTime = DateTime.UtcNow; AttackOptions.Clear(); UpdateLobby(); } void TasOnChannelUserAdded(object sender, TasEventArgs args) { string chan = args.ServerParams[0]; string userName = args.ServerParams[1]; Faction faction = factions.FirstOrDefault(x => x.Shortcut == chan); if (faction != null) { var db = new ZkDataContext(); var acc = Account.AccountByName(db, userName); if (acc != null && acc.CanPlayerPlanetWars()) { UpdateLobby(userName); } } } /// <summary> /// Intercept channel messages for attacking/defending /// </summary> /// <param name="sender"></param> /// <param name="args"></param> void TasOnPreviewSaid(object sender, CancelEventArgs <TasSayEventArgs> args) { if (args.Data.Text.StartsWith("!") && (args.Data.Place == TasSayEventArgs.Places.Channel || args.Data.Place == TasSayEventArgs.Places.Normal) && args.Data.Origin == TasSayEventArgs.Origins.Player && args.Data.UserName != GlobalConst.NightwatchName) { int targetPlanetId; if (int.TryParse(args.Data.Text.Substring(1), out targetPlanetId)) { JoinPlanet(args.Data.UserName, targetPlanetId); } } } /// <summary> /// Remove/reduce poll count due to lobby quits /// </summary> void TasOnUserRemoved(object sender, TasEventArgs args) { if (Challenge == null) { if (AttackOptions.Count > 0) { string userName = args.ServerParams[0]; int sumRemoved = 0; foreach (AttackOption aop in AttackOptions) { sumRemoved += aop.Attackers.RemoveAll(x => x == userName); } if (sumRemoved > 0) { UpdateLobby(); } } } else { string userName = args.ServerParams[0]; if (Challenge.Defenders.RemoveAll(x => x == userName) > 0) { UpdateLobby(); } } } void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { try { if (Challenge == null) { // attack timer if (DateTime.UtcNow > GetAttackDeadline()) { AttackerSideCounter++; ResetAttackOptions(); } } else { // accept timer if (DateTime.UtcNow > GetAcceptDeadline()) { if (Challenge.Defenders.Count >= Challenge.Attackers.Count - 1 && Challenge.Defenders.Count > 0) { AcceptChallenge(); } else { RecordPlanetwarsLoss(Challenge); AttackerSideCounter++; ResetAttackOptions(); } } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); } }
public static string SubmitSpringBattleResult(BattleContext context, string password, BattleResult result, List <BattlePlayerResult> players, List <string> extraData) { try { Account acc = AuthServiceClient.VerifyAccountPlain(context.AutohostName, password); if (acc == null) { throw new Exception("Account name or password not valid"); } AutohostMode mode = context.GetMode(); var db = new ZkDataContext(); if (extraData == null) { extraData = new List <string>(); } var sb = new SpringBattle { HostAccountID = acc.AccountID, Duration = result.Duration, EngineGameID = result.EngineBattleID, MapResourceID = db.Resources.Single(x => x.InternalName == result.Map).ResourceID, ModResourceID = db.Resources.Single(x => x.InternalName == result.Mod).ResourceID, HasBots = result.IsBots, IsMission = result.IsMission, PlayerCount = players.Count(x => !x.IsSpectator), StartTime = result.StartTime, Title = result.Title, ReplayFileName = result.ReplayName, EngineVersion = result.EngineVersion, }; db.SpringBattles.InsertOnSubmit(sb); foreach (BattlePlayerResult p in players) { sb.SpringBattlePlayers.Add(new SpringBattlePlayer { AccountID = db.Accounts.First(x => x.AccountID == p.LobbyID).AccountID, AllyNumber = p.AllyNumber, CommanderType = p.CommanderType, IsInVictoryTeam = p.IsVictoryTeam, IsSpectator = p.IsSpectator, LoseTime = p.LoseTime }); } db.SubmitChanges(); // awards foreach (string line in extraData.Where(x => x.StartsWith("award"))) { string[] partsSpace = line.Substring(6).Split(new[] { ' ' }, 3); string name = partsSpace[0]; string awardType = partsSpace[1]; string awardText = partsSpace[2]; SpringBattlePlayer player = sb.SpringBattlePlayers.FirstOrDefault(x => x.Account.Name == name); if (player != null) { db.AccountBattleAwards.InsertOnSubmit(new AccountBattleAward { AccountID = player.AccountID, SpringBattleID = sb.SpringBattleID, AwardKey = awardType, AwardDescription = awardText }); } } var text = new StringBuilder(); bool isPlanetwars = false; if (mode == AutohostMode.Planetwars && sb.SpringBattlePlayers.Count(x => !x.IsSpectator) >= 2 && sb.Duration >= GlobalConst.MinDurationForPlanetwars) { // test that factions are not intermingled (each faction only has one ally number) - if they are it wasnt actually PW balanced if ( sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.Account.Faction != null) .GroupBy(x => x.Account.Faction) .All(grp => grp.Select(x => x.AllyNumber).Distinct().Count() < 2)) { isPlanetwars = true; List <int> winnerTeams = sb.SpringBattlePlayers.Where(x => x.IsInVictoryTeam && !x.IsSpectator).Select(x => x.AllyNumber).Distinct().ToList(); int?winNum = null; if (winnerTeams.Count == 1) { winNum = winnerTeams[0]; if (winNum > 1) { winNum = null; text.AppendLine("ERROR: Invalid winner"); } } PlanetWarsTurnHandler.EndTurn(result.Map, extraData, db, winNum, sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account).ToList(), text, sb, sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.AllyNumber == 0).Select(x => x.Account).ToList()); Global.PlanetWarsMatchMaker.RemoveFromRunningBattles(context.AutohostName); } else { text.AppendLine("Battle wasn't PlanetWars balanced, it counts as a normal team game only"); } } bool noElo = (extraData.FirstOrDefault(x => x.StartsWith("noElo")) != null); try { db.SubmitChanges(); } catch (System.Data.Linq.DuplicateKeyException ex) { Trace.TraceError(ex.ToString()); } Dictionary <int, int> orgLevels = sb.SpringBattlePlayers.Select(x => x.Account).ToDictionary(x => x.AccountID, x => x.Level); sb.CalculateAllElo(noElo, isPlanetwars); foreach (var u in sb.SpringBattlePlayers.Where(x => !x.IsSpectator)) { u.Account.CheckLevelUp(); } db.SubmitAndMergeChanges(); try { foreach (Account a in sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account)) { Global.Server.PublishAccountUpdate(a); } } catch (Exception ex) { Trace.TraceError("error updating extension data: {0}", ex); } foreach (Account account in sb.SpringBattlePlayers.Select(x => x.Account)) { if (account.Level > orgLevels[account.AccountID]) { try { string message = string.Format("Congratulations {0}! You just leveled up to level {1}. {3}/Users/Detail/{2}", account.Name, account.Level, account.AccountID, GlobalConst.BaseSiteUrl); //text.AppendLine(message); Global.Server.GhostPm(account.Name, message); } catch (Exception ex) { Trace.TraceError("Error sending level up lobby message: {0}", ex); } } } text.AppendLine(string.Format("BATTLE DETAILS AND REPLAY ----> {1}/Battles/Detail/{0} <-----", sb.SpringBattleID, GlobalConst.BaseSiteUrl)); /* * // create debriefing room, join players there and output message * string channelName = "B" + sb.SpringBattleID; * var joinplayers = new List<string>(); * joinplayers.AddRange(context.Players.Select(x => x.Name)); // add those who were there at start * joinplayers.AddRange(sb.SpringBattlePlayers.Select(x => x.Account.Name)); // add those who played * Battle bat = Global.Server.Battles.Values.FirstOrDefault(x => x.Founder.Name == context.AutohostName); // add those in lobby atm * * * var conf = context.GetConfig(); * if (bat != null && (conf == null || conf.MinToJuggle == null)) // if not qm room do not join those who are in battle * { * List<string> inbatPlayers = bat.Users.Keys.ToList(); * joinplayers.RemoveAll(x => inbatPlayers.Contains(x)); * } * foreach (string jp in joinplayers.Distinct().Where(x => x != context.AutohostName)) tas.ForceJoinChannel(jp, channelName); * tas.JoinChannel(channelName); // join nightwatch and say it * tas.Say(SayPlace.Channel, channelName, text.ToString(), true); * tas.LeaveChannel(channelName);*/ //text.Append(string.Format("Debriefing in #{0} - zk://chat/channel/{0} ", channelName)); return(text.ToString()); } catch (Exception ex) { Trace.TraceError(ex.ToString()); return(ex.ToString()); } }
public ActionResult RunSetPlanetOwners() { using (var db = new ZkDataContext()) PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); return(Content("Done.")); }
public ActionResult BombPlanet(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 some faction first")); } Planet planet = db.Planets.Single(x => x.PlanetID == planetID); bool accessible = (useWarp == true) ? planet.CanBombersWarp(acc.Faction) : planet.CanBombersAttack(acc.Faction); if (!accessible) { return(Content("You cannot attack here")); } if (Global.Server.GetPlanetBattles(planet).Any(x => x.IsInGame)) { return(Content("Battle in progress on the planet, cannot bomb planet")); } bool selfbomb = acc.FactionID == planet.OwnerFactionID; if (count < 0) { count = 0; } double avail = Math.Min(count, acc.GetBombersAvailable()); if (useWarp == true) { avail = Math.Min(acc.GetWarpAvailable(), avail); } var capa = acc.GetBomberCapacity(); if (avail > capa) { return(Content("Too many bombers - the fleet limit is " + capa)); } if (avail > 0) { double defense = planet.PlanetStructures.Where(x => x.IsActive).Sum(x => x.StructureType.EffectBomberDefense) ?? 0; double effective = avail; if (!selfbomb) { effective = effective - defense; } if (effective <= 0) { return(Content("Enemy defenses completely block your ships")); } acc.SpendBombers(avail); if (useWarp == true) { acc.SpendWarps(avail); } var r = new Random(); double strucKillChance = !selfbomb ? effective * GlobalConst.BomberKillStructureChance : 0; int strucKillCount = (int)Math.Floor(strucKillChance + r.NextDouble()); double ipKillChance = effective * GlobalConst.BomberKillIpChance; int ipKillCount = (int)Math.Floor(ipKillChance + r.NextDouble()); List <PlanetStructure> structs = planet.PlanetStructures.Where(x => x.StructureType.IsBomberDestructible).ToList(); var bombed = new List <StructureType>(); while (structs.Count > 0 && strucKillCount > 0) { strucKillCount--; PlanetStructure s = structs[r.Next(structs.Count)]; bombed.Add(s.StructureType); structs.Remove(s); db.PlanetStructures.DeleteOnSubmit(s); } double ipKillAmmount = ipKillCount * GlobalConst.BomberKillIpAmount; if (ipKillAmmount > 0) { var influenceDecayMin = planet.PlanetStructures.Where(x => x.IsActive && x.StructureType.EffectPreventInfluenceDecayBelow != null).Select(x => x.StructureType.EffectPreventInfluenceDecayBelow).OrderByDescending(x => x).FirstOrDefault() ?? 0; foreach (PlanetFaction pf in planet.PlanetFactions.Where(x => x.FactionID != acc.FactionID)) { pf.Influence -= ipKillAmmount; if (pf.Influence < 0) { pf.Influence = 0; } // prevent bombing below influence decaymin for owner - set by active structures if (pf.FactionID == planet.OwnerFactionID && pf.Influence < influenceDecayMin) { pf.Influence = influenceDecayMin; } } } var args = new List <object> { acc, acc.Faction, !selfbomb ? planet.Faction : null, planet, avail, defense, useWarp == true ? "They attacked by warp. " : "", ipKillAmmount }; args.AddRange(bombed); string str; if (selfbomb) { str = "{0} of {1} bombed own planet {3} using {4} bombers against {5} defenses. {6}Ground armies lost {7} influence"; } else { str = "{0} of {1} bombed {2} planet {3} using {4} bombers against {5} defenses. {6}Ground armies lost {7} influence"; } if (bombed.Count > 1) { str += " and "; int counter = 8; foreach (var b in bombed) { str += "{" + counter + "}" + ", "; counter++; } str += " were destroyed."; } else if (bombed.Count == 1) { str += " and {8} was destroyed."; } else { str += "."; } db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent(str, args.ToArray())); } db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator()); return(RedirectToAction("Planet", new { id = planetID })); }