diff --git a/Allay-API/src/main/java/org/allaymc/api/container/Container.java b/Allay-API/src/main/java/org/allaymc/api/container/Container.java index f3e64f565..2411a6bd1 100644 --- a/Allay-API/src/main/java/org/allaymc/api/container/Container.java +++ b/Allay-API/src/main/java/org/allaymc/api/container/Container.java @@ -76,10 +76,19 @@ default void clearSlot(int slot) { setItemStack(slot, EMPTY_SLOT_PLACE_HOLDER); } + default void clearAllSlots() { + for (int slot = 0; slot < getItemStackArray().length; slot++) { + clearSlot(slot); + } + } + void addViewer(ContainerViewer viewer); void removeViewer(ContainerViewer viewer); + default void removeAllViewers() { + getViewers().values().forEach(this::removeViewer); + } ContainerViewer removeViewer(byte viewerId); diff --git a/Allay-API/src/main/java/org/allaymc/api/entity/component/event/EntityDieEvent.java b/Allay-API/src/main/java/org/allaymc/api/entity/component/event/EntityDieEvent.java new file mode 100644 index 000000000..3189deca2 --- /dev/null +++ b/Allay-API/src/main/java/org/allaymc/api/entity/component/event/EntityDieEvent.java @@ -0,0 +1,15 @@ +package org.allaymc.api.entity.component.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.allaymc.api.eventbus.event.Event; + +/** + * Allay Project 2024/6/14 + * + * @author daoge_cmd + */ +@Getter +@AllArgsConstructor +public class EntityDieEvent extends Event { +} diff --git a/Allay-API/src/main/java/org/allaymc/api/entity/component/event/EntityFallEvent.java b/Allay-API/src/main/java/org/allaymc/api/entity/component/event/EntityFallEvent.java index 40198532e..5635f7760 100644 --- a/Allay-API/src/main/java/org/allaymc/api/entity/component/event/EntityFallEvent.java +++ b/Allay-API/src/main/java/org/allaymc/api/entity/component/event/EntityFallEvent.java @@ -4,6 +4,11 @@ import lombok.Getter; import org.allaymc.api.eventbus.event.Event; +/** + * Allay Project 2024/2/26 + * + * @author daoge_cmd + */ @Getter @AllArgsConstructor public class EntityFallEvent extends Event { diff --git a/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java b/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java index 2367ededf..b12e9cfce 100644 --- a/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java +++ b/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java @@ -416,7 +416,11 @@ default void addSound(float x, float y, float z, String sound, float volume, flo default void dropItem(ItemStack itemStack, Vector3fc pos) { var rand = ThreadLocalRandom.current(); - dropItem(itemStack, pos, new org.joml.Vector3f(rand.nextFloat(0.2f) - 0.1f, 0.2f, rand.nextFloat(0.2f) - 0.1f), 10); + dropItem(itemStack, pos, new org.joml.Vector3f(rand.nextFloat(0.2f) - 0.1f, 0.2f, rand.nextFloat(0.2f) - 0.1f)); + } + + default void dropItem(ItemStack itemStack, Vector3fc pos, Vector3fc motion) { + dropItem(itemStack, pos, motion, 10); } default void dropItem(ItemStack itemStack, Vector3fc pos, Vector3fc motion, int pickupDelay) { diff --git a/Allay-API/src/main/java/org/allaymc/api/world/World.java b/Allay-API/src/main/java/org/allaymc/api/world/World.java index e2e781039..35435652b 100644 --- a/Allay-API/src/main/java/org/allaymc/api/world/World.java +++ b/Allay-API/src/main/java/org/allaymc/api/world/World.java @@ -88,6 +88,8 @@ default void addTime(long amount) { void setGameRule(GameRule gamerule, Object value); + V getGameRule(GameRule gameRule); + default void broadcastPacket(BedrockPacket packet) { for (var dim : getDimensions().values()) { dim.broadcastPacket(packet); diff --git a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java index 48106162d..1a9252ce3 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java @@ -11,8 +11,6 @@ import org.allaymc.api.component.annotation.Dependency; import org.allaymc.api.container.Container; import org.allaymc.api.container.ContainerViewer; -import org.allaymc.api.entity.init.SimpleEntityInitInfo; -import org.allaymc.api.entity.type.EntityTypes; import org.allaymc.api.eventbus.EventHandler; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.joml.Vector3f; @@ -77,10 +75,12 @@ private void onReplace(BlockOnReplaceEvent event) { var pos = event.getCurrentBlockState().pos(); var dimension = pos.dimension(); var rand = ThreadLocalRandom.current(); + container.removeAllViewers(); for (var itemStack : container.getItemStacks()) { if (itemStack == Container.EMPTY_SLOT_PLACE_HOLDER) continue; dimension.dropItem(itemStack, new Vector3f(pos.x() + rand.nextFloat(0.5f) + 0.25f, pos.y() + rand.nextFloat(0.5f) + 0.25f, pos.z() + rand.nextFloat(0.5f) + 0.25f)); } + container.clearAllSlots(); } @Override diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java index 5dbe15fac..537d79a98 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java @@ -191,6 +191,7 @@ protected void checkDead() { if (attributeComponent.getHealth() == 0 && !dead) { var event = new EntityDieEvent(thisEntity); getWorld().getEventBus().callEvent(event); + manager.callEvent(new org.allaymc.api.entity.component.event.EntityDieEvent()); dead = true; deadTimer = DEFAULT_DEAD_TIMER; applyEntityEvent(EntityEventType.DEATH, 0); diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java index f9e73f227..2f50e4175 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java @@ -1,14 +1,21 @@ package org.allaymc.server.entity.component.common; +import org.allaymc.api.component.annotation.ComponentedObject; +import org.allaymc.api.entity.Entity; +import org.allaymc.api.entity.component.event.EntityDieEvent; +import org.allaymc.api.eventbus.EventHandler; import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.container.BaseContainerHolder; import org.allaymc.api.container.Container; import org.allaymc.api.container.FullContainerType; import org.allaymc.api.entity.component.common.EntityContainerHolderComponent; +import org.allaymc.api.world.gamerule.GameRule; import org.jetbrains.annotations.UnmodifiableView; +import org.joml.Vector3f; import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; /** * Allay Project 2023/7/15 @@ -19,6 +26,8 @@ public class EntityContainerHolderComponentImpl extends BaseContainerHolder impl @ComponentIdentifier protected static final Identifier IDENTIFIER = new Identifier("minecraft:entity_inventory_holder_component"); + @ComponentedObject + protected static Entity entity; public EntityContainerHolderComponentImpl() {} @@ -40,4 +49,29 @@ public T getContainer(FullContainerType type) { public void addContainer(Container container) { super.addContainer(container); } + + @EventHandler + protected void onDie(EntityDieEvent event) { + var pos = entity.getLocation(); + var dimension = pos.dimension(); + var rand = ThreadLocalRandom.current(); + for (var container : getContainers().values()) { + container.removeAllViewers(); + if (!canDropItemInContainers()) continue; + for (var itemStack : container.getItemStacks()) { + if (itemStack == Container.EMPTY_SLOT_PLACE_HOLDER) continue; + dimension.dropItem( + itemStack, + new Vector3f(pos.x() + rand.nextFloat(0.5f) + 0.25f, pos.y() + rand.nextFloat(0.5f) + 0.25f, pos.z() + rand.nextFloat(0.5f) + 0.25f), + new Vector3f(rand.nextFloat(1.0f) - 0.5f, 0.5f, rand.nextFloat(1.0f) - 0.5f), + 40 + ); + } + container.clearAllSlots(); + } + } + + protected boolean canDropItemInContainers() { + return entity.getWorld().getGameRule(GameRule.DO_ENTITY_DROPS); + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java index a944f6fe1..ea31f00a8 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java @@ -172,6 +172,7 @@ protected void syncData() { } protected void tryPickUpItems() { + if (dead || !spawned || willBeDespawnedNextTick) return; var dimension = location.dimension; // pick up items var pickUpArea = new AABBf( diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java index 9207f8aa2..932764a7e 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java @@ -5,6 +5,7 @@ import org.allaymc.api.container.impl.*; import org.allaymc.api.entity.component.player.EntityPlayerContainerHolderComponent; import org.allaymc.api.entity.interfaces.EntityPlayer; +import org.allaymc.api.world.gamerule.GameRule; import org.allaymc.server.entity.component.common.EntityContainerHolderComponentImpl; /** @@ -31,4 +32,9 @@ public EntityPlayerContainerHolderComponentImpl() { public void onInitFinish(ComponentInitInfo initInfo) { addContainer(new PlayerInventoryContainer(player)); } + + @Override + protected boolean canDropItemInContainers() { + return !(boolean)player.getWorld().getGameRule(GameRule.KEEP_INVENTORY); + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java b/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java index 4132cb6ce..40b832b1e 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java @@ -235,6 +235,11 @@ public void setGameRule(GameRule gamerule, Object value) { worldData.setGameRule(gamerule, value); } + @Override + public V getGameRule(GameRule gameRule) { + return worldData.getGameRule(gameRule); + } + @Override public void saveWorldData() { getWorldStorage().writeWorldData(worldData);