aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/kotlin/features/inventory/SaveCursorPosition.kt1
-rw-r--r--src/main/kotlin/features/items/EtherwarpOverlay.kt211
-rw-r--r--src/main/kotlin/util/skyblock/SkyBlockItems.kt1
-rw-r--r--translations/en_us.json8
4 files changed, 210 insertions, 11 deletions
diff --git a/src/main/kotlin/features/inventory/SaveCursorPosition.kt b/src/main/kotlin/features/inventory/SaveCursorPosition.kt
index c47867b..d2e9241 100644
--- a/src/main/kotlin/features/inventory/SaveCursorPosition.kt
+++ b/src/main/kotlin/features/inventory/SaveCursorPosition.kt
@@ -46,6 +46,7 @@ object SaveCursorPosition : FirmamentFeature {
(lastPosition.middle.first - middleX).absoluteValue < 1 &&
(lastPosition.middle.second - middleY).absoluteValue < 1
) {
+ // TODO: GLFW.glfwSetCursorPos(handler, x, y);
InputUtil.setCursorParameters(
MC.window.handle,
InputUtil.GLFW_CURSOR_NORMAL,
diff --git a/src/main/kotlin/features/items/EtherwarpOverlay.kt b/src/main/kotlin/features/items/EtherwarpOverlay.kt
index f6ab1a2..a5d4483 100644
--- a/src/main/kotlin/features/items/EtherwarpOverlay.kt
+++ b/src/main/kotlin/features/items/EtherwarpOverlay.kt
@@ -1,8 +1,13 @@
package moe.nea.firmament.features.items
import io.github.notenoughupdates.moulconfig.ChromaColour
-import me.shedaniel.math.Color
+import net.minecraft.block.Blocks
+import net.minecraft.text.Text
import net.minecraft.util.hit.BlockHitResult
+import net.minecraft.util.hit.HitResult
+import net.minecraft.util.math.BlockPos
+import net.minecraft.util.math.Vec3d
+import net.minecraft.world.BlockView
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.features.FirmamentFeature
@@ -12,6 +17,7 @@ import moe.nea.firmament.util.extraAttributes
import moe.nea.firmament.util.render.RenderInWorldContext
import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.skyblock.SkyBlockItems
+import moe.nea.firmament.util.tr
object EtherwarpOverlay : FirmamentFeature {
override val identifier: String
@@ -22,12 +28,160 @@ object EtherwarpOverlay : FirmamentFeature {
var onlyShowWhileSneaking by toggle("only-show-while-sneaking") { true }
var cube by toggle("cube") { true }
val cubeColour by colour("cube-colour") { ChromaColour.fromStaticRGB(172, 0, 255, 60) }
+ val failureCubeColour by colour("cube-colour-fail") { ChromaColour.fromStaticRGB(255, 0, 172, 60) }
+ val tooCloseCubeColour by colour("cube-colour-tooclose") { ChromaColour.fromStaticRGB(0, 255, 0, 60) }
+ val tooFarCubeColour by colour("cube-colour-toofar") { ChromaColour.fromStaticRGB(255, 255, 0, 60) }
var wireframe by toggle("wireframe") { false }
+ var failureText by toggle("failure-text") { false }
}
override val config: ManagedConfig
get() = TConfig
+ enum class EtherwarpResult(val label: Text?, val color: () -> ChromaColour) {
+ SUCCESS(null, TConfig::cubeColour),
+ INTERACTION_BLOCKED(
+ tr("firmament.etherwarp.fail.tooclosetointeractable", "Too close to interactable"),
+ TConfig::tooCloseCubeColour
+ ),
+ TOO_DISTANT(tr("firmament.etherwarp.fail.toofar", "Too far away"), TConfig::tooFarCubeColour),
+ OCCUPIED(tr("firmament.etherwarp.fail.occupied", "Occupied"), TConfig::failureCubeColour),
+ }
+
+ val interactionBlocked = setOf(
+ Blocks.HOPPER,
+ Blocks.CHEST,
+ Blocks.ENDER_CHEST,
+ Blocks.FURNACE,
+ Blocks.CRAFTING_TABLE,
+ Blocks.CAULDRON,
+ Blocks.WATER_CAULDRON,
+ Blocks.ENCHANTING_TABLE,
+ Blocks.DISPENSER,
+ Blocks.DROPPER,
+ Blocks.BREWING_STAND,
+ Blocks.TRAPPED_CHEST,
+ Blocks.OAK_DOOR,
+ Blocks.IRON_DOOR,
+ Blocks.OAK_TRAPDOOR,
+ Blocks.SPRUCE_TRAPDOOR,
+ Blocks.BIRCH_TRAPDOOR,
+ Blocks.JUNGLE_TRAPDOOR,
+ Blocks.ACACIA_TRAPDOOR,
+ Blocks.CHERRY_TRAPDOOR,
+ Blocks.DARK_OAK_TRAPDOOR,
+ Blocks.PALE_OAK_TRAPDOOR,
+ Blocks.MANGROVE_TRAPDOOR,
+ Blocks.BAMBOO_TRAPDOOR,
+ Blocks.IRON_TRAPDOOR,
+ Blocks.SPRUCE_DOOR,
+ Blocks.BIRCH_DOOR,
+ Blocks.JUNGLE_DOOR,
+ Blocks.ACACIA_DOOR,
+ Blocks.CHERRY_DOOR,
+ Blocks.DARK_OAK_DOOR,
+ Blocks.PALE_OAK_DOOR,
+ Blocks.MANGROVE_DOOR,
+ Blocks.BAMBOO_DOOR,
+ Blocks.CRIMSON_TRAPDOOR,
+ Blocks.WARPED_TRAPDOOR,
+ Blocks.CRIMSON_DOOR,
+ Blocks.WARPED_DOOR,
+ Blocks.COPPER_DOOR,
+ Blocks.EXPOSED_COPPER_DOOR,
+ Blocks.OXIDIZED_COPPER_DOOR,
+ Blocks.WEATHERED_COPPER_DOOR,
+ Blocks.WAXED_COPPER_DOOR,
+ Blocks.WAXED_EXPOSED_COPPER_DOOR,
+ Blocks.WAXED_OXIDIZED_COPPER_DOOR,
+ Blocks.WAXED_WEATHERED_COPPER_DOOR,
+ Blocks.COPPER_TRAPDOOR,
+ Blocks.EXPOSED_COPPER_TRAPDOOR,
+ Blocks.OXIDIZED_COPPER_TRAPDOOR,
+ Blocks.WEATHERED_COPPER_TRAPDOOR,
+ Blocks.WAXED_COPPER_TRAPDOOR,
+ Blocks.WAXED_EXPOSED_COPPER_TRAPDOOR,
+ Blocks.WAXED_OXIDIZED_COPPER_TRAPDOOR,
+ Blocks.WAXED_WEATHERED_COPPER_TRAPDOOR,
+ )
+
+ val etherwarpHallpasses = setOf(
+ Blocks.CREEPER_HEAD,
+ Blocks.CREEPER_WALL_HEAD,
+ Blocks.DRAGON_HEAD,
+ Blocks.DRAGON_WALL_HEAD,
+ Blocks.SKELETON_SKULL,
+ Blocks.SKELETON_WALL_SKULL,
+ Blocks.WITHER_SKELETON_SKULL,
+ Blocks.WITHER_SKELETON_WALL_SKULL,
+ Blocks.PIGLIN_HEAD,
+ Blocks.PIGLIN_WALL_HEAD,
+ Blocks.ZOMBIE_HEAD,
+ Blocks.ZOMBIE_WALL_HEAD,
+ Blocks.PLAYER_HEAD,
+ Blocks.PLAYER_WALL_HEAD,
+ Blocks.REPEATER,
+ Blocks.COMPARATOR,
+ Blocks.BIG_DRIPLEAF_STEM,
+ Blocks.WHITE_CARPET,
+ Blocks.ORANGE_CARPET,
+ Blocks.MAGENTA_CARPET,
+ Blocks.LIGHT_BLUE_CARPET,
+ Blocks.YELLOW_CARPET,
+ Blocks.LIME_CARPET,
+ Blocks.PINK_CARPET,
+ Blocks.GRAY_CARPET,
+ Blocks.LIGHT_GRAY_CARPET,
+ Blocks.CYAN_CARPET,
+ Blocks.PURPLE_CARPET,
+ Blocks.BLUE_CARPET,
+ Blocks.BROWN_CARPET,
+ Blocks.GREEN_CARPET,
+ Blocks.RED_CARPET,
+ Blocks.BLACK_CARPET,
+ Blocks.MOSS_CARPET,
+ Blocks.PALE_MOSS_CARPET,
+ )
+
+ fun isEtherwarpTransparent(world: BlockView, blockPos: BlockPos): Boolean {
+ val blockState = world.getBlockState(blockPos)
+ if (blockState.block.defaultState.getCollisionShape(world, blockPos).isEmpty)
+ return true
+ if (blockState.block in etherwarpHallpasses)
+ return true
+ return false
+ }
+
+ sealed interface EtherwarpBlockHit {
+ data class BlockHit(val blockPos: BlockPos) : EtherwarpBlockHit
+ data object Miss : EtherwarpBlockHit
+ }
+
+ fun raycastWithEtherwarpTransparency(world: BlockView, start: Vec3d, end: Vec3d): EtherwarpBlockHit {
+ return BlockView.raycast<EtherwarpBlockHit, Unit>(
+ start, end, Unit,
+ { _, blockPos ->
+ if (isEtherwarpTransparent(world, blockPos)) {
+ return@raycast null
+ }
+// val defaultedState = world.getBlockState(blockPos).block.defaultState
+// val hitShape = defaultedState.getCollisionShape(
+// world,
+// blockPos,
+// ShapeContext.absent()
+// )
+// if (world.raycastBlock(start, end, blockPos, hitShape, defaultedState) == null) {
+// return@raycast null
+// }
+ return@raycast EtherwarpBlockHit.BlockHit(blockPos)
+ },
+ { EtherwarpBlockHit.Miss })
+ }
+
+ enum class EtherwarpItemKind{
+ MERGED,
+ RAW
+ }
@Subscribe
fun renderEtherwarpOverlay(event: WorldRenderLastEvent) {
@@ -35,20 +189,55 @@ object EtherwarpOverlay : FirmamentFeature {
val player = MC.player ?: return
if (TConfig.onlyShowWhileSneaking && !player.isSneaking) return
val world = player.world
- val camera = MC.camera ?: return
val heldItem = MC.stackInHand
- if (heldItem.skyBlockId !in listOf(SkyBlockItems.ASPECT_OF_THE_VOID, SkyBlockItems.ASPECT_OF_THE_END)) return
- if (!heldItem.extraAttributes.contains("ethermerge")) return
-
- val hitResult = camera.raycast(61.0, 0.0f, false)
- if (hitResult !is BlockHitResult) return
+ val etherwarpTyp = run {
+ if (heldItem.extraAttributes.contains("ethermerge"))
+ EtherwarpItemKind.MERGED
+ else if (heldItem.skyBlockId == SkyBlockItems.ETHERWARP_CONDUIT)
+ EtherwarpItemKind.RAW
+ else
+ return
+ }
+ val playerEyeHeight =
+ if (player.isSneaking || etherwarpTyp == EtherwarpItemKind.MERGED) 1.54 else 1.62 // Sneaking: 1.27 (1.21) 1.54 (1.8.9) / Upright: 1.62 (1.8.9,1.21)
+ val playerEyePos = player.pos.add(0.0, playerEyeHeight, 0.0)
+ val start = playerEyePos
+ val end = player.getRotationVec(0F).multiply(120.0).add(playerEyePos)
+ val hitResult = raycastWithEtherwarpTransparency(
+ world,
+ start,
+ end,
+ )
+ if (hitResult !is EtherwarpBlockHit.BlockHit) return
val blockPos = hitResult.blockPos
- if (camera.squaredDistanceTo(blockPos.toCenterPos()) > 61 * 61) return
- if (!world.getBlockState(blockPos.up()).isAir) return
- if (!world.getBlockState(blockPos.up(2)).isAir) return
+ val success = run {
+ if (!isEtherwarpTransparent(world, blockPos.up()))
+ EtherwarpResult.OCCUPIED
+ else if (!isEtherwarpTransparent(world, blockPos.up(2)))
+ EtherwarpResult.OCCUPIED
+ else if (player.squaredDistanceTo(blockPos.toCenterPos()) > 61 * 61)
+ EtherwarpResult.TOO_DISTANT
+ else if ((MC.instance.crosshairTarget as? BlockHitResult)
+ ?.takeIf { it.type == HitResult.Type.BLOCK }
+ ?.let { world.getBlockState(it.blockPos).block in interactionBlocked }
+ ?: false
+ )
+ EtherwarpResult.INTERACTION_BLOCKED
+ else
+ EtherwarpResult.SUCCESS
+ }
RenderInWorldContext.renderInWorld(event) {
- if (TConfig.cube) block(blockPos, TConfig.cubeColour.getEffectiveColourRGB())
+ if (TConfig.cube)
+ block(
+ blockPos,
+ success.color().getEffectiveColourRGB()
+ )
if (TConfig.wireframe) wireframeCube(blockPos, 10f)
+ if (TConfig.failureText && success.label != null) {
+ withFacingThePlayer(blockPos.toCenterPos()) {
+ text(success.label)
+ }
+ }
}
}
}
diff --git a/src/main/kotlin/util/skyblock/SkyBlockItems.kt b/src/main/kotlin/util/skyblock/SkyBlockItems.kt
index 32c4aab..785866e 100644
--- a/src/main/kotlin/util/skyblock/SkyBlockItems.kt
+++ b/src/main/kotlin/util/skyblock/SkyBlockItems.kt
@@ -21,4 +21,5 @@ object SkyBlockItems {
val TRIBAL_SPEAR = SkyblockId("TRIBAL_SPEAR")
val BLOCK_ZAPPER = SkyblockId("BLOCK_ZAPPER")
val HUNTING_TOOLKIT = SkyblockId("HUNTING_TOOLKIT")
+ val ETHERWARP_CONDUIT = SkyblockId("ETHERWARP_CONDUIT")
}
diff --git a/translations/en_us.json b/translations/en_us.json
index f9ec850..9ca6852 100644
--- a/translations/en_us.json
+++ b/translations/en_us.json
@@ -138,10 +138,18 @@
"firmament.config.etherwarp-overlay": "Etherwarp Overlay",
"firmament.config.etherwarp-overlay.cube": "Cube",
"firmament.config.etherwarp-overlay.cube-colour": "Cube Color",
+ "firmament.config.etherwarp-overlay.cube-colour-fail": "Fail Colour",
+ "firmament.config.etherwarp-overlay.cube-colour-fail.description": "Cube Colour on Fail (Blocks above occupied)",
+ "firmament.config.etherwarp-overlay.cube-colour-tooclose": "Too Close Colour",
+ "firmament.config.etherwarp-overlay.cube-colour-tooclose.description": "Cube Colour if the warp would succeed, but you will interact with the block instead (you are too close, but no blocks above)",
+ "firmament.config.etherwarp-overlay.cube-colour-toofar": "Too Far Colour",
+ "firmament.config.etherwarp-overlay.cube-colour-toofar.description": "Cube Colour if the warp would succeed, if you were closer (too far away, but no blocks above)",
"firmament.config.etherwarp-overlay.cube-colour.description": "Choose the colour of the etherwarp target block.",
"firmament.config.etherwarp-overlay.cube.description": "Displays a full cube on the block",
"firmament.config.etherwarp-overlay.etherwarp-overlay": "Etherwarp Overlay",
"firmament.config.etherwarp-overlay.etherwarp-overlay.description": "Display an overlay that tells you what block you will warp to.",
+ "firmament.config.etherwarp-overlay.failure-text": "Show Failure Text",
+ "firmament.config.etherwarp-overlay.failure-text.description": "Show a text in game explaining why the teleport fails.",
"firmament.config.etherwarp-overlay.only-show-while-sneaking": "Only show while sneaking",
"firmament.config.etherwarp-overlay.only-show-while-sneaking.description": "Displays the Etherwarp overlay only while sneaking.",
"firmament.config.etherwarp-overlay.wireframe": "Outline",