mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-22 21:26:46 +01:00
Immature crop replanting, green thumb tweaks, replant accidental break
protection
This commit is contained in:
parent
8f26544188
commit
e2073ff9f7
@ -1,4 +1,6 @@
|
|||||||
Version 2.1.115
|
Version 2.1.115
|
||||||
|
Hoes no longer give free replants
|
||||||
|
There is now a feature in place to prevent breaking a newly automatically replanted (via green thumb) crop from being breakable for a few seconds after it appears
|
||||||
Using a hoe on non-fully grown crops will replant them as a convenience feature for those who can't bother to wait for all of their plants to grow (put away the hoe to break non-fully grown crops)
|
Using a hoe on non-fully grown crops will replant them as a convenience feature for those who can't bother to wait for all of their plants to grow (put away the hoe to break non-fully grown crops)
|
||||||
Fixed a bug where Salvage always gave the best results
|
Fixed a bug where Salvage always gave the best results
|
||||||
Fixed an issue with arrows causing exceptions with players not yet having data loaded
|
Fixed an issue with arrows causing exceptions with players not yet having data loaded
|
||||||
|
@ -12,4 +12,5 @@ public class OldName extends FixedMetadataValue {
|
|||||||
{
|
{
|
||||||
super(plugin, oldName);
|
super(plugin, oldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.gmail.nossr50.datatypes.meta;
|
||||||
|
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
public class RecentlyReplantedCropMeta extends FixedMetadataValue {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a FixedMetadataValue with an Object
|
||||||
|
*
|
||||||
|
* @param owningPlugin the {@link Plugin} that created this metadata value
|
||||||
|
*/
|
||||||
|
public RecentlyReplantedCropMeta(Plugin owningPlugin) {
|
||||||
|
super(owningPlugin, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -107,6 +107,7 @@ public class mcMMO extends JavaPlugin {
|
|||||||
private static boolean isRetroModeEnabled;
|
private static boolean isRetroModeEnabled;
|
||||||
|
|
||||||
/* Metadata Values */
|
/* Metadata Values */
|
||||||
|
public final static String REPLANT_META_KEY = "mcMMO: Recently Replanted";
|
||||||
public static final String FISH_HOOK_REF_METAKEY = "mcMMO: Fish Hook Tracker";
|
public static final String FISH_HOOK_REF_METAKEY = "mcMMO: Fish Hook Tracker";
|
||||||
public static final String DODGE_TRACKER = "mcMMO: Dodge Tracker";
|
public static final String DODGE_TRACKER = "mcMMO: Dodge Tracker";
|
||||||
public static final String CUSTOM_DAMAGE_METAKEY = "mcMMO: Custom Damage";
|
public static final String CUSTOM_DAMAGE_METAKEY = "mcMMO: Custom Damage";
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
package com.gmail.nossr50.runnables.skills;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockState;
|
||||||
|
import org.bukkit.block.data.Ageable;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
public class DelayedCropReplant extends BukkitRunnable {
|
||||||
|
|
||||||
|
private final int desiredCropAge;
|
||||||
|
private final Location cropLocation;
|
||||||
|
private final Material cropMaterial;
|
||||||
|
private boolean wasImmaturePlant;
|
||||||
|
private final BlockBreakEvent blockBreakEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replants a crop after a delay setting the age to desiredCropAge
|
||||||
|
* @param cropState target {@link BlockState}
|
||||||
|
* @param desiredCropAge desired age of the crop
|
||||||
|
*/
|
||||||
|
public DelayedCropReplant(BlockBreakEvent blockBreakEvent, BlockState cropState, int desiredCropAge, boolean wasImmaturePlant) {
|
||||||
|
//The plant was either immature or something cancelled the event, therefor we need to treat it differently
|
||||||
|
this.blockBreakEvent = blockBreakEvent;
|
||||||
|
this.wasImmaturePlant = wasImmaturePlant;
|
||||||
|
this.cropMaterial = cropState.getType();
|
||||||
|
this.desiredCropAge = desiredCropAge;
|
||||||
|
this.cropLocation = cropState.getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Block cropBlock = cropLocation.getBlock();
|
||||||
|
BlockState currentState = cropBlock.getState();
|
||||||
|
|
||||||
|
if(blockBreakEvent.isCancelled()) {
|
||||||
|
wasImmaturePlant = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Two kinds of air in Minecraft
|
||||||
|
if(currentState.getType().equals(Material.AIR) || currentState.getType().equals(Material.CAVE_AIR)) {
|
||||||
|
//The space is not currently occupied by a block so we can fill it
|
||||||
|
cropBlock.setType(cropMaterial);
|
||||||
|
|
||||||
|
//Get new state (necessary?)
|
||||||
|
BlockState newState = cropBlock.getState();
|
||||||
|
newState.setType(cropMaterial);
|
||||||
|
newState.update();
|
||||||
|
Ageable ageable = (Ageable) newState.getBlockData();
|
||||||
|
|
||||||
|
//Crop age should always be 0 if the plant was immature
|
||||||
|
if(wasImmaturePlant) {
|
||||||
|
ageable.setAge(0);
|
||||||
|
} else {
|
||||||
|
//Otherwise make the plant the desired age
|
||||||
|
ageable.setAge(desiredCropAge);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Age the crop
|
||||||
|
newState.setBlockData(ageable);
|
||||||
|
|
||||||
|
//Play an effect
|
||||||
|
ParticleEffectUtils.playGreenThumbEffect(cropLocation);
|
||||||
|
|
||||||
|
//Remove the metadata marking the block as recently replanted
|
||||||
|
new removePlantMeta(blockBreakEvent.getBlock().getLocation()).runTaskLater(mcMMO.p, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class removePlantMeta extends BukkitRunnable {
|
||||||
|
|
||||||
|
private final Location cropLoc;
|
||||||
|
|
||||||
|
public removePlantMeta(Location cropLoc) {
|
||||||
|
this.cropLoc = cropLoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Block cropBlock = cropLoc.getBlock();
|
||||||
|
cropBlock.removeMetadata(mcMMO.REPLANT_META_KEY, mcMMO.p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -7,6 +7,7 @@ import com.gmail.nossr50.datatypes.BlockSnapshot;
|
|||||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
|
import com.gmail.nossr50.datatypes.experience.XPGainSource;
|
||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||||
|
import com.gmail.nossr50.datatypes.meta.RecentlyReplantedCropMeta;
|
||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||||
@ -14,6 +15,7 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
|
|||||||
import com.gmail.nossr50.datatypes.skills.ToolType;
|
import com.gmail.nossr50.datatypes.skills.ToolType;
|
||||||
import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
|
import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
|
||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.gmail.nossr50.runnables.skills.DelayedCropReplant;
|
||||||
import com.gmail.nossr50.runnables.skills.DelayedHerbalismXPCheckTask;
|
import com.gmail.nossr50.runnables.skills.DelayedHerbalismXPCheckTask;
|
||||||
import com.gmail.nossr50.runnables.skills.HerbalismBlockUpdaterTask;
|
import com.gmail.nossr50.runnables.skills.HerbalismBlockUpdaterTask;
|
||||||
import com.gmail.nossr50.skills.SkillManager;
|
import com.gmail.nossr50.skills.SkillManager;
|
||||||
@ -158,6 +160,13 @@ public class HerbalismManager extends SkillManager {
|
|||||||
private void processHerbalismOnBlocksBroken(BlockBreakEvent blockBreakEvent, HashSet<Block> brokenPlants) {
|
private void processHerbalismOnBlocksBroken(BlockBreakEvent blockBreakEvent, HashSet<Block> brokenPlants) {
|
||||||
BlockState originalBreak = blockBreakEvent.getBlock().getState();
|
BlockState originalBreak = blockBreakEvent.getBlock().getState();
|
||||||
|
|
||||||
|
//Check if the plant was recently replanted
|
||||||
|
if(blockBreakEvent.getBlock().getMetadata(mcMMO.REPLANT_META_KEY).size() >= 1) {
|
||||||
|
//Crop is recently replanted to back out of destroying it
|
||||||
|
blockBreakEvent.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: The design of Green Terra needs to change, this is a mess
|
//TODO: The design of Green Terra needs to change, this is a mess
|
||||||
if(Permissions.greenThumbPlant(getPlayer(), originalBreak.getType())) {
|
if(Permissions.greenThumbPlant(getPlayer(), originalBreak.getType())) {
|
||||||
processGreenThumbPlants(originalBreak, blockBreakEvent, isGreenTerraActive());
|
processGreenThumbPlants(originalBreak, blockBreakEvent, isGreenTerraActive());
|
||||||
@ -639,6 +648,18 @@ public class HerbalismManager extends SkillManager {
|
|||||||
return Herbalism.convertShroomThumb(blockState);
|
return Herbalism.convertShroomThumb(blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the delayed replant task and turns
|
||||||
|
* @param desiredCropAge the desired age of the crop
|
||||||
|
* @param blockBreakEvent the {@link BlockBreakEvent} this crop was involved in
|
||||||
|
* @param cropState the {@link BlockState} of the crop
|
||||||
|
*/
|
||||||
|
private void startReplantTask(int desiredCropAge, BlockBreakEvent blockBreakEvent, BlockState cropState, boolean isImmature) {
|
||||||
|
//Mark the plant as recently replanted to avoid accidental breakage
|
||||||
|
blockBreakEvent.getBlock().setMetadata(mcMMO.REPLANT_META_KEY, new RecentlyReplantedCropMeta(mcMMO.p));
|
||||||
|
new DelayedCropReplant(blockBreakEvent, cropState, desiredCropAge, isImmature).runTaskLater(mcMMO.p, 20 * 2);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the Green Thumb ability for plants.
|
* Process the Green Thumb ability for plants.
|
||||||
*
|
*
|
||||||
@ -651,12 +672,13 @@ public class HerbalismManager extends SkillManager {
|
|||||||
if (!(blockData instanceof Ageable))
|
if (!(blockData instanceof Ageable))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Ageable ageable = (Ageable) blockData;
|
||||||
|
|
||||||
//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
|
||||||
if(!isAgeableMature((Ageable) blockData) && !ItemUtils.isHoe(getPlayer().getItemInHand())) {
|
if(!isAgeableMature(ageable) && !ItemUtils.isHoe(getPlayer().getItemInHand())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Player player = getPlayer();
|
Player player = getPlayer();
|
||||||
PlayerInventory playerInventory = player.getInventory();
|
PlayerInventory playerInventory = player.getInventory();
|
||||||
Material seed = null;
|
Material seed = null;
|
||||||
@ -696,31 +718,36 @@ public class HerbalismManager extends SkillManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!processGrowingPlants(blockState, blockBreakEvent, greenTerra)) {
|
|
||||||
|
if (!playerInventory.containsAtLeast(seedStack, 1)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ItemUtils.isHoe(getPlayer().getInventory().getItemInMainHand()))
|
if (!processGrowingPlants(blockState, ageable, blockBreakEvent, greenTerra)) {
|
||||||
{
|
return;
|
||||||
if (!playerInventory.containsAtLeast(seedStack, 1)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
playerInventory.removeItem(seedStack);
|
|
||||||
player.updateInventory(); // Needed until replacement available
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerInventory.removeItem(seedStack);
|
||||||
|
player.updateInventory(); // Needed until replacement available
|
||||||
|
|
||||||
new HerbalismBlockUpdaterTask(blockState).runTaskLater(mcMMO.p, 0);
|
new HerbalismBlockUpdaterTask(blockState).runTaskLater(mcMMO.p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processGrowingPlants(BlockState blockState, BlockBreakEvent blockBreakEvent, boolean greenTerra) {
|
private boolean processGrowingPlants(BlockState blockState, Ageable ageable, BlockBreakEvent blockBreakEvent, boolean greenTerra) {
|
||||||
Ageable crops = (Ageable) blockState.getBlockData();
|
//This check is needed
|
||||||
|
if(isBizarreAgeable(ageable)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int finalAge = 0;
|
||||||
int greenThumbStage = getGreenThumbStage();
|
int greenThumbStage = getGreenThumbStage();
|
||||||
|
|
||||||
//Immature plants will start over at 0
|
//Immature plants will start over at 0
|
||||||
if(!isAgeableMature(crops)) {
|
if(!isAgeableMature(ageable)) {
|
||||||
crops.setAge(0);
|
|
||||||
blockBreakEvent.setCancelled(true);
|
blockBreakEvent.setCancelled(true);
|
||||||
|
startReplantTask(0, blockBreakEvent, blockState, true);
|
||||||
|
blockState.setType(Material.AIR);
|
||||||
|
blockState.update();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,10 +760,10 @@ public class HerbalismManager extends SkillManager {
|
|||||||
case WHEAT:
|
case WHEAT:
|
||||||
|
|
||||||
if (greenTerra) {
|
if (greenTerra) {
|
||||||
crops.setAge(3);
|
finalAge = 3;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
crops.setAge(greenThumbStage);
|
finalAge = getGreenThumbStage();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -744,30 +771,32 @@ public class HerbalismManager extends SkillManager {
|
|||||||
case NETHER_WART:
|
case NETHER_WART:
|
||||||
|
|
||||||
if (greenTerra || greenThumbStage > 2) {
|
if (greenTerra || greenThumbStage > 2) {
|
||||||
crops.setAge(2);
|
finalAge = 2;
|
||||||
}
|
}
|
||||||
else if (greenThumbStage == 2) {
|
else if (greenThumbStage == 2) {
|
||||||
crops.setAge(1);
|
finalAge = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
crops.setAge(0);
|
finalAge = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COCOA:
|
case COCOA:
|
||||||
|
|
||||||
if (greenTerra || getGreenThumbStage() > 1) {
|
if (greenTerra || getGreenThumbStage() > 1) {
|
||||||
crops.setAge(1);
|
finalAge = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
crops.setAge(0);
|
finalAge = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
blockState.setBlockData(crops);
|
|
||||||
|
//Start the delayed replant
|
||||||
|
startReplantTask(finalAge, blockBreakEvent, blockState, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.gmail.nossr50.util.skills;
|
package com.gmail.nossr50.util.skills;
|
||||||
|
|
||||||
import com.gmail.nossr50.config.Config;
|
import com.gmail.nossr50.config.Config;
|
||||||
|
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||||
|
import com.gmail.nossr50.util.sounds.SoundType;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -14,6 +16,12 @@ public final class ParticleEffectUtils {
|
|||||||
|
|
||||||
private ParticleEffectUtils() {};
|
private ParticleEffectUtils() {};
|
||||||
|
|
||||||
|
public static void playGreenThumbEffect(Location location) {
|
||||||
|
World world = location.getWorld();
|
||||||
|
playSmokeEffect(location);
|
||||||
|
SoundManager.worldSendSoundMaxPitch(world, location, SoundType.POP);
|
||||||
|
}
|
||||||
|
|
||||||
public static void playBleedEffect(LivingEntity livingEntity) {
|
public static void playBleedEffect(LivingEntity livingEntity) {
|
||||||
if (!Config.getInstance().getBleedEffectEnabled()) {
|
if (!Config.getInstance().getBleedEffectEnabled()) {
|
||||||
return;
|
return;
|
||||||
@ -27,7 +35,7 @@ public final class ParticleEffectUtils {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
playSmokeEffect(player);
|
playSmokeEffect(player.getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void playFluxEffect(Location location) {
|
public static void playFluxEffect(Location location) {
|
||||||
@ -38,9 +46,8 @@ public final class ParticleEffectUtils {
|
|||||||
location.getWorld().playEffect(location, Effect.MOBSPAWNER_FLAMES, 1);
|
location.getWorld().playEffect(location, Effect.MOBSPAWNER_FLAMES, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void playSmokeEffect(LivingEntity livingEntity) {
|
public static void playSmokeEffect(Location location) {
|
||||||
Location location = livingEntity.getEyeLocation();
|
World world = location.getWorld();
|
||||||
World world = livingEntity.getWorld();
|
|
||||||
|
|
||||||
// Have to do it this way, because not all block directions are valid for smoke
|
// Have to do it this way, because not all block directions are valid for smoke
|
||||||
world.playEffect(location, Effect.SMOKE, BlockFace.SOUTH_EAST);
|
world.playEffect(location, Effect.SMOKE, BlockFace.SOUTH_EAST);
|
||||||
|
@ -39,6 +39,11 @@ public class SoundManager {
|
|||||||
world.playSound(location, getSound(soundType), getVolume(soundType), getPitch(soundType));
|
world.playSound(location, getSound(soundType), getVolume(soundType), getPitch(soundType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void worldSendSoundMaxPitch(World world, Location location, SoundType soundType) {
|
||||||
|
if(SoundConfig.getInstance().getIsEnabled(soundType))
|
||||||
|
world.playSound(location, getSound(soundType), getVolume(soundType), 2.0F);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All volume is multiplied by the master volume to get its final value
|
* All volume is multiplied by the master volume to get its final value
|
||||||
* @param soundType target soundtype
|
* @param soundType target soundtype
|
||||||
|
Loading…
Reference in New Issue
Block a user