From 9476ecbcc570a4bb4c4ac86843647587c623f26b Mon Sep 17 00:00:00 2001 From: Mrbysco Date: Sat, 1 Mar 2025 15:09:01 +0100 Subject: [PATCH] Initial port to 1.21.1 TODO: * Fix the ghost block rendering * Fix the placement canceling on setting coordinates --- build.gradle | 40 +- gradle.properties | 19 +- gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 27 +- gradlew.bat | 22 +- .../effortlessbuilding/AllGuiTextures.java | 8 +- .../requios/effortlessbuilding/AllIcons.java | 19 +- .../effortlessbuilding/ClientConfig.java | 4 +- .../effortlessbuilding/ClientEvents.java | 32 +- .../effortlessbuilding/CommonConfig.java | 3 +- .../effortlessbuilding/CommonEvents.java | 13 +- .../EffortlessBuilding.java | 41 +- .../EffortlessBuildingClient.java | 18 +- .../effortlessbuilding/ServerConfig.java | 5 +- .../attachment/AttachmentHandler.java | 2 +- .../attachment/PowerLevel.java | 7 +- .../buildmode/BuildModeCategoryEnum.java | 2 +- .../buildmode/BuildModeEnum.java | 13 +- .../buildmode/BuildModes.java | 2 +- .../buildmode/ModeOptions.java | 4 +- .../buildmode/buildmodes/Circle.java | 2 +- .../buildmode/buildmodes/Cube.java | 2 +- .../buildmode/buildmodes/Cylinder.java | 2 +- .../buildmode/buildmodes/DiagonalLine.java | 2 +- .../buildmode/buildmodes/DiagonalWall.java | 2 +- .../buildmode/buildmodes/Floor.java | 4 +- .../buildmode/buildmodes/Line.java | 2 +- .../buildmode/buildmodes/SlopeFloor.java | 4 +- .../buildmode/buildmodes/Sphere.java | 2 +- .../buildmode/buildmodes/Wall.java | 4 +- .../buildmodifier/Array.java | 4 +- .../buildmodifier/BuildModifiers.java | 4 +- .../buildmodifier/Mirror.java | 3 +- .../buildmodifier/RadialMirror.java | 6 +- .../compatibility/CompatHelper.java | 6 +- .../create/AllSpecialTextures.java | 5 +- .../effortlessbuilding/create/Create.java | 2 +- .../create/CreateClient.java | 4 +- .../create/CreateClientTest.java | 23 - .../create/events/ClientEvents.java | 28 +- .../create/events/CommonEvents.java | 8 +- .../ClientResourceReloadListener.java | 2 +- .../foundation/ModFilePackResources.java | 25 - .../block/render/CTSpriteShiftEntry.java | 29 ++ .../foundation/block/render/CTType.java | 15 + .../render/ConnectedTextureBehaviour.java | 283 ++++++++++ .../block/render/SpriteShiftEntry.java | 49 -- .../foundation/gui/AbstractSimiScreen.java | 4 +- .../create/foundation/gui/AllGuiTextures.java | 7 +- .../create/foundation/gui/AllIcons.java | 15 +- .../foundation/gui/ConfirmationScreen.java | 229 -------- .../gui/CustomLightingSettings.java | 8 +- .../foundation/gui/ILightingSettings.java | 12 - .../foundation/gui/RemovedGuiUtils.java | 21 +- .../create/foundation/gui/Theme.java | 11 +- .../gui/TickableGuiEventListener.java | 7 - .../create/foundation/gui/UIRenderHelper.java | 327 ------------ .../AbstractSimiContainerScreen.java | 5 +- .../gui/container/ClearMenuPacket.java | 30 -- .../gui/container/GhostItemMenu.java | 3 +- .../gui/container/GhostItemSubmitPacket.java | 45 -- .../foundation/gui/element/BoxElement.java | 158 ------ .../gui/element/CombinedStencilElement.java | 82 --- .../gui/element/DelegatedStencilElement.java | 52 -- .../gui/element/GuiGameElement.java | 301 ----------- .../foundation/gui/element/RenderElement.java | 89 ---- .../foundation/gui/element/ScreenElement.java | 12 - .../gui/element/StencilElement.java | 54 -- .../gui/element/TextStencilElement.java | 79 --- .../gui/widget/AbstractSimiWidget.java | 2 +- .../foundation/gui/widget/BoxWidget.java | 226 -------- .../foundation/gui/widget/ElementWidget.java | 157 ------ .../foundation/gui/widget/IconButton.java | 2 +- .../foundation/gui/widget/TooltipArea.java | 4 +- .../foundation/item/ItemDescription.java | 15 +- .../create/foundation/item/ItemHelper.java | 12 +- .../create/foundation/item/TooltipHelper.java | 6 +- .../item/render/PartialItemModelRenderer.java | 2 +- .../networking/ISyncPersistentData.java | 53 -- .../networking/SimplePacketBase.java | 12 - .../render/BakedModelRenderHelper.java | 30 -- .../render/BlockEntityRenderHelper.java | 113 ++++ .../foundation/render/CachedBufferer.java | 87 ---- .../foundation/render/ForcedDiffuseState.java | 30 -- .../create/foundation/render/RenderTypes.java | 4 +- .../foundation/render/ShadowRenderHelper.java | 113 ---- .../foundation/render/SuperByteBuffer.java | 492 ------------------ .../render/SuperByteBufferCache.java | 56 -- .../render/SuperRenderTypeBuffer.java | 92 ---- .../render/TileEntityRenderHelper.java | 113 ---- .../foundation/utility/AngleHelper.java | 52 -- .../utility/AnimationTickHolder.java | 56 -- .../create/foundation/utility/BBHelper.java | 20 - .../create/foundation/utility/BlockFace.java | 52 -- .../foundation/utility/BlockHelper.java | 209 +++++--- .../utility/CameraAngleAnimationService.java | 3 +- .../create/foundation/utility/Color.java | 310 ----------- .../foundation/utility/ColorHandlers.java | 26 - .../create/foundation/utility/Couple.java | 151 ------ .../foundation/utility/CreateRegistry.java | 101 ---- .../create/foundation/utility/Debug.java | 6 +- .../create/foundation/utility/DyeHelper.java | 75 --- .../foundation/utility/DynamicComponent.java | 94 ---- .../foundation/utility/FilesHelper.java | 101 ---- .../foundation/utility/FluidFormatter.java | 1 + .../create/foundation/utility/FontHelper.java | 87 ---- .../foundation/utility/IPartialSafeNBT.java | 7 +- .../foundation/utility/IntAttached.java | 61 --- .../create/foundation/utility/Iterate.java | 48 -- .../create/foundation/utility/Lang.java | 6 +- .../foundation/utility/LangBuilder.java | 165 ------ .../foundation/utility/LangNumberFormat.java | 32 -- .../create/foundation/utility/NBTHelper.java | 106 ---- .../foundation/utility/NBTProcessors.java | 84 --- .../create/foundation/utility/Pair.java | 68 --- .../create/foundation/utility/Pointing.java | 35 -- .../foundation/utility/RegisteredObjects.java | 66 --- .../foundation/utility/ResetableLazy.java | 8 +- .../foundation/utility/UniqueLinkedList.java | 102 ---- .../create/foundation/utility/VecHelper.java | 342 ------------ .../foundation/utility/VoxelShaper.java | 2 + .../foundation/utility/WorldAttached.java | 101 ---- .../foundation/utility/WorldHelper.java | 13 - .../foundation/utility/animation/Force.java | 102 ---- .../utility/animation/LerpedFloat.java | 149 ------ .../utility/animation/PhysicalFloat.java | 90 ---- .../utility/ghost/GhostBlockParams.java | 2 +- .../utility/ghost/GhostBlockRenderer.java | 12 +- .../foundation/utility/ghost/GhostBlocks.java | 2 +- .../utility/outliner/AABBOutline.java | 100 ---- .../utility/outliner/BlockClusterOutline.java | 178 ------- .../utility/outliner/ChasingAABBOutline.java | 41 -- .../utility/outliner/LineOutline.java | 65 --- .../foundation/utility/outliner/Outline.java | 246 --------- .../foundation/utility/outliner/Outliner.java | 185 ------- .../worldWrappers/DummyStatusListener.java | 23 - .../PlacementSimulationServerWorld.java | 62 --- .../utility/worldWrappers/RayTraceWorld.java | 47 -- .../worldWrappers/WrappedClientWorld.java | 140 ----- .../worldWrappers/WrappedServerWorld.java | 120 ----- .../utility/worldWrappers/WrappedWorld.java | 267 ---------- .../utility/worldWrappers/package-info.java | 6 - .../foundation/virtualWorld/VirtualChunk.java | 241 +++++++++ .../virtualWorld/VirtualChunkSection.java | 42 ++ .../virtualWorld/VirtualChunkSource.java | 64 +++ .../VirtualLevelEntityGetter.java} | 16 +- .../virtualWorld/VirtualRenderWorld.java | 492 ++++++++++++++++++ .../effortlessbuilding/create/license.txt | 12 - .../gui/DiamondRandomizerBagScreen.java | 2 +- .../gui/GoldenRandomizerBagScreen.java | 2 +- .../gui/RandomizerBagScreen.java | 2 +- .../gui/buildmode/PlayerSettingsGui.java | 54 +- .../gui/buildmode/RadialMenu.java | 41 +- .../gui/buildmodifier/ArrayEntry.java | 2 +- .../gui/buildmodifier/MirrorEntry.java | 2 +- .../gui/buildmodifier/ModifiersScreen.java | 2 +- .../buildmodifier/ModifiersScreenList.java | 15 +- .../gui/buildmodifier/RadialMirrorEntry.java | 2 +- .../gui/elements/GuiCheckBoxFixed.java | 2 +- .../gui/elements/GuiIconButton.java | 4 +- .../gui/elements/GuiScrollPane.java | 87 ++-- .../gui/elements/MiniButton.java | 2 +- .../gui/elements/SlotGui.java | 27 +- .../item/AbstractRandomizerBagItem.java | 13 +- .../item/PowerLevelItem.java | 5 +- .../item/ReachUpgrade1Item.java | 5 +- .../item/ReachUpgrade2Item.java | 7 +- .../item/ReachUpgrade3Item.java | 7 +- .../item/SingleItemLootModifier.java | 7 +- .../network/PacketHandler.java | 42 +- .../message/IsQuickReplacingPacket.java | 32 +- .../message/IsUsingBuildModePacket.java | 32 +- .../message/ModifierSettingsPacket.java | 41 +- .../network/message/PerformRedoPacket.java | 23 +- .../network/message/PerformUndoPacket.java | 23 +- .../network/message/PowerLevelPacket.java | 31 +- .../message/ServerBreakBlocksPacket.java | 23 +- .../message/ServerPlaceBlocksPacket.java | 23 +- .../network/message/TranslatedLogPacket.java | 65 +-- .../effortlessbuilding/proxy/ClientProxy.java | 7 +- .../effortlessbuilding/proxy/IProxy.java | 7 - .../effortlessbuilding/proxy/ServerProxy.java | 4 +- .../render/BlockPreviews.java | 31 +- .../render/ModifierRenderer.java | 52 +- .../render/RenderHandler.java | 17 +- .../systems/BuildSettings.java | 4 +- .../systems/BuilderChain.java | 4 +- .../systems/ServerBlockPlacer.java | 10 +- .../effortlessbuilding/systems/UndoRedo.java | 20 +- .../utilities/BlockPlacerHelper.java | 9 +- .../utilities/BlockUtilities.java | 6 +- .../utilities/InventoryHelper.java | 4 +- .../utilities/SurvivalHelper.java | 2 +- .../utilities/UndoRedoBlockSet.java | 45 -- .../{mods.toml => neoforge.mods.toml} | 18 +- .../diamond_randomizer_bag.json | 3 +- .../golden_randomizer_bag.json | 3 +- .../{recipes => recipe}/randomizer_bag.json | 3 +- .../{recipes => recipe}/reach_upgrade1.json | 3 +- .../{recipes => recipe}/reach_upgrade2.json | 3 +- .../{recipes => recipe}/reach_upgrade3.json | 3 +- src/main/resources/pack.mcmeta | 2 +- 203 files changed, 2149 insertions(+), 8008 deletions(-) delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/CreateClientTest.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/ModFilePackResources.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTSpriteShiftEntry.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTType.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/ConnectedTextureBehaviour.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/SpriteShiftEntry.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ConfirmationScreen.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ILightingSettings.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/TickableGuiEventListener.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/UIRenderHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/ClearMenuPacket.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemSubmitPacket.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/BoxElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/CombinedStencilElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/DelegatedStencilElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/GuiGameElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/RenderElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/ScreenElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/StencilElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/TextStencilElement.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/BoxWidget.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/ElementWidget.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/ISyncPersistentData.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/SimplePacketBase.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BakedModelRenderHelper.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BlockEntityRenderHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/CachedBufferer.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ForcedDiffuseState.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ShadowRenderHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBuffer.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBufferCache.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperRenderTypeBuffer.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/render/TileEntityRenderHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AngleHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AnimationTickHolder.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BBHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockFace.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Color.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ColorHandlers.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Couple.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CreateRegistry.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DyeHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DynamicComponent.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FilesHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FontHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IntAttached.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Iterate.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangBuilder.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangNumberFormat.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTProcessors.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pair.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pointing.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/RegisteredObjects.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/UniqueLinkedList.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VecHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldAttached.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldHelper.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/Force.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/LerpedFloat.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/PhysicalFloat.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/AABBOutline.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/BlockClusterOutline.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/ChasingAABBOutline.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/LineOutline.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outline.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outliner.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/DummyStatusListener.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/PlacementSimulationServerWorld.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/RayTraceWorld.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedClientWorld.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedServerWorld.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedWorld.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/package-info.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunk.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSection.java create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSource.java rename src/main/java/nl/requios/effortlessbuilding/create/foundation/{utility/worldWrappers/DummyLevelEntityGetter.java => virtualWorld/VirtualLevelEntityGetter.java} (50%) create mode 100644 src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualRenderWorld.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/create/license.txt delete mode 100644 src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java delete mode 100644 src/main/java/nl/requios/effortlessbuilding/utilities/UndoRedoBlockSet.java rename src/main/resources/META-INF/{mods.toml => neoforge.mods.toml} (79%) rename src/main/resources/data/effortlessbuilding/{recipes => recipe}/diamond_randomizer_bag.json (81%) rename src/main/resources/data/effortlessbuilding/{recipes => recipe}/golden_randomizer_bag.json (81%) rename src/main/resources/data/effortlessbuilding/{recipes => recipe}/randomizer_bag.json (79%) rename src/main/resources/data/effortlessbuilding/{recipes => recipe}/reach_upgrade1.json (80%) rename src/main/resources/data/effortlessbuilding/{recipes => recipe}/reach_upgrade2.json (80%) rename src/main/resources/data/effortlessbuilding/{recipes => recipe}/reach_upgrade3.json (83%) diff --git a/build.gradle b/build.gradle index 67ed01f..f436c92 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { jarJar.enable() -boolean flywheelInWorkspace = findProject(':Flywheel') != null +boolean ponderInWorkspace = findProject(':Ponder') != null ext.buildNumber = System.getenv('BUILD_NUMBER') @@ -19,7 +19,7 @@ base { archivesName = "effortlessbuilding-${artifact_minecraft_version}" } -java.toolchain.languageVersion = JavaLanguageVersion.of(17) +java.toolchain.languageVersion = JavaLanguageVersion.of(21) println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + ' (' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) @@ -47,9 +47,9 @@ runs { // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. systemProperty 'neoforge.enabledGameTestNamespaces', "effortlessbuilding" - if (flywheelInWorkspace) { + if (ponderInWorkspace) { dependencies { - runtime project(':Flywheel') + runtime project(':Ponder') } } } @@ -74,6 +74,11 @@ repositories { name = 'tterrag maven' url = 'https://maven.tterrag.com' } + maven { + // Ponder, Flywheel + url = "https://maven.createmod.net" + } + maven { url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven" } // NeoForge config api port, needed by ponder exclusiveContent { forRepository { maven { @@ -101,15 +106,24 @@ repositories { dependencies { implementation "net.neoforged:neoforge:${neo_version}" - jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") { - version { prefer "0.6.10" } + jarJar("dev.engine-room.flywheel:flywheel-neoforge-${flywheel_minecraft_version}:${flywheel_version}") { + version { + strictly "[1.0.0-9,2.0)" + } } - if (flywheelInWorkspace) { - implementation project(':Flywheel') + compileOnly("dev.engine-room.flywheel:flywheel-neoforge-api-${flywheel_minecraft_version}:${flywheel_version}") + runtimeOnly("dev.engine-room.flywheel:flywheel-neoforge-${flywheel_minecraft_version}:${flywheel_version}") + runtimeOnly("dev.engine-room.vanillin:vanillin-neoforge-${flywheel_minecraft_version}:${vanillin_version}") + + if (ponderInWorkspace) { + implementation(project(":ponder:Common")) + implementation(project(":ponder:NeoForge")) } else { - implementation "com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}" + implementation("net.createmod.ponder:Ponder-NeoForge-${minecraft_version}:${ponder_version}") } + + jarJar("net.createmod.ponder:Ponder-NeoForge-${minecraft_version}:${ponder_version}") } sourceSets.main.resources { @@ -120,6 +134,14 @@ tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation } +// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior. +idea { + module { + downloadSources = true + downloadJavadoc = true + } +} + compileJava { options.compilerArgs = ['-Xdiags:verbose'] } diff --git a/gradle.properties b/gradle.properties index 9781bc5..fe817f2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,15 +4,18 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false mod_version = 3.5 -artifact_minecraft_version = 1.20.4 +artifact_minecraft_version = 1.21.1 -minecraft_version = 1.20.4 -neo_version = 20.4.232 -neogradle.subsystems.parchment.minecraftVersion = 1.20.4 -neogradle.subsystems.parchment.mappingsVersion = 2024.02.25 +minecraft_version = 1.21.1 +neo_version = 21.1.127 +neogradle.subsystems.parchment.minecraftVersion = 1.21.1 +neogradle.subsystems.parchment.mappingsVersion = 2024.11.17 +neogradle.subsystems.conventions.runs.create-default-run-per-type = false -neogradle_version = 7.0.107 +neogradle_version = 7.0.181 cursegradle_version = 1.4.0 -flywheel_minecraft_version = 1.20.4 -flywheel_version = 0.6.10 \ No newline at end of file +flywheel_minecraft_version = 1.21.1 +flywheel_version = 1.0.0-9 +vanillin_version = 1.0.0-beta-9 +ponder_version = 1.0.39 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79e29d3e0ab67b14947c167a862655af9b..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch literal 43583 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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 GZ~q4|mN%#X literal 62076 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 509c4a2..e2847c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cb..f5feea6 100644 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -83,7 +85,9 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +134,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +205,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/java/nl/requios/effortlessbuilding/AllGuiTextures.java b/src/main/java/nl/requios/effortlessbuilding/AllGuiTextures.java index 62240df..83a50ca 100644 --- a/src/main/java/nl/requios/effortlessbuilding/AllGuiTextures.java +++ b/src/main/java/nl/requios/effortlessbuilding/AllGuiTextures.java @@ -1,13 +1,13 @@ package nl.requios.effortlessbuilding; import com.mojang.blaze3d.systems.RenderSystem; +import net.createmod.catnip.gui.UIRenderHelper; +import net.createmod.catnip.gui.element.ScreenElement; +import net.createmod.catnip.theme.Color; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.resources.ResourceLocation; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; -import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper; -import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; public enum AllGuiTextures implements ScreenElement { ARRAY_ENTRY("modifiers", 226, 64), @@ -35,7 +35,7 @@ public enum AllGuiTextures implements ScreenElement { } private AllGuiTextures(String namespace, String location, int startX, int startY, int width, int height) { - this.location = new ResourceLocation(namespace, "textures/gui/" + location + ".png"); + this.location = ResourceLocation.fromNamespaceAndPath(namespace, "textures/gui/" + location + ".png"); this.width = width; this.height = height; this.startX = startX; diff --git a/src/main/java/nl/requios/effortlessbuilding/AllIcons.java b/src/main/java/nl/requios/effortlessbuilding/AllIcons.java index e5b9548..55aa9d1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/AllIcons.java +++ b/src/main/java/nl/requios/effortlessbuilding/AllIcons.java @@ -2,6 +2,9 @@ package nl.requios.effortlessbuilding; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.createmod.catnip.gui.element.DelegatedStencilElement; +import net.createmod.catnip.gui.element.ScreenElement; +import net.createmod.catnip.theme.Color; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; @@ -10,15 +13,11 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; -import nl.requios.effortlessbuilding.create.Create; -import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement; -import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; import org.joml.Matrix4f; public class AllIcons implements ScreenElement { - public static final ResourceLocation ICON_ATLAS = Create.asResource("textures/gui/icons.png"); + public static final ResourceLocation ICON_ATLAS = EffortlessBuilding.asResource("textures/gui/icons.png"); public static final int ICON_ATLAS_SIZE = 256; private static int x = 0, y = -1; private int iconX; @@ -101,7 +100,6 @@ public class AllIcons implements ScreenElement { } @OnlyIn(Dist.CLIENT) - @Override public void render(GuiGraphics guiGraphics, int x, int y) { guiGraphics.blit(ICON_ATLAS, x, y, 0, iconX, iconY, 16, 16, 256, 256); } @@ -131,11 +129,10 @@ public class AllIcons implements ScreenElement { @OnlyIn(Dist.CLIENT) private void vertex(VertexConsumer builder, Matrix4f matrix, Vec3 vec, Color rgb, float u, float v, int light) { - builder.vertex(matrix, (float) vec.x, (float) vec.y, (float) vec.z) - .color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255) - .uv(u, v) - .uv2(light) - .endVertex(); + builder.addVertex(matrix, (float) vec.x, (float) vec.y, (float) vec.z) + .setColor(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255) + .setUv(u, v) + .setLight(light); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/nl/requios/effortlessbuilding/ClientConfig.java b/src/main/java/nl/requios/effortlessbuilding/ClientConfig.java index a33efcc..5d06071 100644 --- a/src/main/java/nl/requios/effortlessbuilding/ClientConfig.java +++ b/src/main/java/nl/requios/effortlessbuilding/ClientConfig.java @@ -2,7 +2,9 @@ package nl.requios.effortlessbuilding; import net.neoforged.neoforge.common.ModConfigSpec; -import static net.neoforged.neoforge.common.ModConfigSpec.*; +import static net.neoforged.neoforge.common.ModConfigSpec.BooleanValue; +import static net.neoforged.neoforge.common.ModConfigSpec.Builder; +import static net.neoforged.neoforge.common.ModConfigSpec.IntValue; public class ClientConfig { diff --git a/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java b/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java index 32121a0..6ae8aa5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java @@ -7,17 +7,17 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.entity.player.Player; import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.InputEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.neoforge.client.event.ScreenEvent; import net.neoforged.neoforge.client.settings.KeyConflictContext; import net.neoforged.neoforge.client.settings.KeyModifier; -import net.neoforged.neoforge.event.TickEvent; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod.EventBusSubscriber; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmode.BuildModeEnum; import nl.requios.effortlessbuilding.buildmode.ModeOptions; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.gui.buildmodifier.ModifiersScreen; @@ -55,31 +55,31 @@ public class ClientEvents { // @SubscribeEvent // public static void registerShaders(RegisterShadersEvent event) throws IOException { // event.registerShader(new ShaderInstance(event.getResourceManager(), -// new ResourceLocation(EffortlessBuilding.MODID, "dissolve"), +// EffortlessBuilding.modLoc("dissolve"), // DefaultVertexFormat.BLOCK), // shaderInstance -> BuildRenderTypes.dissolveShaderInstance = shaderInstance); // } } @SubscribeEvent - public static void onClientTick(TickEvent.ClientTickEvent event) { + public static void onClientTickPre(ClientTickEvent.Pre event) { if (!isGameActive()) return; - if (event.phase == TickEvent.Phase.START) { + EffortlessBuildingClient.BUILDER_CHAIN.onTick(); - EffortlessBuildingClient.BUILDER_CHAIN.onTick(); + onMouseInput(); - onMouseInput(); + EffortlessBuildingClient.BLOCK_PREVIEWS.onTick(); + } - EffortlessBuildingClient.BLOCK_PREVIEWS.onTick(); + @SubscribeEvent + public static void onClientTickPost(ClientTickEvent.Post event) { + if (!isGameActive()) return; - } else if (event.phase == TickEvent.Phase.END) { - Screen gui = Minecraft.getInstance().screen; - if (gui == null || !gui.isPauseScreen()) { - ticksInGame++; - } + Screen gui = Minecraft.getInstance().screen; + if (gui == null || !gui.isPauseScreen()) { + ticksInGame++; } - } private static void onMouseInput() { diff --git a/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java b/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java index 9bdef2f..dc9224f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java +++ b/src/main/java/nl/requios/effortlessbuilding/CommonConfig.java @@ -2,7 +2,8 @@ package nl.requios.effortlessbuilding; import net.neoforged.neoforge.common.ModConfigSpec; -import static net.neoforged.neoforge.common.ModConfigSpec.*; +import static net.neoforged.neoforge.common.ModConfigSpec.Builder; +import static net.neoforged.neoforge.common.ModConfigSpec.IntValue; public class CommonConfig { diff --git a/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java b/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java index dc590f4..9b7a7a9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java @@ -7,13 +7,12 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.LogicalSide; -import net.neoforged.fml.common.Mod.EventBusSubscriber; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.common.util.FakePlayer; import net.neoforged.neoforge.event.RegisterCommandsEvent; -import net.neoforged.neoforge.event.TickEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.level.BlockEvent; +import net.neoforged.neoforge.event.tick.LevelTickEvent; import nl.requios.effortlessbuilding.attachment.PowerLevel; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.network.message.ModifierSettingsPacket; @@ -37,10 +36,10 @@ public class CommonEvents { } @SubscribeEvent - public static void onTick(TickEvent.LevelTickEvent event) { - if (event.phase != TickEvent.Phase.START) return; - if (event.side == LogicalSide.CLIENT) return; - if (event.level.dimension() != Level.OVERWORLD) return; + public static void onTick(LevelTickEvent.Pre event) { + Level level = event.getLevel(); + if (level.isClientSide) return; + if (!level.dimension().equals(Level.OVERWORLD)) return; EffortlessBuilding.SERVER_BLOCK_PLACER.tick(); } diff --git a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java index 9febc22..3b39601 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java +++ b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java @@ -1,22 +1,25 @@ package nl.requios.effortlessbuilding; -import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.ItemStack; +import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.DistExecutor; -import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfig; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.fml.loading.FMLEnvironment; import net.neoforged.neoforge.attachment.AttachmentType; +import net.neoforged.neoforge.client.gui.ConfigurationScreen; +import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.loot.IGlobalLootModifier; import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; @@ -39,7 +42,6 @@ import nl.requios.effortlessbuilding.item.ReachUpgrade3Item; import nl.requios.effortlessbuilding.item.SingleItemLootModifier; import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.proxy.ClientProxy; -import nl.requios.effortlessbuilding.proxy.IProxy; import nl.requios.effortlessbuilding.proxy.ServerProxy; import nl.requios.effortlessbuilding.systems.ItemUsageTracker; import nl.requios.effortlessbuilding.systems.ServerBlockPlacer; @@ -57,7 +59,6 @@ public class EffortlessBuilding { public static final Logger logger = LogManager.getLogger(); public static EffortlessBuilding instance; - public static IProxy proxy = DistExecutor.unsafeRunForDist(() -> ClientProxy::new, () -> ServerProxy::new); public static final ServerBlockPlacer SERVER_BLOCK_PLACER = new ServerBlockPlacer(); public static final UndoRedo UNDO_REDO = new UndoRedo(); @@ -66,7 +67,7 @@ public class EffortlessBuilding { //Registration private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); private static final DeferredRegister> CONTAINERS = DeferredRegister.create(BuiltInRegistries.MENU, EffortlessBuilding.MODID); - private static final DeferredRegister> LOOT_MODIFIERS = DeferredRegister.create(NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, EffortlessBuilding.MODID); + private static final DeferredRegister> LOOT_MODIFIERS = DeferredRegister.create(NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, EffortlessBuilding.MODID); private static final DeferredRegister> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.Keys.ATTACHMENT_TYPES, EffortlessBuilding.MODID); public static final DeferredItem RANDOMIZER_BAG_ITEM = ITEMS.register("randomizer_bag", RandomizerBagItem::new); @@ -83,24 +84,19 @@ public class EffortlessBuilding { public static final Supplier> GOLDEN_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("golden_randomizer_bag", () -> registerContainer(GoldenRandomizerBagContainer::new)); public static final Supplier> DIAMOND_RANDOMIZER_BAG_CONTAINER = CONTAINERS.register("diamond_randomizer_bag", () -> registerContainer(DiamondRandomizerBagContainer::new)); - public static final Supplier> SINGLE_ITEM_LOOT_MODIFIER = EffortlessBuilding.LOOT_MODIFIERS.register("single_item_loot_modifier", SingleItemLootModifier.CODEC); + public static final Supplier> SINGLE_ITEM_LOOT_MODIFIER = EffortlessBuilding.LOOT_MODIFIERS.register("single_item_loot_modifier", SingleItemLootModifier.CODEC); public static final Supplier> POWER_LEVEL = ATTACHMENT_TYPES.register("power_level", () -> AttachmentType.serializable(PowerLevel::new).build()); - public EffortlessBuilding(IEventBus modEventBus) { + public EffortlessBuilding(IEventBus modEventBus, ModContainer container, Dist dist) { instance = this; - ModLoadingContext modLoadingContext = ModLoadingContext.get(); IEventBus forgeEventBus = NeoForge.EVENT_BUS; modEventBus.addListener(EffortlessBuilding::setup); modEventBus.addListener(EffortlessBuilding::addTabContents); modEventBus.addListener(PacketHandler::setupPackets); - if (FMLEnvironment.dist.isClient()) { - EffortlessBuildingClient.onConstructorClient(modEventBus, forgeEventBus); - } - ITEMS.register(modEventBus); CONTAINERS.register(modEventBus); @@ -108,9 +104,13 @@ public class EffortlessBuilding { ATTACHMENT_TYPES.register(modEventBus); //Register config - modLoadingContext.registerConfig(ModConfig.Type.COMMON, CommonConfig.spec); - modLoadingContext.registerConfig(ModConfig.Type.CLIENT, ClientConfig.spec); - modLoadingContext.registerConfig(ModConfig.Type.SERVER, ServerConfig.spec); + container.registerConfig(ModConfig.Type.COMMON, CommonConfig.spec); + container.registerConfig(ModConfig.Type.SERVER, ServerConfig.spec); + if (dist.isClient()) { + container.registerConfig(ModConfig.Type.CLIENT, ClientConfig.spec); + container.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new); + EffortlessBuildingClient.onConstructorClient(modEventBus, forgeEventBus); + } } public static void setup(final FMLCommonSetupEvent event) { @@ -143,11 +143,18 @@ public class EffortlessBuilding { //Log with translation supported, call either on client or server (which then sends a message) public static void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar) { - proxy.logTranslate(player, prefix, translationKey, suffix, actionBar); + if (FMLEnvironment.dist.isClient()) { + ClientProxy.logTranslate(player, prefix, translationKey, suffix, actionBar); + } else { + ServerProxy.logTranslate(player, prefix, translationKey, suffix, actionBar); + } } public static void logError(String msg) { logger.error(msg); } + public static ResourceLocation asResource(String path) { + return ResourceLocation.fromNamespaceAndPath(MODID, path); + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuildingClient.java b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuildingClient.java index 4c96f6b..f0cb8f8 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuildingClient.java +++ b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuildingClient.java @@ -1,15 +1,17 @@ package nl.requios.effortlessbuilding; -import net.minecraft.client.gui.screens.MenuScreens; import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.gui.DiamondRandomizerBagScreen; import nl.requios.effortlessbuilding.gui.GoldenRandomizerBagScreen; import nl.requios.effortlessbuilding.gui.RandomizerBagScreen; import nl.requios.effortlessbuilding.render.BlockPreviews; -import nl.requios.effortlessbuilding.systems.*; +import nl.requios.effortlessbuilding.systems.BuildSettings; +import nl.requios.effortlessbuilding.systems.BuilderChain; +import nl.requios.effortlessbuilding.systems.BuilderFilter; +import nl.requios.effortlessbuilding.systems.ItemUsageTracker; public class EffortlessBuildingClient { @@ -22,12 +24,12 @@ public class EffortlessBuildingClient { public static final ItemUsageTracker ITEM_USAGE_TRACKER = new ItemUsageTracker(); public static void onConstructorClient(IEventBus modEventBus, IEventBus forgeEventBus) { - modEventBus.addListener(EffortlessBuildingClient::clientSetup); + modEventBus.addListener(EffortlessBuildingClient::registerMenuScreens); } - public static void clientSetup(final FMLClientSetupEvent event) { - MenuScreens.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new); - MenuScreens.register(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), GoldenRandomizerBagScreen::new); - MenuScreens.register(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), DiamondRandomizerBagScreen::new); + public static void registerMenuScreens(final RegisterMenuScreensEvent event) { + event.register(EffortlessBuilding.RANDOMIZER_BAG_CONTAINER.get(), RandomizerBagScreen::new); + event.register(EffortlessBuilding.GOLDEN_RANDOMIZER_BAG_CONTAINER.get(), GoldenRandomizerBagScreen::new); + event.register(EffortlessBuilding.DIAMOND_RANDOMIZER_BAG_CONTAINER.get(), DiamondRandomizerBagScreen::new); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/ServerConfig.java b/src/main/java/nl/requios/effortlessbuilding/ServerConfig.java index 60e2f5b..dcc3d1d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/ServerConfig.java +++ b/src/main/java/nl/requios/effortlessbuilding/ServerConfig.java @@ -5,7 +5,10 @@ import net.neoforged.neoforge.common.ModConfigSpec; import java.util.Arrays; import java.util.List; -import static net.neoforged.neoforge.common.ModConfigSpec.*; +import static net.neoforged.neoforge.common.ModConfigSpec.BooleanValue; +import static net.neoforged.neoforge.common.ModConfigSpec.Builder; +import static net.neoforged.neoforge.common.ModConfigSpec.ConfigValue; +import static net.neoforged.neoforge.common.ModConfigSpec.IntValue; public class ServerConfig { private static final Builder builder = new Builder(); diff --git a/src/main/java/nl/requios/effortlessbuilding/attachment/AttachmentHandler.java b/src/main/java/nl/requios/effortlessbuilding/attachment/AttachmentHandler.java index 0149db5..214c001 100644 --- a/src/main/java/nl/requios/effortlessbuilding/attachment/AttachmentHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/attachment/AttachmentHandler.java @@ -8,7 +8,7 @@ import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.network.message.PowerLevelPacket; public class AttachmentHandler { - public static final ResourceLocation POWER_LEVEL_CAP = new ResourceLocation(EffortlessBuilding.MODID, "power_level"); + public static final ResourceLocation POWER_LEVEL_CAP = EffortlessBuilding.asResource("power_level"); public static void syncToClient(Player player) { PowerLevel powerLevel = player.getData(EffortlessBuilding.POWER_LEVEL); diff --git a/src/main/java/nl/requios/effortlessbuilding/attachment/PowerLevel.java b/src/main/java/nl/requios/effortlessbuilding/attachment/PowerLevel.java index 43ce881..e3ea422 100644 --- a/src/main/java/nl/requios/effortlessbuilding/attachment/PowerLevel.java +++ b/src/main/java/nl/requios/effortlessbuilding/attachment/PowerLevel.java @@ -1,5 +1,6 @@ package nl.requios.effortlessbuilding.attachment; +import net.minecraft.core.HolderLookup.Provider; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; import net.neoforged.neoforge.common.util.INBTSerializable; @@ -93,13 +94,13 @@ public class PowerLevel implements INBTSerializable { return player.getAbilities().instabuild; } - public CompoundTag serializeNBT() { + public CompoundTag serializeNBT(Provider provider) { CompoundTag tag = new CompoundTag(); tag.putInt("powerLevel", getPowerLevel()); return tag; } - - public void deserializeNBT(CompoundTag nbt) { + + public void deserializeNBT(Provider provider, CompoundTag nbt) { setPowerLevel(nbt.getInt("powerLevel")); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeCategoryEnum.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeCategoryEnum.java index 5215938..11ee02a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeCategoryEnum.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeCategoryEnum.java @@ -1,6 +1,6 @@ package nl.requios.effortlessbuilding.buildmode; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; +import net.createmod.catnip.theme.Color; public enum BuildModeCategoryEnum { BASIC(new Color(0f, .5f, 1f, .8f)), diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeEnum.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeEnum.java index 0dabaf5..67425d5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeEnum.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModeEnum.java @@ -1,7 +1,18 @@ package nl.requios.effortlessbuilding.buildmode; import nl.requios.effortlessbuilding.AllIcons; -import nl.requios.effortlessbuilding.buildmode.buildmodes.*; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Circle; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Cube; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Cylinder; +import nl.requios.effortlessbuilding.buildmode.buildmodes.DiagonalLine; +import nl.requios.effortlessbuilding.buildmode.buildmodes.DiagonalWall; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Disabled; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Floor; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Line; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Single; +import nl.requios.effortlessbuilding.buildmode.buildmodes.SlopeFloor; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Sphere; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Wall; public enum BuildModeEnum { DISABLED("normal", new Disabled(), BuildModeCategoryEnum.BASIC, AllIcons.I_DISABLE), diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java index b729302..f7f6994 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java @@ -30,7 +30,7 @@ public class BuildModes { public void setBuildMode(BuildModeEnum buildMode) { this.buildMode = buildMode; - PacketDistributor.SERVER.noArg().send(new IsUsingBuildModePacket(this.buildMode != BuildModeEnum.DISABLED)); + PacketDistributor.sendToServer(new IsUsingBuildModePacket(this.buildMode != BuildModeEnum.DISABLED)); EffortlessBuilding.log(Minecraft.getInstance().player, I18n.get(buildMode.getNameKey()), true); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java index 6461c59..63f20b2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java @@ -69,8 +69,8 @@ public class ModeOptions { if (action == null) return; switch (action) { - case UNDO -> PacketDistributor.SERVER.noArg().send(new PerformUndoPacket()); - case REDO -> PacketDistributor.SERVER.noArg().send(new PerformRedoPacket()); + case UNDO -> PacketDistributor.sendToServer(new PerformUndoPacket()); + case REDO -> PacketDistributor.sendToServer(new PerformRedoPacket()); case OPEN_MODIFIER_SETTINGS -> ClientEvents.openModifierSettings(); case OPEN_PLAYER_SETTINGS -> ClientEvents.openPlayerSettings(); case PREVIOUS_BUILD_MODE -> EffortlessBuildingClient.BUILD_MODES.activatePreviousBuildMode(); diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Circle.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Circle.java index 9f72642..d04086e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Circle.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Circle.java @@ -1,8 +1,8 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cube.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cube.java index 3a2fb1c..82cb9b1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cube.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cube.java @@ -1,7 +1,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cylinder.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cylinder.java index 1c303bf..8547777 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cylinder.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cylinder.java @@ -1,7 +1,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import java.util.ArrayList; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalLine.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalLine.java index 8951b4a..c35b523 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalLine.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalLine.java @@ -1,7 +1,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalWall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalWall.java index c2d039a..146ca3d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalWall.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalWall.java @@ -1,7 +1,7 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; import java.util.ArrayList; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Floor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Floor.java index 4bac2b9..096b318 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Floor.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Floor.java @@ -1,12 +1,12 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Line.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Line.java index 0dd4772..150634d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Line.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Line.java @@ -3,9 +3,9 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/SlopeFloor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/SlopeFloor.java index 867fbde..8fb92e2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/SlopeFloor.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/SlopeFloor.java @@ -1,10 +1,10 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Sphere.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Sphere.java index 0625b18..1150c94 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Sphere.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Sphere.java @@ -1,8 +1,8 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Wall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Wall.java index f41c2a4..d820e8f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Wall.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Wall.java @@ -1,12 +1,12 @@ package nl.requios.effortlessbuilding.buildmode.buildmodes; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java index 5d77b18..a7d27f7 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java @@ -1,9 +1,9 @@ package nl.requios.effortlessbuilding.buildmodifier; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockSet; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java index 2119be2..c0e1601 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java @@ -1,12 +1,12 @@ package nl.requios.effortlessbuilding.buildmodifier; +import net.createmod.catnip.nbt.NBTHelper; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.world.entity.player.Player; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.neoforge.network.PacketDistributor; -import nl.requios.effortlessbuilding.create.foundation.utility.NBTHelper; import nl.requios.effortlessbuilding.network.message.ModifierSettingsPacket; import nl.requios.effortlessbuilding.utilities.BlockSet; @@ -96,7 +96,7 @@ public class BuildModifiers { } public void save() { - PacketDistributor.SERVER.noArg().send(new ModifierSettingsPacket(serializeNBT())); + PacketDistributor.sendToServer(new ModifierSettingsPacket(serializeNBT())); //Save locally as well? // var listTag = NBTHelper.writeCompoundList(modifierSettingsList, BaseModifier::serializeNBT); diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java index 64f92bf..72b5aea 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java @@ -1,11 +1,10 @@ package nl.requios.effortlessbuilding.buildmodifier; import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; -import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; - import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockSet; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java index 48eff2c..098ee5b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java @@ -1,13 +1,13 @@ package nl.requios.effortlessbuilding.buildmodifier; import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.utilities.BlockEntry; diff --git a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java index 52ea80f..704e93b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java @@ -1,11 +1,11 @@ package nl.requios.effortlessbuilding.compatibility; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.items.IItemHandler; import nl.requios.effortlessbuilding.create.foundation.item.ItemHelper; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/AllSpecialTextures.java b/src/main/java/nl/requios/effortlessbuilding/create/AllSpecialTextures.java index 0808f30..7db4cd4 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/AllSpecialTextures.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/AllSpecialTextures.java @@ -1,9 +1,10 @@ package nl.requios.effortlessbuilding.create; import com.mojang.blaze3d.systems.RenderSystem; +import net.createmod.catnip.render.BindableTexture; import net.minecraft.resources.ResourceLocation; -public enum AllSpecialTextures { +public enum AllSpecialTextures implements BindableTexture { BLANK("blank.png"), CHECKERED("checkerboard.png"), @@ -18,7 +19,7 @@ public enum AllSpecialTextures { public static final String ASSET_PATH = "textures/special/"; private ResourceLocation location; - private AllSpecialTextures(String filename) { + AllSpecialTextures(String filename) { location = Create.asResource(ASSET_PATH + filename); } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/Create.java b/src/main/java/nl/requios/effortlessbuilding/create/Create.java index 70d417c..66e92bd 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/Create.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/Create.java @@ -11,6 +11,6 @@ public class Create { public static final Logger LOGGER = LogUtils.getLogger(); public static ResourceLocation asResource(String path) { - return new ResourceLocation(EffortlessBuilding.MODID, path); + return ResourceLocation.fromNamespaceAndPath(EffortlessBuilding.MODID, path); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/CreateClient.java b/src/main/java/nl/requios/effortlessbuilding/create/CreateClient.java index a983c25..7093c24 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/CreateClient.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/CreateClient.java @@ -1,12 +1,10 @@ package nl.requios.effortlessbuilding.create; -import nl.requios.effortlessbuilding.create.foundation.render.SuperByteBufferCache; +import net.createmod.catnip.render.SuperByteBufferCache; import nl.requios.effortlessbuilding.create.foundation.utility.ghost.GhostBlocks; -import nl.requios.effortlessbuilding.create.foundation.utility.outliner.Outliner; public class CreateClient { public static final SuperByteBufferCache BUFFER_CACHE = new SuperByteBufferCache(); - public static final Outliner OUTLINER = new Outliner(); public static final GhostBlocks GHOST_BLOCKS = new GhostBlocks(); public static void invalidateRenderers() { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/CreateClientTest.java b/src/main/java/nl/requios/effortlessbuilding/create/CreateClientTest.java deleted file mode 100644 index 7ed4b71..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/CreateClientTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package nl.requios.effortlessbuilding.create; - -//@Mod.EventBusSubscriber(Dist.CLIENT) -public class CreateClientTest { - -// @SubscribeEvent -// public static void onTick(TickEvent.ClientTickEvent event) { -// CreateClient.GHOST_BLOCKS.showGhostState(1, Blocks.SPRUCE_LOG.defaultBlockState()) -// .at(0, 120, 0) -// .breathingAlpha(); -// CreateClient.GHOST_BLOCKS.showGhostState(2, Blocks.SPRUCE_LOG.defaultBlockState()) -// .at(1, 120, 0) -// .breathingAlpha(); -// -// CreateClient.OUTLINER.showAABB(1, new AABB(0, 0, 0, 10, 2, 6) -// .move(10, 120, 0)) -// .withFaceTexture(AllSpecialTextures.CHECKERED) -// .colored(new Color(0.11f, 0.49f, 0.7f, 1f)) -//// .colored(0xbfbfbf) -// .disableNormals() -// .lineWidth(1 / 32f); -// } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/events/ClientEvents.java b/src/main/java/nl/requios/effortlessbuilding/create/events/ClientEvents.java index d39b8a3..84e3aac 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/events/ClientEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/events/ClientEvents.java @@ -2,46 +2,46 @@ package nl.requios.effortlessbuilding.create.events; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +import net.createmod.catnip.animation.AnimationTickHolder; +import net.createmod.catnip.levelWrappers.WrappedClientLevel; +import net.createmod.catnip.render.DefaultSuperRenderTypeBuffer; +import net.createmod.catnip.render.SuperRenderTypeBuffer; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; import net.neoforged.neoforge.client.event.ViewportEvent; -import net.neoforged.neoforge.event.TickEvent; -import net.neoforged.neoforge.event.TickEvent.ClientTickEvent; import net.neoforged.neoforge.event.level.LevelEvent; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; import nl.requios.effortlessbuilding.create.Create; import nl.requios.effortlessbuilding.create.CreateClient; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; -import nl.requios.effortlessbuilding.create.foundation.utility.AnimationTickHolder; import nl.requios.effortlessbuilding.create.foundation.utility.CameraAngleAnimationService; -import nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers.WrappedClientWorld; -@Mod.EventBusSubscriber(Dist.CLIENT) +@EventBusSubscriber(Dist.CLIENT) public class ClientEvents { private static final String ITEM_PREFIX = "item." + Create.ID; private static final String BLOCK_PREFIX = "block." + Create.ID; @SubscribeEvent - public static void onTick(ClientTickEvent event) { - if (!isGameActive() || event.phase != TickEvent.Phase.END) return; + public static void onTick(ClientTickEvent.Post event) { + if (!isGameActive()) return; AnimationTickHolder.tick(); CreateClient.GHOST_BLOCKS.tickGhosts(); - CreateClient.OUTLINER.tickOutlines(); +// CreateClient.OUTLINER.tickOutlines(); CameraAngleAnimationService.tick(); } @SubscribeEvent public static void onLoadWorld(LevelEvent.Load event) { LevelAccessor world = event.getLevel(); - if (world.isClientSide() && world instanceof ClientLevel && !(world instanceof WrappedClientWorld)) { + if (world.isClientSide() && world instanceof ClientLevel && !(world instanceof WrappedClientLevel)) { CreateClient.invalidateRenderers(); AnimationTickHolder.reset(); } @@ -67,11 +67,11 @@ public class ClientEvents { PoseStack ms = event.getPoseStack(); ms.pushPose(); ms.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z()); - SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance(); + SuperRenderTypeBuffer buffer = DefaultSuperRenderTypeBuffer.getInstance(); CreateClient.GHOST_BLOCKS.renderAll(ms, buffer); - CreateClient.OUTLINER.renderOutlines(ms, buffer, pt); +// CreateClient.OUTLINER.renderOutlines(ms, buffer, pt); buffer.draw(); RenderSystem.enableCull(); diff --git a/src/main/java/nl/requios/effortlessbuilding/create/events/CommonEvents.java b/src/main/java/nl/requios/effortlessbuilding/create/events/CommonEvents.java index 92a4b5c..ab8caab 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/events/CommonEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/events/CommonEvents.java @@ -1,12 +1,12 @@ package nl.requios.effortlessbuilding.create.events; +import net.createmod.catnip.data.WorldAttached; import net.minecraft.world.level.LevelAccessor; -import net.neoforged.neoforge.event.level.LevelEvent; import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; -import nl.requios.effortlessbuilding.create.foundation.utility.WorldAttached; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.level.LevelEvent; -@Mod.EventBusSubscriber +@EventBusSubscriber public class CommonEvents { @SubscribeEvent diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/ClientResourceReloadListener.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/ClientResourceReloadListener.java index f3ec8d0..3d54695 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/ClientResourceReloadListener.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/ClientResourceReloadListener.java @@ -1,6 +1,6 @@ package nl.requios.effortlessbuilding.create.foundation; -import nl.requios.effortlessbuilding.create.foundation.utility.LangNumberFormat; +import net.createmod.catnip.lang.LangNumberFormat; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManagerReloadListener; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/ModFilePackResources.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/ModFilePackResources.java deleted file mode 100644 index 30dc183..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/ModFilePackResources.java +++ /dev/null @@ -1,25 +0,0 @@ -//package nl.requios.effortlessbuilding.create.foundation; -// -//import net.neoforged.neoforgespi.locating.IModFile; -//import net.neoforged.neoforge.resource.PathPackResources; -// -//import java.nio.file.Path; -// -//public class ModFilePackResources extends PathPackResources { -// protected final IModFile modFile; -// protected final String sourcePath; -// -// public ModFilePackResources(String name, IModFile modFile, String sourcePath) { -// super(name, true, modFile.findResource(sourcePath)); -// this.modFile = modFile; -// this.sourcePath = sourcePath; -// } -// -// @Override -// protected Path resolve(String... paths) { -// String[] allPaths = new String[paths.length + 1]; -// allPaths[0] = sourcePath; -// System.arraycopy(paths, 0, allPaths, 1, paths.length); -// return modFile.findResource(allPaths); -// } -//} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTSpriteShiftEntry.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTSpriteShiftEntry.java new file mode 100644 index 0000000..5453cea --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTSpriteShiftEntry.java @@ -0,0 +1,29 @@ +package nl.requios.effortlessbuilding.create.foundation.block.render; + +import net.createmod.catnip.render.SpriteShiftEntry; + +public class CTSpriteShiftEntry extends SpriteShiftEntry { + + protected final CTType type; + + public CTSpriteShiftEntry(CTType type) { + this.type = type; + } + + public CTType getType() { + return type; + } + + public float getTargetU(float localU, int index) { + float uOffset = (index % type.getSheetSize()); + return getTarget().getU( + (getUnInterpolatedU(getOriginal(), localU) + uOffset) / ((float) type.getSheetSize())); + } + + public float getTargetV(float localV, int index) { + float vOffset = (index / type.getSheetSize()); + return getTarget().getV( + (getUnInterpolatedV(getOriginal(), localV) + vOffset) / ((float) type.getSheetSize())); + } + +} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTType.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTType.java new file mode 100644 index 0000000..23be7dd --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/CTType.java @@ -0,0 +1,15 @@ +package nl.requios.effortlessbuilding.create.foundation.block.render; + +import net.minecraft.resources.ResourceLocation; +import nl.requios.effortlessbuilding.create.foundation.block.render.ConnectedTextureBehaviour.CTContext; +import nl.requios.effortlessbuilding.create.foundation.block.render.ConnectedTextureBehaviour.ContextRequirement; + +public interface CTType { + ResourceLocation getId(); + + int getSheetSize(); + + ContextRequirement getContextRequirement(); + + int getTextureIndex(CTContext context); +} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/ConnectedTextureBehaviour.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/ConnectedTextureBehaviour.java new file mode 100644 index 0000000..ac6f712 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/ConnectedTextureBehaviour.java @@ -0,0 +1,283 @@ +package nl.requios.effortlessbuilding.create.foundation.block.render; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.core.Direction.AxisDirection; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class ConnectedTextureBehaviour { + + @Nullable + public CTSpriteShiftEntry getShift(BlockState state, RandomSource rand, Direction direction, + @NotNull TextureAtlasSprite sprite) { + return getShift(state, direction, sprite); + } + + @Nullable + public abstract CTSpriteShiftEntry getShift(BlockState state, Direction direction, + @NotNull TextureAtlasSprite sprite); + + // TODO: allow more than one data type per state/face? + @Nullable + public abstract CTType getDataType(BlockAndTintGetter world, BlockPos pos, BlockState state, Direction direction); + + public boolean buildContextForOccludedDirections() { + return false; + } + + protected boolean isBeingBlocked(BlockState state, BlockAndTintGetter reader, BlockPos pos, BlockPos otherPos, + Direction face) { + BlockPos blockingPos = otherPos.relative(face); + BlockState blockState = reader.getBlockState(pos); + BlockState blockingState = reader.getBlockState(blockingPos); + + if (!Block.isFaceFull(blockingState.getShape(reader, blockingPos), face.getOpposite())) + return false; + if (face.getAxis() + .choose(pos.getX(), pos.getY(), pos.getZ()) != face.getAxis() + .choose(otherPos.getX(), otherPos.getY(), otherPos.getZ())) + return false; + + return connectsTo(state, + getCTBlockState(reader, blockState, face.getOpposite(), pos.relative(face), blockingPos), reader, pos, + blockingPos, face); + } + + public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos, + BlockPos otherPos, Direction face, Direction primaryOffset, Direction secondaryOffset) { + return connectsTo(state, other, reader, pos, otherPos, face); + } + + public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos, + BlockPos otherPos, Direction face) { + return !isBeingBlocked(state, reader, pos, otherPos, face) && state.getBlock() == other.getBlock(); + } + + private boolean testConnection(BlockAndTintGetter reader, BlockPos currentPos, BlockState connectiveCurrentState, + Direction textureSide, final Direction horizontal, final Direction vertical, int sh, int sv) { + BlockState trueCurrentState = reader.getBlockState(currentPos); + BlockPos targetPos = currentPos.relative(horizontal, sh) + .relative(vertical, sv); + BlockState connectiveTargetState = + getCTBlockState(reader, trueCurrentState, textureSide, currentPos, targetPos); + return connectsTo(connectiveCurrentState, connectiveTargetState, reader, currentPos, targetPos, textureSide, + sh == 0 ? null : sh == -1 ? horizontal.getOpposite() : horizontal, + sv == 0 ? null : sv == -1 ? vertical.getOpposite() : vertical); + } + + public BlockState getCTBlockState(BlockAndTintGetter reader, BlockState reference, Direction face, BlockPos fromPos, + BlockPos toPos) { + BlockState blockState = reader.getBlockState(toPos); + return blockState.getAppearance(reader, toPos, face, reference, fromPos); + } + + protected boolean reverseUVs(BlockState state, Direction face) { + return false; + } + + protected boolean reverseUVsHorizontally(BlockState state, Direction face) { + return reverseUVs(state, face); + } + + protected boolean reverseUVsVertically(BlockState state, Direction face) { + return reverseUVs(state, face); + } + + protected Direction getUpDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) { + Axis axis = face.getAxis(); + return axis.isHorizontal() ? Direction.UP : Direction.NORTH; + } + + protected Direction getRightDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) { + Axis axis = face.getAxis(); + return axis == Axis.X ? Direction.SOUTH : Direction.WEST; + } + + public CTContext buildContext(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face, + ContextRequirement requirement) { + boolean positive = face.getAxisDirection() == AxisDirection.POSITIVE; + Direction h = getRightDirection(reader, pos, state, face); + Direction v = getUpDirection(reader, pos, state, face); + h = positive ? h.getOpposite() : h; + if (face == Direction.DOWN) { + v = v.getOpposite(); + h = h.getOpposite(); + } + + final Direction horizontal = h; + final Direction vertical = v; + + boolean flipH = reverseUVsHorizontally(state, face); + boolean flipV = reverseUVsVertically(state, face); + int sh = flipH ? -1 : 1; + int sv = flipV ? -1 : 1; + + CTContext context = new CTContext(); + + if (requirement.up) { + context.up = testConnection(reader, pos, state, face, horizontal, vertical, 0, sv); + } + if (requirement.down) { + context.down = testConnection(reader, pos, state, face, horizontal, vertical, 0, -sv); + } + if (requirement.left) { + context.left = testConnection(reader, pos, state, face, horizontal, vertical, -sh, 0); + } + if (requirement.right) { + context.right = testConnection(reader, pos, state, face, horizontal, vertical, sh, 0); + } + + if (requirement.topLeft) { + context.topLeft = + context.up && context.left && testConnection(reader, pos, state, face, horizontal, vertical, -sh, sv); + } + if (requirement.topRight) { + context.topRight = + context.up && context.right && testConnection(reader, pos, state, face, horizontal, vertical, sh, sv); + } + if (requirement.bottomLeft) { + context.bottomLeft = context.down && context.left + && testConnection(reader, pos, state, face, horizontal, vertical, -sh, -sv); + } + if (requirement.bottomRight) { + context.bottomRight = context.down && context.right + && testConnection(reader, pos, state, face, horizontal, vertical, sh, -sv); + } + + return context; + } + + public static class CTContext { + public static final CTContext EMPTY = new CTContext(); + + public boolean up, down, left, right; + public boolean topLeft, topRight, bottomLeft, bottomRight; + } + + public static class ContextRequirement { + public final boolean up, down, left, right; + public final boolean topLeft, topRight, bottomLeft, bottomRight; + + public ContextRequirement(boolean up, boolean down, boolean left, boolean right, boolean topLeft, + boolean topRight, boolean bottomLeft, boolean bottomRight) { + this.up = up; + this.down = down; + this.left = left; + this.right = right; + this.topLeft = topLeft; + this.topRight = topRight; + this.bottomLeft = bottomLeft; + this.bottomRight = bottomRight; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private boolean up, down, left, right; + private boolean topLeft, topRight, bottomLeft, bottomRight; + + public Builder up() { + up = true; + return this; + } + + public Builder down() { + down = true; + return this; + } + + public Builder left() { + left = true; + return this; + } + + public Builder right() { + right = true; + return this; + } + + public Builder topLeft() { + topLeft = true; + return this; + } + + public Builder topRight() { + topRight = true; + return this; + } + + public Builder bottomLeft() { + bottomLeft = true; + return this; + } + + public Builder bottomRight() { + bottomRight = true; + return this; + } + + public Builder horizontal() { + left(); + right(); + return this; + } + + public Builder vertical() { + up(); + down(); + return this; + } + + public Builder axisAligned() { + horizontal(); + vertical(); + return this; + } + + public Builder corners() { + topLeft(); + topRight(); + bottomLeft(); + bottomRight(); + return this; + } + + public Builder all() { + axisAligned(); + corners(); + return this; + } + + public ContextRequirement build() { + return new ContextRequirement(up, down, left, right, topLeft, topRight, bottomLeft, bottomRight); + } + } + } + + public static abstract class Base extends ConnectedTextureBehaviour { + @Override + @Nullable + public abstract CTSpriteShiftEntry getShift(BlockState state, Direction direction, + @Nullable TextureAtlasSprite sprite); + + @Override + @Nullable + public CTType getDataType(BlockAndTintGetter world, BlockPos pos, BlockState state, Direction direction) { + CTSpriteShiftEntry shift = getShift(state, direction, null); + if (shift == null) { + return null; + } + return shift.getType(); + } + } + +} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/SpriteShiftEntry.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/SpriteShiftEntry.java deleted file mode 100644 index 334dafe..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/block/render/SpriteShiftEntry.java +++ /dev/null @@ -1,49 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.block.render; - -import com.jozufozu.flywheel.core.StitchedSprite; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.resources.ResourceLocation; - -public class SpriteShiftEntry { - protected StitchedSprite original; - protected StitchedSprite target; - - public void set(ResourceLocation originalTextureLocation, ResourceLocation targetTextureLocation) { - original = new StitchedSprite(originalTextureLocation); - target = new StitchedSprite(targetTextureLocation); - } - - public ResourceLocation getOriginalResourceLocation() { - return original.getLocation(); - } - - public ResourceLocation getTargetResourceLocation() { - return target.getLocation(); - } - - public TextureAtlasSprite getOriginal() { - return original.get(); - } - - public TextureAtlasSprite getTarget() { - return target.get(); - } - - public float getTargetU(float localU) { - return getTarget().getU(getUnInterpolatedU(getOriginal(), localU)); - } - - public float getTargetV(float localV) { - return getTarget().getV(getUnInterpolatedV(getOriginal(), localV)); - } - - public static float getUnInterpolatedU(TextureAtlasSprite sprite, float u) { - float f = sprite.getU1() - sprite.getU0(); - return (u - sprite.getU0()) / f * 16.0F; - } - - public static float getUnInterpolatedV(TextureAtlasSprite sprite, float v) { - float f = sprite.getV1() - sprite.getV0(); - return (v - sprite.getV0()) / f * 16.0F; - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AbstractSimiScreen.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AbstractSimiScreen.java index aba40fa..bc22ee9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AbstractSimiScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AbstractSimiScreen.java @@ -2,6 +2,8 @@ package nl.requios.effortlessbuilding.create.foundation.gui; import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.vertex.PoseStack; +import net.createmod.catnip.animation.AnimationTickHolder; +import net.createmod.catnip.gui.TickableGuiEventListener; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.EditBox; @@ -106,7 +108,7 @@ public abstract class AbstractSimiScreen extends Screen { @Override public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - partialTicks = minecraft.getFrameTime(); + partialTicks = AnimationTickHolder.getPartialTicksUI(); PoseStack ms = graphics.pose(); ms.pushPose(); diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllGuiTextures.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllGuiTextures.java index 76b7180..4032cf4 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllGuiTextures.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllGuiTextures.java @@ -1,13 +1,14 @@ package nl.requios.effortlessbuilding.create.foundation.gui; import com.mojang.blaze3d.systems.RenderSystem; +import net.createmod.catnip.gui.UIRenderHelper; +import net.createmod.catnip.gui.element.ScreenElement; +import net.createmod.catnip.theme.Color; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.resources.ResourceLocation; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.create.Create; -import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; public enum AllGuiTextures implements ScreenElement { @@ -60,7 +61,7 @@ public enum AllGuiTextures implements ScreenElement { } private AllGuiTextures(String namespace, String location, int startX, int startY, int width, int height) { - this.location = new ResourceLocation(namespace, "textures/gui/" + location + ".png"); + this.location = ResourceLocation.fromNamespaceAndPath(namespace, "textures/gui/" + location + ".png"); this.width = width; this.height = height; this.startX = startX; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllIcons.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllIcons.java index 7977644..384615a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllIcons.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/AllIcons.java @@ -3,6 +3,9 @@ package nl.requios.effortlessbuilding.create.foundation.gui; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.createmod.catnip.gui.element.DelegatedStencilElement; +import net.createmod.catnip.gui.element.ScreenElement; +import net.createmod.catnip.theme.Color; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; @@ -12,9 +15,6 @@ import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.create.Create; -import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement; -import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; import org.joml.Matrix4f; public class AllIcons implements ScreenElement { @@ -202,11 +202,10 @@ public class AllIcons implements ScreenElement { @OnlyIn(Dist.CLIENT) private void vertex(VertexConsumer builder, Matrix4f matrix, Vec3 vec, Color rgb, float u, float v, int light) { - builder.vertex(matrix, (float) vec.x, (float) vec.y, (float) vec.z) - .color(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255) - .uv(u, v) - .uv2(light) - .endVertex(); + builder.addVertex(matrix, (float) vec.x, (float) vec.y, (float) vec.z) + .setColor(rgb.getRed(), rgb.getGreen(), rgb.getBlue(), 255) + .setUv(u, v) + .setLight(light); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ConfirmationScreen.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ConfirmationScreen.java deleted file mode 100644 index bc48353..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ConfirmationScreen.java +++ /dev/null @@ -1,229 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.FormattedText; -import net.minecraft.network.chat.Style; -import nl.requios.effortlessbuilding.create.foundation.gui.element.BoxElement; -import nl.requios.effortlessbuilding.create.foundation.gui.element.TextStencilElement; -import nl.requios.effortlessbuilding.create.foundation.gui.widget.BoxWidget; -import org.lwjgl.opengl.GL30; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public class ConfirmationScreen extends AbstractSimiScreen { - - private Screen source; - private Consumer action = _success -> { - }; - private List text = new ArrayList<>(); - private boolean centered = false; - private int x; - private int y; - private int textWidth; - private int textHeight; - private boolean tristate; - - private BoxWidget confirm; - private BoxWidget confirmDontSave; - private BoxWidget cancel; - private BoxElement textBackground; - - public enum Response { - Confirm, ConfirmDontSave, Cancel - } - - /* - * Removes text lines from the back of the list - * */ - public ConfirmationScreen removeTextLines(int amount) { - if (amount > text.size()) - return clearText(); - - text.subList(text.size() - amount, text.size()).clear(); - return this; - } - - public ConfirmationScreen clearText() { - this.text.clear(); - return this; - } - - public ConfirmationScreen addText(FormattedText text) { - this.text.add(text); - return this; - } - - public ConfirmationScreen withText(FormattedText text) { - return clearText().addText(text); - } - - public ConfirmationScreen at(int x, int y) { - this.x = Math.max(x, 0); - this.y = Math.max(y, 0); - this.centered = false; - return this; - } - - public ConfirmationScreen centered() { - this.centered = true; - return this; - } - - public ConfirmationScreen withAction(Consumer action) { - this.action = r -> action.accept(r == Response.Confirm); - return this; - } - - public ConfirmationScreen withThreeActions(Consumer action) { - this.action = action; - this.tristate = true; - return this; - } - - public void open(@Nonnull Screen source) { - this.source = source; - Minecraft client = source.getMinecraft(); - this.init(client, client.getWindow().getGuiScaledWidth(), client.getWindow().getGuiScaledHeight()); - this.minecraft.screen = this; - } - - @Override - public void tick() { - super.tick(); - source.tick(); - } - - @Override - protected void init() { - super.init(); - - ArrayList copy = new ArrayList<>(text); - text.clear(); - copy.forEach(t -> text.addAll(font.getSplitter().splitLines(t, 300, Style.EMPTY))); - - textHeight = text.size() * (font.lineHeight + 1) + 4; - textWidth = 300; - - if (centered) { - x = width/2 - textWidth/2 - 2; - y = height/2 - textHeight/2 - 16; - } else { - x = Math.max(0, x - textWidth / 2); - y = Math.max(0, y -= textHeight); - } - - if (x + textWidth > width) { - x = width - textWidth; - } - - if (y + textHeight + 30 > height) { - y = height - textHeight - 30; - } - - int buttonX = x + textWidth / 2 - 6 - (int) (70 * (tristate ? 1.5f : 1)); - - TextStencilElement confirmText = - new TextStencilElement(font, tristate ? "Save" : "Confirm").centered(true, true); - confirm = new BoxWidget(buttonX, y + textHeight + 6, 70, 16).withCallback(() -> accept(Response.Confirm)); - confirm.showingElement(confirmText.withElementRenderer(BoxWidget.gradientFactory.apply(confirm))); - addRenderableWidget(confirm); - - buttonX += 12 + 70; - - if (tristate) { - TextStencilElement confirmDontSaveText = - new TextStencilElement(font, "Don't Save").centered(true, true); - confirmDontSave = - new BoxWidget(buttonX, y + textHeight + 6, 70, 16).withCallback(() -> accept(Response.ConfirmDontSave)); - confirmDontSave.showingElement( - confirmDontSaveText.withElementRenderer(BoxWidget.gradientFactory.apply(confirmDontSave))); - addRenderableWidget(confirmDontSave); - buttonX += 12 + 70; - } - - TextStencilElement cancelText = new TextStencilElement(font, "Cancel").centered(true, true); - cancel = new BoxWidget(buttonX, y + textHeight + 6, 70, 16) - .withCallback(() -> accept(Response.Cancel)); - cancel.showingElement(cancelText.withElementRenderer(BoxWidget.gradientFactory.apply(cancel))); - addRenderableWidget(cancel); - - textBackground = new BoxElement() - .gradientBorder(Theme.p(Theme.Key.BUTTON_DISABLE)) - .withBounds(width + 10, textHeight + 35) - .at(-5, y - 5); - - if (text.size() == 1) - x = (width - font.width(text.get(0))) / 2; - } - - @Override - public void onClose() { - accept(Response.Cancel); - } - - private void accept(Response success) { - minecraft.screen = source; - action.accept(success); - } - - @Override - protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - textBackground.render(graphics); - int offset = font.lineHeight + 1; - int lineY = y - offset; - - PoseStack ms = graphics.pose(); - ms.pushPose(); - ms.translate(0, 0, 200); - - for (FormattedText line : text) { - lineY += offset; - if (line == null) - continue; - graphics.drawString(font, line.getString(), x, lineY, 0xeaeaea, false); - } - - ms.popPose(); - } - - @Override - protected void renderWindowBackground(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - endFrame(); - - source.render(graphics, 0, 0, 10); // zero mouse coords to prevent further tooltips - - prepareFrame(); - - graphics.fillGradient(0, 0, this.width, this.height, 0x70101010, 0x80101010); - } - - - @Override - protected void prepareFrame() { - UIRenderHelper.swapAndBlitColor(minecraft.getMainRenderTarget(), UIRenderHelper.framebuffer); - RenderSystem.clear(GL30.GL_STENCIL_BUFFER_BIT | GL30.GL_DEPTH_BUFFER_BIT, Minecraft.ON_OSX); - } - - @Override - protected void endFrame() { - UIRenderHelper.swapAndBlitColor(UIRenderHelper.framebuffer, minecraft.getMainRenderTarget()); - } - - @Override - public void resize(@Nonnull Minecraft client, int width, int height) { - super.resize(client, width, height); - source.resize(client, width, height); - } - - @Override - public boolean isPauseScreen() { - return true; - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/CustomLightingSettings.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/CustomLightingSettings.java index 5e1bfad..70fb8b9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/CustomLightingSettings.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/CustomLightingSettings.java @@ -1,10 +1,10 @@ package nl.requios.effortlessbuilding.create.foundation.gui; -import org.joml.Matrix4f; -import org.joml.Vector3f; - import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.math.Axis; +import net.createmod.catnip.gui.ILightingSettings; +import org.joml.Matrix4f; +import org.joml.Vector3f; public class CustomLightingSettings implements ILightingSettings { @@ -39,7 +39,7 @@ public class CustomLightingSettings implements ILightingSettings { @Override public void applyLighting() { - RenderSystem.setupLevelDiffuseLighting(light1, light2, lightMatrix); + RenderSystem.setShaderLights(light1, light2); } public static Builder builder() { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ILightingSettings.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ILightingSettings.java deleted file mode 100644 index a349850..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/ILightingSettings.java +++ /dev/null @@ -1,12 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui; - -import com.mojang.blaze3d.platform.Lighting; - -public interface ILightingSettings { - - void applyLighting(); - - static final ILightingSettings DEFAULT_3D = () -> Lighting.setupFor3DItems(); - static final ILightingSettings DEFAULT_FLAT = () -> Lighting.setupForFlatItems(); - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/RemovedGuiUtils.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/RemovedGuiUtils.java index ab268f8..0cead2f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/RemovedGuiUtils.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/RemovedGuiUtils.java @@ -1,18 +1,7 @@ package nl.requios.effortlessbuilding.create.foundation.gui; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nonnull; - -import net.neoforged.neoforge.client.event.RenderTooltipEvent; -import net.neoforged.neoforge.common.NeoForge; -import org.joml.Matrix4f; - import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; - import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; @@ -21,7 +10,14 @@ import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.Style; import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.client.ClientHooks; +import net.neoforged.neoforge.client.event.RenderTooltipEvent; import net.neoforged.neoforge.client.extensions.IGuiGraphicsExtension; +import net.neoforged.neoforge.common.NeoForge; +import org.joml.Matrix4f; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.List; public class RemovedGuiUtils { @Nonnull @@ -179,8 +175,7 @@ public class RemovedGuiUtils { graphics.fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 2, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, zLevel, borderColorEnd, borderColorEnd); - MultiBufferSource.BufferSource renderType = MultiBufferSource.immediate(Tesselator.getInstance() - .getBuilder()); + MultiBufferSource.BufferSource renderType = graphics.bufferSource(); pStack.translate(0.0D, 0.0D, zLevel); for (int lineNumber = 0; lineNumber < list.size(); ++lineNumber) { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/Theme.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/Theme.java index 38d1ae6..163450c 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/Theme.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/Theme.java @@ -1,11 +1,16 @@ package nl.requios.effortlessbuilding.create.foundation.gui; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; -import nl.requios.effortlessbuilding.create.foundation.utility.Couple; +import net.createmod.catnip.data.Couple; +import net.createmod.catnip.theme.Color; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; public class Theme { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/TickableGuiEventListener.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/TickableGuiEventListener.java deleted file mode 100644 index e4bed7d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/TickableGuiEventListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui; - -import net.minecraft.client.gui.components.events.GuiEventListener; - -public interface TickableGuiEventListener extends GuiEventListener { - void tick(); -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/UIRenderHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/UIRenderHelper.java deleted file mode 100644 index 091d5c4..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/UIRenderHelper.java +++ /dev/null @@ -1,327 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui; - -import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.platform.GlConst; -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.math.Axis; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; -import nl.requios.effortlessbuilding.create.foundation.utility.Couple; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; - -public class UIRenderHelper { - - /** - * An FBO that has a stencil buffer for use wherever stencil are necessary. Forcing the main FBO to have a stencil - * buffer will cause GL error spam when using fabulous graphics. - */ - public static CustomRenderTarget framebuffer; - - public static void init() { - RenderSystem.recordRenderCall(() -> { - Window mainWindow = Minecraft.getInstance().getWindow(); - framebuffer = CustomRenderTarget.create(mainWindow); - }); - } - - public static void updateWindowSize(Window mainWindow) { - if (framebuffer != null) - framebuffer.resize(mainWindow.getWidth(), mainWindow.getHeight(), Minecraft.ON_OSX); - } - - public static void drawFramebuffer(float alpha) { - framebuffer.renderWithAlpha(alpha); - } - - /** - * Switch from src to dst, after copying the contents of src to dst. - */ - public static void swapAndBlitColor(RenderTarget src, RenderTarget dst) { - GlStateManager._glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, src.frameBufferId); - GlStateManager._glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, dst.frameBufferId); - GlStateManager._glBlitFrameBuffer(0, 0, src.viewWidth, src.viewHeight, 0, 0, dst.viewWidth, dst.viewHeight, GL30.GL_COLOR_BUFFER_BIT, GL20.GL_LINEAR); - - GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, dst.frameBufferId); - } - - public static void streak(GuiGraphics graphics, float angle, int x, int y, int breadth, int length) { - streak(graphics, angle, x, y, breadth, length, Theme.i(Theme.Key.STREAK)); - } - // angle in degrees; 0° -> fading to the right - // x and y specify the middle point of the starting edge - // breadth is the total width of the streak - - public static void streak(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, int color) { - int a1 = 0xa0 << 24; - int a2 = 0x80 << 24; - int a3 = 0x10 << 24; - int a4 = 0x00 << 24; - - color &= 0x00FFFFFF; - int c1 = a1 | color; - int c2 = a2 | color; - int c3 = a3 | color; - int c4 = a4 | color; - - PoseStack ms = graphics.pose(); - ms.pushPose(); - ms.translate(x, y, 0); - ms.mulPose(Axis.ZP.rotationDegrees(angle - 90)); - - streak(graphics, breadth / 2, length, c1, c2, c3, c4); - - ms.popPose(); - } - - public static void streak(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, Color c) { - Color color = c.copy().setImmutable(); - int c1 = color.scaleAlpha(0.625f).getRGB(); - int c2 = color.scaleAlpha(0.5f).getRGB(); - int c3 = color.scaleAlpha(0.0625f).getRGB(); - int c4 = color.scaleAlpha(0f).getRGB(); - - PoseStack ms = graphics.pose(); - ms.pushPose(); - ms.translate(x, y, 0); - ms.mulPose(Axis.ZP.rotationDegrees(angle - 90)); - - streak(graphics, breadth / 2, length, c1, c2, c3, c4); - - ms.popPose(); - } - - private static void streak(GuiGraphics graphics, int width, int height, int c1, int c2, int c3, int c4) { - double split1 = .5; - double split2 = .75; - graphics.fillGradient(-width, 0, width, (int) (split1 * height), 0, c1, c2); - graphics.fillGradient(-width, (int) (split1 * height), width, (int) (split2 * height), 0, c2, c3); - graphics.fillGradient(-width, (int) (split2 * height), width, height, 0, c3, c4); - } - - /** - * @see #angledGradient(GuiGraphics, float, int, int, int, int, int, Color, Color) - */ - public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, Couple c) { - angledGradient(graphics, angle, x, y, 0, breadth, length, c); - } - - /** - * @see #angledGradient(GuiGraphics, float, int, int, int, int, int, Color, Color) - */ - public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int z, int breadth, int length, Couple c) { - angledGradient(graphics, angle, x, y, z, breadth, length, c.getFirst(), c.getSecond()); - } - - /** - * @see #angledGradient(GuiGraphics, float, int, int, int, int, int, Color, Color) - */ - public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int breadth, int length, Color color1, Color color2) { - angledGradient(graphics, angle, x, y, 0, breadth, length, color1, color2); - } - - /** - * x and y specify the middle point of the starting edge - * - * @param angle the angle of the gradient in degrees; 0° means from left to right - * @param color1 the color at the starting edge - * @param color2 the color at the ending edge - * @param breadth the total width of the gradient - */ - public static void angledGradient(GuiGraphics graphics, float angle, int x, int y, int z, int breadth, int length, Color color1, Color color2) { - PoseStack ms = graphics.pose(); - ms.pushPose(); - ms.translate(x, y, z); - ms.mulPose(Axis.ZP.rotationDegrees(angle - 90)); - - int w = breadth / 2; - graphics.fillGradient(-w, 0, w, length, 0, color1.getRGB(), color2.getRGB()); - - ms.popPose(); - } - - public static void breadcrumbArrow(GuiGraphics graphics, int x, int y, int z, int width, int height, int indent, Couple colors) {breadcrumbArrow(graphics, x, y, z, width, height, indent, colors.getFirst(), colors.getSecond());} - - // draws a wide chevron-style breadcrumb arrow pointing left - public static void breadcrumbArrow(GuiGraphics graphics, int x, int y, int z, int width, int height, int indent, Color startColor, Color endColor) { - PoseStack matrixStack = graphics.pose(); - matrixStack.pushPose(); - matrixStack.translate(x - indent, y, z); - - breadcrumbArrow(graphics, width, height, indent, startColor, endColor); - - matrixStack.popPose(); - } - - private static void breadcrumbArrow(GuiGraphics graphics, int width, int height, int indent, Color c1, Color c2) { - - /* - * 0,0 x1,y1 ********************* x4,y4 ***** x7,y7 - * **** **** - * **** **** - * x0,y0 x2,y2 x5,y5 - * **** **** - * **** **** - * x3,y3 ********************* x6,y6 ***** x8,y8 - * - */ - - float x0 = 0, y0 = height / 2f; - float x1 = indent, y1 = 0; - float x2 = indent, y2 = height / 2f; - float x3 = indent, y3 = height; - float x4 = width, y4 = 0; - float x5 = width, y5 = height / 2f; - float x6 = width, y6 = height; - float x7 = indent + width, y7 = 0; - float x8 = indent + width, y8 = height; - - indent = Math.abs(indent); - width = Math.abs(width); - Color fc1 = Color.mixColors(c1, c2, 0); - Color fc2 = Color.mixColors(c1, c2, (indent) / (width + 2f * indent)); - Color fc3 = Color.mixColors(c1, c2, (indent + width) / (width + 2f * indent)); - Color fc4 = Color.mixColors(c1, c2, 1); - -// RenderSystem.disableTexture(); - RenderSystem.enableBlend(); - RenderSystem.disableCull(); - RenderSystem.defaultBlendFunc(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); - - Tesselator tessellator = Tesselator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuilder(); - Matrix4f model = graphics.pose().last().pose(); - bufferbuilder.begin(VertexFormat.Mode.TRIANGLES, DefaultVertexFormat.POSITION_COLOR); - - bufferbuilder.vertex(model, x0, y0, 0).color(fc1.getRed(), fc1.getGreen(), fc1.getBlue(), fc1.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x1, y1, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x2, y2, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex(); - - bufferbuilder.vertex(model, x0, y0, 0).color(fc1.getRed(), fc1.getGreen(), fc1.getBlue(), fc1.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x2, y2, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x3, y3, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex(); - - bufferbuilder.vertex(model, x3, y3, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x1, y1, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x4, y4, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex(); - - bufferbuilder.vertex(model, x3, y3, 0).color(fc2.getRed(), fc2.getGreen(), fc2.getBlue(), fc2.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x4, y4, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x6, y6, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex(); - - bufferbuilder.vertex(model, x5, y5, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x4, y4, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x7, y7, 0).color(fc4.getRed(), fc4.getGreen(), fc4.getBlue(), fc4.getAlpha()).endVertex(); - - bufferbuilder.vertex(model, x6, y6, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x5, y5, 0).color(fc3.getRed(), fc3.getGreen(), fc3.getBlue(), fc3.getAlpha()).endVertex(); - bufferbuilder.vertex(model, x8, y8, 0).color(fc4.getRed(), fc4.getGreen(), fc4.getBlue(), fc4.getAlpha()).endVertex(); - - tessellator.end(); - RenderSystem.enableCull(); - RenderSystem.disableBlend(); -// RenderSystem.enableTexture(); - } - - //just like AbstractGui#drawTexture, but with a color at every vertex - public static void drawColoredTexture(GuiGraphics graphics, Color c, int x, int y, int tex_left, int tex_top, int width, int height) { - drawColoredTexture(graphics, c, x, y, 0, (float) tex_left, (float) tex_top, width, height, 256, 256); - } - - public static void drawColoredTexture(GuiGraphics graphics, Color c, int x, int y, int z, float tex_left, float tex_top, int width, int height, int sheet_width, int sheet_height) { - drawColoredTexture(graphics, c, x, x + width, y, y + height, z, width, height, tex_left, tex_top, sheet_width, sheet_height); - } - - public static void drawStretched(GuiGraphics graphics, int left, int top, int w, int h, int z, AllGuiTextures tex) { - tex.bind(); - drawTexturedQuad(graphics.pose().last() - .pose(), Color.WHITE, left, left + w, top, top + h, z, tex.startX / 256f, (tex.startX + tex.width) / 256f, - tex.startY / 256f, (tex.startY + tex.height) / 256f); - } - - public static void drawCropped(GuiGraphics graphics, int left, int top, int w, int h, int z, AllGuiTextures tex) { - tex.bind(); - drawTexturedQuad(graphics.pose().last() - .pose(), Color.WHITE, left, left + w, top, top + h, z, tex.startX / 256f, (tex.startX + w) / 256f, - tex.startY / 256f, (tex.startY + h) / 256f); - } - - private static void drawColoredTexture(GuiGraphics graphics, Color c, int left, int right, int top, int bot, int z, int tex_width, int tex_height, float tex_left, float tex_top, int sheet_width, int sheet_height) { - drawTexturedQuad(graphics.pose().last().pose(), c, left, right, top, bot, z, (tex_left + 0.0F) / (float) sheet_width, (tex_left + (float) tex_width) / (float) sheet_width, (tex_top + 0.0F) / (float) sheet_height, (tex_top + (float) tex_height) / (float) sheet_height); - } - - private static void drawTexturedQuad(Matrix4f m, Color c, int left, int right, int top, int bot, int z, float u1, float u2, float v1, float v2) { - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder bufferbuilder = tesselator.getBuilder(); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.setShader(GameRenderer::getPositionColorTexShader); - bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX); - bufferbuilder.vertex(m, (float) left , (float) bot, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u1, v2).endVertex(); - bufferbuilder.vertex(m, (float) right, (float) bot, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u2, v2).endVertex(); - bufferbuilder.vertex(m, (float) right, (float) top, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u2, v1).endVertex(); - bufferbuilder.vertex(m, (float) left , (float) top, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).uv(u1, v1).endVertex(); - tesselator.end(); - RenderSystem.disableBlend(); - } - - public static void flipForGuiRender(PoseStack poseStack) { - poseStack.mulPoseMatrix(new Matrix4f().scaling(1, -1, 1)); - } - - public static class CustomRenderTarget extends RenderTarget { - - public CustomRenderTarget(boolean useDepth) { - super(useDepth); - } - - public static CustomRenderTarget create(Window mainWindow) { - CustomRenderTarget framebuffer = new CustomRenderTarget(true); - framebuffer.resize(mainWindow.getWidth(), mainWindow.getHeight(), Minecraft.ON_OSX); - framebuffer.setClearColor(0, 0, 0, 0); - framebuffer.enableStencil(); - return framebuffer; - } - - public void renderWithAlpha(float alpha) { - Window window = Minecraft.getInstance().getWindow(); - - float vx = (float) window.getGuiScaledWidth(); - float vy = (float) window.getGuiScaledHeight(); - float tx = (float) viewWidth / (float) width; - float ty = (float) viewHeight / (float) height; - -// RenderSystem.enableTexture(); - RenderSystem.enableDepthTest(); - RenderSystem.setShader(() -> Minecraft.getInstance().gameRenderer.blitShader); - RenderSystem.getShader().setSampler("DiffuseSampler", colorTextureId); - - bindRead(); - - Tesselator tessellator = Tesselator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuilder(); - bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX); - - bufferbuilder.vertex(0, vy, 0).color(1, 1, 1, alpha).uv(0, 0).endVertex(); - bufferbuilder.vertex(vx, vy, 0).color(1, 1, 1, alpha).uv(tx, 0).endVertex(); - bufferbuilder.vertex(vx, 0, 0).color(1, 1, 1, alpha).uv(tx, ty).endVertex(); - bufferbuilder.vertex(0, 0, 0).color(1, 1, 1, alpha).uv(0, ty).endVertex(); - - tessellator.end(); - unbindRead(); - } - - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java index 166679e..85789b4 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java @@ -1,6 +1,8 @@ package nl.requios.effortlessbuilding.create.foundation.gui.container; import com.mojang.blaze3d.platform.InputConstants; +import net.createmod.catnip.animation.AnimationTickHolder; +import net.createmod.catnip.gui.TickableGuiEventListener; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.EditBox; @@ -15,7 +17,6 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.AbstractContainerMenu; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; -import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener; import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget; import javax.annotation.ParametersAreNonnullByDefault; @@ -92,7 +93,7 @@ public abstract class AbstractSimiContainerScreen { -// ServerPlayer player = context.getSender(); -// if (player == null) -// return; -// if (!(player.containerMenu instanceof IClearableMenu)) -// return; -// ((IClearableMenu) player.containerMenu).clearContents(); -// }); -// return true; -// } -// -//} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemMenu.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemMenu.java index 03c3063..d69711c 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemMenu.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemMenu.java @@ -7,7 +7,6 @@ import net.minecraft.world.inventory.ClickType; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; -import net.neoforged.neoforge.items.ItemHandlerHelper; import net.neoforged.neoforge.items.ItemStackHandler; public abstract class GhostItemMenu extends MenuBase implements IClearableMenu { @@ -88,7 +87,7 @@ public abstract class GhostItemMenu extends MenuBase implements IClearable ItemStack stackToInsert = playerInventory.getItem(index); for (int i = 0; i < ghostInventory.getSlots(); i++) { ItemStack stack = ghostInventory.getStackInSlot(i); - if (!allowRepeats() && ItemHandlerHelper.canItemStacksStack(stack, stackToInsert)) + if (!allowRepeats() && ItemStack.isSameItemSameComponents(stack, stackToInsert)) break; if (stack.isEmpty()) { ItemStack copy = stackToInsert.copy(); diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemSubmitPacket.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemSubmitPacket.java deleted file mode 100644 index bde9ee2..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/GhostItemSubmitPacket.java +++ /dev/null @@ -1,45 +0,0 @@ -//package nl.requios.effortlessbuilding.create.foundation.gui.container; -// -//import net.minecraft.network.FriendlyByteBuf; -//import net.minecraft.server.level.ServerPlayer; -//import net.minecraft.world.item.ItemStack; -//import net.neoforged.neoforge.network.NetworkEvent.Context; -//import nl.requios.effortlessbuilding.create.foundation.networking.SimplePacketBase; -// -//public class GhostItemSubmitPacket extends SimplePacketBase { -// -// private final ItemStack item; -// private final int slot; -// -// public GhostItemSubmitPacket(ItemStack item, int slot) { -// this.item = item; -// this.slot = slot; -// } -// -// public GhostItemSubmitPacket(FriendlyByteBuf buffer) { -// item = buffer.readItem(); -// slot = buffer.readInt(); -// } -// -// @Override -// public void write(FriendlyByteBuf buffer) { -// buffer.writeItem(item); -// buffer.writeInt(slot); -// } -// -// @Override -// public boolean handle(Context context) { -// context.enqueueWork(() -> { -// ServerPlayer player = context.getSender(); -// if (player == null) -// return; -// -// if (player.containerMenu instanceof GhostItemMenu menu) { -// menu.ghostInventory.setStackInSlot(slot, item); -// menu.getSlot(36 + slot).setChanged(); -// } -// }); -// return true; -// } -// -//} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/BoxElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/BoxElement.java deleted file mode 100644 index 93aac3d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/BoxElement.java +++ /dev/null @@ -1,158 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.blaze3d.vertex.VertexFormat; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; -import nl.requios.effortlessbuilding.create.foundation.utility.Couple; -import org.joml.Matrix4f; - -public class BoxElement extends RenderElement { - - protected Color background = new Color(0xff000000, true); - protected Color borderTop = new Color(0x40ffeedd, true); - protected Color borderBot = new Color(0x20ffeedd, true); - protected int borderOffset = 2; - - public T withBackground(Color color) { - this.background = color; - //noinspection unchecked - return (T) this; - } - - public T withBackground(int color) { - return withBackground(new Color(color, true)); - } - - public T flatBorder(Color color) { - this.borderTop = color; - this.borderBot = color; - //noinspection unchecked - return (T) this; - } - - public T flatBorder(int color) { - return flatBorder(new Color(color, true)); - } - - public T gradientBorder(Couple colors) { - this.borderTop = colors.getFirst(); - this.borderBot = colors.getSecond(); - //noinspection unchecked - return (T) this; - } - - public T gradientBorder(Color top, Color bot) { - this.borderTop = top; - this.borderBot = bot; - //noinspection unchecked - return (T) this; - } - - public T gradientBorder(int top, int bot) { - return gradientBorder(new Color(top, true), new Color(bot, true)); - } - - public T withBorderOffset(int offset) { - this.borderOffset = offset; - //noinspection unchecked - return (T) this; - } - - @Override - public void render(GuiGraphics graphics) { - renderBox(graphics.pose()); - } - - //total box width = 1 * 2 (outer border) + 1 * 2 (inner color border) + 2 * borderOffset + width - //defaults to 2 + 2 + 4 + 16 = 24px - //batch everything together to save a bunch of gl calls over ScreenUtils - protected void renderBox(PoseStack ms) { - /* - * _____________ - * _|_____________|_ - * | | ___________ | | - * | | | | | | | - * | | | | | | | - * | | |--* | | | | - * | | | h | | | - * | | | --w-+ | | | - * | | | | | | - * | | |_________| | | - * |_|_____________|_| - * |_____________| - * - * */ -// RenderSystem.disableTexture(); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); - - Matrix4f model = ms.last().pose(); - int f = borderOffset; - Color c1 = background.copy().scaleAlpha(alpha); - Color c2 = borderTop.copy().scaleAlpha(alpha); - Color c3 = borderBot.copy().scaleAlpha(alpha); - Tesselator tessellator = Tesselator.getInstance(); - BufferBuilder b = tessellator.getBuilder(); - - b.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - //outer top - b.vertex(model, x - f - 1 , y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - //outer left - b.vertex(model, x - f - 2 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x - f - 2 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - //outer bottom - b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - //outer right - b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 2 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 2 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - //inner background - also render behind the inner edges - b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex(); - tessellator.end(); - b.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - //inner top - includes corners - b.vertex(model, x - f - 1 , y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - //inner left - excludes corners - b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - b.vertex(model, x - f , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - b.vertex(model, x - f , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - //inner bottom - includes corners - b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - //inner right - excludes corners - b.vertex(model, x + f + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - b.vertex(model, x + f + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex(); - b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex(); - - tessellator.end(); - - RenderSystem.disableBlend(); -// RenderSystem.enableTexture(); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/CombinedStencilElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/CombinedStencilElement.java deleted file mode 100644 index 57315ce..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/CombinedStencilElement.java +++ /dev/null @@ -1,82 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import javax.annotation.Nonnull; - -import com.mojang.blaze3d.vertex.PoseStack; - -import net.minecraft.client.gui.GuiGraphics; - -public class CombinedStencilElement extends StencilElement { - - private StencilElement element1; - private StencilElement element2; - private ElementMode mode; - - private CombinedStencilElement() {} - - public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2) { - return of(element1, element2, ElementMode.FIRST); - } - - public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2, ElementMode mode) { - CombinedStencilElement e = new CombinedStencilElement(); - e.element1 = element1; - e.element2 = element2; - e.mode = mode; - return e; - } - - public T withFirst(StencilElement element) { - this.element1 = element; - //noinspection unchecked - return (T) this; - } - - public T withSecond(StencilElement element) { - this.element2 = element; - //noinspection unchecked - return (T) this; - } - - public T withMode(ElementMode mode) { - this.mode = mode; - //noinspection unchecked - return (T) this; - } - - @Override - protected void renderStencil(GuiGraphics graphics) { - PoseStack ms = graphics.pose(); - ms.pushPose(); - element1.transform(ms); - element1.withBounds(width, height); - element1.renderStencil(graphics); - ms.popPose(); - ms.pushPose(); - element2.transform(ms); - element2.withBounds(width, height); - element2.renderStencil(graphics); - ms.popPose(); - } - - @Override - protected void renderElement(GuiGraphics graphics) { - if (mode.rendersFirst()) - element1.withBounds(width, height).renderElement(graphics); - - if (mode.rendersSecond()) - element2.withBounds(width, height).renderElement(graphics); - } - - public enum ElementMode { - FIRST, SECOND, BOTH; - - boolean rendersFirst() { - return this == FIRST || this == BOTH; - } - - boolean rendersSecond() { - return this == SECOND || this == BOTH; - } - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/DelegatedStencilElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/DelegatedStencilElement.java deleted file mode 100644 index 2fecfa3..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/DelegatedStencilElement.java +++ /dev/null @@ -1,52 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import net.minecraft.client.gui.GuiGraphics; -import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; - -public class DelegatedStencilElement extends StencilElement { - - protected static final ElementRenderer EMPTY_RENDERER = (graphics, width, height, alpha) -> {}; - protected static final ElementRenderer DEFAULT_ELEMENT = (graphics, width, height, alpha) -> UIRenderHelper.angledGradient(graphics, 0, -3, 5, height+4, width+6, new Color(0xff_10dd10).scaleAlpha(alpha), new Color(0xff_1010dd).scaleAlpha(alpha)); - - protected ElementRenderer stencil; - protected ElementRenderer element; - - public DelegatedStencilElement() { - stencil = EMPTY_RENDERER; - element = DEFAULT_ELEMENT; - } - - public DelegatedStencilElement(ElementRenderer stencil, ElementRenderer element) { - this.stencil = stencil; - this.element = element; - } - - public T withStencilRenderer(ElementRenderer renderer) { - stencil = renderer; - //noinspection unchecked - return (T) this; - } - - public T withElementRenderer(ElementRenderer renderer) { - element = renderer; - //noinspection unchecked - return (T) this; - } - - @Override - protected void renderStencil(GuiGraphics graphics) { - stencil.render(graphics, width, height, 1); - } - - @Override - protected void renderElement(GuiGraphics graphics) { - element.render(graphics, width, height, alpha); - } - - @FunctionalInterface - public interface ElementRenderer { - void render(GuiGraphics graphics, int width, int height, float alpha); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/GuiGameElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/GuiGameElement.java deleted file mode 100644 index 75f48af..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/GuiGameElement.java +++ /dev/null @@ -1,301 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import com.jozufozu.flywheel.core.PartialModel; -import com.jozufozu.flywheel.core.model.ModelUtil; -import com.mojang.blaze3d.platform.GlStateManager.DestFactor; -import com.mojang.blaze3d.platform.GlStateManager.SourceFactor; -import com.mojang.blaze3d.platform.Lighting; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Axis; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.Sheets; -import net.minecraft.client.renderer.block.BlockRenderDispatcher; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.inventory.InventoryMenu; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.BaseFireBlock; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.phys.Vec3; -import net.neoforged.neoforge.client.RenderTypeHelper; -import nl.requios.effortlessbuilding.create.foundation.gui.ILightingSettings; -import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; -import nl.requios.effortlessbuilding.create.foundation.utility.VecHelper; - -import javax.annotation.Nullable; - -public class GuiGameElement { - - public static GuiRenderBuilder of(ItemStack stack) { - return new GuiItemRenderBuilder(stack); - } - - public static GuiRenderBuilder of(ItemLike itemProvider) { - return new GuiItemRenderBuilder(itemProvider); - } - - public static GuiRenderBuilder of(BlockState state) { - return new GuiBlockStateRenderBuilder(state); - } - - public static GuiRenderBuilder of(PartialModel partial) { - return new GuiBlockPartialRenderBuilder(partial); - } - - public static GuiRenderBuilder of(Fluid fluid) { - return new GuiBlockStateRenderBuilder(fluid.defaultFluidState() - .createLegacyBlock() - .setValue(LiquidBlock.LEVEL, 0)); - } - - public static abstract class GuiRenderBuilder extends RenderElement { - protected double xLocal, yLocal, zLocal; - protected double xRot, yRot, zRot; - protected double scale = 1; - protected int color = 0xFFFFFF; - protected Vec3 rotationOffset = Vec3.ZERO; - protected ILightingSettings customLighting = null; - - public GuiRenderBuilder atLocal(double x, double y, double z) { - this.xLocal = x; - this.yLocal = y; - this.zLocal = z; - return this; - } - - public GuiRenderBuilder rotate(double xRot, double yRot, double zRot) { - this.xRot = xRot; - this.yRot = yRot; - this.zRot = zRot; - return this; - } - - public GuiRenderBuilder rotateBlock(double xRot, double yRot, double zRot) { - return this.rotate(xRot, yRot, zRot) - .withRotationOffset(VecHelper.getCenterOf(BlockPos.ZERO)); - } - - public GuiRenderBuilder scale(double scale) { - this.scale = scale; - return this; - } - - public GuiRenderBuilder color(int color) { - this.color = color; - return this; - } - - public GuiRenderBuilder withRotationOffset(Vec3 offset) { - this.rotationOffset = offset; - return this; - } - - public GuiRenderBuilder lighting(ILightingSettings lighting) { - customLighting = lighting; - return this; - } - - protected void prepareMatrix(PoseStack matrixStack) { - matrixStack.pushPose(); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableDepthTest(); - RenderSystem.enableBlend(); - RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); - prepareLighting(matrixStack); - } - - protected void transformMatrix(PoseStack matrixStack) { - matrixStack.translate(x, y, z); - matrixStack.scale((float) scale, (float) scale, (float) scale); - matrixStack.translate(xLocal, yLocal, zLocal); - UIRenderHelper.flipForGuiRender(matrixStack); - matrixStack.translate(rotationOffset.x, rotationOffset.y, rotationOffset.z); - matrixStack.mulPose(Axis.ZP.rotationDegrees((float) zRot)); - matrixStack.mulPose(Axis.XP.rotationDegrees((float) xRot)); - matrixStack.mulPose(Axis.YP.rotationDegrees((float) yRot)); - matrixStack.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z); - } - - protected void cleanUpMatrix(PoseStack matrixStack) { - matrixStack.popPose(); - cleanUpLighting(matrixStack); - } - - protected void prepareLighting(PoseStack matrixStack) { - if (customLighting != null) { - customLighting.applyLighting(); - } else { - Lighting.setupFor3DItems(); - } - } - - protected void cleanUpLighting(PoseStack matrixStack) { - if (customLighting != null) { - Lighting.setupFor3DItems(); - } - } - } - - private static class GuiBlockModelRenderBuilder extends GuiRenderBuilder { - - protected BakedModel blockModel; - protected BlockState blockState; - - public GuiBlockModelRenderBuilder(BakedModel blockmodel, @Nullable BlockState blockState) { - this.blockState = blockState == null ? Blocks.AIR.defaultBlockState() : blockState; - this.blockModel = blockmodel; - } - - @Override - public void render(GuiGraphics graphics) { - PoseStack matrixStack = graphics.pose(); - prepareMatrix(matrixStack); - - Minecraft mc = Minecraft.getInstance(); - BlockRenderDispatcher blockRenderer = mc.getBlockRenderer(); - MultiBufferSource.BufferSource buffer = mc.renderBuffers() - .bufferSource(); - - transformMatrix(matrixStack); - - RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS); - renderModel(blockRenderer, buffer, matrixStack); - - cleanUpMatrix(matrixStack); - } - - protected void renderModel(BlockRenderDispatcher blockRenderer, MultiBufferSource.BufferSource buffer, - PoseStack ms) { - if (blockState.getBlock() == Blocks.AIR) { - RenderType renderType = Sheets.translucentCullBlockSheet(); - blockRenderer.getModelRenderer() - .renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel, 1, 1, 1, - LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, ModelUtil.VIRTUAL_DATA, null); - } else { - int color = Minecraft.getInstance() - .getBlockColors() - .getColor(blockState, null, null, 0); - Color rgb = new Color(color == -1 ? this.color : color); - - for (RenderType chunkType : blockModel.getRenderTypes(blockState, RandomSource.create(42L), ModelUtil.VIRTUAL_DATA)) { - RenderType renderType = RenderTypeHelper.getEntityRenderType(chunkType, true); - blockRenderer.getModelRenderer() - .renderModel(ms.last(), buffer.getBuffer(renderType), blockState, blockModel, - rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(), - LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, ModelUtil.VIRTUAL_DATA, chunkType); - } - } - - buffer.endBatch(); - } - - } - - public static class GuiBlockStateRenderBuilder extends GuiBlockModelRenderBuilder { - - public GuiBlockStateRenderBuilder(BlockState blockstate) { - super(Minecraft.getInstance() - .getBlockRenderer() - .getBlockModel(blockstate), blockstate); - } - - @Override - protected void renderModel(BlockRenderDispatcher blockRenderer, MultiBufferSource.BufferSource buffer, - PoseStack ms) { - if (blockState.getBlock() instanceof BaseFireBlock) { - Lighting.setupForFlatItems(); - super.renderModel(blockRenderer, buffer, ms); - Lighting.setupFor3DItems(); - return; - } - - super.renderModel(blockRenderer, buffer, ms); - - if (blockState.getFluidState() - .isEmpty()) - return; - -// FluidRenderer.renderFluidBox(new FluidStack(blockState.getFluidState() -// .getType(), 1000), 0, 0, 0, 1, 1, 1, buffer, ms, LightTexture.FULL_BRIGHT, false); -// buffer.endBatch(); - } - } - - public static class GuiBlockPartialRenderBuilder extends GuiBlockModelRenderBuilder { - - public GuiBlockPartialRenderBuilder(PartialModel partial) { - super(partial.get(), null); - } - - } - - public static class GuiItemRenderBuilder extends GuiRenderBuilder { - - private final ItemStack stack; - - public GuiItemRenderBuilder(ItemStack stack) { - this.stack = stack; - } - - public GuiItemRenderBuilder(ItemLike provider) { - this(new ItemStack(provider)); - } - - @Override - public void render(GuiGraphics graphics) { - PoseStack matrixStack = graphics.pose(); - prepareMatrix(matrixStack); - transformMatrix(matrixStack); - renderItemIntoGUI(matrixStack, stack, customLighting == null); - cleanUpMatrix(matrixStack); - } - - public static void renderItemIntoGUI(PoseStack matrixStack, ItemStack stack, boolean useDefaultLighting) { - ItemRenderer renderer = Minecraft.getInstance().getItemRenderer(); - BakedModel bakedModel = renderer.getModel(stack, null, null, 0); - - Minecraft.getInstance().textureManager.getTexture(InventoryMenu.BLOCK_ATLAS).setFilter(false, false); - RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS); - RenderSystem.enableBlend(); - RenderSystem.enableCull(); - RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - matrixStack.pushPose(); - matrixStack.translate(0, 0, 100.0F); - matrixStack.translate(8.0F, -8.0F, 0.0F); - matrixStack.scale(16.0F, 16.0F, 16.0F); - MultiBufferSource.BufferSource buffer = Minecraft.getInstance().renderBuffers().bufferSource(); - boolean flatLighting = !bakedModel.usesBlockLight(); - if (useDefaultLighting && flatLighting) { - Lighting.setupForFlatItems(); - } - - renderer.render(stack, ItemDisplayContext.GUI, false, matrixStack, buffer, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, bakedModel); - RenderSystem.disableDepthTest(); - buffer.endBatch(); - - RenderSystem.enableDepthTest(); - if (useDefaultLighting && flatLighting) { - Lighting.setupFor3DItems(); - } - - matrixStack.popPose(); - } - - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/RenderElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/RenderElement.java deleted file mode 100644 index 16a7519..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/RenderElement.java +++ /dev/null @@ -1,89 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import net.minecraft.client.gui.GuiGraphics; - -public abstract class RenderElement implements ScreenElement { - - public static final RenderElement EMPTY = new RenderElement() { - @Override - public void render(GuiGraphics graphics) { - } - }; - - public static RenderElement of(ScreenElement renderable) { - return new SimpleRenderElement(renderable); - } - - protected int width = 16, height = 16; - protected float x = 0, y = 0, z = 0; - protected float alpha = 1f; - - public T at(float x, float y) { - this.x = x; - this.y = y; - //noinspection unchecked - return (T) this; - } - - public T at(float x, float y, float z) { - this.x = x; - this.y = y; - this.z = z; - //noinspection unchecked - return (T) this; - } - - public T withBounds(int width, int height) { - this.width = width; - this.height = height; - //noinspection unchecked - return (T) this; - } - - public T withAlpha(float alpha) { - this.alpha = alpha; - //noinspection unchecked - return (T) this; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public float getX() { - return x; - } - - public float getY() { - return y; - } - - public float getZ() { - return z; - } - - public abstract void render(GuiGraphics graphics); - - @Override - public void render(GuiGraphics graphics, int x, int y) { - this.at(x, y).render(graphics); - } - - public static class SimpleRenderElement extends RenderElement { - - private ScreenElement renderable; - - public SimpleRenderElement(ScreenElement renderable) { - this.renderable = renderable; - } - - @Override - public void render(GuiGraphics graphics) { - renderable.render(graphics, (int) x, (int) y); - } - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/ScreenElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/ScreenElement.java deleted file mode 100644 index 6a6f9ba..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/ScreenElement.java +++ /dev/null @@ -1,12 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import net.minecraft.client.gui.GuiGraphics; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; - -public interface ScreenElement { - - @OnlyIn(Dist.CLIENT) - void render(GuiGraphics graphics, int x, int y); - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/StencilElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/StencilElement.java deleted file mode 100644 index 968ab5d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/StencilElement.java +++ /dev/null @@ -1,54 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import org.lwjgl.opengl.GL11; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; - -public abstract class StencilElement extends RenderElement { - - @Override - public void render(GuiGraphics graphics) { - PoseStack ms = graphics.pose(); - ms.pushPose(); - transform(ms); - prepareStencil(ms); - renderStencil(graphics); - prepareElement(ms); - renderElement(graphics); - cleanUp(ms); - ms.popPose(); - } - - protected abstract void renderStencil(GuiGraphics graphics); - - protected abstract void renderElement(GuiGraphics graphics); - - protected void transform(PoseStack ms) { - ms.translate(x, y, z); - } - - protected void prepareStencil(PoseStack ms) { - GL11.glDisable(GL11.GL_STENCIL_TEST); - RenderSystem.stencilMask(~0); - RenderSystem.clear(GL11.GL_STENCIL_BUFFER_BIT, Minecraft.ON_OSX); - GL11.glEnable(GL11.GL_STENCIL_TEST); - RenderSystem.stencilOp(GL11.GL_REPLACE, GL11.GL_KEEP, GL11.GL_KEEP); - RenderSystem.stencilMask(0xFF); - RenderSystem.stencilFunc(GL11.GL_NEVER, 1, 0xFF); - } - - protected void prepareElement(PoseStack ms) { - GL11.glEnable(GL11.GL_STENCIL_TEST); - RenderSystem.stencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP); - RenderSystem.stencilFunc(GL11.GL_EQUAL, 1, 0xFF); - } - - protected void cleanUp(PoseStack ms) { - GL11.glDisable(GL11.GL_STENCIL_TEST); - - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/TextStencilElement.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/TextStencilElement.java deleted file mode 100644 index 82c554e..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/element/TextStencilElement.java +++ /dev/null @@ -1,79 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.element; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.network.chat.MutableComponent; -import nl.requios.effortlessbuilding.create.foundation.utility.Components; - -public class TextStencilElement extends DelegatedStencilElement { - - protected Font font; - protected MutableComponent component; - protected boolean centerVertically = false; - protected boolean centerHorizontally = false; - - public TextStencilElement(Font font) { - super(); - this.font = font; - height = 10; - } - - public TextStencilElement(Font font, String text) { - this(font); - component = Components.literal(text); - } - - public TextStencilElement(Font font, MutableComponent component) { - this(font); - this.component = component; - } - - public TextStencilElement withText(String text) { - component = Components.literal(text); - return this; - } - - public TextStencilElement withText(MutableComponent component) { - this.component = component; - return this; - } - - public TextStencilElement centered(boolean vertical, boolean horizontal) { - this.centerVertically = vertical; - this.centerHorizontally = horizontal; - return this; - } - - @Override - protected void renderStencil(GuiGraphics graphics) { - float x = 0, y = 0; - if (centerHorizontally) - x = width / 2f - font.width(component) / 2f; - - if (centerVertically) - y = height / 2f - (font.lineHeight - 1) / 2f; - - graphics.drawString(font, component, Math.round(x), Math.round(y), 0xff_000000, false); - } - - @Override - protected void renderElement(GuiGraphics graphics) { - float x = 0, y = 0; - if (centerHorizontally) - x = width / 2f - font.width(component) / 2f; - - if (centerVertically) - y = height / 2f - (font.lineHeight - 1) / 2f; - - PoseStack ms = graphics.pose(); - ms.pushPose(); - ms.translate(x, y, 0); - element.render(graphics, font.width(component), font.lineHeight + 2, alpha); - ms.popPose(); - } - - public MutableComponent getComponent() { - return component; - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/AbstractSimiWidget.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/AbstractSimiWidget.java index 3c4cab6..525753a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/AbstractSimiWidget.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/AbstractSimiWidget.java @@ -1,10 +1,10 @@ package nl.requios.effortlessbuilding.create.foundation.gui.widget; +import net.createmod.catnip.gui.TickableGuiEventListener; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.network.chat.Component; -import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener; import nl.requios.effortlessbuilding.create.foundation.utility.Components; import javax.annotation.Nonnull; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/BoxWidget.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/BoxWidget.java deleted file mode 100644 index 5818c7c..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/BoxWidget.java +++ /dev/null @@ -1,226 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.widget; - -import net.minecraft.client.gui.GuiGraphics; -import nl.requios.effortlessbuilding.create.foundation.gui.Theme; -import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper; -import nl.requios.effortlessbuilding.create.foundation.gui.element.BoxElement; -import nl.requios.effortlessbuilding.create.foundation.gui.element.DelegatedStencilElement; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; -import nl.requios.effortlessbuilding.create.foundation.utility.Couple; -import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat; - -import java.util.function.Function; - -public class BoxWidget extends ElementWidget { - - public static final Function gradientFactory = (box) -> (ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, w/2, -2, w + 4, h + 4, box.gradientColor1, box.gradientColor2); - - protected BoxElement box; - - protected Color customBorderTop; - protected Color customBorderBot; - protected Color customBackground; - protected boolean animateColors = true; - protected LerpedFloat colorAnimation = LerpedFloat.linear(); - - protected Color gradientColor1, gradientColor2; - private Color previousColor1, previousColor2; - private Color colorTarget1 = Theme.c(getIdleTheme(), true).copy(); - private Color colorTarget2 = Theme.c(getIdleTheme(), false).copy(); - - public BoxWidget() { - this(0, 0); - } - - public BoxWidget(int x, int y) { - this(x, y, 16, 16); - } - - public BoxWidget(int x, int y, int width, int height) { - super(x, y, width, height); - box = new BoxElement() - .at(x, y) - .withBounds(width, height); - gradientColor1 = colorTarget1; - gradientColor2 = colorTarget2; - } - - public T withBounds(int width, int height) { - this.width = width; - this.height = height; - //noinspection unchecked - return (T) this; - } - - public T withBorderColors(Couple colors) { - this.customBorderTop = colors.getFirst(); - this.customBorderBot = colors.getSecond(); - updateColorsFromState(); - //noinspection unchecked - return (T) this; - } - - public T withBorderColors(Color top, Color bot) { - this.customBorderTop = top; - this.customBorderBot = bot; - updateColorsFromState(); - //noinspection unchecked - return (T) this; - } - - public T withCustomBackground(Color color) { - this.customBackground = color; - //noinspection unchecked - return (T) this; - } - - public T animateColors(boolean b) { - this.animateColors = b; - //noinspection unchecked - return (T) this; - } - - @Override - public void tick() { - super.tick(); - colorAnimation.tickChaser(); - } - - @Override - public void onClick(double x, double y) { - super.onClick(x, y); - - gradientColor1 = Theme.c(getClickTheme(), true); - gradientColor2 = Theme.c(getClickTheme(), false); - startGradientAnimation(getColorForState(true), getColorForState(false), true, 0.15); - } - - @Override - protected void beforeRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - super.beforeRender(graphics, mouseX, mouseY, partialTicks); - - if (isHovered != wasHovered) { - startGradientAnimation( - getColorForState(true), - getColorForState(false), - isHovered - ); - } - - if (colorAnimation.settled()) { - gradientColor1 = colorTarget1; - gradientColor2 = colorTarget2; - } else { - float animationValue = 1 - Math.abs(colorAnimation.getValue(partialTicks)); - gradientColor1 = Color.mixColors(previousColor1, colorTarget1, animationValue); - gradientColor2 = Color.mixColors(previousColor2, colorTarget2, animationValue); - } - - } - - @Override - public void doRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - float fadeValue = fade.getValue(partialTicks); - if (fadeValue < .1f) - return; - - box.withAlpha(fadeValue); - box.withBackground(customBackground != null ? customBackground : Theme.c(Theme.Key.PONDER_BACKGROUND_TRANSPARENT)) - .gradientBorder(gradientColor1, gradientColor2) - .at(getX(), getY(), z) - .withBounds(width, height) - .render(graphics); - - super.doRender(graphics, mouseX, mouseY, partialTicks); - - wasHovered = isHovered; - } - - @Override - public boolean isMouseOver(double mX, double mY) { - if (!active || !visible) - return false; - - float padX = 2 + paddingX; - float padY = 2 + paddingY; - - return getX() - padX <= mX && getY() - padY <= mY && mX < getX() + padX + width && mY < getY() + padY + height; - } - - @Override - protected boolean clicked(double pMouseX, double pMouseY) { - if (!active || !visible) - return false; - return isMouseOver(pMouseX, pMouseY); - } - - public BoxElement getBox() { - return box; - } - - public void updateColorsFromState() { - colorTarget1 = getColorForState(true); - colorTarget2 = getColorForState(false); - } - - public void animateGradientFromState() { - startGradientAnimation( - getColorForState(true), - getColorForState(false), - true - ); - } - - private void startGradientAnimation(Color c1, Color c2, boolean positive, double expSpeed) { - if (!animateColors) - return; - - colorAnimation.startWithValue(positive ? 1 : -1); - colorAnimation.chase(0, expSpeed, LerpedFloat.Chaser.EXP); - colorAnimation.tickChaser(); - - previousColor1 = gradientColor1; - previousColor2 = gradientColor2; - - colorTarget1 = c1; - colorTarget2 = c2; - } - - private void startGradientAnimation(Color c1, Color c2, boolean positive) { - startGradientAnimation(c1, c2, positive, 0.6); - } - - private Color getColorForState(boolean first) { - if (!active) - return Theme.p(getDisabledTheme()).get(first); - - if (isHovered) { - if (first) - return customBorderTop != null ? customBorderTop.darker() : Theme.c(getHoverTheme(), true); - else - return customBorderBot != null ? customBorderBot.darker() : Theme.c(getHoverTheme(), false); - } - - if (first) - return customBorderTop != null ? customBorderTop : Theme.c(getIdleTheme(), true); - else - return customBorderBot != null ? customBorderBot : Theme.c(getIdleTheme(), false); - } - - public Theme.Key getDisabledTheme() { - return Theme.Key.BUTTON_DISABLE; - } - - public Theme.Key getIdleTheme() { - return Theme.Key.BUTTON_IDLE; - } - - public Theme.Key getHoverTheme() { - return Theme.Key.BUTTON_HOVER; - } - - public Theme.Key getClickTheme() { - return Theme.Key.BUTTON_CLICK; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/ElementWidget.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/ElementWidget.java deleted file mode 100644 index 9cffb11..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/ElementWidget.java +++ /dev/null @@ -1,157 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.gui.widget; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.gui.GuiGraphics; -import nl.requios.effortlessbuilding.create.foundation.gui.element.RenderElement; -import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; -import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat; - -import java.util.function.Consumer; -import java.util.function.UnaryOperator; - -public class ElementWidget extends AbstractSimiWidget { - - protected RenderElement element = RenderElement.EMPTY; - - protected boolean usesFade = false; - protected int fadeModX; - protected int fadeModY; - protected LerpedFloat fade = LerpedFloat.linear().startWithValue(1); - - protected boolean rescaleElement = false; - protected float rescaleSizeX; - protected float rescaleSizeY; - - protected float paddingX = 0; - protected float paddingY = 0; - - public ElementWidget(int x, int y) { - super(x, y); - } - - public ElementWidget(int x, int y, int width, int height) { - super(x, y, width, height); - } - - public T showingElement(RenderElement element) { - this.element = element; - //noinspection unchecked - return (T) this; - } - - public T showing(ScreenElement renderable) { - return this.showingElement(RenderElement.of(renderable)); - } - - public T modifyElement(Consumer consumer) { - if (element != null) - consumer.accept(element); - //noinspection unchecked - return (T) this; - } - - public T mapElement(UnaryOperator function) { - if (element != null) - element = function.apply(element); - //noinspection unchecked - return (T) this; - } - - public T withPadding(float paddingX, float paddingY) { - this.paddingX = paddingX; - this.paddingY = paddingY; - //noinspection unchecked - return (T) this; - } - - public T enableFade(int fadeModifierX, int fadeModifierY) { - this.fade.startWithValue(0); - this.usesFade = true; - this.fadeModX = fadeModifierX; - this.fadeModY = fadeModifierY; - //noinspection unchecked - return (T) this; - } - - public T disableFade() { - this.fade.startWithValue(1); - this.usesFade = false; - //noinspection unchecked - return (T) this; - } - - public LerpedFloat fade() { - return fade; - } - - public T fade(float target) { - fade.chase(target, 0.1, LerpedFloat.Chaser.EXP); - //noinspection unchecked - return (T) this; - } - - /** - * Rescaling and its effects aren't properly tested with most elements. - * Thought it should work fine when using a TextStencilElement. - * Check BaseConfigScreen's title for such an example. - */ - @Deprecated - public T rescaleElement(float rescaleSizeX, float rescaleSizeY) { - this.rescaleElement = true; - this.rescaleSizeX = rescaleSizeX; - this.rescaleSizeY = rescaleSizeY; - //noinspection unchecked - return (T) this; - } - - public T disableRescale() { - this.rescaleElement = false; - //noinspection unchecked - return (T) this; - } - - @Override - public void tick() { - super.tick(); - fade.tickChaser(); - } - - @Override - protected void beforeRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - super.beforeRender(graphics, mouseX, mouseY, partialTicks); - isHovered = isMouseOver(mouseX, mouseY); - - float fadeValue = fade.getValue(partialTicks); - element.withAlpha(fadeValue); - if (fadeValue < 1) { - graphics.pose().translate((1 - fadeValue) * fadeModX, (1 - fadeValue) * fadeModY, 0); - } - } - - @Override - public void doRender(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { - PoseStack ms = graphics.pose(); - ms.pushPose(); - ms.translate(getX() + paddingX, getY() + paddingY, z); - float innerWidth = width - 2 * paddingX; - float innerHeight = height - 2 * paddingY; - float eX = element.getX(), eY = element.getY(); - if (rescaleElement) { - float xScale = innerWidth / rescaleSizeX; - float yScale = innerHeight / rescaleSizeY; - ms.scale(xScale, yScale, 1); - element.at(eX / xScale, eY / yScale); - innerWidth /= xScale; - innerHeight /= yScale; - } - element.withBounds((int) innerWidth, (int) innerHeight).render(graphics); - ms.popPose(); - if (rescaleElement) { - element.at(eX, eY); - } - } - - public RenderElement getRenderElement() { - return element; - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/IconButton.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/IconButton.java index 6554942..6226352 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/IconButton.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/IconButton.java @@ -1,10 +1,10 @@ package nl.requios.effortlessbuilding.create.foundation.gui.widget; import com.mojang.blaze3d.systems.RenderSystem; +import net.createmod.catnip.gui.element.ScreenElement; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; import nl.requios.effortlessbuilding.create.foundation.gui.AllGuiTextures; -import nl.requios.effortlessbuilding.create.foundation.gui.element.ScreenElement; public class IconButton extends AbstractSimiWidget { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/TooltipArea.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/TooltipArea.java index e3dcd78..e457cb3 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/TooltipArea.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/widget/TooltipArea.java @@ -1,10 +1,10 @@ package nl.requios.effortlessbuilding.create.foundation.gui.widget; -import java.util.List; - import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; +import java.util.List; + public class TooltipArea extends AbstractSimiWidget { public TooltipArea(int x, int y, int width, int height) { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemDescription.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemDescription.java index f3be447..233c1b0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemDescription.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemDescription.java @@ -11,7 +11,20 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static net.minecraft.ChatFormatting.*; +import static net.minecraft.ChatFormatting.AQUA; +import static net.minecraft.ChatFormatting.BLUE; +import static net.minecraft.ChatFormatting.DARK_GRAY; +import static net.minecraft.ChatFormatting.DARK_GREEN; +import static net.minecraft.ChatFormatting.DARK_PURPLE; +import static net.minecraft.ChatFormatting.DARK_RED; +import static net.minecraft.ChatFormatting.GOLD; +import static net.minecraft.ChatFormatting.GRAY; +import static net.minecraft.ChatFormatting.GREEN; +import static net.minecraft.ChatFormatting.LIGHT_PURPLE; +import static net.minecraft.ChatFormatting.RED; +import static net.minecraft.ChatFormatting.STRIKETHROUGH; +import static net.minecraft.ChatFormatting.WHITE; +import static net.minecraft.ChatFormatting.YELLOW; import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutStringTextComponent; import static nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper.cutTextComponent; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemHelper.java index 2dd46b2..b1d39ef 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/ItemHelper.java @@ -1,9 +1,9 @@ package nl.requios.effortlessbuilding.create.foundation.item; -import net.neoforged.neoforge.items.ItemHandlerHelper; -import nl.requios.effortlessbuilding.create.foundation.utility.Pair; +import net.createmod.catnip.data.Pair; import net.minecraft.core.BlockPos; import net.minecraft.core.NonNullList; +import net.minecraft.core.component.DataComponents; import net.minecraft.util.Mth; import net.minecraft.world.Containers; import net.minecraft.world.item.ItemStack; @@ -40,9 +40,9 @@ public class ItemHelper { public static void addToList(ItemStack stack, List stacks) { for (ItemStack s : stacks) { - if (!ItemHandlerHelper.canItemStacksStack(stack, s)) + if (!ItemStack.isSameItemSameComponents(stack, s)) continue; - int transferred = Math.min(s.getMaxStackSize() - s.getCount(), stack.getCount()); + int transferred = Math.min(s.getOrDefault(DataComponents.MAX_STACK_SIZE, 64) - s.getCount(), stack.getCount()); s.grow(transferred); stack.shrink(transferred); } @@ -199,7 +199,7 @@ public class ItemHelper { if (!extracting.isEmpty() && !hasEnoughItems && potentialOtherMatch) { ItemStack blackListed = extracting.copy(); - test = test.and(i -> !ItemHandlerHelper.canItemStacksStack(i, blackListed)); + test = test.and(i -> !ItemStack.isSameItemSameComponents(i, blackListed)); continue; } @@ -254,7 +254,7 @@ public class ItemHelper { } public static boolean canItemStackAmountsStack(ItemStack a, ItemStack b) { - return ItemHandlerHelper.canItemStacksStack(a, b) && a.getCount() + b.getCount() <= a.getMaxStackSize(); + return ItemStack.isSameItemSameComponents(a, b) && a.getCount() + b.getCount() <= a.getOrDefault(DataComponents.MAX_STACK_SIZE, 64); } public static ItemStack findFirstMatch(IItemHandler inv, Predicate test) { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/TooltipHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/TooltipHelper.java index 67f723c..1933b42 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/TooltipHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/TooltipHelper.java @@ -1,6 +1,8 @@ package nl.requios.effortlessbuilding.create.foundation.item; import com.google.common.base.Strings; +import net.createmod.catnip.data.Couple; +import net.createmod.catnip.lang.ClientFontHelper; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -12,8 +14,6 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; import nl.requios.effortlessbuilding.create.foundation.item.ItemDescription.Palette; import nl.requios.effortlessbuilding.create.foundation.utility.Components; -import nl.requios.effortlessbuilding.create.foundation.utility.Couple; -import nl.requios.effortlessbuilding.create.foundation.utility.FontHelper; import nl.requios.effortlessbuilding.create.foundation.utility.Lang; import java.text.BreakIterator; @@ -81,7 +81,7 @@ public class TooltipHelper { } Font font = Minecraft.getInstance().font; - List lines = FontHelper.cutString(font, markedUp, maxWidthPerLine); + List lines = ClientFontHelper.cutString(font, markedUp, maxWidthPerLine); // Format String lineStart = Strings.repeat(" ", indent); diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/render/PartialItemModelRenderer.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/render/PartialItemModelRenderer.java index dd90019..540a882 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/render/PartialItemModelRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/item/render/PartialItemModelRenderer.java @@ -2,6 +2,7 @@ package nl.requios.effortlessbuilding.create.foundation.item.render; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import net.createmod.catnip.data.Iterate; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; @@ -14,7 +15,6 @@ import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; import net.neoforged.neoforge.client.model.data.ModelData; import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes; -import nl.requios.effortlessbuilding.create.foundation.utility.Iterate; public class PartialItemModelRenderer { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/ISyncPersistentData.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/ISyncPersistentData.java deleted file mode 100644 index e311e1a..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/ISyncPersistentData.java +++ /dev/null @@ -1,53 +0,0 @@ -//package nl.requios.effortlessbuilding.create.foundation.networking; -// -//import net.minecraft.client.Minecraft; -//import net.minecraft.nbt.CompoundTag; -//import net.minecraft.network.FriendlyByteBuf; -//import net.minecraft.world.entity.Entity; -//import net.neoforged.neoforge.network.NetworkEvent.Context; -// -//import java.util.HashSet; -// -//public interface ISyncPersistentData { -// -// void onPersistentDataUpdated(); -// -// public static class PersistentDataPacket extends SimplePacketBase { -// -// private int entityId; -// private Entity entity; -// private CompoundTag readData; -// -// public PersistentDataPacket(Entity entity) { -// this.entity = entity; -// this.entityId = entity.getId(); -// } -// -// public PersistentDataPacket(FriendlyByteBuf buffer) { -// entityId = buffer.readInt(); -// readData = buffer.readNbt(); -// } -// -// @Override -// public void write(FriendlyByteBuf buffer) { -// buffer.writeInt(entityId); -// buffer.writeNbt(entity.getPersistentData()); -// } -// -// @Override -// public boolean handle(Context context) { -// context.enqueueWork(() -> { -// Entity entityByID = Minecraft.getInstance().level.getEntity(entityId); -// CompoundTag data = entityByID.getPersistentData(); -// new HashSet<>(data.getAllKeys()).forEach(data::remove); -// data.merge(readData); -// if (!(entityByID instanceof ISyncPersistentData)) -// return; -// ((ISyncPersistentData) entityByID).onPersistentDataUpdated(); -// }); -// return true; -// } -// -// } -// -//} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/SimplePacketBase.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/SimplePacketBase.java deleted file mode 100644 index 641fb9e..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/networking/SimplePacketBase.java +++ /dev/null @@ -1,12 +0,0 @@ -//package nl.requios.effortlessbuilding.create.foundation.networking; -// -//import net.minecraft.network.FriendlyByteBuf; -//import net.neoforged.neoforge.network.NetworkEvent.Context; -// -//public abstract class SimplePacketBase { -// -// public abstract void write(FriendlyByteBuf buffer); -// -// public abstract boolean handle(Context context); -// -//} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BakedModelRenderHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BakedModelRenderHelper.java deleted file mode 100644 index 6b68393..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BakedModelRenderHelper.java +++ /dev/null @@ -1,30 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - -import com.jozufozu.flywheel.core.model.ModelUtil; -import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.block.BlockRenderDispatcher; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.world.level.block.state.BlockState; - -public class BakedModelRenderHelper { - - public static SuperByteBuffer standardBlockRender(BlockState renderedState) { - BlockRenderDispatcher dispatcher = Minecraft.getInstance() - .getBlockRenderer(); - return standardModelRender(dispatcher.getBlockModel(renderedState), renderedState); - } - - public static SuperByteBuffer standardModelRender(BakedModel model, BlockState referenceState) { - return standardModelRender(model, referenceState, new PoseStack()); - } - - public static SuperByteBuffer standardModelRender(BakedModel model, BlockState referenceState, PoseStack ms) { - ShadeSeparatedBufferedData data = ModelUtil.getBufferedData(model, referenceState, ms); - SuperByteBuffer sbb = new SuperByteBuffer(data); - data.release(); - return sbb; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BlockEntityRenderHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BlockEntityRenderHelper.java new file mode 100644 index 0000000..3d30435 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/BlockEntityRenderHelper.java @@ -0,0 +1,113 @@ +package nl.requios.effortlessbuilding.create.foundation.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.engine_room.flywheel.api.visualization.VisualizationManager; +import dev.engine_room.flywheel.lib.transform.TransformStack; +import dev.engine_room.flywheel.lib.visualization.VisualizationHelper; +import net.createmod.catnip.animation.AnimationTickHolder; +import net.createmod.catnip.registry.RegisteredObjectsHelper; +import net.createmod.catnip.render.SuperByteBuffer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import nl.requios.effortlessbuilding.create.Create; +import nl.requios.effortlessbuilding.create.foundation.virtualWorld.VirtualRenderWorld; +import org.joml.Matrix4f; +import org.joml.Vector4f; + +import javax.annotation.Nullable; +import java.util.Iterator; + +public class BlockEntityRenderHelper { + + public static void renderBlockEntities(Level world, Iterable customRenderBEs, PoseStack ms, + MultiBufferSource buffer) { + renderBlockEntities(world, null, customRenderBEs, ms, null, buffer); + } + + public static void renderBlockEntities(Level world, Iterable customRenderBEs, PoseStack ms, + MultiBufferSource buffer, float pt) { + renderBlockEntities(world, null, customRenderBEs, ms, null, buffer, pt); + } + + public static void renderBlockEntities(Level world, @Nullable VirtualRenderWorld renderWorld, + Iterable customRenderBEs, PoseStack ms, @Nullable Matrix4f lightTransform, MultiBufferSource buffer) { + renderBlockEntities(world, renderWorld, customRenderBEs, ms, lightTransform, buffer, + AnimationTickHolder.getPartialTicks()); + } + + public static void renderBlockEntities(Level world, @Nullable VirtualRenderWorld renderWorld, + Iterable customRenderBEs, PoseStack ms, @Nullable Matrix4f lightTransform, MultiBufferSource buffer, + float pt) { + Iterator iterator = customRenderBEs.iterator(); + while (iterator.hasNext()) { + BlockEntity blockEntity = iterator.next(); + if (VisualizationManager.supportsVisualization(world) && VisualizationHelper.skipVanillaRender(blockEntity)) + continue; + + BlockEntityRenderer renderer = Minecraft.getInstance().getBlockEntityRenderDispatcher().getRenderer(blockEntity); + if (renderer == null) { + iterator.remove(); + continue; + } + + BlockPos pos = blockEntity.getBlockPos(); + ms.pushPose(); + TransformStack.of(ms) + .translate(pos); + + try { + int worldLight = getCombinedLight(world, getLightPos(lightTransform, pos), renderWorld, pos); + + if (renderWorld != null) { + // Swap the real world for the render world so that the renderer gets contraption-local information + blockEntity.setLevel(renderWorld); + renderer.render(blockEntity, pt, ms, buffer, worldLight, OverlayTexture.NO_OVERLAY); + blockEntity.setLevel(world); + } else { + renderer.render(blockEntity, pt, ms, buffer, worldLight, OverlayTexture.NO_OVERLAY); + } + + } catch (Exception e) { + iterator.remove(); + + String message = "BlockEntity " + RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType()) + .toString() + " could not be rendered virtually."; +// if (AllConfigs.CLIENT.explainRenderErrors.get()) + Create.LOGGER.error(message, e); +// else +// Create.LOGGER.error(message); + } + + ms.popPose(); + } + } + + private static BlockPos getLightPos(@Nullable Matrix4f lightTransform, BlockPos contraptionPos) { + if (lightTransform != null) { + Vector4f lightVec = new Vector4f(contraptionPos.getX() + .5f, contraptionPos.getY() + .5f, contraptionPos.getZ() + .5f, 1); + lightVec.mul(lightTransform); + return BlockPos.containing(lightVec.x(), lightVec.y(), lightVec.z()); + } else { + return contraptionPos; + } + } + + public static int getCombinedLight(Level world, BlockPos worldPos, @Nullable VirtualRenderWorld renderWorld, + BlockPos renderWorldPos) { + int worldLight = LevelRenderer.getLightColor(world, worldPos); + + if (renderWorld != null) { + int renderWorldLight = LevelRenderer.getLightColor(renderWorld, renderWorldPos); + return SuperByteBuffer.maxLight(worldLight, renderWorldLight); + } + + return worldLight; + } + +} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/CachedBufferer.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/CachedBufferer.java deleted file mode 100644 index 3da0b88..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/CachedBufferer.java +++ /dev/null @@ -1,87 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - -import com.jozufozu.flywheel.core.PartialModel; -import com.jozufozu.flywheel.util.transform.TransformStack; -import com.mojang.blaze3d.vertex.PoseStack; -import nl.requios.effortlessbuilding.create.CreateClient; -import nl.requios.effortlessbuilding.create.foundation.render.SuperByteBufferCache.Compartment; -import nl.requios.effortlessbuilding.create.foundation.utility.AngleHelper; -import net.minecraft.core.Direction; -import net.minecraft.world.level.block.state.BlockState; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.function.Supplier; - -import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING; - -public class CachedBufferer { - - public static final Compartment GENERIC_TILE = new Compartment<>(); - public static final Compartment PARTIAL = new Compartment<>(); - public static final Compartment> DIRECTIONAL_PARTIAL = new Compartment<>(); - - public static SuperByteBuffer block(BlockState toRender) { - return block(GENERIC_TILE, toRender); - } - - public static SuperByteBuffer block(Compartment compartment, BlockState toRender) { - return CreateClient.BUFFER_CACHE.get(compartment, toRender, () -> BakedModelRenderHelper.standardBlockRender(toRender)); - } - - public static SuperByteBuffer partial(PartialModel partial, BlockState referenceState) { - return CreateClient.BUFFER_CACHE.get(PARTIAL, partial, - () -> BakedModelRenderHelper.standardModelRender(partial.get(), referenceState)); - } - - public static SuperByteBuffer partial(PartialModel partial, BlockState referenceState, - Supplier modelTransform) { - return CreateClient.BUFFER_CACHE.get(PARTIAL, partial, - () -> BakedModelRenderHelper.standardModelRender(partial.get(), referenceState, modelTransform.get())); - } - - public static SuperByteBuffer partialFacing(PartialModel partial, BlockState referenceState) { - Direction facing = referenceState.getValue(FACING); - return partialFacing(partial, referenceState, facing); - } - - public static SuperByteBuffer partialFacing(PartialModel partial, BlockState referenceState, Direction facing) { - return partialDirectional(partial, referenceState, facing, - rotateToFace(facing)); - } - - public static SuperByteBuffer partialFacingVertical(PartialModel partial, BlockState referenceState, Direction facing) { - return partialDirectional(partial, referenceState, facing, - rotateToFaceVertical(facing)); - } - - public static SuperByteBuffer partialDirectional(PartialModel partial, BlockState referenceState, Direction dir, - Supplier modelTransform) { - return CreateClient.BUFFER_CACHE.get(DIRECTIONAL_PARTIAL, Pair.of(dir, partial), - () -> BakedModelRenderHelper.standardModelRender(partial.get(), referenceState, modelTransform.get())); - } - - public static Supplier rotateToFace(Direction facing) { - return () -> { - PoseStack stack = new PoseStack(); - TransformStack.cast(stack) - .centre() - .rotateY(AngleHelper.horizontalAngle(facing)) - .rotateX(AngleHelper.verticalAngle(facing)) - .unCentre(); - return stack; - }; - } - - public static Supplier rotateToFaceVertical(Direction facing) { - return () -> { - PoseStack stack = new PoseStack(); - TransformStack.cast(stack) - .centre() - .rotateY(AngleHelper.horizontalAngle(facing)) - .rotateX(AngleHelper.verticalAngle(facing) + 90) - .unCentre(); - return stack; - }; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ForcedDiffuseState.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ForcedDiffuseState.java deleted file mode 100644 index 8e1b34c..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ForcedDiffuseState.java +++ /dev/null @@ -1,30 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - -import com.jozufozu.flywheel.util.DiffuseLightCalculator; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; - -import javax.annotation.Nullable; - -public final class ForcedDiffuseState { - private static final ThreadLocal> FORCED_DIFFUSE = ThreadLocal.withInitial(ObjectArrayList::new); - - private ForcedDiffuseState() { - } - - public static void pushCalculator(DiffuseLightCalculator calculator) { - FORCED_DIFFUSE.get().push(calculator); - } - - public static void popCalculator() { - FORCED_DIFFUSE.get().pop(); - } - - @Nullable - public static DiffuseLightCalculator getForcedCalculator() { - ObjectArrayList stack = FORCED_DIFFUSE.get(); - if (stack.isEmpty()) { - return null; - } - return stack.top(); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/RenderTypes.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/RenderTypes.java index fb46e7c..1754c66 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/RenderTypes.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/RenderTypes.java @@ -2,12 +2,12 @@ package nl.requios.effortlessbuilding.create.foundation.render; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; -import nl.requios.effortlessbuilding.create.AllSpecialTextures; -import nl.requios.effortlessbuilding.create.Create; import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.inventory.InventoryMenu; +import nl.requios.effortlessbuilding.create.AllSpecialTextures; +import nl.requios.effortlessbuilding.create.Create; // TODO 1.17: use custom shaders instead of vanilla ones public class RenderTypes extends RenderStateShard { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ShadowRenderHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ShadowRenderHelper.java deleted file mode 100644 index 211c789..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/ShadowRenderHelper.java +++ /dev/null @@ -1,113 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.VoxelShape; - -/** - * Taken from EntityRendererManager - */ -public class ShadowRenderHelper { - - private static final RenderType SHADOW_LAYER = - RenderType.entityNoOutline(new ResourceLocation("textures/misc/shadow.png")); - - public static void renderShadow(PoseStack matrixStack, MultiBufferSource buffer, float opacity, float radius) { - PoseStack.Pose entry = matrixStack.last(); - VertexConsumer builder = buffer.getBuffer(SHADOW_LAYER); - - opacity /= 2; - shadowVertex(entry, builder, opacity, -1 * radius, 0, -1 * radius, 0, 0); - shadowVertex(entry, builder, opacity, -1 * radius, 0, 1 * radius, 0, 1); - shadowVertex(entry, builder, opacity, 1 * radius, 0, 1 * radius, 1, 1); - shadowVertex(entry, builder, opacity, 1 * radius, 0, -1 * radius, 1, 0); - } - - public static void renderShadow(PoseStack matrixStack, MultiBufferSource buffer, LevelReader world, - Vec3 pos, float opacity, float radius) { - float f = radius; - - double d2 = pos.x(); - double d0 = pos.y(); - double d1 = pos.z(); - int i = Mth.floor(d2 - (double) f); - int j = Mth.floor(d2 + (double) f); - int k = Mth.floor(d0 - (double) f); - int l = Mth.floor(d0); - int i1 = Mth.floor(d1 - (double) f); - int j1 = Mth.floor(d1 + (double) f); - PoseStack.Pose entry = matrixStack.last(); - VertexConsumer builder = buffer.getBuffer(SHADOW_LAYER); - - for (BlockPos blockpos : BlockPos.betweenClosed(new BlockPos(i, k, i1), new BlockPos(j, l, j1))) { - renderBlockShadow(entry, builder, world, blockpos, d2, d0, d1, f, - opacity); - } - } - - private static void renderBlockShadow(PoseStack.Pose entry, VertexConsumer builder, - LevelReader world, BlockPos pos, double x, double y, double z, - float radius, float opacity) { - BlockPos blockpos = pos.below(); - BlockState blockstate = world.getBlockState(blockpos); - if (blockstate.getRenderShape() != RenderShape.INVISIBLE && world.getMaxLocalRawBrightness(pos) > 3) { - if (blockstate.isCollisionShapeFullBlock(world, blockpos)) { - VoxelShape voxelshape = blockstate.getShape(world, pos.below()); - if (!voxelshape.isEmpty()) { - float brightness = LightTexture.getBrightness(world.dimensionType(), world.getMaxLocalRawBrightness(pos)); - float f = (float) ((opacity - (y - pos.getY()) / 2.0D) * 0.5D * brightness); - if (f >= 0.0F) { - if (f > 1.0F) { - f = 1.0F; - } - - AABB AABB = voxelshape.bounds(); - double d0 = (double) pos.getX() + AABB.minX; - double d1 = (double) pos.getX() + AABB.maxX; - double d2 = (double) pos.getY() + AABB.minY; - double d3 = (double) pos.getZ() + AABB.minZ; - double d4 = (double) pos.getZ() + AABB.maxZ; - float f1 = (float) (d0 - x); - float f2 = (float) (d1 - x); - float f3 = (float) (d2 - y + 0.015625D); - float f4 = (float) (d3 - z); - float f5 = (float) (d4 - z); - float f6 = -f1 / 2.0F / radius + 0.5F; - float f7 = -f2 / 2.0F / radius + 0.5F; - float f8 = -f4 / 2.0F / radius + 0.5F; - float f9 = -f5 / 2.0F / radius + 0.5F; - shadowVertex(entry, builder, f, f1, f3, f4, f6, f8); - shadowVertex(entry, builder, f, f1, f3, f5, f6, f9); - shadowVertex(entry, builder, f, f2, f3, f5, f7, f9); - shadowVertex(entry, builder, f, f2, f3, f4, f7, f8); - } - } - } - } - } - - private static void shadowVertex(PoseStack.Pose entry, VertexConsumer builder, float alpha, - float x, float y, float z, float u, float v) { - builder.vertex(entry.pose(), x, y, z) - .color(1.0F, 1.0F, 1.0F, alpha) - .uv(u, v) - .overlayCoords(OverlayTexture.NO_OVERLAY) - .uv2(LightTexture.FULL_BRIGHT) - .normal(entry.normal(), 0.0F, 1.0F, 0.0F) - .endVertex(); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBuffer.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBuffer.java deleted file mode 100644 index ece25d2..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBuffer.java +++ /dev/null @@ -1,492 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - - -import com.jozufozu.flywheel.api.vertex.ShadedVertexList; -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.backend.ShadersModHandler; -import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferedData; -import com.jozufozu.flywheel.core.vertex.BlockVertexList; -import com.jozufozu.flywheel.util.Color; -import com.jozufozu.flywheel.util.DiffuseLightCalculator; -import com.jozufozu.flywheel.util.transform.TStack; -import com.jozufozu.flywheel.util.transform.Transform; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import it.unimi.dsi.fastutil.longs.Long2IntMap; -import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.util.Mth; -import net.minecraft.world.level.Level; -import nl.requios.effortlessbuilding.create.foundation.block.render.SpriteShiftEntry; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.joml.Vector4f; - -import java.nio.ByteBuffer; -import java.util.function.IntPredicate; - -public class SuperByteBuffer implements Transform, TStack { - - private final VertexList template; - private final IntPredicate shadedPredicate; - - // Vertex Position - private final PoseStack transforms = new PoseStack(); - - // Vertex Coloring - private boolean shouldColor; - private int r, g, b, a; - private boolean disableDiffuseMult; - private DiffuseLightCalculator diffuseCalculator; - - // Vertex Texture Coords - private SpriteShiftFunc spriteShiftFunc; - - // Vertex Overlay Color - private boolean hasOverlay; - private int overlay = OverlayTexture.NO_OVERLAY; - - // Vertex Lighting - private boolean useWorldLight; - private Matrix4f lightTransform; - private boolean hasCustomLight; - private int packedLightCoords; - private boolean hybridLight; - - // Vertex Normals - private boolean fullNormalTransform; - - // Temporary - private static final Long2IntMap WORLD_LIGHT_CACHE = new Long2IntOpenHashMap(); - - public SuperByteBuffer(ByteBuffer vertexBuffer, BufferBuilder.DrawState drawState, int unshadedStartVertex) { - int vertexCount = drawState.vertexCount(); - int stride = drawState.format().getVertexSize(); - - ShadedVertexList template = new BlockVertexList.Shaded(vertexBuffer, vertexCount, stride, unshadedStartVertex); - shadedPredicate = template::isShaded; - this.template = template; - - transforms.pushPose(); - } - - public SuperByteBuffer(ShadeSeparatedBufferedData data) { - this(data.vertexBuffer(), data.drawState(), data.unshadedStartVertex()); - } - - public SuperByteBuffer(ByteBuffer vertexBuffer, BufferBuilder.DrawState drawState) { - int vertexCount = drawState.vertexCount(); - int stride = drawState.format().getVertexSize(); - - template = new BlockVertexList(vertexBuffer, vertexCount, stride); - shadedPredicate = index -> true; - - transforms.pushPose(); - } - - public void renderInto(PoseStack input, VertexConsumer builder) { - if (isEmpty()) - return; - - Matrix4f modelMat = new Matrix4f(input.last() - .pose()); - Matrix4f localTransforms = transforms.last() - .pose(); - modelMat.mul(localTransforms); - - Matrix3f normalMat; - if (fullNormalTransform) { - normalMat = new Matrix3f(input.last() - .normal()); - Matrix3f localNormalTransforms = transforms.last() - .normal(); - normalMat.mul(localNormalTransforms); - } else { - normalMat = new Matrix3f(transforms.last() - .normal()); - } - - if (useWorldLight) { - WORLD_LIGHT_CACHE.clear(); - } - - final Vector4f pos = new Vector4f(); - final Vector3f normal = new Vector3f(); - final Vector4f lightPos = new Vector4f(); - - DiffuseLightCalculator diffuseCalculator = ForcedDiffuseState.getForcedCalculator(); - final boolean disableDiffuseMult = - this.disableDiffuseMult || (ShadersModHandler.isShaderPackInUse() && diffuseCalculator == null); - if (diffuseCalculator == null) { - diffuseCalculator = this.diffuseCalculator; - if (diffuseCalculator == null) { - diffuseCalculator = DiffuseLightCalculator.forCurrentLevel(); - } - } - - final int vertexCount = template.getVertexCount(); - for (int i = 0; i < vertexCount; i++) { - float x = template.getX(i); - float y = template.getY(i); - float z = template.getZ(i); - - pos.set(x, y, z, 1F); - pos.mul(modelMat); - builder.vertex(pos.x(), pos.y(), pos.z()); - - float normalX = template.getNX(i); - float normalY = template.getNY(i); - float normalZ = template.getNZ(i); - - normal.set(normalX, normalY, normalZ); - normal.mul(normalMat); - float nx = normal.x(); - float ny = normal.y(); - float nz = normal.z(); - - byte r, g, b, a; - if (shouldColor) { - r = (byte) this.r; - g = (byte) this.g; - b = (byte) this.b; - a = (byte) this.a; - } else { - r = template.getR(i); - g = template.getG(i); - b = template.getB(i); - a = template.getA(i); - } - if (disableDiffuseMult) { - builder.color(r, g, b, a); - } else { - float instanceDiffuse = diffuseCalculator.getDiffuse(nx, ny, nz, shadedPredicate.test(i)); - int colorR = transformColor(r, instanceDiffuse); - int colorG = transformColor(g, instanceDiffuse); - int colorB = transformColor(b, instanceDiffuse); - builder.color(colorR, colorG, colorB, a); - } - - float u = template.getU(i); - float v = template.getV(i); - if (spriteShiftFunc != null) { - spriteShiftFunc.shift(builder, u, v); - } else { - builder.uv(u, v); - } - - if (hasOverlay) { - builder.overlayCoords(overlay); - } - - int light; - if (useWorldLight) { - lightPos.set(((x - .5f) * 15 / 16f) + .5f, (y - .5f) * 15 / 16f + .5f, (z - .5f) * 15 / 16f + .5f, 1f); - lightPos.mul(localTransforms); - if (lightTransform != null) { - lightPos.mul(lightTransform); - } - - light = getLight(Minecraft.getInstance().level, lightPos); - if (hasCustomLight) { - light = maxLight(light, packedLightCoords); - } - } else if (hasCustomLight) { - light = packedLightCoords; - } else { - light = template.getLight(i); - } - - if (hybridLight) { - builder.uv2(maxLight(light, template.getLight(i))); - } else { - builder.uv2(light); - } - - builder.normal(nx, ny, nz); - - builder.endVertex(); - } - - reset(); - } - - public SuperByteBuffer reset() { - while (!transforms.clear()) - transforms.popPose(); - transforms.pushPose(); - - shouldColor = false; - r = 0; - g = 0; - b = 0; - a = 0; - disableDiffuseMult = false; - diffuseCalculator = null; - spriteShiftFunc = null; - hasOverlay = false; - overlay = OverlayTexture.NO_OVERLAY; - useWorldLight = false; - lightTransform = null; - hasCustomLight = false; - packedLightCoords = 0; - hybridLight = false; - fullNormalTransform = false; - return this; - } - - public boolean isEmpty() { - return template.isEmpty(); - } - - public void delete() { - template.delete(); - } - - public PoseStack getTransforms() { - return transforms; - } - - @Override - public SuperByteBuffer translate(double x, double y, double z) { - transforms.translate(x, y, z); - return this; - } - - @Override - public SuperByteBuffer multiply(Quaternionf quaternion) { - transforms.mulPose(quaternion); - return this; - } - - @Override - public SuperByteBuffer scale(float factorX, float factorY, float factorZ) { - transforms.scale(factorX, factorY, factorZ); - return this; - } - - @Override - public SuperByteBuffer pushPose() { - transforms.pushPose(); - return this; - } - - @Override - public SuperByteBuffer popPose() { - transforms.popPose(); - return this; - } - - @Override - public SuperByteBuffer mulPose(Matrix4f pose) { - transforms.last() - .pose() - .mul(pose); - return this; - } - - @Override - public SuperByteBuffer mulNormal(Matrix3f normal) { - transforms.last() - .normal() - .mul(normal); - return this; - } - - public SuperByteBuffer transform(PoseStack stack) { - transforms.last() - .pose() - .mul(stack.last() - .pose()); - transforms.last() - .normal() - .mul(stack.last() - .normal()); - return this; - } - - public SuperByteBuffer rotateCentered(Direction axis, float radians) { - translate(.5f, .5f, .5f).rotate(axis, radians) - .translate(-.5f, -.5f, -.5f); - return this; - } - - public SuperByteBuffer rotateCentered(Quaternionf q) { - translate(.5f, .5f, .5f).multiply(q) - .translate(-.5f, -.5f, -.5f); - return this; - } - - public SuperByteBuffer color(int r, int g, int b, int a) { - shouldColor = true; - this.r = r; - this.g = g; - this.b = b; - this.a = a; - return this; - } - - public SuperByteBuffer color(int color) { - shouldColor = true; - r = ((color >> 16) & 0xFF); - g = ((color >> 8) & 0xFF); - b = (color & 0xFF); - a = 255; - return this; - } - - public SuperByteBuffer color(Color c) { - return color(c.getRGB()); - } - - /** - * Prevents vertex colors from being multiplied by the diffuse value calculated - * from the final transformed normal vector. Useful for entity rendering, when - * diffuse is applied automatically later. - */ - public SuperByteBuffer disableDiffuse() { - disableDiffuseMult = true; - return this; - } - - public SuperByteBuffer diffuseCalculator(DiffuseLightCalculator diffuseCalculator) { - this.diffuseCalculator = diffuseCalculator; - return this; - } - - public SuperByteBuffer shiftUV(SpriteShiftEntry entry) { - this.spriteShiftFunc = (builder, u, v) -> { - builder.uv(entry.getTargetU(u), entry.getTargetV(v)); - }; - return this; - } - - public SuperByteBuffer shiftUVScrolling(SpriteShiftEntry entry, float scrollV) { - return this.shiftUVScrolling(entry, 0, scrollV); - } - - public SuperByteBuffer shiftUVScrolling(SpriteShiftEntry entry, float scrollU, float scrollV) { - this.spriteShiftFunc = (builder, u, v) -> { - float targetU = u - entry.getOriginal() - .getU0() + entry.getTarget() - .getU0() - + scrollU; - float targetV = v - entry.getOriginal() - .getV0() + entry.getTarget() - .getV0() - + scrollV; - builder.uv(targetU, targetV); - }; - return this; - } - - public SuperByteBuffer shiftUVtoSheet(SpriteShiftEntry entry, float uTarget, float vTarget, int sheetSize) { - this.spriteShiftFunc = (builder, u, v) -> { - float targetU = entry.getTarget() - .getU((SpriteShiftEntry.getUnInterpolatedU(entry.getOriginal(), u) / sheetSize) + uTarget * 16); - float targetV = entry.getTarget() - .getV((SpriteShiftEntry.getUnInterpolatedV(entry.getOriginal(), v) / sheetSize) + vTarget * 16); - builder.uv(targetU, targetV); - }; - return this; - } - - public SuperByteBuffer overlay() { - hasOverlay = true; - return this; - } - - public SuperByteBuffer overlay(int overlay) { - hasOverlay = true; - this.overlay = overlay; - return this; - } - - public SuperByteBuffer light() { - useWorldLight = true; - return this; - } - - public SuperByteBuffer light(Matrix4f lightTransform) { - useWorldLight = true; - this.lightTransform = lightTransform; - return this; - } - - public SuperByteBuffer light(int packedLightCoords) { - hasCustomLight = true; - this.packedLightCoords = packedLightCoords; - return this; - } - - public SuperByteBuffer light(Matrix4f lightTransform, int packedLightCoords) { - light(lightTransform); - light(packedLightCoords); - return this; - } - - /** - * Uses max light from calculated light (world light or custom light) and vertex - * light for the final light value. Ineffective if any other light method was - * not called. - */ - public SuperByteBuffer hybridLight() { - hybridLight = true; - return this; - } - - /** - * Transforms normals not only by the local matrix stack, but also by the passed - * matrix stack. - */ - public SuperByteBuffer fullNormalTransform() { - fullNormalTransform = true; - return this; - } - - public SuperByteBuffer forEntityRender() { - disableDiffuse(); - overlay(); - fullNormalTransform(); - return this; - } - - public static int transformColor(byte component, float scale) { - return Mth.clamp((int) (Byte.toUnsignedInt(component) * scale), 0, 255); - } - - public static int transformColor(int component, float scale) { - return Mth.clamp((int) (component * scale), 0, 255); - } - - public static int maxLight(int packedLight1, int packedLight2) { - int blockLight1 = LightTexture.block(packedLight1); - int skyLight1 = LightTexture.sky(packedLight1); - int blockLight2 = LightTexture.block(packedLight2); - int skyLight2 = LightTexture.sky(packedLight2); - return LightTexture.pack(Math.max(blockLight1, blockLight2), Math.max(skyLight1, skyLight2)); - } - - private static int getLight(Level world, Vector4f lightPos) { - BlockPos pos = BlockPos.containing(lightPos.x(), lightPos.y(), lightPos.z()); - return WORLD_LIGHT_CACHE.computeIfAbsent(pos.asLong(), $ -> LevelRenderer.getLightColor(world, pos)); - } - - @FunctionalInterface - public interface SpriteShiftFunc { - void shift(VertexConsumer builder, float u, float v); - } - - @FunctionalInterface - public interface VertexLighter { - int getPackedLight(float x, float y, float z); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBufferCache.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBufferCache.java deleted file mode 100644 index 980e76d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperByteBufferCache.java +++ /dev/null @@ -1,56 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; - -public class SuperByteBufferCache { - - protected final Map, Cache> caches = new HashMap<>(); - - public synchronized void registerCompartment(Compartment compartment) { - caches.put(compartment, CacheBuilder.newBuilder() - .removalListener(n -> n.getValue().delete()) - .build()); - } - - public synchronized void registerCompartment(Compartment compartment, long ticksUntilExpired) { - caches.put(compartment, CacheBuilder.newBuilder() - .expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS) - .removalListener(n -> n.getValue().delete()) - .build()); - } - - public SuperByteBuffer get(Compartment compartment, T key, Callable callable) { - Cache cache = caches.get(compartment); - if (cache != null) { - try { - return cache.get(key, callable); - } catch (ExecutionException e) { - e.printStackTrace(); - } - } - return null; - } - - public void invalidate(Compartment compartment, T key) { - caches.get(compartment).invalidate(key); - } - - public void invalidate(Compartment compartment) { - caches.get(compartment).invalidateAll(); - } - - public void invalidate() { - caches.forEach((compartment, cache) -> cache.invalidateAll()); - } - - public static class Compartment { - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperRenderTypeBuffer.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperRenderTypeBuffer.java deleted file mode 100644 index 13c8f2b..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/SuperRenderTypeBuffer.java +++ /dev/null @@ -1,92 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - -import java.util.SortedMap; - -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; -import net.minecraft.Util; -import net.minecraft.client.renderer.SectionBufferBuilderPack; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.Sheets; -import net.minecraft.client.resources.model.ModelBakery; - -public class SuperRenderTypeBuffer implements MultiBufferSource { - - private static final SuperRenderTypeBuffer INSTANCE = new SuperRenderTypeBuffer(); - - public static SuperRenderTypeBuffer getInstance() { - return INSTANCE; - } - - private SuperRenderTypeBufferPhase earlyBuffer; - private SuperRenderTypeBufferPhase defaultBuffer; - private SuperRenderTypeBufferPhase lateBuffer; - - public SuperRenderTypeBuffer() { - earlyBuffer = new SuperRenderTypeBufferPhase(); - defaultBuffer = new SuperRenderTypeBufferPhase(); - lateBuffer = new SuperRenderTypeBufferPhase(); - } - - public VertexConsumer getEarlyBuffer(RenderType type) { - return earlyBuffer.bufferSource.getBuffer(type); - } - - @Override - public VertexConsumer getBuffer(RenderType type) { - return defaultBuffer.bufferSource.getBuffer(type); - } - - public VertexConsumer getLateBuffer(RenderType type) { - return lateBuffer.bufferSource.getBuffer(type); - } - - public void draw() { - earlyBuffer.bufferSource.endBatch(); - defaultBuffer.bufferSource.endBatch(); - lateBuffer.bufferSource.endBatch(); - } - - public void draw(RenderType type) { - earlyBuffer.bufferSource.endBatch(type); - defaultBuffer.bufferSource.endBatch(type); - lateBuffer.bufferSource.endBatch(type); - } - - private static class SuperRenderTypeBufferPhase { - - // Visible clones from RenderBuffers - private final SectionBufferBuilderPack fixedBufferPack = new SectionBufferBuilderPack(); - private final SortedMap fixedBuffers = Util.make(new Object2ObjectLinkedOpenHashMap<>(), map -> { - map.put(Sheets.solidBlockSheet(), this.fixedBufferPack.builder(RenderType.solid())); - map.put(Sheets.cutoutBlockSheet(), this.fixedBufferPack.builder(RenderType.cutout())); - map.put(Sheets.bannerSheet(), this.fixedBufferPack.builder(RenderType.cutoutMipped())); - map.put(Sheets.translucentCullBlockSheet(), this.fixedBufferPack.builder(RenderType.translucent())); - put(map, Sheets.shieldSheet()); - put(map, Sheets.bedSheet()); - put(map, Sheets.shulkerBoxSheet()); - put(map, Sheets.signSheet()); - put(map, Sheets.hangingSignSheet()); - map.put(Sheets.chestSheet(), new BufferBuilder(786432)); - put(map, RenderType.armorGlint()); - put(map, RenderType.armorEntityGlint()); - put(map, RenderType.glint()); - put(map, RenderType.glintDirect()); - put(map, RenderType.glintTranslucent()); - put(map, RenderType.entityGlint()); - put(map, RenderType.entityGlintDirect()); - put(map, RenderType.waterMask()); - ModelBakery.DESTROY_TYPES.forEach(p_173062_ -> put(map, p_173062_)); - }); - private final BufferSource bufferSource = MultiBufferSource.immediateWithBuffers(fixedBuffers, new BufferBuilder(256)); - - private static void put(Object2ObjectLinkedOpenHashMap map, RenderType type) { - map.put(type, new BufferBuilder(type.bufferSize())); - } - - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/TileEntityRenderHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/TileEntityRenderHelper.java deleted file mode 100644 index 5e17cbf..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/render/TileEntityRenderHelper.java +++ /dev/null @@ -1,113 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.render; - -import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; -import com.jozufozu.flywheel.config.BackendType; -import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld; -import com.jozufozu.flywheel.util.transform.TransformStack; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import nl.requios.effortlessbuilding.create.Create; -import nl.requios.effortlessbuilding.create.foundation.utility.AnimationTickHolder; -import nl.requios.effortlessbuilding.create.foundation.utility.RegisteredObjects; -import org.joml.Matrix4f; -import org.joml.Vector4f; - -import javax.annotation.Nullable; -import java.util.Iterator; - -public class TileEntityRenderHelper { - - public static void renderTileEntities(Level world, Iterable customRenderTEs, PoseStack ms, - MultiBufferSource buffer) { - renderTileEntities(world, null, customRenderTEs, ms, null, buffer); - } - - public static void renderTileEntities(Level world, Iterable customRenderTEs, PoseStack ms, - MultiBufferSource buffer, float pt) { - renderTileEntities(world, null, customRenderTEs, ms, null, buffer, pt); - } - - public static void renderTileEntities(Level world, @Nullable VirtualRenderWorld renderWorld, - Iterable customRenderTEs, PoseStack ms, @Nullable Matrix4f lightTransform, MultiBufferSource buffer) { - renderTileEntities(world, renderWorld, customRenderTEs, ms, lightTransform, buffer, - AnimationTickHolder.getPartialTicks()); - } - - public static void renderTileEntities(Level world, @Nullable VirtualRenderWorld renderWorld, - Iterable customRenderTEs, PoseStack ms, @Nullable Matrix4f lightTransform, MultiBufferSource buffer, - float pt) { - Iterator iterator = customRenderTEs.iterator(); - while (iterator.hasNext()) { - BlockEntity tileEntity = iterator.next(); - if (Backend.getBackendType() == BackendType.INSTANCING && Backend.isFlywheelWorld(renderWorld) && InstancedRenderRegistry.shouldSkipRender(tileEntity)) - continue; - - BlockEntityRenderer renderer = Minecraft.getInstance().getBlockEntityRenderDispatcher().getRenderer(tileEntity); - if (renderer == null) { - iterator.remove(); - continue; - } - - BlockPos pos = tileEntity.getBlockPos(); - ms.pushPose(); - TransformStack.cast(ms) - .translate(pos); - - try { - int worldLight = getCombinedLight(world, getLightPos(lightTransform, pos), renderWorld, pos); - - if (renderWorld != null) { - // Swap the real world for the render world so that the renderer gets contraption-local information - tileEntity.setLevel(renderWorld); - renderer.render(tileEntity, pt, ms, buffer, worldLight, OverlayTexture.NO_OVERLAY); - tileEntity.setLevel(world); - } else { - renderer.render(tileEntity, pt, ms, buffer, worldLight, OverlayTexture.NO_OVERLAY); - } - - } catch (Exception e) { - iterator.remove(); - - String message = "BlockEntity " + RegisteredObjects.getKeyOrThrow(tileEntity.getType()) - .toString() + " could not be rendered virtually."; -// if (AllConfigs.CLIENT.explainRenderErrors.get()) - Create.LOGGER.error(message, e); -// else -// Create.LOGGER.error(message); - } - - ms.popPose(); - } - } - - private static BlockPos getLightPos(@Nullable Matrix4f lightTransform, BlockPos contraptionPos) { - if (lightTransform != null) { - Vector4f lightVec = new Vector4f(contraptionPos.getX() + .5f, contraptionPos.getY() + .5f, contraptionPos.getZ() + .5f, 1); - lightVec.mul(lightTransform); - return BlockPos.containing(lightVec.x(), lightVec.y(), lightVec.z()); - } else { - return contraptionPos; - } - } - - public static int getCombinedLight(Level world, BlockPos worldPos, @Nullable VirtualRenderWorld renderWorld, - BlockPos renderWorldPos) { - int worldLight = LevelRenderer.getLightColor(world, worldPos); - - if (renderWorld != null) { - int renderWorldLight = LevelRenderer.getLightColor(renderWorld, renderWorldPos); - return SuperByteBuffer.maxLight(worldLight, renderWorldLight); - } - - return worldLight; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AngleHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AngleHelper.java deleted file mode 100644 index 3855074..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AngleHelper.java +++ /dev/null @@ -1,52 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.util.Mth; - -public class AngleHelper { - - public static float horizontalAngle(Direction facing) { - if (facing.getAxis().isVertical()) - return 0; - float angle = facing.toYRot(); - if (facing.getAxis() == Axis.X) - angle = -angle; - return angle; - } - - public static float verticalAngle(Direction facing) { - return facing == Direction.UP ? -90 : facing == Direction.DOWN ? 90 : 0; - } - - public static float rad(double angle) { - if (angle == 0) - return 0; - return (float) (angle / 180 * Math.PI); - } - - public static float deg(double angle) { - if (angle == 0) - return 0; - return (float) (angle * 180 / Math.PI); - } - - public static float angleLerp(double pct, double current, double target) { - return (float) (current + getShortestAngleDiff(current, target) * pct); - } - - public static float getShortestAngleDiff(double current, double target) { - current = current % 360; - target = target % 360; - return (float) (((((target - current) % 360) + 540) % 360) - 180); - } - - public static float getShortestAngleDiff(double current, double target, float hint) { - float diff = getShortestAngleDiff(current, target); - if (Mth.equal(Math.abs(diff), 180) && Math.signum(diff) != Math.signum(hint)) { - return diff + 360*Math.signum(hint); - } - return diff; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AnimationTickHolder.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AnimationTickHolder.java deleted file mode 100644 index 6269bad..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/AnimationTickHolder.java +++ /dev/null @@ -1,56 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers.WrappedClientWorld; -import net.minecraft.client.Minecraft; -import net.minecraft.world.level.LevelAccessor; - -public class AnimationTickHolder { - - private static int ticks; - private static int pausedTicks; - - public static void reset() { - ticks = 0; - pausedTicks = 0; - } - - public static void tick() { - if (!Minecraft.getInstance() - .isPaused()) { - ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision - } else { - pausedTicks = (pausedTicks + 1) % 1_728_000; - } - } - - public static int getTicks() { - return getTicks(false); - } - - public static int getTicks(boolean includePaused) { - return includePaused ? ticks + pausedTicks : ticks; - } - - public static float getRenderTime() { - return getTicks() + getPartialTicks(); - } - - public static float getPartialTicks() { - Minecraft mc = Minecraft.getInstance(); - return (mc.isPaused() ? mc.pausePartialTick : mc.getFrameTime()); - } - - public static int getTicks(LevelAccessor world) { - if (world instanceof WrappedClientWorld) - return getTicks(((WrappedClientWorld) world).getWrappedWorld()); - return getTicks(); - } - - public static float getRenderTime(LevelAccessor world) { - return getTicks(world) + getPartialTicks(world); - } - - public static float getPartialTicks(LevelAccessor world) { - return getPartialTicks(); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BBHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BBHelper.java deleted file mode 100644 index 7b9ee4a..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BBHelper.java +++ /dev/null @@ -1,20 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.levelgen.structure.BoundingBox; - -public class BBHelper { - - public static BoundingBox encapsulate(BoundingBox bb, BlockPos pos) { - return new BoundingBox(Math.min(bb.minX(), pos.getX()), Math.min(bb.minY(), pos.getY()), - Math.min(bb.minZ(), pos.getZ()), Math.max(bb.maxX(), pos.getX()), Math.max(bb.maxY(), pos.getY()), - Math.max(bb.maxZ(), pos.getZ())); - } - - public static BoundingBox encapsulate(BoundingBox bb, BoundingBox bb2) { - return new BoundingBox(Math.min(bb.minX(), bb2.minX()), Math.min(bb.minY(), bb2.minY()), - Math.min(bb.minZ(), bb2.minZ()), Math.max(bb.maxX(), bb2.maxX()), Math.max(bb.maxY(), bb2.maxY()), - Math.max(bb.maxZ(), bb2.maxZ())); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockFace.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockFace.java deleted file mode 100644 index 925af11..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockFace.java +++ /dev/null @@ -1,52 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; - -public class BlockFace extends Pair { - - public BlockFace(BlockPos first, Direction second) { - super(first, second); - } - - public boolean isEquivalent(BlockFace other) { - if (equals(other)) - return true; - return getConnectedPos().equals(other.getPos()) && getPos().equals(other.getConnectedPos()); - } - - public BlockPos getPos() { - return getFirst(); - } - - public Direction getFace() { - return getSecond(); - } - - public Direction getOppositeFace() { - return getSecond().getOpposite(); - } - - public BlockFace getOpposite() { - return new BlockFace(getConnectedPos(), getOppositeFace()); - } - - public BlockPos getConnectedPos() { - return getPos().relative(getFace()); - } - - public CompoundTag serializeNBT() { - CompoundTag compoundNBT = new CompoundTag(); - compoundNBT.put("Pos", NbtUtils.writeBlockPos(getPos())); - NBTHelper.writeEnum(compoundNBT, "Face", getFace()); - return compoundNBT; - } - - public static BlockFace fromNBT(CompoundTag compound) { - return new BlockFace(NbtUtils.readBlockPos(compound.getCompound("Pos")), - NBTHelper.readEnum(compound, "Face", Direction.class)); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockHelper.java index 9e6a3ab..1d1f817 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/BlockHelper.java @@ -1,7 +1,10 @@ package nl.requios.effortlessbuilding.create.foundation.utility; +import net.createmod.catnip.nbt.NBTProcessors; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.SectionPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.registries.Registries; @@ -16,6 +19,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.GameRules; @@ -29,19 +33,41 @@ import net.minecraft.world.level.block.SlimeBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.material.FluidState; -import net.neoforged.neoforge.common.IPlantable; import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.common.SpecialPlantable; +import net.neoforged.neoforge.event.level.BlockDropsEvent; import net.neoforged.neoforge.event.level.BlockEvent; import javax.annotation.Nullable; +import java.util.List; import java.util.function.Consumer; public class BlockHelper { + private static final List COUNT_STATES = List.of( + BlockStateProperties.EGGS, + BlockStateProperties.PICKLES, + BlockStateProperties.CANDLES + ); + + private static final List VINELIKE_BLOCKS = List.of( + Blocks.VINE, Blocks.GLOW_LICHEN + ); + + private static final List VINELIKE_STATES = List.of( + BlockStateProperties.UP, + BlockStateProperties.NORTH, + BlockStateProperties.EAST, + BlockStateProperties.SOUTH, + BlockStateProperties.WEST, + BlockStateProperties.DOWN + ); public static BlockState setZeroAge(BlockState blockState) { if (blockState.hasProperty(BlockStateProperties.AGE_1)) @@ -78,44 +104,54 @@ public class BlockHelper { Item required = getRequiredItem(block).getItem(); boolean needsTwo = block.hasProperty(BlockStateProperties.SLAB_TYPE) - && block.getValue(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE; + && block.getValue(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE; if (needsTwo) amount *= 2; - if (block.hasProperty(BlockStateProperties.EGGS)) - amount *= block.getValue(BlockStateProperties.EGGS); + for (IntegerProperty property : COUNT_STATES) + if (block.hasProperty(property)) + amount *= block.getValue(property); - if (block.hasProperty(BlockStateProperties.PICKLES)) - amount *= block.getValue(BlockStateProperties.PICKLES); + if (VINELIKE_BLOCKS.contains(block.getBlock())) { + int vineCount = 0; + + for (BooleanProperty vineState : VINELIKE_STATES) { + if (block.hasProperty(vineState) && block.getValue(vineState)) { + vineCount++; + } + } + + amount += vineCount - 1; + } { // Try held Item first int preferredSlot = player.getInventory().selected; ItemStack itemstack = player.getInventory() - .getItem(preferredSlot); + .getItem(preferredSlot); int count = itemstack.getCount(); if (itemstack.getItem() == required && count > 0) { int taken = Math.min(count, amount - amountFound); player.getInventory() - .setItem(preferredSlot, new ItemStack(itemstack.getItem(), count - taken)); + .setItem(preferredSlot, new ItemStack(itemstack.getItem(), count - taken)); amountFound += taken; } } // Search inventory for (int i = 0; i < player.getInventory() - .getContainerSize(); ++i) { + .getContainerSize(); ++i) { if (amountFound == amount) break; ItemStack itemstack = player.getInventory() - .getItem(i); + .getItem(i); int count = itemstack.getCount(); if (itemstack.getItem() == required && count > 0) { int taken = Math.min(count, amount - amountFound); player.getInventory() - .setItem(i, new ItemStack(itemstack.getItem(), count - taken)); + .setItem(i, new ItemStack(itemstack.getItem(), count - taken)); amountFound += taken; } } @@ -124,7 +160,7 @@ public class BlockHelper { // Give back 1 if uneven amount was removed if (amountFound % 2 != 0) player.getInventory() - .add(new ItemStack(required)); + .add(new ItemStack(required)); amountFound /= 2; } @@ -144,68 +180,74 @@ public class BlockHelper { } public static void destroyBlock(Level world, BlockPos pos, float effectChance, - Consumer droppedItemCallback) { + Consumer droppedItemCallback) { destroyBlockAs(world, pos, null, ItemStack.EMPTY, effectChance, droppedItemCallback); } public static boolean destroyBlockAs(Level world, BlockPos pos, @Nullable Player player, ItemStack usedTool, - float effectChance, Consumer droppedItemCallback) { + float effectChance, Consumer droppedItemCallback) { FluidState fluidState = world.getFluidState(pos); BlockState state = world.getBlockState(pos); - + if (world.random.nextFloat() < effectChance) world.levelEvent(2001, pos, Block.getId(state)); - BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null; - + BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null; + if (player != null) { BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, pos, state, player); NeoForge.EVENT_BUS.post(event); if (event.isCanceled()) return false; - if (event.getExpToDrop() > 0 && world instanceof ServerLevel) - state.getBlock() - .popExperience((ServerLevel) world, pos, event.getExpToDrop()); - usedTool.mineBlock(world, state, pos, player); player.awardStat(Stats.BLOCK_MINED.get(state.getBlock())); } - if (world instanceof ServerLevel && world.getGameRules() - .getBoolean(GameRules.RULE_DOBLOCKDROPS) && !world.restoringBlockSnapshots - && (player == null || !player.isCreative())) { - for (ItemStack itemStack : Block.getDrops(state, (ServerLevel) world, pos, tileentity, player, usedTool)) + if (world instanceof ServerLevel serverLevel && world.getGameRules() + .getBoolean(GameRules.RULE_DOBLOCKDROPS) && !world.restoringBlockSnapshots + && (player == null || !player.isCreative())) { + List drops = Block.getDrops(state, serverLevel, pos, blockEntity, player, usedTool); + if (player != null) { + BlockDropsEvent event = new BlockDropsEvent(serverLevel, pos, state, blockEntity, List.of(), player, usedTool); + NeoForge.EVENT_BUS.post(event); + if (!event.isCanceled()) { + if ( event.getDroppedExperience() > 0) + state.getBlock().popExperience(serverLevel, pos, event.getDroppedExperience()); + } + } + for (ItemStack itemStack : drops) droppedItemCallback.accept(itemStack); // Simulating IceBlock#playerDestroy. Not calling method directly as it would drop item // entities as a side-effect - if (state.getBlock() instanceof IceBlock && usedTool.getEnchantmentLevel(Enchantments.SILK_TOUCH) == 0) { + Registry enchantmentRegistry = world.registryAccess().registryOrThrow(Registries.ENCHANTMENT); + if (state.getBlock() instanceof IceBlock && usedTool.getEnchantmentLevel(enchantmentRegistry.getHolderOrThrow(Enchantments.SILK_TOUCH)) == 0) { if (world.dimensionType() - .ultraWarm()) + .ultraWarm()) return false; - BlockState belowState = world.getBlockState(pos.below()); - if (belowState.blocksMotion() || belowState.liquid()) + BlockState blockstate = world.getBlockState(pos.below()); + if (blockstate.blocksMotion() || blockstate.liquid()) world.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); - return true; + return false; } state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true); } - + world.setBlockAndUpdate(pos, fluidState.createLegacyBlock()); return true; } public static boolean isSolidWall(BlockGetter reader, BlockPos fromPos, Direction toDirection) { return hasBlockSolidSide(reader.getBlockState(fromPos.relative(toDirection)), reader, - fromPos.relative(toDirection), toDirection.getOpposite()); + fromPos.relative(toDirection), toDirection.getOpposite()); } public static boolean noCollisionInSpace(BlockGetter reader, BlockPos pos) { return reader.getBlockState(pos) - .getCollisionShape(reader, pos) - .isEmpty(); + .getCollisionShape(reader, pos) + .isEmpty(); } private static void placeRailWithoutUpdate(Level world, BlockState state, BlockPos target) { @@ -218,18 +260,33 @@ public class BlockHelper { chunk.getSections()[idx] = chunksection; } BlockState old = chunksection.setBlockState(SectionPos.sectionRelative(target.getX()), - SectionPos.sectionRelative(target.getY()), SectionPos.sectionRelative(target.getZ()), state); + SectionPos.sectionRelative(target.getY()), SectionPos.sectionRelative(target.getZ()), state); chunk.setUnsaved(true); world.markAndNotifyBlock(target, chunk, old, state, 82, 512); world.setBlock(target, state, 82); world.neighborChanged(target, world.getBlockState(target.below()) - .getBlock(), target.below()); + .getBlock(), target.below()); } - public static boolean placeSchematicBlock(Level world, Player player, BlockState state, BlockPos target, ItemStack stack, - @Nullable CompoundTag data) { - BlockEntity existingTile = world.getBlockEntity(target); + public static CompoundTag prepareBlockEntityData(BlockState blockState, BlockEntity blockEntity) { + CompoundTag data = null; + if (blockEntity == null) + return null; + RegistryAccess access = blockEntity.getLevel().registryAccess(); + if (blockEntity instanceof IPartialSafeNBT safeNbtBE) { + data = new CompoundTag(); + safeNbtBE.writeSafe(data, access); + data = NBTProcessors.process(blockState, blockEntity, data, true); + } + + return data; + } + + public static void placeSchematicBlock(Level world, BlockState state, BlockPos target, ItemStack stack, + @Nullable CompoundTag data) { + BlockEntity existingBlockEntity = world.getBlockEntity(target); + boolean alreadyPlaced = false; // Piston if (state.hasProperty(BlockStateProperties.EXTENDED)) @@ -239,58 +296,69 @@ public class BlockHelper { if (state.getBlock() == Blocks.COMPOSTER) state = Blocks.COMPOSTER.defaultBlockState(); - else if (state.getBlock() != Blocks.SEA_PICKLE && state.getBlock() instanceof IPlantable) - state = ((IPlantable) state.getBlock()).getPlant(world, target); + else if (state.getBlock() != Blocks.SEA_PICKLE && state.getBlock() instanceof SpecialPlantable specialPlantable) { + alreadyPlaced = true; + if (specialPlantable.canPlacePlantAtPosition(stack, world, target, null)) + specialPlantable.spawnPlantAtPosition(stack, world, target, null); + } else if (state.is(BlockTags.CAULDRONS)) state = Blocks.CAULDRON.defaultBlockState(); if (world.dimensionType() - .ultraWarm() && state.getFluidState().is(FluidTags.WATER)) { + .ultraWarm() && state.getFluidState().is(FluidTags.WATER)) { int i = target.getX(); int j = target.getY(); int k = target.getZ(); world.playSound(null, target, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, - 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); + 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); for (int l = 0; l < 8; ++l) { world.addParticle(ParticleTypes.LARGE_SMOKE, i + Math.random(), j + Math.random(), k + Math.random(), - 0.0D, 0.0D, 0.0D); + 0.0D, 0.0D, 0.0D); } Block.dropResources(state, world, target); - return true; + return; } - if (state.getBlock() instanceof BaseRailBlock) { + //noinspection StatementWithEmptyBody + if (alreadyPlaced) { + // pass + } else if (state.getBlock() instanceof BaseRailBlock) { placeRailWithoutUpdate(world, state, target); } else { - world.setBlock(target, state, 2); //Changed flag from 18 to 3 + world.setBlock(target, state, 18); } if (data != null) { -// if (existingTile instanceof IMergeableTE mergeable) { -// BlockEntity loaded = BlockEntity.loadStatic(target, state, data); -// if (existingTile.getType() -// .equals(loaded.getType())) { -// mergeable.accept(loaded); -// return; +// if (existingBlockEntity instanceof IMergeableBE mergeable) { +// BlockEntity loaded = BlockEntity.loadStatic(target, state, data, world.registryAccess()); +// if (loaded != null) { +// if (existingBlockEntity.getType() +// .equals(loaded.getType())) { +// mergeable.accept(loaded); +// return; +// } // } // } - BlockEntity tile = world.getBlockEntity(target); - if (tile != null) { + BlockEntity blockEntity = world.getBlockEntity(target); + if (blockEntity != null) { data.putInt("x", target.getX()); data.putInt("y", target.getY()); data.putInt("z", target.getZ()); -// if (tile instanceof KineticTileEntity) -// ((KineticTileEntity) tile).warnOfMovement(); - tile.load(data); +// if (blockEntity instanceof KineticBlockEntity kbe) +// kbe.warnOfMovement(); +// if (blockEntity instanceof IMultiBlockEntityContainer imbe) +// if (!imbe.isController()) +// data.put("Controller", NbtUtils.writeBlockPos(imbe.getController())); + blockEntity.loadWithComponents(data, world.registryAccess()); } } try { - state.getBlock().setPlacedBy(world, target, state, null, stack); - } catch (Exception ignored) { + state.getBlock() + .setPlacedBy(world, target, state, null, stack); + } catch (Exception e) { } - return true; } public static double getBounceMultiplier(Block block) { @@ -302,22 +370,9 @@ public class BlockHelper { } public static boolean hasBlockSolidSide(BlockState p_220056_0_, BlockGetter p_220056_1_, BlockPos p_220056_2_, - Direction p_220056_3_) { + Direction p_220056_3_) { return !p_220056_0_.is(BlockTags.LEAVES) - && Block.isFaceFull(p_220056_0_.getCollisionShape(p_220056_1_, p_220056_2_), p_220056_3_); - } - - public static boolean extinguishFire(Level world, @Nullable Player p_175719_1_, BlockPos p_175719_2_, - Direction p_175719_3_) { - p_175719_2_ = p_175719_2_.relative(p_175719_3_); - if (world.getBlockState(p_175719_2_) - .getBlock() == Blocks.FIRE) { - world.levelEvent(p_175719_1_, 1009, p_175719_2_, 0); - world.removeBlock(p_175719_2_, false); - return true; - } else { - return false; - } + && Block.isFaceFull(p_220056_0_.getCollisionShape(p_220056_1_, p_220056_2_), p_220056_3_); } public static BlockState copyProperties(BlockState fromState, BlockState toState) { @@ -328,7 +383,7 @@ public class BlockHelper { } public static > BlockState copyProperty(Property property, BlockState fromState, - BlockState toState) { + BlockState toState) { if (fromState.hasProperty(property) && toState.hasProperty(property)) { return toState.setValue(property, fromState.getValue(property)); } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CameraAngleAnimationService.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CameraAngleAnimationService.java index 5148b13..bae9b3f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CameraAngleAnimationService.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CameraAngleAnimationService.java @@ -1,6 +1,7 @@ package nl.requios.effortlessbuilding.create.foundation.utility; -import nl.requios.effortlessbuilding.create.foundation.utility.animation.LerpedFloat; +import net.createmod.catnip.animation.LerpedFloat; +import net.createmod.catnip.math.AngleHelper; import net.minecraft.client.Minecraft; import net.minecraft.util.Mth; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Color.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Color.java deleted file mode 100644 index 8fba9e5..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Color.java +++ /dev/null @@ -1,310 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import com.google.common.hash.Hashing; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.Vec3; -import org.joml.Vector3f; - -import javax.annotation.Nonnull; -import java.util.function.UnaryOperator; - -public class Color { - public final static Color TRANSPARENT_BLACK = new Color(0, 0, 0, 0).setImmutable(); - public final static Color BLACK = new Color(0, 0, 0).setImmutable(); - public final static Color WHITE = new Color(255, 255, 255).setImmutable(); - public final static Color RED = new Color(255, 0, 0).setImmutable(); - public final static Color GREEN = new Color(0, 255, 0).setImmutable(); - public final static Color SPRING_GREEN = new Color(0, 255, 187).setImmutable(); - - protected boolean mutable = true; - protected int value; - - public Color(int r, int g, int b) { - this(r, g, b, 0xff); - } - - public Color(int r, int g, int b, int a) { - value = ((a & 0xff) << 24) | - ((r & 0xff) << 16) | - ((g & 0xff) << 8) | - ((b & 0xff) << 0); - } - - public Color(float r, float g, float b, float a) { - this( - (int) (0.5 + 0xff * Mth.clamp(r, 0, 1)), - (int) (0.5 + 0xff * Mth.clamp(g, 0, 1)), - (int) (0.5 + 0xff * Mth.clamp(b, 0, 1)), - (int) (0.5 + 0xff * Mth.clamp(a, 0, 1)) - ); - } - - public Color(int rgba) { - value = rgba; - } - - public Color(int rgb, boolean hasAlpha) { - if (hasAlpha) { - value = rgb; - } else { - value = rgb | 0xff_000000; - } - } - - public Color copy() { - return copy(true); - } - - public Color copy(boolean mutable) { - if (mutable) - return new Color(value); - else - return new Color(value).setImmutable(); - } - - /** - * Mark this color as immutable. Attempting to mutate this color in the future - * will instead cause a copy to be created that can me modified. - */ - public Color setImmutable() { - this.mutable = false; - return this; - } - - /** - * @return the red component in the range 0-255. - * @see #getRGB - */ - public int getRed() { - return (getRGB() >> 16) & 0xff; - } - - /** - * @return the green component in the range 0-255. - * @see #getRGB - */ - public int getGreen() { - return (getRGB() >> 8) & 0xff; - } - - /** - * @return the blue component in the range 0-255. - * @see #getRGB - */ - public int getBlue() { - return (getRGB() >> 0) & 0xff; - } - - /** - * @return the alpha component in the range 0-255. - * @see #getRGB - */ - public int getAlpha() { - return (getRGB() >> 24) & 0xff; - } - - /** - * @return the red component in the range 0-1f. - */ - public float getRedAsFloat() { - return getRed() / 255f; - } - - /** - * @return the green component in the range 0-1f. - */ - public float getGreenAsFloat() { - return getGreen() / 255f; - } - - /** - * @return the blue component in the range 0-1f. - */ - public float getBlueAsFloat() { - return getBlue() / 255f; - } - - /** - * @return the alpha component in the range 0-1f. - */ - public float getAlphaAsFloat() { - return getAlpha() / 255f; - } - - /** - * Returns the RGB value representing this color - * (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are blue). - * @return the RGB value of the color - */ - public int getRGB() { - return value; - } - - public Vec3 asVector() { - return new Vec3(getRedAsFloat(), getGreenAsFloat(), getBlueAsFloat()); - } - - public Vector3f asVectorF() { - return new Vector3f(getRedAsFloat(), getGreenAsFloat(), getBlueAsFloat()); - } - - public Color setRed(int r) { - return ensureMutable().setRedUnchecked(r); - } - - public Color setGreen(int g) { - return ensureMutable().setGreenUnchecked(g); - } - - public Color setBlue(int b) { - return ensureMutable().setBlueUnchecked(b); - } - - public Color setAlpha(int a) { - return ensureMutable().setAlphaUnchecked(a); - } - - public Color setRed(float r) { - return ensureMutable().setRedUnchecked((int) (0xff * Mth.clamp(r, 0, 1))); - } - - public Color setGreen(float g) { - return ensureMutable().setGreenUnchecked((int) (0xff * Mth.clamp(g, 0, 1))); - } - - public Color setBlue(float b) { - return ensureMutable().setBlueUnchecked((int) (0xff * Mth.clamp(b, 0, 1))); - } - - public Color setAlpha(float a) { - return ensureMutable().setAlphaUnchecked((int) (0xff * Mth.clamp(a, 0, 1))); - } - - public Color scaleAlpha(float factor) { - return ensureMutable().setAlphaUnchecked((int) (getAlpha() * Mth.clamp(factor, 0, 1))); - } - - public Color mixWith(Color other, float weight) { - return ensureMutable() - .setRedUnchecked((int) (getRed() + (other.getRed() - getRed()) * weight)) - .setGreenUnchecked((int) (getGreen() + (other.getGreen() - getGreen()) * weight)) - .setBlueUnchecked((int) (getBlue() + (other.getBlue() - getBlue()) * weight)) - .setAlphaUnchecked((int) (getAlpha() + (other.getAlpha() - getAlpha()) * weight)); - } - - public Color darker() { - int a = getAlpha(); - return ensureMutable().mixWith(BLACK, .25f).setAlphaUnchecked(a); - } - - public Color brighter() { - int a = getAlpha(); - return ensureMutable().mixWith(WHITE, .25f).setAlphaUnchecked(a); - } - - public Color setValue(int value) { - return ensureMutable().setValueUnchecked(value); - } - - public Color modifyValue(UnaryOperator function) { - int newValue = function.apply(value); - if (newValue == value) - return this; - - return ensureMutable().setValueUnchecked(newValue); - } - - // ********* // - - protected Color ensureMutable() { - if (this.mutable) - return this; - - return new Color(this.value); - } - - protected Color setRedUnchecked(int r) { - this.value = (this.value & 0xff_00ffff) | ((r & 0xff) << 16); - return this; - } - - protected Color setGreenUnchecked(int g) { - this.value = (this.value & 0xff_ff00ff) | ((g & 0xff) << 8); - return this; - } - - protected Color setBlueUnchecked(int b) { - this.value = (this.value & 0xff_ffff00) | ((b & 0xff) << 0); - return this; - } - - protected Color setAlphaUnchecked(int a) { - this.value = (this.value & 0x00_ffffff) | ((a & 0xff) << 24); - return this; - } - - protected Color setValueUnchecked(int value) { - this.value = value; - return this; - } - - // ********* // - - public static Color mixColors(@Nonnull Color c1, @Nonnull Color c2, float w) { - return new Color( - (int) (c1.getRed() + (c2.getRed() - c1.getRed()) * w), - (int) (c1.getGreen() + (c2.getGreen() - c1.getGreen()) * w), - (int) (c1.getBlue() + (c2.getBlue() - c1.getBlue()) * w), - (int) (c1.getAlpha() + (c2.getAlpha() - c1.getAlpha()) * w) - ); - } - - public static Color mixColors(@Nonnull Couple colors, float w) { - return mixColors(colors.getFirst(), colors.getSecond(), w); - } - - public static int mixColors(int color1, int color2, float w) { - int a1 = (color1 >> 24); - int r1 = (color1 >> 16) & 0xFF; - int g1 = (color1 >> 8) & 0xFF; - int b1 = color1 & 0xFF; - int a2 = (color2 >> 24); - int r2 = (color2 >> 16) & 0xFF; - int g2 = (color2 >> 8) & 0xFF; - int b2 = color2 & 0xFF; - - return - ((int) (a1 + (a2 - a1) * w) << 24) + - ((int) (r1 + (r2 - r1) * w) << 16) + - ((int) (g1 + (g2 - g1) * w) << 8) + - ((int) (b1 + (b2 - b1) * w) << 0); - } - - public static Color rainbowColor(int timeStep) { - int localTimeStep = Math.abs(timeStep) % 1536; - int timeStepInPhase = localTimeStep % 256; - int phaseBlue = localTimeStep / 256; - int red = colorInPhase(phaseBlue + 4, timeStepInPhase); - int green = colorInPhase(phaseBlue + 2, timeStepInPhase); - int blue = colorInPhase(phaseBlue, timeStepInPhase); - return new Color(red, green, blue); - } - - private static int colorInPhase(int phase, int progress) { - phase = phase % 6; - if (phase <= 1) - return 0; - if (phase == 2) - return progress; - if (phase <= 4) - return 255; - else - return 255 - progress; - } - - public static Color generateFromLong(long l) { - return rainbowColor(Hashing.crc32().hashLong(l).asInt()) - .mixWith(WHITE, 0.5f); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ColorHandlers.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ColorHandlers.java deleted file mode 100644 index cec8e18..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ColorHandlers.java +++ /dev/null @@ -1,26 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.client.color.block.BlockColor; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.renderer.BiomeColors; -import net.minecraft.world.level.GrassColor; -import net.minecraft.world.level.block.RedStoneWireBlock; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; - -public class ColorHandlers { - - public static BlockColor getGrassyBlock() { - return (state, world, pos, layer) -> pos != null && world != null ? BiomeColors.getAverageGrassColor(world, pos) - : GrassColor.get(0.5D, 1.0D); - } - - public static ItemColor getGrassyItem() { - return (stack, layer) -> GrassColor.get(0.5D, 1.0D); - } - - public static BlockColor getRedstonePower() { - return (state, world, pos, layer) -> RedStoneWireBlock - .getColorForPower(pos != null && world != null ? state.getValue(BlockStateProperties.POWER) : 0); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Couple.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Couple.java deleted file mode 100644 index d04238b..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Couple.java +++ /dev/null @@ -1,151 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import com.google.common.collect.ImmutableList; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; - -import java.util.Iterator; -import java.util.List; -import java.util.function.*; -import java.util.stream.Stream; - -public class Couple extends Pair implements Iterable { - - private static final Couple TRUE_AND_FALSE = Couple.create(true, false); - - protected Couple(T first, T second) { - super(first, second); - } - - public static Couple create(T first, T second) { - return new Couple<>(first, second); - } - - public static Couple create(Supplier factory) { - return new Couple<>(factory.get(), factory.get()); - } - - public static Couple createWithContext(Function factory) { - return new Couple<>(factory.apply(true), factory.apply(false)); - } - - public T get(boolean first) { - return first ? getFirst() : getSecond(); - } - - public void set(boolean first, T value) { - if (first) - setFirst(value); - else - setSecond(value); - } - - @Override - public Couple copy() { - return create(first, second); - } - - public Couple map(Function function) { - return Couple.create(function.apply(first), function.apply(second)); - } - - public Couple mapWithContext(BiFunction function) { - return Couple.create(function.apply(first, true), function.apply(second, false)); - } - - public Couple mapWithParams(BiFunction function, Couple values) { - return Couple.create(function.apply(first, values.first), function.apply(second, values.second)); - } - - public Couple mapNotNullWithParam(BiFunction function, R value) { - return Couple.create(first != null ? function.apply(first, value) : null, - second != null ? function.apply(second, value) : null); - } - - public boolean both(Predicate test) { - return test.test(getFirst()) && test.test(getSecond()); - } - - public boolean either(Predicate test) { - return test.test(getFirst()) || test.test(getSecond()); - } - - public void replace(Function function) { - setFirst(function.apply(getFirst())); - setSecond(function.apply(getSecond())); - } - - public void replaceWithContext(BiFunction function) { - replaceWithParams(function, TRUE_AND_FALSE); - } - - public void replaceWithParams(BiFunction function, Couple values) { - setFirst(function.apply(getFirst(), values.getFirst())); - setSecond(function.apply(getSecond(), values.getSecond())); - } - - @Override - public void forEach(Consumer consumer) { - consumer.accept(getFirst()); - consumer.accept(getSecond()); - } - - public void forEachWithContext(BiConsumer consumer) { - forEachWithParams(consumer, TRUE_AND_FALSE); - } - - public void forEachWithParams(BiConsumer function, Couple values) { - function.accept(getFirst(), values.getFirst()); - function.accept(getSecond(), values.getSecond()); - } - - public Couple swap() { - return Couple.create(second, first); - } - - public ListTag serializeEach(Function serializer) { - return NBTHelper.writeCompoundList(ImmutableList.of(first, second), serializer); - } - - public static Couple deserializeEach(ListTag list, Function deserializer) { - List readCompoundList = NBTHelper.readCompoundList(list, deserializer); - return new Couple<>(readCompoundList.get(0), readCompoundList.get(1)); - } - - @Override - public Iterator iterator() { - return new Couplerator<>(this); - } - - public Stream stream() { - return Stream.of(first, second); - } - - private static class Couplerator implements Iterator { - - int state; - private final Couple couple; - - public Couplerator(Couple couple) { - this.couple = couple; - state = 0; - } - - @Override - public boolean hasNext() { - return state != 2; - } - - @Override - public T next() { - state++; - if (state == 1) - return couple.first; - if (state == 2) - return couple.second; - return null; - } - - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CreateRegistry.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CreateRegistry.java deleted file mode 100644 index 8b5aefc..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/CreateRegistry.java +++ /dev/null @@ -1,101 +0,0 @@ -//package nl.requios.effortlessbuilding.create.foundation.utility; -// -//import net.minecraft.resources.ResourceLocation; -//import net.neoforged.neoforge.registries.IForgeRegistry; -//import nl.requios.effortlessbuilding.create.Create; -//import org.jetbrains.annotations.Nullable; -// -//import java.util.*; -// -//public class CreateRegistry { -// private static final List> ALL = new ArrayList<>(); -// -// protected final IForgeRegistry objectRegistry; -// protected final Map locationMap = new HashMap<>(); -// protected final Map objectMap = new IdentityHashMap<>(); -// protected boolean unwrapped = false; -// -// public CreateRegistry(IForgeRegistry objectRegistry) { -// this.objectRegistry = objectRegistry; -// ALL.add(this); -// } -// -// public void register(ResourceLocation location, V value) { -// if (!unwrapped) { -// locationMap.put(location, value); -// } else { -// K object = objectRegistry.getValue(location); -// if (object != null) { -// objectMap.put(object, value); -// } else { -// Create.LOGGER.warn("Could not get object for location '" + location + "' in CreateRegistry after unwrapping!"); -// } -// } -// } -// -// public void register(K object, V value) { -// if (unwrapped) { -// objectMap.put(object, value); -// } else { -// ResourceLocation location = objectRegistry.getKey(object); -// if (location != null) { -// locationMap.put(location, value); -// } else { -// Create.LOGGER.warn("Could not get location of object '" + object + "' in CreateRegistry before unwrapping!"); -// } -// } -// } -// -// @Nullable -// public V get(ResourceLocation location) { -// if (!unwrapped) { -// return locationMap.get(location); -// } else { -// K object = objectRegistry.getValue(location); -// if (object != null) { -// return objectMap.get(object); -// } else { -// Create.LOGGER.warn("Could not get object for location '" + location + "' in CreateRegistry after unwrapping!"); -// return null; -// } -// } -// } -// -// @Nullable -// public V get(K object) { -// if (unwrapped) { -// return objectMap.get(object); -// } else { -// ResourceLocation location = objectRegistry.getKey(object); -// if (location != null) { -// return locationMap.get(location); -// } else { -// Create.LOGGER.warn("Could not get location of object '" + object + "' in CreateRegistry before unwrapping!"); -// return null; -// } -// } -// } -// -// public boolean isUnwrapped() { -// return unwrapped; -// } -// -// protected void unwrap() { -// for (Map.Entry entry : locationMap.entrySet()) { -// ResourceLocation location = entry.getKey(); -// K object = objectRegistry.getValue(location); -// if (object != null) { -// objectMap.put(object, entry.getValue()); -// } else { -// Create.LOGGER.warn("Could not get object for location '" + location + "' in CreateRegistry during unwrapping!"); -// } -// } -// unwrapped = true; -// } -// -// public static void unwrapAll() { -// for (CreateRegistry registry : ALL) { -// registry.unwrap(); -// } -// } -//} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Debug.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Debug.java index 49a1a33..998b131 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Debug.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Debug.java @@ -1,13 +1,13 @@ package nl.requios.effortlessbuilding.create.foundation.utility; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.fml.util.thread.EffectiveSide; -import nl.requios.effortlessbuilding.create.Create; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.fml.util.thread.EffectiveSide; +import nl.requios.effortlessbuilding.create.Create; /** Deprecated so simi doensn't forget to remove debug calls **/ @OnlyIn(value = Dist.CLIENT) diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DyeHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DyeHelper.java deleted file mode 100644 index b53b435..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DyeHelper.java +++ /dev/null @@ -1,75 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import com.google.common.collect.ImmutableMap; -import net.minecraft.world.item.DyeColor; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.Blocks; - -import java.util.Map; - -public class DyeHelper { - - public static ItemLike getWoolOfDye(DyeColor color) { - switch (color) { - case BLACK: - return Blocks.BLACK_WOOL; - case BLUE: - return Blocks.BLUE_WOOL; - case BROWN: - return Blocks.BROWN_WOOL; - case CYAN: - return Blocks.CYAN_WOOL; - case GRAY: - return Blocks.GRAY_WOOL; - case GREEN: - return Blocks.GREEN_WOOL; - case LIGHT_BLUE: - return Blocks.LIGHT_BLUE_WOOL; - case LIGHT_GRAY: - return Blocks.LIGHT_GRAY_WOOL; - case LIME: - return Blocks.LIME_WOOL; - case MAGENTA: - return Blocks.MAGENTA_WOOL; - case ORANGE: - return Blocks.ORANGE_WOOL; - case PINK: - return Blocks.PINK_WOOL; - case PURPLE: - return Blocks.PURPLE_WOOL; - case RED: - return Blocks.RED_WOOL; - case YELLOW: - return Blocks.YELLOW_WOOL; - case WHITE: - default: - return Blocks.WHITE_WOOL; - } - } - - public static final Map> DYE_TABLE = new ImmutableMap.Builder>() - - // DyeColor, ( Front RGB, Back RGB ) - .put(DyeColor.BLACK, Couple.create(0x45403B, 0x21201F)) - .put(DyeColor.RED, Couple.create(0xB13937, 0x632737)) - .put(DyeColor.GREEN, Couple.create(0x208A46, 0x1D6045)) - .put(DyeColor.BROWN, Couple.create(0xAC855C, 0x68533E)) - - .put(DyeColor.BLUE, Couple.create(0x5391E1, 0x504B90)) - .put(DyeColor.GRAY, Couple.create(0x5D666F, 0x313538)) - .put(DyeColor.LIGHT_GRAY, Couple.create(0x95969B, 0x707070)) - .put(DyeColor.PURPLE, Couple.create(0x9F54AE, 0x63366C)) - - .put(DyeColor.CYAN, Couple.create(0x3EABB4, 0x3C7872)) - .put(DyeColor.PINK, Couple.create(0xD5A8CB, 0xB86B95)) - .put(DyeColor.LIME, Couple.create(0xA3DF55, 0x4FB16F)) - .put(DyeColor.YELLOW, Couple.create(0xE6D756, 0xE9AC29)) - - .put(DyeColor.LIGHT_BLUE, Couple.create(0x69CED2, 0x508AA5)) - .put(DyeColor.ORANGE, Couple.create(0xEE9246, 0xD94927)) - .put(DyeColor.MAGENTA, Couple.create(0xF062B0, 0xC04488)) - .put(DyeColor.WHITE, Couple.create(0xEDEAE5, 0xBBB6B0)) - - .build(); - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DynamicComponent.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DynamicComponent.java deleted file mode 100644 index 6fc46da..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/DynamicComponent.java +++ /dev/null @@ -1,94 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import nl.requios.effortlessbuilding.create.Create; -import net.minecraft.commands.CommandSource; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.ComponentUtils; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import net.minecraft.world.phys.Vec2; -import net.minecraft.world.phys.Vec3; - -public class DynamicComponent { - - private JsonElement rawCustomText; - private Component parsedCustomText; - - public DynamicComponent() {} - - public void displayCustomText(Level level, BlockPos pos, String tagElement) { - if (tagElement == null) - return; - - rawCustomText = getJsonFromString(tagElement); - parsedCustomText = parseCustomText(level, pos, rawCustomText); - } - - public boolean sameAs(String tagElement) { - return isValid() && rawCustomText.equals(getJsonFromString(tagElement)); - } - - public boolean isValid() { - return parsedCustomText != null && rawCustomText != null; - } - - public String resolve() { - return parsedCustomText.getString(); - } - - public MutableComponent get() { - return parsedCustomText == null ? Components.empty() : parsedCustomText.copy(); - } - - public void read(Level level, BlockPos pos, CompoundTag nbt) { - rawCustomText = getJsonFromString(nbt.getString("RawCustomText")); - try { - parsedCustomText = Component.Serializer.fromJson(nbt.getString("CustomText")); - } catch (JsonParseException e) { - parsedCustomText = null; - } - } - - public void write(CompoundTag nbt) { - if (!isValid()) - return; - - nbt.putString("RawCustomText", rawCustomText.toString()); - nbt.putString("CustomText", Component.Serializer.toJson(parsedCustomText)); - } - - public static JsonElement getJsonFromString(String string) { - try { - return JsonParser.parseString(string); - } catch (JsonParseException e) { - return null; - } - } - - public static Component parseCustomText(Level level, BlockPos pos, JsonElement customText) { - if (!(level instanceof ServerLevel serverLevel)) - return null; - try { - return ComponentUtils.updateForEntity(getCommandSource(serverLevel, pos), - Component.Serializer.fromJson(customText), null, 0); - } catch (JsonParseException e) { - return null; - } catch (CommandSyntaxException e) { - return null; - } - } - - public static CommandSourceStack getCommandSource(ServerLevel level, BlockPos pos) { - return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, Create.ID, - Components.literal(Create.ID), level.getServer(), null); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FilesHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FilesHelper.java deleted file mode 100644 index 8fba34d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FilesHelper.java +++ /dev/null @@ -1,101 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.google.gson.internal.Streams; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import nl.requios.effortlessbuilding.create.Create; -import net.minecraft.nbt.CompoundTag; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; - -public class FilesHelper { - - public static void createFolderIfMissing(String name) { - try { - Files.createDirectories(Paths.get(name)); - } catch (IOException e) { - Create.LOGGER.warn("Could not create Folder: {}", name); - } - } - - public static String findFirstValidFilename(String name, String folderPath, String extension) { - int index = 0; - String filename; - String filepath; - do { - filename = slug(name) + ((index == 0) ? "" : "_" + index) + "." + extension; - index++; - filepath = folderPath + "/" + filename; - } while (Files.exists(Paths.get(filepath))); - return filename; - } - - public static String slug(String name) { - return Lang.asId(name) - .replaceAll("\\W+", "_"); - } - - public static boolean saveTagCompoundAsJson(CompoundTag compound, String path) { - try { - Files.deleteIfExists(Paths.get(path)); - JsonWriter writer = new JsonWriter(Files.newBufferedWriter(Paths.get(path), StandardOpenOption.CREATE)); - writer.setIndent(" "); - Streams.write(JsonParser.parseString(compound.toString()), writer); - writer.close(); - return true; - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } - - public static boolean saveTagCompoundAsJsonCompact(CompoundTag compound, String path) { - try { - Files.deleteIfExists(Paths.get(path)); - JsonWriter writer = new JsonWriter(Files.newBufferedWriter(Paths.get(path), StandardOpenOption.CREATE)); - Streams.write(JsonParser.parseString(compound.toString()), writer); - writer.close(); - return true; - } catch (IOException e) { - e.printStackTrace(); - } - return false; - - } - - private static JsonElement loadJson(InputStream inputStream) { - try { - JsonReader reader = new JsonReader(new BufferedReader(new InputStreamReader(inputStream))); - reader.setLenient(true); - JsonElement element = Streams.parse(reader); - reader.close(); - inputStream.close(); - return element; - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - public static JsonElement loadJsonResource(String filepath) { - return loadJson(ClassLoader.getSystemResourceAsStream(filepath)); - } - - public static JsonElement loadJson(String filepath) { - try { - return loadJson(Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ)); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FluidFormatter.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FluidFormatter.java index ec19ea9..d43492e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FluidFormatter.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FluidFormatter.java @@ -1,5 +1,6 @@ package nl.requios.effortlessbuilding.create.foundation.utility; +import net.createmod.catnip.data.Couple; import net.minecraft.network.chat.MutableComponent; public class FluidFormatter { diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FontHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FontHelper.java deleted file mode 100644 index 4f18057..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/FontHelper.java +++ /dev/null @@ -1,87 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; -import org.joml.Matrix4f; - -import java.text.BreakIterator; -import java.util.LinkedList; -import java.util.List; - -public final class FontHelper { - - private FontHelper() {} - - public static List cutString(Font font, String text, int maxWidthPerLine) { - // Split words - List words = new LinkedList<>(); - BreakIterator iterator = BreakIterator.getLineInstance(Minecraft.getInstance().getLocale()); - iterator.setText(text); - int start = iterator.first(); - for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) { - String word = text.substring(start, end); - words.add(word); - } - // Apply hard wrap - List lines = new LinkedList<>(); - StringBuilder currentLine = new StringBuilder(); - int width = 0; - for (String word : words) { - int newWidth = font.width(word); - if (width + newWidth > maxWidthPerLine) { - if (width > 0) { - String line = currentLine.toString(); - lines.add(line); - currentLine = new StringBuilder(); - width = 0; - } else { - lines.add(word); - continue; - } - } - currentLine.append(word); - width += newWidth; - } - if (width > 0) { - lines.add(currentLine.toString()); - } - return lines; - } - - public static void drawSplitString(PoseStack ms, Font font, String text, int x, int y, int width, - int color) { - List list = cutString(font, text, width); - Matrix4f matrix4f = ms.last() - .pose(); - - for (String s : list) { - float f = (float) x; - if (font.isBidirectional()) { - int i = font.width(font.bidirectionalShaping(s)); - f += (float) (width - i); - } - - draw(font, s, f, (float) y, color, matrix4f, false); - y += 9; - } - } - - private static int draw(Font font, String p_228078_1_, float p_228078_2_, float p_228078_3_, - int p_228078_4_, Matrix4f p_228078_5_, boolean p_228078_6_) { - if (p_228078_1_ == null) { - return 0; - } else { - MultiBufferSource.BufferSource irendertypebuffer$impl = MultiBufferSource.immediate(Tesselator.getInstance() - .getBuilder()); - int i = font.drawInBatch(p_228078_1_, p_228078_2_, p_228078_3_, p_228078_4_, p_228078_6_, p_228078_5_, - irendertypebuffer$impl, Font.DisplayMode.NORMAL, 0, LightTexture.FULL_BRIGHT); - irendertypebuffer$impl.endBatch(); - return i; - } - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IPartialSafeNBT.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IPartialSafeNBT.java index dfe8a01..89f3c57 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IPartialSafeNBT.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IPartialSafeNBT.java @@ -1,8 +1,11 @@ package nl.requios.effortlessbuilding.create.foundation.utility; +import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; public interface IPartialSafeNBT { - /** This method always runs on the logical server. */ - public void writeSafe(CompoundTag compound); + /** + * This will always be called from the logical server + */ + void writeSafe(CompoundTag compound, HolderLookup.Provider registries); } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IntAttached.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IntAttached.java deleted file mode 100644 index 3d9e28e..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/IntAttached.java +++ /dev/null @@ -1,61 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.nbt.CompoundTag; - -import java.util.Comparator; -import java.util.function.Function; - -public class IntAttached extends Pair { - - protected IntAttached(Integer first, V second) { - super(first, second); - } - - public static IntAttached with(int number, V value) { - return new IntAttached<>(number, value); - } - - public static IntAttached withZero(V value) { - return new IntAttached<>(0, value); - } - - public boolean isZero() { - return first.intValue() == 0; - } - - public boolean exceeds(int value) { - return first.intValue() > value; - } - - public boolean isOrBelowZero() { - return first.intValue() <= 0; - } - - public void increment() { - first++; - } - - public void decrement() { - first--; - } - - public V getValue() { - return getSecond(); - } - - public CompoundTag serializeNBT(Function serializer) { - CompoundTag nbt = new CompoundTag(); - nbt.put("Item", serializer.apply(getValue())); - nbt.putInt("Location", getFirst()); - return nbt; - } - - public static Comparator> comparator() { - return (i1, i2) -> Integer.compare(i2.getFirst(), i1.getFirst()); - } - - public static IntAttached read(CompoundTag nbt, Function deserializer) { - return IntAttached.with(nbt.getInt("Location"), deserializer.apply(nbt.getCompound("Item"))); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Iterate.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Iterate.java deleted file mode 100644 index 6382596..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Iterate.java +++ /dev/null @@ -1,48 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; - -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; - -public class Iterate { - - public static final boolean[] trueAndFalse = { true, false }; - public static final boolean[] falseAndTrue = { false, true }; - public static final int[] zeroAndOne = { 0, 1 }; - public static final int[] positiveAndNegative = { 1, -1 }; - public static final Direction[] directions = Direction.values(); - public static final Direction[] horizontalDirections = getHorizontals(); - public static final Axis[] axes = Axis.values(); - public static final EnumSet axisSet = EnumSet.allOf(Axis.class); - - private static Direction[] getHorizontals() { - Direction[] directions = new Direction[4]; - for (int i = 0; i < 4; i++) - directions[i] = Direction.from2DDataValue(i); - return directions; - } - - public static Direction[] directionsInAxis(Axis axis) { - switch (axis) { - case X: - return new Direction[] { Direction.EAST, Direction.WEST }; - case Y: - return new Direction[] { Direction.UP, Direction.DOWN }; - default: - case Z: - return new Direction[] { Direction.SOUTH, Direction.NORTH }; - } - } - - public static List hereAndBelow(BlockPos pos) { - return Arrays.asList(pos, pos.below()); - } - - public static List hereBelowAndAbove(BlockPos pos) { - return Arrays.asList(pos, pos.below(), pos.above()); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Lang.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Lang.java index 1d4aef6..08976b1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Lang.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Lang.java @@ -1,11 +1,13 @@ package nl.requios.effortlessbuilding.create.foundation.utility; -import nl.requios.effortlessbuilding.create.Create; +import net.createmod.catnip.lang.LangBuilder; +import net.createmod.catnip.lang.LangNumberFormat; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.fluids.FluidStack; +import nl.requios.effortlessbuilding.create.Create; import java.util.ArrayList; import java.util.List; @@ -63,7 +65,7 @@ public class Lang { } public static LangBuilder fluidName(FluidStack stack) { - return builder().add(stack.getDisplayName() + return builder().add(stack.getHoverName() .copy()); } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangBuilder.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangBuilder.java deleted file mode 100644 index b143a0b..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangBuilder.java +++ /dev/null @@ -1,165 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import joptsimple.internal.Strings; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.world.entity.player.Player; - -import java.util.List; - -public class LangBuilder { - - String namespace; - MutableComponent component; - - public LangBuilder(String namespace) { - this.namespace = namespace; - } - - public LangBuilder space() { - return text(" "); - } - - public LangBuilder newLine() { - return text("\n"); - } - - /** - * Appends a localised component
- * To add an independently formatted localised component, use add() and a nested - * builder - * - * @param langKey - * @param args - * @return - */ - public LangBuilder translate(String langKey, Object... args) { - return add(Components.translatable(namespace + "." + langKey, Lang.resolveBuilders(args))); - } - - /** - * Appends a text component - * - * @param literalText - * @return - */ - public LangBuilder text(String literalText) { - return add(Components.literal(literalText)); - } - - /** - * Appends a colored text component - * - * @param format - * @param literalText - * @return - */ - public LangBuilder text(ChatFormatting format, String literalText) { - return add(Components.literal(literalText).withStyle(format)); - } - - /** - * Appends a colored text component - * - * @param color - * @param literalText - * @return - */ - public LangBuilder text(int color, String literalText) { - return add(Components.literal(literalText).withStyle(s -> s.withColor(color))); - } - - /** - * Appends the contents of another builder - * - * @param otherBuilder - * @return - */ - public LangBuilder add(LangBuilder otherBuilder) { - return add(otherBuilder.component()); - } - - /** - * Appends a component - * - * @param customComponent - * @return - */ - public LangBuilder add(MutableComponent customComponent) { - component = component == null ? customComponent : component.append(customComponent); - return this; - } - - // - - /** - * Applies the format to all added components - * - * @param format - * @return - */ - public LangBuilder style(ChatFormatting format) { - assertComponent(); - component = component.withStyle(format); - return this; - } - - /** - * Applies the color to all added components - * - * @param color - * @return - */ - public LangBuilder color(int color) { - assertComponent(); - component = component.withStyle(s -> s.withColor(color)); - return this; - } - - // - - public MutableComponent component() { - assertComponent(); - return component; - } - - public String string() { - return component().getString(); - } - - public String json() { - return Component.Serializer.toJson(component()); - } - - public void sendStatus(Player player) { - player.displayClientMessage(component(), true); - } - - public void sendChat(Player player) { - player.displayClientMessage(component(), false); - } - - public void addTo(List tooltip) { - tooltip.add(component()); - } - - public void forGoggles(List tooltip) { - forGoggles(tooltip, 0); - } - - public void forGoggles(List tooltip, int indents) { - tooltip.add(Lang.builder() - .text(Strings.repeat(' ', 4 + indents)) - .add(this) - .component()); - } - - // - - private void assertComponent() { - if (component == null) - throw new IllegalStateException("No components were added to builder"); - } - -} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangNumberFormat.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangNumberFormat.java deleted file mode 100644 index 77ae9e5..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/LangNumberFormat.java +++ /dev/null @@ -1,32 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.client.Minecraft; - -import java.text.NumberFormat; -import java.util.Locale; - -public class LangNumberFormat { - - private NumberFormat format = NumberFormat.getNumberInstance(Locale.ROOT); - public static LangNumberFormat numberFormat = new LangNumberFormat(); - - public NumberFormat get() { - return format; - } - - public void update() { - format = NumberFormat.getInstance(Minecraft.getInstance() - .getLanguageManager() - .getJavaLocale()); - format.setMaximumFractionDigits(2); - format.setMinimumFractionDigits(0); - format.setGroupingUsed(true); - } - - public static String format(double d) { - return numberFormat.get() - .format(d) - .replace("\u00A0", " "); - } - -} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTHelper.java deleted file mode 100644 index bff79f7..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTHelper.java +++ /dev/null @@ -1,106 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.Vec3i; -import net.minecraft.nbt.*; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.AABB; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; - -public class NBTHelper { - - public static void putMarker(CompoundTag nbt, String marker) { - nbt.putBoolean(marker, true); - } - - public static > T readEnum(CompoundTag nbt, String key, Class enumClass) { - T[] enumConstants = enumClass.getEnumConstants(); - if (enumConstants == null) - throw new IllegalArgumentException("Non-Enum class passed to readEnum: " + enumClass.getName()); - if (nbt.contains(key, Tag.TAG_STRING)) { - String name = nbt.getString(key); - for (T t : enumConstants) { - if (t.name() - .equals(name)) - return t; - } - } - return enumConstants[0]; - } - - public static > void writeEnum(CompoundTag nbt, String key, T enumConstant) { - nbt.putString(key, enumConstant.name()); - } - - public static ListTag writeCompoundList(Iterable list, Function serializer) { - ListTag listNBT = new ListTag(); - list.forEach(t -> { - CompoundTag apply = serializer.apply(t); - if (apply == null) - return; - listNBT.add(apply); - }); - return listNBT; - } - - public static List readCompoundList(ListTag listNBT, Function deserializer) { - List list = new ArrayList<>(listNBT.size()); - listNBT.forEach(inbt -> list.add(deserializer.apply((CompoundTag) inbt))); - return list; - } - - public static void iterateCompoundList(ListTag listNBT, Consumer consumer) { - listNBT.forEach(inbt -> consumer.accept((CompoundTag) inbt)); - } - -// public static ListTag writeItemList(Iterable stacks) { -// return writeCompoundList(stacks, ItemStack::serializeNBT); -// } - - public static List readItemList(ListTag stacks) { - return readCompoundList(stacks, ItemStack::of); - } - - public static ListTag writeAABB(AABB bb) { - ListTag bbtag = new ListTag(); - bbtag.add(FloatTag.valueOf((float) bb.minX)); - bbtag.add(FloatTag.valueOf((float) bb.minY)); - bbtag.add(FloatTag.valueOf((float) bb.minZ)); - bbtag.add(FloatTag.valueOf((float) bb.maxX)); - bbtag.add(FloatTag.valueOf((float) bb.maxY)); - bbtag.add(FloatTag.valueOf((float) bb.maxZ)); - return bbtag; - } - - public static AABB readAABB(ListTag bbtag) { - if (bbtag == null || bbtag.isEmpty()) - return null; - return new AABB(bbtag.getFloat(0), bbtag.getFloat(1), bbtag.getFloat(2), bbtag.getFloat(3), - bbtag.getFloat(4), bbtag.getFloat(5)); - } - - public static ListTag writeVec3i(Vec3i vec) { - ListTag tag = new ListTag(); - tag.add(IntTag.valueOf(vec.getX())); - tag.add(IntTag.valueOf(vec.getY())); - tag.add(IntTag.valueOf(vec.getZ())); - return tag; - } - - public static Vec3i readVec3i(ListTag tag) { - return new Vec3i(tag.getInt(0), tag.getInt(1), tag.getInt(2)); - } - - @Nonnull - public static Tag getINBT(CompoundTag nbt, String id) { - Tag inbt = nbt.get(id); - if (inbt != null) - return inbt; - return new CompoundTag(); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTProcessors.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTProcessors.java deleted file mode 100644 index 218024e..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/NBTProcessors.java +++ /dev/null @@ -1,84 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; -import net.minecraft.network.chat.Component; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.entity.SpawnerBlockEntity; - -import javax.annotation.Nullable; -import java.util.HashMap; -import java.util.Map; -import java.util.function.UnaryOperator; - -public final class NBTProcessors { - - private static final Map, UnaryOperator> processors = new HashMap<>(); - private static final Map, UnaryOperator> survivalProcessors = new HashMap<>(); - - public static synchronized void addProcessor(BlockEntityType type, UnaryOperator processor) { - processors.put(type, processor); - } - - public static synchronized void addSurvivalProcessor(BlockEntityType type, UnaryOperator processor) { - survivalProcessors.put(type, processor); - } - - static { - addProcessor(BlockEntityType.SIGN, data -> { - for (int i = 0; i < 4; ++i) { - if (textComponentHasClickEvent(data.getString("Text" + (i + 1)))) - return null; - } - return data; - }); - addProcessor(BlockEntityType.LECTERN, data -> { - if (!data.contains("Book", Tag.TAG_COMPOUND)) - return data; - CompoundTag book = data.getCompound("Book"); - - if (!book.contains("tag", Tag.TAG_COMPOUND)) - return data; - CompoundTag tag = book.getCompound("tag"); - - if (!tag.contains("pages", Tag.TAG_LIST)) - return data; - ListTag pages = tag.getList("pages", Tag.TAG_STRING); - - for (Tag inbt : pages) { - if (textComponentHasClickEvent(inbt.getAsString())) - return null; - } - return data; - }); - } - - public static boolean textComponentHasClickEvent(String json) { - Component component = Component.Serializer.fromJson(json.isEmpty() ? "\"\"" : json); - return component != null && component.getStyle() != null && component.getStyle().getClickEvent() != null; - } - - private NBTProcessors() { - } - - @Nullable - public static CompoundTag process(BlockEntity tileEntity, CompoundTag compound, boolean survival) { - if (compound == null) - return null; - BlockEntityType type = tileEntity.getType(); - if (survival && survivalProcessors.containsKey(type)) - compound = survivalProcessors.get(type) - .apply(compound); - if (compound != null && processors.containsKey(type)) - return processors.get(type) - .apply(compound); - if (tileEntity instanceof SpawnerBlockEntity) - return compound; - if (tileEntity.onlyOpCanSetNbt()) - return null; - return compound; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pair.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pair.java deleted file mode 100644 index 569b1e4..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pair.java +++ /dev/null @@ -1,68 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import java.util.Objects; - -public class Pair { - - F first; - S second; - - protected Pair(F first, S second) { - this.first = first; - this.second = second; - } - - public static Pair of(F first, S second) { - return new Pair<>(first, second); - } - - public F getFirst() { - return first; - } - - public S getSecond() { - return second; - } - - public void setFirst(F first) { - this.first = first; - } - - public void setSecond(S second) { - this.second = second; - } - - public Pair copy() { - return Pair.of(first, second); - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) - return true; - if (obj instanceof Pair) { - final Pair other = (Pair) obj; - return Objects.equals(first, other.first) && Objects.equals(second, other.second); - } - return false; - } - - @Override - public int hashCode() { - return (nullHash(first) * 31) ^ nullHash(second); - } - - int nullHash(Object o) { - return o == null ? 0 : o.hashCode(); - } - - @Override - public String toString() { - return "(" + first + ", " + second + ")"; - } - - public Pair swap() { - return Pair.of(second, first); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pointing.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pointing.java deleted file mode 100644 index 18a1716..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/Pointing.java +++ /dev/null @@ -1,35 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.core.Direction.AxisDirection; -import net.minecraft.util.StringRepresentable; - -public enum Pointing implements StringRepresentable { - UP(0), LEFT(270), DOWN(180), RIGHT(90); - - private int xRotation; - - private Pointing(int xRotation) { - this.xRotation = xRotation; - } - - @Override - public String getSerializedName() { - return Lang.asId(name()); - } - - public int getXRotation() { - return xRotation; - } - - public Direction getCombinedDirection(Direction direction) { - Axis axis = direction.getAxis(); - Direction top = axis == Axis.Y ? Direction.SOUTH : Direction.UP; - int rotations = direction.getAxisDirection() == AxisDirection.NEGATIVE ? 4 - ordinal() : ordinal(); - for (int i = 0; i < rotations; i++) - top = top.getClockWise(axis); - return top; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/RegisteredObjects.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/RegisteredObjects.java deleted file mode 100644 index 9e31149..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/RegisteredObjects.java +++ /dev/null @@ -1,66 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.Registry; -import net.minecraft.core.particles.ParticleType; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.alchemy.Potion; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.material.Fluid; -import org.jetbrains.annotations.NotNull; - -public final class RegisteredObjects { - // registry argument for easier porting to 1.19 - @NotNull - public static ResourceLocation getKeyOrThrow(Registry registry, V value) { - ResourceLocation key = registry.getKey(value); - if (key == null) { - throw new IllegalArgumentException("Could not get key for value " + value + "!"); - } - return key; - } - - @NotNull - public static ResourceLocation getKeyOrThrow(Block value) { - return getKeyOrThrow(BuiltInRegistries.BLOCK, value); - } - - @NotNull - public static ResourceLocation getKeyOrThrow(Item value) { - return getKeyOrThrow(BuiltInRegistries.ITEM, value); - } - - @NotNull - public static ResourceLocation getKeyOrThrow(Fluid value) { - return getKeyOrThrow(BuiltInRegistries.FLUID, value); - } - - @NotNull - public static ResourceLocation getKeyOrThrow(EntityType value) { - return getKeyOrThrow(BuiltInRegistries.ENTITY_TYPE, value); - } - - @NotNull - public static ResourceLocation getKeyOrThrow(BlockEntityType value) { - return getKeyOrThrow(BuiltInRegistries.BLOCK_ENTITY_TYPE, value); - } - - @NotNull - public static ResourceLocation getKeyOrThrow(Potion value) { - return getKeyOrThrow(BuiltInRegistries.POTION, value); - } - - @NotNull - public static ResourceLocation getKeyOrThrow(ParticleType value) { - return getKeyOrThrow(BuiltInRegistries.PARTICLE_TYPE, value); - } - - @NotNull - public static ResourceLocation getKeyOrThrow(RecipeSerializer value) { - return getKeyOrThrow(BuiltInRegistries.RECIPE_SERIALIZER, value); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ResetableLazy.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ResetableLazy.java index a344a32..4969463 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ResetableLazy.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ResetableLazy.java @@ -1,15 +1,15 @@ package nl.requios.effortlessbuilding.create.foundation.utility; -import net.neoforged.neoforge.common.util.NonNullSupplier; +import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; public class ResetableLazy implements Supplier { - private final NonNullSupplier supplier; + private final Supplier<@NotNull T> supplier; private T value; - public ResetableLazy(NonNullSupplier supplier) { + public ResetableLazy(Supplier<@NotNull T> supplier) { this.supplier = supplier; } @@ -25,7 +25,7 @@ public class ResetableLazy implements Supplier { value = null; } - public static ResetableLazy of(NonNullSupplier supplier) { + public static ResetableLazy of(Supplier<@NotNull T> supplier) { return new ResetableLazy<>(supplier); } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/UniqueLinkedList.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/UniqueLinkedList.java deleted file mode 100644 index d5d148c..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/UniqueLinkedList.java +++ /dev/null @@ -1,102 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.Collectors; - -public class UniqueLinkedList extends LinkedList { - /** - * - */ - private static final long serialVersionUID = 1L; - private final HashSet contained = new HashSet<>(); - - @Override - public boolean contains(Object o) { - return contained.contains(o); - } - - @Override - public E poll() { - E e = super.poll(); - contained.remove(e); - return e; - } - - @Override - public boolean add(E e) { - if (contained.add(e)) - return super.add(e); - else - return false; - } - - @Override - public void add(int index, E element) { - if (contained.add(element)) - super.add(index, element); - } - - @Override - public void addFirst(E e) { - if (contained.add(e)) - super.addFirst(e); - } - - @Override - public void addLast(E e) { - if (contained.add(e)) - super.addLast(e); - } - - @Override - public boolean addAll(Collection c) { - List filtered = c.stream() - .filter(it -> !contained.contains(it)) - .collect(Collectors.toList()); - return super.addAll(filtered); - } - - @Override - public boolean addAll(int index, Collection c) { - List filtered = c.stream() - .filter(it -> !contained.contains(it)) - .collect(Collectors.toList()); - return super.addAll(index, filtered); - } - - @Override - public boolean remove(Object o) { - contained.remove(o); - return super.remove(o); - } - - @Override - public E remove(int index) { - E e = super.remove(index); - contained.remove(e); - return e; - } - - @Override - public E removeFirst() { - E e = super.removeFirst(); - contained.remove(e); - return e; - } - - @Override - public E removeLast() { - E e = super.removeLast(); - contained.remove(e); - return e; - } - - @Override - public void clear() { - super.clear(); - contained.clear(); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VecHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VecHelper.java deleted file mode 100644 index e701f22..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VecHelper.java +++ /dev/null @@ -1,342 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.client.Camera; -import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.core.Vec3i; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.DoubleTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.util.Mth; -import net.minecraft.util.RandomSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.phys.Vec3; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import javax.annotation.Nullable; - -public class VecHelper { - - public static final Vec3 CENTER_OF_ORIGIN = new Vec3(.5, .5, .5); - - public static Vec3 rotate(Vec3 vec, Vec3 rotationVec) { - return rotate(vec, rotationVec.x, rotationVec.y, rotationVec.z); - } - - public static Vec3 rotate(Vec3 vec, double xRot, double yRot, double zRot) { - return rotate(rotate(rotate(vec, xRot, Axis.X), yRot, Axis.Y), zRot, Axis.Z); - } - - public static Vec3 rotateCentered(Vec3 vec, double deg, Axis axis) { - Vec3 shift = getCenterOf(BlockPos.ZERO); - return VecHelper.rotate(vec.subtract(shift), deg, axis) - .add(shift); - } - - public static Vec3 rotate(Vec3 vec, double deg, Axis axis) { - if (deg == 0) - return vec; - if (vec == Vec3.ZERO) - return vec; - - float angle = (float) (deg / 180f * Math.PI); - double sin = Mth.sin(angle); - double cos = Mth.cos(angle); - double x = vec.x; - double y = vec.y; - double z = vec.z; - - if (axis == Axis.X) - return new Vec3(x, y * cos - z * sin, z * cos + y * sin); - if (axis == Axis.Y) - return new Vec3(x * cos + z * sin, y, z * cos - x * sin); - if (axis == Axis.Z) - return new Vec3(x * cos - y * sin, y * cos + x * sin, z); - return vec; - } - - public static Vec3 mirrorCentered(Vec3 vec, Mirror mirror) { - Vec3 shift = getCenterOf(BlockPos.ZERO); - return VecHelper.mirror(vec.subtract(shift), mirror) - .add(shift); - } - - public static Vec3 mirror(Vec3 vec, Mirror mirror) { - if (mirror == null || mirror == Mirror.NONE) - return vec; - if (vec == Vec3.ZERO) - return vec; - - double x = vec.x; - double y = vec.y; - double z = vec.z; - - if (mirror == Mirror.LEFT_RIGHT) - return new Vec3(x, y, -z); - if (mirror == Mirror.FRONT_BACK) - return new Vec3(-x, y, z); - return vec; - } - - public static Vec3 lookAt(Vec3 vec, Vec3 fwd) { - fwd = fwd.normalize(); - Vec3 up = new Vec3(0, 1, 0); - double dot = fwd.dot(up); - if (Math.abs(dot) > 1 - 1.0E-3) - up = new Vec3(0, 0, dot > 0 ? 1 : -1); - Vec3 right = fwd.cross(up) - .normalize(); - up = right.cross(fwd) - .normalize(); - double x = vec.x * right.x + vec.y * up.x + vec.z * fwd.x; - double y = vec.x * right.y + vec.y * up.y + vec.z * fwd.y; - double z = vec.x * right.z + vec.y * up.z + vec.z * fwd.z; - return new Vec3(x, y, z); - } - - public static boolean isVecPointingTowards(Vec3 vec, Direction direction) { - return Vec3.atLowerCornerOf(direction.getNormal()) - .dot(vec.normalize()) > 0.125; // slight tolerance to activate perpendicular movement actors - } - - public static Vec3 getCenterOf(Vec3i pos) { - if (pos.equals(Vec3i.ZERO)) - return CENTER_OF_ORIGIN; - return Vec3.atLowerCornerOf(pos) - .add(.5f, .5f, .5f); - } - - public static Vec3 offsetRandomly(Vec3 vec, RandomSource r, float radius) { - return new Vec3(vec.x + (r.nextFloat() - .5f) * 2 * radius, vec.y + (r.nextFloat() - .5f) * 2 * radius, - vec.z + (r.nextFloat() - .5f) * 2 * radius); - } - - public static Vec3 axisAlingedPlaneOf(Vec3 vec) { - vec = vec.normalize(); - return new Vec3(1, 1, 1).subtract(Math.abs(vec.x), Math.abs(vec.y), Math.abs(vec.z)); - } - - public static Vec3 axisAlingedPlaneOf(Direction face) { - return axisAlingedPlaneOf(Vec3.atLowerCornerOf(face.getNormal())); - } - - public static ListTag writeNBT(Vec3 vec) { - ListTag listnbt = new ListTag(); - listnbt.add(DoubleTag.valueOf(vec.x)); - listnbt.add(DoubleTag.valueOf(vec.y)); - listnbt.add(DoubleTag.valueOf(vec.z)); - return listnbt; - } - - public static CompoundTag writeNBTCompound(Vec3 vec) { - CompoundTag compoundTag = new CompoundTag(); - compoundTag.put("V", writeNBT(vec)); - return compoundTag; - } - - public static Vec3 readNBT(ListTag list) { - if (list.isEmpty()) - return Vec3.ZERO; - return new Vec3(list.getDouble(0), list.getDouble(1), list.getDouble(2)); - } - - public static Vec3 readNBTCompound(CompoundTag nbt) { - return readNBT(nbt.getList("V", Tag.TAG_DOUBLE)); - } - - public static void write(Vec3 vec, FriendlyByteBuf buffer) { - buffer.writeDouble(vec.x); - buffer.writeDouble(vec.y); - buffer.writeDouble(vec.z); - } - - public static Vec3 read(FriendlyByteBuf buffer) { - return new Vec3(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()); - } - - public static Vec3 voxelSpace(double x, double y, double z) { - return new Vec3(x, y, z).scale(1 / 16f); - } - - public static int getCoordinate(Vec3i pos, Axis axis) { - return axis.choose(pos.getX(), pos.getY(), pos.getZ()); - } - - public static float getCoordinate(Vec3 vec, Axis axis) { - return (float) axis.choose(vec.x, vec.y, vec.z); - } - - public static boolean onSameAxis(BlockPos pos1, BlockPos pos2, Axis axis) { - if (pos1.equals(pos2)) - return true; - for (Axis otherAxis : Axis.values()) - if (axis != otherAxis) - if (getCoordinate(pos1, otherAxis) != getCoordinate(pos2, otherAxis)) - return false; - return true; - } - - public static Vec3 clamp(Vec3 vec, float maxLength) { - return vec.length() > maxLength ? vec.normalize() - .scale(maxLength) : vec; - } - - public static Vec3 lerp(float p, Vec3 from, Vec3 to) { - return from.add(to.subtract(from) - .scale(p)); - } - - public static Vec3 slerp(float p, Vec3 from, Vec3 to) { - double theta = Math.acos(from.dot(to)); - return from.scale(Mth.sin(1 - p) * theta) - .add(to.scale(Mth.sin((float) (theta * p)))) - .scale(1 / Mth.sin((float) theta)); - } - - public static Vec3 clampComponentWise(Vec3 vec, float maxLength) { - return new Vec3(Mth.clamp(vec.x, -maxLength, maxLength), Mth.clamp(vec.y, -maxLength, maxLength), - Mth.clamp(vec.z, -maxLength, maxLength)); - } - - public static Vec3 project(Vec3 vec, Vec3 ontoVec) { - if (ontoVec.equals(Vec3.ZERO)) - return Vec3.ZERO; - return ontoVec.scale(vec.dot(ontoVec) / ontoVec.lengthSqr()); - } - - @Nullable - public static Vec3 intersectSphere(Vec3 origin, Vec3 lineDirection, Vec3 sphereCenter, double radius) { - if (lineDirection.equals(Vec3.ZERO)) - return null; - if (lineDirection.length() != 1) - lineDirection = lineDirection.normalize(); - - Vec3 diff = origin.subtract(sphereCenter); - double lineDotDiff = lineDirection.dot(diff); - double delta = lineDotDiff * lineDotDiff - (diff.lengthSqr() - radius * radius); - if (delta < 0) - return null; - double t = -lineDotDiff + Math.sqrt(delta); - return origin.add(lineDirection.scale(t)); - } - - // https://forums.minecraftforge.net/topic/88562-116solved-3d-to-2d-conversion/?do=findComment&comment=413573 - // slightly modified - public static Vec3 projectToPlayerView(Vec3 target, float partialTicks) { - /* - * The (centered) location on the screen of the given 3d point in the world. - * Result is (dist right of center screen, dist up from center screen, if < 0, - * then in front of view plane) - */ - Camera ari = Minecraft.getInstance().gameRenderer.getMainCamera(); - Vec3 camera_pos = ari.getPosition(); - Quaternionf camera_rotation_conj = new Quaternionf(ari.rotation()); - camera_rotation_conj.conjugate(); - - Vector3f result3f = new Vector3f((float) (camera_pos.x - target.x), (float) (camera_pos.y - target.y), - (float) (camera_pos.z - target.z)); - result3f.rotate(camera_rotation_conj); - - // ----- compensate for view bobbing (if active) ----- - // the following code adapted from GameRenderer::applyBobbing (to invert it) - Minecraft mc = Minecraft.getInstance(); - if (mc.options.bobView().get()) { - Entity renderViewEntity = mc.getCameraEntity(); - if (renderViewEntity instanceof Player) { - Player playerentity = (Player) renderViewEntity; - float distwalked_modified = playerentity.walkDist; - - float f = distwalked_modified - playerentity.walkDistO; - float f1 = -(distwalked_modified + f * partialTicks); - float f2 = Mth.lerp(partialTicks, playerentity.oBob, playerentity.bob); - Quaternionf q2 = - com.mojang.math.Axis.XP.rotationDegrees(Math.abs(Mth.cos(f1 * (float) Math.PI - 0.2F) * f2) * 5.0F); - q2.conjugate(); - result3f.rotate(q2); - - Quaternionf q1 = com.mojang.math.Axis.ZP.rotationDegrees(Mth.sin(f1 * (float) Math.PI) * f2 * 3.0F); - q1.conjugate(); - result3f.rotate(q1); - - Vector3f bob_translation = new Vector3f((Mth.sin(f1 * (float) Math.PI) * f2 * 0.5F), - (-Math.abs(Mth.cos(f1 * (float) Math.PI) * f2)), 0.0f); - bob_translation.y = -bob_translation.y(); // this is weird but hey, if it works - result3f.add(bob_translation); - } - } - - // ----- adjust for fov ----- - float fov = 70;//(float) ((GameRendererAccessor) mc.gameRenderer).create$callGetFov(ari, partialTicks, true); - - float half_height = (float) mc.getWindow() - .getGuiScaledHeight() / 2; - float scale_factor = half_height / (result3f.z() * (float) Math.tan(Math.toRadians(fov / 2))); - return new Vec3(-result3f.x() * scale_factor, result3f.y() * scale_factor, result3f.z()); - } - - public static Vec3 bezier(Vec3 p1, Vec3 p2, Vec3 q1, Vec3 q2, float t) { - Vec3 v1 = lerp(t, p1, q1); - Vec3 v2 = lerp(t, q1, q2); - Vec3 v3 = lerp(t, q2, p2); - Vec3 inner1 = lerp(t, v1, v2); - Vec3 inner2 = lerp(t, v2, v3); - Vec3 result = lerp(t, inner1, inner2); - return result; - } - - public static Vec3 bezierDerivative(Vec3 p1, Vec3 p2, Vec3 q1, Vec3 q2, float t) { - return p1.scale(-3 * t * t + 6 * t - 3) - .add(q1.scale(9 * t * t - 12 * t + 3)) - .add(q2.scale(-9 * t * t + 6 * t)) - .add(p2.scale(3 * t * t)); - } - - @Nullable - public static double[] intersectRanged(Vec3 p1, Vec3 q1, Vec3 p2, Vec3 q2, Axis plane) { - Vec3 pDiff = p2.subtract(p1); - Vec3 qDiff = q2.subtract(q1); - double[] intersect = intersect(p1, q1, pDiff.normalize(), qDiff.normalize(), plane); - if (intersect == null) - return null; - if (intersect[0] < 0 || intersect[1] < 0) - return null; - if (intersect[0] > pDiff.length() || intersect[1] > qDiff.length()) - return null; - return intersect; - } - - @Nullable - public static double[] intersect(Vec3 p1, Vec3 p2, Vec3 r, Vec3 s, Axis plane) { - if (plane == Axis.X) { - p1 = new Vec3(p1.y, 0, p1.z); - p2 = new Vec3(p2.y, 0, p2.z); - r = new Vec3(r.y, 0, r.z); - s = new Vec3(s.y, 0, s.z); - } - - if (plane == Axis.Z) { - p1 = new Vec3(p1.x, 0, p1.y); - p2 = new Vec3(p2.x, 0, p2.y); - r = new Vec3(r.x, 0, r.y); - s = new Vec3(s.x, 0, s.y); - } - - Vec3 qminusp = p2.subtract(p1); - double rcs = r.x * s.z - r.z * s.x; - if (Mth.equal(rcs, 0)) - return null; - Vec3 rdivrcs = r.scale(1 / rcs); - Vec3 sdivrcs = s.scale(1 / rcs); - double t = qminusp.x * sdivrcs.z - qminusp.z * sdivrcs.x; - double u = qminusp.x * rdivrcs.z - qminusp.z * rdivrcs.x; - return new double[] { t, u }; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VoxelShaper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VoxelShaper.java index c18807b..6b45732 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VoxelShaper.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/VoxelShaper.java @@ -1,5 +1,7 @@ package nl.requios.effortlessbuilding.create.foundation.utility; +import net.createmod.catnip.data.Iterate; +import net.createmod.catnip.math.VecHelper; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.AxisDirection; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldAttached.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldAttached.java deleted file mode 100644 index 9c9c081..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldAttached.java +++ /dev/null @@ -1,101 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.world.level.LevelAccessor; - -import javax.annotation.Nonnull; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.WeakHashMap; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -public class WorldAttached { - - // weak references to prevent leaking hashmaps when a WorldAttached is GC'd during runtime - static List>> allMaps = new ArrayList<>(); - private final Map attached; - private final Function factory; - - public WorldAttached(Function factory) { - this.factory = factory; - // Weak key hashmaps prevent worlds not existing anywhere else from leaking memory. - // This is only a fallback in the event that unload events fail to fire for any reason. - attached = new WeakHashMap<>(); - allMaps.add(new WeakReference<>(attached)); - } - - public static void invalidateWorld(LevelAccessor world) { - var i = allMaps.iterator(); - while (i.hasNext()) { - Map map = i.next() - .get(); - if (map == null) { - // If the map has been GC'd, remove the weak reference - i.remove(); - } else { - // Prevent leaks - map.remove(world); - } - } - } - - @Nonnull - public T get(LevelAccessor world) { - T t = attached.get(world); - if (t != null) return t; - T entry = factory.apply(world); - put(world, entry); - return entry; - } - - public void put(LevelAccessor world, T entry) { - attached.put(world, entry); - } - - /** - * Replaces the entry with a new one from the factory and returns the new entry. - */ - @Nonnull - public T replace(LevelAccessor world) { - attached.remove(world); - - return get(world); - } - - /** - * Replaces the entry with a new one from the factory and returns the new entry. - */ - @Nonnull - public T replace(LevelAccessor world, Consumer finalizer) { - T remove = attached.remove(world); - - if (remove != null) - finalizer.accept(remove); - - return get(world); - } - - /** - * Deletes all entries after calling a function on them. - * - * @param finalizer Do something with all of the world-value pairs - */ - public void empty(BiConsumer finalizer) { - attached.forEach(finalizer); - attached.clear(); - } - - /** - * Deletes all entries after calling a function on them. - * - * @param finalizer Do something with all of the values - */ - public void empty(Consumer finalizer) { - attached.values() - .forEach(finalizer); - attached.clear(); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldHelper.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldHelper.java deleted file mode 100644 index 03489d4..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/WorldHelper.java +++ /dev/null @@ -1,13 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility; - -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.LevelAccessor; - -public class WorldHelper { - public static ResourceLocation getDimensionID(LevelAccessor world) { - return world.registryAccess() - .registryOrThrow(Registries.DIMENSION_TYPE) - .getKey(world.dimensionType()); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/Force.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/Force.java deleted file mode 100644 index 493a4cf..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/Force.java +++ /dev/null @@ -1,102 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.animation; - -public interface Force { - - float get(float mass, float value, float speed); - - boolean finished(); - - class Drag implements Force { - final float dragFactor; - - public Drag(float dragFactor) { - this.dragFactor = dragFactor; - } - - @Override - public float get(float mass, float value, float speed) { - return -speed * dragFactor; - } - - @Override - public boolean finished() { - return false; - } - } - - class Zeroing implements Force { - final float g; - - public Zeroing(float g) { - this.g = g / 20; - } - - @Override - public float get(float mass, float value, float speed) { - return -Math.signum(value) * g * mass; - } - - @Override - public boolean finished() { - return false; - } - } - - class Impulse implements Force { - - float force; - - public Impulse(float force) { - this.force = force; - } - - @Override - public float get(float mass, float value, float speed) { - return force; - } - - @Override - public boolean finished() { - return true; - } - } - - class OverTime implements Force { - int timeRemaining; - float f; - - public OverTime(int time, float totalAcceleration) { - this.timeRemaining = time; - this.f = totalAcceleration / (float) time; - } - - @Override - public float get(float mass, float value, float speed) { - timeRemaining--; - return f; - } - - @Override - public boolean finished() { - return timeRemaining <= 0; - } - } - - class Static implements Force { - float force; - - public Static(float force) { - this.force = force; - } - - @Override - public float get(float mass, float value, float speed) { - return force; - } - - @Override - public boolean finished() { - return false; - } - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/LerpedFloat.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/LerpedFloat.java deleted file mode 100644 index 1043202..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/LerpedFloat.java +++ /dev/null @@ -1,149 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.animation; - -import nl.requios.effortlessbuilding.create.foundation.utility.AngleHelper; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.Mth; - -public class LerpedFloat { - - protected Interpolator interpolator; - protected float previousValue; - protected float value; - - protected Chaser chaseFunction; - protected float chaseTarget; - protected float chaseSpeed; - protected boolean angularChase; - - protected boolean forcedSync; - - public LerpedFloat(Interpolator interpolator) { - this.interpolator = interpolator; - startWithValue(0); - forcedSync = true; - } - - public static LerpedFloat linear() { - return new LerpedFloat((p, c, t) -> (float) Mth.lerp(p, c, t)); - } - - public static LerpedFloat angular() { - LerpedFloat lerpedFloat = new LerpedFloat(AngleHelper::angleLerp); - lerpedFloat.angularChase = true; - return lerpedFloat; - } - - public LerpedFloat startWithValue(double value) { - float f = (float) value; - this.previousValue = f; - this.chaseTarget = f; - this.value = f; - return this; - } - - public LerpedFloat chase(double value, double speed, Chaser chaseFunction) { - updateChaseTarget((float) value); - this.chaseSpeed = (float) speed; - this.chaseFunction = chaseFunction; - return this; - } - - public LerpedFloat disableSmartAngleChasing() { - angularChase = false; - return this; - } - - public void updateChaseTarget(float target) { - if (angularChase) - target = value + AngleHelper.getShortestAngleDiff(value, target); - this.chaseTarget = target; - } - - public boolean updateChaseSpeed(double speed) { - float prevSpeed = this.chaseSpeed; - this.chaseSpeed = (float) speed; - return !Mth.equal(prevSpeed, speed); - } - - public void tickChaser() { - previousValue = value; - if (chaseFunction == null) - return; - if (Mth.equal((double) value, chaseTarget)) { - value = chaseTarget; - return; - } - value = chaseFunction.chase(value, chaseSpeed, chaseTarget); - } - - public void setValueNoUpdate(double value) { - this.value = (float) value; - } - - public void setValue(double value) { - this.previousValue = this.value; - this.value = (float) value; - } - - public float getValue() { - return getValue(1); - } - - public float getValue(float partialTicks) { - return interpolator.interpolate(partialTicks, previousValue, value); - } - - public boolean settled() { - return Mth.equal((double) previousValue, value); - } - - public float getChaseTarget() { - return chaseTarget; - } - - public void forceNextSync() { - forcedSync = true; - } - - public CompoundTag writeNBT() { - CompoundTag compoundNBT = new CompoundTag(); - compoundNBT.putFloat("Speed", chaseSpeed); - compoundNBT.putFloat("Target", chaseTarget); - compoundNBT.putFloat("Value", value); - if (forcedSync) - compoundNBT.putBoolean("Force", true); - forcedSync = false; - return compoundNBT; - } - - public void readNBT(CompoundTag compoundNBT, boolean clientPacket) { - if (!clientPacket || compoundNBT.contains("Force")) - startWithValue(compoundNBT.getFloat("Value")); - readChaser(compoundNBT); - } - - protected void readChaser(CompoundTag compoundNBT) { - chaseSpeed = compoundNBT.getFloat("Speed"); - chaseTarget = compoundNBT.getFloat("Target"); - } - - @FunctionalInterface - public interface Interpolator { - float interpolate(double progress, double current, double target); - } - - @FunctionalInterface - public interface Chaser { - - Chaser IDLE = (c, s, t) -> (float) c; - Chaser EXP = exp(Double.MAX_VALUE); - Chaser LINEAR = (c, s, t) -> (float) (c + Mth.clamp(t - c, -s, s)); - - static Chaser exp(double maxEffectiveSpeed) { - return (c, s, t) -> (float) (c + Mth.clamp((t - c) * s, -maxEffectiveSpeed, maxEffectiveSpeed)); - } - - float chase(double current, double speed, double target); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/PhysicalFloat.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/PhysicalFloat.java deleted file mode 100644 index c4eb9d4..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/animation/PhysicalFloat.java +++ /dev/null @@ -1,90 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.animation; - -import net.minecraft.util.Mth; - -import java.util.ArrayList; - -public class PhysicalFloat { - - float previousValue; - float value; - - float previousSpeed; - float speed; - float limit = Float.NaN; - - float mass; - - private final ArrayList forces = new ArrayList<>(); - - public static PhysicalFloat create() { - return new PhysicalFloat(1); - } - - public static PhysicalFloat create(float mass) { - return new PhysicalFloat(mass); - } - - public PhysicalFloat(float mass) { - this.mass = mass; - } - - public PhysicalFloat startAt(double value) { - previousValue = this.value = (float) value; - return this; - } - - public PhysicalFloat withDrag(double drag) { - return addForce(new Force.Drag((float) drag)); - } - - public PhysicalFloat zeroing(double g) { - return addForce(new Force.Zeroing((float) g)); - } - - public PhysicalFloat withLimit(float limit) { - this.limit = limit; - return this; - } - - public void tick() { - previousSpeed = speed; - previousValue = value; - - float totalImpulse = 0; - for (Force force : forces) - totalImpulse += force.get(mass, value, speed) / mass; - - speed += totalImpulse; - - forces.removeIf(Force::finished); - - if (Float.isFinite(limit)) { - speed = Mth.clamp(speed, -limit, limit); - } - - value += speed; - } - - public PhysicalFloat addForce(Force f) { - forces.add(f); - return this; - } - - public PhysicalFloat bump(double force) { - return addForce(new Force.Impulse((float) force)); - } - - public PhysicalFloat bump(int time, double force) { - return addForce(new Force.OverTime(time, (float) force)); - } - - public float getValue() { - return getValue(1); - } - - public float getValue(float partialTicks) { - return Mth.lerp(partialTicks, previousValue, value); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockParams.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockParams.java index e05c7e8..f213b6d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockParams.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockParams.java @@ -1,9 +1,9 @@ package nl.requios.effortlessbuilding.create.foundation.utility.ghost; +import net.createmod.catnip.theme.Color; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; import java.util.function.Supplier; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockRenderer.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockRenderer.java index 6a80740..ed6c5ac 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlockRenderer.java @@ -1,9 +1,10 @@ package nl.requios.effortlessbuilding.create.foundation.utility.ghost; -import com.jozufozu.flywheel.core.model.ModelUtil; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; +import net.createmod.catnip.render.SuperRenderTypeBuffer; +import net.createmod.catnip.theme.Color; +import net.createmod.ponder.render.VirtualRenderHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LightTexture; @@ -19,7 +20,6 @@ import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.client.model.data.ModelData; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; import javax.annotation.Nullable; import java.util.List; @@ -56,10 +56,10 @@ public abstract class GhostBlockRenderer { ms.pushPose(); ms.translate(pos.getX(), pos.getY(), pos.getZ()); - for (RenderType layer : model.getRenderTypes(state, RandomSource.create(42L), ModelUtil.VIRTUAL_DATA)) { + for (RenderType layer : model.getRenderTypes(state, RandomSource.create(42L), VirtualRenderHelper.VIRTUAL_DATA)) { VertexConsumer vb = buffer.getEarlyBuffer(layer); renderer.renderModel(ms.last(), vb, state, model, 1f, 1f, 1f, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, - ModelUtil.VIRTUAL_DATA, layer); + VirtualRenderHelper.VIRTUAL_DATA, layer); } ms.popPose(); @@ -93,7 +93,7 @@ public abstract class GhostBlockRenderer { renderModel(ms.last(), vb, state, model, color.getRedAsFloat(), color.getGreenAsFloat(), color.getBlueAsFloat(), alpha, LevelRenderer.getLightColor(mc.level, pos), OverlayTexture.NO_OVERLAY, - ModelUtil.VIRTUAL_DATA, layer); + VirtualRenderHelper.VIRTUAL_DATA, layer); ms.popPose(); } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlocks.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlocks.java index 96c2893..a966aaa 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlocks.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/ghost/GhostBlocks.java @@ -1,7 +1,7 @@ package nl.requios.effortlessbuilding.create.foundation.utility.ghost; import com.mojang.blaze3d.vertex.PoseStack; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; +import net.createmod.catnip.render.SuperRenderTypeBuffer; import net.minecraft.util.Mth; import net.minecraft.world.level.block.state.BlockState; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/AABBOutline.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/AABBOutline.java deleted file mode 100644 index 5c85797..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/AABBOutline.java +++ /dev/null @@ -1,100 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.outliner; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; - -public class AABBOutline extends Outline { - - protected AABB bb; - - public AABBOutline(AABB bb) { - this.setBounds(bb); - } - - @Override - public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { - renderBB(ms, buffer, bb); - } - - public void renderBB(PoseStack ms, SuperRenderTypeBuffer buffer, AABB bb) { - Vec3 projectedView = Minecraft.getInstance().gameRenderer.getMainCamera() - .getPosition(); - boolean noCull = bb.contains(projectedView); - bb = bb.inflate(noCull ? -1 / 128d : 1 / 128d); - noCull |= params.disableCull; - - Vec3 xyz = new Vec3(bb.minX, bb.minY, bb.minZ); - Vec3 Xyz = new Vec3(bb.maxX, bb.minY, bb.minZ); - Vec3 xYz = new Vec3(bb.minX, bb.maxY, bb.minZ); - Vec3 XYz = new Vec3(bb.maxX, bb.maxY, bb.minZ); - Vec3 xyZ = new Vec3(bb.minX, bb.minY, bb.maxZ); - Vec3 XyZ = new Vec3(bb.maxX, bb.minY, bb.maxZ); - Vec3 xYZ = new Vec3(bb.minX, bb.maxY, bb.maxZ); - Vec3 XYZ = new Vec3(bb.maxX, bb.maxY, bb.maxZ); - - Vec3 start = xyz; - renderAACuboidLine(ms, buffer, start, Xyz); - renderAACuboidLine(ms, buffer, start, xYz); - renderAACuboidLine(ms, buffer, start, xyZ); - - start = XyZ; - renderAACuboidLine(ms, buffer, start, xyZ); - renderAACuboidLine(ms, buffer, start, XYZ); - renderAACuboidLine(ms, buffer, start, Xyz); - - start = XYz; - renderAACuboidLine(ms, buffer, start, xYz); - renderAACuboidLine(ms, buffer, start, Xyz); - renderAACuboidLine(ms, buffer, start, XYZ); - - start = xYZ; - renderAACuboidLine(ms, buffer, start, XYZ); - renderAACuboidLine(ms, buffer, start, xyZ); - renderAACuboidLine(ms, buffer, start, xYz); - - renderFace(ms, buffer, Direction.NORTH, xYz, XYz, Xyz, xyz, noCull); - renderFace(ms, buffer, Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, noCull); - renderFace(ms, buffer, Direction.EAST, XYz, XYZ, XyZ, Xyz, noCull); - renderFace(ms, buffer, Direction.WEST, xYZ, xYz, xyz, xyZ, noCull); - renderFace(ms, buffer, Direction.UP, xYZ, XYZ, XYz, xYz, noCull); - renderFace(ms, buffer, Direction.DOWN, xyz, Xyz, XyZ, xyZ, noCull); - - } - - protected void renderFace(PoseStack ms, SuperRenderTypeBuffer buffer, Direction direction, Vec3 p1, Vec3 p2, - Vec3 p3, Vec3 p4, boolean noCull) { - if (!params.faceTexture.isPresent()) - return; - - ResourceLocation faceTexture = params.faceTexture.get() - .getLocation(); - float alphaBefore = params.alpha; - params.alpha = - (direction == params.getHighlightedFace() && params.hightlightedFaceTexture.isPresent()) ? 1 : 0.5f; - - RenderType translucentType = RenderTypes.getOutlineTranslucent(faceTexture, !noCull); - VertexConsumer builder = buffer.getLateBuffer(translucentType); - - Axis axis = direction.getAxis(); - Vec3 uDiff = p2.subtract(p1); - Vec3 vDiff = p4.subtract(p1); - float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); - float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); - putQuadUV(ms, builder, p1, p2, p3, p4, 0, 0, maxU, maxV, Direction.UP); - params.alpha = alphaBefore; - } - - public void setBounds(AABB bb) { - this.bb = bb; - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/BlockClusterOutline.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/BlockClusterOutline.java deleted file mode 100644 index 3ef0a55..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/BlockClusterOutline.java +++ /dev/null @@ -1,178 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.outliner; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import nl.requios.effortlessbuilding.create.AllSpecialTextures; -import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; -import nl.requios.effortlessbuilding.create.foundation.utility.Iterate; -import nl.requios.effortlessbuilding.create.foundation.utility.VecHelper; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.core.Direction.AxisDirection; -import net.minecraft.world.phys.Vec3; - -import java.util.*; - -public class BlockClusterOutline extends Outline { - - private Cluster cluster; - - public BlockClusterOutline(Iterable selection) { - cluster = new Cluster(); - selection.forEach(cluster::include); - } - - @Override - public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { - cluster.visibleEdges.forEach(edge -> { - Vec3 start = Vec3.atLowerCornerOf(edge.pos); - Direction direction = Direction.get(AxisDirection.POSITIVE, edge.axis); - renderAACuboidLine(ms, buffer, start, Vec3.atLowerCornerOf(edge.pos.relative(direction))); - }); - - Optional faceTexture = params.faceTexture; - if (!faceTexture.isPresent()) - return; - - RenderType translucentType = RenderTypes.getOutlineTranslucent(faceTexture.get() - .getLocation(), true); - VertexConsumer builder = buffer.getLateBuffer(translucentType); - - cluster.visibleFaces.forEach((face, axisDirection) -> { - Direction direction = Direction.get(axisDirection, face.axis); - BlockPos pos = face.pos; - if (axisDirection == AxisDirection.POSITIVE) - pos = pos.relative(direction.getOpposite()); - renderBlockFace(ms, builder, pos, direction); - }); - } - - static Vec3 xyz = new Vec3(-.5, -.5, -.5); - static Vec3 Xyz = new Vec3(.5, -.5, -.5); - static Vec3 xYz = new Vec3(-.5, .5, -.5); - static Vec3 XYz = new Vec3(.5, .5, -.5); - static Vec3 xyZ = new Vec3(-.5, -.5, .5); - static Vec3 XyZ = new Vec3(.5, -.5, .5); - static Vec3 xYZ = new Vec3(-.5, .5, .5); - static Vec3 XYZ = new Vec3(.5, .5, .5); - - protected void renderBlockFace(PoseStack ms, VertexConsumer builder, BlockPos pos, Direction face) { - Vec3 center = VecHelper.getCenterOf(pos); - Vec3 offset = Vec3.atLowerCornerOf(face.getNormal()); - offset = offset.scale(1 / 128d); - center = center.add(offset); - - ms.pushPose(); - ms.translate(center.x, center.y, center.z); - - switch (face) { - case DOWN: - putQuad(ms, builder, xyz, Xyz, XyZ, xyZ, face); - break; - case EAST: - putQuad(ms, builder, XYz, XYZ, XyZ, Xyz, face); - break; - case NORTH: - putQuad(ms, builder, xYz, XYz, Xyz, xyz, face); - break; - case SOUTH: - putQuad(ms, builder, XYZ, xYZ, xyZ, XyZ, face); - break; - case UP: - putQuad(ms, builder, xYZ, XYZ, XYz, xYz, face); - break; - case WEST: - putQuad(ms, builder, xYZ, xYz, xyz, xyZ, face); - default: - break; - } - - ms.popPose(); - } - - private static class Cluster { - - private Map visibleFaces; - private Set visibleEdges; - - public Cluster() { - visibleEdges = new HashSet<>(); - visibleFaces = new HashMap<>(); - } - - public void include(BlockPos pos) { - - // 6 FACES - for (Axis axis : Iterate.axes) { - Direction direction = Direction.get(AxisDirection.POSITIVE, axis); - for (int offset : Iterate.zeroAndOne) { - MergeEntry entry = new MergeEntry(axis, pos.relative(direction, offset)); - if (visibleFaces.remove(entry) == null) - visibleFaces.put(entry, offset == 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE); - } - } - - // 12 EDGES - for (Axis axis : Iterate.axes) { - for (Axis axis2 : Iterate.axes) { - if (axis == axis2) - continue; - for (Axis axis3 : Iterate.axes) { - if (axis == axis3) - continue; - if (axis2 == axis3) - continue; - - Direction direction = Direction.get(AxisDirection.POSITIVE, axis2); - Direction direction2 = Direction.get(AxisDirection.POSITIVE, axis3); - - for (int offset : Iterate.zeroAndOne) { - BlockPos entryPos = pos.relative(direction, offset); - for (int offset2 : Iterate.zeroAndOne) { - entryPos = entryPos.relative(direction2, offset2); - MergeEntry entry = new MergeEntry(axis, entryPos); - if (!visibleEdges.remove(entry)) - visibleEdges.add(entry); - } - } - } - - break; - } - } - - } - - } - - private static class MergeEntry { - - private Axis axis; - private BlockPos pos; - - public MergeEntry(Axis axis, BlockPos pos) { - this.axis = axis; - this.pos = pos; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof MergeEntry)) - return false; - - MergeEntry other = (MergeEntry) o; - return this.axis == other.axis && this.pos.equals(other.pos); - } - - @Override - public int hashCode() { - return this.pos.hashCode() * 31 + axis.ordinal(); - } - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/ChasingAABBOutline.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/ChasingAABBOutline.java deleted file mode 100644 index d5639ea..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/ChasingAABBOutline.java +++ /dev/null @@ -1,41 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.outliner; - -import com.mojang.blaze3d.vertex.PoseStack; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.AABB; - -public class ChasingAABBOutline extends AABBOutline { - - AABB targetBB; - AABB prevBB; - - public ChasingAABBOutline(AABB bb) { - super(bb); - prevBB = bb.inflate(0); - targetBB = bb.inflate(0); - } - - public void target(AABB target) { - targetBB = target; - } - - @Override - public void tick() { - prevBB = bb; - setBounds(interpolateBBs(bb, targetBB, .5f)); - } - - @Override - public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { - renderBB(ms, buffer, interpolateBBs(prevBB, bb, pt)); - } - - private static AABB interpolateBBs(AABB current, AABB target, float pt) { - return new AABB(Mth.lerp(pt, current.minX, target.minX), - Mth.lerp(pt, current.minY, target.minY), Mth.lerp(pt, current.minZ, target.minZ), - Mth.lerp(pt, current.maxX, target.maxX), Mth.lerp(pt, current.maxY, target.maxY), - Mth.lerp(pt, current.maxZ, target.maxZ)); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/LineOutline.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/LineOutline.java deleted file mode 100644 index 2829a8d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/LineOutline.java +++ /dev/null @@ -1,65 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.outliner; - -import com.mojang.blaze3d.vertex.PoseStack; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.Vec3; - -public class LineOutline extends Outline { - - protected Vec3 start = Vec3.ZERO; - protected Vec3 end = Vec3.ZERO; - - public LineOutline set(Vec3 start, Vec3 end) { - this.start = start; - this.end = end; - return this; - } - - @Override - public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { - renderCuboidLine(ms, buffer, start, end); - } - - public static class EndChasingLineOutline extends LineOutline { - - float prevProgress = 0; - float progress = 0; - private boolean lockStart; - - public EndChasingLineOutline(boolean lockStart) { - this.lockStart = lockStart; - } - - @Override - public void tick() {} - - public EndChasingLineOutline setProgress(float progress) { - prevProgress = this.progress; - this.progress = progress; - return this; - } - - @Override - public LineOutline set(Vec3 start, Vec3 end) { - if (!end.equals(this.end)) - super.set(start, end); - return this; - } - - @Override - public void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { - float distanceToTarget = Mth.lerp(pt, prevProgress, progress); - if (!lockStart) - distanceToTarget = 1 - distanceToTarget; - Vec3 start = lockStart ? this.end : this.start; - Vec3 end = lockStart ? this.start : this.end; - - start = end.add(this.start.subtract(end) - .scale(distanceToTarget)); - renderCuboidLine(ms, buffer, start, end); - } - - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outline.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outline.java deleted file mode 100644 index 898699f..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outline.java +++ /dev/null @@ -1,246 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.outliner; - -import com.jozufozu.flywheel.util.transform.TransformStack; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import nl.requios.effortlessbuilding.create.AllSpecialTextures; -import nl.requios.effortlessbuilding.create.foundation.render.RenderTypes; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; -import nl.requios.effortlessbuilding.create.foundation.utility.AngleHelper; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; -import nl.requios.effortlessbuilding.create.foundation.utility.VecHelper; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.core.Direction; -import net.minecraft.core.Direction.Axis; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.Vec3; -import org.joml.Matrix3f; - -import javax.annotation.Nullable; -import java.util.Optional; - -public abstract class Outline { - - protected OutlineParams params; - protected Matrix3f transformNormals; // TODO: not used? - - public Outline() { - params = new OutlineParams(); - } - - public abstract void render(PoseStack ms, SuperRenderTypeBuffer buffer, float pt); - - public void tick() {} - - public OutlineParams getParams() { - return params; - } - - public void renderCuboidLine(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 start, Vec3 end) { - Vec3 diff = end.subtract(start); - float hAngle = AngleHelper.deg(Mth.atan2(diff.x, diff.z)); - float hDistance = (float) diff.multiply(1, 0, 1) - .length(); - float vAngle = AngleHelper.deg(Mth.atan2(hDistance, diff.y)) - 90; - ms.pushPose(); - TransformStack.cast(ms) - .translate(start) - .rotateY(hAngle).rotateX(vAngle); - renderAACuboidLine(ms, buffer, Vec3.ZERO, new Vec3(0, 0, diff.length())); - ms.popPose(); - } - - public void renderAACuboidLine(PoseStack ms, SuperRenderTypeBuffer buffer, Vec3 start, Vec3 end) { - float lineWidth = params.getLineWidth(); - if (lineWidth == 0) - return; - - VertexConsumer builder = buffer.getBuffer(RenderTypes.getOutlineSolid()); - - Vec3 diff = end.subtract(start); - if (diff.x + diff.y + diff.z < 0) { - Vec3 temp = start; - start = end; - end = temp; - diff = diff.scale(-1); - } - - Vec3 extension = diff.normalize() - .scale(lineWidth / 2); - Vec3 plane = VecHelper.axisAlingedPlaneOf(diff); - Direction face = Direction.getNearest(diff.x, diff.y, diff.z); - Axis axis = face.getAxis(); - - start = start.subtract(extension); - end = end.add(extension); - plane = plane.scale(lineWidth / 2); - - Vec3 a1 = plane.add(start); - Vec3 b1 = plane.add(end); - plane = VecHelper.rotate(plane, -90, axis); - Vec3 a2 = plane.add(start); - Vec3 b2 = plane.add(end); - plane = VecHelper.rotate(plane, -90, axis); - Vec3 a3 = plane.add(start); - Vec3 b3 = plane.add(end); - plane = VecHelper.rotate(plane, -90, axis); - Vec3 a4 = plane.add(start); - Vec3 b4 = plane.add(end); - - if (params.disableNormals) { - face = Direction.UP; - putQuad(ms, builder, b4, b3, b2, b1, face); - putQuad(ms, builder, a1, a2, a3, a4, face); - putQuad(ms, builder, a1, b1, b2, a2, face); - putQuad(ms, builder, a2, b2, b3, a3, face); - putQuad(ms, builder, a3, b3, b4, a4, face); - putQuad(ms, builder, a4, b4, b1, a1, face); - return; - } - - putQuad(ms, builder, b4, b3, b2, b1, face); - putQuad(ms, builder, a1, a2, a3, a4, face.getOpposite()); - Vec3 vec = a1.subtract(a4); - face = Direction.getNearest(vec.x, vec.y, vec.z); - putQuad(ms, builder, a1, b1, b2, a2, face); - vec = VecHelper.rotate(vec, -90, axis); - face = Direction.getNearest(vec.x, vec.y, vec.z); - putQuad(ms, builder, a2, b2, b3, a3, face); - vec = VecHelper.rotate(vec, -90, axis); - face = Direction.getNearest(vec.x, vec.y, vec.z); - putQuad(ms, builder, a3, b3, b4, a4, face); - vec = VecHelper.rotate(vec, -90, axis); - face = Direction.getNearest(vec.x, vec.y, vec.z); - putQuad(ms, builder, a4, b4, b1, a1, face); - } - - public void putQuad(PoseStack ms, VertexConsumer builder, Vec3 v1, Vec3 v2, Vec3 v3, Vec3 v4, - Direction normal) { - putQuadUV(ms, builder, v1, v2, v3, v4, 0, 0, 1, 1, normal); - } - - public void putQuadUV(PoseStack ms, VertexConsumer builder, Vec3 v1, Vec3 v2, Vec3 v3, Vec3 v4, float minU, - float minV, float maxU, float maxV, Direction normal) { - putVertex(ms, builder, v1, minU, minV, normal); - putVertex(ms, builder, v2, maxU, minV, normal); - putVertex(ms, builder, v3, maxU, maxV, normal); - putVertex(ms, builder, v4, minU, maxV, normal); - } - - protected void putVertex(PoseStack ms, VertexConsumer builder, Vec3 pos, float u, float v, Direction normal) { - putVertex(ms.last(), builder, (float) pos.x, (float) pos.y, (float) pos.z, u, v, normal); - } - - protected void putVertex(PoseStack.Pose pose, VertexConsumer builder, float x, float y, float z, float u, float v, Direction normal) { - Color rgb = params.rgb; - if (transformNormals == null) - transformNormals = pose.normal(); - - int xOffset = 0; - int yOffset = 0; - int zOffset = 0; - - if (normal != null) { - xOffset = normal.getStepX(); - yOffset = normal.getStepY(); - zOffset = normal.getStepZ(); - } - - builder.vertex(pose.pose(), x, y, z) - .color(rgb.getRedAsFloat(), rgb.getGreenAsFloat(), rgb.getBlueAsFloat(), rgb.getAlphaAsFloat() * params.alpha) - .uv(u, v) - .overlayCoords(OverlayTexture.NO_OVERLAY) - .uv2(params.lightMap) - .normal(pose.normal(), xOffset, yOffset, zOffset) - .endVertex(); - - transformNormals = null; - } - - public static class OutlineParams { - protected Optional faceTexture; - protected Optional hightlightedFaceTexture; - protected Direction highlightedFace; - protected boolean fadeLineWidth; - protected boolean disableCull; - protected boolean disableNormals; - protected float alpha; - protected int lightMap; - protected Color rgb; - private float lineWidth; - - public OutlineParams() { - faceTexture = hightlightedFaceTexture = Optional.empty(); - alpha = 1; - lineWidth = 1 / 32f; - fadeLineWidth = true; - rgb = Color.WHITE; - lightMap = LightTexture.FULL_BRIGHT; - } - - // builder - - public OutlineParams colored(int color) { - rgb = new Color(color, false); - return this; - } - - public OutlineParams colored(Color c) { - rgb = c.copy(); - return this; - } - - public OutlineParams lightMap(int light) { - lightMap = light; - return this; - } - - public OutlineParams lineWidth(float width) { - this.lineWidth = width; - return this; - } - - public OutlineParams withFaceTexture(AllSpecialTextures texture) { - this.faceTexture = Optional.ofNullable(texture); - return this; - } - - public OutlineParams clearTextures() { - return this.withFaceTextures(null, null); - } - - public OutlineParams withFaceTextures(AllSpecialTextures texture, AllSpecialTextures highlightTexture) { - this.faceTexture = Optional.ofNullable(texture); - this.hightlightedFaceTexture = Optional.ofNullable(highlightTexture); - return this; - } - - public OutlineParams highlightFace(@Nullable Direction face) { - highlightedFace = face; - return this; - } - - public OutlineParams disableNormals() { - disableNormals = true; - return this; - } - - public OutlineParams disableCull() { - disableCull = true; - return this; - } - - // getter - - public float getLineWidth() { - return fadeLineWidth ? alpha * lineWidth : lineWidth; - } - - public Direction getHighlightedFace() { - return highlightedFace; - } - - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outliner.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outliner.java deleted file mode 100644 index 5588623..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/outliner/Outliner.java +++ /dev/null @@ -1,185 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.outliner; - -import com.mojang.blaze3d.vertex.PoseStack; -import nl.requios.effortlessbuilding.create.foundation.render.SuperRenderTypeBuffer; -import nl.requios.effortlessbuilding.create.foundation.utility.outliner.LineOutline.EndChasingLineOutline; -import nl.requios.effortlessbuilding.create.foundation.utility.outliner.Outline.OutlineParams; -import net.minecraft.core.BlockPos; -import net.minecraft.util.Mth; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; - -import java.util.*; - -public class Outliner { - - private final Map outlines = Collections.synchronizedMap(new HashMap<>()); - private final Map outlinesView = Collections.unmodifiableMap(outlines); - - // Facade - - public OutlineParams showLine(Object slot, Vec3 start, Vec3 end) { - if (!outlines.containsKey(slot)) { - LineOutline outline = new LineOutline(); - outlines.put(slot, new OutlineEntry(outline)); - } - OutlineEntry entry = outlines.get(slot); - entry.ticksTillRemoval = 1; - ((LineOutline) entry.outline).set(start, end); - return entry.outline.getParams(); - } - - public OutlineParams endChasingLine(Object slot, Vec3 start, Vec3 end, float chasingProgress, boolean lockStart) { - if (!outlines.containsKey(slot)) { - EndChasingLineOutline outline = new EndChasingLineOutline(lockStart); - outlines.put(slot, new OutlineEntry(outline)); - } - OutlineEntry entry = outlines.get(slot); - entry.ticksTillRemoval = 1; - ((EndChasingLineOutline) entry.outline).setProgress(chasingProgress) - .set(start, end); - return entry.outline.getParams(); - } - - public OutlineParams showAABB(Object slot, AABB bb, int ttl) { - createAABBOutlineIfMissing(slot, bb); - ChasingAABBOutline outline = getAndRefreshAABB(slot, ttl); - outline.prevBB = outline.targetBB = outline.bb = bb; - return outline.getParams(); - } - - public OutlineParams showAABB(Object slot, AABB bb) { - createAABBOutlineIfMissing(slot, bb); - ChasingAABBOutline outline = getAndRefreshAABB(slot); - outline.prevBB = outline.targetBB = outline.bb = bb; - return outline.getParams(); - } - - public OutlineParams chaseAABB(Object slot, AABB bb) { - createAABBOutlineIfMissing(slot, bb); - ChasingAABBOutline outline = getAndRefreshAABB(slot); - outline.targetBB = bb; - return outline.getParams(); - } - - public OutlineParams showCluster(Object slot, Iterable selection) { - BlockClusterOutline outline = new BlockClusterOutline(selection); - OutlineEntry entry = new OutlineEntry(outline); - outlines.put(slot, entry); - return entry.getOutline() - .getParams(); - } - - public void keep(Object slot) { - if (outlines.containsKey(slot)) - outlines.get(slot).ticksTillRemoval = 1; - } - - //ADDED - public void keep(Object slot, int ticks) { - if (outlines.containsKey(slot)) - outlines.get(slot).ticksTillRemoval = ticks; - } - - public void remove(Object slot) { - outlines.remove(slot); - } - - public Optional edit(Object slot) { - keep(slot); - if (outlines.containsKey(slot)) - return Optional.of(outlines.get(slot) - .getOutline() - .getParams()); - return Optional.empty(); - } - - public Map getOutlines() { - return outlinesView; - } - - // Utility - - private void createAABBOutlineIfMissing(Object slot, AABB bb) { - if (!outlines.containsKey(slot) || !(outlines.get(slot).outline instanceof AABBOutline)) { - ChasingAABBOutline outline = new ChasingAABBOutline(bb); - outlines.put(slot, new OutlineEntry(outline)); - } - } - - private ChasingAABBOutline getAndRefreshAABB(Object slot) { - OutlineEntry entry = outlines.get(slot); - entry.ticksTillRemoval = 1; - return (ChasingAABBOutline) entry.getOutline(); - } - - private ChasingAABBOutline getAndRefreshAABB(Object slot, int ttl) { - OutlineEntry entry = outlines.get(slot); - entry.ticksTillRemoval = ttl; - return (ChasingAABBOutline) entry.getOutline(); - } - - // Maintenance - - public void tickOutlines() { - Iterator iterator = outlines.values() - .iterator(); - while (iterator.hasNext()) { - OutlineEntry entry = iterator.next(); - entry.tick(); - if (!entry.isAlive()) - iterator.remove(); - } - } - - public void renderOutlines(PoseStack ms, SuperRenderTypeBuffer buffer, float pt) { - outlines.forEach((key, entry) -> { - Outline outline = entry.getOutline(); - OutlineParams params = outline.getParams(); - params.alpha = 1; - if (entry.isFading()) { - int prevTicks = entry.ticksTillRemoval + 1; - float fadeticks = OutlineEntry.fadeTicks; - float lastAlpha = prevTicks >= 0 ? 1 : 1 + (prevTicks / fadeticks); - float currentAlpha = 1 + (entry.ticksTillRemoval / fadeticks); - float alpha = Mth.lerp(pt, lastAlpha, currentAlpha); - - params.alpha = alpha * alpha * alpha; - if (params.alpha < 1 / 8f) - return; - } - outline.render(ms, buffer, pt); - }); - } - - public static class OutlineEntry { - - static final int fadeTicks = 4; - private Outline outline; - private int ticksTillRemoval; - - public OutlineEntry(Outline outline) { - this.outline = outline; - ticksTillRemoval = 1; - } - - public void tick() { - ticksTillRemoval--; - outline.tick(); - } - - public boolean isAlive() { - return ticksTillRemoval >= -fadeTicks; - } - - public boolean isFading() { - return ticksTillRemoval < 0; - } - - public Outline getOutline() { - return outline; - } - - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/DummyStatusListener.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/DummyStatusListener.java deleted file mode 100644 index ad9856e..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/DummyStatusListener.java +++ /dev/null @@ -1,23 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; - -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkStatus; - -import javax.annotation.Nullable; - -public class DummyStatusListener implements ChunkProgressListener { - - @Override - public void updateSpawnPos(ChunkPos pCenter) {} - - @Override - public void onStatusChange(ChunkPos pChunkPosition, @Nullable ChunkStatus pNewStatus) {} - - @Override - public void start() {} - - @Override - public void stop() {} - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/PlacementSimulationServerWorld.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/PlacementSimulationServerWorld.java deleted file mode 100644 index e596b9d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/PlacementSimulationServerWorld.java +++ /dev/null @@ -1,62 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; - -import java.util.HashMap; -import java.util.function.Predicate; - -public class PlacementSimulationServerWorld extends WrappedServerWorld { - public HashMap blocksAdded; - - public PlacementSimulationServerWorld(ServerLevel wrapped) { - super(wrapped); - blocksAdded = new HashMap<>(); - } - - public void clear() { - blocksAdded.clear(); - } - - @Override - public boolean setBlock(BlockPos pos, BlockState newState, int flags) { - blocksAdded.put(pos.immutable(), newState); - return true; - } - - @Override - public boolean setBlockAndUpdate(BlockPos pos, BlockState state) { - return setBlock(pos, state, 0); - } - - @Override - public boolean isStateAtPosition(BlockPos pos, Predicate condition) { - return condition.test(getBlockState(pos)); - } - - @Override - public boolean isLoaded(BlockPos pos) { - return true; - } - - @Override - public boolean isAreaLoaded(BlockPos center, int range) { - return true; - } - - @Override - public BlockState getBlockState(BlockPos pos) { - if (blocksAdded.containsKey(pos)) - return blocksAdded.get(pos); - return Blocks.AIR.defaultBlockState(); - } - - @Override - public FluidState getFluidState(BlockPos pos) { - return getBlockState(pos).getFluidState(); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/RayTraceWorld.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/RayTraceWorld.java deleted file mode 100644 index 74b907b..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/RayTraceWorld.java +++ /dev/null @@ -1,47 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; - -import java.util.function.BiFunction; - -public class RayTraceWorld implements BlockGetter { - - private final LevelAccessor template; - private final BiFunction stateGetter; - - public RayTraceWorld(LevelAccessor template, BiFunction stateGetter) { - this.template = template; - this.stateGetter = stateGetter; - } - - @Override - public BlockEntity getBlockEntity(BlockPos pos) { - return template.getBlockEntity(pos); - } - - @Override - public BlockState getBlockState(BlockPos pos) { - return stateGetter.apply(pos, template.getBlockState(pos)); - } - - @Override - public FluidState getFluidState(BlockPos pos) { - return template.getFluidState(pos); - } - - @Override - public int getHeight() { - return template.getHeight(); - } - - @Override - public int getMinBuildHeight() { - return template.getMinBuildHeight(); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedClientWorld.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedClientWorld.java deleted file mode 100644 index 0f65faa..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedClientWorld.java +++ /dev/null @@ -1,140 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.ai.targeting.TargetingConditions; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.ColorResolver; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; -import java.util.List; - -@OnlyIn(Dist.CLIENT) -@SuppressWarnings("deprecation") -@ParametersAreNonnullByDefault -public class WrappedClientWorld extends ClientLevel { - private static final Minecraft mc = Minecraft.getInstance(); - protected Level world; - - private WrappedClientWorld(Level world) { - super(mc.getConnection(), mc.level.getLevelData(), world.dimension(), world.dimensionTypeRegistration(), - mc.getConnection().serverChunkRadius, mc.level.getServerSimulationDistance(), world.getProfilerSupplier(), - mc.levelRenderer, world.isDebug(), world.getBiomeManager().biomeZoomSeed); - this.world = world; - } - - public static WrappedClientWorld of(Level world) { - return new WrappedClientWorld(world); - } - - @Override - public boolean hasChunkAt(BlockPos pos) { - return world.hasChunkAt(pos); - } - - @Override - public boolean isLoaded(BlockPos pos) { - return world.isLoaded(pos); - } - - @Override - public BlockState getBlockState(BlockPos pos) { - return world.getBlockState(pos); - } - - // FIXME: blockstate#getCollisionShape with WrappedClientWorld gives unreliable - // data (maybe) - - @Override - public int getBrightness(LightLayer type, BlockPos pos) { - return world.getBrightness(type, pos); - } - - @Override - public int getLightEmission(BlockPos pos) { - return world.getLightEmission(pos); - } - - @Override - public FluidState getFluidState(BlockPos pos) { - return world.getFluidState(pos); - } - - @Nullable - @Override - public T getNearestEntity(List p_217361_1_, TargetingConditions p_217361_2_, - @Nullable LivingEntity p_217361_3_, double p_217361_4_, double p_217361_6_, double p_217361_8_) { - return world.getNearestEntity(p_217361_1_, p_217361_2_, p_217361_3_, p_217361_4_, p_217361_6_, p_217361_8_); - } - - @Override - public int getBlockTint(BlockPos p_225525_1_, ColorResolver p_225525_2_) { - return world.getBlockTint(p_225525_1_, p_225525_2_); - } - - // FIXME: Emissive Lighting might not light stuff properly - - @Override - public void addParticle(ParticleOptions p_195594_1_, double p_195594_2_, double p_195594_4_, double p_195594_6_, - double p_195594_8_, double p_195594_10_, double p_195594_12_) { - world.addParticle(p_195594_1_, p_195594_2_, p_195594_4_, p_195594_6_, p_195594_8_, p_195594_10_, p_195594_12_); - } - - @Override - public void addParticle(ParticleOptions p_195590_1_, boolean p_195590_2_, double p_195590_3_, double p_195590_5_, - double p_195590_7_, double p_195590_9_, double p_195590_11_, double p_195590_13_) { - world.addParticle(p_195590_1_, p_195590_2_, p_195590_3_, p_195590_5_, p_195590_7_, p_195590_9_, p_195590_11_, - p_195590_13_); - } - - @Override - public void addAlwaysVisibleParticle(ParticleOptions p_195589_1_, double p_195589_2_, double p_195589_4_, - double p_195589_6_, double p_195589_8_, double p_195589_10_, double p_195589_12_) { - world.addAlwaysVisibleParticle(p_195589_1_, p_195589_2_, p_195589_4_, p_195589_6_, p_195589_8_, p_195589_10_, - p_195589_12_); - } - - @Override - public void addAlwaysVisibleParticle(ParticleOptions p_217404_1_, boolean p_217404_2_, double p_217404_3_, - double p_217404_5_, double p_217404_7_, double p_217404_9_, double p_217404_11_, double p_217404_13_) { - world.addAlwaysVisibleParticle(p_217404_1_, p_217404_2_, p_217404_3_, p_217404_5_, p_217404_7_, p_217404_9_, - p_217404_11_, p_217404_13_); - } - - @Override - public void playLocalSound(double p_184134_1_, double p_184134_3_, double p_184134_5_, SoundEvent p_184134_7_, - SoundSource p_184134_8_, float p_184134_9_, float p_184134_10_, boolean p_184134_11_) { - world.playLocalSound(p_184134_1_, p_184134_3_, p_184134_5_, p_184134_7_, p_184134_8_, p_184134_9_, p_184134_10_, - p_184134_11_); - } - - @Override - public void playSound(@Nullable Player p_184148_1_, double p_184148_2_, double p_184148_4_, double p_184148_6_, - SoundEvent p_184148_8_, SoundSource p_184148_9_, float p_184148_10_, float p_184148_11_) { - world.playSound(p_184148_1_, p_184148_2_, p_184148_4_, p_184148_6_, p_184148_8_, p_184148_9_, p_184148_10_, - p_184148_11_); - } - - @Nullable - @Override - public BlockEntity getBlockEntity(BlockPos p_175625_1_) { - return world.getBlockEntity(p_175625_1_); - } - - public Level getWrappedWorld() { - return world; - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedServerWorld.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedServerWorld.java deleted file mode 100644 index f1675b8..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedServerWorld.java +++ /dev/null @@ -1,120 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; - -import net.minecraft.MethodsReturnNonnullByDefault; -import net.minecraft.Util; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.crafting.RecipeManager; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; -import net.minecraft.world.level.storage.ServerLevelData; -import net.minecraft.world.ticks.LevelTicks; - -import javax.annotation.ParametersAreNonnullByDefault; -import java.util.Collections; -import java.util.List; - -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -public class WrappedServerWorld extends ServerLevel { - - protected ServerLevel world; - - public WrappedServerWorld(ServerLevel world) { - super(world.getServer(), Util.backgroundExecutor(), world.getServer().storageSource, - (ServerLevelData) world.getLevelData(), world.dimension(), - new LevelStem(world.dimensionTypeRegistration(), world.getChunkSource().getGenerator()), - new DummyStatusListener(), world.isDebug(), world.getBiomeManager().biomeZoomSeed, - Collections.emptyList(), false, world.getRandomSequences()); - this.world = world; - } - - @Override - public float getSunAngle(float p_72826_1_) { - return 0; - } - - @Override - public int getMaxLocalRawBrightness(BlockPos pos) { - return 15; - } - - @Override - public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) { - world.sendBlockUpdated(pos, oldState, newState, flags); - } - - @Override - public LevelTicks getBlockTicks() { - return super.getBlockTicks(); - } - - @Override - public LevelTicks getFluidTicks() { - return super.getFluidTicks(); - } - - @Override - public void levelEvent(Player player, int type, BlockPos pos, int data) {} - - @Override - public List players() { - return Collections.emptyList(); - } - - @Override - public void playSound(Player player, double x, double y, double z, SoundEvent soundIn, SoundSource category, - float volume, float pitch) {} - - @Override - public void playSound(Player p_217384_1_, Entity p_217384_2_, SoundEvent p_217384_3_, SoundSource p_217384_4_, - float p_217384_5_, float p_217384_6_) {} - - @Override - public Entity getEntity(int id) { - return null; - } - - @Override - public MapItemSavedData getMapData(String mapName) { - return null; - } - - @Override - public boolean addFreshEntity(Entity entityIn) { - entityIn.level = world; - return world.addFreshEntity(entityIn); - } - - @Override - public void setMapData(String mapId, MapItemSavedData mapDataIn) {} - - @Override - public int getFreeMapId() { - return 0; - } - - @Override - public void destroyBlockProgress(int breakerId, BlockPos pos, int progress) {} - - @Override - public RecipeManager getRecipeManager() { - return world.getRecipeManager(); - } - - @Override - public Holder getUncachedNoiseBiome(int p_225604_1_, int p_225604_2_, int p_225604_3_) { - return world.getUncachedNoiseBiome(p_225604_1_, p_225604_2_, p_225604_3_); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedWorld.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedWorld.java deleted file mode 100644 index 18a1840..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/WrappedWorld.java +++ /dev/null @@ -1,267 +0,0 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; - -import net.minecraft.core.*; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.TickRateManager; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.flag.FeatureFlagSet; -import net.minecraft.world.item.crafting.RecipeManager; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkSource; -import net.minecraft.world.level.entity.LevelEntityGetter; -import net.minecraft.world.level.gameevent.GameEvent; -import net.minecraft.world.level.gameevent.GameEvent.Context; -import net.minecraft.world.level.lighting.LevelLightEngine; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; -import net.minecraft.world.level.storage.WritableLevelData; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.scores.Scoreboard; -import net.minecraft.world.ticks.LevelTickAccess; - -import javax.annotation.Nullable; -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; - -public class WrappedWorld extends Level { - - protected Level world; - protected ChunkSource chunkSource; - - protected LevelEntityGetter entityGetter = new DummyLevelEntityGetter<>(); - - public WrappedWorld(Level world) { - super((WritableLevelData) world.getLevelData(), world.dimension(), world.registryAccess(), world.dimensionTypeRegistration(), - world::getProfiler, world.isClientSide, world.isDebug(), 0, 0); - this.world = world; - } - - public void setChunkSource(ChunkSource source) { - this.chunkSource = source; - } - - public Level getLevel() { - return world; - } - - @Override - public LevelLightEngine getLightEngine() { - return world.getLightEngine(); - } - - @Override - public BlockState getBlockState(@Nullable BlockPos pos) { - return world.getBlockState(pos); - } - - @Override - public boolean isStateAtPosition(BlockPos p_217375_1_, Predicate p_217375_2_) { - return world.isStateAtPosition(p_217375_1_, p_217375_2_); - } - - @Override - @Nullable - public BlockEntity getBlockEntity(BlockPos pos) { - return world.getBlockEntity(pos); - } - - @Override - public boolean setBlock(BlockPos pos, BlockState newState, int flags) { - return world.setBlock(pos, newState, flags); - } - - @Override - public int getMaxLocalRawBrightness(BlockPos pos) { - return 15; - } - - @Override - public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) { - world.sendBlockUpdated(pos, oldState, newState, flags); - } - - @Override - public LevelTickAccess getBlockTicks() { - return world.getBlockTicks(); - } - - @Override - public LevelTickAccess getFluidTicks() { - return world.getFluidTicks(); - } - - @Override - public ChunkSource getChunkSource() { - return chunkSource != null ? chunkSource : world.getChunkSource(); - } - - @Override - public void levelEvent(@Nullable Player player, int type, BlockPos pos, int data) {} - - @Override - public List players() { - return Collections.emptyList(); - } - - @Override - public void playSeededSound(Player p_220363_, double p_220364_, double p_220365_, double p_220366_, - SoundEvent p_220367_, SoundSource p_220368_, float p_220369_, float p_220370_, long p_220371_) {} - - @Override - public void playSeededSound(Player pPlayer, double pX, double pY, double pZ, Holder pSound, - SoundSource pSource, float pVolume, float pPitch, long pSeed) {} - - @Override - public void playSeededSound(Player pPlayer, Entity pEntity, Holder pSound, SoundSource pCategory, - float pVolume, float pPitch, long pSeed) {} - - @Override - public void playSound(@Nullable Player player, double x, double y, double z, SoundEvent soundIn, - SoundSource category, float volume, float pitch) {} - - @Override - public void playSound(@Nullable Player p_217384_1_, Entity p_217384_2_, SoundEvent p_217384_3_, - SoundSource p_217384_4_, float p_217384_5_, float p_217384_6_) {} - - @Override - public Entity getEntity(int id) { - return null; - } - - @Override - public TickRateManager tickRateManager() { - return null; - } - - @Override - public MapItemSavedData getMapData(String mapName) { - return null; - } - - @Override - public boolean addFreshEntity(Entity entityIn) { - entityIn.level = world; - return world.addFreshEntity(entityIn); - } - - @Override - public void setMapData(String pMapId, MapItemSavedData pData) {} - - @Override - public int getFreeMapId() { - return world.getFreeMapId(); - } - - @Override - public void destroyBlockProgress(int breakerId, BlockPos pos, int progress) {} - - @Override - public Scoreboard getScoreboard() { - return world.getScoreboard(); - } - - @Override - public RecipeManager getRecipeManager() { - return world.getRecipeManager(); - } - - @Override - public Holder getUncachedNoiseBiome(int p_225604_1_, int p_225604_2_, int p_225604_3_) { - return world.getUncachedNoiseBiome(p_225604_1_, p_225604_2_, p_225604_3_); - } - - @Override - public RegistryAccess registryAccess() { - return world.registryAccess(); - } - - @Override - public float getShade(Direction p_230487_1_, boolean p_230487_2_) { - return world.getShade(p_230487_1_, p_230487_2_); - } - - @Override - public void updateNeighbourForOutputSignal(BlockPos p_175666_1_, Block p_175666_2_) {} - - @Override - public void gameEvent(Entity pEntity, GameEvent pEvent, BlockPos pPos) {} - - @Override - public void gameEvent(GameEvent p_220404_, Vec3 p_220405_, Context p_220406_) {} - - @Override - public String gatherChunkSourceStats() { - return world.gatherChunkSourceStats(); - } - - @Override - protected LevelEntityGetter getEntities() { - return entityGetter; - } - - // Intentionally copied from LevelHeightAccessor. Workaround for issues caused - // when other mods (such as Lithium) - // override the vanilla implementations in ways which cause WrappedWorlds to - // return incorrect, default height info. - // WrappedWorld subclasses should implement their own getMinBuildHeight and - // getHeight overrides where they deviate - // from the defaults for their dimension. - - @Override - public int getMaxBuildHeight() { - return this.getMinBuildHeight() + this.getHeight(); - } - - @Override - public int getSectionsCount() { - return this.getMaxSection() - this.getMinSection(); - } - - @Override - public int getMinSection() { - return SectionPos.blockToSectionCoord(this.getMinBuildHeight()); - } - - @Override - public int getMaxSection() { - return SectionPos.blockToSectionCoord(this.getMaxBuildHeight() - 1) + 1; - } - - @Override - public boolean isOutsideBuildHeight(BlockPos pos) { - return this.isOutsideBuildHeight(pos.getY()); - } - - @Override - public boolean isOutsideBuildHeight(int y) { - return y < this.getMinBuildHeight() || y >= this.getMaxBuildHeight(); - } - - @Override - public int getSectionIndex(int y) { - return this.getSectionIndexFromSectionY(SectionPos.blockToSectionCoord(y)); - } - - @Override - public int getSectionIndexFromSectionY(int sectionY) { - return sectionY - this.getMinSection(); - } - - @Override - public int getSectionYFromSectionIndex(int sectionIndex) { - return sectionIndex + this.getMinSection(); - } - - @Override - public FeatureFlagSet enabledFeatures() { - return world.enabledFeatures(); - } - -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/package-info.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/package-info.java deleted file mode 100644 index bb6a251..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; - -import net.minecraft.MethodsReturnNonnullByDefault; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunk.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunk.java new file mode 100644 index 0000000..02fcf08 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunk.java @@ -0,0 +1,241 @@ +package nl.requios.effortlessbuilding.create.foundation.virtualWorld; + +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.longs.LongSets; +import it.unimi.dsi.fastutil.shorts.ShortList; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.SectionPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureStart; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.ticks.BlackholeTickAccess; +import net.minecraft.world.ticks.TickContainerAccess; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiPredicate; +import java.util.function.Predicate; + +public class VirtualChunk extends ChunkAccess { + public final VirtualRenderWorld world; + + private final VirtualChunkSection[] sections; + + private boolean needsLight; + + public VirtualChunk(VirtualRenderWorld world, int x, int z) { + super(new ChunkPos(x, z), UpgradeData.EMPTY, world, world.registryAccess() + .registryOrThrow(Registries.BIOME), 0L, null, null); + + this.world = world; + + int sectionCount = world.getSectionsCount(); + this.sections = new VirtualChunkSection[sectionCount]; + + for (int i = 0; i < sectionCount; i++) { + sections[i] = new VirtualChunkSection(this, i << 4); + } + + this.needsLight = true; + +// Mods.STARLIGHT.executeIfInstalled(() -> () -> { +// ((ExtendedChunk) this).setBlockNibbles(StarLightEngine.getFilledEmptyLight(this)); +// ((ExtendedChunk) this).setSkyNibbles(StarLightEngine.getFilledEmptyLight(this)); +// }); + } + + @Override + @Nullable + public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving) { + return null; + } + + @Override + public void setBlockEntity(BlockEntity blockEntity) { + } + + @Override + public void addEntity(Entity entity) { + } + + @Override + public Set getBlockEntitiesPos() { + return Collections.emptySet(); + } + + @Override + public LevelChunkSection[] getSections() { + return sections; + } + + @Override + public Collection> getHeightmaps() { + return Collections.emptySet(); + } + + @Override + public void setHeightmap(Heightmap.Types type, long[] data) { + } + + @Override + public Heightmap getOrCreateHeightmapUnprimed(Heightmap.Types type) { + return null; + } + + @Override + public int getHeight(Heightmap.Types type, int x, int z) { + return 0; + } + + @Override + @Nullable + public StructureStart getStartForStructure(Structure structure) { + return null; + } + + @Override + public void setStartForStructure(Structure structure, StructureStart structureStart) { + } + + @Override + public Map getAllStarts() { + return Collections.emptyMap(); + } + + @Override + public void setAllStarts(Map structureStarts) { + } + + @Override + public LongSet getReferencesForStructure(Structure pStructure) { + return LongSets.emptySet(); + } + + @Override + public void addReferenceForStructure(Structure structure, long reference) { + } + + @Override + public Map getAllReferences() { + return Collections.emptyMap(); + } + + @Override + public void setAllReferences(Map structureReferencesMap) { + } + + @Override + public void setUnsaved(boolean unsaved) { + } + + @Override + public boolean isUnsaved() { + return false; + } + + @Override + public ChunkStatus getPersistedStatus() { + return ChunkStatus.LIGHT; + } + + @Override + public void removeBlockEntity(BlockPos pos) { + } + + @Override + public ShortList[] getPostProcessing() { + return new ShortList[0]; + } + + @Override + @Nullable + public CompoundTag getBlockEntityNbt(BlockPos pos) { + return null; + } + + @Override + @Nullable + public CompoundTag getBlockEntityNbtForSaving(BlockPos pos, HolderLookup.Provider registries) { + return null; + } + + @Override + public void findBlocks(@NotNull Predicate roughFilter, @NotNull BiPredicate fineFilter, @NotNull BiConsumer output) { + world.blockStates.forEach((pos, state) -> { + if (SectionPos.blockToSectionCoord(pos.getX()) == chunkPos.x && SectionPos.blockToSectionCoord(pos.getZ()) == chunkPos.z) { + if (roughFilter.test(state) && fineFilter.test(state, pos)) { + output.accept(pos, state); + } + } + }); + } + + @Override + public TickContainerAccess getBlockTicks() { + return BlackholeTickAccess.emptyContainer(); + } + + @Override + public TickContainerAccess getFluidTicks() { + return BlackholeTickAccess.emptyContainer(); + } + + @Override + public TicksToSave getTicksForSerialization() { + throw new UnsupportedOperationException(); + } + + @Override + public long getInhabitedTime() { + return 0; + } + + @Override + public void setInhabitedTime(long amount) { + } + + @Override + public boolean isLightCorrect() { + return needsLight; + } + + @Override + public void setLightCorrect(boolean lightCorrect) { + this.needsLight = lightCorrect; + } + + @Override + @Nullable + public BlockEntity getBlockEntity(BlockPos pos) { + return world.getBlockEntity(pos); + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return world.getBlockState(pos); + } + + @Override + public FluidState getFluidState(BlockPos pos) { + return world.getFluidState(pos); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSection.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSection.java new file mode 100644 index 0000000..b611094 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSection.java @@ -0,0 +1,42 @@ +package nl.requios.effortlessbuilding.create.foundation.virtualWorld; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.material.FluidState; + +public class VirtualChunkSection extends LevelChunkSection { + public final VirtualChunk owner; + + public final int xStart; + public final int yStart; + public final int zStart; + + public VirtualChunkSection(VirtualChunk owner, int yBase) { + super(owner.world.registryAccess() + .registryOrThrow(Registries.BIOME)); + this.owner = owner; + this.xStart = owner.getPos() + .getMinBlockX(); + this.yStart = yBase; + this.zStart = owner.getPos() + .getMinBlockZ(); + } + + @Override + public BlockState getBlockState(int x, int y, int z) { + // ChunkSection#getBlockState expects local chunk coordinates, so we add to get + // back into world coords. + return owner.world.getBlockState(x + xStart, y + yStart, z + zStart); + } + + @Override + public FluidState getFluidState(int x, int y, int z) { + return getBlockState(x, y, z).getFluidState(); + } + + @Override + public BlockState setBlockState(int x, int y, int z, BlockState state, boolean useLocks) { + throw new UnsupportedOperationException("Chunk sections cannot be mutated in a fake world."); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSource.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSource.java new file mode 100644 index 0000000..e201954 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualChunkSource.java @@ -0,0 +1,64 @@ +package nl.requios.effortlessbuilding.create.foundation.virtualWorld; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BooleanSupplier; + +public class VirtualChunkSource extends ChunkSource { + private final VirtualRenderWorld world; + private final Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); + + public VirtualChunkSource(VirtualRenderWorld world) { + this.world = world; + } + + @Override + public Level getLevel() { + return world; + } + + public ChunkAccess getChunk(int x, int z) { + long pos = ChunkPos.asLong(x, z); + return chunks.computeIfAbsent(pos, $ -> new VirtualChunk(world, x, z)); + } + + @Override + @Nullable + public LevelChunk getChunk(int x, int z, boolean load) { + return null; + } + + @Override + @Nullable + public ChunkAccess getChunk(int x, int z, ChunkStatus status, boolean load) { + return getChunk(x, z); + } + + @Override + public void tick(BooleanSupplier hasTimeLeft, boolean tickChunks) { + } + + @Override + public String gatherStats() { + return "VirtualChunkSource"; + } + + @Override + public int getLoadedChunksCount() { + return 0; + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/DummyLevelEntityGetter.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualLevelEntityGetter.java similarity index 50% rename from src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/DummyLevelEntityGetter.java rename to src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualLevelEntityGetter.java index 1b53bc6..3443344 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/utility/worldWrappers/DummyLevelEntityGetter.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualLevelEntityGetter.java @@ -1,4 +1,4 @@ -package nl.requios.effortlessbuilding.create.foundation.utility.worldWrappers; +package nl.requios.effortlessbuilding.create.foundation.virtualWorld; import net.minecraft.util.AbortableIterationConsumer; import net.minecraft.world.level.entity.EntityAccess; @@ -10,15 +10,14 @@ import java.util.Collections; import java.util.UUID; import java.util.function.Consumer; -public class DummyLevelEntityGetter implements LevelEntityGetter { - +public class VirtualLevelEntityGetter implements LevelEntityGetter { @Override - public T get(int p_156931_) { + public T get(int id) { return null; } @Override - public T get(UUID pUuid) { + public T get(UUID uuid) { return null; } @@ -28,15 +27,14 @@ public class DummyLevelEntityGetter implements LevelEnti } @Override - public void get(EntityTypeTest p_156935_, AbortableIterationConsumer p_156936_) { + public void get(EntityTypeTest test, AbortableIterationConsumer consumer) { } @Override - public void get(AABB p_156937_, Consumer p_156938_) { + public void get(AABB boundingBox, Consumer consumer) { } @Override - public void get(EntityTypeTest p_156932_, AABB p_156933_, AbortableIterationConsumer p_156934_) { + public void get(EntityTypeTest test, AABB bounds, AbortableIterationConsumer consumer) { } - } diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualRenderWorld.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualRenderWorld.java new file mode 100644 index 0000000..229b1ab --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/virtualWorld/VirtualRenderWorld.java @@ -0,0 +1,492 @@ +package nl.requios.effortlessbuilding.create.foundation.virtualWorld; + +import dev.engine_room.flywheel.api.visualization.VisualizationLevel; +import it.unimi.dsi.fastutil.objects.Object2ShortMap; +import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.core.SectionPos; +import net.minecraft.core.Vec3i; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.TickRateManager; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.item.alchemy.PotionBrewing; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.entity.LevelEntityGetter; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.gameevent.GameEvent.Context; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.saveddata.maps.MapId; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import net.minecraft.world.level.storage.WritableLevelData; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.scores.Scoreboard; +import net.minecraft.world.ticks.LevelTickAccess; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class VirtualRenderWorld extends Level implements VisualizationLevel { + protected final Level level; + protected final int minBuildHeight; + protected final int height; + protected final Vec3i biomeOffset; + + protected final VirtualChunkSource chunkSource; + protected final LevelLightEngine lightEngine; + + protected final Map blockStates = new HashMap<>(); + protected final Map blockEntities = new HashMap<>(); + protected final Object2ShortMap nonEmptyBlockCounts = new Object2ShortOpenHashMap<>(); + + protected final LevelEntityGetter entityGetter = new VirtualLevelEntityGetter<>(); + + protected final BlockPos.MutableBlockPos scratchPos = new BlockPos.MutableBlockPos(); + + public VirtualRenderWorld(Level level) { + this(level, Vec3i.ZERO); + } + + public VirtualRenderWorld(Level level, Vec3i biomeOffset) { + this(level, level.getMinBuildHeight(), level.getHeight(), biomeOffset); + } + + public VirtualRenderWorld(Level level, int minBuildHeight, int height, Vec3i biomeOffset) { + super((WritableLevelData) level.getLevelData(), level.dimension(), level.registryAccess(), level.dimensionTypeRegistration(), level.getProfilerSupplier(), + true, false, 0, 0); + this.level = level; + this.minBuildHeight = nextMultipleOf16(minBuildHeight); + this.height = nextMultipleOf16(height); + this.biomeOffset = biomeOffset; + + this.chunkSource = new VirtualChunkSource(this); + this.lightEngine = new LevelLightEngine(chunkSource, true, false); + } + + /** + * We need to ensure that height and minBuildHeight are multiples of 16. + * Adapted from: https://math.stackexchange.com/questions/291468 + */ + public static int nextMultipleOf16(int a) { + if (a < 0) { + return -(((Math.abs(a) - 1) | 15) + 1); + } else { + return ((a - 1) | 15) + 1; + } + } + + public void clear() { + blockStates.clear(); + blockEntities.clear(); + + nonEmptyBlockCounts.forEach((sectionPos, nonEmptyBlockCount) -> { + if (nonEmptyBlockCount > 0) { + lightEngine.updateSectionStatus(sectionPos, true); + } + }); + + nonEmptyBlockCounts.clear(); + + runLightEngine(); + } + + public void setBlockEntities(Collection blockEntities) { + this.blockEntities.clear(); + blockEntities.forEach(this::setBlockEntity); + } + + /** + * Run this after you're done using setBlock(). + */ + public void runLightEngine() { + Set chunkPosSet = new ObjectOpenHashSet<>(); + nonEmptyBlockCounts.object2ShortEntrySet().forEach(entry -> { + if (entry.getShortValue() > 0) { + chunkPosSet.add(entry.getKey().chunk()); + } + }); + for (ChunkPos chunkPos : chunkPosSet) { + lightEngine.propagateLightSources(chunkPos); + } + + lightEngine.runLightUpdates(); + } + + // MEANINGFUL OVERRIDES + + @Override + public LevelChunk getChunk(int x, int z) { + throw new UnsupportedOperationException(); + } + + public ChunkAccess actuallyGetChunk(int x, int z) { + return getChunk(x, z, ChunkStatus.FULL); + } + + @Override + public ChunkAccess getChunk(BlockPos pos) { + return actuallyGetChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())); + } + + @Override + public boolean setBlock(BlockPos pos, BlockState newState, int flags, int recursionLeft) { + if (isOutsideBuildHeight(pos)) { + return false; + } + + pos = pos.immutable(); + + BlockState oldState = getBlockState(pos); + if (oldState == newState) { + return false; + } + + blockStates.put(pos, newState); + + SectionPos sectionPos = SectionPos.of(pos); + short nonEmptyBlockCount = nonEmptyBlockCounts.getShort(sectionPos); + boolean prevEmpty = nonEmptyBlockCount == 0; + if (!oldState.isAir()) { + --nonEmptyBlockCount; + } + if (!newState.isAir()) { + ++nonEmptyBlockCount; + } + nonEmptyBlockCounts.put(sectionPos, nonEmptyBlockCount); + boolean nowEmpty = nonEmptyBlockCount == 0; + + if (prevEmpty != nowEmpty) { + lightEngine.updateSectionStatus(sectionPos, nowEmpty); + } + + lightEngine.checkBlock(pos); + + return true; + } + + @Override + public LevelLightEngine getLightEngine() { + return lightEngine; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + if (isOutsideBuildHeight(pos)) { + return Blocks.VOID_AIR.defaultBlockState(); + } + BlockState state = blockStates.get(pos); + if (state != null) { + return state; + } + return Blocks.AIR.defaultBlockState(); + } + + public BlockState getBlockState(int x, int y, int z) { + return getBlockState(scratchPos.set(x, y, z)); + } + + @Override + public FluidState getFluidState(BlockPos pos) { + if (isOutsideBuildHeight(pos)) { + return Fluids.EMPTY.defaultFluidState(); + } + return getBlockState(pos).getFluidState(); + } + + @Override + @Nullable + public BlockEntity getBlockEntity(BlockPos pos) { + if (!isOutsideBuildHeight(pos)) { + return blockEntities.get(pos); + } + return null; + } + + @Override + public void setBlockEntity(BlockEntity blockEntity) { + BlockPos pos = blockEntity.getBlockPos(); + if (!isOutsideBuildHeight(pos)) { + blockEntities.put(pos, blockEntity); + } + } + + @Override + public void removeBlockEntity(BlockPos pos) { + if (!isOutsideBuildHeight(pos)) { + blockEntities.remove(pos); + } + } + + @Override + protected LevelEntityGetter getEntities() { + return entityGetter; + } + + @Override + public ChunkSource getChunkSource() { + return chunkSource; + } + + @Override + public int getMinBuildHeight() { + return minBuildHeight; + } + + @Override + public int getHeight() { + return height; + } + + // BIOME OFFSET + + @Override + public Holder getBiome(BlockPos pos) { + return super.getBiome(pos.offset(biomeOffset)); + } + + @Override + public Holder getNoiseBiome(int x, int y, int z) { + // Control flow should never reach this method, + // so we add biomeOffset in case some other mod calls this directly. + return level.getNoiseBiome(x + biomeOffset.getX(), y + biomeOffset.getY(), z + biomeOffset.getZ()); + } + + @Override + public Holder getUncachedNoiseBiome(int x, int y, int z) { + // Control flow should never reach this method, + // so we add biomeOffset in case some other mod calls this directly. + return level.getUncachedNoiseBiome(x + biomeOffset.getX(), y + biomeOffset.getY(), z + biomeOffset.getZ()); + } + + // RENDERING CONSTANTS + + @Override + public int getMaxLocalRawBrightness(BlockPos pos) { + return 15; + } + + @Override + public float getShade(Direction direction, boolean shade) { + return 1f; + } + + // THIN WRAPPERS + + @Override + public Scoreboard getScoreboard() { + return level.getScoreboard(); + } + + @Override + public RecipeManager getRecipeManager() { + return level.getRecipeManager(); + } + + @Override + public BiomeManager getBiomeManager() { + return level.getBiomeManager(); + } + + @Override + public LevelTickAccess getBlockTicks() { + return level.getBlockTicks(); + } + + @Override + public LevelTickAccess getFluidTicks() { + return level.getFluidTicks(); + } + + @Override + public FeatureFlagSet enabledFeatures() { + return level.enabledFeatures(); + } + + @Override + public PotionBrewing potionBrewing() { + return level.potionBrewing(); + } + + @Override + public void setDayTimeFraction(float v) { + level.setDayTimeFraction(v); + } + + @Override + public void setDayTimePerTick(float v) { + level.setDayTimePerTick(v); + } + + @Override + public float getDayTimeFraction() { + return level.getDayTimeFraction(); + } + + @Override + public float getDayTimePerTick() { + return level.getDayTimePerTick(); + } + + // ADDITIONAL OVERRRIDES + + @Override + public void updateNeighbourForOutputSignal(BlockPos pos, Block block) { + } + + @Override + public boolean isLoaded(BlockPos pos) { + return true; + } + + @Override + public boolean isAreaLoaded(BlockPos center, int range) { + return true; + } + + // UNIMPORTANT IMPLEMENTATIONS + + @Override + public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) { + } + + @Override + public void playSeededSound(Player player, double x, double y, double z, Holder soundEvent, + SoundSource soundSource, float volume, float pitch, long seed) { + } + + @Override + public void playSeededSound(Player player, Entity entity, Holder soundEvent, SoundSource soundSource, + float volume, float pitch, long seed) { + } + + @Override + public String gatherChunkSourceStats() { + return ""; + } + + @Override + @Nullable + public Entity getEntity(int id) { + return null; + } + + @Override + public TickRateManager tickRateManager() { + return level.tickRateManager(); + } + + @Override + @Nullable + public MapItemSavedData getMapData(MapId mapId) { + return null; + } + + @Override + public void setMapData(MapId mapId, MapItemSavedData mapItemSavedData) {} + + @NotNull + @Override + public MapId getFreeMapId() { + return new MapId(0); + } + + @Override + public void destroyBlockProgress(int breakerId, BlockPos pos, int progress) { + } + + @Override + public void levelEvent(@Nullable Player player, int type, BlockPos pos, int data) { + } + + @Override + public void gameEvent(Holder gameEvent, Vec3 pos, Context context) { + } + + @Override + public List players() { + return Collections.emptyList(); + } + + // Override Starlight's ExtendedWorld interface methods: + + public LevelChunk getChunkAtImmediately(final int chunkX, final int chunkZ) { + return chunkSource.getChunk(chunkX, chunkZ, false); + } + + public ChunkAccess getAnyChunkImmediately(final int chunkX, final int chunkZ) { + return chunkSource.getChunk(chunkX, chunkZ); + } + + // Intentionally copied from LevelHeightAccessor. Lithium overrides these methods so we need to, too. + + @Override + public int getMaxBuildHeight() { + return this.getMinBuildHeight() + this.getHeight(); + } + + @Override + public int getSectionsCount() { + return this.getMaxSection() - this.getMinSection(); + } + + @Override + public int getMinSection() { + return SectionPos.blockToSectionCoord(this.getMinBuildHeight()); + } + + @Override + public int getMaxSection() { + return SectionPos.blockToSectionCoord(this.getMaxBuildHeight() - 1) + 1; + } + + @Override + public boolean isOutsideBuildHeight(BlockPos pos) { + return this.isOutsideBuildHeight(pos.getY()); + } + + @Override + public boolean isOutsideBuildHeight(int y) { + return y < this.getMinBuildHeight() || y >= this.getMaxBuildHeight(); + } + + @Override + public int getSectionIndex(int y) { + return this.getSectionIndexFromSectionY(SectionPos.blockToSectionCoord(y)); + } + + @Override + public int getSectionIndexFromSectionY(int sectionY) { + return sectionY - this.getMinSection(); + } + + @Override + public int getSectionYFromSectionIndex(int sectionIndex) { + return sectionIndex + this.getMinSection(); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/license.txt b/src/main/java/nl/requios/effortlessbuilding/create/license.txt deleted file mode 100644 index 86204cf..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/create/license.txt +++ /dev/null @@ -1,12 +0,0 @@ -All files within this folder fall under the MIT license. - -The MIT License Copyright (c) Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the -following conditions: The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java index d253544..536f1b0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/DiamondRandomizerBagScreen.java @@ -16,7 +16,7 @@ import javax.annotation.ParametersAreNonnullByDefault; public class DiamondRandomizerBagScreen extends AbstractContainerScreen { private Inventory inventory; - private static final ResourceLocation guiTextures = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/diamondrandomizerbag.png"); + private static final ResourceLocation guiTextures = EffortlessBuilding.asResource("textures/gui/container/diamondrandomizerbag.png"); public DiamondRandomizerBagScreen(DiamondRandomizerBagContainer randomizerBagContainer, Inventory playerInventory, Component title) { super(randomizerBagContainer, playerInventory, title); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java index 1f11372..cf8e9ec 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/GoldenRandomizerBagScreen.java @@ -16,7 +16,7 @@ import javax.annotation.ParametersAreNonnullByDefault; public class GoldenRandomizerBagScreen extends AbstractContainerScreen { private Inventory inventory; - private static final ResourceLocation guiTextures = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/goldenrandomizerbag.png"); + private static final ResourceLocation guiTextures = EffortlessBuilding.asResource("textures/gui/container/goldenrandomizerbag.png"); public GoldenRandomizerBagScreen(GoldenRandomizerBagContainer randomizerBagContainer, Inventory playerInventory, Component title) { super(randomizerBagContainer, playerInventory, title); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java index 9362c51..d413df7 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagScreen.java @@ -16,7 +16,7 @@ import javax.annotation.ParametersAreNonnullByDefault; public class RandomizerBagScreen extends AbstractContainerScreen { private Inventory inventory; - private static final ResourceLocation guiTextures = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png"); + private static final ResourceLocation guiTextures = EffortlessBuilding.asResource("textures/gui/container/randomizerbag.png"); public RandomizerBagScreen(RandomizerBagContainer randomizerBagContainer, Inventory playerInventory, Component title) { super(randomizerBagContainer, playerInventory, title); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/PlayerSettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/PlayerSettingsGui.java index 1d3f6f1..2932994 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/PlayerSettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/PlayerSettingsGui.java @@ -3,12 +3,12 @@ package nl.requios.effortlessbuilding.gui.buildmode; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.resources.sounds.SimpleSoundInstance; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.ObjectSelectionList; -import net.minecraft.sounds.SoundEvents; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvents; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.neoforge.client.gui.widget.ExtendedButton; @@ -196,10 +196,10 @@ public class PlayerSettingsGui extends Screen { // RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); // float f = 32.0F; // bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); -// bufferbuilder.vertex(this.x0, this.y1, 0.0D).color(20, 20, 20, 180).endVertex(); -// bufferbuilder.vertex(this.x1, this.y1, 0.0D).color(20, 20, 20, 180).endVertex(); -// bufferbuilder.vertex(this.x1, this.y0, 0.0D).color(20, 20, 20, 180).endVertex(); -// bufferbuilder.vertex(this.x0, this.y0, 0.0D).color(20, 20, 20, 180).endVertex(); +// bufferbuilder.addVertex(this.x0, this.y1, 0.0D).setColor(20, 20, 20, 180); +// bufferbuilder.addVertex(this.x1, this.y1, 0.0D).setColor(20, 20, 20, 180); +// bufferbuilder.addVertex(this.x1, this.y0, 0.0D).setColor(20, 20, 20, 180); +// bufferbuilder.addVertex(this.x0, this.y0, 0.0D).setColor(20, 20, 20, 180); // tessellator.end(); // int k = this.getRowLeft(); // int l = this.y0 + 4 - (int) this.getScrollAmount(); @@ -217,16 +217,16 @@ public class PlayerSettingsGui extends Screen { // RenderSystem.setShader(GameRenderer::getPositionColorShader); //// int i1 = 4; //// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); -//// bufferbuilder.pos((double)this.x0, (double)(this.y0 + 4), 0.0D).tex(0.0F, 1.0F).color(0, 0, 0, 0).endVertex(); -//// bufferbuilder.pos((double)this.x1, (double)(this.y0 + 4), 0.0D).tex(1.0F, 1.0F).color(0, 0, 0, 0).endVertex(); -//// bufferbuilder.pos((double)this.x1, (double)this.y0, 0.0D).tex(1.0F, 0.0F).color(0, 0, 0, 255).endVertex(); -//// bufferbuilder.pos((double)this.x0, (double)this.y0, 0.0D).tex(0.0F, 0.0F).color(0, 0, 0, 255).endVertex(); +//// bufferbuilder.pos((double)this.x0, (double)(this.y0 + 4), 0.0D).tex(0.0F, 1.0F).setColor(0, 0, 0, 0); +//// bufferbuilder.pos((double)this.x1, (double)(this.y0 + 4), 0.0D).tex(1.0F, 1.0F).setColor(0, 0, 0, 0); +//// bufferbuilder.pos((double)this.x1, (double)this.y0, 0.0D).tex(1.0F, 0.0F).setColor(0, 0, 0, 255); +//// bufferbuilder.pos((double)this.x0, (double)this.y0, 0.0D).tex(0.0F, 0.0F).setColor(0, 0, 0, 255); //// tessellator.draw(); //// bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); -//// bufferbuilder.pos((double)this.x0, (double)this.y1, 0.0D).tex(0.0F, 1.0F).color(0, 0, 0, 255).endVertex(); -//// bufferbuilder.pos((double)this.x1, (double)this.y1, 0.0D).tex(1.0F, 1.0F).color(0, 0, 0, 255).endVertex(); -//// bufferbuilder.pos((double)this.x1, (double)(this.y1 - 4), 0.0D).tex(1.0F, 0.0F).color(0, 0, 0, 0).endVertex(); -//// bufferbuilder.pos((double)this.x0, (double)(this.y1 - 4), 0.0D).tex(0.0F, 0.0F).color(0, 0, 0, 0).endVertex(); +//// bufferbuilder.pos((double)this.x0, (double)this.y1, 0.0D).tex(0.0F, 1.0F).setColor(0, 0, 0, 255); +//// bufferbuilder.pos((double)this.x1, (double)this.y1, 0.0D).tex(1.0F, 1.0F).setColor(0, 0, 0, 255); +//// bufferbuilder.pos((double)this.x1, (double)(this.y1 - 4), 0.0D).tex(1.0F, 0.0F).setColor(0, 0, 0, 0); +//// bufferbuilder.pos((double)this.x0, (double)(this.y1 - 4), 0.0D).tex(0.0F, 0.0F).setColor(0, 0, 0, 0); //// tessellator.draw(); // // //SCROLLBAR @@ -240,22 +240,22 @@ public class PlayerSettingsGui extends Screen { // } // // bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); -// bufferbuilder.vertex(i, this.y1, 0.0D).uv(0.0F, 1.0F).color(0, 0, 0, 255).endVertex(); -// bufferbuilder.vertex(j, this.y1, 0.0D).uv(1.0F, 1.0F).color(0, 0, 0, 255).endVertex(); -// bufferbuilder.vertex(j, this.y0, 0.0D).uv(1.0F, 0.0F).color(0, 0, 0, 255).endVertex(); -// bufferbuilder.vertex(i, this.y0, 0.0D).uv(0.0F, 0.0F).color(0, 0, 0, 255).endVertex(); +// bufferbuilder.addVertex(i, this.y1, 0.0D).uv(0.0F, 1.0F).setColor(0, 0, 0, 255); +// bufferbuilder.addVertex(j, this.y1, 0.0D).uv(1.0F, 1.0F).setColor(0, 0, 0, 255); +// bufferbuilder.addVertex(j, this.y0, 0.0D).uv(1.0F, 0.0F).setColor(0, 0, 0, 255); +// bufferbuilder.addVertex(i, this.y0, 0.0D).uv(0.0F, 0.0F).setColor(0, 0, 0, 255); // tessellator.end(); // bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); -// bufferbuilder.vertex(i, l1 + k1, 0.0D).uv(0.0F, 1.0F).color(128, 128, 128, 255).endVertex(); -// bufferbuilder.vertex(j, l1 + k1, 0.0D).uv(1.0F, 1.0F).color(128, 128, 128, 255).endVertex(); -// bufferbuilder.vertex(j, l1, 0.0D).uv(1.0F, 0.0F).color(128, 128, 128, 255).endVertex(); -// bufferbuilder.vertex(i, l1, 0.0D).uv(0.0F, 0.0F).color(128, 128, 128, 255).endVertex(); +// bufferbuilder.addVertex(i, l1 + k1, 0.0D).uv(0.0F, 1.0F).setColor(128, 128, 128, 255); +// bufferbuilder.addVertex(j, l1 + k1, 0.0D).uv(1.0F, 1.0F).setColor(128, 128, 128, 255); +// bufferbuilder.addVertex(j, l1, 0.0D).uv(1.0F, 0.0F).setColor(128, 128, 128, 255); +// bufferbuilder.addVertex(i, l1, 0.0D).uv(0.0F, 0.0F).setColor(128, 128, 128, 255); // tessellator.end(); // bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); -// bufferbuilder.vertex(i, l1 + k1 - 1, 0.0D).uv(0.0F, 1.0F).color(192, 192, 192, 255).endVertex(); -// bufferbuilder.vertex(j - 1, l1 + k1 - 1, 0.0D).uv(1.0F, 1.0F).color(192, 192, 192, 255).endVertex(); -// bufferbuilder.vertex(j - 1, l1, 0.0D).uv(1.0F, 0.0F).color(192, 192, 192, 255).endVertex(); -// bufferbuilder.vertex(i, l1, 0.0D).uv(0.0F, 0.0F).color(192, 192, 192, 255).endVertex(); +// bufferbuilder.addVertex(i, l1 + k1 - 1, 0.0D).uv(0.0F, 1.0F).setColor(192, 192, 192, 255); +// bufferbuilder.addVertex(j - 1, l1 + k1 - 1, 0.0D).uv(1.0F, 1.0F).setColor(192, 192, 192, 255); +// bufferbuilder.addVertex(j - 1, l1, 0.0D).uv(1.0F, 0.0F).setColor(192, 192, 192, 255); +// bufferbuilder.addVertex(i, l1, 0.0D).uv(0.0F, 0.0F).setColor(192, 192, 192, 255); // tessellator.end(); // } // diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java index 3050038..a284354 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java @@ -2,10 +2,12 @@ package nl.requios.effortlessbuilding.gui.buildmode; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.BufferUploader; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import net.createmod.catnip.theme.Color; import net.minecraft.ChatFormatting; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; @@ -22,14 +24,13 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; import nl.requios.effortlessbuilding.ClientEvents; import nl.requios.effortlessbuilding.EffortlessBuildingClient; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmode.BuildModeEnum; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions.ActionEnum; import nl.requios.effortlessbuilding.buildmode.ModeOptions.OptionEnum; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.create.foundation.item.ItemDescription; import nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; import nl.requios.effortlessbuilding.create.foundation.utility.Components; import nl.requios.effortlessbuilding.create.foundation.utility.Lang; import org.lwjgl.opengl.GL11; @@ -108,7 +109,6 @@ public class RadialMenu extends Screen { PoseStack ms = guiGraphics.pose(); ms.pushPose(); - ms.translate(0, 0, 200); visibility += fadeSpeed * partialTicks; if (visibility > 1f) visibility = 1f; @@ -121,10 +121,8 @@ public class RadialMenu extends Screen { RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); RenderSystem.setShader(GameRenderer::getPositionColorShader); - final Tesselator tessellator = Tesselator.getInstance(); - final BufferBuilder buffer = tessellator.getBuilder(); - - buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + final Tesselator tesselator = Tesselator.getInstance(); + final BufferBuilder buffer = tesselator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); final double middleX = width / 2.0; final double middleY = height / 2.0; @@ -191,9 +189,11 @@ public class RadialMenu extends Screen { //Draw action backgrounds drawSideButtonBackgrounds(buffer, middleX, middleY, mouseXCenter, mouseYCenter, buttons); - tessellator.end(); + BufferUploader.drawWithShader(buffer.buildOrThrow()); RenderSystem.disableBlend(); + ms.translate(0, 0, 200); + drawIcons(guiGraphics, middleX, middleY, modes, buttons); drawTexts(guiGraphics, currentBuildMode, middleX, middleY, modes, buttons, options, mouseXX, mouseYY); @@ -244,10 +244,11 @@ public class RadialMenu extends Screen { switchTo = menuRegion.mode; } - buffer.vertex(middleX + x1m1, middleY + y1m1, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + x2m1, middleY + y2m1, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + x2m2, middleY + y2m2, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + x1m2, middleY + y1m2, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); + + buffer.addVertex((float)(middleX + x1m1), (float)(middleY + y1m1), 20f).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + x2m1), (float)(middleY + y2m1), 20f).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + x2m2), (float)(middleY + y2m2), 20f).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + x1m2), (float)(middleY + y1m2), 20f).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); //Category line color = menuRegion.mode.category.color; @@ -258,10 +259,10 @@ public class RadialMenu extends Screen { final double y1m3 = Math.sin(beginRadians + fragment) * categoryLineOuterEdge; final double y2m3 = Math.sin(endRadians - fragment) * categoryLineOuterEdge; - buffer.vertex(middleX + x1m1, middleY + y1m1, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + x2m1, middleY + y2m1, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + x2m3, middleY + y2m3, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + x1m3, middleY + y1m3, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); + buffer.addVertex((float)(middleX + x1m1), (float)(middleY + y1m1), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + x2m1), (float)(middleY + y2m1), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + x2m3), (float)(middleY + y2m3), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + x1m3), (float)(middleY + y1m3), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); } } } @@ -291,10 +292,10 @@ public class RadialMenu extends Screen { doAction = btn.action; } - buffer.vertex(middleX + btn.x1, middleY + btn.y1, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + btn.x1, middleY + btn.y2, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + btn.x2, middleY + btn.y2, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); - buffer.vertex(middleX + btn.x2, middleY + btn.y1, 200).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex(); + buffer.addVertex((float)(middleX + btn.x1), (float)(middleY + btn.y1), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + btn.x1), (float)(middleY + btn.y2), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + btn.x2), (float)(middleY + btn.y2), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + buffer.addVertex((float)(middleX + btn.x2), (float)(middleY + btn.y1), 200).setColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArrayEntry.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArrayEntry.java index 484e3b3..ea94cd3 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArrayEntry.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArrayEntry.java @@ -7,9 +7,9 @@ import net.minecraft.network.chat.Component; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.AllGuiTextures; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.BaseModifier; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.create.foundation.gui.widget.ScrollInput; import nl.requios.effortlessbuilding.gui.elements.LabeledScrollInput; import nl.requios.effortlessbuilding.utilities.MathHelper; diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorEntry.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorEntry.java index b7dd1a8..00d1aa2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorEntry.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorEntry.java @@ -8,9 +8,9 @@ import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.AllGuiTextures; import nl.requios.effortlessbuilding.AllIcons; +import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.buildmodifier.BaseModifier; import nl.requios.effortlessbuilding.buildmodifier.Mirror; -import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.create.foundation.gui.widget.IconButton; import nl.requios.effortlessbuilding.create.foundation.gui.widget.ScrollInput; import nl.requios.effortlessbuilding.create.foundation.utility.Components; diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreen.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreen.java index 1d9e3cd..c4dc045 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreen.java @@ -1,5 +1,6 @@ package nl.requios.effortlessbuilding.gui.buildmodifier; +import net.createmod.catnip.gui.widget.BoxWidget; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; @@ -13,7 +14,6 @@ import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import nl.requios.effortlessbuilding.create.foundation.gui.AbstractSimiScreen; import nl.requios.effortlessbuilding.create.foundation.gui.AllIcons; -import nl.requios.effortlessbuilding.create.foundation.gui.widget.BoxWidget; import nl.requios.effortlessbuilding.create.foundation.utility.Components; import javax.annotation.Nonnull; diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreenList.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreenList.java index daebae0..968928a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreenList.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifiersScreenList.java @@ -1,17 +1,15 @@ package nl.requios.effortlessbuilding.gui.buildmodifier; -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.RenderSystem; +import net.createmod.catnip.gui.TickableGuiEventListener; +import net.createmod.catnip.gui.UIRenderHelper; +import net.createmod.catnip.theme.Color; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.ObjectSelectionList; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.network.chat.Component; -import nl.requios.effortlessbuilding.create.foundation.gui.TickableGuiEventListener; -import nl.requios.effortlessbuilding.create.foundation.gui.UIRenderHelper; import nl.requios.effortlessbuilding.create.foundation.gui.widget.AbstractSimiWidget; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; import nl.requios.effortlessbuilding.create.foundation.utility.Components; import java.util.ArrayList; @@ -23,7 +21,7 @@ public class ModifiersScreenList extends ObjectSelectionList tooltip, TooltipFlag flag) { + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag tooltipFlag) { tooltip.add(Component.literal(ChatFormatting.YELLOW + "*Experimental* Only works in singleplayer")); tooltip.add(Component.literal(ChatFormatting.BLUE + "Rightclick" + ChatFormatting.GRAY + " to place a random block")); tooltip.add(Component.literal(ChatFormatting.BLUE + "Sneak + rightclick" + ChatFormatting.GRAY + " to open inventory")); diff --git a/src/main/java/nl/requios/effortlessbuilding/item/PowerLevelItem.java b/src/main/java/nl/requios/effortlessbuilding/item/PowerLevelItem.java index 1f984ac..a3b6dff 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/PowerLevelItem.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/PowerLevelItem.java @@ -17,7 +17,6 @@ import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.attachment.PowerLevel; import nl.requios.effortlessbuilding.create.foundation.item.TooltipHelper; -import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; @@ -51,7 +50,7 @@ public class PowerLevelItem extends Item { if (!world.isClientSide) { EffortlessBuilding.log(player, "Already reached maximum power level!"); - world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.PLAYERS, 1f, 1f); + world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER.value(), SoundSource.PLAYERS, 1f, 1f); } return InteractionResultHolder.fail(player.getItemInHand(hand)); @@ -62,7 +61,7 @@ public class PowerLevelItem extends Item { } @Override - public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag isAdvanced) { + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag tooltipFlag) { tooltip.addAll(TooltipHelper.cutTextComponent(Component.translatable(getDescriptionId() + ".desc"), ChatFormatting.GRAY, ChatFormatting.GRAY)); tooltip.addAll(TooltipHelper.cutTextComponent(Component.translatable("key.effortlessbuilding.upgrade_power_level"), ChatFormatting.BLUE, ChatFormatting.BLUE)); } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java index e8afcca..7008bf7 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java @@ -17,7 +17,6 @@ import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.attachment.PowerLevel; -import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; @@ -52,7 +51,7 @@ public class ReachUpgrade1Item extends Item { if (!world.isClientSide && hand == InteractionHand.MAIN_HAND) { EffortlessBuilding.log(player, "Already used this upgrade! Current power level is " + powerLevel.getPowerLevel() + "."); - world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.PLAYERS, 1f, 1f); + world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER.value(), SoundSource.PLAYERS, 1f, 1f); } } } @@ -61,7 +60,7 @@ public class ReachUpgrade1Item extends Item { } @Override - public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag tooltipFlag) { tooltip.add(Component.literal(ChatFormatting.GRAY + "Consume to increase reach to " + ChatFormatting.BLUE + CommonConfig.reach.level1.get())); } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java index 219852a..bd3fa96 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java @@ -17,7 +17,6 @@ import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.attachment.PowerLevel; -import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; @@ -52,13 +51,13 @@ public class ReachUpgrade2Item extends Item { if (!world.isClientSide) { EffortlessBuilding.log(player, "Use Reach Upgrade 1 first."); - world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.PLAYERS, 1f, 1f); + world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER.value(), SoundSource.PLAYERS, 1f, 1f); } } else if (currentLevel > 1) { if (!world.isClientSide) { EffortlessBuilding.log(player, "Already used this upgrade! Current power level is " + powerLevel.getPowerLevel() + "."); - world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.PLAYERS, 1f, 1f); + world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER.value(), SoundSource.PLAYERS, 1f, 1f); } } } @@ -67,7 +66,7 @@ public class ReachUpgrade2Item extends Item { } @Override - public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag tooltipFlag) { tooltip.add(Component.literal(ChatFormatting.GRAY + "Consume to increase reach to " + ChatFormatting.BLUE + CommonConfig.reach.level2.get())); tooltip.add(Component.literal(ChatFormatting.GRAY + "Previous upgrades need to be consumed first")); } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java index f43a076..8d9466e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java @@ -17,7 +17,6 @@ import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.attachment.AttachmentHandler; import nl.requios.effortlessbuilding.attachment.PowerLevel; -import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; @@ -53,13 +52,13 @@ public class ReachUpgrade3Item extends Item { if (currentLevel == 0) EffortlessBuilding.log(player, "Use Reach Upgrade 1 and 2 first."); if (currentLevel == 1) EffortlessBuilding.log(player, "Use Reach Upgrade 2 first."); - world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.PLAYERS, 1f, 1f); + world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER.value(), SoundSource.PLAYERS, 1f, 1f); } } else if (currentLevel > 2) { if (!world.isClientSide) { EffortlessBuilding.log(player, "Already used this upgrade! Current power level is " + powerLevel.getPowerLevel() + "."); - world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.PLAYERS, 1f, 1f); + world.playSound((Player) null, player.blockPosition(), SoundEvents.ARMOR_EQUIP_LEATHER.value(), SoundSource.PLAYERS, 1f, 1f); } } } @@ -68,7 +67,7 @@ public class ReachUpgrade3Item extends Item { } @Override - public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag tooltipFlag) { tooltip.add(Component.literal(ChatFormatting.GRAY + "Consume to increase reach to " + ChatFormatting.BLUE + CommonConfig.reach.level3.get())); tooltip.add(Component.literal(ChatFormatting.GRAY + "Previous upgrades need to be consumed first")); } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/SingleItemLootModifier.java b/src/main/java/nl/requios/effortlessbuilding/item/SingleItemLootModifier.java index ee20b6d..41ef017 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/SingleItemLootModifier.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/SingleItemLootModifier.java @@ -2,6 +2,7 @@ package nl.requios.effortlessbuilding.item; import com.google.common.base.Suppliers; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.world.item.ItemStack; @@ -20,8 +21,8 @@ import java.util.function.Supplier; //https://mcreator.net/wiki/minecraft-vanilla-loot-tables-list#toc-index-1 public class SingleItemLootModifier extends LootModifier { - public static final Supplier> CODEC = Suppliers.memoize(() -> - RecordCodecBuilder.create(instance -> codecStart(instance).and( + public static final Supplier> CODEC = Suppliers.memoize(() -> + RecordCodecBuilder.mapCodec(instance -> codecStart(instance).and( instance.group( Codec.FLOAT.fieldOf("chance").forGetter(m -> m.chance), ItemStack.SINGLE_ITEM_CODEC.fieldOf("item").forGetter(m -> m.stack) @@ -52,7 +53,7 @@ public class SingleItemLootModifier extends LootModifier { } @Override - public Codec codec() { + public MapCodec codec() { return CODEC.get(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java index 389dc61..0df2249 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java @@ -1,7 +1,8 @@ package nl.requios.effortlessbuilding.network; -import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent; -import net.neoforged.neoforge.network.registration.IPayloadRegistrar; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.handling.DirectionalPayloadHandler; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.network.message.IsQuickReplacingPacket; import nl.requios.effortlessbuilding.network.message.IsUsingBuildModePacket; @@ -15,29 +16,24 @@ import nl.requios.effortlessbuilding.network.message.TranslatedLogPacket; public class PacketHandler { - public static void setupPackets(final RegisterPayloadHandlerEvent event) { - final IPayloadRegistrar registrar = event.registrar(EffortlessBuilding.MODID); + public static void setupPackets(final RegisterPayloadHandlersEvent event) { + final PayloadRegistrar registrar = event.registrar(EffortlessBuilding.MODID); - registrar.play(IsUsingBuildModePacket.ID, IsUsingBuildModePacket::new, handler -> handler - .server(IsUsingBuildModePacket.Handler::handle)); - registrar.play(IsQuickReplacingPacket.ID, IsQuickReplacingPacket::new, handler -> handler - .server(IsQuickReplacingPacket.Handler::handle)); - registrar.play(ServerPlaceBlocksPacket.ID, ServerPlaceBlocksPacket::new, handler -> handler - .server(ServerPlaceBlocksPacket.Handler::handle)); - registrar.play(ServerBreakBlocksPacket.ID, ServerBreakBlocksPacket::new, handler -> handler - .server(ServerBreakBlocksPacket.Handler::handle)); - registrar.play(PerformUndoPacket.ID, PerformUndoPacket::new, handler -> handler - .server(PerformUndoPacket.Handler::handle)); - registrar.play(PerformRedoPacket.ID, PerformRedoPacket::new, handler -> handler - .server(PerformRedoPacket.Handler::handle)); + registrar.playToServer(IsUsingBuildModePacket.ID, IsUsingBuildModePacket.CODEC, IsUsingBuildModePacket.Handler::handle); + registrar.playToServer(IsQuickReplacingPacket.ID, IsQuickReplacingPacket.CODEC, IsQuickReplacingPacket.Handler::handle); + registrar.playToServer(ServerPlaceBlocksPacket.ID, ServerPlaceBlocksPacket.CODEC, ServerPlaceBlocksPacket.Handler::handle); + registrar.playToServer(ServerBreakBlocksPacket.ID, ServerBreakBlocksPacket.CODEC, ServerBreakBlocksPacket.Handler::handle); + registrar.playToServer(PerformUndoPacket.ID, PerformUndoPacket.CODEC, PerformUndoPacket.Handler::handle); + registrar.playToServer(PerformRedoPacket.ID, PerformRedoPacket.CODEC, PerformRedoPacket.Handler::handle); - registrar.play(ModifierSettingsPacket.ID, ModifierSettingsPacket::new, handler -> handler - .server(ModifierSettingsPacket.ServerHandler::handleServer) - .server(ModifierSettingsPacket.ClientHandler::handleClient)); + registrar.playBidirectional(ModifierSettingsPacket.ID, ModifierSettingsPacket.CODEC, + new DirectionalPayloadHandler<>( + ModifierSettingsPacket.ClientHandler::handleClient, + ModifierSettingsPacket.ServerHandler::handleServer + ) + ); - registrar.play(PowerLevelPacket.ID, PowerLevelPacket::new, handler -> handler - .client(PowerLevelPacket.Handler::handle)); - registrar.play(TranslatedLogPacket.ID, TranslatedLogPacket::new, handler -> handler - .client(TranslatedLogPacket.Handler::handle)); + registrar.playToClient(PowerLevelPacket.ID, PowerLevelPacket.CODEC, PowerLevelPacket.Handler::handle); + registrar.playToClient(TranslatedLogPacket.ID, TranslatedLogPacket.CODEC, TranslatedLogPacket.Handler::handle); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/IsQuickReplacingPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/IsQuickReplacingPacket.java index 9d10324..e970154 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/IsQuickReplacingPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/IsQuickReplacingPacket.java @@ -2,39 +2,35 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.systems.ServerBuildState; public record IsQuickReplacingPacket(boolean isQuickReplacing) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "is_quick_replacing"); - - public IsQuickReplacingPacket(FriendlyByteBuf buf) { - this(buf.readBoolean()); - } - - public void write(FriendlyByteBuf buf) { - buf.writeBoolean(isQuickReplacing); - } + public static final StreamCodec CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, + IsQuickReplacingPacket::isQuickReplacing, + IsQuickReplacingPacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("is_quick_replacing")); @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class Handler { - public static void handle(final IsQuickReplacingPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final IsQuickReplacingPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() instanceof ServerPlayer player) { ServerBuildState.setIsQuickReplacing(player, packet.isQuickReplacing()); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.is_quick_replacing.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.is_quick_replacing.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/IsUsingBuildModePacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/IsUsingBuildModePacket.java index 21602e3..ea07288 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/IsUsingBuildModePacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/IsUsingBuildModePacket.java @@ -2,39 +2,35 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.systems.ServerBuildState; public record IsUsingBuildModePacket(boolean isUsingBuildMode) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "is_using_build_mode"); - - public IsUsingBuildModePacket(FriendlyByteBuf buf) { - this(buf.readBoolean()); - } - - public void write(FriendlyByteBuf buf) { - buf.writeBoolean(isUsingBuildMode); - } + public static final StreamCodec CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, + IsUsingBuildModePacket::isUsingBuildMode, + IsUsingBuildModePacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("is_using_build_mode")); @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class Handler { - public static void handle(final IsUsingBuildModePacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final IsUsingBuildModePacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() instanceof ServerPlayer player) { ServerBuildState.setIsUsingBuildMode(player, packet.isUsingBuildMode()); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.is_using_build_mode.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.is_using_build_mode.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/ModifierSettingsPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/ModifierSettingsPacket.java index 7e68cc8..4dcd0d6 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/ModifierSettingsPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/ModifierSettingsPacket.java @@ -3,10 +3,12 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuildingClient; @@ -14,54 +16,49 @@ import nl.requios.effortlessbuilding.EffortlessBuildingClient; * Sync build modifiers between server and client, for saving and loading. */ public record ModifierSettingsPacket(CompoundTag modifiersTag) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "modifier_settings"); + public static final StreamCodec CODEC = StreamCodec.composite( + ByteBufCodecs.COMPOUND_TAG, + ModifierSettingsPacket::modifiersTag, + ModifierSettingsPacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("modifier_settings")); private static final String DATA_KEY = EffortlessBuilding.MODID + ":buildModifiers"; - public ModifierSettingsPacket(FriendlyByteBuf buf) { - this(buf.readNbt()); - } - public ModifierSettingsPacket(Player player) { this(player.getPersistentData().getCompound(DATA_KEY)); } - public void write(FriendlyByteBuf buf) { - buf.writeNbt(modifiersTag); - } - @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class ServerHandler { - public static void handleServer(final ModifierSettingsPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handleServer(final ModifierSettingsPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.flow().isServerbound() && context.player() instanceof ServerPlayer player) { //To server, save to persistent player data player.getPersistentData().put(DATA_KEY, packet.modifiersTag()); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.modifier_settings.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.modifier_settings.failed", e.getMessage())); return null; }); } } public static class ClientHandler { - public static void handleClient(final ModifierSettingsPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handleClient(final ModifierSettingsPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.flow().isClientbound()) { + Player player = context.player(); //To client, load into system EffortlessBuildingClient.BUILD_MODIFIERS.deserializeNBT(packet.modifiersTag()); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.modifier_settings.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.modifier_settings.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/PerformRedoPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/PerformRedoPacket.java index 730fd0a..0c6b3f6 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/PerformRedoPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/PerformRedoPacket.java @@ -2,14 +2,18 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; public record PerformRedoPacket() implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "perform_redo"); + + public static final StreamCodec CODEC = CustomPacketPayload.codec( + PerformRedoPacket::write, + PerformRedoPacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("perform_redo")); public PerformRedoPacket(FriendlyByteBuf buf) { this(); @@ -19,20 +23,19 @@ public record PerformRedoPacket() implements CustomPacketPayload { } @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class Handler { - public static void handle(final PerformRedoPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final PerformRedoPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() instanceof ServerPlayer player) { EffortlessBuilding.UNDO_REDO.redo(player); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.perform_undo.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.perform_undo.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/PerformUndoPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/PerformUndoPacket.java index ab5d0f1..7dd24fa 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/PerformUndoPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/PerformUndoPacket.java @@ -2,14 +2,18 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; public record PerformUndoPacket() implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "perform_undo"); + + public static final StreamCodec CODEC = CustomPacketPayload.codec( + PerformUndoPacket::write, + PerformUndoPacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("perform_undo")); public PerformUndoPacket(FriendlyByteBuf buf) { this(); @@ -18,20 +22,19 @@ public record PerformUndoPacket() implements CustomPacketPayload { public void write(FriendlyByteBuf buf) {} @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class Handler { - public static void handle(final PerformUndoPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final PerformUndoPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() instanceof ServerPlayer player) { EffortlessBuilding.UNDO_REDO.undo(player); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.perform_undo.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.perform_undo.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/PowerLevelPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/PowerLevelPacket.java index efe51e1..8b8f939 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/PowerLevelPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/PowerLevelPacket.java @@ -2,10 +2,11 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.attachment.PowerLevel; @@ -13,33 +14,29 @@ import nl.requios.effortlessbuilding.attachment.PowerLevel; * Sync power level from server to client */ public record PowerLevelPacket(int powerLevel) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "power_level"); - - public PowerLevelPacket(FriendlyByteBuf buf) { - this(buf.readInt()); - } - - public void write(FriendlyByteBuf buf) { - buf.writeInt(powerLevel); - } + public static final StreamCodec CODEC = StreamCodec.composite( + ByteBufCodecs.INT, + PowerLevelPacket::powerLevel, + PowerLevelPacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("power_level")); @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class Handler { - public static void handle(final PowerLevelPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final PowerLevelPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() != null) { + Player player = context.player(); PowerLevel currentLevel = player.getData(EffortlessBuilding.POWER_LEVEL.get()); currentLevel.setPowerLevel(packet.powerLevel); player.setData(EffortlessBuilding.POWER_LEVEL.get(), currentLevel); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.power_level.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.power_level.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/ServerBreakBlocksPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/ServerBreakBlocksPacket.java index 23a03ce..6356c0d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/ServerBreakBlocksPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/ServerBreakBlocksPacket.java @@ -2,10 +2,10 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.utilities.BlockSet; @@ -13,7 +13,11 @@ import nl.requios.effortlessbuilding.utilities.BlockSet; * Sends a message to the server to break multiple blocks */ public record ServerBreakBlocksPacket(BlockSet blocks) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "server_break_blocks"); + + public static final StreamCodec CODEC = CustomPacketPayload.codec( + ServerBreakBlocksPacket::write, + ServerBreakBlocksPacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("server_break_blocks")); public ServerBreakBlocksPacket(FriendlyByteBuf buf) { this(BlockSet.decode(buf)); @@ -24,20 +28,19 @@ public record ServerBreakBlocksPacket(BlockSet blocks) implements CustomPacketPa } @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class Handler { - public static void handle(final ServerBreakBlocksPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final ServerBreakBlocksPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() instanceof ServerPlayer player) { EffortlessBuilding.SERVER_BLOCK_PLACER.breakBlocks(player, packet.blocks()); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.server_break_blocks.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.server_break_blocks.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/ServerPlaceBlocksPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/ServerPlaceBlocksPacket.java index 63c01bb..6f3d773 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/ServerPlaceBlocksPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/ServerPlaceBlocksPacket.java @@ -2,10 +2,10 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.utilities.BlockSet; @@ -13,7 +13,11 @@ import nl.requios.effortlessbuilding.utilities.BlockSet; * Sends a message to the server to place multiple blocks */ public record ServerPlaceBlocksPacket(BlockSet blocks, long placeTime) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "server_place_blocks"); + + public static final StreamCodec CODEC = CustomPacketPayload.codec( + ServerPlaceBlocksPacket::write, + ServerPlaceBlocksPacket::new); + public static final Type ID = new Type<>(EffortlessBuilding.asResource("server_place_blocks")); public ServerPlaceBlocksPacket(FriendlyByteBuf buf) { this(BlockSet.decode(buf), buf.readLong()); @@ -25,21 +29,20 @@ public record ServerPlaceBlocksPacket(BlockSet blocks, long placeTime) implement } @Override - public ResourceLocation id() { + public Type type() { return ID; } public static class Handler { - public static void handle(final ServerPlaceBlocksPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final ServerPlaceBlocksPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() instanceof ServerPlayer player) { EffortlessBuilding.logger.info("Place block packet received from client. Placing blocks..."); EffortlessBuilding.SERVER_BLOCK_PLACER.placeBlocksDelayed(player, packet.blocks(), packet.placeTime()); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.server_place_blocks.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.server_place_blocks.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/message/TranslatedLogPacket.java b/src/main/java/nl/requios/effortlessbuilding/network/message/TranslatedLogPacket.java index fee5e0e..47d7723 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/message/TranslatedLogPacket.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/message/TranslatedLogPacket.java @@ -2,67 +2,46 @@ package nl.requios.effortlessbuilding.network.message; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.neoforged.neoforge.network.handling.IPayloadContext; import nl.requios.effortlessbuilding.EffortlessBuilding; /** * Send packet to client to translate and log the containing message */ -public record TranslatedLogPacket(String prefix, String translationKey, String suffix, boolean actionBar) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(EffortlessBuilding.MODID, "translated_log"); +public record TranslatedLogPacket(String prefix, String translationKey, String suffix, + boolean actionBar) implements CustomPacketPayload { + public static final StreamCodec CODEC = StreamCodec.composite( + ByteBufCodecs.STRING_UTF8, + TranslatedLogPacket::prefix, + ByteBufCodecs.STRING_UTF8, + TranslatedLogPacket::translationKey, + ByteBufCodecs.STRING_UTF8, + TranslatedLogPacket::suffix, + ByteBufCodecs.BOOL, + TranslatedLogPacket::actionBar, + TranslatedLogPacket::new); - public TranslatedLogPacket(FriendlyByteBuf buf) { - this(buf.readUtf(), buf.readUtf(), buf.readUtf(), buf.readBoolean()); - } - - public TranslatedLogPacket(String prefix, String translationKey, String suffix, boolean actionBar) { - this.prefix = prefix; - this.translationKey = translationKey; - this.suffix = suffix; - this.actionBar = actionBar; - } - - public void write(FriendlyByteBuf buf) { - buf.writeUtf(prefix); - buf.writeUtf(translationKey); - buf.writeUtf(suffix); - buf.writeBoolean(actionBar); - } + public static final Type ID = new Type<>(EffortlessBuilding.asResource("translated_log")); @Override - public ResourceLocation id() { + public Type type() { return ID; } - public String getPrefix() { - return prefix; - } - - public String getTranslationKey() { - return translationKey; - } - - public String getSuffix() { - return suffix; - } - - public boolean isActionBar() { - return actionBar; - } - public static class Handler { - public static void handle(final TranslatedLogPacket packet, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { - if (context.player().isPresent()) { - Player player = context.player().get(); + public static void handle(final TranslatedLogPacket packet, final IPayloadContext context) { + context.enqueueWork(() -> { + if (context.player() != null) { + Player player = context.player(); EffortlessBuilding.logTranslate(player, packet.prefix(), packet.translationKey(), packet.suffix(), packet.actionBar()); } }).exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("effortlessbuilding.networking.translated_log.failed", e.getMessage())); + context.disconnect(Component.translatable("effortlessbuilding.networking.translated_log.failed", e.getMessage())); return null; }); } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java index c1c3a06..dbd45c2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java @@ -1,6 +1,5 @@ package nl.requios.effortlessbuilding.proxy; -import net.minecraft.client.Minecraft; import net.minecraft.client.resources.language.I18n; import net.minecraft.world.entity.player.Player; import net.neoforged.api.distmarker.Dist; @@ -8,9 +7,9 @@ import net.neoforged.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.EffortlessBuilding; @OnlyIn(Dist.CLIENT) -public class ClientProxy implements IProxy { +public class ClientProxy { - public void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar) { - EffortlessBuilding.log(Minecraft.getInstance().player, prefix + I18n.get(translationKey) + suffix, actionBar); + public static void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar) { + EffortlessBuilding.log(player, prefix + I18n.get(translationKey) + suffix, actionBar); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java deleted file mode 100644 index a2e8650..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java +++ /dev/null @@ -1,7 +0,0 @@ -package nl.requios.effortlessbuilding.proxy; - -import net.minecraft.world.entity.player.Player; - -public interface IProxy { - void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar); -} diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java index 6948c41..8bdbb9e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java @@ -4,10 +4,10 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.network.message.TranslatedLogPacket; -public class ServerProxy implements IProxy { +public class ServerProxy { //Only physical server! Singleplayer server is seen as clientproxy - public void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar) { + public static void logTranslate(Player player, String prefix, String translationKey, String suffix, boolean actionBar) { ((ServerPlayer)player).connection.send(new TranslatedLogPacket(prefix, translationKey, suffix, actionBar)); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java index b094649..5601fdc 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviews.java @@ -1,18 +1,23 @@ package nl.requios.effortlessbuilding.render; +import net.createmod.catnip.data.Pair; +import net.createmod.catnip.outliner.Outliner; +import net.createmod.catnip.theme.Color; import net.minecraft.client.Minecraft; -import net.minecraft.world.entity.player.Player; import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; -import nl.requios.effortlessbuilding.*; +import nl.requios.effortlessbuilding.ClientConfig; +import nl.requios.effortlessbuilding.ClientEvents; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.buildmode.BuildModeEnum; import nl.requios.effortlessbuilding.create.AllSpecialTextures; import nl.requios.effortlessbuilding.create.CreateClient; -import nl.requios.effortlessbuilding.create.foundation.utility.Color; import nl.requios.effortlessbuilding.systems.BuilderChain; import nl.requios.effortlessbuilding.utilities.BlockEntry; import nl.requios.effortlessbuilding.utilities.BlockSet; @@ -76,25 +81,25 @@ public class BlockPreviews { if (ClientConfig.visuals.showBlockPreviews.get() && blocks.size() < ClientConfig.visuals.maxBlockPreviews.get()) { renderBlockPreviews(blocks, false, 0f); - CreateClient.OUTLINER.showCluster(outlineID, coordinates) + Outliner.getInstance().showCluster(outlineID, coordinates) .withFaceTexture(AllSpecialTextures.CHECKERED) - .disableNormals() + .disableLineNormals() .lineWidth(1 / 32f) .colored(new Color(1f, 1f, 1f, 1f)); } else { //Thicker outline without block previews - CreateClient.OUTLINER.showCluster(outlineID, coordinates) + Outliner.getInstance().showCluster(outlineID, coordinates) .withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED) - .disableNormals() + .disableLineNormals() .lineWidth(1 / 16f) .colored(new Color(1f, 1f, 1f, 1f)); } } else { //Breaking - CreateClient.OUTLINER.showCluster(outlineID, coordinates) + Outliner.getInstance().showCluster(outlineID, coordinates) .withFaceTexture(AllSpecialTextures.THIN_CHECKERED) - .disableNormals() + .disableLineNormals() .lineWidth(1 / 16f) .colored(new Color(0.8f, 0.1f, 0.1f, 1f)); } @@ -153,8 +158,8 @@ public class BlockPreviews { } } - CreateClient.OUTLINER.showAABB("break", aabb) - .disableNormals() + Outliner.getInstance().showAABB("break", aabb) + .disableLineNormals() .lineWidth(1 / 64f) .colored(0x222222); } @@ -227,7 +232,7 @@ public class BlockPreviews { placedBlocksList.add(new PlacedBlocksEntry(ClientEvents.ticksInGame, false, new BlockSet(blocks))); - CreateClient.OUTLINER.keep(blocks.firstPos, ClientConfig.visuals.appearAnimationLength.get()); + Outliner.getInstance().keep(Pair.of(blocks.firstPos, ClientConfig.visuals.appearAnimationLength.get())); } public void onBlocksBroken(BlockSet blocks) { @@ -236,7 +241,7 @@ public class BlockPreviews { placedBlocksList.add(new PlacedBlocksEntry(ClientEvents.ticksInGame, true, new BlockSet(blocks))); - CreateClient.OUTLINER.keep(blocks.firstPos, ClientConfig.visuals.breakAnimationLength.get()); + Outliner.getInstance().keep(Pair.of(blocks.firstPos, ClientConfig.visuals.breakAnimationLength.get())); } private void sortOnDistanceToPlayer(List coordinates, Player player) { diff --git a/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java index 7a7f9e2..4380f4a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java @@ -103,13 +103,13 @@ public class ModifierRenderer { if (drawPlanes) { VertexConsumer buffer = RenderHandler.beginPlanes(renderTypeBuffer); - buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posA.x, (float) posB.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posB.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posB.x, (float) posB.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posA.x, (float) posB.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posB.x, (float) posA.y, (float) posB.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posB.x, (float) posB.y, (float) posB.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); //backface (using triangle strip) - buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posA.x, (float) posB.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posA.x, (float) posB.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); RenderHandler.endPlanes(renderTypeBuffer); } @@ -118,11 +118,11 @@ public class ModifierRenderer { VertexConsumer buffer = RenderHandler.beginLines(renderTypeBuffer); Vec3 middle = posA.add(posB).scale(0.5); - buffer.vertex(matrixPos, (float) posA.x, (float) middle.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posB.x, (float) middle.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) posA.x, (float) middle.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) posB.x, (float) middle.y, (float) posB.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); if (drawVerticalLines) { - buffer.vertex(matrixPos, (float) middle.x, (float) posA.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) middle.x, (float) posB.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) middle.x, (float) posA.y, (float) middle.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) middle.x, (float) posB.y, (float) middle.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); } RenderHandler.endLines(renderTypeBuffer); @@ -137,13 +137,13 @@ public class ModifierRenderer { if (drawPlanes) { VertexConsumer buffer = RenderHandler.beginPlanes(renderTypeBuffer); - buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posB.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posB.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posA.x, (float) posA.y, (float) posB.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posB.x, (float) posA.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posB.x, (float) posA.y, (float) posB.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); //backface (using triangle strip) - buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posA.x, (float) posA.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) posA.x, (float) posA.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); + buffer.addVertex(matrixPos, (float) posA.x, (float) posA.y, (float) posB.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha); RenderHandler.endPlanes(renderTypeBuffer); } @@ -152,10 +152,10 @@ public class ModifierRenderer { VertexConsumer buffer = RenderHandler.beginLines(renderTypeBuffer); Vec3 middle = posA.add(posB).scale(0.5); - buffer.vertex(matrixPos, (float) middle.x, (float) middle.y, (float) posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) middle.x, (float) middle.y, (float) posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posA.x, (float) middle.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) posB.x, (float) middle.y, (float) middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) middle.x, (float) middle.y, (float) posA.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) middle.x, (float) middle.y, (float) posB.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) posA.x, (float) middle.y, (float) middle.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) posB.x, (float) middle.y, (float) middle.z).setColor(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha); RenderHandler.endLines(renderTypeBuffer); } @@ -169,12 +169,12 @@ public class ModifierRenderer { Vec3 pos = m.position.add(epsilon); - buffer.vertex(matrixPos, (float) pos.x - m.radius, (float) pos.y, (float) pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) pos.x + m.radius, (float) pos.y, (float) pos.z).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) pos.x, (float) pos.y - m.radius, (float) pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) pos.x, (float) pos.y + m.radius, (float) pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) pos.x, (float) pos.y, (float) pos.z - m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex(); - buffer.vertex(matrixPos, (float) pos.x, (float) pos.y, (float) pos.z + m.radius).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex(); + buffer.addVertex(matrixPos, (float) pos.x - m.radius, (float) pos.y, (float) pos.z).setColor(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) pos.x + m.radius, (float) pos.y, (float) pos.z).setColor(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) pos.x, (float) pos.y - m.radius, (float) pos.z).setColor(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) pos.x, (float) pos.y + m.radius, (float) pos.z).setColor(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) pos.x, (float) pos.y, (float) pos.z - m.radius).setColor(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha); + buffer.addVertex(matrixPos, (float) pos.x, (float) pos.y, (float) pos.z + m.radius).setColor(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha); RenderHandler.endLines(renderTypeBuffer); } diff --git a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java index 36ddd6a..9b18ccb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java @@ -1,9 +1,8 @@ package nl.requios.effortlessbuilding.render; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.ByteBufferBuilder; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; @@ -14,17 +13,17 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.RenderGuiEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.systems.BuilderChain; /*** * Main render class for Effortless Building */ -@Mod.EventBusSubscriber(Dist.CLIENT) +@EventBusSubscriber(Dist.CLIENT) public class RenderHandler { @SubscribeEvent @@ -33,8 +32,9 @@ public class RenderHandler { Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); PoseStack ms = event.getPoseStack(); - BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder(); - MultiBufferSource.BufferSource buffer = MultiBufferSource.immediate(bufferBuilder); +// BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder(); +// MultiBufferSource.BufferSource buffer = MultiBufferSource.immediate(bufferBuilder); + MultiBufferSource.BufferSource buffer = MultiBufferSource.immediate(new ByteBufferBuilder(1536)); ms.pushPose(); ms.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z()); @@ -130,7 +130,8 @@ public class RenderHandler { Font font = Minecraft.getInstance().font; String text = String.valueOf(stack.getCount()); ms.translate(0.0D, 0.0D, 200.0F); - MultiBufferSource.BufferSource multibuffersource$buffersource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); +// MultiBufferSource.BufferSource multibuffersource$buffersource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); + MultiBufferSource.BufferSource multibuffersource$buffersource = MultiBufferSource.immediate(new ByteBufferBuilder(1536)); font.drawInBatch(text, (float)(x + 19 - 2 - font.width(text)), (float)(y + 6 + 3), missing ? ChatFormatting.RED.getColor() : ChatFormatting.WHITE.getColor(), true, ms.last().pose(), multibuffersource$buffersource, Font.DisplayMode.NORMAL, 0, 15728880); multibuffersource$buffersource.endBatch(); ms.popPose(); diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java b/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java index ebbb462..4043c48 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/BuildSettings.java @@ -4,8 +4,8 @@ import net.minecraft.client.Minecraft; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.neoforge.network.PacketDistributor; -import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.attachment.AttachmentHandler; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.network.message.IsQuickReplacingPacket; @OnlyIn(Dist.CLIENT) @@ -26,7 +26,7 @@ public class BuildSettings { public void setReplaceMode(ReplaceMode replaceMode) { this.replaceMode = replaceMode; - PacketDistributor.SERVER.noArg().send(new IsQuickReplacingPacket(isQuickReplacing())); + PacketDistributor.sendToServer(new IsQuickReplacingPacket(isQuickReplacing())); } public ReplaceMode getReplaceMode() { diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java index 7fef9ba..f81d1ee 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java @@ -94,7 +94,7 @@ public class BuilderChain { blocks.skipFirst = buildMode == BuildModeEnum.DISABLED; long placeTime = player.level().getGameTime(); if (blocks.size() > 1) placeTime += ClientConfig.visuals.appearAnimationLength.get(); - PacketDistributor.SERVER.noArg().send(new ServerPlaceBlocksPacket(blocks, placeTime)); + PacketDistributor.sendToServer(new ServerPlaceBlocksPacket(blocks, placeTime)); } } } @@ -132,7 +132,7 @@ public class BuilderChain { ClientBlockUtilities.playSoundIfFurtherThanNormal(player, blocks.getLastBlockEntry(), true); player.swing(InteractionHand.MAIN_HAND); blocks.skipFirst = buildMode == BuildModeEnum.DISABLED; - PacketDistributor.SERVER.noArg().send(new ServerBreakBlocksPacket(blocks)); + PacketDistributor.sendToServer(new ServerBreakBlocksPacket(blocks)); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java b/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java index 9e12779..279fec5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/ServerBlockPlacer.java @@ -4,9 +4,15 @@ import net.minecraft.ChatFormatting; import net.minecraft.world.entity.player.Player; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.ServerConfig; -import nl.requios.effortlessbuilding.utilities.*; +import nl.requios.effortlessbuilding.utilities.BlockEntry; +import nl.requios.effortlessbuilding.utilities.BlockPlacerHelper; +import nl.requios.effortlessbuilding.utilities.BlockSet; +import nl.requios.effortlessbuilding.utilities.BlockUtilities; +import nl.requios.effortlessbuilding.utilities.InventoryHelper; -import java.util.*; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; // Receives block placement requests from the client and places them public class ServerBlockPlacer { diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/UndoRedo.java b/src/main/java/nl/requios/effortlessbuilding/systems/UndoRedo.java index db1f71a..8dac2ad 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/UndoRedo.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/UndoRedo.java @@ -1,24 +1,30 @@ package nl.requios.effortlessbuilding.systems; import net.minecraft.ChatFormatting; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.util.BlockSnapshot; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.ServerConfig; -import nl.requios.effortlessbuilding.utilities.*; +import nl.requios.effortlessbuilding.utilities.BlockSet; +import nl.requios.effortlessbuilding.utilities.FixedStack; +import nl.requios.effortlessbuilding.utilities.InventoryHelper; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; //Server only public class UndoRedo { - public class UndoSet { + public static class UndoSet { public final List blockSnapshots; public UndoSet(List blockSnapshots) { diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockPlacerHelper.java b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockPlacerHelper.java index 4ee18dd..dacd923 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockPlacerHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockPlacerHelper.java @@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.DiggerItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.util.BlockSnapshot; import net.neoforged.neoforge.event.EventHooks; @@ -42,7 +43,7 @@ public class BlockPlacerHelper { var itemStack = new ItemStack(blockEntry.item); level.captureBlockSnapshots = true; - BlockHelper.placeSchematicBlock(level, player, blockEntry.newBlockState, blockEntry.blockPos, itemStack, null); + BlockHelper.placeSchematicBlock(level, blockEntry.newBlockState, blockEntry.blockPos, itemStack, null); level.captureBlockSnapshots = false; //Find out if we get to keep the placed block by sending a forge event @@ -67,7 +68,7 @@ public class BlockPlacerHelper { for (BlockSnapshot blocksnapshot : Lists.reverse(blockSnapshots)) { level.restoringBlockSnapshots = true; - blocksnapshot.restore(true, false); + blocksnapshot.restore(Block.UPDATE_NONE); level.restoringBlockSnapshots = false; } } @@ -75,8 +76,8 @@ public class BlockPlacerHelper { { for (BlockSnapshot snap : blockSnapshots) { - int updateFlag = snap.getFlag(); - BlockState oldBlock = snap.getReplacedBlock(); + int updateFlag = snap.getFlags(); + BlockState oldBlock = snap.getState(); BlockState newBlock = level.getBlockState(snap.getPos()); newBlock.onPlace(level, snap.getPos(), oldBlock, false); diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java index 778a04e..418dd52 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java @@ -5,7 +5,11 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.DirectionalBlock; +import net.minecraft.world.level.block.DispenserBlock; +import net.minecraft.world.level.block.SlabBlock; +import net.minecraft.world.level.block.StairBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.Half; import net.minecraft.world.level.block.state.properties.SlabType; diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/InventoryHelper.java b/src/main/java/nl/requios/effortlessbuilding/utilities/InventoryHelper.java index debf471..4e3e7f7 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/InventoryHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/InventoryHelper.java @@ -1,10 +1,10 @@ package nl.requios.effortlessbuilding.utilities; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; import nl.requios.effortlessbuilding.EffortlessBuilding; import java.util.Map; diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/SurvivalHelper.java b/src/main/java/nl/requios/effortlessbuilding/utilities/SurvivalHelper.java index 172d47d..f0ef351 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/SurvivalHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/SurvivalHelper.java @@ -21,7 +21,7 @@ public class SurvivalHelper { if (player.isCreative()) return true; - return EventHooks.doPlayerHarvestCheck(player, blockState, true); + return EventHooks.doPlayerHarvestCheck(player, blockState, world, pos); } public static boolean doesBecomeDoubleSlab(Player player, BlockPos pos) { diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/UndoRedoBlockSet.java b/src/main/java/nl/requios/effortlessbuilding/utilities/UndoRedoBlockSet.java deleted file mode 100644 index 7706faf..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/UndoRedoBlockSet.java +++ /dev/null @@ -1,45 +0,0 @@ -package nl.requios.effortlessbuilding.utilities; - -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.core.BlockPos; - -import java.util.List; - -//Server only -@Deprecated -public class UndoRedoBlockSet { - private final List coordinates; - private final List previousBlockStates; - private final List newBlockStates; - private final BlockPos firstPos; - private final BlockPos secondPos; - - public UndoRedoBlockSet(List coordinates, List previousBlockStates, List newBlockStates, - BlockPos firstPos, BlockPos secondPos) { - this.coordinates = coordinates; - this.previousBlockStates = previousBlockStates; - this.newBlockStates = newBlockStates; - this.firstPos = firstPos; - this.secondPos = secondPos; - } - - public List getCoordinates() { - return coordinates; - } - - public List getPreviousBlockStates() { - return previousBlockStates; - } - - public List getNewBlockStates() { - return newBlockStates; - } - - public BlockPos getFirstPos() { - return firstPos; - } - - public BlockPos getSecondPos() { - return secondPos; - } -} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/neoforge.mods.toml similarity index 79% rename from src/main/resources/META-INF/mods.toml rename to src/main/resources/META-INF/neoforge.mods.toml index 9cd6234..44df873 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -1,5 +1,5 @@ modLoader="javafml" -loaderVersion="[2,)" +loaderVersion="[4,)" license="GNU LESSER GENERAL PUBLIC LICENSE" issueTrackerURL="https://bitbucket.org/Requios/effortless-building/issues?status=new&status=open&status=submitted&is_spam=%21spam" showAsResourcePack=false @@ -19,23 +19,23 @@ Makes building easier by providing tools like mirrors, arrays, build modes and a [[dependencies.effortlessbuilding]] modId="neoforge" type="required" - versionRange="[20.4.167,)" + versionRange="[21.1.1,)" ordering="NONE" side="BOTH" [[dependencies.effortlessbuilding]] modId="minecraft" type="required" - versionRange="[1.20.4,1.21)" + versionRange="[1.21.1,1.21.2)" ordering="NONE" side="BOTH" -[[dependencies.effortlessbuilding]] - modId="flywheel" - type="required" - versionRange="[0.6.10,0.7)" - ordering="AFTER" - side="CLIENT" +#[[dependencies.effortlessbuilding]] +# modId="flywheel" +# type="required" +# versionRange="[0.6.10,0.7)" +# ordering="AFTER" +# side="CLIENT" #[[accessTransformers]] # file="META-INF/accesstransformer.cfg" \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/recipes/diamond_randomizer_bag.json b/src/main/resources/data/effortlessbuilding/recipe/diamond_randomizer_bag.json similarity index 81% rename from src/main/resources/data/effortlessbuilding/recipes/diamond_randomizer_bag.json rename to src/main/resources/data/effortlessbuilding/recipe/diamond_randomizer_bag.json index 3caf55b..e1e419c 100644 --- a/src/main/resources/data/effortlessbuilding/recipes/diamond_randomizer_bag.json +++ b/src/main/resources/data/effortlessbuilding/recipe/diamond_randomizer_bag.json @@ -17,6 +17,7 @@ } }, "result": { - "item": "effortlessbuilding:diamond_randomizer_bag" + "count": 1, + "id": "effortlessbuilding:diamond_randomizer_bag" } } \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/recipes/golden_randomizer_bag.json b/src/main/resources/data/effortlessbuilding/recipe/golden_randomizer_bag.json similarity index 81% rename from src/main/resources/data/effortlessbuilding/recipes/golden_randomizer_bag.json rename to src/main/resources/data/effortlessbuilding/recipe/golden_randomizer_bag.json index d5f9676..5aa9fb5 100644 --- a/src/main/resources/data/effortlessbuilding/recipes/golden_randomizer_bag.json +++ b/src/main/resources/data/effortlessbuilding/recipe/golden_randomizer_bag.json @@ -17,6 +17,7 @@ } }, "result": { - "item": "effortlessbuilding:golden_randomizer_bag" + "count": 1, + "id": "effortlessbuilding:golden_randomizer_bag" } } \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/recipes/randomizer_bag.json b/src/main/resources/data/effortlessbuilding/recipe/randomizer_bag.json similarity index 79% rename from src/main/resources/data/effortlessbuilding/recipes/randomizer_bag.json rename to src/main/resources/data/effortlessbuilding/recipe/randomizer_bag.json index b43fc1d..bc242c5 100644 --- a/src/main/resources/data/effortlessbuilding/recipes/randomizer_bag.json +++ b/src/main/resources/data/effortlessbuilding/recipe/randomizer_bag.json @@ -14,6 +14,7 @@ } }, "result": { - "item": "effortlessbuilding:randomizer_bag" + "count": 1, + "id": "effortlessbuilding:randomizer_bag" } } \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade1.json b/src/main/resources/data/effortlessbuilding/recipe/reach_upgrade1.json similarity index 80% rename from src/main/resources/data/effortlessbuilding/recipes/reach_upgrade1.json rename to src/main/resources/data/effortlessbuilding/recipe/reach_upgrade1.json index 42b39f5..c48cea3 100644 --- a/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade1.json +++ b/src/main/resources/data/effortlessbuilding/recipe/reach_upgrade1.json @@ -14,6 +14,7 @@ } }, "result": { - "item": "effortlessbuilding:reach_upgrade1" + "count": 1, + "id": "effortlessbuilding:reach_upgrade1" } } \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade2.json b/src/main/resources/data/effortlessbuilding/recipe/reach_upgrade2.json similarity index 80% rename from src/main/resources/data/effortlessbuilding/recipes/reach_upgrade2.json rename to src/main/resources/data/effortlessbuilding/recipe/reach_upgrade2.json index 201a030..e03ac6a 100644 --- a/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade2.json +++ b/src/main/resources/data/effortlessbuilding/recipe/reach_upgrade2.json @@ -14,6 +14,7 @@ } }, "result": { - "item": "effortlessbuilding:reach_upgrade2" + "count": 1, + "id": "effortlessbuilding:reach_upgrade2" } } \ No newline at end of file diff --git a/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade3.json b/src/main/resources/data/effortlessbuilding/recipe/reach_upgrade3.json similarity index 83% rename from src/main/resources/data/effortlessbuilding/recipes/reach_upgrade3.json rename to src/main/resources/data/effortlessbuilding/recipe/reach_upgrade3.json index 916fbe1..0dc91e0 100644 --- a/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade3.json +++ b/src/main/resources/data/effortlessbuilding/recipe/reach_upgrade3.json @@ -17,6 +17,7 @@ } }, "result": { - "item": "effortlessbuilding:reach_upgrade3" + "count": 1, + "id": "effortlessbuilding:reach_upgrade3" } } \ No newline at end of file diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 53e3a7e..2602108 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "Effortless Building resources", - "pack_format": 15 + "pack_format": 34 } }