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
6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.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
79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/blocks/seats.json
5def5088f7fd31b80e6f28c1c4ea146aa9d7d15b data/create/tags/blocks/toolboxes.json
a8271a2fcefafde4a6589193c50c41edcba1dad7 data/create/tags/blocks/tree_attachments.json
da739ad2160e7df4e0e5cc89587670ce5e9450c3 data/create/tags/blocks/valve_handles.json
72143286fb5cb372a0696550e2eac76ca50e6fbc data/create/tags/blocks/windmill_sails.json
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/create/tags/blocks/windowable.json

View file

@ -1,10 +1,10 @@
{
"replace": false,
"values": [
"minecraft:bee_nest",
"minecraft:vine",
"minecraft:moss_carpet",
"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);
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);

View file

@ -14,7 +14,6 @@ import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllRecipeTypes;
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.itemAssembly.SequencedAssemblyRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingInventory;
@ -480,6 +479,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
return false;
if (TreeCutter.isLog(stateToBreak) || (stateToBreak.is(BlockTags.LEAVES)))
return true;
if (TreeCutter.isRoot(stateToBreak))
return true;
Block block = stateToBreak.getBlock();
if (block instanceof BambooBlock)
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.Blocks;
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.properties.BlockStateProperties;
@ -28,6 +29,10 @@ public class TreeFertilizerItem extends Item {
Block block = state.getBlock();
if (block instanceof BonemealableBlock bonemealableBlock && state.is(BlockTags.SAPLINGS)) {
if (state.getOptionalValue(MangrovePropaguleBlock.HANGING)
.orElse(false))
return InteractionResult.PASS;
if (context.getLevel().isClientSide) {
BoneMealItem.addGrowthParticles(context.getLevel(), context.getClickedPos(), 100);
return InteractionResult.SUCCESS;
@ -89,7 +94,13 @@ public class TreeFertilizerItem extends Item {
protected TreesDreamWorld(ServerLevel wrapped, BlockPos saplingPos) {
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

View file

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