Initial commit
This commit is contained in:
		
							
								
								
									
										68
									
								
								src/main/kotlin/de/mattv/quarry/QuarryBlock.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/main/kotlin/de/mattv/quarry/QuarryBlock.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
package de.mattv.quarry
 | 
			
		||||
 | 
			
		||||
import mcjty.theoneprobe.api.IProbeHitData
 | 
			
		||||
import mcjty.theoneprobe.api.IProbeInfo
 | 
			
		||||
import mcjty.theoneprobe.api.IProbeInfoAccessor
 | 
			
		||||
import mcjty.theoneprobe.api.ProbeMode
 | 
			
		||||
import net.minecraft.core.BlockPos
 | 
			
		||||
import net.minecraft.network.chat.TextComponent
 | 
			
		||||
import net.minecraft.world.InteractionHand
 | 
			
		||||
import net.minecraft.world.InteractionResult
 | 
			
		||||
import net.minecraft.world.entity.item.ItemEntity
 | 
			
		||||
import net.minecraft.world.entity.player.Player
 | 
			
		||||
import net.minecraft.world.item.Item
 | 
			
		||||
import net.minecraft.world.item.ItemStack
 | 
			
		||||
import net.minecraft.world.level.Level
 | 
			
		||||
import net.minecraft.world.level.block.Block
 | 
			
		||||
import net.minecraft.world.level.block.EntityBlock
 | 
			
		||||
import net.minecraft.world.level.block.SoundType
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntity
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntityType
 | 
			
		||||
import net.minecraft.world.level.block.state.BlockState
 | 
			
		||||
import net.minecraft.world.level.material.Material
 | 
			
		||||
import net.minecraft.world.phys.BlockHitResult
 | 
			
		||||
 | 
			
		||||
class QuarryBlock : Block(Properties.of(Material.STONE).sound(SoundType.METAL).strength(5.0f, 10000.0f)), EntityBlock, IProbeInfoAccessor {
 | 
			
		||||
    override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity? = QuarryMod.QUARRY_TILE.get().create(pos, state)
 | 
			
		||||
 | 
			
		||||
    override fun <T : BlockEntity?> getTicker(level: Level, state: BlockState, type: BlockEntityType<T>): BlockEntityTicker<T>? =
 | 
			
		||||
            if (type == QuarryMod.QUARRY_TILE.get()) QuarryTileTicker() else null
 | 
			
		||||
 | 
			
		||||
    override fun use(state: BlockState, level: Level, pos: BlockPos, player: Player, hand: InteractionHand, result: BlockHitResult): InteractionResult {
 | 
			
		||||
        val be = level.getBlockEntity(pos)
 | 
			
		||||
        if (!level.isClientSide() && !player.isSecondaryUseActive && hand == InteractionHand.MAIN_HAND && player.getItemInHand(hand).isEmpty && be is QuarryTile) {
 | 
			
		||||
            player.displayClientMessage(TextComponent(be.playerInfo()), true)
 | 
			
		||||
            return InteractionResult.PASS
 | 
			
		||||
        }
 | 
			
		||||
        return super.use(state, level, pos, player, hand, result)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun dropUpgradeItem(level: Level, pos: BlockPos, count: Int, item: Item) {
 | 
			
		||||
        val x = pos.x.toDouble()
 | 
			
		||||
        val y = pos.y.toDouble()
 | 
			
		||||
        val z = pos.z.toDouble()
 | 
			
		||||
        var toDrop = count
 | 
			
		||||
        while (toDrop > 64) {
 | 
			
		||||
            level.addFreshEntity(ItemEntity(level, x, y, z, ItemStack(item, 64)))
 | 
			
		||||
            toDrop -= 64
 | 
			
		||||
        }
 | 
			
		||||
        if (toDrop > 0)
 | 
			
		||||
            level.addFreshEntity(ItemEntity(level, x, y, z, ItemStack(item, toDrop)))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun playerDestroy(level: Level, player: Player, pos: BlockPos, state: BlockState, be: BlockEntity?, tool: ItemStack) {
 | 
			
		||||
        if (!level.isClientSide() && be is QuarryTile) {
 | 
			
		||||
            val toDrop = be.getUpgradesToDrop()
 | 
			
		||||
            dropUpgradeItem(level, pos, toDrop.a, QuarryMod.QUARRY_SPEED_UPGRADE.get())
 | 
			
		||||
            dropUpgradeItem(level, pos, toDrop.b, QuarryMod.QUARRY_FORTUNE_UPGRADE.get())
 | 
			
		||||
        }
 | 
			
		||||
        super.playerDestroy(level, player, pos, state, be, tool)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun addProbeInfo(mode: ProbeMode?, info: IProbeInfo?, player: Player?, level: Level?, state: BlockState?, data: IProbeHitData?) {
 | 
			
		||||
        val be = level!!.getBlockEntity(data!!.pos)
 | 
			
		||||
        if (be is QuarryTile)
 | 
			
		||||
            be.probeInfo(info!!)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								src/main/kotlin/de/mattv/quarry/QuarryChunk.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/main/kotlin/de/mattv/quarry/QuarryChunk.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
package de.mattv.quarry
 | 
			
		||||
 | 
			
		||||
import net.minecraft.core.BlockPos
 | 
			
		||||
import net.minecraft.nbt.CompoundTag
 | 
			
		||||
 | 
			
		||||
class QuarryChunk(val x: Int, val z: Int) {
 | 
			
		||||
    constructor(pos: BlockPos) : this(
 | 
			
		||||
            pos.x.let {
 | 
			
		||||
                var i = it
 | 
			
		||||
                if (i < 0) i -= 16
 | 
			
		||||
                (i / 16) * 16
 | 
			
		||||
            },
 | 
			
		||||
            pos.z.let {
 | 
			
		||||
                var i = it
 | 
			
		||||
                if (i < 0) i -= 16
 | 
			
		||||
                (i / 16) * 16
 | 
			
		||||
            }
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    constructor(tag: CompoundTag) : this(
 | 
			
		||||
            tag.getInt("x"),
 | 
			
		||||
            tag.getInt("z")
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    fun save(): CompoundTag = CompoundTag().apply {
 | 
			
		||||
        putInt("x", x)
 | 
			
		||||
        putInt("z", z)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun asPos(): BlockPos = BlockPos(x, 0, z)
 | 
			
		||||
 | 
			
		||||
    fun min(other: QuarryChunk) = QuarryChunk(kotlin.math.min(x, other.x), kotlin.math.min(z, other.z))
 | 
			
		||||
    fun max(other: QuarryChunk) = QuarryChunk(kotlin.math.max(x, other.x), kotlin.math.max(z, other.z))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								src/main/kotlin/de/mattv/quarry/QuarryController.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/main/kotlin/de/mattv/quarry/QuarryController.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
package de.mattv.quarry
 | 
			
		||||
 | 
			
		||||
import net.minecraft.core.BlockPos
 | 
			
		||||
import net.minecraft.nbt.CompoundTag
 | 
			
		||||
import net.minecraft.network.chat.Component
 | 
			
		||||
import net.minecraft.network.chat.TextComponent
 | 
			
		||||
import net.minecraft.world.InteractionHand
 | 
			
		||||
import net.minecraft.world.InteractionResultHolder
 | 
			
		||||
import net.minecraft.world.entity.player.Player
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab
 | 
			
		||||
import net.minecraft.world.item.Item
 | 
			
		||||
import net.minecraft.world.item.ItemStack
 | 
			
		||||
import net.minecraft.world.item.TooltipFlag
 | 
			
		||||
import net.minecraft.world.level.ClipContext
 | 
			
		||||
import net.minecraft.world.level.Level
 | 
			
		||||
 | 
			
		||||
class QuarryController : Item(Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1)) {
 | 
			
		||||
    private var areaMode = false
 | 
			
		||||
    private var areaModeFirstPos: QuarryChunk? = null
 | 
			
		||||
    private var quarry: BlockPos? = null
 | 
			
		||||
 | 
			
		||||
    override fun use(level: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
 | 
			
		||||
        if (!level.isClientSide() && hand == InteractionHand.MAIN_HAND) {
 | 
			
		||||
            val item = player.getItemInHand(hand)
 | 
			
		||||
            load(item)
 | 
			
		||||
            if (player.isSecondaryUseActive) {
 | 
			
		||||
                val ray = getPlayerPOVHitResult(level, player, ClipContext.Fluid.NONE)
 | 
			
		||||
                val block = ray.blockPos
 | 
			
		||||
                val be = level.getBlockEntity(block)
 | 
			
		||||
                if (be is QuarryTile) {
 | 
			
		||||
                    quarry = block
 | 
			
		||||
                    player.displayClientMessage(TextComponent("Bound controller to ${block.x}, ${block.y}, ${block.z}"), true)
 | 
			
		||||
                    save(item)
 | 
			
		||||
                    return InteractionResultHolder.success(item)
 | 
			
		||||
                }
 | 
			
		||||
                areaMode = !areaMode
 | 
			
		||||
                if (!areaMode) areaModeFirstPos = null
 | 
			
		||||
                player.displayClientMessage(TextComponent(if (areaMode) "Mode: Area" else "Mode: Single"), true)
 | 
			
		||||
                save(item)
 | 
			
		||||
                return InteractionResultHolder.success(item)
 | 
			
		||||
            } else if (quarry != null) {
 | 
			
		||||
                val be = level.getBlockEntity(quarry!!)
 | 
			
		||||
                if (be is QuarryTile) {
 | 
			
		||||
                    val chunk = QuarryChunk(player.blockPosition())
 | 
			
		||||
                    if (areaMode && areaModeFirstPos != null) {
 | 
			
		||||
                        val chunk1 = areaModeFirstPos!!.min(chunk)
 | 
			
		||||
                        val chunk2 = areaModeFirstPos!!.max(chunk)
 | 
			
		||||
                        var chunkCount = 0
 | 
			
		||||
                        for (x in chunk1.x..chunk2.x step 16) for (z in chunk1.z..chunk2.z step 16) {
 | 
			
		||||
                            be.addChunk(QuarryChunk(x, z))
 | 
			
		||||
                            chunkCount++
 | 
			
		||||
                        }
 | 
			
		||||
                        player.displayClientMessage(TextComponent("Added $chunkCount chunks to quarry"), true)
 | 
			
		||||
                        save(item)
 | 
			
		||||
                        return InteractionResultHolder.pass(item)
 | 
			
		||||
                    } else if (areaMode) {
 | 
			
		||||
                        areaModeFirstPos = chunk
 | 
			
		||||
                        player.displayClientMessage(TextComponent("Set first position of area"), true)
 | 
			
		||||
                        save(item)
 | 
			
		||||
                        return InteractionResultHolder.pass(item)
 | 
			
		||||
                    } else {
 | 
			
		||||
                        be.addChunk(chunk)
 | 
			
		||||
                        player.displayClientMessage(TextComponent("Added chunk"), true)
 | 
			
		||||
                        save(item)
 | 
			
		||||
                        return InteractionResultHolder.pass(item)
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.displayClientMessage(TextComponent("Bound quarry is invalid, please rebind"), true)
 | 
			
		||||
                    quarry = null
 | 
			
		||||
                    save(item)
 | 
			
		||||
                    return InteractionResultHolder.fail(item)
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                player.displayClientMessage(TextComponent("Controller is not bound"), true)
 | 
			
		||||
                return InteractionResultHolder.fail(item)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return super.use(level, player, hand)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun appendHoverText(stack: ItemStack, level: Level?, tooltip: MutableList<Component>, flagIn: TooltipFlag) {
 | 
			
		||||
        load(stack)
 | 
			
		||||
        tooltip.add(TextComponent(if (areaMode) "Mode: Area" else "Mode: Single"))
 | 
			
		||||
        if (areaModeFirstPos != null)
 | 
			
		||||
            tooltip.add(TextComponent("First chunk: ${areaModeFirstPos!!.x} ${areaModeFirstPos!!.z}"))
 | 
			
		||||
        if (quarry != null)
 | 
			
		||||
            tooltip.add(TextComponent("Quarry: ${quarry!!.x}, ${quarry!!.y}, ${quarry!!.z}"))
 | 
			
		||||
        super.appendHoverText(stack, level, tooltip, flagIn)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun save(stack: ItemStack) {
 | 
			
		||||
        val tag = CompoundTag()
 | 
			
		||||
        tag.putBoolean("area", areaMode)
 | 
			
		||||
        if (areaModeFirstPos != null)
 | 
			
		||||
            tag.put("areaFirst", areaModeFirstPos!!.save())
 | 
			
		||||
        if (quarry != null)
 | 
			
		||||
            tag.putIntArray("quarry", arrayListOf(quarry!!.x, quarry!!.y, quarry!!.z))
 | 
			
		||||
 | 
			
		||||
        stack.tag = tag
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun load(stack: ItemStack) {
 | 
			
		||||
        val tag = stack.getOrCreateTag()
 | 
			
		||||
        if (tag.contains("area"))
 | 
			
		||||
            areaMode = tag.getBoolean("area")
 | 
			
		||||
        areaModeFirstPos =
 | 
			
		||||
            if (tag.contains("areaFirst")) QuarryChunk(tag.getCompound("areaFirst"))
 | 
			
		||||
            else null
 | 
			
		||||
        quarry =
 | 
			
		||||
            if (tag.contains("quarry")) {
 | 
			
		||||
                val arr = tag.getIntArray("quarry")
 | 
			
		||||
                BlockPos(arr[0], arr[1], arr[2])
 | 
			
		||||
            }
 | 
			
		||||
            else null
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/main/kotlin/de/mattv/quarry/QuarryMod.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/main/kotlin/de/mattv/quarry/QuarryMod.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
package de.mattv.quarry
 | 
			
		||||
 | 
			
		||||
import net.minecraft.world.item.BlockItem
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab
 | 
			
		||||
import net.minecraft.world.item.Item
 | 
			
		||||
import net.minecraft.world.level.block.Block
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntityType
 | 
			
		||||
import net.minecraftforge.event.RegistryEvent
 | 
			
		||||
import net.minecraftforge.eventbus.api.SubscribeEvent
 | 
			
		||||
import net.minecraftforge.fml.common.Mod
 | 
			
		||||
import net.minecraftforge.registries.DeferredRegister
 | 
			
		||||
import net.minecraftforge.registries.ForgeRegistries
 | 
			
		||||
import net.minecraftforge.registries.RegistryObject
 | 
			
		||||
import thedarkcolour.kotlinforforge.forge.MOD_BUS
 | 
			
		||||
import thedarkcolour.kotlinforforge.forge.registerObject
 | 
			
		||||
 | 
			
		||||
@Mod(QuarryMod.ID)
 | 
			
		||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
 | 
			
		||||
object QuarryMod {
 | 
			
		||||
    const val ID = "mquarry"
 | 
			
		||||
 | 
			
		||||
    //val LOGGER: Logger = LogManager.getLogger(ID)
 | 
			
		||||
 | 
			
		||||
    val BLOCK_REGISTRY = DeferredRegister.create(ForgeRegistries.BLOCKS, ID)
 | 
			
		||||
    val TILES_REGISTRY = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITIES, ID)
 | 
			
		||||
    val ITEM_REGISTRY = DeferredRegister.create(ForgeRegistries.ITEMS, ID)
 | 
			
		||||
 | 
			
		||||
    val QUARRY_BLOCK = BLOCK_REGISTRY.registerObject("quarry", ::QuarryBlock)
 | 
			
		||||
    val QUARRY_TILE = TILES_REGISTRY.registerObject("quarry") { BlockEntityType.Builder.of(::QuarryTile, QUARRY_BLOCK.get()).build(null) }
 | 
			
		||||
    val QUARRY_SPEED_UPGRADE = ITEM_REGISTRY.registerObject("upgrade_speed") { QuarryUpgrade(QuarryUpgrade.Type.SPEED) }
 | 
			
		||||
    val QUARRY_FORTUNE_UPGRADE = ITEM_REGISTRY.registerObject("upgrade_fortune") { QuarryUpgrade(QuarryUpgrade.Type.FORTUNE) }
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        ITEM_REGISTRY.registerObject("controller", ::QuarryController)
 | 
			
		||||
        //LOGGER.log(Level.INFO, "MQuarry initializing")
 | 
			
		||||
        BLOCK_REGISTRY.register(MOD_BUS)
 | 
			
		||||
        TILES_REGISTRY.register(MOD_BUS)
 | 
			
		||||
        ITEM_REGISTRY.register(MOD_BUS)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SubscribeEvent
 | 
			
		||||
    fun onRegisterItems(event: RegistryEvent.Register<Item>) {
 | 
			
		||||
        for (entry in BLOCK_REGISTRY.entries.stream().map(RegistryObject<Block>::get)) {
 | 
			
		||||
            val item = BlockItem(entry, Item.Properties().tab(CreativeModeTab.TAB_MISC))
 | 
			
		||||
            item.setRegistryName(entry.registryName)
 | 
			
		||||
            event.registry.register(item)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										276
									
								
								src/main/kotlin/de/mattv/quarry/QuarryTile.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								src/main/kotlin/de/mattv/quarry/QuarryTile.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
			
		||||
package de.mattv.quarry
 | 
			
		||||
 | 
			
		||||
import com.mojang.authlib.GameProfile
 | 
			
		||||
import mcjty.theoneprobe.api.IProbeInfo
 | 
			
		||||
import net.minecraft.core.BlockPos
 | 
			
		||||
import net.minecraft.core.BlockPos.MutableBlockPos
 | 
			
		||||
import net.minecraft.core.Direction
 | 
			
		||||
import net.minecraft.nbt.CompoundTag
 | 
			
		||||
import net.minecraft.nbt.ListTag
 | 
			
		||||
import net.minecraft.nbt.Tag
 | 
			
		||||
import net.minecraft.network.chat.TextComponent
 | 
			
		||||
import net.minecraft.network.protocol.Packet
 | 
			
		||||
import net.minecraft.network.protocol.game.ClientGamePacketListener
 | 
			
		||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket
 | 
			
		||||
import net.minecraft.server.level.ServerLevel
 | 
			
		||||
import net.minecraft.util.Tuple
 | 
			
		||||
import net.minecraft.world.InteractionHand
 | 
			
		||||
import net.minecraft.world.entity.player.Player
 | 
			
		||||
import net.minecraft.world.item.ItemStack
 | 
			
		||||
import net.minecraft.world.item.Items
 | 
			
		||||
import net.minecraft.world.item.enchantment.Enchantments
 | 
			
		||||
import net.minecraft.world.level.Level
 | 
			
		||||
import net.minecraft.world.level.block.Block
 | 
			
		||||
import net.minecraft.world.level.block.Blocks
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntity
 | 
			
		||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
 | 
			
		||||
import net.minecraft.world.level.block.state.BlockState
 | 
			
		||||
import net.minecraftforge.common.MinecraftForge
 | 
			
		||||
import net.minecraftforge.common.capabilities.Capability
 | 
			
		||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
 | 
			
		||||
import net.minecraftforge.common.util.FakePlayer
 | 
			
		||||
import net.minecraftforge.common.util.FakePlayerFactory
 | 
			
		||||
import net.minecraftforge.common.util.LazyOptional
 | 
			
		||||
import net.minecraftforge.energy.CapabilityEnergy
 | 
			
		||||
import net.minecraftforge.energy.IEnergyStorage
 | 
			
		||||
import net.minecraftforge.event.world.BlockEvent
 | 
			
		||||
import net.minecraftforge.items.CapabilityItemHandler
 | 
			
		||||
import net.minecraftforge.items.ItemHandlerHelper
 | 
			
		||||
import java.util.*
 | 
			
		||||
import kotlin.math.max
 | 
			
		||||
import kotlin.math.min
 | 
			
		||||
import kotlin.math.pow
 | 
			
		||||
import kotlin.streams.asSequence
 | 
			
		||||
 | 
			
		||||
object FakeQuarryPlayer {
 | 
			
		||||
    private val profile = GameProfile(UUID.fromString("21a819e9-a98d-4e58-bd52-f60b9570a918"), "[MQuarry]")
 | 
			
		||||
    fun get(level: ServerLevel): FakePlayer = FakePlayerFactory.get(level, profile)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class QuarryTileTicker<T: BlockEntity?> : BlockEntityTicker<T> {
 | 
			
		||||
    override fun tick(level: Level, pos: BlockPos, state: BlockState, be: T) {
 | 
			
		||||
        if (level.isClientSide()) return
 | 
			
		||||
        val tile = be as QuarryTile
 | 
			
		||||
        tile.tick(level)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class QuarryTile(private val myPos: BlockPos, state: BlockState) : BlockEntity(QuarryMod.QUARRY_TILE.get(), myPos, state), IEnergyStorage, ICapabilityProvider {
 | 
			
		||||
    private var energyStored: Int = 0
 | 
			
		||||
    private var speedLevel: Int = 0
 | 
			
		||||
    private var fortuneLevel: Int = 0
 | 
			
		||||
    private var speedUpgradesNeeded: Int = 1
 | 
			
		||||
    private var fortuneUpgradesNeeded: Int = 1
 | 
			
		||||
    private var itemsToDrop: MutableList<ItemStack> = ArrayList()
 | 
			
		||||
    private var curPos: MutableBlockPos = MutableBlockPos(0, myPos.y - 1, 0)
 | 
			
		||||
    private var curChunk: QuarryChunk? = null
 | 
			
		||||
    private var chunksTodo: MutableList<QuarryChunk> = ArrayList()
 | 
			
		||||
 | 
			
		||||
    override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int {
 | 
			
		||||
        val recv = min(QUARRY_MAX_ENERGY - energyStored, maxReceive)
 | 
			
		||||
        if (!simulate)
 | 
			
		||||
            energyStored += recv
 | 
			
		||||
        return recv
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun extractEnergy(maxExtract: Int, simulate: Boolean): Int {
 | 
			
		||||
        return 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getEnergyStored(): Int {
 | 
			
		||||
        return energyStored
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getMaxEnergyStored(): Int {
 | 
			
		||||
        return QUARRY_MAX_ENERGY
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun canExtract(): Boolean {
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun canReceive(): Boolean {
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun <T: Any?> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
 | 
			
		||||
        if (cap == CapabilityEnergy.ENERGY) return LazyOptional.of { this as T }
 | 
			
		||||
        return super<BlockEntity>.getCapability(cap, side)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun getPickaxe(): ItemStack = Items.NETHERITE_PICKAXE.defaultInstance.apply {
 | 
			
		||||
        if (fortuneLevel > 0) enchant(Enchantments.BLOCK_FORTUNE, fortuneLevel)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun breakBlock(level: Level, pos: BlockPos): Boolean {
 | 
			
		||||
        val state = level.getBlockState(pos)
 | 
			
		||||
        val pickaxe = getPickaxe()
 | 
			
		||||
        val player = FakeQuarryPlayer.get(level as ServerLevel)
 | 
			
		||||
        player.setItemInHand(InteractionHand.MAIN_HAND, pickaxe)
 | 
			
		||||
        val event = BlockEvent.BreakEvent(level, pos, state, player)
 | 
			
		||||
        MinecraftForge.EVENT_BUS.post(event)
 | 
			
		||||
        if (event.isCanceled) return true
 | 
			
		||||
        if (state.isAir) return true
 | 
			
		||||
        if (state.getDestroySpeed(level, pos) < 0) return true
 | 
			
		||||
        val energyNeeded = ENERGY_BASE + max(0, (state.getDestroySpeed(level, pos) * ENERGY_PER_STRENGTH).toInt())
 | 
			
		||||
        if (energyStored < energyNeeded) return false
 | 
			
		||||
        energyStored -= energyNeeded
 | 
			
		||||
        if (level.getFluidState(pos).isEmpty) // Is not a liquid
 | 
			
		||||
            itemsToDrop.addAll(Block.getDrops(state, level, pos, level.getBlockEntity(pos), player, pickaxe))
 | 
			
		||||
        level.setBlock(pos, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL)
 | 
			
		||||
        setChanged()
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun newChunk() {
 | 
			
		||||
        curChunk = chunksTodo.removeFirstOrNull()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun tick(level: Level) {
 | 
			
		||||
        // Mine
 | 
			
		||||
        if (curChunk == null) newChunk()
 | 
			
		||||
        if (itemsToDrop.isEmpty() && curChunk != null) {
 | 
			
		||||
            var curChunkPos = curChunk!!.asPos()
 | 
			
		||||
            for (i in 0..speedLevel) {
 | 
			
		||||
                if (!breakBlock(level, curChunkPos.offset(curPos))) break
 | 
			
		||||
                curPos.x++
 | 
			
		||||
                if (curPos.x == 16) {
 | 
			
		||||
                    curPos.x = 0
 | 
			
		||||
                    curPos.z++
 | 
			
		||||
                }
 | 
			
		||||
                if (curPos.z == 16) {
 | 
			
		||||
                    curPos.z = 0
 | 
			
		||||
                    curPos.y--
 | 
			
		||||
                }
 | 
			
		||||
                if (curPos.y == level.minBuildHeight - 1) {
 | 
			
		||||
                    curPos.y = myPos.y - 1
 | 
			
		||||
                    newChunk()
 | 
			
		||||
                    if (curChunk == null) break
 | 
			
		||||
                    curChunkPos = curChunk!!.asPos()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (itemsToDrop.isEmpty()) return
 | 
			
		||||
        // Drop items
 | 
			
		||||
        val te = level.getBlockEntity(myPos.offset(0, 1, 0)) ?: return
 | 
			
		||||
        val itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.DOWN).orElse(null) ?: return
 | 
			
		||||
        val newDrops = ArrayList<ItemStack>()
 | 
			
		||||
        for (drop in itemsToDrop) {
 | 
			
		||||
            val newDrop = ItemHandlerHelper.insertItemStacked(itemHandler, drop, false)
 | 
			
		||||
            if (!newDrop.isEmpty) newDrops.add(newDrop)
 | 
			
		||||
        }
 | 
			
		||||
        itemsToDrop = newDrops
 | 
			
		||||
        setChanged()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun playerInfo(): String = "Speed: $speedLevel, needed: $speedUpgradesNeeded | Fortune: $fortuneLevel, needed: $fortuneUpgradesNeeded | " + if (curChunk != null) "Chunks in queue: ${chunksTodo.size}" else "Idle"
 | 
			
		||||
 | 
			
		||||
    fun useUpgrade(player: Player, stack: ItemStack) {
 | 
			
		||||
        val item = stack.item as QuarryUpgrade
 | 
			
		||||
        if (item.ty == QuarryUpgrade.Type.SPEED) {
 | 
			
		||||
            val used = min(stack.count, speedUpgradesNeeded)
 | 
			
		||||
            stack.shrink(used)
 | 
			
		||||
            speedUpgradesNeeded -= used
 | 
			
		||||
            if (speedUpgradesNeeded == 0) {
 | 
			
		||||
                speedLevel++
 | 
			
		||||
                speedUpgradesNeeded = (2.0).pow(speedLevel).toInt()
 | 
			
		||||
                player.displayClientMessage(TextComponent("New speed level: $speedLevel, upgrades needed for next level: $speedUpgradesNeeded"), true)
 | 
			
		||||
            } else
 | 
			
		||||
                player.displayClientMessage(TextComponent("Upgrades needed for next level: $speedUpgradesNeeded"), true)
 | 
			
		||||
        } else {
 | 
			
		||||
            val used = min(stack.count, fortuneUpgradesNeeded)
 | 
			
		||||
            stack.shrink(used)
 | 
			
		||||
            fortuneUpgradesNeeded -= used
 | 
			
		||||
            if (fortuneUpgradesNeeded == 0) {
 | 
			
		||||
                fortuneLevel++
 | 
			
		||||
                fortuneUpgradesNeeded = (2.0).pow(fortuneLevel).toInt()
 | 
			
		||||
                player.displayClientMessage(TextComponent("New fortune level: $fortuneLevel, upgrades needed for next level: $fortuneUpgradesNeeded"), true)
 | 
			
		||||
            } else
 | 
			
		||||
                player.displayClientMessage(TextComponent("Upgrades needed for next level: $fortuneUpgradesNeeded"), true)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getUpgradesToDrop() : Tuple<Int, Int> {
 | 
			
		||||
        var speed = (2.0).pow(speedLevel).toInt() - speedUpgradesNeeded
 | 
			
		||||
        for (i in 1..speedLevel) speed += (2.0).pow(i-1).toInt()
 | 
			
		||||
        var fortune = (2.0).pow(fortuneLevel).toInt() - fortuneUpgradesNeeded
 | 
			
		||||
        for (i in 1..fortuneLevel) fortune += (2.0).pow(i-1).toInt()
 | 
			
		||||
        return Tuple(speed, fortune)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addChunk(chunk: QuarryChunk) = chunksTodo.add(chunk)
 | 
			
		||||
 | 
			
		||||
    private fun saveClientData(tag: CompoundTag) {
 | 
			
		||||
        tag.putInt("energy", energyStored)
 | 
			
		||||
        tag.putInt("speedLevel", speedLevel)
 | 
			
		||||
        tag.putInt("fortuneLevel", fortuneLevel)
 | 
			
		||||
        tag.putInt("speedUpgradesNeeded", speedUpgradesNeeded)
 | 
			
		||||
        tag.putInt("fortuneUpgradesNeeded", fortuneUpgradesNeeded)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun saveAdditional(tag: CompoundTag) {
 | 
			
		||||
        saveClientData(tag)
 | 
			
		||||
        val dropsList = ListTag()
 | 
			
		||||
        itemsToDrop.stream().forEach {
 | 
			
		||||
            val itemTag = CompoundTag()
 | 
			
		||||
            it.save(itemTag)
 | 
			
		||||
            dropsList.add(itemTag)
 | 
			
		||||
        }
 | 
			
		||||
        tag.put("drops", dropsList)
 | 
			
		||||
        tag.putInt("curPosX", curPos.x)
 | 
			
		||||
        tag.putInt("curPosY", curPos.y)
 | 
			
		||||
        tag.putInt("curPosZ", curPos.z)
 | 
			
		||||
        if (curChunk != null) {
 | 
			
		||||
            tag.put("curChunk", curChunk!!.save())
 | 
			
		||||
        }
 | 
			
		||||
        val chunkList = ListTag()
 | 
			
		||||
        chunkList.addAll(chunksTodo.stream().map(QuarryChunk::save).asSequence())
 | 
			
		||||
        tag.put("chunks", chunkList)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun load(tag: CompoundTag) {
 | 
			
		||||
        energyStored = tag.getInt("energy")
 | 
			
		||||
        speedLevel = tag.getInt("speedLevel")
 | 
			
		||||
        fortuneLevel = tag.getInt("fortuneLevel")
 | 
			
		||||
        speedUpgradesNeeded = tag.getInt("speedUpgradesNeeded")
 | 
			
		||||
        fortuneUpgradesNeeded = tag.getInt("fortuneUpgradesNeeded")
 | 
			
		||||
        if (!tag.contains("drops")) return // Everything after this is server only
 | 
			
		||||
        itemsToDrop = tag.getList("drops", Tag.TAG_COMPOUND.toInt())
 | 
			
		||||
                .map { ItemStack.of(it as CompoundTag) }.toMutableList()
 | 
			
		||||
        curPos.x = tag.getInt("curPosX")
 | 
			
		||||
        curPos.y = tag.getInt("curPosY")
 | 
			
		||||
        curPos.z = tag.getInt("curPosZ")
 | 
			
		||||
        curChunk = if (tag.contains("curChunk")) QuarryChunk(tag.get("curChunk") as CompoundTag) else null
 | 
			
		||||
        chunksTodo = tag.getList("chunks", CompoundTag.TAG_COMPOUND.toInt())
 | 
			
		||||
                .map { QuarryChunk(it as CompoundTag) }.toMutableList()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getUpdateTag(): CompoundTag {
 | 
			
		||||
        val tag = CompoundTag()
 | 
			
		||||
        saveClientData(tag)
 | 
			
		||||
        return tag
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getUpdatePacket(): Packet<ClientGamePacketListener>? = ClientboundBlockEntityDataPacket.create(this)
 | 
			
		||||
 | 
			
		||||
    fun probeInfo(info: IProbeInfo) {
 | 
			
		||||
        val speedMax = (2.0).pow(speedLevel).toInt()
 | 
			
		||||
        info.text("Speed: level $speedLevel, ${speedMax - speedUpgradesNeeded}/$speedMax")
 | 
			
		||||
        val fortuneMax = (2.0).pow(fortuneLevel).toInt()
 | 
			
		||||
        info.text("Fortune: level $fortuneLevel, ${fortuneMax - fortuneUpgradesNeeded}/$fortuneMax")
 | 
			
		||||
        if (itemsToDrop.isNotEmpty())
 | 
			
		||||
            info.text("Waiting to extract items...")
 | 
			
		||||
        else if (curChunk != null) {
 | 
			
		||||
            val pos = curChunk!!.asPos().offset(curPos)
 | 
			
		||||
            info.text("Currently mining: ${pos.x} ${pos.y} ${pos.z}")
 | 
			
		||||
            info.text("Chunks in queue: ${chunksTodo.size}")
 | 
			
		||||
        } else info.text("Idle")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val QUARRY_MAX_ENERGY: Int = 100_000_000
 | 
			
		||||
        const val ENERGY_BASE = 1000
 | 
			
		||||
        const val ENERGY_PER_STRENGTH = 500
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/main/kotlin/de/mattv/quarry/QuarryUpgrade.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/main/kotlin/de/mattv/quarry/QuarryUpgrade.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
package de.mattv.quarry
 | 
			
		||||
 | 
			
		||||
import net.minecraft.world.InteractionHand
 | 
			
		||||
import net.minecraft.world.InteractionResult
 | 
			
		||||
import net.minecraft.world.item.CreativeModeTab
 | 
			
		||||
import net.minecraft.world.item.Item
 | 
			
		||||
import net.minecraft.world.item.context.UseOnContext
 | 
			
		||||
 | 
			
		||||
class QuarryUpgrade(val ty: Type) : Item(Properties().tab(CreativeModeTab.TAB_MISC)) {
 | 
			
		||||
    enum class Type { SPEED, FORTUNE }
 | 
			
		||||
 | 
			
		||||
    override fun useOn(ctx: UseOnContext): InteractionResult {
 | 
			
		||||
        val be = ctx.level.getBlockEntity(ctx.clickedPos)
 | 
			
		||||
        if (!ctx.level.isClientSide() && ctx.hand == InteractionHand.MAIN_HAND && be is QuarryTile) {
 | 
			
		||||
            be.useUpgrade(ctx.player!!, ctx.itemInHand)
 | 
			
		||||
            return InteractionResult.CONSUME
 | 
			
		||||
        }
 | 
			
		||||
        return super.useOn(ctx)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								src/main/resources/META-INF/mods.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/main/resources/META-INF/mods.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
# This is an example mods.toml file. It contains the data relating to the loading mods.
 | 
			
		||||
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
 | 
			
		||||
# The overall format is standard TOML format, v0.5.0.
 | 
			
		||||
# Note that there are a couple of TOML lists in this file.
 | 
			
		||||
# Find more information on toml format here:  https://github.com/toml-lang/toml
 | 
			
		||||
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
 | 
			
		||||
modLoader="kotlinforforge" #mandatory
 | 
			
		||||
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
 | 
			
		||||
loaderVersion="[3,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
 | 
			
		||||
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
 | 
			
		||||
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
 | 
			
		||||
license="GNU GPL 3.0"
 | 
			
		||||
# A URL to refer people to when problems occur with this mod
 | 
			
		||||
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
 | 
			
		||||
# A list of mods - how many allowed here is determined by the individual mod loader
 | 
			
		||||
[[mods]] #mandatory
 | 
			
		||||
# The modid of the mod
 | 
			
		||||
modId="mquarry" #mandatory
 | 
			
		||||
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
 | 
			
		||||
# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata
 | 
			
		||||
# see the associated build.gradle script for how to populate this completely automatically during a build
 | 
			
		||||
version="${file.jarVersion}" #mandatory
 | 
			
		||||
# A display name for the mod
 | 
			
		||||
displayName="MQuarry" #mandatory
 | 
			
		||||
# A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/
 | 
			
		||||
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
 | 
			
		||||
# A URL for the "homepage" for this mod, displayed in the mod UI
 | 
			
		||||
#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional
 | 
			
		||||
# A file name (in the root of the mod JAR) containing a logo for display
 | 
			
		||||
#logoFile="mattv.png" #optional
 | 
			
		||||
# A text field displayed in the mod UI
 | 
			
		||||
#credits="Thanks for this example mod goes to Java" #optional
 | 
			
		||||
# A text field displayed in the mod UI
 | 
			
		||||
#authors="Love, Cheese and small house plants" #optional
 | 
			
		||||
# The description text for the mod (multi line!) (#mandatory)
 | 
			
		||||
description='''
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
 | 
			
		||||
[[dependencies.mquarry]] #optional
 | 
			
		||||
   # the modid of the dependency
 | 
			
		||||
   modId="forge" #mandatory
 | 
			
		||||
   # Does this dependency have to exist - if not, ordering below must be specified
 | 
			
		||||
   mandatory=true #mandatory
 | 
			
		||||
   # The version range of the dependency
 | 
			
		||||
   versionRange="[40,)" #mandatory
 | 
			
		||||
   # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
 | 
			
		||||
   ordering="NONE"
 | 
			
		||||
   # Side this dependency is applied on - BOTH, CLIENT or SERVER
 | 
			
		||||
   side="BOTH"
 | 
			
		||||
# Here's another dependency
 | 
			
		||||
[[dependencies.mquarry]]
 | 
			
		||||
   modId="minecraft"
 | 
			
		||||
   mandatory=true
 | 
			
		||||
   # This version range declares a minimum of the current minecraft version up to but not including the next major version
 | 
			
		||||
   versionRange="[1.18.2,1.19)"
 | 
			
		||||
   ordering="NONE"
 | 
			
		||||
   side="BOTH"
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
  "variants": {
 | 
			
		||||
    "": {
 | 
			
		||||
      "model": "mquarry:block/quarry"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								src/main/resources/assets/mquarry/lang/en_us.json
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								src/main/resources/assets/mquarry/lang/en_us.json
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
  "block.mquarry.quarry": "MQuarry",
 | 
			
		||||
 | 
			
		||||
  "item.mquarry.upgrade_speed": "MQuarry speed upgrade",
 | 
			
		||||
  "item.mquarry.upgrade_fortune": "MQuarry fortune upgrade",
 | 
			
		||||
  "item.mquarry.controller": "MQuarry controller"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								src/main/resources/assets/mquarry/models/block/quarry.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/main/resources/assets/mquarry/models/block/quarry.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
{
 | 
			
		||||
  "parent": "block/cube_all",
 | 
			
		||||
  "textures": {
 | 
			
		||||
    "up": "mquarry:blocks/quarry/updown",
 | 
			
		||||
    "down": "mquarry:blocks/quarry/updown",
 | 
			
		||||
    "north": "mquarry:blocks/quarry/side",
 | 
			
		||||
    "south": "mquarry:blocks/quarry/side",
 | 
			
		||||
    "west": "mquarry:blocks/quarry/side",
 | 
			
		||||
    "east": "mquarry:blocks/quarry/side"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "parent": "item/generated",
 | 
			
		||||
  "textures": {
 | 
			
		||||
    "layer0": "mquarry:items/controller"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
{
 | 
			
		||||
  "parent": "mquarry:block/quarry"
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "parent": "item/generated",
 | 
			
		||||
  "textures": {
 | 
			
		||||
    "layer0": "mquarry:items/upgrade_fortune"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "parent": "item/generated",
 | 
			
		||||
  "textures": {
 | 
			
		||||
    "layer0": "mquarry:items/upgrade_speed"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/mquarry/textures/blocks/quarry/side.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/assets/mquarry/textures/blocks/quarry/side.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 593 B  | 
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/mquarry/textures/blocks/quarry/updown.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/assets/mquarry/textures/blocks/quarry/updown.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 504 B  | 
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/assets/mquarry/textures/items/controller.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/assets/mquarry/textures/items/controller.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 4.3 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 768 B  | 
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 767 B  | 
@@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "replace": false,
 | 
			
		||||
  "values": [
 | 
			
		||||
    "mquarry:quarry"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "replace": false,
 | 
			
		||||
  "values": [
 | 
			
		||||
    "mquarry:quarry"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
{
 | 
			
		||||
  "type": "minecraft:block",
 | 
			
		||||
  "pools": [
 | 
			
		||||
    {
 | 
			
		||||
      "rolls": 1.0,
 | 
			
		||||
      "entries": [
 | 
			
		||||
        {
 | 
			
		||||
          "type": "minecraft:item",
 | 
			
		||||
          "name": "mquarry:quarry"
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								src/main/resources/pack.mcmeta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/main/resources/pack.mcmeta
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
{
 | 
			
		||||
    "pack": {
 | 
			
		||||
        "description": "mquarry resources",
 | 
			
		||||
                "pack_format": 8
 | 
			
		||||
                                ,"forge:resource_pack_format": 8
 | 
			
		||||
                        ,"forge:data_pack_format": 9
 | 
			
		||||
                            }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user