mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-08-02 12:35:27 +02:00
Rupture has been reworked
This commit is contained in:
@@ -1,214 +1,214 @@
|
||||
package com.gmail.nossr50.runnables.skills;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||
import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.MobHealthbarUtils;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class BleedTimerTask extends BukkitRunnable {
|
||||
private static final @NotNull Map<LivingEntity, BleedContainer> bleedList = new HashMap<>();
|
||||
private static boolean isIterating = false;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
isIterating = true;
|
||||
Iterator<Entry<LivingEntity, BleedContainer>> bleedIterator = bleedList.entrySet().iterator();
|
||||
|
||||
while (bleedIterator.hasNext()) {
|
||||
Entry<LivingEntity, BleedContainer> containerEntry = bleedIterator.next();
|
||||
LivingEntity target = containerEntry.getKey();
|
||||
int toolTier = containerEntry.getValue().toolTier;
|
||||
|
||||
// String debugMessage = "";
|
||||
// debugMessage += ChatColor.GOLD + "Target ["+target.getName()+"]: " + ChatColor.RESET;
|
||||
|
||||
// debugMessage+="RemainingTicks=["+containerEntry.getValue().bleedTicks+"], ";
|
||||
|
||||
if (containerEntry.getValue().bleedTicks <= 0 || !target.isValid()) {
|
||||
if(target instanceof Player)
|
||||
{
|
||||
NotificationManager.sendPlayerInformation((Player) target, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding.Stopped");
|
||||
}
|
||||
|
||||
bleedIterator.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
int armorCount = 0;
|
||||
|
||||
double damage;
|
||||
|
||||
if (target instanceof Player) {
|
||||
damage = AdvancedConfig.getInstance().getRuptureDamagePlayer();
|
||||
|
||||
//Above Bleed Rank 3 deals 50% more damage
|
||||
if (containerEntry.getValue().toolTier >= 4 && containerEntry.getValue().bleedRank >= 3)
|
||||
damage = damage * 1.5;
|
||||
|
||||
Player player = (Player) target;
|
||||
|
||||
if (!player.isOnline()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Count Armor
|
||||
for (ItemStack armorPiece : ((Player) target).getInventory().getArmorContents()) {
|
||||
//We only want to count slots that contain armor.
|
||||
if (armorPiece != null) {
|
||||
armorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
damage = AdvancedConfig.getInstance().getRuptureDamageMobs();
|
||||
|
||||
// debugMessage+="BaseDMG=["+damage+"], ";
|
||||
|
||||
//Above Bleed Rank 3 deals 50% more damage
|
||||
if (containerEntry.getValue().bleedRank >= 3)
|
||||
{
|
||||
damage = damage * 1.5;
|
||||
}
|
||||
|
||||
// debugMessage+="Rank4Bonus=["+String.valueOf(containerEntry.getValue().bleedRank >= 3)+"], ";
|
||||
|
||||
|
||||
MobHealthbarUtils.handleMobHealthbars(target, damage, mcMMO.p); //Update health bars
|
||||
}
|
||||
|
||||
// debugMessage+="FullArmor=["+String.valueOf(armorCount > 3)+"], ";
|
||||
|
||||
if(armorCount > 3)
|
||||
{
|
||||
damage = damage * .75;
|
||||
}
|
||||
|
||||
// debugMessage+="AfterRankAndArmorChecks["+damage+"], ";
|
||||
|
||||
//Weapons below Diamond get damage cut in half
|
||||
if(toolTier < 4)
|
||||
damage = damage / 2;
|
||||
|
||||
// debugMessage+="AfterDiamondCheck=["+String.valueOf(damage)+"], ";
|
||||
|
||||
//Wood weapons get damage cut in half again
|
||||
if(toolTier < 2)
|
||||
damage = damage / 2;
|
||||
|
||||
// debugMessage+="AfterWoodenCheck=["+String.valueOf(damage)+"], ";
|
||||
|
||||
double victimHealth = target.getHealth();
|
||||
|
||||
// debugMessage+="TargetHealthBeforeDMG=["+String.valueOf(target.getHealth())+"], ";
|
||||
|
||||
//Fire a fake event
|
||||
FakeEntityDamageByEntityEvent fakeEntityDamageByEntityEvent = (FakeEntityDamageByEntityEvent) CombatUtils.sendEntityDamageEvent(containerEntry.getValue().damageSource, target, EntityDamageEvent.DamageCause.CUSTOM, damage);
|
||||
Bukkit.getPluginManager().callEvent(fakeEntityDamageByEntityEvent);
|
||||
|
||||
CombatUtils.dealNoInvulnerabilityTickDamageRupture(target, damage, containerEntry.getValue().damageSource, toolTier);
|
||||
|
||||
double victimHealthAftermath = target.getHealth();
|
||||
|
||||
// debugMessage+="TargetHealthAfterDMG=["+String.valueOf(target.getHealth())+"], ";
|
||||
|
||||
if(victimHealthAftermath <= 0 || victimHealth != victimHealthAftermath)
|
||||
{
|
||||
//Play Bleed Sound
|
||||
SoundManager.worldSendSound(target.getWorld(), target.getLocation(), SoundType.BLEED);
|
||||
|
||||
ParticleEffectUtils.playBleedEffect(target);
|
||||
}
|
||||
|
||||
//Lower Bleed Ticks
|
||||
BleedContainer loweredBleedContainer = copyContainer(containerEntry.getValue());
|
||||
loweredBleedContainer.bleedTicks -= 1;
|
||||
|
||||
// debugMessage+="RemainingTicks=["+loweredBleedContainer.bleedTicks+"]";
|
||||
containerEntry.setValue(loweredBleedContainer);
|
||||
|
||||
// Bukkit.broadcastMessage(debugMessage);
|
||||
}
|
||||
isIterating = false;
|
||||
}
|
||||
|
||||
public static @NotNull BleedContainer copyContainer(@NotNull BleedContainer container)
|
||||
{
|
||||
LivingEntity target = container.target;
|
||||
LivingEntity source = container.damageSource;
|
||||
int bleedTicks = container.bleedTicks;
|
||||
int bleedRank = container.bleedRank;
|
||||
int toolTier = container.toolTier;
|
||||
|
||||
return new BleedContainer(target, bleedTicks, bleedRank, toolTier, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantly Bleed out a LivingEntity
|
||||
*
|
||||
* @param entity LivingEntity to bleed out
|
||||
*/
|
||||
public static void bleedOut(@NotNull LivingEntity entity) {
|
||||
/*
|
||||
* Don't remove anything from the list outside of run()
|
||||
*/
|
||||
|
||||
if (bleedList.containsKey(entity)) {
|
||||
CombatUtils.dealNoInvulnerabilityTickDamage(entity, bleedList.get(entity).bleedTicks * 2, bleedList.get(entity).damageSource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a LivingEntity to the bleedList if it is not in it.
|
||||
*
|
||||
* @param entity LivingEntity to add
|
||||
* @param attacker source of the bleed/rupture
|
||||
* @param ticks Number of bleeding ticks
|
||||
*/
|
||||
public static void add(@NotNull LivingEntity entity, @NotNull LivingEntity attacker, int ticks, int bleedRank, int toolTier) {
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalStateException("Cannot add bleed task async!");
|
||||
}
|
||||
|
||||
if(isIterating) {
|
||||
//Used to throw an error here, but in reality all we are really doing is preventing concurrency issues from other plugins being naughty and its not really needed
|
||||
//I'm not really a fan of silent errors, but I'm sick of seeing people using crazy enchantments come in and report this "bug"
|
||||
return;
|
||||
}
|
||||
|
||||
// if (isIterating) throw new IllegalStateException("Cannot add task while iterating timers!");
|
||||
|
||||
if(toolTier < 4)
|
||||
ticks = Math.max(1, (ticks / 3));
|
||||
|
||||
ticks+=1;
|
||||
|
||||
BleedContainer newBleedContainer = new BleedContainer(entity, ticks, bleedRank, toolTier, attacker);
|
||||
bleedList.put(entity, newBleedContainer);
|
||||
}
|
||||
|
||||
public static boolean isBleedOperationAllowed() {
|
||||
return !isIterating && Bukkit.isPrimaryThread();
|
||||
}
|
||||
|
||||
public static boolean isBleeding(@NotNull LivingEntity entity) {
|
||||
return bleedList.containsKey(entity);
|
||||
}
|
||||
}
|
||||
//package com.gmail.nossr50.runnables.skills;
|
||||
//
|
||||
//import com.gmail.nossr50.config.AdvancedConfig;
|
||||
//import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||
//import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
|
||||
//import com.gmail.nossr50.mcMMO;
|
||||
//import com.gmail.nossr50.util.MobHealthbarUtils;
|
||||
//import com.gmail.nossr50.util.player.NotificationManager;
|
||||
//import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
//import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
//import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
//import com.gmail.nossr50.util.sounds.SoundType;
|
||||
//import org.bukkit.Bukkit;
|
||||
//import org.bukkit.entity.LivingEntity;
|
||||
//import org.bukkit.entity.Player;
|
||||
//import org.bukkit.event.entity.EntityDamageEvent;
|
||||
//import org.bukkit.inventory.ItemStack;
|
||||
//import org.bukkit.scheduler.BukkitRunnable;
|
||||
//import org.jetbrains.annotations.NotNull;
|
||||
//
|
||||
//import java.util.HashMap;
|
||||
//import java.util.Iterator;
|
||||
//import java.util.Map;
|
||||
//import java.util.Map.Entry;
|
||||
//
|
||||
//public class BleedTimerTask extends BukkitRunnable {
|
||||
// private static final @NotNull Map<LivingEntity, BleedContainer> bleedList = new HashMap<>();
|
||||
// private static boolean isIterating = false;
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// isIterating = true;
|
||||
// Iterator<Entry<LivingEntity, BleedContainer>> bleedIterator = bleedList.entrySet().iterator();
|
||||
//
|
||||
// while (bleedIterator.hasNext()) {
|
||||
// Entry<LivingEntity, BleedContainer> containerEntry = bleedIterator.next();
|
||||
// LivingEntity target = containerEntry.getKey();
|
||||
// int toolTier = containerEntry.getValue().toolTier;
|
||||
//
|
||||
//// String debugMessage = "";
|
||||
//// debugMessage += ChatColor.GOLD + "Target ["+target.getName()+"]: " + ChatColor.RESET;
|
||||
//
|
||||
//// debugMessage+="RemainingTicks=["+containerEntry.getValue().bleedTicks+"], ";
|
||||
//
|
||||
// if (containerEntry.getValue().bleedTicks <= 0 || !target.isValid()) {
|
||||
// if(target instanceof Player)
|
||||
// {
|
||||
// NotificationManager.sendPlayerInformation((Player) target, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Bleeding.Stopped");
|
||||
// }
|
||||
//
|
||||
// bleedIterator.remove();
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// int armorCount = 0;
|
||||
//
|
||||
// double damage;
|
||||
//
|
||||
// if (target instanceof Player) {
|
||||
// damage = AdvancedConfig.getInstance().getRuptureDamagePlayer();
|
||||
//
|
||||
// //Above Bleed Rank 3 deals 50% more damage
|
||||
// if (containerEntry.getValue().toolTier >= 4 && containerEntry.getValue().bleedRank >= 3)
|
||||
// damage = damage * 1.5;
|
||||
//
|
||||
// Player player = (Player) target;
|
||||
//
|
||||
// if (!player.isOnline()) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// //Count Armor
|
||||
// for (ItemStack armorPiece : ((Player) target).getInventory().getArmorContents()) {
|
||||
// //We only want to count slots that contain armor.
|
||||
// if (armorPiece != null) {
|
||||
// armorCount++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } else {
|
||||
// damage = AdvancedConfig.getInstance().getRuptureDamageMobs();
|
||||
//
|
||||
//// debugMessage+="BaseDMG=["+damage+"], ";
|
||||
//
|
||||
// //Above Bleed Rank 3 deals 50% more damage
|
||||
// if (containerEntry.getValue().bleedRank >= 3)
|
||||
// {
|
||||
// damage = damage * 1.5;
|
||||
// }
|
||||
//
|
||||
//// debugMessage+="Rank4Bonus=["+String.valueOf(containerEntry.getValue().bleedRank >= 3)+"], ";
|
||||
//
|
||||
//
|
||||
// MobHealthbarUtils.handleMobHealthbars(target, damage, mcMMO.p); //Update health bars
|
||||
// }
|
||||
//
|
||||
//// debugMessage+="FullArmor=["+String.valueOf(armorCount > 3)+"], ";
|
||||
//
|
||||
// if(armorCount > 3)
|
||||
// {
|
||||
// damage = damage * .75;
|
||||
// }
|
||||
//
|
||||
//// debugMessage+="AfterRankAndArmorChecks["+damage+"], ";
|
||||
//
|
||||
// //Weapons below Diamond get damage cut in half
|
||||
// if(toolTier < 4)
|
||||
// damage = damage / 2;
|
||||
//
|
||||
//// debugMessage+="AfterDiamondCheck=["+String.valueOf(damage)+"], ";
|
||||
//
|
||||
// //Wood weapons get damage cut in half again
|
||||
// if(toolTier < 2)
|
||||
// damage = damage / 2;
|
||||
//
|
||||
//// debugMessage+="AfterWoodenCheck=["+String.valueOf(damage)+"], ";
|
||||
//
|
||||
// double victimHealth = target.getHealth();
|
||||
//
|
||||
//// debugMessage+="TargetHealthBeforeDMG=["+String.valueOf(target.getHealth())+"], ";
|
||||
//
|
||||
// //Fire a fake event
|
||||
// FakeEntityDamageByEntityEvent fakeEntityDamageByEntityEvent = (FakeEntityDamageByEntityEvent) CombatUtils.sendEntityDamageEvent(containerEntry.getValue().damageSource, target, EntityDamageEvent.DamageCause.CUSTOM, damage);
|
||||
// Bukkit.getPluginManager().callEvent(fakeEntityDamageByEntityEvent);
|
||||
//
|
||||
// CombatUtils.dealNoInvulnerabilityTickDamageRupture(target, damage, containerEntry.getValue().damageSource, toolTier);
|
||||
//
|
||||
// double victimHealthAftermath = target.getHealth();
|
||||
//
|
||||
//// debugMessage+="TargetHealthAfterDMG=["+String.valueOf(target.getHealth())+"], ";
|
||||
//
|
||||
// if(victimHealthAftermath <= 0 || victimHealth != victimHealthAftermath)
|
||||
// {
|
||||
// //Play Bleed Sound
|
||||
// SoundManager.worldSendSound(target.getWorld(), target.getLocation(), SoundType.BLEED);
|
||||
//
|
||||
// ParticleEffectUtils.playBleedEffect(target);
|
||||
// }
|
||||
//
|
||||
// //Lower Bleed Ticks
|
||||
// BleedContainer loweredBleedContainer = copyContainer(containerEntry.getValue());
|
||||
// loweredBleedContainer.bleedTicks -= 1;
|
||||
//
|
||||
//// debugMessage+="RemainingTicks=["+loweredBleedContainer.bleedTicks+"]";
|
||||
// containerEntry.setValue(loweredBleedContainer);
|
||||
//
|
||||
//// Bukkit.broadcastMessage(debugMessage);
|
||||
// }
|
||||
// isIterating = false;
|
||||
// }
|
||||
//
|
||||
// public static @NotNull BleedContainer copyContainer(@NotNull BleedContainer container)
|
||||
// {
|
||||
// LivingEntity target = container.target;
|
||||
// LivingEntity source = container.damageSource;
|
||||
// int bleedTicks = container.bleedTicks;
|
||||
// int bleedRank = container.bleedRank;
|
||||
// int toolTier = container.toolTier;
|
||||
//
|
||||
// return new BleedContainer(target, bleedTicks, bleedRank, toolTier, source);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Instantly Bleed out a LivingEntity
|
||||
// *
|
||||
// * @param entity LivingEntity to bleed out
|
||||
// */
|
||||
// public static void bleedOut(@NotNull LivingEntity entity) {
|
||||
// /*
|
||||
// * Don't remove anything from the list outside of run()
|
||||
// */
|
||||
//
|
||||
// if (bleedList.containsKey(entity)) {
|
||||
// CombatUtils.dealNoInvulnerabilityTickDamage(entity, bleedList.get(entity).bleedTicks * 2, bleedList.get(entity).damageSource);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Add a LivingEntity to the bleedList if it is not in it.
|
||||
// *
|
||||
// * @param entity LivingEntity to add
|
||||
// * @param attacker source of the bleed/rupture
|
||||
// * @param ticks Number of bleeding ticks
|
||||
// */
|
||||
// public static void add(@NotNull LivingEntity entity, @NotNull LivingEntity attacker, int ticks, int bleedRank, int toolTier) {
|
||||
// if (!Bukkit.isPrimaryThread()) {
|
||||
// throw new IllegalStateException("Cannot add bleed task async!");
|
||||
// }
|
||||
//
|
||||
// if(isIterating) {
|
||||
// //Used to throw an error here, but in reality all we are really doing is preventing concurrency issues from other plugins being naughty and its not really needed
|
||||
// //I'm not really a fan of silent errors, but I'm sick of seeing people using crazy enchantments come in and report this "bug"
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
//// if (isIterating) throw new IllegalStateException("Cannot add task while iterating timers!");
|
||||
//
|
||||
// if(toolTier < 4)
|
||||
// ticks = Math.max(1, (ticks / 3));
|
||||
//
|
||||
// ticks+=1;
|
||||
//
|
||||
// BleedContainer newBleedContainer = new BleedContainer(entity, ticks, bleedRank, toolTier, attacker);
|
||||
// bleedList.put(entity, newBleedContainer);
|
||||
// }
|
||||
//
|
||||
// public static boolean isBleedOperationAllowed() {
|
||||
// return !isIterating && Bukkit.isPrimaryThread();
|
||||
// }
|
||||
//
|
||||
// public static boolean isBleeding(@NotNull LivingEntity entity) {
|
||||
// return bleedList.containsKey(entity);
|
||||
// }
|
||||
//}
|
||||
|
@@ -0,0 +1,142 @@
|
||||
package com.gmail.nossr50.runnables.skills;
|
||||
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.MobHealthbarUtils;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.google.common.base.Objects;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RuptureTask extends BukkitRunnable {
|
||||
|
||||
public static final int FIVE_SECOND_DURATION = 20 * 5;
|
||||
public static final int DAMAGE_TICK_INTERVAL = 10;
|
||||
|
||||
private final @NotNull McMMOPlayer ruptureSource;
|
||||
private final @NotNull LivingEntity targetEntity;
|
||||
private final int ruptureRank;
|
||||
private final int expireTick;
|
||||
|
||||
private int ruptureTick;
|
||||
private int damageTickTracker;
|
||||
private final double damageValue; //TODO: Make configurable
|
||||
|
||||
public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity, int ruptureRank, double damageValue) {
|
||||
this.ruptureSource = ruptureSource;
|
||||
this.targetEntity = targetEntity;
|
||||
this.ruptureRank = ruptureRank;
|
||||
this.expireTick = FIVE_SECOND_DURATION;
|
||||
this.damageValue = damageValue;
|
||||
|
||||
this.ruptureTick = 0;
|
||||
this.damageTickTracker = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//Check validity
|
||||
if(targetEntity.isValid()) {
|
||||
ruptureTick += 1; //Advance rupture tick by 1.
|
||||
damageTickTracker += 1; //Increment damage tick tracker
|
||||
|
||||
//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
|
||||
|
||||
if(targetEntity.getHealth() > 0.01) {
|
||||
double healthBeforeRuptureIsApplied = targetEntity.getHealth();
|
||||
double damagedHealth = healthBeforeRuptureIsApplied - getTickDamage();
|
||||
|
||||
if(damagedHealth <= 0) {
|
||||
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
|
||||
double finalDamage = healthBeforeRuptureIsApplied - targetEntity.getHealth();
|
||||
|
||||
//Update health bars
|
||||
MobHealthbarUtils.handleMobHealthbars(targetEntity, finalDamage, mcMMO.p);
|
||||
|
||||
if(finalDamage <= 0) {
|
||||
mcMMO.p.getLogger().severe("DEBUG: Miscalculating final damage for Rupture");
|
||||
} else {
|
||||
//Actually should this even be done?
|
||||
targetEntity.setLastDamage(finalDamage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
explode();
|
||||
}
|
||||
} else {
|
||||
targetEntity.removeMetadata(mcMMO.RUPTURE_META_KEY, mcMMO.p);
|
||||
this.cancel(); //Task no longer needed
|
||||
}
|
||||
}
|
||||
|
||||
public void explode() {
|
||||
ParticleEffectUtils.playBleedEffect(targetEntity); //Animate
|
||||
|
||||
if(ruptureSource.getPlayer() != null && ruptureSource.getPlayer().isValid()) {
|
||||
targetEntity.damage(getExplosionDamage(), ruptureSource.getPlayer());
|
||||
} else {
|
||||
targetEntity.damage(getExplosionDamage(), null);
|
||||
}
|
||||
|
||||
targetEntity.removeMetadata(mcMMO.RUPTURE_META_KEY, mcMMO.p);
|
||||
this.cancel(); //Task no longer needed
|
||||
}
|
||||
|
||||
private double getTickDamage() {
|
||||
double tickDamage = damageValue;
|
||||
|
||||
if(targetEntity.getHealth() <= tickDamage) {
|
||||
tickDamage = targetEntity.getHealth() - 0.01;
|
||||
|
||||
if(tickDamage <= 0) {
|
||||
tickDamage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return tickDamage;
|
||||
}
|
||||
|
||||
private int getExplosionDamage() {
|
||||
//TODO: Balance pass
|
||||
return ruptureRank * 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
RuptureTask that = (RuptureTask) o;
|
||||
return ruptureRank == that.ruptureRank && expireTick == that.expireTick && ruptureTick == that.ruptureTick && damageTickTracker == that.damageTickTracker && Double.compare(that.damageValue, damageValue) == 0 && Objects.equal(ruptureSource, that.ruptureSource) && Objects.equal(targetEntity, that.targetEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(ruptureSource, targetEntity, ruptureRank, expireTick, ruptureTick, damageTickTracker, damageValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RuptureTimerTask{" +
|
||||
"ruptureSource=" + ruptureSource +
|
||||
", targetEntity=" + targetEntity +
|
||||
", ruptureRank=" + ruptureRank +
|
||||
", expireTick=" + expireTick +
|
||||
", ruptureTick=" + ruptureTick +
|
||||
", damageTickTracker=" + damageTickTracker +
|
||||
", damageValue=" + damageValue +
|
||||
'}';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user