Exemple #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);
        }
Exemple #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);
        }
Exemple #3
0
        public override void ExitBattle()
        {
            base.ExitBattle();

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

            // Remove structure from the world if our combat object died
            if (hp > 0)
            {
                return;
            }

            ICity city = Structure.City;

            var lockedRegions = regionManager.LockMultitileRegions(Structure.PrimaryPosition.X, Structure.PrimaryPosition.Y, Structure.Size);

            if (Structure.Lvl > 1)
            {
                Structure.City.Worker.DoPassive(Structure.City,
                                                actionFactory.CreateStructureDowngradePassiveAction(Structure.City.Id,
                                                                                                    Structure.ObjectId),
                                                false);
            }
            else
            {
                Structure.BeginUpdate();
                regionManager.Remove(Structure);
                city.ScheduleRemove(Structure, true);
                Structure.EndUpdate();
            }
            regionManager.UnlockRegions(lockedRegions);
        }
Exemple #4
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);
        }
Exemple #5
0
        public void SenseOfUrgency_WhenCityHasMultipleSenseOfUrgencyTechnologies_ShouldStackUpTo100Percent(
            ICity city,
            IStructure structure,
            BattleProcedure battleProcedure)
        {
            structure.State = GameObjectStateFactory.NormalState();
            structure.Stats.Hp.Returns(50m);
            structure.Stats.Base.Battle.MaxHp.Returns(200m);

            city.GetEnumerator().Returns(x =>
                                         new List <IStructure> {
                structure
            }.GetEnumerator());
            city.Technologies.GetEffects(EffectCode.SenseOfUrgency).Returns(new List <Effect>
            {
                new Effect {
                    Id = EffectCode.SenseOfUrgency, Value = new object[] { 50 }
                },
                new Effect {
                    Id = EffectCode.SenseOfUrgency, Value = new object[] { 25 }
                },
                new Effect {
                    Id = EffectCode.SenseOfUrgency, Value = new object[] { 50 }
                }
            });

            battleProcedure.SenseOfUrgency(city, 50);

            structure.Stats.Hp.Should().Be(100m);
        }
Exemple #6
0
        public override Error Execute()
        {
            ICity city;

            ITroopObject troopObject;

            if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject))
            {
                return(Error.ObjectNotFound);
            }

            if (city.Battle == null)
            {
                StateChange(ActionState.Completed);
                return(Error.Ok);
            }

            RegisterBattleListeners(city);

            troopObject.BeginUpdate();
            troopObject.State = GameObjectStateFactory.BattleState(city.Battle.BattleId);
            troopObject.EndUpdate();
            troopObject.Stub.BeginUpdate();
            troopObject.Stub.State = TroopState.Battle;
            troopObject.Stub.EndUpdate();

            // Add units to battle
            groupId = battleProcedure.AddReinforcementToBattle(city.Battle, troopObject.Stub, formationType);
            cityBattleProcedure.AddLocalUnitsToBattle(city.Battle, city);

            return(Error.Ok);
        }
Exemple #7
0
        public override Error Execute()
        {
            IStronghold stronghold;

            if (!gameObjectLocator.TryGetObjects(strongholdId, out stronghold))
            {
                return(Error.ObjectNotFound);
            }

            world.Add(stronghold.GateBattle);
            dbManager.Save(stronghold.GateBattle);

            //Add gate to battle
            var combatGroup = strongholdBattleProcedure.AddStrongholdGateToBattle(stronghold.GateBattle, stronghold);

            localGroupId = combatGroup.Id;

            stronghold.BeginUpdate();
            stronghold.State = GameObjectStateFactory.BattleState(stronghold.GateBattle.BattleId);
            stronghold.EndUpdate();

            beginTime = SystemClock.Now;
            endTime   = SystemClock.Now.Add(formula.GetBattleDelayStartInterval());

            return(Error.Ok);
        }
Exemple #8
0
        public override void Callback(object custom)
        {
            IBarbarianTribe barbarianTribe;

            if (!gameObjectLocator.TryGetObjects(barbarianTribeId, out barbarianTribe))
            {
                throw new Exception("Barb tribe is missing");
            }

            CallbackLock.CallbackLockHandler lockHandler = delegate
            {
                var toBeLocked = new List <ILockable>();
                toBeLocked.AddRange(barbarianTribe.Battle.LockList);
                toBeLocked.Add(barbarianTribe);
                return(toBeLocked.ToArray());
            };

            locker.Lock(lockHandler, null, barbarianTribe).Do(() =>
            {
                if (barbarianTribe.Battle.ExecuteTurn())
                {
                    // Battle continues, just save it and reschedule
                    dbManager.Save(barbarianTribe.Battle);
                    endTime = SystemClock.Now.AddSeconds(formula.GetBattleInterval(barbarianTribe.Battle.Defenders, barbarianTribe.Battle.Attackers));
                    StateChange(ActionState.Fired);
                    return;
                }

                // Battle has ended
                // Delete the battle
                world.Remove(barbarianTribe.Battle);
                dbManager.Delete(barbarianTribe.Battle);

                barbarianTribe.BeginUpdate();
                barbarianTribe.Battle = null;
                barbarianTribe.State  = GameObjectStateFactory.NormalState();

                var initialBarbResources = formula.BarbarianTribeResources(barbarianTribe);
                if (!initialBarbResources.Equals(barbarianTribe.Resource))
                {
                    // Lower camps remaining
                    barbarianTribe.CampRemains--;

                    // Reset resources
                    barbarianTribe.Resource.Clear();
                    barbarianTribe.Resource.Add(formula.BarbarianTribeResources(barbarianTribe));
                }

                barbarianTribe.EndUpdate();

                StateChange(ActionState.Completed);
            });
        }
Exemple #9
0
        public override Error Execute()
        {
            ICity        city;
            ITroopObject troopObj;

            if (!world.TryGetObjects(cityId, troopObjectId, out city, out troopObj))
            {
                return(Error.ObjectNotFound);
            }

            distanceRemaining = Math.Max(1, tileLocator.TileDistance(troopObj.PrimaryPosition, troopObj.Size, new Position(x, y), 1));

            double moveTimeTotal = formula.MoveTimeTotal(troopObj.Stub, distanceRemaining, isAttacking);

            var actionConfigTime = ActionConfigTime();

            if (actionConfigTime != null)
            {
                moveTime = actionConfigTime.Value;
            }
            else
            {
                moveTime = moveTimeTotal / distanceRemaining;
            }

            beginTime = DateTime.UtcNow;
            endTime   = DateTime.UtcNow.AddSeconds(moveTimeTotal);
            nextTime  = DateTime.UtcNow.AddSeconds(moveTime);

            troopObj.Stub.BeginUpdate();
            troopObj.Stub.State = !isReturningHome ? TroopState.Moving : TroopState.ReturningHome;

            if (!CalculateNextPosition(troopObj))
            {
                troopObj.Stub.State = TroopState.Idle;
                StateChange(ActionState.Completed);
                troopObj.Stub.EndUpdate();
                return(Error.Ok);
            }
            troopObj.Stub.EndUpdate();

            troopObj.BeginUpdate();
            troopObj.TargetX = x;
            troopObj.TargetY = y;
            troopObj.State   = GameObjectStateFactory.MovingState();
            troopObj.EndUpdate();

            return(Error.Ok);
        }
Exemple #10
0
        protected virtual void AddLocalStructuresToBattle(IBattleManager battleManager,
                                                          ICity targetCity,
                                                          ITroopObject attackerTroopObject)
        {
            var localGroup = GetOrCreateLocalGroup(targetCity.Battle, targetCity);

            foreach (IStructure structure in GetStructuresInRadius(targetCity, attackerTroopObject)
                     .Where(structure => structure.State.Type == ObjectState.Normal && CanStructureBeAttacked(structure) == Error.Ok))
            {
                structure.BeginUpdate();
                structure.State = GameObjectStateFactory.BattleState(battleManager.BattleId);
                structure.EndUpdate();

                localGroup.Add(combatUnitFactory.CreateStructureCombatUnit(battleManager, structure));
            }
        }
Exemple #11
0
        public override Error Execute()
        {
            ICity        city;
            ICity        targetCity;
            ITroopObject troopObject;

            if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) ||
                !gameObjectLocator.TryGetObjects(targetCityId, out targetCity))
            {
                return(Error.ObjectNotFound);
            }

            // Save original unit count to know when to bail out of battle
            originalUnitCount = troopObject.Stub.TotalCount;

            // Create the group in the battle
            uint         battleId;
            ICombatGroup combatGroup;

            cityBattleProcedure.JoinOrCreateCityBattle(targetCity, troopObject, dbManager, out combatGroup, out battleId);
            groupId = combatGroup.Id;

            // Register the battle listeners
            RegisterBattleListeners(targetCity);

            // Create stamina monitor
            StaminaMonitor = staminaMonitorFactory.CreateStaminaMonitor(targetCity.Battle,
                                                                        combatGroup,
                                                                        battleFormula.GetStamina(troopObject.Stub, targetCity));
            StaminaMonitor.PropertyChanged += (sender, args) => dbManager.Save(this);

            // Create attack mode monitor
            AttackModeMonitor = new AttackModeMonitor(targetCity.Battle, combatGroup, troopObject.Stub);

            // Set the attacking troop object to the correct state and stamina
            troopObject.BeginUpdate();
            troopObject.State = GameObjectStateFactory.BattleState(battleId);
            troopObject.EndUpdate();

            // Set the troop stub to the correct state
            troopObject.Stub.BeginUpdate();
            troopObject.Stub.State = TroopState.Battle;
            troopObject.Stub.EndUpdate();

            return(Error.Ok);
        }
Exemple #12
0
        public void SenseOfUrgency_WhenCityHasNoSenseOfUrgencyTechnologies_HealsHurtStructuresThatArentInBattle(
            ICity city,
            IStructure inBattleStructure,
            IStructure fullyHealedStructure,
            IStructure hurtStructure,
            BattleProcedure battleProcedure)
        {
            inBattleStructure.State = GameObjectStateFactory.BattleState(0);
            inBattleStructure.Stats.Hp.Returns(50m);
            inBattleStructure.Stats.Base.Battle.MaxHp.Returns(100m);

            fullyHealedStructure.State = GameObjectStateFactory.NormalState();
            fullyHealedStructure.Stats.Hp.Returns(75m);
            fullyHealedStructure.Stats.Base.Battle.MaxHp.Returns(75m);

            hurtStructure.State = GameObjectStateFactory.NormalState();
            hurtStructure.Stats.Hp.Returns(100m);
            hurtStructure.Stats.Base.Battle.MaxHp.Returns(200m);

            city.GetEnumerator().Returns(x =>
                                         new List <IStructure> {
                inBattleStructure, fullyHealedStructure, hurtStructure
            }.GetEnumerator());
            city.Technologies.GetEffects(EffectCode.SenseOfUrgency).Returns(new List <Effect>
            {
                new Effect {
                    Id = EffectCode.SenseOfUrgency, Value = new object[] { 50 }
                }
            });

            battleProcedure.SenseOfUrgency(city, 50);

            inBattleStructure.Stats.Hp.Should().Be(50m);
            hurtStructure.Stats.Hp.Should().Be(125m);
            fullyHealedStructure.Stats.Hp.Should().Be(75m);

            hurtStructure.Received(1).BeginUpdate();
            hurtStructure.Received(1).EndUpdate();

            fullyHealedStructure.Received(0).BeginUpdate();
            fullyHealedStructure.Received(0).EndUpdate();

            inBattleStructure.Received(0).BeginUpdate();
            inBattleStructure.Received(0).EndUpdate();
        }
Exemple #13
0
        public override void Callback(object custom)
        {
            IStronghold stronghold;

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

            CallbackLock.CallbackLockHandler lockHandler = delegate { return(stronghold.LockList().ToArray()); };

            locker.Lock(lockHandler, null, stronghold).Do(() =>
            {
                if (stronghold.GateBattle.ExecuteTurn())
                {
                    // Battle continues, just save it and reschedule
                    dbManager.Save(stronghold.GateBattle);
                    endTime = SystemClock.Now.AddSeconds(formula.GetGateBattleInterval(stronghold));
                    StateChange(ActionState.Fired);
                    return;
                }

                // Battle has ended
                // Delete the battle
                stronghold.GateBattle.GroupKilled    -= BattleOnGroupKilled;
                stronghold.GateBattle.ActionAttacked -= BattleOnActionAttacked;

                world.Remove(stronghold.GateBattle);
                dbManager.Delete(stronghold.GateBattle);
                stronghold.BeginUpdate();
                stronghold.GateBattle = null;
                stronghold.State      = GameObjectStateFactory.NormalState();
                // Heal the gate if no one made through otherwise we let it be healed after the main battle
                if (stronghold.GateOpenTo == null)
                {
                    stronghold.GateMax = (int)formula.StrongholdGateLimit(stronghold.Lvl);
                    stronghold.Gate    = Math.Max(Math.Min(stronghold.GateMax, stronghold.Gate), formula.StrongholdGateHealHp(stronghold.StrongholdState, stronghold.Lvl));
                }
                stronghold.EndUpdate();

                StateChange(ActionState.Completed);
            });
        }
Exemple #14
0
        public override Error Execute()
        {
            ICity        city;
            ITroopObject troopObject;
            IStronghold  targetStronghold;

            if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) ||
                !gameObjectLocator.TryGetObjects(targetStrongholdId, out targetStronghold))
            {
                return(Error.ObjectNotFound);
            }

            // Create the group in the battle
            uint         battleId;
            ICombatGroup combatGroup;

            strongholdBattleProcedure.JoinOrCreateStrongholdGateBattle(targetStronghold,
                                                                       troopObject,
                                                                       out combatGroup,
                                                                       out battleId);
            groupId = combatGroup.Id;

            // Register the battle listeners
            RegisterBattleListeners(targetStronghold);

            // Create stamina monitor
            StaminaMonitor = staminaMonitorFactory.CreateStaminaMonitor(targetStronghold.GateBattle,
                                                                        combatGroup,
                                                                        battleFormula.GetStamina(troopObject.Stub, targetStronghold));
            StaminaMonitor.PropertyChanged += (sender, args) => dbManager.Save(this);

            // Set the attacking troop object to the correct state and stamina
            troopObject.BeginUpdate();
            troopObject.State = GameObjectStateFactory.BattleState(battleId);
            troopObject.EndUpdate();

            // Set the troop stub to the correct state
            troopObject.Stub.BeginUpdate();
            troopObject.Stub.State = TroopState.Battle;
            troopObject.Stub.EndUpdate();

            return(Error.Ok);
        }
Exemple #15
0
        public override Error Execute()
        {
            IStronghold stronghold;

            if (!gameObjectLocator.TryGetObjects(strongholdId, out stronghold))
            {
                return(Error.ObjectNotFound);
            }

            world.Add(stronghold.MainBattle);
            dbManager.Save(stronghold.MainBattle);

            if (stronghold.StrongholdState == StrongholdState.Occupied)
            {
                // Add stationed to battle
                foreach (var stub in stronghold.Troops.StationedHere())
                {
                    stub.BeginUpdate();
                    stub.State = TroopState.BattleStationed;
                    stub.EndUpdate();

                    battleProcedure.AddReinforcementToBattle(stronghold.MainBattle, stub, FormationType.Defense);
                }
            }
            else
            {
                var strongholdGroup = strongholdBattleProcedure.AddStrongholdUnitsToBattle(stronghold.MainBattle,
                                                                                           stronghold,
                                                                                           strongholdManager.GenerateNeutralStub(stronghold));

                npcGroupId = strongholdGroup.Id;
            }

            stronghold.BeginUpdate();
            stronghold.State = GameObjectStateFactory.BattleState(stronghold.MainBattle.BattleId);
            stronghold.EndUpdate();

            beginTime = SystemClock.Now;
            endTime   = SystemClock.Now.Add(formula.GetBattleDelayStartInterval());

            return(Error.Ok);
        }
Exemple #16
0
        public override Error Execute()
        {
            ICity        city;
            ITroopObject troopObject;
            IStronghold  targetStronghold;

            if (!gameObjectLocator.TryGetObjects(cityId, troopObjectId, out city, out troopObject) ||
                !gameObjectLocator.TryGetObjects(targetStrongholdId, out targetStronghold))
            {
                return(Error.ObjectNotFound);
            }

            // Create the group in the battle
            uint         battleId;
            ICombatGroup combatGroup;

            strongholdBattleProcedure.JoinOrCreateStrongholdMainBattle(targetStronghold,
                                                                       troopObject,
                                                                       out combatGroup,
                                                                       out battleId);
            groupId = combatGroup.Id;

            // Create attack mode monitor
            originalUnitCount = troopObject.Stub.TotalCount;
            AttackModeMonitor = new AttackModeMonitor(targetStronghold.MainBattle, combatGroup, troopObject.Stub);

            // Register the battle listeners
            RegisterBattleListeners(targetStronghold);

            // Set the attacking troop object to the correct state and stamina
            troopObject.BeginUpdate();
            troopObject.State = GameObjectStateFactory.BattleState(battleId);
            troopObject.EndUpdate();

            // Set the troop stub to the correct state
            troopObject.Stub.BeginUpdate();
            troopObject.Stub.State = TroopState.Battle;
            troopObject.Stub.EndUpdate();

            return(Error.Ok);
        }
Exemple #17
0
        public override void Callback(object custom)
        {
            ICity        city;
            ITroopObject troopObj;

            locker.Lock(cityId, troopObjectId, out city, out troopObj).Do(() =>
            {
                if (!IsValid())
                {
                    return;
                }

                --distanceRemaining;

                troopObj.BeginUpdate();
                troopObj.Move(new Position(nextX, nextY));
                troopObj.EndUpdate();

                // Fire updated to force sending new position
                troopObj.Stub.BeginUpdate();
                troopObj.Stub.FireUpdated();
                troopObj.Stub.EndUpdate();

                if (!CalculateNextPosition(troopObj))
                {
                    troopObj.Stub.BeginUpdate();
                    troopObj.Stub.State = TroopState.Idle;
                    troopObj.Stub.EndUpdate();

                    troopObj.BeginUpdate();
                    troopObj.State = GameObjectStateFactory.NormalState();
                    troopObj.EndUpdate();
                    StateChange(ActionState.Completed);
                    return;
                }

                nextTime = DateTime.UtcNow.AddSeconds(moveTime);
                StateChange(ActionState.Fired);
            });
        }
Exemple #18
0
        public virtual void JoinOrCreateStrongholdGateBattle(IStronghold targetStronghold,
                                                             ITroopObject attackerTroopObject,
                                                             out ICombatGroup combatGroup,
                                                             out uint battleId)
        {
            // If battle already exists, then we just join it in also bringing any new units
            if (targetStronghold.GateBattle != null)
            {
                combatGroup = battleProcedure.AddAttackerToBattle(targetStronghold.GateBattle, attackerTroopObject);
            }
            // Otherwise, the battle has to be created
            else
            {
                var battleOwner = targetStronghold.Tribe == null
                                          ? new BattleOwner(BattleOwnerType.Stronghold, targetStronghold.ObjectId)
                                          : new BattleOwner(BattleOwnerType.Tribe, targetStronghold.Tribe.Id);

                targetStronghold.GateBattle =
                    battleManagerFactory.CreateStrongholdGateBattleManager(
                        new BattleLocation(BattleLocationType.StrongholdGate,
                                           targetStronghold.ObjectId),
                        battleOwner,
                        targetStronghold);

                combatGroup = battleProcedure.AddAttackerToBattle(targetStronghold.GateBattle, attackerTroopObject);

                var   battlePassiveAction = actionFactory.CreateStrongholdGateBattlePassiveAction(targetStronghold.ObjectId);
                Error result = targetStronghold.Worker.DoPassive(targetStronghold, battlePassiveAction, false);
                if (result != Error.Ok)
                {
                    throw new Exception(string.Format("Failed to start a battle due to error {0}", result));
                }
                targetStronghold.BeginUpdate();
                targetStronghold.State = GameObjectStateFactory.BattleState(targetStronghold.GateBattle.BattleId);
                targetStronghold.EndUpdate();
            }

            battleId = targetStronghold.GateBattle.BattleId;
        }
Exemple #19
0
        private void BattleExitBattle(IBattleManager battle, ICombatList atk, ICombatList def)
        {
            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);
        }
Exemple #20
0
        public virtual void JoinOrCreateBarbarianTribeBattle(IBarbarianTribe barbarianTribe,
                                                             ITroopObject attackerTroopObject,
                                                             out ICombatGroup combatGroup,
                                                             out uint battleId)
        {
            // If battle already exists, then we just join it in also bringing any new units
            if (barbarianTribe.Battle != null)
            {
                combatGroup = battleProcedure.AddAttackerToBattle(barbarianTribe.Battle, attackerTroopObject);
            }
            // Otherwise, the battle has to be created
            else
            {
                var battleOwner = new BattleOwner(BattleOwnerType.BarbarianTribe, barbarianTribe.ObjectId);

                barbarianTribe.Battle =
                    battleManagerFactory.CreateBarbarianBattleManager(new BattleLocation(BattleLocationType.BarbarianTribe, barbarianTribe.ObjectId),
                                                                      battleOwner,
                                                                      barbarianTribe);

                combatGroup = battleProcedure.AddAttackerToBattle(barbarianTribe.Battle, attackerTroopObject);

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

                barbarianTribe.BeginUpdate();
                barbarianTribe.LastAttacked = DateTime.UtcNow;
                barbarianTribe.State        = GameObjectStateFactory.BattleState(barbarianTribe.Battle.BattleId);
                barbarianTribe.EndUpdate();
            }

            battleId = barbarianTribe.Battle.BattleId;
        }
Exemple #21
0
        public override void Callback(object custom)
        {
            IStronghold stronghold;

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

            CallbackLock.CallbackLockHandler lockHandler = delegate { return(stronghold.LockList().ToArray()); };

            locker.Lock(lockHandler, null, stronghold).Do(() =>
            {
                if (stronghold.MainBattle.ExecuteTurn())
                {
                    // Battle continues, just save it and reschedule
                    dbManager.Save(stronghold.MainBattle);
                    endTime = SystemClock.Now.AddSeconds(formula.GetBattleInterval(stronghold.MainBattle.Defenders, stronghold.MainBattle.Attackers));
                    StateChange(ActionState.Fired);
                    return;
                }

                // Battle has ended
                // Delete the battle
                stronghold.MainBattle.UnitCountDecreased -= MainBattleOnUnitKilled;
                stronghold.MainBattle.GroupKilled        -= MainBattleOnGroupKilled;
                stronghold.MainBattle.ActionAttacked     -= MainBattleOnActionAttacked;
                stronghold.MainBattle.ExitTurn           -= MainBattleOnExitTurn;
                stronghold.MainBattle.EnterBattle        -= MainBattleOnEnterBattle;

                // Set troop states to stationed and
                // send back anyone stationed here that doesn't belong
                // Make copy because it may change
                var stationedHere = stronghold.Troops.StationedHere().ToList();
                foreach (var stub in stationedHere)
                {
                    stub.BeginUpdate();
                    stub.State = TroopState.Stationed;
                    stub.EndUpdate();

                    if (stub.City.Owner.IsInTribe && stub.City.Owner.Tribesman.Tribe == stronghold.Tribe)
                    {
                        continue;
                    }

                    var troopInitializer   = troopInitializerFactory.CreateStationedTroopObjectInitializer(stub);
                    var retreatChainAction = actionFactory.CreateRetreatChainAction(stub.City.Id, troopInitializer);
                    var result             = stub.City.Worker.DoPassive(stub.City, retreatChainAction, true);
                    if (result != Error.Ok)
                    {
                        throw new Exception("Unexpected failure when retreating a unit from stronghold");
                    }
                }

                world.Remove(stronghold.MainBattle);
                dbManager.Delete(stronghold.MainBattle);
                stronghold.BeginUpdate();
                stronghold.GateOpenTo = null;
                stronghold.MainBattle = null;
                stronghold.GateMax    = (int)formula.StrongholdGateLimit(stronghold.Lvl);
                stronghold.Gate       = Math.Max(Math.Min(stronghold.GateMax, stronghold.Gate), formula.StrongholdGateHealHp(stronghold.StrongholdState, stronghold.Lvl));
                stronghold.State      = GameObjectStateFactory.NormalState();
                stronghold.EndUpdate();

                StateChange(ActionState.Completed);
            });
        }