callGetStateManager() {
+ return super.getStateDefinition();
+ }
+}
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..1e9ebd80f
--- /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.world.level.block.EntityBlock;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.BlockEntityTicker;
+import net.minecraft.world.level.block.entity.BlockEntityType;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.Level;
+import net.pitan76.mcpitanlib.api.event.block.TileCreateEvent;
+import net.pitan76.mcpitanlib.api.tile.ExtendBlockEntityTicker;
+import org.jetbrains.annotations.Nullable;
+
+public interface ExtendBlockEntityProvider extends EntityBlock {
+
+ /**
+ * @deprecated Use {@link #createBlockEntity(TileCreateEvent)} instead.
+ */
+ @Deprecated
+ @Nullable
+ default BlockEntity newBlockEntity(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().create(event.getBlockPos(), event.getBlockState());
+ }
+
+ @Nullable
+ default BlockEntityType getBlockEntityType() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ default BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) {
+ if (isTick()) {
+ return ((world1, pos, state1, blockEntity) -> {
+ if (getBlockEntityType() == null || blockEntity == getBlockEntityType().getBlockEntity(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 EntityBlock.super.getTicker(world, state, type);
+ }
+
+ @Nullable
+ default ExtendBlockEntityTicker getCompatibleTicker(Level 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..f3b62aad2
--- /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.world.level.block.state.BlockState;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.network.chat.Component;
+import net.minecraft.world.phys.shapes.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 extends ICompatBlock {
+
+ /**
+ * 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 AbstractContainerMenu createScreenHandler(ScreenHandlerCreateEvent event, Options options) {
+ options.cancel = false;
+ return null;
+ }
+
+ /**
+ * get screen title
+ * @return Text
+ */
+ default Component 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/ICompatBlock.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/ICompatBlock.java
new file mode 100644
index 000000000..7647e49a5
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/ICompatBlock.java
@@ -0,0 +1,10 @@
+package net.pitan76.mcpitanlib.api.block;
+
+import net.minecraft.world.level.block.Block;
+import net.pitan76.mcpitanlib.midohra.block.BlockWrapper;
+
+public interface ICompatBlock {
+ default BlockWrapper getWrapper() {
+ return this instanceof Block ? BlockWrapper.of((Block) this) : BlockWrapper.of();
+ }
+}
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..03d51bbfd
--- /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.world.level.block.state.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..73b42a692
--- /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.world.level.block.state.BlockState;
+import net.minecraft.world.level.block.Rotation;
+import net.minecraft.core.Direction;
+import net.pitan76.mcpitanlib.midohra.holder.BlockStatePropertyHolder;
+
+public class RotateArgs implements BlockStatePropertyHolder {
+
+ public BlockState state;
+ public Rotation rotation;
+
+ public RotateArgs(BlockState state, Rotation rotation) {
+ this.state = state;
+ this.rotation = rotation;
+ }
+
+ public BlockState getRawBlockState() {
+ return state;
+ }
+
+ public Rotation 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..cf7f5496a
--- /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.world.level.block.state.BlockState;
+import net.minecraft.core.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..87d133df0
--- /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.world.level.block.state.BlockState state;
+ public final net.minecraft.world.level.LevelReader world;
+ public final net.minecraft.core.BlockPos pos;
+
+ public CanPlaceAtArgs(net.minecraft.world.level.block.state.BlockState state, net.minecraft.world.level.LevelReader world, net.minecraft.core.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.world.level.block.state.BlockState getState() {
+ return state;
+ }
+
+ public net.minecraft.world.level.LevelReader getWorld() {
+ return world;
+ }
+
+ public net.minecraft.core.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.isClientSide();
+ }
+
+ public boolean isServer() {
+ return !world.isClientSide();
+ }
+}
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..1fe0b12b2
--- /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.world.phys.shapes.CollisionContext;
+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, CollisionContext context) {
+ super(state, world, pos, context);
+ }
+
+ public CollisionShapeEvent(net.minecraft.world.level.block.state.BlockState state, net.minecraft.world.level.BlockGetter world, net.minecraft.core.BlockPos pos, CollisionContext 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..4503ffd9c
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/GetComparatorOutputArgs.java
@@ -0,0 +1,60 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.world.level.Level;
+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 Level world;
+ public BlockPos pos;
+ public Direction direction;
+
+ public GetComparatorOutputArgs(BlockState state, Level world, BlockPos pos) {
+ this(state, world, pos, Direction.NORTH);
+ }
+
+ public GetComparatorOutputArgs(BlockState state, Level world, BlockPos pos, Direction direction) {
+ this.state = state;
+ this.world = world;
+ this.pos = pos;
+ this.direction = direction;
+ }
+
+ public BlockState getState() {
+ return state;
+ }
+
+ public Level 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..38d2db82e
--- /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.world.level.block.state.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..5aaade166
--- /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.world.phys.shapes.CollisionContext;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.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 CollisionContext context;
+
+ public OutlineShapeEvent(BlockState state, BlockView world, BlockPos pos, CollisionContext context) {
+ this.state = state;
+ this.world = world;
+ this.pos = pos;
+ this.context = context;
+ }
+
+ public OutlineShapeEvent(net.minecraft.world.level.block.state.BlockState state, net.minecraft.world.level.BlockGetter world, net.minecraft.core.BlockPos pos, net.minecraft.world.phys.shapes.CollisionContext 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 CollisionContext getContext() {
+ return context;
+ }
+
+ public boolean isHolding(Item item) {
+ return getContext().isHoldingItem(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..3f0a8ea03
--- /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.world.level.block.Block;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.item.context.BlockPlaceContext;
+import net.minecraft.world.level.block.state.properties.Property;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.phys.BlockHitResult;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.phys.Vec3;
+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.UseOnContextMixin;
+import org.jetbrains.annotations.Nullable;
+
+public class PlacementStateArgs extends BaseEvent implements BlockStatePropertyHolder {
+ public BlockPlaceContext ctx;
+
+ @Nullable
+ public Block block;
+
+ public PlacementStateArgs(BlockPlaceContext ctx) {
+ this.ctx = ctx;
+ }
+
+ public PlacementStateArgs(BlockPlaceContext ctx, @Nullable Block block) {
+ this.ctx = ctx;
+ this.block = block;
+ }
+
+ public boolean canPlace() {
+ return ctx.canPlace();
+ }
+
+ public BlockPos getRawPos() {
+ return ctx.getClickedPos();
+ }
+
+ 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.core.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.core.Direction[] getRawPlacementDirections() {
+ return ctx.getNearestLookingDirections();
+ }
+
+ public InteractionHand getHand() {
+ return ctx.getHand();
+ }
+
+ public Direction getSide() {
+ return Direction.of(getRawSide());
+ }
+
+ public net.minecraft.core.Direction getRawSide() {
+ return ctx.getClickedFace();
+ }
+
+ public Direction getHorizontalPlayerFacing() {
+ return Direction.of(getRawHorizontalPlayerFacing());
+ }
+
+ public net.minecraft.core.Direction getRawHorizontalPlayerFacing() {
+ return ctx.getHorizontalDirection();
+ }
+
+ public float getPlayerYaw() {
+ return ctx.getRotation();
+ }
+
+ public World getWorld() {
+ return World.of(ctx.getLevel());
+ }
+
+ public IWorldView getWorldView() {
+ return getWorld();
+ }
+
+ public boolean isClient() {
+ return getWorld().isClient();
+ }
+
+ public Vec3 getHitPos() {
+ return ctx.getClickLocation();
+ }
+
+ public boolean canReplaceExisting() {
+ return ctx.replacingClickedOnBlock();
+ }
+
+ @Deprecated
+ public UseOnContextMixin getIUCAccessor() {
+ return (UseOnContextMixin) ctx;
+ }
+
+ public BlockHitResult getHitResult() {
+ return getIUCAccessor().getHitResult();
+ }
+
+ public ItemUseOnBlockEvent toItemUseOnBlockEvent() {
+ return new ItemUseOnBlockEvent(getWorld().getRaw(), getPlayer().getPlayerEntity(), getHand(), ctx.getItemInHand(), getHitResult());
+ }
+
+ public BlockPlaceContext getCtx() {
+ return ctx;
+ }
+
+ public @Nullable Block getRawBlock() {
+ return block;
+ }
+
+ public boolean isBlockExist() {
+ return block != null;
+ }
+
+ public net.minecraft.world.level.block.state.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.world.level.block.state.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..38dfc1a21
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/args/v2/StateForNeighborUpdateArgs.java
@@ -0,0 +1,109 @@
+package net.pitan76.mcpitanlib.api.block.args.v2;
+
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.world.level.LevelAccessor;
+import net.minecraft.world.level.LevelReader;
+import net.minecraft.world.level.ScheduledTickAccess;
+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 LevelReader world;
+ public BlockPos pos;
+ public BlockPos neighborPos;
+ public ScheduledTickAccess tickView;
+ public CompatRandom random;
+
+ public StateForNeighborUpdateArgs(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
+ this.state = state;
+ this.direction = direction;
+ this.neighborState = neighborState;
+ this.world = world;
+ this.pos = pos;
+ this.neighborPos = neighborPos;
+ }
+
+ public StateForNeighborUpdateArgs(BlockState state, Direction direction, BlockState neighborState, LevelReader world, BlockPos pos, BlockPos neighborPos, ScheduledTickAccess tickView, CompatRandom random) {
+ this.state = state;
+ this.direction = direction;
+ this.neighborState = neighborState;
+ this.world = world;
+ this.pos = pos;
+ this.neighborPos = neighborPos;
+ this.tickView = tickView;
+ this.random = random;
+ }
+
+ public Direction getDirection() {
+ return direction;
+ }
+
+ public BlockState getRawNeighborState() {
+ return neighborState;
+ }
+
+ public LevelReader 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(tickView);
+ }
+
+ @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.isClientSide();
+ }
+}
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..722514432
--- /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.world.level.block.state.BlockBehaviour;
+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 BlockBehaviour.Properties _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 BlockBehaviour.Properties _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..8c67c9888
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatBlock.java
@@ -0,0 +1,179 @@
+package net.pitan76.mcpitanlib.api.block.v2;
+
+import net.minecraft.world.level.block.RenderShape;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.phys.shapes.CollisionContext;
+import net.minecraft.world.item.context.BlockPlaceContext;
+import net.minecraft.world.level.block.Rotation;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.util.RandomSource;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import net.minecraft.world.level.BlockGetter;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.LevelReader;
+import net.minecraft.world.level.ScheduledTickAccess;
+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.api.util.math.random.CompatRandom;
+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 RenderShape getRenderShape(BlockState state) {
+ return getRenderType(new RenderTypeArgs(state)).renderType;
+ }
+
+ public CompatBlockRenderType getRenderType(RenderTypeArgs args) {
+ return new CompatBlockRenderType(super.getRenderShape(args.state));
+ }
+
+ @Override
+ @Deprecated
+ protected BlockState rotate(BlockState state, Rotation 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 skipRendering(BlockState state, BlockState stateFrom, Direction direction) {
+ return isSideInvisible(new SideInvisibleArgs(state, stateFrom, direction));
+ }
+
+ public boolean isSideInvisible(SideInvisibleArgs args) {
+ return super.skipRendering(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.getStateForPlacement(args.ctx));
+ }
+
+ @Override
+ public @Nullable BlockState getStateForPlacement(BlockPlaceContext 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.updateShape(args.state, args.world, args.tickView, args.pos, args.direction, args.neighborPos, args.neighborState, args.random.getMcRandom()));
+ }
+
+ @Override
+ protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) {
+ return getStateForNeighborUpdate(new StateForNeighborUpdateArgs(state, direction, neighborState, world, pos, neighborPos, tickView, new CompatRandom(random))).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.getShape(e.state.toMinecraft(), e.world.getRaw(), e.pos.toMinecraft(), e.context);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext 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, BlockGetter world, BlockPos pos, CollisionContext 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 hasAnalogOutputSignal(BlockState state) {
+ return hasComparatorOutput(new HasComparatorOutputArgs(state));
+ }
+
+ public boolean hasComparatorOutput(HasComparatorOutputArgs args) {
+ return super.hasAnalogOutputSignal(args.state);
+ }
+
+ @Deprecated
+ @Override
+ public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos, Direction direction) {
+ return getComparatorOutput(new GetComparatorOutputArgs(state, world, pos, direction));
+ }
+
+ public int getComparatorOutput(GetComparatorOutputArgs args) {
+ return super.getAnalogOutputSignal(args.state, args.world, args.pos, args.direction);
+ }
+
+ @Deprecated
+ @Override
+ protected boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
+ return canPlaceAt(new CanPlaceAtArgs(state, world, pos));
+ }
+
+ public boolean canPlaceAt(CanPlaceAtArgs args) {
+ return super.canSurvive(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..4c677aa45
--- /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.world.level.block.Block;
+import net.minecraft.world.phys.shapes.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).defaultBlockState());
+ }
+
+ return null;
+ }
+
+ default void setDefaultState(BlockState state) {
+ if (this instanceof Block) {
+ ((BlockInvoker) this).setDefaultState_invoke(state.toMinecraft());
+ }
+ }
+
+ @Override
+ @Deprecated
+ default net.minecraft.world.level.block.state.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..fb8ce089d
--- /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.world.phys.shapes.CollisionContext;
+import net.minecraft.world.level.block.StairBlock;
+import net.minecraft.world.level.block.state.properties.Half;
+import net.minecraft.world.level.block.state.properties.StairsShape;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import net.minecraft.world.level.BlockGetter;
+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.*;
+import net.pitan76.mcpitanlib.midohra.block.BlockState;
+
+public class CompatStairsBlock extends net.pitan76.mcpitanlib.api.block.CompatStairsBlock {
+
+ public static final DirectionProperty FACING = CompatProperties.ofDir(StairBlock.FACING);
+ public static final EnumProperty HALF = CompatProperties.of(StairBlock.HALF);
+ public static final EnumProperty SHAPE = CompatProperties.of(StairBlock.SHAPE);
+ public static final BooleanProperty WATERLOGGED = CompatProperties.of(StairBlock.WATERLOGGED);
+
+ public static final BlockHalfProperty COMPAT_HALF = BlockHalfProperty.ofRaw(StairBlock.HALF);
+ public static final StairShapeProperty COMPAT_SHAPE = StairShapeProperty.ofRaw(StairBlock.SHAPE);
+
+ public CompatStairsBlock(net.minecraft.world.level.block.state.BlockState baseBlockState, CompatibleBlockSettings settings) {
+ super(baseBlockState, settings);
+ }
+
+ public CompatStairsBlock(BlockState baseBlockState, CompatibleBlockSettings settings) {
+ this(baseBlockState.toMinecraft(), settings);
+ }
+
+ public VoxelShape getOutlineShape(OutlineShapeEvent e) {
+ return super.getShape(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 getShape(net.minecraft.world.level.block.state.BlockState state, BlockGetter world, BlockPos pos, CollisionContext 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.world.level.block.state.BlockState state, BlockGetter world, BlockPos pos, CollisionContext 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..0a06eb1d1
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v2/CompatibleBlockSettings.java
@@ -0,0 +1,292 @@
+package net.pitan76.mcpitanlib.api.block.v2;
+
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.MapCodec;
+import net.minecraft.world.level.block.state.BlockBehaviour;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.material.MapColor;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.world.level.block.SoundType;
+import net.minecraft.world.item.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 = MapCodec.unitCodec(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.forceSolidOn();
+ if (material.isReplaceable())
+ settings.settings.replaceable();
+ if (material.isSolid())
+ settings.settings.forceSolidOn();
+ if (material.isBurnable())
+ settings.settings.ignitedByLava();
+ settings.settings.pushReaction(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, BlockBehaviour block) {
+ super(block);
+ setId(id);
+ }
+
+ public static CompatibleBlockSettings copy(CompatIdentifier id, BlockBehaviour block) {
+ return new CompatibleBlockSettings(id, block);
+ }
+
+ public CompatibleBlockSettings air() {
+ super.air();
+ return this;
+ }
+
+ public CompatibleBlockSettings blockVision(BlockBehaviour.StatePredicate predicate) {
+ super.blockVision(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings postProcess(BlockBehaviour.PostProcess predicate) {
+ super.postProcess(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings solidBlock(BlockBehaviour.StatePredicate predicate) {
+ super.solidBlock(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings suffocates(BlockBehaviour.StatePredicate 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(BlockBehaviour.StatePredicate predicate) {
+ super.emissiveLighting(predicate);
+ return this;
+ }
+
+ public CompatibleBlockSettings offset(BlockBehaviour.OffsetType offsetType) {
+ super.offset(offsetType);
+ return this;
+ }
+
+ public CompatibleBlockSettings allowsSpawning(BlockBehaviour.StateArgumentPredicate> predicate) {
+ super.allowsSpawning(predicate);
+ return this;
+ }
+
+ public BlockBehaviour.Properties build() {
+ super.build();
+
+ if (identifier != null) {
+ settings.setId(ResourceKey.create(Registries.BLOCK, identifier.toMinecraft()));
+ }
+
+ return settings;
+ }
+
+ @Deprecated
+ @Override
+ public CompatibleBlockSettings sounds(SoundType blockSoundGroup) {
+ super.sounds(blockSoundGroup);
+ return this;
+ }
+
+
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/v3/CompatBlock.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v3/CompatBlock.java
new file mode 100644
index 000000000..f040d159d
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v3/CompatBlock.java
@@ -0,0 +1,60 @@
+package net.pitan76.mcpitanlib.api.block.v3;
+
+import net.pitan76.mcpitanlib.api.block.args.v2.CollisionShapeEvent;
+import net.pitan76.mcpitanlib.api.block.args.v2.OutlineShapeEvent;
+import net.pitan76.mcpitanlib.api.block.v2.BlockSettingsBuilder;
+import net.pitan76.mcpitanlib.api.block.v2.CompatibleBlockSettings;
+import net.pitan76.mcpitanlib.api.event.block.FluidStateArgs;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.midohra.fluid.FluidState;
+import net.pitan76.mcpitanlib.midohra.item.ItemWrapper;
+import net.pitan76.mcpitanlib.midohra.util.shape.VoxelShape;
+
+public class CompatBlock extends net.pitan76.mcpitanlib.api.block.v2.CompatBlock {
+
+ public CompatBlock(CompatibleBlockSettings settings) {
+ super(settings);
+ }
+
+ public CompatBlock(BlockSettingsBuilder builder, CompatIdentifier id) {
+ super(builder.build(id));
+ }
+
+ public CompatBlock(BlockSettingsBuilder builder) {
+ super(builder.build());
+ }
+
+ public ItemWrapper getItemWrapper() {
+ return getWrapper().asItem();
+ }
+
+ public VoxelShape getCollisionShapeM(CollisionShapeEvent e) {
+ return VoxelShape.of(super.getCollisionShape(e));
+ }
+
+ public VoxelShape getOutlineShapeM(OutlineShapeEvent e) {
+ return VoxelShape.of(super.getOutlineShape(e));
+ }
+
+ public FluidState getFluidStateM(FluidStateArgs args) {
+ return FluidState.of(super.getFluidState(args));
+ }
+
+ @Override
+ @Deprecated
+ public net.minecraft.world.phys.shapes.VoxelShape getCollisionShape(CollisionShapeEvent e) {
+ return getCollisionShapeM(e).raw();
+ }
+
+ @Override
+ @Deprecated
+ public net.minecraft.world.phys.shapes.VoxelShape getOutlineShape(OutlineShapeEvent e) {
+ return getOutlineShapeM(e).raw();
+ }
+
+ @Override
+ @Deprecated
+ public net.minecraft.world.level.material.FluidState getFluidState(FluidStateArgs args) {
+ return getFluidStateM(args).getRaw();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/block/v3/CompatBlockEntity.java b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v3/CompatBlockEntity.java
new file mode 100644
index 000000000..493a6fc08
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/block/v3/CompatBlockEntity.java
@@ -0,0 +1,34 @@
+package net.pitan76.mcpitanlib.api.block.v3;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.level.block.entity.BlockEntityType;
+import net.minecraft.world.level.block.state.BlockState;
+import net.pitan76.mcpitanlib.api.event.block.TileCreateEvent;
+import net.pitan76.mcpitanlib.api.registry.CompatRegistryLookup;
+import net.pitan76.mcpitanlib.midohra.block.entity.BlockEntityTypeWrapper;
+import net.pitan76.mcpitanlib.midohra.nbt.NbtCompound;
+
+public class CompatBlockEntity extends net.pitan76.mcpitanlib.api.tile.CompatBlockEntity {
+ public CompatBlockEntity(BlockEntityType> type, BlockPos pos, BlockState state) {
+ super(type, pos, state);
+ }
+
+ public CompatBlockEntity(BlockEntityType> type, TileCreateEvent event) {
+ super(type, event);
+ }
+
+ public CompatBlockEntity(BlockEntityTypeWrapper type, TileCreateEvent event) {
+ super(type, event);
+ }
+
+ public NbtCompound toInitChunkDataNbt(CompatRegistryLookup registryLookup) {
+ return NbtCompound.of(super.toInitialChunkDataNbt(registryLookup));
+ }
+
+ @Override
+ @Deprecated
+ public CompoundTag toInitialChunkDataNbt(CompatRegistryLookup registryLookup) {
+ return toInitChunkDataNbt(registryLookup).toMinecraft();
+ }
+}
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..e20a330ab
--- /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.world.entity.player.Inventory;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.Identifier;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+@Deprecated
+public abstract class CompatInventoryScreen extends SimpleInventoryScreen {
+
+ public CompatInventoryScreen(AbstractContainerMenu handler, Inventory inventory, Component 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..8c61a7640
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleHandledScreen.java
@@ -0,0 +1,318 @@
+package net.pitan76.mcpitanlib.api.client;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.GuiGraphicsExtractor;
+import net.minecraft.client.gui.components.Renderable;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
+import net.minecraft.client.input.KeyEvent;
+import net.minecraft.client.renderer.item.ItemModelResolver;
+import net.minecraft.world.entity.player.Inventory;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.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.api.util.client.ScreenUtil;
+import net.pitan76.mcpitanlib.core.datafixer.Pair;
+
+@Deprecated
+public abstract class SimpleHandledScreen extends AbstractContainerScreen {
+
+ public int width, height, backgroundWidth, backgroundHeight, x, y;
+ public AbstractContainerMenu handler;
+ public Font textRenderer;
+ public ItemModelResolver itemRenderer;
+
+ public Component title;
+ public Minecraft client;
+ public SimpleHandledScreen(AbstractContainerMenu handler, Inventory inventory, Component title) {
+ super(handler, inventory, title);
+ fixScreen();
+ this.handler = handler;
+ this.title = title;
+
+ }
+
+ public T addDrawableChild_compatibility(T drawableElement) {
+ return super.addRenderableWidget(drawableElement);
+ // addButton
+ }
+
+ public T addSelectableChild_compatibility(T selectableElement) {
+ return super.addWidget(selectableElement);
+ }
+
+ public CompatibleTexturedButtonWidget addDrawableCTBW(CompatibleTexturedButtonWidget widget) {
+ return addDrawableChild_compatibility(widget);
+ }
+
+ @Deprecated
+ @Override
+ public void extractBackground(GuiGraphicsExtractor context, int mouseX, int mouseY, float delta) {
+ super.extractBackground(context, mouseX, mouseY, delta);
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawBackgroundOverride(new DrawBackgroundArgs(drawObjectDM, delta, mouseX, mouseY));
+ }
+
+ public abstract void drawBackgroundOverride(DrawBackgroundArgs args);
+
+ @Deprecated
+ @Override
+ protected void extractLabels(GuiGraphicsExtractor context, int mouseX, int mouseY) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawForegroundOverride(new DrawForegroundArgs(drawObjectDM, mouseX, mouseY));
+ }
+
+ protected void drawForegroundOverride(DrawForegroundArgs args) {
+ super.extractLabels(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) {
+ ScreenUtil.RendererUtil.drawTexture(drawObjectDM, 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.extractMenuBackground(args.drawObjectDM.getContext());
+ }
+
+ public void callDrawMouseoverTooltip(DrawMouseoverTooltipArgs args) {
+ super.extractTooltip(args.drawObjectDM.getContext(), args.mouseX, args.mouseY);
+ }
+
+ public void renderOverride(RenderArgs args) {
+ super.extractRenderState(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void resizeOverride(Minecraft client, int width, int height) {
+ }
+
+ public void initOverride() {
+ }
+
+ @Deprecated
+ @Override
+ protected void init() {
+ super.init();
+ fixScreen();
+ initOverride();
+ }
+
+ @Deprecated
+ @Override
+ public void resize(int width, int height) {
+ super.resize(width, height);
+ fixScreen();
+ resizeOverride(Minecraft.getInstance(), width, height);
+ }
+
+ public void fixScreen() {
+ this.backgroundWidth = getBackgroundWidth();
+ this.backgroundHeight = getBackgroundHeight();
+ this.x = super.leftPos; //(this.width - this.backgroundWidth) / 2;
+ this.y = super.topPos; //(this.height - this.backgroundHeight) / 2;
+ this.textRenderer = super.font;
+ this.itemRenderer = Minecraft.getInstance().getItemModelResolver();
+ this.width = super.width;
+ this.height = super.height;
+ if (super.minecraft == null)
+ this.client = Minecraft.getInstance();
+ else
+ this.client = super.minecraft;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ super.leftPos = x;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ super.topPos = y;
+ }
+
+ public void setTextRenderer(Font textRenderer) {
+ this.textRenderer = textRenderer;
+ }
+
+ public void setItemRenderer(ItemModelResolver itemRenderer) {
+ this.itemRenderer = itemRenderer;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ super.width = width;
+ }
+
+ public void setBackgroundWidth(int backgroundWidth) {
+ this.backgroundWidth = backgroundWidth;
+ super.imageWidth = backgroundWidth;
+ }
+
+ public void setBackgroundHeight(int backgroundHeight) {
+ this.backgroundHeight = backgroundHeight;
+ super.imageHeight = backgroundHeight;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ super.height = height;
+ }
+
+ public int getBackgroundWidth() {
+ return super.imageWidth;
+ }
+
+ public int getBackgroundHeight() {
+ return super.imageHeight;
+ }
+
+ @Deprecated
+ @Override
+ public void extractRenderState(GuiGraphicsExtractor 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(new KeyEvent(args.keyCode, args.scanCode, args.modifiers));
+ }
+
+ public boolean keyPressed(KeyEventArgs args) {
+ return super.keyPressed(new KeyEvent(args.keyCode, args.scanCode, args.modifiers));
+ }
+
+ public void renderBackgroundTexture(RenderBackgroundTextureArgs args) {
+ if (getBackgroundTexture() != null)
+ Screen.extractMenuBackgroundTexture(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(KeyEvent input) {
+ return this.keyReleased(new KeyEventArgs(input.key(), input.scancode(), input.modifiers()));
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyPressed(KeyEvent input) {
+ return this.keyPressed(new KeyEventArgs(input.key(), input.scancode(), input.modifiers()));
+ }
+
+ @Deprecated
+ @Override
+ public void extractMenuBackground(GuiGraphicsExtractor context) {
+ this.renderBackgroundTexture(new RenderBackgroundTextureArgs(new DrawObjectDM(context, this), 0));
+ }
+
+ public void closeOverride() {
+ super.onClose();
+ }
+
+ public void removedOverride() {
+ super.removed();
+ }
+
+ @Override
+ public void onClose() {
+ closeOverride();
+ }
+
+ @Override
+ public void removed() {
+ removedOverride();
+ }
+
+ public Identifier getBackgroundTexture() {
+ return IdentifierUtil.from(getCompatBackgroundTexture());
+ }
+
+ public CompatIdentifier getCompatBackgroundTexture() {
+ return null;
+ }
+
+ public void setTitleX(int x) {
+ this.titleLabelX = x;
+ }
+
+ public void setTitleY(int y) {
+ this.titleLabelY = 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.width(title) / 2);
+ }
+
+ public int getTitleX() {
+ return titleLabelX;
+ }
+
+ public int getTitleY() {
+ return titleLabelY;
+ }
+
+ @Deprecated
+ @Override
+ public Component getTitle() {
+ return callGetTitle();
+ }
+
+ public Component callGetTitle() {
+ return super.getTitle();
+ }
+
+ public Pair getTitlePosP() {
+ return new Pair<>(getTitleX(), getTitleY());
+ }
+
+ public int getPlayerInvTitleX() {
+ return inventoryLabelX;
+ }
+
+ public int getPlayerInvTitleY() {
+ return inventoryLabelY;
+ }
+
+ public void setPlayerInvTitleX(int x) {
+ inventoryLabelX = x;
+ }
+
+ public void setPlayerInvTitleY(int y) {
+ inventoryLabelY = 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..c04f5ba63
--- /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.world.entity.player.Inventory;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.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(AbstractContainerMenu handler, Inventory inventory, Component 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..1464212bf
--- /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.screens.Screen;
+import net.minecraft.client.Options;
+import net.minecraft.network.chat.Component;
+
+public class SimpleOptionsScreen extends SimpleScreen {
+
+ protected final Screen parent;
+ protected final Options gameOptions;
+
+ public SimpleOptionsScreen(Component title, Screen parent, Options gameOptions) {
+ super(title);
+ this.parent = parent;
+ this.gameOptions = gameOptions;
+ }
+
+ @Override
+ public void removed() {
+ client.options.save();
+ }
+
+ @Override
+ public void onClose() {
+ 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..cc0f9f2cf
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/SimpleScreen.java
@@ -0,0 +1,195 @@
+package net.pitan76.mcpitanlib.api.client;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.GuiGraphicsExtractor;
+import net.minecraft.client.gui.components.Renderable;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.input.KeyEvent;
+import net.minecraft.client.renderer.item.ItemModelResolver;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.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.RenderUtil;
+import net.pitan76.mcpitanlib.api.util.client.ScreenUtil;
+
+public abstract class SimpleScreen extends Screen {
+
+ public int width, height;
+ public Font textRenderer;
+ public ItemModelResolver itemRenderer;
+
+ public Component title;
+ public Minecraft client;
+
+ public SimpleScreen(Component title) {
+ super(title);
+ fixScreen();
+ this.title = title;
+ }
+
+ public SimpleScreen(TextComponent title) {
+ this(title.getText());
+ }
+
+ public T addDrawableChild_compatibility(T drawableElement) {
+ return super.addRenderableWidget(drawableElement);
+ // addButton
+ }
+
+ public T addSelectableChild_compatibility(T selectableElement) {
+ return super.addWidget(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.RendererUtil.drawTexture(drawObjectDM, texture, x, y, u, v, width, height);
+ }
+
+ 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 extractBackground(GuiGraphicsExtractor context, int mouseX, int mouseY, float delta) {
+ renderBackground(new RenderArgs(new DrawObjectDM(context, this), mouseX, mouseY, delta));
+ }
+
+ public void renderBackground(RenderArgs args) {
+ super.extractBackground(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void render(RenderArgs args) {
+ super.extractRenderState(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void resizeOverride(Minecraft client, int width, int height) {
+ }
+
+ public void initOverride() {
+ }
+
+ @Deprecated
+ @Override
+ protected void init() {
+ super.init();
+ fixScreen();
+ initOverride();
+ }
+
+ @Deprecated
+ @Override
+ public void resize(int width, int height) {
+ super.resize(width, height);
+ fixScreen();
+ resizeOverride(Minecraft.getInstance(), width, height);
+ }
+
+ public void fixScreen() {
+ this.textRenderer = super.font;
+ this.itemRenderer = Minecraft.getInstance().getItemModelResolver();
+ this.width = super.width;
+ this.height = super.height;
+ if (super.minecraft == null)
+ this.client = Minecraft.getInstance();
+ else
+ this.client = super.minecraft;
+ }
+
+ public void setTextRenderer(Font textRenderer) {
+ this.textRenderer = textRenderer;
+ }
+
+ public void setItemRenderer(ItemModelResolver 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 extractRenderState(GuiGraphicsExtractor 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(new KeyEvent(args.keyCode, args.scanCode, args.modifiers));
+ }
+
+ public boolean keyPressed(KeyEventArgs args) {
+ return super.keyPressed(new KeyEvent(args.keyCode, args.scanCode, args.modifiers));
+ }
+
+ public void renderBackgroundTexture(RenderBackgroundTextureArgs args) {
+ if (getBackgroundTexture() != null)
+ Screen.extractMenuBackgroundTexture(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(KeyEvent keyInput) {
+ return this.keyReleased(new KeyEventArgs(keyInput.key(), keyInput.scancode(), keyInput.modifiers()));
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyPressed(KeyEvent keyInput) {
+ return this.keyPressed(new KeyEventArgs(keyInput.key(), keyInput.scancode(), keyInput.modifiers()));
+ }
+
+ @Deprecated
+ @Override
+ public void extractMenuBackground(GuiGraphicsExtractor context) {
+ this.renderBackgroundTexture(new RenderBackgroundTextureArgs(new DrawObjectDM(context, this), 0));
+ }
+
+ public void closeOverride() {
+ super.onClose();
+ }
+
+ public void removedOverride() {
+ super.removed();
+ }
+
+ @Override
+ public void onClose() {
+ 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..a0cbe1ee5
--- /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.client.renderer.block.BlockAndTintGetter;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.state.BlockState;
+import net.pitan76.mcpitanlib.midohra.world.BlockView;
+import org.jetbrains.annotations.Nullable;
+
+public class BlockColorEvent {
+ private final BlockState state;
+ private final BlockAndTintGetter world;
+ private final BlockPos pos;
+ private final int tintIndex;
+
+ public BlockColorEvent(BlockState state, @Nullable BlockAndTintGetter world, @Nullable BlockPos pos, int tintIndex) {
+ this.state = state;
+ this.world = world;
+ this.pos = pos;
+ this.tintIndex = tintIndex;
+ }
+
+ public BlockState getState() {
+ return state;
+ }
+
+ public BlockAndTintGetter 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
+ public 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..254841506
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/color/CompatBlockColorProvider.java
@@ -0,0 +1,54 @@
+package net.pitan76.mcpitanlib.api.client.color;
+
+import net.minecraft.client.color.block.BlockTintSource;
+import net.minecraft.client.renderer.block.BlockAndTintGetter;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.core.BlockPos;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface CompatBlockColorProvider {
+ default int getColor(BlockState state, @Nullable BlockAndTintGetter world, @Nullable BlockPos pos, int tintIndex) {
+ return getColor(new BlockColorEvent(state, world, pos, tintIndex));
+ }
+
+ int getColor(BlockColorEvent e);
+
+ class BuiltBlockTintSource implements BlockTintSource {
+ private final CompatBlockColorProvider provider;
+ private final int tintIndex;
+
+ public BuiltBlockTintSource(CompatBlockColorProvider provider, int tintIndex) {
+ this.provider = provider;
+ this.tintIndex = tintIndex;
+ }
+
+ @Override
+ public int color(BlockState state) {
+ return provider.getColor(new BlockColorEvent(state, null, null, tintIndex));
+ }
+
+ @Override
+ public int colorInWorld(BlockState state, BlockAndTintGetter level, BlockPos pos) {
+ return provider.getColor(new BlockColorEvent(state, level, pos, tintIndex));
+ }
+
+
+ @Override
+ public int colorAsTerrainParticle(BlockState state, BlockAndTintGetter level, BlockPos pos) {
+ return provider.getColor(new BlockColorEvent(state, level, pos, tintIndex));
+ }
+ }
+
+ default List toTintSource() {
+ List tintSources = new ArrayList<>();
+
+ // TODO: 16は適当な数。実際にはtintIndexの最大値に合わせて増やす必要があるかもしれない
+ for (int i = 0; i < 16; i++) {
+ tintSources.add(new BuiltBlockTintSource(this, i));
+ }
+ return tintSources;
+ }
+}
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..ef0efff4e
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/ItemTooltipRegistry.java
@@ -0,0 +1,11 @@
+package net.pitan76.mcpitanlib.api.client.event;
+
+import dev.architectury.injectables.annotations.ExpectPlatform;
+import net.pitan76.mcpitanlib.api.client.event.listener.ItemTooltipListener;
+
+public class ItemTooltipRegistry {
+ @ExpectPlatform
+ public static void registerItemTooltip(ItemTooltipListener listener) {
+
+ }
+}
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..87973b6bf
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/WorldRenderRegistry.java
@@ -0,0 +1,160 @@
+package net.pitan76.mcpitanlib.api.client.event;
+
+//import dev.architectury.injectables.annotations.ExpectPlatform;
+import net.pitan76.mcpitanlib.api.client.event.listener.BeforeBlockOutlineEvent;
+import net.pitan76.mcpitanlib.api.client.event.listener.BeforeBlockOutlineListener;
+import net.pitan76.mcpitanlib.api.client.event.listener.WorldRenderContext;
+import net.pitan76.mcpitanlib.api.client.event.listener.WorldRenderContextListener;
+import net.pitan76.mcpitanlib.api.util.client.ClientUtil;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Matrix4f;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WorldRenderRegistry {
+
+ public static List beforeBlockOutlineListeners = new ArrayList<>();
+ public static List worldRenderAfterLevelListeners = new ArrayList<>();
+
+ public static boolean isEmptyBlockOutlineListeners = true;
+ public static boolean isEmptyWorldRenderAfterLevelListeners = true;
+
+ public WorldRenderRegistry() {
+
+ }
+
+ //@ExpectPlatform
+ public static void registerWorldRenderBeforeBlockOutline(BeforeBlockOutlineListener listener) {
+ beforeBlockOutlineListeners.add(listener);
+ isEmptyBlockOutlineListeners = false;
+ //throw new AssertionError();
+ }
+
+ //@ExpectPlatform
+ public static void registerWorldRenderAfterLevel(WorldRenderContextListener listener) {
+ worldRenderAfterLevelListeners.add(listener);
+ isEmptyWorldRenderAfterLevelListeners = false;
+ //throw new AssertionError();
+ }
+// public static void _registerWorldRenderBeforeBlockOutline(BeforeBlockOutlineListener listener) {
+// WorldRenderEvents.BEFORE_BLOCK_OUTLINE.register(((worldRenderContext, renderState) -> listener.beforeBlockOutline(new BeforeBlockOutlineEvent(
+// new WorldRenderContext() {
+// @Override
+// public WorldRenderer getWorldRenderer() {
+// return worldRenderContext.worldRenderer();
+// }
+//
+// @Override
+// public MatrixStack getMatrixStack() {
+// return worldRenderContext.matrices();
+// }
+//
+// @Override
+// public float getTickDelta() {
+// return MinecraftClient.getInstance().getRenderTickCounter().getDynamicDeltaTicks();
+// }
+//
+// @Override
+// public Camera getCamera() {
+// return worldRenderContext.gameRenderer().getCamera();
+// }
+//
+// @Override
+// public GameRenderer getGameRenderer() {
+// return worldRenderContext.gameRenderer();
+// }
+//
+// @Override
+// public LightmapTextureManager getLightmapTextureManager() {
+// return getGameRenderer().getLightmapTextureManager();
+// }
+//
+// @Override
+// public Matrix4f getProjectionMatrix() {
+// return worldRenderContext.gameRenderer().getBasicProjectionMatrix(0);
+// }
+//
+// @Override
+// public ClientWorld getWorld() {
+// return ClientUtil.getWorld();
+// }
+//
+// @Override
+// public boolean isAdvancedTranslucency() {
+// return renderState.isTranslucent();
+// }
+//
+// @Override
+// public VertexConsumerProvider getConsumers() {
+// return worldRenderContext.consumers();
+// }
+//
+// @Override
+// public Frustum getFrustum() {
+// return worldRenderContext.worldRenderer().getCapturedFrustum();
+// }
+// }, renderState))));
+// }
+//
+// public static void _registerWorldRenderAfterLevel(WorldRenderContextListener listener) {
+// WorldRenderEvents.END_MAIN.register((context -> {
+// listener.render(new WorldRenderContext() {
+// @Override
+// public WorldRenderer getWorldRenderer() {
+// return context.worldRenderer();
+// }
+//
+// @Override
+// public MatrixStack getMatrixStack() {
+// return context.matrices();
+// }
+//
+// @Override
+// public float getTickDelta() {
+// return MinecraftClient.getInstance().getRenderTickCounter().getDynamicDeltaTicks();
+// }
+//
+// @Override
+// public Camera getCamera() {
+// return context.gameRenderer().getCamera();
+// }
+//
+// @Override
+// public GameRenderer getGameRenderer() {
+// return context.gameRenderer();
+// }
+//
+// @Override
+// public LightmapTextureManager getLightmapTextureManager() {
+// return getGameRenderer().getLightmapTextureManager();
+// }
+//
+// @Override
+// public Matrix4f getProjectionMatrix() {
+// return context.gameRenderer().getBasicProjectionMatrix(0);
+// }
+//
+// @Override
+// public ClientWorld getWorld() {
+// return ClientUtil.getWorld();
+// }
+//
+// @Override
+// public boolean isAdvancedTranslucency() {
+// return true;
+// }
+//
+// @Override
+// public @Nullable VertexConsumerProvider getConsumers() {
+// return context.consumers();
+// }
+//
+// @Override
+// public @Nullable Frustum getFrustum() {
+// return context.worldRenderer().getCapturedFrustum();
+// }
+// });
+// }));
+// }
+}
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..36114a46b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/BeforeBlockOutlineEvent.java
@@ -0,0 +1,122 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.minecraft.client.renderer.state.level.BlockOutlineRenderState;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.client.Camera;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.minecraft.client.renderer.LevelRenderer;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.world.phys.BlockHitResult;
+import net.minecraft.world.phys.HitResult;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.phys.AABB;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import net.minecraft.world.level.Level;
+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, BlockOutlineRenderState renderState) {
+ this.context = context;
+ this.hitResult = context.getHitResult();
+ }
+
+ public BeforeBlockOutlineEvent(WorldRenderContext context, HitResult hitResult) {
+ this.context = context;
+ this.hitResult = hitResult;
+ }
+
+ public HitResult getHitResult() {
+ return hitResult;
+ }
+
+ public WorldRenderContext getContext() {
+ return context;
+ }
+
+ public LevelRenderer getWorldRenderer() {
+ return context.getWorldRenderer();
+ }
+
+ public Optional getBlockState() {
+ return Optional.ofNullable(getWorld().getBlockState(getBlockPos().orElse(null)));
+ }
+
+ public Level 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 PoseStack 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(AABB 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..a538df618
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/ItemTooltipContext.java
@@ -0,0 +1,68 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.TooltipFlag;
+import net.minecraft.network.chat.Component;
+import net.pitan76.mcpitanlib.api.text.TextComponent;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+
+import java.util.List;
+
+public class ItemTooltipContext {
+
+ public ItemStack stack;
+ public List texts;
+ public Item.TooltipContext tooltipContext;
+
+ @Deprecated
+ public TooltipFlag type;
+
+ public ItemTooltipContext(ItemStack stack, List texts, Item.TooltipContext tooltipContext, TooltipFlag 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 TooltipFlag getType() {
+ return type;
+ }
+
+ public void addTooltip(Component 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();
+ }
+
+ public void addTooltip(TextComponent textComponent) {
+ addTooltip(textComponent.getText());
+ }
+
+ public void addTooltip(String text) {
+ addTooltip(TextUtil.literal(text));
+ }
+}
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..dc83f5a08
--- /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.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.TooltipFlag;
+import net.minecraft.network.chat.Component;
+
+import java.util.List;
+
+@FunctionalInterface
+public interface ItemTooltipListener {
+ void onTooltip(ItemTooltipContext context);
+
+ default void onTooltip(ItemStack stack, List texts, Item.TooltipContext tooltipContext, TooltipFlag 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..ce15a1e54
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContext.java
@@ -0,0 +1,151 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.Camera;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.client.renderer.LevelRenderer;
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.culling.Frustum;
+import net.minecraft.client.renderer.rendertype.RenderTypes;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.client.Minecraft;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.client.multiplayer.ClientLevel;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.phys.BlockHitResult;
+import net.minecraft.world.phys.HitResult;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.phys.AABB;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import net.pitan76.mcpitanlib.api.client.render.CompatMatrixStack;
+import net.pitan76.mcpitanlib.api.util.VoxelShapeUtil;
+import net.pitan76.mcpitanlib.api.util.client.render.VertexRenderingUtil;
+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 {
+
+ LevelRenderer getWorldRenderer();
+
+ PoseStack getMatrixStack();
+
+ float getTickDelta();
+
+ Camera getCamera();
+
+ GameRenderer getGameRenderer();
+
+// LightTexture getLightmapTextureManager();
+
+ @Deprecated
+ Matrix4f getProjectionMatrix();
+
+ ClientLevel getWorld();
+
+ @Deprecated
+ boolean isAdvancedTranslucency();
+
+ @Nullable MultiBufferSource 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 Minecraft.getInstance().hitResult;
+ }
+
+ 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.getShape(getWorld(),
+ getBlockPos().orElse(null)));
+ }
+
+ default void push() {
+ getMatrixStack().pushPose();
+ }
+
+ default void translate(double x, double y, double z) {
+ getMatrixStack().translate(x, y, z);
+ }
+
+ default void pop() {
+ getMatrixStack().popPose();
+ }
+
+ default CompatMatrixStack getCompatMatrices() {
+ return CompatMatrixStack.of(getMatrixStack());
+ }
+
+ default Optional getVertexConsumer() {
+ if (getConsumers() == null)
+ return Optional.empty();
+
+ return Optional.of(Objects.requireNonNull(getConsumers()).getBuffer(RenderTypes.lines()));
+ }
+
+ 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(AABB box, float red, float green, float blue, float alpha) {
+ Optional vertexConsumer = getVertexConsumer();
+
+ if (!vertexConsumer.isPresent())
+ return;
+
+ VertexConsumer consumer = vertexConsumer.get();
+
+ double x1 = box.minX;
+ double y1 = box.minY;
+ double z1 = box.minZ;
+ double x2 = box.maxX;
+ double y2 = box.maxY;
+ double z2 = box.maxZ;
+
+ VertexRenderingUtil.drawBox(getMatrixStack(), consumer, x1, y1, z1, x2, y2, z2, 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/WorldRenderContextImpl.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContextImpl.java
new file mode 100644
index 000000000..fd7c04ec6
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/event/listener/WorldRenderContextImpl.java
@@ -0,0 +1,118 @@
+package net.pitan76.mcpitanlib.api.client.event.listener;
+
+import net.minecraft.client.Camera;
+import net.minecraft.client.DeltaTracker;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.client.renderer.LevelRenderer;
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.culling.Frustum;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.client.multiplayer.ClientLevel;
+import com.mojang.math.Axis;
+import net.minecraft.world.phys.Vec3;
+import net.pitan76.mcpitanlib.api.util.client.ClientUtil;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Matrix4f;
+
+public class WorldRenderContextImpl implements WorldRenderContext {
+
+ public LevelRenderer worldRenderer;
+ public PoseStack matrixStack;
+ public float tickDelta;
+ public Camera camera;
+ public GameRenderer gameRenderer;
+// public LightTexture lightmapTextureManager;
+ public Matrix4f projectionMatrix;
+ public ClientLevel world;
+ public boolean advancedTranslucency;
+ public @Nullable MultiBufferSource consumers;
+ public @Nullable Frustum frustum;
+
+ @Override
+ public LevelRenderer getWorldRenderer() {
+ return worldRenderer;
+ }
+
+ @Override
+ public PoseStack getMatrixStack() {
+ return matrixStack;
+ }
+
+ @Override
+ public float getTickDelta() {
+ return tickDelta;
+ }
+
+ @Override
+ public Camera getCamera() {
+ if (camera == null) {
+ return getGameRenderer().getMainCamera();
+ }
+ return camera;
+ }
+
+ @Override
+ public GameRenderer getGameRenderer() {
+ if (gameRenderer == null) {
+ return ClientUtil.getGameRenderer();
+ }
+ return gameRenderer;
+ }
+
+// @Override
+// public LightTexture getLightmapTextureManager() {
+// return lightmapTextureManager;
+// }
+
+ @Override
+ public Matrix4f getProjectionMatrix() {
+ return projectionMatrix;
+ }
+
+ @Override
+ public ClientLevel getWorld() {
+ if (world == null) {
+ return ClientUtil.getWorld();
+ }
+ return world;
+ }
+
+ @Override
+ public boolean isAdvancedTranslucency() {
+ return advancedTranslucency;
+ }
+
+ @Override
+ public @Nullable MultiBufferSource getConsumers() {
+ return consumers;
+ }
+
+ @Override
+ public @Nullable Frustum getFrustum() {
+ return frustum;
+ }
+
+ public void prepare(GameRenderer gameRenderer, LevelRenderer worldRenderer, @Nullable ClientLevel world, DeltaTracker tickCounter, boolean renderBlockOutline, Camera camera, Matrix4f positionMatrix, Matrix4f matrix4f, Matrix4f projectionMatrix) {
+ this.gameRenderer = gameRenderer;
+ this.worldRenderer = worldRenderer;
+ this.world = world;
+ this.camera = camera;
+ this.matrixStack = new PoseStack();
+ this.matrixStack.mulPose(projectionMatrix);
+ this.matrixStack.pushPose();
+
+ matrixStack.mulPose(Axis.YP.rotationDegrees(-camera.yRot()));
+ matrixStack.mulPose(Axis.XP.rotationDegrees(camera.xRot()));
+
+ Vec3 camPos = camera.position();
+ matrixStack.translate(-camPos.x, -camPos.y, -camPos.z);
+
+ this.matrixStack.popPose();
+
+ this.projectionMatrix = projectionMatrix;;
+ this.tickDelta = tickCounter.getGameTimeDeltaTicks();
+ this.frustum = gameRenderer.getMainCamera().getCapturedFrustum();
+ }
+
+
+}
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..9691117f6
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/CompatInventoryScreen.java
@@ -0,0 +1,39 @@
+package net.pitan76.mcpitanlib.api.client.gui.screen;
+
+import net.minecraft.world.entity.player.Inventory;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.world.inventory.Slot;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.Identifier;
+import net.pitan76.mcpitanlib.api.client.render.DrawObjectDM;
+import net.pitan76.mcpitanlib.api.text.TextComponent;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.inventory.CompatPlayerInventory;
+import net.pitan76.mcpitanlib.guilib.api.render.SlotRenderer;
+
+public abstract class CompatInventoryScreen extends SimpleInventoryScreen {
+
+ public CompatInventoryScreen(S handler, Inventory inventory, Component title) {
+ super(handler, inventory, title);
+ }
+
+ public CompatInventoryScreen(S handler, CompatPlayerInventory inventory, TextComponent title) {
+ this(handler, inventory.getRaw(), title.getText());
+ }
+
+ 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..df09019ac
--- /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.network.chat.Component;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+
+public class ScreenTexts {
+ public static final Component ON = TextUtil.translatable("options.on");
+ public static final Component OFF = TextUtil.translatable("options.off");
+ public static final Component DONE = TextUtil.translatable("gui.done");
+ public static final Component CANCEL = TextUtil.translatable("gui.cancel");
+ public static final Component YES = TextUtil.translatable("gui.yes");
+ public static final Component NO = TextUtil.translatable("gui.no");
+ public static final Component PROCEED = TextUtil.translatable("gui.proceed");
+ public static final Component BACK = TextUtil.translatable("gui.back");
+ public static final Component CONNECT_FAILED = TextUtil.translatable("connect.failed");
+ public static final Component LINE_BREAK = TextUtil.literal("\n");
+ public static final Component 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..788253e2f
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleHandledScreen.java
@@ -0,0 +1,422 @@
+package net.pitan76.mcpitanlib.api.client.gui.screen;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.GuiGraphicsExtractor;
+import net.minecraft.client.gui.components.Renderable;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
+import net.minecraft.client.input.CharacterEvent;
+import net.minecraft.client.input.KeyEvent;
+import net.minecraft.client.input.MouseButtonEvent;
+import net.minecraft.client.renderer.item.ItemModelResolver;
+import net.minecraft.world.entity.player.Inventory;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.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.api.util.inventory.CompatPlayerInventory;
+import net.pitan76.mcpitanlib.core.datafixer.Pair;
+
+public abstract class SimpleHandledScreen extends AbstractContainerScreen {
+
+ public int width, height, backgroundWidth, backgroundHeight, x, y;
+ public S handler;
+ public Font textRenderer;
+ public ItemModelResolver itemRenderer;
+
+ public Component title;
+ public Minecraft client;
+ public SimpleHandledScreen(S handler, Inventory inventory, Component title) {
+ super(handler, inventory, title);
+ fixScreen();
+ this.handler = handler;
+ this.title = title;
+ }
+
+ public SimpleHandledScreen(S handler, CompatPlayerInventory inventory, TextComponent title) {
+ this(handler, inventory.getRaw(), title.getText());
+ }
+
+ @Deprecated
+ @Override
+ public S getMenu() {
+ return getScreenHandlerOverride();
+ }
+
+ public S getScreenHandlerOverride() {
+ return super.getMenu();
+ }
+
+ public T addDrawableChild_compatibility(T drawableElement) {
+ return super.addRenderableWidget(drawableElement);
+ // addButton
+ }
+
+ public T addSelectableChild_compatibility(T selectableElement) {
+ return super.addWidget(selectableElement);
+ }
+
+ public CompatibleTexturedButtonWidget addDrawableCTBW(CompatibleTexturedButtonWidget widget) {
+ return addDrawableChild_compatibility(widget);
+ }
+
+ @Deprecated
+ @Override
+ public void extractBackground(GuiGraphicsExtractor context, int mouseX, int mouseY, float delta) {
+ super.extractBackground(context, mouseX, mouseY, delta);
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawBackgroundOverride(new DrawBackgroundArgs(drawObjectDM, delta, mouseX, mouseY));
+ }
+
+ public abstract void drawBackgroundOverride(DrawBackgroundArgs args);
+
+ @Deprecated
+ @Override
+ protected void extractLabels(GuiGraphicsExtractor context, int mouseX, int mouseY) {
+ DrawObjectDM drawObjectDM = new DrawObjectDM(context, this);
+ drawForegroundOverride(new DrawForegroundArgs(drawObjectDM, mouseX, mouseY));
+ }
+
+ protected void drawForegroundOverride(DrawForegroundArgs args) {
+ super.extractLabels(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) {
+ ScreenUtil.RendererUtil.drawTexture(drawObjectDM, texture, x, y, u, v, width, height);
+ }
+
+ 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) {
+ // TODO: 以前のバージョンではどう機能しているかチェックする必要がある。このバージョンで利用すると全体が暗くなる
+ // super.extractBackground(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void callDrawMouseoverTooltip(DrawMouseoverTooltipArgs args) {
+ super.extractTooltip(args.drawObjectDM.getContext(), args.mouseX, args.mouseY);
+ }
+
+ public void renderOverride(RenderArgs args) {
+ super.extractRenderState(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ public void resizeOverride(Minecraft client, int width, int height) {
+ }
+
+ public void initOverride() {
+ }
+
+ @Deprecated
+ @Override
+ protected void init() {
+ super.init();
+ fixScreen();
+ initOverride();
+ }
+
+ @Deprecated
+ @Override
+ public void resize(int width, int height) {
+ super.resize(width, height);
+ fixScreen();
+ resizeOverride(Minecraft.getInstance(), width, height);
+ }
+
+ public void fixScreen() {
+ this.backgroundWidth = getBackgroundWidth();
+ this.backgroundHeight = getBackgroundHeight();
+ this.x = super.leftPos; //(this.width - this.backgroundWidth) / 2;
+ this.y = super.topPos; //(this.height - this.backgroundHeight) / 2;
+ this.textRenderer = super.font;
+ this.itemRenderer = Minecraft.getInstance().getItemModelResolver();
+ this.width = super.width;
+ this.height = super.height;
+ if (super.minecraft == null)
+ this.client = Minecraft.getInstance();
+ else
+ this.client = super.minecraft;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ super.leftPos = x;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ super.topPos = y;
+ }
+
+ public void setTextRenderer(Font textRenderer) {
+ this.textRenderer = textRenderer;
+ }
+
+ public void setItemRenderer(ItemModelResolver itemRenderer) {
+ this.itemRenderer = itemRenderer;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ super.width = width;
+ }
+
+ public void setBackgroundWidth(int backgroundWidth) {
+ this.backgroundWidth = backgroundWidth;
+ super.imageWidth = backgroundWidth;
+ }
+
+ public void setBackgroundHeight(int backgroundHeight) {
+ this.backgroundHeight = backgroundHeight;
+ super.imageHeight = backgroundHeight;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ super.height = height;
+ }
+
+ public int getBackgroundWidth() {
+ return super.imageWidth;
+ }
+
+ public int getBackgroundHeight() {
+ return super.imageHeight;
+ }
+
+ @Deprecated
+ @Override
+ public void extractRenderState(GuiGraphicsExtractor 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(new KeyEvent(args.keyCode, args.scanCode, args.modifiers));
+ }
+
+ public boolean keyPressed(KeyEventArgs args) {
+ return super.keyPressed(new KeyEvent(args.keyCode, args.scanCode, args.modifiers));
+ }
+
+ public void renderBackgroundTexture(RenderBackgroundTextureArgs args) {
+ if (getBackgroundTexture() != null)
+ Screen.extractMenuBackgroundTexture(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(KeyEvent input) {
+ return this.keyReleased(new KeyEventArgs(input.key(), input.scancode(), input.modifiers()));
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyPressed(KeyEvent input) {
+ return this.keyPressed(new KeyEventArgs(input.key(), input.scancode(), input.modifiers()));
+ }
+
+ @Deprecated
+ @Override
+ public void extractMenuBackground(GuiGraphicsExtractor context) {
+ callRenderBackground(new RenderArgs(new DrawObjectDM(context, this), 0, 0, 0));
+ }
+
+ public void closeOverride() {
+ super.onClose();
+ }
+
+ public void removedOverride() {
+ super.removed();
+ }
+
+ @Override
+ public void onClose() {
+ closeOverride();
+ }
+
+ @Override
+ public void removed() {
+ removedOverride();
+ }
+
+ public Identifier getBackgroundTexture() {
+ return IdentifierUtil.from(getCompatBackgroundTexture());
+ }
+
+ public CompatIdentifier getCompatBackgroundTexture() {
+ return null;
+ }
+
+ public void setTitleX(int x) {
+ this.titleLabelX = x;
+ }
+
+ public void setTitleY(int y) {
+ this.titleLabelY = 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.width(title) / 2);
+ }
+
+ public int getTitleX() {
+ return titleLabelX;
+ }
+
+ public int getTitleY() {
+ return titleLabelY;
+ }
+
+ public void drawText(DrawObjectDM drawObjectDM, Component 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, Component 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 Component getTitle() {
+ return callGetTitle();
+ }
+
+ public Component callGetTitle() {
+ return super.getTitle();
+ }
+
+ public Pair getTitlePosP() {
+ return new Pair<>(getTitleX(), getTitleY());
+ }
+
+ public int getPlayerInvTitleX() {
+ return inventoryLabelX;
+ }
+
+ public int getPlayerInvTitleY() {
+ return inventoryLabelY;
+ }
+
+ public void setPlayerInvTitleX(int x) {
+ inventoryLabelX = x;
+ }
+
+ public void setPlayerInvTitleY(int y) {
+ inventoryLabelY = y;
+ }
+
+ public void setPlayerInvTitle(int x, int y) {
+ setPlayerInvTitleX(x);
+ setPlayerInvTitleY(y);
+ }
+
+ public Font callGetTextRenderer() {
+ if (textRenderer != null)
+ return textRenderer;
+
+ if (super.getFont() != null)
+ return super.getFont();
+
+ return ClientUtil.getTextRenderer();
+ }
+
+ public ItemModelResolver callGetItemRenderer() {
+ if (itemRenderer != null)
+ return itemRenderer;
+
+ return ClientUtil.getItemRenderer();
+ }
+
+ public Component getPlayerInvTitle() {
+ return playerInventoryTitle;
+ }
+
+ public boolean charTyped(CharEventArgs args) {
+ return super.charTyped(new CharacterEvent(args.getCharacter()));
+ }
+
+ @Deprecated
+ @Override
+ public boolean charTyped(CharacterEvent event) {
+ return charTyped(new CharEventArgs(event.codepoint()));
+ }
+
+ public boolean mouseScrolled(MouseScrolledArgs args) {
+ return super.mouseScrolled(args.getMouseX(), args.getMouseY(), args.getScrollX(), args.getScrollY());
+ }
+
+ @Deprecated
+ @Override
+ public boolean mouseScrolled(double x, double y, double scrollX, double scrollY) {
+ return mouseScrolled(new MouseScrolledArgs(x, y, scrollX, scrollY));
+ }
+
+ public boolean mouseClicked(MouseClickedArgs args) {
+ return super.mouseClicked(new MouseButtonEvent(args.getX(), args.getY(), args.getButtonInfo()), args.isDoubleClick());
+ }
+
+ @Deprecated
+ @Override
+ public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) {
+ return mouseClicked(new MouseClickedArgs(event.x(), event.y(), event.buttonInfo(), doubleClick));
+ }
+
+ public boolean mouseDragged(MouseDraggedArgs args) {
+ return super.mouseDragged(new MouseButtonEvent(args.getX(), args.getY(), args.getButtonInfo()), args.getDeltaX(), args.getDeltaY());
+ }
+
+ @Deprecated
+ @Override
+ public boolean mouseDragged(MouseButtonEvent event, double dx, double dy) {
+ return mouseDragged(new MouseDraggedArgs(event.x(), event.y(), event.buttonInfo(), dx, dy));
+ }
+
+ public boolean mouseReleased(MouseReleasedArgs args) {
+ return super.mouseReleased(new MouseButtonEvent(args.getX(), args.getY(), args.getButtonInfo()));
+ }
+
+ @Deprecated
+ @Override
+ public boolean mouseReleased(MouseButtonEvent event) {
+ return mouseReleased(new MouseReleasedArgs(event.x(), event.y(), event.buttonInfo()));
+ }
+}
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..39b5f47a4
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/screen/SimpleInventoryScreen.java
@@ -0,0 +1,44 @@
+package net.pitan76.mcpitanlib.api.client.gui.screen;
+
+import net.minecraft.world.entity.player.Inventory;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.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.text.TextComponent;
+import net.pitan76.mcpitanlib.api.util.client.RenderUtil;
+import net.pitan76.mcpitanlib.api.util.inventory.CompatPlayerInventory;
+
+public abstract class SimpleInventoryScreen extends SimpleHandledScreen {
+
+ public SimpleInventoryScreen(S handler, Inventory inventory, Component title) {
+ super(handler, inventory, title);
+ }
+
+ public SimpleInventoryScreen(S handler, CompatPlayerInventory inventory, TextComponent title) {
+ this(handler, inventory.getRaw(), title.getText());
+ }
+
+ 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..349b51deb
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatTextFieldWidget.java
@@ -0,0 +1,145 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.components.EditBox;
+import net.minecraft.client.input.CharacterEvent;
+import net.minecraft.client.input.KeyEvent;
+import net.minecraft.network.chat.Component;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+import org.jetbrains.annotations.Nullable;
+
+public class CompatTextFieldWidget extends EditBox {
+ public CompatTextFieldWidget(Font textRenderer, int width, int height) {
+ this(textRenderer, width, height, TextUtil.empty());
+ }
+
+ public CompatTextFieldWidget(Font textRenderer, int x, int y, int width, int height) {
+ this(textRenderer, x, y, width, height, TextUtil.empty());
+ }
+
+ // ----
+
+ public CompatTextFieldWidget(Font textRenderer, int width, int height, Component text) {
+ super(textRenderer, width, height, text);
+ }
+
+ public CompatTextFieldWidget(Font textRenderer, int x, int y, int width, int height, Component text) {
+ super(textRenderer, x, y, width, height, text);
+ }
+
+ public CompatTextFieldWidget(Font textRenderer, int x, int y, int width, int height, @Nullable EditBox copyFrom, Component text) {
+ super(textRenderer, x, y, width, height, copyFrom, text);
+ }
+
+ // ----
+
+ @Deprecated
+ @Override
+ public void setBordered(boolean drawsBackground) {
+ callSetDrawsBackground(drawsBackground);
+ }
+
+ public void callSetDrawsBackground(boolean drawsBackground) {
+ super.setBordered(drawsBackground);
+ }
+
+ @Deprecated
+ @Override
+ public void setFocused(boolean focused) {
+ callSetFocused(focused);
+ }
+
+ public void callSetFocused(boolean focused) {
+ super.setFocused(focused);
+ }
+
+ @Deprecated
+ @Override
+ public void setCanLoseFocus(boolean focusUnlocked) {
+ callSetFocusUnlocked(focusUnlocked);
+ }
+
+ public void callSetFocusUnlocked(boolean focusUnlocked) {
+ super.setCanLoseFocus(focusUnlocked);
+ }
+
+ @Deprecated
+ @Override
+ public void setMaxLength(int maxLength) {
+ callSetMaxLength(maxLength);
+ }
+
+ public void callSetMaxLength(int maxLength) {
+ super.setMaxLength(maxLength);
+ }
+
+ @Deprecated
+ @Override
+ public void setValue(String text) {
+ callSetText(text);
+ }
+
+ public void callSetText(String text) {
+ super.setValue(text);
+ }
+
+ @Deprecated
+ @Override
+ public String getValue() {
+ return callGetText();
+ }
+
+ public String callGetText() {
+ return super.getValue();
+ }
+
+ @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(KeyEvent input) {
+ return callKeyPressed(input.key(), input.scancode(), input.modifiers());
+ }
+
+ public boolean callKeyPressed(int keyCode, int scanCode, int modifiers) {
+ return super.keyPressed(new KeyEvent(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public boolean keyReleased(KeyEvent input) {
+ return callKeyReleased(input.key(), input.scancode(), input.modifiers());
+ }
+
+ public boolean callKeyReleased(int keyCode, int scanCode, int modifiers) {
+ return super.keyReleased(new KeyEvent(keyCode, scanCode, modifiers));
+ }
+
+ @Deprecated
+ @Override
+ public boolean charTyped(CharacterEvent input) {
+ return callCharTyped((char) input.codepoint(), -1);
+ }
+
+ public boolean callCharTyped(char chr, int modifiers) {
+ return super.charTyped(new CharacterEvent(chr));
+ }
+}
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..ddceb64de
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/CompatibleTexturedButtonWidget.java
@@ -0,0 +1,74 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.minecraft.client.gui.GuiGraphicsExtractor;
+import net.minecraft.client.renderer.RenderPipelines;
+import net.minecraft.client.gui.components.WidgetSprites;
+import net.minecraft.client.gui.components.Button;
+import net.minecraft.client.gui.components.ImageButton;
+import net.minecraft.resources.Identifier;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.TextUtil;
+
+public class CompatibleTexturedButtonWidget extends ImageButton {
+ 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, Button.OnPress 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, Button.OnPress 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, Button.OnPress 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, Button.OnPress pressAction, net.minecraft.network.chat.Component text) {
+ super(x, y, width, height, new WidgetSprites(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, Button.OnPress 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, Button.OnPress 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, Button.OnPress 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, Button.OnPress pressAction, net.minecraft.network.chat.Component 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 extractContents(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta) {
+ int i = v;
+ if (this.createNarrationMessage().toString().isEmpty()) {
+ i = v + hoveredVOffset * 2;
+ } else if (this.isHovered()) {
+ i += hoveredVOffset;
+ }
+
+ graphics.blit(RenderPipelines.GUI_TEXTURED, 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..b157c5c43
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/RedrawableTexturedButtonWidget.java
@@ -0,0 +1,46 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.minecraft.resources.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, OnPress pressAction, net.minecraft.network.chat.Component 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 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..f09f5d8f5
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleListWidget.java
@@ -0,0 +1,114 @@
+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.Minecraft;
+import net.minecraft.client.gui.GuiGraphicsExtractor;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
+import net.minecraft.client.gui.components.AbstractWidget;
+import net.minecraft.client.gui.components.ContainerObjectSelectionList;
+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 ContainerObjectSelectionList {
+
+ public SimpleListWidget(Minecraft client, int width, int height, int top, int bottom, int itemHeight) {
+ this(client, width, bottom - top, top, itemHeight);
+ }
+
+ public SimpleListWidget(Minecraft client, int width, int height, int y, int itemHeight) {
+ super(client, width, height, y, itemHeight);
+ this.centerListVertically = false;
+ }
+
+ public void add(AbstractWidget 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 scrollBarX() {
+ return super.scrollBarX() + 32;
+ }
+
+ @Nullable
+ public AbstractWidget 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.extractWidgetRenderState(args.drawObjectDM.getContext(), args.mouseX, args.mouseY, args.delta);
+ }
+
+ @Environment(EnvType.CLIENT)
+ public static class WidgetEntry extends Entry {
+ protected final AbstractWidget widget;
+
+ public WidgetEntry(AbstractWidget widget) {
+ this.widget = widget;
+ }
+
+ public static WidgetEntry create(AbstractWidget widget) {
+ return new WidgetEntry(widget);
+ }
+
+ @Deprecated
+ @Override
+ public void extractContent(GuiGraphicsExtractor context, int mouseX, int mouseY, boolean hovered, float deltaTicks) {
+ widget.extractRenderState(context, mouseX, mouseY, deltaTicks);
+ }
+
+ @Deprecated
+ @Override
+ public List extends GuiEventListener> children() {
+ return ImmutableList.of(widget);
+ }
+
+ @Deprecated
+ @Override
+ public List extends NarratableEntry> narratables() {
+ return ImmutableList.of(widget);
+ }
+
+ public AbstractWidget 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..a8571e6c9
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/gui/widget/SimpleSliderWidget.java
@@ -0,0 +1,80 @@
+package net.pitan76.mcpitanlib.api.client.gui.widget;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.gui.components.AbstractSliderButton;
+import net.minecraft.network.chat.Component;
+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 AbstractSliderButton {
+ protected final Function textGetter;
+ protected final Consumer changeCallback;
+ public SimpleListWidget listWidget = null;
+
+ public SimpleSliderWidget(int x, int y, int width, int height, Component 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, Component 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, Component 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.extractRenderState(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 {
+ Component get(Component 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..1681b0053
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/option/CompatKeyBinding.java
@@ -0,0 +1,83 @@
+package net.pitan76.mcpitanlib.api.client.option;
+
+import net.minecraft.client.KeyMapping;
+import net.minecraft.client.input.KeyEvent;
+import net.minecraft.network.chat.Component;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class CompatKeyBinding {
+ private final KeyMapping keyBinding;
+ public static final Map categories = new HashMap<>();
+
+ public CompatKeyBinding(KeyMapping keyBinding) {
+ this.keyBinding = keyBinding;
+ }
+
+ public CompatKeyBinding(String translationKey, int defaultKeyCode, CompatIdentifier category) {
+ KeyMapping.Category cat;
+
+ if (categories.containsKey(category)) {
+ cat = categories.get(category);
+ } else {
+ cat = KeyMapping.Category.register(category.toMinecraft());
+ categories.put(category, cat);
+ }
+
+ this.keyBinding = new KeyMapping(translationKey, defaultKeyCode, cat);
+ }
+
+ 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");
+ KeyMapping.Category cat;
+
+ if (categories.containsKey(category)) {
+ cat = categories.get(category);
+ } else {
+ cat = KeyMapping.Category.register(category.toMinecraft());
+ categories.put(category, cat);
+ }
+
+ this.keyBinding = new KeyMapping(translationKey, defaultKeyCode, cat);
+ } else {
+ throw new IllegalArgumentException("Cannot infer category from translation key: " + translationKey);
+ }
+ }
+
+ public String getTranslationKey() {
+ return keyBinding.saveString();
+ }
+
+ public Component getBoundKeyLocalizedText() {
+ return keyBinding.getTranslatedKeyMessage();
+ }
+
+ public int getDefaultKeyCode() {
+ return keyBinding.getDefaultKey().getValue();
+ }
+
+ 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 KeyMapping toMinecraft() {
+ return keyBinding;
+ }
+
+ public KeyMapping getRaw() {
+ return keyBinding;
+ }
+
+ public boolean matches(int keyCode, int scanCode, int modifiers) {
+ return keyBinding.matches(new KeyEvent(keyCode, scanCode, modifiers));
+ }
+}
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..141034cf5
--- /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.Options;
+
+public class GameOptionsWrapper {
+ public final Options raw;
+
+ public GameOptionsWrapper(Options options) {
+ this.raw = options;
+ }
+
+ public Options getRaw() {
+ return raw;
+ }
+
+ public void write() {
+ raw.save();
+ }
+}
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..e2868c3ee
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/ArchRegistryClient.java
@@ -0,0 +1,179 @@
+package net.pitan76.mcpitanlib.api.client.registry;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.renderer.block.BlockModelResolver;
+import net.minecraft.client.renderer.item.ItemModelResolver;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.BlockEntityType;
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.gui.screens.inventory.MenuAccess;
+import net.minecraft.client.model.geom.ModelPart;
+import net.minecraft.client.particle.ParticleProvider;
+import net.minecraft.client.particle.SpriteSet;
+import net.minecraft.client.renderer.rendertype.RenderType;
+import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
+import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
+import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
+import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
+import net.minecraft.client.renderer.entity.EntityRendererProvider;
+import net.minecraft.client.model.geom.ModelLayerLocation;
+import net.minecraft.client.model.geom.EntityModelSet;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.player.Inventory;
+import net.minecraft.world.level.material.Fluid;
+import net.minecraft.core.particles.ParticleOptions;
+import net.minecraft.core.particles.ParticleType;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.world.inventory.MenuType;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.Identifier;
+import net.minecraft.util.RandomSource;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+@Deprecated
+@Environment(EnvType.CLIENT)
+public class ArchRegistryClient {
+ public static > void registerScreen(MenuType extends H> type, ScreenFactory factory) {
+ CompatRegistryClient.registerScreen(type, factory::create);
+ }
+
+ public interface ScreenFactory> {
+ S create(H handler, Inventory inventory, Component text);
+ }
+
+ public static void registerParticle(ParticleType type, ParticleProvider factory) {
+ CompatRegistryClient.registerParticle(type, factory);
+ }
+
+ public static void registerParticle(ParticleType type, DeferredParticleProvider provider) {
+ CompatRegistryClient.registerParticle(type, (spriteSet -> provider.create(new ExtendedSpriteSet() {
+ @Override
+ public TextureAtlas getAtlas() {
+ return spriteSet.getAtlas();
+ }
+
+ @Override
+ public List getSprites() {
+ return spriteSet.getSprites();
+ }
+
+ @Override
+ public TextureAtlasSprite get(int index, int max) {
+ return spriteSet.get(index, max);
+ }
+
+ @Override
+ public TextureAtlasSprite get(RandomSource random) {
+ return spriteSet.get(random);
+ }
+
+ @Override
+ public TextureAtlasSprite first() {
+ return spriteSet.first();
+ }
+ })));
+ }
+
+ public static void registerEntityRenderer(Supplier extends EntityType extends T>> type, EntityRendererProvider provider) {
+ CompatRegistryClient.registerEntityRenderer(type, provider);
+ }
+
+ @FunctionalInterface
+ public interface DeferredParticleProvider {
+ ParticleProvider create(ExtendedSpriteSet spriteSet);
+ }
+
+ public interface ExtendedSpriteSet extends SpriteSet {
+ TextureAtlas getAtlas();
+
+ List getSprites();
+ }
+
+ public static void registryClientSpriteAtlasTexture(Identifier identifier) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, identifier);
+ }
+
+ public static void registryClientSpriteAtlasTexture(TextureAtlasSprite sprite) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, sprite);
+ }
+
+ public static void registryClientSprite(Identifier atlasId, Identifier identifier) {
+ // ~1.19.2
+ }
+
+ public static void registryClientSprite(Identifier atlasId, TextureAtlasSprite sprite) {
+ // ~1.19.2
+ }
+
+ public static void registerBlockEntityRenderer(BlockEntityType type, BlockEntityRendererFactory provider) {
+ CompatRegistryClient.registerBlockEntityRenderer(type, (ctx) -> provider.create(new BlockEntityRendererFactory.Context(ctx.getRenderDispatcher(), ctx.getRenderManager(), ctx.getItemModelManager(), ctx.getEntityRenderDispatcher(), ctx.getLayerRenderDispatcher(), ctx.getTextRenderer())));
+ }
+
+ @FunctionalInterface
+ public interface BlockEntityRendererFactory {
+ BlockEntityRenderer create(BlockEntityRendererFactory.Context ctx);
+
+ class Context {
+ private final BlockEntityRenderDispatcher renderDispatcher;
+ private final BlockModelResolver renderManager;
+ private final ItemModelResolver itemRenderer;
+ private final EntityRenderDispatcher entityRenderDispatcher;
+ private final EntityModelSet layerRenderDispatcher;
+ private final Font textRenderer;
+
+ public Context(BlockEntityRenderDispatcher renderDispatcher, BlockModelResolver renderManager, ItemModelResolver itemRenderer, EntityRenderDispatcher entityRenderDispatcher, EntityModelSet layerRenderDispatcher, Font 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 BlockModelResolver getRenderManager() {
+ return this.renderManager;
+ }
+
+ public EntityRenderDispatcher getEntityRenderDispatcher() {
+ return this.entityRenderDispatcher;
+ }
+
+ public ItemModelResolver getItemRenderer() {
+ return this.itemRenderer;
+ }
+
+ public EntityModelSet getLayerRenderDispatcher() {
+ return this.layerRenderDispatcher;
+ }
+
+ public ModelPart getLayerModelPart(ModelLayerLocation modelLayer) {
+ return this.layerRenderDispatcher.bakeLayer(modelLayer);
+ }
+
+ public Font getTextRenderer() {
+ return this.textRenderer;
+ }
+ }
+ }
+
+
+ public static void registerRenderTypeBlock(RenderType layer, Block block) {
+ CompatRegistryClient.registerRenderTypeBlock(layer, block);
+ }
+
+ public static void registerRenderTypeFluid(RenderType layer, Fluid fluid) {
+ CompatRegistryClient.registerRenderTypeFluid(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..cad03cf8b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/CompatRegistryClient.java
@@ -0,0 +1,258 @@
+package net.pitan76.mcpitanlib.api.client.registry;
+
+import dev.architectury.injectables.annotations.ExpectPlatform;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.color.block.BlockTintSource;
+import net.minecraft.client.renderer.block.BlockModelResolver;
+import net.minecraft.client.resources.model.sprite.SpriteGetter;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.BlockEntityType;
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.gui.screens.inventory.MenuAccess;
+import net.minecraft.client.renderer.item.ItemModelResolver;
+import net.minecraft.client.model.geom.ModelPart;
+import net.minecraft.client.particle.ParticleProvider;
+import net.minecraft.client.particle.SpriteSet;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
+import net.minecraft.client.renderer.rendertype.RenderType;
+import net.minecraft.client.renderer.rendertype.RenderTypes;
+import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
+import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
+import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
+import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
+import net.minecraft.client.renderer.entity.EntityRendererProvider;
+import net.minecraft.client.model.geom.ModelLayerLocation;
+import net.minecraft.client.model.geom.EntityModelSet;
+import net.minecraft.client.renderer.PlayerSkinRenderCache;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.player.Inventory;
+import net.minecraft.world.level.material.Fluid;
+import net.minecraft.core.particles.ParticleOptions;
+import net.minecraft.core.particles.ParticleType;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import net.minecraft.world.inventory.MenuType;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.Identifier;
+import net.pitan76.mcpitanlib.MCPitanLib;
+import net.pitan76.mcpitanlib.api.client.color.CompatBlockColorProvider;
+import net.pitan76.mcpitanlib.api.client.gui.screen.SimpleHandledScreen;
+import net.pitan76.mcpitanlib.api.client.render.CompatRenderLayer;
+import net.pitan76.mcpitanlib.api.client.render.EntityModelLayerContext;
+import net.pitan76.mcpitanlib.api.gui.SimpleScreenHandler;
+import net.pitan76.mcpitanlib.api.text.TextComponent;
+import net.pitan76.mcpitanlib.api.util.inventory.CompatPlayerInventory;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+@Environment(EnvType.CLIENT)
+public class CompatRegistryClient {
+ public static > void registerScreen(MenuType extends H> type, ScreenFactory factory) {
+ registerScreen(MCPitanLib.MOD_ID, type, factory);
+ }
+
+ public static & MenuAccess> void registerScreen(MenuType extends H> type, ScreenFactory2 factory) {
+ registerScreen(MCPitanLib.MOD_ID, type, factory);
+ }
+
+ @ExpectPlatform
+ public static > void registerScreen(String modId, MenuType extends H> type, ScreenFactory factory) {
+ throw new AssertionError();
+ }
+
+ public static & MenuAccess> void registerScreen(String modId, MenuType extends H> type, ScreenFactory2 factory) {
+ registerScreen(modId, type, factory);
+ }
+
+ public interface ScreenFactory> {
+ S create(H handler, Inventory inventory, Component text);
+ }
+
+ public interface ScreenFactory2 & MenuAccess> extends ScreenFactory {
+ @Override
+ default S create(H handler, Inventory inventory, Component text) {
+ return create(handler, new CompatPlayerInventory(inventory), new TextComponent(text));
+ }
+
+ S create(H handler, CompatPlayerInventory inventory, TextComponent text);
+ }
+
+ @ExpectPlatform
+ public static void registerParticle(ParticleType type, ParticleProvider factory) {
+ throw new AssertionError();
+ }
+
+ @ExpectPlatform
+ public static void registerParticle(ParticleType type, DeferredParticleProvider provider) {
+ throw new AssertionError();
+ }
+
+ @ExpectPlatform
+ public static void registerEntityModelLayer(ModelLayerLocation layer, EntityModelLayerContext context) {
+ throw new AssertionError();
+ }
+
+ @ExpectPlatform
+ public static void registerEntityRenderer(Supplier extends EntityType extends T>> type, EntityRendererProvider provider) {
+ throw new AssertionError();
+ }
+
+ @FunctionalInterface
+ public interface DeferredParticleProvider {
+ ParticleProvider create(ExtendedSpriteSet spriteSet);
+ }
+
+ public interface ExtendedSpriteSet extends SpriteSet {
+ TextureAtlas getAtlas();
+
+ List getSprites();
+ }
+
+ public static void registryClientSpriteAtlasTexture(Identifier identifier) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, identifier);
+ }
+
+ public static void registryClientSpriteAtlasTexture(TextureAtlasSprite sprite) {
+ //registryClientSprite(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, sprite);
+ }
+
+ public static void registryClientSprite(Identifier atlasId, Identifier identifier) {
+ // ~1.19.2
+ }
+
+ public static void registryClientSprite(Identifier atlasId, TextureAtlasSprite sprite) {
+ // ~1.19.2
+ }
+
+ @ExpectPlatform
+ public static void registerBlockEntityRenderer(BlockEntityType type, BlockEntityRendererFactory provider) {
+ throw new AssertionError();
+ }
+
+ @FunctionalInterface
+ public interface BlockEntityRendererFactory {
+ BlockEntityRenderer create(Context ctx);
+
+ class Context {
+ private final BlockEntityRenderDispatcher renderDispatcher;
+ private final BlockModelResolver renderManager;
+ private final ItemModelResolver itemModelManager;
+ private final EntityRenderDispatcher entityRenderDispatcher;
+ private final EntityModelSet layerRenderDispatcher;
+ private final Font textRenderer;
+ private final SpriteGetter spriteHolder;
+
+ private final PlayerSkinRenderCache playerSkinRenderCache;
+
+ public Context(BlockEntityRenderDispatcher renderDispatcher, BlockModelResolver renderManager, ItemModelResolver itemModelManager, EntityRenderDispatcher entityRenderDispatcher, EntityModelSet layerRenderDispatcher, Font textRenderer, SpriteGetter spriteHolder, PlayerSkinRenderCache playerSkinRenderCache) {
+ this.renderDispatcher = renderDispatcher;
+ this.renderManager = renderManager;
+ this.itemModelManager = itemModelManager;
+ this.entityRenderDispatcher = entityRenderDispatcher;
+ this.layerRenderDispatcher = layerRenderDispatcher;
+ this.textRenderer = textRenderer;
+ this.spriteHolder = spriteHolder;
+ this.playerSkinRenderCache = playerSkinRenderCache;
+ }
+
+ public BlockEntityRenderDispatcher getRenderDispatcher() {
+ return this.renderDispatcher;
+ }
+
+ public BlockModelResolver getRenderManager() {
+ return this.renderManager;
+ }
+
+ public EntityRenderDispatcher getEntityRenderDispatcher() {
+ return this.entityRenderDispatcher;
+ }
+
+ public ItemModelResolver getItemModelManager() {
+ return itemModelManager;
+ }
+
+ public EntityModelSet getLayerRenderDispatcher() {
+ return this.layerRenderDispatcher;
+ }
+
+ public ModelPart getLayerModelPart(ModelLayerLocation modelLayer) {
+ return this.layerRenderDispatcher.bakeLayer(modelLayer);
+ }
+
+ public Font getTextRenderer() {
+ return this.textRenderer;
+ }
+
+ public SpriteGetter getSpriteHolder() {
+ return spriteHolder;
+ }
+
+ public PlayerSkinRenderCache getPlayerSkinRenderCache() {
+ return playerSkinRenderCache;
+ }
+ }
+ }
+
+
+ public static void registerRenderTypeBlock(RenderType layer, Block block) {
+ ChunkSectionLayer blockRenderLayer = null;
+ if (layer == RenderTypes.cutoutMovingBlock()) {
+ blockRenderLayer = ChunkSectionLayer.CUTOUT;
+ } else if (layer == RenderTypes.glintTranslucent()) {
+ blockRenderLayer = ChunkSectionLayer.TRANSLUCENT;
+ } else if (layer == RenderTypes.solidMovingBlock()) {
+ blockRenderLayer = ChunkSectionLayer.SOLID;
+ }
+
+ if (blockRenderLayer == null) return;
+
+// ChunkSectionLayerMap.register(blockRenderLayer, block);
+ }
+
+ public static void registerRenderTypeFluid(RenderType layer, Fluid fluid) {
+ ChunkSectionLayer blockRenderLayer = null;
+ if (layer == RenderTypes.cutoutMovingBlock()) {
+ blockRenderLayer = ChunkSectionLayer.CUTOUT;
+ } else if (layer == RenderTypes.glintTranslucent()) {
+ blockRenderLayer = ChunkSectionLayer.TRANSLUCENT;
+ } else if (layer == RenderTypes.solidMovingBlock()) {
+ blockRenderLayer = ChunkSectionLayer.SOLID;
+ }
+
+ if (blockRenderLayer == null) return;
+
+// ChunkSectionLayerMap.register(blockRenderLayer, fluid);
+ }
+
+ public static void registerCutoutBlock(Block block) {
+ registerRenderTypeBlock(RenderTypes.cutoutMovingBlock(), block);
+ }
+
+ @ExpectPlatform
+ public static void registerCompatBlockEntityRenderer(BlockEntityType type, BlockEntityRendererFactory provider) {
+
+ }
+
+ 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(List provider, Block... blocks) {
+ throw new AssertionError();
+ }
+
+ public static void registerColorProviderBlock(CompatBlockColorProvider provider, Block... blocks) {
+ registerColorProviderBlock(provider.toTintSource(), 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..56564d8e1
--- /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.renderer.entity.EntityRenderer;
+import net.minecraft.client.renderer.entity.ThrownItemRenderer;
+import net.minecraft.world.entity.EntityType;
+
+import java.util.function.Supplier;
+
+public class EntityRendererRegistry {
+ public static void registerEntityRendererAsFlyingItem(Supplier> entityType) {
+ CompatRegistryClient.registerEntityRenderer(entityType, (ctx -> (EntityRenderer) new ThrownItemRenderer<>(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..dca6d41e1
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/KeybindingRegistry.java
@@ -0,0 +1,39 @@
+package net.pitan76.mcpitanlib.api.client.registry;
+
+import dev.architectury.injectables.annotations.ExpectPlatform;
+import net.minecraft.client.KeyMapping;
+import net.minecraft.resources.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 {
+ @ExpectPlatform
+ public static void register(KeyMapping keyBinding) {
+
+ }
+
+ public static void register(KeyMapping keyBinding, ClientTickEventRegistry.Client client) {
+ register(keyBinding);
+ ClientTickEventRegistry.registerPost(client);
+ }
+
+ public static void registerOnLevel(KeyMapping keyBinding, ClientTickEventRegistry.ClientLevel level) {
+ register(keyBinding);
+ ClientTickEventRegistry.registerLevelPost(level);
+ }
+
+ public static void registerWithNetwork(KeyMapping keyBinding, Identifier identifier) {
+ register(keyBinding, client -> {
+ if (keyBinding.consumeClick())
+ ClientNetworking.send(identifier, PacketByteUtil.create());
+ });
+ }
+
+ public static void registerOnLevelWithNetwork(KeyMapping keyBinding, Identifier identifier) {
+ registerOnLevel(keyBinding, client -> {
+ if (keyBinding.consumeClick())
+ 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..c6279645b
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/registry/v2/KeybindingRegistry.java
@@ -0,0 +1,24 @@
+package net.pitan76.mcpitanlib.api.client.registry.v2;
+
+import net.minecraft.client.KeyMapping;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+public class KeybindingRegistry extends net.pitan76.mcpitanlib.api.client.registry.KeybindingRegistry {
+
+ public static void registerWithNetwork(KeyMapping keyBinding, CompatIdentifier identifier) {
+ registerWithNetwork(keyBinding, identifier.toMinecraft());
+ }
+
+ public static void registerOnLevelWithNetwork(KeyMapping keyBinding, CompatIdentifier identifier) {
+ registerOnLevelWithNetwork(keyBinding, identifier.toMinecraft());
+ }
+
+ public static void registerWithNetwork(String translationKey, int code, String category, CompatIdentifier identifier) {
+ registerWithNetwork(new KeyMapping(translationKey, code, KeyMapping.Category.register(CompatIdentifier.of(category).toMinecraft())), identifier);
+ }
+
+ public static void registerOnLevelWithNetwork(String translationKey, int code, String category, CompatIdentifier identifier) {
+ // TODO: categoryの互換性
+ registerOnLevelWithNetwork(new KeyMapping(translationKey, code, KeyMapping.Category.register(CompatIdentifier.of(category).toMinecraft())), 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/CompatMatrix3x2fStack.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatMatrix3x2fStack.java
new file mode 100644
index 000000000..10fefbc48
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatMatrix3x2fStack.java
@@ -0,0 +1,48 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.pitan76.mcpitanlib.api.util.MathUtil;
+import org.joml.Matrix3x2fStack;
+
+public class CompatMatrix3x2fStack extends CompatMatrixStack {
+ private final Matrix3x2fStack matrices;
+
+ public CompatMatrix3x2fStack(Matrix3x2fStack matrices) {
+ super(null);
+ this.matrices = matrices;
+ }
+
+ @Deprecated
+ public Matrix3x2fStack get3x2fRaw() {
+ return matrices;
+ }
+
+ public CompatMatrix3x2fStack push() {
+ get3x2fRaw().pushMatrix();
+ return this;
+ }
+
+ public CompatMatrix3x2fStack pop() {
+ get3x2fRaw().popMatrix();
+ return this;
+ }
+
+ public CompatMatrix3x2fStack translate(double x, double y, double z) {
+ get3x2fRaw().translate((float) x, (float) y);
+ return this;
+ }
+
+ @Override
+ public CompatMatrixStack translate(float x, float y, float z) {
+ get3x2fRaw().translate(x, y);
+ return this;
+ }
+
+ public CompatMatrix3x2fStack scale(float x, float y, float z) {
+ get3x2fRaw().scale(x, y);
+ return this;
+ }
+
+ public CompatMatrix3x2fStack multiply(MathUtil.RotationAxisType type, float deg) {
+ return this;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatMatrixStack.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatMatrixStack.java
new file mode 100644
index 000000000..ad3962cac
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatMatrixStack.java
@@ -0,0 +1,51 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.pitan76.mcpitanlib.api.util.MathUtil;
+import net.pitan76.mcpitanlib.api.util.client.MatrixStackUtil;
+
+public class CompatMatrixStack {
+ private final com.mojang.blaze3d.vertex.PoseStack matrices;
+
+ public CompatMatrixStack(com.mojang.blaze3d.vertex.PoseStack matrices) {
+ this.matrices = matrices;
+ }
+
+ public static CompatMatrixStack of(com.mojang.blaze3d.vertex.PoseStack matrixStack) {
+ return new CompatMatrixStack(matrixStack);
+ }
+
+ @Deprecated
+ public com.mojang.blaze3d.vertex.PoseStack getRaw() {
+ return matrices;
+ }
+
+ public CompatMatrixStack push() {
+ MatrixStackUtil.push(getRaw());
+ return this;
+ }
+
+ public CompatMatrixStack pop() {
+ MatrixStackUtil.pop(getRaw());
+ return this;
+ }
+
+ public CompatMatrixStack translate(double x, double y, double z) {
+ MatrixStackUtil.translate(getRaw(), x, y, z);
+ return this;
+ }
+
+ public CompatMatrixStack translate(float x, float y, float z) {
+ getRaw().translate(x, y, z);
+ return this;
+ }
+
+ public CompatMatrixStack scale(float x, float y, float z) {
+ MatrixStackUtil.scale(getRaw(), x, y, z);
+ return this;
+ }
+
+ public CompatMatrixStack multiply(MathUtil.RotationAxisType type, float deg) {
+ MatrixStackUtil.multiply(getRaw(), type, deg);
+ return this;
+ }
+}
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..5cdf9e8f6
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/CompatRenderLayer.java
@@ -0,0 +1,46 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.minecraft.client.renderer.rendertype.RenderType;
+import net.minecraft.client.renderer.rendertype.RenderTypes;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+
+public class CompatRenderLayer {
+ public static final CompatRenderLayer CUTOUT = new CompatRenderLayer(RenderTypes.cutoutMovingBlock());
+ public static final CompatRenderLayer CUTOUT_MIPPED = new CompatRenderLayer(RenderTypes.cutoutMovingBlock());
+ public static final CompatRenderLayer TRANSLUCENT = new CompatRenderLayer(RenderTypes.glintTranslucent());
+ public static final CompatRenderLayer TRANSLUCENT_MOVING_BLOCK = new CompatRenderLayer(RenderTypes.translucentMovingBlock());
+ public static final CompatRenderLayer SOLID = new CompatRenderLayer(RenderTypes.solidMovingBlock());
+ public static final CompatRenderLayer LINES = new CompatRenderLayer(RenderTypes.lines());
+ public static final CompatRenderLayer LINE_STRIP = new CompatRenderLayer(RenderTypes.linesTranslucent());
+ public static final CompatRenderLayer GLINT = new CompatRenderLayer(RenderTypes.glint());
+
+ public final RenderType layer;
+
+ public CompatRenderLayer(RenderType layer) {
+ this.layer = layer;
+ }
+
+ public RenderType raw() {
+ return layer;
+ }
+
+ public static CompatRenderLayer getEntityCutout(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderTypes.entityCutoutCull(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getEntityCutoutNoCull(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderTypes.entityCutout(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getEntityTranslucent(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderTypes.entityTranslucent(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getArmorCutoutNoCull(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderTypes.armorCutoutNoCull(id.toMinecraft()));
+ }
+
+ public static CompatRenderLayer getEntitySolid(CompatIdentifier id) {
+ return new CompatRenderLayer(RenderTypes.entitySolid(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..8b50aeb1a
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/DrawObjectDM.java
@@ -0,0 +1,110 @@
+package net.pitan76.mcpitanlib.api.client.render;
+
+import net.minecraft.client.gui.GuiGraphicsExtractor;
+import net.minecraft.client.gui.screens.Screen;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.network.chat.Component;
+import net.pitan76.mcpitanlib.api.text.TextComponent;
+import net.pitan76.mcpitanlib.api.util.CompatIdentifier;
+import net.pitan76.mcpitanlib.api.util.client.ScreenUtil.RendererUtil;
+import org.joml.Matrix3x2fStack;
+
+import java.util.List;
+
+public class DrawObjectDM {
+ private PoseStack stack;
+ private Matrix3x2fStack matrix3x2fStack;
+ private GuiGraphicsExtractor context;
+
+ private Screen screen = null;
+
+ public DrawObjectDM(GuiGraphicsExtractor context) {
+ this.context = context;
+ this.matrix3x2fStack = context.pose();
+ }
+
+ public DrawObjectDM(Matrix3x2fStack matrix3x2fStack) {
+ this.matrix3x2fStack = matrix3x2fStack;
+ }
+
+ public DrawObjectDM(PoseStack stack) {
+ this.stack = stack;
+ }
+
+ public DrawObjectDM(GuiGraphicsExtractor context, Screen screen) {
+ this(context);
+ this.screen = screen;
+ }
+
+ public GuiGraphicsExtractor getContext() {
+ return context;
+ }
+
+ public PoseStack getStack() {
+ return stack;
+ }
+
+ public Screen getScreen() {
+ return screen;
+ }
+
+ public void setContext(GuiGraphicsExtractor context) {
+ this.context = context;
+ }
+
+ public void setStack(PoseStack 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(Component text, int x, int y) {
+ RendererUtil.drawText(RendererUtil.getTextRenderer(), this, text, x, y);
+ }
+
+ public void drawTooltip(Component 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 drawTooltip(List texts, int x, int y) {
+ RendererUtil.drawTooltip2(this, texts, 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;
+ }
+
+ public CompatMatrixStack getMatrixStack() {
+ return new CompatMatrix3x2fStack(context.pose());
+ }
+}
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..c69abb2f5
--- /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.renderer.texture.OverlayTexture;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.pitan76.mcpitanlib.api.util.client.render.VertexConsumerUtil;
+import org.joml.Matrix3f;
+import org.joml.Matrix4f;
+
+public class DrawObjectMV {
+ private final PoseStack stack;
+ private final VertexConsumer buffer;
+
+ public DrawObjectMV(PoseStack stack, VertexConsumer buffer) {
+ this.stack = stack;
+ this.buffer = buffer;
+ }
+
+ public DrawObjectMV(PoseStack stack) {
+ this(stack, null);
+ }
+
+ public DrawObjectMV(VertexConsumer buffer) {
+ this(null, buffer);
+ }
+
+ public PoseStack 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.last().pose();
+
+ return matrix4f;
+ }
+
+ public Matrix3f getMatrix3f() {
+ if (matrix3f == null)
+ matrix3f = stack.last().normal();
+
+ 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..6655fb13e
--- /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.geom.builders.MeshDefinition;
+
+public class EntityModelLayerContext {
+ private final MeshDefinition data;
+ private final int width;
+ private final int height;
+
+ public EntityModelLayerContext(MeshDefinition 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 MeshDefinition 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..0d631b3d6
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/CompatBlockEntityRenderer.java
@@ -0,0 +1,45 @@
+package net.pitan76.mcpitanlib.api.client.render.block.entity;
+
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
+import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
+import net.minecraft.client.renderer.SubmitNodeCollector;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.client.renderer.state.level.CameraRenderState;
+import net.minecraft.world.phys.Vec3;
+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);
+
+ default void render(T entity, float tickProgress, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, Vec3 cameraPos) {
+ render(new BlockEntityRenderEvent<>(this, entity, tickProgress, matrices, vertexConsumers, light, overlay));
+ }
+
+ @Override
+ default void submit(S state, PoseStack matrices, SubmitNodeCollector queue, CameraRenderState cameraState) {
+ render(new BlockEntityRenderEvent<>(this, state, matrices, queue, cameraState));
+ }
+
+ default boolean rendersOutsideBoundingBoxOverride(T blockEntity) {
+ return BlockEntityRenderer.super.shouldRenderOffScreen();
+ }
+
+ default int getRenderDistanceOverride() {
+ return BlockEntityRenderer.super.getViewDistance();
+ }
+
+ @Deprecated
+ @Override
+ default boolean shouldRenderOffScreen() {
+ return rendersOutsideBoundingBoxOverride(null);
+ }
+
+ @Deprecated
+ @Override
+ default int getViewDistance() {
+ 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..6928a24c4
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/event/BlockEntityRenderEvent.java
@@ -0,0 +1,204 @@
+package net.pitan76.mcpitanlib.api.client.render.block.entity.event;
+
+import net.minecraft.client.renderer.item.ItemModelResolver;
+import net.minecraft.client.renderer.state.level.CameraRenderState;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.rendertype.RenderType;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
+import net.minecraft.client.renderer.SubmitNodeCollector;
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.core.BlockPos;
+import net.pitan76.mcpitanlib.api.client.registry.CompatRegistryClient;
+import net.pitan76.mcpitanlib.api.client.render.CompatMatrixStack;
+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 PoseStack matrices;
+ public MultiBufferSource vertexConsumers;
+ int light;
+ int overlay;
+
+ public BlockEntityRenderEvent(T blockEntity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay) {
+ this.blockEntity = blockEntity;
+ this.tickDelta = tickDelta;
+ this.matrices = matrices;
+ this.vertexConsumers = vertexConsumers;
+ this.light = light;
+ this.overlay = overlay;
+ }
+
+ private BlockEntityRenderState state;
+ private SubmitNodeCollector queue;
+ private CameraRenderState cameraState;
+
+
+ public BlockEntityRenderEvent(S state, PoseStack matrices, SubmitNodeCollector queue, CameraRenderState cameraState) {
+ this.state = state;
+ this.queue = queue;
+ this.cameraState = cameraState;
+
+ this.matrices = matrices;
+ this.queue = queue;
+ this.cameraState = cameraState;
+ this.tickDelta = Minecraft.getInstance().getDeltaTracker().getGameTimeDeltaTicks();
+ BlockEntity blockEntity = state.blockEntityType.getBlockEntity(Minecraft.getInstance().level, state.blockPos);
+ if (blockEntity instanceof CompatBlockEntity) {
+ this.blockEntity = (T) blockEntity;
+ } else {
+ //throw new IllegalArgumentException("BlockEntityRenderEvent: BlockEntity is not an instance of CompatBlockEntity");
+ }
+
+ this.vertexConsumers = Minecraft.getInstance().renderBuffers().bufferSource();
+ this.light = state.lightCoords;
+ if (state.breakProgress != null)
+ this.overlay = state.breakProgress.progress();
+ else
+ this.overlay = 0;
+ }
+
+ public T getBlockEntity() {
+ return blockEntity;
+ }
+
+ public PoseStack getMatrices() {
+ return matrices;
+ }
+
+ public float getTickDelta() {
+ return tickDelta;
+ }
+
+ public int getLight() {
+ return light;
+ }
+
+ public int getOverlay() {
+ return overlay;
+ }
+
+ public VertexConsumer getVertexConsumer(RenderType layer) {
+ return vertexConsumers.getBuffer(layer);
+ }
+
+ public VertexConsumer getVertexConsumer(CompatRenderLayer layer) {
+ return getVertexConsumer(layer.raw());
+ }
+
+ public MultiBufferSource 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 CompatMatrixStack getCompatMatrices() {
+ return CompatMatrixStack.of(matrices);
+ }
+
+ public ItemModelResolver 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.last().pose();
+
+ return matrix4f;
+ }
+
+ public Matrix3f getMatrix3f() {
+ if (matrix3f == null)
+ matrix3f = matrices.last().normal();
+
+ return matrix3f;
+ }
+
+ public BlockPos getPos() {
+ return state.blockPos;
+ }
+
+ 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, PoseStack matrices, MultiBufferSource 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 BlockEntityRenderEvent(CompatBlockEntityRenderer renderer, BlockEntityRenderState state, PoseStack matrices, SubmitNodeCollector queue, CameraRenderState cameraState) {
+ this(state, matrices, queue, cameraState);
+ 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());
+ }
+
+ @Deprecated
+ public SubmitNodeCollector getQueue() {
+ return queue;
+ }
+
+ @Deprecated
+ public BlockEntityRenderState getState() {
+ return state;
+ }
+
+ @Deprecated
+ public CameraRenderState getCameraState() {
+ return cameraState;
+ }
+}
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..6839a8f33
--- /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.renderer.blockentity.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..3bee38c06
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/block/entity/v2/CompatBlockEntityRenderer.java
@@ -0,0 +1,25 @@
+package net.pitan76.mcpitanlib.api.client.render.block.entity.v2;
+
+import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
+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;
+ }
+
+ @Override
+ public BlockEntityRenderState createRenderState() {
+ return new BlockEntityRenderState();
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/CharEventArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/CharEventArgs.java
new file mode 100644
index 000000000..934f2a628
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/CharEventArgs.java
@@ -0,0 +1,25 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+public class CharEventArgs {
+ private final int character;
+
+ public CharEventArgs(char character, int modifiers) {
+ this.character = character;
+ }
+
+ public CharEventArgs(int codepoint) {
+ this.character = codepoint;
+ }
+
+ public int getCharacter() {
+ return character;
+ }
+
+ public char getChar() {
+ return (char) character;
+ }
+
+ public int getModifiers() {
+ return 0;
+ }
+}
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/MouseButtonArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseButtonArgs.java
new file mode 100644
index 000000000..f1560c4f9
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseButtonArgs.java
@@ -0,0 +1,38 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.minecraft.client.input.MouseButtonInfo;
+
+public class MouseButtonArgs {
+ public final double mouseX, mouseY;
+ public MouseButtonInfo buttonInfo = null;
+
+ public MouseButtonArgs(double mouseX, double mouseY, MouseButtonInfo buttonInfo) {
+ this.mouseX = mouseX;
+ this.mouseY = mouseY;
+ this.buttonInfo = buttonInfo;
+ }
+
+ public MouseButtonArgs(double mouseX, double mouseY, int button) {
+ this.mouseX = mouseX;
+ this.mouseY = mouseY;
+ this.buttonInfo = new MouseButtonInfo(button, 0);
+ }
+
+ public double getX() {
+ return mouseX;
+ }
+
+ public double getY() {
+ return mouseY;
+ }
+
+ public int getButton() {
+ if (getButtonInfo() == null) return -1;
+ return getButtonInfo().button();
+ }
+
+ @Deprecated
+ public MouseButtonInfo getButtonInfo() {
+ return buttonInfo;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseClickedArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseClickedArgs.java
new file mode 100644
index 000000000..5e3a494c0
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseClickedArgs.java
@@ -0,0 +1,26 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.minecraft.client.input.MouseButtonInfo;
+
+public class MouseClickedArgs extends MouseButtonArgs {
+ public boolean doubleClick;
+
+ public MouseClickedArgs(double mouseX, double mouseY, MouseButtonInfo buttonInfo, boolean doubleClick) {
+ super(mouseX, mouseY, buttonInfo);
+ this.doubleClick = doubleClick;
+ }
+
+ public MouseClickedArgs(double mouseX, double mouseY, int button, boolean doubleClick) {
+ super(mouseX, mouseY, button);
+ this.doubleClick = doubleClick;
+ }
+
+ public MouseClickedArgs(double mouseX, double mouseY, int button) {
+ this(mouseX, mouseY, button, false);
+ }
+
+ @Deprecated
+ public boolean isDoubleClick() {
+ return doubleClick;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseDraggedArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseDraggedArgs.java
new file mode 100644
index 000000000..f7889533e
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseDraggedArgs.java
@@ -0,0 +1,29 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.minecraft.client.input.MouseButtonInfo;
+
+public class MouseDraggedArgs extends MouseButtonArgs {
+
+ public final double dx;
+ public final double dy;
+
+ public MouseDraggedArgs(double mouseX, double mouseY, MouseButtonInfo buttonInfo, double dx, double dy) {
+ super(mouseX, mouseY, buttonInfo);
+ this.dx = dx;
+ this.dy = dy;
+ }
+
+ public MouseDraggedArgs(double mouseX, double mouseY, int button, double dx, double dy) {
+ super(mouseX, mouseY, button);
+ this.dx = dx;
+ this.dy = dy;
+ }
+
+ public double getDeltaX() {
+ return dx;
+ }
+
+ public double getDeltaY() {
+ return dy;
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseReleasedArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseReleasedArgs.java
new file mode 100644
index 000000000..9fc2948a6
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseReleasedArgs.java
@@ -0,0 +1,14 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+import net.minecraft.client.input.MouseButtonInfo;
+
+public class MouseReleasedArgs extends MouseButtonArgs {
+
+ public MouseReleasedArgs(double mouseX, double mouseY, MouseButtonInfo buttonInfo) {
+ super(mouseX, mouseY, buttonInfo);
+ }
+
+ public MouseReleasedArgs(double mouseX, double mouseY, int button) {
+ super(mouseX, mouseY, button);
+ }
+}
diff --git a/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseScrolledArgs.java b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseScrolledArgs.java
new file mode 100644
index 000000000..0daf0c5b4
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/client/render/handledscreen/MouseScrolledArgs.java
@@ -0,0 +1,37 @@
+package net.pitan76.mcpitanlib.api.client.render.handledscreen;
+
+public class MouseScrolledArgs {
+ private final double mouseX;
+ private final double mouseY;
+ private final double scrollX;
+ private final double scrollY;
+ private final double amount;
+
+ public MouseScrolledArgs(double mouseX, double mouseY, double scrollX, double scrollY) {
+ this.mouseX = mouseX;
+ this.mouseY = mouseY;
+ this.scrollX = scrollX;
+ this.scrollY = scrollY;
+ this.amount = Math.sqrt(scrollX * scrollX + scrollY * scrollY);
+ }
+
+ public double getMouseX() {
+ return mouseX;
+ }
+
+ public double getMouseY() {
+ return mouseY;
+ }
+
+ public double getScrollX() {
+ return scrollX;
+ }
+
+ public double getScrollY() {
+ return scrollY;
+ }
+
+ public double getAmount() {
+ return amount;
+ }
+}
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..0e64f0485
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandRegistry.java
@@ -0,0 +1,106 @@
+package net.pitan76.mcpitanlib.api.command;
+
+import com.mojang.brigadier.builder.ArgumentBuilder;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import dev.architectury.injectables.annotations.ExpectPlatform;
+import net.minecraft.commands.CommandBuildContext;
+import net.minecraft.commands.Commands;
+import net.minecraft.commands.CommandSourceStack;
+import net.pitan76.mcpitanlib.api.command.argument.*;
+import net.pitan76.mcpitanlib.api.event.*;
+
+import java.util.Map;
+
+public class CommandRegistry {
+
+ @Deprecated
+ public static CommandBuildContext latestCommandRegistryAccess;
+
+ @ExpectPlatform
+ public static void register(String name, LiteralCommand command) {
+
+ }
+
+ @ExpectPlatform
+ public static void register(LiteralArgumentBuilder builder) {
+
+ }
+
+ @Deprecated
+ public 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 = Commands.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 = Commands.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..8e7326e64
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/command/CommandSettings.java
@@ -0,0 +1,43 @@
+package net.pitan76.mcpitanlib.api.command;
+
+import net.minecraft.server.permissions.Permission;
+import net.minecraft.server.permissions.PermissionLevel;
+import net.minecraft.commands.CommandSourceStack;
+
+public class CommandSettings {
+ private int permissionLevel = -1;
+ private ICustom iCustom = null;
+
+ private Permission.HasCommandLevel _level = null;
+
+ public boolean requires(CommandSourceStack source) {
+ if (customRequires(source)) {
+ if (permissionLevel == -1) return true;
+ if (_level == null)
+ _level = new Permission.HasCommandLevel(PermissionLevel.byId(permissionLevel));
+
+ return source.permissions().hasPermission(_level);
+ }
+ return false;
+ }
+
+ private boolean customRequires(CommandSourceStack 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(CommandSourceStack 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..992b43c29
--- /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.world.level.block.Block;
+import net.minecraft.commands.arguments.blocks.BlockStateArgument;
+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 BlockStateArgument getArgumentType() {
+ return BlockStateArgument.block(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..e30a2651b
--- /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.commands.arguments.EntityArgument;
+import net.minecraft.world.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.EntitiesCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class EntitiesCommand extends RequiredCommand {
+ @Override
+ public EntityArgument getArgumentType() {
+ return EntityArgument.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..0af7e0e0c
--- /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.commands.arguments.EntityArgument;
+import net.minecraft.world.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.EntityCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class EntityCommand extends RequiredCommand {
+ @Override
+ public EntityArgument getArgumentType() {
+ return EntityArgument.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..aeaac8193
--- /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.commands.arguments.item.ItemArgument;
+import net.minecraft.world.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 ItemArgument getArgumentType() {
+ return ItemArgument.item(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..c9e444c7d
--- /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.commands.arguments.EntityArgument;
+import net.minecraft.world.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.PlayerCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class PlayerCommand extends RequiredCommand {
+ @Override
+ public EntityArgument getArgumentType() {
+ return EntityArgument.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..0003ec262
--- /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.commands.arguments.EntityArgument;
+import net.minecraft.world.entity.Entity;
+import net.pitan76.mcpitanlib.api.event.PlayersCommandEvent;
+import net.pitan76.mcpitanlib.api.event.ServerCommandEvent;
+
+public abstract class PlayersCommand extends RequiredCommand {
+ @Override
+ public EntityArgument getArgumentType() {
+ return EntityArgument.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..a6a795834
--- /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.world.item.enchantment.Enchantment;
+import net.minecraft.world.item.enchantment.EnchantmentHelper;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.data.registries.VanillaRegistries;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.core.Holder;
+import net.minecraft.resources.Identifier;
+import net.minecraft.world.level.Level;
+import net.pitan76.mcpitanlib.api.util.EnchantmentUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Optional;
+
+public class CompatEnchantment {
+ private final ResourceKey registryKey;
+
+ @Deprecated
+ public CompatEnchantment(ResourceKey registryKey) {
+ this.registryKey = registryKey;
+ }
+
+ public CompatEnchantment of(Identifier identifier) {
+ return EnchantmentUtil.getEnchantment(identifier);
+ }
+
+ public Identifier getId() {
+ return registryKey.registry();
+ }
+
+ @Deprecated
+ public ResourceKey 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 Holder getEntry(@Nullable Level world) {
+ Optional> optionalEntry;
+ if (world == null) {
+ optionalEntry = VanillaRegistries.createLookup()
+ .get(registryKey);
+ } else {
+ optionalEntry = world.registryAccess().get(registryKey);
+ }
+
+ return optionalEntry.orElseThrow();
+ }
+
+ public Enchantment getEnchantment(@Nullable Level world) {
+ return getEntry(world).value();
+ }
+
+ public int getLevel(ItemStack stack, @Nullable Level world) {
+ return EnchantmentHelper.getItemEnchantmentLevel(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..2af53c486
--- /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.world.entity.ContainerUser;
+import net.minecraft.world.entity.LivingEntity;
+
+public class CompatContainerUser {
+ protected ContainerUser containerUser;
+
+ public CompatContainerUser(ContainerUser containerUser) {
+ this.containerUser = containerUser;
+ }
+
+ public double getContainerInteractionRange() {
+ return containerUser.getContainerInteractionRange();
+ }
+
+ public LivingEntity asLivingEntity() {
+ return containerUser.getLivingEntity();
+ }
+
+ public boolean isPlayer() {
+ return containerUser instanceof net.minecraft.world.entity.player.Player;
+ }
+
+ public Player asPlayer() {
+ return new Player((net.minecraft.world.entity.player.Player) containerUser);
+ }
+
+ @Deprecated
+ public ContainerUser 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..f0513e362
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatEntity.java
@@ -0,0 +1,140 @@
+package net.pitan76.mcpitanlib.api.entity;
+
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.damagesource.DamageSource;
+import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.protocol.game.ClientGamePacketListener;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.storage.ValueInput;
+import net.minecraft.world.level.storage.ValueOutput;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.phys.Vec3;
+import net.minecraft.world.level.Level;
+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.core.mc1216.NbtDataConverter;
+import net.pitan76.mcpitanlib.midohra.entity.EntityTypeWrapper;
+import net.pitan76.mcpitanlib.midohra.util.math.Vector3d;
+
+public class CompatEntity extends Entity implements ICompatEntity {
+ public CompatEntity(EntityType> type, Level world) {
+ super(type, world);
+ }
+
+ @Deprecated
+ @Override
+ public void defineSynchedData(SynchedEntityData.Builder builder) {
+ initDataTracker(new InitDataTrackerArgs(builder));
+ }
+
+ @Override
+ public boolean hurtServer(ServerLevel world, DamageSource source, float amount) {
+ return false;
+ }
+
+ public void initDataTracker(InitDataTrackerArgs args) {
+
+ }
+
+ public void readCustomDataFromNbt(ReadNbtArgs nbt) {
+ readAdditionalSaveData(nbt.view);
+ }
+
+ public void writeCustomDataToNbt(WriteNbtArgs nbt) {
+ addAdditionalSaveData(nbt.view);
+ }
+
+ @Deprecated
+ @Override
+ protected void readAdditionalSaveData(ValueInput view) {
+ CompoundTag nbt = NbtDataConverter.data2nbt(view);
+ readCustomDataFromNbt(new ReadNbtArgs(nbt, view));
+ }
+
+ @Deprecated
+ @Override
+ protected void addAdditionalSaveData(ValueOutput view) {
+ CompoundTag nbt = new CompoundTag();
+ writeCustomDataToNbt(new WriteNbtArgs(nbt, view));
+ NbtDataConverter.nbt2writeData(nbt, view);
+ }
+
+ public Packet createSpawnPacket() {
+ return null;
+ }
+
+ public void writeNbt(WriteNbtArgs args) {
+ saveWithoutId(args.view);
+ }
+
+ public void readNbt(ReadNbtArgs args) {
+ load(args.view);
+ }
+
+ @Deprecated
+ @Override
+ public void saveWithoutId(ValueOutput view) {
+ super.saveWithoutId(view);
+ CompoundTag nbt = new CompoundTag();
+ writeNbt(new WriteNbtArgs(nbt, view));
+ NbtDataConverter.nbt2writeData(nbt, view);
+ }
+
+ @Deprecated
+ @Override
+ public void load(ValueInput view) {
+ super.load(view);
+ CompoundTag nbt = NbtDataConverter.data2nbt(view);
+ readNbt(new ReadNbtArgs(nbt, view));
+ }
+
+ @Deprecated
+ @Override
+ public Level level() {
+ return callGetWorld();
+ }
+
+ public Level callGetWorld() {
+ return super.level();
+ }
+
+ public BlockPos callGetBlockPos() {
+ return blockPosition();
+ }
+
+ public Vec3 callGetPos() {
+ return position();
+ }
+
+ public boolean hasServerWorld() {
+ return callGetWorld() instanceof ServerLevel;
+ }
+
+ public ServerLevel getServerWorld() {
+ return (ServerLevel) level();
+ }
+
+ 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());
+ }
+
+ public CompatEntity(EntityTypeWrapper type, net.pitan76.mcpitanlib.midohra.world.World world) {
+ super(type.get(), world.toMinecraft());
+ }
+}
\ 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..5e0bede7e
--- /dev/null
+++ b/common/src/main/java/net/pitan76/mcpitanlib/api/entity/CompatThrownItemEntity.java
@@ -0,0 +1,173 @@
+package net.pitan76.mcpitanlib.api.entity;
+
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.LivingEntity;
+import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.world.entity.projectile.throwableitemprojectile.ThrowableItemProjectile;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.level.storage.ValueInput;
+import net.minecraft.world.level.storage.ValueOutput;
+import net.minecraft.world.phys.EntityHitResult;
+import net.minecraft.world.phys.HitResult;
+import net.minecraft.world.level.Level;
+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;
+import net.pitan76.mcpitanlib.api.util.ItemStackUtil;
+import net.pitan76.mcpitanlib.core.mc1216.NbtDataConverter;
+import net.pitan76.mcpitanlib.midohra.entity.EntityTypeWrapper;
+import net.pitan76.mcpitanlib.midohra.entity.IEntityM;
+
+public abstract class CompatThrownItemEntity extends ThrowableItemProjectile implements IEntityM, ICompatEntity {
+
+ public CompatThrownItemEntity(EntityType extends ThrowableItemProjectile> entityType, Level world) {
+ super(entityType, world);
+ }
+
+ public CompatThrownItemEntity(EntityType extends ThrowableItemProjectile> entityType, double d, double e, double f, Level world) {
+ super(entityType, d, e, f, world, ItemStackUtil.empty());
+ }
+
+ public CompatThrownItemEntity(EntityType extends ThrowableItemProjectile> entityType, LivingEntity livingEntity, Level world) {
+ super(entityType, livingEntity, world, ItemStackUtil.empty());
+ }
+
+ public abstract Item getDefaultItemOverride();
+
+ @Deprecated
+ @Override
+ protected Item getDefaultItem() {
+ return getDefaultItemOverride();
+ }
+
+ public ItemStack callGetItem() {
+ return super.getItem();
+ }
+
+ @Deprecated
+ @Override
+ public ItemStack getItem() {
+ 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.handleEntityEvent(status);
+ }
+
+ @Deprecated
+ @Override
+ public void handleEntityEvent(byte status) {
+ callHandleStatus(status);
+ }
+
+ public void onEntityHit(EntityHitEvent event) {
+ super.onHitEntity(event.entityHitResult);
+ }
+
+ @Deprecated
+ @Override
+ protected void onHitEntity(EntityHitResult entityHitResult) {
+ onEntityHit(new EntityHitEvent(entityHitResult));
+ }
+
+ public void onCollision(CollisionEvent event) {
+ super.onHit(event.hitResult);
+ }
+
+ @Deprecated
+ @Override
+ protected void onHit(HitResult hitResult) {
+ onCollision(new CollisionEvent(hitResult));
+ }
+
+ // ------------------ ExtendEntity ------------------
+
+ @Deprecated
+ @Override
+ public void defineSynchedData(SynchedEntityData.Builder builder) {
+ initDataTracker(new InitDataTrackerArgs(builder, entityData));
+ }
+
+ public void initDataTracker(InitDataTrackerArgs args) {
+ super.defineSynchedData(args.getBuilder());
+ }
+
+ public void readCustomDataFromNbt(ReadNbtArgs nbt) {
+ super.readAdditionalSaveData(nbt.view);
+ }
+
+ public void writeCustomDataToNbt(WriteNbtArgs nbt) {
+ super.addAdditionalSaveData(nbt.view);
+ }
+
+ @Deprecated
+ @Override
+ protected void readAdditionalSaveData(ValueInput view) {
+ CompoundTag nbt = NbtDataConverter.data2nbt(view);
+ readCustomDataFromNbt(new ReadNbtArgs(nbt, view));
+ }
+
+ @Deprecated
+ @Override
+ protected void addAdditionalSaveData(ValueOutput view) {
+ CompoundTag nbt = new CompoundTag();
+ writeCustomDataToNbt(new WriteNbtArgs(nbt, view));
+ NbtDataConverter.nbt2writeData(nbt, view);
+ }
+
+ public void writeNbt(WriteNbtArgs args) {
+ super.saveWithoutId(args.view);
+ }
+
+ public void readNbt(ReadNbtArgs args) {
+ super.load(args.view);
+ }
+
+ @Deprecated
+ @Override
+ public void saveWithoutId(ValueOutput view) {
+ super.saveWithoutId(view);
+ CompoundTag nbt = new CompoundTag();
+ writeNbt(new WriteNbtArgs(nbt, view));
+ NbtDataConverter.nbt2writeData(nbt, view);
+ }
+
+ @Deprecated
+ @Override
+ public void load(ValueInput view) {
+ super.load(view);
+ CompoundTag nbt = NbtDataConverter.data2nbt(view);
+ readNbt(new ReadNbtArgs(nbt, view));
+ }
+
+ @Override
+ public Level level() {
+ return super.level();
+ }
+
+ public void setStack(net.pitan76.mcpitanlib.midohra.item.ItemStack stack) {
+ callSetItem(stack.toMinecraft());
+ }
+
+ public net.pitan76.mcpitanlib.midohra.item.ItemStack getStackM() {
+ return net.pitan76.mcpitanlib.midohra.item.ItemStack.of(callGetItem());
+ }
+
+ public CompatThrownItemEntity(EntityTypeWrapper type, net.pitan76.mcpitanlib.midohra.world.World world) {
+ this((EntityType extends ThrowableItemProjectile>) type.get(), world.toMinecraft());
+ }
+}
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..e6835bd8e
--- /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.world.level.block.Block;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityDimensions;
+import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.MobCategory;
+import net.minecraft.world.level.storage.loot.LootTable;
+import net.minecraft.resources.ResourceKey;
+import net.pitan76.mcpitanlib.MCPitanLib;
+
+import java.util.Optional;
+
+public class EntityTypeBuilder {
+
+ private MobCategory 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(MobCategory spawnGroup, ExtendEntityType.EntityFactory factory) {
+ this();
+ this.spawnGroup = spawnGroup;
+ this.factory = factory;
+ }
+
+ public static EntityTypeBuilder create() {
+ return new EntityTypeBuilder<>();
+ }
+
+ public static EntityTypeBuilder create(MobCategory 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