Package com.sk89q.craftbook.mechanics.ic.gates.world.miscellaneous

Source Code of com.sk89q.craftbook.mechanics.ic.gates.world.miscellaneous.ProgrammableFireworkShow$FireworkShowHandler$FyrestoneInterpreter

package com.sk89q.craftbook.mechanics.ic.gates.world.miscellaneous;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework;
import org.bukkit.inventory.meta.FireworkMeta;
import org.bukkit.scheduler.BukkitTask;

import com.sk89q.craftbook.ChangedSign;
import com.sk89q.craftbook.bukkit.CraftBookPlugin;
import com.sk89q.craftbook.bukkit.util.BukkitUtil;
import com.sk89q.craftbook.mechanics.ic.AbstractICFactory;
import com.sk89q.craftbook.mechanics.ic.AbstractSelfTriggeredIC;
import com.sk89q.craftbook.mechanics.ic.ChipState;
import com.sk89q.craftbook.mechanics.ic.IC;
import com.sk89q.craftbook.mechanics.ic.ICFactory;
import com.sk89q.craftbook.mechanics.ic.ICManager;
import com.sk89q.craftbook.mechanics.ic.ICVerificationException;
import com.sk89q.craftbook.mechanics.ic.RestrictedIC;
import com.sk89q.craftbook.util.RegexUtil;

public class ProgrammableFireworkShow extends AbstractSelfTriggeredIC {

    public ProgrammableFireworkShow(Server server, ChangedSign sign, ICFactory factory) {

        super(server, sign, factory);
    }

    @Override
    public boolean isAlwaysST() {
        return true;
    }

    @Override
    public String getTitle() {

        return "Programmable Firework Show";
    }

    @Override
    public String getSignTitle() {

        return "FIREWORKS";
    }

    String show;
    FireworkShowHandler handler;

    boolean stopOnLow;

    @Override
    public void load() {

        show = getLine(2).trim();
        handler = new FireworkShowHandler(show);

        String[] bits = RegexUtil.COMMA_PATTERN.split(getLine(3));
        if(bits.length > 0)
            stopOnLow = Boolean.getBoolean(bits[0]);
    }

    @Override
    public void trigger(ChipState chip) {

        if (chip.getInput(0) && !handler.isShowRunning())
            handler.startShow();
        else if (handler.isShowRunning() && stopOnLow)
            handler.stopShow();
    }

    @Override
    public void think(ChipState chip) {
        if(handler.isShowRunning() != chip.getOutput(0)) {
            chip.setOutput(0, handler.isShowRunning());
        }
    }

    public static class Factory extends AbstractICFactory implements RestrictedIC {

        public Factory(Server server) {

            super(server);
        }

        @Override
        public IC create(ChangedSign sign) {

            return new ProgrammableFireworkShow(getServer(), sign, this);
        }

        @Override
        public void verify(ChangedSign sign) throws ICVerificationException {

            if (sign.getLine(2).trim().isEmpty() || !new File(ICManager.inst().getFireworkFolder(), sign.getLine(2).trim() + ".txt").exists() && !new File(ICManager.inst().getFireworkFolder(), sign.getLine(2).trim() + ".fwk").exists())
                throw new ICVerificationException("A valid firework show is required on line 3!");
        }

        @Override
        public String getShortDescription() {

            return "Plays a firework show from a file.";
        }

        @Override
        public String[] getLineHelp() {

            return new String[] {"Name of firework show", "true to stop on low"};
        }
    }

    public class FireworkShowHandler {

        ShowInterpreter show;

        String showName;

        int position;

        List<String> lines = new ArrayList<String>();

        BukkitTask task;

        boolean fyrestone = false;

        public FireworkShowHandler(String showName) {

            this.showName = showName;
            try {
                readShow();
            } catch (IOException e) {
                BukkitUtil.printStacktrace(e);
            }
        }

        public void readShow() throws IOException {

            lines.clear();
            File firework = new File(ICManager.inst().getFireworkFolder(), showName + ".txt");
            if(!firework.exists()) {
                fyrestone = true;
                firework = new File(ICManager.inst().getFireworkFolder(), showName + ".fwk");
                if (!firework.exists()) {
                    CraftBookPlugin.logger().severe("Firework File Not Found! " + firework.getName());
                    return;
                }
            }
            else
                fyrestone = false;
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(firework), "UTF-8"));
            String line = "";
            while ((line = br.readLine()) != null) {

                if(line.trim().isEmpty())
                    continue;
                lines.add(line);
            }

            br.close();
        }

        public boolean isShowRunning() {
            return show != null && show.isRunning();
        }

        public void stopShow() {

            show.setRunning(false);
        }

        public void startShow() {

            position = 0;
            if (task != null)
                task.cancel();
            ShowInterpreter show;
            if(!fyrestone)
                show = new BasicShowInterpreter();
            else
                show = new FyrestoneInterpreter();
            task = Bukkit.getScheduler().runTask(CraftBookPlugin.inst(), show);
        }

        private class FyrestoneInterpreter implements ShowInterpreter {

            Map<String, List<FireworkEffect>> effects = new HashMap<String, List<FireworkEffect>>();
            String currentBuilding = null;
            Location location = BukkitUtil.toSign(getSign()).getLocation();
            float duration = 0.5f;
            boolean preciseDuration = false;
            FireworkEffect.Builder builder = FireworkEffect.builder();
            boolean isRunning = false;

            public FyrestoneInterpreter() {
                isRunning = true;
            }

            public FyrestoneInterpreter(Map<String, List<FireworkEffect>> effects, String currentBuilding, Location location, float duration, FireworkEffect.Builder builder) {

                this.effects = effects;
                this.currentBuilding = currentBuilding;
                this.location = location;
                this.duration = duration;
                this.builder = builder;
            }

            @Override
            public void run () {

                while (isRunning && position < lines.size()) {

                    String line = lines.get(position);
                    position++;
                    if (line.trim().startsWith("#") || line.trim().isEmpty())
                        continue;

                    if (line.startsWith("set.")) {

                        if (currentBuilding == null)
                            continue;

                        line = line.replace("set.", "").trim();
                        String[] args = RegexUtil.SPACE_PATTERN.split(line);

                        if (args[0].equalsIgnoreCase("shape")) {

                            FireworkEffect.Type type;
                            if (args[1].equalsIgnoreCase("sball") || args[1].equalsIgnoreCase("smallball"))
                                type = FireworkEffect.Type.BALL;
                            else if (args[1].equalsIgnoreCase("lball") || args[1].equalsIgnoreCase("largeball"))
                                type = FireworkEffect.Type.BALL_LARGE;
                            else if (args[1].equalsIgnoreCase("burst"))
                                type = FireworkEffect.Type.BURST;
                            else if (args[1].equalsIgnoreCase("creeper"))
                                type = FireworkEffect.Type.CREEPER;
                            else if (args[1].equalsIgnoreCase("star"))
                                type = FireworkEffect.Type.STAR;
                            else
                                type = FireworkEffect.Type.BALL;
                            builder.with(type);
                        } else if (args[0].equalsIgnoreCase("color")) {

                            String[] rgb = RegexUtil.COMMA_PATTERN.split(args[1]);
                            Color color = org.bukkit.Color.fromRGB(Integer.parseInt(rgb[0]), Integer.parseInt(rgb[1]), Integer.parseInt(rgb[2]));
                            builder.withColor(color);
                        } else if (args[0].equalsIgnoreCase("fade")) {

                            String[] rgb = RegexUtil.COMMA_PATTERN.split(args[1]);
                            Color fade = org.bukkit.Color.fromRGB(Integer.parseInt(rgb[0]), Integer.parseInt(rgb[1]), Integer.parseInt(rgb[2]));
                            builder.withFade(fade);
                        } else if (args[0].equalsIgnoreCase("flicker") || args[0].equalsIgnoreCase("twinkle")) {

                            builder.flicker(true);
                        } else if (args[0].equalsIgnoreCase("trail")) {

                            builder.trail(true);
                        }
                    } else if (line.startsWith("location ")) {

                        double x,y,z;
                        String[] args = RegexUtil.COMMA_PATTERN.split(line.replace("location ", ""));
                        x = Double.parseDouble(args[0]);
                        y = Double.parseDouble(args[1]);
                        z = Double.parseDouble(args[2]);

                        location = BukkitUtil.toSign(getSign()).getLocation().add(x, y, z);
                    } else if (line.startsWith("duration ")) {

                        String[] bits = RegexUtil.SPACE_PATTERN.split(line.replace("duration ", ""));
                        duration = Float.parseFloat(bits[0]);
                        preciseDuration = bits.length > 1 && bits[1].equalsIgnoreCase("precise");
                    } else if (line.startsWith("wait ")) {

                        FyrestoneInterpreter nshow = new FyrestoneInterpreter(effects,currentBuilding,location,duration,builder);
                        nshow.setRunning(isRunning);
                        task = Bukkit.getScheduler().runTaskLater(CraftBookPlugin.inst(), nshow, Long.parseLong(line.replace("wait ", "")));
                        show = nshow;
                        return;
                    } else if (line.startsWith("sound ")) {

                        String[] bits = RegexUtil.SPACE_PATTERN.split(line.replace("sound ", ""));
                        Sound sound = Sound.valueOf(bits[0]);
                        Location sloc = location.clone();
                        float volume = 1.0f,pitch = 1.0f;
                        if(bits.length > 1) {
                            double x,y,z;
                            String[] args = RegexUtil.COMMA_PATTERN.split(bits[1]);
                            x = Double.parseDouble(args[0]);
                            y = Double.parseDouble(args[1]);
                            z = Double.parseDouble(args[2]);

                            sloc = BukkitUtil.toSign(getSign()).getLocation().add(x, y, z);
                            if(bits.length > 2) {
                                volume = Float.parseFloat(bits[2]);
                                if(bits.length > 3)
                                    pitch = Float.parseFloat(bits[3]);
                            }
                        }
                        sloc.getWorld().playSound(sloc, sound, volume, pitch);
                    } else if (line.startsWith("start ")) {

                        currentBuilding = line.replace("start ", "");
                        builder = FireworkEffect.builder();
                    } else if (line.startsWith("build")) {

                        if (currentBuilding == null)
                            continue;
                        if (effects.containsKey(currentBuilding)) {

                            List<FireworkEffect> effectList = effects.get(currentBuilding);
                            effectList.add(builder.build());
                            effects.put(currentBuilding, effectList);
                        } else {
                            List<FireworkEffect> effectList = new ArrayList<FireworkEffect>();
                            effectList.add(builder.build());
                            effects.put(currentBuilding, effectList);
                        }
                        currentBuilding = null;
                    } else if (line.startsWith("launch ")) {

                        if(effects.containsKey(line.replace("launch ", ""))) {

                            if(!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4))
                                continue;
                            final Firework firework = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
                            FireworkMeta meta = firework.getFireworkMeta();
                            for(FireworkEffect effect : effects.get(line.replace("launch ", "")))
                                meta.addEffect(effect);
                            meta.setPower((int) duration * 2);
                            firework.setFireworkMeta(meta);
                            if(preciseDuration)
                                Bukkit.getScheduler().runTaskLater(CraftBookPlugin.inst(), new Runnable() {
                                    @Override
                                    public void run () {
                                        firework.detonate();
                                    }
                                }, (long) (duration*10));
                        }
                    }
                }

                isRunning = false;
            }

            @Override
            public void setRunning (boolean isRunning) {
                this.isRunning = isRunning;
            }

            @Override
            public boolean isRunning () {
                return isRunning;
            }
        }

        private class BasicShowInterpreter implements ShowInterpreter {

            @Override
            public void run() {

                isRunning = true;

                while (isRunning && position < lines.size()) {

                    String line = lines.get(position);
                    position++;
                    if (line.startsWith("#"))
                        continue;

                    String[] bits = RegexUtil.COLON_PATTERN.split(line, 2);
                    if (bits.length < 2)
                        continue;

                    if (bits[0].equalsIgnoreCase("wait")) {
                        BasicShowInterpreter show = new BasicShowInterpreter();
                        task = Bukkit.getScheduler().runTaskLater(CraftBookPlugin.inst(), show,
                                Long.parseLong(bits[1]));
                        return;
                    } else if (bits[0].equalsIgnoreCase("launch")) {

                        String errorLocation = "Unknown";

                        try {
                            String[] data = RegexUtil.SEMICOLON_PATTERN.split(bits[1]);

                            //Offset data (0)
                            errorLocation = "Offset";
                            String[] offset = RegexUtil.COMMA_PATTERN.split(data[0]);
                            Location location = BukkitUtil.toSign(getSign()).getLocation();
                            location.add(Double.parseDouble(offset[0]), Double.parseDouble(offset[1]),
                                    Double.parseDouble(offset[2]));

                            //Duration data (1)
                            errorLocation = "Duration";
                            double duration = Double.parseDouble(data[1]); //1 duration = 1 second.

                            //Shape data (2)
                            errorLocation = "Shape";
                            FireworkEffect.Type type;
                            if (data[2].equalsIgnoreCase("sball") || data[2].equalsIgnoreCase("smallball"))
                                type = FireworkEffect.Type.BALL;
                            else if (data[2].equalsIgnoreCase("lball") || data[2].equalsIgnoreCase("largeball"))
                                type = FireworkEffect.Type.BALL_LARGE;
                            else if (data[2].equalsIgnoreCase("burst"))
                                type = FireworkEffect.Type.BURST;
                            else if (data[2].equalsIgnoreCase("creeper"))
                                type = FireworkEffect.Type.CREEPER;
                            else if (data[2].equalsIgnoreCase("star"))
                                type = FireworkEffect.Type.STAR;
                            else
                                type = FireworkEffect.Type.BALL;

                            //Colour Data (3)
                            errorLocation = "Colour";
                            String[] rgb = RegexUtil.COMMA_PATTERN.split(data[3]);
                            Color colour = org.bukkit.Color.fromRGB(Integer.parseInt(rgb[0]),
                                    Integer.parseInt(rgb[1]), Integer.parseInt(rgb[2]));

                            //Colour Data (4)
                            errorLocation = "Fade";
                            rgb = RegexUtil.COMMA_PATTERN.split(data[4]);
                            Color fade = org.bukkit.Color.fromRGB(Integer.parseInt(rgb[0]), Integer.parseInt(rgb[1]),
                                    Integer.parseInt(rgb[2]));

                            boolean flicker = false;
                            boolean trail = false;

                            if (data.length > 5) {

                                //Shape data (5)
                                errorLocation = "Effects";
                                if (data[5].equalsIgnoreCase("twinkle"))
                                    flicker = true;
                                else if (data[5].equalsIgnoreCase("trail"))
                                    trail = true;
                            }

                            errorLocation = "Creation";

                            FireworkEffect effect = FireworkEffect.builder().with(type).withColor(colour).withFade(fade).flicker(flicker).trail(trail).build();

                            if(!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4))
                                continue;

                            Firework firework = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
                            FireworkMeta meta = firework.getFireworkMeta();
                            meta.addEffect(effect);
                            meta.setPower((int) duration * 2);
                            firework.setFireworkMeta(meta);
                        } catch (Exception e) {
                            CraftBookPlugin.logger().severe("Error occured while doing: " + errorLocation + ". Whilst reading line " + position + " of the firework file " + showName + "!");
                            BukkitUtil.printStacktrace(e);
                        }
                    }
                }

                isRunning = false;
            }

            @Override
            public void setRunning (boolean isRunning) {
                this.isRunning = isRunning;
            }

            @Override
            public boolean isRunning () {
                return isRunning;
            }

            private boolean isRunning = false;
        }
    }

    public interface ShowInterpreter extends Runnable {

        public void setRunning(boolean isRunning);

        public boolean isRunning();
    }
}
TOP

Related Classes of com.sk89q.craftbook.mechanics.ic.gates.world.miscellaneous.ProgrammableFireworkShow$FireworkShowHandler$FyrestoneInterpreter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.