package net.glowstone.block.state;
import net.glowstone.block.GlowBlock;
import net.glowstone.block.entity.DispenserEntity;
import net.glowstone.dispenser.*;
import net.glowstone.util.InventoryUtil;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.block.Dispenser;
import org.bukkit.entity.Projectile;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.projectiles.BlockProjectileSource;
import org.bukkit.util.Vector;
import java.util.Map;
import java.util.Random;
public class GlowDispenser extends GlowLootableBlock implements Dispenser, BlockProjectileSource {
private static final Random random = new Random();
private static final DispenseBehaviorRegistry dispenseBehaviorRegistry = new DispenseBehaviorRegistry();
public GlowDispenser(GlowBlock block) {
super(block);
}
public static DispenseBehaviorRegistry getDispenseBehaviorRegistry() {
return dispenseBehaviorRegistry;
}
public static void register() {
// register all dispense behaviors
DefaultDispenseBehavior bucketDispenseBehavior = new BucketDispenseBehavior();
getDispenseBehaviorRegistry().putBehavior(Material.WATER_BUCKET, bucketDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.LAVA_BUCKET, bucketDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.BUCKET, new EmptyBucketDispenseBehavior());
getDispenseBehaviorRegistry().putBehavior(Material.FLINT_AND_STEEL, new FlintAndSteelDispenseBehavior());
getDispenseBehaviorRegistry().putBehavior(Material.TNT, new TNTDispenseBehavior());
ArmorDispenseBehavior armorDispenseBehavior = new ArmorDispenseBehavior();
getDispenseBehaviorRegistry().putBehavior(Material.LEATHER_BOOTS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.LEATHER_LEGGINGS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.LEATHER_CHESTPLATE, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.LEATHER_HELMET, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.GOLD_BOOTS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.GOLD_LEGGINGS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.GOLD_CHESTPLATE, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.GOLD_HELMET, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.IRON_BOOTS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.IRON_LEGGINGS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.IRON_CHESTPLATE, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.IRON_HELMET, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.CHAINMAIL_BOOTS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.CHAINMAIL_LEGGINGS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.CHAINMAIL_CHESTPLATE, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.CHAINMAIL_HELMET, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.DIAMOND_BOOTS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.DIAMOND_LEGGINGS, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.DIAMOND_CHESTPLATE, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.DIAMOND_HELMET, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.SKULL_ITEM, armorDispenseBehavior);
getDispenseBehaviorRegistry().putBehavior(Material.PUMPKIN, armorDispenseBehavior);
}
private DispenserEntity getBlockEntity() {
return (DispenserEntity) getBlock().getBlockEntity();
}
@Override
public BlockProjectileSource getBlockProjectileSource() {
return this;
}
@Override
public boolean dispense() {
GlowBlock block = getBlock();
int dispenseSlot = getDispenseSlot();
if (dispenseSlot < 0) {
block.getWorld().playEffect(block.getLocation(), Effect.CLICK1, 0);
return false;
}
ItemStack origItems = getInventory().getItem(dispenseSlot);
DispenseBehavior behavior = getDispenseBehaviorRegistry().getBehavior(origItems.getType());
ItemStack result = behavior.dispense(block, origItems);
getInventory().setItem(dispenseSlot, result);
return true;
}
public int getDispenseSlot() {
return InventoryUtil.getRandomSlot(random, getInventory(), true);
}
public ItemStack placeInDispenser(ItemStack toPlace) {
Inventory inv = getInventory();
Map<Integer, ItemStack> map = inv.addItem(toPlace);
return map.isEmpty() ? null : map.get(0);
}
@Override
public Inventory getInventory() {
return getBlockEntity().getInventory();
}
@Override
public boolean update(boolean force, boolean applyPhysics) {
ItemStack[] contents = getInventory().getContents();
boolean result = super.update(force, applyPhysics);
if (result) {
getBlockEntity().setContents(contents);
getBlockEntity().updateInRange();
}
return result;
}
@Override
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile) {
return launchProjectile(projectile, null);
}
@Override
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity) {
// todo: projectile launching
return null;
}
}