From 524d2c6403246e7da96383376b1a4cc2cb6d66da Mon Sep 17 00:00:00 2001 From: Archy-X Date: Mon, 11 Sep 2023 02:12:34 -0400 Subject: [PATCH] Fix farming and change boss bar --- .../aurelium/auraskills/api/skill/Skills.java | 2 +- .../api/source/type/BlockXpSource.java | 2 + .../bukkit/region/RegionBlockListener.java | 4 +- .../bukkit/source/BlockLeveler.java | 19 ++- .../bukkit/source/BlockLevelerHelper.java | 98 +++++++++++ .../auraskills/bukkit/ui/BossBarManager.java | 153 +++++++++--------- .../bukkit/ui/BukkitUiProvider.java | 1 + bukkit/src/main/resources/config.yml | 32 ++-- .../main/resources/messages/messages_en.yml | 4 +- .../serializer/BlockSourceSerializer.java | 2 +- .../common/source/type/BlockSource.java | 5 + common/src/main/resources/sources/farming.yml | 14 ++ 12 files changed, 235 insertions(+), 101 deletions(-) create mode 100644 bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLevelerHelper.java diff --git a/api/src/main/java/dev/aurelium/auraskills/api/skill/Skills.java b/api/src/main/java/dev/aurelium/auraskills/api/skill/Skills.java index 7c5b89a76..7c7be4eed 100644 --- a/api/src/main/java/dev/aurelium/auraskills/api/skill/Skills.java +++ b/api/src/main/java/dev/aurelium/auraskills/api/skill/Skills.java @@ -65,7 +65,7 @@ public boolean isEnabled() { @Override public Ability getXpMultiplierAbility() { - return xpMultiplierAbility; + return xpMultiplierAbility.isEnabled() ? xpMultiplierAbility : null; } @Override diff --git a/api/src/main/java/dev/aurelium/auraskills/api/source/type/BlockXpSource.java b/api/src/main/java/dev/aurelium/auraskills/api/source/type/BlockXpSource.java index 3171c52b0..ff22254e1 100644 --- a/api/src/main/java/dev/aurelium/auraskills/api/source/type/BlockXpSource.java +++ b/api/src/main/java/dev/aurelium/auraskills/api/source/type/BlockXpSource.java @@ -54,6 +54,8 @@ public interface BlockXpSource extends XpSource { */ double getStateMultiplier(String stateKey, Object stateValue); + boolean hasStateMultiplier(); + /** * Gets whether the source requires a support block. * If this is true, the source will only give xp if the block below it is a valid support block. diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java index ccb75c016..a548b9990 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java @@ -158,7 +158,7 @@ private void checkSupportBelow(Block block) { @Override public void run() { // Remove if block was destroyed - if (!blockLeveler.matchesSource(block, source, BlockXpSource.BlockTriggers.BREAK)) { + if (blockLeveler.isDifferentSource(block, source, BlockXpSource.BlockTriggers.BREAK)) { regionManager.removePlacedBlock(above); } } @@ -177,7 +177,7 @@ private void checkSupportSide(Block block) { @Override public void run() { // Remove if block was destroyed - if (!blockLeveler.matchesSource(block, source, BlockXpSource.BlockTriggers.BREAK)) { + if (blockLeveler.isDifferentSource(block, source, BlockXpSource.BlockTriggers.BREAK)) { regionManager.removePlacedBlock(block); } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java index 0ac1b8d79..1e140daff 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java @@ -24,8 +24,11 @@ public class BlockLeveler extends SourceLeveler { + private final BlockLevelerHelper helper; + public BlockLeveler(AuraSkills plugin) { super(plugin, SourceType.BLOCK); + this.helper = new BlockLevelerHelper(plugin); } @EventHandler @@ -50,7 +53,10 @@ public void onBreak(BlockBreakEvent event) { if (failsChecks(event, player, event.getBlock().getLocation(), skill)) return; - plugin.getLevelManager().addXp(user, skill, source.getXp()); + double multiplier = helper.getBlocksBroken(event.getBlock(), source); + multiplier *= helper.getStateMultiplier(event.getBlock(), source); + + plugin.getLevelManager().addXp(user, skill, source.getXp() * multiplier); } @EventHandler @@ -72,7 +78,10 @@ public void onInteract(PlayerInteractEvent event) { if (failsChecks(event, player, block.getLocation(), skill)) return; - plugin.getLevelManager().addXp(user, skill, source.getXp()); + double multiplier = helper.getBlocksBroken(block, source); + multiplier *= helper.getStateMultiplier(block, source); + + plugin.getLevelManager().addXp(user, skill, source.getXp() * multiplier); applyAbilities(skill, player, user, block, source); } @@ -96,12 +105,12 @@ private void applyAbilities(Skill skill, Player player, User user, Block block, } } - public boolean matchesSource(Block block, BlockXpSource source, BlockXpSource.BlockTriggers trigger) { + public boolean isDifferentSource(Block block, BlockXpSource source, BlockXpSource.BlockTriggers trigger) { var sourcePair = getSource(block, trigger); if (sourcePair == null) { - return false; + return true; } - return sourcePair.first().equals(source); + return !sourcePair.first().equals(source); } @Nullable diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLevelerHelper.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLevelerHelper.java new file mode 100644 index 000000000..264ab2424 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLevelerHelper.java @@ -0,0 +1,98 @@ +package dev.aurelium.auraskills.bukkit.source; + +import dev.aurelium.auraskills.api.source.type.BlockXpSource; +import dev.aurelium.auraskills.bukkit.AuraSkills; +import dev.aurelium.auraskills.common.config.Option; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.Ageable; +import org.bukkit.block.data.type.SeaPickle; + +public class BlockLevelerHelper { + + private final AuraSkills plugin; + + public BlockLevelerHelper(AuraSkills plugin) { + this.plugin = plugin; + } + + /** + * Gets the total number of blocks broken when breaking + * multi-block plants, including the directly broken one. + * + * @param block The directly broken block + * @param source The XP source + * @return Number of blocks broken + */ + public int getBlocksBroken(Block block, BlockXpSource source) { + Material mat = block.getType(); + if (mat == Material.SUGAR_CANE) { + int num = 1; + // Check the two blocks above + BlockState above = block.getRelative(BlockFace.UP).getState(); + if (above.getType() == Material.SUGAR_CANE) { + if (!plugin.getRegionManager().isPlacedBlock(above.getBlock()) || !checkReplace()) { + num++; + } + BlockState aboveAbove = block.getRelative(BlockFace.UP).getRelative(BlockFace.UP).getState(); + if (aboveAbove.getType() == Material.SUGAR_CANE) { + if (!plugin.getRegionManager().isPlacedBlock(aboveAbove.getBlock()) || !checkReplace()) { + num++; + } + } + } + return num; + } else if (mat == Material.BAMBOO || mat == Material.CACTUS || mat == Material.KELP_PLANT) { + int num = 1; + if (checkReplace() && plugin.getRegionManager().isPlacedBlock(block)) { + Block above = block.getRelative(BlockFace.UP); + if (!sourceMatches(block, source) || plugin.getRegionManager().isPlacedBlock(above)) { + return 0; + } + num = 0; + } + num += getSameBlocksAbove(block.getRelative(BlockFace.UP), source, 0); + return num; + } + return 1; + } + + public double getStateMultiplier(Block block, BlockXpSource source) { + if (!source.hasStateMultiplier()) return 1.0; + + if (block.getBlockData() instanceof Ageable ageable) { + return source.getStateMultiplier("age", ageable.getAge()); + } else if (block.getBlockData() instanceof SeaPickle seaPickle) { + return source.getStateMultiplier("pickles", seaPickle.getPickles()); + } + return source.getStateMultiplier("placeholder", 1.0); + } + + + private int getSameBlocksAbove(Block block, BlockXpSource source, int num) { + if (sourceMatches(block, source)) { + if (checkReplace() && plugin.getRegionManager().isPlacedBlock(block)) { + return num; + } + num++; + return getSameBlocksAbove(block.getRelative(BlockFace.UP), source, num); + } + return num; + } + + private boolean sourceMatches(Block block, BlockXpSource source) { + for (String blockName : source.getBlocks()) { + if (block.getType().name().equalsIgnoreCase(blockName)) { + return true; + } + } + return false; + } + + private boolean checkReplace() { + return plugin.configBoolean(Option.CHECK_BLOCK_REPLACE); + } + +} diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java index 2fefdad3e..afd5b9f0a 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java @@ -7,20 +7,19 @@ import dev.aurelium.auraskills.common.config.Option; import dev.aurelium.auraskills.common.hooks.PlaceholderHook; import dev.aurelium.auraskills.common.message.type.ActionBarMessage; -import dev.aurelium.auraskills.common.ui.BossBarColor; -import dev.aurelium.auraskills.common.ui.BossBarStyle; import dev.aurelium.auraskills.common.util.math.BigNumber; import dev.aurelium.auraskills.common.util.math.NumberUtil; import dev.aurelium.auraskills.common.util.math.RomanNumber; import dev.aurelium.auraskills.common.util.text.TextUtil; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Bukkit; -import org.bukkit.boss.BarColor; -import org.bukkit.boss.BarStyle; -import org.bukkit.boss.BossBar; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.scheduler.BukkitRunnable; import java.text.DecimalFormat; import java.text.NumberFormat; @@ -28,8 +27,9 @@ import java.util.Locale; import java.util.Map; import java.util.UUID; +import java.util.concurrent.TimeUnit; -public class BossBarManager { +public class BossBarManager implements Listener { private final Map> bossBars; private final Map> currentActions; @@ -39,8 +39,8 @@ public class BossBarManager { private final Map singleCheckCurrentActions; private String mode; private int stayTime; - private Map colors; - private Map styles; + private Map colors; + private Map overlays; private final NumberFormat nf = new DecimalFormat("#.#"); private final AuraSkills plugin; @@ -58,12 +58,12 @@ public void loadOptions() { mode = plugin.configString(Option.BOSS_BAR_MODE); stayTime = plugin.configInt(Option.BOSS_BAR_STAY_TIME); colors = new HashMap<>(); - styles = new HashMap<>(); + overlays = new HashMap<>(); for (String entry : plugin.configStringList(Option.BOSS_BAR_FORMAT)) { String[] splitEntry = entry.split(" "); Skill skill; - BossBarColor color = BossBarColor.GREEN; - BossBarStyle style = BossBarStyle.SOLID; + BossBar.Color color = BossBar.Color.GREEN; + BossBar.Overlay overlay = BossBar.Overlay.PROGRESS; try { skill = plugin.getSkillRegistry().get(NamespacedId.fromDefault(splitEntry[0].toUpperCase(Locale.ROOT))); } catch (IllegalArgumentException e) { @@ -73,14 +73,14 @@ public void loadOptions() { if (splitEntry.length > 1) { try { - color = BossBarColor.valueOf(splitEntry[1].toUpperCase(Locale.ROOT)); + color = BossBar.Color.valueOf(splitEntry[1].toUpperCase(Locale.ROOT)); } catch (IllegalArgumentException e) { plugin.logger().warn("Error loading boss bar format in config.yml: " + splitEntry[0] + " is not a valid BarColor"); } if (splitEntry.length > 2) { try { - style = BossBarStyle.valueOf(splitEntry[2].toUpperCase(Locale.ROOT)); + overlay = BossBar.Overlay.valueOf(splitEntry[2].toUpperCase(Locale.ROOT)); } catch (IllegalArgumentException e) { plugin.logger().warn("Error loading boss bar format in config.yml: " + splitEntry[0] + " is not a valid BarStyle"); @@ -88,17 +88,18 @@ public void loadOptions() { } } colors.put(skill, color); - styles.put(skill, style); + overlays.put(skill, overlay); } - for (Map.Entry entry : singleBossBars.entrySet()) { - entry.getValue().setVisible(false); - entry.getValue().removeAll(); - } - for (Map.Entry> entry : bossBars.entrySet()) { - Map bossBars = entry.getValue(); - for (Map.Entry bossBarEntry : bossBars.entrySet()) { - bossBarEntry.getValue().setVisible(false); - bossBarEntry.getValue().removeAll(); + for (Player player : Bukkit.getOnlinePlayers()) { + Audience audience = plugin.getAudiences().player(player); + for (Map.Entry entry : singleBossBars.entrySet()) { + audience.hideBossBar(entry.getValue()); + } + for (Map.Entry> entry : bossBars.entrySet()) { + Map bossBars = entry.getValue(); + for (Map.Entry bossBarEntry : bossBars.entrySet()) { + audience.hideBossBar(bossBarEntry.getValue()); + } } } bossBars.clear(); @@ -144,19 +145,20 @@ public void sendBossBar(Player player, Skill skill, double currentXp, double lev private BossBar handleNewBossBar(Player player, Skill skill, double currentXp, double levelXp, double xpGained, int level, boolean maxed) { Locale locale = plugin.getUser(player).getLocale(); - BarColor color = BarColor.valueOf(getColor(skill).name()); - BarStyle style = BarStyle.valueOf(getStyle(skill).name()); + BossBar.Color color = getColor(skill); + BossBar.Overlay overlay = getOverlay(skill); String bossBarText = getBossBarText(player, skill, currentXp, (long) levelXp, (long) xpGained, level, maxed, locale); - BossBar bossBar = Bukkit.createBossBar(bossBarText, color, style); + Component name = LegacyComponentSerializer.legacySection().deserialize(bossBarText); + // Calculate xp progress double progress = currentXp / levelXp; - if (progress <= 1 && progress >= 0) { - bossBar.setProgress(currentXp / levelXp); - } else { - bossBar.setProgress(1.0); + if (progress > 1 || progress < 0) { + progress = 1.0; } - bossBar.addPlayer(player); + BossBar bossBar = BossBar.bossBar(name, (float) progress, color, overlay); + + plugin.getAudiences().player(player).showBossBar(bossBar); // Add to maps if (mode.equals("single")) { singleBossBars.put(player.getUniqueId(), bossBar); @@ -170,15 +172,17 @@ private void handleExistingBossBar(BossBar bossBar, Player player, Skill skill, Locale locale = plugin.getUser(player).getLocale(); String bossBarText = getBossBarText(player, skill, currentXp, (long) levelXp, xpGained, level, maxed, locale); - bossBar.setTitle(bossBarText); // Update the boss bar to the new text value + Component name = LegacyComponentSerializer.legacySection().deserialize(bossBarText); + + bossBar.name(name); // Update the boss bar to the new text value // Calculate xp progress double progress = currentXp / levelXp; - if (progress <= 1 && progress >= 0) { - bossBar.setProgress(currentXp / levelXp); - } else { - bossBar.setProgress(1.0); + if (progress > 1 || progress < 0) { + progress = 1.0; } - bossBar.setVisible(true); // Show the boss bar to the player + bossBar.progress((float) progress); + + plugin.getAudiences().player(player).showBossBar(bossBar); } private String getBossBarText(Player player, Skill skill, double currentXp, long levelXp, double xpGained, int level, boolean maxed, Locale locale) { @@ -190,6 +194,7 @@ private String getBossBarText(Player player, Skill skill, double currentXp, long "{level}", RomanNumber.toRoman(level, plugin), "{current_xp}", currentXpText, "{level_xp}", getLevelXpText(levelXp), + "{percent}", NumberUtil.format2(currentXp / (double) levelXp * 100), "{xp_gained}", NumberUtil.format1(xpGained))); } else { bossBarText = setPlaceholders(player, TextUtil.replace(plugin.getMsg(ActionBarMessage.BOSS_BAR_MAXED, locale), @@ -241,50 +246,50 @@ public void incrementAction(Player player, Skill skill) { private void scheduleHide(UUID playerId, Skill skill, BossBar bossBar) { if (mode.equals("single")) { final int currentAction = singleCurrentActions.get(playerId); - new BukkitRunnable() { - @Override - public void run() { - if (mode.equals("single")) { - if (currentAction == singleCurrentActions.getOrDefault(playerId, 0)) { - if (bossBar != null) { - bossBar.setVisible(false); - } - singleCheckCurrentActions.remove(playerId); - } - } + plugin.getScheduler().scheduleSync(() -> { + if (!mode.equals("single")) { + return; } - }.runTaskLater(plugin, stayTime); - } - else { + if (currentAction != singleCurrentActions.getOrDefault(playerId, 0)) { + return; + } + if (bossBar != null) { + plugin.getAudiences().player(playerId).hideBossBar(bossBar); + } + singleCheckCurrentActions.remove(playerId); + }, stayTime * 50L, TimeUnit.MILLISECONDS); + } else { Map multiCurrentActions = currentActions.get(playerId); - if (multiCurrentActions != null) { - final int currentAction = multiCurrentActions.get(skill); - new BukkitRunnable() { - @Override - public void run() { - if (!mode.equals("single")) { - Map multiCurrentActions = currentActions.get(playerId); - if (multiCurrentActions != null) { - if (currentAction == multiCurrentActions.getOrDefault(skill, 0)) { - if (bossBar != null) { - bossBar.setVisible(false); - } - checkCurrentActions.remove(playerId); - } - } - } - } - }.runTaskLater(plugin, stayTime); + if (multiCurrentActions == null) { + return; } + final int currentAction = multiCurrentActions.get(skill); + + plugin.getScheduler().scheduleSync(() -> { + if (mode.equals("single")) { + return; + } + Map currActions = currentActions.get(playerId); + if (currActions == null) { + return; + } + if (currentAction != currActions.getOrDefault(skill, 0)) { + return; + } + if (bossBar != null) { + plugin.getAudiences().player(playerId).hideBossBar(bossBar); + } + checkCurrentActions.remove(playerId); + }, stayTime * 50L, TimeUnit.MILLISECONDS); } } - private BossBarColor getColor(Skill skill) { - return colors.getOrDefault(skill, BossBarColor.GREEN); + private BossBar.Color getColor(Skill skill) { + return colors.getOrDefault(skill, BossBar.Color.GREEN); } - private BossBarStyle getStyle(Skill skill) { - return styles.getOrDefault(skill, BossBarStyle.SOLID); + private BossBar.Overlay getOverlay(Skill skill) { + return overlays.getOrDefault(skill, BossBar.Overlay.PROGRESS); } public int getCurrentAction(Player player, Skill skill) { diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BukkitUiProvider.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BukkitUiProvider.java index 91c8fc457..8423b21de 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BukkitUiProvider.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BukkitUiProvider.java @@ -21,6 +21,7 @@ public BukkitUiProvider(AuraSkills plugin) { this.plugin = plugin; this.actionBarManager = new BukkitActionBarManager(plugin, this); this.bossBarManager = new BossBarManager(plugin); + plugin.getServer().getPluginManager().registerEvents(bossBarManager, plugin); } @Override diff --git a/bukkit/src/main/resources/config.yml b/bukkit/src/main/resources/config.yml index bebffce56..0994c872f 100644 --- a/bukkit/src/main/resources/config.yml +++ b/bukkit/src/main/resources/config.yml @@ -81,7 +81,7 @@ action_bar: # Boss Bar Options boss_bar: enabled: true - mode: multi + mode: single stay_time: 60 update_every: 1 round_xp: false @@ -89,21 +89,21 @@ boss_bar: placeholder_api: true use_suffix: true format: - - 'FARMING GREEN SOLID' - - 'FORAGING RED SOLID' - - 'MINING PURPLE SOLID' - - 'FISHING BLUE SOLID' - - 'EXCAVATION YELLOW SOLID' - - 'ARCHERY PINK SOLID' - - 'DEFENSE BLUE SOLID' - - 'FIGHTING RED SOLID' - - 'ENDURANCE PURPLE SOLID' - - 'AGILITY WHITE SOLID' - - 'ALCHEMY PINK SOLID' - - 'ENCHANTING PURPLE SOLID' - - 'SORCERY BLUE SOLID' - - 'HEALING WHITE SOLID' - - 'FORGING YELLOW SOLID' + - 'FARMING GREEN PROGRESS' + - 'FORAGING RED PROGRESS' + - 'MINING PURPLE PROGRESS' + - 'FISHING BLUE PROGRESS' + - 'EXCAVATION YELLOW PROGRESS' + - 'ARCHERY PINK PROGRESS' + - 'DEFENSE BLUE PROGRESS' + - 'FIGHTING RED PROGRESS' + - 'ENDURANCE PURPLE PROGRESS' + - 'AGILITY WHITE PROGRESS' + - 'ALCHEMY PINK PROGRESS' + - 'ENCHANTING PURPLE PROGRESS' + - 'SORCERY BLUE PROGRESS' + - 'HEALING WHITE PROGRESS' + - 'FORGING YELLOW PROGRESS' # The base mana amount base_mana: 20 diff --git a/bukkit/src/main/resources/messages/messages_en.yml b/bukkit/src/main/resources/messages/messages_en.yml index 1f9cf28bc..91e37d47a 100644 --- a/bukkit/src/main/resources/messages/messages_en.yml +++ b/bukkit/src/main/resources/messages/messages_en.yml @@ -349,8 +349,8 @@ action_bar: maxed: '{hp}/{max_hp}❤ +{xp_gained} {skill} {xp_unit} (MAXED) {mana}/{max_mana} {mana_unit}' maxed_removed: '{hp}/{max_hp}❤ -{xp_removed} {skill} {xp_unit} (MAXED) {mana}/{max_mana} {mana_unit}' ability: '{message}' - boss_bar_xp: '{skill} {level} ({current_xp}/{level_xp} {xp_unit})' - boss_bar_maxed: '{skill} {level} (MAXED)' + boss_bar_xp: '+{xp_gained} {skill} XP ({percent}%)' + boss_bar_maxed: '+{xp_gained} {skill} XP (MAXED)' commands: prefix: '[Skills] ' armor: diff --git a/common/src/main/java/dev/aurelium/auraskills/common/source/serializer/BlockSourceSerializer.java b/common/src/main/java/dev/aurelium/auraskills/common/source/serializer/BlockSourceSerializer.java index fae524fad..4c27b55dd 100644 --- a/common/src/main/java/dev/aurelium/auraskills/common/source/serializer/BlockSourceSerializer.java +++ b/common/src/main/java/dev/aurelium/auraskills/common/source/serializer/BlockSourceSerializer.java @@ -23,7 +23,7 @@ public BlockSource deserialize(Type type, ConfigurationNode source) throws Seria BlockXpSource.BlockTriggers[] triggers = requiredPluralizedArray("trigger", source, BlockXpSource.BlockTriggers.class); boolean checkReplace = source.node("check_replace").getBoolean(true); BlockXpSource.BlockXpSourceState[] states = pluralizedArray("state", source, BlockXpSource.BlockXpSourceState.class); - String stateMultiplier = source.node("state_multiplier").getString(); + String stateMultiplier = source.node("state_multiplier").getString(""); BlockXpSource.SupportBlockType supportBlockType = source.node("support_block").get(BlockXpSource.SupportBlockType.class, BlockXpSource.SupportBlockType.NONE); boolean trunk = source.node("trunk").getBoolean(false); diff --git a/common/src/main/java/dev/aurelium/auraskills/common/source/type/BlockSource.java b/common/src/main/java/dev/aurelium/auraskills/common/source/type/BlockSource.java index 97fd162de..54754534a 100644 --- a/common/src/main/java/dev/aurelium/auraskills/common/source/type/BlockSource.java +++ b/common/src/main/java/dev/aurelium/auraskills/common/source/type/BlockSource.java @@ -73,6 +73,11 @@ public double getStateMultiplier(String stateKey, Object stateValue) { } } + @Override + public boolean hasStateMultiplier() { + return !stateMultiplier.isEmpty(); + } + @Override public boolean requiresSupportBlock(SupportBlockType direction) { return supportBlockType == direction; diff --git a/common/src/main/resources/sources/farming.yml b/common/src/main/resources/sources/farming.yml index 37cff191d..6869cdcf6 100644 --- a/common/src/main/resources/sources/farming.yml +++ b/common/src/main/resources/sources/farming.yml @@ -84,6 +84,8 @@ sources: xp: 0.3 triggers: [break, break_indirect] check_replace: true + menu_item: + material: kelp sea_pickle: block: sea_pickle xp: 4.0 @@ -109,6 +111,18 @@ sources: berries: true menu_item: material: glow_berries + torchflower: + block: torchflower + xp: 9.0 + check_replace: true + pitcher_plant: + block: pitcher_crop + xp: 1.0 + check_replace: false + state: + age: 4 + menu_item: + material: pitcher_plant tags: bountiful_harvest_applicable: - '*'