mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
implement StateFunction
This commit is contained in:
@@ -16,4 +16,8 @@ public interface BlockState extends Handle {
|
||||
BlockData getBlockData();
|
||||
|
||||
boolean update(boolean applyPhysics);
|
||||
|
||||
default void applyState(String state) {
|
||||
// Do nothing by default.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.dfsek.terra.api.platform.block.state;
|
||||
|
||||
import com.dfsek.terra.api.platform.world.entity.EntityType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface MobSpawner extends BlockState {
|
||||
EntityType getSpawnedType();
|
||||
|
||||
void setSpawnedType(@NotNull EntityType creatureType);
|
||||
|
||||
int getDelay();
|
||||
|
||||
void setDelay(int delay);
|
||||
|
||||
int getMinSpawnDelay();
|
||||
|
||||
void setMinSpawnDelay(int delay);
|
||||
|
||||
int getMaxSpawnDelay();
|
||||
|
||||
void setMaxSpawnDelay(int delay);
|
||||
|
||||
int getSpawnCount();
|
||||
|
||||
void setSpawnCount(int spawnCount);
|
||||
|
||||
int getMaxNearbyEntities();
|
||||
|
||||
void setMaxNearbyEntities(int maxNearbyEntities);
|
||||
|
||||
int getRequiredPlayerRange();
|
||||
|
||||
void setRequiredPlayerRange(int requiredPlayerRange);
|
||||
|
||||
int getSpawnRange();
|
||||
|
||||
void setSpawnRange(int spawnRange);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.dfsek.terra.api.platform.block.state;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SerialState {
|
||||
protected final Map<String, Property<?>> properties = new HashMap<>();
|
||||
|
||||
public SerialState() {
|
||||
}
|
||||
|
||||
public static Map<String, String> parse(String props) {
|
||||
String[] sep = props.split(",");
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for(String item : sep) {
|
||||
map.put(item.substring(0, item.indexOf('=')), item.substring(item.indexOf('=') + 1));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void checkExists(String prop) {
|
||||
if(!properties.containsKey(prop)) throw new IllegalArgumentException("No such property \"" + prop + "\"");
|
||||
}
|
||||
|
||||
private void checkType(Class<?> clazz, Object o, String id) {
|
||||
if(!clazz.isInstance(o))
|
||||
throw new IllegalArgumentException("Invalid data for property " + id + ": " + o);
|
||||
}
|
||||
|
||||
public void setProperty(String id, Object value) {
|
||||
checkExists(id);
|
||||
Property<?> prop = properties.get(id);
|
||||
checkType(prop.getValueClass(), value, id);
|
||||
prop.setValue(value);
|
||||
}
|
||||
|
||||
public int getInteger(String id) {
|
||||
checkExists(id);
|
||||
Property<?> prop = properties.get(id);
|
||||
checkType(Integer.class, prop.getValue(), id);
|
||||
return (Integer) prop.getValue();
|
||||
}
|
||||
|
||||
public String getString(String id) {
|
||||
checkExists(id);
|
||||
Property<?> prop = properties.get(id);
|
||||
checkType(String.class, prop.getValue(), id);
|
||||
return (String) prop.getValue();
|
||||
}
|
||||
|
||||
public long getLong(String id) {
|
||||
checkExists(id);
|
||||
Property<?> prop = properties.get(id);
|
||||
checkType(Long.class, prop.getValue(), id);
|
||||
return (Long) prop.getValue();
|
||||
}
|
||||
|
||||
public boolean getBoolean(String id) {
|
||||
checkExists(id);
|
||||
Property<?> prop = properties.get(id);
|
||||
checkType(Boolean.class, prop.getValue(), id);
|
||||
return (Boolean) prop.getValue();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(String id, Class<T> clazz) {
|
||||
checkExists(id);
|
||||
Property<?> prop = properties.get(id);
|
||||
checkType(clazz, prop.getValue(), id);
|
||||
return (T) prop.getValue();
|
||||
}
|
||||
|
||||
protected static class Property<T> {
|
||||
private final Class<T> clazz;
|
||||
private Object value;
|
||||
|
||||
public Property(Class<T> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public Class<T> getValueClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getValue() {
|
||||
return (T) value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.dfsek.terra.api.platform.block.state;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface Sign extends BlockState {
|
||||
@NotNull String[] getLines();
|
||||
|
||||
@NotNull String getLine(int index) throws IndexOutOfBoundsException;
|
||||
|
||||
void setLine(int index, @NotNull String line) throws IndexOutOfBoundsException;
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.dfsek.terra.api.structures.script.builders.MarkFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.PullFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.RandomFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.RecursionsFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.StateFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.StructureFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.UnaryNumberFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.builders.UnaryStringFunctionBuilder;
|
||||
@@ -63,6 +64,7 @@ public class StructureScript {
|
||||
.registerFunction("entity", new EntityFunctionBuilder(main))
|
||||
.registerFunction("getBiome", new BiomeFunctionBuilder(main))
|
||||
.registerFunction("getBlock", new CheckBlockFunctionBuilder())
|
||||
.registerFunction("state", new StateFunctionBuilder(main))
|
||||
.registerFunction("print", new UnaryStringFunctionBuilder(string -> Debug.info("[" + tempID + "] " + string)))
|
||||
.registerFunction("abs", new UnaryNumberFunctionBuilder(number -> FastMath.abs(number.doubleValue())))
|
||||
.registerFunction("pow", new BinaryNumberFunctionBuilder((number, number2) -> FastMath.pow(number.doubleValue(), number2.doubleValue())))
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.dfsek.terra.api.structures.script.builders;
|
||||
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.structures.parser.exceptions.ParseException;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.functions.StateFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StateFunctionBuilder implements FunctionBuilder<StateFunction> {
|
||||
private final TerraPlugin main;
|
||||
|
||||
public StateFunctionBuilder(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public StateFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
|
||||
if(argumentList.size() < 4) throw new ParseException("Expected data", position);
|
||||
return new StateFunction((Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), (Returnable<String>) argumentList.get(3), main, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int argNumber() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Returnable.ReturnType getArgument(int position) {
|
||||
switch(position) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
return Returnable.ReturnType.NUMBER;
|
||||
case 3:
|
||||
return Returnable.ReturnType.STRING;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.dfsek.terra.api.structures.script.functions;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.structures.parser.lang.ImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.Function;
|
||||
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedStateManipulator;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
public class StateFunction implements Function<Void> {
|
||||
private final Returnable<String> data;
|
||||
private final Returnable<Number> x, y, z;
|
||||
private final Position position;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public StateFunction(Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Returnable<String> data, TerraPlugin main, Position position) {
|
||||
this.position = position;
|
||||
this.main = main;
|
||||
this.data = data;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void apply(ImplementationArguments implementationArguments) {
|
||||
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
|
||||
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue());
|
||||
RotationUtil.rotateVector(xz, arguments.getRotation());
|
||||
|
||||
arguments.getBuffer().addItem(new BufferedStateManipulator(main, data.apply(implementationArguments)), new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments).intValue(), FastMath.roundToInt(xz.getZ())));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnType returnType() {
|
||||
return ReturnType.VOID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.dfsek.terra.api.structures.structure.buffer.items;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
|
||||
public class BufferedStateManipulator implements BufferedItem {
|
||||
private final TerraPlugin main;
|
||||
private final String data;
|
||||
|
||||
public BufferedStateManipulator(TerraPlugin main, String state) {
|
||||
this.main = main;
|
||||
this.data = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
BlockState state = origin.getBlock().getState();
|
||||
try {
|
||||
state.applyState(data);
|
||||
state.update(false);
|
||||
} catch(ClassCastException e) {
|
||||
main.getLogger().warning("Could not apply BlockState at " + origin + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.dfsek.terra.api.structures.structure.buffer.items.state;
|
||||
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.items.BufferedItem;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class BufferedStateManipulator<T extends BlockState> implements BufferedItem {
|
||||
private final TerraPlugin main;
|
||||
|
||||
protected BufferedStateManipulator(TerraPlugin main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paste(Location origin) {
|
||||
BlockState state = origin.getBlock().getState();
|
||||
try {
|
||||
apply((T) state);
|
||||
} catch(ClassCastException e) {
|
||||
main.getLogger().warning("Could not find expected BlockState at " + origin + "; found " + origin.getBlock().getBlockData().getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void apply(T state);
|
||||
}
|
||||
@@ -22,13 +22,11 @@ public class TerraTree implements Tree {
|
||||
|
||||
@Override
|
||||
public synchronized boolean plant(Location location, Random random) {
|
||||
structure.get(random).execute(location.clone().add(0, yOffset, 0), random, Rotation.fromDegrees(90 * random.nextInt(4)));
|
||||
return true;
|
||||
return structure.get(random).execute(location.clone().add(0, yOffset, 0), random, Rotation.fromDegrees(90 * random.nextInt(4)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialSet getSpawnable() {
|
||||
return spawnable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ public class EventListener implements Listener {
|
||||
TreeRegistry registry = c.getTreeRegistry();
|
||||
Tree tree = registry.get(TREE_TYPE_STRING_TRANSFORMER.translate(e.getSpecies()));
|
||||
Debug.info("Overrode tree type: " + e.getSpecies());
|
||||
org.bukkit.Location location = e.getLocation().subtract(0, 1, 0);
|
||||
org.bukkit.Location location = e.getLocation();
|
||||
if(!tree.plant(new Location(bukkit, location.getX(), location.getY(), location.getZ()), new FastRandom())) block.setBlockData(data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.dfsek.terra.api.platform.block.state.BlockState;
|
||||
import com.dfsek.terra.bukkit.world.block.BukkitBlock;
|
||||
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockData;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
public class BukkitBlockState implements BlockState {
|
||||
private final org.bukkit.block.BlockState delegate;
|
||||
@@ -16,6 +17,7 @@ public class BukkitBlockState implements BlockState {
|
||||
|
||||
public static BukkitBlockState newInstance(org.bukkit.block.BlockState block) {
|
||||
if(block instanceof Container) return new BukkitContainer((Container) block);
|
||||
if(block instanceof Sign) return new BukkitSign((Sign) block);
|
||||
return new BukkitBlockState(block);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.dfsek.terra.api.platform.inventory.Inventory;
|
||||
import com.dfsek.terra.bukkit.world.inventory.BukkitInventory;
|
||||
|
||||
public class BukkitContainer extends BukkitBlockState implements Container {
|
||||
|
||||
protected BukkitContainer(org.bukkit.block.Container block) {
|
||||
super(block);
|
||||
}
|
||||
@@ -13,4 +14,5 @@ public class BukkitContainer extends BukkitBlockState implements Container {
|
||||
public Inventory getInventory() {
|
||||
return new BukkitInventory(((org.bukkit.block.Container) getHandle()).getInventory());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.bukkit.world.block.state;
|
||||
|
||||
import com.dfsek.terra.api.platform.block.state.SerialState;
|
||||
import com.dfsek.terra.api.platform.block.state.Sign;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BukkitSign extends BukkitBlockState implements Sign {
|
||||
protected BukkitSign(org.bukkit.block.Sign block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String[] getLines() {
|
||||
return ((org.bukkit.block.Sign) getHandle()).getLines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getLine(int index) throws IndexOutOfBoundsException {
|
||||
return ((org.bukkit.block.Sign) getHandle()).getLine(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLine(int index, @NotNull String line) throws IndexOutOfBoundsException {
|
||||
((org.bukkit.block.Sign) getHandle()).setLine(index, line);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyState(String state) {
|
||||
SerialState.parse(state).forEach((k, v) -> setLine(Integer.parseInt(k), v));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user