Strip all Phase references, TODO/FUTURE roadmap notes, and internal planning comments from the codebase. Run Prettier for consistent formatting across all Java files.
527 lines
18 KiB
Java
527 lines
18 KiB
Java
package com.tiedup.remake.commands;
|
|
|
|
import com.mojang.brigadier.CommandDispatcher;
|
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
|
import com.mojang.brigadier.context.CommandContext;
|
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
import com.tiedup.remake.cells.CellDataV2;
|
|
import com.tiedup.remake.cells.CellRegistryV2;
|
|
import com.tiedup.remake.items.base.ItemCollar;
|
|
import com.tiedup.remake.state.PlayerBindState;
|
|
import com.tiedup.remake.util.teleport.Position;
|
|
import com.tiedup.remake.util.teleport.TeleportHelper;
|
|
import com.tiedup.remake.v2.BodyRegionV2;
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
import net.minecraft.commands.Commands;
|
|
import net.minecraft.commands.arguments.EntityArgument;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.world.item.ItemStack;
|
|
|
|
/**
|
|
* Collar management commands.
|
|
*
|
|
* Commands:
|
|
* /collar claim <player> - Claim ownership of a player's collar
|
|
* /collar unclaim <player> - Remove your ownership
|
|
* /collar rename <player> <name> - Set alias for collar
|
|
* /collar addowner <target> <owner> - Add another owner
|
|
* /collar removeowner <target> <owner> - Remove an owner
|
|
* /collar sethome <player> - Set home location
|
|
* /collar setprison <player> - Set prison location (legacy)
|
|
* /collar setcell <player> <cellname> - Assign cell to collar (preferred)
|
|
* /collar prisonradius <player> <radius> - Set prison fence radius (legacy)
|
|
* /collar prisonfence <player> [on/off] - Toggle prison fence (legacy)
|
|
* /collar backhome <player> - Teleport slave back home
|
|
* /collar info <player> - Show collar info
|
|
*
|
|
* Requires OP level 2.
|
|
*/
|
|
public class CollarCommand {
|
|
|
|
public static void register(
|
|
CommandDispatcher<CommandSourceStack> dispatcher
|
|
) {
|
|
dispatcher.register(createCollarCommand());
|
|
}
|
|
|
|
/**
|
|
* Create the collar command builder (for use as subcommand of /tiedup).
|
|
* @return The command builder
|
|
*/
|
|
public static com.mojang.brigadier.builder.LiteralArgumentBuilder<
|
|
CommandSourceStack
|
|
> createCollarCommand() {
|
|
return Commands.literal("collar")
|
|
.requires(CommandHelper.REQUIRES_OP)
|
|
// /collar claim <player>
|
|
.then(
|
|
Commands.literal("claim").then(
|
|
Commands.argument(
|
|
"player",
|
|
EntityArgument.player()
|
|
).executes(CollarCommand::claim)
|
|
)
|
|
)
|
|
// /collar unclaim <player>
|
|
.then(
|
|
Commands.literal("unclaim").then(
|
|
Commands.argument(
|
|
"player",
|
|
EntityArgument.player()
|
|
).executes(CollarCommand::unclaim)
|
|
)
|
|
)
|
|
// /collar rename <player> <name>
|
|
.then(
|
|
Commands.literal("rename").then(
|
|
Commands.argument("player", EntityArgument.player()).then(
|
|
Commands.argument(
|
|
"name",
|
|
StringArgumentType.greedyString()
|
|
).executes(CollarCommand::rename)
|
|
)
|
|
)
|
|
)
|
|
// /collar addowner <target> <owner>
|
|
.then(
|
|
Commands.literal("addowner").then(
|
|
Commands.argument("target", EntityArgument.player()).then(
|
|
Commands.argument(
|
|
"owner",
|
|
EntityArgument.player()
|
|
).executes(CollarCommand::addOwner)
|
|
)
|
|
)
|
|
)
|
|
// /collar removeowner <target> <owner>
|
|
.then(
|
|
Commands.literal("removeowner").then(
|
|
Commands.argument("target", EntityArgument.player()).then(
|
|
Commands.argument(
|
|
"owner",
|
|
EntityArgument.player()
|
|
).executes(CollarCommand::removeOwner)
|
|
)
|
|
)
|
|
)
|
|
// /collar setcell <player> <cellname> (assigns cell)
|
|
.then(
|
|
Commands.literal("setcell").then(
|
|
Commands.argument("player", EntityArgument.player()).then(
|
|
Commands.argument(
|
|
"cellname",
|
|
StringArgumentType.word()
|
|
).executes(CollarCommand::setCell)
|
|
)
|
|
)
|
|
)
|
|
// /collar tocell <player> (teleport to assigned cell)
|
|
.then(
|
|
Commands.literal("tocell").then(
|
|
Commands.argument(
|
|
"player",
|
|
EntityArgument.player()
|
|
).executes(CollarCommand::teleportToCell)
|
|
)
|
|
)
|
|
// /collar info <player>
|
|
.then(
|
|
Commands.literal("info").then(
|
|
Commands.argument(
|
|
"player",
|
|
EntityArgument.player()
|
|
).executes(CollarCommand::info)
|
|
)
|
|
);
|
|
}
|
|
|
|
private static ItemStack getPlayerCollar(ServerPlayer player) {
|
|
PlayerBindState state = PlayerBindState.getInstance(player);
|
|
if (state == null || !state.hasCollar()) return ItemStack.EMPTY;
|
|
return state.getEquipment(BodyRegionV2.NECK);
|
|
}
|
|
|
|
private static int claim(CommandContext<CommandSourceStack> context)
|
|
throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "player");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (source.getEntity() instanceof ServerPlayer executor) {
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
collarItem.addOwner(collar, executor);
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§aClaimed " +
|
|
target.getName().getString() +
|
|
"'s collar"
|
|
),
|
|
true
|
|
);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
source.sendFailure(Component.literal("Failed to claim collar"));
|
|
return 0;
|
|
}
|
|
|
|
private static int unclaim(CommandContext<CommandSourceStack> context)
|
|
throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "player");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (source.getEntity() instanceof ServerPlayer executor) {
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
collarItem.removeOwner(collar, executor.getUUID());
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§aRemoved your ownership from " +
|
|
target.getName().getString() +
|
|
"'s collar"
|
|
),
|
|
true
|
|
);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
source.sendFailure(Component.literal("Failed to unclaim collar"));
|
|
return 0;
|
|
}
|
|
|
|
private static int rename(CommandContext<CommandSourceStack> context)
|
|
throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "player");
|
|
String name = StringArgumentType.getString(context, "name");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
collarItem.setNickname(collar, name);
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§aSet collar nickname to '" + name + "'"
|
|
),
|
|
true
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static int addOwner(CommandContext<CommandSourceStack> context)
|
|
throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "target");
|
|
ServerPlayer owner = EntityArgument.getPlayer(context, "owner");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
collarItem.addOwner(collar, owner);
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§aAdded " +
|
|
owner.getName().getString() +
|
|
" as owner of " +
|
|
target.getName().getString() +
|
|
"'s collar"
|
|
),
|
|
true
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static int removeOwner(CommandContext<CommandSourceStack> context)
|
|
throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "target");
|
|
ServerPlayer owner = EntityArgument.getPlayer(context, "owner");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
collarItem.removeOwner(collar, owner.getUUID());
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§aRemoved " +
|
|
owner.getName().getString() +
|
|
" as owner of " +
|
|
target.getName().getString() +
|
|
"'s collar"
|
|
),
|
|
true
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* /collar setcell <player> <cellname>
|
|
*
|
|
* Assign a named cell to a player's collar.
|
|
*/
|
|
private static int setCell(CommandContext<CommandSourceStack> context)
|
|
throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "player");
|
|
String cellName = StringArgumentType.getString(context, "cellname");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
// Get the cell by name
|
|
ServerLevel serverLevel = source.getLevel();
|
|
CellRegistryV2 registry = CellRegistryV2.get(serverLevel);
|
|
CellDataV2 cell = registry.getCellByName(cellName);
|
|
|
|
if (cell == null) {
|
|
source.sendFailure(
|
|
Component.literal("Cell '" + cellName + "' not found")
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
collarItem.setCellId(collar, cell.getId());
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§aAssigned cell '" +
|
|
cellName +
|
|
"' to " +
|
|
target.getName().getString() +
|
|
"'s collar"
|
|
),
|
|
true
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* /collar tocell <player>
|
|
*
|
|
* Teleport player to their assigned cell.
|
|
*/
|
|
private static int teleportToCell(
|
|
CommandContext<CommandSourceStack> context
|
|
) throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "player");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
if (!collarItem.hasCellAssigned(collar)) {
|
|
source.sendFailure(
|
|
Component.literal("No cell assigned to collar")
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
// Get cell position and teleport
|
|
java.util.UUID cellId = collarItem.getCellId(collar);
|
|
ServerLevel serverLevel = source.getLevel();
|
|
CellDataV2 cell = CellRegistryV2.get(serverLevel).getCell(cellId);
|
|
|
|
if (cell == null) {
|
|
source.sendFailure(
|
|
Component.literal("Assigned cell no longer exists")
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
net.minecraft.core.BlockPos teleportTarget =
|
|
cell.getSpawnPoint() != null
|
|
? cell.getSpawnPoint()
|
|
: cell.getCorePos().above();
|
|
Position cellPos = new Position(
|
|
teleportTarget,
|
|
serverLevel.dimension()
|
|
);
|
|
TeleportHelper.teleportEntity(target, cellPos);
|
|
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§aTeleported " +
|
|
target.getName().getString() +
|
|
" to cell at " +
|
|
cell.getCorePos().toShortString()
|
|
),
|
|
true
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static int info(CommandContext<CommandSourceStack> context)
|
|
throws CommandSyntaxException {
|
|
CommandSourceStack source = context.getSource();
|
|
ServerPlayer target = EntityArgument.getPlayer(context, "player");
|
|
|
|
ItemStack collar = getPlayerCollar(target);
|
|
if (collar.isEmpty()) {
|
|
source.sendFailure(
|
|
Component.literal(
|
|
target.getName().getString() + " does not have a collar"
|
|
)
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (collar.getItem() instanceof ItemCollar collarItem) {
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§6=== Collar Info for " +
|
|
target.getName().getString() +
|
|
" ==="
|
|
),
|
|
false
|
|
);
|
|
|
|
String nickname = collarItem.getNickname(collar);
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§7Nickname: §f" +
|
|
(nickname.isEmpty() ? "None" : nickname)
|
|
),
|
|
false
|
|
);
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§7Has Owner: §f" + collarItem.hasOwner(collar)
|
|
),
|
|
false
|
|
);
|
|
// Cell assignment
|
|
java.util.UUID cellId = collarItem.getCellId(collar);
|
|
if (cellId != null) {
|
|
ServerLevel serverLevel = source.getLevel();
|
|
CellRegistryV2 registry = CellRegistryV2.get(serverLevel);
|
|
CellDataV2 cell = registry.getCell(cellId);
|
|
if (cell != null) {
|
|
String cellDisplay =
|
|
cell.getName() != null
|
|
? cell.getName()
|
|
: cellId.toString().substring(0, 8) + "...";
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§7Assigned Cell: §a" +
|
|
cellDisplay +
|
|
" §7@ " +
|
|
cell.getCorePos().toShortString()
|
|
),
|
|
false
|
|
);
|
|
} else {
|
|
source.sendSuccess(
|
|
() -> Component.literal("§7Assigned Cell: §c(deleted)"),
|
|
false
|
|
);
|
|
}
|
|
} else {
|
|
source.sendSuccess(
|
|
() -> Component.literal("§7Assigned Cell: §fNone"),
|
|
false
|
|
);
|
|
}
|
|
|
|
source.sendSuccess(
|
|
() ->
|
|
Component.literal(
|
|
"§7Locked: §f" + collarItem.isLocked(collar)
|
|
),
|
|
false
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|