diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java new file mode 100644 index 00000000..4ae857b1 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java @@ -0,0 +1,66 @@ +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.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.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; + +public class ClimbExperienceSource extends SpecificExperienceSource { + //Can be Ladder,Vines,Twisting Vines,Weeping Vines. + private final Material type; + + /** + *Gives Experience when a player climbs on a ladder, a vine, a twisting vine or a weeping vine depending + * on the type precised (if no type is precised it will give xp for the 4) + * The xp given depends on the vertical distance travelled, the random amount given correspond + * to the xp when you climb, one block + */ + public ClimbExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + //If no type precised Ladder and all vines types work + if (!config.contains("type")) + type = null; + else { + String str = config.getString("type").toUpperCase().replace("-", "_"); + Validate.isTrue(str.equals("ladder") || + str.equals("vines") || str.equals("twisting-vines") || str.equals("weeping-vines"), + "The type must be ladder, vine, twisted-vines or weeping-vines"); + type = Material.valueOf(str); + } + + + } + + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onClimb(PlayerMoveEvent e) { + if(e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData=PlayerData.get(e.getPlayer()); + double delta=e.getTo().getY()-e.getFrom().getY(); + if(delta>0) { + for(ClimbExperienceSource source:getSources()) { + if(source.matchesParameter(playerData,e.getTo().getBlock().getType())) + source.giveExperience(playerData,delta,null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Material material) { + if (type == null) + return material.equals(Material.LADDER) || material.equals(Material.VINE) || + material.equals(Material.WEEPING_VINES) || material.equals(Material.TWISTING_VINES); + return type.equals(material); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java new file mode 100644 index 00000000..b87dd880 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageDealtExperienceSource.java @@ -0,0 +1,72 @@ +package net.Indyuce.mmocore.experience.source; + +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; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.event.EventHandler; +import scala.Enumeration; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class DamageDealtExperienceSource extends SpecificExperienceSource { + private final DamageType type; + + /** + *Gives experience when a player deals damage of a certain type. If no type is given it will give xp for all + * the damage type. The random value you give correspond to the xp you get per damage dealt. + */ + + public DamageDealtExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("damage-type")) + type = null; + else { + String str = config.getString("damage-type").toUpperCase().replace("-", "_"); + //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), + "damage-type value not allowed. Damage type value allowed: magic, physical, weapon, skill, projectile," + + " unarmed, on-hit, minion, dot."); + type = DamageType.valueOf(str); + + }} + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onDamageDealt(PlayerAttackEvent e) { + if(e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData=PlayerData.get(e.getPlayer()); + for(DamagePacket packet:e.getDamage().getPackets()) { + for(DamageType damageType:packet.getTypes()) { + + for(DamageDealtExperienceSource source: getSources()) { + if(source.matchesParameter(playerData,damageType)) + source.giveExperience(playerData, packet.getFinalValue(), null); + } + } + + } + + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, DamageType damageType) { + if(type==null) + return true; + else + return type.equals(damageType); + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java new file mode 100644 index 00000000..3c2f31c5 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java @@ -0,0 +1,62 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmocore.api.player.PlayerData; +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.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class DamageTakenExperienceSource extends SpecificExperienceSource { + private final EntityDamageEvent.DamageCause cause; + + /** + *Gives experience when a player takes damage from a certain cause. If no cause is given it will give xp for all + * the damage causes. The random value you give correspond to the xp you get per damage taken. + */ + public DamageTakenExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if(!config.contains("damage-cause")) + cause=null; + else { + String str = config.getString("damage-cause").toUpperCase().replace("-", "_"); + //Checks if the damage type correspond to a value of the damage type enum + Validate.isTrue(Arrays.stream(EntityDamageEvent.DamageCause.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "damage-type value not allowed. Go check at all the Damage Causes in EntityDamageEvent.DamageCause enum."); + cause = EntityDamageEvent.DamageCause.valueOf(str); + } + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onDamageTaken(EntityDamageEvent e) { + if (e.getEntity() instanceof Player && !e.getEntity().hasMetadata("NPC")) { + double amount = e.getDamage(); + PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity()); + for (DamageTakenExperienceSource source : getSources()) { + if(source.matchesParameter(playerData,e.getCause())) + source.giveExperience(playerData, amount, null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, EntityDamageEvent.DamageCause damageCause) { + if(cause==null) + return true; + return damageCause.equals(cause); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java new file mode 100644 index 00000000..505f311b --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java @@ -0,0 +1,80 @@ +package net.Indyuce.mmocore.experience.source; + +import com.mojang.datafixers.types.Func; +import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmocore.api.player.PlayerData; +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.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; +import org.xml.sax.SAXParseException; + +import java.util.Arrays; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class MoveExperienceSource extends SpecificExperienceSource { + MovingType type; + + + + public MoveExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("moving-type")) + type = null; + else { + String str = config.getString("moving-type").toUpperCase().replace("-", "_"); + //Checks if the damage type correspond to a value of the damage type enum + Validate.isTrue(Arrays.stream(MoveExperienceSource.MovingType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "moving-type value not allowed. Moving type values allowed: sneaking, flying, swimming, sprinting, walking."); + type = MovingType.valueOf(str); + } + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onMove(PlayerMoveEvent e) { + 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,e.getTo().distance(e.getFrom()),null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + return type.matches(player.getPlayer()); + } + + public enum MovingType { + SNEAKING(Player::isSneaking), + FLYING(Player::isFlying), + SWIMMING(Player::isSwimming), + SPRINTING(Player::isSprinting), + WALKING((p) -> !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.isSwimming()); + + private final Function matching; + + MovingType(Function matching) { + this.matching = matching; + } + + public boolean matches(Player player) { + return matching.apply(player); + } + + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java new file mode 100644 index 00000000..63dd4344 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/PlayingExperienceSource.java @@ -0,0 +1,88 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.bukkit.BukkitAdapter; +import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; +import net.Indyuce.mmocore.loot.chest.RegionBounds; +import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.scheduler.BukkitRunnable; + +public class PlayingExperienceSource extends SpecificExperienceSource { + + private final World world; + private final double x1, x2, z1, z2; + + /** + * Experience source giving the specified amount of xp to all the players online each second in certain world bounds. + *If no bounds are given, it will give the xp to every player online. + */ + public PlayingExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + + if (!config.contains("world")) + world = null; + else { + String name = config.getString("world"); + Validate.notNull(world = Bukkit.getWorld(name), "Could not find world " + config.getString("world")); + } + if (!config.contains("x1") || !config.contains("x2")) { + x1 = Double.NEGATIVE_INFINITY; + x2 = Double.POSITIVE_INFINITY; + } else { + x1 = Math.min(config.getInt("x1"), config.getInt("x2")); + x2 = Math.max(config.getInt("x1"), config.getInt("x2")); + } + if (!config.contains("z1") || !config.contains("z2")) { + z1 = Double.NEGATIVE_INFINITY; + z2 = Double.POSITIVE_INFINITY; + } else { + z1 = Math.min(config.getInt("z1"), config.getInt("z2")); + z2 = Math.max(config.getInt("z1"), config.getInt("z2")); + } + } + + @Override + public ExperienceSourceManager newManager() { + return new PlayingExperienceSourceManager(); + + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + if (world == null) + return true; + Location location = player.getPlayer().getLocation(); + return location.getWorld().equals(world) && location.getX() > x1 && location.getX() < x2 + && location.getZ() > z1 && location.getZ() < z2; + } + + + private class PlayingExperienceSourceManager extends ExperienceSourceManager { + + public PlayingExperienceSourceManager() { + new BukkitRunnable() { + + @Override + public void run() { + Bukkit.getOnlinePlayers().forEach((player) -> { + if (!player.hasMetadata("NPC")) { + PlayerData playerData = PlayerData.get(player); + for (PlayingExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, null)) + giveExperience(playerData, 1, null); + } + } + }); + } + + }.runTaskTimer(MMOCore.plugin, 0, 20); + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java new file mode 100644 index 00000000..b912354d --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java @@ -0,0 +1,114 @@ +package net.Indyuce.mmocore.experience.source; + +import de.schlichtherle.key.passwd.swing.BasicUnknownKeyFeedback; +import io.lumine.mythic.core.skills.mechanics.ShootMechanic; +import io.lumine.mythic.lib.api.MMOLineConfig; +import me.glaremasters.guilds.utils.BackupUtils; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +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.Location; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; + +public class ProjectileExperienceSource extends SpecificExperienceSource { + + ProjectileType projectileType; + + public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + Validate.isTrue(config.contains("type")); + projectileType = ProjectileType.valueOf(config.getString("type").toUpperCase().replace("-", "_")); + } + + @Override + public ExperienceSourceManager newManager() { + + return new ExperienceSourceManager() { + HashMap projectiles = new HashMap<>(); + + @EventHandler + public void onHit(EntityDamageByEntityEvent e) { + Entity entity = e.getDamager(); + if (e.getEntity() instanceof Projectile) { + Projectile projectile = (Projectile) e.getDamager(); + if (projectile.getShooter() instanceof Player && !((Player) projectile.getShooter()).hasMetadata("NPC")) { + Player player = (Player) projectile.getShooter(); + PlayerData playerData = PlayerData.get(player); + Validate.isTrue(projectiles.containsKey(projectile)); + double distance = projectiles.get(projectile).distance(e.getDamager().getLocation()); + for (ProjectileExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, projectile)) + source.giveExperience(playerData, e.getFinalDamage() * distance, null); + } + + + } + } + + } + + //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 && e.getEntity() instanceof Arrow) { + 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, 15 * 20L); + + + } + } + + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Projectile projectile) { + return projectileType.matches(projectile); + } + + + public enum ProjectileType { + ARROW(Arrow.class), + TRIDENT(Trident.class), + FIREBALL(Fireball.class), + FISH_HOOK(FishHook.class), + ; + + private final Class clazz; + + ProjectileType(Class clazz) { + this.clazz = clazz; + } + + public Class getType() { + return clazz; + } + + public boolean matches(Projectile projectile) { + return projectile.getClass().isAssignableFrom(getType()); + } + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java new file mode 100644 index 00000000..f4a2c472 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java @@ -0,0 +1,65 @@ +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.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.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class RideExperienceSource extends SpecificExperienceSource> { + private final EntityType type; + + /** + *Gives experience when a player moves riding a certain entity. If no entity type is given it will give xp if you move + *while riding an entity whatever it is. + *The random value you give correspond to the xp you get per block travelled while riding. + */ + public RideExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("entity-type")) + type = null; + else { + String str = config.getString("entity-type").toUpperCase().replace("-", "_"); + Validate.isTrue(Arrays.stream(EntityType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "The entity-type must correspond to an entity that exist in the game."); + type=EntityType.valueOf(str); + } + + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + public void onRide(PlayerMoveEvent e) { + if (e.getPlayer().hasMetadata("NPC")) + return; + PlayerData playerData=PlayerData.get(e.getPlayer()); + if(e.getPlayer().isInsideVehicle()) { + Entity vehicle=e.getPlayer().getVehicle(); + for(RideExperienceSource source:getSources()) { + if(source.matchesParameter(playerData,vehicle.getClass())) + giveExperience(playerData,e.getFrom().distance(e.getTo()),null); + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Class obj) { + if(type==null) + return true; + return type.getEntityClass().isAssignableFrom(obj); + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/TamingExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/TamingExperienceSource.java new file mode 100644 index 00000000..a5ea2e3a --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/TamingExperienceSource.java @@ -0,0 +1,47 @@ +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.api.util.MMOCoreUtils; +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.Player; +import org.bukkit.entity.Wolf; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import javax.swing.text.html.parser.Entity; + +public class TamingExperienceSource extends SpecificExperienceSource { + + + public TamingExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + 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(TamingExperienceSource source:getSources()) { + source.giveExperience(playerData,e.getDamage(), MMOCoreUtils.getCenterLocation(e.getEntity())); + } + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + return false; + } +}