Example #1
0
        public override Error Validate(string[] parms)
        {
            ushort tileType = world.Regions.GetTileType(x, y);

            if (!objectTypeFactory.IsTileType("CityStartTile", tileType))
            {
                return(Error.TileMismatch);
            }
            return(Error.Ok);
        }
Example #2
0
        private void LoadRegions(string tmxFiles)
        {
            foreach (var mapFilePath in Directory.GetFiles(tmxFiles, "*.tmx", SearchOption.AllDirectories))
            {
                using (var xmlReader = XmlReader.Create(File.OpenRead(mapFilePath), new XmlReaderSettings {
                    DtdProcessing = DtdProcessing.Parse, XmlResolver = null
                }))
                {
                    var document = new XPathDocument(xmlReader);
                    var nav      = document.CreateNavigator();

                    var nodeIter = nav.Select("/map/layer/data");

                    var region = new MapGenRegion();

                    //load tile info
                    while (nodeIter.MoveNext())
                    {
                        Debug.Assert(nodeIter.Current != null, "nodeIter.Current != null");

                        byte[] zippedMap = Convert.FromBase64String(nodeIter.Current.Value);
                        using (var gzip = new GZipStream(new MemoryStream(zippedMap), CompressionMode.Decompress))
                        {
                            var tmpMap = new byte[TMX_REGION_WIDTH * TMX_REGION_HEIGHT * sizeof(int)];
                            gzip.Read(tmpMap, 0, TMX_REGION_WIDTH * TMX_REGION_HEIGHT * sizeof(int));

                            int cnt = 0;
                            for (int i = 0; i < tmpMap.Length; i += sizeof(int))
                            {
                                var tileId = (ushort)(BitConverter.ToInt32(tmpMap, i) - 1);

                                if (objectTypeFactory.IsTileType("CityStartTile", tileId))
                                {
                                    tileId = 0;
                                }

                                region.Map[cnt++] = tileId;
                            }
                        }

                        break; //not supporting multi layer
                    }

                    regions.Add(region);
                }
            }

            if (regions.Count == 0)
            {
                Console.Out.WriteLine("No maps were found. They should be in the /map/ folder");
                Environment.Exit(-1);
            }
        }
Example #3
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);
        }
Example #4
0
        private void RoadCreate(Session session, Packet packet)
        {
            var reply = new Packet(packet);

            uint x;
            uint y;
            uint cityId;

            try
            {
                cityId = packet.GetUInt32();
                x      = packet.GetUInt32();
                y      = packet.GetUInt32();
            }
            catch (Exception)
            {
                ReplyError(session, packet, Error.Unexpected);
                return;
            }

            if (!world.Regions.IsValidXandY(x, y))
            {
                ReplyError(session, packet, Error.Unexpected);
                return;
            }

            // Make sure there is no structure at this point that has no road requirement
            if (world.Regions.GetObjectsInTile(x, y).Any(
                    s =>
                    s is IStructure &&
                    objectTypeFactory.IsStructureType("NoRoadRequired", (IStructure)s)))
            {
                ReplyError(session, packet, Error.StructureExists);
                return;
            }

            ICity city;

            locker.Lock(cityId, out city).Do(() =>
            {
                if (city == null)
                {
                    ReplyError(session, packet, Error.CityNotFound);
                    return;
                }

                // Make sure user is building road within city walls
                if (tileLocator.TileDistance(city.PrimaryPosition, 1, new Position(x, y), 1) >= city.Radius)
                {
                    ReplyError(session, packet, Error.NotWithinWalls);
                    return;
                }

                world.Regions.LockRegion(x, y);

                // Make sure this tile is not already a road
                if (world.Roads.IsRoad(x, y))
                {
                    world.Regions.UnlockRegion(x, y);
                    ReplyError(session, packet, Error.RoadAlreadyExists);
                    return;
                }

                // Make sure there is a road next to this tile
                bool hasRoad = false;

                foreach (var position in tileLocator.ForeachRadius(x, y, 1, false))
                {
                    if ((world.Roads.IsRoad(position.X, position.Y) &&
                         !world.Regions.GetObjectsInTile(position.X, position.Y).Any(s => s is IStructure && s != city.MainBuilding)))
                    {
                        hasRoad = true;
                        break;
                    }
                }

                if (!hasRoad)
                {
                    world.Regions.UnlockRegion(x, y);
                    ReplyError(session, packet, Error.RoadNotAround);
                    return;
                }

                if (objectTypeFactory.IsTileType("TileResource", world.Regions.GetTileType(x, y)))
                {
                    world.Regions.UnlockRegion(x, y);
                    ReplyError(session, packet, Error.TileMismatch);
                    return;
                }

                world.Roads.CreateRoad(x, y, city.RoadTheme);

                world.Regions.UnlockRegion(x, y);

                session.Write(reply);
            });
        }