From 23df86e2f6d488608b63fcb20bf7d94bdd741171 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 14 Jan 2022 20:29:54 +0700 Subject: [PATCH] Gravitation stabilizer and slightly better blackhole gravity --- .../java/ru/dbotthepony/mc/otm/Registry.java | 28 +++++++ .../otm/block/BlockGravitationStabilizer.kt | 38 +++++++++ .../BlockEntityGravitationStabilizer.kt | 83 +++++++++++++++++++ .../entity/blackhole/BlockEntityBlackHole.kt | 56 ++++++++++--- .../kotlin/ru/dbotthepony/mc/otm/core/Math.kt | 2 + .../overdrive_that_matters/lang/en_us.json | 5 ++ 6 files changed, 199 insertions(+), 13 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockGravitationStabilizer.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityGravitationStabilizer.kt diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index 05904ddd0..87b77cf0d 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -1,7 +1,9 @@ package ru.dbotthepony.mc.otm; +import net.minecraft.ChatFormatting; import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; +import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; @@ -16,6 +18,7 @@ import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.OreBlock; import net.minecraft.world.level.block.SoundType; @@ -30,6 +33,7 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.RegistryBuilder; +import org.jetbrains.annotations.Nullable; import ru.dbotthepony.mc.otm.android.AndroidFeature; import ru.dbotthepony.mc.otm.android.AndroidResearchBuilder; import ru.dbotthepony.mc.otm.android.AndroidResearchType; @@ -52,6 +56,9 @@ import ru.dbotthepony.mc.otm.client.screen.*; import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe; import ru.dbotthepony.mc.otm.recipe.PlatePressRecipeFactory; +import javax.annotation.Nonnull; +import java.util.List; + public class Registry { public static final DamageSource DAMAGE_BECOME_ANDROID = new DamageSource("otm_become_android"); public static final DamageSource DAMAGE_BECOME_HUMANE = new DamageSource("otm_become_humane"); @@ -133,6 +140,7 @@ public class Registry { public static final ResourceLocation DEBUG_SPHERE_POINTS = loc("debug_sphere_points"); public static final ResourceLocation BLACK_HOLE = loc("black_hole"); + public static final ResourceLocation GRAVITATION_STABILIZER = loc("gravitation_stabilizer"); public static final ResourceLocation CARGO_CRATE = loc("cargo_crate"); // building blocks @@ -283,6 +291,7 @@ public class Registry { public static final BlockSphereDebugger DEBUG_SPHERE_POINTS = new BlockSphereDebugger(); public static final BlockBlackHole BLACK_HOLE = new BlockBlackHole(); + public static final BlockGravitationStabilizer GRAVITATION_STABILIZER = new BlockGravitationStabilizer(); public static final Block TRITANIUM_ORE = new OreBlock( BlockBehaviour.Properties.of(Material.STONE) @@ -362,6 +371,8 @@ public class Registry { CHEMICAL_GENERATOR.setRegistryName(Names.CHEMICAL_GENERATOR); PLATE_PRESS.setRegistryName(Names.PLATE_PRESS); + GRAVITATION_STABILIZER.setRegistryName(Names.GRAVITATION_STABILIZER); + DEBUG_EXPLOSION_SMALL.setRegistryName(Names.DEBUG_EXPLOSION_SMALL); DEBUG_SPHERE_POINTS.setRegistryName(Names.DEBUG_SPHERE_POINTS); @@ -397,6 +408,7 @@ public class Registry { event.getRegistry().register(ENERGY_COUNTER); event.getRegistry().register(CHEMICAL_GENERATOR); event.getRegistry().register(PLATE_PRESS); + event.getRegistry().register(GRAVITATION_STABILIZER); event.getRegistry().register(DEBUG_EXPLOSION_SMALL); event.getRegistry().register(DEBUG_SPHERE_POINTS); @@ -430,6 +442,17 @@ public class Registry { public static final BlockItem ENERGY_COUNTER = new BlockItem(Blocks.ENERGY_COUNTER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); public static final BlockItem CHEMICAL_GENERATOR = new BlockItem(Blocks.CHEMICAL_GENERATOR, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); public static final BlockItem PLATE_PRESS = new BlockItem(Blocks.PLATE_PRESS, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); + public static final BlockItem GRAVITATION_STABILIZER = new BlockItem(Blocks.GRAVITATION_STABILIZER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)) { + @Override + public void appendHoverText(@Nonnull ItemStack p_40572_, @Nullable Level p_40573_, @Nonnull List p_40574_, @Nonnull TooltipFlag p_40575_) { + super.appendHoverText(p_40572_, p_40573_, p_40574_, p_40575_); + + p_40574_.add(new TranslatableComponent("block.overdrive_that_matters.gravitation_stabilizer.desc").withStyle(ChatFormatting.GRAY)); + p_40574_.add(new TranslatableComponent("block.overdrive_that_matters.gravitation_stabilizer.desc2").withStyle(ChatFormatting.DARK_GRAY)); + p_40574_.add(new TranslatableComponent("block.overdrive_that_matters.gravitation_stabilizer.desc3").withStyle(ChatFormatting.DARK_GRAY)); + p_40574_.add(new TranslatableComponent("block.overdrive_that_matters.gravitation_stabilizer.desc4").withStyle(ChatFormatting.DARK_GRAY)); + } + }; public static final BlockItem DEBUG_EXPLOSION_SMALL = new BlockItem(Blocks.DEBUG_EXPLOSION_SMALL, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); public static final BlockItem DEBUG_SPHERE_POINTS = new BlockItem(Blocks.DEBUG_SPHERE_POINTS, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); @@ -566,6 +589,7 @@ public class Registry { ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER); CHEMICAL_GENERATOR.setRegistryName(Names.CHEMICAL_GENERATOR); PLATE_PRESS.setRegistryName(Names.PLATE_PRESS); + GRAVITATION_STABILIZER.setRegistryName(Names.GRAVITATION_STABILIZER); DEBUG_EXPLOSION_SMALL.setRegistryName(Names.DEBUG_EXPLOSION_SMALL); DEBUG_SPHERE_POINTS.setRegistryName(Names.DEBUG_SPHERE_POINTS); @@ -647,6 +671,7 @@ public class Registry { event.getRegistry().register(ENERGY_COUNTER); event.getRegistry().register(CHEMICAL_GENERATOR); event.getRegistry().register(PLATE_PRESS); + event.getRegistry().register(GRAVITATION_STABILIZER); event.getRegistry().register(DEBUG_EXPLOSION_SMALL); event.getRegistry().register(DEBUG_SPHERE_POINTS); @@ -734,6 +759,7 @@ public class Registry { public static final BlockEntityType ENERGY_COUNTER = BlockEntityType.Builder.of(BlockEntityEnergyCounter::new, Blocks.ENERGY_COUNTER).build(null); public static final BlockEntityType CHEMICAL_GENERATOR = BlockEntityType.Builder.of(BlockEntityChemicalGenerator::new, Blocks.CHEMICAL_GENERATOR).build(null); public static final BlockEntityType PLATE_PRESS = BlockEntityType.Builder.of(BlockEntityPlatePress::new, Blocks.PLATE_PRESS).build(null); + public static final BlockEntityType GRAVITATION_STABILIZER = BlockEntityType.Builder.of(BlockEntityGravitationStabilizer::new, Blocks.GRAVITATION_STABILIZER).build(null); public static final BlockEntityType DEBUG_EXPLOSION_SMALL = BlockEntityType.Builder.of(BlockEntityExplosionDebugger::new, Blocks.DEBUG_EXPLOSION_SMALL).build(null); public static final BlockEntityType DEBUG_SPHERE_POINTS = BlockEntityType.Builder.of(BlockEntitySphereDebugger::new, Blocks.DEBUG_SPHERE_POINTS).build(null); @@ -757,6 +783,7 @@ public class Registry { ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER); CHEMICAL_GENERATOR.setRegistryName(Names.CHEMICAL_GENERATOR); PLATE_PRESS.setRegistryName(Names.PLATE_PRESS); + GRAVITATION_STABILIZER.setRegistryName(Names.GRAVITATION_STABILIZER); DEBUG_EXPLOSION_SMALL.setRegistryName(Names.DEBUG_EXPLOSION_SMALL); DEBUG_SPHERE_POINTS.setRegistryName(Names.DEBUG_SPHERE_POINTS); @@ -783,6 +810,7 @@ public class Registry { event.getRegistry().register(ENERGY_COUNTER); event.getRegistry().register(CHEMICAL_GENERATOR); event.getRegistry().register(PLATE_PRESS); + event.getRegistry().register(GRAVITATION_STABILIZER); event.getRegistry().register(DEBUG_EXPLOSION_SMALL); event.getRegistry().register(DEBUG_SPHERE_POINTS); diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockGravitationStabilizer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockGravitationStabilizer.kt new file mode 100644 index 000000000..51af449c9 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/BlockGravitationStabilizer.kt @@ -0,0 +1,38 @@ +package ru.dbotthepony.mc.otm.block + +import net.minecraft.core.BlockPos +import net.minecraft.world.level.Level +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.EntityBlock +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.block.state.StateDefinition +import net.minecraft.world.level.material.Material +import net.minecraft.world.level.material.MaterialColor +import ru.dbotthepony.mc.otm.Registry +import ru.dbotthepony.mc.otm.block.entity.BlockEntityGravitationStabilizer +import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState + +class BlockGravitationStabilizer : BlockMatteryRotatable(Properties.of(Material.STONE, MaterialColor.COLOR_BLUE).requiresCorrectToolForDrops().strength(3f, 600.0f)), EntityBlock { + override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): BlockEntity { + return BlockEntityGravitationStabilizer(p_153215_, p_153216_) + } + + override fun getTicker( + p_153212_: Level, + p_153213_: BlockState, + p_153214_: BlockEntityType + ): BlockEntityTicker? { + if (p_153212_.isClientSide || p_153214_ !== Registry.BlockEntities.GRAVITATION_STABILIZER) + return null + + return BlockEntityTicker { level, _, _, tile -> if (tile is BlockEntityGravitationStabilizer) tile.tick(level) } + } + + override fun createBlockStateDefinition(builder: StateDefinition.Builder) { + super.createBlockStateDefinition(builder) + builder.add(WorkerState.SEMI_WORKER_STATE) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityGravitationStabilizer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityGravitationStabilizer.kt new file mode 100644 index 000000000..504e70915 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityGravitationStabilizer.kt @@ -0,0 +1,83 @@ +package ru.dbotthepony.mc.otm.block.entity + +import net.minecraft.core.BlockPos +import net.minecraft.core.SectionPos +import net.minecraft.network.chat.TranslatableComponent +import net.minecraft.world.entity.player.Inventory +import net.minecraft.world.entity.player.Player +import net.minecraft.world.level.Level +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.state.BlockState +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.Registry +import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable +import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityBlackHole +import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState +import ru.dbotthepony.mc.otm.core.plus +import ru.dbotthepony.mc.otm.core.times + +class BlockEntityGravitationStabilizer(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.GRAVITATION_STABILIZER, p_155229_, p_155230_) { + override fun getDefaultDisplayName() = NAME + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player) = null + + private var blackHole: BlockEntityBlackHole? = null + + fun tick(level: Level) { + var findBlackHole: BlockEntityBlackHole? = null + val dir = blockState.getValue(BlockMatteryRotatable.FACING).normal + + for (i in 1 .. RANGE) { + val pos = blockPos + dir * i + val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(pos.x), SectionPos.blockToSectionCoord(pos.z)) ?: continue + val state = chunk.getBlockState(pos) + + if (!state.isAir) { + findBlackHole = chunk.getBlockEntity(pos) as? BlockEntityBlackHole ?: break + break + } + } + + if (findBlackHole != blackHole) { + blackHole?.stabilizerDetached(this) + findBlackHole?.stabilizerAttached(this) + blackHole = findBlackHole + + level.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, if (findBlackHole != null) WorkerState.WORKING else WorkerState.IDLE), Block.UPDATE_CLIENTS) + } + } + + override fun setRemoved() { + super.setRemoved() + blackHole?.stabilizerDetached(this) + } + + override fun setLevel(level: Level) { + super.setLevel(level) + + if (!level.isClientSide) { + OverdriveThatMatters.tickOnce(level) { + for (face in BlockMatteryRotatable.FACING.possibleValues) { + val dir = face.normal + + for (i in 1 .. RANGE) { + val pos = blockPos + dir * i + val chunk = level.chunkSource.getChunkNow(SectionPos.blockToSectionCoord(pos.x), SectionPos.blockToSectionCoord(pos.z)) ?: continue + val state = chunk.getBlockState(pos) + + if (!state.isAir) { + if (chunk.getBlockEntity(pos) is BlockEntityBlackHole) { + level.setBlock(blockPos, blockState.setValue(BlockMatteryRotatable.FACING, face), Block.UPDATE_ALL) + return@tickOnce + } + } + } + } + } + } + } + + companion object { + const val RANGE = 64 + private val NAME = TranslatableComponent("block.overdrive_that_matters.gravitation_stabilizer") + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt index c7eba9b7b..98e879c36 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/blackhole/BlockEntityBlackHole.kt @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.block.entity.blackhole import net.minecraft.client.Minecraft import net.minecraft.core.BlockPos import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.IntTag import net.minecraft.network.Connection import net.minecraft.network.protocol.PacketFlow import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket @@ -21,12 +22,13 @@ 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.BlockEntityGravitationStabilizer 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.sin import kotlin.math.sqrt class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(Registry.BlockEntities.BLACK_HOLE, p_155229_, p_155230_) { @@ -40,17 +42,23 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn field = mass setChanged() - gravitationStrength = mass.div(BASELINE_MASS).toDouble() - if (gravitationStrength > 1) { - gravitationStrength = 20.0.coerceAtMost(sqrt(gravitationStrength)) - } else { - gravitationStrength = 0.08.coerceAtLeast(gravitationStrength.pow(2.0)) + var massForDiv = mass + + when (if (level?.isClientSide == true) stabilizerClientCount else stabilizers.size) { + 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()).coerceAtMost(20.0).coerceAtLeast(0.2) + val level = level - if (level != null && !level.isClientSide && !suppress_updates) + if (level != null && !level.isClientSide && !suppressUpdates) level.sendBlockUpdated(blockPos, blockState, blockState, Block.UPDATE_CLIENTS) affectedBounds = BoundingBox( @@ -70,9 +78,26 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn var gravitationStrength = 1.0 private set - private var suppress_updates = true + private var suppressUpdates = true var spin_direction = false + private val stabilizers = ArrayList() + private var stabilizerClientCount = 0 + + fun stabilizerAttached(stabilizer: BlockEntityGravitationStabilizer) { + if (stabilizers.contains(stabilizer)) + return + + stabilizers.add(stabilizer) + mass = mass + } + + fun stabilizerDetached(stabilizer: BlockEntityGravitationStabilizer) { + if (stabilizers.remove(stabilizer)) { + mass = mass + } + } + fun collapse() { val level = level as? ServerLevel ?: return @@ -139,13 +164,16 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn // received either by game engine (from getUpdateTag on ClientLevelPacket) // or by onDataPacket override fun handleUpdateTag(tag: CompoundTag) { + stabilizerClientCount = (tag["stabilizers"] as IntTag).asInt super.handleUpdateTag(tag) readBlackHoleData(tag) } // called by game engine for ClientLevelPacket override fun getUpdateTag(): CompoundTag { - return writeBlackHoleData(super.getUpdateTag()) + return writeBlackHoleData(super.getUpdateTag()).also { + it["stabilizers"] = stabilizers.size + } } // called by game engine on block updates @@ -183,11 +211,11 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn if (weaker) living.deltaMovement = living.deltaMovement - .add(rotate.multiply(mult * 0.4f, mult * 0.4f, mult * 0.4f)) + .add(rotate.multiply(mult * 0.2f, mult * 0.2f, mult * 0.2f)) .add(delta.multiply(mult * 0.33f, mult * 0.33f, mult * 0.33f)) else living.deltaMovement = living.deltaMovement - .add(rotate.multiply(mult * 0.4f, mult * 0.4f, mult * 0.4f)) + .add(rotate.multiply(mult * 0.2f, mult * 0.2f, mult * 0.2f)) .add(delta.multiply(mult, mult, mult)) } } @@ -209,7 +237,9 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn fun tick() { val level = level as ServerLevel - suppress_updates = false + suppressUpdates = false + + //mass = Fraction(20_000 * sin(System.currentTimeMillis().toDouble() / 1000.0) + 10_000) val center = Vec3.atCenterOf(blockPos) @@ -237,7 +267,7 @@ class BlockEntityBlackHole(p_155229_: BlockPos, p_155230_: BlockState) : BlockEn val mass = MatterRegistry.getMatterValue(item.item) if (mass > Fraction.ZERO) - this.mass += mass + this.mass += mass * item.item.count } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Math.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Math.kt index 0a634df46..4882e5dda 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Math.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Math.kt @@ -38,6 +38,8 @@ operator fun Vec3i.plus(direction: Direction): Vec3i = this.offset(direction.nor operator fun Vec3i.minus(direction: Vec3i): Vec3i = this.subtract(direction) operator fun Vec3i.minus(direction: Direction): Vec3i = this.subtract(direction.normal) +operator fun Vec3i.times(int: Int): Vec3i = this.multiply(int) + operator fun Vector.plus(direction: Vector): Vector = this.add(direction) operator fun Vector.minus(direction: Vector): Vector = this.subtract(direction) diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index d3b2a8fe3..64a748e60 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -166,6 +166,11 @@ "block.overdrive_that_matters.drive_rack": "Condensation Drive Rack", "block.overdrive_that_matters.item_monitor": "Item Monitor", "block.overdrive_that_matters.plate_press": "Plate Press", + "block.overdrive_that_matters.gravitation_stabilizer": "Gravitation Stabilizer", + "block.overdrive_that_matters.gravitation_stabilizer.desc": "Reduces gravitation effects of singularities", + "block.overdrive_that_matters.gravitation_stabilizer.desc2": "Requires no power to operate", + "block.overdrive_that_matters.gravitation_stabilizer.desc3": "Keep in mind the effect of multiple stabilizers produce exponentially increasing result", + "block.overdrive_that_matters.gravitation_stabilizer.desc4": "Too weak gravitation field will cause singularity to melt and evaporate away very fast", "otm.container.matter_panel.number_input": "Input replication task count",