Package com.nitnelave.CreeperHeal.block

Source Code of com.nitnelave.CreeperHeal.block.BurntBlockManager

package com.nitnelave.CreeperHeal.block;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;

import com.nitnelave.CreeperHeal.CreeperHeal;
import com.nitnelave.CreeperHeal.config.CfgVal;
import com.nitnelave.CreeperHeal.config.CreeperConfig;
import com.nitnelave.CreeperHeal.config.WorldConfig;
import com.nitnelave.CreeperHeal.utils.NeighborFire;

/**
* Manager to handle the burnt blocks.
*
* @author nitnelave
*
*/
public abstract class BurntBlockManager
{

    /*
     * The list of burnt blocks waiting to be replaced.
     */
    private static List<CreeperBurntBlock> burntList = new LinkedList<CreeperBurntBlock>();
    /*
     * If the plugin is not in lightweight mode, the list of recently burnt
     * blocks to prevent them from burning again soon.
     */
    private static Map<Location, Date> recentlyBurnt;
    /*
     * If the leaves replacement setting is on, the list of recently burnt
     * blocks for neighbor finding.
     */
    private static NeighborFire fireIndex;

    public static void init()
    {
        if (CreeperConfig.getInt(CfgVal.WAIT_BEFORE_BURN_AGAIN) > 0)
            recentlyBurnt = new HashMap<Location, Date>();
        if (CreeperConfig.getBool(CfgVal.LEAVES_VINES))
            fireIndex = new NeighborFire();

        Bukkit.getScheduler().scheduleSyncRepeatingTask(CreeperHeal.getInstance(), new Runnable()
        {
            @Override
            public void run()
            {
                cleanUp();
            }
        }, 300, 7200);

        Bukkit.getScheduler().runTaskTimer(CreeperHeal.getInstance(), new Runnable()
        {
            @Override
            public void run()
            {
                replaceBurnt();
            }
        }, 0, 20);

    }

    /**
     * Force immediate replacement of all blocks burnt in the specified world
     *
     * @param worldConfig
     *            The world in which to replace the blocks.
     */
    public static void forceReplaceBurnt(WorldConfig worldConfig)
    {
        World world = Bukkit.getServer().getWorld(worldConfig.getName());

        Iterator<CreeperBurntBlock> iter = burntList.iterator();
        int d = CreeperConfig.getInt(CfgVal.WAIT_BEFORE_BURN_AGAIN);
        Date time = new Date(new Date().getTime() + 1000 * d);
        while (iter.hasNext())
        {
            CreeperBurntBlock cBlock = iter.next();
            if (cBlock.getWorld() == world)
            {
                cBlock.replace(true);
                if (d > 0)
                    recentlyBurnt.put(cBlock.getLocation(), time);
                if (CreeperConfig.getBool(CfgVal.LEAVES_VINES))
                    fireIndex.removeElement(cBlock);
                iter.remove();
            }
        }
    }

    /**
     * Force immediate replacement of all blocks burnt.
     */
    public static void forceReplaceBurnt()
    {
        Iterator<CreeperBurntBlock> iter = burntList.iterator();
        int d = CreeperConfig.getInt(CfgVal.WAIT_BEFORE_BURN_AGAIN);
        Date time = new Date(new Date().getTime() + 1000 * d);
        while (iter.hasNext())
            iter.next().replace(true);
        if (d > 0)
        {
            iter = burntList.iterator();
            while (iter.hasNext())
                recentlyBurnt.put(iter.next().getLocation(), time);
        }
        if (CreeperConfig.getBool(CfgVal.LEAVES_VINES))
            fireIndex.clear();
        burntList.clear();
    }

    /**
     * Replace the burnt blocks that have disappeared for long enough.
     */
    private static void replaceBurnt()
    {

        int d = CreeperConfig.getInt(CfgVal.WAIT_BEFORE_BURN_AGAIN);
        Date time = new Date(new Date().getTime() + 1000 * d);
        Iterator<CreeperBurntBlock> iter = burntList.iterator();
        while (iter.hasNext())
        {
            CreeperBurntBlock cBlock = iter.next();
            if (cBlock.checkReplace())
            {
                if (cBlock.wasReplaced())
                {
                    iter.remove();
                    if (d > 0)
                        recentlyBurnt.put(cBlock.getLocation(), time);
                    if (CreeperConfig.getBool(CfgVal.LEAVES_VINES))
                        fireIndex.removeElement(cBlock);
                }
            }
            else
                break;
        }
    }

    /**
     * Record a burnt block.
     *
     * @param block
     *            The block to be recorded.
     */
    public static void recordBurntBlock(Block block)
    {
        CreeperBlock b = CreeperBlock.newBlock(block.getState());
        if (b == null)
            return;

        for (NeighborBlock neighbor : b.getDependentNeighbors())
            if (neighbor.isNeighbor())
                recordBurntBlock(new CreeperBurntBlock(new Date(new Date().getTime() + 100), neighbor.getBlock().getState()));
        recordBurntBlock(new CreeperBurntBlock(new Date(), b));
    }

    /**
     * Add a block to the list of burnt blocks to be replaced, and remove it
     * from the world.
     *
     * @param block
     *            The block to add.
     */
    public static void recordBurntBlock(CreeperBurntBlock block)
    {
        if (block.getBlock() != null)
        {
            burntList.add(block);
            if (CreeperConfig.getBool(CfgVal.LEAVES_VINES))
                fireIndex.addElement(block);
            block.remove();
        }
    }

    /**
     * Get whether the location is close to a recently burnt block.
     *
     * @param location
     *            The location to check.
     * @return Whether the location is close to a recently burnt block.
     */
    public static boolean isNextToFire(Location location)
    {
        if (!CreeperConfig.getBool(CfgVal.LEAVES_VINES))
            return false;
        return fireIndex.hasNeighbor(location);
    }

    /**
     * Get whether there is no recorded blocks to be replaced.
     *
     * @return Whether there is no recorded blocks to be replaced.
     */
    public static boolean isIndexEmpty()
    {
        if (!CreeperConfig.getBool(CfgVal.LEAVES_VINES))
            return false;
        return fireIndex.isEmpty();
    }

    /**
     * Get whether the block was recently burnt and should burn again.
     *
     * @param block
     *            The block.
     * @return Whether the block was recently burnt.
     */
    public static boolean wasRecentlyBurnt(Block block)
    {
        if (CreeperConfig.getInt(CfgVal.WAIT_BEFORE_BURN_AGAIN) <= 0)
            return false;
        Date d = recentlyBurnt.get(block.getLocation());
        return d != null && d.after(new Date());
    }

    /**
     * Clean up the block lists, remove the useless blocks. Do not use when in
     * light weight mode.
     */
    private static void cleanUp()
    {
        if (CreeperConfig.getBool(CfgVal.LEAVES_VINES))
            fireIndex.clean();
        if (CreeperConfig.getInt(CfgVal.WAIT_BEFORE_BURN_AGAIN) > 0)
        {
            Iterator<Location> iter = recentlyBurnt.keySet().iterator();
            Date now = new Date();
            while (iter.hasNext())
            {
                Location l = iter.next();
                Date d = recentlyBurnt.get(l);
                if (d.before(now))
                    iter.remove();
            }
        }

    }

}
TOP

Related Classes of com.nitnelave.CreeperHeal.block.BurntBlockManager

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.