mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-25 22:56:45 +01:00
Fix some bugs with Rupture and fix a small memory leak
This commit is contained in:
parent
002887e244
commit
a2ee4be86a
@ -1,5 +1,7 @@
|
||||
Version 2.1.186
|
||||
Rupture has been reworked to solve a few outstanding issues (see notes)
|
||||
Fixed an exploit involving enchantments (thanks TheBusyBiscuit)
|
||||
Fixed a very small memory leak that would only happen in very rare situations
|
||||
Gore no longer applies Rupture
|
||||
Gore no longer sends a message to the Wolf owner when it triggers
|
||||
Gore no longer sends a message to players that are hit by it
|
||||
@ -27,7 +29,7 @@ Version 2.1.186
|
||||
NOTES:
|
||||
The old Rupture would constantly interfere with your ability to do a Sweep Attack/Swipe with swords, the new one solves this problem
|
||||
Targets will bleed and take "pure" damage while bleeding, this never kills the target. It will reduce them to 0.01 HP.
|
||||
After 5 seconds since your last attack on the target have transpired Rupture "explodes" dealing a large amount of damage, this damage is not pure and is affected by armor etc.
|
||||
After 5 seconds of not applying Rupture on the target Rupture explodes dealing a large amount of damage, this damage is not pure and is affected by armor etc.
|
||||
Rupture no longer tells you that you that you applied it to the target, it should be obvious from the sounds/particle effects
|
||||
The new Rupture no longer constantly interferes with the vanilla Swipe (the AOE attack built into Minecraft)
|
||||
The new Rupture has not had a fine tuned balance pass, I will be balancing it frequently after this patch, it may be too weak or too strong in its current form
|
||||
|
@ -2,7 +2,6 @@ package com.gmail.nossr50.commands.skills;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
|
||||
import com.gmail.nossr50.listeners.InteractionManager;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.gmail.nossr50.commands.skills;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
@ -56,7 +55,7 @@ public class SwordsCommand extends SkillCommand {
|
||||
ruptureExplosionDamageAgainstPlayers = String.valueOf(AdvancedConfig.getInstance().getRuptureExplosionDamage(true, ruptureRank));
|
||||
ruptureExplosionDamageAgainstMobs = String.valueOf(AdvancedConfig.getInstance().getRuptureExplosionDamage(false, ruptureRank));
|
||||
|
||||
ruptureChanceToApply = String.valueOf(AdvancedConfig.getInstance().getRuptureChanceToApplyOnHit(ruptureRank));
|
||||
ruptureChanceToApply = String.valueOf(AdvancedConfig.getInstance().getRuptureChanceToApplyOnHit(ruptureRank) + "%");
|
||||
ruptureChanceToApplyLucky = String.valueOf(AdvancedConfig.getInstance().getRuptureChanceToApplyOnHit(ruptureRank) * 1.33);
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -489,6 +489,10 @@ public class EntityListener implements Listener {
|
||||
if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
|
||||
return;
|
||||
|
||||
if(event.getEntity().hasMetadata(mcMMO.EXPLOSION_FROM_RUPTURE)) {
|
||||
event.getEntity().removeMetadata(mcMMO.EXPLOSION_FROM_RUPTURE, mcMMO.p);
|
||||
}
|
||||
|
||||
if(event.getEntity() instanceof Player)
|
||||
{
|
||||
Player player = (Player) event.getEntity();
|
||||
@ -661,7 +665,7 @@ public class EntityListener implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onEntityDeathLowest(EntityDeathEvent event) {
|
||||
mcMMO.getTransientMetadataTools().cleanAllMobMetadata(event.getEntity());
|
||||
mcMMO.getTransientMetadataTools().cleanAllLivingEntityMetadata(event.getEntity());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -546,6 +546,7 @@ public class PlayerListener implements Listener {
|
||||
|
||||
//Use a sync save if the server is shutting down to avoid race conditions
|
||||
mcMMOPlayer.logout(mcMMO.isServerShutdownExecuted());
|
||||
mcMMO.getTransientMetadataTools().cleanAllLivingEntityMetadata(event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,6 +125,7 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
/* Metadata Values */
|
||||
public static final String REPLANT_META_KEY = "mcMMO: Recently Replanted";
|
||||
public static final String EXPLOSION_FROM_RUPTURE = "mcMMO: Rupture Explosion";
|
||||
public static final String RUPTURE_META_KEY = "mcMMO: RuptureTask";
|
||||
public static final String FISH_HOOK_REF_METAKEY = "mcMMO: Fish Hook Tracker";
|
||||
public static final String DODGE_TRACKER = "mcMMO: Dodge Tracker";
|
||||
|
@ -8,6 +8,7 @@ import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.google.common.base.Objects;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -27,7 +28,7 @@ public class RuptureTask extends BukkitRunnable {
|
||||
public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity, double pureTickDamage, double explosionDamage) {
|
||||
this.ruptureSource = ruptureSource;
|
||||
this.targetEntity = targetEntity;
|
||||
this.expireTick = AdvancedConfig.getInstance().getRuptureDurationSeconds(targetEntity instanceof Player);
|
||||
this.expireTick = AdvancedConfig.getInstance().getRuptureDurationSeconds(targetEntity instanceof Player) * 20;
|
||||
|
||||
this.ruptureTick = 0;
|
||||
this.damageTickTracker = 0;
|
||||
@ -44,12 +45,10 @@ public class RuptureTask extends BukkitRunnable {
|
||||
|
||||
//Rupture hasn't ended yet
|
||||
if(ruptureTick < expireTick) {
|
||||
|
||||
//Is it time to damage?
|
||||
if(damageTickTracker >= DAMAGE_TICK_INTERVAL) {
|
||||
damageTickTracker = 0; //Reset
|
||||
ParticleEffectUtils.playBleedEffect(targetEntity); //Animate
|
||||
double finalDamage = 0; //Used for mob health bars and setting last damage
|
||||
|
||||
if(targetEntity.getHealth() > 0.01) {
|
||||
double healthBeforeRuptureIsApplied = targetEntity.getHealth();
|
||||
@ -59,22 +58,9 @@ public class RuptureTask extends BukkitRunnable {
|
||||
mcMMO.p.getLogger().severe("DEBUG: Miscalculating Rupture tick damage");
|
||||
} else {
|
||||
targetEntity.setHealth(damagedHealth); //Hurt entity without the unwanted side effects of damage()
|
||||
|
||||
//TODO: Do we need to set last damage? Double check
|
||||
finalDamage = healthBeforeRuptureIsApplied - targetEntity.getHealth();
|
||||
|
||||
if(finalDamage <= 0) {
|
||||
mcMMO.p.getLogger().severe("DEBUG: Miscalculating final damage for Rupture");
|
||||
} else {
|
||||
//Actually should this even be done?
|
||||
targetEntity.setLastDamage(finalDamage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Update Health bars
|
||||
MobHealthbarUtils.handleMobHealthbars(targetEntity, finalDamage, mcMMO.p);
|
||||
}
|
||||
} else {
|
||||
explode();
|
||||
}
|
||||
@ -84,8 +70,15 @@ public class RuptureTask extends BukkitRunnable {
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshRupture() {
|
||||
damageTickTracker = DAMAGE_TICK_INTERVAL;
|
||||
ruptureTick = 0;
|
||||
}
|
||||
|
||||
public void explode() {
|
||||
ParticleEffectUtils.playBleedEffect(targetEntity); //Animate
|
||||
targetEntity.setMetadata(mcMMO.EXPLOSION_FROM_RUPTURE, new FixedMetadataValue(mcMMO.p, "null"));
|
||||
|
||||
ParticleEffectUtils.playGreaterImpactEffect(targetEntity); //Animate
|
||||
|
||||
if(ruptureSource.getPlayer() != null && ruptureSource.getPlayer().isValid()) {
|
||||
targetEntity.damage(getExplosionDamage(), ruptureSource.getPlayer());
|
||||
@ -94,6 +87,7 @@ public class RuptureTask extends BukkitRunnable {
|
||||
}
|
||||
|
||||
targetEntity.removeMetadata(mcMMO.RUPTURE_META_KEY, mcMMO.p);
|
||||
|
||||
this.cancel(); //Task no longer needed
|
||||
}
|
||||
|
||||
|
@ -63,19 +63,20 @@ public class SwordsManager extends SkillManager {
|
||||
*
|
||||
* @param target The defending entity
|
||||
*/
|
||||
public void processRupture(@NotNull LivingEntity target) throws IllegalStateException {
|
||||
if(target.hasMetadata(mcMMO.REPLANT_META_KEY)) {
|
||||
public void processRupture(@NotNull LivingEntity target) {
|
||||
if(target.hasMetadata(mcMMO.RUPTURE_META_KEY)) {
|
||||
RuptureTaskMeta ruptureTaskMeta = (RuptureTaskMeta) target.getMetadata(mcMMO.RUPTURE_META_KEY);
|
||||
|
||||
if(mmoPlayer.isDebugMode()) {
|
||||
mmoPlayer.getPlayer().sendMessage("Rupture task ongoing for target " + target.toString());
|
||||
RuptureTaskMeta ruptureTaskMeta = (RuptureTaskMeta) target.getMetadata(mcMMO.RUPTURE_META_KEY);
|
||||
RuptureTask ruptureTask = (RuptureTask) target.getMetadata(mcMMO.RUPTURE_META_KEY);
|
||||
mmoPlayer.getPlayer().sendMessage(ruptureTask.toString());
|
||||
mmoPlayer.getPlayer().sendMessage(ruptureTaskMeta.getRuptureTimerTask().toString());
|
||||
}
|
||||
|
||||
ruptureTaskMeta.getRuptureTimerTask().refreshRupture();
|
||||
return; //Don't apply bleed
|
||||
}
|
||||
|
||||
if (RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.SWORDS_RUPTURE, getPlayer())) {
|
||||
if (RandomChanceUtil.rollDice(AdvancedConfig.getInstance().getRuptureChanceToApplyOnHit(getRuptureRank()), 100)) {
|
||||
|
||||
if (target instanceof Player) {
|
||||
Player defender = (Player) target;
|
||||
|
@ -131,7 +131,7 @@ public final class MobHealthbarUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
int coloredDisplay = (int) Math.ceil(fullDisplay * (healthPercentage / 100.0D));
|
||||
int coloredDisplay = (int) Math.max(Math.ceil(fullDisplay * (healthPercentage / 100.0D)), 0.5);
|
||||
int grayDisplay = fullDisplay - coloredDisplay;
|
||||
|
||||
StringBuilder healthbar = new StringBuilder(color + "");
|
||||
|
@ -2,16 +2,17 @@ package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TransientMetadataTools {
|
||||
public static final String OLD_NAME_METAKEY = TransientMetadataTools.OLD_NAME_METAKEY;
|
||||
private final mcMMO pluginRef;
|
||||
|
||||
public TransientMetadataTools(mcMMO pluginRef) {
|
||||
public TransientMetadataTools(@NotNull mcMMO pluginRef) {
|
||||
this.pluginRef = pluginRef;
|
||||
}
|
||||
|
||||
public void cleanAllMobMetadata(LivingEntity livingEntity) {
|
||||
public void cleanAllLivingEntityMetadata(@NotNull LivingEntity livingEntity) {
|
||||
//Since its not written anywhere, apparently the GC won't touch objects with metadata still present on them
|
||||
if (livingEntity.hasMetadata(mcMMO.customNameKey)) {
|
||||
livingEntity.setCustomName(livingEntity.getMetadata(mcMMO.customNameKey).get(0).asString());
|
||||
@ -33,10 +34,13 @@ public class TransientMetadataTools {
|
||||
livingEntity.removeMetadata(mcMMO.travelingBlock, pluginRef);
|
||||
}
|
||||
|
||||
if(livingEntity.hasMetadata(mcMMO.REPLANT_META_KEY)) {
|
||||
livingEntity.removeMetadata(mcMMO.REPLANT_META_KEY, pluginRef);
|
||||
if(livingEntity.hasMetadata(mcMMO.RUPTURE_META_KEY)) {
|
||||
livingEntity.removeMetadata(mcMMO.RUPTURE_META_KEY, pluginRef);
|
||||
}
|
||||
|
||||
if(livingEntity.hasMetadata(mcMMO.EXPLOSION_FROM_RUPTURE)) {
|
||||
livingEntity.removeMetadata(mcMMO.EXPLOSION_FROM_RUPTURE, pluginRef);
|
||||
}
|
||||
|
||||
//Cleanup mob metadata
|
||||
mcMMO.getCompatibilityManager().getPersistentDataLayer().removeMobFlags(livingEntity);
|
||||
|
@ -12,6 +12,7 @@ import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
|
||||
import com.gmail.nossr50.events.fake.FakeEntityDamageEvent;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.party.PartyManager;
|
||||
import com.gmail.nossr50.runnables.skills.AwardCombatXpTask;
|
||||
import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
|
||||
import com.gmail.nossr50.skills.archery.ArcheryManager;
|
||||
import com.gmail.nossr50.skills.axes.AxesManager;
|
||||
@ -40,7 +41,6 @@ import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import com.gmail.nossr50.runnables.skills.AwardCombatXpTask;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
@ -93,8 +93,7 @@ public final class CombatUtils {
|
||||
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.SWORDS);
|
||||
}
|
||||
|
||||
if(target.getHealth() - event.getFinalDamage() >= 1)
|
||||
{
|
||||
if(target.getHealth() - event.getFinalDamage() > 0) {
|
||||
if (swordsManager.canUseRupture()) {
|
||||
swordsManager.processRupture(target);
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
package com.gmail.nossr50.util.skills;
|
||||
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import org.apache.commons.lang.math.RandomUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class ParticleEffectUtils {
|
||||
|
||||
private ParticleEffectUtils() {}
|
||||
|
Loading…
Reference in New Issue
Block a user