Files
TiedUp-/src/main/java/com/tiedup/remake/commands/subcommands/MasterTestSubCommand.java
NotEvil fa5cfb913c feat(C-01): i18n main commands — 148 translatable keys
Phase 3: Migrate Component.literal() in all remaining command files.
- NPCCommand (34), CellCommand (33), SocialCommand (16), CollarCommand (25),
  KeyCommand (18), BountyCommand (6), KidnapSetCommand (2), CaptivityDebugCommand (7),
  InventorySubCommand (3), TestAnimSubCommand (2), MasterTestSubCommand (7), DebtSubCommand (8)
- Strip all section sign color codes, use .withStyle(ChatFormatting)
- 148 new keys in en_us.json (command.tiedup.*)
- Debug/dynamic strings intentionally kept as literal
2026-04-15 13:54:26 +02:00

247 lines
7.9 KiB
Java

package com.tiedup.remake.commands.subcommands;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.tiedup.remake.commands.CommandHelper;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.entities.ModEntities;
import com.tiedup.remake.entities.ai.master.MasterState;
import com.tiedup.remake.state.PlayerBindState;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.MobSpawnType;
/**
* Master/pet-play test sub-commands for /tiedup.
* Handles: mastertest, masterchair, mastertask
*/
@SuppressWarnings("null")
public class MasterTestSubCommand {
public static void register(
LiteralArgumentBuilder<CommandSourceStack> root
) {
// /tiedup mastertest
root.then(
Commands.literal("mastertest")
.requires(CommandHelper.REQUIRES_OP)
.executes(MasterTestSubCommand::mastertest)
);
// /tiedup masterchair
root.then(
Commands.literal("masterchair")
.requires(CommandHelper.REQUIRES_OP)
.executes(MasterTestSubCommand::masterchair)
);
// /tiedup mastertask <task>
root.then(
Commands.literal("mastertask")
.requires(CommandHelper.REQUIRES_OP)
.then(
Commands.argument("task", StringArgumentType.word())
.suggests((ctx, builder) -> {
for (MasterState s : MasterState.values()) {
builder.suggest(s.name().toLowerCase());
}
return builder.buildFuture();
})
.executes(MasterTestSubCommand::mastertask)
)
);
}
// Command Implementations
/**
* /tiedup mastertest
*
* Spawn a Master NPC nearby and immediately become its pet.
* For testing the pet play system without going through capture.
*/
private static int mastertest(CommandContext<CommandSourceStack> context)
throws CommandSyntaxException {
ServerPlayer player = context.getSource().getPlayerOrException();
ServerLevel level = context.getSource().getLevel();
double x = player.getX() + player.getLookAngle().x * 2;
double y = player.getY();
double z = player.getZ() + player.getLookAngle().z * 2;
EntityMaster master = ModEntities.MASTER.get().create(level);
if (master == null) {
context
.getSource()
.sendFailure(
Component.translatable("command.tiedup.master.spawn_failed")
);
return 0;
}
master.moveTo(x, y, z, player.getYRot() + 180F, 0.0F);
master.finalizeSpawn(
level,
level.getCurrentDifficultyAt(master.blockPosition()),
MobSpawnType.COMMAND,
null,
null
);
level.addFreshEntity(master);
master.setPetPlayer(player);
master.putPetCollar(player);
CommandHelper.syncPlayerState(
player,
PlayerBindState.getInstance(player)
);
String masterName = master.getNpcName();
if (masterName == null || masterName.isEmpty()) masterName = "Master";
String finalName = masterName;
context
.getSource()
.sendSuccess(
() ->
Component.translatable(
"command.tiedup.master.spawned", finalName
),
true
);
return 1;
}
/**
* /tiedup masterchair
*
* Force the nearest Master NPC into HUMAN_CHAIR state.
* Requires the player to be that Master's pet.
*/
private static int masterchair(CommandContext<CommandSourceStack> context)
throws CommandSyntaxException {
ServerPlayer player = context.getSource().getPlayerOrException();
EntityMaster master = findNearestMaster(player);
if (master == null) {
context
.getSource()
.sendFailure(
Component.translatable("command.tiedup.master.no_master_nearby")
);
return 0;
}
if (!master.hasPet()) {
master.setPetPlayer(player);
master.putPetCollar(player);
CommandHelper.syncPlayerState(
player,
PlayerBindState.getInstance(player)
);
}
master.setMasterState(MasterState.HUMAN_CHAIR);
String masterName = master.getNpcName();
if (masterName == null || masterName.isEmpty()) masterName = "Master";
String finalName = masterName;
context
.getSource()
.sendSuccess(
() ->
Component.translatable(
"command.tiedup.master.forced_state", finalName, "HUMAN_CHAIR"
),
true
);
return 1;
}
/**
* /tiedup mastertask <state>
*
* Force the nearest Master NPC into any MasterState.
* Useful for testing specific master behaviors.
*/
private static int mastertask(CommandContext<CommandSourceStack> context)
throws CommandSyntaxException {
ServerPlayer player = context.getSource().getPlayerOrException();
String taskName = StringArgumentType.getString(context, "task");
MasterState targetState;
try {
targetState = MasterState.valueOf(taskName.toUpperCase());
} catch (IllegalArgumentException e) {
context
.getSource()
.sendFailure(
Component.translatable("command.tiedup.master.unknown_state", taskName)
);
return 0;
}
EntityMaster master = findNearestMaster(player);
if (master == null) {
context
.getSource()
.sendFailure(
Component.translatable("command.tiedup.master.no_master_nearby")
);
return 0;
}
if (!master.hasPet()) {
master.setPetPlayer(player);
master.putPetCollar(player);
CommandHelper.syncPlayerState(
player,
PlayerBindState.getInstance(player)
);
}
master.setMasterState(targetState);
String masterName = master.getNpcName();
if (masterName == null || masterName.isEmpty()) masterName = "Master";
String finalName = masterName;
context
.getSource()
.sendSuccess(
() ->
Component.translatable(
"command.tiedup.master.forced_state", finalName, targetState.name()
),
true
);
return 1;
}
/**
* Find the nearest EntityMaster within 20 blocks of a player.
*/
@javax.annotation.Nullable
private static EntityMaster findNearestMaster(ServerPlayer player) {
var masters = player
.level()
.getEntitiesOfClass(
EntityMaster.class,
player.getBoundingBox().inflate(20.0),
m -> m.isAlive()
);
if (masters.isEmpty()) return null;
return masters
.stream()
.min((a, b) ->
Double.compare(a.distanceToSqr(player), b.distanceToSqr(player))
)
.orElse(null);
}
}