diff --git a/README.md b/README.md
index 0dd7d6b..e952e1a 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,8 @@ All you need is a cannon and enough gunpowder, and you can experience a journey
| Mod Update Plan | Status |
|----------------|--------|
| Migration to Forge 1.20.1 | ✅ Completed |
-| Migration to higher versions of NeoForge | Not started, planned for July/August |
-| Open API for cross-mod compatibility | Not started, planned for July/August |
+| Migration to higher versions of NeoForge | Not started |
+| Open API for cross-mod compatibility | Not started, |
| Improve and refactor the original mod's operations | Not started |
## Mod Development Statement
@@ -26,33 +26,30 @@ This mod is a migration and refactor of **Blast Travel** (the original mod only
- The **1.20.1 Quilt version** is based on **Abbie5's fork**, with the MODID remaining as `blasttravel`.
- The **1.20.1 Forge version** is a partial logic refactor by the author, with the MODID changed to `blasttravelreborn`. Please note the difference.
-## Q&A
-
-**Q1: Will there be Fabric support for future higher versions?**
-**A1:** Probably not. The author is not a fan of Fabric's development workflow. However, anyone is welcome to fork the project and develop a Fabric version. That said, the author might consider using the **Architectury** framework for multi-loader support (though it would be quite a hassle).
-
-**Q2: Can my mod integrate with this mod?**
-**A2:** Yes! The author welcomes mod integrations. If you're a mod developer interested in compatibility, feel free to submit an **ISSUE** in this repository. The author is happy to provide code-level support.
-
-**Q3: Will you support versions below 1.19.2?**
-**A3:** No. The author will **never** backport to lower versions. However, there is a mod with similar functionality—**Cannon (Teacon2022 Example Mod)**, which supports **1.18–1.18.2** and can serve as an alternative.
-
# Adding to Your Project
-1. Download mod jar file,and put it under your project's 'libs/' dir, and rename it into "{modid}-{minecraft-version}-{mod_version}.jar"(for example, "blasttravelreborn-1.20.1-1.0.6-forge-all.jar")
-2. Ensure your `build.gradle` has enable 'libs' flatDir repositories
- ```groovy
- repositories {
- flatDir {
- dir 'libs'
- }
+# For Developer
+You can integrate and automatically download JsonEM for your mod project using Gradle.
+Just add the following to your build script (`build.gradle`):
+
+## Repositories
+```gradle
+repositories {
+ maven {
+ name = "LTD Maven"
+ url = "https://nexus.bot.leisuretimedock.top/repository/maven-public/"
}
- ````
-3. Add it to dependencies
- ```groovy
- dependencies {
- implementation fg.deobf("blank:blasttravelreborn-1.20.1:1.0.6-forge-all")//for example
- }
- ````
+}
+```
+### Forge
+```gradle
+dependencies {
+ implementation fg.deobf("com.leisuretimedock.blastravelreborn:${minecraft_version}-${blasttravelreborn_version})"
+}
+```
+### Choose a Version
+
+`${mc_version}` gets replaced by the current Minecraft version. (i.e. `1.20.1`)
+`${blasttravelreborn_version}` gets replaced by the version of JEI you want to use (i.e `1.0.7`)
Cannon Model please install [BlockBench Plugin](https://github.com/LeisureTimeDock/JsonEM_Neo_Forge/blob/1.21/jsonem_models.js) in your BlockBench.
And import 'entity/cannon/main.json' with this jsonem plugin. Then you can view the cannon model correctly and create its texture.
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index cade956..1097e2e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,6 +8,7 @@ buildscript {
plugins {
id 'eclipse'
+ id 'maven-publish'
id 'idea'
id 'net.minecraftforge.gradle' version '[6.0.16,6.2)'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
@@ -152,7 +153,11 @@ repositories {
}
// If you have mod jar dependencies in ./libs, you can declare them as a repository like so.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver
- flatDir {
+ maven {
+ name = "LTD Maven"
+ url = "https://nexus.bot.leisuretimedock.top/repository/maven-public/"
+ }
+ flatDir {
dir 'libs'
}
@@ -167,9 +172,12 @@ dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
implementation 'org.spongepowered:mixin:0.8.5'
annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'
- implementation jarJar(fg.deobf("blank:jsonem-${minecraft_version}:${jsonem_version}")) {
- jarJar.ranged(it, "[0.0,)")
+ implementation "top.r3944realms.lib39:lib39:${lib39_version}"
+ implementation jarJar(fg.deobf("com.leisuretimedock:jsonem-forge-${minecraft_version}:${jsonem_version}")) {
+ jarJar.ranged(it, "[${jsonem_version},)")
}
+
+
// Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}")
@@ -226,3 +234,43 @@ tasks.named('jar', Jar).configure {
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
}
+
+publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ artifactId = base.archivesName.get()
+ from components.java
+ artifactId = "${mod_id}-${project.name}-${minecraft_version}"
+
+ pom {
+ name = rootProject.mod_id
+ description = rootProject.mod_description
+ url = rootProject.mod_source
+ licenses {
+ license {
+ name = rootProject.mod_license
+ }
+ }
+ developers {
+ developer {
+ id = rootProject.mod_id
+ name = rootProject.mod_authors
+ }
+ }
+ }
+ }
+ }
+ repositories {
+ maven {
+ url "file://${project.projectDir}/mcmodsrepo"
+ }
+ maven {
+ name = 'LTDNexus'
+ url = 'https://nexus.bot.leisuretimedock.top/repository/maven-releases/'
+ credentials {
+ username = System.getenv('LTDNexusUsername') ?: ''
+ password = System.getenv('LTDNexusPassword') ?: ''
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index ba9a632..632f6ca 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -38,8 +38,10 @@ mod_name=BlastTravel-Reborn
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT
# The mod version. See https://semver.org/
-mod_version=1.0.6+1.20.1-forge
-jsonem_version=0.2.2+1.20-fabrge
+mod_version=1.0.7
+jsonem_version=0.2.4
+lib39_version=1.20.1-0.0.17
+mod_source=https://github.com/LeisureTimeDock/BlastTravel_Neo_Forge
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
@@ -47,4 +49,4 @@ mod_group_id=com.leisuretimedock.blasttravelreborn
# The authors of the mod. This is a simple text string that is used for display purposes in the mod list.
mod_authors=FoundationGames(Original Author), Abbie5(Migrate into Quilt 1.20.1), R3944Realms
# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list.
-mod_description=Migrate from Quilt 1.20.1,1.19.2
+mod_description=Migrate from Quilt 1.20.1, 1.19.2
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.md5 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.md5
new file mode 100644
index 0000000..2399d48
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.md5
@@ -0,0 +1 @@
+787f3aedc203dff6fcef2b438729cc7e
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha1 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha1
new file mode 100644
index 0000000..155e34e
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha1
@@ -0,0 +1 @@
+0446695fdc79163fa7a1ce6e792172fbcdbaafc1
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha256 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha256
new file mode 100644
index 0000000..bfeeaf2
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha256
@@ -0,0 +1 @@
+0195af1841c2087eb2a10cbc75e0b9fc1d30f62f2a752a6797acbb3d503b8af3
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha512 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha512
new file mode 100644
index 0000000..2bc0b54
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.jar.sha512
@@ -0,0 +1 @@
+ac8caf27e4c5d9e7d04fb6b4eff0bc5aa27e8e0440be346cbf2161c775a5a23c5326c201a83d93fbaea95ee40c8a6fb0a649b5db0d3cc0b14f11dfb8568c3c0f
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom
new file mode 100644
index 0000000..2c7d638
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom
@@ -0,0 +1,8 @@
+
+
+ 4.0.0
+ com.leisuretimedock.blasttravelreborn
+ blasttravel-reborn
+ 1.0.6+1.20.1-forge
+
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.md5 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.md5
new file mode 100644
index 0000000..a8dc868
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.md5
@@ -0,0 +1 @@
+e3426fd0c4b900d1cad53c5308a75011
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha1 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha1
new file mode 100644
index 0000000..f3460fd
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha1
@@ -0,0 +1 @@
+8e2b7ac803f1a5d1bf02a9ef77fcf48d6f138cbb
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha256 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha256
new file mode 100644
index 0000000..7d15038
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha256
@@ -0,0 +1 @@
+48136ed719d64d3e436b1782f494892fdb7abd6f08b9ff7750c07201bc9ff8f8
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha512 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha512
new file mode 100644
index 0000000..b823578
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/1.0.6+1.20.1-forge/blasttravel-reborn-1.0.6+1.20.1-forge.pom.sha512
@@ -0,0 +1 @@
+30938abad6f11d4d26e73abe9cee3cb8321def9421f530574e68a89010f79e56e3bd860ec491e25a5a841a4787ea93a094675ecfc114b193137f808a558ab16c
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml
new file mode 100644
index 0000000..6739775
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml
@@ -0,0 +1,13 @@
+
+
+ com.leisuretimedock.blasttravelreborn
+ blasttravel-reborn
+
+ 1.0.6+1.20.1-forge
+ 1.0.6+1.20.1-forge
+
+ 1.0.6+1.20.1-forge
+
+ 20250612155714
+
+
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.md5 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.md5
new file mode 100644
index 0000000..4cf505e
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.md5
@@ -0,0 +1 @@
+7be97661cf89db9c24d0e144216f7911
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha1 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha1
new file mode 100644
index 0000000..0baada3
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha1
@@ -0,0 +1 @@
+bcbda3d6ce62aa2d5daa5cd991285b008b51ea81
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha256 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha256
new file mode 100644
index 0000000..a2e0527
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha256
@@ -0,0 +1 @@
+e56c09fc1d1fa062ea5b77ea5673c19c4a56ee4b91450646d2aed786832ce267
\ No newline at end of file
diff --git a/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha512 b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha512
new file mode 100644
index 0000000..ba1b527
--- /dev/null
+++ b/mcmodsrepo/com/leisuretimedock/blasttravelreborn/blasttravel-reborn/maven-metadata.xml.sha512
@@ -0,0 +1 @@
+3bdb8ae4325fd516bfaafeb33b0221f51f88eadd8388e3c49ea7f160eca95d34f5e04809a389afd6af913e21bf4985dd3a6d99cb4b491e12961b458293110f62
\ No newline at end of file
diff --git a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924
new file mode 100644
index 0000000..c3d7659
--- /dev/null
+++ b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924
@@ -0,0 +1,2 @@
+// 1.20.1 2025-11-22T19:25:06.9619789 Registries
+e615490187adee92d48183e84dd6953d340753c2 data/blasttravelreborn/damage_type/cannon.json
diff --git a/src/generated/resources/.cache/1de3d2ee724999f84a11b20b51c37030049be277 b/src/generated/resources/.cache/1de3d2ee724999f84a11b20b51c37030049be277
new file mode 100644
index 0000000..6089908
--- /dev/null
+++ b/src/generated/resources/.cache/1de3d2ee724999f84a11b20b51c37030049be277
@@ -0,0 +1,2 @@
+// 1.20.1 2025-11-22T19:25:06.9619789 Languages: zh_tw
+094e7efc852fc45d55f97c0976bf2453de88e219 assets/blasttravelreborn/lang/zh_tw.json
diff --git a/src/generated/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac b/src/generated/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac
new file mode 100644
index 0000000..b90a52e
--- /dev/null
+++ b/src/generated/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac
@@ -0,0 +1,2 @@
+// 1.20.1 2025-11-22T19:25:06.9619789 Languages: zh_cn
+03cccc87a6370bef5c6b95b1d76cd9d22547b86c assets/blasttravelreborn/lang/zh_cn.json
diff --git a/src/generated/resources/.cache/670bd2c23aae7d9a50477c516c446ad8015e32b8 b/src/generated/resources/.cache/670bd2c23aae7d9a50477c516c446ad8015e32b8
new file mode 100644
index 0000000..bc023bb
--- /dev/null
+++ b/src/generated/resources/.cache/670bd2c23aae7d9a50477c516c446ad8015e32b8
@@ -0,0 +1,2 @@
+// 1.20.1 2025-11-22T19:25:06.9619789 Item Models: blasttravelreborn
+3efedd95103ec88f295ab752f9591da6f20e9cb2 assets/blasttravelreborn/models/item/cannon.json
diff --git a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
new file mode 100644
index 0000000..bb15718
--- /dev/null
+++ b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
@@ -0,0 +1,3 @@
+// 1.20.1 2025-11-22T19:25:06.9619789 Recipes
+d38155e7a052e0f1143b0b82dc1a595026c4d98c data/blasttravelreborn/advancements/recipes/misc/cannon.json
+7fd4c6df73dc342481e69f6d24914ca8e767b578 data/blasttravelreborn/recipes/cannon.json
diff --git a/src/generated/resources/.cache/b5294eda5c650593108e068003e23d389cc35af6 b/src/generated/resources/.cache/b5294eda5c650593108e068003e23d389cc35af6
new file mode 100644
index 0000000..baa2dbb
--- /dev/null
+++ b/src/generated/resources/.cache/b5294eda5c650593108e068003e23d389cc35af6
@@ -0,0 +1,2 @@
+// 1.20.1 2025-11-22T19:28:42.6814983 Particle Descriptions
+1aacb18bd6bc829ecf1ac93ae1e3e4a9c30459b9 assets/blasttravelreborn/particles/cannon_blast.json
diff --git a/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8
new file mode 100644
index 0000000..fa5f335
--- /dev/null
+++ b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8
@@ -0,0 +1,2 @@
+// 1.20.1 2025-11-22T19:25:06.9619789 Languages: en_us
+c3f0d412d3d39f47d1dd4065782d0984a17ed4e7 assets/blasttravelreborn/lang/en_us.json
diff --git a/src/generated/resources/assets/blasttravelreborn/lang/en_us.json b/src/generated/resources/assets/blasttravelreborn/lang/en_us.json
new file mode 100644
index 0000000..77fdfd7
--- /dev/null
+++ b/src/generated/resources/assets/blasttravelreborn/lang/en_us.json
@@ -0,0 +1,9 @@
+{
+ "container.blasttravelreborn.cannon_container_menu": "Cannon",
+ "death.attack.blasttravelreborn.cannon": "%s was knocked out by a flying %s",
+ "dialog.blasttravelreborn.full_cannon": "Cannon is full!",
+ "dialog.blasttravelreborn.no_gunpowder": "Cannon has no gunpowder!",
+ "entity.blasttravelreborn.cannon": "Cannon",
+ "item.blasttravelreborn.cannon": "Cannon",
+ "mount.blasttravelreborn.cannon.onboard": "Press %s to Exit, or %s to Fire"
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/blasttravelreborn/lang/zh_cn.json b/src/generated/resources/assets/blasttravelreborn/lang/zh_cn.json
similarity index 73%
rename from src/main/resources/assets/blasttravelreborn/lang/zh_cn.json
rename to src/generated/resources/assets/blasttravelreborn/lang/zh_cn.json
index 11f8179..a93dcf3 100644
--- a/src/main/resources/assets/blasttravelreborn/lang/zh_cn.json
+++ b/src/generated/resources/assets/blasttravelreborn/lang/zh_cn.json
@@ -1,10 +1,9 @@
{
- "container.blasttravelreborn.cannon_container_menu": "大炮",
- "item.blasttravelreborn.cannon": "大炮",
- "entity.blasttravelreborn.cannon": "大炮实体",
-
+ "container.blasttravelreborn.cannon_container_menu": "大炮实体",
"death.attack.blasttravelreborn.cannon": "%s被飞行的%s击倒了",
"dialog.blasttravelreborn.full_cannon": "大炮已装满!",
"dialog.blasttravelreborn.no_gunpowder": "大炮没有火药了!",
+ "entity.blasttravelreborn.cannon": "大炮",
+ "item.blasttravelreborn.cannon": "大炮",
"mount.blasttravelreborn.cannon.onboard": "按%s离开,或按%s发射"
-}
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/blasttravelreborn/lang/zh_tw.json b/src/generated/resources/assets/blasttravelreborn/lang/zh_tw.json
new file mode 100644
index 0000000..cdfb023
--- /dev/null
+++ b/src/generated/resources/assets/blasttravelreborn/lang/zh_tw.json
@@ -0,0 +1,9 @@
+{
+ "container.blasttravelreborn.cannon_container_menu": "大砲實體",
+ "death.attack.blasttravelreborn.cannon": "%s被飛行的%s擊倒了",
+ "dialog.blasttravelreborn.full_cannon": "大砲已裝滿!",
+ "dialog.blasttravelreborn.no_gunpowder": "大砲沒有火藥了!",
+ "entity.blasttravelreborn.cannon": "大砲",
+ "item.blasttravelreborn.cannon": "大砲",
+ "mount.blasttravelreborn.cannon.onboard": "按%s離開,或按%s發射"
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/blasttravelreborn/models/item/cannon.json b/src/generated/resources/assets/blasttravelreborn/models/item/cannon.json
new file mode 100644
index 0000000..20897c8
--- /dev/null
+++ b/src/generated/resources/assets/blasttravelreborn/models/item/cannon.json
@@ -0,0 +1,6 @@
+{
+ "parent": "minecraft:item/generated",
+ "textures": {
+ "layer0": "blasttravelreborn:item/cannon"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/blasttravelreborn/particles/cannon_blast.json b/src/generated/resources/assets/blasttravelreborn/particles/cannon_blast.json
new file mode 100644
index 0000000..028615a
--- /dev/null
+++ b/src/generated/resources/assets/blasttravelreborn/particles/cannon_blast.json
@@ -0,0 +1,12 @@
+{
+ "textures": [
+ "blasttravelreborn:blast_smoke_0",
+ "blasttravelreborn:blast_smoke_1",
+ "blasttravelreborn:blast_smoke_2",
+ "blasttravelreborn:blast_smoke_3",
+ "blasttravelreborn:blast_smoke_4",
+ "blasttravelreborn:blast_smoke_5",
+ "blasttravelreborn:blast_smoke_6",
+ "blasttravelreborn:blast_smoke_7"
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/blasttravelreborn/advancements/recipes/misc/cannon.json b/src/generated/resources/data/blasttravelreborn/advancements/recipes/misc/cannon.json
new file mode 100644
index 0000000..d5efd66
--- /dev/null
+++ b/src/generated/resources/data/blasttravelreborn/advancements/recipes/misc/cannon.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_iron_block": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "minecraft:iron_block"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "blasttravelreborn:cannon"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_iron_block",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "blasttravelreborn:cannon"
+ ]
+ },
+ "sends_telemetry_event": false
+}
\ No newline at end of file
diff --git a/src/main/resources/data/blasttravelreborn/damage_type/cannon.json b/src/generated/resources/data/blasttravelreborn/damage_type/cannon.json
similarity index 77%
rename from src/main/resources/data/blasttravelreborn/damage_type/cannon.json
rename to src/generated/resources/data/blasttravelreborn/damage_type/cannon.json
index 5b2cafd..c6e5753 100644
--- a/src/main/resources/data/blasttravelreborn/damage_type/cannon.json
+++ b/src/generated/resources/data/blasttravelreborn/damage_type/cannon.json
@@ -1,5 +1,5 @@
{
+ "exhaustion": 0.0,
"message_id": "cannon",
- "exhaustion": 0,
"scaling": "when_caused_by_living_non_player"
-}
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/blasttravelreborn/recipes/cannon.json b/src/generated/resources/data/blasttravelreborn/recipes/cannon.json
new file mode 100644
index 0000000..a333a70
--- /dev/null
+++ b/src/generated/resources/data/blasttravelreborn/recipes/cannon.json
@@ -0,0 +1,30 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "A": {
+ "item": "minecraft:iron_block"
+ },
+ "B": {
+ "item": "minecraft:string"
+ },
+ "C": {
+ "tag": "minecraft:stone_crafting_materials"
+ },
+ "D": {
+ "item": "minecraft:stick"
+ },
+ "E": {
+ "tag": "minecraft:logs"
+ }
+ },
+ "pattern": [
+ " A",
+ "BA ",
+ "CDE"
+ ],
+ "result": {
+ "item": "blasttravelreborn:cannon"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/BlastTravelReborn.java b/src/main/java/com/leisuretimedock/blasttravelreborn/BlastTravelReborn.java
index e60a678..7e6cea1 100644
--- a/src/main/java/com/leisuretimedock/blasttravelreborn/BlastTravelReborn.java
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/BlastTravelReborn.java
@@ -9,12 +9,10 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
@Mod(value = BlastTravelReborn.MOD_ID)
public class BlastTravelReborn {
public static final String MOD_ID = "blasttravelreborn";
- public static final Logger LOG = LoggerFactory.getLogger("Blast Travel Reborn");
public BlastTravelReborn() {
FMLJavaModLoadingContext fmlJavaModLoadingContext = FMLJavaModLoadingContext.get();
IEventBus modEventBus = fmlJavaModLoadingContext.getModEventBus();
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/api/events/RegisterCannonBehaviorEvent.java b/src/main/java/com/leisuretimedock/blasttravelreborn/api/events/RegisterCannonBehaviorEvent.java
new file mode 100644
index 0000000..814d927
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/api/events/RegisterCannonBehaviorEvent.java
@@ -0,0 +1,12 @@
+package com.leisuretimedock.blasttravelreborn.api.events;
+
+import com.leisuretimedock.blasttravelreborn.content.entity.cannon.CannonBehavior;
+import net.minecraftforge.eventbus.api.Event;
+import net.minecraftforge.fml.event.IModBusEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class RegisterCannonBehaviorEvent extends Event implements IModBusEvent {
+ public void registerCannonBehavior(@NotNull CannonBehavior behavior) {
+ behavior.register();
+ }
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/client/entity/CannonEntityRenderer.java b/src/main/java/com/leisuretimedock/blasttravelreborn/client/entity/CannonEntityRenderer.java
index 9a1309a..e208d00 100644
--- a/src/main/java/com/leisuretimedock/blasttravelreborn/client/entity/CannonEntityRenderer.java
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/client/entity/CannonEntityRenderer.java
@@ -17,6 +17,7 @@ import net.minecraft.util.Mth;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
+
@OnlyIn(Dist.CLIENT)
public class CannonEntityRenderer extends EntityRenderer {
public static final ModelLayerLocation MODEL = new ModelLayerLocation(BlastTravelReborn.id("cannon"), "main");
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/content/BTRDamageTypes.java b/src/main/java/com/leisuretimedock/blasttravelreborn/content/BTRDamageTypes.java
new file mode 100644
index 0000000..78c6f91
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/content/BTRDamageTypes.java
@@ -0,0 +1,23 @@
+package com.leisuretimedock.blasttravelreborn.content;
+
+import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.data.worldgen.BootstapContext;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.world.damagesource.DamageScaling;
+import net.minecraft.world.damagesource.DamageType;
+
+public class BTRDamageTypes {
+ public static final ResourceKey CANNON = ResourceKey.create(Registries.DAMAGE_TYPE,
+ BlastTravelReborn.id("cannon"));
+
+ public static void bootstrap(BootstapContext context) {
+ context.register(CANNON, new DamageType(
+ "cannon",
+ DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER,
+ 0.0F
+ ));
+
+
+ }
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/CannonEntity.java b/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/CannonEntity.java
index fbf01df..f3f2fac 100644
--- a/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/CannonEntity.java
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/CannonEntity.java
@@ -17,7 +17,6 @@ import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
-import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
@@ -163,6 +162,11 @@ public class CannonEntity extends Entity {
@Override
public @NotNull InteractionResult interact(@NotNull Player player, @NotNull InteractionHand hand) {
+ ItemStack handItem = player.getItemInHand(hand);
+ // 如果手持火药,填充到大炮中
+ if(!player.isShiftKeyDown()) {
+ if (testAndInteract(player, handItem)) return InteractionResult.sidedSuccess(level().isClientSide());
+ }
if (player == this.getFirstPassenger()) {
return super.interact(player, hand);
}
@@ -196,6 +200,90 @@ public class CannonEntity extends Entity {
return super.interact(player, hand);
}
+ private boolean testAndInteract(Player player, @NotNull ItemStack stack) {
+ if (stack.is(Items.GUNPOWDER)) {
+ handlerGunPower(player, stack);
+ return true;
+ } else if (stack.is(Items.CHAIN)) {
+ handlerChain(player, stack);
+ return true;
+ } else if (CannonBehavior.isValidBehaviorStack(stack)) {
+ handlerBehaviorItem(player, stack);
+ return true;
+ }
+ return false;
+ }
+
+ private void handlerGunPower(Player player, ItemStack stack) {
+ if (!level().isClientSide()) {
+ ItemStack currentGunpowder = inventory.getItem(0);
+
+ // 如果炮内已有火药,先还给玩家
+ if (currentGunpowder.getCount() >= currentGunpowder.getMaxStackSize()) {
+ if (!player.isCreative() && !player.getInventory().add(currentGunpowder)) {
+ // 如果背包满了,掉落在地上
+ player.drop(currentGunpowder, false);
+ }
+ }
+
+ // 设置新的火药到炮中
+ ItemStack newGunpowder = stack.copy();
+ newGunpowder.setCount(currentGunpowder.getCount() + 1); // 只放一个火药
+ ((ServerPlayer) player).sendSystemMessage(Component.literal(String.format("%d / %d", currentGunpowder.getCount(), currentGunpowder.getMaxStackSize())), true);
+ inventory.setItem(0, newGunpowder);
+
+ if (!player.isCreative()) {
+ stack.shrink(1);
+ }
+
+ level().playSound(null, this.blockPosition(), SoundEvents.SAND_PLACE, SoundSource.BLOCKS, 1.0f, 1.0f);
+ }
+ }
+
+ private void handlerChain(Player player, ItemStack stack) {
+ if (!level().isClientSide()) {
+ ItemStack currentChain = inventory.getItem(2);
+ if (currentChain.isEmpty()) { // 添加锁链
+ ItemStack item = stack.copy();
+ item.setCount(1);
+ inventory.setItem(2, item);
+ if (!player.isCreative()) {
+ stack.shrink(1);
+ }
+ level().playSound(null, this.blockPosition(), SoundEvents.CHAIN_PLACE, SoundSource.BLOCKS, 1.0f, 1.0f);
+ } else {
+ inventory.setItem(2, ItemStack.EMPTY);
+ if (!player.isCreative()) { // 移除锁链
+ if (!player.getInventory().add(currentChain)) {
+ player.drop(currentChain, false);
+ }
+ }
+ level().playSound(null, this.blockPosition(), SoundEvents.CHAIN_FALL, SoundSource.BLOCKS, 1.0f, 1.0f);
+ }
+ }
+ }
+
+ private void handlerBehaviorItem(Player player, ItemStack stack) {
+ if (!level().isClientSide()) {
+ ItemStack currentBehaviorItem = inventory.getItem(2);
+ if (currentBehaviorItem.isEmpty()) { // 添加物品
+ ItemStack item = stack.copy();
+ item.setCount(1);
+ inventory.setItem(2, item);
+ if (!player.isCreative()) {
+ stack.shrink(1);
+ }
+ level().playSound(null, this.blockPosition(), getBehavior().getPlaceInSound(), SoundSource.BLOCKS, 1.0f, 1.0f);
+ } else {
+ if (stack.is(currentBehaviorItem.getItem())) { //同类物品 +1
+
+ } else { //不同类替换
+
+ }
+ }
+ }
+ }
+
@Override
public boolean skipAttackInteraction(@NotNull Entity attacker) {
if (attacker instanceof Player player && player != this.getFirstPassenger()) {
@@ -299,12 +387,17 @@ public class CannonEntity extends Entity {
System.out.println(" - [B]Server: Bounding Box = " + player.getBoundingBox());
System.out.println(" - [B]Server: Delta Movement = " + player.getDeltaMovement());
}
- player.stopRiding();
- ((ServerPlayer) player).connection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
- ((ServerPlayer) player).connection.send(new ClientboundSetEntityMotionPacket(player));
+
+ // 关键修改:先设置速度,再停止乘坐
player.setDeltaMovement(vel);
- player.hurtMarked = true;
+ player.hurtMarked = true; // 强制同步运动状态
+
+ // 然后停止乘坐
+ player.stopRiding();
+
+ // 设置飞行状态
((PlayerEntityDuck)player).blasttravel$setCannonFlight(true);
+
if (!FMLEnvironment.production) {
System.out.println(" - [A]Server: Is Passenger = " + player.isPassenger());
System.out.println(" - [A]Server: On Ground = " + player.onGround());
@@ -315,7 +408,6 @@ public class CannonEntity extends Entity {
System.out.println(" - [A]Server: Delta Movement = " + player.getDeltaMovement());
}
firedPlayer = player;
-
}
this.level().playSound(null, this.blockPosition(), SoundEvents.GENERIC_EXPLODE, SoundSource.BLOCKS, 1, 1);
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/cannon/CannonBehavior.java b/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/cannon/CannonBehavior.java
index 033fdc6..dd50053 100644
--- a/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/cannon/CannonBehavior.java
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/content/entity/cannon/CannonBehavior.java
@@ -5,6 +5,8 @@ import com.leisuretimedock.blasttravelreborn.content.entity.CannonEntity;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.sounds.SoundEvent;
+import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
@@ -16,13 +18,15 @@ import org.joml.Vector3f;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
public class CannonBehavior {
protected static final Vector3f WHITE = new Vector3f(1, 1, 1);
private static final List ID_TO_BEHAVIOR = new ArrayList<>();
private static final Object2IntMap> FILTER_TO_BEHAVIOR_ID = new Object2IntOpenHashMap<>();
-
+ private final AtomicBoolean registered = new AtomicBoolean(false);
+ private SoundEvent placeInSound = SoundEvents.SAND_PLACE, takeOutSound = SoundEvents.EMPTY;
public final Item icon;
public final Predicate filter;
private final ResourceLocation texture;
@@ -41,10 +45,28 @@ public class CannonBehavior {
this.texture = texture;
}
- public CannonBehavior register() {
- FILTER_TO_BEHAVIOR_ID.put(this.filter, ID_TO_BEHAVIOR.size());
- ID_TO_BEHAVIOR.add(this);
+ public void setPlaceInSound(SoundEvent placeInSound) {
+ this.placeInSound = placeInSound;
+ }
+ public SoundEvent getPlaceInSound() {
+ return placeInSound;
+ }
+
+ public SoundEvent getTakeOutSound() {
+ return takeOutSound;
+ }
+
+ public void setTakeOutSound(SoundEvent takeOutSound) {
+ this.takeOutSound = takeOutSound;
+ }
+
+ public CannonBehavior register() {
+ if (!registered.get()) {
+ FILTER_TO_BEHAVIOR_ID.put(this.filter, ID_TO_BEHAVIOR.size());
+ ID_TO_BEHAVIOR.add(this);
+ registered.set(true);
+ }
return this;
}
@@ -86,6 +108,7 @@ public class CannonBehavior {
return texture;
}
+
@OnlyIn(Dist.CLIENT)
public ResourceLocation headTexture(CannonEntity entity) {
var player = entity.getClientPlayer();
@@ -105,4 +128,5 @@ public class CannonBehavior {
public @Nullable Vector3f fireColor(CannonEntity entity) {
return null;
}
+
}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/BTRRegistries.java b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/BTRRegistries.java
new file mode 100644
index 0000000..ab90c19
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/BTRRegistries.java
@@ -0,0 +1,11 @@
+package com.leisuretimedock.blasttravelreborn.datagen;
+
+import com.leisuretimedock.blasttravelreborn.content.BTRDamageTypes;
+import net.minecraft.core.RegistrySetBuilder;
+import net.minecraft.core.registries.Registries;
+
+public class BTRRegistries {
+ public static final RegistrySetBuilder BUILDER = new RegistrySetBuilder()
+ .add(Registries.DAMAGE_TYPE, BTRDamageTypes::bootstrap)
+ ;
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/DataGeneratorHandler.java b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/DataGeneratorHandler.java
new file mode 100644
index 0000000..89e6ebf
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/DataGeneratorHandler.java
@@ -0,0 +1,62 @@
+package com.leisuretimedock.blasttravelreborn.datagen;
+
+import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
+import com.leisuretimedock.blasttravelreborn.datagen.provider.BTRItemModelProvider;
+import com.leisuretimedock.blasttravelreborn.datagen.provider.BTRParticleProvider;
+import com.leisuretimedock.blasttravelreborn.datagen.provider.BTRRecipeProvider;
+import com.leisuretimedock.blasttravelreborn.datagen.value.BTRLangKeys;
+import net.minecraft.data.DataProvider;
+import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider;
+import net.minecraftforge.data.event.GatherDataEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.common.Mod;
+import org.jetbrains.annotations.NotNull;
+import top.r3944realms.lib39.datagen.provider.SimpleLanguageProvider;
+import top.r3944realms.lib39.datagen.value.McLocale;
+
+import java.util.Set;
+
+@Mod.EventBusSubscriber(modid = BlastTravelReborn.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
+public class DataGeneratorHandler {
+ @SubscribeEvent
+ public static void generatorDataEvent(GatherDataEvent event) {
+ LanguageGenerate(event, McLocale.EN_US);
+ LanguageGenerate(event, McLocale.ZH_CN);
+ LanguageGenerate(event, McLocale.ZH_TW);
+ ModelDataGenerate(event);
+ ParticleGenerate(event);
+ RecipeGenerate(event);
+ DatapackBuiltinEntriesGenerate(event);
+ }
+
+ private static void LanguageGenerate(@NotNull GatherDataEvent event, McLocale language) {
+ event.getGenerator().addProvider(
+ event.includeClient(),
+ (DataProvider.Factory) pOutput -> new SimpleLanguageProvider(pOutput, BlastTravelReborn.MOD_ID ,language , BTRLangKeys.INSTANCE)
+ );
+ }
+ private static void ModelDataGenerate(GatherDataEvent event) {
+ event.getGenerator().addProvider(
+ event.includeClient(),
+ (DataProvider.Factory) pOutput -> new BTRItemModelProvider(pOutput, event.getExistingFileHelper())
+ );
+ }
+ private static void RecipeGenerate(GatherDataEvent event) {
+ event.getGenerator().addProvider(
+ event.includeServer(),
+ (DataProvider.Factory) BTRRecipeProvider::new
+ );
+ }
+ private static void ParticleGenerate(GatherDataEvent event) {
+ event.getGenerator().addProvider(
+ event.includeClient(),
+ (DataProvider.Factory) pOutput -> new BTRParticleProvider(pOutput, event.getExistingFileHelper())
+ );
+ }
+ private static void DatapackBuiltinEntriesGenerate(GatherDataEvent event) {
+ event.getGenerator().addProvider(
+ event.includeServer(),
+ (DataProvider.Factory) pOutput -> new DatapackBuiltinEntriesProvider(pOutput, event.getLookupProvider(), BTRRegistries.BUILDER, Set.of(BlastTravelReborn.MOD_ID))
+ );
+ }
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRItemModelProvider.java b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRItemModelProvider.java
new file mode 100644
index 0000000..e461067
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRItemModelProvider.java
@@ -0,0 +1,35 @@
+package com.leisuretimedock.blasttravelreborn.datagen.provider;
+
+import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
+import com.leisuretimedock.blasttravelreborn.content.item.BTRItems;
+import net.minecraft.data.PackOutput;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.item.Item;
+import net.minecraftforge.client.model.generators.ItemModelProvider;
+import net.minecraftforge.common.data.ExistingFileHelper;
+import net.minecraftforge.registries.ForgeRegistries;
+
+import java.util.Objects;
+
+public class BTRItemModelProvider extends ItemModelProvider {
+ public static final String GENERATED = "item/generated";
+ public BTRItemModelProvider(PackOutput packOutput, ExistingFileHelper existingFileHelper) {
+ super(packOutput, BlastTravelReborn.MOD_ID, existingFileHelper);
+ }
+
+ @Override
+ protected void registerModels() {
+ itemGeneratedModel(BTRItems.CANNON_ITEM.get(), resourceItem("cannon"));
+ }
+ public void itemGeneratedModel(Item item, ResourceLocation texture) {
+ withExistingParent(itemName(item), GENERATED).texture("layer0", texture);
+ }
+
+ private String itemName(Item item) {
+ return Objects.requireNonNull(ForgeRegistries.ITEMS.getKey(item)).getPath();
+ }
+
+ public ResourceLocation resourceItem(String path) {
+ return BlastTravelReborn.id("item/" + path);
+ }
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRParticleProvider.java b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRParticleProvider.java
new file mode 100644
index 0000000..9e77621
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRParticleProvider.java
@@ -0,0 +1,27 @@
+package com.leisuretimedock.blasttravelreborn.datagen.provider;
+
+import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
+import com.leisuretimedock.blasttravelreborn.content.BTRParticleTypes;
+import net.minecraft.data.PackOutput;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraftforge.common.data.ExistingFileHelper;
+import net.minecraftforge.common.data.ParticleDescriptionProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BTRParticleProvider extends ParticleDescriptionProvider {
+
+ public BTRParticleProvider(PackOutput output, ExistingFileHelper fileHelper) {
+ super(output, fileHelper);
+ }
+
+ @Override
+ protected void addDescriptions() {
+ List cannonBlastTextures = new ArrayList<>();
+ for (int i = 0; i <= 7; i++){
+ cannonBlastTextures.add(BlastTravelReborn.id("blast_smoke_" + i));
+ }
+ spriteSet(BTRParticleTypes.CANNON_BLAST.get(), cannonBlastTextures);
+ }
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRRecipeProvider.java b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRRecipeProvider.java
new file mode 100644
index 0000000..bc0f078
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/provider/BTRRecipeProvider.java
@@ -0,0 +1,35 @@
+package com.leisuretimedock.blasttravelreborn.datagen.provider;
+
+import com.leisuretimedock.blasttravelreborn.content.item.BTRItems;
+import net.minecraft.data.PackOutput;
+import net.minecraft.data.recipes.FinishedRecipe;
+import net.minecraft.data.recipes.RecipeCategory;
+import net.minecraft.data.recipes.RecipeProvider;
+import net.minecraft.data.recipes.ShapedRecipeBuilder;
+import net.minecraft.tags.ItemTags;
+import net.minecraft.world.item.Items;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Consumer;
+
+public class BTRRecipeProvider extends RecipeProvider {
+ public BTRRecipeProvider(PackOutput pOutput) {
+ super(pOutput);
+ }
+
+ @Override
+ protected void buildRecipes(@NotNull Consumer pWriter) {
+ // 第二个配方(您提供的JSON转换而来)
+ ShapedRecipeBuilder.shaped(RecipeCategory.MISC, BTRItems.CANNON_ITEM.get(), 1)
+ .define('A', Items.IRON_BLOCK)
+ .define('B', Items.STRING)
+ .define('C', ItemTags.STONE_CRAFTING_MATERIALS)
+ .define('D', Items.STICK)
+ .define('E', ItemTags.LOGS)
+ .pattern(" A")
+ .pattern("BA ")
+ .pattern("CDE")
+ .unlockedBy("has_iron_block", has(Items.IRON_BLOCK))
+ .save(pWriter);
+ }
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/value/BTRLangKeys.java b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/value/BTRLangKeys.java
new file mode 100644
index 0000000..a489636
--- /dev/null
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/datagen/value/BTRLangKeys.java
@@ -0,0 +1,81 @@
+package com.leisuretimedock.blasttravelreborn.datagen.value;
+
+import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
+import com.leisuretimedock.blasttravelreborn.content.item.BTRItems;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Unmodifiable;
+import top.r3944realms.lib39.datagen.value.ILangKeyValueCollection;
+import top.r3944realms.lib39.datagen.value.LangKeyValue;
+import top.r3944realms.lib39.datagen.value.ModPartEnum;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public enum BTRLangKeys implements ILangKeyValueCollection {
+ INSTANCE;
+ BTRLangKeys() {
+ initLangKeyValues();
+ }
+
+ final List langKeyValues = new ArrayList<>();
+ public void initLangKeyValues() {
+ addLang(LangKeyValue.ofSupplier(
+ BTRItems.CANNON_ITEM, ModPartEnum.ITEM,
+ "Cannon",
+ "大炮",
+ "大砲",
+ true
+ ));
+ addLang(LangKeyValue.ofKey(
+ ModPartEnum.ENTITY.getFullKey(BlastTravelReborn.MOD_ID, "cannon"), ModPartEnum.ENTITY,
+ "Cannon",
+ "大炮",
+ "大砲"
+ ));
+ addLang(LangKeyValue.ofKey(
+ "container.blasttravelreborn.cannon_container_menu", ModPartEnum.GUI,
+ "Cannon",
+ "大炮实体",
+ "大砲實體"
+ ));
+ addLang(LangKeyValue.ofKey(
+ "death.attack.blasttravelreborn.cannon", ModPartEnum.MESSAGE,
+ "%s was knocked out by a flying %s",
+ "%s被飞行的%s击倒了",
+ "%s被飛行的%s擊倒了"
+ ));
+ addLang(LangKeyValue.ofKey(
+ "dialog.blasttravelreborn.full_cannon", ModPartEnum.MESSAGE,
+ "Cannon is full!",
+ "大炮已装满!",
+ "大砲已裝滿!"
+ ));
+ addLang(LangKeyValue.ofKey(
+ "dialog.blasttravelreborn.no_gunpowder", ModPartEnum.MESSAGE,
+ "Cannon has no gunpowder!",
+ "大炮没有火药了!",
+ "大砲沒有火藥了!"
+ ));
+ addLang(LangKeyValue.ofKey(
+ "mount.blasttravelreborn.cannon.onboard", ModPartEnum.MESSAGE,
+ "Press %s to Exit, or %s to Fire",
+ "按%s离开,或按%s发射",
+ "按%s離開,或按%s發射"
+ ));
+ }
+
+ public void addLang(LangKeyValue keyValue) {
+ langKeyValues.add(keyValue);
+ }
+
+ public void clear() {
+ langKeyValues.clear();
+ }
+
+ @Contract(pure = true)
+ @Override
+ public @Unmodifiable List getValues() {
+ return List.copyOf(langKeyValues);
+ }
+
+}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/FireCannonPayload.java b/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/FireCannonPayload.java
index eaa6b31..3555f26 100644
--- a/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/FireCannonPayload.java
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/FireCannonPayload.java
@@ -2,7 +2,6 @@ package com.leisuretimedock.blasttravelreborn.network.toClient;
import com.leisuretimedock.blasttravelreborn.content.entity.CannonEntity;
import com.leisuretimedock.blasttravelreborn.util.PlayerEntityDuck;
-import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity;
@@ -40,45 +39,35 @@ public record FireCannonPayload(int cannonId, Optional launchedId, doub
}
public void handler(Supplier ctx) {
NetworkEvent.Context context = ctx.get();
- if(context.getNetworkManager().getPacketListener() instanceof ClientPacketListener clientPacketListener) {
+ if (context.getNetworkManager().getPacketListener() instanceof ClientPacketListener clientPacketListener) {
context.enqueueWork(() -> {
- if(hasPlayer()) {
- //noinspection OptionalGetWithoutIsPresent
+ if (hasPlayer()) {
if (clientPacketListener.getLevel().getEntity(launchedId.get()) instanceof Player launchedPlayer) {
+ // 记录发射前状态
if (!FMLEnvironment.production) {
System.out.println(" - [B]Client: Is Passenger = " + launchedPlayer.isPassenger());
- System.out.println(" - [B]Client: On Ground = " + launchedPlayer.onGround());
- System.out.println(" - [B]Client: noPhysics =" + launchedPlayer.noPhysics);
- System.out.println(" - [B]Client: Pose = " + launchedPlayer.getPose());
- System.out.println(" - [B]Client: riding entity = " + launchedPlayer.getVehicle());
- System.out.println(" - [B]Client: Bounding Box = " + launchedPlayer.getBoundingBox());
System.out.println(" - [B]Client: Delta Movement = " + launchedPlayer.getDeltaMovement());
}
+
+ // 立即停止乘坐并设置速度
if (launchedPlayer.isPassenger()) {
launchedPlayer.stopRiding();
}
- // 延迟一个 tick 执行飞行初始化逻辑
- Minecraft.getInstance().tell(() -> {
- // 此时已脱离炮台,设置速度
- launchedPlayer.getAbilities().flying = false;
- launchedPlayer.setPos(launchedPlayer.getX(), launchedPlayer.getY(), launchedPlayer.getZ());
- launchedPlayer.setDeltaMovement(velocityX, velocityY, velocityZ);
- ((PlayerEntityDuck) launchedPlayer).blasttravel$setCannonFlight(true);
+ // 直接设置速度,不要延迟
+ launchedPlayer.setDeltaMovement(velocityX, velocityY, velocityZ);
+ launchedPlayer.hurtMarked = true; // 强制同步运动
+ ((PlayerEntityDuck) launchedPlayer).blasttravel$setCannonFlight(true);
- // 输出变更后状态
- if (!FMLEnvironment.production) {
- System.out.println(" - [A]Client: Is Passenger = " + launchedPlayer.isPassenger());
- System.out.println(" - [A]Client: On Ground = " + launchedPlayer.onGround());
- System.out.println(" - [A]Client: noPhysics = " + launchedPlayer.noPhysics);
- System.out.println(" - [A]Client: Pose = " + launchedPlayer.getPose());
- System.out.println(" - [A]Client: riding entity = " + launchedPlayer.getVehicle());
- System.out.println(" - [A]Client: Bounding Box = " + launchedPlayer.getBoundingBox());
- System.out.println(" - [A]Client: Delta Movement = " + launchedPlayer.getDeltaMovement());
- }
- });
+ // 记录发射后状态
+ if (!FMLEnvironment.production) {
+ System.out.println(" - [A]Client: Is Passenger = " + launchedPlayer.isPassenger());
+ System.out.println(" - [A]Client: Delta Movement = " + launchedPlayer.getDeltaMovement());
+ }
}
}
+
+ // 处理炮实体效果
Entity entity = clientPacketListener.getLevel().getEntity(cannonId);
if (entity instanceof CannonEntity cannonEntity) {
cannonEntity.fireClient();
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/StopCannonFlightClientPayload.java b/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/StopCannonFlightClientPayload.java
index 29cae20..c247e69 100644
--- a/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/StopCannonFlightClientPayload.java
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/network/toClient/StopCannonFlightClientPayload.java
@@ -11,9 +11,6 @@ import net.minecraftforge.network.NetworkEvent;
import java.util.function.Supplier;
public record StopCannonFlightClientPayload(int flyingId) {
- public StopCannonFlightClientPayload(FriendlyByteBuf buf) {
- this(buf.readInt());
- }
public StopCannonFlightClientPayload(Player flying) {
this(flying.getId());
}
diff --git a/src/main/java/com/leisuretimedock/blasttravelreborn/network/toServer/RequestFirePayload.java b/src/main/java/com/leisuretimedock/blasttravelreborn/network/toServer/RequestFirePayload.java
index f323c94..c8ad10c 100644
--- a/src/main/java/com/leisuretimedock/blasttravelreborn/network/toServer/RequestFirePayload.java
+++ b/src/main/java/com/leisuretimedock/blasttravelreborn/network/toServer/RequestFirePayload.java
@@ -13,9 +13,7 @@ public record RequestFirePayload(int cannonId) {
public RequestFirePayload(CannonEntity cannonEntity) {
this(cannonEntity.getId());
}
- public RequestFirePayload(FriendlyByteBuf buf) {
- this(buf.readInt());
- }
+
public void write(FriendlyByteBuf buf) {
buf.writeInt(cannonId);
}
diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml
index 4a8030c..abcf091 100644
--- a/src/main/resources/META-INF/mods.toml
+++ b/src/main/resources/META-INF/mods.toml
@@ -62,7 +62,12 @@ versionRange = "${minecraft_version_range}"
ordering = "NONE"
side = "BOTH"
[[dependencies."${mod_id}"]]
-versionRange = "[0.2.1+1.20-fabrge,)"
+versionRange = "[0.2.3,)"
modId = "jsonem"
mandatory = false
side = "CLIENT"
+[[dependencies."${mod_id}"]]
+versionRange = "[0.0.17,)"
+modId = "lib39"
+mandatory = false
+side = "BOTH"
diff --git a/src/main/resources/assets/blasttravelreborn/lang/en_us.json b/src/main/resources/assets/blasttravelreborn/lang/en_us.json
deleted file mode 100644
index 60b5516..0000000
--- a/src/main/resources/assets/blasttravelreborn/lang/en_us.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "container.blasttravelreborn.cannon_container_menu": "Cannon",
- "item.blasttravelreborn.cannon": "Cannon",
- "entity.blasttravelreborn.cannon": "Cannon",
-
- "death.attack.blasttravelreborn.cannon": "%s was knocked out by a flying %s",
- "dialog.blasttravelreborn.full_cannon": "Cannon is full!",
- "dialog.blasttravelreborn.no_gunpowder": "Cannon has no gunpowder!",
- "mount.blasttravelreborn.cannon.onboard": "Press %s to Exit, or %s to Fire"
-}
diff --git a/src/main/resources/assets/blasttravelreborn/models/item/cannon.json b/src/main/resources/assets/blasttravelreborn/models/item/cannon.json
deleted file mode 100644
index c3484dc..0000000
--- a/src/main/resources/assets/blasttravelreborn/models/item/cannon.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "parent": "item/generated",
- "textures": {
- "layer0": "blasttravelreborn:item/cannon"
- }
-}
diff --git a/src/main/resources/assets/blasttravelreborn/particles/cannon_blast.json b/src/main/resources/assets/blasttravelreborn/particles/cannon_blast.json
deleted file mode 100644
index 638be25..0000000
--- a/src/main/resources/assets/blasttravelreborn/particles/cannon_blast.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "textures": [
- "blasttravelreborn:blast_smoke_0",
- "blasttravelreborn:blast_smoke_1",
- "blasttravelreborn:blast_smoke_2",
- "blasttravelreborn:blast_smoke_3",
- "blasttravelreborn:blast_smoke_4",
- "blasttravelreborn:blast_smoke_5",
- "blasttravelreborn:blast_smoke_6",
- "blasttravelreborn:blast_smoke_7",
- "blasttravelreborn:blast_smoke_8"
- ]
-}
diff --git a/src/main/resources/blasttravelreborn.mixins.json b/src/main/resources/blasttravelreborn.mixins.json
index 4abf844..4089201 100644
--- a/src/main/resources/blasttravelreborn.mixins.json
+++ b/src/main/resources/blasttravelreborn.mixins.json
@@ -6,10 +6,10 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"LivingEntityAccess",
- "PlayerEntityMixin",
- "PlayerEntityMixinClient"
+ "PlayerEntityMixin"
],
"client": [
+ "PlayerEntityMixinClient",
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerMixin",
"PlayerEntityModelMixin",
diff --git a/src/main/resources/data/blasttravelreborn/recipes/cannon.json b/src/main/resources/data/blasttravelreborn/recipes/cannon.json
deleted file mode 100644
index 4746a98..0000000
--- a/src/main/resources/data/blasttravelreborn/recipes/cannon.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:crafting_shaped",
- "pattern": [
- " A",
- "BA ",
- "CDE"
- ],
- "key": {
- "A": {"item": "minecraft:iron_block"},
- "B": {"item": "minecraft:string"},
- "C": {"tag": "minecraft:stone_crafting_materials"},
- "D": {"item": "minecraft:stick"},
- "E": {"tag": "minecraft:logs"}
- },
- "result": {
- "item": "blasttravelreborn:cannon",
- "count": 1
- }
-}