Exemplo n.º 1
0
        public virtual bool RemoveFromFormation(FormationType sourceFormationType, ISimpleStub unitsToRemove)
        {
            if (!HasFormation(sourceFormationType))
            {
                return(false);
            }

            // Make sure there are enough units
            var sourceFormation  = Data[sourceFormationType];
            var allUnitsToRemove = unitsToRemove.ToUnitList();

            foreach (var unit in allUnitsToRemove)
            {
                ushort count;
                if (!sourceFormation.TryGetValue(unit.Type, out count) || count < unit.Count)
                {
                    return(false);
                }
            }

            foreach (var unit in unitsToRemove.SelectMany(formation => formation))
            {
                Data[sourceFormationType].Remove(unit.Key, unit.Value);
            }

            return(true);
        }
Exemplo n.º 2
0
        private bool TroopObjectCreateFromCity(ICity city,
                                               ISimpleStub stub,
                                               uint x,
                                               uint y,
                                               out ITroopObject troopObject)
        {
            if (stub.TotalCount == 0 || !city.DefaultTroop.RemoveFromFormation(FormationType.Normal, stub))
            {
                troopObject = null;
                return(false);
            }

            var troopStub = city.CreateTroopStub();

            troopStub.BeginUpdate();
            troopStub.Add(stub);
            troopStub.EndUpdate();

            troopObject = city.CreateTroopObject(troopStub, x, y + 1);

            troopObject.BeginUpdate();
            troopObject.Stats = new TroopStats(formula.GetTroopRadius(troopStub, null),
                                               formula.GetTroopSpeed(troopStub));
            world.Regions.Add(troopObject);
            troopObject.EndUpdate();

            return(true);
        }
Exemplo n.º 3
0
        public void DeleteTroopObject_WhenTroopObjectCreated_AddsUnitsBackToOriginalTroop(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);
            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, Arg.Any <ISimpleStub>()).Returns(true);
            stub.City.Troops.Remove(Arg.Any <ushort>()).Returns(true);

            var newStub = Substitute.For <ITroopStub>();

            stub.City.CreateTroopStub().Returns(newStub);

            ITroopObject troopObject = Substitute.For <ITroopObject>();

            troopObject.Stub.Returns(newStub);
            stub.City.CreateTroopObject(newStub, Arg.Any <uint>(), Arg.Any <uint>()).Returns(troopObject);

            troopInitializer.GetTroopObject(out troopObject);

            troopInitializer.DeleteTroopObject();

            stub.Received(1).BeginUpdate();
            stub.Received(1).AddAllToFormation(FormationType.Defense, newStub);
            stub.Received(1).EndUpdate();
        }
Exemplo n.º 4
0
        public override bool RemoveFromFormation(FormationType sourceFormationType, ISimpleStub unitsToRemove)
        {
            BeginUpdate();
            var result = base.RemoveFromFormation(sourceFormationType, unitsToRemove);

            EndUpdate();

            return(result);
        }
Exemplo n.º 5
0
 public StationedPartialTroopObjectInitializer(ITroopStub stub,
                                               ISimpleStub unitsToRetreat,
                                               Formula formula,
                                               IWorld world)
 {
     this.stub           = stub;
     this.unitsToRetreat = unitsToRetreat;
     this.formula        = formula;
     this.world          = world;
 }
Exemplo n.º 6
0
        public void AddAllToFormation(FormationType formation, ISimpleStub unitsToAdd)
        {
            lock (objLock)
            {
                CheckUpdateMode();

                foreach (var unit in unitsToAdd.ToUnitList())
                {
                    AddUnit(formation, unit.Type, unit.Count);
                }
            }
        }
Exemplo n.º 7
0
        public void GetTroopObject_WhenUnitsToRetreatIsEmpty_ReturnsError(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            stub.State.Returns(TroopState.Stationed);
            unitsToRetreat.TotalCount.Returns <ushort>(0);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.TroopEmpty);
            troopObject.Should().BeNull();
        }
Exemplo n.º 8
0
        public void GetTroopObject_WhenStubIsNotStationed_ReturnsError(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);
            stub.State.Returns(TroopState.BattleStationed);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.TroopNotStationed);
            troopObject.Should().BeNull();
        }
Exemplo n.º 9
0
        public void GetTroopObject_WhenCannotRemoveFromExistingTroop_ReturnsError(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);
            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, unitsToRetreat).Returns(false);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.TroopChanged);
            troopObject.Should().BeNull();
        }
Exemplo n.º 10
0
        public void GetTroopObject_WhenAbleToRetreat_AddsNewTroopObjectToWorld(
            [Frozen] ITroopStub stub,
            [Frozen] IWorld world,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);

            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, Arg.Any <ISimpleStub>()).Returns(true);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.Ok);
            world.Regions.Received(1).Add(troopObject);
        }
Exemplo n.º 11
0
        public virtual bool TroopStubCreate(out ITroopStub troopStub,
                                            ICity city,
                                            ISimpleStub stub,
                                            TroopState initialState = TroopState.Idle)
        {
            if (!city.DefaultTroop.RemoveFromFormation(FormationType.Normal, stub))
            {
                troopStub = null;
                return(false);
            }

            troopStub = city.CreateTroopStub();
            troopStub.BeginUpdate();
            troopStub.Add(stub);
            troopStub.State = initialState;
            troopStub.EndUpdate();
            return(true);
        }
Exemplo n.º 12
0
        public void DeleteTroopObject_WhenTroopObjectCreated_ScheduleRemovesTheTroopObject(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);
            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, Arg.Any <ISimpleStub>()).Returns(true);
            stub.City.Troops.Remove(Arg.Any <ushort>()).Returns(true);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject);

            troopInitializer.DeleteTroopObject();

            stub.City.Received(1).ScheduleRemove(troopObject, false);
        }
Exemplo n.º 13
0
 public CityTroopObjectInitializer(uint cityId,
                                   ISimpleStub simpleStub,
                                   TroopBattleGroup group,
                                   AttackMode mode,
                                   IGameObjectLocator gameObjectLocator,
                                   Formula formula,
                                   Procedure procedure,
                                   IWorld world)
 {
     this.cityId            = cityId;
     this.simpleStub        = simpleStub;
     this.group             = group;
     this.mode              = mode;
     this.gameObjectLocator = gameObjectLocator;
     this.formula           = formula;
     this.procedure         = procedure;
     this.world             = world;
 }
Exemplo n.º 14
0
        public void GetTroopObject_WhenCalledTwice_ReturnsSameInstance(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);

            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, Arg.Any <ISimpleStub>()).Returns(true);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.Ok);
            ITroopObject troopObject2;

            troopInitializer.GetTroopObject(out troopObject2).Should().Be(Error.Ok);

            troopObject.Should().BeSameAs(troopObject2);
        }
Exemplo n.º 15
0
        public void GetTroopObject_WhenAbleToRetreat_AddsNewTroopObjectToCity(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);
            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, Arg.Any <ISimpleStub>()).Returns(true);

            stub.Station.PrimaryPosition.Returns(new Position(10, 20));

            var newStub = Substitute.For <ITroopStub>();

            stub.City.CreateTroopStub().Returns(newStub);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.Ok);
            stub.City.Received(1).CreateTroopObject(newStub, 10, 21);
        }
Exemplo n.º 16
0
        public void GetTroopObject_WhenAbleToRetreat_AddsUnitsToNewStub(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);
            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, unitsToRetreat).Returns(true);

            var newStub = Substitute.For <ITroopStub>();

            stub.City.CreateTroopStub().Returns(newStub);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.Ok);
            newStub.Received(1).BeginUpdate();
            newStub.Received(1).Add(unitsToRetreat);
            newStub.Received(1).EndUpdate();
        }
Exemplo n.º 17
0
        public Error JoinAssignment(int id, ICity city, ISimpleStub simpleStub)
        {
            Assignment assignment;

            if (!assignments.TryGetValue(id, out assignment))
            {
                return(Error.AssignmentNotFound);
            }

            if (assignment.Target == city)
            {
                return(Error.AssignmentNotEligible);
            }

            ITroopStub stub;

            if (!procedure.TroopStubCreate(out stub,
                                           city,
                                           simpleStub,
                                           assignment.IsAttack
                                                   ? TroopState.WaitingInOffensiveAssignment
                                                   : TroopState.WaitingInDefensiveAssignment))
            {
                return(Error.TroopChanged);
            }

            if (stub.Upkeep < ASSIGNMENT_MIN_UPKEEP)
            {
                procedure.TroopStubDelete(city, stub);
                return(Error.AssignmentTooFewTroops);
            }

            var error = assignment.Add(stub);

            if (error != Error.Ok)
            {
                procedure.TroopStubDelete(city, stub);
            }

            return(error);
        }
Exemplo n.º 18
0
        public void GetTroopObject_WhenAbleToRetreat_LoadsStats(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            [FrozenMock] Formula formula,
            ITroopObject newTroopObject,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);

            formula.GetTroopRadius(stub, null).Returns <byte>(34);
            formula.GetTroopSpeed(stub).Returns(44);

            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, Arg.Any <ISimpleStub>()).Returns(true);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject).Should().Be(Error.Ok);
            troopObject.Stats.Speed.Should().Be(44);
            troopObject.Stats.AttackRadius.Should().Be(34);
        }
Exemplo n.º 19
0
        public void Add(ISimpleStub stub)
        {
            lock (objLock)
            {
                CheckUpdateMode();

                foreach (IFormation stubFormation in stub)
                {
                    IFormation targetFormation;
                    if (!Data.TryGetValue(stubFormation.Type, out targetFormation))
                    {
                        targetFormation = new Formation(stubFormation.Type);
                        targetFormation.OnUnitUpdated += FormationOnUnitUpdated;
                        Data.Add(stubFormation.Type, targetFormation);
                    }

                    targetFormation.Add(stubFormation);
                }

                FireUnitUpdated();
            }
        }
Exemplo n.º 20
0
        public void DeleteTroopObject_WhenTroopObjectFailsToRemoveFromCity_DoesNotAddUnitsBackToStub(
            [Frozen] ITroopStub stub,
            [Frozen] ISimpleStub unitsToRetreat,
            StationedPartialTroopObjectInitializer troopInitializer)
        {
            unitsToRetreat.TotalCount.Returns <ushort>(1);
            stub.State.Returns(TroopState.Stationed);
            stub.RemoveFromFormation(FormationType.Defense, Arg.Any <ISimpleStub>()).Returns(true);

            var newStub = Substitute.For <ITroopStub>();

            newStub.TroopId.Returns <ushort>(5);
            stub.City.CreateTroopStub().Returns(newStub);

            stub.City.Troops.Remove(newStub.TroopId).Returns(false);

            ITroopObject troopObject;

            troopInitializer.GetTroopObject(out troopObject);

            troopInitializer.DeleteTroopObject();

            stub.DidNotReceiveWithAnyArgs().AddAllToFormation(FormationType.Defense, null);
        }
Exemplo n.º 21
0
        /// <summary>
        ///     This method generates simplestub.
        /// </summary>
        /// <param name="level">level of object</param>
        /// <param name="upkeep">Total output upkeep</param>
        /// <param name="unitLevel">The unit level to generate</param>
        /// <param name="randomness">A percentage of upkeep being completely random, 1 means it's completely random</param>
        /// <param name="seed">seed for the randomizer</param>
        /// <param name="stub">output</param>
        public virtual void Generate(int level, int upkeep, byte unitLevel, double randomness, int seed, out ISimpleStub stub)
        {
            stub = new SimpleStub();
            for (int i = 0; i < type.Length; ++i)
            {
                stub.AddUnit(FormationType.Normal,
                             type[i],
                             (ushort)(upkeep * (1 - randomness) * ratio[level - 1][i] / unitFactory.GetUnitStats(type[i], unitLevel).Upkeep));
            }

            Random random    = new Random(seed);
            int    remaining = (int)(upkeep * randomness);

            while (remaining > 0)
            {
                var nextUpkeep = random.Next(1, remaining);
                var nextType   = random.Next(0, type.Length);
                var unitUpkeep = unitFactory.GetUnitStats(type[nextType], unitLevel).Upkeep;
                var unitCount  = nextUpkeep / unitUpkeep;
                if (unitCount <= 0)
                {
                    continue;
                }
                stub.AddUnit(FormationType.Normal, type[nextType], (ushort)unitCount);
                remaining -= unitUpkeep * unitCount;
            }
        }
Exemplo n.º 22
0
        private void Retreat(Session session, Packet packet)
        {
            uint        cityId;
            ushort      troopId;
            bool        completeRetreat;
            ISimpleStub unitsToRetreat = null;

            try
            {
                cityId          = packet.GetUInt32();
                troopId         = packet.GetUInt16();
                completeRetreat = packet.GetByte() == 1;

                if (!completeRetreat)
                {
                    unitsToRetreat = PacketHelper.ReadStub(packet, FormationType.Defense);
                }
            }
            catch (Exception)
            {
                ReplyError(session, packet, Error.Unexpected);
                return;
            }

            ICity    city;
            IStation station = null;

            //we need to find out the stationed location first then reacquire local + stationed locks
            locker.Lock(cityId, out city).Do(() =>
            {
                if (city == null)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                ITroopStub stub;

                if (!city.Troops.TryGetStub(troopId, out stub) || stub.Station == null)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                station = stub.Station;
            });

            if (station == null)
            {
                return;
            }

            locker.Lock(city, station).Do(() =>
            {
                ITroopStub stub;

                if (!city.Troops.TryGetStub(troopId, out stub))
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                //Make sure that the person sending the retreat is either the guy who owns the troop or the guy who owns the stationed city
                bool stationOwnerRetreating = session.Player.GetCityList().Any(x => x == stub.Station);
                if (city.Owner != session.Player && !stationOwnerRetreating)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                ITroopObjectInitializer troopInitializer;

                if (completeRetreat || unitsToRetreat.TotalCount == stub.TotalCount)
                {
                    troopInitializer = troopObjectInitializerFactory.CreateStationedTroopObjectInitializer(stub);
                }
                else
                {
                    troopInitializer = troopObjectInitializerFactory.CreateStationedPartialTroopObjectInitializer(stub, unitsToRetreat);
                }

                var ra = actionFactory.CreateRetreatChainAction(cityId, troopInitializer);

                Error ret = city.Worker.DoPassive(city, ra, true);
                ReplyWithResult(session, packet, ret);
            });
        }
Exemplo n.º 23
0
        public Error CreateAssignment(ICity city,
                                      ISimpleStub simpleStub,
                                      uint x,
                                      uint y,
                                      ILocation target,
                                      DateTime time,
                                      AttackMode mode,
                                      string desc,
                                      bool isAttack,
                                      out int id)
        {
            id = 0;

            if (assignments.Count > 20)
            {
                return(Error.AssignmentTooManyInProgress);
            }

            // Create troop
            ITroopStub stub;

            if (!procedure.TroopStubCreate(out stub,
                                           city,
                                           simpleStub,
                                           isAttack
                                                       ? TroopState.WaitingInOffensiveAssignment
                                                       : TroopState.WaitingInDefensiveAssignment))
            {
                return(Error.TroopChanged);
            }

            // Max of 48 hrs for planning assignments
            if (DateTime.UtcNow.AddDays(2) < time)
            {
                procedure.TroopStubDelete(city, stub);
                return(Error.AssignmentBadTime);
            }

            if (assignments.Count > 30)
            {
                procedure.TroopStubDelete(city, stub);
                return(Error.AssignmentTooManyInProgress);
            }

            if (stub.Upkeep < ASSIGNMENT_MIN_UPKEEP)
            {
                procedure.TroopStubDelete(city, stub);
                return(Error.AssignmentTooFewTroops);
            }

            if (stub.City.Owner.Tribesman == null)
            {
                procedure.TroopStubDelete(city, stub);
                return(Error.TribeNotFound);
            }

            if (target.LocationType == LocationType.City)
            {
                ICity targetCity;
                if (!cityManager.TryGetCity(target.LocationId, out targetCity))
                {
                    procedure.TroopStubDelete(city, stub);
                    return(Error.CityNotFound);
                }

                // Cant attack other tribesman
                if (isAttack && targetCity.Owner.Tribesman != null &&
                    targetCity.Owner.Tribesman.Tribe == stub.City.Owner.Tribesman.Tribe)
                {
                    procedure.TroopStubDelete(city, stub);
                    return(Error.AssignmentCantAttackFriend);
                }

                // Cant defend the same city
                if (targetCity == stub.City)
                {
                    procedure.TroopStubDelete(city, stub);
                    return(Error.DefendSelf);
                }
            }
            else if (target.LocationType == LocationType.Stronghold)
            {
                IStronghold stronghold;
                if (!strongholdManager.TryGetStronghold(target.LocationId, out stronghold))
                {
                    procedure.TroopStubDelete(city, stub);
                    return(Error.StrongholdNotFound);
                }

                // Cant attack your stronghold
                if (isAttack && stronghold.Tribe == stub.City.Owner.Tribesman.Tribe)
                {
                    procedure.TroopStubDelete(city, stub);
                    return(Error.AttackSelf);
                }
                // Cant defend other tribe's stronghold
                if (!isAttack && stronghold.Tribe != stub.City.Owner.Tribesman.Tribe)
                {
                    procedure.TroopStubDelete(city, stub);
                    return(Error.DefendSelf);
                }
            }
            else
            {
                procedure.TroopStubDelete(city, stub);
                return(Error.ObjectNotAttackable);
            }

            // Player creating the assignment cannot be late (Give a few minutes lead)
            int      distance  = tileLocator.TileDistance(stub.City.PrimaryPosition, 1, new Position(x, y), 1);
            DateTime reachTime = DateTime.UtcNow.AddSeconds(formula.MoveTimeTotal(stub, distance, true));

            if (reachTime.Subtract(new TimeSpan(0, 1, 0)) > time)
            {
                procedure.TroopStubDelete(city, stub);
                return(Error.AssignmentUnitsTooSlow);
            }

            // Create assignment
            Assignment assignment = assignmentFactory.CreateAssignment(this, x, y, target, mode, time, desc, isAttack);

            id = assignment.Id;
            assignments.Add(assignment.Id, assignment);
            assignment.AssignmentComplete += RemoveAssignment;
            var result = assignment.Add(stub);

            if (result != Error.Ok)
            {
                procedure.TroopStubDelete(city, stub);
            }

            SendUpdate();
            return(result);
        }
Exemplo n.º 24
0
 public ITroopObjectInitializer CreateCityTroopObjectInitializer(uint cityId, ISimpleStub simpleStub, TroopBattleGroup @group, AttackMode mode)
 {
     return(new CityTroopObjectInitializer(cityId, simpleStub, @group, mode, kernel.Get <IGameObjectLocator>(), kernel.Get <Formula>(), kernel.Get <Procedure>(), kernel.Get <IWorld>()));
 }
Exemplo n.º 25
0
 public ITroopObjectInitializer CreateStationedPartialTroopObjectInitializer(ITroopStub stub, ISimpleStub unitsToRetreat)
 {
     return(new StationedPartialTroopObjectInitializer(stub, unitsToRetreat, kernel.Get <Formula>(), kernel.Get <IWorld>()));
 }