Fixed additive attack speed

This commit is contained in:
Indyuce 2020-12-27 19:11:43 +01:00
parent 1ae4262e75
commit 79f9265118
24 changed files with 379 additions and 208 deletions

View File

@ -29,6 +29,7 @@ import net.Indyuce.mmoitems.command.completion.UpdateItemCompletion;
import net.Indyuce.mmoitems.comp.AdvancedEnchantmentsHook;
import net.Indyuce.mmoitems.comp.MMOItemsMetrics;
import net.Indyuce.mmoitems.comp.MMOItemsRewardTypes;
import net.Indyuce.mmoitems.comp.McMMONonRPGHook;
import net.Indyuce.mmoitems.comp.RealDualWieldHook;
import net.Indyuce.mmoitems.comp.WorldEditSupport;
import net.Indyuce.mmoitems.comp.eco.VaultSupport;
@ -155,6 +156,9 @@ public class MMOItems extends JavaPlugin {
if (Bukkit.getPluginManager().getPlugin("MMOCore") != null)
new MMOCoreMMOLoader();
if (Bukkit.getPluginManager().getPlugin("mcMMO") != null)
statManager.register(McMMOHook.disableMcMMORepair);
}
public void onEnable() {
@ -232,17 +236,17 @@ public class MMOItems extends JavaPlugin {
*/
Bukkit.getScheduler().runTaskTimer(this, () -> {
for (Player player : Bukkit.getOnlinePlayers())
PlayerData.get(player).checkForInventoryUpdate();
PlayerData.get(player).getInventory().updateCheck();
}, 100, getConfig().getInt("inventory-update-delay"));
if (Bukkit.getPluginManager().getPlugin("mcMMO") != null)
statManager.register(McMMOHook.disableMcMMORepair);
if (Bukkit.getPluginManager().getPlugin("Residence") != null) {
flagPlugin = new ResidenceFlags();
getLogger().log(Level.INFO, "Hooked onto Residence");
}
if (Bukkit.getPluginManager().getPlugin("mcMMO") != null)
Bukkit.getPluginManager().registerEvents(new McMMONonRPGHook(), this);
if (Bukkit.getPluginManager().getPlugin("RPGInventory") != null) {
inventory = new RPGInventoryHook();
getLogger().log(Level.INFO, "Hooked onto RPGInventory");

View File

@ -145,7 +145,7 @@ public class Type {
return melee;
}
public boolean isSpecialActionOnRightClick() {
public boolean rightClickInteraction() {
return rightClickSpecial;
}
@ -258,32 +258,50 @@ public class Type {
return id != null && MMOItems.plugin.getTypes().has(id.toUpperCase().replace("-", "_").replace(" ", "_"));
}
/**
* Used by player inventory updates to store where the items are equipped
* and if they should be updated when some specific event happens.
*
* @author cympe
*
*/
public enum EquipmentSlot {
/*
* can only apply stats in armor
/**
* Can only apply stats in armor slots
*/
ARMOR,
/*
* can't apply stats in vanilla slots
/**
* Can't apply stats in vanilla slots
*/
ACCESSORY,
/*
* cannot apply its stats anywhere
/**
* Cannot apply its stats anywhere
*/
OTHER,
/*
* always apply its stats. may only be used by EquippedItems, and not
/**
* Always apply its stats. may only be used by EquippedItems, and not
* Types since default types do not use it and extra types keep their
* parent equipment slot
*/
ANY,
/**
* Apply stats in main hands only
*/
MAIN_HAND,
/**
* Apply stats in off hand slot only (off hand catalysts mainly)
*/
OFF_HAND,
/**
* Apply stats in both hands, ie shields or bows
*/
BOTH_HANDS;
public boolean isHand() {

View File

@ -28,10 +28,8 @@ public class DurabilityItem {
* Use to handle durability changes for MMOItems without using heavy MMOItem
* class methods
*
* @param player
* Player holding the item
* @param item
* Item with durability
* @param player Player holding the item
* @param item Item with durability
*/
public DurabilityItem(Player player, ItemStack item) {
this(player, MMOLib.plugin.getVersion().getWrapper().getNBTItem(item));
@ -41,10 +39,8 @@ public class DurabilityItem {
* Use to handle durability changes for MMOItems without using heavy MMOItem
* class methods
*
* @param player
* Player holding the item
* @param item
* Item with durability
* @param player Player holding the item
* @param item Item with durability
*/
public DurabilityItem(Player player, NBTItem item) {
this.player = player;
@ -109,13 +105,14 @@ public class DurabilityItem {
// When the item breaks
if (durability <= 0) {
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1);
PlayerData.get(player).scheduleDelayedInventoryUpdate();
PlayerData.get(player).getInventory().scheduleUpdate();
}
return this;
}
public ItemStack toItem() {
/*
* Cross multiplication to display the current item durability on the
* item durability bar. (1 - ratio) because minecraft works with item

View File

@ -1,5 +1,23 @@
package net.Indyuce.mmoitems.api.player;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import net.Indyuce.mmoitems.ItemStats;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.MMOUtils;
@ -8,6 +26,7 @@ import net.Indyuce.mmoitems.api.ItemAttackResult;
import net.Indyuce.mmoitems.api.ItemSet;
import net.Indyuce.mmoitems.api.ItemSet.SetBonuses;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.Indyuce.mmoitems.api.ability.Ability;
import net.Indyuce.mmoitems.api.ability.Ability.CastingMode;
import net.Indyuce.mmoitems.api.ability.AbilityResult;
@ -15,8 +34,10 @@ import net.Indyuce.mmoitems.api.crafting.CraftingStatus;
import net.Indyuce.mmoitems.api.event.AbilityUseEvent;
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
import net.Indyuce.mmoitems.api.player.PlayerStats.CachedStats;
import net.Indyuce.mmoitems.api.player.inventory.EquippedItem;
import net.Indyuce.mmoitems.api.player.inventory.EquippedPlayerItem;
import net.Indyuce.mmoitems.api.player.inventory.InventoryUpdateHandler;
import net.Indyuce.mmoitems.comp.flags.FlagPlugin.CustomFlag;
import net.Indyuce.mmoitems.comp.inventory.PlayerInventory.EquippedItem;
import net.Indyuce.mmoitems.particle.api.ParticleRunnable;
import net.Indyuce.mmoitems.stat.data.AbilityData;
import net.Indyuce.mmoitems.stat.data.AbilityListData;
@ -28,27 +49,6 @@ import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.DamageType;
import net.mmogroup.mmolib.api.item.NBTItem;
import net.mmogroup.mmolib.api.player.MMOPlayerData;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
public class PlayerData {
private static final Map<UUID, PlayerData> data = new HashMap<>();
@ -59,14 +59,7 @@ public class PlayerData {
*/
private RPGPlayer rpgPlayer;
/*
* the inventory is all the items the player can actually use. items are
* cached here to check if the player's items changed, if so just update
* inventory TODO improve player inventory checkup method
*/
private ItemStack helmet = null, chestplate = null, leggings = null, boots = null, hand = null, offhand = null;
private final List<VolatileMMOItem> playerInventory = new ArrayList<>();
private final InventoryUpdateHandler inventory = new InventoryUpdateHandler(this);
private final CraftingStatus craftingStatus = new CraftingStatus();
private final PlayerAbilityData playerAbilityData = new PlayerAbilityData();
private final Map<String, CooldownInformation> abilityCooldowns = new HashMap<>();
@ -140,32 +133,6 @@ public class PlayerData {
return rpgPlayer;
}
/*
* returns all the usable MMOItems in the player inventory, this can be used
* to calculate stats. this list updates each time a player equips a new
* item.
*/
public List<VolatileMMOItem> getMMOItems() {
return playerInventory;
}
public void checkForInventoryUpdate() {
if (!mmoData.isOnline())
return;
PlayerInventory inv = getPlayer().getInventory();
if (isNotSame(helmet, inv.getHelmet()) || isNotSame(chestplate, inv.getChestplate()) || isNotSame(leggings, inv.getLeggings())
|| isNotSame(boots, inv.getBoots()) || isNotSame(hand, inv.getItemInMainHand()) || isNotSame(offhand, inv.getItemInOffHand()))
updateInventory();
}
public void scheduleDelayedInventoryUpdate() {
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, this::updateInventory);
}
private boolean isNotSame(ItemStack item, ItemStack item1) {
return !Objects.equals(item, item1);
}
public void cancelRunnables() {
itemParticles.forEach(BukkitRunnable::cancel);
if (overridingItemParticles != null)
@ -179,20 +146,23 @@ public class PlayerData {
public boolean areHandsFull() {
if (!mmoData.isOnline())
return false;
NBTItem main = MMOLib.plugin.getVersion().getWrapper().getNBTItem(getPlayer().getInventory().getItemInMainHand());
NBTItem off = MMOLib.plugin.getVersion().getWrapper().getNBTItem(getPlayer().getInventory().getItemInOffHand());
return (main.getBoolean("MMOITEMS_TWO_HANDED") && (off.getItem() != null && off.getItem().getType() != Material.AIR))
|| (off.getBoolean("MMOITEMS_TWO_HANDED") && (main.getItem() != null && main.getItem().getType() != Material.AIR));
}
@SuppressWarnings("deprecation")
public void updateInventory() {
if (!mmoData.isOnline())
return;
/*
* very important, clear particle data AFTER canceling the runnable
* otherwise it cannot cancel and the runnable keeps going (severe)
*/
playerInventory.clear();
inventory.getEquipped().clear();
permanentEffects.clear();
itemAbilities.clear();
cancelRunnables();
@ -213,32 +183,28 @@ public class PlayerData {
*/
fullHands = areHandsFull();
// find all the items the player can actually use.
/*
* Find all the items the player can actually use
*/
for (EquippedItem item : MMOItems.plugin.getInventory().getInventory(getPlayer())) {
NBTItem nbtItem = item.newNBTItem();
NBTItem nbtItem = item.getItem();
Type type = Type.get(nbtItem.getType());
if (type == null)
continue;
/*
* if the player is holding an item the wrong way i.e if the item is
* not in the right slot. intuitive methods with small exceptions
* like BOTH_HANDS and ANY
/**
* If the item is a custom item, apply slot and item use
* restrictions (items which only work in a specific equipment slot)
*/
if (!item.matches(type))
if (type != null && (!item.matches(type) || !getRPG().canUse(nbtItem, false)))
continue;
if (!getRPG().canUse(nbtItem, false))
continue;
playerInventory.add(new VolatileMMOItem(nbtItem));
inventory.getEquipped().add(new EquippedPlayerItem(item));
}
for (VolatileMMOItem item : getMMOItems()) {
for (EquippedPlayerItem equipped : inventory.getEquipped()) {
VolatileMMOItem item = equipped.getItem();
/*
* apply permanent potion effects
* Apply permanent potion effects
*/
if (item.hasData(ItemStats.PERM_EFFECTS))
((PotionEffectListData) item.getData(ItemStats.PERM_EFFECTS)).getEffects().forEach(effect -> {
@ -247,7 +213,7 @@ public class PlayerData {
});
/*
* apply item particles
* Apply item particles
*/
if (item.hasData(ItemStats.ITEM_PARTICLES)) {
ParticleData particleData = (ParticleData) item.getData(ItemStats.ITEM_PARTICLES);
@ -260,21 +226,14 @@ public class PlayerData {
}
/*
* apply abilities
* Apply abilities
*/
if (item.hasData(ItemStats.ABILITIES)) {
// if the item with the abilities is in the players offhand AND
// its disabled in the config then just move on, else add the
// ability
if (item.getNBT().getItem().equals(getPlayer().getInventory().getItemInOffHand())
&& MMOItems.plugin.getConfig().getBoolean("disable-abilities-in-offhand")) {
continue;
} else
if (item.hasData(ItemStats.ABILITIES))
if (equipped.getSlot() != EquipmentSlot.OFF_HAND || !MMOItems.plugin.getConfig().getBoolean("disable-abilities-in-offhand"))
itemAbilities.addAll(((AbilityListData) item.getData(ItemStats.ABILITIES)).getAbilities());
}
/*
* apply permissions if vault exists
* Apply permissions if vault exists
*/
if (MMOItems.plugin.hasPermissions() && item.hasData(ItemStats.GRANTED_PERMISSIONS)) {
permissions.addAll(((StringListData) item.getData(ItemStats.GRANTED_PERMISSIONS)).getList());
@ -293,7 +252,8 @@ public class PlayerData {
int max = 0;
ItemSet set = null;
Map<ItemSet, Integer> sets = new HashMap<>();
for (VolatileMMOItem item : getMMOItems()) {
for (EquippedPlayerItem equipped : inventory.getEquipped()) {
VolatileMMOItem item = equipped.getItem();
String tag = item.getNBT().getString("MMOITEMS_ITEM_SET");
ItemSet itemSet = MMOItems.plugin.getSets().get(tag);
if (itemSet == null)
@ -333,12 +293,12 @@ public class PlayerData {
* actually update the player inventory so the task doesn't infinitely
* loop on updating
*/
helmet = getPlayer().getInventory().getHelmet();
chestplate = getPlayer().getInventory().getChestplate();
leggings = getPlayer().getInventory().getLeggings();
boots = getPlayer().getInventory().getBoots();
hand = getPlayer().getInventory().getItemInMainHand();
offhand = getPlayer().getInventory().getItemInOffHand();
inventory.helmet = getPlayer().getInventory().getHelmet();
inventory.chestplate = getPlayer().getInventory().getChestplate();
inventory.leggings = getPlayer().getInventory().getLeggings();
inventory.boots = getPlayer().getInventory().getBoots();
inventory.hand = getPlayer().getInventory().getItemInMainHand();
inventory.offhand = getPlayer().getInventory().getItemInOffHand();
}
public void updateStats() {
@ -353,6 +313,10 @@ public class PlayerData {
getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 40, 1, true, false));
}
public InventoryUpdateHandler getInventory() {
return inventory;
}
public SetBonuses getSetBonuses() {
return setBonuses;
}
@ -441,23 +405,29 @@ public class PlayerData {
}
public void cast(CachedStats stats, LivingEntity target, ItemAttackResult attack, AbilityData ability) {
AbilityUseEvent event = new AbilityUseEvent(this, ability, target);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
/*
* Apply simple conditions including mana and stamina cost, permission
* and cooldown checks
*/
if (!rpgPlayer.canCast(ability))
return;
/*
* check if ability can be cast (custom conditions)
* Apply extra conditions which depend on the ability the player is
* casting
*/
AbilityResult abilityResult = ability.getAbility().whenRan(stats, target, ability, attack);
if (!abilityResult.isSuccessful())
return;
AbilityUseEvent event = new AbilityUseEvent(this, ability, target);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled())
return;
/*
* the player can cast the ability, and it was successfully cast on its
* The player can cast the ability, and it was successfully cast on its
* target, removes resources needed from the player
*/
if (ability.hasModifier("mana"))
@ -470,7 +440,7 @@ public class PlayerData {
applyAbilityCooldown(ability.getAbility(), cooldown);
/*
* finally cast the ability (BUG FIX) cooldown MUST be applied BEFORE
* Finally cast the ability; BUG FIX: cooldown MUST be applied BEFORE
* the ability is cast otherwise instantaneously damaging abilities like
* Sparkle can trigger deadly crash loops
*/
@ -531,31 +501,30 @@ public class PlayerData {
}
public static PlayerData get(UUID uuid) {
if (PlayerData.data.containsKey(uuid))
return data.get(uuid);
return new PlayerData(MMOPlayerData.get(uuid));
return data.get(uuid);
}
/*
* method called when the corresponding MMOPlayerData has already been
* initialized
/**
* Called when the corresponding MMOPlayerData has already been initialized
*/
public static void load(Player player) {
/*
* Double check they are online, for some reason even if this is fired
* from the join event the player can be offline if they left in the
* same tick or something.
*/
if (!player.isOnline() || data.containsKey(player.getUniqueId()))
if (!data.containsKey(player.getUniqueId())) {
data.put(player.getUniqueId(), new PlayerData(MMOPlayerData.get(player)));
return;
PlayerData newData = PlayerData.get(player.getUniqueId());
}
/*
* update the cached RPGPlayer in case of any major change in the player
* Update the cached RPGPlayer in case of any major change in the player
* data of other rpg plugins
*/
newData.rpgPlayer = MMOItems.plugin.getRPG().getInfo(newData);
/* cache the playerdata */
data.put(player.getUniqueId(), newData);
PlayerData playerData = PlayerData.get(player.getUniqueId());
playerData.rpgPlayer = MMOItems.plugin.getRPG().getInfo(playerData);
}
public static Collection<PlayerData> getLoaded() {
@ -564,16 +533,25 @@ public class PlayerData {
public enum CooldownType {
// simple attack cooldown
/**
* Basic attack cooldown like staffs and lutes
*/
ATTACK,
// elemental ttack
/**
* Elemental attacks cooldown
*/
ELEMENTAL_ATTACK,
// item type special effects
/**
* Special attacks like staffs or gauntlets right clicks
*/
SPECIAL_ATTACK,
// piercing / blunt / slashing passive effects
/**
* Special item set attack effects including slashing, piercing and
* blunt attack effects
*/
SET_TYPE_ATTACK
}
}

View File

@ -6,7 +6,8 @@ import java.util.Map;
import org.bukkit.entity.Player;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.Indyuce.mmoitems.api.player.inventory.EquippedPlayerItem;
import net.Indyuce.mmoitems.stat.type.AttributeStat;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import net.mmogroup.mmolib.api.stat.StatInstance;
@ -43,37 +44,49 @@ public class PlayerStats {
public void updateStats() {
getMap().getInstances().forEach(ins -> {
ins.remove("item");
ins.remove("fullSetBonus");
ins.remove("MMOItem");
ins.remove("MMOItemSetBonus");
});
if (playerData.hasSetBonuses())
playerData.getSetBonuses().getStats()
.forEach((stat, value) -> getInstance(stat).addModifier("fullSetBonus", new StatModifier(value, ModifierType.FLAT)));
.forEach((stat, value) -> getInstance(stat).addModifier("MMOItemSetBonus", new StatModifier(value, ModifierType.FLAT)));
for (ItemStat stat : MMOItems.plugin.getStats().getNumericStats()) {
double t = 0;
double sum = 0;
for (VolatileMMOItem item : playerData.getMMOItems())
t += item.getNBT().getStat(stat.getId());
/*
* If the player is holding a weapon granting a certain stat, the
* final stat value should be applied the attribute stat offset like
* 4 for attack speed or 1 for attack damage
*/
boolean hasWeapon = false;
if (t != 0)
getInstance(stat).addModifier("item",
new StatModifier(t - (stat instanceof AttributeStat ? ((AttributeStat) stat).getOffset() : 0), ModifierType.FLAT));
for (EquippedPlayerItem item : playerData.getInventory().getEquipped()) {
double value = item.getItem().getNBT().getStat(stat.getId());
if (value != 0) {
sum += value;
if (!hasWeapon && item.getSlot() == EquipmentSlot.BOTH_HANDS)
hasWeapon = true;
}
}
if (sum != 0) {
double offset = hasWeapon && stat instanceof AttributeStat ? ((AttributeStat) stat).getOffset() : 0;
getInstance(stat).addModifier("MMOItem", new StatModifier(sum - offset, ModifierType.FLAT));
}
}
}
public class CachedStats {
/*
* this field is made final so even when the player logs out, the
* ability can still be cast without any additional errors. this allows
* not to add a safe check in every ability loop.
*/
private final Player player;
private final Map<String, Double> stats = new HashMap<>();
/**
* Used to cache stats when a player casts a skill so that if the player
* swaps items or changes any of his stat value before the end of the
* spell duration, the stat value is not updated
*/
public CachedStats() {
player = playerData.getPlayer();
for (StatInstance ins : getMap().getInstances())

View File

@ -21,6 +21,14 @@ public abstract class RPGPlayer {
this(PlayerData.get(player));
}
/**
* Used to retrieve useful information like class name, level, mana and
* stamina from RPG plugins. This instance is reloaded everytime the player
* logs back on the server to ensure the object references are kept up to
* date
*
* @param playerData The corresponding player
*/
public RPGPlayer(PlayerData playerData) {
this.player = playerData.getPlayer();
this.playerData = playerData;

View File

@ -0,0 +1,47 @@
package net.Indyuce.mmoitems.api.player.inventory;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;
public class EquippedItem {
private final NBTItem item;
private final EquipmentSlot slot;
/**
* An item equipped by a player in a specific slot
*
* @param item The item equipped
* @param slot The corresponding MMOItems slot type
*/
public EquippedItem(ItemStack item, EquipmentSlot slot) {
this(MMOLib.plugin.getVersion().getWrapper().getNBTItem(item), slot);
}
/**
* An item equipped by a player in a specific slot
*
* @param item The item equipped
* @param slot The corresponding MMOItems slot type, must not be null!
*/
public EquippedItem(NBTItem item, EquipmentSlot slot) {
this.item = item;
this.slot = slot;
}
public NBTItem getItem() {
return item;
}
public EquipmentSlot getSlot() {
return slot;
}
public boolean matches(Type type) {
return slot == EquipmentSlot.ANY || (type.getEquipmentType() == EquipmentSlot.BOTH_HANDS ? slot.isHand()
: slot == EquipmentSlot.BOTH_HANDS ? type.getEquipmentType().isHand() : slot == type.getEquipmentType());
}
}

View File

@ -0,0 +1,34 @@
package net.Indyuce.mmoitems.api.player.inventory;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
public class EquippedPlayerItem {
private final VolatileMMOItem item;
private final EquipmentSlot slot;
/**
* An item equipped by a player in a specific slot
*
* @param item The item equipped
* @param slot The corresponding MMOItems slot type, must not be null!
*/
public EquippedPlayerItem(EquippedItem item) {
this.item = new VolatileMMOItem(item.getItem());
this.slot = item.getSlot();
}
public VolatileMMOItem getItem() {
return item;
}
public EquipmentSlot getSlot() {
return slot;
}
public boolean matches(Type type) {
return slot == EquipmentSlot.ANY || (type.getEquipmentType() == EquipmentSlot.BOTH_HANDS ? slot.isHand()
: slot == EquipmentSlot.BOTH_HANDS ? type.getEquipmentType().isHand() : slot == type.getEquipmentType());
}
}

View File

@ -0,0 +1,78 @@
package net.Indyuce.mmoitems.api.player.inventory;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.Indyuce.mmoitems.api.player.PlayerData;
/**
* It's one of the most urgent systems to update. Moving everything to a new
* class to mark everything that needs to be changed
*
* @author cympe
*
*/
public class InventoryUpdateHandler {
private final PlayerData player;
private final List<EquippedPlayerItem> items = new ArrayList<>();
@Deprecated
public ItemStack helmet = null, chestplate = null, leggings = null, boots = null, hand = null, offhand = null;
/**
* Used to handle player inventory updates.
*/
public InventoryUpdateHandler(PlayerData player) {
this.player = player;
}
/**
* @return All equipped MMOItems in the player's inventory. Also includes
* items from custom inventory plugins like MMOInventory
*/
public List<EquippedPlayerItem> getEquipped() {
return items;
}
/**
* @return If the player has in his active item inventory an item with a
* specific equipment slot. This is ran by stat updates because MI
* needs to check if the player is holding a WEAPON before apply an
* attribute base stat value offset (attack damage/speed).
*/
public boolean hasItemWithType(EquipmentSlot checked) {
for (EquippedPlayerItem item : items)
if (item.getSlot() == checked)
return true;
return false;
}
public void updateCheck() {
if (!player.isOnline())
return;
PlayerInventory inv = player.getPlayer().getInventory();
if (isNotSame(helmet, inv.getHelmet()) || isNotSame(chestplate, inv.getChestplate()) || isNotSame(leggings, inv.getLeggings())
|| isNotSame(boots, inv.getBoots()) || isNotSame(hand, inv.getItemInMainHand()) || isNotSame(offhand, inv.getItemInOffHand()))
player.updateInventory();
}
/**
* Schedules an inventory update in one tick
*/
public void scheduleUpdate() {
Bukkit.getScheduler().scheduleSyncDelayedTask(MMOItems.plugin, player::updateInventory);
}
private boolean isNotSame(ItemStack item, ItemStack item1) {
return !Objects.equals(item, item1);
}
}

View File

@ -0,0 +1,27 @@
package net.Indyuce.mmoitems.comp;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import com.gmail.nossr50.events.skills.repair.McMMOPlayerRepairCheckEvent;
import net.mmogroup.mmolib.api.item.NBTItem;
/**
* The McMMOHook class is only instantiated if McMMO is being used by MMOItems
* as a RPGCore plugin however there are features which should enable even if
* McMMO is not detected as a RPG Core plugin if other RPG plugins are used at
* the same time.
*
* @author cympe
*
*/
public class McMMONonRPGHook implements Listener {
@EventHandler(ignoreCancelled = true)
public void handleNoMcMMORepair(McMMOPlayerRepairCheckEvent event) {
NBTItem nbt = NBTItem.get(event.getRepairedObject());
if (nbt.hasType() && nbt.getBoolean("MMOITEMS_DISABLE_MCMMO_REPAIR"))
event.setCancelled(true);
}
}

View File

@ -7,6 +7,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.Indyuce.mmoitems.api.player.inventory.EquippedItem;
public class DefaultPlayerInventory implements PlayerInventory {
@Override

View File

@ -3,7 +3,6 @@ package net.Indyuce.mmoitems.comp.inventory;
import java.util.ArrayList;
import java.util.List;
import net.Indyuce.mmoitems.api.Type;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@ -14,8 +13,10 @@ import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.player.inventory.EquippedItem;
import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;

View File

@ -3,36 +3,9 @@ package net.Indyuce.mmoitems.comp.inventory;
import java.util.List;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;
import net.Indyuce.mmoitems.api.player.inventory.EquippedItem;
public interface PlayerInventory {
List<EquippedItem> getInventory(Player player);
class EquippedItem {
private final NBTItem item;
private final EquipmentSlot slot;
public EquippedItem(ItemStack item, EquipmentSlot slot) {
this(MMOLib.plugin.getVersion().getWrapper().getNBTItem(item), slot);
}
public EquippedItem(NBTItem item, EquipmentSlot slot) {
this.item = item;
this.slot = slot;
}
public NBTItem newNBTItem() {
return item;
}
public boolean matches(Type type) {
return slot == EquipmentSlot.ANY || (type.getEquipmentType() == EquipmentSlot.BOTH_HANDS ? slot.isHand()
: slot == EquipmentSlot.BOTH_HANDS ? type.getEquipmentType().isHand() : slot == type.getEquipmentType());
}
}
}

View File

@ -3,7 +3,6 @@ package net.Indyuce.mmoitems.comp.inventory;
import java.util.ArrayList;
import java.util.List;
import net.Indyuce.mmoitems.api.Type;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -12,8 +11,10 @@ import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.ItemStack;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.Type.EquipmentSlot;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.player.inventory.EquippedItem;
import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;
import ru.endlesscode.rpginventory.api.InventoryAPI;

View File

@ -43,17 +43,17 @@ public class MMOCoreHook implements RPGHandler, Listener {
@EventHandler
public void updateInventoryOnLevelUp(PlayerLevelUpEvent event) {
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
@EventHandler
public void updateInventoryOnClassChange(PlayerChangeClassEvent event) {
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
@EventHandler
public void updateInventoryOnPlayerDataLoad(PlayerDataLoadEvent event) {
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
public static class MMOCoreRPGPlayer extends RPGPlayer {

View File

@ -12,7 +12,7 @@ public class BattleLevelsHook implements RPGHandler, Listener {
@EventHandler
public void a(PlayerLevelUpEvent event) {
PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
@Override

View File

@ -15,7 +15,7 @@ public class DefaultHook implements RPGHandler, Listener {
@EventHandler
public void a(PlayerLevelChangeEvent event) {
PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
@Override

View File

@ -63,12 +63,12 @@ public class HeroesHook implements RPGHandler, Listener, DamageHandler {
*/
@EventHandler
public void a(HeroChangeLevelEvent event) {
PlayerData.get(event.getHero().getPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getHero().getPlayer()).getInventory().scheduleUpdate();
}
@EventHandler
public void b(ClassChangeEvent event) {
PlayerData.get(event.getHero().getPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getHero().getPlayer()).getInventory().scheduleUpdate();
}
// @EventHandler

View File

@ -8,13 +8,11 @@ import com.gmail.nossr50.api.ExperienceAPI;
import com.gmail.nossr50.api.exceptions.McMMOPlayerNotFoundException;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelDownEvent;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent;
import com.gmail.nossr50.events.skills.repair.McMMOPlayerRepairCheckEvent;
import net.Indyuce.mmoitems.api.player.PlayerData;
import net.Indyuce.mmoitems.api.player.RPGPlayer;
import net.Indyuce.mmoitems.stat.type.DisableStat;
import net.Indyuce.mmoitems.stat.type.ItemStat;
import net.mmogroup.mmolib.api.item.NBTItem;
public class McMMOHook implements RPGHandler, Listener {
@ -29,19 +27,12 @@ public class McMMOHook implements RPGHandler, Listener {
@EventHandler(ignoreCancelled = true)
public void a(McMMOPlayerLevelUpEvent event) {
PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
@EventHandler(ignoreCancelled = true)
public void b(McMMOPlayerLevelDownEvent event) {
PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
}
@EventHandler(ignoreCancelled = true)
public void c(McMMOPlayerRepairCheckEvent event) {
NBTItem nbt = NBTItem.get(event.getRepairedObject());
if (nbt.hasType() && nbt.getBoolean("MMOITEMS_DISABLE_MCMMO_REPAIR"))
event.setCancelled(true);
PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
@Override

View File

@ -12,7 +12,7 @@ public class McRPGHook implements RPGHandler, Listener {
@EventHandler
public void a(McRPGPlayerLevelChangeEvent event) {
PlayerData.get(event.getMcRPGPlayer().getOfflineMcRPGPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getMcRPGPlayer().getOfflineMcRPGPlayer()).getInventory().scheduleUpdate();
}
@Override

View File

@ -30,12 +30,12 @@ public class RacesAndClassesHook implements RPGHandler, Listener {
*/
@EventHandler
public void a(LevelUpEvent event) {
PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
@EventHandler
public void b(LevelDownEvent event) {
PlayerData.get(event.getPlayer()).scheduleDelayedInventoryUpdate();
PlayerData.get(event.getPlayer()).getInventory().scheduleUpdate();
}
public static class RacePlayer extends RPGPlayer {

View File

@ -61,7 +61,7 @@ public class SkillAPIHook implements RPGHandler, Listener, DamageHandler {
@EventHandler
public void b(PlayerLevelUpEvent event) {
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayerData().getPlayer()).scheduleDelayedInventoryUpdate();
net.Indyuce.mmoitems.api.player.PlayerData.get(event.getPlayerData().getPlayer()).getInventory().scheduleUpdate();
}
@Override

View File

@ -17,7 +17,7 @@ public class SkillsHook implements RPGHandler, Listener {
public void a(SkillLevelUpEvent event) {
OfflinePlayer player = event.getPlayer();
if (player.isOnline())
PlayerData.get(player).scheduleDelayedInventoryUpdate();
PlayerData.get(player).getInventory().scheduleUpdate();
}
@Override

View File

@ -16,7 +16,7 @@ public class SkillsProHook implements RPGHandler, Listener {
public void a(SkillLevelUpEvent event) {
OfflinePlayer player = event.getPlayer();
if (player.isOnline())
PlayerData.get(player).scheduleDelayedInventoryUpdate();
PlayerData.get(player).getInventory().scheduleUpdate();
}
@Override