/**
* Copyright (c) Lambda Innovation, 2013-2015
* 本作品版权由Lambda Innovation所有。
* http://www.li-dev.cn/
*
* This project is open-source, and it is distributed under
* the terms of GNU General Public License. You can modify
* and distribute freely as long as you follow the license.
* 本项目是一个开源项目,且遵循GNU通用公共授权协议。
* 在遵照该协议的情况下,您可以自由传播和修改。
* http://www.gnu.org/licenses/gpl.html
*/
package cn.dawn47.mob.block;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cn.annoreg.core.Registrant;
import cn.annoreg.mc.RegInit;
import cn.annoreg.mc.RegTileEntity;
import cn.annoreg.mc.network.RegNetworkCall;
import cn.annoreg.mc.s11n.StorageOption;
import cn.annoreg.mc.s11n.StorageOption.Data;
import cn.dawn47.core.proxy.DWResources;
import cn.dawn47.mob.client.render.RendererSpore;
import cn.dawn47.mob.entity.EntityDrone;
import cn.liutils.entityx.handlers.Rigidbody;
import cn.liutils.render.particle.Particle;
import cn.liutils.render.particle.ParticleFactory;
import cn.liutils.util.generic.RandUtils;
import cn.liutils.util.generic.VecUtils;
import cn.liutils.util.helper.BlockPos;
import cn.liutils.util.mc.EntitySelectors;
import cn.liutils.util.mc.IBlockFilter;
import cn.liutils.util.mc.WorldUtils;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* @author WeAthFolD
*
*/
@Registrant
@RegInit(side = RegInit.Side.CLIENT_ONLY)
@RegTileEntity
@RegTileEntity.HasRender
public class TileSpore extends TileEntity {
public int textureID;
public float rot1, rot2;
private boolean released;
private boolean toRelease;
private int ticker = 10;
private int triggerTicker = 3;
private int syncTicker;
static Random r = new Random();
@SideOnly(Side.CLIENT)
static ParticleFactory sporeFactory;
static IBlockFilter sporeFilter = new IBlockFilter() {
@Override
public boolean accepts(World world, int x, int y, int z, Block block) {
return world.getBlock(x, y, z) instanceof BlockSpore;
}
};
@SideOnly(Side.CLIENT)
public static void init() {
Particle template = new Particle();
template.hasLight = true;
template.texture = DWResources.entityTexture("spore");
template.size = 0.06f;
sporeFactory = new ParticleFactory(template);
}
public TileSpore() {
rot1 = RandUtils.rangef(0, 360);
rot2 = RandUtils.rangef(0, 360);
textureID = r.nextInt(2);
}
private void release() {
released = true;
World world = getWorldObj();
if(!world.isRemote) {
double spawnX = xCoord + 0.5,
spawnY = yCoord + 1,
spawnZ = zCoord + 0.5;
EntityDrone drone = new EntityDrone(world);
drone.setPosition(spawnX, spawnY, spawnZ);
world.spawnEntityInWorld(drone);
worldObj.playSoundEffect(spawnX, spawnY, spawnZ, "dawn47:entities.spore", 0.5f, 1.0f);
doClientRelease();
if(!toRelease) {
double range = 3.5;
List<BlockPos> list = WorldUtils.getBlocksWithin(world, spawnX, spawnY, spawnZ, range, 100, sporeFilter);
for(BlockPos bp : list) {
TileEntity te = world.getTileEntity(bp.x, bp.y, bp.z);
if(te instanceof TileSpore) {
((TileSpore) te).triggerRelease();
}
}
}
} else {
releaseClient();
}
}
@SideOnly(Side.CLIENT)
private void releaseClient() {
World world = getWorldObj();
int n = RandUtils.rangei(20, 30);
for(int i = 0; i < n; ++i) {
double yvel = RandUtils.ranged(0.32, 0.48);
double xzvel = RandUtils.ranged(0.08, 0.12);
double theta = RandUtils.ranged(0, Math.PI * 2);
sporeFactory.setPosition(
xCoord + 0.5 + RandUtils.ranged(-0.2, 0.2),
yCoord + 0.2 + RandUtils.ranged(0.1, 0.3),
zCoord + 0.5 + RandUtils.ranged(-0.2, 0.2));
sporeFactory.setVelocity(xzvel * Math.sin(theta), yvel, xzvel * Math.cos(theta));
Particle p = sporeFactory.next(world);
Rigidbody rb = new Rigidbody();
rb.gravity = 0.035;
p.addMotionHandler(rb);
world.spawnEntityInWorld(p);
}
}
public boolean isReleased() {
return released;
}
public void triggerRelease() {
toRelease = true;
}
@Override
public void updateEntity() {
if(--ticker <= 0) {
ticker = 10;
doReleaseCheck();
}
if(!worldObj.isRemote) {
if(++syncTicker == 10) {
syncTicker = 0;
this.receiveUpdate(released);
}
}
if(!released && toRelease && --triggerTicker == 0) {
release();
}
}
private void doReleaseCheck() {
if(!released) {
List<Entity> list = WorldUtils.getEntities(worldObj,
xCoord + .5, yCoord + .7, zCoord + .5,
5, EntitySelectors.survivalPlayer);
if(!list.isEmpty()) {
release();
}
}
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
released = tag.getBoolean("released");
}
@Override
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
tag.setBoolean("released", released);
}
@RegNetworkCall(side = Side.CLIENT, thisStorage = StorageOption.Option.INSTANCE)
public void doClientRelease() {
if(this != null) {
if(!this.released) {
release();
}
}
}
@RegNetworkCall(side = Side.CLIENT, thisStorage = StorageOption.Option.INSTANCE)
public void receiveUpdate(@Data Boolean release) {
if(this != null) {
this.released = release;
}
}
@RegTileEntity.Render
@SideOnly(Side.CLIENT)
public static RendererSpore renderer;
}