Package ch.njol.skript.events

Source Code of ch.njol.skript.events.EvtMoveOn

/*
*   This file is part of Skript.
*
*  Skript is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  Skript 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 General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with Skript.  If not, see <http://www.gnu.org/licenses/>.
*
*
* Copyright 2011-2014 Peter Güttinger
*
*/

package ch.njol.skript.events;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.plugin.EventExecutor;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.SkriptConfig;
import ch.njol.skript.SkriptEventHandler;
import ch.njol.skript.aliases.ItemData;
import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SelfRegisteringSkriptEvent;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.Trigger;
import ch.njol.skript.registrations.Classes;

/**
* @author Peter Güttinger
*/
@SuppressWarnings("deprecation")
public class EvtMoveOn extends SelfRegisteringSkriptEvent { // TODO on jump

//  private final static class BlockLocation {
//    final World world;
//    final int x, y, z;
//   
//    BlockLocation(final World world, final int x, final int y, final int z) {
//      this.world = world;
//      this.x = x;
//      this.y = y;
//      this.z = z;
//    }
//   
//    @Override
//    public boolean equals(final Object obj) {
//      if (obj == this)
//        return true;
//      if (!(obj instanceof BlockLocation))
//        return false;
//      final BlockLocation other = (BlockLocation) obj;
//      return world == other.world && x == other.x && y == other.y && z == other.z;
//    }
//   
//    @Override
//    public int hashCode() {
//      return world.hashCode() + 29 * (x + 17 * (y + 31 * z));
//    }
//  }
 
  static {
//    Skript.registerEvent(EvtMoveOn.class, PlayerMoveEvent.class, "(step|walk) on <.+>");
    Skript.registerEvent("Move On", EvtMoveOn.class, PlayerMoveEvent.class, "(step|walk)[ing] (on|over) %*itemtypes%")
        .description("Called when a player moves onto a certain type of block. Please note that using this event can cause lag if there are many players online.")
        .examples("on walking on dirt or grass", "on stepping on stone")
        .since("2.0");
  }
 
//  private final static HashMap<BlockLocation, List<Trigger>> blockTriggers = new HashMap<BlockLocation, List<Trigger>>();
  final static HashMap<Integer, List<Trigger>> itemTypeTriggers = new HashMap<Integer, List<Trigger>>();
  @SuppressWarnings("null")
  ItemType[] types = null;
//  private World world;
//  private int x, y, z;
 
  private static boolean registeredExecutor = false;
  private final static EventExecutor executor = new EventExecutor() {
    @SuppressWarnings("null")
    @Override
    public void execute(final @Nullable Listener l, final @Nullable Event event) throws EventException {
      if (event == null)
        return;
      final PlayerMoveEvent e = (PlayerMoveEvent) event;
      final Location from = e.getFrom(), to = e.getTo();
//      if (!blockTriggers.isEmpty()) {
//        final List<Trigger> ts = blockTriggers.get(new BlockLocation(to.getWorld(), to.getBlockX(), to.getBlockY(), to.getBlockZ()));
//        if (ts != null) {
//          for (final Trigger t : ts) {
//            SkriptEventHandler.logTriggerStart(t);
//            t.start(e);
//            SkriptEventHandler.logTriggerEnd(t);
//          }
//        }
//      }
      if (!itemTypeTriggers.isEmpty()) {
        final int id = getOnBlock(to);
        if (id == 0)
          return;
        final List<Trigger> ts = itemTypeTriggers.get(id);
        if (ts == null)
          return;
        final int y = getBlockY(to.getY(), id);
        if (to.getWorld().equals(from.getWorld()) && to.getBlockX() == from.getBlockX() && to.getBlockZ() == from.getBlockZ() && y == getBlockY(from.getY(), getOnBlock(from)) && getOnBlock(from) == id)
          return;
        SkriptEventHandler.logEventStart(e);
        final byte data = to.getWorld().getBlockAt(to.getBlockX(), y, to.getBlockZ()).getData();
        triggersLoop: for (final Trigger t : ts) {
          final EvtMoveOn se = (EvtMoveOn) t.getEvent();
          for (final ItemType i : se.types) {
            if (i.isOfType(id, data)) {
              SkriptEventHandler.logTriggerStart(t);
              t.execute(e);
              SkriptEventHandler.logTriggerEnd(t);
              continue triggersLoop;
            }
          }
        }
        SkriptEventHandler.logEventEnd();
      }
    }
  };
 
  final static int getOnBlock(final Location l) {
    int id = l.getWorld().getBlockTypeIdAt(l.getBlockX(), (int) Math.ceil(l.getY()) - 1, l.getBlockZ());
    if (id == 0 && Math.abs((l.getY() - l.getBlockY()) - 0.5) < Skript.EPSILON) { // fences
      id = l.getWorld().getBlockTypeIdAt(l.getBlockX(), l.getBlockY() - 1, l.getBlockZ());
      if (id != Material.FENCE.getId() && id != 107 && id != 113) // fence gate // nether fence
        return 0;
    }
    return id;
  }
 
  final static int getBlockY(final double y, final int id) {
    if ((id == Material.FENCE.getId() || id == 107 || id == 113) && Math.abs((y - Math.floor(y)) - 0.5) < Skript.EPSILON) // fence gate // nether fence
      return (int) Math.floor(y) - 1;
    return (int) Math.ceil(y) - 1;
  }
 
  @SuppressWarnings("null")
  public final static Block getBlock(final PlayerMoveEvent e) {
    return e.getTo().subtract(0, 0.5, 0).getBlock();
  }
 
  @Override
  public boolean init(final Literal<?>[] args, final int matchedPattern, final ParseResult parser) {
//    if (parser.regexes.get(0).group().equalsIgnoreCase("<block>")/* && isValidatingInput*/)
//      return true;
//    final Matcher m = Pattern.compile("<block:(.+)>").matcher(parser.regexes.get(0).group());
//    if (m.matches()) {
//      final Block b = (Block) Skript.deserialize("block", m.group(1));
//      if (b == null)
//        return false;
//      world = b.getWorld();
//      x = b.getX();
//      y = b.getY();
//      z = b.getZ();
//    } else {
    @SuppressWarnings("unchecked")
    final Literal<? extends ItemType> l = (Literal<? extends ItemType>) args[0];//SkriptParser.parseLiteral(parser.regexes.get(0).group(), ItemType.class, ParseContext.EVENT);
    if (l == null)
      return false;
    types = l.getAll();
    for (final ItemType t : types) {
      boolean hasBlock = false;
      for (final ItemData d : t) {
        if (d.getId() == -1) {
          Skript.error("Can't use an 'on walk' event with an alias that matches all blocks");
          return false;
        }
        if (d.getId() <= Skript.MAXBLOCKID && d.getId() != 0) // don't allow air
          hasBlock = true;
      }
      if (!hasBlock) {
        Skript.error(t + " is not a block and can thus not be walked on");
        return false;
      }
    }
//    }
    return true;
  }
 
  @Override
  public String toString(final @Nullable Event e, final boolean debug) {
    return "walk on " + Classes.toString(types, false);
//    return "walk on " + (types != null ? Skript.toString(types, false) : "<block:" + world.getName() + ":" + x + "," + y + "," + z + ">");
  }
 
  @Override
  public void register(final Trigger trigger) {
//    if (types == null) {
//      final BlockLocation l = new BlockLocation(world, x, y, z);
//      List<Trigger> ts = blockTriggers.get(l);
//      if (ts == null)
//        blockTriggers.put(l, ts = new ArrayList<Trigger>());
//      ts.add(trigger);
//    } else {
    for (final ItemType t : types) {
      for (final ItemData d : t) {
        if (d.getId() > Skript.MAXBLOCKID)
          continue;
        List<Trigger> ts = itemTypeTriggers.get(d.getId());
        if (ts == null)
          itemTypeTriggers.put(d.getId(), ts = new ArrayList<Trigger>());
        ts.add(trigger);
      }
    }
//    }
    if (!registeredExecutor) {
      Bukkit.getPluginManager().registerEvent(PlayerMoveEvent.class, new Listener() {}, SkriptConfig.defaultEventPriority.value(), executor, Skript.getInstance(), true);
      registeredExecutor = true;
    }
  }
 
  @Override
  public void unregister(final Trigger t) {
//    final Iterator<Entry<BlockLocation, List<Trigger>>> i = blockTriggers.entrySet().iterator();
//    while (i.hasNext()) {
//      final List<Trigger> ts = i.next().getValue();
//      ts.remove(t);
//      if (ts.isEmpty())
//        i.remove();
//    }
    final Iterator<Entry<Integer, List<Trigger>>> i2 = itemTypeTriggers.entrySet().iterator();
    while (i2.hasNext()) {
      final List<Trigger> ts = i2.next().getValue();
      ts.remove(t);
      if (ts.isEmpty())
        i2.remove();
    }
  }
 
  @Override
  public void unregisterAll() {
//    blockTriggers.clear();
    itemTypeTriggers.clear();
  }
 
}
TOP

Related Classes of ch.njol.skript.events.EvtMoveOn

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.