mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-19 09:28:14 +01:00
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:
parent
09e9bdaeeb
commit
63de196977
6 changed files with 86 additions and 25 deletions
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue