44import java .util .function .ToIntBiFunction ;
55import mekanism .common .block .attribute .Attribute .TileAttribute ;
66import mekanism .common .block .states .BlockStateHelper ;
7- import mekanism .common .lib .multiblock .IInternalMultiblock ;
8- import mekanism .common .lib .multiblock .IMultiblock ;
9- import mekanism .common .lib .multiblock .IStructuralMultiblock ;
10- import mekanism .common .lib .multiblock .MultiblockData ;
11- import mekanism .common .lib .multiblock .Structure ;
127import mekanism .common .tile .base .TileEntityMekanism ;
138import mekanism .common .util .WorldUtils ;
149import net .minecraft .core .BlockPos ;
1510import net .minecraft .core .Direction ;
1611import net .minecraft .world .entity .EntityType ;
17- import net .minecraft .world .level . LevelReader ;
18- import net .minecraft .world .level .block . entity . BlockEntity ;
12+ import net .minecraft .world .entity . Mob ;
13+ import net .minecraft .world .level .BlockGetter ;
1914import net .minecraft .world .level .block .state .BlockBehaviour ;
2015import net .minecraft .world .level .block .state .BlockBehaviour .Properties ;
2116import net .minecraft .world .level .block .state .BlockBehaviour .StateArgumentPredicate ;
17+ import net .minecraft .world .level .block .state .BlockState ;
18+ import net .minecraft .world .level .pathfinder .PathType ;
2219import net .minecraft .world .level .storage .loot .functions .FunctionUserBuilder ;
2320import net .minecraft .world .level .storage .loot .predicates .ConditionUserBuilder ;
2421import org .jetbrains .annotations .NotNull ;
@@ -100,41 +97,7 @@ public static class AttributeMobSpawn implements Attribute {
10097 public static final StateArgumentPredicate <EntityType <?>> NEVER_PREDICATE = (state , reader , pos , entityType ) -> false ;
10198 public static final AttributeMobSpawn NEVER = new AttributeMobSpawn (NEVER_PREDICATE );
10299 public static final AttributeMobSpawn WHEN_NOT_FORMED = new AttributeMobSpawn ((state , reader , pos , entityType ) -> {
103- BlockEntity tile = WorldUtils .getTileEntity (reader , pos );
104- if (tile instanceof IMultiblock <?> multiblockTile ) {
105- if (reader instanceof LevelReader levelReader && levelReader .isClientSide ()) {
106- //If we are on the client just check if we are formed as we don't sync structure information
107- // to the client. This way the client is at least relatively accurate with what values
108- // it returns for if mobs can spawn
109- if (multiblockTile .getMultiblock ().isFormed ()) {
110- return false ;
111- }
112- } else if (multiblockTile .getMultiblock ().isPositionInsideBounds (multiblockTile .getStructure (), pos .above ())) {
113- //If the multiblock is formed and the position above this block is inside the bounds of the multiblock
114- // don't allow spawning on it.
115- return false ;
116- }
117- } else if (tile instanceof IStructuralMultiblock structuralMultiblock && structuralMultiblock .hasFormedMultiblock ()) {
118- //Note: This isn't actually used as all our structural multiblocks are transparent and vanilla tends to not let
119- // mobs spawn on glass or stuff
120- if (reader instanceof LevelReader levelReader && levelReader .isClientSide ()) {
121- //If we are on the client return we can't spawn if it is formed. This way the client is at least relatively
122- // accurate with what values it returns for if mobs can spawn
123- return false ;
124- } else {
125- BlockPos above = pos .above ();
126- for (Structure structure : structuralMultiblock .getStructureMap ().values ()) {
127- //Manually handle the getMultiblockData logic to avoid extra lookups
128- MultiblockData data = structure .getMultiblockData ();
129- if (data != null && data .isFormed () && data .isPositionInsideBounds (structure , above )) {
130- //If the multiblock is formed and the position above this block is inside the bounds of the multiblock
131- // don't allow spawning on it.
132- return false ;
133- }
134- }
135- }
136- } else if (tile instanceof IInternalMultiblock internalMultiblock && internalMultiblock .hasFormedMultiblock ()) {
137- //If it is an internal multiblock don't allow spawning mobs on it if it is formed
100+ if (WorldUtils .isInsideFormedMultiblock (reader , pos , null )) {
138101 return false ;
139102 }
140103 //Super implementation
@@ -153,6 +116,19 @@ public void adjustProperties(Properties props) {
153116 }
154117 }
155118
119+ @ FunctionalInterface
120+ public interface PathCheck {
121+
122+ @ Nullable
123+ PathType getBlockPathType (@ NotNull BlockState state , @ NotNull BlockGetter level , @ NotNull BlockPos pos , @ Nullable Mob mob );
124+ }
125+
126+ public record AttributeCustomPathType (Attributes .PathCheck pathCheck ) implements Attribute {
127+
128+ public static final AttributeCustomPathType WHEN_NOT_FORMED = new AttributeCustomPathType ((state , level , pos , mob ) ->
129+ WorldUtils .isInsideFormedMultiblock (level , pos , mob ) ? PathType .DAMAGE_OTHER : null );
130+ }
131+
156132 /** If a block can emit redstone. */
157133 public static class AttributeRedstoneEmitter <TILE extends TileEntityMekanism > implements TileAttribute <TILE > {
158134
0 commit comments