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); }
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); }
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(); }
public override bool RemoveFromFormation(FormationType sourceFormationType, ISimpleStub unitsToRemove) { BeginUpdate(); var result = base.RemoveFromFormation(sourceFormationType, unitsToRemove); EndUpdate(); return(result); }
public StationedPartialTroopObjectInitializer(ITroopStub stub, ISimpleStub unitsToRetreat, Formula formula, IWorld world) { this.stub = stub; this.unitsToRetreat = unitsToRetreat; this.formula = formula; this.world = world; }
public void AddAllToFormation(FormationType formation, ISimpleStub unitsToAdd) { lock (objLock) { CheckUpdateMode(); foreach (var unit in unitsToAdd.ToUnitList()) { AddUnit(formation, unit.Type, unit.Count); } } }
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(); }
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(); }
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(); }
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); }
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); }
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); }
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; }
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); }
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); }
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(); }
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); }
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); }
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(); } }
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); }
/// <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; } }
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); }); }
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); }
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>())); }
public ITroopObjectInitializer CreateStationedPartialTroopObjectInitializer(ITroopStub stub, ISimpleStub unitsToRetreat) { return(new StationedPartialTroopObjectInitializer(stub, unitsToRetreat, kernel.Get <Formula>(), kernel.Get <IWorld>())); }