Merge remote-tracking branch 'origin/master'

This commit is contained in:
Indyuce 2022-02-12 11:02:14 +01:00
commit 1d6c7377a2
37 changed files with 790 additions and 100 deletions

16
pom.xml
View File

@ -140,7 +140,7 @@
<dependency> <dependency>
<groupId>io.lumine</groupId> <groupId>io.lumine</groupId>
<artifactId>MythicLib-dist</artifactId> <artifactId>MythicLib-dist</artifactId>
<version>1.3-R21-SNAPSHOT</version> <version>1.3-R27-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -208,6 +208,13 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.denizen</groupId>
<artifactId>Dungeons</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<!-- Guild plugins --> <!-- Guild plugins -->
<dependency> <dependency>
<groupId>com.massivecraft</groupId> <groupId>com.massivecraft</groupId>
@ -230,6 +237,13 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.kingdoms.main</groupId>
<artifactId>Kingdoms</artifactId>
<version>1.11.15.0.0.0.1.1</version>
<scope>provided</scope>
</dependency>
<!-- Quest plugins --> <!-- Quest plugins -->
</dependencies> </dependencies>

View File

@ -101,7 +101,7 @@ public class MMOCore extends LuminePlugin {
public boolean shouldDebugSQL = false; public boolean shouldDebugSQL = false;
private static final int MYTHICLIB_COMPATIBILITY_INDEX = 4; private static final int MYTHICLIB_COMPATIBILITY_INDEX = 7;
public MMOCore() { public MMOCore() {
plugin = this; plugin = this;
@ -276,6 +276,7 @@ public class MMOCore extends LuminePlugin {
Bukkit.getPluginManager().registerEvents(new FishingListener(), this); Bukkit.getPluginManager().registerEvents(new FishingListener(), this);
Bukkit.getPluginManager().registerEvents(new PlayerCollectStats(), this); Bukkit.getPluginManager().registerEvents(new PlayerCollectStats(), this);
Bukkit.getPluginManager().registerEvents(new PlayerPressKeyListener(), 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 * Initialize player data from all online players. This is very important to do

View File

@ -7,6 +7,7 @@ import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.handler.SkillHandler; import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.result.SkillResult; import io.lumine.mythic.lib.skill.result.SkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.AbstractParty; import net.Indyuce.mmocore.party.AbstractParty;
@ -110,7 +111,7 @@ public class MMOCoreAPI {
PlayerMetadata casterMeta = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); PlayerMetadata casterMeta = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
TriggerMetadata triggerMeta = new TriggerMetadata(casterMeta, null, null); TriggerMetadata triggerMeta = new TriggerMetadata(casterMeta, null, null);
RegisteredSkill registered = MMOCore.plugin.skillManager.getSkill(skill.getId()); RegisteredSkill registered = MMOCore.plugin.skillManager.getSkill(skill.getId());
Skill cast = registered == null ? new SimpleSkill(skill) : new CastableSkill(new ClassSkill(registered, 0), level); Skill cast = registered == null ? new SimpleSkill(TriggerType.CAST, skill) : new CastableSkill(new ClassSkill(registered, 0), level);
return cast.cast(triggerMeta); return cast.cast(triggerMeta);
} }
} }

View File

@ -245,7 +245,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
@Override @Override
public int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item) { public int getClaims(ExperienceObject object, ExperienceTable table, ExperienceItem item) {
String key = object.getKey() + "." + table.getId() + "." + item.getId(); String key = object.getKey() + "." + table.getId() + "." + item.getId();
return tableItemClaims.get(key); return tableItemClaims.getOrDefault(key, 0);
} }
@Override @Override

View File

@ -66,8 +66,8 @@ public class AttributeModifier extends PlayerModifier {
Validate.notNull(str, "String cannot be null"); Validate.notNull(str, "String cannot be null");
Validate.notEmpty(str, "String cannot be empty"); Validate.notEmpty(str, "String cannot be empty");
type = str.toCharArray()[str.length() - 1] == '%' ? io.lumine.mythic.lib.player.modifier.ModifierType.RELATIVE : io.lumine.mythic.lib.player.modifier.ModifierType.FLAT; type = str.toCharArray()[str.length() - 1] == '%' ? ModifierType.RELATIVE : ModifierType.FLAT;
value = Double.parseDouble(type == io.lumine.mythic.lib.player.modifier.ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str); value = Double.parseDouble(type == ModifierType.RELATIVE ? str.substring(0, str.length() - 1) : str);
this.attribute = attribute; this.attribute = attribute;
} }
@ -76,7 +76,7 @@ public class AttributeModifier extends PlayerModifier {
this.attribute = object.getString("attribute"); this.attribute = object.getString("attribute");
this.value = object.getDouble("value"); this.value = object.getDouble("value");
type = object.getBoolean("multiplicative", false) ? io.lumine.mythic.lib.player.modifier.ModifierType.RELATIVE : io.lumine.mythic.lib.player.modifier.ModifierType.FLAT; type = object.getBoolean("multiplicative", false) ? ModifierType.RELATIVE : ModifierType.FLAT;
} }
public String getAttribute() { public String getAttribute() {

View File

@ -7,6 +7,7 @@ import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.util.PostLoadObject; import io.lumine.mythic.lib.api.util.PostLoadObject;
import io.lumine.mythic.lib.version.VersionMaterial; import io.lumine.mythic.lib.version.VersionMaterial;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions; import net.Indyuce.mmocore.api.player.profess.resource.ManaDisplayOptions;
import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration; import net.Indyuce.mmocore.api.player.profess.resource.ResourceRegeneration;
@ -20,6 +21,8 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.experience.provider.ExperienceDispenser; import net.Indyuce.mmocore.experience.provider.ExperienceDispenser;
import net.Indyuce.mmocore.experience.provider.MainExperienceDispenser; import net.Indyuce.mmocore.experience.provider.MainExperienceDispenser;
import net.Indyuce.mmocore.experience.source.type.ExperienceSource; 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.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -31,8 +34,8 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
@ -50,9 +53,12 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
private final Map<StatType, LinearValue> stats = new HashMap<>(); private final Map<StatType, LinearValue> stats = new HashMap<>();
private final Map<String, ClassSkill> skills = new LinkedHashMap<>(); private final Map<String, ClassSkill> skills = new LinkedHashMap<>();
private final List<Subclass> subclasses = new ArrayList<>(); private final List<Subclass> subclasses = new ArrayList<>();
private final Map<String, ClassTrigger> classTriggers = new HashMap<>();
private final Map<PlayerResource, ResourceRegeneration> resourceHandlers = new HashMap<>(); private final Map<PlayerResource, ResourceRegeneration> resourceHandlers = new HashMap<>();
@Deprecated
private final Map<String, EventTrigger> eventTriggers = new HashMap<>();
private final CastingParticle castParticle; private final CastingParticle castParticle;
public PlayerClass(String id, FileConfiguration config) { public PlayerClass(String id, FileConfiguration config) {
@ -101,6 +107,16 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
} }
this.expTable = expTable; this.expTable = expTable;
if (config.contains("triggers"))
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")) if (config.contains("attributes"))
for (String key : config.getConfigurationSection("attributes").getKeys(false)) for (String key : config.getConfigurationSection("attributes").getKeys(false))
try { try {
@ -279,6 +295,26 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
return options.containsKey(option) ? options.get(option) : option.getDefault(); return options.containsKey(option) ? options.get(option) : option.getDefault();
} }
@Nullable
public ClassTrigger getClassTrigger(ClassTriggerType type) {
return classTriggers.get(type);
}
@Deprecated
public Set<String> getEventTriggers() {
return eventTriggers.keySet();
}
@Deprecated
public boolean hasEventTriggers(String name) {
return eventTriggers.containsKey(name);
}
@Deprecated
public EventTrigger getEventTriggers(String name) {
return eventTriggers.get(name);
}
@Deprecated @Deprecated
public void setStat(StatType type, double base, double perLevel) { public void setStat(StatType type, double base, double perLevel) {
setStat(type, new LinearValue(base, perLevel)); setStat(type, new LinearValue(base, perLevel));

View File

@ -0,0 +1,43 @@
package net.Indyuce.mmocore.api.player.profess.event;
import io.lumine.mythic.lib.api.MMOLineConfig;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.quest.trigger.Trigger;
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import org.apache.commons.lang.Validate;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
/**
* @deprecated Should have NEVER been implemented that way
*/
@Deprecated
public class EventTrigger {
private final String event;
private final Set<Trigger> triggers = new LinkedHashSet<>();
public EventTrigger(String event, List<String> list) {
Validate.notNull(list, "Could not load trigger list");
this.event = event;
for (String format : list)
try {
triggers.add(MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(format)));
} catch (IllegalArgumentException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load trigger '" + format + "' from event trigger '" + event + "': " + exception.getMessage());
}
}
public String getEvent() {
return event;
}
public Set<Trigger> getTriggers() {
return triggers;
}
}

View File

@ -0,0 +1,8 @@
package net.Indyuce.mmocore.api.player.profess.event;
import org.bukkit.event.Listener;
@Deprecated
public interface EventTriggerHandler extends Listener {
boolean handles(String event);
}

View File

@ -0,0 +1,33 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import io.lumine.mythic.lib.damage.DamageType;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@Deprecated
public class AttackEventTrigger implements EventTriggerHandler {
@Override
public boolean handles(String event) {
return event.endsWith("-damage");
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void a(PlayerAttackEvent event) {
// We don't want players dying by themselves when using an enderpearl.
if (event.getPlayer().equals(event.getEntity())) return;
PlayerData player = PlayerData.get(event.getData().getUniqueId());
PlayerClass profess = player.getProfess();
for (DamageType type : event.getAttack().getDamage().collectTypes()) {
String path = type.getPath() + "-damage";
if (profess.hasEventTriggers(path))
profess.getEventTriggers(path).getTriggers().forEach(trigger -> trigger.apply(player));
}
}
}

View File

@ -0,0 +1,24 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
@Deprecated
public class BlockBrokenTrigger implements EventTriggerHandler {
@Override
public boolean handles(String event) {
return event.startsWith("break-block");
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void a(BlockBreakEvent event) {
PlayerData player = PlayerData.get(event.getPlayer());
if (player.getProfess().hasEventTriggers("break-block"))
player.getProfess().getEventTriggers("break-block").getTriggers().forEach(trigger -> trigger.apply(player));
}
}

View File

@ -0,0 +1,24 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockPlaceEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
@Deprecated
public class BlockPlacedTrigger implements EventTriggerHandler {
@Override
public boolean handles(String event) {
return event.startsWith("place-block");
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void a(BlockPlaceEvent event) {
PlayerData player = PlayerData.get(event.getPlayer());
if (player.getProfess().hasEventTriggers("place-block"))
player.getProfess().getEventTriggers("place-block").getTriggers().forEach(trigger -> trigger.apply(player));
}
}

View File

@ -0,0 +1,29 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.PlayerChangeClassEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@Deprecated
public class ClassChosenEventTrigger implements EventTriggerHandler {
@Override
public boolean handles(String event) {
return event.startsWith("class-chosen");
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void a(PlayerChangeClassEvent event) {
PlayerData player = event.getData();
if (event.getNewClass().hasEventTriggers("class-chosen")) {
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> {
event.getNewClass().getEventTriggers("class-chosen").getTriggers().forEach(trigger -> trigger.apply(player));
}, 1);
}
}
}

View File

@ -0,0 +1,42 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
@Deprecated
public class LevelUpEventTrigger implements EventTriggerHandler {
@Override
public boolean handles(String event) {
return event.startsWith("level-up");
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void a(PlayerLevelUpEvent event) {
PlayerData player = event.getData();
PlayerClass profess = player.getProfess();
for(int i = event.getOldLevel(); i < event.getNewLevel(); i++) {
int level = i + 1;
if(event.hasProfession()) {
String prof = event.getProfession().getId().toLowerCase();
processTrigger(player, profess, "level-up-" + prof);
processTrigger(player, profess, "level-up-" + prof + "-" + level);
} else {
processTrigger(player, profess, "level-up");
processTrigger(player, profess, "level-up-" + level);
if(profess.getMaxLevel() == level)
processTrigger(player, profess, "level-up-max");
}
}
}
public void processTrigger(PlayerData player, PlayerClass profess, String trigger) {
if(profess.hasEventTriggers(trigger)) profess.getEventTriggers(trigger).getTriggers().forEach(t -> t.apply(player));
}
}

View File

@ -0,0 +1,48 @@
package net.Indyuce.mmocore.api.player.profess.event.trigger;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.text.DecimalFormat;
@Deprecated
public class MultipleLevelUpEventTrigger implements EventTriggerHandler {
@Override
public boolean handles(String event) {
return event.startsWith("level-up-multiple");
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void a(PlayerLevelUpEvent event) {
PlayerData player = event.getData();
PlayerClass profess = player.getProfess();
for(int i = event.getOldLevel(); i < event.getNewLevel(); i++) {
int level = i + 1;
for (String t : profess.getEventTriggers()){
if (t.startsWith("level-up-multiple")) {
String[] split = t.split("-");
double multiple = Double.parseDouble(split[split.length-1]);
if (level / multiple % 1 == 0) {
DecimalFormat f = new DecimalFormat("#");
if (event.hasProfession()) {
processTrigger(player, profess, "level-up-multiple-" + event.getProfession().getId().toLowerCase() + "-" + f.format(multiple));
} else {
processTrigger(player, profess, "level-up-multiple-" + f.format(multiple));
}
}
}
}
}
}
public void processTrigger(PlayerData player, PlayerClass profess, String trigger) {
if(profess.hasEventTriggers(trigger)) profess.getEventTriggers(trigger).getTriggers().forEach(t -> t.apply(player));
}
}

View File

@ -7,7 +7,12 @@ import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.player.modifier.ModifierSource; import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.modifier.ModifierType; import io.lumine.mythic.lib.player.modifier.ModifierType;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.experience.Profession;
import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.ClassSkill;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
public class PlayerStats { public class PlayerStats {
private final PlayerData data; private final PlayerData data;
@ -37,6 +42,25 @@ public class PlayerStats {
return getMap().getInstance(stat); return getMap().getInstance(stat);
} }
/**
* Allows for stat type enum to have dynamic professions.
* ID FORMAT: STAT_TYPE_HERE_PROFESSION_HERE
*
* @param type the type of stat
* @param profession the stat's specific permission
* @return instance of found stat
* @author Ehhthan
*/
@NotNull
public StatInstance getInstance(StatType type, @Nullable Profession profession) {
if (profession == null)
return getInstance(type);
else {
String id = (type.name() + '_' + profession.getId()).replace('-', '_').replace(' ', '_').toUpperCase(Locale.ROOT);
return getInstance(id);
}
}
/* /*
* applies relative attributes on the base stat too * applies relative attributes on the base stat too
*/ */
@ -78,11 +102,11 @@ public class PlayerStats {
* as statistics (when the player level changes, when his class * as statistics (when the player level changes, when his class
* changes, when he logs on..) * changes, when he logs on..)
* *
* This updates the player's passive skills * This updates the player's PASSIVE skills
*/ */
data.getMMOPlayerData().getPassiveSkillMap().removeModifiers("MMOCorePassiveSkill"); data.getMMOPlayerData().getPassiveSkillMap().removeModifiers("MMOCorePassiveSkill");
for (ClassSkill skill : data.getProfess().getSkills()) for (ClassSkill skill : data.getProfess().getSkills())
if (skill.getSkill().hasTrigger()) if (skill.getSkill().getTrigger().isPassive())
data.getMMOPlayerData().getPassiveSkillMap().addModifier(skill.toPassive(data)); data.getMMOPlayerData().getPassiveSkillMap().addModifier(skill.toPassive(data));
} }
} }

View File

@ -10,6 +10,7 @@ import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent; import net.Indyuce.mmocore.api.event.PlayerExperienceGainEvent;
import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent; import net.Indyuce.mmocore.api.event.PlayerLevelUpEvent;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.stats.StatType;
import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
@ -164,6 +165,9 @@ public class PlayerProfessions {
value = MMOCore.plugin.boosterManager.calculateExp(profession, value); value = MMOCore.plugin.boosterManager.calculateExp(profession, value);
// Adds functionality for additional experience per profession.
value *= 1 + playerData.getStats().getInstance(StatType.ADDITIONAL_EXPERIENCE, profession).getTotal() / 100;
// Display hologram // Display hologram
if (hologramLocation != null) if (hologramLocation != null)
MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message()); MMOCoreUtils.displayIndicator(hologramLocation.add(.5, 1.5, .5), MMOCore.plugin.configManager.getSimpleMessage("exp-hologram", "exp", "" + value).message());

View File

@ -353,7 +353,7 @@ public class SkillList extends EditableInventory {
if (selected == null) if (selected == null)
return; return;
if (selected.getSkill().isPassive()) { if (selected.getSkill().getTrigger().isPassive()) {
MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player); MMOCore.plugin.configManager.getSimpleMessage("not-active-skill").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 2);
return; return;

View File

@ -1,13 +1,18 @@
package net.Indyuce.mmocore.guild; package net.Indyuce.mmocore.guild;
import net.Indyuce.mmocore.guild.compat.FactionsGuildModule; import net.Indyuce.mmocore.guild.compat.FactionsGuildModule;
import net.Indyuce.mmocore.guild.compat.GuildsGuildModule;
import net.Indyuce.mmocore.guild.compat.UltimateClansGuildModule; import net.Indyuce.mmocore.guild.compat.UltimateClansGuildModule;
import net.Indyuce.mmocore.guild.provided.MMOCoreGuildModule;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import javax.inject.Provider; import javax.inject.Provider;
public enum GuildModuleType { public enum GuildModuleType {
FACTIONS("Factions", FactionsGuildModule::new), FACTIONS("Factions", FactionsGuildModule::new),
GUILDS("Guilds", GuildsGuildModule::new),
KINGDOMSX("Guilds", GuildsGuildModule::new),
MMOCORE("MMOCore", MMOCoreGuildModule::new),
ULTIMATE_CLANS("UltimateClans", UltimateClansGuildModule::new), ULTIMATE_CLANS("UltimateClans", UltimateClansGuildModule::new),
; ;

View File

@ -6,6 +6,7 @@ import com.massivecraft.factions.Faction;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild; import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule; import net.Indyuce.mmocore.guild.GuildModule;
import org.jetbrains.annotations.NotNull;
public class FactionsGuildModule implements GuildModule { public class FactionsGuildModule implements GuildModule {
@ -16,6 +17,8 @@ public class FactionsGuildModule implements GuildModule {
} }
class CustomGuild implements AbstractGuild { class CustomGuild implements AbstractGuild {
@NotNull
private final Faction faction; private final Faction faction;
CustomGuild(Faction faction) { CustomGuild(Faction faction) {

View File

@ -5,6 +5,7 @@ import me.glaremasters.guilds.guild.Guild;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild; import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule; import net.Indyuce.mmocore.guild.GuildModule;
import org.jetbrains.annotations.NotNull;
public class GuildsGuildModule implements GuildModule { public class GuildsGuildModule implements GuildModule {
@ -15,6 +16,8 @@ public class GuildsGuildModule implements GuildModule {
} }
class CustomGuild implements AbstractGuild { class CustomGuild implements AbstractGuild {
@NotNull
private final Guild guild; private final Guild guild;
CustomGuild(Guild guild) { CustomGuild(Guild guild) {

View File

@ -0,0 +1,30 @@
package net.Indyuce.mmocore.guild.compat;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.kingdoms.constants.kingdom.Kingdom;
import org.kingdoms.constants.player.KingdomPlayer;
import org.kingdoms.main.Kingdoms;
public class KingdomsXGuildModule implements GuildModule {
@Override
public AbstractGuild getGuild(PlayerData playerData) {
KingdomPlayer kPlayer = Kingdoms.get().getDataHandlers().getKingdomPlayerManager().getData(playerData.getUniqueId());
Kingdom kingdom = kPlayer == null ? null : kPlayer.getKingdom();
return kingdom == null ? null : new CustomGuild(kingdom);
}
class CustomGuild implements AbstractGuild {
@NotNull
private final Kingdom kingdom;
CustomGuild(Kingdom kingdom) {
this.kingdom = kingdom;
}
}
}

View File

@ -6,6 +6,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.guild.AbstractGuild; import net.Indyuce.mmocore.guild.AbstractGuild;
import net.Indyuce.mmocore.guild.GuildModule; import net.Indyuce.mmocore.guild.GuildModule;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
public class UltimateClansGuildModule implements GuildModule { public class UltimateClansGuildModule implements GuildModule {
private static final UClans API = (UClans) Bukkit.getPluginManager().getPlugin("UltimateCLans"); private static final UClans API = (UClans) Bukkit.getPluginManager().getPlugin("UltimateCLans");
@ -15,8 +16,9 @@ public class UltimateClansGuildModule implements GuildModule {
return API.getPlayerAPI().hasClan(playerData.getUniqueId()) ? new CustomGuild(API.getClanAPI().getClan(API.getPlayerAPI().getClanID(playerData.getUniqueId()))) : null; return API.getPlayerAPI().hasClan(playerData.getUniqueId()) ? new CustomGuild(API.getClanAPI().getClan(API.getPlayerAPI().getClanID(playerData.getUniqueId()))) : null;
} }
class CustomGuild implements AbstractGuild { class CustomGuild implements AbstractGuild {
@NotNull
private final ClanData clan; private final ClanData clan;
CustomGuild(ClanData clan) { CustomGuild(ClanData clan) {

View File

@ -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.
* <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}
*/
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);
}
@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 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<TriggerMetadata> triggerMetaProvider) {
// return applyTriggers(PlayerData.get(player), type, triggerMetaProvider);
// }
// @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

@ -15,9 +15,7 @@ public class FishingDropItem {
private final int weight; private final int weight;
public FishingDropItem(String value) { public FishingDropItem(MMOLineConfig config) {
MMOLineConfig config = new MMOLineConfig(value);
config.validate("tugs", "experience"); config.validate("tugs", "experience");
tugs = new RandomAmount(config.getString("tugs")); tugs = new RandomAmount(config.getString("tugs"));

View File

@ -4,14 +4,16 @@ import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.ClassOption; import net.Indyuce.mmocore.api.player.profess.ClassOption;
import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.event.EventTriggerHandler;
import net.Indyuce.mmocore.api.player.profess.event.trigger.*;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.HandlerList;
import java.io.File; import java.io.File;
import java.util.Collection; import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
public class ClassManager implements MMOCoreManager { public class ClassManager implements MMOCoreManager {
@ -23,6 +25,26 @@ public class ClassManager implements MMOCoreManager {
*/ */
private PlayerClass defaultClass; private PlayerClass defaultClass;
/**
* Same different types of trigger events to be able to
* map them later in the player class instances.
*/
private final Set<EventTriggerHandler> triggerHandlers = new HashSet<>();
public ClassManager() {
registerEvent(new LevelUpEventTrigger());
registerEvent(new AttackEventTrigger());
registerEvent(new ClassChosenEventTrigger());
registerEvent(new BlockBrokenTrigger());
registerEvent(new BlockPlacedTrigger());
registerEvent(new MultipleLevelUpEventTrigger());
}
@Deprecated
public void registerEvent(EventTriggerHandler handler) {
triggerHandlers.add(handler);
}
public void register(PlayerClass playerClass) { public void register(PlayerClass playerClass) {
map.put(playerClass.getId(), playerClass); map.put(playerClass.getId(), playerClass);
} }
@ -48,15 +70,18 @@ public class ClassManager implements MMOCoreManager {
return defaultClass; return defaultClass;
} }
public void reloadPlayerClasses() {
PlayerData.getAll().forEach(data -> data.setClass(get(data.getProfess().getId())));
}
@Override @Override
public void initialize(boolean clearBefore) { public void initialize(boolean clearBefore) {
if (clearBefore) if (clearBefore) {
map.clear(); map.clear();
/*
* Do not clear the list of trigger listeners, since it's only setup
* once the server loads and it is never modified.
*/
triggerHandlers.forEach(HandlerList::unregisterAll);
}
for (File file : new File(MMOCore.plugin.getDataFolder() + "/classes").listFiles()) for (File file : new File(MMOCore.plugin.getDataFolder() + "/classes").listFiles())
try { try {
String id = file.getName().substring(0, file.getName().length() - 4); String id = file.getName().substring(0, file.getName().length() - 4);
@ -74,5 +99,8 @@ public class ClassManager implements MMOCoreManager {
defaultClass = map.values().stream().filter(profess -> profess.hasOption(ClassOption.DEFAULT)).findFirst() defaultClass = map.values().stream().filter(profess -> profess.hasOption(ClassOption.DEFAULT)).findFirst()
.orElse(new PlayerClass("HUMAN", "Human", Material.LEATHER_BOOTS)); .orElse(new PlayerClass("HUMAN", "Human", Material.LEATHER_BOOTS));
// Register event triggers
triggerHandlers.forEach(handler -> Bukkit.getPluginManager().registerEvents(handler, MMOCore.plugin));
} }
} }

View File

@ -68,10 +68,10 @@ public class FishingManager extends SpecificProfessionManager {
for (String str : list) for (String str : list)
try { try {
FishingDropItem dropItem = new FishingDropItem(str); FishingDropItem dropItem = new FishingDropItem(new MMOLineConfig(str));
maxWeight += dropItem.getWeight(); maxWeight += dropItem.getWeight();
items.add(dropItem); items.add(dropItem);
} catch (IllegalArgumentException | IndexOutOfBoundsException exception) { } catch (RuntimeException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, MMOCore.plugin.getLogger().log(Level.WARNING,
"Could not load item '" + str + "' from fishing drop table '" + id + "': " + exception.getMessage()); "Could not load item '" + str + "' from fishing drop table '" + id + "': " + exception.getMessage());
} }
@ -91,14 +91,11 @@ public class FishingManager extends SpecificProfessionManager {
} }
public FishingDropItem getRandomItem() { public FishingDropItem getRandomItem() {
int weight = random.nextInt(maxWeight); int randomCoefficient = random.nextInt(maxWeight);
for (FishingDropItem item : items) { for (FishingDropItem item : items)
weight -= item.getWeight(); if ((randomCoefficient -= item.getWeight()) <= 0)
if (weight <= 0)
return item; return item;
}
throw new NullPointerException("Could not find item in drop table"); throw new NullPointerException("Could not find item in drop table");
} }

View File

@ -1,21 +1,18 @@
package net.Indyuce.mmocore.party; package net.Indyuce.mmocore.party;
import net.Indyuce.mmocore.party.compat.DungeonsPartyModule; import net.Indyuce.mmocore.party.compat.*;
import net.Indyuce.mmocore.party.compat.McMMOPartyModule;
import net.Indyuce.mmocore.party.compat.PAFPartyModule;
import net.Indyuce.mmocore.party.compat.PartiesPartyModule;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import javax.inject.Provider; import javax.inject.Provider;
public enum PartyModuleType { public enum PartyModuleType {
DUNGEONSXL("DungeonsXL", () -> new DungeonsPartyModule()), DUNGEONS("Dungeons", DungeonsPartyModule::new),
MMOCORE("MMOCore", () -> new MMOCorePartyModule()), DUNGEONSXL("DungeonsXL", DungeonsXLPartyModule::new),
PARTY_AND_FRIENDS("PartyAndFriends", () -> new PAFPartyModule()), MCMMO("mcMMO", McMMOPartyModule::new),
PARTIES("Parties", () -> new PartiesPartyModule()), MMOCORE("MMOCore", MMOCorePartyModule::new),
MCMMO("mcMMO", () -> new McMMOPartyModule()), PARTIES("Parties", PartiesPartyModule::new),
// DUNGEONS("Dungeons", null), PARTY_AND_FRIENDS("PartyAndFriends", PAFPartyModule::new),
; ;
private final String pluginName; private final String pluginName;

View File

@ -1,52 +1,38 @@
package net.Indyuce.mmocore.party.compat; package net.Indyuce.mmocore.party.compat;
import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.player.PlayerGroup;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.AbstractParty; import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.PartyModule; import net.Indyuce.mmocore.party.PartyModule;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
@Deprecated
public class DungeonsPartyModule implements PartyModule { public class DungeonsPartyModule implements PartyModule {
@Override @Override
public AbstractParty getParty(PlayerData playerData) { public AbstractParty getParty(PlayerData playerData) {
PlayerGroup group = DungeonsXL.getInstance().getPlayerGroup(playerData.getPlayer()); throw new RuntimeException("Not supported");
return group == null ? null : new CustomParty(group);
} }
class CustomParty implements AbstractParty { class CustomParty implements AbstractParty {
private final PlayerGroup group;
public CustomParty(PlayerGroup group) { public CustomParty() {
this.group = group;
} }
@Override @Override
public boolean hasMember(Player player) { public boolean hasMember(Player player) {
return group.getMembers().contains(player.getUniqueId()); throw new RuntimeException("Not supported");
} }
@Override @Override
public List<PlayerData> getOnlineMembers() { public List<PlayerData> getOnlineMembers() {
List<PlayerData> list = new ArrayList<>(); throw new RuntimeException("Not supported");
for (UUID playerUid : group.getMembers().getUniqueIds()) {
PlayerData found = PlayerData.get(playerUid);
if (found.isOnline())
list.add(found);
}
return list;
} }
@Override @Override
public int countMembers() { public int countMembers() {
return group.getMembers().getUniqueIds().size(); throw new RuntimeException("Not supported");
} }
} }
} }

View File

@ -0,0 +1,52 @@
package net.Indyuce.mmocore.party.compat;
import de.erethon.dungeonsxl.DungeonsXL;
import de.erethon.dungeonsxl.api.player.PlayerGroup;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.PartyModule;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class DungeonsXLPartyModule implements PartyModule {
@Override
public AbstractParty getParty(PlayerData playerData) {
PlayerGroup group = DungeonsXL.getInstance().getPlayerGroup(playerData.getPlayer());
return group == null ? null : new CustomParty(group);
}
class CustomParty implements AbstractParty {
private final PlayerGroup group;
public CustomParty(PlayerGroup group) {
this.group = group;
}
@Override
public boolean hasMember(Player player) {
return group.getMembers().contains(player.getUniqueId());
}
@Override
public List<PlayerData> getOnlineMembers() {
List<PlayerData> list = new ArrayList<>();
for (UUID playerUid : group.getMembers().getUniqueIds()) {
PlayerData found = PlayerData.get(playerUid);
if (found.isOnline())
list.add(found);
}
return list;
}
@Override
public int countMembers() {
return group.getMembers().getUniqueIds().size();
}
}
}

View File

@ -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.
* <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}
*/
public class ClassTrigger {
private final ClassTriggerType type;
private final List<Trigger> 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<String> 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));
}
}

View File

@ -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;
}

View File

@ -6,16 +6,20 @@ import io.lumine.mythic.lib.player.cooldown.CooldownInfo;
import io.lumine.mythic.lib.skill.Skill; import io.lumine.mythic.lib.skill.Skill;
import io.lumine.mythic.lib.skill.SkillMetadata; import io.lumine.mythic.lib.skill.SkillMetadata;
import io.lumine.mythic.lib.skill.handler.SkillHandler; import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent; import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import org.jetbrains.annotations.NotNull;
public class CastableSkill extends Skill { public class CastableSkill extends Skill {
private final ClassSkill skill; private final ClassSkill skill;
private final int skillLevel; private final int skillLevel;
public CastableSkill(ClassSkill skill, int skillLevel) { public CastableSkill(ClassSkill skill, int skillLevel) {
super(skill.getSkill().getTrigger());
this.skill = skill; this.skill = skill;
this.skillLevel = skillLevel; this.skillLevel = skillLevel;
} }
@ -27,32 +31,33 @@ public class CastableSkill extends Skill {
@Override @Override
public boolean getResult(SkillMetadata skillMeta) { public boolean getResult(SkillMetadata skillMeta) {
PlayerData playerData = PlayerData.get(skillMeta.getCaster().getData().getUniqueId()); PlayerData playerData = PlayerData.get(skillMeta.getCaster().getData().getUniqueId());
boolean loud = !getTrigger().isSilent();
// If the caster has unlocked that skill // If the caster has unlocked that skill
if (!playerData.hasSkillUnlocked(skill)) { if (!playerData.hasSkillUnlocked(skill)) {
MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(playerData.getPlayer()); if (loud) MMOCore.plugin.configManager.getSimpleMessage("not-unlocked-skill").send(playerData.getPlayer());
return false; return false;
} }
// Global cooldown check // Global cooldown check
if (!skill.getSkill().isPassive() && playerData.getActivityTimeOut(PlayerActivity.CAST_SKILL) > 0) if (!getTrigger().isPassive() && playerData.getActivityTimeOut(PlayerActivity.CAST_SKILL) > 0)
return false; return false;
// Cooldown check // Cooldown check
if (skillMeta.getCaster().getData().getCooldownMap().isOnCooldown(this)) { if (skillMeta.getCaster().getData().getCooldownMap().isOnCooldown(this)) {
MMOCore.plugin.configManager.getSimpleMessage("casting.on-cooldown").send(playerData.getPlayer()); if (loud) MMOCore.plugin.configManager.getSimpleMessage("casting.on-cooldown").send(playerData.getPlayer());
return false; return false;
} }
// Mana cost // Mana cost
if (playerData.getMana() < getModifier("mana")) { if (playerData.getMana() < getModifier("mana")) {
MMOCore.plugin.configManager.getSimpleMessage("casting.no-mana", "mana", playerData.getProfess().getManaDisplay().getName()).send(playerData.getPlayer()); if (loud) MMOCore.plugin.configManager.getSimpleMessage("casting.no-mana", "mana", playerData.getProfess().getManaDisplay().getName()).send(playerData.getPlayer());
return false; return false;
} }
// Stamina cost // Stamina cost
if (playerData.getStamina() < getModifier("stamina")) { if (playerData.getStamina() < getModifier("stamina")) {
MMOCore.plugin.configManager.getSimpleMessage("casting.no-stamina").send(playerData.getPlayer()); if (loud) MMOCore.plugin.configManager.getSimpleMessage("casting.no-stamina").send(playerData.getPlayer());
return false; return false;
} }

View File

@ -114,8 +114,8 @@ public class ClassSkill implements CooldownObject {
} }
public PassiveSkill toPassive(PlayerData caster) { public PassiveSkill toPassive(PlayerData caster) {
Validate.isTrue(skill.hasTrigger(), "Skill is active"); Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active");
return new PassiveSkill("MMOCorePassiveSkill", skill.getTrigger(), toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER); return new PassiveSkill("MMOCorePassiveSkill", toCastable(caster), EquipmentSlot.OTHER, ModifierSource.OTHER);
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package net.Indyuce.mmocore.skill; package net.Indyuce.mmocore.skill;
import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.skill.handler.SkillHandler; import io.lumine.mythic.lib.skill.handler.SkillHandler;
import io.lumine.mythic.lib.skill.trigger.TriggerType; import io.lumine.mythic.lib.skill.trigger.TriggerType;
import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.MMOCoreUtils;
@ -27,13 +28,13 @@ public class RegisteredSkill {
public RegisteredSkill(SkillHandler<?> handler, ConfigurationSection config) { public RegisteredSkill(SkillHandler<?> handler, ConfigurationSection config) {
this.handler = handler; this.handler = handler;
name = Objects.requireNonNull(config.getString("name"), "Could not find skill name"); name = Objects.requireNonNull(config.getString("name"), "Could not find skill name");
icon = MMOCoreUtils.readIcon(Objects.requireNonNull(config.getString("material"), "Could not find skill icon")); icon = MMOCoreUtils.readIcon(Objects.requireNonNull(config.getString("material"), "Could not find skill icon"));
lore = Objects.requireNonNull(config.getStringList("lore"), "Could not find skill lore"); lore = Objects.requireNonNull(config.getStringList("lore"), "Could not find skill lore");
// Trigger type // Trigger type
Validate.isTrue(getHandler().isTriggerable() || !config.contains("passive-type"), "Cannot change the trigger type of a default passive skill"); triggerType = getHandler().isTriggerable() ? (config.contains("passive-type") ? TriggerType.valueOf(UtilityMethods.enumName(config.getString("passive-type"))) : TriggerType.CAST) : TriggerType.API;
triggerType = config.contains("passive-type") ? TriggerType.valueOf(config.getString("passive-type").toUpperCase().replace(" ", "_").replace("-", "_")) : null;
for (String mod : handler.getModifiers()) for (String mod : handler.getModifiers())
defaultModifiers.put(mod, config.contains(mod) ? new LinearValue(config.getConfigurationSection(mod)) : LinearValue.ZERO); defaultModifiers.put(mod, config.contains(mod) ? new LinearValue(config.getConfigurationSection(mod)) : LinearValue.ZERO);
@ -67,35 +68,6 @@ public class RegisteredSkill {
return defaultModifiers.containsKey(modifier); return defaultModifiers.containsKey(modifier);
} }
/**
* There are three types of MMOCore skills:
* - skills with no trigger type (therefore active)
* - default passive skills with no trigger type
* - custom skills with a trigger type (therefore passive)
* <p>
* Illegal:
* - default passive skills with a trigger type
*
* @return If the skill should
*/
public boolean hasTrigger() {
return triggerType != null;
}
/**
* Two types of passive skills:
* - custom passive skills, with a trigger type
* - default passive skills which are untriggerable
* <p>
* This option dictates whether or not it
* can be cast when in casting mode.
*
* @return If the given skill is passive
*/
public boolean isPassive() {
return triggerType != null || !getHandler().isTriggerable();
}
@NotNull @NotNull
public TriggerType getTrigger() { public TriggerType getTrigger() {
return Objects.requireNonNull(triggerType, "Skill has no trigger"); return Objects.requireNonNull(triggerType, "Skill has no trigger");

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}