Skip to content

Commit

Permalink
connectors from 1.20.1 branch & bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-s168 committed May 20, 2024
1 parent eaf9443 commit e0ded94
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ object TournamentBlockEntities {

private val renderers = mutableListOf<RendererEntry<*>>()

/* ================================================================== */
val CONNECTOR = TournamentBlocks.CONNECTOR
.withBE(::ConnectorBlockEntity)
.byName ("connector")
/* ================================================================== */
val SENSOR = TournamentBlocks.SENSOR
.withBE(::SensorBlockEntity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ object TournamentBlocks {
lateinit var PROP_BIG : RegistrySupplier<PropellerBlock>
lateinit var PROP_SMALL : RegistrySupplier<PropellerBlock>
lateinit var CHUNK_LOADER : RegistrySupplier<ChunkLoaderBlock>
lateinit var CONNECTOR : RegistrySupplier<ConnectorBlock>

lateinit var EXPLOSIVE_INSTANT_SMALL : RegistrySupplier<AbstractExplosiveBlock>
lateinit var EXPLOSIVE_INSTANT_MEDIUM : RegistrySupplier<AbstractExplosiveBlock>
Expand Down Expand Up @@ -102,6 +103,7 @@ object TournamentBlocks {
)
}
CHUNK_LOADER = register("chunk_loader", ::ChunkLoaderBlock)
CONNECTOR = register("connector", ::ConnectorBlock)

EXPLOSIVE_INSTANT_SMALL = register("explosive_instant_small") { object : AbstractExplosiveBlock() {
override fun explode(level: ServerLevel, pos: BlockPos) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
package org.valkyrienskies.tournament.blockentity

import net.minecraft.core.BlockPos
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.AABB
import org.joml.Vector3d
import org.joml.Vector3dc
import org.valkyrienskies.core.api.ships.ServerShip
import org.valkyrienskies.core.api.ships.properties.ShipId
import org.valkyrienskies.core.apigame.constraints.VSAttachmentConstraint
import org.valkyrienskies.mod.common.*
import org.valkyrienskies.mod.common.util.toJOMLD
import org.valkyrienskies.mod.common.util.toMinecraft
import org.valkyrienskies.physics_api.ConstraintId
import org.valkyrienskies.tournament.TournamentBlockEntities
import org.valkyrienskies.tournament.TournamentBlocks
import org.valkyrienskies.tournament.util.extension.toBlock
import kotlin.math.min
import kotlin.math.sqrt
import kotlin.streams.asSequence

class ConnectorBlockEntity(pos: BlockPos, state: BlockState):
BlockEntity(TournamentBlockEntities.CONNECTOR.get(), pos, state)
{
var constraint: ConstraintId? = null
var constraintData: VSAttachmentConstraint? = null
var otherbesec: BlockPos? = null
var redstoneLevel = 0
var recreate = false

fun tick() {
val level = level as? ServerLevel ?: return

if (recreate) {
if (redstoneLevel == 0) {
println("restoring constraint")
constraint = level.shipObjectWorld.createNewConstraint(constraintData!!)
val other = constraintData!!.localPos1.sub(0.5, 0.5, 0.5, Vector3d()).toBlock()
val otherBe = level.getBlockEntity(other) as ConnectorBlockEntity
assert(otherBe.constraintData == null)
otherBe.constraint = constraint
otherBe.setChanged()
this.setChanged()
}
recreate = false
}

constraint?.let {
if (redstoneLevel > 0) {
disconnect()
}
return
}

if (redstoneLevel == 0) {
val currentShip = level.getShipObjectManagingPos(blockPos)
val transform = currentShip
?.transform
?.shipToWorld
?.transformPosition(blockPos.toJOMLD())
?: blockPos.toJOMLD()

val off = Vector3d(2.0)
val aabb = AABB(transform.sub(off).toMinecraft(), transform.add(off).toMinecraft())
val res = mutableListOf<Triple<ServerShip, BlockPos, ConnectorBlockEntity>>()
level.transformFromWorldToNearbyShipsAndWorld(aabb) { newbb ->
val ranged = BlockPos.betweenClosedStream(newbb).asSequence()
ranged.map { it.immutable() to level.getBlockState(it) }
.filter { (_, state) -> state.block == TournamentBlocks.CONNECTOR.get() }
.mapNotNull { (pos, _) -> level.getShipObjectManagingPos(pos)?.to(pos) }
.filter { (_, pos) -> pos != blockPos }
.map { (a, b) -> Triple(a, b, level.getBlockEntity(b) as ConnectorBlockEntity) }
.filter { (_, _, be) -> be.constraint == null && be.redstoneLevel == 0 }
.toCollection(res)
}
res.minByOrNull { sqrt(it.second.distToCenterSqr(transform.toMinecraft())) }?.let { (_, pos, be) ->
connect(pos, be)
}
}
}

private fun transform(pos: Vector3dc): Pair<ShipId, Vector3dc> {
val level = level as ServerLevel
return level
.getShipObjectManagingPos(pos)
?.let {
it.id to it.transform
.shipToWorld
.transformPosition(pos.get(Vector3d()))
}
?: (level.shipObjectWorld.dimensionToGroundBodyIdImmutable[level.dimensionId]!! to pos)
}

private fun connect(other: BlockPos, otherBe: ConnectorBlockEntity): Boolean {
val level = level as ServerLevel

val (idA, posA) = transform(blockPos.toJOMLD())
val (idB, posB) = transform(other.toJOMLD())

val cfg = VSAttachmentConstraint(
idA,
idB,
compliance,
blockPos.toJOMLD().add(0.5, 0.5, 0.5),
other.toJOMLD().add(0.5, 0.5, 0.5),
maxForce,
min(posA.distance(posB), 1.4),
)
constraintData = cfg
constraint = level.shipObjectWorld.createNewConstraint(cfg)
otherbesec = null
otherBe.constraint = constraint
otherBe.constraintData = null
otherBe.otherbesec = blockPos
otherBe.setChanged()
this.setChanged()
return constraint != null
}

fun disconnect(recursed: Boolean = false) {
val level = level as? ServerLevel ?: return
if (!recursed) {
constraintData?.let {
fun doo(pos: Vector3dc) {
val other = pos.sub(0.5, 0.5, 0.5, Vector3d()).toBlock()
val otherBe = level.getBlockEntity(other) as? ConnectorBlockEntity?
if (otherBe != this)
otherBe?.disconnect(true)
}
doo(constraintData!!.localPos0)
doo(constraintData!!.localPos1)
}
}
constraint?.let {
level.shipObjectWorld.removeConstraint(constraint!!)
constraint = null
constraintData = null
this.setChanged()
}
if (!recursed) {
otherbesec?.let {
val otherBe = level.getBlockEntity(it) as ConnectorBlockEntity
if (otherBe != this)
otherBe.disconnect(true)
}
}
}

override fun getUpdateTag(): CompoundTag {
val tag = CompoundTag()
saveAdditional(tag)
return tag
}

override fun getUpdatePacket(): ClientboundBlockEntityDataPacket? {
return ClientboundBlockEntityDataPacket.create(this)
}

override fun saveAdditional(tag: CompoundTag) {
constraint?.let {
tag.putInt("constraint", it)
constraintData?.let {
tag.putLong("id0", it.shipId0)
tag.putLong("id1", it.shipId1)

tag.putDouble("lp0x", it.localPos0.x())
tag.putDouble("lp0y", it.localPos0.y())
tag.putDouble("lp0z", it.localPos0.z())

tag.putDouble("lp1x", it.localPos1.x())
tag.putDouble("lp1y", it.localPos1.y())
tag.putDouble("lp1z", it.localPos1.z())

tag.putDouble("dist", it.fixedDistance)
}
otherbesec?.let {
tag.putInt("obx", it.x)
tag.putInt("oby", it.y)
tag.putInt("obz", it.z)
}
}
}

override fun load(tag: CompoundTag) {
constraint = null
if (tag.contains("constraint")) {
constraint = tag.getInt("constraint")

if (tag.contains("id0")) {
recreate = constraintData == null
constraintData = VSAttachmentConstraint(
tag.getLong("id0"),
tag.getLong("id1"),
compliance,
Vector3d(
tag.getDouble("lp0x"),
tag.getDouble("lp0y"),
tag.getDouble("lp0z"),
),
Vector3d(
tag.getDouble("lp1x"),
tag.getDouble("lp1y"),
tag.getDouble("lp1z"),
),
maxForce,
tag.getDouble("dist"),
)
}

if (tag.contains("obx")) {
otherbesec = BlockPos(
tag.getInt("obx"),
tag.getInt("oby"),
tag.getInt("obz"),
)
}
}
}

companion object {
private const val compliance = 1e-20
private const val maxForce = 1e10

val ticker = BlockEntityTicker<ConnectorBlockEntity> { level, _, _, be ->
if(level !is ServerLevel)
return@BlockEntityTicker

assert(level == be.level)
be.tick()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.valkyrienskies.tournament.blocks

import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.BaseEntityBlock
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.RenderShape
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.Material
import org.valkyrienskies.tournament.blockentity.ConnectorBlockEntity

class ConnectorBlock: BaseEntityBlock(
Properties.of(Material.METAL)
) {

override fun getRenderShape(blockState: BlockState): RenderShape {
return RenderShape.MODEL
}

override fun onPlace(state: BlockState, level: Level, pos: BlockPos, oldState: BlockState, isMoving: Boolean) {
super.onPlace(state, level, pos, oldState, isMoving)

if (level as? ServerLevel == null) return


val be = level.getBlockEntity(pos) as? ConnectorBlockEntity
?: return

val signal = level.getBestNeighborSignal(pos)
be.redstoneLevel = signal
}

override fun neighborChanged(
state: BlockState,
level: Level,
pos: BlockPos,
block: Block,
fromPos: BlockPos,
isMoving: Boolean
) {
super.neighborChanged(state, level, pos, block, fromPos, isMoving)

if (level as? ServerLevel == null) return

val be = level.getBlockEntity(pos) as? ConnectorBlockEntity
?: return

val signal = level.getBestNeighborSignal(pos)
be.redstoneLevel = signal
}

override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity =
ConnectorBlockEntity(pos, state)

@Suppress("UNCHECKED_CAST")
override fun <T: BlockEntity> getTicker(
level: Level,
state: BlockState,
blockEntityType: BlockEntityType<T>
): BlockEntityTicker<T> =
ConnectorBlockEntity.ticker as BlockEntityTicker<T>

@Deprecated("Deprecated in Java")
override fun onRemove(state: BlockState, level: Level, pos: BlockPos, newState: BlockState, isMoving: Boolean) {
if (level is ServerLevel) {
val be = level.getBlockEntity(pos) as? ConnectorBlockEntity
?: return

be.disconnect()
}

super.onRemove(state, level, pos, newState, isMoving)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "vs_tournament:block/connector"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"block.vs_tournament.prop_big": "Propeller (big)",
"block.vs_tournament.prop_small": "Propeller (small)",
"block.vs_tournament.chunk_loader": "Chunk Loader",
"block.vs_tournament.connector": "Connector",

"block.vs_tournament.explosive_instant_small": "Instant Explosive (small)",
"block.vs_tournament.explosive_instant_medium": "Instant Explosive (medium)",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "vs_tournament:block/connector"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"parent": "vs_tournament:block/connector"
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx4096M
# Identity
mod_name=Tournament
mod_id=vs_tournament
Tournament_version=1.1.0_beta-4
Tournament_version=1.1.0_beta-5
enabled_platforms=fabric,forge
archives_base_name=tournament
maven_group=org.valkyrienskies
Expand Down

0 comments on commit e0ded94

Please sign in to comment.