Skip to content

Commit

Permalink
feat: Add other interactions as pipeline transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
gabizou committed Jan 2, 2025
1 parent e7a39bd commit 96990e0
Show file tree
Hide file tree
Showing 31 changed files with 550 additions and 125 deletions.
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ insert_final_newline = false
max_line_length = 120
tab_width = 4

[{*.json,*.jsonc,*.png.mcmeta,mcmod.info,pack.mcmeta}]
indent_size = 2

[*.yaml]
indent_size = 2
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.spongepowered.common.bridge.world.level.block.state.BlockStateBridge;
import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseBlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemAtPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemOnBlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.WorldPipeline;
Expand Down Expand Up @@ -117,5 +118,7 @@ public interface TrackedWorldBridge {

UseBlockPipeline bridge$startInteractionChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, BlockHitResult blockRaytraceResultIn, BlockState blockstate, ItemStack copiedStack);

UseItemPipeline bridge$startItemInteractionChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, ItemStack copiedStack, BlockHitResult blockRaytraceResult, boolean creative);
UseItemAtPipeline bridge$startItemInteractionChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, ItemStack copiedStack, BlockHitResult blockRaytraceResult, boolean creative);

UseItemPipeline bridge$startItemInteractionUseChange(Level worldIn, ServerPlayer playerIn, InteractionHand handIn, ItemStack copiedStack);
}
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,10 @@ public static InteractItemEvent.Primary callInteractItemEventPrimary(final net.m
}
}

public static InteractItemEvent.Secondary callInteractItemEventSecondary(final net.minecraft.world.entity.player.Player player, final ItemStack stack, final InteractionHand hand) {
public static InteractItemEvent.Secondary.Pre callInteractItemEventSecondary(final net.minecraft.world.entity.player.Player player, final ItemStack stack, final InteractionHand hand) {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
SpongeCommonEventFactory.applyCommonInteractContext(player, stack, hand, null, null, frame);
final InteractItemEvent.Secondary event = SpongeEventFactory.createInteractItemEventSecondary(frame.currentCause(), ItemStackUtil.snapshotOf(stack));
final var event = SpongeEventFactory.createInteractItemEventSecondaryPre(frame.currentCause(), ItemStackUtil.snapshotOf(stack));
SpongeCommon.post(event);
return event;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.spongepowered.api.event.Event;

@DefaultQualifier(NonNull.class)
record EventByTransaction<T extends Event & Cancellable>(
public record EventByTransaction<T extends Event & Cancellable>(
T event,
ImmutableList<GameTransaction<T>> transactions,
@Nullable GameTransaction<@NonNull ?> parent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.util.Optional;
import java.util.StringJoiner;
import java.util.function.BiConsumer;
import java.util.stream.Stream;

@DefaultQualifier(NonNull.class)
public abstract class GameTransaction<E extends Event & Cancellable> implements TransactionFlow, StatefulTransaction {
Expand Down Expand Up @@ -189,6 +190,18 @@ protected void captureState() {

}

public void associateSideEffectEvents(E e, Stream<Event> elements) {

}

public void pushCause(CauseStackManager.StackFrame frame, E e) {
frame.pushCause(e);
}

public void finalizeSideEffects(E e) {

}

private static class ChildIterator implements Iterator<GameTransaction<@NonNull ?>> {
private final Iterator<ResultingTransactionBySideEffect<?, ?, ?, ?>> effectIterator;
private @Nullable GameTransaction<@NonNull ?> cachedNext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
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;
Expand All @@ -46,6 +45,7 @@
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.block.InteractBlockEvent;
import org.spongepowered.api.event.cause.entity.SpawnType;
import org.spongepowered.api.item.inventory.Inventory;
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
Expand Down Expand Up @@ -74,6 +74,7 @@
import org.spongepowered.common.event.tracking.context.transaction.block.ScheduleUpdateTransaction;
import org.spongepowered.common.event.tracking.context.transaction.effect.BlockAddedEffect;
import org.spongepowered.common.event.tracking.context.transaction.effect.EntityPerformingDropsEffect;
import org.spongepowered.common.event.tracking.context.transaction.effect.InteractionItemEffect;
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;
Expand All @@ -86,6 +87,7 @@
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.InteractItemWithBlockTransaction;
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;
Expand Down Expand Up @@ -421,10 +423,26 @@ default EffectTransactor logInventoryTransaction(final AbstractContainerMenu con
}

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);
final ServerPlayer playerIn, final Vector3d hitVec,
final BlockSnapshot snapshot, final Direction direction, InteractBlockEvent.Secondary.Pre event) {
final InteractItemWithBlockTransaction transaction = new InteractItemWithBlockTransaction(playerIn,
hitVec,
snapshot,
direction,
event.originalUseBlockResult(),
event.useBlockResult(),
event.originalUseItemResult(),
event.useItemResult()
);
this.logTransaction(transaction);
}

default EffectTransactor logSecondaryInteractItemTransaction(
final ServerPlayer playerIn, final ItemStack stackIn
) {
final InteractItemTransaction transaction = new InteractItemTransaction(playerIn, stackIn);
this.logTransaction(transaction);
return this.pushEffect(new ResultingTransactionBySideEffect<>(InteractionItemEffect.getInstance()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,16 @@ private static <E extends Event & Cancellable> void generateEventForTransaction(
if (transaction.sideEffects == null || transaction.sideEffects.isEmpty()) {
continue;
}
generatedEvent.ifPresent(frame::pushCause);
generatedEvent.ifPresent(e -> transaction.pushCause(frame, e));
for (final ResultingTransactionBySideEffect sideEffect : transaction.sideEffects) {
if (sideEffect.head == null) {
continue;
}
builder.addAll(TransactionalCaptureSupplier.batchTransactions(sideEffect.head, pointer, context, transactionPostEventBuilder));
final var elements = TransactionalCaptureSupplier.batchTransactions(sideEffect.head, pointer, context, transactionPostEventBuilder);
generatedEvent.ifPresent(e -> transaction.associateSideEffectEvents(e, elements.stream().map(EventByTransaction::event)));
builder.addAll(elements);
}
generatedEvent.ifPresent(transaction::finalizeSideEffects);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;

public record InteractionArgs(
public record InteractionAtArgs(
Level world,
ServerPlayer player,
InteractionHand hand,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseBlockPipeline;

public final class InteractionItemEffect implements ProcessingSideEffect<UseBlockPipeline, InteractionResult, InteractionArgs, InteractionResult> {
public final class InteractionItemEffect implements ProcessingSideEffect.Simple<UseBlockPipeline, InteractionAtArgs, InteractionResult> {

private static final class Holder {
static final InteractionItemEffect INSTANCE = new InteractionItemEffect();
Expand All @@ -41,7 +41,7 @@ public static InteractionItemEffect getInstance() {

@Override
public EffectResult<InteractionResult> processSideEffect(
UseBlockPipeline pipeline, InteractionResult oldState, InteractionArgs args
UseBlockPipeline pipeline, InteractionResult oldState, InteractionAtArgs args
) {
final var player = args.player();
final var world = args.world();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemOnBlockPipeline;

public final class InteractionUseItemOnBlockEffect implements ProcessingSideEffect<UseItemOnBlockPipeline, ItemInteractionResult, InteractionArgs, ItemInteractionResult> {
public final class InteractionUseItemOnBlockEffect implements ProcessingSideEffect<UseItemOnBlockPipeline, ItemInteractionResult, InteractionAtArgs, ItemInteractionResult> {

private static final class Holder {
static final InteractionUseItemOnBlockEffect INSTANCE = new InteractionUseItemOnBlockEffect();
Expand All @@ -41,7 +41,7 @@ public static InteractionUseItemOnBlockEffect getInstance() {

@Override
public EffectResult<ItemInteractionResult> processSideEffect(
UseItemOnBlockPipeline pipeline, ItemInteractionResult oldState, InteractionArgs args
UseItemOnBlockPipeline pipeline, ItemInteractionResult oldState, InteractionAtArgs args
) {
final var player = args.player();
final var hand = args.hand();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@
@FunctionalInterface
public interface ProcessingSideEffect<T, C, A extends ProcessingSideEffect.Args, @Nullable R> {

interface Simple<T, A extends ProcessingSideEffect.Args, @Nullable R> extends ProcessingSideEffect<T, R, A, R> {

}

EffectResult<R> processSideEffect(T pipeline, C oldState, A args);

sealed interface Args permits BlockChangeArgs, InteractionArgs, UseItemArgs {}
sealed interface Args permits BlockChangeArgs, InteractionAtArgs, UseItemOnArgs, UseItemAtArgs, UseItemArgs {}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,16 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;

import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;

public record UseItemArgs(
Level world,
ServerPlayer player,
InteractionHand hand,
BlockHitResult result,
ItemStack copiedStack,
boolean creative
ServerPlayerGameMode gameMode
) implements ProcessingSideEffect.Args {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* 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.phys.BlockHitResult;

public record UseItemAtArgs(
Level world,
ServerPlayer player,
InteractionHand hand,
BlockHitResult result,
ItemStack copiedStack,
boolean creative
) implements ProcessingSideEffect.Args {
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,43 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;

import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
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.UseItemOnBlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemAtPipeline;

public final class PlayerContainerRefreshEffect implements ProcessingSideEffect<UseItemOnBlockPipeline, InteractionResult, InteractionArgs, InteractionResult> {
public class UseItemAtEffect implements ProcessingSideEffect.Simple<UseItemAtPipeline, UseItemAtArgs, InteractionResult> {

private static final class Holder {
static final PlayerContainerRefreshEffect INSTANCE = new PlayerContainerRefreshEffect();
static final UseItemAtEffect INSTANCE = new UseItemAtEffect();
}

public static PlayerContainerRefreshEffect getInstance() {
return Holder.INSTANCE;
private UseItemAtEffect() {
}

public static UseItemAtEffect getInstance() {
return UseItemAtEffect.Holder.INSTANCE;
}

@Override
public EffectResult<InteractionResult> processSideEffect(
UseItemOnBlockPipeline pipeline, InteractionResult oldState, InteractionArgs args
UseItemAtPipeline pipeline, InteractionResult oldState, UseItemAtArgs args
) {
final var stack = args.copiedStack();
final InteractionResult result;
final var context = new UseOnContext(args.player(), args.hand(), args.result());
if (args.creative()) {
int count = stack.getCount();
result = stack.useOn(context);
stack.setCount(count);
} else {
result = stack.useOn(context);
}
pipeline.transactor().logPlayerInventoryChange(args.player(), PlayerInventoryTransaction.EventCreator.STANDARD);
try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(pipeline.transactor())) {
args.player().containerMenu.broadcastChanges();
}
return EffectResult.nullPass();
return new EffectResult<>(result, true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@
package org.spongepowered.common.event.tracking.context.transaction.effect;

import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
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.UseItemPipeline;

public class UseItemEffect implements ProcessingSideEffect<UseItemPipeline, InteractionResult, UseItemArgs, InteractionResult> {
public class UseItemEffect implements ProcessingSideEffect.Simple<UseItemPipeline, UseItemArgs, InteractionResult> {

private static final class Holder {
static final UseItemEffect INSTANCE = new UseItemEffect();
}

private UseItemEffect() {
}

public static UseItemEffect getInstance() {
return UseItemEffect.Holder.INSTANCE;
}
Expand All @@ -44,16 +46,8 @@ public static UseItemEffect getInstance() {
public EffectResult<InteractionResult> processSideEffect(
UseItemPipeline pipeline, InteractionResult oldState, UseItemArgs args
) {
final var stack = args.copiedStack();
final InteractionResult result;
final var context = new UseOnContext(args.player(), args.hand(), args.result());
if (args.creative()) {
int $$14 = stack.getCount();
result = stack.useOn(context);
stack.setCount($$14);
} else {
result = stack.useOn(context);
}
final var gameMode = args.gameMode();
final InteractionResult result = gameMode.useItem(args.player(), args.world(), args.copiedStack(), args.hand());
pipeline.transactor().logPlayerInventoryChange(args.player(), PlayerInventoryTransaction.EventCreator.STANDARD);
try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(pipeline.transactor())) {
args.player().containerMenu.broadcastChanges();
Expand Down
Loading

0 comments on commit 96990e0

Please sign in to comment.