Advertisement
Guest User

FountainController

a guest
Jan 12th, 2014
490
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.16 KB | None | 0 0
  1. package com.bergerkiller.bukkit.fountains;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. import org.bukkit.Material;
  7. import org.bukkit.World;
  8. import org.bukkit.block.Block;
  9. import org.bukkit.block.Sign;
  10. import org.bukkit.plugin.java.JavaPlugin;
  11.  
  12. import com.bergerkiller.bukkit.common.MaterialTypeProperty;
  13. import com.bergerkiller.bukkit.common.Task;
  14. import com.bergerkiller.bukkit.common.conversion.Conversion;
  15. import com.bergerkiller.bukkit.common.reflection.SafeField;
  16. import com.bergerkiller.bukkit.common.reflection.classes.WorldRef;
  17. import com.bergerkiller.bukkit.common.utils.BlockUtil;
  18. import com.bergerkiller.bukkit.common.utils.MaterialUtil;
  19. import com.bergerkiller.bukkit.common.utils.ParseUtil;
  20.  
  21. public class FountainController extends Task {
  22.     private static final MaterialTypeProperty IS_FOUNTAIN_LINE = new MaterialTypeProperty(Material.WATER, Material.STATIONARY_WATER,
  23.             Material.LAVA, Material.STATIONARY_LAVA, Material.OBSIDIAN, Material.AIR);
  24.     private static List<FountainController> runningTasks = new ArrayList<FountainController>();
  25.     private FountainOptions options;
  26.     private int currentPos;
  27.     private Block baseBlock;
  28.  
  29.     private FountainController(JavaPlugin plugin, Block baseBlock, FountainOptions options) {
  30.         super(plugin);
  31.         this.options = options;
  32.         this.baseBlock = baseBlock;
  33.         this.currentPos = options.up ? 0 : (options.height - 1);
  34.     }
  35.  
  36.     @Override
  37.     public FountainController stop() {
  38.         super.stop();
  39.         runningTasks.remove(this);
  40.         return this;
  41.     }
  42.  
  43.     @Override
  44.     public void run() {
  45.         Block block = this.baseBlock.getRelative(0, this.currentPos, 0);
  46.         if (this.options.up) {
  47.             setBlock(block, this.options.fountainType);
  48.             this.currentPos++;
  49.         } else {
  50.             setBlock(block, Material.AIR);
  51.             this.currentPos--;
  52.         }
  53.         if (this.currentPos < 0 || this.currentPos >= this.options.height) {
  54.             if (!options.spread) {
  55.                 for (int i = 0; i < this.options.height; i++) {
  56.                     BlockUtil.applyPhysics(this.baseBlock.getRelative(0, i, 0), Material.AIR);
  57.                 }
  58.             }
  59.             this.stop();
  60.         }
  61.     }
  62.  
  63.     private void setBlock(Block block, Material type) {
  64.         if (options.spread) {
  65.             block.setType(type);
  66.         } else {
  67.             Object worldHandle = Conversion.toWorldHandle.convert(block.getWorld());
  68.             SafeField<Boolean> callingPlace = WorldRef.TEMPLATE.getField("callingPlaceEvent");
  69.             boolean old = callingPlace.get(worldHandle);
  70.             callingPlace.set(worldHandle, true);
  71.             block.setTypeIdAndData(type.getId(), (byte) 0x8, false);
  72.             callingPlace.set(worldHandle, old);
  73.         }
  74.     }
  75.  
  76.     public static void animate(JavaPlugin plugin, Block baseBlock, FountainOptions options) {
  77.         FountainController newController = new FountainController(plugin, baseBlock, options);
  78.         for (FountainController running : runningTasks.toArray(new FountainController[0])) {
  79.             if (running.baseBlock.equals(baseBlock)) {
  80.                 if (running.options.up == options.up) {
  81.                     // Already busy going up or down
  82.                     return;
  83.                 } else if (newController.options.height != options.height) {
  84.                     // Mismatch, abort
  85.                     running.stop();
  86.                 } else {
  87.                     // Stop the old task and continue from that position
  88.                     running.stop();
  89.                     newController.currentPos = running.currentPos;
  90.                 }
  91.             }
  92.         }
  93.         newController.start(0, options.interval);
  94.         runningTasks.add(newController);
  95.     }
  96.  
  97.     public static boolean isNonSpreadingFountain(Block waterBlock) {
  98.         FountainOptions opts = findFountain(waterBlock);
  99.         return opts != null && !opts.spread;
  100.     }
  101.  
  102.     public static FountainOptions findFountain(Block waterBlock) {
  103.         int bx = waterBlock.getX();
  104.         int bz = waterBlock.getZ();
  105.         World world = waterBlock.getWorld();
  106.         boolean end = false;
  107.         for (int by = waterBlock.getY(); by >= 0; by--) {
  108.             if (MaterialUtil.ISSIGN.get(world, bx, by, bz)) {
  109.                 return FountainOptions.fromSignBlock(world.getBlockAt(bx, by, bz));
  110.             } else if (!IS_FOUNTAIN_LINE.get(world, bx, by, bz)) {
  111.                 // End state is used to ignore the solid block separating sign and water
  112.                 if (end) {
  113.                     return null;
  114.                 } else {
  115.                     end = true;
  116.                 }
  117.             }
  118.         }
  119.         return null;
  120.     }
  121.    
  122.     public static class FountainOptions {
  123.         public boolean up = false;
  124.         public boolean spread = false;
  125.         public Material fountainType = Material.WATER;
  126.         public int interval = 3;
  127.         public int height = 20;
  128.  
  129.         public static FountainOptions fromSignBlock(Block block) {
  130.             if (MaterialUtil.ISSIGN.get(block)) {
  131.                 return fromSign(BlockUtil.getSign(block));
  132.             } else {
  133.                 return null;
  134.             }
  135.         }
  136.  
  137.         public static FountainOptions fromSign(Sign sign) {
  138.             if (sign == null) {
  139.                 return null;
  140.             }
  141.             String title = sign.getLine(0);
  142.             boolean water = title.equalsIgnoreCase("[fountain]") || title.equalsIgnoreCase("[waterfountain]");
  143.             boolean lava = title.equalsIgnoreCase("[lavafountain]");
  144.             if (!water && !lava) {
  145.                 return null;
  146.             }
  147.             FountainOptions opt = new FountainOptions();
  148.             opt.height = ParseUtil.parseInt(sign.getLine(1), opt.height);
  149.             opt.up = sign.getBlock().isBlockIndirectlyPowered();
  150.             opt.spread = ParseUtil.parseBool(sign.getLine(2), opt.spread);
  151.             opt.interval = ParseUtil.parseInt(sign.getLine(3), opt.interval);
  152.             opt.fountainType = lava ? Material.LAVA : Material.WATER;
  153.             return opt;
  154.         }
  155.     }
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement