This repository has been archived by the owner on Nov 9, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented sponge block functionality.
Dry sponges absorb water that can be found within a 7 block taxicab distance. Due to the specific implementation, a taxicab block iterator has been added to help assist in the more complex calculation of which blocks to absorb. The iterator has been designed for reusability.
- Loading branch information
1 parent
87fa006
commit 6e86a71
Showing
5 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
src/main/java/net/glowstone/block/blocktype/BlockSponge.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package net.glowstone.block.blocktype; | ||
|
||
import com.google.common.collect.Sets; | ||
import net.glowstone.block.GlowBlock; | ||
import net.glowstone.block.GlowBlockState; | ||
import net.glowstone.entity.GlowPlayer; | ||
import net.glowstone.util.BlockMaterialValidator; | ||
import net.glowstone.util.TaxicabBlockIterator; | ||
import org.bukkit.Material; | ||
import org.bukkit.SpongeType; | ||
import org.bukkit.block.BlockFace; | ||
import org.bukkit.inventory.ItemStack; | ||
import org.bukkit.material.MaterialData; | ||
import org.bukkit.material.Sponge; | ||
import org.bukkit.util.Vector; | ||
|
||
import java.util.Set; | ||
|
||
public class BlockSponge extends BlockType { | ||
|
||
private static final Set<Material> WATER_MATERIALS = Sets.immutableEnumSet(Material.WATER, Material.STATIONARY_WATER); | ||
|
||
@Override | ||
public void placeBlock(GlowPlayer player, GlowBlockState state, BlockFace face, ItemStack holding, Vector clickedLoc) { | ||
// TODO: Move this to a new method when physics works and run this on neighbour change too. | ||
|
||
MaterialData data = holding.getData(); | ||
if (!(data instanceof Sponge)) { | ||
warnMaterialData(Sponge.class, data); | ||
return; | ||
} | ||
Sponge sponge = (Sponge) data; | ||
|
||
if (sponge.getType() == SpongeType.NORMAL) { | ||
GlowBlock block = state.getBlock(); | ||
|
||
TaxicabBlockIterator iterator = new TaxicabBlockIterator(block); | ||
iterator.setMaxDistance(7); | ||
iterator.setMaxBlocks(66); | ||
iterator.setValidator(new BlockMaterialValidator(WATER_MATERIALS)); | ||
|
||
if (iterator.hasNext()) { | ||
sponge = sponge.clone(); | ||
sponge.setType(SpongeType.WET); | ||
do { | ||
iterator.next().setType(Material.AIR); | ||
} while (iterator.hasNext()); | ||
} | ||
} | ||
|
||
state.setType(Material.SPONGE); | ||
state.setData(sponge); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/net/glowstone/util/BlockMaterialValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package net.glowstone.util; | ||
|
||
import org.bukkit.Material; | ||
import org.bukkit.block.Block; | ||
|
||
import java.util.Set; | ||
|
||
public class BlockMaterialValidator implements Validator<Block> { | ||
|
||
private final Set<Material> validMaterials; | ||
|
||
public BlockMaterialValidator(Set<Material> validMaterials) { | ||
this.validMaterials = validMaterials; | ||
} | ||
|
||
@Override | ||
public boolean isValid(Block block) { | ||
return validMaterials.contains(block.getType()); | ||
} | ||
|
||
} |
102 changes: 102 additions & 0 deletions
102
src/main/java/net/glowstone/util/TaxicabBlockIterator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package net.glowstone.util; | ||
|
||
import org.bukkit.block.Block; | ||
import org.bukkit.block.BlockFace; | ||
|
||
import java.util.*; | ||
|
||
public class TaxicabBlockIterator implements Iterator<Block> { | ||
|
||
private static final BlockFace[] VALID_FACES = new BlockFace[]{ | ||
BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST | ||
}; | ||
|
||
private final Queue<Object> pendingAnalysis = new LinkedList<>(); | ||
private final Queue<Block> nextValidBlocks = new LinkedList<>(); | ||
private final Set<Block> usedBlocks = new HashSet<>(); | ||
private int currentDistance = 1; | ||
private int validBlockCount = 0; | ||
|
||
private int maxDistance = Integer.MAX_VALUE; | ||
private int maxBlocks = Integer.MAX_VALUE; | ||
private Validator<Block> validator; | ||
|
||
public TaxicabBlockIterator(Block origin) { | ||
pendingAnalysis.add(origin); | ||
pendingAnalysis.add(DistanceMarker.INSTANCE); | ||
usedBlocks.add(origin); | ||
} | ||
|
||
public void setMaxDistance(int maxDistance) { | ||
this.maxDistance = maxDistance; | ||
} | ||
|
||
public void setMaxBlocks(int maxBlocks) { | ||
this.maxBlocks = maxBlocks; | ||
} | ||
|
||
public void setValidator(Validator<Block> validator) { | ||
this.validator = validator; | ||
} | ||
|
||
private boolean isValid(Block block) { | ||
return validator == null || validator.isValid(block); | ||
} | ||
|
||
@Override | ||
public boolean hasNext() { | ||
if (validBlockCount >= maxBlocks) { | ||
return false; | ||
} | ||
|
||
// Keep going till the valid block queue contains something, we reach the distance limit, or we empty the pending analysis queue. | ||
// Note that the pending analysis queue will always contain at least one element: the end of distance marker. | ||
while (nextValidBlocks.isEmpty() && currentDistance <= maxDistance && pendingAnalysis.size() >= 2) { | ||
Object object = pendingAnalysis.remove(); | ||
|
||
// If we find the end of distance marker, we'll increase the distance, and then we'll re-add it to the end. | ||
if (object == DistanceMarker.INSTANCE) { | ||
pendingAnalysis.add(object); | ||
currentDistance++; | ||
continue; | ||
} | ||
|
||
// If it wasn't the EoD marker, it must be a block. We'll look now for valid blocks around it. | ||
Block block = (Block) object; | ||
for (BlockFace face : VALID_FACES) { | ||
Block near = block.getRelative(face); | ||
|
||
// Only analyse the block if we haven't checked it yet. | ||
if (usedBlocks.add(near) && isValid(near)) { | ||
nextValidBlocks.add(near); | ||
pendingAnalysis.add(near); | ||
} | ||
} | ||
} | ||
|
||
return !nextValidBlocks.isEmpty(); | ||
} | ||
|
||
@Override | ||
public Block next() { | ||
if (!hasNext()) { | ||
throw new NoSuchElementException(); | ||
} | ||
validBlockCount++; | ||
return nextValidBlocks.remove(); | ||
} | ||
|
||
@Override | ||
public void remove() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
private static final class DistanceMarker { | ||
|
||
public static final DistanceMarker INSTANCE = new DistanceMarker(); | ||
|
||
private DistanceMarker() { | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package net.glowstone.util; | ||
|
||
/** | ||
* Represents a simple validator to compare objects on a true / false basis. | ||
* @param <E> The type of object to compare. | ||
*/ | ||
public interface Validator<E> { | ||
|
||
/** | ||
* Determines if the supplied object is valid as oer the implementation | ||
* rules defined. | ||
* @param object The object to validate | ||
* @return True if valid, false otherwise | ||
*/ | ||
boolean isValid(E object); | ||
|
||
} |