Add Redstone Emitter
This commit is contained in:
parent
4fe6391e69
commit
3cd4a7aa0d
|
@ -7,6 +7,7 @@ import net.minecraft.screen.ScreenHandler
|
||||||
import net.minecraft.sound.SoundEvents
|
import net.minecraft.sound.SoundEvents
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.shadowfacts.cacao.geometry.Point
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
|
import net.shadowfacts.cacao.util.KeyModifiers
|
||||||
import net.shadowfacts.cacao.util.MouseButton
|
import net.shadowfacts.cacao.util.MouseButton
|
||||||
import net.shadowfacts.cacao.util.RenderHelper
|
import net.shadowfacts.cacao.util.RenderHelper
|
||||||
import net.shadowfacts.cacao.window.ScreenHandlerWindow
|
import net.shadowfacts.cacao.window.ScreenHandlerWindow
|
||||||
|
@ -57,15 +58,16 @@ open class CacaoHandledScreen<Handler: ScreenHandler>(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun drawBackground(matrixStack: MatrixStack, delta: Float, mouseX: Int, mouseY: Int) {
|
override fun drawBackground(matrixStack: MatrixStack, delta: Float, mouseX: Int, mouseY: Int) {
|
||||||
|
renderBackground(matrixStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun drawForeground(matrixStack: MatrixStack, mouseX: Int, mouseY: Int) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun render(matrixStack: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
|
override fun render(matrixStack: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
|
||||||
renderBackground(matrixStack)
|
|
||||||
|
|
||||||
val mouse = Point(mouseX, mouseY)
|
val mouse = Point(mouseX, mouseY)
|
||||||
windows.forEachIndexed { index, it ->
|
windows.forEachIndexed { index, it ->
|
||||||
it.draw(matrixStack, mouse, delta)
|
|
||||||
if (it is ScreenHandlerWindow) {
|
if (it is ScreenHandlerWindow) {
|
||||||
if (index == windows.size - 1) {
|
if (index == windows.size - 1) {
|
||||||
super.render(matrixStack, mouseX, mouseY, delta)
|
super.render(matrixStack, mouseX, mouseY, delta)
|
||||||
|
@ -74,7 +76,10 @@ open class CacaoHandledScreen<Handler: ScreenHandler>(
|
||||||
super.render(matrixStack, -1, -1, delta)
|
super.render(matrixStack, -1, -1, delta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
it.draw(matrixStack, mouse, delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawMouseoverTooltip(matrixStack, mouseX, mouseY)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||||
|
@ -90,4 +95,20 @@ open class CacaoHandledScreen<Handler: ScreenHandler>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
|
||||||
|
val modifiersSet by lazy { KeyModifiers(modifiers) }
|
||||||
|
if (findResponder { it.keyPressed(keyCode, modifiersSet) }) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return super.keyPressed(keyCode, scanCode, modifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun charTyped(char: Char, modifiers: Int): Boolean {
|
||||||
|
val modifiersSet by lazy { KeyModifiers(modifiers) }
|
||||||
|
if (findResponder { it.charTyped(char, modifiersSet) }) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return super.charTyped(char, modifiers)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,9 @@ open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title),
|
||||||
return super.charTyped(char, modifiers)
|
return super.charTyped(char, modifiers)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findResponder(fn: (Responder) -> Boolean): Boolean {
|
}
|
||||||
|
|
||||||
|
fun AbstractCacaoScreen.findResponder(fn: (Responder) -> Boolean): Boolean {
|
||||||
var responder = windows.lastOrNull()?.firstResponder
|
var responder = windows.lastOrNull()?.firstResponder
|
||||||
while (responder != null) {
|
while (responder != null) {
|
||||||
if (fn(responder)) {
|
if (fn(responder)) {
|
||||||
|
@ -148,6 +150,4 @@ open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title),
|
||||||
responder = responder.nextResponder
|
responder = responder.nextResponder
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ data class Color(val red: Int, val green: Int, val blue: Int, val alpha: Int = 2
|
||||||
val RED = Color(0xff0000)
|
val RED = Color(0xff0000)
|
||||||
val GREEN = Color(0x00ff00)
|
val GREEN = Color(0x00ff00)
|
||||||
val BLUE = Color(0x0000ff)
|
val BLUE = Color(0x0000ff)
|
||||||
|
val MAGENTA = Color(0xfc46e4)
|
||||||
|
|
||||||
val TEXT = Color(0x404040)
|
val TEXT = Color(0x404040)
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ class Label(
|
||||||
for (i in 0 until lines.size) {
|
for (i in 0 until lines.size) {
|
||||||
val x = when (textAlignment) {
|
val x = when (textAlignment) {
|
||||||
TextAlignment.LEFT -> 0.0
|
TextAlignment.LEFT -> 0.0
|
||||||
TextAlignment.CENTER -> (bounds.width + textRenderer.getWidth(lines[i])) / 2
|
TextAlignment.CENTER -> (bounds.width - textRenderer.getWidth(lines[i])) / 2
|
||||||
TextAlignment.RIGHT -> bounds.width - textRenderer.getWidth(lines[i])
|
TextAlignment.RIGHT -> bounds.width - textRenderer.getWidth(lines[i])
|
||||||
}
|
}
|
||||||
val y = i * textRenderer.fontHeight
|
val y = i * textRenderer.fontHeight
|
||||||
|
|
|
@ -62,12 +62,22 @@ abstract class AbstractTextField<Impl: AbstractTextField<Impl>>(
|
||||||
minecraftWidget.setMaxLength(value)
|
minecraftWidget.setMaxLength(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Minecraft builtin black background and border are drawn. Defaults to true.
|
||||||
|
*/
|
||||||
|
var drawBackground = true
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
minecraftWidget.setHasBorder(value)
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var originInWindow: Point
|
private lateinit var originInWindow: Point
|
||||||
private var minecraftWidget = ProxyWidget()
|
private var minecraftWidget = ProxyWidget()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
minecraftWidget.text = initialText
|
minecraftWidget.text = initialText
|
||||||
minecraftWidget.setTextPredicate { this.validate(it) }
|
minecraftWidget.setTextPredicate { this.validate(it) }
|
||||||
|
minecraftWidget.setHasBorder(drawBackground)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package net.shadowfacts.cacao.view.textfield
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class NumberField(
|
||||||
|
initialValue: Int,
|
||||||
|
handler: ((NumberField) -> Unit)? = null,
|
||||||
|
): AbstractTextField<NumberField>(initialValue.toString()) {
|
||||||
|
|
||||||
|
var number: Int?
|
||||||
|
get() {
|
||||||
|
return if (text.isEmpty()) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Integer.parseInt(text)
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
text = value?.toString() ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var validator: ((Int) -> Boolean)? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.handler = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun validate(proposedText: String): Boolean {
|
||||||
|
return proposedText.isEmpty() || try {
|
||||||
|
val value = Integer.parseInt(proposedText)
|
||||||
|
validator?.invoke(value) ?: true
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ object PhysicalConnectivity: ModInitializer {
|
||||||
registerGlobalReceiver(C2SConfigureActivationMode)
|
registerGlobalReceiver(C2SConfigureActivationMode)
|
||||||
registerGlobalReceiver(C2SConfigureRedstoneController)
|
registerGlobalReceiver(C2SConfigureRedstoneController)
|
||||||
registerGlobalReceiver(C2SConfigureInserterAmount)
|
registerGlobalReceiver(C2SConfigureInserterAmount)
|
||||||
|
registerGlobalReceiver(C2SConfigureRedstoneEmitterAmount)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerGlobalReceiver(receiver: ServerReceiver) {
|
private fun registerGlobalReceiver(receiver: ServerReceiver) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import net.fabricmc.api.ClientModInitializer
|
||||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
||||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry
|
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry
|
||||||
import net.shadowfacts.phycon.block.inserter.InserterScreen
|
import net.shadowfacts.phycon.block.inserter.InserterScreen
|
||||||
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterScreen
|
||||||
import net.shadowfacts.phycon.init.PhyScreens
|
import net.shadowfacts.phycon.init.PhyScreens
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalScreen
|
import net.shadowfacts.phycon.block.terminal.TerminalScreen
|
||||||
import net.shadowfacts.phycon.networking.ClientReceiver
|
import net.shadowfacts.phycon.networking.ClientReceiver
|
||||||
|
@ -17,6 +18,7 @@ object PhysicalConnectivityClient: ClientModInitializer {
|
||||||
override fun onInitializeClient() {
|
override fun onInitializeClient() {
|
||||||
ScreenRegistry.register(PhyScreens.TERMINAL, ::TerminalScreen)
|
ScreenRegistry.register(PhyScreens.TERMINAL, ::TerminalScreen)
|
||||||
ScreenRegistry.register(PhyScreens.INSERTER, ::InserterScreen)
|
ScreenRegistry.register(PhyScreens.INSERTER, ::InserterScreen)
|
||||||
|
ScreenRegistry.register(PhyScreens.REDSTONE_EMITTER, ::RedstoneEmitterScreen)
|
||||||
|
|
||||||
registerGlobalReceiver(S2CTerminalUpdateDisplayedItems)
|
registerGlobalReceiver(S2CTerminalUpdateDisplayedItems)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package net.shadowfacts.phycon.block.redstone_emitter
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.block.Material
|
||||||
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
import net.minecraft.entity.player.PlayerInventory
|
||||||
|
import net.minecraft.network.PacketByteBuf
|
||||||
|
import net.minecraft.screen.ScreenHandler
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity
|
||||||
|
import net.minecraft.sound.BlockSoundGroup
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.minecraft.util.ActionResult
|
||||||
|
import net.minecraft.util.Hand
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.minecraft.util.hit.BlockHitResult
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.Direction
|
||||||
|
import net.minecraft.world.BlockView
|
||||||
|
import net.minecraft.world.World
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class RedstoneEmitterBlock: FaceDeviceBlock<RedstoneEmitterBlockEntity>(
|
||||||
|
Settings.of(Material.METAL)
|
||||||
|
.strength(1.5f)
|
||||||
|
.sounds(BlockSoundGroup.METAL)
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ID = Identifier(PhysicalConnectivity.MODID, "redstone_emitter")
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: don't just copy the redstone controller
|
||||||
|
override val faceThickness = 3.0
|
||||||
|
override val faceShapes = mapOf(
|
||||||
|
Direction.DOWN to createCuboidShape(0.0, 0.0, 0.0, 16.0, 3.0, 16.0),
|
||||||
|
Direction.UP to createCuboidShape(0.0, 13.0, 0.0, 16.0, 16.0, 16.0),
|
||||||
|
Direction.NORTH to createCuboidShape(0.0, 0.0, 0.0, 16.0, 16.0, 3.0),
|
||||||
|
Direction.SOUTH to createCuboidShape(0.0, 0.0, 13.0, 16.0, 16.0, 16.0),
|
||||||
|
Direction.WEST to createCuboidShape(0.0, 0.0, 0.0, 3.0, 16.0, 16.0),
|
||||||
|
Direction.EAST to createCuboidShape(13.0, 0.0, 0.0, 16.0, 16.0, 16.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun createBlockEntity(world: BlockView) = RedstoneEmitterBlockEntity()
|
||||||
|
|
||||||
|
override fun emitsRedstonePower(state: BlockState): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStrongRedstonePower(state: BlockState, world: BlockView, pos: BlockPos, receivingSide: Direction): Int {
|
||||||
|
return if (receivingSide.opposite == state[FACING]) {
|
||||||
|
getBlockEntity(world, pos)!!.cachedEmittedPower
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getWeakRedstonePower(state: BlockState, world: BlockView, pos: BlockPos, receivingSide: Direction): Int {
|
||||||
|
return getStrongRedstonePower(state, world, pos, receivingSide)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUse(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, result: BlockHitResult): ActionResult {
|
||||||
|
if (!world.isClient) {
|
||||||
|
val be = getBlockEntity(world, pos)!!
|
||||||
|
|
||||||
|
be.sync()
|
||||||
|
|
||||||
|
val factory = object: ExtendedScreenHandlerFactory {
|
||||||
|
override fun createMenu(syncId: Int, playerInv: PlayerInventory, player: PlayerEntity): ScreenHandler {
|
||||||
|
return RedstoneEmitterScreenHandler(syncId, playerInv, be)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDisplayName() = this@RedstoneEmitterBlock.name
|
||||||
|
|
||||||
|
override fun writeScreenOpeningData(player: ServerPlayerEntity, buf: PacketByteBuf) {
|
||||||
|
buf.writeBlockPos(be.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.openHandledScreen(factory)
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package net.shadowfacts.phycon.block.redstone_emitter
|
||||||
|
|
||||||
|
import alexiil.mc.lib.attributes.item.GroupedItemInvView
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.shadowfacts.phycon.api.packet.Packet
|
||||||
|
import net.shadowfacts.phycon.api.util.IPAddress
|
||||||
|
import net.shadowfacts.phycon.block.DeviceBlockEntity
|
||||||
|
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
||||||
|
import net.shadowfacts.phycon.init.PhyBlockEntities
|
||||||
|
import net.shadowfacts.phycon.packet.DeviceRemovedPacket
|
||||||
|
import net.shadowfacts.phycon.packet.ReadInventoryPacket
|
||||||
|
import net.shadowfacts.phycon.packet.RequestInventoryPacket
|
||||||
|
import kotlin.math.round
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class RedstoneEmitterBlockEntity: DeviceBlockEntity(PhyBlockEntities.REDSTONE_EMITTER) {
|
||||||
|
|
||||||
|
private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInvView>()
|
||||||
|
var cachedEmittedPower: Int = 0
|
||||||
|
private set
|
||||||
|
|
||||||
|
var stackToMonitor: ItemStack = ItemStack.EMPTY
|
||||||
|
var maxAmount = 64
|
||||||
|
|
||||||
|
override fun handle(packet: Packet) {
|
||||||
|
when (packet) {
|
||||||
|
is ReadInventoryPacket -> handleReadInventory(packet)
|
||||||
|
is DeviceRemovedPacket -> handleDeviceRemoved(packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleReadInventory(packet: ReadInventoryPacket) {
|
||||||
|
inventoryCache[packet.source] = packet.inventory
|
||||||
|
recalculateRedstone()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleDeviceRemoved(packet: DeviceRemovedPacket) {
|
||||||
|
inventoryCache.remove(packet.source)
|
||||||
|
recalculateRedstone()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
super.tick()
|
||||||
|
|
||||||
|
if (!world!!.isClient && counter % 20 == 0L) {
|
||||||
|
if (counter % 80 == 0L) {
|
||||||
|
updateInventories()
|
||||||
|
} else if (counter % 20 == 0L) {
|
||||||
|
recalculateRedstone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateInventories() {
|
||||||
|
sendPacket(RequestInventoryPacket(ipAddress))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun recalculateRedstone() {
|
||||||
|
if (stackToMonitor.isEmpty) {
|
||||||
|
cachedEmittedPower = 0
|
||||||
|
updateWorld()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val networkAmount = inventoryCache.values.fold(0) { acc, inv ->
|
||||||
|
acc + inv.getAmount(stackToMonitor)
|
||||||
|
}
|
||||||
|
cachedEmittedPower =
|
||||||
|
if (networkAmount == 0) {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
1 + round(networkAmount / maxAmount.toDouble() * 14).toInt()
|
||||||
|
}
|
||||||
|
updateWorld()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateWorld() {
|
||||||
|
world!!.updateNeighborsAlways(pos, cachedState.block)
|
||||||
|
world!!.updateNeighborsAlways(pos.offset(cachedState[FaceDeviceBlock.FACING]), cachedState.block)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toCommonTag(tag: CompoundTag) {
|
||||||
|
super.toCommonTag(tag)
|
||||||
|
tag.putInt("CachedEmittedPower", cachedEmittedPower)
|
||||||
|
tag.put("StackToMonitor", stackToMonitor.toTag(CompoundTag()))
|
||||||
|
tag.putInt("MaxAmount", maxAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromCommonTag(tag: CompoundTag) {
|
||||||
|
super.fromCommonTag(tag)
|
||||||
|
cachedEmittedPower = tag.getInt("CachedEmittedPower")
|
||||||
|
stackToMonitor = ItemStack.fromTag(tag.getCompound("StackToMonitor"))
|
||||||
|
maxAmount = tag.getInt("MaxAmount")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
package net.shadowfacts.phycon.block.redstone_emitter
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
|
import net.minecraft.client.util.math.MatrixStack
|
||||||
|
import net.minecraft.entity.player.PlayerInventory
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import net.minecraft.text.TranslatableText
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.cacao.CacaoHandledScreen
|
||||||
|
import net.shadowfacts.cacao.geometry.Axis
|
||||||
|
import net.shadowfacts.cacao.util.Color
|
||||||
|
import net.shadowfacts.cacao.view.Label
|
||||||
|
import net.shadowfacts.cacao.view.StackView
|
||||||
|
import net.shadowfacts.cacao.view.View
|
||||||
|
import net.shadowfacts.cacao.view.textfield.NumberField
|
||||||
|
import net.shadowfacts.cacao.window.ScreenHandlerWindow
|
||||||
|
import net.shadowfacts.kiwidsl.dsl
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.init.PhyBlocks
|
||||||
|
import net.shadowfacts.phycon.networking.C2SConfigureRedstoneEmitterAmount
|
||||||
|
import no.birkett.kiwi.Variable
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class RedstoneEmitterScreen(
|
||||||
|
handler: RedstoneEmitterScreenHandler,
|
||||||
|
playerInv: PlayerInventory,
|
||||||
|
title: Text
|
||||||
|
): CacaoHandledScreen<RedstoneEmitterScreenHandler>(
|
||||||
|
handler,
|
||||||
|
playerInv,
|
||||||
|
title
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val BACKGROUND = Identifier(PhysicalConnectivity.MODID, "textures/gui/redstone_emitter.png")
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
backgroundWidth = 176
|
||||||
|
backgroundHeight = 166
|
||||||
|
|
||||||
|
addWindow(ScreenHandlerWindow(handler, ViewController(handler.emitter)))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun drawBackground(matrixStack: MatrixStack, delta: Float, mouseX: Int, mouseY: Int) {
|
||||||
|
super.drawBackground(matrixStack, delta, mouseX, mouseY)
|
||||||
|
|
||||||
|
RenderSystem.color4f(1f, 1f, 1f, 1f)
|
||||||
|
client!!.textureManager.bindTexture(BACKGROUND)
|
||||||
|
val x = (width - backgroundWidth) / 2
|
||||||
|
val y = (height - backgroundHeight) / 2
|
||||||
|
drawTexture(matrixStack, x, y, 0, 0, backgroundWidth, backgroundHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewController(
|
||||||
|
private val emitter: RedstoneEmitterBlockEntity,
|
||||||
|
): net.shadowfacts.cacao.viewcontroller.ViewController() {
|
||||||
|
|
||||||
|
lateinit var halfLabel: Label
|
||||||
|
lateinit var fullLabel: Label
|
||||||
|
|
||||||
|
override fun viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
val title = Label(PhyBlocks.REDSTONE_EMITTER.name)
|
||||||
|
title.textColor = Color.TEXT
|
||||||
|
view.addSubview(title)
|
||||||
|
|
||||||
|
val inv = Label(MinecraftClient.getInstance().player!!.inventory.displayName)
|
||||||
|
inv.textColor = Color.TEXT
|
||||||
|
view.addSubview(inv)
|
||||||
|
|
||||||
|
val field = NumberField(emitter.maxAmount) {
|
||||||
|
if (it.number != null) {
|
||||||
|
emitter.maxAmount = it.number!!
|
||||||
|
MinecraftClient.getInstance().player!!.networkHandler.sendPacket(C2SConfigureRedstoneEmitterAmount(emitter))
|
||||||
|
}
|
||||||
|
updateLabelTexts()
|
||||||
|
}
|
||||||
|
field.validator = { it >= 0 }
|
||||||
|
field.drawBackground = false
|
||||||
|
view.addSubview(field)
|
||||||
|
|
||||||
|
val hStack = StackView(Axis.HORIZONTAL, StackView.Distribution.FILL, spacing = 2.0)
|
||||||
|
view.addSubview(hStack)
|
||||||
|
|
||||||
|
val zeroStack = hStack.addArrangedSubview(StackView(Axis.VERTICAL))
|
||||||
|
zeroStack.addArrangedSubview(Label(TranslatableText("gui.phycon.emitter.count", 0), textAlignment = Label.TextAlignment.CENTER)).apply {
|
||||||
|
textColor = Color.TEXT
|
||||||
|
}
|
||||||
|
zeroStack.addArrangedSubview(View())
|
||||||
|
zeroStack.addArrangedSubview(Label("0", textAlignment = Label.TextAlignment.CENTER)).apply {
|
||||||
|
textColor = Color.RED
|
||||||
|
}
|
||||||
|
|
||||||
|
val halfStack = hStack.addArrangedSubview(StackView(Axis.VERTICAL))
|
||||||
|
halfLabel = halfStack.addArrangedSubview(Label("half", textAlignment = Label.TextAlignment.CENTER)).apply {
|
||||||
|
textColor = Color.TEXT
|
||||||
|
}
|
||||||
|
halfStack.addArrangedSubview(View())
|
||||||
|
halfStack.addArrangedSubview(Label("8", textAlignment = Label.TextAlignment.CENTER)).apply {
|
||||||
|
textColor = Color.RED
|
||||||
|
}
|
||||||
|
|
||||||
|
val fullStack = hStack.addArrangedSubview(StackView(Axis.VERTICAL))
|
||||||
|
fullLabel = fullStack.addArrangedSubview(Label("full", textAlignment = Label.TextAlignment.CENTER)).apply {
|
||||||
|
textColor = Color.TEXT
|
||||||
|
}
|
||||||
|
fullStack.addArrangedSubview(View())
|
||||||
|
fullStack.addArrangedSubview(Label("15", textAlignment = Label.TextAlignment.CENTER)).apply {
|
||||||
|
textColor = Color.RED
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLabelTexts()
|
||||||
|
|
||||||
|
view.solver.dsl {
|
||||||
|
val minX = Variable("minX")
|
||||||
|
val minY = Variable("minY")
|
||||||
|
minX equalTo ((view.widthAnchor - 176) / 2)
|
||||||
|
minY equalTo ((view.heightAnchor - 166) / 2)
|
||||||
|
|
||||||
|
title.leftAnchor equalTo (minX + 8)
|
||||||
|
title.topAnchor equalTo (minY + 6)
|
||||||
|
|
||||||
|
inv.leftAnchor equalTo (minX + 8)
|
||||||
|
inv.topAnchor equalTo (minY + 72)
|
||||||
|
|
||||||
|
// offset by 1 on each edge to account for MC border
|
||||||
|
field.widthAnchor equalTo 82
|
||||||
|
field.heightAnchor equalTo 11
|
||||||
|
field.leftAnchor equalTo (minX + 56)
|
||||||
|
field.topAnchor equalTo (minY + 23)
|
||||||
|
|
||||||
|
hStack.centerXAnchor equalTo view.centerXAnchor
|
||||||
|
hStack.widthAnchor equalTo (176 - 4)
|
||||||
|
hStack.topAnchor equalTo (field.bottomAnchor + 8)
|
||||||
|
hStack.bottomAnchor equalTo inv.topAnchor
|
||||||
|
|
||||||
|
zeroStack.widthAnchor equalTo halfStack.widthAnchor
|
||||||
|
halfStack.widthAnchor equalTo fullStack.widthAnchor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateLabelTexts() {
|
||||||
|
halfLabel.text = TranslatableText("gui.phycon.emitter.count", ceil(emitter.maxAmount / 2.0).toInt())
|
||||||
|
fullLabel.text = TranslatableText("gui.phycon.emitter.count", emitter.maxAmount)
|
||||||
|
window!!.layout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package net.shadowfacts.phycon.block.redstone_emitter
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
|
import net.minecraft.entity.player.PlayerInventory
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.network.PacketByteBuf
|
||||||
|
import net.minecraft.screen.ScreenHandler
|
||||||
|
import net.minecraft.screen.slot.Slot
|
||||||
|
import net.minecraft.screen.slot.SlotActionType
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.init.PhyBlocks
|
||||||
|
import net.shadowfacts.phycon.init.PhyScreens
|
||||||
|
import net.shadowfacts.phycon.util.GhostSlot
|
||||||
|
import net.shadowfacts.phycon.util.copyWithCount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class RedstoneEmitterScreenHandler(
|
||||||
|
syncId: Int,
|
||||||
|
playerInv: PlayerInventory,
|
||||||
|
val emitter: RedstoneEmitterBlockEntity,
|
||||||
|
): ScreenHandler(PhyScreens.REDSTONE_EMITTER, syncId) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ID = Identifier(PhysicalConnectivity.MODID, "redstone_emitter")
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(syncId: Int, playerInv: PlayerInventory, buf: PacketByteBuf):
|
||||||
|
this(
|
||||||
|
syncId,
|
||||||
|
playerInv,
|
||||||
|
PhyBlocks.REDSTONE_EMITTER.getBlockEntity(playerInv.player.world, buf.readBlockPos())!!
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
// fake slot
|
||||||
|
addSlot(GhostSlot(emitter::stackToMonitor, 31, 20))
|
||||||
|
|
||||||
|
// player inv
|
||||||
|
for (y in 0 until 3) {
|
||||||
|
for (x in 0 until 9) {
|
||||||
|
addSlot(Slot(playerInv, x + y * 9 + 9, 8 + x * 18, 84 + y * 18))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hotbar
|
||||||
|
for (x in 0 until 9) {
|
||||||
|
addSlot(Slot(playerInv, x, 8 + x * 18, 142))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canUse(player: PlayerEntity): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSlotClick(slotId: Int, clickData: Int, slotActionType: SlotActionType, player: PlayerEntity): ItemStack {
|
||||||
|
// fake slot
|
||||||
|
if (slotId == 0) {
|
||||||
|
if (player.inventory.cursorStack.isEmpty) {
|
||||||
|
emitter.stackToMonitor = ItemStack.EMPTY
|
||||||
|
} else {
|
||||||
|
emitter.stackToMonitor = player.inventory.cursorStack.copyWithCount(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onSlotClick(slotId, clickData, slotActionType, player)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transferSlot(player: PlayerEntity, slotId: Int): ItemStack {
|
||||||
|
val slot = slots[slotId]
|
||||||
|
emitter.stackToMonitor = slot.stack.copyWithCount(1)
|
||||||
|
return ItemStack.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,8 @@ import net.shadowfacts.phycon.block.netswitch.SwitchBlock
|
||||||
import net.shadowfacts.phycon.block.netswitch.SwitchBlockEntity
|
import net.shadowfacts.phycon.block.netswitch.SwitchBlockEntity
|
||||||
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
|
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
|
||||||
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlockEntity
|
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlockEntity
|
||||||
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlock
|
||||||
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlockEntity
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalBlockEntity
|
import net.shadowfacts.phycon.block.terminal.TerminalBlockEntity
|
||||||
|
|
||||||
|
@ -32,6 +34,7 @@ object PhyBlockEntities {
|
||||||
val INSERTER = create(::InserterBlockEntity, PhyBlocks.INSERTER)
|
val INSERTER = create(::InserterBlockEntity, PhyBlocks.INSERTER)
|
||||||
val MINER = create(::MinerBlockEntity, PhyBlocks.MINER)
|
val MINER = create(::MinerBlockEntity, PhyBlocks.MINER)
|
||||||
val REDSTONE_CONTROLLER = create(::RedstoneControllerBlockEntity, PhyBlocks.REDSTONE_CONTROLLER)
|
val REDSTONE_CONTROLLER = create(::RedstoneControllerBlockEntity, PhyBlocks.REDSTONE_CONTROLLER)
|
||||||
|
val REDSTONE_EMITTER = create(::RedstoneEmitterBlockEntity, PhyBlocks.REDSTONE_EMITTER)
|
||||||
|
|
||||||
private fun <T: BlockEntity> create(builder: () -> T, block: Block): BlockEntityType<T> {
|
private fun <T: BlockEntity> create(builder: () -> T, block: Block): BlockEntityType<T> {
|
||||||
return BlockEntityType.Builder.create(builder, block).build(null)
|
return BlockEntityType.Builder.create(builder, block).build(null)
|
||||||
|
@ -45,6 +48,7 @@ object PhyBlockEntities {
|
||||||
register(InserterBlock.ID, INSERTER)
|
register(InserterBlock.ID, INSERTER)
|
||||||
register(MinerBlock.ID, MINER)
|
register(MinerBlock.ID, MINER)
|
||||||
register(RedstoneControllerBlock.ID, REDSTONE_CONTROLLER)
|
register(RedstoneControllerBlock.ID, REDSTONE_CONTROLLER)
|
||||||
|
register(RedstoneEmitterBlock.ID, REDSTONE_EMITTER)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun register(id: Identifier, type: BlockEntityType<*>) {
|
private fun register(id: Identifier, type: BlockEntityType<*>) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import net.shadowfacts.phycon.block.miner.MinerBlock
|
||||||
import net.shadowfacts.phycon.block.netinterface.InterfaceBlock
|
import net.shadowfacts.phycon.block.netinterface.InterfaceBlock
|
||||||
import net.shadowfacts.phycon.block.netswitch.SwitchBlock
|
import net.shadowfacts.phycon.block.netswitch.SwitchBlock
|
||||||
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
|
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
|
||||||
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlock
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,6 +26,7 @@ object PhyBlocks {
|
||||||
val INSERTER = InserterBlock()
|
val INSERTER = InserterBlock()
|
||||||
val MINER = MinerBlock()
|
val MINER = MinerBlock()
|
||||||
val REDSTONE_CONTROLLER = RedstoneControllerBlock()
|
val REDSTONE_CONTROLLER = RedstoneControllerBlock()
|
||||||
|
val REDSTONE_EMITTER = RedstoneEmitterBlock()
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
register(InterfaceBlock.ID, INTERFACE)
|
register(InterfaceBlock.ID, INTERFACE)
|
||||||
|
@ -35,6 +37,7 @@ object PhyBlocks {
|
||||||
register(InserterBlock.ID, INSERTER)
|
register(InserterBlock.ID, INSERTER)
|
||||||
register(MinerBlock.ID, MINER)
|
register(MinerBlock.ID, MINER)
|
||||||
register(RedstoneControllerBlock.ID, REDSTONE_CONTROLLER)
|
register(RedstoneControllerBlock.ID, REDSTONE_CONTROLLER)
|
||||||
|
register(RedstoneEmitterBlock.ID, REDSTONE_EMITTER)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun register(id: Identifier, block: Block) {
|
private fun register(id: Identifier, block: Block) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import net.shadowfacts.phycon.block.miner.MinerBlock
|
||||||
import net.shadowfacts.phycon.block.netinterface.InterfaceBlock
|
import net.shadowfacts.phycon.block.netinterface.InterfaceBlock
|
||||||
import net.shadowfacts.phycon.block.netswitch.SwitchBlock
|
import net.shadowfacts.phycon.block.netswitch.SwitchBlock
|
||||||
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
|
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
|
||||||
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlock
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +29,7 @@ object PhyItems {
|
||||||
val INSERTER = BlockItem(PhyBlocks.INSERTER, Item.Settings())
|
val INSERTER = BlockItem(PhyBlocks.INSERTER, Item.Settings())
|
||||||
val MINER = BlockItem(PhyBlocks.MINER, Item.Settings())
|
val MINER = BlockItem(PhyBlocks.MINER, Item.Settings())
|
||||||
val REDSTONE_CONTROLLER = BlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings())
|
val REDSTONE_CONTROLLER = BlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings())
|
||||||
|
val REDSTONE_EMITTER = BlockItem(PhyBlocks.REDSTONE_EMITTER, Item.Settings())
|
||||||
|
|
||||||
val SCREWDRIVER = ScrewdriverItem()
|
val SCREWDRIVER = ScrewdriverItem()
|
||||||
val CONSOLE = ConsoleItem()
|
val CONSOLE = ConsoleItem()
|
||||||
|
@ -41,6 +43,7 @@ object PhyItems {
|
||||||
register(InserterBlock.ID, INSERTER)
|
register(InserterBlock.ID, INSERTER)
|
||||||
register(MinerBlock.ID, MINER)
|
register(MinerBlock.ID, MINER)
|
||||||
register(RedstoneControllerBlock.ID, REDSTONE_CONTROLLER)
|
register(RedstoneControllerBlock.ID, REDSTONE_CONTROLLER)
|
||||||
|
register(RedstoneEmitterBlock.ID, REDSTONE_EMITTER)
|
||||||
|
|
||||||
register(ScrewdriverItem.ID, SCREWDRIVER)
|
register(ScrewdriverItem.ID, SCREWDRIVER)
|
||||||
register(ConsoleItem.ID, CONSOLE)
|
register(ConsoleItem.ID, CONSOLE)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package net.shadowfacts.phycon.init
|
||||||
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry
|
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry
|
||||||
import net.minecraft.screen.ScreenHandlerType
|
import net.minecraft.screen.ScreenHandlerType
|
||||||
import net.shadowfacts.phycon.block.inserter.InserterScreenHandler
|
import net.shadowfacts.phycon.block.inserter.InserterScreenHandler
|
||||||
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterScreenHandler
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalScreenHandler
|
import net.shadowfacts.phycon.block.terminal.TerminalScreenHandler
|
||||||
|
|
||||||
object PhyScreens {
|
object PhyScreens {
|
||||||
|
@ -11,10 +12,13 @@ object PhyScreens {
|
||||||
private set
|
private set
|
||||||
lateinit var INSERTER: ScreenHandlerType<InserterScreenHandler>
|
lateinit var INSERTER: ScreenHandlerType<InserterScreenHandler>
|
||||||
private set
|
private set
|
||||||
|
lateinit var REDSTONE_EMITTER: ScreenHandlerType<RedstoneEmitterScreenHandler>
|
||||||
|
private set
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
TERMINAL = ScreenHandlerRegistry.registerExtended(TerminalScreenHandler.ID, ::TerminalScreenHandler)
|
TERMINAL = ScreenHandlerRegistry.registerExtended(TerminalScreenHandler.ID, ::TerminalScreenHandler)
|
||||||
INSERTER = ScreenHandlerRegistry.registerExtended(InserterScreenHandler.ID, ::InserterScreenHandler)
|
INSERTER = ScreenHandlerRegistry.registerExtended(InserterScreenHandler.ID, ::InserterScreenHandler)
|
||||||
|
REDSTONE_EMITTER = ScreenHandlerRegistry.registerExtended(RedstoneEmitterScreenHandler.ID, ::RedstoneEmitterScreenHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package net.shadowfacts.phycon.networking
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketSender
|
||||||
|
import net.minecraft.network.Packet
|
||||||
|
import net.minecraft.network.PacketByteBuf
|
||||||
|
import net.minecraft.server.MinecraftServer
|
||||||
|
import net.minecraft.server.network.ServerPlayNetworkHandler
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.minecraft.util.registry.Registry
|
||||||
|
import net.minecraft.util.registry.RegistryKey
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.block.inserter.InserterBlockEntity
|
||||||
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlockEntity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
object C2SConfigureRedstoneEmitterAmount: ServerReceiver {
|
||||||
|
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "configure_redstone_emitter_amount")
|
||||||
|
|
||||||
|
operator fun invoke(be: RedstoneEmitterBlockEntity): Packet<*> {
|
||||||
|
val buf = PacketByteBufs.create()
|
||||||
|
|
||||||
|
buf.writeIdentifier(be.world!!.registryKey.value)
|
||||||
|
buf.writeBlockPos(be.pos)
|
||||||
|
buf.writeVarInt(be.maxAmount)
|
||||||
|
|
||||||
|
return createPacket(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun receive(server: MinecraftServer, player: ServerPlayerEntity, handler: ServerPlayNetworkHandler, buf: PacketByteBuf, responseSender: PacketSender) {
|
||||||
|
val dimID = buf.readIdentifier()
|
||||||
|
val pos = buf.readBlockPos()
|
||||||
|
val amount = buf.readVarInt()
|
||||||
|
|
||||||
|
server.execute {
|
||||||
|
val key = RegistryKey.of(Registry.DIMENSION, dimID)
|
||||||
|
val world = server.getWorld(key) ?: return@execute
|
||||||
|
val be = world.getBlockEntity(pos) as? RedstoneEmitterBlockEntity ?: return@execute
|
||||||
|
be.maxAmount = amount
|
||||||
|
be.markDirty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
{
|
||||||
|
"multipart": [
|
||||||
|
{
|
||||||
|
"apply": { "model": "phycon:block/cable_center" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "facing": "down" },
|
||||||
|
"apply": { "model": "phycon:block/redstone_emitter_side" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "facing": "up" },
|
||||||
|
"apply": { "model": "phycon:block/redstone_emitter_side", "x": 180 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "facing": "north" },
|
||||||
|
"apply": { "model": "phycon:block/redstone_emitter_side", "x": 270 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "facing": "south" },
|
||||||
|
"apply": { "model": "phycon:block/redstone_emitter_side", "x": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "facing": "west" },
|
||||||
|
"apply": { "model": "phycon:block/redstone_emitter_side", "x": 90, "y": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "facing": "east" },
|
||||||
|
"apply": { "model": "phycon:block/redstone_emitter_side", "x": 90, "y": 270 }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"when": { "cable_connection": "up", "facing": "down" },
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_straight" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "cable_connection": "down", "facing": "up" },
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_straight", "x": 180 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "cable_connection": "north", "facing": "south" },
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_straight", "x": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "cable_connection": "south", "facing": "north" },
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_straight", "x": 270 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "cable_connection": "west", "facing": "east" },
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_straight", "x": 90, "y": 270 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": { "cable_connection": "east", "facing": "west" },
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_straight", "x": 90, "y": 90 }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "north", "facing": "down"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "east", "facing": "down"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "y": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "south", "facing": "down"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "y": 180 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "west", "facing": "down"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "y": 270 }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "north", "facing": "up"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 180, "y": 180 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "east", "facing": "up"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 180, "y": 270 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "south", "facing": "up"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 180 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "west", "facing": "up"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 180, "y": 90 }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "down", "facing": "north"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 90, "y": 180 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "up", "facing": "north"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 270 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "west", "facing": "north"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_2" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "east", "facing": "north"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_2", "x": 180, "y": 180 }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "down", "facing": "south"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "up", "facing": "south"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 270, "y": 180 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "west", "facing": "south"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_3" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "east", "facing": "south"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_3", "x": 180, "y": 180 }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
"when": {"cable_connection": "down", "facing": "west"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 90, "y": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "up", "facing": "west"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 270, "y": 270 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "north", "facing": "west"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_3", "y": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "south", "facing": "west"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_3", "x": 180, "y": 270 }
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "down", "facing": "east"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 90, "y": 270 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "up", "facing": "east"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner", "x": 270, "y": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "north", "facing": "east"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_2", "y": 90 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {"cable_connection": "south", "facing": "east"},
|
||||||
|
"apply": { "model": "phycon:block/interface_cable_corner_2", "x": 180, "y": 270 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
"block.phycon.inserter": "Inventory Inserter",
|
"block.phycon.inserter": "Inventory Inserter",
|
||||||
"block.phycon.miner": "Block Miner",
|
"block.phycon.miner": "Block Miner",
|
||||||
"block.phycon.redstone_controller": "Redstone Controller",
|
"block.phycon.redstone_controller": "Redstone Controller",
|
||||||
|
"block.phycon.redstone_emitter": "Redstone Emitter",
|
||||||
|
|
||||||
"item.phycon.screwdriver": "Screwdriver",
|
"item.phycon.screwdriver": "Screwdriver",
|
||||||
"item.phycon.console": "Console",
|
"item.phycon.console": "Console",
|
||||||
|
@ -25,5 +26,6 @@
|
||||||
"gui.phycon.redstone_mode.rising_edge": "Rising Edge",
|
"gui.phycon.redstone_mode.rising_edge": "Rising Edge",
|
||||||
"gui.phycon.redstone_mode.falling_edge": "Falling Edge",
|
"gui.phycon.redstone_mode.falling_edge": "Falling Edge",
|
||||||
"gui.phycon.activation_mode.automatic": "Automatic",
|
"gui.phycon.activation_mode.automatic": "Automatic",
|
||||||
"gui.phycon.activation_mode.managed": "Managed"
|
"gui.phycon.activation_mode.managed": "Managed",
|
||||||
|
"gui.phycon.emitter.count": "%d Item(s)"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"parent": "block/block",
|
||||||
|
"textures": {
|
||||||
|
"cable": "phycon:block/cable_straight",
|
||||||
|
"front": "phycon:block/redstone_emitter_front",
|
||||||
|
"back": "phycon:block/redstone_emitter_back",
|
||||||
|
"side": "phycon:block/redstone_emitter_back"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [0, 0, 0],
|
||||||
|
"to": [16, 3, 16],
|
||||||
|
"faces": {
|
||||||
|
"down": { "texture": "#front" },
|
||||||
|
"up": { "texture": "#back" },
|
||||||
|
"north": { "texture": "#side" },
|
||||||
|
"south": { "texture": "#side" },
|
||||||
|
"west": { "texture": "#side" },
|
||||||
|
"east": { "texture": "#side" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [6, 3, 6],
|
||||||
|
"to": [10, 6, 10],
|
||||||
|
"faces": {
|
||||||
|
"north": { "texture": "#cable" },
|
||||||
|
"south": { "texture": "#cable" },
|
||||||
|
"west": { "texture": "#cable" },
|
||||||
|
"east": { "texture": "#cable" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:block",
|
||||||
|
"pools": [
|
||||||
|
{
|
||||||
|
"rolls": 1,
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:item",
|
||||||
|
"name": "phycon:redstone_emitter"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"condition": "minecraft:survives_explosion"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue