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> <dependency>
<groupId>net.citizensnpcs</groupId> <groupId>net.citizensnpcs</groupId>
<artifactId>Citizens</artifactId> <artifactId>Citizens</artifactId>
<version>2.0.25</version> <version>2.0.30</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>

View File

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

View File

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

View File

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

View File

@ -358,16 +358,6 @@ public class SkillList extends EditableInventory {
@Override @Override
public void whenClicked(InventoryClickContext context, InventoryItem item) { 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")) { if (item.getFunction().equals("skill")) {
int index = skillSlots.size() * page + skillSlots.indexOf(context.getSlot()); int index = skillSlots.size() * page + skillSlots.indexOf(context.getSlot());
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2); player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 2);
@ -377,8 +367,6 @@ public class SkillList extends EditableInventory {
} }
if (item.getFunction().equals("reallocation")) { if (item.getFunction().equals("reallocation")) {
int spent = getPlayerData().countSkillPointsWhenReallocate(); int spent = getPlayerData().countSkillPointsWhenReallocate();
if (spent < 1) { if (spent < 1) {
@ -455,7 +443,7 @@ public class SkillList extends EditableInventory {
} }
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.setBoundPassiveSkill(index, selected.toPassive(playerData)); playerData.bindPassiveSkill(index, selected.toPassive(playerData));
open(); open();
return; return;
} }
@ -497,7 +485,7 @@ public class SkillList extends EditableInventory {
} }
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2); player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 2);
playerData.setBoundSkill(index, selected); playerData.bindActiveSkill(index, selected);
open(); open();
return; return;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -70,7 +70,7 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
if (data.getProfess().hasSkill(id)) { if (data.getProfess().hasSkill(id)) {
ClassSkill skill = data.getProfess().getSkill(id); ClassSkill skill = data.getProfess().getSkill(id);
if (skill.getSkill().getTrigger().isPassive()) if (skill.getSkill().getTrigger().isPassive())
data.addPassiveBoundSkill(skill.toPassive(data)); data.bindPassiveSkill(-1, skill.toPassive(data));
else else
data.getBoundSkills().add(skill); 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.modifier.ModifierSource;
import io.lumine.mythic.lib.player.skill.PassiveSkill; import io.lumine.mythic.lib.player.skill.PassiveSkill;
import io.lumine.mythic.lib.script.condition.Condition; 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.player.PlayerData;
import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue; import net.Indyuce.mmocore.api.util.math.formula.IntegerLinearValue;
import net.Indyuce.mmocore.api.util.math.formula.LinearValue; import net.Indyuce.mmocore.api.util.math.formula.LinearValue;
import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.Placeholders;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.*; 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 * Be careful, this method creates a new UUID each time it
* from PassiveSkillMap. * is called. It needs to be saved somewhere when trying to
* * unregister the passive skill from the skill map later on.
* @return
*/ */
public PassiveSkill toPassive(PlayerData caster) { public PassiveSkill toPassive(PlayerData caster) {
Validate.isTrue(skill.getTrigger().isPassive(), "Skill is active"); 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(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"); Validate.isTrue(!combos.values().contains(spellSlot), "There is already a key combo with the same skill slot");
KeyCombo combo = new KeyCombo(); KeyCombo combo = new KeyCombo();
for (String str : config.getStringList("combos." + key)) for (String str : config.getStringList(key))
combo.registerKey(PlayerKey.valueOf(UtilityMethods.enumName(str))); combo.registerKey(PlayerKey.valueOf(UtilityMethods.enumName(str)));
combos.put(combo, spellSlot); combos.put(combo, spellSlot);

View File

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

View File

@ -19,6 +19,7 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.*;
@ -80,7 +81,7 @@ public class KeyCombos implements Listener {
return; return;
} }
CustomSkillCastingHandler casting = null; @Nullable CustomSkillCastingHandler casting = null;
// Player is already casting // Player is already casting
if (event.getData().isCasting()) if (event.getData().isCasting())
@ -88,7 +89,7 @@ public class KeyCombos implements Listener {
// Start combo when there is NO initializer key // Start combo when there is NO initializer key
else { 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())) { if (comboMap.isComboStart(event.getPressed())) {
casting = new CustomSkillCastingHandler(playerData); casting = new CustomSkillCastingHandler(playerData);
playerData.setSkillCasting(casting); playerData.setSkillCasting(casting);
@ -113,7 +114,7 @@ public class KeyCombos implements Listener {
// Hash current combo and check // Hash current combo and check
if (casting.combos.getCombos().containsKey(casting.current)) { if (casting.combos.getCombos().containsKey(casting.current)) {
final int spellSlot = casting.combos.getCombos().get(casting.current) - 1; final int spellSlot = casting.combos.getCombos().get(casting.current) - 1;
playerData.leaveCastingMode(); playerData.leaveSkillCasting();
// Cast spell // Cast spell
if (playerData.hasSkillBound(spellSlot)) { if (playerData.hasSkillBound(spellSlot)) {
@ -125,7 +126,7 @@ public class KeyCombos implements Listener {
// Check if current combo is too large // Check if current combo is too large
if (casting.current.countKeys() >= casting.combos.getLongest()) { if (casting.current.countKeys() >= casting.combos.getLongest()) {
playerData.leaveCastingMode(); playerData.leaveSkillCasting();
if (failComboSound != null) if (failComboSound != null)
failComboSound.playTo(player); 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.player.PlayerMetadata;
import io.lumine.mythic.lib.skill.trigger.TriggerMetadata; import io.lumine.mythic.lib.skill.trigger.TriggerMetadata;
import net.Indyuce.mmocore.MMOCore; 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.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.ClassSkill;
import net.Indyuce.mmocore.skill.RegisteredSkill;
import net.Indyuce.mmocore.skill.cast.PlayerKey; import net.Indyuce.mmocore.skill.cast.PlayerKey;
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler; import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -25,9 +23,11 @@ import java.util.Objects;
public class SkillBar implements Listener { public class SkillBar implements Listener {
private final PlayerKey mainKey; private final PlayerKey mainKey;
private final boolean disableSneak;
public SkillBar(ConfigurationSection config) { public SkillBar(ConfigurationSection config) {
mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key"))); mainKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("open"), "Could not find open key")));
disableSneak = config.getBoolean("disable-sneak");
} }
@EventHandler @EventHandler
@ -62,10 +62,13 @@ public class SkillBar implements Listener {
@EventHandler @EventHandler
public void onSkillCast(PlayerItemHeldEvent event) { public void onSkillCast(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
if (!getCaster().isOnline()) return;
if (!event.getPlayer().equals(getCaster().getPlayer())) return; if (!event.getPlayer().equals(getCaster().getPlayer())) return;
if (!getCaster().isOnline()) {
getCaster().leaveSkillCasting();
return;
}
/* /*
* When the event is cancelled, another playerItemHeldEvent is * When the event is cancelled, another playerItemHeldEvent is
* called and previous and next slots are equal. the event must not * 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 (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. // Extra option to improve support with other plugins
if(player.isSneaking()) return; final Player player = event.getPlayer();
if (disableSneak && player.isSneaking()) return;
event.setCancelled(true); event.setCancelled(true);
int slot = event.getNewSlot() + (event.getNewSlot() >= player.getInventory().getHeldItemSlot() ? -1 : 0); 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)) { if (slot >= 0 && getCaster().hasSkillBound(slot)) {
PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND); PlayerMetadata caster = getCaster().getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
int delay= getCaster().getBoundSkill(slot).getDelay(getCaster()); int delay = getCaster().getBoundSkill(slot).getDelay(getCaster());
getCaster().getBoundSkill(slot).toCastable(getCaster()).cast(new TriggerMetadata(caster, null, null),delay); 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()); MMOCore.plugin.configManager.getSimpleMessage("casting.no-longer").send(getCaster().getPlayer());
} }
}.runTask(MMOCore.plugin); }.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}", 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( String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina(
data, skill) ? noStamina : ready)).replace("{index}", 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())); .replace("{skill}", data.getBoundSkill(j).getSkill().getName()));
} }
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString()); return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString());

View File

@ -54,7 +54,7 @@ public class SkillScroller implements Listener {
if (event.getPressed().shouldCancelEvent()) if (event.getPressed().shouldCancelEvent())
event.setCancelled(true); event.setCancelled(true);
playerData.leaveCastingMode(); playerData.leaveSkillCasting();
if (leaveSound != null) if (leaveSound != null)
leaveSound.playTo(player); leaveSound.playTo(player);
return; return;
@ -94,7 +94,7 @@ public class SkillScroller implements Listener {
return; return;
if (playerData.getBoundSkills().isEmpty()) { if (playerData.getBoundSkills().isEmpty()) {
playerData.leaveCastingMode(); playerData.leaveSkillCasting();
return; 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.skill.trigger.TriggerMetadata;
import io.lumine.mythic.lib.util.EntityLocationType; import io.lumine.mythic.lib.util.EntityLocationType;
import io.lumine.mythic.lib.util.ParabolicProjectile; 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.event.PlayerResourceUpdateEvent;
import net.Indyuce.mmocore.api.player.PlayerData;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Particle; import org.bukkit.Particle;
@ -45,7 +45,7 @@ public class Ambers extends SkillHandler<SimpleSkillResult> implements Listener
@EventHandler @EventHandler
public void spawnAmber(PlayerAttackEvent event) { public void spawnAmber(PlayerAttackEvent event) {
MMOPlayerData data = event.getData(); MMOPlayerData data = event.getAttacker().getData();
if (!event.getAttack().getDamage().hasType(DamageType.SKILL)) if (!event.getAttack().getDamage().hasType(DamageType.SKILL))
return; return;
@ -53,7 +53,7 @@ public class Ambers extends SkillHandler<SimpleSkillResult> implements Listener
if (passive == null) if (passive == null)
return; 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 { public static class Amber extends BukkitRunnable {

View File

@ -37,7 +37,7 @@ public class Sneaky_Picky extends SkillHandler<SimpleSkillResult> implements Lis
@EventHandler @EventHandler
public void a(PlayerAttackEvent event) { 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()) if (!event.getAttack().getDamage().hasType(DamageType.WEAPON) || PlayerData.get(data.getUniqueId()).isInCombat())
return; return;
@ -45,6 +45,6 @@ public class Sneaky_Picky extends SkillHandler<SimpleSkillResult> implements Lis
if (skill == null) if (skill == null)
return; 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; package net.Indyuce.mmocore.tree;
public enum NodeState { 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 io.lumine.mythic.lib.api.util.PostLoadObject;
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.tree.NodeState;
import net.Indyuce.mmocore.tree.skilltree.display.DisplayInfo;
import net.Indyuce.mmocore.manager.registry.RegisteredObject; 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.IntegerCoordinates;
import net.Indyuce.mmocore.tree.NodeState;
import net.Indyuce.mmocore.tree.SkillTreeNode; 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.apache.commons.lang.Validate;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -32,7 +32,6 @@ import java.util.logging.Level;
* - extra attribute pts * - extra attribute pts
* - particle or potion effects * - particle or potion effects
* *
* @author jules
* @author Ka0rX * @author Ka0rX
* @see {@link SkillTreeNode} * @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))); 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")))); this.item = Material.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("item"))));
Validate.isTrue(config.isConfigurationSection("nodes"), "Could not find any nodes in the tree"); 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)) { for (String key : config.getConfigurationSection("nodes").getKeys(false)) {
try { try {
@ -69,7 +68,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
nodes.put(node.getId(), node); nodes.put(node.getId(), node);
} catch (Exception e) { } 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 { 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); MMOCore.log(Level.WARNING, "Couldn't load paths for skill tree: " + id);
} }
try { try {
//Load the icons of the skill tree. //Load the icons of the skill tree.
for (String key : config.getConfigurationSection("icons").getKeys(false)) { for (String key : config.getConfigurationSection("icons").getKeys(false)) {
@ -102,7 +100,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
} }
} }
} catch (Exception e) { } 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(); e.printStackTrace();
} }
} }
@ -118,7 +116,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
} }
} }
@Override @Override
protected abstract void whenPostLoaded(@NotNull ConfigurationSection configurationSection); protected abstract void whenPostLoaded(@NotNull ConfigurationSection configurationSection);
@ -178,7 +175,6 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
roots.add(node); roots.add(node);
} }
/** /**
* Recursively go through the skill trees to update the the node states * 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); setupNodeStateFrom(root, playerData);
} }
public List<SkillTreeNode> getRoots() { public List<SkillTreeNode> getRoots() {
return roots; return roots;
} }
@ -292,6 +287,7 @@ public abstract class SkillTree extends PostLoadObject implements RegisteredObje
public SkillTreeNode getNode(String name) { public SkillTreeNode getNode(String name) {
return Objects.requireNonNull(nodes.get(name), "Could not find node in tree '" + id + "' with name '" + name + "'"); return Objects.requireNonNull(nodes.get(name), "Could not find node in tree '" + id + "' with name '" + name + "'");
} }
public boolean isNode(String name) { public boolean isNode(String name) {
return nodes.containsKey(name); return nodes.containsKey(name);
} }

View File

@ -1,6 +1,7 @@
package net.Indyuce.mmocore.listener; package net.Indyuce.mmocore.listener;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
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.PlayerData; 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.InventoryClickContext;
import net.Indyuce.mmocore.gui.api.PluginInventory; import net.Indyuce.mmocore.gui.api.PluginInventory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
@ -39,9 +37,8 @@ public class PlayerListener implements Listener {
*/ */
@EventHandler @EventHandler
public void b(InventoryClickEvent event) { public void b(InventoryClickEvent event) {
if (event.getInventory().getHolder() instanceof PluginInventory&&event.getCurrentItem()!=null) if (event.getInventory().getHolder() instanceof PluginInventory)
((PluginInventory) event.getInventory().getHolder()) ((PluginInventory) event.getInventory().getHolder()).whenClicked(new InventoryClickContext(event.getRawSlot(), event.getCurrentItem(), event.getClick(), event, event.getInventory()));
.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 * 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 * gets hit by an entity or a projectile sent by another entity
*/ */
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void d(EntityDamageByEntityEvent event) { public void d(PlayerAttackEvent event) {
if (event.getEntity() instanceof Player && !event.getEntity().hasMetadata("NPC")) PlayerData.get(event.getAttacker().getPlayer()).updateCombat();
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 @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.LootBuilder;
import net.Indyuce.mmocore.loot.fishing.FishingDropItem; import net.Indyuce.mmocore.loot.fishing.FishingDropItem;
import net.Indyuce.mmocore.manager.profession.FishingManager.FishingDropTable; import net.Indyuce.mmocore.manager.profession.FishingManager.FishingDropTable;
import org.bukkit.Bukkit; import org.bukkit.*;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.entity.FishHook; import org.bukkit.entity.FishHook;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -183,6 +180,9 @@ public class FishingListener implements Listener {
if (called.isCancelled()) if (called.isCancelled())
return; return;
// Increase player statistic
player.incrementStatistic(Statistic.FISH_CAUGHT);
// Calculate yeet velocity // Calculate yeet velocity
Item item = hook.getWorld().dropItemNaturally(hook.getLocation(), collect); Item item = hook.getWorld().dropItemNaturally(hook.getLocation(), collect);
MMOCoreUtils.displayIndicator(location.add(0, 1.25, 0), MMOCoreUtils.displayIndicator(location.add(0, 1.25, 0),

View File

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

View File

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