Actual block rotation enum impl, with left/right and front/back

This commit is contained in:
DBotThePony 2023-01-30 15:36:25 +07:00
parent 192144cc27
commit 25630a7924
Signed by: DBot
GPG Key ID: DCC23B5715498507
17 changed files with 170 additions and 144 deletions

View File

@ -9,7 +9,6 @@ import net.minecraftforge.client.model.generators.BlockModelBuilder
import net.minecraftforge.client.model.generators.ConfiguredModel
import net.minecraftforge.client.model.generators.ModelFile
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
import ru.dbotthepony.mc.otm.core.registryName
@ -217,16 +216,16 @@ fun addDecorativeData(blockStateProvider: MatteryBlockStateProvider, itemModelPr
blockStateProvider.getVariantBuilder(MBlocks.LABORATORY_LAMP).forAllStates {
return@forAllStates ConfiguredModel.builder()
.modelFile(if (it[BlockStateProperties.LIT]) labLampOn!! else labLampOff!!)
.rotationX(it[BlockRotationFreedom.TWO.property].primary.toXRotBlockstate())
.rotationY(it[BlockRotationFreedom.TWO.property].primary.toYRotBlockstate())
.rotationX(it[BlockRotationFreedom.TWO.property].front.toXRotBlockstate())
.rotationY(it[BlockRotationFreedom.TWO.property].front.toYRotBlockstate())
.build()
}
blockStateProvider.getVariantBuilder(MBlocks.LABORATORY_LAMP_INVERTED).forAllStates {
return@forAllStates ConfiguredModel.builder()
.modelFile(if (it[BlockStateProperties.LIT]) labLampOn!! else labLampOff!!)
.rotationX(it[BlockRotationFreedom.TWO.property].primary.toXRotBlockstate())
.rotationY(it[BlockRotationFreedom.TWO.property].primary.toYRotBlockstate())
.rotationX(it[BlockRotationFreedom.TWO.property].front.toXRotBlockstate())
.rotationY(it[BlockRotationFreedom.TWO.property].front.toYRotBlockstate())
.build()
}
}

View File

@ -6,9 +6,7 @@ import net.minecraft.world.level.block.state.properties.Property
fun Direction.toYRotBlockstate(): Int {
return when (this) {
Direction.DOWN -> 0
Direction.UP -> 0
Direction.NORTH -> 0
Direction.DOWN, Direction.UP, Direction.NORTH -> 0
Direction.SOUTH -> 180
Direction.WEST -> -90
Direction.EAST -> 90
@ -17,8 +15,7 @@ fun Direction.toYRotBlockstate(): Int {
fun Direction.toYRotBlockstateInv(): Int {
return when (this) {
Direction.DOWN -> 0
Direction.UP -> 0
Direction.DOWN, Direction.UP -> 0
Direction.NORTH -> 180
Direction.SOUTH -> 0
Direction.WEST -> 90

View File

@ -5,7 +5,6 @@ import net.minecraft.world.level.block.Block
import net.minecraftforge.client.model.generators.BlockStateProvider
import net.minecraftforge.data.event.GatherDataEvent
import ru.dbotthepony.mc.otm.block.tech.BatteryBankBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
import ru.dbotthepony.mc.otm.datagen.DataGen
import ru.dbotthepony.mc.otm.datagen.toYRotBlockstate
@ -28,13 +27,13 @@ open class BatteryBankProvider(event: GatherDataEvent) : BlockStateProvider(even
val battery_bank = models().getExistingFile(ResourceLocation("overdrive_that_matters:block/$block"))
BlockRotationFreedom.ONE.possibleValues.forEach {
part().modelFile(battery_bank).rotationY(it.primary.toYRotBlockstate()).addModel().condition(
part().modelFile(battery_bank).rotationY(it.front.toYRotBlockstate()).addModel().condition(
BlockRotationFreedom.ONE.property, it)
for (i in 0 .. 11) {
part().modelFile(
models().getExistingFile(ResourceLocation("overdrive_that_matters:$batteryPath$i"))
).rotationY(it.primary.toYRotBlockstate()).addModel()
).rotationY(it.front.toYRotBlockstate()).addModel()
.condition(BlockRotationFreedom.ONE.property, it)
.condition(BatteryBankBlock.BATTERY_SLOTS_PROPS[i], true)
}

View File

@ -7,7 +7,6 @@ import net.minecraftforge.client.model.generators.ConfiguredModel
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
@ -39,7 +38,7 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
with(provider.getMultipartBuilder(MBlocks.PHANTOM_ATTRACTOR)) {
for (dir in BlockRotationFreedom.ONE.possibleValues) {
part().modelFile(provider.models().getExistingFile(modLocation("block/${MNames.PHANTOM_ATTRACTOR}")))
.rotationY(dir.primary.toYRotBlockstate())
.rotationY(dir.front.toYRotBlockstate())
.addModel()
.condition(BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER)
.condition(BlockRotationFreedom.ONE.property, dir)
@ -51,7 +50,7 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
for (dir in BlockRotationFreedom.ONE.possibleValues) {
for (enum in WorkerState.SEMI_WORKER_STATE.possibleValues) {
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_bottler_${enum.name.lowercase()}")))
.rotationY(dir.primary.toYRotBlockstate())
.rotationY(dir.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.ONE.property, dir)
.condition(WorkerState.WORKER_STATE, enum)
@ -62,14 +61,14 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
for (dir in BlockRotationFreedom.ONE.possibleValues) {
for (enum in MatterBottlerBlock.SLOT_PROPERTIES) {
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_bottler_${enum.name}_open")))
.rotationY(dir.primary.toYRotBlockstate())
.rotationY(dir.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.ONE.property, dir)
.condition(enum, false)
.end()
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_bottler_${enum.name}_closed")))
.rotationY(dir.primary.toYRotBlockstate())
.rotationY(dir.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.ONE.property, dir)
.condition(enum, true)
@ -99,7 +98,7 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
OverdriveThatMatters.MOD_ID, "${crate.registryName!!.path}_${if (it.getValue(
CargoCrateBlock.IS_OPEN)) "open" else "closed"}")
))
.rotationY(it.getValue(BlockRotationFreedom.ONE.property).primary.toYRotBlockstate())
.rotationY(it.getValue(BlockRotationFreedom.ONE.property).front.toYRotBlockstate())
.buildLast()
)
}
@ -108,17 +107,17 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
with(provider.getMultipartBuilder(MBlocks.STORAGE_BUS)) {
for (dir in BlockRotationFreedom.TWO.possibleValues) {
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "storage_bus")))
.rotationX(dir.primary.toXRotBlockstate())
.rotationY(dir.primary.toYRotBlockstate())
.rotationX(dir.front.toXRotBlockstate())
.rotationY(dir.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.TWO.property, dir)
.end()
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "storage_cable_connection")))
.rotationX(dir.primary.toXRotBlockstateInv())
.rotationY(dir.primary.toYRotBlockstateInv())
.rotationX(dir.front.toXRotBlockstateInv())
.rotationY(dir.front.toYRotBlockstateInv())
.addModel()
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.primary]!!, true)
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true)
.end()
}
@ -129,17 +128,17 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
with(provider.getMultipartBuilder(MBlocks.STORAGE_IMPORTER)) {
for (dir in BlockRotationFreedom.TWO.possibleValues) {
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "storage_importer")))
.rotationX(dir.primary.toXRotBlockstate())
.rotationY(dir.primary.toYRotBlockstate())
.rotationX(dir.front.toXRotBlockstate())
.rotationY(dir.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.TWO.property, dir)
.end()
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "storage_cable_connection")))
.rotationX(dir.primary.toXRotBlockstateInv())
.rotationY(dir.primary.toYRotBlockstateInv())
.rotationX(dir.front.toXRotBlockstateInv())
.rotationY(dir.front.toYRotBlockstateInv())
.addModel()
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.primary]!!, true)
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true)
.end()
}
@ -150,17 +149,17 @@ fun addBlockStates(provider: MatteryBlockStateProvider) {
with(provider.getMultipartBuilder(MBlocks.STORAGE_EXPORTER)) {
for (dir in BlockRotationFreedom.TWO.possibleValues) {
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "storage_exporter")))
.rotationX(dir.primary.toXRotBlockstate())
.rotationY(dir.primary.toYRotBlockstate())
.rotationX(dir.front.toXRotBlockstate())
.rotationY(dir.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.TWO.property, dir)
.end()
part().modelFile(provider.models().getExistingFile(ResourceLocation(OverdriveThatMatters.MOD_ID, "storage_cable_connection")))
.rotationX(dir.primary.toXRotBlockstateInv())
.rotationY(dir.primary.toYRotBlockstateInv())
.rotationX(dir.front.toXRotBlockstateInv())
.rotationY(dir.front.toYRotBlockstateInv())
.addModel()
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.primary]!!, true)
.condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true)
.end()
}

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.datagen.blocks
import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.block.tech.EnergyCounterBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.block.matter.PatternStorageBlock
import ru.dbotthepony.mc.otm.block.storage.DriveViewerBlock
@ -17,7 +16,7 @@ fun addComplexBlockStates(provider: MatteryBlockStateProvider) {
for (facing in BlockRotationFreedom.ONE.possibleValues) {
part()
.modelFile(provider.models().getExistingFile(ResourceLocation(MOD_ID, "block/drive_viewer_drive_part")))
.rotationY(facing.primary.toYRotBlockstate())
.rotationY(facing.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.ONE.property, facing)
.condition(DriveViewerBlock.DRIVE_PRESENT, true)
@ -25,7 +24,7 @@ fun addComplexBlockStates(provider: MatteryBlockStateProvider) {
for (workState in WorkerState.SEMI_WORKER_STATE.possibleValues) {
part()
.modelFile(provider.models().getExistingFile(ResourceLocation(MOD_ID, "block/drive_viewer_${workState.name.lowercase()}")))
.rotationY(facing.primary.toYRotBlockstate())
.rotationY(facing.front.toYRotBlockstate())
.addModel()
.condition(WorkerState.SEMI_WORKER_STATE, workState)
.condition(BlockRotationFreedom.ONE.property, facing)
@ -37,14 +36,14 @@ fun addComplexBlockStates(provider: MatteryBlockStateProvider) {
for (facing in BlockRotationFreedom.ONE.possibleValues) {
part()
.modelFile(provider.models().getExistingFile(ResourceLocation(MOD_ID, "block/pattern_storage")))
.rotationY(facing.primary.toYRotBlockstate())
.rotationY(facing.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.ONE.property, facing)
for (i in 0 .. 7) {
part()
.modelFile(provider.models().getExistingFile(ResourceLocation(MOD_ID, "block/pattern/model$i")))
.rotationY(facing.primary.toYRotBlockstate())
.rotationY(facing.front.toYRotBlockstate())
.addModel()
.condition(BlockRotationFreedom.ONE.property, facing)
.condition(PatternStorageBlock.PATTERN_STORAGE_DISKS_PROPS[i], true)

View File

@ -6,7 +6,6 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.client.model.generators.BlockStateProvider
import net.minecraftforge.client.model.generators.ConfiguredModel
import net.minecraftforge.data.event.GatherDataEvent
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
import ru.dbotthepony.mc.otm.datagen.DataGen
@ -23,17 +22,17 @@ private fun initialTransform(it: BlockState, modelPath: String, builder: Configu
@Suppress("NAME_SHADOWING") var modelPath = modelPath
it.getValueNullable(BlockRotationFreedom.ONE.property)?.let {
builder.rotationY(it.primary.toYRotBlockstate())
builder.rotationY(it.front.toYRotBlockstate())
}
it.getValueNullable(BlockRotationFreedom.TWO.property)?.let {
builder.rotationY(it.primary.toYRotBlockstate())
builder.rotationX(it.primary.toXRotBlockstate())
builder.rotationY(it.front.toYRotBlockstate())
builder.rotationX(it.front.toXRotBlockstate())
}
it.getValueNullable(BlockRotationFreedom.THREE.property)?.let {
builder.rotationY(it.primary.toYRotBlockstate() + (it.secondary?.toYRotBlockstate() ?: 0))
builder.rotationX(it.primary.toXRotBlockstate())
builder.rotationY(it.front.toYRotBlockstate() + it.top.toYRotBlockstate())
builder.rotationX(it.front.toXRotBlockstate())
}
it.getValueNullable(WorkerState.WORKER_STATE)?.let {

View File

@ -92,7 +92,7 @@ abstract class MatteryBlock @JvmOverloads constructor(
yd += ny * 0.5
zd += nz * 0.5
when (direction.primary) {
when (direction.front) {
Direction.DOWN, Direction.UP -> {
xd += random.nextDouble() - 0.5
zd += random.nextDouble() - 0.5

View File

@ -24,12 +24,12 @@ abstract class RotatableMatteryBlock @JvmOverloads constructor(properties: Prope
return when (val freedom = rotationFreedom()) {
BlockRotationFreedom.ONE -> defaultBlockState().setValue(
freedom.property,
BlockRotation.of(if (faceToPlayer(context)) context.horizontalDirection.opposite else context.horizontalDirection)
freedom.of(if (faceToPlayer(context)) context.horizontalDirection.opposite else context.horizontalDirection)
)
BlockRotationFreedom.TWO -> defaultBlockState().setValue(
freedom.property,
BlockRotation.of(if (faceToPlayer(context)) context.nearestLookingDirection.opposite else context.nearestLookingDirection)
freedom.of(if (faceToPlayer(context)) context.nearestLookingDirection.opposite else context.nearestLookingDirection)
)
BlockRotationFreedom.THREE -> {
@ -42,9 +42,11 @@ abstract class RotatableMatteryBlock @JvmOverloads constructor(properties: Prope
defaultBlockState().setValue(
freedom.property,
BlockRotation.ofSafe(primary, secondary)
freedom.of(primary, secondary)
)
}
BlockRotationFreedom.FOUR -> TODO("Can't rotate with four rotation freedom yet")
}
}

View File

@ -18,7 +18,7 @@ class EngineBlock : RotatableMatteryBlock(Properties.of(Material.METAL, DyeColor
}
private val shapes = getShapeForEachState {
BlockShapes.ENGINE.rotateInv(it[rotationProperty].primary).computeShape()
BlockShapes.ENGINE.rotateInv(it[rotationProperty].front).computeShape()
}
override fun getShape(

View File

@ -23,7 +23,7 @@ class HoloSignBlock : RotatableMatteryBlock(), EntityBlock {
}
private val shapes = getShapeForEachState {
BlockShapes.HOLO_SIGN.rotateInv(it[rotationProperty].primary).computeShape()
BlockShapes.HOLO_SIGN.rotateInv(it[rotationProperty].front).computeShape()
}
override fun getShape(

View File

@ -20,7 +20,6 @@ import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.IItemHandler
import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.AbstractStorageImportExport.Companion.FILTER_KEY
import ru.dbotthepony.mc.otm.capability.MatteryCapability
@ -32,7 +31,6 @@ import ru.dbotthepony.mc.otm.core.math.getCapability
import ru.dbotthepony.mc.otm.core.math.isPositive
import ru.dbotthepony.mc.otm.core.math.isZero
import ru.dbotthepony.mc.otm.core.math.plus
import ru.dbotthepony.mc.otm.core.math.unaryMinus
import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.graph.Graph6Node
@ -113,7 +111,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
private var valid = true
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
return if (valid && cap === MatteryCapability.STORAGE_NODE && side != blockState.getValue(BlockRotationFreedom.TWO.property).primary) {
return if (valid && cap === MatteryCapability.STORAGE_NODE && side != blockState.getValue(BlockRotationFreedom.TWO.property).front) {
cell.get().cast()
} else super.getCapability(cap, side)
}

View File

@ -19,7 +19,6 @@ import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.IItemHandler
import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
@ -75,7 +74,7 @@ abstract class AbstractStorageImportExport<T>(
private var valid = true
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
return if (valid && cap === MatteryCapability.STORAGE_NODE && side != blockState.getValue(BlockRotationFreedom.TWO.property).primary) {
return if (valid && cap === MatteryCapability.STORAGE_NODE && side != blockState.getValue(BlockRotationFreedom.TWO.property).front) {
cell.get().cast()
} else super.getCapability(cap, side)
}
@ -114,7 +113,7 @@ abstract class AbstractStorageImportExport<T>(
protected val target by lazy {
object : BESubscribeList<T>(this@AbstractStorageImportExport, targetCapability) {
override fun test(t: Direction): Boolean {
return t == -this@AbstractStorageImportExport.blockState.getValue(BlockRotationFreedom.TWO.property).primary
return t == -this@AbstractStorageImportExport.blockState.getValue(BlockRotationFreedom.TWO.property).front
}
}
}
@ -179,7 +178,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
}
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (valid && cap == ForgeCapabilities.ITEM_HANDLER && side == blockState.rotationTwo.primary) {
if (valid && cap == ForgeCapabilities.ITEM_HANDLER && side == blockState.rotationTwo.front) {
return resolverItemHandler.cast()
}

View File

@ -11,11 +11,7 @@ import net.minecraft.world.phys.shapes.VoxelShape
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.properties.EnumProperty
import ru.dbotthepony.mc.otm.block.MatteryBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.core.math.BlockRotation
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
@ -32,7 +28,7 @@ class MatterPanelBlock : RotatableMatteryBlock(), EntityBlock {
registerDefaultState(getStateDefinition().any().setValue(BlockRotationFreedom.TWO.property, BlockRotation.SOUTH))
shapes = getShapeForEachState {
when (it.rotationTwo.primary) {
when (it.rotationTwo.front) {
Direction.NORTH -> Shapes.box(
0.0,
0.0,

View File

@ -213,7 +213,7 @@ class BlockGravitationStabilizerLens : RotatableMatteryBlock(props) {
}
fun getBoundingBlockPos(blockState: BlockState, blockPos: BlockPos): BlockPos {
return blockPos + blockState.getValue(BlockRotationFreedom.TWO.property).opposite.normal
return blockPos + blockState.getValue(BlockRotationFreedom.TWO.property).front.opposite.normal
}
private val SHAPES = arrayOf(

View File

@ -8,12 +8,13 @@ import net.minecraft.world.level.block.Rotation
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ICapabilityProvider
import net.minecraftforge.common.util.LazyOptional
import java.util.EnumMap
internal inline val Direction.blockRotation
get() = BlockRotation.of(this)
fun <T> ICapabilityProvider.getCapability(capability: Capability<T>, side: BlockRotation?): LazyOptional<T> {
return getCapability(capability, side?.primary)
return getCapability(capability, side?.front)
}
operator fun Vec3i.plus(other: BlockRotation): Vec3i {
@ -25,15 +26,18 @@ operator fun BlockPos.plus(other: BlockRotation): BlockPos {
}
/**
* [secondary] clarifies about block's top facing direction, NOT bottom
* [top] clarifies about block's top facing direction, NOT bottom
*/
enum class BlockRotation(val primary: Direction, val secondary: Direction?) : StringRepresentable {
enum class BlockRotation(
val front: Direction,
val top: Direction,
) : StringRepresentable {
DOWN(Direction.DOWN, Direction.NORTH),
UP(Direction.UP, Direction.NORTH),
NORTH(Direction.NORTH, null),
SOUTH(Direction.SOUTH, null),
WEST(Direction.WEST, null),
EAST(Direction.EAST, null),
NORTH(Direction.NORTH, Direction.UP),
SOUTH(Direction.SOUTH, Direction.UP),
WEST(Direction.WEST, Direction.UP),
EAST(Direction.EAST, Direction.UP),
DOWN_SOUTH(Direction.DOWN, Direction.SOUTH),
DOWN_WEST(Direction.DOWN, Direction.WEST),
@ -41,7 +45,43 @@ enum class BlockRotation(val primary: Direction, val secondary: Direction?) : St
UP_SOUTH(Direction.UP, Direction.SOUTH),
UP_WEST(Direction.UP, Direction.WEST),
UP_EAST(Direction.UP, Direction.EAST);
UP_EAST(Direction.UP, Direction.EAST),
/**
* This rotation is impossible to achieve using blockstates because blockstate def can't rotate models in XY plane (z axis)
*/
NORTH_DOWN(Direction.NORTH, Direction.DOWN),
/**
* This rotation is impossible to achieve using blockstates because blockstate def can't rotate models in XY plane (z axis)
*/
SOUTH_DOWN(Direction.SOUTH, Direction.DOWN),
/**
* This rotation is impossible to achieve using blockstates because blockstate def can't rotate models in XY plane (z axis)
*/
WEST_DOWN(Direction.WEST, Direction.DOWN),
/**
* This rotation is impossible to achieve using blockstates because blockstate def can't rotate models in XY plane (z axis)
*/
EAST_DOWN(Direction.EAST, Direction.DOWN),
;
val right: Direction
init {
val crossproduct = front.normal.cross(top.normal)
right = Direction.values().first { it.normal == crossproduct }
}
val left: Direction = right.opposite
val bottom: Direction = top.opposite
val back: Direction = front.opposite
operator fun component1() = front
operator fun component2() = top
operator fun component3() = left
val lowercaseName = name.lowercase()
@ -50,7 +90,7 @@ enum class BlockRotation(val primary: Direction, val secondary: Direction?) : St
}
fun rotate(by: Rotation): BlockRotation {
return of(by.rotate(primary), secondary)
return of(by.rotate(front), top)
}
operator fun times(other: Int): Vec3i {
@ -72,8 +112,8 @@ enum class BlockRotation(val primary: Direction, val secondary: Direction?) : St
operator fun unaryMinus() = opposite
// more performant
val opposite by lazy { of(primary.opposite, secondary?.opposite) }
val normal: Vec3i get() = primary.normal
val opposite by lazy { of(front.opposite, top.opposite) }
val normal: Vec3i get() = front.normal
companion object {
@JvmStatic
@ -88,77 +128,26 @@ enum class BlockRotation(val primary: Direction, val secondary: Direction?) : St
}
}
@JvmStatic
fun of(primary: Direction, secondary: Direction?): BlockRotation {
return when (primary) {
Direction.NORTH -> {
require(secondary == null) { "Impossible direction: $primary - $secondary" }
NORTH
}
private val mapped = EnumMap<Direction, EnumMap<Direction, BlockRotation>>(Direction::class.java)
Direction.SOUTH -> {
require(secondary == null) { "Impossible direction: $primary - $secondary" }
SOUTH
}
Direction.WEST -> {
require(secondary == null) { "Impossible direction: $primary - $secondary" }
WEST
}
Direction.EAST -> {
require(secondary == null) { "Impossible direction: $primary - $secondary" }
EAST
}
Direction.UP -> {
when (secondary) {
null -> UP
Direction.SOUTH -> UP_SOUTH
Direction.WEST -> UP_WEST
Direction.EAST -> UP_EAST
else -> throw IllegalArgumentException("Impossible direction: $primary - $secondary")
}
}
Direction.DOWN -> {
when (secondary) {
null -> DOWN
Direction.SOUTH -> DOWN_SOUTH
Direction.WEST -> DOWN_WEST
Direction.EAST -> DOWN_EAST
else -> throw IllegalArgumentException("Impossible direction: $primary - $secondary")
}
}
init {
for (value in values()) {
val (front, top) = value
mapped.computeIfAbsent(front) { EnumMap(Direction::class.java) }.put(top, value)
}
}
@JvmStatic
fun ofSafe(primary: Direction, secondary: Direction?): BlockRotation {
return when (primary) {
Direction.NORTH -> NORTH
Direction.SOUTH -> SOUTH
Direction.WEST -> WEST
Direction.EAST -> EAST
fun of(front: Direction, top: Direction?): BlockRotation {
val f = mapped[front]!!
return f[top ?: (if (front == Direction.DOWN || front == Direction.UP) Direction.NORTH else Direction.UP)] ?: throw IllegalArgumentException("Impossible block rotation: $front - $top")
}
Direction.UP -> {
when (secondary) {
Direction.SOUTH -> UP_SOUTH
Direction.WEST -> UP_WEST
Direction.EAST -> UP_EAST
else -> UP
}
}
Direction.DOWN -> {
when (secondary) {
Direction.SOUTH -> DOWN_SOUTH
Direction.WEST -> DOWN_WEST
Direction.EAST -> DOWN_EAST
else -> DOWN
}
}
}
@JvmStatic
fun ofSafe(front: Direction, top: Direction?): BlockRotation {
val f = mapped[front]!!
val computeTop = if (front == Direction.DOWN || front == Direction.UP) Direction.NORTH else Direction.UP
return f[top ?: computeTop] ?: f[computeTop] ?: f.values.first()
}
}
}

View File

@ -4,14 +4,15 @@ import net.minecraft.core.Direction
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.properties.EnumProperty
import ru.dbotthepony.mc.otm.core.get
import java.util.EnumMap
internal inline val BlockState.rotationOne: BlockRotation get() = this[BlockRotationFreedom.ONE.property]
internal inline val BlockState.rotationTwo: BlockRotation get() = this[BlockRotationFreedom.TWO.property]
internal inline val BlockState.rotationThree: BlockRotation get() = this[BlockRotationFreedom.THREE.property]
internal inline val BlockState.facingOne: Direction get() = this[BlockRotationFreedom.ONE.property].primary
internal inline val BlockState.facingTwo: Direction get() = this[BlockRotationFreedom.TWO.property].primary
internal inline val BlockState.facingThree: Direction get() = this[BlockRotationFreedom.THREE.property].primary
internal inline val BlockState.facingOne: Direction get() = this[BlockRotationFreedom.ONE.property].front
internal inline val BlockState.facingTwo: Direction get() = this[BlockRotationFreedom.TWO.property].front
internal inline val BlockState.facingThree: Direction get() = this[BlockRotationFreedom.THREE.property].front
enum class BlockRotationFreedom(vararg values: BlockRotation) {
ONE(
@ -41,8 +42,57 @@ enum class BlockRotationFreedom(vararg values: BlockRotation) {
BlockRotation.UP_SOUTH,
BlockRotation.UP_WEST,
BlockRotation.UP_EAST,
),
/**
* These rotations are impossible to achieve using blockstates because blockstate def can't rotate models in XY plane (z axis)
*/
FOUR(
BlockRotation.DOWN,
BlockRotation.UP,
BlockRotation.NORTH,
BlockRotation.SOUTH,
BlockRotation.WEST,
BlockRotation.EAST,
BlockRotation.DOWN_SOUTH,
BlockRotation.DOWN_WEST,
BlockRotation.DOWN_EAST,
BlockRotation.UP_SOUTH,
BlockRotation.UP_WEST,
BlockRotation.UP_EAST,
BlockRotation.NORTH_DOWN,
BlockRotation.SOUTH_DOWN,
BlockRotation.WEST_DOWN,
BlockRotation.EAST_DOWN,
);
val possibleValues: Collection<BlockRotation> get() = property.possibleValues
val property: EnumProperty<BlockRotation> = EnumProperty.create("facing", BlockRotation::class.java, *values)
private val oneDirection = EnumMap<Direction, BlockRotation>(Direction::class.java)
private val twoDirection = EnumMap<Direction, EnumMap<Direction, BlockRotation>>(Direction::class.java)
init {
for (direction in Direction.values()) {
oneDirection[direction] = possibleValues.firstOrNull { it.front == direction }
?: possibleValues.first()
val second = EnumMap<Direction, BlockRotation>(Direction::class.java)
twoDirection[direction] = second
for (direction2 in Direction.values()) {
second[direction2] = possibleValues.firstOrNull { it.front == direction && it.top == direction2 }
?: possibleValues.firstOrNull { it.front == direction }
?: possibleValues.first()
}
}
}
fun of(front: Direction): BlockRotation {
return oneDirection[front]!!
}
fun of(front: Direction, top: Direction = Direction.UP): BlockRotation {
return twoDirection[front]!![top]!!
}
}

View File

@ -648,7 +648,7 @@ fun PoseStack.rotateWithBlockFacing(rotation: Direction, clarifyingAxis: Directi
}
fun PoseStack.rotateWithBlockFacing(rotation: BlockRotation): PoseStack {
return rotateWithBlockFacing(rotation = rotation.primary, clarifyingAxis = rotation.secondary)
return rotateWithBlockFacing(rotation = rotation.front, clarifyingAxis = rotation.top)
}
fun PoseStack.rotateYDegrees(rotation: Float): PoseStack {