The way ZetaPistonStructureResolver is initialized makes it very hard to use a Zeta-agnostic approach to separate the piston position from the position of the first block to move, as Zeta implements a copy of the vanilla PistonStructureResolver constructor logic, but uses the (potentially already modified) values of the parent resolver.
Why?
Botania reuses the vanilla piston's pushing logic to support modifications to the way the pushed structure is resolved, including movable block entities and custom sticky blocks. To do so, it mixes into the PistonStructureResolver constructor in order to separate the "piston position" from the first block to move. The reason it does that is so a slime block bound to a Force Relay can pull the block it is supposed to move away from. With vanilla pistons that would be where the piston is, which would never move. But with Botania's pushing options it's completely reasonable that the block there could be movable.
Zeta's custom resolver breaks this reuse attempt by recalculating the first block to move based on the already modified piston position, which is either the force relay block itself (which is already moving) or the coordinates (0, -Integer.MAX_VALUE, 0) if the push was initiated by a force relay. As a result, that push attempt always fails.
How to solve?
I believe the best way to maximize compatibility would be to just reuse pushDirection and startPos instead of calculating them again from the parent's pistonPos and extending values.
(The values passed to the super constructor call are already "poisoned", but that shouldn't be an issue, since all methods are replaced by Zeta implementations, using the corresponding parent logic instead of calling super if Zeta's piston structure features are disabled.)
Example
The above test setup uses honey blocks to move double chests, which in turn drag along a force relay. The force relay (which itself is a non-sticking block, like glazed terracotta) is bound to the slime block, which (though the chains) moves the two blast furnaces. At least that's how it works on Fabric with Carpet rules movableBlockEntities and chainStone enabled. (Slight modifications appear to be necessary for Quark, since it appears to treat double chests as immovable blocks.)
What?
The way
ZetaPistonStructureResolver
is initialized makes it very hard to use a Zeta-agnostic approach to separate the piston position from the position of the first block to move, as Zeta implements a copy of the vanillaPistonStructureResolver
constructor logic, but uses the (potentially already modified) values of the parent resolver.Why?
Botania reuses the vanilla piston's pushing logic to support modifications to the way the pushed structure is resolved, including movable block entities and custom sticky blocks. To do so, it mixes into the
PistonStructureResolver
constructor in order to separate the "piston position" from the first block to move. The reason it does that is so a slime block bound to a Force Relay can pull the block it is supposed to move away from. With vanilla pistons that would be where the piston is, which would never move. But with Botania's pushing options it's completely reasonable that the block there could be movable.Zeta's custom resolver breaks this reuse attempt by recalculating the first block to move based on the already modified piston position, which is either the force relay block itself (which is already moving) or the coordinates (0, -Integer.MAX_VALUE, 0) if the push was initiated by a force relay. As a result, that push attempt always fails.
How to solve?
I believe the best way to maximize compatibility would be to just reuse
pushDirection
andstartPos
instead of calculating them again from the parent'spistonPos
andextending
values. (The values passed to the super constructor call are already "poisoned", but that shouldn't be an issue, since all methods are replaced by Zeta implementations, using the corresponding parent logic instead of calling super if Zeta's piston structure features are disabled.)Example
The above test setup uses honey blocks to move double chests, which in turn drag along a force relay. The force relay (which itself is a non-sticking block, like glazed terracotta) is bound to the slime block, which (though the chains) moves the two blast furnaces. At least that's how it works on Fabric with Carpet rules
movableBlockEntities
andchainStone
enabled. (Slight modifications appear to be necessary for Quark, since it appears to treat double chests as immovable blocks.)