コード例 #1
0
        private void CreateInitialCity(Session session, Packet packet)
        {
            locker.Lock(session.Player).Do(() =>
            {
                string cityName, playerName = null, playerHash = null;
                byte method;
                try
                {
                    cityName = packet.GetString().Trim();
                    method   = packet.GetByte();
                    if (method == 1)
                    {
                        playerName = packet.GetString();
                        playerHash = packet.GetString();
                        if (playerName.Length == 0 || playerHash.Length == 0)
                        {
                            ReplyError(session, packet, Error.PlayerNotFound);
                            return;
                        }
                    }
                }
                catch (Exception)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                // Verify city name is valid
                if (!CityManager.IsNameValid(cityName))
                {
                    ReplyError(session, packet, Error.CityNameInvalid);
                    return;
                }

                ICity city;

                lock (world.Lock)
                {
                    ILocationStrategy strategy;
                    if (method == 1)
                    {
                        uint playerId;
                        if (!world.FindPlayerId(playerName, out playerId))
                        {
                            ReplyError(session, packet, Error.PlayerNotFound);
                            return;
                        }

                        var player = world.Players[playerId];
                        if (String.Compare(player.PlayerHash, playerHash, StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            ReplyError(session, packet, Error.PlayerHashNotFound);
                            return;
                        }
                        strategy = locationStrategyFactory.CreateCityTileNextToFriendLocationStrategy(Config.friend_invite_radius, player);
                    }
                    else
                    {
                        strategy = locationStrategyFactory.CreateCityTileNextAvailableLocationStrategy();
                    }

                    // Verify city name is unique
                    if (world.CityNameTaken(cityName))
                    {
                        ReplyError(session, packet, Error.CityNameTaken);
                        return;
                    }

                    Position cityPosition;
                    var locationStrategyResult = strategy.NextLocation(out cityPosition);

                    if (locationStrategyResult != Error.Ok)
                    {
                        ReplyError(session, packet, locationStrategyResult);
                        return;
                    }

                    procedure.CreateCity(cityFactory, session.Player, cityName, 1, cityPosition, barbarianTribeManager, out city);
                }

                procedure.InitCity(city, callbackProcedure, actionFactory);

                var reply     = new Packet(packet);
                reply.Option |= (ushort)Packet.Options.Compressed;
                PacketHelper.AddLoginToPacket(session, themeManager, reply);
                SubscribeDefaultChannels(session, session.Player);
                session.Write(reply);
            });
        }
コード例 #2
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);
        }