Compare commits

..

20 Commits

Author SHA1 Message Date
67bbef432b feat: 支持自定义姿势 2026-05-17 10:51:49 +08:00
5fb2c614db build: 版本号更为正式版
Some checks failed
Build and Release / build (push) Failing after 34s
Build and Release / release (push) Has been skipped
2026-03-18 23:24:26 +08:00
c05c0bdfc4 build: 修改导致curseforge推送失败的json写法
Some checks failed
Build and Release / build (push) Failing after 34s
Build and Release / release (push) Has been skipped
2026-03-18 23:03:54 +08:00
5a1c2fdbc5 build: 修正CurseForge发布 2026-03-18 22:51:35 +08:00
c9b9e0eefe build: 工作流修正
Some checks failed
Build and Release / build (push) Failing after 1m33s
Build and Release / release (push) Has been skipped
2026-03-18 22:30:37 +08:00
f589cf27a2 build: 修复错误发布问题
Some checks failed
Build and Release / build (push) Failing after 33s
Build and Release / release (push) Has been skipped
2026-03-18 22:02:08 +08:00
35ceb69f0b build: 工作流脚本修复 2026-03-18 21:35:36 +08:00
dbae05691d build: 工作流
Some checks failed
Build and Release / build (push) Failing after 33s
Build and Release / release (push) Has been skipped
2026-03-18 21:19:01 +08:00
a435c3b272 build: 工作流修正 2026-03-18 21:15:24 +08:00
04640d2b12 build: 发布工作流更新
Some checks failed
Build and Release / build (push) Failing after 2h30m21s
Build and Release / release (push) Has been skipped
2026-03-18 20:55:17 +08:00
9dbeb0732f build: 修复发布脚本
Some checks failed
Build and Release / build (push) Failing after 16m59s
Build and Release / release (push) Has been skipped
2026-03-16 15:31:03 +08:00
408482759a Merge remote-tracking branch 'origin/MultiLoader_1_20_1' into MultiLoader_1_20_1 2026-03-16 15:08:07 +08:00
e4fe0f17f2 build: 移除加载DLL的行为(添加模组平台发布流程) 2026-03-16 15:07:46 +08:00
3944Realms
4cdbefc9c3
docs: Merge pull request #3 from 3944Realms/ML_1201_PR
docs: Update implementation section in README.md
2026-03-16 12:39:08 +08:00
3944Realms
c653832a9c
docs: Update implementation section in README.md
Clarified implementation instructions for version 0.5.0+.
2026-03-16 12:35:31 +08:00
85c4c47a72 build: 匹配src路径 2026-03-16 12:31:43 +08:00
80872ebbaa build: 格式检查配置 2026-03-16 12:16:25 +08:00
a5d00dad96 docs: 更新Readme,编写些提示 2026-03-16 11:29:27 +08:00
9eec9972f4 feat: 添加玩偶的Jade皮肤所属者的显示 2026-03-15 13:44:07 +08:00
6c6883b767 feat: 改为多角度的玩偶 2026-03-15 13:10:55 +08:00
90 changed files with 1752 additions and 322 deletions

View File

@ -83,7 +83,18 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Determine version type
id: version_type
run: |
if [[ "${{ github.ref_name }}" == *"alpha"* ]]; then
echo "type=alpha" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref_name }}" == *"beta"* ]]; then
echo "type=beta" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref_name }}" == *"rc"* ]]; then
echo "type=beta" >> $GITHUB_OUTPUT
else
echo "type=release" >> $GITHUB_OUTPUT
fi
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
@ -97,6 +108,69 @@ jobs:
VERSION="${GITHUB_REF_NAME#v}" VERSION="${GITHUB_REF_NAME#v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "minecraft_version=$(grep "^minecraft_version=" gradle.properties | cut -d'=' -f2)" >> $GITHUB_OUTPUT echo "minecraft_version=$(grep "^minecraft_version=" gradle.properties | cut -d'=' -f2)" >> $GITHUB_OUTPUT
# 从 gradle.properties 提取 mod_id如果没有则尝试从文件名推断
MOD_ID=$(grep "^mod_id=" gradle.properties | cut -d'=' -f2 || echo "")
if [ -z "$MOD_ID" ]; then
# 尝试从现有的 jar 文件名提取 mod_id
SAMPLE_JAR=$(ls dist/ | grep -m 1 -E ".*-(fabric|forge)-.*\.jar" || echo "")
if [ -n "$SAMPLE_JAR" ]; then
MOD_ID=$(echo "$SAMPLE_JAR" | sed -E 's/-(fabric|forge)-.*//')
else
MOD_ID="mymod" # 默认值,请根据实际情况修改
fi
fi
echo "mod_id=$MOD_ID" >> $GITHUB_OUTPUT
# 从 gradle.properties 提取 mod_name用于显示
MOD_NAME=$(grep "^mod_name=" gradle.properties | cut -d'=' -f2 || echo "My Mod")
echo "mod_name=$MOD_NAME" >> $GITHUB_OUTPUT
# 从 gradle.properties 提取 modrinth_id
MODRINTH_ID=$(grep "^modrinth_id=" gradle.properties | cut -d'=' -f2 || echo "")
echo "modrinth_id=$MODRINTH_ID" >> $GITHUB_OUTPUT
# 从 gradle.properties 提取 curseforge_id
CURSEFORGE_ID=$(grep "^curseforge_id=" gradle.properties | cut -d'=' -f2 || echo "")
echo "curseforge_id=$CURSEFORGE_ID" >> $GITHUB_OUTPUT
# Java版本 - 使用简单格式不用JSON
JAVA_VERSIONS=$(grep "^java_versions=" gradle.properties | cut -d'=' -f2- || echo "21,17")
# 清理格式,移除无效字符
JAVA_VERSIONS=$(echo "$JAVA_VERSIONS" | sed 's/\[//g; s/\]//g; s/"//g; s/ //g; s/21a/21/g' | tr -d '\r')
echo "java_versions=$JAVA_VERSIONS" >> $GITHUB_OUTPUT
# 读取发布控制布尔值(默认都为 true
PUBLISH_GITHUB=$(grep "^publish_github=" gradle.properties | cut -d'=' -f2 | tr '[:upper:]' '[:lower:]' | tr -d ' ' || echo "true")
if [ "$PUBLISH_GITHUB" = "true" ] || [ "$PUBLISH_GITHUB" = "1" ] || [ "$PUBLISH_GITHUB" = "yes" ]; then
echo "publish_github=true" >> $GITHUB_OUTPUT
else
echo "publish_github=false" >> $GITHUB_OUTPUT
fi
PUBLISH_MODRINTH=$(grep "^publish_modrinth=" gradle.properties | cut -d'=' -f2 | tr '[:upper:]' '[:lower:]' | tr -d ' ' || echo "true")
if [ "$PUBLISH_MODRINTH" = "true" ] || [ "$PUBLISH_MODRINTH" = "1" ] || [ "$PUBLISH_MODRINTH" = "yes" ]; then
echo "publish_modrinth=true" >> $GITHUB_OUTPUT
else
echo "publish_modrinth=false" >> $GITHUB_OUTPUT
fi
PUBLISH_CURSEFORGE=$(grep "^publish_curseforge=" gradle.properties | cut -d'=' -f2 | tr '[:upper:]' '[:lower:]' | tr -d ' ' || echo "true")
if [ "$PUBLISH_CURSEFORGE" = "true" ] || [ "$PUBLISH_CURSEFORGE" = "1" ] || [ "$PUBLISH_CURSEFORGE" = "yes" ]; then
echo "publish_curseforge=true" >> $GITHUB_OUTPUT
else
echo "publish_curseforge=false" >> $GITHUB_OUTPUT
fi
# 读取依赖配置 - 使用简单字符串不用JSON
FABRIC_MODRINTH_DEPS=$(grep "^fabric_modrinth_dependencies=" gradle.properties | cut -d'=' -f2- || echo "")
echo "fabric_modrinth_dependencies=$FABRIC_MODRINTH_DEPS" >> $GITHUB_OUTPUT
FORGE_MODRINTH_DEPS=$(grep "^forge_modrinth_dependencies=" gradle.properties | cut -d'=' -f2- || echo "")
echo "forge_modrinth_dependencies=$FORGE_MODRINTH_DEPS" >> $GITHUB_OUTPUT
FABRIC_CURSEFORGE_DEPS=$(grep "^fabric_curseforge_dependencies=" gradle.properties | cut -d'=' -f2- || echo "")
echo "fabric_curseforge_dependencies=$FABRIC_CURSEFORGE_DEPS" >> $GITHUB_OUTPUT
FORGE_CURSEFORGE_DEPS=$(grep "^forge_curseforge_dependencies=" gradle.properties | cut -d'=' -f2- || echo "")
echo "forge_curseforge_dependencies=$FORGE_CURSEFORGE_DEPS" >> $GITHUB_OUTPUT
- name: Generate CZ-compliant changelog - name: Generate CZ-compliant changelog
id: generate_changelog id: generate_changelog
@ -139,6 +213,7 @@ jobs:
["👷 CI"]="^(ci)(\(.*\))?:" ["👷 CI"]="^(ci)(\(.*\))?:"
["📦 依赖"]="^(chore|deps)(\(.*\))?:" ["📦 依赖"]="^(chore|deps)(\(.*\))?:"
["⏪ 回退"]="^(revert)(\(.*\))?:" ["⏪ 回退"]="^(revert)(\(.*\))?:"
["🛠 合并"]="^Merge "
) )
# 获取所有提交 # 获取所有提交
@ -220,37 +295,6 @@ jobs:
echo "---" >> $TEMP_FILE echo "---" >> $TEMP_FILE
echo "" >> $TEMP_FILE echo "" >> $TEMP_FILE
echo "## 📦 下载文件" >> $TEMP_FILE
echo "" >> $TEMP_FILE
echo "本次发布包含以下平台的构建文件:" >> $TEMP_FILE
echo "" >> $TEMP_FILE
# 列出所有发布的文件
echo "### Fabric 版本" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
ls -1 dist/*fabric*.jar 2>/dev/null | grep -v "sources\|javadoc" | xargs -n1 basename || echo "无 Fabric 主文件" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
echo "" >> $TEMP_FILE
echo "### Forge 版本" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
ls -1 dist/*forge*.jar 2>/dev/null | grep -v "sources\|javadoc" | xargs -n1 basename || echo "无 Forge 主文件" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
echo "" >> $TEMP_FILE
echo "### 通用模块" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
ls -1 dist/*common*.jar 2>/dev/null | grep -v "sources\|javadoc" | xargs -n1 basename || echo "无通用模块" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
echo "" >> $TEMP_FILE
echo "### 源码和文档" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
ls -1 dist/*-sources.jar 2>/dev/null | xargs -n1 basename || echo "无源码文件" >> $TEMP_FILE
ls -1 dist/*-javadoc.jar 2>/dev/null | xargs -n1 basename || echo "无文档文件" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE
echo "" >> $TEMP_FILE
echo "### 📜 详细提交历史" >> $TEMP_FILE echo "### 📜 详细提交历史" >> $TEMP_FILE
echo "" >> $TEMP_FILE echo "" >> $TEMP_FILE
echo "<details>" >> $TEMP_FILE echo "<details>" >> $TEMP_FILE
@ -258,13 +302,19 @@ jobs:
echo "" >> $TEMP_FILE echo "" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE echo "\`\`\`" >> $TEMP_FILE
# 显示所有提交的详细列表
if [ -z "$PREV_TAG" ]; then if [ -z "$PREV_TAG" ]; then
git log --pretty=format:"%h %s - %an (%ad)" --date=short --reverse >> $TEMP_FILE # 使用 while 循环确保每条提交独立一行
git log --pretty=format:"%h %s - %an (%ad)" --date=short --reverse | while IFS= read -r line; do
echo "$line" >> $TEMP_FILE
done
else else
git log --pretty=format:"%h %s - %an (%ad)" --date=short $PREV_TAG..HEAD >> $TEMP_FILE git log --pretty=format:"%h %s - %an (%ad)" --date=short $PREV_TAG..HEAD | while IFS= read -r line; do
echo "$line" >> $TEMP_FILE
done
fi fi
# 确保文件末尾有换行
echo "" >> $TEMP_FILE
echo "\`\`\`" >> $TEMP_FILE echo "\`\`\`" >> $TEMP_FILE
echo "</details>" >> $TEMP_FILE echo "</details>" >> $TEMP_FILE
@ -275,6 +325,7 @@ jobs:
echo "EOF" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT
- name: Create Release - name: Create Release
if: steps.version_info.outputs.publish_github == 'true'
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
artifacts: | artifacts: |
@ -283,7 +334,121 @@ jobs:
name: "${{ steps.version_info.outputs.minecraft_version }} - ${{ github.ref_name }}" name: "${{ steps.version_info.outputs.minecraft_version }} - ${{ github.ref_name }}"
body: ${{ steps.generate_changelog.outputs.changelog }} body: ${{ steps.generate_changelog.outputs.changelog }}
draft: false draft: false
prerelease: false prerelease: ${{ contains(github.ref_name, 'rc') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'alpha') }}
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
allowUpdates: true allowUpdates: true
removeArtifacts: true removeArtifacts: true
# Fabric 发布到 Modrinth 和 CurseForge
- name: Publish Fabric to Modrinth & CurseForge
uses: Kir-Antipov/mc-publish@v3.3
if: success() && (steps.version_info.outputs.publish_modrinth == 'true' || steps.version_info.outputs.publish_curseforge == 'true')
continue-on-error: true
with:
# 文件匹配规则 - 只匹配 fabric 的文件
files: |
dist/${{ steps.version_info.outputs.mod_id }}-fabric-${{ steps.version_info.outputs.minecraft_version }}-${{ steps.version_info.outputs.version }}.jar
dist/${{ steps.version_info.outputs.mod_id }}-fabric-${{ steps.version_info.outputs.minecraft_version }}-${{ steps.version_info.outputs.version }}-javadoc.jar
dist/${{ steps.version_info.outputs.mod_id }}-fabric-${{ steps.version_info.outputs.minecraft_version }}-${{ steps.version_info.outputs.version }}-sources.jar
# 版本信息
name: ${{ steps.version_info.outputs.mod_name }} ${{ steps.version_info.outputs.version }} (Fabric/${{ steps.version_info.outputs.minecraft_version }})
version: "${{ steps.version_info.outputs.minecraft_version }}-fabric-${{ steps.version_info.outputs.version }}"
# 更新日志
changelog: ${{ steps.generate_changelog.outputs.changelog }}
# 版本类型
version-type: ${{ steps.version_type.outputs.type }}
# 只指定 Fabric 加载器
loaders: fabric
# 游戏版本
game-versions: |
${{ steps.version_info.outputs.minecraft_version }}
# Java版本
java: |
${{ steps.version_info.outputs.java_versions }}
# Modrinth 配置
modrinth-id: ${{ steps.version_info.outputs.modrinth_id }}
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
modrinth-featured: true
modrinth-unfeature-mode: any
modrinth-dependencies: ${{ steps.version_info.outputs.fabric_modrinth_dependencies }}
# CurseForge 配置
curseforge-id: ${{ steps.version_info.outputs.curseforge_id }}
curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }}
curseforge-dependencies: ${{ steps.version_info.outputs.fabric_curseforge_dependencies }}
# 失败处理
fail-mode: skip
# Forge 发布到 Modrinth 和 CurseForge
- name: Publish Forge to Modrinth & CurseForge
uses: Kir-Antipov/mc-publish@v3.3
if: success() && (steps.version_info.outputs.publish_modrinth == 'true' || steps.version_info.outputs.publish_curseforge == 'true')
continue-on-error: true
with:
# 文件匹配规则 - 只匹配 forge 的文件
files: |
dist/${{ steps.version_info.outputs.mod_id }}-forge-${{ steps.version_info.outputs.minecraft_version }}-${{ steps.version_info.outputs.version }}.jar
dist/${{ steps.version_info.outputs.mod_id }}-forge-${{ steps.version_info.outputs.minecraft_version }}-${{ steps.version_info.outputs.version }}-javadoc.jar
dist/${{ steps.version_info.outputs.mod_id }}-forge-${{ steps.version_info.outputs.minecraft_version }}-${{ steps.version_info.outputs.version }}-sources.jar
# 版本信息
name: ${{ steps.version_info.outputs.mod_name }} ${{ steps.version_info.outputs.version }} (Forge/${{ steps.version_info.outputs.minecraft_version }})
version: "${{ steps.version_info.outputs.minecraft_version }}-forge-${{ steps.version_info.outputs.version }}"
# 更新日志
changelog: ${{ steps.generate_changelog.outputs.changelog }}
# 版本类型
version-type: ${{ steps.version_type.outputs.type }}
# 只指定 Forge 加载器
loaders: forge
# 游戏版本
game-versions: |
${{ steps.version_info.outputs.minecraft_version }}
# Java版本
java: |
${{ steps.version_info.outputs.java_versions }}
# Modrinth 配置
modrinth-id: ${{ steps.version_info.outputs.modrinth_id }}
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
modrinth-featured: true
modrinth-unfeature-mode: any
modrinth-dependencies: ${{ steps.version_info.outputs.forge_modrinth_dependencies }}
# CurseForge 配置
curseforge-id: ${{ steps.version_info.outputs.curseforge_id }}
curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }}
curseforge-dependencies: ${{ steps.version_info.outputs.forge_curseforge_dependencies }}
# 失败处理
fail-mode: skip
# 发布完成后列出结果
- name: Summary
if: always()
run: |
echo "## 发布结果摘要" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### GitHub Release" >> $GITHUB_STEP_SUMMARY
echo "- 标签: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "- URL: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Modrinth" >> $GITHUB_STEP_SUMMARY
echo "- 项目ID: ${{ steps.version_info.outputs.modrinth_id }}" >> $GITHUB_STEP_SUMMARY
echo "- Fabric版本: ${{ steps.version_info.outputs.version }}-fabric" >> $GITHUB_STEP_SUMMARY
echo "- Forge版本: ${{ steps.version_info.outputs.version }}-forge" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### CurseForge" >> $GITHUB_STEP_SUMMARY
echo "- 项目ID: ${{ steps.version_info.outputs.curseforge_id }}" >> $GITHUB_STEP_SUMMARY
echo "- Fabric版本: ${{ steps.version_info.outputs.version }}-fabric" >> $GITHUB_STEP_SUMMARY
echo "- Forge版本: ${{ steps.version_info.outputs.version }}-forge" >> $GITHUB_STEP_SUMMARY

30
.github/workflows/styleCheck.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: Check Style in Pull Request
on:
pull_request_target:
jobs:
checkstyle:
runs-on: ubuntu-latest
permissions:
pull-requests: write
checks: write
contents: read
steps:
- name: checkout
uses: actions/checkout@v4
with:
ref: refs/pull/${{ github.event.number }}/merge
- name: Setup Java 17
uses: actions/setup-java@v3.6.0
with:
distribution: zulu
java-version: 17
- uses: reviewdog/action-setup@v1
with:
reviewdog_version: latest
- name: download checkstyle
run: curl -o checkstyle.jar -L https://github.com/checkstyle/checkstyle/releases/download/checkstyle-12.1.2/checkstyle-12.1.2-all.jar
- name: checkstyle
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: java -jar checkstyle.jar -c style.xml -f xml */src | reviewdog -f=checkstyle -name="Checkstyle" -reporter=github-pr-review -fail-level=any

View File

@ -6,9 +6,9 @@
**Lib39** is a general-purpose dependency library for Minecraft mods. **Lib39** is a general-purpose dependency library for Minecraft mods.
It provides utility methods and core functionality that other mods can build upon. It provides utility methods and core functionality that other mods can build upon.
### How to implementation? ### How to implementation? ( Only for Version 0.5.0+ )
**In repositories:** #### **In repositories:**
```groovy ```groovy
maven { maven {
@ -17,10 +17,41 @@ It provides utility methods and core functionality that other mods can build upo
} }
``` ```
**In dependencies:** #### **In dependencies:**
##### General
**gradle.properties**
```properties
lib39_version=0.5.1
````
##### For Loom
**build.gradle**
```groovy ```groovy
dependencies { dependencies {
implementation("top.r3944realms.lib39:lib39:1.20.1-0.4.1") modImplementation("top.r3944realms.lib39:lib39-fabric-1.20.1:${lib39_version}")
}
```
##### For ForgeGradle
**build.gradle**
```groovy
dependencies {
implementation fg.deof("top.r3944realms.lib39:lib39-forge-1.20.1:${lib39_version}")
}
```
##### For NeoForgeGradle / ModDevGradle
**build.gradle**
```groovy
dependencies {
modImplementation("top.r3944realms.lib39:lib39-forge-1.20.1:${lib39_version}")
}
```
##### For MultiLoader Project
Add this in your common subproject.
**build.gradle**
```groovy
dependencies {
implementation("top.r3944realms.lib39:lib39-common-1.20.1:${lib39_version}")
} }
``` ```

View File

@ -5,20 +5,26 @@ import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.core.command.SimpleCommandHelpManager; import top.r3944realms.lib39.core.command.SimpleCommandHelpManager;
/** /**
* The type Lib 39 command help manager. * <pre>
* 命令帮助注册管理类
* 这是一个模组内置的示例
* </pre>
*/ */
public class Lib39CommandHelpManager extends SimpleCommandHelpManager { public class Lib39CommandHelpManager extends SimpleCommandHelpManager {
/** /**
* The constant INSTANCE. * 单例模式
*/ */
public static volatile Lib39CommandHelpManager INSTANCE = new Lib39CommandHelpManager(); public static volatile Lib39CommandHelpManager INSTANCE = new Lib39CommandHelpManager();
/** /**
* The Id. * 作为唯一标识符
*/ */
ResourceLocation ID = Lib39.rl("command_helper"); ResourceLocation ID = Lib39.rl("command_helper");
/** /**
* <pre>
* 一定要在构造器方法里调用 {@link #initialize 初始化方法}
* Instantiates a new Lib 39 command help manager. * Instantiates a new Lib 39 command help manager.
* </pre>
*/ */
public Lib39CommandHelpManager() { public Lib39CommandHelpManager() {
initialize(); initialize();

View File

@ -21,11 +21,17 @@ import top.r3944realms.lib39.core.command.SimpleHelpCommand;
import java.util.Map; import java.util.Map;
/** /**
* The type Lib 39 help command. * <pre>
* 指令注册以及帮助编写类
* 这是一个模组内置的示例
* </pre>
*/ */
public class Lib39HelpCommand extends SimpleHelpCommand { public class Lib39HelpCommand extends SimpleHelpCommand {
/** /**
* <pre>
* 需要{@link CommandDispatcher<CommandSourceStack> 指令注册调度器} {@link CommandBuildContext 指令上下文}
* </pre>
* Instantiates a new Lib 39 help command. * Instantiates a new Lib 39 help command.
* *
* @param dispatcher the dispatcher * @param dispatcher the dispatcher

View File

@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer;
/** /**
* The enum Lib 39 lang key. * The enum Lib 39 lang key.
@ -248,6 +249,13 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
addLang(LangKeyValue.copyOf( addLang(LangKeyValue.copyOf(
Lib39Blocks.DOLL, ModPartEnum.BLOCK, dollName Lib39Blocks.DOLL, ModPartEnum.BLOCK, dollName
)); ));
addLang(LangKeyValue.copyOf(
Lib39Blocks.WALL_DOLL, ModPartEnum.BLOCK, dollName
));
addLang(
LangKeyValue.ofKey("config.jade.plugin_lib39.lib39", ModPartEnum.DEFAULT,
"Lib 39", "叁玖库", "叁玖庫", "叁玖庫"
));
addLang(LangKeyValue.ofKey( addLang(LangKeyValue.ofKey(
"tooltip.lib39.content.doll.hover.1", ModPartEnum.DESCRIPTION, "tooltip.lib39.content.doll.hover.1", ModPartEnum.DESCRIPTION,
"§eSkinOwner §7:§a %s ", "§e皮肤所有者§7:§a%s", "§e皮膚所有者§7:§a%s", "§e膚主§7:§a%s" "§eSkinOwner §7:§a %s ", "§e皮肤所有者§7:§a%s", "§e皮膚所有者§7:§a%s", "§e膚主§7:§a%s"
@ -315,7 +323,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_ROOT. * The constant LIB39_ROOT.
*/ */
// 根命令
public static final LangKeyValue LIB39_ROOT = addAndRet( public static final LangKeyValue LIB39_ROOT = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.root", ModPartEnum.MESSAGE, "commands.lib39.root", ModPartEnum.MESSAGE,
@ -330,7 +337,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_TEST. * The constant LIB39_TEST.
*/ */
// 測試命令
public static final LangKeyValue LIB39_TEST = addAndRet( public static final LangKeyValue LIB39_TEST = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.test", ModPartEnum.MESSAGE, "commands.lib39.test", ModPartEnum.MESSAGE,
@ -401,7 +407,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_GREET_BASIC. * The constant LIB39_GREET_BASIC.
*/ */
// 問候命令
public static final LangKeyValue LIB39_GREET_BASIC = addAndRet( public static final LangKeyValue LIB39_GREET_BASIC = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.greet.basic", ModPartEnum.MESSAGE, "commands.lib39.greet.basic", ModPartEnum.MESSAGE,
@ -458,7 +463,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_CALCULATE. * The constant LIB39_CALCULATE.
*/ */
// 計算命令
public static final LangKeyValue LIB39_CALCULATE = addAndRet( public static final LangKeyValue LIB39_CALCULATE = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.calculate", ModPartEnum.MESSAGE, "commands.lib39.calculate", ModPartEnum.MESSAGE,
@ -487,7 +491,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_TELEPORT. * The constant LIB39_TELEPORT.
*/ */
// 傳送命令
public static final LangKeyValue LIB39_TELEPORT = addAndRet( public static final LangKeyValue LIB39_TELEPORT = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.teleport", ModPartEnum.MESSAGE, "commands.lib39.teleport", ModPartEnum.MESSAGE,
@ -516,7 +519,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_INFO. * The constant LIB39_INFO.
*/ */
// 信息命令
public static final LangKeyValue LIB39_INFO = addAndRet( public static final LangKeyValue LIB39_INFO = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.info", ModPartEnum.MESSAGE, "commands.lib39.info", ModPartEnum.MESSAGE,
@ -573,7 +575,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_TEAM. * The constant LIB39_TEAM.
*/ */
// 隊伍系統
public static final LangKeyValue LIB39_TEAM = addAndRet( public static final LangKeyValue LIB39_TEAM = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.team", ModPartEnum.MESSAGE, "commands.lib39.team", ModPartEnum.MESSAGE,
@ -672,7 +673,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_GAME. * The constant LIB39_GAME.
*/ */
// 遊戲系統
public static final LangKeyValue LIB39_GAME = addAndRet( public static final LangKeyValue LIB39_GAME = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.game", ModPartEnum.MESSAGE, "commands.lib39.game", ModPartEnum.MESSAGE,
@ -799,7 +799,6 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
/** /**
* The constant LIB39_SETTINGS. * The constant LIB39_SETTINGS.
*/ */
// 設置命令
public static final LangKeyValue LIB39_SETTINGS = addAndRet( public static final LangKeyValue LIB39_SETTINGS = addAndRet(
LangKeyValue.ofKey( LangKeyValue.ofKey(
"commands.lib39.settings", ModPartEnum.MESSAGE, "commands.lib39.settings", ModPartEnum.MESSAGE,
@ -854,7 +853,7 @@ public enum Lib39LangKey implements ILangKeyValueCollection {
); );
// ===== 添加缺失的導入 ===== // ===== 添加缺失的導入 =====
private static final java.util.function.Consumer<LangKeyValue> addConsumer = items::add; private static final Consumer<LangKeyValue> addConsumer = items::add;
private static LangKeyValue addAndRet(LangKeyValue item) { private static LangKeyValue addAndRet(LangKeyValue item) {
items.add(item); items.add(item);

View File

@ -353,8 +353,8 @@ public class WheelWidget extends AbstractWidget {
* *
* @return the section circle diameter * @return the section circle diameter
*/ */
// 滚轮选择器中每个扇形的圆形直径
public float getSectionCircleDiameter() { public float getSectionCircleDiameter() {
// 滚轮选择器中每个扇形的圆形直径
return this.ringOuterRadius + this.ringInnerRadius; return this.ringOuterRadius + this.ringInnerRadius;
} }
@ -635,8 +635,10 @@ public class WheelWidget extends AbstractWidget {
float pixelOuterRadius = outerRadius * guiScale; float pixelOuterRadius = outerRadius * guiScale;
float pixelAntiAliasing = 2.0f * guiScale; // 抗锯齿范围 float pixelAntiAliasing = 2.0f * guiScale; // 抗锯齿范围
System.out.println("Shader Params - Center: (" + pixelCenterX + ", " + pixelCenterY + // if (Services.PLATFORM.isDevelopmentEnvironment()) {
"), InnerRadius: " + pixelInnerRadius + ", OuterRadius: " + pixelOuterRadius); // System.out.println("Shader Params - Center: (" + pixelCenterX + ", " + pixelCenterY +
// "), InnerRadius: " + pixelInnerRadius + ", OuterRadius: " + pixelOuterRadius);
// }
ShaderInstance shader = Lib39Shaders.getRingShader(); ShaderInstance shader = Lib39Shaders.getRingShader();
shader.safeGetUniform("Center").set(pixelCenterX, pixelCenterY); shader.safeGetUniform("Center").set(pixelCenterX, pixelCenterY);

View File

@ -9,6 +9,7 @@ import net.minecraft.client.model.geom.PartPose;
import net.minecraft.client.model.geom.builders.*; import net.minecraft.client.model.geom.builders.*;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
/** /**
@ -31,13 +32,56 @@ public class DollModel extends Model {
private final ModelPart rightArmSlim; private final ModelPart rightArmSlim;
private final ModelPart leftArmSlim; private final ModelPart leftArmSlim;
private final ModelPart leftLeg; private final ModelPart leftLeg;
@Nullable
private IDollPose currentPose;
/**
* Gets current pose.
*
* @return the current pose
*/
@Nullable
public IDollPose getCurrentPose() {
return currentPose;
}
/**
* Sets doll pose.
*
* @param dollPose the doll pose
*/
public void setDollPose(@NotNull IDollPose dollPose) {
this.currentPose = dollPose;
this.head.loadPose(dollPose.getHeadPose());
this.body.loadPose(dollPose.getBodyPose());
this.rightArm.loadPose(dollPose.getRightArmPose());
this.leftArm.loadPose(dollPose.getLeftArmPose());
this.rightArmSlim.loadPose(dollPose.getRightArmPose());
this.leftArmSlim.loadPose(dollPose.getLeftArmPose());
this.rightLeg.loadPose(dollPose.getRightLegPose());
this.leftLeg.loadPose(dollPose.getLeftLegPose());
}
/**
* Reset pose.
*/
public void resetPose() {
this.currentPose = DollPoses.DEFAULT;
this.head.resetPose();
this.body.resetPose();
this.rightArm.resetPose();
this.leftArm.resetPose();
this.rightArmSlim.resetPose();
this.leftArmSlim.resetPose();
this.rightLeg.resetPose();
this.leftLeg.resetPose();
}
/** /**
* Instantiates a new Doll model. * Instantiates a new Doll model.
* *
* @param root the root * @param root the root
*/ */
public DollModel(ModelPart root) { public DollModel(@NotNull ModelPart root) {
super(RenderType::entityTranslucent); super(RenderType::entityTranslucent);
this.head = root.getChild("head"); this.head = root.getChild("head");
this.body = root.getChild("body"); this.body = root.getChild("body");
@ -54,21 +98,104 @@ public class DollModel extends Model {
* *
* @return the layer definition * @return the layer definition
*/ */
public static LayerDefinition createBodyLayer() { public static @NotNull LayerDefinition createBodyLayer() {
return createBodyLayer(DollPoses.DEFAULT);
}
private static @NotNull LayerDefinition createBodyLayer(@NotNull IDollPose dollPoses) {
MeshDefinition meshdefinition = new MeshDefinition(); MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot(); PartDefinition partdefinition = meshdefinition.getRoot();
partdefinition.addOrReplaceChild("head", CubeListBuilder.create().texOffs(0, 0).addBox(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F)).texOffs(32, 0).addBox(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.5F)), PartPose.offset(0.0F, 9.0F, 0.0F)); partdefinition.addOrReplaceChild(
partdefinition.addOrReplaceChild("body", CubeListBuilder.create().texOffs(16, 16).addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(16, 32).addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)), PartPose.offset(0.0F, 9.0F, 0.0F)); "head",
partdefinition.addOrReplaceChild("right_arm", CubeListBuilder.create().texOffs(40, 16).addBox(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(40, 32).addBox(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)), PartPose.offsetAndRotation(-5.0F, 11.0F, 0.0F, 0.0F, 0.0F, 0.3927F)); CubeListBuilder.create()
partdefinition.addOrReplaceChild("right_arm_slim", CubeListBuilder.create().texOffs(40, 16).addBox(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(40, 32).addBox(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)), PartPose.offsetAndRotation(-5.0F, 11.0F, 0.0F, 0.0F, 0.0F, 0.3927F)); .texOffs(0, 0)
partdefinition.addOrReplaceChild("left_arm_slim", CubeListBuilder.create().texOffs(32, 48).addBox(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(48, 48).addBox(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)), PartPose.offsetAndRotation(5.0F, 11.0F, 0.0F, 0.0F, 0.0F, -0.3927F)); .addBox(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F))
partdefinition.addOrReplaceChild("left_arm", CubeListBuilder.create().texOffs(32, 48).addBox(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(48, 48).addBox(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)), PartPose.offsetAndRotation(5.0F, 11.0F, 0.0F, 0.0F, 0.0F, -0.3927F)); .texOffs(32, 0)
partdefinition.addOrReplaceChild("right_leg", CubeListBuilder.create().texOffs(0, 16).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(0, 32).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)), PartPose.offsetAndRotation(-2.0F, 19.0F, -2.0F, -1.5708F, 0.3927F, 0.0F)); .addBox(
partdefinition.addOrReplaceChild("left_leg", CubeListBuilder.create().texOffs(16, 48).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)).texOffs(0, 48).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)), PartPose.offsetAndRotation(2.0F, 19.0F, -2.0F, -1.5708F, -0.3927F, 0.0F)); -4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F,
new CubeDeformation(0.5F)
), dollPoses.getHeadPose()
);
partdefinition.addOrReplaceChild(
"body",
CubeListBuilder.create()
.texOffs(16, 16)
.addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(16, 32)
.addBox(
-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F,
new CubeDeformation(0.25F)
), dollPoses.getBodyPose()
);
partdefinition.addOrReplaceChild(
"right_arm",
CubeListBuilder.create()
.texOffs(40, 16)
.addBox(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(40, 32)
.addBox(
-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F,
new CubeDeformation(0.25F)
), dollPoses.getRightArmPose()
);
partdefinition.addOrReplaceChild(
"right_arm_slim",
CubeListBuilder.create()
.texOffs(40, 16)
.addBox(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(40, 32)
.addBox(-2.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F,
new CubeDeformation(0.25F)
), dollPoses.getRightArmPose()
);
partdefinition.addOrReplaceChild(
"left_arm_slim",
CubeListBuilder.create()
.texOffs(32, 48)
.addBox(-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(48, 48)
.addBox(
-1.0F, -2.0F, -2.0F, 3.0F, 12.0F, 4.0F,
new CubeDeformation(0.25F)
), dollPoses.getLeftArmPose()
);
partdefinition.addOrReplaceChild(
"left_arm",
CubeListBuilder.create()
.texOffs(32, 48)
.addBox(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(48, 48)
.addBox(
-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F,
new CubeDeformation(0.25F)
), dollPoses.getLeftArmPose()
);
partdefinition.addOrReplaceChild(
"right_leg",
CubeListBuilder.create()
.texOffs(0, 16)
.addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(0, 32)
.addBox(
-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.25F)
), dollPoses.getRightLegPose()
);
partdefinition.addOrReplaceChild(
"left_leg",
CubeListBuilder.create()
.texOffs(16, 48)
.addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F))
.texOffs(0, 48)
.addBox(
-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F,
new CubeDeformation(0.25F)
), dollPoses.getLeftLegPose()
);
return LayerDefinition.create(meshdefinition, 64, 64); return LayerDefinition.create(meshdefinition, 64, 64);
} }
@Override @Override
public void renderToBuffer(PoseStack poseStack, @NotNull VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) { public void renderToBuffer(PoseStack poseStack, @NotNull VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
poseStack.pushPose(); poseStack.pushPose();

View File

@ -0,0 +1,93 @@
package top.r3944realms.lib39.client.model;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.Lib39;
/**
* The enum Doll poses.
*/
public enum DollPoses implements IDollPose{
/**
* Default doll poses.
*/
DEFAULT(
"default",
PartPose.offset(0.0F, 9.0F, 0.0F),
PartPose.offset(0.0F, 9.0F, 0.0F),
PartPose.offsetAndRotation(-5.0F, 11.0F, 0.0F, 0.0F, 0.0F, 0.3927F),
PartPose.offsetAndRotation(5.0F, 11.0F, 0.0F, 0.0F, 0.0F, -0.3927F),
PartPose.offsetAndRotation(-2.0F, 19.0F, -2.0F, -1.5708F, 0.3927F, 0.0F),
PartPose.offsetAndRotation(2.0F, 19.0F, -2.0F, -1.5708F, -0.3927F, 0.0F)
);
// 注册全局
private final ResourceLocation id;
private final Vec3 offset;
private final PartPose headPose;
private final PartPose bodyPose;
private final PartPose rightArmPose;
private final PartPose leftArmPose;
private final PartPose rightLegPose;
private final PartPose leftLegPose;
DollPoses(String name, PartPose headPose, PartPose bodyPose,
PartPose rightArmPose, PartPose leftArmPose,
PartPose rightLegPose, PartPose leftLegPose) {
this(name, Vec3.ZERO, headPose, bodyPose, rightArmPose, leftArmPose, rightLegPose, leftLegPose);
}
DollPoses(String name, Vec3 offset, PartPose headPose, PartPose bodyPose,
PartPose rightArmPose, PartPose leftArmPose,
PartPose rightLegPose, PartPose leftLegPose) {
this.id = Lib39.rl(name);
this.offset = offset;
this.headPose = headPose;
this.bodyPose = bodyPose;
this.rightArmPose = rightArmPose;
this.leftArmPose = leftArmPose;
this.rightLegPose = rightLegPose;
this.leftLegPose = leftLegPose;
}
@Override
public @NotNull ResourceLocation getId() {
return id;
}
@Override
public PartPose getHeadPose() {
return headPose;
}
@Override
public PartPose getBodyPose() {
return bodyPose;
}
@Override
public PartPose getRightArmPose() {
return rightArmPose;
}
@Override
public PartPose getLeftArmPose() {
return leftArmPose;
}
@Override
public PartPose getRightLegPose() {
return rightLegPose;
}
@Override
public PartPose getLeftLegPose() {
return leftLegPose;
}
@Override
public @NotNull Vec3 getTotalOffset() {
return offset;
}
}

View File

@ -0,0 +1,69 @@
package top.r3944realms.lib39.client.model;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
/**
* The interface Doll pose.
*/
public interface IDollPose {
/**
* Gets id.
*
* @return the id
*/
@NotNull ResourceLocation getId();
/**
* Gets total offset.
*
* @return the total offset
*/
@NotNull default Vec3 getTotalOffset() {
return Vec3.ZERO;
}
/**
* Gets head pose.
*
* @return the head pose
*/
@NotNull PartPose getHeadPose();
/**
* Gets body pose.
*
* @return the body pose
*/
@NotNull PartPose getBodyPose();
/**
* Gets right arm pose.
*
* @return the right arm pose
*/
@NotNull PartPose getRightArmPose();
/**
* Gets left arm pose.
*
* @return the left arm pose
*/
@NotNull PartPose getLeftArmPose();
/**
* Gets right leg pose.
*
* @return the right leg pose
*/
@NotNull PartPose getRightLegPose();
/**
* Gets left leg pose.
*
* @return the left leg pose
*/
@NotNull PartPose getLeftLegPose();
}

View File

@ -11,11 +11,15 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.SkullBlock;
import net.minecraft.world.level.block.WallSkullBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.RotationSegment;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.client.model.DollModel; import top.r3944realms.lib39.client.model.DollModel;
import top.r3944realms.lib39.client.renderer.item.DollItemRenderer; import top.r3944realms.lib39.client.renderer.item.DollItemRenderer;
import top.r3944realms.lib39.content.block.DollBlock; import top.r3944realms.lib39.content.block.AbstractDollBlock;
import top.r3944realms.lib39.content.block.WallDollBlock;
import top.r3944realms.lib39.content.block.blockentity.DollBlockEntity; import top.r3944realms.lib39.content.block.blockentity.DollBlockEntity;
import top.r3944realms.lib39.util.lang.Pair; import top.r3944realms.lib39.util.lang.Pair;
@ -37,14 +41,15 @@ public class DollBlockEntityRenderer implements BlockEntityRenderer<DollBlockEnt
@Override @Override
public void render(@NotNull DollBlockEntity dollBlockEntity, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer, int packedLight, int packedOverlay) { public void render(@NotNull DollBlockEntity dollBlockEntity, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer, int packedLight, int packedOverlay) {
BlockState blockState = dollBlockEntity.getBlockState(); BlockState blockState = dollBlockEntity.getBlockState();
if (blockState.getBlock() instanceof DollBlock) { if (blockState.getBlock() instanceof AbstractDollBlock dollBlock) {
Direction facing = blockState.getValue(DollBlock.FACING); boolean isWall = dollBlock instanceof WallDollBlock;
Direction direction = isWall ? blockState.getValue(WallSkullBlock.FACING) : null;
float rotation = isWall ? direction.toYRot() : RotationSegment.convertToDegrees(blockState.getValue(SkullBlock.ROTATION));
GameProfile profile = dollBlockEntity.getOwnerProfile(); GameProfile profile = dollBlockEntity.getOwnerProfile();
Pair<ResourceLocation, Boolean> resourceLocationBooleanPair = DollItemRenderer.loadSkin(profile); Pair<ResourceLocation, Boolean> resourceLocationBooleanPair = DollItemRenderer.loadSkin(profile);
poseStack.pushPose(); poseStack.pushPose();
poseStack.translate(0.5, 1.5, 0.5); poseStack.translate(0.5, 1.5, 0.5);
poseStack.scale(1.0F, -1.0F, -1.0F); poseStack.scale(1.0F, -1.0F, -1.0F);
float rotation = facing.toYRot();
poseStack.mulPose(Axis.YP.rotationDegrees(rotation)); poseStack.mulPose(Axis.YP.rotationDegrees(rotation));
VertexConsumer vertexConsumer = buffer.getBuffer(RenderType.entityTranslucent(resourceLocationBooleanPair.first)); VertexConsumer vertexConsumer = buffer.getBuffer(RenderType.entityTranslucent(resourceLocationBooleanPair.first));
this.dollModel.slim = resourceLocationBooleanPair.second; this.dollModel.slim = resourceLocationBooleanPair.second;

View File

@ -0,0 +1,226 @@
package top.r3944realms.lib39.content.block;
import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.content.block.blockentity.DollBlockEntity;
import top.r3944realms.lib39.content.block.property.DollPose;
import top.r3944realms.lib39.core.register.Lib39BlockEntities;
import top.r3944realms.lib39.core.register.Lib39Items;
import top.r3944realms.lib39.core.register.Lib39SoundEvents;
import top.r3944realms.lib39.util.GameProfileHelper;
import java.util.List;
/**
* The type Abstract doll block.
*/
@SuppressWarnings("deprecation")
public abstract class AbstractDollBlock extends BaseEntityBlock implements SimpleWaterloggedBlock {
/**
* The constant WATERLOGGED.
*/
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
private static final Properties properties = Properties.of()
.instrument(NoteBlockInstrument.BASEDRUM)
.sound(SoundType.WOOL)
.pushReaction(PushReaction.DESTROY)
.strength(0f, 10f)
.noOcclusion();
private static final double PARTICLE_OFFSET_RANGE = 0.25;
private static final double PARTICLE_HEIGHT_OFFSET = 1.0;
private static final double PARTICLE_HEIGHT_VARIANCE = 0.2;
private static final float NOTE_COLOR_DIVISOR = 24.0F;
private static final int MAX_NOTE_COLORS = 4;
private static final float BASE_VOLUME = 1.0f;
private static final float PITCH_VARIANCE = 0.5f;
private static final float BASE_PITCH = 0.75f;
private static final VoxelShape DOLL_SHAPE = Block.box(2.0d, 0.0d, 2.0d, 14.0d, 12.0d, 14.0d);
/**
* The constant POSE.
*/
public static final EnumProperty<DollPose> POSE = EnumProperty.create("pose", DollPose.class);
/**
* Instantiates a new Abstract doll block.
*/
public AbstractDollBlock() {
super(properties);
}
@Override
public boolean canBeReplaced(@NotNull BlockState state, @NotNull BlockPlaceContext useContext) {
return false;
}
@Override
public @NotNull BlockState updateShape(@NotNull BlockState currentState, @NotNull Direction direction, @NotNull BlockState neighborState,
@NotNull LevelAccessor level, @NotNull BlockPos currentPos, @NotNull BlockPos neighborPos) {
if (currentState.getValue(WATERLOGGED)) {
level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
}
return super.updateShape(currentState, direction, neighborState, level, currentPos, neighborPos);
}
@Override
public @NotNull FluidState getFluidState(@NotNull BlockState blockState) {
return blockState.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(blockState);
}
@Override
public @NotNull InteractionResult use(@NotNull BlockState blockState, @NotNull Level level, @NotNull BlockPos blockPos, @NotNull Player player,
@NotNull InteractionHand hand, @NotNull BlockHitResult hitResult) {
if (level instanceof ServerLevel serverLevel) {
// 播放粒子效果
spawnNoteParticles(serverLevel, blockPos);
// 播放音效
playDollSound(serverLevel, blockPos);
}
return InteractionResult.SUCCESS;
}
/**
* 在玩偶位置生成音符粒子效果
*/
private void spawnNoteParticles(ServerLevel serverLevel, BlockPos blockPos) {
Vec3 particlePosition = calculateParticlePosition(serverLevel, blockPos);
float noteColor = calculateNoteColor(serverLevel);
serverLevel.sendParticles(ParticleTypes.NOTE,
particlePosition.x(), particlePosition.y(), particlePosition.z(),
0, noteColor, 0, 0, 1);
}
/**
* 计算粒子生成位置添加随机偏移
*/
private @NotNull Vec3 calculateParticlePosition(@NotNull ServerLevel serverLevel, BlockPos blockPos) {
return Vec3.atBottomCenterOf(blockPos).add(
(serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2,
PARTICLE_HEIGHT_OFFSET + serverLevel.getRandom().nextFloat() * PARTICLE_HEIGHT_VARIANCE,
(serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2
);
}
/**
* 计算音符粒子的颜色
*/
private float calculateNoteColor(@NotNull ServerLevel serverLevel) {
return serverLevel.getRandom().nextInt(MAX_NOTE_COLORS) / NOTE_COLOR_DIVISOR;
}
/**
* 播放玩偶音效
*/
private void playDollSound(@NotNull ServerLevel serverLevel, BlockPos blockPos) {
float pitch = BASE_PITCH + serverLevel.random.nextFloat() * PITCH_VARIANCE;
serverLevel.playSound(null, blockPos, Lib39SoundEvents.DUCK_TOY.get(),
SoundSource.BLOCKS, BASE_VOLUME, pitch);
}
@Override
public @NotNull VoxelShape getShape(@NotNull BlockState blockState, @NotNull BlockGetter level, @NotNull BlockPos blockPos, @NotNull CollisionContext context) {
return DOLL_SHAPE;
}
public @NotNull VoxelShape getOcclusionShape(@NotNull BlockState state, @NotNull BlockGetter level, @NotNull BlockPos pos) {
return Shapes.empty();
}
@Nullable
@Override
public BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) {
return Lib39BlockEntities.DOLL_BLOCK_ENTITY.get().create(blockPos, blockState);
}
@SuppressWarnings("deprecation")
@Override
public @NotNull RenderShape getRenderShape(@NotNull BlockState state) {
return RenderShape.ENTITYBLOCK_ANIMATED;
}
@Override
public @NotNull ItemStack getCloneItemStack(@NotNull BlockGetter level, @NotNull BlockPos pos, @NotNull BlockState state) {
ItemStack stack = super.getCloneItemStack(level, pos, state);
BlockEntity blockEntity = level.getBlockEntity(pos);
if (blockEntity instanceof DollBlockEntity doll) {
GameProfile profile = doll.getOwnerProfile();
if (profile != null) {
GameProfileHelper.saveProfileToItemStack(stack, profile);
}
}
return stack;
}
/**
* 最重要的方法重写掉落逻辑
*/
@Override
@NotNull
public List<ItemStack> getDrops(@NotNull BlockState state, @NotNull LootParams.Builder params) {
// 获取方块实体
BlockEntity blockEntity = params.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
if (blockEntity instanceof DollBlockEntity dollEntity) {
List<ItemStack> customDrops = getCustomDrops(dollEntity, params);
if (customDrops != null) return customDrops;
}
return super.getDrops(state, params);
}
@Override
protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(WATERLOGGED, POSE);
}
/**
* 生成自定义掉落物
*/
@Nullable
private List<ItemStack> getCustomDrops(DollBlockEntity dollEntity, LootParams.Builder params) {
if (params.getOptionalParameter(LootContextParams.THIS_ENTITY) instanceof Player player) {
if (player.isCreative()) {
return List.of();
}
}
GameProfile profile = dollEntity.getOwnerProfile();
if (profile != null) {
ItemStack instance = Lib39Items.DOLL.get().getDefaultInstance();
GameProfileHelper.saveProfileToItemStack(instance, profile);
return List.of(instance);
}
return null;
}
}

View File

@ -1,235 +1,65 @@
package top.r3944realms.lib39.content.block; package top.r3944realms.lib39.content.block;
import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.level.block.state.properties.RotationSegment;
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.content.block.blockentity.DollBlockEntity;
import top.r3944realms.lib39.content.block.property.DollPose; import top.r3944realms.lib39.content.block.property.DollPose;
import top.r3944realms.lib39.core.register.Lib39BlockEntities;
import top.r3944realms.lib39.core.register.Lib39Items;
import top.r3944realms.lib39.core.register.Lib39SoundEvents;
import top.r3944realms.lib39.util.GameProfileHelper;
import java.util.List;
/** /**
* The type Doll block. * The type Doll block.
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class DollBlock extends HorizontalDirectionalBlock implements SimpleWaterloggedBlock, EntityBlock { public class DollBlock extends AbstractDollBlock{
private static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
/** /**
* The constant POSE. * The constant MAX.
*/ */
public static final EnumProperty<DollPose> POSE = EnumProperty.create("pose", DollPose.class); public static final int MAX = RotationSegment.getMaxSegmentIndex();
private static final VoxelShape DOLL_SHAPE = Block.box(2.0d, 0.0d, 2.0d, 14.0d, 12.0d, 14.0d); private static final int ROTATIONS = MAX + 1;
private static final Properties properties = Properties.of() /**
.instrument(NoteBlockInstrument.BASEDRUM) * The constant ROTATION.
.sound(SoundType.WOOL) */
.pushReaction(PushReaction.DESTROY) public static final IntegerProperty ROTATION = BlockStateProperties.ROTATION_16;
.strength(0f, 10f)
.noOcclusion();
private static final double PARTICLE_OFFSET_RANGE = 0.25;
private static final double PARTICLE_HEIGHT_OFFSET = 1.0;
private static final double PARTICLE_HEIGHT_VARIANCE = 0.2;
private static final float NOTE_COLOR_DIVISOR = 24.0F;
private static final int MAX_NOTE_COLORS = 4;
private static final float BASE_VOLUME = 1.0f;
private static final float PITCH_VARIANCE = 0.5f;
private static final float BASE_PITCH = 0.75f;
/** /**
* Instantiates a new Doll block. * Instantiates a new Doll block.
*/ */
public DollBlock() { public DollBlock() {
super(properties); super();
this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.SOUTH) this.registerDefaultState(
this.stateDefinition.any()
.setValue(POSE, DollPose.DEFAULT) .setValue(POSE, DollPose.DEFAULT)
.setValue(WATERLOGGED, false)); .setValue(WATERLOGGED, false)
} .setValue(ROTATION, 0)
@Override
public boolean canBeReplaced(@NotNull BlockState state, @NotNull BlockPlaceContext useContext) {
return false;
}
@Override
public @NotNull BlockState updateShape(@NotNull BlockState currentState, @NotNull Direction direction, @NotNull BlockState neighborState,
@NotNull LevelAccessor level, @NotNull BlockPos currentPos, @NotNull BlockPos neighborPos) {
if (currentState.getValue(WATERLOGGED)) {
level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
}
return super.updateShape(currentState, direction, neighborState, level, currentPos, neighborPos);
}
@Override
public @NotNull FluidState getFluidState(@NotNull BlockState blockState) {
return blockState.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(blockState);
}
@Override
public @NotNull InteractionResult use(@NotNull BlockState blockState, @NotNull Level level, @NotNull BlockPos blockPos, @NotNull Player player,
@NotNull InteractionHand hand, @NotNull BlockHitResult hitResult) {
if (level instanceof ServerLevel serverLevel) {
// 播放粒子效果
spawnNoteParticles(serverLevel, blockPos);
// 播放音效
playDollSound(serverLevel, blockPos);
}
return InteractionResult.SUCCESS;
}
/**
* 在玩偶位置生成音符粒子效果
*/
private void spawnNoteParticles(ServerLevel serverLevel, BlockPos blockPos) {
Vec3 particlePosition = calculateParticlePosition(serverLevel, blockPos);
float noteColor = calculateNoteColor(serverLevel);
serverLevel.sendParticles(ParticleTypes.NOTE,
particlePosition.x(), particlePosition.y(), particlePosition.z(),
0, noteColor, 0, 0, 1);
}
/**
* 计算粒子生成位置添加随机偏移
*/
private @NotNull Vec3 calculateParticlePosition(@NotNull ServerLevel serverLevel, BlockPos blockPos) {
return Vec3.atBottomCenterOf(blockPos).add(
(serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2,
PARTICLE_HEIGHT_OFFSET + serverLevel.getRandom().nextFloat() * PARTICLE_HEIGHT_VARIANCE,
(serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2
); );
} }
/**
* 计算音符粒子的颜色
*/
private float calculateNoteColor(@NotNull ServerLevel serverLevel) {
return serverLevel.getRandom().nextInt(MAX_NOTE_COLORS) / NOTE_COLOR_DIVISOR;
}
/**
* 播放玩偶音效
*/
private void playDollSound(@NotNull ServerLevel serverLevel, BlockPos blockPos) {
float pitch = BASE_PITCH + serverLevel.random.nextFloat() * PITCH_VARIANCE;
serverLevel.playSound(null, blockPos, Lib39SoundEvents.DUCK_TOY.get(),
SoundSource.BLOCKS, BASE_VOLUME, pitch);
}
@Override @Override
public @Nullable BlockState getStateForPlacement(@NotNull BlockPlaceContext context) { public @Nullable BlockState getStateForPlacement(@NotNull BlockPlaceContext context) {
FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos()); BlockState stateForPlacement = super.getStateForPlacement(context);
boolean isWaterlogged = fluidState.getType() == Fluids.WATER; return stateForPlacement != null ? stateForPlacement.setValue(ROTATION, RotationSegment.convertToSegment((context.getRotation()+180) % 360)) : null;
return this.defaultBlockState()
.setValue(FACING, context.getHorizontalDirection().getOpposite())
.setValue(WATERLOGGED, isWaterlogged)
.setValue(POSE, DollPose.DEFAULT);
} }
@Override @Override
public @NotNull VoxelShape getShape(@NotNull BlockState blockState, @NotNull BlockGetter level, @NotNull BlockPos blockPos, @NotNull CollisionContext context) { public @NotNull BlockState rotate(@NotNull BlockState state, @NotNull Rotation rotation) {
return DOLL_SHAPE; return state.setValue(ROTATION, rotation.rotate(state.getValue(ROTATION), ROTATIONS));
}
@Override
public @NotNull BlockState mirror(@NotNull BlockState state, @NotNull Mirror mirror) {
return state.setValue(ROTATION, mirror.mirror(state.getValue(ROTATION), ROTATIONS));
} }
@Override @Override
protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> builder) { protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder); super.createBlockStateDefinition(builder);
builder.add(FACING, WATERLOGGED, POSE); builder.add(ROTATION);
}
@Nullable
@Override
public BlockEntity newBlockEntity(@NotNull BlockPos blockPos, @NotNull BlockState blockState) {
return Lib39BlockEntities.DOLL_BLOCK_ENTITY.get().create(blockPos, blockState);
}
@SuppressWarnings("deprecation")
@Override
public @NotNull RenderShape getRenderShape(@NotNull BlockState state) {
return RenderShape.ENTITYBLOCK_ANIMATED;
}
@Override
public ItemStack getCloneItemStack(BlockGetter level, BlockPos pos, BlockState state) {
ItemStack stack = super.getCloneItemStack(level, pos, state);
BlockEntity blockEntity = level.getBlockEntity(pos);
if (blockEntity instanceof DollBlockEntity doll) {
GameProfile profile = doll.getOwnerProfile();
if (profile != null) {
GameProfileHelper.saveProfileToItemStack(stack, profile);
}
}
return stack;
}
/**
* 最重要的方法重写掉落逻辑
*/
@Override
@NotNull
public List<ItemStack> getDrops(@NotNull BlockState state, @NotNull LootParams.Builder params) {
// 获取方块实体
BlockEntity blockEntity = params.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
if (blockEntity instanceof DollBlockEntity dollEntity) {
List<ItemStack> customDrops = getCustomDrops(dollEntity, params);
if (customDrops != null) return customDrops;
}
return super.getDrops(state, params);
}
/**
* 生成自定义掉落物
*/
@Nullable
private List<ItemStack> getCustomDrops(DollBlockEntity dollEntity, LootParams.Builder params) {
if (params.getOptionalParameter(LootContextParams.THIS_ENTITY) instanceof Player player) {
if (player.isCreative()) {
return List.of();
}
}
GameProfile profile = dollEntity.getOwnerProfile();
if (profile != null) {
ItemStack instance = Lib39Items.DOLL.get().getDefaultInstance();
GameProfileHelper.saveProfileToItemStack(instance, profile);
return List.of(instance);
}
return null;
} }
} }

View File

@ -0,0 +1,56 @@
package top.r3944realms.lib39.content.block;
import net.minecraft.core.Direction;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.content.block.property.DollPose;
/**
* The type Wall doll block.
*/
@SuppressWarnings({"deprecation"})
public class WallDollBlock extends AbstractDollBlock {
/**
* The constant FACING.
*/
public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING;
/**
* Instantiates a new Wall doll block.
*/
public WallDollBlock() {
super();
this.registerDefaultState(
this.stateDefinition.any()
.setValue(POSE, DollPose.DEFAULT)
.setValue(WATERLOGGED, false)
.setValue(FACING, Direction.NORTH)
);
}
public @NotNull BlockState rotate(@NotNull BlockState state, @NotNull Rotation rotation) {
return state.setValue(FACING, rotation.rotate(state.getValue(FACING)));
}
public @NotNull BlockState mirror(@NotNull BlockState state, @NotNull Mirror mirror) {
return state.rotate(mirror.getRotation(state.getValue(FACING)));
}
@Override
public @Nullable BlockState getStateForPlacement(@NotNull BlockPlaceContext context) {
BlockState stateForPlacement = super.getStateForPlacement(context);
return stateForPlacement != null ? stateForPlacement.setValue(FACING, context.getHorizontalDirection().getOpposite()) : null;
}
protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(FACING);
}
}

View File

@ -1,11 +1,12 @@
package top.r3944realms.lib39.content.item; package top.r3944realms.lib39.content.item;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Equipable; import net.minecraft.world.item.Equipable;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.StandingAndWallBlockItem;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -18,14 +19,14 @@ import java.util.List;
/** /**
* The type Doll item. * The type Doll item.
*/ */
public class DollItem extends BlockItem implements Equipable { public class DollItem extends StandingAndWallBlockItem implements Equipable {
/** /**
* Instantiates a new Doll item. * Instantiates a new Doll item.
* *
* @param properties the properties * @param properties the properties
*/ */
public DollItem(Properties properties) { public DollItem(Properties properties) {
super(Lib39Blocks.DOLL.get(), properties); super(Lib39Blocks.DOLL.get(), Lib39Blocks.WALL_DOLL.get(), properties, Direction.DOWN);
} }

View File

@ -15,6 +15,9 @@ public abstract class SimpleHelpCommand implements IHelpCommand {
protected final LiteralArgumentBuilder<CommandSourceStack> root; protected final LiteralArgumentBuilder<CommandSourceStack> root;
/** /**
* <pre>
* 需要{@link CommandDispatcher<CommandSourceStack> 指令注册调度器} {@link CommandBuildContext 指令上下文}
* </pre>
* Instantiates a new Simple help command. * Instantiates a new Simple help command.
* *
* @param dispatcher the dispatcher * @param dispatcher the dispatcher

View File

@ -11,7 +11,7 @@ import java.util.stream.Stream;
*/ */
public class ClassEncryptor { public class ClassEncryptor {
static { static {
System.loadLibrary("ClassEncrypt"); // System.loadLibrary("ClassEncrypt");
} }
/** /**

View File

@ -13,7 +13,7 @@ import java.util.Map;
*/ */
public class EncryptedClassLoader extends ClassLoader { public class EncryptedClassLoader extends ClassLoader {
static { static {
System.loadLibrary("ClassEncrypt"); // System.loadLibrary("ClassEncrypt");
} }
private native byte[] decryptClass(byte[] encryptedData, String key); private native byte[] decryptClass(byte[] encryptedData, String key);

View File

@ -13,5 +13,9 @@ public class Lib39Blocks {
* The constant DOLL. * The constant DOLL.
*/ */
public static Supplier<Block> DOLL; public static Supplier<Block> DOLL;
/**
* The Wall doll.
*/
public static Supplier<Block> WALL_DOLL;
} }

View File

@ -4,6 +4,9 @@ plugins {
id 'multiloader-loader' id 'multiloader-loader'
id 'fabric-loom' id 'fabric-loom'
} }
repositories {
maven { url 'https://maven.covers1624.net/' }
}
dependencies { dependencies {
minecraft "com.mojang:minecraft:${minecraft_version}" minecraft "com.mojang:minecraft:${minecraft_version}"
mappings loom.layered { mappings loom.layered {
@ -17,7 +20,9 @@ dependencies {
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1'
implementation project(":common") implementation project(":common")
modImplementation "curse.maven:jade-324717:6291330"
testImplementation "net.fabricmc:fabric-loader-junit:${fabric_loader_version}" testImplementation "net.fabricmc:fabric-loader-junit:${fabric_loader_version}"
localRuntime 'net.covers1624:DevLogin:0.1.0.5'
} }
loom { loom {
@ -36,10 +41,12 @@ loom {
runs { runs {
client { client {
client() client()
ideConfigGenerated true
programArgs '--launch_target', 'net.fabricmc.loader.impl.launch.knot.KnotClient'
mainClass.set 'net.covers1624.devlogin.DevLogin'
setConfigName("Fabric Client") setConfigName("Fabric Client")
ideConfigGenerated(true) ideConfigGenerated(true)
runDir("run") runDir("run")
programArgs "--username", "R3944Realms"
def args = [ def args = [
"-Dlib39.modid=${mod_id}".toString(), "-Dlib39.modid=${mod_id}".toString(),
"-Dlib39.output=${generatedOutput}".toString(), "-Dlib39.output=${generatedOutput}".toString(),
@ -74,9 +81,6 @@ loom {
] ]
vmArgs.addAll(args) vmArgs.addAll(args)
} }
gameTest {
}
} }
} }

View File

@ -8,6 +8,9 @@ import top.r3944realms.lib39.core.register.FabricLib39Items;
import top.r3944realms.lib39.core.register.FabricLib39SoundEvents; import top.r3944realms.lib39.core.register.FabricLib39SoundEvents;
import top.r3944realms.lib39.example.FabricLib39Example; import top.r3944realms.lib39.example.FabricLib39Example;
/**
* The type Lib 39 fabric.
*/
public class Lib39Fabric implements ModInitializer { public class Lib39Fabric implements ModInitializer {
@Override @Override

View File

@ -9,6 +9,9 @@ import top.r3944realms.lib39.client.ShaderRegistry;
import top.r3944realms.lib39.core.event.FabricCommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
import top.r3944realms.lib39.core.network.FabricNetworkHandler; import top.r3944realms.lib39.core.network.FabricNetworkHandler;
/**
* The type Lib 39 fabric client.
*/
public class Lib39FabricClient implements ClientModInitializer { public class Lib39FabricClient implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {

View File

@ -17,6 +17,7 @@ public class AnvilUpdateCallback {
public interface AnvilUpdate { public interface AnvilUpdate {
/** /**
* 当铁砧内容改变时调用 * 当铁砧内容改变时调用
*
* @param left 左侧输入槽的物品 * @param left 左侧输入槽的物品
* @param right 右侧输入槽的物品 * @param right 右侧输入槽的物品
* @param outputSlot 输出槽的物品 * @param outputSlot 输出槽的物品
@ -34,24 +35,49 @@ public class AnvilUpdateCallback {
*/ */
public record AnvilUpdateResult(ItemStack output, int cost, int materialCost, boolean cancel) { public record AnvilUpdateResult(ItemStack output, int cost, int materialCost, boolean cancel) {
/**
* Cancelled anvil update result.
*
* @return the anvil update result
*/
public static AnvilUpdateResult cancelled() { public static AnvilUpdateResult cancelled() {
return new AnvilUpdateResult(ItemStack.EMPTY, 0, 0, true); return new AnvilUpdateResult(ItemStack.EMPTY, 0, 0, true);
} }
/**
* Passed anvil update result.
*
* @return the anvil update result
*/
public static AnvilUpdateResult passed() { public static AnvilUpdateResult passed() {
return new AnvilUpdateResult(ItemStack.EMPTY, 0, 0, false); return new AnvilUpdateResult(ItemStack.EMPTY, 0, 0, false);
} }
/**
* With output anvil update result.
*
* @param output the output
* @param cost the cost
* @param materialCost the material cost
* @return the anvil update result
*/
public static AnvilUpdateResult withOutput(ItemStack output, int cost, int materialCost) { public static AnvilUpdateResult withOutput(ItemStack output, int cost, int materialCost) {
return new AnvilUpdateResult(output, cost, materialCost, false); return new AnvilUpdateResult(output, cost, materialCost, false);
} }
/**
* Should override boolean.
*
* @return the boolean
*/
public boolean shouldOverride() { public boolean shouldOverride() {
return !output.isEmpty(); return !output.isEmpty();
} }
} }
// 创建事件实例 /**
* The constant EVENT.
*/
public static final Event<AnvilUpdate> EVENT = EventFactory.createArrayBacked( public static final Event<AnvilUpdate> EVENT = EventFactory.createArrayBacked(
AnvilUpdate.class, AnvilUpdate.class,
(listeners) -> (left, right, outputSlot, name, baseCost, player) -> { (listeners) -> (left, right, outputSlot, name, baseCost, player) -> {

View File

@ -33,7 +33,7 @@ public interface MinecraftSetUpServiceCallback {
* *
* @param services the services * @param services the services
* @param mainThreadExecutor the main thread executor * @param mainThreadExecutor the main thread executor
* @return 结果枚举 * @return 结果枚举 action result
*/ */
ActionResult load(Services services, Executor mainThreadExecutor); ActionResult load(Services services, Executor mainThreadExecutor);
} }

View File

@ -12,9 +12,19 @@ import top.r3944realms.lib39.core.command.model.CommandNode;
import top.r3944realms.lib39.core.command.model.CommandPath; import top.r3944realms.lib39.core.command.model.CommandPath;
import top.r3944realms.lib39.core.command.model.Parameter; import top.r3944realms.lib39.core.command.model.Parameter;
/**
* The interface Register command help callback.
*/
@FunctionalInterface @FunctionalInterface
public interface RegisterCommandHelpCallback { public interface RegisterCommandHelpCallback {
/**
* Register action result.
*
* @param registrar the registrar
* @return the action result
*/
ActionResult register(RegisterCommandHelpCallback.Registrar registrar); ActionResult register(RegisterCommandHelpCallback.Registrar registrar);
/** /**
* 创建 Event 实例 * 创建 Event 实例
*/ */
@ -30,6 +40,10 @@ public interface RegisterCommandHelpCallback {
return ActionResult.PASS; return ActionResult.PASS;
} }
); );
/**
* The interface Registrar.
*/
interface Registrar { interface Registrar {
/** /**
* Gets id. * Gets id.
@ -66,6 +80,7 @@ public interface RegisterCommandHelpCallback {
* @param description 命令描述 * @param description 命令描述
*/ */
void registerHelp(CommandNode CommandNode, MutableComponent description); void registerHelp(CommandNode CommandNode, MutableComponent description);
/** /**
* 注册命令帮助信息 * 注册命令帮助信息
* *
@ -73,6 +88,7 @@ public interface RegisterCommandHelpCallback {
* @param descriptionKey 命令描述的语言键 * @param descriptionKey 命令描述的语言键
*/ */
void registerHelp(CommandNode CommandNode, String descriptionKey); void registerHelp(CommandNode CommandNode, String descriptionKey);
/** /**
* 注册命令参数 * 注册命令参数
* *
@ -81,6 +97,10 @@ public interface RegisterCommandHelpCallback {
*/ */
void registerParameters(CommandPath commandPath, Parameter.Builder parametersBuilder); void registerParameters(CommandPath commandPath, Parameter.Builder parametersBuilder);
} }
/**
* The type Command help registrar.
*/
record CommandHelpRegistrar(LiteralArgumentBuilder<CommandSourceStack> builder, ICommandHelpManager helpManager, CommandBuildContext context) implements Registrar { record CommandHelpRegistrar(LiteralArgumentBuilder<CommandSourceStack> builder, ICommandHelpManager helpManager, CommandBuildContext context) implements Registrar {
@Override @Override
public ResourceLocation getID() { public ResourceLocation getID() {

View File

@ -21,6 +21,7 @@ public interface SyncManagerRegisterCallback {
* 注册同步管理器的回调方法 * 注册同步管理器的回调方法
* *
* @param registrar 注册器实例 * @param registrar 注册器实例
* @return the action result
*/ */
ActionResult registerSyncManagers(Registrar registrar); ActionResult registerSyncManagers(Registrar registrar);
@ -47,6 +48,8 @@ public interface SyncManagerRegisterCallback {
/** /**
* 获取 Fabric 同步管理器实例 * 获取 Fabric 同步管理器实例
*
* @return the sync data 2 lookup manager
*/ */
SyncData2LookupManager manager(); SyncData2LookupManager manager();
@ -120,6 +123,10 @@ public interface SyncManagerRegisterCallback {
} }
} }
} }
/**
* The type Sync manager registrar.
*/
record SyncManagerRegistrar( record SyncManagerRegistrar(
SyncData2LookupManager manager) implements SyncManagerRegisterCallback.Registrar { SyncData2LookupManager manager) implements SyncManagerRegisterCallback.Registrar {

View File

@ -4,25 +4,50 @@ import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
/**
* The interface Client world callback.
*/
public interface ClientWorldCallback { public interface ClientWorldCallback {
/**
* The constant LOAD.
*/
Event<ClientWorldCallback.Load> LOAD = EventFactory.createArrayBacked(ClientWorldCallback.Load.class, (callbacks) -> (world) -> { Event<ClientWorldCallback.Load> LOAD = EventFactory.createArrayBacked(ClientWorldCallback.Load.class, (callbacks) -> (world) -> {
for (Load callback : callbacks) { for (Load callback : callbacks) {
callback.onWorldLoad(world); callback.onWorldLoad(world);
} }
}); });
/**
* The constant UNLOAD.
*/
Event<ClientWorldCallback.Unload> UNLOAD = EventFactory.createArrayBacked(ClientWorldCallback.Unload.class, (callbacks) -> (world) -> { Event<ClientWorldCallback.Unload> UNLOAD = EventFactory.createArrayBacked(ClientWorldCallback.Unload.class, (callbacks) -> (world) -> {
for (Unload callback : callbacks) { for (Unload callback : callbacks) {
callback.onWorldUnload(world); callback.onWorldUnload(world);
} }
}); });
/**
* The interface Unload.
*/
@FunctionalInterface @FunctionalInterface
interface Unload { interface Unload {
/**
* On world unload.
*
* @param clientLevel the client level
*/
void onWorldUnload(ClientLevel clientLevel); void onWorldUnload(ClientLevel clientLevel);
} }
/**
* The interface Load.
*/
@FunctionalInterface @FunctionalInterface
interface Load { interface Load {
/**
* On world load.
*
* @param clientLevel the client level
*/
void onWorldLoad(ClientLevel clientLevel); void onWorldLoad(ClientLevel clientLevel);
} }
} }

View File

@ -0,0 +1,25 @@
package top.r3944realms.lib39.base.compat.jade;
import net.minecraft.resources.ResourceLocation;
import snownee.jade.api.IWailaClientRegistration;
import snownee.jade.api.IWailaPlugin;
import snownee.jade.api.WailaPlugin;
import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.base.compat.jade.provider.FabricDollComponentProvider;
import top.r3944realms.lib39.content.block.DollBlock;
/**
* The type Fabric jade plugin.
*/
@WailaPlugin
public class FabricJadePlugin implements IWailaPlugin {
/**
* The constant UID.
*/
public static final ResourceLocation UID = Lib39.rl("lib39");
@Override
public void registerClient(IWailaClientRegistration registration) {
registration.registerBlockComponent(new FabricDollComponentProvider(), DollBlock.class);
}
}

View File

@ -0,0 +1,31 @@
package top.r3944realms.lib39.base.compat.jade.provider;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import snownee.jade.api.BlockAccessor;
import snownee.jade.api.IBlockComponentProvider;
import snownee.jade.api.ITooltip;
import snownee.jade.api.config.IPluginConfig;
import top.r3944realms.lib39.base.compat.jade.FabricJadePlugin;
import top.r3944realms.lib39.content.block.blockentity.DollBlockEntity;
/**
* The type Fabric doll component provider.
*/
public class FabricDollComponentProvider implements IBlockComponentProvider {
@Override
public ResourceLocation getUid() {
return FabricJadePlugin.UID;
}
@Override
public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) {
if (blockAccessor.getBlockEntity() instanceof DollBlockEntity doll) {
GameProfile ownerProfile = doll.getOwnerProfile();
if (ownerProfile != null) {
iTooltip.add(Component.translatable("tooltip.lib39.content.doll.hover.1", ownerProfile.getName()));
}
}
}
}

View File

@ -4,7 +4,13 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import top.r3944realms.lib39.client.renderer.block.DollBlockEntityRenderer; import top.r3944realms.lib39.client.renderer.block.DollBlockEntityRenderer;
import top.r3944realms.lib39.core.register.Lib39BlockEntities; import top.r3944realms.lib39.core.register.Lib39BlockEntities;
/**
* The type Block entity renderer registry.
*/
public class BlockEntityRendererRegistry { public class BlockEntityRendererRegistry {
/**
* Register.
*/
public static void register() { public static void register() {
BlockEntityRenderers.register( BlockEntityRenderers.register(
Lib39BlockEntities.DOLL_BLOCK_ENTITY.get(), Lib39BlockEntities.DOLL_BLOCK_ENTITY.get(),

View File

@ -4,7 +4,13 @@ import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
import top.r3944realms.lib39.client.renderer.item.DollItemRenderer; import top.r3944realms.lib39.client.renderer.item.DollItemRenderer;
import top.r3944realms.lib39.core.register.Lib39Items; import top.r3944realms.lib39.core.register.Lib39Items;
/**
* The type Item renderer registry.
*/
public class ItemRendererRegistry { public class ItemRendererRegistry {
/**
* Register.
*/
public static void register() { public static void register() {
BuiltinItemRendererRegistry.INSTANCE.register( BuiltinItemRendererRegistry.INSTANCE.register(
Lib39Items.DOLL.get(), Lib39Items.DOLL.get(),

View File

@ -3,7 +3,13 @@ package top.r3944realms.lib39.client;
import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry;
import top.r3944realms.lib39.client.model.DollModel; import top.r3944realms.lib39.client.model.DollModel;
/**
* The type Layer definition registry.
*/
public class LayerDefinitionRegistry { public class LayerDefinitionRegistry {
/**
* Register.
*/
public static void register() { public static void register() {
EntityModelLayerRegistry.registerModelLayer( EntityModelLayerRegistry.registerModelLayer(
DollModel.LAYER_LOCATION, DollModel::createBodyLayer DollModel.LAYER_LOCATION, DollModel::createBodyLayer

View File

@ -5,7 +5,13 @@ import net.fabricmc.fabric.api.client.rendering.v1.CoreShaderRegistrationCallbac
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.client.shader.Lib39Shaders; import top.r3944realms.lib39.client.shader.Lib39Shaders;
/**
* The type Shader registry.
*/
public class ShaderRegistry { public class ShaderRegistry {
/**
* Register.
*/
public static void register() { public static void register() {
CoreShaderRegistrationCallback.EVENT.register( context -> { CoreShaderRegistrationCallback.EVENT.register( context -> {
context.register( context.register(

View File

@ -44,7 +44,13 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* The type Fabric common event handler.
*/
public class FabricCommonEventHandler { public class FabricCommonEventHandler {
/**
* The Sync data 2 manager.
*/
static volatile SyncData2LookupManager syncData2Manager; static volatile SyncData2LookupManager syncData2Manager;
private static boolean isSync2MInitialized = false; private static boolean isSync2MInitialized = false;
private static ServerLevel sl; private static ServerLevel sl;
@ -57,6 +63,7 @@ public class FabricCommonEventHandler {
public static ServerLevel getServerLevel() { public static ServerLevel getServerLevel() {
return sl; return sl;
} }
/** /**
* Gets sync data 2 manager. * Gets sync data 2 manager.
* *
@ -65,6 +72,13 @@ public class FabricCommonEventHandler {
public static SyncData2LookupManager getSyncData2Manager() { public static SyncData2LookupManager getSyncData2Manager() {
return syncData2Manager; return syncData2Manager;
} }
/**
* On server world load.
*
* @param server the server
* @param serverLevel the server level
*/
public static void onServerWorldLoad(MinecraftServer server, ServerLevel serverLevel) { public static void onServerWorldLoad(MinecraftServer server, ServerLevel serverLevel) {
if (!serverLevel.dimension().equals(Level.OVERWORLD)) return; if (!serverLevel.dimension().equals(Level.OVERWORLD)) return;
synchronized (FabricCommonEventHandler.class) { synchronized (FabricCommonEventHandler.class) {
@ -80,6 +94,12 @@ public class FabricCommonEventHandler {
} }
/**
* On server world un load.
*
* @param server the server
* @param serverLevel the server level
*/
public static void onServerWorldUnLoad(MinecraftServer server, @NotNull ServerLevel serverLevel) { public static void onServerWorldUnLoad(MinecraftServer server, @NotNull ServerLevel serverLevel) {
if (!serverLevel.dimension().equals(Level.OVERWORLD)) return; if (!serverLevel.dimension().equals(Level.OVERWORLD)) return;
sl = null; sl = null;
@ -87,6 +107,11 @@ public class FabricCommonEventHandler {
isSync2MInitialized = false; isSync2MInitialized = false;
} }
/**
* On server tick.
*
* @param server the server
*/
public static void onServerTick(MinecraftServer server) { public static void onServerTick(MinecraftServer server) {
if (syncData2Manager == null) return; if (syncData2Manager == null) return;
if (server.getTickCount() % 10 == 0) if (server.getTickCount() % 10 == 0)
@ -94,6 +119,12 @@ public class FabricCommonEventHandler {
syncData2Manager.forEach(((resourceLocation, iSyncManager) -> iSyncManager.foreach(ISyncData::checkIfDirtyThenUpdate))); syncData2Manager.forEach(((resourceLocation, iSyncManager) -> iSyncManager.foreach(ISyncData::checkIfDirtyThenUpdate)));
} }
/**
* On entity join world.
*
* @param entity the entity
* @param level the level
*/
public static void onEntityJoinWorld(@NotNull Entity entity, ServerLevel level) { public static void onEntityJoinWorld(@NotNull Entity entity, ServerLevel level) {
if (entity.level().isClientSide) return; if (entity.level().isClientSide) return;
@ -104,6 +135,12 @@ public class FabricCommonEventHandler {
} }
} }
/**
* On entity leave world.
*
* @param entity the entity
* @param level the level
*/
public static void onEntityLeaveWorld(@NotNull Entity entity, ServerLevel level) { public static void onEntityLeaveWorld(@NotNull Entity entity, ServerLevel level) {
if (entity.level().isClientSide) return; if (entity.level().isClientSide) return;
@ -115,6 +152,7 @@ public class FabricCommonEventHandler {
} }
private static final Map<Supplier<Block>, ResourceKey<CreativeModeTab>[]> itemAddMap = new ConcurrentHashMap<>(); private static final Map<Supplier<Block>, ResourceKey<CreativeModeTab>[]> itemAddMap = new ConcurrentHashMap<>();
private static final Map<ResourceKey<CreativeModeTab>, List<Supplier<Block>>> tabToItemsMap = new ConcurrentHashMap<>(); private static final Map<ResourceKey<CreativeModeTab>, List<Supplier<Block>>> tabToItemsMap = new ConcurrentHashMap<>();
/** /**
* Add item to tabs. * Add item to tabs.
* *
@ -131,6 +169,9 @@ public class FabricCommonEventHandler {
} }
} }
/**
* Init common.
*/
public static void initCommon() { public static void initCommon() {
try { try {
Class.forName("top.r3944realms.lib39.base.command.Lib39CommandHelpManager"); Class.forName("top.r3944realms.lib39.base.command.Lib39CommandHelpManager");
@ -166,7 +207,16 @@ public class FabricCommonEventHandler {
new Lib39HelpCommand(commandDispatcher, commandBuildContext); new Lib39HelpCommand(commandDispatcher, commandBuildContext);
}); });
} }
/**
* The type Client opt.
*/
public static class ClientOpt implements IClientOnly { public static class ClientOpt implements IClientOnly {
/**
* On client world load.
*
* @param clientLevel the client level
*/
public static void onClientWorldLoad(@NotNull ClientLevel clientLevel) { public static void onClientWorldLoad(@NotNull ClientLevel clientLevel) {
synchronized (FabricCommonEventHandler.ClientOpt.class) { synchronized (FabricCommonEventHandler.ClientOpt.class) {
IClientOnly.check(() -> { IClientOnly.check(() -> {
@ -180,6 +230,12 @@ public class FabricCommonEventHandler {
}); });
} }
} }
/**
* On client world un load.
*
* @param clientLevel the client level
*/
public static void onClientWorldUnLoad(@NotNull ClientLevel clientLevel) { public static void onClientWorldUnLoad(@NotNull ClientLevel clientLevel) {
synchronized (FabricCommonEventHandler.ClientOpt.class) { synchronized (FabricCommonEventHandler.ClientOpt.class) {
IClientOnly.check(() -> ILevelHelper.LevelHelper.CLIENT.setLevel(null)); IClientOnly.check(() -> ILevelHelper.LevelHelper.CLIENT.setLevel(null));
@ -187,6 +243,9 @@ public class FabricCommonEventHandler {
} }
} }
/**
* Init client.
*/
public static void initClient() { public static void initClient() {
ClientWorldCallback.LOAD.register(ClientOpt::onClientWorldLoad); ClientWorldCallback.LOAD.register(ClientOpt::onClientWorldLoad);
ClientWorldCallback.LOAD.register(ClientOpt::onClientWorldUnLoad); ClientWorldCallback.LOAD.register(ClientOpt::onClientWorldUnLoad);

View File

@ -3,6 +3,9 @@ package top.r3944realms.lib39.core.network;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket; import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPacket;
/**
* The type Fabric network handler.
*/
public class FabricNetworkHandler { public class FabricNetworkHandler {
/** /**

View File

@ -19,13 +19,23 @@ import top.r3944realms.lib39.core.sync.SyncData2Manager;
import java.util.Optional; import java.util.Optional;
/**
* The type Sync nbt lookup data entity s 2 c packet.
*/
public record SyncNBTLookupDataEntityS2CPacket(int entityId, ResourceLocation id, CompoundTag data) implements FabricPacket { public record SyncNBTLookupDataEntityS2CPacket(int entityId, ResourceLocation id, CompoundTag data) implements FabricPacket {
/**
* The constant SYNC_NBT_LOOKUP_PACKET_ID.
*/
public static final ResourceLocation SYNC_NBT_LOOKUP_PACKET_ID = public static final ResourceLocation SYNC_NBT_LOOKUP_PACKET_ID =
Lib39.rl("sync_nbt_lookup_data_entity"); Lib39.rl("sync_nbt_lookup_data_entity");
/**
* The constant TYPE.
*/
public static final PacketType<SyncNBTLookupDataEntityS2CPacket> TYPE = PacketType.create( public static final PacketType<SyncNBTLookupDataEntityS2CPacket> TYPE = PacketType.create(
SYNC_NBT_LOOKUP_PACKET_ID, SYNC_NBT_LOOKUP_PACKET_ID,
buf -> new SyncNBTLookupDataEntityS2CPacket(buf.readInt(), buf.readResourceLocation(), buf.readNbt()) buf -> new SyncNBTLookupDataEntityS2CPacket(buf.readInt(), buf.readResourceLocation(), buf.readNbt())
); );
/** /**
* Instantiates a new Sync nbt data s 2 c pack. * Instantiates a new Sync nbt data s 2 c pack.
* *
@ -50,6 +60,13 @@ public record SyncNBTLookupDataEntityS2CPacket(int entityId, ResourceLocation id
} }
/**
* Receive.
*
* @param packet the packet
* @param localPlayer the local player
* @param packetSender the packet sender
*/
public static void receive(@NotNull SyncNBTLookupDataEntityS2CPacket packet, @NotNull LocalPlayer localPlayer, PacketSender packetSender) { public static void receive(@NotNull SyncNBTLookupDataEntityS2CPacket packet, @NotNull LocalPlayer localPlayer, PacketSender packetSender) {
Level level = localPlayer.level(); Level level = localPlayer.level();
Entity entity = level.getEntity(packet.entityId); Entity entity = level.getEntity(packet.entityId);

View File

@ -14,13 +14,25 @@ import java.util.function.Supplier;
* The type Lib 39 block entities. * The type Lib 39 block entities.
*/ */
public class FabricLib39BlockEntities { public class FabricLib39BlockEntities {
/**
* Init.
*/
@SuppressWarnings("DataFlowIssue") @SuppressWarnings("DataFlowIssue")
public static void init() { public static void init() {
Lib39BlockEntities.DOLL_BLOCK_ENTITY = register("doll", BlockEntityType.Builder Lib39BlockEntities.DOLL_BLOCK_ENTITY = register("doll", BlockEntityType.Builder
.of(DollBlockEntity::new, Lib39Blocks.DOLL.get()) .of(DollBlockEntity::new, Lib39Blocks.DOLL.get(), Lib39Blocks.WALL_DOLL.get())
.build(null) .build(null)
); );
} }
/**
* Register @ not null supplier.
*
* @param <T> the type parameter
* @param path the path
* @param blockEntityType the block entity type
* @return the @ not null supplier
*/
@Contract(pure = true) @Contract(pure = true)
public static <T extends BlockEntityType<?>> @NotNull Supplier<T> register(String path, T blockEntityType) { public static <T extends BlockEntityType<?>> @NotNull Supplier<T> register(String path, T blockEntityType) {
T item = Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, Lib39.rl(path), blockEntityType); T item = Registry.register(BuiltInRegistries.BLOCK_ENTITY_TYPE, Lib39.rl(path), blockEntityType);

View File

@ -7,6 +7,7 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.content.block.DollBlock; import top.r3944realms.lib39.content.block.DollBlock;
import top.r3944realms.lib39.content.block.WallDollBlock;
import top.r3944realms.lib39.util.block.BlockRegistryBuilder; import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -15,13 +16,30 @@ import java.util.function.Supplier;
* The type Lib 39 blocks. * The type Lib 39 blocks.
*/ */
public class FabricLib39Blocks { public class FabricLib39Blocks {
/**
* Init.
*/
public static void init() { public static void init() {
Lib39Blocks.DOLL = BlockRegistryBuilder Lib39Blocks.DOLL = BlockRegistryBuilder
.create() .create()
.withName("doll") .withName("doll")
.registerBlock((name , block) -> register(name, block.get()), DollBlock::new) .registerBlock((name , block) -> register(name, block.get()), DollBlock::new)
.build(); .build();
Lib39Blocks.WALL_DOLL = BlockRegistryBuilder
.create()
.withName("wall_doll")
.registerBlock((name , block) -> register(name, block.get()), WallDollBlock::new)
.build();
} }
/**
* Register @ not null supplier.
*
* @param <T> the type parameter
* @param path the path
* @param block the block
* @return the @ not null supplier
*/
@Contract(pure = true) @Contract(pure = true)
public static <T extends Block> @NotNull Supplier<T> register(String path, T block) { public static <T extends Block> @NotNull Supplier<T> register(String path, T block) {
T item = Registry.register(BuiltInRegistries.BLOCK, Lib39.rl(path), block); T item = Registry.register(BuiltInRegistries.BLOCK, Lib39.rl(path), block);

View File

@ -14,9 +14,21 @@ import java.util.function.Supplier;
* The type Ex lib 39 items. * The type Ex lib 39 items.
*/ */
public class FabricLib39Items { public class FabricLib39Items {
/**
* Init.
*/
public static void init() { public static void init() {
Lib39Items.DOLL = register("doll", new DollItem(new Item.Properties())); Lib39Items.DOLL = register("doll", new DollItem(new Item.Properties()));
} }
/**
* Register @ not null supplier.
*
* @param <T> the type parameter
* @param path the path
* @param item the item
* @return the @ not null supplier
*/
@Contract(pure = true) @Contract(pure = true)
public static <T extends Item> @NotNull Supplier<T> register(String path, T item) { public static <T extends Item> @NotNull Supplier<T> register(String path, T item) {
T register = Registry.register(BuiltInRegistries.ITEM, Lib39.rl(path), item); T register = Registry.register(BuiltInRegistries.ITEM, Lib39.rl(path), item);

View File

@ -13,9 +13,21 @@ import java.util.function.Supplier;
* The type Lib 39 sound events. * The type Lib 39 sound events.
*/ */
public class FabricLib39SoundEvents { public class FabricLib39SoundEvents {
/**
* Init.
*/
public static void init() { public static void init() {
Lib39SoundEvents.DUCK_TOY = register("duck_toy", SoundEvent.createFixedRangeEvent(Lib39SoundEvents.RL_DUCK_TOY, 32.0f)); Lib39SoundEvents.DUCK_TOY = register("duck_toy", SoundEvent.createFixedRangeEvent(Lib39SoundEvents.RL_DUCK_TOY, 32.0f));
} }
/**
* Register @ not null supplier.
*
* @param <T> the type parameter
* @param path the path
* @param soundEvent the sound event
* @return the @ not null supplier
*/
@Contract(pure = true) @Contract(pure = true)
public static <T extends SoundEvent> @NotNull Supplier<T> register(String path, T soundEvent) { public static <T extends SoundEvent> @NotNull Supplier<T> register(String path, T soundEvent) {
T register = Registry.register(BuiltInRegistries.SOUND_EVENT, Lib39.rl(path), soundEvent); T register = Registry.register(BuiltInRegistries.SOUND_EVENT, Lib39.rl(path), soundEvent);

View File

@ -2,6 +2,19 @@ package top.r3944realms.lib39.core.sync;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
/**
* The interface Entity api look up impl extend.
*
* @param <A> the type parameter
* @param <C> the type parameter
*/
public interface IEntityApiLookUpImplExtend<A, C> { public interface IEntityApiLookUpImplExtend<A, C> {
/**
* Lib 39 find without check a.
*
* @param entity the entity
* @param context the context
* @return the a
*/
A lib39$findWithoutCheck(Entity entity, C context); A lib39$findWithoutCheck(Entity entity, C context);
} }

View File

@ -9,6 +9,9 @@ import top.r3944realms.lib39.core.network.toClient.SyncNBTLookupDataEntityS2CPac
import java.util.List; import java.util.List;
/**
* The interface Fabric update.
*/
public interface IFabricUpdate extends IUpdate { public interface IFabricUpdate extends IUpdate {
default void update() { default void update() {
ServerLevel serverLevel = FabricCommonEventHandler.getServerLevel(); ServerLevel serverLevel = FabricCommonEventHandler.getServerLevel();

View File

@ -5,9 +5,30 @@ import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/**
* The interface Lib 39 sync data holder.
*/
public interface ILib39SyncDataHolder { public interface ILib39SyncDataHolder {
/**
* Lib 39 get sync data compound tag.
*
* @return the compound tag
*/
CompoundTag lib39$getSyncData(); CompoundTag lib39$getSyncData();
/**
* Lib 39 set sync data.
*
* @param tag the tag
*/
void lib39$setSyncData(CompoundTag tag); void lib39$setSyncData(CompoundTag tag);
/**
* Lib 39 inject save sync data compound tag.
*
* @param tag the tag
* @return the compound tag
*/
default CompoundTag lib39$injectSaveSyncData(CompoundTag tag) { default CompoundTag lib39$injectSaveSyncData(CompoundTag tag) {
if (lib39$getSyncData() != null && !lib39$getSyncData().isEmpty()) { if (lib39$getSyncData() != null && !lib39$getSyncData().isEmpty()) {
tag.put("Lib39Data", lib39$getSyncData()); tag.put("Lib39Data", lib39$getSyncData());
@ -15,22 +36,43 @@ public interface ILib39SyncDataHolder {
return tag; return tag;
} }
/**
* Lib 39 inject load sync data.
*
* @param tag the tag
*/
default void lib39$injectLoadSyncData(@NotNull CompoundTag tag) { default void lib39$injectLoadSyncData(@NotNull CompoundTag tag) {
if (tag.contains("Lib39Data", Tag.TAG_COMPOUND)) { if (tag.contains("Lib39Data", Tag.TAG_COMPOUND)) {
lib39$setSyncData(tag.getCompound("Lib39Data")); lib39$setSyncData(tag.getCompound("Lib39Data"));
} }
} }
/**
* Save sync data.
*
* @param syncData the sync data
*/
default void saveSyncData(@NotNull NBTEntitySyncData syncData) { default void saveSyncData(@NotNull NBTEntitySyncData syncData) {
lib39$getSyncData().put(syncData.id.toDebugFileName(), syncData.serializeNBT()); lib39$getSyncData().put(syncData.id.toDebugFileName(), syncData.serializeNBT());
} }
/**
* Load sync data.
*
* @param syncData the sync data
*/
default void loadSyncData(NBTEntitySyncData syncData) { default void loadSyncData(NBTEntitySyncData syncData) {
if (syncData != null && lib39$getSyncData().contains(syncData.id.toDebugFileName())) { if (syncData != null && lib39$getSyncData().contains(syncData.id.toDebugFileName())) {
syncData.deserializeNBT(lib39$getSyncData().getCompound(syncData.id.toDebugFileName())); syncData.deserializeNBT(lib39$getSyncData().getCompound(syncData.id.toDebugFileName()));
} }
} }
/**
* Gets holder.
*
* @param entity the entity
* @return the holder
*/
static ILib39SyncDataHolder getHolder(Entity entity) { static ILib39SyncDataHolder getHolder(Entity entity) {
return (ILib39SyncDataHolder) entity; return (ILib39SyncDataHolder) entity;
} }

View File

@ -10,7 +10,13 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
/**
* The type Sync data 2 lookup manager.
*/
public class SyncData2LookupManager extends SyncData2Manager<SyncData2LookupManager.TypedSyncEntry<? extends ISyncData<?>>> { public class SyncData2LookupManager extends SyncData2Manager<SyncData2LookupManager.TypedSyncEntry<? extends ISyncData<?>>> {
/**
* The Typed entries.
*/
protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap(); protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap();
@Override @Override
@ -18,6 +24,11 @@ public class SyncData2LookupManager extends SyncData2Manager<SyncData2LookupMana
return typedEntries; return typedEntries;
} }
/**
* The type Typed sync entry.
*
* @param <T> the type parameter
*/
protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Entity, T> { protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Entity, T> {
/** /**
* Instantiates a new Typed sync entry for Fabric * Instantiates a new Typed sync entry for Fabric
@ -94,6 +105,11 @@ public class SyncData2LookupManager extends SyncData2Manager<SyncData2LookupMana
/** /**
* 更新条目的 EntityApiLookup * 更新条目的 EntityApiLookup
*
* @param <T> the type parameter
* @param id the id
* @param entry the entry
* @param newApiLookup the new api lookup
*/ */
protected <T extends ISyncData<?>> void updateApiLookupInEntry( protected <T extends ISyncData<?>> void updateApiLookupInEntry(
ResourceLocation id, ResourceLocation id,

View File

@ -6,8 +6,25 @@ import net.minecraft.world.entity.Entity;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.core.event.FabricCommonEventHandler; import top.r3944realms.lib39.core.event.FabricCommonEventHandler;
/**
* The type Sync lookup provider.
*
* @param <T> the type parameter
*/
public abstract class SyncLookupProvider<T extends NBTEntitySyncData> implements EntityApiLookup.EntityApiProvider<T, Void> { public abstract class SyncLookupProvider<T extends NBTEntitySyncData> implements EntityApiLookup.EntityApiProvider<T, Void> {
/**
* Create empty lookup t.
*
* @param entity the entity
* @return the t
*/
protected abstract T createEmptyLookup(Entity entity); protected abstract T createEmptyLookup(Entity entity);
/**
* Gets id.
*
* @return the id
*/
protected abstract ResourceLocation getId(); protected abstract ResourceLocation getId();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override

View File

@ -6,8 +6,12 @@ import top.r3944realms.lib39.example.core.event.FabricExCommonEventHandler;
import top.r3944realms.lib39.example.core.network.FabricExNetworkHandler; import top.r3944realms.lib39.example.core.network.FabricExNetworkHandler;
import top.r3944realms.lib39.example.core.register.FabricExLib39Items; import top.r3944realms.lib39.example.core.register.FabricExLib39Items;
/**
* The type Fabric lib 39 example.
*/
public class FabricLib39Example { public class FabricLib39Example {
private static boolean registered = false; private static boolean registered = false;
/** /**
* Instantiates a new Lib 39 example. * Instantiates a new Lib 39 example.
*/ */
@ -17,6 +21,10 @@ public class FabricLib39Example {
registered = true; registered = true;
} }
} }
/**
* Init.
*/
public void init() { public void init() {
FabricExCommonEventHandler.init(); FabricExCommonEventHandler.init();
FabricExLib39Items.init(); FabricExLib39Items.init();

View File

@ -4,7 +4,13 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import top.r3944realms.lib39.core.sync.SyncLookupProvider; import top.r3944realms.lib39.core.sync.SyncLookupProvider;
/**
* The type Fabric test sync lookup provider.
*/
public class FabricTestSyncLookupProvider extends SyncLookupProvider<AbstractedTestSyncData> { public class FabricTestSyncLookupProvider extends SyncLookupProvider<AbstractedTestSyncData> {
/**
* The constant INSTANCE.
*/
public static final FabricTestSyncLookupProvider INSTANCE = new FabricTestSyncLookupProvider(); public static final FabricTestSyncLookupProvider INSTANCE = new FabricTestSyncLookupProvider();
@Override @Override

View File

@ -13,8 +13,16 @@ import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.FabricTestSyncData; import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
import top.r3944realms.lib39.example.core.network.FabricClientDataPacket; import top.r3944realms.lib39.example.core.network.FabricClientDataPacket;
/**
* The type Fabric fabric item.
*/
public class FabricFabricItem extends AbstractFabricItem { public class FabricFabricItem extends AbstractFabricItem {
/**
* Instantiates a new Fabric fabric item.
*
* @param properties the properties
*/
public FabricFabricItem(Properties properties) { public FabricFabricItem(Properties properties) {
super(properties); super(properties);
} }
@ -31,6 +39,12 @@ public class FabricFabricItem extends AbstractFabricItem {
} }
} }
/**
* Gets static data.
*
* @param target the target
* @return the static data
*/
public static @Nullable AbstractedTestSyncData getStaticData(Entity target) { public static @Nullable AbstractedTestSyncData getStaticData(Entity target) {
try { try {
AbstractedTestSyncData abstractData = EntityApiLookup.get(FabricTestSyncData.ID, AbstractedTestSyncData.class, Void.class).find(target, null); AbstractedTestSyncData abstractData = EntityApiLookup.get(FabricTestSyncData.ID, AbstractedTestSyncData.class, Void.class).find(target, null);
@ -43,6 +57,13 @@ public class FabricFabricItem extends AbstractFabricItem {
return null; return null;
} }
/**
* Handle client data from packet.
*
* @param player the player
* @param clientData the client data
* @param targetEntityId the target entity id
*/
public static void handleClientDataFromPacket(@NotNull ServerPlayer player, AbstractedTestSyncData clientData, int targetEntityId) { public static void handleClientDataFromPacket(@NotNull ServerPlayer player, AbstractedTestSyncData clientData, int targetEntityId) {
Entity target = player.level().getEntity(targetEntityId); Entity target = player.level().getEntity(targetEntityId);

View File

@ -5,8 +5,16 @@ import net.minecraft.world.entity.Entity;
import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData; import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.FabricTestSyncData; import top.r3944realms.lib39.example.content.data.FabricTestSyncData;
/**
* The type Fabric neo forge item.
*/
public class FabricNeoForgeItem extends AbstractNeoForgeItem { public class FabricNeoForgeItem extends AbstractNeoForgeItem {
/**
* Instantiates a new Fabric neo forge item.
*
* @param properties the properties
*/
public FabricNeoForgeItem(Properties properties) { public FabricNeoForgeItem(Properties properties) {
super(properties); super(properties);
} }

View File

@ -9,6 +9,9 @@ import top.r3944realms.lib39.core.compat.ICompat;
* The type Lib 39 compat. * The type Lib 39 compat.
*/ */
public class FabricLib39Compat implements ICompat { public class FabricLib39Compat implements ICompat {
/**
* The Initialized.
*/
boolean initialized = false; boolean initialized = false;
/** /**
* The constant INSTANCE. * The constant INSTANCE.

View File

@ -3,6 +3,9 @@ package top.r3944realms.lib39.example.core.compat;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.core.compat.CompatManager; import top.r3944realms.lib39.core.compat.CompatManager;
/**
* The type Fabric lib 39 compat manager.
*/
public class FabricLib39CompatManager extends CompatManager { public class FabricLib39CompatManager extends CompatManager {
/** /**
* Instantiates a new Compat manager. * Instantiates a new Compat manager.

View File

@ -14,6 +14,9 @@ import top.r3944realms.lib39.example.core.compat.FabricLib39CompatManager;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/**
* The type Fabric ex common event handler.
*/
public class FabricExCommonEventHandler { public class FabricExCommonEventHandler {
/** /**
* Gets compat manager. * Gets compat manager.
@ -35,6 +38,10 @@ public class FabricExCommonEventHandler {
* The Compat manager. * The Compat manager.
*/ */
static volatile CompatManager compatManager; static volatile CompatManager compatManager;
/**
* Init.
*/
public static void init() { public static void init() {
SyncManagerRegisterCallback.EVENT.register(registrar -> { SyncManagerRegisterCallback.EVENT.register(registrar -> {
registrar.register( registrar.register(

View File

@ -16,8 +16,14 @@ import top.r3944realms.lib39.example.content.item.FabricFabricItem;
* The type Client data packet. * The type Client data packet.
*/ */
public class FabricClientDataPacket implements FabricPacket { public class FabricClientDataPacket implements FabricPacket {
/**
* The constant CLIENT_TEST_DATA.
*/
public static final ResourceLocation CLIENT_TEST_DATA = public static final ResourceLocation CLIENT_TEST_DATA =
Lib39.rl("client_test_data"); Lib39.rl("client_test_data");
/**
* The constant TYPE.
*/
public static final PacketType<FabricClientDataPacket> TYPE = PacketType.create( public static final PacketType<FabricClientDataPacket> TYPE = PacketType.create(
CLIENT_TEST_DATA, CLIENT_TEST_DATA,
FabricClientDataPacket::new FabricClientDataPacket::new
@ -58,6 +64,13 @@ public class FabricClientDataPacket implements FabricPacket {
return TYPE; return TYPE;
} }
/**
* Receive.
*
* @param packet the packet
* @param serverPlayer the server player
* @param packetSender the packet sender
*/
public static void receive(@NotNull FabricClientDataPacket packet, @NotNull ServerPlayer serverPlayer, PacketSender packetSender) { public static void receive(@NotNull FabricClientDataPacket packet, @NotNull ServerPlayer serverPlayer, PacketSender packetSender) {
FabricFabricItem.handleClientDataFromPacket(serverPlayer, packet.clientData, packet.targetEntityId); FabricFabricItem.handleClientDataFromPacket(serverPlayer, packet.clientData, packet.targetEntityId);
} }

View File

@ -2,6 +2,9 @@ package top.r3944realms.lib39.example.core.network;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
/**
* The type Fabric ex network handler.
*/
public class FabricExNetworkHandler { public class FabricExNetworkHandler {
/** /**
* 注册服务器接收的数据包 * 注册服务器接收的数据包

View File

@ -10,6 +10,9 @@ import top.r3944realms.lib39.example.content.item.ForgeItem;
* The type Ex lib 39 items. * The type Ex lib 39 items.
*/ */
public class FabricExLib39Items { public class FabricExLib39Items {
/**
* Init.
*/
public static void init() { public static void init() {
ExLib39Items.FABRIC = FabricLib39Items.register("fabric", new FabricFabricItem( ExLib39Items.FABRIC = FabricLib39Items.register("fabric", new FabricFabricItem(
new Item.Properties() new Item.Properties()

View File

@ -14,6 +14,12 @@ import top.r3944realms.lib39.core.sync.IEntityApiLookUpImplExtend;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
/**
* The type Mixin api look up.
*
* @param <A> the type parameter
* @param <C> the type parameter
*/
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
@Mixin(value = EntityApiLookupImpl.class, remap = false) @Mixin(value = EntityApiLookupImpl.class, remap = false)
public class MixinApiLookUpImpl<A, C> implements IEntityApiLookUpImplExtend<A, C> { public class MixinApiLookUpImpl<A, C> implements IEntityApiLookUpImplExtend<A, C> {

View File

@ -15,8 +15,16 @@ import top.r3944realms.lib39.core.sync.NBTEntitySyncData;
import java.util.UUID; import java.util.UUID;
/**
* The type Mixin entity.
*/
@Mixin(Entity.class) @Mixin(Entity.class)
public abstract class MixinEntity implements ILib39SyncDataHolder { public abstract class MixinEntity implements ILib39SyncDataHolder {
/**
* Gets uuid.
*
* @return the uuid
*/
@Shadow public abstract UUID getUUID(); @Shadow public abstract UUID getUUID();
@Unique @Unique

View File

@ -13,6 +13,9 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import top.r3944realms.lib39.api.callback.AnvilUpdateCallback; import top.r3944realms.lib39.api.callback.AnvilUpdateCallback;
/**
* The type Mixin anvil menu.
*/
@Mixin(AnvilMenu.class) @Mixin(AnvilMenu.class)
public abstract class MixinAnvilMenu extends AbstractContainerMenu { public abstract class MixinAnvilMenu extends AbstractContainerMenu {
@Shadow @Shadow
@ -25,6 +28,12 @@ public abstract class MixinAnvilMenu extends AbstractContainerMenu {
@Unique @Unique
private Player cachedPlayer; private Player cachedPlayer;
/**
* Instantiates a new Mixin anvil menu.
*
* @param menuType the menu type
* @param containerId the container id
*/
protected MixinAnvilMenu(@Nullable MenuType<?> menuType, int containerId) { protected MixinAnvilMenu(@Nullable MenuType<?> menuType, int containerId) {
super(menuType, containerId); super(menuType, containerId);
} }

View File

@ -26,6 +26,9 @@ import javax.annotation.Nullable;
*/ */
@Mixin(Minecraft.class) @Mixin(Minecraft.class)
public abstract class MixinMinecraft extends ReentrantBlockableEventLoop<Runnable> implements WindowEventHandler { public abstract class MixinMinecraft extends ReentrantBlockableEventLoop<Runnable> implements WindowEventHandler {
/**
* The Level.
*/
@Shadow @Nullable public ClientLevel level; @Shadow @Nullable public ClientLevel level;
/** /**
@ -36,16 +39,30 @@ public abstract class MixinMinecraft extends ReentrantBlockableEventLoop<Runnabl
public MixinMinecraft(String name) { public MixinMinecraft(String name) {
super(name); super(name);
} }
/**
* Set level callback.
*
* @param levelClient the level client
* @param original the original
*/
@WrapMethod(method = "setLevel") @WrapMethod(method = "setLevel")
public void setLevel$callback(ClientLevel levelClient, Operation<Void> original) { public void setLevel$callback(ClientLevel levelClient, Operation<Void> original) {
if (levelClient != null) ClientWorldCallback.UNLOAD.invoker().onWorldUnload(levelClient); if (levelClient != null) ClientWorldCallback.UNLOAD.invoker().onWorldUnload(levelClient);
original.call(levelClient); original.call(levelClient);
} }
/**
* Clear level callback.
*
* @param original the original
*/
@WrapMethod(method = "clearLevel()V") @WrapMethod(method = "clearLevel()V")
public void clearLevel$callback(Operation<Void> original) { public void clearLevel$callback(Operation<Void> original) {
if (level != null) ClientWorldCallback.UNLOAD.invoker().onWorldUnload(level); if (level != null) ClientWorldCallback.UNLOAD.invoker().onWorldUnload(level);
original.call(); original.call();
} }
/** /**
* Set level setup. * Set level setup.
* *

View File

@ -18,8 +18,24 @@ import top.r3944realms.lib39.api.callback.client.ClientWorldCallback;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* The type Mixin client level.
*/
@Mixin(ClientLevel.class) @Mixin(ClientLevel.class)
public abstract class MixinClientLevel extends Level { public abstract class MixinClientLevel extends Level {
/**
* Instantiates a new Mixin client level.
*
* @param levelData the level data
* @param dimension the dimension
* @param registryAccess the registry access
* @param dimensionTypeRegistration the dimension type registration
* @param profiler the profiler
* @param isClientSide the is client side
* @param isDebug the is debug
* @param biomeZoomSeed the biome zoom seed
* @param maxChainedNeighborUpdates the max chained neighbor updates
*/
protected MixinClientLevel(WritableLevelData levelData, ResourceKey<Level> dimension, RegistryAccess registryAccess, Holder<DimensionType> dimensionTypeRegistration, Supplier<ProfilerFiller> profiler, boolean isClientSide, boolean isDebug, long biomeZoomSeed, int maxChainedNeighborUpdates) { protected MixinClientLevel(WritableLevelData levelData, ResourceKey<Level> dimension, RegistryAccess registryAccess, Holder<DimensionType> dimensionTypeRegistration, Supplier<ProfilerFiller> profiler, boolean isClientSide, boolean isDebug, long biomeZoomSeed, int maxChainedNeighborUpdates) {
super(levelData, dimension, registryAccess, dimensionTypeRegistration, profiler, isClientSide, isDebug, biomeZoomSeed, maxChainedNeighborUpdates); super(levelData, dimension, registryAccess, dimensionTypeRegistration, profiler, isClientSide, isDebug, biomeZoomSeed, maxChainedNeighborUpdates);
} }

View File

@ -7,7 +7,13 @@ import top.r3944realms.lib39.api.callback.RegisterCommandHelpCallback;
import top.r3944realms.lib39.core.command.ICommandHelpManager; import top.r3944realms.lib39.core.command.ICommandHelpManager;
import top.r3944realms.lib39.platform.services.IHelpCommandHook; import top.r3944realms.lib39.platform.services.IHelpCommandHook;
/**
* The enum Fabric help command hook.
*/
public enum FabricHelpCommandHook implements IHelpCommandHook { public enum FabricHelpCommandHook implements IHelpCommandHook {
/**
* Instance fabric help command hook.
*/
INSTANCE; INSTANCE;
@Override @Override

View File

@ -11,6 +11,9 @@ import top.r3944realms.lib39.platform.services.IUtilHelper;
import java.util.Objects; import java.util.Objects;
/**
* The type Fabric platform helper.
*/
public class FabricPlatformHelper implements IPlatformHelper { public class FabricPlatformHelper implements IPlatformHelper {
@Override @Override

View File

@ -4,7 +4,13 @@ import top.r3944realms.lib39.platform.services.IUtilHelper;
import top.r3944realms.lib39.util.FabricBlockRegistryBuilder; import top.r3944realms.lib39.util.FabricBlockRegistryBuilder;
import top.r3944realms.lib39.util.block.BlockRegistryBuilder; import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
/**
* The enum Fabric util helper.
*/
public enum FabricUtilHelper implements IUtilHelper { public enum FabricUtilHelper implements IUtilHelper {
/**
* Instance fabric util helper.
*/
INSTANCE; INSTANCE;
@Override @Override
public BlockRegistryBuilder getBlockRegistryBuilder() { public BlockRegistryBuilder getBlockRegistryBuilder() {

View File

@ -8,6 +8,9 @@ import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* The type Fabric block registry builder.
*/
public class FabricBlockRegistryBuilder extends BlockRegistryBuilder { public class FabricBlockRegistryBuilder extends BlockRegistryBuilder {
@SafeVarargs @SafeVarargs
@Override @Override

View File

@ -20,6 +20,9 @@
], ],
"client": [ "client": [
"top.r3944realms.lib39.Lib39FabricClient" "top.r3944realms.lib39.Lib39FabricClient"
],
"jade": [
"top.r3944realms.lib39.base.compat.jade.FabricJadePlugin"
] ]
}, },
"mixins": [ "mixins": [
@ -34,6 +37,13 @@
}, },
"suggests": { "suggests": {
"another-mod": "*" "another-mod": "*"
},
"custom": {
"mc-publish": {
"dependencies": [
"fabric-api(required)"
]
}
} }
} }

View File

@ -77,6 +77,7 @@ dependencies {
modImplementation(group: 'tschipp.carryon', name: 'carryon-forge-1.20.1', version: '2.1.2.7') { modImplementation(group: 'tschipp.carryon', name: 'carryon-forge-1.20.1', version: '2.1.2.7') {
transitive = false transitive = false
} }
modImplementation ("curse.maven:jade-324717:6855440")
implementation(jarJar("io.github.llamalad7:mixinextras-forge:0.2.0")) implementation(jarJar("io.github.llamalad7:mixinextras-forge:0.2.0"))
} }

View File

@ -0,0 +1,25 @@
package top.r3944realms.lib39.base.compat.jade;
import net.minecraft.resources.ResourceLocation;
import snownee.jade.api.IWailaClientRegistration;
import snownee.jade.api.IWailaPlugin;
import snownee.jade.api.WailaPlugin;
import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.base.compat.jade.provider.ForgeDollComponentProvider;
import top.r3944realms.lib39.content.block.DollBlock;
/**
* The type Forge jade plugin.
*/
@WailaPlugin
public class ForgeJadePlugin implements IWailaPlugin {
/**
* The constant UID.
*/
public static final ResourceLocation UID = Lib39.rl("lib39");
@Override
public void registerClient(IWailaClientRegistration registration) {
registration.registerBlockComponent(new ForgeDollComponentProvider(), DollBlock.class);
}
}

View File

@ -0,0 +1,32 @@
package top.r3944realms.lib39.base.compat.jade.provider;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import snownee.jade.api.BlockAccessor;
import snownee.jade.api.IBlockComponentProvider;
import snownee.jade.api.ITooltip;
import snownee.jade.api.config.IPluginConfig;
import top.r3944realms.lib39.base.compat.jade.ForgeJadePlugin;
import top.r3944realms.lib39.content.block.blockentity.DollBlockEntity;
/**
* The type Forge doll component provider.
*/
public class ForgeDollComponentProvider implements IBlockComponentProvider {
@Override
public ResourceLocation getUid() {
return ForgeJadePlugin.UID;
}
@Override
public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) {
if (blockAccessor.getBlockEntity() instanceof DollBlockEntity doll) {
GameProfile ownerProfile = doll.getOwnerProfile();
if (ownerProfile != null) {
iTooltip.add(Component.translatable("tooltip.lib39.content.doll.hover.1", ownerProfile.getName()));
}
}
}
}

View File

@ -13,6 +13,6 @@ public class Lib39BlockLootTable extends BlockLootTables {
*/ */
public Lib39BlockLootTable() { public Lib39BlockLootTable() {
super(ForgeLib39Blocks.BLOCKS); super(ForgeLib39Blocks.BLOCKS);
dropSelf(Lib39Blocks.DOLL); dropSelf(Lib39Blocks.DOLL, Lib39Blocks.WALL_DOLL);
} }
} }

View File

@ -3,7 +3,6 @@ package top.r3944realms.lib39.base.datagen.provider;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.data.PackOutput; import net.minecraft.data.PackOutput;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraftforge.client.model.generators.BlockStateProvider; import net.minecraftforge.client.model.generators.BlockStateProvider;
import net.minecraftforge.client.model.generators.ConfiguredModel; import net.minecraftforge.client.model.generators.ConfiguredModel;
import net.minecraftforge.client.model.generators.ModelFile; import net.minecraftforge.client.model.generators.ModelFile;
@ -39,15 +38,16 @@ public class Lib39BlockStatesProvider extends BlockStateProvider {
models().existingFileHelper models().existingFileHelper
); );
getVariantBuilder(doll).forAllStates(state -> { getVariantBuilder(doll).forAllStates(state -> ConfiguredModel.builder()
Direction direction = state.getValue(BlockStateProperties.HORIZONTAL_FACING);
int rotationY = getMainNorthRotationY(direction);
return ConfiguredModel.builder()
.modelFile(modelFile) .modelFile(modelFile)
.rotationY(rotationY) .build());
.build();
}); Block wallDoll = Lib39Blocks.WALL_DOLL.get();
getVariantBuilder(wallDoll).forAllStates(state -> ConfiguredModel.builder()
.modelFile(modelFile)
.build());
} }
@Contract(pure = true) @Contract(pure = true)

View File

@ -7,7 +7,15 @@ import top.r3944realms.lib39.client.renderer.item.DollItemRenderer;
import java.util.function.Consumer; import java.util.function.Consumer;
/**
* The type Forge doll item.
*/
public class ForgeDollItem extends DollItem { public class ForgeDollItem extends DollItem {
/**
* Instantiates a new Forge doll item.
*
* @param properties the properties
*/
public ForgeDollItem(Properties properties) { public ForgeDollItem(Properties properties) {
super(properties); super(properties);
} }

View File

@ -19,11 +19,30 @@ import java.util.function.Consumer;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public abstract class ForgeCompatManager extends CompatManager { public abstract class ForgeCompatManager extends CompatManager {
protected final IEventBus modEventBus, gameEventBus; /**
* The Mod event bus.
*/
protected final IEventBus modEventBus, /**
* The Game event bus.
*/
gameEventBus;
/**
* The Compats.
*/
protected final Map<ResourceLocation, IForgeCompat> compats = new HashMap<>(); protected final Map<ResourceLocation, IForgeCompat> compats = new HashMap<>();
// 存储事件监听器配置 /**
* The Listener configs.
*/
// 存储事件监听器配置
protected final List<ListenerConfig> listenerConfigs = new ArrayList<>(); protected final List<ListenerConfig> listenerConfigs = new ArrayList<>();
/**
* Instantiates a new Forge compat manager.
*
* @param id the id
* @param modEventBus the mod event bus
* @param gameEventBus the game event bus
*/
public ForgeCompatManager(ResourceLocation id, IEventBus modEventBus, IEventBus gameEventBus) { public ForgeCompatManager(ResourceLocation id, IEventBus modEventBus, IEventBus gameEventBus) {
super(id); super(id);
this.modEventBus = modEventBus; this.modEventBus = modEventBus;
@ -223,6 +242,9 @@ public abstract class ForgeCompatManager extends CompatManager {
addListenerForCompat(compatId, null, bus); addListenerForCompat(compatId, null, bus);
} }
/**
* The type Listener config.
*/
protected static class ListenerConfig { protected static class ListenerConfig {
/** /**
* The Compat id. * The Compat id.

View File

@ -30,6 +30,7 @@ public class ClientEventHandler {
* On register shaders. * On register shaders.
* *
* @param event the event * @param event the event
* @throws IOException the io exception
*/ */
@SubscribeEvent @SubscribeEvent
public static void onRegisterShaders(RegisterShadersEvent event) throws IOException { public static void onRegisterShaders(RegisterShadersEvent event) throws IOException {

View File

@ -220,6 +220,7 @@ public class CommonEventHandler {
public static class Mod extends CommonEventHandler { public static class Mod extends CommonEventHandler {
private static final Map<Supplier<Block>, ResourceKey<CreativeModeTab>[]> itemAddMap = new ConcurrentHashMap<>(); private static final Map<Supplier<Block>, ResourceKey<CreativeModeTab>[]> itemAddMap = new ConcurrentHashMap<>();
private static final Map<ResourceKey<CreativeModeTab>, List<Supplier<Block>>> tabToItemsMap = new ConcurrentHashMap<>(); private static final Map<ResourceKey<CreativeModeTab>, List<Supplier<Block>>> tabToItemsMap = new ConcurrentHashMap<>();
/** /**
* On fml common setup. * On fml common setup.
* *

View File

@ -20,7 +20,7 @@ public class ForgeLib39BlockEntities {
//noinspection DataFlowIssue //noinspection DataFlowIssue
Lib39BlockEntities.DOLL_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("doll", Lib39BlockEntities.DOLL_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register("doll",
() -> BlockEntityType.Builder () -> BlockEntityType.Builder
.of(DollBlockEntity::new, Lib39Blocks.DOLL.get()) .of(DollBlockEntity::new, Lib39Blocks.DOLL.get(), Lib39Blocks.WALL_DOLL.get())
.build(null) .build(null)
); );
} }

View File

@ -6,6 +6,7 @@ import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.content.block.DollBlock; import top.r3944realms.lib39.content.block.DollBlock;
import top.r3944realms.lib39.content.block.WallDollBlock;
import top.r3944realms.lib39.util.block.BlockRegistryBuilder; import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
/** /**
@ -23,8 +24,14 @@ public class ForgeLib39Blocks {
.withName("doll") .withName("doll")
.registerBlock(BLOCKS::register, DollBlock::new) .registerBlock(BLOCKS::register, DollBlock::new)
.build(); .build();
Lib39Blocks.WALL_DOLL = BlockRegistryBuilder
.create()
.withName("wall_doll")
.registerBlock(BLOCKS::register, WallDollBlock::new)
.build();
} }
/** /**
* Register. * Register.
* *

View File

@ -3,6 +3,9 @@ package top.r3944realms.lib39.core.sync;
import top.r3944realms.lib39.core.network.NetworkHandler; import top.r3944realms.lib39.core.network.NetworkHandler;
import top.r3944realms.lib39.core.network.toClient.SyncNBTCapDataEntityS2CPacket; import top.r3944realms.lib39.core.network.toClient.SyncNBTCapDataEntityS2CPacket;
/**
* The interface Forge update.
*/
public interface IForgeUpdate extends IUpdate { public interface IForgeUpdate extends IUpdate {
default void update() { default void update() {
NetworkHandler.sendToAllPlayer(new SyncNBTCapDataEntityS2CPacket(getSyncData().entityId(), getSyncData().id, getSyncData().serializeNBT())); NetworkHandler.sendToAllPlayer(new SyncNBTCapDataEntityS2CPacket(getSyncData().entityId(), getSyncData().id, getSyncData().serializeNBT()));

View File

@ -14,6 +14,9 @@ import java.util.Optional;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class SyncData2CapManager extends SyncData2Manager<SyncData2CapManager.TypedSyncEntry<? extends ISyncData<?>>> { public class SyncData2CapManager extends SyncData2Manager<SyncData2CapManager.TypedSyncEntry<? extends ISyncData<?>>> {
/**
* The Typed entries.
*/
protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap(); protected final Map<ResourceLocation, TypedSyncEntry<?>> typedEntries = Maps.newConcurrentMap();
@Override @Override
@ -21,6 +24,11 @@ public class SyncData2CapManager extends SyncData2Manager<SyncData2CapManager.Ty
return typedEntries; return typedEntries;
} }
/**
* The type Typed sync entry.
*
* @param <T> the type parameter
*/
protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Capability<T>, T> { protected static class TypedSyncEntry<T extends ISyncData<?>> extends SyncData2Manager.TypedSyncEntry<Capability<T>, T> {
/** /**
* Instantiates a new Typed sync entry. * Instantiates a new Typed sync entry.
@ -87,6 +95,14 @@ public class SyncData2CapManager extends SyncData2Manager<SyncData2CapManager.Ty
} }
} }
/**
* Update capability in entry.
*
* @param <T> the type parameter
* @param id the id
* @param entry the entry
* @param newCapability the new capability
*/
protected <T extends ISyncData<?>> void updateCapabilityInEntry(ResourceLocation id, TypedSyncEntry<?> entry, Capability<T> newCapability) { protected <T extends ISyncData<?>> void updateCapabilityInEntry(ResourceLocation id, TypedSyncEntry<?> entry, Capability<T> newCapability) {
updateDataProviderInEntry(id, entry, key -> newCapability != null ? key.getCapability(newCapability).resolve() : Optional.empty()); updateDataProviderInEntry(id, entry, key -> newCapability != null ? key.getCapability(newCapability).resolve() : Optional.empty());
} }

View File

@ -7,8 +7,12 @@ import top.r3944realms.lib39.example.core.event.ExCommonEventHandler;
import top.r3944realms.lib39.example.core.network.ExNetworkHandler; import top.r3944realms.lib39.example.core.network.ExNetworkHandler;
import top.r3944realms.lib39.example.core.register.ForgeExLib39Items; import top.r3944realms.lib39.example.core.register.ForgeExLib39Items;
/**
* The type Forge lib 39 example.
*/
public class ForgeLib39Example { public class ForgeLib39Example {
private static boolean registered = false; private static boolean registered = false;
/** /**
* Instantiates a new Lib 39 example. * Instantiates a new Lib 39 example.
*/ */
@ -19,6 +23,10 @@ public class ForgeLib39Example {
registered = true; registered = true;
} }
} }
/**
* Init.
*/
public void init() { public void init() {
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
ForgeExLib39Items.register(modEventBus); ForgeExLib39Items.register(modEventBus);

View File

@ -12,6 +12,9 @@ import top.r3944realms.lib39.core.compat.IForgeCompat;
* The type Lib 39 compat. * The type Lib 39 compat.
*/ */
public class Lib39Compat implements IForgeCompat { public class Lib39Compat implements IForgeCompat {
/**
* The Initialized.
*/
boolean initialized = false; boolean initialized = false;
/** /**
* The constant INSTANCE. * The constant INSTANCE.

View File

@ -4,6 +4,9 @@ import net.minecraftforge.eventbus.api.IEventBus;
import top.r3944realms.lib39.Lib39; import top.r3944realms.lib39.Lib39;
import top.r3944realms.lib39.core.compat.ForgeCompatManager; import top.r3944realms.lib39.core.compat.ForgeCompatManager;
/**
* The type Lib 39 compat manager.
*/
public class Lib39CompatManager extends ForgeCompatManager { public class Lib39CompatManager extends ForgeCompatManager {
/** /**
* Instantiates a new Compat manager. * Instantiates a new Compat manager.

View File

@ -13,8 +13,16 @@ import top.r3944realms.lib39.example.content.data.TestSyncData;
import top.r3944realms.lib39.example.core.network.ClientDataPacket; import top.r3944realms.lib39.example.core.network.ClientDataPacket;
import top.r3944realms.lib39.example.core.network.ExNetworkHandler; import top.r3944realms.lib39.example.core.network.ExNetworkHandler;
/**
* The type Forge fabric item.
*/
public class ForgeFabricItem extends AbstractFabricItem { public class ForgeFabricItem extends AbstractFabricItem {
/**
* Instantiates a new Forge fabric item.
*
* @param properties the properties
*/
public ForgeFabricItem(Properties properties) { public ForgeFabricItem(Properties properties) {
super(properties); super(properties);
} }
@ -29,6 +37,12 @@ public class ForgeFabricItem extends AbstractFabricItem {
ExNetworkHandler.INSTANCE.sendToServer(new ClientDataPacket(clientData, targetEntityId)); ExNetworkHandler.INSTANCE.sendToServer(new ClientDataPacket(clientData, targetEntityId));
} }
/**
* Gets static data.
*
* @param target the target
* @return the static data
*/
public static @Nullable AbstractedTestSyncData getStaticData(Entity target) { public static @Nullable AbstractedTestSyncData getStaticData(Entity target) {
try { try {
AbstractedTestSyncData abstractData = target.getCapability(ExCapabilityHandler.TEST_CAP).resolve().orElse(null); AbstractedTestSyncData abstractData = target.getCapability(ExCapabilityHandler.TEST_CAP).resolve().orElse(null);
@ -41,6 +55,13 @@ public class ForgeFabricItem extends AbstractFabricItem {
return null; return null;
} }
/**
* Handle client data from packet.
*
* @param player the player
* @param clientData the client data
* @param targetEntityId the target entity id
*/
public static void handleClientDataFromPacket(@NotNull ServerPlayer player, AbstractedTestSyncData clientData, int targetEntityId) { public static void handleClientDataFromPacket(@NotNull ServerPlayer player, AbstractedTestSyncData clientData, int targetEntityId) {
Entity target = player.level().getEntity(targetEntityId); Entity target = player.level().getEntity(targetEntityId);

View File

@ -7,8 +7,16 @@ import top.r3944realms.lib39.example.content.data.AbstractedTestSyncData;
import top.r3944realms.lib39.example.content.data.ExCapabilityHandler; import top.r3944realms.lib39.example.content.data.ExCapabilityHandler;
import top.r3944realms.lib39.example.content.data.TestSyncData; import top.r3944realms.lib39.example.content.data.TestSyncData;
/**
* The type Forge neo forge item.
*/
public class ForgeNeoForgeItem extends AbstractNeoForgeItem{ public class ForgeNeoForgeItem extends AbstractNeoForgeItem{
/**
* Instantiates a new Forge neo forge item.
*
* @param properties the properties
*/
public ForgeNeoForgeItem(Properties properties) { public ForgeNeoForgeItem(Properties properties) {
super(properties); super(properties);
} }
@ -17,6 +25,13 @@ public class ForgeNeoForgeItem extends AbstractNeoForgeItem{
protected AbstractedTestSyncData getData(Entity entity) { protected AbstractedTestSyncData getData(Entity entity) {
return getStaticData(entity); return getStaticData(entity);
} }
/**
* Gets static data.
*
* @param target the target
* @return the static data
*/
@SuppressWarnings("JavaExistingMethodCanBeUsed") @SuppressWarnings("JavaExistingMethodCanBeUsed")
public static @Nullable AbstractedTestSyncData getStaticData(Entity target) { public static @Nullable AbstractedTestSyncData getStaticData(Entity target) {
try { try {

View File

@ -71,7 +71,11 @@ public class ExCommonEventHandler {
* The type Mod. * The type Mod.
*/ */
public static class Mod extends ExCommonEventHandler { public static class Mod extends ExCommonEventHandler {
/**
* The constant EVENT_BUS.
*/
public static final IEventBus EVENT_BUS = FMLJavaModLoadingContext.get().getModEventBus(); public static final IEventBus EVENT_BUS = FMLJavaModLoadingContext.get().getModEventBus();
/** /**
* Gets compat manager. * Gets compat manager.
* *

View File

@ -8,7 +8,13 @@ import top.r3944realms.lib39.api.event.RegisterCommandHelpEvent;
import top.r3944realms.lib39.core.command.ICommandHelpManager; import top.r3944realms.lib39.core.command.ICommandHelpManager;
import top.r3944realms.lib39.platform.services.IHelpCommandHook; import top.r3944realms.lib39.platform.services.IHelpCommandHook;
/**
* The enum Forge help command hook.
*/
public enum ForgeHelpCommandHook implements IHelpCommandHook { public enum ForgeHelpCommandHook implements IHelpCommandHook {
/**
* Instance forge help command hook.
*/
INSTANCE; INSTANCE;
@Override @Override

View File

@ -8,6 +8,9 @@ import top.r3944realms.lib39.platform.services.IHelpCommandHook;
import top.r3944realms.lib39.platform.services.IPlatformHelper; import top.r3944realms.lib39.platform.services.IPlatformHelper;
import top.r3944realms.lib39.platform.services.IUtilHelper; import top.r3944realms.lib39.platform.services.IUtilHelper;
/**
* The type Forge platform helper.
*/
public class ForgePlatformHelper implements IPlatformHelper { public class ForgePlatformHelper implements IPlatformHelper {
@Override @Override

View File

@ -4,7 +4,13 @@ import top.r3944realms.lib39.platform.services.IUtilHelper;
import top.r3944realms.lib39.util.ForgeBlockRegistryBuilder; import top.r3944realms.lib39.util.ForgeBlockRegistryBuilder;
import top.r3944realms.lib39.util.block.BlockRegistryBuilder; import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
/**
* The enum Forge util helper.
*/
public enum ForgeUtilHelper implements IUtilHelper { public enum ForgeUtilHelper implements IUtilHelper {
/**
* Instance forge util helper.
*/
INSTANCE; INSTANCE;
@Override @Override
public BlockRegistryBuilder getBlockRegistryBuilder() { public BlockRegistryBuilder getBlockRegistryBuilder() {

View File

@ -8,6 +8,9 @@ import top.r3944realms.lib39.util.block.BlockRegistryBuilder;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* The type Forge block registry builder.
*/
public class ForgeBlockRegistryBuilder extends BlockRegistryBuilder { public class ForgeBlockRegistryBuilder extends BlockRegistryBuilder {
@SafeVarargs @SafeVarargs
@Override @Override

View File

@ -3,7 +3,7 @@
# Every field you add must be added to buildSrc/src/main/groovy/multiloader-common.gradle expandProps map. # Every field you add must be added to buildSrc/src/main/groovy/multiloader-common.gradle expandProps map.
# Project # Project
version=0.5.0 version=0.5.5
group=top.r3944realms.lib39 group=top.r3944realms.lib39
java_version=17 java_version=17
@ -31,3 +31,18 @@ forge_loader_version_range=[47,)
# Gradle # Gradle
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false org.gradle.daemon=false
# Release
publish_github=true
publish_modrinth=true
publish_curseforge=true
modrinth_id=n65Vs1Vk
curseforge_id=1445917
java_versions=21 17
fabric_modrinth_dependencies=
forge_modrinth_dependencies=
fabric_curseforge_dependencies=
forge_curseforge_dependencies=

23
style.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the Google coding conventions from Google Java Style
that can be found at https://google.github.io/styleguide/javaguide.html
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.org (or in your downloaded distribution).
To completely disable a check, just comment it out or delete it from the file.
To suppress certain violations please review suppression filters.
Authors: Max Vetrenko, Mauryan Kansara, Ruslan Diachenko, Roman Ivanov.
-->
<module name="Checker">
<!-- 检查器配置 -->
<property name="charset" value="UTF-8"/>
<!-- 字符集 -->
</module>