diff --git a/src/main/java/electroblob/wizardry/client/ClientProxy.java b/src/main/java/electroblob/wizardry/client/ClientProxy.java index 95a72691..151e3e30 100644 --- a/src/main/java/electroblob/wizardry/client/ClientProxy.java +++ b/src/main/java/electroblob/wizardry/client/ClientProxy.java @@ -766,6 +766,8 @@ public class ClientProxy extends CommonProxy { new ResourceLocation(Wizardry.MODID, "textures/entity/dart.png"), false, 8.0, 2.0, 16, 5, true)); RenderingRegistry.registerEntityRenderingHandler(EntityIceLance.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, true)); + RenderingRegistry.registerEntityRenderingHandler(EntityFlamecatcherArrow.class, manager -> new RenderMagicArrow(manager, + new ResourceLocation(Wizardry.MODID, "textures/entity/flamecatcher_arrow.png"), false, 8, 2.0, 16, 5, true)); RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new); diff --git a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java index d5d62f29..7f3cd6c2 100644 --- a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java +++ b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java @@ -4,6 +4,7 @@ import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect; import electroblob.wizardry.data.DispenserCastingData; import electroblob.wizardry.data.SpellEmitterData; import electroblob.wizardry.item.ItemArtefact; +import electroblob.wizardry.item.ItemFlamecatcher; import electroblob.wizardry.item.ItemSpectralBow; import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.potion.PotionSlowTime; @@ -164,7 +165,9 @@ public final class WizardryClientEventHandler { public static void onFOVUpdateEvent(FOVUpdateEvent event){ // Bow zoom. Taken directly from AbstractClientPlayer so it works exactly like vanilla. - if(event.getEntity().isHandActive() && event.getEntity().getActiveItemStack().getItem() instanceof ItemSpectralBow){ + if(event.getEntity().isHandActive() && + (event.getEntity().getActiveItemStack().getItem() instanceof ItemSpectralBow + || event.getEntity().getActiveItemStack().getItem() instanceof ItemFlamecatcher)){ int maxUseTicks = event.getEntity().getItemInUseMaxCount(); diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityFlamecatcherArrow.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityFlamecatcherArrow.java new file mode 100644 index 00000000..d45ea22b --- /dev/null +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityFlamecatcherArrow.java @@ -0,0 +1,71 @@ +package electroblob.wizardry.entity.projectile; + +import electroblob.wizardry.registry.Spells; +import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.spell.Spell; +import electroblob.wizardry.util.ParticleBuilder; +import electroblob.wizardry.util.ParticleBuilder.Type; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +public class EntityFlamecatcherArrow extends EntityMagicArrow { + + public static final float SPEED = 3; + + /** Creates a new magic missile in the given world. */ + public EntityFlamecatcherArrow(World world){ + super(world); + } + + @Override public double getDamage(){ return Spells.flamecatcher.getProperty(Spell.DAMAGE).floatValue(); } + + @Override public int getLifetime(){ return (int)(Spells.flamecatcher.getProperty(Spell.RANGE).floatValue() / SPEED); } + + @Override public boolean doGravity(){ return false; } // Zero gravity arrows! + + @Override public boolean doDeceleration(){ return false; } + + @Override + public void onEntityHit(EntityLivingBase entityHit){ + entityHit.setFire(Spells.flamecatcher.getProperty(Spell.BURN_DURATION).intValue()); + this.playSound(WizardrySounds.ENTITY_FLAMECATCHER_ARROW_HIT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + if(this.world.isRemote) ParticleBuilder.create(Type.FLASH).pos(posX, posY, posZ).clr(0xff6d00).spawn(world); + } + + @Override + public void onBlockHit(RayTraceResult hit){ + if(this.world.isRemote){ + // Gets a position slightly away from the block hit so the particle doesn't get cut in half by the block face + Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(0.15)); + ParticleBuilder.create(Type.FLASH).pos(vec).clr(0xff6d00).fade(0.85f, 0.5f, 0.8f).spawn(world); + } + } + + @Override + public void tickInAir(){ + + if(this.world.isRemote){ + + ParticleBuilder.create(Type.MAGIC_FIRE, rand, posX, posY, posZ, 0.03, false) + .time(20 + rand.nextInt(10)).spawn(world); + + if(this.ticksExisted > 1){ // Don't spawn particles behind where it started! + double x = posX - motionX / 2; + double y = posY - motionY / 2; + double z = posZ - motionZ / 2; + ParticleBuilder.create(Type.MAGIC_FIRE, rand, x, y, z, 0.03, false) + .time(20 + rand.nextInt(10)).spawn(world); + } + } + } + + @Override + protected void entityInit(){ + if(world != null && world.isRemote){ + ParticleBuilder.create(Type.FLASH).entity(this).time(this.getLifetime()).scale(1.5f).clr(0xffb800).spawn(world); + } + } + +} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/item/ItemFlamecatcher.java b/src/main/java/electroblob/wizardry/item/ItemFlamecatcher.java new file mode 100644 index 00000000..b9d7e99b --- /dev/null +++ b/src/main/java/electroblob/wizardry/item/ItemFlamecatcher.java @@ -0,0 +1,220 @@ +package electroblob.wizardry.item; + +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.entity.projectile.EntityFlamecatcherArrow; +import electroblob.wizardry.registry.Spells; +import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.spell.Flamecatcher; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.IItemPropertyGetter; +import net.minecraft.item.ItemBow; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; + +public class ItemFlamecatcher extends ItemBow implements IConjuredItem { + + private static final float DRAW_TIME = 10; + + public ItemFlamecatcher(){ + super(); + setMaxDamage(1200); + setNoRepair(); + setCreativeTab(null); + this.addPropertyOverride(new ResourceLocation("pull"), new IItemPropertyGetter(){ + @SideOnly(Side.CLIENT) + public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn){ + if(entityIn == null){ + return 0.0F; + }else{ + ItemStack itemstack = entityIn.getActiveItemStack(); + return itemstack.getItem() == ItemFlamecatcher.this + ? (float)(stack.getMaxItemUseDuration() - entityIn.getItemInUseCount()) / DRAW_TIME : 0; + } + } + }); + this.addPropertyOverride(new ResourceLocation("pulling"), new IItemPropertyGetter(){ + @SideOnly(Side.CLIENT) + public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn){ + return entityIn != null && entityIn.isHandActive() && entityIn.getActiveItemStack() == stack ? 1 : 0; + } + }); + addAnimationPropertyOverrides(); + } + + @Override + public EnumRarity getRarity(ItemStack stack){ + return EnumRarity.EPIC; + } + + @Override + @SideOnly(Side.CLIENT) + // Why does this still exist? Item models deal with this now, right? + public boolean isFull3D(){ + return true; + } + + @Override + public int getMaxDamage(ItemStack stack){ + return this.getMaxDamageFromNBT(stack, Spells.flamecatcher); + } + + @Override + // This method allows the code for the item's timer to be greatly simplified by damaging it directly from + // onUpdate() and removing the workaround that involved WizardData and all sorts of crazy stuff. + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ + + if(!oldStack.isEmpty() || !newStack.isEmpty()){ + // We only care about the situation where we specifically want the animation NOT to play. + if(oldStack.getItem() == newStack.getItem() && !slotChanged) + // This code should only run on the client side, so using Minecraft is ok. + // Why the heck was this here? + //&& !net.minecraft.client.Minecraft.getMinecraft().player.isHandActive()) + return false; + } + + return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); + } + + // Copied fixes from ItemWand made possible by recently-added Forge hooks + + @Override + public boolean canContinueUsing(ItemStack oldStack, ItemStack newStack){ + // Ignore durability changes + if(ItemStack.areItemsEqualIgnoreDurability(oldStack, newStack)) return true; + return super.canContinueUsing(oldStack, newStack); + } + + @Override + public boolean shouldCauseBlockBreakReset(ItemStack oldStack, ItemStack newStack){ + // Ignore durability changes + if(ItemStack.areItemsEqualIgnoreDurability(oldStack, newStack)) return false; + return super.shouldCauseBlockBreakReset(oldStack, newStack); + } + + @Override + public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){ + int damage = stack.getItemDamage(); + if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY); + stack.setItemDamage(damage + 1); + } + + // The following two methods re-route the displayed durability through the proxies in order to override the pausing + // of the item timer when the bow is being pulled. + + @Override + public double getDurabilityForDisplay(ItemStack stack){ + return Wizardry.proxy.getConjuredBowDurability(stack); + } + + public double getDefaultDurabilityForDisplay(ItemStack stack){ + return super.getDurabilityForDisplay(stack); + } + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand){ + + ItemStack stack = player.getHeldItem(hand); + + int shotsLeft = stack.getTagCompound().getInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY); + if(shotsLeft == 0) return ActionResult.newResult(EnumActionResult.PASS, stack); + + ActionResult ret = net.minecraftforge.event.ForgeEventFactory.onArrowNock(stack, world, player, hand, + true); + + if(ret != null) return ret; + + player.setActiveHand(hand); + + return ActionResult.newResult(EnumActionResult.SUCCESS, stack); + + } + + @Override + public boolean getIsRepairable(ItemStack stack, ItemStack stack2){ + return false; + } + + @Override + public int getItemEnchantability(){ + return 0; + } + + @Override + public boolean isEnchantable(ItemStack stack){ + return false; + } + + @Override + public boolean isBookEnchantable(ItemStack stack, ItemStack book){ + return false; + } + + // Cannot be dropped + @Override + public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player){ + return false; + } + +// @Override +// public void onUsingTick(ItemStack stack, EntityLivingBase player, int count){ +// // player.getItemInUseMaxCount() is named incorrectly; you only have to look at the method to see what it really +// // does. +// if(stack.getItemDamage() + player.getItemInUseMaxCount() > stack.getMaxDamage()) +// player.replaceItemInInventory(player.getActiveHand() == EnumHand.MAIN_HAND ? 98 : 99, ItemStack.EMPTY); +// } + + @Override + public void onPlayerStoppedUsing(ItemStack stack, World world, EntityLivingBase entity, int timeLeft){ + // Decreases the timer by the amount it should have been decreased while the bow was in use. + if(!world.isRemote) stack.setItemDamage(stack.getItemDamage() + (this.getMaxItemUseDuration(stack) - timeLeft)); + + if(entity instanceof EntityPlayer){ + + EntityPlayer player = (EntityPlayer)entity; + + int charge = this.getMaxItemUseDuration(stack) - timeLeft; + charge = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, world, (EntityPlayer)entity, charge, true); + if(charge < 0) return; + + if(stack.getTagCompound() != null){ + int shotsLeft = stack.getTagCompound().getInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY); + stack.getTagCompound().setInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY, shotsLeft - 1); + if(shotsLeft == 0 && !world.isRemote){ + stack.setItemDamage(getMaxDamage(stack) - getAnimationFrames()); + } + } + + float velocity = (float)charge / DRAW_TIME; + velocity = (velocity * velocity + velocity * 2) / 3; + + if(velocity > 1) velocity = 1; + + if((double)velocity >= 0.1D){ + + if(!world.isRemote){ + EntityFlamecatcherArrow arrow = new EntityFlamecatcherArrow(world); + arrow.aim(player, EntityFlamecatcherArrow.SPEED * velocity); + world.spawnEntity(arrow); + } + + world.playSound(null, player.posX, player.posY, player.posZ, + WizardrySounds.ITEM_FLAMECATCHER_SHOOT, WizardrySounds.SPELLS, 1, 1); + + world.playSound(null, player.posX, player.posY, player.posZ, + WizardrySounds.ITEM_FLAMECATCHER_FLAME, WizardrySounds.SPELLS, 1, 1); + } + } + } + +} diff --git a/src/main/java/electroblob/wizardry/registry/Spells.java b/src/main/java/electroblob/wizardry/registry/Spells.java index bbc15c90..cee38c17 100644 --- a/src/main/java/electroblob/wizardry/registry/Spells.java +++ b/src/main/java/electroblob/wizardry/registry/Spells.java @@ -253,6 +253,7 @@ public final class Spells { public static final Spell radiant_totem = placeholder(); public static final Spell firestorm = placeholder(); + public static final Spell flamecatcher = placeholder(); public static final Spell zombie_apocalypse = placeholder(); public static final Spell boulder = placeholder(); public static final Spell celestial_smite = placeholder(); @@ -472,6 +473,7 @@ public final class Spells { registry.register(new RadiantTotem()); registry.register(new Firestorm()); + registry.register(new Flamecatcher()); registry.register(new ZombieApocalypse()); registry.register(new Boulder()); registry.register(new CelestialSmite()); diff --git a/src/main/java/electroblob/wizardry/registry/WizardryEntities.java b/src/main/java/electroblob/wizardry/registry/WizardryEntities.java index 12b3df17..d5568de0 100644 --- a/src/main/java/electroblob/wizardry/registry/WizardryEntities.java +++ b/src/main/java/electroblob/wizardry/registry/WizardryEntities.java @@ -112,6 +112,7 @@ public class WizardryEntities { registry.register(createEntry(EntityForceArrow.class, "force_arrow", TrackingType.PROJECTILE).build()); registry.register(createEntry(EntityDart.class, "dart", TrackingType.PROJECTILE).build()); registry.register(createEntry(EntityIceLance.class, "ice_lance", TrackingType.PROJECTILE).build()); + registry.register(createEntry(EntityFlamecatcherArrow.class, "flamecatcher_arrow", TrackingType.PROJECTILE).build()); // Directionless projectiles registry.register(createEntry(EntityFirebomb.class, "firebomb", TrackingType.PROJECTILE).build()); diff --git a/src/main/java/electroblob/wizardry/registry/WizardryItems.java b/src/main/java/electroblob/wizardry/registry/WizardryItems.java index 440c1d84..ec8ea516 100644 --- a/src/main/java/electroblob/wizardry/registry/WizardryItems.java +++ b/src/main/java/electroblob/wizardry/registry/WizardryItems.java @@ -212,6 +212,7 @@ public final class WizardryItems { public static final Item spectral_boots = placeholder(); public static final Item lightning_hammer = placeholder(); + public static final Item flamecatcher = placeholder(); public static final Item ring_condensing = placeholder(); public static final Item ring_siphoning = placeholder(); @@ -583,6 +584,7 @@ public final class WizardryItems { registerItem(registry, "spectral_boots", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.FEET)); registerItem(registry, "lightning_hammer", new ItemLightningHammer()); + registerItem(registry, "flamecatcher", new ItemFlamecatcher()); registerItem(registry, "ring_condensing", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING)); registerItem(registry, "ring_siphoning", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING)); diff --git a/src/main/java/electroblob/wizardry/registry/WizardrySounds.java b/src/main/java/electroblob/wizardry/registry/WizardrySounds.java index e1610825..81295678 100644 --- a/src/main/java/electroblob/wizardry/registry/WizardrySounds.java +++ b/src/main/java/electroblob/wizardry/registry/WizardrySounds.java @@ -43,6 +43,8 @@ public final class WizardrySounds { public static final SoundEvent ITEM_PURIFYING_ELIXIR_DRINK = createSound("item.purifying_elixir.drink"); public static final SoundEvent ITEM_MANA_FLASK_USE = createSound("item.mana_flask.use"); public static final SoundEvent ITEM_MANA_FLASK_RECHARGE = createSound("item.mana_flask.recharge"); + public static final SoundEvent ITEM_FLAMECATCHER_SHOOT = createSound("item.flamecatcher.shoot"); + public static final SoundEvent ITEM_FLAMECATCHER_FLAME = createSound("item.flamecatcher.flame"); public static final SoundEvent ENTITY_BLACK_HOLE_AMBIENT = createSound("entity.black_hole.ambient"); public static final SoundEvent ENTITY_BLACK_HOLE_VANISH = createSound("entity.black_hole.vanish"); @@ -124,6 +126,7 @@ public final class WizardrySounds { public static final SoundEvent ENTITY_FIREBOMB_THROW = createSound("entity.firebomb.throw"); public static final SoundEvent ENTITY_FIREBOMB_SMASH = createSound("entity.firebomb.smash"); public static final SoundEvent ENTITY_FIREBOMB_FIRE = createSound("entity.firebomb.fire"); + public static final SoundEvent ENTITY_FLAMECATCHER_ARROW_HIT = createSound("entity.flamecatcher_arrow.hit"); public static final SoundEvent ENTITY_FORCE_ARROW_HIT = createSound("entity.force_arrow.hit"); public static final SoundEvent ENTITY_FORCE_ORB_HIT = createSound("entity.force_orb.hit"); public static final SoundEvent ENTITY_FORCE_ORB_HIT_BLOCK = createSound("entity.force_orb.hit_block"); diff --git a/src/main/java/electroblob/wizardry/spell/Flamecatcher.java b/src/main/java/electroblob/wizardry/spell/Flamecatcher.java new file mode 100644 index 00000000..fb2035fe --- /dev/null +++ b/src/main/java/electroblob/wizardry/spell/Flamecatcher.java @@ -0,0 +1,43 @@ +package electroblob.wizardry.spell; + +import electroblob.wizardry.registry.WizardryItems; +import electroblob.wizardry.util.ParticleBuilder; +import electroblob.wizardry.util.ParticleBuilder.Type; +import electroblob.wizardry.util.SpellModifiers; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.world.World; + +public class Flamecatcher extends SpellConjuration { + + public static final String SHOT_COUNT = "shot_count"; + public static final String SHOTS_REMAINING_NBT_KEY = "shotsRemaining"; + + public Flamecatcher(){ + super("flamecatcher", WizardryItems.flamecatcher); + addProperties(RANGE, SHOT_COUNT, DAMAGE, BURN_DURATION); + } + + @Override + protected void addItemExtras(EntityPlayer caster, ItemStack stack, SpellModifiers modifiers){ + if(stack.getTagCompound() == null) stack.setTagCompound(new NBTTagCompound()); + stack.getTagCompound().setInteger(SHOTS_REMAINING_NBT_KEY, (int)(getProperty(SHOT_COUNT).intValue() * modifiers.get(SpellModifiers.POTENCY))); + } + + @Override + protected void spawnParticles(World world, EntityLivingBase caster, SpellModifiers modifiers){ + + ParticleBuilder.create(Type.BUFF).entity(caster).clr(0xff6d00).spawn(world); + + for(int i=0; i<10; i++){ + double x = caster.posX + world.rand.nextDouble() * 2 - 1; + double y = caster.posY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble(); + double z = caster.posZ + world.rand.nextDouble() * 2 - 1; + world.spawnParticle(EnumParticleTypes.FLAME, x, y, z, 0, 0, 0); + } + } + +} diff --git a/src/main/java/electroblob/wizardry/spell/SpellConjuration.java b/src/main/java/electroblob/wizardry/spell/SpellConjuration.java index 55eed416..91ab8b59 100644 --- a/src/main/java/electroblob/wizardry/spell/SpellConjuration.java +++ b/src/main/java/electroblob/wizardry/spell/SpellConjuration.java @@ -83,17 +83,29 @@ public class SpellConjuration extends Spell { ItemStack stack = new ItemStack(item); + if(InventoryUtils.doesPlayerHaveItem(caster, item)) return false; + IConjuredItem.setDurationMultiplier(stack, modifiers.get(WizardryItems.duration_upgrade)); IConjuredItem.setDamageMultiplier(stack, modifiers.get(SpellModifiers.POTENCY)); - - if(InventoryUtils.doesPlayerHaveItem(caster, item)) return false; - + + addItemExtras(caster, stack, modifiers); + if(caster.getHeldItemMainhand().isEmpty()){ caster.setHeldItem(EnumHand.MAIN_HAND, stack); - return true; }else{ - return caster.inventory.addItemStackToInventory(stack); + if(!caster.inventory.addItemStackToInventory(stack)) return false; } + + return true; } + /** + * Called directly before the conjured item is added to the inventory to perform additional behaviour (such + * as NBT modification). Does nothing by default. + * @param caster The player that cast this spell + * @param stack The item stack being conjured + * @param modifiers The modifiers this spell was cast with + */ + protected void addItemExtras(EntityPlayer caster, ItemStack stack, SpellModifiers modifiers){} + } diff --git a/src/main/resources/assets/ebwizardry/lang/en_gb.lang b/src/main/resources/assets/ebwizardry/lang/en_gb.lang index be9ae190..0e8d0898 100644 --- a/src/main/resources/assets/ebwizardry/lang/en_gb.lang +++ b/src/main/resources/assets/ebwizardry/lang/en_gb.lang @@ -260,6 +260,7 @@ item.ebwizardry\:spectral_leggings.name=Spectral Leggings item.ebwizardry\:spectral_boots.name=Spectral Boots item.ebwizardry\:lightning_hammer.name=Lightning Hammer +item.ebwizardry\:flamecatcher.name=Flamecatcher item.ebwizardry\:generic.disabled=This item has been disabled in the config @@ -621,6 +622,7 @@ entity.ebwizardry\:ice_lance.name=Magic entity.ebwizardry\:smoke_bomb.name=Magic entity.ebwizardry\:ice_spike.name=Magic entity.ebwizardry\:combustion_rune.name=Magic +entity.ebwizardry\:flamecatcher_arrow.name=Magic entity.ebwizardry\:black_hole.name=Black Hole entity.ebwizardry\:shield.name=Shield @@ -825,6 +827,7 @@ spell.ebwizardry\:fire_sigil=Fire Sigil spell.ebwizardry\:fireskin=Fireskin spell.ebwizardry\:firestorm=Firestorm spell.ebwizardry\:fire_breath=Fire Breath +spell.ebwizardry\:flamecatcher=Flamecatcher spell.ebwizardry\:flame_ray=Flame Ray spell.ebwizardry\:flaming_axe=Flaming Axe spell.ebwizardry\:flaming_weapon=Flaming Weapon @@ -1013,6 +1016,7 @@ spell.ebwizardry\:fire_sigil.desc=Places a magical fire trap on the ground which spell.ebwizardry\:fireskin.desc=Cloaks the caster in flames for 30 seconds, causing anything that attacks them to catch fire. spell.ebwizardry\:firestorm.desc="Purge the land and purge the soil!\nTrees shall burn and lakes shall boil!\nTorch the wood and scorch the stone!\nAll bow before the infernal throne!" spell.ebwizardry\:fire_breath.desc="I am the dragon." +spell.ebwizardry\:flamecatcher.desc=It is said that in times of need, Flamecatcher offers her power to worthy pyromancers, only to vanish back into the night once her deed is done. spell.ebwizardry\:flame_ray.desc=Creates a stream of flames in the direction you are pointing which sets on fire and continually damages targets. spell.ebwizardry\:flaming_axe.desc=Creates a flaming axe which sets enemies on fire when hit. Lasts for 30 seconds. spell.ebwizardry\:flaming_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of flame, causing it to set fire to its victims. The magic wears off after 45 seconds. diff --git a/src/main/resources/assets/ebwizardry/lang/en_us.lang b/src/main/resources/assets/ebwizardry/lang/en_us.lang index af2ab928..b7533fe4 100644 --- a/src/main/resources/assets/ebwizardry/lang/en_us.lang +++ b/src/main/resources/assets/ebwizardry/lang/en_us.lang @@ -260,6 +260,7 @@ item.ebwizardry\:spectral_leggings.name=Spectral Leggings item.ebwizardry\:spectral_boots.name=Spectral Boots item.ebwizardry\:lightning_hammer.name=Lightning Hammer +item.ebwizardry\:flamecatcher.name=Flamecatcher item.ebwizardry\:generic.disabled=This item has been disabled in the config @@ -621,6 +622,7 @@ entity.ebwizardry\:ice_lance.name=Magic entity.ebwizardry\:smoke_bomb.name=Magic entity.ebwizardry\:ice_spike.name=Magic entity.ebwizardry\:combustion_rune.name=Magic +entity.ebwizardry\:flamecatcher_arrow.name=Magic entity.ebwizardry\:black_hole.name=Black Hole entity.ebwizardry\:shield.name=Shield @@ -825,6 +827,7 @@ spell.ebwizardry\:fire_sigil=Fire Sigil spell.ebwizardry\:fireskin=Fireskin spell.ebwizardry\:firestorm=Firestorm spell.ebwizardry\:fire_breath=Fire Breath +spell.ebwizardry\:flamecatcher=Flamecatcher spell.ebwizardry\:flame_ray=Flame Ray spell.ebwizardry\:flaming_axe=Flaming Axe spell.ebwizardry\:flaming_weapon=Flaming Weapon @@ -1013,6 +1016,7 @@ spell.ebwizardry\:fire_sigil.desc=Places a magical fire trap on the ground which spell.ebwizardry\:fireskin.desc=Cloaks the caster in flames for 30 seconds, causing anything that attacks them to catch fire. spell.ebwizardry\:firestorm.desc="Purge the land and purge the soil!\nTrees shall burn and lakes shall boil!\nTorch the wood and scorch the stone!\nAll bow before the infernal throne!" spell.ebwizardry\:fire_breath.desc="I am the dragon." +spell.ebwizardry\:flamecatcher.desc=It is said that in times of need, Flamecatcher offers her power to worthy pyromancers, only to vanish back into the night once her deed is done. spell.ebwizardry\:flame_ray.desc=Creates a stream of flames in the direction you are pointing which sets on fire and continually damages targets. spell.ebwizardry\:flaming_axe.desc=Creates a flaming axe which sets enemies on fire when hit. Lasts for 30 seconds. spell.ebwizardry\:flaming_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of flame, causing it to set fire to its victims. The magic wears off after 45 seconds. diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher.json new file mode 100644 index 00000000..a2337094 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher.json @@ -0,0 +1,105 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_standby" + }, + "display": { + "thirdperson_righthand": { + "rotation": [ -80, 260, -40 ], + "translation": [ -1, -2, 2.5 ], + "scale": [ 0.9, 0.9, 0.9 ] + }, + "thirdperson_lefthand": { + "rotation": [ -80, -280, 40 ], + "translation": [ -1, -2, 2.5 ], + "scale": [ 0.9, 0.9, 0.9 ] + }, + "firstperson_righthand": { + "rotation": [ 0, -90, 25 ], + "translation": [ 1.13, 3.2, 1.13], + "scale": [ 0.68, 0.68, 0.68 ] + }, + "firstperson_lefthand": { + "rotation": [ 0, 90, -25 ], + "translation": [ 1.13, 3.2, 1.13], + "scale": [ 0.68, 0.68, 0.68 ] + } + }, + "overrides": [ + { + "predicate": { + "pulling": 1 + }, + "model": "ebwizardry:item/flamecatcher_pulling_0" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.65 + }, + "model": "ebwizardry:item/flamecatcher_pulling_1" + }, + { + "predicate": { + "pulling": 1, + "pull": 0.9 + }, + "model": "ebwizardry:item/flamecatcher_pulling_2" + }, + { + "predicate": { + "conjuring": 1 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_0" + }, + { + "predicate": { + "conjuring": 1, + "conjure": 0.125 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_1" + }, + { + "predicate": { + "conjuring": 1, + "conjure": 0.25 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_2" + }, + { + "predicate": { + "conjuring": 1, + "conjure": 0.375 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_3" + }, + { + "predicate": { + "conjuring": 1, + "conjure": 0.5 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_4" + }, + { + "predicate": { + "conjuring": 1, + "conjure": 0.625 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_5" + }, + { + "predicate": { + "conjuring": 1, + "conjure": 0.75 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_6" + }, + { + "predicate": { + "conjuring": 1, + "conjure": 0.875 + }, + "model": "ebwizardry:item/flamecatcher_conjuring_7" + } + ] +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_0.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_0.json new file mode 100644 index 00000000..bb2a7ef2 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_0.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_0" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_1.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_1.json new file mode 100644 index 00000000..26ab48e9 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_1.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_1" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_2.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_2.json new file mode 100644 index 00000000..6ab25cd2 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_2.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_2" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_3.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_3.json new file mode 100644 index 00000000..dd041724 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_3.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_3" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_4.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_4.json new file mode 100644 index 00000000..5e980ed4 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_4.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_4" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_5.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_5.json new file mode 100644 index 00000000..bd32f65c --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_5.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_5" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_6.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_6.json new file mode 100644 index 00000000..6669564e --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_6.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_6" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_7.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_7.json new file mode 100644 index 00000000..80bbd6d5 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_conjuring_7.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_conjuring_7" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_0.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_0.json new file mode 100644 index 00000000..528b5b65 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_0.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_pulling_0" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_1.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_1.json new file mode 100644 index 00000000..ae4d8fa2 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_1.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_pulling_1" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_2.json b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_2.json new file mode 100644 index 00000000..ce385d5b --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/flamecatcher_pulling_2.json @@ -0,0 +1,6 @@ +{ + "parent": "item/bow", + "textures": { + "layer0": "ebwizardry:items/flamecatcher_pulling_2" + } +} diff --git a/src/main/resources/assets/ebwizardry/sounds.json b/src/main/resources/assets/ebwizardry/sounds.json index 0b177cdf..92d3bc4c 100644 --- a/src/main/resources/assets/ebwizardry/sounds.json +++ b/src/main/resources/assets/ebwizardry/sounds.json @@ -14,6 +14,8 @@ "item.purifying_elixir.drink": {"category": "player", "sounds": ["ebwizardry:buff_large"]}, "item.mana_flask.use": {"category": "player", "sounds": ["item/bottle/fill1", "item/bottle/fill2", "item/bottle/fill3", "item/bottle/fill4"]}, "item.mana_flask.recharge": {"category": "player", "sounds": ["ebwizardry:conjure"]}, + "item.flamecatcher.shoot": {"category": "player", "sounds": ["fireworks/launch1"]}, + "item.flamecatcher.flame": {"category": "player", "sounds": ["ebwizardry:combust"]}, "entity.black_hole.ambient": {"category": "spells", "sounds": ["portal/portal"]}, "entity.black_hole.vanish": {"category": "spells", "sounds": ["portal/trigger"]}, @@ -95,6 +97,7 @@ "entity.firebomb.throw": {"category": "spells", "sounds": ["random/bow"]}, "entity.firebomb.smash": {"category": "spells", "sounds": ["random/glass1", "random/glass2", "random/glass3"]}, "entity.firebomb.fire": {"category": "spells", "sounds": ["ebwizardry:combust"]}, + "entity.flamecatcher_arrow.hit": {"category": "spells", "sounds": ["damage/hit1", "damage/hit2", "damage/hit3"]}, "entity.force_arrow.hit": {"category": "spells", "sounds": ["fireworks/blast1"]}, "entity.force_orb.hit": {"category": "spells", "sounds": ["damage/hit1", "damage/hit2", "damage/hit3"]}, "entity.force_orb.hit_block": {"category": "spells", "sounds": ["fireworks/blast1"]}, @@ -184,6 +187,7 @@ "spell.fire_breath.start": {"category": "spells", "sounds": ["ebwizardry:flames_start"]}, "spell.fire_breath.loop": {"category": "spells", "sounds": ["ebwizardry:flames_loop"]}, "spell.fire_breath.end": {"category": "spells", "sounds": ["ebwizardry:flames_end"]}, + "spell.flamecatcher": {"category": "spells", "sounds": ["ebwizardry:buff"]}, "spell.flame_ray.start": {"category": "spells", "sounds": ["ebwizardry:flames_start"]}, "spell.flame_ray.loop": {"category": "spells", "sounds": ["ebwizardry:flames_loop"]}, "spell.flame_ray.end": {"category": "spells", "sounds": ["ebwizardry:flames_end"]}, diff --git a/src/main/resources/assets/ebwizardry/spells/flamecatcher.json b/src/main/resources/assets/ebwizardry/spells/flamecatcher.json new file mode 100644 index 00000000..e35c2093 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/spells/flamecatcher.json @@ -0,0 +1,26 @@ +{ + "enabled": { + "book": true, + "scroll": true, + "wands": true, + "npcs": true, + "dispensers": true, + "commands": true, + "treasure": true, + "trades": true, + "looting": true + }, + "tier": "master", + "element": "fire", + "type": "utility", + "cost": 100, + "chargeup": 20, + "cooldown": 150, + "base_properties": { + "item_lifetime": 600, + "range": 40, + "shot_count": 5, + "damage": 16, + "burn_duration": 15 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ebwizardry/textures/entity/flamecatcher_arrow.png b/src/main/resources/assets/ebwizardry/textures/entity/flamecatcher_arrow.png new file mode 100644 index 00000000..db64d4b8 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/entity/flamecatcher_arrow.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_0.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_0.png new file mode 100644 index 00000000..d2765163 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_0.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_1.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_1.png new file mode 100644 index 00000000..5dc4013a Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_1.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_2.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_2.png new file mode 100644 index 00000000..8df96747 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_2.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_3.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_3.png new file mode 100644 index 00000000..9d0eff4d Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_3.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_4.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_4.png new file mode 100644 index 00000000..49b2b8c5 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_4.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_5.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_5.png new file mode 100644 index 00000000..5d308b65 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_5.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_6.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_6.png new file mode 100644 index 00000000..0660ad33 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_6.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_7.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_7.png new file mode 100644 index 00000000..9374f0a5 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_conjuring_7.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_0.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_0.png new file mode 100644 index 00000000..40221234 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_0.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_0.png.mcmeta b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_0.png.mcmeta new file mode 100644 index 00000000..eb5c833c --- /dev/null +++ b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_0.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + + "frametime": 2, + + "frames": [ +0, + 1, 2, 3, 4, 5, 6, 7] + + } + +} \ No newline at end of file diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_1.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_1.png new file mode 100644 index 00000000..811fec21 Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_1.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_1.png.mcmeta b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_1.png.mcmeta new file mode 100644 index 00000000..eb5c833c --- /dev/null +++ b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_1.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + + "frametime": 2, + + "frames": [ +0, + 1, 2, 3, 4, 5, 6, 7] + + } + +} \ No newline at end of file diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_2.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_2.png new file mode 100644 index 00000000..5a68646e Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_2.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_2.png.mcmeta b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_2.png.mcmeta new file mode 100644 index 00000000..eb5c833c --- /dev/null +++ b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_pulling_2.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + + "frametime": 2, + + "frames": [ +0, + 1, 2, 3, 4, 5, 6, 7] + + } + +} \ No newline at end of file diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_standby.png b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_standby.png new file mode 100644 index 00000000..2c680f9d Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_standby.png differ diff --git a/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_standby.png.mcmeta b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_standby.png.mcmeta new file mode 100644 index 00000000..eb5c833c --- /dev/null +++ b/src/main/resources/assets/ebwizardry/textures/items/flamecatcher_standby.png.mcmeta @@ -0,0 +1,12 @@ +{ + "animation": { + + "frametime": 2, + + "frames": [ +0, + 1, 2, 3, 4, 5, 6, 7] + + } + +} \ No newline at end of file diff --git a/src/main/resources/assets/ebwizardry/textures/spells/flamecatcher.png b/src/main/resources/assets/ebwizardry/textures/spells/flamecatcher.png new file mode 100644 index 00000000..aaebf85d Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/spells/flamecatcher.png differ