From 27ae7ae1a76f1370738110c18fea2b2d40c82e3a Mon Sep 17 00:00:00 2001 From: nossr50 Date: Thu, 21 Jan 2021 15:27:50 -0800 Subject: [PATCH] Add Power Level broadcasts Fixes #4388 --- Changelog.txt | 11 ++ .../java/com/gmail/nossr50/config/Config.java | 8 ++ .../PowerLevelUpBroadcastPredicate.java | 100 ++++++++++++++++++ .../com/gmail/nossr50/util/EventUtils.java | 3 + .../util/player/NotificationManager.java | 39 +++++++ src/main/resources/config.yml | 17 +++ .../resources/locale/locale_en_US.properties | 3 +- 7 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gmail/nossr50/datatypes/PowerLevelUpBroadcastPredicate.java diff --git a/Changelog.txt b/Changelog.txt index 73eb614fe..5eaff843c 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,16 @@ Version 2.1.172 Added 'mcmmo.broadcast.levelup' permission node, if a player lacks this node they will not have their level up milestones broadcast to chat + Power Levels are now included in level up broadcasts and they have their own settings (mirroring the existing settings for skill broadcasts) + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels' to config.yml + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Enabled' to config.yml + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Milestone_Interval' to config.yml + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Send_To_Console' to config.yml + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Only_Party_Members' to config.yml + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Only_Same_World' to config.yml + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Distance_Restrictions.Restrict_Distance' to config.yml + Added 'General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Distance_Restrictions.Restricted_Radius' to config.yml + Added 'Broadcasts.PowerLevelUpMilestone' to locale + You can now disable the XP orbs from being dropped when Knock On Wood triggers during Tree Feller Added 'Skills.Woodcutting.TreeFeller.Knock_On_Wood.Add_XP_Orbs_To_Drops' to advanced.yml Updated german locale (thanks TheBusyBiscuit) diff --git a/src/main/java/com/gmail/nossr50/config/Config.java b/src/main/java/com/gmail/nossr50/config/Config.java index 297ab3088..cc8549303 100644 --- a/src/main/java/com/gmail/nossr50/config/Config.java +++ b/src/main/java/com/gmail/nossr50/config/Config.java @@ -589,4 +589,12 @@ public class Config extends AutoUpdateConfigLoader { public int getLevelUpBroadcastRadius() { return config.getInt("General.Level_Up_Chat_Broadcasts.Broadcast_Targets.Distance_Restrictions.Restricted_Radius", 100); } public int getLevelUpBroadcastInterval() { return config.getInt("General.Level_Up_Chat_Broadcasts.Milestone_Interval", 100); } + public boolean shouldPowerLevelUpBroadcasts() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Enabled", true); } + public boolean shouldPowerLevelUpBroadcastToConsole() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Send_To_Console", true); } + public boolean isPowerLevelUpBroadcastsPartyMembersOnly() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Only_Party_Members", false); } + public boolean isPowerLevelUpBroadcastsSameWorldOnly() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Only_Same_World", false); } + public boolean shouldPowerLevelUpBroadcastsRestrictDistance() { return config.getBoolean("General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Distance_Restrictions.Restrict_Distance", false); } + public int getPowerLevelUpBroadcastRadius() { return config.getInt("General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Broadcast_Targets.Distance_Restrictions.Restricted_Radius", 100); } + public int getPowerLevelUpBroadcastInterval() { return config.getInt("General.Level_Up_Chat_Broadcasts.Broadcast_Powerlevels.Milestone_Interval", 100); } + } diff --git a/src/main/java/com/gmail/nossr50/datatypes/PowerLevelUpBroadcastPredicate.java b/src/main/java/com/gmail/nossr50/datatypes/PowerLevelUpBroadcastPredicate.java new file mode 100644 index 000000000..549255006 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/PowerLevelUpBroadcastPredicate.java @@ -0,0 +1,100 @@ +package com.gmail.nossr50.datatypes; + +import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.datatypes.party.Party; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.util.player.UserManager; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Predicate; + +//TODO: Allow for offline players to broadcast +public class PowerLevelUpBroadcastPredicate implements Predicate { + + private final @NotNull T broadcaster; + + public PowerLevelUpBroadcastPredicate(@NotNull T broadcaster) { + this.broadcaster = broadcaster; + } + + @Override + public boolean test(@NotNull T t) { + Player broadcastingPlayer = (Player) broadcaster; //Always a player no need to check cast + + //Broadcaster should be online + if(!broadcastingPlayer.isOnline()) { + return false; + } + + McMMOPlayer mmoBroadcastingPlayer = UserManager.getPlayer(broadcastingPlayer); + + if(mmoBroadcastingPlayer == null) { + //This should never be null, but just in case... + mcMMO.p.getLogger().severe("McMMOPlayer was null for broadcaster in LevelUpBroadcastPredicate when it should never be null!"); + return false; + } + + if(t instanceof Player) { + Player listeningPlayer = (Player) t; + + //Party Member Check + if(Config.getInstance().isPowerLevelUpBroadcastsPartyMembersOnly()) { + McMMOPlayer mmoListeningPlayer = UserManager.getPlayer(listeningPlayer); + + if(mmoListeningPlayer == null) { + return false; //No profile so therefor no party + } + + Party playerWhoLeveledParty = mmoBroadcastingPlayer.getParty(); + Party broadcastRecipientParty = mmoListeningPlayer.getParty(); + + if(playerWhoLeveledParty == null || broadcastRecipientParty == null) { + return false; //No party on either player when being in the same party is required + } + + if(!playerWhoLeveledParty.equals(broadcastRecipientParty)) { + return false; //Not in the same party when it is required + } + } + + //Same world check + if(isPowerLevelUpBroadcastsSameWorldOnly()) { + if(!mmoBroadcastingPlayer.getPlayer().getWorld().equals(listeningPlayer.getWorld())) { + return false; //Not in the same world when its required + } + + //Distance checks + if(Config.getInstance().shouldPowerLevelUpBroadcastsRestrictDistance()) { + if(!Misc.isNear(mmoBroadcastingPlayer.getPlayer().getLocation(), listeningPlayer.getLocation(), Config.getInstance().getPowerLevelUpBroadcastRadius())) { + return false; + } + } + } + + //Visibility checks + if(!listeningPlayer.canSee(mmoBroadcastingPlayer.getPlayer())) { + return false; //Player who leveled should be invisible to this player so don't send the message + } + + return true; + } else { + //Send out to console + return Config.getInstance().shouldPowerLevelUpBroadcastToConsole(); + } + } + + private static boolean isPowerLevelUpBroadcastsSameWorldOnly() { + return Config.getInstance().isPowerLevelUpBroadcastsSameWorldOnly(); + } + + @Override + public String toString() { + return "PowerLevelUpBroadcastPredicate{" + + "broadcaster=" + broadcaster + + '}'; + } +} diff --git a/src/main/java/com/gmail/nossr50/util/EventUtils.java b/src/main/java/com/gmail/nossr50/util/EventUtils.java index a928c7c82..b1f99de72 100644 --- a/src/main/java/com/gmail/nossr50/util/EventUtils.java +++ b/src/main/java/com/gmail/nossr50/util/EventUtils.java @@ -245,6 +245,8 @@ public final class EventUtils { } else { if (isLevelUp) { NotificationManager.processLevelUpBroadcasting(mmoPlayer, skill, mmoPlayer.getSkillLevel(skill)); + NotificationManager.processPowerLevelUpBroadcasting(mmoPlayer, mmoPlayer.getPowerLevel()); + } } @@ -279,6 +281,7 @@ public final class EventUtils { } else { if (isLevelUp) { NotificationManager.processLevelUpBroadcasting(mmoPlayer, skill, mmoPlayer.getSkillLevel(skill)); + NotificationManager.processPowerLevelUpBroadcasting(mmoPlayer, mmoPlayer.getPowerLevel()); } } diff --git a/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java b/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java index 64bedc286..c8ac56c72 100644 --- a/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java +++ b/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java @@ -3,6 +3,7 @@ package com.gmail.nossr50.util.player; import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.datatypes.LevelUpBroadcastPredicate; +import com.gmail.nossr50.datatypes.PowerLevelUpBroadcastPredicate; import com.gmail.nossr50.datatypes.interactions.NotificationType; import com.gmail.nossr50.datatypes.notifications.SensitiveCommandType; import com.gmail.nossr50.datatypes.player.McMMOPlayer; @@ -299,9 +300,47 @@ public class NotificationManager { } } + //TODO: Remove the code duplication, am lazy atm + public static void processPowerLevelUpBroadcasting(@NotNull McMMOPlayer mmoPlayer, int powerLevel) { + if(powerLevel <= 0) + return; + + //Check if broadcasting is enabled + if(Config.getInstance().shouldPowerLevelUpBroadcasts()) { + //Permission check + if(!Permissions.levelUpBroadcast(mmoPlayer.getPlayer())) { + return; + } + + int levelInterval = Config.getInstance().getPowerLevelUpBroadcastInterval(); + int remainder = powerLevel % levelInterval; + + if(remainder == 0) { + //Grab appropriate audience + Audience audience = mcMMO.getAudiences().filter(getPowerLevelUpBroadcastPredicate(mmoPlayer.getPlayer())); + //TODO: Make prettier + HoverEvent levelMilestoneHover = Component.text(mmoPlayer.getPlayer().getName()) + .append(Component.newline()) + .append(Component.text(LocalDate.now().toString())) + .append(Component.newline()) + .append(Component.text("Power level has reached "+powerLevel)).color(TextColor.fromHexString(HEX_BEIGE_COLOR)) + .asHoverEvent(); + + String localeMessage = LocaleLoader.getString("Broadcasts.PowerLevelUpMilestone", mmoPlayer.getPlayer().getDisplayName(), powerLevel); + Component message = Component.text(localeMessage).hoverEvent(levelMilestoneHover); + + audience.sendMessage(Identity.nil(), message); + } + } + } + //TODO: Could cache public static @NotNull LevelUpBroadcastPredicate getLevelUpBroadcastPredicate(@NotNull CommandSender levelUpPlayer) { return new LevelUpBroadcastPredicate<>(levelUpPlayer); } + public static @NotNull PowerLevelUpBroadcastPredicate getPowerLevelUpBroadcastPredicate(@NotNull CommandSender levelUpPlayer) { + return new PowerLevelUpBroadcastPredicate<>(levelUpPlayer); + } + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 7e2d6b787..ad1a09e69 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -12,6 +12,23 @@ General: Level_Up_Chat_Broadcasts: # Whether or not level up broadcasts are enabled Enabled: true + # Whether or not you want power level milestones to be broadcast + Broadcast_Powerlevels: + Enabled: true + # How often to broadcast, you can change this to 1 to always broadcast a level up event, a setting of 100 will limit it to every 100 levels (for example level 100, level 200, etc) + Milestone_Interval: 100 + Broadcast_Targets: + # Send the message to the console as well + Send_To_Console: true + # Whether or not to only send chat messages to party members + Only_Party_Members: false + # Whether or not players who recieve a level up broadcast have to be on the same world as the one who leveled up + Only_Same_World: false + # Distance restrictions + Distance_Restrictions: + Restrict_Distance: false + # When using Restrict_Distance the blow setting configures the range of the broadcast + Restricted_Radius: 100 # How often to broadcast, you can change this to 1 to always broadcast a level up event, a setting of 100 will limit it to every 100 levels (for example level 100, level 200, etc) Milestone_Interval: 100 Broadcast_Targets: diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties index 450ea66aa..e9048c103 100644 --- a/src/main/resources/locale/locale_en_US.properties +++ b/src/main/resources/locale/locale_en_US.properties @@ -1136,4 +1136,5 @@ Chat.Identity.Console=&6* Console * Chat.Channel.On=&6(&amcMMO-Chat&6) &eYour chat messages will now be automatically delivered to the &a{0}&e chat channel. Chat.Channel.Off=&6(&amcMMO-Chat&6) &7Your chat messages will no longer be automatically delivered to specific chat channels. Chat.Spy.Party=&6[&eSPY&6-&a{2}&6] &r{0} &b\u2192 &r{1} -Broadcasts.LevelUpMilestone=&6(&amcMMO&6) {0}&7 has reached level &a{1}&7 in [[DARK_AQUA]]{2}&7! \ No newline at end of file +Broadcasts.LevelUpMilestone=&6(&amcMMO&6) {0}&7 has reached level &a{1}&7 in [[DARK_AQUA]]{2}&7! +Broadcasts.PowerLevelUpMilestone=&6(&amcMMO&6) {0}&7 has reached a Power level of &a{1}&7! \ No newline at end of file