From 9ffc23a0cef4fbf9bd311d5a90f96f645885e439 Mon Sep 17 00:00:00 2001 From: StewStrong Date: Sat, 21 Dec 2024 17:17:42 -0800 Subject: [PATCH 1/9] FAST PHYSICS --- forge/build.gradle | 4 ++-- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/forge/build.gradle b/forge/build.gradle index f108a0c17..e6d657c67 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -115,11 +115,11 @@ dependencies { transitive = false } - forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api_krunch:1.0.0+7db6a103f1") { + forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api_krunch:1.0.0+1dcdf4060f") { transitive = false } - forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api:1.0.0+0ba0cc41e1") { + forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api:1.0.0+0c82dd6264") { transitive = false } diff --git a/gradle.properties b/gradle.properties index df6bc0a76..d171543ad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ forge_version=1.18.2-40.2.4 create_fabric_version=0.5.1-i-build.1598+mc1.18.2 flywheel_version_fabric=0.6.9-38 createbigcannons_version= 0.5.2-nightly-e815ca4 -vs_core_version=1.1.0+e213cc9916 +vs_core_version=1.1.0+9a16ff656c # Prevent kotlin from autoincluding stdlib as a dependency, which breaks # gradle's composite builds (includeBuild) for some reason. We'll add it manually kotlin.stdlib.default.dependency=false From 181b1fbe6d23bd2fae0859f76f28207b99c485bd Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Sat, 21 Dec 2024 21:22:41 -0500 Subject: [PATCH 2/9] hotfix assembly to use dense set --- .../mod/common/assembly/ShipAssembler.kt | 30 ++++++++++--------- .../mod/common/assembly/ShipAssembly.kt | 6 +--- .../mod/common/util/SplitHandler.kt | 11 +++---- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt index dade67e14..6e045bd0d 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt @@ -11,11 +11,13 @@ import org.valkyrienskies.core.api.ships.ServerShip import org.valkyrienskies.core.api.ships.Ship import org.valkyrienskies.core.api.ships.getAttachment import org.valkyrienskies.core.impl.game.ShipTeleportDataImpl +import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.mod.common.BlockStateInfo.onSetBlock import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipObjectManagingPos import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.util.SplittingDisablerAttachment +import org.valkyrienskies.mod.common.util.toBlockPos object ShipAssembler { @@ -32,14 +34,14 @@ object ShipAssembler { } - fun assembleToShip(level: Level, blocks: List, removeOriginal: Boolean, scale: Double = 1.0, shouldDisableSplitting: Boolean = false): ServerShip { + fun assembleToShip(level: Level, blocks: DenseBlockPosSet, removeOriginal: Boolean, scale: Double = 1.0, shouldDisableSplitting: Boolean = false): ServerShip { assert(level is ServerLevel) { "Can't create ships clientside!" } val sLevel: ServerLevel = level as ServerLevel if (blocks.isEmpty()) { throw IllegalArgumentException("No blocks to assemble.") } - val existingShip = sLevel.getShipObjectManagingPos(blocks.find { !sLevel.getBlockState(it).isAir } ?: throw IllegalArgumentException()) + val existingShip = sLevel.getShipObjectManagingPos(blocks.find { !sLevel.getBlockState(it.toBlockPos()).isAir }?.toBlockPos() ?: throw IllegalArgumentException()) var existingShipCouldSplit = true var structureCornerMin: BlockPos? = null @@ -48,13 +50,13 @@ object ShipAssembler { // Calculate bounds of the area containing all blocks adn check for solids and invalid blocks for (itPos in blocks) { - if (isValidShipBlock(level.getBlockState(itPos))) { + if (isValidShipBlock(level.getBlockState(itPos.toBlockPos()))) { if (structureCornerMin == null) { - structureCornerMin = itPos - structureCornerMax = itPos + structureCornerMin = itPos.toBlockPos() + structureCornerMax = itPos.toBlockPos() } else { - structureCornerMin = AssemblyUtil.getMinCorner(structureCornerMin!!, itPos) - structureCornerMax = AssemblyUtil.getMaxCorner(structureCornerMax!!, itPos) + structureCornerMin = AssemblyUtil.getMinCorner(structureCornerMin!!, itPos.toBlockPos()) + structureCornerMax = AssemblyUtil.getMaxCorner(structureCornerMax!!, itPos.toBlockPos()) } hasSolids = true } @@ -87,10 +89,10 @@ object ShipAssembler { // Copy blocks and check if the center block got replaced (is default a stone block) var centerBlockReplaced = false for (itPos in blocks) { - if (isValidShipBlock(level.getBlockState(itPos))) { - val relative: BlockPos = itPos.subtract( BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) + if (isValidShipBlock(level.getBlockState(itPos.toBlockPos()))) { + val relative: BlockPos = itPos.toBlockPos().subtract( BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) val shipPos: BlockPos = shipBlockPos.offset(relative) - AssemblyUtil.copyBlock(level, itPos, shipPos) + AssemblyUtil.copyBlock(level, itPos.toBlockPos(), shipPos) if (relative.equals(BlockPos.ZERO)) centerBlockReplaced = true } } @@ -98,17 +100,17 @@ object ShipAssembler { // Remove original blocks if (removeOriginal) { for (itPos in blocks) { - if (isValidShipBlock(level.getBlockState(itPos))) { - AssemblyUtil.removeBlock(level, itPos) + if (isValidShipBlock(level.getBlockState(itPos.toBlockPos()))) { + AssemblyUtil.removeBlock(level, itPos.toBlockPos()) } } } // Trigger updates on both ships for (itPos in blocks) { - val relative: BlockPos = itPos.subtract(BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) + val relative: BlockPos = itPos.toBlockPos().subtract(BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) val shipPos: BlockPos = shipBlockPos.offset(relative) - AssemblyUtil.updateBlock(level,itPos,shipPos,level.getBlockState(shipPos)) + AssemblyUtil.updateBlock(level,itPos.toBlockPos(),shipPos,level.getBlockState(shipPos)) } val shipCenterPos = ((newShip as ServerShip).inertiaData.centerOfMassInShip).add(0.5, 0.5, 0.5, Vector3d()) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt index e297942fc..5fe9b1156 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt @@ -11,9 +11,5 @@ fun createNewShipWithBlocks( centerBlock: BlockPos, blocks: DenseBlockPosSet, level: ServerLevel ): ServerShip { if (blocks.isEmpty()) throw IllegalArgumentException() - - val blockList: MutableList = mutableListOf() - - blocks.toList().forEach { blockList.add(it.toBlockPos()) } - return ShipAssembler.assembleToShip(level, blockList, true, 1.0) + return ShipAssembler.assembleToShip(level, blocks, true, 1.0) } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt index db2620064..e8a251b57 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt @@ -9,6 +9,7 @@ import org.joml.primitives.AABBi import org.valkyrienskies.core.api.ships.getAttachment import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.CONNECTED import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.DISCONNECTED +import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.core.util.expand import org.valkyrienskies.mod.common.assembly.ShipAssembler import org.valkyrienskies.mod.common.dimensionId @@ -97,17 +98,17 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) //begin the DFSing - val toAssemble = HashSet>() + val toAssemble = HashSet() for (starter in disconnected) { - val visited = HashSet() + val visited = DenseBlockPosSet() val queuedPositions = HashSet() queuedPositions.add(starter) while (queuedPositions.isNotEmpty()) { val current = queuedPositions.first() queuedPositions.remove(current) - visited.add(current) + visited.add(current.toJOML()) val toCheck = HashSet() for (offset in getOffsets(doEdges, doCorners)) { toCheck.add( @@ -115,13 +116,13 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) ) } for (check in toCheck) { - if (!visited.contains(check) && !level.getBlockState(check).isAir) { + if (!visited.contains(check.toJOML()) && !level.getBlockState(check).isAir) { queuedPositions.add(check) } } } //if we have visited all blocks in the component, we can split it - toAssemble.add(visited.toList()) + toAssemble.add(visited) } if (toAssemble.isEmpty()) { From 93cc755c6325585ddf3fd90cfd414e8293474ecc Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Sun, 22 Dec 2024 02:06:10 -0500 Subject: [PATCH 3/9] assembly via structure block --- .../mod/common/assembly/ShipAssembler.kt | 30 ++-- .../mod/common/assembly/ShipAssembly.kt | 144 +++++++++++++++++- .../mod/common/item/AreaAssemblerItem.kt | 27 ++-- .../mod/common/util/SplitHandler.kt | 5 +- gradle.properties | 2 +- 5 files changed, 174 insertions(+), 34 deletions(-) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt index 6e045bd0d..dade67e14 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt @@ -11,13 +11,11 @@ import org.valkyrienskies.core.api.ships.ServerShip import org.valkyrienskies.core.api.ships.Ship import org.valkyrienskies.core.api.ships.getAttachment import org.valkyrienskies.core.impl.game.ShipTeleportDataImpl -import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.mod.common.BlockStateInfo.onSetBlock import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipObjectManagingPos import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.util.SplittingDisablerAttachment -import org.valkyrienskies.mod.common.util.toBlockPos object ShipAssembler { @@ -34,14 +32,14 @@ object ShipAssembler { } - fun assembleToShip(level: Level, blocks: DenseBlockPosSet, removeOriginal: Boolean, scale: Double = 1.0, shouldDisableSplitting: Boolean = false): ServerShip { + fun assembleToShip(level: Level, blocks: List, removeOriginal: Boolean, scale: Double = 1.0, shouldDisableSplitting: Boolean = false): ServerShip { assert(level is ServerLevel) { "Can't create ships clientside!" } val sLevel: ServerLevel = level as ServerLevel if (blocks.isEmpty()) { throw IllegalArgumentException("No blocks to assemble.") } - val existingShip = sLevel.getShipObjectManagingPos(blocks.find { !sLevel.getBlockState(it.toBlockPos()).isAir }?.toBlockPos() ?: throw IllegalArgumentException()) + val existingShip = sLevel.getShipObjectManagingPos(blocks.find { !sLevel.getBlockState(it).isAir } ?: throw IllegalArgumentException()) var existingShipCouldSplit = true var structureCornerMin: BlockPos? = null @@ -50,13 +48,13 @@ object ShipAssembler { // Calculate bounds of the area containing all blocks adn check for solids and invalid blocks for (itPos in blocks) { - if (isValidShipBlock(level.getBlockState(itPos.toBlockPos()))) { + if (isValidShipBlock(level.getBlockState(itPos))) { if (structureCornerMin == null) { - structureCornerMin = itPos.toBlockPos() - structureCornerMax = itPos.toBlockPos() + structureCornerMin = itPos + structureCornerMax = itPos } else { - structureCornerMin = AssemblyUtil.getMinCorner(structureCornerMin!!, itPos.toBlockPos()) - structureCornerMax = AssemblyUtil.getMaxCorner(structureCornerMax!!, itPos.toBlockPos()) + structureCornerMin = AssemblyUtil.getMinCorner(structureCornerMin!!, itPos) + structureCornerMax = AssemblyUtil.getMaxCorner(structureCornerMax!!, itPos) } hasSolids = true } @@ -89,10 +87,10 @@ object ShipAssembler { // Copy blocks and check if the center block got replaced (is default a stone block) var centerBlockReplaced = false for (itPos in blocks) { - if (isValidShipBlock(level.getBlockState(itPos.toBlockPos()))) { - val relative: BlockPos = itPos.toBlockPos().subtract( BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) + if (isValidShipBlock(level.getBlockState(itPos))) { + val relative: BlockPos = itPos.subtract( BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) val shipPos: BlockPos = shipBlockPos.offset(relative) - AssemblyUtil.copyBlock(level, itPos.toBlockPos(), shipPos) + AssemblyUtil.copyBlock(level, itPos, shipPos) if (relative.equals(BlockPos.ZERO)) centerBlockReplaced = true } } @@ -100,17 +98,17 @@ object ShipAssembler { // Remove original blocks if (removeOriginal) { for (itPos in blocks) { - if (isValidShipBlock(level.getBlockState(itPos.toBlockPos()))) { - AssemblyUtil.removeBlock(level, itPos.toBlockPos()) + if (isValidShipBlock(level.getBlockState(itPos))) { + AssemblyUtil.removeBlock(level, itPos) } } } // Trigger updates on both ships for (itPos in blocks) { - val relative: BlockPos = itPos.toBlockPos().subtract(BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) + val relative: BlockPos = itPos.subtract(BlockPos(shipOGPos.x(),shipOGPos.y(),shipOGPos.z())) val shipPos: BlockPos = shipBlockPos.offset(relative) - AssemblyUtil.updateBlock(level,itPos.toBlockPos(),shipPos,level.getBlockState(shipPos)) + AssemblyUtil.updateBlock(level,itPos,shipPos,level.getBlockState(shipPos)) } val shipCenterPos = ((newShip as ServerShip).inertiaData.centerOfMassInShip).add(0.5, 0.5, 0.5, Vector3d()) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt index 5fe9b1156..ccc3d182c 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt @@ -2,14 +2,154 @@ package org.valkyrienskies.mod.common.assembly import net.minecraft.core.BlockPos import net.minecraft.server.level.ServerLevel +import net.minecraft.world.Clearable +import net.minecraft.world.level.ChunkPos +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.levelgen.structure.templatesystem.StructurePlaceSettings +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate +import org.joml.Vector3d import org.valkyrienskies.core.api.ships.ServerShip +import org.valkyrienskies.core.apigame.ShipTeleportData +import org.valkyrienskies.core.impl.game.ShipTeleportDataImpl +import org.valkyrienskies.core.impl.game.ships.ShipData +import org.valkyrienskies.core.impl.game.ships.ShipTransformImpl import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet -import org.valkyrienskies.mod.common.util.toBlockPos +import org.valkyrienskies.mod.common.dimensionId +import org.valkyrienskies.mod.common.executeIf +import org.valkyrienskies.mod.common.isTickingChunk +import org.valkyrienskies.mod.common.shipObjectWorld +import org.valkyrienskies.mod.common.util.toJOML +import org.valkyrienskies.mod.common.util.toJOMLD +import org.valkyrienskies.mod.common.util.toMinecraft +import org.valkyrienskies.mod.util.relocateBlock +import org.valkyrienskies.mod.util.updateBlock @Deprecated("Use [ShipAssembler.assembleToShip] instead") fun createNewShipWithBlocks( centerBlock: BlockPos, blocks: DenseBlockPosSet, level: ServerLevel ): ServerShip { if (blocks.isEmpty()) throw IllegalArgumentException() - return ShipAssembler.assembleToShip(level, blocks, true, 1.0) + //return ShipAssembler.assembleToShip(level, blocks, true, 1.0) + + + val ship = level.shipObjectWorld.createNewShipAtBlock(centerBlock.toJOML(), false, 1.0, level.dimensionId) + val shipChunkX = ship.chunkClaim.xMiddle + val shipChunkZ = ship.chunkClaim.zMiddle + val worldChunkX = centerBlock.x shr 4 + val worldChunkZ = centerBlock.z shr 4 + val deltaX = worldChunkX - shipChunkX + val deltaZ = worldChunkZ - shipChunkZ + val chunksToBeUpdated = mutableMapOf>() + blocks.forEachChunk { x, _, z, _ -> + val sourcePos = ChunkPos(x, z) + val destPos = ChunkPos(x - deltaX, z - deltaZ) + chunksToBeUpdated[sourcePos] = Pair(sourcePos, destPos) + } + val chunkPairs = chunksToBeUpdated.values.toList() + val chunkPoses = chunkPairs.flatMap { it.toList() } + val chunkPosesJOML = chunkPoses.map { it.toJOML() } + // Send a list of all the chunks that we plan on updating to players, so that they + // defer all updates until assembly is finished + // with(vsCore.simplePacketNetworking) { + // PacketStopChunkUpdates(chunkPosesJOML).sendToAllClients() + // } + // Use relocateBlock to copy all the blocks into the ship + blocks.forEachChunk { chunkX, chunkY, chunkZ, chunk -> + val sourceChunk = level.getChunk(chunkX, chunkZ) + val destChunk = level.getChunk(chunkX - deltaX, chunkZ - deltaZ) + chunk.forEach { x, y, z -> + val fromPos = BlockPos((sourceChunk.pos.x shl 4) + x, (chunkY shl 4) + y, (sourceChunk.pos.z shl 4) + z) + val toPos = BlockPos((destChunk.pos.x shl 4) + x, (chunkY shl 4) + y, (destChunk.pos.z shl 4) + z) + relocateBlock(sourceChunk, fromPos, destChunk, toPos, false, ship) + } + } + // Use updateBlock to update blocks after copying + blocks.forEachChunk { chunkX, chunkY, chunkZ, chunk -> + val sourceChunk = level.getChunk(chunkX, chunkZ) + val destChunk = level.getChunk(chunkX - deltaX, chunkZ - deltaZ) + chunk.forEach { x, y, z -> + val fromPos = BlockPos((sourceChunk.pos.x shl 4) + x, (chunkY shl 4) + y, (sourceChunk.pos.z shl 4) + z) + val toPos = BlockPos((destChunk.pos.x shl 4) + x, (chunkY shl 4) + y, (destChunk.pos.z shl 4) + z) + updateBlock(destChunk.level, fromPos, toPos, destChunk.getBlockState(toPos)) + } + } + // Calculate the position of the block that the player clicked after it has been assembled + val centerInShip = Vector3d( + ((shipChunkX shl 4) + (centerBlock.x and 15)).toDouble(), + centerBlock.y.toDouble(), + ((shipChunkZ shl 4) + (centerBlock.z and 15)).toDouble() + ) + // The ship's position has shifted from the center block since we assembled the ship, compensate for that + val centerBlockPosInWorld = ship.inertiaData.centerOfMassInShip.sub(centerInShip, Vector3d()) + .add(ship.transform.positionInWorld) + // Put the ship into the compensated position, so that all the assembled blocks stay in the same place + // TODO: AAAAAAAAA THIS IS HORRIBLE how can the API support this? + (ship as ShipData).transform = (ship.transform as ShipTransformImpl).copy(positionInWorld = centerBlockPosInWorld) + level.server.executeIf( + // This condition will return true if all modified chunks have been both loaded AND + // chunk update packets were sent to players + { chunkPoses.all(level::isTickingChunk) } + ) { + // Once all the chunk updates are sent to players, we can tell them to restart chunk updates + // with(vsCore.simplePacketNetworking) { + // PacketRestartChunkUpdates(chunkPosesJOML).sendToAllClients() + // } + } + + return ship +} + +fun createNewShipWithStructure( + lowerCorner: BlockPos, higherCorner: BlockPos, blocks: StructureTemplate, level: ServerLevel +): ServerShip { + //if (blocks.size.toJOML().length() < 0.0001) throw IllegalArgumentException() + + val ship = level.shipObjectWorld.createNewShipAtBlock(lowerCorner.toJOML(), false, 1.0, level.dimensionId) + val shipChunkX = ship.chunkClaim.xMiddle + val shipChunkZ = ship.chunkClaim.zMiddle + + // Calculate the position of the block that the player clicked after it has been assembled + val lowerCornerInShip = Vector3d( + ((shipChunkX shl 4) + (lowerCorner.x and 15)).toDouble(), + lowerCorner.y.toDouble(), + ((shipChunkZ shl 4) + (lowerCorner.z and 15)).toDouble() + ) + val higherCornerInShip = Vector3d( + ((shipChunkX shl 4) + (higherCorner.x and 15)).toDouble(), + higherCorner.y.toDouble(), + ((shipChunkZ shl 4) + (higherCorner.z and 15)).toDouble() + ) + + blocks.placeInWorld(level, BlockPos(lowerCornerInShip.toMinecraft()), BlockPos(lowerCornerInShip.toMinecraft()), StructurePlaceSettings(), level.random, Block.UPDATE_ALL) + + val diff = higherCorner.subtract(lowerCorner) + val centerPos = lowerCorner.offset(diff.x / 2, diff.y / 2, diff.z / 2) + + // The ship's position has shifted from the center block since we assembled the ship, compensate for that + val centerBlockPosInWorld = ship.inertiaData.centerOfMassInShip.sub(lowerCornerInShip, Vector3d()) + .add(ship.transform.positionInWorld) + // Put the ship into the compensated position, so that all the assembled blocks stay in the same place + // TODO: AAAAAAAAA THIS IS HORRIBLE how can the API support this? + //(ship as ShipData).transform = (ship.transform as ShipTransformImpl).copy(positionInWorld = centerBlockPosInWorld) + level.shipObjectWorld + .teleportShip(ship, ShipTeleportDataImpl(newPos = centerBlockPosInWorld.add(0.0, (128.0 - lowerCorner.y.toDouble() + 0.5), 0.0, Vector3d()), newPosInShip = ship.inertiaData.centerOfMassInShip)) + + + for (x in lowerCorner.x..higherCorner.x) { + for (y in lowerCorner.y..higherCorner.y) { + for (z in lowerCorner.z..higherCorner.z) { + if (!level.getBlockState(BlockPos(x, y, z)).isAir) { + val blockEntity: BlockEntity? = level.getBlockEntity(BlockPos(x, y, z)) + Clearable.tryClear(blockEntity) + level.removeBlockEntity(BlockPos(x, y, z)) + level.setBlock(BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS) + + //level.getChunk(BlockPos(x, y, z)).setBlockState(BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false) + } + } + } + } + return ship } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/AreaAssemblerItem.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/AreaAssemblerItem.kt index cad9346d5..7d5ab48fb 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/AreaAssemblerItem.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/AreaAssemblerItem.kt @@ -3,17 +3,23 @@ package org.valkyrienskies.mod.common.item import net.minecraft.Util import net.minecraft.core.BlockPos import net.minecraft.core.Vec3i +import net.minecraft.gametest.framework.StructureUtils import net.minecraft.network.chat.TextComponent import net.minecraft.server.level.ServerLevel import net.minecraft.world.InteractionResult import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.context.UseOnContext +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.level.levelgen.structure.templatesystem.StructureTemplate import org.joml.primitives.AABBi +import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.mod.common.assembly.ShipAssembler +import org.valkyrienskies.mod.common.assembly.createNewShipWithBlocks +import org.valkyrienskies.mod.common.assembly.createNewShipWithStructure import org.valkyrienskies.mod.common.dimensionId -import org.valkyrienskies.mod.common.getShipManagingPos import org.valkyrienskies.mod.common.getShipObjectManagingPos import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.util.toJOML @@ -53,20 +59,15 @@ class AreaAssemblerItem( } else { val blockAABB = AABBi(blockPos.toJOML(), Vec3i(firstPosX, firstPosY, firstPosZ).toJOML()) blockAABB.correctBounds() - val blocks = ArrayList() + val lowerCorner = BlockPos(blockAABB.minX, blockAABB.minY, blockAABB.minZ) + val upperCorner = BlockPos(blockAABB.maxX, blockAABB.maxY, blockAABB.maxZ) + + val structure = StructureTemplate() + structure.fillFromWorld(level, lowerCorner, upperCorner.offset(1, 1, 1).subtract(lowerCorner), true, Blocks.STRUCTURE_VOID) - for (x in blockAABB.minX..blockAABB.maxX) { - for (y in blockAABB.minY..blockAABB.maxY) { - for (z in blockAABB.minZ..blockAABB.maxZ) { - if (level.getBlockState(BlockPos(x, y, z)).isAir) { - continue - } - blocks.add(BlockPos(x, y, z)) - } - } - } ctx.player?.sendMessage(TextComponent("Assembling (${blockPos.x}, ${blockPos.y}, ${blockPos.z}) to ($firstPosX, $firstPosY, $firstPosZ)!"), Util.NIL_UUID) - ShipAssembler.assembleToShip(level, blocks, true, scale.asDouble, true) + //ShipAssembler.assembleToShip(level, blocks, true, scale.asDouble, true) + createNewShipWithStructure(lowerCorner, upperCorner, structure, level) } item.tag!!.remove("firstPosX") item.tag!!.remove("firstPosY") diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt index e8a251b57..9520a16b1 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt @@ -11,7 +11,7 @@ import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.CONNECTED import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.DISCONNECTED import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.core.util.expand -import org.valkyrienskies.mod.common.assembly.ShipAssembler +import org.valkyrienskies.mod.common.assembly.createNewShipWithBlocks import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipObjectManagingPos import org.valkyrienskies.mod.common.shipObjectWorld @@ -131,7 +131,8 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) } for (component in toAssemble) { - ShipAssembler.assembleToShip(level, component, true, 1.0, true) + //ShipAssembler.assembleToShip(level, component, true, 1.0, true) + createNewShipWithBlocks(component.first().toBlockPos(), component, level) } loadedShip.getAttachment(SplittingDisablerAttachment::class.java)?.enableSplitting() diff --git a/gradle.properties b/gradle.properties index d171543ad..2410644ff 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=1G +org.gradle.jvmargs=-Xmx20G -XX:MaxMetaspaceSize=1G minecraft_version=1.18.2 enabled_platforms=quilt,fabric,forge archives_base_name=valkyrienskies-118 From 58c6bfb72d185c3f0ee886edcabf1903ce7e0acb Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Fri, 27 Dec 2024 00:14:00 -0500 Subject: [PATCH 4/9] Joints! --- ...oundSectionBlocksUpdatePacketAccessor.java | 1 + .../MixinDebugRenderer.java | 24 +++++++++++ .../MixinBlockUpdatePacket.java | 4 ++ .../MixinSectionBlocksUpdatePacket.java | 11 +++++ .../mixinducks/world/WithSealedPositions.java | 9 ++++ .../mod/client/SparseVoxelRenderer.kt | 41 +++++++++++++++++++ .../mod/common/assembly/ShipAssembly.kt | 6 +-- .../mod/common/block/TestHingeBlock.kt | 35 ++++++++-------- .../blockentity/TestHingeBlockEntity.kt | 4 +- .../mod/common/item/ConnectionCheckerItem.kt | 9 +++- .../common/item/PhysicsEntityCreatorItem.kt | 38 ++++++++--------- .../mod/common/util/SplitHandler.kt | 18 +++++--- .../valkyrienskies-common.mixins.json | 8 ++-- gradle.properties | 4 +- 14 files changed, 157 insertions(+), 55 deletions(-) create mode 100644 common/src/main/java/org/valkyrienskies/mod/mixin/feature/debug_sparse_voxel_rendering/MixinDebugRenderer.java create mode 100644 common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinBlockUpdatePacket.java create mode 100644 common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinSectionBlocksUpdatePacket.java create mode 100644 common/src/main/java/org/valkyrienskies/mod/mixinducks/world/WithSealedPositions.java create mode 100644 common/src/main/kotlin/org/valkyrienskies/mod/client/SparseVoxelRenderer.kt diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java b/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java index 39a16b43c..52a8180fa 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java @@ -3,6 +3,7 @@ import net.minecraft.core.SectionPos; import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(ClientboundSectionBlocksUpdatePacket.class) diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/debug_sparse_voxel_rendering/MixinDebugRenderer.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/debug_sparse_voxel_rendering/MixinDebugRenderer.java new file mode 100644 index 000000000..ea5f5b0ed --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/debug_sparse_voxel_rendering/MixinDebugRenderer.java @@ -0,0 +1,24 @@ +package org.valkyrienskies.mod.mixin.feature.debug_sparse_voxel_rendering; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.debug.DebugRenderer; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.valkyrienskies.mod.client.SparseVoxelRenderer; + +@Mixin(DebugRenderer.class) +public class MixinDebugRenderer { + @Unique + @Final + SparseVoxelRenderer sparseVoxelRenderer = new SparseVoxelRenderer(); + + @Inject(method = "render", at = @At("HEAD")) + void render(PoseStack poseStack, MultiBufferSource.BufferSource bufferSource, double d, double e, double f, final CallbackInfo ci) { + //sparseVoxelRenderer.render(poseStack, bufferSource, d, e, f); + } +} diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinBlockUpdatePacket.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinBlockUpdatePacket.java new file mode 100644 index 000000000..f38515020 --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinBlockUpdatePacket.java @@ -0,0 +1,4 @@ +package org.valkyrienskies.mod.mixin.feature.sealed_air_sync; + +public class MixinBlockUpdatePacket { +} diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinSectionBlocksUpdatePacket.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinSectionBlocksUpdatePacket.java new file mode 100644 index 000000000..956fc626a --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sealed_air_sync/MixinSectionBlocksUpdatePacket.java @@ -0,0 +1,11 @@ +package org.valkyrienskies.mod.mixin.feature.sealed_air_sync; + +import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(ClientboundSectionBlocksUpdatePacket.class) +public class MixinSectionBlocksUpdatePacket { + @Unique + private boolean[] sealed; +} diff --git a/common/src/main/java/org/valkyrienskies/mod/mixinducks/world/WithSealedPositions.java b/common/src/main/java/org/valkyrienskies/mod/mixinducks/world/WithSealedPositions.java new file mode 100644 index 000000000..6e835c004 --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixinducks/world/WithSealedPositions.java @@ -0,0 +1,9 @@ +package org.valkyrienskies.mod.mixinducks.world; + +import net.minecraft.core.BlockPos; + +public interface WithSealedPositions { + public void setSealed(BlockPos pos, boolean sealed); + + public boolean[] getSealed(); +} diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/client/SparseVoxelRenderer.kt b/common/src/main/kotlin/org/valkyrienskies/mod/client/SparseVoxelRenderer.kt new file mode 100644 index 000000000..f975f8d35 --- /dev/null +++ b/common/src/main/kotlin/org/valkyrienskies/mod/client/SparseVoxelRenderer.kt @@ -0,0 +1,41 @@ +package org.valkyrienskies.mod.client + +import com.mojang.blaze3d.vertex.PoseStack +import com.mojang.blaze3d.vertex.Tesselator +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.MultiBufferSource.BufferSource +import net.minecraft.client.renderer.RenderType +import net.minecraft.client.renderer.debug.DebugRenderer +import net.minecraft.world.phys.AABB +import org.valkyrienskies.core.util.datastructures.SparseVoxelPosition + +class SparseVoxelRenderer() { + val voxels = HashSet() + + init { + voxels.add(SparseVoxelPosition(0, 128, 0, 2)) + } + + fun render(ms: PoseStack, buffer: BufferSource, camX: Double, camY: Double, camZ: Double) { + for (voxel in voxels) { + drawVoxel(voxel, ms, buffer, camX, camY, camZ) + } + } + + fun drawVoxel(voxel: SparseVoxelPosition, poseStack: PoseStack, buffer: BufferSource, camX: Double, camY: Double, camZ: Double) { + poseStack.pushPose() + + // Draw the voxel + val random = Minecraft.getInstance().level?.random ?: return + DebugRenderer.renderFilledBox(voxel.toAABB(-camX, -camY, -camZ), 1.0f, 1.0f, 0.5f, 0.5f) + //Tesselator.getInstance().end() + + poseStack.popPose() + } + + private fun SparseVoxelPosition.toAABB(offsetX: Double = 0.0, offsetY: Double = 0.0, offsetZ: Double = 0.0): AABB { + return AABB(x.toDouble() + offsetX, y.toDouble() + offsetY, z.toDouble() + offsetZ, + x.toDouble() + extent.toDouble() + offsetX, y.toDouble() + extent.toDouble() + offsetY, z.toDouble() + extent.toDouble() + offsetZ) + + } +} diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt index ccc3d182c..f1e985ad2 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt @@ -125,16 +125,16 @@ fun createNewShipWithStructure( blocks.placeInWorld(level, BlockPos(lowerCornerInShip.toMinecraft()), BlockPos(lowerCornerInShip.toMinecraft()), StructurePlaceSettings(), level.random, Block.UPDATE_ALL) val diff = higherCorner.subtract(lowerCorner) - val centerPos = lowerCorner.offset(diff.x / 2, diff.y / 2, diff.z / 2) + val centerPos = lowerCorner.toJOMLD().add(diff.x / 2.0, diff.y / 2.0, diff.z / 2.0) // The ship's position has shifted from the center block since we assembled the ship, compensate for that - val centerBlockPosInWorld = ship.inertiaData.centerOfMassInShip.sub(lowerCornerInShip, Vector3d()) + val centerBlockPosInWorld = ship.inertiaData.centerOfMassInShip.sub(centerPos, Vector3d()) .add(ship.transform.positionInWorld) // Put the ship into the compensated position, so that all the assembled blocks stay in the same place // TODO: AAAAAAAAA THIS IS HORRIBLE how can the API support this? //(ship as ShipData).transform = (ship.transform as ShipTransformImpl).copy(positionInWorld = centerBlockPosInWorld) level.shipObjectWorld - .teleportShip(ship, ShipTeleportDataImpl(newPos = centerBlockPosInWorld.add(0.0, (128.0 - lowerCorner.y.toDouble() + 0.5), 0.0, Vector3d()), newPosInShip = ship.inertiaData.centerOfMassInShip)) + .teleportShip(ship, ShipTeleportDataImpl(newPos = centerBlockPosInWorld.add(0.0, 0.0, 0.0, Vector3d()), newPosInShip = ship.inertiaData.centerOfMassInShip)) for (x in lowerCorner.x..higherCorner.x) { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt index b22a496ec..6be920674 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt @@ -33,8 +33,9 @@ import org.joml.Quaterniond import org.joml.Quaterniondc import org.joml.Vector3d import org.joml.Vector3dc -import org.valkyrienskies.core.apigame.constraints.VSAttachmentConstraint -import org.valkyrienskies.core.apigame.constraints.VSHingeOrientationConstraint +import org.valkyrienskies.core.apigame.joints.VSJointMaxForceTorque +import org.valkyrienskies.core.apigame.joints.VSJointPose +import org.valkyrienskies.core.apigame.joints.VSRevoluteJoint import org.valkyrienskies.core.impl.game.ships.ShipDataCommon import org.valkyrienskies.core.impl.game.ships.ShipTransformImpl import org.valkyrienskies.mod.common.ValkyrienSkiesMod @@ -200,18 +201,18 @@ object TestHingeBlock : val shipId1 = ship.id // Attachment constraint - run { - // I don't recommend setting compliance lower than 1e-10 because it tends to cause instability - // TODO: Investigate why small compliance cause instability - val attachmentCompliance = 1e-10 - val attachmentMaxForce = 1e10 - val attachmentFixedDistance = 0.0 - val attachmentConstraint = VSAttachmentConstraint( - shipId0, shipId1, attachmentCompliance, attachmentLocalPos0, attachmentLocalPos1, - attachmentMaxForce, attachmentFixedDistance - ) - blockEntity.get().constraintId = level.shipObjectWorld.createNewConstraint(attachmentConstraint) - } + // run { + // // I don't recommend setting compliance lower than 1e-10 because it tends to cause instability + // // TODO: Investigate why small compliance cause instability + // val attachmentCompliance = 1e-10 + // val attachmentMaxForce = 1e10 + // val attachmentFixedDistance = 0.0 + // val attachmentConstraint = VSRevoluteJoint( + // shipId0, shipId1, attachmentCompliance, attachmentLocalPos0, attachmentLocalPos1, + // attachmentMaxForce, attachmentFixedDistance + // ) + // blockEntity.get().constraintId = level.shipObjectWorld.createNewConstraint(attachmentConstraint) + // } // Hinge constraints will attempt to align the X-axes of both bodies, so to align the Y axis we // apply this rotation to the X-axis @@ -221,9 +222,11 @@ object TestHingeBlock : run { // I don't recommend setting compliance lower than 1e-10 because it tends to cause instability val hingeOrientationCompliance = 1e-10 + val attachmentMaxForce = 1e10 val hingeMaxTorque = 1e10 - val hingeConstraint = VSHingeOrientationConstraint( - shipId0, shipId1, hingeOrientationCompliance, hingeOrientation, hingeOrientation, hingeMaxTorque + val hingeConstraint = VSRevoluteJoint( + shipId0, VSJointPose(attachmentLocalPos0, hingeOrientation), shipId1, VSJointPose(attachmentLocalPos1, hingeOrientation), + VSJointMaxForceTorque(attachmentMaxForce.toFloat(), hingeMaxTorque.toFloat()) ) blockEntity.get().constraintId = level.shipObjectWorld.createNewConstraint(hingeConstraint) } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/blockentity/TestHingeBlockEntity.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/blockentity/TestHingeBlockEntity.kt index 19ba56f16..07bc7f6f3 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/blockentity/TestHingeBlockEntity.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/blockentity/TestHingeBlockEntity.kt @@ -3,14 +3,14 @@ package org.valkyrienskies.mod.common.blockentity import net.minecraft.core.BlockPos import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.state.BlockState -import org.valkyrienskies.core.apigame.constraints.VSConstraintId +import org.valkyrienskies.core.apigame.joints.VSJointId import org.valkyrienskies.mod.common.ValkyrienSkiesMod class TestHingeBlockEntity(blockPos: BlockPos, blockState: BlockState) : BlockEntity( ValkyrienSkiesMod.TEST_HINGE_BLOCK_ENTITY_TYPE, blockPos, blockState ) { var otherHingePos: BlockPos? = null - var constraintId: VSConstraintId? = null + var constraintId: VSJointId? = null fun tick() { // println("Amogus") diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ConnectionCheckerItem.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ConnectionCheckerItem.kt index 4c141aa5d..4d2adcccc 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ConnectionCheckerItem.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ConnectionCheckerItem.kt @@ -8,6 +8,8 @@ import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.context.UseOnContext import net.minecraft.world.level.block.state.BlockState +import org.valkyrienskies.core.impl.config_impl.VSCoreConfig +import org.valkyrienskies.mod.common.ValkyrienSkiesMod import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipManagingPos import org.valkyrienskies.mod.common.shipObjectWorld @@ -36,9 +38,11 @@ class ConnectionCheckerItem( if (!blockState.isAir) { // Make a ship val dimensionId = level.dimensionId - - if (parentShip != null) { + println("tested") + if (parentShip != null || ValkyrienSkiesMod.vsCore.hooks.enableWorldConnectivity) { + println("can we get much") if (item.tag != null && item.tag!!.contains("firstPosX")) { + println("so high") val firstPosX = item.tag!!.getInt("firstPosX") val firstPosY = item.tag!!.getInt("firstPosY") val firstPosZ = item.tag!!.getInt("firstPosZ") @@ -48,6 +52,7 @@ class ConnectionCheckerItem( item.tag!!.remove("firstPosY") item.tag!!.remove("firstPosZ") } else { + println("higher") item.tag = item.orCreateTag.apply { putInt("firstPosX", blockPos.x) putInt("firstPosY", blockPos.y) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/PhysicsEntityCreatorItem.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/PhysicsEntityCreatorItem.kt index d6f02bcc4..e7ea8cc06 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/PhysicsEntityCreatorItem.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/PhysicsEntityCreatorItem.kt @@ -8,10 +8,6 @@ import net.minecraft.world.item.context.UseOnContext import org.joml.Quaterniond import org.joml.Vector3d import org.joml.Vector3dc -import org.valkyrienskies.core.apigame.constraints.VSAttachmentConstraint -import org.valkyrienskies.core.apigame.constraints.VSPosDampingConstraint -import org.valkyrienskies.core.apigame.constraints.VSRotDampingAxes -import org.valkyrienskies.core.apigame.constraints.VSRotDampingConstraint import org.valkyrienskies.core.impl.game.ships.ShipTransformImpl.Companion import org.valkyrienskies.mod.common.ValkyrienSkiesMod import org.valkyrienskies.mod.common.dimensionId @@ -61,23 +57,23 @@ class PhysicsEntityCreatorItem( val attachCompliance = 1e-8 val attachMaxForce = 1e10 // Attach the click position of the ship to the surface of the physics entity - val attachConstraint = VSAttachmentConstraint( - shipOn.id, physicsEntityData.shipId, attachCompliance, ctx.clickLocation.toJOML(), offsetInGlobal.mul(-1.0, Vector3d()), - attachMaxForce, 0.0 - ) - val posDampingConstraint = VSPosDampingConstraint( - shipOn.id, physicsEntityData.shipId, attachCompliance, ctx.clickLocation.toJOML(), offsetInGlobal.mul(-1.0, Vector3d()), - attachMaxForce, 0.1 - ) - val rotDampingConstraint = VSRotDampingConstraint( - shipOn.id, physicsEntityData.shipId, attachCompliance, shipOn.transform.shipToWorldRotation.invert( - Quaterniond() - ), - Quaterniond(), 1e10, 0.1, VSRotDampingAxes.ALL_AXES - ) - level.shipObjectWorld.createNewConstraint(attachConstraint) - level.shipObjectWorld.createNewConstraint(posDampingConstraint) - level.shipObjectWorld.createNewConstraint(rotDampingConstraint) + // val attachConstraint = VSAttachmentConstraint( + // shipOn.id, physicsEntityData.shipId, attachCompliance, ctx.clickLocation.toJOML(), offsetInGlobal.mul(-1.0, Vector3d()), + // attachMaxForce, 0.0 + // ) + // val posDampingConstraint = VSPosDampingConstraint( + // shipOn.id, physicsEntityData.shipId, attachCompliance, ctx.clickLocation.toJOML(), offsetInGlobal.mul(-1.0, Vector3d()), + // attachMaxForce, 0.1 + // ) + // val rotDampingConstraint = VSRotDampingConstraint( + // shipOn.id, physicsEntityData.shipId, attachCompliance, shipOn.transform.shipToWorldRotation.invert( + // Quaterniond() + // ), + // Quaterniond(), 1e10, 0.1, VSRotDampingAxes.ALL_AXES + // ) + // level.shipObjectWorld.createNewConstraint(attachConstraint) + // level.shipObjectWorld.createNewConstraint(posDampingConstraint) + // level.shipObjectWorld.createNewConstraint(rotDampingConstraint) } } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt index 9520a16b1..6b4b22ea7 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt @@ -11,6 +11,7 @@ import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.CONNECTED import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.DISCONNECTED import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.core.util.expand +import org.valkyrienskies.mod.common.ValkyrienSkiesMod import org.valkyrienskies.mod.common.assembly.createNewShipWithBlocks import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipObjectManagingPos @@ -22,16 +23,16 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) fun split(level: Level, x: Int, y: Int, z: Int, prevBlockState: BlockState, newBlockState: BlockState) { if (level is ServerLevel) { val loadedShip = level.getShipObjectManagingPos(x shr 4, z shr 4) - if (loadedShip != null && loadedShip.getAttachment()?.canSplit() != false) { + if ((loadedShip != null && loadedShip.getAttachment()?.canSplit() != false)) { if (!prevBlockState.isAir && newBlockState.isAir) { val blockNeighbors: HashSet = HashSet() - val shipBox = loadedShip.shipAABB?.expand(1, AABBi()) ?: return + //val shipBox = loadedShip.shipAABB?.expand(1, AABBi()) ?: return for (neighborOffset in getOffsets(doEdges, doCorners)) { val neighborPos = BlockPos(x + neighborOffset.x, y + neighborOffset.y, z + neighborOffset.z) val neighborState = level.getBlockState(neighborPos) - if (!neighborState.isAir && neighborPos != BlockPos(x, y, z) && shipBox.containsPoint(neighborPos.toJOML())) { + if (!neighborState.isAir && neighborPos != BlockPos(x, y, z)) { blockNeighbors.add(neighborPos) } } @@ -85,6 +86,11 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) toIgnore.add(component) } } + if (level.shipObjectWorld.isIsolatedSolid(otherComponent.x, otherComponent.y, otherComponent.z, level.dimensionId) == CONNECTED) { + if (!toIgnore.contains(otherComponent) && !toIgnore.contains(component)) { + toIgnore.add(component) + } + } } } @@ -93,7 +99,7 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) if (disconnected.isEmpty()) { return } else { - loadedShip.getAttachment(SplittingDisablerAttachment::class.java)?.disableSplitting() + loadedShip?.getAttachment(SplittingDisablerAttachment::class.java)?.disableSplitting() } //begin the DFSing @@ -126,7 +132,7 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) } if (toAssemble.isEmpty()) { - loadedShip.getAttachment(SplittingDisablerAttachment::class.java)?.enableSplitting() + loadedShip?.getAttachment(SplittingDisablerAttachment::class.java)?.enableSplitting() return } @@ -135,7 +141,7 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) createNewShipWithBlocks(component.first().toBlockPos(), component, level) } - loadedShip.getAttachment(SplittingDisablerAttachment::class.java)?.enableSplitting() + loadedShip?.getAttachment(SplittingDisablerAttachment::class.java)?.enableSplitting() } } } diff --git a/common/src/main/resources/valkyrienskies-common.mixins.json b/common/src/main/resources/valkyrienskies-common.mixins.json index 112e704b5..4872bf2d3 100644 --- a/common/src/main/resources/valkyrienskies-common.mixins.json +++ b/common/src/main/resources/valkyrienskies-common.mixins.json @@ -41,6 +41,7 @@ "feature.mob_spawning.NaturalSpawnerMixin", "feature.render_pathfinding.MixinDebugPackets", "feature.screen_distance_check.MixinScreenHandler", + "feature.sealed_air_sync.MixinSectionBlocksUpdatePacket", "feature.shipyard_entities.MixinEntity", "feature.shipyard_entities.MixinEntitySection", "feature.shipyard_entities.MixinEntitySectionStorage", @@ -132,6 +133,7 @@ "client.world.MixinClientLevel", "feature.block_tint.MixinClientLevel", "feature.commands.MixinClientSuggestionProvider", + "feature.debug_sparse_voxel_rendering.MixinDebugRenderer", "feature.fix_render_chunk_sorting.MixinRenderChunk", "feature.fluid_camera_fix.MixinCamera", "feature.render_blockentity_distance_check.MixinBlockEntityRenderDispatcher", @@ -155,6 +157,7 @@ "mod_compat.create.client.MixinCogwheelBlockItemHitOnShaft", "mod_compat.create.client.MixinContraptionRenderDispatcher", "mod_compat.create.client.MixinContraptionRenderInfo", + "mod_compat.create.client.MixinDeployTool", "mod_compat.create.client.MixinElevatorControlsHandler", "mod_compat.create.client.MixinFilteringRenderer", "mod_compat.create.client.MixinGhostBlockRenderer", @@ -163,13 +166,12 @@ "mod_compat.create.client.MixinMultiplePlacementHelpers", "mod_compat.create.client.MixinOutline", "mod_compat.create.client.MixinPlacementHelpers", + "mod_compat.create.client.MixinSchematicToolBase", "mod_compat.create.client.MixinSoundScapes", "mod_compat.create.client.MixinTileEntityRenderHelper", "mod_compat.create.client.MixinTrainRelocator", - "mod_compat.create.client.MixinDeployTool", - "mod_compat.create.client.MixinSchematicToolBase", - "mod_compat.create.client.trackOutlines.MixinBigOutlines", "mod_compat.create.client.MixinValueBox", + "mod_compat.create.client.trackOutlines.MixinBigOutlines", "mod_compat.flywheel.InstancingEngineAccessor", "mod_compat.flywheel.MixinBlockEntityInstanceManager", "mod_compat.flywheel.MixinInstanceManager", diff --git a/gradle.properties b/gradle.properties index 2410644ff..b2ff69dd2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx20G -XX:MaxMetaspaceSize=1G +org.gradle.jvmargs=-Xmx12G -XX:MaxMetaspaceSize=1G minecraft_version=1.18.2 enabled_platforms=quilt,fabric,forge archives_base_name=valkyrienskies-118 @@ -11,7 +11,7 @@ forge_version=1.18.2-40.2.4 create_fabric_version=0.5.1-i-build.1598+mc1.18.2 flywheel_version_fabric=0.6.9-38 createbigcannons_version= 0.5.2-nightly-e815ca4 -vs_core_version=1.1.0+9a16ff656c +vs_core_version=1.1.0+0ea54cda8b # Prevent kotlin from autoincluding stdlib as a dependency, which breaks # gradle's composite builds (includeBuild) for some reason. We'll add it manually kotlin.stdlib.default.dependency=false From 949a69a66af70c8221d6403986a0c899e04bd8d5 Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Fri, 27 Dec 2024 01:19:03 -0500 Subject: [PATCH 5/9] dont do that --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index b2ff69dd2..15e3ca20c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx12G -XX:MaxMetaspaceSize=1G +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=1G minecraft_version=1.18.2 enabled_platforms=quilt,fabric,forge archives_base_name=valkyrienskies-118 From 1a869207aeb1ecf3210ced9771206bfd380968b8 Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Fri, 27 Dec 2024 09:36:55 -0500 Subject: [PATCH 6/9] Make splitting use old assembly for now --- .../org/valkyrienskies/mod/common/util/SplitHandler.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt index 6b4b22ea7..81b195471 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt @@ -12,6 +12,7 @@ import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.DISCONNEC import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.core.util.expand import org.valkyrienskies.mod.common.ValkyrienSkiesMod +import org.valkyrienskies.mod.common.assembly.ShipAssembler import org.valkyrienskies.mod.common.assembly.createNewShipWithBlocks import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipObjectManagingPos @@ -137,8 +138,8 @@ class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) } for (component in toAssemble) { - //ShipAssembler.assembleToShip(level, component, true, 1.0, true) - createNewShipWithBlocks(component.first().toBlockPos(), component, level) + ShipAssembler.assembleToShip(level, component.toSet().map { it.toBlockPos() }, true, 1.0, true) + //createNewShipWithBlocks(component.first().toBlockPos(), component, level) } loadedShip?.getAttachment(SplittingDisablerAttachment::class.java)?.enableSplitting() From a78816380b055c5dfe941aa62136db7e6e03d99c Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Fri, 27 Dec 2024 11:48:43 -0500 Subject: [PATCH 7/9] Api, split queue, config, joints fix --- ...oundSectionBlocksUpdatePacketAccessor.java | 1 - .../mod_compat/create/MixinContraption.java | 1 - .../mixin/server/MixinMinecraftServer.java | 7 ++-- .../mixin/server/world/MixinServerLevel.java | 5 +++ .../mod_compat/bluemap/WorldDuck.java | 1 - .../mod/api_impl/events/VSApiImpl.kt | 25 +++++++++++ .../mod/common/BlockStateInfoProvider.kt | 4 +- .../valkyrienskies/mod/common/VSGameUtils.kt | 5 ++- .../mod/common/ValkyrienSkiesMod.kt | 4 +- .../mod/common/assembly/ShipAssembler.kt | 4 +- .../mod/common/assembly/ShipAssembly.kt | 17 +++++--- .../mod/common/block/TestHingeBlock.kt | 14 ++++--- .../mod/common/config/VSGameConfig.kt | 10 +++++ .../mod/common/config/VSMassDataLoader.kt | 3 +- .../mod/common/entity/ShipMountingEntity.kt | 4 +- .../mod/common/entity/VSPhysicsEntity.kt | 1 + .../entity/handling/WorldEntityHandler.kt | 2 +- .../mod/common/hooks/CommonHooksImpl.kt | 4 ++ .../mod/common/item/ShipCreatorItem.kt | 5 ++- .../mod/common/networking/VSGamePackets.kt | 5 +-- .../mod/common/util/DimensionIdProvider.kt | 2 +- .../common/util/EntityShipCollisionUtils.kt | 3 +- .../mod/common/util/MinecraftPlayer.kt | 2 +- .../mod/common/util/ShipSettings.kt | 9 ++-- .../mod/common/util/SplitHandler.kt | 42 +++++++++++++++---- .../mod/common/world/RaycastUtils.kt | 11 ++--- .../mod/compat/Weather2Compat.kt | 4 +- gradle.properties | 2 +- 28 files changed, 139 insertions(+), 58 deletions(-) diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java b/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java index 52a8180fa..39a16b43c 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/accessors/network/protocol/game/ClientboundSectionBlocksUpdatePacketAccessor.java @@ -3,7 +3,6 @@ import net.minecraft.core.SectionPos; import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(ClientboundSectionBlocksUpdatePacket.class) diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinContraption.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinContraption.java index 6ffd95f24..d677ae582 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinContraption.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinContraption.java @@ -12,7 +12,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.valkyrienskies.core.api.ships.LoadedServerShip; import org.valkyrienskies.mod.common.VSGameUtilsKt; -import org.valkyrienskies.mod.common.util.SplitHandler; import org.valkyrienskies.mod.common.util.SplittingDisablerAttachment; @Mixin(Contraption.class) diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/server/MixinMinecraftServer.java b/common/src/main/java/org/valkyrienskies/mod/mixin/server/MixinMinecraftServer.java index c3ff37678..e7f6c3e42 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/server/MixinMinecraftServer.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/server/MixinMinecraftServer.java @@ -46,6 +46,7 @@ import org.valkyrienskies.core.api.ships.properties.IShipActiveChunksSet; import org.valkyrienskies.core.apigame.GameServer; import org.valkyrienskies.core.apigame.ShipTeleportData; +import org.valkyrienskies.core.apigame.ships.LoadedServerShipCore; import org.valkyrienskies.core.apigame.world.IPlayer; import org.valkyrienskies.core.apigame.world.ServerShipWorldCore; import org.valkyrienskies.core.apigame.world.VSPipeline; @@ -256,7 +257,7 @@ private void handleShipPortals() { final BlockPos blockPos2 = new BlockPos(shipPos.x() + bbRadius, shipPos.y() + bbRadius, shipPos.z() + bbRadius); // Only run this code if the chunks between blockPos and blockPos2 are loaded if (level.hasChunksAt(blockPos, blockPos2)) { - shipObject.decayPortalCoolDown(); + ((LoadedServerShipCore) shipObject).decayPortalCoolDown(); final BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); for (int i = blockPos.getX(); i <= blockPos2.getX(); ++i) { @@ -266,7 +267,7 @@ private void handleShipPortals() { final BlockState blockState = level.getBlockState(mutableBlockPos); if (blockState.getBlock() == Blocks.NETHER_PORTAL) { // Handle nether portal teleport - if (!shipObject.isOnPortalCoolDown()) { + if (!((LoadedServerShipCore) shipObject).isOnPortalCoolDown()) { // Move the ship between dimensions final ServerLevel destLevel = getLevel(level.dimension() == Level.NETHER ? Level.OVERWORLD : Level.NETHER); // TODO: Do we want portal time? @@ -276,7 +277,7 @@ private void handleShipPortals() { level.getProfiler().pop(); } } - shipObject.handleInsidePortal(); + ((LoadedServerShipCore) shipObject).handleInsidePortal(); } else if (blockState.getBlock() == Blocks.END_PORTAL) { // Handle end portal teleport final ServerLevel destLevel = level.getServer().getLevel(level.dimension() == Level.END ? Level.OVERWORLD : Level.END); diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/server/world/MixinServerLevel.java b/common/src/main/java/org/valkyrienskies/mod/mixin/server/world/MixinServerLevel.java index af9fa6e19..0f48547f7 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/server/world/MixinServerLevel.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/server/world/MixinServerLevel.java @@ -51,6 +51,7 @@ import org.valkyrienskies.core.apigame.world.chunks.TerrainUpdate; import org.valkyrienskies.mod.common.IShipObjectWorldServerProvider; import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.ValkyrienSkiesMod; import org.valkyrienskies.mod.common.block.WingBlock; import org.valkyrienskies.mod.common.util.VSServerLevel; import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; @@ -248,6 +249,10 @@ private void postTick(final BooleanSupplier shouldKeepTicking, final CallbackInf voxelShapeUpdates ); + if (ValkyrienSkiesMod.getVsCore().getHooks().getEnableSplitting()) { + ValkyrienSkiesMod.splitHandler.tick(ServerLevel.class.cast(this)); + } + } @Override diff --git a/common/src/main/java/org/valkyrienskies/mod/mixinducks/mod_compat/bluemap/WorldDuck.java b/common/src/main/java/org/valkyrienskies/mod/mixinducks/mod_compat/bluemap/WorldDuck.java index 162811d5f..0091c4bb9 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixinducks/mod_compat/bluemap/WorldDuck.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixinducks/mod_compat/bluemap/WorldDuck.java @@ -1,6 +1,5 @@ package org.valkyrienskies.mod.mixinducks.mod_compat.bluemap; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; public interface WorldDuck { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt b/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt index 3749d133e..b67911bfc 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt @@ -5,12 +5,18 @@ import net.minecraft.core.BlockPos import net.minecraft.world.entity.Entity import net.minecraft.world.level.ChunkPos import net.minecraft.world.level.Level +import org.valkyrienskies.core.api.VsBeta +import org.valkyrienskies.core.api.attachment.AttachmentRegistration +import org.valkyrienskies.core.api.attachment.AttachmentRegistration.Builder +import org.valkyrienskies.core.api.bodies.properties.BodyTransform.Factory import org.valkyrienskies.core.api.ships.Ship +import org.valkyrienskies.core.impl.bodies.properties.BodyTransformFactory import org.valkyrienskies.core.util.events.EventEmitterImpl import org.valkyrienskies.mod.api.VsApi import org.valkyrienskies.mod.api.events.PostRenderShipEvent import org.valkyrienskies.mod.api.events.PreRenderShipEvent import org.valkyrienskies.mod.api.events.RegisterBlockStateEvent +import org.valkyrienskies.mod.common.ValkyrienSkiesMod import org.valkyrienskies.mod.common.entity.ShipMountingEntity import org.valkyrienskies.mod.common.getShipManagingPos import org.valkyrienskies.mod.compat.clothconfig.VSClothConfig @@ -41,4 +47,23 @@ class VsApiImpl : VsApi { override fun getShipManagingChunk(level: Level?, chunkX: Int, chunkZ: Int): Ship? { return level?.getShipManagingPos(chunkX, chunkZ) } + + @VsBeta + override val transformFactory: Factory = BodyTransformFactory + + override fun newAttachmentRegistrationBuilder(attachmentClass: Class): Builder { + return ValkyrienSkiesMod.vsCore.newAttachmentRegistrationBuilder(attachmentClass) + } + + override fun registerAttachment(attachmentClass: Class, registrationBuilder: Builder.() -> Unit) { + ValkyrienSkiesMod.vsCore.registerAttachment(attachmentClass, registrationBuilder) + } + + override fun registerAttachment(registration: AttachmentRegistration) { + ValkyrienSkiesMod.vsCore.registerAttachment(registration) + } + + override fun registerAttachmentForRemoval(attachmentKey: String) { + ValkyrienSkiesMod.vsCore.registerAttachmentForRemoval(attachmentKey) + } } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/BlockStateInfoProvider.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/BlockStateInfoProvider.kt index 9178dfb7a..5962906b0 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/BlockStateInfoProvider.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/BlockStateInfoProvider.kt @@ -135,8 +135,8 @@ object BlockStateInfo { newBlockMass ) - if (ValkyrienSkiesMod.vsCore.hooks.enableConnectivity) { - ValkyrienSkiesMod.splitHandler.split(level, x, y, z, prevBlockState, newBlockState) + if (ValkyrienSkiesMod.vsCore.hooks.enableSplitting) { + ValkyrienSkiesMod.splitHandler.queueSplit(level, x, y, z) } } } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt index 8c4160db7..6c1f081e2 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt @@ -24,16 +24,17 @@ import org.joml.Vector3ic import org.joml.primitives.AABBd import org.joml.primitives.AABBdc import org.valkyrienskies.core.api.ships.ClientShip +import org.valkyrienskies.core.api.ships.LoadedServerShip import org.valkyrienskies.core.api.ships.LoadedShip import org.valkyrienskies.core.api.ships.ServerShip import org.valkyrienskies.core.api.ships.Ship import org.valkyrienskies.core.api.util.functions.DoubleTernaryConsumer import org.valkyrienskies.core.api.world.LevelYRange +import org.valkyrienskies.core.api.world.properties.DimensionId import org.valkyrienskies.core.apigame.world.IPlayer import org.valkyrienskies.core.apigame.world.ServerShipWorldCore import org.valkyrienskies.core.apigame.world.ShipWorldCore import org.valkyrienskies.core.apigame.world.chunks.TerrainUpdate -import org.valkyrienskies.core.apigame.world.properties.DimensionId import org.valkyrienskies.core.game.ships.ShipObjectServer import org.valkyrienskies.core.impl.hooks.VSEvents.TickEndEvent import org.valkyrienskies.core.util.expand @@ -266,7 +267,7 @@ fun ClientLevel?.getShipObjectManagingPos(chunkPos: ChunkPos) = // ServerWorld fun ServerLevel?.getShipObjectManagingPos(chunkX: Int, chunkZ: Int) = - getShipObjectManagingPosImpl(this, chunkX, chunkZ) as ShipObjectServer? + getShipObjectManagingPosImpl(this, chunkX, chunkZ) as LoadedServerShip? fun ServerLevel?.getShipObjectManagingPos(blockPos: Vec3i) = getShipObjectManagingPos(blockPos.x shr 4, blockPos.z shr 4) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt index 312af3a0d..86d136e39 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt @@ -5,7 +5,6 @@ import net.minecraft.world.entity.EntityType import net.minecraft.world.item.Item import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.entity.BlockEntityType -import org.valkyrienskies.core.api.ships.setAttachment import org.valkyrienskies.core.apigame.VSCore import org.valkyrienskies.core.apigame.VSCoreClient import org.valkyrienskies.core.impl.hooks.VSEvents @@ -59,6 +58,9 @@ object ValkyrienSkiesMod { splitHandler = SplitHandler(this.vsCore.hooks.enableBlockEdgeConnectivity, this.vsCore.hooks.enableBlockCornerConnectivity) + vsCore.registerAttachment(GameTickForceApplier::class.java) + vsCore.registerAttachment(SplittingDisablerAttachment::class.java) + VSEvents.ShipLoadEvent.on { event -> event.ship.setAttachment(GameTickForceApplier()) event.ship.setAttachment(SplittingDisablerAttachment(true)) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt index dade67e14..733fd920d 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembler.kt @@ -7,9 +7,9 @@ import net.minecraft.world.level.block.state.BlockState import org.joml.Vector3d import org.joml.Vector3i import org.joml.Vector3ic +import org.valkyrienskies.core.api.attachment.getAttachment import org.valkyrienskies.core.api.ships.ServerShip import org.valkyrienskies.core.api.ships.Ship -import org.valkyrienskies.core.api.ships.getAttachment import org.valkyrienskies.core.impl.game.ShipTeleportDataImpl import org.valkyrienskies.mod.common.BlockStateInfo.onSetBlock import org.valkyrienskies.mod.common.dimensionId @@ -111,7 +111,7 @@ object ShipAssembler { AssemblyUtil.updateBlock(level,itPos,shipPos,level.getBlockState(shipPos)) } - val shipCenterPos = ((newShip as ServerShip).inertiaData.centerOfMassInShip).add(0.5, 0.5, 0.5, Vector3d()) + val shipCenterPos = ((newShip as ServerShip).inertiaData.centerOfMass).add(0.5, 0.5, 0.5, Vector3d()) // This is giga sus, but whatever val shipPos = Vector3d(shipOGPos).add(0.5, 0.5, 0.5) if (existingShip != null) { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt index f1e985ad2..436aea8e6 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/assembly/ShipAssembly.kt @@ -10,10 +10,13 @@ import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate import org.joml.Vector3d +import org.valkyrienskies.core.api.VsBeta import org.valkyrienskies.core.api.ships.ServerShip +import org.valkyrienskies.core.api.ships.properties.ShipTransformVelocity import org.valkyrienskies.core.apigame.ShipTeleportData import org.valkyrienskies.core.impl.game.ShipTeleportDataImpl import org.valkyrienskies.core.impl.game.ships.ShipData +import org.valkyrienskies.core.impl.game.ships.ShipDataCommon import org.valkyrienskies.core.impl.game.ships.ShipTransformImpl import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet import org.valkyrienskies.mod.common.dimensionId @@ -26,6 +29,7 @@ import org.valkyrienskies.mod.common.util.toMinecraft import org.valkyrienskies.mod.util.relocateBlock import org.valkyrienskies.mod.util.updateBlock +@OptIn(VsBeta::class) @Deprecated("Use [ShipAssembler.assembleToShip] instead") fun createNewShipWithBlocks( centerBlock: BlockPos, blocks: DenseBlockPosSet, level: ServerLevel @@ -82,11 +86,14 @@ fun createNewShipWithBlocks( ((shipChunkZ shl 4) + (centerBlock.z and 15)).toDouble() ) // The ship's position has shifted from the center block since we assembled the ship, compensate for that - val centerBlockPosInWorld = ship.inertiaData.centerOfMassInShip.sub(centerInShip, Vector3d()) + val centerBlockPosInWorld = ship.inertiaData.centerOfMass.sub(centerInShip, Vector3d()) .add(ship.transform.positionInWorld) // Put the ship into the compensated position, so that all the assembled blocks stay in the same place // TODO: AAAAAAAAA THIS IS HORRIBLE how can the API support this? - (ship as ShipData).transform = (ship.transform as ShipTransformImpl).copy(positionInWorld = centerBlockPosInWorld) + // well now it doesnt kekw + //(ship as ShipDataCommon).transform = (ship.transform).withTransformFrom(positionInWorld = centerBlockPosInWorld) + + (ship as ShipDataCommon).setFromTransform(ship.transform.copy(position = centerBlockPosInWorld)) level.server.executeIf( // This condition will return true if all modified chunks have been both loaded AND // chunk update packets were sent to players @@ -128,13 +135,11 @@ fun createNewShipWithStructure( val centerPos = lowerCorner.toJOMLD().add(diff.x / 2.0, diff.y / 2.0, diff.z / 2.0) // The ship's position has shifted from the center block since we assembled the ship, compensate for that - val centerBlockPosInWorld = ship.inertiaData.centerOfMassInShip.sub(centerPos, Vector3d()) + val centerBlockPosInWorld = ship.inertiaData.centerOfMass.sub(centerPos, Vector3d()) .add(ship.transform.positionInWorld) // Put the ship into the compensated position, so that all the assembled blocks stay in the same place - // TODO: AAAAAAAAA THIS IS HORRIBLE how can the API support this? - //(ship as ShipData).transform = (ship.transform as ShipTransformImpl).copy(positionInWorld = centerBlockPosInWorld) level.shipObjectWorld - .teleportShip(ship, ShipTeleportDataImpl(newPos = centerBlockPosInWorld.add(0.0, 0.0, 0.0, Vector3d()), newPosInShip = ship.inertiaData.centerOfMassInShip)) + .teleportShip(ship, ShipTeleportDataImpl(newPos = centerBlockPosInWorld.add(0.0, 0.0, 0.0, Vector3d()), newPosInShip = ship.inertiaData.centerOfMass)) for (x in lowerCorner.x..higherCorner.x) { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt index 6be920674..0149f3464 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestHingeBlock.kt @@ -36,8 +36,8 @@ import org.joml.Vector3dc import org.valkyrienskies.core.apigame.joints.VSJointMaxForceTorque import org.valkyrienskies.core.apigame.joints.VSJointPose import org.valkyrienskies.core.apigame.joints.VSRevoluteJoint +import org.valkyrienskies.core.impl.bodies.properties.BodyTransformVelocityImpl import org.valkyrienskies.core.impl.game.ships.ShipDataCommon -import org.valkyrienskies.core.impl.game.ships.ShipTransformImpl import org.valkyrienskies.mod.common.ValkyrienSkiesMod import org.valkyrienskies.mod.common.blockentity.TestHingeBlockEntity import org.valkyrienskies.mod.common.dimensionId @@ -173,22 +173,26 @@ object TestHingeBlock : // Put the new ship where the old ship is val newPos = shipThisIsIn.transform.shipToWorld.transformPosition(attachmentLocalPos0, Vector3d()) newPos.sub(shipThisIsIn.transform.shipToWorldRotation.transform(attachmentOffset1, Vector3d())) - val newTransform = ShipTransformImpl( + val newTransform = BodyTransformVelocityImpl( newPos, ship.transform.positionInShip, shipThisIsIn.transform.shipToWorldRotation, // Copy source ship rotation - ship.transform.shipToWorldScaling + ship.transform.shipToWorldScaling, + velocity = shipThisIsIn.velocity, + angularVelocity = shipThisIsIn.angularVelocity ) // Update the ship transform (ship as ShipDataCommon).transform = newTransform } else { val newPos = Vector3d(attachmentLocalPos0) newPos.sub(attachmentOffset1) - val newTransform = ShipTransformImpl( + val newTransform = BodyTransformVelocityImpl( newPos, ship.transform.positionInShip, ship.transform.shipToWorldRotation, - ship.transform.shipToWorldScaling + ship.transform.shipToWorldScaling, + velocity = ship.velocity, + angularVelocity = ship.angularVelocity ) // Update the ship transform (ship as ShipDataCommon).transform = newTransform diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSGameConfig.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSGameConfig.kt index ebf47e73d..33a626b04 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSGameConfig.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSGameConfig.kt @@ -148,6 +148,16 @@ object VSGameConfig { description = "Minimum scale of ships" ) var minScaling = 0.25 + + @JsonSchema( + description = "Enable splitting in worldspace. (Experimental!)" + ) + var enableWorldSplitting = false + + @JsonSchema( + description = "The default grace timer for splitting. A split won't occur after a block break at a position until this many ticks have passed. Note that setting this too high may prevent things like explosions from properly launching split ships. (in ticks)" + ) + var defaultSplitGraceTimer = 1 } class Common { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSMassDataLoader.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSMassDataLoader.kt index 6ec62527c..f43439fba 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSMassDataLoader.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/config/VSMassDataLoader.kt @@ -27,7 +27,6 @@ import org.valkyrienskies.core.api.physics.blockstates.LiquidState import org.valkyrienskies.core.api.physics.blockstates.SolidBlockShape import org.valkyrienskies.core.apigame.physics.blockstates.VsBlockState import org.valkyrienskies.core.apigame.world.chunks.BlockType -import org.valkyrienskies.core.game.VSBlockType import org.valkyrienskies.mod.common.BlockStateInfoProvider import org.valkyrienskies.mod.common.ValkyrienSkiesMod import org.valkyrienskies.mod.common.hooks.VSGameEvents @@ -44,7 +43,7 @@ private data class VSBlockStateInfo( val mass: Double, val friction: Double, val elasticity: Double, - val type: VSBlockType?, + val type: BlockType?, ) object MassDatapackResolver : BlockStateInfoProvider { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountingEntity.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountingEntity.kt index 34da4e64b..483cfbeaf 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountingEntity.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountingEntity.kt @@ -10,8 +10,8 @@ import net.minecraft.world.entity.LivingEntity import net.minecraft.world.level.Level import net.minecraft.world.phys.Vec3 import org.joml.Vector3f +import org.valkyrienskies.core.api.attachment.removeAttachment import org.valkyrienskies.core.api.ships.LoadedServerShip -import org.valkyrienskies.core.api.ships.setAttachment import org.valkyrienskies.mod.api.SeatedControllingPlayer import org.valkyrienskies.mod.common.config.VSKeyBindings import org.valkyrienskies.mod.common.getShipManagingPos @@ -74,7 +74,7 @@ open class ShipMountingEntity(type: EntityType, level: Level override fun remove(removalReason: RemovalReason) { if (this.isController && !level.isClientSide) (level.getShipObjectManagingPos(blockPosition()) as LoadedServerShip?) - ?.setAttachment(null) + ?.removeAttachment() super.remove(removalReason) } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/VSPhysicsEntity.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/VSPhysicsEntity.kt index 9adbc52d4..28c7b736b 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/VSPhysicsEntity.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/VSPhysicsEntity.kt @@ -233,6 +233,7 @@ open class VSPhysicsEntity(type: EntityType, level: Level) : En shipId: ShipId, transform: ShipTransform, radius: Double = 0.5, mass: Double = 10000.0 ): PhysicsEntityData { val inertia = 0.4 * mass * radius * radius + // todo: fix physics entities for some reason using ship inertia data??? what?? ruby pls val inertiaData: ShipInertiaData = ShipInertiaDataImpl(Vector3d(), mass, Matrix3d().scale(inertia)) val collisionShapeData = VSSphereCollisionShapeData(radius) return PhysicsEntityData( diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/handling/WorldEntityHandler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/handling/WorldEntityHandler.kt index 295792c93..9283d7302 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/handling/WorldEntityHandler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/handling/WorldEntityHandler.kt @@ -64,7 +64,7 @@ object WorldEntityHandler : VSEntityHandler { val newPosInShipLocal = Vector3d(newPos).sub(ship.transform.positionInWorld) val shipVelocity = Vector3d(ship.velocity) // ship linear velocity - .add(Vector3d(ship.omega).cross(newPosInShipLocal)) // angular velocity + .add(Vector3d(ship.angularVelocity).cross(newPosInShipLocal)) // angular velocity .mul(0.05) // Tick velocity val entityVelocity = ship.transform.shipToWorldRotation.transform(entity.deltaMovement.toJOML()) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/hooks/CommonHooksImpl.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/hooks/CommonHooksImpl.kt index 490f306f5..f5e26b1e8 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/hooks/CommonHooksImpl.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/hooks/CommonHooksImpl.kt @@ -30,6 +30,10 @@ abstract class CommonHooksImpl : CoreHooksOut { get() = vsCore.hooks.enableWorldConnectivity set(value) {} + override var enableSplitting: Boolean + get() = vsCore.hooks.enableSplitting + set(value) {} + override val playState: PlayState get() { if (!isPhysicalClient) { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt index d9335bc28..c6deab825 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt @@ -10,6 +10,9 @@ import net.minecraft.world.item.context.UseOnContext import net.minecraft.world.level.block.Rotation.NONE import net.minecraft.world.level.block.state.BlockState import org.joml.Vector3d +import org.valkyrienskies.core.api.ships.properties.ShipTransformVelocity +import org.valkyrienskies.core.impl.bodies.properties.BodyTransformImpl +import org.valkyrienskies.core.impl.bodies.properties.BodyTransformVelocityImpl import org.valkyrienskies.core.impl.game.ships.ShipDataCommon import org.valkyrienskies.core.impl.game.ships.ShipTransformImpl import org.valkyrienskies.mod.common.dimensionId @@ -65,7 +68,7 @@ class ShipCreatorItem( newShipScaling = Vector3d(minScaling, minScaling, minScaling) } val shipTransform = - ShipTransformImpl(newShipPosInWorld, newShipPosInShipyard, newShipRotation, newShipScaling) + BodyTransformVelocityImpl(newShipPosInWorld, newShipPosInShipyard, newShipRotation, newShipScaling, Vector3d(), Vector3d()) (serverShip as ShipDataCommon).transform = shipTransform } } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/networking/VSGamePackets.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/networking/VSGamePackets.kt index 4be65f6eb..cc46f2221 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/networking/VSGamePackets.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/networking/VSGamePackets.kt @@ -3,9 +3,8 @@ package org.valkyrienskies.mod.common.networking import net.minecraft.core.Registry import net.minecraft.resources.ResourceLocation import net.minecraft.server.level.ServerPlayer +import org.valkyrienskies.core.api.attachment.getAttachment import org.valkyrienskies.core.api.ships.LoadedServerShip -import org.valkyrienskies.core.api.ships.getAttachment -import org.valkyrienskies.core.api.ships.setAttachment import org.valkyrienskies.mod.api.SeatedControllingPlayer import org.valkyrienskies.mod.common.entity.ShipMountingEntity import org.valkyrienskies.mod.common.entity.handling.VSEntityManager @@ -31,7 +30,7 @@ object VSGamePackets { val ship = seat.level.getShipObjectManagingPos(seat.blockPosition()) as? LoadedServerShip ?: return@registerServerHandler - val attachment: SeatedControllingPlayer = ship.getAttachment() + val attachment: SeatedControllingPlayer = ship.getAttachment() ?: SeatedControllingPlayer(seat.direction.opposite).apply { ship.setAttachment(this) } attachment.forwardImpulse = driving.impulse.z diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/DimensionIdProvider.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/DimensionIdProvider.kt index a9649fc70..2eb2df991 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/DimensionIdProvider.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/DimensionIdProvider.kt @@ -1,6 +1,6 @@ package org.valkyrienskies.mod.common.util -import org.valkyrienskies.core.apigame.world.properties.DimensionId +import org.valkyrienskies.core.api.world.properties.DimensionId /** * Interface used to get the [DimensionId] from Minecraft [Level] objects diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt index 4b4109ae1..63a610df9 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityShipCollisionUtils.kt @@ -14,6 +14,7 @@ import org.joml.primitives.AABBdc import org.valkyrienskies.core.api.ships.Ship import org.valkyrienskies.core.apigame.collision.ConvexPolygonc import org.valkyrienskies.core.util.extend +import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipsIntersecting import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.vsCore @@ -109,7 +110,7 @@ object EntityShipCollisionUtils { val entityBoxWithMovement = entityBoundingBox.expandTowards(movement) val collidingPolygons: MutableList = ArrayList() val entityBoundingBoxExtended = entityBoundingBox.toJOML().extend(movement.toJOML()) - for (shipObject in world.shipObjectWorld.loadedShips.getIntersecting(entityBoundingBoxExtended)) { + for (shipObject in world.shipObjectWorld.loadedShips.getIntersecting(entityBoundingBoxExtended, world.dimensionId)) { val shipTransform = shipObject.transform val entityPolyInShipCoordinates: ConvexPolygonc = collider.createPolygonFromAABB( entityBoxWithMovement.toJOML(), diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt index 603227d92..766b1b528 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt @@ -2,9 +2,9 @@ package org.valkyrienskies.mod.common.util import net.minecraft.world.entity.player.Player import org.joml.Vector3d +import org.valkyrienskies.core.api.world.properties.DimensionId import org.valkyrienskies.core.apigame.world.IPlayer import org.valkyrienskies.core.apigame.world.PlayerState -import org.valkyrienskies.core.apigame.world.properties.DimensionId import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipMountedToData import org.valkyrienskies.mod.common.vsCore diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/ShipSettings.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/ShipSettings.kt index be9f2f8c7..15b13f85e 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/ShipSettings.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/ShipSettings.kt @@ -1,8 +1,7 @@ package org.valkyrienskies.mod.common.util -import org.valkyrienskies.core.api.ships.ServerShip -import org.valkyrienskies.core.api.ships.getAttachment -import org.valkyrienskies.core.api.ships.saveAttachment +import org.valkyrienskies.core.api.attachment.getAttachment +import org.valkyrienskies.core.api.ships.LoadedServerShip /** * A attachment that stores ship specific settings. @@ -20,5 +19,5 @@ data class ShipSettings( var changeDimensionOnTouchPortals: Boolean = true ) -val ServerShip.settings: ShipSettings - get() = getAttachment() ?: ShipSettings().also { saveAttachment(it) } +val LoadedServerShip.settings: ShipSettings + get() = getAttachment() ?: ShipSettings().also { setAttachment(it) } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt index 81b195471..aa8f7cf1c 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt @@ -5,15 +5,14 @@ import net.minecraft.core.Vec3i import net.minecraft.server.level.ServerLevel import net.minecraft.world.level.Level import net.minecraft.world.level.block.state.BlockState -import org.joml.primitives.AABBi -import org.valkyrienskies.core.api.ships.getAttachment +import org.valkyrienskies.core.api.attachment.getAttachment +import org.valkyrienskies.core.api.ships.LoadedServerShip import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.CONNECTED import org.valkyrienskies.core.api.world.connectivity.ConnectionStatus.DISCONNECTED +import org.valkyrienskies.core.api.world.properties.DimensionId import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet -import org.valkyrienskies.core.util.expand -import org.valkyrienskies.mod.common.ValkyrienSkiesMod import org.valkyrienskies.mod.common.assembly.ShipAssembler -import org.valkyrienskies.mod.common.assembly.createNewShipWithBlocks +import org.valkyrienskies.mod.common.config.VSGameConfig import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.getShipObjectManagingPos import org.valkyrienskies.mod.common.shipObjectWorld @@ -21,11 +20,36 @@ import org.valkyrienskies.mod.util.logger class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) { - fun split(level: Level, x: Int, y: Int, z: Int, prevBlockState: BlockState, newBlockState: BlockState) { + val splitQueue: HashMap> = hashMapOf() + + fun queueSplit(level: Level, x: Int, y: Int, z: Int) { + splitQueue[level.dimensionId]?.put(BlockPos(x, y, z), VSGameConfig.SERVER.defaultSplitGraceTimer) ?: run { + splitQueue[level.dimensionId] = hashMapOf(BlockPos(x, y, z) to VSGameConfig.SERVER.defaultSplitGraceTimer) + } + } + + fun tick(level: ServerLevel) { + if (splitQueue[level.dimensionId] != null && splitQueue[level.dimensionId]!!.isNotEmpty()) { + val splitsToProcess = HashSet() + for (splitIndex in splitQueue[level.dimensionId]!!.keys) { + if (splitQueue[level.dimensionId]!![splitIndex]!! <= 0) { + splitsToProcess.add(splitIndex) + } else { + splitQueue[level.dimensionId]!![splitIndex] = splitQueue[level.dimensionId]!![splitIndex]!! - 1 + } + } + splitsToProcess.forEach { + splitQueue[level.dimensionId]!!.remove(it) + split(level, it.x, it.y, it.z, level.getBlockState(it)) + } + } + } + + fun split(level: Level, x: Int, y: Int, z: Int, newBlockState: BlockState) { if (level is ServerLevel) { - val loadedShip = level.getShipObjectManagingPos(x shr 4, z shr 4) - if ((loadedShip != null && loadedShip.getAttachment()?.canSplit() != false)) { - if (!prevBlockState.isAir && newBlockState.isAir) { + val loadedShip : LoadedServerShip? = level.getShipObjectManagingPos(x shr 4, z shr 4) + if ((loadedShip != null && loadedShip.getAttachment()?.canSplit() != false) || (loadedShip == null && VSGameConfig.SERVER.enableWorldSplitting)) { + if (newBlockState.isAir) { val blockNeighbors: HashSet = HashSet() //val shipBox = loadedShip.shipAABB?.expand(1, AABBi()) ?: return diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/world/RaycastUtils.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/world/RaycastUtils.kt index 6e1699db8..8c61e7672 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/world/RaycastUtils.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/world/RaycastUtils.kt @@ -19,7 +19,8 @@ import org.joml.Vector3d import org.joml.primitives.AABBd import org.joml.primitives.AABBdc import org.valkyrienskies.core.api.ships.properties.ShipId -import org.valkyrienskies.core.game.ships.ShipObjectClient +import org.valkyrienskies.core.api.ships.ClientShip +import org.valkyrienskies.mod.common.dimensionId import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.util.toJOML import org.valkyrienskies.mod.common.util.toMinecraft @@ -52,13 +53,13 @@ fun Level.clipIncludeShips( // Iterate every ship, find do the raycast in ship space, // choose the raycast with the lowest distance to the start position. - for (ship in shipObjectWorld.loadedShips.getIntersecting(clipAABB)) { + for (ship in shipObjectWorld.loadedShips.getIntersecting(clipAABB, dimensionId)) { // Skip skipShip if (ship.id == skipShip) { continue } - val worldToShip = (ship as? ShipObjectClient)?.renderTransform?.worldToShipMatrix ?: ship.worldToShip - val shipToWorld = (ship as? ShipObjectClient)?.renderTransform?.shipToWorldMatrix ?: ship.shipToWorld + val worldToShip = (ship as? ClientShip)?.renderTransform?.worldToShip ?: ship.worldToShip + val shipToWorld = (ship as? ClientShip)?.renderTransform?.shipToWorld ?: ship.shipToWorld val shipStart = worldToShip.transformPosition(ctx.from.toJOML()).toMinecraft() val shipEnd = worldToShip.transformPosition(ctx.to.toJOML()).toMinecraft() @@ -223,7 +224,7 @@ fun Level.raytraceEntities( val start = Vector3d() val end = Vector3d() - shipObjectWorld.loadedShips.getIntersecting(origBoundingBoxM.toJOML()).forEach { + shipObjectWorld.loadedShips.getIntersecting(origBoundingBoxM.toJOML(), dimensionId).forEach { it.worldToShip.transformPosition(origStartVec, start) it.worldToShip.transformPosition(origEndVec, end) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/compat/Weather2Compat.kt b/common/src/main/kotlin/org/valkyrienskies/mod/compat/Weather2Compat.kt index 975b461e8..947efe3ee 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/compat/Weather2Compat.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/compat/Weather2Compat.kt @@ -2,7 +2,7 @@ package org.valkyrienskies.mod.compat import net.minecraft.server.level.ServerLevel import org.joml.Vector3d -import org.valkyrienskies.core.api.ships.getAttachment +import org.valkyrienskies.core.api.attachment.getAttachment import org.valkyrienskies.mod.common.config.VSGameConfig import org.valkyrienskies.mod.common.shipObjectWorld import org.valkyrienskies.mod.common.util.GameTickForceApplier @@ -24,7 +24,7 @@ object Weather2Compat { level.shipObjectWorld.loadedShips.forEach { ship -> val forces = ship.getAttachment()!! - val com = ship.inertiaData.centerOfMassInShip + val com = ship.inertiaData.centerOfMass ship.shipToWorld.transformPosition(com, vec) val pos = vec.toMinecraft() diff --git a/gradle.properties b/gradle.properties index 15e3ca20c..a77b5c5c0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ forge_version=1.18.2-40.2.4 create_fabric_version=0.5.1-i-build.1598+mc1.18.2 flywheel_version_fabric=0.6.9-38 createbigcannons_version= 0.5.2-nightly-e815ca4 -vs_core_version=1.1.0+0ea54cda8b +vs_core_version=1.1.0+774ec4e001 # Prevent kotlin from autoincluding stdlib as a dependency, which breaks # gradle's composite builds (includeBuild) for some reason. We'll add it manually kotlin.stdlib.default.dependency=false From 44ddbd5e14dafbde6e371bdb3707c5a448664ddd Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Fri, 27 Dec 2024 12:02:03 -0500 Subject: [PATCH 8/9] Upgrade kotlin to 2.1.0 --- build.gradle | 2 +- .../valkyrienskies/mod/api_impl/events/VSApiImpl.kt | 3 +++ .../valkyrienskies/mod/common/block/TestSphereBlock.kt | 10 +++++----- .../org/valkyrienskies/mod/common/util/SplitHandler.kt | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 58eff658a..f33da4c42 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { id "dev.architectury.loom" version "1.3.355" apply false id 'io.github.juuxel.loom-vineflower' version '1.11.0' apply false // Kotlin - id "org.jetbrains.kotlin.jvm" version "1.9.10" apply false + id "org.jetbrains.kotlin.jvm" version "2.1.0" apply false id 'com.matthewprenger.cursegradle' version '1.4.0' apply false id "com.modrinth.minotaur" version "2.4.3" apply false } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt b/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt index b67911bfc..8abfdfe0c 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/api_impl/events/VSApiImpl.kt @@ -31,6 +31,9 @@ class VsApiImpl : VsApi { return entity is ShipMountingEntity } + @Deprecated( + "The legacy VS config system will be replaced soon. Migrate to another config library, or the new system when it's released. " + ) override fun createConfigScreenLegacy(parent: Screen, vararg configs: Class<*>): Screen { return VSClothConfig.createConfigScreenFor(parent, *configs) } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestSphereBlock.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestSphereBlock.kt index cfdb38ac8..6c917f951 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestSphereBlock.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/block/TestSphereBlock.kt @@ -10,19 +10,19 @@ import net.minecraft.world.phys.shapes.Shapes import net.minecraft.world.phys.shapes.VoxelShape object TestSphereBlock : Block(Properties.of(Material.STONE)) { + @Deprecated("Deprecated in Java") override fun getVisualShape( - blockState: BlockState?, blockGetter: BlockGetter?, blockPos: BlockPos?, collisionContext: CollisionContext? + blockState: BlockState, blockGetter: BlockGetter, blockPos: BlockPos, collisionContext: CollisionContext ): VoxelShape { return Shapes.empty() } - override fun getShadeBrightness(blockState: BlockState?, blockGetter: BlockGetter?, blockPos: BlockPos?): Float { + @Deprecated("Deprecated in Java") + override fun getShadeBrightness(blockState: BlockState, blockGetter: BlockGetter, blockPos: BlockPos): Float { return 1.0f } - override fun propagatesSkylightDown( - blockState: BlockState?, blockGetter: BlockGetter?, blockPos: BlockPos? - ): Boolean { + override fun propagatesSkylightDown(blockState: BlockState, blockGetter: BlockGetter, blockPos: BlockPos): Boolean { return true } } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt index aa8f7cf1c..f49fdc1e4 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/SplitHandler.kt @@ -20,7 +20,7 @@ import org.valkyrienskies.mod.util.logger class SplitHandler(private val doEdges: Boolean, private val doCorners: Boolean) { - val splitQueue: HashMap> = hashMapOf() + private val splitQueue: HashMap> = hashMapOf() fun queueSplit(level: Level, x: Int, y: Int, z: Int) { splitQueue[level.dimensionId]?.put(BlockPos(x, y, z), VSGameConfig.SERVER.defaultSplitGraceTimer) ?: run { From 83dfca269d0a89919730b574a21529a68bf4d92c Mon Sep 17 00:00:00 2001 From: ThePlasticPotato Date: Fri, 27 Dec 2024 12:31:34 -0500 Subject: [PATCH 9/9] Register shipsettings, that is somewhat important --- .../kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt index 86d136e39..24723f7b1 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt @@ -14,6 +14,7 @@ import org.valkyrienskies.mod.common.entity.ShipMountingEntity import org.valkyrienskies.mod.common.entity.VSPhysicsEntity import org.valkyrienskies.mod.common.networking.VSGamePackets import org.valkyrienskies.mod.common.util.GameTickForceApplier +import org.valkyrienskies.mod.common.util.ShipSettings import org.valkyrienskies.mod.common.util.SplitHandler import org.valkyrienskies.mod.common.util.SplittingDisablerAttachment @@ -58,6 +59,7 @@ object ValkyrienSkiesMod { splitHandler = SplitHandler(this.vsCore.hooks.enableBlockEdgeConnectivity, this.vsCore.hooks.enableBlockCornerConnectivity) + vsCore.registerAttachment(ShipSettings::class.java) vsCore.registerAttachment(GameTickForceApplier::class.java) vsCore.registerAttachment(SplittingDisablerAttachment::class.java)