Package com.sk89q.craftbook.mechanics.minecart.blocks

Source Code of com.sk89q.craftbook.mechanics.minecart.blocks.CartDispenser

package com.sk89q.craftbook.mechanics.minecart.blocks;

import java.util.Locale;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.entity.minecart.PoweredMinecart;
import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.event.EventHandler;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;

import com.sk89q.craftbook.mechanics.minecart.events.CartBlockImpactEvent;
import com.sk89q.craftbook.mechanics.minecart.events.CartBlockRedstoneEvent;
import com.sk89q.craftbook.util.EntityUtil;
import com.sk89q.craftbook.util.ItemInfo;
import com.sk89q.craftbook.util.RailUtil;
import com.sk89q.craftbook.util.RedstoneUtil.Power;
import com.sk89q.craftbook.util.SignUtil;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.bukkit.BukkitUtil;

/**
* <p>
* Collects carts when carts pass over an unpowered chest marked as a dispenser; dispenses carts when power flips on
* if no cart is already above the
* dispenser. The dispenser does not impart velocity to dispensed carts, so it is typical to simply place the track
* above the dispenser so as to be at
* an angle.
* </p>
* <p>
* Carts of all types (including powered and storage carts) will be collected by this mechanism,
* but only regular minecarts are dispensed. This may be
* changed in a future version.
* </p>
* <p>
* Dispenser signs which contain "inf" on the third line will collect carts without storing them and create carts
* without requiring them from
* inventory.
* </p>
* <p>
* Note that this is not an exact reimplementation of the mechanics from hmod; this is something new and more
* consistent with other modern cart
* mechanisms.
* </p>
*
* @author hash
*/
public class CartDispenser extends CartBlockMechanism {

    @EventHandler
    public void onCartImpact(CartBlockImpactEvent event) {

        performMechanic(event.getMinecart(), event.getBlocks());
    }

    @EventHandler
    public void onRedstoneImpact(CartBlockRedstoneEvent event) {

        performMechanic(event.getMinecart(), event.getBlocks());
    }

    public void performMechanic(Minecart cart, CartMechanismBlocks blocks) {

        // validate
        if (!blocks.matches(getMaterial())) return;
        if (!blocks.matches("dispenser")) return;

        // detect intentions
        Power pow = isActive(blocks);
        boolean inf = "inf".equalsIgnoreCase(blocks.getSign().getLine(2));

        if(inf) {

            CartType type = CartType.fromString(blocks.getSign().getLine(0));

            // go
            if (cart == null) {
                switch (pow) {
                    case ON:
                        if(!blocks.getSign().getLine(3).toLowerCase(Locale.ENGLISH).contains("collect"))
                            dispense(blocks, null, type);
                        return;
                    case OFF: // power going off doesn't eat a cart unless the cart moves.
                    case NA:
                }
            } else {
                switch (pow) {
                    case ON: // there's already a cart moving on the dispenser so don't spam.
                        return;
                    case OFF:
                    case NA:
                        if(!blocks.getSign().getLine(3).toLowerCase(Locale.ENGLISH).contains("dispense"))
                            collect(cart, null);
                        return;
                }
            }
        } else {
            for (Chest c : RailUtil.getNearbyChests(blocks.base)) {
                Inventory inv = c.getInventory();

                CartType type = CartType.fromString(blocks.getSign().getLine(0));

                // go
                if (cart == null) {
                    switch (pow) {
                        case ON:
                            if(!blocks.getSign().getLine(3).toLowerCase(Locale.ENGLISH).contains("collect"))
                                dispense(blocks, inv, type);
                            return;
                        case OFF: // power going off doesn't eat a cart unless the cart moves.
                        case NA:
                    }
                } else {
                    switch (pow) {
                        case ON: // there's already a cart moving on the dispenser so don't spam.
                            return;
                        case OFF:
                        case NA:
                            if(!blocks.getSign().getLine(3).toLowerCase(Locale.ENGLISH).contains("dispense"))
                                collect(cart, inv);
                            return;
                    }
                }
            }
        }
    }

    /**
     * @param cart the cart to be destroyed/collected
     * @param inv  the inventory to place a cart item in, or null if we don't care.
     */
    private void collect(Minecart cart, Inventory inv) {

        if (cart == null || cart.isDead()) return;
        cart.eject();
        cart.setDamage(9000);
        cart.remove();
        if (inv != null) {
            Material cartType = Material.MINECART;
            if (cart instanceof StorageMinecart)
                cartType = Material.STORAGE_MINECART;
            else if (cart instanceof PoweredMinecart)
                cartType = Material.POWERED_MINECART;
            else if (cart instanceof ExplosiveMinecart)
                cartType = Material.EXPLOSIVE_MINECART;
            else if (cart instanceof HopperMinecart)
                cartType = Material.HOPPER_MINECART;
            inv.addItem(new ItemStack(cartType, 1));
        }
    }

    /**
     * @param blocks nuff said
     * @param inv    the inventory to remove a cart item from, or null if we don't care.
     */
    private void dispense(CartMechanismBlocks blocks, Inventory inv, CartType type) {

        Location location = BukkitUtil.center(blocks.rail.getLocation());

        if(minecartDispenserLegacy) {
            BlockFace direction =  SignUtil.getFront(blocks.sign).getOppositeFace();
            location = blocks.rail.getRelative(direction).getLocation();
        }

        if(minecartDispenserAntiSpam && EntityUtil.isEntityOfTypeInBlock(location.getBlock(), EntityType.MINECART))
            return;

        if (inv != null) {
            if (type.equals(CartType.Minecart)) {
                if (!inv.contains(Material.MINECART)) return;
                inv.removeItem(new ItemStack(Material.MINECART, 1));
            } else if (type.equals(CartType.StorageMinecart)) {
                if (!inv.contains(Material.STORAGE_MINECART)) return;
                inv.removeItem(new ItemStack(Material.STORAGE_MINECART, 1));
            } else if (type.equals(CartType.PoweredMinecart)) {
                if (!inv.contains(Material.POWERED_MINECART)) return;
                inv.removeItem(new ItemStack(Material.POWERED_MINECART, 1));
            } else if (type.equals(CartType.TNTMinecart)) {
                if (!inv.contains(Material.EXPLOSIVE_MINECART)) return;
                inv.removeItem(new ItemStack(Material.EXPLOSIVE_MINECART, 1));
            } else if (type.equals(CartType.HopperMinecart)) {
                if (!inv.contains(Material.HOPPER_MINECART)) return;
                inv.removeItem(new ItemStack(Material.HOPPER_MINECART, 1));
            }
        }
        Minecart cart = blocks.rail.getWorld().spawn(location, type.toClass());
        if(minecartDispenserPropel) {
            BlockFace dir = SignUtil.getBack(blocks.sign);
            Vector vel = new Vector(dir.getModX(), dir.getModY(), dir.getModZ());
            cart.setVelocity(vel.normalize());
        }
    }

    public enum CartType {
        Minecart("Minecart", Minecart.class), StorageMinecart("Storage", StorageMinecart.class),
        PoweredMinecart("Powered", PoweredMinecart.class), TNTMinecart("TNT", ExplosiveMinecart.class), HopperMinecart("Hopper", org.bukkit.entity.minecart.HopperMinecart.class);

        private final Class<? extends Minecart> cl;
        private final String name;

        private CartType(String name, Class<? extends Minecart> cl) {

            this.name = name;
            this.cl = cl;
        }

        public static CartType fromString(String s) {

            for (CartType ct : CartType.values()) {
                if (ct == null) {
                    continue;
                }
                if (ct.name.equalsIgnoreCase(s)) return ct;
            }
            return Minecart; // Default to minecarts
        }

        public Class<? extends Minecart> toClass() {

            return cl;
        }
    }

    @Override
    public String getName() {

        return "Dispenser";
    }

    @Override
    public String[] getApplicableSigns() {

        return new String[] {"Dispenser"};
    }

    boolean minecartDispenserLegacy;
    boolean minecartDispenserAntiSpam;
    boolean minecartDispenserPropel;

    @Override
    public void loadConfiguration (YAMLProcessor config, String path) {

        config.setComment(path + "block", "Sets the block that is the base of the dispenser mechanic.");
        material = new ItemInfo(config.getString(path + "block", "EMERALD_ORE:0"));

        config.setComment(path + "spawn-infront", "Sets whether the minecarts should spawn infront of the mechanic instead of directly above.");
        minecartDispenserLegacy = config.getBoolean(path + "spawn-infront", false);

        config.setComment(path + "check-for-carts", "Sets whether or not the mechanic checks for existing carts before spawning a new one.");
        minecartDispenserAntiSpam = config.getBoolean(path + "check-for-carts", true);

        config.setComment(path + "propel-cart", "Sets whether or not the dispenser propels carts that it spawns.");
        minecartDispenserPropel = config.getBoolean(path + "propel-cart", false);
    }
}
TOP

Related Classes of com.sk89q.craftbook.mechanics.minecart.blocks.CartDispenser

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.