diff --git a/Changelog.txt b/Changelog.txt
index a76a4ac60..74d437ad3 100644
--- a/Changelog.txt
+++ b/Changelog.txt
@@ -151,6 +151,20 @@ Version 2.2.0
Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition
Added API method to check if a skill was being level capped
Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill
+Version 2.1.60
+ Fixed a NPE error if a LivingEntity's target was set to null
+ Fixed a bug where tamed mobs could kill themselves if their owner shot them once
+ Corrected a typo when naming entities summoned by COTW (Locale string - Taming.Summon.Name.Format)
+ Fixed a bug where tamed mobs could have hearts instead of their name in their own death messages
+ Fixed a bug where multi-block crops would fail to double/triple drop (Sugar Cane, Cactus, etc)
+ Optimized the bonus drop code to reduce overhead
+
+Version 2.1.59
+ Raised the overfishing limit from 3 to 10
+ Improved the overfishing messages to be more clear about its mechanics
+ Overfishing locale keys renamed "Fishing.ScarcityTip" and "Fishing.LowResourcesTip"
+
+ NOTES: This and other exploit prevention measures are much more customizable in 2.2, which shouldn't be too far off.
Version 2.1.58
Fixed the wrong locale string being used for Mining Double Drops
diff --git a/pom.xml b/pom.xml
index ac3f22fdd..ea719d5b8 100755
--- a/pom.xml
+++ b/pom.xml
@@ -212,7 +212,7 @@
org.spigotmc
spigot-api
- 1.14-R0.1-SNAPSHOT
+ 1.14.1-R0.1-SNAPSHOT
provided
diff --git a/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigSectionExploitFishing.java b/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigSectionExploitFishing.java
index 413d21182..dec972172 100644
--- a/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigSectionExploitFishing.java
+++ b/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigSectionExploitFishing.java
@@ -6,7 +6,7 @@ import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ConfigSerializable
public class ConfigSectionExploitFishing {
- public static final int OVER_FISHING_LIMIT_DEFAULT = 3;
+ public static final int OVER_FISHING_LIMIT_DEFAULT = 10;
public static final boolean ADMINS_OVER_FISHING_DEFAULT = true;
public static final float OVER_FISHING_SIZE = 1.0F;
public static final int FISHING_ROD_SPAM_THRESHOLD_MILLISECONDS_DEFAULT = 200;
diff --git a/src/main/java/com/gmail/nossr50/datatypes/meta/BonusDropMeta.java b/src/main/java/com/gmail/nossr50/datatypes/meta/BonusDropMeta.java
index bef3090bc..a9d093a56 100644
--- a/src/main/java/com/gmail/nossr50/datatypes/meta/BonusDropMeta.java
+++ b/src/main/java/com/gmail/nossr50/datatypes/meta/BonusDropMeta.java
@@ -11,4 +11,4 @@ public class BonusDropMeta extends FixedMetadataValue {
public BonusDropMeta(int value, mcMMO plugin) {
super(plugin, value);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
index 5e6c5c672..a2462b266 100644
--- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
@@ -65,7 +65,6 @@ public class BlockListener implements Listener {
if (!mcMMO.getDynamicSettingsManager().getBonusDropManager().isBonusDropWhitelisted(is.getType()))
continue;
- //TODO: Should just store the amount of drops in the metadata itself and use a loop
if (event.getBlock().getMetadata(MetadataConstants.BONUS_DROPS_METAKEY).size() > 0) {
BonusDropMeta bonusDropMeta = (BonusDropMeta) event.getBlock().getMetadata(MetadataConstants.BONUS_DROPS_METAKEY).get(0);
int bonusCount = bonusDropMeta.asInt();
@@ -79,6 +78,30 @@ public class BlockListener implements Listener {
}
}
+ /*@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onBlockDropItemEvent(BlockDropItemEvent event)
+ {
+ for(Item item : event.getItems())
+ {
+ ItemStack is = new ItemStack(item.getItemStack());
+
+ if(event.getBlock().getMetadata(mcMMO.doubleDrops).size() > 0)
+ {
+ List metadataValue = event.getBlock().getMetadata(mcMMO.doubleDrops);
+
+ BonusDrops bonusDrops = (BonusDrops) metadataValue.get(0);
+ Collection potentialDrops = (Collection) bonusDrops.value();
+>>>>>>> 2746bac86ac8b201960ac47bc19eac4b84d790a0
+
+ for (int i = 0; i < bonusCount; i++) {
+ event.getBlock().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
+ }
+
+ event.getBlock().removeMetadata(MetadataConstants.BONUS_DROPS_METAKEY, plugin);
+ }
+ }
+ }
+
/**
* Monitor BlockPistonExtend events.
*
diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java
index c1a973f2c..eb84dc37d 100644
--- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java
@@ -3,7 +3,6 @@ package com.gmail.nossr50.listeners;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.WorldBlacklist;
import com.gmail.nossr50.core.MetadataConstants;
-import com.gmail.nossr50.datatypes.meta.OldName;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.InteractType;
@@ -38,13 +37,10 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.metadata.FixedMetadataValue;
-import org.bukkit.metadata.MetadataValue;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.projectiles.ProjectileSource;
-import java.util.List;
-
public class EntityListener implements Listener {
private final mcMMO plugin;
@@ -67,6 +63,12 @@ public class EntityListener implements Listener {
if (!mcMMO.getConfigManager().getConfigExploitPrevention().getEndermenEndermiteFix())
return;
+ //It's rare but targets can be null sometimes
+ if(event.getTarget() == null)
+ {
+ return;
+ }
+
//Prevent entities from giving XP if they target endermite
if (event.getTarget() instanceof Endermite) {
if (event.getEntity().getMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY) == null || event.getEntity().getMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY).size() <= 0)
@@ -363,21 +365,15 @@ public class EntityListener implements Listener {
/**
* This sets entity names back to whatever they are supposed to be
*/
- if (!(attacker instanceof Player) && defender instanceof Player) {
- if (event.getFinalDamage() >= ((LivingEntity) defender).getHealth()) {
- List metadataValue = attacker.getMetadata("mcMMO_oldName");
-
- if (metadataValue.size() <= 0)
- return;
-
- if (metadataValue != null) {
- OldName oldName = (OldName) metadataValue.get(0);
- attacker.setCustomName(oldName.asString());
- attacker.setCustomNameVisible(false);
- }
+ if(event.getFinalDamage() >= target.getHealth())
+ {
+ if(attacker instanceof LivingEntity)
+ {
+ CombatUtils.fixNames((LivingEntity) attacker);
}
- }
+ CombatUtils.fixNames(target);
+ }
}
diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
index fdf827f62..6a0399279 100644
--- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
@@ -382,7 +382,7 @@ public class PlayerListener implements Listener {
case CAUGHT_FISH:
if (mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitFishing().isPreventFishingExploits()) {
if (fishingManager.isExploitingFishing(event.getHook().getLocation().toVector())) {
- player.sendMessage(LocaleLoader.getString("Fishing.Scarcity"));
+ player.sendMessage(LocaleLoader.getString("Fishing.ScarcityTip", mcMMO.getConfigManager().getConfigExploitPrevention().getOverFishingAreaSize() * 2));
event.setExpToDrop(0);
Item caughtItem = (Item) caught;
caughtItem.remove();
diff --git a/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java b/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java
index f472e03bb..01fb40b5e 100644
--- a/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java
@@ -48,6 +48,10 @@ public class FishingManager extends SkillManager {
private long fishHookSpawnTimestamp;
private long lastWarned;
private long lastWarnedExhaust;
+ public static final int FISHING_ROD_CAST_CD_MILLISECONDS = 100;
+ private final long FISHING_COOLDOWN_SECONDS = 1000L;
+
+ private FishHook fishHookReference;
private BoundingBox lastFishingBoundingBox;
private Location hookLocation;
private int fishCaughtCounter;
@@ -130,7 +134,7 @@ public class FishingManager extends SkillManager {
fishCaughtCounter = 1;
if (fishCaughtCounter + 1 == overfishLimit) {
- getPlayer().sendMessage(LocaleLoader.getString("Fishing.LowResources"));
+ getPlayer().sendMessage(LocaleLoader.getString("Fishing.LowResourcesTip", mcMMO.getConfigManager().getConfigExploitPrevention().getOverFishingAreaSize() * 2));
}
//If the new bounding box does not intersect with the old one, then update our bounding box reference
diff --git a/src/main/java/com/gmail/nossr50/skills/herbalism/Herbalism.java b/src/main/java/com/gmail/nossr50/skills/herbalism/Herbalism.java
index 89a1ea8f5..0dcd991a4 100644
--- a/src/main/java/com/gmail/nossr50/skills/herbalism/Herbalism.java
+++ b/src/main/java/com/gmail/nossr50/skills/herbalism/Herbalism.java
@@ -85,7 +85,9 @@ public class Herbalism {
protected static int countAndMarkDoubleDropsMultiBlockPlant(BlockState blockState, boolean triple, HerbalismManager herbalismManager) {
Block block = blockState.getBlock();
Material blockType = blockState.getType();
- int dropAmount = mcMMO.getPlaceStore().isTrue(block) ? 0 : 1;
+ int dropAmount = 0;
+ int bonusDropAmount = 0;
+ int bonusAdd = triple ? 2 : 1;
if (blockType == Material.CHORUS_PLANT) {
dropAmount = 1;
@@ -94,6 +96,17 @@ public class Herbalism {
dropAmount = calculateChorusPlantDrops(block, triple, herbalismManager);
}
} else {
+ //Check the block itself first
+ if(!mcMMO.getPlaceStore().isTrue(block))
+ {
+ dropAmount++;
+
+ if(herbalismManager.checkDoubleDrop(blockState))
+ bonusDropAmount+=bonusAdd;
+ } else {
+ mcMMO.getPlaceStore().setFalse(blockState);
+ }
+
// Handle the two blocks above it - cacti & sugar cane can only grow 3 high naturally
for (int y = 1; y < 255; y++) {
Block relativeBlock = block.getRelative(BlockFace.UP, y);
@@ -107,12 +120,15 @@ public class Herbalism {
} else {
dropAmount++;
- if (herbalismManager.checkDoubleDrop(relativeBlock.getState()))
- BlockUtils.markDropsAsBonus(relativeBlock.getState(), triple);
+ if(herbalismManager.checkDoubleDrop(relativeBlock.getState()))
+ bonusDropAmount+=bonusAdd;
}
}
}
+ //Mark the original block for bonus drops
+ BlockUtils.markDropsAsBonus(blockState, bonusDropAmount);
+
return dropAmount;
}
diff --git a/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java b/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
index 240e18d07..a5cc882df 100644
--- a/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
@@ -249,6 +249,14 @@ public class TamingManager extends SkillManager {
}
public void attackTarget(LivingEntity target) {
+ if(target instanceof Tameable)
+ {
+ Tameable tameable = (Tameable) target;
+ if(tameable.getOwner() == getPlayer())
+ {
+ return;
+ }
+ }
double range = 5;
Player player = getPlayer();
@@ -299,36 +307,36 @@ public class TamingManager extends SkillManager {
}
location = Misc.getLocationOffset(location, 1);
- LivingEntity entity = (LivingEntity) player.getWorld().spawnEntity(location, type);
+ LivingEntity callOfWildEntity = (LivingEntity) player.getWorld().spawnEntity(location, type);
- FakeEntityTameEvent event = new FakeEntityTameEvent(entity, player);
+ FakeEntityTameEvent event = new FakeEntityTameEvent(callOfWildEntity, player);
mcMMO.p.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
continue;
}
- entity.setMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY, MetadataConstants.metadataValue);
- ((Tameable) entity).setOwner(player);
- entity.setRemoveWhenFarAway(false);
+ callOfWildEntity.setMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY, MetadataConstants.metadataValue);
+ ((Tameable) callOfWildEntity).setOwner(player);
+ callOfWildEntity.setRemoveWhenFarAway(false);
- addToTracker(entity);
+ addToTracker(callOfWildEntity);
switch (type) {
case OCELOT:
- ((Ocelot) entity).setCatType(Ocelot.Type.values()[1 + Misc.getRandom().nextInt(3)]);
+ ((Ocelot) callOfWildEntity).setCatType(Ocelot.Type.values()[1 + Misc.getRandom().nextInt(3)]);
break;
case WOLF:
- entity.setMaxHealth(20.0);
- entity.setHealth(entity.getMaxHealth());
+ callOfWildEntity.setMaxHealth(20.0);
+ callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
break;
case HORSE:
- Horse horse = (Horse) entity;
+ Horse horse = (Horse) callOfWildEntity;
- entity.setMaxHealth(15.0 + (Misc.getRandom().nextDouble() * 15));
- entity.setHealth(entity.getMaxHealth());
+ callOfWildEntity.setMaxHealth(15.0 + (Misc.getRandom().nextDouble() * 15));
+ callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
horse.setColor(Horse.Color.values()[Misc.getRandom().nextInt(Horse.Color.values().length)]);
horse.setStyle(Horse.Style.values()[Misc.getRandom().nextInt(Horse.Style.values().length)]);
horse.setJumpStrength(Math.max(AdvancedConfig.getInstance().getMinHorseJumpStrength(), Math.min(Math.min(Misc.getRandom().nextDouble(), Misc.getRandom().nextDouble()) * 2, AdvancedConfig.getInstance().getMaxHorseJumpStrength())));
@@ -340,10 +348,10 @@ public class TamingManager extends SkillManager {
}
if (Permissions.renamePets(player)) {
- entity.setCustomName(LocaleLoader.getString("Taming.Summon.Name.Format", player.getName(), StringUtils.getPrettyEntityTypeString(type)));
+ callOfWildEntity.setCustomName(LocaleLoader.getString("Taming.Summon.Name.Format", player.getName(), StringUtils.getPrettyEntityTypeString(type)));
}
- ParticleEffectUtils.playCallOfTheWildEffect(entity);
+ ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
}
ItemStack leftovers = new ItemStack(heldItem);
diff --git a/src/main/java/com/gmail/nossr50/util/BlockUtils.java b/src/main/java/com/gmail/nossr50/util/BlockUtils.java
index 519a0dc74..cffb992a2 100644
--- a/src/main/java/com/gmail/nossr50/util/BlockUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/BlockUtils.java
@@ -35,6 +35,15 @@ public final class BlockUtils {
blockState.setMetadata(MetadataConstants.BONUS_DROPS_METAKEY, new BonusDropMeta(1, mcMMO.p));
}
+ /**
+ * Marks a block to drop extra copies of items
+ * @param blockState target blockstate
+ * @param amount amount of extra items to drop
+ */
+ public static void markDropsAsBonus(BlockState blockState, int amount) {
+ blockState.setMetadata(MetadataConstants.BONUS_DROPS_METAKEY, new BonusDropMeta(amount, mcMMO.p));
+ }
+
/**
* Checks if a player successfully passed the double drop check
*
diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
index cdbfedd98..a7030ef78 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
@@ -4,6 +4,7 @@ import com.gmail.nossr50.core.MetadataConstants;
import com.gmail.nossr50.datatypes.experience.SpecialXPKey;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
+import com.gmail.nossr50.datatypes.meta.OldName;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
@@ -31,10 +32,12 @@ import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDamageEvent.DamageModifier;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.metadata.MetadataValue;
import org.bukkit.projectiles.ProjectileSource;
import java.util.EnumMap;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public final class CombatUtils {
@@ -347,6 +350,25 @@ public final class CombatUtils {
}
}
+ /**
+ * This cleans up names from displaying in chat as hearts
+ * @param entity target entity
+ */
+ public static void fixNames(LivingEntity entity)
+ {
+ List metadataValue = entity.getMetadata("mcMMO_oldName");
+
+ if(metadataValue.size() <= 0)
+ return;
+
+ if(metadataValue != null)
+ {
+ OldName oldName = (OldName) metadataValue.get(0);
+ entity.setCustomName(oldName.asString());
+ entity.setCustomNameVisible(false);
+ }
+ }
+
public static int getLimitBreakDamage(Player player, SubSkillType subSkillType) {
return RankUtils.getRank(player, subSkillType);
}
diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties
index 9e3ac26f8..41e632757 100644
--- a/src/main/resources/locale/locale_en_US.properties
+++ b/src/main/resources/locale/locale_en_US.properties
@@ -215,11 +215,11 @@ Excavation.Skills.GigaDrillBreaker.Refresh=[[GREEN]]Your [[YELLOW]]Giga Drill Br
Excavation.Skills.GigaDrillBreaker.Other.Off=Giga Drill Breaker[[GREEN]] has worn off for [[YELLOW]]{0}
Excavation.Skills.GigaDrillBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Giga Drill Breaker!
#FISHING
-Fishing.Scarcity=[[YELLOW]]&oThis area is suffering from overfishing, try fishing in a new area.
+Fishing.ScarcityTip=[[YELLOW]]&oThis area is suffering from overfishing, cast your rod in a different spot for more fish. At least {0} blocks away.
Fishing.Scared=[[GRAY]]&oChaotic movements will scare fish!
Fishing.Exhausting=[[RED]]&oImproper use of the fishing rod will cause fatigue and wear out the rod!
-Fishing.LowResources=[[GRAY]]You sense that there might not be many fish left in this area.
Fishing.OverFishingDetected=[[YELLOW]]Player named &r{0}[[YELLOW]]has over-fished three times in a row at the same location, potential abuse detected.
+Fishing.LowResourcesTip=[[GRAY]]You sense that there might not be many fish left in this area. Try fishing at least {0} blocks away.
Fishing.Ability.Info=Magic Hunter: [[GRAY]] **Improves With Treasure Hunter Rank**
Fishing.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (SHAKE)
Fishing.Ability.Locked.1=LOCKED UNTIL {0}+ SKILL (ICE FISHING)
@@ -474,7 +474,7 @@ Taming.Summon.Fail.Ocelot=[[RED]]You have too many ocelots nearby to summon any
Taming.Summon.Fail.Wolf=[[RED]]You have too many wolves nearby to summon any more.
Taming.Summon.Fail.Horse=[[RED]]You have too many horses nearby to summon any more.
Taming.Summon.Fail.TooMany=[[RED]]You have reached the maximum limit of pets to summon. [[YELLOW]]({0})
-Taming.Summon.Name.Format={0}''s {1}
+Taming.Summon.Name.Format={0}'s {1}
#UNARMED
Unarmed.Ability.Bonus.0=Iron Arm Style
Unarmed.Ability.Bonus.1=+{0} DMG Upgrade