diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt index 41e9360d7..917d02b53 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlackHoleBlockEntity.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.block.entity.blackhole +import it.unimi.dsi.fastutil.objects.ObjectArraySet import net.minecraft.client.Minecraft import net.minecraft.core.BlockPos import net.minecraft.nbt.CompoundTag @@ -28,7 +29,6 @@ import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.plus import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MItems -import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.core.math.getSphericalBlockPositions import ru.dbotthepony.mc.otm.core.nbt.map import ru.dbotthepony.mc.otm.core.nbt.set @@ -36,13 +36,17 @@ import ru.dbotthepony.mc.otm.matter.MatterManager import ru.dbotthepony.mc.otm.registry.MDamageTypes import ru.dbotthepony.mc.otm.registry.MatteryDamageSource import ru.dbotthepony.mc.otm.triggers.BlackHoleTrigger -import java.util.LinkedList import kotlin.math.pow import kotlin.math.roundToInt import kotlin.math.sqrt class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.BLACK_HOLE, p_155229_, p_155230_) { var mass by synchronizer.fraction(BASELINE_MASS, setter = setter@{ mass, field, setByRemote -> + if (setByRemote) { + field.write(mass) + return@setter + } + if (mass <= Decimal.ZERO) { collapse() return@setter @@ -50,77 +54,41 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery field.write(mass) setChanged() - var massForDiv = mass - - when (if (level?.isClientSide == false) stabilizers.size else stabilizerClientCount) { - 1 -> {massForDiv /= 4} - 2 -> {massForDiv /= 16} - 3 -> {massForDiv /= 64} - 4 -> {massForDiv /= 512} - 5 -> {massForDiv /= 2048} - 6 -> {massForDiv /= 16384} - } - - gravitationStrength = sqrt(massForDiv.div(BASELINE_MASS).toDouble()).coerceIn(0.2, 40.0) - - affectedBounds = BoundingBox( - (-30 * gravitationStrength).toInt(), - (-30 * gravitationStrength).toInt(), - (-30 * gravitationStrength).toInt(), - (30 * gravitationStrength).toInt(), - (30 * gravitationStrength).toInt(), - (30 * gravitationStrength).toInt() - ).moved( - blockPos.x, blockPos.y, blockPos.z - ) - - affectedBoundsAABB = AABB.of(affectedBounds) + updateGravStrength() }) - override fun getRenderBoundingBox(): AABB { - return AABB(blockPos.offset(-GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE), blockPos.offset( - GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE)) - } - - var gravitationStrength = 1.0 + var gravitationStrength by synchronizer.double(1.0).property + private set + var affectedBounds = BoundingBox(0, 0, 0, 1, 1, 1) + private set + var affectedBoundsAABB: AABB = AABB.of(affectedBounds) private set - private var suppressUpdates = true - var spinDirection = false + var spinDirection by synchronizer.bool().property + private var lastSphereSizeOuter = 0 + private var sphereIndexOuter = 0 private var sleepTicks = 4 + private val stabilizers = ObjectArraySet(6) + + init { + updateGravStrength() + } override fun setLevel(level: Level) { super.setLevel(level) sleepTicks = 4 } - private fun updateMass() { - mass = mass - } - - private val stabilizers = LinkedList() - private var stabilizerClientCount by synchronizer.int(setter = setter@{ value, field, setByRemote -> - field.write(value) - - if (setByRemote) { - updateMass() - } - }).property - fun stabilizerAttached(stabilizer: GravitationStabilizerBlockEntity) { - if (stabilizer in stabilizers) - return - - stabilizers.add(stabilizer) - mass = mass - stabilizerClientCount = stabilizers.size + if (stabilizers.add(stabilizer)) { + updateGravStrength() + } } fun stabilizerDetached(stabilizer: GravitationStabilizerBlockEntity) { if (stabilizers.remove(stabilizer)) { - mass = mass - stabilizerClientCount = stabilizers.size + updateGravStrength() } } @@ -161,6 +129,39 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery } } + private fun updateGravStrength() { + var massForDiv = mass + + when (stabilizers.size) { + 0 -> {} + 1 -> massForDiv /= 4 + 2 -> massForDiv /= 16 + 3 -> massForDiv /= 64 + 4 -> massForDiv /= 512 + 5 -> massForDiv /= 2048 + else -> massForDiv /= 16384 + } + + gravitationStrength = sqrt(massForDiv.div(BASELINE_MASS).toDouble()).coerceIn(0.2, 40.0) + affectedBounds = BoundingBox( + (-30 * gravitationStrength).toInt(), + (-30 * gravitationStrength).toInt(), + (-30 * gravitationStrength).toInt(), + (30 * gravitationStrength).toInt(), + (30 * gravitationStrength).toInt(), + (30 * gravitationStrength).toInt() + ).moved( + blockPos.x, blockPos.y, blockPos.z + ) + + affectedBoundsAABB = AABB.of(affectedBounds) + } + + override fun getRenderBoundingBox(): AABB { + return AABB(blockPos.offset(-GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE, -GravitationStabilizerBlockEntity.RANGE), blockPos.offset( + GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE, GravitationStabilizerBlockEntity.RANGE)) + } + override fun saveLevel(nbt: CompoundTag) { super.saveLevel(nbt) nbt["mass"] = mass.serializeNBT() @@ -173,11 +174,6 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery spinDirection = nbt.getBoolean("spin_direction") } - var affectedBounds = BoundingBox(0, 0, 0, 1, 1, 1) - private set - var affectedBoundsAABB: AABB = AABB.of(affectedBounds) - private set - private fun setDeltaMovement(living: Entity, center: Vec3, distance: Double, weaker: Boolean) { //final double mult = Math.min(2, (30 * this.gravitation_strength) / Math.max(1, Math.pow(distance, 2))); // Сила притяжения @@ -204,9 +200,8 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery } fun clientTick() { - sleepTicks-- - if (sleepTicks > 0) return - val ply = Minecraft.getInstance().player!! + if (--sleepTicks > 0) return + val ply = Minecraft.getInstance().player ?: return val center = Vec3.atCenterOf(blockPos) if (!ply.abilities.mayfly && ply.getItemBySlot(EquipmentSlot.CHEST).item != MItems.PORTABLE_GRAVITATION_STABILIZER) { @@ -222,10 +217,8 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery override fun tick() { super.tick() - sleepTicks-- - if (sleepTicks > 0) return + if (--sleepTicks > 0) return val level = level as? ServerLevel ?: return - suppressUpdates = false val center = Vec3.atCenterOf(blockPos) @@ -311,13 +304,6 @@ class BlackHoleBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mattery } } - private var lastSphereSizeOuter = 0 - private var sphereIndexOuter = 0 - - init { - mass = mass - } - companion object { const val ITERATIONS = 30_000 val BASELINE_MASS = Decimal(50_000)