-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added custom blocks API with initial oraxen integration
- Loading branch information
Showing
13 changed files
with
689 additions
and
1 deletion.
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
eco-api/src/main/java/com/willfp/eco/core/blocks/Blocks.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,149 @@ | ||
package com.willfp.eco.core.blocks; | ||
|
||
import com.willfp.eco.core.blocks.impl.EmptyTestableBlock; | ||
import com.willfp.eco.core.blocks.impl.MaterialTestableBlock; | ||
import com.willfp.eco.core.blocks.impl.UnrestrictedMaterialTestableBlock; | ||
import com.willfp.eco.core.blocks.provider.BlockProvider; | ||
import com.willfp.eco.util.NamespacedKeyUtils; | ||
import org.bukkit.Location; | ||
import org.bukkit.Material; | ||
import org.bukkit.NamespacedKey; | ||
import org.bukkit.block.Block; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.HashSet; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
/** | ||
* Class to manage all custom and vanilla blocks. | ||
*/ | ||
public final class Blocks { | ||
/** | ||
* All entities. | ||
*/ | ||
private static final Map<NamespacedKey, TestableBlock> REGISTRY = new ConcurrentHashMap<>(); | ||
|
||
/** | ||
* All block providers. | ||
*/ | ||
private static final Map<String, BlockProvider> PROVIDERS = new ConcurrentHashMap<>(); | ||
|
||
/** | ||
* The lookup handler. | ||
*/ | ||
private static final BlocksLookupHandler BLOCKS_LOOKUP_HANDLER = new BlocksLookupHandler(Blocks::doParse); | ||
|
||
/** | ||
* Register a new custom block. | ||
* | ||
* @param key The key of the block. | ||
* @param block The block. | ||
*/ | ||
public static void registerCustomBlock(@NotNull final NamespacedKey key, | ||
@NotNull final TestableBlock block) { | ||
REGISTRY.put(key, block); | ||
} | ||
|
||
/** | ||
* Register a new block provider. | ||
* | ||
* @param provider The provider. | ||
*/ | ||
public static void registerBlockProvider(@NotNull final BlockProvider provider) { | ||
PROVIDERS.put(provider.getNamespace(), provider); | ||
} | ||
|
||
/** | ||
* Remove a block. | ||
* | ||
* @param key The key of the block. | ||
*/ | ||
public static void removeCustomBlock(@NotNull final NamespacedKey key) { | ||
REGISTRY.remove(key); | ||
} | ||
|
||
/** | ||
* This is the backbone of the eco block system. | ||
* <p> | ||
* You can look up a TestableBlock for any material or custom block, | ||
* and it will return it. | ||
* <p> | ||
* If you want to get a Block instance from this, then just call | ||
* {@link TestableBlock#place(Location)}. | ||
* | ||
* @param key The lookup string. | ||
* @return The testable block, or an empty testable block if not found. | ||
*/ | ||
@NotNull | ||
public static TestableBlock lookup(@NotNull final String key) { | ||
return BLOCKS_LOOKUP_HANDLER.parseKey(key); | ||
} | ||
|
||
@NotNull | ||
private static TestableBlock doParse(@NotNull final String[] args) { | ||
if (args.length == 0) { | ||
return new EmptyTestableBlock(); | ||
} | ||
|
||
String[] split = args[0].toLowerCase().split(":"); | ||
if (split.length == 1) { | ||
if (args[0].startsWith("*")) { | ||
Material type = Material.getMaterial(args[0].substring(1)); | ||
return (type == null) ? new EmptyTestableBlock() : new UnrestrictedMaterialTestableBlock(type); | ||
} else { | ||
Material type = Material.getMaterial(args[0].toUpperCase()); | ||
return (type == null) ? new EmptyTestableBlock() : new MaterialTestableBlock(type); | ||
} | ||
} | ||
|
||
NamespacedKey namespacedKey = NamespacedKeyUtils.create(split[0], split[1]); | ||
TestableBlock block = REGISTRY.get(namespacedKey); | ||
|
||
if (block != null) { | ||
return block; | ||
} | ||
|
||
BlockProvider provider = PROVIDERS.get(split[0]); | ||
if (provider == null) { | ||
return new EmptyTestableBlock(); | ||
} | ||
|
||
block = provider.provideForKey(split[1]); | ||
if (block == null) { | ||
return new EmptyTestableBlock(); | ||
} | ||
|
||
registerCustomBlock(namespacedKey, block); | ||
return block; | ||
} | ||
|
||
/** | ||
* Get if block is a custom block. | ||
* | ||
* @param block The block to check. | ||
* @return If is custom. | ||
*/ | ||
public static boolean isCustomBlock(@NotNull final Block block) { | ||
for (TestableBlock testable : REGISTRY.values()) { | ||
if (testable.matches(block)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Get all registered custom blocks. | ||
* | ||
* @return A set of all blocks. | ||
*/ | ||
public static Set<TestableBlock> getCustomBlocks() { | ||
return new HashSet<>(REGISTRY.values()); | ||
} | ||
|
||
private Blocks() { | ||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
eco-api/src/main/java/com/willfp/eco/core/blocks/BlocksLookupHandler.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,48 @@ | ||
package com.willfp.eco.core.blocks; | ||
|
||
import com.willfp.eco.core.blocks.impl.EmptyTestableBlock; | ||
import com.willfp.eco.core.blocks.impl.GroupedTestableBlocks; | ||
import com.willfp.eco.core.lookup.LookupHandler; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Collection; | ||
import java.util.function.Function; | ||
|
||
/** | ||
* Handle block lookup strings. | ||
*/ | ||
public class BlocksLookupHandler implements LookupHandler<TestableBlock> { | ||
/** | ||
* The parser. | ||
*/ | ||
private final Function<String[], @NotNull TestableBlock> parser; | ||
|
||
/** | ||
* Create new lookup handler. | ||
* | ||
* @param parser The parser. | ||
*/ | ||
public BlocksLookupHandler(@NotNull final Function<String[], @NotNull TestableBlock> parser) { | ||
this.parser = parser; | ||
} | ||
|
||
@Override | ||
public @NotNull TestableBlock parse(@NotNull final String[] args) { | ||
return parser.apply(args); | ||
} | ||
|
||
@Override | ||
public boolean validate(@NotNull final TestableBlock object) { | ||
return !(object instanceof EmptyTestableBlock); | ||
} | ||
|
||
@Override | ||
public @NotNull TestableBlock getFailsafe() { | ||
return new EmptyTestableBlock(); | ||
} | ||
|
||
@Override | ||
public @NotNull TestableBlock join(@NotNull final Collection<TestableBlock> options) { | ||
return new GroupedTestableBlocks(options); | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
eco-api/src/main/java/com/willfp/eco/core/blocks/CustomBlock.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,84 @@ | ||
package com.willfp.eco.core.blocks; | ||
|
||
import org.apache.commons.lang.Validate; | ||
import org.bukkit.Location; | ||
import org.bukkit.NamespacedKey; | ||
import org.bukkit.block.Block; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.function.Function; | ||
import java.util.function.Predicate; | ||
|
||
/** | ||
* A custom block has 3 components. | ||
* | ||
* <ul> | ||
* <li>The key to identify it</li> | ||
* <li>The test to check if any block is this custom block</li> | ||
* <li>The supplier to spawn the custom {@link Block}</li> | ||
* </ul> | ||
*/ | ||
public class CustomBlock implements TestableBlock { | ||
/** | ||
* The key. | ||
*/ | ||
private final NamespacedKey key; | ||
|
||
/** | ||
* The test for block to pass. | ||
*/ | ||
private final Predicate<@NotNull Block> test; | ||
|
||
/** | ||
* The provider to spawn the block. | ||
*/ | ||
private final Function<Location, Block> provider; | ||
|
||
/** | ||
* Create a new custom block. | ||
* | ||
* @param key The block key. | ||
* @param test The test. | ||
* @param provider The provider to spawn the block. | ||
*/ | ||
public CustomBlock(@NotNull final NamespacedKey key, | ||
@NotNull final Predicate<@NotNull Block> test, | ||
@NotNull final Function<Location, Block> provider) { | ||
this.key = key; | ||
this.test = test; | ||
this.provider = provider; | ||
} | ||
|
||
@Override | ||
public boolean matches(@Nullable final Block other) { | ||
if (other == null) { | ||
return false; | ||
} | ||
|
||
return test.test(other); | ||
} | ||
|
||
@Override | ||
public @NotNull Block place(@NotNull final Location location) { | ||
Validate.notNull(location.getWorld()); | ||
|
||
return provider.apply(location); | ||
} | ||
|
||
/** | ||
* Register the block. | ||
*/ | ||
public void register() { | ||
Blocks.registerCustomBlock(this.getKey(), this); | ||
} | ||
|
||
/** | ||
* Get the key. | ||
* | ||
* @return The key. | ||
*/ | ||
public NamespacedKey getKey() { | ||
return this.key; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
eco-api/src/main/java/com/willfp/eco/core/blocks/TestableBlock.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,31 @@ | ||
package com.willfp.eco.core.blocks; | ||
|
||
import com.willfp.eco.core.lookup.Testable; | ||
import org.bukkit.Location; | ||
import org.bukkit.block.Block; | ||
import org.bukkit.entity.Entity; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** | ||
* A block with a test. | ||
*/ | ||
public interface TestableBlock extends Testable<Block> { | ||
/** | ||
* If a Block matches the test. | ||
* | ||
* @param other The other block. | ||
* @return If the block matches. | ||
*/ | ||
@Override | ||
boolean matches(@Nullable Block other); | ||
|
||
/** | ||
* Place the block. | ||
* | ||
* @param location The location. | ||
* @return The block. | ||
*/ | ||
@NotNull | ||
Block place(@NotNull Location location); | ||
} |
29 changes: 29 additions & 0 deletions
29
eco-api/src/main/java/com/willfp/eco/core/blocks/impl/EmptyTestableBlock.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,29 @@ | ||
package com.willfp.eco.core.blocks.impl; | ||
|
||
import com.willfp.eco.core.blocks.TestableBlock; | ||
import org.bukkit.Location; | ||
import org.bukkit.block.Block; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** | ||
* Empty block. | ||
*/ | ||
public class EmptyTestableBlock implements TestableBlock { | ||
/** | ||
* Create a new empty testable block. | ||
*/ | ||
public EmptyTestableBlock() { | ||
|
||
} | ||
|
||
@Override | ||
public boolean matches(@Nullable final Block other) { | ||
return false; | ||
} | ||
|
||
@Override | ||
public @NotNull Block place(@NotNull final Location location) { | ||
return location.getBlock(); | ||
} | ||
} |
Oops, something went wrong.