Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.bergerkiller.bukkit.fountains;
- import java.util.ArrayList;
- import java.util.List;
- import org.bukkit.Material;
- import org.bukkit.World;
- import org.bukkit.block.Block;
- import org.bukkit.block.Sign;
- import org.bukkit.plugin.java.JavaPlugin;
- import com.bergerkiller.bukkit.common.MaterialTypeProperty;
- import com.bergerkiller.bukkit.common.Task;
- import com.bergerkiller.bukkit.common.conversion.Conversion;
- import com.bergerkiller.bukkit.common.reflection.SafeField;
- import com.bergerkiller.bukkit.common.reflection.classes.WorldRef;
- import com.bergerkiller.bukkit.common.utils.BlockUtil;
- import com.bergerkiller.bukkit.common.utils.MaterialUtil;
- import com.bergerkiller.bukkit.common.utils.ParseUtil;
- public class FountainController extends Task {
- private static final MaterialTypeProperty IS_FOUNTAIN_LINE = new MaterialTypeProperty(Material.WATER, Material.STATIONARY_WATER,
- Material.LAVA, Material.STATIONARY_LAVA, Material.OBSIDIAN, Material.AIR);
- private static List<FountainController> runningTasks = new ArrayList<FountainController>();
- private FountainOptions options;
- private int currentPos;
- private Block baseBlock;
- private FountainController(JavaPlugin plugin, Block baseBlock, FountainOptions options) {
- super(plugin);
- this.options = options;
- this.baseBlock = baseBlock;
- this.currentPos = options.up ? 0 : (options.height - 1);
- }
- @Override
- public FountainController stop() {
- super.stop();
- runningTasks.remove(this);
- return this;
- }
- @Override
- public void run() {
- Block block = this.baseBlock.getRelative(0, this.currentPos, 0);
- if (this.options.up) {
- setBlock(block, this.options.fountainType);
- this.currentPos++;
- } else {
- setBlock(block, Material.AIR);
- this.currentPos--;
- }
- if (this.currentPos < 0 || this.currentPos >= this.options.height) {
- if (!options.spread) {
- for (int i = 0; i < this.options.height; i++) {
- BlockUtil.applyPhysics(this.baseBlock.getRelative(0, i, 0), Material.AIR);
- }
- }
- this.stop();
- }
- }
- private void setBlock(Block block, Material type) {
- if (options.spread) {
- block.setType(type);
- } else {
- Object worldHandle = Conversion.toWorldHandle.convert(block.getWorld());
- SafeField<Boolean> callingPlace = WorldRef.TEMPLATE.getField("callingPlaceEvent");
- boolean old = callingPlace.get(worldHandle);
- callingPlace.set(worldHandle, true);
- block.setTypeIdAndData(type.getId(), (byte) 0x8, false);
- callingPlace.set(worldHandle, old);
- }
- }
- public static void animate(JavaPlugin plugin, Block baseBlock, FountainOptions options) {
- FountainController newController = new FountainController(plugin, baseBlock, options);
- for (FountainController running : runningTasks.toArray(new FountainController[0])) {
- if (running.baseBlock.equals(baseBlock)) {
- if (running.options.up == options.up) {
- // Already busy going up or down
- return;
- } else if (newController.options.height != options.height) {
- // Mismatch, abort
- running.stop();
- } else {
- // Stop the old task and continue from that position
- running.stop();
- newController.currentPos = running.currentPos;
- }
- }
- }
- newController.start(0, options.interval);
- runningTasks.add(newController);
- }
- public static boolean isNonSpreadingFountain(Block waterBlock) {
- FountainOptions opts = findFountain(waterBlock);
- return opts != null && !opts.spread;
- }
- public static FountainOptions findFountain(Block waterBlock) {
- int bx = waterBlock.getX();
- int bz = waterBlock.getZ();
- World world = waterBlock.getWorld();
- boolean end = false;
- for (int by = waterBlock.getY(); by >= 0; by--) {
- if (MaterialUtil.ISSIGN.get(world, bx, by, bz)) {
- return FountainOptions.fromSignBlock(world.getBlockAt(bx, by, bz));
- } else if (!IS_FOUNTAIN_LINE.get(world, bx, by, bz)) {
- // End state is used to ignore the solid block separating sign and water
- if (end) {
- return null;
- } else {
- end = true;
- }
- }
- }
- return null;
- }
- public static class FountainOptions {
- public boolean up = false;
- public boolean spread = false;
- public Material fountainType = Material.WATER;
- public int interval = 3;
- public int height = 20;
- public static FountainOptions fromSignBlock(Block block) {
- if (MaterialUtil.ISSIGN.get(block)) {
- return fromSign(BlockUtil.getSign(block));
- } else {
- return null;
- }
- }
- public static FountainOptions fromSign(Sign sign) {
- if (sign == null) {
- return null;
- }
- String title = sign.getLine(0);
- boolean water = title.equalsIgnoreCase("[fountain]") || title.equalsIgnoreCase("[waterfountain]");
- boolean lava = title.equalsIgnoreCase("[lavafountain]");
- if (!water && !lava) {
- return null;
- }
- FountainOptions opt = new FountainOptions();
- opt.height = ParseUtil.parseInt(sign.getLine(1), opt.height);
- opt.up = sign.getBlock().isBlockIndirectlyPowered();
- opt.spread = ParseUtil.parseBool(sign.getLine(2), opt.spread);
- opt.interval = ParseUtil.parseInt(sign.getLine(3), opt.interval);
- opt.fountainType = lava ? Material.LAVA : Material.WATER;
- return opt;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement