From c446f320f506a2b0f28e2d4d49c086b04e218800 Mon Sep 17 00:00:00 2001 From: nathank33 Date: Fri, 5 Jun 2015 23:31:02 -0700 Subject: [PATCH] Improved Earth Dynamic Sourcing --- .../ProjectKorra/Utilities/BlockSource.java | 137 ++++++++++++------ 1 file changed, 94 insertions(+), 43 deletions(-) diff --git a/src/com/projectkorra/ProjectKorra/Utilities/BlockSource.java b/src/com/projectkorra/ProjectKorra/Utilities/BlockSource.java index 5f7d426e..f25220a8 100644 --- a/src/com/projectkorra/ProjectKorra/Utilities/BlockSource.java +++ b/src/com/projectkorra/ProjectKorra/Utilities/BlockSource.java @@ -2,6 +2,7 @@ package com.projectkorra.ProjectKorra.Utilities; import java.util.HashMap; +import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; @@ -12,21 +13,18 @@ import com.projectkorra.ProjectKorra.earthbending.EarthMethods; import com.projectkorra.ProjectKorra.waterbending.WaterMethods; /** - * BlockSource is a class that handles water and earth bending sources. - * When a Player left clicks or presses shift the update method is called - * which attempts to update the player's sources. + * BlockSource is a class that handles water and earth bending sources. When a Player left clicks or + * presses shift the update method is called which attempts to update the player's sources. * - * In this class ClickType refers to the way in which the source was selected. - * For example, Surge has two different ways to select a source, one involving shift and - * another involving left clicks. + * In this class ClickType refers to the way in which the source was selected. For example, Surge + * has two different ways to select a source, one involving shift and another involving left clicks. */ public class BlockSource { public static enum BlockSourceType { WATER, ICE, PLANT, EARTH, METAL, LAVA } - private static HashMap>> playerSources = - new HashMap>>(); + private static HashMap>> playerSources = new HashMap>>(); private static FileConfiguration config = ProjectKorra.plugin.getConfig(); // The player should never need to grab source blocks from farther than this. private static double MAX_RANGE = config.getDouble("Abilities.Water.WaterManipulation.Range"); @@ -61,14 +59,14 @@ public class BlockSource { putSource(player, earthBlock, BlockSourceType.METAL, clickType); } } - + // We need to handle lava differently, since getEarthSourceBlock doesn't account for // lava. We should only select the lava source if it is closer than the earth. Block lavaBlock = EarthMethods.getLavaSourceBlock(player, MAX_RANGE); - double earthDist = earthBlock != null ? - earthBlock.getLocation().distanceSquared(player.getLocation()) : Double.MAX_VALUE; - double lavaDist = lavaBlock != null ? - lavaBlock.getLocation().distanceSquared(player.getLocation()) : Double.MAX_VALUE; + double earthDist = earthBlock != null ? earthBlock.getLocation().distanceSquared(player.getLocation()) + : Double.MAX_VALUE; + double lavaDist = lavaBlock != null ? lavaBlock.getLocation().distanceSquared(player.getLocation()) + : Double.MAX_VALUE; if (lavaBlock != null && lavaDist <= earthDist) { putSource(player, null, BlockSourceType.EARTH, clickType); putSource(player, lavaBlock, BlockSourceType.LAVA, clickType); @@ -94,18 +92,17 @@ public class BlockSource { BlockSourceInformation info = new BlockSourceInformation(player, block, sourceType, clickType); playerSources.get(player).get(sourceType).put(clickType, info); } - + /** - * Access a block source information depending on a range and click type. + * Access a block source information depending on a source and click type. * * @param player the player that is trying to bend. - * @param range the maximum range to access the block. * @param clickType the action that was performed to access the source, either * ClickType.SHIFT_DOWN or ClickType.LEFT_CLICK. * @return a valid bendable block, or null if none was found. */ - public static BlockSourceInformation getBlockSourceInformation(Player player, double range, - BlockSourceType sourceType, ClickType clickType) { + public static BlockSourceInformation getBlockSourceInformation(Player player, BlockSourceType sourceType, + ClickType clickType) { if (!playerSources.containsKey(player)) { return null; } else if (!playerSources.get(player).containsKey(sourceType)) { @@ -113,21 +110,37 @@ public class BlockSource { } else if (!playerSources.get(player).get(sourceType).containsKey(clickType)) { return null; } - BlockSourceInformation blockInfo = playerSources.get(player).get(sourceType).get(clickType); - return isStillAValidSource(blockInfo, range, clickType) ? blockInfo : null; + return playerSources.get(player).get(sourceType).get(clickType); } + /** + * Access a block source information depending on a range, source, and click type. + * + * @param player the player that is trying to bend. + * @param range the maximum range to access the block. + * @param sourceType the elemental type of block to find. + * @param clickType the action that was performed to access the source, either + * ClickType.SHIFT_DOWN or ClickType.LEFT_CLICK. + * @return a valid bendable block, or null if none was found. + */ + public static BlockSourceInformation getValidBlockSourceInformation(Player player, double range, BlockSourceType sourceType, + ClickType clickType) { + BlockSourceInformation blockInfo = getBlockSourceInformation(player, sourceType, clickType); + return isStillAValidSource(blockInfo, range, clickType) ? blockInfo : null; + } + /** * Access a specific type of source block depending on a range and click type. * * @param player the player that is trying to bend. * @param range the maximum range to access the block. + * @param sourceType the elemental type of block to find. * @param clickType the action that was performed to access the source, either * ClickType.SHIFT_DOWN or ClickType.LEFT_CLICK. * @return a valid bendable block, or null if none was found. */ public static Block getSourceBlock(Player player, double range, BlockSourceType sourceType, ClickType clickType) { - BlockSourceInformation info = getBlockSourceInformation(player, range, sourceType, clickType); + BlockSourceInformation info = getValidBlockSourceInformation(player, range, sourceType, clickType); return info != null ? info.getBlock() : null; } @@ -189,7 +202,7 @@ public class BlockSource { boolean allowIce, boolean allowPlant) { return getWaterSourceBlock(player, range, clickType, allowWater, allowIce, allowPlant, true); } - + /** * Attempts to access a Water bendable block that was recently shifted or clicked on by the * player. @@ -201,15 +214,16 @@ public class BlockSource { * @param allowWater true if water blocks are allowed. * @param allowIce true if ice blocks are allowed. * @param allowPlant true if plant blocks are allowed. - * @param allowWaterBottles true if we should look for a close water block, that may have - * been created by a WaterBottle. + * @param allowWaterBottles true if we should look for a close water block, that may have been + * created by a WaterBottle. * @return a valid Water bendable block, or null if none was found. */ public static Block getWaterSourceBlock(Player player, double range, ClickType clickType, boolean allowWater, boolean allowIce, boolean allowPlant, boolean allowWaterBottles) { Block sourceBlock = null; if (allowWaterBottles) { - // Check the block in front of the player's eyes, it may have been created by a WaterBottle. + // Check the block in front of the player's eyes, it may have been created by a + // WaterBottle. sourceBlock = WaterMethods.getWaterSourceBlock(player, range, allowPlant); if (sourceBlock == null || sourceBlock.getLocation().distance(player.getEyeLocation()) > 3) { sourceBlock = null; @@ -226,7 +240,7 @@ public class BlockSource { } return sourceBlock; } - + /** * Attempts to access a Earth bendable block that was recently shifted or clicked on by the * player. @@ -238,9 +252,47 @@ public class BlockSource { * @return a valid Earth bendable block, or null if none was found. */ public static Block getEarthSourceBlock(Player player, double range, ClickType clickType) { - return getSourceBlock(player, range, BlockSourceType.EARTH, clickType); + return getEarthSourceBlock(player, range, clickType, true); } - + + /** + * Attempts to access a Earth bendable block that was recently shifted or clicked on by the + * player. + * + * @param player the player that is trying to bend. + * @param range the maximum range to access the block. + * @param clickType the action that was performed to access the source, either + * ClickType.SHIFT_DOWN or ClickType.LEFT_CLICK. + * @param allowNearbySubstitute if a valid earth source could not be found then this method will + * attempt to find a nearby valid earth block. + * @return a valid Earth bendable block, or null if none was found. + */ + public static Block getEarthSourceBlock(Player player, double range, ClickType clickType, + boolean allowNearbySubstitute) { + Block sourceBlock = getSourceBlock(player, range, BlockSourceType.EARTH, clickType); + if (sourceBlock == null && allowNearbySubstitute) { + BlockSourceInformation blockInfo = getBlockSourceInformation(player, + BlockSourceType.EARTH, clickType); + + if (blockInfo == null) { + return null; + } + Block tempBlock = blockInfo.getBlock(); + if (tempBlock == null) { + return null; + } + + Location loc = tempBlock.getLocation(); + sourceBlock = EarthMethods.getNearbyEarthBlock(loc, 3, 3); + if (sourceBlock == null + || Math.abs(sourceBlock.getLocation().distance(player.getEyeLocation())) > range + || !EarthMethods.isEarthbendable(player, sourceBlock)) { + return null; + } + } + return sourceBlock; + } + /** * Attempts to access a Lava bendable block that was recently shifted or clicked on by the * player. @@ -254,10 +306,10 @@ public class BlockSource { public static Block getLavaSourceBlock(Player player, double range, ClickType clickType) { return getSourceBlock(player, range, BlockSourceType.LAVA, clickType); } - + /** - * Attempts to access a Lava bendable block or an Earth block that was recently shifted or clicked on by the - * player. + * Attempts to access a Lava bendable block or an Earth block that was recently shifted or + * clicked on by the player. * * @param player the player that is trying to bend. * @param range the maximum range to access the block. @@ -266,21 +318,20 @@ public class BlockSource { * @return a valid Earth or Lava bendable block, or null if none was found. */ public static Block getEarthOrLavaSourceBlock(Player player, double range, ClickType clickType) { - BlockSourceInformation earthBlockInfo = getBlockSourceInformation(player, range, BlockSourceType.EARTH, clickType); - BlockSourceInformation lavaBlockInfo = getBlockSourceInformation(player, range, BlockSourceType.LAVA, clickType); - if (earthBlockInfo == null && lavaBlockInfo == null) { - return null; - } else if (earthBlockInfo == null && lavaBlockInfo != null) { - return lavaBlockInfo.getBlock(); - } else if (earthBlockInfo != null && lavaBlockInfo == null) { - return earthBlockInfo.getBlock(); - } else if (earthBlockInfo.getCreationTime() <= lavaBlockInfo.getCreationTime()) { - return earthBlockInfo.getBlock(); - } else { + /* + * When Lava is selected as a source it automatically overrides the previous Earth based source. + * Only one of these types can exist, so if Lava exists then we know Earth is null. + */ + Block earthBlock = getEarthSourceBlock(player, range, clickType); + BlockSourceInformation lavaBlockInfo = getValidBlockSourceInformation(player, range, BlockSourceType.LAVA, clickType); + if (earthBlock != null) { + return earthBlock; + } else if (lavaBlockInfo != null) { return lavaBlockInfo.getBlock(); } + return null; } - + /** * Determines if a BlockSourceInformation is valid, depending on the players range from the * source, and if the source has not been modified since the time that it was first created.