diff --git a/build.gradle b/build.gradle index 647b8a371..93366c8b5 100644 --- a/build.gradle +++ b/build.gradle @@ -201,12 +201,12 @@ repositories { } } maven { - name = "Modmaven Jei" + name = "Modmaven" url = 'https://modmaven.dev/' content { - includeGroup("mezz.jei") includeGroup("appeng") includeGroup("mekanism") + includeGroup("mezz.jei") } } maven { @@ -376,20 +376,15 @@ dependencies { // runtimeOnly fg.deobf("curse.maven:createaddition-439890:5099757") // Valkyrien Skies 2 - implementation("org.joml:joml:1.10.4") { - transitive = false - } - implementation("org.joml:joml-primitives:1.10.0") { - transitive = false - } - // implementation fg.deobf("org.valkyrienskies:valkyrienskies-119-common:${vs2_version}") - implementation fg.deobf("org.valkyrienskies:valkyrienskies-119-forge:${vs2_version}") { - transitive = false - } + 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}") 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}") 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}") @@ -427,12 +422,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 diff --git a/gradle.properties b/gradle.properties index f4735631c..93e3534e5 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 @@ -10,53 +10,57 @@ mod_id=advancedperipherals mod_version=0.8r minecraft_version=1.19.2 mod_artifact_suffix= + forge_version=43.4.0 loader_version=43 + release_type=release + mappings_channel=parchment mappings_version=2022.11.20-1.19.2 -jb_annotations=21.0.1 # 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.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.9 -patchouli_version=1.19.2-77 -refinedstorage_version=1.11.7 + +ae2additions_version=4646599 +ae2things_version=4367610 +appliedenergistics_version=12.9.12 +appliedmekanistics_version=4734608 botania_version=1.19.2-440-FORGE +clockwork_version=5171528 create_version=0.5.1.f-46 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 -dimstorage_version=3927875 +refinedstorage_version=1.11.7 valkyrien_skies_version=4994898 -eureka_ships_version=5321628 -clockwork_version=5171528 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) +# Mod dependencies for testing stuff (Only used in the dev environment) +jade_version=4914105 jei_version=1.19.2-forge:11.6.0.1016 -jade_version=4914105 \ No newline at end of file diff --git a/src/generated/resources/.cache/03e4de26f1265135874f8cdcaebc09d9c08eb42b b/src/generated/resources/.cache/03e4de26f1265135874f8cdcaebc09d9c08eb42b index 559ba3090..9c274278b 100644 --- a/src/generated/resources/.cache/03e4de26f1265135874f8cdcaebc09d9c08eb42b +++ b/src/generated/resources/.cache/03e4de26f1265135874f8cdcaebc09d9c08eb42b @@ -1,2 +1,3 @@ -// 1.19.2 2024-05-28T14:53:16.653667 Tags for minecraft:item +// 1.19.2 2025-03-15T16:18:50.46663 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 fe56a6ce0..8e30d22ee 100644 --- a/src/generated/resources/.cache/2db41954e490230d51b10affff25ee2ee27b8d5b +++ b/src/generated/resources/.cache/2db41954e490230d51b10affff25ee2ee27b8d5b @@ -1,2 +1,2 @@ -// 1.19.2 2024-05-28T14:53:16.655175 AP POI Type Tags +// 1.19.2 2025-03-15T16:18:50.465796 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 bc70b7af4..5483d6bb3 100644 --- a/src/generated/resources/.cache/5a761efb7472ef97566e41e81451930a004134bf +++ b/src/generated/resources/.cache/5a761efb7472ef97566e41e81451930a004134bf @@ -1,4 +1,4 @@ -// 1.19.2 2024-05-28T14:53:16.655476 Turtle Upgrades +// 1.19.2 2025-03-15T16:18:50.466321 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 diff --git a/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2 b/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2 index 27846ef32..ca3f6253d 100644 --- a/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2 +++ b/src/generated/resources/.cache/67cce32b1c3cbbcb1f646605f4914e3f196986c2 @@ -1,4 +1,4 @@ -// 1.19.2 2024-09-23T21:28:44.4809605 LootTables +// 1.19.2 2025-03-15T16:18:50.465594 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 diff --git a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e index c4a79999b..5b054c33c 100644 --- a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e +++ b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e @@ -1,4 +1,4 @@ -// 1.19.2 2024-05-28T14:53:16.657381 Recipes +// 1.19.2 2025-03-15T16:18:50.466743 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 diff --git a/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c b/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c index 8fe8c2d79..4a3bf0dbb 100644 --- a/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c +++ b/src/generated/resources/.cache/ae219fa7c7d3297c14e454863eac3998a4eab78c @@ -1,6 +1,7 @@ -// 1.19.2 2024-05-28T14:53:16.655934 Pocket Computer Upgrades +// 1.19.2 2025-03-15T16:18:50.46512 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 01ccc33ab..005d0e248 100644 --- a/src/generated/resources/.cache/b8526e444ae7356037f3a813274f6835d1f3dd16 +++ b/src/generated/resources/.cache/b8526e444ae7356037f3a813274f6835d1f3dd16 @@ -1,4 +1,4 @@ -// 1.19.2 2024-05-28T14:53:16.658228 Block States: advancedperipherals +// 1.19.2 2025-03-15T16:18:50.466039 Block States: advancedperipherals 5e28ce1be9a6996d982641e5df1fa7162090b8cc assets/advancedperipherals/blockstates/block_reader.json f42bdde60f84fdb312f7cf3b2be461d9c11ebdc8 assets/advancedperipherals/blockstates/chat_box.json 1227aa092fcf1327547ace6ccc9db230e45891b0 assets/advancedperipherals/blockstates/colony_integrator.json diff --git a/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 index 752d0ed46..577e18447 100644 --- a/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 +++ b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 @@ -1,2 +1,2 @@ -// 1.19.2 2025-01-18T00:08:46.0946621 Languages: en_us -d4cb5d2a7d78fc44e503663eb08d67a0fb981deb assets/advancedperipherals/lang/en_us.json +// 1.19.2 2025-03-15T16:18:50.465918 Languages: en_us +fe52123263b91f49093d74278e8709484e4dfe59 assets/advancedperipherals/lang/en_us.json diff --git a/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218 b/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218 index 872307de5..032d093dc 100644 --- a/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218 +++ b/src/generated/resources/.cache/f95c7003282837dabaa33e3ffceec4e6865b5218 @@ -1,4 +1,4 @@ -// 1.19.2 2025-01-16T15:46:41.859383 Block tags +// 1.19.2 2025-03-15T16:18:50.466493 Block tags e1f71dcb4f9e7e36e29b0ad09d6520dc3adfa4a6 data/forge/tags/blocks/needs_wood_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/lang/en_us.json b/src/generated/resources/assets/advancedperipherals/lang/en_us.json index 6f3d51a81..9a61a7d44 100644 --- a/src/generated/resources/assets/advancedperipherals/lang/en_us.json +++ b/src/generated/resources/assets/advancedperipherals/lang/en_us.json @@ -34,6 +34,7 @@ "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", @@ -81,6 +82,7 @@ "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", 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/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/forge/tags/blocks/needs_wood_tool.json b/src/generated/resources/data/forge/tags/blocks/needs_wood_tool.json index 0578bfe7e..ffd23c4b9 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,6 +1,5 @@ { "values": [ - "advancedperipherals:peripheral_casing", - "advancedperipherals:colony_integrator" + "advancedperipherals:peripheral_casing" ] } \ No newline at end of file diff --git a/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java b/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java index 615c49195..8f7a80ffd 100644 --- a/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java +++ b/src/main/java/de/srendi/advancedperipherals/AdvancedPeripherals.java @@ -1,6 +1,7 @@ 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.network.APNetworking; import de.srendi.advancedperipherals.common.setup.APRegistration; @@ -11,6 +12,7 @@ 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; @@ -35,6 +37,7 @@ public AdvancedPeripherals() { APConfig.register(ModLoadingContext.get()); modBus.addListener(this::commonSetup); + modBus.addListener(this::onLoadComplete); APRegistration.register(); MinecraftForge.EVENT_BUS.register(this); new APAddons(); @@ -67,4 +70,11 @@ public void commonSetup(FMLCommonSetupEvent event) { }); } + 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 index 8b3d01dac..0dfeb5c28 100644 --- a/src/main/java/de/srendi/advancedperipherals/client/ClientEventSubscriber.java +++ b/src/main/java/de/srendi/advancedperipherals/client/ClientEventSubscriber.java @@ -31,13 +31,14 @@ public static void renderingHuds(RenderGuiOverlayEvent.Pre event) { @SubscribeEvent public static void playerTryDismount(InputEvent.Key event) { Minecraft minecraft = Minecraft.getInstance(); - if (!minecraft.options.keyShift.matches(event.getKey(), event.getScanCode())) { + 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.isPlayerMountedOnTurtle()) { + if (ClientRegistry.SADDLE_TURTLE_OVERLAY.isPlayerControllingTurtle()) { minecraft.options.keyShift.setDown(false); } break; @@ -65,7 +66,7 @@ public static void playerMounting(EntityMountEvent event) { @SubscribeEvent public static void playerMove(MovementInputUpdateEvent event) { - if (ClientRegistry.SADDLE_TURTLE_OVERLAY.isPlayerMountedOnTurtle()) { + 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) { diff --git a/src/main/java/de/srendi/advancedperipherals/client/ClientWorker.java b/src/main/java/de/srendi/advancedperipherals/client/ClientWorker.java new file mode 100644 index 000000000..f29e94db7 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/client/ClientWorker.java @@ -0,0 +1,34 @@ +package de.srendi.advancedperipherals.client; + +import de.srendi.advancedperipherals.AdvancedPeripherals; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Mod.EventBusSubscriber(value = Dist.CLIENT, modid = AdvancedPeripherals.MOD_ID) +public class ClientWorker { + + private static final Map tasks = new ConcurrentHashMap<>(); + + /** + * This method will put a task to current tick's end. + * If a task with given identifier is already exists, the task will be replaced. + */ + public static void put(final String id, final Runnable task) { + tasks.put(id, task); + } + + @SubscribeEvent + public static void clientTick(TickEvent.ClientTickEvent event) { + if (event.phase == TickEvent.Phase.END) { + tasks.forEach((id, runnable) -> { + tasks.remove(id, runnable); + runnable.run(); + }); + } + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java index 8c571b8f5..a0b6f8a7c 100644 --- a/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java +++ b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java @@ -28,7 +28,7 @@ public DistanceDetectorRenderer(BlockEntityRendererProvider.Context pContext) { @Override public void render(@NotNull DistanceDetectorEntity pBlockEntity, float pPartialTick, @NotNull PoseStack pPoseStack, MultiBufferSource pBufferSource, int pPackedLight, int pPackedOverlay) { - if (pBlockEntity.getLaserVisibility()) { + if (pBlockEntity.getShowLaser()) { float distance = pBlockEntity.getCurrentDistance(); float[] color = EnumColor.RED.getRgb(); if (distance == -1) { diff --git a/src/main/java/de/srendi/advancedperipherals/client/screens/KeyboardScreen.java b/src/main/java/de/srendi/advancedperipherals/client/screens/KeyboardScreen.java index ff0fea7f5..fb6cd7ad1 100644 --- a/src/main/java/de/srendi/advancedperipherals/client/screens/KeyboardScreen.java +++ b/src/main/java/de/srendi/advancedperipherals/client/screens/KeyboardScreen.java @@ -1,16 +1,23 @@ package de.srendi.advancedperipherals.client.screens; +import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.vertex.PoseStack; import dan200.computercraft.client.gui.ClientInputHandler; import dan200.computercraft.client.gui.widgets.WidgetTerminal; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.computer.core.InputHandler; -import de.srendi.advancedperipherals.client.screens.base.BaseScreen; +import de.srendi.advancedperipherals.client.ClientWorker; import de.srendi.advancedperipherals.common.container.KeyboardContainer; +import de.srendi.advancedperipherals.common.network.APNetworking; +import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseClickPacket; +import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseMovePacket; +import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseScrollPacket; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.MenuAccess; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; @@ -20,21 +27,36 @@ *

* We just create a terminal which is used to forward all the key presses and mouse clicks but we don't render it. */ -public class KeyboardScreen extends BaseScreen { +public class KeyboardScreen extends Screen implements MenuAccess { + protected final KeyboardContainer keyboardContainer; protected final InputHandler input; private final Terminal terminalData; - private WidgetTerminal terminal; + private MouseState mouseState = MouseState.RELEASED; + private boolean captureMouse; + private boolean regrabingMouse; + private byte[] lastPosLock = new byte[0]; + private double lastX = 0; + private double lastY = 0; + private double lastScroll = 0; + + public KeyboardScreen(KeyboardContainer keyboardContainer, Inventory inv, Component titleIn) { + super(titleIn); + this.keyboardContainer = keyboardContainer; + this.input = new ClientInputHandler(keyboardContainer); + this.terminalData = new Terminal(0, 0, false); + } - public KeyboardScreen(KeyboardContainer screenContainer, Inventory inv, Component titleIn) { - super(screenContainer, inv, titleIn); - input = new ClientInputHandler(menu); - terminalData = new Terminal(0, 0, false); + @Override + public KeyboardContainer getMenu() { + return this.keyboardContainer; } @Override public void render(@NotNull PoseStack poseStack, int x, int y, float partialTicks) { + super.render(poseStack, x, y, partialTicks); + Minecraft minecraft = Minecraft.getInstance(); float scale = 2f; int screenWidth = minecraft.getWindow().getGuiScaledWidth(); @@ -50,48 +72,96 @@ public void render(@NotNull PoseStack poseStack, int x, int y, float partialTick @Override protected void init() { - passEvents = true; + if (this.isCapturingMouse()) { + this.grabMouse(); + } else { + this.grabMouseWithControl(); + } + this.passEvents = true; KeyMapping.releaseAll(); super.init(); - minecraft.keyboardHandler.setSendRepeatsToGui(true); + this.minecraft.keyboardHandler.setSendRepeatsToGui(true); - terminal = addWidget(new WidgetTerminal(terminalData, new ClientInputHandler(menu), 0, 0)); - terminal.visible = false; - terminal.active = false; - setFocused(terminal); + this.terminal = addWidget(new WidgetTerminal(terminalData, new ClientInputHandler(this.keyboardContainer), 0, 0)); + this.terminal.visible = false; + this.terminal.active = false; + setFocused(this.terminal); } - @Override - protected void renderBg(@NotNull PoseStack matrixStack, float partialTicks, int x, int y) { + public final void removed() { + if (this.regrabingMouse) { + return; + } + super.removed(); + this.minecraft.keyboardHandler.setSendRepeatsToGui(false); } @Override - public void renderBackground(@NotNull PoseStack pPoseStack) { + public void onClose() { + // Don't allow closing using standard keys like E. Closing using ESCAPE is still possible due to the keyPressed method } + @Override + public boolean isPauseScreen() { + return false; + } @Override - public final void removed() { - super.removed(); - minecraft.keyboardHandler.setSendRepeatsToGui(false); + public void mouseMoved(double x, double y) { + if (this.mouseState != MouseState.CAPTURE) { + return; + } + ClientWorker.put("mouse_move", () -> { + synchronized (this.lastPosLock) { + double dx = x - this.lastX; + double dy = y - this.lastY; + APNetworking.sendToServer(new KeyboardMouseMovePacket(dx, dy)); + this.lastX = x; + this.lastY = y; + } + }); } @Override - public boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) { - minecraft.player.getInventory().swapPaint(pDelta); - return super.mouseScrolled(pMouseX, pMouseY, pDelta); + public boolean mouseClicked(double x, double y, int button) { + if (this.mouseState != MouseState.CAPTURE) { + return false; + } + APNetworking.sendToServer(new KeyboardMouseClickPacket(button, false)); + return true; } @Override - public void onClose() { - // Don't allow closing using standard keys like E. Closing using ESCAPE is still possible due to the keyPressed method + public boolean mouseReleased(double x, double y, int button) { + if (this.mouseState != MouseState.CAPTURE) { + return false; + } + APNetworking.sendToServer(new KeyboardMouseClickPacket(button, true)); + return true; } @Override - public boolean isPauseScreen() { - return false; + public boolean mouseScrolled(double x, double y, double direction) { + this.lastScroll += direction; + int scrolled = (int) this.lastScroll; + if (scrolled == 0) { + return true; + } + if (this.mouseState == MouseState.CAPTURE) { + ClientWorker.put("mouse_scroll", () -> { + if (this.mouseState != MouseState.CAPTURE) { + return; + } + this.lastScroll -= scrolled; + APNetworking.sendToServer(new KeyboardMouseScrollPacket(scrolled)); + }); + } else { + this.lastScroll -= scrolled; + minecraft.player.getInventory().swapPaint(scrolled); + } + return true; } @Override @@ -108,19 +178,62 @@ public final boolean keyPressed(int key, int scancode, int modifiers) { return super.keyPressed(key, scancode, modifiers); } - // We prevent jei by increasing the image size, even if we don't render it - @Override - public int getSizeX() { - return 4096; + public boolean isCapturingMouse() { + return this.captureMouse; } - @Override - public int getSizeY() { - return 4096; + public void setCaptureMouse(boolean enable) { + this.captureMouse = enable; + if (enable) { + this.grabMouse(); + } else { + this.grabMouseWithControl(); + } } - @Override - public ResourceLocation getTexture() { - return null; + private void grabMouseWithControl() { + if (this.mouseState == MouseState.NORMAL) { + return; + } + this.releaseMouse(); + this.regrabingMouse = true; + this.minecraft.mouseHandler.grabMouse(); + this.regrabingMouse = false; + this.minecraft.screen = this; + this.mouseState = MouseState.NORMAL; + } + + private void grabMouse() { + if (this.minecraft.mouseHandler.isMouseGrabbed()) { + this.minecraft.mouseHandler.releaseMouse(); + } + Window window = this.minecraft.getWindow(); + synchronized (this.lastPosLock) { + this.lastX = window.getScreenWidth() / 2; + this.lastY = window.getScreenHeight() / 2; + InputConstants.grabOrReleaseMouse(window.getWindow(), InputConstants.CURSOR_DISABLED, this.lastX, this.lastY); + } + this.mouseState = MouseState.CAPTURE; + } + + private void releaseMouse() { + if (this.mouseState == MouseState.RELEASED) { + return; + } + if (this.minecraft.mouseHandler.isMouseGrabbed()) { + this.minecraft.mouseHandler.releaseMouse(); + return; + } + Window window = this.minecraft.getWindow(); + synchronized (this.lastPosLock) { + this.lastX = window.getScreenWidth() / 2; + this.lastY = window.getScreenHeight() / 2; + InputConstants.grabOrReleaseMouse(window.getWindow(), InputConstants.CURSOR_NORMAL, this.lastX, this.lastY); + } + this.mouseState = MouseState.RELEASED; + } + + private enum MouseState { + RELEASED, NORMAL, CAPTURE } } diff --git a/src/main/java/de/srendi/advancedperipherals/client/screens/SaddleTurtleScreen.java b/src/main/java/de/srendi/advancedperipherals/client/screens/SaddleTurtleScreen.java index 4fff59801..7dc79a758 100644 --- a/src/main/java/de/srendi/advancedperipherals/client/screens/SaddleTurtleScreen.java +++ b/src/main/java/de/srendi/advancedperipherals/client/screens/SaddleTurtleScreen.java @@ -45,6 +45,11 @@ 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; @@ -131,6 +136,7 @@ private void renderDismountHint(PoseStack stack) { getFont().drawShadow(stack, text, x, top, 0xffffff); } + @Override public void render(ForgeGui gui, PoseStack poseStack, float partialTick, int screenWidth, int screenHeight) { if (!isPlayerMountedOnTurtle()) { return; @@ -143,6 +149,8 @@ public void render(ForgeGui gui, PoseStack poseStack, float partialTick, int scr if (this.shouldRenderFuelBar()) { this.renderFuelBar(poseStack); } - this.renderDismountHint(poseStack); + if (isPlayerControllingTurtle()) { + this.renderDismountHint(poseStack); + } } } 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 6f00434c1..9e209e822 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/APAddons.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/APAddons.java @@ -2,6 +2,7 @@ import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.common.addons.refinedstorage.RefinedStorage; +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; @@ -12,8 +13,6 @@ import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; -import org.valkyrienskies.core.api.ships.Ship; -import org.valkyrienskies.mod.common.VSGameUtilsKt; import top.theillusivec4.curios.api.CuriosApi; import top.theillusivec4.curios.api.SlotResult; import top.theillusivec4.curios.api.SlotTypeMessage; @@ -23,38 +22,51 @@ @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_ADDITIONS_MODID = "ae2additions"; public static final String AE_THINGS_MODID = "ae2things"; public static final String APPLIEDENERGISTICS_MODID = "ae2"; - public static final String MEKANISM_MODID = "mekanism"; - public static final String AE_ADDITIONS_MODID = "ae2additions"; 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 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 aeAdditionsLoaded; - public static boolean appMekLoaded; + public static boolean powahLoaded; + public static boolean refinedStorageLoaded; public static boolean vs2Loaded; // 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); - appliedEnergisticsLoaded = modList.isLoaded(APPLIEDENERGISTICS_MODID); - mekanismLoaded = modList.isLoaded(MEKANISM_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) + if (refinedStorageLoaded) { RefinedStorage.instance = new RefinedStorage(); + } } @SubscribeEvent @@ -83,13 +95,6 @@ public static boolean isBlockOnShip(Level level, BlockPos pos) { if (!vs2Loaded) { return false; } - return VSGameUtilsKt.isBlockInShipyard(level, pos); - } - - public static Ship getVS2Ship(Level level, BlockPos pos) { - if (!vs2Loaded) { - return null; - } - return VSGameUtilsKt.getShipObjectManagingPos(level, pos); + 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/appliedenergistics/AppEngApi.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AppEngApi.java similarity index 99% rename from src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/AppEngApi.java rename to src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AppEngApi.java index fbd53e35b..4ba53c7e5 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/AppEngApi.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/AppEngApi.java @@ -1,4 +1,4 @@ -package de.srendi.advancedperipherals.common.addons.appliedenergistics; +package de.srendi.advancedperipherals.common.addons.ae2; import appeng.api.crafting.IPatternDetails; import appeng.api.inventories.InternalInventory; diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/CraftJob.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/CraftJob.java similarity index 98% rename from src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/CraftJob.java rename to src/main/java/de/srendi/advancedperipherals/common/addons/ae2/CraftJob.java index c7a0b6c95..e113ed21d 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/CraftJob.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/CraftJob.java @@ -1,4 +1,4 @@ -package de.srendi.advancedperipherals.common.addons.appliedenergistics; +package de.srendi.advancedperipherals.common.addons.ae2; import appeng.api.networking.IGrid; import appeng.api.networking.IGridNode; diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeBridgeEntityListener.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeBridgeEntityListener.java similarity index 90% rename from src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeBridgeEntityListener.java rename to src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeBridgeEntityListener.java index 10cc242fb..009b6e8df 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeBridgeEntityListener.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeBridgeEntityListener.java @@ -1,4 +1,4 @@ -package de.srendi.advancedperipherals.common.addons.appliedenergistics; +package de.srendi.advancedperipherals.common.addons.ae2; import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNodeListener; diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeFluidHandler.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeFluidHandler.java similarity index 96% rename from src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeFluidHandler.java rename to src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeFluidHandler.java index 6f10b6be9..4eb75c853 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeFluidHandler.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeFluidHandler.java @@ -1,4 +1,4 @@ -package de.srendi.advancedperipherals.common.addons.appliedenergistics; +package de.srendi.advancedperipherals.common.addons.ae2; import appeng.api.config.Actionable; import appeng.api.networking.security.IActionSource; diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeItemHandler.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeItemHandler.java similarity index 96% rename from src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeItemHandler.java rename to src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeItemHandler.java index a3542cda3..1c5655f70 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/MeItemHandler.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/MeItemHandler.java @@ -1,4 +1,4 @@ -package de.srendi.advancedperipherals.common.addons.appliedenergistics; +package de.srendi.advancedperipherals.common.addons.ae2; import appeng.api.config.Actionable; import appeng.api.networking.security.IActionSource; diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/WiredCableP2PTunnelPart.java b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/WiredCableP2PTunnelPart.java new file mode 100644 index 000000000..596ce5e62 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/ae2/WiredCableP2PTunnelPart.java @@ -0,0 +1,174 @@ +package de.srendi.advancedperipherals.common.addons.ae2; + +import appeng.api.networking.IGridNodeListener; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.items.parts.PartModels; +import appeng.parts.p2p.CapabilityP2PTunnelPart; +import appeng.parts.p2p.P2PModels; +import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.api.network.wired.IWiredElement; +import dan200.computercraft.api.network.wired.IWiredNetworkChange; +import dan200.computercraft.api.network.wired.IWiredNode; +import dan200.computercraft.shared.Capabilities; +import de.srendi.advancedperipherals.AdvancedPeripherals; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.Vec3; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; + +public class WiredCableP2PTunnelPart extends CapabilityP2PTunnelPart { + private static final P2PModels MODELS = new P2PModels(AdvancedPeripherals.getRL("part/p2p/p2p_tunnel_cable")); + + private final IWiredElement element = new P2PWiredElement(); + private final IWiredElement outElement = new P2PWiredElement(); + private final IWiredNode node = this.element.getNode(); + private Set connected = new HashSet<>(); + private boolean activated = false; + + public WiredCableP2PTunnelPart(IPartItem partItem) { + super(partItem, Capabilities.CAPABILITY_WIRED_ELEMENT); + this.inputHandler = outElement; + this.outputHandler = outElement; + this.emptyHandler = null; // should never used + } + + @PartModels + public static List getModels() { + return MODELS.getModels(); + } + + @Override + public IPartModel getStaticModels() { + return MODELS.getModel(this.isPowered(), this.isActive()); + } + + @Override + public void onTunnelConfigChange() { + super.onTunnelConfigChange(); + this.connectionsChanged(); + } + + @Override + public void onTunnelNetworkChange() { + super.onTunnelNetworkChange(); + this.connectionsChanged(); + } + + protected void connectionsChanged() { + if (this.isClientSide()) { + return; + } + if (!this.isActive()) { + return; + } + if (!this.activated) { + this.activated = true; + this.node.connectTo(this.outElement.getNode()); + } + + Stream nodeStream = this.getOutputStream().filter(out -> out != this); + WiredCableP2PTunnelPart in = this.getInput(); + if (in != null && in != this) { + nodeStream = Stream.concat(nodeStream, Stream.of(in)); + } + Set nodes = nodeStream.collect(Collectors.toCollection(HashSet::new)); + + for (WiredCableP2PTunnelPart part : this.connected.stream().filter(n -> !nodes.contains(n)).collect(Collectors.toList())) { + if (part.connected.contains(this)) { + this.node.disconnectFrom(part.node); + part.connected.remove(this); + } + this.connected.remove(part); + } + + for (WiredCableP2PTunnelPart part : nodes) { + if (!this.connected.contains(part)) { + this.node.connectTo(part.node); + this.connected.add(part); + part.connected.add(this); + } + } + } + + @Override + protected void onMainNodeStateChanged(IGridNodeListener.State reason) { + super.onMainNodeStateChanged(reason); + if (reason == IGridNodeListener.State.GRID_BOOT) { + return; + } + if (this.isActive()) { + if (!this.getMainNode().hasGridBooted()) { + return; + } + this.connectionsChanged(); + this.refreshConnection(); + } else if (this.activated) { + this.activated = false; + this.node.remove(); + this.connected.clear(); + } + } + + protected BlockPos getFacingPos() { + return this.getHost().getLocation().getPos().relative(this.getSide()); + } + + protected void refreshConnection() { + BlockEntity cable = this.getLevel().getBlockEntity(this.getFacingPos()); + IWiredElement elem = cable == null ? null : cable.getCapability(Capabilities.CAPABILITY_WIRED_ELEMENT, this.getSide().getOpposite()).orElse(null); + if (elem == null) { + return; + } + elem.getNode().connectTo(this.outElement.getNode()); + } + + @Override + public void onNeighborChanged(BlockGetter level, BlockPos pos, BlockPos neighbor) { + if (!this.getFacingPos().equals(neighbor)) { + return; + } + if (this.activated) { + this.refreshConnection(); + } + } + + private class P2PWiredElement implements IWiredElement { + private final IWiredNode node = ComputerCraftAPI.createWiredNodeForElement(this); + + @Nonnull + @Override + public IWiredNode getNode() { + return node; + } + + @Nonnull + @Override + public String getSenderID() { + return "p2p"; + } + + @Nonnull + @Override + public Level getLevel() { + return WiredCableP2PTunnelPart.this.getLevel(); + } + + @Nonnull + @Override + public Vec3 getPosition() { + return Vec3.atCenterOf(WiredCableP2PTunnelPart.this.getBlockEntity().getBlockPos()); + } + + @Override + public void networkChanged(IWiredNetworkChange change) {} + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/integrations/IntegrationPeripheralProvider.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/integrations/IntegrationPeripheralProvider.java index b3a9d8e7a..eaf6cda03 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/integrations/IntegrationPeripheralProvider.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/integrations/IntegrationPeripheralProvider.java @@ -3,6 +3,7 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralProvider; import de.srendi.advancedperipherals.AdvancedPeripherals; +import de.srendi.advancedperipherals.common.addons.APAddons; import de.srendi.advancedperipherals.common.util.Platform; import de.srendi.advancedperipherals.lib.integrations.IPeripheralIntegration; import de.srendi.advancedperipherals.lib.peripherals.BlockEntityIntegrationPeripheral; @@ -23,7 +24,14 @@ public class IntegrationPeripheralProvider implements IPeripheralProvider { - private static final String[] SUPPORTED_MODS = new String[]{"botania", "create", "mekanism", "powah", "dimstorage", "valkyrienskies"}; + private static final String[] SUPPORTED_MODS = new String[]{ + APAddons.BOTANIA_MODID, + APAddons.CREATE_MODID, + APAddons.MEKANISM_MODID, + APAddons.POWAH_MODID, + APAddons.DIMSTORAGE_MODID, + APAddons.VALKYRIEN_SKIES_MODID, + }; private static final PriorityQueue integrations = new PriorityQueue<>(Comparator.comparingInt(IPeripheralIntegration::getPriority)); diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/BlockEntityPeripheralOwner.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/BlockEntityPeripheralOwner.java index 81250b6f2..0a593045a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/BlockEntityPeripheralOwner.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/BlockEntityPeripheralOwner.java @@ -2,7 +2,6 @@ import dan200.computercraft.api.peripheral.IPeripheral; import de.srendi.advancedperipherals.common.blocks.base.BaseBlock; -import de.srendi.advancedperipherals.common.blocks.blockentities.InventoryManagerEntity; import de.srendi.advancedperipherals.common.util.DataStorageUtil; import de.srendi.advancedperipherals.common.util.fakeplayer.APFakePlayer; import de.srendi.advancedperipherals.lib.peripherals.IPeripheralTileEntity; @@ -12,16 +11,17 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.world.Nameable; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; + +import java.util.Objects; import org.apache.commons.lang3.NotImplementedException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Objects; - public class BlockEntityPeripheralOwner extends BasePeripheralOwner { public final T tileEntity; @@ -70,11 +70,15 @@ public FrontAndTop getOrientation() { return tileEntity.getBlockState().getValue(BaseBlock.ORIENTATION); } + @Nullable + @Override + public Entity getHoldingEntity() { + return null; + } + @Nullable @Override public Player getOwner() { - if (tileEntity instanceof InventoryManagerEntity inventoryManagerEntity) - return inventoryManagerEntity.getOwnerPlayer(); return null; } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/IPeripheralOwner.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/IPeripheralOwner.java index 2dd333a9d..fc737aa5a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/IPeripheralOwner.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/IPeripheralOwner.java @@ -1,20 +1,26 @@ package de.srendi.advancedperipherals.common.addons.computercraft.owner; import dan200.computercraft.api.peripheral.IPeripheral; +import de.srendi.advancedperipherals.common.addons.APAddons; +import de.srendi.advancedperipherals.common.addons.valkyrienskies.ValkyrienSkies; import de.srendi.advancedperipherals.common.util.fakeplayer.APFakePlayer; import de.srendi.advancedperipherals.lib.peripherals.IPeripheralOperation; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.FrontAndTop; import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.OwnableEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public interface IPeripheralOwner { @@ -33,7 +39,32 @@ default Vec3 getCenterPos() { @NotNull FrontAndTop getOrientation(); - @Nullable Player getOwner(); + @NotNull + default Vec3 getDirection() { + Vec3 dir = Vec3.atLowerCornerOf(getFacing().getNormal()); + if (!APAddons.vs2Loaded) { + return dir; + } + return ValkyrienSkies.transformToWorldDir(getLevel(), getPos(), dir); + } + + @Nullable Entity getHoldingEntity(); + + @Nullable + default Player getOwner() { + Entity owner = getHoldingEntity(); + Set checked = new HashSet<>(); + while (owner != null && checked.add(owner)) { + if (owner instanceof Player player) { + return (Player) player; + } + if (!(owner instanceof OwnableEntity ownable)) { + break; + } + owner = ownable.getOwner(); + } + return null; + } @NotNull CompoundTag getDataStorage(); diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/InventoryManagerOwner.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/InventoryManagerOwner.java new file mode 100644 index 000000000..c9bc48605 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/InventoryManagerOwner.java @@ -0,0 +1,17 @@ +package de.srendi.advancedperipherals.common.addons.computercraft.owner; + +import de.srendi.advancedperipherals.common.blocks.blockentities.InventoryManagerEntity; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.Nullable; + +public class InventoryManagerOwner extends BlockEntityPeripheralOwner { + public InventoryManagerOwner(InventoryManagerEntity tile) { + super(tile); + } + + @Nullable + @Override + public Player getOwner() { + return tileEntity.getOwnerPlayer(); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/PocketPeripheralOwner.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/PocketPeripheralOwner.java index ffafe5d54..21dc65ae6 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/PocketPeripheralOwner.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/PocketPeripheralOwner.java @@ -2,6 +2,7 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.util.DataStorageUtil; import de.srendi.advancedperipherals.common.util.fakeplayer.APFakePlayer; @@ -11,7 +12,6 @@ import net.minecraft.core.FrontAndTop; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; @@ -21,12 +21,15 @@ public class PocketPeripheralOwner extends BasePeripheralOwner { private final IPocketAccess pocket; + private final IPocketUpgrade upgrade; - public PocketPeripheralOwner(IPocketAccess pocket) { + public PocketPeripheralOwner(IPocketAccess pocket, IPocketUpgrade upgrade) { super(); this.pocket = pocket; - if(APConfig.PERIPHERALS_CONFIG.disablePocketFuelConsumption.get()) + this.upgrade = upgrade; + if (APConfig.PERIPHERALS_CONFIG.disablePocketFuelConsumption.get()) { attachAbility(PeripheralOwnerAbility.FUEL, new InfinitePocketFuelAbility(this)); + } } @Nullable @@ -39,56 +42,58 @@ public String getCustomName() { @Override public Level getLevel() { Entity owner = pocket.getEntity(); - if (owner == null) return null; - return owner.getCommandSenderWorld(); + return owner == null ? null : owner.getCommandSenderWorld(); } @NotNull @Override public BlockPos getPos() { Entity owner = pocket.getEntity(); - if (owner == null) return new BlockPos(0, 0, 0); - return owner.blockPosition(); + return owner == null ? BlockPos.ZERO : new BlockPos(owner.getEyePosition()); } @NotNull @Override public Vec3 getCenterPos() { Entity owner = pocket.getEntity(); - if (owner == null) return new Vec3(0, 0, 0); - return owner.position(); + return owner == null ? Vec3.ZERO : owner.getEyePosition(); } @NotNull @Override public Direction getFacing() { - Entity owner = pocket.getEntity(); - if (owner == null) return Direction.NORTH; - return owner.getDirection(); + Vec3 dir = getDirection(); + return Direction.getNearest(dir.x, dir.y, dir.z); } - - /** - * Not used for pockets - */ @NotNull @Override public FrontAndTop getOrientation() { - return FrontAndTop.NORTH_UP; + Entity owner = pocket.getEntity(); + if (owner == null) { + return FrontAndTop.NORTH_UP; + } + Vec3 up = owner.getUpVector(1.0f); + return FrontAndTop.fromFrontAndTop(getFacing(), Direction.getNearest(up.x, up.y, up.z)); } - @Nullable + @NotNull @Override - public Player getOwner() { + public Vec3 getDirection() { Entity owner = pocket.getEntity(); - if (owner instanceof Player player) return player; - return null; + return owner == null ? /* North */ new Vec3(0, 0, -1) : owner.getLookAngle(); + } + + @Nullable + @Override + public Entity getHoldingEntity() { + return pocket.getEntity(); } @NotNull @Override public CompoundTag getDataStorage() { - return DataStorageUtil.getDataStorage(pocket); + return DataStorageUtil.getDataStorage(pocket, upgrade); } @Override diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/TurtlePeripheralOwner.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/TurtlePeripheralOwner.java index 17dd0e3fb..e8365fcc7 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/TurtlePeripheralOwner.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/owner/TurtlePeripheralOwner.java @@ -15,6 +15,7 @@ import net.minecraft.core.Direction; import net.minecraft.core.FrontAndTop; import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -64,6 +65,12 @@ public FrontAndTop getOrientation() { return FrontAndTop.fromFrontAndTop(getFacing(), Direction.UP); } + @Nullable + @Override + public Entity getHoldingEntity() { + return null; + } + @Nullable @Override public Player getOwner() { diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/BaseDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/BaseDetectorPeripheral.java new file mode 100644 index 000000000..843c5554f --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/BaseDetectorPeripheral.java @@ -0,0 +1,42 @@ +package de.srendi.advancedperipherals.common.addons.computercraft.peripheral; + +import dan200.computercraft.api.lua.LuaFunction; +import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; +import de.srendi.advancedperipherals.common.blocks.base.BaseDetectorEntity; +import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; + +public abstract class BaseDetectorPeripheral extends BasePeripheral> { + protected BaseDetectorPeripheral(String type, E tileEntity) { + super(type, new BlockEntityPeripheralOwner<>(tileEntity)); + } + + @LuaFunction + public final long getMaxTransferRate() { + return owner.tileEntity.getMaxTransferRate(); + } + + @LuaFunction + public final long getTransferRateLimit() { + return owner.tileEntity.getTransferRateLimit(); + } + + @LuaFunction + public final void setTransferRateLimit(long transferRate) { + owner.tileEntity.setTransferRateLimit(transferRate); + } + + @LuaFunction + public final long getTransferRate() { + return owner.tileEntity.getTransferRate(); + } + + @LuaFunction + public final String getLastTransferedId() { + return owner.tileEntity.getLastTransferedId(); + } + + @LuaFunction + public final String getReadyTransferId() { + return owner.tileEntity.getReadyTransferId(); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChatBoxPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChatBoxPeripheral.java index 9717a36e1..920f64f13 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChatBoxPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChatBoxPeripheral.java @@ -7,6 +7,7 @@ import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; import de.srendi.advancedperipherals.AdvancedPeripherals; @@ -66,8 +67,8 @@ public ChatBoxPeripheral(ITurtleAccess turtle, TurtleSide side) { this(new TurtlePeripheralOwner(turtle, side)); } - public ChatBoxPeripheral(IPocketAccess pocket) { - this(new PocketPeripheralOwner(pocket)); + public ChatBoxPeripheral(IPocketAccess pocket, IPocketUpgrade upgrade) { + this(new PocketPeripheralOwner(pocket, upgrade)); } @Override @@ -250,7 +251,7 @@ public final MethodResult sendFormattedMessage(@NotNull IArguments arguments) th if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension) { continue; } - if (CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, maxRange)) { + if (CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, maxRange)) { player.sendSystemMessage(preparedMessage); } } @@ -293,7 +294,7 @@ public final MethodResult sendMessage(@NotNull IArguments arguments) throws LuaE if (!APConfig.PERIPHERALS_CONFIG.chatBoxMultiDimensional.get() && player.getLevel().dimension() != dimension) { continue; } - if (CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, maxRange)) { + if (CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, maxRange)) { player.sendSystemMessage(preparedMessage); } } @@ -340,7 +341,7 @@ public final MethodResult sendFormattedMessageToPlayer(@NotNull IArguments argum return MethodResult.of(false, "NOT_SAME_DIMENSION"); } - if (CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, maxRange)) { + if (CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, maxRange)) { player.sendSystemMessage(preparedMessage); } return MethodResult.of(true); @@ -398,7 +399,7 @@ public final MethodResult sendFormattedToastToPlayer(@NotNull IArguments argumen return MethodResult.of(false, "NOT_SAME_DIMENSION"); } - if (CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, maxRange)) { + if (CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, maxRange)) { ToastToClientPacket packet = new ToastToClientPacket(titleComponent, preparedMessage); APNetworking.sendTo(packet, player); } @@ -437,7 +438,7 @@ public final MethodResult sendMessageToPlayer(@NotNull IArguments arguments) thr return MethodResult.of(false, "NOT_SAME_DIMENSION"); } - if (CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, maxRange)) { + if (CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, maxRange)) { player.sendSystemMessage(preparedMessage, false); } return MethodResult.of(true); @@ -476,7 +477,7 @@ public final MethodResult sendToastToPlayer(@NotNull IArguments arguments) throw return MethodResult.of(false, "NOT_SAME_DIMENSION"); } - if (CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, maxRange)) { + if (CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, maxRange)) { ToastToClientPacket packet = new ToastToClientPacket(Component.literal(title), preparedMessage); APNetworking.sendTo(packet, player); } @@ -484,6 +485,7 @@ public final MethodResult sendToastToPlayer(@NotNull IArguments arguments) throw }); } + @Override public void update() { lastConsumedMessage = Events.traverseChatMessages(lastConsumedMessage, message -> { for (IComputerAccess computer : getConnectedComputers()) { diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChunkyPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChunkyPeripheral.java index f56d18151..428574bcb 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChunkyPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ChunkyPeripheral.java @@ -1,5 +1,6 @@ package de.srendi.advancedperipherals.common.addons.computercraft.peripheral; +import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; @@ -44,6 +45,11 @@ public boolean isEnabled() { return APConfig.PERIPHERALS_CONFIG.enableChunkyTurtle.get(); } + @LuaFunction + public int getRadius() { + return ChunkManager.getMaxLoadRadius(); + } + public void updateChunkState() { // TODO: should find someway to update after turtle moved or while moving, but not every tick ServerLevel level = (ServerLevel) getLevel(); diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ColonyPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ColonyPeripheral.java index 12aefd596..8b5a9a1e9 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ColonyPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/ColonyPeripheral.java @@ -18,6 +18,7 @@ import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; import de.srendi.advancedperipherals.common.addons.computercraft.owner.IPeripheralOwner; @@ -50,8 +51,8 @@ public ColonyPeripheral(PeripheralBlockEntity tileEntity) { super(PERIPHERAL_TYPE, new BlockEntityPeripheralOwner<>(tileEntity)); } - public ColonyPeripheral(IPocketAccess access) { - super(PERIPHERAL_TYPE, new PocketPeripheralOwner(access)); + public ColonyPeripheral(IPocketAccess access, IPocketUpgrade upgrade) { + super(PERIPHERAL_TYPE, new PocketPeripheralOwner(access, upgrade)); } @Override diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java index bf1f63655..8b595fdf8 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java @@ -3,17 +3,64 @@ import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; +import de.srendi.advancedperipherals.common.addons.computercraft.owner.IPeripheralOwner; +import de.srendi.advancedperipherals.common.addons.computercraft.owner.PocketPeripheralOwner; import de.srendi.advancedperipherals.common.blocks.blockentities.DistanceDetectorEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; +import de.srendi.advancedperipherals.common.util.HitResultUtil; import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; -public class DistanceDetectorPeripheral extends BasePeripheral> { +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +public class DistanceDetectorPeripheral extends BasePeripheral { public static final String PERIPHERAL_TYPE = "distance_detector"; + private final AtomicBoolean isDirty = new AtomicBoolean(false); + private final DistanceDetectorEntity tileEntity; + private final AtomicInteger maxRange; + private volatile float currentDistance; + private final AtomicBoolean showLaser; + private volatile boolean calculatePeriodically; + private volatile boolean ignoreTransparent; + private final AtomicReference detectionType; + public DistanceDetectorPeripheral(DistanceDetectorEntity tileEntity) { super(PERIPHERAL_TYPE, new BlockEntityPeripheralOwner<>(tileEntity)); + this.tileEntity = tileEntity; + // TODO: let distance detector block also use data storage + this.maxRange = new AtomicInteger(Float.floatToRawIntBits(this.tileEntity.getMaxRange())); + this.currentDistance = this.tileEntity.getCurrentDistance(); + this.showLaser = new AtomicBoolean(this.tileEntity.getShowLaser()); + this.calculatePeriodically = this.tileEntity.getCalculatePeriodically(); + this.ignoreTransparent = this.tileEntity.getIgnoreTransparent(); + this.detectionType = new AtomicReference<>(this.tileEntity.getDetectionType()); + } + + protected DistanceDetectorPeripheral(IPeripheralOwner owner) { + super(PERIPHERAL_TYPE, owner); + this.tileEntity = null; + CompoundTag data = this.owner.getDataStorage(); + this.maxRange = new AtomicInteger(Float.floatToRawIntBits(data.contains("maxRange") ? data.getFloat("maxRange") : this.getConfiguredMaxRange())); + this.currentDistance = data.contains("currentDistance") ? data.getFloat("currentDistance") : -1; + this.showLaser = new AtomicBoolean(data.contains("showLaser") ? data.getBoolean("showLaser") : true); + this.calculatePeriodically = data.contains("calculatePeriodically") ? data.getBoolean("calculatePeriodically") : false; + this.ignoreTransparent = data.contains("ignoreTransparent") ? data.getBoolean("ignoreTransparent") : true; + this.detectionType = new AtomicReference<>(data.contains("detectionType") ? DetectionType.values()[data.getByte("detectionType")] : DetectionType.BOTH); + } + + public DistanceDetectorPeripheral(IPocketAccess pocket, IPocketUpgrade upgrade) { + this(new PocketPeripheralOwner(pocket, upgrade)); } @Override @@ -21,24 +68,115 @@ public boolean isEnabled() { return APConfig.PERIPHERALS_CONFIG.enableDistanceDetector.get(); } + public float getConfiguredMaxRange() { + return APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue(); + } + + public int getUpdateRate() { + return APConfig.PERIPHERALS_CONFIG.distanceDetectorUpdateRate.get(); + } + + public float getMaxRange() { + return Float.intBitsToFloat(this.maxRange.get()); + } + + public void setMaxRange(float maxRange) { + maxRange = Math.min(Math.max(maxRange, 0), this.getConfiguredMaxRange()); + int maxRangeBits = Float.floatToRawIntBits(maxRange); + if (this.maxRange.getAndSet(maxRangeBits) == maxRange) { + return; + } + if (this.tileEntity != null) { + this.tileEntity.setMaxRange(maxRange); + this.tileEntity.sendUpdate(); + } + this.isDirty.set(true); + } + + public float getCurrentDistance() { + return this.currentDistance; + } + + public void setCurrentDistance(float currentDistance) { + this.currentDistance = currentDistance; + if (this.tileEntity != null) { + this.tileEntity.setCurrentDistance(currentDistance); + this.tileEntity.sendUpdate(); + } + this.isDirty.set(true); + } + + public boolean getCalculatePeriodically() { + return this.calculatePeriodically; + } + + public void setCalculatePeriodically(boolean calculatePeriodically) { + this.calculatePeriodically = calculatePeriodically; + if (this.tileEntity != null) { + this.tileEntity.setCalculatePeriodically(calculatePeriodically); + } + this.isDirty.set(true); + } + + public boolean getShowLaser() { + return this.showLaser.get(); + } + + public void setShowLaser(boolean showLaser) { + if (this.showLaser.getAndSet(showLaser) == showLaser) { + return; + } + if (this.tileEntity != null) { + this.tileEntity.setShowLaser(showLaser); + this.tileEntity.sendUpdate(); + } + this.isDirty.set(true); + } + + public boolean getIgnoreTransparent() { + return this.ignoreTransparent; + } + + public void setIgnoreTransparent(boolean ignoreTransparent) { + this.ignoreTransparent = ignoreTransparent; + if (this.tileEntity != null) { + this.tileEntity.setIgnoreTransparent(ignoreTransparent); + } + this.isDirty.set(true); + } + + public DetectionType getDetectionType() { + return this.detectionType.get(); + } + + public void setDetectionType(DetectionType detectionType) { + if (this.detectionType.getAndSet(detectionType) == detectionType) { + return; + } + if (this.tileEntity != null) { + this.tileEntity.setDetectionType(detectionType); + } + this.isDirty.set(true); + } + @LuaFunction public final void setLaserVisibility(boolean laser) { - getPeripheralOwner().tileEntity.setShowLaser(laser); + this.setShowLaser(laser); } @LuaFunction public final boolean getLaserVisibility() { - return getPeripheralOwner().tileEntity.getLaserVisibility(); + return this.getShowLaser(); } - @LuaFunction - public final void setIgnoreTransparency(boolean enable) { - getPeripheralOwner().tileEntity.setIgnoreTransparent(enable); + @LuaFunction(value = "setIgnoreTransparency") + public final void setIgnoreTransparencyLua(boolean enable) { + this.setIgnoreTransparent(enable); } @LuaFunction public final boolean ignoresTransparency() { - return getPeripheralOwner().tileEntity.ignoreTransparent(); + return this.getIgnoreTransparent(); } @LuaFunction @@ -61,55 +199,113 @@ public final void setDetectionMode(IArguments args) throws LuaException { } else { throw new LuaException("arg #1 must be a string or a number"); } - getPeripheralOwner().tileEntity.setDetectionType(detectionType); + this.setDetectionType(detectionType); } @LuaFunction public final boolean detectsEntities() { - DetectionType detectionType = getPeripheralOwner().tileEntity.getDetectionType(); - return detectionType.detectEntity(); + return this.getDetectionType().detectEntity(); } @LuaFunction public final boolean detectsBlocks() { - DetectionType detectionType = getPeripheralOwner().tileEntity.getDetectionType(); - return detectionType.detectBlock(); + return this.getDetectionType().detectBlock(); } @LuaFunction public final String getDetectionMode() { - DetectionType detectionType = getPeripheralOwner().tileEntity.getDetectionType(); - return detectionType.toString(); + return this.getDetectionType().toString(); } @LuaFunction public final double getDistance() { - return getPeripheralOwner().tileEntity.getCurrentDistance(); + return this.getCurrentDistance(); } @LuaFunction(mainThread = true) public final double calculateDistance() { - return getPeripheralOwner().tileEntity.calculateAndUpdateDistance(); + return this.calculateAndUpdateDistance(); } @LuaFunction public final boolean shouldCalculatePeriodically() { - return getPeripheralOwner().tileEntity.shouldCalculatePeriodically(); + return this.getCalculatePeriodically(); } - @LuaFunction - public final void setCalculatePeriodically(boolean shouldRenderPeriodically) { - getPeripheralOwner().tileEntity.setShouldCalculatePeriodically(shouldRenderPeriodically); + @LuaFunction(value = "setCalculatePeriodically") + public final void setCalculatePeriodicallyLua(boolean shouldCalculatePeriodically) { + this.setCalculatePeriodically(shouldCalculatePeriodically); } - @LuaFunction - public final void setMaxRange(double maxDistance) { - getPeripheralOwner().tileEntity.setMaxRange((float) maxDistance); + @LuaFunction(value = "setMaxRange") + public final void setMaxRangeLua(double maxDistance) { + this.setMaxRange((float) maxDistance); } - @LuaFunction - public final double getMaxRange() { - return getPeripheralOwner().tileEntity.getMaxRange(); + @LuaFunction(value = "getMaxRange") + public final double getMaxRangeLua() { + return this.getMaxRange(); + } + + protected double calculateDistanceImpl() { + final double maxRange = this.getMaxRange(); + Vec3 direction = this.owner.getDirection(); + Vec3 center = this.getPhysicsPos(); + Vec3 from = center; + Vec3 to = from.add(direction.scale(maxRange)); + + HitResult result = this.getHitResult(from, to); + if (result.getType() == HitResult.Type.MISS) { + return -1; + } + double distance = result.getLocation().distanceTo(center); + if (this.tileEntity != null) { + distance -= 0.5; + } + return distance; + } + + /** + * calculateAndUpdateDistance should only invokes from server main thread + */ + public double calculateAndUpdateDistance() { + double distance = this.calculateDistanceImpl(); + this.setCurrentDistance((float) distance); + return distance; + } + + @Override + public void update() { + if (this.getCalculatePeriodically() && this.getLevel().getGameTime() % this.getUpdateRate() == 0) { + // We calculate the distance every 2 ticks, so we do not have to run the getDistance function of the peripheral + // on the main thread which prevents the 1 tick yield time of the function. + // The calculateDistance function is not thread safe, so we have to run it on the main thread. + // It should be okay to run that function every 2 ticks, calculating it does not take too much time. + this.calculateAndUpdateDistance(); + } + + if (this.isDirty.getAndSet(false)) { + if (this.tileEntity == null) { + CompoundTag data = this.owner.getDataStorage(); + data.putFloat("maxRange", this.getMaxRange()); + data.putFloat("currentDistance", this.getCurrentDistance()); + data.putBoolean("showLaser", this.getShowLaser()); + data.putBoolean("calculatePeriodically", this.getCalculatePeriodically()); + data.putBoolean("ignoreTransparent", this.getIgnoreTransparent()); + data.putByte("detectionType", (byte) this.getDetectionType().ordinal()); + } + this.owner.markDataStorageDirty(); + } + } + + protected HitResult getHitResult(Vec3 from, Vec3 to) { + Level level = this.getLevel(); + ClipContext.ShapeGetter shapeGetter = this.ignoreTransparent ? HitResultUtil.IgnoreNoOccludedContext.INSTANCE : ClipContext.Block.COLLIDER; + return switch (this.getDetectionType()) { + case ENTITY -> HitResultUtil.getEntityHitResult(from, to, level, this.owner.getHoldingEntity()); + case BLOCK -> HitResultUtil.getBlockHitResult(from, to, level, shapeGetter, this.getPos()); + case BOTH -> HitResultUtil.getHitResult(from, to, level, shapeGetter, this.owner); + }; } public enum DetectionType { diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnergyDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnergyDetectorPeripheral.java index 0898fb611..5aff47acd 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnergyDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnergyDetectorPeripheral.java @@ -1,37 +1,18 @@ package de.srendi.advancedperipherals.common.addons.computercraft.peripheral; -import dan200.computercraft.api.lua.LuaFunction; -import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; import de.srendi.advancedperipherals.common.blocks.blockentities.EnergyDetectorEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; -import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; -public class EnergyDetectorPeripheral extends BasePeripheral> { +public class EnergyDetectorPeripheral extends BaseDetectorPeripheral { - public static final String PERIPHERAL_TYPE = "energy_detector"; + public static final String TYPE = "energy_detector"; public EnergyDetectorPeripheral(EnergyDetectorEntity tileEntity) { - super(PERIPHERAL_TYPE, new BlockEntityPeripheralOwner<>(tileEntity)); + super(TYPE, tileEntity); } @Override public boolean isEnabled() { return APConfig.PERIPHERALS_CONFIG.enableEnergyDetector.get(); } - - @LuaFunction(mainThread = true) - public final int getTransferRateLimit() { - return owner.tileEntity.storageProxy.getMaxTransferRate(); - } - - @LuaFunction(mainThread = true) - public final void setTransferRateLimit(long transferRate) { - transferRate = Math.max(0, Math.min(APConfig.PERIPHERALS_CONFIG.energyDetectorMaxFlow.get(), transferRate)); - owner.tileEntity.storageProxy.setMaxTransferRate((int) transferRate); - } - - @LuaFunction(mainThread = true) - public final int getTransferRate() { - return owner.tileEntity.transferRate; - } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnvironmentDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnvironmentDetectorPeripheral.java index 580d1a7f4..62db06f6a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnvironmentDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/EnvironmentDetectorPeripheral.java @@ -5,8 +5,10 @@ import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; + import de.srendi.advancedperipherals.common.addons.computercraft.operations.SphereOperationContext; import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; import de.srendi.advancedperipherals.common.addons.computercraft.owner.IPeripheralOwner; @@ -17,6 +19,7 @@ import de.srendi.advancedperipherals.common.util.LuaConverter; import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; import de.srendi.advancedperipherals.lib.peripherals.IPeripheralPlugin; + import net.minecraft.resources.ResourceKey; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -34,7 +37,6 @@ import net.minecraftforge.event.entity.player.SleepingTimeCheckEvent; import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.server.ServerLifecycleHooks; -import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; @@ -44,6 +46,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Function; +import org.jetbrains.annotations.NotNull; import static de.srendi.advancedperipherals.common.addons.computercraft.operations.SphereOperation.SCAN_ENTITIES; @@ -68,8 +71,8 @@ public EnvironmentDetectorPeripheral(ITurtleAccess turtle, TurtleSide side) { this(new TurtlePeripheralOwner(turtle, side).attachFuel(1)); } - public EnvironmentDetectorPeripheral(IPocketAccess pocket) { - this(new PocketPeripheralOwner(pocket)); + public EnvironmentDetectorPeripheral(IPocketAccess pocket, IPocketUpgrade upgrade) { + this(new PocketPeripheralOwner(pocket, upgrade)); } private static int estimateCost(int radius) { @@ -93,24 +96,24 @@ public boolean isEnabled() { @LuaFunction(mainThread = true) public final String getBiome() { - Optional> biome = getLevel().getBiome(this.getWorldBlockPos()).unwrapKey(); + Optional> biome = getLevel().getBiome(this.getPhysicsBlockPos()).unwrapKey(); return biome.map(biomeResourceKey -> biomeResourceKey.location().toString()).orElse("unknown"); } @LuaFunction(mainThread = true) public final int getSkyLightLevel() { - return getLevel().getBrightness(LightLayer.SKY, this.getWorldBlockPos().offset(0, 1, 0)); + return getLevel().getBrightness(LightLayer.SKY, this.getPhysicsBlockPos().offset(0, 1, 0)); } @LuaFunction(mainThread = true) public final int getBlockLightLevel() { - return getLevel().getBrightness(LightLayer.BLOCK, this.getWorldBlockPos().offset(0, 1, 0)); + return getLevel().getBrightness(LightLayer.BLOCK, this.getPhysicsBlockPos().offset(0, 1, 0)); } @LuaFunction(mainThread = true) public final int getDayLightLevel() { Level level = getLevel(); - int i = level.getBrightness(LightLayer.SKY, this.getWorldBlockPos().offset(0, 1, 0)) - level.getSkyDarken(); + int i = level.getBrightness(LightLayer.SKY, this.getPhysicsBlockPos().offset(0, 1, 0)) - level.getSkyDarken(); float f = level.getSunAngle(1.0F); if (i > 0) { float f1 = f < (float) Math.PI ? 0.0F : ((float) Math.PI * 2F); @@ -128,7 +131,7 @@ public final long getTime() { @LuaFunction(mainThread = true) public final boolean isSlimeChunk() { - ChunkPos chunkPos = new ChunkPos(this.getWorldBlockPos()); + ChunkPos chunkPos = new ChunkPos(this.getPhysicsBlockPos()); return WorldgenRandom.seedSlimeChunk(chunkPos.x, chunkPos.z, ((WorldGenLevel) getLevel()).getSeed(), 987234911L).nextInt(10) == 0; } @@ -208,7 +211,7 @@ public final MethodResult scanEntities(@NotNull IArguments arguments) throws Lua return withOperation(SCAN_ENTITIES, new SphereOperationContext(radius), context -> { return context.getRadius() > SCAN_ENTITIES.getMaxCostRadius() ? MethodResult.of(null, "Radius exceeds max value") : null; }, context -> { - Vec3 pos = this.getWorldPos(); + Vec3 pos = this.getPhysicsPos(); AABB box = new AABB(pos, pos); List> entities = getLevel().getEntities((Entity) null, box.inflate(context.getRadius() + 0.5), entity -> entity instanceof LivingEntity && entity.isAlive()).stream().map(entity -> LuaConverter.completeEntityWithPositionToLua(entity, pos, detailed)).toList(); return MethodResult.of(entities); diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/FluidDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/FluidDetectorPeripheral.java index c54dde612..60cd76182 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/FluidDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/FluidDetectorPeripheral.java @@ -1,43 +1,18 @@ package de.srendi.advancedperipherals.common.addons.computercraft.peripheral; -import dan200.computercraft.api.lua.LuaFunction; -import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; import de.srendi.advancedperipherals.common.blocks.blockentities.FluidDetectorEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; -import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; -import net.minecraftforge.registries.ForgeRegistries; -public class FluidDetectorPeripheral extends BasePeripheral> { +public class FluidDetectorPeripheral extends BaseDetectorPeripheral { public static final String TYPE = "fluid_detector"; public FluidDetectorPeripheral(FluidDetectorEntity tileEntity) { - super(TYPE, new BlockEntityPeripheralOwner<>(tileEntity)); + super(TYPE, tileEntity); } @Override public boolean isEnabled() { return APConfig.PERIPHERALS_CONFIG.enableFluidDetector.get(); } - - @LuaFunction(mainThread = true) - public final int getTransferRateLimit() { - return owner.tileEntity.storageProxy.getMaxTransferRate(); - } - - @LuaFunction(mainThread = true) - public final String getTransferedFluid() { - return ForgeRegistries.FLUIDS.getKey(owner.tileEntity.lastFlowedLiquid.getFluid()).toString(); - } - - @LuaFunction(mainThread = true) - public final void setTransferRateLimit(long transferRate) { - transferRate = Math.min(APConfig.PERIPHERALS_CONFIG.fluidDetectorMaxFlow.get(), transferRate); - owner.tileEntity.storageProxy.setMaxTransferRate((int) transferRate); - } - - @LuaFunction(mainThread = true) - public final int getTransferRate() { - return owner.tileEntity.transferRate; - } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GasDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GasDetectorPeripheral.java index fd94811e3..c5a293179 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GasDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GasDetectorPeripheral.java @@ -1,42 +1,18 @@ package de.srendi.advancedperipherals.common.addons.computercraft.peripheral; -import dan200.computercraft.api.lua.LuaFunction; -import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; import de.srendi.advancedperipherals.common.blocks.blockentities.GasDetectorEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; -import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; -public class GasDetectorPeripheral extends BasePeripheral> { +public class GasDetectorPeripheral extends BaseDetectorPeripheral { public static final String TYPE = "gas_detector"; public GasDetectorPeripheral(GasDetectorEntity tileEntity) { - super(TYPE, new BlockEntityPeripheralOwner<>(tileEntity)); + super(TYPE, tileEntity); } @Override public boolean isEnabled() { return APConfig.PERIPHERALS_CONFIG.enableGasDetector.get(); } - - @LuaFunction(mainThread = true) - public final int getTransferRateLimit() { - return owner.tileEntity.storageProxy.getMaxTransferRate(); - } - - @LuaFunction(mainThread = true) - public final String getTransferedGas() { - return owner.tileEntity.lastFlowedGas.getRaw().getRegistryName().toString(); - } - - @LuaFunction(mainThread = true) - public final void setTransferRateLimit(long transferRate) { - transferRate = Math.min(APConfig.PERIPHERALS_CONFIG.gasDetectorMaxFlow.get(), transferRate); - owner.tileEntity.storageProxy.setMaxTransferRate((int) transferRate); - } - - @LuaFunction(mainThread = true) - public final int getTransferRate() { - return owner.tileEntity.transferRate; - } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GeoScannerPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GeoScannerPeripheral.java index 449256acb..6a9ccacb8 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GeoScannerPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/GeoScannerPeripheral.java @@ -5,6 +5,7 @@ import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; import de.srendi.advancedperipherals.common.addons.computercraft.operations.SphereOperationContext; @@ -57,8 +58,8 @@ public GeoScannerPeripheral(ITurtleAccess turtle, TurtleSide side) { this(new TurtlePeripheralOwner(turtle, side).attachFuel(1)); } - public GeoScannerPeripheral(IPocketAccess pocket) { - this(new PocketPeripheralOwner(pocket)); + public GeoScannerPeripheral(IPocketAccess pocket, IPocketUpgrade upgrade) { + this(new PocketPeripheralOwner(pocket, upgrade)); } private static List> scan(List> result, Level level, Vec3 center, int radius) { @@ -103,7 +104,7 @@ public final MethodResult cost(int radius) { public final MethodResult chunkAnalyze() throws LuaException { return withOperation(SCAN_BLOCKS, SCAN_BLOCKS.free(), null, ignored -> { Level level = getLevel(); - LevelChunk chunk = level.getChunkAt(getWorldBlockPos()); + LevelChunk chunk = level.getChunkAt(getPhysicsBlockPos()); ChunkPos chunkPos = chunk.getPos(); HashMap data = new HashMap<>(); for (int x = chunkPos.getMinBlockX(); x <= chunkPos.getMaxBlockX(); x++) { @@ -136,7 +137,7 @@ public final MethodResult scan(@NotNull IArguments arguments) throws LuaExceptio scan(result, getLevel(), getCenterPos(), context.getRadius()); if (isOnShip()) { int i = result.size(); - scan(result, getLevel(), getWorldPos(), context.getRadius()); + scan(result, getLevel(), getPhysicsPos(), context.getRadius()); for (; i < result.size(); i++) { Map data = result.get(i); data.put("notOnShip", true); diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/InventoryManagerPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/InventoryManagerPeripheral.java index 21fe14a0d..72fda1b7f 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/InventoryManagerPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/InventoryManagerPeripheral.java @@ -4,7 +4,7 @@ import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.MethodResult; import de.srendi.advancedperipherals.AdvancedPeripherals; -import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; +import de.srendi.advancedperipherals.common.addons.computercraft.owner.InventoryManagerOwner; import de.srendi.advancedperipherals.common.blocks.blockentities.InventoryManagerEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.util.LuaConverter; @@ -29,12 +29,12 @@ import java.util.List; import java.util.Map; -public class InventoryManagerPeripheral extends BasePeripheral> { +public class InventoryManagerPeripheral extends BasePeripheral { public static final String PERIPHERAL_TYPE = "inventory_manager"; public InventoryManagerPeripheral(InventoryManagerEntity tileEntity) { - super(PERIPHERAL_TYPE, new BlockEntityPeripheralOwner<>(tileEntity)); + super(PERIPHERAL_TYPE, new InventoryManagerOwner(tileEntity)); } @Override @@ -103,13 +103,13 @@ private MethodResult removeItemCommon(String invDirection, ItemFilter filter) th @LuaFunction(value = {"list", "getItems"}, mainThread = true) public final List getItems() throws LuaException { List items = new ArrayList<>(); - int i = 0; //Used to let users easily sort the items by the slots. Also, a better way for the user to see where an item actually is - for (ItemStack stack : getOwnerPlayer().getInventory().items) { - ItemStack copiedStack = stack.copy(); - if (!copiedStack.isEmpty()) - items.add(LuaConverter.stackToObjectWithSlot(copiedStack, i)); - - i++; + List stacks = getOwnerPlayer().getInventory().items; + // Used to let users easily sort the items by the slots. Also, a better way for the user to see where an item actually is + for (int slot = 0; slot < stacks.size(); slot++) { + ItemStack stack = stacks.get(slot); + if (!stack.isEmpty()) { + items.add(LuaConverter.stackToObjectWithSlot(stack, slot)); + } } return items; } @@ -127,7 +127,7 @@ public final MethodResult getItemsChest(String target) throws LuaException { List items = new ArrayList<>(); for (int slot = 0; slot < inventoryTo.getSlots(); slot++) { if (!inventoryTo.getStackInSlot(slot).isEmpty()) { - items.add(LuaConverter.stackToObjectWithSlot(inventoryTo.getStackInSlot(slot).copy(), slot)); + items.add(LuaConverter.stackToObjectWithSlot(inventoryTo.getStackInSlot(slot), slot)); } } return MethodResult.of(items); @@ -137,9 +137,8 @@ public final MethodResult getItemsChest(String target) throws LuaException { public final List getArmor() throws LuaException { List items = new ArrayList<>(); for (ItemStack stack : getOwnerPlayer().getInventory().armor) { - ItemStack copiedStack = stack.copy(); - if (!copiedStack.isEmpty()) { - items.add(LuaConverter.stackToObjectWithSlot(copiedStack, ArmorSlot.getSlotForItem(copiedStack))); + if (!stack.isEmpty()) { + items.add(LuaConverter.stackToObjectWithSlot(stack, ArmorSlot.getSlotForItem(stack))); } } return items; @@ -157,24 +156,18 @@ public final boolean isPlayerEquipped() throws LuaException { @LuaFunction(mainThread = true) public final boolean isWearing(int index) throws LuaException { - int i = 0; - for (ItemStack stack : getOwnerPlayer().getInventory().armor) { - if (!stack.isEmpty()) { - if (index == i - 100) return true; - i++; - } - } - return false; + List armor = getOwnerPlayer().getInventory().armor; + return 0 <= index && index < armor.size() && !armor.get(index).isEmpty(); } @LuaFunction(mainThread = true) public final int getEmptySpace() throws LuaException { - int i = 0; + int count = 0; for (ItemStack stack : getOwnerPlayer().getInventory().items) { if (stack.isEmpty()) - i++; + count++; } - return i; + return count; } @LuaFunction(mainThread = true) diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MeBridgePeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MeBridgePeripheral.java index 4a535157d..6d028fefb 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MeBridgePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MeBridgePeripheral.java @@ -16,10 +16,10 @@ import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.core.apis.TableHelper; import dan200.computercraft.core.computer.ComputerSide; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.AppEngApi; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.CraftJob; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.MeFluidHandler; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.MeItemHandler; +import de.srendi.advancedperipherals.common.addons.ae2.AppEngApi; +import de.srendi.advancedperipherals.common.addons.ae2.CraftJob; +import de.srendi.advancedperipherals.common.addons.ae2.MeFluidHandler; +import de.srendi.advancedperipherals.common.addons.ae2.MeItemHandler; import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; import de.srendi.advancedperipherals.common.blocks.blockentities.MeBridgeEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; @@ -46,7 +46,7 @@ public class MeBridgePeripheral extends BasePeripheral> implements IStorageSystemPeripheral { - public static final String PERIPHERAL_TYPE = "meBridge"; + public static final String PERIPHERAL_TYPE = "me_bridge"; private final MeBridgeEntity tile; private IGridNode node; diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/PlayerDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/PlayerDetectorPeripheral.java index c06aa150d..b5f418993 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/PlayerDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/PlayerDetectorPeripheral.java @@ -5,6 +5,7 @@ import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; @@ -13,6 +14,7 @@ import de.srendi.advancedperipherals.common.addons.computercraft.owner.TurtlePeripheralOwner; import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; +import de.srendi.advancedperipherals.common.events.Events; import de.srendi.advancedperipherals.common.util.CoordUtil; import de.srendi.advancedperipherals.common.util.LuaConverter; import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; @@ -32,6 +34,7 @@ public class PlayerDetectorPeripheral extends BasePeripheral { public static final String PERIPHERAL_TYPE = "player_detector"; private static final int MAX_RANGE = APConfig.PERIPHERALS_CONFIG.playerDetMaxRange.get(); + private long lastConsumedMessage = Events.getLastPlayerMessageID() - 1; public PlayerDetectorPeripheral(PeripheralBlockEntity tileEntity) { super(PERIPHERAL_TYPE, new BlockEntityPeripheralOwner<>(tileEntity)); @@ -41,8 +44,8 @@ public PlayerDetectorPeripheral(ITurtleAccess access, TurtleSide side) { super(PERIPHERAL_TYPE, new TurtlePeripheralOwner(access, side)); } - public PlayerDetectorPeripheral(IPocketAccess pocket) { - super(PERIPHERAL_TYPE, new PocketPeripheralOwner(pocket)); + public PlayerDetectorPeripheral(IPocketAccess pocket, IPocketUpgrade upgrade) { + super(PERIPHERAL_TYPE, new PocketPeripheralOwner(pocket, upgrade)); } private boolean isAllowedMultiDimensional() { @@ -73,7 +76,7 @@ public final MethodResult getPlayersInCoords(Map firstCoord, Map sec if (!isAllowedMultiDimensional() && player.getLevel().dimension() != dimension) { continue; } - if (CoordUtil.isInRange(getWorldPos(), player, getLevel(), firstPos, secondPos, MAX_RANGE)) { + if (CoordUtil.isInRange(getPhysicsPos(), player, getLevel(), firstPos, secondPos, MAX_RANGE)) { playersName.add(player.getName().getString()); } } @@ -86,7 +89,7 @@ public final List getPlayersInCubic(int x, int y, int z) { ResourceKey dimension = getLevel().dimension(); for (ServerPlayer player : getPlayers()) { - if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getWorldPos(), getLevel(), player, x, y, z, MAX_RANGE)) { + if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, x, y, z, MAX_RANGE)) { playersName.add(player.getName().getString()); } } @@ -99,7 +102,7 @@ public final List getPlayersInRange(int range) { ResourceKey dimension = getLevel().dimension(); for (ServerPlayer player : getPlayers()) { - if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, MAX_RANGE)) { + if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, MAX_RANGE)) { playersName.add(player.getName().getString()); } } @@ -118,7 +121,7 @@ public final boolean isPlayersInCoords(Map firstCoord, Map secondCoo if (!isAllowedMultiDimensional() && player.getLevel().dimension() != dimension) { continue; } - if (CoordUtil.isInRange(getWorldPos(), player, getLevel(), firstPos, secondPos, MAX_RANGE)) { + if (CoordUtil.isInRange(getPhysicsPos(), player, getLevel(), firstPos, secondPos, MAX_RANGE)) { return true; } } @@ -132,7 +135,7 @@ public final boolean isPlayersInCubic(int x, int y, int z) { ResourceKey dimension = getLevel().dimension(); for (ServerPlayer player : getPlayers()) { - if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getWorldPos(), getLevel(), player, x, y, z, MAX_RANGE)) { + if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, x, y, z, MAX_RANGE)) { return true; } } @@ -146,7 +149,7 @@ public final boolean isPlayersInRange(int range) { ResourceKey dimension = getLevel().dimension(); for (ServerPlayer player : getPlayers()) { - if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, MAX_RANGE)) { + if (player.getLevel().dimension() == dimension && CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, MAX_RANGE)) { return true; } } @@ -163,7 +166,7 @@ public final boolean isPlayerInCoords(Map firstCoord, Map secondCoor if (!isAllowedMultiDimensional() && player.getLevel().dimension() != dimension) { return false; } - return CoordUtil.isInRange(getWorldPos(), player, getLevel(), firstPos, secondPos, MAX_RANGE); + return CoordUtil.isInRange(getPhysicsPos(), player, getLevel(), firstPos, secondPos, MAX_RANGE); } @LuaFunction(mainThread = true) @@ -171,7 +174,7 @@ public final boolean isPlayerInCubic(int x, int y, int z, String username) { ResourceKey dimension = getLevel().dimension(); ServerPlayer player = getPlayer(username); - return player.getLevel().dimension() == dimension && CoordUtil.isInRange(getWorldPos(), getLevel(), player, x, y, z, MAX_RANGE); + return player.getLevel().dimension() == dimension && CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, x, y, z, MAX_RANGE); } @LuaFunction(mainThread = true) @@ -179,7 +182,7 @@ public final boolean isPlayerInRange(int range, String username) { ResourceKey dimension = getLevel().dimension(); ServerPlayer player = getPlayer(username); - return player.getLevel().dimension() == dimension && CoordUtil.isInRange(getWorldPos(), getLevel(), player, range, MAX_RANGE); + return player.getLevel().dimension() == dimension && CoordUtil.isInRange(getPhysicsPos(), getLevel(), player, range, MAX_RANGE); } @LuaFunction(value = {"getPlayerPos", "getPlayer"}, mainThread = true) @@ -187,7 +190,7 @@ public final Map getPlayerPos(IArguments arguments) throws LuaEx if (!APConfig.PERIPHERALS_CONFIG.playerSpy.get()) throw new LuaException("This function is disabled in the config. Activate it or ask an admin if he can activate it."); ResourceKey dimension = getLevel().dimension(); - Vec3 pos = getWorldPos(); + Vec3 pos = getPhysicsPos(); ServerPlayer player = getPlayer(arguments.getString(0)); if (player == null) { @@ -264,4 +267,13 @@ private List getPlayers() { private ServerPlayer getPlayer(String name) { return ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayerByName(name); } + + @Override + public void update() { + lastConsumedMessage = Events.traversePlayerMessages(lastConsumedMessage, message -> getConnectedComputers().forEach(computer -> { + if(message.eventName().equals("playerChangedDimension")) { + computer.queueEvent(message.eventName(), message.playerName(), message.fromDimension(), message.toDimension()); + } else computer.queueEvent(message.eventName(), message.playerName(), message.fromDimension()); + })); + } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/SaddlePeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/SaddlePeripheral.java index 68c965e63..b80b62428 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/SaddlePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/SaddlePeripheral.java @@ -14,12 +14,18 @@ import de.srendi.advancedperipherals.common.network.APNetworking; import de.srendi.advancedperipherals.common.network.toclient.SaddleTurtleInfoPacket; import de.srendi.advancedperipherals.common.util.LuaConverter; +import de.srendi.advancedperipherals.common.util.TeleportUtil; +import de.srendi.advancedperipherals.common.util.fakeplayer.APFakePlayer; import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySelector; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.TamableAnimal; +import net.minecraft.world.entity.vehicle.AbstractMinecart; +import net.minecraft.world.entity.vehicle.Boat; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.phys.EntityHitResult; @@ -68,7 +74,7 @@ public boolean isEntityRiding() { @Override public void attach(@NotNull IComputerAccess computer) { super.attach(computer); - this.lastPos = owner.getPos(); + this.lastPos = this.owner.getPos(); } @Override @@ -84,19 +90,29 @@ public void update() { return; } this.seat.keepAlive(); - BlockPos pos = owner.getPos(); - BlockPos dir = pos.subtract(this.lastPos); - int dist = Math.abs(dir.getX()) + Math.abs(dir.getY()) + Math.abs(dir.getZ()); - if (dist != 0) { - Vec3 newPos = new Vec3(pos.getX() + 0.5, pos.getY() + 0.4, pos.getZ() + 0.5); - if (dist == 1 && ++this.moveProg < ANIM_DURATION) { - float step = ((float) this.moveProg) / ANIM_DURATION; - newPos = newPos.add(Vec3.atLowerCornerOf(dir).scale(step - 1)); - } else { - this.moveProg = 0; - this.lastPos = pos; + BlockPos pos = this.owner.getPos(); + Level level = this.owner.getLevel(); + if (this.seat.getLevel() != this.owner.getLevel()) { + this.seat = TeleportUtil.teleportToWithPassengers(this.seat, (ServerLevel) level, this.seat.getTurtlePos()); + this.seat.setTurtle(this.owner.getTurtle()); + this.seat.keepAlive(); + this.rider = this.seat.getFirstPassenger(); + this.moveProg = 0; + this.lastPos = pos; + } else { + BlockPos dir = pos.subtract(this.lastPos); + int dist = Math.abs(dir.getX()) + Math.abs(dir.getY()) + Math.abs(dir.getZ()); + if (dist != 0) { + Vec3 newPos = this.seat.getTurtlePos(); + if (dist == 1 && ++this.moveProg < ANIM_DURATION) { + float step = ((float) this.moveProg) / ANIM_DURATION; + newPos = newPos.add(Vec3.atLowerCornerOf(dir).scale(step - 1)); + } else { + this.moveProg = 0; + this.lastPos = pos; + } + this.seat.moveTo(newPos); } - this.seat.moveTo(newPos.x(), newPos.y(), newPos.z()); } this.tickCount++; if (this.tickCount > 40) { @@ -108,21 +124,20 @@ public void update() { private void sendHUD() { if (this.rider instanceof ServerPlayer player) { - ITurtleAccess turtle = owner.getTurtle(); + ITurtleAccess turtle = this.owner.getTurtle(); SaddleTurtleInfoPacket packet = new SaddleTurtleInfoPacket(turtle.getFuelLevel(), turtle.getFuelLimit(), barColor); APNetworking.sendTo(packet, player); } } private boolean sitDown(@NotNull Entity entity) { - Level world = owner.getLevel(); - BlockPos pos = owner.getPos(); - this.seat = new TurtleSeatEntity(owner.getTurtle()); - this.seat.setPos(pos.getX() + 0.5, pos.getY() + 0.4, pos.getZ() + 0.5); + Level world = this.owner.getLevel(); + this.seat = new TurtleSeatEntity(this.owner.getTurtle()); + this.seat.setPos(this.seat.getTurtlePos()); if (!world.addFreshEntity(this.seat)) { return false; } - if (!entity.startRiding(this.seat, true)) { + if (!entity.startRiding(this.seat)) { return false; } if (entity instanceof TamableAnimal tamable) { @@ -138,14 +153,19 @@ private boolean standUp() { if (this.seat == null) { return false; } - boolean isVehicle = this.seat.isVehicle(); + Entity passenger = this.seat.getFirstPassenger(); + if (passenger != null) { + this.seat.ejectPassengers(); + BlockPos pos = this.owner.getPos(); + passenger.dismountTo(pos.getX() + 0.5, pos.getY() + 0.9, pos.getZ() + 0.5); + } this.seat.discard(); this.seat = null; this.rider = null; if (owner.getTurtle() instanceof TurtleBrain brain) { brain.getOwner().createServerComputer().queueEvent("saddle_release"); } - return isVehicle; + return passenger != null; } @LuaFunction(mainThread = true) @@ -154,16 +174,22 @@ public MethodResult capture() throws LuaException { return MethodResult.of(null, "Another entity is riding"); } return withOperation(SADDLE_CAPTURE, null, null, context -> { - Predicate suitableEntity = (entity) -> entity.isAlive(); + Predicate suitableEntity = EntitySelector.NO_SPECTATORS + .and((entity) -> entity instanceof LivingEntity || entity instanceof AbstractMinecart || entity instanceof Boat) + .and((entity) -> !entity.isPassenger()); if (!APConfig.PERIPHERALS_CONFIG.allowSaddleTurtleCapturePlayer.get()) { suitableEntity = suitableEntity.and((entity) -> !(entity instanceof Player)); } final Predicate finalSuitableEntity = suitableEntity; - HitResult entityHit = owner.withPlayer(player -> player.findHit(false, true, finalSuitableEntity)); + final APFakePlayer.Action action = (player) -> player.findHit(false, true, finalSuitableEntity); + HitResult entityHit = owner.withPlayer(action); if (entityHit.getType() == HitResult.Type.MISS) { - return MethodResult.of(null, "Nothing found"); + entityHit = owner.withPlayer(APFakePlayer.wrapActionWithReachRange(1, APFakePlayer.wrapActionWithRot(0, -90, action))); + if (entityHit.getType() == HitResult.Type.MISS) { + return MethodResult.of(null, "Nothing found"); + } } - LivingEntity entity = (LivingEntity) ((EntityHitResult) entityHit).getEntity(); + Entity entity = ((EntityHitResult) entityHit).getEntity(); if (!sitDown(entity)) { return MethodResult.of(null, "Entity cannot sit"); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataBlockHandPlugin.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataBlockHandPlugin.java index f7a89c5d5..d767c30ec 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataBlockHandPlugin.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataBlockHandPlugin.java @@ -54,7 +54,7 @@ public AutomataBlockHandPlugin(AutomataCorePeripheral automataCore) { @Override public @Nullable IPeripheralOperation[] getOperations() { - return new IPeripheralOperation[]{DIG, USE_ON_BLOCK}; + return new IPeripheralOperation[]{ACCURE_PLACE, DIG, UPDATE_BLOCK, USE_ON_BLOCK}; } @LuaFunction(mainThread = true) diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataLookPlugin.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataLookPlugin.java index 084f20289..cba185c95 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataLookPlugin.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/plugins/AutomataLookPlugin.java @@ -7,9 +7,11 @@ import dan200.computercraft.core.apis.TableHelper; import de.srendi.advancedperipherals.common.addons.APAddons; import de.srendi.advancedperipherals.common.addons.computercraft.owner.TurtlePeripheralOwner; +import de.srendi.advancedperipherals.common.addons.valkyrienskies.ValkyrienSkies; import de.srendi.advancedperipherals.common.util.LuaConverter; import de.srendi.advancedperipherals.common.util.fakeplayer.APFakePlayer; import de.srendi.advancedperipherals.lib.peripherals.AutomataCorePeripheral; + import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.state.BlockState; @@ -18,12 +20,11 @@ import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.registries.ForgeRegistries; -import org.jetbrains.annotations.NotNull; -import org.valkyrienskies.core.api.ships.Ship; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.jetbrains.annotations.NotNull; public class AutomataLookPlugin extends AutomataCorePlugin { @@ -52,16 +53,12 @@ public final MethodResult lookAtBlock(@NotNull IArguments arguments) throws LuaE data.put("name", blockName == null ? null : blockName.toString()); data.put("tags", LuaConverter.tagsToList(() -> state.getBlock().builtInRegistryHolder().tags())); Vec3 pos = blockHit.getLocation(); - Vec3 origin = automataCore.getWorldPos(); + Vec3 origin = automataCore.getPhysicsPos(); data.put("x", pos.x - origin.x); data.put("y", pos.y - origin.y); data.put("z", pos.z - origin.z); if (APAddons.vs2Loaded) { - Ship ship = APAddons.getVS2Ship(automataCore.getLevel(), blockPos); - if (ship != null) { - data.put("shipId", ship.getId()); - data.put("shipName", ship.getSlug()); - } + ValkyrienSkies.encodeShipInfo(automataCore.getLevel(), blockPos, data); } return MethodResult.of(data); } @@ -79,7 +76,7 @@ public final MethodResult lookAtEntity(@NotNull IArguments arguments) throws Lua } EntityHitResult entityHit = (EntityHitResult) result; - Vec3 origin = automataCore.getWorldPos(); + Vec3 origin = automataCore.getPhysicsPos(); return MethodResult.of(LuaConverter.completeEntityWithPositionToLua(entityHit.getEntity(), origin, true)); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketChatBoxUpgrade.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketChatBoxUpgrade.java index e0a17833b..5264a1b46 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketChatBoxUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketChatBoxUpgrade.java @@ -15,8 +15,8 @@ public PocketChatBoxUpgrade(ResourceLocation id, ItemStack stack) { @Nullable @Override - public ChatBoxPeripheral getPeripheral(IPocketAccess access) { - return new ChatBoxPeripheral(access); + public ChatBoxPeripheral getPeripheral(IPocketAccess pocketAccess) { + return new ChatBoxPeripheral(pocketAccess, this); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketColonyIntegratorUpgrade.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketColonyIntegratorUpgrade.java index 752ccb18e..6c439404f 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketColonyIntegratorUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketColonyIntegratorUpgrade.java @@ -13,7 +13,7 @@ public PocketColonyIntegratorUpgrade(ResourceLocation id, ItemStack stack) { } @Override - protected ColonyPeripheral getPeripheral(IPocketAccess access) { - return new ColonyPeripheral(access); + protected ColonyPeripheral getPeripheral(IPocketAccess pocketAccess) { + return new ColonyPeripheral(pocketAccess, this); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketDistanceDetectorUpgrade.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketDistanceDetectorUpgrade.java new file mode 100644 index 000000000..82b47d31f --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketDistanceDetectorUpgrade.java @@ -0,0 +1,23 @@ +package de.srendi.advancedperipherals.common.addons.computercraft.pocket; + +import dan200.computercraft.api.pocket.IPocketAccess; +import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.DistanceDetectorPeripheral; +import de.srendi.advancedperipherals.lib.pocket.BasePocketUpgrade; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class PocketDistanceDetectorUpgrade extends BasePocketUpgrade { + + public PocketDistanceDetectorUpgrade(ResourceLocation id, ItemStack stack) { + super(id, stack); + } + + @Nullable + @Override + public DistanceDetectorPeripheral getPeripheral(@NotNull IPocketAccess pocketAccess) { + return new DistanceDetectorPeripheral(pocketAccess, this); + } + +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketEnvironmentUpgrade.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketEnvironmentUpgrade.java index dc6719b17..dd23a28b8 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketEnvironmentUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketEnvironmentUpgrade.java @@ -16,8 +16,8 @@ public PocketEnvironmentUpgrade(ResourceLocation id, ItemStack stack) { @Nullable @Override - public EnvironmentDetectorPeripheral getPeripheral(@NotNull IPocketAccess iPocketAccess) { - return new EnvironmentDetectorPeripheral(iPocketAccess); + public EnvironmentDetectorPeripheral getPeripheral(@NotNull IPocketAccess pocketAccess) { + return new EnvironmentDetectorPeripheral(pocketAccess, this); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketGeoScannerUpgrade.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketGeoScannerUpgrade.java index 98823d94a..03d23d26a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketGeoScannerUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketGeoScannerUpgrade.java @@ -16,8 +16,8 @@ public PocketGeoScannerUpgrade(ResourceLocation id, ItemStack stack) { @Nullable @Override - public GeoScannerPeripheral getPeripheral(@NotNull IPocketAccess iPocketAccess) { - return new GeoScannerPeripheral(iPocketAccess); + public GeoScannerPeripheral getPeripheral(@NotNull IPocketAccess pocketAccess) { + return new GeoScannerPeripheral(pocketAccess, this); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketPlayerDetectorUpgrade.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketPlayerDetectorUpgrade.java index 1e2b6bb43..422b02e0f 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketPlayerDetectorUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/pocket/PocketPlayerDetectorUpgrade.java @@ -16,8 +16,8 @@ public PocketPlayerDetectorUpgrade(ResourceLocation id, ItemStack stack) { @Nullable @Override - public PlayerDetectorPeripheral getPeripheral(@NotNull IPocketAccess iPocketAccess) { - return new PlayerDetectorPeripheral(iPocketAccess); + public PlayerDetectorPeripheral getPeripheral(@NotNull IPocketAccess pocketAccess) { + return new PlayerDetectorPeripheral(pocketAccess, this); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/turtles/TurtleChatBoxUpgrade.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/turtles/TurtleChatBoxUpgrade.java index b82aafab2..f8d9f7e4d 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/turtles/TurtleChatBoxUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/turtles/TurtleChatBoxUpgrade.java @@ -29,15 +29,4 @@ public ModelResourceLocation getRightModel() { protected ChatBoxPeripheral buildPeripheral(@NotNull ITurtleAccess turtle, @NotNull TurtleSide side) { return new ChatBoxPeripheral(turtle, side); } - - @Override - public void update(@NotNull ITurtleAccess turtle, @NotNull TurtleSide side) { - super.update(turtle, side); - if (turtle.getLevel().isClientSide) - return; - - if (turtle.getPeripheral(side) instanceof ChatBoxPeripheral chatBox) { - chatBox.update(); - } - } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/mekanism/MekanismCapabilities.java b/src/main/java/de/srendi/advancedperipherals/common/addons/mekanism/MekanismCapabilities.java index 858a11b3d..026e1c25a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/mekanism/MekanismCapabilities.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/mekanism/MekanismCapabilities.java @@ -7,9 +7,5 @@ import static net.minecraftforge.common.capabilities.CapabilityManager.get; public class MekanismCapabilities { - - public static final Capability GAS_HANDLER = get(new CapabilityToken<>() { - }); - - + public static final Capability GAS_HANDLER = get(new CapabilityToken<>() {}); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/AutomataVSMountPlugin.java b/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/AutomataVSMountPlugin.java index 758b46a85..543b673cc 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/AutomataVSMountPlugin.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/AutomataVSMountPlugin.java @@ -16,6 +16,7 @@ import net.minecraft.world.phys.Vec3; import org.joml.Vector3d; import org.valkyrienskies.core.api.ships.ServerShip; +import org.valkyrienskies.mod.common.VSGameUtilsKt; import java.util.List; import java.util.Map; @@ -38,7 +39,7 @@ public final boolean isOnShip() { @LuaFunction(mainThread = true) public final MethodResult getCurrentShip() { IPeripheralOwner owner = this.automataCore.getPeripheralOwner(); - ServerShip ship = (ServerShip) APAddons.getVS2Ship(owner.getLevel(), owner.getPos()); + ServerShip ship = (ServerShip) VSGameUtilsKt.getShipObjectManagingPos(owner.getLevel(), owner.getPos()); if (ship == null) { return MethodResult.of(); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/ValkyrienSkies.java b/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/ValkyrienSkies.java index 61d084da1..9e032a0eb 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/ValkyrienSkies.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/valkyrienskies/ValkyrienSkies.java @@ -1,8 +1,8 @@ package de.srendi.advancedperipherals.common.addons.valkyrienskies; -import de.srendi.advancedperipherals.common.addons.APAddons; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import org.joml.Vector3d; import org.valkyrienskies.core.api.ships.ServerShip; @@ -11,12 +11,44 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; public final class ValkyrienSkies { private ValkyrienSkies() {} + public static boolean isBlockOnShip(Level level, BlockPos pos) { + return VSGameUtilsKt.isBlockInShipyard(level, pos); + } + + public static Vec3 transformToWorldPos(Level level, BlockPos blockPos, Vec3 pos) { + Ship ship = VSGameUtilsKt.getShipObjectManagingPos(level, blockPos); + if (ship == null) { + return pos; + } + Vector3d newPos = ship.getShipToWorld().transformPosition(new Vector3d(pos.x, pos.y, pos.z)); + return new Vec3(newPos.x, newPos.y, newPos.z); + } + + public static Vec3 transformToWorldDir(Level level, BlockPos blockPos, Vec3 dir) { + Ship ship = VSGameUtilsKt.getShipObjectManagingPos(level, blockPos); + if (ship == null) { + return dir; + } + Vector3d newDir = ship.getShipToWorld().transformDirection(new Vector3d(dir.x, dir.y, dir.z)); + return new Vec3(newDir.x, newDir.y, newDir.z); + } + + public static void encodeShipInfo(Level level, BlockPos blockPos, Map data) { + Ship ship = VSGameUtilsKt.getShipObjectManagingPos(level, blockPos); + if (ship == null) { + return; + } + data.put("shipId", ship.getId()); + data.put("shipName", ship.getSlug()); + } + public static List getNearbyShips(ServerLevel level, Vec3 pos, double radius) { - Ship ship = APAddons.getVS2Ship(level, new BlockPos(pos)); + Ship ship = VSGameUtilsKt.getShipObjectManagingPos(level, new BlockPos(pos)); if (ship != null) { Vector3d newPos = ship.getShipToWorld().transformPosition(new Vector3d(pos.x, pos.y, pos.z)); pos = new Vec3(newPos.x, newPos.y, newPos.z); diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/APBlockEntityBlock.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/APBlockEntityBlock.java index abbc0c374..5f26e6965 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/APBlockEntityBlock.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/APBlockEntityBlock.java @@ -1,6 +1,5 @@ package de.srendi.advancedperipherals.common.blocks.base; -import de.srendi.advancedperipherals.common.blocks.blockentities.EnergyDetectorEntity; import net.minecraft.core.BlockPos; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.entity.BlockEntity; @@ -33,11 +32,6 @@ public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState sta @Override public void onNeighborChange(BlockState state, LevelReader level, BlockPos pos, BlockPos neighbor) { super.onNeighborChange(state, level, pos, neighbor); - - BlockEntity blockEntity = level.getBlockEntity(pos); - - if(blockEntity instanceof EnergyDetectorEntity energyDetector) - energyDetector.invalidateStorages(); - + // BlockEntity blockEntity = level.getBlockEntity(pos); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/BaseDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/BaseDetectorEntity.java new file mode 100644 index 000000000..0912220ab --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/BaseDetectorEntity.java @@ -0,0 +1,151 @@ +package de.srendi.advancedperipherals.common.blocks.base; + +import de.srendi.advancedperipherals.common.util.proxy.IStorageProxy; +import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @param The storage handle type + * @param The storage proxy type, must implements/extends both {@code } and {@link IStorageProxy} + * @param

The peripheral type, must extends {@link BasePeripheral} + */ +public abstract class BaseDetectorEntity> extends PeripheralBlockEntity

{ + + private static final String RATE_LIMIT_TAG = "RateLimit"; + + private final Capability capability; + // proxy that will forward X to the output but limit it to maxTransferRate + private final S proxy = createProxy(); + private volatile long transferRate = 0; + private LazyOptional inputStorageCap = LazyOptional.empty(); + private LazyOptional zeroStorageCap = LazyOptional.empty(); + + protected BaseDetectorEntity(BlockEntityType tileEntityType, BlockPos pos, BlockState state, Capability capability) { + super(tileEntityType, pos, state); + this.capability = capability; + } + + @NotNull + protected abstract S createProxy(); + + @NotNull + protected abstract T getZeroStorage(); + + @NotNull + protected S getStorageProxy() { + return this.proxy; + } + + /** + * @return the transfered amount of stuff in the last tick + */ + public long getTransferRate() { + return this.transferRate; + } + + /** + * @return the possible maximum transfered amount + */ + public long getMaxTransferRate() { + return this.proxy.getMaxTransferRate(); + } + + /** + * @return the max amount of stuff can be transfered in a tick + */ + public long getTransferRateLimit() { + return this.proxy.getTransferRate(); + } + + /** + * @param rate the max amount of stuff can be transfered in a tick + */ + public void setTransferRateLimit(long rate) { + if (this.proxy.getTransferRate() != rate) { + this.proxy.setTransferRate(rate); + this.setChanged(); + } + } + + /** + * @return the ID of last transfered stuff + */ + @Nullable + public String getLastTransferedId() { + return this.proxy.getLastTransferedId(); + } + + /** + * @return the ID of ready transfered stuff + */ + @Nullable + public String getReadyTransferId() { + return this.proxy.getReadyTransferId(); + } + + public Direction getInputDirection() { + return this.getBlockState().getValue(BaseBlock.ORIENTATION).front(); + } + + public Direction getOutputDirection() { + return this.getBlockState().getValue(BaseBlock.ORIENTATION).front().getOpposite(); + } + + @NotNull + @Override + public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { + Direction inputDirection = this.getInputDirection(); + Direction outputDirection = this.getOutputDirection(); + if (cap == this.capability) { + if (direction == inputDirection) { + if (!this.inputStorageCap.isPresent()) { + this.inputStorageCap = LazyOptional.of(this::getStorageProxy); + } + return this.inputStorageCap.cast(); + } else if (direction == outputDirection) { + if (!this.zeroStorageCap.isPresent()) { + this.zeroStorageCap = LazyOptional.of(this::getZeroStorage); + } + return this.zeroStorageCap.cast(); + } + } + return super.getCapability(cap, direction); + } + + @Override + public void saveAdditional(@NotNull CompoundTag compound) { + super.saveAdditional(compound); + compound.putLong(RATE_LIMIT_TAG, this.getTransferRateLimit()); + } + + @Override + public void load(@NotNull CompoundTag nbt) { + this.proxy.setTransferRate(nbt.getLong(RATE_LIMIT_TAG)); + super.load(nbt); + } + + @Override + public void handleTick(Level level, BlockState state, BlockEntityType type) { + super.handleTick(level, state, type); + if (!level.isClientSide()) { + this.transferRate = this.proxy.getAndResetTransfered(); + } + } + + @NotNull + public LazyOptional getOutputStorage() { + Direction outputDirection = this.getOutputDirection(); + BlockEntity be = level.getBlockEntity(worldPosition.relative(outputDirection)); + return be == null ? LazyOptional.empty() : be.getCapability(this.capability, outputDirection.getOpposite()); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java index d6f256b4e..e62d578c7 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java @@ -1,7 +1,6 @@ package de.srendi.advancedperipherals.common.blocks.base; import dan200.computercraft.api.peripheral.IComputerAccess; -import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.shared.Capabilities; import de.srendi.advancedperipherals.AdvancedPeripherals; @@ -21,7 +20,9 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.common.capabilities.Capability; @@ -39,13 +40,11 @@ public abstract class PeripheralBlockEntity> extends BaseContainerBlockEntity implements WorldlyContainer, MenuProvider, IPeripheralTileEntity { private static final String PERIPHERAL_SETTINGS_KEY = "peripheralSettings"; - protected CompoundTag peripheralSettings; + protected CompoundTag peripheralSettings = new CompoundTag(); protected NonNullList items; - @Nullable - protected T peripheral = null; - private LazyOptional handler; - private LazyOptional fluidHandler; - private LazyOptional peripheralCap; + private LazyOptional handler = LazyOptional.empty(); + private LazyOptional fluidHandler = LazyOptional.empty(); + private LazyOptional peripheralCap = LazyOptional.empty(); protected PeripheralBlockEntity(BlockEntityType tileEntityTypeIn, BlockPos pos, BlockState state) { super(tileEntityTypeIn, pos, state); @@ -54,44 +53,27 @@ protected PeripheralBlockEntity(BlockEntityType tileEntityTypeIn, BlockPos po } else { items = NonNullList.withSize(0, ItemStack.EMPTY); } - peripheralSettings = new CompoundTag(); } @NotNull @Override - public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { + public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { if (cap == Capabilities.CAPABILITY_PERIPHERAL) { - if (peripheral == null) - // Perform later peripheral creation, because creating peripheral - // on init of tile entity cause some infinity loop, if peripheral - // are depend on tile entity data - this.peripheral = createPeripheral(); - if (peripheral.isEnabled()) { - if (peripheralCap == null) { - peripheralCap = LazyOptional.of(() -> peripheral); - } else if (!peripheralCap.isPresent()) { - // Recreate peripheral to allow CC: Tweaked correctly handle - // peripheral update logic, so new peripheral and old one will be - // different - peripheral = createPeripheral(); - peripheralCap = LazyOptional.of(() -> peripheral); + return this.getLazyPeripheral().cast(); + } else if (cap == ForgeCapabilities.ITEM_HANDLER) { + if (!remove && direction != null && this instanceof IInventoryBlock) { + if (!handler.isPresent()) { + handler = LazyOptional.of(() -> new SidedInvWrapper(this, Direction.NORTH)); } - return peripheralCap.cast(); - } else { - AdvancedPeripherals.debug(peripheral.getType() + " is disabled, you can enable it in the Configuration."); + return handler.cast(); + } + } else if (cap == ForgeCapabilities.FLUID_HANDLER) { + if (!remove && direction != null) { + if (!fluidHandler.isPresent()) { + fluidHandler = LazyOptional.of(() -> new FluidTank(0)); + } + return fluidHandler.cast(); } - } - - if (cap == ForgeCapabilities.ITEM_HANDLER && !remove && direction != null && this instanceof IInventoryBlock) { - if (handler == null || !handler.isPresent()) - handler = LazyOptional.of(() -> new SidedInvWrapper(this, Direction.NORTH)); - return handler.cast(); - } - - if (cap == ForgeCapabilities.FLUID_HANDLER && !remove && direction != null) { - if (fluidHandler == null || !fluidHandler.isPresent()) - fluidHandler = LazyOptional.of(() -> new FluidTank(0)); - return fluidHandler.cast(); } return super.getCapability(cap, direction); } @@ -99,26 +81,39 @@ public LazyOptional getCapability(@NotNull Capability cap, @Nullabl @Override public void invalidateCaps() { super.invalidateCaps(); - if (peripheralCap != null) - peripheralCap.invalidate(); - if (handler != null) - handler.invalidate(); - if (fluidHandler != null) - fluidHandler.invalidate(); + peripheralCap.invalidate(); + handler.invalidate(); + fluidHandler.invalidate(); } @NotNull protected abstract T createPeripheral(); public Iterable getConnectedComputers() { - if (peripheral == null) // just avoid some NPE in strange cases - return Collections.emptyList(); - return peripheral.getConnectedComputers(); + return this.getLazyPeripheral().map(BasePeripheral::getConnectedComputers).orElse(Collections.emptyList()); + } + + public LazyOptional getLazyPeripheral() { + // Perform later peripheral creation, because creating peripheral + // on init of tile entity cause some infinity loop, if peripheral + // are depend on tile entity data + if (!this.peripheralCap.isPresent()) { + // Recreate peripheral to allow CC: Tweaked correctly handle + // peripheral update logic, so new peripheral and old one will be + // different + final T peripheral = createPeripheral(); + if (!peripheral.isEnabled()) { + AdvancedPeripherals.debug(peripheral.getType() + " is disabled, you can enable it in the Configuration."); + return LazyOptional.empty(); + } + this.peripheralCap = LazyOptional.of(() -> peripheral); + } + return this.peripheralCap; } @Nullable public T getPeripheral() { - return peripheral; + return this.getLazyPeripheral().orElse(null); } /*@Override @@ -130,7 +125,9 @@ public ITextComponent getDisplayName() { public void saveAdditional(@NotNull CompoundTag compound) { super.saveAdditional(compound); ContainerHelper.saveAllItems(compound, items); - if (!peripheralSettings.isEmpty()) compound.put(PERIPHERAL_SETTINGS_KEY, peripheralSettings); + if (!peripheralSettings.isEmpty()) { + compound.put(PERIPHERAL_SETTINGS_KEY, peripheralSettings); + } } @Override @@ -235,13 +232,21 @@ public void markSettingsChanged() { this.setChanged(); } - protected void sendUpdate() { + public void sendUpdate() { this.setChanged(); - this.getLevel().sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 11); + Level level = this.getLevel(); + if (level != null) { + level.sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 11); + } } public ComputerSide getComputerSide(Direction direction) { FrontAndTop orientation = getBlockState().getValue(BaseBlock.ORIENTATION); return CoordUtil.getComputerSide(orientation, direction); } + + @Override + public void handleTick(Level level, BlockState state, BlockEntityType type) { + this.getLazyPeripheral().ifPresent(BasePeripheral::update); + } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PoweredPeripheralBlockEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PoweredPeripheralBlockEntity.java index 21a25c070..4178f0c5c 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PoweredPeripheralBlockEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PoweredPeripheralBlockEntity.java @@ -17,15 +17,10 @@ public abstract class PoweredPeripheralBlockEntity> extends PeripheralBlockEntity { - private final LazyOptional lazyEnergyStorage; + private LazyOptional lazyEnergyStorage = LazyOptional.empty(); protected PoweredPeripheralBlockEntity(BlockEntityType tileEntityTypeIn, BlockPos pos, BlockState state) { super(tileEntityTypeIn, pos, state); - if (APConfig.PERIPHERALS_CONFIG.enablePoweredPeripherals.get()) { - lazyEnergyStorage = LazyOptional.of(() -> new EnergyStorage(this.getMaxEnergyStored())); - } else { - lazyEnergyStorage = LazyOptional.empty(); - } } protected abstract int getMaxEnergyStored(); @@ -43,9 +38,14 @@ public void load(@NotNull CompoundTag compound) { } @Override - public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { - if (cap == ForgeCapabilities.ENERGY && lazyEnergyStorage.isPresent()) { - return lazyEnergyStorage.cast(); + public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { + if (cap == ForgeCapabilities.ENERGY) { + if (APConfig.PERIPHERALS_CONFIG.enablePoweredPeripherals.get()) { + if (!lazyEnergyStorage.isPresent()) { + lazyEnergyStorage = LazyOptional.of(() -> new EnergyStorage(this.getMaxEnergyStored())); + } + return lazyEnergyStorage.cast(); + } } return super.getCapability(cap, direction); } @@ -55,5 +55,4 @@ public void invalidateCaps() { super.invalidateCaps(); this.lazyEnergyStorage.invalidate(); } - } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/ChatBoxEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/ChatBoxEntity.java index 594645f0c..24e57b8d6 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/ChatBoxEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/ChatBoxEntity.java @@ -4,9 +4,6 @@ import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; @@ -21,11 +18,4 @@ public ChatBoxEntity(BlockPos pos, BlockState state) { protected ChatBoxPeripheral createPeripheral() { return new ChatBoxPeripheral(this); } - - @Override - public void handleTick(Level level, BlockState state, BlockEntityType type) { - if (peripheral != null) { - peripheral.update(); - } - } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java index 2a719f949..9af645790 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java @@ -1,37 +1,25 @@ package de.srendi.advancedperipherals.common.blocks.blockentities; -import de.srendi.advancedperipherals.common.addons.APAddons; import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.DistanceDetectorPeripheral; import de.srendi.advancedperipherals.common.blocks.base.BaseBlock; import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes; -import de.srendi.advancedperipherals.common.util.HitResultUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.world.level.ClipContext; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; -import org.joml.Vector3d; -import org.valkyrienskies.core.api.ships.Ship; - -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; public class DistanceDetectorEntity extends PeripheralBlockEntity { - private final AtomicInteger maxRange = new AtomicInteger(Float.floatToRawIntBits(APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue())); - private final AtomicInteger currentDistance = new AtomicInteger(Float.floatToRawIntBits(-1)); - private final AtomicBoolean showLaser = new AtomicBoolean(true); - private volatile boolean periodicallyCalculate = false; + private volatile float maxRange = APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue(); + private float currentDistance = -1; + private volatile boolean showLaser = true; + private volatile boolean calculatePeriodically = false; private volatile boolean ignoreTransparent = true; private volatile DistanceDetectorPeripheral.DetectionType detectionType = DistanceDetectorPeripheral.DetectionType.BOTH; @@ -46,69 +34,43 @@ protected DistanceDetectorPeripheral createPeripheral() { } public float getMaxRange() { - return Float.intBitsToFloat(this.maxRange.get()); - } - - protected void setMaxRangeNoUpdate(float maxRange) { - maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue()); - int maxRangeBits = Float.floatToRawIntBits(maxRange); - this.maxRange.set(maxRangeBits); + return this.maxRange; } public void setMaxRange(float maxRange) { - maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue()); - int maxRangeBits = Float.floatToRawIntBits(maxRange); - if (this.maxRange.getAndSet(maxRangeBits) != maxRange) { - this.sendUpdate(); - } + this.maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue()); } public float getCurrentDistance() { - return Float.intBitsToFloat(this.currentDistance.get()); - } - - protected void setCurrentDistanceNoUpdate(float currentDistance) { - int currentDistanceBits = Float.floatToRawIntBits(currentDistance); - this.currentDistance.set(currentDistanceBits); + return this.currentDistance; } public void setCurrentDistance(float currentDistance) { - int currentDistanceBits = Float.floatToRawIntBits(currentDistance); - if (this.currentDistance.getAndSet(currentDistanceBits) != currentDistanceBits) { - this.sendUpdate(); - } + this.currentDistance = currentDistance; } - public boolean getLaserVisibility() { - return this.showLaser.get(); - } - - protected void setShowLaserNoUpdate(boolean showLaser) { - this.showLaser.set(showLaser); + public boolean getShowLaser() { + return this.showLaser; } public void setShowLaser(boolean showLaser) { - if (this.showLaser.getAndSet(showLaser) != showLaser) { - this.sendUpdate(); - } + this.showLaser = showLaser; } - public boolean shouldCalculatePeriodically() { - return this.periodicallyCalculate; + public boolean getCalculatePeriodically() { + return this.calculatePeriodically; } - public void setShouldCalculatePeriodically(boolean periodicallyCalculate) { - this.periodicallyCalculate = periodicallyCalculate; - this.setChanged(); + public void setCalculatePeriodically(boolean calculatePeriodically) { + this.calculatePeriodically = calculatePeriodically; } - public boolean ignoreTransparent() { + public boolean getIgnoreTransparent() { return this.ignoreTransparent; } public void setIgnoreTransparent(boolean ignoreTransparent) { this.ignoreTransparent = ignoreTransparent; - this.setChanged(); } public DistanceDetectorPeripheral.DetectionType getDetectionType() { @@ -117,18 +79,6 @@ public DistanceDetectorPeripheral.DetectionType getDetectionType() { public void setDetectionType(DistanceDetectorPeripheral.DetectionType detectionType) { this.detectionType = detectionType; - this.setChanged(); - } - - @Override - public void handleTick(Level level, BlockState state, BlockEntityType type) { - if (level.getGameTime() % APConfig.PERIPHERALS_CONFIG.distanceDetectorUpdateRate.get() == 0 && this.shouldCalculatePeriodically()) { - // We calculate the distance every 2 ticks, so we do not have to run the getDistance function of the peripheral - // on the main thread which prevents the 1 tick yield time of the function. - // The calculateDistance function is not thread safe, so we have to run it on the main thread. - // It should be okay to run that function every 2 ticks, calculating it does not take too much time. - this.calculateAndUpdateDistance(); - } } @Override @@ -145,10 +95,10 @@ public AABB getRenderBoundingBox() { @Override public void load(@NotNull CompoundTag compound) { - this.setMaxRangeNoUpdate(compound.getFloat("maxRange")); - this.setCurrentDistanceNoUpdate(compound.getFloat("currentDistance")); - this.setShowLaserNoUpdate(compound.getBoolean("showLaser")); - this.setShouldCalculatePeriodically(compound.getBoolean("calculatePeriodically")); + this.setMaxRange(compound.getFloat("maxRange")); + this.setCurrentDistance(compound.getFloat("currentDistance")); + this.setShowLaser(compound.getBoolean("showLaser")); + this.setCalculatePeriodically(compound.getBoolean("calculatePeriodically")); this.setIgnoreTransparent(compound.getBoolean("ignoreTransparent")); this.setDetectionType(DistanceDetectorPeripheral.DetectionType.values()[compound.getByte("detectionType")]); super.load(compound); @@ -159,9 +109,9 @@ public void saveAdditional(@NotNull CompoundTag compound) { super.saveAdditional(compound); compound.putFloat("maxRange", this.getMaxRange()); compound.putFloat("currentDistance", this.getCurrentDistance()); - compound.putBoolean("showLaser", this.getLaserVisibility()); - compound.putBoolean("calculatePeriodically", this.shouldCalculatePeriodically()); - compound.putBoolean("ignoreTransparent", this.ignoreTransparent()); + compound.putBoolean("showLaser", this.getShowLaser()); + compound.putBoolean("calculatePeriodically", this.getCalculatePeriodically()); + compound.putBoolean("ignoreTransparent", this.getIgnoreTransparent()); compound.putByte("detectionType", (byte) this.getDetectionType().ordinal()); } @@ -170,7 +120,7 @@ public CompoundTag getUpdateTag() { CompoundTag compound = super.getUpdateTag(); compound.putFloat("maxRange", this.getMaxRange()); compound.putFloat("currentDistance", this.getCurrentDistance()); - compound.putBoolean("showLaser", this.getLaserVisibility()); + compound.putBoolean("showLaser", this.getShowLaser()); return compound; } @@ -178,59 +128,4 @@ public CompoundTag getUpdateTag() { public ClientboundBlockEntityDataPacket getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } - - protected Vec3 getCenterPos() { - Vec3 pos = Vec3.atCenterOf(this.getBlockPos()); - if (!APAddons.vs2Loaded) { - return pos; - } - Ship ship = APAddons.getVS2Ship(this.getLevel(), this.getBlockPos()); - if (ship == null) { - return pos; - } - Vector3d newPos = ship.getShipToWorld().transformPosition(new Vector3d(pos.x, pos.y, pos.z)); - return new Vec3(newPos.x, newPos.y, newPos.z); - } - - protected Vec3 getDirection() { - Vec3 dir = Vec3.atLowerCornerOf(getBlockState().getValue(BaseBlock.ORIENTATION).front().getNormal()); - if (!APAddons.vs2Loaded) { - return dir; - } - Ship ship = APAddons.getVS2Ship(this.getLevel(), this.getBlockPos()); - if (ship == null) { - return dir; - } - Vector3d newDir = ship.getShipToWorld().transformDirection(new Vector3d(dir.x, dir.y, dir.z)); - return new Vec3(newDir.x, newDir.y, newDir.z); - } - - public double calculateDistance() { - final double maxRange = this.getMaxRange(); - Vec3 direction = getDirection(); - Vec3 center = getCenterPos(); - Vec3 from = center; - Vec3 to = from.add(direction.x * maxRange, direction.y * maxRange, direction.z * maxRange); - - HitResult result = this.getHitResult(to, from); - if (result.getType() == HitResult.Type.MISS) { - return -1; - } - return result.getLocation().distanceTo(center) - 0.5f; - } - - public double calculateAndUpdateDistance() { - double distance = this.calculateDistance(); - this.setCurrentDistance((float) distance); - return distance; - } - - private HitResult getHitResult(Vec3 to, Vec3 from) { - Level level = this.getLevel(); - return switch (this.detectionType) { - case ENTITY -> HitResultUtil.getEntityHitResult(to, from, level); - case BLOCK -> HitResultUtil.getBlockHitResult(to, from, level, this.ignoreTransparent ? HitResultUtil.IgnoreNoOccludedContext.INSTANCE : ClipContext.Block.COLLIDER, this.getBlockPos()); - case BOTH -> HitResultUtil.getHitResult(to, from, level, this.ignoreTransparent ? HitResultUtil.IgnoreNoOccludedContext.INSTANCE : ClipContext.Block.COLLIDER, this.getBlockPos()); - }; - } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/EnergyDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/EnergyDetectorEntity.java index 1a9aaad04..fd825dc4f 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/EnergyDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/EnergyDetectorEntity.java @@ -1,108 +1,40 @@ package de.srendi.advancedperipherals.common.blocks.blockentities; import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.EnergyDetectorPeripheral; -import de.srendi.advancedperipherals.common.blocks.base.BaseBlock; -import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; +import de.srendi.advancedperipherals.common.blocks.base.BaseDetectorEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes; -import de.srendi.advancedperipherals.common.util.EnergyStorageProxy; +import de.srendi.advancedperipherals.common.util.proxy.EnergyStorageProxy; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.energy.EnergyStorage; import net.minecraftforge.energy.IEnergyStorage; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Optional; +public class EnergyDetectorEntity extends BaseDetectorEntity { -public class EnergyDetectorEntity extends PeripheralBlockEntity { - - public int transferRate = 0; - //storageProxy that will forward the energy to the output but limit it to maxTransferRate - public final EnergyStorageProxy storageProxy = new EnergyStorageProxy(this, APConfig.PERIPHERALS_CONFIG.energyDetectorMaxFlow.get()); - //a zero size, zero transfer energy storage to ensure that cables connect - private final EnergyStorage zeroStorage = new EnergyStorage(0, 0, 0); - private final LazyOptional energyStorageCap = LazyOptional.of(() -> storageProxy); - private final LazyOptional zeroStorageCap = LazyOptional.of(() -> zeroStorage); - @NotNull - private Optional outReceivingStorage = Optional.empty(); - - private Direction energyInDirection = Direction.NORTH; - private Direction energyOutDirection = Direction.SOUTH; + private static final EnergyStorage ZERO_STORAGE = new EnergyStorage(0, 0, 0); public EnergyDetectorEntity(BlockPos pos, BlockState state) { - super(APBlockEntityTypes.ENERGY_DETECTOR.get(), pos, state); + super(APBlockEntityTypes.ENERGY_DETECTOR.get(), pos, state, ForgeCapabilities.ENERGY); } - @NotNull @Override + @NotNull protected EnergyDetectorPeripheral createPeripheral() { return new EnergyDetectorPeripheral(this); } - @NotNull - @Override - public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { - energyInDirection = getBlockState().getValue(BaseBlock.ORIENTATION).front(); - energyOutDirection = getBlockState().getValue(BaseBlock.ORIENTATION).front().getOpposite(); - if (cap == ForgeCapabilities.ENERGY) { - if (direction == energyInDirection) { - return energyStorageCap.cast(); - } else if (direction == energyOutDirection) { - return zeroStorageCap.cast(); - } - } - return super.getCapability(cap, direction); - } - @Override - public void saveAdditional(@NotNull CompoundTag compound) { - super.saveAdditional(compound); - compound.putInt("rateLimit", storageProxy.getMaxTransferRate()); - } - - @Override - public void handleTick(Level level, BlockState state, BlockEntityType type) { - if (!level.isClientSide) { - // this handles the rare edge case that receiveEnergy is called multiple times in one tick - transferRate = storageProxy.getTransferedInThisTick(); - storageProxy.resetTransferedInThisTick(); - } + @NotNull + protected EnergyStorageProxy createProxy() { + return new EnergyStorageProxy(this, APConfig.PERIPHERALS_CONFIG.energyDetectorMaxFlow.get()); } @Override - public void load(@NotNull CompoundTag nbt) { - storageProxy.setMaxTransferRate(nbt.getInt("rateLimit")); - super.load(nbt); - } - - public void invalidateStorages() { - outReceivingStorage = Optional.empty(); - } - - // returns the cached output storage of the receiving block or fetches it if it has been invalidated @NotNull - public Optional getOutputStorage() { - // the documentation says that the value of the LazyOptional should be cached locally and invalidated using addListener - if (outReceivingStorage.isEmpty()) { - BlockEntity teOut = level.getBlockEntity(worldPosition.relative(energyOutDirection)); - if (teOut == null) { - return Optional.empty(); - } - LazyOptional lazyOptionalOutStorage = teOut.getCapability(ForgeCapabilities.ENERGY, energyOutDirection.getOpposite()); - outReceivingStorage = lazyOptionalOutStorage.resolve(); - lazyOptionalOutStorage.addListener(l -> { - outReceivingStorage = Optional.empty(); - }); - } - return outReceivingStorage; + protected IEnergyStorage getZeroStorage() { + return ZERO_STORAGE; } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/FluidDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/FluidDetectorEntity.java index 81d713ec2..82a9b7788 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/FluidDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/FluidDetectorEntity.java @@ -1,106 +1,40 @@ package de.srendi.advancedperipherals.common.blocks.blockentities; import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.FluidDetectorPeripheral; -import de.srendi.advancedperipherals.common.blocks.base.BaseBlock; -import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; +import de.srendi.advancedperipherals.common.blocks.base.BaseDetectorEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes; -import de.srendi.advancedperipherals.common.util.FluidStorageProxy; +import de.srendi.advancedperipherals.common.util.proxy.FluidStorageProxy; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.capabilities.Capability; 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.fluids.capability.templates.FluidTank; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Optional; +public class FluidDetectorEntity extends BaseDetectorEntity { -public class FluidDetectorEntity extends PeripheralBlockEntity { - - public int transferRate = 0; - public FluidStack lastFlowedLiquid = FluidStack.EMPTY; - - //storageProxy that will forward the fluid to the output but limit it to maxTransferRate - public final FluidStorageProxy storageProxy = new FluidStorageProxy(this, APConfig.PERIPHERALS_CONFIG.fluidDetectorMaxFlow.get()); - //a zero size, zero transfer fluid storage to ensure that cables connect - private final FluidTank zeroStorage = new FluidTank(0); - private final LazyOptional fluidStorageCap = LazyOptional.of(() -> storageProxy); - private final LazyOptional zeroStorageCap = LazyOptional.of(() -> zeroStorage); - private Optional outReceivingStorage = Optional.empty(); - - private Direction fluidInDetection = Direction.NORTH; - private Direction fluidOutDirection = Direction.SOUTH; + private static final FluidTank ZERO_STORAGE = new FluidTank(0); public FluidDetectorEntity(BlockPos pos, BlockState state) { - super(APBlockEntityTypes.FLUID_DETECTOR.get(), pos, state); + super(APBlockEntityTypes.FLUID_DETECTOR.get(), pos, state, ForgeCapabilities.FLUID_HANDLER); } - @NotNull @Override + @NotNull protected FluidDetectorPeripheral createPeripheral() { return new FluidDetectorPeripheral(this); } - @NotNull @Override - public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { - fluidInDetection = getBlockState().getValue(BaseBlock.ORIENTATION).front(); - fluidOutDirection = getBlockState().getValue(BaseBlock.ORIENTATION).front().getOpposite(); - if (cap == ForgeCapabilities.FLUID_HANDLER) { - if (direction == fluidInDetection) { - return fluidStorageCap.cast(); - } else if (direction == fluidOutDirection) { - return zeroStorageCap.cast(); - } - } - return super.getCapability(cap, direction); - } - - @Override - public void saveAdditional(@NotNull CompoundTag compound) { - super.saveAdditional(compound); - compound.putInt("rateLimit", storageProxy.getMaxTransferRate()); - } - - @Override - public void handleTick(Level level, BlockState state, BlockEntityType type) { - if (!level.isClientSide) { - // this handles the rare edge case that receiveFluid is called multiple times in one tick - transferRate = storageProxy.getTransferedInThisTick(); - storageProxy.resetTransferedInThisTick(); - } + @NotNull + protected FluidStorageProxy createProxy() { + return new FluidStorageProxy(this, APConfig.PERIPHERALS_CONFIG.fluidDetectorMaxFlow.get()); } @Override - public void load(@NotNull CompoundTag nbt) { - storageProxy.setMaxTransferRate(nbt.getInt("rateLimit")); - super.load(nbt); - } - - // returns the cached output storage of the receiving block or fetches it if it has been invalidated @NotNull - public Optional getOutputStorage() { - // the documentation says that the value of the LazyOptional should be cached locally and invalidated using addListener - if (outReceivingStorage.isEmpty()) { - BlockEntity teOut = level.getBlockEntity(worldPosition.relative(fluidOutDirection)); - if (teOut == null) { - return Optional.empty(); - } - LazyOptional lazyOptionalOutStorage = teOut.getCapability(ForgeCapabilities.FLUID_HANDLER, fluidOutDirection.getOpposite()); - outReceivingStorage = lazyOptionalOutStorage.resolve(); - lazyOptionalOutStorage.addListener(l -> { - outReceivingStorage = Optional.empty(); - }); - } - return outReceivingStorage; + protected IFluidHandler getZeroStorage() { + return ZERO_STORAGE; } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/GasDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/GasDetectorEntity.java index e87529830..cb1cf6d2b 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/GasDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/GasDetectorEntity.java @@ -2,105 +2,40 @@ import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.GasDetectorPeripheral; import de.srendi.advancedperipherals.common.addons.mekanism.MekanismCapabilities; -import de.srendi.advancedperipherals.common.blocks.base.BaseBlock; -import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; +import de.srendi.advancedperipherals.common.blocks.base.BaseDetectorEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes; -import de.srendi.advancedperipherals.common.util.GasStorageProxy; -import de.srendi.advancedperipherals.common.util.ZeroGasTank; -import mekanism.api.chemical.gas.GasStack; +import de.srendi.advancedperipherals.common.util.proxy.GasStorageProxy; +import de.srendi.advancedperipherals.common.util.proxy.ZeroGasTank; import mekanism.api.chemical.gas.IGasHandler; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.LazyOptional; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Optional; +public class GasDetectorEntity extends BaseDetectorEntity { -public class GasDetectorEntity extends PeripheralBlockEntity { - - public int transferRate = 0; - public GasStack lastFlowedGas = GasStack.EMPTY; - - //storageProxy that will forward the gas to the output but limit it to maxTransferRate - public final GasStorageProxy storageProxy = new GasStorageProxy(this, APConfig.PERIPHERALS_CONFIG.gasDetectorMaxFlow.get()); - //a zero size, zero transfer gas storage to ensure that cables connect - private final IGasHandler zeroStorage = new ZeroGasTank(); - private final LazyOptional gasStorageCap = LazyOptional.of(() -> storageProxy); - private final LazyOptional zeroStorageCap = LazyOptional.of(() -> zeroStorage); - private Optional outReceivingStorage = Optional.empty(); - - private Direction gasInDirection = Direction.NORTH; - private Direction gasOutDirection = Direction.SOUTH; + // a zero size, zero transfer gas storage to ensure that cables connect + private static final IGasHandler ZERO_STORAGE = new ZeroGasTank(); public GasDetectorEntity(BlockPos pos, BlockState state) { - super(APBlockEntityTypes.GAS_DETECTOR.get(), pos, state); + super(APBlockEntityTypes.GAS_DETECTOR.get(), pos, state, MekanismCapabilities.GAS_HANDLER); } - @NotNull @Override + @NotNull protected GasDetectorPeripheral createPeripheral() { return new GasDetectorPeripheral(this); } - @NotNull @Override - public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction direction) { - gasInDirection = getBlockState().getValue(BaseBlock.ORIENTATION).front(); - gasOutDirection = getBlockState().getValue(BaseBlock.ORIENTATION).front().getOpposite(); - if (cap == MekanismCapabilities.GAS_HANDLER) { - if (direction == gasInDirection) { - return gasStorageCap.cast(); - } else if (direction == gasOutDirection) { - return zeroStorageCap.cast(); - } - } - return super.getCapability(cap, direction); - } - - @Override - public void saveAdditional(@NotNull CompoundTag compound) { - super.saveAdditional(compound); - compound.putInt("rateLimit", storageProxy.getMaxTransferRate()); - } - - @Override - public void handleTick(Level level, BlockState state, BlockEntityType type) { - if (!level.isClientSide) { - // this handles the rare edge case that receiveGas is called multiple times in one tick - transferRate = storageProxy.getTransferedInThisTick(); - storageProxy.resetTransferedInThisTick(); - } + @NotNull + protected GasStorageProxy createProxy() { + return new GasStorageProxy(this, APConfig.PERIPHERALS_CONFIG.gasDetectorMaxFlow.get()); } @Override - public void load(@NotNull CompoundTag nbt) { - storageProxy.setMaxTransferRate(nbt.getInt("rateLimit")); - super.load(nbt); - } - - // returns the cached output storage of the receiving block or fetches it if it has been invalidated @NotNull - public Optional getOutputStorage() { - // the documentation says that the value of the LazyOptional should be cached locally and invalidated using addListener - if (outReceivingStorage.isEmpty()) { - BlockEntity teOut = level.getBlockEntity(worldPosition.relative(gasOutDirection)); - if (teOut == null) { - return Optional.empty(); - } - LazyOptional lazyOptionalOutStorage = teOut.getCapability(MekanismCapabilities.GAS_HANDLER, gasOutDirection.getOpposite()); - outReceivingStorage = lazyOptionalOutStorage.resolve(); - lazyOptionalOutStorage.addListener(l -> { - outReceivingStorage = Optional.empty(); - }); - } - return outReceivingStorage; + protected IGasHandler getZeroStorage() { + return ZERO_STORAGE; } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/MeBridgeEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/MeBridgeEntity.java index 0001aa14b..16a66d976 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/MeBridgeEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/MeBridgeEntity.java @@ -12,9 +12,9 @@ import appeng.api.stacks.AEItemKey; import appeng.api.storage.StorageHelper; import appeng.api.util.AECableType; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.AppEngApi; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.CraftJob; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.MeBridgeEntityListener; +import de.srendi.advancedperipherals.common.addons.ae2.AppEngApi; +import de.srendi.advancedperipherals.common.addons.ae2.CraftJob; +import de.srendi.advancedperipherals.common.addons.ae2.MeBridgeEntityListener; import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.MeBridgePeripheral; import de.srendi.advancedperipherals.common.blocks.base.IInventoryBlock; import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; @@ -54,8 +54,13 @@ protected MeBridgePeripheral createPeripheral() { @Override public void handleTick(Level level, BlockState state, BlockEntityType type) { - if (!this.level.isClientSide) { + super.handleTick(level, state, type); + if (!this.level.isClientSide()) { if (!initialized) { + MeBridgePeripheral peripheral = this.getPeripheral(); + if (peripheral == null) { + return; + } mainNode.setFlags(GridFlags.REQUIRE_CHANNEL); mainNode.setIdlePowerUsage(APConfig.PERIPHERALS_CONFIG.meConsumption.get()); @@ -63,9 +68,6 @@ public void handleTick(Level level, BlockState state, Bl mainNode.setInWorldNode(true); mainNode.create(level, getBlockPos()); - //peripheral can be null if `getCapability` was not called before - if (peripheral == null) - peripheral = createPeripheral(); peripheral.setNode(mainNode); initialized = true; } diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/PlayerDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/PlayerDetectorEntity.java index 08a0ac6ef..789d6c36b 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/PlayerDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/PlayerDetectorEntity.java @@ -2,21 +2,14 @@ import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.PlayerDetectorPeripheral; import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; -import de.srendi.advancedperipherals.common.events.Events; import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; public class PlayerDetectorEntity extends PeripheralBlockEntity { - private Long lastConsumedMessage; - public PlayerDetectorEntity(BlockPos pos, BlockState state) { super(APBlockEntityTypes.PLAYER_DETECTOR.get(), pos, state); - lastConsumedMessage = Events.getLastPlayerMessageID() - 1; } @NotNull @@ -24,13 +17,4 @@ public PlayerDetectorEntity(BlockPos pos, BlockState state) { protected PlayerDetectorPeripheral createPeripheral() { return new PlayerDetectorPeripheral(this); } - - @Override - public void handleTick(Level level, BlockState state, BlockEntityType type) { - lastConsumedMessage = Events.traversePlayerMessages(lastConsumedMessage, message -> getConnectedComputers().forEach(computer -> { - if(message.eventName().equals("playerChangedDimension")) { - computer.queueEvent(message.eventName(), message.playerName(), message.fromDimension(), message.toDimension()); - } else computer.queueEvent(message.eventName(), message.playerName(), message.fromDimension()); - })); - } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/commands/APCommands.java b/src/main/java/de/srendi/advancedperipherals/common/commands/APCommands.java index ae08e1ec9..a8519c562 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/commands/APCommands.java +++ b/src/main/java/de/srendi/advancedperipherals/common/commands/APCommands.java @@ -13,6 +13,7 @@ import dan200.computercraft.shared.computer.core.ServerContext; import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.ChunkyPeripheral; +import de.srendi.advancedperipherals.common.util.ChunkManager; import de.srendi.advancedperipherals.common.util.inventory.ItemUtil; import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; @@ -102,6 +103,8 @@ private static int forceloadDump(CommandSourceStack source) throws CommandSyntax ); } + ChunkManager manager = ChunkManager.get(source.getServer().overworld()); + source.sendSuccess(Component.literal("Forced " + manager.getForcedChunksCount() + " chunks"), true); table.display(source); return computers.length; } diff --git a/src/main/java/de/srendi/advancedperipherals/common/container/KeyboardContainer.java b/src/main/java/de/srendi/advancedperipherals/common/container/KeyboardContainer.java index 03838407a..7a098c5b3 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/container/KeyboardContainer.java +++ b/src/main/java/de/srendi/advancedperipherals/common/container/KeyboardContainer.java @@ -9,9 +9,9 @@ import de.srendi.advancedperipherals.common.container.base.BaseContainer; import de.srendi.advancedperipherals.common.items.KeyboardItem; import de.srendi.advancedperipherals.common.setup.APContainerTypes; -import de.srendi.advancedperipherals.common.util.NBTUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -23,21 +23,25 @@ public class KeyboardContainer extends BaseContainer implements ComputerMenu { private final ServerInputState input; + private final ItemStack keyboardItem; @Nullable private ServerComputer computer = null; public KeyboardContainer(int id, Inventory inventory, BlockPos pos, Level level, ItemStack keyboardItem) { super(APContainerTypes.KEYBOARD_CONTAINER.get(), id, inventory, pos, level); - this.input = new ServerInputState<>( this ); + this.input = new ServerInputState<>(this); + this.keyboardItem = keyboardItem; CompoundTag data = keyboardItem.getOrCreateTag(); if (!data.getBoolean(KeyboardItem.BOUND_TYPE_TAG)) { - BlockPos computerPos = NBTUtil.blockPosFromNBT(keyboardItem.getOrCreateTag().getCompound(KeyboardItem.BIND_TAG)); + // Cannot use instance ID here since they will change after reload the block + int computerId = keyboardItem.getOrCreateTag().getInt(KeyboardItem.BIND_TAG); for (ServerComputer computer : ServerContext.get(ServerLifecycleHooks.getCurrentServer()).registry().getComputers()) { - if (computer.getPosition() != null && computer.getPosition().equals(computerPos)) { + if (computer.getID() == computerId) { this.computer = computer; + break; } } } else if (data.contains(KeyboardItem.GLASSES_BIND_TAG)) { @@ -46,11 +50,23 @@ public KeyboardContainer(int id, Inventory inventory, BlockPos pos, Level level, } + public ItemStack getKeyboardItem() { + return this.keyboardItem; + } + @Override public boolean stillValid(@NotNull Player playerIn) { return true; } + @Override + public void removed(Player player) { + super.removed(player); + if (player instanceof ServerPlayer) { + computer.queueEvent("keyboard_closed"); + } + } + @Nullable @Override public ServerComputer getComputer() { diff --git a/src/main/java/de/srendi/advancedperipherals/common/data/EnUsLanguageProvider.java b/src/main/java/de/srendi/advancedperipherals/common/data/EnUsLanguageProvider.java index 59c4308e1..ab443c42c 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/data/EnUsLanguageProvider.java +++ b/src/main/java/de/srendi/advancedperipherals/common/data/EnUsLanguageProvider.java @@ -58,6 +58,8 @@ private void addItems() { addItem(APItems.OVERPOWERED_HUSBANDRY_AUTOMATA_CORE, "Overpowered Husbandry Automata Core"); addItem(APItems.OVERPOWERED_WEAK_AUTOMATA_CORE, "Overpowered Weak Automata Core"); addItem(APItems.WEAK_AUTOMATA_CORE, "Weak Automata Core"); + + addItem(APItems.CABLE_P2P_TUNNEL, "Cable P2P Tunnel"); } private void addBlocks() { @@ -99,6 +101,7 @@ private void addTurtles() { private void addPockets() { addPocket(CCRegistration.ID.CHATTY_POCKET, "Chatty"); addPocket(CCRegistration.ID.COLONY_POCKET, "Colony"); + addPocket(CCRegistration.ID.DISTANCE_POCKET, "Distance Detector"); addPocket(CCRegistration.ID.ENVIRONMENT_POCKET, "Environment"); addPocket(CCRegistration.ID.GEOSCANNER_POCKET, "Geo"); addPocket(CCRegistration.ID.PLAYER_POCKET, "Player Detector"); diff --git a/src/main/java/de/srendi/advancedperipherals/common/data/ItemTagsProvider.java b/src/main/java/de/srendi/advancedperipherals/common/data/ItemTagsProvider.java index 8cd142217..b3b9d4520 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/data/ItemTagsProvider.java +++ b/src/main/java/de/srendi/advancedperipherals/common/data/ItemTagsProvider.java @@ -1,6 +1,7 @@ package de.srendi.advancedperipherals.common.data; import de.srendi.advancedperipherals.AdvancedPeripherals; +import de.srendi.advancedperipherals.common.addons.ae2.AE2Registries; import de.srendi.advancedperipherals.common.setup.APItems; import de.srendi.advancedperipherals.common.setup.APTags; import net.minecraft.core.Registry; @@ -18,6 +19,9 @@ protected ItemTagsProvider(DataGenerator generator, @Nullable ExistingFileHelper @Override protected void addTags() { - tag(APTags.Items.SMART_GLASSES).add(APItems.SMART_GLASSES.get()).add(APItems.SMART_GLASSES_NETHERITE.get()); + tag(APTags.Items.SMART_GLASSES) + .add(APItems.SMART_GLASSES.get()) + .add(APItems.SMART_GLASSES_NETHERITE.get()); + AE2Registries.registerTags(this::tag); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/data/PocketUpgradesProvider.java b/src/main/java/de/srendi/advancedperipherals/common/data/PocketUpgradesProvider.java index 385b75679..a021dbee7 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/data/PocketUpgradesProvider.java +++ b/src/main/java/de/srendi/advancedperipherals/common/data/PocketUpgradesProvider.java @@ -18,9 +18,10 @@ public PocketUpgradesProvider(DataGenerator output) { @Override protected void addUpgrades(@NotNull Consumer>> addUpgrade) { simpleWithCustomItem(CCRegistration.ID.CHATTY_POCKET, CCRegistration.CHAT_BOX_POCKET.get(), APBlocks.CHAT_BOX.get().asItem()).add(addUpgrade); - simpleWithCustomItem(CCRegistration.ID.PLAYER_POCKET, CCRegistration.PLAYER_DETECTOR_POCKET.get(), APBlocks.PLAYER_DETECTOR.get().asItem()).add(addUpgrade); + simpleWithCustomItem(CCRegistration.ID.COLONY_POCKET, CCRegistration.COLONY_POCKET.get(), APBlocks.COLONY_INTEGRATOR.get().asItem()).add(addUpgrade); + simpleWithCustomItem(CCRegistration.ID.DISTANCE_POCKET, CCRegistration.DISTANCE_DETECTOR_POCKET.get(), APBlocks.DISTANCE_DETECTOR.get().asItem()).add(addUpgrade); simpleWithCustomItem(CCRegistration.ID.ENVIRONMENT_POCKET, CCRegistration.ENVIRONMENT_POCKET.get(), APBlocks.ENVIRONMENT_DETECTOR.get().asItem()).add(addUpgrade); simpleWithCustomItem(CCRegistration.ID.GEOSCANNER_POCKET, CCRegistration.GEO_SCANNER_POCKET.get(), APBlocks.GEO_SCANNER.get().asItem()).add(addUpgrade); - simpleWithCustomItem(CCRegistration.ID.COLONY_POCKET, CCRegistration.COLONY_POCKET.get(), APBlocks.COLONY_INTEGRATOR.get().asItem()).add(addUpgrade); + simpleWithCustomItem(CCRegistration.ID.PLAYER_POCKET, CCRegistration.PLAYER_DETECTOR_POCKET.get(), APBlocks.PLAYER_DETECTOR.get().asItem()).add(addUpgrade); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/entity/TurtleSeatEntity.java b/src/main/java/de/srendi/advancedperipherals/common/entity/TurtleSeatEntity.java index f8fc1c492..340bd3cc1 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/entity/TurtleSeatEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/entity/TurtleSeatEntity.java @@ -16,6 +16,7 @@ import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.HasCustomInventoryScreen; @@ -26,6 +27,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.PushReaction; +import net.minecraft.world.level.portal.PortalInfo; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; @@ -34,8 +36,8 @@ public class TurtleSeatEntity extends Entity implements HasCustomInventoryScreen // TODO: better rendering - private ITurtleAccess turtle; - private int life; + private ITurtleAccess turtle = null; + private int life = 0; private boolean forwardKey = false; private boolean backKey = false; @@ -58,7 +60,10 @@ public TurtleSeatEntity(EntityType type, Level world) { public TurtleSeatEntity(ITurtleAccess turtle) { this(APEntities.TURTLE_SEAT.get(), turtle.getLevel()); this.turtle = turtle; - this.life = 0; + } + + public void setTurtle(ITurtleAccess turtle) { + this.turtle = turtle; } public ITurtleAccess getOwner() { @@ -81,6 +86,11 @@ public void keepAlive() { this.life = 2; } + public Vec3 getTurtlePos() { + BlockPos pos = this.turtle.getPosition(); + return Vec3.atCenterOf(pos); + } + @Override public Packet getAddEntityPacket() { return new ClientboundAddEntityPacket(this); @@ -124,7 +134,7 @@ protected void removePassenger(Entity entity) { @Override public Vec3 getDismountLocationForPassenger(LivingEntity entity) { - return super.getDismountLocationForPassenger(entity).add(0, 0.5, 0); + return this.getTurtlePos().add(0, 0.4, 0); } @Override @@ -132,6 +142,11 @@ public Entity getControllingPassenger() { return null; // this.getFirstPassenger(); } + @Override + public double getPassengersRidingOffset() { + return 0.05; + } + @Override public void tick() { if (this.level.isClientSide) { @@ -221,6 +236,11 @@ public boolean canChangeDimensions() { return false; } + @Override + public PortalInfo findDimensionEntryPoint(ServerLevel newLevel) { + return new PortalInfo(this.getTurtlePos(), Vec3.ZERO, 0, 0); + } + @Override public boolean shouldBlockExplode(net.minecraft.world.level.Explosion a0, net.minecraft.world.level.BlockGetter a1, BlockPos a2, BlockState a3, float a4) { return false; diff --git a/src/main/java/de/srendi/advancedperipherals/common/items/KeyboardItem.java b/src/main/java/de/srendi/advancedperipherals/common/items/KeyboardItem.java index abf96b453..2a875f1f7 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/items/KeyboardItem.java +++ b/src/main/java/de/srendi/advancedperipherals/common/items/KeyboardItem.java @@ -5,13 +5,13 @@ import de.srendi.advancedperipherals.common.container.KeyboardContainer; import de.srendi.advancedperipherals.common.items.base.BaseItem; import de.srendi.advancedperipherals.common.items.base.IInventoryItem; +import de.srendi.advancedperipherals.common.network.APNetworking; +import de.srendi.advancedperipherals.common.network.toclient.KeyboardMouseCapturePacket; import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesAccess; import de.srendi.advancedperipherals.common.smartglasses.modules.IModule; import de.srendi.advancedperipherals.common.smartglasses.modules.IModuleItem; import de.srendi.advancedperipherals.common.smartglasses.modules.keyboard.KeyboardModule; import de.srendi.advancedperipherals.common.util.EnumColor; -import de.srendi.advancedperipherals.common.util.KeybindUtil; -import de.srendi.advancedperipherals.common.util.NBTUtil; import de.srendi.advancedperipherals.common.util.SideHelper; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -54,37 +54,42 @@ public boolean isEnabled() { @NotNull @Override public InteractionResult useOn(UseOnContext context) { - if (context.getPlayer() == null) + Player player = context.getPlayer(); + if (player == null) return InteractionResult.PASS; - if (SideHelper.isClientPlayer(context.getPlayer())) + if (SideHelper.isClientPlayer(player)) return InteractionResult.PASS; - if (!context.getPlayer().isShiftKeyDown()) + if (!player.isShiftKeyDown()) return InteractionResult.PASS; BlockEntity entity = context.getLevel().getBlockEntity(context.getClickedPos()); if (entity instanceof TileComputerBase) { - bind(context.getPlayer(), context.getItemInHand(), context.getClickedPos()); + bind(player, context.getItemInHand(), context.getLevel(), context.getClickedPos()); } else { - clear(context.getPlayer(), context.getItemInHand()); + clear(player, context.getItemInHand()); } return super.useOn(context); } @Override public void inventoryTick(ItemStack itemStack, Level level, Entity entity, int inventorySlot, boolean isCurrentItem, @Nullable SmartGlassesAccess access, @Nullable IModule module) { - if (level.isClientSide()) + if (level.isClientSide()) { return; + } - if (access == null) + if (access == null || !(module instanceof KeyboardModule keyboadModule)) { return; + } CompoundTag data = itemStack.getOrCreateTag(); int instanceId = access.getComputer().getInstanceID(); int oldInstanceId = -1; - if (data.contains(GLASSES_BIND_TAG)) oldInstanceId = data.getInt(GLASSES_BIND_TAG); + if (data.contains(GLASSES_BIND_TAG)) { + oldInstanceId = data.getInt(GLASSES_BIND_TAG); + } if (!data.contains(BOUND_TYPE_TAG) || ((oldInstanceId != -1 && oldInstanceId != instanceId)) || !data.getBoolean(BOUND_TYPE_TAG)) { data.putBoolean(BOUND_TYPE_TAG, true); @@ -92,31 +97,43 @@ public void inventoryTick(ItemStack itemStack, Level level, Entity entity, int i data.remove(BIND_TAG); } - if (KeybindUtil.isKeyPressed(KeyBindings.GLASSES_HOTKEY_KEYBINDING)) { - if (entity instanceof ServerPlayer serverPlayer) { - NetworkHooks.openScreen(serverPlayer, ((IInventoryItem) this).createContainer(serverPlayer, itemStack), buf -> { - buf.writeBlockPos(serverPlayer.blockPosition()); - buf.writeItem(itemStack); - }); - } + if (!(entity instanceof ServerPlayer serverPlayer)) { + return; + } + // TODO: this for sure won't work on dedicated server + if (!KeyBindings.GLASSES_HOTKEY_KEYBINDING.isDown()) { + return; + } + + access.getComputer().queueEvent("keyboard_open"); + if (serverPlayer.containerMenu instanceof KeyboardContainer openedKeyboard && openedKeyboard.getKeyboardItem() == itemStack) { + return; + } + + NetworkHooks.openScreen(serverPlayer, this.createContainer(serverPlayer, itemStack), buf -> { + buf.writeBlockPos(serverPlayer.blockPosition()); + buf.writeItem(itemStack); + }); + if (keyboadModule.isCapturingMouse()) { + APNetworking.sendTo(new KeyboardMouseCapturePacket(true), serverPlayer); } } @Override public InteractionResultHolder use(Level worldIn, Player playerIn, InteractionHand handIn) { - if (playerIn.level.isClientSide()) + if (playerIn.level.isClientSide()) { return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn)); + } // Used to prevent the menu from opening when we just want to bind/unbind the keyboard - if (!playerIn.isShiftKeyDown()) { - if (!playerIn.getItemInHand(handIn).getOrCreateTag().contains(BIND_TAG)) { - playerIn.displayClientMessage(EnumColor.buildTextComponent(Component.translatable("text.advancedperipherals.keyboard_notbound")), false); - return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn)); - } - // Run the super use which handles the IInventoryItem stuff to actually open the container - return super.use(worldIn, playerIn, handIn); + if (playerIn.isShiftKeyDown()) { + return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn)); } - - return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn)); + if (!playerIn.getItemInHand(handIn).getOrCreateTag().contains(BIND_TAG)) { + playerIn.displayClientMessage(EnumColor.buildTextComponent(Component.translatable("text.advancedperipherals.keyboard_notbound")), false); + return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn)); + } + // Run the super use which handles the IInventoryItem stuff to actually open the container + return super.use(worldIn, playerIn, handIn); } @Override @@ -125,27 +142,38 @@ public void appendHoverText(ItemStack stack, @Nullable Level levelIn, List LazyOptional getCapability(@NotNull Capability cap, @Nullable D private boolean tick(ItemStack stack, Level world, Entity entity, SmartGlassesComputer computer) { computer.setLevel((ServerLevel) world); + if (entity != null) { + computer.setPosition(entity.blockPosition()); + } boolean changed = false; @@ -118,6 +126,13 @@ private boolean tick(ItemStack stack, Level world, Entity entity, SmartGlassesCo computer.setStack(stack); } + for (Map.Entry e : computer.getUpgrades().entrySet()) { + IPocketUpgrade upgrade = PocketUpgrades.instance().get(e.getKey().toString()); + if (upgrade != null) { + upgrade.update(computer, e.getValue()); + } + } + return changed; } @@ -125,9 +140,9 @@ private boolean tick(ItemStack stack, Level world, Entity entity, SmartGlassesCo public void inventoryTick(@NotNull ItemStack stack, @NotNull Level world, @NotNull Entity entity, int slotNum, boolean selected) { LazyOptional optItemHandler = stack.getCapability(ForgeCapabilities.ITEM_HANDLER); SmartGlassesItemHandler itemHandler = (SmartGlassesItemHandler) optItemHandler.orElse(null); - for(int slot = 0; slot < itemHandler.getSlots(); slot++) { + for (int slot = 0; slot < itemHandler.getSlots(); slot++) { ItemStack itemStack = itemHandler.getStackInSlot(slot); - if(itemStack.getItem() instanceof IModuleItem iModuleItem) { + if (itemStack.getItem() instanceof IModuleItem iModuleItem) { SmartGlassesAccess glassesAccess = null; IModule module = null; if (!world.isClientSide) { @@ -155,7 +170,9 @@ public void inventoryTick(@NotNull ItemStack stack, @NotNull Level world, @NotNu @Override public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) { - if (entity.level.isClientSide || entity.level.getServer() == null) return false; + if (entity.level.isClientSide || entity.level.getServer() == null) { + return false; + } SmartGlassesComputer computer = getServerComputer(entity.level.getServer(), stack); if (computer != null && tick(stack, entity.level, entity, computer)) { @@ -231,7 +248,7 @@ public SmartGlassesComputer getOrCreateComputer(ServerLevel level, Entity entity setComputerID(stack, computerID); } - computer = new SmartGlassesComputer(level, getComputerID(stack), getLabel(stack), getFamily()); + computer = new SmartGlassesComputer(level, getComputerID(stack), getLabel(stack), getFamily(), stack.getOrCreateTag().getCompound(SmartGlassesComputer.UPGRADE_DATAS_TAG)); setInstanceID(stack, computer.register()); setSessionID(stack, registry.getSessionID()); diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java b/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java index d007a4b1d..5738f2553 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java +++ b/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java @@ -2,6 +2,7 @@ import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.common.network.base.IPacket; +import de.srendi.advancedperipherals.common.network.toclient.KeyboardMouseCapturePacket; import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectBulkSyncPacket; import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectClearPacket; import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectDeletePacket; @@ -9,6 +10,9 @@ import de.srendi.advancedperipherals.common.network.toclient.SaddleTurtleInfoPacket; import de.srendi.advancedperipherals.common.network.toclient.ToastToClientPacket; import de.srendi.advancedperipherals.common.network.toserver.GlassesHotkeyPacket; +import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseClickPacket; +import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseMovePacket; +import de.srendi.advancedperipherals.common.network.toserver.KeyboardMouseScrollPacket; import de.srendi.advancedperipherals.common.network.toserver.SaddleTurtleControlPacket; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; @@ -38,13 +42,18 @@ public class APNetworking { private static int index = 0; public static void init() { + registerServerToClient(KeyboardMouseCapturePacket.class, KeyboardMouseCapturePacket::decode); + registerServerToClient(RenderableObjectBulkSyncPacket.class, RenderableObjectBulkSyncPacket::decode); + registerServerToClient(RenderableObjectClearPacket.class, RenderableObjectClearPacket::decode); + registerServerToClient(RenderableObjectDeletePacket.class, RenderableObjectDeletePacket::decode); + registerServerToClient(RenderableObjectSyncPacket.class, RenderableObjectSyncPacket::decode); registerServerToClient(SaddleTurtleInfoPacket.class, SaddleTurtleInfoPacket::decode); registerServerToClient(ToastToClientPacket.class, ToastToClientPacket::decode); - registerServerToClient(RenderableObjectSyncPacket.class, RenderableObjectSyncPacket::decode); - registerServerToClient(RenderableObjectDeletePacket.class, RenderableObjectDeletePacket::decode); - registerServerToClient(RenderableObjectClearPacket.class, RenderableObjectClearPacket::decode); - registerServerToClient(RenderableObjectBulkSyncPacket.class, RenderableObjectBulkSyncPacket::decode); + registerClientToServer(GlassesHotkeyPacket.class, GlassesHotkeyPacket::decode); + registerClientToServer(KeyboardMouseClickPacket.class, KeyboardMouseClickPacket::decode); + registerClientToServer(KeyboardMouseMovePacket.class, KeyboardMouseMovePacket::decode); + registerClientToServer(KeyboardMouseScrollPacket.class, KeyboardMouseScrollPacket::decode); registerClientToServer(SaddleTurtleControlPacket.class, SaddleTurtleControlPacket::decode); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/toclient/KeyboardMouseCapturePacket.java b/src/main/java/de/srendi/advancedperipherals/common/network/toclient/KeyboardMouseCapturePacket.java new file mode 100644 index 000000000..f6e0d53ee --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/network/toclient/KeyboardMouseCapturePacket.java @@ -0,0 +1,36 @@ +package de.srendi.advancedperipherals.common.network.toclient; + +import de.srendi.advancedperipherals.client.screens.KeyboardScreen; +import de.srendi.advancedperipherals.common.network.base.IPacket; +import net.minecraft.client.Minecraft; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; + +public class KeyboardMouseCapturePacket implements IPacket { + + private final boolean enable; + + public KeyboardMouseCapturePacket(boolean enable) { + this.enable = enable; + } + + @OnlyIn(Dist.CLIENT) + @Override + public void handle(NetworkEvent.Context context) { + if (!(Minecraft.getInstance().screen instanceof KeyboardScreen screen)) { + return; + } + screen.setCaptureMouse(this.enable); + } + + @Override + public void encode(FriendlyByteBuf buffer) { + buffer.writeBoolean(this.enable); + } + + public static KeyboardMouseCapturePacket decode(FriendlyByteBuf buffer) { + return new KeyboardMouseCapturePacket(buffer.readBoolean()); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/toserver/GlassesHotkeyPacket.java b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/GlassesHotkeyPacket.java index c6f5506ed..0f31cd4ea 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/network/toserver/GlassesHotkeyPacket.java +++ b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/GlassesHotkeyPacket.java @@ -10,16 +10,12 @@ import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.server.ServerLifecycleHooks; -import java.util.UUID; - public class GlassesHotkeyPacket implements IPacket { - private final UUID player; private final String keyBind; private final int keyPressDuration; - public GlassesHotkeyPacket(UUID player, String keyBind, int keyPressDuration) { - this.player = player; + public GlassesHotkeyPacket(String keyBind, int keyPressDuration) { this.keyBind = keyBind; this.keyPressDuration = keyPressDuration; } @@ -28,28 +24,29 @@ public GlassesHotkeyPacket(UUID player, String keyBind, int keyPressDuration) { public void handle(NetworkEvent.Context context) { MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); - ServerPlayer serverPlayer = server.getPlayerList().getPlayer(player); - if (serverPlayer == null) + ServerPlayer serverPlayer = context.getSender(); + if (serverPlayer == null) { return; + } for (ItemStack stack : serverPlayer.getAllSlots()) { if (stack.getItem() instanceof SmartGlassesItem) { SmartGlassesComputer computer = SmartGlassesItem.getServerComputer(server, stack); - - if (computer != null) - computer.queueEvent("glassesKeyPressed", new Object[]{keyBind, keyPressDuration}); + if (computer != null) { + computer.queueEvent("glasses_key_pressed", new Object[]{keyBind, keyPressDuration}); + break; + } } } } @Override public void encode(FriendlyByteBuf buffer) { - buffer.writeUUID(player); buffer.writeUtf(keyBind); buffer.writeInt(keyPressDuration); } public static GlassesHotkeyPacket decode(FriendlyByteBuf buffer) { - return new GlassesHotkeyPacket(buffer.readUUID(), buffer.readUtf(), buffer.readInt()); + return new GlassesHotkeyPacket(buffer.readUtf(), buffer.readInt()); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseClickPacket.java b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseClickPacket.java new file mode 100644 index 000000000..9c6acb829 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseClickPacket.java @@ -0,0 +1,52 @@ +package de.srendi.advancedperipherals.common.network.toserver; + +import de.srendi.advancedperipherals.common.items.SmartGlassesItem; +import de.srendi.advancedperipherals.common.network.base.IPacket; +import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesComputer; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.server.ServerLifecycleHooks; + +public class KeyboardMouseClickPacket implements IPacket { + + private final int button; + private final boolean isRelease; + + public KeyboardMouseClickPacket(int button, boolean isRelease) { + this.button = button; + this.isRelease = isRelease; + } + + @Override + public void handle(NetworkEvent.Context context) { + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + + ServerPlayer serverPlayer = context.getSender(); + if (serverPlayer == null) { + return; + } + + for (ItemStack stack : serverPlayer.getAllSlots()) { + if (stack.getItem() instanceof SmartGlassesItem) { + SmartGlassesComputer computer = SmartGlassesItem.getServerComputer(server, stack); + if (computer != null) { + computer.queueEvent(isRelease ? "player_mouse_up" : "player_mouse_click", new Object[]{button}); + break; + } + } + } + } + + @Override + public void encode(FriendlyByteBuf buffer) { + buffer.writeVarInt(button); + buffer.writeBoolean(isRelease); + } + + public static KeyboardMouseClickPacket decode(FriendlyByteBuf buffer) { + return new KeyboardMouseClickPacket(buffer.readVarInt(), buffer.readBoolean()); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseMovePacket.java b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseMovePacket.java new file mode 100644 index 000000000..27e8783fd --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseMovePacket.java @@ -0,0 +1,52 @@ +package de.srendi.advancedperipherals.common.network.toserver; + +import de.srendi.advancedperipherals.common.items.SmartGlassesItem; +import de.srendi.advancedperipherals.common.network.base.IPacket; +import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesComputer; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.server.ServerLifecycleHooks; + +public class KeyboardMouseMovePacket implements IPacket { + + private final double dx; + private final double dy; + + public KeyboardMouseMovePacket(double dx, double dy) { + this.dx = dx; + this.dy = dy; + } + + @Override + public void handle(NetworkEvent.Context context) { + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + + ServerPlayer serverPlayer = context.getSender(); + if (serverPlayer == null) { + return; + } + + for (ItemStack stack : serverPlayer.getAllSlots()) { + if (stack.getItem() instanceof SmartGlassesItem) { + SmartGlassesComputer computer = SmartGlassesItem.getServerComputer(server, stack); + if (computer != null) { + computer.queueEvent("player_mouse_move", new Object[]{dx, dy}); + break; + } + } + } + } + + @Override + public void encode(FriendlyByteBuf buffer) { + buffer.writeDouble(dx); + buffer.writeDouble(dy); + } + + public static KeyboardMouseMovePacket decode(FriendlyByteBuf buffer) { + return new KeyboardMouseMovePacket(buffer.readDouble(), buffer.readDouble()); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseScrollPacket.java b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseScrollPacket.java new file mode 100644 index 000000000..9f8752532 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/network/toserver/KeyboardMouseScrollPacket.java @@ -0,0 +1,49 @@ +package de.srendi.advancedperipherals.common.network.toserver; + +import de.srendi.advancedperipherals.common.items.SmartGlassesItem; +import de.srendi.advancedperipherals.common.network.base.IPacket; +import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesComputer; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.network.NetworkEvent; +import net.minecraftforge.server.ServerLifecycleHooks; + +public class KeyboardMouseScrollPacket implements IPacket { + + private final int delta; + + public KeyboardMouseScrollPacket(int delta) { + this.delta = delta; + } + + @Override + public void handle(NetworkEvent.Context context) { + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); + + ServerPlayer serverPlayer = context.getSender(); + if (serverPlayer == null) { + return; + } + + for (ItemStack stack : serverPlayer.getAllSlots()) { + if (stack.getItem() instanceof SmartGlassesItem) { + SmartGlassesComputer computer = SmartGlassesItem.getServerComputer(server, stack); + if (computer != null) { + computer.queueEvent("player_mouse_scroll", new Object[]{delta}); + break; + } + } + } + } + + @Override + public void encode(FriendlyByteBuf buffer) { + buffer.writeVarInt(delta); + } + + public static KeyboardMouseScrollPacket decode(FriendlyByteBuf buffer) { + return new KeyboardMouseScrollPacket(buffer.readVarInt()); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/setup/APContainerTypes.java b/src/main/java/de/srendi/advancedperipherals/common/setup/APContainerTypes.java index dee082a61..cdbc4f94d 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/setup/APContainerTypes.java +++ b/src/main/java/de/srendi/advancedperipherals/common/setup/APContainerTypes.java @@ -14,21 +14,22 @@ public class APContainerTypes { - public static final RegistryObject> INVENTORY_MANAGER_CONTAINER = APRegistration.CONTAINER_TYPES.register("memory_card_container", () -> IForgeMenuType.create((windowId, inv, data) -> { - BlockPos pos = data.readBlockPos(); + public static final RegistryObject> INVENTORY_MANAGER_CONTAINER = APRegistration.CONTAINER_TYPES.register("memory_card_container", () -> IForgeMenuType.create((windowId, inv, buf) -> { + BlockPos pos = buf.readBlockPos(); Level level = inv.player.getCommandSenderWorld(); return new InventoryManagerContainer(windowId, inv, pos, level); })); - public static final RegistryObject> KEYBOARD_CONTAINER = APRegistration.CONTAINER_TYPES.register("keyboard_container", () -> IForgeMenuType.create((windowId, inv, data) -> { - BlockPos pos = data.readBlockPos(); - ItemStack keyboardItem = data.readItem(); + public static final RegistryObject> KEYBOARD_CONTAINER = APRegistration.CONTAINER_TYPES.register("keyboard_container", () -> IForgeMenuType.create((windowId, inv, buf) -> { + BlockPos pos = buf.readBlockPos(); + ItemStack keyboardItem = buf.readItem(); Level level = inv.player.getCommandSenderWorld(); return new KeyboardContainer(windowId, inv, pos, level, keyboardItem); })); - public static final RegistryObject> SMART_GLASSES_CONTAINER = APRegistration.CONTAINER_TYPES.register("smart_glasses_container", () -> ContainerData.toType(ComputerContainerData::new, - (id, inv, data) -> new SmartGlassesContainer(id, player -> true, null, data, inv, data.displayStack()) + public static final RegistryObject> SMART_GLASSES_CONTAINER = APRegistration.CONTAINER_TYPES.register("smart_glasses_container", () -> ContainerData.toType( + ComputerContainerData::new, + (id, inv, buf) -> new SmartGlassesContainer(id, player -> true, null, buf, inv, buf.displayStack()) )); protected static void register() { diff --git a/src/main/java/de/srendi/advancedperipherals/common/setup/APEntities.java b/src/main/java/de/srendi/advancedperipherals/common/setup/APEntities.java index d9976225b..ee3f2bf8e 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/setup/APEntities.java +++ b/src/main/java/de/srendi/advancedperipherals/common/setup/APEntities.java @@ -18,14 +18,14 @@ public class APEntities { () -> EntityType.Builder.of(TurtleEnderPearl::new, MobCategory.MISC) .sized(0.5F, 0.5F) .clientTrackingRange(4) - .updateInterval(5) + .updateInterval(4) .fireImmune() .build("turtle_ender_pearl")); public static final RegistryObject> TURTLE_SEAT = APRegistration.ENTITIES.register("turtle_seat", () -> EntityType.Builder.of(TurtleSeatEntity::new, MobCategory.MISC) - .sized(0.8F, 0.2F) + .sized(0.8F, 0.8F) .clientTrackingRange(4) - .updateInterval(4) + .updateInterval(1) .fireImmune() .build("turtle_seat")); diff --git a/src/main/java/de/srendi/advancedperipherals/common/setup/APItems.java b/src/main/java/de/srendi/advancedperipherals/common/setup/APItems.java index 000118385..9b3c9f26b 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/setup/APItems.java +++ b/src/main/java/de/srendi/advancedperipherals/common/setup/APItems.java @@ -1,5 +1,7 @@ package de.srendi.advancedperipherals.common.setup; +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.items.APItem; import de.srendi.advancedperipherals.common.items.KeyboardItem; @@ -16,6 +18,7 @@ public class APItems { + public static final RegistryObject CABLE_P2P_TUNNEL = APAddons.appliedEnergisticsLoaded ? (RegistryObject) (RegistryObject) AE2Registries.CABLE_P2P_TUNNEL : null; public static final RegistryObject CHUNK_CONTROLLER = APRegistration.ITEMS.register("chunk_controller", () -> new APItem(new Item.Properties().stacksTo(16), APConfig.PERIPHERALS_CONFIG.enableChunkyTurtle)); public static final RegistryObject COMPUTER_TOOL = APRegistration.ITEMS.register("computer_tool", () -> new APItem(new Item.Properties().stacksTo(1), () -> true)); public static final RegistryObject END_AUTOMATA_CORE = APRegistration.ITEMS.register("end_automata_core", () -> new APItem(new Item.Properties().stacksTo(1), APConfig.METAPHYSICS_CONFIG.enableEndAutomataCore)); diff --git a/src/main/java/de/srendi/advancedperipherals/common/setup/CCRegistration.java b/src/main/java/de/srendi/advancedperipherals/common/setup/CCRegistration.java index 2e44565db..a72ff2f45 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/setup/CCRegistration.java +++ b/src/main/java/de/srendi/advancedperipherals/common/setup/CCRegistration.java @@ -7,6 +7,7 @@ import de.srendi.advancedperipherals.common.addons.computercraft.integrations.IntegrationPeripheralProvider; import de.srendi.advancedperipherals.common.addons.computercraft.pocket.PocketChatBoxUpgrade; import de.srendi.advancedperipherals.common.addons.computercraft.pocket.PocketColonyIntegratorUpgrade; +import de.srendi.advancedperipherals.common.addons.computercraft.pocket.PocketDistanceDetectorUpgrade; import de.srendi.advancedperipherals.common.addons.computercraft.pocket.PocketEnvironmentUpgrade; import de.srendi.advancedperipherals.common.addons.computercraft.pocket.PocketGeoScannerUpgrade; import de.srendi.advancedperipherals.common.addons.computercraft.pocket.PocketPlayerDetectorUpgrade; @@ -46,6 +47,7 @@ public class CCRegistration { public static final RegistryObject> CHAT_BOX_POCKET = APRegistration.POCKET_SERIALIZER.register(ID.CHATTY_POCKET.getPath(), () -> PocketUpgradeSerialiser.simpleWithCustomItem(PocketChatBoxUpgrade::new)); public static final RegistryObject> COLONY_POCKET = APRegistration.POCKET_SERIALIZER.register(ID.COLONY_POCKET.getPath(), () -> PocketUpgradeSerialiser.simpleWithCustomItem(PocketColonyIntegratorUpgrade::new)); + public static final RegistryObject> DISTANCE_DETECTOR_POCKET = APRegistration.POCKET_SERIALIZER.register(ID.DISTANCE_POCKET.getPath(), () -> PocketUpgradeSerialiser.simpleWithCustomItem(PocketDistanceDetectorUpgrade::new)); public static final RegistryObject> ENVIRONMENT_POCKET = APRegistration.POCKET_SERIALIZER.register(ID.ENVIRONMENT_POCKET.getPath(), () -> PocketUpgradeSerialiser.simpleWithCustomItem(PocketEnvironmentUpgrade::new)); public static final RegistryObject> GEO_SCANNER_POCKET = APRegistration.POCKET_SERIALIZER.register(ID.GEOSCANNER_POCKET.getPath(), () -> PocketUpgradeSerialiser.simpleWithCustomItem(PocketGeoScannerUpgrade::new)); public static final RegistryObject> PLAYER_DETECTOR_POCKET = APRegistration.POCKET_SERIALIZER.register(ID.PLAYER_POCKET.getPath(), () -> PocketUpgradeSerialiser.simpleWithCustomItem(PocketPlayerDetectorUpgrade::new)); @@ -76,6 +78,7 @@ public static class ID { public static final ResourceLocation CHATTY_POCKET = new ResourceLocation(AdvancedPeripherals.MOD_ID, "chatty_pocket"); public static final ResourceLocation COLONY_POCKET = new ResourceLocation(AdvancedPeripherals.MOD_ID, "colony_pocket"); + public static final ResourceLocation DISTANCE_POCKET = new ResourceLocation(AdvancedPeripherals.MOD_ID, "distance_pocket"); public static final ResourceLocation ENVIRONMENT_POCKET = new ResourceLocation(AdvancedPeripherals.MOD_ID, "environment_pocket"); public static final ResourceLocation GEOSCANNER_POCKET = new ResourceLocation(AdvancedPeripherals.MOD_ID, "geoscanner_pocket"); public static final ResourceLocation PLAYER_POCKET = new ResourceLocation(AdvancedPeripherals.MOD_ID, "player_pocket"); diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesAccess.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesAccess.java index 316c7a715..50420c042 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesAccess.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesAccess.java @@ -43,17 +43,17 @@ public void setLight(int colour) { @Override public CompoundTag getUpgradeNBTData() { - return new CompoundTag(); + return computer.getUpgradeNBTData(); } @Override public void updateUpgradeNBTData() { - + computer.updateUpgradeNBTData(); } @Override public void invalidatePeripheral() { - + computer.invalidatePeripheral(); } @Override diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesComputer.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesComputer.java index 2da4b259e..2880f55f4 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesComputer.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesComputer.java @@ -10,10 +10,10 @@ import de.srendi.advancedperipherals.common.smartglasses.modules.IModule; import de.srendi.advancedperipherals.common.smartglasses.modules.IModuleItem; import de.srendi.advancedperipherals.common.smartglasses.modules.ModulePeripheral; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Inventory; @@ -21,18 +21,21 @@ import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; -import javax.annotation.Nullable; +import com.google.common.collect.ImmutableMap; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import javax.annotation.Nullable; /** * Basically just a {@link dan200.computercraft.shared.pocket.core.PocketServerComputer} but with some changes */ public class SmartGlassesComputer extends ServerComputer implements IPocketAccess { + public static final String UPGRADE_DATAS_TAG = "UpgradeDatas"; + @Nullable private Entity entity; private ItemStack stack = ItemStack.EMPTY; @@ -40,20 +43,21 @@ public class SmartGlassesComputer extends ServerComputer implements IPocketAcces @Nullable private SmartGlassesItemHandler itemHandler = null; @NotNull - private final ModulePeripheral peripheral; + private final ModulePeripheral modulePeripheral; + private final CompoundTag upgradeDatas; - private int lightColour = -1; - private boolean lightChanged = false; - private boolean isDirty = false; + private boolean peripheralOutdated = false; + private boolean isDirty = true; - private final Set tracking = new HashSet<>(); + private Map upgrades = Collections.emptyMap(); private final Map modules = new HashMap<>(); - public SmartGlassesComputer(ServerLevel world, int computerID, @Nullable String label, ComputerFamily family) { + public SmartGlassesComputer(ServerLevel world, int computerID, @Nullable String label, ComputerFamily family, @NotNull CompoundTag upgradeDatas) { super(world, computerID, label, family, 39, 13); this.addAPI(new SmartGlassesAPI()); - peripheral = new ModulePeripheral(this); - this.setPeripheral(ComputerSide.BACK, peripheral); + this.modulePeripheral = new ModulePeripheral(this); + this.upgradeDatas = upgradeDatas; + this.setPeripheral(ComputerSide.BACK, this.modulePeripheral); } @Nullable @@ -65,7 +69,7 @@ public Entity getEntity() { if (entity instanceof Player player) { Inventory inventory = player.getInventory(); - if (inventory.items.contains(stack) || inventory.armor.contains(stack) || inventory.offhand.contains(stack)) { + if (inventory.contains(stack)) { return player; } return null; @@ -76,6 +80,16 @@ public Entity getEntity() { return null; } + @Override + public ServerLevel getLevel() { + return this.entity == null ? super.getLevel() : (ServerLevel) this.entity.getCommandSenderWorld(); + } + + @Override + public BlockPos getPosition() { + return this.entity == null ? super.getPosition() : new BlockPos(this.entity.getEyePosition()); + } + @Override public int getColour() { return 0; @@ -88,6 +102,8 @@ public void setColour(int colour) { public void setStack(ItemStack stack) { this.stack = stack; + this.invalidatePeripheral(); + this.updateUpgradeNBTData(); } public ItemStack getStack() { @@ -96,77 +112,81 @@ public ItemStack getStack() { @Override public int getLight() { - return lightColour; + return 0; } @Override public void setLight(int colour) { - if (colour < 0 || colour > 0xFFFFFF) { - colour = -1; - } - - if (lightColour == colour) { - return; - } - lightColour = colour; - lightChanged = true; } public void setItemHandler(@Nullable SmartGlassesItemHandler itemHandler) { this.itemHandler = itemHandler; } - public void markDirty() { - isDirty = true; + @Override + @NotNull + public CompoundTag getUpgradeNBTData() { + return this.upgradeDatas; } - public boolean isDirty() { - return isDirty; + public void setUpgradeData(@NotNull ComputerSide side, @NotNull ResourceLocation id, @NotNull CompoundTag data) { + data.putString("UpgradeSide", side.getName()); + this.upgradeDatas.put(id.toString(), data); + this.updateUpgradeNBTData(); } - @Override - @NotNull - public CompoundTag getUpgradeNBTData() { - return new CompoundTag(); + public void removeUpgradeData(@NotNull ComputerSide side) { + for (String id : this.upgradeDatas.getAllKeys()) { + if (side.getName().equals(this.upgradeDatas.getCompound(id).getString("UpgradeSide"))) { + this.upgradeDatas.remove(id); + this.updateUpgradeNBTData(); + return; + } + } } @Override public void updateUpgradeNBTData() { - if (entity instanceof Player player) { - player.getInventory().setChanged(); - } + this.isDirty = true; } @Override public void invalidatePeripheral() { + this.peripheralOutdated = true; } @Override @NotNull public Map getUpgrades() { - return Collections.emptyMap(); + return this.upgrades; } + @Override public void setPeripheral(ComputerSide side, IPeripheral peripheral) { super.setPeripheral(side, peripheral); } - public void updatePeripheralsAndModules(SmartGlassesItemHandler itemHandler) { - for (int slot = 0; slot < 5; slot++) { + private void updatePeripheralsAndModules(SmartGlassesItemHandler itemHandler) { + Set upgradesIdSet = new HashSet<>(); + ImmutableMap.Builder upgradesBuilder = new ImmutableMap.Builder<>(); + for (int slot = 0; slot < SmartGlassesItemHandler.PERIPHERAL_SLOTS; slot++) { + ComputerSide side = SmartGlassesSlot.indexToSide(slot); ItemStack peripheralItem = itemHandler.getStackInSlot(slot); - if (!peripheralItem.isEmpty()) { - IPocketUpgrade upgrade = PocketUpgrades.instance().get(peripheralItem); - if (upgrade != null) { - IPeripheral peripheral = upgrade.createPeripheral(smartGlassesAccess); - if (peripheral != null) { - setPeripheral(SmartGlassesSlot.indexToSide(slot), peripheral); - continue; - } + IPocketUpgrade upgrade = PocketUpgrades.instance().get(peripheralItem); + IPeripheral peripheral = upgrade != null ? upgrade.createPeripheral(smartGlassesAccess) : null; + setPeripheral(side, peripheral); + if (peripheral != null) { + ResourceLocation id = upgrade.getUpgradeID(); + if (upgradesIdSet.add(id)) { + upgradesBuilder.put(id, peripheral); + setUpgradeData(side, id, this.upgradeDatas.getCompound(id.toString())); + continue; } } - setPeripheral(SmartGlassesSlot.indexToSide(slot), null); + removeUpgradeData(side); } - for (int slot = 5; slot < 11; slot++) { + this.upgrades = upgradesBuilder.build(); + for (int slot = SmartGlassesItemHandler.PERIPHERAL_SLOTS; slot < SmartGlassesItemHandler.SLOTS; slot++) { ItemStack peripheralItem = itemHandler.getStackInSlot(slot); IModule oldModule = modules.get(slot); if (!peripheralItem.isEmpty() && peripheralItem.getItem() instanceof IModuleItem module) { @@ -175,49 +195,58 @@ public void updatePeripheralsAndModules(SmartGlassesItemHandler itemHandler) { continue; } modules.put(slot, newModule); - peripheral.updateModules(); - setPeripheral(ComputerSide.BACK, null); - setPeripheral(ComputerSide.BACK, peripheral); } else if (oldModule != null) { oldModule.onUnequipped(smartGlassesAccess); modules.remove(slot); } } + this.modulePeripheral.updateModules(); + setPeripheral(ComputerSide.BACK, null); + setPeripheral(ComputerSide.BACK, this.modulePeripheral); + if (this.entity instanceof Player player) { + player.getInventory().setChanged(); + } } @Override public void tickServer() { super.tickServer(); - // Find any players which have gone missing and remove them from the tracking list. - tracking.removeIf(player -> !player.isAlive() || player.level != getLevel()); - - // And now find any new players, add them to the tracking list, and broadcast state where appropriate. - boolean sendState = hasOutputChanged() || lightChanged; - lightChanged = false; - if (sendState) { - tracking.addAll(getLevel().players()); + boolean shouldUpdateInventory = this.peripheralOutdated || this.isDirty; + if (this.peripheralOutdated && this.itemHandler != null) { + this.peripheralOutdated = false; + this.updatePeripheralsAndModules(this.itemHandler); } - - if (isDirty()) { - updatePeripheralsAndModules(this.itemHandler); - isDirty = false; + if (this.isDirty) { + this.isDirty = false; + CompoundTag data = this.stack.getOrCreateTag(); + data.put(UPGRADE_DATAS_TAG, this.upgradeDatas.copy()); + } + if (shouldUpdateInventory && entity instanceof Player player) { + player.getInventory().setChanged(); } - modules.values().forEach(module -> { + this.modules.values().forEach(module -> { module.tick(smartGlassesAccess); }); } public void setEntity(@Nullable Entity entity) { + if (this.entity == entity) { + return; + } this.entity = entity; + if (entity == null) { + return; + } + this.setLevel((ServerLevel) this.entity.getCommandSenderWorld()); + this.setPosition(new BlockPos(this.entity.getEyePosition())); } public Map getModules() { return modules; } - @Override protected void onRemoved() { super.onRemoved(); diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesItemHandler.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesItemHandler.java index e28b7857a..d3b27fad6 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesItemHandler.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/SmartGlassesItemHandler.java @@ -1,19 +1,26 @@ package de.srendi.advancedperipherals.common.smartglasses; +import dan200.computercraft.api.pocket.IPocketUpgrade; +import dan200.computercraft.shared.PocketUpgrades; import de.srendi.advancedperipherals.common.items.SmartGlassesItem; +import de.srendi.advancedperipherals.common.smartglasses.modules.IModuleItem; import net.minecraft.core.NonNullList; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.ContainerHelper; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; import javax.annotation.Nonnull; public class SmartGlassesItemHandler implements IItemHandlerModifiable { - private static final int SLOTS = 12; + public static final int SLOTS = 11; + public static final int PERIPHERAL_SLOTS = 5; private final ItemStack glasses; @Nullable @@ -40,7 +47,34 @@ public int getSlotLimit(int slot) { @Override public boolean isItemValid(int slot, @NotNull ItemStack stack) { - return !(stack.getItem() instanceof SmartGlassesItem); + if (stack.getItem() instanceof SmartGlassesItem) { + return false; + } + List items = this.loadItems(); + if (slot < PERIPHERAL_SLOTS) { + IPocketUpgrade upgrade = PocketUpgrades.instance().get(stack); + if (upgrade == null) { + return false; + } + ResourceLocation id = upgrade.getUpgradeID(); + for (int i = 0; i < PERIPHERAL_SLOTS; i++) { + IPocketUpgrade u = PocketUpgrades.instance().get(items.get(i)); + if (u != null && u.getUpgradeID().equals(id)) { + return false; + } + } + return true; + } + Item item = stack.getItem(); + if (!(item instanceof IModuleItem module)) { + return false; + } + for (int i = PERIPHERAL_SLOTS; i < SLOTS; i++) { + if (items.get(i).getItem() == item) { + return false; + } + } + return true; } @Override @@ -53,15 +87,11 @@ public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate return stack; } ItemStack existing = getStackInSlot(slot); - int limit = getSlotLimit(slot); - if (!existing.isEmpty()) { - if (!ItemHandlerHelper.canItemStacksStack(stack, existing)) { - return stack; - } - limit -= existing.getCount(); + return stack; } + int limit = getSlotLimit(slot); if (limit <= 0) { return stack; } @@ -117,7 +147,7 @@ public ItemStack getStackInSlot(int slot) { @Override public void setStackInSlot(int slot, @NotNull ItemStack stack) { NonNullList items = loadItems(); - if (stack.equals(items.get(slot))) { + if (ItemStack.isSameItemSameTags(stack, items.get(slot))) { return; } items.set(slot, stack); @@ -127,7 +157,7 @@ public void setStackInSlot(int slot, @NotNull ItemStack stack) { public void setChanged() { if (this.computer != null) { - this.computer.markDirty(); + this.computer.invalidatePeripheral(); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheral.java index e72465756..760b03ed2 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheral.java @@ -6,7 +6,7 @@ public class ModulePeripheral extends BasePeripheral { - public static final String PERIPHERAL_TYPE = "smartGlasses"; + public static final String PERIPHERAL_TYPE = "smart_glasses"; public ModulePeripheral(SmartGlassesComputer computer) { super(PERIPHERAL_TYPE, new ModulePeripheralOwner(computer)); @@ -15,14 +15,14 @@ public ModulePeripheral(SmartGlassesComputer computer) { public void updateModules() { // We need to set the initialisation to false so the dynamic peripheral re-builds the plugins - initialized = false; - if (plugins != null) - plugins.clear(); + clearAllPlugins(); - getPeripheralOwner().getComputer().getModules().values().forEach(module -> { - IModuleFunctions functions = module.getFunctions(getPeripheralOwner().getComputer().getSmartGlassesAccess()); - if (functions != null) + SmartGlassesComputer computer = getPeripheralOwner().getComputer(); + computer.getModules().values().forEach(module -> { + IModuleFunctions functions = module.getFunctions(computer.getSmartGlassesAccess()); + if (functions != null) { addPlugin(functions); + } }); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheralOwner.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheralOwner.java index 62d22cdeb..f7353f1ef 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheralOwner.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/ModulePeripheralOwner.java @@ -14,6 +14,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; + import org.apache.commons.lang3.NotImplementedException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,19 +47,33 @@ public Level getLevel() { @NotNull @Override public BlockPos getPos() { - return computer.getEntity().getOnPos(); + return new BlockPos(computer.getEntity().getEyePosition()); + } + + @NotNull + @Override + public Vec3 getCenterPos() { + return computer.getEntity().getEyePosition(); } @NotNull @Override public Direction getFacing() { - return Direction.NORTH; + Vec3 dir = getDirection(); + return Direction.getNearest(dir.x, dir.y, dir.z); } @NotNull @Override public FrontAndTop getOrientation() { - return FrontAndTop.NORTH_UP; + Vec3 up = computer.getEntity().getUpVector(1.0f); + return FrontAndTop.fromFrontAndTop(getFacing(), Direction.getNearest(up.x, up.y, up.z)); + } + + @NotNull + @Override + public Vec3 getDirection() { + return computer.getEntity().getLookAngle(); } @NotNull @@ -65,12 +81,17 @@ public SmartGlassesComputer getComputer() { return computer; } + @Nullable + @Override + public Entity getHoldingEntity() { + return computer.getEntity(); + } + @Nullable @Override public Player getOwner() { Entity owner = computer.getEntity(); - if (owner instanceof Player player) return player; - return null; + return owner instanceof Player player ? player : null; } @NotNull diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/hotkey/HotkeyModuleItem.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/hotkey/HotkeyModuleItem.java index 9dd8594a6..ad0169382 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/hotkey/HotkeyModuleItem.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/hotkey/HotkeyModuleItem.java @@ -36,7 +36,7 @@ public void inventoryTick(@NotNull ItemStack stack, @NotNull Level level, @NotNu if (KeybindUtil.isKeyPressed(KeyBindings.GLASSES_HOTKEY_KEYBINDING)) { // Add another 50ms to the duration, one tick setKeyPressDuration(stack, getKeyPressDuration(stack) + 50); - } else if(getKeyPressDuration(stack) > 0) { + } else if (getKeyPressDuration(stack) > 0) { // If the key is not pressed, but the duration is greater than 0, we can assume that the key was pressed // We can now post the event @@ -44,12 +44,12 @@ public void inventoryTick(@NotNull ItemStack stack, @NotNull Level level, @NotNu setKeyPressDuration(stack, 0); String keyBind = KeyBindings.GLASSES_HOTKEY_KEYBINDING.getKey().getName(); - APNetworking.sendToServer(new GlassesHotkeyPacket(player.getUUID(), keyBind, duration)); + APNetworking.sendToServer(new GlassesHotkeyPacket(keyBind, duration)); } } public static int getKeyPressDuration(ItemStack stack) { - return stack.copy().getOrCreateTag().getInt(KEY_PRESS_DURATION_NBT); + return stack.hasTag() ? stack.getTag().getInt(KEY_PRESS_DURATION_NBT) : 0; } public static void setKeyPressDuration(ItemStack stack, int keyPressDuration) { diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/keyboard/KeyboardFunctions.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/keyboard/KeyboardFunctions.java new file mode 100644 index 000000000..8c5a7f138 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/keyboard/KeyboardFunctions.java @@ -0,0 +1,23 @@ +package de.srendi.advancedperipherals.common.smartglasses.modules.keyboard; + +import dan200.computercraft.api.lua.LuaFunction; +import de.srendi.advancedperipherals.common.smartglasses.modules.IModuleFunctions; + +public class KeyboardFunctions implements IModuleFunctions { + + private final KeyboardModule keyboardModule; + + public KeyboardFunctions(KeyboardModule keyboardModule) { + this.keyboardModule = keyboardModule; + } + + @LuaFunction + public final boolean isCapturingMouse() { + return keyboardModule.isCapturingMouse(); + } + + @LuaFunction + public final void setCaptureMouse(boolean enable) { + keyboardModule.setCaptureMouse(enable); + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/keyboard/KeyboardModule.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/keyboard/KeyboardModule.java index 9031e0fae..b7a02ea6b 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/keyboard/KeyboardModule.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/keyboard/KeyboardModule.java @@ -1,14 +1,20 @@ package de.srendi.advancedperipherals.common.smartglasses.modules.keyboard; import de.srendi.advancedperipherals.AdvancedPeripherals; +import de.srendi.advancedperipherals.common.network.APNetworking; +import de.srendi.advancedperipherals.common.network.toclient.KeyboardMouseCapturePacket; import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesAccess; import de.srendi.advancedperipherals.common.smartglasses.modules.IModule; import de.srendi.advancedperipherals.common.smartglasses.modules.IModuleFunctions; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; import org.jetbrains.annotations.Nullable; public class KeyboardModule implements IModule { + private boolean lastCaptureMouse = false; + private volatile boolean captureMouse = false; + @Override public ResourceLocation getName() { return AdvancedPeripherals.getRL("keyboard"); @@ -17,6 +23,29 @@ public ResourceLocation getName() { @Nullable @Override public IModuleFunctions getFunctions(SmartGlassesAccess smartGlassesAccess) { - return null; + return new KeyboardFunctions(this); + } + + public boolean isCapturingMouse() { + return captureMouse; + } + + public void setCaptureMouse(boolean enable) { + if (captureMouse == enable) { + return; + } + captureMouse = enable; + } + + @Override + public void tick(SmartGlassesAccess glasses) { + if (!(glasses.getEntity() instanceof ServerPlayer player)) { + return; + } + boolean captureMouse = this.captureMouse; + if (captureMouse != lastCaptureMouse) { + lastCaptureMouse = captureMouse; + APNetworking.sendTo(new KeyboardMouseCapturePacket(captureMouse), player); + } } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModule.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModule.java index f1333b273..5c938b289 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModule.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModule.java @@ -11,7 +11,7 @@ public class NightVisionModule implements IModule { - public boolean nightVisionEnabled = true; + private boolean nightVisionEnabled = true; public NightVisionModule() { @@ -35,7 +35,6 @@ public void onUnequipped(SmartGlassesAccess smartGlassesAccess) { player.removeEffect(MobEffects.NIGHT_VISION); } } - } /** diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModuleItem.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModuleItem.java index 44da3ee90..47f5bdc23 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModuleItem.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/nightvision/NightVisionModuleItem.java @@ -30,12 +30,13 @@ public void inventoryTick(ItemStack itemStack, Level level, Entity entity, int i return; } - if (module instanceof NightVisionModule nightVisionModule) { - if (nightVisionModule.nightVisionEnabled) { - player.addEffect(new MobEffectInstance(MobEffects.NIGHT_VISION, 20 * 13 - 1 /* minus 1 tick then the client timing won't flash */)); - } else { - player.removeEffect(MobEffects.NIGHT_VISION); - } + if (!(module instanceof NightVisionModule nightVisionModule)) { + return; + } + if (nightVisionModule.isNightVisionEnabled()) { + player.addEffect(new MobEffectInstance(MobEffects.NIGHT_VISION, 20 * 13 - 1 /* minus 1 tick then the client timing won't flash */)); + } else { + player.removeEffect(MobEffects.NIGHT_VISION); } } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/overlay/OverlayGlassesFunctions.java b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/overlay/OverlayGlassesFunctions.java index bffed31cb..d0c99a7e5 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/overlay/OverlayGlassesFunctions.java +++ b/src/main/java/de/srendi/advancedperipherals/common/smartglasses/modules/overlay/OverlayGlassesFunctions.java @@ -16,6 +16,7 @@ import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.RenderableObject; import de.srendi.advancedperipherals.common.smartglasses.modules.overlay.objects.two_dim.TextObject; import net.minecraft.client.Minecraft; +import net.minecraft.world.phys.Vec3; public class OverlayGlassesFunctions implements IModuleFunctions { @@ -120,7 +121,8 @@ public final MethodResult getSize() { @LuaFunction public final MethodResult getCoords() { - return MethodResult.of(access.getEntity().position().x, access.getEntity().position().y, access.getEntity().position().z); + Vec3 pos = access.getEntity().getEyePosition(); + return MethodResult.of(pos.x, pos.y, pos.z); } @LuaFunction diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/ChunkManager.java b/src/main/java/de/srendi/advancedperipherals/common/util/ChunkManager.java index 8a8ec7e89..238b16943 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/ChunkManager.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/ChunkManager.java @@ -39,6 +39,10 @@ public ChunkManager() { super(); } + public static int getMaxLoadRadius() { + return APConfig.PERIPHERALS_CONFIG.chunkyTurtleRadius.get(); + } + public static @NotNull ChunkManager get(@NotNull ServerLevel level) { return level.getDataStorage().computeIfAbsent(ChunkManager::load, ChunkManager::new, DATA_NAME); } @@ -81,6 +85,10 @@ private static boolean unforceChunk(UUID owner, ServerLevel level, ChunkPos pos) return ForgeChunkManager.forceChunk(level, AdvancedPeripherals.MOD_ID, owner, pos.x, pos.z, false, true); } + public synchronized int getForcedChunksCount() { + return this.forcedChunks.size(); + } + public synchronized boolean addForceChunk(ServerLevel level, UUID owner, ChunkPos pos) { AdvancedPeripherals.debug("Trying to load forced chunk cluster " + pos, Level.WARN); LoadChunkRecord oldRecord = forcedChunks.get(owner); @@ -91,7 +99,7 @@ public synchronized boolean addForceChunk(ServerLevel level, UUID owner, ChunkPo } unforceChunkRecord(owner, oldRecord, oldLevel); } - final int chunkRadius = APConfig.PERIPHERALS_CONFIG.chunkyTurtleRadius.get(); + final int chunkRadius = getMaxLoadRadius(); forcedChunks.put(owner, new LoadChunkRecord(level.dimension().location().toString(), pos, chunkRadius)); setDirty(); boolean result = true; @@ -154,7 +162,7 @@ public synchronized void init() { initialized = true; AdvancedPeripherals.debug(String.format("Schedule chunk manager init, forcedChunks = %d", forcedChunks.size()), Level.WARN); - final int chunkRadius = APConfig.PERIPHERALS_CONFIG.chunkyTurtleRadius.get(); + final int chunkRadius = getMaxLoadRadius(); final Map levels = getServerLevels(); forcedChunks.forEach((uuid, value) -> { String dimensionName = value.getDimensionName(); diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/DataStorageUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/DataStorageUtil.java index 0499427cc..52585dbb4 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/DataStorageUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/DataStorageUtil.java @@ -1,14 +1,17 @@ package de.srendi.advancedperipherals.common.util; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.TurtleSide; import de.srendi.advancedperipherals.common.addons.computercraft.owner.IPeripheralOwner; import de.srendi.advancedperipherals.lib.peripherals.IPeripheralTileEntity; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; import org.jetbrains.annotations.NotNull; public class DataStorageUtil { + private DataStorageUtil() {} public static CompoundTag getDataStorage(@NotNull ITurtleAccess access, @NotNull TurtleSide side) { return access.getUpgradeNBTData(side); @@ -18,8 +21,17 @@ public static CompoundTag getDataStorage(@NotNull IPeripheralTileEntity tileEnti return tileEntity.getPeripheralSettings(); } - public static CompoundTag getDataStorage(@NotNull IPocketAccess pocket) { - return pocket.getUpgradeNBTData(); + public static CompoundTag getDataStorage(@NotNull IPocketAccess pocket, @NotNull IPocketUpgrade upgrade) { + String id = upgrade.getUpgradeID().toString(); + CompoundTag datas = pocket.getUpgradeNBTData(); + Tag tag = datas.get(id); + if (tag instanceof CompoundTag data) { + return data; + } + CompoundTag data = new CompoundTag(); + datas.put(id, data); + pocket.updateUpgradeNBTData(); + return data; } /** diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/EnergyStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/EnergyStorageProxy.java deleted file mode 100644 index 81d7f4a00..000000000 --- a/src/main/java/de/srendi/advancedperipherals/common/util/EnergyStorageProxy.java +++ /dev/null @@ -1,76 +0,0 @@ -package de.srendi.advancedperipherals.common.util; - -import de.srendi.advancedperipherals.common.blocks.blockentities.EnergyDetectorEntity; -import net.minecraftforge.energy.IEnergyStorage; - -import java.util.Optional; - -public class EnergyStorageProxy implements IEnergyStorage { - - private final EnergyDetectorEntity energyDetectorTE; - private int maxTransferRate; - private int transferedInThisTick = 0; - - public EnergyStorageProxy(EnergyDetectorEntity energyDetectorTE, int maxTransferRate) { - this.energyDetectorTE = energyDetectorTE; - this.maxTransferRate = maxTransferRate; - } - - @Override - public boolean canReceive() { - return true; - } - - @Override - public int receiveEnergy(int maxReceive, boolean simulate) { - Optional out = energyDetectorTE.getOutputStorage(); - return out.map(outStorage -> { - int transferred = outStorage.receiveEnergy(Math.min(maxReceive, maxTransferRate), simulate); - if (!simulate) { - transferedInThisTick += transferred; - } - return transferred; - }).orElse(0); - } - - @Override - public int getEnergyStored() { - Optional out = energyDetectorTE.getOutputStorage(); - return out.map(IEnergyStorage::getEnergyStored).orElse(0); - } - - @Override - public int getMaxEnergyStored() { - Optional out = energyDetectorTE.getOutputStorage(); - return out.map(IEnergyStorage::getMaxEnergyStored).orElse(0); - } - - @Override - public boolean canExtract() { - return false; - } - - @Override - public int extractEnergy(int maxExtract, boolean simulate) { - return 0; - } - - public int getMaxTransferRate() { - return maxTransferRate; - } - - public void setMaxTransferRate(int rate) { - maxTransferRate = rate; - } - - /** - * should be called on every tick - */ - public void resetTransferedInThisTick() { - transferedInThisTick = 0; - } - - public int getTransferedInThisTick() { - return transferedInThisTick; - } -} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/FluidStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/FluidStorageProxy.java deleted file mode 100644 index a61361aa0..000000000 --- a/src/main/java/de/srendi/advancedperipherals/common/util/FluidStorageProxy.java +++ /dev/null @@ -1,92 +0,0 @@ -package de.srendi.advancedperipherals.common.util; - -import de.srendi.advancedperipherals.common.blocks.blockentities.FluidDetectorEntity; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.IFluidHandler; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; - -public class FluidStorageProxy implements IFluidHandler { - - private final FluidDetectorEntity fluidDetectorEntity; - private int maxTransferRate; - private int transferedInThisTick = 0; - private final Fluid fluid = Fluids.EMPTY; - - public FluidStorageProxy(FluidDetectorEntity fluidDetectorEntity, int maxTransferRate) { - this.fluidDetectorEntity = fluidDetectorEntity; - this.maxTransferRate = maxTransferRate; - } - - - public int getMaxTransferRate() { - return maxTransferRate; - } - - public void setMaxTransferRate(int rate) { - maxTransferRate = rate; - } - - /** - * should be called on every tick - */ - public void resetTransferedInThisTick() { - transferedInThisTick = 0; - } - - public int getTransferedInThisTick() { - return transferedInThisTick; - } - - @Override - public int getTanks() { - return 1; - } - - @Override - public @NotNull FluidStack getFluidInTank(int tank) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> outStorage.getFluidInTank(tank)).orElse(FluidStack.EMPTY); - } - - @Override - public int getTankCapacity(int tank) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> outStorage.getTankCapacity(tank)).orElse(0); - } - - @Override - public boolean isFluidValid(int tank, @NotNull FluidStack stack) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> outStorage.isFluidValid(tank, stack)).orElse(false); - } - - @Override - public int fill(FluidStack resource, IFluidHandler.FluidAction action) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> { - FluidStack transferring = resource.copy(); - transferring.setAmount(Math.min(resource.getAmount(), maxTransferRate)); - int transferred = outStorage.fill(transferring, action); - if (!action.simulate()) { - transferedInThisTick += transferred; - fluidDetectorEntity.lastFlowedLiquid = resource.copy(); - //transferedInThisTick = transferred; - } - return transferred; - }).orElse(0); - } - - @Override - public @NotNull FluidStack drain(int maxDrain, IFluidHandler.FluidAction action) { - return FluidStack.EMPTY; - } - - @Override - public @NotNull FluidStack drain(FluidStack resource, IFluidHandler.FluidAction action) { - return FluidStack.EMPTY; - } -} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/GasStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/GasStorageProxy.java deleted file mode 100644 index d4e514a6d..000000000 --- a/src/main/java/de/srendi/advancedperipherals/common/util/GasStorageProxy.java +++ /dev/null @@ -1,99 +0,0 @@ -package de.srendi.advancedperipherals.common.util; - -import de.srendi.advancedperipherals.common.blocks.blockentities.GasDetectorEntity; -import mekanism.api.Action; -import mekanism.api.chemical.gas.GasStack; -import mekanism.api.chemical.gas.IGasHandler; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; - -public class GasStorageProxy implements IGasHandler { - - private final GasDetectorEntity fluidDetectorEntity; - private int maxTransferRate; - private int transferedInThisTick = 0; - - public GasStorageProxy(GasDetectorEntity fluidDetectorEntity, int maxTransferRate) { - this.fluidDetectorEntity = fluidDetectorEntity; - this.maxTransferRate = maxTransferRate; - } - - - public int getMaxTransferRate() { - return maxTransferRate; - } - - public void setMaxTransferRate(int rate) { - maxTransferRate = rate; - } - - /** - * should be called on every tick - */ - public void resetTransferedInThisTick() { - transferedInThisTick = 0; - } - - public int getTransferedInThisTick() { - return transferedInThisTick; - } - - @Override - public int getTanks() { - return 1; - } - - @NotNull - @Override - public GasStack getChemicalInTank(int tank) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> outStorage.getChemicalInTank(tank)).orElse(GasStack.EMPTY); - } - - @Override - public void setChemicalInTank(int tank, @NotNull GasStack stack) { - Optional out = fluidDetectorEntity.getOutputStorage(); - out.ifPresent(outStorage -> outStorage.setChemicalInTank(tank, stack)); - } - - @Override - public long getTankCapacity(int tank) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> outStorage.getTankCapacity(tank)).orElse(0L); - } - - @Override - public boolean isValid(int tank, @NotNull GasStack stack) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> outStorage.isValid(tank, stack)).orElse(false); - } - - @NotNull - @Override - public GasStack insertChemical(@NotNull GasStack stack, @NotNull Action action) { - Optional out = fluidDetectorEntity.getOutputStorage(); - return out.map(outStorage -> { - GasStack transferring = stack.copy(); - transferring.setAmount(Math.min(stack.getAmount(), maxTransferRate)); - GasStack transferred = outStorage.insertChemical(transferring, action); - if (!action.simulate()) { - transferedInThisTick += transferring.getAmount() - transferred.getAmount(); - fluidDetectorEntity.lastFlowedGas = stack.copy(); - } - return transferred; - }).orElse(GasStack.EMPTY); - } - - @NotNull - @Override - public GasStack insertChemical(int tank, @NotNull GasStack stack, @NotNull Action action) { - return insertChemical(stack, action); - } - - @NotNull - @Override - public GasStack extractChemical(int tank, long amount, @NotNull Action action) { - return GasStack.EMPTY; - } -} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java index 801937e2c..6112dc4a7 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java @@ -1,9 +1,13 @@ package de.srendi.advancedperipherals.common.util; +import de.srendi.advancedperipherals.common.addons.computercraft.owner.IPeripheralOwner; +import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; +import de.srendi.advancedperipherals.common.addons.computercraft.owner.TurtlePeripheralOwner; import de.srendi.advancedperipherals.common.addons.computercraft.peripheral.DistanceDetectorPeripheral; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySelector; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; @@ -20,37 +24,45 @@ import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.function.Predicate; public class HitResultUtil { /** * This method is used to get the hit result of an entity from the start position of a block * - * @param to the target position/max position * @param from the source position like a block + * @param to the target position/max position * @param level the level * @param shapeGetter the block collision shape getter * @return the hit result. {@link BlockHitResult#miss(Vec3, Direction, BlockPos)} if nothing found */ @NotNull - public static HitResult getHitResult(Vec3 to, Vec3 from, Level level, ClipContext.ShapeGetter shapeGetter) { - return getHitResult(to, from, level, shapeGetter, null); + public static HitResult getHitResult(Vec3 from, Vec3 to, Level level, ClipContext.ShapeGetter shapeGetter) { + return getHitResult(from, to, level, shapeGetter, null); } /** * This method is used to get the hit result of an entity from the start position of a block * - * @param to the target position/max position * @param from the source position like a block + * @param to the target position/max position * @param level the level * @param shapeGetter the block collision shape getter - * @param source the source Entity/BlockPos that will be ignored + * @param source the source Entity/BlockPos that will be ignored, or an {@link IPeripheralOwner} to auto determine the source. * @return the hit result. {@link BlockHitResult#miss(Vec3, Direction, BlockPos)} if nothing found */ @NotNull - public static HitResult getHitResult(Vec3 to, Vec3 from, Level level, ClipContext.ShapeGetter shapeGetter, Object source) { - EntityHitResult entityResult = getEntityHitResult(to, from, level, source instanceof Entity ? (Entity) source : null); - BlockHitResult blockResult = getBlockHitResult(to, from, level, shapeGetter, source instanceof BlockPos ? (BlockPos) source : null); + public static HitResult getHitResult(Vec3 from, Vec3 to, Level level, ClipContext.ShapeGetter shapeGetter, Object source) { + if (source instanceof IPeripheralOwner owner) { + if (owner instanceof BlockEntityPeripheralOwner || owner instanceof TurtlePeripheralOwner) { + source = owner.getPos(); + } else { + source = owner.getHoldingEntity(); + } + } + EntityHitResult entityResult = getEntityHitResult(from, to, level, source instanceof Entity ? (Entity) source : null, source instanceof Predicate ? (Predicate) source : EntitySelector.NO_SPECTATORS); + BlockHitResult blockResult = getBlockHitResult(from, to, level, shapeGetter, source instanceof BlockPos ? (BlockPos) source : null); if (entityResult.getType() == HitResult.Type.MISS) { if (blockResult.getType() == HitResult.Type.MISS) { @@ -73,14 +85,14 @@ public static HitResult getHitResult(Vec3 to, Vec3 from, Level level, ClipContex * this method uses one AABB made out of the two coordinates, this would also find any entities * which are not located in the ray you might want. {@link DistanceDetectorPeripheral#getDistance()} * - * @param to the target position/max position * @param from the source position like a block + * @param to the target position/max position * @param level the world * @return the entity hit result. An empty HitResult with {@link HitResult.Type#MISS} as type if nothing found */ @NotNull - public static EntityHitResult getEntityHitResult(Vec3 to, Vec3 from, Level level) { - return getEntityHitResult(to, from, level, null); + public static EntityHitResult getEntityHitResult(Vec3 from, Vec3 to, Level level) { + return getEntityHitResult(from, to, level, null); } /** @@ -89,17 +101,35 @@ public static EntityHitResult getEntityHitResult(Vec3 to, Vec3 from, Level level * this method uses one AABB made out of the two coordinates, this would also find any entities * which are not located in the ray you might want. {@link DistanceDetectorPeripheral#getDistance()} * - * @param to the target position/max position * @param from the source position like a block + * @param to the target position/max position * @param level the world * @param source the source Entity that will be ignored * @return the entity hit result. An empty HitResult with {@link HitResult.Type#MISS} as type if nothing found */ @NotNull - public static EntityHitResult getEntityHitResult(Vec3 to, Vec3 from, Level level, Entity source) { + public static EntityHitResult getEntityHitResult(Vec3 from, Vec3 to, Level level, Entity source) { + return getEntityHitResult(from, to, level, source, EntitySelector.NO_SPECTATORS); + } + + /** + * This method is used to get the hit result of an entity from the start position of a block + * This could be used to find an entity from the eyes position of another entity but since + * this method uses one AABB made out of the two coordinates, this would also find any entities + * which are not located in the ray you might want. {@link DistanceDetectorPeripheral#getDistance()} + * + * @param from the source position like a block + * @param to the target position/max position + * @param level the world + * @param source the source Entity that will be ignored + * @param entityFilter the entity filter + * @return the entity hit result. An empty HitResult with {@link HitResult.Type#MISS} as type if nothing found + */ + @NotNull + public static EntityHitResult getEntityHitResult(Vec3 from, Vec3 to, Level level, Entity source, Predicate entityFilter) { AABB checkingBox = new AABB(to, from); - List entities = level.getEntities(source, checkingBox, (entity) -> true); + List entities = level.getEntities(source, checkingBox, entityFilter); Entity nearestEntity = null; Vec3 hitPos = null; @@ -124,29 +154,29 @@ public static EntityHitResult getEntityHitResult(Vec3 to, Vec3 from, Level level /** * This method is used to get the hit result of a block from the start position of a block * - * @param to the target position/max position * @param from the source position + * @param to the target position/max position * @param level the world * @param shapeGetter the block collision shape getter * @return the block hit result. {@link BlockHitResult#miss(Vec3, Direction, BlockPos)} if nothing found */ @NotNull - public static BlockHitResult getBlockHitResult(Vec3 to, Vec3 from, Level level, ClipContext.ShapeGetter shapeGetter) { - return getBlockHitResult(to, from, level, shapeGetter, null); + public static BlockHitResult getBlockHitResult(Vec3 from, Vec3 to, Level level, ClipContext.ShapeGetter shapeGetter) { + return getBlockHitResult(from, to, level, shapeGetter, null); } /** * This method is used to get the hit result of a block from the start position of a block * - * @param to the target position/max position * @param from the source position + * @param to the target position/max position * @param level the world * @param shapeGetter the block collision shape getter * @param source the source BlockPos that will be ignored * @return the block hit result. {@link BlockHitResult#miss(Vec3, Direction, BlockPos)} if nothing found */ @NotNull - public static BlockHitResult getBlockHitResult(Vec3 to, Vec3 from, Level level, ClipContext.ShapeGetter shapeGetter, BlockPos source) { + public static BlockHitResult getBlockHitResult(Vec3 from, Vec3 to, Level level, ClipContext.ShapeGetter shapeGetter, BlockPos source) { return level.clip(new AdvancedClipContext(from, to, shapeGetter, ClipContext.Fluid.NONE, null, source)); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java b/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java index 32eea9135..4c0dd08ad 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/LuaConverter.java @@ -44,6 +44,8 @@ public class LuaConverter { + private static final CompoundTag EMPTY_TAG = new CompoundTag(); + public static Map entityToLua(Entity entity) { Map data = new HashMap<>(); data.put("id", entity.getId()); @@ -200,7 +202,10 @@ public static Map itemStackToObject(@NotNull ItemStack stack) { return null; } Map map = itemToObject(stack.getItem()); - CompoundTag nbt = stack.copy().getOrCreateTag(); + CompoundTag nbt = stack.getTag(); + if (nbt == null) { + nbt = EMPTY_TAG; + } map.put("count", stack.getCount()); map.put("displayName", stack.getDisplayName().getString()); map.put("maxStackSize", stack.getMaxStackSize()); @@ -216,7 +221,10 @@ public static Map fluidStackToObject(@NotNull FluidStack stack) return null; } Map map = fluidToObject(stack.getFluid()); - CompoundTag nbt = stack.copy().getOrCreateTag(); + CompoundTag nbt = stack.getTag(); + if (nbt == null) { + nbt = EMPTY_TAG; + } map.put("count", stack.getAmount()); map.put("displayName", stack.getDisplayName().getString()); map.put("nbt", NBTUtil.toLua(nbt)); diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/NBTUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/NBTUtil.java index 114a6e9ed..bb6e37ebd 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/NBTUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/NBTUtil.java @@ -23,6 +23,7 @@ import java.util.Map; public class NBTUtil { + private NBTUtil() {} public static Tag toDirectNBT(Object object) { // Mostly dan200.computercraft.shared.util toNBTTag method diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/ServerWorker.java b/src/main/java/de/srendi/advancedperipherals/common/util/ServerWorker.java index cbde6790b..fc9dced5a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/ServerWorker.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/ServerWorker.java @@ -33,7 +33,7 @@ public static void addToNextTick(final Runnable task) { @SubscribeEvent public static void serverTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.END) { - while (!callQueue.isEmpty()) { + for (int remain = callQueue.size(); remain > 0; remain--) { final Runnable runnable = callQueue.poll(); tasksRan++; AdvancedPeripherals.debug("Running task #" + tasksRan + ". Running " + runnable.getClass()); diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/TeleportUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/TeleportUtil.java new file mode 100644 index 000000000..24edd1379 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/util/TeleportUtil.java @@ -0,0 +1,41 @@ +package de.srendi.advancedperipherals.common.util; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; + +import java.util.ArrayList; +import java.util.List; + +public final class TeleportUtil { + private TeleportUtil() {} + + public static T teleportToWithPassengers(T entity, ServerLevel newLevel, Vec3 newPos) { + Vec3 oldPos = entity.position(); + List passengers = new ArrayList<>(entity.getPassengers()); + T newEntity; + if (entity instanceof ServerPlayer player) { + // TODO <1.20.1>: player will be reconstruct in 1.20.1 + player.teleportTo(newLevel, newPos.x, newPos.y, newPos.z, player.getYRot(), player.getXRot()); + newEntity = entity; + } else { + newEntity = (T) entity.getType().create(newLevel); + if (newEntity == null) { + return null; + } + entity.ejectPassengers(); + newEntity.restoreFrom(entity); + newEntity.moveTo(newPos.x, newPos.y, newPos.z, newEntity.getYRot(), newEntity.getXRot()); + newLevel.addDuringTeleport(newEntity); + entity.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); + } + for (Entity p : passengers) { + Entity newPassenger = teleportToWithPassengers(p, newLevel, p.position().subtract(oldPos).add(newPos)); + if (newPassenger != null) { + newPassenger.startRiding(newEntity, true); + } + } + return newEntity; + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/APFakePlayer.java b/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/APFakePlayer.java index bc7c6bbf2..60d0c56c5 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/APFakePlayer.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/APFakePlayer.java @@ -32,7 +32,6 @@ import net.minecraft.world.level.block.StructureBlock; import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; @@ -46,7 +45,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; import java.util.UUID; import java.util.function.Predicate; @@ -55,12 +53,13 @@ public class APFakePlayer extends FakePlayer { Highly inspired by https://github.com/SquidDev-CC/plethora/blob/minecraft-1.12/src/main/java/org/squiddev/plethora/gameplay/PlethoraFakePlayer.java */ public static final GameProfile PROFILE = new GameProfile(UUID.fromString("6e483f02-30db-4454-b612-3a167614b276"), "[" + AdvancedPeripherals.MOD_ID + "]"); - private static final Predicate collidablePredicate = EntitySelector.NO_SPECTATORS; + private static final Predicate DEFAULT_ENTITY_FILTER = EntitySelector.NO_SPECTATORS.and(LivingEntity.class::isInstance).and((entity) -> !entity.isPassenger()); private BlockPos source = null; private BlockPos digPosition = null; private Block digBlock = null; private float currentDamage = 0; + private double reachRange = -1; public APFakePlayer(ServerLevel world, Entity owner, GameProfile profile) { super(world, profile != null && profile.isComplete() ? profile : PROFILE); @@ -140,13 +139,38 @@ public T doActionWithShiftKey(boolean shift, Action action) { } } + public static Action wrapActionWithReachRange(double range, Action action) { + return player -> player.doActionWithReachRange(range, action); + } + + public T doActionWithReachRange(double range, Action action) { + this.reachRange = range; + try { + return action.apply(this); + } finally { + this.reachRange = -1; + } + } + + public double getReachRange() { + AttributeInstance reachAttribute = this.getAttribute(ForgeMod.REACH_DISTANCE.get()); + if (reachAttribute == null) { + throw new IllegalArgumentException("How did this happened?"); + } + double range = reachAttribute.getValue(); + if (this.reachRange >= 0 && this.reachRange < range) { + range = this.reachRange; + } + return range; + } + public Pair digBlock() { Level world = getLevel(); HitResult hit = findHit(true, false); - if (hit.getType() == HitResult.Type.MISS) { + if (!(hit instanceof BlockHitResult blockHit) || hit.getType() == HitResult.Type.MISS) { return Pair.of(false, "Nothing to break"); } - BlockPos pos = new BlockPos(hit.getLocation()); + BlockPos pos = blockHit.getBlockPos(); BlockState state = world.getBlockState(pos); Block block = state.getBlock(); @@ -276,81 +300,34 @@ public InteractionResult use(boolean skipEntity, boolean skipBlock, @Nullable Pr } public HitResult findHit(boolean skipEntity, boolean skipBlock) { - return findHit(skipEntity, skipBlock, null); + return findHit(skipEntity, skipBlock, DEFAULT_ENTITY_FILTER); } @NotNull - public HitResult findHit(boolean skipEntity, boolean skipBlock, @Nullable Predicate entityFilter) { - AttributeInstance reachAttribute = this.getAttribute(ForgeMod.REACH_DISTANCE.get()); - if (reachAttribute == null) - throw new IllegalArgumentException("How did this happened?"); - - double range = reachAttribute.getValue(); + public HitResult findHit(boolean skipEntity, boolean skipBlock, @NotNull Predicate entityFilter) { + double range = this.getReachRange(); Vec3 origin = new Vec3(this.getX(), this.getY(), this.getZ()); Vec3 look = this.getLookAngle(); Vec3 target = new Vec3(origin.x + look.x * range, origin.y + look.y * range, origin.z + look.z * range); - HitResult blockHit; + + BlockHitResult blockHit; if (skipBlock) { Direction traceDirection = Direction.getNearest(look.x, look.y, look.z); blockHit = BlockHitResult.miss(target, traceDirection, new BlockPos(target)); } else { - blockHit = HitResultUtil.getBlockHitResult(target, origin, level, ClipContext.Block.OUTLINE, this.source); + blockHit = HitResultUtil.getBlockHitResult(origin, target, level, ClipContext.Block.OUTLINE, this.source); } if (skipEntity) { return blockHit; } - List entities = level.getEntities(this, this.getBoundingBox().expandTowards(look.x * range, look.y * range, look.z * range).inflate(1), collidablePredicate); - - LivingEntity closestEntity = null; - Vec3 closestVec = null; - double closestDistance = blockHit.getType() == HitResult.Type.MISS ? range * range : distanceToSqr(blockHit.getLocation()); - for (Entity entityHit : entities) { - if (!(entityHit instanceof LivingEntity entity)) { - continue; - } - // TODO: maybe let entityFilter returns the priority of the entity, instead of only returns the closest one. - if (entityFilter != null && !entityFilter.test(entity)) { - continue; - } - - // Hit vehicle before passenger - if (entity.isPassenger()) { - continue; - } - - AABB box = entity.getBoundingBox(); - Vec3 clipVec; - if (box.contains(origin)) { - clipVec = origin; - } else { - clipVec = box.clip(origin, target).orElse(null); - if (clipVec == null) { - continue; - } - } - double distance = origin.distanceToSqr(clipVec); - // Ignore small enough distance - if (distance <= 1e-6) { - distance = 0; - } - if (distance > closestDistance) { - continue; - } - if (distance == closestDistance && closestEntity != null) { - // Hit larger entity before smaller - if (closestEntity.getBoundingBox().getSize() >= box.getSize()) { - continue; - } - } - closestEntity = entity; - closestVec = clipVec; - closestDistance = distance; - } - if (closestEntity != null) { - return new EntityHitResult(closestEntity, closestVec); + // TODO: maybe let entityFilter returns the priority of the entity, instead of only returns the closest one. + EntityHitResult entityHit = HitResultUtil.getEntityHitResult(origin, target, level, this, entityFilter); + if (entityHit.getType() == HitResult.Type.ENTITY) { + return entityHit; } + return blockHit; } diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/FakePlayerProviderTurtle.java b/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/FakePlayerProviderTurtle.java index 159fcda5c..aa9b0b86e 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/FakePlayerProviderTurtle.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/fakeplayer/FakePlayerProviderTurtle.java @@ -4,6 +4,7 @@ import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.shared.util.WorldUtil; import de.srendi.advancedperipherals.common.addons.APAddons; +import de.srendi.advancedperipherals.common.addons.valkyrienskies.ValkyrienSkies; import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; @@ -15,9 +16,6 @@ import net.minecraft.world.phys.Vec3; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.wrapper.InvWrapper; -import org.joml.Matrix4dc; -import org.joml.Vector3d; -import org.valkyrienskies.core.api.ships.Ship; import java.util.WeakHashMap; @@ -45,14 +43,8 @@ public static void load(APFakePlayer player, ITurtleAccess turtle) { Vec3 direction = Vec3.atLowerCornerOf(turtle.getDirection().getNormal()); Vec3 position = Vec3.atCenterOf(pos); if (APAddons.vs2Loaded) { - Ship ship = APAddons.getVS2Ship(level, pos); - if (ship != null) { - Matrix4dc matrix = ship.getShipToWorld(); - Vector3d newPos = matrix.transformPosition(new Vector3d(position.x, position.y, position.z)); - Vector3d newDir = matrix.transformDirection(new Vector3d(direction.x, direction.y, direction.z)); - position = new Vec3(newPos.x, newPos.y, newPos.z); - direction = new Vec3(newDir.x, newDir.y, newDir.z); - } + position = ValkyrienSkies.transformToWorldPos(level, pos, position); + direction = ValkyrienSkies.transformToWorldDir(level, pos, direction); } player.setPosRaw(position.x, position.y, position.z); player.lookAt(EntityAnchorArgument.Anchor.FEET, position.add(direction)); diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java index a3d8cdec6..f6fcbae85 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/FluidUtil.java @@ -3,11 +3,11 @@ import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; -import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.common.addons.computercraft.owner.IPeripheralOwner; import de.srendi.advancedperipherals.common.util.CoordUtil; import de.srendi.advancedperipherals.common.util.StringUtil; import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -23,13 +23,11 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.Objects; public class FluidUtil { - private FluidUtil() { - } + private FluidUtil() {} @Nullable public static IFluidHandler extractHandler(@Nullable Object object) { @@ -76,16 +74,16 @@ public static IFluidHandler getHandlerFromName(@NotNull IComputerAccess access, @NotNull public static String getFingerprint(@NotNull FluidStack stack) { - String fingerprint = stack.getOrCreateTag() + getRegistryKey(stack).toString() + stack.getDisplayName().getString(); - try { - byte[] bytesOfHash = fingerprint.getBytes(StandardCharsets.UTF_8); - MessageDigest md = MessageDigest.getInstance("MD5"); - return StringUtil.toHexString(md.digest(bytesOfHash)); - } catch (NoSuchAlgorithmException ex) { - AdvancedPeripherals.debug("Could not parse fingerprint.", org.apache.logging.log4j.Level.ERROR); - ex.printStackTrace(); + MessageDigest md = ItemUtil.getMessageDigest("MD5"); + if (md == null) { + return ""; + } + CompoundTag tag = stack.getTag(); + md.update(getRegistryKey(stack).toString().getBytes(StandardCharsets.UTF_8)); + if (tag != null && !tag.isEmpty()) { + md.update(tag.getAsString().getBytes(StandardCharsets.UTF_8)); } - return ""; + return StringUtil.toHexString(md.digest()); } public static ResourceLocation getRegistryKey(Fluid fluid) { @@ -93,6 +91,6 @@ public static ResourceLocation getRegistryKey(Fluid fluid) { } public static ResourceLocation getRegistryKey(FluidStack fluid) { - return ForgeRegistries.FLUIDS.getKey(fluid.copy().getFluid()); + return ForgeRegistries.FLUIDS.getKey(fluid.getFluid()); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ItemUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ItemUtil.java index 008d4d928..87f47ae77 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ItemUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/inventory/ItemUtil.java @@ -3,6 +3,7 @@ import dan200.computercraft.shared.Registry; import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.common.util.StringUtil; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -24,6 +25,18 @@ public class ItemUtil { public static final Item POCKET_NORMAL = Registry.ModItems.POCKET_COMPUTER_NORMAL.get(); public static final Item POCKET_ADVANCED = Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(); + private ItemUtil() {} + + static MessageDigest getMessageDigest(String algorithm) { + try { + return MessageDigest.getInstance(algorithm); + } catch (NoSuchAlgorithmException ex) { + AdvancedPeripherals.debug("Could not generate fingerprint.", Level.ERROR); + ex.printStackTrace(); + return null; + } + } + /** * Fingerprints are MD5 hashes generated out of the nbt tag, the registry name and the display name from item stacks * Used to filter inventory specific operations. {@link de.srendi.advancedperipherals.common.addons.computercraft.peripheral.InventoryManagerPeripheral} @@ -31,16 +44,16 @@ public class ItemUtil { * @return A generated MD5 hash from the item stack */ public static String getFingerprint(ItemStack stack) { - String fingerprint = stack.getOrCreateTag() + getRegistryKey(stack).toString() + stack.getDisplayName().getString(); - try { - byte[] bytesOfHash = fingerprint.getBytes(StandardCharsets.UTF_8); - MessageDigest md = MessageDigest.getInstance("MD5"); - return StringUtil.toHexString(md.digest(bytesOfHash)); - } catch (NoSuchAlgorithmException ex) { - AdvancedPeripherals.debug("Could not parse fingerprint.", Level.ERROR); - ex.printStackTrace(); + MessageDigest md = getMessageDigest("MD5"); + if (md == null) { + return ""; + } + CompoundTag tag = stack.getTag(); + md.update(getRegistryKey(stack).toString().getBytes(StandardCharsets.UTF_8)); + if (tag != null && !tag.isEmpty()) { + md.update(tag.getAsString().getBytes(StandardCharsets.UTF_8)); } - return ""; + return StringUtil.toHexString(md.digest()); } public static ItemStack makeTurtle(Item turtle, String upgrade) { @@ -70,6 +83,6 @@ public static ResourceLocation getRegistryKey(Item item) { } public static ResourceLocation getRegistryKey(ItemStack item) { - return ForgeRegistries.ITEMS.getKey(item.copy().getItem()); + return ForgeRegistries.ITEMS.getKey(item.getItem()); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/proxy/AbstractStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/AbstractStorageProxy.java new file mode 100644 index 000000000..b8e007c37 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/AbstractStorageProxy.java @@ -0,0 +1,42 @@ +package de.srendi.advancedperipherals.common.util.proxy; + +public abstract class AbstractStorageProxy implements IStorageProxy { + private final long maxTransferRate; + private volatile long transferRate; + private long transfered = 0; + + protected AbstractStorageProxy(long maxTransferRate) { + this.maxTransferRate = maxTransferRate; + this.transferRate = maxTransferRate; + } + + @Override + public long getMaxTransferRate() { + return this.maxTransferRate; + } + + @Override + public long getTransferRate() { + return this.transferRate; + } + + @Override + public void setTransferRate(long rate) { + this.transferRate = Math.min(rate, this.maxTransferRate); + } + + protected void resetStatus() { + this.transfered = 0; + } + + @Override + public long getAndResetTransfered() { + long transfered = this.transfered; + this.resetStatus(); + return transfered; + } + + protected void onTransfered(long amount) { + this.transfered += amount; + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/proxy/EnergyStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/EnergyStorageProxy.java new file mode 100644 index 000000000..de4481be4 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/EnergyStorageProxy.java @@ -0,0 +1,74 @@ +package de.srendi.advancedperipherals.common.util.proxy; + +import de.srendi.advancedperipherals.common.blocks.blockentities.EnergyDetectorEntity; +import net.minecraftforge.energy.IEnergyStorage; + +public class EnergyStorageProxy extends AbstractStorageProxy implements IEnergyStorage { + + private final EnergyDetectorEntity energyDetectorTE; + private boolean lastTransfered = false; + private boolean wasReady = false; + private volatile boolean ready = false; + + public EnergyStorageProxy(EnergyDetectorEntity energyDetectorTE, int maxTransferRate) { + super(maxTransferRate); + this.energyDetectorTE = energyDetectorTE; + } + + @Override + public boolean canReceive() { + return true; + } + + @Override + public int receiveEnergy(int maxReceive, boolean simulate) { + return energyDetectorTE.getOutputStorage().map(outStorage -> { + int transferred = outStorage.receiveEnergy((int) Math.min(maxReceive, this.getTransferRate()), simulate); + if (!simulate) { + this.wasReady = true; + if (transferred > 0) { + this.lastTransfered = true; + this.onTransfered(transferred); + } + } + return transferred; + }).orElse(0); + } + + @Override + public String getLastTransferedId() { + return this.lastTransfered ? "forge:energy" : null; + } + + @Override + public String getReadyTransferId() { + return this.ready ? "forge:energy" : null; + } + + @Override + protected void resetStatus() { + super.resetStatus(); + this.ready = this.wasReady; + this.wasReady = false; + } + + @Override + public int getEnergyStored() { + return energyDetectorTE.getOutputStorage().map(IEnergyStorage::getEnergyStored).orElse(0); + } + + @Override + public int getMaxEnergyStored() { + return energyDetectorTE.getOutputStorage().map(IEnergyStorage::getMaxEnergyStored).orElse(0); + } + + @Override + public boolean canExtract() { + return false; + } + + @Override + public int extractEnergy(int maxExtract, boolean simulate) { + return 0; + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/proxy/FluidStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/FluidStorageProxy.java new file mode 100644 index 000000000..ceccd2bcc --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/FluidStorageProxy.java @@ -0,0 +1,85 @@ +package de.srendi.advancedperipherals.common.util.proxy; + +import de.srendi.advancedperipherals.common.blocks.blockentities.FluidDetectorEntity; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.registries.ForgeRegistries; +import org.jetbrains.annotations.NotNull; + +public class FluidStorageProxy extends AbstractStorageProxy implements IFluidHandler { + + private final FluidDetectorEntity fluidDetectorEntity; + private ResourceLocation lastTransfered = null; + private ResourceLocation wasReady = null; + private volatile ResourceLocation ready = null; + + public FluidStorageProxy(FluidDetectorEntity fluidDetectorEntity, int maxTransferRate) { + super(maxTransferRate); + this.fluidDetectorEntity = fluidDetectorEntity; + } + + @Override + public int getTanks() { + return 1; + } + + @Override + public @NotNull FluidStack getFluidInTank(int tank) { + return fluidDetectorEntity.getOutputStorage().map(outStorage -> outStorage.getFluidInTank(tank)).orElse(FluidStack.EMPTY); + } + + @Override + public int getTankCapacity(int tank) { + return fluidDetectorEntity.getOutputStorage().map(outStorage -> outStorage.getTankCapacity(tank)).orElse(0); + } + + @Override + public boolean isFluidValid(int tank, @NotNull FluidStack stack) { + return fluidDetectorEntity.getOutputStorage().map(outStorage -> outStorage.isFluidValid(tank, stack)).orElse(false); + } + + @Override + public int fill(FluidStack resource, IFluidHandler.FluidAction action) { + return fluidDetectorEntity.getOutputStorage().map(outStorage -> { + FluidStack transferring = resource.copy(); + transferring.setAmount((int) Math.min(resource.getAmount(), this.getTransferRate())); + int transferred = outStorage.fill(transferring, action); + if (!action.simulate()) { + this.wasReady = ForgeRegistries.FLUIDS.getKey(resource.getFluid()); + if (transferred > 0) { + this.onTransfered(transferred); + this.lastTransfered = this.wasReady; + } + } + return transferred; + }).orElse(0); + } + + @Override + public String getLastTransferedId() { + return this.lastTransfered == null ? null : this.lastTransfered.toString(); + } + + @Override + public String getReadyTransferId() { + return this.ready == null ? null : this.ready.toString(); + } + + @Override + protected void resetStatus() { + super.resetStatus(); + this.ready = this.wasReady; + this.wasReady = null; + } + + @Override + public @NotNull FluidStack drain(int maxDrain, IFluidHandler.FluidAction action) { + return FluidStack.EMPTY; + } + + @Override + public @NotNull FluidStack drain(FluidStack resource, IFluidHandler.FluidAction action) { + return FluidStack.EMPTY; + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/proxy/GasStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/GasStorageProxy.java new file mode 100644 index 000000000..d2cf8f544 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/GasStorageProxy.java @@ -0,0 +1,95 @@ +package de.srendi.advancedperipherals.common.util.proxy; + +import de.srendi.advancedperipherals.common.blocks.blockentities.GasDetectorEntity; +import mekanism.api.Action; +import mekanism.api.chemical.gas.GasStack; +import mekanism.api.chemical.gas.IGasHandler; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +public class GasStorageProxy extends AbstractStorageProxy implements IGasHandler { + + private final GasDetectorEntity gasDetectorEntity; + private ResourceLocation lastTransfered = null; + private ResourceLocation wasReady = null; + private volatile ResourceLocation ready = null; + + public GasStorageProxy(GasDetectorEntity gasDetectorEntity, int maxTransferRate) { + super(maxTransferRate); + this.gasDetectorEntity = gasDetectorEntity; + } + + @Override + public int getTanks() { + return 1; + } + + @NotNull + @Override + public GasStack getChemicalInTank(int tank) { + return gasDetectorEntity.getOutputStorage().map(outStorage -> outStorage.getChemicalInTank(tank)).orElse(GasStack.EMPTY); + } + + @Override + public void setChemicalInTank(int tank, @NotNull GasStack stack) { + gasDetectorEntity.getOutputStorage().ifPresent(outStorage -> outStorage.setChemicalInTank(tank, stack)); + } + + @Override + public long getTankCapacity(int tank) { + return gasDetectorEntity.getOutputStorage().map(outStorage -> outStorage.getTankCapacity(tank)).orElse(0L); + } + + @Override + public boolean isValid(int tank, @NotNull GasStack stack) { + return gasDetectorEntity.getOutputStorage().map(outStorage -> outStorage.isValid(tank, stack)).orElse(false); + } + + @NotNull + @Override + public GasStack insertChemical(@NotNull GasStack stack, @NotNull Action action) { + return gasDetectorEntity.getOutputStorage().map(outStorage -> { + GasStack transferring = stack.copy(); + transferring.setAmount(Math.min(stack.getAmount(), this.getTransferRate())); + GasStack left = outStorage.insertChemical(transferring, action); + if (!action.simulate()) { + this.wasReady = stack.getTypeRegistryName(); + long transferred = transferring.getAmount() - left.getAmount(); + if (transferred > 0) { + this.onTransfered(transferred); + this.lastTransfered = this.wasReady; + } + } + return left; + }).orElse(GasStack.EMPTY); + } + + @Override + public String getLastTransferedId() { + return this.lastTransfered == null ? null : this.lastTransfered.toString(); + } + + @Override + public String getReadyTransferId() { + return this.ready == null ? null : this.ready.toString(); + } + + @Override + protected void resetStatus() { + super.resetStatus(); + this.ready = this.wasReady; + this.wasReady = null; + } + + @NotNull + @Override + public GasStack insertChemical(int tank, @NotNull GasStack stack, @NotNull Action action) { + return insertChemical(stack, action); + } + + @NotNull + @Override + public GasStack extractChemical(int tank, long amount, @NotNull Action action) { + return GasStack.EMPTY; + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/proxy/IStorageProxy.java b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/IStorageProxy.java new file mode 100644 index 000000000..59ddee014 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/IStorageProxy.java @@ -0,0 +1,19 @@ +package de.srendi.advancedperipherals.common.util.proxy; + +import org.jetbrains.annotations.Nullable; + +public interface IStorageProxy { + long getMaxTransferRate(); + + long getTransferRate(); + + void setTransferRate(long rate); + + long getAndResetTransfered(); + + @Nullable + String getLastTransferedId(); + + @Nullable + String getReadyTransferId(); +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/ZeroGasTank.java b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/ZeroGasTank.java similarity index 94% rename from src/main/java/de/srendi/advancedperipherals/common/util/ZeroGasTank.java rename to src/main/java/de/srendi/advancedperipherals/common/util/proxy/ZeroGasTank.java index 48f81d3b1..bc92925f6 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/ZeroGasTank.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/proxy/ZeroGasTank.java @@ -1,4 +1,4 @@ -package de.srendi.advancedperipherals.common.util; +package de.srendi.advancedperipherals.common.util.proxy; import mekanism.api.Action; import mekanism.api.chemical.gas.GasStack; diff --git a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/AutomataCorePeripheral.java b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/AutomataCorePeripheral.java index 097e855d4..4c38ed502 100644 --- a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/AutomataCorePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/AutomataCorePeripheral.java @@ -14,9 +14,11 @@ import net.minecraft.core.Direction; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; public abstract class AutomataCorePeripheral extends BasePeripheral { private final IAutomataCoreTier tier; @@ -30,6 +32,11 @@ protected AutomataCorePeripheral(String type, ITurtleAccess turtle, TurtleSide s this.tier = tier; } + @Override + public Set getAdditionalTypes() { + return Collections.singleton("automata"); + } + public void addRotationCycle() { addRotationCycle(1); } diff --git a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/BasePeripheral.java b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/BasePeripheral.java index eb41f7430..78ded5854 100644 --- a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/BasePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/BasePeripheral.java @@ -12,15 +12,12 @@ import de.srendi.advancedperipherals.common.addons.computercraft.owner.IPeripheralOwner; import de.srendi.advancedperipherals.common.addons.computercraft.owner.OperationAbility; import de.srendi.advancedperipherals.common.addons.computercraft.owner.PeripheralOwnerAbility; +import de.srendi.advancedperipherals.common.addons.valkyrienskies.ValkyrienSkies; import de.srendi.advancedperipherals.common.util.CoordUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.joml.Vector3d; -import org.valkyrienskies.core.api.ships.Ship; import java.util.ArrayList; import java.util.Collections; @@ -33,6 +30,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public abstract class BasePeripheral implements IBasePeripheral, IDynamicPeripheral { @@ -41,7 +40,7 @@ public abstract class BasePeripheral implements IBas protected final O owner; protected final List pluggedMethods = new ArrayList<>(); protected boolean initialized = false; - protected List plugins = null; + protected final List plugins = new LinkedList<>(); protected String[] methodNames = new String[0]; protected BasePeripheral(String type, O owner) { @@ -49,32 +48,41 @@ protected BasePeripheral(String type, O owner) { this.owner = owner; } + protected void clearAllPlugins() { + this.initialized = false; + plugins.clear(); + } + protected void buildPlugins() { - if (!initialized) { - initialized = true; - this.pluggedMethods.clear(); - if (plugins != null) plugins.forEach(plugin -> { - if (plugin.isSuitable(this)) - pluggedMethods.addAll(plugin.getMethods()); - }); - owner.getAbilities().forEach(ability -> { - if (ability instanceof IPeripheralPlugin peripheralPlugin) - pluggedMethods.addAll(peripheralPlugin.getMethods()); - }); - this.methodNames = pluggedMethods.stream().map(BoundMethod::getName).toArray(String[]::new); + if (this.initialized) { + return; } + this.initialized = true; + this.pluggedMethods.clear(); + this.plugins.forEach(plugin -> { + if (plugin.isSuitable(this)) { + this.pluggedMethods.addAll(plugin.getMethods()); + } + }); + owner.getAbilities().forEach(ability -> { + if (ability instanceof IPeripheralPlugin peripheralPlugin) { + this.pluggedMethods.addAll(peripheralPlugin.getMethods()); + } + }); + this.methodNames = this.pluggedMethods.stream().map(BoundMethod::getName).toArray(String[]::new); } protected void addPlugin(@NotNull IPeripheralPlugin plugin) { - if (plugins == null) plugins = new LinkedList<>(); - plugins.add(plugin); + this.plugins.add(plugin); IPeripheralOperation[] operations = plugin.getOperations(); if (operations != null) { OperationAbility operationAbility = owner.getAbility(PeripheralOwnerAbility.OPERATION); - if (operationAbility == null) + if (operationAbility == null) { throw new IllegalArgumentException("This is not possible to attach plugin with operations to not operationable owner"); - for (IPeripheralOperation operation : operations) + } + for (IPeripheralOperation operation : operations) { operationAbility.registerOperation(operation); + } } } @@ -144,24 +152,19 @@ public Level getLevel() { } public boolean isOnShip() { - return APAddons.vs2Loaded && APAddons.isBlockOnShip(owner.getLevel(), owner.getPos()); + return APAddons.isBlockOnShip(owner.getLevel(), owner.getPos()); } - public Vec3 getWorldPos() { + public Vec3 getPhysicsPos() { Vec3 pos = this.getCenterPos(); if (!APAddons.vs2Loaded) { return pos; } - Ship ship = APAddons.getVS2Ship(owner.getLevel(), owner.getPos()); - if (ship == null) { - return pos; - } - Vector3d newPos = ship.getShipToWorld().transformPosition(new Vector3d(pos.x, pos.y, pos.z)); - return new Vec3(newPos.x, newPos.y, newPos.z); + return ValkyrienSkies.transformToWorldPos(owner.getLevel(), owner.getPos(), pos); } - public final BlockPos getWorldBlockPos() { - return new BlockPos(this.getWorldPos()); + public final BlockPos getPhysicsBlockPos() { + return new BlockPos(this.getPhysicsPos()); } protected Direction validateSide(String direction) throws LuaException { diff --git a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/DisabledPeripheral.java b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/DisabledPeripheral.java index 8fd524d0c..c97099586 100644 --- a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/DisabledPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/DisabledPeripheral.java @@ -1,17 +1,18 @@ package de.srendi.advancedperipherals.lib.peripherals; import dan200.computercraft.api.pocket.IPocketAccess; +import dan200.computercraft.api.pocket.IPocketUpgrade; import de.srendi.advancedperipherals.common.addons.computercraft.owner.PocketPeripheralOwner; public class DisabledPeripheral extends BasePeripheral { - public static final DisabledPeripheral INSTANCE = new DisabledPeripheral("disabledPeripheral", null); + public static final DisabledPeripheral INSTANCE = new DisabledPeripheral("disabledPeripheral", null, null); - private DisabledPeripheral(String type, IPocketAccess access) { - super(type, new PocketPeripheralOwner(access)); + private DisabledPeripheral(String type, IPocketAccess access, IPocketUpgrade upgrade) { + super(type, new PocketPeripheralOwner(access, upgrade)); } @Override public boolean isEnabled() { - return true; + return false; } } diff --git a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IBasePeripheral.java b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IBasePeripheral.java index d1736f7e6..2bdd8fadc 100644 --- a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IBasePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IBasePeripheral.java @@ -16,4 +16,6 @@ default void queueEvent(String event, Object... args) { } T getPeripheralOwner(); + + default void update() {} } diff --git a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IPeripheralTileEntity.java b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IPeripheralTileEntity.java index 47c526faa..cc3caa796 100644 --- a/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IPeripheralTileEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/lib/peripherals/IPeripheralTileEntity.java @@ -11,8 +11,5 @@ public interface IPeripheralTileEntity { void markSettingsChanged(); - default void handleTick(Level level, BlockState state, BlockEntityType type) { - - } - + default void handleTick(Level level, BlockState state, BlockEntityType type) {} } diff --git a/src/main/java/de/srendi/advancedperipherals/lib/pocket/BasePocketUpgrade.java b/src/main/java/de/srendi/advancedperipherals/lib/pocket/BasePocketUpgrade.java index 291a333de..ea6e01fdd 100644 --- a/src/main/java/de/srendi/advancedperipherals/lib/pocket/BasePocketUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/lib/pocket/BasePocketUpgrade.java @@ -28,4 +28,12 @@ public IPeripheral createPeripheral(@NotNull IPocketAccess access) { if (!peripheral.isEnabled()) return DisabledPeripheral.INSTANCE; return peripheral; } + + @Override + public void update(@NotNull IPocketAccess access, @Nullable IPeripheral peripheral) { + super.update(access, peripheral); + if (peripheral instanceof IBasePeripheral basePeripheral) { + basePeripheral.update(); + } + } } diff --git a/src/main/java/de/srendi/advancedperipherals/lib/turtle/PeripheralTurtleUpgrade.java b/src/main/java/de/srendi/advancedperipherals/lib/turtle/PeripheralTurtleUpgrade.java index 2f06c5944..9171dc811 100644 --- a/src/main/java/de/srendi/advancedperipherals/lib/turtle/PeripheralTurtleUpgrade.java +++ b/src/main/java/de/srendi/advancedperipherals/lib/turtle/PeripheralTurtleUpgrade.java @@ -47,4 +47,12 @@ public boolean isItemSuitable(@NotNull ItemStack stack) { } return super.isItemSuitable(stack); } + + @Override + public void update(@NotNull ITurtleAccess turtle, @NotNull TurtleSide side) { + super.update(turtle, side); + if (!turtle.getLevel().isClientSide() && turtle.getPeripheral(side) instanceof IBasePeripheral basePeripheral) { + basePeripheral.update(); + } + } } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index f4a652f24..5ff034ed1 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -1,7 +1,7 @@ modLoader = "javafml" loaderVersion = "[${loader_version},)" -license = "All rights reserved" -issueTrackerURL = "https://github.com/Seniorendi/AdvancedPeripherals/issues" +license = "Apache-2.0" +issueTrackerURL = "https://github.com/IntelligenceModding/AdvancedPeripherals/issues" logoFile = "pack.png" [[mods]] modId = "${mod_id}" diff --git a/src/main/resources/assets/advancedperipherals/models/item/cable_p2p_tunnel.json b/src/main/resources/assets/advancedperipherals/models/item/cable_p2p_tunnel.json new file mode 100644 index 000000000..334ded781 --- /dev/null +++ b/src/main/resources/assets/advancedperipherals/models/item/cable_p2p_tunnel.json @@ -0,0 +1,6 @@ +{ + "parent": "ae2:item/p2p_tunnel_base", + "textures": { + "type": "computercraft:block/wired_modem_face" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/advancedperipherals/models/part/p2p/p2p_tunnel_cable.json b/src/main/resources/assets/advancedperipherals/models/part/p2p/p2p_tunnel_cable.json new file mode 100644 index 000000000..6baaf6042 --- /dev/null +++ b/src/main/resources/assets/advancedperipherals/models/part/p2p/p2p_tunnel_cable.json @@ -0,0 +1,6 @@ +{ + "parent": "ae2:part/p2p/p2p_tunnel_base", + "textures": { + "type": "computercraft:block/wired_modem_face" + } +}