Skip to content

Commit

Permalink
this build range logic feels more right
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanhendriks committed Oct 5, 2016
1 parent ccd4627 commit b28b151
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public PlacingStructureMouse(BattleField battleField, PlacementBuildableEntity p

@Override
public void leftClicked() {
if (!isAllCoordinatesForEntityToPlacePassableAndWithinReach()) return;
if (!canPlaceEntity()) return;

// tell battlefield of the created entity
battleField.entityPlacedOnMap(
Expand Down Expand Up @@ -92,44 +92,56 @@ public void render(Graphics graphics) {

placeableMapCoordinateCandidate.distance = constructingEntityCoordinate.distance(coordinate);

graphics.setColor(Colors.WHITE);
SlickUtils.drawLine(graphics, coordinate, constructingEntityCoordinate);
// render the lines when debug info is true
if (Game.DEBUG_INFO) {
graphics.setColor(Colors.WHITE);
SlickUtils.drawLine(graphics, coordinate, constructingEntityCoordinate);
}

// still placeable? good. Final (expensive) check -> any other units that may block this?
if (isPlaceable) {
EntitiesSet entitiesAtMapCoordinate = entityRepository.findAliveEntitiesOfTypeAtVector(absoluteMapCoordinate, EntityType.STRUCTURE, EntityType.UNIT);
isPlaceable = entitiesAtMapCoordinate.isEmpty();
}
placeableMapCoordinateCandidate.isPassable = isPlaceable;

if (!isPlaceable) {
placeableMapCoordinateCandidate.placeableState = PlaceableState.BLOCKED;
}
}

float maxDistance = entityWhoConstructsIt.getEntityData().buildRange; // from center of the structure that built this entity (to place)

for (PlaceableMapCoordinateCandidate pmcc : mapCoordinatesForEntityToPlace) {
if (!pmcc.isPassable) continue; // not worth evaluating distance
pmcc.isWithinReach = pmcc.distance < maxDistance;
if (pmcc.placeableState != PlaceableState.PLACEABLE) continue;
if (pmcc.distance > maxDistance) {
pmcc.placeableState = PlaceableState.OUT_OF_REACH;
}
}

boolean canPlaceEntity = canPlaceEntity();

// Render stuff!
for (PlaceableMapCoordinateCandidate placeableMapCoordinateCandidate : mapCoordinatesForEntityToPlace) {
Coordinate absoluteMapCoordinate = placeableMapCoordinateCandidate.mapCoordinate.toCoordinate();
Coordinate coordinate = battleField.translateAbsoluteMapCoordinateToViewportCoordinate(absoluteMapCoordinate);

if (placeableMapCoordinateCandidate.isPassable) {
if (placeableMapCoordinateCandidate.isWithinReach) {
graphics.setColor(Colors.GREEN_ALPHA_128);
} else {
graphics.setColor(Colors.YELLOW_ALPHA_128);
}
if (canPlaceEntity) {
graphics.setColor(Colors.GREEN_ALPHA_128);
} else {
if (placeableMapCoordinateCandidate.isWithinReach) {
graphics.setColor(Colors.RED_ALPHA_128);
} else {
graphics.setColor(Colors.DARK_RED_ALPHA_128);
switch (placeableMapCoordinateCandidate.placeableState) {
case PLACEABLE:
graphics.setColor(Colors.GREEN_ALPHA_128);
break;
case BLOCKED:
graphics.setColor(Colors.RED_ALPHA_128);
break;
case OUT_OF_REACH:
graphics.setColor(Colors.YELLOW_ALPHA_128);
break;
}
}


graphics.fillRect(coordinate.getXAsInt(), coordinate.getYAsInt(), Game.TILE_SIZE, Game.TILE_SIZE);
}
}
Expand All @@ -152,7 +164,7 @@ public void movedTo(Vector2D coordinates) {
mapCoordinatesForEntityToPlace =
allMapCoordinates
.stream()
.map(mapCoordinate -> new PlaceableMapCoordinateCandidate(mapCoordinate, false))
.map(mapCoordinate -> new PlaceableMapCoordinateCandidate(mapCoordinate, PlaceableState.PLACEABLE))
.collect(toList());

}
Expand All @@ -176,8 +188,14 @@ public String toString() {
'}';
}

public boolean isAllCoordinatesForEntityToPlacePassableAndWithinReach() {
return this.mapCoordinatesForEntityToPlace.stream().allMatch(c -> c.isPassable && c.isWithinReach);
public boolean canPlaceEntity() {
// blocked == not good
// passable == good
// out of reach, but one passable == good
boolean blocked = this.mapCoordinatesForEntityToPlace.stream().anyMatch(c -> c.placeableState == PlaceableState.BLOCKED);
if (blocked) return false;

return this.mapCoordinatesForEntityToPlace.stream().anyMatch(c -> c.placeableState == PlaceableState.PLACEABLE);
}

/**
Expand Down Expand Up @@ -212,13 +230,18 @@ private Entity findClosestStructureOfPlayer(Coordinate coordinate) {
private class PlaceableMapCoordinateCandidate {

public MapCoordinate mapCoordinate;
public boolean isPassable = false;
public boolean isWithinReach = true;
public PlaceableState placeableState;
public float distance = 99999;

public PlaceableMapCoordinateCandidate(MapCoordinate mapCoordinate, boolean passable) {
public PlaceableMapCoordinateCandidate(MapCoordinate mapCoordinate, PlaceableState state) {
this.mapCoordinate = mapCoordinate;
this.isPassable = passable;
this.placeableState = state;
}
}

enum PlaceableState {
PLACEABLE,
BLOCKED,
OUT_OF_REACH
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class EntityData {
private float chop = -1f;
private float halfChop = -1f;
public float buildTimeInSeconds = 5.0F;
public float buildRange = 208; // 6 * 32 + half a tile
public float buildRange = Game.HALF_TILE + (3 * Game.TILE_SIZE);

public EntityType type;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,11 @@ public void render(Graphics graphics, int x, int y) {
graphics.drawImage(sprite, x, y);

if (Game.DEBUG_INFO) {
// render build-range
Vector2D halfSize = getHalfSize();
Circle circle = new Circle(x + halfSize.getXAsInt(), y + halfSize.getYAsInt(), entityData.buildRange);
graphics.setColor(Colors.YELLOW_ALPHA_32);
ShapeRenderer.fill(circle);

MapCoordinate mapCoordinate = coordinate.toMapCoordinate();
SlickUtils.drawShadowedText(
graphics,
Colors.WHITE,
"" + mapCoordinate.getXAsInt() + "," + mapCoordinate.getYAsInt(),
x,
y);
}
}

Expand Down

0 comments on commit b28b151

Please sign in to comment.