Closed pietro-lopes closed 1 year ago
Proof of concept, adding a sign when it generates an underground structure https://streamable.com/4rkbf8
const $Heightmap$Types = Java.loadClass("net.minecraft.world.level.levelgen.Heightmap$Types")
MoreJSEvents.structureAfterPlace((event) => {
let currChunkBB = event.chunkBoundingBox
let strucBB = event.structureBoundingBox
if (!currChunkBB.isInside(strucBB.center)) return
if (strucBB.maxY() > 64) return
let strucTitle = Utils.snakeCaseToTitleCase(event.id.path)
let groundY = event.worldGenLevel.getChunk(strucBB.center).getHeight($Heightmap$Types.WORLD_SURFACE_WG, strucBB.center.x, strucBB.center.z)
let signPos = strucBB.center.mutable().setY(groundY + 1)
let signBlockState = Blocks.OAK_SIGN.defaultBlockState()
let canSurvive = signBlockState.canSurvive(event.worldGenLevel, signPos)
if (!canSurvive) event.worldGenLevel.setBlock(signPos.below(), Blocks.SANDSTONE.defaultBlockState(), 2)
event.worldGenLevel.setBlock(signPos, signBlockState, 2)
/** @type {Internal.SignBlockEntity} */
let sign = event.worldGenLevel.getBlockEntity(signPos)
let nbt = sign.getUpdateTag()
nbt["front_text"].messages[1] = Text.darkGray("Structure Name").toJson().toString()
nbt["front_text"].messages[2] = Text.red(strucTitle).toJson().toString()
nbt["front_text"]["has_glowing_text"] = NBT.b(1)
sign.load(nbt)
event.server.tell(Text.of("Generated underground structure: ").append(Text.green(strucTitle).clickRunCommand(`/tp @s ${sign.blockPos.x} ${sign.blockPos.y+2} ${sign.blockPos.z}`).hover(Text.of("Click to teleport"))))
})
StreamableWatch "Proof of concept, MoreJS - Structures AfterPlace event" on Streamable.
I can't add the beforePlace because I coudn't solve some issues like: if I injected as soon as it validates the structure and run a script that is very aggressive on cancelling (like all strongholds) and if you try to /locate that you would end up with your server hanged (no error, just hangs trying to find structure forever) If I injected too late, you will have ghost locations on /locate, that it says there is a structure there, but actually it doesnt.
Couldn't find a middle term so I gave up, already spent too much time on that and I'm having trouble trying to debug because it says source code doesn't match bytecode for most of it...
With that said, the afterPlace is working great.
This submission has been automatically marked as abandoned because it has not had recent activity. It will be closed in 3 days. If you want to prevent that, leave a new comment.
This submission has been automatically marked as abandoned because it has not had recent activity. It will be closed in 3 days. If you want to prevent that, leave a new comment.
shoo
I can't add the beforePlace because I coudn't solve some issues like: if I injected as soon as it validates the structure and run a script that is very aggressive on cancelling (like all strongholds) and if you try to /locate that you would end up with your server hanged (no error, just hangs trying to find structure forever) If I injected too late, you will have ghost locations on /locate, that it says there is a structure there, but actually it doesnt.
Couldn't find a middle term so I gave up, already spent too much time on that and I'm having trouble trying to debug because it says source code doesn't match bytecode for most of it...
With that said, the afterPlace is working great.
Yeah we will just skip beforePlace then.
But I also see that there are potential cases where people can lock their world in after place too as the structure generation happens on different threads.
But other than this, lgtm
Proposed Changes
My use case was that I needed to place a feature for each chunk that a structure was generated. Tested single player and multiplayer, it is working fine (didn't test fabric multiplayer tho)
Here are a few methods and usage:
You can directly reach me at KubeJS Discord, I'm very active there, Uncandango.