From a6eb8a0d905ee3a48e8b40e2bee2110cbc38d72d Mon Sep 17 00:00:00 2001 From: aromaa Date: Sun, 24 Nov 2024 01:28:16 +0200 Subject: [PATCH 1/4] Edge case fixes for dummy slots --- .../inventory/custom/SpongeViewableInventoryBuilder.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/spongepowered/common/inventory/custom/SpongeViewableInventoryBuilder.java b/src/main/java/org/spongepowered/common/inventory/custom/SpongeViewableInventoryBuilder.java index c37c4dd9a56..2f2a7bd8dfb 100644 --- a/src/main/java/org/spongepowered/common/inventory/custom/SpongeViewableInventoryBuilder.java +++ b/src/main/java/org/spongepowered/common/inventory/custom/SpongeViewableInventoryBuilder.java @@ -138,6 +138,7 @@ private Slot newDummySlot() { // Slot definition Impl: public BuildingStep slotsAtIndizes(List source, List at) { Validate.isTrue(source.size() == at.size(), "Source and index list sizes differ"); + this.lastSlot = null; for (int i = 0; i < at.size(); i++) { Slot slot = source.get(i); Integer index = at.get(i); @@ -215,7 +216,9 @@ public BuildingStep grid(List source, Vector2i size, int offset) { // dummy @Override public BuildingStep item(ItemStackLike item) { - this.lastSlot.set(item); + if (this.lastSlot != null) { + this.lastSlot.set(item); + } return this; } From dac0122320f716d154157c907ad3888d9cb1c680 Mon Sep 17 00:00:00 2001 From: aromaa Date: Sun, 24 Nov 2024 16:16:20 +0200 Subject: [PATCH 2/4] Fix InventortyMenu change callback --- .../common/inventory/custom/SpongeInventoryMenu.java | 8 ++------ .../inventory/AbstractContainerMenuMixin_Inventory.java | 6 +++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/spongepowered/common/inventory/custom/SpongeInventoryMenu.java b/src/main/java/org/spongepowered/common/inventory/custom/SpongeInventoryMenu.java index e08665640b4..894c657bf60 100644 --- a/src/main/java/org/spongepowered/common/inventory/custom/SpongeInventoryMenu.java +++ b/src/main/java/org/spongepowered/common/inventory/custom/SpongeInventoryMenu.java @@ -370,17 +370,13 @@ private Boolean onClickLeft( public boolean onChange(final ItemStack newStack, final ItemStack oldStack, final Container container, final int slotIndex, final Slot slot) { - // readonly by default cancels top inventory changes . but can be overridden by change callbacks - if (this.readonly && !(slot.container instanceof PlayerInventory)) { - return false; - } - if (this.changeHandler != null) { final Cause cause = PhaseTracker.getCauseStackManager().currentCause(); return this.changeHandler.handle(cause, container, ((org.spongepowered.api.item.inventory.Slot) slot), slotIndex, ItemStackUtil.snapshotOf(oldStack), ItemStackUtil.snapshotOf(newStack)); } - return true; + // readonly by default cancels top inventory changes . but can be overridden by change callbacks + return !this.isReadOnly(slotIndex) || slot.container instanceof PlayerInventory; } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java b/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java index b530cc8df35..de9c3d48c0c 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java +++ b/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java @@ -212,6 +212,7 @@ public abstract class AbstractContainerMenuMixin_Inventory implements TrackedCon try (final EffectTransactor ignored = transactor.logClickContainer(menu, slotId, dragType, clickType, player)) { this.impl$isClicking = true; this.shadow$doClick(slotId, dragType, clickType, player); + this.bridge$detectAndSendChanges(true, false); } finally { this.impl$isClicking = false; } @@ -282,7 +283,10 @@ public abstract class AbstractContainerMenuMixin_Inventory implements TrackedCon // Only call Menu Callbacks when clicking if (this.impl$isClicking && menu != null && !menu.onChange(newStack, oldStack, (org.spongepowered.api.item.inventory.Container) this, i, slot)) { - this.lastSlots.set(i, oldStack.copy()); // revert changes + // revert changes + oldStack = oldStack.copy(); + slot.set(oldStack); + this.lastSlots.set(i, oldStack); this.impl$sendSlotContents(i, oldStack); // Send reverted slots to clients } else { this.impl$capture(i, newStack, oldStack); // Capture changes for inventory events From 699df2ec74c7bafb698b460585b9a0d3a3a5ab44 Mon Sep 17 00:00:00 2001 From: aromaa Date: Sun, 24 Nov 2024 19:45:10 +0200 Subject: [PATCH 3/4] Implement Keys.MATRIX --- SpongeAPI | 2 +- .../data/provider/entity/DisplayEntityData.java | 15 +++++++++++++-- .../test/entity/DisplayEntityTest.java | 10 ++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/SpongeAPI b/SpongeAPI index 0fcd92c3f2a..529eaa9f17d 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 0fcd92c3f2a9dd90527dc75c6aa3c3a629b9c69e +Subproject commit 529eaa9f17db8589abafa1db3b565efc2276aa84 diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/DisplayEntityData.java b/src/main/java/org/spongepowered/common/data/provider/entity/DisplayEntityData.java index dd4bdfddca8..0702c7aacae 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/DisplayEntityData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/DisplayEntityData.java @@ -61,6 +61,9 @@ public static void register(final DataProviderRegistrator registrator) { .asMutable(Display.class) .create(Keys.TRANSFORM) .get(DisplayEntityData::getTransform) + .set((h, v) -> DisplayEntityData.setTransform(h, v.toMatrix())) + .create(Keys.MATRIX) + .get(DisplayEntityData::getMatrix) .set(DisplayEntityData::setTransform) .asMutable(DisplayAccessor.class) .create(Keys.BILLBOARD_TYPE) @@ -219,9 +222,17 @@ private static Transform getTransform(final Display display) { return transform; } - private static void setTransform(final Display h, final Transform transform) { + private static Matrix4d getMatrix(final Display display) { + var vanillaTransform = DisplayAccessor.invoker$createTransformation(display.getEntityData()); + var vMatrix = vanillaTransform.getMatrix(); + return Matrix4d.from( + vMatrix.get(0, 0), vMatrix.get(1, 0), vMatrix.get(2, 0), vMatrix.get(3, 0), + vMatrix.get(0, 1), vMatrix.get(1, 1), vMatrix.get(2, 1), vMatrix.get(3, 1), + vMatrix.get(0, 2), vMatrix.get(1, 2), vMatrix.get(2, 2), vMatrix.get(3, 2), + vMatrix.get(0, 3), vMatrix.get(1, 3), vMatrix.get(2, 3), vMatrix.get(3, 3)); + } - final Matrix4d matrix = transform.toMatrix(); + private static void setTransform(final Display h, final Matrix4d matrix) { var vMatrix = new org.joml.Matrix4f( (float) matrix.get(0, 0), (float) matrix.get(1, 0), (float) matrix.get(2, 0), (float) matrix.get(3, 0), (float) matrix.get(0, 1), (float) matrix.get(1, 1), (float) matrix.get(2, 1), (float) matrix.get(3, 1), diff --git a/testplugins/src/main/java/org/spongepowered/test/entity/DisplayEntityTest.java b/testplugins/src/main/java/org/spongepowered/test/entity/DisplayEntityTest.java index f0317c60f4f..8e9a8b49597 100644 --- a/testplugins/src/main/java/org/spongepowered/test/entity/DisplayEntityTest.java +++ b/testplugins/src/main/java/org/spongepowered/test/entity/DisplayEntityTest.java @@ -50,6 +50,7 @@ import org.spongepowered.api.world.server.ServerLocation; import org.spongepowered.api.world.server.ServerWorld; import org.spongepowered.math.imaginary.Quaterniond; +import org.spongepowered.math.matrix.Matrix4d; import org.spongepowered.math.vector.Vector3d; import org.spongepowered.plugin.PluginContainer; import org.spongepowered.plugin.builtin.jvm.Plugin; @@ -83,6 +84,7 @@ public void onRegisterCommand(final RegisterCommandEvent event) { final int col5 = 3; final int col6 = 5; final int col7 = 6; + final int col8 = 7; var textDisplay = spawnEntity(player.world(), EntityTypes.TEXT_DISPLAY, centerPos, forwardDir, -4, -1); textDisplay.offer(Keys.DISPLAY_NAME, Component.text("DisplayEntityTest").color(NamedTextColor.GOLD)); textDisplay.offer(Keys.SEE_THROUGH_BLOCKS, true); @@ -247,6 +249,14 @@ public void onRegisterCommand(final RegisterCommandEvent event) { textDisplay.offer(Keys.INTERPOLATION_DURATION, Ticks.of(20)); textDisplay.offer(Keys.INTERPOLATION_DELAY, Ticks.of(20)); + blockDisplay = createEntity(player.world(), EntityTypes.BLOCK_DISPLAY, centerPos, forwardDir, col8, 0); + blockDisplay.offer(Keys.BLOCK_STATE, BlockTypes.CHERRY_SAPLING.get().defaultState()); + blockDisplay.offer(Keys.MATRIX, Matrix4d + .createRotation(Quaterniond.fromAxesAnglesDeg(0, 45, 0)) + .scale(0.5) + .rotate(Quaterniond.fromAxesAnglesDeg(45, 0, 0))); + player.world().spawnEntity(blockDisplay); + // TODO interpolate text opacity? }); From 2b74710f6a5d607e3aec656ea20cd6c1d157e055 Mon Sep 17 00:00:00 2001 From: aromaa Date: Sun, 24 Nov 2024 19:46:25 +0200 Subject: [PATCH 4/4] Implement Keys.BOUNDING_BOX_BASE_SIZE and Keys.BOUNDING_BOX_HEIGHT --- SpongeAPI | 2 +- .../world/entity/InteractionAccessor.java | 41 ++++++++++++++++ .../resources/mixins.sponge.accessors.json | 1 + .../data/provider/entity/EntityData.java | 4 ++ .../provider/entity/EntityDataProviders.java | 1 + .../data/provider/entity/InteractionData.java | 49 +++++++++++++++++++ 6 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/accessors/java/org/spongepowered/common/accessor/world/entity/InteractionAccessor.java create mode 100644 src/main/java/org/spongepowered/common/data/provider/entity/InteractionData.java diff --git a/SpongeAPI b/SpongeAPI index 529eaa9f17d..f695db1d1c5 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 529eaa9f17db8589abafa1db3b565efc2276aa84 +Subproject commit f695db1d1c59306d75c1ebf93e9c021335905e09 diff --git a/src/accessors/java/org/spongepowered/common/accessor/world/entity/InteractionAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/entity/InteractionAccessor.java new file mode 100644 index 00000000000..f890218652e --- /dev/null +++ b/src/accessors/java/org/spongepowered/common/accessor/world/entity/InteractionAccessor.java @@ -0,0 +1,41 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.accessor.world.entity; + +import net.minecraft.world.entity.Interaction; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Interaction.class) +public interface InteractionAccessor { + + @Invoker("getWidth") float invoker$getWidth(); + + @Invoker("getHeight") float invoker$getHeight(); + + @Invoker("setWidth") void invoker$setWidth(float width); + + @Invoker("setHeight") void invoker$setHeight(float height); +} diff --git a/src/accessors/resources/mixins.sponge.accessors.json b/src/accessors/resources/mixins.sponge.accessors.json index 24d57dc1f66..720308e5176 100644 --- a/src/accessors/resources/mixins.sponge.accessors.json +++ b/src/accessors/resources/mixins.sponge.accessors.json @@ -66,6 +66,7 @@ "world.entity.EntityAccessor", "world.entity.EntityTypeAccessor", "world.entity.ExperienceOrbAccessor", + "world.entity.InteractionAccessor", "world.entity.LightningBoltAccessor", "world.entity.LivingEntityAccessor", "world.entity.MobAccessor", diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java b/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java index 5e62f6e798b..69937fac579 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java @@ -249,6 +249,10 @@ public static void register(final DataProviderRegistrator registrator) { ((PortalProcessorBridge)h.portalProcess).bridge$init(h.level()); }) .delete(h -> h.portalProcess = null) + .create(Keys.BOUNDING_BOX_BASE_SIZE) + .get(h -> (double) h.getBbWidth()) + .create(Keys.BOUNDING_BOX_HEIGHT) + .get(h -> (double) h.getBbHeight()) .asMutable(EntityMaxAirBridge.class) .create(Keys.MAX_AIR) .get(EntityMaxAirBridge::bridge$getMaxAir) diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java b/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java index 29910a3ecac..39a1ea8b74a 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java @@ -75,6 +75,7 @@ public void registerProviders() { HorseData.register(this.registrator); HumanData.register(this.registrator); IdentifiableData.register(this.registrator); + InteractionData.register(this.registrator); InvulnerableData.register(this.registrator); IronGolemData.register(this.registrator); ItemData.register(this.registrator); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/InteractionData.java b/src/main/java/org/spongepowered/common/data/provider/entity/InteractionData.java new file mode 100644 index 00000000000..363bcbacff2 --- /dev/null +++ b/src/main/java/org/spongepowered/common/data/provider/entity/InteractionData.java @@ -0,0 +1,49 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.data.provider.entity; + +import org.spongepowered.api.data.Keys; +import org.spongepowered.common.accessor.world.entity.InteractionAccessor; +import org.spongepowered.common.data.provider.DataProviderRegistrator; + +public final class InteractionData { + + private InteractionData() { + } + + // @formatter:off + public static void register(final DataProviderRegistrator registrator) { + registrator + .asMutable(InteractionAccessor.class) + .create(Keys.BOUNDING_BOX_BASE_SIZE) + .get(h -> (double) h.invoker$getWidth()) + .set((h, v) -> h.invoker$setWidth(v.floatValue())) + .create(Keys.BOUNDING_BOX_HEIGHT) + .get(h -> (double) h.invoker$getHeight()) + .set((h, v) -> h.invoker$setHeight(v.floatValue())) + ; + } + // @formatter:on +}