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 b57c3d6f1..99b4cdf74 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 @@ -867,6 +867,7 @@ private fun androidFeatures(provider: MatteryLanguageProvider) { private fun gui(provider: MatteryLanguageProvider) { with(provider.english) { + gui("flow_direction_set", "Flow direction set to %s") gui("tick_timer_set", "Timer set to %s ticks") gui("black_hole_generator.help0", "Generates energy using angular momentum of Singularities") 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 c264d6c6f..4dfb98e8d 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 @@ -868,6 +868,7 @@ private fun androidFeatures(provider: MatteryLanguageProvider) { private fun gui(provider: MatteryLanguageProvider) { with(provider.russian) { + gui("flow_direction_set", "Направление потока установлено на %s") gui("tick_timer_set", "Таймер установлен на %s тиков") gui("black_hole_generator.help0", "Генерирует электричество используя угловое ускорение сингулярностей") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/FlowDirection.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/FlowDirection.kt index d11df0163..d00b2fb32 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/FlowDirection.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/FlowDirection.kt @@ -2,7 +2,11 @@ package ru.dbotthepony.mc.otm.capability import com.google.common.collect.ImmutableSet import net.minecraft.network.chat.Component +import net.minecraft.network.chat.MutableComponent +import net.minecraft.util.StringRepresentable import ru.dbotthepony.mc.otm.core.TranslatableComponent +import java.util.Collections +import java.util.EnumSet import java.util.function.Predicate /** @@ -23,7 +27,7 @@ import java.util.function.Predicate * * `BI_DIRECTIONAL.test(OUTPUT)` = `false` * * `BI_DIRECTIONAL.test(INPUT)` = `false` */ -enum class FlowDirection(val input: Boolean, val output: Boolean, val translationKey: String) : Predicate { +enum class FlowDirection(val input: Boolean, val output: Boolean, val translationKey: String) : Predicate, StringRepresentable { /** * Can only be inputted (consumer) */ @@ -64,9 +68,15 @@ enum class FlowDirection(val input: Boolean, val output: Boolean, val translatio }.build() } - val title: Component + val title: MutableComponent get() = TranslatableComponent(translationKey) + private val serializedName = name.lowercase() + + override fun getSerializedName(): String { + return serializedName + } + /** * Subtype test (returns true if we can assign [t] to this, for example if we can assign [BI_DIRECTIONAL] to [INPUT]) */ @@ -106,7 +116,7 @@ enum class FlowDirection(val input: Boolean, val output: Boolean, val translatio companion object { @JvmField - val WITHOUT_NONE: ImmutableSet = ImmutableSet.of(INPUT, OUTPUT, BI_DIRECTIONAL) + val WITHOUT_NONE: Set = Collections.unmodifiableSet(EnumSet.of(INPUT, OUTPUT, BI_DIRECTIONAL)) @JvmStatic fun of(input: Boolean, output: Boolean): FlowDirection { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt index 111bbf8d4..308e5f358 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/ItemEnergyStorageImpl.kt @@ -93,6 +93,18 @@ open class EnergyCapacitorItem( maxBatteryLevel: Decimal, maxInput: Decimal? = null, maxOutput: Decimal? = maxInput, - initialBatteryLevel: Decimal = Decimal.ZERO -) : SimpleEnergyItem(FlowDirection.BI_DIRECTIONAL, stack, maxBatteryLevel, maxInput, maxOutput, initialBatteryLevel) + override val initialBatteryLevel: Decimal = Decimal.ZERO +) : ItemEnergyStorageImpl(stack) { + override val energyFlow: FlowDirection + get() = itemStack[MDataComponentTypes.FLOW_DIRECTION] ?: FlowDirection.BI_DIRECTIONAL + + override var maxInput: Decimal? = maxInput + protected set + + override var maxOutput: Decimal? = maxOutput + protected set + + override var maxBatteryLevel: Decimal = maxBatteryLevel + protected set +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt index 6e03b8bff..380041135 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt @@ -1,10 +1,17 @@ package ru.dbotthepony.mc.otm.core +import net.minecraft.sounds.SoundEvents +import net.minecraft.sounds.SoundSource import net.minecraft.world.entity.Entity +import net.minecraft.world.entity.player.Player import net.minecraft.world.level.Level import net.minecraft.world.phys.AABB import ru.dbotthepony.mc.otm.core.math.Vector +import ru.dbotthepony.mc.otm.core.math.component1 +import ru.dbotthepony.mc.otm.core.math.component2 +import ru.dbotthepony.mc.otm.core.math.component3 import ru.dbotthepony.mc.otm.core.math.minus +import ru.dbotthepony.mc.otm.core.math.plus import java.util.LinkedList import java.util.function.Predicate import kotlin.math.pow @@ -120,3 +127,8 @@ fun Level.getEntitiesInSphere(pos: Vector, radius: Double, predicate: Predicate< fun Level.getEntitiesInSphere(type: Class, pos: Vector, radius: Double, predicate: Predicate): MutableList> { return getEntitiesInEllipsoid(type, pos, Vector(radius, radius, radius), predicate) } + +fun Level.playClickSound(player: Player) { + val (x, y, z) = player.getEyePosition(1f) + player.getViewVector(1f) + playSound(player, x, y, z, SoundEvents.DISPENSER_FAIL, SoundSource.PLAYERS, 0.1f, 1.1f) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt index aaca7ea9c..fa78b113f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/BatteryItem.kt @@ -1,9 +1,9 @@ package ru.dbotthepony.mc.otm.item import net.minecraft.ChatFormatting -import net.minecraft.nbt.CompoundTag -import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerPlayer +import net.minecraft.sounds.SoundEvents +import net.minecraft.sounds.SoundSource import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionResultHolder import net.minecraft.world.effect.MobEffectInstance @@ -23,8 +23,13 @@ import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.config.ItemsConfig import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.math.Decimal +import ru.dbotthepony.mc.otm.core.math.component1 +import ru.dbotthepony.mc.otm.core.math.component2 +import ru.dbotthepony.mc.otm.core.math.component3 +import ru.dbotthepony.mc.otm.core.math.plus import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener import ru.dbotthepony.mc.otm.registry.MDamageTypes +import ru.dbotthepony.mc.otm.registry.MDataComponentTypes import ru.dbotthepony.mc.otm.registry.MatteryDamageSource import ru.dbotthepony.mc.otm.runIfClient import kotlin.math.roundToInt @@ -103,8 +108,39 @@ open class BatteryItem : MatteryItem, CapabilitiesRegisterListener { return p_150901_.matteryEnergy?.getBarColor() ?: super.getBarColor(p_150901_) } + override fun use(level: Level, player: Player, hand: InteractionHand): InteractionResultHolder { + if (player.isShiftKeyDown) { + val item = player.getItemInHand(hand) + level.playClickSound(player) + + if (level.isClientSide) { + return InteractionResultHolder.success(item) + } + + val current = item[MDataComponentTypes.FLOW_DIRECTION] ?: FlowDirection.BI_DIRECTIONAL + val next = when (current) { + FlowDirection.INPUT -> FlowDirection.OUTPUT + FlowDirection.OUTPUT -> FlowDirection.BI_DIRECTIONAL + FlowDirection.BI_DIRECTIONAL, FlowDirection.NONE -> FlowDirection.INPUT + } + + player.sendSystemMessage(TranslatableComponent("otm.gui.flow_direction_set", next.title)) + item[MDataComponentTypes.FLOW_DIRECTION] = next + return InteractionResultHolder.consume(item) + } + + return super.use(level, player, hand) + } + init { tooltips.itemEnergy() + + tooltips.addNormal(TooltipList.TooltipProvider { itemStack, context, acceptor -> + when (val f = itemStack[MDataComponentTypes.FLOW_DIRECTION] ?: FlowDirection.BI_DIRECTIONAL) { + FlowDirection.INPUT, FlowDirection.OUTPUT -> acceptor(TranslatableComponent("otm.gui.flow_direction_set", f.title).withStyle(ChatFormatting.GRAY)) + else -> {} + } + }) } private fun capFor(stack: ItemStack): EnergyCapacitorItem { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDataComponentTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDataComponentTypes.kt index 1a70a9b75..87e90768f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDataComponentTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MDataComponentTypes.kt @@ -7,9 +7,11 @@ import net.minecraft.core.component.DataComponentType import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.network.RegistryFriendlyByteBuf import net.minecraft.network.codec.StreamCodec +import net.minecraft.util.StringRepresentable import net.neoforged.bus.api.IEventBus import net.neoforged.neoforge.fluids.FluidStack import net.neoforged.neoforge.fluids.SimpleFluidContent +import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.core.math.Decimal @@ -46,6 +48,8 @@ object MDataComponentTypes { private fun uuid() = DataComponentType.builder().persistent(UUIDUtil.CODEC).networkSynchronized(UUIDUtil.STREAM_CODEC).build() + val FLOW_DIRECTION: DataComponentType by registry.register("flow_direction") { DataComponentType.builder().persistent(StringRepresentable.fromEnum(FlowDirection::values)).build() } + val BATTERY_LEVEL: DataComponentType by registry.register("battery_level") { DecimalComponent() } val MAX_BATTERY_LEVEL: DataComponentType by registry.register("max_battery_level") { DecimalComponent() } val MAX_BATTERY_INPUT: DataComponentType by registry.register("max_battery_input") { DecimalComponent() }