public BattleReportResponse(Cache cache, BattleReport report, bool victory)
     : base(true)
 {
     Cache = cache;
     BattleReport = report;
     IsVictory = victory;
 }
Esempio n. 2
0
        public Response Attack(Player attacker, int units)
        {
            if (!HasOwner) {
                throw new Exception("Can't attack a cache with no owner");
            }

            double weight = 0.4 + Math.Min((units - Balance) / (double) Balance, 2.0) * 0.05;

            NonPlayerCache npc = null;
            NPCInstance instance = null;
            if (IsNPC) {
                npc = DatabaseManager.SelectFirst<NonPlayerCache>(x => x.CacheID == CacheID);
                instance = NPCInstance.GetInstance(CacheID, attacker.AccountID);

                if (instance.NextAttack > DateTime.Now) {
                    return new ErrorResponse("the camp is still in ruins");
                }
            }

            int balance = IsNPC
                    ? NonPlayerCache.FindNextGarrisonSize(Balance, instance.Attacks, npc.GrowthStyle)
                    : Balance;

            var report = new BattleReport (AccountID) {
                CacheID = CacheID,
                AttackerID = attacker.AccountID,
                AttackerInitial = units,
                AttackerSurvivors = units,
                DefenderInitial = balance,
                DefenderSurvivors = balance
            };

            attacker.Balance -= report.AttackerInitial;

            while (report.AttackerSurvivors > 0 && report.DefenderSurvivors > 0) {
                if (Tools.CoinToss(weight)) {
                    --report.DefenderSurvivors;
                } else {
                    --report.AttackerSurvivors;
                }
            }

            report.AttackerFatalities = report.AttackerInitial - report.AttackerSurvivors;
            report.DefenderFatalities = report.DefenderInitial - report.DefenderSurvivors;

            if (report.AttackerSurvivors > 0) {
                report.AttackerDeserters = 0;
                if (!IsNPC) {
                    report.DefenderDeserters = (int) (report.DefenderFatalities * (Tools.Random() * 0.1 + 0.1));
                    Balance = report.AttackerSurvivors + report.DefenderDeserters;
                    AccountID = attacker.AccountID;
                    DatabaseManager.Delete<Event>(x => x.Type == EventType.CacheAttacked && x.ContextID == CacheID);
                } else {
                    report.DefenderDeserters = report.DefenderInitial / 2 + report.AttackerFatalities;
                    attacker.Balance += report.DefenderDeserters + report.AttackerSurvivors;
                    ++instance.Attacks;
                    instance.NextAttack = DateTime.Now.AddSeconds(NonPlayerCache.FindNextAttackDelay(Balance, instance.Attacks, npc.GrowthStyle));
                    DatabaseManager.Update(instance);
                }
            } else {
                report.DefenderDeserters = 0;
                report.AttackerDeserters = (int) (report.AttackerFatalities * (Tools.Random() * 0.1 + 0.05));

                if (!IsNPC) {
                    Balance = report.DefenderSurvivors;
                    var defender = DatabaseManager.SelectFirst<Player>(x => x.AccountID == this.AccountID);
                    defender.Balance += report.AttackerDeserters;
                    DatabaseManager.Update(defender);
                }
            }

            DatabaseManager.Insert(report);
            report = DatabaseManager.Select<BattleReport>(x => x.CacheID == report.CacheID && x.AttackerID == report.AttackerID).Last();

            DatabaseManager.Insert(new Event(EventType.AttackCache, attacker.AccountID, report.NotificationID));

            if (!IsNPC) {
                DatabaseManager.Update(this);
                DatabaseManager.Insert(new Event(EventType.CacheAttacked, CacheID, report.NotificationID));
            }

            DatabaseManager.Update(attacker);

            return new BattleReportResponse(this, report, report.AttackerSurvivors > 0);
        }