Now Bread monster can spawn when thrown as item

And when killed, inert version is dropped
This commit is contained in:
DBotThePony 2025-03-09 21:11:42 +07:00
parent 29edf383cd
commit 436606abf4
Signed by: DBot
GPG Key ID: DCC23B5715498507
7 changed files with 60 additions and 5 deletions

View File

@ -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")

View File

@ -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", "Нет")

View File

@ -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))
}
}
}
}

View File

@ -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<BreadMonster>, level: Level) : Monster(type, level) {
constructor(level: Level) : this(MEntityTypes.BREAD_MONSTER, level)
val idleState = AnimationState()
init {

View File

@ -1,16 +1,21 @@
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.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.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: Item.Properties) : Item(properties) {
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))
@ -18,4 +23,30 @@ class ImperfectBreadItem(properties: Item.Properties) : Item(properties) {
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)
}
}

View File

@ -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)

View File

@ -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<Decimal> by registry.register("max_battery_output") { DecimalComponent() }
val MATTER_LEVEL: DataComponentType<Decimal> by registry.register("matter_level") { DecimalComponent() }
val INERT: DataComponentType<Boolean> by registry.register("inert") { DataComponentType.builder<Boolean>().persistent(Codec.BOOL).build() }
val EXOPACK_SLOT_COUNT: DataComponentType<Int> by registry.register("exopack_slot_count") { DataComponentType.builder<Int>().persistent(Codec.INT).networkSynchronized(StreamCodecs.INT).build() }
val EXOPACK_UPGRADE_ID: DataComponentType<UUID> by registry.register("exopack_upgrade_id") { uuid() }
val QUANTUM_LINK_ID: DataComponentType<UUID> by registry.register("quantum_link_id") { uuid() }