예제 #1
0
        private void BattleWithdrawAttacker(IBattleManager battle, ICombatGroup group)
        {
            ICity        city;
            ITroopObject troopObject;
            IStronghold  targetStronghold;

            if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) ||
                !gameObjectLocator.TryGetObjects(targetStrongholdId, out targetStronghold))
            {
                throw new ArgumentException();
            }

            if (group.Id != groupId)
            {
                return;
            }

            DeregisterBattleListeners(targetStronghold);

            troopObject.BeginUpdate();
            troopObject.Stub.BeginUpdate();
            troopObject.State      = GameObjectStateFactory.NormalState();
            troopObject.Stub.State = TroopState.Idle;
            troopObject.Stub.EndUpdate();
            troopObject.EndUpdate();

            StateChange(ActionState.Completed);
        }
예제 #2
0
        /// <summary>
        ///     Handles ending this action if our group has been killed
        /// </summary>
        private void BattleGroupKilled(IBattleManager battle,
                                       ICombatGroup combatGroup)
        {
            if (combatGroup.Id != groupId)
            {
                return;
            }

            ICity        city;
            ITroopObject troopObject;

            if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject))
            {
                throw new Exception();
            }

            DeregisterBattleListeners(city);

            troopObject.BeginUpdate();
            troopObject.State = GameObjectStateFactory.NormalState();
            troopObject.EndUpdate();

            troopObject.Stub.BeginUpdate();
            troopObject.Stub.State = TroopState.Idle;
            troopObject.Stub.EndUpdate();

            StateChange(ActionState.Completed);
        }
예제 #3
0
        public uint SnapGroup(uint reportId, ICombatGroup group, ReportState state, bool isAttacker)
        {
            Resource loot = group.GroupLoot;

            uint battleTroopId = (uint)BattleReport.BattleTroopIdGenerator.GetNext();

            dbManager.Query(string.Format(@"INSERT INTO `{0}` 
                                            (`id`, `battle_report_id`, `owner_type`, `owner_id`, `group_id`, `name`, `state`, `is_attacker`, `gold`, `crop`, `iron`, `wood`) VALUES
                                            (@id, @report_id, @owner_type, @owner_id, @group_id, @name, @state, @is_attacker, @gold, @crop, @iron, @wood)", BATTLE_REPORT_TROOPS_DB), new[]
            {
                new DbColumn("id", battleTroopId, DbType.UInt32), new DbColumn("report_id", reportId, DbType.UInt32),
                new DbColumn("owner_type", group.Owner.Type.ToString(), DbType.String, 15),
                new DbColumn("owner_id", group.Owner.Id, DbType.UInt32),
                new DbColumn("group_id", group.Id, DbType.UInt32),
                new DbColumn("name",
                             group.TroopId == 1 ? "[LOCAL]" : group.TroopId.ToString(CultureInfo.InvariantCulture),
                             DbType.String,
                             32),
                new DbColumn("state", state, DbType.Byte),
                new DbColumn("is_attacker", isAttacker, DbType.Boolean),
                new DbColumn("gold", loot.Gold, DbType.Int32), new DbColumn("crop", loot.Crop, DbType.Int32),
                new DbColumn("iron", loot.Iron, DbType.Int32), new DbColumn("wood", loot.Wood, DbType.Int32)
            });

            return(battleTroopId);
        }
예제 #4
0
        /// <summary>
        ///     Writes a report group
        /// </summary>
        public void WriteReportGroup(ICombatGroup group, bool isAttacker, ReportState state)
        {
            WriteBeginReport();

            if (state != ReportState.Staying)
            {
                SnappedImportantEvent = true;
            }

            // Holds the id of the group for the current battle report
            uint reportedGroupId;

            bool alreadySnapped = ReportedGroups.TryGetValue(group, out reportedGroupId);

            if (!alreadySnapped)
            {
                // Snap the group
                reportedGroupId = battleReportWriter.SnapGroup(ReportId, group, state, isAttacker);

                ReportedGroups[group] = reportedGroupId;
            }
            else if (state != ReportState.Staying)
            {
                battleReportWriter.SnapGroupState(reportedGroupId, group, state);
            }

            // Snap each object in the group
            foreach (var combatObject in group)
            {
                battleReportWriter.SnapCombatObject(reportedGroupId, combatObject);
            }
        }
예제 #5
0
        private void MainBattleOnUnitKilled(IBattleManager battle,
                                            BattleManager.BattleSide combatObjectSide,
                                            ICombatGroup combatGroup,
                                            ICombatObject combatObject,
                                            int count)
        {
            IStronghold stronghold;

            if (!gameObjectLocator.TryGetObjects(strongholdId, out stronghold))
            {
                throw new Exception("Stronghold not found");
            }

            var defensiveMeter = battle.GetProperty <decimal>("defense_stronghold_meter");
            var offensiveMeter = battle.GetProperty <decimal>("offense_stronghold_meter");

            if (combatObjectSide == BattleManager.BattleSide.Attack)
            {
                offensiveMeter -= combatObject.Stats.NormalizedCost * count;
            }
            else
            {
                defensiveMeter -= combatObject.Stats.NormalizedCost * count;
            }

            battle.SetProperty("defense_stronghold_meter", defensiveMeter);
            battle.SetProperty("offense_stronghold_meter", offensiveMeter);
        }
예제 #6
0
        private void BattleActionAttacked(IBattleManager battle,
                                          BattleManager.BattleSide attackingside,
                                          ICombatGroup attackerGroup,
                                          ICombatObject attacker,
                                          ICombatGroup targetGroup,
                                          ICombatObject target,
                                          decimal damage,
                                          int attackerCount,
                                          int targetCount)
        {
            // Check if the unit being attacked belongs to us
            if (targetGroup.Id != combatGroup.Id)
            {
                return;
            }

            // Check to see if player should retreat
            var remainingUnitCount = troopStub.TotalCount;

            // Don't return if we haven't fulfilled the minimum rounds or not below the threshold
            if (target.RoundsParticipated < Config.battle_retreat_min_rounds || remainingUnitCount == 0 ||
                remainingUnitCount > troopStub.RetreatCount)
            {
                return;
            }

            battle.Remove(combatGroup,
                          attackingside == BattleManager.BattleSide.Attack
                                  ? BattleManager.BattleSide.Defense
                                  : BattleManager.BattleSide.Attack,
                          ReportState.Retreating);
        }
예제 #7
0
        private void BattleWithdrawAttacker(IBattleManager battle, ICombatGroup group)
        {
            var packet = CreatePacket(battle, Command.BattleWithdrawAttacker);

            packet.AddUInt32(group.Id);
            channel.Post(channelName, packet);
        }
예제 #8
0
        private void BattleReinforceAttacker(IBattleManager battle, ICombatGroup combatGroup)
        {
            var packet = CreatePacket(battle, Command.BattleReinforceAttacker);

            PacketHelper.AddToPacket(combatGroup, packet);
            channel.Post(channelName, packet);
        }
예제 #9
0
        private void BattleActionAttacked(IBattleManager battle,
                                          BattleManager.BattleSide attackingside,
                                          ICombatGroup attackerGroup,
                                          ICombatObject attacker,
                                          ICombatGroup targetGroup,
                                          ICombatObject target,
                                          decimal damage,
                                          int attackerCount,
                                          int targetCount)
        {
            if (target.ClassType == BattleClass.Structure && attackingside == BattleManager.BattleSide.Attack && target.IsDead)
            {
                if (objectTypeFactory.IsObjectType("BattleNoStaminaReduction", target.Type))
                {
                    return;
                }

                if (objectTypeFactory.IsObjectType("BattleNoStaminaReductionEarlyLevels", target.Type) && target.Lvl < 5)
                {
                    return;
                }

                Stamina = BattleFormulas.GetStaminaStructureDestroyed(Stamina, target);
            }
        }
예제 #10
0
        /// <summary>
        ///     Takes care of finishing this action up if all our units are killed
        /// </summary>
        private void BattleGroupKilled(IBattleManager battle, ICombatGroup group)
        {
            // Ignore if not our group
            if (group.Id != groupId)
            {
                return;
            }

            IBarbarianTribe barbarianTribe;
            ICity           city;
            ITroopObject    troopObject;

            if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) ||
                !gameObjectLocator.TryGetObjects(targetObjectId, out barbarianTribe))
            {
                throw new ArgumentException();
            }

            DeregisterBattleListeners(barbarianTribe);

            troopObject.BeginUpdate();
            troopObject.State = GameObjectStateFactory.NormalState();
            troopObject.EndUpdate();

            StateChange(ActionState.Completed);
        }
예제 #11
0
        public AttackModeMonitor(IBattleManager battleManager, ICombatGroup combatGroup, ITroopStub troopStub)
        {
            this.troopStub   = troopStub;
            this.combatGroup = combatGroup;

            battleManager.ActionAttacked   += BattleActionAttacked;
            battleManager.WithdrawAttacker += BattleWithdrawAttacker;
        }
예제 #12
0
 private void BattleUnitKilled(IBattleManager battle,
                               BattleManager.BattleSide objSide,
                               ICombatGroup combatGroup,
                               ICombatObject obj)
 {
     Append("**************Removing****************");
     PrintCombatobject(obj);
 }
예제 #13
0
 public void AddAccess(ICombatGroup group, BattleManager.BattleSide battleSide)
 {
     battleReportWriter.SnapBattleAccess(battle.BattleId,
                                         group.Owner,
                                         group.TroopId,
                                         group.Id,
                                         battleSide == BattleManager.BattleSide.Attack);
 }
예제 #14
0
 private void BattleSkippedAttacker(IBattleManager battle,
                                    BattleManager.BattleSide objSide,
                                    ICombatGroup combatGroup,
                                    ICombatObject obj)
 {
     Append("***************Skipping***************");
     PrintCombatobject(obj);
     Append("**************************************\n");
 }
예제 #15
0
        private bool NextObjectFromList(uint round,
                                        IList <ICombatGroup> combatGroups,
                                        out ICombatObject outObj,
                                        out ICombatGroup outGroup)
        {
            if (combatGroups.Count == 0)
            {
                outGroup = null;
                outObj   = null;
                return(false);
            }

            int startGroupIdx = random.Next(combatGroups.Count);

            // Find any objects that are still in the current round
            for (var combatGroupIdx = 0; combatGroupIdx < combatGroups.Count; combatGroupIdx++)
            {
                var combatGroup = combatGroups[(startGroupIdx + combatGroupIdx) % combatGroups.Count];

                int startObjIdx = random.Next(combatGroup.Count);

                for (var combatObjIdx = 0; combatObjIdx < combatGroup.Count; combatObjIdx++)
                {
                    outObj = combatGroup[(startObjIdx + combatObjIdx) % combatGroup.Count];

                    if (outObj.IsWaitingToJoinBattle || outObj.HasAttacked(round))
                    {
                        continue;
                    }

                    // We've found an object thats still in the current round
                    // so we're done
                    outGroup = combatGroup;
                    return(true);
                }
            }

            // No object in the current round, get a random object from the group we got above
            // We loop incase the group is empty then it continues onto the next one
            for (var combatGroupIdx = 0; combatGroupIdx < combatGroups.Count; combatGroupIdx++)
            {
                var combatGroup = combatGroups[(startGroupIdx + combatGroupIdx) % combatGroups.Count];

                if (combatGroup.Count == 0)
                {
                    continue;
                }

                outGroup = combatGroup;
                outObj   = combatGroup[random.Next(combatGroup.Count)];
                return(false);
            }

            outGroup = null;
            outObj   = null;
            return(false);
        }
예제 #16
0
        private void BattleWithdrawAttacker(IBattleManager battle, ICombatGroup groupWithdrawn)
        {
            if (groupWithdrawn != combatGroup)
            {
                return;
            }

            battle.ActionAttacked   -= BattleActionAttacked;
            battle.WithdrawAttacker -= BattleWithdrawAttacker;
        }
예제 #17
0
        private void BattleManagerOnGroupUnitRemoved(IBattleManager battle,
                                                     BattleManager.BattleSide combatObjectSide,
                                                     ICombatGroup combatGroup,
                                                     ICombatObject combatObject)
        {
            var packet = CreatePacket(battle, Command.BattleGroupUnitRemoved);

            packet.AddUInt32(combatGroup.Id);
            packet.AddUInt32(combatObject.Id);
            channel.Post(channelName, packet);
        }
예제 #18
0
        private void BattleWithdrawAttacker(IBattleManager battle, ICombatGroup groupWithdrawn)
        {
            if (groupWithdrawn != CombatGroup)
            {
                return;
            }

            battle.ActionAttacked   -= BattleActionAttacked;
            battle.WithdrawAttacker -= BattleWithdrawAttacker;
            battle.EnterRound       -= BattleEnterRound;
            battle.ExitTurn         -= BattleExitTurn;
        }
예제 #19
0
        public void Add(ICombatGroup combatGroup, BattleSide battleSide, bool allowReportAccess)
        {
            bool isAttacker = battleSide == BattleSide.Attack;

            lock (battleLock)
            {
                if (GetCombatGroup(combatGroup.Id) != null)
                {
                    throw new Exception(
                              string.Format("Trying to add a group to battle {0} with id {1} that already exists",
                                            BattleId,
                                            combatGroup.Id));
                }

                (battleSide == BattleSide.Attack ? Attackers : Defenders).Add(combatGroup);

                if (isAttacker)
                {
                    combatGroup.CombatObjectAdded   += AttackerGroupOnCombatObjectAdded;
                    combatGroup.CombatObjectRemoved += AttackerGroupOnCombatObjectRemoved;
                }
                else
                {
                    combatGroup.CombatObjectAdded   += DefenderGroupOnCombatObjectAdded;
                    combatGroup.CombatObjectRemoved += DefenderGroupOnCombatObjectRemoved;
                }

                if (BattleStarted)
                {
                    BattleReport.WriteReportGroup(combatGroup, isAttacker, ReportState.Entering);

                    if (isAttacker)
                    {
                        ReinforceAttacker(this, combatGroup);
                    }
                    else
                    {
                        ReinforceDefender(this, combatGroup);
                    }
                }

                if (allowReportAccess)
                {
                    BattleReport.AddAccess(combatGroup, battleSide);
                }

                if (combatGroup.Tribe != null)
                {
                    BattleReport.AddTribeToBattle(combatGroup.Tribe, battleSide);
                }
            }
        }
예제 #20
0
        public void Remove(ICombatGroup group, BattleSide side, ReportState state)
        {
            lock (battleLock)
            {
                // Remove from appropriate combat list
                if (side == BattleSide.Attack)
                {
                    if (!Attackers.Remove(group))
                    {
                        return;
                    }

                    group.CombatObjectAdded   -= AttackerGroupOnCombatObjectAdded;
                    group.CombatObjectRemoved -= AttackerGroupOnCombatObjectRemoved;
                }
                else
                {
                    if (!Defenders.Remove(group))
                    {
                        return;
                    }

                    group.CombatObjectAdded   -= DefenderGroupOnCombatObjectAdded;
                    group.CombatObjectRemoved -= DefenderGroupOnCombatObjectRemoved;
                }

                // If battle hasnt started then dont worry about cleaning anything up since nothing has happened to these objects
                if (!BattleStarted)
                {
                    return;
                }

                // Snap a report of exit
                BattleReport.WriteReportGroup(group, side == BattleSide.Attack, state);

                // Tell objects to exit from battle
                foreach (var co in group.Where(co => !co.Disposed))
                {
                    co.ExitBattle();
                }

                // Send exit events
                if (side == BattleSide.Attack)
                {
                    WithdrawAttacker(this, group);
                }
                else
                {
                    WithdrawDefender(this, group);
                }
            }
        }
예제 #21
0
        public void DbLoaderAddToCombatList(ICombatGroup group, BattleSide side)
        {
            if (side == BattleSide.Defense)
            {
                Defenders.Add(group, false);
            }
            else
            {
                Attackers.Add(group, false);
            }

            groupIdGen.Set(group.Id);
        }
예제 #22
0
 private void BmUnitRemoved2(IBattleManager battle,
                             BattleManager.BattleSide objSide,
                             ICombatGroup group,
                             ICombatObject obj)
 {
     deadObject = obj;
     if (obj is AttackCombatUnit)
     {
         if (sw != null)
         {
             WriteResult(obj);
         }
     }
 }
예제 #23
0
        /// <summary>
        ///     Gives alignment points when a structure is destroyed.
        /// </summary>
        private void BattleUnitKilled(IBattleManager battle,
                                      BattleManager.BattleSide objSide,
                                      ICombatGroup combatGroup,
                                      ICombatObject obj)
        {
            // Keep track of our buildings destroyed HP
            if (objSide != BattleManager.BattleSide.Defense || obj.ClassType != BattleClass.Structure)
            {
                return;
            }

            destroyedHp += (uint)obj.Stats.MaxHp;
            AddAlignmentPoint(battle.Attackers, battle.Defenders, Config.battle_stamina_destroyed_deduction);
        }
예제 #24
0
 private void BattleUnitKilled(IBattleManager battle,
                               BattleManager.BattleSide objSide,
                               ICombatGroup group,
                               ICombatObject obj)
 {
     deadObject = obj;
     if (obj is DefenseCombatUnit)
     {
         if (sw != null)
         {
             WriteResult(obj);
         }
     }
 }
예제 #25
0
        internal static void AddToPacket(ICombatGroup combatGroup, Packet packet)
        {
            packet.AddUInt32(combatGroup.Id);
            packet.AddUInt16(combatGroup.TroopId);
            packet.AddByte((byte)combatGroup.Owner.Type);
            packet.AddUInt32(combatGroup.Owner.Id);
            packet.AddString(combatGroup.Owner.GetName());

            packet.AddInt32(combatGroup.Count);
            foreach (var combatObject in combatGroup)
            {
                AddToPacket(combatObject, packet);
            }
        }
예제 #26
0
 private void BattleActionAttacked(IBattleManager battle,
                                   BattleManager.BattleSide attackingSide,
                                   ICombatGroup attackerGroup,
                                   ICombatObject source,
                                   ICombatGroup defenderGroup,
                                   ICombatObject target,
                                   decimal damage,
                                   int attackerCount,
                                   int targetCount)
 {
     Append("*************Attacking****************");
     PrintCombatobject(source);
     PrintCombatobject(target);
     //Append("**************************************\n");
 }
예제 #27
0
        public virtual void JoinOrCreateCityBattle(ICity targetCity,
                                                   ITroopObject attackerTroopObject,
                                                   IDbManager dbManager,
                                                   out ICombatGroup combatGroup,
                                                   out uint battleId)
        {
            // If battle already exists, then we just join it in also bringing any new units
            if (targetCity.Battle != null)
            {
                AddLocalUnitsToBattle(targetCity.Battle, targetCity);
                AddLocalStructuresToBattle(targetCity.Battle, targetCity, attackerTroopObject);
                combatGroup = battleProcedure.AddAttackerToBattle(targetCity.Battle, attackerTroopObject);
            }
            // Otherwise, the battle has to be created
            else
            {
                targetCity.Battle = battleManagerFactory.CreateBattleManager(new BattleLocation(BattleLocationType.City, targetCity.Id),
                                                                             new BattleOwner(BattleOwnerType.City, targetCity.Id),
                                                                             targetCity);

                var battlePassiveAction = actionFactory.CreateCityBattlePassiveAction(targetCity.Id);

                AddLocalStructuresToBattle(targetCity.Battle, targetCity, attackerTroopObject);
                combatGroup = battleProcedure.AddAttackerToBattle(targetCity.Battle, attackerTroopObject);

                Error result = targetCity.Worker.DoPassive(targetCity, battlePassiveAction, false);
                if (result != Error.Ok)
                {
                    throw new Exception(string.Format("Failed to start a battle due to error {0}", result));
                }

                // send message to player telling them to build tower and basement
                if (targetCity.Owner.NeverAttacked)
                {
                    const string warnMessage =
                        @"Now that you are out of newbie protection, other players are able to attack you. Someone has just finished attacking your town and has probably taken some resources from you. You can see how strong the attack was and how much resources they took in the battle report that was generated for this battle. 
You have several things you can do to help protect your city from attacks. The first is to build a basement which can be done from your lumbermill. Basements will protect up to a certain amount of resources from being looted. If you plan on going offline for a while, your basements can also build temporary basements which will extend the amount of protected resources. 
Another option is increase your city's defenses. The best way to do this early in the game is to build some towers. Towers are built from the training ground or barrack and provide defense for structures within its radius. Any units in your city will also join the battle but be careful since an attacker may kill your entire army in a battle. You can hide your units if you don't want them to defend your town when you get attacked.
Good luck and feel free to ask for help in the chat if you have any questions.";

                    targetCity.Owner.SendSystemMessage(null, "Your city has been attacked", warnMessage);
                    targetCity.Owner.NeverAttacked = false;
                    dbManager.Save(targetCity.Owner);
                }
            }

            battleId = targetCity.Battle.BattleId;
        }
예제 #28
0
        /// <summary>
        ///     Writes an object that is leaving the battle without reporting on the other objects in the group
        /// </summary>
        public void WriteExitingObject(ICombatGroup group, bool isAttacker, ICombatObject combatObject)
        {
            WriteBeginReport();

            uint reportedGroupId;

            bool alreadySnapped = ReportedGroups.TryGetValue(group, out reportedGroupId);

            if (!alreadySnapped)
            {
                reportedGroupId       = battleReportWriter.SnapGroup(ReportId, group, ReportState.Staying, isAttacker);
                ReportedGroups[group] = reportedGroupId;
            }

            battleReportWriter.SnapCombatObject(reportedGroupId, combatObject);
        }
예제 #29
0
        public StaminaMonitor(IBattleManager battleManager,
                              ICombatGroup combatGroup,
                              short initialStamina,
                              IBattleFormulas battleFormulas,
                              IObjectTypeFactory objectTypeFactory)
        {
            this.objectTypeFactory = objectTypeFactory;
            CombatGroup            = combatGroup;
            Stamina        = initialStamina;
            BattleFormulas = battleFormulas;

            battleManager.ActionAttacked   += BattleActionAttacked;
            battleManager.WithdrawAttacker += BattleWithdrawAttacker;
            battleManager.EnterRound       += BattleEnterRound;
            battleManager.ExitTurn         += BattleExitTurn;
        }
예제 #30
0
        private void BattleSkippedAttacker(IBattleManager battle,
                                           BattleManager.BattleSide objSide,
                                           ICombatGroup combatGroup,
                                           ICombatObject source)
        {
            // Don't inform client for objs that simply never attack
            if (source.Stats.Atk == 0)
            {
                return;
            }

            var packet = CreatePacket(battle, Command.BattleSkipped);

            packet.AddUInt32(combatGroup.Id);
            packet.AddUInt32(source.Id);
            channel.Post(channelName, packet);
        }