Skip to content

Commit

Permalink
- relocateBlock uses vanilla blockstate rotate for compatibility
Browse files Browse the repository at this point in the history
 - relocateBlock has option to update blocks around it or not
 - updateBlock method to thoroughly update moved blocks
 - Assembly updates blocks separately after moving all of them
  • Loading branch information
copperwarrior committed Nov 12, 2022
1 parent 38e9f19 commit 9c6279b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.valkyrienskies.mod.common.playerWrapper
import org.valkyrienskies.mod.common.shipObjectWorld
import org.valkyrienskies.mod.common.util.toJOML
import org.valkyrienskies.mod.util.relocateBlock
import org.valkyrienskies.mod.util.updateBlock

fun createNewShipWithBlocks(
centerBlock: BlockPos, blocks: DenseBlockPosSet, level: ServerLevel
Expand Down Expand Up @@ -56,7 +57,20 @@ fun createNewShipWithBlocks(
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, ship)
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))
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.valkyrienskies.mod.common.item

import net.minecraft.Util
import net.minecraft.core.Direction.NORTH
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.Rotation.NONE
import net.minecraft.world.level.block.state.BlockState
import org.joml.Vector3i
import org.valkyrienskies.core.game.ChunkAllocator
Expand Down Expand Up @@ -38,7 +38,7 @@ class ShipCreatorItem(properties: Properties, private val scale: Double) : Item(
val centerPos = shipData.chunkClaim.getCenterBlockCoordinates(Vector3i()).toBlockPos()

// Move the block from the world to a ship
level.relocateBlock(blockPos, centerPos, shipData, NORTH)
level.relocateBlock(blockPos, centerPos, true, shipData, NONE)

ctx.player?.sendMessage(TextComponent("SHIPIFIED!"), Util.NIL_UUID)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package org.valkyrienskies.mod.util

import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.Direction.NORTH
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.Container
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.Rotation
import net.minecraft.world.level.block.Rotation.NONE
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.chunk.LevelChunk
import net.minecraft.world.level.chunk.LevelChunk.EntityCreationType.CHECK
import org.valkyrienskies.core.api.ServerShip
Expand All @@ -24,13 +23,14 @@ private val AIR = Blocks.AIR.defaultBlockState()
* @param toChunk
* @param to coordinate (can be local or global coord)
* @param toShip should be set when you're relocating to a ship
* @param direction Direction.NORTH is no change in direction, Direction.EAST is 90 degrees clockwise, etc.
* @param rotation Rotation.NONE is no change in direction, Rotation.CLOCKWISE_90 is 90 degrees clockwise, etc.
*/
fun relocateBlock(
fromChunk: LevelChunk, from: BlockPos, toChunk: LevelChunk, to: BlockPos, toShip: ServerShip?,
direction: Direction = NORTH
fromChunk: LevelChunk, from: BlockPos, toChunk: LevelChunk, to: BlockPos, doUpdate: Boolean, toShip: ServerShip?,
rotation: Rotation = NONE
) {
val state = fromChunk.getBlockState(from)
val oldState = fromChunk.getBlockState(from)
var state = fromChunk.getBlockState(from)
val entity = fromChunk.getBlockEntity(from)

val tag = entity?.let {
Expand All @@ -48,70 +48,60 @@ fun relocateBlock(
tag
}

rotateBlockState(state, direction)
state = state.rotate(rotation)

val level = toChunk.level

fromChunk.setBlockState(from, AIR, false)
level.sendBlockUpdated(from, state, AIR, 0)
toChunk.setBlockState(to, state, false)
level.sendBlockUpdated(to, state, AIR, 0)
level.chunkSource.lightEngine.checkBlock(from)
level.chunkSource.lightEngine.checkBlock(to)

if (doUpdate) {
updateBlock(level, from, to, state)
}

tag?.let {
val be = toChunk.getBlockEntity(to, CHECK)!!
if (be is ShipBlockEntity)
be.ship = toShip
if (be is ShipBlockEntity) be.ship = toShip

be.load(state, it)
}
}

private fun addDirection(direction1: Direction, direction2: Direction) =
Direction.from2DDataValue((direction1.get2DDataValue() + direction2.get2DDataValue()) and 3)

private fun rotateBlockState(state: BlockState, direction: Direction) {
if (direction == NORTH) return
// TODO there are prob more relevant states that need to get modified
if (state.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) {
state.setValue(
BlockStateProperties.HORIZONTAL_FACING,
addDirection(state.getValue(BlockStateProperties.HORIZONTAL_FACING), direction)
)
} else if (state.hasProperty(BlockStateProperties.FACING)) {
state.setValue(
BlockStateProperties.FACING,
addDirection(state.getValue(BlockStateProperties.FACING), direction)
)
} else if (state.hasProperty(BlockStateProperties.AXIS)) {
state.setValue(
BlockStateProperties.AXIS,
if (direction.axis == Direction.Axis.X)
if (state.getValue(BlockStateProperties.AXIS) == Direction.Axis.X)
Direction.Axis.Z
else if (state.getValue(BlockStateProperties.AXIS) == Direction.Axis.Z)
Direction.Axis.X
else
Direction.Axis.Y
else
state.getValue(BlockStateProperties.AXIS)
)
} else if (state.hasProperty(BlockStateProperties.FACING_HOPPER)) {
state.setValue(
BlockStateProperties.FACING,
addDirection(state.getValue(BlockStateProperties.FACING), direction)
)
}
/**
* Update block after relocate
*
* @param level
* @param fromPos old position coordinate
* @param toPos new position coordinate
* @param toState new blockstate at toPos
*/
fun updateBlock(level: Level, fromPos: BlockPos, toPos: BlockPos, toState: BlockState) {

level.setBlocksDirty(fromPos, toState, AIR)
level.sendBlockUpdated(fromPos, toState, AIR, 75)
//This handles the update for neighboring blocks in worldspace
AIR.updateNeighbourShapes(level, fromPos, 75 and -0x22, 512 - 1)
AIR.updateIndirectNeighbourShapes(level, fromPos, 75 and -0x22, 512 - 1)
//This updates lighting for blocks in worldspace
level.chunkSource.lightEngine.checkBlock(fromPos)

level.setBlocksDirty(toPos, AIR, toState)
level.sendBlockUpdated(toPos, AIR, toState, 75)
//This handles the update for neighboring blocks in shipspace (ladders, redstone)
toState.updateNeighbourShapes(level, toPos, 75 and -0x22, 512 - 1)
toState.updateIndirectNeighbourShapes(level, toPos, 75 and -0x22, 512 - 1)
//This updates lighting for blocks in shipspace
level.chunkSource.lightEngine.checkBlock(toPos)
}

/**
* Relocate block
*
* @param from coordinate (can be local or global coord)
* @param to coordinate (can be local or global coord)
* @param doUpdate update blocks after moving
* @param toShip should be set when you're relocating to a ship
* @param direction Direction.NORTH is no change in direction, Direction.EAST is 90 degrees clockwise, etc.
* @param rotation Rotation.NONE is no change in direction, Rotation.CLOCKWISE_90 is 90 degrees clockwise, etc.
*/
fun Level.relocateBlock(from: BlockPos, to: BlockPos, toShip: ServerShip?, direction: Direction) =
relocateBlock(getChunkAt(from), from, getChunkAt(to), to, toShip, direction)
fun Level.relocateBlock(from: BlockPos, to: BlockPos, doUpdate: Boolean, toShip: ServerShip?, rotation: Rotation) =
relocateBlock(getChunkAt(from), from, getChunkAt(to), to, doUpdate, toShip, rotation)

0 comments on commit 9c6279b

Please sign in to comment.