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

@ -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)
{