Solved Changing a detector rail's direction when powered.

Discussion in 'Spigot Plugin Development' started by BC5, Mar 16, 2020.

  1. BC5

    BC5

    I'm trying to change the direction of a detector rail when it's powered based off of the minecart's direction.

    Code (Java):
    @EventHandler
        private void redstoneChange(BlockRedstoneEvent event)
        {
            Block b = event.getBlock();
            if(b.getType() == Material.DETECTOR_RAIL)
            {
                //Check if block below rail is a Lapis block
                if(b.getRelative(0,-1,0).getType() == Material.LAPIS_BLOCK)
                {
                    //Getting nearby minecarts
                    World w = b.getWorld();
                    Predicate minecartFilter = Predicates.instanceOf(Minecart.class);
                    Collection<Entity> minecarts = w.getNearbyEntities(b.getLocation(),1.5,1.5,1.5,minecartFilter);
                   
                    if(minecarts.size() == 0)
                    {
                        //If none found, ignore.
                        return;
                    }
                    else
                    {
                        Minecart cart = (Minecart) minecarts.iterator().next();
                        Vector velocity = cart.getVelocity();
                        if(velocity.length() > 0)
                        {
                            double velocityX = velocity.getX();
                            double velocityZ = velocity.getZ();

                            //NORTH-SOUTH
                            if(velocityZ != 0 && velocityX == 0)
                            {
                                System.out.println("Redirect NS");
                                RedstoneRail data = (RedstoneRail) b.getState().getBlockData();
                                data.setShape(Rail.Shape.NORTH_SOUTH);
                                b.getState().setBlockData(data);
                                b.getState().update();
                            }

                            //EAST-WEST
                            if(velocityX != 0 && velocityZ == 0)
                            {
                                System.out.println("Redirect EW");
                                RedstoneRail data = (RedstoneRail) b.getState().getBlockData();
                                data.setShape(Rail.Shape.EAST_WEST);
                                b.getState().setBlockData(data);
                                b.getState().update();
                            }
                        }
                    }
                }
            }
        }
    }
     

    The code successfully triggers the "Redirect EW" and "Redirect NS" sysouts respectively, but the rail's direction simply does not update with no error message.

    [​IMG]

    Anyone got any ideas on how I could make this work?
     
  2. Choco

    Moderator

    getState() returns a copy for every call. Call it once and assign it to a variable. Get its block data, change it, set its block data. A call to update() shouldn't be necessary (though I may be wrong on this)
     
  3. BC5

    BC5

    Updated the code with your suggestion, however the direction of the rail still doesn't change despite my console being nothing but "REDIRECT EW" and "REDIRECT NS".

    (Tried both with state.update() removed and included)
    Code (Java):
    //NORTH-SOUTH
                            if(velocityZ != 0 && velocityX == 0)
                            {
                                System.out.println("Redirect NS");
                               
                                BlockState state = b.getState();
                               
                                RedstoneRail data = (RedstoneRail) state.getBlockData();
                                data.setShape(Rail.Shape.NORTH_SOUTH);
                               
                                state.setBlockData(data);
                                state.update();
                            }

                            //EAST-WEST
                            if(velocityX != 0 && velocityZ == 0)
                            {
                                System.out.println("Redirect EW");

                                BlockState state = b.getState();

                                RedstoneRail data = (RedstoneRail) state.getBlockData();
                                data.setShape(Rail.Shape.EAST_WEST);

                                state.setBlockData(data);
                                //state.update();
                            }
     
  4. I think getting BlockState is not necessary. Block has it's own Block#getBlockData and Block#setBlockData(BlockData).
     
    • Agree Agree x 1
  5. BC5

    BC5

    I used the Block.getBlockData and Block.setBlockData originally but switched to the BlockState to try the update().
    Neither seem to work
     
  6. Weird. Try to debug it. Get and print its "shape" before Rail.setShape and after Block.setBlockData.
     
  7. BC5

    BC5

    Code (Java):
        @EventHandler
        private void redstoneChange(BlockRedstoneEvent event)
        {

            Block b = event.getBlock();

            if(b.getType() == Material.DETECTOR_RAIL)
            {
                String initialShape = getBlockShape(b);
                //Check if block below rail is a Lapis block
                if(b.getRelative(0,-1,0).getType() == Material.LAPIS_BLOCK)
                {
                    //Getting nearby minecarts
                    World w = b.getWorld();
                    Predicate minecartFilter = Predicates.instanceOf(Minecart.class);
                    Collection<Entity> minecarts = w.getNearbyEntities(b.getLocation(),1.5,1.5,1.5,minecartFilter);

                    if(minecarts.size() == 0)
                    {
                        //If none found, ignore.
                        return;
                    }
                    else
                    {
                        Minecart cart = (Minecart) minecarts.iterator().next();
                        Vector velocity = cart.getVelocity();
                        if(velocity.length() > 0)
                        {
                            double velocityX = velocity.getX();
                            double velocityZ = velocity.getZ();

                            //NORTH-SOUTH
                            if(velocityZ != 0 && velocityX == 0)
                            {
                                System.out.println("Redirect NS");

                                BlockState state = b.getState();

                                RedstoneRail data = (RedstoneRail) state.getBlockData();
                                data.setShape(Rail.Shape.NORTH_SOUTH);

                                state.setBlockData(data);
                                state.update();
                            }

                            //EAST-WEST
                            if(velocityX != 0 && velocityZ == 0)
                            {
                                System.out.println("Redirect EW");

                                BlockState state = b.getState();

                                RedstoneRail data = (RedstoneRail) state.getBlockData();
                                data.setShape(Rail.Shape.EAST_WEST);

                                state.setBlockData(data);
                                state.update();
                            }
                        }
                    }
                }
                String finalshape = getBlockShape(event.getBlock());
                System.out.println("SHAPE: " + initialShape + " -> " + finalshape);
            }
        }

        private static String getBlockShape(Block b)
        {
            RedstoneRail data = (RedstoneRail) b.getState().getBlockData();
            return data.getShape().toString();
        }

    Code (Text):
    [23:52:51 INFO]: SHAPE: NORTH_SOUTH -> NORTH_SOUTH
    [23:52:51 INFO]: Redirect NS
    [23:52:51 INFO]: SHAPE: EAST_WEST -> NORTH_SOUTH
    [23:52:51 INFO]: Redirect EW
    [23:52:51 INFO]: SHAPE: NORTH_SOUTH -> EAST_WEST
    [23:52:52 INFO]: Redirect NS
    [23:52:52 INFO]: SHAPE: EAST_WEST -> NORTH_SOUTH
    [23:52:55 INFO]: Redirect EW
    [23:52:55 INFO]: SHAPE: EAST_WEST -> EAST_WEST
    [23:52:55 INFO]: Redirect EW
    [23:52:55 INFO]: SHAPE: NORTH_SOUTH -> EAST_WEST
    [23:52:58 INFO]: Redirect NS
    [23:52:58 INFO]: SHAPE: NORTH_SOUTH -> NORTH_SOUTH
    [23:52:58 INFO]: Redirect NS
    [23:52:58 INFO]: SHAPE: EAST_WEST -> NORTH_SOUTH
    [23:52:58 INFO]: Redirect EW
    [23:52:58 INFO]: SHAPE: NORTH_SOUTH -> EAST_WEST
    [23:52:58 INFO]: Redirect NS
    [23:52:58 INFO]: SHAPE: EAST_WEST -> NORTH_SOUTH

    In the above console snippet the minecart is running in a loop over a couple of detector rails and no changes happen in the world.
     
  8. Meh. Can't say really much about it. Try to set its shape one tick later via scheduler.
     
  9. BC5

    BC5

    No idea why, but that did the trick perfectly. Thanks