public static void RegisterBuilidingModelResourceProductionComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var buildingResourceProduction = new TypedComponents <BuildingResourceProduction[]>( BuildingModelResourceProductionComponent, () => System.Array.Empty <BuildingResourceProduction>()); var buildingModelsInitializer = new BuildingModelsInitializer(worldRules.BuildingModels, buildingResourceProduction); var resources = worldRules.Resources; int maxDistance = 16; buildingModelsInitializer.Set( Farm, new BuildingResourceProduction(resources[Resources.Food], 1, maxDistance), new BuildingResourceProduction(resources[Resources.Population], -1, maxDistance)); buildingModelsInitializer.Set( House, new BuildingResourceProduction(resources[Resources.Food], -2, maxDistance), new BuildingResourceProduction(resources[Resources.Population], 4, maxDistance)); buildingModelsInitializer.Set( ConvenienceStore, new BuildingResourceProduction(resources[Resources.Food], -5, maxDistance), new BuildingResourceProduction(resources[Resources.Population], -4, maxDistance)); worldRules.BuildingModels.Extend(buildingResourceProduction); }
public void OnNewWorld(World world) { Contract.Requires(world != null); this.buildingLocation = world.Buildings.GetTypedComponents <Vector>(Buildings.LocationComponent); this.buildingTransportLink = world.Buildings.GetMutableTypedComponents <Vector?>(Buildings.TransportLinkComponent); }
public Action <World> Execute(IWorldView worldView) { Contract.Requires(worldView != null); List <(Vector, int)> posBuildingModelToBuild = worldView.GetZoneMapView() .GetAllPositions() .Select(p => (p, this.buildingConstructorVoter.Vote(p))) .Where(posBuildingModelTuple => posBuildingModelTuple.Item2 != BuildingModels.NoModel) .ToList(); return((world) => { IMap <int> buildingMap = world.GetBuildingMap(); IMap <int> zoneMap = world.GetZoneMap(); AnonymousEntities buildings = world.Buildings; TypedComponents <int> buildingVariant = buildings.GetMutableTypedComponents <int>(BuildingVariants.Component); TypedComponents <int> buildingModels = buildings.GetMutableTypedComponents <int>(Buildings.BuildingModelComponent); TypedComponents <Vector> buildingLocations = buildings.GetMutableTypedComponents <Vector>(Buildings.LocationComponent); Random random = world.Rules.Random; foreach (var posBuildingModelTuple in posBuildingModelToBuild .Where((posBuildingModelTuple) => buildingMap[posBuildingModelTuple.Item1] == MapTypes.NoBuilding)) { int buildingId = buildings.Register(); buildingVariant[buildingId] = random.Next(); buildingLocations[buildingId] = posBuildingModelTuple.Item1; buildingModels[buildingId] = posBuildingModelTuple.Item2; buildingMap[posBuildingModelTuple.Item1] = buildingId; } }); }
/// <summary> /// The connections of each building. /// The connection refers to a building id. /// Connections are bi-directional, in other words, if a building A has a connection to a building B, then building B must have a connection to building A. /// Building connections are used to satisfy the building supply chain. /// For example, a building with a model "house" consuming "food" will need to be connected to a building with a model producing "food" such as a "farm". /// There can be multiple connections for the same resource, until the constraint is satisfied, considering that resource productions have associated quantities. /// </summary> public static void RegisterBuildingConnections(WorldRules worldRules) { Contract.Requires(worldRules != null); var connectionsComponent = new TypedComponents <ISet <int> >(ConnectionsComponent, () => new HashSet <int>()); worldRules.BuildingComponents.Add(connectionsComponent.Name, connectionsComponent); }
/// <summary> /// The transport link of each building. /// The transport link is the position on the map where all path finding related to the building starts and ends. /// </summary> public static void RegisterBuildingTransportLink(WorldRules worldRules) { Contract.Requires(worldRules != null); var connectionsComponent = new TypedComponents <Vector?>(TransportLinkComponent, () => null); worldRules.BuildingComponents.Add(connectionsComponent.Name, connectionsComponent); }
/// <summary> /// The location of each building. /// </summary> public static void RegisterBuildingLocation(WorldRules worldRules) { Contract.Requires(worldRules != null); var connectionsComponent = new TypedComponents <Vector>(LocationComponent, () => new Vector(-1, -1)); worldRules.BuildingComponents.Add(connectionsComponent.Name, connectionsComponent); }
/// <summary> /// The building model of each building, such a house, or a shop. /// Much of the building attributes are defined in the model. /// This is an implementation of the flywheel design pattern. /// </summary> public static void RegisterBuildingModelComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var buildingModelComponent = new TypedComponents <int>(BuildingModelComponent, () => BuildingModels.NoModel); worldRules.BuildingComponents.Add(buildingModelComponent.Name, buildingModelComponent); }
public static void RegisterBuildingComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); TypedComponents <int> typedComponents = new TypedComponents <int>(Component, worldRules.Random.Next); worldRules.BuildingComponents.Add(typedComponents.Name, typedComponents); }
/// <summary> /// A zone component to define legal terrains corresponding to each zone. By default, the only legal terrain is Land. /// </summary> public static void RegisterZonableTerrainsComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var zones = worldRules.Zones; var terrains = worldRules.Terrains; ZonableOnlyOn zonableOnlyOnLand = new ZonableOnlyOn(terrains[Terrains.Land]); TypedComponents <IZonableTerrain> zonableTerrains = new TypedComponents <IZonableTerrain>(ZonableTerrains, () => zonableOnlyOnLand); zonableTerrains[zones[Zones.Empty]] = new AlwaysZonable(); zones.Extend(zonableTerrains); }
public static void RegisterManuallyZonableComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); NamedEntities zones = worldRules.Zones; var manuallyZonable = new TypedComponents <bool>(ManuallyZonable, () => false); manuallyZonable[zones[Zones.Commercial]] = true; manuallyZonable[zones[Zones.Farmland]] = true; manuallyZonable[zones[Zones.Residential]] = true; manuallyZonable[zones[Zones.Road]] = true; zones.Extend(manuallyZonable); }
public static void RegisterBuildingModelZoneComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var buildingModelZoneComponent = new TypedComponents <int>(BuildingModelZoneComponent, () => - 1); var buildingModels = worldRules.BuildingModels; var zones = worldRules.Zones; buildingModelZoneComponent[buildingModels[Farm]] = zones[Zones.Farmland]; buildingModelZoneComponent[buildingModels[House]] = zones[Zones.Residential]; buildingModelZoneComponent[buildingModels[ConvenienceStore]] = zones[Zones.Commercial]; worldRules.BuildingModels.Extend(buildingModelZoneComponent); }
/// <summary> /// The default building model for each zone. This is used as estimate when computing how empty zones will develop. /// </summary> public static void RegisterZonesDefaultBuildingModel(WorldRules worldRules) { Contract.Requires(worldRules != null); var zones = worldRules.Zones; var buildingModels = worldRules.BuildingModels; TypedComponents <int> defaultBuildingModels = new TypedComponents <int>(DefaultBuildingModel, () => BuildingModels.NoModel); defaultBuildingModels[zones[Zones.Farmland]] = buildingModels[BuildingModels.Farm]; defaultBuildingModels[zones[Zones.Residential]] = buildingModels[BuildingModels.House]; defaultBuildingModels[zones[Zones.Commercial]] = buildingModels[BuildingModels.ConvenienceStore]; zones.Extend(defaultBuildingModels); }
internal BuildingModelsInitializer(NamedEntities buildingModels, TypedComponents <BuildingResourceProduction[]> buildingResourceProduction) { this.buildingModels = buildingModels; this.buildingResourceProduction = buildingResourceProduction; }