public void GetInstantTrainCount_WhenEffectIsAssociateWithMultipleUnits([Frozen] IObjectTypeFactory objectTypeFactory, Formula formula, IStructure structure, ITroopStub troopStub) { var effects = new List <Effect> { new Effect { Id = EffectCode.UnitTrainInstantTime, IsPrivate = false, Location = EffectLocation.City, Value = new object[] { 1, "BarrackUnits", 50, 50 } } }; structure.City.Technologies.GetEffects(EffectCode.UnitTrainInstantTime).Returns(effects); objectTypeFactory.IsObjectType("BarrackUnits", 101).Returns(true); objectTypeFactory.IsObjectType("BarrackUnits", 102).Returns(true); objectTypeFactory.IsObjectType("BarrackUnits", 105).Returns(false); structure.Type.Returns((ushort)1); troopStub.ToUnitList().ReturnsForAnyArgs(new List <Unit> { new Unit(101, 10), new Unit(102, 25), new Unit(105, 10) }); structure.City.Troops.MyStubs().Returns(new List <ITroopStub> { troopStub }); formula.GetInstantTrainCount(structure).Should().Be(15); }
public virtual Error CityMaxConcurrentBuildActions(ushort structureType, uint currentActionId, ICity city, IObjectTypeFactory objectTypeFactory) { int maxConcurrentUpgrades = ConcurrentBuildUpgrades(city.MainBuilding.Lvl); if (!objectTypeFactory.IsObjectType("UnlimitedBuilding", structureType) && city.Worker.ActiveActions.Values.Count(action => { if (action.ActionId == currentActionId) { return(false); } if (action.Type == ActionType.StructureUpgradeActive) { return(true); } if (action.Type != ActionType.StructureBuildActive) { return(false); } return(!objectTypeFactory.IsObjectType("UnlimitedBuilding", ((StructureBuildActiveAction)action).BuildType)); }) >= maxConcurrentUpgrades) { return(Error.ActionTotalMaxReached); } return(Error.Ok); }
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); } }
public void GetInstantTrainCount_WhenThereAreMultipleEffects([Frozen] IObjectTypeFactory objectTypeFactory, Formula formula, IStructure structure) { var effects = new List <Effect> { new Effect { Id = EffectCode.UnitTrainInstantTime, IsPrivate = false, Location = EffectLocation.City, Value = new object[] { 1, "BarrackUnits", 20, 150 } }, new Effect { Id = EffectCode.UnitTrainInstantTime, IsPrivate = false, Location = EffectLocation.City, Value = new object[] { 1, "BarrackUnits", 30, 150 } } }; structure.City.Technologies.GetEffects(EffectCode.UnitTrainInstantTime).Returns(effects); objectTypeFactory.IsObjectType("BarrackUnits", 101).Returns(true); structure.Type.Returns((ushort)1); formula.GetInstantTrainCount(structure).Should().Be(50); }
public StructureBuildActiveActionExecuteBuilder(IFixture fixture) { this.fixture = fixture; requirementCsvFactory = fixture.Freeze <IRequirementCsvFactory>(); requirementCsvFactory .GetLayoutRequirement(Arg.Any <ushort>(), Arg.Any <byte>()) .Validate(Arg.Any <IStructure>(), Arg.Any <ushort>(), Arg.Any <uint>(), Arg.Any <uint>(), Arg.Any <byte>()) .Returns(true); structureBaseStats = fixture.Freeze <IStructureBaseStats>(); structureBaseStats.Size.Returns <byte>(0); var structureCost = new Resource(1234, 8446, 1343, 1234, 1246); structureBaseStats.Cost.Returns(structureCost); var structure = fixture.Freeze <IStructure>(); structure.Stats.Base.Returns(structureBaseStats); objectTypeFactory = fixture.Freeze <IObjectTypeFactory>(); objectTypeFactory.IsObjectType("NoRoadRequired", Arg.Any <ushort>()).Returns(true); city = fixture.Create <ICity>(); city.PrimaryPosition.Returns(new Position(99, 98)); city.Radius.Returns <byte>(5); city.Resource.HasEnough(structureBaseStats.Cost).Returns(true); city.CreateStructure(Arg.Any <ushort>(), Arg.Any <byte>(), Arg.Any <uint>(), Arg.Any <uint>()).Returns(structure); roadPathFinder = fixture.Freeze <IRoadPathFinder>(); roadPathFinder.CanBuild(Arg.Any <Position>(), Arg.Any <byte>(), city, Arg.Any <bool>()).Returns(Error.Ok); tileLocator = fixture.Freeze <ITileLocator>(); tileLocator.TileDistance(new Position(99, 98), 1, Arg.Any <Position>(), 1).Returns(1); world = fixture.Freeze <IWorld>(); ICity outCity; world.TryGetObjects(Arg.Any <uint>(), out outCity).Returns(x => { x[1] = city; return(true); }); world.Regions.GetObjectsInTile(Arg.Any <uint>(), Arg.Any <uint>()).Returns(new List <ISimpleGameObject>()); world.Regions.IsValidXandY(0, 0).ReturnsForAnyArgs(true); world.Regions.Add(structure).Returns(true); structureCsvFactory = fixture.Freeze <IStructureCsvFactory>(); structureCsvFactory.GetBaseStats(0, 0).ReturnsForAnyArgs(structureBaseStats); formula = Substitute.For <Formula>(); formula.CityMaxConcurrentBuildActions(0, 0, null, null).ReturnsForAnyArgs(Error.Ok); formula.StructureCost(null, null).ReturnsForAnyArgs(structureCost); fixture.Register(() => formula); }
public virtual int GetNumberOfHits(ICombatObject currentAttacker, ICombatList defenderCombatList) { int splashEvery200 = objectTypeFactory.IsObjectType("SplashEvery200", currentAttacker.Type) ? (Math.Min(defenderCombatList.UpkeepExcludingWaitingToJoinBattle, 4000) / 200) : 0; return(currentAttacker.Stats.Splash == 0 ? 1 : currentAttacker.Stats.Splash + splashEvery200); }
public Error CanBuild(Position position, byte size, ICity city, bool requiresRoad) { var buildingPositions = tileLocator.ForeachMultitile(position.X, position.Y, size).ToArray(); var buildingNeighbors = tileLocator.ForeachRadius(position.X, position.Y, size, 1).ToArray(); var mainBuildingPositions = tileLocator.ForeachMultitile(city.MainBuilding).ToArray(); var roadsBeingBuiltOn = buildingPositions.Any(buildingPosition => world.Roads.IsRoad(buildingPosition.X, buildingPosition.Y)); if (!requiresRoad) { // Cant build on road if this building doesnt require roads return(roadsBeingBuiltOn ? Error.RoadDestroyUniquePath : Error.Ok); } if (roadsBeingBuiltOn) { // All structures should still have a valid path if we are building on top of a road foreach (var str in city) { if (str.IsMainBuilding || objectTypeFactory.IsObjectType("NoRoadRequired", str.Type)) { continue; } if (!HasPath(start: str.PrimaryPosition, startSize: str.Size, city: city, excludedPoints: buildingPositions)) { return(Error.RoadDestroyUniquePath); } } // All neighboring roads should have a different path foreach (var neighborPosition in buildingNeighbors) { if (mainBuildingPositions.Contains(neighborPosition) || !world.Roads.IsRoad(neighborPosition.X, neighborPosition.Y)) { continue; } if (!HasPath(start: neighborPosition, startSize: 1, city: city, excludedPoints: buildingPositions)) { return(Error.RoadDestroyUniquePath); } } } // There should be a road around this building foreach (var neighborPosition in buildingNeighbors) { bool hasStructure = world.Regions.GetObjectsInTile(neighborPosition.X, neighborPosition.Y) .Any(obj => obj is IStructure); if (hasStructure || !world.Roads.IsRoad(neighborPosition.X, neighborPosition.Y)) { continue; } if (roadsBeingBuiltOn && !HasPath(start: neighborPosition, startSize: 1, city: city, excludedPoints: buildingPositions)) { continue; } return(Error.Ok); } return(Error.RoadNotAround); }
public override Error Execute() { ICity city; if (!world.TryGetObjects(cityId, out city)) { return(Error.ObjectNotFound); } var maxConcurrentUpgradesResult = formula.CityMaxConcurrentBuildActions(type, ActionId, city, objectTypeFactory); if (maxConcurrentUpgradesResult != Error.Ok) { return(maxConcurrentUpgradesResult); } var structureBaseStats = structureCsvFactory.GetBaseStats(type, level); var lockedRegions = world.Regions.LockMultitileRegions(X, Y, structureBaseStats.Size); foreach (var position in tileLocator.ForeachMultitile(X, Y, structureBaseStats.Size)) { var tileType = world.Regions.GetTileType(position.X, position.Y); // tile requirement if (!string.IsNullOrEmpty(tileRequirement) && !objectTypeFactory.IsTileType(tileRequirement, tileType)) { world.Regions.UnlockRegions(lockedRegions); return(Error.TileMismatch); } // Only allow buildings that require resource tile to built on them if (tileRequirement != "TileResource" && objectTypeFactory.IsTileType("TileResource", tileType)) { world.Regions.UnlockRegions(lockedRegions); return(Error.TileMismatch); } // dont allow building on edge of world if (!world.Regions.IsValidXandY(position.X, position.Y)) { world.Regions.UnlockRegions(lockedRegions); return(Error.ActionInvalid); } // radius requirements if (tileLocator.TileDistance(city.PrimaryPosition, 1, position, 1) >= city.Radius) { world.Regions.UnlockRegions(lockedRegions); return(Error.NotWithinWalls); } // check if tile is occupied if (world.Regions.GetObjectsInTile(position.X, position.Y).Any(obj => obj is IStructure)) { world.Regions.UnlockRegions(lockedRegions); return(Error.StructureExists); } } // cost requirement cost = formula.StructureCost(city, structureBaseStats); if (!city.Resource.HasEnough(cost)) { world.Regions.UnlockRegions(lockedRegions); return(Error.ResourceNotEnough); } // layout requirement if (!requirementCsvFactory.GetLayoutRequirement(type, level).Validate(WorkerObject as IStructure, type, X, Y, structureBaseStats.Size)) { world.Regions.UnlockRegions(lockedRegions); return(Error.LayoutNotFullfilled); } // check for road requirements var requiresRoad = !objectTypeFactory.IsObjectType("NoRoadRequired", type); var canBuild = roadPathFinder.CanBuild(new Position(X, Y), structureBaseStats.Size, city, requiresRoad); if (canBuild != Error.Ok) { world.Regions.UnlockRegions(lockedRegions); return(canBuild); } // add structure to the map IStructure structure = city.CreateStructure(type, 0, X, Y); city.BeginUpdate(); city.Resource.Subtract(cost); city.EndUpdate(); structure.BeginUpdate(); if (!world.Regions.Add(structure)) { city.ScheduleRemove(structure, false); city.BeginUpdate(); city.Resource.Add(cost); city.EndUpdate(); structure.EndUpdate(); world.Regions.UnlockRegions(lockedRegions); return(Error.MapFull); } structure.EndUpdate(); callbackProcedure.OnStructureUpgrade(structure); structureId = structure.ObjectId; // add to queue for completion var buildTime = formula.BuildTime(structureBaseStats.BuildTime, city, city.Technologies); endTime = SystemClock.Now.AddSeconds(CalculateTime(buildTime)); BeginTime = SystemClock.Now; city.References.Add(structure, this); world.Regions.UnlockRegions(lockedRegions); return(Error.Ok); }