Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added settlement growth rate function #58

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -38,7 +38,10 @@
import org.terasology.dynamicCities.buildings.components.ProductionChestComponent;
import org.terasology.dynamicCities.buildings.components.SettlementRefComponent;
import org.terasology.dynamicCities.buildings.events.OnSpawnDynamicStructureEvent;
import org.terasology.dynamicCities.construction.events.BufferBlockEvent;
import org.terasology.dynamicCities.construction.events.BuildingEntitySpawnedEvent;
import org.terasology.dynamicCities.construction.events.RequestRasterTargetEvent;
import org.terasology.dynamicCities.construction.events.SetBlockEvent;
import org.terasology.dynamicCities.construction.events.SpawnStructureBufferedEvent;
import org.terasology.dynamicCities.decoration.ColumnRasterizer;
import org.terasology.dynamicCities.decoration.DecorationRasterizer;
@@ -68,6 +71,7 @@
import org.terasology.dynamicCities.rasterizer.window.RectWindowRasterizer;
import org.terasology.dynamicCities.rasterizer.window.SimpleWindowRasterizer;
import org.terasology.dynamicCities.rasterizer.window.WindowRasterizer;
import org.terasology.dynamicCities.settlements.events.CheckBuildingForParcelEvent;
import org.terasology.dynamicCities.roads.RoadSegment;
import org.terasology.economy.components.MultiInvStorageComponent;
import org.terasology.entitySystem.entity.EntityManager;
@@ -92,6 +96,7 @@
import org.terasology.registry.CoreRegistry;
import org.terasology.registry.In;
import org.terasology.registry.Share;
import org.terasology.structureTemplates.components.CheckBlockRegionConditionComponent;
import org.terasology.structureTemplates.components.SpawnBlockRegionsComponent;
import org.terasology.structureTemplates.interfaces.StructureTemplateProvider;
import org.terasology.structureTemplates.util.BlockRegionTransform;
@@ -293,13 +298,13 @@ public int flatten(Rect2i area, int defaultHeight, Block filler) {
if (y <= meanHeight) {
for (int i = y; i <= meanHeight; i++) {
setPos.set(pos.x(), i, pos.y());
worldProvider.setBlock(setPos, filler);
worldProvider.getWorldEntity().send(new SetBlockEvent(setPos, filler));
}
}
if (y >= meanHeight) {
for (int i = y; i > meanHeight; i--) {
setPos.set(pos.x(), i, pos.y());
worldProvider.setBlock(setPos, air);
worldProvider.getWorldEntity().send(new SetBlockEvent(setPos, air));
}
}
}
@@ -340,25 +345,36 @@ public SurfaceHeightFacet sample(Rect2i area, int height) {
return surfaceHeightFacet;
}

/**
* Gets a random building according to {@link BuildingManager#getRandomBuildingOfZoneForCulture(String, Rect2i, CultureComponent)}
*
* @param event
* @param settlement
*/
@ReceiveEvent
public void checkBuildingForParcel(CheckBuildingForParcelEvent event, EntityRef settlement, CultureComponent
cultureComponent) {
String zone = event.dynParcel.getZone();
Rect2i shape = event.dynParcel.getShape();
event.building = buildingManager.getRandomBuildingOfZoneForCulture(zone, shape, cultureComponent);
}

//the standard strategy used in Cities and StaticCities module
public boolean buildParcel(DynParcel dynParcel, EntityRef settlement, CultureComponent cultureComponent) {
public boolean buildParcel(DynParcel dynParcel, EntityRef settlement) {
Region3i region = Region3i.createFromMinMax(new Vector3i(dynParcel.getShape().minX(), 255, dynParcel.getShape().minY()),
new Vector3i(dynParcel.getShape().maxX(), -255, dynParcel.getShape().maxY()));
if (!worldProvider.isRegionRelevant(region)) {
return false;
}
/**
* get the building or shrink parcel size if no fitting building was found.
*/
Optional<GenericBuildingComponent> buildingOptional;
GenericBuildingComponent building;
buildingOptional = buildingManager.getRandomBuildingOfZoneForCulture(dynParcel.getZone(), dynParcel.getShape(), cultureComponent);

if (!buildingOptional.isPresent()) {
CheckBuildingForParcelEvent event = new CheckBuildingForParcelEvent(dynParcel);
settlement.send(event);

if (!event.building.isPresent()) {
return false;
} else {
building = buildingOptional.get();
}

GenericBuildingComponent building = event.building.get();
if (building.isScaledDown) {
Vector2i difference = dynParcel.shape.size().sub(building.minSize).div(2);
dynParcel.shape = Rect2i.createFromMinAndMax(dynParcel.shape.min().add(difference), dynParcel.shape.max().sub(difference));
@@ -369,7 +385,9 @@ public boolean buildParcel(DynParcel dynParcel, EntityRef settlement, CultureCom
//Flatten the parcel area
dynParcel.height = flatten(dynParcel.shape, dynParcel.height);

RasterTarget rasterTarget = new BufferRasterTarget(blockBufferSystem, cityTheme, dynParcel.shape);
RequestRasterTargetEvent requestRasterTargetEvent = new RequestRasterTargetEvent(cityTheme, dynParcel.shape);
settlement.send(requestRasterTargetEvent);
RasterTarget rasterTarget = requestRasterTargetEvent.rasterTarget;
Rect2i shape = dynParcel.shape;
HeightMap hm = HeightMaps.constant(dynParcel.height);

@@ -647,15 +665,28 @@ public void onSpawnBlockRegions(SpawnStructureBufferedEvent event, EntityRef ent
block = transformation.transformBlock(block);
if (block.getBlockFamily() == blockManager.getBlockFamily("CoreBlocks:chest")) {
for (Vector3i pos : region) {
worldProvider.setBlock(pos, block);
entity.send(new SetBlockEvent(pos, block));
}
} else {
for (Vector3i pos : region) {
blockBufferSystem.saveBlock(pos, block);
entity.send(new BufferBlockEvent(pos, block));
}
}
}
}

@ReceiveEvent
public void onSetBlockEvent(SetBlockEvent event, EntityRef entity) {
worldProvider.setBlock(event.getPos(), event.block);
}

@ReceiveEvent
public void onBufferBlockEvent(BufferBlockEvent event, EntityRef entity) {
blockBufferSystem.saveBlock(event.getPos(), event.block);
}

@ReceiveEvent
public void onRequestRasterTargetEvent(RequestRasterTargetEvent event, EntityRef entity) {
event.rasterTarget = new BufferRasterTarget(blockBufferSystem, event.theme, event.shape);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2017 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.dynamicCities.construction.events;

import org.terasology.entitySystem.event.ConsumableEvent;
import org.terasology.math.geom.Vector3i;
import org.terasology.world.block.Block;

/**
* Sent when a building has been rasterized and a given block should be buffered
*/
public class BufferBlockEvent implements ConsumableEvent {
public final Block block;
private Vector3i pos = Vector3i.zero();
private boolean consumed;

public BufferBlockEvent(Vector3i pos, Block block) {
this.pos = new Vector3i(pos);
this.block = block;
}

@Override
public boolean isConsumed() {
return consumed;
}

@Override
public void consume() {
consumed = true;
}

public Vector3i getPos() {
return new Vector3i(pos);
}

public void setPos(Vector3i pos) {
this.pos.set(pos);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2017 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.dynamicCities.construction.events;

import org.terasology.cities.BlockTheme;
import org.terasology.cities.raster.RasterTarget;
import org.terasology.entitySystem.event.ConsumableEvent;
import org.terasology.math.geom.Rect2i;

/**
* Emitted when DynamicCities needs a {@link org.terasology.cities.raster.RasterTarget} for rasterizing buildings
*/
public class RequestRasterTargetEvent implements ConsumableEvent {
public RasterTarget rasterTarget;
public BlockTheme theme;
public Rect2i shape;
private boolean consumed;

public RequestRasterTargetEvent(BlockTheme theme, Rect2i shape) {
this.shape = shape;
this.theme = theme;
}

@Override
public boolean isConsumed() {
return consumed;
}

@Override
public void consume() {
consumed = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2017 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.dynamicCities.construction.events;

import org.terasology.entitySystem.event.ConsumableEvent;
import org.terasology.math.geom.Vector3i;
import org.terasology.world.block.Block;

/**
* Sent when a building has been rasterized and a given block should be set directly
*/
public class SetBlockEvent implements ConsumableEvent {
private boolean consumed;
public Block block;
private Vector3i pos;

public SetBlockEvent(Vector3i pos, Block block) {
this.pos = new Vector3i(pos);
this.block = block;
}

@Override
public boolean isConsumed() {
return consumed;
}

@Override
public void consume() {
consumed = true;
}

public Vector3i getPos() {
return new Vector3i(pos);
}

public void setPos(Vector3i pos) {
this.pos.set(pos);
}
}
Original file line number Diff line number Diff line change
@@ -52,7 +52,8 @@ public DistrictOverlay(EntityRef entityRef) {
@Override
public void render(Canvas canvas, Rect2f worldRect) {
/**
* Iterate through all known cities in the settlement manager and check if the boundaries of the screenRect are within city reach.
* Iterate through all known cities in the settlement manager and check if the boundaries of the screenRect are
* within city reach.
* Color rectangles of the district grid in a zone specific color.
*
*/
Original file line number Diff line number Diff line change
@@ -46,7 +46,9 @@
import org.terasology.dynamicCities.roads.RoadSegment;
import org.terasology.dynamicCities.settlements.components.ActiveSettlementComponent;
import org.terasology.dynamicCities.settlements.components.DistrictFacetComponent;
import org.terasology.dynamicCities.settlements.events.CheckBuildingSpawnPreconditionsEvent;
import org.terasology.dynamicCities.settlements.events.CheckSiteSuitabilityEvent;
import org.terasology.dynamicCities.settlements.events.CheckZoneNeededEvent;
import org.terasology.dynamicCities.settlements.events.SettlementFilterResult;
import org.terasology.dynamicCities.settlements.events.SettlementGrowthEvent;
import org.terasology.dynamicCities.settlements.events.SettlementRegisterEvent;
import org.terasology.dynamicCities.sites.SiteComponent;
@@ -132,7 +134,8 @@ public class SettlementEntityManager extends BaseComponentSystem {

private int minDistance = 500;
private int settlementMaxRadius = 150;
private int cyclesLeft = 2; // 1 cycle = approx. 20 seconds
private int cyclesLeft; // 1 cycle = approx. 20 seconds
private int cyclesBeforeGrowth = 2;
private Random rng;
private Multimap<String, String> roadCache = MultimapBuilder.hashKeys().hashSetValues().build();

@@ -144,6 +147,7 @@ public void postBegin() {
settlementEntities = settlementCachingSystem.getSettlementCacheEntity();
long seed = regionEntityManager.hashCode() & 0x921233;
rng = new FastRandom(seed);
cyclesLeft = cyclesBeforeGrowth;

}

@@ -161,15 +165,22 @@ public void onWorldTimeEvent(WorldTimeEvent worldTimeEvent, EntityRef entityRef)
}
Iterable<EntityRef> uncheckedSiteRegions = entityManager.getEntitiesWith(SiteComponent.class);
for (EntityRef siteRegion : uncheckedSiteRegions) {
boolean checkDistance = checkMinDistance(siteRegion);
boolean checkBuildArea = checkBuildArea(siteRegion);
if (checkDistance && regionEntityManager.checkSidesLoadedNear(siteRegion)
&& checkBuildArea) {
EntityRef newSettlement = createSettlement(siteRegion);
newSettlement.send(new SettlementRegisterEvent());
siteRegion.removeComponent(SiteComponent.class);
} else if (!checkDistance || !checkBuildArea) {
siteRegion.removeComponent(SiteComponent.class);
CheckSiteSuitabilityEvent checkSiteSuitabilityEvent = new CheckSiteSuitabilityEvent();
siteRegion.send(checkSiteSuitabilityEvent);
switch (checkSiteSuitabilityEvent.getResult()) {
case SUITABLE:
EntityRef newSettlement = createSettlement(siteRegion);
newSettlement.send(new SettlementRegisterEvent());
siteRegion.removeComponent(SiteComponent.class);
break;

case UNSUITABLE:
siteRegion.removeComponent(SiteComponent.class);
break;

case UNKNOWN:
// not enough information, do nothing
break;
}
}
Iterable<EntityRef> activeSettlements = entityManager.getEntitiesWith(BuildingQueue.class);
@@ -178,9 +189,54 @@ public void onWorldTimeEvent(WorldTimeEvent worldTimeEvent, EntityRef entityRef)
build(settlement);
buildRoads(settlement);
}
cyclesLeft = 2;
cyclesLeft = cyclesBeforeGrowth;
}

/**
* Checks the provided region entity for suitability as a settlement in response to a CheckSiteSuitabilityEvent
*
* The default behavior will check that the region satisfies default distance and build area thresholds, and also
* ensures that the region's "sides" have been loaded. This can be extended by registering a new event handler
* with the same signature and annotation, but a lower priority. It can also be disabled completely by using a
* higher priority and consuming the event in your handler.
*
* @param event
* @param siteRegion
*/
@ReceiveEvent(components = {SiteComponent.class})
public void filterSettlement(CheckSiteSuitabilityEvent event, EntityRef siteRegion) {
boolean checkDistance = checkMinDistance(siteRegion);
boolean checkBuildArea = checkBuildArea(siteRegion);
if (checkDistance && regionEntityManager.checkSidesLoadedNear(siteRegion) && checkBuildArea) {
event.setResult(SettlementFilterResult.SUITABLE);
} else if (!checkDistance || !checkBuildArea) {
event.setResult(SettlementFilterResult.UNSUITABLE);
}
}

/**
* Checks whether the settlement needs the given zone
*
* The default behavior checks the culture need for the zone, multiplies that by the population, then subtracts
* the areaPerZone for the given zone according to the ParcelList. If that "allowed zone area" is greater than
* the minimum area of all buildings for that zone, the check passes.
*
* @param event
* @param settlement
* @param culture
* @param population
* @param parcels
*/
@ReceiveEvent
public void checkZoneNeeded(CheckZoneNeededEvent event, EntityRef settlement, CultureComponent culture,
PopulationComponent population,
ParcelList parcels) {
Map<String, List<Vector2i>> minMaxSizes = buildingManager.getMinMaxSizePerZone();
double minimumZoneArea = minMaxSizes.get(event.zone).get(0).x * minMaxSizes.get(event.zone).get(0).y;
double need = culture.getBuildingNeedsForZone(event.zone);
double allowedZoneArea = need * population.populationSize - parcels.areaPerZone.getOrDefault(event.zone, 0);
event.needed = allowedZoneArea > minimumZoneArea;
}

public boolean checkMinDistance(EntityRef siteRegion) {
Vector3f sitePos = siteRegion.getComponent(LocationComponent.class).getLocalPosition();
@@ -367,19 +423,17 @@ private boolean checkBuildArea(EntityRef siteRegion) {

public void build(EntityRef settlement) {
BuildingQueue buildingQueue = settlement.getComponent(BuildingQueue.class);
CultureComponent cultureComponent = settlement.getComponent(CultureComponent.class);
ParcelList parcelList = settlement.getComponent(ParcelList.class);
Set<DynParcel> removedParcels = new HashSet<>();
Set<DynParcel> parcelsInQueue = buildingQueue.buildingQueue;


for (DynParcel dynParcel : parcelsInQueue) {
Rect2i expandedParcel = dynParcel.shape.expand(SettlementConstants.MAX_TREE_RADIUS, SettlementConstants.MAX_TREE_RADIUS);
if (!treeRemovalSystem.removeTreesInRegions(expandedParcel)) {
continue;
}

if (constructer.buildParcel(dynParcel, settlement, cultureComponent)) {
if (constructer.buildParcel(dynParcel, settlement)) {
removedParcels.add(dynParcel);
}
}
@@ -392,6 +446,19 @@ public void build(EntityRef settlement) {
settlement.saveComponent(parcelList);
}

/**
* Attempts to place new parcels for the settlement as needed
*
* For each zone type, this settlement sends a {@link CheckZoneNeededEvent}. If the event's
* `needed` field is true, a parcel is placed for that zone if possible. This method will then continue to place
* parcels for that zone as needed, sending a new event each time until one finally returns false or until the
* SettlementEntityManager is unable to place a needed parcel. In that case, the city's radius is increased and
* process for that particular zone type stops.
*
* Also inflates the population capacity based on the area of each residential zone in the settlement
*
* @param settlement
*/
public void growSettlement(EntityRef settlement) {
if (blockBufferSystem.getBlockBufferSize() > SettlementConstants.BLOCKBUFFER_SIZE) {
return;
@@ -408,7 +475,6 @@ public void growSettlement(EntityRef settlement) {
int maxIterations = 500;
int buildingSpawned = 0;
List<String> zones = new ArrayList<>(buildingManager.getZones());
Map<String, List<Vector2i>> minMaxSizes = buildingManager.getMinMaxSizePerZone();

if (populationComponent == null) {
logger.error("No population found or was uninitialised!");
@@ -443,13 +509,13 @@ public void growSettlement(EntityRef settlement) {

for (String zone : zones) {
//Checks if the demand for a building of that zone is enough
CheckBuildingSpawnPreconditionsEvent preconditionsEvent = new CheckBuildingSpawnPreconditionsEvent(zone);
settlement.send(preconditionsEvent);
if (!preconditionsEvent.isHandled) {
preconditionsEvent.check = true;
}
while (cultureComponent.getBuildingNeedsForZone(zone) * populationComponent.populationSize - parcels.areaPerZone.getOrDefault(zone, 0) > minMaxSizes.get(zone).get(0).x * minMaxSizes.get(zone).get(0).y
&& buildingSpawned < SettlementConstants.MAX_BUILDINGSPAWN && preconditionsEvent.check) {
while (buildingSpawned < SettlementConstants.MAX_BUILDINGSPAWN) {
CheckZoneNeededEvent preconditionsEvent = new CheckZoneNeededEvent(zone);
settlement.send(preconditionsEvent);
if (!preconditionsEvent.needed) {
break;
}

Optional<DynParcel> parcelOptional = placeParcel(center, zone, parcels, buildingQueue, districtFacetComponent, maxIterations);
//Grow settlement radius if no valid area was found
if (!parcelOptional.isPresent() && parcels.cityRadius < SettlementConstants.SETTLEMENT_RADIUS) {
@@ -648,5 +714,13 @@ private boolean checkIfTerrainIsBuildable(Rect2i area) {
return true;
}

/**
* This function sets the number of cycles the city must wait before growing. Each cycle usually lasts about 20 seconds.
* @param cycles The number of cycles to wait.
*/

public void setCityCyclesBeforeGrowth(int cycles){
skaldarnar marked this conversation as resolved.
Show resolved Hide resolved
cyclesBeforeGrowth = cycles;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2017 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.dynamicCities.settlements.events;

import org.terasology.dynamicCities.buildings.GenericBuildingComponent;
import org.terasology.dynamicCities.parcels.DynParcel;
import org.terasology.entitySystem.event.ConsumableEvent;

import java.util.Optional;

/**
* Sent to check which building should be used for a given parcel
*/
public class CheckBuildingForParcelEvent implements ConsumableEvent {
public DynParcel dynParcel;
public Optional<GenericBuildingComponent> building;
private boolean consumed = false;

public CheckBuildingForParcelEvent(DynParcel dynParcel) {
this.dynParcel = dynParcel;
}

@Override
public boolean isConsumed() {
return consumed;
}

@Override
public void consume() {
consumed = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2017 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.dynamicCities.settlements.events;

import org.terasology.entitySystem.event.ConsumableEvent;

/**
* Issued when the settlement manager wants to know if a site is suitable for creating a settlement.
*/
public class CheckSiteSuitabilityEvent implements ConsumableEvent {
private SettlementFilterResult result = SettlementFilterResult.UNKNOWN;
private boolean consumed;

@Override
public boolean isConsumed() {
return consumed;
}

@Override
public void consume() {
this.consumed = true;
}

public SettlementFilterResult getResult() {
return result;
}

public void setResult(SettlementFilterResult result) {
this.result = result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2016 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.dynamicCities.settlements.events;


import org.terasology.entitySystem.event.ConsumableEvent;

/**
* Sent to check whether an entity needs a parcel of the given zone type
*/
public class CheckZoneNeededEvent implements ConsumableEvent {
public boolean needed;
public String zone;
private boolean consumed;

public CheckZoneNeededEvent(String zone) {
this.zone = zone;
}

@Override
public boolean isConsumed() {
return consumed;
}

@Override
public void consume() {
this.consumed = true;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 MovingBlocks
* Copyright 2017 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,16 +15,8 @@
*/
package org.terasology.dynamicCities.settlements.events;


import org.terasology.entitySystem.event.Event;

public class CheckBuildingSpawnPreconditionsEvent implements Event {
public boolean check;
public boolean isHandled;
public String zone;

public CheckBuildingSpawnPreconditionsEvent(String zone) {
this.zone = zone;
}
public CheckBuildingSpawnPreconditionsEvent() {}
public enum SettlementFilterResult {
SUITABLE,
UNSUITABLE,
UNKNOWN
}