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); }); }
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); }