/* * This file is part of Skript. * * Skript is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Skript is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Skript. If not, see <http://www.gnu.org/licenses/>. * * * Copyright 2011-2014 Peter Güttinger * */ package ch.njol.skript.classes.data; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.CraftingInventory; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.potion.PotionEffectType; import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.aliases.ItemType; import ch.njol.skript.bukkitutil.PlayerUtils; import ch.njol.skript.classes.Changer; import ch.njol.skript.util.Experience; import ch.njol.util.coll.CollectionUtils; /** * @author Peter Güttinger */ public class DefaultChangers { public DefaultChangers() {} public final static Changer<Entity> entityChanger = new Changer<Entity>() { @SuppressWarnings("unchecked") @Override @Nullable public Class<? extends Object>[] acceptChange(final ChangeMode mode) { switch (mode) { case ADD: return CollectionUtils.array(ItemType[].class, Inventory.class, Experience[].class); case DELETE: return CollectionUtils.array(); case REMOVE: return CollectionUtils.array(PotionEffectType[].class, ItemType[].class, Inventory.class); case REMOVE_ALL: return CollectionUtils.array(PotionEffectType[].class, ItemType[].class); case SET: case RESET: // REMIND reset entity? (unshear, remove held item, reset weapon/armour, ...) return null; } assert false; return null; } @Override public void change(final Entity[] entities, final @Nullable Object[] delta, final ChangeMode mode) { if (delta == null) { for (final Entity e : entities) { if (!(e instanceof Player)) e.remove(); } return; } for (final Entity e : entities) { for (final Object d : delta) { if (d instanceof PotionEffectType) { assert mode == ChangeMode.REMOVE || mode == ChangeMode.REMOVE_ALL; if (!(e instanceof LivingEntity)) continue; ((LivingEntity) e).removePotionEffect((PotionEffectType) d); } else { if (e instanceof Player) { final Player p = (Player) e; if (d instanceof Experience) { p.giveExp(((Experience) d).getXP()); } else if (d instanceof Inventory) { final PlayerInventory invi = p.getInventory(); if (mode == ChangeMode.ADD) { for (final ItemStack i : (Inventory) d) { if (i != null) invi.addItem(i); } } else { invi.removeItem(((Inventory) d).getContents()); } } else if (d instanceof ItemType) { final PlayerInventory invi = p.getInventory(); if (invi == null) continue; if (mode == ChangeMode.ADD) ((ItemType) d).addTo(invi); else if (mode == ChangeMode.REMOVE) ((ItemType) d).removeFrom(invi); else ((ItemType) d).removeAll(invi); } } } } if (e instanceof Player) PlayerUtils.updateInventory((Player) e); } } }; public final static Changer<Player> playerChanger = new Changer<Player>() { @Override @Nullable public Class<? extends Object>[] acceptChange(final ChangeMode mode) { if (mode == ChangeMode.DELETE) return null; return entityChanger.acceptChange(mode); } @Override public void change(final Player[] players, final @Nullable Object[] delta, final ChangeMode mode) { entityChanger.change(players, delta, mode); } }; public final static Changer<Entity> nonLivingEntityChanger = new Changer<Entity>() { @SuppressWarnings("unchecked") @Override @Nullable public Class<Object>[] acceptChange(final ChangeMode mode) { if (mode == ChangeMode.DELETE) return CollectionUtils.array(); return null; } @Override public void change(final Entity[] entities, final @Nullable Object[] delta, final ChangeMode mode) { assert mode == ChangeMode.DELETE; for (final Entity e : entities) { if (e instanceof Player) continue; e.remove(); } } }; public final static Changer<Item> itemChanger = new Changer<Item>() { @SuppressWarnings("unchecked") @Override @Nullable public Class<?>[] acceptChange(final ChangeMode mode) { if (mode == ChangeMode.SET) return CollectionUtils.array(ItemStack.class); return nonLivingEntityChanger.acceptChange(mode); } @Override public void change(final Item[] what, final @Nullable Object[] delta, final ChangeMode mode) { if (mode == ChangeMode.SET) { assert delta != null; for (final Item i : what) i.setItemStack((ItemStack) delta[0]); } else { nonLivingEntityChanger.change(what, delta, mode); } } }; public final static Changer<Inventory> inventoryChanger = new Changer<Inventory>() { @SuppressWarnings("unchecked") @Override @Nullable public Class<? extends Object>[] acceptChange(final ChangeMode mode) { if (mode == ChangeMode.RESET) return null; if (mode == ChangeMode.REMOVE_ALL) return CollectionUtils.array(ItemType[].class); if (mode == ChangeMode.SET) return CollectionUtils.array(ItemType[].class, Inventory.class); return CollectionUtils.array(ItemType[].class, Inventory[].class); } @SuppressWarnings("deprecation") @Override public void change(final Inventory[] invis, final @Nullable Object[] delta, final ChangeMode mode) { for (final Inventory invi : invis) { assert invi != null; switch (mode) { case DELETE: invi.clear(); if (invi instanceof PlayerInventory) { ((PlayerInventory) invi).setArmorContents(new ItemStack[4]); if (((PlayerInventory) invi).getHolder() instanceof Player) { final Player p = (Player) ((PlayerInventory) invi).getHolder(); if (invi.equals(p.getOpenInventory().getBottomInventory())) p.getOpenInventory().setCursor(null); if (p.getOpenInventory().getTopInventory() instanceof CraftingInventory) p.getOpenInventory().getTopInventory().clear(); } } break; case SET: invi.clear(); //$FALL-THROUGH$ case ADD: assert delta != null; for (final Object d : delta) { if (d instanceof Inventory) { for (final ItemStack i : (Inventory) d) { if (i != null) invi.addItem(i); } } else { ((ItemType) d).addTo(invi); } } break; case REMOVE: case REMOVE_ALL: assert delta != null; for (final Object d : delta) { if (d instanceof Inventory) { assert mode == ChangeMode.REMOVE; invi.removeItem(((Inventory) d).getContents()); } else { if (mode == ChangeMode.REMOVE) ((ItemType) d).removeFrom(invi); else ((ItemType) d).removeAll(invi); } } break; case RESET: assert false; } if (invi.getHolder() instanceof Player) { ((Player) invi.getHolder()).updateInventory(); } } } }; public final static Changer<Block> blockChanger = new Changer<Block>() { @SuppressWarnings("unchecked") @Override @Nullable public Class<?>[] acceptChange(final ChangeMode mode) { if (mode == ChangeMode.RESET) return null; // REMIND regenerate? if (mode == ChangeMode.SET) return CollectionUtils.array(ItemType.class); return CollectionUtils.array(ItemType[].class, Inventory[].class); } @SuppressWarnings("deprecation") @Override public void change(final Block[] blocks, final @Nullable Object[] delta, final ChangeMode mode) { for (final Block block : blocks) { assert block != null; switch (mode) { case SET: assert delta != null; ((ItemType) delta[0]).getBlock().setBlock(block, true); break; case DELETE: block.setTypeId(0, true); break; case ADD: case REMOVE: case REMOVE_ALL: assert delta != null; final BlockState state = block.getState(); if (!(state instanceof InventoryHolder)) break; final Inventory invi = ((InventoryHolder) state).getInventory(); if (invi == null) continue; if (mode == ChangeMode.ADD) { for (final Object d : delta) { if (d instanceof Inventory) { for (final ItemStack i : (Inventory) d) { if (i != null) invi.addItem(i); } } else { ((ItemType) d).addTo(invi); } } } else { for (final Object d : delta) { if (d instanceof Inventory) { invi.removeItem(((Inventory) d).getContents()); } else { if (mode == ChangeMode.REMOVE) ((ItemType) d).removeFrom(invi); else ((ItemType) d).removeAll(invi); } } } state.update(); break; case RESET: assert false; } } } }; }