Skip to content

Instantly share code, notes, and snippets.

@matshou
Created October 18, 2016 14:51
Show Gist options
  • Save matshou/3c0509e00dd406e9812cdbae7990617a to your computer and use it in GitHub Desktop.
Save matshou/3c0509e00dd406e9812cdbae7990617a to your computer and use it in GitHub Desktop.
Workaround for not registering EntityItem
package com.yooksi.fierysouls.block;
import javax.annotation.Nullable;
import com.yooksi.fierysouls.entity.item.EntityItemTorch;
import com.yooksi.fierysouls.item.ItemTorch;
import com.yooksi.fierysouls.tileentity.TileEntityTorch;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public abstract class BlockTorch extends net.minecraft.block.BlockTorch
{
/**
* Drop the block as item when harvested by player. <br>
* Called when the player destroys the block by left-clicking it in survival mode. <p>
*
* <i>Note: This method is not triggered in creative mode.</i>
*
* @param worldIn The world instance where the player is harvesting the block
* @param player EntityPlayer harvesting the block
* @param pos Position of the block that's being harvested
* @param state Current state of the block
* @param te TileEntity that belongs to this block
*/
@Override
public void harvestBlock(World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, @Nullable ItemStack stack)
{
player.addStat(StatList.getBlockStats(this));
player.addExhaustion(0.025F);
if (te != null && te instanceof TileEntityTorch)
{
TileEntityTorch torchEntity = (TileEntityTorch)te;
java.util.List<ItemStack> items = new java.util.ArrayList<ItemStack>();
ItemStack itemstack = this.createStackedBlock(state);
if (itemstack != null)
items.add(itemstack);
for (ItemStack item : items)
{
// This is where we pass our custom NBT from TileEntity to the new ItemStack.
if (ItemTorch.isItemTorch(item.getItem(), false) && torchEntity != null)
ItemTorch.createCustomItemNBTFromExisting(item, worldIn, torchEntity.saveDataToPacket());
spawnAsEntity(worldIn, pos, item);
}
}
}
/**
* Will be called when a block beneath the block is broken and the item is forced to drop. <br>
* For regular drops we should use {@link #harvestBlock}.
*/
@Override
public void dropBlockAsItemWithChance(World worldIn, BlockPos pos, IBlockState state, float chance, int fortune)
{
TileEntityTorch teTorch = (TileEntityTorch) TileEntityTorch.findTorchTileEntity(worldIn, pos, true);
if (!worldIn.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe
{
java.util.List<ItemStack> items = getDrops(worldIn, pos, state, fortune);
chance = net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, worldIn, pos, state, fortune, chance, false, harvesters.get());
for (ItemStack item : items)
{
// This is where we pass our custom NBT from TileEntity to the new ItemStack.
if (ItemTorch.isItemTorch(item.getItem(), false) && teTorch != null)
{
ItemTorch.createCustomItemNBTFromExisting(item, worldIn, teTorch.saveDataToPacket());
if (worldIn.rand.nextFloat() <= chance)
spawnAsTorchEntity(worldIn, pos, item);
}
else if (worldIn.rand.nextFloat() <= chance)
spawnAsEntity(worldIn, pos, item);
}
}
}
/**
* A slightly modified version of {@link Block#spawnAsEntity} designed to create <br>
* and spawn our own custom torch entity.
*/
private void spawnAsTorchEntity(World worldIn, BlockPos pos, ItemStack stack)
{
if (!worldIn.isRemote && worldIn.getGameRules().getBoolean("doTileDrops") && !worldIn.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe
{
if (!captureDrops.get())
{
double d0 = (double)(worldIn.rand.nextFloat() * 0.5F) + 0.25D;
double d1 = (double)(worldIn.rand.nextFloat() * 0.5F) + 0.25D;
double d2 = (double)(worldIn.rand.nextFloat() * 0.5F) + 0.25D;
EntityItem entityitem = new EntityItemTorch(worldIn, (double)pos.getX() + d0, (double)pos.getY() + d1, (double)pos.getZ() + d2, stack);
entityitem.setDefaultPickupDelay();
worldIn.spawnEntityInWorld(entityitem);
}
else capturedDrops.get().add(stack);
}
}
}
package com.yooksi.fierysouls.entity.item;
import com.yooksi.fierysouls.block.BlockTorchLight;
import com.yooksi.fierysouls.common.SharedDefines;
import com.yooksi.fierysouls.common.SharedDefines.TorchUpdateType;
import com.yooksi.fierysouls.item.ItemTorch;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
public final class EntityItemTorch extends EntityItem
{
public EntityItemTorch(World worldObj, double posX, double d0, double posZ, ItemStack stack)
{
super(worldObj, posX, d0, posZ, stack);
}
/**
* Called to update the entity's position/logic. <br>
* <i>Gets called only on server for this entity.</i>
*/
@Override
public void onUpdate()
{
super.onUpdate();
final NBTTagCompound itemTagCompound = getEntityItem().getTagCompound();
// TODO: Humidity should speed up item decay (decrease it's lifespan).
// Update only at set intervals to reduce performance hits.
if (!ItemTorch.shouldUpdateItem(itemTagCompound, worldObj.getTotalWorldTime()))
return;
final boolean isTorchLit = ItemTorch.isItemTorchLit(getEntityItem().getItem(), false);
if (isTorchLit && !(worldObj.getBlockState(getPosition()).getBlock() instanceof BlockTorchLight))
BlockTorchLight.createNewTorchLight(this, getPosition());
// Currently we're only updating humidity and not combustion,
// so there is no need to go further if humidity is at maximum value.
if (ItemTorch.getItemHumidity(itemTagCompound) >= SharedDefines.TORCH_HUMIDITY_THRESHOLD)
return;
// Check if the entity is in water first because rain doesn't matter
// if we're submerged in a pool of water anyways.
if (isInWater() /**&& isInsideOfMaterial(Material.water)*/)
{
ItemTorch.extinguishItemTorch(getEntityItem(), this, -1, true);
}
else if (isTorchLit && ItemTorch.updateItemCombustionTime(itemTagCompound, TorchUpdateType.MAIN_UPDATE.getInterval() * -1) < 1)
{
ItemTorch.extinguishItemTorch(getEntityItem(), this, -1, false);
}
else if (worldObj.isRainingAt(getPosition()))
{
if (ItemTorch.updateItemHumidity(itemTagCompound, TorchUpdateType.MAIN_UPDATE.getInterval()) >= SharedDefines.TORCH_HUMIDITY_THRESHOLD)
ItemTorch.extinguishItemTorch(getEntityItem(), this, -1, false);
}
}
/**
* Create a new EntityItemTorch from a stack being tossed <i>(dropped or drag-n-dropped)</i> in the world <br>
* and prepare it for being added in the world as a tossed item by initialize motion data and pickup delay. <p>
*
* <i>The code is a slightly modified copy from <b>EntityPlayer.dropItem</b>.</i>
*
* @param stack ItemStack to create EntityItem from
* @param player EntityPlayer tossing the item in the world
* @return newly created entity item already prepared to be added to the world
*
* @see {@link net.minecraft.entity.player.EntityPlayer#dropItem}
* {@link com.yooksi.fierysouls.common.EventHandler#itemEvent}
*/
public static EntityItemTorch createTossedEntityItem(ItemStack stack, net.minecraft.entity.player.EntityPlayer player)
{
double d0 = player.posY - 0.30000001192092896D + (double)player.getEyeHeight();
EntityItemTorch entityTorch = new EntityItemTorch(player.worldObj, player.posX, d0, player.posZ, stack);
entityTorch.setPickupDelay(40);
java.util.Random rand = new java.util.Random();
entityTorch.motionX = (double)(-MathHelper.sin(player.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(player.rotationPitch / 180.0F * (float)Math.PI) * 0.3F);
entityTorch.motionZ = (double)(MathHelper.cos(player.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(player.rotationPitch / 180.0F * (float)Math.PI) * 0.3F);
entityTorch.motionY = (double)(-MathHelper.sin(player.rotationPitch / 180.0F * (float)Math.PI) * 0.3F + 0.1F);
float f = 0.02F * rand.nextFloat();
float f1 = rand.nextFloat() * (float)Math.PI * 2.0F;
entityTorch.motionX += Math.cos((double)f1) * (double)f;
entityTorch.motionY += (double)((rand.nextFloat() - rand.nextFloat()) * 0.1F);
entityTorch.motionZ += Math.sin((double)f1) * (double)f;
return entityTorch;
}
}
@SubscribeEvent
public void itemEvent(net.minecraftforge.event.entity.item.ItemTossEvent event)
{
// NOTE: This event gets called only on SERVER.
net.minecraft.item.ItemStack droppedStack = event.getEntityItem().getEntityItem();
boolean isItemCustomTorch = Block.getBlockFromItem(droppedStack.getItem()) instanceof BlockTorch;
if (droppedStack.stackSize > 0 && isItemCustomTorch)
{
if (!droppedStack.hasTagCompound())
ItemTorch.createCustomItemNBT(droppedStack, event.getEntity().worldObj);
// We're going to create a custom EntityItem and do all the work needed here.
// The entity will then spawn in the world as being tossed in front of the player.
EntityItem entityItemTorch = EntityItemTorch.createTossedEntityItem(droppedStack, event.getPlayer());
event.getEntity().worldObj.spawnEntityInWorld(entityItemTorch);
// We created and added the EntityItem to the world here, override default event action.
event.setCanceled(true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment