Skip to content

Commit

Permalink
Add ability for a "random" add or remove command
Browse files Browse the repository at this point in the history
Partial address for #51
  • Loading branch information
legobmw99 committed May 29, 2021
1 parent ae6f96e commit 10c71a9
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 68 deletions.
18 changes: 10 additions & 8 deletions src/main/java/com/legobmw99/allomancy/datagen/Languages.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public Languages(DataGenerator gen, String modid, String locale) {
super(gen, modid, locale);
}

private static String getDisplayName(Metal mt) {
return toTitleCase(mt.getName());
}

private static String toTitleCase(String in) {
return in.substring(0, 1).toUpperCase() + in.substring(1);
}

@Override
protected void addTranslations() {
add("itemGroup.allomancy", "Allomancy");
Expand Down Expand Up @@ -88,6 +96,8 @@ protected void addTranslations() {
add("commands.allomancy.addpower", "%s added Allomantic power %s");
add("commands.allomancy.removepower", "%s removed Allomantic power %s");
add("commands.allomancy.unrecognized", "Unrecognized Allomancy power: '%s'");
add("commands.allomancy.err_add", "Unable to add power %s, already had");
add("commands.allomancy.err_remove", "Unable to remove power %s, did not have");

for (DyeColor color : DyeColor.values()) {
for (Metal mt : Metal.values()) {
Expand All @@ -102,16 +112,8 @@ public String getName() {
return "Allomancy Language";
}

private static String getDisplayName(Metal mt) {
return toTitleCase(mt.getName());
}

private String getDisplayName(DyeColor color) {
String[] trans = color.getName().split("_");
return Arrays.stream(trans).map(Languages::toTitleCase).collect(Collectors.joining(" "));
}

private static String toTitleCase(String in) {
return in.substring(0, 1).toUpperCase() + in.substring(1);
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
package com.legobmw99.allomancy.modules.powers.command;

import com.legobmw99.allomancy.api.IAllomancyData;
import com.legobmw99.allomancy.modules.powers.data.AllomancyCapability;
import com.legobmw99.allomancy.modules.powers.network.AllomancyDataPacket;
import com.legobmw99.allomancy.network.Network;
import com.legobmw99.allomancy.util.Metal;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.tree.LiteralCommandNode;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.command.arguments.EntityArgument;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.util.NonNullConsumer;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;

public class AllomancyPowerCommand {

protected static final String[] names = new String[Metal.values().length + 1];
protected static final String[] names = new String[Metal.values().length + 2];
private static final DynamicCommandExceptionType ERROR_CANT_ADD = new DynamicCommandExceptionType(s -> new TranslationTextComponent("commands.allomancy.err_add", s));
private static final DynamicCommandExceptionType ERROR_CANT_REMOVE = new DynamicCommandExceptionType(s -> new TranslationTextComponent("commands.allomancy.err_remove", s));

static {
int i = 0;
for (Metal mt : Metal.values()) {
names[i++] = mt.getName();
}
names[i++] = "random";
names[i] = "all";

}

private static Predicate<CommandSource> permissions(int level) {
Expand All @@ -39,24 +49,28 @@ public static void register(CommandDispatcher<CommandSource> dispatcher) {
root.then(Commands
.literal("get")
.requires(permissions(0))
.executes(ctx -> getPowers(ctx, false))
.then(Commands.argument("targets", EntityArgument.players()).executes(ctx -> getPowers(ctx, true))));
.executes(ctx -> handleMultiPlayer(ctx, false, AllomancyPowerCommand::getPowers))
.then(Commands.argument("targets", EntityArgument.players()).executes(ctx -> handleMultiPlayer(ctx, true, AllomancyPowerCommand::getPowers))));

root.then(Commands
.literal("add")
.requires(permissions(2))
.then(Commands
.argument("type", AllomancyPowerType.INSTANCE)
.executes(ctx -> addPower(ctx, false))
.then(Commands.argument("targets", EntityArgument.players()).executes(ctx -> addPower(ctx, true)))));
.executes(ctx -> handleMultiPlayer(ctx, false, AllomancyPowerCommand::addPower))
.then(Commands
.argument("targets", EntityArgument.players())
.executes(ctx -> handleMultiPlayer(ctx, true, AllomancyPowerCommand::addPower)))));

root.then(Commands
.literal("remove")
.requires(permissions(2))
.then(Commands
.argument("type", AllomancyPowerType.INSTANCE)
.executes(ctx -> removePower(ctx, false))
.then(Commands.argument("targets", EntityArgument.players()).executes(ctx -> removePower(ctx, true)))));
.executes(ctx -> handleMultiPlayer(ctx, false, AllomancyPowerCommand::removePower))
.then(Commands
.argument("targets", EntityArgument.players())
.executes(ctx -> handleMultiPlayer(ctx, true, AllomancyPowerCommand::removePower)))));


LiteralCommandNode<CommandSource> command = dispatcher.register(root);
Expand All @@ -65,18 +79,28 @@ public static void register(CommandDispatcher<CommandSource> dispatcher) {
}


private static int getPowers(CommandContext<CommandSource> ctx, boolean hasPlayer) throws CommandSyntaxException {
/**
* Abstraction to handle possibly multiple players
*
* @param ctx Command context
* @param hasPlayer If true, command had player(s) in the "targets" argument
* @param toApply Function to apply to all players or sender
* @return The number of players successfully applied to
* @throws CommandSyntaxException
*/
private static int handleMultiPlayer(CommandContext<CommandSource> ctx,
boolean hasPlayer,
CheckedBiCon<CommandContext<CommandSource>, ServerPlayerEntity> toApply) throws CommandSyntaxException {
int i = 0;
if (hasPlayer) {
for (ServerPlayerEntity p : EntityArgument.getPlayers(ctx, "targets")) {
getPowers(ctx, p);
toApply.accept(ctx, p);
i++;
}
} else {
getPowers(ctx, ctx.getSource().getPlayerOrException());
toApply.accept(ctx, ctx.getSource().getPlayerOrException());
i = 1;
}

return i;
}

Expand All @@ -102,63 +126,67 @@ private static void getPowers(CommandContext<CommandSource> ctx, ServerPlayerEnt
ctx.getSource().sendSuccess(new TranslationTextComponent("commands.allomancy.getpowers", player.getDisplayName(), powers.toString()), true);
}

private static int addPower(CommandContext<CommandSource> ctx, boolean hasPlayer) throws CommandSyntaxException {
int i = 0;
if (hasPlayer) {
for (ServerPlayerEntity p : EntityArgument.getPlayers(ctx, "targets")) {
addPower(ctx, p);
i++;
}
} else {
addPower(ctx, ctx.getSource().getPlayerOrException());
i = 1;
}
return i;
private static void addPower(CommandContext<CommandSource> ctx, ServerPlayerEntity player) throws CommandSyntaxException {
handlePowerChange(ctx, player, IAllomancyData::setMistborn, data -> (mt -> !data.hasPower(mt)), mt -> (data -> data.addPower(mt)), ERROR_CANT_ADD::create,
"commands.allomancy.addpower");
}

private static void addPower(CommandContext<CommandSource> ctx, ServerPlayerEntity player) {
String type = ctx.getArgument("type", String.class);
player.getCapability(AllomancyCapability.PLAYER_CAP).ifPresent(data -> {
if (type.equalsIgnoreCase("all")) {
data.setMistborn();
} else {
Metal mt = Metal.valueOf(type.toUpperCase());
data.addPower(mt);
}

Network.sendTo(new AllomancyDataPacket(data, player), player);
});
ctx.getSource().sendSuccess(new TranslationTextComponent("commands.allomancy.addpower", player.getDisplayName(), type), true);
private static void removePower(CommandContext<CommandSource> ctx, ServerPlayerEntity player) throws CommandSyntaxException {
handlePowerChange(ctx, player, IAllomancyData::setUninvested, (data) -> data::hasPower, (mt) -> (data -> data.revokePower(mt)), ERROR_CANT_REMOVE::create,
"commands.allomancy.removepower");
}

private static int removePower(CommandContext<CommandSource> ctx, boolean hasPlayer) throws CommandSyntaxException {
int i = 0;
if (hasPlayer) {
for (ServerPlayerEntity p : EntityArgument.getPlayers(ctx, "targets")) {
removePower(ctx, p);
i++;
}
} else {
removePower(ctx, ctx.getSource().getPlayerOrException());
i = 1;
}
return i;
}
/**
* Function abstraction for both add and remove
*
* @param ctx The command context
* @param player The player
* @param all Function to call with 'all' type, either setMistborn or setUninvested
* @param filterFunction Either data -> data.hasMetal or its inverse
* @param single Either metal -> data.addPower or its inverse
* @param exception Function to create an exception
* @param success String used when successful
* @throws CommandSyntaxException
*/
private static void handlePowerChange(CommandContext<CommandSource> ctx,
ServerPlayerEntity player,
NonNullConsumer<IAllomancyData> all,
Function<IAllomancyData, Predicate<Metal>> filterFunction,
Function<Metal, NonNullConsumer<IAllomancyData>> single,
Function<String, CommandSyntaxException> exception,
String success) throws CommandSyntaxException {

private static void removePower(CommandContext<CommandSource> ctx, ServerPlayerEntity player) {
String type = ctx.getArgument("type", String.class);
player.getCapability(AllomancyCapability.PLAYER_CAP).ifPresent(data -> {
if (type.equalsIgnoreCase("all")) {
data.setUninvested();

if (type.equalsIgnoreCase("all")) {
player.getCapability(AllomancyCapability.PLAYER_CAP).ifPresent(all);
} else {
Predicate<Metal> filter = player.getCapability(AllomancyCapability.PLAYER_CAP).map(filterFunction::apply).orElse((m) -> false);

if (type.equalsIgnoreCase("random")) {
List<Metal> metalList = Arrays.asList(Metal.values());
Collections.shuffle(metalList);
Metal mt = metalList.stream().filter(filter).findFirst().orElseThrow(() -> exception.apply(type));
player.getCapability(AllomancyCapability.PLAYER_CAP).ifPresent(single.apply(mt));
} else {
Metal mt = Metal.valueOf(type.toUpperCase());
data.revokePower(mt);
if (filter.test(mt)) {
player.getCapability(AllomancyCapability.PLAYER_CAP).ifPresent(single.apply(mt));
} else {
throw exception.apply(type);
}
}
Network.sendTo(new AllomancyDataPacket(data, player), player);
});
}
Network.sync(player);

ctx.getSource().sendSuccess(new TranslationTextComponent(success, player.getDisplayName(), type), true);

ctx.getSource().sendSuccess(new TranslationTextComponent("commands.allomancy.removepower", player.getDisplayName(), type), true);
}


@FunctionalInterface
private interface CheckedBiCon<T, U> {
void accept(T t, U u) throws CommandSyntaxException;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,31 @@ public DefaultAllomancyData() {


public void tickBurning(ServerPlayerEntity player) {
boolean sync = false;
for (Metal metal : Metal.values()) {
if (this.isBurning(metal)) {
if (!this.hasPower(metal)) {
// put out any metals that the player shouldn't be able to burn
this.setBurning(metal, false);
Network.sync(this, player);
sync = true;
} else {
this.setBurnTime(metal, this.getBurnTime(metal) - 1);
if (this.getBurnTime(metal) <= 0) {
if (this.getAmount(metal) <= 0) {
this.setBurning(metal, false);
sync = true;
} else {
this.setAmount(metal, this.getAmount(metal) - 1);
}
this.setBurnTime(metal, MAX_BURN_TIME[metal.getIndex()]);
Network.sync(this, player);
}
}
}
}
if (sync) {
Network.sync(this, player);
}

}


Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/assets/allomancy/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@
"block.minecraft.banner.allomancy_zinc.white": "White Zinc Symbol",
"block.minecraft.banner.allomancy_zinc.yellow": "Yellow Zinc Symbol",
"commands.allomancy.addpower": "%s added Allomantic power %s",
"commands.allomancy.err_add": "Unable to add power %s, already had",
"commands.allomancy.err_remove": "Unable to remove power %s, did not have",
"commands.allomancy.getpowers": "%s currently has Allomantic powers: %s",
"commands.allomancy.removepower": "%s removed Allomantic power %s",
"commands.allomancy.unrecognized": "Unrecognized Allomancy power: '%s'",
Expand Down

0 comments on commit 10c71a9

Please sign in to comment.