You can now harvest pinecones and acorns from spruce and oak leaves using a hoe

This commit is contained in:
Sollace 2024-03-27 19:23:16 +00:00
parent e02c6f57a0
commit e931be3388
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
4 changed files with 109 additions and 2 deletions

View file

@ -14,6 +14,8 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
public class InteractionManager { public class InteractionManager {
@ -90,4 +92,8 @@ public class InteractionManager {
public void sendPlayerLookAngles(PlayerEntity player) { public void sendPlayerLookAngles(PlayerEntity player) {
} }
public void addBlockBreakingParticles(BlockPos pos, Direction direction) {
}
} }

View file

@ -41,6 +41,8 @@ import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -161,4 +163,9 @@ public class ClientInteractionManager extends InteractionManager {
c.networkHandler.sendPacket(new PlayerMoveC2SPacket.LookAndOnGround(player.getYaw(), player.getPitch(), player.isOnGround())); c.networkHandler.sendPacket(new PlayerMoveC2SPacket.LookAndOnGround(player.getYaw(), player.getPitch(), player.isOnGround()));
} }
} }
@Override
public void addBlockBreakingParticles(BlockPos pos, Direction direction) {
client.particleManager.addBlockBreakingParticles(pos, direction);
}
} }

View file

@ -0,0 +1,93 @@
package com.minelittlepony.unicopia.item;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil;
import com.minelittlepony.unicopia.server.world.BlockDestructionManager;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.HoeItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ToolMaterials;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.ItemTags;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.WorldEvents;
public class ForageableItem extends Item {
private static final List<ForageableItem> REGISTRY = new ArrayList<>();
static {
UseBlockCallback.EVENT.register((PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) -> {
if (player.shouldCancelInteraction()) {
return ActionResult.PASS;
}
ItemStack stack = player.getStackInHand(hand);
if (!stack.isIn(ItemTags.HOES)) {
return ActionResult.PASS;
}
BlockPos pos = hitResult.getBlockPos();
BlockState state = world.getBlockState(pos);
ActionResult result = ActionResult.PASS;
if (state.isIn(BlockTags.LEAVES)) {
player.swingHand(hand);
world.playSound(player, pos, state.getSoundGroup().getHitSound(), SoundCategory.BLOCKS);
InteractionManager.instance().addBlockBreakingParticles(pos, hitResult.getSide());
int miningLevel = (stack.getItem() instanceof HoeItem hoe ? hoe.getMaterial().getMiningLevel() : 59);
for (ForageableItem item : REGISTRY) {
if ((result = item.onTryForage(world, pos, state, stack, player, miningLevel)).isAccepted()) {
stack.damage(1, player, p -> p.sendToolBreakStatus(hand));
return result;
}
}
}
return result.isAccepted() ? ActionResult.SUCCESS : ActionResult.PASS;
});
}
private final Supplier<Block> targetBlock;
public ForageableItem(Settings settings, Supplier<Block> targetBlock) {
super(settings);
this.targetBlock = targetBlock;
REGISTRY.add(this);
}
public ActionResult onTryForage(World world, BlockPos pos, BlockState state, ItemStack stack, PlayerEntity player, int miningLevel) {
if (state.isOf(targetBlock.get())) {
int spawnChance = (int)((1F - MathHelper.clamp(miningLevel / (float)ToolMaterials.NETHERITE.getMiningLevel(), 0, 1)) * 32);
spawnChance -= EnchantmentUtil.getLuck(1, player);
if (spawnChance <= 0 || world.random.nextInt(spawnChance) == 0) {
Block.dropStack(world, pos, new ItemStack(this, 1 + EnchantmentHelper.getLooting(player)));
world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(state));
if (BlockDestructionManager.of(world).damageBlock(pos, world.getRandom().nextBetween(3, 7)) >= BlockDestructionManager.MAX_DAMAGE) {
world.breakBlock(pos, true);
}
return ActionResult.SUCCESS;
}
return ActionResult.FAIL;
}
return ActionResult.PASS;
}
}

View file

@ -16,6 +16,7 @@ import com.terraformersmc.terraform.boat.api.TerraformBoatType;
import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry;
import com.terraformersmc.terraform.boat.api.item.TerraformBoatItemHelper; import com.terraformersmc.terraform.boat.api.item.TerraformBoatItemHelper;
import net.minecraft.block.Blocks;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.entity.vehicle.BoatEntity;
@ -85,8 +86,8 @@ public interface UItems {
Item WHEAT_WORMS = register("wheat_worms", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.WORMS)), ItemGroups.NATURAL); Item WHEAT_WORMS = register("wheat_worms", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.WORMS)), ItemGroups.NATURAL);
Item MUFFIN = register("muffin", new MuffinItem(new Item.Settings().maxCount(32).food(FoodComponents.BREAD), 0), ItemGroups.FOOD_AND_DRINK); Item MUFFIN = register("muffin", new MuffinItem(new Item.Settings().maxCount(32).food(FoodComponents.BREAD), 0), ItemGroups.FOOD_AND_DRINK);
Item PINECONE = register("pinecone", new Item(new Item.Settings().food(UFoodComponents.PINECONE).maxCount(3)), ItemGroups.FOOD_AND_DRINK); Item PINECONE = register("pinecone", new ForageableItem(new Item.Settings().food(UFoodComponents.PINECONE).maxCount(16), () -> Blocks.SPRUCE_LEAVES), ItemGroups.FOOD_AND_DRINK);
Item ACORN = register("acorn", new Item(new Item.Settings().food(UFoodComponents.ACORN).maxCount(16)), ItemGroups.FOOD_AND_DRINK); Item ACORN = register("acorn", new ForageableItem(new Item.Settings().food(UFoodComponents.ACORN).maxCount(16), () -> Blocks.OAK_LEAVES), ItemGroups.FOOD_AND_DRINK);
Item MANGO = register("mango", new Item(new Item.Settings().food(UFoodComponents.MANGO)), ItemGroups.FOOD_AND_DRINK); Item MANGO = register("mango", new Item(new Item.Settings().food(UFoodComponents.MANGO)), ItemGroups.FOOD_AND_DRINK);
Item BANANA = register("banana", new Item(new Item.Settings().food(UFoodComponents.BANANA)), ItemGroups.FOOD_AND_DRINK); Item BANANA = register("banana", new Item(new Item.Settings().food(UFoodComponents.BANANA)), ItemGroups.FOOD_AND_DRINK);
Item CURING_JOKE = register("curing_joke", new CuringJokeItem(UBlocks.CURING_JOKE, new Item.Settings().food(UFoodComponents.POISON_JOKE)), ItemGroups.NATURAL); Item CURING_JOKE = register("curing_joke", new CuringJokeItem(UBlocks.CURING_JOKE, new Item.Settings().food(UFoodComponents.POISON_JOKE)), ItemGroups.NATURAL);