package blusunrize.immersiveengineering.common.items; import blusunrize.immersiveengineering.api.Lib; import blusunrize.immersiveengineering.api.tool.BulletHandler; import blusunrize.immersiveengineering.api.tool.BulletHandler.IBullet; import blusunrize.immersiveengineering.client.ClientProxy; import blusunrize.immersiveengineering.common.Config.IEConfig; import blusunrize.immersiveengineering.common.entities.EntityRevolvershot; import blusunrize.immersiveengineering.common.entities.EntityRevolvershotFlare; import blusunrize.immersiveengineering.common.entities.EntityRevolvershotHoming; import blusunrize.immersiveengineering.common.entities.EntityWolfpackShot; import blusunrize.immersiveengineering.common.items.IEItemInterfaces.IColouredItem; import blusunrize.immersiveengineering.common.items.IEItemInterfaces.ITextureOverride; import blusunrize.immersiveengineering.common.util.IEDamageSources; import blusunrize.immersiveengineering.common.util.ItemNBTHelper; import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4; import net.minecraft.client.gui.FontRenderer; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityAreaEffectCloud; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.*; import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionType; import net.minecraft.potion.PotionUtils; import net.minecraft.util.DamageSource; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.translation.I18n; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Function; public class ItemBullet extends ItemIEBase implements ITextureOverride//IBullet { public ItemBullet() { // super("bullet", 64, "emptyCasing","emptyShell","casull","armorPiercing","buckshot","HE","dragonsbreath","homing","wolfpack","silver","potion","flare"); super("bullet", 64, "emptyCasing", "emptyShell", "bullet"); BulletHandler.emptyCasing = new ItemStack(this, 1, 0); BulletHandler.emptyShell = new ItemStack(this, 1, 1); BulletHandler.basicCartridge = new ItemStack(this, 1, 2); BulletHandler.registerBullet("casull", new BulletHandler.DamagingBullet( entities -> IEDamageSources.causeCasullDamage((EntityRevolvershot) entities[0], entities[1]), IEConfig.Tools.bulletDamage_Casull, BulletHandler.emptyCasing, new ResourceLocation("immersiveengineering:items/bullet_casull"))); BulletHandler.registerBullet("armorPiercing", new BulletHandler.DamagingBullet( entities -> IEDamageSources.causePiercingDamage((EntityRevolvershot) entities[0], entities[1]), IEConfig.Tools.bulletDamage_AP, BulletHandler.emptyCasing, new ResourceLocation("immersiveengineering:items/bullet_armorPiercing"))); BulletHandler.registerBullet("buckshot", new BulletHandler.DamagingBullet( entities -> IEDamageSources.causeBuckshotDamage((EntityRevolvershot) entities[0], entities[1]), IEConfig.Tools.bulletDamage_Buck, true, false, BulletHandler.emptyShell, new ResourceLocation("immersiveengineering:items/bullet_buckshot")) { @Override public int getProjectileCount(EntityPlayer shooter) { return 10; } }); BulletHandler.registerBullet("HE", new BulletHandler.DamagingBullet(null, 0, BulletHandler.emptyCasing, new ResourceLocation("immersiveengineering:items/bullet_HE")) { @Override public void onHitTarget(World world, RayTraceResult target, EntityLivingBase shooter, Entity projectile, boolean headshot) { world.createExplosion(shooter, projectile.posX, projectile.posY, projectile.posZ, 2, false); } }); BulletHandler.registerBullet("silver", new BulletHandler.DamagingBullet( entities -> IEDamageSources.causeSilverDamage((EntityRevolvershot) entities[0], entities[1]), IEConfig.Tools.bulletDamage_Silver, BulletHandler.emptyCasing, new ResourceLocation("immersiveengineering:items/bullet_silver"))); BulletHandler.registerBullet("dragonsbreath", new BulletHandler.DamagingBullet( entities -> IEDamageSources.causeDragonsbreathDamage((EntityRevolvershot) entities[0], entities[1]), IEConfig.Tools.bulletDamage_Dragon, true, true, BulletHandler.emptyShell, new ResourceLocation("immersiveengineering:items/bullet_dragonsbreath")) { @Override public int getProjectileCount(EntityPlayer shooter) { return 30; } @Override public Entity getProjectile(EntityPlayer shooter, ItemStack cartridge, Entity projectile, boolean electro) { ((EntityRevolvershot) projectile).setTickLimit(10); projectile.setFire(3); return projectile; } }); BulletHandler.registerBullet("potion", new PotionBullet()); BulletHandler.registerBullet("flare", new FlareBullet()); } @Override @SideOnly(Side.CLIENT) public void getSubItems(Item item, CreativeTabs tab, List list) { list.add(new ItemStack(this, 1, 0)); list.add(new ItemStack(this, 1, 1)); for(Map.Entry<String, IBullet> entry : BulletHandler.registry.entrySet()) if(entry.getValue().isProperCartridge()) { ItemStack s = new ItemStack(this, 1, 2); ItemNBTHelper.setString(s, "bullet", entry.getKey()); list.add(s); } } @Override @SideOnly(Side.CLIENT) public FontRenderer getFontRenderer(ItemStack stack) { return ClientProxy.itemFont; } @SideOnly(Side.CLIENT) @Override public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean advanced) { if(stack.getItemDamage() == 2) { String key = ItemNBTHelper.getString(stack, "bullet"); IBullet bullet = BulletHandler.getBullet(key); if(bullet != null) bullet.addTooltip(stack, player, list, advanced); } } @Override public String getItemStackDisplayName(ItemStack stack) { if(stack.getItemDamage() == 2) { String s = "item.immersiveengineering.bullet."; String key = ItemNBTHelper.getString(stack, "bullet"); s += key; IBullet bullet = BulletHandler.getBullet(key); if(bullet != null) s = bullet.getUnlocalizedName(stack, s); return I18n.translateToLocal(s + ".name").trim(); } return super.getItemStackDisplayName(stack); } @Override public boolean hasCustomItemColours() { return true; } @Override public int getColourForIEItem(ItemStack stack, int pass) { if(stack.getMetadata() == 2 && ItemNBTHelper.hasKey(stack, "bullet")) { IBullet bullet = BulletHandler.getBullet(ItemNBTHelper.getString(stack, "bullet")); if(bullet != null) return bullet.getColour(stack, pass); } return super.getColourForIEItem(stack, pass); } @Override @SideOnly(Side.CLIENT) public String getModelCacheKey(ItemStack stack) { if(stack.getMetadata() == 2 && ItemNBTHelper.hasKey(stack, "bullet")) return ItemNBTHelper.getString(stack, "bullet"); return null; } @Override @SideOnly(Side.CLIENT) public List<ResourceLocation> getTextures(ItemStack stack, String key) { IBullet bullet = BulletHandler.getBullet(key); if(bullet != null) return Arrays.asList(bullet.getTextures()); return Arrays.asList(new ResourceLocation("immersiveengieering:items/bullet_casull")); } // @Override // public ItemStack getCasing(ItemStack stack) // { // return new ItemStack(this, 1, stack.getItemDamage()==1||stack.getItemDamage()==4||stack.getItemDamage()==6||stack.getItemDamage()==11?1:0); // } // @Override // public boolean canSpawnBullet(ItemStack bulletStack) // { // return bulletStack!=null && bulletStack.getItemDamage()>1 && (bulletStack.getItemDamage()!=10||ItemNBTHelper.getItemStack(bulletStack, "potion")!=null); // } // @Override // public void spawnBullet(EntityPlayer player, ItemStack bulletStack, boolean electro) // { // Vec3d vec = player.getLookVec(); // int type = bulletStack.getItemDamage()-2; // switch(type) // { // case 0://casull // doSpawnBullet(player, vec, vec, type, bulletStack, electro); // break; // case 1://armorPiercing // doSpawnBullet(player, vec, vec, type, bulletStack, electro); // break; // case 2://buckshot // for(int i=0; i<10; i++) // { // Vec3d vecDir = vec.addVector(player.getRNG().nextGaussian()*.1,player.getRNG().nextGaussian()*.1,player.getRNG().nextGaussian()*.1); // doSpawnBullet(player, vec, vecDir, type, bulletStack, electro); // } // break; // case 3://HE // doSpawnBullet(player, vec, vec, type, bulletStack, electro); // break; // case 4://dragonsbreath // for(int i=0; i<30; i++) // { // Vec3d vecDir = vec.addVector(player.getRNG().nextGaussian()*.1,player.getRNG().nextGaussian()*.1,player.getRNG().nextGaussian()*.1); // EntityRevolvershot shot = doSpawnBullet(player, vec, vecDir, type, bulletStack, electro); // shot.setTickLimit(10); // shot.setFire(3); // } // break; // case 5://homing // EntityRevolvershotHoming bullet = new EntityRevolvershotHoming(player.worldObj, player, vec.xCoord*1.5,vec.yCoord*1.5,vec.zCoord*1.5, type, bulletStack); // bullet.motionX = vec.xCoord; // bullet.motionY = vec.yCoord; // bullet.motionZ = vec.zCoord; // bullet.bulletElectro = electro; // player.worldObj.spawnEntityInWorld(bullet); // break; // case 6://wolfpack // doSpawnBullet(player, vec, vec, type, bulletStack, electro); // break; // case 7://Silver // doSpawnBullet(player, vec, vec, type, bulletStack, electro); // break; // case 8://Potion // EntityRevolvershot shot = doSpawnBullet(player, vec, vec, type, bulletStack, electro); // shot.bulletPotion = ItemNBTHelper.getItemStack(bulletStack, "potion"); // break; // case 9://Flare // EntityRevolvershotFlare flare = new EntityRevolvershotFlare(player.worldObj, player, vec.xCoord*1.5,vec.yCoord*1.5,vec.zCoord*1.5, type, bulletStack); // flare.motionX = vec.xCoord; // flare.motionY = vec.yCoord; // flare.motionZ = vec.zCoord; // flare.bulletElectro = electro; // flare.colour = this.getColourForIEItem(bulletStack, 1); // flare.setColourSynced(); // player.worldObj.spawnEntityInWorld(flare); // break; // } // } public static class PotionBullet extends BulletHandler.DamagingBullet { public PotionBullet() { super(entities -> IEDamageSources.causePotionDamage((EntityRevolvershot) entities[0], entities[1]), IEConfig.Tools.bulletDamage_Potion, BulletHandler.emptyCasing, new ResourceLocation("immersiveengineering:items/bullet_potion"), new ResourceLocation("immersiveengineering:items/bullet_potion_layer")); } @Override public String getUnlocalizedName(ItemStack cartridge, String baseName) { ItemStack pot = ItemNBTHelper.getItemStack(cartridge, "potion"); if(pot != null) if(pot.getItem() instanceof ItemLingeringPotion) baseName += ".linger"; else if(pot.getItem() instanceof ItemSplashPotion) baseName += ".splash"; return baseName; } @Override public Entity getProjectile(EntityPlayer shooter, ItemStack cartridge, Entity projectile, boolean electro) { ((EntityRevolvershot) projectile).bulletPotion = ItemNBTHelper.getItemStack(cartridge, "potion"); return projectile; } @Override public void onHitTarget(World world, RayTraceResult target, EntityLivingBase shooter, Entity projectile, boolean headshot) { super.onHitTarget(world, target, shooter, projectile, headshot); EntityRevolvershot bullet = (EntityRevolvershot)projectile; if(bullet.bulletPotion != null && bullet.bulletPotion.hasTagCompound()) { PotionType potionType = PotionUtils.getPotionFromItem(bullet.bulletPotion); List<PotionEffect> effects = PotionUtils.getEffectsFromStack(bullet.bulletPotion); if(effects != null) if(bullet.bulletPotion.getItem() instanceof ItemLingeringPotion) { EntityAreaEffectCloud entityareaeffectcloud = new EntityAreaEffectCloud(bullet.worldObj, bullet.posX, bullet.posY, bullet.posZ); entityareaeffectcloud.setOwner(shooter); entityareaeffectcloud.setRadius(3.0F); entityareaeffectcloud.setRadiusOnUse(-0.5F); entityareaeffectcloud.setWaitTime(10); entityareaeffectcloud.setRadiusPerTick(-entityareaeffectcloud.getRadius() / (float)entityareaeffectcloud.getDuration()); entityareaeffectcloud.setPotion(potionType); for(PotionEffect potioneffect : effects) entityareaeffectcloud.addEffect(new PotionEffect(potioneffect.getPotion(), potioneffect.getDuration(), potioneffect.getAmplifier())); bullet.worldObj.spawnEntityInWorld(entityareaeffectcloud); } else if(bullet.bulletPotion.getItem() instanceof ItemSplashPotion) { List<EntityLivingBase> livingEntities = bullet.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, bullet.getEntityBoundingBox().expand(4.0D, 2.0D, 4.0D)); if(livingEntities != null && !livingEntities.isEmpty()) for(EntityLivingBase living : livingEntities) if(living.canBeHitWithPotion()) { double dist = bullet.getDistanceSqToEntity(living); if(dist < 16D) { double dist2 = 1 - Math.sqrt(dist) / 4D; if(living == target.entityHit) dist2 = 1D; for(PotionEffect p : effects) if(p.getPotion().isInstant()) p.getPotion().affectEntity(bullet, shooter, living, p.getAmplifier(), dist2); else { int j = (int)(dist2 * p.getDuration() + .5D); if(j > 20) living.addPotionEffect(new PotionEffect(p.getPotion(), j, p.getAmplifier())); } } } } else if(target.entityHit instanceof EntityLivingBase) for(PotionEffect p : effects) { if(p.getDuration() < 1) p = new PotionEffect(p.getPotion(), 1); ((EntityLivingBase)target.entityHit).addPotionEffect(p); } world.playEvent(2002, new BlockPos(bullet), PotionType.getID(potionType)); } } @Override public void addTooltip(ItemStack stack, EntityPlayer player, List<String> list, boolean advanced) { ItemStack pot = ItemNBTHelper.getItemStack(stack, "potion"); if(pot != null && pot.getItem() instanceof ItemPotion) PotionUtils.addPotionTooltip(pot, list, 1f); } @Override public int getColour(ItemStack stack, int layer) { if(layer == 1) { ItemStack pot = ItemNBTHelper.getItemStack(stack, "potion"); return pot == null ? 0xff385dc6 : PotionUtils.getPotionColorFromEffectList(PotionUtils.getEffectsFromStack(pot)); } return 0xffffffff; } } public static class FlareBullet implements BulletHandler.IBullet { static ResourceLocation[] textures = {new ResourceLocation("immersiveengineering:items/bullet_flare"), new ResourceLocation("immersiveengineering:items/bullet_flare_layer")}; public FlareBullet() { } @Override public Entity getProjectile(EntityPlayer shooter, ItemStack cartridge, Entity projectile, boolean electro) { EntityRevolvershotFlare flare = shooter!=null?new EntityRevolvershotFlare(projectile.worldObj, shooter, projectile.motionX*1.5,projectile.motionY*1.5,projectile.motionZ*1.5, this, cartridge): new EntityRevolvershotFlare(projectile.worldObj, projectile.posX,projectile.posY,projectile.posZ, 0,0,0, this); flare.motionX = projectile.motionX; flare.motionY = projectile.motionY; flare.motionZ = projectile.motionZ; flare.bulletElectro = electro; flare.colour = this.getColour(cartridge, 1); flare.setColourSynced(); return flare; } @Override public void onHitTarget(World world, RayTraceResult target, EntityLivingBase shooter, Entity projectile, boolean headshot) { } @Override public ItemStack getCasing(ItemStack stack) { return BulletHandler.emptyShell; } @Override public ResourceLocation[] getTextures() { return textures; } @Override public void addTooltip(ItemStack stack, EntityPlayer player, List<String> list, boolean advanced) { if(stack.getItem() instanceof IColouredItem) { String hexCol = Integer.toHexString(((IColouredItem)stack.getItem()).getColourForIEItem(stack, 1)); list.add(I18n.translateToLocalFormatted(Lib.DESC_INFO + "bullet.flareColour", "<hexcol=" + hexCol + ":#" + hexCol + ">")); } } @Override public int getColour(ItemStack stack, int layer) { if(layer != 1) return 0xffffffff; return ItemNBTHelper.hasKey(stack, "flareColour") ? ItemNBTHelper.getInt(stack, "flareColour") : 0xcc2e06; } @Override public boolean isValidForTurret() { return true; } } public static class HomingBullet extends BulletHandler.DamagingBullet { public HomingBullet(float damage, ResourceLocation... textures) { super(new Function<Entity[], DamageSource>() { @Override public DamageSource apply(Entity[] entities) { return IEDamageSources.causeHomingDamage((EntityRevolvershot)entities[0], entities[1]); } }, damage, BulletHandler.emptyCasing, textures); } @Override public Entity getProjectile(EntityPlayer shooter, ItemStack cartridge, Entity projectile, boolean electro) { EntityRevolvershotHoming shot = shooter!=null?new EntityRevolvershotHoming(projectile.worldObj, shooter, projectile.motionX*1.5,projectile.motionY*1.5,projectile.motionZ*1.5, this, cartridge): new EntityRevolvershotHoming(projectile.worldObj, projectile.posX,projectile.posY,projectile.posZ, 0,0,0, this); shot.motionX = projectile.motionX; shot.motionY = projectile.motionY; shot.motionZ = projectile.motionZ; shot.bulletElectro = electro; return shot; } @Override public int getColour(ItemStack stack, int layer) { return 0xffffffff; } } public static class WolfpackBullet extends BulletHandler.DamagingBullet { public WolfpackBullet() { super(entities -> IEDamageSources.causeWolfpackDamage((EntityRevolvershot)entities[0], entities[1]), IEConfig.Tools.bulletDamage_Wolfpack, BulletHandler.emptyShell, new ResourceLocation("immersiveengineering:items/bullet_wolfpack")); } @Override public void onHitTarget(World world, RayTraceResult target, EntityLivingBase shooter, Entity projectile, boolean headshot) { super.onHitTarget(world, target, shooter, projectile, headshot); Vec3d v = new Vec3d(-projectile.motionX, -projectile.motionY, -projectile.motionZ); int split = 6; for(int i = 0; i < split; i++) { float angle = i * (360f / split); Matrix4 matrix = new Matrix4(); matrix.rotate(angle, v.xCoord, v.yCoord, v.zCoord); Vec3d vecDir = new Vec3d(0, 1, 0); vecDir = matrix.apply(vecDir); EntityWolfpackShot bullet = shooter!=null?new EntityWolfpackShot(world, shooter, vecDir.xCoord * 1.5, vecDir.yCoord * 1.5, vecDir.zCoord * 1.5, this, null) : new EntityWolfpackShot(world, 0,0,0, 0,0,0, this); if(target.entityHit instanceof EntityLivingBase) bullet.targetOverride = (EntityLivingBase)target.entityHit; bullet.setPosition(target.hitVec.xCoord + vecDir.xCoord, target.hitVec.yCoord + vecDir.yCoord, target.hitVec.zCoord + vecDir.zCoord); bullet.motionX = vecDir.xCoord * .375; bullet.motionY = vecDir.yCoord * .375; bullet.motionZ = vecDir.zCoord * .375; world.spawnEntityInWorld(bullet); } } @Override public int getColour(ItemStack stack, int layer) { return 0xffffffff; } } public static class WolfpackPartBullet extends BulletHandler.DamagingBullet { public WolfpackPartBullet() { super(entities -> IEDamageSources.causeWolfpackDamage((EntityRevolvershot)entities[0], entities[1]), IEConfig.Tools.bulletDamage_WolfpackPart, BulletHandler.emptyCasing, new ResourceLocation("immersiveengineering:items/bullet_wolfpack")); } @Override public boolean isProperCartridge() { return false; } @Override public int getColour(ItemStack stack, int layer) { return 0xffffffff; } } }