Search in sources :

Example 81 with Player

use of net.minecraft.world.entity.player.Player in project SpongeCommon by SpongePowered.

the class LivingEntityMixin_Attack_impl method hurt.

// @formatter:on
/**
 * @author bloodmc - November 22, 2015
 * @author gabizou - Updated April 11th, 2016 - Update for 1.9 changes
 * @author Aaron1011 - Updated Nov 11th, 2016 - Update for 1.11 changes
 * @author gabizou - Updated Nov 15th, 2020 - Update for 1.15 changes
 * @author gabizou - Updated Jan 26th, 2022 - Update for 1.16.5 changes
 * @reason Reroute damageEntity calls to our hook in order to prevent damage.
 */
@Overwrite
public boolean hurt(final DamageSource source, final float amount) {
    // Sponge start - Add certain hooks for necessities
    this.lastDamageSource = source;
    if (source == null) {
        new PrettyPrinter(60).centre().add("Null DamageSource").hr().addWrapped("Sponge has found a null damage source! This should NEVER happen " + "as the DamageSource is used for all sorts of calculations. Usually" + " this can be considered developer error. Please report the following" + " stacktrace to the most appropriate mod/plugin available.").add().add(new IllegalArgumentException("Null DamageSource")).log(SpongeCommon.logger(), Level.WARN);
        return false;
    }
    // Sponge - This hook is for forge use mainly
    if (!this.bridge$onLivingAttack((LivingEntity) (Object) this, source, amount)) {
        return false;
    }
    // Sponge end
    if (this.shadow$isInvulnerableTo(source)) {
        return false;
    } else if (this.level.isClientSide) {
        return false;
    // Sponge - Also ignore our customary damage source
    } else if (this.shadow$isDeadOrDying() && source != SpongeDamageSources.IGNORED) {
        return false;
    } else if (source.isFire() && this.shadow$hasEffect(MobEffects.FIRE_RESISTANCE)) {
        return false;
    } else {
        if (this.shadow$isSleeping() && !this.level.isClientSide) {
            this.shadow$stopSleeping();
        }
        this.noActionTime = 0;
        final float f = amount;
        // Sponge - ignore as this is handled in our damageEntityHook
        // if ((source == DamageSource.ANVIL || source == DamageSource.FALLING_BLOCK) && !this.getItemStackFromSlot(EntityEquipmentSlot.HEAD).isEmpty())
        // {
        // this.getItemStackFromSlot(EquipmentSlotType.HEAD).damageItem((int)(amount * 4.0F + this.rand.nextFloat() * amount * 2.0F), this, (p_213341_0_) -> {
        // p_213341_0_.sendBreakAnimation(EquipmentSlotType.HEAD);
        // });
        // amount *= 0.75F;
        // }
        // Sponge End
        // Sponge - set the 'shield blocking ran' flag to the proper value, since
        // we comment out the logic below
        float f1 = 0.0F;
        final boolean flag = amount > 0.0F && this.shadow$isDamageSourceBlocked(source);
        // but we need to account for the amount later.
        if (flag) {
            f1 = amount;
        }
        // boolean flag = false;
        // 
        // if (amount > 0.0F && this.shadow$canBlockDamageSource(source))
        // {
        // this.damageShield(amount);
        // amount = 0.0F;
        // 
        // if (!source.isProjectile())
        // {
        // Entity entity = source.getImmediateSource();
        // 
        // if (entity instanceof EntityLivingBase)
        // {
        // this.blockUsingShield((EntityLivingBase)entity);
        // }
        // }
        // 
        // flag = true;
        // }
        // Sponge end
        this.animationSpeed = 1.5F;
        boolean flag1 = true;
        if ((float) this.invulnerableTime > 10.0F) {
            if (amount <= this.lastHurt) {
                // Technically, this is wrong since 'amount' won't be 0 if a shield is used. However, we need bridge$damageEntityHook so that we process the shield, so we leave it as-is
                return false;
            }
            // damageEntity method, which would re-run our bridge$damageEntityHook.
            if (((EntityTypeBridge) this.shadow$getType()).bridge$overridesDamageEntity()) {
                this.shadow$actuallyHurt(source, amount - this.lastHurt);
            } else {
                if (!this.bridge$damageEntity(source, amount - this.lastHurt)) {
                    return false;
                }
            }
            // this.damageEntity(source, amount - this.lastHurt); // handled above
            // Sponge end
            this.lastHurt = amount;
            flag1 = false;
        } else {
            // Sponge start - reroute to our damage hook
            if (((EntityTypeBridge) this.shadow$getType()).bridge$overridesDamageEntity()) {
                this.shadow$actuallyHurt(source, amount);
            } else {
                if (!this.bridge$damageEntity(source, amount)) {
                    return false;
                }
            }
            this.lastHurt = amount;
            this.invulnerableTime = 20;
            // this.damageEntity(source, amount); // handled above
            // Sponge end
            this.hurtDuration = 10;
            this.hurtTime = this.hurtDuration;
        }
        this.hurtDir = 0.0F;
        final Entity entity = source.getEntity();
        if (entity != null) {
            if (entity instanceof LivingEntity) {
                this.shadow$setLastHurtByMob((LivingEntity) entity);
            }
            if (entity instanceof Player) {
                this.lastHurtByPlayerTime = 100;
                this.lastHurtByPlayer = (Player) entity;
            // Forge Start - use TameableEntity instead of WolfEntity
            // } else if (entity1 instanceof WolfEntity) {
            // WolfEntity wolfentity = (WolfEntity)entity1;
            } else if (entity instanceof TamableAnimal) {
                final TamableAnimal wolfentity = (TamableAnimal) entity;
                if (wolfentity.isTame()) {
                    this.lastHurtByPlayerTime = 100;
                    final LivingEntity livingentity = wolfentity.getOwner();
                    if (livingentity != null && livingentity.getType() == EntityType.PLAYER) {
                        this.lastHurtByPlayer = (Player) livingentity;
                    } else {
                        this.lastHurtByPlayer = null;
                    }
                }
            }
        }
        if (flag1) {
            if (flag) {
                this.level.broadcastEntityEvent((LivingEntity) (Object) this, (byte) 29);
            } else if (source instanceof EntityDamageSource && ((EntityDamageSource) source).isThorns()) {
                this.level.broadcastEntityEvent((LivingEntity) (Object) this, (byte) 33);
            } else {
                final byte b0;
                if (source == DamageSource.DROWN) {
                    b0 = 36;
                } else if (source.isFire()) {
                    b0 = 37;
                } else if (source == DamageSource.SWEET_BERRY_BUSH) {
                    b0 = 44;
                } else {
                    b0 = 2;
                }
                this.level.broadcastEntityEvent((LivingEntity) (Object) this, b0);
            }
            if (source != DamageSource.DROWN && !flag) {
                // Sponge - remove 'amount > 0.0F' - it's redundant in Vanilla, and breaks our handling of shields
                this.shadow$markHurt();
            }
            if (entity != null) {
                double d1 = entity.getX() - this.shadow$getX();
                double d0;
                for (d0 = entity.getZ() - this.shadow$getZ(); d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) {
                    d1 = (Math.random() - Math.random()) * 0.01D;
                }
                this.hurtDir = (float) (Mth.atan2(d0, d1) * 57.2957763671875D - (double) this.yRot);
                this.shadow$knockback(0.4F, d1, d0);
            } else {
                this.hurtDir = (float) (Math.random() * 2.0D * 180);
            }
        }
        if (this.shadow$isDeadOrDying()) {
            if (!this.shadow$checkTotemDeathProtection(source)) {
                final SoundEvent soundevent = this.shadow$getDeathSound();
                // Sponge - Check that we're not vanished
                if (this.bridge$vanishState().createsSounds() && flag1 && soundevent != null) {
                    this.shadow$playSound(soundevent, this.shadow$getSoundVolume(), this.shadow$getVoicePitch());
                }
                // Sponge tracker will redirect this call
                this.shadow$die(source);
            }
        } else if (flag1) {
            // Sponge - Check if we're vanished
            if (this.bridge$vanishState().createsSounds()) {
                this.shadow$playHurtSound(source);
            }
        }
        // Sponge - remove 'amount > 0.0F' since it's handled in the event
        final boolean flag2 = !flag;
        if (flag2) {
            this.lastDamageSource = source;
            this.lastDamageStamp = this.level.getGameTime();
        }
        if ((LivingEntity) (Object) this instanceof net.minecraft.server.level.ServerPlayer) {
            CriteriaTriggers.ENTITY_HURT_PLAYER.trigger((net.minecraft.server.level.ServerPlayer) (Object) this, source, f, amount, flag);
            if (f1 > 0.0F && f1 < 3.4028235E37F) {
                ((net.minecraft.server.level.ServerPlayer) (Object) this).awardStat(Stats.DAMAGE_BLOCKED_BY_SHIELD, Math.round(f1 * 10.0F));
            }
        }
        if (entity instanceof net.minecraft.server.level.ServerPlayer) {
            CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((net.minecraft.server.level.ServerPlayer) entity, (Entity) (Object) this, source, f, amount, flag);
        }
        return flag2;
    }
}
Also used : LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) Player(net.minecraft.world.entity.player.Player) TamableAnimal(net.minecraft.world.entity.TamableAnimal) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource) LivingEntity(net.minecraft.world.entity.LivingEntity) SoundEvent(net.minecraft.sounds.SoundEvent) PrettyPrinter(org.spongepowered.common.util.PrettyPrinter) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 82 with Player

use of net.minecraft.world.entity.player.Player 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 83 with Player

use of net.minecraft.world.entity.player.Player in project SpongeCommon by SpongePowered.

the class FishingHookMixin method retrieve.

/**
 * @author Aaron1011 - February 6th, 2015
 * @author Minecrell - December 24th, 2016 (Updated to Minecraft 1.11.2)
 * @author Minecrell - June 14th, 2017 (Rewritten to handle cases where no items are dropped)
 * @reason This needs to handle for both cases where a fish and/or an entity is being caught.
 */
@Overwrite
public int retrieve(final ItemStack stack) {
    final Player playerEntity = this.shadow$getPlayerOwner();
    if (!this.level.isClientSide && playerEntity != null) {
        int i = 0;
        // Sponge start
        final List<Transaction<@NonNull ItemStackSnapshot>> transactions;
        if (this.nibble > 0) {
            // Moved from below
            final LootContext.Builder lootcontext$builder = new LootContext.Builder((ServerLevel) this.level).withParameter(LootContextParams.ORIGIN, this.shadow$position()).withParameter(LootContextParams.TOOL, stack).withParameter(LootContextParams.THIS_ENTITY, (FishingHook) (Object) this).withRandom(this.random).withLuck((float) this.luck + playerEntity.getLuck());
            final LootTable lootTable = this.level.getServer().getLootTables().get(BuiltInLootTables.FISHING);
            final List<ItemStack> list = lootTable.getRandomItems(lootcontext$builder.create(LootContextParamSets.FISHING));
            transactions = list.stream().map(ItemStackUtil::snapshotOf).map(snapshot -> new Transaction<>(snapshot, snapshot)).collect(Collectors.toList());
            CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) playerEntity, stack, (FishingHook) (Object) this, list);
        } else {
            transactions = new ArrayList<>();
        }
        PhaseTracker.getCauseStackManager().pushCause(playerEntity);
        if (SpongeCommon.post(SpongeEventFactory.createFishingEventStop(PhaseTracker.getCauseStackManager().currentCause(), ((FishingBobber) this), transactions))) {
            // Event is cancelled
            return 0;
        }
        if (this.hookedIn != null) {
            this.bringInHookedEntity();
            CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) playerEntity, stack, (FishingHook) (Object) this, Collections.emptyList());
            this.level.broadcastEntityEvent((FishingHook) (Object) this, (byte) 31);
            i = this.hookedIn instanceof ItemEntity ? 3 : 5;
        }
        // Sponge start - Moved up to event call
        if (!transactions.isEmpty()) {
            // Use transactions
            for (final Transaction<@NonNull ItemStackSnapshot> transaction : transactions) {
                if (!transaction.isValid()) {
                    continue;
                }
                final ItemStack itemstack = (ItemStack) (Object) transaction.finalReplacement().createStack();
                // Sponge end
                final ItemEntity entityitem = new ItemEntity(this.level, this.shadow$getX(), this.shadow$getY(), this.shadow$getZ(), itemstack);
                final double d0 = playerEntity.getX() - this.shadow$getX();
                final double d1 = playerEntity.getY() - this.shadow$getY();
                final double d2 = playerEntity.getZ() - this.shadow$getZ();
                final double d3 = Mth.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
                // double d4 = 0.1D;
                entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Mth.sqrt(d3) * 0.08D, d2 * 0.1D);
                this.level.addFreshEntity(entityitem);
                playerEntity.level.addFreshEntity(new ExperienceOrb(playerEntity.level, playerEntity.getX(), playerEntity.getY() + 0.5D, playerEntity.getZ() + 0.5D, this.random.nextInt(6) + 1));
                final Item item = itemstack.getItem();
                if (item.is(ItemTags.FISHES)) {
                    playerEntity.awardStat(Stats.FISH_CAUGHT, 1);
                }
            }
            PhaseTracker.getCauseStackManager().popCause();
            // Sponge: Don't lower damage if we've also caught an entity
            i = Math.max(i, 1);
        }
        if (this.onGround) {
            i = 2;
        }
        this.shadow$remove();
        return i;
    } else {
        return 0;
    }
}
Also used : LootTable(net.minecraft.world.level.storage.loot.LootTable) ServerLevel(net.minecraft.server.level.ServerLevel) ServerPlayer(net.minecraft.server.level.ServerPlayer) Player(net.minecraft.world.entity.player.Player) ItemEntity(net.minecraft.world.entity.item.ItemEntity) LootContext(net.minecraft.world.level.storage.loot.LootContext) ExperienceOrb(net.minecraft.world.entity.ExperienceOrb) Item(net.minecraft.world.item.Item) Transaction(org.spongepowered.api.data.Transaction) NonNull(org.checkerframework.checker.nullness.qual.NonNull) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) ItemStack(net.minecraft.world.item.ItemStack) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 84 with Player

use of net.minecraft.world.entity.player.Player in project SpongeCommon by SpongePowered.

the class RunAroundLikeCrazyGoalMixin method tick.

// @formatter:on
/**
 * @author rexbut - December 16th, 2016
 * @author i509VCB - February 18th, 2020 - 1.14.4
 *
 * @reason - adjusted to support {@link DismountTypes}
 */
@Overwrite
public void tick() {
    if (!this.horse.isTamed() && this.horse.getRandom().nextInt(50) == 0) {
        Entity entity = this.horse.getPassengers().get(0);
        if (entity == null) {
            return;
        }
        if (entity instanceof Player) {
            int i = this.horse.getTemper();
            int j = this.horse.getMaxTemper();
            if (j > 0 && this.horse.getRandom().nextInt(j) < i) {
                // Sponge start - Fire Tame Entity event
                try (CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
                    frame.pushCause(entity);
                    if (SpongeCommon.post(SpongeEventFactory.createTameEntityEvent(frame.currentCause(), (HorseLike) this.horse))) {
                        return;
                    }
                }
                // Sponge end
                this.horse.tameWithName((Player) entity);
                return;
            }
            this.horse.modifyTemper(5);
        }
        // this.horseHost.ejectPassengers(); // Vanilla
        if (((EntityBridge) this.horse).bridge$removePassengers(DismountTypes.DERAIL.get())) {
            // Sponge end
            this.horse.makeMad();
            this.horse.level.broadcastEntityEvent(this.horse, (byte) 6);
        }
    }
}
Also used : Entity(net.minecraft.world.entity.Entity) Player(net.minecraft.world.entity.player.Player) CauseStackManager(org.spongepowered.api.event.CauseStackManager) HorseLike(org.spongepowered.api.entity.living.animal.horse.HorseLike) EntityBridge(org.spongepowered.common.bridge.world.entity.EntityBridge) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 85 with Player

use of net.minecraft.world.entity.player.Player in project SpongeCommon by SpongePowered.

the class ExplosionMixin method explode.

/**
 * @author gabizou
 * @author zidane
 * @reason Fire ExplosionEvent.Detonate
 */
@Overwrite
public void explode() {
    // Sponge Start - Do not run calculation logic on client thread
    if (this.level.isClientSide) {
        return;
    }
    // Sponge Start - If the explosion should not break blocks, don't bother calculating it on server thread
    if (this.impl$shouldBreakBlocks) {
        final Set<BlockPos> set = Sets.newHashSet();
        final int i = 16;
        for (int j = 0; j < 16; ++j) {
            for (int k = 0; k < 16; ++k) {
                for (int l = 0; l < 16; ++l) {
                    if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
                        double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
                        double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
                        double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
                        final double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
                        d0 = d0 / d3;
                        d1 = d1 / d3;
                        d2 = d2 / d3;
                        float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F);
                        double d4 = this.x;
                        double d6 = this.y;
                        double d8 = this.z;
                        for (final float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
                            final BlockPos blockpos = new BlockPos(d4, d6, d8);
                            final BlockState blockstate = this.level.getBlockState(blockpos);
                            final FluidState fluidstate = this.level.getFluidState(blockpos);
                            Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance((net.minecraft.world.level.Explosion) (Object) this, this.level, blockpos, blockstate, fluidstate);
                            if (optional.isPresent()) {
                                f -= (optional.get() + 0.3F) * 0.3F;
                            }
                            if (f > 0.0F && this.damageCalculator.shouldBlockExplode((net.minecraft.world.level.Explosion) (Object) this, this.level, blockpos, blockstate, f)) {
                                set.add(blockpos);
                            }
                            d4 += d0 * (double) 0.3F;
                            d6 += d1 * (double) 0.3F;
                            d8 += d2 * (double) 0.3F;
                        }
                    }
                }
            }
        }
        this.toBlow.addAll(set);
    }
    // Sponge End
    final float f3 = this.radius * 2.0F;
    final int k1 = Mth.floor(this.x - (double) f3 - 1.0D);
    final int l1 = Mth.floor(this.x + (double) f3 + 1.0D);
    final int i2 = Mth.floor(this.y - (double) f3 - 1.0D);
    final int i1 = Mth.floor(this.y + (double) f3 + 1.0D);
    final int j2 = Mth.floor(this.z - (double) f3 - 1.0D);
    final int j1 = Mth.floor(this.z + (double) f3 + 1.0D);
    // Sponge Start - Only query for entities if we're to damage them
    final List<Entity> list = this.impl$shouldDamageEntities ? this.level.getEntities(this.source, new AABB((double) k1, (double) i2, (double) j2, (double) l1, (double) i1, (double) j1)) : Collections.emptyList();
    if (ShouldFire.EXPLOSION_EVENT_DETONATE) {
        final List<ServerLocation> blockPositions = new ArrayList<>(this.toBlow.size());
        final List<org.spongepowered.api.entity.Entity> entities = new ArrayList<>(list.size());
        for (final BlockPos pos : this.toBlow) {
            blockPositions.add(ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) this.level, pos.getX(), pos.getY(), pos.getZ()));
        }
        for (final Entity entity : list) {
            // Make sure to check the entity is immune first.
            if (!entity.ignoreExplosion()) {
                entities.add((org.spongepowered.api.entity.Entity) entity);
            }
        }
        final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
        final ExplosionEvent.Detonate detonate = SpongeEventFactory.createExplosionEventDetonate(cause, blockPositions, entities, (Explosion) this, (org.spongepowered.api.world.server.ServerWorld) this.level);
        SpongeCommon.post(detonate);
        // Clear the positions so that they can be pulled from the event
        this.toBlow.clear();
        if (detonate.isCancelled()) {
            return;
        }
        if (this.impl$shouldBreakBlocks) {
            for (final ServerLocation worldLocation : detonate.affectedLocations()) {
                this.toBlow.add(VecHelper.toBlockPos(worldLocation));
            }
        }
        // Clear the list of entities so they can be pulled from the event.
        list.clear();
        if (this.impl$shouldDamageEntities) {
            for (final org.spongepowered.api.entity.Entity entity : detonate.entities()) {
                try {
                    list.add((Entity) entity);
                } catch (final Exception e) {
                // Do nothing, a plugin tried to use the wrong entity somehow.
                }
            }
        }
    }
    // Sponge End
    final Vec3 vec3d = new Vec3(this.x, this.y, this.z);
    for (int k2 = 0; k2 < list.size(); ++k2) {
        final Entity entity = list.get(k2);
        if (!entity.ignoreExplosion()) {
            final double d12 = (double) (Mth.sqrt(entity.distanceToSqr(vec3d)) / f3);
            if (d12 <= 1.0D) {
                double d5 = entity.getX() - this.x;
                double d7 = entity.getEyeY() - this.y;
                double d9 = entity.getZ() - this.z;
                final double d13 = (double) Mth.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
                if (d13 != 0.0D) {
                    d5 = d5 / d13;
                    d7 = d7 / d13;
                    d9 = d9 / d13;
                    final double d14 = (double) net.minecraft.world.level.Explosion.getSeenPercent(vec3d, entity);
                    final double d10 = (1.0D - d12) * d14;
                    entity.hurt(this.shadow$getDamageSource(), (float) ((int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f3 + 1.0D)));
                    double d11 = d10;
                    if (entity instanceof LivingEntity) {
                        d11 = ProtectionEnchantment.getExplosionKnockbackAfterDampener((LivingEntity) entity, d10);
                    }
                    // Sponge Start - Honor our knockback value from event
                    entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11 * this.impl$knockback, d7 * d11 * this.impl$knockback, d9 * d11 * this.impl$knockback));
                    if (entity instanceof Player) {
                        final Player playerentity = (Player) entity;
                        if (!playerentity.isSpectator() && (!playerentity.isCreative() || !playerentity.abilities.flying)) {
                            this.hitPlayers.put(playerentity, new Vec3(d5 * d10 * this.impl$knockback, d7 * d10 * this.impl$knockback, d9 * d10 * this.impl$knockback));
                        }
                    }
                // Sponge End
                }
            }
        }
    }
}
Also used : LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) ServerLocation(org.spongepowered.api.world.server.ServerLocation) ExplosionEvent(org.spongepowered.api.event.world.ExplosionEvent) ArrayList(java.util.ArrayList) LivingEntity(net.minecraft.world.entity.LivingEntity) Cause(org.spongepowered.api.event.Cause) Vec3(net.minecraft.world.phys.Vec3) BlockPos(net.minecraft.core.BlockPos) Player(net.minecraft.world.entity.player.Player) Explosion(org.spongepowered.api.world.explosion.Explosion) BlockState(net.minecraft.world.level.block.state.BlockState) AABB(net.minecraft.world.phys.AABB) FluidState(net.minecraft.world.level.material.FluidState) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Aggregations

Player (net.minecraft.world.entity.player.Player)97 ItemStack (net.minecraft.world.item.ItemStack)65 Level (net.minecraft.world.level.Level)56 InteractionHand (net.minecraft.world.InteractionHand)55 InteractionResult (net.minecraft.world.InteractionResult)52 ItemEntity (net.minecraft.world.entity.item.ItemEntity)51 Items (net.minecraft.world.item.Items)51 EntitySize (de.Keyle.MyPet.api.entity.EntitySize)50 MyPet (de.Keyle.MyPet.api.entity.MyPet)50 InvocationTargetException (java.lang.reflect.InvocationTargetException)50 EntityDataAccessor (net.minecraft.network.syncher.EntityDataAccessor)42 EntityDataSerializers (net.minecraft.network.syncher.EntityDataSerializers)42 SynchedEntityData (net.minecraft.network.syncher.SynchedEntityData)42 ServerLevel (net.minecraft.server.level.ServerLevel)40 Bukkit (org.bukkit.Bukkit)39 MyPetApi (de.Keyle.MyPet.MyPetApi)38 Util (de.Keyle.MyPet.api.Util)38 Pair (com.mojang.datafixers.util.Pair)36 EquipmentSlot (de.Keyle.MyPet.api.entity.EquipmentSlot)36 Arrays (java.util.Arrays)36