Fixed damagedealt{} exp source crashing the server when giving a cookie to a parrot

This commit is contained in:
Jules 2024-05-23 18:33:05 -07:00
parent dad9db0edd
commit 0e5ac9ce3a
2 changed files with 44 additions and 50 deletions

View File

@ -10,6 +10,7 @@ import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.attribute.Attribute;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import java.util.Arrays; import java.util.Arrays;
@ -18,7 +19,7 @@ import java.util.stream.Collectors;
import static org.bukkit.event.EventPriority.MONITOR; import static org.bukkit.event.EventPriority.MONITOR;
public class DamageDealtExperienceSource extends SpecificExperienceSource<DamageType> { public class DamageDealtExperienceSource extends SpecificExperienceSource<Void> {
private final DamageType type; private final DamageType type;
/** /**
@ -28,14 +29,11 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource<Damage
public DamageDealtExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { public DamageDealtExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
super(dispenser, config); super(dispenser, config);
if (!config.contains("type")) if (!config.contains("type")) type = null;
type = null;
else { else {
String str = UtilityMethods.enumName(config.getString("type")); String str = UtilityMethods.enumName(config.getString("type"));
//Checks if the damage type correspond to a value of the damage type enum //Checks if the damage type correspond to a value of the damage type enum
Validate.isTrue(Arrays.stream(DamageType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), Validate.isTrue(Arrays.stream(DamageType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), "Type value not allowed. Type value allowed: magic, physical, weapon, skill, projectile," + " unarmed, on-hit, minion, dot.");
"Type value not allowed. Type value allowed: magic, physical, weapon, skill, projectile," +
" unarmed, on-hit, minion, dot.");
type = DamageType.valueOf(str); type = DamageType.valueOf(str);
} }
} }
@ -43,35 +41,26 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource<Damage
@Override @Override
public ExperienceSourceManager<DamageDealtExperienceSource> newManager() { public ExperienceSourceManager<DamageDealtExperienceSource> newManager() {
return new ExperienceSourceManager<DamageDealtExperienceSource>() { return new ExperienceSourceManager<DamageDealtExperienceSource>() {
//It isn't triggered when the PlayerAttackEvent gets cancelled
@EventHandler(priority = MONITOR,ignoreCancelled = true)
public void onDamageDealt(PlayerAttackEvent e) {
PlayerData playerData = PlayerData.get(e.getPlayer());
for (DamageDealtExperienceSource source : getSources()) {
double value = 0;
for (DamagePacket packet : e.getDamage().getPackets()) {
for (DamageType damageType : packet.getTypes()) {
if (source.matchesParameter(playerData, damageType))
value += packet.getFinalValue();
}
} @EventHandler(priority = MONITOR, ignoreCancelled = true)
public void onDamageDealt(PlayerAttackEvent event) {
final PlayerData playerData = PlayerData.get(event.getPlayer());
for (DamageDealtExperienceSource source : getSources())
if (source.matches(playerData, null)) {
double value = event.getDamage().getDamage(source.type);
if (value == 0) continue;
// Cannot count more than the entity's max health
final double enemyMaxHealth = event.getEntity().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
value = Math.min(value, enemyMaxHealth);
source.giveExperience(playerData, value, null); source.giveExperience(playerData, value, null);
} }
} }
}; };
} }
@Override @Override
public boolean matchesParameter(PlayerData player, DamageType damageType) { public boolean matchesParameter(PlayerData player, Void v) {
if (type == null) {
return true; return true;
} }
else {
return type.equals(damageType);
}
}
} }

View File

@ -1,13 +1,15 @@
package net.Indyuce.mmocore.experience.source; package net.Indyuce.mmocore.experience.source;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.MMOLineConfig; import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.util.Lazy;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.OfflinePlayer; import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
@ -42,33 +44,36 @@ public class DamageTakenExperienceSource extends SpecificExperienceSource<Entity
@Override @Override
public ExperienceSourceManager<DamageTakenExperienceSource> newManager() { public ExperienceSourceManager<DamageTakenExperienceSource> newManager() {
return new ExperienceSourceManager<DamageTakenExperienceSource>() { return new ExperienceSourceManager<DamageTakenExperienceSource>() {
@EventHandler(priority = HIGHEST,ignoreCancelled = true) @EventHandler(priority = HIGHEST, ignoreCancelled = true)
public void onDamageTaken(EntityDamageEvent e) { public void onDamageTaken(EntityDamageEvent event) {
if (e.getEntity() instanceof Player && !e.getEntity().hasMetadata("NPC")) { if (!UtilityMethods.isRealPlayer(event.getEntity())) return;
double amount = e.getDamage();
PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity()); final PlayerData playerData = PlayerData.get((Player) event.getEntity());
//We wait 2 tick to check if the player is Dead final Lazy<Double> effectiveDamage = Lazy.of(() -> {
final double eventDamage = event.getDamage();
final double maxHealth = ((Player) event.getEntity()).getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
return Math.min(eventDamage, maxHealth);
});
// Wait 2 tick to check if the player died
new BukkitRunnable() { new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
for (DamageTakenExperienceSource source : getSources()) { for (DamageTakenExperienceSource source : getSources())
if (source.matchesParameter(playerData, e.getCause())) if (source.matchesParameter(playerData, event.getCause())) {
source.giveExperience(playerData, amount, null); // System.out.println("-> " + effectiveDamage.get());
source.giveExperience(playerData, effectiveDamage.get(), null);
} }
} }
}.runTaskLater(MMOCore.plugin, 2); }.runTaskLater(MMOCore.plugin, 2);
} }
}
}; };
} }
@Override @Override
public boolean matchesParameter(PlayerData player, EntityDamageEvent.DamageCause damageCause) { public boolean matchesParameter(PlayerData player, EntityDamageEvent.DamageCause damageCause) {
if (player.getPlayer().isDead()) if (player.getPlayer().isDead()) return false;
return false; return cause == null || damageCause.equals(cause);
if (cause == null)
return true;
return damageCause.equals(cause);
} }
} }