@@ -138,6 +138,7 @@ void setUp() throws Exception {
138138 doAnswer (invocation -> null ).when (addon ).log (anyString ());
139139 doAnswer (invocation -> null ).when (addon ).logError (anyString ());
140140 when (addon .isCoveredGameMode (anyString ())).thenReturn (true );
141+ // Limits settings: stacked-plants defaults false (mock default), messages on
141142 when (addon .getSettings ()).thenReturn (limitsSettings );
142143 when (limitsSettings .isShowLimitMessages ()).thenReturn (true );
143144 when (addon .inGameModeWorld (any (World .class ))).thenReturn (false );
@@ -966,6 +967,61 @@ void testEntityChangeBlockFarmlandRemovesCropAbove() {
966967 assertEquals (1 , ibc .getBlockCount (Material .DIRT .getKey ()));
967968 }
968969
970+ // --- Stacked plants count as one (#53) ---
971+
972+ @ Test
973+ void testStackedPlantSegmentNotCountedWhenEnabled () {
974+ when (limitsSettings .isStackedPlantsCountAsOne ()).thenReturn (true );
975+ Block below = mockBlock (Material .SUGAR_CANE , new Location (world , 100 , 64 , 100 ));
976+ Block block = mockBlock (Material .SUGAR_CANE , blockLocation );
977+ when (block .getRelative (BlockFace .DOWN )).thenReturn (below );
978+
979+ BlockState replacedState = mock (BlockState .class );
980+ BlockPlaceEvent event = new BlockPlaceEvent (block , replacedState , block ,
981+ new ItemStack (Material .SUGAR_CANE ), player , true , EquipmentSlot .HAND );
982+ listener .onBlock (event );
983+
984+ assertFalse (event .isCancelled ());
985+ IslandBlockCount ibc = listener .getIsland ("test-island-id" );
986+ assertTrue (ibc == null || ibc .getBlockCount (Material .SUGAR_CANE .getKey ()) == 0 );
987+ }
988+
989+ @ Test
990+ void testStackedPlantBaseCountedWhenEnabled () {
991+ when (limitsSettings .isStackedPlantsCountAsOne ()).thenReturn (true );
992+ Block block = mockBlock (Material .SUGAR_CANE , blockLocation );
993+ // Below is AIR from the mockBlock helper — this is the base segment
994+
995+ BlockState replacedState = mock (BlockState .class );
996+ BlockPlaceEvent event = new BlockPlaceEvent (block , replacedState , block ,
997+ new ItemStack (Material .SUGAR_CANE ), player , true , EquipmentSlot .HAND );
998+ listener .onBlock (event );
999+
1000+ assertEquals (1 , listener .getIsland ("test-island-id" ).getBlockCount (Material .SUGAR_CANE .getKey ()));
1001+ }
1002+
1003+ @ Test
1004+ void testStackedPlantBreakBaseDecrementsOnlyOneWhenEnabled () {
1005+ when (limitsSettings .isStackedPlantsCountAsOne ()).thenReturn (true );
1006+ // Only the base was ever counted
1007+ IslandBlockCount ibc = new IslandBlockCount ("test-island-id" , "BSkyBlock" );
1008+ ibc .add (Environment .NORMAL , Material .SUGAR_CANE .getKey ());
1009+ listener .setIsland ("test-island-id" , ibc );
1010+
1011+ when (world .getMaxHeight ()).thenReturn (320 );
1012+ Block bottomBlock = mockBlock (Material .SUGAR_CANE , new Location (world , 100 , 65 , 100 ));
1013+ when (bottomBlock .getY ()).thenReturn (65 );
1014+ Block midBlock = mockBlock (Material .SUGAR_CANE , new Location (world , 100 , 66 , 100 ));
1015+ when (midBlock .getY ()).thenReturn (66 );
1016+ when (bottomBlock .getRelative (BlockFace .UP )).thenReturn (midBlock );
1017+
1018+ BlockBreakEvent event = new BlockBreakEvent (bottomBlock , player );
1019+ listener .onBlock (event );
1020+
1021+ // Exactly the one counted base is removed; the stem walk must not run
1022+ assertEquals (0 , listener .getIsland ("test-island-id" ).getBlockCount (Material .SUGAR_CANE .getKey ()));
1023+ }
1024+
9691025 // --- Block cascade tests ---
9701026
9711027 @ Test
0 commit comments