diff --git a/src/main/kotlin/com/coderjoe/atlas/Atlas.kt b/src/main/kotlin/com/coderjoe/atlas/Atlas.kt index 8c71ec4..44f1d83 100644 --- a/src/main/kotlin/com/coderjoe/atlas/Atlas.kt +++ b/src/main/kotlin/com/coderjoe/atlas/Atlas.kt @@ -179,7 +179,8 @@ class Atlas : JavaPlugin() { com.coderjoe.atlas.power.block.SmallDrill.descriptor, com.coderjoe.atlas.power.block.SmallBattery.descriptor, com.coderjoe.atlas.power.block.PowerCable.descriptor, - com.coderjoe.atlas.power.block.LavaGenerator.descriptor + com.coderjoe.atlas.power.block.LavaGenerator.descriptor, + com.coderjoe.atlas.power.block.AutoSmelter.descriptor ).associateBy { it.baseBlockId } } diff --git a/src/main/kotlin/com/coderjoe/atlas/guide/GuideBook.kt b/src/main/kotlin/com/coderjoe/atlas/guide/GuideBook.kt index abaa519..6f26b59 100644 --- a/src/main/kotlin/com/coderjoe/atlas/guide/GuideBook.kt +++ b/src/main/kotlin/com/coderjoe/atlas/guide/GuideBook.kt @@ -23,6 +23,7 @@ object GuideBook { private const val FLUID_PIPE = "\uE106" private const val FLUID_CONTAINER = "\uE107" private const val CONVEYOR_BELT = "\uE108" + private const val AUTO_SMELTER = "\uE109" fun create(): ItemStack { val book = ItemStack(Material.WRITTEN_BOOK) @@ -208,14 +209,26 @@ object GuideBook { .append(Component.text("place after a drill\nto auto-collect mined\nblocks.", darkGray)) .build(), - // Page 13: Tips + // Page 13: Auto Smelter + Component.text() + .append(Component.text("Auto Smelter\n", Style.style(TextDecoration.BOLD).color(darkGreen))) + .append(Component.text("\n")) + .append(Component.text(AUTO_SMELTER)) + .append(Component.text(" ")) + .append(Component.text("Auto Smelter\n", Style.style(TextDecoration.BOLD).color(darkGreen))) + .append(Component.text("\nSmelts items passing\nthrough it. Conveyor\nbelt on the bottom,\nfire chamber on top.\n\n", darkGray)) + .append(Component.text("Power cost: ", bold)) + .append(Component.text("2 per item", darkGray)) + .build(), + + // Page 14: Tips Component.text() .append(Component.text("Tips & Tricks\n", Style.style(TextDecoration.BOLD).color(darkRed))) .append(Component.text("\n")) .append(Component.text("Lava power pipeline:\n", bold)) .append(Component.text("Pump > Pipe >\nContainer > Lava Gen\n\n", darkGray)) .append(Component.text("Auto-mining:\n", bold)) - .append(Component.text("Drill + Conveyor Belt\ncollects drops for you\n\n", darkGray)) + .append(Component.text("Drill + Conveyor Belt\n+ Auto Smelter for\nauto ore processing\n\n", darkGray)) .append(Component.text("Placement:\n", bold)) .append(Component.text("blocks face where you\nlook. The pull direction\nis always from behind.", darkGray)) .build() diff --git a/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt b/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt index 7bd7e55..bb62079 100644 --- a/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt +++ b/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt @@ -2,6 +2,7 @@ package com.coderjoe.atlas.power import com.coderjoe.atlas.core.AtlasBlockDialog import com.coderjoe.atlas.core.BlockRegistry +import com.coderjoe.atlas.power.block.AutoSmelter import com.coderjoe.atlas.power.block.LavaGenerator import com.coderjoe.atlas.power.block.PowerCable import com.coderjoe.atlas.power.block.SmallBattery @@ -125,6 +126,7 @@ object PowerBlockDialog { is SmallDrill -> "Small Drill" is PowerCable -> "Power Cable (${powerBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" is LavaGenerator -> "Lava Generator" + is AutoSmelter -> "Auto Smelter (${powerBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" else -> "Power Block" } @@ -169,6 +171,8 @@ object PowerBlockDialog { .color(NamedTextColor.GRAY) is LavaGenerator -> Component.text("Generator - produces ${LavaGenerator.POWER_PER_LAVA} power per lava unit") .color(NamedTextColor.GRAY) + is AutoSmelter -> Component.text("Machine - smelts items passing through, consumes ${AutoSmelter.POWER_PER_SMELT} power/item") + .color(NamedTextColor.GRAY) else -> Component.text("Power block") .color(NamedTextColor.GRAY) } diff --git a/src/main/kotlin/com/coderjoe/atlas/power/block/AutoSmelter.kt b/src/main/kotlin/com/coderjoe/atlas/power/block/AutoSmelter.kt new file mode 100644 index 0000000..c6bc3da --- /dev/null +++ b/src/main/kotlin/com/coderjoe/atlas/power/block/AutoSmelter.kt @@ -0,0 +1,126 @@ +package com.coderjoe.atlas.power.block + +import com.coderjoe.atlas.core.BlockDescriptor +import com.coderjoe.atlas.core.PlacementType +import com.coderjoe.atlas.power.PowerBlock +import com.coderjoe.atlas.power.PowerBlockRegistry +import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.block.BlockFace +import org.bukkit.entity.Item +import org.bukkit.inventory.FurnaceRecipe +import org.bukkit.inventory.ItemStack + +class AutoSmelter(location: Location, facing: BlockFace = BlockFace.NORTH) : PowerBlock(location, maxStorage = 2) { + + override val canReceivePower: Boolean = true + override val updateIntervalTicks: Long = 20L + override val baseBlockId: String = BLOCK_ID + + var direction: BlockFace = if (facing == BlockFace.SELF) BlockFace.NORTH else facing + + override val facing: BlockFace get() = direction + + companion object { + const val BLOCK_ID = "auto_smelter" + const val POWER_PER_SMELT = 2 + private const val MOVE_DISTANCE = 1.0 + + val DIRECTIONAL_IDS = mapOf( + BlockFace.NORTH to "auto_smelter_north", + BlockFace.SOUTH to "auto_smelter_south", + BlockFace.EAST to "auto_smelter_east", + BlockFace.WEST to "auto_smelter_west" + ) + + val POWERED_IDS = mapOf( + BlockFace.NORTH to "auto_smelter_north_on", + BlockFace.SOUTH to "auto_smelter_south_on", + BlockFace.EAST to "auto_smelter_east_on", + BlockFace.WEST to "auto_smelter_west_on" + ) + + val ID_TO_FACING: Map = buildMap { + DIRECTIONAL_IDS.forEach { (face, id) -> put(id, face) } + POWERED_IDS.forEach { (face, id) -> put(id, face) } + } + + val ALL_VARIANT_IDS: List = DIRECTIONAL_IDS.values.toList() + POWERED_IDS.values.toList() + + fun facingFromBlockId(blockId: String): BlockFace? = ID_TO_FACING[blockId] + + val descriptor = BlockDescriptor( + baseBlockId = BLOCK_ID, + displayName = "Auto Smelter", + description = "Smelts items passing through, consumes 2 power per item", + placementType = PlacementType.DIRECTIONAL, + directionalVariants = DIRECTIONAL_IDS, + allRegistrableIds = ALL_VARIANT_IDS, + constructor = { loc, face -> AutoSmelter(loc, face) } + ) + + fun getSmeltingResult(input: ItemStack): ItemStack? { + return try { + Bukkit.recipeIterator().asSequence() + .filterIsInstance() + .find { it.inputChoice.test(input) } + ?.result + } catch (_: Exception) { + null + } + } + } + + override fun getVisualStateBlockId(): String { + return if (hasPower()) { + POWERED_IDS[direction]!! + } else { + DIRECTIONAL_IDS[direction]!! + } + } + + override fun powerUpdate() { + // Pull power from adjacent blocks + if (canAcceptPower()) { + val registry = PowerBlockRegistry.instance ?: return + val neighbors = registry.getAdjacentPowerBlocks(location) + for (neighbor in neighbors) { + if (!canAcceptPower()) break + if (neighbor.hasPower()) { + val pulled = neighbor.removePower(1) + if (pulled > 0) { + addPower(pulled) + } + } + } + } + + val world = location.world ?: return + + // Scan for items on the belt surface (same as conveyor belt) + val scanCenter = location.clone().add(0.5, 0.75, 0.5) + val nearbyItems = world.getNearbyEntities(scanCenter, 0.5, 0.75, 0.5) + .filterIsInstance() + + if (nearbyItems.isEmpty()) return + + val dx = direction.direction.x * MOVE_DISTANCE + val dz = direction.direction.z * MOVE_DISTANCE + + for (item in nearbyItems) { + // Try to smelt the item if we have power + if (currentPower >= POWER_PER_SMELT) { + val result = getSmeltingResult(item.itemStack) + if (result != null) { + removePower(POWER_PER_SMELT) + val smeltedStack = result.clone() + smeltedStack.amount = item.itemStack.amount + item.itemStack = smeltedStack + } + } + + // Always move items forward (conveyor belt behavior) + item.teleportAsync(item.location.add(dx, 0.0, dz)) + } + } +} diff --git a/src/main/resources/nexo/items/atlas_blocks.yml b/src/main/resources/nexo/items/atlas_blocks.yml index a1f0759..92e7257 100644 --- a/src/main/resources/nexo/items/atlas_blocks.yml +++ b/src/main/resources/nexo/items/atlas_blocks.yml @@ -2860,3 +2860,273 @@ conveyor_belt_west: loots: - nexo_item: conveyor_belt probability: 1.0 + +auto_smelter: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ns + textures: + north: atlas:block/auto_smelter_front + south: atlas:block/auto_smelter_back + east: atlas:block/auto_smelter_side + west: atlas:block/auto_smelter_side + up: atlas:block/auto_smelter_top_north + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 49 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_north: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ns + textures: + north: atlas:block/auto_smelter_front + south: atlas:block/auto_smelter_back + east: atlas:block/auto_smelter_side + west: atlas:block/auto_smelter_side + up: atlas:block/auto_smelter_top_north + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 50 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_south: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ns + textures: + north: atlas:block/auto_smelter_back + south: atlas:block/auto_smelter_front + east: atlas:block/auto_smelter_side + west: atlas:block/auto_smelter_side + up: atlas:block/auto_smelter_top_south + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 51 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_east: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ew + textures: + north: atlas:block/auto_smelter_side + south: atlas:block/auto_smelter_side + east: atlas:block/auto_smelter_front + west: atlas:block/auto_smelter_back + up: atlas:block/auto_smelter_top_east + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 52 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_west: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ew + textures: + north: atlas:block/auto_smelter_side + south: atlas:block/auto_smelter_side + east: atlas:block/auto_smelter_back + west: atlas:block/auto_smelter_front + up: atlas:block/auto_smelter_top_west + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 53 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_north_on: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ns_on + textures: + north: atlas:block/auto_smelter_front + south: atlas:block/auto_smelter_back + east: atlas:block/auto_smelter_side + west: atlas:block/auto_smelter_side + up: atlas:block/auto_smelter_top_north + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 54 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_south_on: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ns_on + textures: + north: atlas:block/auto_smelter_back + south: atlas:block/auto_smelter_front + east: atlas:block/auto_smelter_side + west: atlas:block/auto_smelter_side + up: atlas:block/auto_smelter_top_south + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 55 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_east_on: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ew_on + textures: + north: atlas:block/auto_smelter_side + south: atlas:block/auto_smelter_side + east: atlas:block/auto_smelter_front + west: atlas:block/auto_smelter_back + up: atlas:block/auto_smelter_top_east + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 56 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 + +auto_smelter_west_on: + itemname: "Auto Smelter" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/auto_smelter_ew_on + textures: + north: atlas:block/auto_smelter_side + south: atlas:block/auto_smelter_side + east: atlas:block/auto_smelter_back + west: atlas:block/auto_smelter_front + up: atlas:block/auto_smelter_top_west + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 57 + hardness: 3 + block_sounds: + break_sound: block.metal.break + place_sound: block.metal.place + hit_sound: block.metal.hit + step_sound: block.metal.step + fall_sound: block.metal.fall + drop: + silktouch: false + loots: + - nexo_item: auto_smelter + probability: 1.0 diff --git a/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ew.json b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ew.json new file mode 100644 index 0000000..e337731 --- /dev/null +++ b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ew.json @@ -0,0 +1,53 @@ +{ + "textures": { + "particle": "#up", + "fire": "atlas:block/auto_smelter_fire_off", + "housing": "atlas:block/auto_smelter_housing" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 6, 16], + "faces": { + "north": { "texture": "#north", "uv": [0, 10, 16, 16] }, + "south": { "texture": "#south", "uv": [0, 10, 16, 16] }, + "east": { "texture": "#east", "uv": [0, 10, 16, 16] }, + "west": { "texture": "#west", "uv": [0, 10, 16, 16] }, + "up": { "texture": "#up" }, + "down": { "texture": "#down", "cullface": "down" } + } + }, + { + "from": [0, 6, 0], + "to": [16, 16, 4], + "faces": { + "north": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "south": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "east": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "west": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "up": { "texture": "#housing", "uv": [0, 0, 16, 4] } + } + }, + { + "from": [0, 6, 12], + "to": [16, 16, 16], + "faces": { + "north": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "south": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "east": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "west": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "up": { "texture": "#housing", "uv": [0, 12, 16, 16] } + } + }, + { + "from": [0, 14, 4], + "to": [16, 16, 12], + "faces": { + "east": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "west": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "up": { "texture": "#up", "uv": [0, 4, 16, 12] }, + "down": { "texture": "#fire", "uv": [0, 4, 16, 12] } + } + } + ] +} diff --git a/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ew_on.json b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ew_on.json new file mode 100644 index 0000000..75b6a5a --- /dev/null +++ b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ew_on.json @@ -0,0 +1,53 @@ +{ + "textures": { + "particle": "#up", + "fire": "atlas:block/auto_smelter_fire", + "housing": "atlas:block/auto_smelter_housing" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 6, 16], + "faces": { + "north": { "texture": "#north", "uv": [0, 10, 16, 16] }, + "south": { "texture": "#south", "uv": [0, 10, 16, 16] }, + "east": { "texture": "#east", "uv": [0, 10, 16, 16] }, + "west": { "texture": "#west", "uv": [0, 10, 16, 16] }, + "up": { "texture": "#up" }, + "down": { "texture": "#down", "cullface": "down" } + } + }, + { + "from": [0, 6, 0], + "to": [16, 16, 4], + "faces": { + "north": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "south": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "east": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "west": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "up": { "texture": "#housing", "uv": [0, 0, 16, 4] } + } + }, + { + "from": [0, 6, 12], + "to": [16, 16, 16], + "faces": { + "north": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "south": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "east": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "west": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "up": { "texture": "#housing", "uv": [0, 12, 16, 16] } + } + }, + { + "from": [0, 14, 4], + "to": [16, 16, 12], + "faces": { + "east": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "west": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "up": { "texture": "#up", "uv": [0, 4, 16, 12] }, + "down": { "texture": "#fire", "uv": [0, 4, 16, 12] } + } + } + ] +} diff --git a/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ns.json b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ns.json new file mode 100644 index 0000000..ae0249f --- /dev/null +++ b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ns.json @@ -0,0 +1,53 @@ +{ + "textures": { + "particle": "#up", + "fire": "atlas:block/auto_smelter_fire_off", + "housing": "atlas:block/auto_smelter_housing" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 6, 16], + "faces": { + "north": { "texture": "#north", "uv": [0, 10, 16, 16] }, + "south": { "texture": "#south", "uv": [0, 10, 16, 16] }, + "east": { "texture": "#east", "uv": [0, 10, 16, 16] }, + "west": { "texture": "#west", "uv": [0, 10, 16, 16] }, + "up": { "texture": "#up" }, + "down": { "texture": "#down", "cullface": "down" } + } + }, + { + "from": [0, 6, 0], + "to": [4, 16, 16], + "faces": { + "north": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "south": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "east": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "west": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "up": { "texture": "#housing", "uv": [0, 0, 4, 16] } + } + }, + { + "from": [12, 6, 0], + "to": [16, 16, 16], + "faces": { + "north": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "south": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "east": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "west": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "up": { "texture": "#housing", "uv": [12, 0, 16, 16] } + } + }, + { + "from": [4, 14, 0], + "to": [12, 16, 16], + "faces": { + "north": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "south": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "up": { "texture": "#up", "uv": [4, 0, 12, 16] }, + "down": { "texture": "#fire", "uv": [4, 0, 12, 16] } + } + } + ] +} diff --git a/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ns_on.json b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ns_on.json new file mode 100644 index 0000000..fce2d8a --- /dev/null +++ b/src/main/resources/nexo/pack/assets/atlas/models/block/auto_smelter_ns_on.json @@ -0,0 +1,53 @@ +{ + "textures": { + "particle": "#up", + "fire": "atlas:block/auto_smelter_fire", + "housing": "atlas:block/auto_smelter_housing" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 6, 16], + "faces": { + "north": { "texture": "#north", "uv": [0, 10, 16, 16] }, + "south": { "texture": "#south", "uv": [0, 10, 16, 16] }, + "east": { "texture": "#east", "uv": [0, 10, 16, 16] }, + "west": { "texture": "#west", "uv": [0, 10, 16, 16] }, + "up": { "texture": "#up" }, + "down": { "texture": "#down", "cullface": "down" } + } + }, + { + "from": [0, 6, 0], + "to": [4, 16, 16], + "faces": { + "north": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "south": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "east": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "west": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "up": { "texture": "#housing", "uv": [0, 0, 4, 16] } + } + }, + { + "from": [12, 6, 0], + "to": [16, 16, 16], + "faces": { + "north": { "texture": "#housing", "uv": [12, 0, 16, 10] }, + "south": { "texture": "#housing", "uv": [0, 0, 4, 10] }, + "east": { "texture": "#housing", "uv": [0, 0, 16, 10] }, + "west": { "texture": "#fire", "uv": [0, 0, 16, 10] }, + "up": { "texture": "#housing", "uv": [12, 0, 16, 16] } + } + }, + { + "from": [4, 14, 0], + "to": [12, 16, 16], + "faces": { + "north": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "south": { "texture": "#housing", "uv": [4, 0, 12, 2] }, + "up": { "texture": "#up", "uv": [4, 0, 12, 16] }, + "down": { "texture": "#fire", "uv": [4, 0, 12, 16] } + } + } + ] +} diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_back.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_back.png new file mode 100644 index 0000000..48b6b84 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_back.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_fire.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_fire.png new file mode 100644 index 0000000..8b7b27d Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_fire.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_fire_off.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_fire_off.png new file mode 100644 index 0000000..b788c34 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_fire_off.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_front.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_front.png new file mode 100644 index 0000000..379176a Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_front.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_housing.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_housing.png new file mode 100644 index 0000000..79edad8 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_housing.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_side.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_side.png new file mode 100644 index 0000000..24165d2 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_side.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_east.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_east.png new file mode 100644 index 0000000..d974460 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_east.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_north.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_north.png new file mode 100644 index 0000000..73c8321 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_north.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_south.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_south.png new file mode 100644 index 0000000..88ae177 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_south.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_west.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_west.png new file mode 100644 index 0000000..da66567 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/auto_smelter_top_west.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_auto_smelter.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_auto_smelter.png new file mode 100644 index 0000000..58ece5b Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_auto_smelter.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_conveyor_belt.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_conveyor_belt.png new file mode 100644 index 0000000..ab6f35a Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_conveyor_belt.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_container.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_container.png new file mode 100644 index 0000000..448aaed Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_container.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_pipe.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_pipe.png new file mode 100644 index 0000000..60a8557 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_pipe.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_pump.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_pump.png new file mode 100644 index 0000000..b8e1546 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_fluid_pump.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_lava_generator.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_lava_generator.png new file mode 100644 index 0000000..eb0ea27 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_lava_generator.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_power_cable.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_power_cable.png new file mode 100644 index 0000000..02e746e Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_power_cable.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_battery.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_battery.png new file mode 100644 index 0000000..0488b18 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_battery.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_drill.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_drill.png new file mode 100644 index 0000000..464f599 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_drill.png differ diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_solar_panel.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_solar_panel.png new file mode 100644 index 0000000..7ff2e81 Binary files /dev/null and b/src/main/resources/nexo/pack/assets/atlas/textures/block/guide_small_solar_panel.png differ diff --git a/src/main/resources/nexo/pack/assets/minecraft/font/default.json b/src/main/resources/nexo/pack/assets/minecraft/font/default.json index 199774f..5e5d6a8 100644 --- a/src/main/resources/nexo/pack/assets/minecraft/font/default.json +++ b/src/main/resources/nexo/pack/assets/minecraft/font/default.json @@ -2,66 +2,73 @@ "providers": [ { "type": "bitmap", - "file": "atlas:block/small_solar_panel.png", + "file": "atlas:block/guide_small_solar_panel.png", "ascent": 7, "height": 16, "chars": ["\uE100"] }, { "type": "bitmap", - "file": "atlas:block/lava_generator_side.png", + "file": "atlas:block/guide_lava_generator.png", "ascent": 7, "height": 16, "chars": ["\uE101"] }, { "type": "bitmap", - "file": "atlas:block/power_cable_front.png", + "file": "atlas:block/guide_power_cable.png", "ascent": 7, "height": 16, "chars": ["\uE102"] }, { "type": "bitmap", - "file": "atlas:block/small_battery.png", + "file": "atlas:block/guide_small_battery.png", "ascent": 7, "height": 16, "chars": ["\uE103"] }, { "type": "bitmap", - "file": "atlas:block/small_drill_front.png", + "file": "atlas:block/guide_small_drill.png", "ascent": 7, "height": 16, "chars": ["\uE104"] }, { "type": "bitmap", - "file": "atlas:block/fluid_pump_top.png", + "file": "atlas:block/guide_fluid_pump.png", "ascent": 7, "height": 16, "chars": ["\uE105"] }, { "type": "bitmap", - "file": "atlas:block/fluid_pipe_front.png", + "file": "atlas:block/guide_fluid_pipe.png", "ascent": 7, "height": 16, "chars": ["\uE106"] }, { "type": "bitmap", - "file": "atlas:block/fluid_container_front.png", + "file": "atlas:block/guide_fluid_container.png", "ascent": 7, "height": 16, "chars": ["\uE107"] }, { "type": "bitmap", - "file": "atlas:block/conveyor_belt_top_north.png", + "file": "atlas:block/guide_conveyor_belt.png", "ascent": 7, "height": 16, "chars": ["\uE108"] + }, + { + "type": "bitmap", + "file": "atlas:block/guide_auto_smelter.png", + "ascent": 7, + "height": 16, + "chars": ["\uE109"] } ] } diff --git a/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml b/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml index 587ff75..2123a03 100644 --- a/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml +++ b/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml @@ -119,3 +119,18 @@ conveyor_belt_recipe: B: amount: 3 minecraft_type: REDSTONE + +auto_smelter_recipe: + result: + nexo_item: auto_smelter + amount: 1 + ingredients: + A: + amount: 3 + minecraft_type: IRON_INGOT + B: + amount: 3 + minecraft_type: REDSTONE + C: + amount: 1 + minecraft_type: FURNACE diff --git a/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt b/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt index 058ae3e..e1d9949 100644 --- a/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt +++ b/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt @@ -28,9 +28,9 @@ class AtlasPluginTest { } @Test - fun `power system initializes with 19 block types`() { + fun `power system initializes with 27 block types`() { TestHelper.initPowerFactory() - assertEquals(19, PowerBlockFactory.getRegisteredBlockIds().size) + assertEquals(27, PowerBlockFactory.getRegisteredBlockIds().size) } @Test diff --git a/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt b/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt index 68f2e96..ca8a49b 100644 --- a/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt +++ b/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt @@ -15,6 +15,7 @@ import com.coderjoe.atlas.transport.TransportBlock import com.coderjoe.atlas.transport.TransportBlockFactory import com.coderjoe.atlas.transport.TransportBlockRegistry import com.coderjoe.atlas.transport.block.ConveyorBelt +import com.coderjoe.atlas.power.block.AutoSmelter import com.coderjoe.atlas.power.block.LavaGenerator import com.coderjoe.atlas.power.block.PowerCable import com.coderjoe.atlas.power.block.SmallBattery @@ -170,7 +171,7 @@ object TestHelper { PowerBlockFactory.registerFromDescriptors(listOf( SmallSolarPanel.descriptor, SmallDrill.descriptor, SmallBattery.descriptor, PowerCable.descriptor, - LavaGenerator.descriptor + LavaGenerator.descriptor, AutoSmelter.descriptor )) } diff --git a/src/test/kotlin/com/coderjoe/atlas/guide/GuideBookTest.kt b/src/test/kotlin/com/coderjoe/atlas/guide/GuideBookTest.kt index 574358a..177a98f 100644 --- a/src/test/kotlin/com/coderjoe/atlas/guide/GuideBookTest.kt +++ b/src/test/kotlin/com/coderjoe/atlas/guide/GuideBookTest.kt @@ -23,9 +23,9 @@ class GuideBookTest { } @Test - fun `buildPages produces 13 pages`() { + fun `buildPages produces 14 pages`() { val pages = GuideBook.buildPages() - assertEquals(13, pages.size) + assertEquals(14, pages.size) } @Test diff --git a/src/test/kotlin/com/coderjoe/atlas/power/AutoSmelterTest.kt b/src/test/kotlin/com/coderjoe/atlas/power/AutoSmelterTest.kt new file mode 100644 index 0000000..d81ed29 --- /dev/null +++ b/src/test/kotlin/com/coderjoe/atlas/power/AutoSmelterTest.kt @@ -0,0 +1,243 @@ +package com.coderjoe.atlas.power + +import com.coderjoe.atlas.TestHelper +import com.coderjoe.atlas.TestHelper.callPowerUpdate +import com.coderjoe.atlas.power.block.AutoSmelter +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.bukkit.Location +import org.bukkit.block.BlockFace +import org.bukkit.entity.Item +import org.bukkit.inventory.ItemStack +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.* +import java.util.concurrent.CompletableFuture + +class AutoSmelterTest { + + @BeforeEach + fun setup() { + TestHelper.setup() + } + + @AfterEach + fun teardown() { + TestHelper.teardown() + } + + @Test + fun `auto smelter has correct facing`() { + val smelter = AutoSmelter(TestHelper.createLocation(), BlockFace.NORTH) + assertEquals(BlockFace.NORTH, smelter.facing) + } + + @Test + fun `auto smelter visual state unpowered matches facing`() { + for ((face, id) in AutoSmelter.DIRECTIONAL_IDS) { + val smelter = AutoSmelter(TestHelper.createLocation(), face) + smelter.currentPower = 0 + assertEquals(id, smelter.getVisualStateBlockId()) + } + } + + @Test + fun `auto smelter visual state powered matches facing`() { + for ((face, id) in AutoSmelter.POWERED_IDS) { + val smelter = AutoSmelter(TestHelper.createLocation(), face) + smelter.currentPower = 2 + assertEquals(id, smelter.getVisualStateBlockId()) + } + } + + @Test + fun `auto smelter base block ID is auto_smelter`() { + val smelter = AutoSmelter(TestHelper.createLocation(), BlockFace.SOUTH) + assertEquals("auto_smelter", smelter.baseBlockId) + } + + @Test + fun `auto smelter descriptor has correct properties`() { + val desc = AutoSmelter.descriptor + assertEquals("auto_smelter", desc.baseBlockId) + assertEquals("Auto Smelter", desc.displayName) + assertEquals(8, desc.allRegistrableIds.size) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_north")) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_south")) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_east")) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_west")) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_north_on")) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_south_on")) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_east_on")) + assertTrue(desc.allRegistrableIds.contains("auto_smelter_west_on")) + } + + @Test + fun `auto smelter descriptor has directional placement`() { + val desc = AutoSmelter.descriptor + assertEquals(com.coderjoe.atlas.core.PlacementType.DIRECTIONAL, desc.placementType) + assertEquals(4, desc.directionalVariants.size) + } + + @Test + fun `facingFromBlockId returns correct facing`() { + assertEquals(BlockFace.NORTH, AutoSmelter.facingFromBlockId("auto_smelter_north")) + assertEquals(BlockFace.SOUTH, AutoSmelter.facingFromBlockId("auto_smelter_south")) + assertEquals(BlockFace.EAST, AutoSmelter.facingFromBlockId("auto_smelter_east")) + assertEquals(BlockFace.WEST, AutoSmelter.facingFromBlockId("auto_smelter_west")) + } + + @Test + fun `facingFromBlockId returns correct facing for powered IDs`() { + assertEquals(BlockFace.NORTH, AutoSmelter.facingFromBlockId("auto_smelter_north_on")) + assertEquals(BlockFace.SOUTH, AutoSmelter.facingFromBlockId("auto_smelter_south_on")) + assertEquals(BlockFace.EAST, AutoSmelter.facingFromBlockId("auto_smelter_east_on")) + assertEquals(BlockFace.WEST, AutoSmelter.facingFromBlockId("auto_smelter_west_on")) + } + + @Test + fun `facingFromBlockId returns null for unknown ID`() { + assertNull(AutoSmelter.facingFromBlockId("auto_smelter_up")) + assertNull(AutoSmelter.facingFromBlockId("unknown")) + } + + @Test + fun `all directional IDs are registered`() { + TestHelper.initPowerFactory() + for (id in AutoSmelter.DIRECTIONAL_IDS.values) { + assertTrue(PowerBlockFactory.isRegistered(id), "Missing auto smelter ID: $id") + } + } + + @Test + fun `factory creates AutoSmelter from directional ID`() { + TestHelper.initPowerFactory() + val block = PowerBlockFactory.createPowerBlock("auto_smelter_north", TestHelper.createLocation(), BlockFace.NORTH) + assertTrue(block is AutoSmelter) + assertEquals(BlockFace.NORTH, block!!.facing) + } + + @Test + fun `max storage is 2`() { + val smelter = AutoSmelter(TestHelper.createLocation(), BlockFace.NORTH) + assertEquals(2, smelter.maxStorage) + } + + @Test + fun `power update does not throw with no nearby entities`() { + PowerBlockRegistry(TestHelper.mockPlugin) + val smelter = AutoSmelter(TestHelper.createLocation(), BlockFace.NORTH) + + every { TestHelper.mockWorld.getNearbyEntities(any(), any(), any(), any()) } returns emptyList() + + assertDoesNotThrow { + smelter.callPowerUpdate() + } + } + + @Test + fun `power update moves item forward without smelting when no power`() { + PowerBlockRegistry(TestHelper.mockPlugin) + val smelter = AutoSmelter(TestHelper.createLocation(0.0, 64.0, 0.0), BlockFace.NORTH) + smelter.currentPower = 0 + + val itemLoc = Location(TestHelper.mockWorld, 0.5, 64.375, 0.5) + val mockItem = mockk(relaxed = true) + every { mockItem.location } returns itemLoc + every { mockItem.teleportAsync(any()) } returns CompletableFuture.completedFuture(true) + + every { TestHelper.mockWorld.getNearbyEntities(any(), any(), any(), any()) } returns listOf(mockItem) + + smelter.callPowerUpdate() + + verify { mockItem.teleportAsync(match { loc -> + loc.z < 0.5 && loc.x == 0.5 + }) } + } + + @Test + fun `power update moves item east`() { + PowerBlockRegistry(TestHelper.mockPlugin) + val smelter = AutoSmelter(TestHelper.createLocation(0.0, 64.0, 0.0), BlockFace.EAST) + smelter.currentPower = 0 + + val itemLoc = Location(TestHelper.mockWorld, 0.5, 64.375, 0.5) + val mockItem = mockk(relaxed = true) + every { mockItem.location } returns itemLoc + every { mockItem.teleportAsync(any()) } returns CompletableFuture.completedFuture(true) + + every { TestHelper.mockWorld.getNearbyEntities(any(), any(), any(), any()) } returns listOf(mockItem) + + smelter.callPowerUpdate() + + verify { mockItem.teleportAsync(match { loc -> + loc.x > 0.5 && loc.z == 0.5 + }) } + } + + @Test + fun `items still move forward when powered but no smelting recipe available`() { + PowerBlockRegistry(TestHelper.mockPlugin) + val smelter = AutoSmelter(TestHelper.createLocation(0.0, 64.0, 0.0), BlockFace.NORTH) + smelter.currentPower = 2 + + val itemLoc = Location(TestHelper.mockWorld, 0.5, 64.375, 0.5) + val mockItem = mockk(relaxed = true) + every { mockItem.location } returns itemLoc + every { mockItem.teleportAsync(any()) } returns CompletableFuture.completedFuture(true) + // itemStack getter not mocked, so getSmeltingResult will catch the exception and return null + + every { TestHelper.mockWorld.getNearbyEntities(any(), any(), any(), any()) } returns listOf(mockItem) + + smelter.callPowerUpdate() + + // Item should still be moved forward even without smelting + verify { mockItem.teleportAsync(match { loc -> + loc.z < 0.5 && loc.x == 0.5 + }) } + // Power should not be consumed since no recipe was found + assertEquals(2, smelter.currentPower) + } + + @Test + fun `pulls power from adjacent blocks`() { + val registry = PowerBlockRegistry(TestHelper.mockPlugin) + val smelterLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val smelter = AutoSmelter(smelterLoc, BlockFace.NORTH) + TestHelper.addToRegistry(registry, smelter, "auto_smelter_north") + + // Place a battery with power adjacent + val batteryLoc = TestHelper.createLocation(1.0, 64.0, 0.0) + val battery = com.coderjoe.atlas.power.block.SmallBattery(batteryLoc, BlockFace.WEST) + battery.currentPower = 5 + TestHelper.addToRegistry(registry, battery, "small_battery") + + every { TestHelper.mockWorld.getNearbyEntities(any(), any(), any(), any()) } returns emptyList() + + smelter.callPowerUpdate() + + assertTrue(smelter.currentPower > 0, "Smelter should have pulled power") + assertTrue(battery.currentPower < 5, "Battery should have less power") + } + + @Test + fun `does not exceed max storage when pulling power`() { + val registry = PowerBlockRegistry(TestHelper.mockPlugin) + val smelterLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val smelter = AutoSmelter(smelterLoc, BlockFace.NORTH) + smelter.currentPower = 2 // Already full + TestHelper.addToRegistry(registry, smelter, "auto_smelter_north") + + val batteryLoc = TestHelper.createLocation(1.0, 64.0, 0.0) + val battery = com.coderjoe.atlas.power.block.SmallBattery(batteryLoc, BlockFace.WEST) + battery.currentPower = 5 + TestHelper.addToRegistry(registry, battery, "small_battery") + + every { TestHelper.mockWorld.getNearbyEntities(any(), any(), any(), any()) } returns emptyList() + + smelter.callPowerUpdate() + + assertEquals(2, smelter.currentPower, "Should not exceed max storage") + assertEquals(5, battery.currentPower, "Battery should not lose power when smelter is full") + } +} diff --git a/src/test/kotlin/com/coderjoe/atlas/power/PowerBlockInitializerTest.kt b/src/test/kotlin/com/coderjoe/atlas/power/PowerBlockInitializerTest.kt index 8021de9..981aa33 100644 --- a/src/test/kotlin/com/coderjoe/atlas/power/PowerBlockInitializerTest.kt +++ b/src/test/kotlin/com/coderjoe/atlas/power/PowerBlockInitializerTest.kt @@ -26,8 +26,8 @@ class PowerBlockRegistrationTest { TestHelper.initPowerFactory() val ids = PowerBlockFactory.getRegisteredBlockIds() - // 1 solar + 6 drill + 4 battery + 6 cable + 2 lava generator = 19 - assertEquals(19, ids.size) + // 1 solar + 6 drill + 4 battery + 6 cable + 2 lava generator + 8 auto smelter = 27 + assertEquals(27, ids.size) } @Test