Skip to content

Commit

Permalink
Merge from 1.19.2/main
Browse files Browse the repository at this point in the history
  • Loading branch information
StewStrong committed Oct 28, 2024
2 parents 91091b2 + 7e18ed0 commit a13faa3
Show file tree
Hide file tree
Showing 17 changed files with 487 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ private void shipChangeDimension(@NotNull final ServerLevel srcLevel, @NotNull f
new Vector3d(),
new Vector3d(),
VSGameUtilsKt.getDimensionId(destLevel),
null,
null
);
shipWorld.teleportShip(shipObject, shipTeleportData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,9 @@ object BlockStateInfo {
x, y, z, level.dimensionId, prevBlockType, newBlockType, prevBlockMass,
newBlockMass
)

if (ValkyrienSkiesMod.vsCore.hooks.enableConnectivity) {
ValkyrienSkiesMod.splitHandler.split(level, x, y, z, prevBlockState, newBlockState)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ 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.SplitHandler
import org.valkyrienskies.mod.common.util.SplittingDisablerAttachment

object ValkyrienSkiesMod {
const val MOD_ID = "valkyrienskies"
Expand All @@ -31,9 +33,11 @@ object ValkyrienSkiesMod {
lateinit var TEST_FLAP: Block
lateinit var TEST_WING: Block
lateinit var TEST_SPHERE: Block
lateinit var CONNECTION_CHECKER_ITEM: Item
lateinit var SHIP_CREATOR_ITEM: Item
lateinit var SHIP_ASSEMBLER_ITEM: Item
lateinit var SHIP_CREATOR_ITEM_SMALLER: Item
lateinit var AREA_ASSEMBLER_ITEM: Item
lateinit var PHYSICS_ENTITY_CREATOR_ITEM: Item
lateinit var SHIP_MOUNTING_ENTITY_TYPE: EntityType<ShipMountingEntity>
lateinit var PHYSICS_ENTITY_TYPE: EntityType<VSPhysicsEntity>
Expand All @@ -53,6 +57,9 @@ object ValkyrienSkiesMod {
@JvmStatic
val api = VsApiImpl()

@JvmStatic
lateinit var splitHandler: SplitHandler

fun init(core: VSCore) {
this.vsCore = core

Expand All @@ -61,8 +68,12 @@ object ValkyrienSkiesMod {
VSGamePackets.registerHandlers()

core.registerConfigLegacy("vs", VSGameConfig::class.java)

splitHandler = SplitHandler(this.vsCore.hooks.enableBlockEdgeConnectivity, this.vsCore.hooks.enableBlockCornerConnectivity)

VSEvents.ShipLoadEvent.on { event ->
event.ship.setAttachment(GameTickForceApplier())
event.ship.setAttachment(SplittingDisablerAttachment(true))
}
}

Expand All @@ -75,9 +86,12 @@ object ValkyrienSkiesMod {
output.accept(TEST_HINGE.asItem())
output.accept(TEST_FLAP.asItem())
output.accept(TEST_WING.asItem())
output.accept(TEST_SPHERE.asItem())
output.accept(CONNECTION_CHECKER_ITEM)
output.accept(SHIP_CREATOR_ITEM)
output.accept(SHIP_ASSEMBLER_ITEM)
output.accept(SHIP_CREATOR_ITEM_SMALLER)
output.accept(AREA_ASSEMBLER_ITEM)
output.accept(PHYSICS_ENTITY_CREATOR_ITEM)
}
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.joml.Vector3i
private val AIR = Blocks.AIR.defaultBlockState()
object AssemblyUtil {

fun setBlock(level: Level, pos: BlockPos, state: BlockState?) {
fun setBlock(level: Level, pos: BlockPos, state: BlockState) {
val chunk = level.getChunk(pos) as LevelChunk
val section = chunk.getSection(chunk.getSectionIndex(pos.y))
val oldState = level.getBlockState(pos)
Expand All @@ -26,13 +26,13 @@ object AssemblyUtil {

fun removeBlock(level: Level, pos: BlockPos) {
level.removeBlockEntity(pos)
setBlock(level, pos, Blocks.AIR.defaultBlockState())
level.getChunk(pos).setBlockState(pos, Blocks.AIR.defaultBlockState(), false)
}

fun copyBlock(level: Level, from: BlockPos?, to: BlockPos) {
fun copyBlock(level: Level, from: BlockPos, to: BlockPos) {
val state = level.getBlockState(from)
val blockentity = level.getBlockEntity(from)
setBlock(level, to, state)
level.getChunk(to).setBlockState(to, state, false)

// Transfer pending schedule-ticks
if (level.blockTicks.hasScheduledTick(from, state.block)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ package org.valkyrienskies.mod.common.assembly
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Blocks
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.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
import org.valkyrienskies.mod.common.getShipObjectManagingPos
import org.valkyrienskies.mod.common.shipObjectWorld
import org.valkyrienskies.mod.common.util.SplittingDisablerAttachment

object ShipAssembler {

Expand All @@ -31,29 +32,34 @@ object ShipAssembler {
}


fun assembleToShip(level: Level, blocks: List<BlockPos>, removeOriginal: Boolean, scale: Double): ServerShip {
assert(level is ServerLevel) { "Can't manage contraptions on client side!" }
fun assembleToShip(level: Level, blocks: List<BlockPos>, 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()
throw IllegalArgumentException("No blocks to assemble.")
}

val existingShip = sLevel.getShipObjectManagingPos(blocks.find { !sLevel.getBlockState(it).isAir } ?: throw IllegalArgumentException())

var structureCornerMin: BlockPos = blocks[0]
var structureCornerMax: BlockPos = blocks[0]
var structureCornerMin: BlockPos? = null
var structureCornerMax: BlockPos? = null
var hasSolids = false

// Calculate bounds of the area containing all blocks adn check for solids and invalid blocks
for (itPos in blocks) {
if (isValidShipBlock(level.getBlockState(itPos))) {
structureCornerMin = AssemblyUtil.getMinCorner(structureCornerMin, itPos)
structureCornerMax = AssemblyUtil.getMaxCorner(structureCornerMax, itPos)
if (structureCornerMin == null) {
structureCornerMin = itPos
structureCornerMax = itPos
} else {
structureCornerMin = AssemblyUtil.getMinCorner(structureCornerMin!!, itPos)
structureCornerMax = AssemblyUtil.getMaxCorner(structureCornerMax!!, itPos)
}
hasSolids = true
}
}
if (!hasSolids) throw IllegalArgumentException("No solid blocks found in the structure")
val contraptionOGPos: Vector3ic = AssemblyUtil.getMiddle(structureCornerMin, structureCornerMax)
val contraptionOGPos: Vector3ic = AssemblyUtil.getMiddle(structureCornerMin!!, structureCornerMax!!)
// Create new contraption at center of bounds
val contraptionWorldPos: Vector3i = if (existingShip != null) {
val doubleVer = existingShip.shipToWorld.transformPosition(Vector3d(contraptionOGPos)).floor()
Expand All @@ -66,7 +72,10 @@ object ShipAssembler {
val newShip: Ship = (level as ServerLevel).server.shipObjectWorld
.createNewShipAtBlock(contraptionWorldPos, false, scale, level.dimensionId)

// Stone for safety reasons
if (shouldDisableSplitting) {
level.shipObjectWorld.loadedShips.getById(newShip.id)?.getAttachment<SplittingDisablerAttachment>()?.disableSplitting()

}

val contraptionShipPos = newShip.worldToShip.transformPosition(Vector3d(contraptionWorldPos.x.toDouble(),contraptionWorldPos.y.toDouble(),contraptionWorldPos.z.toDouble()))
val contraptionBlockPos = BlockPos(contraptionShipPos.x.toInt(),contraptionShipPos.y.toInt(),contraptionShipPos.z.toInt())
Expand All @@ -79,14 +88,14 @@ object ShipAssembler {
val relative: BlockPos = itPos.subtract( BlockPos(contraptionOGPos.x(),contraptionOGPos.y(),contraptionOGPos.z()))
val shipPos: BlockPos = contraptionBlockPos.offset(relative)
AssemblyUtil.copyBlock(level, itPos, shipPos)
if (relative == BlockPos.ZERO) centerBlockReplaced = true
if (relative.equals(BlockPos.ZERO)) centerBlockReplaced = true
}
}

// If center block got not replaced, remove the stone block
if (!centerBlockReplaced) {
level.setBlock(contraptionBlockPos, Blocks.AIR.defaultBlockState(), 3)
}
// if (!centerBlockReplaced) {
// level.setBlock(contraptionBlockPos, Blocks.AIR.defaultBlockState(), 3)
// }

// Remove original blocks
if (removeOriginal) {
Expand All @@ -104,9 +113,20 @@ 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())
// This is giga sus, but whatever
val shipPos = Vector3d(contraptionOGPos).add(0.5, 0.5, 0.5)
if (existingShip != null) {
sLevel.server.shipObjectWorld
.teleportShip(newShip as ServerShip, ShipTeleportDataImpl(existingShip.shipToWorld.transformPosition(shipPos, Vector3d()), existingShip.transform.shipToWorldRotation, existingShip.velocity, existingShip.omega, existingShip.chunkClaimDimension, newScale = existingShip.transform.shipToWorldScaling.x(), newPosInShip = shipCenterPos))

sLevel.server.shipObjectWorld
.teleportShip(newShip as ServerShip, ShipTeleportDataImpl(Vector3d(contraptionWorldPos.x.toDouble(),contraptionWorldPos.y.toDouble(),contraptionWorldPos.z.toDouble())))
} else {
sLevel.server.shipObjectWorld
.teleportShip(newShip as ServerShip, ShipTeleportDataImpl(newPos = shipPos, newPosInShip = shipCenterPos))
}
if (shouldDisableSplitting) {
level.shipObjectWorld.loadedShips.getById(newShip.id)?.getAttachment<SplittingDisablerAttachment>()?.enableSplitting()
}

return newShip as ServerShip
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,12 @@ package org.valkyrienskies.mod.common.assembly

import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.ChunkPos
import org.joml.Vector3d
import org.valkyrienskies.core.api.ships.ServerShip
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.dimensionId
import org.valkyrienskies.mod.common.executeIf
import org.valkyrienskies.mod.common.isTickingChunk
import org.valkyrienskies.mod.common.networking.PacketRestartChunkUpdates
import org.valkyrienskies.mod.common.networking.PacketStopChunkUpdates
import org.valkyrienskies.mod.common.playerWrapper
import org.valkyrienskies.mod.common.shipObjectWorld
import org.valkyrienskies.mod.common.util.toBlockPos
import org.valkyrienskies.mod.common.util.toJOML
import org.valkyrienskies.mod.common.vsCore
import org.valkyrienskies.mod.util.relocateBlock
import org.valkyrienskies.mod.util.updateBlock

@Deprecated("Use ShipAssembler.assembleToShip instead")
@Deprecated("Use [ShipAssembler.assembleToShip] instead")
fun createNewShipWithBlocks(
centerBlock: BlockPos, blocks: DenseBlockPosSet, level: ServerLevel
): ServerShip = with(vsCore.simplePacketNetworking) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,26 @@ import org.valkyrienskies.core.apigame.hooks.PlayState.CLIENT_TITLESCREEN
import org.valkyrienskies.core.apigame.hooks.PlayState.SERVERSIDE
import org.valkyrienskies.mod.common.ValkyrienSkiesMod
import org.valkyrienskies.mod.common.shipObjectWorld
import org.valkyrienskies.mod.common.vsCore

abstract class CommonHooksImpl : CoreHooksOut {

override var enableBlockEdgeConnectivity: Boolean
get() = vsCore.hooks.enableBlockEdgeConnectivity
set(value) {}

override var enableBlockCornerConnectivity: Boolean
get() = vsCore.hooks.enableBlockCornerConnectivity
set(value) {}

override var enableConnectivity: Boolean
get() = vsCore.hooks.enableConnectivity
set(value) {}

override var enableWorldConnectivity: Boolean
get() = vsCore.hooks.enableWorldConnectivity
set(value) {}

override val playState: PlayState
get() {
if (!isPhysicalClient) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.valkyrienskies.mod.common.item

import net.minecraft.Util
import net.minecraft.core.BlockPos
import net.minecraft.core.Vec3i
import net.minecraft.network.chat.Component
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.state.BlockState
import org.joml.primitives.AABBi
import org.valkyrienskies.mod.common.assembly.ShipAssembler
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
import java.awt.TextComponent
import java.util.function.DoubleSupplier

class AreaAssemblerItem(
properties: Properties, private val scale: DoubleSupplier, private val minScaling: DoubleSupplier
) : Item(properties) {

override fun isFoil(stack: ItemStack): Boolean {
return true
}

override fun useOn(ctx: UseOnContext): InteractionResult {
val level = ctx.level as? ServerLevel ?: return super.useOn(ctx)
val blockPos = ctx.clickedPos
val blockState: BlockState = level.getBlockState(blockPos)
val item = ctx.itemInHand

if (item.item !is AreaAssemblerItem) {
return InteractionResult.FAIL
}

if (!level.isClientSide) {
if (!blockState.isAir) {
// Make a ship
val dimensionId = level.dimensionId

if (item.tag != null && item.tag!!.contains("firstPosX")) {
val firstPosX = item.tag!!.getInt("firstPosX")
val firstPosY = item.tag!!.getInt("firstPosY")
val firstPosZ = item.tag!!.getInt("firstPosZ")
if (level.shipObjectWorld.isBlockInShipyard(blockPos.x, blockPos.y, blockPos.z, dimensionId) != level.shipObjectWorld.isBlockInShipyard(firstPosX, firstPosY, firstPosZ, dimensionId)) {
ctx.player?.sendSystemMessage(Component.translatable("Cannot assemble between ship and world!"))
} else if (level.getShipObjectManagingPos(blockPos) != level.getShipObjectManagingPos(Vec3i(firstPosX, firstPosY, firstPosZ))) {
ctx.player?.sendSystemMessage(Component.translatable("Cannot assemble something between two ships!"))
} else {
val blockAABB = AABBi(blockPos.toJOML(), Vec3i(firstPosX, firstPosY, firstPosZ).toJOML())
blockAABB.correctBounds()
val blocks = ArrayList<BlockPos>()

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?.sendSystemMessage(
Component.translatable("Assembling (${blockPos.x}, ${blockPos.y}, ${blockPos.z}) to ($firstPosX, $firstPosY, $firstPosZ)!"))
ShipAssembler.assembleToShip(level, blocks, true, scale.asDouble)
}
item.tag!!.remove("firstPosX")
item.tag!!.remove("firstPosY")
item.tag!!.remove("firstPosZ")
} else {
item.tag = item.orCreateTag.apply {
putInt("firstPosX", blockPos.x)
putInt("firstPosY", blockPos.y)
putInt("firstPosZ", blockPos.z)
}
ctx.player?.sendSystemMessage(
Component.translatable("First block selected: (${blockPos.x}, ${blockPos.y}, ${blockPos.z})"))
}
}
}

return super.useOn(ctx)
}
}
Loading

0 comments on commit a13faa3

Please sign in to comment.