mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Add /racelist show and /racelist rest
This commit is contained in:
parent
db53f4906e
commit
e97adc8841
13 changed files with 144 additions and 27 deletions
|
@ -19,6 +19,7 @@ import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
|||
import net.minecraft.command.argument.RegistryKeyArgumentType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.registry.Registry;
|
||||
|
@ -135,18 +136,19 @@ public record Race (Supplier<Composite> compositeSupplier, Availability availabi
|
|||
public boolean isPermitted(@Nullable PlayerEntity sender) {
|
||||
Set<String> whitelist = Unicopia.getConfig().speciesWhiteList.get();
|
||||
|
||||
return isUnset()
|
||||
return this == HUMAN
|
||||
|| isUnset()
|
||||
|| whitelist.isEmpty()
|
||||
|| whitelist.contains(getId().toString());
|
||||
}
|
||||
|
||||
public Race validate(PlayerEntity sender) {
|
||||
if (!isPermitted(sender)) {
|
||||
if (this == EARTH) {
|
||||
return HUMAN;
|
||||
Race alternative = this == EARTH ? HUMAN : EARTH.validate(sender);
|
||||
if (alternative != this && sender instanceof ServerPlayerEntity spe) {
|
||||
spe.sendMessageToClient(Text.translatable("respawn.reason.illegal_race", getDisplayName()), false);
|
||||
}
|
||||
|
||||
return EARTH.validate(sender);
|
||||
return alternative;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package com.minelittlepony.unicopia.client;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.*;
|
||||
|
||||
public interface FlowingText {
|
||||
public interface TextHelper {
|
||||
static Stream<Text> wrap(Text text, int maxWidth) {
|
||||
return MinecraftClient.getInstance().textRenderer.getTextHandler().wrapLines(text, maxWidth, Style.EMPTY).stream().map(line -> {
|
||||
MutableText compiled = Text.literal("");
|
||||
|
@ -17,4 +19,11 @@ public interface FlowingText {
|
|||
return compiled;
|
||||
});
|
||||
}
|
||||
|
||||
static Text join(Text delimiter, Iterable<? extends MutableText> elements) {
|
||||
MutableText initial = Text.empty();
|
||||
return StreamSupport.stream(elements.spliterator(), false).collect(Collectors.reducing(initial, (a, b) -> {
|
||||
return a == initial ? b : a.append(delimiter).append(b);
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ import com.minelittlepony.common.client.gui.GameGui;
|
|||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.*;
|
||||
import com.minelittlepony.unicopia.client.FlowingText;
|
||||
import com.minelittlepony.unicopia.client.TextHelper;
|
||||
import com.minelittlepony.unicopia.client.render.model.SphereModel;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
|
@ -195,7 +195,7 @@ public class DismissSpellScreen extends GameGui {
|
|||
tooltip.add(ScreenTexts.EMPTY);
|
||||
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.affinity", actualSpell.getAffinity().name()).formatted(actualSpell.getAffinity().getColor()));
|
||||
tooltip.add(ScreenTexts.EMPTY);
|
||||
tooltip.addAll(FlowingText.wrap(Text.translatable(actualSpell.getType().getTranslationKey() + ".lore").formatted(actualSpell.getAffinity().getColor()), 180).toList());
|
||||
tooltip.addAll(TextHelper.wrap(Text.translatable(actualSpell.getType().getTranslationKey() + ".lore").formatted(actualSpell.getAffinity().getColor()), 180).toList());
|
||||
if (spell instanceof TimedSpell timed) {
|
||||
tooltip.add(ScreenTexts.EMPTY);
|
||||
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.time_left", StringHelper.formatTicks(timed.getTimer().getTicksRemaining())));
|
||||
|
|
|
@ -14,7 +14,7 @@ import com.minelittlepony.unicopia.Debug;
|
|||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.client.FlowingText;
|
||||
import com.minelittlepony.unicopia.client.TextHelper;
|
||||
import com.minelittlepony.unicopia.client.gui.*;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookChapterList.*;
|
||||
import com.minelittlepony.unicopia.compat.trinkets.TrinketSlotBackSprites;
|
||||
|
@ -219,7 +219,7 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> imple
|
|||
|
||||
List<Text> tooltip = new ArrayList<>();
|
||||
tooltip.add(spell.type().getName());
|
||||
tooltip.addAll(FlowingText.wrap(Text.translatable(spell.type().getTranslationKey() + ".lore").formatted(spell.type().getAffinity().getColor()), 180).toList());
|
||||
tooltip.addAll(TextHelper.wrap(Text.translatable(spell.type().getTranslationKey() + ".lore").formatted(spell.type().getAffinity().getColor()), 180).toList());
|
||||
|
||||
|
||||
context.drawTooltip(textRenderer, tooltip, x, y);
|
||||
|
|
|
@ -9,7 +9,7 @@ import com.minelittlepony.common.client.gui.element.Label;
|
|||
import com.minelittlepony.common.client.gui.sprite.TextureSprite;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.*;
|
||||
import com.minelittlepony.unicopia.client.FlowingText;
|
||||
import com.minelittlepony.unicopia.client.TextHelper;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookChapterList.Chapter;
|
||||
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen.ImageButton;
|
||||
import com.minelittlepony.unicopia.container.SpellbookState;
|
||||
|
@ -191,7 +191,7 @@ public class SpellbookTraitDexPageContent implements SpellbookChapterList.Conten
|
|||
.setTextureSize(16, 16)
|
||||
.setSize(16, 16)
|
||||
.setTexture(trait.getSprite()));
|
||||
getStyle().setTooltip(Tooltip.of(FlowingText.wrap(trait.getTooltip(), 200).toList()));
|
||||
getStyle().setTooltip(Tooltip.of(TextHelper.wrap(trait.getTooltip(), 200).toList()));
|
||||
|
||||
onClick(sender -> Pony.of(MinecraftClient.getInstance().player).getDiscoveries().markRead(trait));
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package com.minelittlepony.unicopia.command;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.unicopia.*;
|
||||
import com.minelittlepony.unicopia.client.TextHelper;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
|
@ -15,8 +18,41 @@ class RacelistCommand {
|
|||
|
||||
static LiteralArgumentBuilder<ServerCommandSource> create() {
|
||||
return CommandManager.literal("racelist").requires(s -> s.hasPermissionLevel(3))
|
||||
.then(CommandManager.literal("show")
|
||||
.executes(context -> {
|
||||
context.getSource().sendFeedback(() -> {
|
||||
Set<String> whitelist = Unicopia.getConfig().speciesWhiteList.get();
|
||||
if (whitelist.isEmpty()) {
|
||||
return Text.translatable("commands.racelist.inactive");
|
||||
}
|
||||
Set<MutableText> allowed = new HashSet<>();
|
||||
Set<MutableText> unallowed = new HashSet<>();
|
||||
Race.REGISTRY.forEach(race -> {
|
||||
(race.isPermitted(null) ? allowed : unallowed).add(Text.translatable("commands.racelist.get.list_item",
|
||||
race.getDisplayName(),
|
||||
Text.literal(race.getId().toString()).formatted(Formatting.GRAY)
|
||||
));
|
||||
});
|
||||
|
||||
return Text.translatable("commands.racelist.get.allowed", allowed.size()).formatted(Formatting.YELLOW)
|
||||
.append("\n").append(TextHelper.join(Text.literal("\n"), allowed))
|
||||
.append("\n")
|
||||
.append(Text.translatable("commands.racelist.get.not_allowed", unallowed.size()).formatted(Formatting.YELLOW))
|
||||
.append("\n").append(TextHelper.join(Text.literal("\n"), unallowed));
|
||||
}, false);
|
||||
return 0;
|
||||
})
|
||||
)
|
||||
.then(CommandManager.literal("reset")
|
||||
.executes(context -> {
|
||||
Unicopia.getConfig().speciesWhiteList.get().clear();
|
||||
Unicopia.getConfig().save();
|
||||
context.getSource().sendFeedback(() -> Text.translatable("commands.racelist.clear.success").formatted(Formatting.GREEN), false);
|
||||
return 0;
|
||||
})
|
||||
)
|
||||
.then(CommandManager.literal("allow")
|
||||
.then(CommandManager.argument("race", Race.argument())
|
||||
.then(CommandManager.argument("race", Race.argument()).suggests(UCommandSuggestion.ALL_RACE_SUGGESTIONS)
|
||||
.executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), Race.fromArgument(context, "race"), "allowed", race -> {
|
||||
|
||||
if (race.isUnset()) {
|
||||
|
@ -31,7 +67,7 @@ class RacelistCommand {
|
|||
}))
|
||||
))
|
||||
.then(CommandManager.literal("disallow")
|
||||
.then(CommandManager.argument("race", Race.argument())
|
||||
.then(CommandManager.argument("race", Race.argument()).suggests(UCommandSuggestion.ALL_RACE_SUGGESTIONS)
|
||||
.executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), Race.fromArgument(context, "race"), "disallowed", race -> {
|
||||
boolean result = Unicopia.getConfig().speciesWhiteList.get().remove(race.getId().toString());
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.minelittlepony.unicopia.entity.player.Pony;
|
|||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgTribeSelect;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
|
||||
import net.minecraft.command.argument.EntityArgumentType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
|
@ -38,13 +37,13 @@ class SpeciesCommand {
|
|||
.executes(context -> get(context.getSource(), EntityArgumentType.getPlayer(context, "target"), false))
|
||||
))
|
||||
.then(CommandManager.literal("set")
|
||||
.then(CommandManager.argument("race", Race.argument())
|
||||
.then(CommandManager.argument("race", Race.argument()).suggests(UCommandSuggestion.ALL_RACE_SUGGESTIONS)
|
||||
.executes(context -> set(context.getSource(), context.getSource().getPlayer(), Race.fromArgument(context, "race"), true))
|
||||
.then(CommandManager.argument("target", EntityArgumentType.player())
|
||||
.executes(context -> set(context.getSource(), EntityArgumentType.getPlayer(context, "target"), Race.fromArgument(context, "race"), false)))
|
||||
))
|
||||
.then(CommandManager.literal("describe")
|
||||
.then(CommandManager.argument("race", Race.argument())
|
||||
.then(CommandManager.argument("race", Race.argument()).suggests(UCommandSuggestion.ALL_RACE_SUGGESTIONS)
|
||||
.executes(context -> describe(context.getSource().getPlayer(), Race.fromArgument(context, "race")))
|
||||
))
|
||||
.then(CommandManager.literal("list")
|
||||
|
@ -60,7 +59,7 @@ class SpeciesCommand {
|
|||
pony.setDirty();
|
||||
|
||||
if (race.isUnset()) {
|
||||
Channel.SERVER_SELECT_TRIBE.sendToPlayer(new MsgTribeSelect(Race.allPermitted(player), "gui.unicopia.tribe_selection.respawn"), (ServerPlayerEntity)player);
|
||||
Channel.SERVER_SELECT_TRIBE.sendToPlayer(new MsgTribeSelect(Race.allPermitted(player), "gui.unicopia.tribe_selection.welcome"), (ServerPlayerEntity)player);
|
||||
}
|
||||
|
||||
if (player == source.getPlayer()) {
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package com.minelittlepony.unicopia.command;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class UCommandSuggestion {
|
||||
public static final SuggestionProvider<ServerCommandSource> ALL_RACE_SUGGESTIONS = suggestFromRegistry(Race.REGISTRY_KEY);
|
||||
public static final SuggestionProvider<ServerCommandSource> ALLOWED_RACE_SUGGESTIONS = suggestFromRegistry(Race.REGISTRY_KEY, (context, race) -> race.isPermitted(context.getSource().getPlayer()));
|
||||
|
||||
public static <T> SuggestionProvider<ServerCommandSource> suggestFromRegistry(RegistryKey<? extends Registry<T>> registryKey, @Nullable BiPredicate<CommandContext<ServerCommandSource>, T> filter) {
|
||||
return (context, builder) -> {
|
||||
Registry<T> registry = context.getSource().getRegistryManager().get(registryKey);
|
||||
return suggestIdentifiers(
|
||||
filter == null ? registry : registry.stream().filter(v -> filter.test(context, v))::iterator,
|
||||
registry::getId,
|
||||
builder, registryKey.getValue().getNamespace());
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> SuggestionProvider<ServerCommandSource> suggestFromRegistry(RegistryKey<? extends Registry<T>> registryKey) {
|
||||
return suggestFromRegistry(registryKey, null);
|
||||
}
|
||||
|
||||
public static <T> CompletableFuture<Suggestions> suggestIdentifiers(Iterable<T> candidates, Function<T, Identifier> idFunc, SuggestionsBuilder builder, String defaultNamespace) {
|
||||
forEachMatching(candidates, builder.getRemaining().toLowerCase(Locale.ROOT), idFunc, id -> builder.suggest(idFunc.apply(id).toString()), defaultNamespace);
|
||||
return builder.buildFuture();
|
||||
}
|
||||
|
||||
public static <T> void forEachMatching(Iterable<T> candidates, String input, Function<T, Identifier> idFunc, Consumer<T> consumer, String defaultNamespace) {
|
||||
final boolean hasNamespaceDelimiter = input.indexOf(58) > -1;
|
||||
for (T object : candidates) {
|
||||
final Identifier id = idFunc.apply(object);
|
||||
if (hasNamespaceDelimiter) {
|
||||
if (CommandSource.shouldSuggest(input, id.toString())) {
|
||||
consumer.accept(object);
|
||||
}
|
||||
} else {
|
||||
if (CommandSource.shouldSuggest(input, id.getNamespace())
|
||||
|| (id.getNamespace().equals(defaultNamespace) && CommandSource.shouldSuggest(input, id.getPath()))
|
||||
) {
|
||||
consumer.accept(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ class WorldTribeCommand {
|
|||
return CommandManager.literal("worldtribe").requires(s -> s.hasPermissionLevel(3))
|
||||
.then(CommandManager.literal("get").executes(context -> get(context.getSource())))
|
||||
.then(CommandManager.literal("set")
|
||||
.then(CommandManager.argument("race", Race.argument())
|
||||
.then(CommandManager.argument("race", Race.argument()).suggests(UCommandSuggestion.ALLOWED_RACE_SUGGESTIONS)
|
||||
.executes(context -> set(context.getSource(), Race.fromArgument(context, "race")))));
|
||||
}
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
public void setSpecies(Race race) {
|
||||
race = race.validate(entity);
|
||||
Race current = getSpecies();
|
||||
entity.getDataTracker().set(RACE, Race.REGISTRY.getId(race.validate(entity)).toString());
|
||||
entity.getDataTracker().set(RACE, race.getId().toString());
|
||||
if (race != current) {
|
||||
clearSuppressedRace();
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
|
||||
public void setSuppressedRace(Race race) {
|
||||
entity.getDataTracker().set(SUPPRESSED_RACE, Race.REGISTRY.getId(race.validate(entity)).toString());
|
||||
entity.getDataTracker().set(SUPPRESSED_RACE, race.validate(entity).getId().toString());
|
||||
}
|
||||
|
||||
public void clearSuppressedRace() {
|
||||
|
|
|
@ -10,7 +10,7 @@ import com.minelittlepony.unicopia.Affinity;
|
|||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.client.FlowingText;
|
||||
import com.minelittlepony.unicopia.client.TextHelper;
|
||||
import com.minelittlepony.unicopia.entity.player.PlayerCharmTracker;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.group.MultiItem;
|
||||
|
@ -90,7 +90,7 @@ public class GemstoneItem extends Item implements MultiItem, EnchantableItem {
|
|||
line = line.formatted(Formatting.OBFUSCATED);
|
||||
}
|
||||
|
||||
lines.addAll(FlowingText.wrap(line, 180).toList());
|
||||
lines.addAll(TextHelper.wrap(line, 180).toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,11 @@ public record MsgRequestSpeciesChange (
|
|||
Pony player = Pony.of(sender);
|
||||
|
||||
if (force || player.getSpecies().isUnset()) {
|
||||
player.setSpecies(newRace.isPermitted(sender) ? newRace : UnicopiaWorldProperties.forWorld((ServerWorld)player.asWorld()).getDefaultRace());
|
||||
boolean permitted = newRace.isPermitted(sender);
|
||||
player.setSpecies(permitted ? newRace : UnicopiaWorldProperties.forWorld((ServerWorld)player.asWorld()).getDefaultRace());
|
||||
if (!permitted) {
|
||||
sender.sendMessageToClient(Text.translatable("respawn.reason.illegal_race", newRace.getDisplayName()), false);
|
||||
}
|
||||
|
||||
if (force) {
|
||||
if (sender.getWorld().getGameRules().getBoolean(UGameRules.ANNOUNCE_TRIBE_JOINS)) {
|
||||
|
|
|
@ -699,6 +699,7 @@
|
|||
"gui.unicopia.page_num": "%d of %d",
|
||||
|
||||
"respawn.reason.joined_new_tribe": "%1$s was reborn as a %2$s",
|
||||
"respawn.reason.illegal_race": "The %s race is not permitted by your server's configuration.",
|
||||
|
||||
"gui.unicopia.tribe_selection.respawn": "You have died.",
|
||||
"gui.unicopia.tribe_selection.respawn.journey": "But the end is not all, for at the end of every end is another beginning.",
|
||||
|
@ -1327,7 +1328,12 @@
|
|||
|
||||
"commands.racelist.illegal": "The default race %s cannot be used with this command.",
|
||||
"commands.racelist.allowed": "Added %1$s to the whitelist.",
|
||||
"commands.racelist.allowed.failed": "%1$s is already whitelisted.",
|
||||
"commands.racelist.get.allowed": "Allowed (%s):",
|
||||
"commands.racelist.get.not_allowed": "Not Allowed (%s):",
|
||||
"commands.racelist.get.list_item": "- %s (%s)",
|
||||
"commands.racelist.clear.success": "Disabled Whitelist",
|
||||
"commands.racelist.allowed.failed": "%1$s is already allowed.",
|
||||
"commands.racelist.inactive": "The allowlist is not active. Add races with /unicopia racelist allow <race> to configure it.",
|
||||
|
||||
"commands.racelist.disallowed": "Removed %1$s from the whitelist.",
|
||||
"commands.racelist.disallowed.failed": "%1$s is not on the whitelist.",
|
||||
|
@ -1335,7 +1341,6 @@
|
|||
"commands.worldtribe.success.get": "Default race for all new players is currently set to: %s",
|
||||
"commands.worldtribe.success.set": "Set default race for new players is now set to: %s",
|
||||
|
||||
"commands.disguise.usage": "/disguise <player> <entity> [nbt]",
|
||||
"commands.disguise.notfound": "The entity id '%s' does not exist.",
|
||||
"commands.disguise.removed": "Your disguise has been removed.",
|
||||
"commands.disguise.removed.self": "Removed own disguise.",
|
||||
|
|
Loading…
Reference in a new issue