From 20bc79edfc088ddc14653029ac6191c70ff0eaa3 Mon Sep 17 00:00:00 2001 From: Jeremy Diamond Date: Thu, 14 Aug 2014 02:59:39 -0700 Subject: [PATCH] Hoot Hoot --- .../java/fox/spiteful/forbidden/Config.java | 3 + .../spiteful/forbidden/FMEventHandler.java | 56 +++- .../fox/spiteful/forbidden/Forbidden.java | 3 + .../forbidden/blocks/BlockRoseBush.java | 240 ++++++++++++++++++ .../spiteful/forbidden/compat/BloodMagic.java | 14 +- .../forbidden/items/ForbiddenItems.java | 4 + .../forbidden/items/ItemBloodRapier.java | 61 +++++ .../forbidden/items/ItemResource.java | 10 +- .../forbidden/potions/DarkPotions.java | 38 +++ .../forbidden/potions/PotionBloodSeal.java | 20 ++ .../assets/forbidden/lang/en_US.lang | 9 + .../textures/blocks/umbral_rose_bottom.png | Bin 0 -> 532 bytes .../textures/blocks/umbral_rose_top.png | Bin 0 -> 441 bytes .../forbidden/textures/items/blood_rapier.png | Bin 0 -> 321 bytes .../assets/forbidden/textures/items/fork.png | Bin 304 -> 4119 bytes .../textures/items/tainted_blood_shard.png | Bin 0 -> 518 bytes .../items/tainted_blood_shard.png.mcmeta | 5 + .../forbidden/textures/items/taintshovel.png | Bin 308 -> 1291 bytes .../textures/items/wand_rod_witchwood.png | Bin 346 -> 346 bytes .../items/wand_rod_witchwood_staff.png | Bin 178 -> 279 bytes .../forbidden/textures/misc/potions.png | Bin 0 -> 2163 bytes .../textures/models/wand_rod_witchwood.png | Bin 222 -> 589 bytes 22 files changed, 449 insertions(+), 14 deletions(-) create mode 100644 src/main/java/fox/spiteful/forbidden/blocks/BlockRoseBush.java create mode 100644 src/main/java/fox/spiteful/forbidden/items/ItemBloodRapier.java create mode 100644 src/main/java/fox/spiteful/forbidden/potions/DarkPotions.java create mode 100644 src/main/java/fox/spiteful/forbidden/potions/PotionBloodSeal.java create mode 100644 src/main/resources/assets/forbidden/textures/blocks/umbral_rose_bottom.png create mode 100644 src/main/resources/assets/forbidden/textures/blocks/umbral_rose_top.png create mode 100644 src/main/resources/assets/forbidden/textures/items/blood_rapier.png create mode 100644 src/main/resources/assets/forbidden/textures/items/tainted_blood_shard.png create mode 100644 src/main/resources/assets/forbidden/textures/items/tainted_blood_shard.png.mcmeta create mode 100644 src/main/resources/assets/forbidden/textures/misc/potions.png diff --git a/src/main/java/fox/spiteful/forbidden/Config.java b/src/main/java/fox/spiteful/forbidden/Config.java index 8649e5b..d337cae 100644 --- a/src/main/java/fox/spiteful/forbidden/Config.java +++ b/src/main/java/fox/spiteful/forbidden/Config.java @@ -24,6 +24,8 @@ public class Config { public static int corruptingEnchID; public static int eternalEnchID; + public static int bloodSealPotionID = 70; + public static int thaumcraftTaintBiomeID; public static int thaumcraftTaintPotionID; public static ItemStack thaumcraftResource; @@ -72,6 +74,7 @@ public class Config { wrathEff = 4; wrathCrazy = conf.get("general", "Wrath Cage Cries Havoc", wrathCrazy, "Enable to let the Wrath Cage imprint on ANY non-boss mob. May break your game or make your game Awesome.").getBoolean(false); spork = conf.get("silly", "Spork of Doom", spork, "What is this? I don't even...").getBoolean(false); + bloodSealPotionID = conf.get("potions", "Blood Seal", bloodSealPotionID).getInt(bloodSealPotionID); } catch (Exception e) { LogHandler.log(Level.ERROR, e, "Had a problem loading its configuration."); } finally { diff --git a/src/main/java/fox/spiteful/forbidden/FMEventHandler.java b/src/main/java/fox/spiteful/forbidden/FMEventHandler.java index 1b2268d..a8ba79e 100644 --- a/src/main/java/fox/spiteful/forbidden/FMEventHandler.java +++ b/src/main/java/fox/spiteful/forbidden/FMEventHandler.java @@ -1,12 +1,12 @@ package fox.spiteful.forbidden; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.Random; +import java.util.*; +import WayofTime.alchemicalWizardry.api.soulNetwork.SoulNetworkHandler; import fox.spiteful.forbidden.blocks.BlockBlackFlower; +import fox.spiteful.forbidden.compat.Compat; import fox.spiteful.forbidden.items.ItemTaintPickaxe; +import fox.spiteful.forbidden.potions.DarkPotions; import net.minecraft.block.Block; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; @@ -24,6 +24,7 @@ import net.minecraft.entity.monster.EntitySilverfish; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; @@ -38,10 +39,8 @@ import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.event.entity.living.LivingDeathEvent; -import net.minecraftforge.event.entity.living.LivingDropsEvent; -import net.minecraftforge.event.entity.living.LivingHurtEvent; -import net.minecraftforge.event.entity.living.LivingSpawnEvent; +import net.minecraftforge.event.entity.living.*; +import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.player.BonemealEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; @@ -50,6 +49,7 @@ import net.minecraftforge.event.world.BlockEvent.HarvestDropsEvent; import org.apache.logging.log4j.Level; import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.entities.ITaintedMob; import thaumcraft.common.items.wands.ItemWandCasting; import thaumcraft.common.lib.Utils; @@ -64,6 +64,7 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; public class FMEventHandler { Random randy = new Random(); final Aspect[] primals = { Aspect.ENTROPY, Aspect.ORDER, Aspect.FIRE, Aspect.WATER, Aspect.EARTH, Aspect.AIR }; + HashMap lastLP = new HashMap(); @SubscribeEvent public void onPlayerBreaking(BreakSpeed event) { @@ -89,7 +90,21 @@ public class FMEventHandler { @SubscribeEvent public void onLivingDrops(LivingDropsEvent event) { - if (Config.silverfishEmeralds && event.entityLiving instanceof EntitySilverfish) { + if (event.source.getDamageType().equals("player") && event.entityLiving instanceof ITaintedMob) + { + PotionEffect effect = event.entityLiving.getActivePotionEffect(Potion.weakness); + if (effect != null) + { + if (effect.getAmplifier() >= 2) { + double rand = Math.random(); + if (rand < 0.50d) { + addDrop(event, new ItemStack(ForbiddenItems.resource, 1, 3)); + } + } + } + } + + if (Config.silverfishEmeralds && event.entityLiving instanceof EntitySilverfish) { if (event.entityLiving.worldObj.getBiomeGenForCoords((int) event.entityLiving.posX, (int) event.entityLiving.posZ).biomeID == BiomeGenBase.extremeHills.biomeID) { if (event.recentlyHit && event.source.getEntity() != null && event.source.getEntity() instanceof EntityPlayer && randy.nextInt(30) <= (2 + event.lootingLevel * 2)) addDrop(event, new ItemStack(ForbiddenItems.resource, 1, 0)); @@ -395,4 +410,27 @@ public class FMEventHandler { } } + @SubscribeEvent + public void onEntityUpdate(LivingUpdateEvent event){ + if(Compat.bm && event.entityLiving != null && event.entityLiving instanceof EntityPlayer && !event.entityLiving.worldObj.isRemote){ + EntityPlayer player = (EntityPlayer)event.entityLiving; + String name = player.getDisplayName(); + if(player.isPotionActive(DarkPotions.bloodSeal)){ + try { + if (lastLP.containsKey(name)) { + if (SoulNetworkHandler.getCurrentEssence(name) > lastLP.get(name)) + SoulNetworkHandler.setCurrentEssence(name, lastLP.get(name)); + else + lastLP.put(name, SoulNetworkHandler.getCurrentEssence(name)); + } + else + lastLP.put(name, SoulNetworkHandler.getCurrentEssence(name)); + } + catch(Throwable e){} + } + else if(lastLP.containsKey(name)) + lastLP.remove(name); + } + } + } \ No newline at end of file diff --git a/src/main/java/fox/spiteful/forbidden/Forbidden.java b/src/main/java/fox/spiteful/forbidden/Forbidden.java index 18c37a0..a346107 100644 --- a/src/main/java/fox/spiteful/forbidden/Forbidden.java +++ b/src/main/java/fox/spiteful/forbidden/Forbidden.java @@ -1,5 +1,6 @@ package fox.spiteful.forbidden; +import fox.spiteful.forbidden.potions.DarkPotions; import net.minecraft.init.Blocks; import net.minecraftforge.common.MinecraftForge; import thaumcraft.api.wands.WandTriggerRegistry; @@ -39,6 +40,8 @@ public class Forbidden { ForbiddenItems.addItems(); ForbiddenBlocks.addBlocks(); DarkEnchantments.hex(); + if(Compat.bm) + DarkPotions.alchemize(); proxy.registerRenderInfo(); } diff --git a/src/main/java/fox/spiteful/forbidden/blocks/BlockRoseBush.java b/src/main/java/fox/spiteful/forbidden/blocks/BlockRoseBush.java new file mode 100644 index 0000000..a41f8d9 --- /dev/null +++ b/src/main/java/fox/spiteful/forbidden/blocks/BlockRoseBush.java @@ -0,0 +1,240 @@ +package fox.spiteful.forbidden.blocks; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.block.BlockBush; +import net.minecraft.block.IGrowable; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatList; +import net.minecraft.util.IIcon; +import net.minecraft.util.MathHelper; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.IShearable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class BlockRoseBush extends BlockBush implements IGrowable +{ + + @SideOnly(Side.CLIENT) + public IIcon top; + @SideOnly(Side.CLIENT) + public IIcon bottom; + + public BlockRoseBush() + { + super(Material.plants); + this.setHardness(0.0F); + this.setStepSound(soundTypeGrass); + this.setBlockName("blackRoseBush"); + } + + /** + * The type of render function that is called for this block + */ + public int getRenderType() + { + return 40; + } + + /** + * Updates the blocks bounds based on its current state. Args: world, x, y, z + */ + public void setBlockBoundsBasedOnState(IBlockAccess p_149719_1_, int p_149719_2_, int p_149719_3_, int p_149719_4_) + { + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + /** + * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z + */ + public boolean canPlaceBlockAt(World world, int x, int y, int z) + { + return super.canPlaceBlockAt(world, x, y, z) && world.isAirBlock(x, y + 1, z); + } + + /** + * checks if the block can stay, if not drop as item + */ + protected void checkAndDropBlock(World p_149855_1_, int p_149855_2_, int p_149855_3_, int p_149855_4_) + { + /*if (!this.canBlockStay(p_149855_1_, p_149855_2_, p_149855_3_, p_149855_4_)) + { + int l = p_149855_1_.getBlockMetadata(p_149855_2_, p_149855_3_, p_149855_4_); + + if (!func_149887_c(l)) + { + this.dropBlockAsItem(p_149855_1_, p_149855_2_, p_149855_3_, p_149855_4_, l, 0); + + if (p_149855_1_.getBlock(p_149855_2_, p_149855_3_ + 1, p_149855_4_) == this) + { + p_149855_1_.setBlock(p_149855_2_, p_149855_3_ + 1, p_149855_4_, Blocks.air, 0, 2); + } + } + + p_149855_1_.setBlock(p_149855_2_, p_149855_3_, p_149855_4_, Blocks.air, 0, 2); + }*/ + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. + */ + public boolean canBlockStay(World world, int x, int y, int z) + { + if (world.getBlock(x, y, z) != this) return super.canBlockStay(world, x, y, z); //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check. + int l = world.getBlockMetadata(x, y, z); + return l == 1 ? world.getBlock(x, y - 1, z) == this : world.getBlock(x, y + 1, z) == this && super.canBlockStay(world, x, y, z); + } + + public Item getItemDropped(int metadata, Random rand, int fortune) + { + if (metadata != 0) + { + return null; + } + else + { + return Item.getItemFromBlock(this); + } + } + + /** + * Gets the block's texture. Args: side, meta + */ + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) + { + if(meta == 0) + return bottom; + else + return top; + } + + /** + * Called when the block is placed in the world. + */ + public void onBlockPlacedBy(World p_149689_1_, int p_149689_2_, int p_149689_3_, int p_149689_4_, EntityLivingBase p_149689_5_, ItemStack p_149689_6_) + { + int l = ((MathHelper.floor_double((double) (p_149689_5_.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) + 2) % 4; + p_149689_1_.setBlock(p_149689_2_, p_149689_3_ + 1, p_149689_4_, this, 8 | l, 2); + } + + /** + * Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the + * block and l is the block's subtype/damage. + */ + public void harvestBlock(World p_149636_1_, EntityPlayer p_149636_2_, int p_149636_3_, int p_149636_4_, int p_149636_5_, int p_149636_6_) + { + /*if (p_149636_1_.isRemote || p_149636_2_.getCurrentEquippedItem() == null || p_149636_2_.getCurrentEquippedItem().getItem() != Items.shears || func_149887_c(p_149636_6_) || !this.func_149886_b(p_149636_1_, p_149636_3_, p_149636_4_, p_149636_5_, p_149636_6_, p_149636_2_)) + { + super.harvestBlock(p_149636_1_, p_149636_2_, p_149636_3_, p_149636_4_, p_149636_5_, p_149636_6_); + }*/ + } + + /** + * Called when the block is attempted to be harvested + */ + public void onBlockHarvested(World p_149681_1_, int p_149681_2_, int p_149681_3_, int p_149681_4_, int p_149681_5_, EntityPlayer p_149681_6_) + { + /*if (func_149887_c(p_149681_5_)) + { + if (p_149681_1_.getBlock(p_149681_2_, p_149681_3_ - 1, p_149681_4_) == this) + { + if (!p_149681_6_.capabilities.isCreativeMode) + { + int i1 = p_149681_1_.getBlockMetadata(p_149681_2_, p_149681_3_ - 1, p_149681_4_); + int j1 = func_149890_d(i1); + + if (j1 != 3 && j1 != 2) + { + p_149681_1_.func_147480_a(p_149681_2_, p_149681_3_ - 1, p_149681_4_, true); + } + else + { + if (!p_149681_1_.isRemote && p_149681_6_.getCurrentEquippedItem() != null && p_149681_6_.getCurrentEquippedItem().getItem() == Items.shears) + { + this.func_149886_b(p_149681_1_, p_149681_2_, p_149681_3_, p_149681_4_, i1, p_149681_6_); + } + + p_149681_1_.setBlockToAir(p_149681_2_, p_149681_3_ - 1, p_149681_4_); + } + } + else + { + p_149681_1_.setBlockToAir(p_149681_2_, p_149681_3_ - 1, p_149681_4_); + } + } + } + else if (p_149681_6_.capabilities.isCreativeMode && p_149681_1_.getBlock(p_149681_2_, p_149681_3_ + 1, p_149681_4_) == this) + { + p_149681_1_.setBlock(p_149681_2_, p_149681_3_ + 1, p_149681_4_, Blocks.air, 0, 2); + } + + super.onBlockHarvested(p_149681_1_, p_149681_2_, p_149681_3_, p_149681_4_, p_149681_5_, p_149681_6_);*/ + } + + private boolean func_149886_b(World p_149886_1_, int p_149886_2_, int p_149886_3_, int p_149886_4_, int p_149886_5_, EntityPlayer p_149886_6_) + { + /*int i1 = func_149890_d(p_149886_5_); + + if (i1 != 3 && i1 != 2) + { + return false; + } + else + { + p_149886_6_.addStat(StatList.mineBlockStatArray[Block.getIdFromBlock(this)], 1); + byte b0 = 1; + + if (i1 == 3) + { + b0 = 2; + } + + this.dropBlockAsItem(p_149886_1_, p_149886_2_, p_149886_3_, p_149886_4_, new ItemStack(Blocks.tallgrass, 2, b0));*/ + return true; + //} + } + + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister register) + { + this.top = register.registerIcon("forbidden:umbral_rose_top"); + this.bottom = register.registerIcon("forbidden:umbral_rose_bottom"); + } + + @Override + /* Whether the plant isn't fully grown? Who knows? Aside from Mojang. */ + public boolean func_149851_a(World world, int p_149851_2_, int p_149851_3_, int p_149851_4_, boolean p_149851_5_) + { + return true; + } + + @Override + /* Whether it can accept bonemeal? Who knows? Aside from Mojang. */ + public boolean func_149852_a(World p_149852_1_, Random p_149852_2_, int p_149852_3_, int p_149852_4_, int p_149852_5_) + { + return true; + } + + @Override + /* What happens when the block is bonemealed? Maybe? Fuck Obfuscation. */ + public void func_149853_b(World world, Random rand, int x, int y, int z) + { + //int l = this.func_149885_e(world, x, y, z); + //this.dropBlockAsItem(world, x, y, z, new ItemStack(this, 1, l)); + } + +} \ No newline at end of file diff --git a/src/main/java/fox/spiteful/forbidden/compat/BloodMagic.java b/src/main/java/fox/spiteful/forbidden/compat/BloodMagic.java index 187b3f7..d426029 100644 --- a/src/main/java/fox/spiteful/forbidden/compat/BloodMagic.java +++ b/src/main/java/fox/spiteful/forbidden/compat/BloodMagic.java @@ -1,7 +1,9 @@ package fox.spiteful.forbidden.compat; +import WayofTime.alchemicalWizardry.api.alchemy.AlchemicalPotionCreationHandler; import fox.spiteful.forbidden.DarkAspects; import fox.spiteful.forbidden.LogHandler; +import fox.spiteful.forbidden.potions.DarkPotions; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -15,6 +17,7 @@ import thaumcraft.api.aspects.Aspect; import thaumcraft.api.aspects.AspectList; import thaumcraft.api.crafting.IArcaneRecipe; import thaumcraft.api.crafting.InfusionRecipe; +import thaumcraft.api.potions.PotionFluxTaint; import thaumcraft.api.research.ResearchPage; import WayofTime.alchemicalWizardry.api.altarRecipeRegistry.AltarRecipeRegistry; @@ -23,11 +26,16 @@ import fox.spiteful.forbidden.items.ForbiddenItems; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.registry.GameRegistry; +import thaumcraft.common.lib.potions.PotionWarpWard; public class BloodMagic { public static void stab() { try { - AspectList list; + AlchemicalPotionCreationHandler.addPotion(ItemApi.getItem("itemResource", 14), PotionWarpWard.instance.getId(), 1800); + AlchemicalPotionCreationHandler.addPotion(ItemApi.getItem("itemResource", 11), PotionFluxTaint.instance.getId(), 450); + AlchemicalPotionCreationHandler.addPotion(new ItemStack(ForbiddenItems.resource, 1, 3), DarkPotions.bloodSeal.getId(), 1200); + + AspectList list; Item masterOrb = GameRegistry.findItem("AWWayofTime", "masterBloodOrb"); Item archmasterOrb = GameRegistry.findItem("AWWayofTime", "archmageBloodOrb"); Item imbuedSlate = GameRegistry.findItem("AWWayofTime", "imbuedSlate"); @@ -58,6 +66,10 @@ public class BloodMagic { IArcaneRecipe blood_staff = ThaumcraftApi.addArcaneCraftingRecipe("ROD_blood_staff", new ItemStack(ForbiddenItems.wandCore, 1, 9), (new AspectList()).add(Aspect.ENTROPY, 26).add(Aspect.FIRE, 26).add(Aspect.WATER, 26).add(Aspect.AIR, 26).add(Aspect.EARTH, 26).add(Aspect.ORDER, 26), new Object[] { "__D", "_B_", "B__", Character.valueOf('B'), new ItemStack(ForbiddenItems.wandCore, 1, 3), Character.valueOf('D'), new ItemStack(demonShard) }); (new DarkResearchItem("ROD_blood_staff", "FORBIDDEN", "[BM]", (new AspectList()).add(Aspect.LIFE, 8).add(Aspect.WATER, 7).add(Aspect.WEAPON, 6), -5, -7, 5, new ItemStack(ForbiddenItems.wandCore, 1, 9))).setPages(new ResearchPage[] { new ResearchPage("forbidden.research_page.ROD_blood_staff.1"), new ResearchPage(blood_staff) }).setParents(new String[] { "ROD_silverwood_staff", "ROD_blood" }).setSpecial().setConcealed().registerResearchItem(); + InfusionRecipe blood_rapier = ThaumcraftApi.addInfusionCraftingRecipe("BLOODRAPIER", new ItemStack(ForbiddenItems.bloodRapier, 1, 0), 8, (new AspectList()).add(Aspect.LIFE, 18).add(Aspect.HUNGER, 32).add(Aspect.WEAPON, 8), ItemApi.getItem("itemSwordThaumium", 0), new ItemStack[] { ItemApi.getItem("itemResource", 12), new ItemStack(ForbiddenItems.deadlyShards, 1, 0), new ItemStack(ForbiddenItems.gluttonyShard, 1, 0), new ItemStack(Items.feather), ItemApi.getItem("itemResource", 6) }); + (new DarkResearchItem("BLOODRAPIER", "FORBIDDEN", "[BM]", (new AspectList()).add(Aspect.LIFE, 16).add(Aspect.HUNGER, 12).add(Aspect.WEAPON, 12).add(Aspect.MAGIC, 12), -9, 8, 4, new ItemStack(ForbiddenItems.bloodRapier, 1, 0))).setPages(new ResearchPage[] { new ResearchPage("forbidden.research_page.BLOODRAPIER.1"), new ResearchPage(blood_rapier) }).setParents(new String[] { "INFAUXSION" }).setConcealed().registerResearchItem(); + ThaumcraftApi.addWarpToResearch("BLOODRAPIER", 3); + if (Compat.kami) { try { diff --git a/src/main/java/fox/spiteful/forbidden/items/ForbiddenItems.java b/src/main/java/fox/spiteful/forbidden/items/ForbiddenItems.java index 3566744..fe040e8 100644 --- a/src/main/java/fox/spiteful/forbidden/items/ForbiddenItems.java +++ b/src/main/java/fox/spiteful/forbidden/items/ForbiddenItems.java @@ -51,6 +51,7 @@ public class ForbiddenItems { public static Item ridingCrop; public static Item divinewell; public static Item boundShears; + public static Item bloodRapier; public static Item bloodwell; public static Item bloodOrb; @@ -171,6 +172,9 @@ public class ForbiddenItems { divinewell = new ItemDivinewell().setUnlocalizedName("Divinewell"); GameRegistry.registerItem(divinewell, "Divinewell"); + bloodRapier = new ItemBloodRapier().setUnlocalizedName("BloodRapier"); + GameRegistry.registerItem(bloodRapier, "BloodRapier"); + // boundShears = new ItemBoundShears(Config.boundShearsID, // ThaumcraftApi.toolMatThaumium).setUnlocalizedName("BoundShears"); // GameRegistry.registerItem(boundShears, "BoundSHears"); diff --git a/src/main/java/fox/spiteful/forbidden/items/ItemBloodRapier.java b/src/main/java/fox/spiteful/forbidden/items/ItemBloodRapier.java new file mode 100644 index 0000000..39f77a2 --- /dev/null +++ b/src/main/java/fox/spiteful/forbidden/items/ItemBloodRapier.java @@ -0,0 +1,61 @@ +package fox.spiteful.forbidden.items; + +import WayofTime.alchemicalWizardry.api.soulNetwork.SoulNetworkHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import fox.spiteful.forbidden.compat.Compat; +import fox.spiteful.forbidden.potions.DarkPotions; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemSword; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.IIcon; +import net.minecraftforge.common.util.EnumHelper; +import thaumcraft.api.IRepairable; + +public class ItemBloodRapier extends ItemSword implements IRepairable{ + + static final ToolMaterial bloodsucker = EnumHelper.addToolMaterial("BLOODSUCKER", 3, 1500, 10F, -3F, 18); + private IIcon icon; + + public ItemBloodRapier(){ + super(bloodsucker); + } + + @Override + public boolean hitEntity(ItemStack stack, EntityLivingBase victim, EntityLivingBase player) { + stack.damageItem(1, player); + victim.motionY *= 0.8; + if (victim.hurtResistantTime > 18) + victim.hurtResistantTime -= 5; + if (Compat.bm & victim instanceof EntityPlayer) { + try { + String target = ((EntityPlayer) victim).getDisplayName(); + int lp = SoulNetworkHandler.getCurrentEssence(target); + int damage = Math.max(4000, lp / 4); + if (lp >= damage) + lp -= damage; + else + lp = 0; + SoulNetworkHandler.setCurrentEssence(target, lp); + } + catch(Throwable e){} + victim.addPotionEffect(new PotionEffect(DarkPotions.bloodSeal.getId(), 1200)); + } + return true; + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIconFromDamage(int par1) { + return this.icon; + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister ir) { + this.icon = ir.registerIcon("forbidden:blood_rapier"); + } +} diff --git a/src/main/java/fox/spiteful/forbidden/items/ItemResource.java b/src/main/java/fox/spiteful/forbidden/items/ItemResource.java index 9d68ca3..2cdab54 100644 --- a/src/main/java/fox/spiteful/forbidden/items/ItemResource.java +++ b/src/main/java/fox/spiteful/forbidden/items/ItemResource.java @@ -30,29 +30,31 @@ public class ItemResource extends Item { @SideOnly(Side.CLIENT) @Override public void registerIcons(IIconRegister ir) { - icons = new IIcon[3]; + icons = new IIcon[4]; icons[0] = ir.registerIcon("forbidden:emerald_nugget"); icons[1] = ir.registerIcon("forbidden:dye_powder_black"); icons[2] = ir.registerIcon("forbidden:nuggetmanasteel"); + icons[3] = ir.registerIcon("forbidden:tainted_blood_shard"); } @SideOnly(Side.CLIENT) @Override public IIcon getIconFromDamage(int dam) { - return this.icons[dam]; + return this.icons[dam % icons.length]; } @Override public String getUnlocalizedName(ItemStack stack) { - int i = MathHelper.clamp_int(stack.getItemDamage(), 0, 2); + //int i = MathHelper.clamp_int(stack.getItemDamage(), 0, 3); + int i = stack.getItemDamage(); return super.getUnlocalizedName() + "." + i; } @SideOnly(Side.CLIENT) @Override public void getSubItems(Item par1, CreativeTabs xCreativeTabs, List list) { - for (int j = 0; j < 3; ++j) { + for (int j = 0; j < 4; ++j) { list.add(new ItemStack(par1, 1, j)); } } diff --git a/src/main/java/fox/spiteful/forbidden/potions/DarkPotions.java b/src/main/java/fox/spiteful/forbidden/potions/DarkPotions.java new file mode 100644 index 0000000..17b117e --- /dev/null +++ b/src/main/java/fox/spiteful/forbidden/potions/DarkPotions.java @@ -0,0 +1,38 @@ +package fox.spiteful.forbidden.potions; + +import fox.spiteful.forbidden.Config; +import net.minecraft.potion.Potion; +import net.minecraft.util.ResourceLocation; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public class DarkPotions { + public static final ResourceLocation icons = new ResourceLocation("forbidden", "textures/misc/potions.png"); + public static Potion bloodSeal; + + public static void alchemize(){ + if(Potion.potionTypes.length < 256) { + Potion[] potionTypes = null; + for (Field f : Potion.class.getDeclaredFields()) { + f.setAccessible(true); + try { + if (f.getName().equals("potionTypes") || f.getName().equals("field_76425_a")) { + Field modfield = Field.class.getDeclaredField("modifiers"); + modfield.setAccessible(true); + modfield.setInt(f, f.getModifiers() & ~Modifier.FINAL); + potionTypes = (Potion[]) f.get(null); + final Potion[] newPotionTypes = new Potion[256]; + System.arraycopy(potionTypes, 0, newPotionTypes, 0, potionTypes.length); + f.set(null, newPotionTypes); + } + } catch (Exception e) { + System.err.println("Severe error, please report this to the mod author:"); + System.err.println(e); + } + } + } + + bloodSeal = new PotionBloodSeal(Config.bloodSealPotionID); + } +} diff --git a/src/main/java/fox/spiteful/forbidden/potions/PotionBloodSeal.java b/src/main/java/fox/spiteful/forbidden/potions/PotionBloodSeal.java new file mode 100644 index 0000000..b31c797 --- /dev/null +++ b/src/main/java/fox/spiteful/forbidden/potions/PotionBloodSeal.java @@ -0,0 +1,20 @@ +package fox.spiteful.forbidden.potions; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; +import net.minecraft.potion.Potion; + +public class PotionBloodSeal extends Potion { + public PotionBloodSeal(int id){ + super(id, true, 0xAC1919); + this.setPotionName("potion.blood_seal"); + this.setIconIndex(4, 0); + } + + @SideOnly(Side.CLIENT) + public int getStatusIconIndex() { + Minecraft.getMinecraft().renderEngine.bindTexture(DarkPotions.icons); + return super.getStatusIconIndex(); + } +} diff --git a/src/main/resources/assets/forbidden/lang/en_US.lang b/src/main/resources/assets/forbidden/lang/en_US.lang index 886589b..ab4c8ec 100644 --- a/src/main/resources/assets/forbidden/lang/en_US.lang +++ b/src/main/resources/assets/forbidden/lang/en_US.lang @@ -29,6 +29,7 @@ item.MorphAxe.name=Chameleon Axe item.FMResource.0.name=Emerald Fragment item.FMResource.1.name=Shadow Ink item.FMResource.2.name=Manasteel Nugget +item.FMResource.3.name=Tainted Blood Shard item.MobCrystalEmpty.name=Blank Imprinting Crystal item.MobCrystal.name=Imprinted Crystal item.DiabolistFork.name=Diabolist Fork @@ -40,6 +41,7 @@ item.Crystalwell.name=Crystal Scribing Tools item.RidingCrop.name=Riding Crop item.Divinewell.name=Scribing Tools of Thoth item.BoundShears.name=Bound Shears +item.BloodRapier.name=Strix Rapier # # Wand components item.Wand.tainted.rod=Tainted @@ -87,6 +89,9 @@ enchantment.educational=Educational enchantment.corrupting=Corrupting enchantment.eternal=Eternal # +# Potions +potion.blood_seal=Blood Seal +# # Misc itemGroup.forbidden=Forbidden Magic itemGroup.mobcrystal=Imprinting Crystals @@ -235,6 +240,10 @@ forbidden.research_name.DIVINEORB=Transcendent Blood Orb forbidden.research_text.DIVINEORB=Orb of Armok forbidden.research_page.DIVINEORB.1=It is whispered among some Thaumaturgic circles that Ichor is actually the blood of the divine. You don't know whether this is true or not, but Ichor does seem to have an affinity with more advanced alchemical devices.

The Transcendent Blood Orb is what happens when you combine the most advanced Thaumaturgy and Alchemical Wizardry available. The infusion vastly increases the orb's carrying capacity, allowing it to hold a whopping 70,000,000 LP. What would you ever need that much LP for? # +forbidden.research_name.BLOODRAPIER=Strix Rapier +forbidden.research_text.BLOODRAPIER=Destroyer of Blood Magic +forbidden.research_page.BLOODRAPIER.1=There's nothing more dangerous than a Blood Magus that is gorged on life essence. As long as they have enough life energy, there's very little that can pierce their defenses.

Until now.

The Strix Rapier, upon striking someone, drinks LP directly from their Soul Network and seals it so that they can't regain any more LP for a while. It may not do very much physical damage, but it packs a metaphysical punch against Blood Magi. +# forbidden.research_name.CRYSTALWELL=Crystal Scribing Tools forbidden.research_text.CRYSTALWELL=Arcane Research Grant forbidden.research_page.CRYSTALWELL.1=Combining elemental shards with your inkwell results in some interesting effects. The Crystal Scribing Tools seem to absorb knowledge as you use them to write. Once the well is empty of ink, you can absorb this knowledge for a small burst of research points by holding the tools in your hand and right clicking. Unfortunately, this burns the tool out and turns it back into a mundane Scribing Tool again. diff --git a/src/main/resources/assets/forbidden/textures/blocks/umbral_rose_bottom.png b/src/main/resources/assets/forbidden/textures/blocks/umbral_rose_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..ba299907846570bdeb5637f32e7053a7edf03725 GIT binary patch literal 532 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 delta 277 zcmV+w0qXvjAg}_EB!2;OQb$4nuFf3k00004XF*Lt006O%3;baP00009a7bBm000id z000id0mpBsWB>pF#Ysd#R5(waki8AUFcgF>HJ8D;iQW%w(rwRg4gM=kGJb3jtX=B5KGL@$35DcyPAymrx%?e?e#yL%;tm9*IX?&PU84oRC)kz4RQUM?YtB2yBOvwN=L7Mf) zdf}c0ng9y#bCcLTmeneqByT0zJzr35n=ZUo>td38^c#Q>oumo?0Rlq`sRnof0vCY) b9K#zRYk43Znhvi800000NkvXXu0mjf6Qyv) diff --git a/src/main/resources/assets/forbidden/textures/items/tainted_blood_shard.png b/src/main/resources/assets/forbidden/textures/items/tainted_blood_shard.png new file mode 100644 index 0000000000000000000000000000000000000000..90ff8807cd47d7c507c4ad157f19647be85bfcb0 GIT binary patch literal 518 zcmV+h0{Q)kP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RY2@L@P z3QjNnRsaA18gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$DE-^7j^FlWO00Cl2L_t(Y zOWju6O2a@94b1#TYpwo+wu-+{M390Md=tbMKUIn%qA&fCF_Yzl+1X8u2_>Zu%R+YM z?3vri79vs%S%aMQ;zocQ-pLhz%aT8Cc0{1qh!j$vO%46LoILI4RjZ)8HN#94EdWuT50 zS$n|8?rpN2s31NZR0nx#WMIpv#^}l%U{Xfk>$(2VecRtOcGZaeF&Iw|Y$>fCASb=` z03~eI1ACa$gVu3|ptR`$E@;&Q%fjnHPS*aV2LL|;J+O1qI19b?psNo2DJbKQ^I!(! z>H+9`JYUkmLRYuz{-y?6$f8b{+4H`4+SvobHs5^t+gFN+Ev zt4bfMDnFYVf7{vsySm)0I9b=`?7)>dL923uSLcPSF`VP$zmnP>w*7@N&R q8vu%D^gtrX03BoulO$}we+B@IOp@3TGkx9w0000P=o;&77-F-Nc5}t?`<3PAE%@7X-@X9 z`rnzi@_$Bf<9}!K0PKd~G5}=rvaVxb%>j-{q`3g38D?{|X8~@_Ab%md0OV(ohMs~o z|1(3H{)f3{{s)QS1;_?~G%xRlI6J~U=RZu2C<8#w2H6bK46+&7V7vyvqN*%z64=>H zpa4S;SiA;+Z0;>w3lD8V2qr)00000NkvXXu0mjfygOZ> delta 225 zcmV<703QF^0@?zQJPHp001FQRlKBIrkw!^>NRR;+77-R=i14%h?`miCAE%@7X^sl8 z`(KwA{68+(;lI6w9(F@;833|*Zf81JvzL=8X)XY1hS?nKWrbTa$Y01V0QniDp&>uy ze|(7Je?M3A{~$5E0NDVL=J{P2U}pzP7$mYhvPFNs9H^?z z)5S5w!aq4dfjOnk;%Qq~7{6g*m#vxZ zw_m?2bE0m&y}ak><*D-{vVck%OM?7@862M7NCR>#JzX3_IIbr*FdSpkc)WovBw;yo zi{d;^Q4OI6gO<>ROm2)BOs)ouqAMIGG3zn9t|$$XW(;uSp2EgZ$;SRor?7Jt&=dww LS3j3^P6=ES4z)+>iz|hdl!0_`w zkbcR)P-?)y@G60U!D;=pVj0`0~e!>4oHed+;&JHX$7&r?& zB8wRq_zr?Ftn z%5F~=$B>G+x3jwYW*dmGHu`RueD?o;y{*0#rfX9ye{fk$_PX67W`8Wbrg`gGg@0K` zp4&4tuyhDJFn(m%z`2Nl3&IRw4PanB!nvTKf?)-dMg!9$mH-DEh7d*(2gX7s4Fx%d zRSaAU8Y~z^1o#<38CU}x<^XlFH)u5gCH;UpnH@wOfRgG!os0{(7L0Ub*I&<`+qfDxN%a|Q0)ZSs!a8*oTx$RktTm~VAcdrG? z6#qZo)o-0pQU297L9?>(UccmlJwL+P3!?Y29Z?dv_Qxz+KzPGlmGax0zU8l|5cZio zZ`*+{b=9f=7hcQUDB^JI-SeOQ@m%5eSaYGC7XYz7?|2(+& znXkV8y!-9&u+yd2e*RxOjk)9ezL$j-x_^GWv5xhWKgYD-E|1Baq!#0erW?*^&+qx3 zwLDL4)~4dwRpnRbzDs}olwIlewoT_Jnr;94SdT$MSVOP**yAGiqY~_R! zeE($po!GE=ZO7LN4~KJ#txx|O`Zqj%QuJ#R`+_>96p-{rPPtsyHOH0bH`ueT?RvAy<0nG%E7=H)`0001UdV2H#0004VQb$4nuFf3k00004XF*Lt006O%3;baP z00009a7bBm000id000id0mpBsWB>pF8gxZibW?9;ba!ELWdKlNX>N2bPDNB8b~7$D zE-^7j^FlWO00F#7L_t(oN9~r|NLTnS>1<^OGk?phw6e_1QqjspJ0FRn zlMzKx5JXVWMM3X4@eK*Rz(^Nc7}na}%s2o4ueEngjq`I9a1?M9_*LL2{UU{#vg9Hs zQi|P3)rDD}Je6$tSn|^svKGCp9)PRPE&Z+I;%kqHr^&C?9PCQ6rWJ59&M{=5bw+A>_dX~-joh$^m z6o3HE1&TWT)!L^$z)AK^r>5cR)R_hm8`$3zzwH5-a%=ux8&iv+U5O5^D9~}{)gGW+ z_)^(ZWBXcoPafD;C4}cIAL{*IfaK`5K4XRXDL`f>C4c!8(-TPS;3%2{>?NPn0vgAL z3OY3aT+5RKS$lw;g-1OF$jj1NhH%Oa=fTkh~39N4jG605s#)BY+go_zyt9Giwh(^9lf-b0<^){2f#F05qj| zE%&yB^f~Nf1#4@g*B-#z92AOX?uJhNAQ@;2>snvyvIj6vxzpgkEARtgVnyhnVvdvm O0000L_G^L0|P^2NcwRgB@y5g;tHf)EEFyEW&G?_?TzIPG$bP2wUlLrF0D;* z1j;d%1o;IsI6S+N2IQ1@x;TbtoIiVZBX5g=fJIN(KM`