支持通过对角线坐标设置随机坐标选取范围
远离边界这个保护的实现有问题,然后地狱末地什么玩意的也不对,重试机制也不存在,这些之后再鸽
This commit is contained in:
TheWhiteDog9487
2026-02-11 18:12:06 +08:00
parent a0a6e1c35d
commit 8b03098280
6 changed files with 209 additions and 79 deletions

View File

@@ -18,7 +18,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
@@ -88,7 +88,7 @@ public class CommandRegister {
// /rtp
.requires(Commands.hasPermission(PermissionLevel))
.executes(context -> ExecuteCommand(
context.getSource(),null,null, null))
context.getSource(),null,null, null, null, null))
// /rtp <Radius(半径)>
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
.requires(Commands.hasPermission(PermissionLevel))
@@ -96,6 +96,8 @@ public class CommandRegister {
context.getSource(),
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
null,
null,
null,
null)))
// /rtp <PlayerID(被传送玩家名)>
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
@@ -104,6 +106,8 @@ public class CommandRegister {
context.getSource(),
null,
EntityArgument.getEntity(context,CommandArgumentName_Target),
null,
null,
null)))
// /rtp <Radius(半径)> <PlayerID(被传送玩家名)>
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
@@ -113,6 +117,8 @@ public class CommandRegister {
context.getSource(),
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
EntityArgument.getEntity(context,CommandArgumentName_Target),
null,
null,
null))))
// /rtp <PlayerID(被传送玩家名)> <Radius(半径)>
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
@@ -122,6 +128,8 @@ public class CommandRegister {
context.getSource(),
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
EntityArgument.getEntity(context,CommandArgumentName_Target),
null,
null,
null))))
// // /rtp <Radius(半径)> <Origin(随机中心)>
// .then(argument("Radius(半径)", LongArgumentType.longArg())
@@ -140,8 +148,9 @@ public class CommandRegister {
context.getSource(),
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
null,
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition)))))
// /rtp <Radius(半径)> <被传送玩家名(PlayerID)> <OriginEntity(随机中心,实体)>
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition),
null,
null))))
// /rtp <Radius(半径)> <PlayerID(被传送玩家名)> <OriginEntity(随机中心,实体)>
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
@@ -152,8 +161,9 @@ public class CommandRegister {
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
EntityArgument.getEntity(context,CommandArgumentName_Target),
new Vec2( (float) EntityArgument.getEntity( context,CommandArgumentName_OriginEntity).position().x,
(float) EntityArgument.getEntity( context,CommandArgumentName_OriginEntity).position().z ))))))
// /rtp <Radius(半径)> <被传送玩家名(PlayerID)> <OriginPos(随机中心,坐标)>
(float) EntityArgument.getEntity( context,CommandArgumentName_OriginEntity).position().z ),
null,
null)))))
// /rtp <Radius(半径)> <PlayerID(被传送玩家名)> <OriginPos(随机中心,坐标)>
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
@@ -163,8 +173,9 @@ public class CommandRegister {
context.getSource(),
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
EntityArgument.getEntity(context,CommandArgumentName_Target),
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition))))))
// /rtp <被传送玩家名(PlayerID)> <Radius(半径)> <OriginEntity(随机中心,实体)>
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition),
null,
null)))))
// /rtp <PlayerID(被传送玩家名)> <Radius(半径)> <OriginEntity(随机中心,实体)>
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
@@ -175,8 +186,9 @@ public class CommandRegister {
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
EntityArgument.getEntity(context,CommandArgumentName_Target),
new Vec2( (float) EntityArgument.getEntity( context,CommandArgumentName_OriginEntity).position().x,
(float) EntityArgument.getEntity( context,CommandArgumentName_OriginEntity).position().z ))))))
// /rtp <被传送玩家名(PlayerID)> <Radius(半径)> <OriginPos(随机中心,坐标)>
(float) EntityArgument.getEntity( context,CommandArgumentName_OriginEntity).position().z ),
null,
null)))))
// /rtp <PlayerID(被传送玩家名)> <Radius(半径)> <OriginPos(随机中心,坐标)>
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
@@ -186,7 +198,71 @@ public class CommandRegister {
context.getSource(),
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
EntityArgument.getEntity(context,CommandArgumentName_Target),
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition)))))) );});}
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition),
null,
null)))))
// /rtp <RegionFrom(随机区域起点,坐标)> <RegionTo(随机区域终点,坐标)>
.then(argument(CommandArgumentName_RegionFromPosition, Vec2Argument.vec2())
.then(argument(CommandArgumentName_RegionToPosition, Vec2Argument.vec2())
.requires(Commands.hasPermission(PermissionLevel))
.executes(context -> ExecuteCommand(
context.getSource(),
null,
null,
null,
Vec2Argument.getVec2(context, CommandArgumentName_RegionFromPosition),
Vec2Argument.getVec2(context, CommandArgumentName_RegionToPosition)))))
// /rtp <RegionFrom(随机区域起点,坐标)> <RegionTo(随机区域终点,坐标)> <PlayerID(被传送玩家名)>
.then(argument(CommandArgumentName_RegionFromPosition, Vec2Argument.vec2())
.then(argument(CommandArgumentName_RegionToPosition, Vec2Argument.vec2())
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
.requires(Commands.hasPermission(PermissionLevel))
.executes(context -> ExecuteCommand(
context.getSource(),
null,
EntityArgument.getEntity(context,CommandArgumentName_Target),
null,
Vec2Argument.getVec2(context, CommandArgumentName_RegionFromPosition),
Vec2Argument.getVec2(context, CommandArgumentName_RegionToPosition))))))
// /rtp <PlayerID(被传送玩家名)> <RegionFrom(随机区域起点,坐标)> <RegionTo(随机区域终点,坐标)>
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
.then(argument(CommandArgumentName_RegionFromPosition, Vec2Argument.vec2())
.then(argument(CommandArgumentName_RegionToPosition, Vec2Argument.vec2())
.requires(Commands.hasPermission(PermissionLevel))
.executes(context -> ExecuteCommand(
context.getSource(),
null,
EntityArgument.getEntity(context,CommandArgumentName_Target),
null,
Vec2Argument.getVec2(context, CommandArgumentName_RegionFromPosition),
Vec2Argument.getVec2(context, CommandArgumentName_RegionToPosition))))))
// /rtp <RegionFrom(随机区域起点,实体)> <RegionTo(随机区域终点,实体)>
.then(argument(CommandArgumentName_RegionFromEntity, EntityArgument.entity())
.then(argument(CommandArgumentName_RegionToEntity, EntityArgument.entity())
.requires(Commands.hasPermission(PermissionLevel))
.executes(context -> ExecuteCommand(
context.getSource(),
null,
null,
null,
new Vec2( (float) EntityArgument.getEntity( context,CommandArgumentName_RegionFromEntity).position().x,
(float) EntityArgument.getEntity( context,CommandArgumentName_RegionFromEntity).position().z ),
new Vec2( (float) EntityArgument.getEntity( context,CommandArgumentName_RegionToEntity).position().x,
(float) EntityArgument.getEntity( context,CommandArgumentName_RegionToEntity).position().z ) ) )))
// /rtp <RegionFrom(随机区域起点,实体)> <RegionTo(随机区域终点,实体)> <PlayerID(被传送玩家名)>
.then(argument(CommandArgumentName_RegionFromEntity, EntityArgument.entity())
.then(argument(CommandArgumentName_RegionToEntity, EntityArgument.entity())
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
.requires(Commands.hasPermission(PermissionLevel))
.executes(context -> ExecuteCommand(
context.getSource(),
null,
EntityArgument.getEntity(context,CommandArgumentName_Target),
null,
new Vec2( (float) EntityArgument.getEntity( context,CommandArgumentName_RegionFromEntity).position().x,
(float) EntityArgument.getEntity( context,CommandArgumentName_RegionFromEntity).position().z ),
new Vec2( (float) EntityArgument.getEntity( context,CommandArgumentName_RegionToEntity).position().x,
(float) EntityArgument.getEntity( context,CommandArgumentName_RegionToEntity).position().z )))))) );});}
/**
* 向游戏内注册命令
@@ -205,9 +281,11 @@ public class CommandRegister {
* @param Radius 随机选择的目的坐标距离参数 {@code Origin} 的最大距离
* @param Entity 被传送的实体
* @param Origin 随机选择的目的坐标的中心
* @param RegionFrom 选择随机坐标的范围的起始坐标
* @param RegionTo 选择随机坐标的范围的结束坐标
* @return 命令运行是否成功
*/
static int ExecuteCommand(CommandSourceStack Source, @Nullable Integer Radius, @Nullable Entity Entity, @Nullable Vec2 Origin){
static int ExecuteCommand(CommandSourceStack Source, @Nullable Integer Radius, @Nullable Entity Entity, @Nullable Vec2 Origin, @Nullable Vec2 RegionFrom, @Nullable Vec2 RegionTo){
Entity TargetEntity = Entity == null ? Source.getPlayer() : Entity;
/*
@@ -219,34 +297,46 @@ public class CommandRegister {
*/
if (TargetEntity == null) {
Source.sendSuccess(()->{ return Component.translatableWithFallback("error.no_target","不存在被传送目标由非玩家物体执行命令时请显式指定被传送玩家ID"); }, true);
return -1;}
if (Radius == null){Radius = (int) (WorldBorder - 1e4);}
// ↑ 远离世界边界
return -1; }
int Coordinate_X = 0;
int Coordinate_Z = 0;
try {
if (Origin == null){
Coordinate_X = SR.nextInt(-Radius, Radius + 1);
Coordinate_Z = SR.nextInt(-Radius, Radius + 1); }
else{
Coordinate_X = SR.nextInt((int) Origin.x - Radius, (int) Origin.x + Radius + 1);
Coordinate_Z = SR.nextInt((int) Origin.y - Radius, (int) Origin.y + Radius + 1); } }
catch (IllegalArgumentException e) {
// 半径为零
if (Origin == null) {
Source.sendSuccess(()->{ return Component.translatableWithFallback("warning.radius_equal_zero_no_target", "由于你设置的随机半径为0并且未设置随机中心点坐标因此什么都不会发生"); },true);
return -1;}
else {
Coordinate_X = (int) Origin.x;
Coordinate_Z = (int) Origin.y;
int finalCoordinate_X1 = Coordinate_X;
int finalCoordinate_Z1 = Coordinate_Z;
// ↑ "lambda 表达式中使用的变量应为 final 或有效 final"
Source.sendSuccess(()->{ return Component.translatableWithFallback("warning.radius_equal_zero", "警告由于你设置的随机半径为0因此在选择出合适高度之后将直接把你传送至%d %d", finalCoordinate_X1, finalCoordinate_Z1); },true);}}
if (RegionFrom == null || RegionTo == null) { // ← 按半径和中心取随机
if (Radius == null) { Radius = (int) (WorldBorder - 1e4); }
// ↑ 远离世界边界
try {
if (Origin == null) {
Coordinate_X = SR.nextInt(-Radius, Radius + 1);
Coordinate_Z = SR.nextInt(-Radius, Radius + 1); }
else {
Coordinate_X = SR.nextInt((int) Origin.x - Radius, (int) Origin.x + Radius + 1);
Coordinate_Z = SR.nextInt((int) Origin.y - Radius, (int) Origin.y + Radius + 1); } }
catch (IllegalArgumentException e) {
// 半径为零
if (Origin == null) {
Source.sendSuccess(() -> {
return Component.translatableWithFallback("warning.radius_equal_zero_no_target", "由于你设置的随机半径为0并且未设置随机中心点坐标因此什么都不会发生"); }, true);
return -1; }
else {
Coordinate_X = (int) Origin.x;
Coordinate_Z = (int) Origin.y;
int finalCoordinate_X1 = Coordinate_X;
int finalCoordinate_Z1 = Coordinate_Z;
// ↑ "lambda 表达式中使用的变量应为 final 或有效 final"
Source.sendSuccess(() -> {
return Component.translatableWithFallback("warning.radius_equal_zero", "警告由于你设置的随机半径为0因此在选择出合适高度之后将直接把你传送至%d %d", finalCoordinate_X1, finalCoordinate_Z1); }, true); } } }
else { // ← 按范围取随机
Coordinate_X = SR.nextInt( Math.min( (int)RegionFrom.x, (int)RegionTo.x ), Math.max( (int)RegionFrom.x, (int)RegionTo.x ) + 1 );
Coordinate_Z = SR.nextInt( Math.min( (int)RegionFrom.y, (int)RegionTo.y ), Math.max( (int)RegionFrom.y, (int)RegionTo.y ) + 1 ); }
if (Coordinate_X >= WorldBorder){ Coordinate_X = (int) (WorldBorder - 1e4); }
else if (Coordinate_X <= -WorldBorder){ Coordinate_X = (int) (-WorldBorder + 1e4); }
if (Coordinate_Z >= WorldBorder){ Coordinate_Z = (int) (WorldBorder - 1e4); }
else if (Coordinate_Z <= -WorldBorder){ Coordinate_Z = (int) (-WorldBorder + 1e4); }
// ↑ 远离世界边界
Level EntityWorld = TargetEntity.level();
EntityWorld.getChunk(Coordinate_X >> 4, Coordinate_Z >> 4, ChunkStatus.FULL, true);
// ↑ 加载目标区块不然下面获取到的Coordinate_Y一定是-64
// 必须是 >> 4 ,不能是 / 16
// 按位右移4和除以16在被除数小于0时的结果不一致一个是向上取整一个是向下取整
// 因此必须是 >> 4 ,不能是 / 16
int Coordinate_Y = EntityWorld.getHeight(MOTION_BLOCKING_NO_LEAVES, Coordinate_X, Coordinate_Z);
BlockPos.MutableBlockPos BlockPos = new BlockPos.MutableBlockPos();
for (int x = -1; x <= 1; x++) {
@@ -265,5 +355,5 @@ public class CommandRegister {
// ↑ "lambda 表达式中使用的变量应为 final 或有效 final"
final var FeedbackFallbackString = String.format("已将玩家%s传送到%d %d %d", TargetEntity.getName().getString(), Coordinate_X, Coordinate_Y, Coordinate_Z);
Source.sendSuccess(()->{ return Component.translatableWithFallback("info.success", FeedbackFallbackString, TargetEntity.getName(), finalCoordinate_X, Coordinate_Y, finalCoordinate_Z); },true);
return Command.SINGLE_SUCCESS;}
return Command.SINGLE_SUCCESS; }
}