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