From 7d88f73dc6e76defb28833981ed237f1b37a758d Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 7 Nov 2024 22:00:56 +0100 Subject: [PATCH] black powder effects --- .../java/com/hbm/crafting/WeaponRecipes.java | 5 ++ .../inventory/recipes/AmmoPressRecipes.java | 14 ++++ .../hbm/items/weapon/sedna/BulletConfig.java | 2 + .../hbm/items/weapon/sedna/factory/Lego.java | 2 + .../weapon/sedna/factory/XFactory12ga.java | 6 +- .../sedna/factory/XFactoryBlackPowder.java | 8 +- .../particle/ParticleBlackPowderSmoke.java | 78 ++++++++++++++++++ .../particle/ParticleBlackPowderSpark.java | 51 ++++++++++++ .../particle/helper/BlackPowderHelper.java | 67 +++++++++++++++ .../hbm/particle/helper/IParticleCreator.java | 7 ++ .../hbm/particle/helper/ParticleCreators.java | 1 + .../assets/hbm/sounds/block/warnAPUFire.ogg | Bin 0 -> 20697 bytes 12 files changed, 234 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/hbm/particle/ParticleBlackPowderSmoke.java create mode 100644 src/main/java/com/hbm/particle/ParticleBlackPowderSpark.java create mode 100644 src/main/java/com/hbm/particle/helper/BlackPowderHelper.java create mode 100644 src/main/resources/assets/hbm/sounds/block/warnAPUFire.ogg diff --git a/src/main/java/com/hbm/crafting/WeaponRecipes.java b/src/main/java/com/hbm/crafting/WeaponRecipes.java index 1a68a8fa7..f2be25e18 100644 --- a/src/main/java/com/hbm/crafting/WeaponRecipes.java +++ b/src/main/java/com/hbm/crafting/WeaponRecipes.java @@ -9,6 +9,7 @@ import com.hbm.inventory.material.Mats; import static com.hbm.inventory.OreDictManager.*; import com.hbm.items.ItemAmmoEnums.*; +import com.hbm.items.ItemEnums.EnumCasingType; import com.hbm.items.food.ItemConserve.EnumFoodType; import com.hbm.items.machine.ItemCircuit.EnumCircuitType; import com.hbm.items.ModItems; @@ -32,6 +33,10 @@ public class WeaponRecipes { //SEDNA Parts CraftingManager.addRecipeAuto(new ItemStack(ModItems.part_stock, 1, Mats.MAT_WOOD.id), new Object[] { "WWW", " W", 'W', KEY_PLANKS }); CraftingManager.addRecipeAuto(new ItemStack(ModItems.part_grip, 1, Mats.MAT_WOOD.id), new Object[] { "W ", " W", " W", 'W', KEY_PLANKS }); + + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.casing, EnumCasingType.SHOTSHELL, 2), new Object[] { "P", "C", 'P', GUNMETAL.plate(), 'C', DictFrame.fromOne(ModItems.casing, EnumCasingType.LARGE) }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.casing, EnumCasingType.BUCKSHOT, 2), new Object[] { "P", "C", 'P', ANY_PLASTIC.ingot(), 'C', DictFrame.fromOne(ModItems.casing, EnumCasingType.LARGE) }); + CraftingManager.addRecipeAuto(DictFrame.fromOne(ModItems.casing, EnumCasingType.BUCKSHOT_ADVANCED, 2), new Object[] { "P", "C", 'P', ANY_PLASTIC.ingot(), 'C', DictFrame.fromOne(ModItems.casing, EnumCasingType.LARGE_STEEL) }); //SEDNA Guns CraftingManager.addRecipeAuto(new ItemStack(ModItems.gun_pepperbox, 1), new Object[] { "IIW", " C", 'I', IRON.ingot(), 'W', KEY_PLANKS, 'C', CU.ingot() }); diff --git a/src/main/java/com/hbm/inventory/recipes/AmmoPressRecipes.java b/src/main/java/com/hbm/inventory/recipes/AmmoPressRecipes.java index a4ae668ba..cb9602261 100644 --- a/src/main/java/com/hbm/inventory/recipes/AmmoPressRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/AmmoPressRecipes.java @@ -29,6 +29,7 @@ public class AmmoPressRecipes extends SerializableRecipe { public void registerDefaults() { OreDictStack lead = new OreDictStack(PB.ingot()); + OreDictStack nugget = new OreDictStack(PB.nugget()); OreDictStack steel = new OreDictStack(STEEL.ingot()); OreDictStack wSteel = new OreDictStack(WEAPONSTEEL.ingot()); OreDictStack copper = new OreDictStack(CU.ingot()); @@ -177,6 +178,19 @@ public class AmmoPressRecipes extends SerializableRecipe { null, uranium.copy(2), null, null, smokeless.copy(6), null, null, sBig, null)); + + recipes.add(new AmmoPressRecipe(DictFrame.fromOne(ModItems.ammo_standard, EnumAmmo.G12_BP, 6), + null, nugget.copy(6), null, + null, smokeless, null, + null, bpShell, null)); + recipes.add(new AmmoPressRecipe(DictFrame.fromOne(ModItems.ammo_standard, EnumAmmo.G12_MAGNUM, 6), + null, nugget.copy(8), null, + null, smokeless, null, + null, bpShell, null)); + recipes.add(new AmmoPressRecipe(DictFrame.fromOne(ModItems.ammo_standard, EnumAmmo.G12_SLUG, 6), + null, lead, null, + null, smokeless, null, + null, bpShell, null)); } @Override diff --git a/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java b/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java index 4fdd36eca..213a2684b 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java +++ b/src/main/java/com/hbm/items/weapon/sedna/BulletConfig.java @@ -72,6 +72,7 @@ public class BulletConfig implements Cloneable { public boolean isSpectral = false; public int selfDamageDelay = 2; + public boolean blackPowder = false; public boolean renderRotations = true; public SpentCasing casing; public BiConsumer renderer; @@ -111,6 +112,7 @@ public class BulletConfig implements Cloneable { public BulletConfig setDoesPenetrate(boolean pen) { this.doesPenetrate = pen; return this; } public BulletConfig setSpectral(boolean spectral) { this.isSpectral = spectral; return this; } public BulletConfig setSelfDamageDelay(int delay) { this.selfDamageDelay = delay; return this; } + public BulletConfig setBlackPowder(boolean bp) { this.blackPowder = bp; return this; } public BulletConfig setRenderRotations(boolean rot) { this.renderRotations = rot; return this; } public BulletConfig setCasing(SpentCasing casing) { this.casing = casing; return this; } diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java b/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java index 70a837049..a7f9dc938 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/Lego.java @@ -20,6 +20,7 @@ import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext; import com.hbm.items.weapon.sedna.ItemGunBaseNT.SmokeNode; import com.hbm.items.weapon.sedna.Receiver; import com.hbm.items.weapon.sedna.mags.IMagazine; +import com.hbm.particle.helper.BlackPowderHelper; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationSequence; import com.hbm.render.anim.HbmAnimations.AnimType; @@ -221,6 +222,7 @@ public class Lego { float spread = calcSpread(ctx, stack, primary, calcWear, index, aim); EntityBulletBaseMK4 mk4 = new EntityBulletBaseMK4(entity, config, damage, spread, sideOffset, heightOffset, forwardOffset); if(ItemGunBaseNT.getIsLockedOn(stack)) mk4.lockonTarget = entity.worldObj.getEntityByID(ItemGunBaseNT.getLockonTarget(stack)); + if(i == 0 && config.blackPowder) BlackPowderHelper.composeEffect(entity.worldObj, mk4.posX, mk4.posY, mk4.posZ, mk4.motionX, mk4.motionY, mk4.motionZ, 10, 0.25F, 0.5F, 10, 0.25F); entity.worldObj.spawnEntityInWorld(mk4); } diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java index c766034e2..4b3eada23 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java @@ -50,9 +50,9 @@ public class XFactory12ga { public static void init() { - g12_bp = new BulletConfig().setItem(EnumAmmo.G12_BP).setProjectiles(8).setSpread(0.05F).setRicochetAngle(15).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(SpentCasing.COLOR_CASE_BRASS, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_BP")); - g12_bp_magnum = new BulletConfig().setItem(EnumAmmo.G12_BP_MAGNUM).setProjectiles(4).setSpread(0.05F).setRicochetAngle(25).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(SpentCasing.COLOR_CASE_BRASS, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_BP_MAGNUM")); - g12_bp_slug = new BulletConfig().setItem(EnumAmmo.G12_BP_SLUG).setSpread(0.01F).setRicochetAngle(5).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(SpentCasing.COLOR_CASE_BRASS, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_BP_SLUG")); + g12_bp = new BulletConfig().setItem(EnumAmmo.G12_BP).setBlackPowder(true).setProjectiles(8).setSpread(0.05F).setRicochetAngle(15).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(SpentCasing.COLOR_CASE_BRASS, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_BP")); + g12_bp_magnum = new BulletConfig().setItem(EnumAmmo.G12_BP_MAGNUM).setBlackPowder(true).setProjectiles(4).setSpread(0.05F).setRicochetAngle(25).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(SpentCasing.COLOR_CASE_BRASS, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_BP_MAGNUM")); + g12_bp_slug = new BulletConfig().setItem(EnumAmmo.G12_BP_SLUG).setBlackPowder(true).setSpread(0.01F).setRicochetAngle(5).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(SpentCasing.COLOR_CASE_BRASS, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_BP_SLUG")); g12 = new BulletConfig().setItem(EnumAmmo.G12).setProjectiles(8).setSpread(0.05F).setRicochetAngle(15).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(0xB52B2B, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA")); g12_slug = new BulletConfig().setItem(EnumAmmo.G12_SLUG).setSpread(0.0F).setRicochetAngle(25).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(0x393939, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_SLUG")); g12_flechette = new BulletConfig().setItem(EnumAmmo.G12_FLECHETTE).setProjectiles(8).setSpread(0.025F).setRicochetAngle(5).setCasing(new SpentCasing(CasingType.SHOTGUN).setColor(0x3C80F0, SpentCasing.COLOR_CASE_BRASS).setScale(0.75F).register("12GA_FLECHETTE")); diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java index 60e3182b0..3cb6a8403 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryBlackPowder.java @@ -20,10 +20,10 @@ import net.minecraft.item.ItemStack; public class XFactoryBlackPowder { - public static BulletConfig stone = new BulletConfig().setItem(EnumAmmo.STONE).setSpread(0.025F).setRicochetAngle(15); - public static BulletConfig flint = new BulletConfig().setItem(EnumAmmo.STONE_AP).setSpread(0.01F).setRicochetAngle(5).setDoesPenetrate(true).setDamage(1.75F); - public static BulletConfig iron = new BulletConfig().setItem(EnumAmmo.STONE_IRON).setSpread(0F).setRicochetAngle(90).setRicochetCount(5).setDoesPenetrate(true).setDamageFalloutByPen(false).setDamage(2F); - public static BulletConfig shot = new BulletConfig().setItem(EnumAmmo.STONE_SHOT).setSpread(0.1F).setRicochetAngle(45).setProjectiles(6, 6).setDamage(0.5F); + public static BulletConfig stone = new BulletConfig().setItem(EnumAmmo.STONE).setBlackPowder(true).setSpread(0.025F).setRicochetAngle(15); + public static BulletConfig flint = new BulletConfig().setItem(EnumAmmo.STONE_AP).setBlackPowder(true).setSpread(0.01F).setRicochetAngle(5).setDoesPenetrate(true).setDamage(1.75F); + public static BulletConfig iron = new BulletConfig().setItem(EnumAmmo.STONE_IRON).setBlackPowder(true).setSpread(0F).setRicochetAngle(90).setRicochetCount(5).setDoesPenetrate(true).setDamageFalloutByPen(false).setDamage(2F); + public static BulletConfig shot = new BulletConfig().setItem(EnumAmmo.STONE_SHOT).setBlackPowder(true).setSpread(0.1F).setRicochetAngle(45).setProjectiles(6, 6).setDamage(0.5F); public static void init() { diff --git a/src/main/java/com/hbm/particle/ParticleBlackPowderSmoke.java b/src/main/java/com/hbm/particle/ParticleBlackPowderSmoke.java new file mode 100644 index 000000000..c11b88f57 --- /dev/null +++ b/src/main/java/com/hbm/particle/ParticleBlackPowderSmoke.java @@ -0,0 +1,78 @@ +package com.hbm.particle; + +import java.awt.Color; + +import com.hbm.main.ModEventHandlerClient; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class ParticleBlackPowderSmoke extends EntityFXRotating { + + public float hue; + + public ParticleBlackPowderSmoke(World world, double x, double y, double z, float scale) { + super(world, x, y, z); + particleIcon = ModEventHandlerClient.particleBase; + this.particleMaxAge = 30 + rand.nextInt(15); + this.particleScale = scale * 0.9F + rand.nextFloat() * 0.2F; + + this.particleGravity = 0F; + + this.hue = 20F + rand.nextFloat() * 20F; + Color color = Color.getHSBColor(hue / 255F, 1F, 1F); + this.particleRed = color.getRed() / 255F; + this.particleGreen = color.getGreen() / 255F; + this.particleBlue = color.getBlue() / 255F; + + this.noClip = true; + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + this.particleAge++; + + if(this.particleAge >= this.particleMaxAge) { + this.setDead(); + } + + this.motionY -= particleGravity; + this.prevRotationPitch = this.rotationPitch; + + float ageScaled = (float) this.particleAge / (float) this.particleMaxAge; + this.rotationPitch += (1 - ageScaled) * 2 * ((this.getEntityId() % 2) - 0.5); + + this.motionX *= 0.65D; + this.motionY *= 0.65D; + this.motionZ *= 0.65D; + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + } + + @Override + public void renderParticle(Tessellator tess, float interp, float sX, float sY, float sZ, float dX, float dZ) { + + double ageScaled = (double) (this.particleAge + interp) / (double) this.particleMaxAge; + + Color color = Color.getHSBColor(hue / 255F, Math.max(1F - (float) ageScaled * 2F, 0), MathHelper.clamp_float(1.25F - (float) ageScaled * 2F, 0.7F, 1F)); + this.particleRed = color.getRed() / 255F; + this.particleGreen = color.getGreen() / 255F; + this.particleBlue = color.getBlue() / 255F; + + this.particleAlpha = (float) Math.pow(1 - Math.min(ageScaled, 1), 0.25); + + tess.setColorRGBA_F(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha * 0.25F); + tess.setNormal(0.0F, 1.0F, 0.0F); + + double scale = (0.25 + ageScaled + (this.particleAge + interp) * 0.025) * this.particleScale; + renderParticleRotated(tess, interp, sX, sY, sZ, dX, dZ, scale); + } +} diff --git a/src/main/java/com/hbm/particle/ParticleBlackPowderSpark.java b/src/main/java/com/hbm/particle/ParticleBlackPowderSpark.java new file mode 100644 index 000000000..7c0e9ea22 --- /dev/null +++ b/src/main/java/com/hbm/particle/ParticleBlackPowderSpark.java @@ -0,0 +1,51 @@ +package com.hbm.particle; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class ParticleBlackPowderSpark extends EntityFX { + + public ParticleBlackPowderSpark(World world, double x, double y, double z, double mX, double mY, double mZ) { + super(world, x, y, z, mX, mY, mZ); + + this.motionX = mX; + this.motionY = mY; + this.motionZ = mZ; + + float f = this.rand.nextFloat() * 0.1F + 0.2F; + this.particleRed = f + 0.7F; + this.particleGreen = f + 0.5F; + this.particleBlue = f; + this.setParticleTextureIndex(0); + this.setSize(0.02F, 0.02F); + this.particleScale *= this.rand.nextFloat() * 0.6F + 0.5F; + this.particleMaxAge = 15 + this.rand.nextInt(5); + + this.particleGravity = 0.01F; + } + + @Override + public void onUpdate() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.motionY -= particleGravity; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.95D; + this.motionY *= 0.95D; + this.motionZ *= 0.95D; + + if(this.particleMaxAge-- <= 0) { + this.setDead(); + } + } + + @Override + @SideOnly(Side.CLIENT) + public int getBrightnessForRender(float interp) { + return 15728880; + } +} diff --git a/src/main/java/com/hbm/particle/helper/BlackPowderHelper.java b/src/main/java/com/hbm/particle/helper/BlackPowderHelper.java new file mode 100644 index 000000000..72aa720c1 --- /dev/null +++ b/src/main/java/com/hbm/particle/helper/BlackPowderHelper.java @@ -0,0 +1,67 @@ +package com.hbm.particle.helper; + +import java.util.Random; + +import com.hbm.particle.ParticleBlackPowderSmoke; +import com.hbm.particle.ParticleBlackPowderSpark; +import com.hbm.util.Vec3NT; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +public class BlackPowderHelper implements IParticleCreator { + + public static void composeEffect(World world, double x, double y, double z, double headingX, double headingY, double headingZ, int cloudCount, float cloudScale, float cloudSpeedMult, int sparkCount, float sparkSpeedMult) { + + NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "blackPowder"); + data.setInteger("cloudCount", cloudCount); + data.setFloat("cloudScale", cloudScale); + data.setFloat("cloudSpeedMult", cloudSpeedMult); + data.setInteger("sparkCount", sparkCount); + data.setFloat("sparkSpeedMult", sparkSpeedMult); + data.setDouble("hX", headingX); + data.setDouble("hY", headingY); + data.setDouble("hZ", headingZ); + IParticleCreator.sendPacket(world, x, y, z, 200, data); + } + + @Override + @SideOnly(Side.CLIENT) + public void makeParticle(World world, EntityPlayer player, TextureManager texman, Random rand, double x, double y, double z, NBTTagCompound data) { + + double headingX = data.getDouble("hX"); + double headingY = data.getDouble("hY"); + double headingZ = data.getDouble("hZ"); + int cloudCount = data.getInteger("cloudCount"); + float cloudScale = data.getFloat("cloudScale"); + float cloudSpeedMult = data.getFloat("cloudSpeedMult"); + int sparkCount = data.getInteger("sparkCount"); + float sparkSpeedMult = data.getFloat("sparkSpeedMult"); + + Vec3NT heading = new Vec3NT(headingX, headingY, headingZ).normalizeSelf(); + + for(int i = 0; i < cloudCount; i++) { + ParticleBlackPowderSmoke particle = new ParticleBlackPowderSmoke(world, x, y, z, cloudScale); + double speedMult = 0.85 + rand.nextDouble() * 0.3; + particle.motionX = heading.xCoord * cloudSpeedMult * speedMult + rand.nextGaussian() * 0.05; + particle.motionY = heading.yCoord * cloudSpeedMult * speedMult + rand.nextGaussian() * 0.05; + particle.motionZ = heading.zCoord * cloudSpeedMult * speedMult + rand.nextGaussian() * 0.05; + Minecraft.getMinecraft().effectRenderer.addEffect(particle); + } + + for(int i = 0; i < sparkCount; i++) { + double speedMult = 0.85 + rand.nextDouble() * 0.3; + ParticleBlackPowderSpark particle = new ParticleBlackPowderSpark(world, x, y, z, + heading.xCoord * sparkSpeedMult * speedMult + rand.nextGaussian() * 0.02, + heading.yCoord * sparkSpeedMult * speedMult + rand.nextGaussian() * 0.02, + heading.zCoord * sparkSpeedMult * speedMult + rand.nextGaussian() * 0.02); + Minecraft.getMinecraft().effectRenderer.addEffect(particle); + } + } +} diff --git a/src/main/java/com/hbm/particle/helper/IParticleCreator.java b/src/main/java/com/hbm/particle/helper/IParticleCreator.java index f55ef2f05..dce577ced 100644 --- a/src/main/java/com/hbm/particle/helper/IParticleCreator.java +++ b/src/main/java/com/hbm/particle/helper/IParticleCreator.java @@ -13,6 +13,13 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; +/** + * Does two cool things: + *
- requires no more additions to ClientProxy which is already bloated, full of other stuff and cumbersome to work with + *
- being a separate class, we can get as messy as we want without affecting other particles, so effects can overall have more logic behind them without turning into a big ugly clump + * @author hbm + * + */ public interface IParticleCreator { @SideOnly(Side.CLIENT) diff --git a/src/main/java/com/hbm/particle/helper/ParticleCreators.java b/src/main/java/com/hbm/particle/helper/ParticleCreators.java index 84df3293b..1e93ed27f 100644 --- a/src/main/java/com/hbm/particle/helper/ParticleCreators.java +++ b/src/main/java/com/hbm/particle/helper/ParticleCreators.java @@ -11,5 +11,6 @@ public class ParticleCreators { particleCreators.put("casingNT", new CasingCreator()); particleCreators.put("flamethrower", new FlameCreator()); particleCreators.put("explosionSmall", new ExplosionSmallCreator()); + particleCreators.put("blackPowder", new BlackPowderHelper()); } } diff --git a/src/main/resources/assets/hbm/sounds/block/warnAPUFire.ogg b/src/main/resources/assets/hbm/sounds/block/warnAPUFire.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5035c21095650e84f0fdc439ffc4feae8c010a9b GIT binary patch literal 20697 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