From d38ac076a4861c2faf81cbdcec3bbe9e77b2a7ca Mon Sep 17 00:00:00 2001 From: Jules Date: Mon, 31 Jan 2022 20:37:09 +0100 Subject: [PATCH] added back class triggers --- pom.xml | 2 +- .../java/net/Indyuce/mmocore/MMOCore.java | 3 +- .../api/player/profess/PlayerClass.java | 21 ++++- .../mmocore/listener/ClassTriggers.java | 92 +++++++++++++++++++ .../player/playerclass/ClassTrigger.java | 64 +++++++++++++ .../player/playerclass/ClassTriggerType.java | 26 ++++++ .../skill/custom/mechanic/ManaMechanic.java | 33 +++++++ .../custom/mechanic/StaminaMechanic.java | 33 +++++++ .../custom/mechanic/StelliumMechanic.java | 33 +++++++ 9 files changed, 303 insertions(+), 4 deletions(-) create mode 100644 src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java create mode 100644 src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java create mode 100644 src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTriggerType.java create mode 100644 src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java create mode 100644 src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java create mode 100644 src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java diff --git a/pom.xml b/pom.xml index 0677a122..705a347f 100644 --- a/pom.xml +++ b/pom.xml @@ -140,7 +140,7 @@ io.lumine MythicLib-dist - 1.3-R21-SNAPSHOT + 1.3-R24-SNAPSHOT provided diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index 2a86dc55..f9eb4c3f 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -101,7 +101,7 @@ public class MMOCore extends LuminePlugin { public boolean shouldDebugSQL = false; - private static final int MYTHICLIB_COMPATIBILITY_INDEX = 4; + private static final int MYTHICLIB_COMPATIBILITY_INDEX = 5; public MMOCore() { plugin = this; @@ -276,6 +276,7 @@ public class MMOCore extends LuminePlugin { Bukkit.getPluginManager().registerEvents(new FishingListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerCollectStats(), this); Bukkit.getPluginManager().registerEvents(new PlayerPressKeyListener(), this); + Bukkit.getPluginManager().registerEvents(new ClassTriggers(), this); /* * Initialize player data from all online players. This is very important to do diff --git a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java index a7ca96e8..c64ef2cc 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java @@ -20,6 +20,8 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceTable; import net.Indyuce.mmocore.experience.provider.ExperienceDispenser; import net.Indyuce.mmocore.experience.provider.MainExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.ExperienceSource; +import net.Indyuce.mmocore.player.playerclass.ClassTrigger; +import net.Indyuce.mmocore.player.playerclass.ClassTriggerType; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; import net.md_5.bungee.api.ChatColor; @@ -31,8 +33,8 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import javax.annotation.Nullable; import java.lang.reflect.Field; import java.util.*; import java.util.logging.Level; @@ -50,7 +52,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { private final Map stats = new HashMap<>(); private final Map skills = new LinkedHashMap<>(); private final List subclasses = new ArrayList<>(); - + private final Map classTriggers = new HashMap<>(); private final Map resourceHandlers = new HashMap<>(); private final CastingParticle castParticle; @@ -101,6 +103,16 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { } this.expTable = expTable; + if (config.contains("triggers")) + for (String key : config.getConfigurationSection("triggers").getKeys(false)) { + try { + String format = key.toLowerCase().replace("_", "-").replace(" ", "-"); + classTriggers.put(format, new ClassTrigger(format, config.getStringList("triggers." + key))); + } catch (IllegalArgumentException exception) { + MMOCore.log(Level.WARNING, "Could not load trigger '" + key + "' from class '" + id + "':" + exception.getMessage()); + } + } + if (config.contains("attributes")) for (String key : config.getConfigurationSection("attributes").getKeys(false)) try { @@ -279,6 +291,11 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject { return options.containsKey(option) ? options.get(option) : option.getDefault(); } + @Nullable + public ClassTrigger getClassTrigger(ClassTriggerType type) { + return classTriggers.get(type); + } + @Deprecated public void setStat(StatType type, double base, double perLevel) { setStat(type, new LinearValue(base, perLevel)); diff --git a/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java b/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java new file mode 100644 index 00000000..02dd14a1 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/listener/ClassTriggers.java @@ -0,0 +1,92 @@ +package net.Indyuce.mmocore.listener; + +import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent; +import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.player.playerclass.ClassTrigger; +import net.Indyuce.mmocore.player.playerclass.ClassTriggerType; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +import java.util.HashMap; +import java.util.Map; + +/** + * This class still uses quest triggers because this was implemented + * in 1.9 and 1.9 is big enough as an update. + *

+ * Future implementation will utilize skill mechanics. MMOCore 1.10 + * will merge the quest triggers with the ML skill mechanics. + * + * @author jules + * @see {@link ClassTrigger} + */ +public class ClassTriggers implements Listener { + + @Deprecated + private static final Map damageTriggers = new HashMap<>(); + + static { + damageTriggers.put(DamageType.MAGIC, ClassTriggerType.MAGIC_DAMAGE); + damageTriggers.put(DamageType.PHYSICAL, ClassTriggerType.PHYSICAL_DAMAGE); + damageTriggers.put(DamageType.PROJECTILE, ClassTriggerType.PROJECTILE_DAMAGE); + damageTriggers.put(DamageType.WEAPON, ClassTriggerType.WEAPON_DAMAGE); + damageTriggers.put(DamageType.SKILL, ClassTriggerType.SKILL_DAMAGE); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onAttack(PlayerAttackEvent event) { + for (Map.Entry entry : damageTriggers.entrySet()) + if (event.getDamage().hasType(entry.getKey())) + applyTriggers(event.getPlayer(), entry.getValue()); //, () -> new TriggerMetadata(event.getAttack(), event.getEntity()) + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onClassChange(PlayerChangeClassEvent event) { + Bukkit.getScheduler().runTask(MMOCore.plugin, () -> applyTriggers(event.getData(), ClassTriggerType.CLASS_CHOSEN)); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onLevelUp(PlayerLevelUpEvent event) { + applyTriggers(event.getData(), ClassTriggerType.LEVEL_UP); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onBlockBreak(BlockBreakEvent event) { + applyTriggers(event.getPlayer(), ClassTriggerType.BREAK_BLOCK); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onBlockPlace(BlockBreakEvent event) { + applyTriggers(event.getPlayer(), ClassTriggerType.PLACE_BLOCK); + } + + private void applyTriggers(Player player, ClassTriggerType type) { + applyTriggers(PlayerData.get(player), type); + } + + private void applyTriggers(PlayerData player, ClassTriggerType type) { + //return applyTriggers(player, type, () -> new TriggerMetadata(player.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND), null, null)); + ClassTrigger trigger = player.getProfess().getClassTrigger(type); + if (trigger != null) + trigger.trigger(player); + } + + // @Nullable + // private SkillResult applyTriggers(Player player, ClassTriggerType type, Provider triggerMetaProvider) { + // return applyTriggers(PlayerData.get(player), type, triggerMetaProvider); + // } + + // @Nullable + // private SkillResult applyTriggers(PlayerData player, ClassTriggerType type, Provider triggerMetaProvider) { + // ClassTrigger trigger = player.getProfess().getClassTrigger(type); + // return trigger == null ? null : trigger.trigger(triggerMetaProvider.get()); + // } +} diff --git a/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java new file mode 100644 index 00000000..c043c3cd --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTrigger.java @@ -0,0 +1,64 @@ +package net.Indyuce.mmocore.player.playerclass; + +import io.lumine.mythic.lib.UtilityMethods; +import io.lumine.mythic.lib.api.MMOLineConfig; +import io.lumine.mythic.lib.skill.custom.mechanic.Mechanic; +import io.lumine.mythic.lib.skill.result.SkillResult; +import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.quest.trigger.Trigger; +import net.Indyuce.mmocore.listener.ClassTriggers; +import org.apache.commons.lang.Validate; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class triggers are shortcuts for the MythicLib custom + * passive skill creation system. + *

+ * A class trigger is defined by a {@link ClassTriggerType} which + * determines when the action is performed, and a set of {@link Mechanic} + * which determines what happens when triggered. + *

+ * Class triggers fully replace 'event triggers' which were an + * over simplified implementation of passive skills. + * + * @author jules + * @see {@link ClassTriggers} + */ +public class ClassTrigger { + private final ClassTriggerType type; + private final List triggers = new ArrayList<>(); + // private final CustomSkill skill = new CustomSkill("classTrigger", false); + // private final Skill castableSkill = new SimpleSkill(new MythicLibSkillHandler(skill)); + + public ClassTrigger(String triggerTypeString, List mechanicStringList) { + Validate.notNull(mechanicStringList, "Mechanic list cannot be null"); + type = ClassTriggerType.valueOf(UtilityMethods.enumName(triggerTypeString)); + + + for (String key : mechanicStringList) { + MMOLineConfig config = new MMOLineConfig(key); + triggers.add(MMOCore.plugin.loadManager.loadTrigger(config)); + // ConfigObject config = new LineConfigObject(new MMOLineConfig(key)); + // Mechanic mechanic = MythicLib.plugin.getSkills().loadMechanic(config); + // skill.getMechanics().add(mechanic); + } + } + + public ClassTriggerType getType() { + return type; + } + + @Deprecated + public SkillResult trigger(TriggerMetadata triggerMeta) { + // return castableSkill.cast(triggerMeta); + return null; + } + + public void trigger(PlayerData player) { + triggers.forEach(trigger -> trigger.apply(player)); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTriggerType.java b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTriggerType.java new file mode 100644 index 00000000..47f662fd --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/player/playerclass/ClassTriggerType.java @@ -0,0 +1,26 @@ +package net.Indyuce.mmocore.player.playerclass; + +public enum ClassTriggerType { + BREAK_BLOCK, + + PLACE_BLOCK, + + CLASS_CHOSEN, + + LEVEL_UP, + + @Deprecated + MAGIC_DAMAGE, + + @Deprecated + PHYSICAL_DAMAGE, + + @Deprecated + PROJECTILE_DAMAGE, + + @Deprecated + WEAPON_DAMAGE, + + @Deprecated + SKILL_DAMAGE; +} diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java new file mode 100644 index 00000000..ebd6e8b6 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/ManaMechanic.java @@ -0,0 +1,33 @@ +package net.Indyuce.mmocore.skill.custom.mechanic; + +import io.lumine.mythic.lib.UtilityMethods; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.custom.mechanic.type.TargetMechanic; +import io.lumine.mythic.lib.util.DoubleFormula; +import io.lumine.mythic.lib.util.configobject.ConfigObject; +import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.player.PlayerData; +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class ManaMechanic extends TargetMechanic { + private final DoubleFormula amount; + private final PlayerResourceUpdateEvent.UpdateReason reason; + + public ManaMechanic(ConfigObject config) { + super(config); + + config.validateKeys("amount"); + + amount = new DoubleFormula(config.getString("amount")); + reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM"))); + } + + @Override + public void cast(SkillMetadata meta, Entity target) { + Validate.isTrue(target instanceof Player, "Target is not a player"); + PlayerData targetData = PlayerData.get(target.getUniqueId()); + targetData.giveMana(amount.evaluate(meta), reason); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java new file mode 100644 index 00000000..3d6e4bd8 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StaminaMechanic.java @@ -0,0 +1,33 @@ +package net.Indyuce.mmocore.skill.custom.mechanic; + +import io.lumine.mythic.lib.UtilityMethods; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.custom.mechanic.type.TargetMechanic; +import io.lumine.mythic.lib.util.DoubleFormula; +import io.lumine.mythic.lib.util.configobject.ConfigObject; +import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.player.PlayerData; +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class StaminaMechanic extends TargetMechanic { + private final DoubleFormula amount; + private final PlayerResourceUpdateEvent.UpdateReason reason; + + public StaminaMechanic(ConfigObject config) { + super(config); + + config.validateKeys("amount"); + + amount = new DoubleFormula(config.getString("amount")); + reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM"))); + } + + @Override + public void cast(SkillMetadata meta, Entity target) { + Validate.isTrue(target instanceof Player, "Target is not a player"); + PlayerData targetData = PlayerData.get(target.getUniqueId()); + targetData.giveStamina(amount.evaluate(meta), reason); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java new file mode 100644 index 00000000..92ecb179 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/skill/custom/mechanic/StelliumMechanic.java @@ -0,0 +1,33 @@ +package net.Indyuce.mmocore.skill.custom.mechanic; + +import io.lumine.mythic.lib.UtilityMethods; +import io.lumine.mythic.lib.skill.SkillMetadata; +import io.lumine.mythic.lib.skill.custom.mechanic.type.TargetMechanic; +import io.lumine.mythic.lib.util.DoubleFormula; +import io.lumine.mythic.lib.util.configobject.ConfigObject; +import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; +import net.Indyuce.mmocore.api.player.PlayerData; +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +public class StelliumMechanic extends TargetMechanic { + private final DoubleFormula amount; + private final PlayerResourceUpdateEvent.UpdateReason reason; + + public StelliumMechanic(ConfigObject config) { + super(config); + + config.validateKeys("amount"); + + amount = new DoubleFormula(config.getString("amount")); + reason = PlayerResourceUpdateEvent.UpdateReason.valueOf(UtilityMethods.enumName(config.getString("reason", "CUSTOM"))); + } + + @Override + public void cast(SkillMetadata meta, Entity target) { + Validate.isTrue(target instanceof Player, "Target is not a player"); + PlayerData targetData = PlayerData.get(target.getUniqueId()); + targetData.giveStellium(amount.evaluate(meta), reason); + } +}