Fix bug where Green Thumb did not replant if seeds were solely in the offhand Fixes #4994

This commit is contained in:
nossr50 2024-04-21 14:56:57 -07:00
parent 0db5330416
commit c078e853eb
5 changed files with 80 additions and 53 deletions

View File

@ -16,9 +16,7 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
* Only skills using the old system will fire this event * Only skills using the old system will fire this event
* @param player target player * @param player target player
* @param subSkillType target subskill * @param subSkillType target subskill
* @Deprecated Skills will be using a new system stemming from the AbstractSubSkill class so make sure you check for both events, this event will be removed eventually.
*/ */
@Deprecated
public SubSkillEvent(Player player, SubSkillType subSkillType) { public SubSkillEvent(Player player, SubSkillType subSkillType) {
super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType)); super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
this.subSkillType = subSkillType; this.subSkillType = subSkillType;
@ -29,9 +27,7 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
* @param player target player * @param player target player
* @param subSkillType target subskill * @param subSkillType target subskill
* @param resultModifier a value multiplied against the final result of the dice roll, typically between 0-1.0 * @param resultModifier a value multiplied against the final result of the dice roll, typically between 0-1.0
* @Deprecated Skills will be using a new system stemming from the AbstractSubSkill class so make sure you check for both events, this event will be removed eventually.
*/ */
@Deprecated
public SubSkillEvent(Player player, SubSkillType subSkillType, double resultModifier) { public SubSkillEvent(Player player, SubSkillType subSkillType, double resultModifier) {
super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType)); super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
this.subSkillType = subSkillType; this.subSkillType = subSkillType;

View File

@ -44,7 +44,9 @@ public final class ShareHandler {
nearMembers.add(mcMMOPlayer.getPlayer()); nearMembers.add(mcMMOPlayer.getPlayer());
int partySize = nearMembers.size(); int partySize = nearMembers.size();
double shareBonus = Math.min(mcMMO.p.getGeneralConfig().getPartyShareBonusBase() + (partySize * mcMMO.p.getGeneralConfig().getPartyShareBonusIncrease()), mcMMO.p.getGeneralConfig().getPartyShareBonusCap()); double shareBonus = Math.min(mcMMO.p.getGeneralConfig().getPartyShareBonusBase()
+ (partySize * mcMMO.p.getGeneralConfig().getPartyShareBonusIncrease()),
mcMMO.p.getGeneralConfig().getPartyShareBonusCap());
float splitXp = (float) (xp / partySize * shareBonus); float splitXp = (float) (xp / partySize * shareBonus);
for (Player member : nearMembers) { for (Player member : nearMembers) {

View File

@ -33,6 +33,7 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.data.Ageable; import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -41,6 +42,9 @@ import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
import static com.gmail.nossr50.util.ItemUtils.hasItemIncludingOffHand;
import static com.gmail.nossr50.util.ItemUtils.removeItemIncludingOffHand;
public class HerbalismManager extends SkillManager { public class HerbalismManager extends SkillManager {
public HerbalismManager(McMMOPlayer mcMMOPlayer) { public HerbalismManager(McMMOPlayer mcMMOPlayer) {
super(mcMMOPlayer, PrimarySkillType.HERBALISM); super(mcMMOPlayer, PrimarySkillType.HERBALISM);
@ -745,13 +749,14 @@ public class HerbalismManager extends SkillManager {
* @param blockState The {@link BlockState} to check ability activation for * @param blockState The {@link BlockState} to check ability activation for
* @param greenTerra boolean to determine if greenTerra is active or not * @param greenTerra boolean to determine if greenTerra is active or not
*/ */
private boolean processGreenThumbPlants(BlockState blockState, BlockBreakEvent blockBreakEvent, boolean greenTerra) { private boolean processGreenThumbPlants(@NotNull BlockState blockState, @NotNull BlockBreakEvent blockBreakEvent,
boolean greenTerra) {
if (!ItemUtils.isHoe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand()) if (!ItemUtils.isHoe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand())
&& !ItemUtils.isAxe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand())) { && !ItemUtils.isAxe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand())) {
return false; return false;
} }
BlockData blockData = blockState.getBlockData(); final BlockData blockData = blockState.getBlockData();
if (!(blockData instanceof Ageable ageable)) { if (!(blockData instanceof Ageable ageable)) {
return false; return false;
@ -759,47 +764,28 @@ public class HerbalismManager extends SkillManager {
//If the ageable is NOT mature and the player is NOT using a hoe, abort //If the ageable is NOT mature and the player is NOT using a hoe, abort
Player player = getPlayer(); final Player player = getPlayer();
PlayerInventory playerInventory = player.getInventory(); final Material replantMaterial;
Material seed;
switch (blockState.getType().getKey().getKey().toLowerCase(Locale.ROOT)) { switch (blockState.getType().getKey().getKey().toLowerCase(Locale.ENGLISH)) {
case "carrots": case "carrots" -> replantMaterial = Material.matchMaterial("CARROT");
seed = Material.matchMaterial("CARROT"); case "wheat" -> replantMaterial = Material.matchMaterial("WHEAT_SEEDS");
break; case "nether_wart" -> replantMaterial = Material.getMaterial("NETHER_WART");
case "potatoes" -> replantMaterial = Material.matchMaterial("POTATO");
case "wheat": case "beetroots" -> replantMaterial = Material.matchMaterial("BEETROOT_SEEDS");
seed = Material.matchMaterial("WHEAT_SEEDS"); case "cocoa" -> replantMaterial = Material.matchMaterial("COCOA_BEANS");
break; case "torchflower" -> replantMaterial = Material.matchMaterial("TORCHFLOWER_SEEDS");
default -> {
case "nether_wart":
seed = Material.getMaterial("NETHER_WART");
break;
case "potatoes":
seed = Material.matchMaterial("POTATO");
break;
case "beetroots":
seed = Material.matchMaterial("BEETROOT_SEEDS");
break;
case "cocoa":
seed = Material.matchMaterial("COCOA_BEANS");
break;
case "torchflower":
seed = Material.matchMaterial("TORCHFLOWER_SEEDS");
break;
default:
return false; return false;
}
} }
if (replantMaterial == null) {
ItemStack seedStack = new ItemStack(seed); return false;
}
if (ItemUtils.isAxe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand()) if (ItemUtils.isAxe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand())
&& blockState.getType() != Material.COCOA) { && blockState.getType() != Material.COCOA) {
return false; return false;
} }
@ -807,25 +793,25 @@ public class HerbalismManager extends SkillManager {
return false; return false;
} }
if (!playerInventory.containsAtLeast(seedStack, 1)) { if (!hasItemIncludingOffHand(player, replantMaterial)) {
return false; return false;
} }
if (!processGrowingPlants(blockState, ageable, blockBreakEvent, greenTerra)) { if(EventUtils.callSubSkillBlockEvent(player, SubSkillType.HERBALISM_GREEN_THUMB, blockState.getBlock())
return false; .isCancelled()) {
}
if(EventUtils.callSubSkillBlockEvent(player, SubSkillType.HERBALISM_GREEN_THUMB, blockState.getBlock()).isCancelled()) {
return false; return false;
} else { } else {
playerInventory.removeItem(seedStack); if (!processGrowingPlants(blockState, ageable, blockBreakEvent, greenTerra)) {
player.updateInventory(); // Needed until replacement available return false;
}
// remove the item from the player's inventory
removeItemIncludingOffHand(player, replantMaterial, 1);
// player.updateInventory(); // Needed until replacement available
//Play sound //Play sound
SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_CONSUMED); SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_CONSUMED);
return true; return true;
} }
// new HerbalismBlockUpdaterTask(blockState).runTaskLater(mcMMO.p, 0);
} }
private boolean processGrowingPlants(BlockState blockState, Ageable ageable, BlockBreakEvent blockBreakEvent, boolean greenTerra) { private boolean processGrowingPlants(BlockState blockState, Ageable ageable, BlockBreakEvent blockBreakEvent, boolean greenTerra) {

View File

@ -197,7 +197,6 @@ public final class EventUtils {
* @param block associated block * @param block associated block
* @return the event after it has been fired * @return the event after it has been fired
*/ */
@Deprecated
public static @NotNull SubSkillBlockEvent callSubSkillBlockEvent(@NotNull Player player, @NotNull SubSkillType subSkillType, @NotNull Block block) { public static @NotNull SubSkillBlockEvent callSubSkillBlockEvent(@NotNull Player player, @NotNull SubSkillType subSkillType, @NotNull Block block) {
SubSkillBlockEvent event = new SubSkillBlockEvent(player, subSkillType, block); SubSkillBlockEvent event = new SubSkillBlockEvent(player, subSkillType, block);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);

View File

@ -41,6 +41,50 @@ public final class ItemUtils {
return mcMMO.getMaterialMapStore().isBow(item.getType().getKey().getKey()); return mcMMO.getMaterialMapStore().isBow(item.getType().getKey().getKey());
} }
/**
* Checks if a player has an item in their inventory or offhand.
*
* @param player Player to check
* @param material Material to check for
* @return true if the player has the item in their inventory or offhand, false otherwise
*/
public static boolean hasItemIncludingOffHand(Player player, Material material) {
// Checks main inventory / item bar
boolean containsInMain = player.getInventory().contains(material);
if (containsInMain) {
return true;
}
return player.getInventory().getItemInOffHand().getType() == material;
}
/**
* Removes an item from a player's inventory, including their offhand.
*
* @param player Player to remove the item from
* @param material Material to remove
* @param amount Amount of the material to remove
*/
public static void removeItemIncludingOffHand(@NotNull Player player, @NotNull Material material, int amount) {
// Checks main inventory / item bar
if (player.getInventory().contains(material)) {
player.getInventory().removeItem(new ItemStack(material, amount));
return;
}
// Check off-hand
final ItemStack offHandItem = player.getInventory().getItemInOffHand();
if (offHandItem.getType() == material) {
int newAmount = offHandItem.getAmount() - amount;
if (newAmount > 0) {
offHandItem.setAmount(newAmount);
} else {
player.getInventory().setItemInOffHand(new ItemStack(Material.AIR));
}
}
}
// TODO: Unit tests // TODO: Unit tests
public static boolean isCrossbow(@NotNull ItemStack item) { public static boolean isCrossbow(@NotNull ItemStack item) {
return mcMMO.getMaterialMapStore().isCrossbow(item.getType().getKey().getKey()); return mcMMO.getMaterialMapStore().isCrossbow(item.getType().getKey().getKey());