11package com .teammoeg .frostedheart .content .decoration ;
22
3- import com .simibubi .create .content .equipment .extendoGrip .ExtendoGripItem ;
4- import com .simibubi .create .foundation .placement .IPlacementHelper ;
5- import com .simibubi .create .foundation .placement .PlacementHelpers ;
6- import com .simibubi .create .foundation .placement .PlacementOffset ;
7- import com .simibubi .create .infrastructure .config .AllConfigs ;
83import com .teammoeg .chorda .block .CBlock ;
94import com .teammoeg .chorda .util .struct .FastEnumMap ;
105import com .teammoeg .frostedheart .bootstrap .reference .FHTags ;
116import net .minecraft .core .BlockPos ;
127import net .minecraft .core .Direction ;
13- import net .minecraft .sounds .SoundEvents ;
14- import net .minecraft .sounds .SoundSource ;
15- import net .minecraft .world .InteractionHand ;
16- import net .minecraft .world .InteractionResult ;
17- import net .minecraft .world .entity .ai .attributes .AttributeInstance ;
18- import net .minecraft .world .entity .player .Player ;
8+ import net .minecraft .world .entity .LivingEntity ;
199import net .minecraft .world .item .BlockItem ;
20- import net .minecraft .world .item .ItemStack ;
2110import net .minecraft .world .item .context .BlockPlaceContext ;
2211import net .minecraft .world .level .BlockGetter ;
23- import net .minecraft .world .level .Level ;
2412import net .minecraft .world .level .LevelAccessor ;
2513import net .minecraft .world .level .block .Block ;
2614import net .minecraft .world .level .block .SimpleWaterloggedBlock ;
3018import net .minecraft .world .level .block .state .properties .BooleanProperty ;
3119import net .minecraft .world .level .material .FluidState ;
3220import net .minecraft .world .level .material .Fluids ;
33- import net .minecraft .world .phys .BlockHitResult ;
3421import net .minecraft .world .phys .shapes .CollisionContext ;
22+ import net .minecraft .world .phys .shapes .EntityCollisionContext ;
3523import net .minecraft .world .phys .shapes .Shapes ;
3624import net .minecraft .world .phys .shapes .VoxelShape ;
37- import net .minecraftforge .common .ForgeMod ;
3825import net .minecraftforge .registries .ForgeRegistries ;
3926import org .jetbrains .annotations .NotNull ;
4027import org .jetbrains .annotations .Nullable ;
4128
4229import java .util .ArrayList ;
4330import java .util .List ;
4431import java .util .concurrent .ConcurrentHashMap ;
45- import java .util .function .Predicate ;
4632
4733public class FHScaffoldingBlock extends CBlock implements SimpleWaterloggedBlock {
4834 public static final BooleanProperty SURFACE = BooleanProperty .create ("surface" );
@@ -69,8 +55,6 @@ public class FHScaffoldingBlock extends CBlock implements SimpleWaterloggedBlock
6955
7056 private static final ConcurrentHashMap <BlockState , VoxelShape > shapeCache = new ConcurrentHashMap <>();
7157
72- public static final int PLACEMENT_HELPER_ID = PlacementHelpers .register (new ScaffoldingPlacementHelper ());
73-
7458 public FHScaffoldingBlock (Properties blockProps ) {
7559 super (blockProps );
7660 registerDefaultState (stateDefinition .any ()
@@ -99,7 +83,7 @@ protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockSt
9983
10084 @ Override
10185 public VoxelShape getShape (BlockState pState , BlockGetter pLevel , BlockPos pPos , CollisionContext pContext ) {
102- return isScaffolding (pState ) ? Shapes .block () : shapeCache .computeIfAbsent (pState , this ::computeShape );
86+ return isHoldingScaffolding (pState , pLevel , pPos , pContext ) ? Shapes .block () : shapeCache .computeIfAbsent (pState , this ::computeShape );
10387 }
10488
10589 private VoxelShape computeShape (BlockState state ) {
@@ -138,24 +122,6 @@ public FluidState getFluidState(BlockState pState) {
138122 return pState .getValue (BlockStateProperties .WATERLOGGED ) ? Fluids .WATER .getSource (false ) : super .getFluidState (pState );
139123 }
140124
141- @ Override
142- public InteractionResult use (BlockState pState , Level pLevel , BlockPos pPos , Player pPlayer , InteractionHand pHand , BlockHitResult pHit ) {
143- var heldItem = pPlayer .getItemInHand (pHand );
144-
145- if (heldItem .is (FHTags .forgeTag (ForgeRegistries .ITEMS , "rods" ))) {
146- pLevel .setBlock (pPos , pState .setValue (HANDRAIL , !pState .getValue (HANDRAIL )), 2 );
147- pLevel .playSound ((Player )null , pPos , SoundEvents .COPPER_PLACE , SoundSource .BLOCKS , 1.0F , 0.8F + pLevel .random .nextFloat () * 0.4F );
148- return InteractionResult .SUCCESS ;
149- }
150-
151- IPlacementHelper helper = PlacementHelpers .get (PLACEMENT_HELPER_ID );
152- if (helper .matchesItem (heldItem ))
153- return helper .getOffset (pPlayer , pLevel , pState , pPos , pHit )
154- .placeInWorld (pLevel , (BlockItem ) heldItem .getItem (), pPlayer , pHand , pHit );
155-
156- return super .use (pState , pLevel , pPos , pPlayer , pHand , pHit );
157- }
158-
159125 @ Override
160126 public BlockState updateShape (BlockState pState , Direction pDirection , BlockState pNeighborState , LevelAccessor pLevel , BlockPos pPos , BlockPos pNeighborPos ) {
161127 if (pState .getValue (BlockStateProperties .WATERLOGGED )) {
@@ -217,78 +183,23 @@ public static boolean isScaffolding(BlockState state) {
217183 return state .is (FHTags .Blocks .SCAFFOLDING .get ());
218184 }
219185
186+ public static boolean isHoldingScaffolding (BlockState state , BlockGetter level , BlockPos pos , CollisionContext context ) {
187+ if (context instanceof EntityCollisionContext ecc ) {
188+ if (ecc .getEntity () instanceof LivingEntity entity && entity .getMainHandItem ().getItem () instanceof BlockItem bi ) {
189+ return isScaffolding (bi .getBlock ().defaultBlockState ());
190+ }
191+ return false ;
192+ }
193+
194+ var tags = ForgeRegistries .BLOCKS .tags ();
195+ return tags != null && tags .getTag (FHTags .Blocks .SCAFFOLDING .tag ).stream ().anyMatch (b -> context .isHoldingItem (b .asItem ()));
196+ }
197+
220198 public static FastEnumMap <Direction , BlockPos > getNeighbors (BlockPos pos ) {
221199 FastEnumMap <Direction , BlockPos > map = new FastEnumMap <>(Direction .values ());
222200 for (Direction dir : Direction .values ()) {
223201 map .put (dir , pos .relative (dir ));
224202 }
225203 return map ;
226204 }
227-
228- public static class ScaffoldingPlacementHelper implements IPlacementHelper {
229-
230- @ Override
231- public Predicate <ItemStack > getItemPredicate () {
232- return i -> i .getItem () instanceof BlockItem
233- && ((BlockItem ) i .getItem ()).getBlock () instanceof FHScaffoldingBlock ;
234- }
235-
236- @ Override
237- public Predicate <BlockState > getStatePredicate () {
238- return FHScaffoldingBlock ::isScaffolding ;
239- }
240-
241- private boolean canExtendToward (BlockState state , Direction side ) {
242- return getStatePredicate ().test (state ) && side .getAxis () == Direction .Axis .Y ;
243- }
244-
245- private int attachedBlocks (Level world , BlockPos pos , Direction direction ) {
246- BlockPos checkPos = pos .relative (direction );
247- int count = 0 ;
248- while (getStatePredicate ().test (world .getBlockState (checkPos ))) {
249- count ++;
250- checkPos = checkPos .relative (direction );
251- }
252- return count ;
253- }
254-
255- @ Override
256- public PlacementOffset getOffset (Player player , Level world , BlockState state , BlockPos pos , BlockHitResult ray ) {
257- List <Direction > directions ;
258-
259- if (player != null && ray .getDirection () == Direction .UP ) {
260- Direction facing = player .getDirection ();
261- directions = List .of (facing );
262- } else {
263- directions = IPlacementHelper .orderedByDistance (pos , ray .getLocation (),
264- dir -> canExtendToward (state , dir ));
265- }
266-
267- int range = AllConfigs .server ().equipment .placementAssistRange .get ();
268- if (player != null ) {
269- AttributeInstance reach = player .getAttribute (ForgeMod .BLOCK_REACH .get ());
270- if (reach != null && reach .hasModifier (ExtendoGripItem .singleRangeAttributeModifier ))
271- range += 4 ;
272- }
273-
274- for (Direction dir : directions ) {
275- int poles = attachedBlocks (world , pos , dir );
276- if (poles >= range )
277- continue ;
278-
279- BlockPos newPos = pos .relative (dir , poles + 1 );
280- int newY = newPos .getY ();
281- if (newY <= world .getMinBuildHeight () || newY >= world .getMaxBuildHeight ())
282- continue ;
283- BlockState newState = world .getBlockState (newPos );
284- if (!newState .canBeReplaced ())
285- continue ;
286-
287- return PlacementOffset .success (newPos ,
288- bState -> calcState (bState , newPos , world ));
289- }
290-
291- return PlacementOffset .fail ();
292- }
293- }
294205}
0 commit comments