new mmoinfo command and JSON click events

This commit is contained in:
nossr50 2019-01-10 01:17:47 -08:00
parent 0cb9bbb530
commit d5a4103858
14 changed files with 285 additions and 24 deletions

View File

@ -13,12 +13,13 @@ Version 2.1.0
+ You can now disable specific skills in coreskills.yml without the need for permissions
+ Added links to mcMMO related websites to various commands
+ Certain elements of mcMMO's UI have been restyled
+ added the subtext "Overhaul Era" to various locations until 3.0.0 comes out
+ Added the tagline "Overhaul Era" to various locations until 3.0.0 comes out
+ (Config) New config file added coreskills.yml
+ (Config) Added rank settings for the new Woodcutting skill
+ (Config) Added configurable parameters for the new Tree Feller
+ (Config) Added classic toggle for Tree Feller
+ (Chat) Added ability for admins to spy on party chat (off unless toggled on)
+ (Commands) Added new info command /mmoinfo or /mcinfo
+ (Commands) Added toggle command /mcchatspy
+ (API) Added many missing SubSkills to SubSkillType class
+ (Permissions) Added permission node mcmmo.commands.mcchatspy & mcmmo.commands.mcchatspy.others
@ -48,11 +49,13 @@ Version 2.1.0
! (Config) Axes.CriticalHit in advanced.yml is now Axes.CriticalStrikes
! (Config) Archery's Skill Shot now uses RankDamageMultiplier for its damage bonus calculations
! (Config) Axe's Axe mastery now uses RankDamageMultiplier for its damage bonus calculations
+ (Permissions) Added mcmmo.commands.mmoinfo for the new mmoinfo/mcinfo command
! (Permissions) Replaced the old Double Drop permission node for woodcutting with a new Harvest Lumber permission node
! (Permissions) Fast Food Service permission node renamed to mcmmo.ability.taming.fastfoodservice
! (Permissions) Counter Attack permission node renamed to mcmmo.ability.swords.counterattack
! (Permissions) Arrow Deflect permission node renamed to mcmmo.ability.unarmed.arrowdeflect
! (Permissions) Iron Arm Style permission node renamed to mcmmo.ability.unarmed.ironarmstyle
! (Locale) The descriptions of a few skills have changed
! (Locale) Removed redundant information from some skill names and descriptions en_US (other locales will need to be updated)
! (Locale) SubSkill locale keys are now located at {ParentSkill}.SubSkill.SubSkillName
! (Locale) Super Abilities no longer have (ABILITY) in their Skill.Effect strings

View File

@ -0,0 +1,80 @@
package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.listeners.InteractionManager;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.TextComponentFactory;
import com.google.common.collect.ImmutableList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
/**
* This is the command that retrieves data about skills from in-game sources
*/
public class MmoInfo implements TabExecutor {
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
if(commandSender instanceof Player)
{
Player player = (Player) commandSender;
if(Permissions.mmoinfo(player))
{
if(args == null || args[0] == null)
return false;
//Real skill
if(InteractionManager.getAbstractByName(args[0]) != null || PrimarySkill.SUBSKILL_NAMES.contains(args[0]))
{
displayInfo(player, args[0]);
return true;
}
//Not a real skill
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.NoMatch"));
}
}
return false;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
switch (args.length) {
case 1:
return StringUtil.copyPartialMatches(args[0], PrimarySkill.SUBSKILL_NAMES, new ArrayList<String>(PrimarySkill.SUBSKILL_NAMES.size()));
default:
return ImmutableList.of();
}
}
private void displayInfo(Player player, String subSkillName)
{
System.out.println("[mcMMO] Debug: Grabbing info for skill "+subSkillName);
//Check to see if the skill exists in the new system
AbstractSubSkill abstractSubSkill = InteractionManager.getAbstractByName(subSkillName);
if(abstractSubSkill != null)
{
/* New System Skills are programmable */
abstractSubSkill.printInfo(player);
//TextComponentFactory.sendPlayerUrlHeader(player);
} else {
/*
* Skill is only in the old system
*/
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", subSkillName));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.OldSkill"));
//TextComponentFactory.sendPlayerUrlHeader(player);
}
}
}

View File

@ -59,6 +59,7 @@ public enum PrimarySkill {
private List<SubSkillType> subSkillTypes;
public static final List<String> SKILL_NAMES;
public static final List<String> SUBSKILL_NAMES;
public static final List<PrimarySkill> CHILD_SKILLS;
public static final List<PrimarySkill> NON_CHILD_SKILLS;
@ -71,6 +72,7 @@ public enum PrimarySkill {
List<PrimarySkill> childSkills = new ArrayList<PrimarySkill>();
List<PrimarySkill> nonChildSkills = new ArrayList<PrimarySkill>();
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> subSkillNames = new ArrayList<>();
for (PrimarySkill skill : values()) {
if (skill.isChildSkill()) {
@ -80,11 +82,16 @@ public enum PrimarySkill {
nonChildSkills.add(skill);
}
for(SubSkillType subSkillType : skill.subSkillTypes)
{
subSkillNames.add(subSkillType.getNiceNameNoSpaces(subSkillType));
}
names.add(skill.getName());
}
Collections.sort(names);
SKILL_NAMES = ImmutableList.copyOf(names);
SUBSKILL_NAMES = ImmutableList.copyOf(subSkillNames);
CHILD_SKILLS = ImmutableList.copyOf(childSkills);
NON_CHILD_SKILLS = ImmutableList.copyOf(nonChildSkills);

View File

@ -195,6 +195,16 @@ public enum SubSkillType {
return LocaleLoader.getString(StringUtils.getCapitalized(getParentSkill().toString())+".SkillName");
}
/**
* Gets the "nice" name of the subskill without spaces
* @param subSkillType target subskill
* @return the "nice" name without spaces
*/
public String getNiceNameNoSpaces(SubSkillType subSkillType)
{
return getConfigName(subSkillType.toString());
}
/**
* This finds the substring index for our SubSkillType's name after its parent name prefix
* @param subSkillName The name to process

View File

@ -6,6 +6,8 @@ import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Rank;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.SubSkill;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.SubSkillProperties;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.TextComponentFactory;
import org.bukkit.entity.Player;
public abstract class AbstractSubSkill implements SubSkill, Interaction, Rank, SubSkillProperties {
/*
@ -40,4 +42,20 @@ public abstract class AbstractSubSkill implements SubSkill, Interaction, Rank, S
//TODO: This might be troublesome...
return CoreSkillsConfig.getInstance().isSkillEnabled(this);
}
/**
* Prints detailed info about this subskill to the player
*
* @param player the target player
*/
@Override
public void printInfo(Player player) {
/* DEFAULT SETTINGS PRINT THE BARE MINIMUM */
//TextComponentFactory.sendPlayerUrlHeader(player);
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", getConfigKeyName()));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
}
}

View File

@ -29,7 +29,6 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.ItemStack;
public class Roll extends AcrobaticsSubSkill implements RandomChance {
private int fallTries = 0;
protected Location lastFallLocation;
@ -137,7 +136,6 @@ public class Roll extends AcrobaticsSubSkill implements RandomChance {
* Append the messages
*/
/*componentBuilder.append(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Acrobatics.Effect.2"), LocaleLoader.getString("Acrobatics.Effect.3")));
componentBuilder.append("\n");*/
@ -319,4 +317,83 @@ public class Roll extends AcrobaticsSubSkill implements RandomChance {
public int getNumRanks() {
return 0;
}
/**
* Prints detailed info about this subskill to the player
*
* @param player the target player
*/
@Override
public void printInfo(Player player) {
//Header
super.printInfo(player);
//Start the description string.
//player.sendMessage(getDescription());
//Player stats
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Stats",
LocaleLoader.getString("Acrobatics.SubSkill.Roll.Stats", getStats(player)[0], getStats(player)[1])));
//Mechanics
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mechanics"));
player.sendMessage(getMechanics());
}
/**
* Returns a collection of strings about how a skill works
*
* @return
*/
@Override
public String getMechanics() {
//Vars passed to locale
//0 = chance to roll at half max level
//1 = chance to roll with grace at half max level
//2 = level where maximum bonus is reached
//3 = additive chance to succeed per level
/*
Roll:
# ChanceMax: Maximum chance of rolling when on <MaxBonusLevel> or higher
# MaxBonusLevel: On this level or higher, the roll chance will not go higher than <ChanceMax>
# DamageThreshold: The max damage a player can negate with a roll
ChanceMax: 100.0
MaxBonusLevel: 100
DamageThreshold: 7.0
*/
double rollChanceHalfMax, graceChanceHalfMax, maxBonusLevel, curve, damageThreshold, chancePerLevel;
curve = AdvancedConfig.getInstance().getMaxChance(this);
maxBonusLevel = (double) AdvancedConfig.getInstance().getMaxBonusLevel(this);
//Chance
rollChanceHalfMax = 100 * SkillUtils.getChanceOfSuccess(maxBonusLevel / 2, maxBonusLevel, curve);
graceChanceHalfMax = 100 * SkillUtils.getChanceOfSuccess(maxBonusLevel / 2, maxBonusLevel, curve / 2);
damageThreshold = AdvancedConfig.getInstance().getRollDamageThreshold();
chancePerLevel = (1/curve) * maxBonusLevel;
return LocaleLoader.getString("Acrobatics.SubSkill.Roll.Mechanics", rollChanceHalfMax, graceChanceHalfMax, maxBonusLevel, chancePerLevel, damageThreshold);
}
/**
* Get an array of various stats for a player
*
* @param player target player
* @return stat array for target player for this skill
*/
@Override
public Double[] getStats(Player player)
{
double curve, maxBonusLevel, playerChanceRoll, playerChanceGrace;
curve = AdvancedConfig.getInstance().getMaxChance(this);
maxBonusLevel = (double) AdvancedConfig.getInstance().getMaxBonusLevel(this);
playerChanceRoll = 100 * SkillUtils.getChanceOfSuccess(UserManager.getPlayer(player).getSkillLevel(getPrimarySkill()), maxBonusLevel, curve);
playerChanceGrace = 100 * SkillUtils.getChanceOfSuccess(UserManager.getPlayer(player).getSkillLevel(getPrimarySkill()), maxBonusLevel, curve / 2);
Double[] stats = { playerChanceRoll, playerChanceGrace};
return stats;
}
}

View File

@ -4,6 +4,8 @@ import com.gmail.nossr50.datatypes.skills.interfaces.Skill;
import net.md_5.bungee.api.chat.ComponentBuilder;
import org.bukkit.entity.Player;
import java.util.ArrayList;
public interface SubSkill extends Skill {
/**
* Grabs the permission node for this skill
@ -11,6 +13,19 @@ public interface SubSkill extends Skill {
*/
String getPermissionNode();
/**
* Returns a collection of strings about how a skill works
* @return
*/
String getMechanics();
/**
* Get an array of various stats for a player
* @param player target player
* @return stat array for target player for this skill
*/
Double[] getStats(Player player);
/**
* Checks if a player has permission to use this skill
* @param player target player
@ -55,4 +70,10 @@ public interface SubSkill extends Skill {
* @return true if enabled
*/
boolean isEnabled();
/**
* Prints detailed info about this subskill to the player
* @param player the target player
*/
void printInfo(Player player);
}

View File

@ -19,6 +19,7 @@ import java.util.HashMap;
public class InteractionManager {
private static HashMap<InteractType, ArrayList<Interaction>> interactRegister;
private static HashMap<String, AbstractSubSkill> subSkillNameMap; //Used for mmoinfo optimization
private static ArrayList<AbstractSubSkill> subSkillList;
/**
@ -27,13 +28,16 @@ public class InteractionManager {
*/
public static void registerSubSkill(AbstractSubSkill abstractSubSkill)
{
//Init map
/* INIT MAPS */
if(interactRegister == null)
interactRegister = new HashMap<>();
if(subSkillList == null)
subSkillList = new ArrayList<>();
if(subSkillNameMap == null)
subSkillNameMap = new HashMap<>();
//Store a unique copy of each subskill
if(!subSkillList.contains(abstractSubSkill))
subSkillList.add(abstractSubSkill);
@ -47,12 +51,27 @@ public class InteractionManager {
//Register skill
arrayRef.add(abstractSubSkill);
//TEST
//interactRegister.put(abstractSubSkill.getInteractType(), arrayRef);
String lowerCaseName = abstractSubSkill.getConfigKeyName().toLowerCase();
//Register in name map
if(subSkillNameMap.get(lowerCaseName) == null)
subSkillNameMap.put(lowerCaseName, abstractSubSkill);
System.out.println("[mcMMO] registered subskill: "+ abstractSubSkill.getConfigKeyName());
}
/**
* Grabs the registered abstract skill by its name
* Is not case sensitive
* @param name name of subskill, not case sensitive
* @return null if the subskill is not registered
*/
public static AbstractSubSkill getAbstractByName(String name)
{
return subSkillNameMap.get(name.toLowerCase());
}
/**
* Processes the associated Interactions for this event
* @param event target event

View File

@ -43,6 +43,7 @@ public final class Permissions {
* COMMANDS
*/
public static boolean mmoinfo(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mmoinfo"); }
public static boolean addlevels(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.addlevels"); }
public static boolean addlevelsOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.addlevels.others"); }

View File

@ -252,6 +252,7 @@ public class TextComponentFactory {
//Insertion
textComponent.setInsertion(skillName);
textComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/mmoinfo "+subSkillType.getNiceNameNoSpaces(subSkillType)));
subSkillTextComponents.put(key, textComponent);
return subSkillTextComponents.get(key);
@ -285,6 +286,7 @@ public class TextComponentFactory {
//Insertion
textComponent.setInsertion(skillName);
textComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/mmoinfo "+abstractSubSkill.getConfigKeyName()));
subSkillTextComponents.put(key, textComponent);
return subSkillTextComponents.get(key);
@ -295,7 +297,6 @@ public class TextComponentFactory {
private static BaseComponent[] getBaseComponent(Player player, AbstractSubSkill abstractSubSkill)
{
int curRank = RankUtils.getRank(player, abstractSubSkill);
String key = abstractSubSkill.getConfigKeyName();

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import com.gmail.nossr50.commands.chat.McChatSpy;
import com.gmail.nossr50.commands.skills.*;
import org.bukkit.command.PluginCommand;
import com.gmail.nossr50.mcMMO;
@ -37,21 +38,6 @@ import com.gmail.nossr50.commands.player.MccooldownCommand;
import com.gmail.nossr50.commands.player.McrankCommand;
import com.gmail.nossr50.commands.player.McstatsCommand;
import com.gmail.nossr50.commands.player.MctopCommand;
import com.gmail.nossr50.commands.skills.AcrobaticsCommand;
import com.gmail.nossr50.commands.skills.AlchemyCommand;
import com.gmail.nossr50.commands.skills.ArcheryCommand;
import com.gmail.nossr50.commands.skills.AxesCommand;
import com.gmail.nossr50.commands.skills.ExcavationCommand;
import com.gmail.nossr50.commands.skills.FishingCommand;
import com.gmail.nossr50.commands.skills.HerbalismCommand;
import com.gmail.nossr50.commands.skills.MiningCommand;
import com.gmail.nossr50.commands.skills.RepairCommand;
import com.gmail.nossr50.commands.skills.SalvageCommand;
import com.gmail.nossr50.commands.skills.SmeltingCommand;
import com.gmail.nossr50.commands.skills.SwordsCommand;
import com.gmail.nossr50.commands.skills.TamingCommand;
import com.gmail.nossr50.commands.skills.UnarmedCommand;
import com.gmail.nossr50.commands.skills.WoodcuttingCommand;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
import com.gmail.nossr50.locale.LocaleLoader;
@ -170,6 +156,15 @@ public final class CommandRegistrationManager {
command.setExecutor(new McgodCommand());
}
private static void registerMmoInfoCommand() {
PluginCommand command = mcMMO.p.getCommand("mmoinfo");
command.setDescription(LocaleLoader.getString("Commands.Description.mmoinfo"));
command.setPermission("mcmmo.commands.mmoinfo");
command.setPermissionMessage(permissionsMessage);
command.setUsage(LocaleLoader.getString("Commands.Usage.1", "mmoinfo", "[" + LocaleLoader.getString("Commands.Usage.SubSkill") + "]"));
command.setExecutor(new MmoInfo());
}
private static void registerMcChatSpyCommand() {
PluginCommand command = mcMMO.p.getCommand("mcchatspy");
command.setDescription(LocaleLoader.getString("Commands.Description.mcchatspy"));
@ -441,6 +436,7 @@ public final class CommandRegistrationManager {
public static void registerCommands() {
// Generic Commands
registerMmoInfoCommand();
registerMcImportCommand();
registerKrakenCommand();
registerMcabilityCommand();

View File

@ -311,6 +311,19 @@ public class SkillUtils {
}
}
public static double getChanceOfSuccess(int skillLevel, double maxLevelBonus, double curve)
{
return getChanceOfSuccess((double) skillLevel, maxLevelBonus, curve);
}
public static double getChanceOfSuccess(double skillLevel, double maxLevelBonus, double curve)
{
if(skillLevel > maxLevelBonus)
return maxLevelBonus / curve;
return skillLevel / curve;
}
/* NEW VERSION */
public static boolean isActivationSuccessful(SkillActivationType skillActivationType, AbstractSubSkill abstractSubSkill, Player player, double maxChance, int maxBonusLevel)
{

View File

@ -40,10 +40,12 @@ JSON.Acrobatics.SubSkill.Roll.Details.Tips=If you hold sneak while falling you c
Acrobatics.Ability.Proc=[[GREEN]]**Graceful Landing**
Acrobatics.Combat.Proc=[[GREEN]]**Dodged**
Acrobatics.DodgeChance=[[RED]]Dodge Chance: [[YELLOW]]{0}
Acrobatics.SubSkill.Roll.Stats=[[GOLD]]Roll Chance [[YELLOW]]{0}%[[GOLD]] Graceful Roll Chance[[YELLOW]] {1}%
Acrobatics.SubSkill.Roll.Name=Roll
Acrobatics.SubSkill.Roll.Description=Reduces or Negates fall damage
Acrobatics.SubSkill.Roll.Description=Land strategically to avoid damage.
Acrobatics.SubSkill.Roll.Chance=[[RED]]Roll Chance: [[YELLOW]]{0}
Acrobatics.SubSkill.Roll.GraceChance=[[RED]]Graceful Roll Chance: [[YELLOW]]{0}
Acrobatics.SubSkill.Roll.Mechanics=[[GRAY]]Rolling is an active Sub-Skill with a passive component.\nWhenever you take fall damage you have a chance to completely negate the damage based on your skill level, at level 50 you have a [[YELLOW]]{0}%[[GRAY]] chance to prevent damage, and [[YELLOW]]{1}%[[GRAY]] if you activate Graceful Roll.\nThe chance for success is scaled against your skill level in a linear curve until level [[YELLOW]]{2}[[GRAY]] where it maxes out, every level in Acrobatics gives you a [[YELLOW]]{3}%[[GRAY]] chance to succeed.\nBy holding the sneak button you can double your odds to avoid fall damage and avoid up to twice the fall damage! Holding sneak will transform a normal roll into a Graceful Roll.\nRolling will only prevent up to [[RED]]{4}[[GRAY]] damage.
Acrobatics.SubSkill.GracefulRoll.Name=Graceful Roll
Acrobatics.SubSkill.GracefulRoll.Description=Twice as effective as a normal Roll
Acrobatics.SubSkill.Dodge.Name=Dodge
@ -607,7 +609,15 @@ Commands.Usage.Password=password
Commands.Usage.Player=player
Commands.Usage.Rate=rate
Commands.Usage.Skill=skill
Commands.Usage.SubSkill=subskill
Commands.Usage.XP=xp
Commands.MmoInfo.NoMatch=That subskill doesn't exist!
Commands.MmoInfo.Header=[[DARK_AQUA]]-=[]=====[][[GOLD]] MMO Info [[DARK_AQUA]][]=====[]=-
Commands.MmoInfo.SubSkillHeader=[[GOLD]]Name:[[YELLOW]] {0}
Commands.MmoInfo.DetailsHeader=[[DARK_AQUA]]-=[]=====[][[GREEN]] Details [[DARK_AQUA]][]=====[]=-
Commands.MmoInfo.OldSkill=[[GRAY]]mcMMO skills are being converted into an improved modular skill system, unfortunately this skill has not been converted yet and lacks detailed stats. The new system will allow for faster release times for new mcMMO skills and greater flexibility with existing skills.
Commands.MmoInfo.Mechanics=[[DARK_AQUA]]-=[]=====[][[GOLD]] Mechanics [[DARK_AQUA]][]=====[]=-
Commands.MmoInfo.Stats=[[RED]]STATS: {0}
mcMMO.NoInvites=[[RED]]You have no invites at this time
mcMMO.NoPermission=[[DARK_RED]]Insufficient permissions.
mcMMO.NoSkillNote=[[DARK_GRAY]]If you don't have access to a skill it will not be shown here.

View File

@ -12,13 +12,17 @@ description: >
author: nossr50
authors: [GJ, NuclearW, bm01, Glitchfinder, TfT_02, t00thpick1, Riking]
website: https://mcmmo.org
website: https://www.mcmmo.org
main: com.gmail.nossr50.mcMMO
softdepend: [CombatTag, HealthBar]
load: STARTUP
api-version: 1.13
commands:
mmoinfo:
aliases: [mcinfo]
description: Info pages for mcMMO
permission: mcmmo.commands.mmoinfo
xprate:
aliases: [mcxprate]
description: Modify the xp rate or start an event
@ -750,6 +754,7 @@ permissions:
mcmmo.commands.defaults:
description: Implies all default mcmmo.commands permissions.
children:
mcmmo.commands.mmoinfo: true
mcmmo.commands.acrobatics: true
mcmmo.commands.alchemy: true
mcmmo.commands.archery: true