示例#1
0
  public static Location lookAt(Location loc, Location lookat) {

    loc = loc.clone();

    double dx = lookat.getX() - loc.getX();
    double dy = lookat.getY() - loc.getY();
    double dz = lookat.getZ() - loc.getZ();

    if (dx != 0) {
      if (dx < 0) {
        loc.setYaw((float) (1.5 * Math.PI));
      } else {
        loc.setYaw((float) (0.5 * Math.PI));
      }
      loc.setYaw(loc.getYaw() - (float) Math.atan(dz / dx));
    } else if (dz < 0) {
      loc.setYaw((float) Math.PI);
    }

    double dxz = Math.sqrt(Math.pow(dx, 2) + Math.pow(dz, 2));

    loc.setPitch((float) -Math.atan(dy / dxz));

    loc.setYaw(-loc.getYaw() * 180f / (float) Math.PI);
    loc.setPitch(loc.getPitch() * 180f / (float) Math.PI);

    return loc;
  }
示例#2
0
  @Override
  public CastResult cast(SpellContext context) {
    Player player = context.<Player>getPlayer();
    Block target = context.<Block>getTarget().get();
    BlockFace direction = getClickedFace(player);
    Block phased = null;

    switch (direction) {
      case NORTH:
        phased = target.getRelative(0, 0, -1);
        break;
      case SOUTH:
        phased = target.getRelative(0, 0, 1);
        break;
      case EAST:
        phased = target.getRelative(1, 0, 0);
        break;
      case WEST:
        phased = target.getRelative(-1, 0, 0);
        break;
      case UP:
        phased = target.getRelative(0, +3, 0);
        break;
      case DOWN:
        phased = target.getRelative(0, -2, 0);
        break;
      default:
        phased = target;
        break;
    }

    if (!BukkitTargetUtils.getTransparent().contains(phased.getType())) {
      player.sendMessage(ChatColor.RED + "You cannot phase through that block");
      return CastResult.FAILURE;
    } else if (BukkitTargetUtils.getTransparent()
        .contains(phased.getRelative(0, -1, 0).getType())) {
      Location loc = phased.getRelative(0, -1, 0).getLocation();
      loc.add(0.5, 0, 0.5);
      loc.setPitch(player.getLocation().getPitch());
      loc.setYaw(player.getLocation().getYaw());
      player.teleport(loc);
      return CastResult.SUCCESS;
    } else if (BukkitTargetUtils.getTransparent().contains(phased.getRelative(0, 1, 0).getType())) {
      Location loc = phased.getLocation();
      loc.add(0.5, 0, 0.5);
      loc.setPitch(player.getLocation().getPitch());
      loc.setYaw(player.getLocation().getYaw());
      player.teleport(loc);
      return CastResult.SUCCESS;
    } else {
      player.sendMessage(ChatColor.RED + "You cannot phase through that block");
      return CastResult.FAILURE;
    }
  }
示例#3
0
 @EventHandler(priority = EventPriority.HIGHEST)
 public void onPlayerMove(PlayerMoveEvent event) {
   if (region.contains(event.getTo().toVector()) && !region.contains(event.getFrom().toVector())) {
     if ((filter == null || filter.evaluate(event.getPlayer()).equals(FilterState.ALLOW))
         || (TeamUtils.getTeamByPlayer(event.getPlayer()) != null
             && TeamUtils.getTeamByPlayer(event.getPlayer()).isObserver())
         || !GameHandler.getGameHandler().getMatch().isRunning()) {
       if (destination != null) {
         event.getPlayer().teleport(destination.getRandomPoint().getLocation());
         if (sound)
           event
               .getPlayer()
               .playSound(event.getPlayer().getLocation(), Sound.ENDERMAN_TELEPORT, 0.2F, 1);
       } else {
         Location newLocation = event.getTo();
         if (xRelative) newLocation.setX(newLocation.getX() + location.getX());
         else newLocation.setX(location.getX());
         if (yRelative) newLocation.setY(newLocation.getY() + location.getY());
         else newLocation.setY(location.getY());
         if (zRelative) newLocation.setZ(newLocation.getZ() + location.getZ());
         else newLocation.setZ(location.getZ());
         if (yawRelative) newLocation.setYaw(newLocation.getYaw() + yaw);
         else newLocation.setYaw(yaw);
         if (pitchRelative) newLocation.setPitch(newLocation.getPitch() + pitch);
         else newLocation.setPitch(pitch);
         event.getPlayer().teleport(newLocation);
         if (sound)
           event
               .getPlayer()
               .playSound(event.getPlayer().getLocation(), Sound.ENDERMAN_TELEPORT, 0.2F, 1);
       }
     }
   }
   if (destination != null
       && destination.contains(event.getTo().toVector())
       && !destination.contains(event.getFrom().toVector())
       && this.bidirectional) {
     if (filter == null
         || filter.evaluate(event.getPlayer()).equals(FilterState.ALLOW)
         || (TeamUtils.getTeamByPlayer(event.getPlayer()) != null
             && TeamUtils.getTeamByPlayer(event.getPlayer()).isObserver())
         || !GameHandler.getGameHandler().getMatch().isRunning()) {
       event.getPlayer().teleport(region.getRandomPoint().getLocation());
       if (sound)
         event
             .getPlayer()
             .playSound(event.getPlayer().getLocation(), Sound.ENDERMAN_TELEPORT, 0.2F, 1);
     }
   }
 }
  @Override
  public SpellResult step(CastContext context) {
    if (entity == null) {
      return SpellResult.FAIL;
    }
    SpellResult result = super.step(context);
    Location target = actionContext.getTargetLocation();

    // TODO: locationOffset and velocityOffset should be made relative
    if (locationOffset != null) {
      target = target.clone().add(locationOffset);
    }
    if (doVelocity) {
      Vector velocity = this.velocity.clone().multiply(distanceTravelledThisTick);
      if (velocityOffset != null) {
        velocity = velocity.add(velocityOffset);
      }
      entity.setVelocity(velocity);
    }
    Location currentLocation = entity.getLocation();
    if (doTeleport) {
      if (!orient) {
        target.setYaw(currentLocation.getYaw());
        target.setPitch(currentLocation.getPitch());
      }
      entity.teleport(target);
    }
    return result;
  }
示例#5
0
 @Override
 public SpellResult perform(CastContext context) {
   Entity entity = context.getEntity();
   if (entity == null) {
     return SpellResult.ENTITY_REQUIRED;
   }
   Location targetLocation = context.getLocation();
   for (int i = 0; i < 2; i++) {
     if (!context.allowPassThrough(targetLocation.getBlock().getType()))
       return SpellResult.NO_TARGET;
     targetLocation.setY(targetLocation.getY() + 1);
   }
   Location location = context.findPlaceToStand(targetLocation, verticalSearchDistance, true);
   if (location == null && !safe) {
     location = context.getTargetLocation();
     location.setPitch(targetLocation.getPitch());
     location.setYaw(targetLocation.getYaw());
     verticalSearchDistance = 0;
   }
   if (location != null) {
     teleport(context, entity, location);
     return SpellResult.CAST;
   }
   return SpellResult.NO_TARGET;
 }
  @Override
  public void handle(Session session, SpoutPlayer player, PositionMessage message) {
    if (player == null) {
      return;
    }

    PlayerMoveEvent event =
        EventFactory.onPlayerMove(
            player,
            player.getLocation(),
            new Location(
                player.getWorld(),
                message.getX(),
                message.getY(),
                message.getZ(),
                player.getLocation().getYaw(),
                player.getLocation().getPitch()));

    if (event.isCancelled()) {
      return;
    }

    Location l = event.getTo();
    l.setYaw(player.getLocation().getYaw());
    l.setPitch(player.getLocation().getPitch());

    player.setRawLocation(l);
  }
示例#7
0
  public Location getExit(Location traveller) {
    Location loc = null;
    // Check if the gate has an exit block
    if (gate.getExit() != null) {
      Blox exit = getBlockAt(gate.getExit());
      int back = (isBackwards()) ? -1 : 1;
      loc =
          exit.modRelativeLoc(
              0D, 0D, 1D, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back);
    } else {
      Stargate.log.log(
          Level.WARNING,
          "[Stargate] Missing destination point in .gate file " + gate.getFilename());
    }
    if (loc != null) {

      if (getWorld().getBlockTypeIdAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())
          == Material.STEP.getId()) {
        loc.setY(loc.getY() + 0.5);
      }

      loc.setPitch(traveller.getPitch());
      return loc;
    }
    return traveller;
  }
    public ItemProjectile(Player caster, float power) {
      this.caster = caster;
      this.power = power;
      Location location = caster.getEyeLocation().add(0, yOffset, 0);
      location.setPitch(0f);
      if (vertSpeedUsed) {
        vel = caster.getLocation().getDirection().setY(0).multiply(speed).setY(vertSpeed);
      } else {
        vel = caster.getLocation().getDirection().multiply(speed);
      }
      entity = caster.getWorld().dropItem(location, item.clone());
      MagicSpells.getVolatileCodeHandler().setGravity(entity, projectileHasGravity);
      playSpellEffects(EffectPosition.PROJECTILE, entity);
      playTrackingLinePatterns(
          EffectPosition.DYNAMIC_CASTER_PROJECTILE_LINE,
          caster.getLocation(),
          entity.getLocation(),
          caster,
          entity);
      entity.teleport(location);
      entity.setPickupDelay(1000000);
      entity.setVelocity(vel);

      taskId = MagicSpells.scheduleRepeatingTask(this, 3, 3);
    }
示例#9
0
	@Override
	public void run(final CommandSender sender, final String commandLabel, final String[] args) throws Exception
	{
		if (args.length < 4)
		{
			throw new NotEnoughArgumentsException();
		}

		IUser user = ess.getUserMap().getUser(server.getPlayer(args[0]));
		final int x = Integer.parseInt(args[1]);
		final int y = Integer.parseInt(args[2]);
		final int z = Integer.parseInt(args[3]);
		final Location location = new Location(user.getPlayer().getWorld(), x, y, z);
		if (args.length > 4)
		{
			location.setYaw((Float.parseFloat(args[4]) + 180 + 360) % 360);
		}
		if (args.length > 5)
		{
			location.setPitch(Float.parseFloat(args[5]));
		}
		sender.sendMessage(_("teleporting"));
		user.sendMessage(_("teleporting"));
		user.getTeleport().teleport(location, null, TeleportCause.COMMAND);
	}
示例#10
0
	@Override
	public void run(final IUser user, final String commandLabel, final String[] args) throws Exception
	{
		if (args.length < 3)
		{
			throw new NotEnoughArgumentsException();
		}

		final int x = Integer.parseInt(args[0]);
		final int y = Integer.parseInt(args[1]);
		final int z = Integer.parseInt(args[2]);
		final Location location = new Location(user.getPlayer().getWorld(), x, y, z);
		if (args.length > 3)
		{
			location.setYaw((Float.parseFloat(args[3]) + 180 + 360) % 360);
		}
		if (args.length > 4)
		{
			location.setPitch(Float.parseFloat(args[4]));
		}
		final Trade charge = new Trade(commandName, ess);
		charge.isAffordableFor(user);
		user.sendMessage(_("teleporting"));
		user.getTeleport().teleport(location, charge, TeleportCause.COMMAND);
		throw new NoChargeException();
	}
示例#11
0
 public void CancelTarget(final Core.CoreType coreType) {
   if ((coreType == CoreNow) || (coreType == Core.CoreType.ANY)) {
     if (CoreNow == Core.CoreType.RANDOM_POSITION) {
       Stop_RM();
       Stop_RS();
       Stop_CG();
       final Location nowloc =
           new Location(Bukkit.getServer().getWorlds().get(0), 0.0, -20.0, 0.0);
       nowloc.setYaw(1.0f);
       nowloc.setPitch(1.0f);
       HerobrineAI.HerobrineNPC.moveTo(nowloc);
       CoreNow = Core.CoreType.ANY;
       HerobrineAI.getPluginCore().getPathManager().setPath(null);
     }
     if (AICore.isTarget) {
       if (CoreNow == Core.CoreType.ATTACK) {
         ((Attack) getCore(Core.CoreType.ATTACK)).StopHandler();
       }
       if (CoreNow == Core.CoreType.HAUNT) {
         ((Haunt) getCore(Core.CoreType.HAUNT)).StopHandler();
       }
       AICore._ticks = 0;
       AICore.isTarget = false;
       HerobrineAI.HerobrineHP = HerobrineAI.HerobrineMaxHP;
       AICore.log.info("[HerobrineAI] Target cancelled.");
       final Location nowloc =
           new Location(Bukkit.getServer().getWorlds().get(0), 0.0, -20.0, 0.0);
       nowloc.setYaw(1.0f);
       nowloc.setPitch(1.0f);
       HerobrineAI.HerobrineNPC.moveTo(nowloc);
       CoreNow = Core.CoreType.ANY;
       Bukkit.getServer()
           .getScheduler()
           .scheduleSyncDelayedTask(
               AICore.plugin,
               new Runnable() {
                 @Override
                 public void run() {
                   AICore.this.FindPlayer();
                 }
               },
               (6 / HerobrineAI.getPluginCore().getConfigDB().ShowRate)
                   * (HerobrineAI.getPluginCore().getConfigDB().ShowInterval * 1L));
     }
   }
 }
示例#12
0
  /**
   * Finds a teleport location for a spectator NEAR to another location
   *
   * <p>If possible, they will be placed 5 blocks away, facing towards the destination player.
   *
   * @param l the location they are to be teleported near to
   */
  public static Location getSpectatorTeleportLocation(Location l) {
    Location lp = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
    Location lxp = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
    Location lxn = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
    Location lzp = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
    Location lzn = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
    Location tpl = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
    boolean xp = true, xn = true, zp = true, zn = true;

    for (int i = 0; i < 5; i++) {
      if (xp) {
        lxp.setX(lxp.getX() + 1);
        if (!TeleportUtils.isSpaceForPlayer(lxp)) xp = false;
      }
      if (xn) {
        lxn.setX(lxn.getX() - 1);
        if (!TeleportUtils.isSpaceForPlayer(lxn)) xn = false;
      }
      if (zp) {
        lzp.setZ(lzp.getZ() + 1);
        if (!TeleportUtils.isSpaceForPlayer(lzp)) zp = false;
      }
      if (zn) {
        lzn.setZ(lzn.getZ() - 1);
        if (!TeleportUtils.isSpaceForPlayer(lzn)) zn = false;
      }
    }

    if (!xp) lxp.setX(lxp.getX() - 1);
    if (!xn) lxn.setX(lxn.getX() + 1);
    if (!zp) lzp.setZ(lzp.getZ() - 1);
    if (!zn) lzn.setZ(lzn.getZ() + 1);

    tpl.setYaw(90);
    tpl.setPitch(0);

    if (lxp.distanceSquared(lp) > tpl.distanceSquared(lp)) {
      tpl = lxp;
      tpl.setYaw(90);
    }
    if (lxn.distanceSquared(lp) > tpl.distanceSquared(lp)) {
      tpl = lxn;
      tpl.setYaw(270);
    }
    if (lzp.distanceSquared(lp) > tpl.distanceSquared(lp)) {
      tpl = lzp;
      tpl.setYaw(180);
    }
    if (lzn.distanceSquared(lp) > tpl.distanceSquared(lp)) {
      tpl = lzn;
      tpl.setYaw(0);
    }
    return tpl;
  }
示例#13
0
  public Location getLocation(Location loc) {
    if (loc != null) {
      loc.setWorld(getWorld());
      loc.setX(entity.posX);
      loc.setY(entity.posY);
      loc.setZ(entity.posZ);
      loc.setYaw(entity.rotationYaw);
      loc.setPitch(entity.rotationPitch);
    }

    return loc;
  }
示例#14
0
  public Location getLocation(Location loc) {
    if (loc != null) {
      loc.setWorld(getWorld());
      loc.setX(entity.locX);
      loc.setY(entity.locY);
      loc.setZ(entity.locZ);
      loc.setYaw(entity.yaw);
      loc.setPitch(entity.pitch);
    }

    return loc;
  }
示例#15
0
  /**
   * Gets the Location of the given world's new player spawn.
   *
   * @param world The world to get the new player spawn for.
   * @return The Location of the new player spawn.
   */
  public Location getNewPlayerSpawn(String world) {
    Location spawn = this.getServer().getWorld(world).getSpawnLocation();

    if (deathSpawnExists(world)) {
      spawn.setX(spawns.getDouble("new-player-spawn." + world + ".x", spawn.getX()));
      spawn.setY(spawns.getDouble("new-player-spawn." + world + ".y", spawn.getY()));
      spawn.setZ(spawns.getDouble("new-player-spawn." + world + ".z", spawn.getZ()));
      spawn.setYaw(Float.parseFloat(spawns.getString("new-player-spawn." + world + ".yaw")));
      spawn.setPitch(Float.parseFloat(spawns.getString("new-player-spawn." + world + ".pitch")));
    }

    return spawn;
  }
 private void freeze(LivingEntity entity, String name) {
   broadcast(entity.getLocation(), this.applyText, name);
   Location pLoc = entity.getLocation();
   Location pBlockLoc = pLoc.getBlock().getLocation();
   Location tpLoc =
       new Location(
           pLoc.getWorld(), pBlockLoc.getX() + 0.5D, pBlockLoc.getY(), pBlockLoc.getZ() + 0.5D);
   tpLoc.setYaw(pLoc.getYaw());
   tpLoc.setPitch(pLoc.getPitch());
   entity.teleport(tpLoc);
   this.loc = tpLoc;
   this.blocks = placeIceBlock(entity);
 }
示例#17
0
 public TeleportationTask(Player player) {
   this.player = player;
   cycleLeft = Main.getInstance().getConfig().getInt("variable.Cycle");
   location = player.getWorld().getSpawnLocation();
   location.setPitch(player.getLocation().getPitch());
   location.setYaw(player.getLocation().getYaw());
   if (Main.getInstance().getConfig().getBoolean("variable.EnableConfusionEffect")) {
     player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 1000000, 1));
   }
   TeleportationTask.noFallDamage.add(player.getName());
   runTaskTimer(
       Main.getInstance(), 0, Main.getInstance().getConfig().getInt("variable.TicksPerCycle"));
 }
示例#18
0
 /**
  * Simulates the gun being fired
  *
  * @param player Player that fired the gun
  */
 public void fire(final Player player) {
   loadedInClip--;
   SpoutGUI.getHudOf(player).updateHUD();
   lastFired = System.currentTimeMillis();
   if (!(player.isSneaking())) {
     player.setVelocity(player.getLocation().getDirection().multiply(-recoilBack));
     Location loc = player.getLocation();
     loc.setPitch(loc.getPitch() + -recoilVertical);
     loc.setYaw(loc.getYaw() + recoilHorizontal);
     player.teleport(loc);
   } else {
     player.setVelocity(player.getLocation().getDirection().multiply(-recoilBack / 2));
     Location loc = player.getLocation();
     loc.setPitch(loc.getPitch() + -recoilVertical / 2);
     loc.setYaw(loc.getYaw() + recoilHorizontal / 2);
     player.teleport(loc);
   }
   if (loadedInClip == 0) {
     if (autoReload) {
       reload(player);
     }
   }
 }
示例#19
0
	private void fixBlockGlitch(Player p, Block b) {
		Location bLoc = b.getLocation();
		Location pLoc = p.getLocation();

		if (shouldFix(pLoc, bLoc)) {
			if (!SimpleBlockData.isSolid(b.getTypeId()))
				return;

			bLoc.setY(bLoc.getY() + 1);
			bLoc.setX(pLoc.getX());
			bLoc.setZ(pLoc.getZ());
			bLoc.setPitch(pLoc.getPitch());
			bLoc.setYaw(pLoc.getYaw());

			p.teleport(bLoc);
		}
	}
示例#20
0
 protected Location getLocation(String json) throws Exception {
   JSONObject data = (JSONObject) new JSONParser().parse(json);
   // world
   World world = Bukkit.getWorld((String) data.get("world"));
   // x, y, z
   double x = Double.parseDouble((String) data.get("x"));
   double y = Double.parseDouble((String) data.get("y"));
   double z = Double.parseDouble((String) data.get("z"));
   // pitch, yaw
   float pitch = Float.parseFloat((String) data.get("pitch"));
   float yaw = Float.parseFloat((String) data.get("yaw"));
   // generate Location
   Location loc = new Location(world, x, y, z);
   loc.setPitch(pitch);
   loc.setYaw(yaw);
   return loc;
 }
示例#21
0
  @Override
  public SpellResult perform(CastContext context) {
    Block targetBlock = context.getTargetBlock();
    Entity currentEntity = current == null ? null : current.get();
    current = null;
    if (currentEntity != null) {
      currentEntity.remove();
    }

    targetBlock = targetBlock.getRelative(BlockFace.UP);

    Location spawnLocation = targetBlock.getLocation();
    Location sourceLocation = context.getLocation();
    spawnLocation.setPitch(sourceLocation.getPitch());
    spawnLocation.setYaw(sourceLocation.getYaw());

    MageController controller = context.getController();
    if (entityData == null) {
      String randomType = RandomUtils.weightedRandom(entityTypeProbability);
      try {
        entityData = controller.getMob(randomType);
        if (entityData == null) {
          entityData =
              new com.elmakers.mine.bukkit.entity.EntityData(
                  EntityType.valueOf(randomType.toUpperCase()));
        }
      } catch (Throwable ex) {
        entityData = null;
      }
    }
    if (entityData == null) {
      return SpellResult.FAIL;
    }

    if (force) {
      controller.setForceSpawn(true);
    }
    Entity spawnedEntity = null;
    try {
      spawnedEntity = entityData.spawn(context.getController(), spawnLocation, spawnReason);
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    if (force) {
      controller.setForceSpawn(false);
    }

    if (spawnedEntity == null) {
      return SpellResult.FAIL;
    }

    if (!loot) {
      spawnedEntity.setMetadata("nodrops", new FixedMetadataValue(controller.getPlugin(), true));
    }
    if (speed > 0) {
      Vector motion = direction;
      if (motion == null) {
        motion = context.getDirection();
      } else {
        motion = motion.clone();
      }

      if (dyOffset != 0) {
        motion.setY(motion.getY() + dyOffset);
      }
      motion.normalize();
      motion.multiply(speed);
      CompatibilityUtils.setEntityMotion(spawnedEntity, motion);
    }

    Collection<EffectPlayer> projectileEffects = context.getEffects("spawned");
    for (EffectPlayer effectPlayer : projectileEffects) {
      effectPlayer.start(spawnedEntity.getLocation(), spawnedEntity, null, null);
    }
    context.registerForUndo(spawnedEntity);

    if (track) {
      current = new WeakReference<Entity>(spawnedEntity);
    }
    if (setTarget) {
      context.setTargetEntity(spawnedEntity);
    }
    return SpellResult.CAST;
  }
示例#22
0
 void setRotY(float rotY) {
   bukkitLocation.setPitch(rotY);
 }
示例#23
0
  @Override
  public int process(int maxBlocks) {
    int processedBlocks = 0;
    if (state == SimulationState.SCANNING_COMMAND) {
      // Process the casting command block first, and only if specially configured to do so.
      if (includeCommands && castCommandBlock != null) {
        // We are going to rely on the block toggling to kick this back to life when the chunk
        // reloads, so for now just bail and hope the timing works out.
        if (!castCommandBlock.getChunk().isLoaded()) {
          finish();
          // TODO: Maybe Scatter-shot and register all 6 surrounding power blocks for reload toggle.
          // Can't really do it without the chunk being loaded though, so hrm.
          return processedBlocks;
        }

        // Check for death since activation (e.g. during delay period)
        if (castCommandBlock.getType() != Material.COMMAND) {
          die();
          finish();
          return processedBlocks;
        }

        // Check for power blocks
        for (BlockFace powerFace : POWER_FACES) {
          Block checkForPower = castCommandBlock.getRelative(powerFace);
          if (checkForPower.getType() == POWER_MATERIAL) {
            if (commandReload) {
              controller.unregisterAutomata(checkForPower);
            }
            powerSimMaterial.modify(checkForPower);
            commandPowered = true;
          }
        }

        if (!commandPowered) {
          die();
          finish();
          return processedBlocks;
        }

        // Make this a normal block so the sim will process it
        // this also serves to reset the command block for the next tick, if it lives.
        birthMaterial.modify(castCommandBlock);
      }

      processedBlocks++;
      state = SimulationState.SCANNING;
    }

    while (state == SimulationState.SCANNING && processedBlocks <= maxBlocks) {
      if (!simulateBlocks(x, y, z)) {
        return processedBlocks;
      }

      y++;
      if (y > yRadius) {
        y = 0;
        if (x < radius) {
          x++;
        } else {
          z--;
          if (z < 0) {
            r++;
            z = r;
            x = 0;
          }
        }
      }

      if (r > radius) {
        state = SimulationState.UPDATING;
      }
    }

    while (state == SimulationState.UPDATING && processedBlocks <= maxBlocks) {
      int deadIndex = updatingIndex;
      if (deadIndex >= 0 && deadIndex < deadBlocks.size()) {
        Block killBlock = deadBlocks.get(deadIndex);
        if (!killBlock.getChunk().isLoaded()) {
          killBlock.getChunk().load();
          return processedBlocks;
        }

        if (birthMaterial.is(killBlock)) {
          registerForUndo(killBlock);
          killBlock.setType(deathMaterial);
        } else {
          // If this block was destroyed while we were processing,
          // avoid spawning a random birth block.
          // This tries to make it so automata don't "cheat" when
          // getting destroyed. A bit hacky though, I'm not about
          // to re-simulate...
          if (bornBlocks.size() > 0) {
            bornBlocks.remove(bornBlocks.size() - 1);
          }
        }
        processedBlocks++;
      }

      int bornIndex = updatingIndex - deadBlocks.size();
      if (bornIndex >= 0 && bornIndex < bornBlocks.size()) {
        Block birthBlock = bornBlocks.get(bornIndex);
        if (!birthBlock.getChunk().isLoaded()) {
          birthBlock.getChunk().load();
          return processedBlocks;
        }
        registerForUndo(birthBlock);
        birthMaterial.modify(birthBlock);
      }

      updatingIndex++;
      if (updatingIndex >= deadBlocks.size() + bornBlocks.size()) {
        state = SimulationState.COMMAND_SEARCH;

        // Wait at least a tick before re-populating the command block.
        return maxBlocks;
      }
    }

    // Each of the following states will end in this tick, to give the
    // MC sim time to register power updates.
    if (state == SimulationState.COMMAND_SEARCH) {
      if (includeCommands && potentialCommandBlocks.size() > 0) {
        switch (targetMode) {
          case HUNT:
            Collections.sort(potentialCommandBlocks);
            break;
          case FLEE:
            Collections.sort(potentialCommandBlocks);
            break;
          default:
            Collections.shuffle(potentialCommandBlocks);
            break;
        }

        // Find a valid block for the command
        powerTargetBlock = null;
        commandTargetBlock = null;
        Block backupBlock = null;
        while (commandTargetBlock == null && potentialCommandBlocks.size() > 0) {
          Block block = potentialCommandBlocks.remove(0).getBlock();
          if (block != null && birthMaterial.is(block)) {
            // If we're powering the block, look for one with a powerable neighbor.
            if (!commandPowered) {
              commandTargetBlock = block;
            } else {
              backupBlock = block;
              BlockFace powerFace = findPowerLocation(block, powerSimMaterial);
              if (powerFace != null) {
                commandTargetBlock = block;
              }
            }
          }
        }

        // If we didn't find any powerable blocks, but we did find at least one valid sim block
        // just use that one.
        if (commandTargetBlock == null) commandTargetBlock = backupBlock;

        // Search for a power block
        if (commandTargetBlock != null) {
          // First try and replace a live cell
          BlockFace powerDirection = findPowerLocation(commandTargetBlock, powerSimMaterial);
          // Next try to replace a dead cell, which will affect the simulation outcome
          // but this is perhaps better than it dying?
          if (powerDirection == null) {
            if (DEBUG) {
              controller
                  .getLogger()
                  .info("Had to fall back to backup location, pattern may diverge");
            }
            powerDirection = findPowerLocation(commandTargetBlock, powerSimMaterialBackup);
          }
          // If it's *still* not valid, search for something breakable.
          if (powerDirection == null) {
            for (BlockFace face : POWER_FACES) {
              if (blockSpell.isDestructible(commandTargetBlock.getRelative(face))) {
                if (DEBUG) {
                  controller
                      .getLogger()
                      .info(
                          "Had to fall back to destructible location, pattern may diverge and may destroy blocks");
                }
                powerDirection = face;
                break;
              }
            }
          }

          if (powerDirection != null) {
            powerTargetBlock = commandTargetBlock.getRelative(powerDirection);
          }
        }
      }
      if (DEBUG) {
        if (commandTargetBlock != null) {
          controller
              .getLogger()
              .info(
                  "MOVED: "
                      + commandTargetBlock.getLocation().toVector().subtract(center.toVector()));
        }
      }
      state = SimulationState.COMMON_RESET_REDSTONE;
      return processedBlocks;
    }

    if (state == SimulationState.COMMON_RESET_REDSTONE) {
      if (includeCommands && commandTargetBlock != null) {
        DeprecatedUtils.setData(commandTargetBlock, (byte) 0);
      }
      if (includeCommands && powerTargetBlock != null) {
        DeprecatedUtils.setData(powerTargetBlock, (byte) 0);
      }
      state = SimulationState.COMMAND_UPDATE;
      return processedBlocks;
    }

    if (state == SimulationState.COMMAND_UPDATE) {
      if (includeCommands) {
        if (commandTargetBlock != null) {
          if (!commandTargetBlock.getChunk().isLoaded()) {
            commandTargetBlock.getChunk().load();
            return processedBlocks;
          }

          commandTargetBlock.setType(Material.COMMAND);
          BlockState commandData = commandTargetBlock.getState();
          if (castCommand != null && commandData != null && commandData instanceof CommandBlock) {
            CommandBlock copyCommand = (CommandBlock) commandData;
            copyCommand.setCommand(castCommand);
            copyCommand.setName(commandName);
            copyCommand.update();

            // Also move the mage
            Location newLocation = commandTargetBlock.getLocation();
            newLocation.setPitch(center.getPitch());
            newLocation.setYaw(center.getYaw());
            mage.setLocation(newLocation);
          } else {
            commandTargetBlock = null;
          }
        } else {
          die();
        }
      }
      powerDelayTicks = POWER_DELAY_TICKS;
      state = SimulationState.COMMAND_POWER;
      return processedBlocks;
    }

    if (state == SimulationState.COMMAND_POWER) {
      // Continue to power the command block
      if (commandPowered && powerTargetBlock != null && includeCommands) {
        // Wait a bit before powering for redstone signals to reset
        if (powerDelayTicks > 0) {
          powerDelayTicks--;
          return processedBlocks;
        }

        if (powerTargetBlock != null) {
          powerTargetBlock.setType(POWER_MATERIAL);
          if (commandReload) {
            String automataName = commandName;
            if (automataName == null || automataName.length() <= 1) {
              automataName = controller.getMessages().get("automata.default_name");
            }
            controller.registerAutomata(powerTargetBlock, automataName, "automata.awaken");
          }
        }
      }
      state = SimulationState.FINISHED;
      return processedBlocks;
    }

    if (state == SimulationState.FINISHED) {
      finish();
    }

    return processedBlocks;
  }
示例#24
0
 private boolean execTpThereCommand(final CommandSender sender, final String[] args) {
   if (args.length == 0) {
     if (!(sender instanceof Player)) {
       this.plugin.sendMessage(sender, MessageId.cmdOnlyAvailableForPlayers);
       return true;
     } else {
       final Player player = (Player) sender;
       final Block targetBlock = PlayerUtil.getTargetBlock(player, null, Integer.MAX_VALUE);
       if (targetBlock == null) {
         this.plugin.sendMessage(player, MessageId.general_tp_noTarget);
         return true;
       } else {
         final Location loc = targetBlock.getLocation();
         loc.add(0.5, 0.05, 0.5);
         while (loc.getBlock().getType().isSolid()
             || loc.getBlock().getRelative(BlockFace.UP).getType().isSolid()) {
           loc.add(0, 1, 0);
         }
         loc.setPitch(player.getLocation().getPitch());
         loc.setYaw(player.getLocation().getYaw());
         this.backMap.put(player.getName(), new NLocation(player.getLocation()));
         player.teleport(loc);
         this.plugin.sendMessage(
             player,
             MessageId.general_tp_youToLocation,
             "<" + loc.getX() + ';' + loc.getY() + ';' + loc.getZ() + '>');
         return true;
       }
     }
   } else if (args.length == 1) {
     if (!(sender instanceof Player)) {
       this.plugin.sendMessage(sender, MessageId.cmdOnlyAvailableForPlayers);
       return true;
     } else {
       final Player player = (Player) sender;
       final Block targetBlock = PlayerUtil.getTargetBlock(player, null, Integer.MAX_VALUE);
       if (targetBlock == null) {
         this.plugin.sendMessage(player, MessageId.general_tp_noTarget);
         return true;
       } else {
         final Location loc = targetBlock.getLocation();
         loc.add(0.5, 0.05, 0.5);
         while (loc.getBlock().getType().isSolid()
             || loc.getBlock().getRelative(BlockFace.UP).getType().isSolid()) {
           loc.add(0, 1, 0);
         }
         for (final String playerName : args[0].split(",")) {
           final Player toTeleport = Bukkit.getPlayer(playerName);
           if (toTeleport == null) {
             this.plugin.sendMessage(sender, MessageId.noPlayerFoundForGivenName, args[0]);
           } else {
             this.backMap.put(toTeleport.getName(), new NLocation(toTeleport.getLocation()));
             loc.setPitch(toTeleport.getLocation().getPitch());
             loc.setYaw(toTeleport.getLocation().getYaw());
             toTeleport.teleport(loc);
             this.plugin.sendMessage(
                 toTeleport, MessageId.general_tp_somebodyToLocation, sender.getName());
             this.plugin.sendMessage(
                 sender,
                 MessageId.general_tp_youSomebodyToLocation,
                 toTeleport.getName(),
                 "<" + loc.getX() + ';' + loc.getY() + ';' + loc.getZ() + '>');
           }
         }
         return true;
       }
     }
   } else {
     return false;
   }
 }
示例#25
0
  private boolean orientPlayer(Player player, String[] args, Iterator<Location> it) {
    final int bone;
    try {
      bone = Integer.parseInt(args[0], 10);
    } catch (NumberFormatException e) {
      return false;
    }

    if (bone == 0) {
      player.sendMessage("There is no bone 0.");
      return true;
    }

    int i = 0;
    Location loc = null;
    while (i < bone) {
      if (it.hasNext()) {
        loc = it.next();
        ++i;
      } else {
        player.sendMessage("I only know about " + i + " bone" + (i == 1 ? "" : "s") + " for you");
        return true;
      }
    }

    loc = loc.clone();

    final List<String> argsList = Arrays.asList(args);
    final boolean tracking;

    if (argsList.indexOf("compass") != -1) {
      if (plugin.checkPermission(player, "com.mouthpunch.bones.track")) {
        player.setCompassTarget(loc);
        player.sendMessage("Your compass will lead the way to your" + " bones.");
        tracking = true;
      } else {
        player.sendMessage("You don't have permission to track bones.");
        tracking = true;
      }
    } else {
      tracking = false;
    }

    if (!plugin.checkPermission(player, "com.mouthpunch.bones.orient")) {
      if (!tracking) {
        player.sendMessage("You don't have permission to orient" + " yourself towards bones.");
      }
      return true;
    }

    final Vector n = loc.subtract(player.getEyeLocation()).toVector().normalize();

    float pitch = (float) Math.toDegrees(Math.asin(n.getY()));
    pitch = -pitch;

    float yaw = (float) Math.toDegrees(Math.atan2(n.getZ(), n.getX()));
    yaw -= 90f;

    final Location playerLoc = player.getLocation();
    playerLoc.setPitch(pitch);
    playerLoc.setYaw(yaw);

    player.teleport(playerLoc);

    return true;
  }
示例#26
0
  @Override
  public void run() {
    for (Location l : Storage.blackholes.keySet()) {
      for (Entity e : Utilities.getNearbyEntities(l, 10, 10, 10)) {
        if (e instanceof Player) {
          if (((Player) e).getGameMode().equals(CREATIVE)) {
            continue;
          }
        }
        if (Storage.blackholes.get(l)) {
          Vector v = l.clone().subtract(e.getLocation()).toVector();
          v.setX(v.getX() + (-.5f + Storage.rnd.nextFloat()) * 10);
          v.setY(v.getY() + (-.5f + Storage.rnd.nextFloat()) * 10);
          v.setZ(v.getZ() + (-.5f + Storage.rnd.nextFloat()) * 10);
          e.setVelocity(v.multiply(.35f));
          e.setFallDistance(0);
        } else {
          Vector v = e.getLocation().subtract(l.clone()).toVector();
          v.setX(v.getX() + (-.5f + Storage.rnd.nextFloat()) * 2);
          v.setY(v.getY() + Storage.rnd.nextFloat());
          v.setZ(v.getZ() + (-.5f + Storage.rnd.nextFloat()) * 2);
          e.setVelocity(v.multiply(.35f));
        }
      }
    }
    // Arrows
    toRemove.clear();
    for (Set<CustomArrow> pro : Storage.advancedProjectiles.values()) {
      for (CustomArrow a : pro) {
        a.onFlight();
        a.tick++;
        if (a.entity.isDead() || a.tick > 600) {
          toRemove.add(a);
        }
      }
    }
    for (CustomArrow pro : toRemove) {
      Storage.advancedProjectiles.remove(pro.entity);
      pro.entity.remove();
    }
    for (Block block : Storage.webs) {
      if (Storage.rnd.nextInt(175) == 0 && block.getChunk().isLoaded()) {
        block.setType(AIR);
        websToRemove.add(block);
      }
    }
    for (Block block : websToRemove) {
      Storage.webs.remove(block);
    }
    websToRemove.clear();
    for (LivingEntity ent : Storage.derpingEntities) {
      Location loc = ent.getLocation();
      loc.setYaw(Storage.rnd.nextFloat() * 360F);
      loc.setPitch(Storage.rnd.nextFloat() * 180F - 90F);
      ent.teleport(loc);
    }
    tick++;
    // Other stuff
    for (FallingBlock b : Storage.anthMobs2) {
      if (!Storage.anthVortex.contains(Storage.anthMobs.get(b))) {
        for (Entity e : b.getNearbyEntities(7, 7, 7)) {
          if (e instanceof LivingEntity) {
            LivingEntity lE = (LivingEntity) e;
            if (!(lE instanceof Player) && lE instanceof Monster) {
              b.setVelocity(e.getLocation().subtract(b.getLocation()).toVector().multiply(.25));
              if (lE.getLocation().getWorld().equals(b.getLocation().getWorld())) {
                if (lE.getLocation().distance(b.getLocation()) < 1.2) {
                  EntityDamageEvent evt =
                      new EntityDamageEvent(lE, EntityDamageEvent.DamageCause.SUFFOCATION, 100);
                  Bukkit.getPluginManager().callEvent(evt);
                  lE.setLastDamageCause(evt);
                  if (!evt.isCancelled()) {
                    lE.damage(8f);
                  }
                }
              }
            }
          }
        }
      }
    }
    boolean r = Storage.fallBool;
    Storage.fallBool = !Storage.fallBool;
    for (FallingBlock b : Storage.anthMobs.keySet()) {
      if (Storage.anthVortex.contains(Storage.anthMobs.get(b))) {
        Location loc = Storage.anthMobs.get(b).getLocation();
        Vector v;
        if (b.getLocation().getWorld().equals(Storage.anthMobs.get(b).getLocation().getWorld())) {
          if (r && b.getLocation().distance(Storage.anthMobs.get(b).getLocation()) < 10) {
            v = b.getLocation().subtract(loc).toVector();
          } else {
            int x = Storage.rnd.nextInt(12) - 6;
            int z = Storage.rnd.nextInt(12) - 6;
            Location tLoc = loc.clone();
            tLoc.setX(tLoc.getX() + x);
            tLoc.setZ(tLoc.getZ() + z);
            v = tLoc.subtract(b.getLocation()).toVector();
          }
          v.multiply(.05);
          boolean close = false;
          for (int x = -3; x < 0; x++) {
            if (b.getLocation().getBlock().getRelative(0, x, 0).getType() != AIR) {
              close = true;
            }
          }
          if (close) {
            v.setY(5);
          } else {
            v.setY(-.1);
          }
          b.setVelocity(v);
        }
      }
    }

    for (Arrow e : Storage.tracer.keySet()) {
      Entity close = null;
      double distance = 100;
      int level = Storage.tracer.get(e);
      level = level + 2;
      for (Entity e1 : e.getNearbyEntities(level, level, level)) {
        if (e1.getLocation().getWorld().equals(e.getLocation().getWorld())) {
          double d = e1.getLocation().distance(e.getLocation());
          if (e.getLocation()
              .getWorld()
              .equals(((Entity) e.getShooter()).getLocation().getWorld())) {
            if (d < distance
                && e1 instanceof LivingEntity
                && !e1.equals(e.getShooter())
                && e.getLocation().distance(((Entity) e.getShooter()).getLocation()) > 15) {
              distance = d;
              close = e1;
            }
          }
        }
      }
      if (close != null) {
        Location location = close.getLocation();
        org.bukkit.util.Vector v = new org.bukkit.util.Vector(0D, 0D, 0D);
        Location pos = e.getLocation();
        double its =
            Math.sqrt(
                (location.getBlockX() - pos.getBlockX()) * (location.getBlockX() - pos.getBlockX())
                    + (location.getBlockY() - pos.getBlockY())
                        * (location.getBlockY() - pos.getBlockY())
                    + (location.getBlockZ() - pos.getBlockZ())
                        * (location.getBlockZ() - pos.getBlockZ()));
        if (its == 0) {
          its = (double) 1;
        }
        v.setX((location.getBlockX() - pos.getBlockX()) / its);
        v.setY((location.getBlockY() - pos.getBlockY()) / its);
        v.setZ((location.getBlockZ() - pos.getBlockZ()) / its);
        e.setVelocity(v.multiply(2));
      }
    }

    for (Guardian g : Storage.guardianMove.keySet()) {
      if (g.getLocation().distance(Storage.guardianMove.get(g).getLocation()) > 2
          && g.getTicksLived() < 160) {
        g.setVelocity(
            Storage.guardianMove
                .get(g)
                .getLocation()
                .toVector()
                .subtract(g.getLocation().toVector()));
      } else {
        Storage.guardianMove.remove(g);
      }
    }

    for (Player player : Bukkit.getOnlinePlayers()) {
      Config config = Config.get(player.getWorld());
      for (ItemStack stk : player.getInventory().getArmorContents()) {
        HashMap<CustomEnchantment, Integer> map = config.getEnchants(stk);
        for (CustomEnchantment ench : map.keySet()) {
          ench.onFastScan(player, map.get(ench));
        }
      }
      HashMap<CustomEnchantment, Integer> map = config.getEnchants(player.getItemInHand());
      for (CustomEnchantment ench : map.keySet()) {
        ench.onFastScanHand(player, map.get(ench));
      }
    }
    HashSet<Player> toDelete = new HashSet<>();
    for (Player player : Storage.hungerPlayers.keySet()) {
      if (Storage.hungerPlayers.get(player) < 1) {
        toDelete.add(player);
      } else {
        Storage.hungerPlayers.put(player, Storage.hungerPlayers.get(player) - 1);
      }
    }
    for (Player p : toDelete) {
      Storage.hungerPlayers.remove(p);
    }
    toDelete.clear();
    for (Player player : Storage.moverBlockDecay.keySet()) {
      Storage.moverBlockDecay.put(player, Storage.moverBlockDecay.get(player) + 1);
      if (Storage.moverBlockDecay.get(player) > 5) {
        Storage.moverBlocks.remove(player);
        toDelete.add(player);
      }
    }
    for (Player p : toDelete) {
      Storage.moverBlockDecay.remove(p);
    }
  }
示例#27
0
  private Location potentialViolation(
      final Player player,
      Location loc,
      final PlayerLocation from,
      final PlayerLocation to,
      final int manhattan,
      String tags,
      final MovingData data,
      final MovingConfig cc) {
    // Moving into a block, possibly a violation.

    // Check the players location if different from others.
    // (It provides a better set-back for some exploits.)
    final int lbX = loc.getBlockX();
    final int lbY = loc.getBlockY();
    final int lbZ = loc.getBlockZ();
    // First check if the player is moving from a passable location.
    // If not, the move might still be allowed, if moving inside of the same block, or from and to
    // have head position passable.
    if (from.isPassable()) {
      // Put one workaround for 1.5 high blocks here:
      if (from.isBlockAbove(to)
          && (BlockProperties.getBlockFlags(to.getTypeId()) & BlockProperties.F_HEIGHT150) != 0) {
        // Check if the move went from inside of the block.
        if (BlockProperties.collidesBlock(
            to.getBlockCache(),
            from.getX(),
            from.getY(),
            from.getZ(),
            from.getX(),
            from.getY(),
            from.getZ(),
            to.getBlockX(),
            to.getBlockY(),
            to.getBlockZ(),
            to.getTypeId())) {
          // Allow moving inside of 1.5 high blocks.
          return null;
        }
      }
      // From should be the set-back.
      loc = null;
      tags += "into";
    } else if (BlockProperties.isPassable(
        from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
      tags += "into_shift";
    }
    //				} else if (BlockProperties.isPassableExact(from.getBlockCache(), loc.getX(), loc.getY(),
    // loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
    // (Mind that this can be the case on the same block theoretically.)
    // Keep loc as set-back.
    //				}
    else if (!from.isSameBlock(lbX, lbY, lbZ)) {
      // Otherwise keep loc as set-back.
      tags += "cross_shift";
    } else if (manhattan == 1
        && to.isBlockAbove(from)
        && BlockProperties.isPassable(
            from.getBlockCache(),
            from.getX(),
            from.getY() + player.getEyeHeight(),
            from.getZ(),
            from.getTypeId(
                from.getBlockX(),
                Location.locToBlock(from.getY() + player.getEyeHeight()),
                from.getBlockZ()))) {
      //				else if (to.isBlockAbove(from) && BlockProperties.isPassableExact(from.getBlockCache(),
      // from.getX(), from.getY() + player.getEyeHeight(), from.getZ(),
      // from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()),
      // from.getBlockZ()))) {
      // Allow the move up if the head is free.
      return null;
    } else if (manhattan > 0) {
      // Otherwise keep from as set-back.
      loc = null;
      tags += "cross";
    } else {
      // All blocks are the same, allow the move.
      return null;
    }

    // Discard inconsistent locations.
    // TODO: Might get rid of using the in-between loc - needs use-case checking.
    if (loc != null
        && (TrigUtil.distance(from, to) > 0.75 || TrigUtil.distance(from, loc) > 0.125)) {
      loc = null;
    }

    // Prefer the set-back location from the data.
    if (data.hasSetBack()) {
      final Location ref = data.getSetBack(to);
      if (BlockProperties.isPassable(from.getBlockCache(), ref)
          || loc == null
          || TrigUtil.distance(from, loc) > 0.13) {
        //					if (BlockProperties.isPassableExact(from.getBlockCache(), ref)) {
        loc = ref;
        if (cc.debug) {
          System.out.println(player.getName() + " Using set-back location for passable.");
        }
      } else if (cc.debug) {
        System.out.println(player.getName() + " Ignoring set-back for passable.");
      }
    }

    // TODO: set data.set-back ? or something: still some aji here.

    // Return the reset position.
    data.passableVL += 1d;
    final ViolationData vd =
        new ViolationData(this, player, data.passableVL, 1, cc.passableActions);
    if (cc.debug || vd.needsParameters()) {
      vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId());
      if (!tags.isEmpty()) {
        vd.setParameter(ParameterName.TAGS, tags);
      }
    }
    if (executeActions(vd)) {
      // TODO: Consider another set back position for this, also keeping track of players moving
      // around in blocks.
      final Location newTo;
      if (loc != null) {
        // Ensure the given location is cloned.
        newTo = LocUtil.clone(loc);
      } else {
        newTo = from.getLocation();
        if (cc.debug) {
          System.out.println(player.getName() + " Using from location for passable.");
        }
      }
      newTo.setYaw(to.getYaw());
      newTo.setPitch(to.getPitch());
      return newTo;
    } else {
      // No cancel action set.
      return null;
    }
  }
示例#28
0
  private Location potentialViolation(
      final Player player,
      final Location loc,
      final PlayerLocation from,
      final PlayerLocation to,
      final int manhattan,
      String tags,
      final MovingData data,
      final MovingConfig cc) {
    // Moving into a block, possibly a violation.

    // Check the players location if different from others.
    // (It provides a better set-back for some exploits.)
    final int lbX = loc.getBlockX();
    final int lbY = loc.getBlockY();
    final int lbZ = loc.getBlockZ();
    Location setBackLoc = null; // Alternative to from.getLocation().
    // First check if the player is moving from a passable location.
    // If not, the move might still be allowed, if moving inside of the same block, or from and to
    // have head position passable.
    if (from.isPassable()) {
      // Put one workaround for 1.5 high blocks here:
      if (from.isBlockAbove(to)
          && (BlockProperties.getBlockFlags(to.getTypeId()) & BlockProperties.F_HEIGHT150) != 0) {
        // Check if the move went from inside of the block.
        if (BlockProperties.collidesBlock(
            to.getBlockCache(),
            from.getX(),
            from.getY(),
            from.getZ(),
            from.getX(),
            from.getY(),
            from.getZ(),
            to.getBlockX(),
            to.getBlockY(),
            to.getBlockZ(),
            to.getTypeId())) {
          // Allow moving inside of 1.5 high blocks.
          return null;
        }
      }
      // From should be the set-back.
      tags += "into";
    } else if (BlockProperties.isPassable(
        from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
      // Keep loc, because it it is passable.
      tags += "into_shift";
      setBackLoc = loc;
    }
    //				} else if (BlockProperties.isPassableExact(from.getBlockCache(), loc.getX(), loc.getY(),
    // loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
    // (Mind that this can be the case on the same block theoretically.)
    // Keep loc as set-back.
    //				}
    else if (!from.isSameBlock(lbX, lbY, lbZ)) {
      // Both loc and from are not passable. Use from as set.back (earliest).
      tags += "cross_shift";
    } else if (manhattan == 1
        && to.isBlockAbove(from)
        && BlockProperties.isPassable(
            from.getBlockCache(),
            from.getX(),
            from.getY() + player.getEyeHeight(),
            from.getZ(),
            from.getTypeId(
                from.getBlockX(),
                Location.locToBlock(from.getY() + player.getEyeHeight()),
                from.getBlockZ()))) {
      //				else if (to.isBlockAbove(from) && BlockProperties.isPassableExact(from.getBlockCache(),
      // from.getX(), from.getY() + player.getEyeHeight(), from.getZ(),
      // from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()),
      // from.getBlockZ()))) {
      // Allow the move up if the head is free.
      // TODO: Better distinguish ray-tracing (through something thin) or check to-head-passable
      // too?
      return null;
    } else if (manhattan > 0) {
      // Otherwise keep from as set-back.
      tags += "cross";
    } else {
      // All blocks are the same, allow the move.
      return null;
    }

    // Discard inconsistent locations.
    // TODO: Might get rid of using the in-between loc - needs use-case checking.
    if (setBackLoc != null
        && (TrigUtil.distance(from, to) > 0.75 || TrigUtil.distance(from, setBackLoc) > 0.125)) {
      setBackLoc = null;
    }

    // Prefer the set-back location from the data.
    if (data.hasSetBack()) {
      // TODO: Review or make configurable.
      final Location ref = data.getSetBack(to);
      if (BlockProperties.isPassable(from.getBlockCache(), ref)
          || setBackLoc == null
          || TrigUtil.distance(from, setBackLoc) > 0.13) {
        //					if (BlockProperties.isPassableExact(from.getBlockCache(), ref)) {
        setBackLoc = ref;
        if (data.debug) {
          NCPAPIProvider.getNoCheatPlusAPI()
              .getLogManager()
              .debug(
                  Streams.TRACE_FILE, player.getName() + " Using set-back location for passable.");
        }
      } else if (data.debug) {
        NCPAPIProvider.getNoCheatPlusAPI()
            .getLogManager()
            .debug(Streams.TRACE_FILE, player.getName() + " Ignoring set-back for passable.");
      }
    }

    // TODO: set data.set-back ? or something: still some aji here.

    // Return the reset position.
    data.passableVL += 1d;
    final ViolationData vd =
        new ViolationData(this, player, data.passableVL, 1, cc.passableActions);
    if (data.debug || vd.needsParameters()) {
      vd.setParameter(
          ParameterName.LOCATION_FROM,
          String.format(Locale.US, "%.2f, %.2f, %.2f", from.getX(), from.getY(), from.getZ()));
      vd.setParameter(
          ParameterName.LOCATION_TO,
          String.format(Locale.US, "%.2f, %.2f, %.2f", to.getX(), to.getY(), to.getZ()));
      vd.setParameter(
          ParameterName.DISTANCE, String.format(Locale.US, "%.2f", TrigUtil.distance(from, to)));
      // TODO: Consider adding from.getTypeId() too, if blocks differ and non-air.
      vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId());
      if (!tags.isEmpty()) {
        vd.setParameter(ParameterName.TAGS, tags);
      }
    }
    if (executeActions(vd)) {
      // TODO: Consider another set back position for this, also keeping track of players moving
      // around in blocks.
      final Location newTo;
      if (setBackLoc != null) {
        // Ensure the given location is cloned.
        newTo = LocUtil.clone(setBackLoc);
      } else {
        newTo = from.getLocation();
        if (data.debug) {
          NCPAPIProvider.getNoCheatPlusAPI()
              .getLogManager()
              .debug(Streams.TRACE_FILE, player.getName() + " Using from location for passable.");
        }
      }
      newTo.setYaw(to.getYaw());
      newTo.setPitch(to.getPitch());
      return newTo;
    } else {
      // No cancel action set.
      return null;
    }
  }
  @EventHandler(priority = EventPriority.HIGHEST)
  public void onBlockDispense(BlockDispenseEvent event) {
    Block block = event.getBlock();
    if (block.getType() == Material.DISPENSER) {

      Cannon cannon = plugin.getCannon(block, false);
      if (cannon == null) {
        return;
      }

      Material material = event.getItem().getType();

      Grenade grenade = plugin.getArmageddonConfig().getGrenade(material);

      if (grenade.getType() == Type.DUD || !grenade.isCannonUse()) {
        return;
      }

      Dispenser dispenser = (Dispenser) block.getType().getNewData(block.getData());

      double vx = cannon.getVelocity() * Math.cos((double) (Math.PI * cannon.getAngle() / 180));
      double y = cannon.getVelocity() * Math.sin((double) (Math.PI * cannon.getAngle() / 180));

      double x = 0;
      double z = 0;

      int yaw = 0;

      switch (dispenser.getFacing()) {
        case NORTH:
          x = -vx;
          yaw = 90;
          break;

        case SOUTH:
          x = vx;
          yaw = 270;
          break;

        case WEST:
          z = vx;
          yaw = 0;
          break;

        case EAST:
          z = -vx;
          yaw = 180;
          break;
      }

      Vector initialVelocity = new Vector(x, y, z);
      Location location = block.getRelative(dispenser.getFacing()).getLocation().add(0.5, 0.5, 0.5);
      World world = block.getWorld();

      Entity entity = null;

      x = location.getX();
      y = location.getY();
      z = location.getZ();

      Location locClone = location.clone();

      switch (grenade.getType()) {
        case PIG:
          entity = world.spawn(location, Pig.class);
          break;

        case COW:
          entity = world.spawn(location, Cow.class);
          break;

        case SHEEP:
          entity = world.spawn(location, Sheep.class);
          break;

        case TNT:
          entity = world.spawn(location, TNTPrimed.class);
          ((TNTPrimed) entity).setFuseTicks(cannon.getFuse());
          break;

        case EXPLOSIVE:
        case NUCLEAR:
        case WATER_BALLOON:
        case SPIDER_WEB:
        case SNARE:
        case STUN:
          entity = world.spawn(location, Snowball.class);
          break;

        case MOLOTOV:
          locClone.setPitch(0);
          locClone.setYaw(yaw);
          entity = world.spawn(locClone, Fireball.class);
          LivingEntity owner = plugin.getServer().getPlayer(cannon.getOwner());
          if (owner == null) {
            // get the closest living entity
            double distance = Double.MAX_VALUE;
            for (LivingEntity e : world.getLivingEntities()) {
              if (e.getLocation().distance(locClone) < distance) {
                distance = e.getLocation().distance(locClone);
                owner = e;
              }
            }
          }
          ((Fireball) entity).setShooter(owner);
          break;

        default:
          return;
      }

      if (entity != null) {
        if (!(entity instanceof Fireball)) {
          entity.setVelocity(initialVelocity);
        }

        if (!(entity instanceof LivingEntity)) {
          plugin.registerGrenade(entity, grenade);
        }

        plugin.adjustInventoryAndUsage(
            ((org.bukkit.block.Dispenser) block.getState()).getInventory(),
            cannon,
            material,
            grenade.getUses());

        event.setCancelled(true);
        world.createExplosion(location, 0);
      }
    }
  }