[JAVA] I made a plug-in that can "Daruma-san fell" with Minecraft

I uploaded the production process before, but it was powered up by the time I finished giving it all, so I will renew it.

Development environment

The language is Java and the editor uses IntelliJ IDEA. The version of Minecraft is 1.13.2. The type of plugin is spigot.

What you can do with this plugin

This plug-in is a plug-in that allows you to play the old-fashioned Japanese play "Daruma-san ga Koro" that you probably did in Minecraft.

About the description and function of this plugin

Description of this plugin

――When the real Daruma doll falls, there is a demon role, but this plug-in does not have a demon. Instead, there is a ** goal **. "Daruma-san has fallen" is what you can do with this plug-in, while Daruma-san falls and progresses to that goal. ――There is a ** turn ** in this plug-in "Daruma-san fell". In this plug-in, one turn is from the time when you finish saying "Daruma-san fell" and judge whether it moved or not until you start saying the next "da". For example, if you say 3 turns, the game ends after performing the flow of saying "Daruma-san fell" and judging whether it moved or not. This number of turns can be set by command from within the game, so the length of the game can be freely decided on the spot. One turn is about 13 seconds (10 seconds until you finish saying "Daruma-san fell", 3 seconds for judgment time). --If the player moves while determining whether it has moved, it will be returned to the starting point. If it has passed a savepoint, it will be returned to the last savepoint passed. --Game participants will be automatically recognized as participants in the game mode adventure player when they type the command to start the game, and will be registered in the participant list (participants will be displayed in the terminal). .. Other players are not registered in the participant list, so no matter what you do, they will not be recognized as participants unless you type a special command.

Features of this plugin

All of the following features will only be activated by players who are in the game and are recognized as participants.

The one that makes it easy to understand whether it is a participant or not

スクリーンショット 2019-07-18 14.35.14.png スクリーンショット 2019-07-18 14.35.23.png At the start of the game or when you reach the goal, [Watching] or [Participant] will be displayed next to the name in the player list. This allows the administrator to know the participants, spectators, who has scored, etc. in one shot.

goal

2019-06-24_22.04.06.png If you place a stone button on top of a gold block, that is your goal. If there is a stone button other than the top of the gold block, it will not be a goal. When the player finishes, the game mode is changed to spectator mode and it becomes spectator mode.

public void GoalEvent(PlayerInteractEvent event) {
        if (Daruma.check) {
            Player player = event.getPlayer();
            Block block = event.getClickedBlock();
            if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                if ((block != null ? block.getType() : null) == Material.STONE_BUTTON) {
                    Location location = block.getLocation().clone();
                    location.add(0,-0.1,0);
                    if (player.getGameMode() == GameMode.ADVENTURE && Daruma.list.contains(player.getName()) && location.getBlock().getType().equals(Material.GOLD_BLOCK)) {
                        getServer().broadcastMessage(ChatColor.BLUE + player.getName() + ChatColor.WHITE + "Got a goal!");
                        player.setPlayerListName("["+ChatColor.BLUE+"Goal finished"+ChatColor.WHITE+"]"+"["+ChatColor.RED+"Watching the game"+ChatColor.WHITE+"]"+ChatColor.RED+player.getName());
                        if (player.hasMetadata(Events.DATA_KEY)) {
                            player.removeMetadata(Events.DATA_KEY, plugin);
                        }
                        getServer().broadcastMessage(clearTime(Daruma.time));
                        (player.getWorld()).playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 1);
                        Daruma.Goallist.add(player.getName()+"<"+clearTime(Daruma.time)+ChatColor.WHITE+">");
                        player.setGameMode(GameMode.SPECTATOR);
                        Daruma.list.remove(player.getName());
                        if(Daruma.list.isEmpty()){
                            getServer().broadcastMessage("The game ends because all the participants have reached the goal.");
                            for (Player target : Bukkit.getOnlinePlayers()) {
                                if (target.getGameMode() == GameMode.ADVENTURE || target.getGameMode() == GameMode.SPECTATOR) {
                                    target.sendTitle(ChatColor.RED + "Finished!", "", 10, 15, 10);
                                    target.teleport(target.getWorld().getSpawnLocation());
                                    target.setGameMode(GameMode.ADVENTURE);
                                    target.setPlayerListName(target.getName());
                                    target.setLevel(0);
                                }
                            }
                            Daruma.game=false;
                            Daruma.check=false;
                        }
                    }
                }
            }
        }
    }

The code looks like this. If a participant clicks on a gold block with a stone button, change the game mode to display the clear time and at the same time register the clear time in the ranking table and list the player as a participant. It is supposed to be deleted from and added [Goaled] to the player list. At this point, if all the participants have reached the goal, the game will end automatically.

int min,sec;
        min = (time%3600)/60;
        sec = time%60;
        String clearTime;
        clearTime = ChatColor.GREEN+"Clear time:"+min+"Minutes"+sec+"Seconds";
        return clearTime;

The clear time is calculated with a code like this.

Savepoint

2019-06-24_22.04.19.png If you place an emerald block, it becomes a savepoint. Since it is an automatic save function, it is automatically saved the moment it passes over the emerald block that is the save point, and if it moves while judging whether it has moved, it will not be returned to the start point, but will be returned to the last saved save point I will. The auto-save feature uses metadata and the save has a 5 second cooldown.


Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.EMERALD_BLOCK) && Daruma.list.contains(player.getName())&&player.getLevel()<1) {
                    player.setLevel(5);
                    player.setMetadata(DATA_KEY, new FixedMetadataValue(plugin,player.getLocation().clone()));
                    player.sendMessage(ChatColor.AQUA + "I saved it!");
                    player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1, 24);
                    Timer timer = new Timer();
                    TimerTask task = new TimerTask() {
                        int i = 5;
                        @Override
                        public void run() {
                            if(i<1){
                                player.setLevel(0);
                                player.setExp(0);
                                timer.cancel();
                            }
                            player.setLevel(i);
                            i--;
                        }
                    };
                    timer.schedule(task,0,1000);
                }
            }

The code looks like this, it is like getting the player's destination, recording the player's current location in the metadata if there is an emerald block there, and giving it to the player. If it is left as it is, it will be activated continuously, so we have implemented a cooldown to prevent continuous activation.

Ranking

2019-06-24_13.48.11.png When a player finishes, the server will display the player's clear time. Even after the game is over, it is possible to display the clear time list of the person who scored the goal with the command from within the game.

String string;
            if (!(Daruma.Goallist.isEmpty())) {
                for (int i = 1; i <= Daruma.Goallist.size(); i++) {
                    string = i + "Rank:" + Daruma.Goallist.get(i - 1);
                    getServer().broadcastMessage(string);
                }
            } else {
                getServer().broadcastMessage("No player scored a goal.");
            }

The code looks like this. If something is written on the ranking table, the ranking table will be displayed. If the ranking table is empty, the ranking table will not be displayed.

gimmick

I made a gimmick that activates when you step on it by applying save points.

Jump pad

void jumpPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.REDSTONE_BLOCK) && Daruma.list.contains(player.getName())) {
                    player.sendMessage(ChatColor.AQUA+"I got on the jump pad!");
                    for(float o=0;o<360;o=(float)(o+0.5)){
                        (player.getWorld()).spawnParticle(Particle.CLOUD,(float) (location.getX()+Math.sin(Math.toRadians(o))*1), (float) (location.getY()), (float) (location.getZ()+Math.cos(Math.toRadians(o))*1), 1, 0, 0, 0, 0);
                    }
                    player.playSound(player.getLocation(), Sound.ITEM_FIRECHARGE_USE, 1, 1);
                    player.setVelocity(new Vector(0,1.75,0));
                }
            }
        }
    }

I made a jump pad that jumps up when you step on the redstone block. It's not fun to just jump as it is, so I also use plays sound and spawn Particles to add direction.

The floor you shouldn't step on

void dontstep(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.NETHER_WART_BLOCK) && Daruma.list.contains(player.getName())) {
                    (player.getWorld()).spawnParticle(Particle.FLAME, location.getX(), location.getY(), location.getZ(), 30, 0.35, 0.35, 0.35);
                    if (player.hasMetadata(DATA_KEY)) {
                        MetadataValue value = null;
                        List<MetadataValue> values = player.getMetadata(DATA_KEY);
                        for (MetadataValue v : values) {
                            if (Objects.requireNonNull(v.getOwningPlugin()).getName().equals(plugin.getName())) {
                                value = v;
                                break;
                            }
                        }
                        if (value == null) {
                            return;
                        }
                        Location location1 = (Location) value.value();
                        assert location1 != null;
                        player.teleport(location1);
                    } else {
                        player.teleport(Daruma.startpoint);
                    }
                    player.playSound(player.getLocation(), Sound.ENTITY_GHAST_HURT, 1, 1);
                }
            }
        }
    }

When you step on the Nether Wart block, you will be taken to the save point or start point. This also has a production that says, "Sparks are scattered from the point where the player lands." ~~ When I actually tried it, it looked like rock ● ~

Speed pad

void dashPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.DIAMOND_BLOCK) && Daruma.list.contains(player.getName())&&!(player.hasPotionEffect(PotionEffectType.SPEED))) {
                    player.sendMessage(ChatColor.AQUA+"I got on the dash pad!");
                    player.playSound(player.getLocation(),Sound.BLOCK_BEACON_AMBIENT,1,1);
                    player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,30,3),true);
                }
            }
        }
    }

I made a dash pad that speeds up for a certain period of time when you step on the diamond block. The addPotionEffect gives a potion effect that increases the movement speed. ~~ Don't say I couldn't think of a production ~~

Slow pad

void slowPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.LAPIS_BLOCK) && Daruma.list.contains(player.getName())&&!(player.hasPotionEffect(PotionEffectType.SLOW))) {
                    player.playSound(player.getLocation(),Sound.ENTITY_SLIME_JUMP,1,1);
                    player.sendMessage(ChatColor.RED+"I got on the slow pad!");
                    player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW,80,3),true);
                }
            }
        }
    }

I made a slow pad that slows down for a certain period of time when you step on the lapis lazuli block. The mechanism is almost the same as the speed pad.

Blind pad

void blindPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.COAL_BLOCK) && Daruma.list.contains(player.getName())&&!(player.hasPotionEffect(PotionEffectType.BLINDNESS))) {
                    player.playSound(player.getLocation(),Sound.ENTITY_SLIME_JUMP,1,1);
                    player.sendMessage(ChatColor.RED+"I got on the blind pad!");
                    player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,80,255),true);
                }
            }
        }
    }

I made a blind pad that disappears for a certain period of time when you step on the coal block. The mechanism is almost the same as the speed pad.

Finally

It took about half a year to make it so far. This plug-in is a proud work for me because it was finally completed while being spit out as a slimy fatal error. I use the sleep method in some parts of the game processing, but if I use it without thinking, the game itself will stop (because all processing is done in one thread), so the Timer class so that the game does not stop It was difficult to devise something like using a timer. There may be a better way, but I used this for the time being. However, I am still immature and I think there are still some points that can be improved, so I would like to improve there. If there is a voice such as "I want you to distribute it", I will distribute it with explanations such as dedicated commands. ~~ I'd be happy if you like it, stock it, or spread it on Twitter ~~ Thank you for reading this far. The source will be here.

Recommended Posts

I made a plug-in that can "Daruma-san fell" with Minecraft
I made a package that can compare morphological analyzers with Python
I made a shuffle that can be reset (reverted) with Python
I made a plug-in "EZPrinter" that easily outputs map PDF with QGIS.
I made a module PyNanaco that can charge nanaco credit with python
Format summary of formats that can be serialized with gensim
I investigated the pretreatment that can be done with PyCaret
I made a plug-in that can "Daruma-san fell" with Minecraft
A story that stumbled when I made a chatbot with Transformer
I made a fortune with Python.
I made a rigid Pomodoro timer that works with CUI
I made a daemon with Python
I made a program that automatically calculates the zodiac with tkinter
[python] I made a class that can write a file tree quickly
I made a character counter with Python
I made a Hex map with Python
I made a life game with Numpy
I made a stamp generator with GAN
I made a roguelike game with Python
I made a simple blackjack with Python
I made a configuration file with Python
I made a WEB application with Django
I made a neuron simulator with Python
[Python] I made a utility that can access dict type like a path
I made a tool that makes decompression a little easier with CLI (Python3)
I made a stamp substitute bot with line
I made a weather forecast bot-like with Python.
I made a GUI application with Python + PyQt5
A memo that made a graph animated with plotly
I made a Twitter fujoshi blocker with Python ①
[Python] I made a Youtube Downloader with Tkinter.
I made a simple Bitcoin wallet with pycoin
I made a LINE Bot with Serverless Framework!
I made a random number graph with Numpy
I made a bin picking game with Python
I made a Mattermost bot with Python (+ Flask)
I registered PyQCheck, a library that can perform QuickCheck with Python, in PyPI.
I made a Docker image that can call FBX SDK Python from Node.js
A story that I was addicted to when I made SFTP communication with python
〇✕ I made a game
[AWS] I made a reminder BOT with LINE WORKS
I made a household account book bot with LINE Bot
I made a ready-to-use syslog server with Play with Docker
I made a Christmas tree lighting game with Python
I made a window for Log output with Tkinter
I made a VM that runs OpenCV for Python
I made a Python3 environment on Ubuntu with direnv.
I made a LINE BOT with Python and Heroku
A memo that I touched the Datastore with python
I made a falling block game with Sense HAT
I made a twitter app that decodes the characters of Pricone with heroku (failure)
I made a web application that maps IT event information with Vue and Flask
[Python] I made a function that decrypts AES encryption just by throwing it with pycrypto.
I made a simple typing game with tkinter in Python
I made a package to filter time series with python
I made blackjack with python!
I made a simple book application with python + Flask ~ Introduction ~
I made a class that easily performs unixtime ← → datetime conversion
I made a fucking app that won't let you skip
I made a resource monitor for Raspberry Pi with a spreadsheet
[Atcoder] [C ++] I made a test automation tool that can be used during the contest
I made a puzzle game (like) with Tkinter in Python
How to display hover text and text that can be executed by clicking with Minecraft plugin