From 61460e6e6c100559d104321d77b36de386539d27 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 14 Dec 2020 21:23:09 +0300 Subject: [PATCH] Respawn obelisk (WIP) --- .../betterend/blocks/BlockRespawnObelisk.java | 174 ++++++++++++++++++ .../mixin/common/PlayerEntityMixin.java | 55 ++++++ .../java/ru/betterend/registry/EndBlocks.java | 3 + .../blockstates/respawn_obelisk.json | 7 + .../materialmaps/block/respawn_obelisk.json | 10 + .../models/block/respawn_obelisk_bottom.json | 47 +++++ .../models/block/respawn_obelisk_middle.json | 34 ++++ .../models/block/respawn_obelisk_top.json | 47 +++++ .../models/item/respawn_obelisk.json | 6 + .../textures/block/aurora_crystal.png | Bin 285 -> 384 bytes .../block/respawn_obelisk_bottom_side.png | Bin 0 -> 2393 bytes .../block/respawn_obelisk_top_and_side.png | Bin 0 -> 1900 bytes .../textures/item/respawn_obelisk.png | Bin 0 -> 1759 bytes .../resources/betterend.mixins.common.json | 1 + 14 files changed, 384 insertions(+) create mode 100644 src/main/java/ru/betterend/blocks/BlockRespawnObelisk.java create mode 100644 src/main/java/ru/betterend/mixin/common/PlayerEntityMixin.java create mode 100644 src/main/resources/assets/betterend/blockstates/respawn_obelisk.json create mode 100644 src/main/resources/assets/betterend/materialmaps/block/respawn_obelisk.json create mode 100644 src/main/resources/assets/betterend/models/block/respawn_obelisk_bottom.json create mode 100644 src/main/resources/assets/betterend/models/block/respawn_obelisk_middle.json create mode 100644 src/main/resources/assets/betterend/models/block/respawn_obelisk_top.json create mode 100644 src/main/resources/assets/betterend/models/item/respawn_obelisk.json create mode 100644 src/main/resources/assets/betterend/textures/block/respawn_obelisk_bottom_side.png create mode 100644 src/main/resources/assets/betterend/textures/block/respawn_obelisk_top_and_side.png create mode 100644 src/main/resources/assets/betterend/textures/item/respawn_obelisk.png diff --git a/src/main/java/ru/betterend/blocks/BlockRespawnObelisk.java b/src/main/java/ru/betterend/blocks/BlockRespawnObelisk.java new file mode 100644 index 00000000..5560afbb --- /dev/null +++ b/src/main/java/ru/betterend/blocks/BlockRespawnObelisk.java @@ -0,0 +1,174 @@ +package ru.betterend.blocks; + +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import com.google.common.collect.Lists; + +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.ShapeContext; +import net.minecraft.client.color.block.BlockColorProvider; +import net.minecraft.client.color.item.ItemColorProvider; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.context.LootContext; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.EnumProperty; +import net.minecraft.text.TranslatableText; +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.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.WorldView; +import ru.betterend.blocks.BlockProperties.TripleShape; +import ru.betterend.blocks.basis.BlockBase; +import ru.betterend.client.render.ERenderLayer; +import ru.betterend.interfaces.IColorProvider; +import ru.betterend.interfaces.IRenderTypeable; +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndItems; +import ru.betterend.util.BlocksHelper; +import ru.betterend.util.MHelper; + +public class BlockRespawnObelisk extends BlockBase implements IColorProvider, IRenderTypeable { + private static final VoxelShape VOXEL_SHAPE_BOTTOM = Block.createCuboidShape(1, 0, 1, 15, 16, 15); + private static final VoxelShape VOXEL_SHAPE_MIDDLE_TOP = Block.createCuboidShape(2, 0, 2, 14, 16, 14); + + public static final EnumProperty SHAPE = BlockProperties.TRIPLE_SHAPE; + + public BlockRespawnObelisk() { + super(FabricBlockSettings.copyOf(Blocks.END_STONE).luminance((state) -> { + return (state.get(SHAPE) == TripleShape.BOTTOM) ? 0 : 15; + })); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) { + return (state.get(SHAPE) == TripleShape.BOTTOM) ? VOXEL_SHAPE_BOTTOM : VOXEL_SHAPE_MIDDLE_TOP; + } + + @Override + protected void appendProperties(StateManager.Builder stateManager) { + stateManager.add(SHAPE); + } + + @Override + public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) { + for (int i = 0; i < 3; i++) { + if (!world.getBlockState(pos.up(i)).getMaterial().isReplaceable()) { + return false; + } + } + return true; + } + + @Override + public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { + state = this.getDefaultState(); + BlocksHelper.setWithUpdate(world, pos, state.with(SHAPE, TripleShape.BOTTOM)); + BlocksHelper.setWithUpdate(world, pos.up(), state.with(SHAPE, TripleShape.MIDDLE)); + BlocksHelper.setWithUpdate(world, pos.up(2), state.with(SHAPE, TripleShape.TOP)); + } + + @Override + public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + TripleShape shape = state.get(SHAPE); + if (shape == TripleShape.BOTTOM) { + if (world.getBlockState(pos.up()).isOf(this)) { + return state; + } + else { + return Blocks.AIR.getDefaultState(); + } + } + else if (shape == TripleShape.MIDDLE) { + if (world.getBlockState(pos.up()).isOf(this) && world.getBlockState(pos.down()).isOf(this)) { + return state; + } + else { + return Blocks.AIR.getDefaultState(); + } + } + else { + if (world.getBlockState(pos.down()).isOf(this)) { + return state; + } + else { + return Blocks.AIR.getDefaultState(); + } + } + } + + @Override + public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + if (player.isCreative()) { + TripleShape shape = state.get(SHAPE); + if (shape == TripleShape.MIDDLE) { + BlocksHelper.setWithUpdate(world, pos.down(), Blocks.AIR); + } + else if (shape == TripleShape.TOP) { + BlocksHelper.setWithUpdate(world, pos.down(2), Blocks.AIR); + } + } + super.onBreak(world, pos, state, player); + } + + @Override + public List getDroppedStacks(BlockState state, LootContext.Builder builder) { + if (state.get(SHAPE) == TripleShape.BOTTOM) { + return Lists.newArrayList(new ItemStack(this)); + } + else { + return Lists.newArrayList(); + } + } + + @Override + public ERenderLayer getRenderLayer() { + return ERenderLayer.TRANSLUCENT; + } + + @Override + public BlockColorProvider getProvider() { + return ((IColorProvider) EndBlocks.AURORA_CRYSTAL).getProvider(); + } + + @Override + public ItemColorProvider getItemProvider() { + return (stack, tintIndex) -> { + return MHelper.color(255, 255, 255); + }; + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + ItemStack itemStack = player.getStackInHand(hand); + boolean canActivate = itemStack.getItem() == EndItems.AMBER_GEM && itemStack.getCount() > 3; + if (hand != Hand.MAIN_HAND || !canActivate) { + return ActionResult.FAIL; + } + if (!world.isClient) { + ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) player; + serverPlayerEntity.setSpawnPoint(world.getRegistryKey(), pos, 0.0F, false, true); + serverPlayerEntity.sendMessage(new TranslatableText("message.betterend.set_spawn"), true); + world.playSound(null, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, SoundEvents.BLOCK_RESPAWN_ANCHOR_SET_SPAWN, SoundCategory.BLOCKS, 1.0F, 1.0F); + if (!player.isCreative()) { + itemStack.decrement(4); + } + } + return player.isCreative() ? ActionResult.PASS : ActionResult.success(world.isClient); + } +} diff --git a/src/main/java/ru/betterend/mixin/common/PlayerEntityMixin.java b/src/main/java/ru/betterend/mixin/common/PlayerEntityMixin.java new file mode 100644 index 00000000..e00fa670 --- /dev/null +++ b/src/main/java/ru/betterend/mixin/common/PlayerEntityMixin.java @@ -0,0 +1,55 @@ +package ru.betterend.mixin.common; + +import java.util.Optional; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import ru.betterend.blocks.BlockProperties; +import ru.betterend.blocks.BlockProperties.TripleShape; +import ru.betterend.registry.EndBlocks; +import ru.betterend.util.BlocksHelper; +import ru.betterend.util.MHelper; + +@Mixin(PlayerEntity.class) +public abstract class PlayerEntityMixin { + private static Direction[] HORIZONTAL; + + @Inject(method = "findRespawnPosition", at = @At(value = "HEAD"), cancellable = true) + private static void statueRespawn(ServerWorld world, BlockPos pos, float f, boolean bl, boolean bl2, CallbackInfoReturnable> info) { + BlockState blockState = world.getBlockState(pos); + if (blockState.isOf(EndBlocks.RESPAWN_OBELISK)) { + info.setReturnValue(beObeliskRespawnPosition(world, pos, blockState)); + info.cancel(); + } + } + + private static Optional beObeliskRespawnPosition(ServerWorld world, BlockPos pos, BlockState state) { + if (state.get(BlockProperties.TRIPLE_SHAPE) == TripleShape.TOP) { + pos = pos.down(2); + } + else if (state.get(BlockProperties.TRIPLE_SHAPE) == TripleShape.MIDDLE) { + pos = pos.down(); + } + if (HORIZONTAL == null) { + HORIZONTAL = BlocksHelper.makeHorizontal(); + } + MHelper.shuffle(HORIZONTAL, world.getRandom()); + for (Direction dir: HORIZONTAL) { + BlockPos p = pos.offset(dir); + BlockState state2 = world.getBlockState(p); + if (!state2.getMaterial().blocksMovement() && state2.getCollisionShape(world, pos).isEmpty()) { + return Optional.of(Vec3d.of(p).add(0.5, 0, 0.5)); + } + } + return Optional.empty(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/betterend/registry/EndBlocks.java b/src/main/java/ru/betterend/registry/EndBlocks.java index 5fd62b0c..ffac7064 100644 --- a/src/main/java/ru/betterend/registry/EndBlocks.java +++ b/src/main/java/ru/betterend/registry/EndBlocks.java @@ -54,6 +54,7 @@ import ru.betterend.blocks.BlockMurkweed; import ru.betterend.blocks.BlockNeedlegrass; import ru.betterend.blocks.BlockPath; import ru.betterend.blocks.BlockPythadendronSapling; +import ru.betterend.blocks.BlockRespawnObelisk; import ru.betterend.blocks.BlockShadowBerry; import ru.betterend.blocks.BlockShadowGrass; import ru.betterend.blocks.BlockSulphurCrystal; @@ -245,6 +246,8 @@ public class EndBlocks { public static final Block AURORA_CRYSTAL = registerBlock("aurora_crystal", new AuroraCrystalBlock()); public static final Block AMBER_BLOCK = registerBlock("amber_block", new BlockAmber()); + public static final Block RESPAWN_OBELISK = registerBlock("respawn_obelisk", new BlockRespawnObelisk()); + // Lanterns public static final Block ANDESITE_LANTERN = registerBlock("andesite_lantern", new BlockStoneLantern(Blocks.ANDESITE)); public static final Block DIORITE_LANTERN = registerBlock("diorite_lantern", new BlockStoneLantern(Blocks.DIORITE)); diff --git a/src/main/resources/assets/betterend/blockstates/respawn_obelisk.json b/src/main/resources/assets/betterend/blockstates/respawn_obelisk.json new file mode 100644 index 00000000..b7ccb4d2 --- /dev/null +++ b/src/main/resources/assets/betterend/blockstates/respawn_obelisk.json @@ -0,0 +1,7 @@ +{ + "variants": { + "shape=top": { "model": "betterend:block/respawn_obelisk_top" }, + "shape=middle": { "model": "betterend:block/respawn_obelisk_middle" }, + "shape=bottom": { "model": "betterend:block/respawn_obelisk_bottom" } + } +} diff --git a/src/main/resources/assets/betterend/materialmaps/block/respawn_obelisk.json b/src/main/resources/assets/betterend/materialmaps/block/respawn_obelisk.json new file mode 100644 index 00000000..31a6585c --- /dev/null +++ b/src/main/resources/assets/betterend/materialmaps/block/respawn_obelisk.json @@ -0,0 +1,10 @@ +{ + "defaultMap": { + "spriteMap": [ + { + "sprite": "betterend:block/aurora_crystal", + "material": "betterend:glow_all" + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/respawn_obelisk_bottom.json b/src/main/resources/assets/betterend/models/block/respawn_obelisk_bottom.json new file mode 100644 index 00000000..78495db5 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/respawn_obelisk_bottom.json @@ -0,0 +1,47 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/amber_block", + "texture": "betterend:block/amber_block", + "side": "betterend:block/respawn_obelisk_bottom_side" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 1, 0, 1 ], + "to": [ 15, 4, 15 ], + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#texture", "cullface": "down" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#texture" }, + "north": { "uv": [ 1, 12, 15, 16 ], "texture": "#side" }, + "south": { "uv": [ 1, 12, 15, 16 ], "texture": "#side" }, + "west": { "uv": [ 1, 12, 15, 16 ], "texture": "#side" }, + "east": { "uv": [ 1, 12, 15, 16 ], "texture": "#side" } + } + }, + { + "__comment": "Box1", + "from": [ 2, 4, 2 ], + "to": [ 14, 14, 14 ], + "faces": { + "north": { "uv": [ 2, 2, 14, 12 ], "texture": "#side" }, + "south": { "uv": [ 2, 2, 14, 12 ], "texture": "#side" }, + "west": { "uv": [ 2, 2, 14, 12 ], "texture": "#side" }, + "east": { "uv": [ 2, 2, 14, 12 ], "texture": "#side" } + } + }, + { + "__comment": "Box1", + "from": [ 1, 14, 1 ], + "to": [ 15, 16, 15 ], + "faces": { + "down": { "uv": [ 1, 1, 15, 15 ], "texture": "#texture" }, + "up": { "uv": [ 1, 1, 15, 15 ], "texture": "#texture" }, + "north": { "uv": [ 1, 0, 15, 2 ], "texture": "#side" }, + "south": { "uv": [ 1, 0, 15, 2 ], "texture": "#side" }, + "west": { "uv": [ 1, 0, 15, 2 ], "texture": "#side" }, + "east": { "uv": [ 1, 0, 15, 2 ], "texture": "#side" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/respawn_obelisk_middle.json b/src/main/resources/assets/betterend/models/block/respawn_obelisk_middle.json new file mode 100644 index 00000000..499c8183 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/respawn_obelisk_middle.json @@ -0,0 +1,34 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/amber_block", + "texture": "betterend:block/respawn_obelisk_top_and_side", + "crystal": "betterend:block/aurora_crystal" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 2, 0, 2 ], + "to": [ 14, 2, 14 ], + "faces": { + "up": { "uv": [ 2, 2, 14, 14 ], "texture": "#texture" }, + "north": { "uv": [ 2, 14, 14, 16 ], "texture": "#texture" }, + "south": { "uv": [ 2, 14, 14, 16 ], "texture": "#texture" }, + "west": { "uv": [ 2, 14, 14, 16 ], "texture": "#texture" }, + "east": { "uv": [ 2, 14, 14, 16 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 3, 2, 3 ], + "to": [ 13, 16, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 0, 13, 14 ], "texture": "#crystal", "tintindex": 0 }, + "south": { "uv": [ 3, 0, 13, 14 ], "texture": "#crystal", "tintindex": 0 }, + "west": { "uv": [ 3, 0, 13, 14 ], "texture": "#crystal", "tintindex": 0 }, + "east": { "uv": [ 3, 0, 13, 14 ], "texture": "#crystal", "tintindex": 0 } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/block/respawn_obelisk_top.json b/src/main/resources/assets/betterend/models/block/respawn_obelisk_top.json new file mode 100644 index 00000000..63a80682 --- /dev/null +++ b/src/main/resources/assets/betterend/models/block/respawn_obelisk_top.json @@ -0,0 +1,47 @@ +{ + "__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio", + "textures": { + "particle": "betterend:block/amber_block", + "texture": "betterend:block/respawn_obelisk_top_and_side", + "crystal": "betterend:block/aurora_crystal" + }, + "elements": [ + { + "__comment": "Box1", + "from": [ 2, 12, 2 ], + "to": [ 14, 14, 14 ], + "faces": { + "down": { "uv": [ 2, 2, 14, 14 ], "texture": "#texture" }, + "up": { "uv": [ 2, 2, 14, 14 ], "texture": "#texture" }, + "north": { "uv": [ 2, 0, 14, 2 ], "texture": "#texture" }, + "south": { "uv": [ 2, 0, 14, 2 ], "texture": "#texture" }, + "west": { "uv": [ 2, 0, 14, 2 ], "texture": "#texture" }, + "east": { "uv": [ 2, 0, 14, 2 ], "texture": "#texture" } + } + }, + { + "__comment": "Box1", + "from": [ 3, 0, 3 ], + "to": [ 13, 12, 13 ], + "shade": false, + "faces": { + "north": { "uv": [ 3, 4, 13, 16 ], "texture": "#crystal", "tintindex": 0 }, + "south": { "uv": [ 3, 4, 13, 16 ], "texture": "#crystal", "tintindex": 0 }, + "west": { "uv": [ 3, 4, 13, 16 ], "texture": "#crystal", "tintindex": 0 }, + "east": { "uv": [ 3, 4, 13, 16 ], "texture": "#crystal", "tintindex": 0 } + } + }, + { + "__comment": "Box1", + "from": [ 3, 14, 3 ], + "to": [ 13, 16, 13 ], + "faces": { + "up": { "uv": [ 3, 3, 13, 13 ], "texture": "#texture", "cullface": "up" }, + "north": { "uv": [ 3, 0, 13, 2 ], "texture": "#texture" }, + "south": { "uv": [ 3, 0, 13, 2 ], "texture": "#texture" }, + "west": { "uv": [ 3, 0, 13, 2 ], "texture": "#texture" }, + "east": { "uv": [ 3, 0, 13, 2 ], "texture": "#texture" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/betterend/models/item/respawn_obelisk.json b/src/main/resources/assets/betterend/models/item/respawn_obelisk.json new file mode 100644 index 00000000..e7f6febb --- /dev/null +++ b/src/main/resources/assets/betterend/models/item/respawn_obelisk.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "betterend:item/respawn_obelisk" + } +} diff --git a/src/main/resources/assets/betterend/textures/block/aurora_crystal.png b/src/main/resources/assets/betterend/textures/block/aurora_crystal.png index 560e74b552fab8749ac5b858e157f6bf23bbe006..1998fb7e2fb99aaeef2e63d2ce7f7b70d9100677 100644 GIT binary patch delta 357 zcmV-r0h<1u0)PXMB!2;OQb$4nuFf3k00004XF*Lt006O%3;baP00009a7bBm000id z000id0mpBsWB>pG6-h)vR5(wilFthPK^(xx^5fO+G;iK#_B-EMK3ZSQMcZOpt$(Z?+*LL-INOQ5!MtA5 z)oq%yyU07om?l1jqt#qVg(FAi@WKAl{REDO^@$2&jd$uTGoH$@Z{SmZ>Yy5k+t%3h zgLlK}GxE@3Ig{&vuZ4&_4kYmMgAt-9S~O(y2u4MiW0V{C!4!gr5h5R1^bDTB?tZX0 zMDqGLw$rd2@m>x_2u(wfs#I@F{z!o7oZrCk#6K`9mp%9u#$4XQuW-6jX1uqZFI5FV|kgGQue#7y}^00000NkvXXu0mjf Dt_q=k delta 257 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/betterend/textures/item/respawn_obelisk.png b/src/main/resources/assets/betterend/textures/item/respawn_obelisk.png new file mode 100644 index 0000000000000000000000000000000000000000..05b978d6e458a3f6150702f6fa8e7651cdf46eff GIT binary patch literal 1759 zcmbVNYitx%6rP$EX|^%0>8M?)Gx7v-JQrm5|J}}&!xjQ@Q&fIb4 zw!1AVLM3W2#DqVl@qtJh^@qP`W7SBAuT)~yXcIwW8o-38i6KxcKEONs5)C4<$?V*F z_dDM?-#O==eY&^j?)ti$>L`k;k9WoT$a{tNEMG>xZ#i=TkXNnUb)QR7*WKtnRn)}u zt0}5x+(-=KL8V((k?8{(N7c%MVMqz;T1ay zGe*~#1N+B%66)BHDrwB7Ho7%069N-rK-WzSvzQUt||y zG8o%3$K`T4U(WACj?M{^ByqgRi6To7tUGF9kY_D-eVHK!UDYvcY#@vF7(ogR;|N0{ zElM!$3a#aq(nJ!*<$=u!KHig50NNRZk()vP0w_*Dc2w9oLOibb)Yx*=fdC^Xfl#(w zsNS+XIvVu~(?T~V4NF5g_tuMSU<_awVMJc!SwUolKtd#i3zFL1&iiGaFG3a43L3!R z%D_l7(xd+gt>jmZqAYS0q>(uM46Uhh8aXB)xiCziL(aDJLKKQ3$1N8FONH@Rgdwth zhM~zJUQCCAFu(?h2sRuHs4P$gzzQjUARG>mgO*g;K8Dm`uTEuq?SI;Db_{a4K=!J6 z$R+qocbTP~C~`^l+|m{40D5VaHQGFxUYIRmkQUNXi0A?VHl+r_Y$}}sERdk8fpp5R zN>VH5-3MYs7gt3h?(!ZBT`G4OUIe2hzy0vxN(6MFF=e277cRo6UZ+8gDIFVEU6CSf zE&~baW!kR@b5R=SfCJlgQoSqbaITz#q7?3*DhrvqXp)rSWITDx%3LIy%4CHW8K(}J zo5^k8wo+8pHSt(`qUFfc-pD=gZC$zRrKKq)KXr~?IR4Ro`qcJQCpX-@`@-B*fB288 zw>Bm}>-@ZZ`SdzN+56>#Pwr9PU;WP4-#uo}%`7!HzO3Ny>t?@t>hxK8_KCTL{(;5U zZmTByNAo*JHdi&DxEBACm^pC6j)`Y1_;cF_c+0BYEAD)uA+% zKOVoo9&b5(dRykmWYcK(;sa-DsL3Cu-|PtJ11DF$TO(|LWr54ho~SmDe$u#hX=z`> zhhIEfn@cVo{B``t#YX+P^XD5LvNjxFyNf#T>AK&V^w%3}Hd07m_W1Ai^#l6k{NnT@ pM-NYQoZT_gJ%1>(@7S?(YgRR*>Td>KZSwwt;+;LQH#)ZN{1Y*UPv`&u literal 0 HcmV?d00001 diff --git a/src/main/resources/betterend.mixins.common.json b/src/main/resources/betterend.mixins.common.json index 9308e018..1d7539f8 100644 --- a/src/main/resources/betterend.mixins.common.json +++ b/src/main/resources/betterend.mixins.common.json @@ -24,6 +24,7 @@ "HostileEntityMixin", "LivingEntityMixin", "BoneMealItemMixin", + "PlayerEntityMixin", "SlimeEntityMixin", "BrewingAccessor", "EntityMixin"