Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package io.papermc.paper.event.entity;

import org.bukkit.block.Container;
import org.bukkit.entity.CopperGolem;
import org.bukkit.entity.Entity;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;

/**
* Called when an item-transporting entity (typically a {@link CopperGolem},
* although other entities may be possible through non-API means)
* is inspecting a destination {@link Container} to decide if the item it is holding
* belongs in said container. This gives plugin developers an opportunity to
* override the {@link CopperGolem}'s sorting behavior.
*/
@NullMarked
public class ItemTransportingEntitySortEvent extends EntityEvent {
protected static final HandlerList HANDLER_LIST = new HandlerList();

public enum ItemTransportingEntityDecision {
ALLOW_DESTINATION,
REJECT_DESTINATION,
DEFAULT
}

private final ItemStack itemStack;
private final Inventory containerInventory;
private ItemTransportingEntityDecision decision;

@ApiStatus.Internal
public ItemTransportingEntitySortEvent(
final Entity entity,
final ItemStack itemStack,
final Inventory containerInventory
) {
super(entity);
this.containerInventory = containerInventory;
this.itemStack = itemStack;
this.decision = ItemTransportingEntityDecision.DEFAULT;
}

/**
* Sets if the item belongs in the container.
*
* @param d Whether the item belongs in the chest.
*/
public void setDecision(boolean d) {
this.decision = d ? ItemTransportingEntityDecision.ALLOW_DESTINATION : ItemTransportingEntityDecision.REJECT_DESTINATION;
}

/**
* Gets if the held item stack belongs in the container.
*
* @return Whether the item stack belongs in the chest.
*/
public ItemTransportingEntityDecision getDecision() {
return this.decision;
}
Comment thread
jsbrn marked this conversation as resolved.

/**
* Gets the container the entity is comparing to the held item.
*
* @return The potential destination container
*/
public Inventory getContainerInventory() {
return this.containerInventory;
}

/**
* Gets the held item stack being compared against the container.
*
* @return The held item stack
*/
public ItemStack getHeldItemStack() {
return this.itemStack;
}

public static HandlerList getHandlerList() {
return HANDLER_LIST;
}

@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,22 @@
return isValidTarget ? transportItemTarget : null;
}
}
@@ -505,7 +_,17 @@
}

private static boolean matchesLeavingItemsRequirement(final PathfinderMob body, final Container container) {
- return container.isEmpty() || hasItemMatchingHandItem(body, container);
+ // Paper start - Add event for container assessment
+ io.papermc.paper.event.entity.ItemTransportingEntitySortEvent sortEvent = org.bukkit.craftbukkit.event.CraftEventFactory.createItemTransportingEntitySortEvent(body, container);
+ sortEvent.callEvent();
+ if (sortEvent.getDecision() !=
+ io.papermc.paper.event.entity.ItemTransportingEntitySortEvent.ItemTransportingEntityDecision.DEFAULT) {
+ return sortEvent.getDecision()
+ == io.papermc.paper.event.entity.ItemTransportingEntitySortEvent.ItemTransportingEntityDecision.ALLOW_DESTINATION;
+ } else {
+ return container.isEmpty() || hasItemMatchingHandItem(body, container);
+ }
+ // Paper end - Add event for container assessment
}

private static boolean hasItemMatchingHandItem(final PathfinderMob body, final Container container) {
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Either;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.block.TileStateInventoryHolder;
import io.papermc.paper.block.bed.BedEnterProblem;
import io.papermc.paper.connection.HorriblePlayerLoginEventHack;
import io.papermc.paper.connection.PlayerConnection;
import io.papermc.paper.event.block.BlockLockCheckEvent;
import io.papermc.paper.event.connection.PlayerConnectionValidateLoginEvent;
import io.papermc.paper.event.entity.ItemTransportingEntitySortEvent;
import io.papermc.paper.event.entity.ItemTransportingEntityValidateTargetEvent;
import io.papermc.paper.event.player.PlayerBedFailEnterEvent;
import io.papermc.paper.event.player.PlayerToggleEntityAgeLockEvent;
Expand Down Expand Up @@ -105,6 +107,8 @@
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.entity.CraftSpellcaster;
import org.bukkit.craftbukkit.inventory.CraftContainer;
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.inventory.CraftItemType;
Expand Down Expand Up @@ -2421,10 +2425,15 @@ public static boolean callPlayerToggleEntityAgeLockEvent(net.minecraft.world.ent
return true;
}

public static ItemTransportingEntitySortEvent createItemTransportingEntitySortEvent(PathfinderMob mob, Container container) {
return new ItemTransportingEntitySortEvent(mob.getBukkitEntity(), mob.getMainHandItem().asBukkitCopy(), new CraftInventory(container));
}

public static ClockTimeSkipEvent createTimeSkipEvent(final CommandSourceStack source, final long skipAmount) {
if (io.papermc.paper.configuration.GlobalConfiguration.get().time.affectsAllWorlds) {
return new ClockTimeSkipEvent(ClockTimeSkipEvent.SkipReason.COMMAND, skipAmount);
}
return new TimeSkipEvent(source.getLevel().getWorld(), ClockTimeSkipEvent.SkipReason.COMMAND, skipAmount);
}

}