Skip to content

Commit

Permalink
fix: fix crafting grid
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcmd committed Jun 22, 2024
1 parent 0fc77ee commit d31f24d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.Getter;
import lombok.Setter;
import org.allaymc.api.container.BaseContainer;
import org.allaymc.api.container.ContainerViewer;
import org.allaymc.api.container.FullContainerType;
import org.allaymc.api.entity.interfaces.EntityPlayer;
import org.allaymc.api.item.ItemStack;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class CraftRecipeActionProcessor implements ContainerActionProcessor<Craf

@Override
public ActionResponse handle(CraftRecipeAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map<Object, Object> dataPool) {
CraftingContainer craftingContainer = player.getContainer(FullContainerType.CRAFTING_TABLE);
CraftingContainer craftingContainer = player.getOpenedContainer(FullContainerType.CRAFTING_TABLE);
if (craftingContainer == null) {
// The player is not opening a crafting table, using crafting grid instead
craftingContainer = player.getContainer(FullContainerType.CRAFTING_GRID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventoryContentPacket;
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.HashMap;
import java.util.Map;

import static org.allaymc.api.container.FullContainerType.CRAFTING_GRID;

/**
* Allay Project 2023/9/23
*
Expand Down Expand Up @@ -91,39 +94,53 @@ public void sendContent(Container container, int slot) {

@Override
public void onOpen(byte assignedId, Container container) {
sendContainerOpenPacket(assignedId, container);
registerOpenedContainer(assignedId, container);

var containerType = container.getContainerType();
//We should send the container's contents to client if the container is not held by the entity
if (containerHolderComponent.getContainer(containerType) == null) {
sendContents(container);
}
}

protected void registerOpenedContainer(byte assignedId, Container container) {
idToContainer.put(assignedId, container);
typeToContainer.put(container.getContainerType(), container);
container.getContainerType().heldSlotTypes().forEach(slotType -> slotTypeToFullType.put(slotType, container.getContainerType()));
}

private void sendContainerOpenPacket(byte assignedId, Container container) {
var containerOpenPacket = new ContainerOpenPacket();
containerOpenPacket.setId(assignedId);
var containerType = container.getContainerType();
containerOpenPacket.setType(containerType.toNetworkType());
containerOpenPacket.setType(container.getContainerType().toNetworkType());
if (container.hasBlockPos()) {
containerOpenPacket.setBlockPosition(MathUtils.JOMLVecToCBVec(container.getBlockPos()));
} else {
var location = baseComponent.getLocation();
containerOpenPacket.setBlockPosition(Vector3i.from(location.x(), location.y(), location.z()));
}
networkComponent.sendPacket(containerOpenPacket);

idToContainer.put(assignedId, container);
typeToContainer.put(container.getContainerType(), container);
container.getContainerType().heldSlotTypes().forEach(slotType -> slotTypeToFullType.put(slotType, container.getContainerType()));

//We should send the container's contents to client if the container is not held by the entity
if (containerHolderComponent.getContainer(containerType) == null) {
sendContents(container);
}
}

@Override
public void onClose(byte assignedId, Container container) {
if (!idToContainer.containsKey(assignedId))
throw new IllegalArgumentException("Trying to close a container which is not opened! Type: " + container.getContainerType());
sendContainerClosePacket(assignedId, container);
unregisterOpenedContainer(assignedId, container);
}

protected void unregisterOpenedContainer(byte assignedId, Container container) {
typeToContainer.remove(idToContainer.remove(assignedId).getContainerType());
container.getContainerType().heldSlotTypes().forEach(slotType -> slotTypeToFullType.remove(slotType));
}

protected void sendContainerClosePacket(byte assignedId, Container container) {
var containerClosePacket = new ContainerClosePacket();
containerClosePacket.setId(assignedId);
containerClosePacket.setType(container.getContainerType().toNetworkType());
networkComponent.sendPacket(containerClosePacket);

typeToContainer.remove(idToContainer.remove(assignedId).getContainerType());
container.getContainerType().heldSlotTypes().forEach(slotType -> slotTypeToFullType.remove(slotType));
}

@Override
Expand All @@ -133,18 +150,43 @@ public void onSlotChange(Container container, int slot) {
}

@Override

public <T extends Container> T getOpenedContainer(FullContainerType<T> type) {
return (T) typeToContainer.get(type);
// 特判: 如果玩家打开了背包,则他也同步打开了一系列其他容器,尽管没有注册
Container container = null;
if (isPlayerInventoryOpened()) {
if (
type == FullContainerType.ARMOR ||
type == FullContainerType.OFFHAND ||
type == CRAFTING_GRID
) {
container = containerHolderComponent.getContainer(type);
}
}
if (container == null) container = typeToContainer.get(type);
return (T) container;
}

@Override
public <T extends Container> T getOpenedContainerBySlotType(ContainerSlotType slotType) {
return (T) getOpenedContainer(slotTypeToFullType.get(slotType));
// 同上,需要特判
FullContainerType<?> fullType = null;
if (isPlayerInventoryOpened()) {
fullType = switch (slotType) {
case ARMOR -> FullContainerType.ARMOR;
case OFFHAND -> FullContainerType.OFFHAND;
case CRAFTING_INPUT -> FullContainerType.CRAFTING_GRID;
default -> null;
};
}
if (fullType == null) fullType = slotTypeToFullType.get(slotType);
return (T) getOpenedContainer(fullType);
}

@Override
protected boolean isPlayerInventoryOpened() {
return typeToContainer.get(FullContainerType.PLAYER_INVENTORY) != null;
}

@Override
public Container getOpenedContainer(byte id) {
return idToContainer.get(id);
}
Expand Down

0 comments on commit d31f24d

Please sign in to comment.