Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ka0rX 2022-11-29 07:49:41 +01:00
commit a64a2d0ab8
30 changed files with 170 additions and 163 deletions

View File

@ -192,7 +192,7 @@
<dependency>
<groupId>net.citizensnpcs</groupId>
<artifactId>Citizens</artifactId>
<version>2.0.25</version>
<version>2.0.30</version>
<scope>provided</scope>
</dependency>

View File

@ -277,8 +277,8 @@ public class MMOCore extends JavaPlugin {
commandMap.register("mmocore", new PartyCommand(config.getConfigurationSection("party")));
if (config.contains("guild"))
commandMap.register("mmocore", new GuildCommand(config.getConfigurationSection("guild")));
if (config.contains("skill-tree"))
commandMap.register("mmocore", new SkillTreeCommand(config.getConfigurationSection("skill-tree")));
if (config.contains("skill-trees"))
commandMap.register("mmocore", new SkillTreeCommand(config.getConfigurationSection("skill-trees")));
if (hasEconomy() && economy.isValid()) {
if (config.contains("withdraw"))
commandMap.register("mmocore", new WithdrawCommand(config.getConfigurationSection("withdraw")));

View File

@ -6,8 +6,6 @@ import io.lumine.mythic.lib.api.stat.StatInstance;
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
import io.lumine.mythic.lib.player.cooldown.CooldownMap;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import net.Indyuce.mmocore.party.provided.Party;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.ConfigMessage;
import net.Indyuce.mmocore.api.SoundEvent;
@ -34,8 +32,9 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
import net.Indyuce.mmocore.guild.provided.Guild;
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
import net.Indyuce.mmocore.party.AbstractParty;
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
import net.Indyuce.mmocore.party.provided.Party;
import net.Indyuce.mmocore.player.Unlockable;
import net.Indyuce.mmocore.player.stats.StatInfo;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
@ -72,6 +71,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
*/
private final MMOPlayerData mmoData;
/**
* Can be null, the {@link #getProfess()} method will return the
* player class, or the default one if this field is null.
@ -119,8 +119,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
private final Map<String, Integer> tableItemClaims = new HashMap<>();
// NON-FINAL player data stuff made public to facilitate field change
public boolean noCooldown;
private boolean statLoaded;
public boolean noCooldown, statsLoaded;
public CombatRunnable combat;
/**
@ -136,14 +135,13 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
questData = new PlayerQuests(this);
playerStats = new PlayerStats(this);
//Used to see if the triggers need to be applied
boolean statLoaded = false;
// Used to see if the triggers need to be applied
for (StatInstance instance : mmoData.getStatMap().getInstances())
for (StatModifier modifier : instance.getModifiers())
if (modifier.getKey().startsWith("trigger"))
statLoaded = true;
this.statLoaded = statLoaded;
if (modifier.getKey().startsWith("trigger")) {
statsLoaded = true;
break;
}
}
/**
@ -173,34 +171,28 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
j++;
}
for (SkillTree skillTree : profess.getSkillTrees()) {
for (SkillTreeNode node : skillTree.getNodes()) {
for (SkillTree skillTree : getProfess().getSkillTrees())
for (SkillTreeNode node : skillTree.getNodes())
if (!nodeLevels.containsKey(node))
nodeLevels.put(node, 0);
}
}
setupSkillTree();
}
public void setupSkillTree() {
//Node states setup
for (SkillTree skillTree : profess.getSkillTrees())
// Node states setup
for (SkillTree skillTree : getProfess().getSkillTrees())
skillTree.setupNodeState(this);
if (!statLoaded)
//Stat triggers setup
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) {
for (SkillTreeNode node : skillTree.getNodes()) {
// Stat triggers setup
if (!statsLoaded) {
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll())
for (SkillTreeNode node : skillTree.getNodes())
node.getExperienceTable().claimStatTriggers(this, node);
}
}
statLoaded = true;
statsLoaded = true;
}
}
public int getPointSpent(SkillTree skillTree) {
return pointSpent.getOrDefault(skillTree, 0);
}
@ -211,7 +203,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
public void clearPointsSpent() {
pointSpent.clear();
}
public void setSkillTreePoints(String treeId, int points) {
@ -233,27 +224,23 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return new HashMap(skillTreePoints);
}
public void clearSkillTreePoints() {
skillTreePoints.clear();
}
public boolean containsSkillPointTreeId(String treeId) {
return skillTreePoints.containsKey(treeId);
}
public Set<Map.Entry<String, Integer>> getNodeLevelsEntrySet() {
HashMap<String, Integer> nodeLevelsString = new HashMap<>();
for (SkillTreeNode node : nodeLevels.keySet()) {
for (SkillTreeNode node : nodeLevels.keySet())
nodeLevelsString.put(node.getFullId(), nodeLevels.get(node));
}
return nodeLevelsString.entrySet();
}
public boolean isStatLoaded() {
return statLoaded;
public boolean areStatsLoaded() {
return statsLoaded;
}
public Map<SkillTreeNode, Integer> getNodeLevels() {
@ -377,7 +364,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
tableItemClaims.clear();
}
@Override
public void close() {
@ -796,8 +782,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
* If it's null, no hologram will be displayed
* @param splitExp Should the exp be split among party members
*/
public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation,
boolean splitExp) {
public void giveExperience(double value, EXPSource source, @Nullable Location hologramLocation, boolean splitExp) {
if (value <= 0)
return;
@ -999,7 +984,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return Objects.requireNonNull(skillCasting, "Player not in casting mode");
}
public void leaveCastingMode() {
public void leaveSkillCasting() {
Validate.isTrue(isCasting(), "Player not in casting mode");
skillCasting.close();
this.skillCasting = null;
@ -1115,36 +1100,56 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
return slot >= boundSkills.size() ? null : boundSkills.get(slot);
}
public void setBoundPassiveSkill(int slot, PassiveSkill skill) {
/**
* Registers a passive skill in the list. This method guarantees interface
* between ML passive skills and the MMOCore list.
*
* @param slot Slot to which you're binding the skill.
* Use -1 to force-register the skill
* @param skill Skill being bound
*/
public void bindPassiveSkill(int slot, @NotNull PassiveSkill skill) {
Validate.notNull(skill, "Skill cannot be null");
if (boundPassiveSkills.size() < getProfess().getMaxBoundActiveSkills())
boundPassiveSkills.add(skill);
else
boundPassiveSkills.set(slot, skill);
boundPassiveSkills.get(slot).register(getMMOPlayerData());
final int maxBound = getProfess().getMaxBoundActiveSkills();
if (slot > 0 && boundPassiveSkills.size() >= maxBound) {
final @NotNull PassiveSkill current = boundPassiveSkills.set(slot, skill);
if (current != null)
current.unregister(mmoData);
skill.register(mmoData);
return;
}
boundPassiveSkills.add(skill);
skill.register(mmoData);
}
public boolean hasPassiveSkillBound(int slot) {
return slot < boundPassiveSkills.size();
}
@Nullable
public PassiveSkill getBoundPassiveSkill(int slot) {
return slot >= boundPassiveSkills.size() ? null : boundPassiveSkills.get(slot);
}
public void addPassiveBoundSkill(PassiveSkill skill) {
boundPassiveSkills.add(skill);
skill.register(getMMOPlayerData());
@Deprecated
public void setBoundSkill(int slot, ClassSkill skill) {
bindActiveSkill(slot, skill);
}
public void setBoundSkill(int slot, ClassSkill skill) {
/**
* Binds a skill to the player.
*
* @param slot Slot to which you're binding the skill.
* Use -1 to force-register the skill
* @param skill Skill being bound
*/
public void bindActiveSkill(int slot, ClassSkill skill) {
Validate.notNull(skill, "Skill cannot be null");
if (boundSkills.size() < getProfess().getMaxBoundActiveSkills())
boundSkills.add(skill);
else
if (slot > 0 && boundSkills.size() >= getProfess().getMaxBoundActiveSkills())
boundSkills.set(slot, skill);
else
boundSkills.add(skill);
}
public void unbindSkill(int slot) {
@ -1155,7 +1160,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
PassiveSkill skill = boundPassiveSkills.get(slot);
skill.unregister(getMMOPlayerData());
boundPassiveSkills.remove(slot);
}
public List<ClassSkill> getBoundSkills() {

View File

@ -25,7 +25,7 @@ public class SkillTreeCommand extends BukkitCommand {
if (!(sender instanceof Player player))
return false;
PlayerData data = PlayerData.get(player);
MMOCommandEvent event = new MMOCommandEvent(data, "skilltree");
MMOCommandEvent event = new MMOCommandEvent(data, "skilltrees");
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled())
return true;

View File

@ -100,7 +100,7 @@ public class PlayerProfessions {
for (Entry<String, JsonElement> entry : obj.getAsJsonObject("timesClaimed").entrySet())
playerData.getItemClaims().put("profession." + entry.getKey(), entry.getValue().getAsInt());
if (!playerData.isStatLoaded())
if (!playerData.areStatsLoaded())
for (Profession profession : MMOCore.plugin.professionManager.getAll()) {
if (profession.hasExperienceTable())
profession.getExperienceTable().claimStatTriggers(playerData, profession);

View File

@ -358,16 +358,6 @@ public class SkillList extends EditableInventory {
@Override
public void whenClicked(InventoryClickContext context, InventoryItem item) {
/*
if (skillSlots.contains(event.getRawSlot())
&& event.getRawSlot() != ((SkillItem) getEditable().getByFunction("skill")).selectedSkillSlot) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
playerData.skillGuiDisplayOffset = (playerData.skillGuiDisplayOffset + (event.getRawSlot() - 13)) % skills.size();
open();
return;
}
*/
if (item.getFunction().equals("skill")) {
int index = skillSlots.size() * page + skillSlots.indexOf(context.getSlot());
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
@ -377,8 +367,6 @@ public class SkillList extends EditableInventory {
}
if (item.getFunction().equals("reallocation")) {
int spent = getPlayerData().countSkillPointsWhenReallocate();
if (spent < 1) {
@ -455,7 +443,7 @@ public class SkillList extends EditableInventory {
}
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.setBoundPassiveSkill(index, selected.toPassive(playerData));
playerData.bindPassiveSkill(index, selected.toPassive(playerData));
open();
return;
}
@ -497,7 +485,7 @@ public class SkillList extends EditableInventory {
}
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.setBoundSkill(index, selected);
playerData.bindActiveSkill(index, selected);
open();
return;
}

View File

@ -4,26 +4,31 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class InventoryClickContext {
private final int slot;
private final ItemStack itemStack;
@Nullable
private final ItemStack currentItem;
@NotNull
private final ClickType clickType;
@NotNull
private final Cancellable event;
private Inventory inv;
public InventoryClickContext(int slot, ItemStack itemStack, ClickType clickType, Cancellable event) {
this.slot = slot;
this.itemStack = itemStack;
this.clickType = clickType;
this.event = event;
@Nullable
private final Inventory inv;
public InventoryClickContext(int slot, ItemStack currentItem, ClickType clickType, Cancellable event) {
this(slot, currentItem, clickType, event, null);
}
public InventoryClickContext(int slot, ItemStack itemStack, ClickType clickType, Cancellable event, Inventory inv) {
public InventoryClickContext(int slot, ItemStack currentItem, ClickType clickType, Cancellable event, Inventory inv) {
this.slot = slot;
this.itemStack = itemStack;
this.currentItem = currentItem;
this.clickType = clickType;
this.event = event;
this.inv = inv;
@ -48,13 +53,15 @@ public class InventoryClickContext {
*/
@Nullable
public ItemStack getClickedItem() {
return itemStack;
return currentItem;
}
@NotNull
public Cancellable getEvent() {
return event;
}
@Nullable
public Inventory getInventory() {
return inv;
}
@ -63,6 +70,7 @@ public class InventoryClickContext {
return inv != null;
}
@NotNull
public ClickType getClickType() {
return clickType;
}

View File

@ -76,12 +76,12 @@ public class ConfigManager {
loadDefaultFile("expcurves", "mining.txt");
}
if(!new File(MMOCore.plugin.getDataFolder()+"/skilltree").exists()) {
loadDefaultFile("skilltree","combat.yml");
loadDefaultFile("skilltree","mage-arcane-mage.yml");
loadDefaultFile("skilltree","rogue-marksman.yml");
loadDefaultFile("skilltree","warrior-paladin.yml");
loadDefaultFile("skilltree","general.yml");
if(!new File(MMOCore.plugin.getDataFolder()+"/skill-trees").exists()) {
loadDefaultFile("skill-trees","combat.yml");
loadDefaultFile("skill-trees","mage-arcane-mage.yml");
loadDefaultFile("skill-trees","rogue-marksman.yml");
loadDefaultFile("skill-trees","warrior-paladin.yml");
loadDefaultFile("skill-trees","general.yml");
}

View File

@ -57,7 +57,7 @@ public class SkillTreeManager extends MMOCoreRegister<SkillTree> {
public void initialize(boolean clearBefore) {
if (clearBefore)
registered.clear();
File file = new File(MMOCore.plugin.getDataFolder() + "/skilltree");
File file = new File(MMOCore.plugin.getDataFolder() + "/skill-trees");
if (!file.exists())
file.mkdirs();
load(file);

View File

@ -121,7 +121,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
if (data.getProfess().hasSkill(id)) {
ClassSkill skill = data.getProfess().getSkill(id);
if (skill.getSkill().getTrigger().isPassive())
data.addPassiveBoundSkill(skill.toPassive(data));
data.bindPassiveSkill(-1, skill.toPassive(data));
else
data.getBoundSkills().add(skill);
}

View File

@ -70,7 +70,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
if (data.getProfess().hasSkill(id)) {
ClassSkill skill = data.getProfess().getSkill(id);
if (skill.getSkill().getTrigger().isPassive())
data.addPassiveBoundSkill(skill.toPassive(data));
data.bindPassiveSkill(-1, skill.toPassive(data));
else
data.getBoundSkills().add(skill);

View File

@ -5,14 +5,12 @@ import io.lumine.mythic.lib.player.cooldown.CooldownObject;
import io.lumine.mythic.lib.player.modifier.ModifierSource;
import io.lumine.mythic.lib.player.skill.PassiveSkill;
import io.lumine.mythic.lib.script.condition.Condition;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.gui.api.item.Placeholders;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.*;
@ -121,10 +119,9 @@ public class ClassSkill implements CooldownObject {
/**
* Be careful, this method creates a new UUID each time it is called. Need to be remembered when trying to unregister passive skill
* from PassiveSkillMap.
*
* @return
* Be careful, this method creates a new UUID each time it
* is called. It needs to be saved somewhere when trying to
* unregister the passive skill from the skill map later on.
*/
public PassiveSkill toPassive(PlayerData caster) {
Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active");

View File

@ -33,7 +33,7 @@ public class ComboMap {
Validate.isTrue(spellSlot >= 0, "Spell slot must be at least 0");
Validate.isTrue(!combos.values().contains(spellSlot), "There is already a key combo with the same skill slot");
KeyCombo combo = new KeyCombo();
for (String str : config.getStringList("combos." + key))
for (String str : config.getStringList(key))
combo.registerKey(PlayerKey.valueOf(UtilityMethods.enumName(str)));
combos.put(combo, spellSlot);

View File

@ -40,7 +40,7 @@ public abstract class SkillCastingHandler extends BukkitRunnable implements List
@Override
public void run() {
if (!caster.isOnline() || caster.getPlayer().isDead())
caster.leaveCastingMode();
caster.leaveSkillCasting();
else {
// Apply casting particles

View File

@ -19,6 +19,7 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.*;
@ -80,7 +81,7 @@ public class KeyCombos implements Listener {
return;
}
CustomSkillCastingHandler casting = null;
@Nullable CustomSkillCastingHandler casting = null;
// Player is already casting
if (event.getData().isCasting())
@ -88,7 +89,7 @@ public class KeyCombos implements Listener {
// Start combo when there is NO initializer key
else {
final ComboMap comboMap = Objects.requireNonNullElse(playerData.getProfess().getComboMap(), this.comboMap);
final @NotNull ComboMap comboMap = Objects.requireNonNullElse(playerData.getProfess().getComboMap(), this.comboMap);
if (comboMap.isComboStart(event.getPressed())) {
casting = new CustomSkillCastingHandler(playerData);
playerData.setSkillCasting(casting);
@ -113,7 +114,7 @@ public class KeyCombos implements Listener {
// Hash current combo and check
if (casting.combos.getCombos().containsKey(casting.current)) {
final int spellSlot = casting.combos.getCombos().get(casting.current) - 1;
playerData.leaveCastingMode();
playerData.leaveSkillCasting();
// Cast spell
if (playerData.hasSkillBound(spellSlot)) {
@ -125,7 +126,7 @@ public class KeyCombos implements Listener {
// Check if current combo is too large
if (casting.current.countKeys() >= casting.combos.getLongest()) {
playerData.leaveCastingMode();
playerData.leaveSkillCasting();
if (failComboSound != null)
failComboSound.playTo(player);
}

View File

@ -5,12 +5,10 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot;
import io.lumine.mythic.lib.player.PlayerMetadata;
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.event.PlayerKeyPressEvent;
import net.Indyuce.mmocore.api.SoundEvent;
import net.Indyuce.mmocore.loot.chest.particle.CastingParticle;
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.PlayerKey;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
import org.bukkit.GameMode;
@ -25,9 +23,11 @@ import java.util.Objects;
public class SkillBar implements Listener {
private final PlayerKey mainKey;
private final boolean disableSneak;
public SkillBar(ConfigurationSection config) {
mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key")));
disableSneak = config.getBoolean("disable-sneak");
}
@EventHandler
@ -62,10 +62,13 @@ public class SkillBar implements Listener {
@EventHandler
public void onSkillCast(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
if (!getCaster().isOnline()) return;
if (!event.getPlayer().equals(getCaster().getPlayer())) return;
if (!getCaster().isOnline()) {
getCaster().leaveSkillCasting();
return;
}
/*
* When the event is cancelled, another playerItemHeldEvent is
* called and previous and next slots are equal. the event must not
@ -73,8 +76,9 @@ public class SkillBar implements Listener {
*/
if (event.getPreviousSlot() == event.getNewSlot()) return;
//If the player is sneaking, we don't trigger the casting mode (used to avoid conflicts with other plugins using shift+F to open GUI.
if(player.isSneaking()) return;
// Extra option to improve support with other plugins
final Player player = event.getPlayer();
if (disableSneak && player.isSneaking()) return;
event.setCancelled(true);
int slot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0);
@ -86,8 +90,8 @@ public class SkillBar implements Listener {
*/
if (slot >= 0 && getCaster().hasSkillBound(slot)) {
PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
int delay= getCaster().getBoundSkill(slot).getDelay(getCaster());
getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null),delay);
int delay = getCaster().getBoundSkill(slot).getDelay(getCaster());
getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null), delay);
}
}
@ -103,7 +107,7 @@ public class SkillBar implements Listener {
MMOCore.plugin.configManager.getSimpleMessage("casting.no-longer").send(getCaster().getPlayer());
}
}.runTask(MMOCore.plugin);
PlayerData.get(player).leaveCastingMode();
getCaster().leaveSkillCasting();
}
}
@ -115,7 +119,7 @@ public class SkillBar implements Listener {
str.append((str.length() == 0) ? "" : split).append((onCooldown(data, skill) ? onCooldown.replace("{cooldown}",
String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina(
data, skill) ? noStamina : ready)).replace("{index}",
"" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0)))
"" + (j + 1 + (data.getPlayer().getInventory().getHeldItemSlot() <= j ? 1 : 0)))
.replace("{skill}", data.getBoundSkill(j).getSkill().getName()));
}
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString());

View File

@ -54,7 +54,7 @@ public class SkillScroller implements Listener {
if (event.getPressed().shouldCancelEvent())
event.setCancelled(true);
playerData.leaveCastingMode();
playerData.leaveSkillCasting();
if (leaveSound != null)
leaveSound.playTo(player);
return;
@ -94,7 +94,7 @@ public class SkillScroller implements Listener {
return;
if (playerData.getBoundSkills().isEmpty()) {
playerData.leaveCastingMode();
playerData.leaveSkillCasting();
return;
}

View File

@ -11,8 +11,8 @@ import io.lumine.mythic.lib.skill.result.def.SimpleSkillResult;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.util.EntityLocationType;
import io.lumine.mythic.lib.util.ParabolicProjectile;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
@ -45,7 +45,7 @@ public class Ambers extends SkillHandler<SimpleSkillResult> implements Listener
@EventHandler
public void spawnAmber(PlayerAttackEvent event) {
MMOPlayerData data = event.getData();
MMOPlayerData data = event.getAttacker().getData();
if (!event.getAttack().getDamage().hasType(DamageType.SKILL))
return;
@ -53,7 +53,7 @@ public class Ambers extends SkillHandler<SimpleSkillResult> implements Listener
if (passive == null)
return;
passive.getTriggeredSkill().cast(new TriggerMetadata(event.getAttack(), event.getEntity()));
passive.getTriggeredSkill().cast(new TriggerMetadata(event.getAttacker(), event.getAttack(), event.getEntity()));
}
public static class Amber extends BukkitRunnable {

View File

@ -37,7 +37,7 @@ public class Sneaky_Picky extends SkillHandler<SimpleSkillResult> implements Lis
@EventHandler
public void a(PlayerAttackEvent event) {
MMOPlayerData data = event.getData();
MMOPlayerData data = event.getAttacker().getData();
if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || PlayerData.get(data.getUniqueId()).isInCombat())
return;
@ -45,6 +45,6 @@ public class Sneaky_Picky extends SkillHandler<SimpleSkillResult> implements Lis
if (skill == null)
return;
skill.getTriggeredSkill().cast(new TriggerMetadata(event.getAttack(), event.getEntity()));
skill.getTriggeredSkill().cast(new TriggerMetadata(event.getAttacker(), event.getAttack(), event.getEntity()));
}
}

View File

@ -1,6 +1,24 @@
package net.Indyuce.mmocore.tree;
public enum NodeState {
LOCKED,UNLOCKED,UNLOCKABLE,FULLY_LOCKED;
/**
* The player does not have access to this skill tree node just yet.
*/
LOCKED,
/**
* The player has bought and unlocked the skill tree node.
*/
UNLOCKED,
/**
* The player has access to but has not unlocked the node yet.
*/
UNLOCKABLE,
/**
* The player had access to this node, but unlocked another
* node which now prevents him from unlocking this one.
*/
FULLY_LOCKED;
}

View File

@ -5,12 +5,12 @@ import io.lumine.mythic.lib.UtilityMethods;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.tree.NodeState;
import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo;
import net.Indyuce.mmocore.manager.registry.RegisteredObject;
import net.Indyuce.mmocore.tree.skilltree.display.Icon;
import net.Indyuce.mmocore.tree.IntegerCoordinates;
import net.Indyuce.mmocore.tree.NodeState;
import net.Indyuce.mmocore.tree.SkillTreeNode;
import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo;
import net.Indyuce.mmocore.tree.skilltree.display.Icon;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@ -32,7 +32,6 @@ import java.util.logging.Level;
* - extra attribute pts
* - particle or potion effects
*
* @author jules
* @author Ka0rX
* @see {@link SkillTreeNode}
*/
@ -61,7 +60,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
Objects.requireNonNull(config.getStringList("lore"), "Could not find skill tree lore").forEach(str -> lore.add(MythicLib.plugin.parseColors(str)));
this.item = Material.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("item"))));
Validate.isTrue(config.isConfigurationSection("nodes"), "Could not find any nodes in the tree");
this.maxPointSpent =config.getInt("max-point-spent",Integer.MAX_VALUE);
this.maxPointSpent = config.getInt("max-point-spent", Integer.MAX_VALUE);
for (String key : config.getConfigurationSection("nodes").getKeys(false)) {
try {
@ -69,7 +68,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
nodes.put(node.getId(), node);
} catch (Exception e) {
MMOCore.log( "Couldn't load skill tree node " + id + "." + key + ": " + e.getMessage());
MMOCore.log("Couldn't load skill tree node " + id + "." + key + ": " + e.getMessage());
}
}
try {
@ -86,7 +85,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
MMOCore.log(Level.WARNING, "Couldn't load paths for skill tree: " + id);
}
try {
//Load the icons of the skill tree.
for (String key : config.getConfigurationSection("icons").getKeys(false)) {
@ -102,7 +100,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
}
}
} catch (Exception e) {
MMOCore.log( "Couldn't load icons for the skill tree " + id);
MMOCore.log("Couldn't load icons for the skill tree " + id);
e.printStackTrace();
}
}
@ -118,7 +116,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
}
}
@Override
protected abstract void whenPostLoaded(@NotNull ConfigurationSection configurationSection);
@ -178,7 +175,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
roots.add(node);
}
/**
* Recursively go through the skill trees to update the the node states
*/
@ -187,7 +183,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
setupNodeStateFrom(root, playerData);
}
public List<SkillTreeNode> getRoots() {
return roots;
}
@ -292,6 +287,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
public SkillTreeNode getNode(String name) {
return Objects.requireNonNull(nodes.get(name), "Could not find node in tree '" + id + "' with name '" + name + "'");
}
public boolean isNode(String name) {
return nodes.containsKey(name);
}

View File

@ -1,6 +1,7 @@
package net.Indyuce.mmocore.listener;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
@ -8,12 +9,9 @@ import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
import net.Indyuce.mmocore.gui.api.InventoryClickContext;
import net.Indyuce.mmocore.gui.api.PluginInventory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.inventory.InventoryClickEvent;
@ -39,9 +37,8 @@ public class PlayerListener implements Listener {
*/
@EventHandler
public void b(InventoryClickEvent event) {
if (event.getInventory().getHolder() instanceof PluginInventory&&event.getCurrentItem()!=null)
((PluginInventory) event.getInventory().getHolder())
.whenClicked(new InventoryClickContext(event.getRawSlot(), event.getCurrentItem(), event.getClick(), event, event.getInventory()));
if (event.getInventory().getHolder() instanceof PluginInventory)
((PluginInventory) event.getInventory().getHolder()).whenClicked(new InventoryClickContext(event.getRawSlot(), event.getCurrentItem(), event.getClick(), event, event.getInventory()));
}
/**
@ -57,17 +54,9 @@ public class PlayerListener implements Listener {
* Updates the player's combat log data every time he hits an entity, or
* gets hit by an entity or a projectile sent by another entity
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void d(EntityDamageByEntityEvent event) {
if (event.getEntity() instanceof Player && !event.getEntity().hasMetadata("NPC"))
PlayerData.get((Player) event.getEntity()).updateCombat();
if (event.getDamager() instanceof Player && !event.getDamager().hasMetadata("NPC"))
PlayerData.get((Player) event.getDamager()).updateCombat();
if (event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof Player)
if (!((Player) ((Projectile) event.getDamager()).getShooter()).hasMetadata("NPC"))
PlayerData.get((Player) ((Projectile) event.getDamager()).getShooter()).updateCombat();
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void d(PlayerAttackEvent event) {
PlayerData.get(event.getAttacker().getPlayer()).updateCombat();
}
@EventHandler

View File

@ -9,10 +9,7 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils;
import net.Indyuce.mmocore.loot.LootBuilder;
import net.Indyuce.mmocore.loot.fishing.FishingDropItem;
import net.Indyuce.mmocore.manager.profession.FishingManager.FishingDropTable;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.*;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
@ -183,6 +180,9 @@ public class FishingListener implements Listener {
if (called.isCancelled())
return;
// Increase player statistic
player.incrementStatistic(Statistic.FISH_CAUGHT);
// Calculate yeet velocity
Item item = hook.getWorld().dropItemNaturally(hook.getLocation(), collect);
MMOCoreUtils.displayIndicator(location.add(0, 1.25, 0),

View File

@ -28,8 +28,8 @@ guild:
withdraw:
main: "withdraw"
aliases: ["w"]
skill-tree:
main: "skilltree"
skill-trees:
main: "skilltrees"
aliase: ["st"]
deposit:
main: "deposit"

View File

@ -22,7 +22,8 @@ exp-sources: {}
on-fish:
overriding-drop-table:
conditions:
- 'biome{name=swamp}'
- 'region{name=swamp,second-region}'
- 'biome{name=beach}'
# When drop table is read, one of these
# items will be selected randomly.
@ -30,15 +31,16 @@ on-fish:
# Tugs needed: 4 to 5
# Fishing EXP earned: 1 to 6
- 'mmoitem{type=CONSUMABLE;id=SUSHI_ROLL;tugs=30-40;experience=1-6}'
- 'mmoitem{type=CONSUMABLE;id=SUSHI_ROLL;tugs=4-5;experience=1-6} 1 1-1 9'
# Tugs needed: 10 to 20
# Fishing EXP earned: 20 to 30
- 'mmoitem{type=GEM_STONE;id=SPITEFUL_OPAQUE_DIAMOND;tugs=10-15;experience=20-30}'
- 'mmoitem{type=GEM_STONE;id=SPITEFUL_OPAQUE_DIAMOND;tugs=10-15;experience=20-30} 1 1-1 1'
# Default drop table which always apply.
# When removing every drop table, the vanilla
# fishing mecanism is back.
default:
items:
- 'vanilla{type=SALMON;tugs=4-5;experience=1-6}'
- 'vanilla{type=SALMON;tugs=4-5;experience=1-6} 1 2-5 1'