Search in sources :

Example 16 with TransactionalCaptureSupplier

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

the class PlayerListMixin method impl$onInitPlayer_join.

@Inject(method = "placeNewPlayer", at = @At(value = "RETURN"))
private void impl$onInitPlayer_join(final Connection networkManager, final net.minecraft.server.level.ServerPlayer mcPlayer, final CallbackInfo ci) {
    final ServerPlayer player = (ServerPlayer) mcPlayer;
    final ServerSideConnection connection = player.connection();
    final Cause cause = Cause.of(EventContext.empty(), connection, player);
    final Audience audience = Audiences.onlinePlayers();
    final Component joinComponent = SpongeAdventure.asAdventure(((ServerPlayerBridge) mcPlayer).bridge$getConnectionMessageToSend());
    final ServerSideConnectionEvent.Join event = SpongeEventFactory.createServerSideConnectionEventJoin(cause, audience, Optional.of(audience), joinComponent, joinComponent, connection, player, false);
    SpongeCommon.post(event);
    if (!event.isMessageCancelled()) {
        event.audience().ifPresent(audience1 -> audience1.sendMessage(Identity.nil(), event.message()));
    }
    ((ServerPlayerBridge) mcPlayer).bridge$setConnectionMessageToSend(null);
    final PhaseContext<?> context = PhaseTracker.SERVER.getPhaseContext();
    PhaseTracker.SERVER.pushCause(event);
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    transactor.logPlayerInventoryChange(mcPlayer, PlayerInventoryTransaction.EventCreator.STANDARD);
    try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(transactor)) {
        // in case plugins modified it
        mcPlayer.inventoryMenu.broadcastChanges();
    }
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) Audience(net.kyori.adventure.audience.Audience) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) Cause(org.spongepowered.api.event.Cause) ServerSideConnection(org.spongepowered.api.network.ServerSideConnection) ServerSideConnectionEvent(org.spongepowered.api.event.network.ServerSideConnectionEvent) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) TranslatableComponent(net.minecraft.network.chat.TranslatableComponent) TextComponent(net.minecraft.network.chat.TextComponent) MutableComponent(net.minecraft.network.chat.MutableComponent) Component(net.kyori.adventure.text.Component) ServerPlayerBridge(org.spongepowered.common.bridge.server.level.ServerPlayerBridge) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 17 with TransactionalCaptureSupplier

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

the class ServerPlayerGameModeMixin_Tracker method useItemOn.

/**
 * @author Morph
 * @reason Fire interact block event.
 */
@Overwrite
public InteractionResult useItemOn(final ServerPlayer playerIn, final Level worldIn, final ItemStack stackIn, final InteractionHand handIn, final BlockHitResult blockRaytraceResultIn) {
    final BlockPos blockpos = blockRaytraceResultIn.getBlockPos();
    final BlockState blockstate = worldIn.getBlockState(blockpos);
    // Sponge start
    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 InteractBlockEvent.Secondary event = SpongeCommonEventFactory.callInteractBlockEventSecondary(playerIn, stackIn, hitVec, snapshot, direction, handIn);
    if (event.isCancelled()) {
        return InteractionResult.FAIL;
    }
    final Tristate useItem = event.useItemResult();
    final Tristate useBlock = event.useBlockResult();
    // 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) {
                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;
                    }
                }
            }
            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) {
                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();
                transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD);
                this.player.inventoryMenu.broadcastChanges();
            // Sponge end
            }
            if (result.consumesAction()) {
                CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(playerIn, blockpos, copiedStack);
            }
            return result;
        } else {
            return InteractionResult.PASS;
        }
    }
}
Also used : ServerLocation(org.spongepowered.api.world.server.ServerLocation) Tristate(org.spongepowered.api.util.Tristate) ContainerBridge(org.spongepowered.common.bridge.world.inventory.container.ContainerBridge) ServerWorld(org.spongepowered.api.world.server.ServerWorld) InteractionResult(net.minecraft.world.InteractionResult) InteractBlockEvent(org.spongepowered.api.event.block.InteractBlockEvent) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) AbstractContainerMenu(net.minecraft.world.inventory.AbstractContainerMenu) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BlockPos(net.minecraft.core.BlockPos) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) UseOnContext(net.minecraft.world.item.context.UseOnContext) MenuProvider(net.minecraft.world.MenuProvider) BlockState(net.minecraft.world.level.block.state.BlockState) Vector3d(org.spongepowered.math.vector.Vector3d) Vector3i(org.spongepowered.math.vector.Vector3i) ItemStack(net.minecraft.world.item.ItemStack) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 18 with TransactionalCaptureSupplier

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

the class SwapHandItemsState method populateContext.

@Override
public void populateContext(final ServerPlayer playerMP, final Packet<?> packet, final InventoryPacketContext context) {
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    transactor.logPlayerInventoryChangeWithEffect(playerMP, PlayerInventoryTransaction.EventCreator.SWAP_HAND);
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier)

Example 19 with TransactionalCaptureSupplier

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

the class PlayerMixin_Attack_Impl method attack.

// @formatter:on
/**
 * @author gabizou - April 8th, 2016
 * @author gabizou - April 11th, 2016 - Update for 1.9 - This enitre method was rewritten
 * @author i509VCB - February 15th, 2020 - Update for 1.14.4
 * @author gabizou - November 15th, 2020 - Update for 1.15.2
 *
 * @reason Rewrites the attack to throw an {@link AttackEntityEvent} prior
 * to the ensuing {@link org.spongepowered.api.event.entity.DamageEntityEvent}. This should cover all cases where players are
 * attacking entities and those entities override {@link LivingEntity#hurt(DamageSource, float)}
 * and effectively bypass our damage event hooks.
 *
 * LVT Rename Table:
 * float f        | damage               |
 * float f1       | enchantmentDamage    |
 * float f2       | attackStrength       |
 * boolean flag   | isStrongAttack       |
 * boolean flag1  | isSprintingAttack    |
 * boolean flag2  | isCriticalAttack     | Whether critical particles will spawn and of course, multiply the output damage
 * boolean flag3  | isSweapingAttack     | Whether the player is sweaping an attack and will deal AoE damage
 * int i          | knockbackModifier    | The knockback modifier, must be set from the event after it has been thrown
 * float f4       | targetOriginalHealth | This is initially set as the entity original health
 * boolean flag4  | litEntityOnFire      | This is an internal flag to where if the attack failed, the entity is no longer set on fire
 * int j          | fireAspectModifier   | Literally just to check that the weapon used has fire aspect enchantments
 * double d0      | distanceWalkedDelta  | This checks that the distance walked delta is more than the normal walking speed to evaluate if you're making a sweaping attack
 * double d1      | targetMotionX        | Current target entity motion x vector
 * double d2      | targetMotionY        | Current target entity motion y vector
 * double d3      | targetMotionZ        | Current target entity motion z vector
 * boolean flag5  | attackSucceeded      | Whether the attack event succeeded
 *
 * @param targetEntity The target entity
 */
@Overwrite
public void attack(final Entity targetEntity) {
    // Sponge Start - Add SpongeImpl hook to override in forge as necessary
    if (!PlatformHooks.INSTANCE.getEntityHooks().checkAttackEntity((net.minecraft.world.entity.player.Player) (Object) this, targetEntity)) {
        return;
    }
    // Sponge End
    if (targetEntity.isAttackable()) {
        if (!targetEntity.skipAttackInteraction((net.minecraft.world.entity.player.Player) (Object) this)) {
            // Sponge Start - Prepare our event values
            // float damage = (float) this.getEntityAttribute(Attributes.ATTACK_DAMAGE).getAttributeValue();
            final double originalBaseDamage = this.shadow$getAttribute(Attributes.ATTACK_DAMAGE).getValue();
            float damage = (float) originalBaseDamage;
            // Sponge End
            float enchantmentDamage = 0.0F;
            // Sponge Start - Redirect getting enchantments for our damage event handlers
            // if (targetEntity instanceof LivingEntity) {
            // enchantmentDamage = EnchantmentHelper.getModifierForCreature(this.getHeldItemMainhand(), ((LivingEntity) targetEntity).getCreatureAttribute());
            // } else {
            // enchantmentDamage = EnchantmentHelper.getModifierForCreature(this.getHeldItemMainhand(), CreatureAttribute.UNDEFINED);
            // }
            final float attackStrength = this.shadow$getAttackStrengthScale(0.5F);
            final List<DamageFunction> originalFunctions = new ArrayList<>();
            final MobType creatureAttribute = targetEntity instanceof LivingEntity ? ((LivingEntity) targetEntity).getMobType() : MobType.UNDEFINED;
            final List<DamageFunction> enchantmentModifierFunctions = DamageEventUtil.createAttackEnchantmentFunction(this.shadow$getMainHandItem(), creatureAttribute, attackStrength);
            // This is kept for the post-damage event handling
            final List<DamageModifier> enchantmentModifiers = enchantmentModifierFunctions.stream().map(ModifierFunction::modifier).collect(Collectors.toList());
            enchantmentDamage = (float) enchantmentModifierFunctions.stream().map(ModifierFunction::function).mapToDouble(function -> function.applyAsDouble(originalBaseDamage)).sum();
            originalFunctions.addAll(enchantmentModifierFunctions);
            // Sponge End
            originalFunctions.add(DamageEventUtil.provideCooldownAttackStrengthFunction((net.minecraft.world.entity.player.Player) (Object) this, attackStrength));
            damage = damage * (0.2F + attackStrength * attackStrength * 0.8F);
            enchantmentDamage = enchantmentDamage * attackStrength;
            this.shadow$resetAttackStrengthTicker();
            if (damage > 0.0F || enchantmentDamage > 0.0F) {
                final boolean isStrongAttack = attackStrength > 0.9F;
                boolean isSprintingAttack = false;
                boolean isCriticalAttack = false;
                boolean isSweapingAttack = false;
                int knockbackModifier = 0;
                knockbackModifier = knockbackModifier + EnchantmentHelper.getKnockbackBonus((net.minecraft.world.entity.player.Player) (Object) this);
                if (this.shadow$isSprinting() && isStrongAttack) {
                    // Sponge - Only play sound after the event has be thrown and not cancelled.
                    // this.world.playSound((EntityPlayer) null, this.posX, this.posY, this.posZ, SoundEvents.entity_player_attack_knockback, this.getSoundCategory(), 1.0F, 1.0F);
                    ++knockbackModifier;
                    isSprintingAttack = true;
                }
                isCriticalAttack = isStrongAttack && this.fallDistance > 0.0F && !this.onGround && !this.shadow$onClimbable() && !this.shadow$isInWater() && !this.shadow$hasEffect(MobEffects.BLINDNESS) && !this.shadow$isPassenger() && targetEntity instanceof LivingEntity;
                isCriticalAttack = isCriticalAttack && !this.shadow$isSprinting();
                final EventHooks.CriticalHitResult criticalResult = PlatformHooks.INSTANCE.getEventHooks().callCriticalHitEvent((net.minecraft.world.entity.player.Player) (Object) this, targetEntity, isCriticalAttack, isCriticalAttack ? 1.5F : 1.0F);
                isCriticalAttack = criticalResult.criticalHit;
                if (isCriticalAttack) {
                    // Sponge Start - add critical attack tuple
                    // damage *= 1.5F; // Sponge - This is handled in the event
                    originalFunctions.add(DamageEventUtil.provideCriticalAttackTuple((net.minecraft.world.entity.player.Player) (Object) this, criticalResult.modifier));
                // Sponge End
                }
                // damage = damage + enchantmentDamage; // Sponge - We don't need this since our event will re-assign the damage to deal
                final double distanceWalkedDelta = (double) (this.walkDist - this.walkDistO);
                final ItemStack heldItem = this.shadow$getMainHandItem();
                if (isStrongAttack && !isCriticalAttack && !isSprintingAttack && this.onGround && distanceWalkedDelta < (double) this.shadow$getSpeed()) {
                    if (heldItem.getItem() instanceof SwordItem) {
                        isSweapingAttack = true;
                    }
                }
                // Sponge Start - Create the event and throw it
                final DamageSource damageSource = DamageSource.playerAttack((net.minecraft.world.entity.player.Player) (Object) this);
                final boolean isMainthread = !this.level.isClientSide;
                if (isMainthread) {
                    PhaseTracker.getInstance().pushCause(damageSource);
                }
                final Cause currentCause = isMainthread ? PhaseTracker.getInstance().currentCause() : Cause.of(EventContext.empty(), damageSource);
                final AttackEntityEvent event = SpongeEventFactory.createAttackEntityEvent(currentCause, (org.spongepowered.api.entity.Entity) targetEntity, originalFunctions, knockbackModifier, originalBaseDamage);
                SpongeCommon.post(event);
                if (isMainthread) {
                    PhaseTracker.getInstance().popCause();
                }
                if (event.isCancelled()) {
                    return;
                }
                damage = (float) event.finalOutputDamage();
                // Sponge End
                // Sponge Start - need final for later events
                final double attackDamage = damage;
                knockbackModifier = (int) event.knockbackModifier();
                enchantmentDamage = (float) enchantmentModifiers.stream().mapToDouble(event::outputDamage).sum();
                // Sponge End
                float targetOriginalHealth = 0.0F;
                boolean litEntityOnFire = false;
                final int fireAspectModifier = EnchantmentHelper.getFireAspect((net.minecraft.world.entity.player.Player) (Object) this);
                if (targetEntity instanceof LivingEntity) {
                    targetOriginalHealth = ((LivingEntity) targetEntity).getHealth();
                    if (fireAspectModifier > 0 && !targetEntity.isOnFire()) {
                        litEntityOnFire = true;
                        targetEntity.setSecondsOnFire(1);
                    }
                }
                final net.minecraft.world.phys.Vec3 targetMotion = targetEntity.getDeltaMovement();
                final boolean attackSucceeded = targetEntity.hurt(DamageSource.playerAttack((net.minecraft.world.entity.player.Player) (Object) this), damage);
                if (attackSucceeded) {
                    if (knockbackModifier > 0) {
                        if (targetEntity instanceof LivingEntity) {
                            ((LivingEntity) targetEntity).knockback((float) knockbackModifier * 0.5F, (double) Mth.sin(this.yRot * 0.017453292F), (double) (-Mth.cos(this.yRot * 0.017453292F)));
                        } else {
                            targetEntity.push((double) (-Mth.sin(this.yRot * 0.017453292F) * (float) knockbackModifier * 0.5F), 0.1D, (double) (Mth.cos(this.yRot * 0.017453292F) * (float) knockbackModifier * 0.5F));
                        }
                        this.shadow$setDeltaMovement(this.shadow$getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
                        this.shadow$setSprinting(false);
                    }
                    if (isSweapingAttack) {
                        for (final LivingEntity livingEntity : this.level.getEntitiesOfClass(LivingEntity.class, targetEntity.getBoundingBox().inflate(1.0D, 0.25D, 1.0D))) {
                            if (livingEntity != (net.minecraft.world.entity.player.Player) (Object) this && livingEntity != targetEntity && !this.shadow$isAlliedTo(livingEntity) && (!(livingEntity instanceof ArmorStand) || !((ArmorStand) livingEntity).isMarker()) && this.shadow$distanceToSqr(livingEntity) < 9.0D) {
                                // Sponge Start - Do a small event for these entities
                                // livingEntity.knockBack(this, 0.4F, (double)MathHelper.sin(this.rotationYaw * 0.017453292F), (double)(-MathHelper.cos(this.rotationYaw * 0.017453292F)));
                                // livingEntity.attackEntityFrom(DamageSource.causePlayerDamage(this), 1.0F);
                                final EntityDamageSource sweepingAttackSource = EntityDamageSource.builder().entity((org.spongepowered.api.entity.living.player.Player) this).type(DamageTypes.SWEEPING_ATTACK).build();
                                try (final CauseStackManager.StackFrame frame = isMainthread ? PhaseTracker.getInstance().pushCauseFrame() : null) {
                                    if (isMainthread) {
                                        frame.pushCause(sweepingAttackSource);
                                    }
                                    final ItemStackSnapshot heldSnapshot = ItemStackUtil.snapshotOf(heldItem);
                                    if (isMainthread) {
                                        frame.addContext(EventContextKeys.WEAPON, heldSnapshot);
                                    }
                                    final DamageFunction sweapingFunction = DamageFunction.of(DamageModifier.builder().cause(Cause.of(EventContext.empty(), heldSnapshot)).item(heldSnapshot).type(DamageModifierTypes.SWEEPING).build(), incoming -> EnchantmentHelper.getSweepingDamageRatio((net.minecraft.world.entity.player.Player) (Object) this) * attackDamage);
                                    final List<DamageFunction> sweapingFunctions = new ArrayList<>();
                                    sweapingFunctions.add(sweapingFunction);
                                    final AttackEntityEvent sweepingAttackEvent = SpongeEventFactory.createAttackEntityEvent(currentCause, (org.spongepowered.api.entity.Entity) livingEntity, sweapingFunctions, 1, 1.0D);
                                    SpongeCommon.post(sweepingAttackEvent);
                                    if (!sweepingAttackEvent.isCancelled()) {
                                        livingEntity.knockback(sweepingAttackEvent.knockbackModifier() * 0.4F, (double) Mth.sin(this.yRot * ((float) Math.PI / 180F)), (double) -Mth.cos(this.yRot * ((float) Math.PI / 180F)));
                                        livingEntity.hurt(DamageSource.playerAttack((net.minecraft.world.entity.player.Player) (Object) this), (float) sweepingAttackEvent.finalOutputDamage());
                                    }
                                }
                            // Sponge End
                            }
                        }
                        if (this.bridge$vanishState().createsSounds()) {
                            this.level.playSound(null, this.shadow$getX(), this.shadow$getY(), this.shadow$getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, this.shadow$getSoundSource(), 1.0F, 1.0F);
                        }
                        this.shadow$sweepAttack();
                    }
                    if (targetEntity instanceof ServerPlayer && targetEntity.hurtMarked) {
                        ((ServerPlayer) targetEntity).connection.send(new ClientboundSetEntityMotionPacket(targetEntity));
                        targetEntity.hurtMarked = false;
                        targetEntity.setDeltaMovement(targetMotion);
                    }
                    if (isCriticalAttack) {
                        if (this.bridge$vanishState().createsSounds()) {
                            this.level.playSound(null, this.shadow$getX(), this.shadow$getY(), this.shadow$getZ(), SoundEvents.PLAYER_ATTACK_CRIT, this.shadow$getSoundSource(), 1.0F, 1.0F);
                        }
                        this.shadow$crit(targetEntity);
                    }
                    if (!isCriticalAttack && !isSweapingAttack && this.bridge$vanishState().createsSounds()) {
                        if (isStrongAttack) {
                            this.level.playSound(null, this.shadow$getX(), this.shadow$getY(), this.shadow$getZ(), SoundEvents.PLAYER_ATTACK_STRONG, this.shadow$getSoundSource(), 1.0F, 1.0F);
                        } else {
                            this.level.playSound(null, this.shadow$getX(), this.shadow$getY(), this.shadow$getZ(), SoundEvents.PLAYER_ATTACK_WEAK, this.shadow$getSoundSource(), 1.0F, 1.0F);
                        }
                    }
                    if (enchantmentDamage > 0.0F) {
                        this.shadow$magicCrit(targetEntity);
                    }
                    this.shadow$setLastHurtMob(targetEntity);
                    if (targetEntity instanceof LivingEntity) {
                        EnchantmentHelper.doPostHurtEffects((LivingEntity) targetEntity, (net.minecraft.world.entity.player.Player) (Object) this);
                    }
                    EnchantmentHelper.doPostDamageEffects((net.minecraft.world.entity.player.Player) (Object) this, targetEntity);
                    final ItemStack itemstack1 = this.shadow$getMainHandItem();
                    Entity entity = targetEntity;
                    // Sponge - Forge compatibility for multi-part entities
                    entity = PlatformHooks.INSTANCE.getEntityHooks().getParentPart(entity);
                    if (!this.level.isClientSide && !itemstack1.isEmpty() && entity instanceof LivingEntity) {
                        itemstack1.hurtEnemy((LivingEntity) entity, (net.minecraft.world.entity.player.Player) (Object) this);
                        if (itemstack1.isEmpty()) {
                            // Sponge - platform hook for forge
                            PlatformHooks.INSTANCE.getEventHooks().callItemDestroyedEvent((net.minecraft.world.entity.player.Player) (Object) this, itemstack1, InteractionHand.MAIN_HAND);
                            this.shadow$setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY);
                        }
                        // Sponge Start
                        final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
                        final TransactionalCaptureSupplier transactor = context.getTransactor();
                        transactor.logPlayerInventoryChange((net.minecraft.world.entity.player.Player) (Object) this, PlayerInventoryTransaction.EventCreator.STANDARD);
                        // capture
                        this.inventoryMenu.broadcastChanges();
                    // Spong End
                    }
                    if (targetEntity instanceof LivingEntity) {
                        final float f5 = targetOriginalHealth - ((LivingEntity) targetEntity).getHealth();
                        this.shadow$awardStat(Stats.DAMAGE_DEALT, Math.round(f5 * 10.0F));
                        if (fireAspectModifier > 0) {
                            targetEntity.setSecondsOnFire(fireAspectModifier * 4);
                        }
                        if (this.level instanceof ServerWorld && f5 > 2.0F) {
                            final int k = (int) ((double) f5 * 0.5D);
                            ((net.minecraft.server.level.ServerLevel) this.level).sendParticles(ParticleTypes.DAMAGE_INDICATOR, targetEntity.getX(), targetEntity.getY() + (double) (targetEntity.getBbHeight() * 0.5F), targetEntity.getZ(), k, 0.1D, 0.0D, 0.1D, 0.2D);
                        }
                    }
                    this.shadow$causeFoodExhaustion(0.1F);
                } else {
                    if (this.bridge$vanishState().createsSounds()) {
                        this.level.playSound(null, this.shadow$getX(), this.shadow$getY(), this.shadow$getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.shadow$getSoundSource(), 1.0F, 1.0F);
                    }
                    if (litEntityOnFire) {
                        targetEntity.clearFire();
                    }
                }
            }
        }
    }
}
Also used : ResourceLocation(net.minecraft.resources.ResourceLocation) LivingEntity(net.minecraft.world.entity.LivingEntity) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) MobType(net.minecraft.world.entity.MobType) EventContext(org.spongepowered.api.event.EventContext) Mixin(org.spongepowered.asm.mixin.Mixin) PlayerInventoryTransaction(org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) AttackEntityEvent(org.spongepowered.api.event.entity.AttackEntityEvent) InventoryMenu(net.minecraft.world.inventory.InventoryMenu) DamageTypes(org.spongepowered.api.event.cause.entity.damage.DamageTypes) Final(org.spongepowered.asm.mixin.Final) Collectors(java.util.stream.Collectors) ClientboundSetEntityMotionPacket(net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket) Player(net.minecraft.world.entity.player.Player) DamageEventUtil(org.spongepowered.common.util.DamageEventUtil) List(java.util.List) PlatformHooks(org.spongepowered.common.hooks.PlatformHooks) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) Shadow(org.spongepowered.asm.mixin.Shadow) ItemStack(net.minecraft.world.item.ItemStack) ModifierFunction(org.spongepowered.api.event.cause.entity.damage.ModifierFunction) EntityDamageSource(org.spongepowered.api.event.cause.entity.damage.source.EntityDamageSource) NonNull(org.checkerframework.checker.nullness.qual.NonNull) EventContextKeys(org.spongepowered.api.event.EventContextKeys) ServerWorld(org.spongepowered.api.world.server.ServerWorld) EventHooks(org.spongepowered.common.hooks.EventHooks) DamageModifierTypes(org.spongepowered.api.event.cause.entity.damage.DamageModifierTypes) Overwrite(org.spongepowered.asm.mixin.Overwrite) MobEffects(net.minecraft.world.effect.MobEffects) ArrayList(java.util.ArrayList) ServerPlayer(net.minecraft.server.level.ServerPlayer) ItemStackUtil(org.spongepowered.common.item.util.ItemStackUtil) DamageSource(net.minecraft.world.damagesource.DamageSource) EnchantmentHelper(net.minecraft.world.item.enchantment.EnchantmentHelper) SoundEvents(net.minecraft.sounds.SoundEvents) Stats(net.minecraft.stats.Stats) ArmorStand(net.minecraft.world.entity.decoration.ArmorStand) CauseStackManager(org.spongepowered.api.event.CauseStackManager) LivingEntityMixin(org.spongepowered.common.mixin.core.world.entity.LivingEntityMixin) SwordItem(net.minecraft.world.item.SwordItem) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) SpongeCommon(org.spongepowered.common.SpongeCommon) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) Cause(org.spongepowered.api.event.Cause) Entity(net.minecraft.world.entity.Entity) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) Attributes(net.minecraft.world.entity.ai.attributes.Attributes) InteractionHand(net.minecraft.world.InteractionHand) ParticleTypes(net.minecraft.core.particles.ParticleTypes) Mth(net.minecraft.util.Mth) LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) ArrayList(java.util.ArrayList) MobType(net.minecraft.world.entity.MobType) SwordItem(net.minecraft.world.item.SwordItem) EntityDamageSource(org.spongepowered.api.event.cause.entity.damage.source.EntityDamageSource) LivingEntity(net.minecraft.world.entity.LivingEntity) ServerWorld(org.spongepowered.api.world.server.ServerWorld) AttackEntityEvent(org.spongepowered.api.event.entity.AttackEntityEvent) ClientboundSetEntityMotionPacket(net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket) ArmorStand(net.minecraft.world.entity.decoration.ArmorStand) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) CauseStackManager(org.spongepowered.api.event.CauseStackManager) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) Cause(org.spongepowered.api.event.Cause) EventHooks(org.spongepowered.common.hooks.EventHooks) Player(net.minecraft.world.entity.player.Player) ServerPlayer(net.minecraft.server.level.ServerPlayer) EntityDamageSource(org.spongepowered.api.event.cause.entity.damage.source.EntityDamageSource) DamageSource(net.minecraft.world.damagesource.DamageSource) ServerPlayer(net.minecraft.server.level.ServerPlayer) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ModifierFunction(org.spongepowered.api.event.cause.entity.damage.ModifierFunction) ItemStack(net.minecraft.world.item.ItemStack) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 20 with TransactionalCaptureSupplier

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

the class ServerPlayerMixin_Inventory method inventory$onUpdateUsingItem.

@Override
protected void inventory$onUpdateUsingItem(final LivingEntity thisPlayer) {
    final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext();
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    try (final EffectTransactor ignored = transactor.logPlayerInventoryChangeWithEffect((ServerPlayer) (Object) this, PlayerInventoryTransaction.EventCreator.STANDARD)) {
        this.shadow$completeUsingItem();
        this.inventoryMenu.broadcastChanges();
    }
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)

Aggregations

TransactionalCaptureSupplier (org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier)25 EffectTransactor (org.spongepowered.common.event.tracking.context.transaction.EffectTransactor)16 Redirect (org.spongepowered.asm.mixin.injection.Redirect)11 Inventory (org.spongepowered.api.item.inventory.Inventory)5 ServerPlayer (net.minecraft.server.level.ServerPlayer)4 ItemStack (net.minecraft.world.item.ItemStack)4 CraftingInventory (org.spongepowered.api.item.inventory.crafting.CraftingInventory)4 Inject (org.spongepowered.asm.mixin.injection.Inject)4 InteractionResult (net.minecraft.world.InteractionResult)2 Player (net.minecraft.world.entity.player.Player)2 AbstractContainerMenu (net.minecraft.world.inventory.AbstractContainerMenu)2 Cause (org.spongepowered.api.event.Cause)2 CauseStackManager (org.spongepowered.api.event.CauseStackManager)2 ServerWorld (org.spongepowered.api.world.server.ServerWorld)2 Overwrite (org.spongepowered.asm.mixin.Overwrite)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Collectors (java.util.stream.Collectors)1 Audience (net.kyori.adventure.audience.Audience)1 Component (net.kyori.adventure.text.Component)1