@Inject(
      method = "onUpdate",
      at =
          @At(
              value = "INVOKE",
              target = "Lnet/minecraft/entity/effect/EntityLightningBolt;setDead()V"))
  public void onSetDead(CallbackInfo ci) {
    if (this.isDead) {
      return;
    }
    World world = (World) this.worldObj;
    LightningEvent.Strike strike =
        SpongeEventFactory.createLightningEventStrike(
            this.cause, this.struckEntities, this.struckEntitySnapshots, world, this.struckBlocks);
    Sponge.getEventManager().post(strike);

    if (!strike.isCancelled()) {
      for (Transaction<BlockSnapshot> bt : strike.getTransactions()) {
        if (bt.isValid()) {
          BlockSnapshot bs = bt.getFinal();
          world.setBlock(bs.getPosition(), bs.getState());
        }
      }
      for (Entity e : strike.getEntities()) {
        ((net.minecraft.entity.Entity) e).onStruckByLightning((EntityLightningBolt) (Object) this);
      }
      SpongeImpl.postEvent(SpongeEventFactory.createLightningEventPost(this.cause));
    }
  }
Beispiel #2
0
 /**
  * @author gabizou - February 7th, 2016
  *     <p>This will short circuit all other patches such that we control the entities being loaded
  *     by chunkloading and can throw our bulk entity event. This will bypass Forge's hook for
  *     individual entity events, but the SpongeModEventManager will still successfully throw the
  *     appropriate event and cancel the entities otherwise contained.
  * @param entities The entities being loaded
  * @param callbackInfo The callback info
  */
 @Final
 @Inject(method = "loadEntities", at = @At("HEAD"), cancellable = true)
 private void spongeLoadEntities(
     Collection<net.minecraft.entity.Entity> entities, CallbackInfo callbackInfo) {
   if (entities.isEmpty()) {
     // just return, no entities to load!
     callbackInfo.cancel();
     return;
   }
   List<Entity> entityList = new ArrayList<>();
   ImmutableList.Builder<EntitySnapshot> snapshotBuilder = ImmutableList.builder();
   for (net.minecraft.entity.Entity entity : entities) {
     entityList.add((Entity) entity);
     snapshotBuilder.add(((Entity) entity).createSnapshot());
   }
   SpawnCause cause = SpawnCause.builder().type(InternalSpawnTypes.CHUNK_LOAD).build();
   List<NamedCause> causes = new ArrayList<>();
   causes.add(NamedCause.source(cause));
   causes.add(NamedCause.of("World", this));
   SpawnEntityEvent.ChunkLoad chunkLoad =
       SpongeEventFactory.createSpawnEntityEventChunkLoad(
           Cause.of(causes), entityList, snapshotBuilder.build(), this);
   SpongeImpl.postEvent(chunkLoad);
   if (!chunkLoad.isCancelled()) {
     for (Entity successful : chunkLoad.getEntities()) {
       this.loadedEntityList.add((net.minecraft.entity.Entity) successful);
       this.onEntityAdded((net.minecraft.entity.Entity) successful);
     }
   }
   callbackInfo.cancel();
 }
 @Inject(
     method = "newExplosion",
     at = @At(value = "INVOKE", target = "Lnet/minecraft/world/Explosion;doExplosionA()V"),
     locals = LocalCapture.CAPTURE_FAILHARD,
     cancellable = true)
 public void callWorldOnExplosionEvent(
     Entity entityIn,
     double x,
     double y,
     double z,
     float strength,
     boolean isFlaming,
     boolean isSmoking,
     CallbackInfoReturnable<Explosion> cir,
     Explosion explosion) {
   final ExplosionEvent.Pre event =
       SpongeEventFactory.createExplosionEventPre(
           Sponge.getGame(),
           Cause.of(this),
           (org.spongepowered.api.world.explosion.Explosion) explosion,
           (org.spongepowered.api.world.World) this);
   if (Sponge.getGame().getEventManager().post(event)) {
     cir.setReturnValue(explosion);
   }
 }
 @Redirect(
     method = "interact",
     at =
         @At(
             value = "INVOKE",
             target = "Ljava/util/Random;nextInt(I)I",
             ordinal = 0,
             remap = false))
 public int onTame(Random rand, int bound, EntityPlayer player) {
   int random = rand.nextInt(bound);
   if (random == 0
       && !SpongeImpl.postEvent(
           SpongeEventFactory.createTameEntityEvent(
               Cause.of(
                   NamedCause.source(player),
                   NamedCause.of(
                       TameEntityEvent.USED_ITEM,
                       ((org.spongepowered.api.item.inventory.ItemStack) this.currentItemStack)
                           .createSnapshot())),
               this))) {
     this.currentItemStack = null;
     return random;
   }
   this.currentItemStack = null;
   return 1;
 }
 @Inject(
     method = "dropItem",
     at =
         @At(
             value = "FIELD",
             opcode = Opcodes.GETFIELD,
             target = "Lnet/minecraft/entity/player/EntityPlayer;posY:D"),
     cancellable = true)
 private void onDropTop(
     ItemStack itemStack,
     boolean a,
     boolean b,
     CallbackInfoReturnable<EntityItem> callbackInfoReturnable) {
   final double height = this.posY - 0.3D + (double) this.getEyeHeight();
   Transform<org.spongepowered.api.world.World> transform =
       new Transform<>(this.getWorld(), new Vector3d(this.posX, height, this.posZ));
   SpawnCause cause =
       EntitySpawnCause.builder().entity(this).type(SpawnTypes.DROPPED_ITEM).build();
   ConstructEntityEvent.Pre event =
       SpongeEventFactory.createConstructEntityEventPre(
           Cause.of(NamedCause.source(cause)), EntityTypes.ITEM, transform);
   SpongeImpl.postEvent(event);
   if (event.isCancelled()) {
     callbackInfoReturnable.setReturnValue(null);
   }
 }
  @Overwrite
  public static PlayerInteractEvent onPlayerInteract(
      EntityPlayer player,
      Action action,
      net.minecraft.world.World world,
      BlockPos pos,
      EnumFacing face) {
    if (world.isRemote) {
      PlayerInteractEvent event = new PlayerInteractEvent(player, action, pos, face, world);
      MinecraftForge.EVENT_BUS.post(event);
      return event;
    }

    InteractBlockEvent event = null;
    if (action == Action.LEFT_CLICK_BLOCK) {
      event =
          SpongeEventFactory.createInteractBlockEventPrimary(
              SpongeImpl.getGame(),
              Cause.of(player),
              Optional.empty(),
              ((World) world).createSnapshot(VecHelper.toVector(pos)),
              face == null
                  ? Direction.NONE
                  : DirectionFacingProvider.getInstance().getKey(face).get());
    } else {
      event =
          SpongeEventFactory.createInteractBlockEventSecondary(
              SpongeImpl.getGame(),
              Cause.of(player),
              Optional.empty(),
              ((World) world).createSnapshot(VecHelper.toVector(pos)),
              face == null
                  ? Direction.NONE
                  : DirectionFacingProvider.getInstance().getKey(face).get());
    }

    SpongeImpl.postEvent(event);

    return (PlayerInteractEvent) SpongeForgeEventFactory.lastForgeEvent;
  }
  /**
   * @Author Zidane
   *
   * <p>Invoke before {@code System.arraycopy(packetIn.getLines(), 0, tileentitysign.signText, 0,
   * 4);} (line 1156 in source) to call SignChangeEvent.
   *
   * @param packetIn Injected packet param
   * @param ci Info to provide mixin on how to handle the callback
   * @param worldserver Injected world param
   * @param blockpos Injected blockpos param
   * @param tileentity Injected tilentity param
   * @param tileentitysign Injected tileentitysign param
   */
  @Inject(
      method = "processUpdateSign",
      at =
          @At(
              value = "INVOKE",
              target =
                  "Lnet/minecraft/network/play/client/C12PacketUpdateSign;getLines()[Lnet/minecraft/util/IChatComponent;"),
      cancellable = true,
      locals = LocalCapture.CAPTURE_FAILSOFT)
  public void callSignChangeEvent(
      C12PacketUpdateSign packetIn,
      CallbackInfo ci,
      WorldServer worldserver,
      BlockPos blockpos,
      TileEntity tileentity,
      TileEntitySign tileentitysign) {
    ci.cancel();
    final Optional<SignData> existingSignData = ((Sign) tileentitysign).getData();
    if (!existingSignData.isPresent()) {
      // TODO Unsure if this is the best to do here...
      throw new RuntimeException("Critical error! Sign data not present on sign!");
    }
    final SignData changedSignData = existingSignData.get().copy();

    for (int i = 0; i < packetIn.getLines().length; i++) {
      changedSignData.setLine(i, SpongeTexts.toText(packetIn.getLines()[i]));
    }
    // I pass changedSignData in here twice to emulate the fact that even-though the current sign
    // data doesn't have the lines from the packet
    // applied, this is what it "is" right now. If the data shown in the world is desired, it can be
    // fetched from Sign.getData
    final SignChangeEvent event =
        SpongeEventFactory.createSignChange(
            Sponge.getGame(),
            new Cause(null, this.playerEntity, null),
            (Sign) tileentitysign,
            changedSignData,
            changedSignData);
    if (!Sponge.getGame().getEventManager().post(event)) {
      ((Sign) tileentitysign).offer(event.getNewData());
    } else {
      // If cancelled, I set the data back that was fetched from the sign. This means that if its a
      // new sign, the sign will be empty else
      // it will be the text of the sign that was showing in the world
      ((Sign) tileentitysign).offer(existingSignData.get());
    }
    tileentitysign.markDirty();
    worldserver.markBlockForUpdate(blockpos);
  }
Beispiel #8
0
 @Inject(
     method = "randomTick",
     at = @At(value = "HEAD"),
     locals = LocalCapture.CAPTURE_FAILEXCEPTION,
     cancellable = true)
 public void callRandomTickEvent(
     World world, BlockPos pos, IBlockState state, Random rand, CallbackInfo ci) {
   final BlockRandomTickEvent event =
       SpongeEventFactory.createBlockRandomTick(
           Sponge.getGame(),
           null,
           new Location<org.spongepowered.api.world.World>(
               (org.spongepowered.api.world.World) world,
               VecHelper.toVector(pos))); // TODO Fix null Cause
   Sponge.getGame().getEventManager().post(event);
   if (event.isCancelled()) {
     ci.cancel();
   }
 }
 @Inject(
     method = "randomTick",
     at = @At(value = "HEAD"),
     locals = LocalCapture.CAPTURE_FAILEXCEPTION,
     cancellable = true)
 public void callRandomTickEvent(
     net.minecraft.world.World world,
     BlockPos pos,
     IBlockState state,
     Random rand,
     CallbackInfo ci) {
   BlockSnapshot blockSnapshot = ((World) world).createSnapshot(VecHelper.toVector(pos));
   final TickBlockEvent event =
       SpongeEventFactory.createTickBlockEvent(Cause.of(NamedCause.source(world)), blockSnapshot);
   SpongeImpl.postEvent(event);
   if (event.isCancelled()) {
     ci.cancel();
   }
 }
 @Redirect(
     method = "onUpdate",
     at =
         @At(
             value = "INVOKE",
             target = "Lnet/minecraft/entity/player/EntityPlayer;isPlayerSleeping()Z"))
 public boolean onIsPlayerSleeping(EntityPlayer self) {
   if (self.isPlayerSleeping()) {
     if (!this.worldObj.isRemote) {
       SpongeImpl.postEvent(
           SpongeEventFactory.createSleepingEventTick(
               Cause.of(NamedCause.source(this)),
               this.getWorld().createSnapshot(VecHelper.toVector(this.playerLocation)),
               this));
     }
     return true;
   }
   return false;
 }
 @Redirect(
     method = "onUpdate()V",
     at =
         @At(
             value = "INVOKE",
             target =
                 "Lnet/minecraft/entity/Entity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z"))
 public boolean onAttackEntityFrom(
     net.minecraft.entity.Entity entity, DamageSource damageSource, float damage) {
   EntitySnapshot fishHookSnapshot = this.createSnapshot();
   FishingEvent.HookEntity event =
       SpongeEventFactory.createFishingEventHookEntity(
           Cause.of(NamedCause.source(this.angler)), this.createSnapshot(), this, (Entity) entity);
   if (!SpongeImpl.postEvent(event)) {
     if (this.getShooter() instanceof Entity) {
       DamageSource.causeThrownDamage(
           (net.minecraft.entity.Entity) (Object) this,
           (net.minecraft.entity.Entity) this.getShooter());
     }
     return entity.attackEntityFrom(damageSource, (float) this.getDamage());
   }
   return false;
 }
  @Inject(
      method = "processPlayer",
      at =
          @At(
              value = "FIELD",
              target = "net.minecraft.network.NetHandlerPlayServer.hasMoved:Z",
              ordinal = 2),
      cancellable = true)
  public void proccesPlayerMoved(C03PacketPlayer packetIn, CallbackInfo ci) {
    if (packetIn.isMoving() || packetIn.getRotating() && !this.playerEntity.isDead) {
      Player player = (Player) this.playerEntity;
      Vector3d fromrot = player.getRotation();

      // If Sponge used the player's current location, the delta might never be triggered which
      // could be exploited
      Location from = player.getLocation();
      if (this.lastMoveLocation != null) {
        from = this.lastMoveLocation;
      }

      Vector3d torot = new Vector3d(packetIn.getPitch(), packetIn.getYaw(), 0);
      Location to =
          new Location(
              player.getWorld(),
              packetIn.getPositionX(),
              packetIn.getPositionY(),
              packetIn.getPositionZ());

      // Minecraft sends a 0, 0, 0 position when rotation only update occurs, this needs to be
      // recognized and corrected
      boolean rotationOnly = !packetIn.isMoving() && packetIn.getRotating();
      if (rotationOnly) {
        // Correct the to location so it's not misrepresented to plugins, only when player rotates
        // without moving
        // In this case it's only a rotation update, which isn't related to the to location
        from = player.getLocation();
        to = from;
      }

      // Minecraft does the same with rotation when it's only a positional update
      boolean positionOnly = packetIn.isMoving() && !packetIn.getRotating();
      if (positionOnly) {
        // Correct the new rotation to match the old rotation
        torot = fromrot;
      }

      double deltaSquared = to.getPosition().distanceSquared(from.getPosition());
      double deltaAngleSquared = fromrot.distanceSquared(torot);

      // These magic numbers are sad but help prevent excessive lag from this event.
      // eventually it would be nice to not have them
      if (deltaSquared > ((1f / 16) * (1f / 16)) || deltaAngleSquared > (.15f * .15f)) {
        PlayerMoveEvent event =
            SpongeEventFactory.createPlayerMove(Sponge.getGame(), player, from, to, torot);
        Sponge.getGame().getEventManager().post(event);
        if (event.isCancelled()) {
          player.setLocationAndRotation(from, fromrot);
          this.lastMoveLocation = from;
          ci.cancel();
        } else if (!event.getNewLocation().equals(to)) {
          player.setLocationAndRotation(event.getNewLocation(), event.getRotation());
          this.lastMoveLocation = event.getNewLocation();
          ci.cancel();
        } else if (!from.equals(player.getLocation()) && this.justTeleported) {
          this.lastMoveLocation = player.getLocation();
          // Prevent teleports during the move event from causing odd behaviors
          this.justTeleported = false;
          ci.cancel();
        } else {
          this.lastMoveLocation = event.getNewLocation();
        }
      }
    }
  }
  /**
   * @author Aaron1011 - February 6th, 2015
   * @reason This needs to handle for both cases where a fish and/or an entity is being caught.
   *     There's no real good way to do this with an injection.
   */
  @Overwrite
  public int handleHookRetraction() {
    if (this.worldObj.isRemote) {
      return 0;
    }

    // Sponge start
    byte b0 = 0;

    net.minecraft.item.ItemStack itemStack = null;
    int exp = 0;
    if (this.ticksCatchable > 0) {
      itemStack = this.getFishingResult();
      exp = this.rand.nextInt(6) + 1;
    }

    EntitySnapshot fishHookSnapshot = this.createSnapshot();

    Transaction<ItemStackSnapshot> transaction = null;
    if (itemStack != null) {
      ItemStackSnapshot original = ((ItemStack) itemStack).createSnapshot();
      ItemStackSnapshot replacement = ((ItemStack) itemStack).createSnapshot();
      transaction = new Transaction<>(original, replacement);
    } else {
      transaction = new Transaction<>(ItemStackSnapshot.NONE, ItemStackSnapshot.NONE);
    }

    FishingEvent.Stop event =
        SpongeEventFactory.createFishingEventStop(
            Cause.of(NamedCause.source(this.angler)),
            exp,
            exp,
            fishHookSnapshot,
            this,
            transaction,
            (Player) this.angler);
    if (!SpongeImpl.postEvent(event)) {
      // Sponge end
      if (this.caughtEntity != null) {
        double d0 = this.angler.posX - this.posX;
        double d2 = this.angler.posY - this.posY;
        double d4 = this.angler.posZ - this.posZ;
        double d6 = (double) MathHelper.sqrt_double(d0 * d0 + d2 * d2 + d4 * d4);
        double d8 = 0.1D;
        this.caughtEntity.motionX += d0 * d8;
        this.caughtEntity.motionY += d2 * d8 + (double) MathHelper.sqrt_double(d6) * 0.08D;
        this.caughtEntity.motionZ += d4 * d8;
        b0 = 3;
      }

      // Sponge Start
      if (!event.getItemStackTransaction().getFinal().getType().equals(ItemTypes.NONE)) {
        ItemStackSnapshot itemSnapshot = event.getItemStackTransaction().getFinal();
        EntityItem entityitem1 =
            new EntityItem(
                this.worldObj,
                this.posX,
                this.posY,
                this.posZ,
                (net.minecraft.item.ItemStack) itemSnapshot.createStack());
        double d1 = this.angler.posX - this.posX;
        double d3 = this.angler.posY - this.posY;
        double d5 = this.angler.posZ - this.posZ;
        double d7 = MathHelper.sqrt_double(d1 * d1 + d3 * d3 + d5 * d5);
        double d9 = 0.1D;
        entityitem1.motionX = d1 * d9;
        entityitem1.motionY = d3 * d9 + MathHelper.sqrt_double(d7) * 0.08D;
        entityitem1.motionZ = d5 * d9;
        this.worldObj.spawnEntityInWorld(entityitem1);
        this.angler.worldObj.spawnEntityInWorld(
            new EntityXPOrb(
                this.angler.worldObj,
                this.angler.posX,
                this.angler.posY + 0.5D,
                this.angler.posZ + 0.5D,
                event.getExperience()));
        // Sponge End
        b0 = 1;
      }

      if (this.inGround) {
        b0 = 2;
      }

      this.setDead();
      this.angler.fishEntity = null;

      // Sponge Start
      if (this.fishingRod != null) {
        this.fishingRod.damageItem(b0, this.angler);
        this.angler.swingItem();
        this.fishingRod = null;
      }
      // Sponge End
    }
    return b0;
  }
  /**
   * @author gabizou - April 8th, 2016
   * @reason Rewrites the attackTargetEntityWithCurrentItem to throw an {@link AttackEntityEvent}
   *     prior to the ensuing {@link DamageEntityEvent}. This should cover all cases where players
   *     are attacking entities and those entities override {@link
   *     EntityLivingBase#attackEntityFrom(DamageSource, float)} and effectively bypass our damage
   *     event hooks.
   * @param targetEntity The target entity
   */
  @Overwrite
  public void attackTargetEntityWithCurrentItem(net.minecraft.entity.Entity targetEntity) {
    // Sponge Start - Add SpongeImpl hook to override in forge as necessary
    if (!SpongeImplHooks.checkAttackEntity((EntityPlayer) (Object) this, targetEntity)) {
      return;
    }
    // Sponge End
    if (targetEntity.canAttackWithItem()) {
      if (!targetEntity.hitByEntity((EntityPlayer) (Object) this)) {
        // Sponge Start - Prepare our event values
        // float baseDamage =
        // this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue();
        final double originalBaseDamage =
            this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue();
        float baseDamage = (float) originalBaseDamage;
        // Sponge End
        int knockbackModifier = 0;
        float enchantmentModifierAmount = 0.0F;

        // Sponge Start - gather the attack modifiers
        final List<Tuple<DamageModifier, Function<? super Double, Double>>> originalFunctions =
            new ArrayList<>();

        final EnumCreatureAttribute creatureAttribute =
            targetEntity instanceof EntityLivingBase
                ? ((EntityLivingBase) targetEntity).getCreatureAttribute()
                : EnumCreatureAttribute.UNDEFINED;
        final List<Tuple<DamageModifier, Function<? super Double, Double>>>
            enchantmentModifierFunctions =
                DamageEventHandler.createAttackEnchamntmentFunction(
                    this.getHeldItem(), creatureAttribute);
        // if (targetEntity instanceof EntityLivingBase) {
        //     enchantmentModifierAmount =
        // EnchantmentHelper.getModifierForCreature(this.getHeldItem(), creatureAttribute);
        // } else {
        //     enchantmentModifierAmount =
        // EnchantmentHelper.getModifierForCreature(this.getHeldItem(),
        // EnumCreatureAttribute.UNDEFINED);
        // }
        enchantmentModifierAmount =
            (float)
                enchantmentModifierFunctions
                    .stream()
                    .map(Tuple::getSecond)
                    .mapToDouble(function -> function.apply(originalBaseDamage))
                    .sum();
        originalFunctions.addAll(enchantmentModifierFunctions);
        // Sponge End

        knockbackModifier =
            knockbackModifier
                + EnchantmentHelper.getKnockbackModifier((EntityPlayer) (Object) this);

        if (this.isSprinting()) {
          ++knockbackModifier;
        }

        if (baseDamage > 0.0F || enchantmentModifierAmount > 0.0F) {
          boolean fallingCriticalHit =
              this.fallDistance > 0.0F
                  && !this.onGround
                  && !this.isOnLadder()
                  && !this.isInWater()
                  && !this.isPotionActive(Potion.blindness)
                  && this.ridingEntity == null
                  && targetEntity instanceof EntityLivingBase;

          if (fallingCriticalHit && baseDamage > 0.0F) {
            // Sponge - Add the function for critical attacking
            originalFunctions.add(
                DamageEventHandler.provideCriticalAttackTuple((EntityPlayer) (Object) this));
            // baseDamage *= 1.5F; Sponge - remove since it's handled in the event
          }

          // baseDamage = baseDamage + enchantmentModifierAmount; // Sponge - remove since it is
          // delegated through the event.
          boolean targetLitOnFire = false;
          int fireAspectLevel =
              EnchantmentHelper.getFireAspectModifier((EntityPlayer) (Object) this);

          if (targetEntity instanceof EntityLivingBase
              && fireAspectLevel > 0
              && !targetEntity.isBurning()) {
            targetLitOnFire = true;
            targetEntity.setFire(1);
          }

          double targetMotionX = targetEntity.motionX;
          double targetMotionY = targetEntity.motionY;
          double targetMotionZ = targetEntity.motionZ;

          // Sponge Start - Create the event and throw it
          final DamageSource damageSource =
              DamageSource.causePlayerDamage((EntityPlayer) (Object) this);
          final AttackEntityEvent event =
              SpongeEventFactory.createAttackEntityEvent(
                  Cause.source(damageSource).build(),
                  originalFunctions,
                  EntityUtil.fromNative(targetEntity),
                  knockbackModifier,
                  originalBaseDamage);
          SpongeImpl.postEvent(event);
          if (event.isCancelled()) {
            if (targetLitOnFire) {
              targetEntity.extinguish();
            }
            return;
          }
          baseDamage = (float) event.getFinalOutputDamage();
          knockbackModifier = event.getKnockbackModifier();
          boolean attackSucceded =
              targetEntity.attackEntityFrom(damageSource, (float) event.getFinalOutputDamage());
          // Sponge End
          if (attackSucceded) {
            if (knockbackModifier > 0) {
              targetEntity.addVelocity(
                  (double)
                      (-MathHelper.sin(this.rotationYaw * (float) Math.PI / 180.0F)
                          * (float) knockbackModifier
                          * 0.5F),
                  0.1D,
                  (double)
                      (MathHelper.cos(this.rotationYaw * (float) Math.PI / 180.0F)
                          * (float) knockbackModifier
                          * 0.5F));
              this.motionX *= 0.6D;
              this.motionZ *= 0.6D;
              this.setSprinting(false);
            }

            if (targetEntity instanceof EntityPlayerMP && targetEntity.velocityChanged) {
              ((EntityPlayerMP) targetEntity)
                  .playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(targetEntity));
              targetEntity.velocityChanged = false;
              targetEntity.motionX = targetMotionX;
              targetEntity.motionY = targetMotionY;
              targetEntity.motionZ = targetMotionZ;
            }

            if (fallingCriticalHit) {
              this.onCriticalHit(targetEntity);
            }

            if (enchantmentModifierAmount > 0.0F) {
              this.onEnchantmentCritical(targetEntity);
            }

            if (baseDamage >= 18.0F) {
              this.triggerAchievement(AchievementList.overkill);
            }

            this.setLastAttacker(targetEntity);

            if (targetEntity instanceof EntityLivingBase) {
              EnchantmentHelper.applyThornEnchantments(
                  (EntityLivingBase) targetEntity, (EntityPlayer) (Object) this);
            }

            EnchantmentHelper.applyArthropodEnchantments(
                (EntityPlayer) (Object) this, targetEntity);
            ItemStack itemstack = this.getCurrentEquippedItem();
            net.minecraft.entity.Entity entity = targetEntity;

            if (targetEntity instanceof EntityDragonPart) {
              IEntityMultiPart ientitymultipart = ((EntityDragonPart) targetEntity).entityDragonObj;

              if (ientitymultipart instanceof EntityLivingBase) {
                entity = (EntityLivingBase) ientitymultipart;
              }
            }

            if (itemstack != null && entity instanceof EntityLivingBase) {
              itemstack.hitEntity((EntityLivingBase) entity, (EntityPlayer) (Object) this);

              if (itemstack.stackSize <= 0) {
                this.destroyCurrentEquippedItem();
              }
            }

            if (targetEntity instanceof EntityLivingBase) {
              this.addStat(StatList.damageDealtStat, Math.round(baseDamage * 10.0F));

              if (fireAspectLevel > 0) {
                targetEntity.setFire(fireAspectLevel * 4);
              }
            }

            this.addExhaustion(0.3F);
          } else if (targetLitOnFire) {
            targetEntity.extinguish();
          }
        }
      }
    }
  }
 public void postState(Class<? extends StateEvent> type) {
   this.game.getEventManager().post(SpongeEventFactory.createState(type, this.game));
 }