diff --git a/SpongeAPI b/SpongeAPI
index cb4ee935103..ab94acf7c6b 160000
--- a/SpongeAPI
+++ b/SpongeAPI
@@ -1 +1 @@
-Subproject commit cb4ee935103e4cd09e9bcb7a4e8cd649e0287fc9
+Subproject commit ab94acf7c6b27a71ce6da210636ec546e3be22c0
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
deleted file mode 100644
index 665e527ab06..00000000000
--- a/gradle/verification-metadata.xml
+++ /dev/null
@@ -1,3669 +0,0 @@
-
-
-
- true
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java b/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java
index fbc9060b94c..4b17c828fcd 100644
--- a/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java
+++ b/src/main/java/org/spongepowered/common/bridge/world/TrackedWorldBridge.java
@@ -26,11 +26,16 @@
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
+import net.minecraft.world.phys.BlockHitResult;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.world.BlockChangeFlag;
@@ -41,6 +46,7 @@
import org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge;
import org.spongepowered.common.event.tracking.PhaseContext;
import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier;
+import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.WorldPipeline;
import java.util.Optional;
@@ -111,4 +117,5 @@ public interface TrackedWorldBridge {
*/
SpongeBlockSnapshot bridge$createSnapshotWithEntity(BlockState state, BlockPos pos, BlockChangeFlag updateFlag, @Nullable BlockEntity tileEntity);
+ InteractItemPipeline bridge$startInteractionChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, BlockHitResult blockRaytraceResultIn, BlockState blockstate, ItemStack copiedStack);
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java
index cabf97ef8ca..b1e025c7e73 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/EffectTransactor.java
@@ -30,13 +30,13 @@
import java.util.Deque;
public class EffectTransactor implements AutoCloseable {
- final @Nullable ResultingTransactionBySideEffect previousEffect;
+ final @Nullable ResultingTransactionBySideEffect, ?, ?, ?> previousEffect;
public final @Nullable GameTransaction<@NonNull ?> parent;
private final TransactionalCaptureSupplier supplier;
- private final ResultingTransactionBySideEffect effect;
+ private final ResultingTransactionBySideEffect, ?, ?, ?> effect;
- EffectTransactor(final ResultingTransactionBySideEffect effect, final @Nullable GameTransaction<@NonNull ?> parent,
- final @Nullable ResultingTransactionBySideEffect previousEffect, final TransactionalCaptureSupplier transactor) {
+ EffectTransactor(final ResultingTransactionBySideEffect, ?, ?, ?> effect, final @Nullable GameTransaction<@NonNull ?> parent,
+ final @Nullable ResultingTransactionBySideEffect, ?, ?, ?> previousEffect, final TransactionalCaptureSupplier transactor) {
/*
| ChangeBlock(1) <- head will be RemoveTileEntity(1), tail is still RemoveTileentity(1)
| |- RemoveTileEntity <- Head will be ChangeBlock(2) tail is still ChangeBlock(2)
@@ -55,7 +55,7 @@ public void close() {
&& this.parent.sideEffects != null
&& this.parent.getEffects().peekLast() == this.effect
) {
- final Deque effects = this.parent.getEffects();
+ final Deque> effects = this.parent.getEffects();
effects.removeLast();
if (effects.isEmpty()) {
this.parent.sideEffects = null;
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java
index d546d535e8e..fd733d01d77 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/GameTransaction.java
@@ -54,7 +54,7 @@ public abstract class GameTransaction implements
protected boolean cancelled = false;
// Children Definitions
- @Nullable LinkedList sideEffects;
+ @Nullable LinkedList> sideEffects;
// LinkedList node definitions
@Nullable GameTransaction<@NonNull ?> previous;
@@ -75,14 +75,14 @@ public final TransactionType extends E> getTransactionType() {
return this.transactionType;
}
- final Deque getEffects() {
+ final Deque> getEffects() {
if (this.sideEffects == null) {
this.sideEffects = new LinkedList<>();
}
return this.sideEffects;
}
- public final void addLast(final ResultingTransactionBySideEffect effect) {
+ public final void addLast(final ResultingTransactionBySideEffect, ?, ?, ?> effect) {
if (this.sideEffects == null) {
this.sideEffects = new LinkedList<>();
}
@@ -97,7 +97,7 @@ public final boolean hasAnyPrimaryChildrenTransactions() {
if (this.sideEffects == null) {
return false;
}
- for (final ResultingTransactionBySideEffect sideEffect : this.sideEffects) {
+ for (final ResultingTransactionBySideEffect, ?, ?, ?> sideEffect : this.sideEffects) {
@Nullable GameTransaction<@NonNull ?> transaction = sideEffect.head;
while (transaction != null) {
if (transaction.transactionType.isPrimary() || transaction.hasChildTransactions()) {
@@ -131,10 +131,17 @@ public abstract Optional generateEvent(
public final void markCancelled() {
this.cancelled = true;
this.childIterator().forEachRemaining(GameTransaction::markCancelled);
+ if (this.next != null && this.next.hasUnknownChainRequiringCancellation()) {
+ this.next.markCancelled();
+ }
}
public abstract boolean markCancelledTransactions(E event, ImmutableList extends GameTransaction> transactions);
+ protected boolean hasUnknownChainRequiringCancellation() {
+ return false;
+ }
+
public void postProcessEvent(final PhaseContext<@NonNull ?> context, final E event) {
}
@@ -183,16 +190,16 @@ protected void captureState() {
}
private static class ChildIterator implements Iterator> {
- private final Iterator effectIterator;
+ private final Iterator> effectIterator;
private @Nullable GameTransaction<@NonNull ?> cachedNext;
private @MonotonicNonNull GameTransaction<@NonNull ?> pointer;
private boolean hasNoRemainingElements = false;
- ChildIterator(final Iterator iterator) {
+ ChildIterator(final Iterator> iterator) {
// We're going to search the iterator's effects until we find the first at least
this.effectIterator = iterator;
while (this.effectIterator.hasNext()) {
- final ResultingTransactionBySideEffect next = this.effectIterator.next();
+ final ResultingTransactionBySideEffect, ?, ?, ?> next = this.effectIterator.next();
if (next.head != null) {
this.cachedNext = next.head;
this.pointer = next.head;
@@ -219,7 +226,7 @@ public boolean hasNext() {
// start search for the next, sadly because effects don't make a clean chain,
// there can be many effects with no transactions recorded
while (this.effectIterator.hasNext()) {
- final ResultingTransactionBySideEffect next = this.effectIterator.next();
+ final ResultingTransactionBySideEffect, ?, ?, ?> next = this.effectIterator.next();
if (next.head != null) {
this.cachedNext = next.head;
return true;
@@ -250,16 +257,16 @@ public boolean hasNext() {
private static class ReverseChildIterator implements Iterator> {
- private final Iterator effectIterator;
+ private final Iterator> effectIterator;
private @Nullable GameTransaction<@NonNull ?> cachedPrevious;
private @MonotonicNonNull GameTransaction<@NonNull ?> pointer;
private boolean hasNoRemainingElements = false;
- ReverseChildIterator(final Iterator iterator) {
+ ReverseChildIterator(final Iterator> iterator) {
// We're going to search the iterator's effects until we find the first at least
this.effectIterator = iterator;
while (this.effectIterator.hasNext()) {
- final ResultingTransactionBySideEffect next = this.effectIterator.next();
+ final ResultingTransactionBySideEffect, ?, ?, ?> next = this.effectIterator.next();
if (next.tail != null) {
this.pointer = next.tail;
this.cachedPrevious = next.tail;
@@ -287,7 +294,7 @@ public boolean hasNext() {
// start search for the next, sadly because effects don't make a clean chain,
// there can be many effects with no transactions recorded
while (this.effectIterator.hasNext()) {
- final ResultingTransactionBySideEffect next = this.effectIterator.next();
+ final ResultingTransactionBySideEffect, ?, ?, ?> next = this.effectIterator.next();
if (next.tail != null) {
this.cachedPrevious = next.tail;
return true;
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java
index c224628dbbc..3cae058b582 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/ResultingTransactionBySideEffect.java
@@ -33,12 +33,12 @@
import java.util.Iterator;
import java.util.Optional;
-public class ResultingTransactionBySideEffect {
- public final ProcessingSideEffect effect;
+public class ResultingTransactionBySideEffect {
+ public final ProcessingSideEffect effect;
@Nullable GameTransaction<@NonNull ?> head;
@Nullable GameTransaction<@NonNull ?> tail;
- public ResultingTransactionBySideEffect(final ProcessingSideEffect effect) {
+ public ResultingTransactionBySideEffect(final ProcessingSideEffect effect) {
this.effect = effect;
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java
index baa4a79567a..b12eba91265 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionSink.java
@@ -27,6 +27,7 @@
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
@@ -45,12 +46,14 @@
import net.minecraft.world.ticks.ScheduledTick;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.event.cause.entity.SpawnType;
import org.spongepowered.api.item.inventory.Inventory;
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
import org.spongepowered.api.item.inventory.Slot;
import org.spongepowered.api.item.inventory.crafting.CraftingInventory;
import org.spongepowered.api.item.inventory.transaction.SlotTransaction;
+import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.BlockChangeFlag;
import org.spongepowered.api.world.BlockChangeFlags;
import org.spongepowered.common.SpongeCommon;
@@ -72,6 +75,7 @@
import org.spongepowered.common.event.tracking.context.transaction.effect.EntityPerformingDropsEffect;
import org.spongepowered.common.event.tracking.context.transaction.effect.InventoryEffect;
import org.spongepowered.common.event.tracking.context.transaction.effect.PrepareBlockDrops;
+import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect;
import org.spongepowered.common.event.tracking.context.transaction.inventory.ClickCreativeMenuTransaction;
import org.spongepowered.common.event.tracking.context.transaction.inventory.ClickMenuTransaction;
import org.spongepowered.common.event.tracking.context.transaction.inventory.CloseMenuTransaction;
@@ -80,6 +84,7 @@
import org.spongepowered.common.event.tracking.context.transaction.inventory.CraftingTransaction;
import org.spongepowered.common.event.tracking.context.transaction.inventory.DropFromPlayerInventoryTransaction;
import org.spongepowered.common.event.tracking.context.transaction.inventory.ExplicitInventoryOmittedTransaction;
+import org.spongepowered.common.event.tracking.context.transaction.inventory.InteractItemTransaction;
import org.spongepowered.common.event.tracking.context.transaction.inventory.InventoryTransaction;
import org.spongepowered.common.event.tracking.context.transaction.inventory.OpenMenuTransaction;
import org.spongepowered.common.event.tracking.context.transaction.inventory.PlaceRecipeTransaction;
@@ -97,6 +102,7 @@
import org.spongepowered.common.world.BlockChange;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
import org.spongepowered.common.world.volume.VolumeStreamUtils;
+import org.spongepowered.math.vector.Vector3d;
import java.lang.ref.WeakReference;
import java.util.Objects;
@@ -121,7 +127,7 @@ interface TransactionSink {
@Deprecated
void logTransaction(StatefulTransaction transaction);
- EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect);
+ EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect);
default ChangeBlock logBlockChange(final SpongeBlockSnapshot originalBlockSnapshot, final BlockState newState,
final BlockChangeFlag flags
@@ -174,7 +180,7 @@ default EffectTransactor logBlockDrops(
original.blockChange = BlockChange.MODIFY;
final PrepareBlockDropsTransaction transaction = new PrepareBlockDropsTransaction(pos, state, original);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(PrepareBlockDrops.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(PrepareBlockDrops.getInstance()));
}
@SuppressWarnings("ConstantConditions")
@@ -258,7 +264,7 @@ default boolean logTileRemoval(final @Nullable BlockEntity tileentity, final Sup
final EntityPerformingDropsTransaction transaction = new EntityPerformingDropsTransaction(entity);
this.logTransaction(transaction);
if (transaction.recorded()) {
- return this.pushEffect(new ResultingTransactionBySideEffect(EntityPerformingDropsEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(EntityPerformingDropsEffect.getInstance()));
}
return null;
}
@@ -334,44 +340,44 @@ default EffectTransactor logClickContainer(
final ClickMenuTransaction transaction = new ClickMenuTransaction(
player, menu, slotNum, buttonNum, clickType, slot, ItemStackUtil.snapshotOf(player.containerMenu.getCarried()));
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default EffectTransactor logPlayerInventoryChangeWithEffect(final Player player, final PlayerInventoryTransaction.EventCreator eventCreator) {
final PlayerInventoryTransaction transaction = new PlayerInventoryTransaction(player, eventCreator);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default EffectTransactor logCreativeClickContainer(final int slotNum, final ItemStackSnapshot creativeStack, final Player player) {
final ClickCreativeMenuTransaction transaction = new ClickCreativeMenuTransaction(player, slotNum, creativeStack);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default EffectTransactor logDropFromPlayerInventory(final ServerPlayer player, final boolean dropAll) {
final DropFromPlayerInventoryTransaction transaction = new DropFromPlayerInventoryTransaction(player, dropAll);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default EffectTransactor logOpenInventory(final Player player) {
final OpenMenuTransaction transaction = new OpenMenuTransaction(player);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default EffectTransactor logCloseInventory(final Player player, final boolean clientSource) {
final CloseMenuTransaction transaction = new CloseMenuTransaction(player, clientSource);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default EffectTransactor logPlaceRecipe(final boolean shift, final RecipeHolder> recipe, final ServerPlayer player, final CraftingInventory craftInv) {
final PlaceRecipeTransaction transaction = new PlaceRecipeTransaction(player, shift, recipe, craftInv);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default void logSelectTrade(final ServerPlayer player, final int item) {
@@ -403,12 +409,20 @@ default void logCrafting(final Player player, @Nullable final ItemStack craftedS
default EffectTransactor logIgnoredInventory(AbstractContainerMenu containerMenu) {
final ExplicitInventoryOmittedTransaction transaction = new ExplicitInventoryOmittedTransaction(containerMenu);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
default EffectTransactor logInventoryTransaction(final AbstractContainerMenu containerMenu) {
final InventoryTransaction transaction = new InventoryTransaction((Inventory) containerMenu);
this.logTransaction(transaction);
- return this.pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()));
+ return this.pushEffect(new ResultingTransactionBySideEffect<>(InventoryEffect.getInstance()));
}
+
+ default void logSecondaryInteractionTransaction(
+ final ServerPlayer playerIn, final ItemStack stackIn, final Vector3d hitVec,
+ final BlockSnapshot snapshot, final Direction direction, final InteractionHand handIn) {
+ final InteractItemTransaction transaction = new InteractItemTransaction(playerIn, stackIn, hitVec, snapshot, direction, handIn);
+ this.logTransaction(transaction);
+ }
+
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java
index 29288ef3395..9a32ad5960b 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/TransactionalCaptureSupplier.java
@@ -38,6 +38,7 @@
import org.spongepowered.common.event.tracking.PhaseTracker;
import org.spongepowered.common.event.tracking.context.ICaptureSupplier;
import org.spongepowered.common.event.tracking.context.transaction.effect.PrepareBlockDrops;
+import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect;
import org.spongepowered.common.event.tracking.context.transaction.type.TransactionType;
import java.util.Collections;
@@ -94,9 +95,9 @@ public boolean isEmpty() {
*/
@Override
- public EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect) {
+ public EffectTransactor pushEffect(final ResultingTransactionBySideEffect effect) {
final GameTransaction<@NonNull ?> parentTransaction = Optional.ofNullable(this.effect)
- .map(child -> (GameTransaction) child.tail)
+ .map(child -> child.tail)
.orElse(Objects.requireNonNull(this.tail, "Somehow pushing a new effect without an owning Transaction"));
final EffectTransactor effectTransactor = new EffectTransactor(effect, parentTransaction, this.effect, this);
this.effect = effect;
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java
index 51e1a40d109..b5d84553284 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/AddBlockLootDropsEffect.java
@@ -40,7 +40,7 @@
import org.spongepowered.common.util.VecHelper;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class AddBlockLootDropsEffect implements ProcessingSideEffect {
+public final class AddBlockLootDropsEffect implements ProcessingSideEffect {
private static final class Holder {
static final AddBlockLootDropsEffect INSTANCE = new AddBlockLootDropsEffect();
@@ -54,9 +54,11 @@ public static AddBlockLootDropsEffect getInstance() {
@Override
public EffectResult processSideEffect(
- final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag,
- final int limit
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final BlockState newState = args.newState();
+ final SpongeBlockChangeFlag flag = args.flag();
+ final int limit = args.limit();
final PhaseContext<@NonNull ?> phaseContext = PhaseTracker.getInstance().getPhaseContext();
final ServerLevel world = pipeline.getServerWorld();
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java
index bb2a8c66667..1519511ee19 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockAddedEffect.java
@@ -25,11 +25,12 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class BlockAddedEffect implements ProcessingSideEffect {
+public final class BlockAddedEffect implements ProcessingSideEffect {
private static final class Holder {
static final BlockAddedEffect INSTANCE = new BlockAddedEffect();
@@ -42,9 +43,11 @@ public static BlockAddedEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final var flag = args.flag();
+ final var newState = args.newState();
// Vanilla will check if this is the server
// if (!this.level.isClientSide) {
// var2.onPlace(this.level, var1, var11, var3);
@@ -55,6 +58,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
if (flag.performBlockPhysics()) {
newState.onPlace(pipeline.getServerWorld(), oldState.pos, oldState.state, flag.movingBlocks());
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockChangeArgs.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockChangeArgs.java
new file mode 100644
index 00000000000..3c011a8a4e6
--- /dev/null
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BlockChangeArgs.java
@@ -0,0 +1,37 @@
+/*
+ * 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.event.tracking.context.transaction.effect;
+
+import net.minecraft.world.level.block.state.BlockState;
+import org.spongepowered.common.world.SpongeBlockChangeFlag;
+
+public record BlockChangeArgs(
+ BlockState newState,
+ SpongeBlockChangeFlag flag,
+ int limit
+) implements ProcessingSideEffect.Args {
+
+}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java
index 8664482ce9b..5d4300c3fb2 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/BroadcastInventoryChangesEffect.java
@@ -25,14 +25,14 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor;
import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect;
import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class BroadcastInventoryChangesEffect implements ProcessingSideEffect {
+public final class BroadcastInventoryChangesEffect implements ProcessingSideEffect {
private static final class Holder {
static final BroadcastInventoryChangesEffect INSTANCE = new BroadcastInventoryChangesEffect();
@@ -41,16 +41,16 @@ public static BroadcastInventoryChangesEffect getInstance() {
return Holder.INSTANCE;
}
public static EffectTransactor transact(final TransactionalCaptureSupplier transactor) {
- return transactor.pushEffect(new ResultingTransactionBySideEffect(BroadcastInventoryChangesEffect.getInstance()));
+ return transactor.pushEffect(new ResultingTransactionBySideEffect<>(BroadcastInventoryChangesEffect.getInstance()));
}
BroadcastInventoryChangesEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java
index f3693379738..c97e9417f9e 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/CheckBlockPostPlacementIsSameEffect.java
@@ -26,11 +26,11 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunkSection;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class CheckBlockPostPlacementIsSameEffect implements ProcessingSideEffect {
+public final class CheckBlockPostPlacementIsSameEffect implements ProcessingSideEffect {
private static final class Holder {
static final CheckBlockPostPlacementIsSameEffect INSTANCE = new CheckBlockPostPlacementIsSameEffect();
}
@@ -40,9 +40,10 @@ public static CheckBlockPostPlacementIsSameEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final var newState = args.newState();
final LevelChunkSection chunkSection = pipeline.getAffectedSection();
final int x = oldState.pos.getX() & 15;
final int y = oldState.pos.getY() & 15;
@@ -51,6 +52,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
if (!currentState.is(newState.getBlock())) {
return new EffectResult(newState, true);
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java
index eecb265b5b7..b283c89e7ca 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ChunkChangeCompleteEffect.java
@@ -30,11 +30,12 @@
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class ChunkChangeCompleteEffect implements ProcessingSideEffect {
+public final class ChunkChangeCompleteEffect implements ProcessingSideEffect {
private static final class Holder {
static final ChunkChangeCompleteEffect INSTANCE = new ChunkChangeCompleteEffect();
}
+
ChunkChangeCompleteEffect() {
}
@@ -43,10 +44,9 @@ public static ChunkChangeCompleteEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
-
final LevelChunk chunk = pipeline.getAffectedChunk();
// this.unsaved = true; // Vanilla, we'll just call the accessor available
chunk.setUnsaved(true);
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java
index 3ceacfb2e23..e6076ae2b0b 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EffectResult.java
@@ -25,30 +25,35 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.block.state.BlockState;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Collections;
import java.util.List;
-public final class EffectResult {
+public final class EffectResult<@Nullable R> {
- public static final EffectResult NULL_RETURN = new EffectResult(null, true);
- public static final EffectResult NULL_PASS = new EffectResult(null, false);
+ public static <@Nullable T> EffectResult nullReturn() {
+ return new EffectResult<>(null, true);
+ }
+
+ public static <@Nullable T> EffectResult nullPass() {
+ return new EffectResult<>(null, false);
+ }
- public final @Nullable BlockState resultingState;
+ public final @Nullable R resultingState;
public final List drops;
public final boolean hasResult;
- public EffectResult(final @Nullable BlockState resultingState, final boolean hasResult) {
+ public EffectResult(final @Nullable R resultingState, final boolean hasResult) {
this.resultingState = resultingState;
this.hasResult = hasResult;
this.drops = Collections.emptyList();
}
- public EffectResult(final @Nullable BlockState resultingState, final List drops, final boolean hasResult) {
+ public EffectResult(final @Nullable R resultingState, final List drops, final boolean hasResult) {
this.resultingState = resultingState;
this.drops = drops;
this.hasResult = hasResult;
}
+
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java
index eeb7ee4e4e5..4d9d4065a3d 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/EntityPerformingDropsEffect.java
@@ -25,11 +25,11 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class EntityPerformingDropsEffect implements ProcessingSideEffect {
+public final class EntityPerformingDropsEffect implements ProcessingSideEffect {
private static final class Holder {
static final EntityPerformingDropsEffect INSTANCE = new EntityPerformingDropsEffect();
@@ -40,10 +40,10 @@ public static EntityPerformingDropsEffect getInstance() {
EntityPerformingDropsEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java
index baaf064fadd..bfc7c1610ac 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ExplodeBlockEffect.java
@@ -28,14 +28,14 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.PhaseContext;
import org.spongepowered.common.event.tracking.PhaseTracker;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
import org.spongepowered.common.event.tracking.phase.general.ExplosionContext;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class ExplodeBlockEffect implements ProcessingSideEffect {
+public final class ExplodeBlockEffect implements ProcessingSideEffect {
private static final class Holder {
static final ExplodeBlockEffect INSTANCE = new ExplodeBlockEffect();
@@ -47,11 +47,9 @@ public static ExplodeBlockEffect getInstance() {
ExplodeBlockEffect() {}
- @SuppressWarnings({"unchecked", "rawtypes"})
@Override
- public EffectResult processSideEffect(
- final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag,
- final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
final PhaseContext<@NonNull ?> phaseContext = PhaseTracker.getInstance().getPhaseContext();
@@ -61,6 +59,6 @@ public EffectResult processSideEffect(
oldState.state.getBlock().wasExploded(world, pos, ((ExplosionContext) phaseContext).getExplosion());
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionArgs.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionArgs.java
new file mode 100644
index 00000000000..14247da9acd
--- /dev/null
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionArgs.java
@@ -0,0 +1,43 @@
+/*
+ * 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.event.tracking.context.transaction.effect;
+
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.phys.BlockHitResult;
+
+public record InteractionArgs(
+ Level world,
+ ServerPlayer player,
+ InteractionHand hand,
+ BlockHitResult blockRaytraceResult,
+ BlockState blockstate,
+ ItemStack copiedStack
+) implements ProcessingSideEffect.Args {
+}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionUseItemEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionUseItemEffect.java
new file mode 100644
index 00000000000..baec608bece
--- /dev/null
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InteractionUseItemEffect.java
@@ -0,0 +1,60 @@
+/*
+ * 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.event.tracking.context.transaction.effect;
+
+import net.minecraft.world.InteractionResult;
+import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor;
+import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction;
+import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline;
+
+public final class InteractionUseItemEffect implements ProcessingSideEffect {
+
+ private static final class Holder {
+ static final InteractionUseItemEffect INSTANCE = new InteractionUseItemEffect();
+ }
+
+ public static InteractionUseItemEffect getInstance() {
+ return Holder.INSTANCE;
+ }
+
+ @Override
+ public EffectResult processSideEffect(
+ InteractItemPipeline pipeline, InteractionResult oldState, InteractionArgs args
+ ) {
+ final var player = args.player();
+ final var hand = args.hand();
+ final var world = args.world();
+ final var blockRaytraceResult = args.blockRaytraceResult();
+ final var blockstate = args.blockstate();
+ final InteractionResult result = blockstate.use(world, player, hand, blockRaytraceResult);
+ pipeline.transactor().logPlayerInventoryChange(args.player(), PlayerInventoryTransaction.EventCreator.STANDARD);
+ try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(pipeline.transactor())) {
+ args.player().containerMenu.broadcastChanges();
+ }
+ return new EffectResult<>(result, true);
+ }
+
+}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java
index 459b9c9c038..e58f1cb2849 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/InventoryEffect.java
@@ -25,11 +25,11 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class InventoryEffect implements ProcessingSideEffect {
+public final class InventoryEffect implements ProcessingSideEffect {
private static final class Holder {
static final InventoryEffect INSTANCE = new InventoryEffect();
@@ -40,10 +40,10 @@ public static InventoryEffect getInstance() {
InventoryEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java
index 63f49fc4df6..ab322ffc648 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyClientEffect.java
@@ -32,7 +32,7 @@
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class NotifyClientEffect implements ProcessingSideEffect {
+public final class NotifyClientEffect implements ProcessingSideEffect {
private static final class Holder {
static final NotifyClientEffect INSTANCE = new NotifyClientEffect();
@@ -45,9 +45,11 @@ public static NotifyClientEffect getInstance() {
NotifyClientEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final BlockState newState = args.newState();
+ final SpongeBlockChangeFlag flag = args.flag();
final LevelChunk chunk = pipeline.getAffectedChunk();
final ServerLevel world = pipeline.getServerWorld();
@@ -58,7 +60,7 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
// this.notifyBlockUpdate(pos, blockstate, newWorldState, flags);
world.sendBlockUpdated(oldState.pos, oldState.state, newState, flag.getRawFlag());
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java
index 8702afdf483..309f7f8d8a1 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/NotifyNeighborSideEffect.java
@@ -26,11 +26,11 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class NotifyNeighborSideEffect implements ProcessingSideEffect {
+public final class NotifyNeighborSideEffect implements ProcessingSideEffect {
private static final class Holder {
static final NotifyNeighborSideEffect INSTANCE = new NotifyNeighborSideEffect();
@@ -44,9 +44,11 @@ public static NotifyNeighborSideEffect getInstance() {
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final var flag = args.flag();
+ final var newState = args.newState();
final ServerLevel world = pipeline.getServerWorld();
// Vanilla isClientSide is redundant
@@ -59,7 +61,7 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
world.updateNeighbourForOutputSignal(oldState.pos, newState.getBlock());
}
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java
index ffaaf61c60b..60be05b5664 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/OldBlockOnReplaceEffect.java
@@ -25,11 +25,11 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class OldBlockOnReplaceEffect implements ProcessingSideEffect {
+public final class OldBlockOnReplaceEffect implements ProcessingSideEffect {
private static final class Holder {
static final OldBlockOnReplaceEffect INSTANCE = new OldBlockOnReplaceEffect();
}
@@ -42,9 +42,8 @@ public static OldBlockOnReplaceEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(
- final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
// Normally, vanilla does this:
// boolean var14 = var11.hasBlockEntity();
@@ -56,7 +55,9 @@ public EffectResult processSideEffect(
// However, since we know we're not on the client (ChunkPipeline is not
// used outside of server world context)
// we can safely just do oldState.onRemove(this.level, var1, var2, var3).
+ final var flag = args.flag();
+ final var newState = args.newState();
oldState.state.onRemove(pipeline.getServerWorld(), oldState.pos, newState, flag.movingBlocks());
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java
index 0e6a2b9d443..04439d1ccac 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PerformBlockDropsFromDestruction.java
@@ -27,11 +27,11 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class PerformBlockDropsFromDestruction implements ProcessingSideEffect {
+public final class PerformBlockDropsFromDestruction implements ProcessingSideEffect {
private static final class Holder {
static final PerformBlockDropsFromDestruction INSTANCE = new PerformBlockDropsFromDestruction();
@@ -43,11 +43,11 @@ public static PerformBlockDropsFromDestruction getInstance() {
PerformBlockDropsFromDestruction() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
Block.dropResources(oldState.state, pipeline.getServerWorld(), oldState.pos, oldState.tileEntity, oldState.destroyer, ItemStack.EMPTY);
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PlayerContainerRefreshEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PlayerContainerRefreshEffect.java
new file mode 100644
index 00000000000..153730d812f
--- /dev/null
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PlayerContainerRefreshEffect.java
@@ -0,0 +1,53 @@
+/*
+ * 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.event.tracking.context.transaction.effect;
+
+import net.minecraft.world.InteractionResult;
+import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor;
+import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction;
+import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline;
+
+public final class PlayerContainerRefreshEffect implements ProcessingSideEffect {
+
+ private static final class Holder {
+ static final PlayerContainerRefreshEffect INSTANCE = new PlayerContainerRefreshEffect();
+ }
+
+ public static PlayerContainerRefreshEffect getInstance() {
+ return Holder.INSTANCE;
+ }
+
+ @Override
+ public EffectResult processSideEffect(
+ InteractItemPipeline pipeline, InteractionResult oldState, InteractionArgs args
+ ) {
+ pipeline.transactor().logPlayerInventoryChange(args.player(), PlayerInventoryTransaction.EventCreator.STANDARD);
+ try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(pipeline.transactor())) {
+ args.player().containerMenu.broadcastChanges();
+ }
+ return EffectResult.nullPass();
+ }
+}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java
index 9c3c772729e..4ea2225adf3 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/PrepareBlockDrops.java
@@ -25,11 +25,11 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class PrepareBlockDrops implements ProcessingSideEffect {
+public final class PrepareBlockDrops implements ProcessingSideEffect {
private static final class Holder {
static final PrepareBlockDrops INSTANCE = new PrepareBlockDrops();
@@ -41,10 +41,10 @@ public static PrepareBlockDrops getInstance() {
PrepareBlockDrops() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java
index 2d62b184f61..ecbea460ff5 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/ProcessingSideEffect.java
@@ -24,16 +24,13 @@
*/
package org.spongepowered.common.event.tracking.context.transaction.effect;
-import net.minecraft.world.level.block.state.BlockState;
-import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
-import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
+import org.checkerframework.checker.nullness.qual.Nullable;
@FunctionalInterface
-public interface ProcessingSideEffect {
+public interface ProcessingSideEffect {
- EffectResult processSideEffect(BlockPipeline pipeline, PipelineCursor oldState, BlockState newState, SpongeBlockChangeFlag flag,
- int limit
- );
+ EffectResult processSideEffect(T pipeline, C oldState, A args);
+
+ sealed interface Args permits BlockChangeArgs, InteractionArgs {}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java
index cc118789df8..4080bed5029 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/RemoveTileEntityFromChunkEffect.java
@@ -28,9 +28,8 @@
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class RemoveTileEntityFromChunkEffect implements ProcessingSideEffect {
+public final class RemoveTileEntityFromChunkEffect implements ProcessingSideEffect {
private static final class Holder {
static final RemoveTileEntityFromChunkEffect INSTANCE = new RemoveTileEntityFromChunkEffect();
@@ -43,14 +42,14 @@ public static RemoveTileEntityFromChunkEffect getInstance() {
RemoveTileEntityFromChunkEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
final BlockEntity tileEntity = oldState.tileEntity;
if (tileEntity == null) {
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
pipeline.getAffectedChunk().removeBlockEntity(oldState.pos);
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java
index 7733123bc27..10e1d5813ee 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetAndRegisterBlockEntityToLevelChunk.java
@@ -31,9 +31,8 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class SetAndRegisterBlockEntityToLevelChunk implements ProcessingSideEffect {
+public final class SetAndRegisterBlockEntityToLevelChunk implements ProcessingSideEffect {
private static final class Holder {
static final SetAndRegisterBlockEntityToLevelChunk INSTANCE = new SetAndRegisterBlockEntityToLevelChunk();
@@ -46,17 +45,16 @@ public static SetAndRegisterBlockEntityToLevelChunk getInstance() {
SetAndRegisterBlockEntityToLevelChunk() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag,
- final int limit
+ public EffectResult processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
final ServerLevel serverWorld = pipeline.getServerWorld();
final @Nullable BlockEntity blockEntity = oldState.tileEntity;
final BlockPos pos = oldState.pos;
if (serverWorld.isOutsideBuildHeight(pos)) {
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
pipeline.getAffectedChunk().addAndRegisterBlockEntity(blockEntity);
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java
index 6db0b84c8fa..390b88b3278 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SetBlockToChunkSectionEffect.java
@@ -28,9 +28,8 @@
import net.minecraft.world.level.chunk.LevelChunkSection;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class SetBlockToChunkSectionEffect implements ProcessingSideEffect {
+public final class SetBlockToChunkSectionEffect implements ProcessingSideEffect {
private static final class Holder {
private static final SetBlockToChunkSectionEffect INSTANCE = new SetBlockToChunkSectionEffect();
@@ -42,17 +41,17 @@ public static SetBlockToChunkSectionEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final BlockState newState = args.newState();
final LevelChunkSection chunkSection = pipeline.getAffectedSection();
final int x = oldState.pos.getX() & 15;
final int y = oldState.pos.getY() & 15;
final int z = oldState.pos.getZ() & 15;
final BlockState oldStateReturned = chunkSection.setBlockState(x, y, z, newState);
if (oldStateReturned == newState) {
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java
index b167636ec06..5b5304022cf 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/SpawnDestructBlocksEffect.java
@@ -29,13 +29,13 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
import java.util.List;
-public final class SpawnDestructBlocksEffect implements ProcessingSideEffect {
+public final class SpawnDestructBlocksEffect implements ProcessingSideEffect {
private static final class Holder {
static final SpawnDestructBlocksEffect INSTANCE = new SpawnDestructBlocksEffect();
@@ -47,11 +47,9 @@ public static SpawnDestructBlocksEffect getInstance() {
SpawnDestructBlocksEffect() {}
- @SuppressWarnings({"unchecked", "rawtypes"})
@Override
- public EffectResult processSideEffect(
- final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState, final SpongeBlockChangeFlag flag,
- final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
final ServerLevel world = pipeline.getServerWorld();
final BlockPos pos = oldState.pos;
@@ -60,6 +58,6 @@ public EffectResult processSideEffect(
drops.forEach(drop -> Block.popResource(world, pos, drop));
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java
index b27cfad1ec7..9a665d98ebc 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateChunkLightManagerEffect.java
@@ -26,11 +26,11 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunkSection;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class UpdateChunkLightManagerEffect implements ProcessingSideEffect {
+public final class UpdateChunkLightManagerEffect implements ProcessingSideEffect {
private static final class Holder {
static final UpdateChunkLightManagerEffect INSTANCE = new UpdateChunkLightManagerEffect();
@@ -43,9 +43,8 @@ public static UpdateChunkLightManagerEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag,
- final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
final LevelChunkSection chunkSection = pipeline.getAffectedSection();
final boolean wasEmpty = pipeline.wasEmpty();
@@ -53,6 +52,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
if (wasEmpty != isStillEmpty) {
pipeline.getServerWorld().getChunkSource().getLightEngine().updateSectionStatus(oldState.pos, isStillEmpty);
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java
index ca520619017..7bc888a6774 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateConnectingBlocksEffect.java
@@ -27,11 +27,11 @@
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class UpdateConnectingBlocksEffect implements ProcessingSideEffect {
+public final class UpdateConnectingBlocksEffect implements ProcessingSideEffect {
private static final class Holder {
static final UpdateConnectingBlocksEffect INSTANCE = new UpdateConnectingBlocksEffect();
@@ -44,11 +44,14 @@ public static UpdateConnectingBlocksEffect getInstance() {
UpdateConnectingBlocksEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
final ServerLevel world = pipeline.getServerWorld();
final BlockPos pos = oldState.pos;
+ final var flag = args.flag();
+ final var newState = args.newState();
+ final var limit = args.limit();
if (flag.updateNeighboringShapes() && limit > 0) {
// int i = p_241211_3_ & -34; // Vanilla negates 34 to flip neighbor notification and and "state drops"
final int withoutNeighborDropsAndNestedNeighborUpdates = flag.asNestedNeighborUpdates().getRawFlag();
@@ -60,7 +63,7 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
newState.updateIndirectNeighbourShapes(world, pos, withoutNeighborDropsAndNestedNeighborUpdates, limit - 1);
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java
index 00693ff8e4a..8d33d0815a9 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateHeightMapEffect.java
@@ -26,14 +26,14 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.Heightmap;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.accessor.world.level.chunk.ChunkAccessAccessor;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
import java.util.Map;
-public final class UpdateHeightMapEffect implements ProcessingSideEffect {
+public final class UpdateHeightMapEffect implements ProcessingSideEffect {
private static final class Holder {
static final UpdateHeightMapEffect INSTANCE = new UpdateHeightMapEffect();
@@ -46,9 +46,10 @@ public static UpdateHeightMapEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final var newState = args.newState();
final Map heightMap = ((ChunkAccessAccessor) pipeline.getAffectedChunk()).accessor$heightmaps();
if (heightMap == null) {
throw new IllegalStateException("Heightmap dereferenced!");
@@ -60,6 +61,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
heightMap.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(x, y, z, newState);
heightMap.get(Heightmap.Types.OCEAN_FLOOR).update(x, y, z, newState);
heightMap.get(Heightmap.Types.WORLD_SURFACE).update(x, y, z, newState);
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java
index 38c38aeaed3..b58ed1430c8 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateLightSideEffect.java
@@ -26,11 +26,11 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class UpdateLightSideEffect implements ProcessingSideEffect {
+public final class UpdateLightSideEffect implements ProcessingSideEffect {
private static final class Holder {
static final UpdateLightSideEffect INSTANCE = new UpdateLightSideEffect();
@@ -44,12 +44,13 @@ public static UpdateLightSideEffect getInstance() {
}
@Override
- public EffectResult processSideEffect(
+ public EffectResult<@Nullable BlockState> processSideEffect(
final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ final BlockChangeArgs args
) {
+ final var flag = args.flag();
if (!flag.updateLighting()) {
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
final int originalOpactiy = oldState.opacity;
final ServerLevel serverWorld = pipeline.getServerWorld();
@@ -80,7 +81,7 @@ public EffectResult processSideEffect(
// this.profiler.endSection();
serverWorld.getProfiler().pop();
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java
index 0ecc8ef372d..00137c776da 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateOrCreateNewTileEntityPostPlacementEffect.java
@@ -33,9 +33,8 @@
import org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class UpdateOrCreateNewTileEntityPostPlacementEffect implements ProcessingSideEffect {
+public final class UpdateOrCreateNewTileEntityPostPlacementEffect implements ProcessingSideEffect {
private static final class Holder {
static final UpdateOrCreateNewTileEntityPostPlacementEffect INSTANCE = new UpdateOrCreateNewTileEntityPostPlacementEffect();
@@ -49,9 +48,10 @@ public static UpdateOrCreateNewTileEntityPostPlacementEffect getInstance() {
@SuppressWarnings("deprecation")
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final var newState = args.newState();
final ServerLevel serverWorld = pipeline.getServerWorld();
final LevelChunk chunk = pipeline.getAffectedChunk();
if (((BlockStateBridge) newState).bridge$hasTileEntity()) {
@@ -69,6 +69,6 @@ public EffectResult processSideEffect(final BlockPipeline pipeline, final Pipeli
((LevelChunkAccessor) chunk).accessor$updateBlockEntityTicker(maybeNewTileEntity);
}
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java
index 67608577360..6f58022fb8e 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/UpdateWorldRendererEffect.java
@@ -25,11 +25,11 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class UpdateWorldRendererEffect implements ProcessingSideEffect {
+public final class UpdateWorldRendererEffect implements ProcessingSideEffect {
private static final class Holder {
static final UpdateWorldRendererEffect INSTANCE = new UpdateWorldRendererEffect();
@@ -42,12 +42,13 @@ public static UpdateWorldRendererEffect getInstance() {
UpdateWorldRendererEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
- final BlockState newState, final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState,
+ final BlockChangeArgs args
) {
+ final var newState = args.newState();
if (oldState.state != newState) {
pipeline.getServerWorld().setBlocksDirty(oldState.pos, oldState.state, newState);
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java
index 3afdc4e476f..28552ca395b 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldBlockChangeCompleteEffect.java
@@ -29,7 +29,7 @@
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class WorldBlockChangeCompleteEffect implements ProcessingSideEffect{
+public final class WorldBlockChangeCompleteEffect implements ProcessingSideEffect {
private static final class Holder {
static final WorldBlockChangeCompleteEffect INSTANCE = new WorldBlockChangeCompleteEffect();
@@ -42,9 +42,10 @@ public static WorldBlockChangeCompleteEffect getInstance() {
WorldBlockChangeCompleteEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
+ final BlockState newState = args.newState();
+ final SpongeBlockChangeFlag flag = args.flag();
if (flag.notifyPathfinding()) {
pipeline.getServerWorld().onBlockStateChange(oldState.pos, oldState.state, newState);
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java
index d1dafaa2841..2bb6737698e 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/effect/WorldDestroyBlockLevelEffect.java
@@ -27,11 +27,11 @@
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.BlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
-import org.spongepowered.common.world.SpongeBlockChangeFlag;
-public final class WorldDestroyBlockLevelEffect implements ProcessingSideEffect {
+public final class WorldDestroyBlockLevelEffect implements ProcessingSideEffect {
private static final class Holder {
static final WorldDestroyBlockLevelEffect INSTANCE = new WorldDestroyBlockLevelEffect();
@@ -44,12 +44,12 @@ public static WorldDestroyBlockLevelEffect getInstance() {
WorldDestroyBlockLevelEffect() {}
@Override
- public EffectResult processSideEffect(final BlockPipeline pipeline, final PipelineCursor oldState, final BlockState newState,
- final SpongeBlockChangeFlag flag, final int limit
+ public EffectResult<@Nullable BlockState> processSideEffect(
+ final BlockPipeline pipeline, final PipelineCursor oldState, final BlockChangeArgs args
) {
if (!(oldState.state.getBlock() instanceof BaseFireBlock)) {
pipeline.getServerWorld().levelEvent(2001, oldState.pos, Block.getId(oldState.state));
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
}
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InteractItemTransaction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InteractItemTransaction.java
new file mode 100644
index 00000000000..b02cfaaba3f
--- /dev/null
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InteractItemTransaction.java
@@ -0,0 +1,102 @@
+/*
+ * 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.event.tracking.context.transaction.inventory;
+
+import com.google.common.collect.ImmutableList;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.item.ItemStack;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.api.block.BlockSnapshot;
+import org.spongepowered.api.event.Cause;
+import org.spongepowered.api.event.CauseStackManager;
+import org.spongepowered.api.event.block.InteractBlockEvent;
+import org.spongepowered.api.item.inventory.ItemStackSnapshot;
+import org.spongepowered.api.util.Direction;
+import org.spongepowered.common.event.tracking.PhaseContext;
+import org.spongepowered.common.event.tracking.context.transaction.GameTransaction;
+import org.spongepowered.common.event.tracking.context.transaction.type.TransactionTypes;
+import org.spongepowered.common.item.util.ItemStackUtil;
+import org.spongepowered.common.util.PrettyPrinter;
+import org.spongepowered.math.vector.Vector3d;
+
+import java.util.Optional;
+import java.util.function.BiConsumer;
+
+public class InteractItemTransaction extends GameTransaction {
+
+
+ private final Vector3d hitVec;
+ private final BlockSnapshot snapshot;
+ private final Direction direction;
+ private final InteractionHand hand;
+ private final ItemStackSnapshot stack;
+
+ public InteractItemTransaction(ServerPlayer playerIn, ItemStack stackIn, Vector3d hitVec, BlockSnapshot snapshot, Direction direction, InteractionHand handIn) {
+ super(TransactionTypes.INTERACT_BLOCK_SECONDARY.get());
+ this.stack = ItemStackUtil.snapshotOf(stackIn);
+ this.hitVec = hitVec;
+ this.snapshot = snapshot;
+ this.direction = direction;
+ this.hand = handIn;
+ }
+
+
+ @Override
+ public Optional, CauseStackManager.StackFrame>> getFrameMutator(
+ @Nullable GameTransaction<@NonNull ?> parent
+ ) {
+ return Optional.empty();
+ }
+
+ @Override
+ public void addToPrinter(PrettyPrinter printer) {
+
+ }
+
+ @Override
+ public Optional generateEvent(
+ final PhaseContext<@NonNull ?> context,
+ final @Nullable GameTransaction<@NonNull ?> parent,
+ final ImmutableList> gameTransactions,
+ final Cause currentCause
+ ) {
+ return Optional.empty();
+ }
+
+ @Override
+ public void restore(PhaseContext<@NonNull ?> context, InteractBlockEvent.Secondary.Composite event) {
+
+ }
+
+ @Override
+ public boolean markCancelledTransactions(
+ final InteractBlockEvent.Secondary.Composite event,
+ final ImmutableList extends GameTransaction> gameTransactions) {
+ return false;
+ }
+}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java
index 45672accf3a..be736521434 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/inventory/InventoryBasedTransaction.java
@@ -67,6 +67,11 @@ protected InventoryBasedTransaction(final Inventory inventory) {
this.inventory = inventory;
}
+ @Override
+ protected boolean hasUnknownChainRequiringCancellation() {
+ return true;
+ }
+
@Override
public Optional, CauseStackManager.StackFrame>> getFrameMutator(
@Nullable final GameTransaction<@NonNull ?> parent
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java
index a6b34239bc1..7c33c35b7af 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/ChunkPipeline.java
@@ -37,6 +37,7 @@
import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor;
import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect;
import org.spongepowered.common.event.tracking.context.transaction.block.ChangeBlock;
+import org.spongepowered.common.event.tracking.context.transaction.effect.BlockChangeArgs;
import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult;
import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
@@ -118,12 +119,11 @@ public LevelChunkSection getAffectedSection() {
for (final ResultingTransactionBySideEffect effect : this.chunkEffects) {
try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) {
- final EffectResult result = effect.effect.processSideEffect(
+ final var args = new BlockChangeArgs(proposedState, flag, limit);
+ final EffectResult<@Nullable BlockState> result = effect.effect.processSideEffect(
this,
formerState,
- proposedState,
- flag,
- limit
+ args
);
if (result.hasResult) {
return result.resultingState;
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/InteractItemPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/InteractItemPipeline.java
new file mode 100644
index 00000000000..51a6733693e
--- /dev/null
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/InteractItemPipeline.java
@@ -0,0 +1,101 @@
+/*
+ * 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.event.tracking.context.transaction.pipeline;
+
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.InteractionResult;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.phys.BlockHitResult;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.common.event.tracking.PhaseContext;
+import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor;
+import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect;
+import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier;
+import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult;
+import org.spongepowered.common.event.tracking.context.transaction.effect.InteractionArgs;
+import org.spongepowered.common.event.tracking.context.transaction.effect.InteractionUseItemEffect;
+
+import java.util.List;
+import java.util.Objects;
+
+public final class InteractItemPipeline {
+
+ private final ServerLevel worldIn;
+ private final ServerPlayer player;
+ private final InteractionHand hand;
+ private final BlockHitResult blockRaytraceResult;
+ private final BlockState blockstate;
+ private final ItemStack copiedStack;
+ private final List> effects;
+ private final TransactionalCaptureSupplier transactor;
+
+
+ public InteractItemPipeline(ServerLevel worldIn,
+ ServerPlayer playerIn,
+ InteractionHand handIn,
+ BlockHitResult blockRaytraceResultIn,
+ BlockState blockstate,
+ ItemStack copiedStack,
+ final TransactionalCaptureSupplier transactor) {
+
+ this.worldIn = worldIn;
+ this.player = playerIn;
+ this.hand = handIn;
+ this.blockRaytraceResult = blockRaytraceResultIn;
+ this.blockstate = blockstate;
+ this.copiedStack = copiedStack;
+ this.effects = List.of(
+ new ResultingTransactionBySideEffect<>(InteractionUseItemEffect.getInstance())
+ );
+ this.transactor = transactor;
+ }
+
+ public InteractionResult processInteraction(PhaseContext> context) {
+ var interaction = InteractionResult.PASS;
+ for (final var effect : this.effects) {
+ try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) {
+ final InteractionArgs args = new InteractionArgs(this.worldIn, this.player, this.hand, this.blockRaytraceResult, this.blockstate, this.copiedStack);
+ final EffectResult result = effect.effect.processSideEffect(
+ this,
+ interaction,
+ args
+ );
+ if (result.hasResult) {
+ final @Nullable InteractionResult resultingState = result.resultingState;
+ interaction = Objects.requireNonNullElse(resultingState, interaction);
+ }
+ }
+ }
+ return interaction;
+ }
+
+ public TransactionalCaptureSupplier transactor() {
+ return this.transactor;
+ }
+}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java
index ac6fdd6ac4b..35b6b4d1360 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/TileEntityPipeline.java
@@ -26,6 +26,7 @@
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -33,6 +34,7 @@
import org.spongepowered.common.event.tracking.PhaseContext;
import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor;
import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect;
+import org.spongepowered.common.event.tracking.context.transaction.effect.BlockChangeArgs;
import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult;
import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
@@ -49,7 +51,7 @@ public final class TileEntityPipeline implements BlockPipeline {
private final @Nullable Supplier chunkSupplier;
private final @Nullable Supplier serverWorld;
private final @Nullable Supplier sectionSupplier;
- private final List effects;
+ private final List> effects;
private TileEntityPipeline(final Builder builder) {
this.chunkSupplier = builder.chunkSupplier;
@@ -98,15 +100,18 @@ public boolean wasEmpty() {
public boolean processEffects(final PhaseContext> context, final PipelineCursor initialCursor) {
PipelineCursor currentCursor = initialCursor;
- for (final ResultingTransactionBySideEffect effect : this.effects) {
+ for (final ResultingTransactionBySideEffect effect : this.effects) {
try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) {
- final EffectResult result = effect.effect.processSideEffect(
- this,
- currentCursor,
+ final BlockChangeArgs args = new BlockChangeArgs(
currentCursor.state,
(SpongeBlockChangeFlag) BlockChangeFlags.NONE,
currentCursor.limit
);
+ final EffectResult<@Nullable BlockState> result = effect.effect.processSideEffect(
+ this,
+ currentCursor,
+ args
+ );
if (result.resultingState != currentCursor.state) {
currentCursor = new PipelineCursor(
result.resultingState,
@@ -130,13 +135,13 @@ public static final class Builder {
@Nullable Supplier serverWorld;
@Nullable Supplier chunkSupplier;
@Nullable Supplier sectionSupplier;
- List effects;
+ List> effects;
- public Builder addEffect(final ProcessingSideEffect effect) {
+ public Builder addEffect(final ProcessingSideEffect effect) {
if (this.effects == null) {
this.effects = new LinkedList<>();
}
- this.effects.add(new ResultingTransactionBySideEffect(Objects.requireNonNull(effect, "Effect is null")));
+ this.effects.add(new ResultingTransactionBySideEffect<>(Objects.requireNonNull(effect, "Effect is null")));
return this;
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java
index 81165311770..62ab2617393 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/pipeline/WorldPipeline.java
@@ -36,6 +36,7 @@
import org.spongepowered.common.event.tracking.PhaseContext;
import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor;
import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect;
+import org.spongepowered.common.event.tracking.context.transaction.effect.BlockChangeArgs;
import org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult;
import org.spongepowered.common.event.tracking.context.transaction.effect.ProcessingSideEffect;
import org.spongepowered.common.world.SpongeBlockChangeFlag;
@@ -52,7 +53,7 @@ public final class WorldPipeline implements BlockPipeline {
private final Supplier serverWorld;
private final Supplier sectionSupplier;
private final boolean wasEmpty;
- private final List worldEffects;
+ private final List> worldEffects;
private final ChunkPipeline chunkPipeline;
WorldPipeline(final Builder builder) {
@@ -101,14 +102,13 @@ public boolean processEffects(final PhaseContext> context, final BlockState cu
final int oldOpacity = oldState.getLightBlock(serverWorld, pos);
PipelineCursor formerState = new PipelineCursor(oldState, oldOpacity, pos, existing, destroyer, limit);
- for (final ResultingTransactionBySideEffect effect : this.worldEffects) {
+ for (final ResultingTransactionBySideEffect effect : this.worldEffects) {
try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) {
- final EffectResult result = effect.effect.processSideEffect(
+ final var args = new BlockChangeArgs(newProposedState, flag, limit);
+ final EffectResult<@Nullable BlockState> result = effect.effect.processSideEffect(
this,
formerState,
- newProposedState,
- flag,
- limit
+ args
);
if (result.hasResult) {
return result.resultingState != null;
@@ -134,8 +134,8 @@ public static final class Builder {
final Supplier serverWorld;
final Supplier chunkSupplier;
- final Supplier sectionSupplier;
- @MonotonicNonNull List effects;
+ final Supplier<@Nullable LevelChunkSection> sectionSupplier;
+ @MonotonicNonNull List> effects;
final ChunkPipeline chunkPipeline;
Builder(final ChunkPipeline chunkPipeline) {
@@ -145,11 +145,11 @@ public static final class Builder {
this.chunkPipeline = chunkPipeline;
}
- public Builder addEffect(final ProcessingSideEffect effect) {
+ public Builder addEffect(final ProcessingSideEffect effect) {
if (this.effects == null) {
this.effects = new LinkedList<>();
}
- this.effects.add(new ResultingTransactionBySideEffect(Objects.requireNonNull(effect, "Effect is null")));
+ this.effects.add(new ResultingTransactionBySideEffect<>(Objects.requireNonNull(effect, "Effect is null")));
return this;
}
diff --git a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java
index 7e628429740..83bb4d3ceb8 100644
--- a/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java
+++ b/src/main/java/org/spongepowered/common/event/tracking/context/transaction/type/TransactionTypes.java
@@ -29,6 +29,7 @@
import org.spongepowered.api.event.Cancellable;
import org.spongepowered.api.event.Event;
import org.spongepowered.api.event.block.ChangeBlockEvent;
+import org.spongepowered.api.event.block.InteractBlockEvent;
import org.spongepowered.api.event.block.NotifyNeighborBlockEvent;
import org.spongepowered.api.event.entity.HarvestEntityEvent;
import org.spongepowered.api.event.entity.SpawnEntityEvent;
@@ -65,6 +66,8 @@ public final class TransactionTypes {
public static final DefaultedRegistryReference> CHANGE_INVENTORY_EVENT = TransactionTypes.key(ResourceKey.sponge("change_inventory"));
public static final DefaultedRegistryReference> SLOT_CHANGE = TransactionTypes.key(ResourceKey.sponge("slot_change"));
+ public static final DefaultedRegistryReference> INTERACT_BLOCK_SECONDARY = TransactionTypes.key(ResourceKey.sponge("interact_block_secondary"));
+
// SORTFIELDS:OFF
// @formatter:on
diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java
index 82e86c1939a..4b8cf417095 100644
--- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java
+++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/ai/goal/RunAroundLikeCrazyGoalMixin.java
@@ -56,14 +56,14 @@ public abstract class RunAroundLikeCrazyGoalMixin extends GoalMixin {
*/
@Overwrite
public void tick() {
- if (!this.horse.isTamed() && this.horse.getRandom().nextInt(50) == 0) {
+ if (!this.horse.isTamed() && this.horse.getRandom().nextInt(this.shadow$adjustedTickDelay(50)) == 0) {
Entity entity = this.horse.getPassengers().get(0);
if (entity == null) {
return;
}
- if (entity instanceof Player) {
+ if (entity instanceof Player p) {
int i = this.horse.getTemper();
int j = this.horse.getMaxTemper();
@@ -76,7 +76,7 @@ public void tick() {
}
}
// Sponge end
- this.horse.tameWithName((Player)entity);
+ this.horse.tameWithName(p);
return;
}
diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java
index 223e6986d28..6391f478d61 100644
--- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java
+++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java
@@ -36,7 +36,9 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.RandomSource;
+import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
+import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockEventData;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.block.Block;
@@ -46,6 +48,7 @@
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
+import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.ticks.ScheduledTick;
import net.minecraft.world.ticks.TickPriority;
@@ -105,6 +108,7 @@
import org.spongepowered.common.event.tracking.context.transaction.effect.WorldBlockChangeCompleteEffect;
import org.spongepowered.common.event.tracking.context.transaction.effect.WorldDestroyBlockLevelEffect;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.ChunkPipeline;
+import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.PipelineCursor;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.TileEntityPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.WorldPipeline;
@@ -458,11 +462,11 @@ public void scheduleTick(final BlockPos pos, final Fluid fluid, final int trigge
// Then build and use the BlockPipeline
final ChunkPipeline chunkPipeline = mixinChunk.bridge$createChunkPipeline(pos, newState, currentState, spongeFlag, limit);
final WorldPipeline.Builder worldPipelineBuilder = WorldPipeline.builder(chunkPipeline);
- worldPipelineBuilder.addEffect((pipeline, oldState, newState1, flag1, cursorLimit) -> {
+ worldPipelineBuilder.addEffect((pipeline, oldState, args) -> {
if (oldState == null) {
- return EffectResult.NULL_RETURN;
+ return EffectResult.nullReturn();
}
- return EffectResult.NULL_PASS;
+ return EffectResult.nullPass();
})
.addEffect(UpdateLightSideEffect.getInstance())
.addEffect(CheckBlockPostPlacementIsSameEffect.getInstance())
@@ -588,6 +592,31 @@ public boolean destroyBlock(final BlockPos pos, final boolean doDrops, @Nullable
return builder.build();
}
+ @Override
+ public InteractItemPipeline bridge$startInteractionChange(net.minecraft.world.level.Level worldIn, ServerPlayer playerIn, InteractionHand handIn, BlockHitResult blockRaytraceResultIn, BlockState blockstate, ItemStack copiedStack) {
+ if (this.shadow$isDebug()) { // isClientSide is always false since this is WorldServer
+ return null;
+ }
+ if (this.bridge$isFake()) {
+ return null;
+ }
+
+ final var instance = PhaseTracker.getInstance();
+ if (instance.getSidedThread() != PhaseTracker.SERVER.getSidedThread() && instance != PhaseTracker.SERVER) {
+ throw new UnsupportedOperationException("Cannot perform a tracked Block Change on a ServerWorld while not on the main thread!");
+ }
+ final var pipeline = new InteractItemPipeline(
+ (ServerLevel) worldIn,
+ playerIn,
+ handIn,
+ blockRaytraceResultIn,
+ blockstate,
+ copiedStack,
+ instance.getPhaseContext().getTransactor()
+ );
+ return pipeline;
+ }
+
/**
* Technically an overwrite, but because this is simply an override, we can
* effectively do as we need to, which is determine if we are performing
diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java
index 1a4121bf4a0..43a78ad6ae2 100644
--- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java
+++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerPlayerGameModeMixin_Tracker.java
@@ -55,6 +55,7 @@
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.common.bridge.server.level.ServerPlayerGameModeBridge;
+import org.spongepowered.common.bridge.world.TrackedWorldBridge;
import org.spongepowered.common.bridge.world.inventory.container.ContainerBridge;
import org.spongepowered.common.event.SpongeCommonEventFactory;
import org.spongepowered.common.event.inventory.InventoryEventFactory;
@@ -65,6 +66,7 @@
import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier;
import org.spongepowered.common.event.tracking.context.transaction.effect.InventoryEffect;
import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction;
+import org.spongepowered.common.event.tracking.context.transaction.pipeline.InteractItemPipeline;
import org.spongepowered.common.registry.provider.DirectionFacingProvider;
import org.spongepowered.common.util.VecHelper;
import org.spongepowered.math.vector.Vector3d;
@@ -104,6 +106,8 @@ public InteractionResult useItemOn(final ServerPlayer playerIn, final Level worl
final BlockSnapshot snapshot = ((ServerWorld) (worldIn)).createSnapshot(VecHelper.toVector3i(blockpos));
final Vector3d hitVec = Vector3d.from(blockRaytraceResultIn.getBlockPos().getX(), blockRaytraceResultIn.getBlockPos().getY(), blockRaytraceResultIn.getBlockPos().getZ());
final org.spongepowered.api.util.Direction direction = DirectionFacingProvider.INSTANCE.getKey(blockRaytraceResultIn.getDirection()).get();
+ final PhaseContext> phaseContext = PhaseTracker.getInstance().getPhaseContext();
+ phaseContext.getTransactor().logSecondaryInteractionTransaction(playerIn, stackIn, hitVec, snapshot, direction, handIn);
final InteractBlockEvent.Secondary event = SpongeCommonEventFactory.callInteractBlockEventSecondary(playerIn, stackIn, hitVec, snapshot, direction, handIn);
final Tristate useItem = event.useItemResult();
final Tristate useBlock = event.useBlockResult();
@@ -112,90 +116,99 @@ public InteractionResult useItemOn(final ServerPlayer playerIn, final Level worl
player.inventoryMenu.sendAllDataToRemote();
return InteractionResult.FAIL;
}
- // Sponge end
- if (this.gameModeForPlayer == GameType.SPECTATOR) {
- final MenuProvider inamedcontainerprovider = blockstate.getMenuProvider(worldIn, blockpos);
- if (inamedcontainerprovider != null) {
- playerIn.openMenu(inamedcontainerprovider);
- final Vector3i pos = VecHelper.toVector3i(blockRaytraceResultIn.getBlockPos());
- final ServerLocation location = ServerLocation.of((ServerWorld) worldIn, pos);
- try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
- frame.pushCause(playerIn);
- frame.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld)(worldIn)).createSnapshot(pos));
- ((ContainerBridge) playerIn.containerMenu).bridge$setOpenLocation(location);
- if (!InventoryEventFactory.callInteractContainerOpenEvent(playerIn)) {
- return InteractionResult.SUCCESS;
- }
- }
- return InteractionResult.SUCCESS;
- } else {
- return InteractionResult.PASS;
- }
- } else {
- final boolean flag = !playerIn.getMainHandItem().isEmpty() || !playerIn.getOffhandItem().isEmpty();
- final boolean flag1 = playerIn.isSecondaryUseActive() && flag;
- final ItemStack copiedStack = stackIn.copy();
- if (useBlock != Tristate.FALSE && !flag1) { // Sponge check useBlock
- final AbstractContainerMenu lastOpenContainer = playerIn.containerMenu;
- final InteractionResult result = blockstate.use(worldIn, playerIn, handIn, blockRaytraceResultIn);
- if (result.consumesAction() && lastOpenContainer != playerIn.containerMenu) {
+ try (final var frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
+ frame.pushCause(event);
+ // Sponge end
+ if (this.gameModeForPlayer == GameType.SPECTATOR) {
+ final MenuProvider inamedcontainerprovider = blockstate.getMenuProvider(worldIn, blockpos);
+ if (inamedcontainerprovider != null) {
+ playerIn.openMenu(inamedcontainerprovider);
final Vector3i pos = VecHelper.toVector3i(blockRaytraceResultIn.getBlockPos());
final ServerLocation location = ServerLocation.of((ServerWorld) worldIn, pos);
- try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
- frame.pushCause(playerIn);
- frame.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld) (worldIn)).createSnapshot(pos));
+ try (final CauseStackManager.StackFrame blockHit = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
+ blockHit.pushCause(playerIn);
+ blockHit.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld) (worldIn)).createSnapshot(pos));
((ContainerBridge) playerIn.containerMenu).bridge$setOpenLocation(location);
if (!InventoryEventFactory.callInteractContainerOpenEvent(playerIn)) {
- return InteractionResult.FAIL;
+ return InteractionResult.SUCCESS;
}
}
- }
- if (result.consumesAction()) {
- CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack);
- return result;
- }
- }
-
- if (!stackIn.isEmpty() && !playerIn.getCooldowns().isOnCooldown(stackIn.getItem())) {
- // Sponge start
- if (useItem == Tristate.FALSE) {
- ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true);
+ return InteractionResult.SUCCESS;
+ } else {
return InteractionResult.PASS;
}
- // Sponge end
- final UseOnContext itemusecontext = new UseOnContext(playerIn, handIn, blockRaytraceResultIn);
- final InteractionResult result;
- if (this.isCreative()) {
- final int i = stackIn.getCount();
- result = stackIn.useOn(itemusecontext);
- stackIn.setCount(i);
- } else {
- result = stackIn.useOn(itemusecontext);
- // Sponge start - log change in hand
- final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
- final TransactionalCaptureSupplier transactor = context.getTransactor();
- if (!transactor.isEmpty()) { //TODO: Add effect to attach the transaction to be the child of the parents
- try (final EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()))) {
- transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD);
- this.player.inventoryMenu.broadcastChanges();
+ } else {
+ final boolean flag = !playerIn.getMainHandItem().isEmpty() || !playerIn.getOffhandItem().isEmpty();
+ final boolean flag1 = playerIn.isSecondaryUseActive() && flag;
+ final ItemStack copiedStack = stackIn.copy();
+ if (useBlock != Tristate.FALSE && !flag1) { // Sponge check useBlock
+ final AbstractContainerMenu lastOpenContainer = playerIn.containerMenu;
+ final var interaction = ((TrackedWorldBridge) level).bridge$startInteractionChange(worldIn, playerIn, handIn, blockRaytraceResultIn, blockstate, copiedStack);
+ if (interaction == null) {
+ return InteractionResult.FAIL;
+ }
+ final PhaseContext<@NonNull ?> context = phaseContext;
+ final InteractionResult result = interaction.processInteraction(context);
+
+ if (result.consumesAction() && lastOpenContainer != playerIn.containerMenu) {
+ final Vector3i pos = VecHelper.toVector3i(blockRaytraceResultIn.getBlockPos());
+ final ServerLocation location = ServerLocation.of((ServerWorld) worldIn, pos);
+ try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
+ frame.pushCause(playerIn);
+ frame.addContext(EventContextKeys.BLOCK_HIT, ((ServerWorld) (worldIn)).createSnapshot(pos));
+ ((ContainerBridge) playerIn.containerMenu).bridge$setOpenLocation(location);
+ if (!InventoryEventFactory.callInteractContainerOpenEvent(playerIn)) {
+ return InteractionResult.FAIL;
+ }
}
}
- // Sponge end
+ if (result.consumesAction()) {
+ CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack);
+ return result;
+ }
}
- if (result.consumesAction()) {
- CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack);
- }
+ if (!stackIn.isEmpty() && !playerIn.getCooldowns().isOnCooldown(stackIn.getItem())) {
+ // Sponge start
+ if (useItem == Tristate.FALSE) {
+ ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true);
+ return InteractionResult.PASS;
+ }
+ // Sponge end
+ final UseOnContext itemusecontext = new UseOnContext(playerIn, handIn, blockRaytraceResultIn);
+ final InteractionResult result;
+ if (this.isCreative()) {
+ final int i = stackIn.getCount();
+ result = stackIn.useOn(itemusecontext);
+ stackIn.setCount(i);
+ } else {
+ result = stackIn.useOn(itemusecontext);
+ // Sponge start - log change in hand
+ final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
+ final TransactionalCaptureSupplier transactor = context.getTransactor();
+ if (!transactor.isEmpty()) { //TODO: Add effect to attach the transaction to be the child of the parents
+ try (final EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()))) {
+ transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD);
+ this.player.inventoryMenu.broadcastChanges();
+ }
+ }
+ // Sponge end
+ }
- return result;
- } else {
- // Sponge start
- if(useBlock == Tristate.FALSE && !flag1) {
- ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true);
- }
- // Sponge end
+ if (result.consumesAction()) {
+ CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack);
+ }
- return InteractionResult.PASS;
+ return result;
+ } else {
+ // Sponge start
+ if (useBlock == Tristate.FALSE && !flag1) {
+ ((ServerPlayerGameModeBridge) this).bridge$setInteractBlockRightClickCancelled(true);
+ }
+ // Sponge end
+
+ return InteractionResult.PASS;
+ }
}
}
}
diff --git a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java
index ae2d2435294..6af34f1d593 100644
--- a/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java
+++ b/src/test/java/org/spongepowered/common/util/transformation/VolumeTransformationTest.java
@@ -325,8 +325,7 @@ void testTransformationsOfPositions(
.sub(VolumePositionTranslators.BLOCK_OFFSET);
final Vector3i invertedBlockPos = invertedTransformedPos.toInt();
final Vector3i expectedPos;
- Assertions.assertTrue(
- type instanceof StubState,
+ Assertions.assertInstanceOf(StubState.class, type,
() -> String.format("expected state to be a stub state for pos: [%f, %f, %f] but got %s", x, y, z,
type
)