diff --git a/README.md b/README.md index a5e63f4..f8a8044 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Iron Chests (StationAPI) - +Requires Fabric Kotlin Basic port of Iron Chests for b1.7.3 with Fabric and [StationAPI](https://github.com/ModificationStation/StationAPI). @@ -13,4 +13,4 @@ unashamedly stole code ## Features - [x] Iron, Gold and Diamond Chest - [ ] Other modded metal chests (Silver, copper, dimando?) -- [ ] Chest upgrades \ No newline at end of file +- [x] Chest upgrades \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 36163e6..c76ced4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,7 +15,7 @@ howmanyitems_version=5.2.1 modmenu_version=v1.8.5-beta.3 # Mod Properties -next_version=0.1.0 +next_version=0.2.0 maven_group=net.zekromaster.minecraft archives_base_name=IronChestsStationAPI diff --git a/src/main/java/net/zekromaster/minecraft/ironchests/mixin/ChestMixin.java b/src/main/java/net/zekromaster/minecraft/ironchests/mixin/ChestMixin.java new file mode 100644 index 0000000..b71db29 --- /dev/null +++ b/src/main/java/net/zekromaster/minecraft/ironchests/mixin/ChestMixin.java @@ -0,0 +1,30 @@ +package net.zekromaster.minecraft.ironchests.mixin; + +import net.minecraft.block.ChestBlock; +import net.minecraft.block.entity.ChestBlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.world.World; +import net.zekromaster.minecraft.ironchests.ChestUpgrade; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ChestBlock.class) +public class ChestMixin { + + @Inject(method = "onUse", at=@At("HEAD"), cancellable = true) + void onUseMixin(World world, int x, int y, int z, PlayerEntity player, CallbackInfoReturnable cir) { + var chest = (ChestBlockEntity) world.getBlockEntity(x, y, z); + var hand = player.getHand(); + if (hand != null) { + if (hand.getItem() instanceof ChestUpgrade upgrade) { + if (upgrade.upgrade(world, x, y, z, player, chest)) { + hand.count--; + } + cir.setReturnValue(true); + } + } + } + +} diff --git a/src/main/kotlin/net/zekromaster/minecraft/ironchests/block-entity.kt b/src/main/kotlin/net/zekromaster/minecraft/ironchests/block.kt similarity index 55% rename from src/main/kotlin/net/zekromaster/minecraft/ironchests/block-entity.kt rename to src/main/kotlin/net/zekromaster/minecraft/ironchests/block.kt index e70441a..cf8a15d 100644 --- a/src/main/kotlin/net/zekromaster/minecraft/ironchests/block-entity.kt +++ b/src/main/kotlin/net/zekromaster/minecraft/ironchests/block.kt @@ -1,18 +1,24 @@ package net.zekromaster.minecraft.ironchests +import net.mine_diver.unsafeevents.listener.EventListener import net.minecraft.block.Block import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.ChestBlockEntity import net.minecraft.block.material.Material import net.minecraft.entity.ItemEntity import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound import net.minecraft.screen.GenericContainerScreenHandler import net.minecraft.world.World import net.modificationstation.stationapi.api.block.BlockState +import net.modificationstation.stationapi.api.event.block.entity.BlockEntityRegisterEvent +import net.modificationstation.stationapi.api.event.recipe.RecipeRegisterEvent +import net.modificationstation.stationapi.api.event.registry.BlockRegistryEvent import net.modificationstation.stationapi.api.gui.screen.container.GuiHelper import net.modificationstation.stationapi.api.item.ItemPlacementContext +import net.modificationstation.stationapi.api.recipe.CraftingRegistry import net.modificationstation.stationapi.api.state.StateManager import net.modificationstation.stationapi.api.state.property.EnumProperty import net.modificationstation.stationapi.api.template.block.TemplateBlockWithEntity @@ -21,13 +27,74 @@ import net.modificationstation.stationapi.api.util.math.Direction import net.zekromaster.minecraft.ironchests.mixin.ChestInventoryAccessor import java.util.* import java.util.function.Predicate -import kotlin.math.floor -class IronChestBlockEntity(material: IronChestMaterial): ChestBlockEntity() { - constructor(): this(IronChestMaterial.IRON) +object IronChestsBlockEntrypoint { + @JvmStatic @get:JvmName("ironChest") + lateinit var IRON_CHEST: IronChestBlock + private set + @JvmStatic @get:JvmName("goldChest") + lateinit var GOLD_CHEST: IronChestBlock + private set + @JvmStatic @get:JvmName("diamondChest") + lateinit var DIAMOND_CHEST: IronChestBlock + private set + + @EventListener + fun registerBlocks(event: BlockRegistryEvent) { + IRON_CHEST = IronChestBlock(Identifier.of("ironchests:iron_chest"), IronChestMaterial.IRON) + IRON_CHEST.setTranslationKey(Identifier.of("ironchests:iron_chest")) + GOLD_CHEST = IronChestBlock(Identifier.of("ironchests:gold_chest"), IronChestMaterial.GOLD) + GOLD_CHEST.setTranslationKey(Identifier.of("ironchests:gold_chest")) + DIAMOND_CHEST = IronChestBlock(Identifier.of("ironchests:diamond_chest"), IronChestMaterial.DIAMOND) + DIAMOND_CHEST.setTranslationKey(Identifier.of("ironchests:diamond_chest")) + } + + @EventListener + internal fun registerTileEntities(event: BlockEntityRegisterEvent) { + event.register( + IronChestBlockEntity::class.java, + "ironchest" + ) + } - private var material = material + @EventListener + internal fun registerRecipes(event: RecipeRegisterEvent) { + val type = RecipeRegisterEvent.Vanilla.fromType(event.recipeId) + + if (type == RecipeRegisterEvent.Vanilla.CRAFTING_SHAPED) { + CraftingRegistry.addShapedRecipe( + ItemStack(IRON_CHEST), + "iii", "ici", "iii", + 'i', ItemStack(Item.IRON_INGOT), + 'c', ItemStack(Block.CHEST) + ) + CraftingRegistry.addShapedRecipe( + ItemStack(GOLD_CHEST), + "iii", "ici", "iii", + 'i', ItemStack(Item.GOLD_INGOT), + 'c', ItemStack(IRON_CHEST) + ) + CraftingRegistry.addShapedRecipe( + ItemStack(DIAMOND_CHEST), + "gig", "ici", "gig", + 'i', ItemStack(Item.DIAMOND), + 'c', ItemStack(GOLD_CHEST), + 'g', ItemStack(Block.GLASS) + ) + CraftingRegistry.addShapedRecipe( + ItemStack(DIAMOND_CHEST), + "igi", "gcg", "igi", + 'i', ItemStack(Item.DIAMOND), + 'c', ItemStack(GOLD_CHEST), + 'g', ItemStack(Block.GLASS) + ) + } + } +} + +class IronChestBlockEntity @JvmOverloads constructor(material: IronChestMaterial = IronChestMaterial.IRON): ChestBlockEntity() { + var material = material set(x) = run { field = x updateInventorySize() @@ -37,6 +104,7 @@ class IronChestBlockEntity(material: IronChestMaterial): ChestBlockEntity() { override fun getName(): String = material.chestName init { + @Suppress("CAST_NEVER_SUCCEEDS") (this as ChestInventoryAccessor).inventory = arrayOfNulls(material.size) } @@ -51,7 +119,8 @@ class IronChestBlockEntity(material: IronChestMaterial): ChestBlockEntity() { } private fun updateInventorySize() { - (this as ChestInventoryAccessor).inventory.copyOf(material.size) + @Suppress("CAST_NEVER_SUCCEEDS") + (this as ChestInventoryAccessor).inventory = inventory.copyOf(material.size) } } @@ -75,16 +144,7 @@ class IronChestBlock(identifier: Identifier, private val chestMaterial: IronChes super.appendProperties(builder) } - override fun getPlacementState(context: ItemPlacementContext): BlockState { - val direction: Int = floor((context.player!!.yaw * 4.0f / 360.0f).toDouble() + 0.5).toInt() and 3 - return when (direction) { - 0 -> defaultState.with(FACING, Direction.NORTH) - 1 -> defaultState.with(FACING, Direction.EAST) - 2 -> defaultState.with(FACING, Direction.SOUTH) - 3 -> defaultState.with(FACING, Direction.WEST) - else -> defaultState.with(FACING, Direction.NORTH) - } - } + override fun getPlacementState(context: ItemPlacementContext): BlockState = defaultState.with(FACING, context.player!!.placementFacing()) override fun createBlockEntity(): BlockEntity { return IronChestBlockEntity(chestMaterial) @@ -125,7 +185,20 @@ class IronChestBlock(identifier: Identifier, private val chestMaterial: IronChes override fun onUse(world: World, x: Int, y: Int, z: Int, player: PlayerEntity): Boolean { val entity = world.getBlockEntity(x, y, z) ?: return true - if (entity !is IronChestBlockEntity || world.shouldSuffocate(x, y+1, z) || world.isRemote) { + + if (entity !is IronChestBlockEntity || world.isRemote) { + return true + } + + val handheldItem = player.hand?.item + if (handheldItem is ChestUpgrade) { + if (handheldItem.upgrade(world, x, y, z, player, entity)) { + player.hand!!.count-- + } + return true + } + + if (world.shouldSuffocate(x, y+1, z)) { return true } diff --git a/src/main/kotlin/net/zekromaster/minecraft/ironchests/entrypoints.kt b/src/main/kotlin/net/zekromaster/minecraft/ironchests/entrypoints.kt deleted file mode 100644 index f65fb22..0000000 --- a/src/main/kotlin/net/zekromaster/minecraft/ironchests/entrypoints.kt +++ /dev/null @@ -1,113 +0,0 @@ -package net.zekromaster.minecraft.ironchests - -import net.mine_diver.unsafeevents.listener.EventListener -import net.minecraft.block.Block -import net.minecraft.client.gui.screen.Screen -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.inventory.Inventory -import net.minecraft.item.Item -import net.minecraft.item.ItemStack -import net.modificationstation.stationapi.api.event.block.entity.BlockEntityRegisterEvent -import net.modificationstation.stationapi.api.event.recipe.RecipeRegisterEvent -import net.modificationstation.stationapi.api.event.registry.BlockRegistryEvent -import net.modificationstation.stationapi.api.event.registry.GuiHandlerRegistryEvent -import net.modificationstation.stationapi.api.recipe.CraftingRegistry -import net.modificationstation.stationapi.api.util.Identifier -import uk.co.benjiweber.expressions.tuple.BiTuple -import java.util.function.BiFunction -import java.util.function.Supplier - -object IronChests { - - @JvmStatic @get:JvmName("ironChest") - lateinit var IRON_CHEST: IronChestBlock - private set - @JvmStatic @get:JvmName("goldChest") - lateinit var GOLD_CHEST: IronChestBlock - private set - @JvmStatic @get:JvmName("diamondChest") - lateinit var DIAMOND_CHEST: IronChestBlock - private set - - @EventListener - internal fun registerBlocks(event: BlockRegistryEvent) { - IRON_CHEST = IronChestBlock(Identifier.of("ironchests:iron_chest"), IronChestMaterial.IRON) - IRON_CHEST.setTranslationKey(Identifier.of("ironchests:iron_chest")) - GOLD_CHEST = IronChestBlock(Identifier.of("ironchests:gold_chest"), IronChestMaterial.GOLD) - GOLD_CHEST.setTranslationKey(Identifier.of("ironchests:gold_chest")) - DIAMOND_CHEST = IronChestBlock(Identifier.of("ironchests:diamond_chest"), IronChestMaterial.DIAMOND) - DIAMOND_CHEST.setTranslationKey(Identifier.of("ironchests:diamond_chest")) - } - - @EventListener - internal fun registerTileEntities(event: BlockEntityRegisterEvent) { - event.register( - IronChestBlockEntity::class.java, - "ironchest" - ) - } - - @EventListener - internal fun registerRecipes(event: RecipeRegisterEvent) { - val type = RecipeRegisterEvent.Vanilla.fromType(event.recipeId) - - if (type == RecipeRegisterEvent.Vanilla.CRAFTING_SHAPED) { - CraftingRegistry.addShapedRecipe( - ItemStack(IRON_CHEST), - "iii", "ici", "iii", - 'i', ItemStack(Item.IRON_INGOT), - 'c', ItemStack(Block.CHEST) - ) - CraftingRegistry.addShapedRecipe( - ItemStack(GOLD_CHEST), - "iii", "ici", "iii", - 'i', ItemStack(Item.GOLD_INGOT), - 'c', ItemStack(IRON_CHEST) - ) - CraftingRegistry.addShapedRecipe( - ItemStack(DIAMOND_CHEST), - "gig", "ici", "gig", - 'i', ItemStack(Item.DIAMOND), - 'c', ItemStack(GOLD_CHEST), - 'g', ItemStack(Block.GLASS) - ) - CraftingRegistry.addShapedRecipe( - ItemStack(DIAMOND_CHEST), - "igi", "gcg", "igi", - 'i', ItemStack(Item.DIAMOND), - 'c', ItemStack(GOLD_CHEST), - 'g', ItemStack(Block.GLASS) - ) - } - } - -} - - -internal object RegisterGUIs { - - private class OpenInventory(private val material: IronChestMaterial): BiFunction { - override fun apply(player: PlayerEntity, inventory: Inventory): Screen = - IronChestScreen(player.inventory, inventory, material) - } - - private data class IronChestFactory(val material: IronChestMaterial): Supplier { - override fun get(): IronChestBlockEntity = IronChestBlockEntity(material) - } - - @EventListener - fun registerGUIs(event: GuiHandlerRegistryEvent) { - event.registry.registerValueNoMessage(Identifier.of("ironchests:gui_iron"), BiTuple.of( - OpenInventory(IronChestMaterial.IRON), - IronChestFactory(IronChestMaterial.IRON) - )) - event.registry.registerValueNoMessage(Identifier.of("ironchests:gui_gold"), BiTuple.of( - OpenInventory(IronChestMaterial.GOLD), - IronChestFactory(IronChestMaterial.GOLD) - )) - event.registry.registerValueNoMessage(Identifier.of("ironchests:gui_diamond"), BiTuple.of( - OpenInventory(IronChestMaterial.DIAMOND), - IronChestFactory(IronChestMaterial.DIAMOND) - )) - } -} \ No newline at end of file diff --git a/src/main/kotlin/net/zekromaster/minecraft/ironchests/gui.kt b/src/main/kotlin/net/zekromaster/minecraft/ironchests/gui.kt index 98edd17..0dfb1a6 100644 --- a/src/main/kotlin/net/zekromaster/minecraft/ironchests/gui.kt +++ b/src/main/kotlin/net/zekromaster/minecraft/ironchests/gui.kt @@ -2,13 +2,50 @@ package net.zekromaster.minecraft.ironchests import net.fabricmc.api.EnvType import net.fabricmc.api.Environment +import net.mine_diver.unsafeevents.listener.EventListener +import net.minecraft.client.gui.screen.Screen import net.minecraft.client.gui.screen.ingame.HandledScreen import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.Inventory import net.minecraft.screen.ScreenHandler import net.minecraft.screen.slot.Slot +import net.modificationstation.stationapi.api.event.registry.GuiHandlerRegistryEvent +import net.modificationstation.stationapi.api.util.Identifier import org.lwjgl.opengl.GL11 +import uk.co.benjiweber.expressions.tuple.BiTuple +import java.util.function.BiFunction +import java.util.function.Supplier +internal object RegisterGUIs { + + private class OpenInventory(private val material: IronChestMaterial): BiFunction { + override fun apply(player: PlayerEntity, inventory: Inventory): Screen = + IronChestScreen(player.inventory, inventory, material) + } + + private data class IronChestFactory(val material: IronChestMaterial): Supplier { + override fun get(): IronChestBlockEntity = IronChestBlockEntity(material) + } + + @EventListener + fun registerGUIs(event: GuiHandlerRegistryEvent) { + event.registry.registerValueNoMessage( + Identifier.of("ironchests:gui_iron"), BiTuple.of( + OpenInventory(IronChestMaterial.IRON), + IronChestFactory(IronChestMaterial.IRON) + )) + event.registry.registerValueNoMessage( + Identifier.of("ironchests:gui_gold"), BiTuple.of( + OpenInventory(IronChestMaterial.GOLD), + IronChestFactory(IronChestMaterial.GOLD) + )) + event.registry.registerValueNoMessage( + Identifier.of("ironchests:gui_diamond"), BiTuple.of( + OpenInventory(IronChestMaterial.DIAMOND), + IronChestFactory(IronChestMaterial.DIAMOND) + )) + } +} private fun IronChestMaterial.gui() = when (this) { @@ -22,10 +59,6 @@ private enum class GUIType(val material: IronChestMaterial, val width: Int, val IRON(IronChestMaterial.IRON, 184, 202, "ironchest.png"), GOLD(IronChestMaterial.GOLD, 184, 256, "goldchest.png"), DIAMOND(IronChestMaterial.DIAMOND, 238, 256, "diamondchest.png"); - - fun handler(playerInventory: Inventory, inventory: Inventory): ScreenHandler = - IronChestScreenHandler(this, playerInventory, inventory, width, height) - } private class IronChestScreenHandler( diff --git a/src/main/kotlin/net/zekromaster/minecraft/ironchests/upgrades.kt b/src/main/kotlin/net/zekromaster/minecraft/ironchests/upgrades.kt new file mode 100644 index 0000000..c84c178 --- /dev/null +++ b/src/main/kotlin/net/zekromaster/minecraft/ironchests/upgrades.kt @@ -0,0 +1,131 @@ +package net.zekromaster.minecraft.ironchests + +import net.mine_diver.unsafeevents.listener.EventListener +import net.minecraft.block.Block +import net.minecraft.block.entity.ChestBlockEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.world.World +import net.modificationstation.stationapi.api.event.recipe.RecipeRegisterEvent +import net.modificationstation.stationapi.api.event.registry.ItemRegistryEvent +import net.modificationstation.stationapi.api.recipe.CraftingRegistry +import net.modificationstation.stationapi.api.registry.ItemRegistry +import net.modificationstation.stationapi.api.tag.TagKey +import net.modificationstation.stationapi.api.template.item.TemplateItem +import net.modificationstation.stationapi.api.util.Identifier +import net.modificationstation.stationapi.api.util.math.Direction +import net.zekromaster.minecraft.ironchests.IronChestBlock.Companion.FACING +import net.zekromaster.minecraft.ironchests.IronChestMaterial.* +import net.zekromaster.minecraft.ironchests.IronChestsBlockEntrypoint.DIAMOND_CHEST +import net.zekromaster.minecraft.ironchests.IronChestsBlockEntrypoint.GOLD_CHEST +import net.zekromaster.minecraft.ironchests.IronChestsBlockEntrypoint.IRON_CHEST +import net.zekromaster.minecraft.ironchests.mixin.ChestInventoryAccessor + +object IronChestsUpgradesEntrypoint { + + @JvmStatic @get:JvmName("woodToIron") + lateinit var WOOD_TO_IRON: ChestUpgrade + private set + @JvmStatic @get:JvmName("ironToGold") + lateinit var IRON_TO_GOLD: ChestUpgrade + private set + @JvmStatic @get:JvmName("goldToDiamond") + lateinit var GOLD_TO_DIAMOND: ChestUpgrade + private set + + @EventListener + fun registerItems(event: ItemRegistryEvent) { + Identifier.of("ironchests:upgrades/wood_to_iron").apply { + WOOD_TO_IRON = WoodToIronUpgrade(this, IRON) + WOOD_TO_IRON.setTranslationKey(this) + } + Identifier.of("ironchests:upgrades/iron_to_gold").apply { + IRON_TO_GOLD = IronToIronUpgrade(this, IRON, GOLD) + IRON_TO_GOLD.setTranslationKey(this) + } + Identifier.of("ironchests:upgrades/gold_to_diamond").apply { + GOLD_TO_DIAMOND = IronToIronUpgrade(this, GOLD, DIAMOND) + GOLD_TO_DIAMOND.setTranslationKey(this) + } + } + + @EventListener + internal fun registerRecipes(event: RecipeRegisterEvent) { + val type = RecipeRegisterEvent.Vanilla.fromType(event.recipeId) + + if (type == RecipeRegisterEvent.Vanilla.CRAFTING_SHAPED) { + CraftingRegistry.addShapedRecipe( + ItemStack(WOOD_TO_IRON), + "iii", "ici", "iii", + 'i', ItemStack(Item.IRON_INGOT), + 'c', TagKey.of(ItemRegistry.KEY, Identifier.of("planks")) + ) + CraftingRegistry.addShapedRecipe( + ItemStack(IRON_TO_GOLD), + "iii", "ici", "iii", + 'i', ItemStack(Item.GOLD_INGOT), + 'c', ItemStack(Item.IRON_INGOT) + ) + CraftingRegistry.addShapedRecipe( + ItemStack(GOLD_TO_DIAMOND), + "gig", "ici", "gig", + 'i', ItemStack(Item.DIAMOND), + 'c', ItemStack(Item.GOLD_INGOT), + 'g', ItemStack(Block.GLASS) + ) + CraftingRegistry.addShapedRecipe( + ItemStack(GOLD_TO_DIAMOND), + "igi", "gcg", "igi", + 'i', ItemStack(Item.DIAMOND), + 'c', ItemStack(Item.GOLD_INGOT), + 'g', ItemStack(Block.GLASS) + ) + } + } +} + +fun IronChestMaterial.block(): Block = + when (this) { + IRON -> IRON_CHEST + GOLD -> GOLD_CHEST + DIAMOND -> DIAMOND_CHEST + } + +sealed class ChestUpgrade(identifier: Identifier, private val destination: IronChestMaterial): TemplateItem(identifier) { + fun upgrade(world: World, x: Int, y: Int, z: Int, player: PlayerEntity, blockEntity: ChestBlockEntity): Boolean { + if (canUpgrade(blockEntity)) { + val oldBlockState = world.getBlockState(x, y, z) + val oldContents = (blockEntity as ChestInventoryAccessor).inventory.copyOf() + val oldBlock = blockEntity.block + + (blockEntity as ChestInventoryAccessor).inventory = arrayOfNulls(blockEntity.size()) + world.setBlock(x, y, z, destination.block().id) + + if (oldBlock is IronChestBlock) { + world.setBlockState(x, y, z, world.getBlockState(x, y, z).with(FACING, oldBlockState.get(FACING) ?: Direction.NORTH)) + } else { + world.setBlockState(x, y, z, world.getBlockState(x, y, z).with(FACING, player.placementFacing())) + } + + val newEntity = world.getBlockEntity(x, y, z) as IronChestBlockEntity + @Suppress("CAST_NEVER_SUCCEEDS") + (newEntity as ChestInventoryAccessor).inventory = oldContents.copyOf(newEntity.size()) + world.setBlockDirty(x, y, z) + blockEntity.markDirty() + return true + } + return false + } + + protected abstract fun canUpgrade(blockEntity: ChestBlockEntity): Boolean + +} + +class WoodToIronUpgrade(identifier: Identifier, destination: IronChestMaterial): ChestUpgrade(identifier, destination) { + override fun canUpgrade(blockEntity: ChestBlockEntity) = blockEntity.block == Block.CHEST +} + +class IronToIronUpgrade(identifier: Identifier, val starting: IronChestMaterial, destination: IronChestMaterial): ChestUpgrade(identifier, destination) { + override fun canUpgrade(blockEntity: ChestBlockEntity): Boolean = blockEntity is IronChestBlockEntity && blockEntity.material == starting +} \ No newline at end of file diff --git a/src/main/kotlin/net/zekromaster/minecraft/ironchests/util.kt b/src/main/kotlin/net/zekromaster/minecraft/ironchests/util.kt index ebd77cb..641ef9f 100644 --- a/src/main/kotlin/net/zekromaster/minecraft/ironchests/util.kt +++ b/src/main/kotlin/net/zekromaster/minecraft/ironchests/util.kt @@ -1,5 +1,9 @@ package net.zekromaster.minecraft.ironchests +import net.minecraft.entity.player.PlayerEntity +import net.modificationstation.stationapi.api.util.math.Direction +import kotlin.math.floor + data class IronChestGrid(val rows: Int, val columns: Int) { val size = rows * columns } @@ -22,4 +26,15 @@ enum class IronChestMaterial(val id: String, val grid: IronChestGrid) { } } -} \ No newline at end of file +} + +fun PlayerEntity.placementFacing(): Direction { + val direction = floor((this.yaw * 4.0f / 360.0f).toDouble() + 0.5).toInt() and 3 + return when (direction) { + 0 -> Direction.NORTH + 1 -> Direction.EAST + 2 -> Direction.SOUTH + 3 -> Direction.WEST + else -> Direction.NORTH + } +} diff --git a/src/main/resources/assets/ironchests/stationapi/lang/en_US.lang b/src/main/resources/assets/ironchests/stationapi/lang/en_US.lang index c4fe27c..d5df130 100644 --- a/src/main/resources/assets/ironchests/stationapi/lang/en_US.lang +++ b/src/main/resources/assets/ironchests/stationapi/lang/en_US.lang @@ -1,3 +1,7 @@ tile.@.iron_chest.name=Iron Chest tile.@.gold_chest.name=Gold Chest -tile.@.diamond_chest.name=Diamond Chest \ No newline at end of file +tile.@.diamond_chest.name=Diamond Chest + +item.@.upgrades/wood_to_iron.name=Wood to Iron Upgrade +item.@.upgrades/iron_to_gold.name=Iron to Gold Upgrade +item.@.upgrades/gold_to_diamond.name=Gold to Diamond Upgrade \ No newline at end of file diff --git a/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/gold_to_diamond.json b/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/gold_to_diamond.json new file mode 100644 index 0000000..63bc5a9 --- /dev/null +++ b/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/gold_to_diamond.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "ironchests:item/upgrades/gold_to_diamond" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/iron_to_gold.json b/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/iron_to_gold.json new file mode 100644 index 0000000..8923928 --- /dev/null +++ b/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/iron_to_gold.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "ironchests:item/upgrades/iron_to_gold" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/wood_to_iron.json b/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/wood_to_iron.json new file mode 100644 index 0000000..410911c --- /dev/null +++ b/src/main/resources/assets/ironchests/stationapi/models/item/upgrades/wood_to_iron.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "ironchests:item/upgrades/wood_to_iron" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/gold_to_diamond.png b/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/gold_to_diamond.png new file mode 100644 index 0000000..219a27f Binary files /dev/null and b/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/gold_to_diamond.png differ diff --git a/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/iron_to_gold.png b/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/iron_to_gold.png new file mode 100644 index 0000000..b150a65 Binary files /dev/null and b/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/iron_to_gold.png differ diff --git a/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/wood_to_iron.png b/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/wood_to_iron.png new file mode 100644 index 0000000..2ea329a Binary files /dev/null and b/src/main/resources/assets/ironchests/stationapi/textures/item/upgrades/wood_to_iron.png differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 9ff0228..417bb9c 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -22,7 +22,11 @@ }, { "adapter": "kotlin", - "value": "net.zekromaster.minecraft.ironchests.IronChests" + "value": "net.zekromaster.minecraft.ironchests.IronChestsBlockEntrypoint" + }, + { + "adapter": "kotlin", + "value": "net.zekromaster.minecraft.ironchests.IronChestsUpgradesEntrypoint" } ], "stationapi:event_bus_client": [], diff --git a/src/main/resources/ironchests.mixins.json b/src/main/resources/ironchests.mixins.json index b50abba..22b2e77 100644 --- a/src/main/resources/ironchests.mixins.json +++ b/src/main/resources/ironchests.mixins.json @@ -4,7 +4,8 @@ "package": "net.zekromaster.minecraft.ironchests.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ - "ChestInventoryAccessor" + "ChestInventoryAccessor", + "ChestMixin" ], "server": [], "client": [],