diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 4cd1fe88c..66d7109fd 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1 +1,2 @@
-patreon: srendi
+ko_fi: srendi
+github: SirEndii
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dde6f4283..425e8ab82 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+
+For now, just a prototype changelog so I don't need to remember/search everything I did
+### Added
+- NBT Hashes for filters and item/fluid properties. Lightweight version of the fingerprints, cc also uses nbt hashes for everything nbt related
+
## [1.19.2-0.7.37r] - 2024-10-06
### Added
diff --git a/README.md b/README.md
index 74d5d8a3e..78c94213d 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ will close pull requests related to translations.
[CurseForge]: https://www.curseforge.com/minecraft/mc-mods/advanced-peripherals
[Actions]: https://github.com/Seniorendi/AdvancedPeripherals/actions
[Crowdin]: https://crowdin.com/project/advanced-peripherals
-[Discord]: https://discord.com/invite/QuF3hWDtWC
+[Discord]: https://discord.intelligence-modding.de
[Banner]: https://www.bisecthosting.com/images/CF/Advanced_Peripherals/BH_AP_Header.png 'Advanced Peripherals'
[PeripheralsPlusOne]: https://github.com/rolandoislas/PeripheralsPlusOne
diff --git a/build.gradle b/build.gradle
index 4d6f7d61c..5cbf98fa4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,17 +3,17 @@ import net.darkhax.curseforgegradle.TaskPublishCurseForge
import java.text.SimpleDateFormat
plugins {
- id "maven-publish"
+ id 'checkstyle'
+ id 'com.github.breadmoirai.github-release' version '2.5.2'
+ id 'com.modrinth.minotaur' version '2.+'
+ id 'java'
+ id 'maven-publish'
id 'net.darkhax.curseforgegradle' version '1.1.16'
- id 'org.jetbrains.changelog' version '1.2.1'
- id "com.modrinth.minotaur" version "2.+"
- id "org.jetbrains.kotlin.jvm" version "1.6.10"
id 'net.minecraftforge.gradle' version '[6.0.18,6.2)'
+ id 'org.jetbrains.changelog' version '1.2.1'
+ id 'org.jetbrains.kotlin.jvm' version '1.6.10'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
id 'org.spongepowered.mixin' version '0.7.+'
- id "com.github.breadmoirai.github-release" version "2.5.2"
- id 'checkstyle'
- id 'java'
}
java {
@@ -201,20 +201,18 @@ repositories {
}
}
maven {
- name = "Modmaven Jei"
+ name = "Modmaven"
url = 'https://modmaven.dev/'
content {
- includeGroup("mezz.jei")
includeGroup("appeng")
includeGroup("mekanism")
+ includeGroup("mezz.jei")
}
}
maven {
name = "Create maven"
url = "https://maven.tterrag.com/"
content {
- includeGroup("com.simibubi.create")
- includeGroup("com.jozufozu.flywheel")
includeGroup("com.tterrag.registrate")
}
}
@@ -246,7 +244,17 @@ repositories {
maven {
url = "https://cursemaven.com"
content {
- includeGroup "curse.maven"
+ includeGroup("curse.maven")
+ }
+ }
+ maven {
+ url = "https://maven.valkyrienskies.org"
+ content {
+ includeGroup("org.valkyrienskies")
+ includeGroup("org.valkyrienskies.core")
+ includeGroup("com.github.LlamaLad7")
+ includeGroup("com.github.Rubydesic")
+ includeGroup("org.mapstruct")
}
}
}
@@ -313,23 +321,29 @@ dependencies {
compileOnly fg.deobf("com.ldtteam:multipiston:${multipiston_version}")
compileOnly fg.deobf("com.ldtteam:domum_ornamentum:${domumornamentum_version}:universal")
compileOnly fg.deobf("com.ldtteam:blockui:${blockui_version}")
- // IMPORTANT. This should be removed/uncommented when running `runData`
- runtimeOnly fg.deobf("com.ldtteam:minecolonies:${minecolonies_version}")
- runtimeOnly fg.deobf("com.ldtteam:structurize:${structurize_version}")
- runtimeOnly fg.deobf("com.ldtteam:multipiston:${multipiston_version}")
- runtimeOnly fg.deobf("com.ldtteam:domum_ornamentum:${domumornamentum_version}:universal")
- runtimeOnly fg.deobf("com.ldtteam:blockui:${blockui_version}")
-
- //Patchouli
+ // IMPORTANT. This should be removed/commented when running `runData`
+ // Automated now, tho if you are not executing runData directly it's no help
+ if (!project.gradle.startParameter.taskNames.contains("runData")) {
+ runtimeOnly fg.deobf("com.ldtteam:minecolonies:${minecolonies_version}")
+ runtimeOnly fg.deobf("com.ldtteam:structurize:${structurize_version}")
+ runtimeOnly fg.deobf("com.ldtteam:multipiston:${multipiston_version}")
+ runtimeOnly fg.deobf("com.ldtteam:domum_ornamentum:${domumornamentum_version}:universal")
+ runtimeOnly fg.deobf("com.ldtteam:blockui:${blockui_version}")
+ }
+
+ // Patchouli
compileOnly fg.deobf("vazkii.patchouli:Patchouli:${patchouli_version}")
runtimeOnly fg.deobf("vazkii.patchouli:Patchouli:${patchouli_version}")
// Create
- compileOnly fg.deobf("com.simibubi.create:create-${minecraft_version}:${create_version}:all")
- runtimeOnly fg.deobf("com.simibubi.create:create-${minecraft_version}:${create_version}:all")
+ compileOnly fg.deobf("curse.maven:create-328085:${create_version}")
+ runtimeOnly fg.deobf("curse.maven:create-328085:${create_version}")
- //Removed until fully ported
- //testImplementation fg.deobf("site.siredvin.ttoolkit:ttoolkit-${minecraft_version}:${ttoolkit_version}")
+ // DimStorage
+ compileOnly fg.deobf("curse.maven:dimstorage-353882:${dimstorage_version}")
+ compileOnly fg.deobf("curse.maven:edivadlib-638508:${edivadlib_version}")
+ // runtimeOnly fg.deobf("curse.maven:dimstorage-353882:${dimstorage_version}")
+ // runtimeOnly fg.deobf("curse.maven:edivadlib-638508:${edivadlib_version}")
//Powah
compileOnly fg.deobf("curse.maven:powah-633483:${powah_version}")
@@ -337,7 +351,7 @@ dependencies {
runtimeOnly fg.deobf("me.shedaniel.cloth:cloth-config-forge:8.2.88")
runtimeOnly fg.deobf("dev.architectury:architectury-forge:6.2.43")
- // Crash utilities. Used to debug the chunky turtle. Can be uncommented if not needed
+ // Crash utilities. Used to debug the chunky turtle. Can be commented if not needed
runtimeOnly fg.deobf("curse.maven:crash-utilities-371813:4406293")
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_version}"
@@ -352,9 +366,30 @@ dependencies {
// JEI
implementation fg.deobf("mezz.jei:jei-${jei_version}")
+ // Jade
+ implementation fg.deobf("curse.maven:jade-324717:${jade_version}")
+
// Create Crafts & Additions
compileOnly fg.deobf("curse.maven:createaddition-439890:5099757")
// runtimeOnly fg.deobf("curse.maven:createaddition-439890:5099757")
+
+ // Valkyrien Skies 2
+ compileOnly("org.joml:joml:1.10.4")
+ compileOnly("org.joml:joml-primitives:1.10.0")
+ // compileOnly fg.deobf("org.valkyrienskies:valkyrienskies-119-common:${vs2_version}")
+ compileOnly fg.deobf("org.valkyrienskies:valkyrienskies-119-forge:${vs2_version}") {
+ transitive = false
+ }
+ compileOnly "org.valkyrienskies.core:api:${vs_core_version}"
+ compileOnly "org.valkyrienskies.core:api-game:${vs_core_version}"
+ compileOnly "org.valkyrienskies.core:util:${vs_core_version}"
+ compileOnly "org.valkyrienskies.core:impl:${vs_core_version}"
+ runtimeOnly fg.deobf("org.valkyrienskies:valkyrienskies-119-forge:${vs2_version}") {
+ transitive = false
+ }
+ runtimeOnly fg.deobf("curse.maven:valkyrien-skies-258371:${valkyrien_skies_version}")
+ runtimeOnly fg.deobf("curse.maven:eureka-ships-654384:${eureka_ships_version}")
+ runtimeOnly fg.deobf("curse.maven:clockwork-807792:${clockwork_version}")
}
@@ -389,12 +424,12 @@ task setupServer(type: Copy) {
}
["Client", "Server"].forEach { name ->
- tasks.register("test$name", JavaExec.class).configure {
+ tasks.register("test${name}", JavaExec.class).configure {
it.group('In-game tests')
it.description("Runs tests on a temporary Minecraft instance.")
- it.dependsOn(setupServer, "prepareRunTest$name", "cleanTest$name", 'compileTestModJava')
+ it.dependsOn(setupServer, "prepareRunTest${name}", "cleanTest${name}", 'compileTestModJava')
- JavaExec exec = tasks.getByName("runTest$name")
+ JavaExec exec = tasks.getByName("runTest${name}")
exec.copyTo(it)
it.setClasspath(exec.getClasspath())
it.mainClass = exec.mainClass
@@ -433,6 +468,8 @@ jar {
jar.finalizedBy('reobfJar')
+compileKotlin.enabled = false
+
tasks.withType(Checkstyle) {
reports {
xml.required = false
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 7ca06cbc2..a379e1d45 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -37,7 +37,6 @@
-
diff --git a/gradle.properties b/gradle.properties
index 6b4647d35..b4e3848fa 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,5 +1,5 @@
-org.gradle.jvmargs=-Xmx4G
org.gradle.daemon=false
+org.gradle.jvmargs=-Xmx4G
org.gradle.logging.level=info
# Minecraft related
@@ -7,46 +7,61 @@ mod_id=advancedperipherals
# do not include mod_version/minecraft_version with equals sign anywhere else in the file (even in comments)
# also do not add space around the equal sign
# since we are using poor grep command to do automation :p
-mod_version=0.7.38r
+mod_version=0.8r
minecraft_version=1.19.2
mod_artifact_suffix=
-forge_version=43.3.8
+
+forge_version=43.5.0
loader_version=43
+
release_type=release
+
mappings_channel=parchment
-mappings_version=2022.11.27-1.19.2
-jb_annotations=21.0.1
+mappings_version=2022.11.20-1.19.2
# Test dependencies
-junit_version=5.7.2
hamcrest_version=2.2
+jb_annotations=21.0.1
+junit_version=5.7.2
kotlin_version=1.8.0
-kotlinx_coroutines_version=1.6.0-RC3
+kotlinx_coroutines_version=1.7.3
ttoolkit_version=0.1.3
# Mod dependencies
cc_version=1.101.3
-curios_version=1.19.2-5.1.4.1
-minecolonies_version=1.19.2-1.1.473-BETA
-appliedenergistics_version=12.9.5
-patchouli_version=1.19.2-77
-refinedstorage_version=1.11.6
+
+ae2additions_version=4646599
+ae2things_version=4367610
+appliedenergistics_version=12.9.12
+appliedmekanistics_version=4734608
botania_version=1.19.2-440-FORGE
-create_version=0.5.1.f-46
+clockwork_version=5171528
+#v0.5.1
+create_version=5797604
createca_version=5099757
+curios_version=1.19.2-5.1.4.1
+dimstorage_version=3927875
+eureka_ships_version=5321628
+kotlinforforge_version=3.12.0
mekanism_version=1.19.2-10.3.9.13
-ae2things_version=4367610
+minecolonies_version=1.19.2-1.1.473-BETA
+patchouli_version=1.19.2-77
powah_version=4183078
-ae2additions_version=4646599
-kotlinforforge_version=3.12.0
-appliedmekanistics_version=4734608
+refinedstorage_version=1.11.7
+valkyrien_skies_version=4994898
+vs2_version=2.1.2-beta.1+a04911c932
+vs_core_version=1.1.0+2a62e6a823
# Mod dependencies which are needed for other mods
# For minecolonies
-structurize_version=1.19.2-1.0.649-BETA
-multipiston_version=1.19.2-1.2.21-ALPHA
blockui_version=1.19.2-0.0.102-ALPHA
domumornamentum_version=1.19-1.0.141-BETA
+multipiston_version=1.19.2-1.2.21-ALPHA
+structurize_version=1.19.2-1.0.649-BETA
+
+# For DimStorage
+edivadlib_version=3927847
-# Mod dependencies for testing stuff(Only used in the dev environment)
-jei_version=1.19.2-forge:11.6.0.1016
\ No newline at end of file
+# Mod dependencies for testing stuff (Only used in the dev environment)
+jade_version=4914105
+jei_version=1.19.2-forge:11.6.0.1016
diff --git a/qodana.yaml b/qodana.yaml
index dfc5cbb26..f2df31528 100644
--- a/qodana.yaml
+++ b/qodana.yaml
@@ -16,7 +16,8 @@ exclude:
- src/test/resources/*
- src/testMod/resources/*
- src/server-files/resources/*
-include:
- name: CheckDependencyLicenses
+
+include:
- name: TrivialIf
- name: NullableProblems
\ No newline at end of file
diff --git a/src/generated/resources/.cache/03e4de26f1265135874f8cdcaebc09d9c08eb42b b/src/generated/resources/.cache/03e4de26f1265135874f8cdcaebc09d9c08eb42b
new file mode 100644
index 000000000..beca45b50
--- /dev/null
+++ b/src/generated/resources/.cache/03e4de26f1265135874f8cdcaebc09d9c08eb42b
@@ -0,0 +1,3 @@
+// 1.19.2 2025-01-20T07:59:27.474151 Tags for minecraft:item
+de4b4f45ec18b2b1f0db1c36882981042e20ee23 data/advancedperipherals/tags/items/p2p_attunements/cable_p2p_tunnel.json
+72eba3b11f69e16c87488f7c4ba7cfdad42c378e data/advancedperipherals/tags/items/smart_glasses.json
diff --git a/src/generated/resources/.cache/2db41954e490230d51b10affff25ee2ee27b8d5b b/src/generated/resources/.cache/2db41954e490230d51b10affff25ee2ee27b8d5b
index f319707e2..fe56a6ce0 100644
--- a/src/generated/resources/.cache/2db41954e490230d51b10affff25ee2ee27b8d5b
+++ b/src/generated/resources/.cache/2db41954e490230d51b10affff25ee2ee27b8d5b
@@ -1,2 +1,2 @@
-// 1.19.2 2023-07-19T14:31:39.6951106 AP POI Type Tags
+// 1.19.2 2024-05-28T14:53:16.655175 AP POI Type Tags
d3d6b837660a4e213f287ad9d11e12368b90cd8e data/minecraft/tags/point_of_interest_type/acquirable_job_site.json
diff --git a/src/generated/resources/.cache/5a761efb7472ef97566e41e81451930a004134bf b/src/generated/resources/.cache/5a761efb7472ef97566e41e81451930a004134bf
index cb8219ecf..bc70b7af4 100644
--- a/src/generated/resources/.cache/5a761efb7472ef97566e41e81451930a004134bf
+++ b/src/generated/resources/.cache/5a761efb7472ef97566e41e81451930a004134bf
@@ -1,4 +1,4 @@
-// 1.19.2 2023-07-19T14:31:39.6751301 Turtle Upgrades
+// 1.19.2 2024-05-28T14:53:16.655476 Turtle Upgrades
b8f19ae0fb5bb898facc08e3787e0f96c8211881 data/advancedperipherals/computercraft/turtle_upgrades/chatty_turtle.json
fe98c60e7d61139aacf2d0872873e610aac8a37b data/advancedperipherals/computercraft/turtle_upgrades/chunky_turtle.json
ae619da638ad89d7302d832d6c09e2c87401c539 data/advancedperipherals/computercraft/turtle_upgrades/compass_turtle.json
@@ -10,4 +10,5 @@ c9b2df2d4fed11f60a8e6f8da77b2fa53dd13572 data/advancedperipherals/computercraft/
42fc2b9a2601ef44d617cb18302c2c4fff31d282 data/advancedperipherals/computercraft/turtle_upgrades/overpowered_husbandry_automata.json
fa7743922ef6b4dd3e633f2857e4047d533f13b5 data/advancedperipherals/computercraft/turtle_upgrades/overpowered_weak_automata.json
4054c59ceb099f17c4555fd5f36b2f8b4109f624 data/advancedperipherals/computercraft/turtle_upgrades/player_turtle.json
+fa6624d0dab03bd26c2cccecad51848d5071ecd3 data/advancedperipherals/computercraft/turtle_upgrades/saddle_turtle.json
c8059a2717cfac5b02898658c4d2d52fbd5710d4 data/advancedperipherals/computercraft/turtle_upgrades/weak_automata.json
diff --git a/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2 b/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2
index b767c20d4..ac730fb60 100644
--- a/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2
+++ b/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2
@@ -1,14 +1,17 @@
-// 1.19.2 2024-01-15T20:01:57.516745 LootTables
-d865e8ac35302c486faf5c7122569c554186186d data/advancedperipherals/loot_tables/blocks/block_reader.json
-a6f896cc3dbd8da12737825ec71e32970f54025c data/advancedperipherals/loot_tables/blocks/chat_box.json
-f50f506ae1987537f76be4c05a81689b25798f91 data/advancedperipherals/loot_tables/blocks/colony_integrator.json
-1d1b858d09538dc66bab2c33a2f9c58361a9c472 data/advancedperipherals/loot_tables/blocks/energy_detector.json
-317004b1358ef9bf83957d2d6796529a226161c7 data/advancedperipherals/loot_tables/blocks/environment_detector.json
-d5a3964f518b138cbd7305c819a36af3d9340e4a data/advancedperipherals/loot_tables/blocks/geo_scanner.json
-8aa1deea908fd02f049e047c8ca16679bbef68a2 data/advancedperipherals/loot_tables/blocks/inventory_manager.json
-9a2898a63e2e0c087ce8eba211c63d1c8b9fd4aa data/advancedperipherals/loot_tables/blocks/me_bridge.json
-973770040bacb61482adb9739fd1d977f16c107f data/advancedperipherals/loot_tables/blocks/nbt_storage.json
-b4b80e8c9d62b53d9252cdfc5918c077d3a01f6e data/advancedperipherals/loot_tables/blocks/peripheral_casing.json
-58b6adbea5d4ae43ed9af0b627df2b8a4907acde data/advancedperipherals/loot_tables/blocks/player_detector.json
-a58aebcc52684302968e7af4f50a12aff93aaf2d data/advancedperipherals/loot_tables/blocks/redstone_integrator.json
-0ef1678f88b8fcb744bfd95261f66745340be8f4 data/advancedperipherals/loot_tables/blocks/rs_bridge.json
+// 1.19.2 2025-01-16T15:46:41.860623 LootTables
+618b63c020ab64890c8a2d2506dd61cd30259a44 data/advancedperipherals/loot_tables/blocks/block_reader.json
+0923665563d05307a7fa7d711a2d7a994a31eb6e data/advancedperipherals/loot_tables/blocks/chat_box.json
+bf2a80256cfba0bd8c0283d493882e5816882f1f data/advancedperipherals/loot_tables/blocks/colony_integrator.json
+cff4b81aa381bc0d1172b0a4c8bb35c1b954a018 data/advancedperipherals/loot_tables/blocks/distance_detector.json
+1c5dbe1a8e07e040a3c2893a002cd535ee41dc20 data/advancedperipherals/loot_tables/blocks/energy_detector.json
+8cc03eca1d191f725bc558836f26a85a466cb127 data/advancedperipherals/loot_tables/blocks/environment_detector.json
+12589e7642b383029457d97a64637494ea8507a3 data/advancedperipherals/loot_tables/blocks/fluid_detector.json
+421a3ece56485bd46374844639bfd606ce4665ec data/advancedperipherals/loot_tables/blocks/gas_detector.json
+a2ae352dce564b878daecf47026f268dd432fbcf data/advancedperipherals/loot_tables/blocks/geo_scanner.json
+807d449d02c0af701f84d3e806ebac20d3a1f91c data/advancedperipherals/loot_tables/blocks/inventory_manager.json
+bb9b442dfad1d5f31397585c8394c85243fa169a data/advancedperipherals/loot_tables/blocks/me_bridge.json
+52b1fe2e265be456ebf48d7e0d9ebcc8c994176f data/advancedperipherals/loot_tables/blocks/nbt_storage.json
+2651e6053857a31f5bccc360969924848a197ad5 data/advancedperipherals/loot_tables/blocks/peripheral_casing.json
+6b5058b6bc49689bf2b858b89f3981a4bb681750 data/advancedperipherals/loot_tables/blocks/player_detector.json
+6af6542c7b64aa22dbfcdb01299daf4911827a49 data/advancedperipherals/loot_tables/blocks/redstone_integrator.json
+b221c6a82da0875264a112b54f847ac6a1f36797 data/advancedperipherals/loot_tables/blocks/rs_bridge.json
diff --git a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
index 949aa05ae..c4a79999b 100644
--- a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
+++ b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
@@ -1,4 +1,5 @@
-// 1.19.2 2024-01-15T20:01:57.5157458 Recipes
+// 1.19.2 2024-05-28T14:53:16.657381 Recipes
+045608027e4a5ea2d7dee7f402346b8e69f21675 data/advancedperipherals/advancements/recipes/advancedperipheralstab/armor/smart_glasses_netherite.json
db2dada2fdf42ca1bbf47f1eb075d1f9de89dfa8 data/advancedperipherals/advancements/recipes/advancedperipheralstab/block_reader.json
77c55e8500be4a344ca563a8bf7642257cdc7b8b data/advancedperipherals/advancements/recipes/advancedperipheralstab/chat_box.json
96208b06b0c3c125762cd517506a5ffb6b1d55ac data/advancedperipherals/advancements/recipes/advancedperipheralstab/chunk_controller.json
@@ -16,6 +17,7 @@ d27c1267208fd9036c5c45f7f6cbd4f6f67b3845 data/advancedperipherals/advancements/r
d8870644bb7d48c5ae33dcea2afbcfa106729d7b data/advancedperipherals/advancements/recipes/advancedperipheralstab/player_detector.json
7acff70533792bd089a655f8f24cdea6995aac0c data/advancedperipherals/advancements/recipes/advancedperipheralstab/redstone_integrator.json
fc0c3d99bec43318802f357083c7d98fde92567f data/advancedperipherals/advancements/recipes/advancedperipheralstab/weak_automata_core.json
+66999fea36aa4113567753f104630f6490dda6ba data/advancedperipherals/recipes/armor/smart_glasses_netherite.json
b10b5cbcc668438001744d5b90d9838ab4d293cb data/advancedperipherals/recipes/block_reader.json
3c9618832fe0ac32cac0f04fbc5afad225418239 data/advancedperipherals/recipes/chat_box.json
a78adfcca4c7579b143aac5648a7eca9085c0dba data/advancedperipherals/recipes/chunk_controller.json
@@ -25,8 +27,8 @@ f1f468c732f8c802c27776d3fd7aac432bcac8e3 data/advancedperipherals/recipes/comput
55c257e4e8548d1453a7ab96c547d64c22b3e1d6 data/advancedperipherals/recipes/environment_detector.json
2ddf64c122165bcd3a277db8a1c7e96b4d510c67 data/advancedperipherals/recipes/geo_scanner.json
ebe70aa9fe80c5b962c13aa1fbadc32269ba81b9 data/advancedperipherals/recipes/inventory_manager.json
-809bc6929cf5eab72648e8f1fb565b58749fec12 data/advancedperipherals/recipes/memory_card.json
82895838af6c6aea0c60e3a3fbf71073ab684167 data/advancedperipherals/recipes/me_bridge.json
+809bc6929cf5eab72648e8f1fb565b58749fec12 data/advancedperipherals/recipes/memory_card.json
8a73c4eb66e7a1cdc8e51d33466cf5a30da9270e data/advancedperipherals/recipes/nbt_storage.json
360432f30d61291066aa8c54692629f7a92e178d data/advancedperipherals/recipes/overpowered_end_automata_core.json
4ea6e90d13a61d90ad245539d20020ff9cb843e1 data/advancedperipherals/recipes/overpowered_husbandry_automata_core.json
diff --git a/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c b/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c
index b9e492ca6..5821f3f8a 100644
--- a/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c
+++ b/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c
@@ -1,6 +1,7 @@
-// 1.19.2 2023-07-19T14:31:39.6815264 Pocket Computer Upgrades
+// 1.19.2 2025-01-25T19:46:21.23515 Pocket Computer Upgrades
b672635324c0df354e587efc81d0b19a581eae2f data/advancedperipherals/computercraft/pocket_upgrades/chatty_pocket.json
30b8f663613c7ce77048fd69631afcc11a682276 data/advancedperipherals/computercraft/pocket_upgrades/colony_pocket.json
+661dc77bd0442bfb2a5ed80cff271071817bb22d data/advancedperipherals/computercraft/pocket_upgrades/distance_pocket.json
d4647159c2f2693a9c5e8d12bf740635751d29a8 data/advancedperipherals/computercraft/pocket_upgrades/environment_pocket.json
8216a0a7d8ebe3ae738c8fc3626df25eb0a2e07a data/advancedperipherals/computercraft/pocket_upgrades/geoscanner_pocket.json
a38aa83593f7ad0ace98e01bb3b5f06f272ef734 data/advancedperipherals/computercraft/pocket_upgrades/player_pocket.json
diff --git a/src/generated/resources/.cache/b8526e444ae7356037f3a813274f6835d1f3dd16 b/src/generated/resources/.cache/b8526e444ae7356037f3a813274f6835d1f3dd16
index 54d53cf45..01ccc33ab 100644
--- a/src/generated/resources/.cache/b8526e444ae7356037f3a813274f6835d1f3dd16
+++ b/src/generated/resources/.cache/b8526e444ae7356037f3a813274f6835d1f3dd16
@@ -1,9 +1,12 @@
-// 1.19.2 2024-01-15T20:01:57.5177444 Block States: advancedperipherals
+// 1.19.2 2024-05-28T14:53:16.658228 Block States: advancedperipherals
5e28ce1be9a6996d982641e5df1fa7162090b8cc assets/advancedperipherals/blockstates/block_reader.json
f42bdde60f84fdb312f7cf3b2be461d9c11ebdc8 assets/advancedperipherals/blockstates/chat_box.json
1227aa092fcf1327547ace6ccc9db230e45891b0 assets/advancedperipherals/blockstates/colony_integrator.json
+83144ea6122b3abe70777458ac913b6f217c27cc assets/advancedperipherals/blockstates/distance_detector.json
67420f28031606ca03db9a044141bb22b0fa78b7 assets/advancedperipherals/blockstates/energy_detector.json
340b5baa62e5e6a2c35a05b4411be5937ac2bbb8 assets/advancedperipherals/blockstates/environment_detector.json
+f40e0ac205d0473908fd957d035dd747dc64e26a assets/advancedperipherals/blockstates/fluid_detector.json
+bbefa012be11f3735da4d9deb1f0d2402c761cd8 assets/advancedperipherals/blockstates/gas_detector.json
57c00996bcf1d783116a9210842f246612089555 assets/advancedperipherals/blockstates/geo_scanner.json
d1fe6188b0b0ce8779cb9795a746177858cbaa41 assets/advancedperipherals/blockstates/inventory_manager.json
7f82e776900e3d120cb1a06ec975731905dcaff7 assets/advancedperipherals/blockstates/me_bridge.json
@@ -13,15 +16,18 @@ ff12c7217911184266589813a2c8f9b0d46cfd65 assets/advancedperipherals/blockstates/
726cf2599b0c765bcfacda88a1943be74f985877 assets/advancedperipherals/blockstates/redstone_integrator.json
6b176e8fdb048f7b6678bfbc1c4baf2bcfa67a1f assets/advancedperipherals/blockstates/rs_bridge.json
544ff1ecb58622350b58940036b4b1908e1146da assets/advancedperipherals/models/block/block_reader.json
-b28693973b6bbbb61e0c1ffc59e8ca98d8bb7e97 assets/advancedperipherals/models/block/chat_box.json
-8361da86b709e26f17374dfd46637940894a2212 assets/advancedperipherals/models/block/colony_integrator.json
-96ef564804fdc2b5184462747935f52baa35c651 assets/advancedperipherals/models/block/energy_detector.json
-41556ddf5c5e67def6efd8e2e0645718d950af25 assets/advancedperipherals/models/block/environment_detector.json
-ba233597a497c1032d884fc3058e27b9d965725e assets/advancedperipherals/models/block/geo_scanner.json
-fb58e0b712f1f6ce1b2ea4dcfa0747905cf6ed95 assets/advancedperipherals/models/block/inventory_manager.json
-75b59d2b73a96a27e3d4a1ed3b9a928b7dff102e assets/advancedperipherals/models/block/me_bridge.json
-a647b86b8a7862af738136c9375a5d27d3b08860 assets/advancedperipherals/models/block/nbt_storage.json
-36b6ac01be085492aa6298eeb89e6ecaa3cb6f82 assets/advancedperipherals/models/block/peripheral_casing.json
-40369caaaf2f593d786a9c64284647fed8ae3a47 assets/advancedperipherals/models/block/player_detector.json
-bed2ba2ba497ccde06c99712483fe220c277b4be assets/advancedperipherals/models/block/redstone_integrator.json
-019c10d5062b5e7ae3e641527b9badab7a50878d assets/advancedperipherals/models/block/rs_bridge.json
+fbaa69d6c98549d3f2d4a1c7bebd9b6b80d56621 assets/advancedperipherals/models/block/chat_box.json
+68f9d37bd85649937150ba0bb8f4496bb2ef218d assets/advancedperipherals/models/block/colony_integrator.json
+80b30400b6ebac490a1abaad965f33c1b62c19e9 assets/advancedperipherals/models/block/distance_detector.json
+b4c6645fda79d960e9201e2a60eb1c8063a07d18 assets/advancedperipherals/models/block/energy_detector.json
+eca505b2bd8db5f1d13f1e28093db329b70af978 assets/advancedperipherals/models/block/environment_detector.json
+f6ab51bcfc829c7db490f691e8eb491e5e7028f3 assets/advancedperipherals/models/block/fluid_detector.json
+35bbc0e2edf74f6e27029cc23465e203d459f234 assets/advancedperipherals/models/block/gas_detector.json
+46ebb4c9a31e224bac13ad20334469c0b55d285c assets/advancedperipherals/models/block/geo_scanner.json
+2142aaccd0a0bc56aaa2091128466d2c9a733aab assets/advancedperipherals/models/block/inventory_manager.json
+f089dda9e6ac12d638707fd24d099ccd56a54ccc assets/advancedperipherals/models/block/me_bridge.json
+65afcae128339b244508dc66620c6c00729fce8e assets/advancedperipherals/models/block/nbt_storage.json
+f6cb0dda1ce8217563903d2dfaf5ef0297939750 assets/advancedperipherals/models/block/peripheral_casing.json
+5a1679b4dcc8da2d8c67674216d242456bb51366 assets/advancedperipherals/models/block/player_detector.json
+d08b8946e1eb01cc9c8af4fa297b582614d1034b assets/advancedperipherals/models/block/redstone_integrator.json
+41cf7d22016a995aeda9df9d9cbf1d4069b99f9e assets/advancedperipherals/models/block/rs_bridge.json
diff --git a/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8
index 42f19ff63..c804ec644 100644
--- a/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8
+++ b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8
@@ -1,2 +1,2 @@
-// 1.19.2 2024-01-15T20:01:57.5147447 Languages: en_us
-d2006c7f1d9c5f1f768b50a3c445dc8b566bf9dd assets/advancedperipherals/lang/en_us.json
+// 1.19.2 2025-01-25T19:46:21.234203 Languages: en_us
+e858500d72e9279f0fe0e8b2d03f94469c8d1f65 assets/advancedperipherals/lang/en_us.json
diff --git a/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218 b/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218
index 042110e02..872307de5 100644
--- a/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218
+++ b/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218
@@ -1,4 +1,4 @@
-// 1.19.2 2024-01-15T20:01:57.5177444 Block tags
+// 1.19.2 2025-01-16T15:46:41.859383 Block tags
e1f71dcb4f9e7e36e29b0ad09d6520dc3adfa4a6 data/forge/tags/blocks/needs_wood_tool.json
-dcbdeb0bc268b24e9970e4bada12e8e8da97b8d5 data/minecraft/tags/blocks/mineable/pickaxe.json
-1017ee5cf2a99941ddfc00c2c5e07a19644470b6 data/minecraft/tags/blocks/needs_iron_tool.json
+03322cd493601129eaad6ba7c2a6d808023dfac1 data/minecraft/tags/blocks/mineable/pickaxe.json
+277fe59db076a3eab3c97080531ad345f8ca5f3d data/minecraft/tags/blocks/needs_iron_tool.json
diff --git a/src/generated/resources/assets/advancedperipherals/blockstates/distance_detector.json b/src/generated/resources/assets/advancedperipherals/blockstates/distance_detector.json
new file mode 100644
index 000000000..4201dd6d7
--- /dev/null
+++ b/src/generated/resources/assets/advancedperipherals/blockstates/distance_detector.json
@@ -0,0 +1,57 @@
+{
+ "variants": {
+ "orientation=down_east": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 90,
+ "y": 90
+ },
+ "orientation=down_north": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 90
+ },
+ "orientation=down_south": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 90,
+ "y": 180
+ },
+ "orientation=down_west": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 90,
+ "y": 270
+ },
+ "orientation=east_up": {
+ "model": "advancedperipherals:block/distance_detector",
+ "y": 90
+ },
+ "orientation=north_up": {
+ "model": "advancedperipherals:block/distance_detector"
+ },
+ "orientation=south_up": {
+ "model": "advancedperipherals:block/distance_detector",
+ "y": 180
+ },
+ "orientation=up_east": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 270,
+ "y": 90
+ },
+ "orientation=up_north": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 270
+ },
+ "orientation=up_south": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 270,
+ "y": 180
+ },
+ "orientation=up_west": {
+ "model": "advancedperipherals:block/distance_detector",
+ "x": 270,
+ "y": 270
+ },
+ "orientation=west_up": {
+ "model": "advancedperipherals:block/distance_detector",
+ "y": 270
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/blockstates/fluid_detector.json b/src/generated/resources/assets/advancedperipherals/blockstates/fluid_detector.json
new file mode 100644
index 000000000..6641af423
--- /dev/null
+++ b/src/generated/resources/assets/advancedperipherals/blockstates/fluid_detector.json
@@ -0,0 +1,57 @@
+{
+ "variants": {
+ "orientation=down_east": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 90,
+ "y": 90
+ },
+ "orientation=down_north": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 90
+ },
+ "orientation=down_south": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 90,
+ "y": 180
+ },
+ "orientation=down_west": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 90,
+ "y": 270
+ },
+ "orientation=east_up": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "y": 90
+ },
+ "orientation=north_up": {
+ "model": "advancedperipherals:block/fluid_detector"
+ },
+ "orientation=south_up": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "y": 180
+ },
+ "orientation=up_east": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 270,
+ "y": 90
+ },
+ "orientation=up_north": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 270
+ },
+ "orientation=up_south": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 270,
+ "y": 180
+ },
+ "orientation=up_west": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "x": 270,
+ "y": 270
+ },
+ "orientation=west_up": {
+ "model": "advancedperipherals:block/fluid_detector",
+ "y": 270
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/blockstates/gas_detector.json b/src/generated/resources/assets/advancedperipherals/blockstates/gas_detector.json
new file mode 100644
index 000000000..aee9fc55d
--- /dev/null
+++ b/src/generated/resources/assets/advancedperipherals/blockstates/gas_detector.json
@@ -0,0 +1,57 @@
+{
+ "variants": {
+ "orientation=down_east": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 90,
+ "y": 90
+ },
+ "orientation=down_north": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 90
+ },
+ "orientation=down_south": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 90,
+ "y": 180
+ },
+ "orientation=down_west": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 90,
+ "y": 270
+ },
+ "orientation=east_up": {
+ "model": "advancedperipherals:block/gas_detector",
+ "y": 90
+ },
+ "orientation=north_up": {
+ "model": "advancedperipherals:block/gas_detector"
+ },
+ "orientation=south_up": {
+ "model": "advancedperipherals:block/gas_detector",
+ "y": 180
+ },
+ "orientation=up_east": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 270,
+ "y": 90
+ },
+ "orientation=up_north": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 270
+ },
+ "orientation=up_south": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 270,
+ "y": 180
+ },
+ "orientation=up_west": {
+ "model": "advancedperipherals:block/gas_detector",
+ "x": 270,
+ "y": 270
+ },
+ "orientation=west_up": {
+ "model": "advancedperipherals:block/gas_detector",
+ "y": 270
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/lang/en_us.json b/src/generated/resources/assets/advancedperipherals/lang/en_us.json
index ed66cc743..3da1acb77 100644
--- a/src/generated/resources/assets/advancedperipherals/lang/en_us.json
+++ b/src/generated/resources/assets/advancedperipherals/lang/en_us.json
@@ -2,25 +2,28 @@
"advancedperipherals.name": "Advanced Peripherals",
"advancements.advancedperipherals.base_toolkit": "Gentleman's set!",
"advancements.advancedperipherals.base_toolkit.description": "Collect a redstone integrator, inventory manager and energy detector. How did you even play without this?",
- "advancements.advancedperipherals.end_automata_core": "End automata core",
+ "advancements.advancedperipherals.end_automata_core": "End Automata Core",
"advancements.advancedperipherals.end_automata_core.description": "If you can code gps-free position location with this, you're a powerful human being",
- "advancements.advancedperipherals.husbandry_automata_core": "Husbandry automata core",
+ "advancements.advancedperipherals.husbandry_automata_core": "Husbandry Automata Core",
"advancements.advancedperipherals.husbandry_automata_core.description": "Is this core gluten-free?",
"advancements.advancedperipherals.nbt_toolkit": "No secrets",
"advancements.advancedperipherals.nbt_toolkit.description": "Collect a NBT storage and block reader. Now, all the world's secrets are open to you!",
- "advancements.advancedperipherals.overpowered_automata_core": "Overpowered automata core",
+ "advancements.advancedperipherals.overpowered_automata_core": "Overpowered Automata Core",
"advancements.advancedperipherals.overpowered_automata_core.description": "Can you handle so much power?",
"advancements.advancedperipherals.root": "Advanced Peripherals",
"advancements.advancedperipherals.root.description": "Every journey starts with the first block",
"advancements.advancedperipherals.sense_toolkit": "The truth can't hide forever",
"advancements.advancedperipherals.sense_toolkit.description": "Collect a geo scanner and environmental detector. There are no limits for observability!",
- "advancements.advancedperipherals.weak_automata_core": "First automata core",
+ "advancements.advancedperipherals.weak_automata_core": "First Automata Core",
"advancements.advancedperipherals.weak_automata_core.description": "Does the afterlife exist in minecraft?",
"block.advancedperipherals.block_reader": "Block Reader",
"block.advancedperipherals.chat_box": "Chat Box",
"block.advancedperipherals.colony_integrator": "Colony Integrator",
+ "block.advancedperipherals.distance_detector": "Distance Detector",
"block.advancedperipherals.energy_detector": "Energy Detector",
"block.advancedperipherals.environment_detector": "Environment Detector",
+ "block.advancedperipherals.fluid_detector": "Fluid Detector",
+ "block.advancedperipherals.gas_detector": "Gas Detector",
"block.advancedperipherals.geo_scanner": "Geo Scanner",
"block.advancedperipherals.inventory_manager": "Inventory Manager",
"block.advancedperipherals.me_bridge": "ME Bridge",
@@ -29,21 +32,29 @@
"block.advancedperipherals.player_detector": "Player Detector",
"block.advancedperipherals.redstone_integrator": "Redstone Integrator",
"block.advancedperipherals.rs_bridge": "RS Bridge",
+ "curios.identifier.glasses": "Glasses",
"entity.minecraft.villager.advancedperipherals.computer_scientist": "Computer Scientist",
+ "item.advancedperipherals.cable_p2p_tunnel": "Cable P2P Tunnel",
"item.advancedperipherals.chunk_controller": "Chunk Controller",
"item.advancedperipherals.computer_tool": "Computer Tool",
"item.advancedperipherals.end_automata_core": "End Automata Core",
+ "item.advancedperipherals.hotkey_module": "Hotkey Module",
"item.advancedperipherals.husbandry_automata_core": "Husbandry Automata Core",
"item.advancedperipherals.memory_card": "Memory Card",
+ "item.advancedperipherals.nightvision_module": "Night Vision Module",
+ "item.advancedperipherals.overlay_module": "Overlay Module",
"item.advancedperipherals.overpowered_end_automata_core": "Overpowered End Automata Core",
"item.advancedperipherals.overpowered_husbandry_automata_core": "Overpowered Husbandry Automata Core",
"item.advancedperipherals.overpowered_weak_automata_core": "Overpowered Weak Automata Core",
+ "item.advancedperipherals.smart_glasses": "Smart Glasses",
+ "item.advancedperipherals.smart_glasses_interface": "Smart Glasses Interface",
+ "item.advancedperipherals.smart_glasses_netherite": "Netherite reinforced Smart Glasses",
"item.advancedperipherals.tooltip.block_reader": "&7Reads nbt data of blocks to interact with blocks which do not have computer support.",
"item.advancedperipherals.tooltip.chat_box": "&7Interacts with the ingame chat, can read and write messages.",
"item.advancedperipherals.tooltip.chunk_controller": "&7A crafting ingredient for the Chunky Turtle.",
"item.advancedperipherals.tooltip.colony_integrator": "&7Interacts with Minecolonies to read data about your colony and citizens.",
"item.advancedperipherals.tooltip.computer_tool": "&7This tool was made to tune our blocks. But for now, it's just a blue useless wrench.",
- "item.advancedperipherals.tooltip.disabled": "&cThis item is disabled in the config, so you can craft it, but it'll not have any functionality.",
+ "item.advancedperipherals.tooltip.disabled": "&cThis item is disabled in config, so you can craft it, but it'll not have any functionality.",
"item.advancedperipherals.tooltip.end_automata_core": "&7Upgrade for turtles, that allows basic interaction with the world and teleportation in one dimension.",
"item.advancedperipherals.tooltip.energy_detector": "&7Can detect energy flow and acts as a resistor.",
"item.advancedperipherals.tooltip.environment_detector": "&7This peripheral interacts with the minecraft world.",
@@ -57,7 +68,7 @@
"item.advancedperipherals.tooltip.overpowered_end_automata_core": "&7Improved version of the end automata core, that provides some overpowered uses! Be careful, the upgrade is very fragile.",
"item.advancedperipherals.tooltip.overpowered_husbandry_automata_core": "&7Improved version of the husbandry automata core, that provides some overpowered uses! Be careful, the upgrade is very fragile.",
"item.advancedperipherals.tooltip.overpowered_weak_automata_core": "&7Improved version of the weak automata core, that provides some overpowered uses! Be careful, the upgrade is very fragile.",
- "item.advancedperipherals.tooltip.peripheral_casing": "&7An empty hull without the love it deserves. Used as a crafting ingredient",
+ "item.advancedperipherals.tooltip.peripheral_casing": "&7An empty hull without the love it deserves. Used as crafting ingredient",
"item.advancedperipherals.tooltip.player_detector": "&7This peripheral can be used to interact with players, but don't be a stalker.",
"item.advancedperipherals.tooltip.redstone_integrator": "&7This block is able to interact with redstone. Works exactly like the redstone api of an computer.",
"item.advancedperipherals.tooltip.rs_bridge": "&7The RS Bridge interacts with Refined Storage to manage your items.",
@@ -69,22 +80,27 @@
"keybind.advancedperipherals.description": "Show Description",
"pocket.advancedperipherals.chatty_pocket": "Chatty",
"pocket.advancedperipherals.colony_pocket": "Colony",
+ "pocket.advancedperipherals.distance_pocket": "Distance Detector",
"pocket.advancedperipherals.environment_pocket": "Environment",
"pocket.advancedperipherals.geoscanner_pocket": "Geo",
"pocket.advancedperipherals.player_pocket": "Player Detector",
"text.advancedperipherals.added_player": "Added you to the memory card",
- "text.advancedperipherals.automata_core_feed_by_player": "You're trying to feed an entity to a soul, but your own body refuses to do this. Maybe something more mechanical can do this?",
+ "text.advancedperipherals.automata_core.feed_by_player": "You're trying to feed an entity to a soul, but your own body refuses to do this. Maybe something more mechanical can do this?",
"text.advancedperipherals.removed_player": "Cleared the memory card",
+ "text.advancedperipherals.saddle_turtle.dismount_hint": "Controlling %1$s. Press %2$s and %3$s to dismount.",
+ "text.advancedperipherals.smart_glasses.modules": "Modules",
+ "text.advancedperipherals.smart_glasses.peripherals": "Peripherals",
"turtle.advancedperipherals.chatty_turtle": "Chatty",
"turtle.advancedperipherals.chunky_turtle": "Chunky",
"turtle.advancedperipherals.compass_turtle": "Compass",
- "turtle.advancedperipherals.end_automata": "End automata",
+ "turtle.advancedperipherals.end_automata": "End Automata",
"turtle.advancedperipherals.environment_turtle": "Environment",
"turtle.advancedperipherals.geoscanner_turtle": "Geo",
- "turtle.advancedperipherals.husbandry_automata": "Husbandry automata",
- "turtle.advancedperipherals.overpowered_end_automata": "Overpowered end automata",
- "turtle.advancedperipherals.overpowered_husbandry_automata": "Overpowered husbandry automata",
- "turtle.advancedperipherals.overpowered_weak_automata": "Overpowered weak automata",
+ "turtle.advancedperipherals.husbandry_automata": "Husbandry Automata",
+ "turtle.advancedperipherals.overpowered_end_automata": "Overpowered End Automata",
+ "turtle.advancedperipherals.overpowered_husbandry_automata": "Overpowered Husbandry Automata",
+ "turtle.advancedperipherals.overpowered_weak_automata": "Overpowered Weak Automata",
"turtle.advancedperipherals.player_turtle": "Player Detector",
- "turtle.advancedperipherals.weak_automata": "Weak automata"
+ "turtle.advancedperipherals.saddle_turtle": "Saddle",
+ "turtle.advancedperipherals.weak_automata": "Weak Automata"
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/chat_box.json b/src/generated/resources/assets/advancedperipherals/models/block/chat_box.json
index 487d0eb4e..ba89671f2 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/chat_box.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/chat_box.json
@@ -2,7 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/chat_box",
+ "down": "advancedperipherals:block/bottom",
"north": "advancedperipherals:block/chat_box_front",
- "particle": "advancedperipherals:block/chat_box_front"
+ "particle": "advancedperipherals:block/chat_box_front",
+ "up": "advancedperipherals:block/chat_box_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/colony_integrator.json b/src/generated/resources/assets/advancedperipherals/models/block/colony_integrator.json
index 884006124..7f52aebb0 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/colony_integrator.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/colony_integrator.json
@@ -2,8 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/colony_integrator",
- "down": "minecraft:block/oak_log_top",
- "particle": "advancedperipherals:block/colony_integrator",
- "up": "minecraft:block/oak_log_top"
+ "down": "advancedperipherals:block/bottom",
+ "north": "advancedperipherals:block/colony_integrator_front",
+ "particle": "advancedperipherals:block/colony_integrator_front",
+ "up": "advancedperipherals:block/colony_integrator_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/distance_detector.json b/src/generated/resources/assets/advancedperipherals/models/block/distance_detector.json
new file mode 100644
index 000000000..0cee7c371
--- /dev/null
+++ b/src/generated/resources/assets/advancedperipherals/models/block/distance_detector.json
@@ -0,0 +1,12 @@
+{
+ "parent": "minecraft:block/cube_all",
+ "textures": {
+ "down": "advancedperipherals:block/distance_detector_down",
+ "east": "advancedperipherals:block/distance_detector_east",
+ "north": "advancedperipherals:block/distance_detector_north",
+ "particle": "advancedperipherals:block/distance_detector_north",
+ "south": "advancedperipherals:block/distance_detector_south",
+ "up": "advancedperipherals:block/distance_detector_up",
+ "west": "advancedperipherals:block/distance_detector_west"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/energy_detector.json b/src/generated/resources/assets/advancedperipherals/models/block/energy_detector.json
index d1b21431d..ebb28dd2e 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/energy_detector.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/energy_detector.json
@@ -2,8 +2,11 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/energy_detector",
+ "down": "advancedperipherals:block/bottom",
+ "east": "advancedperipherals:block/energy_detector_east",
"north": "advancedperipherals:block/energy_detector_front",
"particle": "advancedperipherals:block/energy_detector_front",
- "south": "advancedperipherals:block/energy_detector_back"
+ "south": "advancedperipherals:block/energy_detector_back",
+ "up": "advancedperipherals:block/energy_detector_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/environment_detector.json b/src/generated/resources/assets/advancedperipherals/models/block/environment_detector.json
index e049a94d1..ce251a7af 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/environment_detector.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/environment_detector.json
@@ -2,7 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/environment_detector",
+ "down": "advancedperipherals:block/bottom",
"north": "advancedperipherals:block/environment_detector_front",
- "particle": "advancedperipherals:block/environment_detector_front"
+ "particle": "advancedperipherals:block/environment_detector_front",
+ "up": "advancedperipherals:block/environment_detector_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/fluid_detector.json b/src/generated/resources/assets/advancedperipherals/models/block/fluid_detector.json
new file mode 100644
index 000000000..6460c20e7
--- /dev/null
+++ b/src/generated/resources/assets/advancedperipherals/models/block/fluid_detector.json
@@ -0,0 +1,12 @@
+{
+ "parent": "minecraft:block/cube_all",
+ "textures": {
+ "all": "advancedperipherals:block/fluid_detector",
+ "down": "advancedperipherals:block/bottom",
+ "east": "advancedperipherals:block/fluid_detector_east",
+ "north": "advancedperipherals:block/fluid_detector_front",
+ "particle": "advancedperipherals:block/fluid_detector_front",
+ "south": "advancedperipherals:block/fluid_detector_back",
+ "up": "advancedperipherals:block/fluid_detector_top"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/gas_detector.json b/src/generated/resources/assets/advancedperipherals/models/block/gas_detector.json
new file mode 100644
index 000000000..c03bc40ae
--- /dev/null
+++ b/src/generated/resources/assets/advancedperipherals/models/block/gas_detector.json
@@ -0,0 +1,12 @@
+{
+ "parent": "minecraft:block/cube_all",
+ "textures": {
+ "all": "advancedperipherals:block/gas_detector",
+ "down": "advancedperipherals:block/bottom",
+ "east": "advancedperipherals:block/gas_detector_east",
+ "north": "advancedperipherals:block/gas_detector_front",
+ "particle": "advancedperipherals:block/gas_detector_front",
+ "south": "advancedperipherals:block/gas_detector_back",
+ "up": "advancedperipherals:block/gas_detector_top"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/geo_scanner.json b/src/generated/resources/assets/advancedperipherals/models/block/geo_scanner.json
index d81084e52..4870d8a6b 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/geo_scanner.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/geo_scanner.json
@@ -2,7 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/geo_scanner",
+ "down": "advancedperipherals:block/bottom",
"north": "advancedperipherals:block/geo_scanner_front",
- "particle": "advancedperipherals:block/geo_scanner_front"
+ "particle": "advancedperipherals:block/geo_scanner_front",
+ "up": "advancedperipherals:block/geo_scanner_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/inventory_manager.json b/src/generated/resources/assets/advancedperipherals/models/block/inventory_manager.json
index 16ac6a767..8431aaece 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/inventory_manager.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/inventory_manager.json
@@ -2,7 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/inventory_manager",
+ "down": "advancedperipherals:block/bottom",
"north": "advancedperipherals:block/inventory_manager_front",
- "particle": "advancedperipherals:block/inventory_manager_front"
+ "particle": "advancedperipherals:block/inventory_manager_front",
+ "up": "advancedperipherals:block/inventory_manager_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/me_bridge.json b/src/generated/resources/assets/advancedperipherals/models/block/me_bridge.json
index 0d5355f55..ab8392272 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/me_bridge.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/me_bridge.json
@@ -2,7 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/me_bridge",
+ "down": "advancedperipherals:block/bottom",
"north": "advancedperipherals:block/me_bridge_front",
- "particle": "advancedperipherals:block/me_bridge_front"
+ "particle": "advancedperipherals:block/me_bridge_front",
+ "up": "advancedperipherals:block/me_bridge_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/nbt_storage.json b/src/generated/resources/assets/advancedperipherals/models/block/nbt_storage.json
index 4472f8466..8545dbe6a 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/nbt_storage.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/nbt_storage.json
@@ -2,7 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/nbt_storage",
+ "down": "advancedperipherals:block/bottom",
"north": "advancedperipherals:block/nbt_storage_front",
- "particle": "advancedperipherals:block/nbt_storage_front"
+ "particle": "advancedperipherals:block/nbt_storage_front",
+ "up": "advancedperipherals:block/nbt_storage_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/peripheral_casing.json b/src/generated/resources/assets/advancedperipherals/models/block/peripheral_casing.json
index d6dd9f3cc..598971334 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/peripheral_casing.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/peripheral_casing.json
@@ -2,6 +2,7 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/peripheral_casing",
+ "down": "advancedperipherals:block/bottom",
"particle": "advancedperipherals:block/peripheral_casing"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/player_detector.json b/src/generated/resources/assets/advancedperipherals/models/block/player_detector.json
index f3d2db295..c658c96c7 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/player_detector.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/player_detector.json
@@ -1,12 +1,13 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
- "all": "advancedperipherals:block/player_detector",
+ "down": "advancedperipherals:block/bottom",
"east": "advancedperipherals:block/player_detector_side",
"north": "advancedperipherals:block/player_detector_front",
"particle": "advancedperipherals:block/player_detector_front",
"side": "advancedperipherals:block/player_detector_side",
"south": "advancedperipherals:block/player_detector_side",
+ "up": "advancedperipherals:block/player_detector_top",
"west": "advancedperipherals:block/player_detector_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/redstone_integrator.json b/src/generated/resources/assets/advancedperipherals/models/block/redstone_integrator.json
index 2fa89aaa5..038dd8561 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/redstone_integrator.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/redstone_integrator.json
@@ -1,8 +1,13 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
- "all": "advancedperipherals:block/redstone_integrator",
+ "down": "advancedperipherals:block/redstone_integrator_bottom",
+ "east": "advancedperipherals:block/redstone_integrator_side",
"north": "advancedperipherals:block/redstone_integrator_front",
- "particle": "advancedperipherals:block/redstone_integrator_front"
+ "particle": "advancedperipherals:block/redstone_integrator_front",
+ "side": "advancedperipherals:block/redstone_integrator_side",
+ "south": "advancedperipherals:block/redstone_integrator_side",
+ "up": "advancedperipherals:block/redstone_integrator_top",
+ "west": "advancedperipherals:block/redstone_integrator_side"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/advancedperipherals/models/block/rs_bridge.json b/src/generated/resources/assets/advancedperipherals/models/block/rs_bridge.json
index 10e0f003a..b7e3d476b 100644
--- a/src/generated/resources/assets/advancedperipherals/models/block/rs_bridge.json
+++ b/src/generated/resources/assets/advancedperipherals/models/block/rs_bridge.json
@@ -2,7 +2,9 @@
"parent": "minecraft:block/cube_all",
"textures": {
"all": "advancedperipherals:block/rs_bridge",
+ "down": "advancedperipherals:block/bottom",
"north": "advancedperipherals:block/rs_bridge_front",
- "particle": "advancedperipherals:block/rs_bridge_front"
+ "particle": "advancedperipherals:block/rs_bridge_front",
+ "up": "advancedperipherals:block/rs_bridge_top"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/advancements/recipes/advancedperipheralstab/armor/smart_glasses_netherite.json b/src/generated/resources/data/advancedperipherals/advancements/recipes/advancedperipheralstab/armor/smart_glasses_netherite.json
new file mode 100644
index 000000000..bb6e067ec
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/advancements/recipes/advancedperipheralstab/armor/smart_glasses_netherite.json
@@ -0,0 +1,34 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "minecraft:netherite_ingot"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "advancedperipherals:armor/smart_glasses_netherite"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "advancedperipherals:armor/smart_glasses_netherite"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/computercraft/pocket_upgrades/distance_pocket.json b/src/generated/resources/data/advancedperipherals/computercraft/pocket_upgrades/distance_pocket.json
new file mode 100644
index 000000000..0d83ccc1d
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/computercraft/pocket_upgrades/distance_pocket.json
@@ -0,0 +1,4 @@
+{
+ "type": "advancedperipherals:distance_pocket",
+ "item": "advancedperipherals:distance_detector"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/computercraft/turtle_upgrades/saddle_turtle.json b/src/generated/resources/data/advancedperipherals/computercraft/turtle_upgrades/saddle_turtle.json
new file mode 100644
index 000000000..0670d5c0b
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/computercraft/turtle_upgrades/saddle_turtle.json
@@ -0,0 +1,4 @@
+{
+ "type": "advancedperipherals:saddle_turtle",
+ "item": "minecraft:saddle"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/loot_tables/blocks/distance_detector.json b/src/generated/resources/data/advancedperipherals/loot_tables/blocks/distance_detector.json
new file mode 100644
index 000000000..4da55fb18
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/loot_tables/blocks/distance_detector.json
@@ -0,0 +1,26 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "functions": [
+ {
+ "function": "minecraft:copy_name",
+ "source": "block_entity"
+ }
+ ],
+ "name": "advancedperipherals:distance_detector"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/loot_tables/blocks/fluid_detector.json b/src/generated/resources/data/advancedperipherals/loot_tables/blocks/fluid_detector.json
new file mode 100644
index 000000000..a57de0eab
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/loot_tables/blocks/fluid_detector.json
@@ -0,0 +1,26 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "functions": [
+ {
+ "function": "minecraft:copy_name",
+ "source": "block_entity"
+ }
+ ],
+ "name": "advancedperipherals:fluid_detector"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/loot_tables/blocks/gas_detector.json b/src/generated/resources/data/advancedperipherals/loot_tables/blocks/gas_detector.json
new file mode 100644
index 000000000..be3a1af68
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/loot_tables/blocks/gas_detector.json
@@ -0,0 +1,26 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "functions": [
+ {
+ "function": "minecraft:copy_name",
+ "source": "block_entity"
+ }
+ ],
+ "name": "advancedperipherals:gas_detector"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/recipes/armor/smart_glasses_netherite.json b/src/generated/resources/data/advancedperipherals/recipes/armor/smart_glasses_netherite.json
new file mode 100644
index 000000000..e46b01d51
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/recipes/armor/smart_glasses_netherite.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:smithing",
+ "addition": {
+ "item": "minecraft:netherite_ingot"
+ },
+ "base": {
+ "item": "advancedperipherals:smart_glasses"
+ },
+ "result": {
+ "item": "advancedperipherals:smart_glasses_netherite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/tags/items/p2p_attunements/cable_p2p_tunnel.json b/src/generated/resources/data/advancedperipherals/tags/items/p2p_attunements/cable_p2p_tunnel.json
new file mode 100644
index 000000000..7fc8269c3
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/tags/items/p2p_attunements/cable_p2p_tunnel.json
@@ -0,0 +1,7 @@
+{
+ "values": [
+ "computercraft:cable",
+ "computercraft:wired_modem",
+ "computercraft:wired_modem_full"
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/advancedperipherals/tags/items/smart_glasses.json b/src/generated/resources/data/advancedperipherals/tags/items/smart_glasses.json
new file mode 100644
index 000000000..1f793687e
--- /dev/null
+++ b/src/generated/resources/data/advancedperipherals/tags/items/smart_glasses.json
@@ -0,0 +1,6 @@
+{
+ "values": [
+ "advancedperipherals:smart_glasses",
+ "advancedperipherals:smart_glasses_netherite"
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/forge/tags/blocks/needs_wood_tool.json b/src/generated/resources/data/forge/tags/blocks/needs_wood_tool.json
index ffd23c4b9..0578bfe7e 100644
--- a/src/generated/resources/data/forge/tags/blocks/needs_wood_tool.json
+++ b/src/generated/resources/data/forge/tags/blocks/needs_wood_tool.json
@@ -1,5 +1,6 @@
{
"values": [
- "advancedperipherals:peripheral_casing"
+ "advancedperipherals:peripheral_casing",
+ "advancedperipherals:colony_integrator"
]
}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json
index ada8618ef..67218e709 100644
--- a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json
+++ b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json
@@ -1,17 +1,20 @@
{
"values": [
- "advancedperipherals:environment_detector",
+ "advancedperipherals:block_reader",
"advancedperipherals:chat_box",
- "advancedperipherals:player_detector",
- "advancedperipherals:me_bridge",
- "advancedperipherals:rs_bridge",
+ "advancedperipherals:colony_integrator",
+ "advancedperipherals:distance_detector",
"advancedperipherals:energy_detector",
- "advancedperipherals:peripheral_casing",
+ "advancedperipherals:environment_detector",
+ "advancedperipherals:fluid_detector",
+ "advancedperipherals:gas_detector",
+ "advancedperipherals:geo_scanner",
"advancedperipherals:inventory_manager",
+ "advancedperipherals:me_bridge",
+ "advancedperipherals:nbt_storage",
+ "advancedperipherals:peripheral_casing",
+ "advancedperipherals:player_detector",
"advancedperipherals:redstone_integrator",
- "advancedperipherals:block_reader",
- "advancedperipherals:geo_scanner",
- "advancedperipherals:colony_integrator",
- "advancedperipherals:nbt_storage"
+ "advancedperipherals:rs_bridge"
]
}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json b/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json
index 002d1e917..5a4f0e2b8 100644
--- a/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json
+++ b/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json
@@ -1,16 +1,19 @@
{
"values": [
- "advancedperipherals:environment_detector",
+ "advancedperipherals:block_reader",
"advancedperipherals:chat_box",
- "advancedperipherals:player_detector",
- "advancedperipherals:me_bridge",
- "advancedperipherals:rs_bridge",
+ "advancedperipherals:colony_integrator",
+ "advancedperipherals:distance_detector",
"advancedperipherals:energy_detector",
+ "advancedperipherals:environment_detector",
+ "advancedperipherals:fluid_detector",
+ "advancedperipherals:gas_detector",
+ "advancedperipherals:geo_scanner",
"advancedperipherals:inventory_manager",
+ "advancedperipherals:me_bridge",
+ "advancedperipherals:nbt_storage",
+ "advancedperipherals:player_detector",
"advancedperipherals:redstone_integrator",
- "advancedperipherals:block_reader",
- "advancedperipherals:geo_scanner",
- "advancedperipherals:colony_integrator",
- "advancedperipherals:nbt_storage"
+ "advancedperipherals:rs_bridge"
]
}
\ No newline at end of file
diff --git a/src/main/java/de/srendi/advancedperipherals/APCreativeTab.java b/src/main/java/de/srendi/advancedperipherals/APCreativeTab.java
index dcdd0c566..8489c5f95 100644
--- a/src/main/java/de/srendi/advancedperipherals/APCreativeTab.java
+++ b/src/main/java/de/srendi/advancedperipherals/APCreativeTab.java
@@ -1,8 +1,8 @@
package de.srendi.advancedperipherals;
-import de.srendi.advancedperipherals.common.setup.Blocks;
+import de.srendi.advancedperipherals.common.setup.APBlocks;
+import de.srendi.advancedperipherals.common.setup.APRegistration;
import de.srendi.advancedperipherals.common.setup.CCRegistration;
-import de.srendi.advancedperipherals.common.setup.Registration;
import de.srendi.advancedperipherals.common.util.inventory.ItemUtil;
import net.minecraft.core.NonNullList;
import net.minecraft.resources.ResourceLocation;
@@ -22,7 +22,7 @@ public APCreativeTab() {
@Override
public void fillItemList(NonNullList items) {
- Registration.ITEMS.getEntries().stream().map(RegistryObject::get).forEach(item -> items.add(new ItemStack(item)));
+ APRegistration.ITEMS.getEntries().stream().map(RegistryObject::get).forEach(item -> items.add(new ItemStack(item)));
items.addAll(pocketUpgrade(CCRegistration.ID.COLONY_POCKET));
items.addAll(pocketUpgrade(CCRegistration.ID.CHATTY_POCKET));
items.addAll(pocketUpgrade(CCRegistration.ID.PLAYER_POCKET));
@@ -32,6 +32,7 @@ public void fillItemList(NonNullList items) {
items.addAll(turtleUpgrade(CCRegistration.ID.CHATTY_TURTLE));
items.addAll(turtleUpgrade(CCRegistration.ID.CHUNKY_TURTLE));
items.addAll(turtleUpgrade(CCRegistration.ID.COMPASS_TURTLE));
+ items.addAll(turtleUpgrade(CCRegistration.ID.SADDLE_TURTLE));
items.addAll(turtleUpgrade(CCRegistration.ID.PLAYER_TURTLE));
items.addAll(turtleUpgrade(CCRegistration.ID.ENVIRONMENT_TURTLE));
items.addAll(turtleUpgrade(CCRegistration.ID.GEOSCANNER_TURTLE));
@@ -57,6 +58,6 @@ private static Collection turtleUpgrade(ResourceLocation pocketId) {
@Override
@NotNull
public ItemStack makeIcon() {
- return new ItemStack(Blocks.CHAT_BOX.get());
+ return new ItemStack(APBlocks.CHAT_BOX.get());
}
}
diff --git a/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java b/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java
index 40ab9c1a9..8f7a80ffd 100644
--- a/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java
+++ b/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java
@@ -1,16 +1,18 @@
package de.srendi.advancedperipherals;
import de.srendi.advancedperipherals.common.addons.APAddons;
+import de.srendi.advancedperipherals.common.addons.ae2.AE2Registries;
import de.srendi.advancedperipherals.common.configuration.APConfig;
-import de.srendi.advancedperipherals.common.setup.Registration;
+import de.srendi.advancedperipherals.common.network.APNetworking;
+import de.srendi.advancedperipherals.common.setup.APRegistration;
import de.srendi.advancedperipherals.common.village.VillageStructures;
-import de.srendi.advancedperipherals.network.APNetworking;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
+import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
@@ -26,6 +28,7 @@ public class AdvancedPeripherals {
public static final Logger LOGGER = LogManager.getLogger(NAME);
public static final Random RANDOM = new Random();
public static final APCreativeTab TAB = new APCreativeTab();
+ public static final APAddons ADDONS = new APAddons();
public AdvancedPeripherals() {
LOGGER.info("AdvancedPeripherals says hello!");
@@ -34,8 +37,10 @@ public AdvancedPeripherals() {
APConfig.register(ModLoadingContext.get());
modBus.addListener(this::commonSetup);
- Registration.register();
+ modBus.addListener(this::onLoadComplete);
+ APRegistration.register();
MinecraftForge.EVENT_BUS.register(this);
+ new APAddons();
}
public static void debug(String message) {
@@ -48,16 +53,28 @@ public static void debug(String message, Level level) {
LOGGER.log(level, "[DEBUG] {}", message);
}
+ public static void exception(String message, Exception exception) {
+ if (APConfig.GENERAL_CONFIG.enableDebugMode.get()) {
+ LOGGER.error("[DEBUG]", exception);
+ }
+ }
+
public static ResourceLocation getRL(String resource) {
return new ResourceLocation(MOD_ID, resource);
}
public void commonSetup(FMLCommonSetupEvent event) {
- APAddons.commonSetup();
event.enqueueWork(() -> {
APNetworking.init();
VillageStructures.init();
});
}
+ public void onLoadComplete(FMLLoadCompleteEvent event) {
+ event.enqueueWork(() -> {
+ if (APAddons.appliedEnergisticsLoaded) {
+ AE2Registries.finishRegister();
+ }
+ });
+ }
}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/ClientEventSubscriber.java b/src/main/java/de/srendi/advancedperipherals/client/ClientEventSubscriber.java
new file mode 100644
index 000000000..0dfeb5c28
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/ClientEventSubscriber.java
@@ -0,0 +1,85 @@
+package de.srendi.advancedperipherals.client;
+
+import com.mojang.blaze3d.platform.InputConstants;
+import de.srendi.advancedperipherals.AdvancedPeripherals;
+import de.srendi.advancedperipherals.common.entity.TurtleSeatEntity;
+import de.srendi.advancedperipherals.common.network.APNetworking;
+import de.srendi.advancedperipherals.common.network.toserver.SaddleTurtleControlPacket;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.player.Input;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.client.event.InputEvent;
+import net.minecraftforge.client.event.MovementInputUpdateEvent;
+import net.minecraftforge.client.event.RenderGuiOverlayEvent;
+import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay;
+import net.minecraftforge.event.entity.EntityMountEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.common.Mod;
+
+@Mod.EventBusSubscriber(modid = AdvancedPeripherals.MOD_ID, value = Dist.CLIENT)
+public class ClientEventSubscriber {
+ @SubscribeEvent
+ public static void renderingHuds(RenderGuiOverlayEvent.Pre event) {
+ if (ClientRegistry.SADDLE_TURTLE_OVERLAY.shouldRenderFuelBar() && event.getOverlay().id().equals(VanillaGuiOverlay.EXPERIENCE_BAR.id())) {
+ event.setCanceled(true);
+ return;
+ }
+ }
+
+ private static boolean sneaking = false;
+
+ @SubscribeEvent
+ public static void playerTryDismount(InputEvent.Key event) {
+ Minecraft minecraft = Minecraft.getInstance();
+ boolean isShift = minecraft.options.keyShift.matches(event.getKey(), event.getScanCode());
+ if (!isShift) {
+ return;
+ }
+ switch (event.getAction()) {
+ case InputConstants.PRESS:
+ sneaking = true;
+ if (ClientRegistry.SADDLE_TURTLE_OVERLAY.isPlayerControllingTurtle()) {
+ minecraft.options.keyShift.setDown(false);
+ }
+ break;
+ case InputConstants.RELEASE:
+ sneaking = false;
+ break;
+ }
+ }
+
+ private static Input lastInput = new Input();
+ private static boolean lastSneak = false;
+
+ @SubscribeEvent
+ public static void playerMounting(EntityMountEvent event) {
+ if (event.isMounting() && event.getEntityMounting() == Minecraft.getInstance().player && event.getEntityBeingMounted() instanceof TurtleSeatEntity) {
+ // clear last key records
+ lastInput.up = false;
+ lastInput.down = false;
+ lastInput.left = false;
+ lastInput.right = false;
+ lastInput.jumping = false;
+ lastSneak = false;
+ }
+ }
+
+ @SubscribeEvent
+ public static void playerMove(MovementInputUpdateEvent event) {
+ if (ClientRegistry.SADDLE_TURTLE_OVERLAY.isPlayerControllingTurtle()) {
+ Input input = event.getInput();
+ if (sneaking == lastSneak && lastInput != null) {
+ if (lastInput.up == input.up && lastInput.down == input.down && lastInput.left == input.left && lastInput.right == input.right && lastInput.jumping == input.jumping) {
+ return;
+ }
+ }
+ lastInput.up = input.up;
+ lastInput.down = input.down;
+ lastInput.left = input.left;
+ lastInput.right = input.right;
+ lastInput.jumping = input.jumping;
+ lastSneak = sneaking;
+ APNetworking.sendToServer(new SaddleTurtleControlPacket(input.up, input.down, input.left, input.right, input.jumping, sneaking));
+ }
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/ClientRegistry.java b/src/main/java/de/srendi/advancedperipherals/client/ClientRegistry.java
index 160836009..4a784dfc3 100644
--- a/src/main/java/de/srendi/advancedperipherals/client/ClientRegistry.java
+++ b/src/main/java/de/srendi/advancedperipherals/client/ClientRegistry.java
@@ -3,15 +3,24 @@
import dan200.computercraft.api.client.ComputerCraftAPIClient;
import dan200.computercraft.api.client.turtle.TurtleUpgradeModeller;
import de.srendi.advancedperipherals.AdvancedPeripherals;
-import de.srendi.advancedperipherals.common.container.InventoryManagerScreen;
+import de.srendi.advancedperipherals.client.renderer.DistanceDetectorRenderer;
+import de.srendi.advancedperipherals.client.screens.InventoryManagerScreen;
+import de.srendi.advancedperipherals.client.screens.SaddleTurtleScreen;
+import de.srendi.advancedperipherals.client.screens.SmartGlassesScreen;
+import de.srendi.advancedperipherals.client.smartglasses.OverlayModuleOverlay;
+import de.srendi.advancedperipherals.client.smartglasses.OverlayObjectHolder;
+import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes;
+import de.srendi.advancedperipherals.common.setup.APContainerTypes;
import de.srendi.advancedperipherals.common.setup.CCRegistration;
-import de.srendi.advancedperipherals.common.setup.ContainerTypes;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.client.event.ModelEvent;
+import net.minecraftforge.client.event.RegisterGuiOverlaysEvent;
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
+import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
@@ -21,6 +30,9 @@ public class ClientRegistry {
private static final String[] TURTLE_MODELS = new String[]{"turtle_chat_box_upgrade_left", "turtle_chat_box_upgrade_right", "turtle_environment_upgrade_left", "turtle_environment_upgrade_right", "turtle_player_upgrade_left", "turtle_player_upgrade_right", "turtle_geoscanner_upgrade_left", "turtle_geoscanner_upgrade_right"};
+ public static final SaddleTurtleScreen SADDLE_TURTLE_OVERLAY = new SaddleTurtleScreen();
+ public static final OverlayModuleOverlay OVERLAY_MODULE_OVERLAY = new OverlayModuleOverlay();
+
@SubscribeEvent
public static void registerModels(ModelEvent.RegisterAdditional event) {
for (String model : TURTLE_MODELS) {
@@ -30,10 +42,12 @@ public static void registerModels(ModelEvent.RegisterAdditional event) {
@SubscribeEvent
public static void onClientSetup(FMLClientSetupEvent event) {
- MenuScreens.register(ContainerTypes.INVENTORY_MANAGER_CONTAINER.get(), InventoryManagerScreen::new);
+ MenuScreens.register(APContainerTypes.INVENTORY_MANAGER_CONTAINER.get(), InventoryManagerScreen::new);
+ MenuScreens.register(APContainerTypes.SMART_GLASSES_CONTAINER.get(), SmartGlassesScreen::new);
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.CHUNKY_TURTLE.get(), TurtleUpgradeModeller.flatItem());
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.COMPASS_TURTLE.get(), TurtleUpgradeModeller.flatItem());
+ ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.SADDLE_TURTLE.get(), TurtleUpgradeModeller.flatItem());
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.CHAT_BOX_TURTLE.get(), TurtleUpgradeModeller.sided(new ModelResourceLocation(AdvancedPeripherals.getRL("turtle_chat_box_upgrade_left"), "inventory"), new ModelResourceLocation(AdvancedPeripherals.getRL("turtle_chat_box_upgrade_right"), "inventory")));
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.ENVIRONMENT_TURTLE.get(), TurtleUpgradeModeller.sided(new ModelResourceLocation(AdvancedPeripherals.getRL("turtle_environment_upgrade_left"), "inventory"), new ModelResourceLocation(AdvancedPeripherals.getRL("turtle_environment_upgrade_right"), "inventory")));
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.GEO_SCANNER_TURTLE.get(), TurtleUpgradeModeller.sided(new ModelResourceLocation(AdvancedPeripherals.getRL("turtle_geoscanner_upgrade_left"), "inventory"), new ModelResourceLocation(AdvancedPeripherals.getRL("turtle_geoscanner_upgrade_right"), "inventory")));
@@ -44,16 +58,24 @@ public static void onClientSetup(FMLClientSetupEvent event) {
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.HUSBANDRY_TURTLE.get(), new MetaTurtleUpgradeModeller<>());
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.END_TURTLE.get(), new MetaTurtleUpgradeModeller<>());
ComputerCraftAPIClient.registerTurtleUpgradeModeller(CCRegistration.WEAK_TURTLE.get(), new MetaTurtleUpgradeModeller<>());
+
+ ItemPropertiesRegistry.register();
+ OverlayObjectHolder.registerDecodeObjects();
}
@SubscribeEvent
- public static void onClientSetup(RegisterKeyMappingsEvent event) {
+ public static void registeringKeymappings(RegisterKeyMappingsEvent event) {
KeyBindings.register(event);
}
- //TODO change the icon of the curio icon
- /*@SubscribeEvent
- public static void onTextureStitching(TextureStitchEvent.Pre event) {
- event.addSprite(new ResourceLocation(AdvancedPeripherals.MOD_ID, "item/empty_glasses_slot"));
- }*/
+ @SubscribeEvent
+ public static void registeringRenderers(EntityRenderersEvent.RegisterRenderers event) {
+ event.registerBlockEntityRenderer(APBlockEntityTypes.DISTANCE_DETECTOR.get(), DistanceDetectorRenderer::new);
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ public static void registeringOverlays(RegisterGuiOverlaysEvent event) {
+ event.registerAboveAll(SaddleTurtleScreen.ID, SADDLE_TURTLE_OVERLAY);
+ event.registerAboveAll(OverlayModuleOverlay.ID, OVERLAY_MODULE_OVERLAY);
+ }
}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/ItemPropertiesRegistry.java b/src/main/java/de/srendi/advancedperipherals/client/ItemPropertiesRegistry.java
new file mode 100644
index 000000000..00ef43539
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/ItemPropertiesRegistry.java
@@ -0,0 +1,17 @@
+package de.srendi.advancedperipherals.client;
+
+import de.srendi.advancedperipherals.AdvancedPeripherals;
+import de.srendi.advancedperipherals.common.setup.APItems;
+import net.minecraft.client.renderer.item.ItemProperties;
+import net.minecraft.resources.ResourceLocation;
+
+public class ItemPropertiesRegistry {
+
+ public static void register() {
+ ItemProperties.register(APItems.MEMORY_CARD.get(), new ResourceLocation(AdvancedPeripherals.MOD_ID, "bounded"), (stack, level, entity, seed) -> {
+ boolean bounded = stack.getOrCreateTag().contains("owner");
+ return bounded ? 1 : 0;
+ });
+ }
+
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/KeyBindings.java b/src/main/java/de/srendi/advancedperipherals/client/KeyBindings.java
index 2cbd46438..37cea5f0d 100644
--- a/src/main/java/de/srendi/advancedperipherals/client/KeyBindings.java
+++ b/src/main/java/de/srendi/advancedperipherals/client/KeyBindings.java
@@ -7,9 +7,11 @@
public class KeyBindings {
public static final KeyMapping DESCRIPTION_KEYBINDING = new KeyMapping("keybind.advancedperipherals.description", GLFW.GLFW_KEY_LEFT_CONTROL, "keybind.advancedperipherals.category");
+ public static final KeyMapping GLASSES_HOTKEY_KEYBINDING = new KeyMapping("keybind.advancedperipherals.glasses_hotkey", GLFW.GLFW_KEY_G, "keybind.advancedperipherals.category");
public static void register(RegisterKeyMappingsEvent event) {
event.register(DESCRIPTION_KEYBINDING);
+ event.register(GLASSES_HOTKEY_KEYBINDING);
}
}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/RenderUtil.java b/src/main/java/de/srendi/advancedperipherals/client/RenderUtil.java
new file mode 100644
index 000000000..4a4826238
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/RenderUtil.java
@@ -0,0 +1,367 @@
+package de.srendi.advancedperipherals.client;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import com.mojang.math.Matrix4f;
+import com.mojang.math.Quaternion;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.texture.OverlayTexture;
+import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.core.Direction;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.inventory.InventoryMenu;
+
+public class RenderUtil {
+
+ public static void drawBox(PoseStack poseStack, VertexConsumer buffer, float r, float g, float b, float a, float pX, float pY, float pZ, float xRot, float yRot, float zRot, float sX, float sY, float sZ) {
+ poseStack.pushPose();
+ sX = sX / 16; //Sizes in pixels please
+ sY = sY / 16;
+ sZ = sZ / 16;
+ pX = pX / 16;
+ pY = pY / 16;
+ pZ = pZ / 16;
+
+ poseStack.mulPose(new Quaternion(xRot, yRot, zRot, true));
+
+ drawPlane(poseStack, buffer, r, g, b, a, Direction.UP, pX, pY, pZ, sX, sY, sZ);
+ drawPlane(poseStack, buffer, r, g, b, a, Direction.DOWN, pX, pY, pZ, sX, sY, sZ);
+ drawPlane(poseStack, buffer, r, g, b, a, Direction.EAST, pX, pY, pZ, sX, sY, sZ);
+ drawPlane(poseStack, buffer, r, g, b, a, Direction.WEST, pX, pY, pZ, sX, sY, sZ);
+ drawPlane(poseStack, buffer, r, g, b, a, Direction.NORTH, pX, pY, pZ, sX, sY, sZ);
+ drawPlane(poseStack, buffer, r, g, b, a, Direction.SOUTH, pX, pY, pZ, sX, sY, sZ);
+ poseStack.popPose();
+ }
+
+ public static void drawPlane(PoseStack posestack, VertexConsumer buffer, float r, float g, float b, float a, Direction perspective, float pX, float pY, float pZ, float sX, float sY, float sZ) {
+ posestack.pushPose();
+
+ pX = pX + 0.5f;
+ pY = pY + 0.5f;
+ pZ = pZ + 0.5f;
+
+ posestack.translate(pX, pY, pZ);
+
+ Matrix4f matrix4f = posestack.last().pose();
+
+ sX = sX / 2;
+ sY = sY / 2;
+ sZ = sZ / 2;
+
+
+ if (perspective == Direction.UP) {
+ buffer.vertex(matrix4f, -sX, sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ }
+ if (perspective == Direction.DOWN) {
+ buffer.vertex(matrix4f, -sX, -sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, -sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ }
+ if (perspective == Direction.SOUTH) {
+ buffer.vertex(matrix4f, sX, -sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ }
+ if (perspective == Direction.NORTH) {
+ buffer.vertex(matrix4f, -sX, -sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, -sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ }
+ if (perspective == Direction.EAST) {
+ buffer.vertex(matrix4f, -sX, -sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, -sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ }
+ if (perspective == Direction.WEST) {
+ buffer.vertex(matrix4f, -sX, -sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, sZ).color(r, g, b, a).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ }
+ posestack.popPose();
+ }
+
+ public static void drawTorus(PoseStack poseStack, VertexConsumer consumer, float majorRadius, float minorRadius, double pX, double pY, double pZ, float xRot, float yRot, float zRot, float r, float g, float b, float a, int sides, int rings) {
+ poseStack.pushPose();
+ poseStack.translate(pX, pY, pZ);
+ poseStack.mulPose(new Quaternion(xRot, yRot, zRot, true));
+
+ Matrix4f matrix4f = poseStack.last().pose();
+ TextureAtlasSprite texture = Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(new ResourceLocation("block/crimson_stem"));
+
+ float x, y, z;
+ float nx, ny, nz;
+
+ float ringStep = (float) (2 * Math.PI / rings);
+ float sideStep = (float) (2 * Math.PI / sides);
+ float ringAngle, sideAngle;
+
+ for (int i = 0; i < rings; ++i) {
+ ringAngle = i * ringStep;
+ float cosRingAngle = (float) Math.cos(ringAngle);
+ float sinRingAngle = (float) Math.sin(ringAngle);
+
+ float nextRingAngle = (i + 1) * ringStep;
+ float nextCosRingAngle = (float) Math.cos(nextRingAngle);
+ float nextSinRingAngle = (float) Math.sin(nextRingAngle);
+
+ // Calculate the center point of the minor circles
+ float centerX = majorRadius * cosRingAngle;
+ float centerY = majorRadius * sinRingAngle;
+ float nextCenterX = majorRadius * nextCosRingAngle;
+ float nextCenterY = majorRadius * nextSinRingAngle;
+
+ for (int j = 0; j < sides; ++j) {
+ sideAngle = j * sideStep;
+ float cosSideAngle = (float) Math.cos(sideAngle);
+ float sinSideAngle = (float) Math.sin(sideAngle);
+
+ float nextSideAngle = (j + 1) * sideStep;
+ float nextCosSideAngle = (float) Math.cos(nextSideAngle);
+ float nextSinSideAngle = (float) Math.sin(nextSideAngle);
+
+ float s = j / sides;
+ float t = i / rings;
+
+ float u1 = getU(s * sides, texture.getU1(), texture.getU0(), sides);
+ float u2 = getU((s + 1.0f / sides) * sides, texture.getU1(), texture.getU0(), sides);
+ float v1 = getV(t * rings, texture.getV1(), texture.getV0(), rings);
+ float v2 = getV((t + 1.0f / rings) * rings, texture.getV1(), texture.getV0(), rings);
+
+ x = centerX + minorRadius * nextCosSideAngle * cosRingAngle;
+ y = centerY + minorRadius * nextCosSideAngle * sinRingAngle;
+ z = minorRadius * nextSinSideAngle;
+
+ nx = x - centerX;
+ ny = y - centerY;
+ nz = z;
+ consumer.vertex(matrix4f, x, y, z).color(r, g, b, a).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx, ny, nz).endVertex();
+
+ // Calculate vertex positions
+ x = centerX + minorRadius * cosSideAngle * cosRingAngle;
+ y = centerY + minorRadius * cosSideAngle * sinRingAngle;
+ z = minorRadius * sinSideAngle;
+
+ // Calculate normal
+ nx = x - centerX;
+ ny = y - centerY;
+ nz = z;
+
+ consumer.vertex(matrix4f, x, y, z).color(r, g, b, a).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx, ny, nz).endVertex();
+
+ x = nextCenterX + minorRadius * cosSideAngle * nextCosRingAngle;
+ y = nextCenterY + minorRadius * cosSideAngle * nextSinRingAngle;
+ z = minorRadius * sinSideAngle;
+
+ nx = x - nextCenterX;
+ ny = y - nextCenterY;
+ nz = z;
+ consumer.vertex(matrix4f, x, y, z).color(r, g, b, a).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx, ny, nz).endVertex();
+
+
+ x = nextCenterX + minorRadius * nextCosSideAngle * nextCosRingAngle;
+ y = nextCenterY + minorRadius * nextCosSideAngle * nextSinRingAngle;
+ z = minorRadius * nextSinSideAngle;
+
+ nx = x - nextCenterX;
+ ny = y - nextCenterY;
+ nz = z;
+ consumer.vertex(matrix4f, x, y, z).color(r, g, b, a).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx, ny, nz).endVertex();
+ }
+ }
+
+ poseStack.popPose();
+ }
+
+ public static void drawSphere(PoseStack poseStack, VertexConsumer consumer, float radius, double pX, double pY, double pZ, float xRot, float yRot, float zRot, float r, float g, float b, float a, int sectors, int stacks) {
+ poseStack.pushPose();
+ poseStack.translate(pX, pY, pZ);
+ poseStack.mulPose(new Quaternion(xRot, yRot, zRot, true));
+
+ Matrix4f matrix4f = poseStack.last().pose();
+ TextureAtlasSprite texture = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(new ResourceLocation("block/dirt"));
+
+ float z, xy;
+ float nx1, ny1, nz1, nx2, ny2, nz2, nx3, ny3, nz3, nx4, ny4, nz4, lengthInv = (1.0f / radius); // vertex normal
+ float s, t;
+
+ float sectorStep = (float) (2 * Math.PI / sectors);
+ float stackStep = (float) (Math.PI / stacks);
+ float sectorAngle, stackAngle;
+
+ for (int i = 1; i <= stacks; ++i) {
+ stackAngle = (float) (Math.PI / 2 - i * stackStep);
+
+ xy = (float) (radius * Math.cos(stackAngle));
+ z = (float) (radius * Math.sin(stackAngle));
+
+ for (int j = 0; j < sectors; ++j) {
+
+ sectorAngle = j * sectorStep;
+
+ float x1 = (float) (xy * Math.cos(sectorAngle));
+ float y1 = (float) (xy * Math.sin(sectorAngle));
+
+ float x2 = (float) (xy * Math.cos(sectorAngle + sectorStep));
+ float y2 = (float) (xy * Math.sin(sectorAngle + sectorStep));
+
+ float x3 = (float) (radius * Math.cos(stackAngle + stackStep) * Math.cos(sectorAngle + sectorStep));
+ float y3 = (float) (radius * Math.cos(stackAngle + stackStep) * Math.sin(sectorAngle + sectorStep));
+ float z3 = (float) (radius * Math.sin(stackAngle + stackStep));
+
+ float x4 = (float) (radius * Math.cos(stackAngle + stackStep) * Math.cos(sectorAngle));
+ float y4 = (float) (radius * Math.cos(stackAngle + stackStep) * Math.sin(sectorAngle));
+ float z4 = (float) (radius * Math.sin(stackAngle + stackStep));
+
+ nx1 = x1 * lengthInv;
+ ny1 = y1 * lengthInv;
+ nz1 = z * lengthInv;
+
+ nx2 = x2 * lengthInv;
+ ny2 = y2 * lengthInv;
+ nz2 = z * lengthInv;
+
+ nx3 = x3 * lengthInv;
+ ny3 = y3 * lengthInv;
+ nz3 = z3 * lengthInv;
+
+ nx4 = x4 * lengthInv;
+ ny4 = y4 * lengthInv;
+ nz4 = z4 * lengthInv;
+
+ s = j / sectors;
+ t = i / stacks;
+
+ float u1 = getU(s * sectors, texture.getU1(), texture.getU0(), sectors);
+ float u2 = getU((s + 1.0d / sectors) * sectors, texture.getU1(), texture.getU0(), sectors);
+ float v1 = getV(t * stacks, texture.getV1(), texture.getV0(), stacks);
+ float v2 = getV((t + 1.0d / stacks) * stacks, texture.getV1(), texture.getV0(), stacks);
+
+ // For a reason which I am too dumb to understand, the uv coords have a one pixel offset
+ // So... I just reverse it and it works
+ v1 -= (texture.getV1() - texture.getV0()) / stacks;
+ v2 -= (texture.getV1() - texture.getV0()) / stacks;
+
+ consumer.vertex(matrix4f, x1, y1, z).color(r, g, b, a).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx1, ny1, nz1).endVertex();
+ consumer.vertex(matrix4f, x2, y2, z).color(r, g, b, a).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx2, ny2, nz2).endVertex();
+ consumer.vertex(matrix4f, x3, y3, z3).color(r, g, b, a).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx3, ny3, nz3).endVertex();
+ consumer.vertex(matrix4f, x4, y4, z4).color(r, g, b, a).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(nx4, ny4, nz4).endVertex();
+
+ }
+ }
+ poseStack.popPose();
+
+ }
+
+ private static float getU(double pU, float u1, float u0, float resolution) {
+ float f = u1 - u0;
+ return u0 + f * (float) pU / resolution;
+ }
+
+ private static float getV(double pV, float v1, float v0, float resolution) {
+ float f = v1 - v0;
+ return v0 + f * (float) pV / resolution;
+ }
+
+ public static void drawBox(PoseStack poseStack, VertexConsumer buffer, ResourceLocation texture, float pX, float pY, float pZ, float xRot, float yRot, float zRot, float sX, float sY, float sZ, float pUOffset, float pVOffset, float pWidth, float pHeight) {
+ poseStack.pushPose();
+ sX = sX / 16; //Sizes in pixels please
+ sY = sY / 16;
+ sZ = sZ / 16;
+ pX = pX / 16;
+ pY = pY / 16;
+ pZ = pZ / 16;
+
+ poseStack.mulPose(new Quaternion(xRot, yRot, zRot, true));
+
+ drawPlane(poseStack, buffer, texture, Direction.UP, pX, pY, pZ, sX, sY, sZ, pUOffset, pVOffset, pWidth, pHeight);
+ drawPlane(poseStack, buffer, texture, Direction.DOWN, pX, pY, pZ, sX, sY, sZ, pUOffset, pVOffset, pWidth, pHeight);
+ drawPlane(poseStack, buffer, texture, Direction.EAST, pX, pY, pZ, sX, sY, sZ, pUOffset, pVOffset, pWidth, pHeight);
+ drawPlane(poseStack, buffer, texture, Direction.WEST, pX, pY, pZ, sX, sY, sZ, pUOffset, pVOffset, pWidth, pHeight);
+ drawPlane(poseStack, buffer, texture, Direction.NORTH, pX, pY, pZ, sX, sY, sZ, pUOffset, pVOffset, pWidth, pHeight);
+ drawPlane(poseStack, buffer, texture, Direction.SOUTH, pX, pY, pZ, sX, sY, sZ, pUOffset, pVOffset, pWidth, pHeight);
+ poseStack.popPose();
+ }
+
+ public static void drawPlane(PoseStack poseStack, VertexConsumer buffer, ResourceLocation texture, Direction perspective, float pX, float pY, float pZ, float sX, float sY, float sZ, float pUOffset, float pVOffset, float pWidth, float pHeight) {
+ poseStack.pushPose();
+
+ pX = pX + 0.5f;
+ pY = pY + 0.5f;
+ pZ = pZ + 0.5f;
+
+ poseStack.translate(pX, pY, pZ);
+
+ Matrix4f matrix4f = poseStack.last().pose();
+
+ TextureAtlasSprite stillTexture = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
+
+ sX = sX / 2;
+ sY = sY / 2;
+ sZ = sZ / 2;
+
+ float u1 = stillTexture.getU(pUOffset);
+ float u2 = stillTexture.getU(pWidth);
+ float v1 = stillTexture.getV(pVOffset);
+ float v2 = stillTexture.getV(pHeight);
+
+ if (perspective == Direction.UP) {
+ buffer.vertex(matrix4f, -sX, sY, sZ).color(1, 1, 1, 1f).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, sZ).color(1, 1, 1, 1f).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, -sZ).color(1, 1, 1, 1f).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, -sZ).color(1, 1, 1, 1f).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ }
+ if (perspective == Direction.DOWN) {
+ buffer.vertex(matrix4f, -sX, -sY, sZ).color(1, 1, 1, 1f).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, -sY, -sZ).color(1, 1, 1, 1f).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, -sZ).color(1, 1, 1, 1f).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, sZ).color(1, 1, 1, 1f).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, -1f, 0f).endVertex();
+ }
+ if (perspective == Direction.SOUTH) {
+ buffer.vertex(matrix4f, sX, -sY, sZ).color(1, 1, 1, 1f).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, -sZ).color(1, 1, 1, 1f).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, -sZ).color(1, 1, 1, 1f).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, sZ).color(1, 1, 1, 1f).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ }
+ if (perspective == Direction.NORTH) {
+ buffer.vertex(matrix4f, -sX, -sY, sZ).color(1, 1, 1, 1f).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, sZ).color(1, 1, 1, 1f).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, -sZ).color(1, 1, 1, 1f).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, -sY, -sZ).color(1, 1, 1, 1f).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(1f, 0f, 0f).endVertex();
+ }
+ if (perspective == Direction.EAST) {
+ buffer.vertex(matrix4f, -sX, -sY, -sZ).color(1, 1, 1, 1f).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, -sZ).color(1, 1, 1, 1f).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, -sZ).color(1, 1, 1, 1f).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, -sZ).color(1, 1, 1, 1f).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ }
+ if (perspective == Direction.WEST) {
+ buffer.vertex(matrix4f, -sX, -sY, sZ).color(1, 1, 1, 1f).uv(u1, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, -sY, sZ).color(1, 1, 1, 1f).uv(u1, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, sX, sY, sZ).color(1, 1, 1, 1f).uv(u2, v1).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ buffer.vertex(matrix4f, -sX, sY, sZ).color(1, 1, 1, 1f).uv(u2, v2).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(0xF000F0).normal(0f, 1f, 0f).endVertex();
+ }
+ poseStack.popPose();
+ }
+
+ public static float getBlue(int hex) {
+ return (hex & 0xFF) / 255.0F;
+ }
+
+ public static float getGreen(int hex) {
+ return (hex >> 8 & 0xFF) / 255.0F;
+ }
+
+ public static float getRed(int hex) {
+ return (hex >> 16 & 0xFF) / 255.0F;
+ }
+
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java
new file mode 100644
index 000000000..a0b6f8a7c
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java
@@ -0,0 +1,104 @@
+package de.srendi.advancedperipherals.client.renderer;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import com.mojang.math.Matrix3f;
+import com.mojang.math.Matrix4f;
+import com.mojang.math.Vector3f;
+import de.srendi.advancedperipherals.common.blocks.base.BaseBlock;
+import de.srendi.advancedperipherals.common.blocks.blockentities.DistanceDetectorEntity;
+import de.srendi.advancedperipherals.common.util.EnumColor;
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.RenderType;
+import net.minecraft.client.renderer.blockentity.BeaconRenderer;
+import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
+import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
+import net.minecraft.client.renderer.texture.OverlayTexture;
+import net.minecraft.core.Direction;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.Mth;
+import net.minecraft.world.phys.Vec3;
+import org.jetbrains.annotations.NotNull;
+
+public class DistanceDetectorRenderer implements BlockEntityRenderer {
+
+ public DistanceDetectorRenderer(BlockEntityRendererProvider.Context pContext) {
+ super();
+ }
+
+ @Override
+ public void render(@NotNull DistanceDetectorEntity pBlockEntity, float pPartialTick, @NotNull PoseStack pPoseStack, MultiBufferSource pBufferSource, int pPackedLight, int pPackedOverlay) {
+ if (pBlockEntity.getShowLaser()) {
+ float distance = pBlockEntity.getCurrentDistance();
+ float[] color = EnumColor.RED.getRgb();
+ if (distance == -1) {
+ distance = pBlockEntity.getMaxRange();
+ color = EnumColor.DARK_RED.getRgb();
+ }
+ renderBeaconBeam(pBlockEntity, pPoseStack, pBufferSource, BeaconRenderer.BEAM_LOCATION, pPartialTick, 1, 0, distance + 0.5f, color, 0.05f, 0.09f);
+ }
+ }
+
+ @Override
+ public boolean shouldRenderOffScreen(@NotNull DistanceDetectorEntity pBlockEntity) {
+ return true;
+ }
+
+ @Override
+ public int getViewDistance() {
+ return 256;
+ }
+
+ @Override
+ public boolean shouldRender(@NotNull DistanceDetectorEntity pBlockEntity, @NotNull Vec3 pCameraPos) {
+ return true;
+ }
+
+ public static void renderBeaconBeam(DistanceDetectorEntity detectorEntity, PoseStack pPoseStack, MultiBufferSource pBufferSource, ResourceLocation pBeamLocation, float pPartialTick, float pTextureScale, int pYOffset, float pHeight, float[] pColors, float pBeamRadius, float pGlowRadius) {
+ long pGameTime = detectorEntity.getLevel().getGameTime();
+ float maxX = pYOffset + pHeight;
+ Direction direction = detectorEntity.getBlockState().getValue(BaseBlock.ORIENTATION).front();
+ pPoseStack.pushPose();
+ pPoseStack.translate(0.5D, 0.5D, 0.5D);
+ float degrees = Math.floorMod(pGameTime, 360) + pPartialTick;
+ float reversedDegrees = pHeight < 0 ? degrees : -degrees;
+ float time = Mth.frac(reversedDegrees * 0.2F - Mth.floor(reversedDegrees * 0.1F));
+ float r = pColors[0];
+ float g = pColors[1];
+ float b = pColors[2];
+ pPoseStack.pushPose();
+ pPoseStack.mulPose(direction.getRotation());
+ pPoseStack.mulPose(Vector3f.YP.rotationDegrees(degrees * 2.25F - 45.0F));
+ float f15 = -1.0F + time;
+ float f16 = pHeight * pTextureScale * (0.5F / pBeamRadius) + f15;
+ renderPart(pPoseStack, pBufferSource.getBuffer(RenderType.beaconBeam(pBeamLocation, false)), r, g, b, 1.0F, pYOffset, maxX, 0.0F, pBeamRadius, pBeamRadius, 0.0F, -pBeamRadius, 0.0F, 0.0F, -pBeamRadius, 0.0F, 1.0F, f16, f15);
+ pPoseStack.popPose();
+ pPoseStack.mulPose(direction.getRotation());
+ f15 = -1.0F + time;
+ f16 = pHeight * pTextureScale + f15;
+ renderPart(pPoseStack, pBufferSource.getBuffer(RenderType.beaconBeam(pBeamLocation, true)), r, g, b, 0.225F, pYOffset, maxX, -pGlowRadius, -pGlowRadius, pGlowRadius, -pGlowRadius, -pBeamRadius, pGlowRadius, pGlowRadius, pGlowRadius, 0.0F, 1.0F, f16, f15);
+ pPoseStack.popPose();
+ }
+
+ private static void renderPart(PoseStack pPoseStack, VertexConsumer pConsumer, float pRed, float pGreen, float pBlue, float pAlpha, int pMinY, float pMaxY, float pX0, float pZ0, float pX1, float pZ1, float pX2, float pZ2, float pX3, float pZ3, float pMinU, float pMaxU, float pMinV, float pMaxV) {
+ PoseStack.Pose posestackPose = pPoseStack.last();
+ Matrix4f matrix4f = posestackPose.pose();
+ Matrix3f matrix3f = posestackPose.normal();
+ renderQuad(matrix4f, matrix3f, pConsumer, pRed, pGreen, pBlue, pAlpha, pMinY, pMaxY, pX0, pZ0, pX1, pZ1, pMinU, pMaxU, pMinV, pMaxV);
+ renderQuad(matrix4f, matrix3f, pConsumer, pRed, pGreen, pBlue, pAlpha, pMinY, pMaxY, pX3, pZ3, pX2, pZ2, pMinU, pMaxU, pMinV, pMaxV);
+ renderQuad(matrix4f, matrix3f, pConsumer, pRed, pGreen, pBlue, pAlpha, pMinY, pMaxY, pX1, pZ1, pX3, pZ3, pMinU, pMaxU, pMinV, pMaxV);
+ renderQuad(matrix4f, matrix3f, pConsumer, pRed, pGreen, pBlue, pAlpha, pMinY, pMaxY, pX2, pZ2, pX0, pZ0, pMinU, pMaxU, pMinV, pMaxV);
+ }
+
+ private static void renderQuad(Matrix4f pPose, Matrix3f pNormal, VertexConsumer pConsumer, float pRed, float pGreen, float pBlue, float pAlpha, int pMinY, float pMaxY, float pMinX, float pMinZ, float pMaxX, float pMaxZ, float pMinU, float pMaxU, float pMinV, float pMaxV) {
+ addVertex(pPose, pNormal, pConsumer, pRed, pGreen, pBlue, pAlpha, pMaxY, pMinX, pMinZ, pMaxU, pMinV);
+ addVertex(pPose, pNormal, pConsumer, pRed, pGreen, pBlue, pAlpha, pMinY, pMinX, pMinZ, pMaxU, pMaxV);
+ addVertex(pPose, pNormal, pConsumer, pRed, pGreen, pBlue, pAlpha, pMinY, pMaxX, pMaxZ, pMinU, pMaxV);
+ addVertex(pPose, pNormal, pConsumer, pRed, pGreen, pBlue, pAlpha, pMaxY, pMaxX, pMaxZ, pMinU, pMinV);
+ }
+
+ private static void addVertex(Matrix4f pPose, Matrix3f pNormal, VertexConsumer pConsumer, float pRed, float pGreen, float pBlue, float pAlpha, float pY, float pX, float pZ, float pU, float pV) {
+ pConsumer.vertex(pPose, pX, pY, pZ).color(pRed, pGreen, pBlue, pAlpha).uv(pU, pV).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(15728880).normal(pNormal, 0.0F, 1.0F, 0.0F).endVertex();
+ }
+
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/common/container/InventoryManagerScreen.java b/src/main/java/de/srendi/advancedperipherals/client/screens/InventoryManagerScreen.java
similarity index 78%
rename from src/main/java/de/srendi/advancedperipherals/common/container/InventoryManagerScreen.java
rename to src/main/java/de/srendi/advancedperipherals/client/screens/InventoryManagerScreen.java
index e4d88e29c..d1730b50b 100644
--- a/src/main/java/de/srendi/advancedperipherals/common/container/InventoryManagerScreen.java
+++ b/src/main/java/de/srendi/advancedperipherals/client/screens/InventoryManagerScreen.java
@@ -1,7 +1,8 @@
-package de.srendi.advancedperipherals.common.container;
+package de.srendi.advancedperipherals.client.screens;
import de.srendi.advancedperipherals.AdvancedPeripherals;
-import de.srendi.advancedperipherals.common.container.base.BaseScreen;
+import de.srendi.advancedperipherals.client.screens.base.BaseScreen;
+import de.srendi.advancedperipherals.common.container.InventoryManagerContainer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
diff --git a/src/main/java/de/srendi/advancedperipherals/client/screens/SaddleTurtleScreen.java b/src/main/java/de/srendi/advancedperipherals/client/screens/SaddleTurtleScreen.java
new file mode 100644
index 000000000..7dc79a758
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/screens/SaddleTurtleScreen.java
@@ -0,0 +1,156 @@
+package de.srendi.advancedperipherals.client.screens;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
+import de.srendi.advancedperipherals.common.entity.TurtleSeatEntity;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.GuiComponent;
+import net.minecraft.client.player.LocalPlayer;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.FormattedText;
+import net.minecraft.util.FormattedCharSequence;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+import net.minecraftforge.client.gui.overlay.IGuiOverlay;
+
+public class SaddleTurtleScreen extends GuiComponent implements IGuiOverlay {
+ public static final String ID = "saddle_turtle_overlay";
+
+ private static final long ACTIVE_TIMEOUT = 5000;
+
+ private ForgeGui gui;
+ private int screenWidth = 0;
+ private int screenHeight = 0;
+
+ private int fuelLevel = 0;
+ private int fuelLimit = 0;
+ private int barColor = 0;
+ private long lastActived = 0;
+
+ public SaddleTurtleScreen() {}
+
+ protected Font getFont() {
+ return this.gui.getMinecraft().font;
+ }
+
+ protected int textWidth(String text) {
+ return getFont().width(text);
+ }
+
+ protected int textWidth(FormattedText text) {
+ return getFont().width(text);
+ }
+
+ protected int textWidth(FormattedCharSequence text) {
+ return getFont().width(text);
+ }
+
+ public static boolean isPlayerControllingTurtle() {
+ LocalPlayer player = Minecraft.getInstance().player;
+ return player != null && player.getVehicle() instanceof TurtleSeatEntity;
+ }
+
+ public static boolean isPlayerMountedOnTurtle() {
+ LocalPlayer player = Minecraft.getInstance().player;
+ return player != null && player.getRootVehicle() instanceof TurtleSeatEntity;
+ }
+
+ public boolean shouldRenderFuelBar() {
+ if (this.lastActived == 0) {
+ return false;
+ }
+ if (!isPlayerMountedOnTurtle()) {
+ this.hide();
+ return false;
+ }
+ return this.lastActived + ACTIVE_TIMEOUT > System.currentTimeMillis();
+ }
+
+ public void hide() {
+ this.fuelLevel = 0;
+ this.fuelLimit = 0;
+ this.barColor = 0;
+ this.lastActived = 0;
+ }
+
+ public void keepAlive() {
+ this.lastActived = System.currentTimeMillis();
+ }
+
+ public void setFuelLevel(int level) {
+ if (level < 0) {
+ level = 0;
+ }
+ if (this.fuelLevel != level) {
+ this.fuelLevel = level;
+ this.keepAlive();
+ }
+ }
+
+ public void setFuelLimit(int limit) {
+ if (this.fuelLimit != limit) {
+ this.fuelLimit = limit;
+ this.keepAlive();
+ }
+ }
+
+ public void setBarColor(int color) {
+ if (this.barColor != color) {
+ this.barColor = color;
+ this.keepAlive();
+ }
+ }
+
+ private void renderFuelBar(PoseStack stack) {
+ // TODO: use a better looking bar here, and/or find someway to change the bar's color
+ RenderSystem.setShaderTexture(0, GuiComponent.GUI_ICONS_LOCATION);
+ int fontColor = 0x80ff20;
+
+ int width = 182;
+ int left = this.screenWidth / 2 - 91;
+ int top = this.screenHeight - 32 + 3;
+ this.blit(stack, left, top, 0, 64, width, 5);
+ if (fuelLevel > 0 && fuelLimit > 0) {
+ int progWidth = fuelLevel * width / fuelLimit;
+ this.blit(stack, left, top, 0, 69, progWidth, 5);
+ }
+
+ String text = fuelLimit > 0 ? String.format("%d / %d", fuelLevel, fuelLimit) : "Infinity";
+ int x = (this.screenWidth - getFont().width(text)) / 2;
+ int y = this.screenHeight - 31;
+ getFont().draw(stack, text, (float)(x + 1), (float) y, 0);
+ getFont().draw(stack, text, (float)(x - 1), (float) y, 0);
+ getFont().draw(stack, text, (float) x, (float)(y + 1), 0);
+ getFont().draw(stack, text, (float) x, (float)(y - 1), 0);
+ getFont().draw(stack, text, (float) x, (float) y, fontColor);
+ }
+
+ private void renderDismountHint(PoseStack stack) {
+ Minecraft minecraft = Minecraft.getInstance();
+ Component name = Component.translatable("block.computercraft.turtle_normal.upgraded", Component.translatable("turtle.advancedperipherals.saddle_turtle"));
+ // TODO: get and render turtle's label if exists
+ Component text = Component.translatable("text.advancedperipherals.saddle_turtle.dismount_hint",
+ name, minecraft.options.keyShift.getTranslatedKeyMessage(), minecraft.options.keyInventory.getTranslatedKeyMessage());
+ float top = 10;
+ float x = (float)(this.screenWidth / 2 - textWidth(text) / 2);
+ getFont().drawShadow(stack, text, x, top, 0xffffff);
+ }
+
+ @Override
+ public void render(ForgeGui gui, PoseStack poseStack, float partialTick, int screenWidth, int screenHeight) {
+ if (!isPlayerMountedOnTurtle()) {
+ return;
+ }
+
+ this.gui = gui;
+ this.screenWidth = screenWidth;
+ this.screenHeight = screenHeight;
+
+ if (this.shouldRenderFuelBar()) {
+ this.renderFuelBar(poseStack);
+ }
+ if (isPlayerControllingTurtle()) {
+ this.renderDismountHint(poseStack);
+ }
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/screens/SmartGlassesScreen.java b/src/main/java/de/srendi/advancedperipherals/client/screens/SmartGlassesScreen.java
new file mode 100644
index 000000000..c81884b59
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/screens/SmartGlassesScreen.java
@@ -0,0 +1,78 @@
+package de.srendi.advancedperipherals.client.screens;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
+import dan200.computercraft.client.gui.ComputerScreenBase;
+import dan200.computercraft.client.gui.widgets.ComputerSidebar;
+import dan200.computercraft.client.gui.widgets.WidgetTerminal;
+import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
+import de.srendi.advancedperipherals.AdvancedPeripherals;
+import de.srendi.advancedperipherals.client.widgets.SmartGlassesSettingsSwitch;
+import de.srendi.advancedperipherals.common.container.SmartGlassesContainer;
+import de.srendi.advancedperipherals.common.smartglasses.SlotType;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.FormattedCharSequence;
+import net.minecraft.world.entity.player.Inventory;
+import org.jetbrains.annotations.NotNull;
+
+public class SmartGlassesScreen extends ComputerScreenBase {
+
+ private static final ResourceLocation BACKGROUND = new ResourceLocation(AdvancedPeripherals.MOD_ID, "textures/gui/smart_glasses_gui.png");
+ public static final ResourceLocation SIDEBAR = new ResourceLocation(AdvancedPeripherals.MOD_ID, "textures/gui/corners_glasses.png");
+
+ private static final int TEX_WIDTH = 254;
+ private static final int TEX_HEIGHT = 217;
+ private SlotType currentType = SlotType.defaultType();
+
+ public SmartGlassesScreen(SmartGlassesContainer container, Inventory player, Component title) {
+ super(container, player, title, ContainerTurtle.BORDER);
+
+ imageWidth = TEX_WIDTH + ComputerSidebar.WIDTH;
+ imageHeight = TEX_HEIGHT;
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ addRenderableWidget(new SmartGlassesSettingsSwitch(254, 147, SlotType.PERIPHERALS, this));
+ addRenderableWidget(new SmartGlassesSettingsSwitch(254, 170, SlotType.MODULES, this));
+ }
+
+ @Override
+ protected WidgetTerminal createTerminal() {
+ return new WidgetTerminal(terminalData, input, leftPos + ContainerTurtle.BORDER + ComputerSidebar.WIDTH, topPos + ContainerTurtle.BORDER);
+ }
+
+ @Override
+ protected void renderBg(@NotNull PoseStack transform, float partialTicks, int mouseX, int mouseY) {
+ RenderSystem.setShaderTexture(0, BACKGROUND);
+ blit(transform, leftPos + ComputerSidebar.WIDTH, topPos, 0, 0, TEX_WIDTH, TEX_HEIGHT);
+
+ if (currentType == SlotType.PERIPHERALS)
+ blit(transform, leftPos + ComputerSidebar.WIDTH + 222, topPos + 183, 186, 183, 18, 18);
+
+ RenderSystem.setShaderTexture(0, SIDEBAR);
+ ComputerSidebar.renderBackground(transform, leftPos, topPos + sidebarYOffset);
+ }
+
+ @Override
+ protected void renderTooltip(@NotNull PoseStack poseStack, int x, int y) {
+ super.renderTooltip(poseStack, x, y);
+ renderables.forEach(renderable -> {
+ if (renderable instanceof SmartGlassesSettingsSwitch smartGlassesSettingsSwitch) {
+ smartGlassesSettingsSwitch.renderTooltip(poseStack, x, y);
+ }
+ });
+ }
+
+ @Override
+ protected void renderLabels(@NotNull PoseStack poseStack, int x, int y) {
+ FormattedCharSequence formattedcharsequence = currentType.getName().getVisualOrderText();
+ this.font.draw(poseStack, formattedcharsequence, (212 + ComputerSidebar.WIDTH - (float) this.font.width(formattedcharsequence) / 2), 133, 4210752);
+ }
+
+ public void setCurrentType(SlotType currentType) {
+ this.currentType = currentType;
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/common/container/base/BaseItemScreen.java b/src/main/java/de/srendi/advancedperipherals/client/screens/base/BaseItemScreen.java
similarity index 73%
rename from src/main/java/de/srendi/advancedperipherals/common/container/base/BaseItemScreen.java
rename to src/main/java/de/srendi/advancedperipherals/client/screens/base/BaseItemScreen.java
index 527878f10..a7e7e9476 100644
--- a/src/main/java/de/srendi/advancedperipherals/common/container/base/BaseItemScreen.java
+++ b/src/main/java/de/srendi/advancedperipherals/client/screens/base/BaseItemScreen.java
@@ -1,16 +1,18 @@
-package de.srendi.advancedperipherals.common.container.base;
+package de.srendi.advancedperipherals.client.screens.base;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
+import de.srendi.advancedperipherals.common.container.base.BaseItemContainer;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
+import org.jetbrains.annotations.NotNull;
public abstract class BaseItemScreen extends AbstractContainerScreen {
- public BaseItemScreen(T screenContainer, Inventory inv, Component titleIn) {
+ protected BaseItemScreen(T screenContainer, Inventory inv, Component titleIn) {
super(screenContainer, inv, titleIn);
imageWidth = getSizeX();
@@ -18,14 +20,14 @@ public BaseItemScreen(T screenContainer, Inventory inv, Component titleIn) {
}
@Override
- public void render(PoseStack matrixStack, int x, int y, float partialTicks) {
+ public void render(@NotNull PoseStack matrixStack, int x, int y, float partialTicks) {
renderBackground(matrixStack);
super.render(matrixStack, x, y, partialTicks);
renderTooltip(matrixStack, x, y);
}
@Override
- protected void renderBg(PoseStack matrixStack, float partialTicks, int x, int y) {
+ protected void renderBg(@NotNull PoseStack matrixStack, float partialTicks, int x, int y) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, getTexture());
diff --git a/src/main/java/de/srendi/advancedperipherals/common/container/base/BaseScreen.java b/src/main/java/de/srendi/advancedperipherals/client/screens/base/BaseScreen.java
similarity index 86%
rename from src/main/java/de/srendi/advancedperipherals/common/container/base/BaseScreen.java
rename to src/main/java/de/srendi/advancedperipherals/client/screens/base/BaseScreen.java
index f9311435e..9390fa902 100644
--- a/src/main/java/de/srendi/advancedperipherals/common/container/base/BaseScreen.java
+++ b/src/main/java/de/srendi/advancedperipherals/client/screens/base/BaseScreen.java
@@ -1,7 +1,8 @@
-package de.srendi.advancedperipherals.common.container.base;
+package de.srendi.advancedperipherals.client.screens.base;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
+import de.srendi.advancedperipherals.common.container.base.BaseContainer;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
@@ -11,7 +12,7 @@
public abstract class BaseScreen extends AbstractContainerScreen {
- public BaseScreen(T screenContainer, Inventory inv, Component titleIn) {
+ protected BaseScreen(T screenContainer, Inventory inv, Component titleIn) {
super(screenContainer, inv, titleIn);
imageWidth = getSizeX();
imageHeight = getSizeY();
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayModuleLevelRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayModuleLevelRenderer.java
new file mode 100644
index 000000000..1a8aa23c2
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayModuleLevelRenderer.java
@@ -0,0 +1,115 @@
+package de.srendi.advancedperipherals.client.smartglasses;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.Tesselator;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import de.srendi.advancedperipherals.AdvancedPeripherals;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.client.smartglasses.objects.threedim.IThreeDObjectRenderer;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.ThreeDimensionalObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import de.srendi.advancedperipherals.common.util.EnumColor;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.client.renderer.RenderType;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
+import net.minecraft.world.inventory.InventoryMenu;
+import net.minecraft.world.phys.Vec3;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.client.event.RenderLevelStageEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.common.Mod;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.FORGE, modid = AdvancedPeripherals.MOD_ID)
+public class OverlayModuleLevelRenderer {
+
+ @SubscribeEvent
+ public static void renderLevelState(RenderLevelStageEvent event) {
+ PoseStack posestack = event.getPoseStack();
+ Vec3 view = Minecraft.getInstance().getEntityRenderDispatcher().camera.getPosition();
+
+ BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
+ if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) {
+ Map, List> batches = new HashMap<>();
+
+ for (RenderableObject object : OverlayObjectHolder.getObjects()) {
+ if (!object.isEnabled() || !(object.getRenderObject() instanceof IThreeDObjectRenderer))
+ continue;
+
+ ThreeDimensionalObject threeDimObject = (ThreeDimensionalObject) object;
+
+ Class extends ThreeDimensionalObject> objectClass = threeDimObject.getClass();
+
+ if (batches.containsKey(objectClass)) {
+ batches.get(objectClass).add(threeDimObject);
+ continue;
+ }
+
+ List newBatchArray = new ArrayList<>();
+ newBatchArray.add(threeDimObject);
+ batches.put(objectClass, newBatchArray);
+ }
+
+ for (List batch : batches.values()) {
+ ((IThreeDObjectRenderer) batch.get(0).getRenderObject()).renderBatch(batch, event, posestack, view, bufferbuilder);
+ }
+
+ //TODO Everything below here is just for debugging and testing. Will be removed before we push to production
+ BlockPos blockPos = new BlockPos(2, 100, 0);
+
+ float[] colors = EnumColor.DARK_PURPLE.getRgb();
+
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ bufferbuilder.begin(RenderType.translucent().mode(), DefaultVertexFormat.POSITION_COLOR_NORMAL);
+ posestack.pushPose();
+
+ posestack.translate(-view.x + blockPos.getX(), -view.y + blockPos.getY(), -view.z + blockPos.getZ());
+
+ RenderUtil.drawPlane(posestack, bufferbuilder, colors[0], colors[1], colors[2], 0.8f, Direction.UP, 0f, 0.5f, 0f, 0.5f, 0f, 1f);
+
+ BufferUploader.drawWithShader(bufferbuilder.end());
+ posestack.popPose();
+
+ VertexConsumer boxVertexConsumer = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(RenderType.entityCutout(InventoryMenu.BLOCK_ATLAS));
+ //RenderSystem.setShader(GameRenderer::getPositionColorLightmapShader);
+
+ //bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_LIGHTMAP);
+ posestack.pushPose();
+ colors = EnumColor.WHITE.getRgb();
+
+ blockPos = new BlockPos(0, 100, 0);
+ posestack.translate(-view.x + blockPos.getX(), -view.y + blockPos.getY(), -view.z + blockPos.getZ());
+
+ RenderUtil.drawSphere(posestack, boxVertexConsumer, 2f, 0f, 0f, 0f, 270f, 0f, 0f, colors[0], colors[1], colors[2], 0.4f, 16, 128);
+
+ //BufferUploader.drawWithShader(bufferbuilder.end());
+ posestack.popPose();
+
+ boxVertexConsumer = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(RenderType.entityCutout(InventoryMenu.BLOCK_ATLAS));
+
+ //bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_NORMAL);
+ posestack.pushPose();
+
+ colors = EnumColor.WHITE.getRgb();
+ blockPos = new BlockPos(6, 100, 0);
+ posestack.translate(-view.x + blockPos.getX(), -view.y + blockPos.getY(), -view.z + blockPos.getZ());
+
+ RenderUtil.drawTorus(posestack, boxVertexConsumer, 1f, 0.4f, 0f, 0f, 0f, 0f, 0f, 0f, colors[0], colors[1], colors[2], 1f, 48, 48);
+
+ //BufferUploader.drawWithShader(bufferbuilder.end());
+ posestack.popPose();
+
+ }
+ }
+
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayModuleOverlay.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayModuleOverlay.java
new file mode 100644
index 000000000..6ef3fab90
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayModuleOverlay.java
@@ -0,0 +1,56 @@
+package de.srendi.advancedperipherals.client.smartglasses;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import de.srendi.advancedperipherals.client.smartglasses.objects.twodim.ITwoDObjectRenderer;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.RectangleObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.TextObject;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+import net.minecraftforge.client.gui.overlay.IGuiOverlay;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class OverlayModuleOverlay implements IGuiOverlay {
+ public static final String ID = "overlay_module_overlay";
+
+ @Override
+ public void render(ForgeGui gui, PoseStack poseStack, float partialTick, int screenWidth, int screenHeight) {
+ poseStack.pushPose();
+
+ Map, List>> prioritizedBatches = new TreeMap<>();
+
+ for (RenderableObject object : OverlayObjectHolder.getObjects()) {
+ if (!object.isEnabled() || !(object.getRenderObject() instanceof ITwoDObjectRenderer)) {
+ continue;
+ }
+
+ // We need to sort the objects by their weight, some things can't be rendered before something else.
+ // For example, when texts are rendered before our circles, rectangles, etc., the other objects can't be transparent anymore
+ int weight = object.getRenderObject().getWeight();
+ Class extends RenderableObject> objectClass = object.getClass();
+
+ // Get or create the batch map for the current weight
+ Map, List> batchesForWeight = prioritizedBatches.computeIfAbsent(weight, k -> new HashMap<>());
+
+ List batch = batchesForWeight.computeIfAbsent(objectClass, k -> new ArrayList<>());
+
+ batch.add(object);
+ }
+
+ for (Map, List> batchesForWeight : prioritizedBatches.values()) {
+ for (List batch : batchesForWeight.values()) {
+
+ if (!batch.isEmpty()) {
+ ((ITwoDObjectRenderer) batch.get(0).getRenderObject()).renderBatch(batch, gui, poseStack, partialTick, screenWidth, screenHeight);
+ }
+ }
+ }
+ poseStack.popPose();
+
+ }
+
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayObjectHolder.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayObjectHolder.java
new file mode 100644
index 000000000..e319679fd
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/OverlayObjectHolder.java
@@ -0,0 +1,60 @@
+package de.srendi.advancedperipherals.client.smartglasses;
+
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.ObjectDecodeRegistry;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.BlockObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.BoxObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.SphereObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.TorusObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.CircleObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.ItemObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.LineObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.RectangleObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.TextObject;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Static holder for client side renderable objects - will change
+ */
+public class OverlayObjectHolder {
+
+ public static Map objects = new HashMap<>();
+
+ public static void addOrUpdateObject(RenderableObject object) {
+ objects.put(object.getId(), object);
+ }
+
+ public static void addOrUpdateObjects(Collection objects) {
+ for (RenderableObject renderableObject : objects) {
+ addOrUpdateObject(renderableObject);
+ }
+ }
+
+ public static void removeObject(int id) {
+ objects.remove(id);
+ }
+
+ public static Collection getObjects() {
+ return objects.values();
+ }
+
+ public static void clear() {
+ objects.clear();
+ }
+
+ public static void registerDecodeObjects() {
+ ObjectDecodeRegistry.register(RectangleObject.TYPE_ID, RectangleObject::decode);
+ ObjectDecodeRegistry.register(CircleObject.TYPE_ID, CircleObject::decode);
+ ObjectDecodeRegistry.register(TextObject.TYPE_ID, TextObject::decode);
+ ObjectDecodeRegistry.register(ItemObject.TYPE_ID, ItemObject::decode);
+ ObjectDecodeRegistry.register(LineObject.TYPE_ID, LineObject::decode);
+
+ ObjectDecodeRegistry.register(BoxObject.TYPE_ID, BoxObject::decode);
+ ObjectDecodeRegistry.register(BlockObject.TYPE_ID, BlockObject::decode);
+ ObjectDecodeRegistry.register(SphereObject.TYPE_ID, SphereObject::decode);
+ ObjectDecodeRegistry.register(TorusObject.TYPE_ID, TorusObject::decode);
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/IObjectRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/IObjectRenderer.java
new file mode 100644
index 000000000..aeefb36a9
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/IObjectRenderer.java
@@ -0,0 +1,13 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects;
+
+public interface IObjectRenderer {
+ /**
+ * Get the weight of the renderer. Lower weight means higher priority and it will render first.
+ * Some things need to be rendered before others to prevent color and opacity issues.
+ * @return the weight of the renderer.
+ */
+ default int getWeight() {
+ return 100;
+ }
+
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/BlockRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/BlockRenderer.java
new file mode 100644
index 000000000..152f9c3fe
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/BlockRenderer.java
@@ -0,0 +1,65 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.threedim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.math.Quaternion;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.BlockObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.ThreeDimensionalObject;
+import de.srendi.advancedperipherals.common.util.RegistryUtil;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.client.renderer.RenderType;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.phys.Vec3;
+import net.minecraftforge.client.event.RenderLevelStageEvent;
+import net.minecraftforge.registries.ForgeRegistries;
+
+import java.util.List;
+
+public class BlockRenderer implements IThreeDObjectRenderer {
+
+ @Override
+ public void renderBatch(List batch, RenderLevelStageEvent event, PoseStack poseStack, Vec3 view, BufferBuilder bufferBuilder) {
+ poseStack.pushPose();
+
+ for (ThreeDimensionalObject obj : batch) {
+ poseStack.pushPose();
+ onPreRender(obj);
+
+ bufferBuilder.begin(RenderType.solid().mode(), DefaultVertexFormat.BLOCK);
+
+ BlockObject block = (BlockObject) obj;
+
+ poseStack.translate(-view.x + block.getX(), -view.y + block.getY(), -view.z + block.getZ());
+ poseStack.mulPose(new Quaternion(block.rotX, block.rotY, block.rotZ, true));
+ poseStack.translate(-0.5f, -0.5f, -0.5f);
+ float alpha = block.opacity;
+ float red = RenderUtil.getRed(block.color);
+ float green = RenderUtil.getGreen(block.color);
+ float blue = RenderUtil.getBlue(block.color);
+
+ RenderSystem.setShader(GameRenderer::getBlockShader);
+ RenderSystem.setShaderColor(red, green, blue, alpha);
+
+ Block blockToRender = RegistryUtil.getRegistryEntry(block.block, ForgeRegistries.BLOCKS);
+ BlockPos blockPos = new BlockPos(obj.getX(), obj.getY(), obj.getZ());
+
+ if (blockToRender != null)
+ Minecraft.getInstance().getBlockRenderer().renderBatched(blockToRender.defaultBlockState(), blockPos, event.getCamera().getEntity().level, poseStack, bufferBuilder, false, event.getCamera().getEntity().level.random);
+
+ poseStack.popPose();
+ BufferUploader.drawWithShader(bufferBuilder.end());
+ onPostRender(obj);
+ RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
+ }
+
+
+ poseStack.popPose();
+
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/BoxRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/BoxRenderer.java
new file mode 100644
index 000000000..e773a6ec4
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/BoxRenderer.java
@@ -0,0 +1,47 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.threedim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexFormat;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.BoxObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.ThreeDimensionalObject;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.world.phys.Vec3;
+import net.minecraftforge.client.event.RenderLevelStageEvent;
+
+import java.util.List;
+
+public class BoxRenderer implements IThreeDObjectRenderer {
+
+ @Override
+ public void renderBatch(List batch, RenderLevelStageEvent event, PoseStack poseStack, Vec3 view, BufferBuilder bufferBuilder) {
+ poseStack.pushPose();
+
+ for (ThreeDimensionalObject obj : batch) {
+ poseStack.pushPose();
+ onPreRender(obj);
+ bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_NORMAL);
+
+ BoxObject box = (BoxObject) obj;
+
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ float alpha = box.opacity;
+ float red = RenderUtil.getRed(box.color);
+ float green = RenderUtil.getGreen(box.color);
+ float blue = RenderUtil.getBlue(box.color);
+
+ poseStack.translate(-view.x + box.getX(), -view.y + box.getY(), -view.z + box.getZ());
+ RenderUtil.drawBox(poseStack, bufferBuilder, red, green, blue, alpha, box.x, box.y, box.z, obj.rotX, obj.rotY, obj.rotZ, obj.maxX, obj.maxY, obj.maxZ);
+ BufferUploader.drawWithShader(bufferBuilder.end());
+ onPostRender(obj);
+
+ poseStack.popPose();
+ }
+
+ poseStack.popPose();
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/IThreeDObjectRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/IThreeDObjectRenderer.java
new file mode 100644
index 000000000..119277f6f
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/IThreeDObjectRenderer.java
@@ -0,0 +1,30 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.threedim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.PoseStack;
+import de.srendi.advancedperipherals.client.smartglasses.objects.IObjectRenderer;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.ThreeDimensionalObject;
+import net.minecraft.world.phys.Vec3;
+import net.minecraftforge.client.event.RenderLevelStageEvent;
+
+import java.util.List;
+
+public interface IThreeDObjectRenderer extends IObjectRenderer {
+
+ void renderBatch(List batch, RenderLevelStageEvent event, PoseStack poseStack, Vec3 view, BufferBuilder bufferBuilder);
+
+ default void onPostRender(ThreeDimensionalObject object) {
+ if (object.disableCulling)
+ RenderSystem.enableCull();
+ if (object.disableDepthTest)
+ RenderSystem.enableDepthTest();
+ }
+
+ default void onPreRender(ThreeDimensionalObject object) {
+ if (object.disableCulling)
+ RenderSystem.disableCull();
+ if (object.disableDepthTest)
+ RenderSystem.disableDepthTest();
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/SphereRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/SphereRenderer.java
new file mode 100644
index 000000000..71388a20e
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/SphereRenderer.java
@@ -0,0 +1,49 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.threedim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.SphereObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.ThreeDimensionalObject;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.client.renderer.RenderType;
+import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.world.phys.Vec3;
+import net.minecraftforge.client.event.RenderLevelStageEvent;
+
+import java.util.List;
+
+public class SphereRenderer implements IThreeDObjectRenderer {
+
+ @Override
+ public void renderBatch(List batch, RenderLevelStageEvent event, PoseStack poseStack, Vec3 view, BufferBuilder bufferBuilder) {
+ poseStack.pushPose();
+
+ for (ThreeDimensionalObject obj : batch) {
+ poseStack.pushPose();
+ onPreRender(obj);
+ VertexConsumer boxVertexConsumer = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(RenderType.entitySmoothCutout(TextureAtlas.LOCATION_BLOCKS));
+
+ SphereObject sphere = (SphereObject) obj;
+
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ float alpha = sphere.opacity;
+ float red = RenderUtil.getRed(sphere.color);
+ float green = RenderUtil.getRed(sphere.color);
+ float blue = RenderUtil.getRed(sphere.color);
+
+ poseStack.translate(-view.x, -view.y, -view.z);
+ RenderUtil.drawSphere(poseStack, boxVertexConsumer, sphere.radius, sphere.x, sphere.y, sphere.z, sphere.rotX, sphere.rotY, sphere.rotZ, red, green, blue, alpha, sphere.sectors, sphere.stacks);
+ onPostRender(obj);
+
+ poseStack.popPose();
+ }
+
+
+ poseStack.popPose();
+
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/TorusRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/TorusRenderer.java
new file mode 100644
index 000000000..7921b8a71
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/threedim/TorusRenderer.java
@@ -0,0 +1,47 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.threedim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexFormat;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.ThreeDimensionalObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.three_dim.TorusObject;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.world.phys.Vec3;
+import net.minecraftforge.client.event.RenderLevelStageEvent;
+
+import java.util.List;
+
+public class TorusRenderer implements IThreeDObjectRenderer {
+
+ @Override
+ public void renderBatch(List batch, RenderLevelStageEvent event, PoseStack poseStack, Vec3 view, BufferBuilder bufferBuilder) {
+ poseStack.pushPose();
+
+ for (ThreeDimensionalObject obj : batch) {
+ poseStack.pushPose();
+ onPreRender(obj);
+ bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_NORMAL);
+
+ TorusObject torus = (TorusObject) obj;
+
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ float alpha = torus.opacity;
+ float red = RenderUtil.getRed(torus.color);
+ float green = RenderUtil.getGreen(torus.color);
+ float blue = RenderUtil.getBlue(torus.color);
+
+ poseStack.translate(-view.x + torus.x, -view.y + torus.y, -view.z + torus.z);
+ RenderUtil.drawTorus(poseStack, bufferBuilder, torus.majorRadius, torus.minorRadius, 0, 0, 0, torus.rotX, torus.rotY, torus.rotZ, red, green, blue, alpha, torus.rings, torus.sides);
+ BufferUploader.drawWithShader(bufferBuilder.end());
+ onPostRender(obj);
+
+ poseStack.popPose();
+ }
+
+ poseStack.popPose();
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/CircleRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/CircleRenderer.java
new file mode 100644
index 000000000..5929b3e8e
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/CircleRenderer.java
@@ -0,0 +1,189 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.twodim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.Tesselator;
+import com.mojang.blaze3d.vertex.VertexFormat;
+import com.mojang.math.Matrix4f;
+import com.mojang.math.Quaternion;
+import com.mojang.math.Vector3f;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.CircleObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+
+import java.util.List;
+
+public class CircleRenderer implements ITwoDObjectRenderer {
+
+ @Override
+ public void renderBatch(List objects, ForgeGui gui, PoseStack poseStack, float partialTick, int screenWidth, int screenHeight) {
+ for (RenderableObject obj : objects) {
+
+ CircleObject circle = (CircleObject) obj;
+
+ float alpha = circle.opacity;
+ float red = RenderUtil.getRed(circle.color);
+ float green = RenderUtil.getGreen(circle.color);
+ float blue = RenderUtil.getBlue(circle.color);
+
+ drawCircle(poseStack, circle, red, green, blue, alpha);
+ }
+ }
+
+ public void drawCircle(PoseStack t, CircleObject circle, float red, float green, float blue, float alpha) {
+ float r = circle.radius;
+ float cx = circle.x;
+ float cy = circle.y;
+ float cz = circle.z;
+ float rotX = circle.rotX;
+ float rotY = circle.rotY;
+ float rotZ = circle.rotZ;
+ float borderWidth = circle.borderWidth;
+ int segments = circle.segments;
+
+ boolean isFilled = circle.filled;
+ boolean isPixelated = circle.pixelated;
+
+ PoseStack poseStack = new PoseStack();
+
+ poseStack.translate(cx, cy, cz);
+
+ poseStack.pushPose();
+
+ poseStack.mulPose(Vector3f.XP.rotationDegrees(rotX));
+ poseStack.mulPose(Vector3f.YP.rotationDegrees(rotY));
+ poseStack.mulPose(Vector3f.ZP.rotationDegrees(rotZ));
+
+ RenderSystem.disableCull();
+
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
+
+ Matrix4f matrix = poseStack.last().pose();
+
+ // Normal, smooth lines
+ if (!isPixelated) {
+ if (isFilled) {
+
+ bufferbuilder.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR);
+
+ bufferbuilder.vertex(matrix, 0, 0, 0f).color(red, green, blue, alpha).endVertex();
+
+ double angleStep = Math.PI * 2 / segments;
+
+ for (int i = 0; i <= segments; i++) {
+ double angle = i * angleStep;
+ double x = r * Math.sin(angle);
+ double y = r * Math.cos(angle);
+
+ bufferbuilder.vertex(matrix, (float) x, (float) y, 0).color(red, green, blue, alpha).endVertex();
+ }
+
+ } else {
+ float outerRadius = r;
+ float innerRadius = r - borderWidth;
+
+ bufferbuilder.begin(VertexFormat.Mode.TRIANGLE_STRIP, DefaultVertexFormat.POSITION_COLOR);
+
+ double angleStep = Math.PI * 2 / segments;
+
+ for (int i = 0; i <= segments; i++) {
+ double angle = i * angleStep;
+
+ // Outer circle vertex
+ double outerX = innerRadius * Math.sin(angle);
+ double outerY = innerRadius * Math.cos(angle);
+ bufferbuilder.vertex(matrix, (float) outerX, (float) outerY, 0f).color(red, green, blue, alpha).endVertex();
+
+ // Inner circle vertex
+ double innerX = outerRadius * Math.sin(angle);
+ double innerY = outerRadius * Math.cos(angle);
+ bufferbuilder.vertex(matrix, (float) innerX, (float) innerY, 0f).color(red, green, blue, alpha).endVertex();
+ }
+ }
+
+ BufferUploader.drawWithShader(bufferbuilder.end());
+
+ return;
+ }
+
+ // Pixelated lines
+ bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
+
+ final float PIXEL_SIZE = borderWidth; // Defines the size of each "pixel" square
+
+ // The thickness of the hollow line in terms of pixel units.
+ // A value of 1.0f means the line will be roughly one pixel thick.
+ final float LINE_THICKNESS_PIXELS = 1f;
+
+ // Calculate the effective min/max coordinates in the relative space
+ float effectiveMinX = -r - PIXEL_SIZE;
+ float effectiveMaxX = r + PIXEL_SIZE;
+ float effectiveMinY = -r - PIXEL_SIZE;
+ float effectiveMaxY = r + PIXEL_SIZE;
+
+// Start the loop at the first multiple of PIXEL_SIZE that is less than or equal to effectiveMinX/Y
+ float startX = (float) Math.floor(effectiveMinX / PIXEL_SIZE) * PIXEL_SIZE;
+ float startY = (float) Math.floor(effectiveMinY / PIXEL_SIZE) * PIXEL_SIZE;
+
+
+ for (float x = startX; x <= effectiveMaxX; x += PIXEL_SIZE) {
+ for (float y = startY; y <= effectiveMaxY; y += PIXEL_SIZE) {
+ // Calculate the center of the current pixel cell.
+ // This is where you determine if the *center* of this block should be drawn.
+ float pixelCenterX = x + (PIXEL_SIZE / 2.0F);
+ float pixelCenterY = y + (PIXEL_SIZE / 2.0F);
+
+ // Distance is calculated from (pixelCenterX, pixelCenterY) to (0,0)
+ double distanceToCenter = Math.sqrt(
+ Math.pow(pixelCenterX, 2) + Math.pow(pixelCenterY, 2)
+ );
+
+ boolean shouldDrawPixel;
+
+ if (!isFilled) {
+ float outerRadius = r + (LINE_THICKNESS_PIXELS * (PIXEL_SIZE / 2.0F));
+ float innerRadius = r - (LINE_THICKNESS_PIXELS * (PIXEL_SIZE / 2.0F));
+
+ if (innerRadius < 0) innerRadius = 0;
+
+ shouldDrawPixel = (distanceToCenter <= outerRadius) && (distanceToCenter >= innerRadius);
+ } else {
+ shouldDrawPixel = distanceToCenter <= r + (PIXEL_SIZE / 2.0F);
+ }
+
+ if (shouldDrawPixel) {
+ // Vertices for the QUAD (a PIXEL_SIZE x PIXEL_SIZE square)
+ // These coordinates are now relative to the current origin (0,0,0)
+ float p_x1 = x;
+ float p_y1 = y;
+ float p_z = 0f; // z-coordinate is relative to cz, so 0 in this space
+
+ float p_x2 = x + PIXEL_SIZE;
+ float p_y2 = y + PIXEL_SIZE;
+
+ // Vertices for the QUAD
+ // Ensure proper winding order (counter-clockwise for front face)
+ bufferbuilder.vertex(matrix, p_x1, p_y2, p_z).color(red, green, blue, alpha).endVertex(); // Bottom-left
+ bufferbuilder.vertex(matrix, p_x2, p_y2, p_z).color(red, green, blue, alpha).endVertex(); // Bottom-right
+ bufferbuilder.vertex(matrix, p_x2, p_y1, p_z).color(red, green, blue, alpha).endVertex(); // Top-right
+ bufferbuilder.vertex(matrix, p_x1, p_y1, p_z).color(red, green, blue, alpha).endVertex(); // Top-left
+ }
+ }
+ }
+
+ RenderSystem.enableCull();
+
+ BufferUploader.drawWithShader(bufferbuilder.end());
+
+
+ poseStack.popPose();
+
+ }
+}
+
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/ITwoDObjectRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/ITwoDObjectRenderer.java
new file mode 100644
index 000000000..543f3580c
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/ITwoDObjectRenderer.java
@@ -0,0 +1,14 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.twodim;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import de.srendi.advancedperipherals.client.smartglasses.objects.IObjectRenderer;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+
+import java.util.List;
+
+public interface ITwoDObjectRenderer extends IObjectRenderer {
+
+ void renderBatch(List object, ForgeGui gui, PoseStack poseStack, float partialTick, int screenWidth, int screenHeight);
+
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/ItemRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/ItemRenderer.java
new file mode 100644
index 000000000..6d2ff7ccb
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/ItemRenderer.java
@@ -0,0 +1,29 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.twodim;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.ItemObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import de.srendi.advancedperipherals.common.util.RegistryUtil;
+import net.minecraft.client.Minecraft;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+import net.minecraftforge.registries.ForgeRegistries;
+
+import java.util.List;
+
+public class ItemRenderer implements ITwoDObjectRenderer {
+
+ @Override
+ public void renderBatch(List objects, ForgeGui gui, PoseStack poseStack, float partialTick, int screenWidth, int screenHeight) {
+ Minecraft minecraft = Minecraft.getInstance();
+
+ for (RenderableObject obj : objects) {
+ Item renderItem = RegistryUtil.getRegistryEntry(((ItemObject) obj).item, ForgeRegistries.ITEMS);
+ if (renderItem == null)
+ continue;
+ minecraft.getItemRenderer().renderGuiItem(new ItemStack(renderItem), (int) obj.x, (int) obj.y);
+ }
+
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/LineRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/LineRenderer.java
new file mode 100644
index 000000000..71579398a
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/LineRenderer.java
@@ -0,0 +1,103 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.twodim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.Tesselator;
+import com.mojang.blaze3d.vertex.VertexFormat;
+import com.mojang.math.Matrix4f;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.LineObject;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+
+import java.util.List;
+
+public class LineRenderer implements ITwoDObjectRenderer {
+
+ @Override
+ public void renderBatch(List objects, ForgeGui gui, PoseStack poseStack, float partialTick, int screenWidth, int screenHeight) {
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
+ Matrix4f matrix = poseStack.last().pose();
+
+ for (RenderableObject obj : objects) {
+
+ LineObject line = (LineObject) obj;
+
+ float alpha = obj.opacity;
+ float red = RenderUtil.getRed(obj.color);
+ float green = RenderUtil.getGreen(obj.color);
+ float blue = RenderUtil.getBlue(obj.color);
+
+ // Start and end points of the line
+ float x1 = obj.x;
+ float y1 = obj.y;
+ float z1 = obj.z;
+
+ float x2 = obj.maxX;
+ float y2 = obj.maxY;
+ float z2 = obj.maxZ;
+
+ // Normal, smooth lines
+ if (!line.pixelated) {
+ bufferbuilder.begin(VertexFormat.Mode.DEBUG_LINE_STRIP, DefaultVertexFormat.POSITION_COLOR);
+ bufferbuilder.vertex(matrix, x1, y1, 0).color(red, green, blue, alpha).endVertex();
+ bufferbuilder.vertex(matrix, x2, y2, 0).color(red, green, blue, alpha).endVertex();
+ BufferUploader.drawWithShader(bufferbuilder.end());
+
+ continue; // Skip the rest of the loop for this object
+ }
+
+ // Pixelated lines
+ bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
+
+ // Calculate the delta for each axis
+ float dx = x2 - x1;
+ float dy = y2 - y1;
+ float dz = z2 - z1;
+
+ final float PIXEL_SIZE = line.pixelSize;
+
+ float maxDim = Math.max(Math.abs(dx), Math.max(Math.abs(dy), Math.abs(dz)));
+ int numPixels = (int) Math.ceil(maxDim / PIXEL_SIZE);
+
+ if (numPixels == 0) {
+ numPixels = 1; // Always draw at least one pixel for very short lines
+ }
+
+ // Iterate and draw a square for each "pixel"
+ for (int i = 0; i <= numPixels; i++) {
+ float t = (float) i / numPixels; // Interpolation factor (0.0 to 1.0)
+
+ // Calculate the exact point on the line
+ float currentX = x1 + dx * t;
+ float currentY = y1 + dy * t;
+ float currentZ = z1 + dz * t;
+
+ // Snap current point to the nearest pixel grid for consistent placement.
+ // This is key for placing pixels at corners or full side of each other.
+ currentX = Math.round(currentX / PIXEL_SIZE) * PIXEL_SIZE;
+ currentY = Math.round(currentY / PIXEL_SIZE) * PIXEL_SIZE;
+ currentZ = Math.round(currentZ / PIXEL_SIZE) * PIXEL_SIZE;
+
+ float p_x1 = currentX;
+ float p_y1 = currentY;
+ float p_z1 = currentZ;
+
+ float p_x2 = currentX + PIXEL_SIZE;
+ float p_y2 = currentY + PIXEL_SIZE;
+ float p_z2 = currentZ;
+
+ bufferbuilder.vertex(matrix, p_x1, p_y2, p_z1).color(red, green, blue, alpha).endVertex(); // Bottom-left
+ bufferbuilder.vertex(matrix, p_x2, p_y2, p_z1).color(red, green, blue, alpha).endVertex(); // Bottom-right
+ bufferbuilder.vertex(matrix, p_x2, p_y1, p_z2).color(red, green, blue, alpha).endVertex(); // Top-right
+ bufferbuilder.vertex(matrix, p_x1, p_y1, p_z2).color(red, green, blue, alpha).endVertex(); // Top-left
+ }
+ BufferUploader.drawWithShader(bufferbuilder.end());
+ }
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/RectangleRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/RectangleRenderer.java
new file mode 100644
index 000000000..55618cf74
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/RectangleRenderer.java
@@ -0,0 +1,60 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.twodim;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.BufferUploader;
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.Tesselator;
+import com.mojang.blaze3d.vertex.VertexFormat;
+import com.mojang.math.Matrix4f;
+import com.mojang.math.Vector3f;
+import de.srendi.advancedperipherals.client.RenderUtil;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+
+import java.util.List;
+
+public class RectangleRenderer implements ITwoDObjectRenderer {
+
+ @Override
+ public void renderBatch(List objects, ForgeGui gui, PoseStack ignored, float partialTick, int screenWidth, int screenHeight) {
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder();
+
+ bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
+
+ for (RenderableObject obj : objects) {
+ float rotX = obj.rotX;
+ float rotY = obj.rotY;
+ float rotZ = obj.rotZ;
+
+ PoseStack poseStack = new PoseStack();
+
+ poseStack.translate(obj.x, obj.y, obj.z);
+
+ poseStack.pushPose();
+
+ Matrix4f matrix = poseStack.last().pose();
+
+ poseStack.mulPose(Vector3f.XP.rotationDegrees(rotX));
+ poseStack.mulPose(Vector3f.YP.rotationDegrees(rotY));
+ poseStack.mulPose(Vector3f.ZP.rotationDegrees(rotZ));
+
+ float alpha = obj.opacity;
+ float red = RenderUtil.getRed(obj.color);
+ float green = RenderUtil.getGreen(obj.color);
+ float blue = RenderUtil.getBlue(obj.color);
+
+ bufferbuilder.vertex(matrix, 0, obj.maxY - obj.y, 0).color(red, green, blue, alpha).endVertex();
+ bufferbuilder.vertex(matrix, obj.maxX - obj.x, obj.maxY - obj.y, 0).color(red, green, blue, alpha).endVertex();
+ bufferbuilder.vertex(matrix, obj.maxX - obj.x, 0, 0).color(red, green, blue, alpha).endVertex();
+ bufferbuilder.vertex(matrix, 0, 0, 0).color(red, green, blue, alpha).endVertex();
+ poseStack.popPose();
+
+ }
+
+ BufferUploader.drawWithShader(bufferbuilder.end());
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/TextRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/TextRenderer.java
new file mode 100644
index 000000000..ecde02ad7
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/smartglasses/objects/twodim/TextRenderer.java
@@ -0,0 +1,55 @@
+package de.srendi.advancedperipherals.client.smartglasses.objects.twodim;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.math.Matrix4f;
+import com.mojang.math.Vector3f;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.RenderableObject;
+import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.TextObject;
+import net.minecraft.client.Minecraft;
+import net.minecraftforge.client.gui.overlay.ForgeGui;
+
+import java.util.List;
+
+public class TextRenderer implements ITwoDObjectRenderer {
+
+ @Override
+ public void renderBatch(List objects, ForgeGui gui, PoseStack ignored, float partialTick, int screenWidth, int screenHeight) {
+ Minecraft minecraft = Minecraft.getInstance();
+ for (RenderableObject obj : objects) {
+ TextObject text = (TextObject) obj;
+ float rotX = obj.rotX;
+ float rotY = obj.rotY;
+ float rotZ = obj.rotZ;
+
+ float x = text.x;
+
+ if (text.center) {
+ x -= (minecraft.font.width(text.content) * text.fontSize) / 2f;
+ }
+
+ PoseStack poseStack = new PoseStack();
+
+ poseStack.translate(x / text.fontSize, text.y / text.fontSize, obj.z);
+
+ poseStack.pushPose();
+
+ poseStack.mulPose(Vector3f.XP.rotationDegrees(rotX));
+ poseStack.mulPose(Vector3f.YP.rotationDegrees(rotY));
+ poseStack.mulPose(Vector3f.ZP.rotationDegrees(rotZ));
+
+ poseStack.scale(text.fontSize, text.fontSize, 1);
+
+ if (!text.shadow) {
+ minecraft.font.drawShadow(poseStack, text.content, 0, 0, text.color);
+ } else {
+ minecraft.font.draw(poseStack, text.content, 0, 0, text.color);
+ }
+ poseStack.popPose();
+ }
+ }
+
+ @Override
+ public int getWeight() {
+ return 110;
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/client/widgets/SmartGlassesSettingsSwitch.java b/src/main/java/de/srendi/advancedperipherals/client/widgets/SmartGlassesSettingsSwitch.java
new file mode 100644
index 000000000..a6ab0c0cc
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/client/widgets/SmartGlassesSettingsSwitch.java
@@ -0,0 +1,85 @@
+package de.srendi.advancedperipherals.client.widgets;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
+import dan200.computercraft.client.gui.widgets.ComputerSidebar;
+import de.srendi.advancedperipherals.AdvancedPeripherals;
+import de.srendi.advancedperipherals.client.screens.SmartGlassesScreen;
+import de.srendi.advancedperipherals.common.smartglasses.SlotType;
+import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesSlot;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.components.AbstractWidget;
+import net.minecraft.client.gui.narration.NarrationElementOutput;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.inventory.Slot;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+
+public class SmartGlassesSettingsSwitch extends AbstractWidget {
+
+ private static final ResourceLocation BACKGROUND = new ResourceLocation(AdvancedPeripherals.MOD_ID, "textures/gui/smart_glasses_gui.png");
+
+ private final SmartGlassesScreen screen;
+ private final SlotType type;
+ private boolean isEnabled;
+
+ public SmartGlassesSettingsSwitch(int x, int y, SlotType type, SmartGlassesScreen screen) {
+ super(screen.getGuiLeft() + x + ComputerSidebar.WIDTH, screen.getGuiTop() + y, 21, 22, type.getName());
+ this.screen = screen;
+ this.type = type;
+ this.isEnabled = type == SlotType.defaultType();
+ }
+
+ @Override
+ public void render(@NotNull PoseStack pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {
+ renderBg(pPoseStack, Minecraft.getInstance(), pMouseX, pMouseY);
+ }
+
+ @Override
+ public void renderButton(@NotNull PoseStack pPoseStack, int pMouseX, int pMouseY, float pPartialTick) {
+ // Disable rendering of default buttons
+ }
+
+ @Override
+ protected void renderBg(@NotNull PoseStack pPoseStack, @NotNull Minecraft pMinecraft, int pMouseX, int pMouseY) {
+ RenderSystem.setShaderTexture(0, BACKGROUND);
+ if (isEnabled) {
+ blit(pPoseStack, this.x - 3, this.y, 45, 217, 24, 22);
+ } else {
+ blit(pPoseStack, this.x, this.y, 23, 217, 21, 22);
+ }
+ }
+
+ @Override
+ public void onClick(double pMouseX, double pMouseY) {
+ if (this.isEnabled)
+ return;
+ for (Slot slot : screen.getMenu().slots) {
+ if (slot instanceof SmartGlassesSlot smartGlassesSlot) {
+ if (smartGlassesSlot.slotType == this.type) {
+ smartGlassesSlot.setEnabled(true);
+ continue;
+ }
+ smartGlassesSlot.setEnabled(false);
+ }
+ }
+ screen.renderables.forEach(renderable -> {
+ if (renderable instanceof SmartGlassesSettingsSwitch smartGlassesSettingsSwitch) {
+ smartGlassesSettingsSwitch.isEnabled = false;
+ }
+ });
+ screen.setCurrentType(this.type);
+ this.isEnabled = true;
+ }
+
+ public void renderTooltip(PoseStack poseStack, int x, int y) {
+ if (screen != null && isMouseOver(x, y))
+ screen.renderComponentTooltip(poseStack, Collections.singletonList(type.getName()), x, y);
+ }
+
+ @Override
+ public void updateNarration(@NotNull NarrationElementOutput pNarrationElementOutput) {
+
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/APAddons.java b/src/main/java/de/srendi/advancedperipherals/common/addons/APAddons.java
index c26e2652a..bdc4e4265 100644
--- a/src/main/java/de/srendi/advancedperipherals/common/addons/APAddons.java
+++ b/src/main/java/de/srendi/advancedperipherals/common/addons/APAddons.java
@@ -1,41 +1,72 @@
package de.srendi.advancedperipherals.common.addons;
import de.srendi.advancedperipherals.AdvancedPeripherals;
-import de.srendi.advancedperipherals.common.addons.refinedstorage.RefinedStorage;
+import de.srendi.advancedperipherals.common.addons.refinedstorage.RSApi;
+import de.srendi.advancedperipherals.common.addons.valkyrienskies.ValkyrienSkies;
+import net.minecraft.core.BlockPos;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.Level;
import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
+import top.theillusivec4.curios.api.CuriosApi;
+import top.theillusivec4.curios.api.SlotResult;
+import top.theillusivec4.curios.api.SlotTypeMessage;
+
+import java.util.List;
@Mod.EventBusSubscriber(modid = AdvancedPeripherals.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class APAddons {
- public static final String CURIOS_MODID = "curios";
- public static final String REFINEDSTORAGE_MODID = "refinedstorage";
- public static final String AE_THINGS_MODID = "ae2things";
public static final String AE_ADDITIONS_MODID = "ae2additions";
+ public static final String AE_THINGS_MODID = "ae2things";
+ public static final String APPLIEDENERGISTICS_MODID = "ae2";
public static final String APP_MEKANISTICS_MODID = "appmek";
+ public static final String BOTANIA_MODID = "botania";
+ public static final String CREATE_MODID = "create";
+ public static final String CURIOS_MODID = "curios";
+ public static final String DIMSTORAGE_MODID = "dimstorage";
+ public static final String MEKANISM_MODID = "mekanism";
+ public static final String POWAH_MODID = "powah";
+ public static final String REFINEDSTORAGE_MODID = "refinedstorage";
+ public static final String VALKYRIEN_SKIES_MODID = "valkyrienskies";
- public static boolean curiosLoaded;
- public static boolean refinedStorageLoaded;
- public static boolean aeThingsLoaded;
public static boolean aeAdditionsLoaded;
+ public static boolean aeThingsLoaded;
public static boolean appMekLoaded;
+ public static boolean appliedEnergisticsLoaded;
+ public static boolean botaniaLoaded;
+ public static boolean createLoaded;
+ public static boolean curiosLoaded;
+ public static boolean dimstorageLoaded;
+ public static boolean mekanismLoaded;
+ public static boolean powahLoaded;
+ public static boolean refinedStorageLoaded;
+ public static boolean vs2Loaded;
- private APAddons() {
- }
-
- public static void commonSetup() {
+ // Use static so these checks run as early as possible, so we can use them for our registries
+ static {
ModList modList = ModList.get();
- curiosLoaded = modList.isLoaded(CURIOS_MODID);
- refinedStorageLoaded = modList.isLoaded(REFINEDSTORAGE_MODID);
- aeThingsLoaded = modList.isLoaded(AE_THINGS_MODID);
aeAdditionsLoaded = modList.isLoaded(AE_ADDITIONS_MODID);
+ aeThingsLoaded = modList.isLoaded(AE_THINGS_MODID);
appMekLoaded = modList.isLoaded(APP_MEKANISTICS_MODID);
+ appliedEnergisticsLoaded = modList.isLoaded(APPLIEDENERGISTICS_MODID);
+ botaniaLoaded = modList.isLoaded(BOTANIA_MODID);
+ createLoaded = modList.isLoaded(CREATE_MODID);
+ curiosLoaded = modList.isLoaded(CURIOS_MODID);
+ dimstorageLoaded = modList.isLoaded(DIMSTORAGE_MODID);
+ mekanismLoaded = modList.isLoaded(MEKANISM_MODID);
+ powahLoaded = modList.isLoaded(POWAH_MODID);
+ refinedStorageLoaded = modList.isLoaded(REFINEDSTORAGE_MODID);
+ vs2Loaded = modList.isLoaded(VALKYRIEN_SKIES_MODID);
- if (refinedStorageLoaded)
- RefinedStorage.instance = new RefinedStorage();
-
+ if (refinedStorageLoaded) {
+ RSApi.instance = new RSApi();
+ }
}
@SubscribeEvent
@@ -43,6 +74,27 @@ public static void interModComms(InterModEnqueueEvent event) {
if (!curiosLoaded)
return;
- // InterModComms.sendTo("curios", SlotTypeMessage.REGISTER_TYPE, () -> new SlotTypeMessage.Builder("glasses").size(1).build());
+ InterModComms.sendTo(CURIOS_MODID, SlotTypeMessage.REGISTER_TYPE,
+ () -> new SlotTypeMessage.Builder("glasses")
+ .size(1)
+ .icon(new ResourceLocation(AdvancedPeripherals.MOD_ID, "slot/empty_glasses_slot"))
+ .build());
+ }
+
+ public static ItemStack getCurioGlasses(Player player) {
+ if (!curiosLoaded)
+ return ItemStack.EMPTY;
+ List curioSlots = CuriosApi.getCuriosHelper().findCurios(player, "glasses");
+ if (curioSlots.isEmpty())
+ return ItemStack.EMPTY;
+
+ return curioSlots.get(0).stack();
+ }
+
+ public static boolean isBlockOnShip(Level level, BlockPos pos) {
+ if (!vs2Loaded) {
+ return false;
+ }
+ return ValkyrienSkies.isBlockOnShip(level, pos);
}
}
diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AE2Registries.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AE2Registries.java
new file mode 100644
index 000000000..b4759df1d
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AE2Registries.java
@@ -0,0 +1,42 @@
+package de.srendi.advancedperipherals.common.addons.ae2;
+
+import appeng.api.features.P2PTunnelAttunement;
+import appeng.api.parts.IPart;
+import appeng.api.parts.IPartItem;
+import appeng.api.parts.PartModels;
+import appeng.items.parts.PartItem;
+import appeng.items.parts.PartModelsHelper;
+import dan200.computercraft.shared.Registry.ModItems;
+import de.srendi.advancedperipherals.common.setup.APRegistration;
+import net.minecraft.data.tags.TagsProvider;
+import net.minecraft.tags.TagKey;
+import net.minecraft.world.item.Item;
+import net.minecraftforge.registries.RegistryObject;
+
+import java.util.function.Function;
+
+public final class AE2Registries {
+ private AE2Registries() {}
+
+ public static final RegistryObject> CABLE_P2P_TUNNEL = registerPart("cable_p2p_tunnel", WiredCableP2PTunnelPart.class, WiredCableP2PTunnelPart::new);
+
+ private static RegistryObject> registerPart(String id, Class clazz, Function, T> factory) {
+ PartModels.registerModels(PartModelsHelper.createModels(clazz));
+ return APRegistration.ITEMS.register(id, () -> new PartItem<>(new Item.Properties(), clazz, factory));
+ }
+
+ public static void finishRegister() {
+ P2PTunnelAttunement.registerAttunementTag(CABLE_P2P_TUNNEL.get());
+ }
+
+ public static TagKey- getCableP2PTag() {
+ return P2PTunnelAttunement.getAttunementTag(CABLE_P2P_TUNNEL.get());
+ }
+
+ public static void registerTags(Function, TagsProvider.TagAppender
- > tagger) {
+ tagger.apply(getCableP2PTag())
+ .add(ModItems.CABLE.get())
+ .add(ModItems.WIRED_MODEM.get())
+ .add(ModItems.WIRED_MODEM_FULL.get());
+ }
+}
diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AEApi.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AEApi.java
new file mode 100644
index 000000000..51958de66
--- /dev/null
+++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AEApi.java
@@ -0,0 +1,961 @@
+package de.srendi.advancedperipherals.common.addons.ae2;
+
+import appeng.api.crafting.IPatternDetails;
+import appeng.api.inventories.InternalInventory;
+import appeng.api.networking.IGrid;
+import appeng.api.networking.IGridNode;
+import appeng.api.networking.crafting.CraftingJobStatus;
+import appeng.api.networking.crafting.ICraftingCPU;
+import appeng.api.networking.crafting.ICraftingService;
+import appeng.api.networking.storage.IStorageService;
+import appeng.api.stacks.AEFluidKey;
+import appeng.api.stacks.AEItemKey;
+import appeng.api.stacks.AEKey;
+import appeng.api.stacks.AEKeyType;
+import appeng.api.stacks.GenericStack;
+import appeng.api.stacks.KeyCounter;
+import appeng.api.storage.AEKeyFilter;
+import appeng.api.storage.IStorageProvider;
+import appeng.api.storage.MEStorage;
+import appeng.api.storage.cells.IBasicCellItem;
+import appeng.blockentity.storage.DriveBlockEntity;
+import appeng.crafting.execution.CraftingCpuLogic;
+import appeng.crafting.pattern.EncodedPatternItem;
+import appeng.helpers.iface.PatternContainer;
+import appeng.items.storage.BasicStorageCell;
+import appeng.me.cells.BasicCellHandler;
+import appeng.me.cells.BasicCellInventory;
+import appeng.me.cluster.implementations.CraftingCPUCluster;
+import appeng.parts.storagebus.StorageBusPart;
+import com.the9grounds.aeadditions.item.storage.StorageCell;
+import com.the9grounds.aeadditions.item.storage.SuperStorageCell;
+import de.srendi.advancedperipherals.AdvancedPeripherals;
+import de.srendi.advancedperipherals.common.addons.APAddons;
+import de.srendi.advancedperipherals.common.util.LuaConverter;
+import de.srendi.advancedperipherals.common.util.Pair;
+import de.srendi.advancedperipherals.common.util.inventory.FluidFilter;
+import de.srendi.advancedperipherals.common.util.inventory.GenericFilter;
+import de.srendi.advancedperipherals.common.util.inventory.ItemFilter;
+import io.github.projectet.ae2things.item.DISKDrive;
+import it.unimi.dsi.fastutil.objects.Object2LongMap;
+import me.ramidzkh.mekae2.ae2.MekanismKey;
+import me.ramidzkh.mekae2.ae2.MekanismKeyType;
+import me.ramidzkh.mekae2.item.ChemicalStorageCell;
+import mekanism.api.chemical.merged.MergedChemicalTank;
+import mekanism.common.tile.TileEntityChemicalTank;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraftforge.common.capabilities.ForgeCapabilities;
+import net.minecraftforge.common.util.LazyOptional;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.capability.IFluidHandler;
+import net.minecraftforge.items.IItemHandler;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class AEApi {
+
+ public static Pair findAEStackFromStack(MEStorage monitor, @Nullable ICraftingService crafting, ItemStack item) {
+ return findAEStackFromFilter(monitor, crafting, ItemFilter.fromStack(item));
+ }
+
+ public static Pair findAEStackFromFilter(MEStorage monitor, @Nullable ICraftingService crafting, ItemFilter item) {
+ for (Object2LongMap.Entry temp : monitor.getAvailableStacks()) {
+ if (temp.getKey() instanceof AEItemKey key && item.test(key.toStack()))
+ return Pair.of(temp.getLongValue(), key);
+ }
+
+ if (crafting == null)
+ return Pair.of(0L, AEItemKey.of(ItemStack.EMPTY));
+
+ for (var temp : crafting.getCraftables(param -> true)) {
+ if (temp instanceof AEItemKey key && item.test(key.toStack()))
+ return Pair.of(0L, key);
+ }
+
+ return Pair.of(0L, AEItemKey.of(ItemStack.EMPTY));
+ }
+
+ public static Pair findAEFluidFromStack(MEStorage monitor, @Nullable ICraftingService crafting, FluidStack item) {
+ return findAEFluidFromFilter(monitor, crafting, FluidFilter.fromStack(item));
+ }
+
+ public static Pair findAEFluidFromFilter(MEStorage monitor, @Nullable ICraftingService crafting, FluidFilter item) {
+ for (Object2LongMap.Entry temp : monitor.getAvailableStacks()) {
+ if (temp.getKey() instanceof AEFluidKey key && item.test(key.toStack(1)))
+ return Pair.of(temp.getLongValue(), key);
+ }
+
+ if (crafting == null)
+ return Pair.of(0L, AEFluidKey.of(FluidStack.EMPTY));
+
+ for (var temp : crafting.getCraftables(param -> true)) {
+ if (temp instanceof AEFluidKey key && item.test(key.toStack(1)))
+ return Pair.of(0L, key);
+ }
+
+ return Pair.of(0L, AEFluidKey.of(FluidStack.EMPTY));
+ }
+
+ /**
+ * Finds a pattern from filters.
+ *
+ * @param grid The grid to search patterns from.
+ * @param level The level of the grid.
+ * @param inputFilter The input filter to apply, can be null to ignore input filter.
+ * @param outputFilter The output filter to apply, can be null to ignore output filter.
+ * @return A Pair object containing the matched pattern and an error message if no pattern is found.
+ * The pattern can be null if no pattern is found.
+ * The error message is "NO_PATTERN_FOUND" if no pattern is found.
+ */
+ public static Pair findPatternFromFilters(IGrid grid, Level level, @Nullable GenericFilter inputFilter, @Nullable GenericFilter outputFilter) {
+ for (IPatternDetails pattern : getPatterns(grid, level)) {
+ if (pattern.getInputs().length == 0)
+ continue;
+ if (pattern.getOutputs().length == 0)
+ continue;
+
+ boolean inputMatch = false;
+ boolean outputMatch = false;
+
+ if (inputFilter != null) {
+ outerLoop:
+ for (IPatternDetails.IInput input : pattern.getInputs()) {
+ for (GenericStack possibleInput : input.getPossibleInputs()) {
+ if (inputFilter.testAE(possibleInput)) {
+ inputMatch = true;
+ break outerLoop;
+ }
+ }
+ }
+ } else {
+ inputMatch = true;
+ }
+
+ if (outputFilter != null) {
+ for (GenericStack output : pattern.getOutputs()) {
+ if (outputFilter.testAE(output)) {
+ outputMatch = true;
+ break;
+ }
+ }
+ } else {
+ outputMatch = true;
+ }
+
+ if (inputMatch && outputMatch)
+ return Pair.of(pattern, null);
+ }
+
+ return Pair.of(null, "NO_PATTERN_FOUND");
+ }
+
+
+ public static List