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);
        }
Exemple #2
0
        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 }));
        }
Exemple #3
0
        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 }));
        }
Exemple #4
0
        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 }));
        }
Exemple #5
0
        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 }));
        }
Exemple #7
0
        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 }));
        }
Exemple #8
0
        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 }));
        }
Exemple #10
0
        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);*/
    }
Exemple #12
0
        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());
            }
        }
Exemple #13
0
        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());
            }
        }
Exemple #14
0
 public ActionResult RunSetPlanetOwners()
 {
     using (var db = new ZkDataContext()) PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db);
     return(Content("Done."));
 }
Exemple #15
0
        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 }));
        }