Package com.bergerkiller.bukkit.tc.signactions

Source Code of com.bergerkiller.bukkit.tc.signactions.SignActionDetector

package com.bergerkiller.bukkit.tc.signactions;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;

import com.bergerkiller.bukkit.tc.Permission;
import com.bergerkiller.bukkit.tc.TrainCarts;
import com.bergerkiller.bukkit.tc.Util;
import com.bergerkiller.bukkit.common.collections.BlockMap;
import com.bergerkiller.bukkit.common.config.DataReader;
import com.bergerkiller.bukkit.common.config.DataWriter;
import com.bergerkiller.bukkit.common.utils.CommonUtil;
import com.bergerkiller.bukkit.common.utils.FaceUtil;
import com.bergerkiller.bukkit.common.utils.StreamUtil;
import com.bergerkiller.bukkit.tc.signactions.detector.DetectorSignPair;
import com.bergerkiller.bukkit.tc.utils.TrackMap;
import com.bergerkiller.bukkit.tc.detector.DetectorRegion;
import com.bergerkiller.bukkit.tc.events.SignActionEvent;
import com.bergerkiller.bukkit.tc.events.SignChangeActionEvent;

public class SignActionDetector extends SignAction {
  private static BlockMap<DetectorSignPair> detectors = new BlockMap<DetectorSignPair>();

  public static void removeDetector(Block at) {
    DetectorSignPair dec = detectors.get(at);
    if (dec != null) {
      detectors.remove(at.getWorld(), dec.sign1.getLocation());
      detectors.remove(at.getWorld(), dec.sign2.getLocation());
      dec.region.remove();
    }
  }

  @Override
  public boolean match(SignActionEvent info) {
    return isValid(info);
  }

  @Override
  public void execute(SignActionEvent info) {
    //nothing happens here, relies on rail detector events
  }

  @Override
  public boolean build(SignChangeActionEvent event) {
    if (!isValid(event)) {
      return false;
    }
    if (handleBuild(event, Permission.BUILD_DETECTOR, "train detector", "detect trains between this detector sign and another")) {
      //try to create the other sign
      if (!event.hasRails()) {
        event.getPlayer().sendMessage(ChatColor.RED + "No rails are nearby: This detector sign has not been activated!");
        return true;
      }
      Block startsign = event.getBlock();
      Block startrails = event.getRails();
      BlockFace dir = event.getFacing();
      if (!tryBuild(startrails, startsign, dir)) {
        if (!tryBuild(startrails, startsign, FaceUtil.rotate(dir, 2))) {
          if (!tryBuild(startrails, startsign, FaceUtil.rotate(dir, -2))) {
            event.getPlayer().sendMessage(ChatColor.RED + "Failed to find a second detector sign: No region set.");
            event.getPlayer().sendMessage(ChatColor.YELLOW + "Place a second connected detector sign to finish this region!");
            return true;
          }
        }
      }
      event.getPlayer().sendMessage(ChatColor.GREEN + "A second detector sign was found: Region set.");
      return true;
    }
    return false;
  }

  @Override
  public void destroy(SignActionEvent info) {
    removeDetector(info.getBlock());
  }

  public boolean tryBuild(Block startrails, Block startsign, BlockFace direction) {
    final TrackMap map = new TrackMap(startrails, direction, TrainCarts.maxDetectorLength);
    map.next();
    //now try to find the end rails : find the other sign
    Block endsign = null;
    SignActionEvent info;
    while (map.hasNext()) {
      for (Block signblock : Util.getSignsFromRails(map.next())) {
        info = new SignActionEvent(signblock);
        if (match(info)) {
          endsign = signblock;
          //start and end found : add it
          final DetectorSignPair detector = new DetectorSignPair(startsign, endsign);
          detectors.put(startsign, detector);
          detectors.put(endsign, detector);
          CommonUtil.nextTick(new Runnable() {
            public void run() {
              DetectorRegion.create(map).register(detector);
            }
          });
          return true;
        }
      }
    }
    return false;
  }

  public static boolean isValid(SignActionEvent event) {
    return event != null && event.getMode() != SignActionMode.NONE && event.isType("detector");
  }

  public static void init(String filename) {
    detectors.clear();
    new DataReader(filename) {
      public void read(DataInputStream stream) throws IOException {
        for (int count = stream.readInt(); count > 0; --count) {
          //get required info
          UUID id = StreamUtil.readUUID(stream);
          //init a new detector
          DetectorSignPair det = DetectorSignPair.read(stream);
          //register
          det.region = DetectorRegion.getRegion(id);
          if (det.region == null) continue;
          det.region.register(det);
          detectors.put(det.region.getWorldName(), det.sign1.getLocation(), det);
          detectors.put(det.region.getWorldName(), det.sign2.getLocation(), det);
        }
      }
    }.read();
  }
  public static void save(String filename) {
    new DataWriter(filename) {
      public void write(DataOutputStream stream) throws IOException {
        Set<DetectorSignPair> detectorset = new HashSet<DetectorSignPair>(detectors.size() / 2);
        for (DetectorSignPair dec : detectors.values()) {
          detectorset.add(dec);
        }
        stream.writeInt(detectorset.size());
        for (DetectorSignPair det : detectorset) {
          StreamUtil.writeUUID(stream, det.region.getUniqueId());
          det.write(stream);
        }
      }
    }.write();
  }
}
TOP

Related Classes of com.bergerkiller.bukkit.tc.signactions.SignActionDetector

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.