diff --git a/pom.xml b/pom.xml index e0540704..51b355ac 100644 --- a/pom.xml +++ b/pom.xml @@ -39,10 +39,21 @@ + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + C:\Users\guill\Minecraft Server\Server\plugins + + + + org.apache.maven.plugins maven-compiler-plugin 3.8.1 + 9 9 @@ -215,6 +226,33 @@ provided + + + me.blackvein + Quests + 4.4.1-b340 + provided + + + fr.skytasul.quests + BeautyQuests + 0.19.5 + provided + + + com.guillaumevdn + QuestCreator + 6.39.0 + provided + + + com.guillaumevdn + GCore + 8.39.0 + provided + + + com.massivecraft diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index cd21f590..aa2bec6f 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -230,6 +230,19 @@ public class MMOCore extends LuminePlugin { DebugMode.enableActionBar(); } + // Load quest module + try { + String questPluginName = UtilityMethods.enumName(getConfig().getString("quest-plugin")); + PartyModuleType moduleType = PartyModuleType.valueOf(questPluginName); + Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed"); + partyModule = moduleType.provideModule(); + } catch (RuntimeException exception) { + getLogger().log(Level.WARNING, "Could not initialize quest module: " + exception.getMessage()); + partyModule = new MMOCorePartyModule(); + } + + + // Load party module try { String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin")); @@ -241,6 +254,7 @@ public class MMOCore extends LuminePlugin { partyModule = new MMOCorePartyModule(); } + // Skill casting try { SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode"))); diff --git a/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java index 72ed5928..bd48b40d 100644 --- a/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java +++ b/src/main/java/net/Indyuce/mmocore/api/event/PlayerExperienceGainEvent.java @@ -16,14 +16,14 @@ public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancel private final Profession profession; private final EXPSource source; - private int experience; + private double experience; private boolean cancelled; - public PlayerExperienceGainEvent(PlayerData player, int experience, EXPSource source) { + public PlayerExperienceGainEvent(PlayerData player, double experience, EXPSource source) { this(player, null, experience, source); } - public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, int experience, EXPSource source) { + public PlayerExperienceGainEvent(PlayerData player, @Nullable Profession profession, double experience, EXPSource source) { super(player); this.profession = profession; @@ -31,7 +31,7 @@ public class PlayerExperienceGainEvent extends PlayerDataEvent implements Cancel this.source = source; } - public int getExperience() { + public double getExperience() { return experience; } diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index 074b123d..9ec22aca 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -1,26 +1,19 @@ package net.Indyuce.mmocore.api.load; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; -import net.Indyuce.mmocore.loot.droptable.condition.*; +import net.Indyuce.mmocore.experience.source.*; +import net.Indyuce.mmocore.loot.chest.condition.*; import org.bukkit.configuration.ConfigurationSection; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; + import net.Indyuce.mmocore.loot.droptable.dropitem.DropTableDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.GoldDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.NoteDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.VanillaDropItem; -import net.Indyuce.mmocore.experience.source.BrewPotionExperienceSource; -import net.Indyuce.mmocore.experience.source.CraftItemExperienceSource; -import net.Indyuce.mmocore.experience.source.EnchantItemExperienceSource; -import net.Indyuce.mmocore.experience.source.FishItemExperienceSource; -import net.Indyuce.mmocore.experience.source.KillMobExperienceSource; -import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource; -import net.Indyuce.mmocore.experience.source.PlaceBlockExperienceSource; -import net.Indyuce.mmocore.experience.source.RepairItemExperienceSource; -import net.Indyuce.mmocore.experience.source.SmeltItemExperienceSource; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.api.quest.objective.ClickonObjective; import net.Indyuce.mmocore.api.quest.objective.GoToObjective; @@ -40,130 +33,154 @@ import io.lumine.mythic.lib.api.MMOLineConfig; public class DefaultMMOLoader extends MMOLoader { - @Override - public Trigger loadTrigger(MMOLineConfig config) { - if (config.getKey().equals("message")) - return new MessageTrigger(config); + @Override + public Trigger loadTrigger(MMOLineConfig config) { + if (config.getKey().equals("message")) + return new MessageTrigger(config); - if (config.getKey().equals("sound") || config.getKey().equals("playsound")) - return new SoundTrigger(config); + if (config.getKey().equals("sound") || config.getKey().equals("playsound")) + return new SoundTrigger(config); - if (config.getKey().equals("mana")) - return new ManaTrigger(config); + if (config.getKey().equals("mana")) + return new ManaTrigger(config); - if (config.getKey().equals("stamina")) - return new StaminaTrigger(config); - - if (config.getKey().equals("stellium")) - return new StelliumTrigger(config); + if (config.getKey().equals("stamina")) + return new StaminaTrigger(config); - if (config.getKey().equals("command")) - return new CommandTrigger(config); + if (config.getKey().equals("stellium")) + return new StelliumTrigger(config); - if (config.getKey().equals("item") || config.getKey().equals("vanilla")) - return new ItemTrigger(config); + if (config.getKey().equals("command")) + return new CommandTrigger(config); - if (config.getKey().equals("exp") || config.getKey().equals("experience")) - return new ExperienceTrigger(config); + if (config.getKey().equals("item") || config.getKey().equals("vanilla")) + return new ItemTrigger(config); - return null; - } + if (config.getKey().equals("exp") || config.getKey().equals("experience")) + return new ExperienceTrigger(config); - @Override - public DropItem loadDropItem(MMOLineConfig config) { - if (config.getKey().equals("droptable")) - return new DropTableDropItem(config); + return null; + } - if (config.getKey().equals("vanilla")) - return new VanillaDropItem(config); + @Override + public DropItem loadDropItem(MMOLineConfig config) { + if (config.getKey().equals("droptable")) + return new DropTableDropItem(config); - if (config.getKey().equals("note")) - return new NoteDropItem(config); + if (config.getKey().equals("vanilla")) + return new VanillaDropItem(config); - if (config.getKey().equals("gold") || config.getKey().equals("coin")) - return new GoldDropItem(config); + if (config.getKey().equals("note")) + return new NoteDropItem(config); - return null; - } + if (config.getKey().equals("gold") || config.getKey().equals("coin")) + return new GoldDropItem(config); - @Override - public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) { - if (config.getKey().equals("goto")) - return new GoToObjective(section, config); + return null; + } - if (config.getKey().equals("mineblock")) - return new MineBlockObjective(section, config); + @Override + public Objective loadObjective(MMOLineConfig config, ConfigurationSection section) { + if (config.getKey().equals("goto")) + return new GoToObjective(section, config); - if (config.getKey().equals("killmob")) - return new KillMobObjective(section, config); + if (config.getKey().equals("mineblock")) + return new MineBlockObjective(section, config); - if (config.getKey().equals("clickon")) - return new ClickonObjective(section, config); + if (config.getKey().equals("killmob")) + return new KillMobObjective(section, config); - return null; - } + if (config.getKey().equals("clickon")) + return new ClickonObjective(section, config); - @Override - public Condition loadCondition(MMOLineConfig config) { - if(config.getKey().equals("distance")) - return new DistanceCondition(config); + return null; + } - if (config.getKey().equals("world")) - return new WorldCondition(config); + @Override + public Condition loadCondition(MMOLineConfig config) { + if (config.getKey().equals("distance")) + return new DistanceCondition(config); - if (config.getKey().equals("biome")) - return new BiomeCondition(config); + if (config.getKey().equals("world")) + return new WorldCondition(config); - if (config.getKey().equals("level")) - return new LevelCondition(config); - - if (config.getKey().equals("permission")) - return new PermissionCondition(config); + if (config.getKey().equals("biome")) + return new BiomeCondition(config); - return null; - } + if (config.getKey().equals("level")) + return new LevelCondition(config); - @Override - public ExperienceSource loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) { - if (config.getKey().equals("fishitem")) - return new FishItemExperienceSource(dispenser, config); + if (config.getKey().equals("permission")) + return new PermissionCondition(config); - if (config.getKey().equals("killmob")) - return new KillMobExperienceSource(dispenser, config); + return null; + } - if (config.getKey().equals("mineblock")) - return new MineBlockExperienceSource(dispenser, config); + @Override + public ExperienceSource loadExperienceSource(MMOLineConfig config, ExperienceDispenser dispenser) { + if (config.getKey().equals("resource")) + return new ResourceExperienceSource(dispenser, config); - if (config.getKey().equals("placeblock")) - return new PlaceBlockExperienceSource(dispenser, config); + if (config.getKey().equals("climb")) + return new ClimbExperienceSource(dispenser, config); - if (config.getKey().equals("brewpotion")) - return new BrewPotionExperienceSource(dispenser, config); + if (config.getKey().equals("damagedealt")) + return new DamageDealtExperienceSource(dispenser, config); - if (config.getKey().equals("smeltitem")) - return new SmeltItemExperienceSource(dispenser, config); + if (config.getKey().equals("damagetaken")) + return new DamageTakenExperienceSource(dispenser, config); - if (config.getKey().equals("enchantitem")) - return new EnchantItemExperienceSource(dispenser, config); + if (config.getKey().equals("move")) + return new MoveExperienceSource(dispenser, config); - if (config.getKey().equals("repairitem")) - return new RepairItemExperienceSource(dispenser, config); + if (config.getKey().equals("play")) + return new PlayExperienceSource(dispenser, config); - if (config.getKey().equals("craftitem")) - return new CraftItemExperienceSource(dispenser, config); + if (config.getKey().equals("projectile")) + return new ProjectileExperienceSource(dispenser, config); - return null; - } + if (config.getKey().equals("ride")) + return new RideExperienceSource(dispenser, config); - @Override - public BlockType loadBlockType(MMOLineConfig config) { + if (config.getKey().equals("tame")) + return new TameExperienceSource(dispenser, config); - if (config.getKey().equalsIgnoreCase("vanilla")) - return new VanillaBlockType(config); - - if (config.getKey().equalsIgnoreCase("skull") || config.getKey().equals("head") || config.getKey().equals("playerhead")) - return new SkullBlockType(config); + if (config.getKey().equals("killmob")) + return new KillMobExperienceSource(dispenser, config); - return null; - } + if (config.getKey().equals("mineblock")) + return new MineBlockExperienceSource(dispenser, config); + + if (config.getKey().equals("placeblock")) + return new PlaceBlockExperienceSource(dispenser, config); + + if (config.getKey().equals("brewpotion")) + return new BrewPotionExperienceSource(dispenser, config); + + if (config.getKey().equals("smeltitem")) + return new SmeltItemExperienceSource(dispenser, config); + + if (config.getKey().equals("enchantitem")) + return new EnchantItemExperienceSource(dispenser, config); + + if (config.getKey().equals("repairitem")) + return new RepairItemExperienceSource(dispenser, config); + + if (config.getKey().equals("craftitem")) + return new CraftItemExperienceSource(dispenser, config); + + return null; + } + + @Override + public BlockType loadBlockType(MMOLineConfig config) { + + if (config.getKey().equalsIgnoreCase("vanilla")) + return new VanillaBlockType(config); + + if (config.getKey().equalsIgnoreCase("skull") || config.getKey().equals("head") || config.getKey().equals("playerhead")) + return new SkullBlockType(config); + + return null; + } } diff --git a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java index c3065e0e..c1bed441 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/MMOLoader.java @@ -2,7 +2,7 @@ package net.Indyuce.mmocore.api.load; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; diff --git a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index 9bb4c523..e2ca69ab 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -68,7 +68,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc */ @Nullable private PlayerClass profess; - private int level, experience, classPoints, skillPoints, attributePoints, attributeReallocationPoints;// skillReallocationPoints, + private int level, classPoints, skillPoints, attributePoints, attributeReallocationPoints;// skillReallocationPoints, + private double experience; private double mana, stamina, stellium; private Guild guild; private SkillCastingHandler skillCasting; @@ -322,7 +323,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc giveExperience(total, source); } - public void setExperience(int value) { + public void setExperience(double value) { experience = Math.max(0, value); refreshVanillaExp(); } @@ -518,7 +519,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * @param value Experience to give the player * @param source How the player earned experience */ - public void giveExperience(int value, EXPSource source) { + public void giveExperience(double value, EXPSource source) { giveExperience(value, source, null, true); } @@ -552,7 +553,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc member.giveExperience(value, EXPSource.PARTY_SHARING, null, false); } - PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, (int) value, source); + PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(this, value, source); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; @@ -593,7 +594,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc refreshVanillaExp(); } - public int getExperience() { + public double getExperience() { return experience; } diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java index 21bed8f3..f5d2698e 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/SavedClassInformation.java @@ -17,13 +17,14 @@ import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.manager.data.PlayerDataManager.DefaultPlayerData; public class SavedClassInformation { - private final int level, experience, skillPoints, attributePoints, attributeReallocationPoints; + private final int level, skillPoints, attributePoints, attributeReallocationPoints; + private final double experience; private final Map attributes; private final Map skills; public SavedClassInformation(ConfigurationSection config) { level = config.getInt("level"); - experience = config.getInt("experience"); + experience = config.getDouble("experience"); skillPoints = config.getInt("skill-points"); attributePoints = config.getInt("attribute-points"); attributeReallocationPoints = config.getInt("attribute-realloc-points"); @@ -38,7 +39,7 @@ public class SavedClassInformation { public SavedClassInformation(JsonObject json) { level = json.get("level").getAsInt(); - experience = json.get("experience").getAsInt(); + experience = json.get("experience").getAsDouble(); skillPoints = json.get("skill-points").getAsInt(); attributePoints = json.get("attribute-points").getAsInt(); attributeReallocationPoints = json.get("attribute-realloc-points").getAsInt(); @@ -63,11 +64,11 @@ public class SavedClassInformation { this(data.getLevel(), 0, data.getSkillPoints(), data.getAttributePoints(), data.getAttrReallocPoints()); } - public SavedClassInformation(int level, int experience, int skillPoints, int attributePoints, int attributeReallocationPoints) { + public SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints) { this(level, experience, skillPoints, attributePoints, attributeReallocationPoints, new HashMap<>(), new HashMap<>()); } - private SavedClassInformation(int level, int experience, int skillPoints, int attributePoints, int attributeReallocationPoints, + private SavedClassInformation(int level, double experience, int skillPoints, int attributePoints, int attributeReallocationPoints, Map attributes, Map skills) { this.level = level; this.experience = experience; @@ -82,7 +83,7 @@ public class SavedClassInformation { return level; } - public int getExperience() { + public double getExperience() { return experience; } diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java index dbe80a15..c8b8a9d0 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/RegionCondition.java @@ -3,8 +3,8 @@ package net.Indyuce.mmocore.comp.region; import java.util.Arrays; import java.util.List; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import io.lumine.mythic.lib.api.MMOLineConfig; public class RegionCondition extends Condition { diff --git a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java index 0c771cf7..735ebda6 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/comp/region/WorldGuardMMOLoader.java @@ -1,6 +1,6 @@ package net.Indyuce.mmocore.comp.region; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.api.load.MMOLoader; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java index 1c84c39e..2caddb5b 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java +++ b/src/main/java/net/Indyuce/mmocore/experience/PlayerProfessions.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.Map.Entry; public class PlayerProfessions { - private final Map exp = new HashMap<>(); + private final Map exp = new HashMap<>(); private final Map level = new HashMap<>(); private final PlayerData playerData; @@ -41,7 +41,7 @@ public class PlayerProfessions { public PlayerProfessions load(ConfigurationSection config) { for (String key : config.getKeys(false)) if (MMOCore.plugin.professionManager.has(key)) { - exp.put(key, config.getInt(key + ".exp")); + exp.put(key, config.getDouble(key + ".exp")); level.put(key, config.getInt(key + ".level")); } @@ -89,7 +89,7 @@ public class PlayerProfessions { for (Entry entry : obj.entrySet()) if (MMOCore.plugin.professionManager.has(entry.getKey())) { JsonObject value = entry.getValue().getAsJsonObject(); - exp.put(entry.getKey(), value.get("exp").getAsInt()); + exp.put(entry.getKey(), value.get("exp").getAsDouble()); level.put(entry.getKey(), value.get("level").getAsInt()); } @@ -111,11 +111,11 @@ public class PlayerProfessions { return getLevel(profession.getId()); } - public int getExperience(String id) { - return exp.getOrDefault(id, 0); + public double getExperience(String id) { + return exp.getOrDefault(id, 0.); } - public int getExperience(Profession profession) { + public double getExperience(Profession profession) { return getExperience(profession.getId()); } @@ -136,7 +136,7 @@ public class PlayerProfessions { level.put(profession.getId(), Math.max(1, current - value)); } - public void setExperience(Profession profession, int value) { + public void setExperience(Profession profession, double value) { exp.put(profession.getId(), value); } @@ -147,7 +147,7 @@ public class PlayerProfessions { giveExperience(profession, total, source); } - public void giveExperience(Profession profession, int value, EXPSource source) { + public void giveExperience(Profession profession, double value, EXPSource source) { giveExperience(profession, value, source, null); } @@ -174,13 +174,14 @@ public class PlayerProfessions { if (hologramLocation != null) MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message()); - PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, (int) value, source); + PlayerExperienceGainEvent event = new PlayerExperienceGainEvent(playerData, profession, value, source); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; - exp.put(profession.getId(), Math.max(0, exp.getOrDefault(profession.getId(), 0) + event.getExperience())); - int needed, exp, level, oldLevel = getLevel(profession); + exp.put(profession.getId(), Math.max(0, exp.getOrDefault(profession.getId(), 0.) + event.getExperience())); + int level, oldLevel = getLevel(profession); + double needed,exp; /* * Loop for exp overload when leveling up, will continue @@ -197,7 +198,7 @@ public class PlayerProfessions { this.exp.put(profession.getId(), exp - needed); this.level.put(profession.getId(), level + 1); check = true; - playerData.giveExperience((int) profession.getExperience().calculate(level), null); + playerData.giveExperience(profession.getExperience().calculate(level), null); } if (check) { diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java index 8be7dfe0..917f7b14 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java +++ b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ClassExperienceDispenser.java @@ -17,7 +17,7 @@ public class ClassExperienceDispenser implements ExperienceDispenser { @Override public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { hologramLocation = !MMOCore.plugin.getConfig().getBoolean("display-main-class-exp-holograms") ? null - : hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation; + : hologramLocation; playerData.giveExperience(experience, source, hologramLocation, true); } diff --git a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java index af385fc1..273a05b2 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java +++ b/src/main/java/net/Indyuce/mmocore/experience/dispenser/ProfessionExperienceDispenser.java @@ -16,7 +16,7 @@ public class ProfessionExperienceDispenser implements ExperienceDispenser { @Override public void giveExperience(PlayerData playerData, double experience, @Nullable Location hologramLocation, EXPSource source) { hologramLocation = !profession.getOption(Profession.ProfessionOption.EXP_HOLOGRAMS) ? null - : hologramLocation == null ? getPlayerLocation(playerData) : hologramLocation; + : hologramLocation; playerData.getCollectionSkills().giveExperience(profession, experience, EXPSource.SOURCE, hologramLocation); } diff --git a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java index e676156b..4ba8028c 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java +++ b/src/main/java/net/Indyuce/mmocore/experience/droptable/ExperienceItem.java @@ -13,7 +13,10 @@ import java.util.Random; public class ExperienceItem { private final String id; + + //A period of 0 means the item will only trigger one time. private final int period; + private final int firstTrigger; private final double claimChance, failReduction; private final List triggers; @@ -23,6 +26,7 @@ public class ExperienceItem { * One item for an experience table * * @param period The experience item is claimed every X level ups + * @param firstTrigger The experience item if claimed for the first time at X level ups. * @param claimChance Chance for that item to be claimed every X level ups * @param failReduction Between 0 and 1, by how much the fail chance is reduced * every time the item is not claimed when leveling up. @@ -32,19 +36,22 @@ public class ExperienceItem { * where n is the amount of successive claiming fails * @param triggers Actions cast when the exp item is claimed */ - public ExperienceItem(String id, int period, double claimChance, double failReduction, List triggers) { + public ExperienceItem(String id, int period, int firstTrigger,double claimChance, double failReduction, List triggers) { this.id = id; this.period = period; this.claimChance = claimChance; this.failReduction = failReduction; this.triggers = triggers; + this.firstTrigger=firstTrigger; } public ExperienceItem(ConfigurationSection config) { Validate.notNull(config, "Config cannot be null"); Validate.isTrue(config.contains("triggers")); id = config.getName(); - period = config.getInt("period", 1); + + period = config.getInt("period", 0); + firstTrigger=config.getInt("first-trigger",period); claimChance = config.getDouble("chance", 100) / 100; failReduction = config.getDouble("fail-reduction", 80) / 100; triggers = new ArrayList<>(); @@ -64,7 +71,7 @@ public class ExperienceItem { * account the randomness factor from the 'chance' parameter */ public boolean roll(int professionLevel, int timesCollected) { - int claimsRequired = professionLevel - (timesCollected + 1) * period; + int claimsRequired = professionLevel+1 - (firstTrigger-+timesCollected * period); if (claimsRequired < 1) return false; diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java index a5c085b7..a0f6b5bf 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/BrewPotionExperienceSource.java @@ -168,7 +168,7 @@ public class BrewPotionExperienceSource extends ExperienceSource { */ // exp += getTotal(mapEffectDurations()); - getDispenser().giveExperience(PlayerData.get(player), (int) exp * multiplier, null, EXPSource.SOURCE); + getDispenser().giveExperience(PlayerData.get(player), exp * multiplier, player.getLocation(), EXPSource.SOURCE); } } } 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..c26ebd0a --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ClimbExperienceSource.java @@ -0,0 +1,75 @@ +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.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +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("VINE") || str.equals("TWISTING_VINES_PLANT") || str.equals("WEEPING_VINES"), + "ClimbExperienceSource problem: 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) { + 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); + } + } + } + }; + } + + @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) || + material.equals(Material.WEEPING_VINES_PLANT) || material.equals(Material.TWISTING_VINES_PLANT); + if (type.equals(Material.WEEPING_VINES)) + return material.equals(Material.WEEPING_VINES) || material.equals(Material.WEEPING_VINES_PLANT); + if (type.equals(Material.TWISTING_VINES)) + return material.equals(Material.TWISTING_VINES) || material.equals(Material.TWISTING_VINES_PLANT); + return material.equals(type); + + } +} 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..7e1c91ac --- /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("type")) + type = null; + else { + String str = config.getString("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), + "Type value not allowed. 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) { + 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(); + } + + } + source.giveExperience(playerData, value, 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..d361d3a4 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/DamageTakenExperienceSource.java @@ -0,0 +1,72 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.damage.DamageType; +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.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.scheduler.BukkitRunnable; + +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("cause")) + cause = null; + else { + String str = config.getString("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), + "Cause 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()); + //We wait 2 tick to check if the player is Dead + new BukkitRunnable() { + @Override + public void run() { + for (DamageTakenExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, e.getCause())) + source.giveExperience(playerData, amount, null); + } + } + }.runTaskLater(MMOCore.plugin, 2); + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, EntityDamageEvent.DamageCause damageCause) { + if (player.getPlayer().isDead()) + return false; + if (cause == null) + return true; + return damageCause.equals(cause); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java new file mode 100644 index 00000000..b6db5451 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/EatExperienceSource.java @@ -0,0 +1,58 @@ +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.lang3.Validate; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.inventory.ItemStack; + +public class EatExperienceSource extends SpecificExperienceSource { + private final Material type; + + /** + * Gives xp when you eat a certain type of food. If not type is given it will give xp from all the food sources. + * The amount of xp given is the xp per food regenerated. + */ + public EatExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if(!config.contains("type")) + type=null; + else { + Material material=Material.valueOf(config.getString("type").toUpperCase().replace("-","_")); + Validate.isTrue(material!=null,"You must precise a valid material!"); + type=material; + } + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + + @EventHandler + public void a(FoodLevelChangeEvent e) { + if (!(e.getEntity() instanceof Player) || e.getEntity().hasMetadata("NPC")) + return; + PlayerData playerData = PlayerData.get((OfflinePlayer) e.getEntity()); + for (EatExperienceSource source : getSources()) { + if (source.matchesParameter(playerData, e.getItem())) + source.giveExperience(playerData, e.getFoodLevel(), null); + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, ItemStack obj) { + if(type==null) + return true; + return type.equals(obj.getType()); + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java index aae363b1..3a9c334d 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/EnchantItemExperienceSource.java @@ -60,7 +60,7 @@ public class EnchantItemExperienceSource extends ExperienceSource { double exp = 0; for (Entry entry : applicableEnchants.entrySet()) exp += MMOCore.plugin.enchantManager.getBaseExperience(entry.getKey()) * entry.getValue(); - getDispenser().giveExperience(player, (int) exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE); + getDispenser().giveExperience(player, exp, event.getEnchantBlock().getLocation(), EXPSource.SOURCE); } } }; 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..6af6bf03 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/MoveExperienceSource.java @@ -0,0 +1,87 @@ +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.Bukkit; +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("type")) + type = null; + else { + String str = config.getString("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: sneak, fly, swim, sprint, walk."); + type = MovingType.valueOf(str); + } + } + + @Override + public ExperienceSourceManager newManager() { + return new ExperienceSourceManager() { + @EventHandler + 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); + } + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + return type==null||type.matches(player.getPlayer()); + } + + public enum MovingType { + SNEAK(Player::isSneaking), + FLY((p)->p.isFlying()||p.isGliding()), + SWIM((p)->p.getLocation().getBlock().isLiquid()), + SPRINT(Player::isSprinting), + WALK((p) -> !p.isSneaking() && !p.isSprinting() && !p.isFlying() && !p.getLocation().getBlock().isLiquid()); + + private final Function matching; + + MovingType(Function matching) { + this.matching = matching; + } + + public boolean matches(Player player) { + return !player.isInsideVehicle()&&matching.apply(player); + } + + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java new file mode 100644 index 00000000..d95e6a7b --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/PlayExperienceSource.java @@ -0,0 +1,96 @@ +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.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; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.scheduler.BukkitRunnable; + +public class PlayExperienceSource extends SpecificExperienceSource { + + private final World world; + private final double x1, x2, z1, z2; + private final boolean inCombat; + + /** + * 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. You can also specifiy if the player + * has to be inCombat or not to get the xp. + */ + public PlayExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("in-combat")) + inCombat = false; + else { + inCombat = config.getBoolean("in-combat"); + } + + 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 (inCombat && !player.isInCombat()) + return false; + + 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 (PlayExperienceSource 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..49647b70 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ProjectileExperienceSource.java @@ -0,0 +1,129 @@ +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.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.*; +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.HashSet; +import java.util.Locale; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ProjectileExperienceSource extends SpecificExperienceSource { + + private final ProjectileType projectileType; + + public ProjectileExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + 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)); + projectileType = ProjectileType.valueOf(str); + } + } + + @Override + public ExperienceSourceManager newManager() { + + return new ExperienceSourceManager() { + HashMap projectiles = new HashMap<>(); + + @EventHandler + public void onHit(ProjectileHitEvent e) { + if (e.getHitBlock() != null && projectiles.containsKey(e.getEntity())) + projectiles.remove(e.getEntity()); + + } + + @EventHandler + 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); + + + } + } + + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Projectile projectile) { + if (projectileType == null) + return true; + return projectileType.matches(projectile); + } + + + public enum ProjectileType { + ARROW((p) -> p instanceof Arrow), + TRIDENT((p) -> p instanceof Trident); + + private final Function matching; + + ProjectileType(Function matching) { + this.matching = matching; + } + + + public boolean matches(Projectile projectile) { + return matching.apply(projectile); + } + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/RepairItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/RepairItemExperienceSource.java index e7942846..070e5e24 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/RepairItemExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/RepairItemExperienceSource.java @@ -75,7 +75,7 @@ public class RepairItemExperienceSource extends ExperienceSource { */ double exp = MMOCore.plugin.smithingManager.getBaseExperience(item.getType()) * Math.max(0, ((Damageable) old.getItemMeta()).getDamage() - ((Damageable) item.getItemMeta()).getDamage()) / 100; - getDispenser().giveExperience(data, (int) exp, null, EXPSource.SOURCE); + getDispenser().giveExperience(data, exp, data.getPlayer().getLocation(), EXPSource.SOURCE); } } } diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java new file mode 100644 index 00000000..7b9463d3 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/ResourceExperienceSource.java @@ -0,0 +1,62 @@ +package net.Indyuce.mmocore.experience.source; + +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 org.apache.commons.lang.Validate; +import org.bukkit.event.EventHandler; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public class ResourceExperienceSource extends SpecificExperienceSource { + private final PlayerResource resource; + + + /** + * Gives experience when the player uses a specific resoure. If no resource is precised it will trigger for + * mana, stamina and stellium. The amount specified si the xp given per resource consummed. + */ + public ResourceExperienceSource(ExperienceDispenser dispenser, MMOLineConfig config) { + super(dispenser, config); + if (!config.contains("resource")) + resource = null; + else { + String str = config.getString("resource").toUpperCase().replace("-", "_"); + 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 newManager() { + return new ExperienceSourceManager() { + @EventHandler + 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); + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, PlayerResource obj) { + if (resource == null) + return !obj.equals(PlayerResource.HEALTH); + return resource.equals(obj); + } +} 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..9c9578ce --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/RideExperienceSource.java @@ -0,0 +1,74 @@ +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.Bukkit; +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("type")) + type = null; + else { + String str = config.getString("type").toUpperCase().replace("-", "_"); + Validate.isTrue(Arrays.stream(EntityType.values()).map(Objects::toString).collect(Collectors.toList()).contains(str), + "The 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().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); + } + } + } + } + + }; + } + + @Override + public boolean matchesParameter(PlayerData player, EntityType obj) { + if (type == null) + return true; + return type.equals(obj); + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java new file mode 100644 index 00000000..af7a22a4 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/experience/source/TameExperienceSource.java @@ -0,0 +1,44 @@ +package net.Indyuce.mmocore.experience.source; + +import io.lumine.mythic.lib.api.MMOLineConfig; +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; + +public class TameExperienceSource extends SpecificExperienceSource { + + + public TameExperienceSource(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(TameExperienceSource source:getSources()) { + source.giveExperience(playerData,e.getDamage(), MMOCoreUtils.getCenterLocation(e.getEntity())); + } + } + } + } + }; + } + + @Override + public boolean matchesParameter(PlayerData player, Object obj) { + return false; + } +} diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java index 6e62560c..05cf0b3d 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/type/SpecificExperienceSource.java @@ -5,11 +5,13 @@ import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.math.formula.RandomAmount; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.jetbrains.annotations.Nullable; public abstract class SpecificExperienceSource extends ExperienceSource { private final RandomAmount amount; + double counter = 0; /** * Used to register experience sources with SPECIFIC experience outputs. @@ -27,8 +29,8 @@ public abstract class SpecificExperienceSource extends ExperienceSource { return amount; } - public int rollAmount() { - return amount.calculateInt(); + public double rollAmount() { + return amount.calculate(); } /** diff --git a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java index a60e027d..af983f3c 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/SkillList.java +++ b/src/main/java/net/Indyuce/mmocore/gui/SkillList.java @@ -11,6 +11,7 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; +import net.Indyuce.mmocore.manager.SkillManager; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; import org.apache.commons.lang.Validate; @@ -38,8 +39,6 @@ public class SkillList extends EditableInventory { if (function.equals("skill")) return new SkillItem(config); - if (function.equals("switch")) - return new SwitchItem(config); if (function.equals("level")) return new LevelItem(config); @@ -49,7 +48,7 @@ public class SkillList extends EditableInventory { @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - RegisteredSkill selected = inv.selected.getSkill(); + RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill(); Placeholders holders = new Placeholders(); holders.register("skill_caps", selected.getName().toUpperCase()); @@ -59,10 +58,6 @@ public class SkillList extends EditableInventory { return holders; } - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return !inv.binding; - } }; if (function.equals("slot")) @@ -74,7 +69,7 @@ public class SkillList extends EditableInventory { @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { - RegisteredSkill selected = inv.selected.getSkill(); + RegisteredSkill selected = inv.selected==null?null:inv.selected.getSkill(); RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n) ? inv.getPlayerData().getBoundSkill(n).getSkill() : null; Placeholders holders = new Placeholders(); @@ -82,7 +77,7 @@ public class SkillList extends EditableInventory { holders.register("skill", skill == null ? none : skill.getName()); holders.register("index", "" + (n + 1)); holders.register("slot", MMOCoreUtils.intToRoman(n + 1)); - holders.register("selected", selected.getName()); + holders.register("selected", selected==null?none:selected.getName()); return holders; } @@ -102,16 +97,28 @@ public class SkillList extends EditableInventory { return item; } - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return inv.binding; - } - @Override public boolean hasDifferentDisplay() { return true; } }; + if (function.equals("previous")) + return new SimplePlaceholderItem(config) { + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return inv.page > 0; + } + }; + if (function.equals("next")) { + return new SimplePlaceholderItem(config) { + + @Override + public boolean canDisplay(SkillViewerInventory inv) { + return inv.page < inv.skills.size() / 12; + } + }; + } return new SimplePlaceholderItem(config); } @@ -120,30 +127,6 @@ public class SkillList extends EditableInventory { return new SkillViewerInventory(data, this); } - public class SwitchItem extends SimplePlaceholderItem { - private final SimplePlaceholderItem binding, upgrading; - - public SwitchItem(ConfigurationSection config) { - super(config); - - Validate.isTrue(config.contains("binding"), "Config must have 'binding'"); - Validate.isTrue(config.contains("upgrading"), "Config must have 'upgrading'"); - - binding = new SimplePlaceholderItem(config.getConfigurationSection("binding")); - upgrading = new SimplePlaceholderItem(config.getConfigurationSection("upgrading")); - } - - @Override - public ItemStack display(SkillViewerInventory inv, int n) { - return inv.binding ? upgrading.display(inv) : binding.display(inv); - } - - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return true; - } - } - public class LevelItem extends InventoryItem { private final int offset; @@ -189,24 +172,21 @@ public class SkillList extends EditableInventory { return NBTItem.get(item).addTag(new ItemTag("skillId", skill.getSkill().getHandler().getId())).toItem(); } + @Override public Placeholders getPlaceholders(SkillViewerInventory inv, int n) { return new Placeholders(); } - @Override - public boolean canDisplay(SkillViewerInventory inv) { - return !inv.binding; - } + } public class SkillItem extends InventoryItem { - private final int selectedSkillSlot; + public SkillItem(ConfigurationSection config) { super(Material.BARRIER, config); - selectedSkillSlot = config.getInt("selected-slot"); } @Override @@ -220,12 +200,16 @@ public class SkillList extends EditableInventory { /* * calculate placeholders */ - ClassSkill skill = inv.skills.get(mod(n + inv.getPlayerData().skillGuiDisplayOffset, inv.skills.size())); + int index=n+inv.skillSlots.size()*inv.page; + if(index>=inv.skills.size()) + return new ItemStack(Material.AIR); + + ClassSkill skill = inv.skills.get(index); Placeholders holders = getPlaceholders(inv.getPlayerData(), skill); List lore = new ArrayList<>(getLore()); - int index = lore.indexOf("{lore}"); + index = lore.indexOf("{lore}"); lore.remove(index); List skillLore = skill.calculateLore(inv.getPlayerData()); for (int j = 0; j < skillLore.size(); j++) @@ -272,8 +256,9 @@ public class SkillList extends EditableInventory { private final List skillSlots; private final List slotSlots; - private boolean binding; + //The skill the player Selected private ClassSkill selected; + private int page = 0; public SkillViewerInventory(PlayerData playerData, EditableInventory editable) { super(playerData, editable); @@ -281,24 +266,23 @@ public class SkillList extends EditableInventory { skills = new ArrayList<>(playerData.getProfess().getSkills()); skillSlots = getEditable().getByFunction("skill").getSlots(); slotSlots = getEditable().getByFunction("slot").getSlots(); + selected=skills.get(page*skillSlots.size()); } @Override public String calculateName() { - return getName(); + return getName().replace("{skill}", selected.getSkill().getName()); } @Override public void open() { - int selectedSkillSlot = ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot; - selected = skills.get(mod(selectedSkillSlot + playerData.skillGuiDisplayOffset, skills.size())); - super.open(); } @Override public void whenClicked(InventoryClickEvent event, InventoryItem item) { + /* if (skillSlots.contains(event.getRawSlot()) && event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) { player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); @@ -306,24 +290,26 @@ public class SkillList extends EditableInventory { open(); return; } + */ + + if (item.getFunction().equals("skill")) { + int index = skillSlots.size() * page + skillSlots.indexOf(event.getRawSlot()); + player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); + selected = skills.get(index); + open(); + return; + } if (item.getFunction().equals("previous")) { player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset - 1) % skills.size(); + page--; open(); return; } if (item.getFunction().equals("next")) { player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + 1) % skills.size(); - open(); - return; - } - - if (item.getFunction().equals("switch")) { - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); - binding = !binding; + page++; open(); return; } @@ -331,51 +317,50 @@ public class SkillList extends EditableInventory { /* * binding or unbinding skills. */ - if (binding) { - for (int index = 0; index < slotSlots.size(); index++) { - int slot = slotSlots.get(index); - if (event.getRawSlot() == slot) { + if (item.getFunction().equals("slot")) { + int index = slotSlots.indexOf(event.getRawSlot()); - // unbind if there is a current spell. - if (event.getAction() == InventoryAction.PICKUP_HALF) { - if (!playerData.hasSkillBound(index)) { - MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.unbindSkill(index); - open(); - return; - } - - if (selected == null) - return; - - if (selected.getSkill().getTrigger().isPassive()) { - MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - if (!playerData.hasSkillUnlocked(selected)) { - MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); - return; - } - - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); - playerData.setBoundSkill(index, selected); - open(); + // unbind if there is a current spell. + if (event.getAction() == InventoryAction.PICKUP_HALF) { + if (!playerData.hasSkillBound(index)) { + MMOCore.plugin.configManager.getSimpleMessage("no-skill-bound").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); return; } + + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); + playerData.unbindSkill(index); + open(); + return; } - /* - * upgrading a player skill - */ - } else if (item.getFunction().equals("upgrade")) { + if (selected == null) + return; + + if (selected.getSkill().getTrigger().isPassive()) { + MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + if (!playerData.hasSkillUnlocked(selected)) { + MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); + return; + } + + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); + playerData.setBoundSkill(index, selected); + open(); + return; + } + + + /* + * upgrading a player skill + */ + if (item.getFunction().equals("upgrade")) { if (!playerData.hasSkillUnlocked(selected)) { MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(player); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); @@ -402,6 +387,7 @@ public class SkillList extends EditableInventory { open(); } } + } private int mod(int x, int n) { diff --git a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java index 3553deca..2ff6c505 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/BlockListener.java @@ -11,7 +11,7 @@ import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.experience.source.MineBlockExperienceSource; import net.Indyuce.mmocore.loot.LootBuilder; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; diff --git a/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java b/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java index 7f697c80..49a19c45 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java +++ b/src/main/java/net/Indyuce/mmocore/listener/option/RedirectVanillaExp.java @@ -16,7 +16,7 @@ public class RedirectVanillaExp implements Listener { @EventHandler public void a(PlayerExpChangeEvent event) { - int a = (int) (event.getAmount() * ratio); + double a = (event.getAmount() * ratio); if (a > 0) PlayerData.get(event.getPlayer()).giveExperience(a, EXPSource.VANILLA); } diff --git a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java index 19ec3c4f..fe678f07 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/profession/FishingListener.java @@ -80,7 +80,7 @@ public class FishingListener implements Listener { public FishingData(Player player, FishHook hook, FishingDropTable table) { this.location = hook.getLocation(); - this.caught = table.getRandomItem(); + this.caught = table.getRandomItem(PlayerData.get(player)); this.playerData = PlayerData.get(this.player = player); this.hook = hook; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/BiomeCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/BiomeCondition.java similarity index 91% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/BiomeCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/BiomeCondition.java index 7da08703..1c55c5fc 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/BiomeCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/BiomeCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.loot.chest.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/Condition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/Condition.java similarity index 84% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/Condition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/Condition.java index d1445364..b924cea2 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/Condition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/Condition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.loot.chest.condition; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/ConditionInstance.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java similarity index 93% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/ConditionInstance.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java index 937b9475..1666ee8e 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/ConditionInstance.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/ConditionInstance.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.loot.chest.condition; import java.util.List; import java.util.stream.Stream; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/DistanceCondition.java similarity index 88% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/DistanceCondition.java index 486ce977..21e46f8f 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/DistanceCondition.java @@ -1,15 +1,10 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.loot.chest.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.entity.Entity; -import org.bukkit.generator.WorldInfo; - - -import java.util.stream.Collectors; public class DistanceCondition extends Condition{ private final Location location; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/LevelCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/LevelCondition.java similarity index 93% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/LevelCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/LevelCondition.java index e3fe2a0d..c448c96c 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/LevelCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/LevelCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.loot.chest.condition; import net.Indyuce.mmocore.api.player.PlayerData; import io.lumine.mythic.lib.api.MMOLineConfig; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java similarity index 90% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java index 43967da5..312719ca 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/PermissionCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/PermissionCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.loot.chest.condition; import io.lumine.mythic.lib.api.MMOLineConfig; import org.bukkit.entity.Player; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/WorldCondition.java b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/WorldCondition.java similarity index 90% rename from src/main/java/net/Indyuce/mmocore/loot/droptable/condition/WorldCondition.java rename to src/main/java/net/Indyuce/mmocore/loot/chest/condition/WorldCondition.java index 35e6341d..97c58cc4 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/WorldCondition.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/condition/WorldCondition.java @@ -1,4 +1,4 @@ -package net.Indyuce.mmocore.loot.droptable.condition; +package net.Indyuce.mmocore.loot.chest.condition; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java index 1cce3177..c8588074 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/DropTable.java @@ -5,8 +5,8 @@ import java.util.List; import java.util.Set; import java.util.logging.Level; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; @@ -73,7 +73,7 @@ public class DropTable extends PostLoadObject { public List collect(LootBuilder builder) { for (DropItem item : drops) - if (item.rollChance() && builder.getCapacity() >= item.getWeight()) { + if (item.rollChance(builder.getEntity()) && builder.getCapacity() >= item.getWeight()) { item.collect(builder); builder.reduceCapacity(item.getWeight()); } diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java index 05d99b44..143ebbca 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropItem.java @@ -2,41 +2,46 @@ package net.Indyuce.mmocore.loot.droptable.dropitem; import java.util.Random; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.api.util.math.formula.RandomAmount; import io.lumine.mythic.lib.api.MMOLineConfig; public abstract class DropItem { - protected static final Random random = new Random(); + protected static final Random random = new Random(); - private final double chance, weight; - private final RandomAmount amount; + private final double chance, weight; + private final RandomAmount amount; - public DropItem(MMOLineConfig config) { - chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1; - amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 1); - weight = config.args().length > 2 ? Double.parseDouble(config.args()[2]) : 0; - } + public DropItem(MMOLineConfig config) { + chance = config.args().length > 0 ? Double.parseDouble(config.args()[0]) : 1; + amount = config.args().length > 1 ? new RandomAmount(config.args()[1]) : new RandomAmount(1, 1); + weight = config.args().length > 2 ? Double.parseDouble(config.args()[2]) : 0; + } - public RandomAmount getAmount() { - return amount; - } + public RandomAmount getAmount() { + return amount; + } - public double getChance() { - return chance; - } + public double getChance() { + return chance; + } - public double getWeight() { - return weight; - } + public double getWeight() { + return weight; + } - public int rollAmount() { - return amount.calculateInt(); - } + public int rollAmount() { + return amount.calculateInt(); + } - public boolean rollChance() { - return random.nextDouble() < chance; - } + /** + * If the player chance is 0 the random value will remain the same. When he get lucks the chance gets closer to one. + */ + public boolean rollChance(PlayerData player) { + return Math.pow(random.nextDouble(), 1 / Math.log(1 + player.getStats().getStat(StatType.CHANCE))) < chance; + } - public abstract void collect(LootBuilder builder); + public abstract void collect(LootBuilder builder); } diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java index 02123b38..e6c160f2 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/dropitem/DropTableDropItem.java @@ -3,7 +3,7 @@ package net.Indyuce.mmocore.loot.droptable.dropitem; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.loot.droptable.DropTable; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.LootBuilder; import net.Indyuce.mmocore.api.player.PlayerData; import org.apache.commons.lang.Validate; diff --git a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java index 67f7c279..666ba042 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/MMOLoadManager.java @@ -11,7 +11,7 @@ import org.bukkit.configuration.ConfigurationSection; import com.google.gson.JsonParseException; import net.Indyuce.mmocore.api.block.BlockType; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; import net.Indyuce.mmocore.api.load.DefaultMMOLoader; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java index c6e72d9e..5b69846d 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/CustomBlockManager.java @@ -7,11 +7,10 @@ import net.Indyuce.mmocore.api.block.BlockInfo.RegeneratingBlock; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.api.util.MMOCoreUtils; import io.lumine.mythic.lib.api.MMOLineConfig; -import net.Indyuce.mmocore.manager.profession.SpecificProfessionManager; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.Block; diff --git a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java index aa9e1738..93a5a73f 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/profession/FishingManager.java @@ -2,8 +2,10 @@ package net.Indyuce.mmocore.manager.profession; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.stats.StatType; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.droptable.dropitem.fishing.FishingDropItem; import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; @@ -90,12 +92,23 @@ public class FishingManager extends SpecificProfessionManager { return conditions; } - public FishingDropItem getRandomItem() { - double randomCoefficient = RANDOM.nextDouble() * maxWeight; + /** + * The Fishing Drop Item is calculated randomly bu the chance stat will make + * low weight items more likely to be caught. + */ + public FishingDropItem getRandomItem(PlayerData player) { + double chance = player.getStats().getStat(StatType.CHANCE); - for (FishingDropItem item : items) - if ((randomCoefficient -= item.getItem().getWeight()) <= 0) + //chance=0 ->the tier.chance remains the same + //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law + //chance=8-> tierChance=sqrt(tierChance) + double sum = 0; + double randomCoefficient=RANDOM.nextDouble(); + for (FishingDropItem item : items) { + sum += Math.pow(item.getItem().getWeight(), 1 / Math.log(1 + chance)); + if(sum> { - - /** - * @return Quest with given name - */ - public T getQuestOrThrow(String id); - - /** - * @return Info about the completed quests from a specific player - */ - public U getQuestData(PlayerData playerData); -} diff --git a/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java new file mode 100644 index 00000000..7bcd4bfa --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/QuestModuleType.java @@ -0,0 +1,35 @@ +package net.Indyuce.mmocore.quest; + +import net.Indyuce.mmocore.party.PartyModule; +import net.Indyuce.mmocore.quest.compat.BeautyQuestModule; +import net.Indyuce.mmocore.quest.compat.BlackVeinQuestsModule; +import net.Indyuce.mmocore.quest.compat.QuestCreatorModule; +import net.Indyuce.mmocore.quest.compat.QuestModule; +import org.bukkit.Bukkit; + +import javax.inject.Provider; + +public enum QuestModuleType { + MMOCORE("MMOCore",MMOCoreQuestModule::new), + QUESTS("Quests", BlackVeinQuestsModule::new), + BEAUTY_QUEST("Beauty Quests", BeautyQuestModule::new), + QUEST_CREATOR("Quest Creator", QuestCreatorModule::new); + + + + private final String pluginName; + private final Provider provider; + + QuestModuleType(String pluginName, Provider provider) { + this.pluginName = pluginName; + this.provider = provider; + } + + public boolean isValid() { + return Bukkit.getPluginManager().getPlugin(pluginName) != null; + } + + public QuestModule provideModule() { + return provider.get(); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java new file mode 100644 index 00000000..e1e4f720 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/BeautyQuestModule.java @@ -0,0 +1,47 @@ +package net.Indyuce.mmocore.quest.compat; + +import fr.skytasul.quests.api.QuestsAPI; +import fr.skytasul.quests.players.PlayerAccount; +import fr.skytasul.quests.players.PlayerQuestDatas; +import fr.skytasul.quests.players.PlayersManager; +import fr.skytasul.quests.structure.Quest; +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.bukkit.entity.Player; + +public class BeautyQuestModule implements QuestModule { + + + @Override + public BeautyQuestQuest getQuestOrThrow(String questId) { + Quest quest=QuestsAPI.getQuests().getQuest(Integer.parseInt(questId)); + return quest==null?null:new BeautyQuestQuest(quest); + } + + @Override + public boolean hasCompletedQuest(String questId, Player player) { + PlayerAccount account=PlayersManager.getPlayerAccount(player); + PlayerQuestDatas quest=account.getQuestDatas(QuestsAPI.getQuests().getQuest(Integer.parseInt(questId))); + return quest.isFinished(); + } + + + + public class BeautyQuestQuest implements AbstractQuest { + + Quest quest; + + public BeautyQuestQuest(Quest quest) { + this.quest = quest; + } + + @Override + public String getName() { + return quest.getName(); + } + + @Override + public String getId() { + return ""+quest.getID(); + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/BlackVeinQuestsModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/BlackVeinQuestsModule.java new file mode 100644 index 00000000..413dc22d --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/BlackVeinQuestsModule.java @@ -0,0 +1,53 @@ +package net.Indyuce.mmocore.quest.compat; + +import me.blackvein.quests.Quest; +import me.blackvein.quests.Quester; +import me.blackvein.quests.Quests; +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + + +public class BlackVeinQuestsModule implements QuestModule { + private final Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests"); + + + + @Override + public BlackVeinQuestQuest getQuestOrThrow(String id) { + Quests plugin = (Quests) Bukkit.getPluginManager().getPlugin("Quests"); + return plugin.getQuestById(id)==null?null:new BlackVeinQuestQuest(plugin.getQuestById(id)); + } + + + @Override + public boolean hasCompletedQuest(String questId, Player player) { + Quester quester = plugin.getQuester(player.getUniqueId()); + + for(Quest quest:quester.getCompletedQuests()) { + if(quest.getId().equals(questId)) + return true; + } + return false; + } + + + public class BlackVeinQuestQuest implements AbstractQuest { + private final Quest quest; + + public BlackVeinQuestQuest(Quest quest) { + this.quest = quest; + } + + @Override + public String getName() { + return quest.getName(); + } + + @Override + public String getId() { + return quest.getId(); + } + } + +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/QuestCreatorModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestCreatorModule.java new file mode 100644 index 00000000..adade213 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestCreatorModule.java @@ -0,0 +1,56 @@ +package net.Indyuce.mmocore.quest.compat; + +import com.guillaumevdn.questcreator.ConfigQC; +import com.guillaumevdn.questcreator.data.user.QuestHistoryElement; +import com.guillaumevdn.questcreator.data.user.UserQC; +import com.guillaumevdn.questcreator.lib.model.ElementModel; +import com.guillaumevdn.questcreator.lib.quest.QuestEndType; +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Player; +import java.util.Arrays; +import java.util.List; + +public class QuestCreatorModule implements QuestModule{ + + @Override + public QuestCreatorQuest getQuestOrThrow(String id) { + return new QuestCreatorQuest(id); + } + + @Override + public boolean hasCompletedQuest(String questId, Player player) { + UserQC playerData=UserQC.cachedOrNull(player); + Validate.notNull(playerData,"QuestCreator User hasn't been loaded!"); + //Gets all the quests the player has succeeded at + List elements=playerData.getQuestHistory().getElements(questId, Arrays.asList(QuestEndType.SUCCESS),0); + for(QuestHistoryElement el:elements) { + if(el.getModelId().equals(questId)) + return true; + } + return false; + } + + + /** + *QC ElementModel corresponds to our quest and their quests correspond to our Quest progress class + */ + + public class QuestCreatorQuest implements AbstractQuest { + ElementModel questModel; + + public QuestCreatorQuest(String modelId) { + questModel=ConfigQC.models.getElement(modelId).orNull(); + } + + @Override + public String getName() { + return questModel.getDisplayName().getId(); + } + + @Override + public String getId() { + return questModel.getId(); + } + } +} diff --git a/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java new file mode 100644 index 00000000..d4cae6b4 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/quest/compat/QuestModule.java @@ -0,0 +1,18 @@ +package net.Indyuce.mmocore.quest.compat; + +import net.Indyuce.mmocore.quest.AbstractQuest; +import org.bukkit.entity.Player; + +public interface QuestModule { + + /** + * @return Quest with given name + */ + public T getQuestOrThrow(String id); + + /** + * @return If a specific player did a certain quest + */ + public boolean hasCompletedQuest(String quest, Player player); + +} diff --git a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java index b19ca467..6395ea81 100644 --- a/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java +++ b/src/main/java/net/Indyuce/mmocore/waypoint/Waypoint.java @@ -2,11 +2,10 @@ package net.Indyuce.mmocore.waypoint; import io.lumine.mythic.lib.api.MMOLineConfig; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.ConditionInstance; +import net.Indyuce.mmocore.loot.chest.condition.Condition; +import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.player.Unlockable; import org.apache.commons.lang.Validate; -import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -15,7 +14,6 @@ import org.bukkit.craftbukkit.libs.jline.internal.Nullable; import org.bukkit.entity.Player; import java.util.*; -import java.util.logging.Level; public class Waypoint implements Unlockable { private final String id, name; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5611ba68..0ccdbde5 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -58,6 +58,14 @@ protect-custom-mine: false # - parties_and_friends party-plugin: mmocore +## Edit the plugin handling parties here. +## Supported values (just copy and paste): +## - mmocore +## - beauty_quest +## - quest_creator +## - quests +quest-plugin: mmocore + # MythicLib introduces a CHANCE stat that is used in # several different systems in MMOCore. By changing these # weights you can define how much the Chance stat impacts @@ -67,7 +75,6 @@ party-plugin: mmocore # the chance stat in one particular system. The weights are # all set to 1 by default, this option is really server specific chance-stat-weight: - loot-chests: 1 # Whether blocks generated with a "cobblegenerator" should diff --git a/src/main/resources/default/drop-tables/example-drop-tables.yml b/src/main/resources/default/drop-tables/example-drop-tables.yml index 25894aaf..4faf4e78 100644 --- a/src/main/resources/default/drop-tables/example-drop-tables.yml +++ b/src/main/resources/default/drop-tables/example-drop-tables.yml @@ -8,7 +8,7 @@ diamond-drop-table: items: - 'vanilla{type=DIAMOND} 1 1-3' - # - 'mmoitem{type=material;id=RARE_DIAMOND} .1 1-3' + # - 'mmoitem{type=material;id=RARE_DIAMOND;period=} .1 1-3' - 'droptable{id=other-drop-table} .1' other-drop-table: diff --git a/src/main/resources/default/gui/skill-list.yml b/src/main/resources/default/gui/skill-list.yml index 60993b92..04dc88a6 100644 --- a/src/main/resources/default/gui/skill-list.yml +++ b/src/main/resources/default/gui/skill-list.yml @@ -1,97 +1,95 @@ - # GUI display name -name: Your Skills +name: 'Selected Skill: &6{skill}' # Number of slots in your inventory. Must be # between 9 and 54 and must be a multiple of 9. -slots: 45 +slots: 54 items: - skill: - slots: [11,12,13,14,15] - - # Index from 'slots' of the skill - # currently selected in the GUI - selected-slot: 2 - - function: skill - name: '&a{skill} &6[{level}]' - lore: - - '' - - '{unlocked}&a✔ Requires Level {unlock}' - - '{locked}&c✖ Requires Level {unlock}' - - '{max_level}&e✔ Maximum Level Hit!' - - '' - - '{lore}' - next: - slots: [16] - function: next - item: PLAYER_HEAD - texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19 - name: '&aNext' - lore: {} - previous: - slots: [10] - function: previous - item: PLAYER_HEAD - texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ== - name: '&aPrevious' - lore: {} - switch: - slots: [28] - function: switch - item: PLAYER_HEAD - binding: - item: PINK_STAINED_GLASS - name: '&aSwitch to Binding' - lore: {} - upgrading: - item: PINK_STAINED_GLASS - name: '&aSwitch to Upgrading' - lore: {} - skill-slot: - slots: [29,30,31,32,33,34] - function: slot - item: BOOK - - # Material used when the slot is empty - empty-item: GRAY_DYE - - name: '&aSkill Slot {slot}' - no-skill: '&cNone' - lore: - - '&7Current Skill: &6{skill}' - - '' - - '&7&oCast this spell by pressing [F] followed' - - '&7&oby the keybind displayed on the action bar.' - - '' - - '&e► Left click to bind {selected}.' - - '&e► Right click to unbind.' - skill-level: - slots: [29,30,31,32,33,34] - function: level - - # Skill level offset, should be changed - # according to the amount of inventory - # slots the skill-level item occupies. - offset: 2 - - # Item displayed if the skill level is - # too low to display a level item in the GUI - too-low: - item: AIR - - item: LIME_DYE - name: '&a{skill} Level {roman}' - lore: - - '' - - '{lore}' - upgrade: - slots: [31] - function: upgrade - item: GREEN_STAINED_GLASS_PANE - name: '&a&lUPGRADE {skill_caps}' - lore: - - '&7Costs 1 skill point.' - - '' - - '&eCurrent Skill Points: {skill_points}' + skill: + slots: [ 10,11,12,19,20,21,28,29,30,37,38,39] + + function: skill + name: '&a{skill} &6[{level}]' + lore: + - '' + - '{unlocked}&a✔ Requires Level {unlock}' + - '{locked}&c✖ Requires Level {unlock}' + - '{max_level}&e✔ Maximum Level Hit!' + - '' + - '{lore}' + next: + slots: [ 47 ] + function: next + item: PLAYER_HEAD + texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTliZjMyOTJlMTI2YTEwNWI1NGViYTcxM2FhMWIxNTJkNTQxYTFkODkzODgyOWM1NjM2NGQxNzhlZDIyYmYifX19 + name: '&aNext' + lore: { } + previous: + slots: [ 2 ] + function: previous + item: PLAYER_HEAD + texture: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmQ2OWUwNmU1ZGFkZmQ4NGU1ZjNkMWMyMTA2M2YyNTUzYjJmYTk0NWVlMWQ0ZDcxNTJmZGM1NDI1YmMxMmE5In19fQ== + name: '&aPrevious' + lore: { } + + + #switch: + # + # slots: [28] + # function: switch + # item: PLAYER_HEAD + # binding: + # item: PINK_STAINED_GLASS + # name: '&aSwitch to Binding' + # lore: {} + # upgrading: + # item: PINK_STAINED_GLASS + # name: '&aSwitch to Upgrading' + # lore: {} + skill-slot: + slots: [ 8,17,26,35,44,53 ] + function: slot + item: BOOK + + # Material used when the slot is empty + empty-item: GRAY_DYE + + name: '&aSkill Slot {slot}' + no-skill: '&cNone' + lore: + - '&7Current Skill: &6{skill}' + - '' + - '&7&oCast this spell by pressing [F] followed' + - '&7&oby the keybind displayed on the action bar.' + - '' + - '&e► Left click to bind {selected}.' + - '&e► Right click to unbind.' + skill-level: + slots: [ 6,15,24,33,42,51 ] + function: level + + # Skill level offset, should be changed + # according to the amount of inventory + # slots the skill-level item occupies. + offset: 2 + + # Item displayed if the skill level is + # too low to display a level item in the GUI + too-low: + item: AIR + + item: LIME_DYE + name: '&a{skill} Level {roman}' + lore: + - '' + - '{lore}' + upgrade: + slots: [ 15 ] + function: upgrade + item: GREEN_STAINED_GLASS_PANE + name: '&a&lUPGRADE {skill_caps}' + lore: + - '&7Costs 1 skill point.' + - '' + - '&eCurrent Skill Points: {skill_points}' diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml index ff58f2c2..cd90f0c8 100644 --- a/src/main/resources/default/gui/waypoints.yml +++ b/src/main/resources/default/gui/waypoints.yml @@ -68,7 +68,7 @@ items: lore: - '&7You can teleport to this waypoint.' - - '&7Intermediary waypoints : {intermediary_waypoints}' + - '&7Intermediary waypoints: {intermediary_waypoints}' - '&7Click to teleport for &b{current_cost} &7Stellium.' next: