mirror of
https://github.com/chylex/Hardcore-Ender-Expansion-2.git
synced 2025-04-08 12:15:50 +02:00
Move debug utilities to a separate module
This commit is contained in:
parent
7565443e38
commit
e0c3ed6bc3
.idea
build.gradledata/src/main/java/chylex/hee/datagen/client
modules
debug
system/src/main/java/chylex/hee
src/main/java/chylex/hee
@ -12,6 +12,7 @@
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/data" />
|
||||
<option value="$PROJECT_DIR$/modules/debug" />
|
||||
<option value="$PROJECT_DIR$/modules/system" />
|
||||
<option value="$PROJECT_DIR$/modules/util" />
|
||||
</set>
|
||||
|
11
build.gradle
11
build.gradle
@ -60,6 +60,7 @@ idea {
|
||||
|
||||
["out", "src/main/kotlin", "src/test/kotlin"].each {
|
||||
excludeDirs += file(it)
|
||||
excludeDirs += file("modules/debug/" + it)
|
||||
excludeDirs += file("modules/system/" + it)
|
||||
excludeDirs += file("modules/util/" + it)
|
||||
}
|
||||
@ -128,7 +129,6 @@ minecraft {
|
||||
|
||||
runs {
|
||||
client {
|
||||
property "hee.debug", ""
|
||||
property "mixin.env.remapRefMap", "true"
|
||||
property "mixin.env.refMapRemappingFile", "${projectDir}/build/createSrgToMcp/output.srg"
|
||||
arg "-mixin.config=hee.mixins.json"
|
||||
@ -138,6 +138,7 @@ minecraft {
|
||||
mods {
|
||||
hee {
|
||||
source sourceSets.main
|
||||
source project(":debug").sourceSets.main
|
||||
source project(":system").sourceSets.main
|
||||
source project(":util").sourceSets.main
|
||||
}
|
||||
@ -145,7 +146,6 @@ minecraft {
|
||||
}
|
||||
|
||||
server {
|
||||
property "hee.debug", ""
|
||||
property "mixin.env.remapRefMap", "true"
|
||||
property "mixin.env.refMapRemappingFile", "${projectDir}/build/createSrgToMcp/output.srg"
|
||||
arg "-mixin.config=hee.mixins.json"
|
||||
@ -155,6 +155,7 @@ minecraft {
|
||||
mods {
|
||||
hee {
|
||||
source sourceSets.main
|
||||
source project(":debug").sourceSets.main
|
||||
source project(":system").sourceSets.main
|
||||
source project(":util").sourceSets.main
|
||||
}
|
||||
@ -162,7 +163,6 @@ minecraft {
|
||||
}
|
||||
|
||||
data {
|
||||
property "hee.debug", ""
|
||||
args "--mod", "hee"
|
||||
args "--all"
|
||||
args "--output", file("data/gen")
|
||||
@ -174,6 +174,7 @@ minecraft {
|
||||
mods {
|
||||
hee {
|
||||
source sourceSets.main
|
||||
source project(":debug").sourceSets.main
|
||||
source project(":system").sourceSets.main
|
||||
source project(":util").sourceSets.main
|
||||
source project(":datagen").sourceSets.main
|
||||
@ -190,12 +191,12 @@ mixin {
|
||||
dependencies {
|
||||
minecraft "net.minecraftforge:forge:" + mc_version + "-" + forge_version
|
||||
|
||||
implementation project(":system")
|
||||
implementation project(":util")
|
||||
implementation project(":system")
|
||||
implementation "thedarkcolour:kotlinforforge:" + kotlin_mod_version
|
||||
|
||||
testImplementation project(":system")
|
||||
testImplementation project(":util")
|
||||
testImplementation project(":system")
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.0-RC1"
|
||||
|
||||
if (System.getProperty("idea.sync.active") != "true") {
|
||||
|
@ -91,7 +91,7 @@ class LangEnglish(generator: DataGenerator, modid: String) : LanguageProvider(ge
|
||||
}
|
||||
}
|
||||
|
||||
for (command in ClientCommandHandler.nonHelpCommands.values) {
|
||||
for (command in ClientCommandHandler.all.values) {
|
||||
val name = command.name
|
||||
add("commands.hee.$name.info", command.description)
|
||||
}
|
||||
|
33
modules/debug/build.gradle
Normal file
33
modules/debug/build.gradle
Normal file
@ -0,0 +1,33 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = "https://files.minecraftforge.net/maven" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath group: "net.minecraftforge.gradle", name: "ForgeGradle", version: forge_gradle_version, changing: true
|
||||
classpath group: "org.jetbrains.kotlin", name: "kotlin-gradle-plugin", version: kotlin_version
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "net.minecraftforge.gradle"
|
||||
|
||||
minecraft {
|
||||
mappings channel: "snapshot", version: rootProject.mapping_version
|
||||
setAccessTransformers(rootProject.access_transformers)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraftforge:forge:" + mc_version + "-" + forge_version
|
||||
implementation rootProject
|
||||
implementation project(":system")
|
||||
implementation project(":util")
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes([
|
||||
"FMLModType": "LIBRARY"
|
||||
])
|
||||
}
|
||||
}
|
143
modules/debug/src/main/java/chylex/hee/client/BuildStick.kt
Normal file
143
modules/debug/src/main/java/chylex/hee/client/BuildStick.kt
Normal file
@ -0,0 +1,143 @@
|
||||
package chylex.hee.client
|
||||
|
||||
import chylex.hee.client.render.RenderStateBuilder
|
||||
import chylex.hee.client.render.util.DF_ONE
|
||||
import chylex.hee.client.render.util.DF_ZERO
|
||||
import chylex.hee.client.render.util.SF_ONE_MINUS_SRC_ALPHA
|
||||
import chylex.hee.client.render.util.SF_SRC_ALPHA
|
||||
import chylex.hee.client.util.MC
|
||||
import chylex.hee.game.item.util.nbtOrNull
|
||||
import chylex.hee.game.world.util.floodFill
|
||||
import chylex.hee.game.world.util.getBlock
|
||||
import chylex.hee.game.world.util.getState
|
||||
import chylex.hee.game.world.util.isAir
|
||||
import chylex.hee.game.world.util.removeBlock
|
||||
import chylex.hee.game.world.util.setState
|
||||
import chylex.hee.util.nbt.hasKey
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.item.BlockItem
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.EAST
|
||||
import net.minecraft.util.Direction.NORTH
|
||||
import net.minecraft.util.Direction.SOUTH
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.Direction.WEST
|
||||
import net.minecraft.util.Hand.MAIN_HAND
|
||||
import net.minecraft.util.Hand.OFF_HAND
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.BlockRayTraceResult
|
||||
import net.minecraft.util.math.shapes.ISelectionContext
|
||||
import net.minecraft.world.IWorld
|
||||
import net.minecraftforge.client.event.DrawHighlightEvent
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock
|
||||
import net.minecraftforge.event.world.BlockEvent.BreakEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
object BuildStick {
|
||||
private val RENDER_TYPE_LINE = with(RenderStateBuilder()) {
|
||||
line(2.25)
|
||||
blend(SF_SRC_ALPHA, DF_ONE, SF_ONE_MINUS_SRC_ALPHA, DF_ZERO)
|
||||
layering(RenderStateBuilder.LAYERING_OFFSET_Z)
|
||||
mask(RenderStateBuilder.MASK_COLOR)
|
||||
buildType("hee:debug_line", DefaultVertexFormats.POSITION_COLOR, GL11.GL_LINES, bufferSize = 256)
|
||||
}
|
||||
|
||||
private fun isHoldingBuildStick(player: PlayerEntity): Boolean {
|
||||
val heldItem = player.getHeldItem(MAIN_HAND)
|
||||
return heldItem.item === Items.STICK && heldItem.nbtOrNull.hasKey("HEE_BUILD")
|
||||
}
|
||||
|
||||
private fun getBuildStickBlocks(world: IWorld, pos: BlockPos, state: BlockState, face: Direction): List<BlockPos> {
|
||||
val floodFaces = when (face) {
|
||||
UP, DOWN -> listOf(NORTH, SOUTH, EAST, WEST)
|
||||
NORTH, SOUTH -> listOf(UP, DOWN, EAST, WEST)
|
||||
EAST, WEST -> listOf(UP, DOWN, NORTH, SOUTH)
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
val limit = 1000
|
||||
val block = state.block
|
||||
return pos.floodFill(floodFaces, limit) { it.getBlock(world) === block }.takeIf { it.size < limit }.orEmpty()
|
||||
}
|
||||
|
||||
private var lastLeftClickHit: BlockRayTraceResult? = null
|
||||
|
||||
@SubscribeEvent
|
||||
fun onLeftClickBlock(e: LeftClickBlock) {
|
||||
val world = e.world
|
||||
|
||||
if (isHoldingBuildStick(e.player) && !world.isRemote) {
|
||||
lastLeftClickHit = MC.instance.objectMouseOver as? BlockRayTraceResult
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onBlockBreak(e: BreakEvent) {
|
||||
val world = e.world
|
||||
|
||||
if (isHoldingBuildStick(e.player) && !world.isRemote) {
|
||||
val hit = lastLeftClickHit ?: return
|
||||
|
||||
for (pos in getBuildStickBlocks(world, e.pos, e.state, hit.face)) {
|
||||
pos.removeBlock(world)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onRightClickBlock(e: RightClickBlock) {
|
||||
val world = e.world
|
||||
val player = e.player
|
||||
|
||||
if (isHoldingBuildStick(player) && !world.isRemote) {
|
||||
val state = e.pos.getState(world)
|
||||
val face = e.face!!
|
||||
|
||||
val place = (player.getHeldItem(OFF_HAND).item as? BlockItem)?.block?.defaultState ?: state
|
||||
|
||||
for (pos in getBuildStickBlocks(world, e.pos, state, face)) {
|
||||
val offset = pos.offset(face)
|
||||
|
||||
if (offset.isAir(world)) {
|
||||
offset.setState(world, place)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onRenderOverlay(e: DrawHighlightEvent.HighlightBlock) {
|
||||
val player = MC.player!!
|
||||
|
||||
if (isHoldingBuildStick(player)) {
|
||||
val hit = MC.instance.objectMouseOver as? BlockRayTraceResult ?: return
|
||||
val world = player.world
|
||||
val center = hit.pos
|
||||
val info = e.info
|
||||
|
||||
val matrix = e.matrix.last.matrix
|
||||
val builder = e.buffers.getBuffer(RENDER_TYPE_LINE)
|
||||
|
||||
for (pos in getBuildStickBlocks(world, center, center.getState(world), hit.face)) {
|
||||
val x = pos.x - info.projectedView.x
|
||||
val y = pos.y - info.projectedView.y
|
||||
val z = pos.z - info.projectedView.z
|
||||
|
||||
val shape = pos.getState(world).getShape(world, pos, ISelectionContext.forEntity(info.renderViewEntity))
|
||||
|
||||
shape.forEachEdge { x1, y1, z1, x2, y2, z2 ->
|
||||
builder.pos(matrix, (x1 + x).toFloat(), (y1 + y).toFloat(), (z1 + z).toFloat()).color(1F, 1F, 1F, 1F).endVertex()
|
||||
builder.pos(matrix, (x2 + x).toFloat(), (y2 + y).toFloat(), (z2 + z).toFloat()).color(1F, 1F, 1F, 1F).endVertex()
|
||||
}
|
||||
}
|
||||
|
||||
e.isCanceled = true
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package chylex.hee.client
|
||||
|
||||
import chylex.hee.client.util.MC
|
||||
import net.minecraftforge.client.event.InputEvent.KeyInputEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
import org.lwjgl.glfw.GLFW
|
||||
|
||||
object GameModeToggle {
|
||||
@SubscribeEvent
|
||||
fun onKeyPressed(e: KeyInputEvent) {
|
||||
if (e.action != GLFW.GLFW_PRESS) {
|
||||
return
|
||||
}
|
||||
|
||||
if (e.key == GLFW.GLFW_KEY_GRAVE_ACCENT) {
|
||||
val player = MC.player ?: return
|
||||
|
||||
if (player.isCreative) {
|
||||
val ctrl = (e.modifiers and GLFW.GLFW_MOD_CONTROL) != 0
|
||||
player.sendChatMessage(if (ctrl) "/gamemode spectator" else "/gamemode survival")
|
||||
}
|
||||
else {
|
||||
player.sendChatMessage("/gamemode creative")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package chylex.hee.client
|
||||
|
||||
import chylex.hee.client.render.TerritoryRenderer
|
||||
import chylex.hee.client.util.MC
|
||||
import chylex.hee.game.world.isInEndDimension
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||
|
||||
object TerritoryVoidDebug {
|
||||
@SubscribeEvent
|
||||
fun onRenderGameOverlayText(e: RenderGameOverlayEvent.Text) {
|
||||
if (MC.settings.showDebugInfo && MC.player?.isInEndDimension == true) {
|
||||
with(e.left) {
|
||||
add("")
|
||||
add("End Void Factor: ${"%.3f".format(TerritoryRenderer.currentVoidFactor)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
72
modules/debug/src/main/java/chylex/hee/debug/Debug.kt
Normal file
72
modules/debug/src/main/java/chylex/hee/debug/Debug.kt
Normal file
@ -0,0 +1,72 @@
|
||||
package chylex.hee.debug
|
||||
|
||||
import chylex.hee.HEE
|
||||
import chylex.hee.client.BuildStick
|
||||
import chylex.hee.client.GameModeToggle
|
||||
import chylex.hee.client.TerritoryVoidDebug
|
||||
import chylex.hee.game.block.BlockScaffoldingDebug
|
||||
import chylex.hee.game.block.HeeBlock
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import chylex.hee.game.command.client.CommandClientDebugToggles
|
||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||
import chylex.hee.game.command.server.CommandServerInstability
|
||||
import chylex.hee.game.command.server.CommandServerStructure
|
||||
import chylex.hee.game.command.server.CommandServerTerritory
|
||||
import chylex.hee.game.command.server.CommandServerTestWorld
|
||||
import chylex.hee.system.IDebugModule
|
||||
import chylex.hee.util.forge.Side
|
||||
import chylex.hee.util.forge.Sided
|
||||
import chylex.hee.util.forge.SubscribeAllEvents
|
||||
import chylex.hee.util.forge.SubscribeEvent
|
||||
import net.minecraftforge.client.event.GuiOpenEvent
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.MOD
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
|
||||
|
||||
@SubscribeAllEvents(modid = HEE.ID, bus = MOD)
|
||||
internal object Debug : IDebugModule {
|
||||
init {
|
||||
HEE.debug = true
|
||||
HEE.debugModule = this
|
||||
}
|
||||
|
||||
override val clientCommands
|
||||
get() = listOf(
|
||||
CommandClientScaffolding,
|
||||
CommandClientDebugToggles
|
||||
)
|
||||
|
||||
override val serverCommands
|
||||
get() = listOf(
|
||||
CommandServerInstability,
|
||||
CommandServerStructure,
|
||||
CommandServerTerritory,
|
||||
CommandServerTestWorld
|
||||
)
|
||||
|
||||
override fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock {
|
||||
return BlockScaffoldingDebug(builder)
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onClientSetup(@Suppress("UNUSED_PARAMETER") e: FMLClientSetupEvent) {
|
||||
initializeClient()
|
||||
}
|
||||
|
||||
@Sided(Side.CLIENT)
|
||||
private fun initializeClient() {
|
||||
if (HEE.debug) {
|
||||
MinecraftForge.EVENT_BUS.register(BuildStick)
|
||||
MinecraftForge.EVENT_BUS.register(GameModeToggle)
|
||||
MinecraftForge.EVENT_BUS.register(TerritoryVoidDebug)
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(object : Any() {
|
||||
@SubscribeEvent
|
||||
fun onGuiOpen(@Suppress("UNUSED_PARAMETER") e: GuiOpenEvent) {
|
||||
PowerShell.maximizeWindow()
|
||||
MinecraftForge.EVENT_BUS.unregister(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
26
modules/debug/src/main/java/chylex/hee/debug/PowerShell.kt
Normal file
26
modules/debug/src/main/java/chylex/hee/debug/PowerShell.kt
Normal file
@ -0,0 +1,26 @@
|
||||
package chylex.hee.debug
|
||||
|
||||
import chylex.hee.game.Environment
|
||||
import chylex.hee.util.forge.Side
|
||||
import org.apache.commons.lang3.SystemUtils
|
||||
import java.io.File
|
||||
import java.lang.management.ManagementFactory
|
||||
|
||||
internal object PowerShell {
|
||||
private fun canExecutePowershell(scriptName: String): Boolean {
|
||||
return SystemUtils.IS_OS_WINDOWS && Environment.side == Side.CLIENT && File(scriptName).exists()
|
||||
}
|
||||
|
||||
fun setClipboardContents(file: File) {
|
||||
if (canExecutePowershell("filecopy.ps1")) {
|
||||
ProcessBuilder("powershell.exe", "-ExecutionPolicy", "Unrestricted", "-Sta", "-File", "filecopy.ps1", file.absolutePath).start()
|
||||
}
|
||||
}
|
||||
|
||||
fun maximizeWindow() {
|
||||
if (canExecutePowershell("maximize.ps1")) {
|
||||
val pid = ManagementFactory.getRuntimeMXBean().name.split("@")[0]
|
||||
ProcessBuilder("powershell.exe", "-ExecutionPolicy", "Unrestricted", "-File", "maximize.ps1", pid).start()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
package chylex.hee.game.block
|
||||
|
||||
import chylex.hee.debug.PowerShell
|
||||
import chylex.hee.game.Environment
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||
import chylex.hee.game.world.generation.structure.file.StructureFile
|
||||
import chylex.hee.game.world.generation.util.WorldToStructureWorldAdapter
|
||||
import chylex.hee.game.world.util.getBlock
|
||||
import chylex.hee.game.world.util.offsetUntilExcept
|
||||
import chylex.hee.util.math.BoundingBox
|
||||
import chylex.hee.util.math.Pos
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.nbt.CompressedStreamTools
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.ActionResultType.FAIL
|
||||
import net.minecraft.util.ActionResultType.SUCCESS
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.EAST
|
||||
import net.minecraft.util.Direction.NORTH
|
||||
import net.minecraft.util.Direction.SOUTH
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.Direction.WEST
|
||||
import net.minecraft.util.Hand
|
||||
import net.minecraft.util.Util
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.BlockRayTraceResult
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import net.minecraft.util.text.TextFormatting
|
||||
import net.minecraft.world.World
|
||||
import java.nio.file.Files
|
||||
|
||||
class BlockScaffoldingDebug(builder: BlockBuilder) : BlockScaffolding(builder) {
|
||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||
if (world.isRemote && player.isSneaking && !player.abilities.isFlying) {
|
||||
val palette = CommandClientScaffolding.currentPalette
|
||||
|
||||
if (palette == null) {
|
||||
player.sendMessage(StringTextComponent("No structure set."), Util.DUMMY_UUID)
|
||||
return FAIL
|
||||
}
|
||||
|
||||
val minPos = findMinPos(world, pos)?.let { findMinPos(world, it) } // double pass to find min from any side
|
||||
val maxPos = minPos?.let { findMaxPos(world, it) }
|
||||
|
||||
if (minPos == null || maxPos == null) {
|
||||
player.sendMessage(StringTextComponent("Could not find structure boundaries."), Util.DUMMY_UUID)
|
||||
return FAIL
|
||||
}
|
||||
|
||||
val box = BoundingBox(minPos, maxPos)
|
||||
val serverWorld = Environment.getDimension(world.dimensionKey)
|
||||
|
||||
val (structureTag, missingMappings) = StructureFile.save(WorldToStructureWorldAdapter(serverWorld, serverWorld.rand, box.min), box.size, palette, this)
|
||||
val structureFile = Files.createTempDirectory("HardcoreEnderExpansion_Structure_").resolve(CommandClientScaffolding.currentFile).toFile()
|
||||
|
||||
CompressedStreamTools.write(structureTag, structureFile)
|
||||
PowerShell.setClipboardContents(structureFile)
|
||||
|
||||
if (missingMappings.isNotEmpty()) {
|
||||
player.sendMessage(StringTextComponent("Missing mappings for states:"), Util.DUMMY_UUID)
|
||||
|
||||
for (missingMapping in missingMappings) {
|
||||
player.sendMessage(StringTextComponent(" - ${TextFormatting.GRAY}$missingMapping"), Util.DUMMY_UUID)
|
||||
}
|
||||
}
|
||||
|
||||
player.sendMessage(StringTextComponent("Generated structure file of ${box.size}."), Util.DUMMY_UUID)
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
return FAIL
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
private fun find(world: World, pos: BlockPos?, direction: Direction): BlockPos? {
|
||||
return pos?.offsetUntilExcept(direction, 0..255) { it.getBlock(world) === Blocks.AIR }
|
||||
}
|
||||
|
||||
private fun findMinPos(world: World, pos: BlockPos): BlockPos? {
|
||||
val bottomPos = find(world, pos, DOWN)
|
||||
|
||||
val y = bottomPos?.y
|
||||
val x = find(world, bottomPos, WEST)?.x
|
||||
val z = find(world, bottomPos, NORTH)?.z
|
||||
|
||||
return if (x == null || y == null || z == null) null else Pos(x, y, z)
|
||||
}
|
||||
|
||||
private fun findMaxPos(world: World, pos: BlockPos): BlockPos? {
|
||||
val topPos = find(world, pos, UP)
|
||||
|
||||
val y = topPos?.y
|
||||
val x = find(world, topPos, EAST)?.x
|
||||
val z = find(world, topPos, SOUTH)?.z
|
||||
|
||||
return if (x == null || y == null || z == null) null else Pos(x, y, z)
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
package chylex.hee.game.command.client
|
||||
|
||||
import chylex.hee.client.render.TerritoryRenderer
|
||||
import chylex.hee.game.block.BlockScaffolding
|
||||
import chylex.hee.game.command.IClientCommand
|
||||
import chylex.hee.game.territory.TerritoryVoid
|
||||
import chylex.hee.init.ModBlocks
|
||||
import net.minecraft.command.CommandSource
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
|
||||
object CommandDebugToggles : IClientCommand {
|
||||
object CommandClientDebugToggles : IClientCommand {
|
||||
override val name = "debug"
|
||||
override val description = "access to debug toggles"
|
||||
|
||||
@ -23,8 +23,8 @@ object CommandDebugToggles : IClientCommand {
|
||||
sender.sendFeedback(StringTextComponent("Territory debugging ${if (debug) "enabled" else "disabled"}."), false)
|
||||
}
|
||||
else if (name == "scaffolding") {
|
||||
ModBlocks.SCAFFOLDING.enableShape = !ModBlocks.SCAFFOLDING.enableShape
|
||||
sender.sendFeedback(StringTextComponent("Scaffolding shape ${if (ModBlocks.SCAFFOLDING.enableShape) "enabled" else "disabled"}."), false)
|
||||
BlockScaffolding.enableShape = !BlockScaffolding.enableShape
|
||||
sender.sendFeedback(StringTextComponent("Scaffolding shape ${if (BlockScaffolding.enableShape) "enabled" else "disabled"}."), false)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package chylex.hee.game.command.client
|
||||
|
||||
import chylex.hee.game.command.IClientCommand
|
||||
import chylex.hee.game.command.server.CommandDebugStructure
|
||||
import chylex.hee.game.command.server.CommandServerStructure
|
||||
import net.minecraft.command.CommandSource
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import java.util.prefs.Preferences
|
||||
@ -14,7 +14,7 @@ object CommandClientScaffolding : IClientCommand {
|
||||
get() = Preferences.userRoot().node("chylex-hee-scaffolding")
|
||||
|
||||
val currentPalette
|
||||
get() = data.get("Structure", null)?.let(CommandDebugStructure.structureDescriptions::get)?.PALETTE
|
||||
get() = data.get("Structure", null)?.let(CommandServerStructure.structureDescriptions::get)?.PALETTE
|
||||
|
||||
val currentFile
|
||||
get() = data.get("File", "")!!.ifBlank { "structure.nbt" }
|
||||
@ -22,7 +22,7 @@ object CommandClientScaffolding : IClientCommand {
|
||||
override fun executeCommand(sender: CommandSource, args: Array<String>) {
|
||||
val structure = args.getOrNull(0) ?: return
|
||||
|
||||
if (!CommandDebugStructure.structureDescriptions.containsKey(structure)) {
|
||||
if (!CommandServerStructure.structureDescriptions.containsKey(structure)) {
|
||||
sender.sendFeedback(StringTextComponent("Unknown structure."), false)
|
||||
return
|
||||
}
|
@ -15,7 +15,7 @@ import net.minecraft.command.Commands.argument
|
||||
import net.minecraft.command.Commands.literal
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
|
||||
object CommandDebugInstability : ICommand {
|
||||
object CommandServerInstability : ICommand {
|
||||
override val name = "instability"
|
||||
override val description = "utilities for instability"
|
||||
|
@ -31,7 +31,7 @@ import net.minecraft.util.Rotation
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import java.util.Random
|
||||
|
||||
object CommandDebugStructure : ICommand {
|
||||
object CommandServerStructure : ICommand {
|
||||
val structureDescriptions = mapOf(
|
||||
"stronghold" to StrongholdPieces,
|
||||
"energyshrine" to EnergyShrinePieces,
|
@ -23,7 +23,7 @@ import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import java.util.Random
|
||||
|
||||
object CommandDebugTerritory : ICommand {
|
||||
object CommandServerTerritory : ICommand {
|
||||
override val name = "territory"
|
||||
override val description = "utilities for territories"
|
||||
|
@ -7,7 +7,7 @@ import com.mojang.brigadier.builder.ArgumentBuilder
|
||||
import com.mojang.brigadier.context.CommandContext
|
||||
import net.minecraft.command.CommandSource
|
||||
|
||||
object CommandDebugTestWorld : ICommand, CommandExecutionFunction {
|
||||
object CommandServerTestWorld : ICommand, CommandExecutionFunction {
|
||||
override val name = "testworld"
|
||||
override val description = "converts overworld into a test world"
|
||||
|
7
modules/debug/src/main/resources/pack.mcmeta
Normal file
7
modules/debug/src/main/resources/pack.mcmeta
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"pack": {
|
||||
"description": "Hardcore Ender Expansion 2 (Debug Library)",
|
||||
"pack_format": 6,
|
||||
"_comment": ""
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package chylex.hee
|
||||
|
||||
import chylex.hee.game.Resource
|
||||
import chylex.hee.system.IDebugModule
|
||||
import net.minecraft.util.RegistryKey
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.minecraft.world.World
|
||||
@ -12,6 +13,10 @@ object HEE {
|
||||
|
||||
lateinit var version: String
|
||||
|
||||
@JvmField
|
||||
var debug = false
|
||||
var debugModule: IDebugModule? = null
|
||||
|
||||
val log: Logger = LogManager.getLogger("HardcoreEnderExpansion")
|
||||
val dim: RegistryKey<World> = RegistryKey.getOrCreateKey(Registry.WORLD_KEY, Resource.Custom("end"))
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import chylex.hee.game.world.generation.structure.piece.IStructurePieceConnectio
|
||||
import chylex.hee.game.world.generation.structure.piece.StructureBuild.AddMode.APPEND
|
||||
import chylex.hee.game.world.generation.structure.piece.StructureBuild.AddMode.MERGE
|
||||
import chylex.hee.game.world.generation.structure.world.OffsetStructureWorld
|
||||
import chylex.hee.system.Debug
|
||||
import chylex.hee.util.math.Size
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
@ -83,7 +82,7 @@ class StructureBuild<T : StructurePiece<*>.MutableInstance>(val size: Size) {
|
||||
* [MERGE] mode allows intersection with [targetPiece] but no other pieces.
|
||||
*/
|
||||
fun addPiece(newPiece: T, newPieceConnection: IStructurePieceConnection, targetPiece: PositionedPiece<T>, targetPieceConnection: IStructurePieceConnection, mode: AddMode = APPEND): PositionedPiece<T>? {
|
||||
if (Debug.enabled && !pieces.contains(targetPiece)) {
|
||||
if (HEE.debug && !pieces.contains(targetPiece)) {
|
||||
HEE.log.error("[StructureBuild] attempted to connect to a piece that is not present in the structure")
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import chylex.hee.game.world.generation.structure.IStructureWorld
|
||||
import chylex.hee.game.world.generation.structure.world.segments.ISegment
|
||||
import chylex.hee.game.world.generation.structure.world.segments.ISegment.Companion.index
|
||||
import chylex.hee.game.world.util.Transform
|
||||
import chylex.hee.system.Debug
|
||||
import chylex.hee.util.math.Pos
|
||||
import chylex.hee.util.math.Size
|
||||
import chylex.hee.util.math.ceilToInt
|
||||
@ -32,7 +31,7 @@ open class SegmentedWorld(override val rand: Random, val worldSize: Size, privat
|
||||
if (!isInside(pos)) {
|
||||
HEE.log.warn("[SegmentedWorld] attempted to access position outside bounds: $pos is outside $worldSize")
|
||||
|
||||
if (Debug.enabled) {
|
||||
if (HEE.debug) {
|
||||
Thread.dumpStack()
|
||||
}
|
||||
|
||||
|
@ -1,206 +0,0 @@
|
||||
package chylex.hee.system
|
||||
|
||||
import chylex.hee.client.render.RenderStateBuilder
|
||||
import chylex.hee.client.render.RenderStateBuilder.Companion.LAYERING_OFFSET_Z
|
||||
import chylex.hee.client.render.RenderStateBuilder.Companion.MASK_COLOR
|
||||
import chylex.hee.client.render.util.DF_ONE
|
||||
import chylex.hee.client.render.util.DF_ZERO
|
||||
import chylex.hee.client.render.util.SF_ONE_MINUS_SRC_ALPHA
|
||||
import chylex.hee.client.render.util.SF_SRC_ALPHA
|
||||
import chylex.hee.client.util.MC
|
||||
import chylex.hee.game.Environment
|
||||
import chylex.hee.game.item.util.nbtOrNull
|
||||
import chylex.hee.game.world.util.floodFill
|
||||
import chylex.hee.game.world.util.getBlock
|
||||
import chylex.hee.game.world.util.getState
|
||||
import chylex.hee.game.world.util.isAir
|
||||
import chylex.hee.game.world.util.removeBlock
|
||||
import chylex.hee.game.world.util.setState
|
||||
import chylex.hee.util.forge.Side
|
||||
import chylex.hee.util.forge.Sided
|
||||
import chylex.hee.util.forge.SubscribeEvent
|
||||
import chylex.hee.util.nbt.hasKey
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.item.BlockItem
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.EAST
|
||||
import net.minecraft.util.Direction.NORTH
|
||||
import net.minecraft.util.Direction.SOUTH
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.Direction.WEST
|
||||
import net.minecraft.util.Hand.MAIN_HAND
|
||||
import net.minecraft.util.Hand.OFF_HAND
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.BlockRayTraceResult
|
||||
import net.minecraft.util.math.shapes.ISelectionContext
|
||||
import net.minecraft.world.IWorld
|
||||
import net.minecraftforge.client.event.DrawHighlightEvent
|
||||
import net.minecraftforge.client.event.GuiOpenEvent
|
||||
import net.minecraftforge.client.event.InputEvent.KeyInputEvent
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock
|
||||
import net.minecraftforge.event.world.BlockEvent.BreakEvent
|
||||
import org.apache.commons.lang3.SystemUtils
|
||||
import org.lwjgl.glfw.GLFW
|
||||
import org.lwjgl.opengl.GL11
|
||||
import java.io.File
|
||||
import java.lang.management.ManagementFactory
|
||||
|
||||
object Debug {
|
||||
@JvmField
|
||||
val enabled = System.getProperty("hee.debug") != null
|
||||
|
||||
@Sided(Side.CLIENT)
|
||||
fun initializeClient() {
|
||||
if (enabled) {
|
||||
MinecraftForge.EVENT_BUS.register(object : Any() {
|
||||
@SubscribeEvent
|
||||
fun onKeyPressed(e: KeyInputEvent) {
|
||||
if (e.action != GLFW.GLFW_PRESS) {
|
||||
return
|
||||
}
|
||||
|
||||
if (e.key == GLFW.GLFW_KEY_GRAVE_ACCENT) {
|
||||
val player = MC.player ?: return
|
||||
|
||||
if (player.isCreative) {
|
||||
val ctrl = (e.modifiers and GLFW.GLFW_MOD_CONTROL) != 0
|
||||
player.sendChatMessage(if (ctrl) "/gamemode spectator" else "/gamemode survival")
|
||||
}
|
||||
else {
|
||||
player.sendChatMessage("/gamemode creative")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isHoldingBuildStick(player: PlayerEntity): Boolean {
|
||||
val heldItem = player.getHeldItem(MAIN_HAND)
|
||||
return heldItem.item === Items.STICK && heldItem.nbtOrNull.hasKey("HEE_BUILD")
|
||||
}
|
||||
|
||||
private fun getBuildStickBlocks(world: IWorld, pos: BlockPos, state: BlockState, face: Direction): List<BlockPos> {
|
||||
val floodFaces = when (face) {
|
||||
UP, DOWN -> listOf(NORTH, SOUTH, EAST, WEST)
|
||||
NORTH, SOUTH -> listOf(UP, DOWN, EAST, WEST)
|
||||
EAST, WEST -> listOf(UP, DOWN, NORTH, SOUTH)
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
val limit = 1000
|
||||
val block = state.block
|
||||
return pos.floodFill(floodFaces, limit) { it.getBlock(world) === block }.takeIf { it.size < limit }.orEmpty()
|
||||
}
|
||||
|
||||
private var lastLeftClickHit: BlockRayTraceResult? = null
|
||||
|
||||
@SubscribeEvent
|
||||
fun onLeftClickBlock(e: LeftClickBlock) {
|
||||
val world = e.world
|
||||
|
||||
if (isHoldingBuildStick(e.player) && !world.isRemote) {
|
||||
lastLeftClickHit = MC.instance.objectMouseOver as? BlockRayTraceResult
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onBlockBreak(e: BreakEvent) {
|
||||
val world = e.world
|
||||
|
||||
if (isHoldingBuildStick(e.player) && !world.isRemote) {
|
||||
val hit = lastLeftClickHit ?: return
|
||||
|
||||
for (pos in getBuildStickBlocks(world, e.pos, e.state, hit.face)) {
|
||||
pos.removeBlock(world)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onRightClickBlock(e: RightClickBlock) {
|
||||
val world = e.world
|
||||
val player = e.player
|
||||
|
||||
if (isHoldingBuildStick(player) && !world.isRemote) {
|
||||
val state = e.pos.getState(world)
|
||||
val face = e.face!!
|
||||
|
||||
val place = (player.getHeldItem(OFF_HAND).item as? BlockItem)?.block?.defaultState ?: state
|
||||
|
||||
for (pos in getBuildStickBlocks(world, e.pos, state, face)) {
|
||||
val offset = pos.offset(face)
|
||||
|
||||
if (offset.isAir(world)) {
|
||||
offset.setState(world, place)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val RENDER_TYPE_LINE = with(RenderStateBuilder()) {
|
||||
line(2.25)
|
||||
blend(SF_SRC_ALPHA, DF_ONE, SF_ONE_MINUS_SRC_ALPHA, DF_ZERO)
|
||||
layering(LAYERING_OFFSET_Z)
|
||||
mask(MASK_COLOR)
|
||||
buildType("hee:debug_line", DefaultVertexFormats.POSITION_COLOR, GL11.GL_LINES, bufferSize = 256)
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onRenderOverlay(e: DrawHighlightEvent.HighlightBlock) {
|
||||
val player = MC.player!!
|
||||
|
||||
if (isHoldingBuildStick(player)) {
|
||||
val hit = MC.instance.objectMouseOver as? BlockRayTraceResult ?: return
|
||||
val world = player.world
|
||||
val center = hit.pos
|
||||
val info = e.info
|
||||
|
||||
val matrix = e.matrix.last.matrix
|
||||
val builder = e.buffers.getBuffer(RENDER_TYPE_LINE)
|
||||
|
||||
for (pos in getBuildStickBlocks(world, center, center.getState(world), hit.face)) {
|
||||
val x = pos.x - info.projectedView.x
|
||||
val y = pos.y - info.projectedView.y
|
||||
val z = pos.z - info.projectedView.z
|
||||
|
||||
val shape = pos.getState(world).getShape(world, pos, ISelectionContext.forEntity(info.renderViewEntity))
|
||||
|
||||
shape.forEachEdge { x1, y1, z1, x2, y2, z2 ->
|
||||
builder.pos(matrix, (x1 + x).toFloat(), (y1 + y).toFloat(), (z1 + z).toFloat()).color(1F, 1F, 1F, 1F).endVertex()
|
||||
builder.pos(matrix, (x2 + x).toFloat(), (y2 + y).toFloat(), (z2 + z).toFloat()).color(1F, 1F, 1F, 1F).endVertex()
|
||||
}
|
||||
}
|
||||
|
||||
e.isCanceled = true
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (canExecutePowershell("maximize.ps1")) {
|
||||
MinecraftForge.EVENT_BUS.register(object : Any() {
|
||||
@SubscribeEvent
|
||||
fun onGuiOpen(@Suppress("UNUSED_PARAMETER") e: GuiOpenEvent) {
|
||||
val pid = ManagementFactory.getRuntimeMXBean().name.split("@")[0]
|
||||
ProcessBuilder("powershell.exe", "-ExecutionPolicy", "Unrestricted", "-File", "maximize.ps1", pid).start()
|
||||
|
||||
MinecraftForge.EVENT_BUS.unregister(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setClipboardContents(file: File) {
|
||||
if (canExecutePowershell("filecopy.ps1")) {
|
||||
ProcessBuilder("powershell.exe", "-ExecutionPolicy", "Unrestricted", "-Sta", "-File", "filecopy.ps1", file.absolutePath).start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun canExecutePowershell(scriptName: String): Boolean {
|
||||
return SystemUtils.IS_OS_WINDOWS && Environment.side == Side.CLIENT && File(scriptName).exists()
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package chylex.hee.system
|
||||
|
||||
import chylex.hee.game.block.HeeBlock
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import chylex.hee.game.command.IClientCommand
|
||||
import chylex.hee.game.command.ICommand
|
||||
|
||||
interface IDebugModule {
|
||||
val clientCommands: List<IClientCommand>
|
||||
val serverCommands: List<ICommand>
|
||||
|
||||
fun createScaffoldingBlock(builder: BlockBuilder): HeeBlock
|
||||
}
|
@ -19,7 +19,7 @@ object MinecraftForgeEventBus {
|
||||
}
|
||||
|
||||
for (listener in item.javaClass.methods.filter { !Modifier.isStatic(it.modifiers) && it.isAnnotationPresent(SubscribeEvent::class.java) }) {
|
||||
if (Debug.enabled) {
|
||||
if (HEE.debug) {
|
||||
HEE.log.info("[MinecraftForgeEventBus] registering ${listener.parameterTypes.firstOrNull()?.name?.substringAfterLast('.')} for ${item.javaClass.simpleName}")
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
include ":system"
|
||||
include ":util"
|
||||
include ":system"
|
||||
include ":debug"
|
||||
include ":datagen"
|
||||
|
||||
project(":system").projectDir = file("./modules/system")
|
||||
project(":util").projectDir = file("./modules/util")
|
||||
project(":system").projectDir = file("./modules/system")
|
||||
project(":debug").projectDir = file("./modules/debug")
|
||||
project(":datagen").projectDir = file("./data")
|
||||
|
@ -19,7 +19,6 @@ import chylex.hee.init.ModPackets
|
||||
import chylex.hee.init.ModPotions
|
||||
import chylex.hee.init.ModTileEntities
|
||||
import chylex.hee.network.NetworkManager
|
||||
import chylex.hee.system.Debug
|
||||
import chylex.hee.util.forge.Side
|
||||
import chylex.hee.util.forge.SubscribeAllEvents
|
||||
import chylex.hee.util.forge.SubscribeEvent
|
||||
@ -29,7 +28,6 @@ import net.minecraftforge.fml.DistExecutor.SafeRunnable
|
||||
import net.minecraftforge.fml.ModLoadingContext
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.MOD
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent
|
||||
|
||||
@ -41,6 +39,10 @@ object Mod {
|
||||
HEE.version = activeContainer.modInfo.version.toString()
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("chylex.hee.debug.Debug")
|
||||
} catch (e: ClassNotFoundException) {}
|
||||
|
||||
@Suppress("ConvertLambdaToReference")
|
||||
DistExecutor.safeRunWhenOn(Side.CLIENT) {
|
||||
SafeRunnable { VanillaResourceOverrides.register() }
|
||||
@ -51,11 +53,6 @@ object Mod {
|
||||
ModCreativeTabs
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onClientSetup(@Suppress("UNUSED_PARAMETER") e: FMLClientSetupEvent) {
|
||||
Debug.initializeClient()
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onCommonSetup(@Suppress("UNUSED_PARAMETER") e: FMLCommonSetupEvent) {
|
||||
NetworkManager.initialize(ModPackets.ALL)
|
||||
|
@ -17,7 +17,6 @@ import chylex.hee.game.territory.TerritoryType
|
||||
import chylex.hee.game.territory.TerritoryVoid
|
||||
import chylex.hee.game.territory.system.properties.TerritoryEnvironment
|
||||
import chylex.hee.game.world.isInEndDimension
|
||||
import chylex.hee.system.Debug
|
||||
import chylex.hee.util.color.IntColor
|
||||
import chylex.hee.util.color.RGB
|
||||
import chylex.hee.util.forge.EventPriority
|
||||
@ -36,7 +35,6 @@ import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.util.math.vector.Vector3f
|
||||
import net.minecraftforge.client.event.EntityViewRenderEvent.RenderFogEvent
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
import net.minecraftforge.event.TickEvent.ClientTickEvent
|
||||
import net.minecraftforge.event.TickEvent.Phase
|
||||
import org.lwjgl.opengl.GL11.GL_GREATER
|
||||
@ -159,12 +157,6 @@ object TerritoryRenderer {
|
||||
|
||||
val voidFactor = LerpedFloat(TerritoryVoid.OUTSIDE_VOID_FACTOR)
|
||||
|
||||
init {
|
||||
if (Debug.enabled) {
|
||||
MinecraftForge.EVENT_BUS.register(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun tick(player: PlayerEntity) {
|
||||
val factor = TerritoryVoid.getVoidFactor(player).also(voidFactor::update)
|
||||
|
||||
@ -186,16 +178,6 @@ object TerritoryRenderer {
|
||||
fun reset() {
|
||||
voidFactor.updateImmediately(TerritoryVoid.OUTSIDE_VOID_FACTOR)
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
fun onRenderGameOverlayText(e: RenderGameOverlayEvent.Text) {
|
||||
if (MC.settings.showDebugInfo && MC.player?.isInEndDimension == true) {
|
||||
with(e.left) {
|
||||
add("")
|
||||
add("End Void Factor: ${"%.3f".format(voidFactor.currentValue)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text rendering
|
||||
|
@ -1,48 +1,27 @@
|
||||
package chylex.hee.game.block
|
||||
|
||||
import chylex.hee.HEE
|
||||
import chylex.hee.game.Environment
|
||||
import chylex.hee.game.block.properties.BlockBuilder
|
||||
import chylex.hee.game.block.properties.BlockModel
|
||||
import chylex.hee.game.block.properties.BlockRenderLayer.CUTOUT
|
||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||
import chylex.hee.game.world.generation.structure.file.StructureFile
|
||||
import chylex.hee.game.world.generation.util.WorldToStructureWorldAdapter
|
||||
import chylex.hee.game.world.util.getBlock
|
||||
import chylex.hee.game.world.util.offsetUntilExcept
|
||||
import chylex.hee.system.Debug
|
||||
import chylex.hee.util.forge.Side
|
||||
import chylex.hee.util.forge.Sided
|
||||
import chylex.hee.util.math.BoundingBox
|
||||
import chylex.hee.util.math.Pos
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.block.Blocks
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.nbt.CompressedStreamTools
|
||||
import net.minecraft.util.ActionResultType
|
||||
import net.minecraft.util.ActionResultType.FAIL
|
||||
import net.minecraft.util.ActionResultType.SUCCESS
|
||||
import net.minecraft.util.Direction
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.EAST
|
||||
import net.minecraft.util.Direction.NORTH
|
||||
import net.minecraft.util.Direction.SOUTH
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.Direction.WEST
|
||||
import net.minecraft.util.Hand
|
||||
import net.minecraft.util.Util
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.BlockRayTraceResult
|
||||
import net.minecraft.util.math.shapes.ISelectionContext
|
||||
import net.minecraft.util.math.shapes.VoxelShape
|
||||
import net.minecraft.util.math.shapes.VoxelShapes
|
||||
import net.minecraft.util.text.StringTextComponent
|
||||
import net.minecraft.util.text.TextFormatting
|
||||
import net.minecraft.world.IBlockReader
|
||||
import net.minecraft.world.World
|
||||
import java.nio.file.Files
|
||||
|
||||
class BlockScaffolding(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
var enableShape = true
|
||||
open class BlockScaffolding protected constructor(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
companion object {
|
||||
var enableShape = true
|
||||
|
||||
fun create(builder: BlockBuilder): HeeBlock {
|
||||
return HEE.debugModule?.createScaffoldingBlock(builder) ?: BlockScaffolding(builder)
|
||||
}
|
||||
}
|
||||
|
||||
override val model
|
||||
get() = BlockModel.Manual
|
||||
@ -50,73 +29,6 @@ class BlockScaffolding(builder: BlockBuilder) : HeeBlock(builder) {
|
||||
override val renderLayer
|
||||
get() = CUTOUT
|
||||
|
||||
override fun onBlockActivated(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hit: BlockRayTraceResult): ActionResultType {
|
||||
if (world.isRemote && player.isSneaking && !player.abilities.isFlying && Debug.enabled) {
|
||||
val palette = CommandClientScaffolding.currentPalette
|
||||
|
||||
if (palette == null) {
|
||||
player.sendMessage(StringTextComponent("No structure set."), Util.DUMMY_UUID)
|
||||
return FAIL
|
||||
}
|
||||
|
||||
val minPos = findMinPos(world, pos)?.let { findMinPos(world, it) } // double pass to find min from any side
|
||||
val maxPos = minPos?.let { findMaxPos(world, it) }
|
||||
|
||||
if (minPos == null || maxPos == null) {
|
||||
player.sendMessage(StringTextComponent("Could not find structure boundaries."), Util.DUMMY_UUID)
|
||||
return FAIL
|
||||
}
|
||||
|
||||
val box = BoundingBox(minPos, maxPos)
|
||||
val serverWorld = Environment.getDimension(world.dimensionKey)
|
||||
|
||||
val (structureTag, missingMappings) = StructureFile.save(WorldToStructureWorldAdapter(serverWorld, serverWorld.rand, box.min), box.size, palette, this)
|
||||
val structureFile = Files.createTempDirectory("HardcoreEnderExpansion_Structure_").resolve(CommandClientScaffolding.currentFile).toFile()
|
||||
|
||||
CompressedStreamTools.write(structureTag, structureFile)
|
||||
Debug.setClipboardContents(structureFile)
|
||||
|
||||
if (missingMappings.isNotEmpty()) {
|
||||
player.sendMessage(StringTextComponent("Missing mappings for states:"), Util.DUMMY_UUID)
|
||||
|
||||
for (missingMapping in missingMappings) {
|
||||
player.sendMessage(StringTextComponent(" - ${TextFormatting.GRAY}$missingMapping"), Util.DUMMY_UUID)
|
||||
}
|
||||
}
|
||||
|
||||
player.sendMessage(StringTextComponent("Generated structure file of ${box.size}."), Util.DUMMY_UUID)
|
||||
return SUCCESS
|
||||
}
|
||||
|
||||
return FAIL
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
private fun find(world: World, pos: BlockPos?, direction: Direction): BlockPos? {
|
||||
return pos?.offsetUntilExcept(direction, 0..255) { it.getBlock(world) === Blocks.AIR }
|
||||
}
|
||||
|
||||
private fun findMinPos(world: World, pos: BlockPos): BlockPos? {
|
||||
val bottomPos = find(world, pos, DOWN)
|
||||
|
||||
val y = bottomPos?.y
|
||||
val x = find(world, bottomPos, WEST)?.x
|
||||
val z = find(world, bottomPos, NORTH)?.z
|
||||
|
||||
return if (x == null || y == null || z == null) null else Pos(x, y, z)
|
||||
}
|
||||
|
||||
private fun findMaxPos(world: World, pos: BlockPos): BlockPos? {
|
||||
val topPos = find(world, pos, UP)
|
||||
|
||||
val y = topPos?.y
|
||||
val x = find(world, topPos, EAST)?.x
|
||||
val z = find(world, topPos, SOUTH)?.z
|
||||
|
||||
return if (x == null || y == null || z == null) null else Pos(x, y, z)
|
||||
}
|
||||
|
||||
// Visuals and physics
|
||||
|
||||
override fun getShape(state: BlockState, world: IBlockReader, pos: BlockPos, context: ISelectionContext): VoxelShape {
|
||||
|
@ -3,8 +3,6 @@ package chylex.hee.game.command
|
||||
import chylex.hee.HEE
|
||||
import chylex.hee.client.util.MC
|
||||
import chylex.hee.game.command.client.CommandClientHelp
|
||||
import chylex.hee.game.command.client.CommandClientScaffolding
|
||||
import chylex.hee.game.command.client.CommandDebugToggles
|
||||
import chylex.hee.init.ModCommands
|
||||
import chylex.hee.util.forge.EventPriority
|
||||
import chylex.hee.util.forge.Side
|
||||
@ -14,11 +12,15 @@ import net.minecraftforge.client.event.ClientChatEvent
|
||||
|
||||
@SubscribeAllEvents(Side.CLIENT, modid = HEE.ID)
|
||||
object ClientCommandHandler { // UPDATE
|
||||
val nonHelpCommands = listOf(
|
||||
CommandClientHelp,
|
||||
CommandClientScaffolding,
|
||||
CommandDebugToggles
|
||||
).associateBy { it.name }
|
||||
private val client
|
||||
get() = listOf(
|
||||
CommandClientHelp
|
||||
)
|
||||
|
||||
private val debug
|
||||
get() = HEE.debugModule?.clientCommands.orEmpty()
|
||||
|
||||
val all = (client + debug).associateBy { it.name }
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
fun onClientChat(e: ClientChatEvent) {
|
||||
@ -34,7 +36,7 @@ object ClientCommandHandler { // UPDATE
|
||||
val command = when {
|
||||
arguments.isEmpty() -> CommandClientHelp
|
||||
arguments[0] == CommandClientHelp.name -> CommandClientHelp.takeIf { arguments.size < 2 || arguments[1] == "1" } ?: return
|
||||
else -> nonHelpCommands[arguments[0]] ?: return
|
||||
else -> all[arguments[0]] ?: return
|
||||
}
|
||||
|
||||
command.executeCommand(source, arguments.drop(1).toTypedArray())
|
||||
|
@ -10,6 +10,6 @@ object CommandClientHelp : IClientCommand {
|
||||
override val description = CommandServerHelp.description
|
||||
|
||||
override fun executeCommand(sender: CommandSource, args: Array<String>) {
|
||||
CommandServerHelp.sendCommandListPage(sender, ClientCommandHandler.nonHelpCommands.keys, emptyMap(), "commands.hee.help.header.client", 1, null)
|
||||
CommandServerHelp.sendCommandListPage(sender, ClientCommandHandler.all.keys, emptyMap(), "commands.hee.help.header.client", 1, null)
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ object ModBlocks {
|
||||
// Blocks: Utilities
|
||||
|
||||
@JvmField val ETERNAL_FIRE = BlockEternalFire(buildEternalFire) named "eternal_fire"
|
||||
@JvmField val SCAFFOLDING = BlockScaffolding(buildScaffolding) named "scaffolding"
|
||||
@JvmField val SCAFFOLDING = BlockScaffolding.create(buildScaffolding) named "scaffolding"
|
||||
|
||||
// Registry
|
||||
|
||||
|
@ -3,17 +3,12 @@ package chylex.hee.init
|
||||
import chylex.hee.HEE
|
||||
import chylex.hee.game.command.argument.EnumArgument
|
||||
import chylex.hee.game.command.argument.ValidatedStringArgument
|
||||
import chylex.hee.game.command.server.CommandDebugInstability
|
||||
import chylex.hee.game.command.server.CommandDebugStructure
|
||||
import chylex.hee.game.command.server.CommandDebugTerritory
|
||||
import chylex.hee.game.command.server.CommandDebugTestWorld
|
||||
import chylex.hee.game.command.server.CommandServerCausatum
|
||||
import chylex.hee.game.command.server.CommandServerHelp
|
||||
import chylex.hee.game.command.server.CommandServerInfusions
|
||||
import chylex.hee.game.command.server.CommandServerLootChest
|
||||
import chylex.hee.game.command.server.CommandServerPortalToken
|
||||
import chylex.hee.game.command.util.executes
|
||||
import chylex.hee.system.Debug
|
||||
import chylex.hee.util.forge.SubscribeAllEvents
|
||||
import chylex.hee.util.forge.SubscribeEvent
|
||||
import net.minecraft.command.Commands.literal
|
||||
@ -32,13 +27,7 @@ object ModCommands {
|
||||
CommandServerPortalToken
|
||||
)
|
||||
|
||||
val debug = if (Debug.enabled) listOf(
|
||||
CommandDebugInstability,
|
||||
CommandDebugStructure,
|
||||
CommandDebugTerritory,
|
||||
CommandDebugTestWorld
|
||||
)
|
||||
else emptyList()
|
||||
val debug = HEE.debugModule?.serverCommands.orEmpty()
|
||||
|
||||
init {
|
||||
ArgumentTypes.register("hee:enum", EnumArgument::class.java, EnumArgument.Serializer)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package chylex.hee.mixin;
|
||||
|
||||
import chylex.hee.HEE;
|
||||
import chylex.hee.client.util.MC;
|
||||
import chylex.hee.system.Debug;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Minecraft.WorldSelectionType;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
public abstract class HookUselessExperimentalWorldWarning { // UPDATE remove when https://github.com/MinecraftForge/MinecraftForge/pull/7275 is pulled
|
||||
@Inject(method = "deleteWorld", at = @At("HEAD"), cancellable = true)
|
||||
private void ignoreUselessWarning(final WorldSelectionType selectionType, final String worldName, final boolean customized, final Runnable runnable, final CallbackInfo ci) {
|
||||
if (Debug.enabled) {
|
||||
if (HEE.debug) {
|
||||
ci.cancel();
|
||||
MC.instance.enqueue(runnable);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package chylex.hee.network.client
|
||||
|
||||
import chylex.hee.HEE
|
||||
import chylex.hee.game.block.BlockDragonEggOverride
|
||||
import chylex.hee.game.block.BlockEnderGooPurified
|
||||
import chylex.hee.game.block.BlockPuzzleLogic
|
||||
@ -35,7 +36,6 @@ import chylex.hee.game.mechanics.table.TableParticleHandler
|
||||
import chylex.hee.game.potion.BanishmentEffect
|
||||
import chylex.hee.game.world.generation.feature.tombdungeon.piece.TombDungeonRoom_Tomb
|
||||
import chylex.hee.network.BaseClientPacket
|
||||
import chylex.hee.system.Debug
|
||||
import chylex.hee.util.forge.Side
|
||||
import chylex.hee.util.forge.Sided
|
||||
import io.netty.buffer.ByteBuf
|
||||
@ -114,7 +114,7 @@ class PacketClientFX<T : IFxData>() : BaseClientPacket() {
|
||||
val index = buffer.readByte().toInt()
|
||||
|
||||
if (index == -1) {
|
||||
if (Debug.enabled) {
|
||||
if (HEE.debug) {
|
||||
throw IndexOutOfBoundsException("could not find FX handler")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user