Skip to content

Commit

Permalink
Improve handling of polymer item / block / entity use interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
Patbox committed Oct 20, 2024
1 parent 177c7a4 commit 63439b1
Show file tree
Hide file tree
Showing 14 changed files with 242 additions and 43 deletions.
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ org.gradle.jvmargs=-Xmx4G
# Fabric Properties
# check these on https://fabricmc.net/use

minecraft_version=1.21.2-pre4
yarn_mappings=1.21.2-pre4+build.2
minecraft_version=1.21.2-rc1
yarn_mappings=1.21.2-rc1+build.1
loader_version=0.16.7

# Fabric API
fabric_version=0.105.4+1.21.2
fabric_version=0.106.0+1.21.2

maven_group = eu.pb4

mod_version = 0.10.0-alpha
mod_version = 0.10.0-rc.1

minecraft_version_supported = ">=1.21.2-"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import xyz.nucleoid.packettweaker.PacketContext;

Expand Down Expand Up @@ -58,4 +62,8 @@ default Block getPolymerReplacement(PacketContext context) {
default boolean handleMiningOnServer(ItemStack tool, BlockState state, BlockPos pos, ServerPlayerEntity player) {
return true;
}

default boolean isPolymerBlockInteraction(BlockState state, ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, BlockHitResult blockHitResult, ActionResult actionResult) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
import net.minecraft.registry.Registries;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkSectionPos;
import org.jetbrains.annotations.ApiStatus;
Expand All @@ -45,6 +48,7 @@ public final class PolymerBlockUtils {
*/
public static final BooleanEvent<MineEventListener> SERVER_SIDE_MINING_CHECK = new BooleanEvent<>();
public static final SimpleEvent<BreakingProgressListener> BREAKING_PROGRESS_UPDATE = new SimpleEvent<>();
public static final BooleanEvent<PolymerBlockInteractionListener> POLYMER_BLOCK_INTERACTION_CHECK = new BooleanEvent<>();
/**
* This event allows you to force syncing of light updates between server and clinet
*/
Expand Down Expand Up @@ -146,7 +150,7 @@ public static BlockState getBlockBreakBlockStateSafely(PolymerBlock block, Block
*
* @param block PolymerBlock
* @param blockState Server side BlockState
* @param player Possible target player
* @param context Possible target player
* @return Client side BlockState
*/
public static BlockState getBlockStateSafely(PolymerBlock block, BlockState blockState, PacketContext context) {
Expand Down Expand Up @@ -242,6 +246,17 @@ public static NbtCompound transformBlockEntityNbt(PacketContext context, BlockEn
return override != null ? override : original;
}

public static boolean isPolymerBlockInteraction(ServerPlayerEntity player, ItemStack stack, Hand hand, BlockHitResult blockHitResult, ServerWorld world, ActionResult actionResult) {
var blockState = world.getBlockState(blockHitResult.getBlockPos());
if (blockState.getBlock() instanceof PolymerBlock polymerBlock && polymerBlock.isPolymerBlockInteraction(blockState, player, hand, stack, world, blockHitResult, actionResult)) {
return true;
} else if (stack.getItem() instanceof PolymerItem polymerItem && polymerItem.isPolymerBlockInteraction(blockState, player, hand, stack, world, blockHitResult, actionResult)) {
return true;
}

return POLYMER_BLOCK_INTERACTION_CHECK.invoke(x -> x.isPolymerBlockInteraction(blockState, player, hand, stack, world, blockHitResult, actionResult));
}

@FunctionalInterface
public interface MineEventListener {
boolean onBlockMine(BlockState state, BlockPos pos, ServerPlayerEntity player);
Expand All @@ -251,4 +266,9 @@ public interface MineEventListener {
public interface BreakingProgressListener {
void onBreakingProgressUpdate(ServerPlayerEntity player, BlockPos pos, BlockState finalState, int i);
}

@FunctionalInterface
public interface PolymerBlockInteractionListener {
boolean isPolymerBlockInteraction(BlockState state, ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, BlockHitResult blockHitResult, ActionResult actionResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.mojang.datafixers.util.Pair;
import eu.pb4.polymer.core.api.utils.PolymerObject;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.data.DataTracker;
Expand All @@ -10,6 +11,11 @@
import net.minecraft.network.packet.s2c.play.EntityAttributesS2CPacket;
import net.minecraft.server.network.PlayerAssociatedNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Vec3d;
import xyz.nucleoid.packettweaker.PacketContext;

Expand Down Expand Up @@ -88,4 +94,8 @@ default boolean canSynchronizeToPolymerClient(ServerPlayerEntity player) {
default boolean sendEmptyTrackerUpdates(ServerPlayerEntity player) {
return true;
}

default boolean isPolymerEntityInteraction(ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, ActionResult actionResult) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
package eu.pb4.polymer.core.api.entity;

import eu.pb4.polymer.common.api.events.BooleanEvent;
import eu.pb4.polymer.common.impl.CommonImplUtils;
import eu.pb4.polymer.common.impl.entity.InternalEntityHelpers;
import eu.pb4.polymer.core.api.item.PolymerItem;
import eu.pb4.polymer.core.impl.interfaces.EntityAttachedPacket;
import eu.pb4.polymer.core.impl.networking.PolymerServerProtocol;
import eu.pb4.polymer.core.mixin.entity.EntityAccessor;
import eu.pb4.polymer.core.mixin.entity.PlayerListS2CPacketAccessor;
import eu.pb4.polymer.rsm.api.RegistrySyncUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
import net.minecraft.registry.Registries;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Util;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.village.VillagerProfession;
import org.jetbrains.annotations.Nullable;

Expand All @@ -29,6 +33,7 @@
public final class PolymerEntityUtils {
private PolymerEntityUtils() {
}
public static final BooleanEvent<PolymerEntityInteractionListener> POLYMER_ENTITY_INTERACTION_CHECK = new BooleanEvent<>();

private static final Set<EntityType<?>> ENTITY_TYPES = new ObjectOpenCustomHashSet<>(CommonImplUtils.IDENTITY_HASH);
private static final Set<EntityAttribute> ENTITY_ATTRIBUTES = new ObjectOpenCustomHashSet<>(CommonImplUtils.IDENTITY_HASH);
Expand Down Expand Up @@ -159,5 +164,20 @@ public static Entity getEntityContext(Packet<?> packet) {
public static void sendEntityType(ServerPlayerEntity player, int entityId, EntityType<?> entityType) {
PolymerServerProtocol.sendEntityInfo(player.networkHandler, entityId, entityType);
}

public static boolean isPolymerEntityInteraction(ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, Entity entity, ActionResult actionResult) {
if (entity instanceof PolymerEntity polymerEntity && polymerEntity.isPolymerEntityInteraction(player, hand, stack, world, actionResult)) {
return true;
} else if (stack.getItem() instanceof PolymerItem polymerItem && polymerItem.isPolymerEntityInteraction(player, hand, stack, world, entity, actionResult)) {
return true;
}

return POLYMER_ENTITY_INTERACTION_CHECK.invoke(x -> x.isPolymerEntityInteraction(player, hand, stack, world, entity, actionResult));
}

@FunctionalInterface
public interface PolymerEntityInteractionListener {
boolean isPolymerEntityInteraction(ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, Entity entity, ActionResult actionResult);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
import eu.pb4.polymer.core.impl.PolymerImplUtils;
import net.minecraft.block.BlockState;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.Entity;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -69,4 +75,16 @@ default boolean handleMiningOnServer(ItemStack tool, BlockState targetBlock, Blo
default boolean shouldStorePolymerItemStackCount() {
return false;
}

default boolean isPolymerBlockInteraction(BlockState state, ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, BlockHitResult blockHitResult, ActionResult actionResult) {
return false;
}

default boolean isPolymerEntityInteraction(ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, Entity entity, ActionResult actionResult) {
return false;
}

default boolean isPolymerItemInteraction(ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, ActionResult actionResult) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryOps;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.Unit;
import net.minecraft.util.*;
import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.packettweaker.PacketContext;

Expand Down Expand Up @@ -74,6 +74,9 @@ public final class PolymerItemUtils {
* You can also return new ItemStack, however please keep previous nbt so other modifications aren't removed if not needed!
*/
public static final FunctionEvent<ItemModificationEventHandler, ItemStack> ITEM_MODIFICATION_EVENT = new FunctionEvent<>();

public static final BooleanEvent<PolymerItemInteractionListener> POLYMER_ITEM_INTERACTION_CHECK = new BooleanEvent<>();

private static final ComponentType<?>[] COMPONENTS_TO_COPY = {DataComponentTypes.CAN_BREAK, DataComponentTypes.CAN_PLACE_ON,
DataComponentTypes.BLOCK_ENTITY_DATA, DataComponentTypes.TRIM,
DataComponentTypes.TOOL,
Expand Down Expand Up @@ -514,11 +517,23 @@ public static ItemStack getClientItemStack(ItemStack stack, PacketContext contex
return out;
}

public static boolean isPolymerItemInteraction(ServerPlayerEntity player, ItemStack stack, Hand hand, ServerWorld world, ActionResult actionResult) {
if (stack.getItem() instanceof PolymerItem polymerItem && polymerItem.isPolymerItemInteraction(player, hand, stack, world, actionResult)) {
return true;
}
return POLYMER_ITEM_INTERACTION_CHECK.invoke((x) -> x.isPolymerItemInteraction(player, hand, stack, world, actionResult));
}

@FunctionalInterface
public interface ItemModificationEventHandler {
ItemStack modifyItem(ItemStack original, ItemStack client, PacketContext context);
}

@FunctionalInterface
public interface PolymerItemInteractionListener {
boolean isPolymerItemInteraction(ServerPlayerEntity player, Hand hand, ItemStack stack, ServerWorld world, ActionResult actionResult);
}

public record ItemWithMetadata(Item item, Identifier itemModel) {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package eu.pb4.polymer.core.impl.interfaces;

import eu.pb4.polymer.core.impl.other.ActionSource;
import net.minecraft.util.ActionResult;

public interface LastActionResultStorer {
void polymer$setLastActionResult(ActionResult result);
void polymer$setLastActionSource(ActionSource source);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package eu.pb4.polymer.core.impl.other;

public enum ActionSource {
BLOCK,
ITEM,
ENTITY
}
Loading

0 comments on commit 63439b1

Please sign in to comment.