Bladeren bron

mcMMO now alerts you when you progress in a skill

nossr50 6 jaren geleden
bovenliggende
commit
96742e6c42

+ 1 - 0
Changelog.txt

@@ -17,6 +17,7 @@ Version 2.1.0
  + Certain elements of mcMMO's UI have been restyled
  + Added the tagline "Overhaul Era" to various locations until 3.0.0 comes out
  ! (Scoreboards) Scoreboards are now disabled by default, I don't like them. You can turn them back on in config.yml
+ + (Experience) mcMMO now notifies you when you progress in a skill!
  + (Experience) Coral (blocks) now give Mining XP
  + (Experience) Coral (plants) now give Herbalism XP
  + (Experience) Blue Ice now gives Mining XP

+ 10 - 1
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -55,6 +55,7 @@ import org.bukkit.Location;
 import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.metadata.FixedMetadataValue;
+import org.bukkit.plugin.Plugin;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -142,17 +143,25 @@ public class McMMOPlayer {
         experienceBarManager.hideExperienceBar(primarySkillType);
     }*/
 
-    public void processPostXpEvent(XPGainReason xpGainReason, PrimarySkillType primarySkillType, mcMMO plugin)
+    public void processPostXpEvent(XPGainReason xpGainReason, PrimarySkillType primarySkillType, mcMMO plugin, int xpGained)
     {
         if(xpGainReason != XPGainReason.SHARED_PVP && xpGainReason != XPGainReason.SHARED_PVE && xpGainReason != XPGainReason.VAMPIRISM)
             updateXPBar(primarySkillType, plugin);
     }
 
+    public void processUnlockNotifications(mcMMO plugin, PrimarySkillType primarySkillType, int level)
+    {
+        RankUtils.executeSkillUnlockNotifications(plugin, this, primarySkillType, profile.getSkillLevel(primarySkillType));
+    }
+
     public void updateXPBar(PrimarySkillType primarySkillType, mcMMO plugin)
     {
+        //Skill Unlock Notifications
+
         if(primarySkillType.isChildSkill())
             return;
 
+        //XP BAR UPDATES
         experienceBarManager.updateExperienceBar(primarySkillType, plugin);
     }
 

+ 7 - 1
src/main/java/com/gmail/nossr50/datatypes/skills/subskills/AbstractSubSkill.java

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.datatypes.skills.subskills;
 
 import com.gmail.nossr50.config.CoreSkillsConfig;
+import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Interaction;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Rank;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.SubSkill;
@@ -14,11 +15,13 @@ public abstract class AbstractSubSkill implements SubSkill, Interaction, Rank, S
      */
     protected String configKeySubSkill;
     protected String configKeyPrimary;
+    protected SubSkillType subSkillType;
 
-    public AbstractSubSkill(String configKeySubSkill, String configKeyPrimary)
+    public AbstractSubSkill(String configKeySubSkill, String configKeyPrimary, SubSkillType subSkillType)
     {
         this.configKeySubSkill = configKeySubSkill;
         this.configKeyPrimary = configKeyPrimary;
+        this.subSkillType = subSkillType;
     }
 
     /**
@@ -55,6 +58,9 @@ public abstract class AbstractSubSkill implements SubSkill, Interaction, Rank, S
         player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
         player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", getConfigKeyName()));
         player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
+    }
 
+    public SubSkillType getSubSkillType() {
+        return subSkillType;
     }
 }

+ 3 - 2
src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/AcrobaticsSubSkill.java

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
 
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.InteractType;
 import com.gmail.nossr50.locale.LocaleLoader;
@@ -13,8 +14,8 @@ public abstract class AcrobaticsSubSkill extends AbstractSubSkill {
 
     protected EventPriority interactionPriority;
 
-    public AcrobaticsSubSkill(String configKeySub, EventPriority interactionPriority) {
-        super(configKeySub, "Acrobatics");
+    public AcrobaticsSubSkill(String configKeySub, EventPriority interactionPriority, SubSkillType subSkillType) {
+        super(configKeySub, "Acrobatics", subSkillType);
 
         this.interactionPriority = interactionPriority;
     }

+ 1 - 1
src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java

@@ -34,7 +34,7 @@ public class Roll extends AcrobaticsSubSkill implements RandomChance {
     protected Location lastFallLocation;
 
     public Roll() {
-        super("Roll", EventPriority.HIGHEST);
+        super("Roll", EventPriority.HIGHEST, SubSkillType.ACROBATICS_ROLL);
     }
 
     /**

+ 5 - 3
src/main/java/com/gmail/nossr50/listeners/SelfListener.java

@@ -30,6 +30,8 @@ public class SelfListener implements Listener {
         Player player = event.getPlayer();
         PrimarySkillType skill = event.getSkill();
 
+        UserManager.getPlayer(player).processUnlockNotifications(plugin, event.getSkill(), event.getSkillLevel());
+
         if(Config.getInstance().getScoreboardsEnabled())
             ScoreboardManager.handleLevelUp(player, skill);
 
@@ -63,7 +65,7 @@ public class SelfListener implements Listener {
         if (event.getXpGainReason() == XPGainReason.COMMAND)
         {
             //Update the XP Bar
-            mcMMOPlayer.processPostXpEvent(event.getXpGainReason(), primarySkillType, plugin);
+            mcMMOPlayer.processPostXpEvent(event.getXpGainReason(), primarySkillType, plugin, (int) event.getRawXpGained());
             return;
         }
 
@@ -72,7 +74,7 @@ public class SelfListener implements Listener {
         if (threshold <= 0 || !ExperienceConfig.getInstance().getDiminishedReturnsEnabled()) {
             // Diminished returns is turned off
             //Update the XP Bar
-            mcMMOPlayer.processPostXpEvent(event.getXpGainReason(), primarySkillType, plugin);
+            mcMMOPlayer.processPostXpEvent(event.getXpGainReason(), primarySkillType, plugin, (int) event.getRawXpGained());
             return;
         }
 
@@ -118,6 +120,6 @@ public class SelfListener implements Listener {
 
         //Update the XP Bar
         if(!event.isCancelled())
-            mcMMOPlayer.processPostXpEvent(event.getXpGainReason(), primarySkillType, plugin);
+            mcMMOPlayer.processPostXpEvent(event.getXpGainReason(), primarySkillType, plugin, (int) event.getRawXpGained());
     }
 }

+ 4 - 0
src/main/java/com/gmail/nossr50/mcMMO.java

@@ -41,6 +41,7 @@ import com.gmail.nossr50.util.commands.CommandRegistrationManager;
 import com.gmail.nossr50.util.experience.FormulaManager;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
+import com.gmail.nossr50.util.skills.RankUtils;
 import com.gmail.nossr50.util.upgrade.UpgradeManager;
 import com.google.common.base.Charsets;
 import net.shatteredlands.shatt.backup.ZipLibrary;
@@ -181,6 +182,9 @@ public class mcMMO extends JavaPlugin {
                 Permissions.generateWorldTeleportPermissions();
             }
 
+            //Populate Ranked Skill Maps (DO THIS LAST)
+            RankUtils.populateRanks();
+
             //If anonymous statistics are enabled then use them
 
             Metrics metrics;

+ 41 - 0
src/main/java/com/gmail/nossr50/runnables/skills/SkillUnlockNotificationTask.java

@@ -0,0 +1,41 @@
+package com.gmail.nossr50.runnables.skills;
+
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.datatypes.skills.SubSkillType;
+import com.gmail.nossr50.util.player.NotificationManager;
+import org.bukkit.scheduler.BukkitRunnable;
+
+
+public class SkillUnlockNotificationTask extends BukkitRunnable {
+    private McMMOPlayer mcMMOPlayer;
+    private SubSkillType subSkillType;
+    private int rank;
+    /**
+     * Notify a player about a newly unlocked subskill
+     * @param mcMMOPlayer target player
+     * @param subSkillType the subskill that they just unlocked
+     * @param rank the rank of the subskill
+     */
+    public SkillUnlockNotificationTask(McMMOPlayer mcMMOPlayer, SubSkillType subSkillType, int rank)
+    {
+        this.mcMMOPlayer = mcMMOPlayer;
+        this.subSkillType = subSkillType;
+        this.rank = rank;
+    }
+    /**
+     * When an object implementing interface <code>Runnable</code> is used
+     * to create a thread, starting the thread causes the object's
+     * <code>run</code> method to be called in that separately executing
+     * thread.
+     * <p>
+     * The general contract of the method <code>run</code> is that it may
+     * take any action whatsoever.
+     *
+     * @see Thread#run()
+     */
+    @Override
+    public void run() {
+        //mcMMOPlayer.getPlayer().sendTitle(subSkillType.getLocaleName(), "Rank "+rank, 7, 20, 7);
+        NotificationManager.sendPlayerUnlockNotification(mcMMOPlayer, subSkillType);
+    }
+}

+ 9 - 0
src/main/java/com/gmail/nossr50/util/TextComponentFactory.java

@@ -516,6 +516,15 @@ public class TextComponentFactory {
             }
         }
     }
+
+    public static TextComponent getSubSkillUnlockedNotificationComponents(Player player, SubSkillType subSkillType)
+    {
+        TextComponent unlockMessage = new TextComponent("");
+        unlockMessage.setText(LocaleLoader.getString("JSON.SkillUnlockMessage", subSkillType.getLocaleName(), RankUtils.getRank(player, subSkillType)));
+        unlockMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, getSubSkillHoverComponent(player, subSkillType)));
+        unlockMessage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/"+subSkillType.getParentSkill().toString().toLowerCase()));
+        return unlockMessage;
+    }
 }
 
 

+ 16 - 0
src/main/java/com/gmail/nossr50/util/player/NotificationManager.java

@@ -4,9 +4,12 @@ import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.events.skills.McMMOPlayerNotificationEvent;
+import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.TextComponentFactory;
+import com.gmail.nossr50.util.skills.RankUtils;
 import net.md_5.bungee.api.ChatMessageType;
 import net.md_5.bungee.api.chat.TextComponent;
 import org.bukkit.Bukkit;
@@ -115,4 +118,17 @@ public class NotificationManager {
             player.sendTitle(title, subtitle, i1, i2, i3);
         }
     }
+
+    public static void sendPlayerUnlockNotification(McMMOPlayer mcMMOPlayer, SubSkillType subSkillType)
+    {
+        //CHAT MESSAGE
+        mcMMOPlayer.getPlayer().spigot().sendMessage(TextComponentFactory.getSubSkillUnlockedNotificationComponents(mcMMOPlayer.getPlayer(), subSkillType));
+
+        //ACTION BAR MESSAGE
+        /*if(AdvancedConfig.getInstance().doesNotificationUseActionBar(NotificationType.SUBSKILL_UNLOCKED))
+            mcMMOPlayer.getPlayer().spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(LocaleLoader.getString("JSON.SkillUnlockMessage",
+                    subSkillType.getLocaleName(),
+                    String.valueOf(RankUtils.getRank(mcMMOPlayer.getPlayer(),
+                            subSkillType)))));*/
+    }
 }

+ 56 - 5
src/main/java/com/gmail/nossr50/util/skills/RankUtils.java

@@ -1,16 +1,55 @@
 package com.gmail.nossr50.util.skills;
 
 import com.gmail.nossr50.config.RankConfig;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
+import com.gmail.nossr50.listeners.InteractionManager;
+import com.gmail.nossr50.runnables.skills.SkillUnlockNotificationTask;
 import com.gmail.nossr50.util.player.UserManager;
 import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
 public class RankUtils {
-    public static HashMap<String, HashMap<Integer, Integer>> subSkillRanks;
+    private static HashMap<String, HashMap<Integer, Integer>> subSkillRanks;
+
+    /**
+     *
+     * @param plugin plugin instance ref
+     * @param mcMMOPlayer target player
+     * @param primarySkillType
+     * @param newLevel the new level of this skill
+     */
+    public static void executeSkillUnlockNotifications(Plugin plugin, McMMOPlayer mcMMOPlayer, PrimarySkillType primarySkillType, int newLevel)
+    {
+        int count = 0;
+
+        for(SubSkillType subSkillType : primarySkillType.getSkillAbilities())
+        {
+            int playerRankInSkill = getRank(mcMMOPlayer.getPlayer(), subSkillType);
+
+            HashMap<Integer, Integer> innerMap = subSkillRanks.get(subSkillType.toString());
+
+            //If the skill doesn't have registered ranks gtfo
+            if(innerMap == null || innerMap.get(playerRankInSkill) == null)
+                return;
+
+            //The players level is the exact level requirement for this skill
+            if(newLevel == innerMap.get(playerRankInSkill))
+            {
+                SkillUnlockNotificationTask skillUnlockNotificationTask = new SkillUnlockNotificationTask(mcMMOPlayer, subSkillType, newLevel);
+
+                skillUnlockNotificationTask.runTaskLater(plugin, ((count * 5) + 1) * 20);
+
+                count++;
+            }
+        }
+    }
 
     /* NEW SYSTEM */
     private static void addRanks(AbstractSubSkill abstractSubSkill)
@@ -39,6 +78,22 @@ public class RankUtils {
         }
     }
 
+    /**
+     * Populates the ranks for every skill we know about
+     */
+    public static void populateRanks()
+    {
+        for(SubSkillType subSkillType : SubSkillType.values())
+        {
+            addRanks(subSkillType);
+        }
+
+        for(AbstractSubSkill abstractSubSkill : InteractionManager.getSubSkillList())
+        {
+            addRanks(abstractSubSkill);
+        }
+    }
+
     /**
      * Returns whether or not the player has unlocked the first rank in target subskill
      * @param player the player
@@ -190,8 +245,6 @@ public class RankUtils {
 
         HashMap<Integer, Integer> rankMap = subSkillRanks.get(abstractSubSkill.getConfigKeyName());
 
-        //TODO: Remove this debug code
-        //System.out.println("[DEBUG]: Rank "+rank+" for "+subSkillName.toString()+" requires skill level "+getRankUnlockLevel(subSkillType, rank));
         rankMap.put(rank, getRankUnlockLevel(abstractSubSkill, rank));
     }
 
@@ -202,8 +255,6 @@ public class RankUtils {
 
         HashMap<Integer, Integer> rankMap = subSkillRanks.get(subSkillType.toString());
 
-        //TODO: Remove this debug code
-        //System.out.println("[DEBUG]: Rank "+rank+" for "+subSkillName.toString()+" requires skill level "+getRankUnlockLevel(subSkillType, rank));
         rankMap.put(rank, getRankUnlockLevel(subSkillType, rank));
     }
 

+ 2 - 1
src/main/resources/locale/locale_en_US.properties

@@ -46,6 +46,7 @@ JSON.URL.Patreon=Support nossr50 and his work for mcMMO on Patreon!
 JSON.URL.Spigot=The official mcMMO Spigot Resource Page!
 JSON.URL.Translation=Translate mcMMO into other languages!
 JSON.URL.Wiki=The official mcMMO wiki!
+JSON.SkillUnlockMessage=[[GOLD]][ mcMMO[[YELLOW]] @[[DARK_AQUA]]{0} [[GOLD]]Rank [[DARK_AQUA]]{1}[[GOLD]] Unlocked! ]
 
 #This is the message sent to players when an ability is activated
 JSON.Notification.SuperAbility={0}
@@ -95,7 +96,7 @@ XPBar.Taming=Taming Lv.[[GOLD]]{0}
 XPBar.Unarmed=Unarmed Lv.[[GOLD]]{0}
 XPBar.Woodcutting=Woodcutting Lv.[[GOLD]]{0}
 #This is just a preset template that gets used if the 'ExtraDetails' setting is turned on in experience.yml (off by default), you can ignore this template and just edit the strings above
-XPBar.Complex.Template={0} [[GRAY]] {4}[[WHITE]]% [[GRAY]]([[WHITE]]{1}[[GRAY]]/[[WHITE]]{2}[[GRAY]])
+XPBar.Complex.Template={0} [[DARK_AQUA]] {4}[[WHITE]]% [[DARK_AQUA]]([[WHITE]]{1}[[DARK_AQUA]]/[[WHITE]]{2}[[DARK_AQUA]])
 # XP BAR Allows for the following variables -- {0} = Skill Level, {1} Current XP, {2} XP Needed for next level, {3} Power Level, {4} Percentage of Level
 # Make sure you turn on Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained if you want the XP bar title to update every time a player gains XP!
 # END STYLING