Skip to content

Commit

Permalink
wip: Add other interactions as pipeline transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
gabizou committed Jun 5, 2024
1 parent a36f6a7 commit be67a5f
Show file tree
Hide file tree
Showing 34 changed files with 1,081 additions and 649 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = false
max_line_length = 120
tab_width = 4

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

[*mixins.*.json]
indent_size = 4
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
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.UseItemOnBlockPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemAtPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.UseItemPipeline;
import org.spongepowered.common.event.tracking.context.transaction.pipeline.WorldPipeline;

Expand Down Expand Up @@ -123,5 +124,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 @@ -302,10 +302,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,32 +32,19 @@
import org.spongepowered.api.event.Event;

@DefaultQualifier(NonNull.class)
final class EventByTransaction<T extends Event & Cancellable> {

final T event;
final ImmutableList<GameTransaction<T>> transactions;
final GameTransaction<T> decider;
final @Nullable GameTransaction<@NonNull ?> parent;

EventByTransaction(final T event,
final ImmutableList<GameTransaction<T>> transactions,
final @Nullable GameTransaction<@NonNull ?> parent,
final GameTransaction<T> decider
) {
this.parent = parent;
this.event = event;
this.transactions = transactions;
this.decider = decider;
}
public record EventByTransaction<T extends Event & Cancellable>(
T event, ImmutableList<GameTransaction<T>> transactions,
@Nullable GameTransaction<@NonNull ?> parent,
GameTransaction<T> decider) {

public void markCancelled() {
this.decider.markCancelled();
for (GameTransaction<T> transaction : this.transactions) {
this.decider().markCancelled();
for (GameTransaction<T> transaction : this.transactions()) {
transaction.markCancelled();
}
}

public boolean isParentOrDeciderCancelled() {
return this.decider.cancelled || (this.parent != null && this.parent.cancelled);
return this.decider().cancelled || (this.parent() != null && this.parent().cancelled);
}
}
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 @@ -47,6 +46,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 @@ -85,6 +85,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 @@ -419,9 +420,24 @@ 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 void logSecondaryInteractItemTransaction(
final ServerPlayer playerIn, final ItemStack stackIn
) {
final InteractItemTransaction transaction = new InteractItemTransaction(playerIn, stackIn);
this.logTransaction(transaction);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public boolean processTransactions(final PhaseContext<@NonNull ?> context) {
);
boolean cancelledAny = false;
for (final EventByTransaction<@NonNull ?> eventWithTransactions : batched) {
final Event event = eventWithTransactions.event;
final Event event = eventWithTransactions.event();
if (eventWithTransactions.isParentOrDeciderCancelled()) {
cancelledAny = true;
eventWithTransactions.markCancelled();
Expand All @@ -186,12 +186,12 @@ public boolean processTransactions(final PhaseContext<@NonNull ?> context) {
eventWithTransactions.markCancelled();
cancelledAny = true;
}
if (((GameTransaction) eventWithTransactions.decider).markCancelledTransactions(event, eventWithTransactions.transactions)) {
if (((GameTransaction) eventWithTransactions.decider()).markCancelledTransactions(event, eventWithTransactions.transactions())) {
cancelledAny = true;
}
for (final GameTransaction<@NonNull ?> transaction : eventWithTransactions.transactions) {
for (final GameTransaction<@NonNull ?> transaction : eventWithTransactions.transactions()) {
if (transaction.cancelled) {
((GameTransaction) transaction).markEventAsCancelledIfNecessary(eventWithTransactions.event);
((GameTransaction) transaction).markEventAsCancelledIfNecessary(eventWithTransactions.event());
}
if (!transaction.cancelled) {
((GameTransaction) transaction).postProcessEvent(context, event);
Expand All @@ -200,12 +200,12 @@ public boolean processTransactions(final PhaseContext<@NonNull ?> context) {
}
if (cancelledAny) {
for (final EventByTransaction<@NonNull ?> eventByTransaction : batched.reverse()) {
if (eventByTransaction.decider.cancelled) {
((GameTransaction) eventByTransaction.decider).markEventAsCancelledIfNecessary(eventByTransaction.event);
if (eventByTransaction.decider().cancelled) {
((GameTransaction) eventByTransaction.decider()).markEventAsCancelledIfNecessary(eventByTransaction.event());
}
for (final GameTransaction<@NonNull ?> gameTransaction : eventByTransaction.transactions.reverse()) {
for (final GameTransaction<@NonNull ?> gameTransaction : eventByTransaction.transactions().reverse()) {
if (gameTransaction.cancelled) {
((GameTransaction) gameTransaction).restore(context, eventByTransaction.event);
((GameTransaction) gameTransaction).restore(context, eventByTransaction.event());
}
}
}
Expand Down 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
@@ -0,0 +1,40 @@
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.UseBlockPipeline;

public final class InteractionUseItemOnEffect implements ProcessingSideEffect.Simple<UseBlockPipeline, UseItemOnArgs, InteractionResult> {

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

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

@Override
public EffectResult<InteractionResult> processSideEffect(
UseBlockPipeline pipeline, InteractionResult oldState, UseItemOnArgs args
) {
// Run vanilla change
InteractionResult result;
final var stack = args.itemStack();
if (args.isCreative()) {
var i = stack.getCount();
result = stack.useOn(args.context());
stack.setCount(i);
} else {
result = stack.useOn(args.context());
}

final var player = args.player();
pipeline.transactor().logPlayerInventoryChange(player, PlayerInventoryTransaction.EventCreator.STANDARD);
try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(pipeline.transactor())) {
player.containerMenu.broadcastChanges();
}
return new EffectResult<>(result, true);
}
}
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,6 +25,7 @@
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;
Expand All @@ -34,8 +35,7 @@ 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 {
}
Loading

0 comments on commit be67a5f

Please sign in to comment.