Black holes now break blocks in range

This commit is contained in:
DBotThePony 2022-01-11 11:45:54 +07:00
parent c28ff851c9
commit c41fc2c61b
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -20,11 +20,13 @@ import net.minecraft.world.level.levelgen.structure.BoundingBox
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec3
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.BlockBlackHole
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue.Companion.queueForLevel
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.matter.MatterRegistry
import ru.dbotthepony.mc.otm.set
import kotlin.math.pow
import kotlin.math.roundToInt
import kotlin.math.sqrt
class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(Registry.BlockEntities.BLACK_HOLE, p_155229_, p_155230_) {
@ -245,14 +247,111 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn
if (level.random.nextDouble() < 0.01 * 0.05 * (1 / gravitationStrength)) {
this.mass += HAWKING_MASS_LOSE_STEP
}
if (gravitationStrength > 0.4f) {
val sphere = getSphericalShape((gravitationStrength * 6.0).roundToInt())
if (sphere.size != lastSphereSizeOuter) {
lastSphereSizeOuter = sphere.size
sphereIndexOuter = 0
}
var iterations = 0
while (iterations < ITERATIONS) {
iterations++
val pos = sphere[sphereIndexOuter] + blockPos
sphereIndexOuter = (sphereIndexOuter + 1) % lastSphereSizeOuter
if (sphereIndexOuter == 0 && lastSphereSizeOuter <= ITERATIONS)
break
val getBlock = level.getBlockState(pos)
if (!getBlock.isAir && getBlock.block !is BlockBlackHole) {
val speed = getBlock.getDestroySpeed(level, pos)
val eResist = try {
getBlock.getExplosionResistance(level, pos, null)
} catch (err: Throwable) {
getBlock.block.getExplosionResistance()
// Потому что возможно какой-либо мод не ожидает что Explosion == null
// особенно учитывая что интерфейс IForgeBlock не имеет @ParamsAreNonnullByDefault
// и аргумент не помечен как @Nullable
// тем самым имеет тип Explosion! который указывается как Explosion? .. Explosion!!
}
var strengthLinear = sqrt(blockPos.distSqr(pos))
if (strengthLinear < gravitationStrength * 1.1) {
strengthLinear /= 4.0
}
if (speed >= 0f && (speed * 2f).coerceAtLeast(eResist / 3f) < gravitationStrength * (8.0 / strengthLinear)) {
Block.dropResources(getBlock, level, pos, level.getBlockEntity(pos))
getBlock.block.destroy(level, pos, getBlock)
level.setBlock(pos, getBlock.fluidState.createLegacyBlock(), Block.UPDATE_ALL)
}
}
}
}
}
private var lastSphereSizeOuter = 0
private var sphereIndexOuter = 0
init {
mass = mass
}
companion object {
const val ITERATIONS = 30_000
val BASELINE_MASS = Fraction(1_000)
val HAWKING_MASS_LOSE_STEP = Fraction("-0.1")
private val blockShapeCache = HashMap<Int, Array<BlockPos>>()
private fun getSphericalShape(size: Int): Array<BlockPos> {
return blockShapeCache.computeIfAbsent(size) {
val result = ArrayList<BlockPos>((it * it * it * Math.PI * (4.0 / 3.0)).toInt() + 16)
for (x in -it .. it) {
for (y in -it .. it) {
for (z in -it .. it) {
val dist = sqrt(x * x.toDouble() + y * y.toDouble() + z * z.toDouble())
if (dist <= size && dist != 0.0) {
result.add(BlockPos(x, y, z))
}
}
}
}
val arr = result.toTypedArray()
arr.sortWith { a, b ->
val xa = a.x
val ya = a.y
val za = a.z
val distA = sqrt(xa * xa.toDouble() + ya * ya.toDouble() + za * za.toDouble())
val xb = b.x
val yb = b.y
val zb = b.z
val distB = sqrt(xb * xb.toDouble() + yb * yb.toDouble() + zb * zb.toDouble())
if (distA == distB) {
return@sortWith 0
} else if (distA > distB) {
return@sortWith 1
} else {
return@sortWith -1
}
}
return@computeIfAbsent arr
}
}
}
}