package joshie.progression.criteria.rewards;
import com.google.gson.JsonObject;
import joshie.progression.api.criteria.*;
import joshie.progression.api.special.*;
import joshie.progression.gui.fields.EntityFilterFieldPreview;
import joshie.progression.gui.fields.ItemFilterField;
import joshie.progression.gui.filters.FilterTypeEntity;
import joshie.progression.gui.filters.FilterTypeLocation;
import joshie.progression.helpers.EntityHelper;
import joshie.progression.helpers.MCClientHelper;
import joshie.progression.helpers.StackHelper;
import joshie.progression.lib.WorldLocation;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.apache.commons.lang3.text.WordUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static net.minecraft.util.text.TextFormatting.DARK_GREEN;
@ProgressionRule(name="entity", color=0xFFE599FF)
public class RewardSpawnEntity extends RewardBase implements IInit, ICustomDescription, ICustomTooltip, ICustomWidth, ICustomIcon, IHasFilters, ISpecialFieldProvider, ISpecialJSON {
public List<IFilterProvider> locations = new ArrayList();
public List<IFilterProvider> entities = new ArrayList();
public NBTTagCompound tagValue = new NBTTagCompound();
public int spawnNumberMin = 1;
public int spawnNumberMax = 1;
public String nbtData = "";
protected transient IField field;
protected transient EntityLivingBase entity;
protected transient int ticker;
public RewardSpawnEntity() {
field = new ItemFilterField("locations", this);
}
@Override
public void init(boolean isClient) {
tagValue = StackHelper.getTag(new String[] { nbtData }, 0);
}
@Override
public String getDescription() {
return format(spawnNumberMin, spawnNumberMax) + " \n" + field.getField();
}
@Override
public void addTooltip(List list) {
list.add(DARK_GREEN + format(spawnNumberMin, spawnNumberMax));
list.addAll(Arrays.asList(WordUtils.wrap((String)field.getField(), 28).split("\r\n")));
if (entity != null) {
list.add("---");
list.add(entity.getName());
}
}
@Override
public int getWidth(DisplayMode mode) {
return mode == DisplayMode.DISPLAY ? 121: 100;
}
@Override
public ItemStack getIcon() {
return EntityHelper.getItemForEntity(getEntity());
}
@Override
public List<IFilterProvider> getAllFilters() {
ArrayList<IFilterProvider> all = new ArrayList();
all.addAll(locations);
all.addAll(entities);
return all;
}
@Override
public IFilterType getFilterForField(String fieldName) {
if (fieldName.equals("locations")) return FilterTypeLocation.INSTANCE;
if (fieldName.equals("entities")) return FilterTypeEntity.INSTANCE;
return null;
}
@Override
public void addSpecialFields(List<IField> fields, DisplayMode mode) {
if (mode == DisplayMode.EDIT) {
fields.add(new ItemFilterField("locations", this));
fields.add(new ItemFilterField("entities", this));
} else fields.add(new EntityFilterFieldPreview("entities", this, 45, 70, 2.8F));
}
@Override
public void reward(EntityPlayerMP player) {
if (player != null) {
int random = Math.max(0, (spawnNumberMax - spawnNumberMin));
int additional = 0;
if (random != 0) {
additional = player.worldObj.rand.nextInt(random + 1);
}
int spawnNumber = spawnNumberMin + additional;
for (int i = 0; i < spawnNumber; i++) {
boolean notspawned = true;
for (int j = 0; j < 10 && notspawned; j++) {
WorldLocation location = WorldLocation.getRandomLocationFromFilters(locations, player);
if (location != null) {
BlockPos pos = new BlockPos(location.pos);
if (player.worldObj.isBlockLoaded(pos)) {
if (isValidLocation(player.worldObj, pos)) {
pos = pos.up();
notspawned = false;
//Now that we have a random location, let's grab a random Entity
IFilter filter = EntityHelper.getFilter(entities, player);
if (filter != null) {
List<EntityLivingBase> entities = (List<EntityLivingBase>) filter.getRandom(player);
for (EntityLivingBase entity : entities) {
EntityLivingBase clone = EntityHelper.clone(player.worldObj, entity, tagValue, filter);
clone.setLocationAndAngles(pos.getX(), pos.getY(), pos.getZ(), player.worldObj.rand.nextFloat() * 360.0F, 0.0F);
player.worldObj.spawnEntityInWorld(clone);
player.worldObj.playEvent(2004, pos, 0);
if (clone instanceof EntityLiving) {
((EntityLiving) clone).spawnExplosionParticle();
}
}
}
}
}
}
}
}
}
}
@Override
public boolean onlySpecial() {
return false;
}
@Override
public void readFromJSON(JsonObject data) {
if (data.get("spawnNumber") != null) {
spawnNumberMin = data.get("spawnNumber").getAsInt();
spawnNumberMax = data.get("spawnNumber").getAsInt();
}
}
@Override
public void writeToJSON(JsonObject object) {}
//Helper Methods
private boolean isValidLocation(World world, BlockPos pos) {
IBlockState floorState = world.getBlockState(pos);
IBlockState feetState = world.getBlockState(pos.up());
IBlockState headState = world.getBlockState(pos.up(2));
Material floor = floorState.getBlock().getMaterial(floorState);
Material feet = feetState.getBlock().getMaterial(feetState);
Material head = headState.getBlock().getMaterial(headState);
if (feet.blocksMovement()) return false;
if (head.blocksMovement()) return false;
if (floor.isLiquid() || feet.isLiquid() || head.isLiquid()) return false;
return floor.blocksMovement();
}
private EntityLivingBase getEntity() {
if (ticker >= 200 || ticker == 0) {
entity = EntityHelper.getRandomEntityFromFilters(entities, MCClientHelper.getPlayer());
ticker = 1;
}
if (!GuiScreen.isShiftKeyDown()) ticker++;
return entity != null ? entity : MCClientHelper.getPlayer();
}
}