Package org.getspout.spout.listeners

Source Code of org.getspout.spout.listeners.SpoutBlockListener

/*
* This file is part of SpoutcraftPlugin.
*
* Copyright (c) 2011 SpoutcraftDev <http://spoutcraft.org//>
* SpoutcraftPlugin is licensed under the GNU Lesser General Public License.
*
* SpoutcraftPlugin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SpoutcraftPlugin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.getspout.spout.listeners;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.PistonMoveReaction;
import org.bukkit.craftbukkit.v1_6_R3.CraftWorld;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.getspout.spout.Spout;

import org.getspout.spout.block.SpoutCraftBlock;
import org.getspout.spout.inventory.SimpleMaterialManager;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.block.SpoutBlock;
import org.getspout.spoutapi.event.spout.ServerTickEvent;
import org.getspout.spoutapi.material.CustomBlock;
import org.getspout.spoutapi.player.SpoutPlayer;

public class SpoutBlockListener implements Listener {
  private final SimpleMaterialManager mm;

  /**
   * Used to prevent multiple piston events in the same tick.
   */
  private List<Location> pistonEventQueue = new ArrayList<Location>();

  public SpoutBlockListener(Spout plugin) {
    mm = (SimpleMaterialManager) SpoutManager.getMaterialManager();
    Bukkit.getPluginManager().registerEvents(this, plugin);
  }

  @EventHandler(priority = EventPriority.MONITOR)
  public void onBlockBreak(BlockBreakEvent event) {
    if (event.isCancelled()) {
      return;
    }

    SpoutBlock block = (SpoutBlock) event.getBlock();

    SpoutPlayer player = (SpoutPlayer) event.getPlayer();

    if (block.getCustomBlock() != null) {
      CustomBlock material = block.getCustomBlock();
      material.onBlockDestroyed(block.getWorld(), block.getX(), block.getY(), block.getZ(), player);
      if (material.getItemDrop() != null) {
        if (player.getGameMode() == GameMode.SURVIVAL) {
          block.getWorld().dropItem(block.getLocation(), material.getItemDrop());
        }
        block.setTypeId(0);
        event.setCancelled(true);
      }
      mm.removeBlockOverride(block);
    }
  }

  // This replaces nms functionality that is broken due to the references in the nms.Block.byId[] no longer matching the static final refernces in Block.
  // Specifically, public boolean a(int i, int j, int k, int l, boolean flag, int i1) in World.java is broken otherwise.
  @EventHandler(priority = EventPriority.LOWEST)
  public void onBlockCanBuild(BlockCanBuildEvent event) {
    if (event.isBuildable()) {
      return;
    }
    Block block = event.getBlock();
    Material type = block.getType();
    if (type == Material.WATER || type == Material.STATIONARY_WATER || type == Material.LAVA || type == Material.STATIONARY_LAVA || type == Material.FIRE || type == Material.SNOW || type == Material.DEAD_BUSH || type == Material.LONG_GRASS) {
      if (net.minecraft.server.v1_6_R3.Block.byId[event.getMaterialId()].canPlace(((CraftWorld) block.getWorld()).getHandle(), block.getX(), block.getY(), block.getZ())) {
        event.setBuildable(true);
      }
    }
  }

  @EventHandler(priority = EventPriority.MONITOR)
  public void onBlockPistonExtend(BlockPistonExtendEvent event) {
    if (event.isCancelled()) {
      return;
    }

    if (this.pistonEventQueue.contains(event.getBlock().getLocation())) {
      return;
    }
    pistonEventQueue.add(event.getBlock().getLocation());

    List eventBlocks = event.getBlocks();
    ListIterator itr = eventBlocks.listIterator(eventBlocks.size());
    while (itr.hasPrevious()) {
      SpoutBlock sb = (SpoutBlock) itr.previous();
      pistonBlockMove(sb, event.getDirection());
    }
  }

  @EventHandler(priority = EventPriority.MONITOR)
  public void onBlockPistonRetract(BlockPistonRetractEvent event) {
    if ((event.isCancelled()) || (!event.isSticky())) {
      return;
    }

    if (this.pistonEventQueue.contains(event.getBlock().getLocation())) {
      return;
    }
    pistonEventQueue.add(event.getBlock().getLocation());

    pistonBlockMove((SpoutBlock) event.getBlock().getRelative(event.getDirection(), 2), event.getDirection().getOppositeFace());
  }

  private void pistonBlockMove(SpoutBlock block, BlockFace blockFace) {
    if (block.getCustomBlock() == null) {
      return;
    }
    if (block.getPistonMoveReaction().equals(PistonMoveReaction.MOVE)) {
      int customBlockId = block.getCustomBlock().getCustomId();
      Byte customBlockData = block.getCustomBlockData();

      SpoutCraftBlock targetScb = (SpoutCraftBlock) block.getRelative(blockFace);

      // Only move the data, since the base block will be moved *After* this event fires. So if we also move the base block now, we are in fact, creating a new block.
      targetScb.setCustomBlockId(customBlockId);
      targetScb.setCustomBlockData(customBlockData);
      this.mm.queueBlockOverrides(targetScb, customBlockId, customBlockData);

      this.mm.removeBlockOverride(block);
    } else if (block.getPistonMoveReaction().equals(PistonMoveReaction.BREAK)) {
      breakOnPushed(block);
    }
  }

  public void breakOnPushed(SpoutBlock sb) {
    if (sb.getCustomBlock() == null || !sb.getPistonMoveReaction().equals(PistonMoveReaction.BREAK)) {
      return;
    }
    sb.getWorld().dropItemNaturally(sb.getLocation(), sb.getCustomBlock().getItemDrop());
    SpoutManager.getMaterialManager().removeBlockOverride(sb);
  }

  @EventHandler
  public void onTick(ServerTickEvent event) {
    pistonEventQueue.clear();
  }
}
TOP

Related Classes of org.getspout.spout.listeners.SpoutBlockListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.