/*
* 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.expressions;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import ch.njol.skript.Skript;
import ch.njol.skript.Skript.ExpressionType;
import ch.njol.skript.api.Changer;
import ch.njol.skript.api.Converter;
import ch.njol.skript.api.Converter.ConverterUtils;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.DefaultChangers;
import ch.njol.skript.expressions.ExprAttackerAlt.Attacker;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SimpleExpression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.util.ItemType;
/**
*
* @author Peter Güttinger
*/
public class ExprAttackerAlt extends SimpleExpression<Attacker> {
public static final class Attacker {
private final Object attacker;
public Attacker(final Object attacker) {
this.attacker = attacker;
}
public Object getAttacker() {
return attacker;
}
@Override
public String toString() {
return Skript.toString(attacker);
}
public Inventory getInventory() {
if (getAttacker() instanceof Block) {
final BlockState state = ((Block) getAttacker()).getState();
if (state instanceof InventoryHolder)
return ((InventoryHolder) state).getInventory();
} else if (getAttacker() instanceof InventoryHolder) {
return ((InventoryHolder) getAttacker()).getInventory();
}
return null;
}
}
static {
Skript.registerExpression(ExprAttackerAlt.class, Attacker.class, ExpressionType.SIMPLE, "[the] (attacker|damager)");
Skript.registerClass(new ClassInfo<Attacker>(Attacker.class, "attacker", "attacker")
.changer(new Changer<Attacker, ItemType[]>() {
@Override
public void change(final Attacker[] what, final ItemType[] delta, final ChangeMode mode) {
DefaultChangers.inventoryChanger.change(ConverterUtils.convert(what, new Converter<Attacker, Inventory>() {
@Override
public Inventory convert(final Attacker a) {
return a.getInventory();
}
}, Inventory.class), delta, mode);
}
@Override
public Class<? extends ItemType[]> acceptChange(final ChangeMode mode) {
return DefaultChangers.inventoryChanger.acceptChange(mode);
}
}));
Skript.registerConverter(Attacker.class, Entity.class, new Converter<Attacker, Entity>() {
@Override
public Entity convert(final Attacker a) {
if (a.getAttacker() instanceof Entity)
return (Entity) a.getAttacker();
return null;
}
});
Skript.registerConverter(Attacker.class, Block.class, new Converter<Attacker, Block>() {
@Override
public Block convert(final Attacker a) {
if (a.getAttacker() instanceof Block)
return (Block) a.getAttacker();
return null;
}
});
Skript.registerConverter(Attacker.class, Inventory.class, new Converter<Attacker, Inventory>() {
@Override
public Inventory convert(final Attacker a) {
return a.getInventory();
}
});
Skript.registerConverter(Attacker.class, Location.class, new Converter<Attacker, Location>() {
@Override
public Location convert(final Attacker a) {
if (a.getAttacker() instanceof Block)
return ((Block) a.getAttacker()).getLocation().add(0.5, 0.5, 0.5);
return ((Entity) a.getAttacker()).getLocation();
}
});
}
@Override
public boolean init(final Expression<?>[] vars, final int matchedPattern, final ParseResult parser) {
return true;
}
@Override
protected Attacker[] get(final Event e) {
return new Attacker[] {new Attacker(getAttacker(e))};
}
private static Object getAttacker(final Event e) {
if (e instanceof EntityDamageByEntityEvent) {
if (((EntityDamageByEntityEvent) e).getDamager() instanceof Projectile) {
return ((Projectile) ((EntityDamageByEntityEvent) e).getDamager()).getShooter();
}
return ((EntityDamageByEntityEvent) e).getDamager();
} else if (e instanceof EntityDamageByBlockEvent) {
return ((EntityDamageByBlockEvent) e).getDamager();
} else if (e instanceof EntityDeathEvent) {
return getAttacker(((EntityDeathEvent) e).getEntity().getLastDamageCause());
} else if (e instanceof VehicleDamageEvent) {
return ((VehicleDamageEvent) e).getAttacker();
} else if (e instanceof VehicleDestroyEvent) {
return ((VehicleDestroyEvent) e).getAttacker();
}
return null;
}
@Override
public Class<? extends Attacker> getReturnType() {
return Attacker.class;
}
@Override
public String toString(final Event e, final boolean debug) {
if (e == null)
return "the attacker";
return Skript.getDebugMessage(getSingle(e) == null ? null : getSingle(e).attacker);
}
@Override
public boolean isSingle() {
return true;
}
@Override
public boolean getAnd() {
return true;
}
}