mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-20 03:44:23 +01:00
Trees can now have mismatched trunks and leaves, and added support for trees added by mods with no explicit mapping
This commit is contained in:
parent
138b9e19b4
commit
1a211095ae
4 changed files with 195 additions and 55 deletions
|
@ -25,6 +25,7 @@ import net.minecraft.block.entity.BeehiveBlockEntity;
|
||||||
import net.minecraft.entity.ItemEntity;
|
import net.minecraft.entity.ItemEntity;
|
||||||
import net.minecraft.entity.passive.BeeEntity;
|
import net.minecraft.entity.passive.BeeEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.particle.BlockStateParticleEffect;
|
import net.minecraft.particle.BlockStateParticleEffect;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -65,7 +66,7 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
||||||
@Override
|
@Override
|
||||||
public boolean canApply(Pony player, Pos data) {
|
public boolean canApply(Pony player, Pos data) {
|
||||||
BlockPos pos = data.pos();
|
BlockPos pos = data.pos();
|
||||||
TreeType tree = TreeType.get(player.getWorld().getBlockState(pos));
|
TreeType tree = TreeType.at(pos, player.getWorld());
|
||||||
|
|
||||||
return tree != TreeType.NONE && tree.findBase(player.getWorld(), pos).map(base -> {
|
return tree != TreeType.NONE && tree.findBase(player.getWorld(), pos).map(base -> {
|
||||||
return tree.countBlocks(player.getWorld(), pos) > 0;
|
return tree.countBlocks(player.getWorld(), pos) > 0;
|
||||||
|
@ -94,7 +95,7 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
||||||
|
|
||||||
if (destr.getBlockDestruction(pos) + 4 >= BlockDestructionManager.MAX_DAMAGE) {
|
if (destr.getBlockDestruction(pos) + 4 >= BlockDestructionManager.MAX_DAMAGE) {
|
||||||
if (!harmed || player.world.random.nextInt(30) == 0) {
|
if (!harmed || player.world.random.nextInt(30) == 0) {
|
||||||
TreeType.get(player.world.getBlockState(pos)).traverse(player.world, pos, (w, state, p, recurseLevel) -> {
|
TreeType.at(pos, player.world).traverse(player.world, pos, (w, state, p, recurseLevel) -> {
|
||||||
if (recurseLevel < 5) {
|
if (recurseLevel < 5) {
|
||||||
w.breakBlock(p, true);
|
w.breakBlock(p, true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -150,10 +151,9 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int dropApples(PlayerEntity player, BlockPos pos) {
|
private int dropApples(PlayerEntity player, BlockPos pos) {
|
||||||
TreeType tree = TreeType.get(player.world.getBlockState(pos));
|
TreeType tree = TreeType.at(pos, player.world);
|
||||||
|
|
||||||
if (tree.countBlocks(player.world, pos) > 0) {
|
if (tree.countBlocks(player.world, pos) > 0) {
|
||||||
|
|
||||||
List<ItemEntity> capturedDrops = Lists.newArrayList();
|
List<ItemEntity> capturedDrops = Lists.newArrayList();
|
||||||
|
|
||||||
tree.traverse(player.world, pos, (world, state, position, recurse) -> {
|
tree.traverse(player.world, pos, (world, state, position, recurse) -> {
|
||||||
|
@ -162,13 +162,17 @@ public class EarthPonyKickAbility implements Ability<Pos> {
|
||||||
affectBlockChange(player, position);
|
affectBlockChange(player, position);
|
||||||
|
|
||||||
if (world.getBlockState(position.down()).isAir()) {
|
if (world.getBlockState(position.down()).isAir()) {
|
||||||
WorldEvent.play(WorldEvent.DESTROY_BLOCK, world, position, state);
|
ItemStack stack = tree.pickRandomStack(state);
|
||||||
capturedDrops.add(new ItemEntity(world,
|
if (!stack.isEmpty()) {
|
||||||
|
WorldEvent.play(WorldEvent.DESTROY_BLOCK, world, position, state);
|
||||||
|
|
||||||
|
capturedDrops.add(new ItemEntity(world,
|
||||||
position.getX() + world.random.nextFloat(),
|
position.getX() + world.random.nextFloat(),
|
||||||
position.getY() - 0.5,
|
position.getY() - 0.5,
|
||||||
position.getZ() + world.random.nextFloat(),
|
position.getZ() + world.random.nextFloat(),
|
||||||
tree.pickRandomStack()
|
stack
|
||||||
));
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,52 +4,37 @@ import com.minelittlepony.unicopia.util.PosHelper;
|
||||||
import com.minelittlepony.unicopia.util.Weighted;
|
import com.minelittlepony.unicopia.util.Weighted;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.LeavesBlock;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public final class TreeType {
|
public interface TreeType {
|
||||||
public static final TreeType NONE = new TreeType(
|
TreeType NONE = new TreeTypeImpl(
|
||||||
new Identifier("unicopia", "none"),
|
new Identifier("unicopia", "none"),
|
||||||
false,
|
false,
|
||||||
new Weighted<Supplier<ItemStack>>(),
|
new Weighted<Supplier<ItemStack>>(),
|
||||||
Set.of(),
|
Set.of(),
|
||||||
Set.of()
|
Set.of()
|
||||||
);
|
);
|
||||||
private static final Direction[] WIDE_DIRS = new Direction[] { Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST };
|
Direction[] WIDE_DIRS = new Direction[] { Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST };
|
||||||
|
|
||||||
private final Identifier name;
|
default void traverse(World w, BlockPos start, Reactor consumer) {
|
||||||
private final boolean wideTrunk;
|
|
||||||
private final Set<Identifier> logs;
|
|
||||||
private final Set<Identifier> leaves;
|
|
||||||
private final Weighted<Supplier<ItemStack>> pool;
|
|
||||||
|
|
||||||
TreeType(Identifier name, boolean wideTrunk, Weighted<Supplier<ItemStack>> pool, Set<Identifier> logs, Set<Identifier> leaves) {
|
|
||||||
this.name = name;
|
|
||||||
this.wideTrunk = wideTrunk;
|
|
||||||
this.pool = pool;
|
|
||||||
this.logs = logs;
|
|
||||||
this.leaves = leaves;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void traverse(World w, BlockPos start, Reactor consumer) {
|
|
||||||
traverse(w, start, consumer, consumer);
|
traverse(w, start, consumer, consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void traverse(World w, BlockPos start, Reactor logConsumer, Reactor leavesConsumer) {
|
default void traverse(World w, BlockPos start, Reactor logConsumer, Reactor leavesConsumer) {
|
||||||
traverse(new HashSet<>(), new HashSet<>(), w, start, 0, 50, logConsumer, leavesConsumer);
|
traverse(new HashSet<>(), new HashSet<>(), w, start, 0, 50, logConsumer, leavesConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void traverse(Set<BlockPos> logs, Set<BlockPos> leaves, World w, BlockPos start, int recurseLevel, int maxRecurse, Reactor logConsumer, Reactor leavesConsumer) {
|
default void traverse(Set<BlockPos> logs, Set<BlockPos> leaves, World w, BlockPos start, int recurseLevel, int maxRecurse, Reactor logConsumer, Reactor leavesConsumer) {
|
||||||
if (this == NONE) {
|
if (this == NONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +75,7 @@ public final class TreeType {
|
||||||
/**
|
/**
|
||||||
* Recursively locates the base of the tree.
|
* Recursively locates the base of the tree.
|
||||||
*/
|
*/
|
||||||
public Optional<BlockPos> findBase(World w, BlockPos pos) {
|
default Optional<BlockPos> findBase(World w, BlockPos pos) {
|
||||||
return findBase(new HashSet<BlockPos>(), w, new BlockPos.Mutable(pos.getX(), pos.getY(), pos.getZ()));
|
return findBase(new HashSet<BlockPos>(), w, new BlockPos.Mutable(pos.getX(), pos.getY(), pos.getZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +89,7 @@ public final class TreeType {
|
||||||
done.add(pos.move(Direction.DOWN).toImmutable());
|
done.add(pos.move(Direction.DOWN).toImmutable());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wideTrunk) {
|
if (isWide()) {
|
||||||
PosHelper.all(pos.toImmutable(), p -> findBase(done, w, new BlockPos.Mutable(p.getX(), p.getY(), p.getZ()))
|
PosHelper.all(pos.toImmutable(), p -> findBase(done, w, new BlockPos.Mutable(p.getX(), p.getY(), p.getZ()))
|
||||||
.filter(a -> a.getY() < pos.getY())
|
.filter(a -> a.getY() < pos.getY())
|
||||||
.ifPresent(pos::set), PosHelper.HORIZONTAL);
|
.ifPresent(pos::set), PosHelper.HORIZONTAL);
|
||||||
|
@ -117,7 +102,7 @@ public final class TreeType {
|
||||||
/**
|
/**
|
||||||
* Counts the number of logs and leaves present in the targeted tree.
|
* Counts the number of logs and leaves present in the targeted tree.
|
||||||
*/
|
*/
|
||||||
public int countBlocks(World w, BlockPos pos) {
|
default int countBlocks(World w, BlockPos pos) {
|
||||||
if (this == NONE) {
|
if (this == NONE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +125,7 @@ public final class TreeType {
|
||||||
/**
|
/**
|
||||||
* Locates the top of the tree's trunk. Usually the point where wood meets leaves.
|
* Locates the top of the tree's trunk. Usually the point where wood meets leaves.
|
||||||
*/
|
*/
|
||||||
public BlockPos findCanopy(World w, BlockPos pos) {
|
default BlockPos findCanopy(World w, BlockPos pos) {
|
||||||
while (isLog(w.getBlockState(pos.up()))) {
|
while (isLog(w.getBlockState(pos.up()))) {
|
||||||
if (PosHelper.any(pos, p -> isLeaves(w.getBlockState(p)), PosHelper.HORIZONTAL)) {
|
if (PosHelper.any(pos, p -> isLeaves(w.getBlockState(p)), PosHelper.HORIZONTAL)) {
|
||||||
break;
|
break;
|
||||||
|
@ -151,38 +136,66 @@ public final class TreeType {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLeaves(BlockState state) {
|
/**
|
||||||
return findMatch(leaves, state) && (!state.contains(LeavesBlock.PERSISTENT) || !state.get(LeavesBlock.PERSISTENT));
|
* Finds the tree type of the leaves on top of this tree, independent of what this tree expects for its leaves.
|
||||||
|
*/
|
||||||
|
default TreeType findLeavesType(World w, BlockPos pos) {
|
||||||
|
while (isLog(w.getBlockState(pos.up()))) {
|
||||||
|
if (PosHelper.any(pos, p -> isLeaves(w.getBlockState(p)), PosHelper.HORIZONTAL)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = pos.up();
|
||||||
|
}
|
||||||
|
|
||||||
|
return of(w.getBlockState(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLog(BlockState state) {
|
boolean isLeaves(BlockState state);
|
||||||
return findMatch(logs, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean matches(BlockState state) {
|
boolean isLog(BlockState state);
|
||||||
|
|
||||||
|
default boolean matches(BlockState state) {
|
||||||
return isLeaves(state) || isLog(state);
|
return isLeaves(state) || isLog(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack pickRandomStack() {
|
ItemStack pickRandomStack(BlockState state);
|
||||||
return pool.get().map(Supplier::get).orElse(ItemStack.EMPTY);
|
|
||||||
|
boolean isWide();
|
||||||
|
|
||||||
|
static TreeType at(BlockPos pos, World world) {
|
||||||
|
return TreeTypeLoader.INSTANCE.get(world.getBlockState(pos), pos, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TreeType get(BlockState state) {
|
static TreeType of(BlockState state) {
|
||||||
return TreeTypeLoader.INSTANCE.get(state);
|
return TreeTypeLoader.INSTANCE.get(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
static TreeType of(TreeType logs, TreeType leaves) {
|
||||||
public boolean equals(Object o) {
|
if (logs == NONE || leaves == NONE || Objects.equals(logs, leaves)) {
|
||||||
return o instanceof TreeType && name.compareTo(((TreeType)o).name) == 0;
|
return logs;
|
||||||
}
|
}
|
||||||
|
return new TreeType() {
|
||||||
|
@Override
|
||||||
|
public boolean isLeaves(BlockState state) {
|
||||||
|
return leaves.isLeaves(state);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean findMatch(Set<Identifier> ids, BlockState state) {
|
@Override
|
||||||
return ids.contains(Registry.BLOCK.getId(state.getBlock()));
|
public boolean isLog(BlockState state) {
|
||||||
}
|
return logs.isLog(state);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public ItemStack pickRandomStack(BlockState state) {
|
||||||
return name.hashCode();
|
return (isLeaves(state) ? leaves : logs).pickRandomStack(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWide() {
|
||||||
|
return logs.isWide();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Reactor {
|
public interface Reactor {
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.minelittlepony.unicopia.ability.data.tree;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.util.Weighted;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.LeavesBlock;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
public final class TreeTypeImpl implements TreeType {
|
||||||
|
private final Identifier name;
|
||||||
|
private final boolean wideTrunk;
|
||||||
|
private final Set<Identifier> logs;
|
||||||
|
private final Set<Identifier> leaves;
|
||||||
|
private final Weighted<Supplier<ItemStack>> pool;
|
||||||
|
|
||||||
|
TreeTypeImpl(Identifier name, boolean wideTrunk, Weighted<Supplier<ItemStack>> pool, Set<Identifier> logs, Set<Identifier> leaves) {
|
||||||
|
this.name = name;
|
||||||
|
this.wideTrunk = wideTrunk;
|
||||||
|
this.pool = pool;
|
||||||
|
this.logs = logs;
|
||||||
|
this.leaves = leaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLeaves(BlockState state) {
|
||||||
|
return findMatch(leaves, state) && isNonPersistent(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLog(BlockState state) {
|
||||||
|
return findMatch(logs, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWide() {
|
||||||
|
return wideTrunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack pickRandomStack(BlockState state) {
|
||||||
|
return pool.get().map(Supplier::get).orElse(ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof TreeTypeImpl && name.compareTo(((TreeTypeImpl)o).name) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean findMatch(Set<Identifier> ids, BlockState state) {
|
||||||
|
return ids.contains(Registry.BLOCK.getId(state.getBlock()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isNonPersistent(BlockState state) {
|
||||||
|
return !state.contains(LeavesBlock.PERSISTENT) || !state.get(LeavesBlock.PERSISTENT);
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,19 +11,24 @@ import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import com.minelittlepony.common.util.settings.ToStringAdapter;
|
import com.minelittlepony.common.util.settings.ToStringAdapter;
|
||||||
|
import com.minelittlepony.unicopia.util.PosHelper;
|
||||||
import com.minelittlepony.unicopia.util.Weighted;
|
import com.minelittlepony.unicopia.util.Weighted;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.LeavesBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.resource.JsonDataLoader;
|
import net.minecraft.resource.JsonDataLoader;
|
||||||
import net.minecraft.resource.ResourceManager;
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
import net.minecraft.tag.BlockTags;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.profiler.Profiler;
|
import net.minecraft.util.profiler.Profiler;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResourceReloadListener {
|
public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResourceReloadListener {
|
||||||
|
|
||||||
private static final Identifier ID = new Identifier("unicopia", "data/tree_type");
|
private static final Identifier ID = new Identifier("unicopia", "data/tree_type");
|
||||||
public static final Gson GSON = new GsonBuilder()
|
public static final Gson GSON = new GsonBuilder()
|
||||||
.registerTypeAdapter(Identifier.class, new ToStringAdapter<>(Identifier::new))
|
.registerTypeAdapter(Identifier.class, new ToStringAdapter<>(Identifier::new))
|
||||||
|
@ -33,6 +38,9 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
|
||||||
|
|
||||||
private final Set<TreeType> entries = new HashSet<>();
|
private final Set<TreeType> entries = new HashSet<>();
|
||||||
|
|
||||||
|
private final TreeType any1x = createDynamic(false);
|
||||||
|
private final TreeType any2x = createDynamic(true);
|
||||||
|
|
||||||
TreeTypeLoader() {
|
TreeTypeLoader() {
|
||||||
super(GSON, "tree_types");
|
super(GSON, "tree_types");
|
||||||
}
|
}
|
||||||
|
@ -42,8 +50,57 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
|
||||||
return ID;
|
return ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TreeType get(BlockState state, BlockPos pos, World world) {
|
||||||
|
return entries.stream()
|
||||||
|
.filter(type -> type.matches(state))
|
||||||
|
.findFirst()
|
||||||
|
.map(type -> TreeType.of(type, type.findLeavesType(world, pos)))
|
||||||
|
.orElseGet(() -> {
|
||||||
|
if (any1x.matches(state)) {
|
||||||
|
if (PosHelper.any(pos, p -> world.getBlockState(p).isOf(state.getBlock()), PosHelper.HORIZONTAL)) {
|
||||||
|
return any2x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return any1x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TreeType.NONE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public TreeType get(BlockState state) {
|
public TreeType get(BlockState state) {
|
||||||
return entries.stream().filter(type -> type.matches(state)).findFirst().orElse(TreeType.NONE);
|
return entries.stream()
|
||||||
|
.filter(type -> type.matches(state))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(TreeType.NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeType createDynamic(boolean wide) {
|
||||||
|
return new TreeType() {
|
||||||
|
@Override
|
||||||
|
public boolean isLeaves(BlockState state) {
|
||||||
|
return (state.isIn(BlockTags.LEAVES) || state.getBlock() instanceof LeavesBlock || entries.stream().anyMatch(t -> t.isLeaves(state))) && TreeTypeImpl.isNonPersistent(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLog(BlockState state) {
|
||||||
|
return state.isIn(BlockTags.LOGS_THAT_BURN) || entries.stream().anyMatch(t -> t.isLog(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack pickRandomStack(BlockState state) {
|
||||||
|
TreeType type = get(state);
|
||||||
|
if (type == TreeType.NONE) {
|
||||||
|
type = get(Blocks.OAK_LOG.getDefaultState());
|
||||||
|
}
|
||||||
|
return type.pickRandomStack(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWide() {
|
||||||
|
return wide;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,7 +112,7 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
|
||||||
TreeTypeDef typeDef = GSON.fromJson(entry.getValue(), TreeTypeDef.class);
|
TreeTypeDef typeDef = GSON.fromJson(entry.getValue(), TreeTypeDef.class);
|
||||||
|
|
||||||
if (typeDef != null) {
|
if (typeDef != null) {
|
||||||
entries.add(new TreeType(
|
entries.add(new TreeTypeImpl(
|
||||||
entry.getKey(),
|
entry.getKey(),
|
||||||
typeDef.wideTrunk,
|
typeDef.wideTrunk,
|
||||||
typeDef.getWeighted(new Weighted<Supplier<ItemStack>>()),
|
typeDef.getWeighted(new Weighted<Supplier<ItemStack>>()),
|
||||||
|
|
Loading…
Reference in a new issue