/*
* ReActions, Minecraft bukkit plugin
* (c)2012-2017, fromgate, fromgate@gmail.com
* http://dev.bukkit.org/server-mods/reactions/
*
* This file is part of ReActions.
*
* ReActions 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.
*
* ReActions 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 ReActions. If not, see <http://www.gnorg/licenses/>.
*
*/
package me.fromgate.reactions.util.mob;
import me.fromgate.reactions.ReActions;
import me.fromgate.reactions.externals.RAEffects;
import me.fromgate.reactions.externals.RAWorldGuard;
import me.fromgate.reactions.util.BukkitCompatibilityFix;
import me.fromgate.reactions.util.Locator;
import me.fromgate.reactions.util.Param;
import me.fromgate.reactions.util.Util;
import me.fromgate.reactions.util.item.ItemUtil;
import me.fromgate.reactions.util.message.M;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MobSpawn {
private static Map<LivingEntity, List<ItemStack>> drops = new HashMap<>();
public static void mobSpawn(Player p, Param params) {
String mob = params.getParam("type", "").toUpperCase();
if (mob.isEmpty()) {
M.logMessage("Failed to spawn mob: " + params.getParam("param-line"));
return;
}
String locstr = params.getParam("loc", "");
Location loc = Locator.parseLocation(locstr, p == null ? null : p.getLocation());
String region = params.getParam("region", "");
int radius = params.getParam("radius", 0);
int num = Util.getMinMaxRandom(params.getParam("num", "1"));
String hparam = params.getParam("health", "0");
double health = Util.getMinMaxRandom(hparam);
String playeffect = params.getParam("effect", "");
String dtheffect = params.getParam("dtheffect", "");
String chest = params.getParam("chest", "");
String leg = params.getParam("leg", "");
String helm = params.getParam("helm", "");
String boot = params.getParam("boot", "");
String weapon = params.getParam("weapon", "");
String offhand = params.getParam("offhand", "");
boolean land = params.getParam("land", true);
String poteff = params.getParam("potion", "");
String name = params.getParam("name", "");
String drop = params.getParam("drop", "");
String xp = params.getParam("xp", "");
String money = params.getParam("money", "");
String growl = params.getParam("growl", "");
String cry = params.getParam("cry", "");
String equip = params.getParam("equip", "");
double dmg = params.getParam("dmg", 1.0D);
String exec = params.getParam("run", "");
String exec_delay = params.getParam("rundelay", "1t");
if (RAWorldGuard.isRegionExists(region)) loc = Locator.getRegionLocation(region, land);
else if (radius > 0) loc = Locator.getRadiusLocation(loc, radius, land);
if (loc == null) return;
for (int i = 0; i < num; i++) {
List<LivingEntity> mobs = spawnMob(loc, mob);
for (LivingEntity le : mobs) {
setMobHealth(le, health);
setMobName(le, name);
potionEffect(le, poteff);
if (equip.isEmpty()) setMobEquipment(le, helm, chest, leg, boot, weapon, offhand);
else setMobEquipment(le, equip);
setMobDrop(le, drop);
setMobXP(le, xp);
setMobMoney(le, money);
setMobExec(le, exec, exec_delay);
setMobDmgMultiplier(le, dmg);
setMobGrowl(le, growl);
setMobCry(le, cry);
setDeathEffect(le, dtheffect);
}
playMobEffect(loc, playeffect);
}
}
@SuppressWarnings("deprecation")
private static List<LivingEntity> spawnMob(Location loc, String mobstr) {
List<LivingEntity> mobs = new ArrayList<>();
String[] ln = mobstr.split(":");
if (ln.length < 1) return mobs;
for (int i = 0; i < Math.min(2, ln.length); i++) {
String mbs = ln[i];
String name = "";
if (mbs.contains("$")) {
name = mbs.substring(0, mbs.indexOf("$"));
mbs = mbs.substring(name.length() + 1);
}
EntityType et = EntityType.fromName(mbs);
if (mbs.equalsIgnoreCase("horse")) et = MobHorse.getHorseType();
if (mbs.equalsIgnoreCase("wither")) et = MobWither.getWitherType();
if (et == null) {
M.logOnce("mobspawnunknowntype_" + mobstr, "Unknown mob type " + mbs + " (" + mobstr + ")");
continue;
}
Entity e = loc.getWorld().spawnEntity(loc, et);
if (e == null) {
M.logOnce("mobspawnfail_" + mobstr, "Cannot spawn mob " + mbs + " (" + mobstr + ")");
continue;
}
if (!(e instanceof LivingEntity)) {
e.remove();
M.logOnce("mobspawnnotmob_" + mobstr, "Cannot spawn mob " + mbs + " (" + mobstr + ")");
continue;
}
LivingEntity mob = (LivingEntity) e;
setMobName(mob, name);
mobs.add(mob);
}
if (mobs.size() == 2) mobs.get(1).setPassenger(mobs.get(0));
return mobs;
}
public static void playMobEffect(Location loc, String playeffect) {
if (playeffect.isEmpty()) return;
int data = 0;
if (playeffect.equalsIgnoreCase("smoke")) data = 9;
RAEffects.playEffect(loc, playeffect, data);
}
public static void setMobName(LivingEntity e, String name) {
if (name.isEmpty()) return;
if ((e.getCustomName() != null) && (!e.getCustomName().isEmpty())) return;
e.setCustomName(ChatColor.translateAlternateColorCodes('&', name.replace("_", " ")));
e.setCustomNameVisible(true);
}
public static void setMobXP(LivingEntity e, String xp) {
if (xp.isEmpty()) return;
e.setMetadata("ReActions-xp", new FixedMetadataValue(ReActions.instance, xp));
}
public static void setMobMoney(LivingEntity e, String money) {
if (money.isEmpty()) return;
e.setMetadata("ReActions-money", new FixedMetadataValue(ReActions.instance, money));
}
public static void setMobExec(LivingEntity e, String exec_activator, String exec_delay) {
if (exec_activator.isEmpty()) return;
e.setMetadata("ReActions-activator", new FixedMetadataValue(ReActions.instance, "activator:" + exec_activator + (exec_delay.isEmpty() ? "" : " delay:" + exec_delay)));
}
public static void setMobDrop(LivingEntity e, String drop) {
//id:data*amount,id:dat*amount%chance;id:data*amount;id:dat*amount%chance;id:data*amount;id:dat*amount%chance
if (drop.isEmpty()) return;
List<ItemStack> stack = ItemUtil.parseRandomItemsStr(drop);
if (stack.isEmpty()) return;
setMobDropStack(e, stack);
}
private static void setMobDmgMultiplier(LivingEntity e, double dmg) {
if (dmg < 0) return;
e.setMetadata("ReActions-dmg", new FixedMetadataValue(ReActions.instance, dmg));
}
private static void setMobCry(LivingEntity e, String cry) {
if (cry.isEmpty()) return;
e.setMetadata("ReActions-cry", new FixedMetadataValue(ReActions.instance, cry));
}
private static void setMobGrowl(LivingEntity e, String growl) {
if (growl.isEmpty()) return;
e.setMetadata("ReActions-growl", new FixedMetadataValue(ReActions.instance, growl));
}
public static void setMobDropStack(LivingEntity e, List<ItemStack> stack) {
if (stack.isEmpty()) return;
drops.put(e, stack);
//e.setMetadata("ReActions-drop", new FixedMetadataValue(ReActions.instance, stack));
}
private static void setDeathEffect(LivingEntity e, String dtheffect) {
if (dtheffect.isEmpty()) return;
e.setMetadata("ReActions-deatheffect", new FixedMetadataValue(ReActions.instance, dtheffect));
}
public static void setMobHealth(LivingEntity e, double health) {
if (health > 0) {
if (health > BukkitCompatibilityFix.getEntityHealth(e))
BukkitCompatibilityFix.setEntityMaxHealth(e, health);
BukkitCompatibilityFix.setEntityHealth(e, health);
}
}
public static void setMobEquipment(LivingEntity e, String equip) {
if (equip.isEmpty()) return;
if (!Util.isWordInList(e.getType().name(), "zombie,skeleton")) return;
String[] ln = equip.split(";");
if (ln.length == 0) return;
String[] eq = {"", "", "", "", "", ""};
for (int i = 0; i < Math.min(ln.length, 6); i++) eq[i] = ln[i];
setMobEquipment(e, eq[0], eq[1], eq[2], eq[3], eq[4], eq[5]);
}
public static void setMobEquipment(LivingEntity e, String helm, String chest, String leg, String boot, String weapon, String offhand) {
// if (!Util.isWordInList(e.getType().name(), "zombie,skeleton,villager")) return;
if (!helm.isEmpty()) {
ItemStack item = ItemUtil.getRndItem(helm);
if (item != null) e.getEquipment().setHelmet(item);
}
if (!chest.isEmpty()) {
ItemStack item = ItemUtil.getRndItem(chest);
if (item != null) e.getEquipment().setChestplate(item);
}
if (!leg.isEmpty()) {
ItemStack item = ItemUtil.getRndItem(leg);
if (item != null) e.getEquipment().setLeggings(item);
}
if (!boot.isEmpty()) {
ItemStack item = ItemUtil.getRndItem(boot);
if (item != null) e.getEquipment().setBoots(item);
}
if (!weapon.isEmpty()) {
ItemStack item = ItemUtil.getRndItem(weapon);
if (item != null) BukkitCompatibilityFix.setItemInHand(e, item);
}
if (!offhand.isEmpty()) {
ItemStack item = ItemUtil.getRndItem(offhand);
if (item != null) BukkitCompatibilityFix.setItemInOffHand(e, item);
}
}
public static void potionEffect(LivingEntity e, String potion) {
if (potion.isEmpty()) return;
String[] pts = potion.split(",");
for (String pot : pts) {
String pef;
int level = 1;
String[] ln = pot.split(":");
pef = ln[0];
PotionEffectType pet = Util.parsePotionEffect(pef);
if (pet == null) continue;
if ((ln.length == 2) && Util.isInteger(ln[1])) level = Integer.parseInt(ln[1]);
PotionEffect pe = new PotionEffect(pet, Integer.MAX_VALUE, level, true);
e.addPotionEffect(pe);
}
}
public static List<ItemStack> getMobDrop(LivingEntity le) {
if (drops.containsKey(le)) {
List<ItemStack> drop = drops.get(le);
drops.remove(le);
return drop;
} else {
List<LivingEntity> deadMobs = new ArrayList<>();
for (LivingEntity l : drops.keySet())
if (l.isDead()) deadMobs.add(l);
for (LivingEntity l : deadMobs)
drops.remove(l);
}
return null;
}
}