diff --git a/gradle.properties b/gradle.properties index e0c63b221..face01890 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ mixin_version=0.8.5 neogradle.subsystems.parchment.minecraftVersion=1.21.1 neogradle.subsystems.parchment.mappingsVersion=2024.11.17 -kommons_version=3.3.2 +kommons_version=3.5.2 caffeine_cache_version=3.1.5 jei_version=19.16.4.171 diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt index 206133507..8ce8671ac 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/DataGen.kt @@ -34,6 +34,7 @@ import ru.dbotthepony.mc.otm.datagen.items.MatteryItemModelProvider import ru.dbotthepony.mc.otm.datagen.lang.AddEnglishLanguage import ru.dbotthepony.mc.otm.datagen.models.MatteryBlockModelProvider import ru.dbotthepony.mc.otm.core.registryName +import ru.dbotthepony.mc.otm.core.util.PCG32RandomSource import ru.dbotthepony.mc.otm.data.FlywheelMaterialDataProvider import ru.dbotthepony.mc.otm.datagen.advancements.addAdvancements import ru.dbotthepony.mc.otm.datagen.advancements.addAndroidAdvancements @@ -68,6 +69,10 @@ internal fun modLootTable(string: String) = ResourceKey.create(Registries.LOOT_T object DataGen { const val MOD_ID = OverdriveThatMatters.MOD_ID + // for things which need to be random (e.g. UUIDs), + // so builds continue to be reproducible + val random = PCG32RandomSource(822393994030754753L) + var blockModelProvider: MatteryBlockModelProvider by WriteOnce() private set var itemModelProvider: MatteryItemModelProvider by WriteOnce() diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt index d288f3e34..7958800d9 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/MatterData.kt @@ -437,4 +437,6 @@ fun addMatterData(provider: MatterDataProvider) { } } } + + provider.inherit(MItems.IMPERFECT_BREAD, Items.BREAD, 1.5) } diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt index 1c4bc7248..94c9b76ab 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt @@ -194,6 +194,8 @@ fun addItemModels(provider: MatteryItemModelProvider) { provider.generated(MItems.PATTERN_DRIVE_CREATIVE) provider.generated(MItems.PATTERN_DRIVE_CREATIVE2) + provider.withExistingParent(MItems.GOLD_DISK, MItems.PATTERN_DRIVE_CREATIVE.registryName!!) + provider.generated(MItems.MATTER_DUST) provider.generated(MItems.TRITANIUM_DOOR.values) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index 673379cff..9dc45033e 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -145,6 +145,8 @@ private fun sounds(provider: MatteryLanguageProvider) { private fun misc(provider: MatteryLanguageProvider) { with(provider.english) { + misc("misc.inert", "Inert") + misc("misc.yes", "Yes") misc("misc.no", "No") @@ -879,6 +881,9 @@ private fun items(provider: MatteryLanguageProvider) { add(MItems.PATTERN_DRIVE_QUAD, "Quad-Level Pattern Drive") add(MItems.PATTERN_DRIVE_CREATIVE, "Creative Pattern Drive") + add(MItems.GOLD_DISK, "Gold Disk") + add(MItems.GOLD_DISK, "single_item", "Gold Disk (%s)") + add(MItems.PATTERN_DRIVE_CREATIVE2, "Omni-Present Pattern Drive") add(MItems.PATTERN_DRIVE_CREATIVE2, "description1", "Creative-only item") add(MItems.PATTERN_DRIVE_CREATIVE2, "description2", "Holds pattern for every item that have matter value") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt index ae0d7b49b..9a8cfdc09 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt @@ -159,6 +159,8 @@ private fun sounds(provider: MatteryLanguageProvider) { private fun misc(provider: MatteryLanguageProvider) { with(provider.russian) { + misc("misc.inert", "Инертен") + misc("misc.yes", "Да") misc("misc.no", "Нет") @@ -872,6 +874,9 @@ private fun items(provider: MatteryLanguageProvider) { add(MItems.PATTERN_DRIVE_QUAD, "Четырёхуровневый диск шаблонов") add(MItems.PATTERN_DRIVE_CREATIVE, "Творческий диск шаблонов") + add(MItems.GOLD_DISK, "Золотой диск") + add(MItems.GOLD_DISK, "single_item", "Золотой диск (%s)") + add(MItems.PATTERN_DRIVE_CREATIVE2, "Вездесущий диск шаблонов") add(MItems.PATTERN_DRIVE_CREATIVE2, "description1", "Предмет режима творчества") add(MItems.PATTERN_DRIVE_CREATIVE2, "description2", "Содержит в себе шаблоны всех предметов, которые имеют значение материи") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/EntityLoot.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/EntityLoot.kt index 16ce1b445..1988712d3 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/EntityLoot.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/EntityLoot.kt @@ -1,7 +1,10 @@ package ru.dbotthepony.mc.otm.datagen.loot +import net.minecraft.world.level.storage.loot.functions.SetComponentsFunction import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets import ru.dbotthepony.mc.otm.datagen.modLootTable +import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes +import ru.dbotthepony.mc.otm.registry.game.MEntityTypes import ru.dbotthepony.mc.otm.registry.game.MItems fun addEntityLoot(loot: LootTables) { @@ -18,4 +21,12 @@ fun addEntityLoot(loot: LootTables) { setRolls(1) } } + + loot.builder(LootContextParamSets.ENTITY, MEntityTypes.BREAD_MONSTER.defaultLootTable) { + lootPool { + item(MItems.IMPERFECT_BREAD) { + apply(SetComponentsFunction.setComponent(MDataComponentTypes.INERT, true)) + } + } + } } diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt index 3305a8958..d186819db 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootModifiersData.kt @@ -5,6 +5,7 @@ import net.minecraft.resources.ResourceLocation import net.minecraft.util.valueproviders.UniformInt import net.minecraft.world.entity.EntityType import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.Items import net.minecraft.world.level.storage.loot.BuiltInLootTables import net.minecraft.world.level.storage.loot.LootTable import net.minecraft.world.level.storage.loot.predicates.LootItemCondition @@ -18,9 +19,11 @@ import ru.dbotthepony.mc.otm.data.condition.HasExoPackCondition import ru.dbotthepony.mc.otm.data.condition.ItemInInventoryCondition import ru.dbotthepony.mc.otm.data.condition.KilledByRealPlayerOrIndirectly import ru.dbotthepony.mc.otm.data.loot.LootPoolAppender +import ru.dbotthepony.mc.otm.datagen.DataGen import ru.dbotthepony.mc.otm.datagen.modLootTable import ru.dbotthepony.mc.otm.item.ProceduralBatteryItem import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem +import ru.dbotthepony.mc.otm.item.matter.GoldDiskItem import ru.dbotthepony.mc.otm.registry.game.MItems @Suppress("FunctionName") @@ -66,6 +69,11 @@ fun addLootModifiers(it: LootModifiers) { apply(ProceduralExopackSlotUpgradeItem.Randomizer(UniformInt.of(4, 10))) }, + singleItem(MItems.GOLD_DISK) { + chanceCondition(0.1) + apply(GoldDiskItem.patterns(DataGen.random, MItems.IMPERFECT_BREAD)) + }, + singleItem(MItems.PROCEDURAL_BATTERY) { chanceCondition(0.15) @@ -122,6 +130,11 @@ fun addLootModifiers(it: LootModifiers) { chanceCondition(0.1) apply(ProceduralExopackSlotUpgradeItem.Randomizer(UniformInt.of(27, 56), UniformInt.of(2, 6))) }, + + singleItem(MItems.GOLD_DISK) { + chanceCondition(0.15) + apply(GoldDiskItem.patterns(DataGen.random, Items.ENDER_PEARL)) + }, )) it.add("dungeon_pill", PlainLootAppender( diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/EquipmentTags.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/EquipmentTags.kt index 3b2d9d3eb..3b3ae39d3 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/EquipmentTags.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/EquipmentTags.kt @@ -34,7 +34,12 @@ fun addEquipmentTags(tagsProvider: TagsProvider) { .add(MItems.TRITANIUM_BOOTS) .add(MItems.SIMPLE_TRITANIUM_BOOTS) - tagsProvider.items.Appender(ItemTags.SWORDS).add(MItems.TRITANIUM_SWORD).add(MItems.ENERGY_SWORD) + tagsProvider.items.Appender(ItemTags.SWORDS) + .add(MItems.TRITANIUM_SWORD) + .add(MItems.ENERGY_SWORD) + .add(MItems.FALLING_SUN) + .add(MItems.WITHERED_STEEL_SWORD) + tagsProvider.items.Appender(ItemTags.AXES).add(MItems.TRITANIUM_AXE) tagsProvider.items.Appender(ItemTags.PICKAXES).add(MItems.TRITANIUM_PICKAXE) tagsProvider.items.Appender(ItemTags.SHOVELS).add(MItems.TRITANIUM_SHOVEL) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt index 1e4a600d9..5f49c00f4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/GlobalEventHandler.kt @@ -7,6 +7,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder import net.minecraft.client.server.IntegratedServer import net.minecraft.core.HolderLookup import net.minecraft.server.MinecraftServer +import net.minecraft.util.RandomSource import net.minecraft.world.level.Level import net.neoforged.api.distmarker.Dist import net.neoforged.fml.loading.FMLLoader @@ -22,12 +23,17 @@ import ru.dbotthepony.mc.otm.core.collect.WeakHashSet import ru.dbotthepony.mc.otm.core.util.AtomicallyInvalidatedLazy import ru.dbotthepony.mc.otm.core.util.IConditionalTickable import ru.dbotthepony.mc.otm.core.util.ITickable +import ru.dbotthepony.mc.otm.core.util.PCG32RandomSource import ru.dbotthepony.mc.otm.core.util.TickList import ru.dbotthepony.mc.otm.graph.GraphNodeList import java.lang.ref.Cleaner import java.util.* import java.util.concurrent.atomic.AtomicInteger +private val threadLocalRandom = ThreadLocal.withInitial { PCG32RandomSource() } +internal val THREAD_LOCAL_RANDOM: RandomSource + get() = threadLocalRandom.get() + private val preServerTick = TickList() private val postServerTick = TickList() private val preWorldTick = WeakHashMap() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt index 70238b168..d5ebbd7fb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt @@ -1,7 +1,13 @@ package ru.dbotthepony.mc.otm.capability.matter +import net.minecraft.ChatFormatting +import net.minecraft.network.chat.Component import net.minecraft.world.item.Item +import net.minecraft.world.item.Item.TooltipContext +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.TooltipFlag import ru.dbotthepony.kommons.math.RGBAColor +import ru.dbotthepony.mc.otm.core.TranslatableComponent import java.util.* import java.util.function.Predicate import java.util.stream.Collectors @@ -72,3 +78,19 @@ fun IPatternStorage.getBarWidth(): Int { fun IPatternStorage.getBarColor(): Int { return RGBAColor.LOW_PATTERNS.linearInterpolation((storedPatterns / patternCapacity).toFloat(), RGBAColor.FULL_PATTERNS).toBGR() } + +fun IPatternStorage.gatherTooltip( + context: TooltipContext, + components: MutableList, + tooltipType: TooltipFlag +) { + for (state in patterns) { + components.add( + TranslatableComponent( + "otm.item.pattern.line", + state.item.getName(ItemStack(state.item, 1)), + String.format("%.2f", state.researchPercent * 100.0) + ).withStyle(ChatFormatting.AQUA) + ) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ServerConfig.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ServerConfig.kt index 78c37014b..64766db67 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ServerConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ServerConfig.kt @@ -76,4 +76,12 @@ object ServerConfig : AbstractConfig("misc") { builder.pop() } } + + val WITHER_SKELETON_HELMET_CHANCE: Double by builder + .comment("Chance of Wither Skeleton spawning with Netherite Helmet AND Withered Steel sword") + .defineInRange("WITHER_SKELETON_HELMET_CHANCE", 0.1, 0.0, 1.0) + + val WITHER_SKELETON_SWORD_CHANCE: Double by builder + .comment("Chance of Wither Skeleton spawning with Withered Steel sword") + .defineInRange("WITHER_SKELETON_HELMET_CHANCE", 0.24, 0.0, 1.0) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt index 0c0070806..06879d676 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/UpgradeContainer.kt @@ -39,9 +39,9 @@ class UpgradeContainer( } override val speedBonus: Double - get() = iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.speedBonus ?: 0.0) * it.count }.reduce(0.0) { a, b -> a + b } + get() = if (isEmpty) 0.0 else iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.speedBonus ?: 0.0) * it.count }.reduce(0.0) { a, b -> a + b } override val processingItems: Int - get() = iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.processingItems ?: 0).coerceAtLeast(0) * it.count }.reduce(0) { a, b -> a + b } + get() = if (isEmpty) 0 else iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.processingItems ?: 0).coerceAtLeast(0) * it.count }.reduce(0) { a, b -> a + b } override val energyStorageFlat: Decimal get() = positiveDecimals(IMatteryUpgrade::energyStorageFlat, Decimal::plus) override val energyStorage: Decimal @@ -53,7 +53,7 @@ class UpgradeContainer( override val energyConsumed: Decimal get() = anyDecimals(IMatteryUpgrade::energyConsumed, Decimal::plus) override val failureMultiplier: Double - get() = iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.failureMultiplier ?: 1.0).coerceAtLeast(0.0).pow(it.count.toDouble()) }.reduce(1.0) { a, b -> a * b } + get() = if (isEmpty) 1.0 else iterator().map { (it.getCapability(MatteryCapability.UPGRADE)?.failureMultiplier ?: 1.0).coerceAtLeast(0.0).pow(it.count.toDouble()) }.reduce(1.0) { a, b -> a * b } override val energyThroughputFlat: Decimal get() = positiveDecimals(IMatteryUpgrade::energyThroughputFlat, Decimal::plus) override val energyThroughput: Decimal @@ -62,24 +62,24 @@ class UpgradeContainer( fun transform(values: EnergyBalanceValues): EnergyBalanceValues { return object : EnergyBalanceValues { override val energyCapacity: Decimal - get() = values.energyCapacity * (energyStorage + Decimal.ONE) + energyStorageFlat + get() = if (isEmpty) values.energyCapacity else values.energyCapacity * (energyStorage + Decimal.ONE) + energyStorageFlat override val energyThroughput: Decimal - get() = values.energyThroughput * (this@UpgradeContainer.energyThroughput + Decimal.ONE) + energyThroughputFlat + get() = if (isEmpty) values.energyThroughput else values.energyThroughput * (this@UpgradeContainer.energyThroughput + Decimal.ONE) + energyThroughputFlat } } fun transform(values: VerboseEnergyBalanceValues): VerboseEnergyBalanceValues { return object : VerboseEnergyBalanceValues { override val energyCapacity: Decimal - get() = values.energyCapacity * (energyStorage + Decimal.ONE) + energyStorageFlat + get() = if (isEmpty) values.energyCapacity else values.energyCapacity * (energyStorage + Decimal.ONE) + energyStorageFlat override val maxEnergyReceive: Decimal - get() = values.maxEnergyReceive * (energyThroughput + Decimal.ONE) + energyThroughputFlat + get() = if (isEmpty) values.maxEnergyReceive else values.maxEnergyReceive * (energyThroughput + Decimal.ONE) + energyThroughputFlat override val maxEnergyExtract: Decimal - get() = values.maxEnergyExtract * (energyThroughput + Decimal.ONE) + energyThroughputFlat + get() =if (isEmpty) values.maxEnergyExtract else values.maxEnergyExtract * (energyThroughput + Decimal.ONE) + energyThroughputFlat } } fun matterCapacity(value: () -> Decimal): () -> Decimal { - return { value.invoke() * (matterStorage + Decimal.ONE) + matterStorageFlat } + return { if (isEmpty) value.invoke() else value.invoke() * (matterStorage + Decimal.ONE) + matterStorageFlat } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt index 6661fc996..47b8a1c39 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt @@ -627,6 +627,10 @@ infix fun FluidStack.isNotSameAs(other: FluidStack): Boolean { data class DoublePair(val first: Double, val second: Double) +fun RandomSource.nextUUID(): UUID { + return UUID(nextLong(), nextLong()) +} + // normal distribution via Marsaglia polar method fun RandomGenerator.nextNormalDoubles(stddev: Double, mean: Double): DoublePair { var rand1: Double diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt index c2891df03..16225f78f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/CMWCRandom.kt @@ -5,7 +5,7 @@ import net.minecraft.util.RandomSource import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian import net.minecraft.world.level.levelgen.PositionalRandomFactory import net.minecraft.world.level.levelgen.RandomSupport -import ru.dbotthepony.kommons.random.LCG64Random +import ru.dbotthepony.kommons.random.PCG32Random import java.lang.StringBuilder import java.util.random.RandomGenerator @@ -23,7 +23,7 @@ class CMWCRandom(seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenera } override fun setSeed(seed: Long) { - val rng = LCG64Random(seed) + val rng = PCG32Random(seed) // init state with regular LCG produced values for (i in 1 until state.size) { @@ -92,7 +92,7 @@ class CMWCRandom(seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenera return Positional(nextLong()) } - class Positional(val seed: Long) : PositionalRandomFactory { + class Positional(private val seed: Long) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { return CMWCRandom(Mth.getSeed(x, y, z).xor(seed)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt new file mode 100644 index 000000000..0f8ac64c8 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/GJRAND64RandomSource.kt @@ -0,0 +1,55 @@ +package ru.dbotthepony.mc.otm.core.util + +import net.minecraft.util.Mth +import net.minecraft.util.RandomSource +import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian +import net.minecraft.world.level.levelgen.PositionalRandomFactory +import ru.dbotthepony.kommons.random.GJRAND64Random +import java.lang.StringBuilder + +class GJRAND64RandomSource : GJRAND64Random, IRandomSourceGenerator { + private val gaussian = MarsagliaPolarGaussian(this) + + constructor(seed: Long) : super(seed) + constructor(seed0: Long, seed1: Long) : super(seed0, seed1) + + override fun nextInt(): Int { + return nextLong().ushr(32).toInt() + } + + override fun nextGaussian(): Double { + return gaussian.nextGaussian() + } + + override fun fork(): RandomSource { + return GJRAND64RandomSource(nextLong(), nextLong()) + } + + override fun forkPositional(): PositionalRandomFactory { + return Positional(nextLong(), nextLong()) + } + + override fun setSeed(seed: Long) { + reinitialize(seed) + gaussian.reset() + } + + class Positional(private val seed0: Long, private val seed1: Long) : PositionalRandomFactory { + override fun at(x: Int, y: Int, z: Int): RandomSource { + val seed = Mth.getSeed(x, y, z) + return GJRAND64RandomSource(seed0.xor(seed.rotateLeft(32)), seed1.xor(seed)) + } + + override fun fromHashOf(name: String): RandomSource { + return GJRAND64RandomSource(name.hashCode().toLong().xor(seed0), seed1) + } + + override fun fromSeed(seed: Long): RandomSource { + return GJRAND64RandomSource(seed) + } + + override fun parityConfigString(builder: StringBuilder) { + throw UnsupportedOperationException() + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt index 60f07343c..849e38e87 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/LCG64RandomSource.kt @@ -39,7 +39,7 @@ class LCG64RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : LCG64 return Positional(nextLong()) } - class Positional(val seed: Long) : PositionalRandomFactory { + class Positional(private val seed: Long) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { return LCG64RandomSource(Mth.getSeed(x, y, z).xor(seed)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt index da61dbff2..ae2f74205 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/PCG32RandomSource.kt @@ -2,11 +2,9 @@ package ru.dbotthepony.mc.otm.core.util import net.minecraft.util.Mth import net.minecraft.util.RandomSource -import net.minecraft.world.level.levelgen.LegacyRandomSource import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian import net.minecraft.world.level.levelgen.PositionalRandomFactory import net.minecraft.world.level.levelgen.RandomSupport -import ru.dbotthepony.kommons.random.LCG64Random import ru.dbotthepony.kommons.random.PCG32Random import java.lang.StringBuilder @@ -33,7 +31,7 @@ class PCG32RandomSource(seed: Long = RandomSupport.generateUniqueSeed()) : PCG32 return Positional(nextLong()) } - class Positional(val seed: Long) : PositionalRandomFactory { + class Positional(private val seed: Long) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { return PCG32RandomSource(Mth.getSeed(x, y, z).xor(seed)) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt index 5d1e2ee28..133762f55 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Xoshiro256Random.kt @@ -55,10 +55,10 @@ class Xoshiro256Random : Xoshiro256StarStarRandom, IRandomSourceGenerator { } class Positional( - val s0: Long, - val s1: Long, - val s2: Long, - val s3: Long, + private val s0: Long, + private val s1: Long, + private val s2: Long, + private val s3: Long, ) : PositionalRandomFactory { override fun at(x: Int, y: Int, z: Int): RandomSource { val rng = LCG64RandomSource(Mth.getSeed(x, y, z)) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/BreadMonster.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/BreadMonster.kt index 512563d84..1303709cd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/BreadMonster.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/BreadMonster.kt @@ -21,8 +21,11 @@ import net.minecraft.world.entity.monster.Zombie import net.minecraft.world.entity.npc.Villager import net.minecraft.world.entity.player.Player import net.minecraft.world.level.Level +import ru.dbotthepony.mc.otm.registry.game.MEntityTypes class BreadMonster(type: EntityType, level: Level) : Monster(type, level) { + constructor(level: Level) : this(MEntityTypes.BREAD_MONSTER, level) + val idleState = AnimationState() init { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/SpawnModifiers.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/SpawnModifiers.kt index 6ceaea61b..d7d1bb5d4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/SpawnModifiers.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/SpawnModifiers.kt @@ -6,24 +6,28 @@ import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items import net.neoforged.bus.api.SubscribeEvent import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent +import ru.dbotthepony.mc.otm.config.ServerConfig +import ru.dbotthepony.mc.otm.core.otmRandom import ru.dbotthepony.mc.otm.registry.game.MItems object WitheredSkeletonSpawnHandler { - @SubscribeEvent fun onEntityJoin(event: EntityJoinLevelEvent) { val entity = event.entity - if (entity is WitherSkeleton){ - val giveHelmet = entity.random.nextFloat() < 0.1f - val giveSword = entity.random.nextFloat() < 0.24f + if (entity is WitherSkeleton) { + val giveHelmet = event.level.otmRandom.nextFloat() < ServerConfig.WITHER_SKELETON_HELMET_CHANCE + val giveSword = event.level.otmRandom.nextFloat() < ServerConfig.WITHER_SKELETON_SWORD_CHANCE if (giveHelmet) { - entity.setItemSlot(EquipmentSlot.HEAD, ItemStack(Items.NETHERITE_HELMET)) - entity.setItemSlot(EquipmentSlot.MAINHAND, ItemStack(MItems.WITHERED_STEEL_SWORD)) - } else if (giveSword) { - entity.setItemSlot(EquipmentSlot.MAINHAND, ItemStack(MItems.WITHERED_STEEL_SWORD)) + if (!entity.hasItemInSlot(EquipmentSlot.HEAD)) + entity.setItemSlot(EquipmentSlot.HEAD, ItemStack(Items.NETHERITE_HELMET)) + } + + if (giveSword || giveHelmet) { + if (!entity.hasItemInSlot(EquipmentSlot.MAINHAND) || entity.getItemBySlot(EquipmentSlot.MAINHAND).item == Items.STONE_SWORD) + entity.setItemSlot(EquipmentSlot.MAINHAND, ItemStack(MItems.WITHERED_STEEL_SWORD)) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt index 473813cce..76098d215 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/QuantumBatteryItem.kt @@ -24,6 +24,7 @@ import net.neoforged.neoforge.event.tick.ServerTickEvent import net.neoforged.neoforge.network.PacketDistributor import net.neoforged.neoforge.network.handling.IPayloadContext import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.THREAD_LOCAL_RANDOM import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.trackedItems @@ -42,6 +43,8 @@ import ru.dbotthepony.mc.otm.core.math.readDecimal import ru.dbotthepony.mc.otm.core.math.set import ru.dbotthepony.mc.otm.core.math.writeDecimal import ru.dbotthepony.mc.otm.core.nbt.set +import ru.dbotthepony.mc.otm.core.nextUUID +import ru.dbotthepony.mc.otm.core.util.PCG32RandomSource import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.isClientThread import ru.dbotthepony.mc.otm.isServerThread @@ -82,7 +85,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc } } - class UnboundValues(override val uuid: UUID = UUID.randomUUID()) : IValues { + class UnboundValues(override val uuid: UUID = THREAD_LOCAL_RANDOM.nextUUID()) : IValues { override var energy: Decimal = Decimal.ZERO override var passed: Decimal = Decimal.ZERO override var received: Decimal = Decimal.ZERO @@ -125,7 +128,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc } fun values(): Values { - return values(UUID.randomUUID()) + return values(THREAD_LOCAL_RANDOM.nextUUID()) } override fun save(nbt: CompoundTag, registry: HolderLookup.Provider): CompoundTag { @@ -160,7 +163,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc fun updateValues() { if (!values.isServer && isServerThread()) { - values = serverData.values(stack[MDataComponentTypes.QUANTUM_LINK_ID] ?: UUID.randomUUID().also { stack[MDataComponentTypes.QUANTUM_LINK_ID] = it }) + values = serverData.values(stack[MDataComponentTypes.QUANTUM_LINK_ID] ?: THREAD_LOCAL_RANDOM.nextUUID().also { stack[MDataComponentTypes.QUANTUM_LINK_ID] = it }) } else if (isClientThread()) { val id = stack[MDataComponentTypes.QUANTUM_LINK_ID] ?: return diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/consumables/ImperfectBread.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/consumables/ImperfectBread.kt deleted file mode 100644 index d67ae84e9..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/consumables/ImperfectBread.kt +++ /dev/null @@ -1,25 +0,0 @@ -package ru.dbotthepony.mc.otm.item.consumables - -import net.minecraft.world.effect.MobEffectInstance -import net.minecraft.world.effect.MobEffects -import net.minecraft.world.level.Level -import net.minecraft.world.entity.LivingEntity -import net.minecraft.world.entity.player.Player -import net.minecraft.world.food.FoodProperties -import net.minecraft.world.item.Item -import net.minecraft.world.item.ItemStack - -class ImperfectBread(properties: Item.Properties) : Item(properties) { - override fun finishUsingItem(stack: ItemStack, level: Level, entity: LivingEntity): ItemStack { - if (entity is Player) { - entity.addEffect(MobEffectInstance(MobEffects.POISON, 80, 0)) - } - return super.finishUsingItem(stack, level, entity) - } -} - -val IMPERFECT_BREAD_FOOD: FoodProperties = FoodProperties.Builder() - .nutrition(5) - .saturationModifier(0.6f) - .build() - diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/consumables/ImperfectBreadItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/consumables/ImperfectBreadItem.kt new file mode 100644 index 000000000..089de13fc --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/consumables/ImperfectBreadItem.kt @@ -0,0 +1,52 @@ +package ru.dbotthepony.mc.otm.item.consumables + +import net.minecraft.ChatFormatting +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.effect.MobEffectInstance +import net.minecraft.world.effect.MobEffects +import net.minecraft.world.entity.LivingEntity +import net.minecraft.world.entity.item.ItemEntity +import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.Level +import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.core.otmRandom +import ru.dbotthepony.mc.otm.core.position +import ru.dbotthepony.mc.otm.entity.BreadMonster +import ru.dbotthepony.mc.otm.item.MatteryItem +import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes + +class ImperfectBreadItem(properties: Properties) : MatteryItem(properties) { + override fun finishUsingItem(stack: ItemStack, level: Level, entity: LivingEntity): ItemStack { + if (entity is ServerPlayer) { + entity.addEffect(MobEffectInstance(MobEffects.POISON, 80, 2)) + } + + return super.finishUsingItem(stack, level, entity) + } + + init { + tooltips.addNormal { itemStack, context, acceptor -> + if (itemStack[MDataComponentTypes.INERT] == true) { + acceptor(TranslatableComponent("otm.misc.inert").withStyle(ChatFormatting.DARK_GRAY)) + } + } + } + + override fun onEntityItemUpdate(stack: ItemStack, entity: ItemEntity): Boolean { + if (stack[MDataComponentTypes.INERT] == true) + return super.onEntityItemUpdate(stack, entity) + + // roll multiple times so multiple bread monsters can spawn on tick + // and also chance be less biased + for (i in 0 until stack.count.coerceAtMost(16)) { + if (entity.level().otmRandom.nextFloat() < 0.001f) { + val ent = BreadMonster(entity.level()) + ent.position = entity.position + entity.level().addFreshEntity(ent) + stack.shrink(1) + } + } + + return super.onEntityItemUpdate(stack, entity) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/GoldDiskItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/GoldDiskItem.kt new file mode 100644 index 000000000..dcdfda6c4 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/GoldDiskItem.kt @@ -0,0 +1,84 @@ +package ru.dbotthepony.mc.otm.item.matter + +import com.google.common.collect.ImmutableList +import net.minecraft.network.chat.Component +import net.minecraft.util.RandomSource +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.Items +import net.minecraft.world.item.TooltipFlag +import net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction +import net.minecraft.world.level.storage.loot.functions.SetComponentsFunction +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent +import ru.dbotthepony.mc.otm.capability.MatteryCapability +import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage +import ru.dbotthepony.mc.otm.capability.matter.PatternInsertFailure +import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus +import ru.dbotthepony.mc.otm.capability.matter.PatternState +import ru.dbotthepony.mc.otm.capability.matter.gatherTooltip +import ru.dbotthepony.mc.otm.core.TextComponent +import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.core.stream +import ru.dbotthepony.mc.otm.item.MatteryItem +import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener +import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes +import java.util.* +import java.util.stream.Stream + +class GoldDiskItem(parameters: Properties) : MatteryItem(parameters), CapabilitiesRegisterListener { + override fun registerCapabilities(event: RegisterCapabilitiesEvent) { + event.registerItem(MatteryCapability.PATTERN_ITEM, { o, _ -> ItemPatternStorageCapability(o) }, this) + } + + override fun getName(stack: ItemStack): Component { + val data = stack[MDataComponentTypes.PATTERNS] + + if (data == null || data.size > 1) { + return super.getName(stack) + } else if (data.size == 0 || data[0].item == Items.AIR) { + return TranslatableComponent("$descriptionId.single_item", TextComponent("???")) + } else { + return TranslatableComponent("$descriptionId.single_item", data[0].item.getName(ItemStack(data[0].item))) + } + } + + override fun appendHoverText( + itemStack: ItemStack, + context: TooltipContext, + components: MutableList, + tooltipType: TooltipFlag + ) { + itemStack.getCapability(MatteryCapability.PATTERN_ITEM)?.gatherTooltip(context, components, tooltipType) + + super.appendHoverText(itemStack, context, components, tooltipType) + } + + class ItemPatternStorageCapability(val stack: ItemStack) : IPatternStorage { + override val patternCapacity: Int get() { + return stack[MDataComponentTypes.PATTERNS]?.size ?: 0 + } + + override val storedPatterns: Int get() { + return patternCapacity + } + + override val patterns: Stream get() { + return stack[MDataComponentTypes.PATTERNS]?.stream() ?: Stream.empty() + } + + override fun insertPattern(pattern: PatternState, onlyUpdate: Boolean, simulate: Boolean): PatternInsertStatus { + return PatternInsertFailure + } + } + + companion object { + fun patterns(random: RandomSource, vararg items: Item): LootItemConditionalFunction.Builder<*> { + return SetComponentsFunction.setComponent( + MDataComponentTypes.PATTERNS, + items + .stream() + .map { PatternState(UUID(random.nextLong(), random.nextLong()), it, 1.0) } + .collect(ImmutableList.toImmutableList())) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt index eb4f62599..ee85ced91 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/matter/PatternStorageItem.kt @@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.item.matter import com.google.common.collect.ImmutableList import net.minecraft.ChatFormatting import net.minecraft.network.chat.Component -import net.minecraft.world.item.Item import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Rarity import net.minecraft.world.item.TooltipFlag @@ -15,23 +14,20 @@ import ru.dbotthepony.mc.otm.capability.matter.PatternInsertInserted import ru.dbotthepony.mc.otm.capability.matter.PatternInsertStatus import ru.dbotthepony.mc.otm.capability.matter.PatternInsertUpdated import ru.dbotthepony.mc.otm.capability.matter.PatternState +import ru.dbotthepony.mc.otm.capability.matter.gatherTooltip import ru.dbotthepony.mc.otm.capability.matter.getBarColor import ru.dbotthepony.mc.otm.capability.matter.getBarWidth import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.item.MatteryItem import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes import java.util.stream.Stream -class PatternStorageItem : Item, CapabilitiesRegisterListener { +class PatternStorageItem : MatteryItem, CapabilitiesRegisterListener { private val _capacity: () -> Int val capacity get() = _capacity.invoke() var isCreative: Boolean - constructor(capacity: Int) : super(Properties().stacksTo(1)) { - _capacity = { capacity } - isCreative = false - } - constructor(capacity: () -> Int) : super(Properties().stacksTo(1)) { _capacity = capacity isCreative = false @@ -47,29 +43,21 @@ class PatternStorageItem : Item, CapabilitiesRegisterListener { } override fun appendHoverText( - p_41421_: ItemStack, - p_339594_: TooltipContext, - list: MutableList, - p_41424_: TooltipFlag + itemStack: ItemStack, + context: TooltipContext, + components: MutableList, + tooltipType: TooltipFlag ) { - p_41421_.getCapability(MatteryCapability.PATTERN_ITEM)?.let { + itemStack.getCapability(MatteryCapability.PATTERN_ITEM)?.let { if (isCreative) - list.add(TranslatableComponent("otm.item.pattern.infinite.stored", it.storedPatterns).withStyle(ChatFormatting.GRAY)) + components.add(TranslatableComponent("otm.item.pattern.infinite.stored", it.storedPatterns).withStyle(ChatFormatting.GRAY)) else - list.add(TranslatableComponent("otm.item.pattern.stored", it.storedPatterns, it.patternCapacity).withStyle(ChatFormatting.GRAY)) + components.add(TranslatableComponent("otm.item.pattern.stored", it.storedPatterns, it.patternCapacity).withStyle(ChatFormatting.GRAY)) - for (state in it.patterns) { - list.add( - TranslatableComponent( - "otm.item.pattern.line", - state.item.getName(ItemStack(state.item, 1)), - String.format("%.2f", state.researchPercent * 100.0) - ).withStyle(ChatFormatting.AQUA) - ) - } + it.gatherTooltip(context, components, tooltipType) } - super.appendHoverText(p_41421_, p_339594_, list, p_41424_) + super.appendHoverText(itemStack, context, components, tooltipType) } override fun isBarVisible(p_150899_: ItemStack): Boolean { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/WitheredSteelSwordItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/WitheredSteelSwordItem.kt index 8960a05fb..7de70f248 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/WitheredSteelSwordItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/WitheredSteelSwordItem.kt @@ -13,23 +13,19 @@ import net.minecraft.world.item.Tiers import net.minecraft.world.item.component.ItemAttributeModifiers import ru.dbotthepony.mc.otm.registry.game.MItems -class WitheredSteelSwordItem(properties: Item.Properties) : SwordItem(Tiers.IRON, properties){ +class WitheredSteelSwordItem(properties: Properties) : SwordItem(Tiers.IRON, properties) { private val attributes: ItemAttributeModifiers init { - var builder = ItemAttributeModifiers.builder() + val builder = ItemAttributeModifiers.builder() builder.add(Attributes.ATTACK_DAMAGE, AttributeModifier(BASE_ATTACK_DAMAGE_ID, 4.5, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND) builder.add(Attributes.ATTACK_SPEED, AttributeModifier(BASE_ATTACK_SPEED_ID, -2.4, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND) attributes = builder.build() } - override fun getMaxDamage(stack: ItemStack): Int { - return 420 - } - - override fun isEnchantable(p_41456_: ItemStack): Boolean { - return p_41456_.count == 1 + override fun isEnchantable(stack: ItemStack): Boolean { + return stack.count == 1 } override fun getEnchantmentValue(stack: ItemStack): Int { @@ -41,13 +37,12 @@ class WitheredSteelSwordItem(properties: Item.Properties) : SwordItem(Tiers.IRON } override fun hurtEnemy(stack: ItemStack, target: LivingEntity, attacker: LivingEntity): Boolean { - target.addEffect(MobEffectInstance(MobEffects.WITHER, 100, 0)) - return super.hurtEnemy(stack, target, attacker) + val status = super.hurtEnemy(stack, target, attacker) + if (status) target.addEffect(MobEffectInstance(MobEffects.WITHER, 100, 0), attacker) + return status } override fun getDefaultAttributeModifiers(stack: ItemStack): ItemAttributeModifiers { return attributes } - - } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MCreativeTabs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MCreativeTabs.kt index 0d13a7607..4d1f4f08d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MCreativeTabs.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MCreativeTabs.kt @@ -287,6 +287,9 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) { accept(MItems.NUTRIENT_PASTE) accept(MItems.IMPERFECT_BREAD) + accept(ItemStack(MItems.IMPERFECT_BREAD).also { + it[MDataComponentTypes.INERT] = true + }) // exo accept(MItems.EXOPACK_PROBE) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MDataComponentTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MDataComponentTypes.kt index 1817fed3a..4459e52e0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MDataComponentTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MDataComponentTypes.kt @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList import com.mojang.serialization.Codec import net.minecraft.core.UUIDUtil import net.minecraft.core.component.DataComponentType +import net.minecraft.core.component.DataComponents import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.nbt.CompoundTag import net.minecraft.network.RegistryFriendlyByteBuf @@ -69,6 +70,8 @@ object MDataComponentTypes { val MAX_BATTERY_OUTPUT: DataComponentType by registry.register("max_battery_output") { DecimalComponent() } val MATTER_LEVEL: DataComponentType by registry.register("matter_level") { DecimalComponent() } + val INERT: DataComponentType by registry.register("inert") { DataComponentType.builder().persistent(Codec.BOOL).build() } + val EXOPACK_SLOT_COUNT: DataComponentType by registry.register("exopack_slot_count") { DataComponentType.builder().persistent(Codec.INT).networkSynchronized(StreamCodecs.INT).build() } val EXOPACK_UPGRADE_ID: DataComponentType by registry.register("exopack_upgrade_id") { uuid() } val QUANTUM_LINK_ID: DataComponentType by registry.register("quantum_link_id") { uuid() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MItems.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MItems.kt index cbd83e673..eacba6edc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MItems.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MItems.kt @@ -26,18 +26,12 @@ import net.minecraft.world.item.Tiers import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.level.block.Block import net.neoforged.bus.api.IEventBus -import net.neoforged.neoforge.common.DeferredSpawnEggItem import net.neoforged.neoforge.common.SimpleTier -import ru.dbotthepony.mc.otm.block.MatteryBlock -import ru.dbotthepony.mc.otm.block.addSimpleDescription -import ru.dbotthepony.mc.otm.block.tech.FlywheelBatteryBlock import ru.dbotthepony.mc.otm.capability.ITieredUpgradeSet import ru.dbotthepony.mc.otm.capability.MatteryPlayer import ru.dbotthepony.mc.otm.capability.UpgradeType import ru.dbotthepony.mc.otm.config.CablesConfig import ru.dbotthepony.mc.otm.config.ItemsConfig -import ru.dbotthepony.mc.otm.core.addAll -import ru.dbotthepony.mc.otm.core.asSupplierArray import ru.dbotthepony.mc.otm.core.collect.SupplierList import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.core.math.Decimal @@ -66,6 +60,7 @@ import ru.dbotthepony.mc.otm.item.exopack.ExopackSlotUpgradeItem import ru.dbotthepony.mc.otm.item.exopack.ExopackUpgradeItem import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem import ru.dbotthepony.mc.otm.item.matter.CreativePatternItem +import ru.dbotthepony.mc.otm.item.matter.GoldDiskItem import ru.dbotthepony.mc.otm.item.matter.MatterCapacitorItem import ru.dbotthepony.mc.otm.item.matter.MatterDustItem import ru.dbotthepony.mc.otm.item.matter.PatternStorageItem @@ -429,7 +424,7 @@ object MItems { val PILL_HEAL: Item by registry.register(MNames.PILL_HEAL) { HealPillItem() } val PILL_NOT_NORMAL: Item by registry.register(MNames.PILL_NOT_NORMAL) { NotNormalPill() } - val IMPERFECT_BREAD: Item by registry.register(MNames.IMPERFECT_BREAD) { ImperfectBread(Item.Properties().food(IMPERFECT_BREAD_FOOD)) } + val IMPERFECT_BREAD: Item by registry.register(MNames.IMPERFECT_BREAD) { ImperfectBreadItem(Item.Properties().food(FoodProperties.Builder().nutrition(5).saturationModifier(0.6f).build())) } val PILLS = SupplierList( MItems::PILL_ANDROID, @@ -503,6 +498,8 @@ object MItems { val PATTERN_DRIVE_CREATIVE: Item by registry.register(MNames.PATTERN_DRIVE_CREATIVE) { PatternStorageItem() } val PATTERN_DRIVE_CREATIVE2: Item by registry.register(MNames.PATTERN_DRIVE_CREATIVE2) { CreativePatternItem() } + val GOLD_DISK: Item by registry.register("gold_disk") { GoldDiskItem(Properties().stacksTo(16).rarity(Rarity.RARE)) } + val PORTABLE_CONDENSATION_DRIVE: Item by registry.register(MNames.PORTABLE_CONDENSATION_DRIVE) { PortableCondensationDriveItem(4000) } val PORTABLE_DENSE_CONDENSATION_DRIVE: Item by registry.register(MNames.PORTABLE_DENSE_CONDENSATION_DRIVE) { PortableCondensationDriveItem(25000) }