callGetStateManager() {
+ return super.getStateManager();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/ExtendBlockEntityProvider.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/ExtendBlockEntityProvider.java
new file mode 100644
index 000000000..2b9481a95
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/ExtendBlockEntityProvider.java
@@ -0,0 +1,79 @@
+package net.pitan76.mcpitanlib.api.block;
+
+import net.minecraft.block.BlockEntityProvider;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.block.entity.BlockEntityTicker;
+import net.minecraft.block.entity.BlockEntityType;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.pitan76.mcpitanlib.api.event.block.TileCreateEvent;
+import net.pitan76.mcpitanlib.api.tile.ExtendBlockEntityTicker;
+import org.jetbrains.annotations.Nullable;
+
+public interface ExtendBlockEntityProvider extends BlockEntityProvider {
+
+ /**
+ * @deprecated Use {@link #createBlockEntity(TileCreateEvent)} instead.
+ */
+ @Deprecated
+ @Nullable
+ default BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
+ return createBlockEntity(new TileCreateEvent(pos, state));
+ }
+
+ /**
+ * create instance of BlockEntity
+ * @param event TileCreateEvent
+ * @return BlockEntity
+ *
+ * {@code
+ * public BlockEntity createBlockEntity(TileCreateEvent e) {
+ * return new ExampleBlockEntity(e); // ExampleBlockEntity extends CompatBlockEntity
+ * }
+ */
+ @Nullable
+ default BlockEntity createBlockEntity(TileCreateEvent event) {
+ if (getBlockEntityType() == null) return null;
+
+ // return new ...BlockEntity(pos, state)
+ return getBlockEntityType().instantiate(event.getBlockPos(), event.getBlockState());
+ }
+
+ @Nullable
+ default BlockEntityType getBlockEntityType() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ default BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) {
+ if (isTick()) {
+ return ((world1, pos, state1, blockEntity) -> {
+ if (getBlockEntityType() == null || blockEntity == getBlockEntityType().get(world, pos)) {
+ if (blockEntity instanceof ExtendBlockEntityTicker>) {
+ ExtendBlockEntityTicker ticker = (ExtendBlockEntityTicker) blockEntity;
+ ticker.tick(world, pos, state, blockEntity);
+ } else if (blockEntity instanceof BlockEntityTicker>) {
+ BlockEntityTicker ticker = (BlockEntityTicker) blockEntity;
+ ticker.tick(world, pos, state, blockEntity);
+ }
+ }
+ });
+ }
+ return BlockEntityProvider.super.getTicker(world, state, type);
+ }
+
+ @Nullable
+ default ExtendBlockEntityTicker getCompatibleTicker(World world, BlockState state, BlockEntityType type) {
+ BlockEntityTicker ticker = getTicker(world, state, type);
+ if (ticker instanceof ExtendBlockEntityTicker)
+ return (ExtendBlockEntityTicker) ticker;
+
+ return null;
+ }
+
+ default boolean isTick() {
+ return false;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/ExtendBlockProvider.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/ExtendBlockProvider.java
new file mode 100644
index 000000000..996661e2f
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/ExtendBlockProvider.java
@@ -0,0 +1,161 @@
+package net.pitan76.mcpitanlib.api.block;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.item.ItemStack;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.shape.VoxelShape;
+import net.pitan76.mcpitanlib.api.event.block.*;
+import net.pitan76.mcpitanlib.api.event.block.result.BlockBreakResult;
+import net.pitan76.mcpitanlib.api.event.item.ItemAppendTooltipEvent;
+import net.pitan76.mcpitanlib.api.util.CompatActionResult;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+
+import java.util.List;
+
+public interface ExtendBlockProvider {
+
+ /**
+ * get collision voxel shape
+ * @param event CollisionShapeEvent
+ * @param options Options
+ * @return VoxelShape
+ */
+ default VoxelShape getCollisionShape(CollisionShapeEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * get outline voxel shape
+ * @param event OutlineShapeEvent
+ * @param options Options
+ * @return VoxelShape
+ */
+ default VoxelShape getOutlineShape(OutlineShapeEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * block scheduled tick event
+ * @param event BlockScheduledTickEvent
+ * @param options Options
+ */
+ default void scheduledTick(BlockScheduledTickEvent event, Options options) {
+ options.cancel = false;
+ }
+
+ /**
+ * block right click event
+ * @param event BlockUseEvent
+ * @param options Options
+ * @return ActionResult
+ */
+ default CompatActionResult onRightClick(BlockUseEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * screen handler create event
+ * @param event ScreenHandlerCreateEvent
+ * @param options Options
+ * @return ScreenHandler
+ */
+ default ScreenHandler createScreenHandler(ScreenHandlerCreateEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * get screen title
+ * @return Text
+ */
+ default Text getScreenTitle() {
+ return TextUtil.literal("");
+ }
+
+ /**
+ * block placed event
+ * @param event BlockPlacedEvent
+ * @param options Options
+ */
+ default void onPlaced(BlockPlacedEvent event, Options options) {
+ options.cancel = false;
+ }
+
+ /**
+ * block break event
+ * @param event BlockBreakEvent
+ * @param options Options
+ * @return BlockBreakResult
+ */
+ default BlockBreakResult onBreak(BlockBreakEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * block state replaced event
+ * @param event StateReplacedEvent
+ * @param options Options
+ */
+ default void onStateReplaced(StateReplacedEvent event, Options options) {
+ options.cancel = false;
+ }
+
+ /**
+ * get pick stack
+ * @param event PickStackEvent
+ * @param options Options
+ * @return ItemStack
+ */
+ default ItemStack getPickStack(PickStackEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * get placement state
+ * @param args PlacementStateArgs
+ * @param options Options
+ */
+ default BlockState getPlacementState(PlacementStateArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * append properties
+ * @param args AppendPropertiesArgs
+ * @param options Options
+ */
+ default void appendProperties(AppendPropertiesArgs args, Options options) {
+ options.cancel = false;
+ }
+
+ /**
+ * get dropped stacks
+ * @param args DroppedStacksArgs
+ * @param options Options
+ * @return List
+ */
+ default List getDroppedStacks(DroppedStacksArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ default void appendTooltip(ItemAppendTooltipEvent event, Options options) {
+ options.cancel = false;
+ }
+
+ default Boolean canPathfindThrough(CanPathfindThroughArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ public static class Options {
+ public boolean cancel = true;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/RenderTypeArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/RenderTypeArgs.java
new file mode 100644
index 000000000..645b17745
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/RenderTypeArgs.java
@@ -0,0 +1,21 @@
+package net.pitan76.mcpitanlib.api.block.args;
+
+import net.minecraft.block.BlockState;
+import net.pitan76.mcpitanlib.midohra.holder.BlockStatePropertyHolder;
+
+public class RenderTypeArgs implements BlockStatePropertyHolder {
+ public BlockState state;
+
+ public RenderTypeArgs(BlockState state) {
+ this.state = state;
+ }
+
+ public BlockState getRawBlockState() {
+ return state;
+ }
+
+ @Override
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getBlockState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(getRawBlockState());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/RotateArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/RotateArgs.java
new file mode 100644
index 000000000..0b4e6339e
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/RotateArgs.java
@@ -0,0 +1,38 @@
+package net.pitan76.mcpitanlib.api.block.args;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.util.BlockRotation;
+import net.minecraft.util.math.Direction;
+import net.pitan76.mcpitanlib.midohra.holder.BlockStatePropertyHolder;
+
+public class RotateArgs implements BlockStatePropertyHolder {
+
+ public BlockState state;
+ public BlockRotation rotation;
+
+ public RotateArgs(BlockState state, BlockRotation rotation) {
+ this.state = state;
+ this.rotation = rotation;
+ }
+
+ public BlockState getRawBlockState() {
+ return state;
+ }
+
+ public BlockRotation getRawRotation() {
+ return rotation;
+ }
+
+ @Override
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getBlockState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(state);
+ }
+
+ public Direction rotate(Direction direction) {
+ return rotation.rotate(direction);
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.Direction rotate(net.pitan76.mcpitanlib.midohra.util.math.Direction direction) {
+ return net.pitan76.mcpitanlib.midohra.util.math.Direction.of(rotation.rotate(direction.toMinecraft()));
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/SideInvisibleArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/SideInvisibleArgs.java
new file mode 100644
index 000000000..503136183
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/SideInvisibleArgs.java
@@ -0,0 +1,46 @@
+package net.pitan76.mcpitanlib.api.block.args;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.util.math.Direction;
+
+public class SideInvisibleArgs {
+ public BlockState state;
+ public BlockState stateFrom;
+ public Direction direction;
+
+ public SideInvisibleArgs(BlockState state, BlockState stateFrom, Direction direction) {
+ this.state = state;
+ this.stateFrom = stateFrom;
+ this.direction = direction;
+ }
+
+ public SideInvisibleArgs(net.pitan76.mcpitanlib.midohra.block.BlockState state, net.pitan76.mcpitanlib.midohra.block.BlockState stateFrom, net.pitan76.mcpitanlib.midohra.util.math.Direction direction) {
+ this.state = state.toMinecraft();
+ this.stateFrom = stateFrom.toMinecraft();
+ this.direction = direction.toMinecraft();
+ }
+
+ public BlockState getState() {
+ return state;
+ }
+
+ public BlockState getStateFrom() {
+ return stateFrom;
+ }
+
+ public Direction getDirection() {
+ return direction;
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getMidohraState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(getState());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getMidohraStateFrom() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(getStateFrom());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.Direction getMidohraDirection() {
+ return net.pitan76.mcpitanlib.midohra.util.math.Direction.of(getDirection());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/CanPlaceAtArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/CanPlaceAtArgs.java
new file mode 100644
index 000000000..c111c0aa3
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/CanPlaceAtArgs.java
@@ -0,0 +1,54 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.pitan76.mcpitanlib.api.event.BaseEvent;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+import net.pitan76.mcpitanlib.midohra.util.math.BlockPos;
+import net.pitan76.mcpitanlib.midohra.world.WorldView;
+
+public class CanPlaceAtArgs extends BaseEvent {
+ public final net.minecraft.block.BlockState state;
+ public final net.minecraft.world.WorldView world;
+ public final net.minecraft.util.math.BlockPos pos;
+
+ public CanPlaceAtArgs(net.minecraft.block.BlockState state, net.minecraft.world.WorldView world, net.minecraft.util.math.BlockPos pos) {
+ this.state = state;
+ this.world = world;
+ this.pos = pos;
+ }
+
+ public CanPlaceAtArgs(BlockState state, WorldView world, BlockPos pos) {
+ this(state.toMinecraft(), world.toMinecraft(), pos.toMinecraft());
+ }
+
+ public net.minecraft.block.BlockState getState() {
+ return state;
+ }
+
+ public net.minecraft.world.WorldView getWorld() {
+ return world;
+ }
+
+ public net.minecraft.util.math.BlockPos getPos() {
+ return pos;
+ }
+
+ public BlockState getMidohraState() {
+ return BlockState.of(state);
+ }
+
+ public WorldView getMidohraWorld() {
+ return WorldView.of(world);
+ }
+
+ public BlockPos getMidohraPos() {
+ return BlockPos.of(pos);
+ }
+
+ public boolean isClient() {
+ return world.isClient();
+ }
+
+ public boolean isServer() {
+ return !world.isClient();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/CollisionShapeEvent.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/CollisionShapeEvent.java
new file mode 100644
index 000000000..a5544b4db
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/CollisionShapeEvent.java
@@ -0,0 +1,17 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.block.ShapeContext;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+import net.pitan76.mcpitanlib.midohra.util.math.BlockPos;
+import net.pitan76.mcpitanlib.midohra.world.BlockView;
+
+public class CollisionShapeEvent extends OutlineShapeEvent {
+
+ public CollisionShapeEvent(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
+ super(state, world, pos, context);
+ }
+
+ public CollisionShapeEvent(net.minecraft.block.BlockState state, net.minecraft.world.BlockView world, net.minecraft.util.math.BlockPos pos, ShapeContext context) {
+ super(BlockState.of(state), BlockView.of(world), BlockPos.of(pos), context);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/GetComparatorOutputArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/GetComparatorOutputArgs.java
new file mode 100644
index 000000000..2fc46d19f
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/GetComparatorOutputArgs.java
@@ -0,0 +1,53 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.pitan76.mcpitanlib.api.event.BaseEvent;
+import net.pitan76.mcpitanlib.api.util.WorldUtil;
+import net.pitan76.mcpitanlib.api.util.screen.ScreenHandlerUtil;
+
+public class GetComparatorOutputArgs extends BaseEvent {
+ public BlockState state;
+ public World world;
+ public BlockPos pos;
+
+ public GetComparatorOutputArgs(BlockState state, World world, BlockPos pos) {
+ this.state = state;
+ this.world = world;
+ this.pos = pos;
+ }
+
+ public BlockState getState() {
+ return state;
+ }
+
+ public World getWorld() {
+ return world;
+ }
+
+ public BlockPos getPos() {
+ return pos;
+ }
+
+ public BlockEntity getBlockEntity() {
+ return WorldUtil.getBlockEntity(world, pos);
+ }
+
+ public int calcComparatorOutputFromBlockEntity() {
+ return ScreenHandlerUtil.calcComparatorOutput(getBlockEntity());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getMidohraState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(state);
+ }
+
+ public net.pitan76.mcpitanlib.midohra.world.World getMidohraWorld() {
+ return net.pitan76.mcpitanlib.midohra.world.World.of(world);
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.BlockPos getMidohraPos() {
+ return net.pitan76.mcpitanlib.midohra.util.math.BlockPos.of(pos);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/HasComparatorOutputArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/HasComparatorOutputArgs.java
new file mode 100644
index 000000000..2fe77f18a
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/HasComparatorOutputArgs.java
@@ -0,0 +1,16 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.block.BlockState;
+import net.pitan76.mcpitanlib.api.event.BaseEvent;
+
+public class HasComparatorOutputArgs extends BaseEvent {
+ public BlockState state;
+
+ public HasComparatorOutputArgs(BlockState state) {
+ this.state = state;
+ }
+
+ public BlockState getState() {
+ return state;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/OutlineShapeEvent.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/OutlineShapeEvent.java
new file mode 100644
index 000000000..225949458
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/OutlineShapeEvent.java
@@ -0,0 +1,64 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.block.ShapeContext;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.item.Item;
+import net.pitan76.mcpitanlib.api.event.BaseEvent;
+import net.pitan76.mcpitanlib.midohra.block.entity.BlockEntityWrapper;
+import net.pitan76.mcpitanlib.midohra.holder.BlockStatePropertyHolder;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+import net.pitan76.mcpitanlib.midohra.item.ItemWrapper;
+import net.pitan76.mcpitanlib.midohra.util.math.BlockPos;
+import net.pitan76.mcpitanlib.midohra.world.BlockView;
+import net.pitan76.mcpitanlib.midohra.world.IWorldView;
+
+public class OutlineShapeEvent extends BaseEvent implements BlockStatePropertyHolder {
+ public BlockState state;
+ public BlockView world;
+ public BlockPos pos;
+ public ShapeContext context;
+
+ public OutlineShapeEvent(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
+ this.state = state;
+ this.world = world;
+ this.pos = pos;
+ this.context = context;
+ }
+
+ public OutlineShapeEvent(net.minecraft.block.BlockState state, net.minecraft.world.BlockView world, net.minecraft.util.math.BlockPos pos, net.minecraft.block.ShapeContext context) {
+ this(BlockState.of(state), BlockView.of(world), BlockPos.of(pos), context);
+ }
+
+ @Override
+ public BlockState getBlockState() {
+ return state;
+ }
+
+ public BlockEntityWrapper getBlockEntity() {
+ return world.getBlockEntity(pos);
+ }
+
+ public BlockEntity getRawBlockEntity() {
+ return getBlockEntity().get();
+ }
+
+ public IWorldView getWorldView() {
+ return world;
+ }
+
+ public BlockPos getPos() {
+ return pos;
+ }
+
+ public ShapeContext getContext() {
+ return context;
+ }
+
+ public boolean isHolding(Item item) {
+ return getContext().isHolding(item);
+ }
+
+ public boolean isHolding(ItemWrapper item) {
+ return isHolding(item.get());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/PlacementStateArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/PlacementStateArgs.java
new file mode 100644
index 000000000..ebc3d207b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/PlacementStateArgs.java
@@ -0,0 +1,175 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.item.ItemPlacementContext;
+import net.minecraft.state.property.Property;
+import net.minecraft.util.Hand;
+import net.minecraft.util.hit.BlockHitResult;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
+import net.pitan76.mcpitanlib.api.entity.Player;
+import net.pitan76.mcpitanlib.api.event.BaseEvent;
+import net.pitan76.mcpitanlib.api.event.item.ItemUseOnBlockEvent;
+import net.pitan76.mcpitanlib.api.util.BlockStateUtil;
+import net.pitan76.mcpitanlib.midohra.holder.BlockStatePropertyHolder;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+import net.pitan76.mcpitanlib.midohra.block.BlockWrapper;
+import net.pitan76.mcpitanlib.midohra.block.entity.BlockEntityWrapper;
+import net.pitan76.mcpitanlib.midohra.util.hit.HitResultType;
+import net.pitan76.mcpitanlib.midohra.util.math.Direction;
+import net.pitan76.mcpitanlib.midohra.world.IWorldView;
+import net.pitan76.mcpitanlib.midohra.world.World;
+import net.pitan76.mcpitanlib.mixin.ItemUsageContextMixin;
+import org.jetbrains.annotations.Nullable;
+
+public class PlacementStateArgs extends BaseEvent implements BlockStatePropertyHolder {
+ public ItemPlacementContext ctx;
+
+ @Nullable
+ public Block block;
+
+ public PlacementStateArgs(ItemPlacementContext ctx) {
+ this.ctx = ctx;
+ }
+
+ public PlacementStateArgs(ItemPlacementContext ctx, @Nullable Block block) {
+ this.ctx = ctx;
+ this.block = block;
+ }
+
+ public boolean canPlace() {
+ return ctx.canPlace();
+ }
+
+ public BlockPos getRawPos() {
+ return ctx.getBlockPos();
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.BlockPos getPos() {
+ return net.pitan76.mcpitanlib.midohra.util.math.BlockPos.of(getRawPos());
+ }
+
+ public Player getPlayer() {
+ return new Player(ctx.getPlayer());
+ }
+
+ public Direction[] getPlacementDirections() {
+ net.minecraft.util.math.Direction[] rawDirs = getRawPlacementDirections();
+ Direction[] directions = new Direction[rawDirs.length];
+ for (int i = 0; i < directions.length; i++) {
+ directions[i] = Direction.of(rawDirs[i]);
+ }
+
+ return directions;
+ }
+
+ public net.minecraft.util.math.Direction[] getRawPlacementDirections() {
+ return ctx.getPlacementDirections();
+ }
+
+ public Hand getHand() {
+ return ctx.getHand();
+ }
+
+ public Direction getSide() {
+ return Direction.of(getRawSide());
+ }
+
+ public net.minecraft.util.math.Direction getRawSide() {
+ return ctx.getSide();
+ }
+
+ public Direction getHorizontalPlayerFacing() {
+ return Direction.of(getRawHorizontalPlayerFacing());
+ }
+
+ public net.minecraft.util.math.Direction getRawHorizontalPlayerFacing() {
+ return ctx.getHorizontalPlayerFacing();
+ }
+
+ public float getPlayerYaw() {
+ return ctx.getPlayerYaw();
+ }
+
+ public World getWorld() {
+ return World.of(ctx.getWorld());
+ }
+
+ public IWorldView getWorldView() {
+ return getWorld();
+ }
+
+ public boolean isClient() {
+ return getWorld().isClient();
+ }
+
+ public Vec3d getHitPos() {
+ return ctx.getHitPos();
+ }
+
+ public boolean canReplaceExisting() {
+ return ctx.canReplaceExisting();
+ }
+
+ @Deprecated
+ public ItemUsageContextMixin getIUCAccessor() {
+ return (ItemUsageContextMixin) ctx;
+ }
+
+ public BlockHitResult getHitResult() {
+ return getIUCAccessor().getHit();
+ }
+
+ public ItemUseOnBlockEvent toItemUseOnBlockEvent() {
+ return new ItemUseOnBlockEvent(getWorld().getRaw(), getPlayer().getPlayerEntity(), getHand(), ctx.getStack(), getHitResult());
+ }
+
+ public ItemPlacementContext getCtx() {
+ return ctx;
+ }
+
+ public @Nullable Block getRawBlock() {
+ return block;
+ }
+
+ public boolean isBlockExist() {
+ return block != null;
+ }
+
+ public net.minecraft.block.BlockState getRawBlockState() {
+ return BlockStateUtil.getDefaultState(block);
+ }
+
+ public BlockEntity getRawBlockEntity() {
+ return getWorld().getBlockEntity(getRawPos());
+ }
+
+ public BlockWrapper getBlock() {
+ return BlockWrapper.of(block);
+ }
+
+ public , V extends T> net.minecraft.block.BlockState with(Property property, V value) {
+ if (block == null)
+ return null;
+
+ return BlockStateUtil.with(BlockStateUtil.getDefaultState(block), property, value);
+ }
+
+ @Override
+ public BlockState getBlockState() {
+ return BlockState.of(getRawBlockState());
+ }
+
+ public BlockEntityWrapper getBlockEntity() {
+ return getWorld().getBlockEntity(getPos());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.hit.BlockHitResult getHitResultM() {
+ return net.pitan76.mcpitanlib.midohra.util.hit.BlockHitResult.of(getHitResult());
+ }
+
+ public HitResultType getHitResultTypeM() {
+ return HitResultType.from(getHitResult().getType());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/StateForNeighborUpdateArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/StateForNeighborUpdateArgs.java
new file mode 100644
index 000000000..c6d7a6845
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/StateForNeighborUpdateArgs.java
@@ -0,0 +1,97 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Direction;
+import net.minecraft.world.WorldAccess;
+import net.minecraft.world.WorldView;
+import net.pitan76.mcpitanlib.api.util.math.random.CompatRandom;
+import net.pitan76.mcpitanlib.midohra.block.entity.BlockEntityWrapper;
+import net.pitan76.mcpitanlib.midohra.holder.BlockStatePropertyHolder;
+import net.pitan76.mcpitanlib.midohra.world.IWorldView;
+
+public class StateForNeighborUpdateArgs implements BlockStatePropertyHolder {
+ public BlockState state;
+ public Direction direction;
+ public BlockState neighborState;
+ public WorldAccess world;
+ public BlockPos pos;
+ public BlockPos neighborPos;
+ public CompatRandom random;
+
+ public StateForNeighborUpdateArgs(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
+ this.state = state;
+ this.direction = direction;
+ this.neighborState = neighborState;
+ this.world = world;
+ this.pos = pos;
+ this.neighborPos = neighborPos;
+ this.random = new CompatRandom(world.getRandom());
+ }
+
+ public Direction getDirection() {
+ return direction;
+ }
+
+ public BlockState getRawNeighborState() {
+ return neighborState;
+ }
+
+ public WorldView getRawWorld() {
+ return world;
+ }
+
+ public BlockPos getRawPos() {
+ return pos;
+ }
+
+ public BlockPos getRawNeighborPos() {
+ return neighborPos;
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getNeighborState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(getRawNeighborState());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.world.WorldView getWorld() {
+ return net.pitan76.mcpitanlib.midohra.world.WorldView.of(getRawWorld());
+ }
+
+ public IWorldView getWorldView() {
+ return getWorld();
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.BlockPos getPos() {
+ return net.pitan76.mcpitanlib.midohra.util.math.BlockPos.of(getRawPos());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.BlockPos getNeighborPos() {
+ return net.pitan76.mcpitanlib.midohra.util.math.BlockPos.of(getRawNeighborPos());
+ }
+
+ public CompatRandom getRandom() {
+ return random;
+ }
+
+ public net.pitan76.mcpitanlib.midohra.world.tick.ScheduledTickView getTickView() {
+ return net.pitan76.mcpitanlib.midohra.world.tick.ScheduledTickView.of(world);
+ }
+
+ @Override
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getBlockState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(state);
+ }
+
+ public BlockEntityWrapper getBlockEntity() {
+ return getWorld().getBlockEntity(getPos());
+ }
+
+ public BlockEntity getRawBlockEntity() {
+ return world.getBlockEntity(pos);
+ }
+
+ public boolean isClient() {
+ return world.isClient();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/BlockSettingsBuilder.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/BlockSettingsBuilder.java
new file mode 100644
index 000000000..95b2afca6
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/BlockSettingsBuilder.java
@@ -0,0 +1,170 @@
+package net.pitan76.mcpitanlib.api.block.v2;
+
+import net.minecraft.block.AbstractBlock;
+import net.pitan76.mcpitanlib.api.block.CompatibleMaterial;
+import net.pitan76.mcpitanlib.api.sound.CompatBlockSoundGroup;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.color.CompatDyeColor;
+import net.pitan76.mcpitanlib.api.util.color.CompatMapColor;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+import net.pitan76.mcpitanlib.midohra.block.BlockWrapper;
+
+import java.util.function.ToIntFunction;
+
+public class BlockSettingsBuilder {
+
+ public CompatIdentifier id;
+ public float hardness = -1;
+ public float resistance = -1;
+ public CompatBlockSoundGroup blockSoundGroup;
+ public CompatibleMaterial material;
+ public CompatMapColor mapColor;
+ public CompatDyeColor dyeColor;
+ public boolean requiresTool;
+ public boolean dropsNothing;
+ public ToIntFunction luminance;
+
+ protected BlockWrapper copyFromBlock = null;
+
+ public BlockSettingsBuilder(CompatIdentifier id) {
+ this.id = id;
+ }
+
+ public BlockSettingsBuilder() {
+
+ }
+
+ public BlockSettingsBuilder hardness(float hardness) {
+ this.hardness = hardness;
+ return this;
+ }
+
+ public BlockSettingsBuilder resistance(float resistance) {
+ this.resistance = resistance;
+ return this;
+ }
+
+ public BlockSettingsBuilder strength(float hardness, float resistance) {
+ this.hardness = hardness;
+ this.resistance = resistance;
+ return this;
+ }
+
+ public BlockSettingsBuilder sounds(CompatBlockSoundGroup blockSoundGroup) {
+ this.blockSoundGroup = blockSoundGroup;
+ return this;
+ }
+
+ public BlockSettingsBuilder material(CompatibleMaterial material) {
+ this.material = material;
+ return this;
+ }
+
+ public BlockSettingsBuilder mapColor(CompatMapColor mapColor) {
+ this.mapColor = mapColor;
+ return this;
+ }
+
+ public BlockSettingsBuilder dyeColor(CompatDyeColor dyeColor) {
+ this.dyeColor = dyeColor;
+ return this;
+ }
+
+ public BlockSettingsBuilder requiresTool() {
+ this.requiresTool = true;
+ return this;
+ }
+
+ public BlockSettingsBuilder dropsNothing() {
+ this.dropsNothing = true;
+ return this;
+ }
+
+ public BlockSettingsBuilder luminance(ToIntFunction luminance) {
+ this.luminance = luminance;
+ return this;
+ }
+
+ public CompatibleBlockSettings build() {
+ return build(id);
+ }
+
+ public AbstractBlock.Settings _build() {
+ return build().build();
+ }
+
+ public CompatibleBlockSettings build(CompatIdentifier id) {
+ CompatibleBlockSettings settings;
+
+ if (copyFromBlock != null) {
+ settings = CompatibleBlockSettings.copy(id, copyFromBlock.get());
+ } else {
+ settings = CompatibleBlockSettings.of(id);
+ }
+
+ if (material != null)
+ settings = CompatibleBlockSettings.of(id, material);
+
+ if (mapColor != null) {
+ settings = settings.mapColor(mapColor.getColor());
+ } else if (dyeColor != null) {
+ settings = settings.mapColor(dyeColor.getColor().getMapColor());
+ }
+
+ if (requiresTool) settings.requiresTool();
+ if (dropsNothing) settings.dropsNothing();
+ if (luminance != null) settings.luminance((state) -> luminance.applyAsInt(BlockState.of(state)));
+
+ if (hardness != -1 && resistance != -1) settings.strength(hardness, resistance);
+ else if (hardness != -1) settings.strength(hardness);
+
+ if (blockSoundGroup != null) settings.sounds(blockSoundGroup);
+
+ return settings;
+ }
+
+ public AbstractBlock.Settings _build(CompatIdentifier id) {
+ return build(id).build();
+ }
+
+ public BlockSettingsBuilder copy(CompatIdentifier id) {
+ BlockSettingsBuilder builder = new BlockSettingsBuilder();
+
+ builder.copyFromBlock = this.copyFromBlock;
+
+ builder.id = id;
+ builder.hardness = this.hardness;
+ builder.resistance = this.resistance;
+ builder.blockSoundGroup = this.blockSoundGroup;
+ builder.material = this.material;
+ builder.mapColor = this.mapColor;
+ builder.dyeColor = this.dyeColor;
+ builder.requiresTool = this.requiresTool;
+ builder.dropsNothing = this.dropsNothing;
+ builder.luminance = this.luminance;
+ return builder;
+ }
+
+ public BlockSettingsBuilder copy() {
+ return copy(this.id);
+ }
+
+ public static BlockSettingsBuilder of(CompatIdentifier id) {
+ return new BlockSettingsBuilder(id);
+ }
+
+ public static BlockSettingsBuilder of() {
+ return new BlockSettingsBuilder();
+ }
+
+ public static BlockSettingsBuilder copyBlock(BlockWrapper block) {
+ BlockSettingsBuilder builder = new BlockSettingsBuilder(block.getId());
+ builder.copyFromBlock = block;
+
+ return builder;
+ }
+
+ public static BlockSettingsBuilder copyBlock(CompatIdentifier id) {
+ return copyBlock(BlockWrapper.of(id));
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatBlock.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatBlock.java
new file mode 100644
index 000000000..ffbf00cc3
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatBlock.java
@@ -0,0 +1,177 @@
+package net.pitan76.mcpitanlib.api.block.v2;
+
+import net.minecraft.block.BlockRenderType;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.ShapeContext;
+import net.minecraft.item.ItemPlacementContext;
+import net.minecraft.util.BlockRotation;
+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 net.pitan76.mcpitanlib.api.block.CompatBlockRenderType;
+import net.pitan76.mcpitanlib.api.block.ExtendBlock;
+import net.pitan76.mcpitanlib.api.block.args.RenderTypeArgs;
+import net.pitan76.mcpitanlib.api.block.args.RotateArgs;
+import net.pitan76.mcpitanlib.api.block.args.SideInvisibleArgs;
+import net.pitan76.mcpitanlib.api.block.args.v2.*;
+import net.pitan76.mcpitanlib.midohra.block.BlockWrapper;
+import org.jetbrains.annotations.Nullable;
+
+public class CompatBlock extends ExtendBlock {
+
+ public CompatibleBlockSettings settings;
+
+ public CompatBlock(CompatibleBlockSettings settings) {
+ super(settings);
+ this.settings = settings;
+ }
+
+ public CompatibleBlockSettings getCompatSettings() {
+ return settings;
+ }
+
+ public BlockWrapper getWrapper() {
+ return BlockWrapper.of(this);
+ }
+
+ @Override
+ @Deprecated
+ protected BlockRenderType getRenderType(BlockState state) {
+ return getRenderType(new RenderTypeArgs(state)).renderType;
+ }
+
+ public CompatBlockRenderType getRenderType(RenderTypeArgs args) {
+ return new CompatBlockRenderType(super.getRenderType(args.state));
+ }
+
+ @Override
+ @Deprecated
+ protected BlockState rotate(BlockState state, BlockRotation rotation) {
+ return rotate(new RotateArgs(state, rotation)).toMinecraft();
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState rotate(RotateArgs args) {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(super.rotate(args.state, args.rotation));
+ }
+
+ @Override
+ @Deprecated
+ protected boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
+ return isSideInvisible(new SideInvisibleArgs(state, stateFrom, direction));
+ }
+
+ public boolean isSideInvisible(SideInvisibleArgs args) {
+ return super.isSideInvisible(args.state, args.stateFrom, args.direction);
+ }
+
+ /**
+ * Compatible for getDefaultState()
+ * @return default block state
+ */
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getDefaultMidohraState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(getNewDefaultState());
+ }
+
+ /**
+ * Compatible for setDefaultState()
+ * @param state BlockState
+ */
+ public void setDefaultState(net.pitan76.mcpitanlib.midohra.block.BlockState state) {
+ setNewDefaultState(state.toMinecraft());
+ }
+
+ public @Nullable net.pitan76.mcpitanlib.midohra.block.BlockState getPlacementState(PlacementStateArgs args) {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(super.getPlacementState(args.ctx));
+ }
+
+ @Override
+ public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
+ return getPlacementState(new PlacementStateArgs(ctx)).toMinecraft();
+ }
+
+ @Deprecated
+ @Override
+ public @Nullable BlockState getPlacementState(net.pitan76.mcpitanlib.api.event.block.PlacementStateArgs args) {
+ return super.getPlacementState(args);
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getStateForNeighborUpdate(StateForNeighborUpdateArgs args) {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(super.getStateForNeighborUpdate(args.state, args.direction, args.neighborState, args.world, args.pos, args.neighborPos));
+ }
+
+ @Override
+ protected BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
+ return getStateForNeighborUpdate(new StateForNeighborUpdateArgs(state, direction, neighborState, world, pos, neighborPos)).toMinecraft();
+ }
+
+ @Deprecated
+ @Override
+ public BlockState getStateForNeighborUpdate(net.pitan76.mcpitanlib.api.event.block.StateForNeighborUpdateArgs args) {
+ return super.getStateForNeighborUpdate((args));
+ }
+
+ public VoxelShape getOutlineShape(OutlineShapeEvent e) {
+ return super.getOutlineShape(e.state.toMinecraft(), e.world.getRaw(), e.pos.toMinecraft(), e.context);
+ }
+
+ @Override
+ public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
+ return getOutlineShape(new OutlineShapeEvent(state, world, pos, context));
+ }
+
+ @Deprecated
+ @Override
+ public VoxelShape getOutlineShape(net.pitan76.mcpitanlib.api.event.block.OutlineShapeEvent e) {
+ return super.getOutlineShape(e);
+ }
+
+ public VoxelShape getCollisionShape(CollisionShapeEvent e) {
+ return super.getCollisionShape(e.state.toMinecraft(), e.world.getRaw(), e.pos.toMinecraft(), e.context);
+ }
+
+ @Deprecated
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
+ return getCollisionShape(new CollisionShapeEvent(state, world, pos, context));
+ }
+
+ @Deprecated
+ @Override
+ public VoxelShape getCollisionShape(net.pitan76.mcpitanlib.api.event.block.CollisionShapeEvent e) {
+ return super.getCollisionShape(e);
+ }
+
+ @Deprecated
+ @Override
+ public boolean hasComparatorOutput(BlockState state) {
+ return hasComparatorOutput(new HasComparatorOutputArgs(state));
+ }
+
+ public boolean hasComparatorOutput(HasComparatorOutputArgs args) {
+ return super.hasComparatorOutput(args.state);
+ }
+
+ @Deprecated
+ @Override
+ public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
+ return getComparatorOutput(new GetComparatorOutputArgs(state, world, pos));
+ }
+
+ public int getComparatorOutput(GetComparatorOutputArgs args) {
+ return super.getComparatorOutput(args.state, args.world, args.pos);
+ }
+
+ @Deprecated
+ @Override
+ protected boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
+ return canPlaceAt(new CanPlaceAtArgs(state, world, pos));
+ }
+
+ public boolean canPlaceAt(CanPlaceAtArgs args) {
+ return super.canPlaceAt(args.state, args.world, args.pos);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatBlockProvider.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatBlockProvider.java
new file mode 100644
index 000000000..368be8ddc
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatBlockProvider.java
@@ -0,0 +1,91 @@
+package net.pitan76.mcpitanlib.api.block.v2;
+
+import net.minecraft.block.Block;
+import net.minecraft.util.shape.VoxelShape;
+import net.pitan76.mcpitanlib.api.block.CompatBlockRenderType;
+import net.pitan76.mcpitanlib.api.block.ExtendBlockProvider;
+import net.pitan76.mcpitanlib.api.block.args.RenderTypeArgs;
+import net.pitan76.mcpitanlib.api.block.args.RotateArgs;
+import net.pitan76.mcpitanlib.api.block.args.SideInvisibleArgs;
+import net.pitan76.mcpitanlib.api.block.args.v2.CollisionShapeEvent;
+import net.pitan76.mcpitanlib.api.block.args.v2.OutlineShapeEvent;
+import net.pitan76.mcpitanlib.api.block.args.v2.PlacementStateArgs;
+import net.pitan76.mcpitanlib.api.block.args.v2.StateForNeighborUpdateArgs;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+import net.pitan76.mcpitanlib.midohra.block.BlockWrapper;
+import net.pitan76.mcpitanlib.mixin.BlockInvoker;
+
+public interface CompatBlockProvider extends ExtendBlockProvider {
+ CompatibleBlockSettings getCompatSettings();
+
+ default BlockWrapper getWrapper() {
+ return this instanceof Block ? BlockWrapper.of((Block) this) : BlockWrapper.of();
+ }
+
+ default CompatBlockRenderType getRenderType(RenderTypeArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ default BlockState rotate(RotateArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ default Boolean isSideInvisible(SideInvisibleArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ default BlockState getDefaultMidohraState() {
+ if (this instanceof Block) {
+ return BlockState.of(((Block) this).getDefaultState());
+ }
+
+ return null;
+ }
+
+ default void setDefaultState(BlockState state) {
+ if (this instanceof Block) {
+ ((BlockInvoker) this).setDefaultState_invoke(state.toMinecraft());
+ }
+ }
+
+ @Override
+ @Deprecated
+ default net.minecraft.block.BlockState getPlacementState(net.pitan76.mcpitanlib.api.event.block.PlacementStateArgs args, Options options) {
+ return ExtendBlockProvider.super.getPlacementState(args, options);
+ }
+
+ default BlockState getPlacementState(PlacementStateArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ default BlockState getStateForNeighborUpdate(StateForNeighborUpdateArgs args, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ @Override
+ @Deprecated
+ default VoxelShape getOutlineShape(net.pitan76.mcpitanlib.api.event.block.OutlineShapeEvent event, Options options) {
+ return ExtendBlockProvider.super.getOutlineShape(event, options);
+ }
+
+ default VoxelShape getOutlineShape(OutlineShapeEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ @Deprecated
+ @Override
+ default VoxelShape getCollisionShape(net.pitan76.mcpitanlib.api.event.block.CollisionShapeEvent event, Options options) {
+ return ExtendBlockProvider.super.getCollisionShape(event, options);
+ }
+
+ default VoxelShape getCollisionShape(CollisionShapeEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatStairsBlock.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatStairsBlock.java
new file mode 100644
index 000000000..f92115a8a
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatStairsBlock.java
@@ -0,0 +1,69 @@
+package net.pitan76.mcpitanlib.api.block.v2;
+
+import net.minecraft.block.ShapeContext;
+import net.minecraft.block.StairsBlock;
+import net.minecraft.block.enums.BlockHalf;
+import net.minecraft.block.enums.StairShape;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.shape.VoxelShape;
+import net.minecraft.world.BlockView;
+import net.pitan76.mcpitanlib.api.block.args.v2.CollisionShapeEvent;
+import net.pitan76.mcpitanlib.api.block.args.v2.OutlineShapeEvent;
+import net.pitan76.mcpitanlib.api.state.property.BooleanProperty;
+import net.pitan76.mcpitanlib.api.state.property.CompatProperties;
+import net.pitan76.mcpitanlib.api.state.property.DirectionProperty;
+import net.pitan76.mcpitanlib.api.state.property.EnumProperty;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+
+public class CompatStairsBlock extends net.pitan76.mcpitanlib.api.block.CompatStairsBlock {
+
+ public static final DirectionProperty FACING = CompatProperties.ofDir(StairsBlock.FACING);
+ public static final EnumProperty HALF = CompatProperties.of(StairsBlock.HALF);
+ public static final EnumProperty SHAPE = CompatProperties.of(StairsBlock.SHAPE);
+ public static final BooleanProperty WATERLOGGED = CompatProperties.of(StairsBlock.WATERLOGGED);
+
+ public CompatStairsBlock(net.minecraft.block.BlockState baseBlockState, CompatibleBlockSettings settings) {
+ super(baseBlockState, settings);
+ }
+
+ public CompatStairsBlock(BlockState baseBlockState, CompatibleBlockSettings settings) {
+ this(baseBlockState.toMinecraft(), settings);
+ }
+
+ public VoxelShape getOutlineShape(OutlineShapeEvent e) {
+ return super.getOutlineShape(e.state.toMinecraft(), e.world.getRaw(), e.pos.toMinecraft(), e.context);
+ }
+
+ public VoxelShape getCollisionShape(CollisionShapeEvent e) {
+ return super.getCollisionShape(e.state.toMinecraft(), e.world.getRaw(), e.pos.toMinecraft(), e.context);
+ }
+
+ @Deprecated
+ @Override
+ public VoxelShape getOutlineShape(net.pitan76.mcpitanlib.api.event.block.OutlineShapeEvent e) {
+ return getOutlineShape(new OutlineShapeEvent(e.state, e.world, e.pos, e.context));
+ }
+
+ @Deprecated
+ @Override
+ public VoxelShape getOutlineShape(net.minecraft.block.BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
+ return getOutlineShape(new OutlineShapeEvent(state, world, pos, context));
+ }
+
+ @Deprecated
+ @Override
+ public VoxelShape getOutlineShape(OutlineShapeEvent e, Options options) {
+ return super.getOutlineShape(e, options);
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(net.minecraft.block.BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
+ return getCollisionShape(new CollisionShapeEvent(state, world, pos, context));
+ }
+
+ @Deprecated
+ @Override
+ public VoxelShape getCollisionShape(CollisionShapeEvent event, Options options) {
+ return super.getCollisionShape(event, options);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatibleBlockSettings.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatibleBlockSettings.java
new file mode 100644
index 000000000..8b1ffdc2b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatibleBlockSettings.java
@@ -0,0 +1,286 @@
+package net.pitan76.mcpitanlib.api.block.v2;
+
+import com.mojang.serialization.Codec;
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.MapColor;
+import net.minecraft.registry.RegistryKey;
+import net.minecraft.registry.RegistryKeys;
+import net.minecraft.sound.BlockSoundGroup;
+import net.minecraft.util.DyeColor;
+import net.pitan76.mcpitanlib.api.block.CompatibleMaterial;
+import net.pitan76.mcpitanlib.api.sound.CompatBlockSoundGroup;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.color.CompatDyeColor;
+import net.pitan76.mcpitanlib.api.util.color.CompatMapColor;
+
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+
+@SuppressWarnings("deprecation")
+public class CompatibleBlockSettings extends net.pitan76.mcpitanlib.api.block.CompatibleBlockSettings {
+ protected CompatIdentifier identifier = null;
+ public boolean changedTranslationKey = false;
+
+ public static final Codec CODEC = Codec.unit(CompatibleBlockSettings::new);
+
+ @Deprecated
+ protected CompatibleBlockSettings() {
+ super();
+ }
+
+ public CompatibleBlockSettings(CompatIdentifier identifier) {
+ super();
+ setId(identifier);
+ }
+
+ public static CompatibleBlockSettings of(CompatIdentifier id) {
+ return new CompatibleBlockSettings(id);
+ }
+
+ @Deprecated
+ public CompatibleBlockSettings setId(CompatIdentifier identifier) {
+ this.identifier = identifier;
+ return this;
+ }
+
+ private static CompatibleBlockSettings copy(CompatibleMaterial material, CompatibleBlockSettings settings) {
+ settings.mapColor(material.getColor());
+ if (material.isLiquid())
+ settings.settings.liquid();
+ if (material.isSolid())
+ settings.settings.solid();
+ if (material.isReplaceable())
+ settings.settings.replaceable();
+ if (material.isSolid())
+ settings.settings.solid();
+ if (material.isBurnable())
+ settings.settings.burnable();
+ settings.settings.pistonBehavior(material.getPistonBehavior());
+ return settings;
+ }
+
+ public CompatibleBlockSettings(CompatIdentifier id, CompatibleMaterial material, MapColor mapColor) {
+ this(id);
+ copy(material, this);
+ mapColor(mapColor);
+ }
+
+ public CompatibleBlockSettings(CompatIdentifier id, CompatibleMaterial material, DyeColor dyeColor) {
+ this(id);
+ copy(material, this);
+ mapColor(dyeColor);
+ }
+
+ public CompatibleBlockSettings(CompatIdentifier id, CompatibleMaterial material) {
+ this(id);
+ copy(material, this);
+ }
+
+ public CompatibleBlockSettings(CompatIdentifier id, CompatibleMaterial material, Function mapColor) {
+ this(id);
+ copy(material, this);
+ mapColor(mapColor);
+ }
+
+ public static CompatibleBlockSettings of(CompatIdentifier id, CompatibleMaterial material, MapColor mapColor) {
+ return new CompatibleBlockSettings(id, material, mapColor);
+ }
+
+ public static CompatibleBlockSettings of(CompatIdentifier id, CompatibleMaterial material, DyeColor dyeColor) {
+ return new CompatibleBlockSettings(id, material, dyeColor);
+ }
+
+ public static CompatibleBlockSettings of(CompatIdentifier id, CompatibleMaterial material) {
+ return new CompatibleBlockSettings(id, material);
+ }
+
+ public static CompatibleBlockSettings of(CompatIdentifier id, CompatibleMaterial material, Function mapColor) {
+ return new CompatibleBlockSettings(id, material, mapColor);
+ }
+
+ public CompatibleBlockSettings(CompatIdentifier id, AbstractBlock block) {
+ super(block);
+ setId(id);
+ }
+
+ public static CompatibleBlockSettings copy(CompatIdentifier id, AbstractBlock block) {
+ return new CompatibleBlockSettings(id, block);
+ }
+
+ public CompatibleBlockSettings air() {
+ super.air();
+ return this;
+ }
+
+ public CompatibleBlockSettings blockVision(AbstractBlock.ContextPredicate predicate) {
+ super.blockVision(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings postProcess(AbstractBlock.ContextPredicate predicate) {
+ super.postProcess(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings solidBlock(AbstractBlock.ContextPredicate predicate) {
+ super.solidBlock(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings suffocates(AbstractBlock.ContextPredicate predicate) {
+ super.suffocates(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings mapColor(MapColor color) {
+ super.mapColor(color);
+ return this;
+ }
+
+ public CompatibleBlockSettings mapColor(DyeColor color) {
+ super.mapColor(color);
+ return this;
+ }
+
+ public CompatibleBlockSettings mapColor(CompatMapColor color) {
+ super.mapColor(color.getColor());
+ return this;
+ }
+
+ public CompatibleBlockSettings mapColor(CompatDyeColor color) {
+ super.mapColor(color.getColor());
+ return this;
+ }
+
+ public CompatibleBlockSettings mapColor(Function color) {
+ super.mapColor(color);
+ return this;
+ }
+
+ public CompatibleBlockSettings compatMapColor(Function color) {
+ super.mapColor(state -> color.apply(net.pitan76.mcpitanlib.midohra.block.BlockState.of(state)).getColor());
+ return this;
+ }
+
+ @Deprecated
+ public CompatibleBlockSettings dropsLike(Block source) {
+ super.dropsLike(source);
+ return this;
+ }
+
+ public CompatibleBlockSettings breakInstantly() {
+ super.breakInstantly();
+ return this;
+ }
+
+ public CompatibleBlockSettings dropsNothing() {
+ super.dropsNothing();
+ return this;
+ }
+
+ public CompatibleBlockSettings dynamicBounds() {
+ super.dynamicBounds();
+ return this;
+ }
+
+ public CompatibleBlockSettings hardness(float hardness) {
+ super.hardness(hardness);
+ return this;
+ }
+
+ public CompatibleBlockSettings noBlockBreakParticles() {
+ super.noBlockBreakParticles();
+ return this;
+ }
+
+ public CompatibleBlockSettings requiresTool() {
+ super.requiresTool();
+ return this;
+ }
+
+ public CompatibleBlockSettings noCollision() {
+ super.noCollision();
+ return this;
+ }
+
+ public CompatibleBlockSettings nonOpaque() {
+ super.nonOpaque();
+ return this;
+ }
+
+ public CompatibleBlockSettings resistance(float resistance) {
+ super.resistance(resistance);
+ return this;
+ }
+
+ public CompatibleBlockSettings strength(float strength) {
+ super.strength(strength);
+ return this;
+ }
+
+ public CompatibleBlockSettings strength(float hardness, float resistance) {
+ super.strength(hardness, resistance);
+ return this;
+ }
+
+ public CompatibleBlockSettings ticksRandomly() {
+ super.ticksRandomly();
+ return this;
+ }
+
+ public CompatibleBlockSettings sounds(CompatBlockSoundGroup blockSoundGroup) {
+ super.sounds(blockSoundGroup);
+ return this;
+ }
+
+ public CompatibleBlockSettings luminance(ToIntFunction luminance) {
+ super.luminance(luminance);
+ return this;
+ }
+
+ public CompatibleBlockSettings jumpVelocityMultiplier(float jumpVelocityMultiplier) {
+ super.jumpVelocityMultiplier(jumpVelocityMultiplier);
+ return this;
+ }
+
+ public CompatibleBlockSettings slipperiness(float slipperiness) {
+ super.slipperiness(slipperiness);
+ return this;
+ }
+
+ public CompatibleBlockSettings velocityMultiplier(float velocityMultiplier) {
+ super.velocityMultiplier(velocityMultiplier);
+ return this;
+ }
+
+ public CompatibleBlockSettings emissiveLighting(AbstractBlock.ContextPredicate predicate) {
+ super.emissiveLighting(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings offset(AbstractBlock.OffsetType offsetType) {
+ super.offset(offsetType);
+ return this;
+ }
+
+ public CompatibleBlockSettings allowsSpawning(AbstractBlock.TypedContextPredicate> predicate) {
+ super.allowsSpawning(predicate);
+ return this;
+ }
+
+ public AbstractBlock.Settings build() {
+ super.build();
+ return settings;
+ }
+
+ @Deprecated
+ @Override
+ public CompatibleBlockSettings sounds(BlockSoundGroup blockSoundGroup) {
+ super.sounds(blockSoundGroup);
+ return this;
+ }
+
+
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/CompatInventoryScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/CompatInventoryScreen.java
new file mode 100644
index 000000000..28fd67071
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/CompatInventoryScreen.java
@@ -0,0 +1,22 @@
+package net.pitan76.mcpitanlib.api.client;
+
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+@Deprecated
+public abstract class CompatInventoryScreen extends SimpleInventoryScreen {
+
+ public CompatInventoryScreen(ScreenHandler handler, PlayerInventory inventory, Text title) {
+ super(handler, inventory, title);
+ }
+
+ public abstract CompatIdentifier getCompatTexture();
+
+ @Override
+ public Identifier getTexture() {
+ return getCompatTexture().toMinecraft();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleHandledScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleHandledScreen.java
new file mode 100644
index 000000000..060e17547
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleHandledScreen.java
@@ -0,0 +1,316 @@
+package net.pitan76.mcpitanlib.api.client;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.Drawable;
+import net.minecraft.client.gui.Element;
+import net.minecraft.client.gui.Selectable;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.client.gui.widget.CompatibleTexturedButtonWidget;
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.*;
+import net.pitan76.mcpitanlib.api.client.render.screen.RenderBackgroundTextureArgs;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.IdentifierUtil;
+import net.pitan76.mcpitanlib.api.util.client.ClientUtil;
+import net.pitan76.mcpitanlib.api.util.client.RenderUtil;
+import net.pitan76.mcpitanlib.core.datafixer.Pair;
+
+@Deprecated
+public abstract class SimpleHandledScreen extends HandledScreen {
+
+ public int width, height, backgroundWidth, backgroundHeight, x, y;
+ public ScreenHandler handler;
+ public TextRenderer textRenderer;
+ public ItemRenderer itemRenderer;
+
+ public Text title;
+ public MinecraftClient client;
+ public SimpleHandledScreen(ScreenHandler handler, PlayerInventory inventory, Text title) {
+ super(handler, inventory, title);
+ fixScreen();
+ this.handler = handler;
+ this.title = title;
+
+ }
+
+ public T addDrawableChild_compatibility(T drawableElement) {
+ return super.addDrawableChild(drawableElement);
+ // addButton
+ }
+
+ public T addSelectableChild_compatibility(T selectableElement) {
+ return super.addSelectableChild(selectableElement);
+ }
+
+ public CompatibleTexturedButtonWidget addDrawableCTBW(CompatibleTexturedButtonWidget widget) {
+ return addDrawableChild_compatibility(widget);
+ }
+
+ @Deprecated
+ @Override
+ protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawBackgroundOverride(new DrawBackgroundArgs(drawObjectDM, delta, mouseX, mouseY));
+ }
+
+ public abstract void drawBackgroundOverride(DrawBackgroundArgs args);
+
+ @Deprecated
+ @Override
+ protected void drawForeground(DrawContext context, int mouseX, int mouseY) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawForegroundOverride(new DrawForegroundArgs(drawObjectDM, mouseX, mouseY));
+ }
+
+ protected void drawForegroundOverride(DrawForegroundArgs args) {
+ super.drawForeground(args.drawObjectDM.getContext(), args.mouseX, args.mouseY);
+ }
+
+ public void callDrawTexture(DrawObjectDM drawObjectDM, Identifier texture, int x, int y, int u, int v, int width, int height) {
+ drawObjectDM.getContext().drawTexture(texture, x, y, u, v, width, height, 256, 256);
+ }
+
+ public void callDrawTexture(DrawObjectDM drawObjectDM, CompatIdentifier texture, int x, int y, int u, int v, int width, int height) {
+ callDrawTexture(drawObjectDM, texture.toMinecraft(), x, y, u, v, width, height);
+ }
+
+ @Deprecated
+ public void callRenderBackground(DrawObjectDM drawObjectDM) {
+ callRenderBackground(new RenderArgs(drawObjectDM, 0, 0, 0));
+ }
+
+
+ public void callRenderBackground(RenderArgs args) {
+ super.renderBackground(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void callDrawMouseoverTooltip(DrawMouseoverTooltipArgs args) {
+ super.drawMouseoverTooltip(args.drawObjectDM.getContext(), args.mouseX, args.mouseY);
+ }
+
+ public void renderOverride(RenderArgs args) {
+ super.render(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void resizeOverride(MinecraftClient client, int width, int height) {
+ }
+
+ public void initOverride() {
+ }
+
+ @Deprecated
+ @Override
+ protected void init() {
+ super.init();
+ fixScreen();
+ initOverride();
+ }
+
+ @Deprecated
+ @Override
+ public void resize(MinecraftClient client, int width, int height) {
+ super.resize(client, width, height);
+ fixScreen();
+ resizeOverride(client, width, height);
+ }
+
+ public void fixScreen() {
+ this.backgroundWidth = getBackgroundWidth();
+ this.backgroundHeight = getBackgroundHeight();
+ this.x = super.x; //(this.width - this.backgroundWidth) / 2;
+ this.y = super.y; //(this.height - this.backgroundHeight) / 2;
+ this.textRenderer = super.textRenderer;
+ this.itemRenderer = MinecraftClient.getInstance().getItemRenderer();
+ this.width = super.width;
+ this.height = super.height;
+ if (super.client == null)
+ this.client = MinecraftClient.getInstance();
+ else
+ this.client = super.client;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ super.x = x;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ super.y = y;
+ }
+
+ public void setTextRenderer(TextRenderer textRenderer) {
+ this.textRenderer = textRenderer;
+ super.textRenderer = textRenderer;
+ }
+
+ public void setItemRenderer(ItemRenderer itemRenderer) {
+ this.itemRenderer = itemRenderer;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ super.width = width;
+ }
+
+ public void setBackgroundWidth(int backgroundWidth) {
+ this.backgroundWidth = backgroundWidth;
+ super.backgroundWidth = backgroundWidth;
+ }
+
+ public void setBackgroundHeight(int backgroundHeight) {
+ this.backgroundHeight = backgroundHeight;
+ super.backgroundHeight = backgroundHeight;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ super.height = height;
+ }
+
+ public int getBackgroundWidth() {
+ return super.backgroundWidth;
+ }
+
+ public int getBackgroundHeight() {
+ return super.backgroundHeight;
+ }
+
+ @Deprecated
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ renderOverride(new RenderArgs(drawObjectDM, mouseX, mouseY, delta));
+ }
+
+ public boolean keyReleased(KeyEventArgs args) {
+ return super.keyReleased(args.keyCode, args.scanCode, args.modifiers);
+ }
+
+ public boolean keyPressed(KeyEventArgs args) {
+ return super.keyPressed(args.keyCode, args.scanCode, args.modifiers);
+ }
+
+ public void renderBackgroundTexture(RenderBackgroundTextureArgs args) {
+ if (getBackgroundTexture() != null)
+ Screen.renderBackgroundTexture(args.getDrawObjectDM().getContext(), getBackgroundTexture(), x, y, 0, 0, this.width, this.height);
+
+ RenderUtil.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ callDrawTexture(args.drawObjectDM, getBackgroundTexture(), 0, 0, 0, 0, width, height);
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
+ return this.keyReleased(new KeyEventArgs(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ return this.keyPressed(new KeyEventArgs(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public void renderDarkening(DrawContext context) {
+ this.renderBackgroundTexture(new RenderBackgroundTextureArgs(new DrawObjectDM(context, this), 0));
+ }
+
+ public void closeOverride() {
+ super.close();
+ }
+
+ public void removedOverride() {
+ super.removed();
+ }
+
+ @Override
+ public void close() {
+ closeOverride();
+ }
+
+ @Override
+ public void removed() {
+ removedOverride();
+ }
+
+ public Identifier getBackgroundTexture() {
+ return IdentifierUtil.from(getCompatBackgroundTexture());
+ }
+
+ public CompatIdentifier getCompatBackgroundTexture() {
+ return null;
+ }
+
+ public void setTitleX(int x) {
+ this.titleX = x;
+ }
+
+ public void setTitleY(int y) {
+ this.titleY = y;
+ }
+
+ public void setTitlePos(int x, int y) {
+ setTitleX(x);
+ setTitleY(y);
+ }
+
+ public void setTitleXCenter() {
+ if (textRenderer == null)
+ textRenderer = ClientUtil.getTextRenderer();
+
+ setTitleX(backgroundWidth / 2 - textRenderer.getWidth(title) / 2);
+ }
+
+ public int getTitleX() {
+ return titleX;
+ }
+
+ public int getTitleY() {
+ return titleY;
+ }
+
+ @Deprecated
+ @Override
+ public Text getTitle() {
+ return callGetTitle();
+ }
+
+ public Text callGetTitle() {
+ return super.getTitle();
+ }
+
+ public Pair getTitlePosP() {
+ return new Pair<>(getTitleX(), getTitleY());
+ }
+
+ public int getPlayerInvTitleX() {
+ return playerInventoryTitleX;
+ }
+
+ public int getPlayerInvTitleY() {
+ return playerInventoryTitleY;
+ }
+
+ public void setPlayerInvTitleX(int x) {
+ playerInventoryTitleX = x;
+ }
+
+ public void setPlayerInvTitleY(int y) {
+ playerInventoryTitleY = y;
+ }
+
+ public void setPlayerInvTitle(int x, int y) {
+ setPlayerInvTitleX(x);
+ setPlayerInvTitleY(y);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleInventoryScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleInventoryScreen.java
new file mode 100644
index 000000000..de34a65fc
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleInventoryScreen.java
@@ -0,0 +1,39 @@
+package net.pitan76.mcpitanlib.api.client;
+
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.DrawBackgroundArgs;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.DrawMouseoverTooltipArgs;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.RenderArgs;
+import net.pitan76.mcpitanlib.api.util.client.RenderUtil;
+
+@Deprecated
+public abstract class SimpleInventoryScreen extends SimpleHandledScreen {
+
+ public SimpleInventoryScreen(ScreenHandler handler, PlayerInventory inventory, Text title) {
+ super(handler, inventory, title);
+ }
+
+ public abstract Identifier getTexture();
+
+ @Override
+ public Identifier getBackgroundTexture() {
+ return getTexture();
+ }
+
+ @Override
+ public void drawBackgroundOverride(DrawBackgroundArgs args) {
+ RenderUtil.setShaderToPositionTexProgram();
+ RenderUtil.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ callDrawTexture(args.drawObjectDM, getTexture(), x, y, 0, 0, backgroundWidth, backgroundHeight);
+ }
+
+ @Override
+ public void renderOverride(RenderArgs args) {
+ this.callRenderBackground(args);
+ super.renderOverride(args);
+ this.callDrawMouseoverTooltip(new DrawMouseoverTooltipArgs(args.drawObjectDM, args.mouseX, args.mouseY));
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleOptionsScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleOptionsScreen.java
new file mode 100644
index 000000000..572621b5a
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleOptionsScreen.java
@@ -0,0 +1,27 @@
+package net.pitan76.mcpitanlib.api.client;
+
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.option.GameOptions;
+import net.minecraft.text.Text;
+
+public class SimpleOptionsScreen extends SimpleScreen {
+
+ protected final Screen parent;
+ protected final GameOptions gameOptions;
+
+ public SimpleOptionsScreen(Text title, Screen parent, GameOptions gameOptions) {
+ super(title);
+ this.parent = parent;
+ this.gameOptions = gameOptions;
+ }
+
+ @Override
+ public void removed() {
+ client.options.write();
+ }
+
+ @Override
+ public void close() {
+ client.setScreen(this.parent);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleScreen.java
new file mode 100644
index 000000000..7a129ecdb
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleScreen.java
@@ -0,0 +1,192 @@
+package net.pitan76.mcpitanlib.api.client;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.Drawable;
+import net.minecraft.client.gui.Element;
+import net.minecraft.client.gui.Selectable;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.client.gui.widget.CompatibleTexturedButtonWidget;
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.*;
+import net.pitan76.mcpitanlib.api.client.render.screen.RenderBackgroundTextureArgs;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.IdentifierUtil;
+import net.pitan76.mcpitanlib.api.util.client.RenderUtil;
+
+public abstract class SimpleScreen extends Screen {
+
+ public int width, height;
+ public TextRenderer textRenderer;
+ public ItemRenderer itemRenderer;
+
+ public Text title;
+ public MinecraftClient client;
+
+ public SimpleScreen(Text title) {
+ super(title);
+ fixScreen();
+ this.title = title;
+ }
+
+ public T addDrawableChild_compatibility(T drawableElement) {
+ return super.addDrawableChild(drawableElement);
+ // addButton
+ }
+
+ public T addSelectableChild_compatibility(T selectableElement) {
+ return super.addSelectableChild(selectableElement);
+ }
+
+ public CompatibleTexturedButtonWidget addDrawableCTBW(CompatibleTexturedButtonWidget widget) {
+ return addDrawableChild_compatibility(widget);
+ }
+
+ public void callDrawTexture(DrawObjectDM drawObjectDM, Identifier texture, int x, int y, int u, int v, int width, int height) {
+ //ScreenUtil.setBackground(GUI);
+ //super.drawTexture(matrices, x, y, u, v, width, height);
+ drawObjectDM.getContext().drawTexture(texture, x, y, u, v, width, height, 256, 256);
+ }
+
+ public void callDrawTexture(DrawObjectDM drawObjectDM, CompatIdentifier texture, int x, int y, int u, int v, int width, int height) {
+ callDrawTexture(drawObjectDM, texture.toMinecraft(), x, y, u, v, width, height);
+ }
+
+ @Deprecated
+ @Override
+ public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) {
+ renderBackground(new RenderArgs(new DrawObjectDM(context, this), mouseX, mouseY, delta));
+ }
+
+
+ public void renderBackground(RenderArgs args) {
+ super.renderBackground(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void render(RenderArgs args) {
+ super.render(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void resizeOverride(MinecraftClient client, int width, int height) {
+ }
+
+ public void initOverride() {
+ }
+
+ @Deprecated
+ @Override
+ protected void init() {
+ super.init();
+ fixScreen();
+ initOverride();
+ }
+
+ @Deprecated
+ @Override
+ public void resize(MinecraftClient client, int width, int height) {
+ super.resize(client, width, height);
+ fixScreen();
+ resizeOverride(client, width, height);
+ }
+
+ public void fixScreen() {
+ this.textRenderer = super.textRenderer;
+ this.itemRenderer = MinecraftClient.getInstance().getItemRenderer();
+ this.width = super.width;
+ this.height = super.height;
+ if (super.client == null)
+ this.client = MinecraftClient.getInstance();
+ else
+ this.client = super.client;
+ }
+
+ public void setTextRenderer(TextRenderer textRenderer) {
+ this.textRenderer = textRenderer;
+ super.textRenderer = textRenderer;
+ }
+
+ public void setItemRenderer(ItemRenderer itemRenderer) {
+ this.itemRenderer = itemRenderer;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ super.width = width;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ super.height = height;
+ }
+
+ @Deprecated
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ render(new RenderArgs(drawObjectDM, mouseX, mouseY, delta));
+ }
+
+ public boolean keyReleased(KeyEventArgs args) {
+ return super.keyReleased(args.keyCode, args.scanCode, args.modifiers);
+ }
+
+ public boolean keyPressed(KeyEventArgs args) {
+ return super.keyPressed(args.keyCode, args.scanCode, args.modifiers);
+ }
+
+ public void renderBackgroundTexture(RenderBackgroundTextureArgs args) {
+ if (getBackgroundTexture() != null)
+ Screen.renderBackgroundTexture(args.getDrawObjectDM().getContext(), getBackgroundTexture(), 0, 0, 0, 0, this.width, this.height);
+
+ RenderUtil.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ callDrawTexture(args.drawObjectDM, getBackgroundTexture(), 0, 0, 0, 0, width, height);
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
+ return this.keyReleased(new KeyEventArgs(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ return this.keyPressed(new KeyEventArgs(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public void renderDarkening(DrawContext context) {
+ this.renderBackgroundTexture(new RenderBackgroundTextureArgs(new DrawObjectDM(context, this), 0));
+ }
+
+ public void closeOverride() {
+ super.close();
+ }
+
+ public void removedOverride() {
+ super.removed();
+ }
+
+ @Override
+ public void close() {
+ closeOverride();
+ }
+
+ @Override
+ public void removed() {
+ removedOverride();
+ }
+
+ public Identifier getBackgroundTexture() {
+ return IdentifierUtil.from(getCompatBackgroundTexture());
+ }
+
+ public CompatIdentifier getCompatBackgroundTexture() {
+ return null;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/color/BlockColorEvent.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/color/BlockColorEvent.java
new file mode 100644
index 000000000..7e2873166
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/color/BlockColorEvent.java
@@ -0,0 +1,83 @@
+package net.pitan76.mcpitanlib.api.client.color;
+
+import dev.architectury.injectables.annotations.ExpectPlatform;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.BlockRenderView;
+import net.pitan76.mcpitanlib.midohra.world.BlockView;
+import org.jetbrains.annotations.Nullable;
+
+public class BlockColorEvent {
+ private final BlockState state;
+ private final BlockRenderView world;
+ private final BlockPos pos;
+ private final int tintIndex;
+
+ public BlockColorEvent(BlockState state, @Nullable BlockRenderView world, @Nullable BlockPos pos, int tintIndex) {
+ this.state = state;
+ this.world = world;
+ this.pos = pos;
+ this.tintIndex = tintIndex;
+ }
+
+ public BlockState getState() {
+ return state;
+ }
+
+ public BlockRenderView getWorld() {
+ return world;
+ }
+
+ public BlockPos getPos() {
+ return pos;
+ }
+
+ public int getTintIndex() {
+ return tintIndex;
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.BlockPos getMidohraPos() {
+ return net.pitan76.mcpitanlib.midohra.util.math.BlockPos.of(getPos());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getMidohraState() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(getState());
+ }
+
+ public boolean hasWorld() {
+ return getWorld() != null;
+ }
+
+ public boolean hasPos() {
+ return getPos() != null;
+ }
+
+ public BlockView getMidohraWorld() {
+ if (!hasWorld()) return null;
+ return net.pitan76.mcpitanlib.midohra.world.BlockView.of(getWorld());
+ }
+
+ public BlockEntity getBlockEntity() {
+ if (!hasWorld() || !hasPos()) return null;
+ return getWorld().getBlockEntity(getPos());
+ }
+
+ public int getDefaultColor() {
+ return 0xFFFFFF;
+ }
+
+ public Object getRenderData() {
+ if (!hasWorld() || !hasPos()) return null;
+ return getRenderDataD(getBlockEntity());
+ }
+
+ @ExpectPlatform
+ protected static Object getRenderDataD(BlockEntity blockEntity) {
+ if (blockEntity instanceof net.pitan76.mcpitanlib.api.tile.RenderDataBlockEntity) {
+ return ((net.pitan76.mcpitanlib.api.tile.RenderDataBlockEntity) blockEntity).getCompatRenderData();
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/color/CompatBlockColorProvider.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/color/CompatBlockColorProvider.java
new file mode 100644
index 000000000..50ceb12f4
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/color/CompatBlockColorProvider.java
@@ -0,0 +1,15 @@
+package net.pitan76.mcpitanlib.api.client.color;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.client.color.block.BlockColorProvider;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.BlockRenderView;
+import org.jetbrains.annotations.Nullable;
+
+public interface CompatBlockColorProvider extends BlockColorProvider {
+ default int getColor(BlockState state, @Nullable BlockRenderView world, @Nullable BlockPos pos, int tintIndex) {
+ return getColor(new BlockColorEvent(state, world, pos, tintIndex));
+ }
+
+ int getColor(BlockColorEvent e);
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/ItemTooltipRegistry.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/ItemTooltipRegistry.java
new file mode 100644
index 000000000..8166f7406
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/ItemTooltipRegistry.java
@@ -0,0 +1,10 @@
+package net.pitan76.mcpitanlib.api.client.event;
+
+import dev.architectury.event.events.client.ClientTooltipEvent;
+import net.pitan76.mcpitanlib.api.client.event.listener.ItemTooltipListener;
+
+public class ItemTooltipRegistry {
+ public static void registerItemTooltip(ItemTooltipListener listener) {
+ ClientTooltipEvent.ITEM.register(listener::onTooltip);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/WorldRenderRegistry.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/WorldRenderRegistry.java
new file mode 100644
index 000000000..6cba6e3aa
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/WorldRenderRegistry.java
@@ -0,0 +1,21 @@
+package net.pitan76.mcpitanlib.api.client.event;
+
+import dev.architectury.injectables.annotations.ExpectPlatform;
+import net.pitan76.mcpitanlib.api.client.event.listener.BeforeBlockOutlineListener;
+import net.pitan76.mcpitanlib.api.client.event.listener.WorldRenderContextListener;
+
+public class WorldRenderRegistry {
+ public WorldRenderRegistry() {
+
+ }
+
+ @ExpectPlatform
+ public static void registerWorldRenderBeforeBlockOutline(BeforeBlockOutlineListener listener) {
+ throw new AssertionError();
+ }
+
+ @ExpectPlatform
+ public static void registerWorldRenderAfterLevel(WorldRenderContextListener listener) {
+ throw new AssertionError();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/BeforeBlockOutlineEvent.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/BeforeBlockOutlineEvent.java
new file mode 100644
index 000000000..2f740d104
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/BeforeBlockOutlineEvent.java
@@ -0,0 +1,116 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.VertexConsumer;
+import net.minecraft.client.render.WorldRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.hit.BlockHitResult;
+import net.minecraft.util.hit.HitResult;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import net.minecraft.util.shape.VoxelShape;
+import net.minecraft.world.World;
+import net.pitan76.mcpitanlib.midohra.client.render.CameraWrapper;
+import net.pitan76.mcpitanlib.midohra.util.hit.HitResultType;
+
+import java.util.Optional;
+
+public class BeforeBlockOutlineEvent {
+ public WorldRenderContext context;
+ public HitResult hitResult;
+
+ public BeforeBlockOutlineEvent(WorldRenderContext context, HitResult hitResult) {
+ this.context = context;
+ this.hitResult = hitResult;
+ }
+
+ public HitResult getHitResult() {
+ return hitResult;
+ }
+
+ public WorldRenderContext getContext() {
+ return context;
+ }
+
+ public WorldRenderer getWorldRenderer() {
+ return context.getWorldRenderer();
+ }
+
+ public Optional getBlockState() {
+ return Optional.ofNullable(getWorld().getBlockState(getBlockPos().orElse(null)));
+ }
+
+ public World getWorld() {
+ return context.getWorld();
+ }
+
+ public Optional getBlockPos() {
+ return Optional.ofNullable(((BlockHitResult) hitResult).getBlockPos());
+ }
+
+ public boolean isBlockType() {
+ return getHitResultType() == HitResult.Type.BLOCK;
+ }
+
+ public HitResult.Type getHitResultType() {
+ return hitResult.getType();
+ }
+
+ @Deprecated
+ public Camera getCamera() {
+ return context.getCamera();
+ }
+
+ public CameraWrapper getCameraWrapper() {
+ return CameraWrapper.of(getCamera());
+ }
+
+ public Optional getOutlineShape() {
+ return context.getOutlineShape();
+ }
+
+ public MatrixStack getMatrixStack() {
+ return context.getMatrixStack();
+ }
+
+ public void push() {
+ context.push();
+ }
+
+ public void translate(double x, double y, double z) {
+ context.translate(x, y, z);
+ }
+
+ public void pop() {
+ context.pop();
+ }
+
+ public Optional getVertexConsumer() {
+ return context.getVertexConsumer();
+ }
+
+ public void drawBox(float red, float green, float blue, float alpha) {
+ context.drawBox(red, green, blue, alpha);
+ }
+
+ public void drawBox(Box box, float red, float green, float blue, float alpha) {
+ context.drawBox(box, red, green, blue, alpha);
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.hit.HitResult getHitResultM() {
+ return net.pitan76.mcpitanlib.midohra.util.hit.HitResult.of(hitResult);
+ }
+
+ public HitResultType getHitResultTypeM() {
+ return HitResultType.from(hitResult.getType());
+ }
+
+ public BlockState getBlockState2() {
+ return getWorld().getBlockState(getHitResultM().asBlockHitResult().get().getBlockPos());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.block.BlockState getBlockStateM() {
+ return net.pitan76.mcpitanlib.midohra.block.BlockState.of(getBlockState2());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/BeforeBlockOutlineListener.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/BeforeBlockOutlineListener.java
new file mode 100644
index 000000000..881ee7b11
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/BeforeBlockOutlineListener.java
@@ -0,0 +1,11 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+
+@Environment(EnvType.CLIENT)
+@FunctionalInterface
+public interface BeforeBlockOutlineListener {
+ boolean beforeBlockOutline(BeforeBlockOutlineEvent event);
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/ItemTooltipContext.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/ItemTooltipContext.java
new file mode 100644
index 000000000..296fd2778
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/ItemTooltipContext.java
@@ -0,0 +1,58 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.tooltip.TooltipType;
+import net.minecraft.text.Text;
+
+import java.util.List;
+
+public class ItemTooltipContext {
+
+ public ItemStack stack;
+ public List texts;
+ public Item.TooltipContext tooltipContext;
+
+ @Deprecated
+ public TooltipType type;
+
+ public ItemTooltipContext(ItemStack stack, List texts, Item.TooltipContext tooltipContext, TooltipType type) {
+ this.stack = stack;
+ this.texts = texts;
+ this.tooltipContext = tooltipContext;
+ this.type = type;
+ }
+
+ public ItemStack getStack() {
+ return stack;
+ }
+
+ public List getTexts() {
+ return texts;
+ }
+
+ public Item.TooltipContext getTooltipContext() {
+ return tooltipContext;
+ }
+
+ @Deprecated
+ public TooltipType getType() {
+ return type;
+ }
+
+ public void addTooltip(Text text) {
+ texts.add(text);
+ }
+
+ public void addTooltip(List texts) {
+ this.texts.addAll(texts);
+ }
+
+ public boolean isAdvanced() {
+ return type.isAdvanced();
+ }
+
+ public boolean isCreative() {
+ return type.isCreative();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/ItemTooltipListener.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/ItemTooltipListener.java
new file mode 100644
index 000000000..d86227934
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/ItemTooltipListener.java
@@ -0,0 +1,17 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.tooltip.TooltipType;
+import net.minecraft.text.Text;
+
+import java.util.List;
+
+@FunctionalInterface
+public interface ItemTooltipListener {
+ void onTooltip(ItemTooltipContext context);
+
+ default void onTooltip(ItemStack stack, List texts, Item.TooltipContext tooltipContext, TooltipType type) {
+ onTooltip(new ItemTooltipContext(stack, texts, tooltipContext, type));
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContext.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContext.java
new file mode 100644
index 000000000..8a65518d4
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContext.java
@@ -0,0 +1,130 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.block.BlockState;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.*;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.hit.BlockHitResult;
+import net.minecraft.util.hit.HitResult;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import net.minecraft.util.shape.VoxelShape;
+import net.pitan76.mcpitanlib.api.util.VoxelShapeUtil;
+import net.pitan76.mcpitanlib.midohra.client.render.CameraWrapper;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Matrix4f;
+
+import java.util.Objects;
+import java.util.Optional;
+
+public interface WorldRenderContext {
+
+ WorldRenderer getWorldRenderer();
+
+ MatrixStack getMatrixStack();
+
+ float getTickDelta();
+
+ Camera getCamera();
+
+ GameRenderer getGameRenderer();
+
+ LightmapTextureManager getLightmapTextureManager();
+
+ @Deprecated
+ Matrix4f getProjectionMatrix();
+
+ ClientWorld getWorld();
+
+ @Deprecated
+ boolean isAdvancedTranslucency();
+
+ @Nullable VertexConsumerProvider getConsumers();
+ @Nullable Frustum getFrustum();
+
+ @Environment(EnvType.CLIENT)
+ interface BlockOutlineContext {
+ @Deprecated
+ VertexConsumer vertexConsumer();
+
+ Entity entity();
+
+ double cameraX();
+
+ double cameraY();
+
+ double cameraZ();
+
+ BlockPos blockPos();
+
+ BlockState blockState();
+ }
+
+ default HitResult getHitResult() {
+ return MinecraftClient.getInstance().crosshairTarget;
+ }
+
+ default Optional getBlockState() {
+ return Optional.ofNullable(getWorld().getBlockState(getBlockPos().orElse(null)));
+ }
+
+ default Optional getBlockPos() {
+ return Optional.ofNullable(((BlockHitResult) getHitResult()).getBlockPos());
+ }
+
+ default boolean isBlockType() {
+ return getHitResultType() == HitResult.Type.BLOCK;
+ }
+
+ default HitResult.Type getHitResultType() {
+ return getHitResult().getType();
+ }
+
+ default Optional getOutlineShape() {
+ return getBlockState().map(blockState -> blockState.getOutlineShape(getWorld(),
+ getBlockPos().orElse(null)));
+ }
+
+ default void push() {
+ getMatrixStack().push();
+ }
+
+ default void translate(double x, double y, double z) {
+ getMatrixStack().translate(x, y, z);
+ }
+
+ default void pop() {
+ getMatrixStack().pop();
+ }
+
+ default Optional getVertexConsumer() {
+ if (getConsumers() == null)
+ return Optional.empty();
+
+ return Optional.of(Objects.requireNonNull(getConsumers()).getBuffer(RenderLayer.getLines()));
+ }
+
+ default void drawBox(float red, float green, float blue, float alpha) {
+ Optional outlineShape = getOutlineShape();
+ if (!outlineShape.isPresent()) return;
+
+ drawBox(VoxelShapeUtil.getBoundingBox(outlineShape.get()), red, green, blue, alpha);
+ }
+
+ default void drawBox(Box box, float red, float green, float blue, float alpha) {
+ Optional vertexConsumer = getVertexConsumer();
+
+ if (!vertexConsumer.isPresent())
+ return;
+
+ WorldRenderer.drawBox(getMatrixStack(), vertexConsumer.get(), box, red, green, blue, alpha);
+ }
+
+ default CameraWrapper getCameraWrapper() {
+ return CameraWrapper.of(getCamera());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContextListener.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContextListener.java
new file mode 100644
index 000000000..7025eae59
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContextListener.java
@@ -0,0 +1,10 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+
+@Environment(EnvType.CLIENT)
+@FunctionalInterface
+public interface WorldRenderContextListener {
+ void render(WorldRenderContext context);
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/CompatInventoryScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/CompatInventoryScreen.java
new file mode 100644
index 000000000..675de4d31
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/CompatInventoryScreen.java
@@ -0,0 +1,33 @@
+package net.pitan76.mcpitanlib.api.client.gui.screen;
+
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.screen.slot.Slot;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.guilib.api.render.SlotRenderer;
+
+public abstract class CompatInventoryScreen extends SimpleInventoryScreen {
+
+ public CompatInventoryScreen(S handler, PlayerInventory inventory, Text title) {
+ super(handler, inventory, title);
+ }
+
+ public abstract CompatIdentifier getCompatTexture();
+
+ @Deprecated
+ @Override
+ public Identifier getTexture() {
+ return getCompatTexture().toMinecraft();
+ }
+
+ public void drawSlot(DrawObjectDM drawObjectDM, Slot slot) {
+ SlotRenderer.drawSlot(drawObjectDM, slot, x, y);
+ }
+
+ public void drawSlots(DrawObjectDM drawObjectDM) {
+ SlotRenderer.drawSlots(drawObjectDM, handler, x, y);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/ScreenTexts.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/ScreenTexts.java
new file mode 100644
index 000000000..da47fb543
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/ScreenTexts.java
@@ -0,0 +1,21 @@
+package net.pitan76.mcpitanlib.api.client.gui.screen;
+
+import net.minecraft.text.Text;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+
+public class ScreenTexts {
+ public static final Text ON = TextUtil.translatable("options.on");
+ public static final Text OFF = TextUtil.translatable("options.off");
+ public static final Text DONE = TextUtil.translatable("gui.done");
+ public static final Text CANCEL = TextUtil.translatable("gui.cancel");
+ public static final Text YES = TextUtil.translatable("gui.yes");
+ public static final Text NO = TextUtil.translatable("gui.no");
+ public static final Text PROCEED = TextUtil.translatable("gui.proceed");
+ public static final Text BACK = TextUtil.translatable("gui.back");
+ public static final Text CONNECT_FAILED = TextUtil.translatable("connect.failed");
+ public static final Text LINE_BREAK = TextUtil.literal("\n");
+ public static final Text SENTENCE_SEPARATOR = TextUtil.literal(". ");
+
+ public ScreenTexts() {
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleHandledScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleHandledScreen.java
new file mode 100644
index 000000000..fd7773668
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleHandledScreen.java
@@ -0,0 +1,364 @@
+package net.pitan76.mcpitanlib.api.client.gui.screen;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.Drawable;
+import net.minecraft.client.gui.Element;
+import net.minecraft.client.gui.Selectable;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.client.gui.widget.CompatibleTexturedButtonWidget;
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.*;
+import net.pitan76.mcpitanlib.api.client.render.screen.RenderBackgroundTextureArgs;
+import net.pitan76.mcpitanlib.api.text.TextComponent;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.IdentifierUtil;
+import net.pitan76.mcpitanlib.api.util.client.ClientUtil;
+import net.pitan76.mcpitanlib.api.util.client.RenderUtil;
+import net.pitan76.mcpitanlib.api.util.client.ScreenUtil;
+import net.pitan76.mcpitanlib.core.datafixer.Pair;
+
+public abstract class SimpleHandledScreen extends HandledScreen {
+
+ public int width, height, backgroundWidth, backgroundHeight, x, y;
+ public S handler;
+ public TextRenderer textRenderer;
+ public ItemRenderer itemRenderer;
+
+ public Text title;
+ public MinecraftClient client;
+ public SimpleHandledScreen(S handler, PlayerInventory inventory, Text title) {
+ super(handler, inventory, title);
+ fixScreen();
+ this.handler = handler;
+ this.title = title;
+
+ }
+
+ @Deprecated
+ @Override
+ public S getScreenHandler() {
+ return getScreenHandlerOverride();
+ }
+
+ public S getScreenHandlerOverride() {
+ return super.getScreenHandler();
+ }
+
+ public T addDrawableChild_compatibility(T drawableElement) {
+ return super.addDrawableChild(drawableElement);
+ // addButton
+ }
+
+ public T addSelectableChild_compatibility(T selectableElement) {
+ return super.addSelectableChild(selectableElement);
+ }
+
+ public CompatibleTexturedButtonWidget addDrawableCTBW(CompatibleTexturedButtonWidget widget) {
+ return addDrawableChild_compatibility(widget);
+ }
+
+ @Deprecated
+ @Override
+ protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawBackgroundOverride(new DrawBackgroundArgs(drawObjectDM, delta, mouseX, mouseY));
+ }
+
+ public abstract void drawBackgroundOverride(DrawBackgroundArgs args);
+
+ @Deprecated
+ @Override
+ protected void drawForeground(DrawContext context, int mouseX, int mouseY) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawForegroundOverride(new DrawForegroundArgs(drawObjectDM, mouseX, mouseY));
+ }
+
+ protected void drawForegroundOverride(DrawForegroundArgs args) {
+ super.drawForeground(args.drawObjectDM.getContext(), args.mouseX, args.mouseY);
+ }
+
+ public void callDrawTexture(DrawObjectDM drawObjectDM, Identifier texture, int x, int y, int u, int v, int width, int height) {
+ drawObjectDM.getContext().drawTexture(texture, x, y, u, v, width, height, 256, 256);
+ }
+
+ public void callDrawTexture(DrawObjectDM drawObjectDM, CompatIdentifier texture, int x, int y, int u, int v, int width, int height) {
+ callDrawTexture(drawObjectDM, texture.toMinecraft(), x, y, u, v, width, height);
+ }
+
+ @Deprecated
+ public void callRenderBackground(DrawObjectDM drawObjectDM) {
+ callRenderBackground(new RenderArgs(drawObjectDM, 0, 0, 0));
+ }
+
+
+ public void callRenderBackground(RenderArgs args) {
+ super.renderBackground(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void callDrawMouseoverTooltip(DrawMouseoverTooltipArgs args) {
+ super.drawMouseoverTooltip(args.drawObjectDM.getContext(), args.mouseX, args.mouseY);
+ }
+
+ public void renderOverride(RenderArgs args) {
+ super.render(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void resizeOverride(MinecraftClient client, int width, int height) {
+ }
+
+ public void initOverride() {
+ }
+
+ @Deprecated
+ @Override
+ protected void init() {
+ super.init();
+ fixScreen();
+ initOverride();
+ }
+
+ @Deprecated
+ @Override
+ public void resize(MinecraftClient client, int width, int height) {
+ super.resize(client, width, height);
+ fixScreen();
+ resizeOverride(client, width, height);
+ }
+
+ public void fixScreen() {
+ this.backgroundWidth = getBackgroundWidth();
+ this.backgroundHeight = getBackgroundHeight();
+ this.x = super.x; //(this.width - this.backgroundWidth) / 2;
+ this.y = super.y; //(this.height - this.backgroundHeight) / 2;
+ this.textRenderer = super.textRenderer;
+ this.itemRenderer = MinecraftClient.getInstance().getItemRenderer();
+ this.width = super.width;
+ this.height = super.height;
+ if (super.client == null)
+ this.client = MinecraftClient.getInstance();
+ else
+ this.client = super.client;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ super.x = x;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ super.y = y;
+ }
+
+ public void setTextRenderer(TextRenderer textRenderer) {
+ this.textRenderer = textRenderer;
+ super.textRenderer = textRenderer;
+ }
+
+ public void setItemRenderer(ItemRenderer itemRenderer) {
+ this.itemRenderer = itemRenderer;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ super.width = width;
+ }
+
+ public void setBackgroundWidth(int backgroundWidth) {
+ this.backgroundWidth = backgroundWidth;
+ super.backgroundWidth = backgroundWidth;
+ }
+
+ public void setBackgroundHeight(int backgroundHeight) {
+ this.backgroundHeight = backgroundHeight;
+ super.backgroundHeight = backgroundHeight;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ super.height = height;
+ }
+
+ public int getBackgroundWidth() {
+ return super.backgroundWidth;
+ }
+
+ public int getBackgroundHeight() {
+ return super.backgroundHeight;
+ }
+
+ @Deprecated
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ renderOverride(new RenderArgs(drawObjectDM, mouseX, mouseY, delta));
+ }
+
+ public boolean keyReleased(KeyEventArgs args) {
+ return super.keyReleased(args.keyCode, args.scanCode, args.modifiers);
+ }
+
+ public boolean keyPressed(KeyEventArgs args) {
+ return super.keyPressed(args.keyCode, args.scanCode, args.modifiers);
+ }
+
+ public void renderBackgroundTexture(RenderBackgroundTextureArgs args) {
+ if (getBackgroundTexture() != null)
+ Screen.renderBackgroundTexture(args.getDrawObjectDM().getContext(), getBackgroundTexture(), x, y, 0, 0, this.width, this.height);
+
+ RenderUtil.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ callDrawTexture(args.drawObjectDM, getBackgroundTexture(), 0, 0, 0, 0, width, height);
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
+ return this.keyReleased(new KeyEventArgs(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ return this.keyPressed(new KeyEventArgs(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public void renderDarkening(DrawContext context) {
+ this.renderBackgroundTexture(new RenderBackgroundTextureArgs(new DrawObjectDM(context, this), 0));
+ }
+
+ public void closeOverride() {
+ super.close();
+ }
+
+ public void removedOverride() {
+ super.removed();
+ }
+
+ @Override
+ public void close() {
+ closeOverride();
+ }
+
+ @Override
+ public void removed() {
+ removedOverride();
+ }
+
+ public Identifier getBackgroundTexture() {
+ return IdentifierUtil.from(getCompatBackgroundTexture());
+ }
+
+ public CompatIdentifier getCompatBackgroundTexture() {
+ return null;
+ }
+
+ public void setTitleX(int x) {
+ this.titleX = x;
+ }
+
+ public void setTitleY(int y) {
+ this.titleY = y;
+ }
+
+ public void setTitlePos(int x, int y) {
+ setTitleX(x);
+ setTitleY(y);
+ }
+
+ public void setTitleXCenter() {
+ if (textRenderer == null)
+ textRenderer = ClientUtil.getTextRenderer();
+
+ setTitleX(backgroundWidth / 2 - textRenderer.getWidth(title) / 2);
+ }
+
+ public int getTitleX() {
+ return titleX;
+ }
+
+ public int getTitleY() {
+ return titleY;
+ }
+
+ public void drawText(DrawObjectDM drawObjectDM, Text text, int x, int y, int color) {
+ ScreenUtil.RendererUtil.drawText(textRenderer, drawObjectDM, text, x, y, color);
+ }
+
+ public void drawText(DrawObjectDM drawObjectDM, TextComponent text, int x, int y, int color) {
+ ScreenUtil.RendererUtil.drawText(textRenderer, drawObjectDM, text, x, y, color);
+ }
+
+ public void drawText(DrawObjectDM drawObjectDM, Text text, int x, int y) {
+ ScreenUtil.RendererUtil.drawText(textRenderer, drawObjectDM, text, x, y);
+ }
+
+ public void drawText(DrawObjectDM drawObjectDM, TextComponent text, int x, int y) {
+ ScreenUtil.RendererUtil.drawText(textRenderer, drawObjectDM, text, x, y);
+ }
+
+ @Deprecated
+ @Override
+ public Text getTitle() {
+ return callGetTitle();
+ }
+
+ public Text callGetTitle() {
+ return super.getTitle();
+ }
+
+ public Pair getTitlePosP() {
+ return new Pair<>(getTitleX(), getTitleY());
+ }
+
+ public int getPlayerInvTitleX() {
+ return playerInventoryTitleX;
+ }
+
+ public int getPlayerInvTitleY() {
+ return playerInventoryTitleY;
+ }
+
+ public void setPlayerInvTitleX(int x) {
+ playerInventoryTitleX = x;
+ }
+
+ public void setPlayerInvTitleY(int y) {
+ playerInventoryTitleY = y;
+ }
+
+ public void setPlayerInvTitle(int x, int y) {
+ setPlayerInvTitleX(x);
+ setPlayerInvTitleY(y);
+ }
+
+ public TextRenderer callGetTextRenderer() {
+ if (textRenderer != null)
+ return textRenderer;
+
+ if (super.textRenderer != null)
+ return super.textRenderer;
+
+ return ClientUtil.getTextRenderer();
+ }
+
+ public ItemRenderer callGetItemRenderer() {
+ if (itemRenderer != null)
+ return itemRenderer;
+
+ return ClientUtil.getItemRenderer();
+ }
+
+ public Text getPlayerInvTitle() {
+ return playerInventoryTitle;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleInventoryScreen.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleInventoryScreen.java
new file mode 100644
index 000000000..daa47269d
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleInventoryScreen.java
@@ -0,0 +1,38 @@
+package net.pitan76.mcpitanlib.api.client.gui.screen;
+
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.DrawBackgroundArgs;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.DrawMouseoverTooltipArgs;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.RenderArgs;
+import net.pitan76.mcpitanlib.api.util.client.RenderUtil;
+
+public abstract class SimpleInventoryScreen extends SimpleHandledScreen {
+
+ public SimpleInventoryScreen(S handler, PlayerInventory inventory, Text title) {
+ super(handler, inventory, title);
+ }
+
+ public abstract Identifier getTexture();
+
+ @Override
+ public Identifier getBackgroundTexture() {
+ return getTexture();
+ }
+
+ @Override
+ public void drawBackgroundOverride(DrawBackgroundArgs args) {
+ RenderUtil.setShaderToPositionTexProgram();
+ RenderUtil.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ callDrawTexture(args.drawObjectDM, getTexture(), x, y, 0, 0, backgroundWidth, backgroundHeight);
+ }
+
+ @Override
+ public void renderOverride(RenderArgs args) {
+ this.callRenderBackground(args);
+ super.renderOverride(args);
+ this.callDrawMouseoverTooltip(new DrawMouseoverTooltipArgs(args.drawObjectDM, args.mouseX, args.mouseY));
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatTextFieldWidget.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatTextFieldWidget.java
new file mode 100644
index 000000000..a29256a75
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatTextFieldWidget.java
@@ -0,0 +1,143 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.widget.TextFieldWidget;
+import net.minecraft.text.Text;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+import org.jetbrains.annotations.Nullable;
+
+public class CompatTextFieldWidget extends TextFieldWidget {
+ public CompatTextFieldWidget(TextRenderer textRenderer, int width, int height) {
+ this(textRenderer, width, height, TextUtil.empty());
+ }
+
+ public CompatTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height) {
+ this(textRenderer, x, y, width, height, TextUtil.empty());
+ }
+
+ // ----
+
+ public CompatTextFieldWidget(TextRenderer textRenderer, int width, int height, Text text) {
+ super(textRenderer, width, height, text);
+ }
+
+ public CompatTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, Text text) {
+ super(textRenderer, x, y, width, height, text);
+ }
+
+ public CompatTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, @Nullable TextFieldWidget copyFrom, Text text) {
+ super(textRenderer, x, y, width, height, copyFrom, text);
+ }
+
+ // ----
+
+ @Deprecated
+ @Override
+ public void setDrawsBackground(boolean drawsBackground) {
+ callSetDrawsBackground(drawsBackground);
+ }
+
+ public void callSetDrawsBackground(boolean drawsBackground) {
+ super.setDrawsBackground(drawsBackground);
+ }
+
+ @Deprecated
+ @Override
+ public void setFocused(boolean focused) {
+ callSetFocused(focused);
+ }
+
+ public void callSetFocused(boolean focused) {
+ super.setFocused(focused);
+ }
+
+ @Deprecated
+ @Override
+ public void setFocusUnlocked(boolean focusUnlocked) {
+ callSetFocusUnlocked(focusUnlocked);
+ }
+
+ public void callSetFocusUnlocked(boolean focusUnlocked) {
+ super.setFocusUnlocked(focusUnlocked);
+ }
+
+ @Deprecated
+ @Override
+ public void setMaxLength(int maxLength) {
+ callSetMaxLength(maxLength);
+ }
+
+ public void callSetMaxLength(int maxLength) {
+ super.setMaxLength(maxLength);
+ }
+
+ @Deprecated
+ @Override
+ public void setText(String text) {
+ callSetText(text);
+ }
+
+ public void callSetText(String text) {
+ super.setText(text);
+ }
+
+ @Deprecated
+ @Override
+ public String getText() {
+ return callGetText();
+ }
+
+ public String callGetText() {
+ return super.getText();
+ }
+
+ @Deprecated
+ @Override
+ public void setEditable(boolean editable) {
+ callSetEditable(editable);
+ }
+
+ public void callSetEditable(boolean editable) {
+ super.setEditable(editable);
+ }
+
+ @Deprecated
+ @Override
+ public boolean isFocused() {
+ return callIsFocused();
+ }
+
+ public boolean callIsFocused() {
+ return super.isFocused();
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ return callKeyPressed(keyCode, scanCode, modifiers);
+ }
+
+ public boolean callKeyPressed(int keyCode, int scanCode, int modifiers) {
+ return super.keyPressed(keyCode, scanCode, modifiers);
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
+ return callKeyReleased(keyCode, scanCode, modifiers);
+ }
+
+ public boolean callKeyReleased(int keyCode, int scanCode, int modifiers) {
+ return super.keyReleased(keyCode, scanCode, modifiers);
+ }
+
+ @Deprecated
+ @Override
+ public boolean charTyped(char chr, int modifiers) {
+ return callCharTyped(chr, modifiers);
+ }
+
+ public boolean callCharTyped(char chr, int modifiers) {
+ return super.charTyped(chr, modifiers);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatibleTexturedButtonWidget.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatibleTexturedButtonWidget.java
new file mode 100644
index 000000000..570ccc957
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatibleTexturedButtonWidget.java
@@ -0,0 +1,73 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ButtonTextures;
+import net.minecraft.client.gui.widget.ButtonWidget;
+import net.minecraft.client.gui.widget.TexturedButtonWidget;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+
+public class CompatibleTexturedButtonWidget extends TexturedButtonWidget {
+ private final Identifier texture;
+ private final int u;
+ private final int v;
+ private final int hoveredVOffset;
+ private final int textureWidth;
+ private final int textureHeight;
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, Identifier texture, ButtonWidget.PressAction pressAction) {
+ this(x, y, width, height, u, v, height, texture, 256, 256, pressAction);
+ }
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, ButtonWidget.PressAction pressAction) {
+ this(x, y, width, height, u, v, hoveredVOffset, texture, 256, 256, pressAction);
+ }
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight, ButtonWidget.PressAction pressAction) {
+ this(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, TextUtil.empty());
+ }
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight, ButtonWidget.PressAction pressAction, Text text) {
+ super(x, y, width, height, new ButtonTextures(texture, texture), pressAction, text);
+ this.textureWidth = textureWidth;
+ this.textureHeight = textureHeight;
+ this.u = u;
+ this.v = v;
+ this.hoveredVOffset = hoveredVOffset;
+ this.texture = texture;
+ }
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, CompatIdentifier texture, ButtonWidget.PressAction pressAction) {
+ this(x, y, width, height, u, v, texture.toMinecraft(), pressAction);
+ }
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, CompatIdentifier texture, ButtonWidget.PressAction pressAction) {
+ this(x, y, width, height, u, v, hoveredVOffset, texture.toMinecraft(), pressAction);
+ }
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, CompatIdentifier texture, int textureWidth, int textureHeight, ButtonWidget.PressAction pressAction) {
+ this(x, y, width, height, u, v, hoveredVOffset, texture.toMinecraft(), textureWidth, textureHeight, pressAction);
+ }
+
+ public CompatibleTexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, CompatIdentifier texture, int textureWidth, int textureHeight, ButtonWidget.PressAction pressAction, Text text) {
+ this(x, y, width, height, u, v, hoveredVOffset, texture.toMinecraft(), textureWidth, textureHeight, pressAction, text);
+ }
+
+ public void setPos(int x, int y) {
+ setX(x);
+ setY(y);
+ }
+
+ @Override
+ public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
+ int i = v;
+ if (!this.isNarratable()) {
+ i = v + hoveredVOffset * 2;
+ } else if (this.isHovered()) {
+ i += hoveredVOffset;
+ }
+ context.drawTexture(texture, this.getX(), this.getY(), u, i, this.width, this.height, textureWidth, textureHeight);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/RedrawableTexturedButtonWidget.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/RedrawableTexturedButtonWidget.java
new file mode 100644
index 000000000..ba6363c39
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/RedrawableTexturedButtonWidget.java
@@ -0,0 +1,52 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+
+public class RedrawableTexturedButtonWidget extends CompatibleTexturedButtonWidget {
+ public Identifier texture;
+ public int u;
+ public int v;
+ public int hoveredVOffset;
+ public int textureWidth;
+ public int textureHeight;
+
+ public RedrawableTexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight, PressAction pressAction, Text message) {
+ super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, message);
+ this.textureWidth = textureWidth;
+ this.textureHeight = textureHeight;
+ this.u = u;
+ this.v = v;
+ this.hoveredVOffset = hoveredVOffset;
+ this.texture = texture;
+ }
+
+ public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) {
+ super.renderWidget(context, mouseX, mouseY, delta);
+ }
+
+ public void setTexture(Identifier texture) {
+ this.texture = texture;
+ }
+
+ public void setU(int u) {
+ this.u = u;
+ }
+
+ public void setV(int v) {
+ this.v = v;
+ }
+
+ public void setHoveredVOffset(int hoveredVOffset) {
+ this.hoveredVOffset = hoveredVOffset;
+ }
+
+ public void setTextureWidth(int textureWidth) {
+ this.textureWidth = textureWidth;
+ }
+
+ public void setTextureHeight(int textureHeight) {
+ this.textureHeight = textureHeight;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleListWidget.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleListWidget.java
new file mode 100644
index 000000000..d93a910dd
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleListWidget.java
@@ -0,0 +1,115 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import com.google.common.collect.ImmutableList;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.Element;
+import net.minecraft.client.gui.Selectable;
+import net.minecraft.client.gui.widget.ClickableWidget;
+import net.minecraft.client.gui.widget.ElementListWidget;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.RenderArgs;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Optional;
+
+@Environment(EnvType.CLIENT)
+public class SimpleListWidget extends ElementListWidget {
+
+ public SimpleListWidget(MinecraftClient client, int width, int height, int top, int bottom, int itemHeight) {
+ this(client, width, bottom - top, top, itemHeight);
+ }
+
+ public SimpleListWidget(MinecraftClient client, int width, int height, int y, int itemHeight) {
+ super(client, width, height, y, itemHeight);
+ this.centerListVertically = false;
+ }
+
+ public void add(ClickableWidget widget) {
+ super.addEntry(WidgetEntry.create(widget));
+ }
+
+ @Override
+ public int getRowWidth() {
+ return 400;
+ }
+
+ public int getWidth() {
+ return this.width;
+ }
+
+ public int getHeight() {
+ return this.height;
+ }
+
+ @Override
+ protected int getScrollbarX() {
+ return super.getScrollbarX() + 32;
+ }
+
+ @Nullable
+ public ClickableWidget getWidget(int index) {
+ if (index < 0 || index >= this.children().size()) {
+ return null;
+ }
+ return this.children().get(index).getWidget();
+ }
+
+ public Optional getHoveredWidget(double mouseX, double mouseY) {
+ for (WidgetEntry entry : this.children()) {
+ if (entry.getWidget().isMouseOver(mouseX, mouseY)) {
+ return Optional.of(entry.getWidget());
+ }
+ }
+ return Optional.empty();
+ }
+
+ /*
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ this.render(new RenderArgs(new DrawObjectDM(context), mouseX, mouseY, delta));
+ }
+ */
+
+ public void render(RenderArgs args) {
+ super.render(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ @Environment(EnvType.CLIENT)
+ public static class WidgetEntry extends Entry {
+ protected final ClickableWidget widget;
+
+ public WidgetEntry(ClickableWidget widget) {
+ this.widget = widget;
+ }
+
+ public static WidgetEntry create(ClickableWidget widget) {
+ return new WidgetEntry(widget);
+ }
+
+ @Deprecated
+ @Override
+ public void render(DrawContext matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
+ widget.setY(y);
+ widget.render(matrices, mouseX, mouseY, tickDelta);
+ }
+
+ @Deprecated
+ @Override
+ public List extends Element> children() {
+ return ImmutableList.of(widget);
+ }
+
+ @Deprecated
+ @Override
+ public List extends Selectable> selectableChildren() {
+ return ImmutableList.of(widget);
+ }
+
+ public ClickableWidget getWidget() {
+ return widget;
+ }
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleSliderWidget.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleSliderWidget.java
new file mode 100644
index 000000000..7c4b87d68
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleSliderWidget.java
@@ -0,0 +1,82 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.widget.SliderWidget;
+import net.minecraft.text.Text;
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.RenderArgs;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+@Environment(EnvType.CLIENT)
+public class SimpleSliderWidget extends SliderWidget {
+ protected final Function textGetter;
+ protected final Consumer changeCallback;
+ public SimpleListWidget listWidget = null;
+
+ public SimpleSliderWidget(int x, int y, int width, int height, Text text, double defaultValue, ValueTextGetter valueTextGetter, Consumer changeCallback) {
+ super(x, y, width, height, text, defaultValue);
+ this.textGetter = (Double value) -> valueTextGetter.get(text, value);
+ this.changeCallback = changeCallback;
+ this.updateMessage();
+ }
+ public SimpleSliderWidget(int x, int y, int width, int height, double defaultValue, ValueTextGetter valueTextGetter, Consumer changeCallback) {
+ this(x, y, width, height, TextUtil.empty(), defaultValue, valueTextGetter, changeCallback);
+ }
+
+ public SimpleSliderWidget(int x, int y, int width, Text text, double defaultValue, ValueTextGetter valueTextGetter, Consumer changeCallback) {
+ this(x, y, width, 20, text, defaultValue, valueTextGetter, changeCallback);
+ }
+
+ public SimpleSliderWidget(int x, int y, int width, double defaultValue, ValueTextGetter valueTextGetter, Consumer changeCallback) {
+ this(x, y, width, 20, defaultValue, valueTextGetter, changeCallback);
+ }
+
+ public SimpleSliderWidget(SimpleListWidget listWidget, int width, Text text, double defaultValue, ValueTextGetter valueTextGetter, Consumer changeCallback) {
+ this(listWidget.getWidth() / 2 - 155, 0, width, 20, text, defaultValue, valueTextGetter, changeCallback);
+ this.listWidget = listWidget;
+ }
+
+ public SimpleSliderWidget(SimpleListWidget listWidget, int width, double defaultValue, ValueTextGetter valueTextGetter, Consumer changeCallback) {
+ this(listWidget, width, TextUtil.empty(), defaultValue, valueTextGetter, changeCallback);
+ }
+
+ /*
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ this.render(new RenderArgs(new DrawObjectDM(context), mouseX, mouseY, delta));
+ }
+ */
+
+ public void render(RenderArgs args) {
+ super.render(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void setValue(double value) {
+ super.value = value;
+ }
+
+ public double getValue() {
+ return super.value;
+ }
+
+ @Override
+ protected void updateMessage() {
+ this.setMessage(this.textGetter.apply(this.getValue()));
+ }
+
+ @Override
+ protected void applyValue() {
+ this.changeCallback.accept(this.getValue());
+ }
+
+ @Environment(EnvType.CLIENT)
+ @FunctionalInterface
+ public interface ValueTextGetter {
+ Text get(Text optionText, Double value);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/CompatKeyBinding.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/CompatKeyBinding.java
new file mode 100644
index 000000000..ab95ef05b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/CompatKeyBinding.java
@@ -0,0 +1,57 @@
+package net.pitan76.mcpitanlib.api.client.option;
+
+import net.minecraft.client.option.KeyBinding;
+import net.minecraft.text.Text;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+import java.util.Objects;
+
+public class CompatKeyBinding {
+ private final KeyBinding keyBinding;
+
+ public CompatKeyBinding(KeyBinding keyBinding) {
+ this.keyBinding = keyBinding;
+ }
+
+ public CompatKeyBinding(String translationKey, int defaultKeyCode, CompatIdentifier category) {
+ this.keyBinding = new KeyBinding(translationKey, defaultKeyCode, "key.category." + category.getNamespace() + "." + category.getPath());
+ }
+
+ public CompatKeyBinding(String translationKey, int defaultKeyCode) {
+ String[] parts = translationKey.split("\\.");
+ if (Objects.equals(parts[0], "key") && parts.length == 3) {
+ CompatIdentifier category = CompatIdentifier.of(parts[1], "main");
+ this.keyBinding = new KeyBinding(translationKey, defaultKeyCode, "key.category." + category.getNamespace() + "." + category.getPath());
+ } else {
+ throw new IllegalArgumentException("Cannot infer category from translation key: " + translationKey);
+ }
+ }
+
+ public String getTranslationKey() {
+ return keyBinding.getBoundKeyTranslationKey();
+ }
+
+ public Text getBoundKeyLocalizedText() {
+ return keyBinding.getBoundKeyLocalizedText();
+ }
+
+ public int getDefaultKeyCode() {
+ return keyBinding.getDefaultKey().getCode();
+ }
+
+ public static CompatKeyBinding of(String translationKey, int defaultKeyCode, CompatIdentifier category) {
+ return new CompatKeyBinding(translationKey, defaultKeyCode, category);
+ }
+
+ public static CompatKeyBinding of(String translationKey, int defaultKeyCode) {
+ return new CompatKeyBinding(translationKey, defaultKeyCode);
+ }
+
+ public KeyBinding toMinecraft() {
+ return keyBinding;
+ }
+
+ public KeyBinding getRaw() {
+ return keyBinding;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/GameOptionsWrapper.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/GameOptionsWrapper.java
new file mode 100644
index 000000000..3bdfa6bfe
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/GameOptionsWrapper.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.client.option;
+
+import net.minecraft.client.option.GameOptions;
+
+public class GameOptionsWrapper {
+ public final GameOptions raw;
+
+ public GameOptionsWrapper(GameOptions options) {
+ this.raw = options;
+ }
+
+ public GameOptions getRaw() {
+ return raw;
+ }
+
+ public void write() {
+ raw.write();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/KeyCodes.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/KeyCodes.java
new file mode 100644
index 000000000..27187f69f
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/KeyCodes.java
@@ -0,0 +1,127 @@
+package net.pitan76.mcpitanlib.api.client.option;
+
+import org.lwjgl.glfw.GLFW;
+
+public class KeyCodes {
+ public static final int KEY_UNKNOWN = GLFW.GLFW_KEY_UNKNOWN,
+ KEY_SPACE = GLFW.GLFW_KEY_SPACE,
+ KEY_APOSTROPHE = GLFW.GLFW_KEY_APOSTROPHE,
+ KEY_COMMA = GLFW.GLFW_KEY_COMMA,
+ KEY_MINUS = GLFW.GLFW_KEY_MINUS,
+ KEY_PERIOD = GLFW.GLFW_KEY_PERIOD,
+ KEY_SLASH = GLFW.GLFW_KEY_SLASH,
+ KEY_0 = GLFW.GLFW_KEY_0,
+ KEY_1 = GLFW.GLFW_KEY_1,
+ KEY_2 = GLFW.GLFW_KEY_2,
+ KEY_3 = GLFW.GLFW_KEY_3,
+ KEY_4 = GLFW.GLFW_KEY_4,
+ KEY_5 = GLFW.GLFW_KEY_5,
+ KEY_6 = GLFW.GLFW_KEY_6,
+ KEY_7 = GLFW.GLFW_KEY_7,
+ KEY_8 = GLFW.GLFW_KEY_8,
+ KEY_9 = GLFW.GLFW_KEY_9,
+ KEY_SEMICOLON = GLFW.GLFW_KEY_SEMICOLON,
+ KEY_EQUAL = GLFW.GLFW_KEY_EQUAL,
+ KEY_A = GLFW.GLFW_KEY_A,
+ KEY_B = GLFW.GLFW_KEY_B,
+ KEY_C = GLFW.GLFW_KEY_C,
+ KEY_D = GLFW.GLFW_KEY_D,
+ KEY_E = GLFW.GLFW_KEY_E,
+ KEY_F = GLFW.GLFW_KEY_F,
+ KEY_G = GLFW.GLFW_KEY_G,
+ KEY_H = GLFW.GLFW_KEY_H,
+ KEY_I = GLFW.GLFW_KEY_I,
+ KEY_J = GLFW.GLFW_KEY_J,
+ KEY_K = GLFW.GLFW_KEY_K,
+ KEY_L = GLFW.GLFW_KEY_L,
+ KEY_M = GLFW.GLFW_KEY_M,
+ KEY_N = GLFW.GLFW_KEY_N,
+ KEY_O = GLFW.GLFW_KEY_O,
+ KEY_P = GLFW.GLFW_KEY_P,
+ KEY_Q = GLFW.GLFW_KEY_Q,
+ KEY_R = GLFW.GLFW_KEY_R,
+ KEY_S = GLFW.GLFW_KEY_S,
+ KEY_T = GLFW.GLFW_KEY_T,
+ KEY_U = GLFW.GLFW_KEY_U,
+ KEY_V = GLFW.GLFW_KEY_V,
+ KEY_W = GLFW.GLFW_KEY_W,
+ KEY_X = GLFW.GLFW_KEY_X,
+ KEY_Y = GLFW.GLFW_KEY_Y,
+ KEY_Z = GLFW.GLFW_KEY_Z,
+ KEY_LEFT_BRACKET = GLFW.GLFW_KEY_LEFT_BRACKET,
+ KEY_BACKSLASH = GLFW.GLFW_KEY_BACKSLASH,
+ KEY_RIGHT_BRACKET = GLFW.GLFW_KEY_RIGHT_BRACKET,
+ KEY_GRAVE_ACCENT = GLFW.GLFW_KEY_GRAVE_ACCENT,
+ KEY_WORLD_1 = GLFW.GLFW_KEY_WORLD_1,
+ KEY_WORLD_2 = GLFW.GLFW_KEY_WORLD_2,
+ KEY_ESCAPE = GLFW.GLFW_KEY_ESCAPE,
+ KEY_ENTER = GLFW.GLFW_KEY_ENTER,
+ KEY_TAB = GLFW.GLFW_KEY_TAB,
+ KEY_BACKSPACE = GLFW.GLFW_KEY_BACKSPACE,
+ KEY_INSERT = GLFW.GLFW_KEY_INSERT,
+ KEY_DELETE = GLFW.GLFW_KEY_DELETE,
+ KEY_RIGHT = GLFW.GLFW_KEY_RIGHT,
+ KEY_LEFT = GLFW.GLFW_KEY_LEFT,
+ KEY_DOWN = GLFW.GLFW_KEY_DOWN,
+ KEY_UP = GLFW.GLFW_KEY_UP,
+ KEY_PAGE_UP = GLFW.GLFW_KEY_PAGE_UP,
+ KEY_PAGE_DOWN = GLFW.GLFW_KEY_PAGE_DOWN,
+ KEY_HOME = GLFW.GLFW_KEY_HOME,
+ KEY_END = GLFW.GLFW_KEY_END,
+ KEY_CAPS_LOCK = GLFW.GLFW_KEY_CAPS_LOCK,
+ KEY_SCROLL_LOCK = GLFW.GLFW_KEY_SCROLL_LOCK,
+ KEY_NUM_LOCK = GLFW.GLFW_KEY_NUM_LOCK,
+ KEY_PRINT_SCREEN = GLFW.GLFW_KEY_PRINT_SCREEN,
+ KEY_PAUSE = GLFW.GLFW_KEY_PAUSE,
+ KEY_F1 = GLFW.GLFW_KEY_F1,
+ KEY_F2 = GLFW.GLFW_KEY_F2,
+ KEY_F3 = GLFW.GLFW_KEY_F3,
+ KEY_F4 = GLFW.GLFW_KEY_F4,
+ KEY_F5 = GLFW.GLFW_KEY_F5,
+ KEY_F6 = GLFW.GLFW_KEY_F6,
+ KEY_F7 = GLFW.GLFW_KEY_F7,
+ KEY_F8 = GLFW.GLFW_KEY_F8,
+ KEY_F9 = GLFW.GLFW_KEY_F9,
+ KEY_F10 = GLFW.GLFW_KEY_F10,
+ KEY_F11 = GLFW.GLFW_KEY_F11,
+ KEY_F12 = GLFW.GLFW_KEY_F12,
+ KEY_F13 = GLFW.GLFW_KEY_F13,
+ KEY_F14 = GLFW.GLFW_KEY_F14,
+ KEY_F15 = GLFW.GLFW_KEY_F15,
+ KEY_F16 = GLFW.GLFW_KEY_F16,
+ KEY_F17 = GLFW.GLFW_KEY_F17,
+ KEY_F18 = GLFW.GLFW_KEY_F18,
+ KEY_F19 = GLFW.GLFW_KEY_F19,
+ KEY_F20 = GLFW.GLFW_KEY_F20,
+ KEY_F21 = GLFW.GLFW_KEY_F21,
+ KEY_F22 = GLFW.GLFW_KEY_F22,
+ KEY_F23 = GLFW.GLFW_KEY_F23,
+ KEY_F24 = GLFW.GLFW_KEY_F24,
+ KEY_F25 = GLFW.GLFW_KEY_F25,
+ KEY_KP_0 = GLFW.GLFW_KEY_KP_0,
+ KEY_KP_1 = GLFW.GLFW_KEY_KP_1,
+ KEY_KP_2 = GLFW.GLFW_KEY_KP_2,
+ KEY_KP_3 = GLFW.GLFW_KEY_KP_3,
+ KEY_KP_4 = GLFW.GLFW_KEY_KP_4,
+ KEY_KP_5 = GLFW.GLFW_KEY_KP_5,
+ KEY_KP_6 = GLFW.GLFW_KEY_KP_6,
+ KEY_KP_7 = GLFW.GLFW_KEY_KP_7,
+ KEY_KP_8 = GLFW.GLFW_KEY_KP_8,
+ KEY_KP_9 = GLFW.GLFW_KEY_KP_9,
+ KEY_KP_DECIMAL = GLFW.GLFW_KEY_KP_DECIMAL,
+ KEY_KP_DIVIDE = GLFW.GLFW_KEY_KP_DIVIDE,
+ KEY_KP_MULTIPLY = GLFW.GLFW_KEY_KP_MULTIPLY,
+ KEY_KP_SUBTRACT = GLFW.GLFW_KEY_KP_SUBTRACT,
+ KEY_KP_ADD = GLFW.GLFW_KEY_KP_ADD,
+ KEY_KP_ENTER = GLFW.GLFW_KEY_KP_ENTER,
+ KEY_KP_EQUAL = GLFW.GLFW_KEY_KP_EQUAL,
+ KEY_LEFT_SHIFT = GLFW.GLFW_KEY_LEFT_SHIFT,
+ KEY_LEFT_CONTROL = GLFW.GLFW_KEY_LEFT_CONTROL,
+ KEY_LEFT_ALT = GLFW.GLFW_KEY_LEFT_ALT,
+ KEY_LEFT_SUPER = GLFW.GLFW_KEY_LEFT_SUPER,
+ KEY_RIGHT_SHIFT = GLFW.GLFW_KEY_RIGHT_SHIFT,
+ KEY_RIGHT_CONTROL = GLFW.GLFW_KEY_RIGHT_CONTROL,
+ KEY_RIGHT_ALT = GLFW.GLFW_KEY_RIGHT_ALT,
+ KEY_RIGHT_SUPER = GLFW.GLFW_KEY_RIGHT_SUPER,
+ KEY_MENU = GLFW.GLFW_KEY_MENU;
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/ArchRegistryClient.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/ArchRegistryClient.java
new file mode 100644
index 000000000..89a0facf0
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/ArchRegistryClient.java
@@ -0,0 +1,180 @@
+package net.pitan76.mcpitanlib.api.client.registry;
+
+import dev.architectury.registry.client.level.entity.EntityRendererRegistry;
+import dev.architectury.registry.client.particle.ParticleProviderRegistry;
+import dev.architectury.registry.client.rendering.BlockEntityRendererRegistry;
+import dev.architectury.registry.client.rendering.RenderTypeRegistry;
+import dev.architectury.registry.menu.MenuRegistry;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.block.Block;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.block.entity.BlockEntityType;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
+import net.minecraft.client.model.ModelPart;
+import net.minecraft.client.particle.ParticleFactory;
+import net.minecraft.client.particle.SpriteProvider;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.block.BlockRenderManager;
+import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
+import net.minecraft.client.render.block.entity.BlockEntityRenderer;
+import net.minecraft.client.render.entity.EntityRenderDispatcher;
+import net.minecraft.client.render.entity.EntityRendererFactory;
+import net.minecraft.client.render.entity.model.EntityModelLayer;
+import net.minecraft.client.render.entity.model.EntityModelLoader;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.client.texture.Sprite;
+import net.minecraft.client.texture.SpriteAtlasTexture;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.particle.ParticleEffect;
+import net.minecraft.particle.ParticleType;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.screen.ScreenHandlerType;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.random.Random;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+@Deprecated
+@Environment(EnvType.CLIENT)
+public class ArchRegistryClient {
+ public static > void registerScreen(ScreenHandlerType extends H> type, ScreenFactory factory) {
+ MenuRegistry.registerScreenFactory(type, factory::create);
+ }
+
+ public interface ScreenFactory> {
+ S create(H handler, PlayerInventory inventory, Text text);
+ }
+
+ public static void registerParticle(ParticleType type, ParticleFactory factory) {
+ ParticleProviderRegistry.register(type, factory);
+ }
+
+ public static void registerParticle(ParticleType type, DeferredParticleProvider provider) {
+ ParticleProviderRegistry.register(type, spriteSet -> provider.create(new ExtendedSpriteSet() {
+ @Override
+ public SpriteAtlasTexture getAtlas() {
+ return spriteSet.getAtlas();
+ }
+
+ @Override
+ public List getSprites() {
+ return spriteSet.getSprites();
+ }
+
+ @Override
+ public Sprite getSprite(int age, int maxAge) {
+ return spriteSet.getSprite(age, maxAge);
+ }
+
+ @Override
+ public Sprite getSprite(Random random) {
+ return spriteSet.getSprite(random);
+ }
+ }));
+ }
+
+ public static void registerEntityRenderer(Supplier extends EntityType extends T>> type, EntityRendererFactory provider) {
+ EntityRendererRegistry.register(type, provider);
+ }
+
+ @FunctionalInterface
+ public interface DeferredParticleProvider {
+ ParticleFactory create(ExtendedSpriteSet spriteSet);
+ }
+
+ public interface ExtendedSpriteSet extends SpriteProvider {
+ SpriteAtlasTexture getAtlas();
+
+ List getSprites();
+ }
+
+ public static void registryClientSpriteAtlasTexture(Identifier identifier) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, identifier);
+ }
+
+ public static void registryClientSpriteAtlasTexture(Sprite sprite) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, sprite);
+ }
+
+ public static void registryClientSprite(Identifier atlasId, Identifier identifier) {
+ // ~1.19.2
+ }
+
+ public static void registryClientSprite(Identifier atlasId, Sprite sprite) {
+ // ~1.19.2
+ }
+
+ public static void registerBlockEntityRenderer(BlockEntityType type, BlockEntityRendererFactory provider) {
+ BlockEntityRendererRegistry.register(type, ctx -> provider.create(new BlockEntityRendererFactory.Context(
+ ctx.getRenderDispatcher(), ctx.getRenderManager(), ctx.getItemRenderer(), ctx.getEntityRenderDispatcher(), ctx.getLayerRenderDispatcher(), ctx.getTextRenderer()
+ )));
+ }
+
+ @FunctionalInterface
+ public interface BlockEntityRendererFactory {
+ BlockEntityRenderer create(BlockEntityRendererFactory.Context ctx);
+
+ class Context {
+ private final BlockEntityRenderDispatcher renderDispatcher;
+ private final BlockRenderManager renderManager;
+ private final ItemRenderer itemRenderer;
+ private final EntityRenderDispatcher entityRenderDispatcher;
+ private final EntityModelLoader layerRenderDispatcher;
+ private final TextRenderer textRenderer;
+
+ public Context(BlockEntityRenderDispatcher renderDispatcher, BlockRenderManager renderManager, ItemRenderer itemRenderer, EntityRenderDispatcher entityRenderDispatcher, EntityModelLoader layerRenderDispatcher, TextRenderer textRenderer) {
+ this.renderDispatcher = renderDispatcher;
+ this.renderManager = renderManager;
+ this.itemRenderer = itemRenderer;
+ this.entityRenderDispatcher = entityRenderDispatcher;
+ this.layerRenderDispatcher = layerRenderDispatcher;
+ this.textRenderer = textRenderer;
+ }
+
+ public BlockEntityRenderDispatcher getRenderDispatcher() {
+ return this.renderDispatcher;
+ }
+
+ public BlockRenderManager getRenderManager() {
+ return this.renderManager;
+ }
+
+ public EntityRenderDispatcher getEntityRenderDispatcher() {
+ return this.entityRenderDispatcher;
+ }
+
+ public ItemRenderer getItemRenderer() {
+ return this.itemRenderer;
+ }
+
+ public EntityModelLoader getLayerRenderDispatcher() {
+ return this.layerRenderDispatcher;
+ }
+
+ public ModelPart getLayerModelPart(EntityModelLayer modelLayer) {
+ return this.layerRenderDispatcher.getModelPart(modelLayer);
+ }
+
+ public TextRenderer getTextRenderer() {
+ return this.textRenderer;
+ }
+ }
+ }
+
+
+ public static void registerRenderTypeBlock(RenderLayer layer, Block block) {
+ RenderTypeRegistry.register(layer, block);
+ }
+
+ public static void registerRenderTypeFluid(RenderLayer layer, Fluid fluid) {
+ RenderTypeRegistry.register(layer, fluid);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/CompatRegistryClient.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/CompatRegistryClient.java
new file mode 100644
index 000000000..4925199d1
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/CompatRegistryClient.java
@@ -0,0 +1,222 @@
+package net.pitan76.mcpitanlib.api.client.registry;
+
+import dev.architectury.injectables.annotations.ExpectPlatform;
+import dev.architectury.registry.client.level.entity.EntityModelLayerRegistry;
+import dev.architectury.registry.client.level.entity.EntityRendererRegistry;
+import dev.architectury.registry.client.particle.ParticleProviderRegistry;
+import dev.architectury.registry.client.rendering.BlockEntityRendererRegistry;
+import dev.architectury.registry.client.rendering.RenderTypeRegistry;
+import dev.architectury.registry.menu.MenuRegistry;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.block.Block;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.block.entity.BlockEntityType;
+import net.minecraft.client.color.block.BlockColorProvider;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
+import net.minecraft.client.model.ModelPart;
+import net.minecraft.client.model.TexturedModelData;
+import net.minecraft.client.particle.ParticleFactory;
+import net.minecraft.client.particle.SpriteProvider;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.block.BlockRenderManager;
+import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
+import net.minecraft.client.render.block.entity.BlockEntityRenderer;
+import net.minecraft.client.render.entity.EntityRenderDispatcher;
+import net.minecraft.client.render.entity.EntityRendererFactory;
+import net.minecraft.client.render.entity.model.EntityModelLayer;
+import net.minecraft.client.render.entity.model.EntityModelLoader;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.client.texture.Sprite;
+import net.minecraft.client.texture.SpriteAtlasTexture;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.particle.ParticleEffect;
+import net.minecraft.particle.ParticleType;
+import net.minecraft.screen.ScreenHandler;
+import net.minecraft.screen.ScreenHandlerType;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.random.Random;
+import net.pitan76.mcpitanlib.MCPitanLib;
+import net.pitan76.mcpitanlib.api.client.color.CompatBlockColorProvider;
+import net.pitan76.mcpitanlib.api.client.render.CompatRenderLayer;
+import net.pitan76.mcpitanlib.api.client.render.EntityModelLayerContext;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+@Environment(EnvType.CLIENT)
+public class CompatRegistryClient {
+ public static > void registerScreen(ScreenHandlerType extends H> type, ScreenFactory factory) {
+ registerScreen(MCPitanLib.MOD_ID, type, factory);
+ }
+
+ public static > void registerScreen(String modId, ScreenHandlerType extends H> type, ScreenFactory factory) {
+ MenuRegistry.registerScreenFactory(type, factory::create);
+ }
+
+ public interface ScreenFactory> {
+ S create(H handler, PlayerInventory inventory, Text text);
+ }
+
+ public static void registerParticle(ParticleType type, ParticleFactory factory) {
+ ParticleProviderRegistry.register(type, factory);
+ }
+
+ public static void registerParticle(ParticleType type, DeferredParticleProvider provider) {
+ ParticleProviderRegistry.register(type, spriteSet -> provider.create(new ExtendedSpriteSet() {
+ @Override
+ public SpriteAtlasTexture getAtlas() {
+ return spriteSet.getAtlas();
+ }
+
+ @Override
+ public List getSprites() {
+ return spriteSet.getSprites();
+ }
+
+ @Override
+ public Sprite getSprite(int age, int maxAge) {
+ return spriteSet.getSprite(age, maxAge);
+ }
+
+ @Override
+ public Sprite getSprite(Random random) {
+ return spriteSet.getSprite(random);
+ }
+ }));
+ }
+
+ public static void registerEntityModelLayer(EntityModelLayer layer, EntityModelLayerContext context) {
+ EntityModelLayerRegistry.register(layer, () -> TexturedModelData.of(context.getData(), context.getWidth(), context.getHeight()));
+ }
+
+ public static void registerEntityRenderer(Supplier extends EntityType extends T>> type, EntityRendererFactory provider) {
+ EntityRendererRegistry.register(type, provider);
+ }
+
+ @FunctionalInterface
+ public interface DeferredParticleProvider {
+ ParticleFactory create(ExtendedSpriteSet spriteSet);
+ }
+
+ public interface ExtendedSpriteSet extends SpriteProvider {
+ SpriteAtlasTexture getAtlas();
+
+ List getSprites();
+ }
+
+ public static void registryClientSpriteAtlasTexture(Identifier identifier) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, identifier);
+ }
+
+ public static void registryClientSpriteAtlasTexture(Sprite sprite) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, sprite);
+ }
+
+ public static void registryClientSprite(Identifier atlasId, Identifier identifier) {
+ // ~1.19.2
+ }
+
+ public static void registryClientSprite(Identifier atlasId, Sprite sprite) {
+ // ~1.19.2
+ }
+
+ public static void registerBlockEntityRenderer(BlockEntityType type, BlockEntityRendererFactory provider) {
+ BlockEntityRendererRegistry.register(type, ctx -> provider.create(new BlockEntityRendererFactory.Context(
+ ctx.getRenderDispatcher(), ctx.getRenderManager(), ctx.getItemRenderer(), ctx.getEntityRenderDispatcher(), ctx.getLayerRenderDispatcher(), ctx.getTextRenderer()
+ )));
+ }
+
+ @FunctionalInterface
+ public interface BlockEntityRendererFactory {
+ BlockEntityRenderer create(Context ctx);
+
+ class Context {
+ private final BlockEntityRenderDispatcher renderDispatcher;
+ private final BlockRenderManager renderManager;
+ private final ItemRenderer itemRenderer;
+ private final EntityRenderDispatcher entityRenderDispatcher;
+ private final EntityModelLoader layerRenderDispatcher;
+ private final TextRenderer textRenderer;
+
+ public Context(BlockEntityRenderDispatcher renderDispatcher, BlockRenderManager renderManager, ItemRenderer itemRenderer, EntityRenderDispatcher entityRenderDispatcher, EntityModelLoader layerRenderDispatcher, TextRenderer textRenderer) {
+ this.renderDispatcher = renderDispatcher;
+ this.renderManager = renderManager;
+ this.itemRenderer = itemRenderer;
+ this.entityRenderDispatcher = entityRenderDispatcher;
+ this.layerRenderDispatcher = layerRenderDispatcher;
+ this.textRenderer = textRenderer;
+ }
+
+ public BlockEntityRenderDispatcher getRenderDispatcher() {
+ return this.renderDispatcher;
+ }
+
+ public BlockRenderManager getRenderManager() {
+ return this.renderManager;
+ }
+
+ public EntityRenderDispatcher getEntityRenderDispatcher() {
+ return this.entityRenderDispatcher;
+ }
+
+ public ItemRenderer getItemRenderer() {
+ return this.itemRenderer;
+ }
+
+ public EntityModelLoader getLayerRenderDispatcher() {
+ return this.layerRenderDispatcher;
+ }
+
+ public ModelPart getLayerModelPart(EntityModelLayer modelLayer) {
+ return this.layerRenderDispatcher.getModelPart(modelLayer);
+ }
+
+ public TextRenderer getTextRenderer() {
+ return this.textRenderer;
+ }
+ }
+ }
+
+
+ public static void registerRenderTypeBlock(RenderLayer layer, Block block) {
+ RenderTypeRegistry.register(layer, block);
+ }
+
+ public static void registerRenderTypeFluid(RenderLayer layer, Fluid fluid) {
+ RenderTypeRegistry.register(layer, fluid);
+ }
+
+ public static void registerCutoutBlock(Block block) {
+ registerRenderTypeBlock(RenderLayer.getCutout(), block);
+ }
+
+ public static void registerCompatBlockEntityRenderer(BlockEntityType type, BlockEntityRendererFactory provider) {
+ BlockEntityRendererRegistry.register(type, ctx -> provider.create(new BlockEntityRendererFactory.Context(
+ ctx.getRenderDispatcher(), ctx.getRenderManager(), ctx.getItemRenderer(), ctx.getEntityRenderDispatcher(), ctx.getLayerRenderDispatcher(), ctx.getTextRenderer()
+ )));
+ }
+
+ public static void registerRenderTypeBlock(CompatRenderLayer layer, Block block) {
+ registerRenderTypeBlock(layer.layer, block);
+ }
+
+ public static void registerRenderTypeFluid(CompatRenderLayer layer, Fluid fluid) {
+ registerRenderTypeFluid(layer.layer, fluid);
+ }
+
+ @ExpectPlatform
+ public static void registerColorProviderBlock(BlockColorProvider provider, Block... blocks) {
+ throw new AssertionError("This method should be replaced by the platform implementation");
+ }
+
+ public static void registerColorProviderBlock(CompatBlockColorProvider provider, Block... blocks) {
+ registerColorProviderBlock((BlockColorProvider) provider, blocks);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/EntityRendererRegistry.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/EntityRendererRegistry.java
new file mode 100644
index 000000000..7fa99982f
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/EntityRendererRegistry.java
@@ -0,0 +1,13 @@
+package net.pitan76.mcpitanlib.api.client.registry;
+
+import net.minecraft.client.render.entity.EntityRenderer;
+import net.minecraft.client.render.entity.FlyingItemEntityRenderer;
+import net.minecraft.entity.EntityType;
+
+import java.util.function.Supplier;
+
+public class EntityRendererRegistry {
+ public static void registerEntityRendererAsFlyingItem(Supplier> entityType) {
+ CompatRegistryClient.registerEntityRenderer(entityType, (ctx -> (EntityRenderer) new FlyingItemEntityRenderer<>(ctx)));
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/KeybindingRegistry.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/KeybindingRegistry.java
new file mode 100644
index 000000000..771f39bc4
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/KeybindingRegistry.java
@@ -0,0 +1,38 @@
+package net.pitan76.mcpitanlib.api.client.registry;
+
+import dev.architectury.registry.client.keymappings.KeyMappingRegistry;
+import net.minecraft.client.option.KeyBinding;
+import net.minecraft.util.Identifier;
+import net.pitan76.mcpitanlib.api.event.v0.ClientTickEventRegistry;
+import net.pitan76.mcpitanlib.api.network.ClientNetworking;
+import net.pitan76.mcpitanlib.api.network.PacketByteUtil;
+
+public class KeybindingRegistry {
+ public static void register(KeyBinding keyBinding) {
+ KeyMappingRegistry.register(keyBinding);
+ }
+
+ public static void register(KeyBinding keyBinding, ClientTickEventRegistry.Client client) {
+ register(keyBinding);
+ ClientTickEventRegistry.registerPost(client);
+ }
+
+ public static void registerOnLevel(KeyBinding keyBinding, ClientTickEventRegistry.ClientLevel level) {
+ register(keyBinding);
+ ClientTickEventRegistry.registerLevelPost(level);
+ }
+
+ public static void registerWithNetwork(KeyBinding keyBinding, Identifier identifier) {
+ register(keyBinding, client -> {
+ if (keyBinding.wasPressed())
+ ClientNetworking.send(identifier, PacketByteUtil.create());
+ });
+ }
+
+ public static void registerOnLevelWithNetwork(KeyBinding keyBinding, Identifier identifier) {
+ registerOnLevel(keyBinding, client -> {
+ if (keyBinding.wasPressed())
+ ClientNetworking.send(identifier, PacketByteUtil.create());
+ });
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/v2/KeybindingRegistry.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/v2/KeybindingRegistry.java
new file mode 100644
index 000000000..80a026101
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/v2/KeybindingRegistry.java
@@ -0,0 +1,23 @@
+package net.pitan76.mcpitanlib.api.client.registry.v2;
+
+import net.minecraft.client.option.KeyBinding;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+public class KeybindingRegistry extends net.pitan76.mcpitanlib.api.client.registry.KeybindingRegistry {
+
+ public static void registerWithNetwork(KeyBinding keyBinding, CompatIdentifier identifier) {
+ registerWithNetwork(keyBinding, identifier.toMinecraft());
+ }
+
+ public static void registerOnLevelWithNetwork(KeyBinding keyBinding, CompatIdentifier identifier) {
+ registerOnLevelWithNetwork(keyBinding, identifier.toMinecraft());
+ }
+
+ public static void registerWithNetwork(String translationKey, int code, String category, CompatIdentifier identifier) {
+ registerWithNetwork(new KeyBinding(translationKey, code, category), identifier);
+ }
+
+ public static void registerOnLevelWithNetwork(String translationKey, int code, String category, CompatIdentifier identifier) {
+ registerOnLevelWithNetwork(new KeyBinding(translationKey, code, category), identifier);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/v3/KeybindingRegistry.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/v3/KeybindingRegistry.java
new file mode 100644
index 000000000..91f382b28
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/v3/KeybindingRegistry.java
@@ -0,0 +1,37 @@
+package net.pitan76.mcpitanlib.api.client.registry.v3;
+
+import net.pitan76.mcpitanlib.api.client.option.CompatKeyBinding;
+import net.pitan76.mcpitanlib.api.event.v0.ClientTickEventRegistry;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+public class KeybindingRegistry {
+ public static void registerWithNetwork(CompatKeyBinding keyBinding, CompatIdentifier networkId) {
+ net.pitan76.mcpitanlib.api.client.registry.v2.KeybindingRegistry.registerWithNetwork(keyBinding.toMinecraft(), networkId.toMinecraft());
+ }
+
+ public static void registerOnLevelWithNetwork(CompatKeyBinding keyBinding, CompatIdentifier networkId) {
+ net.pitan76.mcpitanlib.api.client.registry.v2.KeybindingRegistry.registerOnLevelWithNetwork(keyBinding.toMinecraft(), networkId.toMinecraft());
+ }
+
+ public static void registerWithNetwork(String translationKey, int code, CompatIdentifier category, CompatIdentifier networkId) {
+ registerWithNetwork(CompatKeyBinding.of(translationKey, code, category), networkId);
+ }
+
+ public static void registerOnLevelWithNetwork(String translationKey, int code, CompatIdentifier category, CompatIdentifier networkId) {
+ registerOnLevelWithNetwork(CompatKeyBinding.of(translationKey, code, category), networkId);
+ }
+
+ public static void register(CompatKeyBinding keyBinding) {
+ net.pitan76.mcpitanlib.api.client.registry.KeybindingRegistry.register(keyBinding.toMinecraft());
+ }
+
+ public static void register(CompatKeyBinding keyBinding, ClientTickEventRegistry.Client client) {
+ register(keyBinding);
+ ClientTickEventRegistry.registerPost(client);
+ }
+
+ public static void registerOnLevel(CompatKeyBinding keyBinding, ClientTickEventRegistry.ClientLevel level) {
+ register(keyBinding);
+ ClientTickEventRegistry.registerLevelPost(level);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatRenderLayer.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatRenderLayer.java
new file mode 100644
index 000000000..69c3fc968
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatRenderLayer.java
@@ -0,0 +1,45 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.minecraft.client.render.RenderLayer;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+public class CompatRenderLayer {
+ public static final CompatRenderLayer CUTOUT = new CompatRenderLayer(RenderLayer.getCutout());
+ public static final CompatRenderLayer CUTOUT_MIPPED = new CompatRenderLayer(RenderLayer.getCutoutMipped());
+ public static final CompatRenderLayer TRANSLUCENT = new CompatRenderLayer(RenderLayer.getTranslucent());
+ public static final CompatRenderLayer TRANSLUCENT_MOVING_BLOCK = new CompatRenderLayer(RenderLayer.getTranslucentMovingBlock());
+ public static final CompatRenderLayer SOLID = new CompatRenderLayer(RenderLayer.getSolid());
+ public static final CompatRenderLayer LINES = new CompatRenderLayer(RenderLayer.getLines());
+ public static final CompatRenderLayer LINE_STRIP = new CompatRenderLayer(RenderLayer.getLineStrip());
+ public static final CompatRenderLayer GLINT = new CompatRenderLayer(RenderLayer.getGlint());
+
+ public final RenderLayer layer;
+
+ public CompatRenderLayer(RenderLayer layer) {
+ this.layer = layer;
+ }
+
+ public RenderLayer raw() {
+ return layer;
+ }
+
+ public static CompatRenderLayer getEntityCutout(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderLayer.getEntityCutout(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getEntityCutoutNoCull(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderLayer.getEntityCutoutNoCull(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getEntityTranslucent(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderLayer.getEntityTranslucent(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getArmorCutoutNoCull(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderLayer.getArmorCutoutNoCull(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getEntitySolid(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderLayer.getEntitySolid(id.toMinecraft()));
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/DrawObjectDM.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/DrawObjectDM.java
new file mode 100644
index 000000000..7f449b306
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/DrawObjectDM.java
@@ -0,0 +1,94 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
+import net.pitan76.mcpitanlib.api.text.TextComponent;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.client.ScreenUtil.RendererUtil;
+
+public class DrawObjectDM {
+ private MatrixStack stack;
+ private DrawContext context;
+
+ private Screen screen = null;
+
+ public DrawObjectDM(DrawContext context) {
+ this.context = context;
+ this.stack = context.getMatrices();
+ }
+
+ public DrawObjectDM(MatrixStack stack) {
+ this.stack = stack;
+ }
+
+ public DrawObjectDM(DrawContext context, Screen screen) {
+ this(context);
+ this.screen = screen;
+ }
+
+ public DrawContext getContext() {
+ return context;
+ }
+
+ public MatrixStack getStack() {
+ return stack;
+ }
+
+ public Screen getScreen() {
+ return screen;
+ }
+
+ public void setContext(DrawContext context) {
+ this.context = context;
+ }
+
+ public void setStack(MatrixStack stack) {
+ this.stack = stack;
+ }
+
+ public void setScreen(Screen screen) {
+ this.screen = screen;
+ }
+
+ public boolean hasScreen() {
+ return screen != null;
+ }
+
+ public void drawTexture(CompatIdentifier texture, int x, int y, float u, float v, int width, int height) {
+ RendererUtil.drawTexture(this, texture, x, y, u, v, width, height);
+ }
+
+ public void drawTexture(CompatIdentifier texture, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight) {
+ RendererUtil.drawTexture(this, texture, x, y, u, v, width, height, textureWidth, textureHeight);
+ }
+
+ public void drawText(Text text, int x, int y) {
+ RendererUtil.drawText(RendererUtil.getTextRenderer(), this, text, x, y);
+ }
+
+ public void drawTooltip(Text text, int x, int y) {
+ RendererUtil.drawTooltip(this, text, x, y);
+ }
+
+ public void drawText(TextComponent text, int x, int y) {
+ RendererUtil.drawText(RendererUtil.getTextRenderer(), this, text, x, y);
+ }
+
+ public void drawTooltip(TextComponent text, int x, int y) {
+ RendererUtil.drawTooltip(this, text, x, y);
+ }
+
+ public void drawBorder(int x, int y, int width, int height, int color) {
+ RendererUtil.drawBorder(this, x, y, width, height, color);
+ }
+
+ public int getWidth() {
+ return hasScreen() ? screen.width : -1;
+ }
+
+ public int getHeight() {
+ return hasScreen() ? screen.height : -1;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/DrawObjectMV.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/DrawObjectMV.java
new file mode 100644
index 000000000..37e2df47d
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/DrawObjectMV.java
@@ -0,0 +1,119 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.minecraft.client.render.OverlayTexture;
+import net.minecraft.client.render.VertexConsumer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.pitan76.mcpitanlib.api.util.client.render.VertexConsumerUtil;
+import org.joml.Matrix3f;
+import org.joml.Matrix4f;
+
+public class DrawObjectMV {
+ private final MatrixStack stack;
+ private final VertexConsumer buffer;
+
+ public DrawObjectMV(MatrixStack stack, VertexConsumer buffer) {
+ this.stack = stack;
+ this.buffer = buffer;
+ }
+
+ public DrawObjectMV(MatrixStack stack) {
+ this(stack, null);
+ }
+
+ public DrawObjectMV(VertexConsumer buffer) {
+ this(null, buffer);
+ }
+
+ public MatrixStack getStack() {
+ return stack;
+ }
+
+ public VertexConsumer getBuffer() {
+ return buffer;
+ }
+
+ public DrawObjectMV vertex(float x, float y, float z) {
+ return VertexConsumerUtil.vertex(this, x, y, z);
+ }
+
+ public DrawObjectMV normal(float x, float y, float z) {
+ return VertexConsumerUtil.normal(this, x, y, z);
+ }
+
+ public DrawObjectMV color(float red, float green, float blue, float alpha) {
+ return VertexConsumerUtil.color(this, red, green, blue, alpha);
+ }
+
+ public DrawObjectMV color(int red, int green, int blue, int alpha) {
+ return VertexConsumerUtil.color(this, red, green, blue, alpha);
+ }
+
+ public DrawObjectMV colorARGB(int argb) {
+ return VertexConsumerUtil.colorARGB(this, argb);
+ }
+
+ public DrawObjectMV colorRGB(int rgb) {
+ return VertexConsumerUtil.colorRGB(this, rgb);
+ }
+
+ public DrawObjectMV light(int light) {
+ return VertexConsumerUtil.light(this, light);
+ }
+
+ public DrawObjectMV overlay(int overlay) {
+ return VertexConsumerUtil.overlay(this, overlay);
+ }
+
+ public DrawObjectMV overlayDefaultUV() {
+ return VertexConsumerUtil.overlayDefaultUV(this);
+ }
+
+ public Matrix4f matrix4f;
+ public Matrix3f matrix3f;
+
+ public Matrix4f getMatrix4f() {
+ if (matrix4f == null)
+ matrix4f = stack.peek().getPositionMatrix();
+
+ return matrix4f;
+ }
+
+ public Matrix3f getMatrix3f() {
+ if (matrix3f == null)
+ matrix3f = stack.peek().getNormalMatrix();
+
+ return matrix3f;
+ }
+
+ public DrawObjectMV vertexWithMatrix4f(float x, float y, float z) {
+ VertexConsumerUtil.vertex(buffer, getMatrix4f(), x, y, z);
+ return this;
+ }
+
+ public DrawObjectMV vertexWithMatrix(float x, float y, float z) {
+ VertexConsumerUtil.vertex(buffer, stack, x, y, z);
+ return this;
+ }
+
+ public DrawObjectMV normalWithMatrix(float x, float y, float z) {
+ VertexConsumerUtil.normal(buffer, stack, x, y, z);
+ return this;
+ }
+
+ public DrawObjectMV texture(float u, float v) {
+ VertexConsumerUtil.texture(buffer, u, v);
+ return this;
+ }
+
+ public DrawObjectMV next() {
+ VertexConsumerUtil.next(buffer);
+ return this;
+ }
+
+ public void renderQuad(float x1, float y1, float z1, float x2, float y2, float z2,
+ float normalX, float normalY, float normalZ, int r, int g, int b, int alpha, int u, int v, int overlay, int light) {
+ VertexConsumerUtil.renderQuad(buffer, stack, getMatrix4f(), getMatrix3f(),
+ x1, y1, z1, x2, y2, z2,
+ normalX, normalY, normalZ, r, g, b, alpha, u, v, overlay, light);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/EntityModelLayerContext.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/EntityModelLayerContext.java
new file mode 100644
index 000000000..d1d343924
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/EntityModelLayerContext.java
@@ -0,0 +1,27 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.minecraft.client.model.ModelData;
+
+public class EntityModelLayerContext {
+ private final ModelData data;
+ private final int width;
+ private final int height;
+
+ public EntityModelLayerContext(ModelData data, int width, int height) {
+ this.data = data;
+ this.width = width;
+ this.height = height;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public ModelData getData() {
+ return data;
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/CompatBlockEntityRenderer.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/CompatBlockEntityRenderer.java
new file mode 100644
index 000000000..0db5cb14c
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/CompatBlockEntityRenderer.java
@@ -0,0 +1,37 @@
+package net.pitan76.mcpitanlib.api.client.render.block.entity;
+
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.block.entity.BlockEntityRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.pitan76.mcpitanlib.api.client.render.block.entity.event.BlockEntityRenderEvent;
+import net.pitan76.mcpitanlib.api.tile.CompatBlockEntity;
+
+@Deprecated
+public interface CompatBlockEntityRenderer extends BlockEntityRenderer {
+ void render(BlockEntityRenderEvent event);
+
+ @Override
+ default void render(T entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
+ render(new BlockEntityRenderEvent<>(this, entity, tickDelta, matrices, vertexConsumers, light, overlay));
+ }
+
+ default boolean rendersOutsideBoundingBoxOverride(T blockEntity) {
+ return BlockEntityRenderer.super.rendersOutsideBoundingBox(blockEntity);
+ }
+
+ default int getRenderDistanceOverride() {
+ return BlockEntityRenderer.super.getRenderDistance();
+ }
+
+ @Deprecated
+ @Override
+ default boolean rendersOutsideBoundingBox(T blockEntity) {
+ return rendersOutsideBoundingBoxOverride(blockEntity);
+ }
+
+ @Deprecated
+ @Override
+ default int getRenderDistance() {
+ return getRenderDistanceOverride();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/event/BlockEntityRenderEvent.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/event/BlockEntityRenderEvent.java
new file mode 100644
index 000000000..2d655398c
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/event/BlockEntityRenderEvent.java
@@ -0,0 +1,143 @@
+package net.pitan76.mcpitanlib.api.client.render.block.entity.event;
+
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.VertexConsumer;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.math.BlockPos;
+import net.pitan76.mcpitanlib.api.client.registry.CompatRegistryClient;
+import net.pitan76.mcpitanlib.api.client.render.CompatRenderLayer;
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectMV;
+import net.pitan76.mcpitanlib.api.client.render.block.entity.CompatBlockEntityRenderer;
+import net.pitan76.mcpitanlib.api.tile.CompatBlockEntity;
+import net.pitan76.mcpitanlib.api.util.MathUtil;
+import net.pitan76.mcpitanlib.api.util.client.ClientUtil;
+import net.pitan76.mcpitanlib.api.util.client.MatrixStackUtil;
+import net.pitan76.mcpitanlib.api.util.client.render.CompatItemRenderUtil;
+import org.joml.Matrix3f;
+import org.joml.Matrix4f;
+
+public class BlockEntityRenderEvent {
+ public T blockEntity;
+ public float tickDelta;
+ public MatrixStack matrices;
+ public VertexConsumerProvider vertexConsumers;
+ int light;
+ int overlay;
+
+ public BlockEntityRenderEvent(T blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
+ this.blockEntity = blockEntity;
+ this.tickDelta = tickDelta;
+ this.matrices = matrices;
+ this.vertexConsumers = vertexConsumers;
+ this.light = light;
+ this.overlay = overlay;
+ }
+
+ public T getBlockEntity() {
+ return blockEntity;
+ }
+
+ public MatrixStack getMatrices() {
+ return matrices;
+ }
+
+ public float getTickDelta() {
+ return tickDelta;
+ }
+
+ public int getLight() {
+ return light;
+ }
+
+ public int getOverlay() {
+ return overlay;
+ }
+
+ public VertexConsumer getVertexConsumer(RenderLayer layer) {
+ return vertexConsumers.getBuffer(layer);
+ }
+
+ public VertexConsumer getVertexConsumer(CompatRenderLayer layer) {
+ return getVertexConsumer(layer.raw());
+ }
+
+ public VertexConsumerProvider getVertexConsumers() {
+ return vertexConsumers;
+ }
+
+ public void push() {
+ MatrixStackUtil.push(matrices);
+ }
+
+ public void translate(double x, double y, double z) {
+ MatrixStackUtil.translate(matrices, x, y, z);
+ }
+
+ public void pop() {
+ MatrixStackUtil.pop(matrices);
+ }
+
+ public void multiply(MathUtil.RotationAxisType type, float deg) {
+ MatrixStackUtil.multiply(matrices, type, deg);
+ }
+
+ public void scale(float x, float y, float z) {
+ MatrixStackUtil.scale(matrices, x, y, z);
+ }
+
+ public ItemRenderer getItemRenderer() {
+ return ClientUtil.getItemRenderer();
+ }
+
+ public boolean isRemoved() {
+ return blockEntity.isRemoved();
+ }
+
+ public DrawObjectMV getDrawObject(CompatRenderLayer layer) {
+ return new DrawObjectMV(getMatrices(), getVertexConsumer(layer));
+ }
+
+ public Matrix4f matrix4f;
+ public Matrix3f matrix3f;
+
+ public Matrix4f getMatrix4f() {
+ if (matrix4f == null)
+ matrix4f = matrices.peek().getPositionMatrix();
+
+ return matrix4f;
+ }
+
+ public Matrix3f getMatrix3f() {
+ if (matrix3f == null)
+ matrix3f = matrices.peek().getNormalMatrix();
+
+ return matrix3f;
+ }
+
+ public BlockPos getPos() {
+ return blockEntity.callGetPos();
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.BlockPos getMidohraPos() {
+ return net.pitan76.mcpitanlib.midohra.util.math.BlockPos.of(getPos());
+ }
+
+ //----
+
+ @Deprecated
+ public CompatRegistryClient.BlockEntityRendererFactory.Context ctx;
+
+ public BlockEntityRenderEvent(CompatBlockEntityRenderer renderer, T blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
+ this(blockEntity, tickDelta, matrices, vertexConsumers, light, overlay);
+ if (renderer instanceof net.pitan76.mcpitanlib.api.client.render.block.entity.v2.CompatBlockEntityRenderer>) {
+ this.ctx = ((net.pitan76.mcpitanlib.api.client.render.block.entity.v2.CompatBlockEntityRenderer>) renderer).ctx;
+ }
+ }
+
+ public void renderItemFixed(ItemStack stack) {
+ CompatItemRenderUtil.renderItemFixed(stack, this, blockEntity.callGetWorld());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/event/CompatBlockEntityRendererConstructArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/event/CompatBlockEntityRendererConstructArgs.java
new file mode 100644
index 000000000..d0dc58e39
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/event/CompatBlockEntityRendererConstructArgs.java
@@ -0,0 +1,16 @@
+package net.pitan76.mcpitanlib.api.client.render.block.entity.event;
+
+import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
+import net.pitan76.mcpitanlib.api.util.client.ClientUtil;
+
+public class CompatBlockEntityRendererConstructArgs {
+ public final BlockEntityRenderDispatcher dispatcher;
+
+ public CompatBlockEntityRendererConstructArgs(BlockEntityRenderDispatcher dispatcher) {
+ this.dispatcher = dispatcher;
+ }
+
+ public CompatBlockEntityRendererConstructArgs() {
+ this(ClientUtil.getClient().getBlockEntityRenderDispatcher());
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/v2/CompatBlockEntityRenderer.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/v2/CompatBlockEntityRenderer.java
new file mode 100644
index 000000000..2d3b4f911
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/v2/CompatBlockEntityRenderer.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.client.render.block.entity.v2;
+
+import net.pitan76.mcpitanlib.api.client.registry.CompatRegistryClient;
+import net.pitan76.mcpitanlib.api.client.render.block.entity.event.CompatBlockEntityRendererConstructArgs;
+import net.pitan76.mcpitanlib.api.tile.CompatBlockEntity;
+
+public abstract class CompatBlockEntityRenderer implements net.pitan76.mcpitanlib.api.client.render.block.entity.CompatBlockEntityRenderer {
+
+ @Deprecated
+ public CompatRegistryClient.BlockEntityRendererFactory.Context ctx;
+
+ public CompatBlockEntityRenderer(CompatBlockEntityRendererConstructArgs args) {
+
+ }
+
+ public CompatBlockEntityRenderer(CompatRegistryClient.BlockEntityRendererFactory.Context ctx) {
+ this.ctx = ctx;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawBackgroundArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawBackgroundArgs.java
new file mode 100644
index 000000000..4c0a4ab27
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawBackgroundArgs.java
@@ -0,0 +1,48 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+
+public class DrawBackgroundArgs {
+ public DrawObjectDM drawObjectDM;
+ public float delta;
+ public int mouseX, mouseY;
+
+ public DrawBackgroundArgs(DrawObjectDM drawObjectDM, float delta, int mouseX, int mouseY) {
+ setDrawObjectDM(drawObjectDM);
+ setDelta(delta);
+ setMouseX(mouseX);
+ setMouseY(mouseY);
+ }
+
+ public void setDrawObjectDM(DrawObjectDM drawObjectDM) {
+ this.drawObjectDM = drawObjectDM;
+ }
+
+ public void setDelta(float delta) {
+ this.delta = delta;
+ }
+
+ public void setMouseX(int mouseX) {
+ this.mouseX = mouseX;
+ }
+
+ public void setMouseY(int mouseY) {
+ this.mouseY = mouseY;
+ }
+
+ public DrawObjectDM getDrawObjectDM() {
+ return drawObjectDM;
+ }
+
+ public float getDelta() {
+ return delta;
+ }
+
+ public int getMouseX() {
+ return mouseX;
+ }
+
+ public int getMouseY() {
+ return mouseY;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawForegroundArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawForegroundArgs.java
new file mode 100644
index 000000000..643a5bf80
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawForegroundArgs.java
@@ -0,0 +1,38 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+
+public class DrawForegroundArgs {
+ public DrawObjectDM drawObjectDM;
+ public int mouseX, mouseY;
+
+ public DrawForegroundArgs(DrawObjectDM drawObjectDM, int mouseX, int mouseY) {
+ setDrawObjectDM(drawObjectDM);
+ setMouseX(mouseX);
+ setMouseY(mouseY);
+ }
+
+ public void setDrawObjectDM(DrawObjectDM drawObjectDM) {
+ this.drawObjectDM = drawObjectDM;
+ }
+
+ public void setMouseX(int mouseX) {
+ this.mouseX = mouseX;
+ }
+
+ public void setMouseY(int mouseY) {
+ this.mouseY = mouseY;
+ }
+
+ public DrawObjectDM getDrawObjectDM() {
+ return drawObjectDM;
+ }
+
+ public int getMouseX() {
+ return mouseX;
+ }
+
+ public int getMouseY() {
+ return mouseY;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawMouseoverTooltipArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawMouseoverTooltipArgs.java
new file mode 100644
index 000000000..652c5ed68
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/DrawMouseoverTooltipArgs.java
@@ -0,0 +1,38 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+
+public class DrawMouseoverTooltipArgs {
+ public DrawObjectDM drawObjectDM;
+ public int mouseX, mouseY;
+
+ public DrawMouseoverTooltipArgs(DrawObjectDM drawObjectDM, int mouseX, int mouseY) {
+ setDrawObjectDM(drawObjectDM);
+ setMouseX(mouseX);
+ setMouseY(mouseY);
+ }
+
+ public void setDrawObjectDM(DrawObjectDM drawObjectDM) {
+ this.drawObjectDM = drawObjectDM;
+ }
+
+ public void setMouseX(int mouseX) {
+ this.mouseX = mouseX;
+ }
+
+ public void setMouseY(int mouseY) {
+ this.mouseY = mouseY;
+ }
+
+ public DrawObjectDM getDrawObjectDM() {
+ return drawObjectDM;
+ }
+
+ public int getMouseX() {
+ return mouseX;
+ }
+
+ public int getMouseY() {
+ return mouseY;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/KeyEventArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/KeyEventArgs.java
new file mode 100644
index 000000000..45c4ceeed
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/KeyEventArgs.java
@@ -0,0 +1,35 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+public class KeyEventArgs {
+ public int keyCode, scanCode, modifiers;
+
+ public KeyEventArgs(int keyCode, int scanCode, int modifiers) {
+ setKeyCode(keyCode);
+ setScanCode(scanCode);
+ setModifiers(modifiers);
+ }
+
+ public void setKeyCode(int keyCode) {
+ this.keyCode = keyCode;
+ }
+
+ public void setModifiers(int modifiers) {
+ this.modifiers = modifiers;
+ }
+
+ public void setScanCode(int scanCode) {
+ this.scanCode = scanCode;
+ }
+
+ public int getKeyCode() {
+ return keyCode;
+ }
+
+ public int getModifiers() {
+ return modifiers;
+ }
+
+ public int getScanCode() {
+ return scanCode;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/RenderArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/RenderArgs.java
new file mode 100644
index 000000000..8b4905d78
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/RenderArgs.java
@@ -0,0 +1,48 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+
+public class RenderArgs {
+ public DrawObjectDM drawObjectDM;
+ public float delta;
+ public int mouseX, mouseY;
+
+ public RenderArgs(DrawObjectDM drawObjectDM, int mouseX, int mouseY, float delta) {
+ setDrawObjectDM(drawObjectDM);
+ setDelta(delta);
+ setMouseX(mouseX);
+ setMouseY(mouseY);
+ }
+
+ public void setDrawObjectDM(DrawObjectDM drawObjectDM) {
+ this.drawObjectDM = drawObjectDM;
+ }
+
+ public void setDelta(float delta) {
+ this.delta = delta;
+ }
+
+ public void setMouseX(int mouseX) {
+ this.mouseX = mouseX;
+ }
+
+ public void setMouseY(int mouseY) {
+ this.mouseY = mouseY;
+ }
+
+ public DrawObjectDM getDrawObjectDM() {
+ return drawObjectDM;
+ }
+
+ public float getDelta() {
+ return delta;
+ }
+
+ public int getMouseX() {
+ return mouseX;
+ }
+
+ public int getMouseY() {
+ return mouseY;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/screen/RenderBackgroundTextureArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/screen/RenderBackgroundTextureArgs.java
new file mode 100644
index 000000000..610b56280
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/screen/RenderBackgroundTextureArgs.java
@@ -0,0 +1,34 @@
+package net.pitan76.mcpitanlib.api.client.render.screen;
+
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+import net.pitan76.mcpitanlib.api.client.render.handledscreen.RenderArgs;
+
+public class RenderBackgroundTextureArgs {
+ public DrawObjectDM drawObjectDM;
+ int vOffset;
+
+ public RenderBackgroundTextureArgs(DrawObjectDM drawObjectDM, int vOffset) {
+ this.drawObjectDM = drawObjectDM;
+ this.vOffset = vOffset;
+ }
+
+ public RenderBackgroundTextureArgs(RenderArgs args) {
+ this(args.drawObjectDM, 0);
+ }
+
+ public DrawObjectDM getDrawObjectDM() {
+ return drawObjectDM;
+ }
+
+ public int getvOffset() {
+ return vOffset;
+ }
+
+ public void setDrawObjectDM(DrawObjectDM drawObjectDM) {
+ this.drawObjectDM = drawObjectDM;
+ }
+
+ public void setvOffset(int vOffset) {
+ this.vOffset = vOffset;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/AbstractCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/AbstractCommand.java
new file mode 100644
index 000000000..5b2fbdf00
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/AbstractCommand.java
@@ -0,0 +1,47 @@
+package net.pitan76.mcpitanlib.api.command;
+
+import net.pitan76.mcpitanlib.api.command.argument.RequiredCommand;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class AbstractCommand {
+
+ private Map> argumentCommands = new HashMap<>();
+ public int isSuccess = 1;
+
+ public void init() {
+
+ }
+
+ public void init(CommandSettings settings) {
+ init();
+ }
+
+ public void success() {
+ isSuccess = 1;
+ }
+
+ public void failure() {
+ isSuccess = 0;
+ }
+
+ public Map> getArgumentCommands() {
+ return argumentCommands;
+ }
+
+ public void setArgumentCommands(Map> argumentCommands) {
+ this.argumentCommands = argumentCommands;
+ }
+
+ public void addArgumentCommand(String name, AbstractCommand> command) {
+ getArgumentCommands().put(name, command);
+ }
+
+ public void addArgumentCommand(RequiredCommand> command) {
+ getArgumentCommands().put(command.getArgumentName(), command);
+ }
+
+ public abstract void execute(ServerCommandEvent event);
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandRegistry.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandRegistry.java
new file mode 100644
index 000000000..03467b2a7
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandRegistry.java
@@ -0,0 +1,125 @@
+package net.pitan76.mcpitanlib.api.command;
+
+import com.mojang.brigadier.builder.ArgumentBuilder;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import dev.architectury.event.events.common.CommandRegistrationEvent;
+import net.minecraft.command.CommandRegistryAccess;
+import net.minecraft.server.command.CommandManager;
+import net.minecraft.server.command.ServerCommandSource;
+import net.pitan76.mcpitanlib.api.command.argument.*;
+import net.pitan76.mcpitanlib.api.event.*;
+
+import java.util.Map;
+
+public class CommandRegistry {
+
+ @Deprecated
+ public static CommandRegistryAccess latestCommandRegistryAccess;
+
+ public static void register(String name, LiteralCommand command) {
+ CommandRegistrationEvent.EVENT.register((dispatcher, registry, environment) -> {
+ latestCommandRegistryAccess = registry;
+
+ CommandSettings settings = new CommandSettings();
+ command.init(settings);
+
+ LiteralArgumentBuilder builder = LiteralArgumentBuilder.literal(name).requires(settings::requires)
+ .executes(context -> {
+ ServerCommandEvent event = new ServerCommandEvent();
+ event.setContext(context);
+ command.execute(event);
+ return command.isSuccess;
+ });
+
+ forArgsCmd(command, builder);
+
+ //register(builder);
+ dispatcher.register(builder);
+ });
+ }
+
+ public static void register(LiteralArgumentBuilder builder) {
+ CommandRegistrationEvent.EVENT.register((dispatcher, registry, environment) -> {
+ latestCommandRegistryAccess = registry;
+ dispatcher.register(builder);
+ }
+ );
+ }
+
+ private static > void forArgsCmd(AbstractCommand> absCmd, ArgumentBuilder builder) {
+
+ if (!absCmd.getArgumentCommands().isEmpty()) {
+ // 引数コマンド
+ for (Map.Entry> argCmd : absCmd.getArgumentCommands().entrySet()) {
+ ArgumentBuilder nextBuilder = null;
+ argCmd.getValue().init(new CommandSettings());
+
+ if (argCmd.getValue() instanceof LiteralCommand) {
+ LiteralCommand command = (LiteralCommand) argCmd.getValue();
+ nextBuilder = CommandManager.literal(argCmd.getKey())
+ .executes(context -> {
+ ServerCommandEvent event = new ServerCommandEvent();
+ event.setContext(context);
+ event.setCommand(command);
+ command.execute(event);
+ return command.isSuccess;
+ }
+ );
+ }
+
+ if (argCmd.getValue() instanceof RequiredCommand) {
+ RequiredCommand> command = (RequiredCommand>) argCmd.getValue();
+
+ nextBuilder = CommandManager.argument(argCmd.getKey(), command.getArgumentType())
+ .executes(context -> {
+ ServerCommandEvent event = new ServerCommandEvent();
+ if (command instanceof IntegerCommand) {
+ event = new IntegerCommandEvent();
+ }
+ if (command instanceof DoubleCommand) {
+ event = new DoubleCommandEvent();
+ }
+ if (command instanceof FloatCommand) {
+ event = new FloatCommandEvent();
+ }
+ if (command instanceof LongCommand) {
+ event = new LongCommandEvent();
+ }
+ if (command instanceof BooleanCommand) {
+ event = new BooleanCommandEvent();
+ }
+ if (command instanceof StringCommand) {
+ event = new StringCommandEvent();
+ }
+ if (command instanceof EntityCommand) {
+ event = new EntityCommandEvent();
+ }
+ if (command instanceof EntitiesCommand) {
+ event = new EntitiesCommandEvent();
+ }
+ if (command instanceof PlayerCommand) {
+ event = new PlayerCommandEvent();
+ }
+ if (command instanceof PlayersCommand) {
+ event = new PlayersCommandEvent();
+ }
+ if (command instanceof ItemCommand) {
+ event = new ItemCommandEvent();
+ }
+ if (command instanceof BlockCommand) {
+ event = new BlockCommandEvent();
+ }
+
+ event.setContext(context);
+ event.setCommand(command);
+ command.execute(event);
+ return command.isSuccess;
+ }
+ );
+ }
+ forArgsCmd(argCmd.getValue(), nextBuilder);
+ builder.then(nextBuilder);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandSettings.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandSettings.java
new file mode 100644
index 000000000..8a1d5fb2d
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandSettings.java
@@ -0,0 +1,33 @@
+package net.pitan76.mcpitanlib.api.command;
+
+import net.minecraft.server.command.ServerCommandSource;
+
+public class CommandSettings {
+ private int permissionLevel = -1;
+ private ICustom iCustom = null;
+
+ public boolean requires(ServerCommandSource source) {
+
+ return customRequires(source) && (permissionLevel == -1 || source.hasPermissionLevel(permissionLevel));
+ }
+
+ private boolean customRequires(ServerCommandSource source) {
+ if (iCustom == null) return true;
+ return iCustom.custom(source);
+ }
+
+ public CommandSettings permissionLevel(int level) {
+ this.permissionLevel = level;
+ return this;
+ }
+
+ public CommandSettings custom(ICustom iCustom) {
+ this.iCustom = iCustom;
+ return this;
+ }
+
+ @FunctionalInterface
+ public interface ICustom {
+ boolean custom(ServerCommandSource source);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/ConfigCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/ConfigCommand.java
new file mode 100644
index 000000000..0c4a9fb54
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/ConfigCommand.java
@@ -0,0 +1,173 @@
+package net.pitan76.mcpitanlib.api.command;
+
+import com.mojang.brigadier.arguments.StringArgumentType;
+import net.pitan76.easyapi.config.Config;
+import net.pitan76.mcpitanlib.api.command.argument.StringCommand;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+import net.pitan76.mcpitanlib.api.event.StringCommandEvent;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.function.Supplier;
+
+public class ConfigCommand extends LiteralCommand {
+
+ public final Config config;
+ public File file;
+ public Supplier defaultConfigFunction;
+ public String prefix = "[MCPitanLib]";
+
+ public ConfigCommand(Config config, File file, String prefix) {
+ this.config = config;
+ this.file = file;
+ this.prefix = prefix;
+ }
+
+ public ConfigCommand(Config config, File file, String prefix, @Nullable Supplier supplier) {
+ this.config = config;
+ this.file = file;
+ this.defaultConfigFunction = supplier;
+ this.prefix = prefix;
+ }
+
+ public ConfigCommand(Config config, File file, @Nullable Supplier supplier) {
+ this.config = config;
+ this.file = file;
+ this.defaultConfigFunction = supplier;
+ }
+
+ public ConfigCommand(Config config, File file) {
+ this.config = config;
+ this.file = file;
+ }
+
+ public ConfigCommand(Config config) {
+ this.config = config;
+ }
+
+ @Override
+ public void init(CommandSettings settings) {
+ settings.permissionLevel(3);
+
+ addArgumentCommand("set", new LiteralCommand() {
+ @Override
+ public void init(CommandSettings settings) {
+
+ addArgumentCommand("key", new StringCommand() {
+ @Override
+ public String getArgumentName() {
+ return "key";
+ }
+
+
+ @Override
+ public void init(CommandSettings settings) {
+
+ addArgumentCommand("value", new StringCommand() {
+ @Override
+ public String getArgumentName() {
+ return "value";
+ }
+
+ @Override
+ public void execute(StringCommandEvent event) {
+ String key = StringArgumentType.getString(event.context, "key");
+ String value = StringArgumentType.getString(event.context, "value");
+ if (config.get(key) == null) {
+ event.sendFailure(TextUtil.literal(prefix + " Key not found."));
+ return;
+ }
+ if (config.get(key).getClass() == String.class) {
+ config.setString(key, value);
+ event.sendSuccess(TextUtil.literal(prefix + " Set " + key + " to " + value), false);
+
+ } else if (config.get(key).getClass() == Integer.class) {
+ config.setInt(key, Integer.parseInt(value));
+ event.sendSuccess(TextUtil.literal(prefix + " Set " + key + " to " + value), false);
+
+ } else if (config.get(key).getClass() == Double.class) {
+ config.setDouble(key, Double.parseDouble(value));
+ event.sendSuccess(TextUtil.literal(prefix + " Set " + key + " to " + value), false);
+
+ } else if (config.get(key).getClass() == Boolean.class) {
+ config.setBoolean(key, Boolean.parseBoolean(value));
+ event.sendSuccess(TextUtil.literal(prefix + " Set " + key + " to " + value), false);
+
+ } else {
+ event.sendFailure(TextUtil.literal(prefix + " Not supported type."));
+ }
+ if (file != null)
+ config.save(file);
+ }
+ });
+ }
+
+ @Override
+ public void execute(StringCommandEvent event) {
+ }
+ });
+ }
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+
+ }
+ });
+
+ addArgumentCommand("get", new LiteralCommand() {
+ @Override
+ public void init(CommandSettings settings) {
+ addArgumentCommand("key", new StringCommand() {
+ @Override
+ public String getArgumentName() {
+ return "key";
+ }
+
+ @Override
+ public void execute(StringCommandEvent event) {
+ String key = StringArgumentType.getString(event.context, "key");
+ if (config.get(key) == null) {
+ event.sendFailure(TextUtil.literal(prefix + " Key not found."));
+ return;
+ }
+ event.sendSuccess(TextUtil.literal(prefix + " " + key + ": " + config.get(key).toString()), false);
+ }
+ });
+ }
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+
+ }
+ });
+
+ addArgumentCommand("list", new LiteralCommand() {
+ @Override
+ public void execute(ServerCommandEvent event) {
+ event.sendSuccess(TextUtil.literal(prefix + " Config List"), false);
+ for (String key : config.configMap.keySet()) {
+ event.sendSuccess(TextUtil.literal(" - " + key + ": " + config.get(key).toString()), false);
+ }
+ }
+ });
+
+ if (defaultConfigFunction != null) {
+ addArgumentCommand("reset", new LiteralCommand() {
+ @Override
+ public void execute(ServerCommandEvent event) {
+ config.configMap.clear();
+ defaultConfigFunction.get();
+ if (file != null)
+ config.save(file);
+ event.sendSuccess(TextUtil.literal(prefix + " Reset config."), false);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/LiteralCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/LiteralCommand.java
new file mode 100644
index 000000000..f382775a9
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/LiteralCommand.java
@@ -0,0 +1,7 @@
+package net.pitan76.mcpitanlib.api.command;
+
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class LiteralCommand extends AbstractCommand {
+
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/BlockCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/BlockCommand.java
new file mode 100644
index 000000000..452c85dac
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/BlockCommand.java
@@ -0,0 +1,21 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import net.minecraft.block.Block;
+import net.minecraft.command.argument.BlockStateArgumentType;
+import net.pitan76.mcpitanlib.api.command.CommandRegistry;
+import net.pitan76.mcpitanlib.api.event.BlockCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class BlockCommand extends RequiredCommand {
+ @Override
+ public BlockStateArgumentType getArgumentType() {
+ return BlockStateArgumentType.blockState(CommandRegistry.latestCommandRegistryAccess);
+ }
+
+ public abstract void execute(BlockCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((BlockCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/BooleanCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/BooleanCommand.java
new file mode 100644
index 000000000..32687d804
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/BooleanCommand.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.BoolArgumentType;
+import net.pitan76.mcpitanlib.api.event.BooleanCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class BooleanCommand extends RequiredCommand {
+ @Override
+ public BoolArgumentType getArgumentType() {
+ return BoolArgumentType.bool();
+ }
+
+ public abstract void execute(BooleanCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((BooleanCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/DoubleCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/DoubleCommand.java
new file mode 100644
index 000000000..b8ede9b0d
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/DoubleCommand.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.DoubleArgumentType;
+import net.pitan76.mcpitanlib.api.event.DoubleCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class DoubleCommand extends RequiredCommand {
+ @Override
+ public DoubleArgumentType getArgumentType() {
+ return DoubleArgumentType.doubleArg();
+ }
+
+ public abstract void execute(DoubleCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((DoubleCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/EntitiesCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/EntitiesCommand.java
new file mode 100644
index 000000000..4157c76d3
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/EntitiesCommand.java
@@ -0,0 +1,20 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import net.minecraft.command.argument.EntityArgumentType;
+import net.minecraft.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.EntitiesCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class EntitiesCommand extends RequiredCommand {
+ @Override
+ public EntityArgumentType getArgumentType() {
+ return EntityArgumentType.entities();
+ }
+
+ public abstract void execute(EntitiesCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((EntitiesCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/EntityCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/EntityCommand.java
new file mode 100644
index 000000000..cf0c76ec6
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/EntityCommand.java
@@ -0,0 +1,20 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import net.minecraft.command.argument.EntityArgumentType;
+import net.minecraft.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.EntityCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class EntityCommand extends RequiredCommand {
+ @Override
+ public EntityArgumentType getArgumentType() {
+ return EntityArgumentType.entity();
+ }
+
+ public abstract void execute(EntityCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((EntityCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/FloatCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/FloatCommand.java
new file mode 100644
index 000000000..1b178e01b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/FloatCommand.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.FloatArgumentType;
+import net.pitan76.mcpitanlib.api.event.FloatCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class FloatCommand extends RequiredCommand {
+ @Override
+ public FloatArgumentType getArgumentType() {
+ return FloatArgumentType.floatArg();
+ }
+
+ public abstract void execute(FloatCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((FloatCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/GreedyStringCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/GreedyStringCommand.java
new file mode 100644
index 000000000..afff6b7e8
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/GreedyStringCommand.java
@@ -0,0 +1,10 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.StringArgumentType;
+
+public abstract class GreedyStringCommand extends StringCommand {
+ @Override
+ public StringArgumentType getArgumentType() {
+ return StringArgumentType.greedyString();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/IntegerCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/IntegerCommand.java
new file mode 100644
index 000000000..bfcdec912
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/IntegerCommand.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.IntegerArgumentType;
+import net.pitan76.mcpitanlib.api.event.IntegerCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class IntegerCommand extends RequiredCommand {
+ @Override
+ public IntegerArgumentType getArgumentType() {
+ return IntegerArgumentType.integer();
+ }
+
+ public abstract void execute(IntegerCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((IntegerCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/ItemCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/ItemCommand.java
new file mode 100644
index 000000000..2d24871bc
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/ItemCommand.java
@@ -0,0 +1,21 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import net.minecraft.command.argument.ItemStackArgumentType;
+import net.minecraft.item.Item;
+import net.pitan76.mcpitanlib.api.command.CommandRegistry;
+import net.pitan76.mcpitanlib.api.event.ItemCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class ItemCommand extends RequiredCommand- {
+ @Override
+ public ItemStackArgumentType getArgumentType() {
+ return ItemStackArgumentType.itemStack(CommandRegistry.latestCommandRegistryAccess);
+ }
+
+ public abstract void execute(ItemCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((ItemCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/LongCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/LongCommand.java
new file mode 100644
index 000000000..45bd3b622
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/LongCommand.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.LongArgumentType;
+import net.pitan76.mcpitanlib.api.event.LongCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class LongCommand extends RequiredCommand {
+ @Override
+ public LongArgumentType getArgumentType() {
+ return LongArgumentType.longArg();
+ }
+
+ public abstract void execute(LongCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((LongCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/PlayerCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/PlayerCommand.java
new file mode 100644
index 000000000..3a674b908
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/PlayerCommand.java
@@ -0,0 +1,20 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import net.minecraft.command.argument.EntityArgumentType;
+import net.minecraft.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.PlayerCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class PlayerCommand extends RequiredCommand {
+ @Override
+ public EntityArgumentType getArgumentType() {
+ return EntityArgumentType.player();
+ }
+
+ public abstract void execute(PlayerCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((PlayerCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/PlayersCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/PlayersCommand.java
new file mode 100644
index 000000000..195d81d3b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/PlayersCommand.java
@@ -0,0 +1,20 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import net.minecraft.command.argument.EntityArgumentType;
+import net.minecraft.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.PlayersCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class PlayersCommand extends RequiredCommand {
+ @Override
+ public EntityArgumentType getArgumentType() {
+ return EntityArgumentType.players();
+ }
+
+ public abstract void execute(PlayersCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((PlayersCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/RequiredCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/RequiredCommand.java
new file mode 100644
index 000000000..a3428290f
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/RequiredCommand.java
@@ -0,0 +1,10 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.ArgumentType;
+import net.pitan76.mcpitanlib.api.command.AbstractCommand;
+
+public abstract class RequiredCommand extends AbstractCommand {
+ public abstract String getArgumentName();
+
+ public abstract ArgumentType getArgumentType();
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/StringCommand.java b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/StringCommand.java
new file mode 100644
index 000000000..008bfefaf
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/argument/StringCommand.java
@@ -0,0 +1,19 @@
+package net.pitan76.mcpitanlib.api.command.argument;
+
+import com.mojang.brigadier.arguments.StringArgumentType;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+import net.pitan76.mcpitanlib.api.event.StringCommandEvent;
+
+public abstract class StringCommand extends RequiredCommand {
+ @Override
+ public StringArgumentType getArgumentType() {
+ return StringArgumentType.string();
+ }
+
+ public abstract void execute(StringCommandEvent event);
+
+ @Override
+ public void execute(ServerCommandEvent event) {
+ execute((StringCommandEvent) event);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/datafixer/ItemStackFixer.java b/common/src/main/java/net/pitan76/mcpitanlib/api/datafixer/ItemStackFixer.java
new file mode 100644
index 000000000..a3b041b01
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/datafixer/ItemStackFixer.java
@@ -0,0 +1,52 @@
+package net.pitan76.mcpitanlib.api.datafixer;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class ItemStackFixer {
+ private static final Map> nbt2componentMapIfItemEqualMap = new HashMap<>();
+ private static final Map, Map> nbt2componentMapIfitemMatchesMap = new HashMap<>();
+ private static final Map nbt2componentMap = new HashMap<>();
+
+ public static void nbt2componentIfItemEquals(String itemId, String nbtKey, String componentId) {
+ Map nbt2componentMap;
+ if (nbt2componentMapIfItemEqualMap.containsKey(itemId)) {
+ nbt2componentMap = nbt2componentMapIfItemEqualMap.get(itemId);
+ } else {
+ nbt2componentMap = new HashMap<>();
+ nbt2componentMapIfItemEqualMap.put(itemId, nbt2componentMap);
+ }
+
+ nbt2componentMap.put(nbtKey, componentId);
+ }
+
+ public static void nbt2componentIfItemMatches(Set itemId, String nbtKey, String componentId) {
+ Map nbt2componentMap;
+ if (nbt2componentMapIfitemMatchesMap.containsKey(itemId)) {
+ nbt2componentMap = nbt2componentMapIfitemMatchesMap.get(itemId);
+ } else {
+ nbt2componentMap = new HashMap<>();
+ nbt2componentMapIfitemMatchesMap.put(itemId, nbt2componentMap);
+ }
+
+ nbt2componentMap.put(nbtKey, componentId);
+ }
+
+ public static void nbt2component(String nbtKey, String componentId) {
+ if (nbt2componentMap.containsKey(nbtKey)) return;
+ nbt2componentMap.put(nbtKey, componentId);
+ }
+
+ public static Map> getNbt2componentMapIfItemEqualMap() {
+ return nbt2componentMapIfItemEqualMap;
+ }
+
+ public static Map, Map> getNbt2componentMapIfitemMatchesMap() {
+ return nbt2componentMapIfitemMatchesMap;
+ }
+
+ public static Map getNbt2componentMap() {
+ return nbt2componentMap;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/enchantment/CompatEnchantment.java b/common/src/main/java/net/pitan76/mcpitanlib/api/enchantment/CompatEnchantment.java
new file mode 100644
index 000000000..d20d4a2b4
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/enchantment/CompatEnchantment.java
@@ -0,0 +1,69 @@
+package net.pitan76.mcpitanlib.api.enchantment;
+
+import net.minecraft.enchantment.Enchantment;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.item.ItemStack;
+import net.minecraft.registry.BuiltinRegistries;
+import net.minecraft.registry.RegistryKey;
+import net.minecraft.registry.RegistryKeys;
+import net.minecraft.registry.entry.RegistryEntry;
+import net.minecraft.util.Identifier;
+import net.minecraft.world.World;
+import net.pitan76.mcpitanlib.api.util.EnchantmentUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Optional;
+
+public class CompatEnchantment {
+ private final RegistryKey registryKey;
+
+ @Deprecated
+ public CompatEnchantment(RegistryKey registryKey) {
+ this.registryKey = registryKey;
+ }
+
+ public CompatEnchantment of(Identifier identifier) {
+ return EnchantmentUtil.getEnchantment(identifier);
+ }
+
+ public Identifier getId() {
+ return registryKey.getRegistry();
+ }
+
+ @Deprecated
+ public RegistryKey getRegistryKey() {
+ return registryKey;
+ }
+
+ public String toString() {
+ return getId().toString();
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof CompatEnchantment) {
+ return ((CompatEnchantment) obj).getId().equals(getId());
+ }
+ return false;
+ }
+
+ @Deprecated
+ public RegistryEntry getEntry(@Nullable World world) {
+ Optional> optionalEntry;
+ if (world == null) {
+ optionalEntry = BuiltinRegistries.createWrapperLookup().createRegistryLookup()
+ .getOptionalEntry(RegistryKeys.ENCHANTMENT, registryKey);
+ } else {
+ optionalEntry = world.getRegistryManager().get(RegistryKeys.ENCHANTMENT).getEntry(registryKey);
+ }
+
+ return optionalEntry.orElseThrow();
+ }
+
+ public Enchantment getEnchantment(@Nullable World world) {
+ return getEntry(world).value();
+ }
+
+ public int getLevel(ItemStack stack, @Nullable World world) {
+ return EnchantmentHelper.getLevel(getEntry(world), stack);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatContainerUser.java b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatContainerUser.java
new file mode 100644
index 000000000..ca2ab6026
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatContainerUser.java
@@ -0,0 +1,33 @@
+package net.pitan76.mcpitanlib.api.entity;
+
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+
+public class CompatContainerUser {
+ protected PlayerEntity containerUser;
+
+ public CompatContainerUser(PlayerEntity containerUser) {
+ this.containerUser = containerUser;
+ }
+
+ public double getContainerInteractionRange() {
+ return 4.5d;
+ }
+
+ public LivingEntity asLivingEntity() {
+ return containerUser;
+ }
+
+ public boolean isPlayer() {
+ return true;
+ }
+
+ public Player asPlayer() {
+ return new Player(containerUser);
+ }
+
+ @Deprecated
+ public PlayerEntity getRaw() {
+ return containerUser;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatEntity.java b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatEntity.java
new file mode 100644
index 000000000..f78178be2
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatEntity.java
@@ -0,0 +1,119 @@
+package net.pitan76.mcpitanlib.api.entity;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.data.DataTracker;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.network.listener.ClientPlayPacketListener;
+import net.minecraft.network.packet.Packet;
+import net.minecraft.server.world.ServerWorld;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.world.World;
+import net.pitan76.mcpitanlib.api.event.entity.InitDataTrackerArgs;
+import net.pitan76.mcpitanlib.api.event.nbt.ReadNbtArgs;
+import net.pitan76.mcpitanlib.api.event.nbt.WriteNbtArgs;
+import net.pitan76.mcpitanlib.midohra.util.math.Vector3d;
+
+public class CompatEntity extends Entity {
+ public CompatEntity(EntityType> type, World world) {
+ super(type, world);
+ }
+
+ @Deprecated
+ @Override
+ public void initDataTracker(DataTracker.Builder builder) {
+ initDataTracker(new InitDataTrackerArgs(builder));
+ }
+
+ public void initDataTracker(InitDataTrackerArgs args) {
+
+ }
+
+ public void readCustomDataFromNbt(ReadNbtArgs nbt) {
+
+ }
+
+ public void writeCustomDataToNbt(WriteNbtArgs nbt) {
+
+ }
+
+ @Deprecated
+ @Override
+ public void readCustomDataFromNbt(NbtCompound nbt) {
+ readCustomDataFromNbt(new ReadNbtArgs(nbt));
+ }
+
+ @Deprecated
+ @Override
+ public void writeCustomDataToNbt(NbtCompound nbt) {
+ writeCustomDataToNbt(new WriteNbtArgs(nbt));
+ }
+
+ public Packet createSpawnPacket() {
+ return null;
+ }
+
+ public void writeNbt(WriteNbtArgs args) {
+ super.writeNbt(args.getNbt());
+ }
+
+ public void readNbt(ReadNbtArgs args) {
+ super.readNbt(args.getNbt());
+ }
+
+ @Deprecated
+ @Override
+ public NbtCompound writeNbt(NbtCompound nbt) {
+ writeNbt(new WriteNbtArgs(nbt));
+ return nbt;
+ }
+
+ @Deprecated
+ @Override
+ public void readNbt(NbtCompound nbt) {
+ readNbt(new ReadNbtArgs(nbt));
+ }
+
+ @Deprecated
+ @Override
+ public World getWorld() {
+ return callGetWorld();
+ }
+
+ public World callGetWorld() {
+ return super.getWorld();
+ }
+
+ public BlockPos callGetBlockPos() {
+ return getBlockPos();
+ }
+
+ public Vec3d callGetPos() {
+ return getPos();
+ }
+
+ public boolean hasServerWorld() {
+ return callGetWorld() instanceof ServerWorld;
+ }
+
+ public ServerWorld getServerWorld() {
+ return (ServerWorld) getWorld();
+ }
+
+ public net.pitan76.mcpitanlib.midohra.world.World getMidohraWorld() {
+ return net.pitan76.mcpitanlib.midohra.world.World.of(callGetWorld());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.util.math.BlockPos getMidohraBlockPos() {
+ return net.pitan76.mcpitanlib.midohra.util.math.BlockPos.of(callGetBlockPos());
+ }
+
+ public Vector3d getMidohraPos() {
+ return Vector3d.of(callGetPos());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.world.ServerWorld getMidohraServerWorld() {
+ return net.pitan76.mcpitanlib.midohra.world.ServerWorld.of(getServerWorld());
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatThrownItemEntity.java b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatThrownItemEntity.java
new file mode 100644
index 000000000..ccfe74e97
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatThrownItemEntity.java
@@ -0,0 +1,149 @@
+package net.pitan76.mcpitanlib.api.entity;
+
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.data.DataTracker;
+import net.minecraft.entity.projectile.thrown.ThrownItemEntity;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.text.Text;
+import net.minecraft.util.hit.EntityHitResult;
+import net.minecraft.util.hit.HitResult;
+import net.minecraft.world.World;
+import net.pitan76.mcpitanlib.api.event.entity.CollisionEvent;
+import net.pitan76.mcpitanlib.api.event.entity.EntityHitEvent;
+import net.pitan76.mcpitanlib.api.event.entity.InitDataTrackerArgs;
+import net.pitan76.mcpitanlib.api.event.nbt.ReadNbtArgs;
+import net.pitan76.mcpitanlib.api.event.nbt.WriteNbtArgs;
+
+public abstract class CompatThrownItemEntity extends ThrownItemEntity {
+
+ public CompatThrownItemEntity(EntityType extends ThrownItemEntity> entityType, World world) {
+ super(entityType, world);
+ }
+
+ public CompatThrownItemEntity(EntityType extends ThrownItemEntity> entityType, double d, double e, double f, World world) {
+ super(entityType, d, e, f, world);
+ }
+
+ public CompatThrownItemEntity(EntityType extends ThrownItemEntity> entityType, LivingEntity livingEntity, World world) {
+ super(entityType, livingEntity, world);
+ }
+
+ public abstract Item getDefaultItemOverride();
+
+ @Deprecated
+ @Override
+ protected Item getDefaultItem() {
+ return getDefaultItemOverride();
+ }
+
+ public ItemStack callGetItem() {
+ return super.getStack();
+ }
+
+ @Deprecated
+ @Override
+ public ItemStack getStack() {
+ return callGetItem();
+ }
+
+ public void callSetItem(ItemStack stack) {
+ super.setItem(stack);
+ }
+
+ @Deprecated
+ @Override
+ public void setItem(ItemStack stack) {
+ callSetItem(stack);
+ }
+
+ public void callHandleStatus(byte status) {
+ super.handleStatus(status);
+ }
+
+ @Deprecated
+ @Override
+ public void handleStatus(byte status) {
+ callHandleStatus(status);
+ }
+
+ public void onEntityHit(EntityHitEvent event) {
+ super.onEntityHit(event.entityHitResult);
+ }
+
+ @Deprecated
+ @Override
+ protected void onEntityHit(EntityHitResult entityHitResult) {
+ onEntityHit(new EntityHitEvent(entityHitResult));
+ }
+
+ public void onCollision(CollisionEvent event) {
+ super.onCollision(event.hitResult);
+ }
+
+ @Deprecated
+ @Override
+ protected void onCollision(HitResult hitResult) {
+ onCollision(new CollisionEvent(hitResult));
+ }
+
+ // ------------------ ExtendEntity ------------------
+
+ @Deprecated
+ @Override
+ public void initDataTracker(DataTracker.Builder builder) {
+ initDataTracker(new InitDataTrackerArgs(builder, dataTracker));
+ }
+
+ public void initDataTracker(InitDataTrackerArgs args) {
+ super.initDataTracker(args.getBuilder());
+ }
+
+ public void readCustomDataFromNbt(ReadNbtArgs nbt) {
+ super.readCustomDataFromNbt(nbt.getNbt());
+ }
+
+ public void writeCustomDataToNbt(WriteNbtArgs nbt) {
+ super.writeCustomDataToNbt(nbt.getNbt());
+ }
+
+ @Deprecated
+ @Override
+ public void readCustomDataFromNbt(NbtCompound nbt) {
+ readCustomDataFromNbt(new ReadNbtArgs(nbt));
+ }
+
+ @Deprecated
+ @Override
+ public void writeCustomDataToNbt(NbtCompound nbt) {
+ writeCustomDataToNbt(new WriteNbtArgs(nbt));
+ }
+
+ public void writeNbt(WriteNbtArgs args) {
+ super.writeNbt(args.getNbt());
+ }
+
+ public void readNbt(ReadNbtArgs args) {
+ super.readNbt(args.getNbt());
+ }
+
+ @Deprecated
+ @Override
+ public NbtCompound writeNbt(NbtCompound nbt) {
+ writeNbt(new WriteNbtArgs(nbt));
+ return nbt;
+ }
+
+ @Deprecated
+ @Override
+ public void readNbt(NbtCompound nbt) {
+ readNbt(new ReadNbtArgs(nbt));
+ }
+
+ @Override
+ public World getWorld() {
+ return super.getWorld();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/entity/EntityTypeBuilder.java b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/EntityTypeBuilder.java
new file mode 100644
index 000000000..933e0d8fc
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/EntityTypeBuilder.java
@@ -0,0 +1,133 @@
+package net.pitan76.mcpitanlib.api.entity;
+
+import com.google.common.collect.ImmutableSet;
+import net.minecraft.block.Block;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityDimensions;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.SpawnGroup;
+import net.minecraft.loot.LootTable;
+import net.minecraft.registry.RegistryKey;
+import net.pitan76.mcpitanlib.MCPitanLib;
+
+import java.util.Optional;
+
+public class EntityTypeBuilder {
+
+ private SpawnGroup spawnGroup;
+ private ExtendEntityType.EntityFactory factory;
+ private EntityDimensions entityDimensions;
+ private boolean saveable;
+ private boolean summonable;
+ private boolean fireImmune;
+ private boolean spawnableFarFromPlayer;
+ private ImmutableSet canSpawnBlocks;
+ private int maxTrackDistance;
+ private int trackTickInterval;
+ private Boolean alwaysUpdateVelocity = null;
+ private String translationKey = "entity." + MCPitanLib.MOD_ID;
+ private Optional> lootTable = Optional.empty();
+
+ @Deprecated
+ // Recommend: create()
+ public EntityTypeBuilder() {
+ setSaveable(true);
+ setSummonable(true);
+ setFireImmune(false);
+ setChangingDimensions(-1.0f, -1.0f);
+ spawnableFarFromPlayer = false;
+ maxTrackDistance = 5;
+ trackTickInterval = 3;
+ canSpawnBlocks = ImmutableSet.of();
+ }
+
+ @Deprecated
+ public EntityTypeBuilder(SpawnGroup spawnGroup, ExtendEntityType.EntityFactory factory) {
+ this();
+ this.spawnGroup = spawnGroup;
+ this.factory = factory;
+ }
+
+ public static EntityTypeBuilder create() {
+ return new EntityTypeBuilder<>();
+ }
+
+ public static EntityTypeBuilder create(SpawnGroup spawnGroup, ExtendEntityType.EntityFactory factory) {
+ return new EntityTypeBuilder<>(spawnGroup, factory);
+ }
+
+ public EntityType build() {
+ return new ExtendEntityType<>(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnBlocks, entityDimensions, maxTrackDistance, trackTickInterval, translationKey, lootTable, alwaysUpdateVelocity);
+ }
+
+ public EntityTypeBuilder setSpawnGroup(SpawnGroup spawnGroup) {
+ this.spawnGroup = spawnGroup;
+ return this;
+ }
+
+ public EntityTypeBuilder setEntityFactory(ExtendEntityType.EntityFactory factory) {
+ this.factory = factory;
+ return this;
+ }
+
+ public EntityTypeBuilder setDimensions(EntityDimensions entityDimensions) {
+ this.entityDimensions = entityDimensions;
+ return this;
+ }
+
+ public EntityTypeBuilder setFixedDimensions(float width, float height) {
+ return setDimensions(EntityDimensions.fixed(width, height));
+ }
+
+ public EntityTypeBuilder setChangingDimensions(float width, float height) {
+ return setDimensions(EntityDimensions.changing(width, height));
+ }
+
+ public EntityTypeBuilder setSaveable(boolean saveable) {
+ this.saveable = saveable;
+ return this;
+ }
+
+ public EntityTypeBuilder setSummonable(boolean summonable) {
+ this.summonable = summonable;
+ return this;
+ }
+
+ public EntityTypeBuilder setFireImmune(boolean fireImmune) {
+ this.fireImmune = fireImmune;
+ return this;
+ }
+
+ public EntityTypeBuilder setSpawnableFarFromPlayer(boolean spawnableFarFromPlayer) {
+ this.spawnableFarFromPlayer = spawnableFarFromPlayer;
+ return this;
+ }
+
+ public EntityTypeBuilder setCanSpawnBlocks(ImmutableSet canSpawnBlocks) {
+ this.canSpawnBlocks = canSpawnBlocks;
+ return this;
+ }
+
+ public EntityTypeBuilder setMaxTrackDistance(int maxTrackDistance) {
+ this.maxTrackDistance = maxTrackDistance;
+ return this;
+ }
+
+ public EntityTypeBuilder setTrackTickInterval(int trackTickInterval) {
+ this.trackTickInterval = trackTickInterval;
+ return this;
+ }
+
+ public EntityTypeBuilder