My mangrove is to blow up

- Extended saw behaviour to work with mangroves
- Fixed tree fertilizer not working when trees are growing on mud (?)
This commit is contained in:
simibubi 2022-09-21 09:27:20 +02:00
parent 09e9bdaeeb
commit 63de196977
6 changed files with 86 additions and 25 deletions

View file

@ -1,4 +1,4 @@
// 1.19.2 2022-09-17T21:51:07.3812115 Registrate Provider for create [Recipes, Advancements, Loot tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)] // 1.19.2 2022-09-21T09:09:19.8483732 Registrate Provider for create [Recipes, Advancements, Loot tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json 60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json
6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json 6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json
c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json
@ -4489,6 +4489,7 @@ e3510f08cc217e52b58692dcc7f3eda0289ff751 data/create/tags/blocks/passive_boiler_
5ac75e77c57ab675e5d36a1e2bd7d37804b7de05 data/create/tags/blocks/safe_nbt.json 5ac75e77c57ab675e5d36a1e2bd7d37804b7de05 data/create/tags/blocks/safe_nbt.json
79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/blocks/seats.json 79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/blocks/seats.json
5def5088f7fd31b80e6f28c1c4ea146aa9d7d15b data/create/tags/blocks/toolboxes.json 5def5088f7fd31b80e6f28c1c4ea146aa9d7d15b data/create/tags/blocks/toolboxes.json
a8271a2fcefafde4a6589193c50c41edcba1dad7 data/create/tags/blocks/tree_attachments.json
da739ad2160e7df4e0e5cc89587670ce5e9450c3 data/create/tags/blocks/valve_handles.json da739ad2160e7df4e0e5cc89587670ce5e9450c3 data/create/tags/blocks/valve_handles.json
72143286fb5cb372a0696550e2eac76ca50e6fbc data/create/tags/blocks/windmill_sails.json 72143286fb5cb372a0696550e2eac76ca50e6fbc data/create/tags/blocks/windmill_sails.json
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/blocks/windowable.json 35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/blocks/windowable.json

View file

@ -1,10 +1,10 @@
{ {
"replace": false,
"values": [ "values": [
"minecraft:bee_nest", "minecraft:bee_nest",
"minecraft:vine", "minecraft:vine",
"minecraft:moss_carpet", "minecraft:moss_carpet",
"minecraft:shroomlight", "minecraft:shroomlight",
"minecraft:cocoa" "minecraft:cocoa",
"minecraft:mangrove_propagule"
] ]
} }

View file

@ -417,7 +417,7 @@ public class AllTags {
Blocks.TRIPWIRE, Blocks.TRIPWIRE_HOOK, Blocks.DAYLIGHT_DETECTOR, Blocks.TARGET, Blocks.HOPPER); Blocks.TRIPWIRE, Blocks.TRIPWIRE_HOOK, Blocks.DAYLIGHT_DETECTOR, Blocks.TARGET, Blocks.HOPPER);
AllBlockTags.TREE_ATTACHMENTS.add(Blocks.BEE_NEST, Blocks.VINE, Blocks.MOSS_CARPET, Blocks.SHROOMLIGHT, AllBlockTags.TREE_ATTACHMENTS.add(Blocks.BEE_NEST, Blocks.VINE, Blocks.MOSS_CARPET, Blocks.SHROOMLIGHT,
Blocks.COCOA); Blocks.COCOA, Blocks.MANGROVE_PROPAGULE);
AllBlockTags.ORE_OVERRIDE_STONE.includeAll(BlockTags.STONE_ORE_REPLACEABLES); AllBlockTags.ORE_OVERRIDE_STONE.includeAll(BlockTags.STONE_ORE_REPLACEABLES);

View file

@ -14,7 +14,6 @@ import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity;
import com.simibubi.create.content.contraptions.itemAssembly.SequencedAssemblyRecipe; import com.simibubi.create.content.contraptions.itemAssembly.SequencedAssemblyRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingInventory; import com.simibubi.create.content.contraptions.processing.ProcessingInventory;
@ -480,6 +479,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
return false; return false;
if (TreeCutter.isLog(stateToBreak) || (stateToBreak.is(BlockTags.LEAVES))) if (TreeCutter.isLog(stateToBreak) || (stateToBreak.is(BlockTags.LEAVES)))
return true; return true;
if (TreeCutter.isRoot(stateToBreak))
return true;
Block block = stateToBreak.getBlock(); Block block = stateToBreak.getBlock();
if (block instanceof BambooBlock) if (block instanceof BambooBlock)
return true; return true;

View file

@ -12,6 +12,7 @@ import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.BonemealableBlock; import net.minecraft.world.level.block.BonemealableBlock;
import net.minecraft.world.level.block.MangrovePropaguleBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
@ -28,6 +29,10 @@ public class TreeFertilizerItem extends Item {
Block block = state.getBlock(); Block block = state.getBlock();
if (block instanceof BonemealableBlock bonemealableBlock && state.is(BlockTags.SAPLINGS)) { if (block instanceof BonemealableBlock bonemealableBlock && state.is(BlockTags.SAPLINGS)) {
if (state.getOptionalValue(MangrovePropaguleBlock.HANGING)
.orElse(false))
return InteractionResult.PASS;
if (context.getLevel().isClientSide) { if (context.getLevel().isClientSide) {
BoneMealItem.addGrowthParticles(context.getLevel(), context.getClickedPos(), 100); BoneMealItem.addGrowthParticles(context.getLevel(), context.getClickedPos(), 100);
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
@ -89,7 +94,13 @@ public class TreeFertilizerItem extends Item {
protected TreesDreamWorld(ServerLevel wrapped, BlockPos saplingPos) { protected TreesDreamWorld(ServerLevel wrapped, BlockPos saplingPos) {
super(wrapped); super(wrapped);
soil = wrapped.getBlockState(saplingPos.below()); BlockState stateUnderSapling = wrapped.getBlockState(saplingPos.below());
// Tree features don't seem to succeed with mud as soil
if (stateUnderSapling.is(BlockTags.DIRT))
stateUnderSapling = Blocks.DIRT.defaultBlockState();
soil = stateUnderSapling;
} }
@Override @Override

View file

@ -41,7 +41,9 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.block.state.properties.Property;
public class TreeCutter { public class TreeCutter {
public static final Tree NO_TREE = new Tree(Collections.emptyList(), Collections.emptyList());
public static final Tree NO_TREE =
new Tree(Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
public static boolean canDynamicTreeCutFrom(Block startBlock) { public static boolean canDynamicTreeCutFrom(Block startBlock) {
return Mods.DYNAMICTREES.runIfInstalled(() -> () -> DynamicTree.isDynamicBranch(startBlock)) return Mods.DYNAMICTREES.runIfInstalled(() -> () -> DynamicTree.isDynamicBranch(startBlock))
@ -69,6 +71,7 @@ public class TreeCutter {
List<BlockPos> logs = new ArrayList<>(); List<BlockPos> logs = new ArrayList<>();
List<BlockPos> leaves = new ArrayList<>(); List<BlockPos> leaves = new ArrayList<>();
List<BlockPos> attachments = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
List<BlockPos> frontier = new LinkedList<>(); List<BlockPos> frontier = new LinkedList<>();
@ -83,7 +86,7 @@ public class TreeCutter {
logs.add(current); logs.add(current);
} }
Collections.reverse(logs); Collections.reverse(logs);
return new Tree(logs, leaves); return new Tree(logs, leaves, attachments);
} }
// Chorus // Chorus
@ -103,7 +106,7 @@ public class TreeCutter {
} }
} }
Collections.reverse(logs); Collections.reverse(logs);
return new Tree(logs, leaves); return new Tree(logs, leaves, attachments);
} }
// Regular Tree // Regular Tree
@ -114,40 +117,60 @@ public class TreeCutter {
BlockPos.betweenClosedStream(pos.offset(-1, 0, -1), pos.offset(1, 1, 1)) BlockPos.betweenClosedStream(pos.offset(-1, 0, -1), pos.offset(1, 1, 1))
.forEach(p -> frontier.add(new BlockPos(p))); .forEach(p -> frontier.add(new BlockPos(p)));
// Find all logs // Find all logs & roots
boolean hasRoots = false;
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
BlockPos currentPos = frontier.remove(0); BlockPos currentPos = frontier.remove(0);
if (visited.contains(currentPos)) if (!visited.add(currentPos))
continue; continue;
visited.add(currentPos);
if (!isLog(reader.getBlockState(currentPos))) BlockState currentState = reader.getBlockState(currentPos);
if (isRoot(currentState))
hasRoots = true;
else if (!isLog(currentState))
continue; continue;
logs.add(currentPos); logs.add(currentPos);
forNeighbours(currentPos, visited, true, p -> frontier.add(new BlockPos(p))); forNeighbours(currentPos, visited, SearchDirection.UP, p -> frontier.add(new BlockPos(p)));
} }
// Find all leaves
visited.clear(); visited.clear();
visited.addAll(logs); visited.addAll(logs);
frontier.addAll(logs); frontier.addAll(logs);
if (hasRoots) {
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
BlockPos prevPos = frontier.remove(0); BlockPos currentPos = frontier.remove(0);
if (!logs.contains(prevPos) && visited.contains(prevPos)) if (!logs.contains(currentPos) && !visited.add(currentPos))
continue;
BlockState currentState = reader.getBlockState(currentPos);
if (!isRoot(currentState))
continue;
logs.add(currentPos);
forNeighbours(currentPos, visited, SearchDirection.DOWN, p -> frontier.add(new BlockPos(p)));
}
visited.clear();
visited.addAll(logs);
frontier.addAll(logs);
}
// Find all leaves
while (!frontier.isEmpty()) {
BlockPos prevPos = frontier.remove(0);
if (!logs.contains(prevPos) && !visited.add(prevPos))
continue; continue;
visited.add(prevPos);
BlockState prevState = reader.getBlockState(prevPos); BlockState prevState = reader.getBlockState(prevPos);
int prevLeafDistance = isLeaf(prevState) ? getLeafDistance(prevState) : 0; int prevLeafDistance = isLeaf(prevState) ? getLeafDistance(prevState) : 0;
forNeighbours(prevPos, visited, false, currentPos -> { forNeighbours(prevPos, visited, SearchDirection.BOTH, currentPos -> {
BlockState state = reader.getBlockState(currentPos); BlockState state = reader.getBlockState(currentPos);
BlockPos subtract = currentPos.subtract(pos); BlockPos subtract = currentPos.subtract(pos);
BlockPos currentPosImmutable = currentPos.immutable(); BlockPos currentPosImmutable = currentPos.immutable();
if (AllBlockTags.TREE_ATTACHMENTS.matches(state)) { if (AllBlockTags.TREE_ATTACHMENTS.matches(state)) {
leaves.add(currentPosImmutable); attachments.add(currentPosImmutable);
visited.add(currentPosImmutable); visited.add(currentPosImmutable);
return; return;
} }
@ -168,7 +191,7 @@ public class TreeCutter {
}); });
} }
return new Tree(logs, leaves); return new Tree(logs, leaves, attachments);
} }
private static int getLeafDistance(BlockState state) { private static int getLeafDistance(BlockState state) {
@ -215,12 +238,17 @@ public class TreeCutter {
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
BlockPos currentPos = frontier.remove(0); BlockPos currentPos = frontier.remove(0);
BlockPos belowPos = currentPos.below();
visited.add(currentPos); visited.add(currentPos);
boolean lowerLayer = currentPos.getY() == posY; boolean lowerLayer = currentPos.getY() == posY;
if (!isLog(reader.getBlockState(currentPos))) BlockState currentState = reader.getBlockState(currentPos);
BlockState belowState = reader.getBlockState(belowPos);
if (!isLog(currentState) && !isRoot(currentState))
continue; continue;
if (!lowerLayer && !pos.equals(currentPos.below()) && isLog(reader.getBlockState(currentPos.below()))) if (!lowerLayer && !pos.equals(belowPos) && (isLog(belowState) || isRoot(belowState)))
return false; return false;
for (Direction direction : Iterate.directions) { for (Direction direction : Iterate.directions) {
@ -239,12 +267,29 @@ public class TreeCutter {
return true; return true;
} }
private static void forNeighbours(BlockPos pos, Set<BlockPos> visited, boolean up, Consumer<BlockPos> acceptor) { private enum SearchDirection {
BlockPos.betweenClosedStream(pos.offset(-1, up ? 0 : -1, -1), pos.offset(1, 1, 1)) UP(0, 1), DOWN(-1, 0), BOTH(-1, 1);
int minY;
int maxY;
private SearchDirection(int minY, int maxY) {
this.minY = minY;
this.maxY = maxY;
}
}
private static void forNeighbours(BlockPos pos, Set<BlockPos> visited, SearchDirection direction,
Consumer<BlockPos> acceptor) {
BlockPos.betweenClosedStream(pos.offset(-1, direction.minY, -1), pos.offset(1, direction.maxY, 1))
.filter(((Predicate<BlockPos>) visited::contains).negate()) .filter(((Predicate<BlockPos>) visited::contains).negate())
.forEach(acceptor); .forEach(acceptor);
} }
public static boolean isRoot(BlockState state) {
return state.is(Blocks.MANGROVE_ROOTS);
}
public static boolean isLog(BlockState state) { public static boolean isLog(BlockState state) {
return state.is(BlockTags.LOGS) || AllTags.AllBlockTags.SLIMY_LOGS.matches(state) return state.is(BlockTags.LOGS) || AllTags.AllBlockTags.SLIMY_LOGS.matches(state)
|| state.is(Blocks.MUSHROOM_STEM); || state.is(Blocks.MUSHROOM_STEM);
@ -272,15 +317,18 @@ public class TreeCutter {
public static class Tree extends AbstractBlockBreakQueue { public static class Tree extends AbstractBlockBreakQueue {
private final List<BlockPos> logs; private final List<BlockPos> logs;
private final List<BlockPos> leaves; private final List<BlockPos> leaves;
private final List<BlockPos> attachments;
public Tree(List<BlockPos> logs, List<BlockPos> leaves) { public Tree(List<BlockPos> logs, List<BlockPos> leaves, List<BlockPos> attachments) {
this.logs = logs; this.logs = logs;
this.leaves = leaves; this.leaves = leaves;
this.attachments = attachments;
} }
@Override @Override
public void destroyBlocks(Level world, ItemStack toDamage, @Nullable Player playerEntity, public void destroyBlocks(Level world, ItemStack toDamage, @Nullable Player playerEntity,
BiConsumer<BlockPos, ItemStack> drop) { BiConsumer<BlockPos, ItemStack> drop) {
attachments.forEach(makeCallbackFor(world, 1 / 32f, toDamage, playerEntity, drop));
logs.forEach(makeCallbackFor(world, 1 / 2f, toDamage, playerEntity, drop)); logs.forEach(makeCallbackFor(world, 1 / 2f, toDamage, playerEntity, drop));
leaves.forEach(makeCallbackFor(world, 1 / 8f, toDamage, playerEntity, drop)); leaves.forEach(makeCallbackFor(world, 1 / 8f, toDamage, playerEntity, drop));
} }