Search in sources :

Example 11 with EffectTransactor

use of org.spongepowered.common.event.tracking.context.transaction.EffectTransactor in project SpongeCommon by SpongePowered.

the class ChunkPipeline method processChange.

@Nullable
public BlockState processChange(final PhaseContext<?> context, final BlockState currentState, final BlockState proposedState, final BlockPos pos, final int limit) {
    if (this.chunkEffects.isEmpty()) {
        return null;
    }
    final ServerLevel serverWorld = this.serverWorld.get();
    final int oldOpacity = currentState.getLightBlock(serverWorld, pos);
    final SpongeBlockChangeFlag flag = this.transaction.getBlockChangeFlag();
    @Nullable final BlockEntity existing = this.chunkSupplier.get().getBlockEntity(pos, LevelChunk.EntityCreationType.CHECK);
    PipelineCursor formerState = new PipelineCursor(currentState, oldOpacity, pos, existing, (Entity) null, limit);
    for (final ResultingTransactionBySideEffect effect : this.chunkEffects) {
        try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) {
            final EffectResult result = effect.effect.processSideEffect(this, formerState, proposedState, flag, limit);
            if (result.hasResult) {
                return result.resultingState;
            }
            if (formerState.drops.isEmpty() && !result.drops.isEmpty()) {
                formerState = new PipelineCursor(currentState, oldOpacity, pos, existing, null, result.drops, limit);
            }
        }
    }
    // if we've gotten here, means something is wrong, we didn't build our effects right.
    return null;
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) SpongeBlockChangeFlag(org.spongepowered.common.world.SpongeBlockChangeFlag) EffectResult(org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult) ResultingTransactionBySideEffect(org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Nullable(org.checkerframework.checker.nullness.qual.Nullable) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 12 with EffectTransactor

use of org.spongepowered.common.event.tracking.context.transaction.EffectTransactor in project SpongeCommon by SpongePowered.

the class PacketContext method close.

@Override
public void close() {
    // Make sure to call any broadcast changes to capture any inventory transactions
    // for events
    final TransactionalCaptureSupplier transactor = this.getTransactor();
    if (this.packetPlayer != null) {
        transactor.logPlayerInventoryChange(this.packetPlayer, PlayerInventoryTransaction.EventCreator.STANDARD);
        try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(transactor)) {
            this.packetPlayer.containerMenu.broadcastChanges();
        }
    }
    super.close();
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)

Example 13 with EffectTransactor

use of org.spongepowered.common.event.tracking.context.transaction.EffectTransactor in project SpongeCommon by SpongePowered.

the class WorldPipeline method processEffects.

public boolean processEffects(final PhaseContext<?> context, final BlockState currentState, final BlockState newProposedState, final BlockPos pos, @Nullable final Entity destroyer, final SpongeBlockChangeFlag flag, final int limit) {
    if (this.worldEffects.isEmpty()) {
        return false;
    }
    final ServerLevel serverWorld = Objects.requireNonNull(this.serverWorld).get();
    // Keep track of the existing block entity prior to processing the chunk pipeline
    // and the reasoning is that in several cases where the block entity that is being removed
    // will no longer be available. This could be avoided by having the "previous cursor" returned
    // from ChunkPipeline, but alas.... that's a refactor for another time.
    @Nullable final BlockEntity existing = this.chunkSupplier.get().getBlockEntity(pos, LevelChunk.EntityCreationType.CHECK);
    // We have to get the "old state" from
    @Nullable final BlockState oldState = this.chunkPipeline.processChange(context, currentState, newProposedState, pos, limit);
    if (oldState == null) {
        return false;
    }
    final int oldOpacity = oldState.getLightBlock(serverWorld, pos);
    PipelineCursor formerState = new PipelineCursor(oldState, oldOpacity, pos, existing, destroyer, limit);
    for (final ResultingTransactionBySideEffect effect : this.worldEffects) {
        try (final EffectTransactor ignored = context.getTransactor().pushEffect(effect)) {
            final EffectResult result = effect.effect.processSideEffect(this, formerState, newProposedState, flag, limit);
            if (result.hasResult) {
                return result.resultingState != null;
            }
            if (formerState.drops.isEmpty() && !result.drops.isEmpty()) {
                formerState = new PipelineCursor(oldState, oldOpacity, pos, existing, formerState.destroyer, result.drops, limit);
            }
        }
    }
    // if we've gotten here, means something is wrong, we didn't build our effects right.
    return false;
}
Also used : ServerLevel(net.minecraft.server.level.ServerLevel) BlockState(net.minecraft.world.level.block.state.BlockState) EffectResult(org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult) ResultingTransactionBySideEffect(org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Nullable(org.checkerframework.checker.nullness.qual.Nullable) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity)

Example 14 with EffectTransactor

use of org.spongepowered.common.event.tracking.context.transaction.EffectTransactor in project SpongeCommon by SpongePowered.

the class ServerPlayerGameModeMixin_Forge_Tracker method forgeTracker$pushTransactionAndEffect.

// @formatter:on
@Redirect(method = "destroyBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;mineBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;)V"))
private void forgeTracker$pushTransactionAndEffect(final ItemStack itemStack, final Level level, final BlockState state, final BlockPos pos, final Player player) {
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    // Log the prepare drops here because Forge rewrites
    // this method to call mine block before calling destroy block
    // and mods will possibly already have performed modifications on
    // the block before we can capture it in level.destroy.
    transactor.logBlockDrops(level, pos, state, level.getBlockEntity(pos));
    itemStack.mineBlock(level, state, pos, player);
    // Needs to get logged as a sideeffect under the BlockChange
    try (EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect(InventoryEffect.getInstance()))) {
        transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD);
        this.player.inventoryMenu.broadcastChanges();
    }
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) ResultingTransactionBySideEffect(org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Example 15 with EffectTransactor

use of org.spongepowered.common.event.tracking.context.transaction.EffectTransactor in project SpongeCommon by SpongePowered.

the class ServerGamePacketListenerImplMixin_Forge method forge$onPlaceRecipe.

@SuppressWarnings({ "UnresolvedMixinReference", "unchecked", "rawtypes" })
@Redirect(method = "lambda$handlePlaceRecipe$11", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/RecipeBookMenu;handlePlacement(ZLnet/minecraft/world/item/crafting/Recipe;Lnet/minecraft/server/level/ServerPlayer;)V"))
private void forge$onPlaceRecipe(final RecipeBookMenu recipeBookMenu, final boolean shift, final Recipe<?> recipe, final net.minecraft.server.level.ServerPlayer player) {
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    final Inventory craftInv = ((Inventory) player.containerMenu).query(QueryTypes.INVENTORY_TYPE.get().of(CraftingInventory.class));
    if (!(craftInv instanceof CraftingInventory)) {
        recipeBookMenu.handlePlacement(shift, recipe, player);
        SpongeCommon.logger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
        return;
    }
    try (final EffectTransactor ignored = transactor.logPlaceRecipe(shift, recipe, player, (CraftingInventory) craftInv)) {
        recipeBookMenu.handlePlacement(shift, recipe, player);
        player.containerMenu.broadcastChanges();
    }
}
Also used : CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) Inventory(org.spongepowered.api.item.inventory.Inventory) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Aggregations

EffectTransactor (org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)24 TransactionalCaptureSupplier (org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier)16 Redirect (org.spongepowered.asm.mixin.injection.Redirect)13 ResultingTransactionBySideEffect (org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect)4 ServerPlayer (org.spongepowered.api.entity.living.player.server.ServerPlayer)3 Inventory (org.spongepowered.api.item.inventory.Inventory)3 LevelBridge (org.spongepowered.common.bridge.world.level.LevelBridge)3 ServerLevel (net.minecraft.server.level.ServerLevel)2 ServerPlayer (net.minecraft.server.level.ServerPlayer)2 ItemStack (net.minecraft.world.item.ItemStack)2 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)2 Nullable (org.checkerframework.checker.nullness.qual.Nullable)2 CraftingInventory (org.spongepowered.api.item.inventory.crafting.CraftingInventory)2 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)2 EffectResult (org.spongepowered.common.event.tracking.context.transaction.effect.EffectResult)2 Audience (net.kyori.adventure.audience.Audience)1 Component (net.kyori.adventure.text.Component)1 MutableComponent (net.minecraft.network.chat.MutableComponent)1 TextComponent (net.minecraft.network.chat.TextComponent)1 TranslatableComponent (net.minecraft.network.chat.TranslatableComponent)1