/*
* This file is part of Matter Overdrive
* Copyright (c) 2015., Simeon Radivoev, All rights reserved.
*
* Matter Overdrive 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.
*
* Matter Overdrive 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 Matter Overdrive. If not, see <http://www.gnu.org/licenses>.
*/
package matteroverdrive.tile;
import cpw.mods.fml.relauncher.Side;
import matteroverdrive.Reference;
import matteroverdrive.api.inventory.UpgradeTypes;
import matteroverdrive.api.weapon.IWeaponColor;
import matteroverdrive.data.BlockPos;
import matteroverdrive.data.Inventory;
import matteroverdrive.data.inventory.ModuleSlot;
import matteroverdrive.data.inventory.TeleportFlashDriveSlot;
import matteroverdrive.entity.monster.EntityMeleeRougeAndroidMob;
import matteroverdrive.entity.monster.EntityRangedRogueAndroidMob;
import matteroverdrive.entity.monster.EntityRougeAndroidMob;
import matteroverdrive.items.TransportFlashDrive;
import matteroverdrive.machines.MOTileEntityMachine;
import matteroverdrive.machines.MachineNBTCategory;
import matteroverdrive.machines.configs.ConfigPropertyInteger;
import matteroverdrive.machines.configs.ConfigPropertyString;
import matteroverdrive.util.WeaponHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import java.util.*;
/**
* Created by Simeon on 12/10/2015.
*/
public class TileEntityAndroidSpawner extends MOTileEntityMachine
{
public int FLASH_DRIVE_SLOT_START;
public static final int FLASH_DRIVE_COUNT = 6;
public int COLOR_MODULE_SLOT;
private Set<EntityRougeAndroidMob> spawnedAndroids;
public TileEntityAndroidSpawner()
{
super(0);
spawnedAndroids = new HashSet<>();
playerSlotsMain = true;
playerSlotsHotbar = true;
}
protected void RegisterSlots(Inventory inventory)
{
COLOR_MODULE_SLOT = inventory.AddSlot(new ModuleSlot(true,Reference.MODULE_COLOR,null));
TeleportFlashDriveSlot slot = new TeleportFlashDriveSlot(false);
slot.setKeepOnDismante(true);
FLASH_DRIVE_SLOT_START = inventory.AddSlot(slot);
for (int i = 0;i < FLASH_DRIVE_COUNT-1;i++)
{
slot = new TeleportFlashDriveSlot(false);
slot.setKeepOnDismante(true);
inventory.AddSlot(slot);
}
super.RegisterSlots(inventory);
}
@Override
public void updateEntity()
{
super.updateEntity();
if (!worldObj.isRemote)
{
if (isActive())
{
if (getSpawnDelay() == 0 || worldObj.getTotalWorldTime() % getSpawnDelay() == 0)
{
for (int i = spawnedAndroids.size(); i < getMaxSpawnCount(); ++i)
{
EntityRougeAndroidMob entity;
if (random.nextInt(10) < 3)
{
entity = new EntityMeleeRougeAndroidMob(worldObj);
}else
{
entity = new EntityRangedRogueAndroidMob(worldObj);
}
double spawnRange = getSpawnRange();
double x = (double) xCoord + MathHelper.clamp_double(worldObj.rand.nextGaussian(),0,1) * spawnRange;
double y = (double) (yCoord + worldObj.rand.nextInt(3) - 1);
double z = (double) zCoord + MathHelper.clamp_double(worldObj.rand.nextGaussian(),0,1) * spawnRange;
int topY = worldObj.getHeightValue((int)x,(int)z);
topY = Math.min(topY,yCoord+3);
entity.setLocationAndAngles(x, topY, z, worldObj.rand.nextFloat() * 360.0F, 0.0F);
if (entity.getCanSpawnHere(true,true,true))
{
entity.onSpawnWithEgg((IEntityLivingData) null);
entity.setSpawnerPosition(new BlockPos(this));
entity.func_110163_bv();
addSpawnedAndroid(entity);
worldObj.playAuxSFX(2004, xCoord, yCoord, zCoord, 0);
ScorePlayerTeam team = getTeam();
if (team != null)
{
entity.setTeam(team);
if (inventory.getStackInSlot(COLOR_MODULE_SLOT) != null && inventory.getStackInSlot(COLOR_MODULE_SLOT).getItem() instanceof IWeaponColor)
{
entity.setVisorColor(((IWeaponColor) inventory.getStackInSlot(COLOR_MODULE_SLOT).getItem()).getColor(inventory.getStackInSlot(COLOR_MODULE_SLOT), null));
if (entity.getHeldItem() != null)
{
WeaponHelper.setModuleAtSlot(Reference.MODULE_COLOR, entity.getHeldItem(), inventory.getStackInSlot(COLOR_MODULE_SLOT));
}
}
}
this.spawnEntity(entity);
entity.spawnExplosionParticle();
forceSync();
}
}
}
}
}
}
public ScorePlayerTeam getTeam()
{
String teamName= getTeamName();
if (teamName != null && !teamName.isEmpty())
{
return worldObj.getScoreboard().getTeam(teamName);
}
return null;
}
public boolean isTeamValid()
{
String teamName= getTeamName();
if (teamName != null && !teamName.isEmpty())
{
return worldObj.getScoreboard().getTeam(teamName) != null;
}
return true;
}
public void assignPath(EntityRougeAndroidMob androidMob)
{
List<Vec3> paths = new ArrayList<>();
for (int i = FLASH_DRIVE_SLOT_START;i < FLASH_DRIVE_COUNT;i++)
{
ItemStack flashDrive = inventory.getSlot(i).getItem();
if (flashDrive != null && flashDrive.getItem() instanceof TransportFlashDrive)
{
BlockPos position = ((TransportFlashDrive) flashDrive.getItem()).getTraget(flashDrive);
if (position != null)
paths.add(Vec3.createVectorHelper(position.x,position.y,position.z));
}
}
if (paths.size() <= 0)
{
androidMob.setPath(new Vec3[]{Vec3.createVectorHelper(xCoord,yCoord,zCoord)},getSpawnRange());
}else
{
androidMob.setPath(paths.toArray(new Vec3[]{}),getSpawnRange());
}
}
public int getMaxSpawnCount()
{
return configs.getInteger("max_spawn_amount",6);
}
public int getSpawnRange()
{
return configs.getInteger("spawn_range",4);
}
public String getTeamName()
{
return configs.getString("team",null);
}
public int getSpawnDelay(){return configs.getInteger("spawn_delay",300);}
public int getSpawnedCount(){return spawnedAndroids.size();}
@Override
protected void registerComponents()
{
super.registerComponents();
configs.addProperty(new ConfigPropertyInteger("max_spawn_amount","gui.config.spawn_amount",0,32,6));
configs.addProperty(new ConfigPropertyInteger("spawn_range","gui.config.spawn_range",0,32,4));
configs.addProperty(new ConfigPropertyInteger("spawn_delay","gui.config.spawn_delay",0,100000,300));
configs.addProperty(new ConfigPropertyString("team","gui.config.team",""));
}
public EntityRougeAndroidMob spawnEntity(EntityRougeAndroidMob entity)
{
worldObj.spawnEntityInWorld(entity);
return entity;
}
@Override
public void readCustomNBT(NBTTagCompound nbt, EnumSet<MachineNBTCategory> categories)
{
super.readCustomNBT(nbt,categories);
}
@Override
public void writeCustomNBT(NBTTagCompound nbt, EnumSet<MachineNBTCategory> categories, boolean toDisk)
{
super.writeCustomNBT(nbt,categories, toDisk);
}
@Override
public String getSound()
{
return null;
}
@Override
public boolean hasSound()
{
return false;
}
@Override
public boolean getServerActive()
{
return getRedstoneActive() && isTeamValid() && spawnedAndroids.size() <= getMaxSpawnCount();
}
@Override
public float soundVolume()
{
return 0;
}
@Override
protected void onActiveChange()
{
}
@Override
public boolean isAffectedByUpgrade(UpgradeTypes type)
{
return false;
}
@Override
protected void onAwake(Side side)
{
if (side == Side.SERVER)
{
for (Entity entity : (List<Entity>)worldObj.loadedEntityList)
{
if (entity instanceof EntityRougeAndroidMob)
{
if(((EntityRougeAndroidMob) entity).wasSpawnedFrom(this))
{
addSpawnedAndroid((EntityRougeAndroidMob)entity);
assignPath((EntityRougeAndroidMob)entity);
}
}
}
}
}
@Override
public void onAdded(World world, int x, int y, int z)
{
}
@Override
public void onPlaced(World world, EntityLivingBase entityLiving)
{
}
@Override
public void onDestroyed()
{
removeAllAndroids();
}
public void removeAllAndroids()
{
for (EntityRougeAndroidMob androidMob : spawnedAndroids)
{
androidMob.isDead = true;
}
spawnedAndroids.clear();
}
public void addSpawnedAndroid(EntityRougeAndroidMob androidMob)
{
if (!spawnedAndroids.contains(androidMob))
{
spawnedAndroids.add(androidMob);
assignPath(androidMob);
}
}
public void removeAndroid(EntityRougeAndroidMob androidMob)
{
if(spawnedAndroids.remove(androidMob))
{
}
}
}