Implemented class scripts

This commit is contained in:
Jules 2022-08-07 22:58:13 +02:00
parent 312522d77c
commit 6ef15ffcea
7 changed files with 110 additions and 213 deletions

View File

@ -5,7 +5,15 @@ import com.mojang.authlib.properties.Property;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
import io.lumine.mythic.lib.script.Script;
import io.lumine.mythic.lib.skill.SimpleSkill;
import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.handler.MythicLibSkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
@ -20,8 +28,6 @@ import net.Indyuce.mmocore.experience.ExpCurve;
import net.Indyuce.mmocore.experience.ExperienceObject;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
import net.Indyuce.mmocore.player.playerclass.ClassTrigger;
import net.Indyuce.mmocore.player.playerclass.ClassTriggerType;
import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
@ -45,25 +51,29 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
private final List<String> description = new ArrayList<>(), attrDescription = new ArrayList<>();
private final ItemStack icon;
private final Map<ClassOption, Boolean> options = new HashMap<>();
private final ManaDisplayOptions manaDisplay;
private final int maxLevel, displayOrder;
@NotNull
private final ManaDisplayOptions manaDisplay;
@NotNull
private final ExpCurve expCurve;
@Nullable
private final ExperienceTable expTable;
@NotNull
private final CastingParticle castParticle;
private final Map<String, LinearValue> stats = new HashMap<>();
private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
private final List<Subclass> subclasses = new ArrayList<>();
@Deprecated
private final Map<String, ClassTrigger> classTriggers = new HashMap<>();
private final List<PassiveSkill> classScripts = new LinkedList<>();
private final Map<PlayerResource, ResourceRegeneration> resourceHandlers = new HashMap<>();
@Deprecated
private final Map<String, EventTrigger> eventTriggers = new HashMap<>();
private final CastingParticle castParticle;
public PlayerClass(String id, FileConfiguration config) {
super(config);
@ -82,7 +92,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
profileField.set(meta, gp);
icon.setItemMeta(meta);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException
| SecurityException exception) {
| SecurityException exception) {
throw new IllegalArgumentException("Could not apply playerhead texture: " + exception.getMessage());
}
@ -110,15 +120,26 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
}
this.expTable = expTable;
if (config.contains("scripts"))
for (String key : config.getConfigurationSection("scripts").getKeys(false))
try {
final TriggerType trigger = TriggerType.valueOf(UtilityMethods.enumName(key));
final Script script = MythicLib.plugin.getSkills().loadScript(config.getConfigurationSection("scripts." + key));
final Skill castSkill = new SimpleSkill(trigger, new MythicLibSkillHandler(script));
final PassiveSkill skill = new PassiveSkill("MMOCoreClassScript", castSkill, EquipmentSlot.OTHER, ModifierSource.OTHER);
classScripts.add(skill);
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load script '" + key + "' from class '" + id + "': " + exception.getMessage());
}
if (config.contains("triggers"))
for (String key : config.getConfigurationSection("triggers").getKeys(false)) {
for (String key : config.getConfigurationSection("triggers").getKeys(false))
try {
String format = key.toLowerCase().replace("_", "-").replace(" ", "-");
eventTriggers.put(format, new EventTrigger(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))
@ -308,10 +329,15 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return equals(playerData.getProfess());
}
@Nullable
@Deprecated
public ClassTrigger getClassTrigger(ClassTriggerType type) {
return classTriggers.get(type);
/**
* @return A list of passive skills which correspond to class
* scripts wrapped in a format recognized by MythicLib.
* Class scripts are handled just like
* passive skills
*/
@NotNull
public List<PassiveSkill> getScripts() {
return classScripts;
}
@Deprecated

View File

@ -6,13 +6,13 @@ import io.lumine.mythic.lib.api.stat.StatMap;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
import io.lumine.mythic.lib.player.skill.PassiveSkillMap;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
public class PlayerStats {
private final PlayerData data;
@ -96,9 +96,15 @@ public class PlayerStats {
*
* This updates the player's PASSIVE skills
*/
data.getMMOPlayerData().getPassiveSkillMap().removeModifiers("MMOCorePassiveSkill");
final PassiveSkillMap skillMap = data.getMMOPlayerData().getPassiveSkillMap();
skillMap.removeModifiers("MMOCorePassiveSkill");
for (ClassSkill skill : data.getProfess().getSkills())
if (skill.getSkill().getTrigger().isPassive())
data.getMMOPlayerData().getPassiveSkillMap().addModifier(skill.toPassive(data));
skillMap.addModifier(skill.toPassive(data));
// This updates the player's class SCRIPTS
skillMap.removeModifiers("MMOCoreClassScript");
for (PassiveSkill script : data.getProfess().getScripts())
skillMap.addModifier(script);
}
}

View File

@ -0,0 +1,50 @@
package net.Indyuce.mmocore.listener;
import io.lumine.mythic.lib.api.player.MMOPlayerData;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
import net.Indyuce.mmocore.script.trigger.MMOCoreTriggerType;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
/**
* This class calls trigger types registered by MMOCore
* which are specific to player classes.
*
* @see {@link MMOCoreTriggerType}
*/
public class ClassScriptListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onClassChange(PlayerChangeClassEvent event) {
// With delay
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> {
final MMOPlayerData caster = event.getData().getMMOPlayerData();
caster.triggerSkills(MMOCoreTriggerType.CLASS_CHOSEN, null);
});
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onLevelUp(PlayerLevelUpEvent event) {
// With delay
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> {
final MMOPlayerData caster = event.getData().getMMOPlayerData();
caster.triggerSkills(MMOCoreTriggerType.LEVEL_UP, null);
});
}
/* @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onBlockBreak(BlockBreakEvent event) {
performScripts(event.getPlayer(), MMOCoreTriggerType.BREAK_BLOCK);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onBlockPlace(BlockBreakEvent event) {
performScripts(event.getPlayer(), MMOCoreTriggerType.PLACE_BLOCK);
}*/
}

View File

@ -1,106 +0,0 @@
package net.Indyuce.mmocore.listener;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.damage.DamageType;
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.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 javax.annotation.Nullable;
import javax.inject.Provider;
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.
* <p>
* Future implementation will utilize skill mechanics. MMOCore 1.10
* will merge the quest triggers with the ML skill mechanics.
*
* @author jules
* @see {@link ClassTrigger}
*/
@Deprecated
public class ClassTriggers implements Listener {
@Deprecated
private static final Map<DamageType, ClassTriggerType> 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);
damageTriggers.put(DamageType.UNARMED, ClassTriggerType.SKILL_DAMAGE);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onAttack(PlayerAttackEvent event) {
for (Map.Entry<DamageType, ClassTriggerType> 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 SkillResult applyTriggers(Player player, ClassTriggerType type) {
return applyTriggers(PlayerData.get(player), type);
}
private SkillResult applyTriggers(PlayerData player, ClassTriggerType type) {
return applyTriggers(player, type, () -> new TriggerMetadata(player.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND), null, null));
}
@Nullable
private SkillResult applyTriggers(Player player, ClassTriggerType type, Provider<TriggerMetadata> triggerMetaProvider) {
return applyTriggers(PlayerData.get(player), type, triggerMetaProvider);
}
/**
* Apply class shortcut skills from a specific class trigger type.
*
* @param player Player triggering
* @param type Trigger type
* @param triggerMetaProvider Small optimization: if no shortcut skill is found
* with the corresponding trigger type, trigger meta
* is not calculated which saves computations
* @return Skill result or null if no shortcut skill was cast
*/
@Nullable
private SkillResult applyTriggers(PlayerData player, ClassTriggerType type, Provider<TriggerMetadata> triggerMetaProvider) {
ClassTrigger trigger = player.getProfess().getClassTrigger(type);
return trigger == null ? null : trigger.trigger(triggerMetaProvider.get());
}
}

View File

@ -1,58 +0,0 @@
package net.Indyuce.mmocore.player.playerclass;
import io.lumine.mythic.lib.MythicLib;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.script.Script;
import io.lumine.mythic.lib.script.mechanic.Mechanic;
import io.lumine.mythic.lib.skill.SimpleSkill;
import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.handler.MythicLibSkillHandler;
import io.lumine.mythic.lib.skill.result.SkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import io.lumine.mythic.lib.util.configobject.ConfigObject;
import net.Indyuce.mmocore.listener.ClassTriggers;
import org.apache.commons.lang.Validate;
import java.util.List;
/**
* Class triggers are shortcuts for the MythicLib custom
* passive skill creation system.
* <p>
* 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.
* <p>
* Class triggers fully replace 'event triggers' which were an
* over simplified implementation of passive skills.
*
* @author jules
* @see {@link ClassTriggers}
*/
@Deprecated
public class ClassTrigger {
private final ClassTriggerType type;
private final Script skill = new Script("classTrigger", false);
private final Skill castableSkill = new SimpleSkill(TriggerType.CAST, new MythicLibSkillHandler(skill));
public ClassTrigger(String triggerTypeString, List<String> mechanicStringList) {
Validate.notNull(mechanicStringList, "Mechanic list cannot be null");
type = ClassTriggerType.valueOf(UtilityMethods.enumName(triggerTypeString));
for (String key : mechanicStringList) {
ConfigObject config = new MMOLineConfig(key);
Mechanic mechanic = MythicLib.plugin.getSkills().loadMechanic(config);
skill.getMechanics().add(mechanic);
}
}
public ClassTriggerType getType() {
return type;
}
public SkillResult trigger(TriggerMetadata triggerMeta) {
return castableSkill.cast(triggerMeta);
}
}

View File

@ -1,29 +0,0 @@
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,
@Deprecated
UNARMED_DAMAGE;
}

View File

@ -0,0 +1,8 @@
package net.Indyuce.mmocore.script.trigger;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
public class MMOCoreTriggerType {
public static final TriggerType LEVEL_UP = new TriggerType("LEVEL_UP"),
CLASS_CHOSEN = new TriggerType("CLASS_CHOSEN");
}