diff --git a/src/main/java/net/Indyuce/mmocore/MMOCore.java b/src/main/java/net/Indyuce/mmocore/MMOCore.java index d173f3d8..6e084b52 100644 --- a/src/main/java/net/Indyuce/mmocore/MMOCore.java +++ b/src/main/java/net/Indyuce/mmocore/MMOCore.java @@ -41,15 +41,20 @@ import net.Indyuce.mmocore.manager.profession.*; import net.Indyuce.mmocore.manager.social.BoosterManager; import net.Indyuce.mmocore.manager.social.PartyManager; import net.Indyuce.mmocore.manager.social.RequestManager; +import net.Indyuce.mmocore.party.PartyModule; +import net.Indyuce.mmocore.party.PartyModuleType; +import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; import net.Indyuce.mmocore.skill.cast.SkillCastingMode; import net.Indyuce.mmocore.skill.list.Ambers; import net.Indyuce.mmocore.skill.list.Neptune_Gift; import net.Indyuce.mmocore.skill.list.Sneaky_Picky; +import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandMap; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.lang.reflect.Field; @@ -83,6 +88,10 @@ public class MMOCore extends LuminePlugin { public PlaceholderParser placeholderParser = new DefaultParser(); public DataProvider dataProvider = new YAMLDataProvider(); + // Modules + @NotNull + public PartyModule partyModule; + // Profession managers public final CustomBlockManager mineManager = new CustomBlockManager(); public final FishingManager fishingManager = new FishingManager(); @@ -214,14 +223,23 @@ public class MMOCore extends LuminePlugin { if (getConfig().getBoolean("vanilla-exp-redirection.enabled")) Bukkit.getPluginManager().registerEvents(new RedirectVanillaExp(getConfig().getDouble("vanilla-exp-redirection.ratio")), this); - /* - * enable debug mode for extra debug tools. - */ + // Enable debug mode for extra debug tools if (getConfig().contains("debug")) { DebugMode.setLevel(getConfig().getInt("debug", 0)); DebugMode.enableActionBar(); } + // Load party module + try { + String partyPluginName = UtilityMethods.enumName(getConfig().getString("party-plugin")); + PartyModuleType moduleType = PartyModuleType.valueOf(partyPluginName); + Validate.isTrue(moduleType.isValid(), "Plugin '" + moduleType.name() + "' is not installed"); + partyModule = moduleType.provideModule(); + } catch (RuntimeException exception) { + getLogger().log(Level.WARNING, "Could not initialize party module: " + exception.getMessage()); + partyModule = new MMOCorePartyModule(); + } + // Skill casting try { SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode"))); @@ -247,7 +265,6 @@ public class MMOCore extends LuminePlugin { Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), this); Bukkit.getPluginManager().registerEvents(new BlockListener(), this); Bukkit.getPluginManager().registerEvents(new LootableChestsListener(), this); - Bukkit.getPluginManager().registerEvents(new PartyListener(), this); Bukkit.getPluginManager().registerEvents(new GuildListener(), this); Bukkit.getPluginManager().registerEvents(new FishingListener(), this); Bukkit.getPluginManager().registerEvents(new PlayerCollectStats(), this); diff --git a/src/main/java/net/Indyuce/mmocore/api/event/social/PartyChatEvent.java b/src/main/java/net/Indyuce/mmocore/api/event/social/PartyChatEvent.java index c6c02bb7..29802662 100644 --- a/src/main/java/net/Indyuce/mmocore/api/event/social/PartyChatEvent.java +++ b/src/main/java/net/Indyuce/mmocore/api/event/social/PartyChatEvent.java @@ -1,54 +1,54 @@ package net.Indyuce.mmocore.api.event.social; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - import net.Indyuce.mmocore.api.event.PlayerDataEvent; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.social.Party; +import net.Indyuce.mmocore.party.provided.Party; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; public class PartyChatEvent extends PlayerDataEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); + private static final HandlerList handlers = new HandlerList(); - private final Party party; + private final Party party; - private boolean cancelled; - private String message; + private boolean cancelled; + private String message; - public PartyChatEvent(PlayerData playerData, String message) { - super(playerData); - this.party = playerData.getParty(); - this.message = message; - } + public PartyChatEvent(Party party, PlayerData playerData, String message) { + super(playerData); - public void setMessage(String message) { - this.message = message; - } + this.party = party; + this.message = message; + } - public String getMessage() { - return message; - } + public void setMessage(String message) { + this.message = message; + } - public Party getParty() { - return party; - } + public String getMessage() { + return message; + } - @Override - public boolean isCancelled() { - return cancelled; - } + public Party getParty() { + return party; + } - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } + @Override + public boolean isCancelled() { + return cancelled; + } - @Override - public HandlerList getHandlers() { - return handlers; - } + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } - public static HandlerList getHandlerList() { - return handlers; - } + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index a10b9048..366d3857 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -17,7 +17,6 @@ import net.Indyuce.mmocore.api.player.profess.SavedClassInformation; import net.Indyuce.mmocore.api.player.profess.Subclass; import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource; import net.Indyuce.mmocore.api.player.social.FriendRequest; -import net.Indyuce.mmocore.api.player.social.Party; import net.Indyuce.mmocore.api.player.social.guilds.Guild; import net.Indyuce.mmocore.api.player.stats.PlayerStats; import net.Indyuce.mmocore.api.player.stats.StatType; @@ -27,6 +26,8 @@ import net.Indyuce.mmocore.api.util.MMOCoreUtils; import net.Indyuce.mmocore.api.util.math.particle.SmallParticleEffect; import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.PlayerProfessions; +import net.Indyuce.mmocore.party.AbstractParty; +import net.Indyuce.mmocore.party.provided.Party; import net.Indyuce.mmocore.skill.ClassSkill; import net.Indyuce.mmocore.skill.RegisteredSkill; import net.Indyuce.mmocore.skill.cast.SkillCastingHandler; @@ -63,7 +64,6 @@ public class PlayerData extends OfflinePlayerData implements Closable { private PlayerClass profess; private int level, experience, classPoints, skillPoints, attributePoints, attributeReallocationPoints;// skillReallocationPoints, private double mana, stamina, stellium; - private Party party; private Guild guild; private SkillCastingHandler skillCasting; @@ -150,8 +150,9 @@ public class PlayerData extends OfflinePlayerData implements Closable { public void close() { // Remove from party - if (hasParty()) - getParty().removeMember(this); + AbstractParty party = getParty(); + if (party != null && party instanceof Party) + ((Party) party).removeMember(this); // Close quest data questData.close(); @@ -203,8 +204,9 @@ public class PlayerData extends OfflinePlayerData implements Closable { return Math.max(1, level); } - public Party getParty() { - return party; + @Nullable + public AbstractParty getParty() { + return MMOCore.plugin.partyModule.getParty(this); } public boolean hasGuild() { @@ -246,10 +248,6 @@ public class PlayerData extends OfflinePlayerData implements Closable { return mmoData.isOnline(); } - public boolean hasParty() { - return party != null; - } - public boolean inGuild() { return guild != null; } @@ -386,10 +384,6 @@ public class PlayerData extends OfflinePlayerData implements Closable { return friends.contains(uuid); } - public void setParty(Party party) { - this.party = party; - } - public void setGuild(Guild guild) { this.guild = guild; } @@ -502,7 +496,8 @@ public class PlayerData extends OfflinePlayerData implements Closable { value *= 1 + getStats().getStat(StatType.ADDITIONAL_EXPERIENCE) / 100; // Splitting exp through party members - if (splitExp && hasParty()) { + AbstractParty party = getParty(); + if (splitExp && party != null) { List onlineMembers = getParty().getOnlineMembers(); value /= onlineMembers.size(); for (PlayerData member : onlineMembers) diff --git a/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java b/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java index dcd5eef0..603ca617 100644 --- a/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java +++ b/src/main/java/net/Indyuce/mmocore/command/PartyCommand.java @@ -2,6 +2,7 @@ package net.Indyuce.mmocore.command; import java.util.UUID; +import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; @@ -13,7 +14,7 @@ import org.bukkit.entity.Player; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.event.MMOCommandEvent; import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.social.PartyInvite; +import net.Indyuce.mmocore.party.provided.PartyInvite; import net.Indyuce.mmocore.api.player.social.Request; import net.Indyuce.mmocore.manager.InventoryManager; @@ -55,7 +56,7 @@ public class PartyCommand extends BukkitCommand { return true; } - if (!MMOCore.plugin.partyManager.isRegistered(((PartyInvite) request).getParty())) { + if (!((MMOCorePartyModule) MMOCore.plugin.partyModule).isRegistered(((PartyInvite) request).getParty())) { MMOCore.plugin.requestManager.unregisterRequest(uuid); return true; } @@ -67,7 +68,7 @@ public class PartyCommand extends BukkitCommand { return true; } - if (data.hasParty()) + if (data.getParty() != null) InventoryManager.PARTY_VIEW.newInventory(data).open(); else InventoryManager.PARTY_CREATION.newInventory(data).open(); diff --git a/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java b/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java index 265bba11..5935b582 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java +++ b/src/main/java/net/Indyuce/mmocore/comp/MMOCoreTargetRestriction.java @@ -3,9 +3,12 @@ package net.Indyuce.mmocore.comp; import io.lumine.mythic.lib.comp.target.InteractionType; import io.lumine.mythic.lib.comp.target.TargetRestriction; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.party.AbstractParty; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import java.util.Optional; + public class MMOCoreTargetRestriction implements TargetRestriction { @Override @@ -15,7 +18,8 @@ public class MMOCoreTargetRestriction implements TargetRestriction { PlayerData targetData = PlayerData.get(target.getUniqueId()); // Check for the same party - if (targetData.hasParty() && targetData.getParty().hasMember(player)) + AbstractParty party = targetData.getParty(); + if (party != null && party.hasMember(player)) return false; } diff --git a/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java b/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java index 2259b749..dd9e3433 100644 --- a/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java +++ b/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java @@ -9,6 +9,7 @@ import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.api.quest.PlayerQuests; import net.Indyuce.mmocore.experience.PlayerProfessions; import net.Indyuce.mmocore.experience.Profession; +import net.Indyuce.mmocore.party.AbstractParty; import net.Indyuce.mmocore.skill.RegisteredSkill; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -117,8 +118,10 @@ public class RPGPlaceholders extends PlaceholderExpansion { return "" + PlayerData.get(player).getCollectionSkills() .getLevelUpExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()); - else if (identifier.startsWith("party_count")) - return playerData.hasParty() ? String.valueOf(playerData.getParty().getMembers().size()) : "0"; + else if (identifier.startsWith("party_count")) { + AbstractParty party = playerData.getParty(); + return party == null ? "0" : String.valueOf(party.countMembers()); + } else if (identifier.startsWith("profession_")) return String diff --git a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java index 70ae1de9..e7bdfff5 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java +++ b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java @@ -14,6 +14,7 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; +import net.Indyuce.mmocore.party.AbstractParty; import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.configuration.ConfigurationSection; @@ -177,7 +178,7 @@ public class PlayerStats extends EditableInventory { public Placeholders getPlaceholders(GeneratedInventory inv, int n) { Placeholders holders = new Placeholders(); - int count = inv.getPlayerData().getParty().getMembers().size(); + int count = inv.getPlayerData().getParty().getOnlineMembers().size(); holders.register("count", "" + count); for (StatModifier buff : MMOCore.plugin.partyManager.getBonuses()) holders.register("buff_" + buff.getStat().toLowerCase(), buff.multiply(count - 1).toString()); @@ -187,7 +188,8 @@ public class PlayerStats extends EditableInventory { @Override public boolean canDisplay(GeneratedInventory inv) { - return inv.getPlayerData().hasParty() && inv.getPlayerData().getParty().getMembers().size() > 1; + AbstractParty party = inv.getPlayerData().getParty(); + return party != null && party.getOnlineMembers().size() > 1; } } diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java index ce68b0b2..c1e9b2ed 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java +++ b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyCreation.java @@ -7,6 +7,7 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.manager.InventoryManager; +import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; import org.bukkit.Sound; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryClickEvent; @@ -36,8 +37,8 @@ public class EditablePartyCreation extends EditableInventory { return; if (item.getFunction().equals("create")) { - MMOCore.plugin.partyManager.newRegisteredParty(playerData); - InventoryManager.PARTY_VIEW.newInventory(playerData).open(); + ((MMOCorePartyModule) MMOCore.plugin.partyModule).newRegisteredParty(playerData); + InventoryManager.PARTY_VIEW.newInventory(playerData).open(); player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); } diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java index ec99da6d..a115dec2 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java +++ b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java @@ -11,6 +11,7 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; +import net.Indyuce.mmocore.party.provided.Party; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -49,7 +50,8 @@ public class EditablePartyView extends EditableInventory { @Override public Placeholders getPlaceholders(GeneratedInventory inv, int n) { - PlayerData member = inv.getPlayerData().getParty().getMembers().get(n); + Party party = (Party) inv.getPlayerData().getParty(); + PlayerData member = party.getMembers().get(n); Placeholders holders = new Placeholders(); if (member.isOnline()) @@ -62,7 +64,8 @@ public class EditablePartyView extends EditableInventory { @Override public ItemStack display(GeneratedInventory inv, int n) { - PlayerData member = inv.getPlayerData().getParty().getMembers().get(n); + Party party = (Party) inv.getPlayerData().getParty(); + PlayerData member = party.getMembers().get(n); ItemStack disp = super.display(inv, n); ItemMeta meta = disp.getItemMeta(); @@ -97,7 +100,8 @@ public class EditablePartyView extends EditableInventory { @Override public ItemStack display(GeneratedInventory inv, int n) { - return inv.getPlayerData().getParty().getMembers().size() > n ? member.display(inv, n) : empty.display(inv, n); + Party party = (Party) inv.getPlayerData().getParty(); + return party.getMembers().size() > n ? member.display(inv, n) : empty.display(inv, n); } @Override @@ -126,14 +130,16 @@ public class EditablePartyView extends EditableInventory { @Override public String calculateName() { - return getName().replace("{max}", "" + max).replace("{players}", "" + getPlayerData().getParty().getMembers().size()); + Party party = (Party) getPlayerData().getParty(); + return getName().replace("{max}", "" + max).replace("{players}", "" + party.getMembers().size()); } @Override public void whenClicked(InventoryClickEvent event, InventoryItem item) { + Party party = (Party) playerData.getParty(); if (item.getFunction().equals("leave")) { - playerData.getParty().removeMember(playerData); + party.removeMember(playerData); player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); player.closeInventory(); return; @@ -141,7 +147,7 @@ public class EditablePartyView extends EditableInventory { if (item.getFunction().equals("invite")) { - if (playerData.getParty().getMembers().size() >= max) { + if (party.getMembers().size() >= max) { MMOCore.plugin.configManager.getSimpleMessage("party-is-full").send(player); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); return; @@ -156,7 +162,7 @@ public class EditablePartyView extends EditableInventory { return; } - long remaining = playerData.getParty().getLastInvite(target) + 60 * 2 * 1000 - System.currentTimeMillis(); + long remaining = party.getLastInvite(target) + 60 * 2 * 1000 - System.currentTimeMillis(); if (remaining > 0) { MMOCore.plugin.configManager.getSimpleMessage("party-invite-cooldown", "player", target.getName(), "cooldown", new DelayFormat().format(remaining)).send(player); open(); @@ -164,14 +170,14 @@ public class EditablePartyView extends EditableInventory { } PlayerData targetData = PlayerData.get(target); - if (playerData.getParty().hasMember(targetData)) { + if (party.hasMember(target)) { MMOCore.plugin.configManager.getSimpleMessage("already-in-party", "player", target.getName()).send(player); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); open(); return; } - playerData.getParty().sendInvite(playerData, targetData); + party.sendInvite(playerData, targetData); MMOCore.plugin.configManager.getSimpleMessage("sent-party-invite", "player", target.getName()).send(player); player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); open(); @@ -179,14 +185,14 @@ public class EditablePartyView extends EditableInventory { } if (item.getFunction().equals("member") && event.getAction() == InventoryAction.PICKUP_HALF) { - if (!playerData.getParty().getOwner().equals(playerData)) + if (!party.getOwner().equals(playerData)) return; OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(NBTItem.get(event.getCurrentItem()).getString("uuid"))); if (target.equals(player)) return; - playerData.getParty().removeMember(PlayerData.get(target)); + party.removeMember(PlayerData.get(target)); MMOCore.plugin.configManager.getSimpleMessage("kick-from-party", "player", target.getName()).send(player); player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); } diff --git a/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java b/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java index 6c9b9ab0..f5ed1be4 100644 --- a/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java +++ b/src/main/java/net/Indyuce/mmocore/listener/PartyListener.java @@ -1,5 +1,13 @@ package net.Indyuce.mmocore.listener; +import io.lumine.mythic.lib.api.event.PlayerAttackEvent; +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.event.social.PartyChatEvent; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.manager.ConfigManager.SimpleMessage; +import net.Indyuce.mmocore.party.AbstractParty; +import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; +import net.Indyuce.mmocore.party.provided.Party; import org.bukkit.Bukkit; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -8,13 +16,12 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; -import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.event.social.PartyChatEvent; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.manager.ConfigManager.SimpleMessage; -import io.lumine.mythic.lib.api.event.PlayerAttackEvent; - public class PartyListener implements Listener { + private final MMOCorePartyModule module; + + public PartyListener(MMOCorePartyModule module) { + this.module = module; + } @EventHandler(priority = EventPriority.LOW) public void a(AsyncPlayerChatEvent event) { @@ -22,24 +29,20 @@ public class PartyListener implements Listener { return; PlayerData data = PlayerData.get(event.getPlayer()); - if (!data.hasParty()) + Party party = module.getParty(data); + if (party == null) return; event.setCancelled(true); - /* - * running it in a delayed task is recommended - */ + // Running it in a delayed task is recommended Bukkit.getScheduler().scheduleSyncDelayedTask(MMOCore.plugin, () -> { SimpleMessage format = MMOCore.plugin.configManager.getSimpleMessage("party-chat", "player", data.getPlayer().getName(), "message", event.getMessage().substring(MMOCore.plugin.configManager.partyChatPrefix.length())); - PartyChatEvent called = new PartyChatEvent(data, format.message()); + PartyChatEvent called = new PartyChatEvent(party, data, format.message()); Bukkit.getPluginManager().callEvent(called); if (!called.isCancelled()) - data.getParty().getMembers().forEach(member -> { - if (member.isOnline()) - format.send(member.getPlayer()); - }); + party.getOnlineMembers().forEach(member -> format.send(member.getPlayer())); }); } @@ -54,7 +57,8 @@ public class PartyListener implements Listener { LivingEntity entity = event.getEntity(); if (entity instanceof Player && !entity.hasMetadata("NPC")) { PlayerData targetData = PlayerData.get((Player) event.getEntity()); - if (targetData.hasParty() && targetData.getParty().hasMember(PlayerData.get(event.getData().getUniqueId()))) + AbstractParty party = targetData.getParty(); + if (party != null && party.hasMember(event.getData().getPlayer())) event.setCancelled(true); } } diff --git a/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java b/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java index 2dedc4ae..be3c8358 100644 --- a/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java +++ b/src/main/java/net/Indyuce/mmocore/manager/social/PartyManager.java @@ -2,61 +2,34 @@ package net.Indyuce.mmocore.manager.social; import io.lumine.mythic.lib.api.stat.modifier.StatModifier; import net.Indyuce.mmocore.MMOCore; -import net.Indyuce.mmocore.api.player.PlayerData; -import net.Indyuce.mmocore.api.player.social.Party; import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.manager.MMOCoreManager; -import org.apache.commons.lang.Validate; import org.bukkit.configuration.ConfigurationSection; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.logging.Level; public class PartyManager implements MMOCoreManager { - private final Set parties = new HashSet<>(); - private final Set buffs = new HashSet<>(); + private final Set buffs = new HashSet<>(); - public void registerParty(Party party) { - parties.add(party); - } + public Set getBonuses() { + return buffs; + } - public Party newRegisteredParty(PlayerData owner) { - Party party = new Party(owner); - registerParty(party); - return party; - } + @Override + public void initialize(boolean clearBefore) { + if (clearBefore) + buffs.clear(); - public boolean isRegistered(Party party) { - return parties.contains(party); - } - - public void unregisterParty(Party party) { - // IMPORTANT: clears all party members before unregistering the party - party.forEachMember(party::removeMember); - Validate.isTrue(party.getMembers().isEmpty(), "Tried unregistering a non-empty party"); - parties.remove(party); - } - - public Set getBonuses() { - return buffs; - } - - @Override - public void initialize(boolean clearBefore) { - if (clearBefore) - buffs.clear(); - - ConfigurationSection config = MMOCore.plugin.getConfig().getConfigurationSection("party.buff"); - if (config != null) - for (String key : config.getKeys(false)) - try { - StatType stat = StatType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_")); - buffs.add(new StatModifier("mmocoreParty", stat.name(), config.getString(key))); - } catch (IllegalArgumentException exception) { - MMOCore.log(Level.WARNING, "Could not load party buff '" + key + "': " + exception.getMessage()); - } - } + ConfigurationSection config = MMOCore.plugin.getConfig().getConfigurationSection("party.buff"); + if (config != null) + for (String key : config.getKeys(false)) + try { + StatType stat = StatType.valueOf(key.toUpperCase().replace("-", "_").replace(" ", "_")); + buffs.add(new StatModifier("mmocoreParty", stat.name(), config.getString(key))); + } catch (IllegalArgumentException exception) { + MMOCore.log(Level.WARNING, "Could not load party buff '" + key + "': " + exception.getMessage()); + } + } } diff --git a/src/main/java/net/Indyuce/mmocore/party/AbstractParty.java b/src/main/java/net/Indyuce/mmocore/party/AbstractParty.java new file mode 100644 index 00000000..4bae9093 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/party/AbstractParty.java @@ -0,0 +1,24 @@ +package net.Indyuce.mmocore.party; + +import net.Indyuce.mmocore.api.player.PlayerData; +import org.bukkit.OfflinePlayer; + +import java.util.List; + +public interface AbstractParty { + + /** + * @return If given player is in that party + */ + boolean hasMember(OfflinePlayer player); + + /** + * @return List of online members + */ + List getOnlineMembers(); + + /** + * @return Number of online/offline players in the party + */ + int countMembers(); +} diff --git a/src/main/java/net/Indyuce/mmocore/party/PartyModule.java b/src/main/java/net/Indyuce/mmocore/party/PartyModule.java new file mode 100644 index 00000000..1c47e74e --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/party/PartyModule.java @@ -0,0 +1,10 @@ +package net.Indyuce.mmocore.party; + +import net.Indyuce.mmocore.api.player.PlayerData; +import org.jetbrains.annotations.Nullable; + +public interface PartyModule { + + @Nullable + public T getParty(PlayerData playerData); +} diff --git a/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java b/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java new file mode 100644 index 00000000..816b457d --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/party/PartyModuleType.java @@ -0,0 +1,29 @@ +package net.Indyuce.mmocore.party; + +import net.Indyuce.mmocore.party.dungeon.DungeonsPartyModule; +import net.Indyuce.mmocore.party.provided.MMOCorePartyModule; +import org.bukkit.Bukkit; + +import javax.inject.Provider; + +public enum PartyModuleType { + DUNGEONSXL("DungeonsXL", () -> new DungeonsPartyModule()), + MMOCORE("MMOCore", () -> new MMOCorePartyModule()), + ; + + private final String pluginName; + private final Provider> provider; + + PartyModuleType(String pluginName, Provider> provider) { + this.pluginName = pluginName; + this.provider = provider; + } + + public boolean isValid() { + return Bukkit.getPluginManager().getPlugin(pluginName) != null; + } + + public PartyModule provideModule() { + return provider.get(); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/party/dungeon/DungeonsParty.java b/src/main/java/net/Indyuce/mmocore/party/dungeon/DungeonsParty.java new file mode 100644 index 00000000..03ee8857 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/party/dungeon/DungeonsParty.java @@ -0,0 +1,41 @@ +package net.Indyuce.mmocore.party.dungeon; + +import de.erethon.dungeonsxl.api.player.PlayerGroup; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.party.AbstractParty; +import org.bukkit.OfflinePlayer; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class DungeonsParty implements AbstractParty { + private final PlayerGroup group; + + public DungeonsParty(PlayerGroup group) { + this.group = group; + } + + @Override + public boolean hasMember(OfflinePlayer player) { + return group.getMembers().contains(player.getUniqueId()); + } + + @Override + public List getOnlineMembers() { + List list = new ArrayList<>(); + + for (UUID playerUid : group.getMembers().getUniqueIds()) { + PlayerData found = PlayerData.get(playerUid); + if (found.isOnline()) + list.add(found); + } + + return list; + } + + @Override + public int countMembers() { + return group.getMembers().getUniqueIds().size(); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/party/dungeon/DungeonsPartyModule.java b/src/main/java/net/Indyuce/mmocore/party/dungeon/DungeonsPartyModule.java new file mode 100644 index 00000000..037a251b --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/party/dungeon/DungeonsPartyModule.java @@ -0,0 +1,15 @@ +package net.Indyuce.mmocore.party.dungeon; + +import de.erethon.dungeonsxl.DungeonsXL; +import de.erethon.dungeonsxl.api.player.PlayerGroup; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.party.PartyModule; + +public class DungeonsPartyModule implements PartyModule { + + @Override + public DungeonsParty getParty(PlayerData playerData) { + PlayerGroup group = DungeonsXL.getInstance().getPlayerGroup(playerData.getPlayer()); + return group == null ? null : new DungeonsParty(group); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java b/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java new file mode 100644 index 00000000..98ad8656 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/party/provided/MMOCorePartyModule.java @@ -0,0 +1,52 @@ +package net.Indyuce.mmocore.party.provided; + +import net.Indyuce.mmocore.MMOCore; +import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.listener.PartyListener; +import net.Indyuce.mmocore.party.PartyModule; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; + +import java.util.*; + +public class MMOCorePartyModule implements PartyModule { + private final Set parties = new HashSet<>(); + private final Map playerParties = new HashMap<>(); + + public MMOCorePartyModule() { + Bukkit.getPluginManager().registerEvents(new PartyListener(this), MMOCore.plugin); + } + + public void registerParty(Party party) { + parties.add(party); + } + + /** + * Creates and registers a new party with given owner + */ + public Party newRegisteredParty(PlayerData owner) { + Party party = new Party(this, owner); + registerParty(party); + return party; + } + + public boolean isRegistered(Party party) { + return parties.contains(party); + } + + public void unregisterParty(Party party) { + // IMPORTANT: clears all party members before unregistering the party + party.forEachMember(party::removeMember); + Validate.isTrue(party.getMembers().isEmpty(), "Tried unregistering a non-empty party"); + parties.remove(party); + } + + @Override + public Party getParty(PlayerData playerData) { + return this.playerParties.get(playerData.getUniqueId()); + } + + public void setParty(PlayerData playerData, Party party) { + this.playerParties.put(playerData.getUniqueId(), party); + } +} diff --git a/src/main/java/net/Indyuce/mmocore/api/player/social/Party.java b/src/main/java/net/Indyuce/mmocore/party/provided/Party.java similarity index 80% rename from src/main/java/net/Indyuce/mmocore/api/player/social/Party.java rename to src/main/java/net/Indyuce/mmocore/party/provided/Party.java index 9844d0cd..3f8d8ecc 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/social/Party.java +++ b/src/main/java/net/Indyuce/mmocore/party/provided/Party.java @@ -1,30 +1,39 @@ -package net.Indyuce.mmocore.api.player.social; +package net.Indyuce.mmocore.party.provided; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.ConfigMessage; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.social.Request; import net.Indyuce.mmocore.gui.api.PluginInventory; import net.Indyuce.mmocore.gui.social.party.EditablePartyView.PartyViewInventory; import net.Indyuce.mmocore.manager.InventoryManager; +import net.Indyuce.mmocore.party.AbstractParty; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import java.util.*; import java.util.function.Consumer; -public class Party { +public class Party implements AbstractParty { private final List members = new ArrayList<>(); private final Map invites = new HashMap<>(); - // used to check if two parties are the same + /** + * Used for {@link #equals(Object)} + */ private final UUID id = UUID.randomUUID(); - /* - * owner changes when the old owner leaves party + /** + * Owner has to change when previous owner leaves party */ private PlayerData owner; - public Party(PlayerData owner) { + private final MMOCorePartyModule module; + + public Party(MMOCorePartyModule module, PlayerData owner) { this.owner = owner; + this.module = module; + addMember(owner); } @@ -40,6 +49,7 @@ public class Party { return members; } + @Override public List getOnlineMembers() { List online = new ArrayList<>(); @@ -50,6 +60,11 @@ public class Party { return online; } + @Override + public int countMembers() { + return members.size(); + } + public PlayerData getMember(int index) { return members.get(index); } @@ -62,11 +77,8 @@ public class Party { invites.remove(player.getUniqueId()); } - public boolean hasMember(PlayerData playerData) { - return hasMember(playerData.getUniqueId()); - } - - public boolean hasMember(Player player) { + @Override + public boolean hasMember(OfflinePlayer player) { return hasMember(player.getUniqueId()); } @@ -87,14 +99,15 @@ public class Party { InventoryManager.PARTY_CREATION.newInventory(data).open(); members.remove(data); - data.setParty(null); + + module.setParty(data, null); clearStatBonuses(data); members.forEach(this::applyStatBonuses); updateOpenInventories(); // Disband the party if no member left if (members.size() < 1) { - MMOCore.plugin.partyManager.unregisterParty(this); + module.unregisterParty(this); return; } @@ -107,10 +120,11 @@ public class Party { } public void addMember(PlayerData data) { - if (data.hasParty()) - data.getParty().removeMember(data); + Party party = (Party) data.getParty(); + if (party != null) + party.removeMember(data); - data.setParty(this); + module.setParty(data, this); members.add(data); members.forEach(this::applyStatBonuses); @@ -164,7 +178,15 @@ public class Party { } @Override - public boolean equals(Object obj) { - return obj instanceof Party && ((Party) obj).getUniqueId().equals(getUniqueId()); + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Party party = (Party) o; + return id.equals(party.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); } } diff --git a/src/main/java/net/Indyuce/mmocore/api/player/social/PartyInvite.java b/src/main/java/net/Indyuce/mmocore/party/provided/PartyInvite.java similarity index 93% rename from src/main/java/net/Indyuce/mmocore/api/player/social/PartyInvite.java rename to src/main/java/net/Indyuce/mmocore/party/provided/PartyInvite.java index 1777fe53..41e89dd6 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/social/PartyInvite.java +++ b/src/main/java/net/Indyuce/mmocore/party/provided/PartyInvite.java @@ -1,7 +1,8 @@ -package net.Indyuce.mmocore.api.player.social; +package net.Indyuce.mmocore.party.provided; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.social.Request; import net.Indyuce.mmocore.manager.InventoryManager; public class PartyInvite extends Request { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a3306b47..673be8e6 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -58,6 +58,14 @@ custom-mine-conditions: # broken when custom mining conditions are met protect-custom-mine: false +# Edit the plugin handling parties here. +# Supported values (just copy and paste): +# - mmocore +# - dungeonsxl +# - parties +# - parties_and_friends +party-plugin: mmocore + # Whether blocks generated with a "cobblegenerator" should # provide the player with experience points or not should-cobblestone-generators-give-exp: false @@ -65,43 +73,8 @@ should-cobblestone-generators-give-exp: false # Edit how to cast skills here. This part of the config is # pretty tricky so it's best to read the wiki page before editing anything skill-casting: - mode: KEY_COMBOS - initializer-key: SWAP_HANDS - sound: - begin-combo: - sound: BLOCK_END_PORTAL_FRAME_FILL - volume: 1 - pitch: 2 - combo-key: - sound: BLOCK_LEVER_CLICK - volume: 1 - pitch: 2 - fail-combo: - sound: BLOCK_FIRE_EXTINGUISH - volume: 1 - pitch: 2 - action-bar: - separator: ' - ' - no-key: '***' - key-name: - LEFT_CLICK: 'LEFT' - RIGHT_CLICK: 'RGHT' - DROP: 'DROP' - SWAP_HANDS: 'SWAP' - CROUCH: 'SHFT' - combos: - '1': - - LEFT_CLICK - - LEFT_CLICK - '2': - - LEFT_CLICK - - RIGHT_CLICK - '3': - - RIGHT_CLICK - - LEFT_CLICK - '4': - - RIGHT_CLICK - - RIGHT_CLICK + mode: SKILL_BAR + open: SWAP_HANDS loot-chests: