Fixing a major bug with sub-skills not being shown when using commands

This commit is contained in:
nossr50 2020-11-04 12:05:29 -08:00
parent 5afaeb40a8
commit cb9c7acceb
3 changed files with 137 additions and 41 deletions

View File

@ -1,3 +1,7 @@
Version 2.1.153
Fixed a bug where most sub-skills were not being displayed when using a skills command (for example /taming)
Fixed a bug where some URL links were not being colored
Version 2.1.152 Version 2.1.152
Fixed a bug where Tree Feller would sometimes double drop blocks inappropriately Fixed a bug where Tree Feller would sometimes double drop blocks inappropriately
Fixed a bug with bleed damage calculations and player armor Fixed a bug with bleed damage calculations and player armor

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId> <groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId> <artifactId>mcMMO</artifactId>
<version>2.1.152</version> <version>2.1.153-SNAPSHOT</version>
<name>mcMMO</name> <name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url> <url>https://github.com/mcMMO-Dev/mcMMO</url>
<scm> <scm>
@ -202,17 +202,17 @@
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-gson</artifactId> <artifactId>adventure-text-serializer-gson</artifactId>
<version>4.1.1</version> <version>4.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId> <artifactId>adventure-api</artifactId>
<version>4.1.1</version> <version>4.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>
<artifactId>adventure-nbt</artifactId> <artifactId>adventure-nbt</artifactId>
<version>4.1.1</version> <version>4.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.kyori</groupId> <groupId>net.kyori</groupId>

View File

@ -22,11 +22,15 @@ import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
/** /**
* This class handles many of the JSON components that mcMMO makes and uses * This class handles many of the JSON components that mcMMO makes and uses
@ -105,49 +109,138 @@ public class TextComponentFactory {
), MessageType.SYSTEM); ), MessageType.SYSTEM);
} }
public static void sendPlayerSubSkillList(Player player, List<Component> textComponents) public static void sendPlayerSubSkillList(@NotNull Player player, @NotNull List<Component> subSkillComponents) {
{
TextComponent emptySpace = Component.space();
AtomicReference<Component> messageToSend = new AtomicReference<>();
int newLineCount = 0; //Hacky solution to wordwrap problems
final Audience audience = mcMMO.getAudiences().player(player); final Audience audience = mcMMO.getAudiences().player(player);
for (Component textComponent : textComponents) {
//Don't send more than 3 subskills per line to avoid MOST wordwrap problems
if(newLineCount > 2)
{
Component toSend = messageToSend.get();
if (toSend != null) {
audience.sendMessage(Identity.nil(), toSend.append(emptySpace));
}
messageToSend.set(null); //@ Signs, done for style
newLineCount = 0; Component space = Component.space();
} TextComponent atSignComponent = Component.text(LocaleLoader.getString("JSON.Hover.AtSymbolSkills"));
//Style the skills into @links
final String originalTxt = textComponent instanceof TextComponent ? ((TextComponent) textComponent).content() : "";
TextComponent.Builder stylizedText = Component.text().content(LocaleLoader.getString("JSON.Hover.AtSymbolSkills")); //Only send 3 sub-skills per line
addChild(stylizedText, originalTxt); Component[][] splitSubSkills = splitComponentsIntoGroups(subSkillComponents, 3);
ArrayList<Component> individualLinesToSend = new ArrayList<>();
if(textComponent.hoverEvent() != null) //Create each line
stylizedText.hoverEvent(textComponent.hoverEvent()); for (Component[] componentArray : splitSubSkills) {
individualLinesToSend.add(fromArray(componentArray, atSignComponent, space));
if(textComponent.clickEvent() != null)
stylizedText.clickEvent(textComponent.clickEvent());
messageToSend.set(stylizedText.build().append(emptySpace));
newLineCount++;
} }
Component toSend = messageToSend.get(); //Send each group
if (toSend != null) { for(Component curLine : individualLinesToSend) {
audience.sendMessage(Identity.nil(), toSend.append(emptySpace)); audience.sendMessage(Identity.nil(), curLine);
} }
} }
/**
* Makes a single component from an array of components, can optionally add prefixes and suffixes to come before and after each component
* @param componentsArray target array
* @return
*/
private static @NotNull Component fromArray(@NotNull Component[] componentsArray, @Nullable Component prefixComponent, @Nullable Component suffixComponent) {
TextComponent.Builder componentBuilder = Component.text();
for(Component component : componentsArray) {
if(component == null) //Individual elements can be null
continue;
if(prefixComponent != null)
componentBuilder.append(prefixComponent);
componentBuilder.append(component);
if(suffixComponent != null)
componentBuilder.append(suffixComponent);
}
return componentBuilder.build();
}
/**
* Takes a list of components and splits them into arrays each with a maximum element limit
* Individual elements in [][X] may be null
*
* @param components target component list
* @param groupsSize maximum size per array
* @return a 2D array with components split into groups
*/
private static @NotNull Component[][] splitComponentsIntoGroups(@NotNull List<Component> components, int groupsSize) {
int groupCount = (int) Math.ceil((double) components.size() / (double) groupsSize);
Component[][] splitGroups = new Component[groupCount][groupsSize];
int groupsFinished = 0;
while (groupsFinished < groupCount) {
//Fill group with members
for(int i = 0; i < groupsSize; i++) {
int indexOfPotentialMember = i + (groupsFinished * 3); //Groups don't always fill all members neatly
//Some groups won't have entirely non-null elements
if(indexOfPotentialMember > components.size()-1) {
break;
}
Component potentialMember = components.get(indexOfPotentialMember);
//Make sure the potential member exists because of rounding
if(potentialMember != null) {
splitGroups[groupsFinished][i] = potentialMember;
}
}
//Another group is finished
groupsFinished++;
}
return splitGroups;
}
// public static void sendPlayerSubSkillList(Player player, List<Component> textComponents)
// {
// TextComponent emptySpace = Component.space();
//
// AtomicReference<Component> messageToSend = new AtomicReference<>();
// int newLineCount = 0; //Hacky solution to wordwrap problems
//
// final Audience audience = mcMMO.getAudiences().player(player);
// for (Component textComponent : textComponents) {
// //Don't send more than 3 subskills per line to avoid MOST wordwrap problems
// if(newLineCount > 2)
// {
// Component toSend = messageToSend.get();
// if (toSend != null) {
// audience.sendMessage(Identity.nil(), toSend.append(emptySpace));
// }
//
// messageToSend.set(null);
// newLineCount = 0;
// }
// //Style the skills into @links
// final String originalTxt = textComponent instanceof TextComponent ? ((TextComponent) textComponent).content() : "";
//
// TextComponent.Builder stylizedText = Component.text().content(LocaleLoader.getString("JSON.Hover.AtSymbolSkills"));
// addChild(stylizedText, originalTxt);
//
// if(textComponent.hoverEvent() != null)
// stylizedText.hoverEvent(textComponent.hoverEvent());
//
// if(textComponent.clickEvent() != null)
// stylizedText.clickEvent(textComponent.clickEvent());
//
// messageToSend.set(stylizedText.build().append(emptySpace));
//
// newLineCount++;
// }
//
// Component toSend = messageToSend.get();
// if (toSend != null) {
// audience.sendMessage(Identity.nil(), toSend.append(emptySpace));
// }
// }
private static Component getWebLinkTextComponent(McMMOWebLinks webLinks) private static Component getWebLinkTextComponent(McMMOWebLinks webLinks)
{ {
TextComponent.Builder webTextComponent; TextComponent.Builder webTextComponent;
@ -201,8 +294,7 @@ public class TextComponentFactory {
} }
private static void addChild(ComponentBuilder<?, ?> webTextComponent, String childName) { private static void addChild(ComponentBuilder<?, ?> webTextComponent, String childName) {
TextComponent childComponent = Component.text(childName); TextComponent childComponent = Component.text(childName).color(NamedTextColor.BLUE);
childComponent.color(NamedTextColor.BLUE);
webTextComponent.append(childComponent); webTextComponent.append(childComponent);
} }