/**
* Copyright (c) Lambda Innovation, 2013-2016
* This file is part of the AcademyCraft mod.
* https://github.com/LambdaInnovation/AcademyCraft
* Licensed under GPLv3, see project root for more information.
*/
package cn.academy.vanilla.electromaster.entity;
import cn.academy.core.AcademyCraft;
import cn.academy.core.event.ConfigModifyEvent;
import cn.academy.vanilla.ModuleVanilla;
import cn.academy.vanilla.electromaster.client.renderer.RendererCoinThrowing;
import cn.academy.vanilla.electromaster.item.ItemCoin;
import cn.lambdalib.annoreg.core.Registrant;
import cn.lambdalib.annoreg.mc.RegEntity;
import cn.lambdalib.annoreg.mc.RegEventHandler;
import cn.lambdalib.annoreg.mc.RegEventHandler.Bus;
import cn.lambdalib.annoreg.mc.RegInitCallback;
import cn.lambdalib.s11n.network.NetworkS11n;
import cn.lambdalib.s11n.network.NetworkS11n.ContextException;
import cn.lambdalib.s11n.network.NetworkS11n.NetS11nAdaptor;
import cn.lambdalib.util.entityx.EntityAdvanced;
import cn.lambdalib.util.entityx.MotionHandler;
import cn.lambdalib.util.entityx.handlers.Rigidbody;
import cn.lambdalib.util.generic.RandUtils;
import cn.lambdalib.util.mc.PlayerUtils;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
/**
*
* @author KSkun
*/
@Registrant
@RegEntity
@RegEntity.HasRender
public class EntityCoinThrowing extends EntityAdvanced {
public static boolean PLAY_HEADS_OR_TAILS;
static {
NetworkS11n.addDirect(EntityCoinThrowing.class, new NetS11nAdaptor<EntityCoinThrowing>() {
@Override
public void write(ByteBuf buf, EntityCoinThrowing obj) {
NetworkS11n.serializeWithHint(buf, obj.player, EntityPlayer.class);
}
@Override
public EntityCoinThrowing read(ByteBuf buf) throws ContextException {
return ItemCoin.getPlayerCoin(NetworkS11n.deserializeWithHint(buf, EntityPlayer.class));
}
});
}
double yOffset = 0.6;
private class KeepPosition extends MotionHandler<EntityCoinThrowing> {
public KeepPosition() {}
@Override
public void onUpdate() {
if(EntityCoinThrowing.this.player != null) {
posX = player.posX;
posZ = player.posZ;
if((posY < player.posY && motionY < 0) || ticksExisted > MAXLIFE) {
finishThrowing();
}
}
maxHt = Math.max(maxHt, posY);
}
@Override
public String getID() {
return "kip";
}
@Override
public void onStart() {}
}
@SideOnly(Side.CLIENT)
@RegEntity.Render
public static RendererCoinThrowing renderer;
private static final int MAXLIFE = 120;
private static final double INITVEL = 0.92;
//private EntitySyncer syncer;
//@Synchronized(SyncType.ONCE)
private float initHt;
private double maxHt;
//@Synchronized(SyncType.ONCE)
public EntityPlayer player;
public ItemStack stack;
public Vec3 axis;
public boolean isSync = false;
public EntityCoinThrowing(World world) {
super(world);
isSync = true;
setup();
}
public EntityCoinThrowing(EntityPlayer player, ItemStack is) {
super(player.worldObj);
this.stack = is;
this.player = player;
this.initHt = (float) player.posY;
setPosition(player.posX, player.posY, player.posZ);
this.motionY = player.motionY;
setup();
this.ignoreFrustumCheck = true;
}
@Override
public void onUpdate() {
if (worldObj.isRemote && isSync)
setDead();
//if(!worldObj.isRemote || isSync)
//syncer.update();
//System.out.println(initHt + " " + player + " " + worldObj.isRemote);
super.onUpdate();
}
private void setup() {
Rigidbody rb = new Rigidbody();
rb.gravity = 0.06;
this.addMotionHandler(rb);
this.addMotionHandler(new KeepPosition());
this.motionY += INITVEL;
axis = Vec3.createVectorHelper(.1 + rand.nextDouble(), rand.nextDouble(), rand.nextDouble());
this.setSize(0.2F, 0.2F);
}
void finishThrowing() {
//try merge
if(!worldObj.isRemote && !player.capabilities.isCreativeMode) {
ItemStack equipped = player.getCurrentEquippedItem();
if(equipped == null) {
player.setCurrentItemOrArmor(0, new ItemStack(ModuleVanilla.coin));
} else if(equipped.getItem() == ModuleVanilla.coin && equipped.stackSize < equipped.getMaxStackSize()) {
++equipped.stackSize;
player.inventory.inventoryChanged = true;
} else if(PlayerUtils.mergeStackable(player.inventory, new ItemStack(
ModuleVanilla.coin)) == 0) {
;
} else {
//if fail...
worldObj.spawnEntityInWorld(new EntityItem(worldObj, player.posX, player.posY
+ yOffset, player.posZ, new ItemStack(ModuleVanilla.coin)));
}
}
if (worldObj.isRemote && PLAY_HEADS_OR_TAILS) {
player.addChatComponentMessage(new ChatComponentTranslation(
"ac.headsOrTails." + RandUtils.nextInt(2)));
}
setDead();
}
public double getProgress() {
if(motionY > 0) { //Throwing up
return (INITVEL - motionY) / INITVEL * 0.5;
} else {
return Math.min(1.0, 0.5 + ((maxHt - posY) / (maxHt - initHt)) * 0.5);
}
}
@Override
public void entityInit() {
//syncer = new EntitySyncer(this);
//syncer.init();
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
setDead();
worldObj.spawnEntityInWorld(new EntityItem(worldObj, posX, posY, posZ, new ItemStack(
ModuleVanilla.coin)));
}
@Override
protected void readEntityFromNBT(NBTTagCompound p_70037_1_) {
}
@Override
protected void writeEntityToNBT(NBTTagCompound p_70014_1_) {
}
@Registrant
public enum EventListener {
@RegEventHandler(Bus.Forge)
instance;
@RegInitCallback
private static void init() {
PLAY_HEADS_OR_TAILS = AcademyCraft.config.getBoolean("headsOrTails",
"generic", false, "Show heads or tails after throwing a coin.");
}
@SubscribeEvent
public void onConfigModified(ConfigModifyEvent e) {
PLAY_HEADS_OR_TAILS = AcademyCraft.config.getBoolean("headsOrTails",
"generic", false, "Show heads or tails after throwing a coin.");
}
}
}