RandomBlocks 1.1.0

Tell it like it is, they are not 'lucky blocks' they are random blocks

  1. StealthMuskrat
    Native Minecraft Version:
    1.13
    Tested Minecraft Versions:
    • 1.13
    • 1.14
    • 1.15
    • 1.16
    To put it simply, this is just a lucky blocks plugin that allows you to easily create 'random blocks' and 'events' for them with the RandomBlocks api as an 'addon'.

    If you already heard of lucky blocks then you will know what happens when you break them in game, for those that don't it simply picks a weight/chance based event to occur from the type of random block that was broken.

    nice.png

    Although luck is implemented, crafting with luck upgrades is currently disabled due to how spigot handles crafting and causes duplication issues.
    dupe_issue.png
    I've attempted to fix/find a way around this with several different ways with no success, so until I can find a way to fix it, crafting with luck upgrades is going to be disabled.

    root command = /randomblocks
    alias command = /rbs
    permission = randomblocks.admin
    Comes with tab completion

    /rbs help - gives this list
    /rbs give <player> <random block> <amount> - give random blocks to a player
    /rbs edit <random block> <event> <field> <value> - edit a random blocks' field for an event
    /rbs test <random block> <event> - test a random blocks' event
    /rbs enable <random block> - enables a random block
    /rbs enable <random block> <event> - enables a random blocks event
    /rbs disable <random block> - disables a random block
    /rbs disable <random block> <event> - disables a random blocks event
    /rbs savedata - saves current data
    /rbs buggered <fix/remove> fixes or removes random blocks that have an incorrect block
    /rbs delete <random block/@all> <world/@all> deletes all random blocks in a world

    Code (YAML):

    #How often to check for buggered random blocks
    checkBuggeredInterval
    : 20
    #The action to take once a buggered random block is found - true = fix, false = remove
    fixOrRemove
    : false
    #Should random blocks trigger if they are broken in creative
    triggerInCreative
    : false
    #If random blocks should trigger when it fades - true = trigger, false = drop
    #For more info: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/block/BlockFadeEvent.html
    triggerOnFade
    : true
     

    Code (YAML):

    #List of all random block locations and data
    blockLocs
    : []
     

    Code (YAML):
    main: fun.stuf.testaddon.TestAddon
    name
    : RBTestAddon
    version
    : 1.0.0
    api-version
    : '1.14'
    author
    : StealthMuskrat
    depend
    :
     - RandomBlocks

    Code (Java):
    package fun.stuf.testaddon;

    import fun.stuf.randomblocks.RandomBlocks;
    import fun.stuf.randomblocks.events.RandomBlockBreakEvent;
    import fun.stuf.randomblocks.events.RandomBlockPlaceEvent;
    import fun.stuf.randomblocks.randomblock.Event;
    import fun.stuf.randomblocks.randomblock.RandomBlock;
    import fun.stuf.utils.C;
    import fun.stuf.utils.Items;
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.NamespacedKey;
    import org.bukkit.Particle;
    import org.bukkit.Sound;
    import org.bukkit.entity.Creeper;
    import org.bukkit.entity.FallingBlock;
    import org.bukkit.entity.LivingEntity;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.FurnaceRecipe;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapelessRecipe;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
    import org.bukkit.util.Vector;

    //Adding a random block with events example
    public class TestAddon extends JavaPlugin {
        public static TestAddon testAddon;

        @Override
        public void onEnable() {
            testAddon = this;

            //String = random block name - must be alphanumeric and/or underscores
            //ItemStack = the itemstack that players hold - must be a block
            //Material = the type of block that represents a placed random block - must be solid
            RandomBlock testBlock = new RandomBlock("Test_Block",new ItemStack(Material.CARROT),Material.SAND) {
                @Override
                public void onPlace(RandomBlockPlaceEvent e) {
                    e.getRandomBlock(); //The random block type that was placed
                    e.getWorld(); //The world the random block was placed in
                    e.getBlock(); //The block that was placed
                    e.getCenter(); //The center of the block that was placed
                    e.getEntity(); //The entity that placed the block (might be null)
                    e.getDisplayStand(); //The display armor stand (might be null)
                    e.getInnerStand(); //The inner armor stand (might be null)

                    //Example usage
                    e.getWorld().playSound(e.getCenter(),Sound.ENTITY_CAT_HURT,1,1);
                }
            };

            //THE BELOW SETTINGS ARE OPTIONAL
            //IF YOU ARE USING DISPLAY STAND, SET THE DISPLAY NAME
            //IF YOU ARE USING INNER STAND, SET THE INNER TEXTURE

            //Sets the recipe to make the random block (no recipe by default) the recipe result is irrelevant as it will be changed to the random blocks' itemstack
            testBlock.setRecipe(new FurnaceRecipe(new NamespacedKey(this,"test_block"), new ItemStack(Material.STONE),Material.TNT,10,160));
            testBlock.setTriggerOnExplode(false); //If this random block should trigger if it gets exploded (false by default)
            testBlock.setTriggerOnBurn(true); //If this random block should trigger if it gets burned (false by default)
            testBlock.setDisplayName(C.parse("&aTest &bBlock")); //Sets the display name for the display armor stand (null by default)
            testBlock.setUseDisplayStand(true); //If should use display armor stand (false by default)
            //Sets the texture of the inner armor stand (value/url/uuid/username/material/itemstack)
            testBlock.setInnerTexture("http://textures.minecraft.net/texture/87c63d9079b75f90979783cf07ca726f65e3024415ac622a7c906cd25082af");
            testBlock.setSmallInnerStand(true); //If the inner armor stand should be small (false by default)
            testBlock.setUseInnerStand(true); //If should use inner armor stand (false by default)

            //Event Manager is where events are stored and handled
            testBlock.getEventManager(); //Gets the event manager
            testBlock.getEventManager().setIsUsingLuck(false); //Sets if picking events uses luck (false by default)
            //If you are not using luck, then don't worry about the next 4 options
            //Adds a luck upgrade for increasing luck in the crafting table by the set amount, add as many as you want. Amount must be between -100 and 100 inclusive
            testBlock.getEventManager().addLuckUpgrade(Material.IRON_INGOT,1);
            //Sets the chance of getting a good/neutral/bad event at a luck of 0, must add up to 100 (default 25/50/25)
            testBlock.getEventManager().setChanceAt0(25,50,25);
            //Sets the chance of getting a good/neutral/bad event at a luck of 100, must add up to 100 (default 75/20/5)
            testBlock.getEventManager().setChanceAt0(75,20,5);
            //Sets the chance of getting a good/neutral/bad event at a luck of -100, must add up to 100 (default 5/20/75)
            testBlock.getEventManager().setChanceAt0(5,20,75);

            //Add as many events as you want
            //Event - The event to occur
            testBlock.addEvent(new Event() {
                //Non final public primitive fields + strings are editable in game
                public int speed = 2;
                public int explosionRadius = 5;
                public int fuseTicks = 50;
                public double health = 10;
                public boolean powered = true;
                public boolean glowing = true;
                public String customName = "&bSuper Creeper";

                //The name of the event - must be alphanumeric and/or underscores
                @Override
                public String getName() {
                    return "super_creeper";
                }

                //The weight/chance of the event to happen, must be >= 0
                @Override
                public double getWeight() {
                    return .1;
                }

                //The type of event, GOOD - NEUTRAL - BAD
                //If you are not using luck, then set this to whatever because it doesn't really matter
                @Override
                public EventType getType() {
                    return EventType.BAD;
                }

                //What happens when you break the block
                @Override
                public void onBreak(RandomBlockBreakEvent e) {
                    //+ the above methods in the onPlace method
                    e.isRemoveDisplayStand(); //If the display armor stand is going to be removed
                    e.isRemoveInnerStand(); //If the inner armor stand is going to be removed
                    e.setRemoveDisplayStand(true); //Set if the display armor stand should be removed (true by default)
                    e.setRemoveInnerStand(true); //Set if the inner armor stand should be removed (true by default)

                    //Example usage
                    e.getWorld().playSound(e.getCenter(), Sound.ENTITY_CREEPER_DEATH,1,.5F);

                    e.getWorld().getNearbyEntities(e.getCenter(),5,5,5).forEach(entity -> {
                        Vector velocity = entity.getLocation().toVector().subtract(e.getCenter().toVector()).normalize();
                        velocity.multiply(5.5-entity.getLocation().distance(e.getCenter()));
                        entity.setVelocity(velocity);
                    });

                    if(e.getEntity() instanceof Player) {
                        Player player = (Player) e.getEntity();
                        player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,80,1,false,false,false));
                        player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW,160,1,false,false,false));
                    }

                    e.getWorld().spawn(e.getCenter(),Creeper.class,creeper ->  {
                        creeper.setExplosionRadius(explosionRadius);
                        creeper.setPowered(powered);
                        creeper.setMaxFuseTicks(fuseTicks);
                        creeper.setHealth(health);
                        creeper.setCustomName(C.parse(customName));
                        creeper.setGlowing(glowing);
                        creeper.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,2000,speed,false,false,false));
                        if(e.getEntity() instanceof LivingEntity)
                            creeper.setTarget((LivingEntity) e.getEntity());
                    });
                }
            });

            //Add as many random blocks as you want
            //Add/register the random block
            RandomBlocks.getInstance().addRandomBlock(testBlock);

            //Can also do as a 1 liner
            RandomBlocks.getInstance().addRandomBlock(new RandomBlock("Stinky", Items.buildItem(Material.ACACIA_WOOD).displayName("&r&eUh oh, Stinky").build(),Material.ACACIA_LOG) {
                @Override
                public void onPlace(RandomBlockPlaceEvent e) {
                    e.getWorld().playSound(e.getCenter(),Sound.BLOCK_ANVIL_PLACE,1,.5F);
                }
            }.setTriggerOnExplode(true)
            .setUseDisplayStand(true)
            .setDisplayName(C.parse("&6&kM&2Uh oh, Stinky!&6&kM"))
            .setRecipe(new ShapelessRecipe(new NamespacedKey(this,"stinky"),new ItemStack(Material.STONE))
            .addIngredient(1,Material.DIRT).addIngredient(1,Material.ROTTEN_FLESH)
            .addIngredient(1,Material.SLIME_BALL).addIngredient(1,Material.WATER_BUCKET))
            .addEvent(new Event() {
                @Override
                public String getName() {
                    return "ear_rape";
                }

                @Override
                public double getWeight() {
                    return .5;
                }

                @Override
                public EventType getType() {
                    return EventType.NEUTRAL;
                }

                @Override
                public void onBreak(RandomBlockBreakEvent e) {
                    e.getWorld().playSound(e.getCenter(),Sound.ENTITY_ENDER_DRAGON_DEATH,10,1.8F);
                    e.getWorld().playSound(e.getCenter(),Sound.ENTITY_WITHER_DEATH,10,.6F);
                    e.getWorld().playSound(e.getCenter(),Sound.ENTITY_ELDER_GUARDIAN_DEATH,10,.55F);
                    e.getWorld().playSound(e.getCenter(),Sound.ENTITY_TURTLE_DEATH,1,.5F);
                    int taskId = Bukkit.getScheduler().runTaskTimer(testAddon,()->{
                        e.getWorld().playSound(e.getCenter(),Sound.ENTITY_GENERIC_EXPLODE,10,2);
                        e.getWorld().playSound(e.getCenter(),Sound.ENTITY_CAT_DEATH,10,.65F);
                        e.getWorld().playSound(e.getCenter(),Sound.BLOCK_NOTE_BLOCK_BELL,10,1.75F);
                    },0,1).getTaskId();
                    Bukkit.getScheduler().runTaskLater(testAddon,()->Bukkit.getScheduler().cancelTask(taskId),100);
                }
            }).addEvent(new Event() {
                public float height = 10;
                @Override
                public String getName() {
                    return "fall";
                }

                @Override
                public double getWeight() {
                    return .5;
                }

                @Override
                public EventType getType() {
                    return EventType.BAD;
                }

                @Override
                public void onBreak(RandomBlockBreakEvent e) {
                    if(e.getEntity() != null)
                        e.getEntity().setFallDistance(height);
                }
            }).addEvent(new Event() {
                @Override
                public String getName() {
                    return "not_stinky";
                }

                @Override
                public double getWeight() {
                    return .1;
                }

                @Override
                public EventType getType() {
                    return EventType.GOOD;
                }

                @Override
                public void onBreak(RandomBlockBreakEvent e) {
                    int taskId = Bukkit.getScheduler().runTaskTimer(testAddon,()->{
                        FallingBlock fallingBlock = e.getWorld().spawnFallingBlock(e.getBlock().getLocation(),Material.DIAMOND_BLOCK.createBlockData());
                        fallingBlock.setVelocity(new Vector(0,3,0));
                        e.getWorld().spawnParticle(Particle.END_ROD,e.getCenter(),10,.25,.25,.25,.4);
                    },0,4).getTaskId();
                    Bukkit.getScheduler().runTaskLater(testAddon,()->Bukkit.getScheduler().cancelTask(taskId),20);
                }
            }));
        }
    }

    RandomBlockBreakEvent
    RandomBlockPlaceEvent

    WindLeaf and SnowCutieOwO like this.

Recent Updates

  1. Added luck
  2. Removed unnecessary exception

Recent Reviews

  1. RuthlessJailer
    RuthlessJailer
    5/5,
    Version: 1.0.0
    damn son this is cool af
    keep cool things coming
    API looks cool like the sight of that