mirror of
https://github.com/TheWhiteDog9487/RandomTeleporter.git
synced 2026-04-06 09:35:36 +08:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6dff863d3f | ||
|
|
4137a166ae | ||
|
|
8b03098280 | ||
|
|
a0a6e1c35d | ||
|
|
5f3ca6c68f | ||
|
|
5788f78a4d | ||
|
|
2f5e154cc4 | ||
|
|
c579c266a5 | ||
|
|
62c8267311 | ||
|
|
74046be828 | ||
|
|
33e01b3d35 | ||
|
|
e7f9ac069a | ||
|
|
eb85fff326 | ||
|
|
48a5027cce | ||
|
|
62c3484c5e | ||
| d47907cdf4 | |||
| 8c55311f27 | |||
| 35ac4dd842 | |||
| 34ea09dfd9 | |||
| ad014a2b1b | |||
| 4de867d6aa | |||
| 9770b72448 | |||
| 66a1529132 | |||
| 96a69f3262 | |||
| da6802f605 | |||
| 7376393f37 | |||
| c442f12de4 |
9
.gitattributes
vendored
Normal file
9
.gitattributes
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
# Linux start script should use lf
|
||||
/gradlew text eol=lf
|
||||
|
||||
# These are Windows script files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
|
||||
37
.github/workflows/build.yml
vendored
Normal file
37
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# Automatically build the project and run any configured tests for every push
|
||||
# and submitted pull request. This can help catch issues that only occur on
|
||||
# certain platforms or Java versions, and provides a first line of defence
|
||||
# against bad commits.
|
||||
|
||||
name: build
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
# Use these Java versions
|
||||
java: [
|
||||
25, # Current Java LTS
|
||||
]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: validate gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v2
|
||||
- name: setup jdk ${{ matrix.java }}
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
distribution: 'microsoft'
|
||||
- name: make gradle wrapper executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: build
|
||||
run: ./gradlew build
|
||||
- name: capture build artifacts
|
||||
if: ${{ matrix.java == '21' }} # Only upload artifacts built from latest java
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Artifacts
|
||||
path: build/libs/
|
||||
128
README.md
128
README.md
@@ -1,63 +1,104 @@
|
||||
<div align="center">
|
||||
<a href="https://github.com/TheWhiteDog9487/RandomTeleporter/blob/%E4%B8%BB%E8%A6%81/README.md">简体中文(GitHub)</a>
|
||||
<a href="https://git.thewhitedog9487.xyz/TheWhiteDog9487/RandomTeleporter/src/branch/%E4%B8%BB%E8%A6%81/README.md">简体中文(Gitea)</a>
|
||||
<a href="https://github.com/TheWhiteDog9487/RandomTeleporter/blob/%E4%B8%BB%E8%A6%81/README_EN.md">English(GitHub)</a>
|
||||
<a href="https://git.thewhitedog9487.xyz/TheWhiteDog9487/RandomTeleporter/src/branch/%E4%B8%BB%E8%A6%81/README_EN.md">English(Gitea)</a>
|
||||
</div>
|
||||
|
||||
# 介绍
|
||||
这个模组增加了一个命令(/rtp),用于将玩家随机传送到世界的任何一个位置。
|
||||
这个模组增加了一个命令 `/rtp`,用于将玩家随机传送到世界的任何一个位置。
|
||||
|
||||
# 命令格式
|
||||
- /rtp
|
||||
- /rtp <Radius(半径)>
|
||||
- /rtp <被传送玩家名(PlayerID)>
|
||||
- /rtp <Radius(半径)> <被传送玩家名(PlayerID)>
|
||||
- /rtp <被传送玩家名(PlayerID)> <Radius(半径)>
|
||||
- /rtp <Radius(半径)> <OriginPos(随机中心,坐标)>
|
||||
- /rtp <Radius(半径)> <被传送玩家名(PlayerID)> <OriginEntity(随机中心,实体)>
|
||||
- /rtp <Radius(半径)> <被传送玩家名(PlayerID)> <OriginPos(随机中心,坐标)>
|
||||
- /rtp <被传送玩家名(PlayerID)> <Radius(半径)> <OriginEntity(随机中心,实体)>
|
||||
- /rtp <被传送玩家名(PlayerID)> <Radius(半径)> <OriginPos(随机中心,坐标)>
|
||||
- `/rtp`
|
||||
- `/rtp back`
|
||||
- `/rtp back <被传送玩家ID>`
|
||||
- `/rtp <被传送玩家ID> back`
|
||||
- `/rtp <随机半径>`
|
||||
- `/rtp <被传送玩家ID>`
|
||||
- `/rtp <随机半径> <被传送玩家ID>`
|
||||
- `/rtp <被传送玩家ID> <随机半径>`
|
||||
- `/rtp <随机半径> <随机中心点坐标>`
|
||||
- `/rtp <随机半径> <被传送玩家ID> <作为随机中心的实体>`
|
||||
- `/rtp <随机半径> <被传送玩家ID> <随机中心点坐标>`
|
||||
- `/rtp <被传送玩家ID> <随机半径> <作为随机中心的实体>`
|
||||
- `/rtp <被传送玩家ID> <随机半径> <随机中心点坐标>`
|
||||
- `/rtp <随机区域起点坐标> <随机区域终点坐标>`
|
||||
- `/rtp <随机区域起点坐标> <随机区域终点坐标> <被传送玩家ID>`
|
||||
- `/rtp <被传送玩家ID> <随机区域起点坐标> <随机区域终点坐标>`
|
||||
- `/rtp <随机区域起点实体> <随机区域终点实体>`
|
||||
- `/rtp <随机区域起点实体> <随机区域终点实体> <被传送玩家ID>`
|
||||
|
||||
## 命令示例
|
||||
- /rtp
|
||||
将执行命令的玩家随机传送到以(0,0)为中心点,2.9e7 - 1e4作为随机半径的范围内的随机一点
|
||||
2.9e+7 = 2.9 x 10^7 = 29000000 = 两千九百万
|
||||
1e4 = 10^4 = 10000 = 一万
|
||||
- `/rtp`
|
||||
将执行命令的玩家随机传送到以`(0,0)`为中心点,$2.9 \times 10^7 - 10^4$ 作为随机半径的范围内的随机一点
|
||||
$2.9 \times 10^7 = 29,000,000$ = 两千九百万
|
||||
$10^4 = 10,000$ = 一万
|
||||
|
||||
- /rtp 1000
|
||||
将执行命令的玩家随机传送到以(0,0)为中心点,1000作为随机半径的范围内的随机一点
|
||||
- `/rtp back`
|
||||
将执行命令的玩家传送回最近一次使用随机传送前的位置
|
||||
**注意:这个功能保存的上一次随机传送前的位置信息只会在游戏(服务器)运行期间存在,游戏(服务器)关闭后就会丢失**
|
||||
|
||||
- /rtp TheWhiteDog9487
|
||||
将TheWhiteDog9487随机传送到以(0,0)为中心点,2.9e7 - 1e4作为随机半径的范围内的随机一点
|
||||
- `/rtp back TheWhiteDog9487`
|
||||
将TheWhiteDog9487传送回其最近一次使用随机传送前的位置
|
||||
|
||||
- /rtp TheWhiteDog9487 1000
|
||||
将TheWhiteDog9487随机传送到以(0,0)为中心点,1000作为随机半径的范围内的随机一点
|
||||
- `/rtp TheWhiteDog9487 back`
|
||||
将TheWhiteDog9487传送回其最近一次使用随机传送前的位置
|
||||
|
||||
- /rtp 1000 TheWhiteDog9487
|
||||
将TheWhiteDog9487随机传送到以(0,0)为中心点,1000作为随机半径的范围内的随机一点
|
||||
- `/rtp 1000`
|
||||
将执行命令的玩家随机传送到以`(0,0)`为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- /rtp 1000 10000 ~ 10000
|
||||
将执行命令的玩家随机传送到以(10000,10000)为中心点,1000作为随机半径的范围内的随机一点
|
||||
提示:按照道理来说中心坐标是不需要高度(Y轴)的,但由于坐标的类型是Vec3d,所以还是要写高度的。
|
||||
至于高度的具体数值,随便写,代码里也没用到过。
|
||||
- `/rtp TheWhiteDog9487`
|
||||
将TheWhiteDog9487随机传送到以`(0,0)`为中心点,$2.9 \times 10^7 - 10^4$ 作为随机半径的范围内的随机一点
|
||||
|
||||
- /rtp 1000 TheWhiteDog9487 TheWhiteDog_CN
|
||||
- `/rtp TheWhiteDog9487 1000`
|
||||
将TheWhiteDog9487随机传送到以`(0,0)`为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- `/rtp 1000 TheWhiteDog9487`
|
||||
将TheWhiteDog9487随机传送到以`(0,0)`为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- `/rtp 1000 10000 10000`
|
||||
将执行命令的玩家随机传送到以`(10000,10000)`为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- `/rtp 1000 TheWhiteDog9487 TheWhiteDog_CN`
|
||||
将TheWhiteDog9487随机传送到以TheWhiteDog_CN所在位置为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- /rtp 1000 TheWhiteDog9487 10000 ~ 10000
|
||||
将TheWhiteDog9487随机传送到以(10000,10000)为中心点,1000作为随机半径的范围内的随机一点
|
||||
- `/rtp 1000 TheWhiteDog9487 10000 10000`
|
||||
将TheWhiteDog9487随机传送到以`(10000,10000)`为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- /rtp TheWhiteDog9487 1000 TheWhiteDog_CN
|
||||
- `/rtp TheWhiteDog9487 1000 TheWhiteDog_CN`
|
||||
将TheWhiteDog9487随机传送到以TheWhiteDog_CN所在位置为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- /rtp TheWhiteDog9487 1000 10000 ~ 10000
|
||||
将TheWhiteDog9487随机传送到以(10000,10000)为中心点,1000作为随机半径的范围内的随机一点
|
||||
- `/rtp TheWhiteDog9487 1000 10000 10000`
|
||||
将TheWhiteDog9487随机传送到以`(10000,10000)`为中心点,1000作为随机半径的范围内的随机一点
|
||||
|
||||
- `/rtp 10000.0 10000.0 20000.0 20000.0`
|
||||
将执行命令的玩家随机传送到以`(10000,10000)`,`(20000,10000)`,`(20000,20000)`,`(10000,20000)`四个顶点围成的长方形区域内的随机一点
|
||||
您需要提供的坐标是这个长方形的任意一个顶点和这个顶点对应的斜对角顶点的位置
|
||||
|
||||
- `/rtp TheWhiteDog9487 10000.0 10000.0 20000.0 20000.0`
|
||||
将TheWhiteDog9487随机传送到以`(10000,10000)`,`(20000,10000)`,`(20000,20000)`,`(10000,20000)`四个顶点围成的长方形区域内的随机一点
|
||||
|
||||
- `/rtp 10000.0 10000.0 20000.0 20000.0 TheWhiteDog9487`
|
||||
将TheWhiteDog9487随机传送到以`(10000,10000)`,`(20000,10000)`,`(20000,20000)`,`(10000,20000)`四个顶点围成的长方形区域内的随机一点
|
||||
|
||||
- `/rtp TheWhiteDog9487 TheWhiteDog_CN`
|
||||
将命令执行者传送到以TheWhiteDog9487和TheWhiteDog_CN当前所在位置为对角线的长方形区域内的随机一点
|
||||
|
||||
- `/rtp TheWhiteDog9487 TheWhiteDog_CN TheWhiteDog4568`
|
||||
将TheWhiteDog4568随机传送到以TheWhiteDog9487和TheWhiteDog_CN当前所在位置为对角线的长方形区域内的随机一点
|
||||
|
||||
### 特别提示
|
||||
/rtp <Radius(半径)> <Origin(随机中心,实体)> 这种格式不存在。
|
||||
`/rtp <随机半径> <作为随机中心的实体>` 这种格式不存在。
|
||||
因为第二个参数可能是被传送玩家名,也可能是做随机中心点的实体。
|
||||
这两种都是实体类型,无法区分到底是哪一种,存在歧义。
|
||||
同样,`/rtp <被传送玩家ID> <随机区域起点实体> <随机区域终点实体>` 这一组也是不存在的
|
||||
三个参数都是实体类型,没办法区分`被传送玩家ID`是第一个还是第三个
|
||||
|
||||
# 依赖项
|
||||
由于我使用了fabric.api.command.v2中的CommandRegistrationCallback.EVENT来向游戏注册命令,所以这个模组需要依赖Fabric API
|
||||
Fabric API
|
||||
|
||||
# 关于玩家权限
|
||||
我参照原版的 /tp 命令,给 /rtp 设置了2级的权限要求。
|
||||
我参照原版的 `/tp` 命令,给 `/rtp` 设置了2级的权限要求。
|
||||
如果是原版或者类原版,你只需要让玩家有作弊的权限就可以用。
|
||||
插件服务器方面那些具体的权限分配,因为我自己没玩过所以我也没法给出参考意见。
|
||||
|
||||
@@ -69,20 +110,19 @@
|
||||
2. 单人游戏 + 开放局域网
|
||||
1. 使用客户端内置的服务器,开放局域网的那位玩家的客户端需要安装
|
||||
2. 其他加入游戏的玩家不需要安装
|
||||
3. 使用独立服务器(类似server.jar这种文件)
|
||||
3. 使用独立服务器(类似`server.jar`这种文件)
|
||||
1. 服务器需要安装
|
||||
2. 客户端不需要
|
||||
|
||||
**注意:情况2和3,虽然其他玩家不需要安装本模组就能使用功能。但是由于命令执行后的反馈结果文字使用了翻译,如果其他玩家没有安装模组会导致显示不正常,玩家会直接看到翻译键而不是对应的文字。
|
||||
因此,虽然可以但不建议其他人不安装。
|
||||
能安装的话还是都装一下吧。**
|
||||
**注意:情况2和3,如果其他玩家不安装本模组,他们看到的命令执行反馈就无法正确使用翻译,而在这种情况下默认显示中文文本。
|
||||
如果有查看多语言翻译文本的需求 ,那建议还是都装一下吧。**
|
||||
|
||||
# 一些小彩蛋
|
||||
你可以使用 /随机传送 来替代 /rtp
|
||||
你可以使用 `/随机传送` 来替代 `/rtp`
|
||||
没错,Minecraft的命令是可以存在非ASCII字符的,所以我就整了一个
|
||||
例如:
|
||||
- /rtp TheWhiteDog9487 1000
|
||||
- /随机传送 TheWhiteDog9487 1000
|
||||
- `/rtp TheWhiteDog9487 1000`
|
||||
- `/随机传送 TheWhiteDog9487 1000`
|
||||
|
||||
这两个命令的效果没有任何差别
|
||||
玩家权限限制和 /rtp 当然也是一样的,都是2级
|
||||
玩家权限限制和 `/rtp` 当然也是一样的,都是2级
|
||||
104
README_EN.md
Normal file
104
README_EN.md
Normal file
@@ -0,0 +1,104 @@
|
||||
<div align="center">
|
||||
<a href="https://github.com/TheWhiteDog9487/RandomTeleporter/blob/%E4%B8%BB%E8%A6%81/README.md">简体中文(GitHub)</a>
|
||||
<a href="https://git.thewhitedog9487.xyz/TheWhiteDog9487/RandomTeleporter/src/branch/%E4%B8%BB%E8%A6%81/README.md">简体中文(Gitea)</a>
|
||||
<a href="https://github.com/TheWhiteDog9487/RandomTeleporter/blob/%E4%B8%BB%E8%A6%81/README_EN.md">English(GitHub)</a>
|
||||
<a href="https://git.thewhitedog9487.xyz/TheWhiteDog9487/RandomTeleporter/src/branch/%E4%B8%BB%E8%A6%81/README_EN.md">English(Gitea)</a>
|
||||
</div>
|
||||
|
||||
# Introduction
|
||||
This mod adds a command `/rtp` for randomly teleporting players to any location in the world.
|
||||
|
||||
# Command Formats
|
||||
- `/rtp`
|
||||
- `/rtp back`
|
||||
- `/rtp back <PlayerID>`
|
||||
- `/rtp <PlayerID> back`
|
||||
- `/rtp <Radius>`
|
||||
- `/rtp <PlayerID>`
|
||||
- `/rtp <Radius> <PlayerID>`
|
||||
- `/rtp <PlayerID> <Radius>`
|
||||
- `/rtp <Radius> <OriginPos>`
|
||||
- `/rtp <Radius> <PlayerID> <OriginEntity>`
|
||||
- `/rtp <Radius> <PlayerID> <OriginPos>`
|
||||
- `/rtp <PlayerID> <Radius> <OriginEntity>`
|
||||
- `/rtp <PlayerID> <Radius> <OriginPos>`
|
||||
- `/rtp <RegionFromPos> <RegionToPos>`
|
||||
- `/rtp <RegionFromPos> <RegionToPos> <PlayerID>`
|
||||
- `/rtp <PlayerID> <RegionFromPos> <RegionToPos>`
|
||||
- `/rtp <RegionFromEntity> <RegionToEntity>`
|
||||
- `/rtp <RegionFromEntity> <RegionToEntity> <PlayerID>`
|
||||
|
||||
## Command Examples
|
||||
- `/rtp`
|
||||
Teleports the player executing the command to a random point within a radius of $2.9 \times 10^7 - 10^4$ centered at `(0,0)`.
|
||||
$2.9 \times 10^7 = 29,000,000$
|
||||
$10^4 = 10,000$
|
||||
|
||||
- `/rtp back`
|
||||
Teleports the player back to their position before the last random teleport.
|
||||
**Note: The previous position information is only stored during the game (server) session and will be lost after the game (server) is closed.**
|
||||
|
||||
- `/rtp back TheWhiteDog9487`
|
||||
Teleports `TheWhiteDog9487` back to their position before their last random teleport.
|
||||
|
||||
- `/rtp TheWhiteDog9487 back`
|
||||
Teleports `TheWhiteDog9487` back to their position before their last random teleport.
|
||||
|
||||
- `/rtp 1000`
|
||||
Teleports the player to a random point within a radius of `1000` centered at `(0,0)`.
|
||||
|
||||
- `/rtp TheWhiteDog9487`
|
||||
Teleports `TheWhiteDog9487` to a random point within a radius of $2.9 \times 10^7 - 10^4$ centered at `(0,0)`.
|
||||
|
||||
- `/rtp TheWhiteDog9487 1000`
|
||||
Teleports `TheWhiteDog9487` to a random point within a radius of `1000` centered at `(0,0)`.
|
||||
|
||||
- `/rtp 1000 TheWhiteDog9487`
|
||||
Teleports `TheWhiteDog9487` to a random point within a radius of `1000` centered at `(0,0)`.
|
||||
|
||||
- `/rtp 1000 10000 10000`
|
||||
Teleports the player to a random point within a radius of `1000` centered at `(10000,10000)`.
|
||||
|
||||
- `/rtp 1000 TheWhiteDog9487 TheWhiteDog_CN`
|
||||
Teleports `TheWhiteDog9487` to a random point within a radius of `1000` centered at `TheWhiteDog_CN`'s location.
|
||||
|
||||
- `/rtp 1000 TheWhiteDog9487 10000 10000`
|
||||
Teleports `TheWhiteDog9487` to a random point within a radius of `1000` centered at `(10000,10000)`.
|
||||
|
||||
- `/rtp TheWhiteDog9487 1000 TheWhiteDog_CN`
|
||||
Teleports `TheWhiteDog9487` to a random point within a radius of `1000` centered at `TheWhiteDog_CN`'s location.
|
||||
|
||||
- `/rtp TheWhiteDog9487 1000 10000 10000`
|
||||
Teleports `TheWhiteDog9487` to a random point within a radius of `1000` centered at `(10000,10000)`.
|
||||
|
||||
- `/rtp 10000.0 10000.0 20000.0 20000.0`
|
||||
Teleports the player to a random point within a rectangular region formed by vertices `(10000,10000)`, `(20000,10000)`, `(20000,20000)`, and `(10000,20000)`.
|
||||
You need to provide any vertex and its diagonally opposite vertex of this rectangle.
|
||||
|
||||
- `/rtp TheWhiteDog9487 10000.0 10000.0 20000.0 20000.0`
|
||||
Teleports `TheWhiteDog9487` to a random point within the same rectangular region described above.
|
||||
|
||||
- `/rtp 10000.0 10000.0 20000.0 20000.0 TheWhiteDog9487`
|
||||
Teleports `TheWhiteDog9487` to a random point within the same rectangular region described above.
|
||||
|
||||
- `/rtp TheWhiteDog9487 TheWhiteDog_CN`
|
||||
Teleports the command executor to a random point within a rectangular region where `TheWhiteDog9487` and `TheWhiteDog_CN`'s current positions are diagonals.
|
||||
|
||||
- `/rtp TheWhiteDog9487 TheWhiteDog_CN TheWhiteDog4568`
|
||||
Teleports `TheWhiteDog4568` to a random point within a rectangular region where `TheWhiteDog9487` and `TheWhiteDog_CN`'s current positions are diagonals.
|
||||
|
||||
### Special Notes
|
||||
The format `/rtp <Radius> <OriginEntity>` does not exist because the second parameter could be either the teleported player's name or the entity serving as the random center. Both are entity types, leading to ambiguity. Similarly, `/rtp <PlayerID> <RegionFromEntity> <RegionToEntity>` is also absent as all three parameters are entity types, making it impossible to distinguish the player ID.
|
||||
|
||||
# Dependencies
|
||||
Fabric API
|
||||
|
||||
# Player Permissions
|
||||
Following the standard `/tp` command, `/rtp` requires a permission level of `2`. For vanilla or vanilla-like servers, players only need "cheats" enabled. For plugin-based servers, specific permission management depends on your setup.
|
||||
|
||||
# Installation: Client or Server?
|
||||
- **Singleplayer**: Install on the client.
|
||||
- **Singleplayer + Open to LAN**: Install on the host client. Other players do not need to install it.
|
||||
- **Dedicated Server**: Install on the server. Clients do not strictly need to install it.
|
||||
|
||||
**Note**: In multiplayer scenarios, if clients do not have the mod installed, they will see command feedback in the server's default language (currently Chinese). Installing the mod on both sides is recommended for full multi-language support.
|
||||
@@ -1,9 +1,9 @@
|
||||
plugins {
|
||||
id("fabric-loom") version "1.8-SNAPSHOT"
|
||||
id("net.fabricmc.fabric-loom") version "1.15-SNAPSHOT"
|
||||
id("maven-publish")
|
||||
}
|
||||
|
||||
version = "${project.extra["mod_version"]}"
|
||||
version = project.extra["mod_version"] as String
|
||||
group = project.extra["maven_group"] as String
|
||||
|
||||
base {
|
||||
@@ -25,28 +25,26 @@ loom {
|
||||
splitEnvironmentSourceSets()
|
||||
|
||||
mods {
|
||||
create("randomteleporter") {
|
||||
sourceSet(sourceSets["main"])
|
||||
sourceSet(sourceSets["client"])
|
||||
}
|
||||
val mod = create("randomteleporter")
|
||||
mod.sourceSet("main")
|
||||
mod.sourceSet("client")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// To change the versions see the gradle.properties file
|
||||
minecraft("com.mojang:minecraft:${project.extra["minecraft_version"]}")
|
||||
mappings("net.fabricmc:yarn:${project.extra["yarn_mappings"]}:v2")
|
||||
modImplementation("net.fabricmc:fabric-loader:${project.extra["loader_version"]}")
|
||||
implementation("net.fabricmc:fabric-loader:${project.extra["loader_version"]}")
|
||||
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modImplementation("net.fabricmc.fabric-api:fabric-api:${project.extra["fabric_version"]}")
|
||||
implementation("net.fabricmc.fabric-api:fabric-api:${project.extra["fabric_api_version"]}")
|
||||
|
||||
// Uncomment the following line to enable the deprecated Fabric API modules.
|
||||
// These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time.
|
||||
// "modImplementation"("net.fabricmc.fabric-api:fabric-api-deprecated:${project.extra["fabric_version"]}")
|
||||
|
||||
// ↓ 开发测试用
|
||||
modRuntimeOnly("com.terraformersmc:modmenu:${project.extra["modmenu_version"]}")
|
||||
// runtimeOnly("com.terraformersmc:modmenu:${project.extra["modmenu_version"]}")
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
@@ -58,7 +56,7 @@ tasks.processResources {
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.release.set(21)
|
||||
options.release.set(25)
|
||||
}
|
||||
|
||||
java {
|
||||
@@ -67,21 +65,18 @@ java {
|
||||
// If you remove this line, sources will not be generated.
|
||||
withSourcesJar()
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
sourceCompatibility = JavaVersion.VERSION_25
|
||||
targetCompatibility = JavaVersion.VERSION_25
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
from("LICENSE") {
|
||||
rename { "${it}_${project.base.archivesName.get()}" } }
|
||||
}
|
||||
|
||||
tasks.remapJar{
|
||||
// https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:archiveFileName
|
||||
// 用这个属性设置jar包的文件名格式
|
||||
// 别用上面那个Jar任务的配置,会被remapJar覆盖掉
|
||||
archiveFileName = "${project.base.archivesName.get()}-${project.version} mc${project.extra["minecraft_version"]}.jar"}
|
||||
tasks.remapSourcesJar{
|
||||
|
||||
tasks.named<Jar>("sourcesJar") {
|
||||
archiveFileName = "${project.base.archivesName.get()}-${project.version} mc${project.extra["minecraft_version"]}-sources.jar"}
|
||||
|
||||
// configure the maven publication
|
||||
|
||||
@@ -4,24 +4,17 @@ org.gradle.parallel=true
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/develop
|
||||
minecraft_version=1.21.2
|
||||
yarn_mappings=1.21.2+build.1
|
||||
loader_version=0.16.7
|
||||
minecraft_version=26.1.1
|
||||
loader_version=0.18.6
|
||||
|
||||
# Mod Properties
|
||||
mod_version=0.3.2
|
||||
mod_version=0.5.2
|
||||
maven_group=xyz.thewhitedog9487
|
||||
archives_base_name=randomteleporter
|
||||
archives_base_name=RandomTeleporter
|
||||
|
||||
# Dependencies
|
||||
fabric_version=0.106.1+1.21.2
|
||||
fabric_api_version=0.145.3+26.1.1
|
||||
|
||||
# https://modrinth.com/mod/modmenu/versions
|
||||
# https://maven.terraformersmc.com/releases/com/terraformersmc/modmenu
|
||||
modmenu_version=12.0.0-beta.1
|
||||
|
||||
# loom_libraries_base=https://bmclapi2.bangbang93.com/maven/
|
||||
# loom_resources_base=https://bmclapi2.bangbang93.com/assets/
|
||||
# loom_version_manifests=https://bmclapi2.bangbang93.com/mc/game/version_manifest.json
|
||||
# loom_experimental_versions=https://maven.fabricmc.net/net/minecraft/experimental_versions.json
|
||||
# loom_fabric_repository=https://repository.hanbings.io/proxy/
|
||||
modmenu_version=18.0.0-alpha.8
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https://services.gradle.org/distributions/gradle-8.10-bin.zip
|
||||
distributionUrl=https://services.gradle.org/distributions/gradle-9.4.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package xyz.thewhitedog9487.mixin.client;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(MinecraftClient.class)
|
||||
@Mixin(Minecraft.class)
|
||||
public class ExampleClientMixin {
|
||||
@Inject(at = @At("HEAD"), method = "run")
|
||||
private void run(CallbackInfo info) {
|
||||
|
||||
@@ -1,208 +1,412 @@
|
||||
package xyz.thewhitedog9487;
|
||||
|
||||
import com.mojang.brigadier.arguments.LongArgumentType;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.command.argument.EntityArgumentType;
|
||||
import net.minecraft.command.argument.Vec3ArgumentType;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.server.commands.TeleportCommand;
|
||||
import net.minecraft.server.permissions.PermissionCheck;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.commands.arguments.EntityArgument;
|
||||
import net.minecraft.commands.arguments.coordinates.Vec2Argument;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.network.chat.Component;
|
||||
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 net.minecraft.world.phys.Vec3;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.SplittableRandom;
|
||||
import module java.base;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
import static net.minecraft.world.level.levelgen.Heightmap.Types.MOTION_BLOCKING_NO_LEAVES;
|
||||
import static xyz.thewhitedog9487.ResourceReloaderListener.*;
|
||||
|
||||
public class CommandRegister {
|
||||
final static long WorldBorder = (long) 2.9e7;
|
||||
static byte PermissionLevel = 2;
|
||||
|
||||
/**
|
||||
* 随机数生成器
|
||||
*/
|
||||
final static SplittableRandom SR = new SplittableRandom();
|
||||
|
||||
/**
|
||||
* 传送后用于生成保护平台的方块
|
||||
*/
|
||||
final static Block TargetBlock = Blocks.GLASS;
|
||||
|
||||
/**
|
||||
* 传送后会被 {@link CommandRegister#TargetBlock} 替换掉的方块
|
||||
* <br>
|
||||
* 替换中心:被传送目标脚下方块
|
||||
* <br>
|
||||
* 替换范围:替换中心周围半径为一的正方形区域
|
||||
*/
|
||||
final static Set<Block> ReplaceToTargetBlock = Set.of(
|
||||
Blocks.AIR,
|
||||
Blocks.VOID_AIR,
|
||||
Blocks.CAVE_AIR,
|
||||
Blocks.WATER,
|
||||
Blocks.LAVA,
|
||||
Blocks.SHORT_GRASS,
|
||||
Blocks.VINE );
|
||||
|
||||
/**
|
||||
* 世界边界
|
||||
* <br>
|
||||
* @see <a href="https://zh.minecraft.wiki/w/%E4%B8%96%E7%95%8C%E8%BE%B9%E7%95%8C#%E5%A4%A7%E5%B0%8F">Minecraft Wiki (中文)</a>
|
||||
* @see <a href="https://minecraft.wiki/w/World_border#General_information">Minecraft Wiki (English)</a>
|
||||
*/
|
||||
final static Integer WorldBorder = (int) 2.9e7;
|
||||
|
||||
/**
|
||||
* 执行命令所需权限等级
|
||||
* @see TeleportCommand
|
||||
* @see Commands
|
||||
* @see <a href="https://zh.minecraft.wiki/w/%E6%9D%83%E9%99%90%E7%AD%89%E7%BA%A7">Minecraft Wiki (中文)</a>
|
||||
* @see <a href="https://minecraft.wiki/w/Permission_level">Minecraft Wiki (English)</a>
|
||||
*/
|
||||
final static PermissionCheck PermissionLevel = Commands.LEVEL_GAMEMASTERS;
|
||||
|
||||
/**
|
||||
* 在传送之前记录当前位置,以支持传送回去
|
||||
*/
|
||||
static Map<UUID, Vec3> OldPositions = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 命令执行失败时的返回值
|
||||
* @see <a href="https://zh.minecraft.wiki/w/%E5%91%BD%E4%BB%A4#%E7%BB%93%E6%9E%9C">Minecraft Wiki (中文)</a>
|
||||
* @see <a href="https://minecraft.wiki/w/Commands">Minecraft Wiki (English)</a>
|
||||
*/
|
||||
final static int CommandExecuteFailure = 0;
|
||||
|
||||
/**
|
||||
* 使用Fabric API向游戏内注册命令
|
||||
* @param Name 根命令名
|
||||
* <br>
|
||||
* @see <a href="https://docs.fabricmc.net/zh_cn/develop/commands/basics">Fabric Docs (中文)</a>
|
||||
* @see <a href="https://wiki.fabricmc.net/zh_cn:tutorial:commands">Fabric Wiki (中文)</a>
|
||||
* @see <a href="https://docs.fabricmc.net/develop/commands/basics">Fabric Docs (English)</a>
|
||||
* @see <a href="https://wiki.fabricmc.net/tutorial:commands">Fabric Wiki (English)</a>
|
||||
*/
|
||||
public static void Register(String Name){
|
||||
// /rtp
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) ->{
|
||||
dispatcher.register(literal(Name)
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
context.getSource(),null,null, null)));});
|
||||
|
||||
// /rtp
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),null,null, null, null, null))
|
||||
// /rtp back
|
||||
.then(literal("back")
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> TeleportBack(
|
||||
context.getSource(), null)))
|
||||
// /rtp back <PlayerID(被传送玩家名)>
|
||||
.then(literal("back")
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> TeleportBack(
|
||||
context.getSource(),
|
||||
EntityArgument.getEntity(context,CommandArgumentName_Target)))))
|
||||
// /rtp <PlayerID(被传送玩家名)> back
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.then(literal("back")
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> TeleportBack(
|
||||
context.getSource(),
|
||||
EntityArgument.getEntity(context,CommandArgumentName_Target)))))
|
||||
// /rtp <Radius(半径)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
|
||||
null,
|
||||
null))));});
|
||||
|
||||
// /rtp <被传送玩家名(PlayerID)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("被传送玩家名(PlayerID)", EntityArgumentType.entity())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
null,
|
||||
null,
|
||||
null)))
|
||||
// /rtp <PlayerID(被传送玩家名)>
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
null,
|
||||
EntityArgumentType.getEntity(context,"被传送玩家名(PlayerID)"),
|
||||
null))));});
|
||||
|
||||
// /rtp <Radius(半径)> <被传送玩家名(PlayerID)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.then(argument("被传送玩家名(PlayerID)", EntityArgumentType.entity())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
EntityArgument.getEntity(context,CommandArgumentName_Target),
|
||||
null,
|
||||
null,
|
||||
null)))
|
||||
// /rtp <Radius(半径)> <PlayerID(被传送玩家名)>
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
EntityArgumentType.getEntity(context,"被传送玩家名(PlayerID)"),
|
||||
null)))));});
|
||||
|
||||
// /rtp <被传送玩家名(PlayerID)> <Radius(半径)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("被传送玩家名(PlayerID)", EntityArgumentType.entity())
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
|
||||
EntityArgument.getEntity(context,CommandArgumentName_Target),
|
||||
null,
|
||||
null,
|
||||
null))))
|
||||
// /rtp <PlayerID(被传送玩家名)> <Radius(半径)>
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
EntityArgumentType.getEntity(context,"被传送玩家名(PlayerID)"),
|
||||
null)))));});
|
||||
|
||||
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
|
||||
EntityArgument.getEntity(context,CommandArgumentName_Target),
|
||||
null,
|
||||
null,
|
||||
null))))
|
||||
// // /rtp <Radius(半径)> <Origin(随机中心)>
|
||||
// CommandRegistrationCallback.EVENT
|
||||
// .register((dispatcher, registryAccess, environment) -> {
|
||||
// dispatcher.register(literal(Name)
|
||||
// .then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
// .then(argument("Origin(随机中心)",EntityArgumentType.player())
|
||||
// .requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
// .requires(Commands.hasPermission(PermissionLevel))
|
||||
// .executes(context -> execute_command_origin(
|
||||
// context.getSource(),
|
||||
// LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
// null,
|
||||
// EntityArgumentType.getEntity(context,"Origin(随机中心)"))))));});
|
||||
// EntityArgumentType.getEntity(context,"Origin(随机中心)")))))
|
||||
// /rtp <Radius(半径)> <OriginPos(随机中心,坐标)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.then(argument("OriginPos(随机中心,坐标)",Vec3ArgumentType.vec3())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.then(argument(CommandArgumentName_OriginPosition, Vec2Argument.vec2())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
|
||||
null,
|
||||
Vec3ArgumentType.getVec3(context,"OriginPos(随机中心,坐标)"))))));});
|
||||
|
||||
// /rtp <Radius(半径)> <被传送玩家名(PlayerID)> <OriginEntity(随机中心,实体)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.then(argument("被传送玩家名(PlayerID)", EntityArgumentType.entity())
|
||||
.then(argument("OriginEntity(随机中心,实体)",EntityArgumentType.entity())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition),
|
||||
null,
|
||||
null))))
|
||||
// /rtp <Radius(半径)> <PlayerID(被传送玩家名)> <OriginEntity(随机中心,实体)>
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.then(argument(CommandArgumentName_OriginEntity, EntityArgument.entity())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
EntityArgumentType.getEntity(context,"被传送玩家名(PlayerID)"),
|
||||
EntityArgumentType.getEntity(context,"OriginEntity(随机中心,实体)").getPos()))))));});
|
||||
|
||||
// /rtp <Radius(半径)> <被传送玩家名(PlayerID)> <OriginPos(随机中心,坐标)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.then(argument("被传送玩家名(PlayerID)", EntityArgumentType.entity())
|
||||
.then(argument("OriginPos(随机中心,坐标)",Vec3ArgumentType.vec3())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
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 ),
|
||||
null,
|
||||
null)))))
|
||||
// /rtp <Radius(半径)> <PlayerID(被传送玩家名)> <OriginPos(随机中心,坐标)>
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.then(argument(CommandArgumentName_OriginPosition, Vec2Argument.vec2())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
EntityArgumentType.getEntity(context,"被传送玩家名(PlayerID)"),
|
||||
Vec3ArgumentType.getVec3(context,"OriginPos(随机中心,坐标)")))))));});
|
||||
|
||||
// /rtp <被传送玩家名(PlayerID)> <Radius(半径)> <OriginEntity(随机中心,实体)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("被传送玩家名(PlayerID)", EntityArgumentType.entity())
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.then(argument("OriginEntity(随机中心,实体)",EntityArgumentType.entity())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
|
||||
EntityArgument.getEntity(context,CommandArgumentName_Target),
|
||||
Vec2Argument.getVec2(context,CommandArgumentName_OriginPosition),
|
||||
null,
|
||||
null)))))
|
||||
// /rtp <PlayerID(被传送玩家名)> <Radius(半径)> <OriginEntity(随机中心,实体)>
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.then(argument(CommandArgumentName_OriginEntity, EntityArgument.entity())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
EntityArgumentType.getEntity(context,"被传送玩家名(PlayerID)"),
|
||||
EntityArgumentType.getEntity(context,"OriginEntity(随机中心,实体)").getPos()))))));});
|
||||
|
||||
// /rtp <被传送玩家名(PlayerID)> <Radius(半径)> <OriginPos(随机中心,坐标)>
|
||||
CommandRegistrationCallback.EVENT
|
||||
.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(literal(Name)
|
||||
.then(argument("被传送玩家名(PlayerID)", EntityArgumentType.entity())
|
||||
.then(argument("Radius(半径)", LongArgumentType.longArg())
|
||||
.then(argument("OriginPos(随机中心,坐标)",Vec3ArgumentType.vec3())
|
||||
.requires(source -> source.hasPermissionLevel(PermissionLevel))
|
||||
.executes(context -> execute_command(
|
||||
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 ),
|
||||
null,
|
||||
null)))))
|
||||
// /rtp <PlayerID(被传送玩家名)> <Radius(半径)> <OriginPos(随机中心,坐标)>
|
||||
.then(argument(CommandArgumentName_Target, EntityArgument.entity())
|
||||
.then(argument(CommandArgumentName_Radius, IntegerArgumentType.integer(0))
|
||||
.then(argument(CommandArgumentName_OriginPosition, Vec2Argument.vec2())
|
||||
.requires(Commands.hasPermission(PermissionLevel))
|
||||
.executes(context -> ExecuteCommand(
|
||||
context.getSource(),
|
||||
LongArgumentType.getLong(context, "Radius(半径)"),
|
||||
EntityArgumentType.getEntity(context,"被传送玩家名(PlayerID)"),
|
||||
Vec3ArgumentType.getVec3(context,"OriginPos(随机中心,坐标)")))))));});}
|
||||
IntegerArgumentType.getInteger(context, CommandArgumentName_Radius),
|
||||
EntityArgument.getEntity(context,CommandArgumentName_Target),
|
||||
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 )))))) );});}
|
||||
|
||||
/**
|
||||
* 向游戏内注册命令
|
||||
* <br>
|
||||
* 是 {@link CommandRegister#Register(String)} 的包装器
|
||||
* @see CommandRegister#Register(String)
|
||||
*/
|
||||
public static void Register(){
|
||||
Register("随机传送");
|
||||
Register("rtp");}
|
||||
static int execute_command(ServerCommandSource Source, @Nullable Long Radius, @Nullable Entity Player, @Nullable Vec3d Origin){
|
||||
Entity entity = Player == null ? Source.getPlayer() : Player;
|
||||
if (entity == null) {
|
||||
Source.sendFeedback(()->{ return Text.translatable("error.not_player"); }, true);
|
||||
return -1;}
|
||||
if (Radius == null){Radius = WorldBorder - (long) 1e4;}
|
||||
Radius = Math.abs(Radius);
|
||||
long Coordinate_X;
|
||||
long Coordinate_Z;
|
||||
if (Origin == null){
|
||||
Coordinate_X = new SplittableRandom().nextLong(-Radius, Radius);
|
||||
Coordinate_Z = new SplittableRandom().nextLong(-Radius, Radius);}
|
||||
Register("rtp");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Source 命令执行者
|
||||
* @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, @Nullable Vec2 RegionFrom, @Nullable Vec2 RegionTo){
|
||||
Entity TargetEntity = Entity == null ? Source.getPlayer() : Entity;
|
||||
/*
|
||||
↑
|
||||
Entity TargetEntity = null;
|
||||
if (TargetEntity == null){
|
||||
TargetEntity = Source.getPlayer();}
|
||||
else{
|
||||
Coordinate_X = new SplittableRandom().nextLong(Math.round(Origin.getX() - Radius), Math.round(Origin.getX() + Radius));
|
||||
Coordinate_Z = new SplittableRandom().nextLong(Math.round(Origin.getZ() - Radius), Math.round(Origin.getZ() + Radius));}
|
||||
int Coordinate_Y = 320;
|
||||
for (var CurrentBlock = Source.getWorld().getBlockState(new BlockPos(Math.toIntExact(Coordinate_X), Coordinate_Y, Math.toIntExact(Coordinate_Z))).getBlock();
|
||||
// 从世界顶层往下找,直到遇到一个非空气方块
|
||||
Blocks.AIR == CurrentBlock ||
|
||||
Blocks.VOID_AIR == CurrentBlock ||
|
||||
Blocks.CAVE_AIR == CurrentBlock
|
||||
;CurrentBlock = Source.getWorld().getBlockState(new BlockPos(Math.toIntExact(Coordinate_X), Coordinate_Y, Math.toIntExact(Coordinate_Z))).getBlock()){
|
||||
Coordinate_Y--;}
|
||||
TargetEntity = Entity;}
|
||||
*/
|
||||
if (TargetEntity == null) {
|
||||
Source.sendSuccess(()->{ return Component.translatableWithFallback("error.no_target","不存在被传送目标,由非玩家物体执行命令时请显式指定被传送玩家ID"); }, true);
|
||||
return CommandExecuteFailure; }
|
||||
int Coordinate_X = 0;
|
||||
int Coordinate_Z = 0;
|
||||
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.sendFailure(Component.translatableWithFallback("warning.radius_equal_zero_no_target", "由于你设置的随机半径为0,并且未设置随机中心点坐标,因此什么都不会发生"));
|
||||
return CommandExecuteFailure; }
|
||||
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在被除数小于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++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
// 如果传送到的位置周围一圈是空气、水或岩浆,将其替换为玻璃
|
||||
var BlockPos = new BlockPos(Math.toIntExact(Coordinate_X - x), Coordinate_Y, Math.toIntExact(Coordinate_Z - z));
|
||||
var CurrentBlock = Source.getWorld().getBlockState(BlockPos).getBlock();
|
||||
if ( CurrentBlock == Blocks.AIR ||
|
||||
CurrentBlock == Blocks.VOID_AIR ||
|
||||
CurrentBlock == Blocks.CAVE_AIR ||
|
||||
CurrentBlock == Blocks.WATER ||
|
||||
CurrentBlock == Blocks.LAVA ){
|
||||
// 只替换空气、水和岩浆,其余保留
|
||||
Source.getWorld().setBlockState(BlockPos, Blocks.GLASS.getDefaultState());}}}
|
||||
// if ( String.valueOf(entity.getWorld().getBiome(new BlockPos(Math.toIntExact(Coordinate_X), Coordinate_Y, Math.toIntExact(Coordinate_Z))).getKey()).equals("minecraft:the_void") ) {
|
||||
// 如果传送到的位置周围一圈是ReplaceToTargetBlock的方块,将其替换为TargetBlock
|
||||
BlockPos.set(Coordinate_X - x, Coordinate_Y - 1, Coordinate_Z - z);
|
||||
var CurrentBlock = EntityWorld.getBlockState(BlockPos).getBlock();
|
||||
if ( ReplaceToTargetBlock.contains(CurrentBlock) ) {
|
||||
// 只替换ReplaceToTargetBlock内的方块,其余保留
|
||||
EntityWorld.setBlockAndUpdate(BlockPos, TargetBlock.defaultBlockState());}}}
|
||||
// if ( String.valueOf(TargetEntity.getWorld().getBiome(new BlockPos(Math.toIntExact(Coordinate_X), Coordinate_Y, Math.toIntExact(Coordinate_Z))).getKey()).equals("minecraft:the_void") ) {
|
||||
// Coordinate_Y++;}
|
||||
Coordinate_Y++;
|
||||
// ↑ 高一层,人别站在土里了
|
||||
entity.teleport(Source.getWorld(),Coordinate_X + 0.5, Coordinate_Y, Coordinate_Z + 0.5, new HashSet<>(), entity.getYaw(), entity.getPitch(), false);
|
||||
Source.sendFeedback(()->{ return Text.translatable("info.success", entity.getName(), Coordinate_Z, Coordinate_Z, Coordinate_Z); },true);
|
||||
return 0;}
|
||||
OldPositions.put(TargetEntity.getUUID(), TargetEntity.position());
|
||||
TargetEntity.teleportTo((ServerLevel) EntityWorld,Coordinate_X + 0.5, Coordinate_Y, Coordinate_Z + 0.5, new HashSet<>(), TargetEntity.getYRot(), TargetEntity.getXRot(), false);
|
||||
int finalCoordinate_X = Coordinate_X;
|
||||
int finalCoordinate_Z = Coordinate_Z;
|
||||
// ↑ "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; }
|
||||
|
||||
static int TeleportBack(CommandSourceStack Source, @Nullable Entity TargetEntity) {
|
||||
TargetEntity = TargetEntity != null ? TargetEntity : Source.getPlayer();
|
||||
/*
|
||||
↑
|
||||
if (TargetEntity == null){
|
||||
TargetEntity = Source.getPlayer(); }
|
||||
*/
|
||||
if (TargetEntity == null) {
|
||||
Source.sendFailure(Component.translatableWithFallback("error.no_target", "不存在被传送目标,由非玩家物体执行命令时请显式指定被传送玩家ID"));
|
||||
return CommandExecuteFailure; }
|
||||
var OldPos = OldPositions.get(TargetEntity.getUUID());
|
||||
if (OldPos == null) {
|
||||
Source.sendFailure(Component.translatableWithFallback("error.no_old_position", "%s还未使用过随机传送,因此无法回溯", TargetEntity.getName().getString()));
|
||||
return CommandExecuteFailure; }
|
||||
else {
|
||||
TargetEntity.teleportTo(( ServerLevel) TargetEntity.level(), OldPos.x, OldPos.y, OldPos.z, new HashSet<>(), TargetEntity.getYRot(), TargetEntity.getXRot(), false);
|
||||
Entity finalTargetEntity = TargetEntity;
|
||||
// ↑ "lambda 表达式中使用的变量应为 final 或有效 final"
|
||||
Source.sendSuccess(() -> Component.translatableWithFallback("info.success.back", "已将玩家%s传送回原位置", finalTargetEntity.getName().getString()), true);
|
||||
return Command.SINGLE_SUCCESS; } }
|
||||
}
|
||||
@@ -9,14 +9,18 @@ public class RandomTeleporter implements ModInitializer {
|
||||
// This logger is used to write text to the console and the log file.
|
||||
// It is considered best practice to use your mod id as the logger's name.
|
||||
// That way, it's clear which mod wrote info, warnings, and errors.
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("randomteleporter");
|
||||
public static final String MOD_ID = "randomteleporter";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// This code runs as soon as Minecraft is in a mod-load-ready state.
|
||||
// However, some things (like resources) may still be uninitialized.
|
||||
// Proceed with mild caution.
|
||||
|
||||
ResourceReloaderListener.Register();
|
||||
ServerLifecycleListener.Register();
|
||||
CommandRegister.Register();
|
||||
LOGGER.info("RandomTeleporter Loading!");
|
||||
LOGGER.info("RandomTeleporter已写入命令注册回调,目标命令将会在该注册的时候被注册");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package xyz.thewhitedog9487;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.v1.ResourceLoader;
|
||||
import net.fabricmc.fabric.api.resource.v1.reloader.SimpleReloadListener;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
|
||||
import static net.minecraft.server.packs.PackType.CLIENT_RESOURCES;
|
||||
import static xyz.thewhitedog9487.RandomTeleporter.MOD_ID;
|
||||
|
||||
/**
|
||||
* 在游戏资源重新加载之后刷新翻译文本
|
||||
*/
|
||||
public class ResourceReloaderListener {
|
||||
public static String CommandArgumentName_Radius = "Radius(半径)";
|
||||
public static String CommandArgumentName_Target = "PlayerID(被传送玩家名)";
|
||||
public static String CommandArgumentName_OriginPosition = "OriginPos(随机中心,坐标)";
|
||||
public static String CommandArgumentName_OriginEntity = "OriginEntity(随机中心,实体)";
|
||||
public static String CommandArgumentName_RegionFromPosition = "RegionFrom(随机范围起始位置,坐标)";
|
||||
public static String CommandArgumentName_RegionToPosition = "RegionTo(随机范围结束位置,坐标)";
|
||||
public static String CommandArgumentName_RegionFromEntity = "RegionFrom(随机范围起始位置,实体)";
|
||||
public static String CommandArgumentName_RegionToEntity = "RegionTo(随机范围结束位置,实体)";
|
||||
|
||||
public static void Register(){
|
||||
ResourceLoader.get(CLIENT_RESOURCES).registerReloadListener(Identifier.fromNamespaceAndPath(MOD_ID, "translate_text_apply"), new SimpleReloadListener<Void>() {
|
||||
/**
|
||||
* 用不到,不用管
|
||||
*/
|
||||
@Override
|
||||
protected Void prepare(PreparableReloadListener.@NonNull SharedState store) {
|
||||
return null; }
|
||||
|
||||
@Override
|
||||
protected void apply(Void prepared, PreparableReloadListener.@NonNull SharedState store) {
|
||||
CommandArgumentName_Radius = Component.translatableWithFallback("command.argument.radius", "Radius(半径)").getString();
|
||||
CommandArgumentName_Target = Component.translatableWithFallback("command.argument.target", "PlayerID(被传送玩家名)").getString();
|
||||
CommandArgumentName_OriginPosition = Component.translatableWithFallback("command.argument.origin_pos", "OriginPos(随机中心,坐标)").getString();
|
||||
CommandArgumentName_OriginEntity = Component.translatableWithFallback("command.argument.origin_entity", "OriginEntity(随机中心,实体)").getString();
|
||||
CommandArgumentName_RegionFromPosition = Component.translatableWithFallback("command.argument.region_from_pos", "RegionFrom(随机范围起始位置,坐标)").getString();
|
||||
CommandArgumentName_RegionToPosition = Component.translatableWithFallback("command.argument.region_to_pos", "RegionTo(随机范围结束位置,坐标)").getString();
|
||||
CommandArgumentName_RegionFromEntity = Component.translatableWithFallback("command.argument.region_from_entity", "RegionFrom(随机范围起始位置,实体)").getString();
|
||||
CommandArgumentName_RegionToEntity = Component.translatableWithFallback("command.argument.region_to_entity", "RegionTo(随机范围结束位置,实体)").getString(); } } ); } }
|
||||
@@ -0,0 +1,9 @@
|
||||
package xyz.thewhitedog9487;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
|
||||
public class ServerLifecycleListener {
|
||||
public static void Register() {
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
|
||||
CommandRegister.OldPositions.clear();
|
||||
RandomTeleporter.LOGGER.info("已清空传送历史记录"); } ); } }
|
||||
@@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(MinecraftServer.class)
|
||||
public class ExampleMixin {
|
||||
@Inject(at = @At("HEAD"), method = "loadWorld")
|
||||
@Inject(at = @At("HEAD"), method = "loadLevel")
|
||||
private void init(CallbackInfo info) {
|
||||
// This code is injected into the start of MinecraftServer.loadWorld()V
|
||||
}
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
{
|
||||
"modmenu.nameTranslation.randomteleporter": "RandomTeleporter",
|
||||
"modmenu.descriptionTranslation.randomteleporter": "Added two commands for random teleportation",
|
||||
"info.success": "Teleported %s to %d %d %d",
|
||||
"info.success.back": "Teleported %s back to original position",
|
||||
"error.no_target": "There is no teleported target, and the teleported player ID is explicitly specified when executed by a non-player object",
|
||||
"error.no_old_position": "%s has not used random teleport yet, so it cannot be traced back",
|
||||
"warning.radius_equal_zero": "Warning: Since you set a random radius of 0, selecting the right height will teleport you directly to %d %d",
|
||||
"warning.radius_equal_zero_no_target": "Warning: Since you set a random radius of 0 and you don't set a random center point coordinates, nothing happens",
|
||||
"bilibili": "Bilibili",
|
||||
"blog": "Blog"
|
||||
"command.argument.radius": "radius",
|
||||
"command.argument.target": "teleported entity",
|
||||
"command.argument.origin_pos": "origin(pos)",
|
||||
"command.argument.origin_entity": "origin(entity)",
|
||||
"command.argument.region_from_pos": "region start(pos)",
|
||||
"command.argument.region_to_pos": "region end(pos)",
|
||||
"command.argument.region_from_entity": "region start(entity)",
|
||||
"command.argument.region_to_entity": "region end(entity)"
|
||||
}
|
||||
@@ -2,7 +2,18 @@
|
||||
"modmenu.nameTranslation.randomteleporter": "随机传送",
|
||||
"modmenu.descriptionTranslation.randomteleporter": "增加了两个用于随机传送的命令",
|
||||
"info.success": "已将玩家%s传送到%d %d %d",
|
||||
"error.not_player": "执行命令的不是玩家",
|
||||
"info.success.back": "已将玩家%s传送回原位置",
|
||||
"error.no_target": "不存在被传送目标,由非玩家物体执行命令时请显式指定被传送玩家ID",
|
||||
"error.no_old_position": "%s还未使用过随机传送,因此无法回溯",
|
||||
"warning.radius_equal_zero": "警告:由于你设置的随机半径为0,因此在选择出合适高度之后将直接把你传送至%d %d",
|
||||
"warning.radius_equal_zero_no_target": "警告:由于你设置的随机半径为0,并且未设置随机中心点坐标,因此什么都不会发生",
|
||||
"bilibili": "TheWhiteDog9487的哔哩哔哩主页",
|
||||
"blog": "TheWhiteDog9487的博客"
|
||||
"command.argument.radius": "半径",
|
||||
"command.argument.target": "被传送实体",
|
||||
"command.argument.origin_pos": "随机中心(坐标)",
|
||||
"command.argument.origin_entity": "随机中心(实体)",
|
||||
"command.argument.region_from_pos": "坐标选取区域起点(坐标)",
|
||||
"command.argument.region_to_pos": "坐标选取区域终点(坐标)",
|
||||
"command.argument.region_from_entity": "坐标选取区域起点(实体)",
|
||||
"command.argument.region_to_entity": "坐标选取区域终点(实体)"
|
||||
}
|
||||
@@ -27,10 +27,10 @@
|
||||
}
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.15.11",
|
||||
"minecraft": "1.21.2",
|
||||
"java": ">=21",
|
||||
"fabric-api": "*"
|
||||
"fabricloader": ">=0.18.6",
|
||||
"minecraft": "26.1.1",
|
||||
"java": ">=25",
|
||||
"fabric-api": ">=0.145.3"
|
||||
},
|
||||
"suggests": {
|
||||
"another-mod": "*"
|
||||
@@ -38,7 +38,6 @@
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"links": {
|
||||
"bilibili": "https://space.bilibili.com/401746666",
|
||||
"blog": "www.thewhitedog9487.xyz"},
|
||||
"update_checker": true}}
|
||||
"bilibili": "https://space.bilibili.com/401746666"},
|
||||
"update_checker": true } }
|
||||
}
|
||||
Reference in New Issue
Block a user