diff --git a/Changelog.txt b/Changelog.txt index 0a9564627..c2e983976 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -19,6 +19,7 @@ Version 1.4.06-dev + Added new permission node for /ptp; mcmmo.commands.ptp.send (enabled by default) + Added configurable cooldown and warmup times when using /ptp + Added a new Party item share category "Misc" which contains a list of configurable items. (By default all tools and armor) + + Added fishing exploit prevention = Fixed bug where players were able to join the same party multiple times = Fixed displaying partial names when trying to use /ptp = Fixed wolves from Call of the Wild only having 8 health diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index a4098014a..fd02f32ab 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -177,6 +177,12 @@ public class PlayerListener implements Listener { switch (event.getState()) { case FISHING: + event.setCancelled(fishingManager.exploitPrevention()); + + if (event.isCancelled()) { + return; + } + if (fishingManager.canMasterAngler()) { fishingManager.masterAngler(event.getHook()); } diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/KrakenAttackTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/KrakenAttackTask.java new file mode 100644 index 000000000..4c6475c51 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/runnables/skills/KrakenAttackTask.java @@ -0,0 +1,28 @@ +package com.gmail.nossr50.runnables.skills; + +import org.bukkit.entity.Player; +import org.bukkit.entity.Squid; +import org.bukkit.scheduler.BukkitRunnable; + +public class KrakenAttackTask extends BukkitRunnable { + private Squid kraken; + private Player player; + + public KrakenAttackTask(Squid kraken, Player player) { + this.kraken = kraken; + this.player = player; + } + + @Override + public void run() { + if (!player.isDead()) { + kraken.teleport(player); + player.damage(1, kraken); + player.getWorld().strikeLightningEffect(player.getLocation()); + } + else { + kraken.remove(); + this.cancel(); + } + } +} 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 7664c3f83..b74e955f1 100644 --- a/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java +++ b/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java @@ -4,12 +4,17 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.WeatherType; +import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Fish; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; @@ -17,7 +22,9 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Sheep; import org.bukkit.entity.Skeleton; import org.bukkit.entity.Skeleton.SkeletonType; +import org.bukkit.entity.Squid; import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.ItemStack; import com.gmail.nossr50.mcMMO; @@ -30,6 +37,7 @@ import com.gmail.nossr50.datatypes.treasure.FishingTreasure; import com.gmail.nossr50.datatypes.treasure.ShakeTreasure; import com.gmail.nossr50.events.fake.FakePlayerFishEvent; import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.runnables.skills.KrakenAttackTask; import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.skills.fishing.Fishing.Tier; import com.gmail.nossr50.util.ItemUtils; @@ -39,10 +47,23 @@ import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.SkillUtils; public class FishingManager extends SkillManager { + private final long FISHING_COOLDOWN_SECONDS = 5000L; + + private int fishingTries = 1; + private long fishingTimestamp = 0L; + public FishingManager(McMMOPlayer mcMMOPlayer) { super(mcMMOPlayer, SkillType.FISHING); } + public void incrementTries() { + fishingTries++; + } + + public void setTimestamp() { + fishingTimestamp = (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR); + } + public boolean canShake(Entity target) { return target instanceof LivingEntity && getSkillLevel() >= AdvancedConfig.getInstance().getShakeUnlockLevel() && Permissions.shake(getPlayer()); } @@ -51,6 +72,45 @@ public class FishingManager extends SkillManager { return Permissions.masterAngler(getPlayer()); } + private boolean unleashTheKraken() { + if (fishingTries < 50 || fishingTries <= Misc.getRandom().nextInt(200)) { + return false; + } + + Player player = getPlayer(); + World world = player.getWorld(); + + player.setPlayerWeather(WeatherType.DOWNFALL); + player.teleport(player.getTargetBlock(null, 100).getLocation(), TeleportCause.PLUGIN); + + Location location = player.getLocation(); + + world.strikeLightningEffect(location); + world.strikeLightningEffect(location); + world.strikeLightningEffect(location); + player.sendMessage("THE KRAKEN HAS BEEN UNLEASHED!"); + mcMMO.p.getServer().broadcastMessage(player.getDisplayName() + ChatColor.RED + "has unleashed the kraken!"); + + Squid kraken = (Squid) world.spawnEntity(player.getEyeLocation(), EntityType.SQUID); + kraken.setCustomName("The Kraken"); + kraken.setMaxHealth(kraken.getMaxHealth() * 5); + kraken.setHealth(kraken.getMaxHealth()); + player.setItemInHand(null); + + new KrakenAttackTask(kraken, player).runTaskTimer(mcMMO.p, 20L, 20L); + fishingTries = 1; + return true; + } + + public boolean exploitPrevention() { + long currentTime = System.currentTimeMillis(); + boolean hasFished = currentTime < fishingTimestamp + FISHING_COOLDOWN_SECONDS; + + fishingTries = hasFished ? fishingTries + 1 : fishingTries - 1; + fishingTimestamp = currentTime; + return unleashTheKraken(); + } + public boolean canIceFish(Block block) { if (getSkillLevel() < AdvancedConfig.getInstance().getIceFishingUnlockLevel()) { return false; diff --git a/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java b/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java index 5845af8d8..e22eec8d3 100644 --- a/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java +++ b/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java @@ -50,6 +50,14 @@ public final class MobHealthbarUtils { } String oldName = target.getCustomName(); + + if (oldName == null) { + oldName = ""; + } + else if (oldName.equalsIgnoreCase("The Kraken")) { + return; + } + boolean oldNameVisible = target.isCustomNameVisible(); String newName = createHealthDisplay(profile, target, damage); @@ -59,10 +67,6 @@ public final class MobHealthbarUtils { int displayTime = Config.getInstance().getMobHealthbarTime(); if (displayTime != -1) { - if (oldName == null) { - oldName = ""; - } - boolean updateName = !ChatColor.stripColor(oldName).equalsIgnoreCase(ChatColor.stripColor(newName)); if (updateName) {