Hopefully fixed compatibility with MM and Heroes bow damage

This commit is contained in:
Jules 2022-03-02 19:45:51 +01:00
parent 264f8c7220
commit 05e9d89124
2 changed files with 45 additions and 3 deletions

View File

@ -8,8 +8,10 @@ import io.lumine.mythic.lib.api.item.NBTItem;
import io.lumine.mythic.lib.damage.AttackMetadata; import io.lumine.mythic.lib.damage.AttackMetadata;
import io.lumine.mythic.lib.player.PlayerMetadata; import io.lumine.mythic.lib.player.PlayerMetadata;
import net.Indyuce.mmoitems.api.ItemAttackMetadata; import net.Indyuce.mmoitems.api.ItemAttackMetadata;
import net.Indyuce.mmoitems.manager.EntityManager;
import net.Indyuce.mmoitems.stat.data.PotionEffectData; import net.Indyuce.mmoitems.stat.data.PotionEffectData;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
public class ProjectileData { public class ProjectileData {
@ -17,6 +19,8 @@ public class ProjectileData {
private final PlayerMetadata shooter; private final PlayerMetadata shooter;
private final boolean customWeapon; private final boolean customWeapon;
private double cachedInitialDamage;
public ProjectileData(PlayerMetadata shooter, NBTItem sourceItem, boolean customWeapon) { public ProjectileData(PlayerMetadata shooter, NBTItem sourceItem, boolean customWeapon) {
this.shooter = shooter; this.shooter = shooter;
this.sourceItem = sourceItem; this.sourceItem = sourceItem;
@ -64,6 +68,20 @@ public class ProjectileData {
shooter.setStat("ATTACK_DAMAGE", damage); shooter.setStat("ATTACK_DAMAGE", damage);
} }
/**
* @see {@link EntityManager#cacheInitialProjectileDamage(EntityDamageByEntityEvent)}
*/
public double getCachedInitialDamage() {
return cachedInitialDamage;
}
/**
* @see {@link EntityManager#cacheInitialProjectileDamage(EntityDamageByEntityEvent)}
*/
public void cacheInitialDamage(double cachedInitialDamage) {
this.cachedInitialDamage = cachedInitialDamage;
}
public void applyPotionEffects(LivingEntity target) { public void applyPotionEffects(LivingEntity target) {
if (sourceItem.hasTag("MMOITEMS_ARROW_POTION_EFFECTS")) if (sourceItem.hasTag("MMOITEMS_ARROW_POTION_EFFECTS"))
for (JsonElement entry : MythicLib.plugin.getJson().parse(sourceItem.getString("MMOITEMS_ARROW_POTION_EFFECTS"), JsonArray.class)) { for (JsonElement entry : MythicLib.plugin.getJson().parse(sourceItem.getString("MMOITEMS_ARROW_POTION_EFFECTS"), JsonArray.class)) {

View File

@ -106,6 +106,30 @@ public class EntityManager implements Listener {
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, () -> unregisterCustomEntity(event.getEntity())); Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, () -> unregisterCustomEntity(event.getEntity()));
} }
/**
* This fixes an issue with Heroes and MythicMobs as they are
* plugins which MODIFY or apply damage modifiers to bow hit events.
* <p>
* By caching the event damage with LOWEST priority you basically store
* the VANILLA amount of damage the bow would have dealt if there was no
* plugin.
* <p>
* The main problem comes from not being able to SET the bow damage. You are
* only allowed to add flat modifiers to it, and if all the plugins do that
* the calculations are fully correct.
* <p>
* On NORMAL priority, MMOItems calculates the bow damage, substract from that
* the vanilla bow damage which outputs the damage modifier from MMOItems. This
* makes it compatible with other plugins modifying the damage.
*
* @see {@link #applyOnHitEffects(EntityDamageByEntityEvent)}
*/
@EventHandler(priority = EventPriority.LOWEST)
public void cacheInitialProjectileDamage(EntityDamageByEntityEvent event) {
if (event.getEntity() instanceof Projectile)
projectiles.get(event.getEntity().getEntityId()).cacheInitialDamage(event.getDamage());
}
// Projectile damage and effects // Projectile damage and effects
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void applyOnHitEffects(EntityDamageByEntityEvent event) { public void applyOnHitEffects(EntityDamageByEntityEvent event) {
@ -113,10 +137,10 @@ public class EntityManager implements Listener {
return; return;
Projectile projectile = (Projectile) event.getDamager(); Projectile projectile = (Projectile) event.getDamager();
if (!isCustomProjectile(projectile)) ProjectileData data = projectiles.get(projectile.getEntityId());
if (data == null)
return; return;
ProjectileData data = getProjectileData(projectile);
LivingEntity target = (LivingEntity) event.getEntity(); LivingEntity target = (LivingEntity) event.getEntity();
double damage = data.getDamage(); double damage = data.getDamage();
@ -131,7 +155,7 @@ public class EntityManager implements Listener {
damage += new ElementalAttack(data.getShooter(), data.getSourceItem(), damage, target).getDamageModifier(); damage += new ElementalAttack(data.getShooter(), data.getSourceItem(), damage, target).getDamageModifier();
} }
event.setDamage(damage); event.setDamage(event.getDamage() + damage - data.getCachedInitialDamage());
// Remove projectile if it has no piercing anymore // Remove projectile if it has no piercing anymore
if (!(projectile instanceof AbstractArrow) && ((AbstractArrow) projectile).getPierceLevel() <= 1) if (!(projectile instanceof AbstractArrow) && ((AbstractArrow) projectile).getPierceLevel() <= 1)