forked from Upstream/mmocore
Fixed some exp sources working across some classes/professions
This commit is contained in:
parent
0e5ac9ce3a
commit
6e739b3787
@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Used to differenciate between the main class experience and
|
||||
* Used to differentiate between the main class experience and
|
||||
* experience given in a specific profession. Also being used to
|
||||
* monitor EXP holograms.
|
||||
*
|
||||
|
@ -3,9 +3,9 @@ package net.Indyuce.mmocore.experience.source;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.experience.EXPSource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@ -44,44 +44,46 @@ public class BrewPotionExperienceSource extends ExperienceSource<PotionMeta> {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<BrewPotionExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<BrewPotionExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BrewEvent event) {
|
||||
Optional<Player> playerOpt = getNearbyPlayer(event.getBlock().getLocation());
|
||||
if (!playerOpt.isPresent())
|
||||
return;
|
||||
|
||||
final ItemStack found = findPotion(event.getContents());
|
||||
if (found != null)
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
|
||||
ItemStack brewn = findPotion(event.getContents());
|
||||
if (brewn == null)
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(playerOpt.get());
|
||||
for (BrewPotionExperienceSource source : getSources())
|
||||
if (source.matches(data, (PotionMeta) brewn.getItemMeta()))
|
||||
new PotionUpgrade(found, brewn).process(data.getPlayer());
|
||||
});
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
private ItemStack findPotion(BrewerInventory inv) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
ItemStack item = inv.getItem(j);
|
||||
if (item != null && item.hasItemMeta() && item.getItemMeta() instanceof PotionMeta)
|
||||
return item;
|
||||
private static class Manager extends ExperienceSourceManager<BrewPotionExperienceSource> {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BrewEvent event) {
|
||||
Optional<Player> playerOpt = getNearbyPlayer(event.getBlock().getLocation());
|
||||
if (!playerOpt.isPresent())
|
||||
return;
|
||||
|
||||
final ItemStack found = findPotion(event.getContents());
|
||||
if (found != null)
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> {
|
||||
ItemStack brewn = findPotion(event.getContents());
|
||||
if (brewn == null)
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(playerOpt.get());
|
||||
for (BrewPotionExperienceSource source : getSources())
|
||||
if (source.matches(data, (PotionMeta) brewn.getItemMeta()))
|
||||
new PotionUpgrade(found, brewn).process(source, data.getPlayer());
|
||||
});
|
||||
}
|
||||
|
||||
private ItemStack findPotion(BrewerInventory inv) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
ItemStack item = inv.getItem(j);
|
||||
if (item != null && item.hasItemMeta() && item.getItemMeta() instanceof PotionMeta)
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Optional<Player> getNearbyPlayer(Location loc) {
|
||||
return loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100).findAny();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Optional<Player> getNearbyPlayer(Location loc) {
|
||||
return loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100).findAny();
|
||||
}
|
||||
|
||||
public class PotionUpgrade {
|
||||
private static class PotionUpgrade {
|
||||
|
||||
/*
|
||||
* if the potion was extended using redstone or upgraded using
|
||||
@ -161,14 +163,14 @@ public class BrewPotionExperienceSource extends ExperienceSource<PotionMeta> {
|
||||
// effect.getType() == type).findFirst();
|
||||
// }
|
||||
|
||||
public void process(Player player) {
|
||||
public void process(BrewPotionExperienceSource source, Player player) {
|
||||
|
||||
/*
|
||||
* calculate extra exp due to extra effects
|
||||
*/
|
||||
// exp += getTotal(mapEffectDurations());
|
||||
|
||||
getDispenser().giveExperience(PlayerData.get(player), exp * multiplier, player.getLocation(), EXPSource.SOURCE);
|
||||
source.getDispenser().giveExperience(PlayerData.get(player), exp * source.multiplier, player.getLocation(), EXPSource.SOURCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
import static org.bukkit.event.EventPriority.HIGHEST;
|
||||
import static org.bukkit.event.EventPriority.MONITOR;
|
||||
|
||||
public class ClimbExperienceSource extends SpecificExperienceSource<Material> {
|
||||
//Can be Ladder,Vines,Twisting Vines,Weeping Vines.
|
||||
@ -36,28 +35,11 @@ public class ClimbExperienceSource extends SpecificExperienceSource<Material> {
|
||||
|
||||
type = Material.valueOf(str);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<ClimbExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<ClimbExperienceSource>() {
|
||||
@EventHandler(priority = HIGHEST,ignoreCancelled = true)
|
||||
public void onClimb(PlayerMoveEvent e) {
|
||||
double delta=e.getTo().getBlockY()-e.getFrom().getBlockY();
|
||||
if (delta > 0) {
|
||||
if (e.getPlayer().hasMetadata("NPC"))
|
||||
return;
|
||||
PlayerData playerData = PlayerData.get(e.getPlayer());
|
||||
for (ClimbExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, e.getFrom().getBlock().getType()))
|
||||
source.giveExperience(playerData, delta, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,6 +53,22 @@ public class ClimbExperienceSource extends SpecificExperienceSource<Material> {
|
||||
if (type.equals(Material.TWISTING_VINES))
|
||||
return material.equals(Material.TWISTING_VINES) || material.equals(Material.TWISTING_VINES_PLANT);
|
||||
return material.equals(type);
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<ClimbExperienceSource> {
|
||||
|
||||
@EventHandler(priority = HIGHEST, ignoreCancelled = true)
|
||||
public void onClimb(PlayerMoveEvent e) {
|
||||
double delta = e.getTo().getBlockY() - e.getFrom().getBlockY();
|
||||
if (delta > 0) {
|
||||
if (e.getPlayer().hasMetadata("NPC"))
|
||||
return;
|
||||
PlayerData playerData = PlayerData.get(e.getPlayer());
|
||||
for (ClimbExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, e.getFrom().getBlock().getType()))
|
||||
source.giveExperience(playerData, delta, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package net.Indyuce.mmocore.experience.source;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -30,51 +30,7 @@ public class CraftItemExperienceSource extends SpecificExperienceSource<Material
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<CraftItemExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<CraftItemExperienceSource>() {
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void a(CraftItemEvent event) {
|
||||
if (event.getAction() == InventoryAction.NOTHING ||
|
||||
event.getInventory().getResult() == null) return;
|
||||
|
||||
PlayerData data = PlayerData.get((Player) event.getWhoClicked());
|
||||
|
||||
/**
|
||||
* This makes sure that the crafting recipe was performed correctly.
|
||||
*
|
||||
* In some scenarii, the CraftItemEvent (which is only a click event
|
||||
* by the way) is not cancelled, but the item is not crafted which makes
|
||||
* EXP duplication a game breaking glitch. MMOCore make sure that at
|
||||
* least one ingredient has lowered in amount.
|
||||
*
|
||||
* The second objective of that check is to deduce the amount of items that
|
||||
* were crafted during this event. For that, it finds the item with the lowest
|
||||
* amount in the crafting matrix and see how many items disappeared,
|
||||
* multiplied by the recipe output amount (works for a shift click).
|
||||
*
|
||||
* References:
|
||||
* - https://git.lumine.io/mythiccraft/mmocore/-/issues/102
|
||||
* - https://www.spigotmc.org/threads/how-to-get-amount-of-item-crafted.377598/
|
||||
*/
|
||||
final int index = getLowerAmountIngredientIndex(event.getInventory().getMatrix());
|
||||
final int oldAmount = event.getInventory().getMatrix()[index].getAmount();
|
||||
final int itemsCraftedPerRecipe = event.getInventory().getResult().getAmount();
|
||||
final Material resultType = event.getInventory().getResult().getType();
|
||||
|
||||
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> {
|
||||
|
||||
// First check
|
||||
int newAmount = getAmount(event.getInventory().getMatrix()[index]);
|
||||
if (newAmount >= oldAmount)
|
||||
return;
|
||||
|
||||
// Deduce amount crafted
|
||||
int amountCrafted = (event.getClick().isShiftClick() ? oldAmount - newAmount : 1) * itemsCraftedPerRecipe;
|
||||
for (CraftItemExperienceSource source : getSources())
|
||||
if (source.matches(data, resultType))
|
||||
source.giveExperience(data, amountCrafted, event.getInventory().getLocation());
|
||||
});
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,23 +38,68 @@ public class CraftItemExperienceSource extends SpecificExperienceSource<Material
|
||||
return material == obj;
|
||||
}
|
||||
|
||||
private int getAmount(@Nullable ItemStack item) {
|
||||
return item == null || item.getType() == Material.AIR ? 0 : item.getAmount();
|
||||
}
|
||||
private static class Manager extends ExperienceSourceManager<CraftItemExperienceSource> {
|
||||
|
||||
private int getLowerAmountIngredientIndex(ItemStack[] matrix) {
|
||||
int lower = Integer.MAX_VALUE;
|
||||
int index = -1;
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void a(CraftItemEvent event) {
|
||||
if (event.getAction() == InventoryAction.NOTHING || event.getInventory().getResult() == null) return;
|
||||
|
||||
for (int i = 0; i < matrix.length; i++) {
|
||||
ItemStack checked = matrix[i];
|
||||
if (checked != null && checked.getType() != Material.AIR && checked.getAmount() > 0 && checked.getAmount() < lower) {
|
||||
lower = checked.getAmount();
|
||||
index = i;
|
||||
}
|
||||
PlayerData data = PlayerData.get((Player) event.getWhoClicked());
|
||||
|
||||
/**
|
||||
* This makes sure that the crafting recipe was performed correctly.
|
||||
*
|
||||
* In some scenarii, the CraftItemEvent (which is only a click event
|
||||
* by the way) is not cancelled, but the item is not crafted which makes
|
||||
* EXP duplication a game breaking glitch. MMOCore make sure that at
|
||||
* least one ingredient has lowered in amount.
|
||||
*
|
||||
* The second objective of that check is to deduce the amount of items that
|
||||
* were crafted during this event. For that, it finds the item with the lowest
|
||||
* amount in the crafting matrix and see how many items disappeared,
|
||||
* multiplied by the recipe output amount (works for a shift click).
|
||||
*
|
||||
* References:
|
||||
* - https://git.lumine.io/mythiccraft/mmocore/-/issues/102
|
||||
* - https://www.spigotmc.org/threads/how-to-get-amount-of-item-crafted.377598/
|
||||
*/
|
||||
final int index = getLowerAmountIngredientIndex(event.getInventory().getMatrix());
|
||||
final int oldAmount = event.getInventory().getMatrix()[index].getAmount();
|
||||
final int itemsCraftedPerRecipe = event.getInventory().getResult().getAmount();
|
||||
final Material resultType = event.getInventory().getResult().getType();
|
||||
|
||||
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> {
|
||||
|
||||
// First check
|
||||
int newAmount = getAmount(event.getInventory().getMatrix()[index]);
|
||||
if (newAmount >= oldAmount) return;
|
||||
|
||||
// Deduce amount crafted
|
||||
int amountCrafted = (event.getClick().isShiftClick() ? oldAmount - newAmount : 1) * itemsCraftedPerRecipe;
|
||||
for (CraftItemExperienceSource source : getSources())
|
||||
if (source.matches(data, resultType))
|
||||
source.giveExperience(data, amountCrafted, event.getInventory().getLocation());
|
||||
});
|
||||
}
|
||||
|
||||
Validate.isTrue(index != -1, "No item in matrix");
|
||||
return index;
|
||||
private int getAmount(@Nullable ItemStack item) {
|
||||
return item == null || item.getType() == Material.AIR ? 0 : item.getAmount();
|
||||
}
|
||||
|
||||
private int getLowerAmountIngredientIndex(ItemStack[] matrix) {
|
||||
int lower = Integer.MAX_VALUE;
|
||||
int index = -1;
|
||||
|
||||
for (int i = 0; i < matrix.length; i++) {
|
||||
ItemStack checked = matrix[i];
|
||||
if (checked != null && checked.getType() != Material.AIR && checked.getAmount() > 0 && checked.getAmount() < lower) {
|
||||
lower = checked.getAmount();
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
Validate.isTrue(index != -1, "No item in matrix");
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ 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.event.PlayerAttackEvent;
|
||||
import io.lumine.mythic.lib.damage.DamagePacket;
|
||||
import io.lumine.mythic.lib.damage.DamageType;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
@ -40,27 +39,29 @@ public class DamageDealtExperienceSource extends SpecificExperienceSource<Void>
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<DamageDealtExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<DamageDealtExperienceSource>() {
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, Void v) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<DamageDealtExperienceSource> {
|
||||
|
||||
@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 = source.type == null ? event.getDamage().getDamage() : 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,32 +43,7 @@ public class DamageTakenExperienceSource extends SpecificExperienceSource<Entity
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<DamageTakenExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<DamageTakenExperienceSource>() {
|
||||
@EventHandler(priority = HIGHEST, ignoreCancelled = true)
|
||||
|
||||
public void onDamageTaken(EntityDamageEvent event) {
|
||||
if (!UtilityMethods.isRealPlayer(event.getEntity())) return;
|
||||
|
||||
final PlayerData playerData = PlayerData.get((Player) event.getEntity());
|
||||
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() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (DamageTakenExperienceSource source : getSources())
|
||||
if (source.matchesParameter(playerData, event.getCause())) {
|
||||
// System.out.println("-> " + effectiveDamage.get());
|
||||
source.giveExperience(playerData, effectiveDamage.get(), null);
|
||||
}
|
||||
}
|
||||
}.runTaskLater(MMOCore.plugin, 2);
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,4 +51,32 @@ public class DamageTakenExperienceSource extends SpecificExperienceSource<Entity
|
||||
if (player.getPlayer().isDead()) return false;
|
||||
return cause == null || damageCause.equals(cause);
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<DamageTakenExperienceSource> {
|
||||
|
||||
@EventHandler(priority = HIGHEST, ignoreCancelled = true)
|
||||
|
||||
public void onDamageTaken(EntityDamageEvent event) {
|
||||
if (!UtilityMethods.isRealPlayer(event.getEntity())) return;
|
||||
|
||||
final PlayerData playerData = PlayerData.get((Player) event.getEntity());
|
||||
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() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (DamageTakenExperienceSource source : getSources())
|
||||
if (source.matchesParameter(playerData, event.getCause())) {
|
||||
// System.out.println("-> " + effectiveDamage.get());
|
||||
source.giveExperience(playerData, effectiveDamage.get(), null);
|
||||
}
|
||||
}
|
||||
}.runTaskLater(MMOCore.plugin, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,19 +33,7 @@ public class EatExperienceSource extends SpecificExperienceSource<ItemStack> {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<EatExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<EatExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = MONITOR,ignoreCancelled = true)
|
||||
public void a(PlayerItemConsumeEvent e) {
|
||||
if(!e.getPlayer().hasMetadata("NPC")) {
|
||||
PlayerData playerData = PlayerData.get(e.getPlayer());
|
||||
for (EatExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, e.getItem()))
|
||||
source.giveExperience(playerData, 1, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,4 +43,18 @@ public class EatExperienceSource extends SpecificExperienceSource<ItemStack> {
|
||||
return type.equals(obj.getType());
|
||||
}
|
||||
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<EatExperienceSource> {
|
||||
|
||||
@EventHandler(priority = MONITOR,ignoreCancelled = true)
|
||||
public void a(PlayerItemConsumeEvent e) {
|
||||
if(!e.getPlayer().hasMetadata("NPC")) {
|
||||
PlayerData playerData = PlayerData.get(e.getPlayer());
|
||||
for (EatExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, e.getItem()))
|
||||
source.giveExperience(playerData, 1, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.experience.EXPSource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.ExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -41,28 +41,30 @@ public class EnchantItemExperienceSource extends ExperienceSource<Void> {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<EnchantItemExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<EnchantItemExperienceSource>() {
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(EnchantItemEvent event) {
|
||||
PlayerData player = PlayerData.get(event.getEnchanter());
|
||||
for (EnchantItemExperienceSource source : getSources())
|
||||
if (source.matches(player, null)) {
|
||||
Map<Enchantment, Integer> applicableEnchants = new HashMap<>(event.getEnchantsToAdd());
|
||||
private static class Manager extends ExperienceSourceManager<EnchantItemExperienceSource> {
|
||||
|
||||
// Filter out enchants if required
|
||||
if (!source.enchants.isEmpty())
|
||||
applicableEnchants.keySet().removeIf(enchantment -> !source.enchants.contains(enchantment));
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(EnchantItemEvent event) {
|
||||
PlayerData player = PlayerData.get(event.getEnchanter());
|
||||
for (EnchantItemExperienceSource source : getSources())
|
||||
if (source.matches(player, null)) {
|
||||
Map<Enchantment, Integer> applicableEnchants = new HashMap<>(event.getEnchantsToAdd());
|
||||
|
||||
if (applicableEnchants.isEmpty())
|
||||
continue;
|
||||
// Filter out enchants if required
|
||||
if (!source.enchants.isEmpty())
|
||||
applicableEnchants.keySet().removeIf(enchantment -> !source.enchants.contains(enchantment));
|
||||
|
||||
double exp = 0;
|
||||
for (Entry<Enchantment, Integer> entry : applicableEnchants.entrySet())
|
||||
exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue();
|
||||
getDispenser().giveExperience(player, exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (applicableEnchants.isEmpty())
|
||||
continue;
|
||||
|
||||
double exp = 0;
|
||||
for (Entry<Enchantment, Integer> entry : applicableEnchants.entrySet())
|
||||
exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue();
|
||||
source.getDispenser().giveExperience(player, exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Item;
|
||||
@ -25,26 +25,28 @@ public class FishItemExperienceSource extends SpecificExperienceSource<ItemStack
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<FishItemExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<FishItemExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(PlayerFishEvent event) {
|
||||
if (event.getState() == State.CAUGHT_FISH) {
|
||||
ItemStack caught = ((Item) event.getCaught()).getItemStack();
|
||||
if (caught.hasItemMeta())
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
for (FishItemExperienceSource source : getSources())
|
||||
if (source.matches(data, caught))
|
||||
source.giveExperience(data, caught.getAmount(), event.getHook().getLocation().add(0, 1.0f, 0));
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, ItemStack obj) {
|
||||
return obj.getType() == material;
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<FishItemExperienceSource> {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(PlayerFishEvent event) {
|
||||
if (event.getState() == State.CAUGHT_FISH) {
|
||||
ItemStack caught = ((Item) event.getCaught()).getItemStack();
|
||||
if (caught.hasItemMeta())
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
for (FishItemExperienceSource source : getSources())
|
||||
if (source.matches(data, caught))
|
||||
source.giveExperience(data, caught.getAmount(), event.getHook().getLocation().add(0, 1.0f, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,20 +33,22 @@ public class FromExperienceSource extends ExperienceSource {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<FromExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<>() {
|
||||
|
||||
/**
|
||||
* Used to register all the children experience sources.
|
||||
*/
|
||||
@Override
|
||||
public void registerSource(FromExperienceSource source) {
|
||||
source.experienceSources.forEach(expSource -> MMOCore.plugin.experience.registerSource(expSource));
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, Object obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<FromExperienceSource> {
|
||||
|
||||
/**
|
||||
* Used to register all the children experience sources.
|
||||
*/
|
||||
@Override
|
||||
public void registerSource(FromExperienceSource source) {
|
||||
source.experienceSources.forEach(expSource -> MMOCore.plugin.experience.registerSource(expSource));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,44 +38,47 @@ public class KillMobExperienceSource extends SpecificExperienceSource<Entity> {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<KillMobExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<KillMobExperienceSource>() {
|
||||
|
||||
/**
|
||||
* This map is used to keep track of the last player who
|
||||
* hit some entity. It is flushed on entity death.
|
||||
*/
|
||||
private final FlushableRegistry<UUID, UUID> registry = new FlushableRegistry<>((entity, attacker) -> Bukkit.getEntity(entity) == null, 20 * 60);
|
||||
|
||||
@Override
|
||||
public void whenClosed() {
|
||||
registry.close();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void registerLastAttacker(PlayerAttackEvent event) {
|
||||
registry.getRegistry().put(event.getEntity().getUniqueId(), event.getAttacker().getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void giveExp(EntityDeathEvent event) {
|
||||
|
||||
// Always remove entry from map
|
||||
final @Nullable UUID lastAttacker = this.registry.getRegistry().remove(event.getEntity().getUniqueId());
|
||||
if (lastAttacker == null) return;
|
||||
|
||||
if (event.getEntity().getPersistentDataContainer().has(new NamespacedKey(MMOCore.plugin, "spawner_spawned"), PersistentDataType.STRING))
|
||||
return;
|
||||
|
||||
final PlayerData data = PlayerData.get(lastAttacker);
|
||||
for (KillMobExperienceSource source : getSources())
|
||||
if (source.matches(data, event.getEntity()))
|
||||
source.giveExperience(data, 1, MMOCoreUtils.getCenterLocation(event.getEntity()));
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, Entity obj) {
|
||||
return obj.getType() == type && (displayName == null || displayName.equals(obj.getCustomName()));
|
||||
}
|
||||
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<KillMobExperienceSource> {
|
||||
|
||||
/**
|
||||
* This map is used to keep track of the last player who
|
||||
* hit some entity. It is flushed on entity death.
|
||||
*/
|
||||
private final FlushableRegistry<UUID, UUID> registry = new FlushableRegistry<>((entity, attacker) -> Bukkit.getEntity(entity) == null, 20 * 60);
|
||||
|
||||
@Override
|
||||
public void whenClosed() {
|
||||
registry.close();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void registerLastAttacker(PlayerAttackEvent event) {
|
||||
registry.getRegistry().put(event.getEntity().getUniqueId(), event.getAttacker().getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void giveExp(EntityDeathEvent event) {
|
||||
|
||||
// Always remove entry from map
|
||||
final @Nullable UUID lastAttacker = this.registry.getRegistry().remove(event.getEntity().getUniqueId());
|
||||
if (lastAttacker == null) return;
|
||||
|
||||
if (event.getEntity().getPersistentDataContainer().has(new NamespacedKey(MMOCore.plugin, "spawner_spawned"), PersistentDataType.STRING))
|
||||
return;
|
||||
|
||||
final PlayerData data = PlayerData.get(lastAttacker);
|
||||
for (KillMobExperienceSource source : getSources())
|
||||
if (source.matches(data, event.getEntity()))
|
||||
source.giveExperience(data, 1, MMOCoreUtils.getCenterLocation(event.getEntity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
@ -40,36 +40,36 @@ public class MineBlockExperienceSource extends SpecificExperienceSource<Material
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<MineBlockExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<MineBlockExperienceSource>() {
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BlockBreakEvent event) {
|
||||
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL) return;
|
||||
if (UtilityMethods.isFake(event)) return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
|
||||
for (MineBlockExperienceSource source : getSources()) {
|
||||
if (source.silkTouch && hasSilkTouch(event.getPlayer().getInventory().getItemInMainHand()))
|
||||
continue;
|
||||
if (source.crop && !MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock()))
|
||||
continue;
|
||||
if (!source.playerPlaced && event.getBlock().hasMetadata("player_placed"))
|
||||
continue;
|
||||
|
||||
if (source.matches(data, event.getBlock().getType()))
|
||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private boolean hasSilkTouch(ItemStack item) {
|
||||
return item != null && item.hasItemMeta() && item.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, Material obj) {
|
||||
|
||||
return material == obj;
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<MineBlockExperienceSource> {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BlockBreakEvent event) {
|
||||
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL) return;
|
||||
if (UtilityMethods.isFake(event)) return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
|
||||
for (MineBlockExperienceSource source : getSources()) {
|
||||
if (source.silkTouch && hasSilkTouch(event.getPlayer().getInventory().getItemInMainHand())) continue;
|
||||
if (source.crop && !MythicLib.plugin.getVersion().getWrapper().isCropFullyGrown(event.getBlock()))
|
||||
continue;
|
||||
if (!source.playerPlaced && event.getBlock().hasMetadata("player_placed")) continue;
|
||||
|
||||
if (source.matches(data, event.getBlock().getType()))
|
||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasSilkTouch(ItemStack item) {
|
||||
return item != null && item.hasItemMeta() && item.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,27 +36,7 @@ public class MoveExperienceSource extends SpecificExperienceSource {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<MoveExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<MoveExperienceSource>() {
|
||||
@EventHandler(priority = MONITOR,ignoreCancelled = true)
|
||||
public void onMove(PlayerMoveEvent e) {
|
||||
double deltax = e.getTo().getBlockX() - e.getFrom().getBlockX();
|
||||
double deltay = e.getTo().getBlockY() - e.getFrom().getBlockY();
|
||||
double deltaz = e.getTo().getBlockZ() - e.getFrom().getBlockZ();
|
||||
if (deltax != 0 || deltay != 0 || deltaz != 0) {
|
||||
|
||||
double delta = Math.sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz);
|
||||
if (e.getPlayer().hasMetadata("NPC"))
|
||||
return;
|
||||
Player player = e.getPlayer();
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
for (MoveExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, null)) {
|
||||
giveExperience(playerData, delta, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,7 +49,7 @@ public class MoveExperienceSource extends SpecificExperienceSource {
|
||||
FLY((p) -> p.isFlying() || p.isGliding()),
|
||||
SWIM((p) -> p.getLocation().getBlock().isLiquid()),
|
||||
SPRINT(Player::isSprinting),
|
||||
WALK((p) -> !p.isSneaking() && !p.isSprinting() &&((Entity)p).isOnGround()&& !p.isFlying() && !p.getLocation().getBlock().isLiquid());
|
||||
WALK((p) -> !p.isSneaking() && !p.isSprinting() && ((Entity) p).isOnGround() && !p.isFlying() && !p.getLocation().getBlock().isLiquid());
|
||||
|
||||
private final Function<Player, Boolean> matching;
|
||||
|
||||
@ -82,4 +62,24 @@ public class MoveExperienceSource extends SpecificExperienceSource {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<MoveExperienceSource> {
|
||||
@EventHandler(priority = MONITOR, ignoreCancelled = true)
|
||||
public void onMove(PlayerMoveEvent e) {
|
||||
double deltax = e.getTo().getBlockX() - e.getFrom().getBlockX();
|
||||
double deltay = e.getTo().getBlockY() - e.getFrom().getBlockY();
|
||||
double deltaz = e.getTo().getBlockZ() - e.getFrom().getBlockZ();
|
||||
if (deltax != 0 || deltay != 0 || deltaz != 0) {
|
||||
|
||||
double delta = Math.sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz);
|
||||
if (e.getPlayer().hasMetadata("NPC"))
|
||||
return;
|
||||
Player player = e.getPlayer();
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
for (MoveExperienceSource source : getSources())
|
||||
if (source.matchesParameter(playerData, null))
|
||||
source.giveExperience(playerData, delta, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
@ -23,23 +23,26 @@ public class PlaceBlockExperienceSource extends SpecificExperienceSource<Materia
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<PlaceBlockExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<PlaceBlockExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BlockPlaceEvent event) {
|
||||
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL)
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
for (PlaceBlockExperienceSource source : getSources())
|
||||
if (source.matches(data, event.getBlock().getType()))
|
||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, Material obj) {
|
||||
return material == obj;
|
||||
}
|
||||
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<PlaceBlockExperienceSource> {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BlockPlaceEvent event) {
|
||||
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL)
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(event.getPlayer());
|
||||
for (PlaceBlockExperienceSource source : getSources())
|
||||
if (source.matches(data, event.getBlock().getType()))
|
||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class PlayExperienceSource extends SpecificExperienceSource {
|
||||
|
||||
private final World world;
|
||||
private final double x1, x2, z1, z2;
|
||||
private final boolean inCombat;
|
||||
@ -48,7 +47,7 @@ public class PlayExperienceSource extends SpecificExperienceSource {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<PlayExperienceSource> newManager() {
|
||||
return new PlayingExperienceSourceManager();
|
||||
return new Manager();
|
||||
|
||||
}
|
||||
|
||||
@ -65,9 +64,9 @@ public class PlayExperienceSource extends SpecificExperienceSource {
|
||||
}
|
||||
|
||||
|
||||
private class PlayingExperienceSourceManager extends ExperienceSourceManager<PlayExperienceSource> {
|
||||
private static class Manager extends ExperienceSourceManager<PlayExperienceSource> {
|
||||
|
||||
public PlayingExperienceSourceManager() {
|
||||
public Manager() {
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
@ -77,7 +76,7 @@ public class PlayExperienceSource extends SpecificExperienceSource {
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
for (PlayExperienceSource source : getSources())
|
||||
if (source.matchesParameter(playerData, null))
|
||||
giveExperience(playerData, 1, null);
|
||||
source. giveExperience(playerData, 1, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import io.lumine.mythic.lib.util.FlushableRegistry;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
@ -16,10 +17,8 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -30,8 +29,7 @@ public class ProjectileExperienceSource extends SpecificExperienceSource<Project
|
||||
|
||||
public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||
super(dispenser, config);
|
||||
if (!config.contains("type"))
|
||||
projectileType = null;
|
||||
if (!config.contains("type")) projectileType = null;
|
||||
else {
|
||||
String str = config.getString("type").toUpperCase().replace("-", "_");
|
||||
Validate.isTrue(Arrays.stream(ProjectileType.values()).map(ProjectileType::toString).collect(Collectors.toList()).contains(str));
|
||||
@ -41,76 +39,17 @@ public class ProjectileExperienceSource extends SpecificExperienceSource<Project
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<ProjectileExperienceSource> newManager() {
|
||||
|
||||
return new ExperienceSourceManager<ProjectileExperienceSource>() {
|
||||
HashMap<Projectile, Location> projectiles = new HashMap<>();
|
||||
|
||||
@EventHandler(priority = HIGHEST,ignoreCancelled = true)
|
||||
public void onHit(ProjectileHitEvent e) {
|
||||
if (e.getHitBlock() != null && projectiles.containsKey(e.getEntity()))
|
||||
projectiles.remove(e.getEntity());
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = HIGHEST,ignoreCancelled = true)
|
||||
public void onDamage(EntityDamageByEntityEvent e) {
|
||||
|
||||
if (e.getEntity() instanceof Projectile) {
|
||||
Projectile projectile = (Projectile) e.getEntity();
|
||||
if (!projectiles.containsKey(projectile))
|
||||
return;
|
||||
if (projectile.getShooter() instanceof Player && !((Player) projectile.getShooter()).hasMetadata("NPC")) {
|
||||
Player player = (Player) projectile.getShooter();
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
double distance = projectiles.get(projectile).distance(e.getEntity().getLocation());
|
||||
for (ProjectileExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, projectile))
|
||||
source.giveExperience(playerData, e.getFinalDamage() * distance, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
projectiles.remove(projectile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Mark every arrow with the the location at which it was shot to calculate the distance
|
||||
@EventHandler
|
||||
public void onLaunch(ProjectileLaunchEvent e) {
|
||||
if (e.getEntity().getShooter() instanceof Player) {
|
||||
Player player = (Player) e.getEntity().getShooter();
|
||||
if (player.hasMetadata("NPC"))
|
||||
return;
|
||||
|
||||
|
||||
projectiles.put(e.getEntity(), e.getLocation());
|
||||
//Remove the projectile 15 s after it was launched
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
projectiles.remove(e.getEntity());
|
||||
}
|
||||
}.runTaskLater(MMOCore.plugin, 60 * 20L);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, Projectile projectile) {
|
||||
if (projectileType == null)
|
||||
return true;
|
||||
if (projectileType == null) return true;
|
||||
return projectileType.matches(projectile);
|
||||
}
|
||||
|
||||
|
||||
public enum ProjectileType {
|
||||
ARROW((p) -> p instanceof Arrow),
|
||||
TRIDENT((p) -> p instanceof Trident);
|
||||
ARROW((p) -> p instanceof Arrow), TRIDENT((p) -> p instanceof Trident);
|
||||
|
||||
private final Function<Projectile, Boolean> matching;
|
||||
|
||||
@ -124,4 +63,41 @@ public class ProjectileExperienceSource extends SpecificExperienceSource<Project
|
||||
}
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<ProjectileExperienceSource> {
|
||||
private final FlushableRegistry<Projectile, Location> projectiles = new FlushableRegistry<>((proj, loc) -> proj.isDead(), 20 * 60);
|
||||
|
||||
@EventHandler(priority = HIGHEST, ignoreCancelled = true)
|
||||
public void onHit(ProjectileHitEvent e) {
|
||||
if (e.getHitBlock() != null) projectiles.getRegistry().remove(e.getEntity());
|
||||
}
|
||||
|
||||
@EventHandler(priority = HIGHEST, ignoreCancelled = true)
|
||||
public void onDamage(EntityDamageByEntityEvent e) {
|
||||
|
||||
if (e.getEntity() instanceof Projectile) {
|
||||
Projectile projectile = (Projectile) e.getEntity();
|
||||
Location loc = projectiles.getRegistry().get(projectile);
|
||||
if (loc == null) return;
|
||||
|
||||
if (projectile.getShooter() instanceof Player && !((Player) projectile.getShooter()).hasMetadata("NPC")) {
|
||||
Player player = (Player) projectile.getShooter();
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
double distance = loc.distance(e.getEntity().getLocation());
|
||||
for (ProjectileExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, projectile))
|
||||
source.giveExperience(playerData, e.getFinalDamage() * distance, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Mark every arrow with the location at which it was shot to calculate the distance
|
||||
@EventHandler
|
||||
public void onLaunch(ProjectileLaunchEvent e) {
|
||||
if (e.getEntity().getShooter() instanceof Player && UtilityMethods.isRealPlayer((Player) e.getEntity().getShooter())) {
|
||||
projectiles.getRegistry().put(e.getEntity(), e.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ public class RepairItemExperienceSource extends ExperienceSource<ItemStack> {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<RepairItemExperienceSource> newManager() {
|
||||
return new CustomExperienceManager();
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
private class CustomExperienceManager extends ExperienceSourceManager<RepairItemExperienceSource> {
|
||||
private static class Manager extends ExperienceSourceManager<RepairItemExperienceSource> {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(InventoryClickEvent event) {
|
||||
@ -80,8 +80,8 @@ public class RepairItemExperienceSource extends ExperienceSource<ItemStack> {
|
||||
*/
|
||||
final double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType())
|
||||
* Math.max(0, ((Damageable) old.getItemMeta()).getDamage() - ((Damageable) item.getItemMeta()).getDamage()) / 100;
|
||||
getDispenser().giveExperience(data, exp, data.getPlayer().getLocation(), EXPSource.SOURCE);
|
||||
source.getDispenser().giveExperience(data, exp, data.getPlayer().getLocation(), EXPSource.SOURCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
@ -21,39 +22,37 @@ public class ResourceExperienceSource extends SpecificExperienceSource<PlayerRes
|
||||
*/
|
||||
public ResourceExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||
super(dispenser, config);
|
||||
if (!config.contains("type"))
|
||||
resource = null;
|
||||
if (!config.contains("type")) resource = null;
|
||||
else {
|
||||
String str = config.getString("type").toUpperCase().replace("-", "_");
|
||||
Validate.isTrue(str.equals("MANA") || str.equals("STELLIUM") || str.equals("STAMINA"),
|
||||
"ResourceExperienceSource problem: The resource can only be mana, stamina or STELLIUM");
|
||||
Validate.isTrue(str.equals("MANA") || str.equals("STELLIUM") || str.equals("STAMINA"), "ResourceExperienceSource problem: The resource can only be mana, stamina or STELLIUM");
|
||||
resource = PlayerResource.valueOf(str);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<ResourceExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<ResourceExperienceSource>() {
|
||||
@EventHandler(priority = HIGHEST,ignoreCancelled = true)
|
||||
public void onResource(PlayerResourceUpdateEvent e) {
|
||||
if (e.getPlayer().hasMetadata("NPC"))
|
||||
return;
|
||||
PlayerData playerData = PlayerData.get(e.getPlayer());
|
||||
if(e.getAmount()<0)
|
||||
for (ResourceExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, e.getResource()))
|
||||
source.giveExperience(playerData, -e.getAmount(), null);
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, PlayerResource obj) {
|
||||
if (resource == null)
|
||||
return !obj.equals(PlayerResource.HEALTH);
|
||||
if (resource == null) return !obj.equals(PlayerResource.HEALTH);
|
||||
return resource.equals(obj);
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<ResourceExperienceSource> {
|
||||
|
||||
@EventHandler(priority = HIGHEST, ignoreCancelled = true)
|
||||
public void onResource(PlayerResourceUpdateEvent event) {
|
||||
if (!UtilityMethods.isRealPlayer(event.getPlayer())) return;
|
||||
|
||||
PlayerData playerData = PlayerData.get(event.getPlayer());
|
||||
if (event.getAmount() >= 0) return;
|
||||
|
||||
for (ResourceExperienceSource source : getSources())
|
||||
if (source.matchesParameter(playerData, event.getResource()))
|
||||
source.giveExperience(playerData, -event.getAmount(), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
@ -40,29 +41,7 @@ public class RideExperienceSource extends SpecificExperienceSource<EntityType> {
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<RideExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<RideExperienceSource>() {
|
||||
@EventHandler(priority = HIGHEST,ignoreCancelled = true)
|
||||
public void onRide(PlayerMoveEvent e) {
|
||||
|
||||
if (e.getPlayer().isInsideVehicle()) {
|
||||
double deltax = e.getTo().getBlockX() - e.getFrom().getBlockX();
|
||||
double deltay = e.getTo().getBlockY() - e.getFrom().getBlockY();
|
||||
double deltaz = e.getTo().getBlockZ() - e.getFrom().getBlockZ();
|
||||
if (deltax != 0 && deltay != 0 && deltaz != 0) {
|
||||
double delta = Math.sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz);
|
||||
if (e.getPlayer().hasMetadata("NPC"))
|
||||
return;
|
||||
PlayerData playerData = PlayerData.get(e.getPlayer());
|
||||
Entity vehicle = e.getPlayer().getVehicle();
|
||||
for (RideExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, vehicle.getType()))
|
||||
giveExperience(playerData, e.getFrom().distance(e.getTo()), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -72,4 +51,25 @@ public class RideExperienceSource extends SpecificExperienceSource<EntityType> {
|
||||
return type.equals(obj);
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<RideExperienceSource> {
|
||||
|
||||
@EventHandler(priority = HIGHEST, ignoreCancelled = true)
|
||||
public void onRide(PlayerMoveEvent event) {
|
||||
if (!event.getPlayer().isInsideVehicle()) return;
|
||||
|
||||
double deltax = event.getTo().getBlockX() - event.getFrom().getBlockX();
|
||||
double deltay = event.getTo().getBlockY() - event.getFrom().getBlockY();
|
||||
double deltaz = event.getTo().getBlockZ() - event.getFrom().getBlockZ();
|
||||
if (deltax != 0 || deltay != 0 || deltaz != 0) {
|
||||
if (!UtilityMethods.isRealPlayer(event.getPlayer())) return;
|
||||
|
||||
PlayerData playerData = PlayerData.get(event.getPlayer());
|
||||
Entity vehicle = event.getPlayer().getVehicle();
|
||||
for (RideExperienceSource source : getSources()) {
|
||||
if (source.matchesParameter(playerData, vehicle.getType()))
|
||||
source.giveExperience(playerData, event.getFrom().distance(event.getTo()), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -27,43 +27,41 @@ public class SmeltItemExperienceSource extends SpecificExperienceSource<ItemStac
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<SmeltItemExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<SmeltItemExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BlockCookEvent event) {
|
||||
Optional<Player> player = getNearestPlayer(event.getBlock().getLocation());
|
||||
if (!player.isPresent())
|
||||
return;
|
||||
|
||||
ItemStack caught = event.getResult();
|
||||
if (caught.hasItemMeta())
|
||||
return;
|
||||
|
||||
PlayerData data = PlayerData.get(player.get());
|
||||
for (SmeltItemExperienceSource source : getSources())
|
||||
if (source.matches(data, caught))
|
||||
source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Optional<Player> getNearestPlayer(Location loc) {
|
||||
final Player[] nearby = loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100)
|
||||
.toArray(Player[]::new);
|
||||
Player selected = null;
|
||||
double lastDist = 100;
|
||||
for (Player p : nearby) {
|
||||
double currDist = p.getLocation().distance(loc);
|
||||
if (currDist < lastDist) {
|
||||
lastDist = currDist;
|
||||
selected = p;
|
||||
}
|
||||
}
|
||||
return Optional.ofNullable(selected);
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, ItemStack obj) {
|
||||
return obj.getType() == material;
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<SmeltItemExperienceSource> {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void a(BlockCookEvent event) {
|
||||
Optional<Player> player = getNearestPlayer(event.getBlock().getLocation());
|
||||
if (!player.isPresent()) return;
|
||||
|
||||
ItemStack caught = event.getResult();
|
||||
if (caught.hasItemMeta()) return;
|
||||
|
||||
PlayerData data = PlayerData.get(player.get());
|
||||
for (SmeltItemExperienceSource source : getSources())
|
||||
if (source.matches(data, caught)) source.giveExperience(data, 1, event.getBlock().getLocation());
|
||||
}
|
||||
|
||||
private Optional<Player> getNearestPlayer(Location loc) {
|
||||
final Player[] nearby = loc.getWorld().getPlayers().stream().filter(player -> player.getLocation().distanceSquared(loc) < 100).toArray(Player[]::new);
|
||||
Player selected = null;
|
||||
double lastDist = 100;
|
||||
for (Player p : nearby) {
|
||||
double currDist = p.getLocation().distance(loc);
|
||||
if (currDist < lastDist) {
|
||||
lastDist = currDist;
|
||||
selected = p;
|
||||
}
|
||||
}
|
||||
return Optional.ofNullable(selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.Indyuce.mmocore.experience.source;
|
||||
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.MMOLineConfig;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
@ -7,38 +8,44 @@ import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser;
|
||||
import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource;
|
||||
import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityTameEvent;
|
||||
|
||||
public class TameExperienceSource extends SpecificExperienceSource {
|
||||
public class TameExperienceSource extends SpecificExperienceSource<EntityType> {
|
||||
public TameExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) {
|
||||
super(dispenser, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExperienceSourceManager<TameExperienceSource> newManager() {
|
||||
return new ExperienceSourceManager<TameExperienceSource>() {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST,ignoreCancelled = true)
|
||||
public void onWolfHit(EntityDamageByEntityEvent e) {
|
||||
if(e.getDamager() instanceof Wolf) {
|
||||
Wolf wolf= (Wolf) e.getDamager();
|
||||
if(wolf.getOwner() instanceof Player &&!((Player) wolf.getOwner()).hasMetadata("NPC")) {
|
||||
PlayerData playerData=PlayerData.get((OfflinePlayer) wolf.getOwner());
|
||||
for(TameExperienceSource source:getSources()) {
|
||||
source.giveExperience(playerData,e.getDamage(), MMOCoreUtils.getCenterLocation(e.getEntity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return new Manager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesParameter(PlayerData player, Object obj) {
|
||||
return false;
|
||||
public boolean matchesParameter(PlayerData player, EntityType entityType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class Manager extends ExperienceSourceManager<TameExperienceSource> {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onWolfHit(EntityTameEvent event) {
|
||||
|
||||
// Only wolves at the moment
|
||||
if (!(event.getEntity() instanceof Wolf)) return;
|
||||
|
||||
if (!(event.getOwner() instanceof Player) || !UtilityMethods.isRealPlayer((Entity) event.getOwner()))
|
||||
return;
|
||||
|
||||
PlayerData playerData = PlayerData.get((OfflinePlayer) event.getOwner());
|
||||
for (TameExperienceSource source : getSources())
|
||||
if (source.matches(playerData, event.getEntity().getType()))
|
||||
source.giveExperience(playerData, 1, MMOCoreUtils.getCenterLocation(event.getEntity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user