From a18cdf04b6c539e9f2d29a71131e782b0092f9c0 Mon Sep 17 00:00:00 2001 From: CoderJoe Date: Sat, 14 Mar 2026 02:41:06 -0500 Subject: [PATCH 1/4] Add cobblestone and obsidian generator blocks Cobblestone generator consumes 2 power + water + lava to produce cobblestone. Obsidian generator consumes 100 power + water + lava to produce obsidian. Both atomically check that water and lava are available before consuming either. --- .../atlas/power/block/CobblestoneGenerator.kt | 118 ++++++++++++ .../atlas/power/block/ObsidianGenerator.kt | 118 ++++++++++++ .../block/cobblestone_generator_bottom.png | Bin 0 -> 496 bytes .../block/cobblestone_generator_side.png | Bin 0 -> 499 bytes .../cobblestone_generator_side_active.png | Bin 0 -> 495 bytes .../block/cobblestone_generator_top.png | Bin 0 -> 497 bytes .../cobblestone_generator_top_active.png | Bin 0 -> 497 bytes .../block/obsidian_generator_bottom.png | Bin 0 -> 500 bytes .../block/obsidian_generator_side.png | Bin 0 -> 504 bytes .../block/obsidian_generator_side_active.png | Bin 0 -> 513 bytes .../textures/block/obsidian_generator_top.png | Bin 0 -> 501 bytes .../block/obsidian_generator_top_active.png | Bin 0 -> 512 bytes .../atlas/power/CobblestoneGeneratorTest.kt | 180 +++++++++++++++++ .../atlas/power/ObsidianGeneratorTest.kt | 181 ++++++++++++++++++ 14 files changed, 597 insertions(+) create mode 100644 src/main/kotlin/com/coderjoe/atlas/power/block/CobblestoneGenerator.kt create mode 100644 src/main/kotlin/com/coderjoe/atlas/power/block/ObsidianGenerator.kt create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_bottom.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_side.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_side_active.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_top.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_top_active.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_bottom.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_side.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_side_active.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_top.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_top_active.png create mode 100644 src/test/kotlin/com/coderjoe/atlas/power/CobblestoneGeneratorTest.kt create mode 100644 src/test/kotlin/com/coderjoe/atlas/power/ObsidianGeneratorTest.kt diff --git a/src/main/kotlin/com/coderjoe/atlas/power/block/CobblestoneGenerator.kt b/src/main/kotlin/com/coderjoe/atlas/power/block/CobblestoneGenerator.kt new file mode 100644 index 0000000..3b7f304 --- /dev/null +++ b/src/main/kotlin/com/coderjoe/atlas/power/block/CobblestoneGenerator.kt @@ -0,0 +1,118 @@ +package com.coderjoe.atlas.power.block + +import com.coderjoe.atlas.atlasInfo +import com.coderjoe.atlas.core.BlockDescriptor +import com.coderjoe.atlas.core.PlacementType +import com.coderjoe.atlas.fluid.FluidBlockRegistry +import com.coderjoe.atlas.fluid.FluidType +import com.coderjoe.atlas.fluid.block.FluidContainer +import com.coderjoe.atlas.fluid.block.FluidMerger +import com.coderjoe.atlas.fluid.block.FluidPipe +import com.coderjoe.atlas.fluid.block.FluidPump +import com.coderjoe.atlas.power.PowerBlock +import com.coderjoe.atlas.power.PowerBlockRegistry +import org.bukkit.Location +import org.bukkit.Material +import org.bukkit.block.BlockFace +import org.bukkit.inventory.ItemStack + +class CobblestoneGenerator(location: Location) : PowerBlock(location, maxStorage = 2) { + + override val canReceivePower: Boolean = true + override val updateIntervalTicks: Long = 20L + + companion object { + const val BLOCK_ID = "cobblestone_generator" + const val BLOCK_ID_ACTIVE = "cobblestone_generator_active" + const val POWER_COST = 2 + + private val ADJACENT_FACES = listOf( + BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, + BlockFace.WEST, BlockFace.UP, BlockFace.DOWN + ) + + val descriptor = BlockDescriptor( + baseBlockId = BLOCK_ID, + displayName = "Cobblestone Generator", + description = "Machine - consumes $POWER_COST power + water + lava → cobblestone", + placementType = PlacementType.SIMPLE, + directionalVariants = emptyMap(), + allRegistrableIds = listOf(BLOCK_ID, BLOCK_ID_ACTIVE), + constructor = { loc, _ -> CobblestoneGenerator(loc) } + ) + } + + override val baseBlockId: String = BLOCK_ID + + override fun getVisualStateBlockId(): String = when { + currentPower >= POWER_COST -> BLOCK_ID_ACTIVE + else -> BLOCK_ID + } + + 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) + } + } + } + } + + if (currentPower < POWER_COST) return + + val fluidRegistry = FluidBlockRegistry.instance ?: return + + // Check that BOTH water and lava are available before consuming either + var waterSource: Pair? = null + var lavaSource: Pair? = null + + for (face in ADJACENT_FACES) { + val source = fluidRegistry.getAdjacentFluidBlock(location, face) ?: continue + if (waterSource == null && hasFluidAvailable(source, face, FluidType.WATER)) { + waterSource = Pair(source, face) + } else if (lavaSource == null && hasFluidAvailable(source, face, FluidType.LAVA)) { + lavaSource = Pair(source, face) + } + if (waterSource != null && lavaSource != null) break + } + + if (waterSource == null || lavaSource == null) return + + // Both available — consume atomically + pullFluid(waterSource.first, waterSource.second) + pullFluid(lavaSource.first, lavaSource.second) + removePower(POWER_COST) + + val world = location.world ?: return + val dropLocation = location.clone().add(0.5, 1.0, 0.5) + world.dropItemNaturally(dropLocation, ItemStack(Material.COBBLESTONE)) + + plugin.logger.atlasInfo("CobblestoneGenerator at ${location.blockX},${location.blockY},${location.blockZ} produced 1 cobblestone") + } + + private fun hasFluidAvailable(source: com.coderjoe.atlas.fluid.FluidBlock, face: BlockFace, fluidType: FluidType): Boolean { + return when (source) { + is FluidPump -> source.canRemoveFluidFrom(face.oppositeFace) && source.storedFluid == fluidType + is FluidPipe -> source.hasFluid() && source.storedFluid == fluidType + is FluidContainer -> source.canRemoveFluidFrom(face.oppositeFace) && source.storedFluid == fluidType + is FluidMerger -> source.hasFluid() && source.storedFluid == fluidType + else -> false + } + } + + private fun pullFluid(source: com.coderjoe.atlas.fluid.FluidBlock, face: BlockFace) { + when (source) { + is FluidPump -> source.removeFluid() + is FluidPipe -> source.removeFluid() + is FluidContainer -> source.removeFluid() + is FluidMerger -> source.removeFluid() + } + } +} diff --git a/src/main/kotlin/com/coderjoe/atlas/power/block/ObsidianGenerator.kt b/src/main/kotlin/com/coderjoe/atlas/power/block/ObsidianGenerator.kt new file mode 100644 index 0000000..5934a37 --- /dev/null +++ b/src/main/kotlin/com/coderjoe/atlas/power/block/ObsidianGenerator.kt @@ -0,0 +1,118 @@ +package com.coderjoe.atlas.power.block + +import com.coderjoe.atlas.atlasInfo +import com.coderjoe.atlas.core.BlockDescriptor +import com.coderjoe.atlas.core.PlacementType +import com.coderjoe.atlas.fluid.FluidBlockRegistry +import com.coderjoe.atlas.fluid.FluidType +import com.coderjoe.atlas.fluid.block.FluidContainer +import com.coderjoe.atlas.fluid.block.FluidMerger +import com.coderjoe.atlas.fluid.block.FluidPipe +import com.coderjoe.atlas.fluid.block.FluidPump +import com.coderjoe.atlas.power.PowerBlock +import com.coderjoe.atlas.power.PowerBlockRegistry +import org.bukkit.Location +import org.bukkit.Material +import org.bukkit.block.BlockFace +import org.bukkit.inventory.ItemStack + +class ObsidianGenerator(location: Location) : PowerBlock(location, maxStorage = 100) { + + override val canReceivePower: Boolean = true + override val updateIntervalTicks: Long = 20L + + companion object { + const val BLOCK_ID = "obsidian_generator" + const val BLOCK_ID_ACTIVE = "obsidian_generator_active" + const val POWER_COST = 100 + + private val ADJACENT_FACES = listOf( + BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, + BlockFace.WEST, BlockFace.UP, BlockFace.DOWN + ) + + val descriptor = BlockDescriptor( + baseBlockId = BLOCK_ID, + displayName = "Obsidian Generator", + description = "Machine - consumes $POWER_COST power + water + lava → obsidian", + placementType = PlacementType.SIMPLE, + directionalVariants = emptyMap(), + allRegistrableIds = listOf(BLOCK_ID, BLOCK_ID_ACTIVE), + constructor = { loc, _ -> ObsidianGenerator(loc) } + ) + } + + override val baseBlockId: String = BLOCK_ID + + override fun getVisualStateBlockId(): String = when { + currentPower >= POWER_COST -> BLOCK_ID_ACTIVE + else -> BLOCK_ID + } + + 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) + } + } + } + } + + if (currentPower < POWER_COST) return + + val fluidRegistry = FluidBlockRegistry.instance ?: return + + // Check that BOTH water and lava are available before consuming either + var waterSource: Pair? = null + var lavaSource: Pair? = null + + for (face in ADJACENT_FACES) { + val source = fluidRegistry.getAdjacentFluidBlock(location, face) ?: continue + if (waterSource == null && hasFluidAvailable(source, face, FluidType.WATER)) { + waterSource = Pair(source, face) + } else if (lavaSource == null && hasFluidAvailable(source, face, FluidType.LAVA)) { + lavaSource = Pair(source, face) + } + if (waterSource != null && lavaSource != null) break + } + + if (waterSource == null || lavaSource == null) return + + // Both available — consume atomically + pullFluid(waterSource.first, waterSource.second) + pullFluid(lavaSource.first, lavaSource.second) + removePower(POWER_COST) + + val world = location.world ?: return + val dropLocation = location.clone().add(0.5, 1.0, 0.5) + world.dropItemNaturally(dropLocation, ItemStack(Material.OBSIDIAN)) + + plugin.logger.atlasInfo("ObsidianGenerator at ${location.blockX},${location.blockY},${location.blockZ} produced 1 obsidian") + } + + private fun hasFluidAvailable(source: com.coderjoe.atlas.fluid.FluidBlock, face: BlockFace, fluidType: FluidType): Boolean { + return when (source) { + is FluidPump -> source.canRemoveFluidFrom(face.oppositeFace) && source.storedFluid == fluidType + is FluidPipe -> source.hasFluid() && source.storedFluid == fluidType + is FluidContainer -> source.canRemoveFluidFrom(face.oppositeFace) && source.storedFluid == fluidType + is FluidMerger -> source.hasFluid() && source.storedFluid == fluidType + else -> false + } + } + + private fun pullFluid(source: com.coderjoe.atlas.fluid.FluidBlock, face: BlockFace) { + when (source) { + is FluidPump -> source.removeFluid() + is FluidPipe -> source.removeFluid() + is FluidContainer -> source.removeFluid() + is FluidMerger -> source.removeFluid() + } + } +} diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_bottom.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..d8d8ef8a02b6fa288d1c2e8aab1fef74ee371050 GIT binary patch literal 496 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBGHM;uumf=k2Y9fky%)+%Cql zP4)8Nzo=>T>#KwMMW1;K8WhT=RrfJ`WiMv`yzlw8+<5*?cI)MzSJvJCdtj5!>ffJp z-={N7uf3mNo6uAE``X{fso#$mp1Ci-{lC%wCWc2W0_qJGj7K;X{1^(EI)okOz=dqz zGTy5D&QM>$7q>lk_g}fUb$g!ND>j%6SAazir@}coAWATK|CVtEZll3EzcCbkV_007 z&woG#hYO$o==NCxlH<D;uumf=k2YHfrlMLTmxq> zWHxQ&+E^9P`YKU+A=lRf70g@$jmPg4Gj;6qcsJqAZhN`@_0o~^&&xlrtc(A9V3W@3 z-=A~er!)Bf-WUJtfW+fZYk%K9{jUGJWCA!|;ejK)t~N zF0}hL^OnEw82^2c*^_s>?5FLmzZEC zoDu4+b*!=b=ClCI9KOZlYu@AR5ICkTXynOY3 zCJWp7=e^};6vyo=t*^fQ_wmPw{rmO)r~YGQJi@8q$56=BA?z@R;Sq~~dV>XAX!mXA zEqlK))K~D``&PUEkKEh3eNXQd8+4<2$3O1?5D_niIvapU)Y%t!t*S;vIUYby`<2#iPu MPgg&ebxsLQ0LKimTmS$7 literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_top.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_top.png new file mode 100644 index 0000000000000000000000000000000000000000..663f2663174b929e981e411c6eb37cd4bf5a5736 GIT binary patch literal 497 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBF#9;uumf=k2YHfkzxfSPxov zS)?q^5$S9SRGH1YPif&6Hb#!euV&;iuhE~QIj8n~?(KbYDYbF-=RW`0_q#DQGVJ^F z+xN~h=>6Vz|JMPD$KTfeK7RUL|Kl0^?eqSp{$pi4!l~fLP{`CF>@bJn5sQF&g9Tiu z`WEw+zwa3TeURCccf0Jj?XABRC-**2P=hPLq6a8s3q%Jp?%ifKz-=^G=NraHZy4P^ z-;-HG$>zJFuz!Rk`ojR>rAtP7a6?Oy0j`oPioT$jZ)MKk(Y{#XI(CsgZZ*=U2bCceuk}%n^FVhj$%6 QFe({5UHx3vIVCg!0LqcIvH$=8 literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_top_active.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/cobblestone_generator_top_active.png new file mode 100644 index 0000000000000000000000000000000000000000..2d848cc490e8fb16642b963cb87731640d7eb648 GIT binary patch literal 497 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBF#9;uumf=k2YHfkzxfSPxov zB}`a6L!_B0kVks5%%z1}*cdq;znYQ9yheYH=A7E|xwrSprPRjRpZol0-|xoKSn==A zZ{Iu5pm)6R&aVR!kH4+`ef;#h@3r&y+vojH{m069gj2zfp^&LV*kKOCBNhSm1`D`Q z^)2Qtf8R0w`yjI?=XTj|+gpDtPVRl4paxffMGsKO7KjdH+`G+efZJ%W&NqyY-Y~j- zz9-kI0H3wkd>Xie&Ds?i+AkTN@MTL&#!)O?{J6TS2bKF&iJ4b QFe({5UHx3vIVCg!0KMC^`Tzg` literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_bottom.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..3d8cccae9731bc3ab0fa4cfaf7e09437b72e623e GIT binary patch literal 500 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBGEL;uumf=j|;;KjuIQw~OIT z>ksxE3%LDveWDImZ182-33ftFsak4hZQTRDZhyx1dEene9r@-p*MHCd{`u3+uiX2t zoj&>Z)0XeX4ZC0O`l>CryVSmHXTA0Rnte9kF56f$9^q8*V<=?m5O$cu@Q6h~y}<%5 zWPO8q%inj5+w45=9eY|LbNl|{yYXc^zssCaK~jW8-)8oX&Fm6qtE(B*;AUY_1{AUd zq5~QCZZjL;b_H1H8^%X(7~MYKlWXwA;aI2z>HGre{06hWe`D~$>L-Ldsv9h-8!qnI z&YmEI>2-uM#v?bGfvD%%UR#FA=ph7Gw&SP7m+yrS_UFC+7X3Z>d-Z?DNBbD<|2{XF Ua4KsaFg6)HUHx3vIVCg!06V+6%>V!Z literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_side.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_side.png new file mode 100644 index 0000000000000000000000000000000000000000..a7ccf2d4c42a100b23ed9c5b684de5d184f852cc GIT binary patch literal 504 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBGKN;uumf=k2Y9K~8}ZZWo&u z&s-uln{DNu|Hc8jF5SsW(K3DoYwk%)+{tG3w4Y)-?Q^c&vCpp+UVr=ZJad0-^e@); z?U&E}{g(AUogqEG{da48VN~Jkx|kRL^8Q=e=ZF0<`rp9th($oX!GiG!r-C0tAybF2 z!yLF!?iA4g=d0KsEBtN|C$`^xw|(4`d&LHm;cBpG<5V~&2Sf=b@82@cz->BM z=QoDJZw!ko^Z5^`;BW-gg3at5o7pAKR#!8qVRb9Q9kvd0Y!77IyUlEX5X0)+H;j+o zFuHxdC)ePK?sHU~>HGre{06hWe`D}L4IpG?&yp{^Ki+6>y=F(Lyzopr0Pk?KCjbBd literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_side_active.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/obsidian_generator_side_active.png new file mode 100644 index 0000000000000000000000000000000000000000..687b8e7170ab9efd0788eb0aae14aad3a1923c20 GIT binary patch literal 513 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9aJ;uumf=j|;+FK0&yw~I$Q z@>H4_Z#QUPJQ}fk#v7Lnyb&{ceH1;G6)>*n{5UT-vvf11i{j4^zg}v6&r+B+gb>GpJz(5=_}=(+__nwtQip{kZJ; hzml!r|1lr=%ar=gDXdC-0pz?e(+o8Q)(!zq4gGMplJI;~U0DZy4P^-;-f<2e&i8I;$Hjsv9ou+0LFIgu}H^3vMzWxyjt~Y_BcDWUQWoyW^ak!a2DF zllN~KXTZe}en%Gi#!&c;VR2BAc8B)vt#>PBlBZx>G8F{4=;ZIm+43?Bd@H6 Vi&*)|&%o$p@O1TaS?83{1OSE^vW;uumf=k2Y9fzFN+ZWmh| z_bOfJ^kBcZWulr!v)Uy$6ImAlU%}Ng*DPpAH+ncv+2JpLG5hBG-*(I?lin2f-u~FT zUwgkXpMJZcyuS98+uJ|6S8OmDT_vjKb8-sj6tV@P0~z;jGaKOc z7+B{U#z$`$-9F!wYw*P3f2alN`~vCx2D83@WAMQmOkictvLF04%y`Q_?RMh(f4{bT e|HpjfFO#&DH!I_fMh9TbGI+ZBxvX 0) + assertTrue(gen.currentPower < 100) + } +} From 9bc4416f37c01ae005683d06b6e8a59f3c10f3a5 Mon Sep 17 00:00:00 2001 From: CoderJoe Date: Sat, 14 Mar 2026 02:41:13 -0500 Subject: [PATCH 2/4] Add power merger block Pulls power from all non-facing adjacent blocks and stores it for downstream blocks to pull from in the facing direction. --- .../coderjoe/atlas/power/block/PowerMerger.kt | 78 ++++++++++ .../textures/block/power_merger_back.png | Bin 0 -> 499 bytes .../block/power_merger_back_powered.png | Bin 0 -> 500 bytes .../textures/block/power_merger_bottom.png | Bin 0 -> 500 bytes .../block/power_merger_bottom_powered.png | Bin 0 -> 497 bytes .../textures/block/power_merger_front.png | Bin 0 -> 502 bytes .../block/power_merger_front_powered.png | Bin 0 -> 502 bytes .../textures/block/power_merger_side.png | Bin 0 -> 499 bytes .../block/power_merger_side_powered.png | Bin 0 -> 499 bytes .../atlas/textures/block/power_merger_top.png | Bin 0 -> 499 bytes .../block/power_merger_top_powered.png | Bin 0 -> 499 bytes .../coderjoe/atlas/power/PowerMergerTest.kt | 144 ++++++++++++++++++ 12 files changed, 222 insertions(+) create mode 100644 src/main/kotlin/com/coderjoe/atlas/power/block/PowerMerger.kt create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_back.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_back_powered.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_bottom.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_bottom_powered.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_front.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_front_powered.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_side.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_side_powered.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_top.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_top_powered.png create mode 100644 src/test/kotlin/com/coderjoe/atlas/power/PowerMergerTest.kt diff --git a/src/main/kotlin/com/coderjoe/atlas/power/block/PowerMerger.kt b/src/main/kotlin/com/coderjoe/atlas/power/block/PowerMerger.kt new file mode 100644 index 0000000..7b26ce3 --- /dev/null +++ b/src/main/kotlin/com/coderjoe/atlas/power/block/PowerMerger.kt @@ -0,0 +1,78 @@ +package com.coderjoe.atlas.power.block + +import com.coderjoe.atlas.atlasInfo +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.Location +import org.bukkit.block.BlockFace + +class PowerMerger(location: Location, override val facing: BlockFace) : PowerBlock(location, maxStorage = 2) { + + override val canReceivePower: Boolean = false + override val updateIntervalTicks: Long = 20L + + companion object { + const val BLOCK_ID = "power_merger" + + val DIRECTIONAL_IDS = mapOf( + BlockFace.NORTH to "power_merger_north", + BlockFace.SOUTH to "power_merger_south", + BlockFace.EAST to "power_merger_east", + BlockFace.WEST to "power_merger_west", + BlockFace.UP to "power_merger_up", + BlockFace.DOWN to "power_merger_down" + ) + + val POWERED_IDS = mapOf( + BlockFace.NORTH to "power_merger_north_powered", + BlockFace.SOUTH to "power_merger_south_powered", + BlockFace.EAST to "power_merger_east_powered", + BlockFace.WEST to "power_merger_west_powered", + BlockFace.UP to "power_merger_up_powered", + BlockFace.DOWN to "power_merger_down_powered" + ) + + val ID_TO_FACING = (DIRECTIONAL_IDS.entries.associate { (face, id) -> id to face } + + POWERED_IDS.entries.associate { (face, id) -> id to face }) + + fun facingFromBlockId(blockId: String): BlockFace? = ID_TO_FACING[blockId] + + val descriptor = BlockDescriptor( + baseBlockId = BLOCK_ID, + displayName = "Power Merger", + description = "Cable - merges power from all sides, outputs in facing direction", + placementType = PlacementType.DIRECTIONAL, + directionalVariants = DIRECTIONAL_IDS, + allRegistrableIds = DIRECTIONAL_IDS.values.toList() + POWERED_IDS.values.toList(), + constructor = { loc, facing -> PowerMerger(loc, facing) } + ) + } + + override val baseBlockId: String = BLOCK_ID + + override fun getVisualStateBlockId(): String = + if (currentPower > 0) POWERED_IDS[facing]!! + else DIRECTIONAL_IDS[facing]!! + + override fun powerUpdate() { + val registry = PowerBlockRegistry.instance ?: return + + // Pull power from all faces except the output (facing) direction + val inputFaces = listOf(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN) + .filter { it != facing } + + for (face in inputFaces) { + if (currentPower >= maxStorage) break + val source = registry.getAdjacentPowerBlock(location, face) ?: continue + if (source.hasPower()) { + val pulled = source.removePower(1) + if (pulled > 0) { + addPower(pulled) + plugin.logger.atlasInfo("PowerMerger at ${location.blockX},${location.blockY},${location.blockZ} pulled $pulled power from ${source::class.simpleName} at ${face.name} (now $currentPower/$maxStorage)") + } + } + } + } +} diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_back.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_back.png new file mode 100644 index 0000000000000000000000000000000000000000..a06eb86de59147d93edeadc98829c2d5c20e91c7 GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBF>D;uumf=k2Y9g@+wPTmvm1 z3$^qnuTqNH(j6g{w?@e*?g5j?gTi-~3XbuLNRLuJZcdr*-r9@9+Dc`j46M2&aM{Lm^X#u)`dNM=S#B4Hj@A z>zmA5_I_iiui)FKcf0I|?XABRr}sWjP=hPLq6a8s3q%Jp?%ifKz-=^G=NraHZy4P^ z-;-HG$>zJFuz!Rk`ojR>rAtP7a6?Oy0j`oPioT$jZ)MKkz*H!bN_YYhPd0{l8KDpYc&0<8f#4hNMHg R4gn*R!PC{xWt~$(695cA!O>pX|iRiMuDHIoY?{f%Y+ZM>Khj8tC!DtW37Ap+ujMKb^ms}`F;K(zsBa`2G2{^Y+^t^?M5cT>JZJ-S5+X?dt1g|DXQD&eS37Fo)q0i-3BA1>+G;1wV#D zxKQ~f_KfPcjQ>8!)WmLk`=NTv?~l`}&mZ)GE5M=$C{ztX7x!#uPY}XsG+5_N<|8+m zd!FsJWtfb^1yBpl$tj$ZOE7u=mT?AFha%kZjiK-x!{W+({sStQ{y`{X>e$QgTe~DWM4fj^eoD literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_bottom.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..9ca4f379b4b9b2ea61513f248e9113aea843cb4f GIT binary patch literal 500 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBGEL;uumf=k2YHg@+tOTmv62 zwcg9Ygb<{`~UPGcBT$thdB(7SOnA?EEtb)D)=!J z!iCB=v1e4jW&HO+rY3gV+Yi-Set(=+eg2>iTmcq6K%r_7y0~XMdx8*7qrp0FG9S6g z-1BU&EyH9SE`VBaPEO&RT!P8_w~RBeIuzlKZw!Us7#3IN^B+*b^bbNAQ^#g@Ad)y+ zUCp3|?rmgcz`(Huq5~QCZZjL8h7Pi_+3Oq6A78LozGBVmtAGD({Qi&m$X}*-NAY9d T)*LE2!U z_ka8M=hua|WpB8XW%ifuuX**aX#e^9_Q(Gl{cmJ=#3G>HV8M8VQ^Aj+kf}r1VGdkq z?ieuUuJJt^xkrYC%QURt?B#%>HG$>zJFuzK{XCl8PL*d5W2W$ zJ9~l`Dp&28UX*L=R-fBNyqjo+Ei zm+swF|L5lK&##@o|K6wHv+@76zeQL6J}sNQ|NgiCssET6k8mpZF%&X&2s_MSc*G*0 z-e3V2vcAc@W$!nJ{S|!s^loqaZF}pl#glu*29wd%p=v!Rr*KX#!Q}m0#u=!_p(+Df z`VE8@SLX8{P(iX4Lm5-YW_BQwI9pxKpaypw7G*#oTOc}+aql*>0d8-Bb-rPI^oG&x z^F6r+PaM97T9D2!kj`%~>-#qbAFP1{R`x9U!uR8i^Q+dqei!}y^uzD}n2*#l6>4%P U?9vaF1I8zVr>mdKI;Vst0EMr+W&i*H literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_front_powered.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_front_powered.png new file mode 100644 index 0000000000000000000000000000000000000000..0bb875e96ebbf2830ef2ab2817af37e33c51ef4a GIT binary patch literal 502 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBG8J;uumf=k2YHfrlMLTmxqo z%Jvnq=ebN>(YMy6cL#G(_@NDr?IMB|59SFwd~q#mPr09YbKCdUHJ`8dpWat5^Y=h< z?D}`#?W^nS>R!~@e`_`DyT20e! z-EeWwcJ>4z94>%baFhASP3E3wdu^dC8@~Ac_<+CdwXYx6{(k!O`#D;uumf=k2YHxlE2Ct{0Ck z;=5$p>R=w?Y<{_8tLD@Q9|y+Q3=gaQ65Q+O##qiQkIu@`p|3mxp2cL`fzN_mmv%gpL-g1T~iYg3^>HGre{06hWe`D}LG7Li*(8_8M zy0~XMdx8+mPHf5;kKAMiqMm1aZ5bxxbS+rtIXQ)MatS8y-!jg?;VGB}-xvzNF)Xgk z=Rcr=&F?T}OdXrqfk@(Pbv1(;W)Q)YeK!5@Q)0_^=KfOK-S_Rj-K%fd5wFH6(Umtb SXd*B&89ZJ6T-G@yGywo%ptU^! literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_side_powered.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_side_powered.png new file mode 100644 index 0000000000000000000000000000000000000000..a9c8a7b17e312dff11307d02aafabd5b73936b33 GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBF>D;uumf=k2YHfrlMLTmxqo z%JvmXu5!^k8{K(YpxyQG;({iihPgvFe-C-jqUv2*(=KAX2 z$LH_0-)~p4|NZYn62J5B>bu{K&)fdJWwr z?U-!qa66m-L-+FsuQ%oHzQ6cxzw3*5I_x28V)L$Iq_TlG9 R`w5Ip22WQ%mvv4FO#tiQu%rM0 literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_top.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_top.png new file mode 100644 index 0000000000000000000000000000000000000000..8dc5975d16c74e841573cdec843f760525e8e749 GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBF>D;uumf=k2Y9g@+wPTmvm1 zTlFNb@(P*QsC~=J<#4R$G47ZKCYy7%>?$v`pZJ~FcX?CpeeTHT&-+jB`!DnNKyvK* zci;Q>+V8h3*)RY5ki_x)yZY~U?Z1=v`TO;c`_I%XG*~bm;Z*QrC}ipoc9_HPh($mh zE~H-Fu|uczMT+wZOI- THLq?1Mka%&tDnm{r-UW|X414D literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_top_powered.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/power_merger_top_powered.png new file mode 100644 index 0000000000000000000000000000000000000000..9b876b73808ae712fee77c5cf388f48bfd9465da GIT binary patch literal 499 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVBF>D;uumf=k2YHfrlMLTmxqo z%JvoN7AddFklvWBSgy(=UEv|v$o9^X(IsA`+~eEaX}Q($C#>rK?y!-QueSdXbA9#i z{r&_%ReRbqK?R zc1*T)xSh@aq5JuR*PC*8-(P&U-}#*_yD_>tG_7wKAH898`+QHX!4t(eG-WIT>HI)s zFzfp_1|K9_F_Zz_Rt-WI_iSfR5P~@ln=-~DH<^K`=hNohgRdl~O R^#LQ3!PC{xWt~$(69CCyuZ;iz literal 0 HcmV?d00001 diff --git a/src/test/kotlin/com/coderjoe/atlas/power/PowerMergerTest.kt b/src/test/kotlin/com/coderjoe/atlas/power/PowerMergerTest.kt new file mode 100644 index 0000000..f40ce36 --- /dev/null +++ b/src/test/kotlin/com/coderjoe/atlas/power/PowerMergerTest.kt @@ -0,0 +1,144 @@ +package com.coderjoe.atlas.power + +import com.coderjoe.atlas.TestHelper +import com.coderjoe.atlas.TestHelper.callPowerUpdate +import com.coderjoe.atlas.power.block.PowerMerger +import com.coderjoe.atlas.power.block.SmallSolarPanel +import org.bukkit.block.BlockFace +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.* + +class PowerMergerTest { + + private lateinit var registry: PowerBlockRegistry + + @BeforeEach + fun setup() { + TestHelper.setup() + registry = PowerBlockRegistry(TestHelper.mockPlugin) + } + + @AfterEach + fun teardown() { + TestHelper.teardown() + } + + @Test + fun `maxStorage is 2`() { + val merger = PowerMerger(TestHelper.createLocation(), BlockFace.NORTH) + assertEquals(2, merger.maxStorage) + } + + @Test + fun `canReceivePower is false`() { + // PowerMerger does not use canReceivePower — it pulls manually from non-facing sides + val merger = PowerMerger(TestHelper.createLocation(), BlockFace.NORTH) + assertFalse(merger.canAcceptPower()) + } + + @Test + fun `visual state unpowered when no power`() { + val merger = PowerMerger(TestHelper.createLocation(), BlockFace.NORTH) + assertEquals("power_merger_north", merger.getVisualStateBlockId()) + } + + @Test + fun `visual state powered when has power`() { + val merger = PowerMerger(TestHelper.createLocation(), BlockFace.NORTH) + merger.currentPower = 1 + assertEquals("power_merger_north_powered", merger.getVisualStateBlockId()) + } + + @Test + fun `visual state varies by facing direction`() { + for ((face, expectedId) in PowerMerger.DIRECTIONAL_IDS) { + val merger = PowerMerger(TestHelper.createLocation(), face) + assertEquals(expectedId, merger.getVisualStateBlockId()) + } + } + + @Test + fun `pulls power from non-facing sides`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = PowerMerger(mergerLoc, BlockFace.NORTH) + TestHelper.addToRegistry(registry, merger, "power_merger_north") + + // Source to the south (opposite of facing — behind) + val source1 = SmallSolarPanel(TestHelper.createLocation(0.0, 64.0, 1.0)) + source1.currentPower = 1 + TestHelper.addToRegistry(registry, source1, "small_solar_panel") + + // Source to the east (side) + val source2 = SmallSolarPanel(TestHelper.createLocation(1.0, 64.0, 0.0)) + source2.currentPower = 1 + TestHelper.addToRegistry(registry, source2, "small_solar_panel") + + merger.callPowerUpdate() + + assertEquals(2, merger.currentPower) + assertEquals(0, source1.currentPower) + assertEquals(0, source2.currentPower) + } + + @Test + fun `does not pull power from facing direction`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = PowerMerger(mergerLoc, BlockFace.NORTH) + TestHelper.addToRegistry(registry, merger, "power_merger_north") + + // Source to the north (facing direction — should NOT pull from here) + val source = SmallSolarPanel(TestHelper.createLocation(0.0, 64.0, -1.0)) + source.currentPower = 1 + TestHelper.addToRegistry(registry, source, "small_solar_panel") + + merger.callPowerUpdate() + + assertEquals(0, merger.currentPower) + assertEquals(1, source.currentPower) + } + + @Test + fun `stops pulling when full`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = PowerMerger(mergerLoc, BlockFace.NORTH) + merger.currentPower = 2 + TestHelper.addToRegistry(registry, merger, "power_merger_north") + + val source = SmallSolarPanel(TestHelper.createLocation(0.0, 64.0, 1.0)) + source.currentPower = 1 + TestHelper.addToRegistry(registry, source, "small_solar_panel") + + merger.callPowerUpdate() + + assertEquals(2, merger.currentPower) + assertEquals(1, source.currentPower) + } + + @Test + fun `descriptor has correct properties`() { + val desc = PowerMerger.descriptor + assertEquals("power_merger", desc.baseBlockId) + assertEquals("Power Merger", desc.displayName) + assertEquals(12, desc.allRegistrableIds.size) + assertTrue(desc.allRegistrableIds.contains("power_merger_north")) + assertTrue(desc.allRegistrableIds.contains("power_merger_north_powered")) + } + + @Test + fun `downstream block can pull from merger in facing direction`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = PowerMerger(mergerLoc, BlockFace.NORTH) + merger.currentPower = 2 + TestHelper.addToRegistry(registry, merger, "power_merger_north") + + // Consumer to the north (facing direction) that pulls from adjacent + val consumer = com.coderjoe.atlas.power.block.SmallDrill(TestHelper.createLocation(0.0, 64.0, -1.0), BlockFace.DOWN) + TestHelper.addToRegistry(registry, consumer, "small_drill_down") + + // The merger stores power; downstream blocks pull from it via their own update + assertTrue(merger.hasPower()) + val pulled = merger.removePower(1) + assertEquals(1, pulled) + assertEquals(1, merger.currentPower) + } +} From 6fdd578bc4908a95c79fa897cde013d5dd7c7334 Mon Sep 17 00:00:00 2001 From: CoderJoe Date: Sat, 14 Mar 2026 02:41:23 -0500 Subject: [PATCH 3/4] Add fluid merger block with full network integration Pulls fluid from all non-facing adjacent fluid blocks and holds it for downstream blocks to pull from in the facing direction. Updated FluidPipe, FluidContainer, LavaGenerator, CobblestoneGenerator, and ObsidianGenerator to recognize FluidMerger as a valid fluid source. --- .../atlas/fluid/block/FluidContainer.kt | 10 ++ .../coderjoe/atlas/fluid/block/FluidMerger.kt | 117 ++++++++++++++ .../coderjoe/atlas/fluid/block/FluidPipe.kt | 7 + .../atlas/power/block/LavaGenerator.kt | 7 + .../textures/block/fluid_merger_back.png | Bin 0 -> 507 bytes .../textures/block/fluid_merger_back_lava.png | Bin 0 -> 509 bytes .../block/fluid_merger_back_water.png | Bin 0 -> 514 bytes .../textures/block/fluid_merger_bottom.png | Bin 0 -> 513 bytes .../block/fluid_merger_bottom_lava.png | Bin 0 -> 511 bytes .../block/fluid_merger_bottom_water.png | Bin 0 -> 506 bytes .../textures/block/fluid_merger_front.png | Bin 0 -> 514 bytes .../block/fluid_merger_front_lava.png | Bin 0 -> 512 bytes .../block/fluid_merger_front_water.png | Bin 0 -> 514 bytes .../textures/block/fluid_merger_side.png | Bin 0 -> 514 bytes .../textures/block/fluid_merger_side_lava.png | Bin 0 -> 511 bytes .../block/fluid_merger_side_water.png | Bin 0 -> 514 bytes .../atlas/textures/block/fluid_merger_top.png | Bin 0 -> 514 bytes .../textures/block/fluid_merger_top_lava.png | Bin 0 -> 507 bytes .../textures/block/fluid_merger_top_water.png | Bin 0 -> 511 bytes .../coderjoe/atlas/fluid/FluidMergerTest.kt | 152 ++++++++++++++++++ 20 files changed, 293 insertions(+) create mode 100644 src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidMerger.kt create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back_lava.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back_water.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_bottom.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_bottom_lava.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_bottom_water.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_front.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_front_lava.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_front_water.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_side.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_side_lava.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_side_water.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_top.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_top_lava.png create mode 100644 src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_top_water.png create mode 100644 src/test/kotlin/com/coderjoe/atlas/fluid/FluidMergerTest.kt diff --git a/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidContainer.kt b/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidContainer.kt index 67d8df8..9a1af2f 100644 --- a/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidContainer.kt +++ b/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidContainer.kt @@ -160,6 +160,16 @@ class FluidContainer(location: Location, override val facing: BlockFace) : Fluid } } } + is FluidMerger -> { + if (source.hasFluid()) { + val fluid = source.removeFluid() + if (storeFluid(fluid)) { + plugin.logger.atlasInfo("FluidContainer at ${location.blockX},${location.blockY},${location.blockZ} pulled ${fluid.name} from FluidMerger") + } else { + source.storeFluid(fluid) + } + } + } } } diff --git a/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidMerger.kt b/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidMerger.kt new file mode 100644 index 0000000..0fca43d --- /dev/null +++ b/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidMerger.kt @@ -0,0 +1,117 @@ +package com.coderjoe.atlas.fluid.block + +import com.coderjoe.atlas.atlasInfo +import com.coderjoe.atlas.core.BlockDescriptor +import com.coderjoe.atlas.core.PlacementType +import com.coderjoe.atlas.fluid.FluidBlock +import com.coderjoe.atlas.fluid.FluidBlockRegistry +import com.coderjoe.atlas.fluid.FluidType +import org.bukkit.Location +import org.bukkit.block.BlockFace + +class FluidMerger(location: Location, override val facing: BlockFace) : FluidBlock(location) { + + override val updateIntervalTicks: Long = 20L + + companion object { + const val BLOCK_ID = "fluid_merger" + + val DIRECTIONAL_IDS = mapOf( + BlockFace.NORTH to "fluid_merger_north", + BlockFace.SOUTH to "fluid_merger_south", + BlockFace.EAST to "fluid_merger_east", + BlockFace.WEST to "fluid_merger_west", + BlockFace.UP to "fluid_merger_up", + BlockFace.DOWN to "fluid_merger_down" + ) + + val WATER_FILLED_IDS = mapOf( + BlockFace.NORTH to "fluid_merger_north_filled", + BlockFace.SOUTH to "fluid_merger_south_filled", + BlockFace.EAST to "fluid_merger_east_filled", + BlockFace.WEST to "fluid_merger_west_filled", + BlockFace.UP to "fluid_merger_up_filled", + BlockFace.DOWN to "fluid_merger_down_filled" + ) + + val LAVA_FILLED_IDS = mapOf( + BlockFace.NORTH to "fluid_merger_north_filled_lava", + BlockFace.SOUTH to "fluid_merger_south_filled_lava", + BlockFace.EAST to "fluid_merger_east_filled_lava", + BlockFace.WEST to "fluid_merger_west_filled_lava", + BlockFace.UP to "fluid_merger_up_filled_lava", + BlockFace.DOWN to "fluid_merger_down_filled_lava" + ) + + val ID_TO_FACING = DIRECTIONAL_IDS.entries.associate { (face, id) -> id to face } + + fun facingFromBlockId(blockId: String): BlockFace? = ID_TO_FACING[blockId] + + val descriptor = BlockDescriptor( + baseBlockId = BLOCK_ID, + displayName = "Fluid Merger", + description = "Merger - merges fluid from all sides, outputs in facing direction", + placementType = PlacementType.DIRECTIONAL, + directionalVariants = DIRECTIONAL_IDS, + allRegistrableIds = DIRECTIONAL_IDS.values.toList() + WATER_FILLED_IDS.values.toList() + LAVA_FILLED_IDS.values.toList(), + constructor = { loc, facing -> FluidMerger(loc, facing) } + ) + } + + override val baseBlockId: String = BLOCK_ID + + override fun getVisualStateBlockId(): String = when (storedFluid) { + FluidType.WATER -> WATER_FILLED_IDS[facing]!! + FluidType.LAVA -> LAVA_FILLED_IDS[facing]!! + FluidType.NONE -> DIRECTIONAL_IDS[facing]!! + } + + override fun fluidUpdate() { + if (hasFluid()) return + + val registry = FluidBlockRegistry.instance ?: return + + // Pull fluid from all faces except the output (facing) direction + val inputFaces = listOf(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN) + .filter { it != facing } + + for (face in inputFaces) { + val source = registry.getAdjacentFluidBlock(location, face) ?: continue + + when (source) { + is FluidPump -> { + if (source.canRemoveFluidFrom(face.oppositeFace) && source.hasFluid()) { + val fluid = source.removeFluid() + storeFluid(fluid) + plugin.logger.atlasInfo("FluidMerger at ${location.blockX},${location.blockY},${location.blockZ} pulled ${fluid.name} from FluidPump at ${face.name}") + return + } + } + is FluidPipe -> { + if (source.hasFluid()) { + val fluid = source.removeFluid() + storeFluid(fluid) + plugin.logger.atlasInfo("FluidMerger at ${location.blockX},${location.blockY},${location.blockZ} pulled ${fluid.name} from FluidPipe at ${face.name}") + return + } + } + is FluidContainer -> { + if (source.canRemoveFluidFrom(face.oppositeFace) && source.hasFluid()) { + val fluid = source.removeFluid() + storeFluid(fluid) + plugin.logger.atlasInfo("FluidMerger at ${location.blockX},${location.blockY},${location.blockZ} pulled ${fluid.name} from FluidContainer at ${face.name}") + return + } + } + is FluidMerger -> { + if (source.hasFluid()) { + val fluid = source.removeFluid() + storeFluid(fluid) + plugin.logger.atlasInfo("FluidMerger at ${location.blockX},${location.blockY},${location.blockZ} pulled ${fluid.name} from FluidMerger at ${face.name}") + return + } + } + } + } + } +} diff --git a/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidPipe.kt b/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidPipe.kt index 92a8b4a..d3708c0 100644 --- a/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidPipe.kt +++ b/src/main/kotlin/com/coderjoe/atlas/fluid/block/FluidPipe.kt @@ -95,6 +95,13 @@ class FluidPipe(location: Location, override val facing: BlockFace) : FluidBlock plugin.logger.atlasInfo("FluidPipe at ${location.blockX},${location.blockY},${location.blockZ} pulled ${fluid.name} from FluidContainer") } } + is FluidMerger -> { + if (source.hasFluid()) { + val fluid = source.removeFluid() + storeFluid(fluid) + plugin.logger.atlasInfo("FluidPipe at ${location.blockX},${location.blockY},${location.blockZ} pulled ${fluid.name} from FluidMerger") + } + } } } } diff --git a/src/main/kotlin/com/coderjoe/atlas/power/block/LavaGenerator.kt b/src/main/kotlin/com/coderjoe/atlas/power/block/LavaGenerator.kt index f07dff1..53dd541 100644 --- a/src/main/kotlin/com/coderjoe/atlas/power/block/LavaGenerator.kt +++ b/src/main/kotlin/com/coderjoe/atlas/power/block/LavaGenerator.kt @@ -6,6 +6,7 @@ import com.coderjoe.atlas.core.PlacementType import com.coderjoe.atlas.fluid.FluidBlockRegistry import com.coderjoe.atlas.fluid.FluidType import com.coderjoe.atlas.fluid.block.FluidContainer +import com.coderjoe.atlas.fluid.block.FluidMerger import com.coderjoe.atlas.fluid.block.FluidPipe import com.coderjoe.atlas.fluid.block.FluidPump import com.coderjoe.atlas.power.PowerBlock @@ -84,6 +85,12 @@ class LavaGenerator(location: Location) : PowerBlock(location, maxStorage = 50) return true } } + is FluidMerger -> { + if (source.hasFluid() && source.storedFluid == FluidType.LAVA) { + source.removeFluid() + return true + } + } } return false } diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d182ed9fdd850a9f24589de29285a10e4e592b GIT binary patch literal 507 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9jM;uumf=j|;+KPN{Cw?G56 zDfyyO8h6-E7aHoNZ%bU5C_bemEpGAJ^@>&JHJAKaxO3yo{QYz0_gQa}dp`f^=WiRo za<4mn_~hTW=kKj&ToV_+t@iMaoc*Qyci;Yd`}ePp8~#rJ$IRGI2Eo1C*%O3N zOhi-0c;qHC5cRy+Ys)Yh$zlv;oC@dUfGEM`{aeNvaQ9(R1{C@RLdsS7{0CHU`V6dd zGkeEoc8QDC)eLGl0sv-#t-~DK10DBnGaFzHC$O?;`Q|!1zCX8s!FuiQyL;dNF(0XA YwB}Twr{XEU6Bwxsp00i_>zopr09K2+&;S4c literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back_lava.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back_lava.png new file mode 100644 index 0000000000000000000000000000000000000000..7e73e63a29c38fe3e2d86606567579f933a2a5ce GIT binary patch literal 509 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9dK;uumf=j|;;KW9e?w~Nyj z%sQpl#J;XAx5Skr?1-7c4so+U&sCo88yXCKcRuF`_<#6L!n51+=9T+PZ<1SYzpsw( z{$_cLcjvo*AHI99pJCm-c>Q4c9}&;<@8;)~{r|R8dcXX#|3?3t7#^_*s5e+J9^q8* zV<=?m5O$aY7s`FhcSr#fUUzE+XJ`uY-djp zKr#&>54YeZ^O2j(YtB|zGYoknADe#oC1LWr@$tVsJM8bg-TR-RaQ}T9&t-Ls-)aG) OmBG{1&t;ucLK6U{ue`qi literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back_water.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_back_water.png new file mode 100644 index 0000000000000000000000000000000000000000..b00b792b1e16c85904d4b336238fd72f442938c1 GIT binary patch literal 514 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9yR;uumf=k2Y9fzFN+ZWmh^ zI~zO&U5+f_@R3@?BGt99!&K1ZV1kmNPguYKgdOHE zJYo@0Z?IrI!l~c~7rOS1A-BG|VX6P5`;T|j-jf&G@4nkU?&-Z^gUMLc!;Ls6r*KX# z!Q}m0#u;!igt5p%-xvzNF)Xgk=Rcr=ZacCvrjE_*KqPUtx|%@^)sd*mfL^f$q5~QC zZZjJo`vpT8!=pEhK;-uMo?L?`+{;*$u?VE|1Chb3@81}Fa0k}2><3Q`GhVWvn|=4% i-7QYd7z&kD6Fo`mgwV zSykjO*7vv1p8Naq{JrxG=j{0VPwz{VnSOs)eC(@#zkZh1V}JZ zwzDS)A(@AvjPb}#W+3W$w%3+nGTd4$$~YCy$pKM<$@{mAGjKZ?tn(W~;WviGmHGS! zRB-qUYQbjqj?L^6XRE6j)UbLV;SO7eIkpEf?%ifKK!~9`cXq#{y*zte?(WFC*L9^Y ftN$}T+Q-mcWOh)?@M0w}Y8gCT{an^LB{Ts5O|ZJ$ literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_bottom_lava.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_bottom_lava.png new file mode 100644 index 0000000000000000000000000000000000000000..89816fb98b93fa1f944b544558f7d1d3d0990011 GIT binary patch literal 511 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9pO;uumf=k2YHzD07vvmpCPH%X&8*KZ>d-3@kr&av3)Xl!f%D>1I zyRR>e-*A7A{GIpz-u&fx@aW~op literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_bottom_water.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_bottom_water.png new file mode 100644 index 0000000000000000000000000000000000000000..61a26943d9bf3202f6be2022fcad5b372907887d GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9vQ;uumf=k2Y9fy{vtZWmh) z<_j9G@nE0v#VPWOkTbjgf*=>GgnLpO)|@n`wB{Tbi0+T%}aDlI2`wfV2}{r2;F z`aATOU;X>`{Jng}oVfenY7g&tx4*Q$;>O?OzrTIl@_+hIeii}s1`Ea`oCRrIzvE_NVWTmoIv6Il~iEF|z)2et~p;gGJxJG5DaH ziL4B0b2SJF?%mFwAcSHynli>CH<^K`=fz%IhRH}S#8Aema83@05?tQDWt;)`2o_~P zp>H6hT$Rs%Km}(IfOT$W@7T;Pak09ZK@CSp0hQfOzHt6{V|=vV@BF*+a<%X69qx$B X^r$ZgU%NIJ7^e)Lu6{1-oD!Mnmo>7w@j0S?|bD$kZY1 zFo)q0i-3BA1>+G;1wXjZwQmf$@zo9SHthNN-@bR>Uwl{oT+w^W8J=(zSTwN+r1Jxj z!L0A!7<_P>4c1xRU{T$0anE-41R)$wfLd^q`N&P?o@aY)875FyNX}HxMlEk^>bP0l+XkKry#k1 literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_front_lava.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_front_lava.png new file mode 100644 index 0000000000000000000000000000000000000000..ce263aa32b9e58eedfc651c581f46b7f3153555c GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9>W;uumf=k2Y9p-zP|ZHXTO zIC~r>^XB+Cma{)AVBZ~l=NX%uyFvu7+`q@jLn!Z};=P+g|^zj-}x1znb3_)2Ccnw%3+ns2jQC?E7}+?^bW0-`^FlTlZdG;T`*`#pWU+#bP0l+XkKPK>&Q literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_front_water.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_front_water.png new file mode 100644 index 0000000000000000000000000000000000000000..4c1f82fb0d843fabcf91783e9e14bca75ee18125 GIT binary patch literal 514 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9yR;uumf=k2YHzDEC0J9Oh$v_S1S%_YAUR3;VQ|C&}`zgy{b z)xS!+{W^b}zTZuJ{qIlu`*eo+d2;i`Y7f4)(A`(Mf7gw_w?F39#p(V_{m069gj2zf zp^&LV*kKOCBNhSm1`D`Q^lj!XwQm{gKFaL5`$k@Dzx!_c*eCaj4JM;2MAdsvPT`zf zg30^0j5AQpLsbT}^&1E+uFU5@pn_yAhBBs(&FnxVakjdeK@ILYEXsgFwm@_swLrb=nbRW=X-Juo;bV@wIH2eAf4Y}*7t7=K3GEutn69xh4053{kv}beSZ1$pUSO2X8#mt5m0ZiU_8R9 z;KxwN)FJFJhv5-iC@+`)!neKb5x-P^+V$Q3eK_x9^_Jg{UEkTV8)H?EFyam4qc@Ch zpYO>vcw!ohP{tyV&JRQev%Y_0@Ikj7SsBoc)gW|n&vy0%ArwcVDPufxlNpG5p6#_| zn2h8X3}u`O=j4DW!Q}m0#u;!gV^Iba`UXOaEA#mesNfDPJGQ?yGC#KdP5Zg__tmBE d|FU=dW(qxJCs8lGKnfVQ44$rjF6*2Ung9Z$yVL*x literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_side_lava.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_side_lava.png new file mode 100644 index 0000000000000000000000000000000000000000..7652c79e38056b05a01b62e5c39ba174c9777888 GIT binary patch literal 511 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9pO;uumf=k2YHzD=YW?4$1)-c_{U-B~o6J4W z_S!N`MmG{!8K=TIIUq_fdH4gm?hpX$e8c$Y4WrxVdvXn)I08!8;Z6(PkM#HH4C>eW&!7I+P#973x~_EF@BZn_e|}E-X#QEBL&1-skf}r1 zVGhG176J7J3&tayFrhoQ0q$Vbbf(!euG)x zzcKjW@E6R2>IRGIhKqZ)vnL2)^FB-&H<^K`=hvvf z11d;GpND6j71qx$QFnWWZb*WY=AqkX7@YV%d^+z?vJf|U03?D e`ak2NeGL4;cFc_`TmJ#$mci52&t;ucLK6T#gS=M& literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_top_lava.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_top_lava.png new file mode 100644 index 0000000000000000000000000000000000000000..67268a84daf7c158d768e67c1937a9bfa2e41c72 GIT binary patch literal 507 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9jM;uumf=k2YHzDxlUZh;2h zcn&ZbHLY`aD_}LjJ7V*p=!2Xx4ZJ+(kKFhrrSyG{(<=E{(zCzk#>JWCA!|;ejK)u0& z@d&4aA44HrX!}<7jNdnz*Vwbq=U?yt`u)Xs=fih?mpP+?sT5iFX7-NF>=I|Is~ObL zO+;1(wAU7h4rJWB&1`^bF`6=lM{gK`$nEnzxdu-p_hBew5lH6;B7<4qzcKj0y@5p; zP^cP&F7DaRo*;xX0KhtLG9S6g-1BU&EyH9S;iTTM_x=7F{eAZ8`@i`G azO&Y`t83{0?k@vIDubu1pUXO@geCw)%(oB# literal 0 HcmV?d00001 diff --git a/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_top_water.png b/src/main/resources/nexo/pack/assets/atlas/textures/block/fluid_merger_top_water.png new file mode 100644 index 0000000000000000000000000000000000000000..f4d5b830a7010793df1141b4cac3b20ccf9d7781 GIT binary patch literal 511 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU_9pO;uumf=k2Y9fzFN+ZWmh; z*?OCV;-o570~}3`E(m5+%~1|u;_FS`)O7HZfaH$n9E<)PxpVN%_WjZQr~B5t{ycy7 z^^cpra@$S&`k?O5&EJv-ZoYl|d6|BN^zyUY-<6B+uCK3}F+Y5E{mgnthC-$eVTU;k zk5~lM8!Q-)a4Pu0g}!}b$c?XVh__*ve|P=yv+o(-mv`T(=1UX8p&n|)P39vvnR}k? zwPl!$)mXSq=j0U5$t9S)f6F)nE{3ojS?C)>;WviGmHGS!RL~uXtcb_eZD8x;0X^IbY*vHcz*q}_>g>h*WYV@ h-(C9tkNHR~6Wcc1d~TJ}GGN3qc)I$ztaD0e0svXsyd3}l literal 0 HcmV?d00001 diff --git a/src/test/kotlin/com/coderjoe/atlas/fluid/FluidMergerTest.kt b/src/test/kotlin/com/coderjoe/atlas/fluid/FluidMergerTest.kt new file mode 100644 index 0000000..de2f041 --- /dev/null +++ b/src/test/kotlin/com/coderjoe/atlas/fluid/FluidMergerTest.kt @@ -0,0 +1,152 @@ +package com.coderjoe.atlas.fluid + +import com.coderjoe.atlas.TestHelper +import com.coderjoe.atlas.TestHelper.callFluidUpdate +import com.coderjoe.atlas.fluid.block.FluidMerger +import com.coderjoe.atlas.fluid.block.FluidPipe +import org.bukkit.block.BlockFace +import org.junit.jupiter.api.* +import org.junit.jupiter.api.Assertions.* + +class FluidMergerTest { + + private lateinit var registry: FluidBlockRegistry + + @BeforeEach + fun setup() { + TestHelper.setup() + registry = FluidBlockRegistry(TestHelper.mockPlugin) + } + + @AfterEach + fun teardown() { + TestHelper.teardown() + } + + @Test + fun `visual state empty when no fluid`() { + val merger = FluidMerger(TestHelper.createLocation(), BlockFace.NORTH) + assertEquals("fluid_merger_north", merger.getVisualStateBlockId()) + } + + @Test + fun `visual state water when holding water`() { + val merger = FluidMerger(TestHelper.createLocation(), BlockFace.NORTH) + merger.storeFluid(FluidType.WATER) + assertEquals("fluid_merger_north_filled", merger.getVisualStateBlockId()) + } + + @Test + fun `visual state lava when holding lava`() { + val merger = FluidMerger(TestHelper.createLocation(), BlockFace.NORTH) + merger.storeFluid(FluidType.LAVA) + assertEquals("fluid_merger_north_filled_lava", merger.getVisualStateBlockId()) + } + + @Test + fun `visual state varies by facing direction`() { + for ((face, expectedId) in FluidMerger.DIRECTIONAL_IDS) { + val merger = FluidMerger(TestHelper.createLocation(), face) + assertEquals(expectedId, merger.getVisualStateBlockId()) + } + } + + @Test + fun `pulls fluid from non-facing pipe`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = FluidMerger(mergerLoc, BlockFace.NORTH) + TestHelper.addToRegistry(registry, merger, "fluid_merger_north") + + // Pipe to the south (not facing direction) + val pipeLoc = TestHelper.createLocation(0.0, 64.0, 1.0) + val pipe = FluidPipe(pipeLoc, BlockFace.NORTH) + pipe.storeFluid(FluidType.WATER) + TestHelper.addToRegistry(registry, pipe, "fluid_pipe_north_filled") + + merger.callFluidUpdate() + + assertTrue(merger.hasFluid()) + assertEquals(FluidType.WATER, merger.storedFluid) + assertFalse(pipe.hasFluid()) + } + + @Test + fun `does not pull fluid from facing direction`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = FluidMerger(mergerLoc, BlockFace.NORTH) + TestHelper.addToRegistry(registry, merger, "fluid_merger_north") + + // Pipe to the north (facing direction — should NOT pull from here) + val pipeLoc = TestHelper.createLocation(0.0, 64.0, -1.0) + val pipe = FluidPipe(pipeLoc, BlockFace.SOUTH) + pipe.storeFluid(FluidType.WATER) + TestHelper.addToRegistry(registry, pipe, "fluid_pipe_south_filled") + + merger.callFluidUpdate() + + assertFalse(merger.hasFluid()) + assertTrue(pipe.hasFluid()) + } + + @Test + fun `does not pull when already holding fluid`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = FluidMerger(mergerLoc, BlockFace.NORTH) + merger.storeFluid(FluidType.WATER) + TestHelper.addToRegistry(registry, merger, "fluid_merger_north_filled") + + val pipeLoc = TestHelper.createLocation(0.0, 64.0, 1.0) + val pipe = FluidPipe(pipeLoc, BlockFace.NORTH) + pipe.storeFluid(FluidType.LAVA) + TestHelper.addToRegistry(registry, pipe, "fluid_pipe_north_filled_lava") + + merger.callFluidUpdate() + + assertEquals(FluidType.WATER, merger.storedFluid) + assertTrue(pipe.hasFluid()) + } + + @Test + fun `pulls from multiple input directions`() { + // First pull from east + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = FluidMerger(mergerLoc, BlockFace.NORTH) + TestHelper.addToRegistry(registry, merger, "fluid_merger_north") + + val pipeLoc = TestHelper.createLocation(1.0, 64.0, 0.0) + val pipe = FluidPipe(pipeLoc, BlockFace.WEST) + pipe.storeFluid(FluidType.LAVA) + TestHelper.addToRegistry(registry, pipe, "fluid_pipe_west_filled_lava") + + merger.callFluidUpdate() + + assertTrue(merger.hasFluid()) + assertEquals(FluidType.LAVA, merger.storedFluid) + assertFalse(pipe.hasFluid()) + } + + @Test + fun `downstream pipe can pull from merger`() { + val mergerLoc = TestHelper.createLocation(0.0, 64.0, 0.0) + val merger = FluidMerger(mergerLoc, BlockFace.NORTH) + merger.storeFluid(FluidType.WATER) + TestHelper.addToRegistry(registry, merger, "fluid_merger_north_filled") + + // Merger holds fluid; downstream blocks pull via their own update + assertTrue(merger.hasFluid()) + val fluid = merger.removeFluid() + assertEquals(FluidType.WATER, fluid) + assertFalse(merger.hasFluid()) + } + + @Test + fun `descriptor has correct properties`() { + val desc = FluidMerger.descriptor + assertEquals("fluid_merger", desc.baseBlockId) + assertEquals("Fluid Merger", desc.displayName) + assertEquals(18, desc.allRegistrableIds.size) + assertTrue(desc.allRegistrableIds.contains("fluid_merger_north")) + assertTrue(desc.allRegistrableIds.contains("fluid_merger_north_filled")) + assertTrue(desc.allRegistrableIds.contains("fluid_merger_north_filled_lava")) + } +} From f81c998b8324cd81943261b4345bf843718b6d04 Mon Sep 17 00:00:00 2001 From: CoderJoe Date: Sat, 14 Mar 2026 02:41:32 -0500 Subject: [PATCH 4/4] Register new blocks and add YAML definitions and recipes Register all four new blocks in Atlas, dialogs, and test factories. Add YAML block definitions, recipes, and update test counts. --- src/main/kotlin/com/coderjoe/atlas/Atlas.kt | 8 +- .../coderjoe/atlas/fluid/FluidBlockDialog.kt | 4 + .../coderjoe/atlas/power/PowerBlockDialog.kt | 12 + .../resources/nexo/items/atlas_blocks.yml | 1734 +++++++++++++---- .../nexo/recipes/shapeless/atlas_recipes.yml | 72 + .../com/coderjoe/atlas/AtlasPluginTest.kt | 4 +- .../kotlin/com/coderjoe/atlas/TestHelper.kt | 9 +- .../atlas/fluid/FluidBlockInitializerTest.kt | 4 +- .../atlas/power/PowerBlockInitializerTest.kt | 4 +- 9 files changed, 1511 insertions(+), 340 deletions(-) diff --git a/src/main/kotlin/com/coderjoe/atlas/Atlas.kt b/src/main/kotlin/com/coderjoe/atlas/Atlas.kt index 50507be..27e83ee 100644 --- a/src/main/kotlin/com/coderjoe/atlas/Atlas.kt +++ b/src/main/kotlin/com/coderjoe/atlas/Atlas.kt @@ -181,7 +181,10 @@ class Atlas : JavaPlugin() { com.coderjoe.atlas.power.block.PowerCable.descriptor, com.coderjoe.atlas.power.block.LavaGenerator.descriptor, com.coderjoe.atlas.power.block.AutoSmelter.descriptor, - com.coderjoe.atlas.power.block.MultiPowerCable.descriptor + com.coderjoe.atlas.power.block.MultiPowerCable.descriptor, + com.coderjoe.atlas.power.block.CobblestoneGenerator.descriptor, + com.coderjoe.atlas.power.block.ObsidianGenerator.descriptor, + com.coderjoe.atlas.power.block.PowerMerger.descriptor ).associateBy { it.baseBlockId } } @@ -189,7 +192,8 @@ class Atlas : JavaPlugin() { return listOf( com.coderjoe.atlas.fluid.block.FluidPump.descriptor, com.coderjoe.atlas.fluid.block.FluidPipe.descriptor, - com.coderjoe.atlas.fluid.block.FluidContainer.descriptor + com.coderjoe.atlas.fluid.block.FluidContainer.descriptor, + com.coderjoe.atlas.fluid.block.FluidMerger.descriptor ).associateBy { it.baseBlockId } } } diff --git a/src/main/kotlin/com/coderjoe/atlas/fluid/FluidBlockDialog.kt b/src/main/kotlin/com/coderjoe/atlas/fluid/FluidBlockDialog.kt index 75b5eb1..d7c6c13 100644 --- a/src/main/kotlin/com/coderjoe/atlas/fluid/FluidBlockDialog.kt +++ b/src/main/kotlin/com/coderjoe/atlas/fluid/FluidBlockDialog.kt @@ -4,6 +4,7 @@ import com.coderjoe.atlas.core.AtlasBlockDialog import com.coderjoe.atlas.core.BlockRegistry import com.coderjoe.atlas.fluid.block.FluidContainer import com.coderjoe.atlas.fluid.block.FluidPipe +import com.coderjoe.atlas.fluid.block.FluidMerger import com.coderjoe.atlas.fluid.block.FluidPump import io.papermc.paper.dialog.Dialog import io.papermc.paper.registry.data.dialog.ActionButton @@ -71,6 +72,7 @@ object FluidBlockDialog { is FluidPump -> "Fluid Pump" is FluidPipe -> "Fluid Pipe (${fluidBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" is FluidContainer -> "Fluid Container (${fluidBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" + is FluidMerger -> "Fluid Merger (${fluidBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" else -> "Fluid Block" } @@ -107,6 +109,8 @@ object FluidBlockDialog { .color(NamedTextColor.GRAY) is FluidContainer -> Component.text("Container - stores up to ${FluidContainer.MAX_CAPACITY} units of fluid") .color(NamedTextColor.GRAY) + is FluidMerger -> Component.text("Merger - merges fluid from all sides, outputs in facing direction") + .color(NamedTextColor.GRAY) else -> Component.text("Fluid block") .color(NamedTextColor.GRAY) } diff --git a/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt b/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt index 5459e8b..6c88a3f 100644 --- a/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt +++ b/src/main/kotlin/com/coderjoe/atlas/power/PowerBlockDialog.kt @@ -8,6 +8,9 @@ import com.coderjoe.atlas.power.block.PowerCable import com.coderjoe.atlas.power.block.SmallBattery import com.coderjoe.atlas.power.block.SmallDrill import com.coderjoe.atlas.power.block.MultiPowerCable +import com.coderjoe.atlas.power.block.CobblestoneGenerator +import com.coderjoe.atlas.power.block.ObsidianGenerator +import com.coderjoe.atlas.power.block.PowerMerger import com.coderjoe.atlas.power.block.SmallSolarPanel import io.papermc.paper.dialog.Dialog import io.papermc.paper.registry.data.dialog.ActionButton @@ -129,6 +132,9 @@ object PowerBlockDialog { is LavaGenerator -> "Lava Generator" is AutoSmelter -> "Auto Smelter (${powerBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" is MultiPowerCable -> "Multi Power Cable (${powerBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" + is CobblestoneGenerator -> "Cobblestone Generator" + is ObsidianGenerator -> "Obsidian Generator" + is PowerMerger -> "Power Merger (${powerBlock.facing.name.lowercase().replaceFirstChar { it.uppercase() }})" else -> "Power Block" } @@ -177,6 +183,12 @@ object PowerBlockDialog { .color(NamedTextColor.GRAY) is MultiPowerCable -> Component.text("Cable - distributes power to all adjacent faces") .color(NamedTextColor.GRAY) + is CobblestoneGenerator -> Component.text("Machine - consumes ${CobblestoneGenerator.POWER_COST} power + water + lava → cobblestone") + .color(NamedTextColor.GRAY) + is ObsidianGenerator -> Component.text("Machine - consumes ${ObsidianGenerator.POWER_COST} power + water + lava → obsidian") + .color(NamedTextColor.GRAY) + is PowerMerger -> Component.text("Cable - merges power from all sides, outputs in facing direction") + .color(NamedTextColor.GRAY) else -> Component.text("Power block") .color(NamedTextColor.GRAY) } diff --git a/src/main/resources/nexo/items/atlas_blocks.yml b/src/main/resources/nexo/items/atlas_blocks.yml index 78cd2bf..f4cabe7 100644 --- a/src/main/resources/nexo/items/atlas_blocks.yml +++ b/src/main/resources/nexo/items/atlas_blocks.yml @@ -2649,6 +2649,572 @@ fluid_container_down_lava_full: - nexo_item: fluid_container probability: 1.0 +# ─── Fluid Merger ──────────────────────────────────────────────── +fluid_merger: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube_all + textures: + all: atlas:block/fluid_merger_side + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 184 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_north: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_front + south: atlas:block/fluid_merger_back + east: atlas:block/fluid_merger_side + west: atlas:block/fluid_merger_side + up: atlas:block/fluid_merger_top + down: atlas:block/fluid_merger_bottom + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 185 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_south: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_back + south: atlas:block/fluid_merger_front + east: atlas:block/fluid_merger_side + west: atlas:block/fluid_merger_side + up: atlas:block/fluid_merger_top + down: atlas:block/fluid_merger_bottom + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 186 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_east: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side + south: atlas:block/fluid_merger_side + east: atlas:block/fluid_merger_front + west: atlas:block/fluid_merger_back + up: atlas:block/fluid_merger_top + down: atlas:block/fluid_merger_bottom + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 187 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_west: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side + south: atlas:block/fluid_merger_side + east: atlas:block/fluid_merger_back + west: atlas:block/fluid_merger_front + up: atlas:block/fluid_merger_top + down: atlas:block/fluid_merger_bottom + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 188 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_up: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side + south: atlas:block/fluid_merger_side + east: atlas:block/fluid_merger_side + west: atlas:block/fluid_merger_side + up: atlas:block/fluid_merger_front + down: atlas:block/fluid_merger_back + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 189 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_down: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side + south: atlas:block/fluid_merger_side + east: atlas:block/fluid_merger_side + west: atlas:block/fluid_merger_side + up: atlas:block/fluid_merger_back + down: atlas:block/fluid_merger_front + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 190 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_north_filled: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_front_water + south: atlas:block/fluid_merger_back_water + east: atlas:block/fluid_merger_side_water + west: atlas:block/fluid_merger_side_water + up: atlas:block/fluid_merger_top_water + down: atlas:block/fluid_merger_bottom_water + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 191 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_south_filled: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_back_water + south: atlas:block/fluid_merger_front_water + east: atlas:block/fluid_merger_side_water + west: atlas:block/fluid_merger_side_water + up: atlas:block/fluid_merger_top_water + down: atlas:block/fluid_merger_bottom_water + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 192 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_east_filled: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_water + south: atlas:block/fluid_merger_side_water + east: atlas:block/fluid_merger_front_water + west: atlas:block/fluid_merger_back_water + up: atlas:block/fluid_merger_top_water + down: atlas:block/fluid_merger_bottom_water + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 193 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_west_filled: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_water + south: atlas:block/fluid_merger_side_water + east: atlas:block/fluid_merger_back_water + west: atlas:block/fluid_merger_front_water + up: atlas:block/fluid_merger_top_water + down: atlas:block/fluid_merger_bottom_water + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 194 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_up_filled: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_water + south: atlas:block/fluid_merger_side_water + east: atlas:block/fluid_merger_side_water + west: atlas:block/fluid_merger_side_water + up: atlas:block/fluid_merger_front_water + down: atlas:block/fluid_merger_back_water + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 195 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_down_filled: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_water + south: atlas:block/fluid_merger_side_water + east: atlas:block/fluid_merger_side_water + west: atlas:block/fluid_merger_side_water + up: atlas:block/fluid_merger_back_water + down: atlas:block/fluid_merger_front_water + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 196 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_north_filled_lava: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_front_lava + south: atlas:block/fluid_merger_back_lava + east: atlas:block/fluid_merger_side_lava + west: atlas:block/fluid_merger_side_lava + up: atlas:block/fluid_merger_top_lava + down: atlas:block/fluid_merger_bottom_lava + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 197 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_south_filled_lava: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_back_lava + south: atlas:block/fluid_merger_front_lava + east: atlas:block/fluid_merger_side_lava + west: atlas:block/fluid_merger_side_lava + up: atlas:block/fluid_merger_top_lava + down: atlas:block/fluid_merger_bottom_lava + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 198 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_east_filled_lava: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_lava + south: atlas:block/fluid_merger_side_lava + east: atlas:block/fluid_merger_front_lava + west: atlas:block/fluid_merger_back_lava + up: atlas:block/fluid_merger_top_lava + down: atlas:block/fluid_merger_bottom_lava + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 199 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_west_filled_lava: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_lava + south: atlas:block/fluid_merger_side_lava + east: atlas:block/fluid_merger_back_lava + west: atlas:block/fluid_merger_front_lava + up: atlas:block/fluid_merger_top_lava + down: atlas:block/fluid_merger_bottom_lava + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 200 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_up_filled_lava: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_lava + south: atlas:block/fluid_merger_side_lava + east: atlas:block/fluid_merger_side_lava + west: atlas:block/fluid_merger_side_lava + up: atlas:block/fluid_merger_front_lava + down: atlas:block/fluid_merger_back_lava + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 201 + hardness: 2 + 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: fluid_merger + probability: 1.0 + +fluid_merger_down_filled_lava: + itemname: "Fluid Merger" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/fluid_merger_side_lava + south: atlas:block/fluid_merger_side_lava + east: atlas:block/fluid_merger_side_lava + west: atlas:block/fluid_merger_side_lava + up: atlas:block/fluid_merger_back_lava + down: atlas:block/fluid_merger_front_lava + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 202 + hardness: 2 + 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: fluid_merger + probability: 1.0 + # ─── Lava Generator ─────────────────────────────────────────────── lava_generator: itemname: "Lava Generator" @@ -2657,17 +3223,523 @@ lava_generator: generate_model: true parent_model: block/cube textures: - north: atlas:block/lava_generator_side - south: atlas:block/lava_generator_side - east: atlas:block/lava_generator_side - west: atlas:block/lava_generator_side - up: atlas:block/lava_generator_top - down: atlas:block/lava_generator_bottom + north: atlas:block/lava_generator_side + south: atlas:block/lava_generator_side + east: atlas:block/lava_generator_side + west: atlas:block/lava_generator_side + up: atlas:block/lava_generator_top + down: atlas:block/lava_generator_bottom + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 152 + hardness: 5 + 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: lava_generator + probability: 1.0 + +lava_generator_active: + itemname: "Lava Generator" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/lava_generator_side_active + south: atlas:block/lava_generator_side_active + east: atlas:block/lava_generator_side_active + west: atlas:block/lava_generator_side_active + up: atlas:block/lava_generator_top_active + down: atlas:block/lava_generator_bottom + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 153 + hardness: 5 + 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: lava_generator + probability: 1.0 + +# ─── Conveyor Belt ──────────────────────────────────────────────── +conveyor_belt: + itemname: "Conveyor Belt" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/conveyor_belt + textures: + north: atlas:block/conveyor_belt_front + south: atlas:block/conveyor_belt_back + east: atlas:block/conveyor_belt_side + west: atlas:block/conveyor_belt_side + up: atlas:block/conveyor_belt_top_north + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 44 + 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: conveyor_belt + probability: 1.0 + +conveyor_belt_north: + itemname: "Conveyor Belt" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/conveyor_belt + textures: + north: atlas:block/conveyor_belt_front + south: atlas:block/conveyor_belt_back + east: atlas:block/conveyor_belt_side + west: atlas:block/conveyor_belt_side + up: atlas:block/conveyor_belt_top_north + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 45 + 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: conveyor_belt + probability: 1.0 + +conveyor_belt_south: + itemname: "Conveyor Belt" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/conveyor_belt + textures: + north: atlas:block/conveyor_belt_back + south: atlas:block/conveyor_belt_front + east: atlas:block/conveyor_belt_side + west: atlas:block/conveyor_belt_side + up: atlas:block/conveyor_belt_top_south + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 46 + 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: conveyor_belt + probability: 1.0 + +conveyor_belt_east: + itemname: "Conveyor Belt" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/conveyor_belt + textures: + north: atlas:block/conveyor_belt_side + south: atlas:block/conveyor_belt_side + east: atlas:block/conveyor_belt_front + west: atlas:block/conveyor_belt_back + up: atlas:block/conveyor_belt_top_east + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 47 + 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: conveyor_belt + probability: 1.0 + +conveyor_belt_west: + itemname: "Conveyor Belt" + material: paper + Pack: + generate_model: true + parent_model: atlas:block/conveyor_belt + textures: + north: atlas:block/conveyor_belt_side + south: atlas:block/conveyor_belt_side + east: atlas:block/conveyor_belt_back + west: atlas:block/conveyor_belt_front + up: atlas:block/conveyor_belt_top_west + down: atlas:block/conveyor_belt_bottom + Mechanics: + custom_block: + type: CHORUSBLOCK + custom_variation: 48 + 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: 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 + +multi_power_cable: + itemname: "Multi Power Cable" + material: paper + Pack: + generate_model: true + parent_model: block/cube_all + textures: + all: atlas:block/multi_power_cable_side + Mechanics: + custom_block: + type: NOTEBLOCK + custom_variation: 154 + hardness: 2 + 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: multi_power_cable + probability: 1.0 + +multi_power_cable_north: + itemname: "Multi Power Cable" + material: paper + Pack: + generate_model: true + parent_model: block/cube + textures: + north: atlas:block/multi_power_cable_front + south: atlas:block/multi_power_cable_back + east: atlas:block/multi_power_cable_side + west: atlas:block/multi_power_cable_side + up: atlas:block/multi_power_cable_cap + down: atlas:block/multi_power_cable_cap Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 152 - hardness: 5 + custom_variation: 155 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2677,27 +3749,27 @@ lava_generator: drop: silktouch: false loots: - - nexo_item: lava_generator + - nexo_item: multi_power_cable probability: 1.0 -lava_generator_active: - itemname: "Lava Generator" +multi_power_cable_south: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/lava_generator_side_active - south: atlas:block/lava_generator_side_active - east: atlas:block/lava_generator_side_active - west: atlas:block/lava_generator_side_active - up: atlas:block/lava_generator_top_active - down: atlas:block/lava_generator_bottom + north: atlas:block/multi_power_cable_back + south: atlas:block/multi_power_cable_front + east: atlas:block/multi_power_cable_side + west: atlas:block/multi_power_cable_side + up: atlas:block/multi_power_cable_cap + down: atlas:block/multi_power_cable_cap Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 153 - hardness: 5 + custom_variation: 156 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2707,28 +3779,27 @@ lava_generator_active: drop: silktouch: false loots: - - nexo_item: lava_generator + - nexo_item: multi_power_cable probability: 1.0 -# ─── Conveyor Belt ──────────────────────────────────────────────── -conveyor_belt: - itemname: "Conveyor Belt" +multi_power_cable_east: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/conveyor_belt + parent_model: block/cube textures: - north: atlas:block/conveyor_belt_front - south: atlas:block/conveyor_belt_back - east: atlas:block/conveyor_belt_side - west: atlas:block/conveyor_belt_side - up: atlas:block/conveyor_belt_top_north - down: atlas:block/conveyor_belt_bottom + north: atlas:block/multi_power_cable_side + south: atlas:block/multi_power_cable_side + east: atlas:block/multi_power_cable_front + west: atlas:block/multi_power_cable_back + up: atlas:block/multi_power_cable_cap + down: atlas:block/multi_power_cable_cap Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 44 - hardness: 3 + type: NOTEBLOCK + custom_variation: 157 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2738,27 +3809,27 @@ conveyor_belt: drop: silktouch: false loots: - - nexo_item: conveyor_belt + - nexo_item: multi_power_cable probability: 1.0 -conveyor_belt_north: - itemname: "Conveyor Belt" +multi_power_cable_west: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/conveyor_belt + parent_model: block/cube textures: - north: atlas:block/conveyor_belt_front - south: atlas:block/conveyor_belt_back - east: atlas:block/conveyor_belt_side - west: atlas:block/conveyor_belt_side - up: atlas:block/conveyor_belt_top_north - down: atlas:block/conveyor_belt_bottom + north: atlas:block/multi_power_cable_side + south: atlas:block/multi_power_cable_side + east: atlas:block/multi_power_cable_back + west: atlas:block/multi_power_cable_front + up: atlas:block/multi_power_cable_cap + down: atlas:block/multi_power_cable_cap Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 45 - hardness: 3 + type: NOTEBLOCK + custom_variation: 158 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2768,27 +3839,27 @@ conveyor_belt_north: drop: silktouch: false loots: - - nexo_item: conveyor_belt + - nexo_item: multi_power_cable probability: 1.0 -conveyor_belt_south: - itemname: "Conveyor Belt" +multi_power_cable_up: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/conveyor_belt + parent_model: block/cube textures: - north: atlas:block/conveyor_belt_back - south: atlas:block/conveyor_belt_front - east: atlas:block/conveyor_belt_side - west: atlas:block/conveyor_belt_side - up: atlas:block/conveyor_belt_top_south - down: atlas:block/conveyor_belt_bottom + north: atlas:block/multi_power_cable_side + south: atlas:block/multi_power_cable_side + east: atlas:block/multi_power_cable_side + west: atlas:block/multi_power_cable_side + up: atlas:block/multi_power_cable_front + down: atlas:block/multi_power_cable_back Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 46 - hardness: 3 + type: NOTEBLOCK + custom_variation: 159 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2798,27 +3869,27 @@ conveyor_belt_south: drop: silktouch: false loots: - - nexo_item: conveyor_belt + - nexo_item: multi_power_cable probability: 1.0 -conveyor_belt_east: - itemname: "Conveyor Belt" +multi_power_cable_down: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/conveyor_belt + parent_model: block/cube textures: - north: atlas:block/conveyor_belt_side - south: atlas:block/conveyor_belt_side - east: atlas:block/conveyor_belt_front - west: atlas:block/conveyor_belt_back - up: atlas:block/conveyor_belt_top_east - down: atlas:block/conveyor_belt_bottom + north: atlas:block/multi_power_cable_side + south: atlas:block/multi_power_cable_side + east: atlas:block/multi_power_cable_side + west: atlas:block/multi_power_cable_side + up: atlas:block/multi_power_cable_back + down: atlas:block/multi_power_cable_front Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 47 - hardness: 3 + type: NOTEBLOCK + custom_variation: 160 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2828,27 +3899,27 @@ conveyor_belt_east: drop: silktouch: false loots: - - nexo_item: conveyor_belt + - nexo_item: multi_power_cable probability: 1.0 -conveyor_belt_west: - itemname: "Conveyor Belt" +multi_power_cable_north_powered: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/conveyor_belt + parent_model: block/cube textures: - north: atlas:block/conveyor_belt_side - south: atlas:block/conveyor_belt_side - east: atlas:block/conveyor_belt_back - west: atlas:block/conveyor_belt_front - up: atlas:block/conveyor_belt_top_west - down: atlas:block/conveyor_belt_bottom + north: atlas:block/multi_power_cable_front_powered + south: atlas:block/multi_power_cable_back_powered + east: atlas:block/multi_power_cable_side_powered + west: atlas:block/multi_power_cable_side_powered + up: atlas:block/multi_power_cable_cap_powered + down: atlas:block/multi_power_cable_cap_powered Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 48 - hardness: 3 + type: NOTEBLOCK + custom_variation: 161 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2858,27 +3929,27 @@ conveyor_belt_west: drop: silktouch: false loots: - - nexo_item: conveyor_belt + - nexo_item: multi_power_cable probability: 1.0 -auto_smelter: - itemname: "Auto Smelter" +multi_power_cable_south_powered: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ns + parent_model: block/cube 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 + north: atlas:block/multi_power_cable_back_powered + south: atlas:block/multi_power_cable_front_powered + east: atlas:block/multi_power_cable_side_powered + west: atlas:block/multi_power_cable_side_powered + up: atlas:block/multi_power_cable_cap_powered + down: atlas:block/multi_power_cable_cap_powered Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 49 - hardness: 3 + type: NOTEBLOCK + custom_variation: 162 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2888,27 +3959,27 @@ auto_smelter: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: multi_power_cable probability: 1.0 -auto_smelter_north: - itemname: "Auto Smelter" +multi_power_cable_east_powered: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ns + parent_model: block/cube 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 + north: atlas:block/multi_power_cable_side_powered + south: atlas:block/multi_power_cable_side_powered + east: atlas:block/multi_power_cable_front_powered + west: atlas:block/multi_power_cable_back_powered + up: atlas:block/multi_power_cable_cap_powered + down: atlas:block/multi_power_cable_cap_powered Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 50 - hardness: 3 + type: NOTEBLOCK + custom_variation: 163 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2918,27 +3989,27 @@ auto_smelter_north: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: multi_power_cable probability: 1.0 -auto_smelter_south: - itemname: "Auto Smelter" +multi_power_cable_west_powered: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ns + parent_model: block/cube 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 + north: atlas:block/multi_power_cable_side_powered + south: atlas:block/multi_power_cable_side_powered + east: atlas:block/multi_power_cable_back_powered + west: atlas:block/multi_power_cable_front_powered + up: atlas:block/multi_power_cable_cap_powered + down: atlas:block/multi_power_cable_cap_powered Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 51 - hardness: 3 + type: NOTEBLOCK + custom_variation: 164 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -2948,57 +4019,57 @@ auto_smelter_south: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: multi_power_cable probability: 1.0 -auto_smelter_east: - itemname: "Auto Smelter" +multi_power_cable_up_powered: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ew + parent_model: block/cube 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 + north: atlas:block/multi_power_cable_side_powered + south: atlas:block/multi_power_cable_side_powered + east: atlas:block/multi_power_cable_side_powered + west: atlas:block/multi_power_cable_side_powered + up: atlas:block/multi_power_cable_front_powered + down: atlas:block/multi_power_cable_back_powered Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 52 - hardness: 3 + type: NOTEBLOCK + custom_variation: 165 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place hit_sound: block.metal.hit - step_sound: block.metal.step + step_sound: block.metal.hit fall_sound: block.metal.fall drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: multi_power_cable probability: 1.0 -auto_smelter_west: - itemname: "Auto Smelter" +multi_power_cable_down_powered: + itemname: "Multi Power Cable" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ew + parent_model: block/cube 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 + north: atlas:block/multi_power_cable_side_powered + south: atlas:block/multi_power_cable_side_powered + east: atlas:block/multi_power_cable_side_powered + west: atlas:block/multi_power_cable_side_powered + up: atlas:block/multi_power_cable_back_powered + down: atlas:block/multi_power_cable_front_powered Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 53 - hardness: 3 + type: NOTEBLOCK + custom_variation: 166 + hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -3008,27 +4079,28 @@ auto_smelter_west: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: multi_power_cable probability: 1.0 -auto_smelter_north_on: - itemname: "Auto Smelter" +# ─── Cobblestone Generator ────────────────────────────────────── +cobblestone_generator: + itemname: "Cobblestone Generator" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ns_on + parent_model: block/cube 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 + north: atlas:block/cobblestone_generator_side + south: atlas:block/cobblestone_generator_side + east: atlas:block/cobblestone_generator_side + west: atlas:block/cobblestone_generator_side + up: atlas:block/cobblestone_generator_top + down: atlas:block/cobblestone_generator_bottom Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 54 - hardness: 3 + type: NOTEBLOCK + custom_variation: 167 + hardness: 5 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -3038,27 +4110,27 @@ auto_smelter_north_on: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: cobblestone_generator probability: 1.0 -auto_smelter_south_on: - itemname: "Auto Smelter" +cobblestone_generator_active: + itemname: "Cobblestone Generator" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ns_on + parent_model: block/cube 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 + north: atlas:block/cobblestone_generator_side_active + south: atlas:block/cobblestone_generator_side_active + east: atlas:block/cobblestone_generator_side_active + west: atlas:block/cobblestone_generator_side_active + up: atlas:block/cobblestone_generator_top_active + down: atlas:block/cobblestone_generator_bottom Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 55 - hardness: 3 + type: NOTEBLOCK + custom_variation: 168 + hardness: 5 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -3068,27 +4140,28 @@ auto_smelter_south_on: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: cobblestone_generator probability: 1.0 -auto_smelter_east_on: - itemname: "Auto Smelter" +# ─── Obsidian Generator ───────────────────────────────────────── +obsidian_generator: + itemname: "Obsidian Generator" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ew_on + parent_model: block/cube 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 + north: atlas:block/obsidian_generator_side + south: atlas:block/obsidian_generator_side + east: atlas:block/obsidian_generator_side + west: atlas:block/obsidian_generator_side + up: atlas:block/obsidian_generator_top + down: atlas:block/obsidian_generator_bottom Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 56 - hardness: 3 + type: NOTEBLOCK + custom_variation: 169 + hardness: 5 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -3098,27 +4171,27 @@ auto_smelter_east_on: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: obsidian_generator probability: 1.0 -auto_smelter_west_on: - itemname: "Auto Smelter" +obsidian_generator_active: + itemname: "Obsidian Generator" material: paper Pack: generate_model: true - parent_model: atlas:block/auto_smelter_ew_on + parent_model: block/cube 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 + north: atlas:block/obsidian_generator_side_active + south: atlas:block/obsidian_generator_side_active + east: atlas:block/obsidian_generator_side_active + west: atlas:block/obsidian_generator_side_active + up: atlas:block/obsidian_generator_top_active + down: atlas:block/obsidian_generator_bottom Mechanics: custom_block: - type: CHORUSBLOCK - custom_variation: 57 - hardness: 3 + type: NOTEBLOCK + custom_variation: 170 + hardness: 5 block_sounds: break_sound: block.metal.break place_sound: block.metal.place @@ -3128,21 +4201,22 @@ auto_smelter_west_on: drop: silktouch: false loots: - - nexo_item: auto_smelter + - nexo_item: obsidian_generator probability: 1.0 -multi_power_cable: - itemname: "Multi Power Cable" +# ─── Power Merger ──────────────────────────────────────────────── +power_merger: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube_all textures: - all: atlas:block/multi_power_cable_side + all: atlas:block/power_merger_side Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 154 + custom_variation: 171 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3153,26 +4227,26 @@ multi_power_cable: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_north: - itemname: "Multi Power Cable" +power_merger_north: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_front - south: atlas:block/multi_power_cable_back - east: atlas:block/multi_power_cable_side - west: atlas:block/multi_power_cable_side - up: atlas:block/multi_power_cable_cap - down: atlas:block/multi_power_cable_cap + north: atlas:block/power_merger_front + south: atlas:block/power_merger_back + east: atlas:block/power_merger_side + west: atlas:block/power_merger_side + up: atlas:block/power_merger_top + down: atlas:block/power_merger_bottom Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 155 + custom_variation: 172 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3183,26 +4257,26 @@ multi_power_cable_north: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_south: - itemname: "Multi Power Cable" +power_merger_south: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_back - south: atlas:block/multi_power_cable_front - east: atlas:block/multi_power_cable_side - west: atlas:block/multi_power_cable_side - up: atlas:block/multi_power_cable_cap - down: atlas:block/multi_power_cable_cap + north: atlas:block/power_merger_back + south: atlas:block/power_merger_front + east: atlas:block/power_merger_side + west: atlas:block/power_merger_side + up: atlas:block/power_merger_top + down: atlas:block/power_merger_bottom Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 156 + custom_variation: 173 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3213,26 +4287,26 @@ multi_power_cable_south: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_east: - itemname: "Multi Power Cable" +power_merger_east: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side - south: atlas:block/multi_power_cable_side - east: atlas:block/multi_power_cable_front - west: atlas:block/multi_power_cable_back - up: atlas:block/multi_power_cable_cap - down: atlas:block/multi_power_cable_cap + north: atlas:block/power_merger_side + south: atlas:block/power_merger_side + east: atlas:block/power_merger_front + west: atlas:block/power_merger_back + up: atlas:block/power_merger_top + down: atlas:block/power_merger_bottom Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 157 + custom_variation: 174 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3243,26 +4317,26 @@ multi_power_cable_east: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_west: - itemname: "Multi Power Cable" +power_merger_west: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side - south: atlas:block/multi_power_cable_side - east: atlas:block/multi_power_cable_back - west: atlas:block/multi_power_cable_front - up: atlas:block/multi_power_cable_cap - down: atlas:block/multi_power_cable_cap + north: atlas:block/power_merger_side + south: atlas:block/power_merger_side + east: atlas:block/power_merger_back + west: atlas:block/power_merger_front + up: atlas:block/power_merger_top + down: atlas:block/power_merger_bottom Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 158 + custom_variation: 175 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3273,26 +4347,26 @@ multi_power_cable_west: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_up: - itemname: "Multi Power Cable" +power_merger_up: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side - south: atlas:block/multi_power_cable_side - east: atlas:block/multi_power_cable_side - west: atlas:block/multi_power_cable_side - up: atlas:block/multi_power_cable_front - down: atlas:block/multi_power_cable_back + north: atlas:block/power_merger_side + south: atlas:block/power_merger_side + east: atlas:block/power_merger_side + west: atlas:block/power_merger_side + up: atlas:block/power_merger_front + down: atlas:block/power_merger_back Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 159 + custom_variation: 176 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3303,26 +4377,26 @@ multi_power_cable_up: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_down: - itemname: "Multi Power Cable" +power_merger_down: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side - south: atlas:block/multi_power_cable_side - east: atlas:block/multi_power_cable_side - west: atlas:block/multi_power_cable_side - up: atlas:block/multi_power_cable_back - down: atlas:block/multi_power_cable_front + north: atlas:block/power_merger_side + south: atlas:block/power_merger_side + east: atlas:block/power_merger_side + west: atlas:block/power_merger_side + up: atlas:block/power_merger_back + down: atlas:block/power_merger_front Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 160 + custom_variation: 177 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3333,26 +4407,26 @@ multi_power_cable_down: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_north_powered: - itemname: "Multi Power Cable" +power_merger_north_powered: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_front_powered - south: atlas:block/multi_power_cable_back_powered - east: atlas:block/multi_power_cable_side_powered - west: atlas:block/multi_power_cable_side_powered - up: atlas:block/multi_power_cable_cap_powered - down: atlas:block/multi_power_cable_cap_powered + north: atlas:block/power_merger_front_powered + south: atlas:block/power_merger_back_powered + east: atlas:block/power_merger_side_powered + west: atlas:block/power_merger_side_powered + up: atlas:block/power_merger_top_powered + down: atlas:block/power_merger_bottom_powered Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 161 + custom_variation: 178 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3363,26 +4437,26 @@ multi_power_cable_north_powered: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_south_powered: - itemname: "Multi Power Cable" +power_merger_south_powered: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_back_powered - south: atlas:block/multi_power_cable_front_powered - east: atlas:block/multi_power_cable_side_powered - west: atlas:block/multi_power_cable_side_powered - up: atlas:block/multi_power_cable_cap_powered - down: atlas:block/multi_power_cable_cap_powered + north: atlas:block/power_merger_back_powered + south: atlas:block/power_merger_front_powered + east: atlas:block/power_merger_side_powered + west: atlas:block/power_merger_side_powered + up: atlas:block/power_merger_top_powered + down: atlas:block/power_merger_bottom_powered Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 162 + custom_variation: 179 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3393,26 +4467,26 @@ multi_power_cable_south_powered: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_east_powered: - itemname: "Multi Power Cable" +power_merger_east_powered: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side_powered - south: atlas:block/multi_power_cable_side_powered - east: atlas:block/multi_power_cable_front_powered - west: atlas:block/multi_power_cable_back_powered - up: atlas:block/multi_power_cable_cap_powered - down: atlas:block/multi_power_cable_cap_powered + north: atlas:block/power_merger_side_powered + south: atlas:block/power_merger_side_powered + east: atlas:block/power_merger_front_powered + west: atlas:block/power_merger_back_powered + up: atlas:block/power_merger_top_powered + down: atlas:block/power_merger_bottom_powered Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 163 + custom_variation: 180 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3423,26 +4497,26 @@ multi_power_cable_east_powered: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_west_powered: - itemname: "Multi Power Cable" +power_merger_west_powered: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side_powered - south: atlas:block/multi_power_cable_side_powered - east: atlas:block/multi_power_cable_back_powered - west: atlas:block/multi_power_cable_front_powered - up: atlas:block/multi_power_cable_cap_powered - down: atlas:block/multi_power_cable_cap_powered + north: atlas:block/power_merger_side_powered + south: atlas:block/power_merger_side_powered + east: atlas:block/power_merger_back_powered + west: atlas:block/power_merger_front_powered + up: atlas:block/power_merger_top_powered + down: atlas:block/power_merger_bottom_powered Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 164 + custom_variation: 181 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3453,56 +4527,56 @@ multi_power_cable_west_powered: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_up_powered: - itemname: "Multi Power Cable" +power_merger_up_powered: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side_powered - south: atlas:block/multi_power_cable_side_powered - east: atlas:block/multi_power_cable_side_powered - west: atlas:block/multi_power_cable_side_powered - up: atlas:block/multi_power_cable_front_powered - down: atlas:block/multi_power_cable_back_powered + north: atlas:block/power_merger_side_powered + south: atlas:block/power_merger_side_powered + east: atlas:block/power_merger_side_powered + west: atlas:block/power_merger_side_powered + up: atlas:block/power_merger_front_powered + down: atlas:block/power_merger_back_powered Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 165 + custom_variation: 182 hardness: 2 block_sounds: break_sound: block.metal.break place_sound: block.metal.place hit_sound: block.metal.hit - step_sound: block.metal.hit + step_sound: block.metal.step fall_sound: block.metal.fall drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 -multi_power_cable_down_powered: - itemname: "Multi Power Cable" +power_merger_down_powered: + itemname: "Power Merger" material: paper Pack: generate_model: true parent_model: block/cube textures: - north: atlas:block/multi_power_cable_side_powered - south: atlas:block/multi_power_cable_side_powered - east: atlas:block/multi_power_cable_side_powered - west: atlas:block/multi_power_cable_side_powered - up: atlas:block/multi_power_cable_back_powered - down: atlas:block/multi_power_cable_front_powered + north: atlas:block/power_merger_side_powered + south: atlas:block/power_merger_side_powered + east: atlas:block/power_merger_side_powered + west: atlas:block/power_merger_side_powered + up: atlas:block/power_merger_back_powered + down: atlas:block/power_merger_front_powered Mechanics: custom_block: type: NOTEBLOCK - custom_variation: 166 + custom_variation: 183 hardness: 2 block_sounds: break_sound: block.metal.break @@ -3513,5 +4587,5 @@ multi_power_cable_down_powered: drop: silktouch: false loots: - - nexo_item: multi_power_cable + - nexo_item: power_merger probability: 1.0 diff --git a/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml b/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml index c4c2763..30c82c0 100644 --- a/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml +++ b/src/main/resources/nexo/recipes/shapeless/atlas_recipes.yml @@ -195,3 +195,75 @@ auto_smelter_recipe: minecraft_type: REDSTONE G: minecraft_type: FURNACE + +cobblestone_generator_recipe: + result: + nexo_item: cobblestone_generator + amount: 1 + ingredients: + A: + minecraft_type: IRON_INGOT + B: + minecraft_type: IRON_INGOT + C: + minecraft_type: IRON_INGOT + D: + minecraft_type: REDSTONE + E: + minecraft_type: REDSTONE + F: + minecraft_type: REDSTONE + G: + minecraft_type: COBBLESTONE + +fluid_merger_recipe: + result: + nexo_item: fluid_merger + amount: 1 + ingredients: + A: + minecraft_type: IRON_INGOT + B: + minecraft_type: IRON_INGOT + C: + minecraft_type: IRON_INGOT + D: + minecraft_type: IRON_INGOT + E: + minecraft_type: BUCKET + +power_merger_recipe: + result: + nexo_item: power_merger + amount: 1 + ingredients: + A: + minecraft_type: COPPER_INGOT + B: + minecraft_type: COPPER_INGOT + C: + minecraft_type: COPPER_INGOT + D: + minecraft_type: COPPER_INGOT + E: + minecraft_type: REDSTONE + +obsidian_generator_recipe: + result: + nexo_item: obsidian_generator + amount: 1 + ingredients: + A: + minecraft_type: IRON_INGOT + B: + minecraft_type: IRON_INGOT + C: + minecraft_type: IRON_INGOT + D: + minecraft_type: REDSTONE + E: + minecraft_type: REDSTONE + F: + minecraft_type: REDSTONE + G: + minecraft_type: OBSIDIAN diff --git a/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt b/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt index c0c656a..37b989b 100644 --- a/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt +++ b/src/test/kotlin/com/coderjoe/atlas/AtlasPluginTest.kt @@ -30,13 +30,13 @@ class AtlasPluginTest { @Test fun `power system initializes with 27 block types`() { TestHelper.initPowerFactory() - assertEquals(39, PowerBlockFactory.getRegisteredBlockIds().size) + assertEquals(55, PowerBlockFactory.getRegisteredBlockIds().size) } @Test fun `fluid system initializes with 63 block types`() { TestHelper.initFluidFactory() - assertEquals(63, FluidBlockFactory.getRegisteredBlockIds().size) + assertEquals(81, FluidBlockFactory.getRegisteredBlockIds().size) } @Test diff --git a/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt b/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt index de4fddd..2e33f55 100644 --- a/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt +++ b/src/test/kotlin/com/coderjoe/atlas/TestHelper.kt @@ -7,6 +7,7 @@ import com.coderjoe.atlas.fluid.FluidBlockFactory import com.coderjoe.atlas.fluid.FluidBlockRegistry import com.coderjoe.atlas.fluid.block.FluidContainer import com.coderjoe.atlas.fluid.block.FluidPipe +import com.coderjoe.atlas.fluid.block.FluidMerger import com.coderjoe.atlas.fluid.block.FluidPump import com.coderjoe.atlas.power.PowerBlock import com.coderjoe.atlas.power.PowerBlockFactory @@ -21,6 +22,9 @@ import com.coderjoe.atlas.power.block.PowerCable import com.coderjoe.atlas.power.block.SmallBattery import com.coderjoe.atlas.power.block.SmallDrill import com.coderjoe.atlas.power.block.MultiPowerCable +import com.coderjoe.atlas.power.block.CobblestoneGenerator +import com.coderjoe.atlas.power.block.ObsidianGenerator +import com.coderjoe.atlas.power.block.PowerMerger import com.coderjoe.atlas.power.block.SmallSolarPanel import io.mockk.* import org.bukkit.Location @@ -173,14 +177,15 @@ object TestHelper { SmallSolarPanel.descriptor, SmallDrill.descriptor, SmallBattery.descriptor, PowerCable.descriptor, LavaGenerator.descriptor, AutoSmelter.descriptor, - MultiPowerCable.descriptor + MultiPowerCable.descriptor, CobblestoneGenerator.descriptor, + ObsidianGenerator.descriptor, PowerMerger.descriptor )) } fun initFluidFactory() { FluidBlockFactory.registerFromDescriptors(listOf( FluidPump.descriptor, FluidPipe.descriptor, - FluidContainer.descriptor + FluidContainer.descriptor, FluidMerger.descriptor )) } diff --git a/src/test/kotlin/com/coderjoe/atlas/fluid/FluidBlockInitializerTest.kt b/src/test/kotlin/com/coderjoe/atlas/fluid/FluidBlockInitializerTest.kt index 1eda9f4..23fcd5f 100644 --- a/src/test/kotlin/com/coderjoe/atlas/fluid/FluidBlockInitializerTest.kt +++ b/src/test/kotlin/com/coderjoe/atlas/fluid/FluidBlockInitializerTest.kt @@ -24,8 +24,8 @@ class FluidBlockRegistrationTest { TestHelper.initFluidFactory() val ids = FluidBlockFactory.getRegisteredBlockIds() - // 3 pump + 6 directional pipe + 6 water-filled + 6 lava-filled + 42 container = 63 - assertEquals(63, ids.size) + // 3 pump + 6 directional pipe + 6 water-filled + 6 lava-filled + 42 container + 18 fluid merger = 81 + assertEquals(81, ids.size) } @Test diff --git a/src/test/kotlin/com/coderjoe/atlas/power/PowerBlockInitializerTest.kt b/src/test/kotlin/com/coderjoe/atlas/power/PowerBlockInitializerTest.kt index e2f5b7c..7132f52 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 + 8 auto smelter + 12 multi power cable = 39 - assertEquals(39, ids.size) + // 1 solar + 6 drill + 4 battery + 6 cable + 2 lava generator + 8 auto smelter + 12 multi power cable + 2 cobblestone generator + 2 obsidian generator + 12 power merger = 55 + assertEquals(55, ids.size) } @Test