Example #1
0
        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);
        }
Example #2
0
        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);
        }