Skip to content

Instantly share code, notes, and snippets.

@Daomephsta
Created April 5, 2017 08:22
Show Gist options
  • Save Daomephsta/39338a1dcde34a58edd0f82adcf82674 to your computer and use it in GitHub Desktop.
Save Daomephsta/39338a1dcde34a58edd0f82adcf82674 to your computer and use it in GitHub Desktop.
package net.einsteinsci.betterbeginnings.entity.projectile;
import io.netty.buffer.ByteBuf;
import net.einsteinsci.betterbeginnings.items.ItemKnife;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.init.MobEffects;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
public class EntityThrownKnife extends EntityThrowable implements IEntityAdditionalSpawnData
{
private static final String TAG_THROWN_KNIFE = "ThrownKnife";
private ItemStack knife;
private float baseDamage;
private float force;
private boolean inTerrain;
private BlockPos stuckPos = new BlockPos(-1, -1, -1);
public EntityThrownKnife(World worldIn)
{
super(worldIn);
}
public EntityThrownKnife(World world, EntityLivingBase thrower, ItemStack knife)
{
super(world, thrower);
this.knife = knife.copy();
this.knife.stackSize = 1;
this.baseDamage = ((ItemTool)knife.getItem()).getToolMaterial().getDamageVsEntity() + ItemKnife.BASE_DAMAGE;
}
@Override
protected void onImpact(RayTraceResult mop)
{
switch(mop.typeOfHit)
{
case BLOCK:
if (!inTerrain)
{
doBlockHitEffects(world, mop);
}
BlockPos pos = mop.getBlockPos();
IBlockState state = world.getBlockState(pos);
if(state.getBlock().canCollideCheck(state, false))
{
this.inTerrain = true;
this.stuckPos = pos;
this.setVelocity(0.0F, 0.0F, 0.0F);
}
break;
case ENTITY:
if(mop.entityHit instanceof EntityLivingBase && mop.entityHit != this.getThrower())
{
EntityLivingBase entityLiving = (EntityLivingBase) mop.entityHit;
if(!world.isRemote && !knife.attemptDamageItem(2, rand))
{
entityLiving.attackEntityFrom(DamageSource.causeThrownDamage(mop.entityHit, this.getThrower()), baseDamage * force);
entityLiving.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, (int) (100 * force), 2, false, false));
}
}
break;
default:
break;
}
}
@Override
public void onCollideWithPlayer(EntityPlayer playerIn)
{
if(inTerrain && playerIn.inventory.addItemStackToInventory(this.knife))
{
this.setDead();
}
}
@Override
public void onUpdate()
{
IBlockState stuck = world.getBlockState(this.stuckPos);
if(stuck.getCollisionBoundingBox(world, stuckPos) == Block.NULL_AABB)
{
this.inTerrain = false;
}
if(!inTerrain)
{
super.onUpdate();
}
world.spawnParticle(EnumParticleTypes.FIREWORKS_SPARK, this.posX, this.posY, this.posZ, 0.0F, 1.0F, 0.0F);
}
private void doBlockHitEffects(World world, RayTraceResult mop)
{
IBlockState state = world.getBlockState(mop.getBlockPos());
for(int p = 0; p < 8; p ++)
{
world.spawnParticle(EnumParticleTypes.BLOCK_CRACK, this.posX, this.posY, this.posZ, 0.0F, 0.0F, 0.0F, Block.getStateId(state));
}
world.playSound(this.posX, this.posY, this.posZ, state.getBlock().getSoundType(state, world, mop.getBlockPos(), this).getStepSound(), SoundCategory.NEUTRAL, 0.8F, 0.9F, false);
}
@Override
public void readEntityFromNBT(NBTTagCompound tagCompound)
{
super.readEntityFromNBT(tagCompound);
knife = ItemStack.loadItemStackFromNBT(tagCompound.getCompoundTag(TAG_THROWN_KNIFE));
}
@Override
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
super.writeEntityToNBT(tagCompound);
if(knife != null)
{
NBTTagCompound thrownKnife = knife.writeToNBT(new NBTTagCompound());
tagCompound.setTag(TAG_THROWN_KNIFE, thrownKnife);
}
}
public ItemStack getKnife()
{
return knife;
}
public EntityThrownKnife setForce(float force)
{
this.force = force;
return this;
}
@Override
public void writeSpawnData(ByteBuf additionalData)
{
ByteBufUtils.writeItemStack(additionalData, knife);
additionalData.writeFloat(baseDamage);
additionalData.writeFloat(force);
}
@Override
public void readSpawnData(ByteBuf additionalData)
{
knife = ByteBufUtils.readItemStack(additionalData);
baseDamage = additionalData.readFloat();
force = additionalData.readFloat();
}
}
package net.einsteinsci.betterbeginnings.items;
import java.util.HashSet;
import java.util.Set;
import net.einsteinsci.betterbeginnings.entity.projectile.EntityThrownKnife;
//Disable throwing knives due to desync issues
//import net.einsteinsci.betterbeginnings.entity.projectile.EntityThrownKnife;
import net.einsteinsci.betterbeginnings.register.IBBName;
import net.einsteinsci.betterbeginnings.util.Prep1_11;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.*;
import net.minecraft.util.*;
import net.minecraft.world.World;
public abstract class ItemKnife extends ItemTool implements IBBName
{
public static final float BASE_DAMAGE = 1.0f;
public static final float SPEED = -2.2f;
public static final int DRAW_TIME = 32;
public ItemKnife(ToolMaterial material)
{
super(BASE_DAMAGE, SPEED, material, getBreakable());
}
public static Set<Block> getBreakable()
{
Set<Block> s = new HashSet<Block>();
s.add(Blocks.PUMPKIN);
s.add(Blocks.LIT_PUMPKIN);
s.add(Blocks.MELON_BLOCK);
s.add(Blocks.CLAY);
s.add(Blocks.GRASS);
s.add(Blocks.MYCELIUM);
s.add(Blocks.LEAVES);
s.add(Blocks.LEAVES2);
s.add(Blocks.BROWN_MUSHROOM_BLOCK);
s.add(Blocks.RED_MUSHROOM_BLOCK);
s.add(Blocks.GLASS);
s.add(Blocks.GLASS_PANE);
s.add(Blocks.SOUL_SAND);
s.add(Blocks.STAINED_GLASS);
s.add(Blocks.STAINED_GLASS_PANE);
s.add(Blocks.CACTUS);
return s;
}
@Override
public ActionResult<ItemStack> onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand)
{
//Disable throwing knives due to desync issues
player.setActiveHand(hand);
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack);
}
@Override
public void onPlayerStoppedUsing(ItemStack stack, World worldIn, EntityLivingBase entityLiving, int timeLeft)
{
//Disable throwing knives due to desync issues
if(entityLiving instanceof EntityPlayer && !((EntityPlayer)entityLiving).capabilities.isCreativeMode)
{
entityLiving.setHeldItem(entityLiving.getActiveHand(), Prep1_11.getEmptyStack());
}
if(!worldIn.isRemote)
{
EntityThrownKnife knife = new EntityThrownKnife(worldIn, entityLiving, stack);
knife.setForce((float) Math.min((this.getMaxItemUseDuration(stack) - timeLeft), ItemKnife.DRAW_TIME) / ItemKnife.DRAW_TIME);
knife.setHeadingFromThrower(entityLiving, entityLiving.rotationPitch, entityLiving.rotationYaw, 0.0F, 1.5F, 1.0F);
worldIn.spawnEntity(knife);
}
}
@Override
public EnumAction getItemUseAction(ItemStack stack)
{
return EnumAction.BOW;
}
@Override
public int getMaxItemUseDuration(ItemStack stack)
{
return 72000;
}
@Override
public boolean shouldRotateAroundWhenRendering()
{
return true;
}
@Override
public int getHarvestLevel(ItemStack stack, String toolClass)
{
return toolMaterial.getHarvestLevel();
}
@Override
public Set<String> getToolClasses(ItemStack stack)
{
Set<String> res = new HashSet<>();
res.add("knife");
return res;
}
// ...which also requires this...
@Override
public ItemStack getContainerItem(ItemStack itemStack)
{
ItemStack result = itemStack.copy();
result.setItemDamage(itemStack.getItemDamage() + 1);
return result;
}
// Allows durability-based crafting.
@Override
public boolean hasContainerItem(ItemStack stack)
{
return true;
}
@Override
public abstract String getName();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment