Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-2606

Include affected blocks in EntitySpawnEvent

XMLWordPrintable

      Currently it's very difficult to determine which blocks caused entities like an iron golem, snowman and wither to spawn. I need to know that for a protection plugin to stop players from modifying blocks that they are not allowed by placing pumpkins or wither skulls in snow/soul sand/iron blocks adjacents to an unprotected terrain. It's difficult because they can be formed by many different ways (combinations of upside down, laid down, vertical arms) and some have rules that invalidate the structure (for example, iron golems can't have iron blocks in shoulders).

      It would be fairly simple for CraftBukkit to pass the affected blocks in an event because they are already collected in a BlockStateListPopulator before the EntitySpawnEvent is fired, so you could just add a field with an unmodified collection or create a new event like:

      /**
       * Fired when an entity formed by blocks is spawned into a world.
       * <p/>
       * If the event is cancelled the entity will not spawn and the blocks will not change.
       */
      public class EntitySpawnFromBlocksEvent extends EntitySpawnEvent
      {
          private final List<BlockState> states;
          public EntitySpawnFromBlocksEvent(Entity spawnee, Collection<BlockState> blocks)
          {
              super(spawnee);
              this.states = ImmutableList.copyOf(blocks);
          }
      
          /**
           * Gets a list of block states with the new state of all blocks that
           * would be changed after this entity spawns.
           * Most of these blocks will just have a Material type of AIR.
           *
           * @return immutable list of replaced BlockStates
           */
          public List<BlockState> getNewBlockStates() {
              return states;
          }
      
          /**
           * Gets the a new list of blocks that would be replaced
           *
           * @return a new mutable list of the blocks that would be replaced
           */
          public List<Block> getReplacedBlocks() {
              List<Block> list = new ArrayList<>(states.size());
              for(BlockState state: states) {
                  list.add(state.getBlock());
              }
      
              return list;
          }
      }
      

            Unassigned Unassigned
            joserobjr José Roberto de Araújo Júnior
            Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: