Ejemplo n.º 1
0
        public override Error Execute()
        {
            ICity      city;
            IStructure structure;

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

            cost = formula.StructureCost(structure.City, structureCsvFactory.GetBaseStats((ushort)type, lvl));
            if (cost == null)
            {
                return(Error.ObjectNotFound);
            }

            if (!structure.City.Resource.HasEnough(cost))
            {
                return(Error.ResourceNotEnough);
            }

            structure.City.BeginUpdate();
            structure.City.Resource.Subtract(cost);
            structure.City.EndUpdate();

            var buildTime = formula.BuildTime(structureCsvFactory.GetTime((ushort)type, lvl), city, structure.Technologies);

            endTime   = SystemClock.Now.AddSeconds(CalculateTime(buildTime));
            BeginTime = SystemClock.Now;

            return(Error.Ok);
        }
Ejemplo n.º 2
0
        public override Error Execute()
        {
            ICity      city;
            IStructure structure;

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

            if (
                city.Worker.ActiveActions.Values.Any(
                    action =>
                    action.Type == Type &&
                    UnitType == ((UnitUpgradeActiveAction)action).UnitType &&
                    action != this))
            {
                return(Error.ActionAlreadyInProgress);
            }

            IBaseUnitStats unitStats = city.Template[UnitType];

            if (unitStats == null)
            {
                return(Error.Unexpected);
            }

            Resource cost = formula.UnitUpgradeCost(city, UnitType, (byte)(unitStats.Lvl + 1));

            if (cost == null)
            {
                return(Error.Unexpected);
            }

            if (!city.Resource.HasEnough(cost))
            {
                return(Error.ResourceNotEnough);
            }

            city.BeginUpdate();
            city.Resource.Subtract(cost);
            city.EndUpdate();

            var upgradeTime = formula.BuildTime(unitFactory.GetUpgradeTime(UnitType, (byte)(unitStats.Lvl + 1)),
                                                city,
                                                structure.Technologies);

            endTime   = DateTime.UtcNow.AddSeconds(CalculateTime(upgradeTime));
            BeginTime = DateTime.UtcNow;

            return(Error.Ok);
        }
Ejemplo n.º 3
0
        public override Error Execute()
        {
            ICity      city;
            IStructure structure;

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

            var maxConcurrentUpgradesResult = formula.CityMaxConcurrentBuildActions(type, ActionId, city, objectTypeFactory);

            if (maxConcurrentUpgradesResult != Error.Ok)
            {
                return(maxConcurrentUpgradesResult);
            }

            var stats = structureCsvFactory.GetBaseStats(structure.Type, (byte)(structure.Lvl + 1));

            if (stats == null)
            {
                return(Error.ObjectStructureNotFound);
            }

            cost = formula.StructureCost(city, stats);
            type = structure.Type;

            // layout requirement
            if (!requirementCsvFactory
                .GetLayoutRequirement(structure.Type, (byte)(structure.Lvl + 1))
                .Validate(structure, structure.Type, structure.PrimaryPosition.X, structure.PrimaryPosition.Y, structure.Size))
            {
                return(Error.LayoutNotFullfilled);
            }

            if (!structure.City.Resource.HasEnough(cost))
            {
                return(Error.ResourceNotEnough);
            }

            structure.City.BeginUpdate();
            structure.City.Resource.Subtract(cost);
            structure.City.EndUpdate();

            var buildTime = formula.BuildTime(structureCsvFactory.GetTime(structure.Type, (byte)(structure.Lvl + 1)), city, structure.Technologies);

            endTime   = SystemClock.Now.AddSeconds(CalculateTime(buildTime));
            BeginTime = SystemClock.Now;

            return(Error.Ok);
        }
Ejemplo n.º 4
0
        public override Error Execute()
        {
            ICity      city;
            IStructure structure;

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

            Technology     tech;
            TechnologyBase techBase;

            if (structure.Technologies.TryGetTechnology(techId, out tech))
            {
                techBase = technologyFactory.GetTechnologyBase(tech.Type, (byte)(tech.Level + 1));
            }
            else
            {
                techBase = technologyFactory.GetTechnologyBase(techId, 1);
            }

            if (techBase == null)
            {
                return(Error.ObjectNotFound);
            }

            if (!city.Resource.HasEnough(techBase.Resources))
            {
                return(Error.ResourceNotEnough);
            }

            city.BeginUpdate();
            city.Resource.Subtract(techBase.Resources);
            city.EndUpdate();

            BeginTime = DateTime.UtcNow;
            endTime   = DateTime.UtcNow.AddSeconds(CalculateTime(formula.BuildTime((int)techBase.Time, city, city.Technologies)));

            return(Error.Ok);
        }
Ejemplo n.º 5
0
        public override Error Execute()
        {
            ICity      city;
            IStructure structure;

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

            if (objectTypeFactory.IsStructureType("MainBuilding", structure))
            {
                return(Error.StructureUndowngradable);
            }

            if (objectTypeFactory.IsStructureType("NonUserDestroyable", structure))
            {
                return(Error.StructureUndowngradable);
            }

            if (objectTypeFactory.IsStructureType("Undestroyable", structure))
            {
                return(Error.StructureUndestroyable);
            }

            var buildTime = formula.BuildTime(structureCsvFactory.GetTime(structure.Type, (byte)(structure.Lvl + 1)), city, structure.Technologies)
                            .Clamp((int)TimeSpan.FromMinutes(3).TotalSeconds, (int)TimeSpan.FromHours(1).TotalSeconds);

            endTime   = DateTime.UtcNow.AddSeconds(CalculateTime(buildTime));
            BeginTime = DateTime.UtcNow;

            if (WorkerObject.WorkerId != structureId)
            {
                city.References.Add(structure, this);
            }

            return(Error.Ok);
        }
Ejemplo n.º 6
0
        public override Error Execute()
        {
            ICity city;
            ICity newCity;

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

            if (!CityManager.IsNameValid(cityName))
            {
                return(Error.CityNameInvalid);
            }

            if (!world.Regions.IsValidXandY(x, y))
            {
                return(Error.ActionInvalid);
            }

            // cost requirement uses town center lvl 1 for cost
            int    influencePoints, wagons;
            ushort wagonType = (ushort)objectTypeFactory.GetTypes("Wagon").First();

            formula.GetNewCityCost(city.Owner.GetCityCount(), out influencePoints, out wagons);
            if (city.Owner.Value < influencePoints && !Config.actions_ignore_requirements)
            {
                return(Error.ResourceNotEnough);
            }

            var totalWagons = city.DefaultTroop.Sum(f =>
            {
                if (f.Type != FormationType.Normal && f.Type != FormationType.Garrison)
                {
                    return(0);
                }

                return(f.ContainsKey(wagonType) ? f[wagonType] : 0);
            });

            if (totalWagons < wagons && !Config.actions_ignore_requirements)
            {
                return(Error.ResourceNotEnough);
            }

            var lockedRegions = world.Regions.LockMultitileRegions(x, y, formula.GetInitialCityRadius());

            if (!objectTypeFactory.IsTileType("CityStartTile", world.Regions.GetTileType(x, y)))
            {
                world.Regions.UnlockRegions(lockedRegions);
                return(Error.TileMismatch);
            }

            // check if tile is occupied
            if (world.Regions.GetObjectsInTile(x, y).Any(obj => obj is IStructure))
            {
                world.Regions.UnlockRegions(lockedRegions);
                return(Error.StructureExists);
            }

            // create new city
            lock (world.Lock)
            {
                // Verify city name is unique
                if (world.CityNameTaken(cityName))
                {
                    world.Regions.UnlockRegions(lockedRegions);
                    return(Error.CityNameTaken);
                }

                var cityPosition = new Position(x, y);

                // Creating New City
                procedure.CreateCity(cityFactory, city.Owner, cityName, 0, cityPosition, barbarianTribeManager, out newCity);

                world.Regions.SetTileType(x, y, 0, true);

                var mainBuilding = newCity.MainBuilding;

                // Take resource from the old city
                city.BeginUpdate();
                city.DefaultTroop.BeginUpdate();
                wagons -= city.DefaultTroop.RemoveUnit(FormationType.Normal, wagonType, (ushort)wagons);
                if (wagons > 0)
                {
                    city.DefaultTroop.RemoveUnit(FormationType.Garrison, wagonType, (ushort)wagons);
                }
                city.DefaultTroop.EndUpdate();
                city.EndUpdate();

                callbackProcedure.OnStructureUpgrade(mainBuilding);

                newStructureId = mainBuilding.ObjectId;
            }

            world.Regions.UnlockRegions(lockedRegions);

            newCityId = newCity.Id;

            // add to queue for completion
            int baseBuildTime = structureCsvFactory.GetBaseStats((ushort)objectTypeFactory.GetTypes("MainBuilding")[0], 1).BuildTime;

            EndTime   = DateTime.UtcNow.AddSeconds(CalculateTime(formula.BuildTime(baseBuildTime, city, city.Technologies)));
            BeginTime = DateTime.UtcNow;

            return(Error.Ok);
        }
Ejemplo n.º 7
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);
        }