@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));
    }
  }
  public static ChangeBlockEvent.Break callBlockBreakEvent(Event event) {
    if (!(event instanceof ChangeBlockEvent.Break)) {
      throw new IllegalArgumentException("Event is not a valid ChangeBlockEventBreak");
    }

    ChangeBlockEvent.Break spongeEvent = (ChangeBlockEvent.Break) event;

    if (spongeEvent.getCause().first(Player.class).isPresent()) {
      Player player = spongeEvent.getCause().first(Player.class).get();
      Iterator<Transaction<BlockSnapshot>> iterator = spongeEvent.getTransactions().iterator();
      while (iterator.hasNext()) {
        Transaction<BlockSnapshot> transaction = iterator.next();
        Location<World> location = transaction.getOriginal().getLocation().get();
        net.minecraft.world.World world = (net.minecraft.world.World) location.getExtent();
        BlockPos pos =
            new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());

        StaticMixinHelper.breakEventExtendedState =
            (IBlockState) transaction.getOriginal().getExtendedState();
        BlockEvent.BreakEvent forgeEvent =
            new BlockEvent.BreakEvent(
                world,
                pos,
                (IBlockState) transaction.getOriginal().getState(),
                (EntityPlayer) player);
        StaticMixinHelper.breakEventExtendedState = null;

        ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
        if (forgeEvent.isCanceled()) {
          transaction.setValid(false);
        }
      }
    }
    return spongeEvent;
  }
Ejemplo n.º 3
0
  @Listener
  public void onModifyBlock(ChangeBlockEvent event, @First Player player) {
    logger.info("Call: " + event.getClass());
    if (event
        .getCause()
        .get(NamedCause.NOTIFIER, Player.class)
        .map(p -> p.equals(player))
        .orElse(false)) {
      logger.info("Player cause is notifier.");
      return;
    }

    WorldFallbackContext worldContext = worldContexts.get(event.getTargetWorld().getUniqueId());

    boolean canModifyWild =
        Optional.ofNullable(worldContext)
            .flatMap(w -> w.getWilderness().getPublicPermission(MODIFY))
            .orElse(MODIFY.isAllowedByDefaultOnTheWild());

    Optional<Map<Vector3i, ClaimedChunk>> chunkMap = getChunkMap(event.getTargetWorld());

    claimedCheck:
    if (chunkMap.isPresent()) {
      Map<Vector3i, ClaimedChunk> subMap = chunkMap.get();
      Set<Vector3i> checkedChunks = new HashSet<>(2);

      for (Transaction<BlockSnapshot> transaction : event.getTransactions()) {
        Vector3i chunkPosition = blockToChunk(transaction.getOriginal().getPosition());
        if (checkedChunks.contains(chunkPosition)) continue;

        ClaimedChunk claimedChunk = subMap.get(chunkPosition);
        if (claimedChunk != null && !claimedChunk.check(MODIFY, player)) {
          logger.info("Chunk modification cancelled: " + chunkPosition + " " + event.getCause());
          event.setCancelled(true);
          return;
        } else if (!canModifyWild) break claimedCheck;

        checkedChunks.add(chunkPosition);
        logger.info("Chunk modification allowed: " + chunkPosition + " " + event);
      }

      return;
    }

    if (!canModifyWild) {
      if (worldContext != null) worldContext.getWilderness().notifyFailure(MODIFY, player);
      else MODIFY.notifyFailure(player, PlayerName.WILDERNESS);

      logger.info("Chunk modification cancelled because MODIFY is not allowed on unclaimed chunks");
      event.setCancelled(true);
    }
  }
  @Override
  public IBlockState getBlockState(BlockPos pos) {
    if (this.processed.containsKey(pos)) { // first just check if there's already a pos list built.
      return this.processed.get(pos);
    }
    Transaction<BlockSnapshot> unknown = this.transactions.get(this.index);
    if (unknown != null) {
      final BlockPos actualPos = this.poses.get(this.index);
      if (pos.equals(actualPos)) {
        return (IBlockState) unknown.getFinal().getState();
      }
    }

    return this.original.getBlockState(pos);
  }
  public static ChangeBlockEvent.Place callBlockPlaceEvent(Event event) {
    if (!(event instanceof ChangeBlockEvent.Place)) {
      throw new IllegalArgumentException("Event is not a valid ChangeBlockEventPlace");
    }

    ChangeBlockEvent.Place spongeEvent = (ChangeBlockEvent.Place) event;

    if (spongeEvent.getCause().first(Player.class).isPresent()) {
      EntityPlayer player = (EntityPlayer) spongeEvent.getCause().first(Player.class).get();
      net.minecraft.world.World world = (net.minecraft.world.World) spongeEvent.getTargetWorld();

      if (spongeEvent.getTransactions().size() == 1) {
        BlockPos pos =
            VecHelper.toBlockPos(spongeEvent.getTransactions().get(0).getOriginal().getPosition());
        IBlockState state =
            (IBlockState) spongeEvent.getTransactions().get(0).getOriginal().getState();
        net.minecraftforge.common.util.BlockSnapshot blockSnapshot =
            new net.minecraftforge.common.util.BlockSnapshot(world, pos, state);
        IBlockState placedAgainst = Blocks.air.getDefaultState();
        if (StaticMixinHelper.packetPlayer != null
            && StaticMixinHelper.processingPacket instanceof C08PacketPlayerBlockPlacement) {
          C08PacketPlayerBlockPlacement packet =
              (C08PacketPlayerBlockPlacement) StaticMixinHelper.processingPacket;
          EnumFacing facing = EnumFacing.getFront(packet.getPlacedBlockDirection());
          placedAgainst =
              blockSnapshot.world.getBlockState(blockSnapshot.pos.offset(facing.getOpposite()));
        }

        BlockEvent.PlaceEvent forgeEvent =
            new BlockEvent.PlaceEvent(blockSnapshot, placedAgainst, player);
        ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
        if (forgeEvent.isCanceled()) {
          spongeEvent.getTransactions().get(0).setValid(false);
        }
      } else { // multi
        Iterator<Transaction<BlockSnapshot>> iterator = spongeEvent.getTransactions().iterator();
        List<net.minecraftforge.common.util.BlockSnapshot> blockSnapshots = new ArrayList<>();

        while (iterator.hasNext()) {
          Transaction<BlockSnapshot> transaction = iterator.next();
          Location<World> location = transaction.getOriginal().getLocation().get();
          IBlockState state = (IBlockState) transaction.getOriginal().getState();
          BlockPos pos =
              new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
          net.minecraftforge.common.util.BlockSnapshot blockSnapshot =
              new net.minecraftforge.common.util.BlockSnapshot(world, pos, state);
          blockSnapshots.add(blockSnapshot);
        }

        IBlockState placedAgainst = Blocks.air.getDefaultState();
        if (StaticMixinHelper.packetPlayer != null
            && StaticMixinHelper.processingPacket instanceof C08PacketPlayerBlockPlacement) {
          C08PacketPlayerBlockPlacement packet =
              (C08PacketPlayerBlockPlacement) StaticMixinHelper.processingPacket;
          EnumFacing facing = EnumFacing.getFront(packet.getPlacedBlockDirection());
          placedAgainst =
              blockSnapshots
                  .get(0)
                  .world
                  .getBlockState(blockSnapshots.get(0).pos.offset(facing.getOpposite()));
        }

        BlockEvent.MultiPlaceEvent forgeEvent =
            new BlockEvent.MultiPlaceEvent(blockSnapshots, placedAgainst, player);
        ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(forgeEvent, true);
        if (forgeEvent.isCanceled()) {
          while (iterator.hasNext()) {
            iterator.next().setValid(false);
          }
        }
      }
    }
    return spongeEvent;
  }