public IEnumerable <ISimpleGameObject> GetObjectsWithin(uint x, uint y, int radius) { var list = new List <ISimpleGameObject>(); foreach (var position in tileLocator.ForeachTile(x, y, radius)) { if (position.X < WorldWidth && position.Y < WorldHeight) { list.AddRange(GetObjectsInTile(position.X, position.Y)); } } return(list); }
public Error SetRoadTheme(ICity city, string id) { if (!HasTheme(city.Owner, id)) { return(Error.ThemeNotPurchased); } var previousTheme = city.RoadTheme; city.BeginUpdate(); city.RoadTheme = id; city.EndUpdate(); var lockedRegions = regionManager.LockRegions(tileLocator.ForeachTile(city.PrimaryPosition.X, city.PrimaryPosition.Y, city.Radius)); roadManager.ChangeRoadTheme(city, previousTheme, id); regionManager.UnlockRegions(lockedRegions); return(Error.Ok); }
private void GenerateCityLocationsAndResources() { var cityLocations = new HashSet <Position>(); do { var newCityPosition = new Position((uint)random.Next(10, WIDTH - 10), (uint)random.Next(10, HEIGHT - 10)); var tooCloseToOtherCity = tileLocator.ForeachTile(newCityPosition.X, newCityPosition.Y, MIN_DIST_BETWEEN_CITIES).Any(cityLocations.Contains); if (tooCloseToOtherCity) { continue; } cityResourceTileGenerator.GenerateResource(newCityPosition, map); cityLocations.Add(newCityPosition); map[newCityPosition.X, newCityPosition.Y] = CITY_TILE; }while (cityLocations.Count < TOTAL_PLAYERS); }
public bool TooCloseToCities(Position position, byte size) { return(tileLocator.ForeachMultitile(position.X, position.Y, size) .SelectMany(eachPosition => tileLocator.ForeachTile(eachPosition.X, eachPosition.Y, MIN_DISTANCE_AWAY_FROM_CITIES)) .Any(positionToCheck => cityLocationsByPosition.Contains(positionToCheck))); }
public void Callback(object custom) { ICity city; IStructure mainBuilding; if (!world.TryGetObjects(cityId, out city)) { throw new Exception("City not found"); } bool shouldReturn = locker.Lock(GetForeignTroopLockList, new object[] { city }, city) .Do(() => { if (city == null) { return(true); } // if local city is in battle, try again later if (city.Battle != null) { Reschedule(SHORT_RETRY); return(true); } // send all stationed from other players back if (city.Troops.StationedHere().Any()) { IEnumerable <ITroopStub> stationedTroops = new List <ITroopStub>(city.Troops.StationedHere()); foreach (var stub in stationedTroops) { if (RemoveForeignTroop(stub) != Error.Ok) { logger.Error(String.Format("removeForeignTroop failed! cityid[{0}] stubid[{1}]", city.Id, stub.StationTroopId)); } } } // If city is being targetted by an assignment, try again later var reader = dbManager.ReaderQuery(string.Format("SELECT id FROM `{0}` WHERE `location_type` = 'City' AND `location_id` = @locationId LIMIT 1", Assignment.DB_TABLE), new[] { new DbColumn("locationId", city.Id, DbType.UInt32) }); bool beingTargetted = reader.HasRows; reader.Close(); if (beingTargetted) { Reschedule(LONG_RETRY); return(true); } return(false); }); if (shouldReturn) { return; } shouldReturn = locker.Lock(GetLocalTroopLockList, new object[] { city }, city) .Do(() => { if (city.TryGetStructure(1, out mainBuilding)) { // don't continue unless all troops are either idle or stationed if (city.TroopObjects.Any() || city.Troops.Any(s => s.State != TroopState.Idle && s.State != TroopState.Stationed)) { Reschedule(LONG_RETRY); return(true); } // starve all troops) city.Troops.Starve(100, true); if (city.Troops.Upkeep > 0) { Reschedule(LONG_RETRY); return(true); } // remove all buildings except mainbuilding if (city.Any(structure => !structure.IsMainBuilding)) { city.BeginUpdate(); foreach (IStructure structure in new List <IStructure>(city).Where(structure => structure.IsBlocked == 0 && !structure.IsMainBuilding)) { structure.BeginUpdate(); world.Regions.Remove(structure); city.ScheduleRemove(structure, false); structure.EndUpdate(); } city.EndUpdate(); Reschedule(SHORT_RETRY); return(true); } // remove all customized tiles foreach (var position in tileLocator.ForeachTile(city.PrimaryPosition.X, city.PrimaryPosition.Y, city.Radius)) { world.Regions.RevertTileType(position.X, position.Y, true); } } return(false); }); if (shouldReturn) { return; } // remove all remaining passive action if (city.TryGetStructure(1, out mainBuilding)) { foreach (var passiveAction in new List <PassiveAction>(city.Worker.PassiveActions.Values)) { passiveAction.WorkerRemoved(false); } } locker.Lock(cityId, out city).Do(() => { if (city.Notifications.Count > 0) { Reschedule(SHORT_RETRY); return; } // remove mainbuilding if (city.TryGetStructure(1, out mainBuilding)) { // remove default troop city.Troops.Remove(1); // remove city from the region world.Regions.MiniMapRegions.Remove(city); mainBuilding.BeginUpdate(); world.Regions.Remove(mainBuilding); city.ScheduleRemove(mainBuilding, false); mainBuilding.EndUpdate(); Reschedule(SHORT_RETRY); return; } // in the case of the OjectRemoveAction for mainbuilding is still there if (city.Worker.PassiveActions.Count > 0) { Reschedule(SHORT_RETRY); return; } logger.Info(string.Format("Player {0}:{1} City {2}:{3} Lvl {4} is deleted.", city.Owner.Name, city.Owner.PlayerId, city.Name, city.Id, city.Lvl)); world.Cities.Remove(city); }); }
public override Error Execute() { ICity city; IStructure lumbermill; IForest forest; if (!world.TryGetObjects(cityId, lumbermillId, out city, out lumbermill) || !forestManager.TryGetValue(forestId, out forest)) { return(Error.ObjectNotFound); } // Count number of camps and verify there's enough space left int campCount = city.Count(s => objectTypeFactory.IsStructureType("ForestCamp", s)); if (campCount >= 5) { return(Error.ForestCampMaxReached); } // Make sure some labors are being put in if (labors <= 0) { return(Error.LaborNotEnough); } // Make sure we have the specified number of laborers int currentInUsedLabor = lumbermill.City.Where(s => objectTypeFactory.IsStructureType("ForestCamp", s)).Sum(x => x.Stats.Labor); if (formula.GetLumbermillMaxLabor(lumbermill) < labors + currentInUsedLabor) { return(Error.LaborOverflow); } // Make sure it's within the limit of a forest camp if (labors > formula.GetForestCampMaxLabor(lumbermill)) { return(Error.ForestCampMaxLaborReached); } // Make sure this user is not already milking this forest. if (forest.Count(obj => obj.City == city) > 0) { return(Error.AlreadyInForest); } // Cost requirement Resource cost = formula.StructureCost(city, structureCsvFactory.GetBaseStats(campType, 1)); // Add labor count to the total cost cost.Labor += labors; if (!city.Resource.HasEnough(cost)) { return(Error.ResourceNotEnough); } // find an open space around the forest uint emptyX = 0; uint emptyY = 0; foreach (var position in tileLocator.ForeachTile(forest.PrimaryPosition.X, forest.PrimaryPosition.Y, 1, false).Reverse()) { // Make sure it's not taken if (world.Regions.GetObjectsInTile(position.X, position.Y).Any()) { continue; } emptyX = position.X; emptyY = position.Y; break; } if (emptyX == 0 || emptyY == 0) { return(Error.ForestFull); } world.Regions.LockRegion(emptyX, emptyY); // add structure to the map IStructure structure = city.CreateStructure(campType, 0, emptyX, emptyY); structure.BeginUpdate(); structure["Rate"] = 0; // Set initial rate for camp structure.Stats.Labor = labors; city.BeginUpdate(); city.Resource.Subtract(cost); city.EndUpdate(); if (!world.Regions.Add(structure)) { city.ScheduleRemove(structure, false); city.BeginUpdate(); city.Resource.Add(cost); city.EndUpdate(); structure.EndUpdate(); world.Regions.UnlockRegion(emptyX, emptyY); return(Error.MapFull); } structure.EndUpdate(); campId = structure.ObjectId; forest.BeginUpdate(); forest.AddLumberjack(structure); forest.RecalculateForest(); forest.EndUpdate(); lumbermill.BeginUpdate(); lumbermill["Labor"] = formula.GetForestCampLaborerString(lumbermill); lumbermill.EndUpdate(); // add to queue for completion var campBuildTime = structureCsvFactory.GetTime(campType, 1); var actionEndTime = formula.GetLumbermillCampBuildTime(campBuildTime, lumbermill, forest, tileLocator); endTime = SystemClock.Now.AddSeconds(CalculateTime(actionEndTime)); BeginTime = SystemClock.Now; city.References.Add(structure, this); world.Regions.UnlockRegion(emptyX, emptyY); return(Error.Ok); }