Black holes now break blocks in range
This commit is contained in:
parent
c28ff851c9
commit
c41fc2c61b
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user