Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Treetap #775

Merged
merged 8 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ repositories {
url = uri("https://maven.terraformersmc.com/")
}

maven {
name = "Ladysnake"
url = uri("https://maven.ladysnake.org/releases")
}

maven {
name = "Shedaniel"
url = uri("https://maven.shedaniel.me/")
Expand Down
1 change: 0 additions & 1 deletion config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<property name="option" value="alone"/>
<property name="tokens" value="LITERAL_ELSE, METHOD_DEF"/>
</module>
<module name="InnerTypeLast"/>
<module name="OneTopLevelClass"/>
<module name="RequireThis"/>
<module name="ArrayTypeStyle"/>
Expand Down
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ paradiseLostVersion=2.1.0-beta+1.19.2

minecraftVersion=1.19.2
yarnVersion=1.19.2+build.28
loaderVersion=0.14.13
loaderVersion=0.15.7
javaVersion=17

fabricApiVersion=0.73.2+1.19.2
fabricApiVersion=0.77.0+1.19.2
incubusCoreVersion=1.9.4
customportalapiVersion=0.0.1-beta54-1.19
customportalapiVersion=0.0.1-beta63.5-1.19.X
cardinalComponentsVersion=5.0.1
trinketsVersion=3.4.0
crowdinTranslateVersion=1.19.2
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/id/paradiselost/ParadiseLost.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import net.id.paradiselost.items.ParadiseLostItems;
import net.id.paradiselost.loot.ParadiseLostLootNumberProviderTypes;
import net.id.paradiselost.lore.ParadiseLostLore;
import net.id.paradiselost.recipe.ParadiseLostRecipeTypes;
import net.id.paradiselost.registry.ParadiseLostRegistries;
import net.id.paradiselost.screen.ParadiseLostScreens;
import net.id.paradiselost.util.ParadiseLostSoundEvents;
Expand Down Expand Up @@ -89,6 +90,7 @@ public void onInitialize() {
ParadiseLostEntityTypes.init();
ParadiseLostItems.init();
ParadiseLostBlockEntityTypes.init();
ParadiseLostRecipeTypes.init();
ParadiseLostCommands.init();
ParadiseLostGameRules.init();
ParadiseLostLootNumberProviderTypes.init();
Expand Down
27 changes: 21 additions & 6 deletions src/main/java/net/id/paradiselost/blocks/ParadiseLostBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,24 @@
import net.id.incubus_core.woodtypefactory.api.chest.ChestFactory;
import net.id.paradiselost.ParadiseLost;
import net.id.paradiselost.blocks.decorative.*;
import net.id.paradiselost.blocks.mechanical.*;
import net.id.paradiselost.blocks.natural.*;
import net.id.paradiselost.blocks.natural.cloud.*;
import net.id.paradiselost.blocks.natural.crop.*;
import net.id.paradiselost.blocks.mechanical.CherineCampfireBlock;
import net.id.paradiselost.blocks.mechanical.FoodBowlBlock;
import net.id.paradiselost.blocks.mechanical.FourBiteCakeBlock;
import net.id.paradiselost.blocks.mechanical.IncubatorBlock;
import net.id.paradiselost.blocks.mechanical.TreeTapBlock;
import net.id.paradiselost.blocks.natural.ParadiseLostGrassBlock;
import net.id.paradiselost.blocks.natural.ParadiseLostSaplingBlock;
import net.id.paradiselost.blocks.natural.ParadiseLostSnowyBlock;
import net.id.paradiselost.blocks.natural.PoofBlock;
import net.id.paradiselost.blocks.natural.SurtrumOreBlock;
import net.id.paradiselost.blocks.natural.cloud.ParadiseLostCloudBlock;
import net.id.paradiselost.blocks.natural.cloud.BlueParadiseLostCloudBlock;
import net.id.paradiselost.blocks.natural.cloud.GoldenParadiseLostCloudBlock;
import net.id.paradiselost.blocks.natural.cloud.PinkParadiseLostCloudBlock;
import net.id.paradiselost.blocks.natural.crop.AmadrysCropBlock;
import net.id.paradiselost.blocks.natural.crop.BlackcurrantBushBlock;
import net.id.paradiselost.blocks.natural.crop.FlaxCropBlock;
import net.id.paradiselost.blocks.natural.crop.SwedrootCropBlock;
import net.id.paradiselost.blocks.natural.plant.*;
import net.id.paradiselost.blocks.natural.tree.*;
import net.id.paradiselost.fluids.ParadiseLostFluids;
Expand Down Expand Up @@ -41,7 +55,7 @@
@SuppressWarnings("unused")
public class ParadiseLostBlocks {

protected static Settings unbreakable(AbstractBlock.Settings settings) {
protected static Settings unbreakable(AbstractBlock.Settings settings) {
return settings.strength(-1f, 3600000f);
}

Expand Down Expand Up @@ -375,6 +389,7 @@ private static Settings cherineTorch() {
// Usables
public static final IncubatorBlock INCUBATOR = add("incubator", new IncubatorBlock(of(Material.WOOD, MapColor.DULL_RED).strength(2.5f).sounds(BlockSoundGroup.WOOD).nonOpaque()), cutoutMippedRenderLayer);
public static final FoodBowlBlock FOOD_BOWL = add("food_bowl", new FoodBowlBlock(of(Material.WOOD, MapColor.DULL_RED).strength(2.5f).sounds(BlockSoundGroup.WOOD).nonOpaque()), cutoutMippedRenderLayer);
public static final Block TREE_TAP = add("tree_tap", new TreeTapBlock(of(Material.WOOD, MapColor.OAK_TAN).strength(2.5f).sounds(BlockSoundGroup.WOOD).nonOpaque().ticksRandomly()), cutoutRenderLayer);

//dungeon
// public static final DungeonSwitchBlock DUNGEON_SWITCH = add("dungeonswitch", new DungeonSwitchBlock(of(Material.METAL, MapColor.BLUE).strength(-1.0F, 3600000.0F)));
Expand All @@ -395,7 +410,7 @@ private static <V extends Block> V add(String id, V block, Action<? super V>...

/*
This is the same thing the add method above, but it doesn't wait to register or perform the actions.
This is required because some of the block settings code uses ID caches, so without it some blocks
This is required because some block settings code uses ID caches, so without it some blocks
behave like air.
*/
@SafeVarargs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ public class ParadiseLostBlockEntityTypes {
public static final BlockEntityType<FoodBowlBlockEntity> FOOD_BOWL = create(FoodBowlBlockEntity::new, ParadiseLostBlocks.FOOD_BOWL).build();
public static final BlockEntityType<IncubatorBlockEntity> INCUBATOR = create(IncubatorBlockEntity::new, ParadiseLostBlocks.INCUBATOR).build();
public static final BlockEntityType<CherineCampfireBlockEntity> CHERINE_CAMPFIRE = create(CherineCampfireBlockEntity::new, ParadiseLostBlocks.CHERINE_CAMPFIRE).build();
public static final BlockEntityType<TreeTapBlockEntity> TREE_TAP = create(TreeTapBlockEntity::new, ParadiseLostBlocks.TREE_TAP).build();
// public static final BlockEntityType<DungeonSwitchBlockEntity> DUNGEON_SWITCH = create(DungeonSwitchBlockEntity::new, ParadiseLostBlocks.DUNGEON_SWITCH).build();

public static void init() {
register("food_bowl", FOOD_BOWL);
register("incubator", INCUBATOR);
register("cherine_campfire", CHERINE_CAMPFIRE);
register("tree_tap", TREE_TAP);
// register("dungeonswitch", DUNGEON_SWITCH);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package net.id.paradiselost.blocks.blockentity;

import net.id.incubus_core.be.InventoryBlockEntity;
import net.id.paradiselost.recipe.ParadiseLostRecipeTypes;
import net.id.paradiselost.recipe.TreeTapRecipe;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventories;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.Packet;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

public class TreeTapBlockEntity extends BlockEntity implements InventoryBlockEntity {

private final DefaultedList<ItemStack> inventory;

public TreeTapBlockEntity(BlockPos pos, BlockState state) {
super(ParadiseLostBlockEntityTypes.TREE_TAP, pos, state);
inventory = DefaultedList.ofSize(1, ItemStack.EMPTY);
}

public void handleUse(PlayerEntity player, Hand hand, ItemStack handStack) {
ItemStack stored = inventory.get(0);
inventory.set(0, handStack);
player.setStackInHand(hand, stored);
markDirty();
}

@Override
public @NotNull HopperStrategy getHopperStrategy() {
return HopperStrategy.IN_ANY_OUT_BOTTOM;
}

@Override
public DefaultedList<ItemStack> getItems() {
return inventory;
}

@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);

Inventories.readNbt(nbt, inventory);
}

@Override
public void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
Inventories.writeNbt(nbt, inventory);
}

public BlockState getTappedState() {
return this.world.getBlockState(this.pos.offset(getCachedState().get(Properties.HORIZONTAL_FACING).getOpposite()));
}

public void tryCraft() {
ItemStack stack = getStack(0);
if (stack.isEmpty()) {
return;
}

Optional<TreeTapRecipe> recipe = this.world.getRecipeManager().getFirstMatch(ParadiseLostRecipeTypes.TREE_TAP_RECIPE_TYPE, this, this.world);
if (recipe.isPresent()) {
ItemStack output = recipe.get().craft(this);
stack.decrement(1);

// TODO: play a sound?
if (stack.isEmpty()) {
this.inventory.set(0, output);
updateInClientWorld();
} else {
ItemScatterer.spawn(world, pos.getX(), pos.getY(), pos.getZ(), output);
}
}
}

@Override
public NbtCompound toInitialChunkDataNbt() {
NbtCompound nbtCompound = new NbtCompound();
this.writeNbt(nbtCompound);
return nbtCompound;
}

@Nullable
@Override
public Packet<ClientPlayPacketListener> toUpdatePacket() {
return BlockEntityUpdateS2CPacket.create(this);
}

public void updateInClientWorld() {
((ServerWorld) world).getChunkManager().markForUpdate(pos);
}

}
141 changes: 141 additions & 0 deletions src/main/java/net/id/paradiselost/blocks/mechanical/TreeTapBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package net.id.paradiselost.blocks.mechanical;

import net.id.paradiselost.blocks.blockentity.TreeTapBlockEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.DirectionProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.ActionResult;
import net.minecraft.util.BlockMirror;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class TreeTapBlock extends ParadiseLostBlockWithEntity {

public static final DirectionProperty FACING = Properties.HORIZONTAL_FACING;
private static final VoxelShape SHAPE = Block.createCuboidShape(0, 0, 0, 16, 5, 16);

public TreeTapBlock(Settings settings) {
super(settings, true);
}

@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!player.isSneaking() && world.getBlockEntity(pos) instanceof TreeTapBlockEntity treeTapBlockEntity) {
treeTapBlockEntity.handleUse(player, hand, player.getStackInHand(hand));
return ActionResult.success(world.isClient());
}
return super.onUse(state, world, pos, player, hand, hit);
}

@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SHAPE;
}

@Override
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
Direction direction = state.get(FACING);
if (!direction.getAxis().isHorizontal()) {
return false;
}

BlockPos blockPos = pos.offset(direction.getOpposite());
BlockState blockState = world.getBlockState(blockPos);
return blockState.isSideSolidFullSquare(world, blockPos, direction);
}

@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}

@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
Direction direction = ctx.getSide();
if (!direction.getAxis().isHorizontal()) {
return null;
}

return this.getDefaultState().with(FACING, direction);
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(WATERLOGGED, POWERED, FACING);
}

@Override
public BlockState rotate(BlockState state, BlockRotation rotation) {
return state.with(FACING, rotation.rotate(state.get(FACING)));
}

@Override
public BlockState mirror(BlockState state, BlockMirror mirror) {
return state.rotate(mirror.getRotation(state.get(FACING)));
}

@Override
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
super.randomTick(state, world, pos, random);

if (!world.isClient && world.getBlockEntity(pos) instanceof TreeTapBlockEntity treeTapBlockEntity) {
treeTapBlockEntity.tryCraft();
}
}

@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new TreeTapBlockEntity(pos, state);
}

@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if (!state.isOf(newState.getBlock())) {
scatterContents(world, pos);
world.updateComparators(pos, this);
}
super.onStateReplaced(state, world, pos, newState, moved);
}

public static void scatterContents(World world, BlockPos pos) {
Block block = world.getBlockState(pos).getBlock();
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof Inventory inventory) {
ItemScatterer.spawn(world, pos, inventory);
world.updateComparators(pos, block);
}
}

@Override
public boolean hasComparatorOutput(BlockState state) {
return true;
}

@Override
public int getComparatorOutput(BlockState state, @NotNull World world, BlockPos pos) {
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry;
import net.id.paradiselost.blocks.blockentity.ParadiseLostBlockEntityTypes;
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;

@Environment(EnvType.CLIENT)
public class ParadiseLostBlockEntityRenderers {

@Environment(EnvType.CLIENT)
public static void initClient() {
BlockEntityRendererRegistry.register(ParadiseLostBlockEntityTypes.INCUBATOR, IncubatorBlockEntityRenderer::new);
BlockEntityRendererRegistry.register(ParadiseLostBlockEntityTypes.CHERINE_CAMPFIRE, CherineCampfireBlockEntityRenderer::new);
// BlockEntityRendererRegistry.register(ParadiseLostBlockEntityTypes.DUNGEON_SWITCH, DungeonSwitchBlockEntityRenderer::new);
BlockEntityRendererFactories.register(ParadiseLostBlockEntityTypes.INCUBATOR, IncubatorBlockEntityRenderer::new);
BlockEntityRendererFactories.register(ParadiseLostBlockEntityTypes.CHERINE_CAMPFIRE, CherineCampfireBlockEntityRenderer::new);
BlockEntityRendererFactories.register(ParadiseLostBlockEntityTypes.TREE_TAP, TreeTapBlockEntityRenderer::new);
// BlockEntityRendererFactories.register(ParadiseLostBlockEntityTypes.DUNGEON_SWITCH, DungeonSwitchBlockEntityRenderer::new);
}
}
Loading
Loading