From 51e392011eaf6975c98007e0400391e1a7089931 Mon Sep 17 00:00:00 2001 From: UFFR Date: Fri, 18 Nov 2022 16:54:01 -0500 Subject: [PATCH 1/4] Basis of casing system All untested and should be considered still in-development. Just commiting for backup. --- .../java/com/hbm/crafting/WeaponRecipes.java | 5 +- .../com/hbm/handler/GunConfiguration.java | 10 +- .../hbm/handler/guncfg/Gun556mmFactory.java | 7 +- src/main/java/com/hbm/main/ClientProxy.java | 1689 +++++++++-------- src/main/java/com/hbm/main/ServerProxy.java | 46 +- .../com/hbm/particle/ParticleSpentCasing.java | 97 + .../com/hbm/particle/SpentCasingConfig.java | 200 ++ .../particle/SpentCasingConfigBuilder.java | 293 +++ .../hbm/textures/particle/casing_brass.png | Bin 0 -> 633 bytes .../hbm/textures/particle/casing_shotgun.png | Bin 0 -> 628 bytes .../assets/hbm/textures/particle/casings.png | Bin 0 -> 773 bytes 11 files changed, 1473 insertions(+), 874 deletions(-) create mode 100644 src/main/java/com/hbm/particle/ParticleSpentCasing.java create mode 100644 src/main/java/com/hbm/particle/SpentCasingConfig.java create mode 100644 src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java create mode 100644 src/main/resources/assets/hbm/textures/particle/casing_brass.png create mode 100644 src/main/resources/assets/hbm/textures/particle/casing_shotgun.png create mode 100644 src/main/resources/assets/hbm/textures/particle/casings.png diff --git a/src/main/java/com/hbm/crafting/WeaponRecipes.java b/src/main/java/com/hbm/crafting/WeaponRecipes.java index 08f268db2..c43fdb11f 100644 --- a/src/main/java/com/hbm/crafting/WeaponRecipes.java +++ b/src/main/java/com/hbm/crafting/WeaponRecipes.java @@ -72,7 +72,6 @@ public class WeaponRecipes { CraftingManager.addRecipeAuto(new ItemStack(ModItems.gun_quadro, 1), new Object[] { "SSS", "SSS", "CM ", 'S', ModItems.hull_small_steel, 'C', ModItems.circuit_targeting_tier3, 'M', ModItems.mechanism_launcher_2 }); CraftingManager.addRecipeAuto(new ItemStack(ModItems.gun_hk69, 1), new Object[] { "SSI", " MB", 'S', ModItems.hull_small_steel, 'I', FE.ingot(), 'M', ModItems.mechanism_launcher_1, 'B', ModItems.bolt_tungsten }); CraftingManager.addRecipeAuto(new ItemStack(ModItems.gun_stinger, 1), new Object[] { "SSW", "CMW", 'S', STEEL.plate(), 'W', TI.plate(), 'C', ModItems.circuit_red_copper, 'M', ModItems.mechanism_launcher_2 }); - CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_stinger_rocket, 4), new Object[] { "SS ", "STI", " IR", 'S', STEEL.plate(), 'T', Item.getItemFromBlock(Blocks.tnt), 'I', AL.plate(), 'R', REDSTONE.dust() }); CraftingManager.addRecipeAuto(new ItemStack(ModItems.gun_revolver, 1), new Object[] { "SSM", " RW", 'S', STEEL.plate(), 'W', KEY_PLANKS, 'R', ModItems.wire_aluminium, 'M', ModItems.mechanism_revolver_1 }); CraftingManager.addRecipeAuto(new ItemStack(ModItems.gun_revolver_saturnite, 1), new Object[] { "SSM", " RW", 'S', BIGMT.plate(), 'W', KEY_PLANKS, 'R', ModItems.wire_tungsten, 'M', ModItems.mechanism_revolver_2 }); CraftingManager.addRecipeAuto(new ItemStack(ModItems.gun_revolver_iron, 1), new Object[] { "SSM", " RW", 'S', FE.plate(), 'W', KEY_PLANKS, 'R', ModItems.wire_aluminium, 'M', ModItems.mechanism_revolver_1 }); @@ -215,8 +214,8 @@ public class WeaponRecipes { CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_folly_du, 1), new Object[] { " B ", "EEE", " S ", 'B', ModItems.folly_bullet_du, 'E', ModBlocks.det_charge, 'S', ModItems.folly_shell }); //Rockets - CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_rocket, 1), new Object[] { " T ", "GCG", " P ", 'T', Blocks.tnt, 'G', ModItems.rocket_fuel, 'C', ModItems.casing_50, 'P', ModItems.primer_50 });// I got tired of changing *all* of them, the stock one is always the first one anyway - CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_rocket, 2), new Object[] { " T ", "GCG", " P ", 'T', ANY_PLASTICEXPLOSIVE.ingot(), 'G', ModItems.rocket_fuel, 'C', ModItems.casing_50, 'P', ModItems.primer_50 }); + CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_rocket, 1), new Object[] { " T ", "GCG", " P ", 'T', ModItems.ball_dynamite, 'G', ModItems.rocket_fuel, 'C', ModItems.hull_small_aluminium, 'P', ModItems.primer_50 });// I got tired of changing *all* of them, the stock one is always the first one anyway + CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_rocket, 2), new Object[] { " T ", "GCG", " P ", 'T', ANY_PLASTICEXPLOSIVE.ingot(), 'G', ModItems.rocket_fuel, 'C', ModItems.hull_small_aluminium, 'P', ModItems.primer_50 }); CraftingManager.addRecipeAuto(ModItems.ammo_rocket.stackFromEnum(AmmoRocket.HE), new Object[] { "G", "R", 'G', ANY_PLASTICEXPLOSIVE.ingot(), 'R', ModItems.ammo_rocket }); CraftingManager.addRecipeAuto(ModItems.ammo_rocket.stackFromEnum(AmmoRocket.INCENDIARY), new Object[] { "G", "R", 'G', P_RED.dust(), 'R', ModItems.ammo_rocket }); CraftingManager.addRecipeAuto(ModItems.ammo_rocket.stackFromEnum(AmmoRocket.PHOSPHORUS), new Object[] { "G", "R", 'G', P_WHITE.ingot(), 'R', ModItems.ammo_rocket }); diff --git a/src/main/java/com/hbm/handler/GunConfiguration.java b/src/main/java/com/hbm/handler/GunConfiguration.java index 2b52f2015..0ea58fb3e 100644 --- a/src/main/java/com/hbm/handler/GunConfiguration.java +++ b/src/main/java/com/hbm/handler/GunConfiguration.java @@ -1,11 +1,14 @@ package com.hbm.handler; import java.util.ArrayList; -import java.util.HashMap; +import java.util.EnumMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import com.hbm.lib.HbmCollection.EnumGunManufacturer; import com.hbm.main.MainRegistry; +import com.hbm.particle.SpentCasingConfig; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.HbmAnimations.AnimType; import com.hbm.render.util.RenderScreenOverlay.Crosshair; @@ -32,7 +35,7 @@ public class GunConfiguration implements Cloneable { public int durability; //animations! - public HashMap animations = new HashMap(); + public final Map animations = new EnumMap<>(AnimType.class); //whether ot not to disable crosshais when sneaking public boolean hasSights; @@ -89,6 +92,9 @@ public class GunConfiguration implements Cloneable { //crosshair public Crosshair crosshair; + + /**Controller for spent casings. If {@code Optional.empty()} it will not eject casings.**/ + public Optional casingConfig = Optional.empty(); public static final int MODE_NORMAL = 0; public static final int MODE_RELEASE = 1; diff --git a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java index 94ac53b32..cc9f467ad 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java @@ -1,7 +1,6 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; -import java.util.HashMap; import com.hbm.entity.projectile.EntityBulletBase; import com.hbm.handler.BulletConfigSyncingUtil; @@ -133,7 +132,7 @@ public class Gun556mmFactory { public static GunConfiguration getMLRConfig() { - GunConfiguration config = new GunConfiguration(); + final GunConfiguration config = new GunConfiguration(); config.rateOfFire = 2; config.roundsPerCycle = 1; @@ -156,7 +155,6 @@ public class Gun556mmFactory { config.config.addAll(HbmCollection.NATO); config.config.addAll(HbmCollection.NATOFlechette); - config.animations = new HashMap<>(); config.animations.put(AnimType.CYCLE, new BusAnimation() .addBus("RECOIL", new BusAnimationSequence() .addKeyframe(new BusAnimationKeyframe(-0.35, 0, 0, 30)) @@ -167,7 +165,7 @@ public class Gun556mmFactory { public static GunConfiguration getG36Config() { - GunConfiguration config = new GunConfiguration(); + final GunConfiguration config = new GunConfiguration(); config.rateOfFire = 3; config.roundsPerCycle = 1; @@ -188,7 +186,6 @@ public class Gun556mmFactory { config.config.addAll(HbmCollection.NATO); - config.animations = new HashMap<>(); config.animations.put(AnimType.CYCLE, new BusAnimation() .addBus("RECOIL", new BusAnimationSequence() .addKeyframe(new BusAnimationKeyframe(-0.35, 0, 0, 30)) diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index ce92f0c7c..1218e4ea7 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -130,7 +130,7 @@ public class ClientProxy extends ServerProxy { //SoundUtil.addSoundCategory("ntmMachines"); } - private void registerClientEventHandler(Object handler) { + private static void registerClientEventHandler(Object handler) { MinecraftForge.EVENT_BUS.register(handler); FMLCommonHandler.instance().bus().register(handler); } @@ -343,7 +343,7 @@ public class ClientProxy extends ServerProxy { MinecraftForgeClient.registerItemRenderer(entry.getKey(), entry.getValue()); //this bit registers an item renderer for every existing tile entity renderer that implements IItemRendererProvider - Iterator iterator = TileEntityRendererDispatcher.instance.mapSpecialRenderers.values().iterator(); + Iterator iterator = TileEntityRendererDispatcher.instance.mapSpecialRenderers.values().iterator(); while(iterator.hasNext()) { Object renderer = iterator.next(); if(renderer instanceof IItemRendererProvider) { @@ -783,10 +783,10 @@ public class ClientProxy extends ServerProxy { MissilePart.registerAllParts(); - Iterator it = MissilePart.parts.entrySet().iterator(); + Iterator it = MissilePart.parts.entrySet().iterator(); while(it.hasNext()) { - Map.Entry pair = (Map.Entry) it.next(); + Map.Entry pair = (Map.Entry) it.next(); MissilePart part = (MissilePart) pair.getValue(); MinecraftForgeClient.registerItemRenderer(part.part, new ItemRenderMissilePart(part)); } @@ -828,6 +828,8 @@ public class ClientProxy extends ServerProxy { ParticleRadiationFog fog = new ParticleRadiationFog(man, world, x, y, z); Minecraft.getMinecraft().effectRenderer.addEffect(fog); break; + default: + break; } } @@ -869,6 +871,7 @@ public class ClientProxy extends ServerProxy { } //mk3, only use this one + @Override public void effectNT(NBTTagCompound data) { World world = Minecraft.getMinecraft().theWorld; @@ -885,861 +888,867 @@ public class ClientProxy extends ServerProxy { double y = data.getDouble("posY"); double z = data.getDouble("posZ"); - if("smoke".equals(type)) { + switch (type) + { + case "smoke": { - String mode = data.getString("mode"); int count = Math.max(1, data.getInteger("count")); - if("cloud".equals(mode)) { - - for(int i = 0; i < count; i++) { - ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); - fx.motionY = rand.nextGaussian() * (1 + (count / 100)); - fx.motionX = rand.nextGaussian() * (1 + (count / 150)); - fx.motionZ = rand.nextGaussian() * (1 + (count / 150)); - if(rand.nextBoolean()) fx.motionY = Math.abs(fx.motionY); - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - } - } - - if("radial".equals(mode)) { - - for(int i = 0; i < count; i++) { - ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); - fx.motionY = rand.nextGaussian() * (1 + (count / 50)); - fx.motionX = rand.nextGaussian() * (1 + (count / 50)); - fx.motionZ = rand.nextGaussian() * (1 + (count / 50)); - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - } - } - - if("radialDigamma".equals(mode)) { - - Vec3 vec = Vec3.createVectorHelper(2, 0, 0); - vec.rotateAroundY(rand.nextFloat() * (float)Math.PI * 2F); - - for(int i = 0; i < count; i++) { - ParticleDigammaSmoke fx = new ParticleDigammaSmoke(man, world, x, y, z); - fx.motionY = 0; - fx.motionX = vec.xCoord; - fx.motionZ = vec.zCoord; - Minecraft.getMinecraft().effectRenderer.addEffect(fx); + switch (data.getString("mode")) + { + case "cloud": { - vec.rotateAroundY((float)Math.PI * 2F / (float)count); - } - } - - if("shock".equals(mode)) { - - double strength = data.getDouble("strength"); - - Vec3 vec = Vec3.createVectorHelper(strength, 0, 0); - vec.rotateAroundY(rand.nextInt(360)); - - for(int i = 0; i < count; i++) { - ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); - fx.motionY = 0; - fx.motionX = vec.xCoord; - fx.motionZ = vec.zCoord; - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - - vec.rotateAroundY((float)Math.PI * 2F / (float)count); - } - } - - if("shockRand".equals(mode)) { - - double strength = data.getDouble("strength"); - - Vec3 vec = Vec3.createVectorHelper(strength, 0, 0); - vec.rotateAroundY(rand.nextInt(360)); - double r; - - for(int i = 0; i < count; i++) { - r = rand.nextDouble(); - ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); - fx.motionY = 0; - fx.motionX = vec.xCoord * r; - fx.motionZ = vec.zCoord * r; - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - - vec.rotateAroundY(360 / count); - } - } - - if("wave".equals(mode)) { - - double strength = data.getDouble("range"); - - Vec3 vec = Vec3.createVectorHelper(strength, 0, 0); - - for(int i = 0; i < count; i++) { - - vec.rotateAroundY((float) Math.toRadians(rand.nextFloat() * 360F)); - - ParticleExSmoke fx = new ParticleExSmoke(man, world, x + vec.xCoord, y, z + vec.zCoord); - fx.maxAge = 50; - fx.motionY = 0; - fx.motionX = 0; - fx.motionZ = 0; - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - - vec.rotateAroundY(360 / count); - } - } - } - - if("exhaust".equals(type)) { - - String mode = data.getString("mode"); - - if("soyuz".equals(mode)) { - - if(Vec3.createVectorHelper(player.posX - x, player.posY - y, player.posZ - z).lengthVector() > 350) - return; + for(int i = 0; i < count; i++) { + ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); + fx.motionY = rand.nextGaussian() * (1 + (count / 100)); + fx.motionX = rand.nextGaussian() * (1 + (count / 150)); + fx.motionZ = rand.nextGaussian() * (1 + (count / 150)); + if(rand.nextBoolean()) fx.motionY = Math.abs(fx.motionY); + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + break; + } - int count = Math.max(1, data.getInteger("count")); - double width = data.getDouble("width"); - - for(int i = 0; i < count; i++) { - - ParticleRocketFlame fx = new ParticleRocketFlame(man, world, x + rand.nextGaussian() * width, y, z + rand.nextGaussian() * width); - fx.motionY = -0.75 + rand.nextDouble() * 0.5; - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - } - } - - if("meteor".equals(mode)) { - - if(Vec3.createVectorHelper(player.posX - x, player.posY - y, player.posZ - z).lengthVector() > 350) - return; + case "radial": { - int count = Math.max(1, data.getInteger("count")); - double width = data.getDouble("width"); + for(int i = 0; i < count; i++) { + ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); + fx.motionY = rand.nextGaussian() * (1 + (count / 50)); + fx.motionX = rand.nextGaussian() * (1 + (count / 50)); + fx.motionZ = rand.nextGaussian() * (1 + (count / 50)); + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + break; + } + + case "radialDigamma": { + + Vec3 vec = Vec3.createVectorHelper(2, 0, 0); + vec.rotateAroundY(rand.nextFloat() * (float)Math.PI * 2F); + + for(int i = 0; i < count; i++) { + ParticleDigammaSmoke fx = new ParticleDigammaSmoke(man, world, x, y, z); + fx.motionY = 0; + fx.motionX = vec.xCoord; + fx.motionZ = vec.zCoord; + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + + vec.rotateAroundY((float)Math.PI * 2F / count); + } + break; + } - for(int i = 0; i < count; i++) { + case "shock": { - ParticleRocketFlame fx = new ParticleRocketFlame(man, world, x + rand.nextGaussian() * width, y + rand.nextGaussian() * width, z + rand.nextGaussian() * width); - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - } - } - } + double strength = data.getDouble("strength"); - if("fireworks".equals(type)) { - int color = data.getInteger("color"); - char c = (char)data.getInteger("char"); - - ParticleLetter fx = new ParticleLetter(world, x, y, z, color, c); - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - - for(int i = 0; i < 50; i++) { - EntityFireworkSparkFX blast = new EntityFireworkSparkFX(world, x, y, z, - 0.4 * world.rand.nextGaussian(), - 0.4 * world.rand.nextGaussian(), - 0.4 * world.rand.nextGaussian(), Minecraft.getMinecraft().effectRenderer); - blast.setColour(color); - Minecraft.getMinecraft().effectRenderer.addEffect(blast); - } - } + Vec3 vec = Vec3.createVectorHelper(strength, 0, 0); + vec.rotateAroundY(rand.nextInt(360)); + + for(int i = 0; i < count; i++) { + ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); + fx.motionY = 0; + fx.motionX = vec.xCoord; + fx.motionZ = vec.zCoord; + Minecraft.getMinecraft().effectRenderer.addEffect(fx); - if("vanillaburst".equals(type)) { - - double motion = data.getDouble("motion"); - - for(int i = 0; i < data.getInteger("count"); i++) { - - double mX = rand.nextGaussian() * motion; - double mY = rand.nextGaussian() * motion; - double mZ = rand.nextGaussian() * motion; + vec.rotateAroundY((float)Math.PI * 2F / count); + } + break; + } - EntityFX fx = null; - - if("flame".equals(data.getString("mode"))) { - fx = new EntityFlameFX(world, x, y, z, mX, mY, mZ); - } - - if("cloud".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityCloudFX(world, x, y, z, mX, mY, mZ); - } - - if("reddust".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.0F, 0.0F, 0.0F); - fx.motionX = mX; - fx.motionY = mY; - fx.motionZ = mZ; - } - - if("bluedust".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.01F, 1F); - } - - if("greendust".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.5F, 0.1F); - } - - if("blockdust".equals(data.getString("mode"))) { + case "shockRand": { - Block b = Block.getBlockById(data.getInteger("block")); - fx = new net.minecraft.client.particle.EntityBlockDustFX(world, x, y, z, mX, mY + 0.2, mZ, b, 0); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 50 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); + double strength = data.getDouble("strength"); + + Vec3 vec = Vec3.createVectorHelper(strength, 0, 0); + vec.rotateAroundY(rand.nextInt(360)); + double r; + + for(int i = 0; i < count; i++) { + r = rand.nextDouble(); + ParticleExSmoke fx = new ParticleExSmoke(man, world, x, y, z); + fx.motionY = 0; + fx.motionX = vec.xCoord * r; + fx.motionZ = vec.zCoord * r; + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + + vec.rotateAroundY(360 / count); + } + break; + } + + case "wave": { + + double strength = data.getDouble("range"); + + Vec3 vec = Vec3.createVectorHelper(strength, 0, 0); + + for(int i = 0; i < count; i++) { + + vec.rotateAroundY((float) Math.toRadians(rand.nextFloat() * 360F)); + + ParticleExSmoke fx = new ParticleExSmoke(man, world, x + vec.xCoord, y, z + vec.zCoord); + fx.maxAge = 50; + fx.motionY = 0; + fx.motionX = 0; + fx.motionZ = 0; + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + + vec.rotateAroundY(360 / count); + } + break; + } + default: break; + } + break; + } + + case "exhaust": { + + switch (data.getString("mode")) + { + case "soyuz": { + + if(Vec3.createVectorHelper(player.posX - x, player.posY - y, player.posZ - z).lengthVector() > 350) + return; + + int count = Math.max(1, data.getInteger("count")); + double width = data.getDouble("width"); + + for(int i = 0; i < count; i++) { + + ParticleRocketFlame fx = new ParticleRocketFlame(man, world, x + rand.nextGaussian() * width, y, z + rand.nextGaussian() * width); + fx.motionY = -0.75 + rand.nextDouble() * 0.5; + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + break; } - if(fx != null) - Minecraft.getMinecraft().effectRenderer.addEffect(fx); + case "meteor": { + + if(Vec3.createVectorHelper(player.posX - x, player.posY - y, player.posZ - z).lengthVector() > 350) + return; + + int count = Math.max(1, data.getInteger("count")); + double width = data.getDouble("width"); + + for(int i = 0; i < count; i++) { + + ParticleRocketFlame fx = new ParticleRocketFlame(man, world, x + rand.nextGaussian() * width, y + rand.nextGaussian() * width, z + rand.nextGaussian() * width); + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + break; + } + default: break; } } - if("vanillaExt".equals(type)) { - - double mX = data.getDouble("mX"); - double mY = data.getDouble("mY"); - double mZ = data.getDouble("mZ"); - - EntityFX fx = null; - - if("flame".equals(data.getString("mode"))) { - fx = new EntityFlameFX(world, x, y, z, mX, mY, mZ); - } - - if("smoke".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntitySmokeFX(world, x, y, z, mX, mY, mZ); - } - - if("volcano".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntitySmokeFX(world, x, y, z, mX, mY, mZ); - float scale = 100; - ReflectionHelper.setPrivateValue(net.minecraft.client.particle.EntitySmokeFX.class, (net.minecraft.client.particle.EntitySmokeFX)fx, scale, "smokeParticleScale", "field_70587_a"); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 200 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); - fx.noClip = true; - fx.motionY = 2.5 + rand.nextDouble(); - fx.motionX = rand.nextGaussian() * 0.2; - fx.motionZ = rand.nextGaussian() * 0.2; - } - - if("cloud".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityCloudFX(world, x, y, z, mX, mY, mZ); - - if(data.hasKey("r")) { - float rng = rand.nextFloat() * 0.1F; - fx.setRBGColorF(data.getFloat("r") + rng, data.getFloat("g") + rng, data.getFloat("b") + rng); - ReflectionHelper.setPrivateValue(net.minecraft.client.particle.EntityCloudFX.class, (EntityCloudFX)fx, 7.5F, "field_70569_a"); - fx.motionX = 0; - fx.motionY = 0; - fx.motionZ = 0; - } - } - - if("reddust".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, (float)mX, (float)mY, (float)mZ); - } - - if("bluedust".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.01F, 1F); - } - - if("greendust".equals(data.getString("mode"))) { - fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.5F, 0.1F); - } - - if("largeexplode".equals(data.getString("mode"))) { - - - fx = new net.minecraft.client.particle.EntityLargeExplodeFX(man, world, x, y, z, data.getFloat("size"), 0.0F, 0.0F); - float r = 1.0F - rand.nextFloat() * 0.2F; - fx.setRBGColorF(1F * r, 0.9F * r, 0.5F * r); - - for(int i = 0; i < data.getByte("count"); i++) { - net.minecraft.client.particle.EntityExplodeFX sec = new net.minecraft.client.particle.EntityExplodeFX(world, x, y, z, 0.0F, 0.0F, 0.0F); - float r2 = 1.0F - rand.nextFloat() * 0.5F; - sec.setRBGColorF(0.5F * r2, 0.5F * r2, 0.5F * r2); - sec.multipleParticleScaleBy(i + 1); - Minecraft.getMinecraft().effectRenderer.addEffect(sec); - } - } - - if("townaura".equals(data.getString("mode"))) { - fx = new EntityAuraFX(world, x, y, z, 0, 0, 0); - float color = 0.5F + rand.nextFloat() * 0.5F; - fx.setRBGColorF(0.8F * color, 0.9F * color, 1.0F * color); - fx.setVelocity(mX, mY, mZ); - } - - if("blockdust".equals(data.getString("mode"))) { - - Block b = Block.getBlockById(data.getInteger("block")); - fx = new net.minecraft.client.particle.EntityBlockDustFX(world, x, y, z, mX, mY + 0.2, mZ, b, 0); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 10 + rand.nextInt(20), "particleMaxAge", "field_70547_e"); - } - - if("colordust".equals(data.getString("mode"))) { - - Block b = Blocks.wool; - fx = new net.minecraft.client.particle.EntityBlockDustFX(world, x, y, z, mX, mY + 0.2, mZ, b, 0); - fx.setRBGColorF(data.getFloat("r"), data.getFloat("g"), data.getFloat("b")); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 10 + rand.nextInt(20), "particleMaxAge", "field_70547_e"); - } - - if(fx != null) { - - if(data.getBoolean("noclip")) { - fx.noClip = true; - } - - if(data.getInteger("overrideAge") > 0) { - ReflectionHelper.setPrivateValue(EntityFX.class, fx, data.getInteger("overrideAge"), "particleMaxAge", "field_70547_e"); - } + case "fireworks": { + int color = data.getInteger("color"); + char c = (char)data.getInteger("char"); + ParticleLetter fx = new ParticleLetter(world, x, y, z, color, c); Minecraft.getMinecraft().effectRenderer.addEffect(fx); - } - } - - if("vanilla".equals(type)) { - - double mX = data.getDouble("mX"); - double mY = data.getDouble("mY"); - double mZ = data.getDouble("mZ"); - world.spawnParticle(data.getString("mode"), x, y, z, mX, mY, mZ); - } - - if("jetpack".equals(type)) { - - if(particleSetting == 2) - return; - - Entity ent = world.getEntityByID(data.getInteger("player")); - - if(ent instanceof EntityPlayer) { - EntityPlayer p = (EntityPlayer)ent; - - Vec3 vec = Vec3.createVectorHelper(0, 0, -0.25); - Vec3 offset = Vec3.createVectorHelper(0.125, 0, 0); - float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); - - vec.rotateAroundY(angle); - offset.rotateAroundY(angle); - - double ix = p.posX + vec.xCoord; - double iy = p.posY + p.eyeHeight - 1; - double iz = p.posZ + vec.zCoord; - double ox = offset.xCoord; - double oz = offset.zCoord; - - double moX = 0; - double moY = 0; - double moZ = 0; - - int mode = data.getInteger("mode"); - - if(mode == 0) { - moY -= 0.2; - } - - if(mode == 1) { - Vec3 look = p.getLookVec(); - - moX -= look.xCoord * 0.1D; - moY -= look.yCoord * 0.1D; - moZ -= look.zCoord * 0.1D; - } - - if(particleSetting == 0) { - Vec3 pos = Vec3.createVectorHelper(ix, iy, iz); - Vec3 thrust = Vec3.createVectorHelper(moX, moY, moZ); - thrust = thrust.normalize(); - Vec3 target = pos.addVector(thrust.xCoord * 10, thrust.yCoord * 10, thrust.zCoord * 10); - MovingObjectPosition mop = player.worldObj.func_147447_a(pos, target, false, false, true); - - if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK && mop.sideHit == 1) { - - Block b = world.getBlock(mop.blockX, mop.blockY, mop.blockZ); - int meta = world.getBlockMetadata(mop.blockX, mop.blockY, mop.blockZ); - - Vec3 delta = Vec3.createVectorHelper(ix - mop.hitVec.xCoord, iy - mop.hitVec.yCoord, iz - mop.hitVec.zCoord); - Vec3 vel = Vec3.createVectorHelper(0.75 - delta.lengthVector() * 0.075, 0, 0); - - for(int i = 0; i < (10 - delta.lengthVector()); i++) { - vel.rotateAroundY(world.rand.nextFloat() * (float)Math.PI * 2F); - Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlockDustFX(world, mop.hitVec.xCoord, mop.hitVec.yCoord + 0.1, mop.hitVec.zCoord, vel.xCoord, 0.1, vel.zCoord, b, meta)); - } - } - } - - double mX2 = BobMathUtil.safeClamp(p.motionX + moX * 2, -5, 5); - double mY2 = BobMathUtil.safeClamp(p.motionY + moY * 2, -5, 5); - double mZ2 = BobMathUtil.safeClamp(p.motionZ + moZ * 2, -5, 5); - double mX3 = BobMathUtil.safeClamp(p.motionX + moX * 2, -10, 10); - double mY3 = BobMathUtil.safeClamp(p.motionY + moY * 2, -10, 10); - double mZ3 = BobMathUtil.safeClamp(p.motionZ + moZ * 2, -10, 10); - - Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix + ox, iy, iz + oz, mX2, mY2, mZ2)); - Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix - ox, iy, iz - oz, mX2, mY2, mZ2)); - - if(particleSetting == 0) { - Minecraft.getMinecraft().effectRenderer.addEffect(new net.minecraft.client.particle.EntitySmokeFX(world, ix + ox, iy, iz + oz, mX3, mY3, mZ3)); - Minecraft.getMinecraft().effectRenderer.addEffect(new net.minecraft.client.particle.EntitySmokeFX(world, ix - ox, iy, iz - oz, mX3, mY3, mZ3)); + for(int i = 0; i < 50; i++) { + EntityFireworkSparkFX blast = new EntityFireworkSparkFX(world, x, y, z, + 0.4 * world.rand.nextGaussian(), + 0.4 * world.rand.nextGaussian(), + 0.4 * world.rand.nextGaussian(), Minecraft.getMinecraft().effectRenderer); + blast.setColour(color); + Minecraft.getMinecraft().effectRenderer.addEffect(blast); } + break; } - } - if("bnuuy".equals(type)) { + case "vanillaburst": { - if(particleSetting == 2) - return; - - Entity ent = world.getEntityByID(data.getInteger("player")); - - if(ent instanceof EntityPlayer) { - - EntityPlayer p = (EntityPlayer)ent; - - Vec3 vec = Vec3.createVectorHelper(0, 0, -0.6); - Vec3 offset = Vec3.createVectorHelper(0.275, 0, 0); - float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); - - vec.rotateAroundY(angle); - offset.rotateAroundY(angle); - - double ix = p.posX + vec.xCoord; - double iy = p.posY + p.eyeHeight - 1 + 0.4; - double iz = p.posZ + vec.zCoord; - double ox = offset.xCoord; - double oz = offset.zCoord; - - vec = vec.normalize(); - double mult = 0.025D; - double mX = vec.xCoord * mult; - double mZ = vec.zCoord * mult; - - //Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix + ox, iy, iz + oz, 0, 0, 0)); - //Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix - ox, iy, iz - oz, 0, 0, 0)); - - for(int i = 0; i < 2; i++) { - net.minecraft.client.particle.EntitySmokeFX fx = new net.minecraft.client.particle.EntitySmokeFX(world, ix + ox * (i == 0 ? -1 : 1), iy, iz + oz * (i == 0 ? -1 : 1), mX, 0, mZ); - float scale = 0.5F; - ReflectionHelper.setPrivateValue(net.minecraft.client.particle.EntitySmokeFX.class, (net.minecraft.client.particle.EntitySmokeFX)fx, scale, "smokeParticleScale", "field_70587_a"); - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - } - } - } - - if("jetpack_bj".equals(type)) { - - if(particleSetting == 2) - return; - - Entity ent = world.getEntityByID(data.getInteger("player")); - - if(ent instanceof EntityPlayer) { - - EntityPlayer p = (EntityPlayer)ent; - - Vec3 vec = Vec3.createVectorHelper(0, 0, -0.3125); - Vec3 offset = Vec3.createVectorHelper(0.125, 0, 0); - float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); - - vec.rotateAroundY(angle); - offset.rotateAroundY(angle); - - double ix = p.posX + vec.xCoord; - double iy = p.posY + p.eyeHeight - 0.9375; - double iz = p.posZ + vec.zCoord; - double ox = offset.xCoord; - double oz = offset.zCoord; - - if(particleSetting == 0) { - Vec3 pos = Vec3.createVectorHelper(ix, iy, iz); - Vec3 thrust = Vec3.createVectorHelper(0, -1, 0); - Vec3 target = pos.addVector(thrust.xCoord * 10, thrust.yCoord * 10, thrust.zCoord * 10); - MovingObjectPosition mop = player.worldObj.func_147447_a(pos, target, false, false, true); - - if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK && mop.sideHit == 1) { - - Block b = world.getBlock(mop.blockX, mop.blockY, mop.blockZ); - int meta = world.getBlockMetadata(mop.blockX, mop.blockY, mop.blockZ); - - Vec3 delta = Vec3.createVectorHelper(ix - mop.hitVec.xCoord, iy - mop.hitVec.yCoord, iz - mop.hitVec.zCoord); - Vec3 vel = Vec3.createVectorHelper(0.75 - delta.lengthVector() * 0.075, 0, 0); - - for(int i = 0; i < (10 - delta.lengthVector()); i++) { - vel.rotateAroundY(world.rand.nextFloat() * (float)Math.PI * 2F); - Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlockDustFX(world, mop.hitVec.xCoord, mop.hitVec.yCoord + 0.1, mop.hitVec.zCoord, vel.xCoord, 0.1, vel.zCoord, b, meta)); - } - } - } - - EntityReddustFX dust1 = new EntityReddustFX(world, ix + ox, iy, iz + oz, 0.8F, 0.5F, 1.0F); - EntityReddustFX dust2 = new EntityReddustFX(world, ix - ox, iy, iz - oz, 0.8F, 0.5F, 1.0F); - dust1.setVelocity(p.motionX, p.motionY, p.motionZ); - dust2.setVelocity(p.motionX, p.motionY, p.motionZ); - Minecraft.getMinecraft().effectRenderer.addEffect(dust1); - Minecraft.getMinecraft().effectRenderer.addEffect(dust2); - } - } - - if("jetpack_dns".equals(type)) { - - if(particleSetting == 2) - return; - - Entity ent = world.getEntityByID(data.getInteger("player")); - - if(ent instanceof EntityPlayer) { - - EntityPlayer p = (EntityPlayer)ent; - - Vec3 offset = Vec3.createVectorHelper(0.125, 0, 0); - float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); - - offset.rotateAroundY(angle); - - double ix = p.posX; - double iy = p.posY - p.getYOffset() - 0.5D; - double iz = p.posZ; - double ox = offset.xCoord; - double oz = offset.zCoord; - - if(particleSetting == 0) { - Vec3 pos = Vec3.createVectorHelper(ix, iy, iz); - Vec3 thrust = Vec3.createVectorHelper(0, -1, 0); - Vec3 target = pos.addVector(thrust.xCoord * 10, thrust.yCoord * 10, thrust.zCoord * 10); - MovingObjectPosition mop = player.worldObj.func_147447_a(pos, target, false, false, true); - - if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK && mop.sideHit == 1) { - - Block b = world.getBlock(mop.blockX, mop.blockY, mop.blockZ); - int meta = world.getBlockMetadata(mop.blockX, mop.blockY, mop.blockZ); - - Vec3 delta = Vec3.createVectorHelper(ix - mop.hitVec.xCoord, iy - mop.hitVec.yCoord, iz - mop.hitVec.zCoord); - Vec3 vel = Vec3.createVectorHelper(0.75 - delta.lengthVector() * 0.075, 0, 0); - - for(int i = 0; i < (10 - delta.lengthVector()); i++) { - vel.rotateAroundY(world.rand.nextFloat() * (float)Math.PI * 2F); - Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlockDustFX(world, mop.hitVec.xCoord, mop.hitVec.yCoord + 0.1, mop.hitVec.zCoord, vel.xCoord, 0.1, vel.zCoord, b, meta)); - } - } - } - - EntityReddustFX dust1 = new EntityReddustFX(world, ix + ox, iy, iz + oz, 0.01F, 1.0F, 1.0F); - EntityReddustFX dust2 = new EntityReddustFX(world, ix - ox, iy, iz - oz, 0.01F, 1.0F, 1.0F); - dust1.setVelocity(p.motionX, p.motionY, p.motionZ); - dust2.setVelocity(p.motionX, p.motionY, p.motionZ); - Minecraft.getMinecraft().effectRenderer.addEffect(dust1); - Minecraft.getMinecraft().effectRenderer.addEffect(dust2); - } - } - - if("muke".equals(type)) { - - ParticleMukeWave wave = new ParticleMukeWave(man, world, x, y, z); - ParticleMukeFlash flash = new ParticleMukeFlash(man, world, x, y, z, data.getBoolean("balefire")); - - Minecraft.getMinecraft().effectRenderer.addEffect(wave); - Minecraft.getMinecraft().effectRenderer.addEffect(flash); - - //single swing: HT 15, MHT 15 - //double swing: HT 60, MHT 50 - //vic's immersive swing: HT 100, MHT 50 - - if(player.getDisplayName().equals("Vic4Games")) { - player.hurtTime = 100; - player.maxHurtTime = 50; - } else { - player.hurtTime = 15; - player.maxHurtTime = 15; - } - player.attackedAtYaw = 0F; - } - - if("tinytot".equals(type)) { - - ParticleMukeWave wave = new ParticleMukeWave(man, world, x, y, z); - Minecraft.getMinecraft().effectRenderer.addEffect(wave); - - for(double d = 0.0D; d <= 1.6D; d += 0.1) { - ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y, z, rand.nextGaussian() * 0.05, d + rand.nextGaussian() * 0.02, rand.nextGaussian() * 0.05); - Minecraft.getMinecraft().effectRenderer.addEffect(cloud); - } - for(int i = 0; i < 50; i++) { - ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y + 0.5, z, rand.nextGaussian() * 0.5, rand.nextInt(5) == 0 ? 0.02 : 0, rand.nextGaussian() * 0.5); - Minecraft.getMinecraft().effectRenderer.addEffect(cloud); - } - for(int i = 0; i < 15; i++) { - double ix = rand.nextGaussian() * 0.2; - double iz = rand.nextGaussian() * 0.2; - - if(ix * ix + iz * iz > 0.75) { - ix *= 0.5; - iz *= 0.5; - } - - double iy = 1.6 + (rand.nextDouble() * 2 - 1) * (0.75 - (ix * ix + iz * iz)) * 0.5; - - ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y, z, ix, iy + rand.nextGaussian() * 0.02, iz); - Minecraft.getMinecraft().effectRenderer.addEffect(cloud); - } - if(player.getDisplayName().equals("Vic4Games")) { - player.hurtTime = 100; - player.maxHurtTime = 50; - } else { - player.hurtTime = 15; - player.maxHurtTime = 15; - } - player.attackedAtYaw = 0F; - } - - if("ufo".equals(type)) { - double motion = data.getDouble("motion"); - ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y, z, rand.nextGaussian() * motion, 0, rand.nextGaussian() * motion); - Minecraft.getMinecraft().effectRenderer.addEffect(cloud); - } - - if("haze".equals(type)) { - - ParticleHaze fog = new ParticleHaze(man, world, x, y, z); - Minecraft.getMinecraft().effectRenderer.addEffect(fog); - } - - if("plasmablast".equals(type)) { - - ParticlePlasmaBlast cloud = new ParticlePlasmaBlast(man, world, x, y, z, data.getFloat("r"), data.getFloat("g"), data.getFloat("b"), data.getFloat("pitch"), data.getFloat("yaw")); - cloud.setScale(data.getFloat("scale")); - Minecraft.getMinecraft().effectRenderer.addEffect(cloud); - } - - if("justTilt".equals(type)) { - - player.hurtTime = player.maxHurtTime = data.getInteger("time"); - player.attackedAtYaw = 0F; - } - - if("properJolt".equals(type)) { - - player.hurtTime = data.getInteger("time"); - player.maxHurtTime = data.getInteger("maxTime"); - player.attackedAtYaw = 0F; - } - - if("sweat".equals(type)) { - - Entity e = world.getEntityByID(data.getInteger("entity")); - Block b = Block.getBlockById(data.getInteger("block")); - int meta = data.getInteger("meta"); - - if(e instanceof EntityLivingBase) { + double motion = data.getDouble("motion"); for(int i = 0; i < data.getInteger("count"); i++) { - double ix = e.boundingBox.minX - 0.2 + (e.boundingBox.maxX - e.boundingBox.minX + 0.4) * rand.nextDouble(); - double iy = e.boundingBox.minY + (e.boundingBox.maxY - e.boundingBox.minY + 0.2) * rand.nextDouble(); - double iz = e.boundingBox.minZ - 0.2 + (e.boundingBox.maxZ - e.boundingBox.minZ + 0.4) * rand.nextDouble(); + double mX = rand.nextGaussian() * motion; + double mY = rand.nextGaussian() * motion; + double mZ = rand.nextGaussian() * motion; + EntityFX fx = null; + + switch (data.getString("mode")) + { + case "flame": fx = new EntityFlameFX(world, x, y, z, mX, mY, mZ); break; + case "cloud": fx = new net.minecraft.client.particle.EntityCloudFX(world, x, y, z, mX, mY, mZ); break; + + case "reddust": + fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.0F, 0.0F, 0.0F); + fx.motionX = mX; + fx.motionY = mY; + fx.motionZ = mZ; + break; + case "bluedust": fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.01F, 1F); break; + case "greendust": fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.5F, 0.1F); break; + + case "blockdust": + Block b = Block.getBlockById(data.getInteger("block")); + fx = new net.minecraft.client.particle.EntityBlockDustFX(world, x, y, z, mX, mY + 0.2, mZ, b, 0); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 50 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); + break; + default: break; + } - EntityFX fx = new net.minecraft.client.particle.EntityBlockDustFX(world, ix, iy, iz, 0, 0, 0, b, meta); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 150 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); + if(fx != null) + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + + } + break; + } + + case "vanillaExt": { + + double mX = data.getDouble("mX"); + double mY = data.getDouble("mY"); + double mZ = data.getDouble("mZ"); + + EntityFX fx = null; + + switch (data.getString("mode")) + { + case "flame": fx = new EntityFlameFX(world, x, y, z, mX, mY, mZ); break; + case "smoke": fx = new net.minecraft.client.particle.EntitySmokeFX(world, x, y, z, mX, mY, mZ); break; + case "volcano": + fx = new net.minecraft.client.particle.EntitySmokeFX(world, x, y, z, mX, mY, mZ); + float scale = 100; + ReflectionHelper.setPrivateValue(net.minecraft.client.particle.EntitySmokeFX.class, (net.minecraft.client.particle.EntitySmokeFX)fx, scale, "smokeParticleScale", "field_70587_a"); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 200 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); + fx.noClip = true; + fx.motionY = 2.5 + rand.nextDouble(); + fx.motionX = rand.nextGaussian() * 0.2; + fx.motionZ = rand.nextGaussian() * 0.2; + break; + case "cloud": + fx = new net.minecraft.client.particle.EntityCloudFX(world, x, y, z, mX, mY, mZ); + + if(data.hasKey("r")) { + float rng = rand.nextFloat() * 0.1F; + fx.setRBGColorF(data.getFloat("r") + rng, data.getFloat("g") + rng, data.getFloat("b") + rng); + ReflectionHelper.setPrivateValue(net.minecraft.client.particle.EntityCloudFX.class, (EntityCloudFX)fx, 7.5F, "field_70569_a"); + fx.motionX = 0; + fx.motionY = 0; + fx.motionZ = 0; + } + break; + case "reddust": fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, (float)mX, (float)mY, (float)mZ); break; + case "bluedust": fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.01F, 1F); break; + case "greendust": fx = new net.minecraft.client.particle.EntityReddustFX(world, x, y, z, 0.01F, 0.5F, 0.1F); break; + case "largeexplode": + fx = new net.minecraft.client.particle.EntityLargeExplodeFX(man, world, x, y, z, data.getFloat("size"), 0.0F, 0.0F); + float r = 1.0F - rand.nextFloat() * 0.2F; + fx.setRBGColorF(1F * r, 0.9F * r, 0.5F * r); + + for(int i = 0; i < data.getByte("count"); i++) { + net.minecraft.client.particle.EntityExplodeFX sec = new net.minecraft.client.particle.EntityExplodeFX(world, x, y, z, 0.0F, 0.0F, 0.0F); + float r2 = 1.0F - rand.nextFloat() * 0.5F; + sec.setRBGColorF(0.5F * r2, 0.5F * r2, 0.5F * r2); + sec.multipleParticleScaleBy(i + 1); + Minecraft.getMinecraft().effectRenderer.addEffect(sec); + } + break; + case "townaura": + fx = new EntityAuraFX(world, x, y, z, 0, 0, 0); + float color = 0.5F + rand.nextFloat() * 0.5F; + fx.setRBGColorF(0.8F * color, 0.9F * color, 1.0F * color); + fx.setVelocity(mX, mY, mZ); + break; + case "blockdust": + { + Block b = Block.getBlockById(data.getInteger("block")); + fx = new net.minecraft.client.particle.EntityBlockDustFX(world, x, y, z, mX, mY + 0.2, mZ, b, 0); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 10 + rand.nextInt(20), "particleMaxAge", "field_70547_e"); + break; + } + case "colordust": + { + Block b = Blocks.wool; + fx = new net.minecraft.client.particle.EntityBlockDustFX(world, x, y, z, mX, mY + 0.2, mZ, b, 0); + fx.setRBGColorF(data.getFloat("r"), data.getFloat("g"), data.getFloat("b")); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 10 + rand.nextInt(20), "particleMaxAge", "field_70547_e"); + break; + } + } + + if(fx != null) { + + fx.noClip = data.getBoolean("noclip"); + + if(data.getInteger("overrideAge") > 0) { + ReflectionHelper.setPrivateValue(EntityFX.class, fx, data.getInteger("overrideAge"), "particleMaxAge", "field_70547_e"); + } Minecraft.getMinecraft().effectRenderer.addEffect(fx); } + break; } - } - if("vomit".equals(type)) { - - Entity e = world.getEntityByID(data.getInteger("entity")); - int count = data.getInteger("count") / (particleSetting + 1); - - if(e instanceof EntityLivingBase) { + case "vanilla": { - double ix = e.posX; - double iy = e.posY - e.getYOffset() + e.getEyeHeight() + (e instanceof EntityPlayer ? 1 : 0); - double iz = e.posZ; + double mX = data.getDouble("mX"); + double mY = data.getDouble("mY"); + double mZ = data.getDouble("mZ"); + world.spawnParticle(data.getString("mode"), x, y, z, mX, mY, mZ); + break; + } + + case "jetpack": { + + if(particleSetting == 2) + return; - Vec3 vec = e.getLookVec(); + Entity ent = world.getEntityByID(data.getInteger("player")); - for(int i = 0; i < count; i++) { + if(ent instanceof EntityPlayer) { - if("normal".equals(data.getString("mode"))) { - EntityFX fx = new net.minecraft.client.particle.EntityBlockDustFX(world, ix, iy, iz, (vec.xCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.yCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.zCoord + rand.nextGaussian() * 0.2) * 0.2, Blocks.stained_hardened_clay, (rand.nextBoolean() ? 5 : 13)); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 150 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); - Minecraft.getMinecraft().effectRenderer.addEffect(fx); + EntityPlayer p = (EntityPlayer)ent; + + Vec3 vec = Vec3.createVectorHelper(0, 0, -0.25); + Vec3 offset = Vec3.createVectorHelper(0.125, 0, 0); + float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); + + vec.rotateAroundY(angle); + offset.rotateAroundY(angle); + + double ix = p.posX + vec.xCoord; + double iy = p.posY + p.eyeHeight - 1; + double iz = p.posZ + vec.zCoord; + double ox = offset.xCoord; + double oz = offset.zCoord; + + double moX = 0; + double moY = 0; + double moZ = 0; + + int mode = data.getInteger("mode"); + + if(mode == 0) { + moY -= 0.2; } - if("blood".equals(data.getString("mode"))) { - EntityFX fx = new net.minecraft.client.particle.EntityBlockDustFX(world, ix, iy, iz, (vec.xCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.yCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.zCoord + rand.nextGaussian() * 0.2) * 0.2, Blocks.redstone_block, 0); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 150 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); - Minecraft.getMinecraft().effectRenderer.addEffect(fx); + if(mode == 1) { + Vec3 look = p.getLookVec(); + + moX -= look.xCoord * 0.1D; + moY -= look.yCoord * 0.1D; + moZ -= look.zCoord * 0.1D; } + + if(particleSetting == 0) { + Vec3 pos = Vec3.createVectorHelper(ix, iy, iz); + Vec3 thrust = Vec3.createVectorHelper(moX, moY, moZ); + thrust = thrust.normalize(); + Vec3 target = pos.addVector(thrust.xCoord * 10, thrust.yCoord * 10, thrust.zCoord * 10); + MovingObjectPosition mop = player.worldObj.func_147447_a(pos, target, false, false, true); + + if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK && mop.sideHit == 1) { + + Block b = world.getBlock(mop.blockX, mop.blockY, mop.blockZ); + int meta = world.getBlockMetadata(mop.blockX, mop.blockY, mop.blockZ); + + Vec3 delta = Vec3.createVectorHelper(ix - mop.hitVec.xCoord, iy - mop.hitVec.yCoord, iz - mop.hitVec.zCoord); + Vec3 vel = Vec3.createVectorHelper(0.75 - delta.lengthVector() * 0.075, 0, 0); + + for(int i = 0; i < (10 - delta.lengthVector()); i++) { + vel.rotateAroundY(world.rand.nextFloat() * (float)Math.PI * 2F); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlockDustFX(world, mop.hitVec.xCoord, mop.hitVec.yCoord + 0.1, mop.hitVec.zCoord, vel.xCoord, 0.1, vel.zCoord, b, meta)); + } + } + } + + double mX2 = BobMathUtil.safeClamp(p.motionX + moX * 2, -5, 5); + double mY2 = BobMathUtil.safeClamp(p.motionY + moY * 2, -5, 5); + double mZ2 = BobMathUtil.safeClamp(p.motionZ + moZ * 2, -5, 5); + double mX3 = BobMathUtil.safeClamp(p.motionX + moX * 2, -10, 10); + double mY3 = BobMathUtil.safeClamp(p.motionY + moY * 2, -10, 10); + double mZ3 = BobMathUtil.safeClamp(p.motionZ + moZ * 2, -10, 10); + + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix + ox, iy, iz + oz, mX2, mY2, mZ2)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix - ox, iy, iz - oz, mX2, mY2, mZ2)); - if("smoke".equals(data.getString("mode"))) { - EntityFX fx = new net.minecraft.client.particle.EntitySmokeFX(world, ix, iy, iz, (vec.xCoord + rand.nextGaussian() * 0.1) * 0.05, (vec.yCoord + rand.nextGaussian() * 0.1) * 0.05, (vec.zCoord + rand.nextGaussian() * 0.1) * 0.05, 0.2F); - ReflectionHelper.setPrivateValue(EntityFX.class, fx, 10 + rand.nextInt(10), "particleMaxAge", "field_70547_e"); + if(particleSetting == 0) { + Minecraft.getMinecraft().effectRenderer.addEffect(new net.minecraft.client.particle.EntitySmokeFX(world, ix + ox, iy, iz + oz, mX3, mY3, mZ3)); + Minecraft.getMinecraft().effectRenderer.addEffect(new net.minecraft.client.particle.EntitySmokeFX(world, ix - ox, iy, iz - oz, mX3, mY3, mZ3)); + } + } + break; + } + + case "bnuuy": { + + if(particleSetting == 2) + return; + + Entity ent = world.getEntityByID(data.getInteger("player")); + + if(ent instanceof EntityPlayer) { + + EntityPlayer p = (EntityPlayer)ent; + + Vec3 vec = Vec3.createVectorHelper(0, 0, -0.6); + Vec3 offset = Vec3.createVectorHelper(0.275, 0, 0); + float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); + + vec.rotateAroundY(angle); + offset.rotateAroundY(angle); + + double ix = p.posX + vec.xCoord; + double iy = p.posY + p.eyeHeight - 1 + 0.4; + double iz = p.posZ + vec.zCoord; + double ox = offset.xCoord; + double oz = offset.zCoord; + + vec = vec.normalize(); + double mult = 0.025D; + double mX = vec.xCoord * mult; + double mZ = vec.zCoord * mult; + + //Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix + ox, iy, iz + oz, 0, 0, 0)); + //Minecraft.getMinecraft().effectRenderer.addEffect(new EntityFlameFX(world, ix - ox, iy, iz - oz, 0, 0, 0)); + + for(int i = 0; i < 2; i++) { + net.minecraft.client.particle.EntitySmokeFX fx = new net.minecraft.client.particle.EntitySmokeFX(world, ix + ox * (i == 0 ? -1 : 1), iy, iz + oz * (i == 0 ? -1 : 1), mX, 0, mZ); + float scale = 0.5F; + ReflectionHelper.setPrivateValue(net.minecraft.client.particle.EntitySmokeFX.class, fx, scale, "smokeParticleScale", "field_70587_a"); Minecraft.getMinecraft().effectRenderer.addEffect(fx); } } + break; } - } - if("radiation".equals(type)) { + case "jetpack_bj": { - for(int i = 0; i < data.getInteger("count"); i++) { + if(particleSetting == 2) + return; - EntityAuraFX flash = new EntityAuraFX(world, - player.posX + rand.nextGaussian() * 4, - player.posY + rand.nextGaussian() * 2, - player.posZ + rand.nextGaussian() * 4, - 0, 0, 0); + Entity ent = world.getEntityByID(data.getInteger("player")); - flash.setRBGColorF(0F, 0.75F, 1F); - flash.setVelocity(rand.nextGaussian(), rand.nextGaussian(), rand.nextGaussian()); + if(ent instanceof EntityPlayer) { + + EntityPlayer p = (EntityPlayer)ent; + + Vec3 vec = Vec3.createVectorHelper(0, 0, -0.3125); + Vec3 offset = Vec3.createVectorHelper(0.125, 0, 0); + float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); + + vec.rotateAroundY(angle); + offset.rotateAroundY(angle); + + double ix = p.posX + vec.xCoord; + double iy = p.posY + p.eyeHeight - 0.9375; + double iz = p.posZ + vec.zCoord; + double ox = offset.xCoord; + double oz = offset.zCoord; + + if(particleSetting == 0) { + Vec3 pos = Vec3.createVectorHelper(ix, iy, iz); + Vec3 thrust = Vec3.createVectorHelper(0, -1, 0); + Vec3 target = pos.addVector(thrust.xCoord * 10, thrust.yCoord * 10, thrust.zCoord * 10); + MovingObjectPosition mop = player.worldObj.func_147447_a(pos, target, false, false, true); + + if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK && mop.sideHit == 1) { + + Block b = world.getBlock(mop.blockX, mop.blockY, mop.blockZ); + int meta = world.getBlockMetadata(mop.blockX, mop.blockY, mop.blockZ); + + Vec3 delta = Vec3.createVectorHelper(ix - mop.hitVec.xCoord, iy - mop.hitVec.yCoord, iz - mop.hitVec.zCoord); + Vec3 vel = Vec3.createVectorHelper(0.75 - delta.lengthVector() * 0.075, 0, 0); + + for(int i = 0; i < (10 - delta.lengthVector()); i++) { + vel.rotateAroundY(world.rand.nextFloat() * (float)Math.PI * 2F); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlockDustFX(world, mop.hitVec.xCoord, mop.hitVec.yCoord + 0.1, mop.hitVec.zCoord, vel.xCoord, 0.1, vel.zCoord, b, meta)); + } + } + } + + EntityReddustFX dust1 = new EntityReddustFX(world, ix + ox, iy, iz + oz, 0.8F, 0.5F, 1.0F); + EntityReddustFX dust2 = new EntityReddustFX(world, ix - ox, iy, iz - oz, 0.8F, 0.5F, 1.0F); + dust1.setVelocity(p.motionX, p.motionY, p.motionZ); + dust2.setVelocity(p.motionX, p.motionY, p.motionZ); + Minecraft.getMinecraft().effectRenderer.addEffect(dust1); + Minecraft.getMinecraft().effectRenderer.addEffect(dust2); + } + break; + } + + case "jetpack_dns": { + + if(particleSetting == 2) + return; + + Entity ent = world.getEntityByID(data.getInteger("player")); + + if(ent instanceof EntityPlayer) { + + EntityPlayer p = (EntityPlayer)ent; + + Vec3 offset = Vec3.createVectorHelper(0.125, 0, 0); + float angle = (float) -Math.toRadians(p.rotationYawHead - (p.rotationYawHead - p.renderYawOffset)); + + offset.rotateAroundY(angle); + + double ix = p.posX; + double iy = p.posY - p.getYOffset() - 0.5D; + double iz = p.posZ; + double ox = offset.xCoord; + double oz = offset.zCoord; + + if(particleSetting == 0) { + Vec3 pos = Vec3.createVectorHelper(ix, iy, iz); + Vec3 thrust = Vec3.createVectorHelper(0, -1, 0); + Vec3 target = pos.addVector(thrust.xCoord * 10, thrust.yCoord * 10, thrust.zCoord * 10); + MovingObjectPosition mop = player.worldObj.func_147447_a(pos, target, false, false, true); + + if(mop != null && mop.typeOfHit == MovingObjectType.BLOCK && mop.sideHit == 1) { + + Block b = world.getBlock(mop.blockX, mop.blockY, mop.blockZ); + int meta = world.getBlockMetadata(mop.blockX, mop.blockY, mop.blockZ); + + Vec3 delta = Vec3.createVectorHelper(ix - mop.hitVec.xCoord, iy - mop.hitVec.yCoord, iz - mop.hitVec.zCoord); + Vec3 vel = Vec3.createVectorHelper(0.75 - delta.lengthVector() * 0.075, 0, 0); + + for(int i = 0; i < (10 - delta.lengthVector()); i++) { + vel.rotateAroundY(world.rand.nextFloat() * (float)Math.PI * 2F); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlockDustFX(world, mop.hitVec.xCoord, mop.hitVec.yCoord + 0.1, mop.hitVec.zCoord, vel.xCoord, 0.1, vel.zCoord, b, meta)); + } + } + } + + EntityReddustFX dust1 = new EntityReddustFX(world, ix + ox, iy, iz + oz, 0.01F, 1.0F, 1.0F); + EntityReddustFX dust2 = new EntityReddustFX(world, ix - ox, iy, iz - oz, 0.01F, 1.0F, 1.0F); + dust1.setVelocity(p.motionX, p.motionY, p.motionZ); + dust2.setVelocity(p.motionX, p.motionY, p.motionZ); + Minecraft.getMinecraft().effectRenderer.addEffect(dust1); + Minecraft.getMinecraft().effectRenderer.addEffect(dust2); + } + break; + } + + case "muke": { + + ParticleMukeWave wave = new ParticleMukeWave(man, world, x, y, z); + ParticleMukeFlash flash = new ParticleMukeFlash(man, world, x, y, z, data.getBoolean("balefire")); + + Minecraft.getMinecraft().effectRenderer.addEffect(wave); Minecraft.getMinecraft().effectRenderer.addEffect(flash); - } - } - - if("schrabfog".equals(type)) { + + //single swing: HT 15, MHT 15 + //double swing: HT 60, MHT 50 + //vic's immersive swing: HT 100, MHT 50 - EntityAuraFX flash = new EntityAuraFX(world, x, y, z, 0, 0, 0); - flash.setRBGColorF(0F, 1F, 1F); - Minecraft.getMinecraft().effectRenderer.addEffect(flash); - } - - if("hadron".equals(type)) { - - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleHadron(man, world, x, y, z)); - } - - if("rift".equals(type)) { - - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRift(man, world, x, y, z)); - } - - if("rbmkflame".equals(type)) { - int maxAge = data.getInteger("maxAge"); - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRBMKFlame(man, world, x, y, z, maxAge)); - } - - if("rbmkmush".equals(type)) { - float scale = data.getFloat("scale"); - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRBMKMush(man, world, x, y, z, scale)); - } - - if("tower".equals(type)) { - if(particleSetting == 0 || (particleSetting == 1 && rand.nextBoolean())) { - ParticleCoolingTower fx = new ParticleCoolingTower(man, world, x, y, z); - fx.setLift(data.getFloat("lift")); - fx.setBaseScale(data.getFloat("base")); - fx.setMaxScale(data.getFloat("max")); - fx.setLife(data.getInteger("life") / (particleSetting + 1)); - - if(data.hasKey("color")) { - Color color = new Color(data.getInteger("color")); - fx.setRBGColorF(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F); - } - - Minecraft.getMinecraft().effectRenderer.addEffect(fx); - } - } - - if("deadleaf".equals(type)) { - if(particleSetting == 0 || (particleSetting == 1 && rand.nextBoolean())) - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDeadLeaf(man, world, x, y, z)); - } - - if("anim".equals(type)) { - - /* crucible deploy */ - if("crucible".equals(data.getString("mode")) && player.getHeldItem() != null) { - - BusAnimation animation = new BusAnimation() - .addBus("GUARD_ROT", new BusAnimationSequence() - .addKeyframe(new BusAnimationKeyframe(90, 0, 1, 0)) - .addKeyframe(new BusAnimationKeyframe(90, 0, 1, 800)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 1, 50))); - - HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); - } - - /* crucible swing */ - if("cSwing".equals(data.getString("mode"))) { - - if(HbmAnimations.getRelevantTransformation("SWING_ROT")[0] == 0) { - - int offset = rand.nextInt(80) - 20; - - BusAnimation animation = new BusAnimation() - .addBus("SWING_ROT", new BusAnimationSequence() - .addKeyframe(new BusAnimationKeyframe(90 - offset, 90 - offset, 35, 75)) - .addKeyframe(new BusAnimationKeyframe(90 + offset, 90 - offset, -45, 150)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 500))) - .addBus("SWING_TRANS", new BusAnimationSequence() - .addKeyframe(new BusAnimationKeyframe(-3, 0, 0, 75)) - .addKeyframe(new BusAnimationKeyframe(8, 0, 0, 150)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 500))); - - Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("hbm:weapon.cSwing"), 0.8F + player.getRNG().nextFloat() * 0.2F)); - - HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); - } - } - - /* chainsaw swing */ - if("sSwing".equals(data.getString("mode")) || "lSwing".equals(data.getString("mode"))) { //temp for lance - - int forward = 150; - int sideways = 100; - int retire = 200; - - if(HbmAnimations.getRelevantAnim() == null) { - - BusAnimation animation = new BusAnimation() - .addBus("SWING_ROT", new BusAnimationSequence() - .addKeyframe(new BusAnimationKeyframe(0, 0, 90, forward)) - .addKeyframe(new BusAnimationKeyframe(45, 0, 90, sideways)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))) - .addBus("SWING_TRANS", new BusAnimationSequence() - .addKeyframe(new BusAnimationKeyframe(0, 0, 3, forward)) - .addKeyframe(new BusAnimationKeyframe(2, 0, 2, sideways)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))); - - - HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); - + if(player.getDisplayName().equals("Vic4Games")) { + player.hurtTime = 100; + player.maxHurtTime = 50; } else { - - double[] rot = HbmAnimations.getRelevantTransformation("SWING_ROT"); - double[] trans = HbmAnimations.getRelevantTransformation("SWING_TRANS"); - - if(System.currentTimeMillis() - HbmAnimations.getRelevantAnim().startMillis < 50) return; - - BusAnimation animation = new BusAnimation() - .addBus("SWING_ROT", new BusAnimationSequence() - .addKeyframe(new BusAnimationKeyframe(rot[0], rot[1], rot[2], 0)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 90, forward)) - .addKeyframe(new BusAnimationKeyframe(45, 0, 90, sideways)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))) - .addBus("SWING_TRANS", new BusAnimationSequence() - .addKeyframe(new BusAnimationKeyframe(trans[0], trans[1], trans[2], 0)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 3, forward)) - .addKeyframe(new BusAnimationKeyframe(2, 0, 2, sideways)) - .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))); - - HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); + player.hurtTime = 15; + player.maxHurtTime = 15; } + player.attackedAtYaw = 0F; + break; } - } - if("tau".equals(type)) { + case "tinytot": { + + ParticleMukeWave wave = new ParticleMukeWave(man, world, x, y, z); + Minecraft.getMinecraft().effectRenderer.addEffect(wave); + + for(double d = 0.0D; d <= 1.6D; d += 0.1) { + ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y, z, rand.nextGaussian() * 0.05, d + rand.nextGaussian() * 0.02, rand.nextGaussian() * 0.05); + Minecraft.getMinecraft().effectRenderer.addEffect(cloud); + } + for(int i = 0; i < 50; i++) { + ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y + 0.5, z, rand.nextGaussian() * 0.5, rand.nextInt(5) == 0 ? 0.02 : 0, rand.nextGaussian() * 0.5); + Minecraft.getMinecraft().effectRenderer.addEffect(cloud); + } + for(int i = 0; i < 15; i++) { + double ix = rand.nextGaussian() * 0.2; + double iz = rand.nextGaussian() * 0.2; + + if(ix * ix + iz * iz > 0.75) { + ix *= 0.5; + iz *= 0.5; + } + + double iy = 1.6 + (rand.nextDouble() * 2 - 1) * (0.75 - (ix * ix + iz * iz)) * 0.5; + + ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y, z, ix, iy + rand.nextGaussian() * 0.02, iz); + Minecraft.getMinecraft().effectRenderer.addEffect(cloud); + } + if(player.getDisplayName().equals("Vic4Games")) { + player.hurtTime = 100; + player.maxHurtTime = 50; + } else { + player.hurtTime = 15; + player.maxHurtTime = 15; + } + player.attackedAtYaw = 0F; + } + + case "ufo": { + double motion = data.getDouble("motion"); + ParticleMukeCloud cloud = new ParticleMukeCloud(man, world, x, y, z, rand.nextGaussian() * motion, 0, rand.nextGaussian() * motion); + Minecraft.getMinecraft().effectRenderer.addEffect(cloud); + break; + } + + case "haze": { + ParticleHaze fog = new ParticleHaze(man, world, x, y, z); + Minecraft.getMinecraft().effectRenderer.addEffect(fog); + break; + } + + case "plasmablast": { - for(int i = 0; i < data.getByte("count"); i++) - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSpark(world, x, y, z, rand.nextGaussian() * 0.05, 0.05, rand.nextGaussian() * 0.05)); - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleHadron(man, world, x, y, z)); - } + ParticlePlasmaBlast cloud = new ParticlePlasmaBlast(man, world, x, y, z, data.getFloat("r"), data.getFloat("g"), data.getFloat("b"), data.getFloat("pitch"), data.getFloat("yaw")); + cloud.setScale(data.getFloat("scale")); + Minecraft.getMinecraft().effectRenderer.addEffect(cloud); + break; + } - if("vanish".equals(type)) { - int ent = data.getInteger("ent"); - this.vanish(ent); - } + case "justTilt": { + + player.hurtTime = player.maxHurtTime = data.getInteger("time"); + player.attackedAtYaw = 0F; + break; + } - if("giblets".equals(type)) { + case "properJolt": { + + player.hurtTime = data.getInteger("time"); + player.maxHurtTime = data.getInteger("maxTime"); + player.attackedAtYaw = 0F; + break; + } + + case "sweat": { + + Entity e = world.getEntityByID(data.getInteger("entity")); + Block b = Block.getBlockById(data.getInteger("block")); + int meta = data.getInteger("meta"); + + if(e instanceof EntityLivingBase) { + + for(int i = 0; i < data.getInteger("count"); i++) { + + double ix = e.boundingBox.minX - 0.2 + (e.boundingBox.maxX - e.boundingBox.minX + 0.4) * rand.nextDouble(); + double iy = e.boundingBox.minY + (e.boundingBox.maxY - e.boundingBox.minY + 0.2) * rand.nextDouble(); + double iz = e.boundingBox.minZ - 0.2 + (e.boundingBox.maxZ - e.boundingBox.minZ + 0.4) * rand.nextDouble(); + + + EntityFX fx = new net.minecraft.client.particle.EntityBlockDustFX(world, ix, iy, iz, 0, 0, 0, b, meta); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 150 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); + + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + } + break; + } + + case "vomit": { + + Entity e = world.getEntityByID(data.getInteger("entity")); + int count = data.getInteger("count") / (particleSetting + 1); + + if(e instanceof EntityLivingBase) { + + double ix = e.posX; + double iy = e.posY - e.getYOffset() + e.getEyeHeight() + (e instanceof EntityPlayer ? 1 : 0); + double iz = e.posZ; + + Vec3 vec = e.getLookVec(); + + for(int i = 0; i < count; i++) { + + if("normal".equals(data.getString("mode"))) { + EntityFX fx = new net.minecraft.client.particle.EntityBlockDustFX(world, ix, iy, iz, (vec.xCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.yCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.zCoord + rand.nextGaussian() * 0.2) * 0.2, Blocks.stained_hardened_clay, (rand.nextBoolean() ? 5 : 13)); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 150 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + + if("blood".equals(data.getString("mode"))) { + EntityFX fx = new net.minecraft.client.particle.EntityBlockDustFX(world, ix, iy, iz, (vec.xCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.yCoord + rand.nextGaussian() * 0.2) * 0.2, (vec.zCoord + rand.nextGaussian() * 0.2) * 0.2, Blocks.redstone_block, 0); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 150 + rand.nextInt(50), "particleMaxAge", "field_70547_e"); + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + + if("smoke".equals(data.getString("mode"))) { + EntityFX fx = new net.minecraft.client.particle.EntitySmokeFX(world, ix, iy, iz, (vec.xCoord + rand.nextGaussian() * 0.1) * 0.05, (vec.yCoord + rand.nextGaussian() * 0.1) * 0.05, (vec.zCoord + rand.nextGaussian() * 0.1) * 0.05, 0.2F); + ReflectionHelper.setPrivateValue(EntityFX.class, fx, 10 + rand.nextInt(10), "particleMaxAge", "field_70547_e"); + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + } + } + break; + } + + case "radiation": { + + for(int i = 0; i < data.getInteger("count"); i++) { + + EntityAuraFX flash = new EntityAuraFX(world, + player.posX + rand.nextGaussian() * 4, + player.posY + rand.nextGaussian() * 2, + player.posZ + rand.nextGaussian() * 4, + 0, 0, 0); + + flash.setRBGColorF(0F, 0.75F, 1F); + flash.setVelocity(rand.nextGaussian(), rand.nextGaussian(), rand.nextGaussian()); + Minecraft.getMinecraft().effectRenderer.addEffect(flash); + } + break; + } + + case "schrabfog": { + + EntityAuraFX flash = new EntityAuraFX(world, x, y, z, 0, 0, 0); + flash.setRBGColorF(0F, 1F, 1F); + Minecraft.getMinecraft().effectRenderer.addEffect(flash); + break; + } + + case "hadron": Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleHadron(man, world, x, y, z)); break; + case "rift": Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRift(man, world, x, y, z)); break; + case "rbmkflame": Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRBMKFlame(man, world, x, y, z, data.getInteger("maxAge"))); break; + case "rbmkmush": Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRBMKMush(man, world, x, y, z, data.getFloat("scale"))); break; + + case "tower": { + if(particleSetting == 0 || (particleSetting == 1 && rand.nextBoolean())) { + ParticleCoolingTower fx = new ParticleCoolingTower(man, world, x, y, z); + fx.setLift(data.getFloat("lift")); + fx.setBaseScale(data.getFloat("base")); + fx.setMaxScale(data.getFloat("max")); + fx.setLife(data.getInteger("life") / (particleSetting + 1)); + + if(data.hasKey("color")) { + Color color = new Color(data.getInteger("color")); + fx.setRBGColorF(color.getRed() / 255F, color.getGreen() / 255F, color.getBlue() / 255F); + } + + Minecraft.getMinecraft().effectRenderer.addEffect(fx); + } + break; + } + + case "deadleaf": { + if(particleSetting == 0 || (particleSetting == 1 && rand.nextBoolean())) + Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDeadLeaf(man, world, x, y, z)); + break; + } + + case "anim": { + + /* crucible deploy */ + switch (data.getString("mode")) + { + case "crucible": + if(player.getHeldItem() != null) { + + BusAnimation animation = new BusAnimation() + .addBus("GUARD_ROT", new BusAnimationSequence() + .addKeyframe(new BusAnimationKeyframe(90, 0, 1, 0)) + .addKeyframe(new BusAnimationKeyframe(90, 0, 1, 800)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 1, 50))); + + HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); + } + break; + /* crucible swing */ + case "cSwing": { + + if(HbmAnimations.getRelevantTransformation("SWING_ROT")[0] == 0) { + + int offset = rand.nextInt(80) - 20; + + BusAnimation animation = new BusAnimation() + .addBus("SWING_ROT", new BusAnimationSequence() + .addKeyframe(new BusAnimationKeyframe(90 - offset, 90 - offset, 35, 75)) + .addKeyframe(new BusAnimationKeyframe(90 + offset, 90 - offset, -45, 150)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 500))) + .addBus("SWING_TRANS", new BusAnimationSequence() + .addKeyframe(new BusAnimationKeyframe(-3, 0, 0, 75)) + .addKeyframe(new BusAnimationKeyframe(8, 0, 0, 150)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 500))); + + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("hbm:weapon.cSwing"), 0.8F + player.getRNG().nextFloat() * 0.2F)); + + HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); + } + break; + } + + /* chainsaw swing */ + case "sSwing": + case "lSwing": + { //temp for lance + + int forward = 150; + int sideways = 100; + int retire = 200; + + if(HbmAnimations.getRelevantAnim() == null) { + + BusAnimation animation = new BusAnimation() + .addBus("SWING_ROT", new BusAnimationSequence() + .addKeyframe(new BusAnimationKeyframe(0, 0, 90, forward)) + .addKeyframe(new BusAnimationKeyframe(45, 0, 90, sideways)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))) + .addBus("SWING_TRANS", new BusAnimationSequence() + .addKeyframe(new BusAnimationKeyframe(0, 0, 3, forward)) + .addKeyframe(new BusAnimationKeyframe(2, 0, 2, sideways)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))); + + + HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); + + } else { + + double[] rot = HbmAnimations.getRelevantTransformation("SWING_ROT"); + double[] trans = HbmAnimations.getRelevantTransformation("SWING_TRANS"); + + if(System.currentTimeMillis() - HbmAnimations.getRelevantAnim().startMillis < 50) return; + + BusAnimation animation = new BusAnimation() + .addBus("SWING_ROT", new BusAnimationSequence() + .addKeyframe(new BusAnimationKeyframe(rot[0], rot[1], rot[2], 0)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 90, forward)) + .addKeyframe(new BusAnimationKeyframe(45, 0, 90, sideways)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))) + .addBus("SWING_TRANS", new BusAnimationSequence() + .addKeyframe(new BusAnimationKeyframe(trans[0], trans[1], trans[2], 0)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 3, forward)) + .addKeyframe(new BusAnimationKeyframe(2, 0, 2, sideways)) + .addKeyframe(new BusAnimationKeyframe(0, 0, 0, retire))); + + HbmAnimations.hotbar[player.inventory.currentItem] = new Animation(player.getHeldItem().getItem().getUnlocalizedName(), System.currentTimeMillis(), animation); + } + } + default: + break; + } + break; + } + + case "tau": { + + for(int i = 0; i < data.getByte("count"); i++) + Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSpark(world, x, y, z, rand.nextGaussian() * 0.05, 0.05, rand.nextGaussian() * 0.05)); + Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleHadron(man, world, x, y, z)); + break; + } + + case "vanish": { + int ent = data.getInteger("ent"); + this.vanish(ent); + break; + } + + case "giblets": { int ent = data.getInteger("ent"); this.vanish(ent); Entity e = world.getEntityByID(ent); @@ -1766,48 +1775,48 @@ public class ClientProxy extends ServerProxy { for(int i = 0; i < count; i++) { Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleGiblet(man, world, x, y, z, rand.nextGaussian() * 0.25 * mult, rand.nextDouble() * mult, rand.nextGaussian() * 0.25 * mult)); } + break; } + case "amat": Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleAmatFlash(world, x, y, z, data.getFloat("scale"))); break; - if("amat".equals(type)) { - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleAmatFlash(world, x, y, z, data.getFloat("scale"))); - } - - if("debug".equals(type)) { - String t = data.getString("text"); - int color = data.getInteger("color"); - float scale = data.getFloat("scale"); - ParticleText text = new ParticleText(world, x, y, z, color, t); - text.multipleParticleScaleBy(scale); - Minecraft.getMinecraft().effectRenderer.addEffect(text); - } - - if("network".equals(type)) { - ParticleDebug debug = null; - double mX = data.getDouble("mX"); - double mY = data.getDouble("mY"); - double mZ = data.getDouble("mZ"); - - if("power".equals(data.getString("mode"))) { - debug = new ParticleDebug(man, world, x, y, z, mX, mY, mZ); - } - if("fluid".equals(data.getString("mode"))) { + case "debug": { + String t = data.getString("text"); int color = data.getInteger("color"); - debug = new ParticleDebug(man, world, x, y, z, mX, mY, mZ, color); + float scale = data.getFloat("scale"); + ParticleText text = new ParticleText(world, x, y, z, color, t); + text.multipleParticleScaleBy(scale); + Minecraft.getMinecraft().effectRenderer.addEffect(text); + break; } - Minecraft.getMinecraft().effectRenderer.addEffect(debug); - } - if("gasfire".equals(type)) { - double mX = data.getDouble("mX"); - double mY = data.getDouble("mY"); - double mZ = data.getDouble("mZ"); - float scale = data.getFloat("scale"); - ParticleGasFlame text = new ParticleGasFlame(world, x, y, z, mX, mY, mZ, scale > 0 ? scale : 6.5F); - Minecraft.getMinecraft().effectRenderer.addEffect(text); + case "network": { + ParticleDebug debug = null; + double mX = data.getDouble("mX"); + double mY = data.getDouble("mY"); + double mZ = data.getDouble("mZ"); + switch (data.getString("mode")) + { + case "power": debug = new ParticleDebug(man, world, x, y, z, mX, mY, mZ); break; + case "fluid": debug = new ParticleDebug(man, world, x, y, z, mX, mY, mZ, data.getInteger("color")); break; + default: break; + } + Minecraft.getMinecraft().effectRenderer.addEffect(debug); + break; + } + + case "gasfire": { + double mX = data.getDouble("mX"); + double mY = data.getDouble("mY"); + double mZ = data.getDouble("mZ"); + float scale = data.getFloat("scale"); + ParticleGasFlame text = new ParticleGasFlame(world, x, y, z, mX, mY, mZ, scale > 0 ? scale : 6.5F); + Minecraft.getMinecraft().effectRenderer.addEffect(text); + break; + } } } - private HashMap vanished = new HashMap(); + private final HashMap vanished = new HashMap(); public void vanish(int ent) { vanished.put(ent, System.currentTimeMillis() + 2000); @@ -1853,9 +1862,9 @@ public class ClientProxy extends ServerProxy { public void displayTooltip(String msg, int time, int id) { if(id != 0) - this.theInfoSystem.push(new InfoEntry(msg, time), id); + RenderInfoSystem.push(new InfoEntry(msg, time), id); else - this.theInfoSystem.push(new InfoEntry(msg, time)); + RenderInfoSystem.push(new InfoEntry(msg, time)); } @Override @@ -1872,9 +1881,9 @@ public class ClientProxy extends ServerProxy { case CRANE_LEFT: return HbmKeybinds.craneLeftKey.getIsKeyPressed(); case CRANE_RIGHT: return HbmKeybinds.craneRightKey.getIsKeyPressed(); case CRANE_LOAD: return HbmKeybinds.craneLoadKey.getIsKeyPressed(); + default: return false; } - return false; } @Override @@ -1886,13 +1895,15 @@ public class ClientProxy extends ServerProxy { public void openLink(String url) { try { Desktop.getDesktop().browse(new URI(url)); - } catch (Exception e) { } + } catch (Exception e) { + MainRegistry.logger.catching(e); + } } @Override public List getSubItems(ItemStack stack) { - List list = new ArrayList(); + List list = new ArrayList(); stack.getItem().getSubItems(stack.getItem(), stack.getItem().getCreativeTab(), list); for(ItemStack sta : list) { sta.stackSize = stack.stackSize; diff --git a/src/main/java/com/hbm/main/ServerProxy.java b/src/main/java/com/hbm/main/ServerProxy.java index 47aadfd5a..9a8f17ce2 100644 --- a/src/main/java/com/hbm/main/ServerProxy.java +++ b/src/main/java/com/hbm/main/ServerProxy.java @@ -14,7 +14,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; -public class ServerProxy { +public abstract class ServerProxy { //sort by estimated time of display. longer lasting ones should be sorted at the top. public static final int ID_DUCK = 0; @@ -28,50 +28,46 @@ public class ServerProxy { public static final int ID_GUN_MODE = 8; public static final int ID_GAS_HAZARD = 9; - public void registerRenderInfo() { } - public void registerTileEntitySpecialRenderer() { } - public void registerItemRenderer() { } - public void registerEntityRenderer() { } - public void registerBlockRenderer() { } + public abstract void registerRenderInfo(); + public abstract void registerTileEntitySpecialRenderer(); + public abstract void registerItemRenderer(); + public abstract void registerEntityRenderer(); + public abstract void registerBlockRenderer(); - public void particleControl(double x, double y, double z, int type) { } + public abstract void particleControl(double x, double y, double z, int type); - public void spawnParticle(double x, double y, double z, String type, float[] args) { } + public abstract void spawnParticle(double x, double y, double z, String type, float... args); - public void effectNT(NBTTagCompound data) { } + public abstract void effectNT(NBTTagCompound data); - public void registerMissileItems() { } + public abstract void registerMissileItems(); - public AudioWrapper getLoopedSound(String sound, float x, float y, float z, float volume, float pitch) { return null; } - public AudioWrapper getLoopedSoundStartStop(World world, String sound, String start, String stop, float x, float y, float z, float volume, float pitch) { return null; } + public abstract AudioWrapper getLoopedSound(String sound, float x, float y, float z, float volume, float pitch); + public abstract AudioWrapper getLoopedSoundStartStop(World world, String sound, String start, String stop, float x, float y, float z, float volume, float pitch); - public void playSound(String sound, Object data) { } + public abstract void playSound(String sound, Object data); public void displayTooltip(String msg, int id) { displayTooltip(msg, 1000, id); } - public void displayTooltip(String msg, int time, int id) { } + public abstract void displayTooltip(String msg, int time, int id); - public boolean getIsKeyPressed(EnumKeybind key) { - return false; - } - public EntityPlayer me() { - return null; - } + public abstract boolean getIsKeyPressed(EnumKeybind key); + public abstract EntityPlayer me(); - public boolean isVanished(Entity e) { - return false; - } + public abstract boolean isVanished(Entity e); - public void openLink(String url) { } + public abstract void openLink(String url); + @SuppressWarnings({ "unused", "static-method" }) public SoundWrapper getTileSound(String sound, ISoundSourceTE source) { return new SoundWrapper(); } + @SuppressWarnings("static-method") public List getSubItems(ItemStack stack) { - List list = new ArrayList(); + List list = new ArrayList(); list.add(stack); return list; } diff --git a/src/main/java/com/hbm/particle/ParticleSpentCasing.java b/src/main/java/com/hbm/particle/ParticleSpentCasing.java new file mode 100644 index 000000000..254f44a2d --- /dev/null +++ b/src/main/java/com/hbm/particle/ParticleSpentCasing.java @@ -0,0 +1,97 @@ +package com.hbm.particle; + +import org.lwjgl.opengl.GL11; + +import com.hbm.lib.RefStrings; +import com.hbm.particle.SpentCasingConfig.CasingType; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class ParticleSpentCasing extends EntityFX +{ + private static final ResourceLocation TEXTURE_BRASS = new ResourceLocation(RefStrings.MODID, "textures/particle/casing_brass.png"), + TEXTURE_SHOTGUN = new ResourceLocation(RefStrings.MODID, "textures/particle/casing_shotgun.png"), + TEXTURE_AR2 = new ResourceLocation(RefStrings.MODID, "textures/particle/casing_ar2.png"); + + private final TextureManager textureManager; + + private final float momentumPitch, momentumYaw; + private final CasingType casingType; + public ParticleSpentCasing(TextureManager textureManager, World world, double x, double y, double z, double mx, double my, double mz, CasingType casingType, float momentumPitch, float momentumYaw) + { + super(world, x, y, z, mx, my, mz); + particleMaxAge = 120; + this.textureManager = textureManager; + this.casingType = casingType; + this.momentumPitch = momentumPitch; + this.momentumYaw = momentumYaw; + } + + @Override + public int getFXLayer() + { + return 3; + } + + @Override + public void onUpdate() + { + // TODO Auto-generated method stub + super.onUpdate(); + + prevRotationPitch = rotationPitch; + prevRotationYaw = rotationYaw; + + if (!onGround) + { + rotationPitch += momentumPitch; + rotationYaw += momentumYaw; + } + } + + @Override + public void renderParticle( + Tessellator tessellator, float interp, float x, float y, float z, + float tx, float tz + ) + { + // TODO Auto-generated method stub + super.renderParticle(tessellator, interp, x, y, z, tx, tz); + + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); + final ResourceLocation texture; + switch (casingType) + { + case AR2: texture = TEXTURE_AR2; break; + case BRASS: texture = TEXTURE_BRASS; break; + case SHOTGUN: texture = TEXTURE_SHOTGUN; break; + default: throw new IllegalStateException("CasingType [" + casingType + "] is not recognized, cannot render spent casing!"); + } + textureManager.bindTexture(texture); + + final float scale = particleScale * 0.1f, + xInterp = (float) (prevPosX + (posX - prevPosX) * interp - interpPosX), + yInterp = (float) (prevPosY + (posY - prevPosY) * interp - interpPosY), + zInterp = (float) (prevPosZ + (posZ - prevPosZ) * interp - interpPosZ); + + tessellator.startDrawingQuads(); + tessellator.setNormal(0, 1, 0); + tessellator.setBrightness(240); + tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, particleAlpha); + tessellator.addVertexWithUV(xInterp - x * scale - tx * scale, yInterp - y, zInterp - z * scale - tz * scale, 0, 0); + tessellator.addVertexWithUV(xInterp - x * scale + tx * scale, yInterp + y, zInterp - z * scale + tz * scale, 0, 1); + tessellator.addVertexWithUV(xInterp + x * scale + tx * scale, yInterp + y, zInterp + z * scale + tz * scale, 1, 1); + tessellator.addVertexWithUV(xInterp + x * scale - tx * scale, yInterp - y, zInterp + z * scale - tz * scale, 1, 0); + tessellator.draw(); + + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/com/hbm/particle/SpentCasingConfig.java b/src/main/java/com/hbm/particle/SpentCasingConfig.java new file mode 100644 index 000000000..3bf9e031b --- /dev/null +++ b/src/main/java/com/hbm/particle/SpentCasingConfig.java @@ -0,0 +1,200 @@ +package com.hbm.particle; + +import java.util.Objects; + +public class SpentCasingConfig implements Cloneable +{ + + public enum CasingType + { + /**The typical ejected type. Most pistols, rifles, and even cannons will likely use it.**/ + BRASS, + /**Shotgun shells.**/ + SHOTGUN, + /**AR2 pulse rifle plugs.**/ + AR2; + } + + /**Change position of the ejecting shell.**/ + private final double offsetX, offsetY, offsetZ; + /**Set initial motion after ejecting.**/ + private final double motionX, motionY, motionZ; + /**Rescale the sprite to match the approximate scale of the rounds.**/ + private final float stretchX, stretchY; + /**Multipliers for random pitch and yaw.**/ + private final float pitchFactor, yawFactor; + /**Overrides for the sprite colors.**/ + private final int redOverride, greenOverride, blueOverride; + /**Whether or not to override the default sprite color scheme.**/ + private final boolean overrideColor; + /**The type of casing.**/ + private final CasingType casingType; + /**Amount of casings to spawn per event. Default 1.**/ + private final int casingAmount; + /**If the casing(s) should be spawned after reloading, instead of after firing.**/ + private final boolean afterReload; + public SpentCasingConfig( + double offsetX, double offsetY, double offsetZ, double motionX, double motionY, double motionZ, + float stretchX, float stretchY, float pitchFactor, float yawFactor, int redOverride, int greenOverride, + int blueOverride, boolean overrideColor, CasingType casingType, int casingAmount, boolean afterReload + ) + { + this.offsetX = offsetX; + this.offsetY = offsetY; + this.offsetZ = offsetZ; + this.motionX = motionX; + this.motionY = motionY; + this.motionZ = motionZ; + this.stretchX = stretchX; + this.stretchY = stretchY; + this.pitchFactor = pitchFactor; + this.yawFactor = yawFactor; + this.redOverride = redOverride; + this.greenOverride = greenOverride; + this.blueOverride = blueOverride; + this.overrideColor = overrideColor; + this.casingType = casingType; + this.casingAmount = casingAmount; + this.afterReload = afterReload; + } + + /** + * Apply these settings to an initialized casing entity + * @param entity The entity to apply the settings defined by this object + */ + public void applyToEntity(ParticleSpentCasing entity) + { + entity.setPosition((entity.posX - Math.cos(entity.rotationYaw / 180 * Math.PI)) + offsetX, + (entity.posY - 0.1) + offsetY, + (entity.posZ - Math.sin(entity.rotationYaw / 180 * Math.PI) + offsetZ)); + + entity.setRBGColorF((float) redOverride / 255, (float) greenOverride / 255, (float) blueOverride / 255); + } + + public double getOffsetX() + { + return offsetX; + } + public double getOffsetY() + { + return offsetY; + } + public double getOffsetZ() + { + return offsetZ; + } + public double getMotionX() + { + return motionX; + } + public double getMotionY() + { + return motionY; + } + public double getMotionZ() + { + return motionZ; + } + public float getStretchX() + { + return stretchX; + } + public float getStretchY() + { + return stretchY; + } + public float getPitchFactor() + { + return pitchFactor; + } + public float getYawFactor() + { + return yawFactor; + } + public int getRedOverride() + { + return redOverride; + } + public int getGreenOverride() + { + return greenOverride; + } + public int getBlueOverride() + { + return blueOverride; + } + public boolean isOverrideColor() + { + return overrideColor; + } + public CasingType getCasingType() + { + return casingType; + } + public int getCasingAmount() + { + return casingAmount; + } + public boolean isAfterReload() + { + return afterReload; + } + @Override + public int hashCode() + { + return Objects.hash(afterReload, blueOverride, casingAmount, casingType, greenOverride, motionX, motionY, motionZ, + offsetX, offsetY, offsetZ, overrideColor, pitchFactor, redOverride, stretchX, stretchY, yawFactor); + } + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (!(obj instanceof SpentCasingConfig)) + return false; + final SpentCasingConfig other = (SpentCasingConfig) obj; + return afterReload == other.afterReload && blueOverride == other.blueOverride + && casingAmount == other.casingAmount && casingType == other.casingType + && greenOverride == other.greenOverride + && Double.doubleToLongBits(motionX) == Double.doubleToLongBits(other.motionX) + && Double.doubleToLongBits(motionY) == Double.doubleToLongBits(other.motionY) + && Double.doubleToLongBits(motionZ) == Double.doubleToLongBits(other.motionZ) + && Double.doubleToLongBits(offsetX) == Double.doubleToLongBits(other.offsetX) + && Double.doubleToLongBits(offsetY) == Double.doubleToLongBits(other.offsetY) + && Double.doubleToLongBits(offsetZ) == Double.doubleToLongBits(other.offsetZ) + && overrideColor == other.overrideColor + && Float.floatToIntBits(pitchFactor) == Float.floatToIntBits(other.pitchFactor) + && redOverride == other.redOverride + && Float.floatToIntBits(stretchX) == Float.floatToIntBits(other.stretchX) + && Float.floatToIntBits(stretchY) == Float.floatToIntBits(other.stretchY) + && Float.floatToIntBits(yawFactor) == Float.floatToIntBits(other.yawFactor); + } + @Override + public String toString() + { + final StringBuilder builder = new StringBuilder(); + builder.append("SpentCasingConfig [offsetX=").append(offsetX).append(", offsetY=").append(offsetY) + .append(", offsetZ=").append(offsetZ).append(", motionX=").append(motionX).append(", motionY=") + .append(motionY).append(", motionZ=").append(motionZ).append(", stretchX=").append(stretchX) + .append(", stretchY=").append(stretchY).append(", pitchFactor=").append(pitchFactor) + .append(", yawFactor=").append(yawFactor).append(", redOverride=").append(redOverride) + .append(", greenOverride=").append(greenOverride).append(", blueOverride=").append(blueOverride) + .append(", overrideColor=").append(overrideColor).append(", casingType=").append(casingType) + .append(", casingAmount=").append(casingAmount).append(", afterReload=").append(afterReload) + .append(']'); + return builder.toString(); + } + @Override + public SpentCasingConfig clone() + { + try + { + return (SpentCasingConfig) super.clone(); + } catch (CloneNotSupportedException e) + { + e.printStackTrace(); + return new SpentCasingConfig(offsetX, offsetY, offsetZ, motionX, motionY, motionZ, stretchX, stretchY, pitchFactor, yawFactor, redOverride, greenOverride, blueOverride, overrideColor, casingType, casingAmount, afterReload); + } + } + +} diff --git a/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java b/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java new file mode 100644 index 000000000..13e975773 --- /dev/null +++ b/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java @@ -0,0 +1,293 @@ +package com.hbm.particle; + +import java.util.Objects; + +import com.hbm.particle.SpentCasingConfig.CasingType; + +import net.minecraft.util.MathHelper; + +public class SpentCasingConfigBuilder implements Cloneable +{ + /**Change position of the ejecting shell.**/ + private double offsetX, offsetY, offsetZ; + /**Set initial motion after ejecting.**/ + private double motionX, motionY, motionZ; + /**Rescale the sprite to match the approximate scale of the rounds.**/ + private float stretchX, stretchY; + /**Multipliers for random pitch and yaw.**/ + private float pitchFactor = 1, yawFactor = 1; + /**Overrides for the sprite colors.**/ + private int redOverride, greenOverride, blueOverride; + /**Whether or not to override the default sprite color scheme.**/ + private boolean overrideColor; + /**The type of casing.**/ + private CasingType casingType; + /**Amount of casings to spawn per event. Default 1.**/ + private int casingAmount = 1; + /**If the casing(s) should be spawned after reloading, instead of after firing.**/ + private boolean afterReload; + public SpentCasingConfigBuilder(CasingType casingType, boolean overrideColor) + { + this.casingType = casingType; + this.overrideColor = overrideColor; + } + + public double getOffsetX() + { + return offsetX; + } + + public SpentCasingConfigBuilder setOffsetX(double offsetX) + { + this.offsetX = offsetX; + return this; + } + + public double getOffsetY() + { + return offsetY; + } + + public SpentCasingConfigBuilder setOffsetY(double offsetY) + { + this.offsetY = offsetY; + return this; + } + + public double getOffsetZ() + { + return offsetZ; + } + + public SpentCasingConfigBuilder setOffsetZ(double offsetZ) + { + this.offsetZ = offsetZ; + return this; + } + + public double getMotionX() + { + return motionX; + } + + public SpentCasingConfigBuilder setMotionX(double motionX) + { + this.motionX = motionX; + return this; + } + + public double getMotionY() + { + return motionY; + } + + public SpentCasingConfigBuilder setMotionY(double motionY) + { + this.motionY = motionY; + return this; + } + + public double getMotionZ() + { + return motionZ; + } + + public SpentCasingConfigBuilder setMotionZ(double motionZ) + { + this.motionZ = motionZ; + return this; + } + + public double getStretchX() + { + return stretchX; + } + + public SpentCasingConfigBuilder setStretchX(float stretchX) + { + this.stretchX = stretchX; + return this; + } + + public double getStretchY() + { + return stretchY; + } + + public SpentCasingConfigBuilder setStretchY(float stretchY) + { + this.stretchY = stretchY; + return this; + } + + public float getPitchFactor() + { + return pitchFactor; + } + + public SpentCasingConfigBuilder setPitchFactor(float pitchFactor) + { + this.pitchFactor = pitchFactor; + return this; + } + + public float getYawFactor() + { + return yawFactor; + } + + public SpentCasingConfigBuilder setYawFactor(float yawFactor) + { + this.yawFactor = yawFactor; + return this; + } + + public int getRedOverride() + { + return redOverride; + } + + public SpentCasingConfigBuilder setRedOverride(int redOverride) + { + this.redOverride = MathHelper.clamp_int(redOverride, 0, 255); + return this; + } + + public int getGreenOverride() + { + return greenOverride; + } + + public SpentCasingConfigBuilder setGreenOverride(int greenOverride) + { + this.greenOverride = MathHelper.clamp_int(greenOverride, 0, 255); + return this; + } + + public int getBlueOverride() + { + return blueOverride; + } + + public SpentCasingConfigBuilder setBlueOverride(int blueOverride) + { + this.blueOverride = MathHelper.clamp_int(blueOverride, 0, 255); + return this; + } + + public boolean isOverrideColor() + { + return overrideColor; + } + + public SpentCasingConfigBuilder setOverrideColor(boolean overrideColor) + { + this.overrideColor = overrideColor; + return this; + } + + public CasingType getCasingType() + { + return casingType; + } + + public SpentCasingConfigBuilder setCasingType(CasingType casingType) + { + this.casingType = casingType; + return this; + } + + public int getCasingAmount() + { + return casingAmount; + } + + public SpentCasingConfigBuilder setCasingAmount(int casingAmount) + { + this.casingAmount = casingAmount; + return this; + } + + public boolean isAfterReload() + { + return afterReload; + } + + public SpentCasingConfigBuilder setAfterReload(boolean afterReload) + { + this.afterReload = afterReload; + return this; + } + + public SpentCasingConfig build() + { + return new SpentCasingConfig(offsetX, offsetY, offsetZ, motionX, motionY, motionZ, stretchX, stretchY, pitchFactor, yawFactor, redOverride, greenOverride, blueOverride, overrideColor, casingType, casingAmount, afterReload); + } + + @Override + public int hashCode() + { + return Objects.hash(afterReload, blueOverride, casingAmount, casingType, greenOverride, motionX, motionY, + motionZ, offsetX, offsetY, offsetZ, overrideColor, pitchFactor, redOverride, stretchX, stretchY, + yawFactor); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (!(obj instanceof SpentCasingConfigBuilder)) + return false; + final SpentCasingConfigBuilder other = (SpentCasingConfigBuilder) obj; + return afterReload == other.afterReload && blueOverride == other.blueOverride + && casingAmount == other.casingAmount && casingType == other.casingType + && greenOverride == other.greenOverride + && Double.doubleToLongBits(motionX) == Double.doubleToLongBits(other.motionX) + && Double.doubleToLongBits(motionY) == Double.doubleToLongBits(other.motionY) + && Double.doubleToLongBits(motionZ) == Double.doubleToLongBits(other.motionZ) + && Double.doubleToLongBits(offsetX) == Double.doubleToLongBits(other.offsetX) + && Double.doubleToLongBits(offsetY) == Double.doubleToLongBits(other.offsetY) + && Double.doubleToLongBits(offsetZ) == Double.doubleToLongBits(other.offsetZ) + && overrideColor == other.overrideColor + && Float.floatToIntBits(pitchFactor) == Float.floatToIntBits(other.pitchFactor) + && redOverride == other.redOverride + && Float.floatToIntBits(stretchX) == Float.floatToIntBits(other.stretchX) + && Float.floatToIntBits(stretchY) == Float.floatToIntBits(other.stretchY) + && Float.floatToIntBits(yawFactor) == Float.floatToIntBits(other.yawFactor); + } + + @Override + public String toString() + { + final StringBuilder builder = new StringBuilder(); + builder.append("SpentCasingConfigBuilder [offsetX=").append(offsetX).append(", offsetY=").append(offsetY) + .append(", offsetZ=").append(offsetZ).append(", motionX=").append(motionX).append(", motionY=") + .append(motionY).append(", motionZ=").append(motionZ).append(", stretchX=").append(stretchX) + .append(", stretchY=").append(stretchY).append(", pitchFactor=").append(pitchFactor) + .append(", yawFactor=").append(yawFactor).append(", redOverride=").append(redOverride) + .append(", greenOverride=").append(greenOverride).append(", blueOverride=").append(blueOverride) + .append(", overrideColor=").append(overrideColor).append(", casingType=").append(casingType) + .append(", casingAmount=").append(casingAmount).append(", afterReload=").append(afterReload) + .append(']'); + return builder.toString(); + } + + @Override + public SpentCasingConfigBuilder clone() + { + try + { + return (SpentCasingConfigBuilder) super.clone(); + } catch (CloneNotSupportedException e) + { + e.printStackTrace(); + return new SpentCasingConfigBuilder(casingType, overrideColor).setBlueOverride(blueOverride) + .setCasingAmount(casingAmount).setGreenOverride(greenOverride).setMotionX(motionX) + .setMotionY(motionY).setMotionZ(motionZ).setOffsetX(offsetX).setOffsetY(offsetY) + .setOffsetZ(offsetZ).setPitchFactor(pitchFactor).setRedOverride(redOverride) + .setStretchX(stretchX).setStretchY(stretchY).setYawFactor(yawFactor); + } + } + +} diff --git a/src/main/resources/assets/hbm/textures/particle/casing_brass.png b/src/main/resources/assets/hbm/textures/particle/casing_brass.png new file mode 100644 index 0000000000000000000000000000000000000000..fe691d7f58d332bb67aff772daa0e1386335a4e4 GIT binary patch literal 633 zcmV-<0*3vGP)EX>4Tx04R}tkv&MmKpe$iQ^le!4i*$~$WWauNELC^DionYs1;guFu8t0lZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`n1Q3&%sn1DL5}xDh9zMR_MR}I@xj#oJmp2*U6NzV;Zdk+{#M7IW z&Uv3W%t~^O_?&p$pbHW|a$RxxjdRgqfoFz|bZVYBOe_{VSm|I^GF0Lz;z&-_C|}69 zoa4O3S*_Gq>z@3D!MwJz%ypV0NMI35kRU=q4P{hdAxf)8iis5M$36VRj$a~|Las6x zITlcb3fb|4|H1EW&BA2NO$x?=?ibts7zKKEfo9#dzmILZc>?&Kfh(=;uQq_0Ptxmc zEpi0(Zvz+CZB5w&E_Z;TCtWsVNAlAY3I*W(jJ_!g4BP^}Yi@6?eVjf3Y3eF@0~{Oz zV@1kd_jq@pv$ucGwEFu2b%b)Lq}GR=00006VoOIv0000U0Mu?pBgg;%010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru<_iu17aC&a1I7RV0Cq`4K~y-)V_+EafN@%}^nY?R zX7xU0oK`ITpC!;;mt4#L2fFJrFj49S78Xu1@-=gck?(?6Z@xhc5z){f(}>LsA{rVD zEDS&2kskm*-;wWy$4}owys&N64zeAvZPgAcMB}<`SIE*hcMk(21H+a71D}}y^w%AA T5|ts-00000NkvXXu0mjfcmxQ= literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/particle/casing_shotgun.png b/src/main/resources/assets/hbm/textures/particle/casing_shotgun.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed08d5ab85f94cd0db2c09e260a3b66617bad5b GIT binary patch literal 628 zcmV-)0*n2LP)EX>4Tx04R}tkv&MmKpe$iQ^le!4i*$~$WWauNELC^DionYs1;guFu8t0lZGV4 z#ZhoAIQX$xb#QUk)xlK|1V2C=otzY1q{ROvg%&X$9QWhhy~o`n1Q3&%sn1DL5}xDh9zMR_MR}I@xj#oJmp2*U6NzV;Zdk+{#M7IW z&Uv3W%t~^O_?&p$pbHW|a$RxxjdRgqfoFz|bZVYBOe_{VSm|I^GF0Lz;z&-_C|}69 zoa4O3S*_Gq>z@3D!MwJz%ypV0NMI35kRU=q4P{hdAxf)8iis5M$36VRj$a~|Las6x zITlcb3fb|4|H1EW&BA2NO$x?=?ibts7zKKEfo9#dzmILZc>?&Kfh(=;uQq_0Ptxmc zEpi0(Zvz+CZB5w&E_Z;TCtWsVNAlAY3I*W(jJ_!g4BP^}Yi@6?eVjf3Y3eF@0~{Oz zV@1kd_jq@pv$ucGwEFu2b%b)Lq}GR=00006VoOIv0000U0Mu?pBgg;%010qNS#tmY z3ljhU3ljkVnw%H_000McNliru<_iu17bK&E9&G>s0C7n~K~y-)?TQ1I)V7^@8#4m{LEX>4Tx04R}tkv&MmKpe$i(@I5K1nnT=kfAzR5EXIMDionYs1;guFuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=;Wm6A|?JWDYS_7;J6>}?mh0_0YbgZG%GL;Xu55t z5^*t;T@{0`=tUTQ^dlfM%b1g-Bsz|-d-(Wz7vou-&;2>VYR+PSPb8jYhG`RT5KnK~ z2Iqa^2rJ4e@j3CBNf#u3C`-Ngjg)JvC_t@Xlle$#8Fk#DPPEV zta9Gstd*;*c~AbrP)=W2<~q$`B(R7jND!f*iW17O5u;Tn#X^eq;~o4%u3sXTLaq`R zITlcX2HEw4|H1EWt^DMKmlTQvT`!LFF#-g4fkw@7zKZ37qAElt@2E_Z;zCqp)6SMt*o@_FF>jJ_!g4BP@eYhG{7eVjf3Y3eF@0~{Oz zqXo)d@9^&K_TK(I)9mjD>EUv472mt>00006VoOIv0C@m;0C|6SqlN$g010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru<_ir3H8=!GX$JrR0Rl-xK~yNujgmi3!!Q`df0i<3 zh=`yJsaTMQ?i`^P=#ooBY+X44Qr2!PtQos>fQ1Wi0V@lN1Wrg8k@Ck3RZ1!)k-y3B zd)D($@)Ow1?U%8+7T(=YdP$OqvAys6rfpl=w#C_Pm!l6waVB=#rHSH9EEd<;j+F9r zR!SkIL@9OJ1wmlyx(1+W8hQ`_C)}(jVqZj3xzu-uN~RA$N(00000NkvXXu0mjf DfIwQ3 literal 0 HcmV?d00001 From 84ad6bd659a6c20de3517801d133e77b651b2e0c Mon Sep 17 00:00:00 2001 From: UFFR Date: Wed, 14 Dec 2022 22:55:47 -0500 Subject: [PATCH 2/4] Major work Most guns and turrets use the system now. Still needs work, rotations are a bit weird and the smoke effect is horrendous. Other tweaks pending. --- src/main/java/com/hbm/calc/EasyLocation.java | 60 +- .../projectile/EntityCombineBallNT.java | 2 +- .../com/hbm/handler/BulletConfiguration.java | 2 +- .../com/hbm/handler/GunConfiguration.java | 5 +- .../hbm/handler/guncfg/Gun12GaugeFactory.java | 40 + .../hbm/handler/guncfg/Gun20GaugeFactory.java | 26 + .../hbm/handler/guncfg/Gun22LRFactory.java | 16 + .../handler/guncfg/Gun357MagnumFactory.java | 22 +- .../handler/guncfg/Gun44MagnumFactory.java | 11 + .../hbm/handler/guncfg/Gun45ACPFactory.java | 23 + .../hbm/handler/guncfg/Gun4GaugeFactory.java | 20 +- .../hbm/handler/guncfg/Gun50AEFactory.java | 14 + .../hbm/handler/guncfg/Gun50BMGFactory.java | 25 + .../hbm/handler/guncfg/Gun556mmFactory.java | 46 +- .../com/hbm/handler/guncfg/Gun5mmFactory.java | 7 + .../hbm/handler/guncfg/Gun762mmFactory.java | 9 + .../com/hbm/handler/guncfg/Gun9mmFactory.java | 11 + .../hbm/handler/guncfg/GunCannonFactory.java | 25 +- .../com/hbm/handler/guncfg/GunDGKFactory.java | 7 + .../hbm/handler/guncfg/GunGrenadeFactory.java | 10 + .../hbm/handler/guncfg/GunOSIPRFactory.java | 91 +- .../com/hbm/interfaces/IByteSerializable.java | 19 + .../com/hbm/interfaces/INBTSerializable.java | 16 + .../java/com/hbm/items/tool/ItemWandD.java | 11 +- .../com/hbm/items/weapon/ItemGunBase.java | 34 +- src/main/java/com/hbm/main/ClientProxy.java | 12 +- .../java/com/hbm/main/ResourceManager.java | 6 + .../com/hbm/particle/ParticleSpentCasing.java | 165 ++- .../com/hbm/particle/SpentCasingConfig.java | 271 +++-- .../particle/SpentCasingConfigBuilder.java | 341 +++++-- .../entity/effect/RenderCasingTest.java | 56 + .../render/item/weapon/ItemRenderBenelli.java | 14 +- .../item/weapon/ItemRenderLunaticSniper.java | 8 +- .../turret/TileEntityTurretArty.java | 37 +- .../turret/TileEntityTurretBaseArtillery.java | 2 +- .../turret/TileEntityTurretBaseNT.java | 36 + .../turret/TileEntityTurretBrandon.java | 14 + .../turret/TileEntityTurretChekhov.java | 37 +- .../turret/TileEntityTurretFriendly.java | 10 +- .../turret/TileEntityTurretFritz.java | 13 + .../turret/TileEntityTurretHIMARS.java | 13 + .../turret/TileEntityTurretHoward.java | 18 +- .../turret/TileEntityTurretJeremy.java | 14 + .../turret/TileEntityTurretMaxwell.java | 15 +- .../turret/TileEntityTurretRichard.java | 13 + .../turret/TileEntityTurretTauon.java | 15 +- src/main/java/com/hbm/util/Quaternion.java | 302 ++++++ .../assets/hbm/models/effect/casings.mtl | 13 + .../assets/hbm/models/effect/casings.obj | 965 ++++++++++++++++++ .../hbm/textures/particle/casing_ar2.png | Bin 0 -> 625 bytes .../hbm/textures/particle/casing_tex.png | Bin 0 -> 10168 bytes 51 files changed, 2602 insertions(+), 340 deletions(-) create mode 100644 src/main/java/com/hbm/interfaces/IByteSerializable.java create mode 100644 src/main/java/com/hbm/interfaces/INBTSerializable.java create mode 100644 src/main/java/com/hbm/render/entity/effect/RenderCasingTest.java create mode 100644 src/main/java/com/hbm/util/Quaternion.java create mode 100644 src/main/resources/assets/hbm/models/effect/casings.mtl create mode 100644 src/main/resources/assets/hbm/models/effect/casings.obj create mode 100644 src/main/resources/assets/hbm/textures/particle/casing_ar2.png create mode 100644 src/main/resources/assets/hbm/textures/particle/casing_tex.png diff --git a/src/main/java/com/hbm/calc/EasyLocation.java b/src/main/java/com/hbm/calc/EasyLocation.java index c22e6b484..6f0d31d38 100644 --- a/src/main/java/com/hbm/calc/EasyLocation.java +++ b/src/main/java/com/hbm/calc/EasyLocation.java @@ -6,18 +6,21 @@ import java.util.Optional; import javax.annotation.CheckForNull; +import com.hbm.interfaces.IByteSerializable; import com.hbm.interfaces.ILocationProvider; +import com.hbm.interfaces.INBTSerializable; import com.hbm.main.DeserializationException; import api.hbm.serialization.ISerializable; import api.hbm.serialization.SerializationRegistry; import io.netty.buffer.ByteBuf; import net.minecraft.entity.Entity; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Vec3; import net.minecraft.world.World; -public class EasyLocation implements Cloneable, Comparable, ISerializable, ILocationProvider +public class EasyLocation implements Cloneable, Comparable, ISerializable, IByteSerializable, INBTSerializable, ILocationProvider { /** * @@ -31,13 +34,26 @@ public class EasyLocation implements Cloneable, Comparable, ISeria { SerializationRegistry.register(EasyLocation.class, EasyLocation::new); } + + /** + * Returns a new {@code EasyLocation} object with all coordinates set to 0. + * @return A unique {@code EasyLocation} object at position (0, 0, 0). + */ + public static EasyLocation getZeroLocation() + { + return ZERO_LOCATION.clone(); + } + public EasyLocation(ILocationProvider locationProvider) { posX = locationProvider.posX(); posY = locationProvider.posY(); posZ = locationProvider.posZ(); if (locationProvider.hasWorld()) + { world = Optional.of(locationProvider.getWorld()); + dimID = locationProvider.getWorld().provider.dimensionId; + } } public EasyLocation(double x, double y, double z) { @@ -272,7 +288,7 @@ public class EasyLocation implements Cloneable, Comparable, ISeria final double myDist = ILocationProvider.distance(this, ZERO_LOCATION); if (testDist == myDist) return 0; - return myDist < testDist ? 1 : -1; + return myDist > testDist ? 1 : -1; } @Override @@ -310,4 +326,44 @@ public class EasyLocation implements Cloneable, Comparable, ISeria { return world.get(); } + + @Override + public void writeToNBT(NBTTagCompound nbt) + { + nbt.setDouble("posX", posX); + nbt.setDouble("posY", posY); + nbt.setDouble("posZ", posZ); + nbt.setInteger("dimID", dimID); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) + { + posX = nbt.getDouble("posX"); + posY = nbt.getDouble("posY"); + posZ = nbt.getDouble("posZ"); + dimID = nbt.getInteger("dimID"); + } + + @Override + public void writeToBytes(ByteBuf buf) + { + buf.writeBytes(serialize()); + } + + @Override + public void readFromBytes(byte[] bytes) throws DeserializationException + { + try + { + final ByteBuf buf = allocCopy.apply(bytes); + posX = buf.readDouble(); + posY = buf.readDouble(); + posZ = buf.readDouble(); + dimID = buf.readInt(); + } catch (Exception e) + { + throw new DeserializationException(e); + } + } } \ No newline at end of file diff --git a/src/main/java/com/hbm/entity/projectile/EntityCombineBallNT.java b/src/main/java/com/hbm/entity/projectile/EntityCombineBallNT.java index aa85c6fa6..cebd81411 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityCombineBallNT.java +++ b/src/main/java/com/hbm/entity/projectile/EntityCombineBallNT.java @@ -11,7 +11,7 @@ public class EntityCombineBallNT extends EntityBulletBase super(world, config, shooter); overrideDamage = 1000; } - + @Override public void setDead() { diff --git a/src/main/java/com/hbm/handler/BulletConfiguration.java b/src/main/java/com/hbm/handler/BulletConfiguration.java index 72037b14f..7acc16ac6 100644 --- a/src/main/java/com/hbm/handler/BulletConfiguration.java +++ b/src/main/java/com/hbm/handler/BulletConfiguration.java @@ -88,7 +88,7 @@ public class BulletConfiguration implements Cloneable { /**The function that handles lost penetration over distance**/ @Nonnull public Optional modFunction = Optional.of(DEFAULT_FUNCTION); - + //whether or not the bullet should penetrate mobs public boolean doesPenetrate; //whether or not the bullet should phase through blocks diff --git a/src/main/java/com/hbm/handler/GunConfiguration.java b/src/main/java/com/hbm/handler/GunConfiguration.java index 0ea58fb3e..e41d7a1fe 100644 --- a/src/main/java/com/hbm/handler/GunConfiguration.java +++ b/src/main/java/com/hbm/handler/GunConfiguration.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import javax.annotation.Nonnull; + import com.hbm.lib.HbmCollection.EnumGunManufacturer; import com.hbm.main.MainRegistry; import com.hbm.particle.SpentCasingConfig; @@ -94,8 +96,9 @@ public class GunConfiguration implements Cloneable { public Crosshair crosshair; /**Controller for spent casings. If {@code Optional.empty()} it will not eject casings.**/ + @Nonnull public Optional casingConfig = Optional.empty(); - + public static final int MODE_NORMAL = 0; public static final int MODE_RELEASE = 1; public static final int MODE_BOTH = 1; diff --git a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java index 8a4e8424a..a22c378fb 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java @@ -1,11 +1,17 @@ package com.hbm.handler.guncfg; +import java.util.Optional; + +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.potion.HbmPotion; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationKeyframe; @@ -15,9 +21,33 @@ import com.hbm.render.util.RenderScreenOverlay.Crosshair; import net.minecraft.entity.EntityLivingBase; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.Vec3; public class Gun12GaugeFactory { + private static final SpentCasingConfigBuilder CASING_12G_BUILDER = new SpentCasingConfigBuilder("", CasingType.SHOTGUN, false) + .setScaleX(1.5f).setScaleY(1.5f).setScaleZ(1.5f); + static final SpentCasingConfig + CASING_SPAS = CASING_12G_BUILDER.setRegistryName("spas12").setPosOffset(new EasyLocation(1.5, 0, 0)) + .setInitialMotion(Vec3.createVectorHelper(-0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setSmokeChance(0).setDelay(10) + .build(), + + CASING_SPAS_ALT = CASING_12G_BUILDER.setRegistryName("spas12alt").setCasingAmount(2) + .build(), + + CASING_BENELLI = CASING_12G_BUILDER.setRegistryName("benelli").setCasingAmount(1).setDelay(0) + .setInitialMotion(Vec3.createVectorHelper(-0.3, 1.1, 0)) + .build(), + + CASING_UBOINIK = CASING_12G_BUILDER.setRegistryName("uboinik").setOverrideColor(true) + .setBlueOverride(255) + .build(), + + CASING_SSG = CASING_12G_BUILDER.setRegistryName("ssg").setBlueOverride(0).setRedOverride(255).setCasingAmount(2) + .setPosOffset(new EasyLocation(-2, 0, 0)).setInitialMotion(Vec3.createVectorHelper(0.2, 0, -0.2)) + .build(); + public static GunConfiguration getSpas12Config() { GunConfiguration config = new GunConfiguration(); @@ -59,6 +89,8 @@ public class Gun12GaugeFactory { ) ); + config.casingConfig = Optional.of(CASING_SPAS); + return config; } @@ -78,6 +110,8 @@ public class Gun12GaugeFactory { config.config = HbmCollection.twelveGauge; + + config.casingConfig = Optional.of(CASING_SPAS_ALT); return config; } @@ -105,6 +139,8 @@ public class Gun12GaugeFactory { config.config = HbmCollection.twelveGauge; + config.casingConfig = Optional.of(CASING_UBOINIK); + return config; } @@ -156,6 +192,8 @@ public class Gun12GaugeFactory { config.config = HbmCollection.twelveGauge; + config.casingConfig = Optional.of(CASING_SSG); + return config; } @@ -230,6 +268,8 @@ public class Gun12GaugeFactory { config.advFuncLore.add("user to quickly exchange the various assembly groups (barrel, buttstock, forend, etc.) without the use"); config.advFuncLore.add("of additional tools."); + config.casingConfig = Optional.of(CASING_BENELLI); + return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java index 719c35a09..135254b75 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java @@ -1,7 +1,9 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; @@ -9,6 +11,9 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationKeyframe; import com.hbm.render.anim.BusAnimationSequence; @@ -17,9 +22,18 @@ import com.hbm.render.util.RenderScreenOverlay.Crosshair; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.Vec3; public class Gun20GaugeFactory { + private static final SpentCasingConfigBuilder CASING_20G_BUILDER = new SpentCasingConfigBuilder("20g_lever", CasingType.SHOTGUN, false); + static final SpentCasingConfig + CASING_20G_LEVER = CASING_20G_BUILDER + .setPosOffset(new EasyLocation(1.5, 0, 0)) + .setInitialMotion(Vec3.createVectorHelper(-0.1, 0.95, 0)).setPitchFactor(0.05f).setYawFactor(0.01f) + .setSmokeChance(0) + .build(); + public static GunConfiguration getShotgunConfig() { GunConfiguration config = new GunConfiguration(); @@ -53,6 +67,8 @@ public class Gun20GaugeFactory { config.config = HbmCollection.twentyGauge; + config.casingConfig = Optional.of(CASING_20G_LEVER); + return config; } @@ -69,6 +85,8 @@ public class Gun20GaugeFactory { config.manufacturer = EnumGunManufacturer.WINCHESTER; config.config = HbmCollection.twentyGauge; + + config.casingConfig = Optional.of(CASING_20G_LEVER); return config; } @@ -86,6 +104,8 @@ public class Gun20GaugeFactory { config.manufacturer = EnumGunManufacturer.WINCHESTER; config.config = HbmCollection.twentyGauge; + + config.casingConfig = Optional.of(CASING_20G_LEVER); return config; } @@ -121,6 +141,8 @@ public class Gun20GaugeFactory { ); config.config = HbmCollection.twentyGauge; + + config.casingConfig = Optional.of(CASING_20G_LEVER); return config; } @@ -157,6 +179,8 @@ public class Gun20GaugeFactory { config.config = HbmCollection.twentyGauge; + + config.casingConfig = Optional.of(CASING_20G_LEVER); return config; } @@ -202,6 +226,8 @@ public class Gun20GaugeFactory { config.config.add(BulletConfigSyncingUtil.G20_SHOCK_FIRE); config.config.add(BulletConfigSyncingUtil.G20_WITHER_FIRE); config.config.add(BulletConfigSyncingUtil.G20_SLEEK); + + config.casingConfig = Optional.of(CASING_20G_LEVER); return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java index 83f7e660a..57787fc5a 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java @@ -1,17 +1,29 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.render.util.RenderScreenOverlay.Crosshair; +import net.minecraft.util.Vec3; + public class Gun22LRFactory { + static final SpentCasingConfig CASING_22LR = new SpentCasingConfigBuilder("22lr", CasingType.BRASS_STRAIGHT_WALL, false) + .setSmokeChance(20).setScaleX(0.4f).setScaleY(0.4f).setScaleZ(0.4f) + .setInitialMotion(Vec3.createVectorHelper(-0.3, 1, 0)).setPitchFactor(0.03f).setYawFactor(0.01f).setPosOffset(new EasyLocation(1.5, 0, 0)) + .build(); + public static GunConfiguration getUziConfig() { GunConfiguration config = new GunConfiguration(); @@ -54,6 +66,8 @@ public class Gun22LRFactory { config.advFuncLore.add("to be moved far back into the receiver and the magazine to be housed in the pistol grip, allowing for a heavier,"); config.advFuncLore.add("slower-firing bolt in a shorter, better-balanced weapon."); + config.casingConfig = Optional.of(CASING_22LR); + return config; } @@ -70,6 +84,8 @@ public class Gun22LRFactory { config.config.add(BulletConfigSyncingUtil.LR22_NORMAL_FIRE); config.config.add(BulletConfigSyncingUtil.LR22_AP_FIRE); config.config.add(BulletConfigSyncingUtil.CHL_LR22_FIRE); + + config.casingConfig = Optional.of(CASING_22LR); return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java index 3817e3ee1..9ddc7721f 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java @@ -1,7 +1,9 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; @@ -9,6 +11,9 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection.EnumGunManufacturer; import com.hbm.lib.ModDamageSource; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfigBuilder; +import com.hbm.particle.SpentCasingConfig.CasingType; import com.hbm.potion.HbmPotion; import com.hbm.render.util.RenderScreenOverlay.Crosshair; @@ -16,6 +21,15 @@ import net.minecraft.potion.PotionEffect; public class Gun357MagnumFactory { + private static final SpentCasingConfigBuilder CASING_357_BUILDER = new SpentCasingConfigBuilder("357", CasingType.BRASS_STRAIGHT_WALL, false) + .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.1, 0)).setSmokeChance(6).setAfterReload(true); + static final SpentCasingConfig + CASING_357 = CASING_357_BUILDER.build(), + + CASING_357_SA = CASING_357_BUILDER.setRegistryName("357Schrabidium").setSmokeChance(0).setOverrideColor(true) + .setRedOverride(2).setGreenOverride(207).setBlueOverride(207) + .build(); + public static GunConfiguration getBaseConfig() { GunConfiguration config = new GunConfiguration(); @@ -34,6 +48,8 @@ public class Gun357MagnumFactory { config.firingSound = "hbm:weapon.revolverShoot"; config.reloadSoundEnd = false; + config.casingConfig = Optional.of(CASING_357); + return config; } @@ -149,6 +165,8 @@ public class Gun357MagnumFactory { config.config = new ArrayList(); config.config.add(BulletConfigSyncingUtil.SCHRABIDIUM_REVOLVER); config.config.add(BulletConfigSyncingUtil.DESH_REVOLVER); + + config.casingConfig = Optional.of(CASING_357_SA); return config; } @@ -184,6 +202,8 @@ public class Gun357MagnumFactory { config.config = new ArrayList(); config.config.add(BulletConfigSyncingUtil.NIGHT2_REVOLVER); + config.casingConfig = Optional.of(Gun20GaugeFactory.CASING_20G_LEVER); + return config; } @@ -210,7 +230,7 @@ public class Gun357MagnumFactory { public static GunConfiguration getColtPythonConfig() { - GunConfiguration config = getBaseConfig().clone(); + GunConfiguration config = getBaseConfig(); config.durability = 8000; config.name = "cPython"; diff --git a/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java index 796f3f011..4c184270b 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java @@ -1,7 +1,9 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.entity.particle.EntityBSmokeFX; import com.hbm.entity.projectile.EntityBoxcar; import com.hbm.entity.projectile.EntityBuilding; @@ -15,6 +17,9 @@ import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfigBuilder; +import com.hbm.particle.SpentCasingConfig.CasingType; import com.hbm.potion.HbmPotion; import com.hbm.render.util.RenderScreenOverlay.Crosshair; @@ -24,6 +29,10 @@ import net.minecraft.potion.PotionEffect; public class Gun44MagnumFactory { + static final SpentCasingConfig CASING_44 = new SpentCasingConfigBuilder("44Magnum", CasingType.BRASS_STRAIGHT_WALL, false) + .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.1, 0)).setSmokeChance(6) + .setAfterReload(true).setScaleX(1.25f).build(); + public static GunConfiguration getBaseConfig() { GunConfiguration config = new GunConfiguration(); @@ -44,6 +53,8 @@ public class Gun44MagnumFactory { config.config.addAll(HbmCollection.fourtyFourMagBasic); + config.casingConfig = Optional.of(CASING_44); + return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java index 71e657cf4..ffe301bef 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java @@ -1,22 +1,39 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationKeyframe; import com.hbm.render.anim.BusAnimationSequence; import com.hbm.render.anim.HbmAnimations.AnimType; import com.hbm.render.util.RenderScreenOverlay.Crosshair; +import net.minecraft.util.Vec3; + public class Gun45ACPFactory { + private static final SpentCasingConfigBuilder CASING_45_BUILDER = new SpentCasingConfigBuilder("45acp", CasingType.BRASS_STRAIGHT_WALL, false) + .setSmokeChance(8).setInitialMotion(Vec3.createVectorHelper(-0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(1.5, 0, 0)).setScaleZ(0.75f); + static final SpentCasingConfig + CASING_45 = CASING_45_BUILDER.build(), + + CASING_45_UAC = CASING_45_BUILDER.setRegistryName("45acp_UAC_Pistol") + .setInitialMotion(Vec3.createVectorHelper(0.3, 0.9, 0)).setPosOffset(new EasyLocation(1.5, -1, 0)) + .build(); + public static GunConfiguration getThompsonConfig() { GunConfiguration config = new GunConfiguration(); @@ -48,6 +65,8 @@ public class Gun45ACPFactory config.advLore.add("Thompson in 1918. It was originally designed to break the stalemate of trench warfare of World"); config.advLore.add("War I, but was not finished until after the war ended."); + config.casingConfig = Optional.of(CASING_45); + return config; } @@ -85,6 +104,8 @@ public class Gun45ACPFactory .addKeyframe(new BusAnimationKeyframe(15, 0, 0, 10)) .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 40)))); + config.casingConfig = Optional.of(CASING_45_UAC); + return config; } @@ -114,6 +135,8 @@ public class Gun45ACPFactory config.config.addAll(HbmCollection.fourtyFiveACP); + config.casingConfig = Optional.of(CASING_45); + return config; } public static BulletConfiguration get45AutoConfig() diff --git a/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java index ba7568da4..9b2a769ed 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java @@ -2,7 +2,9 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.entity.projectile.EntityBulletBase; import com.hbm.explosion.ExplosionLarge; import com.hbm.explosion.ExplosionNT; @@ -18,6 +20,9 @@ import com.hbm.lib.HbmCollection.EnumGunManufacturer; import com.hbm.lib.ModDamageSource; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.potion.HbmPotion; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationKeyframe; @@ -31,10 +36,16 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.Vec3; import net.minecraftforge.common.IExtendedEntityProperties; public class Gun4GaugeFactory { + static final SpentCasingConfig CASING_4G = new SpentCasingConfigBuilder("4g", CasingType.SHOTGUN, false) + .setSmokeChance(0).setPosOffset(new EasyLocation(1.5, 0, 0)) + .setInitialMotion(Vec3.createVectorHelper(-0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setScaleX(2.5f).setScaleY(2.5f).setScaleZ(2.5f).build(); + private static GunConfiguration getShotgunConfig() { GunConfiguration config = new GunConfiguration(); @@ -52,6 +63,8 @@ public class Gun4GaugeFactory { config.crosshair = Crosshair.L_CIRCLE; config.reloadSound = GunConfiguration.RSOUND_SHOTGUN; + config.casingConfig = Optional.of(CASING_4G); + return config; } @@ -123,7 +136,6 @@ public class Gun4GaugeFactory { return config; } static byte i = 0; - static final BulletConfiguration stock = get4GaugeConfig(); public static BulletConfiguration get4GaugeConfig() { BulletConfiguration bullet = BulletConfigFactory.standardBuckshotConfig(); @@ -339,7 +351,7 @@ public class Gun4GaugeFactory { public static BulletConfiguration get4GaugeClawConfig() { - BulletConfiguration bullet = stock.clone(); + BulletConfiguration bullet = BulletConfigFactory.standardBuckshotConfig(); bullet.ammo = new ComparableStack(ModItems.ammo_4gauge, 1, i++); bullet.dmgMin = 6; @@ -373,7 +385,7 @@ public class Gun4GaugeFactory { public static BulletConfiguration get4GaugeVampireConfig() { - BulletConfiguration bullet = stock.clone(); + BulletConfiguration bullet = BulletConfigFactory.standardBuckshotConfig(); bullet.ammo = new ComparableStack(ModItems.ammo_4gauge, 1, i++); bullet.dmgMin = 5; @@ -407,7 +419,7 @@ public class Gun4GaugeFactory { public static BulletConfiguration get4GaugeVoidConfig() { - BulletConfiguration bullet = stock.clone(); + BulletConfiguration bullet = BulletConfigFactory.standardBuckshotConfig(); bullet.ammo = new ComparableStack(ModItems.ammo_4gauge, 1, i++); bullet.dmgMin = 6; diff --git a/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java index 4f5783430..c13ebb40e 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java @@ -1,15 +1,27 @@ package com.hbm.handler.guncfg; +import java.util.Optional; + +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.render.util.RenderScreenOverlay.Crosshair; +import net.minecraft.util.Vec3; + public class Gun50AEFactory { + static final SpentCasingConfig CASING_50AE = new SpentCasingConfigBuilder("50ae", CasingType.BRASS_STRAIGHT_WALL, false) + .setSmokeChance(4).setInitialMotion(Vec3.createVectorHelper(-0.3, 0.9, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(1.5, 0, 0)).setScaleZ(1.5f).build(); + public static GunConfiguration getBaseConfig() { GunConfiguration config = new GunConfiguration(); @@ -28,6 +40,8 @@ public class Gun50AEFactory { config.firingSound = "hbm:weapon.deagleShoot"; config.reloadSoundEnd = false; + config.casingConfig = Optional.of(CASING_50AE); + return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java index 9d0ac4458..cb87223f4 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java @@ -1,7 +1,9 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.entity.projectile.EntityBulletBase; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; @@ -12,6 +14,9 @@ import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.potion.HbmPotion; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationKeyframe; @@ -26,9 +31,22 @@ import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.Vec3; public class Gun50BMGFactory { + public static final SpentCasingConfig + CONFIG_50BMG = new SpentCasingConfigBuilder("50bmg", CasingType.BRASS_BOTTLENECK, false) + .setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-0.4, 1, 0)).setScaleX(3).setScaleY(3).setScaleZ(3) + .setPosOffset(new EasyLocation(0.2, 0.2, -0.08)).setPitchFactor(0.1f).setYawFactor(0.01f) + .build(), + + CONFIG_LUNA = new SpentCasingConfigBuilder("luna", CasingType.BRASS_BOTTLENECK, true) + .setScaleX(4).setScaleY(4).setScaleZ(4).setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-2, 0, 0)) + .setPosOffset(new EasyLocation(0.5, 0.2, 0.08)).setRedOverride(11).setGreenOverride(97).setBlueOverride(109) + .setYawFactor(0.02f) + .build(); + public static GunConfiguration getCalamityConfig() { GunConfiguration config = new GunConfiguration(); @@ -141,6 +159,8 @@ public class Gun50BMGFactory { // .addKeyframe(new BusAnimationKeyframe(-20, -2, 0.75, 400))//Just plop that thing in there // .addKeyframe(new BusAnimationKeyframe(20, -2, 0.75, 75))));//Wait for the slide to close + config.casingConfig = Optional.of(CONFIG_LUNA); + return config; } @@ -155,6 +175,7 @@ public class Gun50BMGFactory { bullet.dmgMin = 450F; bullet.penetration = 10000; bullet.penetrationModifier = 1; + bullet.headshotMult = 2.5f; bullet.wear = 2000; bullet.velocity = 100; bullet.doesPenetrate = true; @@ -219,6 +240,8 @@ public class Gun50BMGFactory { config.config.addAll(HbmCollection.fiftyBMG); config.config.addAll(HbmCollection.fiftyBMGFlechette); + config.casingConfig = Optional.of(CONFIG_50BMG); + return config; } @@ -257,6 +280,8 @@ public class Gun50BMGFactory { config.advFuncLore.add("gun on aircraft before and during World War II, as on the early versions of the Curtiss P-40 fighter."); config.advFuncLore.add("The M2 is a scaled-up version of John Browning's M1917 .30 caliber machine gun. "); + config.casingConfig = Optional.of(CONFIG_50BMG); + return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java index cc9f467ad..12265a75d 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java @@ -1,7 +1,9 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.entity.projectile.EntityBulletBase; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; @@ -12,6 +14,9 @@ import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.particle.SpentCasingConfigBuilder; import com.hbm.potion.HbmPotion; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationKeyframe; @@ -22,9 +27,15 @@ import com.hbm.render.util.RenderScreenOverlay.Crosshair; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.Vec3; public class Gun556mmFactory { + static final SpentCasingConfig CONFIG_556 = new SpentCasingConfigBuilder("556", CasingType.BRASS_BOTTLENECK, false) + .setSmokeChance(4).setInitialMotion(Vec3.createVectorHelper(-0.3, 1, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(1.5, 0, 0)).setScaleZ(1.5f) + .build(); + public static GunConfiguration getEuphieConfig() { GunConfiguration config = new GunConfiguration(); @@ -61,6 +72,8 @@ public class Gun556mmFactory { config.config.add(BulletConfigSyncingUtil.CHL_R556); config.config.add(BulletConfigSyncingUtil.R556_SLEEK); config.config.add(BulletConfigSyncingUtil.R556_K); + + config.casingConfig = Optional.of(CONFIG_556); return config; } @@ -101,6 +114,8 @@ public class Gun556mmFactory { config.config = new ArrayList(); config.config.addAll(HbmCollection.NATOFlechette); + + config.casingConfig = Optional.of(CONFIG_556); return config; } @@ -127,6 +142,8 @@ public class Gun556mmFactory { config.config = new ArrayList(); config.config.addAll(HbmCollection.grenade); + config.casingConfig = Optional.of(GunGrenadeFactory.CASING_40); + return config; } @@ -160,6 +177,8 @@ public class Gun556mmFactory { .addKeyframe(new BusAnimationKeyframe(-0.35, 0, 0, 30)) .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 30)))); + config.casingConfig = Optional.of(CONFIG_556); + return config; } @@ -191,10 +210,13 @@ public class Gun556mmFactory { .addKeyframe(new BusAnimationKeyframe(-0.35, 0, 0, 30)) .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 30)))); + config.casingConfig = Optional.of(CONFIG_556); + return config; } static final float inaccuracy = 1.15F; + public static BulletConfiguration get556Config() { BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); @@ -216,7 +238,7 @@ public class Gun556mmFactory { bullet.dmgMin = 250; bullet.dmgMax = 320; bullet.spread = 0.0F; - + return bullet; } @@ -244,7 +266,7 @@ public class Gun556mmFactory { PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, projectile.posX, projectile.posY, projectile.posZ), new TargetPoint(projectile.dimension, projectile.posX, projectile.posY, projectile.posZ, 50)); }; - + return bullet; } @@ -258,7 +280,7 @@ public class Gun556mmFactory { bullet.penetration *= 1.5; bullet.wear = 15; bullet.leadChance = 10; - + return bullet; } @@ -272,7 +294,7 @@ public class Gun556mmFactory { bullet.penetration *= 2; bullet.wear = 25; bullet.leadChance = 50; - + return bullet; } @@ -286,7 +308,7 @@ public class Gun556mmFactory { bullet.penetration *= 2.5; bullet.wear = 25; bullet.leadChance = 100; - + return bullet; } @@ -327,7 +349,7 @@ public class Gun556mmFactory { meteor.shooter = projectile.shooter; projectile.worldObj.spawnEntityInWorld(meteor); }; - + return bullet; } @@ -354,7 +376,7 @@ public class Gun556mmFactory { bullet.wear = 15; bullet.style = BulletConfiguration.STYLE_FLECHETTE; bullet.doesPenetrate = false; - + return bullet; } @@ -364,7 +386,7 @@ public class Gun556mmFactory { bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 9); bullet.incendiary = 5; - + return bullet; } @@ -390,7 +412,7 @@ public class Gun556mmFactory { PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, projectile.posX, projectile.posY, projectile.posZ), new TargetPoint(projectile.dimension, projectile.posX, projectile.posY, projectile.posZ, 50)); }; - + return bullet; } @@ -405,7 +427,7 @@ public class Gun556mmFactory { bullet.wear = 25; bullet.leadChance = 50; bullet.doesPenetrate = true; - + return bullet; } @@ -446,7 +468,7 @@ public class Gun556mmFactory { meteor.shooter = projectile.shooter; projectile.worldObj.spawnEntityInWorld(meteor); }; - + return bullet; } @@ -459,7 +481,7 @@ public class Gun556mmFactory { bullet.dmgMax = 0; bullet.penetration = 0; bullet.maxAge = 0; - + return bullet; } } \ No newline at end of file diff --git a/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java index c5a0b866b..7d162bcd2 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java @@ -1,6 +1,7 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; @@ -9,10 +10,14 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; import com.hbm.render.util.RenderScreenOverlay.Crosshair; public class Gun5mmFactory { + public static final SpentCasingConfig CASING_5MM = Gun22LRFactory.CASING_22LR.toBuilder("5mm").setCasingAmount(5).build(), + CASING_5MM_TURRET = CASING_5MM.toBuilder("5mmTurret").setCasingAmount(1).build(); + public static GunConfiguration getMinigunConfig() { GunConfiguration config = new GunConfiguration(); @@ -32,6 +37,8 @@ public class Gun5mmFactory { config.config = HbmCollection.fiveMM; + config.casingConfig = Optional.of(CASING_5MM); + return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java index 50e370d68..a9d3dce92 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java @@ -1,6 +1,7 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; @@ -8,6 +9,7 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; import com.hbm.potion.HbmPotion; import com.hbm.render.util.RenderScreenOverlay.Crosshair; @@ -16,6 +18,9 @@ import net.minecraft.potion.PotionEffect; public class Gun762mmFactory { + static final SpentCasingConfig CASING_762_NATO = Gun556mmFactory.CONFIG_556.toBuilder("762NATO").setSmokeChance(2).setScaleX(2) + .setScaleZ(2.5f).build(); + public static GunConfiguration getUACDMRConfig() { final GunConfiguration config = new GunConfiguration(); @@ -42,6 +47,8 @@ public class Gun762mmFactory config.config.addAll(HbmCollection.threeZeroEight); + config.casingConfig = Optional.of(CASING_762_NATO); + return config; } @@ -118,6 +125,8 @@ public class Gun762mmFactory config.advFuncLore.add("extra ammunition, and reloads and spots targets for the gunner. The ammunition bearer carries additional ammunition"); config.advFuncLore.add("and the tripod with associated traversing and elevation mechanism, if issued, and fetches more ammunition as needed"); config.advFuncLore.add("during firing."); + + config.casingConfig = Optional.of(CASING_762_NATO); return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java index 0d2c60532..fff5dc221 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java @@ -1,6 +1,7 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; @@ -9,6 +10,7 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.BusAnimationKeyframe; import com.hbm.render.anim.BusAnimationSequence; @@ -17,6 +19,9 @@ import com.hbm.render.util.RenderScreenOverlay.Crosshair; public class Gun9mmFactory { + static final SpentCasingConfig CASING_9 = Gun45ACPFactory.CASING_45.toBuilder("9") + .setScaleX(1).setScaleY(1).setScaleZ(0.6f).build(); + public static GunConfiguration getMP40Config() { GunConfiguration config = new GunConfiguration(); @@ -46,6 +51,8 @@ public class Gun9mmFactory { config.config.add(BulletConfigSyncingUtil.CHL_P9); config.config.add(BulletConfigSyncingUtil.P9_ROCKET); + config.casingConfig = Optional.of(CASING_9); + return config; } @@ -77,6 +84,8 @@ public class Gun9mmFactory { config.config.add(BulletConfigSyncingUtil.P9_DU); config.config.add(BulletConfigSyncingUtil.CHL_P9); config.config.add(BulletConfigSyncingUtil.P9_ROCKET); + + config.casingConfig = Optional.of(CASING_9); return config; } @@ -110,6 +119,8 @@ public class Gun9mmFactory { .addBus("RECOIL", new BusAnimationSequence() .addKeyframe(new BusAnimationKeyframe(0, 0, -0.1, 30)) .addKeyframe(new BusAnimationKeyframe(0, 0, 0, 30)))); + + config.casingConfig = Optional.of(CASING_9); return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java b/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java index 0e667779f..bbf7f64da 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java @@ -1,13 +1,30 @@ package com.hbm.handler.guncfg; +import com.hbm.calc.EasyLocation; import com.hbm.config.BombConfig; import com.hbm.entity.effect.EntityNukeCloudSmall; import com.hbm.entity.logic.EntityNukeExplosionMK4; import com.hbm.handler.BulletConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfigBuilder; +import com.hbm.particle.SpentCasingConfig.CasingType; + +import net.minecraft.util.Vec3; public class GunCannonFactory { + + private static final SpentCasingConfigBuilder CASING_CANNON_BUILDER = new SpentCasingConfigBuilder("240", CasingType.BRASS_BOTTLENECK, false) + .setInitialMotion(Vec3.createVectorHelper(0, 0.2, -1)).setPosOffset(new EasyLocation(0, 1.75, 0)).setSmokeChance(0) + .setScaleX(10).setScaleY(10).setScaleZ(10); + public static final SpentCasingConfig + CASING_240 = CASING_CANNON_BUILDER.build(), + + CASING_16IN = CASING_CANNON_BUILDER.setRegistryName("16inch").setInitialMotion(Vec3.createVectorHelper(0, 1, -1.75)) + .setScaleX(20).setScaleY(20).setScaleZ(25) + .build(); + static final int stockPen = 10000; static byte i = 0; public static BulletConfiguration getShellConfig() { @@ -17,8 +34,8 @@ public class GunCannonFactory { bullet.ammo = new ComparableStack(ModItems.ammo_shell, 1, i++); bullet.dmgMin = 225; bullet.dmgMax = 235; - bullet.penetration = stockPen; - bullet.explosive = 40F; + bullet.penetration = 40; + bullet.explosive = 20F; bullet.blockDamage = false; return bullet; @@ -31,8 +48,8 @@ public class GunCannonFactory { bullet.ammo = new ComparableStack(ModItems.ammo_shell, 1, i++); bullet.dmgMin = 235; bullet.dmgMax = 245; - bullet.penetration = stockPen; - bullet.explosive = 40F; + bullet.penetration = 50; + bullet.explosive = 25F; bullet.blockDamage = true; return bullet; diff --git a/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java b/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java index aa61cff4e..931578c99 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java @@ -3,9 +3,16 @@ package com.hbm.handler.guncfg; import com.hbm.handler.BulletConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; +import com.hbm.particle.SpentCasingConfig; + +import net.minecraft.util.Vec3; public class GunDGKFactory { + public static final SpentCasingConfig CASING_DGK = Gun50BMGFactory.CONFIG_LUNA.toBuilder("dgk") + .setInitialMotion(Vec3.createVectorHelper(1, 1, 0)).setPosOffset(null).setOverrideColor(false) + .build(); + public static BulletConfiguration getDGKConfig() { BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); diff --git a/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java b/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java index e8bd2a05c..e49d86fc9 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java @@ -1,6 +1,7 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Optional; import com.hbm.config.BombConfig; import com.hbm.entity.effect.EntityCloudTom; @@ -11,10 +12,17 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfigBuilder; +import com.hbm.particle.SpentCasingConfig.CasingType; import com.hbm.render.util.RenderScreenOverlay.Crosshair; public class GunGrenadeFactory { + static final SpentCasingConfig CASING_40 = new SpentCasingConfigBuilder("40", CasingType.BRASS_STRAIGHT_WALL, false) + .setSmokeChance(0).setScaleX(4).setAfterReload(true).setPitchFactor(0.02f).setYawFactor(0.03f) + .build(); + public static GunConfiguration getHK69Config() { GunConfiguration config = new GunConfiguration(); @@ -40,6 +48,8 @@ public class GunGrenadeFactory { config.config = new ArrayList(); config.config.addAll(HbmCollection.grenade); config.durability = 300; + + config.casingConfig = Optional.of(GunGrenadeFactory.CASING_40); return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java b/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java index e662b397d..5c1b849ae 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java @@ -1,24 +1,41 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; import com.hbm.blocks.generic.RedBarrel; +import com.hbm.calc.EasyLocation; +import com.hbm.entity.projectile.EntityBulletBase; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; +import com.hbm.interfaces.ILocationProvider; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.particle.SpentCasingConfigBuilder; +import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.lib.Library; import com.hbm.lib.ModDamageSource; import com.hbm.potion.HbmPotion; import com.hbm.render.util.RenderScreenOverlay.Crosshair; import net.minecraft.block.Block; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.Vec3; public class GunOSIPRFactory { + static final SpentCasingConfig CASING_AR2 = new SpentCasingConfigBuilder("ar2", CasingType.AR2, false) + .setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-0.15, 0.2, 0)).setPitchFactor(0.02f) + .setAfterReload(true).setPosOffset(new EasyLocation(3.5, 0, 0)).build(); + public static GunConfiguration getOSIPRConfig() { GunConfiguration config = new GunConfiguration(); @@ -44,6 +61,8 @@ public class GunOSIPRFactory { config.config = new ArrayList(); config.config.add(BulletConfigSyncingUtil.SPECIAL_OSIPR); + config.casingConfig = Optional.of(CASING_AR2); + return config; } @@ -151,37 +170,41 @@ public class GunOSIPRFactory { return bullet; } -// private static void tryRedirectBall(EntityBulletBase ball, EntityLivingBase lastHit) -// { -// if (!ball.worldObj.isRemote) -// { -// final ILocationProvider ballLoc = ILocationProvider.wrap(ball, false), targetLoc; -// final Vec3 newVector; -// final List entities = ball.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(ball.posX - 10, ball.posY - 10, ball.posZ - 10, ball.posX + 10, ball.posY + 10, ball.posZ + 10)); -// entities.remove(ball); -// entities.remove(ball.shooter); -// entities.remove(lastHit); -// entities.removeIf(e -> Library.isObstructed(ball.worldObj, ballLoc, ILocationProvider.wrap(e, false))); -// if (entities.isEmpty()) -// return; -// -// entities.sort(Comparator.comparing(e -> ILocationProvider.distance(ILocationProvider.wrap(e, false), ballLoc))); -// -// targetLoc = ILocationProvider.wrap(entities.get(0), false); -// newVector = ILocationProvider.makeVector(ballLoc, targetLoc).normalize(); -// -// System.out.println(ballLoc); -// System.out.println(targetLoc); -// System.out.println(newVector); -// System.out.println(Vec3.createVectorHelper(ball.motionX, ball.motionY, ball.motionZ)); -// -// final double total = ball.motionX + ball.motionY + ball.motionZ; -// -// ball.motionX = newVector.xCoord * total; -// ball.motionY = newVector.yCoord * total; -// ball.motionZ = newVector.zCoord * total; -// -// System.out.println(Vec3.createVectorHelper(ball.motionX, ball.motionY, ball.motionZ)); -// } -// } -} \ No newline at end of file + private static void tryRedirectBall(EntityBulletBase ball, EntityLivingBase lastHit) + { + if (!ball.worldObj.isRemote) + { + final ILocationProvider ballLoc = ILocationProvider.wrap(ball, false), targetLoc; + final Vec3 newVector; + final List entities = ball.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(ball.posX - 10, ball.posY - 10, ball.posZ - 10, ball.posX + 10, ball.posY + 10, ball.posZ + 10)); + entities.remove(ball); + entities.remove(ball.shooter); + entities.remove(lastHit); + entities.removeIf(e -> Library.isObstructed(ball.worldObj, ballLoc, ILocationProvider.wrap(e, false))); + if (entities.isEmpty()) + return; + + entities.sort(Comparator.comparing(e -> ILocationProvider.distance(ILocationProvider.wrap(e, false), ballLoc))); + + targetLoc = ILocationProvider.wrap(entities.get(0), false); + + System.out.println(ballLoc); + System.out.println(targetLoc); + System.out.println(Vec3.createVectorHelper(ball.motionX, ball.motionY, ball.motionZ)); + + final double oldMagnitude = Math.sqrt(ball.motionX * ball.motionX + ball.motionY * ball.motionY + ball.motionZ * ball.motionZ), newMagnitude; + newVector = Vec3.createVectorHelper( + targetLoc.posX() - ball.motionX, + targetLoc.posY() - ball.motionY, + targetLoc.posZ() - ball.motionZ + ); + newMagnitude = Math.sqrt(newVector.xCoord * newVector.xCoord + newVector.yCoord * newVector.yCoord + newVector.zCoord * newVector.zCoord); + + ball.motionX = newVector.xCoord * oldMagnitude / newMagnitude; + ball.motionY = newVector.yCoord * oldMagnitude / newMagnitude; + ball.motionZ = newVector.zCoord * oldMagnitude / newMagnitude; + + System.out.println(Vec3.createVectorHelper(ball.motionX, ball.motionY, ball.motionZ)); + } + } +} diff --git a/src/main/java/com/hbm/interfaces/IByteSerializable.java b/src/main/java/com/hbm/interfaces/IByteSerializable.java new file mode 100644 index 000000000..d23d7552b --- /dev/null +++ b/src/main/java/com/hbm/interfaces/IByteSerializable.java @@ -0,0 +1,19 @@ +package com.hbm.interfaces; + +import com.hbm.main.DeserializationException; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +public interface IByteSerializable +{ + public void writeToBytes(ByteBuf buf); + public void readFromBytes(byte[] bytes) throws DeserializationException; + + public default byte[] writeToBytes() + { + final ByteBuf buf = Unpooled.buffer(); + writeToBytes(buf); + return buf.array(); + } +} diff --git a/src/main/java/com/hbm/interfaces/INBTSerializable.java b/src/main/java/com/hbm/interfaces/INBTSerializable.java new file mode 100644 index 000000000..8dc9b42f7 --- /dev/null +++ b/src/main/java/com/hbm/interfaces/INBTSerializable.java @@ -0,0 +1,16 @@ +package com.hbm.interfaces; + +import net.minecraft.nbt.NBTTagCompound; + +public interface INBTSerializable +{ + public void writeToNBT(NBTTagCompound nbt); + public void readFromNBT(NBTTagCompound nbt); + + public default NBTTagCompound writeToNBT() + { + final NBTTagCompound nbt = new NBTTagCompound(); + writeToNBT(nbt); + return nbt; + } +} diff --git a/src/main/java/com/hbm/items/tool/ItemWandD.java b/src/main/java/com/hbm/items/tool/ItemWandD.java index 69fdac079..b0b95df35 100644 --- a/src/main/java/com/hbm/items/tool/ItemWandD.java +++ b/src/main/java/com/hbm/items/tool/ItemWandD.java @@ -2,26 +2,17 @@ package com.hbm.items.tool; import java.util.List; -import com.hbm.blocks.ModBlocks; -import com.hbm.entity.effect.EntityNukeTorex; -import com.hbm.entity.mob.siege.EntitySiegeTunneler; -import com.hbm.items.ModItems; -import com.hbm.items.special.ItemKitCustom; import com.hbm.lib.Library; import com.hbm.world.feature.OilSpot; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; public class ItemWandD extends Item { - + @Override public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { diff --git a/src/main/java/com/hbm/items/weapon/ItemGunBase.java b/src/main/java/com/hbm/items/weapon/ItemGunBase.java index 58186803b..f07cfac11 100644 --- a/src/main/java/com/hbm/items/weapon/ItemGunBase.java +++ b/src/main/java/com/hbm/items/weapon/ItemGunBase.java @@ -16,10 +16,12 @@ import com.hbm.interfaces.IItemHUD; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.IEquipReceiver; import com.hbm.lib.HbmCollection; +import com.hbm.main.MainRegistry; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.GunAnimationPacket; import com.hbm.packet.GunButtonPacket; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import com.hbm.render.anim.BusAnimation; import com.hbm.render.anim.HbmAnimations.AnimType; import com.hbm.render.util.RenderScreenOverlay; @@ -208,6 +210,9 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu } world.playSoundAtEntity(player, mainConfig.firingSound, 1.0F, mainConfig.firingPitch); + + if (mainConfig.casingConfig.isPresent() && !mainConfig.casingConfig.get().isAfterReload()) + spawnCasing(player, mainConfig.casingConfig.get(), stack); if(player.getDisplayName().equals("Vic4Games")) { NBTTagCompound nbt = new NBTTagCompound(); @@ -245,6 +250,9 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu } world.playSoundAtEntity(player, altConfig.firingSound, 1.0F, altConfig.firingPitch); + + if (altConfig.casingConfig.isPresent() && !altConfig.casingConfig.get().isAfterReload()) + spawnCasing(player, altConfig.casingConfig.get(), stack); } //spawns the actual projectile, can be overridden to change projectile entity @@ -438,6 +446,10 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu if(hasLoaded && mainConfig.reloadSoundEnd) world.playSoundAtEntity(player, mainConfig.reloadSound, 1.0F, 1.0F); + + if (mainConfig.casingConfig.isPresent() && mainConfig.casingConfig.get().isAfterReload()) + spawnCasing(player, mainConfig.casingConfig.get(), stack); + InventoryUtil.doesPlayerHaveAStack(player, ammo, true, false); } else { setReloadCycle(stack, getReloadCycle(stack) - 1); @@ -579,6 +591,8 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu list.add("Is Reloading: " + getIsReloading(stack)); list.add("Reload Cycle: " + getReloadCycle(stack)); list.add("RoF Cooldown: " + getDelay(stack)); +// list.add("Casing Spawning: " + stack.stackTagCompound.getBoolean("casingReady")); +// list.add("Casing Cooldown: " + stack.stackTagCompound.getByte("casingDelay")); } if (!mainConfig.advLore.isEmpty() || !mainConfig.advFuncLore.isEmpty()) list.add(""); @@ -844,10 +858,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu event.setCanceled(true); - if(!(gcfg.hasSights && player.isSneaking())) - RenderScreenOverlay.renderCustomCrosshairs(event.resolution, Minecraft.getMinecraft().ingameGUI, ((IHoldableWeapon)player.getHeldItem().getItem()).getCrosshair()); - else - RenderScreenOverlay.renderCustomCrosshairs(event.resolution, Minecraft.getMinecraft().ingameGUI, Crosshair.NONE); + RenderScreenOverlay.renderCustomCrosshairs(event.resolution, Minecraft.getMinecraft().ingameGUI, (gcfg.hasSights && player.isSneaking()) ? Crosshair.NONE : ((IHoldableWeapon)player.getHeldItem().getItem()).getCrosshair()); } } @@ -863,4 +874,19 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu if (!mainConfig.equipSound.isEmpty() && !player.worldObj.isRemote) player.worldObj.playSoundAtEntity(player, mainConfig.equipSound, 1, 1); } + + // TODO Do something to handle delays + protected static void spawnCasing(Entity entity, SpentCasingConfig config, ItemStack stack) + { + final NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "casing"); + data.setDouble("posX", entity.posX); + data.setDouble("posY", entity.posY + entity.getEyeHeight()); + data.setDouble("posZ", entity.posZ); + data.setFloat("pitch", (float) Math.toRadians(entity.rotationPitch)); + data.setFloat("yaw", (float) Math.toRadians(entity.rotationYaw)); + data.setBoolean("crouched", entity.isSneaking()); + data.setString("name", config.getRegistryName()); + MainRegistry.proxy.effectNT(data); + } } diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 1218e4ea7..98bead3d9 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -103,7 +103,6 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.ReflectionHelper; public class ClientProxy extends ServerProxy { - public RenderInfoSystem theInfoSystem = new RenderInfoSystem(); @Override @@ -528,6 +527,8 @@ public class ClientProxy extends ServerProxy { MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(ModBlocks.steel_wall), new ItemRenderDecoBlock()); MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(ModBlocks.steel_corner), new ItemRenderDecoBlock()); MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(ModBlocks.steel_roof), new ItemRenderDecoBlock()); + + MinecraftForgeClient.registerItemRenderer(ModItems.wand_d, new RenderCasingTest()); } @Override @@ -1174,6 +1175,8 @@ public class ClientProxy extends ServerProxy { ReflectionHelper.setPrivateValue(EntityFX.class, fx, 10 + rand.nextInt(20), "particleMaxAge", "field_70547_e"); break; } + default: + break; } if(fx != null) { @@ -1813,6 +1816,13 @@ public class ClientProxy extends ServerProxy { Minecraft.getMinecraft().effectRenderer.addEffect(text); break; } + case "casing": + final SpentCasingConfig casingConfig = SpentCasingConfig.get(data.getString("name")); + for (int i = 0; i < casingConfig.getCasingAmount(); i++) + casingConfig.spawnCasing(man, world, x, y, z, data.getFloat("pitch"), data.getFloat("yaw"), data.getBoolean("crouched")); + break; + default: + break; } } diff --git a/src/main/java/com/hbm/main/ResourceManager.java b/src/main/java/com/hbm/main/ResourceManager.java index 6edfe9257..faa98d485 100644 --- a/src/main/java/com/hbm/main/ResourceManager.java +++ b/src/main/java/com/hbm/main/ResourceManager.java @@ -989,6 +989,9 @@ public class ResourceManager { public static final IModelCustom cart = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/vehicles/cart.obj")); public static final IModelCustom cart_destroyer = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/vehicles/cart_destroyer.obj")); public static final IModelCustom cart_powder = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/vehicles/cart_powder.obj")); + + //Casings + public static final IModelCustom casings = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/effect/casings.obj")); ////Texture Entities @@ -1261,6 +1264,9 @@ public class ResourceManager { public static final ResourceLocation cart_semtex_side = new ResourceLocation(RefStrings.MODID, "textures/blocks/semtex_side.png"); public static final ResourceLocation cart_semtex_top = new ResourceLocation(RefStrings.MODID, "textures/blocks/semtex_bottom.png"); + //Casings + public static final ResourceLocation casings_tex = new ResourceLocation(RefStrings.MODID, "textures/particle/casing_tex.png"); + //ISBRHs public static final IModelCustom scaffold = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/blocks/scaffold.obj")); public static final IModelCustom taperecorder = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/blocks/taperecorder.obj")); diff --git a/src/main/java/com/hbm/particle/ParticleSpentCasing.java b/src/main/java/com/hbm/particle/ParticleSpentCasing.java index 254f44a2d..e3f16c893 100644 --- a/src/main/java/com/hbm/particle/ParticleSpentCasing.java +++ b/src/main/java/com/hbm/particle/ParticleSpentCasing.java @@ -1,37 +1,49 @@ package com.hbm.particle; +import java.util.ArrayList; +import java.util.List; + import org.lwjgl.opengl.GL11; -import com.hbm.lib.RefStrings; -import com.hbm.particle.SpentCasingConfig.CasingType; +import com.hbm.calc.EasyLocation; +import com.hbm.main.ResourceManager; +import com.hbm.util.Tuple.Pair; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.particle.EntityFX; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Vec3; import net.minecraft.world.World; @SideOnly(Side.CLIENT) public class ParticleSpentCasing extends EntityFX { - private static final ResourceLocation TEXTURE_BRASS = new ResourceLocation(RefStrings.MODID, "textures/particle/casing_brass.png"), - TEXTURE_SHOTGUN = new ResourceLocation(RefStrings.MODID, "textures/particle/casing_shotgun.png"), - TEXTURE_AR2 = new ResourceLocation(RefStrings.MODID, "textures/particle/casing_ar2.png"); + private static final float dScale = 0.05f, smokeOffset = 0.025f, gravity = -0.5f; + private static final byte smokeAccel = 1; + + private final List> smokeNodes = new ArrayList>(); private final TextureManager textureManager; private final float momentumPitch, momentumYaw; - private final CasingType casingType; - public ParticleSpentCasing(TextureManager textureManager, World world, double x, double y, double z, double mx, double my, double mz, CasingType casingType, float momentumPitch, float momentumYaw) + private final SpentCasingConfig config; + private final boolean smoke; + + private boolean onGroundPreviously = false; + public ParticleSpentCasing(TextureManager textureManager, World world, double x, double y, double z, double mx, double my, double mz, float momentumPitch, float momentumYaw, SpentCasingConfig config) { super(world, x, y, z, mx, my, mz); - particleMaxAge = 120; this.textureManager = textureManager; - this.casingType = casingType; this.momentumPitch = momentumPitch; this.momentumYaw = momentumYaw; + this.config = config; + + particleMaxAge = 120; + smoke = config.getSmokeChance() == 0 ? true + : config.getSmokeChance() < 0 ? false + : rand.nextInt(config.getSmokeChance()) == 0; } @Override @@ -43,13 +55,53 @@ public class ParticleSpentCasing extends EntityFX @Override public void onUpdate() { - // TODO Auto-generated method stub super.onUpdate(); + if (!onGroundPreviously && onGround) + onGroundPreviously = true; + else if (onGroundPreviously && !onGround) + onGroundPreviously = false; + + if (!config.getBounceSound().isEmpty()) + { + if (!onGroundPreviously && onGround) + worldObj.playSoundEffect(posX, posY, posZ, config.getBounceSound(), 1, 1); + } + + if (particleAge > 90 && !smokeNodes.isEmpty()) + smokeNodes.clear(); + + if (smoke && particleAge <= 90) + { + final double side = (rotationYaw - prevRotationYaw) * 0.1D; + final Vec3 prev = Vec3.createVectorHelper(motionX, -motionY, motionZ); + prev.rotateAroundY((float) Math.toRadians(rotationYaw)); + + for (Pair pair : smokeNodes) + { + final EasyLocation node = pair.getKey(); + + node.posX += prev.xCoord * smokeAccel + rand.nextGaussian() * smokeOffset + side; + node.posY += prev.yCoord + 1.5; + node.posZ += prev.zCoord * smokeAccel + rand.nextGaussian() * smokeOffset; + } + + final double alpha = (particleAge / 20d); + + smokeNodes.add(new Pair(EasyLocation.getZeroLocation(), alpha)); + } + prevRotationPitch = rotationPitch; prevRotationYaw = rotationYaw; - if (!onGround) + if (motionY > gravity && !onGround) + motionY += gravity; + if (motionY < -0.75) + motionY = -0.75; + + if (onGround) + rotationPitch = 0; + else { rotationPitch += momentumPitch; rotationYaw += momentumYaw; @@ -62,36 +114,73 @@ public class ParticleSpentCasing extends EntityFX float tx, float tz ) { - // TODO Auto-generated method stub - super.renderParticle(tessellator, interp, x, y, z, tx, tz); - GL11.glPushMatrix(); - GL11.glDisable(GL11.GL_LIGHTING); - final ResourceLocation texture; - switch (casingType) + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glShadeModel(GL11.GL_SMOOTH); + + textureManager.bindTexture(ResourceManager.casings_tex); + + GL11.glTranslated( + prevPosX + (posX - prevPosX) * interp - interpPosX, + prevPosY + (posY - prevPosY) * interp - interpPosY, + prevPosZ + (posZ - prevPosZ) * interp - interpPosZ); + + GL11.glScalef(dScale, dScale, dScale); + + GL11.glScalef(config.getScaleX(), config.getScaleY(), config.getScaleZ()); + +// GL11.glRotatef(prevRotationYaw + (rotationYaw - prevRotationYaw), +// 0.0F, 1.0F, 0.0F); +// GL11.glRotatef(prevRotationPitch + (rotationPitch - prevRotationPitch), +// 0.0F, 0.0F, 1.0F); + + GL11.glRotatef(180 - rotationYaw, 0, 1, 0); + GL11.glRotatef(-rotationPitch, 1, 0, 0); + if (config.doesOverrideColor()) + GL11.glColor3f(config.getRedOverride(), config.getBlueOverride(), config.getGreenOverride()); + + if (!smokeNodes.isEmpty()) { - case AR2: texture = TEXTURE_AR2; break; - case BRASS: texture = TEXTURE_BRASS; break; - case SHOTGUN: texture = TEXTURE_SHOTGUN; break; - default: throw new IllegalStateException("CasingType [" + casingType + "] is not recognized, cannot render spent casing!"); + tessellator.startDrawingQuads(); + tessellator.setNormal(0F, 1F, 0F); + + for (int i = 0; i < smokeNodes.size() - 1; i++) + { + final Pair node = smokeNodes.get(i), past = smokeNodes.get(i + 1); + final EasyLocation nodeLoc = node.getKey(), pastLoc = past.getKey(); + final float nodeAlpha = node.getValue().floatValue(), pastAlpha = past.getValue().floatValue(), scale = Math.max(config.getScaleX(), config.getScaleY()); + + tessellator.setColorRGBA_F(1F, 1F, 1F, nodeAlpha); + tessellator.addVertex(nodeLoc.posX(), nodeLoc.posY(), nodeLoc.posZ()); + tessellator.setColorRGBA_F(1F, 1F, 1F, 0F); + tessellator.addVertex(nodeLoc.posX() + scale, nodeLoc.posY(), nodeLoc.posZ()); + tessellator.setColorRGBA_F(1F, 1F, 1F, 0F); + tessellator.addVertex(pastLoc.posX() + scale, pastLoc.posY(), pastLoc.posZ()); + tessellator.setColorRGBA_F(1F, 1F, 1F, pastAlpha); + tessellator.addVertex(pastLoc.posX(), pastLoc.posY(), pastLoc.posZ()); + + tessellator.setColorRGBA_F(1F, 1F, 1F, nodeAlpha); + tessellator.addVertex(nodeLoc.posX(), nodeLoc.posY(), nodeLoc.posZ()); + tessellator.setColorRGBA_F(1F, 1F, 1F, 0F); + tessellator.addVertex(nodeLoc.posX() - scale, nodeLoc.posY(), nodeLoc.posZ()); + tessellator.setColorRGBA_F(1F, 1F, 1F, 0F); + tessellator.addVertex(pastLoc.posX() - scale, pastLoc.posY(), pastLoc.posZ()); + tessellator.setColorRGBA_F(1F, 1F, 1F, pastAlpha); + tessellator.addVertex(pastLoc.posX(), pastLoc.posY(), pastLoc.posZ()); + } + + GL11.glAlphaFunc(GL11.GL_GREATER, 0F); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_TEXTURE_2D); + tessellator.draw(); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_BLEND); + GL11.glAlphaFunc(GL11.GL_GEQUAL, 0.1F); } - textureManager.bindTexture(texture); - - final float scale = particleScale * 0.1f, - xInterp = (float) (prevPosX + (posX - prevPosX) * interp - interpPosX), - yInterp = (float) (prevPosY + (posY - prevPosY) * interp - interpPosY), - zInterp = (float) (prevPosZ + (posZ - prevPosZ) * interp - interpPosZ); - - tessellator.startDrawingQuads(); - tessellator.setNormal(0, 1, 0); - tessellator.setBrightness(240); - tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, particleAlpha); - tessellator.addVertexWithUV(xInterp - x * scale - tx * scale, yInterp - y, zInterp - z * scale - tz * scale, 0, 0); - tessellator.addVertexWithUV(xInterp - x * scale + tx * scale, yInterp + y, zInterp - z * scale + tz * scale, 0, 1); - tessellator.addVertexWithUV(xInterp + x * scale + tx * scale, yInterp + y, zInterp + z * scale + tz * scale, 1, 1); - tessellator.addVertexWithUV(xInterp + x * scale - tx * scale, yInterp - y, zInterp + z * scale - tz * scale, 1, 0); - tessellator.draw(); + ResourceManager.casings.renderPart(config.getCasingType().objName); + GL11.glShadeModel(GL11.GL_FLAT); GL11.glPopMatrix(); } } diff --git a/src/main/java/com/hbm/particle/SpentCasingConfig.java b/src/main/java/com/hbm/particle/SpentCasingConfig.java index 3bf9e031b..e0edaddfc 100644 --- a/src/main/java/com/hbm/particle/SpentCasingConfig.java +++ b/src/main/java/com/hbm/particle/SpentCasingConfig.java @@ -1,28 +1,55 @@ package com.hbm.particle; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; +import java.util.Random; -public class SpentCasingConfig implements Cloneable +import org.lwjgl.util.vector.Matrix4f; +import org.lwjgl.util.vector.Vector3f; +import org.lwjgl.util.vector.Vector4f; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableMap; +import com.hbm.interfaces.ILocationProvider; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.util.Vec3; +import net.minecraft.world.World; + +@Beta +public class SpentCasingConfig { - + private static final Map CONFIG_MAP = new HashMap(); + private static final Random RANDOM = new Random(); public enum CasingType { - /**The typical ejected type. Most pistols, rifles, and even cannons will likely use it.**/ - BRASS, + /**The typical handgun ejected type. Most pistol and some cannon rounds will likely use it.**/ + BRASS_STRAIGHT_WALL("Brass_Straight_Casing"), + /**The typical rife ejected type. Most rifle round and sometimes cannon rounds use it. Only use if the bottleneck shape is noticeable.**/ + BRASS_BOTTLENECK("Brass_Bottleneck_Casing.002"), /**Shotgun shells.**/ - SHOTGUN, + SHOTGUN("Shotgun_Shell_Cylinder.002"), /**AR2 pulse rifle plugs.**/ - AR2; + AR2("AR2_Cylinder.001"); + public final String objName; + private CasingType(String objName) + { + this.objName = objName; + } } + /**Unique name used for map lookup.**/ + private final String registryName; /**Change position of the ejecting shell.**/ - private final double offsetX, offsetY, offsetZ; + private final ILocationProvider posOffset; /**Set initial motion after ejecting.**/ - private final double motionX, motionY, motionZ; - /**Rescale the sprite to match the approximate scale of the rounds.**/ - private final float stretchX, stretchY; + private final Vec3 initialMotion; /**Multipliers for random pitch and yaw.**/ private final float pitchFactor, yawFactor; + /**Rescale the sprite to match the approximate scale of the rounds.**/ + private final float scaleX, scaleY, scaleZ; /**Overrides for the sprite colors.**/ private final int redOverride, greenOverride, blueOverride; /**Whether or not to override the default sprite color scheme.**/ @@ -30,25 +57,31 @@ public class SpentCasingConfig implements Cloneable /**The type of casing.**/ private final CasingType casingType; /**Amount of casings to spawn per event. Default 1.**/ - private final int casingAmount; + private final byte casingAmount; /**If the casing(s) should be spawned after reloading, instead of after firing.**/ private final boolean afterReload; + /**Sound effect for bouncing. Make empty string to have no sound.**/ + private final String bounceSound; + /**Delay before casings are actually spawned**/ + private final byte delay; + /**Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke.**/ + private final byte smokeChance; + public SpentCasingConfig( - double offsetX, double offsetY, double offsetZ, double motionX, double motionY, double motionZ, - float stretchX, float stretchY, float pitchFactor, float yawFactor, int redOverride, int greenOverride, - int blueOverride, boolean overrideColor, CasingType casingType, int casingAmount, boolean afterReload + String registryName, ILocationProvider posOffset, Vec3 initialMotion, float pitchFactor, float yawFactor, + float scaleX, float scaleY, float scaleZ, int redOverride, int greenOverride, int blueOverride, + boolean overrideColor, CasingType casingType, byte casingAmount, boolean afterReload, String bounceSound, + byte delay, byte smokeChance ) { - this.offsetX = offsetX; - this.offsetY = offsetY; - this.offsetZ = offsetZ; - this.motionX = motionX; - this.motionY = motionY; - this.motionZ = motionZ; - this.stretchX = stretchX; - this.stretchY = stretchY; + this.registryName = registryName; + this.posOffset = posOffset; + this.initialMotion = initialMotion; this.pitchFactor = pitchFactor; this.yawFactor = yawFactor; + this.scaleX = scaleX; + this.scaleY = scaleY; + this.scaleZ = scaleZ; this.redOverride = redOverride; this.greenOverride = greenOverride; this.blueOverride = blueOverride; @@ -56,52 +89,88 @@ public class SpentCasingConfig implements Cloneable this.casingType = casingType; this.casingAmount = casingAmount; this.afterReload = afterReload; - } - - /** - * Apply these settings to an initialized casing entity - * @param entity The entity to apply the settings defined by this object - */ - public void applyToEntity(ParticleSpentCasing entity) - { - entity.setPosition((entity.posX - Math.cos(entity.rotationYaw / 180 * Math.PI)) + offsetX, - (entity.posY - 0.1) + offsetY, - (entity.posZ - Math.sin(entity.rotationYaw / 180 * Math.PI) + offsetZ)); + this.bounceSound = bounceSound; + this.delay = delay; + this.smokeChance = smokeChance; - entity.setRBGColorF((float) redOverride / 255, (float) greenOverride / 255, (float) blueOverride / 255); + CONFIG_MAP.put(registryName, this); + } + + public void spawnCasing(TextureManager textureManager, World world, double x, double y, double z, float pitch, float yaw, boolean crouched) + { + final Vec3 rotatedMotionVec = rotateVector(getInitialMotion(), + pitch + (float) (RANDOM.nextGaussian() * pitchFactor * 0.5), + yaw + (float) (RANDOM.nextGaussian() * yawFactor * 0.5), + pitchFactor, yawFactor); + + final ParticleSpentCasing casing = new ParticleSpentCasing(textureManager, world, x, + y, z, 0, 0, 0, +// 0, 0, + (float) (getPitchFactor() * RANDOM.nextGaussian()), (float) (getYawFactor() * RANDOM.nextGaussian()), + this); + + casing.motionX = rotatedMotionVec.xCoord; + casing.motionY = rotatedMotionVec.yCoord; + casing.motionZ = rotatedMotionVec.zCoord; + + offsetCasing(casing, getPosOffset(), yaw, crouched); + + casing.rotationPitch = (float) Math.toDegrees(pitch); + casing.rotationYaw = (float) Math.toDegrees(yaw); + + if (overrideColor) + casing.setRBGColorF(redOverride, blueOverride, greenOverride); + Minecraft.getMinecraft().effectRenderer.addEffect(casing); } - public double getOffsetX() + private static void offsetCasing(ParticleSpentCasing casing, ILocationProvider offset, float yaw, boolean crouched) { - return offsetX; + casing.posX -= Math.cos(yaw) * offset.posX() + (crouched ? 0.16 : -0.05); + casing.posY -= offset.posY(); + casing.posZ -= Math.sin(yaw) * offset.posZ(); } - public double getOffsetY() + + private static Vec3 rotateVector(Vec3 vector, float pitch, float yaw, float pitchFactor, float yawFactor) { - return offsetY; + vector.xCoord += RANDOM.nextGaussian() * yawFactor; + vector.yCoord += RANDOM.nextGaussian() * pitchFactor; + vector.zCoord += RANDOM.nextGaussian() * yawFactor; + + final Matrix4f pitchMatrix = new Matrix4f(), yawMatrix = new Matrix4f(); + + pitchMatrix.setIdentity(); + pitchMatrix.rotate(-pitch, new Vector3f(1, 0, 0)); + + yawMatrix.setIdentity(); + yawMatrix.rotate(-yaw, new Vector3f(0, 1, 0)); + + final Vector4f vector4f = new Vector4f((float) vector.xCoord, (float) vector.yCoord, (float) vector.zCoord, 1); + + Matrix4f.transform(pitchMatrix, vector4f, vector4f); + Matrix4f.transform(yawMatrix, vector4f, vector4f); + + return Vec3.createVectorHelper(vector4f.x, vector4f.y, vector4f.z); } - public double getOffsetZ() + + public ILocationProvider getPosOffset() { - return offsetZ; + return posOffset; } - public double getMotionX() + public Vec3 getInitialMotion() { - return motionX; + return Vec3.createVectorHelper(initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord); } - public double getMotionY() + public float getScaleX() { - return motionY; + return scaleX; } - public double getMotionZ() + public float getScaleY() { - return motionZ; + return scaleY; } - public float getStretchX() + public float getScaleZ() { - return stretchX; - } - public float getStretchY() - { - return stretchY; + return scaleZ; } public float getPitchFactor() { @@ -123,7 +192,7 @@ public class SpentCasingConfig implements Cloneable { return blueOverride; } - public boolean isOverrideColor() + public boolean doesOverrideColor() { return overrideColor; } @@ -131,7 +200,7 @@ public class SpentCasingConfig implements Cloneable { return casingType; } - public int getCasingAmount() + public byte getCasingAmount() { return casingAmount; } @@ -139,11 +208,44 @@ public class SpentCasingConfig implements Cloneable { return afterReload; } + public String getRegistryName() + { + return registryName; + } + public String getBounceSound() + { + return bounceSound; + } + public byte getDelay() + { + return delay; + } + public byte getSmokeChance() + { + return smokeChance; + } + + /** + * Convert to a new builder for modification. + * @param newName The new registry name. + * @return A new builder with all the settings inherited from this config, except for registry name. + */ + public SpentCasingConfigBuilder toBuilder(String newName) + { + final SpentCasingConfigBuilder builder = new SpentCasingConfigBuilder(newName, casingType, overrideColor); + builder.setAfterReload(afterReload).setBlueOverride(blueOverride).setBounceSound(bounceSound).setCasingAmount(casingAmount) + .setDelay(delay).setGreenOverride(greenOverride).setInitialMotion(getInitialMotion()).setPitchFactor(pitchFactor) + .setPosOffset(getPosOffset()).setRedOverride(redOverride).setScaleX(scaleX).setScaleY(scaleY).setScaleZ(scaleZ) + .setSmokeChance(smokeChance).setYawFactor(yawFactor); + return builder; + } + @Override public int hashCode() { - return Objects.hash(afterReload, blueOverride, casingAmount, casingType, greenOverride, motionX, motionY, motionZ, - offsetX, offsetY, offsetZ, overrideColor, pitchFactor, redOverride, stretchX, stretchY, yawFactor); + return Objects.hash(afterReload, blueOverride, bounceSound, casingAmount, casingType, delay, greenOverride, + initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord, overrideColor, pitchFactor, + posOffset, redOverride, registryName, scaleX, scaleY, scaleZ, smokeChance, yawFactor); } @Override public boolean equals(Object obj) @@ -154,47 +256,50 @@ public class SpentCasingConfig implements Cloneable return false; final SpentCasingConfig other = (SpentCasingConfig) obj; return afterReload == other.afterReload && blueOverride == other.blueOverride - && casingAmount == other.casingAmount && casingType == other.casingType - && greenOverride == other.greenOverride - && Double.doubleToLongBits(motionX) == Double.doubleToLongBits(other.motionX) - && Double.doubleToLongBits(motionY) == Double.doubleToLongBits(other.motionY) - && Double.doubleToLongBits(motionZ) == Double.doubleToLongBits(other.motionZ) - && Double.doubleToLongBits(offsetX) == Double.doubleToLongBits(other.offsetX) - && Double.doubleToLongBits(offsetY) == Double.doubleToLongBits(other.offsetY) - && Double.doubleToLongBits(offsetZ) == Double.doubleToLongBits(other.offsetZ) + && Objects.equals(bounceSound, other.bounceSound) && casingAmount == other.casingAmount + && casingType == other.casingType && delay == other.delay && greenOverride == other.greenOverride + && Double.doubleToLongBits(initialMotion.xCoord) == Double.doubleToLongBits(other.initialMotion.xCoord) + && Double.doubleToLongBits(initialMotion.yCoord) == Double.doubleToLongBits(other.initialMotion.yCoord) + && Double.doubleToLongBits(initialMotion.zCoord) == Double.doubleToLongBits(other.initialMotion.zCoord) && overrideColor == other.overrideColor && Float.floatToIntBits(pitchFactor) == Float.floatToIntBits(other.pitchFactor) - && redOverride == other.redOverride - && Float.floatToIntBits(stretchX) == Float.floatToIntBits(other.stretchX) - && Float.floatToIntBits(stretchY) == Float.floatToIntBits(other.stretchY) + && Objects.equals(posOffset, other.posOffset) && redOverride == other.redOverride + && Objects.equals(registryName, other.registryName) + && Float.floatToIntBits(scaleX) == Float.floatToIntBits(other.scaleX) + && Float.floatToIntBits(scaleY) == Float.floatToIntBits(other.scaleY) + && Float.floatToIntBits(scaleZ) == Float.floatToIntBits(other.scaleZ) + && smokeChance == other.smokeChance && Float.floatToIntBits(yawFactor) == Float.floatToIntBits(other.yawFactor); } @Override public String toString() { final StringBuilder builder = new StringBuilder(); - builder.append("SpentCasingConfig [offsetX=").append(offsetX).append(", offsetY=").append(offsetY) - .append(", offsetZ=").append(offsetZ).append(", motionX=").append(motionX).append(", motionY=") - .append(motionY).append(", motionZ=").append(motionZ).append(", stretchX=").append(stretchX) - .append(", stretchY=").append(stretchY).append(", pitchFactor=").append(pitchFactor) - .append(", yawFactor=").append(yawFactor).append(", redOverride=").append(redOverride) + builder.append("SpentCasingConfig [registryName=").append(registryName).append(", posOffset=").append(posOffset) + .append(", initialMotion=").append(initialMotion).append(", pitchFactor=").append(pitchFactor) + .append(", yawFactor=").append(yawFactor).append(", scaleX=").append(scaleX).append(", scaleY=") + .append(scaleY).append(", scaleZ=").append(scaleZ).append(", redOverride=").append(redOverride) .append(", greenOverride=").append(greenOverride).append(", blueOverride=").append(blueOverride) .append(", overrideColor=").append(overrideColor).append(", casingType=").append(casingType) .append(", casingAmount=").append(casingAmount).append(", afterReload=").append(afterReload) - .append(']'); + .append(", bounceSound=").append(bounceSound).append(", delay=").append(delay).append(", smokeChance=") + .append(smokeChance).append("]"); return builder.toString(); } - @Override - public SpentCasingConfig clone() + + public static boolean containsKey(String key) { - try - { - return (SpentCasingConfig) super.clone(); - } catch (CloneNotSupportedException e) - { - e.printStackTrace(); - return new SpentCasingConfig(offsetX, offsetY, offsetZ, motionX, motionY, motionZ, stretchX, stretchY, pitchFactor, yawFactor, redOverride, greenOverride, blueOverride, overrideColor, casingType, casingAmount, afterReload); - } + return CONFIG_MAP.containsKey(key); } + public static SpentCasingConfig get(String key) + { + return CONFIG_MAP.get(key); + } + + public static Map getConfigMap() + { + return ImmutableMap.copyOf(CONFIG_MAP); + } + } diff --git a/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java b/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java index 13e975773..a3f7368f3 100644 --- a/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java +++ b/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java @@ -2,121 +2,135 @@ package com.hbm.particle; import java.util.Objects; +import com.google.common.annotations.Beta; +import com.hbm.calc.EasyLocation; +import com.hbm.interfaces.ILocationProvider; +import com.hbm.main.MainRegistry; import com.hbm.particle.SpentCasingConfig.CasingType; import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; +@Beta public class SpentCasingConfigBuilder implements Cloneable { + /**Unique name used for map lookup.**/ + private String registryName; /**Change position of the ejecting shell.**/ - private double offsetX, offsetY, offsetZ; + private ILocationProvider posOffset = EasyLocation.getZeroLocation(); /**Set initial motion after ejecting.**/ - private double motionX, motionY, motionZ; - /**Rescale the sprite to match the approximate scale of the rounds.**/ - private float stretchX, stretchY; + private Vec3 initialMotion = Vec3.createVectorHelper(0, 0, 0); /**Multipliers for random pitch and yaw.**/ - private float pitchFactor = 1, yawFactor = 1; + private float pitchFactor, yawFactor; + /**Rescale the sprite to match the approximate scale of the rounds.**/ + private float scaleX = 1, scaleY = 1, scaleZ = 1; /**Overrides for the sprite colors.**/ private int redOverride, greenOverride, blueOverride; /**Whether or not to override the default sprite color scheme.**/ private boolean overrideColor; /**The type of casing.**/ - private CasingType casingType; + private CasingType casingType = CasingType.BRASS_STRAIGHT_WALL; /**Amount of casings to spawn per event. Default 1.**/ - private int casingAmount = 1; + private byte casingAmount = 1; /**If the casing(s) should be spawned after reloading, instead of after firing.**/ private boolean afterReload; - public SpentCasingConfigBuilder(CasingType casingType, boolean overrideColor) + /**Sound effect for bouncing. Make empty string to have no sound.**/ + private String bounceSound = ""; + /**Delay before casings are actually spawned**/ + private byte delay; + /**Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke.**/ + private byte smokeChance = -1; + /** + * Constructor with fields for the required bare minimum parameters.
+ * All parameters may overridden using setters at any time at your discretion, however. + * @param registryName The unique name for map lookup. Null not permitted, becomes empty string. + * @param casingType Type of casing model to use. Null not permitted, defaults to straight wall type. + * @param overrideColor Whether or not the config will override the model texture's color. + */ + public SpentCasingConfigBuilder(String registryName, CasingType casingType, boolean overrideColor) { - this.casingType = casingType; + this.registryName = registryName == null ? "" : registryName; + this.casingType = casingType == null ? CasingType.BRASS_STRAIGHT_WALL : casingType; this.overrideColor = overrideColor; } - public double getOffsetX() + public ILocationProvider getPosOffset() { - return offsetX; + return posOffset; } - - public SpentCasingConfigBuilder setOffsetX(double offsetX) + + /** + * Set the relative x, y, z coordinate offset on spawn. + * @param posOffset Any ILocationProvider that serves as the offset. Null becomes a zero location. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setPosOffset(ILocationProvider posOffset) { - this.offsetX = offsetX; + this.posOffset = posOffset == null ? EasyLocation.getZeroLocation() : posOffset; return this; } - public double getOffsetY() + public Vec3 getInitialMotion() { - return offsetY; + return initialMotion; + } + + /** + * Sets the casing's initial relative x, y, z motion on spawn. + * @param initialMotion Vector representing the initial motion. Null becomes a zero vector. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setInitialMotion(Vec3 initialMotion) + { + this.initialMotion = initialMotion == null ? Vec3.createVectorHelper(0, 0, 0) : initialMotion; + return this; + } + + public double getScaleX() + { + return scaleX; } - public SpentCasingConfigBuilder setOffsetY(double offsetY) + /** + * Scale of the model on its x-axis. + * @param scaleX The scale/stretch factor of the model on the x-axis. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setScaleX(float scaleX) { - this.offsetY = offsetY; + this.scaleX = scaleX; return this; } - public double getOffsetZ() + public double getScaleY() { - return offsetZ; + return scaleY; } - public SpentCasingConfigBuilder setOffsetZ(double offsetZ) + /** + * Scale of the model on its y-axis. + * @param scaleY The scale/stretch factor of the model on the y-axis. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setScaleY(float scaleY) { - this.offsetZ = offsetZ; + this.scaleY = scaleY; return this; } - - public double getMotionX() + + public float getScaleZ() { - return motionX; + return scaleZ; } - - public SpentCasingConfigBuilder setMotionX(double motionX) + + /** + * Scale of the model on its z-axis. + * @param scaleZ The scale/stretch of the model on the z-axis. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setScaleZ(float scaleZ) { - this.motionX = motionX; - return this; - } - - public double getMotionY() - { - return motionY; - } - - public SpentCasingConfigBuilder setMotionY(double motionY) - { - this.motionY = motionY; - return this; - } - - public double getMotionZ() - { - return motionZ; - } - - public SpentCasingConfigBuilder setMotionZ(double motionZ) - { - this.motionZ = motionZ; - return this; - } - - public double getStretchX() - { - return stretchX; - } - - public SpentCasingConfigBuilder setStretchX(float stretchX) - { - this.stretchX = stretchX; - return this; - } - - public double getStretchY() - { - return stretchY; - } - - public SpentCasingConfigBuilder setStretchY(float stretchY) - { - this.stretchY = stretchY; + this.scaleZ = scaleZ; return this; } @@ -125,6 +139,11 @@ public class SpentCasingConfigBuilder implements Cloneable return pitchFactor; } + /** + * Multiplier for random pitch-related motion. Recommended to keep in the thousanths (0.00X), as even with the hundreths (0.0X) the pitch can get crazy at times. + * @param pitchFactor The multiplier. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setPitchFactor(float pitchFactor) { this.pitchFactor = pitchFactor; @@ -136,6 +155,11 @@ public class SpentCasingConfigBuilder implements Cloneable return yawFactor; } + /** + * Multiplier for random yaw-related motion. Recommended to keep in the thousanths (0.00X), as even with the hundreths (0.0X) the yaw can get crazy at times. + * @param yawFactor The multiplier. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setYawFactor(float yawFactor) { this.yawFactor = yawFactor; @@ -147,6 +171,11 @@ public class SpentCasingConfigBuilder implements Cloneable return redOverride; } + /** + * Red color override. Clamped between 0-255, but I don't know how it actually works on the receiving end, so feel free to change. + * @param redOverride Red color override. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setRedOverride(int redOverride) { this.redOverride = MathHelper.clamp_int(redOverride, 0, 255); @@ -158,6 +187,11 @@ public class SpentCasingConfigBuilder implements Cloneable return greenOverride; } + /** + * Green color override. Clamped between 0-255, but I don't know how it actually works on the receiving end, so feel free to change. + * @param greenOverride Green color override. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setGreenOverride(int greenOverride) { this.greenOverride = MathHelper.clamp_int(greenOverride, 0, 255); @@ -169,17 +203,27 @@ public class SpentCasingConfigBuilder implements Cloneable return blueOverride; } + /** + * Blue color override. Clamped between 0-255, but I don't know how it actually works on the receiving end, so feel free to change. + * @param blueOverride Blue color override. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setBlueOverride(int blueOverride) { this.blueOverride = MathHelper.clamp_int(blueOverride, 0, 255); return this; } - public boolean isOverrideColor() + public boolean doesOverrideColor() { return overrideColor; } + /** + * Sets whether or not the config will override color. If false, the integer overrides will be ignored. + * @param overrideColor True, to use the integer color overrides, false to ignore them. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setOverrideColor(boolean overrideColor) { this.overrideColor = overrideColor; @@ -191,20 +235,30 @@ public class SpentCasingConfigBuilder implements Cloneable return casingType; } + /** + * Sets the model the casing will use. + * @param casingType One of the 4 casing model types. Null is not permitted, will have no effect. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setCasingType(CasingType casingType) { - this.casingType = casingType; + this.casingType = casingType == null ? this.casingType : casingType; return this; } - public int getCasingAmount() + public byte getCasingAmount() { return casingAmount; } + /** + * Sets the amount of casings to spawn. Default is 1. + * @param casingAmount Amount of casings to spawn. Clamped to a positive byte (0 - 127). + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setCasingAmount(int casingAmount) { - this.casingAmount = casingAmount; + this.casingAmount = (byte) MathHelper.clamp_int(casingAmount, 0, 127); return this; } @@ -213,23 +267,102 @@ public class SpentCasingConfigBuilder implements Cloneable return afterReload; } + /** + * Sets whether or not the casing will be spawned after reloading is done or after firing. + * @param afterReload If true, casings will be spawned when reloading, false, they will be spawned after firing. + * @return Itself for chaining. + */ public SpentCasingConfigBuilder setAfterReload(boolean afterReload) { this.afterReload = afterReload; return this; } + public String getRegistryName() + { + return registryName; + } + + /** + * Resets the unique name for the config used in map lookup.
+ * As the real class is self-registering, make sure to set this in reused builders. + * @param registryName The registry name to use. Null is not permitted, becomes an empty string. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setRegistryName(String registryName) + { + this.registryName = registryName == null ? "" : registryName; + return this; + } + + public String getBounceSound() + { + return bounceSound; + } + + /** + * The sound used when bouncing. If empty, no sound will be made. + * @param bounceSound The sound path. Null is not permitted, becomes an empty string. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setBounceSound(String bounceSound) + { + this.bounceSound = bounceSound == null ? "" : bounceSound; + return this; + } + + public byte getDelay() + { + return delay; + } + + /** + * The delay in ticks before spawning. + * @param delay Tick spawn delay. Must be nonnegative, otherwise 0. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setDelay(int delay) + { + this.delay = (byte) (delay < 0 ? 0 : delay); + return this; + } + + public byte getSmokeChance() + { + return smokeChance; + } + + /** + * Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke. + * @param smokeChance Chance to emit smoke. Clamped to a byte. + * @return Itself for chaining. + */ + public SpentCasingConfigBuilder setSmokeChance(int smokeChance) + { + this.smokeChance = (byte) smokeChance; + return this; + } + + /** + * Constructs the true immutable config with all settings loaded from this builder.
+ * This builder may be reused as all non-immutable and primitive fields are copied before being passed to the constructor.
+ * The config's constructor is self-registering. + * @return The finished config with its settings specified by this builder. + */ public SpentCasingConfig build() { - return new SpentCasingConfig(offsetX, offsetY, offsetZ, motionX, motionY, motionZ, stretchX, stretchY, pitchFactor, yawFactor, redOverride, greenOverride, blueOverride, overrideColor, casingType, casingAmount, afterReload); + return new SpentCasingConfig(registryName, new EasyLocation(posOffset), + Vec3.createVectorHelper(initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord), pitchFactor, + yawFactor, scaleX, scaleY, scaleZ, redOverride, greenOverride, blueOverride, overrideColor, casingType, + casingAmount, afterReload, bounceSound, delay, smokeChance); } @Override public int hashCode() { - return Objects.hash(afterReload, blueOverride, casingAmount, casingType, greenOverride, motionX, motionY, - motionZ, offsetX, offsetY, offsetZ, overrideColor, pitchFactor, redOverride, stretchX, stretchY, - yawFactor); + return Objects.hash(afterReload, blueOverride, bounceSound, casingAmount, casingType, delay, greenOverride, + initialMotion.xCoord, initialMotion.yCoord, initialMotion.zCoord, overrideColor, pitchFactor, + posOffset, redOverride, registryName, scaleX, scaleY, scaleZ, smokeChance, yawFactor); } @Override @@ -241,19 +374,19 @@ public class SpentCasingConfigBuilder implements Cloneable return false; final SpentCasingConfigBuilder other = (SpentCasingConfigBuilder) obj; return afterReload == other.afterReload && blueOverride == other.blueOverride - && casingAmount == other.casingAmount && casingType == other.casingType - && greenOverride == other.greenOverride - && Double.doubleToLongBits(motionX) == Double.doubleToLongBits(other.motionX) - && Double.doubleToLongBits(motionY) == Double.doubleToLongBits(other.motionY) - && Double.doubleToLongBits(motionZ) == Double.doubleToLongBits(other.motionZ) - && Double.doubleToLongBits(offsetX) == Double.doubleToLongBits(other.offsetX) - && Double.doubleToLongBits(offsetY) == Double.doubleToLongBits(other.offsetY) - && Double.doubleToLongBits(offsetZ) == Double.doubleToLongBits(other.offsetZ) + && Objects.equals(bounceSound, other.bounceSound) && casingAmount == other.casingAmount + && casingType == other.casingType && delay == other.delay && greenOverride == other.greenOverride + && Double.doubleToLongBits(initialMotion.xCoord) == Double.doubleToLongBits(other.initialMotion.xCoord) + && Double.doubleToLongBits(initialMotion.yCoord) == Double.doubleToLongBits(other.initialMotion.yCoord) + && Double.doubleToLongBits(initialMotion.zCoord) == Double.doubleToLongBits(other.initialMotion.zCoord) && overrideColor == other.overrideColor && Float.floatToIntBits(pitchFactor) == Float.floatToIntBits(other.pitchFactor) - && redOverride == other.redOverride - && Float.floatToIntBits(stretchX) == Float.floatToIntBits(other.stretchX) - && Float.floatToIntBits(stretchY) == Float.floatToIntBits(other.stretchY) + && Objects.equals(posOffset, other.posOffset) && redOverride == other.redOverride + && Objects.equals(registryName, other.registryName) + && Float.floatToIntBits(scaleX) == Float.floatToIntBits(other.scaleX) + && Float.floatToIntBits(scaleY) == Float.floatToIntBits(other.scaleY) + && Float.floatToIntBits(scaleZ) == Float.floatToIntBits(other.scaleZ) + && smokeChance == other.smokeChance && Float.floatToIntBits(yawFactor) == Float.floatToIntBits(other.yawFactor); } @@ -261,15 +394,15 @@ public class SpentCasingConfigBuilder implements Cloneable public String toString() { final StringBuilder builder = new StringBuilder(); - builder.append("SpentCasingConfigBuilder [offsetX=").append(offsetX).append(", offsetY=").append(offsetY) - .append(", offsetZ=").append(offsetZ).append(", motionX=").append(motionX).append(", motionY=") - .append(motionY).append(", motionZ=").append(motionZ).append(", stretchX=").append(stretchX) - .append(", stretchY=").append(stretchY).append(", pitchFactor=").append(pitchFactor) - .append(", yawFactor=").append(yawFactor).append(", redOverride=").append(redOverride) - .append(", greenOverride=").append(greenOverride).append(", blueOverride=").append(blueOverride) - .append(", overrideColor=").append(overrideColor).append(", casingType=").append(casingType) - .append(", casingAmount=").append(casingAmount).append(", afterReload=").append(afterReload) - .append(']'); + builder.append("SpentCasingConfigBuilder [registryName=").append(registryName).append(", posOffset=") + .append(posOffset).append(", initialMotion=").append(initialMotion).append(", pitchFactor=") + .append(pitchFactor).append(", yawFactor=").append(yawFactor).append(", scaleX=").append(scaleX) + .append(", scaleY=").append(scaleY).append(", scaleZ=").append(scaleZ).append(", redOverride=") + .append(redOverride).append(", greenOverride=").append(greenOverride).append(", blueOverride=") + .append(blueOverride).append(", overrideColor=").append(overrideColor).append(", casingType=") + .append(casingType).append(", casingAmount=").append(casingAmount).append(", afterReload=") + .append(afterReload).append(", bounceSound=").append(bounceSound).append(", delay=").append(delay) + .append(", smokeChance=").append(smokeChance).append(']'); return builder.toString(); } @@ -281,12 +414,8 @@ public class SpentCasingConfigBuilder implements Cloneable return (SpentCasingConfigBuilder) super.clone(); } catch (CloneNotSupportedException e) { - e.printStackTrace(); - return new SpentCasingConfigBuilder(casingType, overrideColor).setBlueOverride(blueOverride) - .setCasingAmount(casingAmount).setGreenOverride(greenOverride).setMotionX(motionX) - .setMotionY(motionY).setMotionZ(motionZ).setOffsetX(offsetX).setOffsetY(offsetY) - .setOffsetZ(offsetZ).setPitchFactor(pitchFactor).setRedOverride(redOverride) - .setStretchX(stretchX).setStretchY(stretchY).setYawFactor(yawFactor); + MainRegistry.logger.catching(e); + return new SpentCasingConfigBuilder(registryName, casingType, overrideColor); } } diff --git a/src/main/java/com/hbm/render/entity/effect/RenderCasingTest.java b/src/main/java/com/hbm/render/entity/effect/RenderCasingTest.java new file mode 100644 index 000000000..381d1834a --- /dev/null +++ b/src/main/java/com/hbm/render/entity/effect/RenderCasingTest.java @@ -0,0 +1,56 @@ +package com.hbm.render.entity.effect; + +import org.lwjgl.opengl.GL11; + +import com.hbm.main.ResourceManager; +import com.hbm.particle.SpentCasingConfig.CasingType; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.IItemRenderer; + +public class RenderCasingTest implements IItemRenderer +{ + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) + { + return true; + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) + { + return false; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) + { + final EntityPlayer player = Minecraft.getMinecraft().thePlayer; + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glShadeModel(GL11.GL_SMOOTH); + + Minecraft.getMinecraft().getTextureManager().bindTexture(ResourceManager.casings_tex); + +// GL11.glTranslated( +// player.prevPosX + (player.posX - player.prevPosX), +// player.prevPosY + (player.posY - player.prevPosY), +// player.prevPosZ + (player.posZ - player.prevPosZ)); + +// GL11.glRotatef(player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw), +// 0.0F, 1.0F, 0.0F); +// GL11.glRotatef(player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch), +// 0.0F, 0.0F, 1.0F); + + GL11.glRotatef(180 - player.rotationYaw, 0, 1, 0); + GL11.glRotatef(-player.rotationPitch, 1, 0, 0); + + ResourceManager.casings.renderPart(CasingType.BRASS_BOTTLENECK.objName); + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glPopMatrix(); + } + +} diff --git a/src/main/java/com/hbm/render/item/weapon/ItemRenderBenelli.java b/src/main/java/com/hbm/render/item/weapon/ItemRenderBenelli.java index 90ba0e4b4..06a0986d9 100644 --- a/src/main/java/com/hbm/render/item/weapon/ItemRenderBenelli.java +++ b/src/main/java/com/hbm/render/item/weapon/ItemRenderBenelli.java @@ -39,7 +39,7 @@ public class ItemRenderBenelli implements IItemRenderer static final String frontGrip = "Pump_Cylinder.003"; static final String slide = "Cylinder"; static final String barrelAndTube = "Body_Cube.002"; - static final String shell = "Shell_Cylinder.002"; +// static final String shell = "Shell_Cylinder.002"; @Override public void renderItem(ItemRenderType type, ItemStack item, Object... data) { @@ -55,7 +55,7 @@ public class ItemRenderBenelli implements IItemRenderer final double scale3 = 0.52D; double[] recoil = HbmAnimations.getRelevantTransformation("RECOIL"); - double[] eject = HbmAnimations.getRelevantTransformation("EJECT"); +// double[] eject = HbmAnimations.getRelevantTransformation("EJECT"); // double[] reload = HbmAnimations.getRelevantTransformation("RELOAD"); double[] feedNew = HbmAnimations.getRelevantTransformation("PUMP"); switch (type) @@ -82,7 +82,7 @@ public class ItemRenderBenelli implements IItemRenderer // GL11.glTranslated(reload[2] / 2, 0, 0); // GL11.glRotated(reload[0], 1, 0, 0); // GL11.glRotated(reload[1], 0, 0, 1); - ResourceManager.benelli.renderAllExcept(shell, slide); + ResourceManager.benelli.renderAll(); // Pump new round if empty if (magSize == 0) GL11.glTranslated(feedNew[0], feedNew[1], feedNew[2]); @@ -90,8 +90,8 @@ public class ItemRenderBenelli implements IItemRenderer GL11.glPopMatrix(); // Eject spent shell GL11.glPushMatrix(); - GL11.glTranslated(eject[0], eject[1], eject[2]); - ResourceManager.benelli.renderPart(shell); +// GL11.glTranslated(eject[0], eject[1], eject[2]); +// ResourceManager.benelli.renderPart(shell); GL11.glPopMatrix(); break; case EQUIPPED:// In hand from other's POV @@ -104,8 +104,8 @@ public class ItemRenderBenelli implements IItemRenderer GL11.glScaled(scale2 - scale2 * 2, scale2, scale2); GL11.glPushMatrix(); - GL11.glTranslated(eject[0], eject[1], eject[2]); - ResourceManager.benelli.renderPart(shell); +// GL11.glTranslated(eject[0], eject[1], eject[2]); +// ResourceManager.benelli.renderPart(shell); GL11.glPopMatrix(); break; case ENTITY:// Dropped entity diff --git a/src/main/java/com/hbm/render/item/weapon/ItemRenderLunaticSniper.java b/src/main/java/com/hbm/render/item/weapon/ItemRenderLunaticSniper.java index 097bb0cd0..1c788e292 100644 --- a/src/main/java/com/hbm/render/item/weapon/ItemRenderLunaticSniper.java +++ b/src/main/java/com/hbm/render/item/weapon/ItemRenderLunaticSniper.java @@ -49,7 +49,7 @@ public class ItemRenderLunaticSniper implements IItemRenderer { GL11.glPushMatrix(); double[] recoil = HbmAnimations.getRelevantTransformation("RECOIL"); - double[] eject = HbmAnimations.getRelevantTransformation("EJECT"); +// double[] eject = HbmAnimations.getRelevantTransformation("EJECT"); double[] tilt = HbmAnimations.getRelevantTransformation("TILT"); // double[] insert = HbmAnimations.getRelevantTransformation("INSERT_ROUND"); Minecraft.getMinecraft().renderEngine.bindTexture(ResourceManager.lunatic_sniper_tex); @@ -93,7 +93,7 @@ public class ItemRenderLunaticSniper implements IItemRenderer // Eject casing GL11.glPushMatrix(); GL11.glTranslated(0, 2, 0);//FIXME Where on earth is it?! - ResourceManager.lunatic_sniper.renderPart(spentShell); +// ResourceManager.lunatic_sniper.renderPart(spentShell); GL11.glPopMatrix(); break; case EQUIPPED:// In hand from other's POV @@ -103,8 +103,8 @@ public class ItemRenderLunaticSniper implements IItemRenderer GL11.glTranslatef(0F, -0.25F, -0.76F); GL11.glScalef(scale2 - scale2 * 2, scale2, scale2); GL11.glPushMatrix(); - GL11.glTranslated(eject[0] / 2, 0, -5); - ResourceManager.lunatic_sniper.renderPart(spentShell); +// GL11.glTranslated(eject[0] / 2, 0, -5); +// ResourceManager.lunatic_sniper.renderPart(spentShell); GL11.glPopMatrix(); break; case ENTITY:// Dropped item diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java index cfc551c83..026b21408 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java @@ -5,6 +5,7 @@ import java.util.List; import com.hbm.blocks.BlockDummyable; import com.hbm.entity.projectile.EntityArtilleryShell; +import com.hbm.handler.guncfg.GunCannonFactory; import com.hbm.inventory.container.ContainerTurretBase; import com.hbm.inventory.gui.GUITurretArty; import com.hbm.items.ModItems; @@ -12,6 +13,7 @@ import com.hbm.lib.Library; import com.hbm.main.MainRegistry; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import com.hbm.tileentity.IGUIProvider; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @@ -45,7 +47,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen if(ammoStacks != null) return ammoStacks; - ammoStacks = new ArrayList(); + ammoStacks = new ArrayList<>(); List list = new ArrayList(); ModItems.ammo_arty.getSubItems(ModItems.ammo_arty, MainRegistry.weaponTab, list); @@ -56,7 +58,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen @Override protected List getAmmoList() { - return new ArrayList(); + return new ArrayList<>(); } @Override @@ -86,12 +88,12 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen @Override public double getDecetorRange() { - return this.mode == this.MODE_CANNON ? 250D : 3000D; + return this.mode == MODE_CANNON ? 250D : 3000D; } @Override public double getDecetorGrace() { - return this.mode == this.MODE_CANNON ? 32D : 250D; + return this.mode == MODE_CANNON ? 32D : 250D; } @Override @@ -121,7 +123,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen @Override public boolean doLOSCheck() { - return this.mode == this.MODE_CANNON; + return this.mode == MODE_CANNON; } @Override @@ -198,12 +200,13 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen proj.setTarget((int) tPos.xCoord, (int) tPos.yCoord, (int) tPos.zCoord); proj.setType(type); - if(this.mode != this.MODE_CANNON) + if(this.mode != MODE_CANNON) proj.setWhistle(true); worldObj.spawnEntityInWorld(proj); } + @Override protected void updateConnections() { ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - BlockDummyable.offset).getOpposite(); ForgeDirection rot = dir.getRotation(ForgeDirection.UP); @@ -239,7 +242,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen } } - if(this.mode == this.MODE_MANUAL) { + if(this.mode == MODE_MANUAL) { if(!this.targetQueue.isEmpty()) { this.tPos = this.targetQueue.get(0); } @@ -264,7 +267,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen } } - if(target != null && this.mode != this.MODE_MANUAL) { + if(target != null && this.mode != MODE_MANUAL) { if(!this.entityInLOS(this.target)) { this.target = null; } @@ -275,7 +278,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen if(target != null) { this.tPos = this.getEntityPos(target); } else { - if(this.mode != this.MODE_MANUAL) { + if(this.mode != MODE_MANUAL) { this.tPos = null; } } @@ -307,7 +310,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen if(searchTimer <= 0) { searchTimer = this.getDecetorInterval(); - if(this.target == null && this.mode != this.MODE_MANUAL) + if(this.target == null && this.mode != MODE_MANUAL) this.seekNewTarget(); } } else { @@ -373,7 +376,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, pos.xCoord + vec.xCoord, pos.yCoord + vec.yCoord, pos.zCoord + vec.zCoord), new TargetPoint(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 150)); } - if(this.mode == this.MODE_MANUAL && !this.targetQueue.isEmpty()) { + if(this.mode == MODE_MANUAL && !this.targetQueue.isEmpty()) { this.targetQueue.remove(0); this.tPos = null; } @@ -436,4 +439,16 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen public GuiScreen provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { return new GUITurretArty(player.inventory, this); } + + @Override + public boolean usesCasings() + { + return true; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return GunCannonFactory.CASING_16IN; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseArtillery.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseArtillery.java index 35d211872..9b2eeaefb 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseArtillery.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseArtillery.java @@ -8,7 +8,7 @@ import net.minecraft.util.Vec3; public abstract class TileEntityTurretBaseArtillery extends TileEntityTurretBaseNT { - protected List targetQueue = new ArrayList(); + protected List targetQueue = new ArrayList<>(); public void enqueueTarget(double x, double y, double z) { diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java index bff77dba0..c53c9b283 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java @@ -17,6 +17,8 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.items.machine.ItemTurretBiometry; import com.hbm.lib.Library; +import com.hbm.main.MainRegistry; +import com.hbm.particle.SpentCasingConfig; import com.hbm.tileentity.TileEntityMachineBase; import api.hbm.energy.IEnergyUser; @@ -90,6 +92,8 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple //tally marks! public int stattrak; + // Not saved because client side only + public byte casingDelay; /** * X @@ -226,6 +230,14 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple else this.lastRotationYaw -= Math.PI * 2; } + + if (usesCasings() && getCasingConfig().getDelay() > 0) + { + if (casingDelay > 0) + casingDelay--; + else + spawnCasing(); + } } } @@ -297,6 +309,8 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple } public abstract void updateFiringTick(); + public abstract boolean usesCasings(); + public abstract SpentCasingConfig getCasingConfig(); public BulletConfiguration getFirstConfigLoaded() { @@ -338,6 +352,14 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple proj.setThrowableHeading(vec.xCoord, vec.yCoord, vec.zCoord, bullet.velocity, bullet.spread); worldObj.spawnEntityInWorld(proj); + + if (usesCasings()) + { + if (getCasingConfig().getDelay() == 0) + spawnCasing(); + else + casingDelay = getCasingConfig().getDelay(); + } } public void conusmeAmmo(ComparableStack ammo) { @@ -821,4 +843,18 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple public void closeInventory() { this.worldObj.playSoundEffect(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, "hbm:block.closeC", 1.0F, 1.0F); } + + protected void spawnCasing() + { + final NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "casing"); + data.setDouble("posX", xCoord); + data.setDouble("posY", yCoord + 0.5); + data.setDouble("posZ", zCoord); + data.setFloat("pitch", (float) rotationPitch); + data.setFloat("yaw", (float) rotationYaw); + data.setBoolean("crouched", false); + data.setString("name", getCasingConfig().getRegistryName()); + MainRegistry.proxy.effectNT(data); + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBrandon.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBrandon.java index d0598c8d5..4857d820a 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBrandon.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBrandon.java @@ -2,6 +2,8 @@ package com.hbm.tileentity.turret; import java.util.List; +import com.hbm.particle.SpentCasingConfig; + public class TileEntityTurretBrandon extends TileEntityTurretBaseNT { @Override @@ -28,4 +30,16 @@ public class TileEntityTurretBrandon extends TileEntityTurretBaseNT { return null; } + @Override + public boolean usesCasings() + { + return false; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return null; + } + } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretChekhov.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretChekhov.java index 80f5da180..05e23d4cf 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretChekhov.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretChekhov.java @@ -3,10 +3,12 @@ package com.hbm.tileentity.turret; import java.util.ArrayList; import java.util.List; -import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.guncfg.Gun50BMGFactory; +import com.hbm.lib.HbmCollection; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraft.nbt.NBTTagCompound; @@ -14,21 +16,22 @@ import net.minecraft.util.Vec3; public class TileEntityTurretChekhov extends TileEntityTurretBaseNT { - static List configs = new ArrayList(); + static List configs = new ArrayList<>(); //because cramming it into the ArrayList's constructor with nested curly brackets and all that turned out to be not as pretty //also having a floaty `static` like this looks fun //idk if it's just me though static { - configs.add(BulletConfigSyncingUtil.BMG50_NORMAL); - configs.add(BulletConfigSyncingUtil.BMG50_INCENDIARY); - configs.add(BulletConfigSyncingUtil.BMG50_EXPLOSIVE); - configs.add(BulletConfigSyncingUtil.BMG50_AP); - configs.add(BulletConfigSyncingUtil.BMG50_DU); - configs.add(BulletConfigSyncingUtil.BMG50_STAR); - configs.add(BulletConfigSyncingUtil.BMG50_PHOSPHORUS); - configs.add(BulletConfigSyncingUtil.BMG50_SLEEK); - configs.add(BulletConfigSyncingUtil.CHL_BMG50); +// configs.add(BulletConfigSyncingUtil.BMG50_NORMAL); +// configs.add(BulletConfigSyncingUtil.BMG50_INCENDIARY); +// configs.add(BulletConfigSyncingUtil.BMG50_EXPLOSIVE); +// configs.add(BulletConfigSyncingUtil.BMG50_AP); +// configs.add(BulletConfigSyncingUtil.BMG50_DU); +// configs.add(BulletConfigSyncingUtil.BMG50_STAR); +// configs.add(BulletConfigSyncingUtil.BMG50_PHOSPHORUS); +// configs.add(BulletConfigSyncingUtil.BMG50_SLEEK); +// configs.add(BulletConfigSyncingUtil.CHL_BMG50); + configs.addAll(HbmCollection.fiftyBMG); } @Override @@ -142,4 +145,16 @@ public class TileEntityTurretChekhov extends TileEntityTurretBaseNT { manual = true; } + + @Override + public boolean usesCasings() + { + return true; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return Gun50BMGFactory.CONFIG_50BMG; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java index cadfc4c94..081cb1383 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java @@ -4,10 +4,12 @@ import java.util.ArrayList; import java.util.List; import com.hbm.handler.BulletConfigSyncingUtil; +import com.hbm.handler.guncfg.Gun5mmFactory; +import com.hbm.particle.SpentCasingConfig; public class TileEntityTurretFriendly extends TileEntityTurretChekhov { - static List configs = new ArrayList(); + static List configs = new ArrayList<>(); static { configs.add(BulletConfigSyncingUtil.R5_NORMAL); @@ -31,4 +33,10 @@ public class TileEntityTurretFriendly extends TileEntityTurretChekhov { public int getDelay() { return 5; } + + @Override + public SpentCasingConfig getCasingConfig() + { + return Gun5mmFactory.CASING_5MM_TURRET; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFritz.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFritz.java index f571c4c03..cd41c778d 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFritz.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFritz.java @@ -13,6 +13,7 @@ import com.hbm.inventory.fluid.tank.FluidTank; import com.hbm.items.ModItems; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import api.hbm.fluid.IFluidStandardReceiver; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @@ -212,4 +213,16 @@ public class TileEntityTurretFritz extends TileEntityTurretBaseNT implements IFl public FluidTank[] getAllTanks() { return new FluidTank[] { tank }; } + + @Override + public boolean usesCasings() + { + return false; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return null; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java index 1bb2d49c9..9e052854d 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHIMARS.java @@ -8,6 +8,7 @@ import com.hbm.inventory.gui.GUITurretHIMARS; import com.hbm.items.ModItems; import com.hbm.lib.Library; import com.hbm.main.MainRegistry; +import com.hbm.particle.SpentCasingConfig; import com.hbm.tileentity.IGUIProvider; import cpw.mods.fml.relauncher.Side; @@ -257,4 +258,16 @@ public class TileEntityTurretHIMARS extends TileEntityTurretBaseArtillery implem public GuiScreen provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { return new GUITurretHIMARS(player.inventory, this); } + + @Override + public boolean usesCasings() + { + return false; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return null; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java index 94df68742..d9ab5ab64 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java @@ -6,9 +6,11 @@ import java.util.List; import com.hbm.config.WeaponConfig; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.guncfg.GunDGKFactory; import com.hbm.lib.ModDamageSource; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import com.hbm.util.EntityDamageUtil; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @@ -17,7 +19,7 @@ import net.minecraft.util.Vec3; public class TileEntityTurretHoward extends TileEntityTurretBaseNT { - static List configs = new ArrayList(); + static List configs = new ArrayList<>(); static { configs.add(BulletConfigSyncingUtil.DGK_NORMAL); @@ -159,6 +161,8 @@ public class TileEntityTurretHoward extends TileEntityTurretBaseNT { data.setByte("count", (byte)1); PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, pos.xCoord + vec.xCoord + hOff.xCoord, pos.yCoord + vec.yCoord + hOff.yCoord, pos.zCoord + vec.zCoord + hOff.zCoord), new TargetPoint(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 50)); } + + spawnCasing(); } } } @@ -174,4 +178,16 @@ public class TileEntityTurretHoward extends TileEntityTurretBaseNT { super.writeToNBT(nbt); nbt.setInteger("loaded", loaded); } + + @Override + public boolean usesCasings() + { + return true; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return GunDGKFactory.CASING_DGK; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java index 5e022996d..930e1be42 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java @@ -4,9 +4,11 @@ import java.util.ArrayList; import java.util.List; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.guncfg.GunCannonFactory; import com.hbm.lib.HbmCollection; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraft.nbt.NBTTagCompound; @@ -98,4 +100,16 @@ public class TileEntityTurretJeremy extends TileEntityTurretBaseNT { } } } + + @Override + public boolean usesCasings() + { + return true; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return GunCannonFactory.CASING_240; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretMaxwell.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretMaxwell.java index 413a166ad..8a9175b0a 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretMaxwell.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretMaxwell.java @@ -7,6 +7,7 @@ import com.hbm.items.ModItems; import com.hbm.lib.ModDamageSource; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import com.hbm.potion.HbmPotion; import com.hbm.util.EntityDamageUtil; @@ -39,7 +40,7 @@ public class TileEntityTurretMaxwell extends TileEntityTurretBaseNT { if(ammoStacks != null) return ammoStacks; - ammoStacks = new ArrayList(); + ammoStacks = new ArrayList<>(); ammoStacks.add(new ItemStack(ModItems.upgrade_speed_1)); ammoStacks.add(new ItemStack(ModItems.upgrade_speed_2)); @@ -232,4 +233,16 @@ public class TileEntityTurretMaxwell extends TileEntityTurretBaseNT { else super.networkUnpack(nbt); } + + @Override + public boolean usesCasings() + { + return false; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return null; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretRichard.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretRichard.java index 2750202d5..8cae81356 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretRichard.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretRichard.java @@ -7,6 +7,7 @@ import com.hbm.entity.projectile.EntityBulletBase; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; import com.hbm.items.ItemAmmoEnums.AmmoRocket; +import com.hbm.particle.SpentCasingConfig; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.Vec3; @@ -163,4 +164,16 @@ public class TileEntityTurretRichard extends TileEntityTurretBaseNT { super.writeToNBT(nbt); nbt.setInteger("loaded", this.loaded); } + + @Override + public boolean usesCasings() + { + return false; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return null; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretTauon.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretTauon.java index d3d8d7f27..798f79653 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretTauon.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretTauon.java @@ -8,6 +8,7 @@ import com.hbm.handler.BulletConfiguration; import com.hbm.lib.ModDamageSource; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraft.nbt.NBTTagCompound; @@ -15,7 +16,7 @@ import net.minecraft.util.Vec3; public class TileEntityTurretTauon extends TileEntityTurretBaseNT { - static List configs = new ArrayList(); + static List configs = new ArrayList<>(); static { configs.add(BulletConfigSyncingUtil.SPECIAL_GAUSS); @@ -149,4 +150,16 @@ public class TileEntityTurretTauon extends TileEntityTurretBaseNT { else super.networkUnpack(nbt); } + + @Override + public boolean usesCasings() + { + return false; + } + + @Override + public SpentCasingConfig getCasingConfig() + { + return null; + } } diff --git a/src/main/java/com/hbm/util/Quaternion.java b/src/main/java/com/hbm/util/Quaternion.java new file mode 100644 index 000000000..21aa12ed9 --- /dev/null +++ b/src/main/java/com/hbm/util/Quaternion.java @@ -0,0 +1,302 @@ +package com.hbm.util; + +import java.io.Serializable; +import java.util.Objects; + +import com.hbm.interfaces.IByteSerializable; +import com.hbm.interfaces.INBTSerializable; +import com.hbm.main.DeserializationException; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.Vec3; + +/** + * Credits to Apache for the basic structure. + * @author UFFR + * + */ +public class Quaternion implements Serializable, Cloneable, IByteSerializable, INBTSerializable +{ + /** + * + */ + private static final long serialVersionUID = -403051011515625947L; + private double w, x, y, z; + + public Quaternion(double pitch, double yaw) + { + final double rPitch = Math.toRadians(pitch), + rYaw = Math.toRadians(yaw), + + cp = Math.cos(rPitch * 0.5), + sp = Math.sin(rPitch * 0.5), + cy = Math.cos(rYaw * 0.5), + sy = Math.sin(rYaw * 0.5); + + w = cy * sp; + x = sy * cp; + y = sy * cp; + z = cy * cp; + } + + public Quaternion(double roll, double pitch, double yaw) + { + final double rRoll = Math.toRadians(roll), + rPitch = Math.toRadians(pitch), + rYaw = Math.toRadians(yaw), + + cr = Math.cos(rRoll * 0.5), + sr = Math.sin(rRoll * 0.5), + cp = Math.cos(rPitch * 0.5), + sp = Math.sin(rPitch * 0.5), + cy = Math.cos(rYaw * 0.5), + sy = Math.sin(rYaw * 0.5); + + w = cr * cp * cy + sr * sp * sy; + x = sr * cp * cy - cr * sp * sy; + y = cr * sp * cy + sr * cp * sy; + z = cr * cp * sy - sr * sp * cy; + + } + + public Quaternion(double w, double x, double y, double z) + { + this.w = w; + this.x = x; + this.y = y; + this.z = z; + } + + public Quaternion(double w, Vec3 vec3) + { + this.w = w; + + x = vec3.xCoord; + y = vec3.yCoord; + z = vec3.zCoord; + } + + public Quaternion(Vec3 vec3) + { + this(0, vec3); + } + + public Quaternion(double w, double[] vector) + { + if (vector.length != 3) + throw new IllegalArgumentException("Vector argument must only have 3 values!"); + + this.w = w; + + x = vector[0]; + y = vector[1]; + z = vector[2]; + } + + public Quaternion(double[] vector) + { + this(0, vector); + } + + public Quaternion getConjugate() + { + return new Quaternion(w, -x, -y, -z); + } + + public Quaternion add(Quaternion q) + { + return add(this, q); + } + + public Quaternion subtract(Quaternion q) + { + return subtract(this, q); + } + + public Quaternion multiply(Quaternion q) + { + return multiply(this, q); + } + + public Quaternion dotProduct(Quaternion q) + { + return dotProduct(this, q); + } + + public double getNorm() + { + return Math.sqrt(w * w + x * x + y * y + z * z); + } + + public Quaternion normalize() + { + final double norm = getNorm(); + if (norm < Double.MIN_NORMAL) + throw new ArithmeticException("Quaternion norm zero!"); + + return new Quaternion( + w / norm, + x / norm, + y / norm, + z / norm); + } + + public double getPitch() + { + return Math.atan2(2 * (y * z + w * x), w * w - x * x - y * y + z * z); + } + + public double getYaw() + { + return Math.asin(-2 * (x * z - w * y)); + } + + public double getRoll() + { + return Math.atan2(2 * (x * y + w * z), w * w + x * x - y * y - z * z); + } + + public static Quaternion add(Quaternion q1, Quaternion q2) + { + return new Quaternion(q1.w + q2.w, q1.x + q2.x, q1.y + q2.y, q1.z + q2.z); + } + + public static Quaternion subtract(Quaternion q1, Quaternion q2) + { + return new Quaternion(q1.w - q2.w, q1.x - q2.x, q1.y - q2.y, q1.z - q2.z); + } + + public static Quaternion multiply(Quaternion q1, Quaternion q2) + { + return new Quaternion( + q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z, + q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y, + q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x, + q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w + ); + } + + public static Quaternion dotProduct(Quaternion q1, Quaternion q2) + { + return new Quaternion(q1.w * q2.w, q1.x * q2.x, q1.y * q2.y, q1.z * q2.z); + } + + public static Vec3 rotate(Quaternion q, Vec3 vec3) + { + return q.multiply(new Quaternion(vec3)).multiply(q.getConjugate()).getVector(); + } + + public static Vec3 rotate(Quaternion q, Vec3 vec3, Vec3 origin) + { + return q.multiply(new Quaternion(vec3.subtract(origin))).multiply(q.getConjugate()).getVector().addVector(origin.xCoord, origin.yCoord, origin.zCoord); + } + + public double getW() + { + return w; + } + + public double getX() + { + return x; + } + + public double getY() + { + return y; + } + + public double getZ() + { + return z; + } + + public Vec3 getVector() + { + return Vec3.createVectorHelper(x, y, z); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) + { + nbt.setDouble("w", w); + nbt.setDouble("x", x); + nbt.setDouble("y", y); + nbt.setDouble("z", z); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) + { + w = nbt.getDouble("w"); + x = nbt.getDouble("x"); + y = nbt.getDouble("y"); + z = nbt.getDouble("z"); + } + + @Override + public void writeToBytes(ByteBuf buf) + { + buf.writeDouble(w).writeDouble(x).writeDouble(y).writeDouble(z); + } + + @Override + public void readFromBytes(byte[] bytes) throws DeserializationException + { + try + { + final ByteBuf buf = Unpooled.copiedBuffer(bytes); + w = buf.readDouble(); + x = buf.readDouble(); + y = buf.readDouble(); + z = buf.readDouble(); + } catch (Exception e) + { + throw new DeserializationException(e); + } + } + + @Override + public int hashCode() + { + return Objects.hash(w, x, y, z); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (!(obj instanceof Quaternion)) + return false; + final Quaternion other = (Quaternion) obj; + return Double.doubleToLongBits(w) == Double.doubleToLongBits(other.w) + && Double.doubleToLongBits(x) == Double.doubleToLongBits(other.x) + && Double.doubleToLongBits(y) == Double.doubleToLongBits(other.y) + && Double.doubleToLongBits(z) == Double.doubleToLongBits(other.z); + } + + @Override + public String toString() + { + final StringBuilder builder = new StringBuilder(); + builder.append("Quaternion [w=").append(w).append(", x=").append(x).append(", y=").append(y).append(", z=") + .append(z).append(']'); + return builder.toString(); + } + + @Override + public Quaternion clone() + { + try + { + return (Quaternion) super.clone(); + } catch (CloneNotSupportedException e) + { + return new Quaternion(w, x, y, z); + } + } + +} diff --git a/src/main/resources/assets/hbm/models/effect/casings.mtl b/src/main/resources/assets/hbm/models/effect/casings.mtl new file mode 100644 index 000000000..9870c10af --- /dev/null +++ b/src/main/resources/assets/hbm/models/effect/casings.mtl @@ -0,0 +1,13 @@ +# Blender MTL File: 'casings.blend' +# Material Count: 1 + +newmtl None +Ns 500.000001 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.800000 0.800000 0.800000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 +map_Kd /home/justin/eclipse-workspace/Hbm-s-Nuclear-Tech-GIT/src/main/resources/assets/hbm/textures/particle/casing_tex.png diff --git a/src/main/resources/assets/hbm/models/effect/casings.obj b/src/main/resources/assets/hbm/models/effect/casings.obj new file mode 100644 index 000000000..aafd7bc83 --- /dev/null +++ b/src/main/resources/assets/hbm/models/effect/casings.obj @@ -0,0 +1,965 @@ +# Blender v3.0.1 OBJ File: 'casings.blend' +# www.blender.org +mtllib casings.mtl +o AR2_Cylinder.001 +v 0.000000 0.360000 -1.200000 +v 0.000000 0.360000 -0.400000 +v 0.254558 0.254558 -1.200000 +v 0.254558 0.254558 -0.400000 +v 0.360000 0.000000 -1.200000 +v 0.360000 -0.000000 -0.400000 +v 0.254558 -0.254558 -1.200000 +v 0.254558 -0.254558 -0.400000 +v -0.000000 -0.360000 -1.200000 +v -0.000000 -0.360000 -0.400000 +v -0.254558 -0.254558 -1.200000 +v -0.254558 -0.254559 -0.400000 +v -0.360000 0.000000 -1.200000 +v -0.360000 -0.000000 -0.400000 +v -0.254559 0.254558 -1.200000 +v -0.254559 0.254558 -0.400000 +v 0.000000 0.600000 -0.400000 +v 0.000000 0.600000 0.000000 +v 0.424264 0.424264 -0.400000 +v 0.424264 0.424264 0.000000 +v 0.600000 -0.000000 -0.400000 +v 0.600000 -0.000000 0.000000 +v 0.424264 -0.424264 -0.400000 +v 0.424264 -0.424264 0.000000 +v -0.000000 -0.600000 -0.400000 +v -0.000000 -0.600000 0.000000 +v -0.424264 -0.424264 -0.400000 +v -0.424264 -0.424264 0.000000 +v -0.600000 0.000000 -0.400000 +v -0.600000 0.000000 0.000000 +v -0.424264 0.424264 -0.400000 +v -0.424264 0.424264 0.000000 +vt 0.162500 0.566875 +vt 0.146875 0.504375 +vt 0.162500 0.504375 +vt 0.146875 0.566875 +vt 0.131250 0.504375 +vt 0.131250 0.566875 +vt 0.115625 0.504375 +vt 0.115625 0.566875 +vt 0.100000 0.504375 +vt 0.100000 0.566875 +vt 0.084375 0.504375 +vt 0.084375 0.566875 +vt 0.068750 0.504375 +vt 0.101250 0.599125 +vt 0.002250 0.500125 +vt 0.101250 0.401125 +vt 0.068750 0.566875 +vt 0.053125 0.504375 +vt 0.053125 0.566875 +vt 0.037500 0.504375 +vt 0.171253 0.570129 +vt 0.171253 0.430121 +vt 0.031246 0.430122 +vt 0.162500 0.566875 +vt 0.146875 0.504375 +vt 0.162500 0.504375 +vt 0.146875 0.566875 +vt 0.131250 0.504375 +vt 0.131250 0.566875 +vt 0.115625 0.504375 +vt 0.115625 0.566875 +vt 0.100000 0.504375 +vt 0.100000 0.566875 +vt 0.084375 0.504375 +vt 0.084375 0.566875 +vt 0.068750 0.504375 +vt 0.171253 0.430121 +vt 0.200250 0.500125 +vt 0.002250 0.500125 +vt 0.068750 0.566875 +vt 0.053125 0.504375 +vt 0.053125 0.566875 +vt 0.037500 0.504375 +vt 0.171253 0.430121 +vt 0.031246 0.430122 +vt 0.031246 0.570129 +vt 0.200250 0.500125 +vt 0.171253 0.570129 +vt 0.031246 0.570129 +vt 0.031246 0.430122 +vt 0.171253 0.430121 +vt 0.037500 0.566875 +vt 0.031246 0.570129 +vt 0.101250 0.599125 +vt 0.200250 0.500125 +vt 0.101250 0.401125 +vt 0.002250 0.500125 +vt 0.171253 0.570129 +vt 0.101250 0.599125 +vt 0.031246 0.570129 +vt 0.031246 0.430122 +vt 0.101250 0.401125 +vt 0.037500 0.566875 +vt 0.101250 0.599125 +vt 0.171253 0.570129 +vt 0.200250 0.500125 +vt 0.101250 0.401125 +vt 0.002250 0.500125 +vn 0.3827 0.9239 0.0000 +vn 0.9239 0.3827 0.0000 +vn 0.9239 -0.3827 -0.0000 +vn 0.3827 -0.9239 -0.0000 +vn -0.3827 -0.9239 0.0000 +vn -0.9239 -0.3827 -0.0000 +vn 0.0000 -0.0000 1.0000 +vn -0.9239 0.3827 0.0000 +vn -0.3827 0.9239 0.0000 +vn -0.0000 0.0000 -1.0000 +usemtl None +s off +f 2/1/1 3/2/1 1/3/1 +f 4/4/2 5/5/2 3/2/2 +f 6/6/3 7/7/3 5/5/3 +f 8/8/4 9/9/4 7/7/4 +f 10/10/5 11/11/5 9/9/5 +f 12/12/6 13/13/6 11/11/6 +f 2/14/7 14/15/7 10/16/7 +f 14/17/8 15/18/8 13/13/8 +f 16/19/9 1/20/9 15/18/9 +f 3/21/10 7/22/10 11/23/10 +f 18/24/1 19/25/1 17/26/1 +f 20/27/2 21/28/2 19/25/2 +f 22/29/3 23/30/3 21/28/3 +f 24/31/4 25/32/4 23/30/4 +f 26/33/5 27/34/5 25/32/5 +f 28/35/6 29/36/6 27/34/6 +f 24/37/7 22/38/7 30/39/7 +f 30/40/8 31/41/8 29/36/8 +f 32/42/9 17/43/9 31/41/9 +f 23/44/10 27/45/10 31/46/10 +f 2/1/1 4/4/1 3/2/1 +f 4/4/2 6/6/2 5/5/2 +f 6/6/3 8/8/3 7/7/3 +f 8/8/4 10/10/4 9/9/4 +f 10/10/5 12/12/5 11/11/5 +f 12/12/6 14/17/6 13/13/6 +f 6/47/7 4/48/7 2/14/7 +f 2/14/7 16/49/7 14/15/7 +f 14/15/7 12/50/7 10/16/7 +f 10/16/7 8/51/7 6/47/7 +f 6/47/7 2/14/7 10/16/7 +f 14/17/8 16/19/8 15/18/8 +f 16/19/9 2/52/9 1/20/9 +f 15/53/10 1/54/10 3/21/10 +f 3/21/10 5/55/10 7/22/10 +f 7/22/10 9/56/10 11/23/10 +f 11/23/10 13/57/10 15/53/10 +f 15/53/10 3/21/10 11/23/10 +f 18/24/1 20/27/1 19/25/1 +f 20/27/2 22/29/2 21/28/2 +f 22/29/3 24/31/3 23/30/3 +f 24/31/4 26/33/4 25/32/4 +f 26/33/5 28/35/5 27/34/5 +f 28/35/6 30/40/6 29/36/6 +f 22/38/7 20/58/7 18/59/7 +f 18/59/7 32/60/7 22/38/7 +f 32/60/7 30/39/7 22/38/7 +f 30/39/7 28/61/7 26/62/7 +f 26/62/7 24/37/7 30/39/7 +f 30/40/8 32/42/8 31/41/8 +f 32/42/9 18/63/9 17/43/9 +f 31/46/10 17/64/10 19/65/10 +f 19/65/10 21/66/10 23/44/10 +f 23/44/10 25/67/10 27/45/10 +f 27/45/10 29/68/10 31/46/10 +f 31/46/10 19/65/10 23/44/10 +o Shotgun_Shell_Cylinder.002 +v -0.317579 0.317579 1.112764 +v 0.000000 0.449124 -1.223040 +v -0.317579 0.317579 -1.223040 +v 0.449124 -0.000000 1.112764 +v 0.317579 -0.317578 -1.223040 +v 0.449124 -0.000000 -1.223040 +v 0.317579 -0.317578 1.112764 +v 0.000000 -0.449123 -1.223040 +v 0.000000 -0.449124 1.112764 +v -0.317579 -0.317578 -1.223040 +v -0.317579 -0.317578 1.112764 +v -0.449124 -0.000000 -1.223040 +v -0.449124 -0.000000 1.112764 +v 0.000000 0.449124 1.112764 +v 0.317579 0.317579 -1.223040 +v 0.317579 0.317579 1.112764 +v 0.353356 0.353357 1.148335 +v 0.499721 -0.000000 1.148335 +v 0.353356 -0.353356 1.148335 +v 0.000000 -0.499721 1.148335 +v -0.353356 -0.353356 1.148335 +v -0.499721 -0.000000 1.148335 +v -0.353356 0.353357 1.148335 +v 0.000000 0.499721 1.148335 +vt 0.468081 0.764346 +vt 0.489255 0.933910 +vt 0.468081 0.933910 +vt 0.395789 0.764346 +vt 0.416963 0.933910 +vt 0.395789 0.933910 +vt 0.293553 0.764346 +vt 0.323497 0.933910 +vt 0.293553 0.933910 +vt 0.323497 0.764346 +vt 0.344671 0.933910 +vt 0.416963 0.764346 +vt 0.438137 0.933910 +vt 0.416963 0.933910 +vt 0.438137 0.764346 +vt 0.344671 0.764346 +vt 0.365845 0.933910 +vt 0.344671 0.933910 +vt 0.365845 0.764346 +vt 0.175844 0.775274 +vt 0.144213 0.779346 +vt 0.145900 0.775274 +vt 0.120654 0.755786 +vt 0.124726 0.754100 +vt 0.124726 0.724156 +vt 0.120654 0.722469 +vt 0.145900 0.702982 +vt 0.144213 0.698910 +vt 0.177531 0.698910 +vt 0.175844 0.702982 +vt 0.201090 0.722469 +vt 0.197018 0.724155 +vt 0.197018 0.754100 +vt 0.201090 0.755787 +vt 0.177531 0.779346 +vt 0.489255 0.764346 +vt 0.416963 0.764346 +vt 0.344671 0.764346 +vt 0.960365 0.912783 +vt 0.858129 0.955131 +vt 0.815781 0.852895 +vt 0.067942 0.886801 +vt 0.086790 0.867953 +vt 0.113444 0.867953 +vt 0.918017 0.810547 +vt 0.960365 0.852895 +vt 0.918017 0.955131 +vt 0.815781 0.912784 +vt 0.858128 0.810547 +vt 0.132291 0.886801 +vt 0.132291 0.913455 +vt 0.113444 0.932302 +vt 0.086790 0.932302 +vt 0.067942 0.913455 +vn -0.3827 0.9239 0.0000 +vn 0.9239 -0.3827 -0.0000 +vn 0.3827 -0.9239 -0.0000 +vn -0.3827 -0.9239 -0.0000 +vn -0.9239 -0.3827 -0.0000 +vn -0.9239 0.3827 0.0000 +vn 0.3827 0.9239 0.0000 +vn 0.9239 0.3827 0.0000 +vn 0.2317 0.5595 -0.7958 +vn 0.5595 0.2317 -0.7958 +vn 0.5595 -0.2317 -0.7958 +vn 0.2317 -0.5595 -0.7958 +vn -0.2317 -0.5595 -0.7958 +vn -0.5595 -0.2317 -0.7958 +vn -0.5595 0.2317 -0.7958 +vn -0.2317 0.5595 -0.7958 +vn -0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +usemtl None +s 1 +f 33/69/11 34/70/11 35/71/11 +f 36/72/12 37/73/12 38/74/12 +f 39/75/13 40/76/13 37/77/13 +f 41/78/14 42/79/14 40/76/14 +f 43/80/15 44/81/15 42/82/15 +f 45/83/16 35/71/16 44/81/16 +f 46/84/17 47/85/17 34/86/17 +f 48/87/18 38/74/18 47/85/18 +f 46/88/19 49/89/19 48/90/19 +f 48/90/20 50/91/20 36/92/20 +f 39/93/21 50/91/21 51/94/21 +f 41/95/22 51/94/22 52/96/22 +f 41/95/23 53/97/23 43/98/23 +f 43/98/24 54/99/24 45/100/24 +f 33/101/25 54/99/25 55/102/25 +f 46/88/26 55/102/26 56/103/26 +f 33/69/11 46/104/11 34/70/11 +f 36/72/12 39/105/12 37/73/12 +f 39/75/13 41/78/13 40/76/13 +f 41/78/14 43/106/14 42/79/14 +f 43/80/15 45/83/15 44/81/15 +f 45/83/16 33/69/16 35/71/16 +f 46/84/17 48/87/17 47/85/17 +f 48/87/18 36/72/18 38/74/18 +f 34/107/27 38/108/27 40/109/27 +f 46/88/19 56/103/19 49/89/19 +f 48/90/20 49/89/20 50/91/20 +f 39/93/21 36/92/21 50/91/21 +f 41/95/22 39/93/22 51/94/22 +f 41/95/23 52/96/23 53/97/23 +f 43/98/24 53/97/24 54/99/24 +f 33/101/25 45/100/25 54/99/25 +f 46/88/26 33/101/26 55/102/26 +f 53/110/28 52/111/28 51/112/28 +f 44/113/27 35/114/27 34/107/27 +f 34/107/27 47/115/27 38/108/27 +f 38/108/27 37/116/27 40/109/27 +f 40/109/27 42/117/27 44/113/27 +f 44/113/27 34/107/27 40/109/27 +f 51/112/28 50/118/28 49/119/28 +f 49/119/28 56/120/28 51/112/28 +f 56/120/28 55/121/28 51/112/28 +f 55/121/28 54/122/28 51/112/28 +f 54/122/28 53/110/28 51/112/28 +o Brass_Straight_Casing +v 0.300002 -0.000003 0.685047 +v 0.185616 0.185613 0.685047 +v -0.000000 -0.262503 0.735047 +v 0.300002 -0.000001 0.785047 +v -0.212132 -0.212133 0.685047 +v -0.185614 -0.185617 0.685047 +v -0.212132 0.212131 0.685047 +v -0.000000 0.262499 0.685047 +v -0.000000 0.299999 0.685047 +v 0.212132 0.212131 0.685047 +v 0.212132 -0.212133 0.685047 +v 0.185616 -0.185617 0.685047 +v 0.300002 -0.000003 0.735047 +v -0.000000 0.299999 0.735047 +v -0.212132 0.212131 0.735047 +v -0.185614 0.185613 0.735047 +v -0.185614 -0.185617 0.735047 +v 0.185616 -0.185617 0.735047 +v 0.185616 0.185613 0.735047 +v 0.212132 -0.212133 0.785047 +v -0.300000 -0.000001 0.785047 +v -0.212132 0.212131 0.785047 +v -0.212132 -0.212133 0.785047 +v -0.212132 -0.212133 -0.814953 +v 0.300002 -0.000003 -0.814953 +v 0.212132 0.212131 -0.814953 +v -0.000000 0.299999 -0.814953 +v 0.212132 -0.212133 -0.814953 +v -0.000000 -0.300001 -0.814953 +v -0.000000 -0.300001 0.685047 +v -0.300000 -0.000003 -0.814953 +v -0.300000 -0.000003 0.685047 +v -0.212132 0.212131 -0.814953 +v -0.212132 -0.212133 0.735047 +v -0.000000 -0.300001 0.785047 +v 0.212132 -0.212133 0.735047 +v 0.212132 0.212131 0.785047 +v 0.212132 0.212131 0.735047 +v -0.000000 0.299999 0.785047 +v -0.300000 -0.000003 0.735047 +v -0.000000 -0.300001 0.735047 +v -0.000000 -0.262503 0.685047 +v 0.262502 -0.000003 0.735047 +v 0.262502 -0.000003 0.685047 +v -0.000000 0.262499 0.735047 +v -0.185614 0.185613 0.685047 +v -0.262500 -0.000003 0.735047 +v -0.262500 -0.000003 0.685047 +vt 0.555701 0.706657 +vt 0.559782 0.681299 +vt 0.559782 0.704967 +vt 0.374299 0.628133 +vt 0.353483 0.613088 +vt 0.355173 0.609007 +vt 0.621002 0.706657 +vt 0.600185 0.721702 +vt 0.616920 0.704966 +vt 0.601875 0.660482 +vt 0.576517 0.664564 +vt 0.574827 0.660482 +vt 0.555701 0.679609 +vt 0.574827 0.725783 +vt 0.576518 0.721702 +vt 0.616920 0.681299 +vt 0.621002 0.679609 +vt 0.601876 0.725783 +vt 0.600185 0.664564 +vt 0.328125 0.609007 +vt 0.313080 0.629823 +vt 0.308998 0.628133 +vt 0.308998 0.655181 +vt 0.329815 0.670226 +vt 0.328124 0.674308 +vt 0.355173 0.674308 +vt 0.353482 0.670226 +vt 0.370218 0.653491 +vt 0.370218 0.629824 +vt 0.329815 0.613088 +vt 0.313080 0.653491 +vt 0.374299 0.655181 +vt 0.555701 0.614308 +vt 0.378998 0.641356 +vt 0.378998 0.614308 +vt 0.378998 0.725783 +vt 0.555701 0.752832 +vt 0.378998 0.752832 +vt 0.555701 0.725783 +vt 0.378998 0.706657 +vt 0.555701 0.706657 +vt 0.555701 0.660482 +vt 0.378998 0.660482 +vt 0.378998 0.679609 +vt 0.555701 0.660482 +vt 0.555701 0.679609 +vt 0.555701 0.706657 +vt 0.378998 0.706657 +vt 0.555701 0.799007 +vt 0.378998 0.771958 +vt 0.555701 0.771958 +vt 0.834098 0.918854 +vt 0.872350 0.826504 +vt 0.964699 0.864757 +vt 0.555701 0.641356 +vt 0.378998 0.660482 +vt 0.378998 0.799007 +vt 0.964699 0.918854 +vt 0.926447 0.957106 +vt 0.872350 0.957106 +vt 0.834098 0.864757 +vt 0.926448 0.826504 +vt 0.078463 0.847672 +vt 0.152342 0.878274 +vt 0.121740 0.952153 +vt 0.578726 0.628418 +vt 0.559600 0.622528 +vt 0.578726 0.622528 +vt 0.559600 0.622528 +vt 0.578726 0.616637 +vt 0.578726 0.622528 +vt 0.605775 0.628418 +vt 0.586649 0.634308 +vt 0.586649 0.628418 +vt 0.605775 0.616637 +vt 0.578726 0.610747 +vt 0.605775 0.610747 +vt 0.605775 0.628418 +vt 0.605775 0.622528 +vt 0.605775 0.616637 +vt 0.605775 0.622528 +vt 0.559600 0.634308 +vt 0.559600 0.628418 +vt 0.578726 0.616637 +vt 0.559600 0.610747 +vt 0.572436 0.725783 +vt 0.596104 0.731673 +vt 0.572436 0.731673 +vt 0.600003 0.604857 +vt 0.616739 0.610747 +vt 0.600003 0.610747 +vt 0.555701 0.725783 +vt 0.555701 0.731673 +vt 0.583268 0.610747 +vt 0.559600 0.604857 +vt 0.583268 0.604857 +vt 0.600003 0.610747 +vt 0.600003 0.604857 +vt 0.622437 0.634308 +vt 0.646104 0.640198 +vt 0.622437 0.640198 +vt 0.605701 0.634308 +vt 0.605701 0.640198 +vt 0.616739 0.604857 +vt 0.640406 0.610747 +vt 0.559600 0.628418 +vt 0.559600 0.616637 +vt 0.605775 0.634308 +vt 0.559600 0.616637 +vt 0.596104 0.725783 +vt 0.559600 0.610747 +vt 0.646104 0.634308 +vt 0.640406 0.604857 +vt 0.078463 0.952153 +vt 0.047861 0.921551 +vt 0.047861 0.878274 +vt 0.121740 0.847672 +vt 0.152342 0.921551 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn -0.9239 -0.3827 -0.0000 +vn -0.3827 0.9239 0.0000 +vn -0.9239 0.3827 0.0000 +vn -0.3827 -0.9239 -0.0000 +vn 0.9239 -0.3827 -0.0000 +vn 0.3827 -0.9239 -0.0000 +vn 0.9239 0.3827 0.0000 +vn 0.3827 0.9239 0.0000 +vn 0.5490 -0.5490 0.6303 +vn 0.5490 0.5490 0.6303 +vn -0.5490 0.5490 0.6303 +vn -0.7071 -0.7071 0.0000 +vn -0.0000 -0.7764 0.6303 +vn -0.5490 -0.5490 0.6303 +vn 1.0000 -0.0000 -0.0000 +vn 0.7071 -0.7071 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.7071 0.7071 -0.0000 +vn 0.0000 0.7764 0.6303 +vn -1.0000 -0.0000 -0.0000 +vn -0.7764 0.0000 0.6303 +vn 0.0000 -1.0000 0.0000 +vn 0.7764 0.0000 0.6303 +vn -0.7071 0.7071 -0.0000 +usemtl None +s off +f 57/123/29 58/124/29 100/125/29 +f 90/126/30 59/127/30 97/128/30 +f 61/129/29 98/130/29 62/131/29 +f 63/132/29 64/133/29 65/134/29 +f 66/135/29 64/133/29 58/124/29 +f 67/136/29 100/125/29 68/137/29 +f 61/129/29 104/138/29 88/139/29 +f 67/136/29 98/130/29 86/140/29 +f 88/139/29 102/141/29 63/132/29 +f 92/142/30 99/143/30 69/144/30 +f 94/145/30 101/146/30 70/147/30 +f 71/148/30 101/146/30 72/149/30 +f 90/126/30 103/150/30 73/151/30 +f 92/142/30 59/127/30 74/152/30 +f 69/144/30 75/153/30 94/145/30 +f 96/154/30 72/149/30 103/150/30 +f 57/123/29 66/135/29 58/124/29 +f 90/126/30 73/151/30 59/127/30 +f 61/129/29 86/140/29 98/130/29 +f 63/132/29 102/141/29 64/133/29 +f 66/135/29 65/134/29 64/133/29 +f 67/136/29 57/123/29 100/125/29 +f 61/129/29 62/131/29 104/138/29 +f 67/136/29 68/137/29 98/130/29 +f 88/139/29 104/138/29 102/141/29 +f 92/142/30 74/152/30 99/143/30 +f 94/145/30 75/153/30 101/146/30 +f 71/148/30 70/147/30 101/146/30 +f 90/126/30 96/154/30 103/150/30 +f 92/142/30 97/128/30 59/127/30 +f 69/144/30 99/143/30 75/153/30 +f 96/154/30 71/148/30 72/149/30 +f 87/155/31 61/156/31 88/157/31 +f 89/158/32 65/159/32 83/160/32 +f 63/161/33 87/162/33 88/163/33 +f 61/156/34 85/164/34 86/165/34 +f 84/166/35 57/167/35 67/168/35 +f 84/166/36 86/169/36 85/170/36 +f 57/171/37 82/172/37 66/173/37 +f 83/160/38 66/173/38 82/172/38 +f 89/174/30 82/175/30 84/176/30 +f 87/155/31 80/177/31 61/156/31 +f 89/158/32 63/161/32 65/159/32 +f 63/161/33 89/158/33 87/162/33 +f 61/156/34 80/177/34 85/164/34 +f 84/166/35 81/178/35 57/167/35 +f 84/166/36 67/168/36 86/169/36 +f 57/171/37 81/179/37 82/172/37 +f 83/160/38 65/159/38 66/173/38 +f 84/176/30 85/180/30 80/181/30 +f 80/181/30 87/182/30 89/174/30 +f 89/174/30 83/183/30 82/175/30 +f 82/175/30 81/184/30 84/176/30 +f 84/176/30 80/181/30 89/174/30 +s 1 +f 76/185/39 93/186/40 78/187/41 +f 90/188/42 91/189/43 79/190/44 +f 69/191/45 76/192/39 92/193/46 +f 70/194/47 93/195/40 94/196/48 +f 70/197/47 78/198/41 95/199/49 +f 96/200/50 79/190/44 77/201/51 +f 92/193/46 91/202/43 97/203/52 +f 94/196/48 60/204/53 69/205/45 +f 71/206/54 77/207/51 78/198/41 +f 74/208/46 98/209/52 68/210/46 +f 59/211/52 62/212/42 98/213/52 +f 99/214/45 68/210/46 100/215/45 +f 75/216/48 100/217/45 58/218/48 +f 101/219/47 58/218/48 64/220/47 +f 72/221/54 64/222/47 102/223/54 +f 103/224/50 102/223/54 104/225/50 +f 73/226/42 104/227/50 62/212/42 +f 90/188/42 97/228/52 91/189/43 +f 69/191/45 60/229/53 76/192/39 +f 70/194/47 95/230/49 93/195/40 +f 70/197/47 71/206/54 78/198/41 +f 96/200/50 90/188/42 79/190/44 +f 92/193/46 76/192/39 91/202/43 +f 94/196/48 93/195/40 60/204/53 +f 71/206/54 96/231/50 77/207/51 +f 74/208/46 59/232/52 98/209/52 +f 59/211/52 73/226/42 62/212/42 +f 99/214/45 74/208/46 68/210/46 +f 75/216/48 99/233/45 100/217/45 +f 101/219/47 75/216/48 58/218/48 +f 72/221/54 101/234/47 64/222/47 +f 103/224/50 72/221/54 102/223/54 +f 73/226/42 103/235/50 104/227/50 +f 78/187/41 77/236/51 79/237/44 +f 79/237/44 91/238/43 76/185/39 +f 76/185/39 60/239/53 93/186/40 +f 93/186/40 95/240/49 78/187/41 +f 78/187/41 79/237/44 76/185/39 +o Brass_Bottleneck_Casing.002 +v 0.300002 -0.000003 0.685047 +v 0.185616 0.185613 0.685047 +v -0.000000 -0.262503 0.735047 +v 0.300002 -0.000001 0.785047 +v -0.212132 -0.212133 0.685047 +v -0.185614 -0.185617 0.685047 +v -0.212132 0.212131 0.685047 +v -0.000000 0.262499 0.685047 +v -0.000000 0.299999 0.685047 +v 0.212132 0.212131 0.685047 +v 0.212132 -0.212133 0.685047 +v 0.185616 -0.185617 0.685047 +v 0.300002 -0.000003 0.735047 +v -0.000000 0.299999 0.735047 +v -0.212132 0.212131 0.735047 +v -0.185614 0.185613 0.735047 +v -0.185614 -0.185617 0.735047 +v 0.185616 -0.185617 0.735047 +v 0.185616 0.185613 0.735047 +v 0.212132 -0.212133 0.785047 +v -0.300000 -0.000001 0.785047 +v -0.212132 0.212131 0.785047 +v -0.212132 -0.212133 0.785047 +v -0.000000 -0.300001 0.685047 +v -0.300000 -0.000003 0.685047 +v -0.212132 -0.212133 0.735047 +v -0.000000 -0.300001 0.785047 +v 0.212132 -0.212133 0.735047 +v 0.212132 0.212131 0.785047 +v 0.212132 0.212131 0.735047 +v -0.000000 0.299999 0.785047 +v -0.300000 -0.000003 0.735047 +v -0.000000 -0.300001 0.735047 +v -0.000000 -0.262503 0.685047 +v 0.262502 -0.000003 0.735047 +v 0.262502 -0.000003 0.685047 +v -0.000000 0.262499 0.735047 +v -0.185614 0.185613 0.685047 +v -0.262500 -0.000003 0.735047 +v -0.262500 -0.000003 0.685047 +v -0.135596 -0.135597 -0.764953 +v -0.212132 -0.212133 -0.414953 +v 0.191762 -0.000003 -0.764953 +v 0.300002 -0.000003 -0.414953 +v 0.212132 0.212131 -0.414953 +v 0.135595 0.135594 -0.764953 +v -0.000000 0.299999 -0.414953 +v -0.000000 0.191760 -0.764953 +v 0.135596 -0.135596 -0.764953 +v 0.212132 -0.212133 -0.414953 +v -0.000000 -0.191762 -0.764953 +v -0.000000 -0.300001 -0.414953 +v -0.191761 -0.000003 -0.764953 +v -0.300000 -0.000003 -0.414953 +v -0.212132 0.212131 -0.414953 +v -0.135595 0.135594 -0.764953 +v -0.000000 -0.191762 -1.014953 +v 0.135596 -0.135596 -1.014953 +v -0.135595 0.135594 -1.014953 +v -0.191761 -0.000003 -1.014953 +v -0.000000 0.191760 -1.014953 +v 0.135595 0.135594 -1.014953 +v -0.135596 -0.135597 -1.014953 +v 0.191762 -0.000003 -1.014953 +vt 0.630972 0.689316 +vt 0.635004 0.664263 +vt 0.635004 0.687646 +vt 0.760004 0.662592 +vt 0.739438 0.647728 +vt 0.741108 0.643696 +vt 0.695488 0.689316 +vt 0.674922 0.704180 +vt 0.691456 0.687645 +vt 0.676592 0.643696 +vt 0.651539 0.647728 +vt 0.649868 0.643696 +vt 0.630972 0.662592 +vt 0.649869 0.708212 +vt 0.651539 0.704180 +vt 0.691456 0.664263 +vt 0.695488 0.662592 +vt 0.676592 0.708212 +vt 0.674922 0.647728 +vt 0.714385 0.643696 +vt 0.699521 0.664262 +vt 0.695488 0.662592 +vt 0.695488 0.689316 +vt 0.716055 0.704180 +vt 0.714385 0.708212 +vt 0.741108 0.708212 +vt 0.739438 0.704180 +vt 0.755972 0.687645 +vt 0.755972 0.664262 +vt 0.716055 0.647728 +vt 0.699521 0.687645 +vt 0.760005 0.689316 +vt 0.565094 0.763968 +vt 0.437169 0.737244 +vt 0.565094 0.737244 +vt 0.395530 0.665471 +vt 0.366932 0.677549 +vt 0.366456 0.665471 +vt 0.436423 0.653832 +vt 0.565094 0.672728 +vt 0.437169 0.672728 +vt 0.436423 0.718348 +vt 0.565094 0.699452 +vt 0.564349 0.718348 +vt 0.436423 0.718348 +vt 0.565094 0.627109 +vt 0.436423 0.608212 +vt 0.564349 0.608212 +vt 0.436423 0.782864 +vt 0.564348 0.782864 +vt 0.437168 0.627109 +vt 0.565094 0.653832 +vt 0.437168 0.653832 +vt 0.396006 0.677549 +vt 0.396006 0.631929 +vt 0.395530 0.619851 +vt 0.396006 0.649011 +vt 0.395530 0.729986 +vt 0.396006 0.742065 +vt 0.437169 0.699452 +vt 0.396006 0.694631 +vt 0.396006 0.759147 +vt 0.437169 0.763968 +vt 0.818608 0.930835 +vt 0.866923 0.814195 +vt 0.983563 0.862509 +vt 0.366456 0.729986 +vt 0.395530 0.706709 +vt 0.366932 0.694631 +vt 0.395530 0.771225 +vt 0.366932 0.759147 +vt 0.366932 0.742065 +vt 0.366932 0.631929 +vt 0.366456 0.619851 +vt 0.564349 0.653832 +vt 0.564349 0.718348 +vt 0.983563 0.930836 +vt 0.935248 0.979150 +vt 0.866923 0.979150 +vt 0.818608 0.862509 +vt 0.935250 0.814194 +vt 0.366456 0.706709 +vt 0.366456 0.771225 +vt 0.366932 0.649011 +vt 0.078761 0.848420 +vt 0.151753 0.878654 +vt 0.121519 0.951645 +vt 0.714385 0.637881 +vt 0.741108 0.643696 +vt 0.714385 0.643696 +vt 0.585352 0.637881 +vt 0.566456 0.642951 +vt 0.566456 0.637136 +vt 0.630972 0.637136 +vt 0.612076 0.643696 +vt 0.612076 0.637881 +vt 0.760099 0.660723 +vt 0.786724 0.666973 +vt 0.760004 0.666537 +vt 0.695488 0.637136 +vt 0.695488 0.642951 +vt 0.760004 0.637136 +vt 0.741108 0.637881 +vt 0.585352 0.643696 +vt 0.786819 0.661159 +vt 0.805630 0.666537 +vt 0.816456 0.643044 +vt 0.799922 0.637881 +vt 0.816456 0.637229 +vt 0.799922 0.643696 +vt 0.776539 0.637881 +vt 0.655571 0.643696 +vt 0.639037 0.637229 +vt 0.655571 0.637881 +vt 0.678954 0.643696 +vt 0.678954 0.637881 +vt 0.695488 0.643044 +vt 0.695488 0.637229 +vt 0.783384 0.660723 +vt 0.760099 0.654527 +vt 0.783479 0.654909 +vt 0.799927 0.660341 +vt 0.800022 0.654527 +vt 0.776539 0.643696 +vt 0.760004 0.637229 +vt 0.630972 0.642951 +vt 0.760004 0.642951 +vt 0.805725 0.660723 +vt 0.639037 0.643044 +vt 0.760004 0.660341 +vt 0.760004 0.643044 +vt 0.078761 0.951645 +vt 0.048527 0.921411 +vt 0.048527 0.878654 +vt 0.121519 0.848420 +vt 0.151753 0.921411 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.9239 0.3827 0.0000 +vn 0.3827 -0.9239 0.0000 +vn -0.9239 -0.3827 -0.0000 +vn 0.3827 0.9239 0.0000 +vn -0.9239 0.3827 0.0000 +vn 0.9239 -0.3827 -0.0000 +vn -0.3827 0.9239 0.0000 +vn 0.3680 -0.8883 -0.2747 +vn -0.8883 0.3680 -0.2747 +vn -0.3680 0.8883 -0.2747 +vn 0.3680 0.8883 -0.2747 +vn -0.3680 -0.8883 -0.2747 +vn 0.8883 -0.3680 -0.2747 +vn -0.8883 -0.3680 -0.2747 +vn 0.8883 0.3680 -0.2747 +vn -0.3827 -0.9239 -0.0000 +vn 0.5490 -0.5490 0.6303 +vn 0.5490 0.5490 0.6303 +vn -0.5490 0.5490 0.6303 +vn -0.7071 -0.7071 0.0000 +vn -0.0000 -0.7764 0.6303 +vn -0.5490 -0.5490 0.6303 +vn 1.0000 -0.0000 -0.0000 +vn 0.7071 -0.7071 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.7071 0.7071 -0.0000 +vn 0.0000 0.7764 0.6303 +vn -1.0000 -0.0000 -0.0000 +vn -0.7764 0.0000 0.6303 +vn 0.0000 -1.0000 0.0000 +vn 0.7764 0.0000 0.6303 +vn -0.7071 0.7071 -0.0000 +usemtl None +s off +f 105/241/55 106/242/55 140/243/55 +f 130/244/56 107/245/56 137/246/56 +f 109/247/55 138/248/55 110/249/55 +f 111/250/55 112/251/55 113/252/55 +f 114/253/55 112/251/55 106/242/55 +f 115/254/55 140/243/55 116/255/55 +f 109/247/55 144/256/55 129/257/55 +f 115/254/55 138/248/55 128/258/55 +f 129/257/55 142/259/55 111/250/55 +f 132/260/56 139/261/56 117/262/56 +f 134/263/56 141/264/56 118/265/56 +f 119/266/56 141/264/56 120/267/56 +f 130/244/56 143/268/56 121/269/56 +f 132/260/56 107/245/56 122/270/56 +f 117/262/56 123/271/56 134/263/56 +f 136/272/56 120/267/56 143/268/56 +f 105/273/57 149/274/57 114/275/57 +f 105/241/55 114/253/55 106/242/55 +f 130/244/56 121/269/56 107/245/56 +f 109/247/55 128/258/55 138/248/55 +f 111/250/55 142/259/55 112/251/55 +f 114/253/55 113/252/55 112/251/55 +f 115/254/55 105/241/55 140/243/55 +f 109/247/55 110/249/55 144/256/55 +f 115/254/55 116/255/55 138/248/55 +f 129/257/55 144/256/55 142/259/55 +f 132/260/56 122/270/56 139/261/56 +f 134/263/56 123/271/56 141/264/56 +f 119/266/56 118/265/56 141/264/56 +f 130/244/56 136/272/56 143/268/56 +f 132/260/56 137/246/56 107/245/56 +f 117/262/56 139/261/56 123/271/56 +f 136/272/56 119/266/56 120/267/56 +f 153/276/58 161/277/58 162/278/58 +f 154/279/58 128/280/58 156/281/58 +f 158/282/59 109/283/59 129/284/59 +f 151/285/60 114/275/60 149/274/60 +f 111/286/61 158/287/61 129/288/61 +f 154/289/62 105/273/62 115/290/62 +f 159/291/63 113/292/63 151/293/63 +f 154/279/64 155/294/64 153/276/64 +f 158/287/65 160/295/65 157/296/65 +f 160/295/66 151/293/66 152/297/66 +f 152/298/67 149/274/67 150/299/67 +f 155/294/68 146/300/68 145/301/68 +f 154/289/69 147/302/69 148/303/69 +f 158/282/70 145/301/70 146/300/70 +f 147/302/71 149/274/71 148/303/71 +f 109/283/72 156/281/72 128/280/72 +f 163/304/56 166/305/56 162/306/56 +f 150/299/60 165/307/60 152/298/60 +f 157/308/59 167/309/59 145/301/59 +f 153/310/62 168/311/62 147/302/62 +f 145/301/72 161/277/72 155/294/72 +f 150/299/57 168/311/57 166/312/57 +f 152/297/63 163/313/63 160/295/63 +f 160/295/61 164/314/61 157/296/61 +f 105/273/57 148/303/57 149/274/57 +f 153/276/58 155/294/58 161/277/58 +f 154/279/58 115/315/58 128/280/58 +f 158/282/59 146/300/59 109/283/59 +f 151/285/60 113/316/60 114/275/60 +f 111/286/61 159/291/61 158/287/61 +f 154/289/62 148/303/62 105/273/62 +f 159/291/63 111/286/63 113/292/63 +f 154/279/64 156/281/64 155/294/64 +f 158/287/65 159/291/65 160/295/65 +f 160/295/66 159/291/66 151/293/66 +f 152/298/67 151/285/67 149/274/67 +f 155/294/68 156/281/68 146/300/68 +f 154/289/69 153/310/69 147/302/69 +f 158/282/70 157/308/70 145/301/70 +f 147/302/71 150/299/71 149/274/71 +f 109/283/72 146/300/72 156/281/72 +f 162/306/56 161/317/56 163/304/56 +f 161/317/56 167/318/56 163/304/56 +f 167/318/56 164/319/56 163/304/56 +f 163/304/56 165/320/56 166/305/56 +f 166/305/56 168/321/56 162/306/56 +f 150/299/60 166/312/60 165/307/60 +f 157/308/59 164/322/59 167/309/59 +f 153/310/62 162/323/62 168/311/62 +f 145/301/72 167/309/72 161/277/72 +f 150/299/57 147/302/57 168/311/57 +f 152/297/63 165/324/63 163/313/63 +f 160/295/61 163/313/61 164/314/61 +s 1 +f 124/325/73 133/326/74 126/327/75 +f 130/328/76 131/329/77 127/330/78 +f 117/331/79 124/332/73 132/333/80 +f 118/334/81 133/335/74 134/336/82 +f 118/337/81 126/338/75 135/339/83 +f 136/340/84 127/330/78 125/341/85 +f 132/342/80 131/329/77 137/343/86 +f 134/336/82 108/344/87 117/331/79 +f 119/345/88 125/346/85 126/338/75 +f 122/347/80 138/348/86 116/349/80 +f 107/350/86 110/351/76 138/348/86 +f 139/352/79 116/353/80 140/354/79 +f 123/355/82 140/354/79 106/356/82 +f 141/357/81 106/356/82 112/358/81 +f 120/359/88 112/360/81 142/361/88 +f 143/362/84 142/361/88 144/363/84 +f 121/364/76 144/365/84 110/351/76 +f 130/328/76 137/343/86 131/329/77 +f 117/331/79 108/344/87 124/332/73 +f 118/334/81 135/366/83 133/335/74 +f 118/337/81 119/345/88 126/338/75 +f 136/340/84 130/328/76 127/330/78 +f 132/342/80 124/367/73 131/329/77 +f 134/336/82 133/335/74 108/344/87 +f 119/345/88 136/368/84 125/346/85 +f 122/347/80 107/350/86 138/348/86 +f 107/350/86 121/364/76 110/351/76 +f 139/352/79 122/369/80 116/353/80 +f 123/355/82 139/352/79 140/354/79 +f 141/357/81 123/355/82 106/356/82 +f 120/359/88 141/370/81 112/360/81 +f 143/362/84 120/359/88 142/361/88 +f 121/364/76 143/371/84 144/365/84 +f 126/327/75 125/372/85 127/373/78 +f 127/373/78 131/374/77 124/325/73 +f 124/325/73 108/375/87 133/326/74 +f 133/326/74 135/376/83 126/327/75 +f 126/327/75 127/373/78 124/325/73 diff --git a/src/main/resources/assets/hbm/textures/particle/casing_ar2.png b/src/main/resources/assets/hbm/textures/particle/casing_ar2.png new file mode 100644 index 0000000000000000000000000000000000000000..6186525b25b30e63df86617deb3cebf5edd1fe9f GIT binary patch literal 625 zcmV-%0*?KOP)EX>4Tx04R}tkv&MmKpe$iQ>8^K4ptFy$WWauh>AFB6^c+H)C#RSm|Xe=O&XFG z7e~Rh;NZt%)xpJCR|i)?5c~jfbaGO3krMxx6k5c1aNLh~_a1le0HI!Dn$k~y#OK6gCS8#Dk?V@fZ=CZE3p_Jyrjql-VPY}g#!4Hrf~gTt5l2)_r+gvp zvdVdjvsS9I<~{ifLs@-gnd>x%5yv8yAVGwJDvBtff+(#zDHf8nAM@}JIev*;3b~44 z0{s+IiwQ`daZc-=)biUa3#|RME1sXNm{yw(t#tGnm2Cnp$zg!1qK1r{& zw8# zjOHnO-Q(TC_TK(I)9mjD4|{Td$$uXW00006VoOIv01*HY01?xd?Dzlx010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru<_i`A7a42^lT`o!0B%V{K~y-)&C;_y$kEkaHF*?!6yx;K8OzOex6~t8;Ky8vaLZ?wE+C^5?JV00000 LNkvXXu0mjf)s_o$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/textures/particle/casing_tex.png b/src/main/resources/assets/hbm/textures/particle/casing_tex.png new file mode 100644 index 0000000000000000000000000000000000000000..e9ddbafa51b249f36c2795aff5d89ad6f97484b8 GIT binary patch literal 10168 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 Date: Tue, 20 Dec 2022 00:04:58 -0500 Subject: [PATCH 3/4] Fixes and tinkering Fixed offset rotation sorta, now casing align with the ejection port for the most part. Turrets still need work in this regard. Fixed some texture asset names. FBI shotgunners make spent casings, but they are jank since NPC rotations don't match with their rendered rotation for some reason (ie NPC is facing player when rendered visually, but the actual entity isn't). --- .../java/com/hbm/entity/mob/EntityFBI.java | 15 ++++ .../hbm/handler/guncfg/Gun12GaugeFactory.java | 49 ++++++----- .../hbm/handler/guncfg/Gun20GaugeFactory.java | 28 +++---- .../hbm/handler/guncfg/Gun22LRFactory.java | 3 +- .../handler/guncfg/Gun357MagnumFactory.java | 2 +- .../handler/guncfg/Gun44MagnumFactory.java | 2 +- .../hbm/handler/guncfg/Gun45ACPFactory.java | 6 +- .../hbm/handler/guncfg/Gun4GaugeFactory.java | 4 +- .../hbm/handler/guncfg/Gun50AEFactory.java | 4 +- .../hbm/handler/guncfg/Gun50BMGFactory.java | 12 ++- .../hbm/handler/guncfg/Gun556mmFactory.java | 4 +- .../hbm/handler/guncfg/Gun762mmFactory.java | 1 + .../com/hbm/handler/guncfg/Gun9mmFactory.java | 6 +- .../hbm/handler/guncfg/GunCannonFactory.java | 8 +- .../com/hbm/handler/guncfg/GunDGKFactory.java | 4 +- .../hbm/handler/guncfg/GunOSIPRFactory.java | 2 +- .../com/hbm/items/weapon/ItemAmmoArty.java | 52 +++++++----- .../com/hbm/particle/ParticleSpentCasing.java | 79 +++++++++++------- .../com/hbm/particle/SpentCasingConfig.java | 52 ++++++++---- .../particle/SpentCasingConfigBuilder.java | 1 + .../turret/TileEntityTurretArty.java | 3 + .../turret/TileEntityTurretBaseNT.java | 2 +- src/main/java/com/hbm/util/BobMathUtil.java | 8 +- ...{ammo_4gauge.png => ammo_4gauge.stock.png} | Bin .../{gun_pm_ammo.png => ammo_556.gold.png} | Bin ...arty.classic.png => ammo_arty_classic.png} | Bin .../{ammo_arty.he.png => ammo_arty_he.png} | Bin ....mini_nuke.png => ammo_arty_mini_nuke.png} | Bin ...ulti.png => ammo_arty_mini_nuke_multi.png} | Bin ...{ammo_arty.nuke.png => ammo_arty_nuke.png} | Bin ...hosphorus.png => ammo_arty_phosphorus.png} | Bin ...lti.png => ammo_arty_phosphorus_multi.png} | Bin 32 files changed, 224 insertions(+), 123 deletions(-) rename src/main/resources/assets/hbm/textures/items/{ammo_4gauge.png => ammo_4gauge.stock.png} (100%) rename src/main/resources/assets/hbm/textures/items/{gun_pm_ammo.png => ammo_556.gold.png} (100%) rename src/main/resources/assets/hbm/textures/items/{ammo_arty.classic.png => ammo_arty_classic.png} (100%) rename src/main/resources/assets/hbm/textures/items/{ammo_arty.he.png => ammo_arty_he.png} (100%) rename src/main/resources/assets/hbm/textures/items/{ammo_arty.mini_nuke.png => ammo_arty_mini_nuke.png} (100%) rename src/main/resources/assets/hbm/textures/items/{ammo_arty.mini_nuke_multi.png => ammo_arty_mini_nuke_multi.png} (100%) rename src/main/resources/assets/hbm/textures/items/{ammo_arty.nuke.png => ammo_arty_nuke.png} (100%) rename src/main/resources/assets/hbm/textures/items/{ammo_arty.phosphorus.png => ammo_arty_phosphorus.png} (100%) rename src/main/resources/assets/hbm/textures/items/{ammo_arty.phosphorus_multi.png => ammo_arty_phosphorus_multi.png} (100%) diff --git a/src/main/java/com/hbm/entity/mob/EntityFBI.java b/src/main/java/com/hbm/entity/mob/EntityFBI.java index fbbd5e6e6..7696f0097 100644 --- a/src/main/java/com/hbm/entity/mob/EntityFBI.java +++ b/src/main/java/com/hbm/entity/mob/EntityFBI.java @@ -9,7 +9,9 @@ import com.hbm.config.MobConfig; import com.hbm.entity.mob.ai.EntityAIBreaking; import com.hbm.entity.mob.ai.EntityAI_MLPF; import com.hbm.entity.projectile.EntityBullet; +import com.hbm.handler.guncfg.Gun4GaugeFactory; import com.hbm.items.ModItems; +import com.hbm.main.MainRegistry; import net.minecraft.block.Block; import net.minecraft.entity.EntityLivingBase; @@ -32,6 +34,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; @@ -145,6 +148,18 @@ public class EntityFBI extends EntityMob implements IRangedAttackMob { this.worldObj.spawnEntityInWorld(bullet); } this.playSound("hbm:weapon.shotgunShoot", 1.0F, 1.0F); + + // Casing stuff, not doing it in a method or anything because I'm gonna do that with the SNPC class. + final NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "casing"); + data.setDouble("posX", posX); + data.setDouble("posY", posY + getEyeHeight()); + data.setDouble("posZ", posZ); + data.setFloat("pitch", (float) Math.toRadians(rotationPitch)); + data.setFloat("yaw", (float) Math.toRadians(rotationYaw)); + data.setBoolean("crouched", isSneaking()); + data.setString("name", "4g"); + MainRegistry.proxy.effectNT(data); } } } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java index a22c378fb..a9ee91341 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java @@ -25,28 +25,33 @@ import net.minecraft.util.Vec3; public class Gun12GaugeFactory { - private static final SpentCasingConfigBuilder CASING_12G_BUILDER = new SpentCasingConfigBuilder("", CasingType.SHOTGUN, false) - .setScaleX(1.5f).setScaleY(1.5f).setScaleZ(1.5f); - static final SpentCasingConfig - CASING_SPAS = CASING_12G_BUILDER.setRegistryName("spas12").setPosOffset(new EasyLocation(1.5, 0, 0)) - .setInitialMotion(Vec3.createVectorHelper(-0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) - .setSmokeChance(0).setDelay(10) - .build(), - - CASING_SPAS_ALT = CASING_12G_BUILDER.setRegistryName("spas12alt").setCasingAmount(2) - .build(), - - CASING_BENELLI = CASING_12G_BUILDER.setRegistryName("benelli").setCasingAmount(1).setDelay(0) - .setInitialMotion(Vec3.createVectorHelper(-0.3, 1.1, 0)) - .build(), - - CASING_UBOINIK = CASING_12G_BUILDER.setRegistryName("uboinik").setOverrideColor(true) - .setBlueOverride(255) - .build(), - - CASING_SSG = CASING_12G_BUILDER.setRegistryName("ssg").setBlueOverride(0).setRedOverride(255).setCasingAmount(2) - .setPosOffset(new EasyLocation(-2, 0, 0)).setInitialMotion(Vec3.createVectorHelper(0.2, 0, -0.2)) - .build(); + static final SpentCasingConfig CASING_SPAS, CASING_SPAS_ALT, CASING_BENELLI, CASING_UBOINIK, CASING_SSG; + + static + { + final SpentCasingConfigBuilder CASING_12G_BUILDER = new SpentCasingConfigBuilder("", CasingType.SHOTGUN, false) + .setScaleX(1.5f).setScaleY(1.5f).setScaleZ(1.5f); + CASING_SPAS = CASING_12G_BUILDER.setRegistryName("spas12").setInitialMotion(Vec3.createVectorHelper(-0.4, 0.1, 0)) + .setPosOffset(new EasyLocation(-0.35, 0, 0.5)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setSmokeChance(0).setDelay(10) + .build(); + + CASING_SPAS_ALT = CASING_12G_BUILDER.setRegistryName("spas12alt").setCasingAmount(2) + .build(); + + CASING_BENELLI = CASING_12G_BUILDER.setRegistryName("benelli").setCasingAmount(1).setDelay(0) + .setInitialMotion(Vec3.createVectorHelper(-0.3, 1, 0)) + .build(); + + CASING_UBOINIK = CASING_12G_BUILDER.setRegistryName("uboinik").setOverrideColor(true) + .setBlueOverride(255).setPosOffset(new EasyLocation(-0.35, -0.3, 0.5)) + .build(); + + CASING_SSG = CASING_12G_BUILDER.setRegistryName("ssg").setBlueOverride(0).setRedOverride(255).setCasingAmount(2) + .setPosOffset(new EasyLocation(0.8, 0, 0)).setInitialMotion(Vec3.createVectorHelper(0.2, 0, -0.2)) + .setPitchFactor(0.05f).setYawFactor(0.02f) + .build(); + } public static GunConfiguration getSpas12Config() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java index 135254b75..d809071e8 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun20GaugeFactory.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Optional; import com.hbm.calc.EasyLocation; -import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; @@ -29,8 +28,8 @@ public class Gun20GaugeFactory { private static final SpentCasingConfigBuilder CASING_20G_BUILDER = new SpentCasingConfigBuilder("20g_lever", CasingType.SHOTGUN, false); static final SpentCasingConfig CASING_20G_LEVER = CASING_20G_BUILDER - .setPosOffset(new EasyLocation(1.5, 0, 0)) - .setInitialMotion(Vec3.createVectorHelper(-0.1, 0.95, 0)).setPitchFactor(0.05f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(-0.55, 0, 0.5)) + .setInitialMotion(Vec3.createVectorHelper(-0.4, 0.95, 0)).setPitchFactor(0.05f).setYawFactor(0.01f) .setSmokeChance(0) .build(); @@ -215,17 +214,18 @@ public class Gun20GaugeFactory { ) ); - config.config = new ArrayList(); - config.config.add(BulletConfigSyncingUtil.G20_SLUG_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_NORMAL_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_FLECHETTE_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_SHRAPNEL); - config.config.add(BulletConfigSyncingUtil.G20_EXPLOSIVE_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_CAUSTIC_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_SHOCK_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_WITHER_FIRE); - config.config.add(BulletConfigSyncingUtil.G20_SLEEK); +// config.config = new ArrayList(); +// config.config.add(BulletConfigSyncingUtil.G20_SLUG_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_NORMAL_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_FLECHETTE_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_SHRAPNEL); +// config.config.add(BulletConfigSyncingUtil.G20_EXPLOSIVE_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_CAUSTIC_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_SHOCK_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_WITHER_FIRE); +// config.config.add(BulletConfigSyncingUtil.G20_SLEEK); + config.config = HbmCollection.twentyGauge; config.casingConfig = Optional.of(CASING_20G_LEVER); diff --git a/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java index 57787fc5a..e5ecf60e4 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun22LRFactory.java @@ -21,7 +21,8 @@ public class Gun22LRFactory { static final SpentCasingConfig CASING_22LR = new SpentCasingConfigBuilder("22lr", CasingType.BRASS_STRAIGHT_WALL, false) .setSmokeChance(20).setScaleX(0.4f).setScaleY(0.4f).setScaleZ(0.4f) - .setInitialMotion(Vec3.createVectorHelper(-0.3, 1, 0)).setPitchFactor(0.03f).setYawFactor(0.01f).setPosOffset(new EasyLocation(1.5, 0, 0)) + .setInitialMotion(Vec3.createVectorHelper(-0.4, 0.1, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(-0.35, -0.2, 0.35)) .build(); public static GunConfiguration getUziConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java index 9ddc7721f..588d951b3 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java @@ -22,7 +22,7 @@ import net.minecraft.potion.PotionEffect; public class Gun357MagnumFactory { private static final SpentCasingConfigBuilder CASING_357_BUILDER = new SpentCasingConfigBuilder("357", CasingType.BRASS_STRAIGHT_WALL, false) - .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.1, 0)).setSmokeChance(6).setAfterReload(true); + .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.15, 0)).setSmokeChance(6).setAfterReload(true); static final SpentCasingConfig CASING_357 = CASING_357_BUILDER.build(), diff --git a/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java index 4c184270b..ad8f4f2d1 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java @@ -30,7 +30,7 @@ import net.minecraft.potion.PotionEffect; public class Gun44MagnumFactory { static final SpentCasingConfig CASING_44 = new SpentCasingConfigBuilder("44Magnum", CasingType.BRASS_STRAIGHT_WALL, false) - .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.1, 0)).setSmokeChance(6) + .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.15, 0)).setSmokeChance(6) .setAfterReload(true).setScaleX(1.25f).build(); public static GunConfiguration getBaseConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java index ffe301bef..9d0bf6d82 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java @@ -25,13 +25,13 @@ public class Gun45ACPFactory { private static final SpentCasingConfigBuilder CASING_45_BUILDER = new SpentCasingConfigBuilder("45acp", CasingType.BRASS_STRAIGHT_WALL, false) - .setSmokeChance(8).setInitialMotion(Vec3.createVectorHelper(-0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) - .setPosOffset(new EasyLocation(1.5, 0, 0)).setScaleZ(0.75f); + .setSmokeChance(8).setInitialMotion(Vec3.createVectorHelper(0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(-0.3, -0.25, 0.6)).setScaleZ(0.75f); static final SpentCasingConfig CASING_45 = CASING_45_BUILDER.build(), CASING_45_UAC = CASING_45_BUILDER.setRegistryName("45acp_UAC_Pistol") - .setInitialMotion(Vec3.createVectorHelper(0.3, 0.9, 0)).setPosOffset(new EasyLocation(1.5, -1, 0)) + .setInitialMotion(Vec3.createVectorHelper(0.3, 0.9, 0)) .build(); public static GunConfiguration getThompsonConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java index 9b2a769ed..9c88012e9 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun4GaugeFactory.java @@ -42,8 +42,8 @@ import net.minecraftforge.common.IExtendedEntityProperties; public class Gun4GaugeFactory { static final SpentCasingConfig CASING_4G = new SpentCasingConfigBuilder("4g", CasingType.SHOTGUN, false) - .setSmokeChance(0).setPosOffset(new EasyLocation(1.5, 0, 0)) - .setInitialMotion(Vec3.createVectorHelper(-0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setSmokeChance(0).setPosOffset(new EasyLocation(-0.5, 0, 0.5)) + .setInitialMotion(Vec3.createVectorHelper(-0.4, 0.4, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) .setScaleX(2.5f).setScaleY(2.5f).setScaleZ(2.5f).build(); private static GunConfiguration getShotgunConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java index c13ebb40e..ddbdff3fd 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java @@ -19,8 +19,8 @@ import net.minecraft.util.Vec3; public class Gun50AEFactory { static final SpentCasingConfig CASING_50AE = new SpentCasingConfigBuilder("50ae", CasingType.BRASS_STRAIGHT_WALL, false) - .setSmokeChance(4).setInitialMotion(Vec3.createVectorHelper(-0.3, 0.9, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) - .setPosOffset(new EasyLocation(1.5, 0, 0)).setScaleZ(1.5f).build(); + .setSmokeChance(4).setInitialMotion(Vec3.createVectorHelper(-0.3, 0.7, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(-0.5, 0, 0.5)).setScaleZ(1.5f).build(); public static GunConfiguration getBaseConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java index cb87223f4..0a0d0e758 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java @@ -37,13 +37,13 @@ public class Gun50BMGFactory { public static final SpentCasingConfig CONFIG_50BMG = new SpentCasingConfigBuilder("50bmg", CasingType.BRASS_BOTTLENECK, false) - .setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-0.4, 1, 0)).setScaleX(3).setScaleY(3).setScaleZ(3) - .setPosOffset(new EasyLocation(0.2, 0.2, -0.08)).setPitchFactor(0.1f).setYawFactor(0.01f) + .setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-0.35, 0.9, 0)).setScaleX(3).setScaleY(3).setScaleZ(3) + .setPosOffset(new EasyLocation(-0.45, -0.2, 0.35)).setPitchFactor(0.05f).setYawFactor(0.01f) .build(), CONFIG_LUNA = new SpentCasingConfigBuilder("luna", CasingType.BRASS_BOTTLENECK, true) - .setScaleX(4).setScaleY(4).setScaleZ(4).setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-2, 0, 0)) - .setPosOffset(new EasyLocation(0.5, 0.2, 0.08)).setRedOverride(11).setGreenOverride(97).setBlueOverride(109) + .setScaleX(4).setScaleY(4).setScaleZ(4).setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-2, 0.15, 0)) + .setPosOffset(new EasyLocation(-0.45, -0.2, 0.35)).setRedOverride(11).setGreenOverride(97).setBlueOverride(109) .setYawFactor(0.02f) .build(); @@ -85,6 +85,8 @@ public class Gun50BMGFactory { config.config = HbmCollection.fiftyBMG; + config.casingConfig = Optional.of(CONFIG_50BMG); + return config; } @@ -111,6 +113,8 @@ public class Gun50BMGFactory { config.config = HbmCollection.fiftyBMG; + config.casingConfig = Optional.of(CONFIG_50BMG); + return config; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java index 12265a75d..874d451c5 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java @@ -32,8 +32,8 @@ import net.minecraft.util.Vec3; public class Gun556mmFactory { static final SpentCasingConfig CONFIG_556 = new SpentCasingConfigBuilder("556", CasingType.BRASS_BOTTLENECK, false) - .setSmokeChance(4).setInitialMotion(Vec3.createVectorHelper(-0.3, 1, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) - .setPosOffset(new EasyLocation(1.5, 0, 0)).setScaleZ(1.5f) + .setSmokeChance(4).setInitialMotion(Vec3.createVectorHelper(-0.35, 0.6, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) + .setPosOffset(new EasyLocation(-0.35, 0, 0.35)).setScaleZ(1.5f) .build(); public static GunConfiguration getEuphieConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java index a9d3dce92..6591e9a72 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun762mmFactory.java @@ -18,6 +18,7 @@ import net.minecraft.potion.PotionEffect; public class Gun762mmFactory { + // TODO Confirm static final SpentCasingConfig CASING_762_NATO = Gun556mmFactory.CONFIG_556.toBuilder("762NATO").setSmokeChance(2).setScaleX(2) .setScaleZ(2.5f).build(); diff --git a/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java index fff5dc221..08a4f6024 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java @@ -3,6 +3,7 @@ package com.hbm.handler.guncfg; import java.util.ArrayList; import java.util.Optional; +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; import com.hbm.handler.GunConfiguration; @@ -17,9 +18,12 @@ import com.hbm.render.anim.BusAnimationSequence; import com.hbm.render.anim.HbmAnimations.AnimType; import com.hbm.render.util.RenderScreenOverlay.Crosshair; +import net.minecraft.util.Vec3; + public class Gun9mmFactory { - static final SpentCasingConfig CASING_9 = Gun45ACPFactory.CASING_45.toBuilder("9") + static final SpentCasingConfig CASING_9 = Gun45ACPFactory.CASING_45_UAC.toBuilder("9") + .setInitialMotion(Vec3.createVectorHelper(-0.3, 0.6, 0)).setPosOffset(new EasyLocation(-0.35, -0.2, 0.55)) .setScaleX(1).setScaleY(1).setScaleZ(0.6f).build(); public static GunConfiguration getMP40Config() { diff --git a/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java b/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java index bbf7f64da..ad62fdf50 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java @@ -16,13 +16,13 @@ import net.minecraft.util.Vec3; public class GunCannonFactory { private static final SpentCasingConfigBuilder CASING_CANNON_BUILDER = new SpentCasingConfigBuilder("240", CasingType.BRASS_BOTTLENECK, false) - .setInitialMotion(Vec3.createVectorHelper(0, 0.2, -1)).setPosOffset(new EasyLocation(0, 1.75, 0)).setSmokeChance(0) - .setScaleX(10).setScaleY(10).setScaleZ(10); + .setInitialMotion(Vec3.createVectorHelper(0, 0.2, -1)).setPosOffset(new EasyLocation(0, 1.75, -1.5)).setSmokeChance(0) + .setScaleX(10).setScaleY(10).setScaleZ(10).setPitchFactor(0.15f).setYawFactor(0.015f); public static final SpentCasingConfig CASING_240 = CASING_CANNON_BUILDER.build(), - CASING_16IN = CASING_CANNON_BUILDER.setRegistryName("16inch").setInitialMotion(Vec3.createVectorHelper(0, 1, -1.75)) - .setScaleX(20).setScaleY(20).setScaleZ(25) + CASING_16IN = CASING_CANNON_BUILDER.setRegistryName("16inch").setInitialMotion(Vec3.createVectorHelper(0, 2, -1.75)) + .setScaleX(20).setScaleY(20).setScaleZ(25).setCasingType(CasingType.BRASS_STRAIGHT_WALL) .build(); static final int stockPen = 10000; diff --git a/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java b/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java index 931578c99..db11ee141 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java @@ -1,5 +1,6 @@ package com.hbm.handler.guncfg; +import com.hbm.calc.EasyLocation; import com.hbm.handler.BulletConfiguration; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; @@ -10,7 +11,8 @@ import net.minecraft.util.Vec3; public class GunDGKFactory { public static final SpentCasingConfig CASING_DGK = Gun50BMGFactory.CONFIG_LUNA.toBuilder("dgk") - .setInitialMotion(Vec3.createVectorHelper(1, 1, 0)).setPosOffset(null).setOverrideColor(false) + .setInitialMotion(Vec3.createVectorHelper(0.8, 1, 0)).setPosOffset(new EasyLocation(0.15, 1.5, -1.5)) + .setOverrideColor(false).setPitchFactor(0.1f).setYawFactor(0.08f) .build(); public static BulletConfiguration getDGKConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java b/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java index 5c1b849ae..0829183a2 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java @@ -34,7 +34,7 @@ public class GunOSIPRFactory { static final SpentCasingConfig CASING_AR2 = new SpentCasingConfigBuilder("ar2", CasingType.AR2, false) .setSmokeChance(0).setInitialMotion(Vec3.createVectorHelper(-0.15, 0.2, 0)).setPitchFactor(0.02f) - .setAfterReload(true).setPosOffset(new EasyLocation(3.5, 0, 0)).build(); + .setAfterReload(true).setPosOffset(new EasyLocation(-0.4, 0, 0)).build(); public static GunConfiguration getOSIPRConfig() { diff --git a/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java b/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java index 803b44ed5..463207c36 100644 --- a/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java +++ b/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java @@ -41,17 +41,17 @@ import net.minecraft.util.Vec3; public class ItemAmmoArty extends Item { - public static ArtilleryShell[] itemTypes = new ArtilleryShell[ /* >>> */ 8 /* <<< */ ]; - public static ArtilleryShell[] shellTypes = new ArtilleryShell[ /* >>> */ 8 /* <<< */ ]; + public static final ArtilleryShell[] itemTypes = new ArtilleryShell[ /* >>> */ 8 /* <<< */ ]; + public static final ArtilleryShell[] shellTypes = new ArtilleryShell[ /* >>> */ 8 /* <<< */ ]; /* item types */ - public final int NORMAL = 0; - public final int CLASSIC = 1; - public final int EXPLOSIVE = 2; - public final int MINI_NUKE = 3; - public final int NUKE = 4; - public final int PHOSPHORUS = 5; - public final int MINI_NUKE_MULTI = 6; - public final int PHOSPHORUS_MULTI = 7; + public static final int NORMAL = 0; + public static final int CLASSIC = 1; + public static final int EXPLOSIVE = 2; + public static final int MINI_NUKE = 3; + public static final int NUKE = 4; + public static final int PHOSPHORUS = 5; + public static final int MINI_NUKE_MULTI = 6; + public static final int PHOSPHORUS_MULTI = 7; /* non-item shell types */ public ItemAmmoArty() { @@ -118,11 +118,13 @@ public class ItemAmmoArty extends Item { list.add(r + "(that is the best skull and crossbones"); list.add(r + "minecraft's unicode has to offer)"); break; + default: break; } } private IIcon[] icons = new IIcon[itemTypes.length]; + @Override @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister reg) { @@ -204,12 +206,16 @@ public class ItemAmmoArty extends Item { private void init() { /* STANDARD SHELLS */ - this.shellTypes[NORMAL] = this.itemTypes[NORMAL] = new ArtilleryShell("ammo_arty") { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 10F, 3F, false); }}; - this.shellTypes[CLASSIC] = this.itemTypes[CLASSIC] = new ArtilleryShell("ammo_arty_classic") { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 5F, false); }}; - this.shellTypes[EXPLOSIVE] = this.itemTypes[EXPLOSIVE] = new ArtilleryShell("ammo_arty_he") { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 3F, true); }}; + ItemAmmoArty.shellTypes[NORMAL] = ItemAmmoArty.itemTypes[NORMAL] = new ArtilleryShell("ammo_arty") { @Override + public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 10F, 3F, false); }}; + ItemAmmoArty.shellTypes[CLASSIC] = ItemAmmoArty.itemTypes[CLASSIC] = new ArtilleryShell("ammo_arty_classic") { @Override + public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 5F, false); }}; + ItemAmmoArty.shellTypes[EXPLOSIVE] = ItemAmmoArty.itemTypes[EXPLOSIVE] = new ArtilleryShell("ammo_arty_he") { @Override + public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 3F, true); }}; /* MINI NUKE */ - this.shellTypes[MINI_NUKE] = this.itemTypes[MINI_NUKE] = new ArtilleryShell("ammo_arty_mini_nuke") { + ItemAmmoArty.shellTypes[MINI_NUKE] = ItemAmmoArty.itemTypes[MINI_NUKE] = new ArtilleryShell("ammo_arty_mini_nuke") { + @Override public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { shell.killAndClear(); Vec3 vec = Vec3.createVectorHelper(shell.motionX, shell.motionY, shell.motionZ).normalize(); @@ -218,7 +224,8 @@ public class ItemAmmoArty extends Item { }; /* FULL NUKE */ - this.shellTypes[NUKE] = this.itemTypes[NUKE] = new ArtilleryShell("ammo_arty_nuke") { + ItemAmmoArty.shellTypes[NUKE] = ItemAmmoArty.itemTypes[NUKE] = new ArtilleryShell("ammo_arty_nuke") { + @Override public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { shell.worldObj.spawnEntityInWorld(EntityNukeExplosionMK4.statFac(shell.worldObj, BombConfig.missileRadius, mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord)); EntityNukeCloudSmall entity2 = new EntityNukeCloudSmall(shell.worldObj, 1000, BombConfig.missileRadius * 0.005F); @@ -231,7 +238,8 @@ public class ItemAmmoArty extends Item { }; /* PHOSPHORUS */ - this.shellTypes[PHOSPHORUS] = this.itemTypes[PHOSPHORUS] = new ArtilleryShell("ammo_arty_phosphorus") { + ItemAmmoArty.shellTypes[PHOSPHORUS] = ItemAmmoArty.itemTypes[PHOSPHORUS] = new ArtilleryShell("ammo_arty_phosphorus") { + @Override public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 10F, 3F, false); shell.worldObj.playSoundEffect(shell.posX, shell.posY, shell.posZ, "hbm:weapon.explosionMedium", 20.0F, 0.9F + shell.worldObj.rand.nextFloat() * 0.2F); @@ -260,12 +268,16 @@ public class ItemAmmoArty extends Item { }; /* CLUSTER SHELLS */ - this.shellTypes[PHOSPHORUS_MULTI] = this.itemTypes[PHOSPHORUS_MULTI] = new ArtilleryShell("ammo_arty_phosphorus_multi") { - public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { ItemAmmoArty.this.shellTypes[PHOSPHORUS].onImpact(shell, mop); } + ItemAmmoArty.shellTypes[PHOSPHORUS_MULTI] = ItemAmmoArty.itemTypes[PHOSPHORUS_MULTI] = new ArtilleryShell("ammo_arty_phosphorus_multi") { + @Override + public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { ItemAmmoArty.shellTypes[PHOSPHORUS].onImpact(shell, mop); } + @Override public void onUpdate(EntityArtilleryShell shell) { standardCluster(shell, PHOSPHORUS, 10, 300, 5); } }; - this.shellTypes[MINI_NUKE_MULTI] = this.itemTypes[MINI_NUKE_MULTI] = new ArtilleryShell("ammo_arty_mini_nuke_multi") { - public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { ItemAmmoArty.this.shellTypes[MINI_NUKE].onImpact(shell, mop); } + ItemAmmoArty.shellTypes[MINI_NUKE_MULTI] = ItemAmmoArty.itemTypes[MINI_NUKE_MULTI] = new ArtilleryShell("ammo_arty_mini_nuke_multi") { + @Override + public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { ItemAmmoArty.shellTypes[MINI_NUKE].onImpact(shell, mop); } + @Override public void onUpdate(EntityArtilleryShell shell) { standardCluster(shell, MINI_NUKE, 5, 300, 5); } }; } diff --git a/src/main/java/com/hbm/particle/ParticleSpentCasing.java b/src/main/java/com/hbm/particle/ParticleSpentCasing.java index e3f16c893..ae401cb95 100644 --- a/src/main/java/com/hbm/particle/ParticleSpentCasing.java +++ b/src/main/java/com/hbm/particle/ParticleSpentCasing.java @@ -20,7 +20,7 @@ import net.minecraft.world.World; @SideOnly(Side.CLIENT) public class ParticleSpentCasing extends EntityFX { - private static final float dScale = 0.05f, smokeOffset = 0.025f, gravity = -0.5f; + private static final float dScale = 0.05f, smokeJitter = 0.025f; private static final byte smokeAccel = 1; private final List> smokeNodes = new ArrayList>(); @@ -34,16 +34,22 @@ public class ParticleSpentCasing extends EntityFX private boolean onGroundPreviously = false; public ParticleSpentCasing(TextureManager textureManager, World world, double x, double y, double z, double mx, double my, double mz, float momentumPitch, float momentumYaw, SpentCasingConfig config) { - super(world, x, y, z, mx, my, mz); + super(world, x, y, z, 0, 0, 0); this.textureManager = textureManager; this.momentumPitch = momentumPitch; this.momentumYaw = momentumYaw; this.config = config; - particleMaxAge = 120; + particleMaxAge = 240; smoke = config.getSmokeChance() == 0 ? true : config.getSmokeChance() < 0 ? false : rand.nextInt(config.getSmokeChance()) == 0; + + motionX = mx; + motionY = my; + motionZ = mz; + + particleGravity = 8f; } @Override @@ -62,16 +68,13 @@ public class ParticleSpentCasing extends EntityFX else if (onGroundPreviously && !onGround) onGroundPreviously = false; - if (!config.getBounceSound().isEmpty()) - { - if (!onGroundPreviously && onGround) - worldObj.playSoundEffect(posX, posY, posZ, config.getBounceSound(), 1, 1); - } + if (!onGroundPreviously && onGround) + tryPlayBounceSound(); - if (particleAge > 90 && !smokeNodes.isEmpty()) + if (particleAge > 120 && !smokeNodes.isEmpty()) smokeNodes.clear(); - if (smoke && particleAge <= 90) + if (smoke && particleAge <= 120) { final double side = (rotationYaw - prevRotationYaw) * 0.1D; final Vec3 prev = Vec3.createVectorHelper(motionX, -motionY, motionZ); @@ -81,23 +84,25 @@ public class ParticleSpentCasing extends EntityFX { final EasyLocation node = pair.getKey(); - node.posX += prev.xCoord * smokeAccel + rand.nextGaussian() * smokeOffset + side; + node.posX += prev.xCoord * smokeAccel + rand.nextGaussian() * smokeJitter + side; node.posY += prev.yCoord + 1.5; - node.posZ += prev.zCoord * smokeAccel + rand.nextGaussian() * smokeOffset; + node.posZ += prev.zCoord * smokeAccel + rand.nextGaussian() * smokeJitter; } - final double alpha = (particleAge / 20d); - - smokeNodes.add(new Pair(EasyLocation.getZeroLocation(), alpha)); + if (particleAge < 60) + { + final double alpha = (particleAge / 20d); + smokeNodes.add(new Pair(EasyLocation.getZeroLocation(), alpha)); + } } prevRotationPitch = rotationPitch; prevRotationYaw = rotationYaw; - if (motionY > gravity && !onGround) - motionY += gravity; - if (motionY < -0.75) - motionY = -0.75; +// if (motionY > gravity && !onGround) +// motionY += gravity; +// if (motionY < -0.75) +// motionY = -0.75; if (onGround) rotationPitch = 0; @@ -128,17 +133,13 @@ public class ParticleSpentCasing extends EntityFX GL11.glScalef(dScale, dScale, dScale); - GL11.glScalef(config.getScaleX(), config.getScaleY(), config.getScaleZ()); - -// GL11.glRotatef(prevRotationYaw + (rotationYaw - prevRotationYaw), -// 0.0F, 1.0F, 0.0F); -// GL11.glRotatef(prevRotationPitch + (rotationPitch - prevRotationPitch), -// 0.0F, 0.0F, 1.0F); - GL11.glRotatef(180 - rotationYaw, 0, 1, 0); GL11.glRotatef(-rotationPitch, 1, 0, 0); + + GL11.glScalef(config.getScaleX(), config.getScaleY(), config.getScaleZ()); + if (config.doesOverrideColor()) - GL11.glColor3f(config.getRedOverride(), config.getBlueOverride(), config.getGreenOverride()); + GL11.glColor3b((byte) config.getRedOverride(), (byte) config.getGreenOverride(), (byte) config.getBlueOverride()); if (!smokeNodes.isEmpty()) { @@ -149,7 +150,7 @@ public class ParticleSpentCasing extends EntityFX { final Pair node = smokeNodes.get(i), past = smokeNodes.get(i + 1); final EasyLocation nodeLoc = node.getKey(), pastLoc = past.getKey(); - final float nodeAlpha = node.getValue().floatValue(), pastAlpha = past.getValue().floatValue(), scale = Math.max(config.getScaleX(), config.getScaleY()); + final float nodeAlpha = node.getValue().floatValue(), pastAlpha = past.getValue().floatValue(), scale = config.getScaleX(); tessellator.setColorRGBA_F(1F, 1F, 1F, nodeAlpha); tessellator.addVertex(nodeLoc.posX(), nodeLoc.posY(), nodeLoc.posZ()); @@ -183,4 +184,26 @@ public class ParticleSpentCasing extends EntityFX GL11.glShadeModel(GL11.GL_FLAT); GL11.glPopMatrix(); } + + private void tryPlayBounceSound() + { + if (!config.getBounceSound().isEmpty()) + worldObj.playSoundEffect(posX, posY, posZ, config.getBounceSound(), 1, 1); + } + +// private static float[] getOffset(float time) +// { +// final float sinVal1 = (float) ((Math.sin(time * 0.15) + Math.sin(time * 0.25 - 10) + Math.sin(time * 0.1 + 10)) / 3f), +// sinVal2 = (float) ((Math.sin(time * 0.1) + Math.sin(time * 0.05 + 20) + Math.sin(time * 0.13 + 20)) / 3f); +// +// return new float[] {BobMathUtil.remap(BobMathUtil.smoothStep(sinVal1, -1, 1), 0, 1, -2, 1.5F), BobMathUtil.remap(sinVal2, -1, 1, -0.03F, 0.05F)}; +// } +// +// private static float[] getJitter(float time) +// { +// final float sinVal1 = (float) ((Math.sin(time * 0.8) + Math.sin(time * 0.6 - 10) + Math.sin(time * 0.9 + 10)) / 3f), +// sinVal2 = (float) ((Math.sin(time * 0.3) + Math.sin(time * 0.2 + 20) + Math.sin(time * 0.1 + 20)) / 3f); +// +// return new float[] {BobMathUtil.remap(sinVal1, -1, 1, -3, 3), BobMathUtil.remap(sinVal2, -1, 1, -1F, 1F)}; +// } } diff --git a/src/main/java/com/hbm/particle/SpentCasingConfig.java b/src/main/java/com/hbm/particle/SpentCasingConfig.java index e0edaddfc..8fd314de4 100644 --- a/src/main/java/com/hbm/particle/SpentCasingConfig.java +++ b/src/main/java/com/hbm/particle/SpentCasingConfig.java @@ -99,39 +99,63 @@ public class SpentCasingConfig public void spawnCasing(TextureManager textureManager, World world, double x, double y, double z, float pitch, float yaw, boolean crouched) { final Vec3 rotatedMotionVec = rotateVector(getInitialMotion(), - pitch + (float) (RANDOM.nextGaussian() * pitchFactor * 0.5), - yaw + (float) (RANDOM.nextGaussian() * yawFactor * 0.5), - pitchFactor, yawFactor); + pitch + (float) RANDOM.nextGaussian() * getPitchFactor(), yaw + (float) RANDOM.nextGaussian() * getPitchFactor(), + getPitchFactor(), getPitchFactor()); final ParticleSpentCasing casing = new ParticleSpentCasing(textureManager, world, x, - y, z, 0, 0, 0, + y, z, rotatedMotionVec.xCoord, rotatedMotionVec.yCoord, rotatedMotionVec.zCoord, // 0, 0, (float) (getPitchFactor() * RANDOM.nextGaussian()), (float) (getYawFactor() * RANDOM.nextGaussian()), this); - casing.motionX = rotatedMotionVec.xCoord; - casing.motionY = rotatedMotionVec.yCoord; - casing.motionZ = rotatedMotionVec.zCoord; - - offsetCasing(casing, getPosOffset(), yaw, crouched); + offsetCasing(casing, getPosOffset(), pitch, yaw, crouched); casing.rotationPitch = (float) Math.toDegrees(pitch); casing.rotationYaw = (float) Math.toDegrees(yaw); if (overrideColor) - casing.setRBGColorF(redOverride, blueOverride, greenOverride); + casing.setRBGColorF(redOverride / 255f, blueOverride / 255f, greenOverride / 255f); Minecraft.getMinecraft().effectRenderer.addEffect(casing); } - private static void offsetCasing(ParticleSpentCasing casing, ILocationProvider offset, float yaw, boolean crouched) + // Rotate a position + private static void offsetCasing(ParticleSpentCasing casing, ILocationProvider offset, float pitch, float yaw, boolean crouched) { - casing.posX -= Math.cos(yaw) * offset.posX() + (crouched ? 0.16 : -0.05); - casing.posY -= offset.posY(); - casing.posZ -= Math.sin(yaw) * offset.posZ(); +// // x-axis offset, 0 if crouched to center +// final double oX = crouched ? 0 : offset.posX(); +// // Trigonometric operations, saved for convenience +// final double sinP = Math.sin(pitch), cosP = Math.cos(pitch), sinY = Math.sin(yaw), cosY = Math.cos(yaw); +// // New offsets +// final double newX = oX * cosY - offset.posZ() * sinY, +// newY = offset.posY() * cosP - sinP * (oX * sinY + offset.posZ() * cosY), +// newZ = offset.posZ() * sinP + cosP * (oX * sinY + offset.posZ() * cosY); +// +// // Apply +// casing.setPosition(casing.posX + newX, casing.posY + newY, casing.posZ + newZ); + + // x-axis offset, 0 if crouched to center + final float oX = (float) (crouched ? 0 : offset.posX()); + // Create rotation matrices for pitch and yaw + final Matrix4f pitchMatrix = new Matrix4f(), yawMatrix = new Matrix4f(); + + pitchMatrix.rotate(pitch, new Vector3f(1, 0, 0)); // modify axis of rotation + yawMatrix.rotate(-yaw, new Vector3f(0, 1, 0)); + + // Multiply matrices to get combined rotation matrix + final Matrix4f rotMatrix = Matrix4f.mul(yawMatrix, pitchMatrix, null); + // Create vector representing the offset and apply rotation + final Vector4f offsetVector = new Vector4f(oX, (float) offset.posY(), (float) offset.posZ(), 1); // set fourth coordinate to 1 + Matrix4f.transform(rotMatrix, offsetVector, offsetVector); + final Vector3f result = new Vector3f(); // create result vector + result.set(offsetVector.x, offsetVector.y, offsetVector.z); // set result vector using transformed coordinates + // Apply rotation + casing.setPosition(casing.posX + result.x, casing.posY + result.y, casing.posZ + result.z); } +// Rotate a vector private static Vec3 rotateVector(Vec3 vector, float pitch, float yaw, float pitchFactor, float yawFactor) { + // Apply randomness to vector vector.xCoord += RANDOM.nextGaussian() * yawFactor; vector.yCoord += RANDOM.nextGaussian() * pitchFactor; vector.zCoord += RANDOM.nextGaussian() * yawFactor; diff --git a/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java b/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java index a3f7368f3..9dc24c102 100644 --- a/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java +++ b/src/main/java/com/hbm/particle/SpentCasingConfigBuilder.java @@ -40,6 +40,7 @@ public class SpentCasingConfigBuilder implements Cloneable private byte delay; /**Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke.**/ private byte smokeChance = -1; + // TODO Setting to disregard crouch effect and/or another offset specifically for crouching which can be set to null to use the default one /** * Constructor with fields for the required bare minimum parameters.
* All parameters may overridden using setters at any time at your discretion, however. diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java index 026b21408..1d6dae6b5 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java @@ -204,6 +204,8 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen proj.setWhistle(true); worldObj.spawnEntityInWorld(proj); + + spawnCasing(); } @Override @@ -374,6 +376,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen data.setFloat("size", 0F); data.setByte("count", (byte)5); PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, pos.xCoord + vec.xCoord, pos.yCoord + vec.yCoord, pos.zCoord + vec.zCoord), new TargetPoint(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 150)); + } if(this.mode == MODE_MANUAL && !this.targetQueue.isEmpty()) { diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java index c53c9b283..6545cbce1 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java @@ -849,7 +849,7 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple final NBTTagCompound data = new NBTTagCompound(); data.setString("type", "casing"); data.setDouble("posX", xCoord); - data.setDouble("posY", yCoord + 0.5); + data.setDouble("posY", yCoord + 1); data.setDouble("posZ", zCoord); data.setFloat("pitch", (float) rotationPitch); data.setFloat("yaw", (float) rotationYaw); diff --git a/src/main/java/com/hbm/util/BobMathUtil.java b/src/main/java/com/hbm/util/BobMathUtil.java index 065142b57..51325f3b0 100644 --- a/src/main/java/com/hbm/util/BobMathUtil.java +++ b/src/main/java/com/hbm/util/BobMathUtil.java @@ -81,6 +81,12 @@ public class BobMathUtil { return MathHelper.clamp_float((num - min1) / (max1 - min1), 0, 1); } + public static float smoothStep(float f, float lower, float upper) + { + final float t = MathHelper.clamp_float((f - lower) / (upper - lower), 0, 1); + return t * t * (3f - 2f * t); + } + public static ForgeDirection[] getShuffledDirs() { ForgeDirection[] dirs = new ForgeDirection[6]; @@ -94,7 +100,7 @@ public class BobMathUtil { return dirs; } - public static String toPercentage(float amount, float total) { + public static String toPercentage(double amount, double total) { return NumberFormat.getPercentInstance().format(amount / total); } diff --git a/src/main/resources/assets/hbm/textures/items/ammo_4gauge.png b/src/main/resources/assets/hbm/textures/items/ammo_4gauge.stock.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_4gauge.png rename to src/main/resources/assets/hbm/textures/items/ammo_4gauge.stock.png diff --git a/src/main/resources/assets/hbm/textures/items/gun_pm_ammo.png b/src/main/resources/assets/hbm/textures/items/ammo_556.gold.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/gun_pm_ammo.png rename to src/main/resources/assets/hbm/textures/items/ammo_556.gold.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_arty.classic.png b/src/main/resources/assets/hbm/textures/items/ammo_arty_classic.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_arty.classic.png rename to src/main/resources/assets/hbm/textures/items/ammo_arty_classic.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_arty.he.png b/src/main/resources/assets/hbm/textures/items/ammo_arty_he.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_arty.he.png rename to src/main/resources/assets/hbm/textures/items/ammo_arty_he.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_arty.mini_nuke.png b/src/main/resources/assets/hbm/textures/items/ammo_arty_mini_nuke.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_arty.mini_nuke.png rename to src/main/resources/assets/hbm/textures/items/ammo_arty_mini_nuke.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_arty.mini_nuke_multi.png b/src/main/resources/assets/hbm/textures/items/ammo_arty_mini_nuke_multi.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_arty.mini_nuke_multi.png rename to src/main/resources/assets/hbm/textures/items/ammo_arty_mini_nuke_multi.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_arty.nuke.png b/src/main/resources/assets/hbm/textures/items/ammo_arty_nuke.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_arty.nuke.png rename to src/main/resources/assets/hbm/textures/items/ammo_arty_nuke.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_arty.phosphorus.png b/src/main/resources/assets/hbm/textures/items/ammo_arty_phosphorus.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_arty.phosphorus.png rename to src/main/resources/assets/hbm/textures/items/ammo_arty_phosphorus.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_arty.phosphorus_multi.png b/src/main/resources/assets/hbm/textures/items/ammo_arty_phosphorus_multi.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_arty.phosphorus_multi.png rename to src/main/resources/assets/hbm/textures/items/ammo_arty_phosphorus_multi.png From 57f9bbf404e185f49742ea10277037e08574e2aa Mon Sep 17 00:00:00 2001 From: UFFR Date: Wed, 21 Dec 2022 21:47:02 -0500 Subject: [PATCH 4/4] Tinkering + config More tinkering, also tried to implement bounce sound effects, but they don't seem to work. Added a config to disable casings. Commented out smoke effect because it wasn't working out. --- .../java/com/hbm/config/WeaponConfig.java | 4 + .../handler/guncfg/BulletConfigFactory.java | 2 + .../handler/guncfg/Gun357MagnumFactory.java | 3 +- .../handler/guncfg/Gun44MagnumFactory.java | 2 +- .../hbm/handler/guncfg/Gun45ACPFactory.java | 2 +- .../hbm/handler/guncfg/Gun50AEFactory.java | 2 +- .../hbm/handler/guncfg/Gun50BMGFactory.java | 64 +- .../hbm/handler/guncfg/Gun556mmFactory.java | 54 +- .../com/hbm/handler/guncfg/Gun9mmFactory.java | 2 +- .../hbm/handler/guncfg/GunGrenadeFactory.java | 2 +- .../java/com/hbm/items/ItemAmmoEnums.java | 6 +- .../com/hbm/items/weapon/ItemGunBase.java | 2 +- src/main/java/com/hbm/lib/Library.java | 21 + src/main/java/com/hbm/main/ClientProxy.java | 720 ++++++++++++++++-- src/main/java/com/hbm/main/ServerProxy.java | 67 +- .../com/hbm/particle/ParticleSpentCasing.java | 85 ++- .../com/hbm/particle/SpentCasingConfig.java | 2 +- src/main/java/com/hbm/util/ParticleUtil.java | 25 + src/main/java/com/hbm/util/Quaternion.java | 302 -------- src/main/resources/assets/hbm/sounds.json | 4 + .../assets/hbm/sounds/weapon/BRASS_C1.ogg | Bin 0 -> 4717 bytes .../assets/hbm/sounds/weapon/BRASS_C2.ogg | Bin 0 -> 5281 bytes .../assets/hbm/sounds/weapon/BRASS_C3.ogg | Bin 0 -> 4961 bytes .../assets/hbm/sounds/weapon/BRASS_C4.ogg | Bin 0 -> 4530 bytes .../assets/hbm/sounds/weapon/BRASS_C5.ogg | Bin 0 -> 6288 bytes .../assets/hbm/sounds/weapon/DSAOUNC1.ogg | Bin 0 -> 7045 bytes .../assets/hbm/sounds/weapon/DSAOUNC2.ogg | Bin 0 -> 6466 bytes .../assets/hbm/sounds/weapon/DSAOUNC3.ogg | Bin 0 -> 6658 bytes .../assets/hbm/sounds/weapon/DSAOUNC4.ogg | Bin 0 -> 6812 bytes .../assets/hbm/sounds/weapon/DSBOUNC1.ogg | Bin 0 -> 4774 bytes .../assets/hbm/sounds/weapon/DSBOUNC2.ogg | Bin 0 -> 5963 bytes .../assets/hbm/sounds/weapon/DSBOUNC3.ogg | Bin 0 -> 5156 bytes .../assets/hbm/sounds/weapon/DSBOUNC4.ogg | Bin 0 -> 6548 bytes .../assets/hbm/sounds/weapon/DSSHELL1.ogg | Bin 0 -> 4721 bytes .../assets/hbm/sounds/weapon/DSSHELL2.ogg | Bin 0 -> 4582 bytes .../assets/hbm/sounds/weapon/DSSHELL3.ogg | Bin 0 -> 5715 bytes 36 files changed, 852 insertions(+), 519 deletions(-) delete mode 100644 src/main/java/com/hbm/util/Quaternion.java create mode 100644 src/main/resources/assets/hbm/sounds/weapon/BRASS_C1.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/BRASS_C2.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/BRASS_C3.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/BRASS_C4.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/BRASS_C5.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSAOUNC1.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSAOUNC2.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSAOUNC3.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSAOUNC4.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSBOUNC1.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSBOUNC2.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSBOUNC3.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSBOUNC4.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSSHELL1.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSSHELL2.ogg create mode 100644 src/main/resources/assets/hbm/sounds/weapon/DSSHELL3.ogg diff --git a/src/main/java/com/hbm/config/WeaponConfig.java b/src/main/java/com/hbm/config/WeaponConfig.java index 88c3dbdae..cf992059c 100644 --- a/src/main/java/com/hbm/config/WeaponConfig.java +++ b/src/main/java/com/hbm/config/WeaponConfig.java @@ -16,6 +16,8 @@ public class WeaponConfig { public static boolean dropCrys = true; public static boolean dropDead = true; + public static boolean spawnCasings = true; + public static void loadFromConfig(Configuration config) { final String CATEGORY_MISSILE = CommonConfig.CATEGORY_MISSILE; @@ -38,5 +40,7 @@ public class WeaponConfig { dropStar = CommonConfig.createConfigBool(config, CATEGORY_DROPS, "10.02_dropStar", "Whether rigged star blaster cells should explode when dropped", true); dropCrys = CommonConfig.createConfigBool(config, CATEGORY_DROPS, "10.04_dropCrys", "Whether xen crystals should move blocks when dropped", true); dropDead = CommonConfig.createConfigBool(config, CATEGORY_DROPS, "10.05_dropDead", "Whether dead man's explosives should explode when dropped", true); + + spawnCasings = CommonConfig.createConfigBool(config, CATEGORY_DROPS, "10.06_spawnCasings", "Should applicable guns spawn spent shell casings? (Disable if performance heavy)", true); } } diff --git a/src/main/java/com/hbm/handler/guncfg/BulletConfigFactory.java b/src/main/java/com/hbm/handler/guncfg/BulletConfigFactory.java index 0a8c4c274..3496811b5 100644 --- a/src/main/java/com/hbm/handler/guncfg/BulletConfigFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/BulletConfigFactory.java @@ -67,6 +67,8 @@ public class BulletConfigFactory { } + public static final float defaultSpread = 0.005f; + /// STANDARD CONFIGS /// //do not include damage or ammo public static BulletConfiguration standardBulletConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java index 588d951b3..cd6db534d 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun357MagnumFactory.java @@ -22,7 +22,8 @@ import net.minecraft.potion.PotionEffect; public class Gun357MagnumFactory { private static final SpentCasingConfigBuilder CASING_357_BUILDER = new SpentCasingConfigBuilder("357", CasingType.BRASS_STRAIGHT_WALL, false) - .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.15, 0)).setSmokeChance(6).setAfterReload(true); + .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.15, 0)).setSmokeChance(6).setAfterReload(true) + .setBounceSound("weapon.smallCasingBouncePB3"); static final SpentCasingConfig CASING_357 = CASING_357_BUILDER.build(), diff --git a/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java index ad8f4f2d1..ac287c724 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun44MagnumFactory.java @@ -31,7 +31,7 @@ public class Gun44MagnumFactory { static final SpentCasingConfig CASING_44 = new SpentCasingConfigBuilder("44Magnum", CasingType.BRASS_STRAIGHT_WALL, false) .setCasingAmount(6).setYawFactor(0.05f).setPosOffset(new EasyLocation(0, -0.15, 0)).setSmokeChance(6) - .setAfterReload(true).setScaleX(1.25f).build(); + .setAfterReload(true).setScaleX(1.25f).setBounceSound("weapon.smallCasingBouncePB3").build(); public static GunConfiguration getBaseConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java index 9d0bf6d82..5bede6b0a 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun45ACPFactory.java @@ -26,7 +26,7 @@ public class Gun45ACPFactory private static final SpentCasingConfigBuilder CASING_45_BUILDER = new SpentCasingConfigBuilder("45acp", CasingType.BRASS_STRAIGHT_WALL, false) .setSmokeChance(8).setInitialMotion(Vec3.createVectorHelper(0.3, 0.75, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) - .setPosOffset(new EasyLocation(-0.3, -0.25, 0.6)).setScaleZ(0.75f); + .setPosOffset(new EasyLocation(-0.3, -0.25, 0.6)).setScaleZ(0.75f).setBounceSound("weapon.smallCasingBouncePB3"); static final SpentCasingConfig CASING_45 = CASING_45_BUILDER.build(), diff --git a/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java index ddbdff3fd..da4785ef4 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun50AEFactory.java @@ -20,7 +20,7 @@ public class Gun50AEFactory { static final SpentCasingConfig CASING_50AE = new SpentCasingConfigBuilder("50ae", CasingType.BRASS_STRAIGHT_WALL, false) .setSmokeChance(4).setInitialMotion(Vec3.createVectorHelper(-0.3, 0.7, 0)).setPitchFactor(0.03f).setYawFactor(0.01f) - .setPosOffset(new EasyLocation(-0.5, 0, 0.5)).setScaleZ(1.5f).build(); + .setPosOffset(new EasyLocation(-0.5, 0, 0.5)).setScaleZ(1.5f).setBounceSound("weapon.smallCasingBouncePB3").build(); public static GunConfiguration getBaseConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java index 0a0d0e758..7737f4030 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun50BMGFactory.java @@ -241,8 +241,8 @@ public class Gun50BMGFactory { config.manufacturer = EnumGunManufacturer.ARMALITE; config.config = new ArrayList(); - config.config.addAll(HbmCollection.fiftyBMG); config.config.addAll(HbmCollection.fiftyBMGFlechette); + config.config.addAll(HbmCollection.fiftyBMG); config.casingConfig = Optional.of(CONFIG_50BMG); @@ -251,7 +251,7 @@ public class Gun50BMGFactory { public static GunConfiguration getM2Config() { - GunConfiguration config = getAR15Config().clone(); + GunConfiguration config = getAR15Config(); config.rateOfFire = 2; config.durability *= 10; @@ -286,17 +286,20 @@ public class Gun50BMGFactory { config.casingConfig = Optional.of(CONFIG_50BMG); + config.config.clear(); + config.config.addAll(HbmCollection.fiftyBMG); + config.config.addAll(HbmCollection.fiftyBMGFlechette); + return config; } - static final float inaccuracy = 0.0005F; - static byte i = 0; + static final float inaccuracy = 0.0005F, standardSpread = BulletConfigFactory.defaultSpread * inaccuracy; public static BulletConfiguration get50BMGConfig() { BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, 0); + bullet.spread = standardSpread; bullet.dmgMin = 50; bullet.dmgMax = 56; bullet.penetration = 120; @@ -306,10 +309,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGFireConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 1; bullet.dmgMin = 50; bullet.dmgMax = 56; bullet.penetration = 120; @@ -321,10 +323,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGPhosphorusConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 2; bullet.dmgMin = 50; bullet.dmgMax = 56; bullet.penetration = 75; @@ -354,10 +355,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGExplosiveConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 3; bullet.dmgMin = 90; bullet.dmgMax = 94; bullet.penetration = 100; @@ -369,10 +369,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGAPConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 4; bullet.dmgMin = 82; bullet.dmgMax = 88; bullet.penetration = 150; @@ -384,10 +383,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGDUConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 5; bullet.dmgMin = 90; bullet.dmgMax = 96; bullet.penetration = 200; @@ -399,10 +397,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGStarConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 6; bullet.dmgMin = 108; bullet.dmgMax = 112; bullet.penetration = 250; @@ -414,10 +411,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGSleekConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 8; bullet.dmgMin = 60; bullet.dmgMax = 80; bullet.penetration = 120; @@ -457,10 +453,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGFlechetteConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 9; bullet.dmgMin = 60; bullet.dmgMax = 64; bullet.penetration = 130; @@ -471,10 +466,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGFlechetteAMConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); - bullet.spread *= inaccuracy; + bullet.ammo.meta = 10; bullet.dmgMin = 70; bullet.dmgMax = 74; bullet.penetration = 140; @@ -495,9 +489,9 @@ public class Gun50BMGFactory { public static BulletConfiguration get50BMGFlechettePOConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get50BMGConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_50bmg, 1, i++); + bullet.ammo.meta = 11; bullet.spread *= inaccuracy; bullet.dmgMin = 70; bullet.dmgMax = 74; diff --git a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java index 874d451c5..43b6f13c8 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun556mmFactory.java @@ -12,6 +12,7 @@ import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ModItems; import com.hbm.lib.HbmCollection; import com.hbm.lib.HbmCollection.EnumGunManufacturer; +import com.hbm.lib.Library; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; import com.hbm.particle.SpentCasingConfig; @@ -62,16 +63,17 @@ public class Gun556mmFactory { config.comment.add("Why is this gun so sticky?"); config.config = new ArrayList(); - config.config.add(BulletConfigSyncingUtil.R556_NORMAL); - config.config.add(BulletConfigSyncingUtil.R556_GOLD); - config.config.add(BulletConfigSyncingUtil.R556_TRACER); - config.config.add(BulletConfigSyncingUtil.R556_PHOSPHORUS); - config.config.add(BulletConfigSyncingUtil.R556_AP); - config.config.add(BulletConfigSyncingUtil.R556_DU); - config.config.add(BulletConfigSyncingUtil.R556_STAR); - config.config.add(BulletConfigSyncingUtil.CHL_R556); - config.config.add(BulletConfigSyncingUtil.R556_SLEEK); - config.config.add(BulletConfigSyncingUtil.R556_K); + config.config.addAll(HbmCollection.NATO); +// config.config.add(BulletConfigSyncingUtil.R556_NORMAL); +// config.config.add(BulletConfigSyncingUtil.R556_GOLD); +// config.config.add(BulletConfigSyncingUtil.R556_TRACER); +// config.config.add(BulletConfigSyncingUtil.R556_PHOSPHORUS); +// config.config.add(BulletConfigSyncingUtil.R556_AP); +// config.config.add(BulletConfigSyncingUtil.R556_DU); +// config.config.add(BulletConfigSyncingUtil.R556_STAR); +// config.config.add(BulletConfigSyncingUtil.CHL_R556); +// config.config.add(BulletConfigSyncingUtil.R556_SLEEK); +// config.config.add(BulletConfigSyncingUtil.R556_K); config.casingConfig = Optional.of(CONFIG_556); @@ -169,8 +171,7 @@ public class Gun556mmFactory { config.manufacturer = EnumGunManufacturer.LUNA; config.comment.add("\"May you never reincarnate again\""); - config.config.addAll(HbmCollection.NATO); - config.config.addAll(HbmCollection.NATOFlechette); + config.config.addAll(Library.mergeWithoutDuplicates(HbmCollection.NATO, HbmCollection.NATOFlechette)); config.animations.put(AnimType.CYCLE, new BusAnimation() .addBus("RECOIL", new BusAnimationSequence() @@ -234,7 +235,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 1); + bullet.ammo.meta = 1; bullet.dmgMin = 250; bullet.dmgMax = 320; bullet.spread = 0.0F; @@ -246,7 +247,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 2); + bullet.ammo.meta = 2; bullet.wear = 15; bullet.incendiary = 5; bullet.doesPenetrate = false; @@ -274,7 +275,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 3); + bullet.ammo.meta = 3; bullet.dmgMin = 20; bullet.dmgMax = 26; bullet.penetration *= 1.5; @@ -288,7 +289,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 4); + bullet.ammo.meta = 4; bullet.dmgMin = 24; bullet.dmgMax = 32; bullet.penetration *= 2; @@ -302,7 +303,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 5); + bullet.ammo.meta = 5; bullet.dmgMin = 30; bullet.dmgMax = 36; bullet.penetration *= 2.5; @@ -316,7 +317,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 6); + bullet.ammo.meta = 7; bullet.dmgMin = 45; bullet.dmgMax = 50; bullet.wear = 10; @@ -357,7 +358,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 7); + bullet.ammo.meta = 8; bullet.vPFX = "reddust"; return bullet; @@ -367,7 +368,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 8); + bullet.ammo.meta = 9; bullet.dmgMin = 26; bullet.dmgMax = 32; bullet.penetration = 22; @@ -384,7 +385,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556FlechetteConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 9); + bullet.ammo.meta = 10; bullet.incendiary = 5; return bullet; @@ -394,7 +395,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556FlechetteConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 10); + bullet.ammo.meta = 11; bullet.incendiary = 5; PotionEffect eff = new PotionEffect(HbmPotion.phosphorus.id, 20 * 20, 0, true); @@ -420,7 +421,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556FlechetteConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 11); + bullet.ammo.meta = 12; bullet.dmgMin = 46; bullet.dmgMax = 52; bullet.penetration *= 2.5; @@ -435,7 +436,7 @@ public class Gun556mmFactory { BulletConfiguration bullet = get556FlechetteConfig(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 12); + bullet.ammo.meta = 13; bullet.dmgMin = 45; bullet.dmgMax = 50; bullet.wear = 10; @@ -474,13 +475,14 @@ public class Gun556mmFactory { public static BulletConfiguration get556KConfig() { - BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); + BulletConfiguration bullet = get556Config(); - bullet.ammo = new ComparableStack(ModItems.ammo_556, 1, 13); + bullet.ammo.meta = 14; bullet.dmgMin = 0; bullet.dmgMax = 0; bullet.penetration = 0; bullet.maxAge = 0; + bullet.wear /= 2; return bullet; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java index 08a4f6024..a1bcf8cf8 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun9mmFactory.java @@ -24,7 +24,7 @@ public class Gun9mmFactory { static final SpentCasingConfig CASING_9 = Gun45ACPFactory.CASING_45_UAC.toBuilder("9") .setInitialMotion(Vec3.createVectorHelper(-0.3, 0.6, 0)).setPosOffset(new EasyLocation(-0.35, -0.2, 0.55)) - .setScaleX(1).setScaleY(1).setScaleZ(0.6f).build(); + .setScaleX(1).setScaleY(1).setScaleZ(0.6f).setBounceSound("weapon.smallCasingBouncePB3").build(); public static GunConfiguration getMP40Config() { diff --git a/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java b/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java index e49d86fc9..2f52fadef 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunGrenadeFactory.java @@ -20,7 +20,7 @@ import com.hbm.render.util.RenderScreenOverlay.Crosshair; public class GunGrenadeFactory { static final SpentCasingConfig CASING_40 = new SpentCasingConfigBuilder("40", CasingType.BRASS_STRAIGHT_WALL, false) - .setSmokeChance(0).setScaleX(4).setAfterReload(true).setPitchFactor(0.02f).setYawFactor(0.03f) + .setSmokeChance(0).setScaleX(4).setScaleY(4).setScaleZ(3).setAfterReload(true).setPitchFactor(0.02f).setYawFactor(0.03f) .build(); public static GunConfiguration getHK69Config() { diff --git a/src/main/java/com/hbm/items/ItemAmmoEnums.java b/src/main/java/com/hbm/items/ItemAmmoEnums.java index 900973025..bffbef5b8 100644 --- a/src/main/java/com/hbm/items/ItemAmmoEnums.java +++ b/src/main/java/com/hbm/items/ItemAmmoEnums.java @@ -560,9 +560,9 @@ public class ItemAmmoEnums STAR(Gun50BMGFactory.get50BMGStarConfig(), HbmCollection.StarmetalType), CHLOROPHYTE(Gun50BMGFactory.get50BMGConfig().getChlorophyte(), HbmCollection.ChlorophyteType), SLEEK(Gun50BMGFactory.get50BMGSleekConfig(), AmmoItemTrait.NEU_MASKMAN_METEORITE), - FLECHETTE(Gun50BMGFactory.get50BMGFlechetteConfig()), - FLECHETTE_AM(Gun50BMGFactory.get50BMGFlechetteAMConfig()), - FLECHETTE_PO(Gun50BMGFactory.get50BMGFlechettePOConfig()); + FLECHETTE(Gun50BMGFactory.get50BMGFlechetteConfig(), AmmoItemTrait.PRO_DAMAGE), + FLECHETTE_AM(Gun50BMGFactory.get50BMGFlechetteAMConfig(), AmmoItemTrait.PRO_DAMAGE, AmmoItemTrait.NEU_UHH), + FLECHETTE_PO(Gun50BMGFactory.get50BMGFlechettePOConfig(), AmmoItemTrait.PRO_DAMAGE, AmmoItemTrait.NEU_UHH); private final Set traits; private final BulletConfiguration config; private Ammo50BMG(BulletConfiguration config, AmmoItemTrait...traits) diff --git a/src/main/java/com/hbm/items/weapon/ItemGunBase.java b/src/main/java/com/hbm/items/weapon/ItemGunBase.java index f07cfac11..23d2dee3f 100644 --- a/src/main/java/com/hbm/items/weapon/ItemGunBase.java +++ b/src/main/java/com/hbm/items/weapon/ItemGunBase.java @@ -251,7 +251,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu world.playSoundAtEntity(player, altConfig.firingSound, 1.0F, altConfig.firingPitch); - if (altConfig.casingConfig.isPresent() && !altConfig.casingConfig.get().isAfterReload()) + if (altConfig.casingConfig.isPresent()) spawnCasing(player, altConfig.casingConfig.get(), stack); } diff --git a/src/main/java/com/hbm/lib/Library.java b/src/main/java/com/hbm/lib/Library.java index 3c261c648..01cb315a8 100644 --- a/src/main/java/com/hbm/lib/Library.java +++ b/src/main/java/com/hbm/lib/Library.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.stream.Collectors; import com.google.common.collect.Sets; import com.hbm.blocks.ModBlocks; @@ -106,6 +107,26 @@ public class Library { public static final ForgeDirection POS_Z = ForgeDirection.SOUTH; public static final ForgeDirection NEG_Z = ForgeDirection.NORTH; + public static List mergeWithoutDuplicates(List...lists) + { + final List totalList = new ArrayList(); + for (List list : lists) + totalList.addAll(list); + return listWithoutDuplicates(totalList); + } + + public static List listWithoutDuplicates(List list) + { + return list.stream().distinct().collect(Collectors.toList()); + } + + public static void removeListDuplicates(List list) + { + final List newList = listWithoutDuplicates(list); + list.clear(); + list.addAll(newList); + } + /* * Is putting this into this trash can a good idea? No. Do I have a better idea? Not currently. */ diff --git a/src/main/java/com/hbm/main/ClientProxy.java b/src/main/java/com/hbm/main/ClientProxy.java index 98bead3d9..e738d14f5 100644 --- a/src/main/java/com/hbm/main/ClientProxy.java +++ b/src/main/java/com/hbm/main/ClientProxy.java @@ -1,5 +1,637 @@ package com.hbm.main; +import java.awt.Color; +import java.awt.Desktop; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Random; + +import com.hbm.blocks.ModBlocks; +import com.hbm.blocks.generic.BlockBobble.TileEntityBobble; +import com.hbm.blocks.generic.BlockEmitter.TileEntityEmitter; +import com.hbm.blocks.generic.BlockLoot.TileEntityLoot; +import com.hbm.config.WeaponConfig; +import com.hbm.entity.cart.EntityMinecartCrate; +import com.hbm.entity.cart.EntityMinecartNTM; +import com.hbm.entity.effect.EntityBlackHole; +import com.hbm.entity.effect.EntityCloudFleija; +import com.hbm.entity.effect.EntityCloudFleijaRainbow; +import com.hbm.entity.effect.EntityCloudSolinium; +import com.hbm.entity.effect.EntityCloudTom; +import com.hbm.entity.effect.EntityEMPBlast; +import com.hbm.entity.effect.EntityFalloutRain; +import com.hbm.entity.effect.EntityNukeCloudBig; +import com.hbm.entity.effect.EntityNukeCloudNoShroom; +import com.hbm.entity.effect.EntityNukeCloudSmall; +import com.hbm.entity.effect.EntityNukeTorex; +import com.hbm.entity.effect.EntityQuasar; +import com.hbm.entity.effect.EntityRagingVortex; +import com.hbm.entity.effect.EntitySpear; +import com.hbm.entity.effect.EntityVortex; +import com.hbm.entity.grenade.EntityGrenadeASchrab; +import com.hbm.entity.grenade.EntityGrenadeBlackHole; +import com.hbm.entity.grenade.EntityGrenadeBouncyBaseNT; +import com.hbm.entity.grenade.EntityGrenadeBouncyGeneric; +import com.hbm.entity.grenade.EntityGrenadeBreach; +import com.hbm.entity.grenade.EntityGrenadeBurst; +import com.hbm.entity.grenade.EntityGrenadeCloud; +import com.hbm.entity.grenade.EntityGrenadeCluster; +import com.hbm.entity.grenade.EntityGrenadeDynamite; +import com.hbm.entity.grenade.EntityGrenadeElectric; +import com.hbm.entity.grenade.EntityGrenadeFire; +import com.hbm.entity.grenade.EntityGrenadeFlare; +import com.hbm.entity.grenade.EntityGrenadeFrag; +import com.hbm.entity.grenade.EntityGrenadeGas; +import com.hbm.entity.grenade.EntityGrenadeGascan; +import com.hbm.entity.grenade.EntityGrenadeGeneric; +import com.hbm.entity.grenade.EntityGrenadeIFBouncy; +import com.hbm.entity.grenade.EntityGrenadeIFBrimstone; +import com.hbm.entity.grenade.EntityGrenadeIFConcussion; +import com.hbm.entity.grenade.EntityGrenadeIFGeneric; +import com.hbm.entity.grenade.EntityGrenadeIFHE; +import com.hbm.entity.grenade.EntityGrenadeIFHopwire; +import com.hbm.entity.grenade.EntityGrenadeIFImpact; +import com.hbm.entity.grenade.EntityGrenadeIFIncendiary; +import com.hbm.entity.grenade.EntityGrenadeIFMystery; +import com.hbm.entity.grenade.EntityGrenadeIFNull; +import com.hbm.entity.grenade.EntityGrenadeIFSpark; +import com.hbm.entity.grenade.EntityGrenadeIFSticky; +import com.hbm.entity.grenade.EntityGrenadeIFToxic; +import com.hbm.entity.grenade.EntityGrenadeImpactGeneric; +import com.hbm.entity.grenade.EntityGrenadeLemon; +import com.hbm.entity.grenade.EntityGrenadeMIRV; +import com.hbm.entity.grenade.EntityGrenadeMk2; +import com.hbm.entity.grenade.EntityGrenadeNuclear; +import com.hbm.entity.grenade.EntityGrenadeNuke; +import com.hbm.entity.grenade.EntityGrenadePC; +import com.hbm.entity.grenade.EntityGrenadePlasma; +import com.hbm.entity.grenade.EntityGrenadePoison; +import com.hbm.entity.grenade.EntityGrenadePulse; +import com.hbm.entity.grenade.EntityGrenadeSchrabidium; +import com.hbm.entity.grenade.EntityGrenadeShrapnel; +import com.hbm.entity.grenade.EntityGrenadeSmart; +import com.hbm.entity.grenade.EntityGrenadeStrong; +import com.hbm.entity.grenade.EntityGrenadeTau; +import com.hbm.entity.grenade.EntityGrenadeZOMG; +import com.hbm.entity.grenade.EntityWastePearl; +import com.hbm.entity.item.EntityFireworks; +import com.hbm.entity.item.EntityMagnusCartus; +import com.hbm.entity.item.EntityMinecartTest; +import com.hbm.entity.item.EntityMovingItem; +import com.hbm.entity.item.EntityMovingPackage; +import com.hbm.entity.item.EntityTNTPrimedBase; +import com.hbm.entity.logic.EntityBomber; +import com.hbm.entity.logic.EntityDeathBlast; +import com.hbm.entity.logic.EntityEMP; +import com.hbm.entity.logic.EntityNukeExplosionAdvanced; +import com.hbm.entity.missile.EntityBobmazon; +import com.hbm.entity.missile.EntityBombletSelena; +import com.hbm.entity.missile.EntityBombletTheta; +import com.hbm.entity.missile.EntityBooster; +import com.hbm.entity.missile.EntityCarrier; +import com.hbm.entity.missile.EntityMIRV; +import com.hbm.entity.missile.EntityMinerRocket; +import com.hbm.entity.missile.EntityMissileAntiBallistic; +import com.hbm.entity.missile.EntityMissileBHole; +import com.hbm.entity.missile.EntityMissileBunkerBuster; +import com.hbm.entity.missile.EntityMissileBurst; +import com.hbm.entity.missile.EntityMissileBusterStrong; +import com.hbm.entity.missile.EntityMissileCluster; +import com.hbm.entity.missile.EntityMissileClusterStrong; +import com.hbm.entity.missile.EntityMissileCustom; +import com.hbm.entity.missile.EntityMissileDoomsday; +import com.hbm.entity.missile.EntityMissileDrill; +import com.hbm.entity.missile.EntityMissileEMP; +import com.hbm.entity.missile.EntityMissileEMPStrong; +import com.hbm.entity.missile.EntityMissileEndo; +import com.hbm.entity.missile.EntityMissileExo; +import com.hbm.entity.missile.EntityMissileGeneric; +import com.hbm.entity.missile.EntityMissileIncendiary; +import com.hbm.entity.missile.EntityMissileIncendiaryStrong; +import com.hbm.entity.missile.EntityMissileInferno; +import com.hbm.entity.missile.EntityMissileMicro; +import com.hbm.entity.missile.EntityMissileMirv; +import com.hbm.entity.missile.EntityMissileNuclear; +import com.hbm.entity.missile.EntityMissileRain; +import com.hbm.entity.missile.EntityMissileSchrabidium; +import com.hbm.entity.missile.EntityMissileShuttle; +import com.hbm.entity.missile.EntityMissileStrong; +import com.hbm.entity.missile.EntityMissileTaint; +import com.hbm.entity.missile.EntityMissileVolcano; +import com.hbm.entity.missile.EntitySiegeDropship; +import com.hbm.entity.missile.EntitySoyuz; +import com.hbm.entity.missile.EntitySoyuzCapsule; +import com.hbm.entity.missile.EntityTestMissile; +import com.hbm.entity.mob.EntityBlockSpider; +import com.hbm.entity.mob.EntityCyberCrab; +import com.hbm.entity.mob.EntityDuck; +import com.hbm.entity.mob.EntityFBI; +import com.hbm.entity.mob.EntityGhost; +import com.hbm.entity.mob.EntityHunterChopper; +import com.hbm.entity.mob.EntityMaskMan; +import com.hbm.entity.mob.EntityNuclearCreeper; +import com.hbm.entity.mob.EntityQuackos; +import com.hbm.entity.mob.EntityRADBeast; +import com.hbm.entity.mob.EntityTaintCrab; +import com.hbm.entity.mob.EntityTaintedCreeper; +import com.hbm.entity.mob.EntityTeslaCrab; +import com.hbm.entity.mob.EntityUFO; +import com.hbm.entity.mob.botprime.EntityBOTPrimeBody; +import com.hbm.entity.mob.botprime.EntityBOTPrimeHead; +import com.hbm.entity.mob.siege.EntitySiegeCraft; +import com.hbm.entity.mob.siege.EntitySiegeSkeleton; +import com.hbm.entity.mob.siege.EntitySiegeTunneler; +import com.hbm.entity.mob.siege.EntitySiegeUFO; +import com.hbm.entity.mob.siege.EntitySiegeZombie; +import com.hbm.entity.particle.EntityBSmokeFX; +import com.hbm.entity.particle.EntityChlorineFX; +import com.hbm.entity.particle.EntityDSmokeFX; +import com.hbm.entity.particle.EntityFogFX; +import com.hbm.entity.particle.EntityGasFX; +import com.hbm.entity.particle.EntityOilSpillFX; +import com.hbm.entity.particle.EntityOrangeFX; +import com.hbm.entity.particle.EntityPinkCloudFX; +import com.hbm.entity.particle.EntitySSmokeFX; +import com.hbm.entity.particle.EntitySmokeFX; +import com.hbm.entity.particle.EntityTSmokeFX; +import com.hbm.entity.projectile.EntityAAShell; +import com.hbm.entity.projectile.EntityArtilleryShell; +import com.hbm.entity.projectile.EntityBeamVortex; +import com.hbm.entity.projectile.EntityBombletZeta; +import com.hbm.entity.projectile.EntityBoxcar; +import com.hbm.entity.projectile.EntityBuilding; +import com.hbm.entity.projectile.EntityBullet; +import com.hbm.entity.projectile.EntityBulletBase; +import com.hbm.entity.projectile.EntityBurningFOEQ; +import com.hbm.entity.projectile.EntityChemical; +import com.hbm.entity.projectile.EntityChopperMine; +import com.hbm.entity.projectile.EntityCog; +import com.hbm.entity.projectile.EntityCombineBall; +import com.hbm.entity.projectile.EntityDischarge; +import com.hbm.entity.projectile.EntityDuchessGambit; +import com.hbm.entity.projectile.EntityExplosiveBeam; +import com.hbm.entity.projectile.EntityFallingNuke; +import com.hbm.entity.projectile.EntityFire; +import com.hbm.entity.projectile.EntityLN2; +import com.hbm.entity.projectile.EntityLaser; +import com.hbm.entity.projectile.EntityLaserBeam; +import com.hbm.entity.projectile.EntityMeteor; +import com.hbm.entity.projectile.EntityMinerBeam; +import com.hbm.entity.projectile.EntityModBeam; +import com.hbm.entity.projectile.EntityNightmareBlast; +import com.hbm.entity.projectile.EntityOilSpill; +import com.hbm.entity.projectile.EntityPlasmaBeam; +import com.hbm.entity.projectile.EntityRBMKDebris; +import com.hbm.entity.projectile.EntityRainbow; +import com.hbm.entity.projectile.EntityRocket; +import com.hbm.entity.projectile.EntityRocketHoming; +import com.hbm.entity.projectile.EntityRubble; +import com.hbm.entity.projectile.EntitySawblade; +import com.hbm.entity.projectile.EntitySchrab; +import com.hbm.entity.projectile.EntityShrapnel; +import com.hbm.entity.projectile.EntitySiegeLaser; +import com.hbm.entity.projectile.EntitySparkBeam; +import com.hbm.entity.projectile.EntityTom; +import com.hbm.entity.projectile.EntityWaterSplash; +import com.hbm.entity.projectile.EntityZirnoxDebris; +import com.hbm.handler.HbmKeybinds; +import com.hbm.handler.HbmKeybinds.EnumKeybind; +import com.hbm.items.ItemAmmoEnums.AmmoHandGrenade; +import com.hbm.items.ModItems; +import com.hbm.particle.ParticleAmatFlash; +import com.hbm.particle.ParticleContrail; +import com.hbm.particle.ParticleCoolingTower; +import com.hbm.particle.ParticleDeadLeaf; +import com.hbm.particle.ParticleDebug; +import com.hbm.particle.ParticleDigammaSmoke; +import com.hbm.particle.ParticleExSmoke; +import com.hbm.particle.ParticleGasFlame; +import com.hbm.particle.ParticleGiblet; +import com.hbm.particle.ParticleHadron; +import com.hbm.particle.ParticleHaze; +import com.hbm.particle.ParticleLetter; +import com.hbm.particle.ParticleMukeCloud; +import com.hbm.particle.ParticleMukeFlash; +import com.hbm.particle.ParticleMukeWave; +import com.hbm.particle.ParticlePlasmaBlast; +import com.hbm.particle.ParticleRBMKFlame; +import com.hbm.particle.ParticleRBMKMush; +import com.hbm.particle.ParticleRadiationFog; +import com.hbm.particle.ParticleRift; +import com.hbm.particle.ParticleRocketFlame; +import com.hbm.particle.ParticleSmokePlume; +import com.hbm.particle.ParticleSpark; +import com.hbm.particle.ParticleText; +import com.hbm.particle.SpentCasingConfig; +import com.hbm.render.anim.BusAnimation; +import com.hbm.render.anim.BusAnimationKeyframe; +import com.hbm.render.anim.BusAnimationSequence; +import com.hbm.render.anim.HbmAnimations; +import com.hbm.render.anim.HbmAnimations.Animation; +import com.hbm.render.block.RenderAntennaTop; +import com.hbm.render.block.RenderAnvil; +import com.hbm.render.block.RenderBarbedWire; +import com.hbm.render.block.RenderBarrel; +import com.hbm.render.block.RenderBattery; +import com.hbm.render.block.RenderBlockCT; +import com.hbm.render.block.RenderBlockDecoModel; +import com.hbm.render.block.RenderBlockMultipass; +import com.hbm.render.block.RenderBlockRotated; +import com.hbm.render.block.RenderBlockSideRotation; +import com.hbm.render.block.RenderBoxDuct; +import com.hbm.render.block.RenderCable; +import com.hbm.render.block.RenderCableClassic; +import com.hbm.render.block.RenderChain; +import com.hbm.render.block.RenderConserve; +import com.hbm.render.block.RenderConveyor; +import com.hbm.render.block.RenderConveyorChute; +import com.hbm.render.block.RenderConveyorLift; +import com.hbm.render.block.RenderCrystal; +import com.hbm.render.block.RenderDetCord; +import com.hbm.render.block.RenderDiode; +import com.hbm.render.block.RenderFence; +import com.hbm.render.block.RenderFoundryBasin; +import com.hbm.render.block.RenderFoundryChannel; +import com.hbm.render.block.RenderFoundryMold; +import com.hbm.render.block.RenderFoundryOutlet; +import com.hbm.render.block.RenderFoundryTank; +import com.hbm.render.block.RenderGrate; +import com.hbm.render.block.RenderMirror; +import com.hbm.render.block.RenderPipe; +import com.hbm.render.block.RenderPribris; +import com.hbm.render.block.RenderRBMKControl; +import com.hbm.render.block.RenderRBMKReflector; +import com.hbm.render.block.RenderRBMKRod; +import com.hbm.render.block.RenderRTGBlock; +import com.hbm.render.block.RenderScaffoldBlock; +import com.hbm.render.block.RenderSpikeBlock; +import com.hbm.render.block.RenderSteelBeam; +import com.hbm.render.block.RenderTaintBlock; +import com.hbm.render.block.RenderTapeBlock; +import com.hbm.render.block.RenderTestPipe; +import com.hbm.render.entity.RenderEmpty; +import com.hbm.render.entity.effect.ElectricityRenderer; +import com.hbm.render.entity.effect.FogRenderer; +import com.hbm.render.entity.effect.GasRenderer; +import com.hbm.render.entity.effect.MultiCloudRenderer; +import com.hbm.render.entity.effect.RenderBigNuke; +import com.hbm.render.entity.effect.RenderBlackHole; +import com.hbm.render.entity.effect.RenderCasingTest; +import com.hbm.render.entity.effect.RenderCloudFleija; +import com.hbm.render.entity.effect.RenderCloudRainbow; +import com.hbm.render.entity.effect.RenderCloudSolinium; +import com.hbm.render.entity.effect.RenderCloudTom; +import com.hbm.render.entity.effect.RenderDeathBlast; +import com.hbm.render.entity.effect.RenderEMPBlast; +import com.hbm.render.entity.effect.RenderFallout; +import com.hbm.render.entity.effect.RenderFireball; +import com.hbm.render.entity.effect.RenderFlare; +import com.hbm.render.entity.effect.RenderNoCloud; +import com.hbm.render.entity.effect.RenderQuasar; +import com.hbm.render.entity.effect.RenderSmallNukeMK4; +import com.hbm.render.entity.effect.RenderSpear; +import com.hbm.render.entity.effect.RenderTorex; +import com.hbm.render.entity.effect.SSmokeRenderer; +import com.hbm.render.entity.effect.SpillRenderer; +import com.hbm.render.entity.effect.TSmokeRenderer; +import com.hbm.render.entity.item.RenderBomber; +import com.hbm.render.entity.item.RenderMagnusCartus; +import com.hbm.render.entity.item.RenderMinecartTest; +import com.hbm.render.entity.item.RenderMovingItem; +import com.hbm.render.entity.item.RenderMovingPackage; +import com.hbm.render.entity.item.RenderNeoCart; +import com.hbm.render.entity.item.RenderTNTPrimedBase; +import com.hbm.render.entity.mob.RenderBlockSpider; +import com.hbm.render.entity.mob.RenderCyberCrab; +import com.hbm.render.entity.mob.RenderDuck; +import com.hbm.render.entity.mob.RenderFBI; +import com.hbm.render.entity.mob.RenderGhost; +import com.hbm.render.entity.mob.RenderHunterChopper; +import com.hbm.render.entity.mob.RenderMaskMan; +import com.hbm.render.entity.mob.RenderNuclearCreeper; +import com.hbm.render.entity.mob.RenderQuacc; +import com.hbm.render.entity.mob.RenderRADBeast; +import com.hbm.render.entity.mob.RenderSiegeCraft; +import com.hbm.render.entity.mob.RenderSiegeSkeleton; +import com.hbm.render.entity.mob.RenderSiegeTunneler; +import com.hbm.render.entity.mob.RenderSiegeUFO; +import com.hbm.render.entity.mob.RenderSiegeZombie; +import com.hbm.render.entity.mob.RenderTaintCrab; +import com.hbm.render.entity.mob.RenderTaintedCreeper; +import com.hbm.render.entity.mob.RenderTeslaCrab; +import com.hbm.render.entity.mob.RenderUFO; +import com.hbm.render.entity.mob.RenderWormBody; +import com.hbm.render.entity.mob.RenderWormHead; +import com.hbm.render.entity.projectile.RenderArtilleryShell; +import com.hbm.render.entity.projectile.RenderBeam; +import com.hbm.render.entity.projectile.RenderBeam2; +import com.hbm.render.entity.projectile.RenderBeam3; +import com.hbm.render.entity.projectile.RenderBeam4; +import com.hbm.render.entity.projectile.RenderBeam5; +import com.hbm.render.entity.projectile.RenderBeam6; +import com.hbm.render.entity.projectile.RenderBombletSelena; +import com.hbm.render.entity.projectile.RenderBombletTheta; +import com.hbm.render.entity.projectile.RenderBoxcar; +import com.hbm.render.entity.projectile.RenderBullet; +import com.hbm.render.entity.projectile.RenderChemical; +import com.hbm.render.entity.projectile.RenderChopperMine; +import com.hbm.render.entity.projectile.RenderCog; +import com.hbm.render.entity.projectile.RenderFOEQ; +import com.hbm.render.entity.projectile.RenderFallingNuke; +import com.hbm.render.entity.projectile.RenderGenericGrenade; +import com.hbm.render.entity.projectile.RenderGrenade; +import com.hbm.render.entity.projectile.RenderLN2; +import com.hbm.render.entity.projectile.RenderLaser; +import com.hbm.render.entity.projectile.RenderMeteor; +import com.hbm.render.entity.projectile.RenderMirv; +import com.hbm.render.entity.projectile.RenderOminousBullet; +import com.hbm.render.entity.projectile.RenderRBMKDebris; +import com.hbm.render.entity.projectile.RenderRainbow; +import com.hbm.render.entity.projectile.RenderRocket; +import com.hbm.render.entity.projectile.RenderRubble; +import com.hbm.render.entity.projectile.RenderSRocket; +import com.hbm.render.entity.projectile.RenderSawblade; +import com.hbm.render.entity.projectile.RenderShrapnel; +import com.hbm.render.entity.projectile.RenderSiegeLaser; +import com.hbm.render.entity.projectile.RenderTom; +import com.hbm.render.entity.projectile.RenderVortexBeam; +import com.hbm.render.entity.projectile.RenderZirnoxDebris; +import com.hbm.render.entity.rocket.RenderBoosterMissile; +import com.hbm.render.entity.rocket.RenderCarrierMissile; +import com.hbm.render.entity.rocket.RenderMinerRocket; +import com.hbm.render.entity.rocket.RenderMissileCustom; +import com.hbm.render.entity.rocket.RenderMissileDoomsday; +import com.hbm.render.entity.rocket.RenderMissileGeneric; +import com.hbm.render.entity.rocket.RenderMissileHuge; +import com.hbm.render.entity.rocket.RenderMissileMirv; +import com.hbm.render.entity.rocket.RenderMissileNuclear; +import com.hbm.render.entity.rocket.RenderMissileShuttle; +import com.hbm.render.entity.rocket.RenderMissileStrong; +import com.hbm.render.entity.rocket.RenderMissileTaint; +import com.hbm.render.entity.rocket.RenderMissileThermo; +import com.hbm.render.entity.rocket.RenderSoyuz; +import com.hbm.render.entity.rocket.RenderSoyuzCapsule; +import com.hbm.render.item.ItemRenderBase; +import com.hbm.render.item.ItemRenderDetonatorLaser; +import com.hbm.render.item.ItemRenderLibrary; +import com.hbm.render.item.ItemRenderMissile; +import com.hbm.render.item.ItemRenderMissilePart; +import com.hbm.render.item.ItemRenderMultitool; +import com.hbm.render.item.ItemRenderTemplate; +import com.hbm.render.item.ItemRenderTransformer; +import com.hbm.render.item.ItemRendererHot; +import com.hbm.render.item.ItemRendererMeteorSword; +import com.hbm.render.item.block.ItemRenderDecoBlock; +import com.hbm.render.item.block.ItemRenderTestContainer; +import com.hbm.render.item.weapon.ItemRenderBFLauncher; +import com.hbm.render.item.weapon.ItemRenderBenelli; +import com.hbm.render.item.weapon.ItemRenderBigSword; +import com.hbm.render.item.weapon.ItemRenderBioRevolver; +import com.hbm.render.item.weapon.ItemRenderBullshit; +import com.hbm.render.item.weapon.ItemRenderChainsaw; +import com.hbm.render.item.weapon.ItemRenderCrucible; +import com.hbm.render.item.weapon.ItemRenderCryolator; +import com.hbm.render.item.weapon.ItemRenderEMPRay; +import com.hbm.render.item.weapon.ItemRenderFatMan; +import com.hbm.render.item.weapon.ItemRenderFireExt; +import com.hbm.render.item.weapon.ItemRenderG36; +import com.hbm.render.item.weapon.ItemRenderGavel; +import com.hbm.render.item.weapon.ItemRenderGunAnim; +import com.hbm.render.item.weapon.ItemRenderHLR; +import com.hbm.render.item.weapon.ItemRenderImmolator; +import com.hbm.render.item.weapon.ItemRenderLLR; +import com.hbm.render.item.weapon.ItemRenderLunaticSniper; +import com.hbm.render.item.weapon.ItemRenderM2; +import com.hbm.render.item.weapon.ItemRenderMIRVLauncher; +import com.hbm.render.item.weapon.ItemRenderMLR; +import com.hbm.render.item.weapon.ItemRenderMP; +import com.hbm.render.item.weapon.ItemRenderMP40; +import com.hbm.render.item.weapon.ItemRenderOSIPR; +import com.hbm.render.item.weapon.ItemRenderObj; +import com.hbm.render.item.weapon.ItemRenderOverkill; +import com.hbm.render.item.weapon.ItemRenderRedstoneSword; +import com.hbm.render.item.weapon.ItemRenderRevolverInverted; +import com.hbm.render.item.weapon.ItemRenderRpg; +import com.hbm.render.item.weapon.ItemRenderShim; +import com.hbm.render.item.weapon.ItemRenderStinger; +import com.hbm.render.item.weapon.ItemRenderTWR; +import com.hbm.render.item.weapon.ItemRenderTestBombAdvanced; +import com.hbm.render.item.weapon.ItemRenderUACPistol; +import com.hbm.render.item.weapon.ItemRenderUZI; +import com.hbm.render.item.weapon.ItemRenderUboinik; +import com.hbm.render.item.weapon.ItemRenderWeaponAR15; +import com.hbm.render.item.weapon.ItemRenderWeaponBolter; +import com.hbm.render.item.weapon.ItemRenderWeaponChemthrower; +import com.hbm.render.item.weapon.ItemRenderWeaponFFBolt; +import com.hbm.render.item.weapon.ItemRenderWeaponFFColt; +import com.hbm.render.item.weapon.ItemRenderWeaponFFCursed; +import com.hbm.render.item.weapon.ItemRenderWeaponFFMG42; +import com.hbm.render.item.weapon.ItemRenderWeaponFFMaresLeg; +import com.hbm.render.item.weapon.ItemRenderWeaponFFNightmare; +import com.hbm.render.item.weapon.ItemRenderWeaponFFNightmareDark; +import com.hbm.render.item.weapon.ItemRenderWeaponGlass; +import com.hbm.render.item.weapon.ItemRenderWeaponObj; +import com.hbm.render.item.weapon.ItemRenderWeaponQuadro; +import com.hbm.render.item.weapon.ItemRenderWeaponSauer; +import com.hbm.render.item.weapon.ItemRenderWeaponShotty; +import com.hbm.render.item.weapon.ItemRenderWeaponSpas12; +import com.hbm.render.item.weapon.ItemRenderWeaponThompson; +import com.hbm.render.item.weapon.ItemRenderWeaponVortex; +import com.hbm.render.item.weapon.ItemRenderXVL1456; +import com.hbm.render.item.weapon.ItemRenderZOMG; +import com.hbm.render.loader.HmfModelLoader; +import com.hbm.render.tileentity.*; +import com.hbm.render.util.MissilePart; +import com.hbm.render.util.RenderInfoSystem; +import com.hbm.render.util.RenderInfoSystem.InfoEntry; +import com.hbm.sound.AudioWrapper; +import com.hbm.sound.AudioWrapperClient; +import com.hbm.sound.AudioWrapperClientStartStop; +import com.hbm.tileentity.TileEntityDoorGeneric; +import com.hbm.tileentity.bomb.TileEntityBombMulti; +import com.hbm.tileentity.bomb.TileEntityCelPrime; +import com.hbm.tileentity.bomb.TileEntityCelPrimeBattery; +import com.hbm.tileentity.bomb.TileEntityCelPrimePort; +import com.hbm.tileentity.bomb.TileEntityCelPrimeTanks; +import com.hbm.tileentity.bomb.TileEntityCelPrimeTerminal; +import com.hbm.tileentity.bomb.TileEntityCharge; +import com.hbm.tileentity.bomb.TileEntityCompactLauncher; +import com.hbm.tileentity.bomb.TileEntityCrashedBomb; +import com.hbm.tileentity.bomb.TileEntityLandmine; +import com.hbm.tileentity.bomb.TileEntityLaunchPad; +import com.hbm.tileentity.bomb.TileEntityLaunchTable; +import com.hbm.tileentity.bomb.TileEntityNukeBalefire; +import com.hbm.tileentity.bomb.TileEntityNukeBoy; +import com.hbm.tileentity.bomb.TileEntityNukeCustom; +import com.hbm.tileentity.bomb.TileEntityNukeFleija; +import com.hbm.tileentity.bomb.TileEntityNukeGadget; +import com.hbm.tileentity.bomb.TileEntityNukeMan; +import com.hbm.tileentity.bomb.TileEntityNukeMike; +import com.hbm.tileentity.bomb.TileEntityNukeN2; +import com.hbm.tileentity.bomb.TileEntityNukeN45; +import com.hbm.tileentity.bomb.TileEntityNukePrototype; +import com.hbm.tileentity.bomb.TileEntityNukeSolinium; +import com.hbm.tileentity.bomb.TileEntityNukeTsar; +import com.hbm.tileentity.bomb.TileEntityTestBombAdvanced; +import com.hbm.tileentity.conductor.TileEntityFluidDuct; +import com.hbm.tileentity.conductor.TileEntityGasDuct; +import com.hbm.tileentity.conductor.TileEntityOilDuct; +import com.hbm.tileentity.conductor.TileEntityRFDuct; +import com.hbm.tileentity.deco.TileEntityBomber; +import com.hbm.tileentity.deco.TileEntityDecoBlock; +import com.hbm.tileentity.deco.TileEntityDecoBlockAlt; +import com.hbm.tileentity.deco.TileEntityDecoBlockAltF; +import com.hbm.tileentity.deco.TileEntityDecoBlockAltG; +import com.hbm.tileentity.deco.TileEntityDecoBlockAltW; +import com.hbm.tileentity.deco.TileEntityDecoPoleSatelliteReceiver; +import com.hbm.tileentity.deco.TileEntityObjTester; +import com.hbm.tileentity.deco.TileEntityRotationTester; +import com.hbm.tileentity.deco.TileEntityTestRender; +import com.hbm.tileentity.machine.TileEntityAMSBase; +import com.hbm.tileentity.machine.TileEntityAMSEmitter; +import com.hbm.tileentity.machine.TileEntityAMSLimiter; +import com.hbm.tileentity.machine.TileEntityBlastDoor; +import com.hbm.tileentity.machine.TileEntityBroadcaster; +import com.hbm.tileentity.machine.TileEntityCharger; +import com.hbm.tileentity.machine.TileEntityChungus; +import com.hbm.tileentity.machine.TileEntityCore; +import com.hbm.tileentity.machine.TileEntityCoreEmitter; +import com.hbm.tileentity.machine.TileEntityCoreInjector; +import com.hbm.tileentity.machine.TileEntityCoreReceiver; +import com.hbm.tileentity.machine.TileEntityCoreStabilizer; +import com.hbm.tileentity.machine.TileEntityCrucible; +import com.hbm.tileentity.machine.TileEntityDemonLamp; +import com.hbm.tileentity.machine.TileEntityDeuteriumTower; +import com.hbm.tileentity.machine.TileEntityElectrolyser; +import com.hbm.tileentity.machine.TileEntityFEL; +import com.hbm.tileentity.machine.TileEntityFF; +import com.hbm.tileentity.machine.TileEntityForceField; +import com.hbm.tileentity.machine.TileEntityFoundryBasin; +import com.hbm.tileentity.machine.TileEntityFoundryMold; +import com.hbm.tileentity.machine.TileEntityFurnaceIron; +import com.hbm.tileentity.machine.TileEntityFurnaceSteel; +import com.hbm.tileentity.machine.TileEntityGeiger; +import com.hbm.tileentity.machine.TileEntityHeatBoiler; +import com.hbm.tileentity.machine.TileEntityHeaterElectric; +import com.hbm.tileentity.machine.TileEntityHeaterFirebox; +import com.hbm.tileentity.machine.TileEntityHeaterOilburner; +import com.hbm.tileentity.machine.TileEntityITER; +import com.hbm.tileentity.machine.TileEntityITERStruct; +import com.hbm.tileentity.machine.TileEntityMachineAssembler; +import com.hbm.tileentity.machine.TileEntityMachineAssemfac; +import com.hbm.tileentity.machine.TileEntityMachineCentrifuge; +import com.hbm.tileentity.machine.TileEntityMachineChemfac; +import com.hbm.tileentity.machine.TileEntityMachineChemplant; +import com.hbm.tileentity.machine.TileEntityMachineCrystallizer; +import com.hbm.tileentity.machine.TileEntityMachineCyclotron; +import com.hbm.tileentity.machine.TileEntityMachineEPress; +import com.hbm.tileentity.machine.TileEntityMachineGasCent; +import com.hbm.tileentity.machine.TileEntityMachineIGenerator; +import com.hbm.tileentity.machine.TileEntityMachineLargeTurbine; +import com.hbm.tileentity.machine.TileEntityMachineMiniRTG; +import com.hbm.tileentity.machine.TileEntityMachineMiningDrill; +import com.hbm.tileentity.machine.TileEntityMachineMiningLaser; +import com.hbm.tileentity.machine.TileEntityMachineMissileAssembly; +import com.hbm.tileentity.machine.TileEntityMachinePlasmaHeater; +import com.hbm.tileentity.machine.TileEntityMachinePress; +import com.hbm.tileentity.machine.TileEntityMachineRTG; +import com.hbm.tileentity.machine.TileEntityMachineRadGen; +import com.hbm.tileentity.machine.TileEntityMachineRadar; +import com.hbm.tileentity.machine.TileEntityMachineRadiolysis; +import com.hbm.tileentity.machine.TileEntityMachineReactorBreeding; +import com.hbm.tileentity.machine.TileEntityMachineSatDock; +import com.hbm.tileentity.machine.TileEntityMachineSeleniumEngine; +import com.hbm.tileentity.machine.TileEntityMachineShredderLarge; +import com.hbm.tileentity.machine.TileEntityMachineTurbofan; +import com.hbm.tileentity.machine.TileEntityMicrowave; +import com.hbm.tileentity.machine.TileEntityMultiblock; +import com.hbm.tileentity.machine.TileEntityPlasmaStruct; +import com.hbm.tileentity.machine.TileEntityRadioRec; +import com.hbm.tileentity.machine.TileEntityRadiobox; +import com.hbm.tileentity.machine.TileEntityReactorResearch; +import com.hbm.tileentity.machine.TileEntityReactorZirnox; +import com.hbm.tileentity.machine.TileEntitySILEX; +import com.hbm.tileentity.machine.TileEntitySawmill; +import com.hbm.tileentity.machine.TileEntitySolarBoiler; +import com.hbm.tileentity.machine.TileEntitySoyuzLauncher; +import com.hbm.tileentity.machine.TileEntitySoyuzStruct; +import com.hbm.tileentity.machine.TileEntityStirling; +import com.hbm.tileentity.machine.TileEntityStorageDrum; +import com.hbm.tileentity.machine.TileEntityStructureMarker; +import com.hbm.tileentity.machine.TileEntityTesla; +import com.hbm.tileentity.machine.TileEntityTowerLarge; +import com.hbm.tileentity.machine.TileEntityTowerSmall; +import com.hbm.tileentity.machine.TileEntityVaultDoor; +import com.hbm.tileentity.machine.TileEntityWatz; +import com.hbm.tileentity.machine.TileEntityZirnoxDestroyed; +import com.hbm.tileentity.machine.oil.TileEntityMachineCatalyticCracker; +import com.hbm.tileentity.machine.oil.TileEntityMachineFrackingTower; +import com.hbm.tileentity.machine.oil.TileEntityMachineFractionTower; +import com.hbm.tileentity.machine.oil.TileEntityMachineGasFlare; +import com.hbm.tileentity.machine.oil.TileEntityMachineLiquefactor; +import com.hbm.tileentity.machine.oil.TileEntityMachineOilWell; +import com.hbm.tileentity.machine.oil.TileEntityMachinePumpjack; +import com.hbm.tileentity.machine.oil.TileEntityMachineRefinery; +import com.hbm.tileentity.machine.oil.TileEntityMachineSolidifier; +import com.hbm.tileentity.machine.oil.TileEntitySpacer; +import com.hbm.tileentity.machine.rbmk.TileEntityCraneConsole; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKAbsorber; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKBlank; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKBoiler; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKConsole; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKControlAuto; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKControlManual; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKCooler; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKHeater; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKModerator; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKOutgasser; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKReflector; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKRod; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKRodReaSim; +import com.hbm.tileentity.machine.rbmk.TileEntityRBMKStorage; +import com.hbm.tileentity.machine.storage.TileEntityBarrel; +import com.hbm.tileentity.machine.storage.TileEntityMachineBAT9000; +import com.hbm.tileentity.machine.storage.TileEntityMachineFENSU; +import com.hbm.tileentity.machine.storage.TileEntityMachineFluidTank; +import com.hbm.tileentity.machine.storage.TileEntityMachineOrbus; +import com.hbm.tileentity.machine.storage.TileEntityMachinePuF6Tank; +import com.hbm.tileentity.machine.storage.TileEntityMachineUF6Tank; +import com.hbm.tileentity.machine.storage.TileEntitySoyuzCapsule; +import com.hbm.tileentity.network.TileEntityConnector; +import com.hbm.tileentity.network.TileEntityPylon; +import com.hbm.tileentity.network.TileEntityPylonLarge; +import com.hbm.tileentity.network.TileEntitySubstation; +import com.hbm.tileentity.turret.TileEntityTurretArty; +import com.hbm.tileentity.turret.TileEntityTurretBrandon; +import com.hbm.tileentity.turret.TileEntityTurretCIWS; +import com.hbm.tileentity.turret.TileEntityTurretCheapo; +import com.hbm.tileentity.turret.TileEntityTurretChekhov; +import com.hbm.tileentity.turret.TileEntityTurretFlamer; +import com.hbm.tileentity.turret.TileEntityTurretFriendly; +import com.hbm.tileentity.turret.TileEntityTurretFritz; +import com.hbm.tileentity.turret.TileEntityTurretHIMARS; +import com.hbm.tileentity.turret.TileEntityTurretHeavy; +import com.hbm.tileentity.turret.TileEntityTurretHoward; +import com.hbm.tileentity.turret.TileEntityTurretHowardDamaged; +import com.hbm.tileentity.turret.TileEntityTurretJeremy; +import com.hbm.tileentity.turret.TileEntityTurretLight; +import com.hbm.tileentity.turret.TileEntityTurretMaxwell; +import com.hbm.tileentity.turret.TileEntityTurretRichard; +import com.hbm.tileentity.turret.TileEntityTurretRocket; +import com.hbm.tileentity.turret.TileEntityTurretSpitfire; +import com.hbm.tileentity.turret.TileEntityTurretTau; +import com.hbm.tileentity.turret.TileEntityTurretTauon; +import com.hbm.util.BobMathUtil; + +import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.client.registry.RenderingRegistry; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.ReflectionHelper; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.audio.PositionedSoundRecord; @@ -23,85 +655,14 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Vec3; -import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.client.model.AdvancedModelLoader; import net.minecraftforge.common.MinecraftForge; -import java.awt.Color; -import java.awt.Desktop; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; - -import com.hbm.blocks.ModBlocks; -import com.hbm.blocks.generic.BlockBobble.TileEntityBobble; -import com.hbm.blocks.generic.BlockEmitter.TileEntityEmitter; -import com.hbm.blocks.generic.BlockLoot.TileEntityLoot; -import com.hbm.entity.cart.*; -import com.hbm.entity.effect.*; -import com.hbm.entity.grenade.*; -import com.hbm.entity.item.*; -import com.hbm.entity.logic.*; -import com.hbm.entity.missile.*; -import com.hbm.entity.mob.*; -import com.hbm.entity.mob.botprime.*; -import com.hbm.entity.mob.siege.*; -import com.hbm.entity.particle.*; -import com.hbm.entity.projectile.*; -import com.hbm.handler.HbmKeybinds; -import com.hbm.handler.HbmKeybinds.EnumKeybind; -import com.hbm.items.ModItems; -import com.hbm.items.ItemAmmoEnums.AmmoHandGrenade; -import com.hbm.particle.*; -import com.hbm.render.anim.*; -import com.hbm.render.anim.HbmAnimations.Animation; -import com.hbm.render.block.*; -import com.hbm.render.entity.*; -import com.hbm.render.entity.effect.*; -import com.hbm.render.entity.item.*; -import com.hbm.render.entity.mob.*; -import com.hbm.render.entity.projectile.*; -import com.hbm.render.entity.rocket.*; -import com.hbm.render.item.*; -import com.hbm.render.item.block.*; -import com.hbm.render.item.weapon.*; -import com.hbm.render.loader.HmfModelLoader; -import com.hbm.render.tileentity.*; -import com.hbm.render.util.MissilePart; -import com.hbm.render.util.RenderInfoSystem; -import com.hbm.render.util.RenderInfoSystem.InfoEntry; -import com.hbm.sound.AudioWrapper; -import com.hbm.sound.AudioWrapperClient; -import com.hbm.sound.AudioWrapperClientStartStop; -import com.hbm.sound.nt.ISoundSourceTE; -import com.hbm.sound.nt.SoundWrapper; -import com.hbm.sound.nt.SoundWrapperClient; -import com.hbm.tileentity.TileEntityDoorGeneric; -import com.hbm.tileentity.bomb.*; -import com.hbm.tileentity.conductor.*; -import com.hbm.tileentity.deco.*; -import com.hbm.tileentity.machine.*; -import com.hbm.tileentity.machine.oil.*; -import com.hbm.tileentity.machine.rbmk.*; -import com.hbm.tileentity.machine.storage.*; -import com.hbm.tileentity.network.*; -import com.hbm.tileentity.turret.*; -import com.hbm.util.BobMathUtil; - -import cpw.mods.fml.client.registry.ClientRegistry; -import cpw.mods.fml.client.registry.RenderingRegistry; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.relauncher.ReflectionHelper; - public class ClientProxy extends ServerProxy { public RenderInfoSystem theInfoSystem = new RenderInfoSystem(); @@ -1817,9 +2378,12 @@ public class ClientProxy extends ServerProxy { break; } case "casing": - final SpentCasingConfig casingConfig = SpentCasingConfig.get(data.getString("name")); - for (int i = 0; i < casingConfig.getCasingAmount(); i++) - casingConfig.spawnCasing(man, world, x, y, z, data.getFloat("pitch"), data.getFloat("yaw"), data.getBoolean("crouched")); + if (WeaponConfig.spawnCasings) + { + final SpentCasingConfig casingConfig = SpentCasingConfig.get(data.getString("name")); + for (int i = 0; i < casingConfig.getCasingAmount(); i++) + casingConfig.spawnCasing(man, world, x, y, z, data.getFloat("pitch"), data.getFloat("yaw"), data.getBoolean("crouched")); + } break; default: break; @@ -1859,12 +2423,6 @@ public class ClientProxy extends ServerProxy { return audio; } - @Override - public SoundWrapper getTileSound(String sound, ISoundSourceTE tile) { - SoundWrapperClient wrapper = new SoundWrapperClient(sound, tile); - return wrapper; - } - @Override public void playSound(String sound, Object data) { } diff --git a/src/main/java/com/hbm/main/ServerProxy.java b/src/main/java/com/hbm/main/ServerProxy.java index 9a8f17ce2..aa28b5f51 100644 --- a/src/main/java/com/hbm/main/ServerProxy.java +++ b/src/main/java/com/hbm/main/ServerProxy.java @@ -4,9 +4,8 @@ import java.util.ArrayList; import java.util.List; import com.hbm.handler.HbmKeybinds.EnumKeybind; +import com.hbm.saveddata.TomSaveData; import com.hbm.sound.AudioWrapper; -import com.hbm.sound.nt.ISoundSourceTE; -import com.hbm.sound.nt.SoundWrapper; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; @@ -14,7 +13,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; -public abstract class ServerProxy { +public class ServerProxy { //sort by estimated time of display. longer lasting ones should be sorted at the top. public static final int ID_DUCK = 0; @@ -28,47 +27,59 @@ public abstract class ServerProxy { public static final int ID_GUN_MODE = 8; public static final int ID_GAS_HAZARD = 9; - public abstract void registerRenderInfo(); - public abstract void registerTileEntitySpecialRenderer(); - public abstract void registerItemRenderer(); - public abstract void registerEntityRenderer(); - public abstract void registerBlockRenderer(); + public void registerRenderInfo() { } + public void registerTileEntitySpecialRenderer() { } + public void registerItemRenderer() { } + public void registerEntityRenderer() { } + public void registerBlockRenderer() { } - public abstract void particleControl(double x, double y, double z, int type); + public void particleControl(double x, double y, double z, int type) { } - public abstract void spawnParticle(double x, double y, double z, String type, float... args); + public void spawnParticle(double x, double y, double z, String type, float[] args) { } - public abstract void effectNT(NBTTagCompound data); + public void effectNT(NBTTagCompound data) { } - public abstract void registerMissileItems(); + public void registerMissileItems() { } - public abstract AudioWrapper getLoopedSound(String sound, float x, float y, float z, float volume, float pitch); - public abstract AudioWrapper getLoopedSoundStartStop(World world, String sound, String start, String stop, float x, float y, float z, float volume, float pitch); + public AudioWrapper getLoopedSound(String sound, float x, float y, float z, float volume, float pitch) { return null; } + public AudioWrapper getLoopedSoundStartStop(World world, String sound, String start, String stop, float x, float y, float z, float volume, float pitch) { return null; } - public abstract void playSound(String sound, Object data); + public void playSound(String sound, Object data) { } public void displayTooltip(String msg, int id) { displayTooltip(msg, 1000, id); } - public abstract void displayTooltip(String msg, int time, int id); + public void displayTooltip(String msg, int time, int id) { } - public abstract boolean getIsKeyPressed(EnumKeybind key); - public abstract EntityPlayer me(); - - public abstract boolean isVanished(Entity e); - - public abstract void openLink(String url); - - @SuppressWarnings({ "unused", "static-method" }) - public SoundWrapper getTileSound(String sound, ISoundSourceTE source) { - return new SoundWrapper(); + public boolean getIsKeyPressed(EnumKeybind key) { + return false; } + public EntityPlayer me() { + return null; + } + + public boolean isVanished(Entity e) { + return false; + } + + public void openLink(String url) { } - @SuppressWarnings("static-method") public List getSubItems(ItemStack stack) { - List list = new ArrayList(); + List list = new ArrayList<>(); list.add(stack); return list; } + + public float getImpactDust(World world) { + return TomSaveData.forWorld(world).dust; + } + + public float getImpactFire(World world) { + return TomSaveData.forWorld(world).fire; + } + + public boolean getImpact(World world) { + return TomSaveData.forWorld(world).impact; + } } \ No newline at end of file diff --git a/src/main/java/com/hbm/particle/ParticleSpentCasing.java b/src/main/java/com/hbm/particle/ParticleSpentCasing.java index ae401cb95..7667d7ef7 100644 --- a/src/main/java/com/hbm/particle/ParticleSpentCasing.java +++ b/src/main/java/com/hbm/particle/ParticleSpentCasing.java @@ -14,24 +14,24 @@ import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.particle.EntityFX; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.util.Vec3; import net.minecraft.world.World; @SideOnly(Side.CLIENT) public class ParticleSpentCasing extends EntityFX { - private static final float dScale = 0.05f, smokeJitter = 0.025f; - private static final byte smokeAccel = 1; + private static final float dScale = 0.05f;//, smokeJitter = 0.025f, smokeAccel = 0.5f; +// private static final byte maxSmokeGen = 60, maxSmokeLife = 120; private final List> smokeNodes = new ArrayList>(); private final TextureManager textureManager; - private final float momentumPitch, momentumYaw; private final SpentCasingConfig config; - private final boolean smoke; +// private final boolean smoke; + private float momentumPitch, momentumYaw; private boolean onGroundPreviously = false; + private double maxHeight; public ParticleSpentCasing(TextureManager textureManager, World world, double x, double y, double z, double mx, double my, double mz, float momentumPitch, float momentumYaw, SpentCasingConfig config) { super(world, x, y, z, 0, 0, 0); @@ -41,15 +41,17 @@ public class ParticleSpentCasing extends EntityFX this.config = config; particleMaxAge = 240; - smoke = config.getSmokeChance() == 0 ? true - : config.getSmokeChance() < 0 ? false - : rand.nextInt(config.getSmokeChance()) == 0; +// smoke = config.getSmokeChance() == 0 ? true +// : config.getSmokeChance() < 0 ? false +// : rand.nextInt(config.getSmokeChance()) == 0; motionX = mx; motionY = my; motionZ = mz; particleGravity = 8f; + + maxHeight = y; } @Override @@ -63,38 +65,48 @@ public class ParticleSpentCasing extends EntityFX { super.onUpdate(); - if (!onGroundPreviously && onGround) - onGroundPreviously = true; - else if (onGroundPreviously && !onGround) - onGroundPreviously = false; - + if (motionY > 0 && posY > maxHeight) + maxHeight = posY; + if (!onGroundPreviously && onGround) tryPlayBounceSound(); - if (particleAge > 120 && !smokeNodes.isEmpty()) - smokeNodes.clear(); - - if (smoke && particleAge <= 120) + // TODO Bounce factor in config + if (!onGroundPreviously && onGround) { - final double side = (rotationYaw - prevRotationYaw) * 0.1D; - final Vec3 prev = Vec3.createVectorHelper(motionX, -motionY, motionZ); - prev.rotateAroundY((float) Math.toRadians(rotationYaw)); + onGroundPreviously = true; + motionY = Math.log10(maxHeight - posY + 2); + momentumPitch = (float) rand.nextGaussian() * config.getPitchFactor(); + momentumYaw = (float) rand.nextGaussian() * config.getYawFactor(); - for (Pair pair : smokeNodes) - { - final EasyLocation node = pair.getKey(); - - node.posX += prev.xCoord * smokeAccel + rand.nextGaussian() * smokeJitter + side; - node.posY += prev.yCoord + 1.5; - node.posZ += prev.zCoord * smokeAccel + rand.nextGaussian() * smokeJitter; - } - - if (particleAge < 60) - { - final double alpha = (particleAge / 20d); - smokeNodes.add(new Pair(EasyLocation.getZeroLocation(), alpha)); - } - } + maxHeight = posY; + } else if (onGroundPreviously && !onGround) + onGroundPreviously = false; + +// if (particleAge > maxSmokeLife && !smokeNodes.isEmpty()) +// smokeNodes.clear(); + +// if (smoke && particleAge <= maxSmokeLife) +// { +// final double side = (rotationYaw - prevRotationYaw) * 0.1D; +// final Vec3 prev = Vec3.createVectorHelper(motionX, motionY, motionZ); +// prev.rotateAroundY((float) Math.toRadians(rotationYaw)); +// +// for (Pair pair : smokeNodes) +// { +// final EasyLocation node = pair.getKey(); +// +// node.posX += prev.xCoord * smokeAccel + rand.nextGaussian() * smokeJitter + side; +// node.posY += prev.yCoord + smokeAccel; +// node.posZ += prev.zCoord * smokeAccel + rand.nextGaussian() * smokeJitter; +// } +// +// if (particleAge < maxSmokeGen || inWater) +// { +// final double alpha = (particleAge / 20d); +// smokeNodes.add(new Pair(EasyLocation.getZeroLocation(), alpha)); +// } +// } prevRotationPitch = rotationPitch; prevRotationYaw = rotationYaw; @@ -188,7 +200,8 @@ public class ParticleSpentCasing extends EntityFX private void tryPlayBounceSound() { if (!config.getBounceSound().isEmpty()) - worldObj.playSoundEffect(posX, posY, posZ, config.getBounceSound(), 1, 1); + worldObj.playSoundAtEntity(this, config.getBounceSound(), 2, 1); +// playSound(config.getBounceSound(), 2, 1); } // private static float[] getOffset(float time) diff --git a/src/main/java/com/hbm/particle/SpentCasingConfig.java b/src/main/java/com/hbm/particle/SpentCasingConfig.java index 8fd314de4..e6b07db31 100644 --- a/src/main/java/com/hbm/particle/SpentCasingConfig.java +++ b/src/main/java/com/hbm/particle/SpentCasingConfig.java @@ -66,7 +66,7 @@ public class SpentCasingConfig private final byte delay; /**Chance for the casing to emit smoke. 0 for 100% chance and -1 for it to never make smoke.**/ private final byte smokeChance; - + // TODO Setting to disregard crouch effect and/or another offset specifically for crouching which can be set to null to use the default one public SpentCasingConfig( String registryName, ILocationProvider posOffset, Vec3 initialMotion, float pitchFactor, float yawFactor, float scaleX, float scaleY, float scaleZ, int redOverride, int greenOverride, int blueOverride, diff --git a/src/main/java/com/hbm/util/ParticleUtil.java b/src/main/java/com/hbm/util/ParticleUtil.java index 0428ec19b..e3d742f2b 100644 --- a/src/main/java/com/hbm/util/ParticleUtil.java +++ b/src/main/java/com/hbm/util/ParticleUtil.java @@ -1,8 +1,10 @@ package com.hbm.util; +import com.hbm.interfaces.ILocationProvider; import com.hbm.main.MainRegistry; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasingConfig; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraft.nbt.NBTTagCompound; @@ -27,4 +29,27 @@ public class ParticleUtil { PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, x, y, z), new TargetPoint(world.provider.dimensionId, x, y, z, 150)); } } + + /** + * Spawn a spent shell casing. + * @param location Location to spawn from. + * @param config The shell casing configuration to use. + * @param pitch Pitch rotation in radians. + * @param yaw Yaw rotation in radians. + * @param heightAdjustment Height adjustment. + * @param sneaking Assume from a sneaking/crouched entity. + */ + public static void spawnCasing(ILocationProvider location, SpentCasingConfig config, float pitch, float yaw, float heightAdjustment, boolean sneaking) + { + final NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "casing"); + data.setDouble("posX", location.posX()); + data.setDouble("posY", location.posY() + heightAdjustment); + data.setDouble("posZ", location.posZ()); + data.setFloat("pitch", pitch); + data.setFloat("yaw", yaw); + data.setBoolean("crouched", sneaking); + data.setString("name", config.getRegistryName()); + MainRegistry.proxy.effectNT(data); + } } diff --git a/src/main/java/com/hbm/util/Quaternion.java b/src/main/java/com/hbm/util/Quaternion.java deleted file mode 100644 index 21aa12ed9..000000000 --- a/src/main/java/com/hbm/util/Quaternion.java +++ /dev/null @@ -1,302 +0,0 @@ -package com.hbm.util; - -import java.io.Serializable; -import java.util.Objects; - -import com.hbm.interfaces.IByteSerializable; -import com.hbm.interfaces.INBTSerializable; -import com.hbm.main.DeserializationException; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.Vec3; - -/** - * Credits to Apache for the basic structure. - * @author UFFR - * - */ -public class Quaternion implements Serializable, Cloneable, IByteSerializable, INBTSerializable -{ - /** - * - */ - private static final long serialVersionUID = -403051011515625947L; - private double w, x, y, z; - - public Quaternion(double pitch, double yaw) - { - final double rPitch = Math.toRadians(pitch), - rYaw = Math.toRadians(yaw), - - cp = Math.cos(rPitch * 0.5), - sp = Math.sin(rPitch * 0.5), - cy = Math.cos(rYaw * 0.5), - sy = Math.sin(rYaw * 0.5); - - w = cy * sp; - x = sy * cp; - y = sy * cp; - z = cy * cp; - } - - public Quaternion(double roll, double pitch, double yaw) - { - final double rRoll = Math.toRadians(roll), - rPitch = Math.toRadians(pitch), - rYaw = Math.toRadians(yaw), - - cr = Math.cos(rRoll * 0.5), - sr = Math.sin(rRoll * 0.5), - cp = Math.cos(rPitch * 0.5), - sp = Math.sin(rPitch * 0.5), - cy = Math.cos(rYaw * 0.5), - sy = Math.sin(rYaw * 0.5); - - w = cr * cp * cy + sr * sp * sy; - x = sr * cp * cy - cr * sp * sy; - y = cr * sp * cy + sr * cp * sy; - z = cr * cp * sy - sr * sp * cy; - - } - - public Quaternion(double w, double x, double y, double z) - { - this.w = w; - this.x = x; - this.y = y; - this.z = z; - } - - public Quaternion(double w, Vec3 vec3) - { - this.w = w; - - x = vec3.xCoord; - y = vec3.yCoord; - z = vec3.zCoord; - } - - public Quaternion(Vec3 vec3) - { - this(0, vec3); - } - - public Quaternion(double w, double[] vector) - { - if (vector.length != 3) - throw new IllegalArgumentException("Vector argument must only have 3 values!"); - - this.w = w; - - x = vector[0]; - y = vector[1]; - z = vector[2]; - } - - public Quaternion(double[] vector) - { - this(0, vector); - } - - public Quaternion getConjugate() - { - return new Quaternion(w, -x, -y, -z); - } - - public Quaternion add(Quaternion q) - { - return add(this, q); - } - - public Quaternion subtract(Quaternion q) - { - return subtract(this, q); - } - - public Quaternion multiply(Quaternion q) - { - return multiply(this, q); - } - - public Quaternion dotProduct(Quaternion q) - { - return dotProduct(this, q); - } - - public double getNorm() - { - return Math.sqrt(w * w + x * x + y * y + z * z); - } - - public Quaternion normalize() - { - final double norm = getNorm(); - if (norm < Double.MIN_NORMAL) - throw new ArithmeticException("Quaternion norm zero!"); - - return new Quaternion( - w / norm, - x / norm, - y / norm, - z / norm); - } - - public double getPitch() - { - return Math.atan2(2 * (y * z + w * x), w * w - x * x - y * y + z * z); - } - - public double getYaw() - { - return Math.asin(-2 * (x * z - w * y)); - } - - public double getRoll() - { - return Math.atan2(2 * (x * y + w * z), w * w + x * x - y * y - z * z); - } - - public static Quaternion add(Quaternion q1, Quaternion q2) - { - return new Quaternion(q1.w + q2.w, q1.x + q2.x, q1.y + q2.y, q1.z + q2.z); - } - - public static Quaternion subtract(Quaternion q1, Quaternion q2) - { - return new Quaternion(q1.w - q2.w, q1.x - q2.x, q1.y - q2.y, q1.z - q2.z); - } - - public static Quaternion multiply(Quaternion q1, Quaternion q2) - { - return new Quaternion( - q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z, - q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y, - q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x, - q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w - ); - } - - public static Quaternion dotProduct(Quaternion q1, Quaternion q2) - { - return new Quaternion(q1.w * q2.w, q1.x * q2.x, q1.y * q2.y, q1.z * q2.z); - } - - public static Vec3 rotate(Quaternion q, Vec3 vec3) - { - return q.multiply(new Quaternion(vec3)).multiply(q.getConjugate()).getVector(); - } - - public static Vec3 rotate(Quaternion q, Vec3 vec3, Vec3 origin) - { - return q.multiply(new Quaternion(vec3.subtract(origin))).multiply(q.getConjugate()).getVector().addVector(origin.xCoord, origin.yCoord, origin.zCoord); - } - - public double getW() - { - return w; - } - - public double getX() - { - return x; - } - - public double getY() - { - return y; - } - - public double getZ() - { - return z; - } - - public Vec3 getVector() - { - return Vec3.createVectorHelper(x, y, z); - } - - @Override - public void writeToNBT(NBTTagCompound nbt) - { - nbt.setDouble("w", w); - nbt.setDouble("x", x); - nbt.setDouble("y", y); - nbt.setDouble("z", z); - } - - @Override - public void readFromNBT(NBTTagCompound nbt) - { - w = nbt.getDouble("w"); - x = nbt.getDouble("x"); - y = nbt.getDouble("y"); - z = nbt.getDouble("z"); - } - - @Override - public void writeToBytes(ByteBuf buf) - { - buf.writeDouble(w).writeDouble(x).writeDouble(y).writeDouble(z); - } - - @Override - public void readFromBytes(byte[] bytes) throws DeserializationException - { - try - { - final ByteBuf buf = Unpooled.copiedBuffer(bytes); - w = buf.readDouble(); - x = buf.readDouble(); - y = buf.readDouble(); - z = buf.readDouble(); - } catch (Exception e) - { - throw new DeserializationException(e); - } - } - - @Override - public int hashCode() - { - return Objects.hash(w, x, y, z); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (!(obj instanceof Quaternion)) - return false; - final Quaternion other = (Quaternion) obj; - return Double.doubleToLongBits(w) == Double.doubleToLongBits(other.w) - && Double.doubleToLongBits(x) == Double.doubleToLongBits(other.x) - && Double.doubleToLongBits(y) == Double.doubleToLongBits(other.y) - && Double.doubleToLongBits(z) == Double.doubleToLongBits(other.z); - } - - @Override - public String toString() - { - final StringBuilder builder = new StringBuilder(); - builder.append("Quaternion [w=").append(w).append(", x=").append(x).append(", y=").append(y).append(", z=") - .append(z).append(']'); - return builder.toString(); - } - - @Override - public Quaternion clone() - { - try - { - return (Quaternion) super.clone(); - } catch (CloneNotSupportedException e) - { - return new Quaternion(w, x, y, z); - } - } - -} diff --git a/src/main/resources/assets/hbm/sounds.json b/src/main/resources/assets/hbm/sounds.json index ac277b9c5..9b3d481fb 100644 --- a/src/main/resources/assets/hbm/sounds.json +++ b/src/main/resources/assets/hbm/sounds.json @@ -188,6 +188,10 @@ "weapon.LMGMagInPB3": {"category": "player", "sounds": [{"name": "weapon/LMGIN", "stream": false}]}, "weapon.LMGCockPB3": {"category": "player", "sounds": [{"name": "weapon/LMGCLK", "stream": false}]}, "weapon.shotgunDrumPB3": {"category": "player", "sounds": ["weapon/ASGDRM1", "weapon/ASGDRM2"]}, + "weapon.shotgunShellBouncePB3": {"category": "player", "sounds": ["weapon/DSSHELL1", "weapon/DSSHELL2", "weapon/DSSHELL3"]}, + "weapon.smallCasingBouncePB3": {"category": "player", "sounds": ["weapon/BRASS_C1", "weapon/BRASS_C2", "weapon/BRASS_C3", "weapon/BRASS_C4", "weapon/BRASS_C5"]}, + "weapon.smallMagBouncePB3": {"category": "player", "sounds": ["weapon/DSAOUNC1", "weapon/DSAOUNC2", "weapon/DSAOUNC3", "weapon/DSAOUNC4"]}, + "weapon.largeMagBouncePB3": {"category": "player", "sounds": ["weapon/DSBOUNC1", "weapon/DSBOUNC2", "weapon/DSBOUNC3", "weapon/DSBOUNC4"]}, "weapon.dFlash": {"category": "player", "sounds": [{"name": "weapon/dFlash", "stream": false}]}, diff --git a/src/main/resources/assets/hbm/sounds/weapon/BRASS_C1.ogg b/src/main/resources/assets/hbm/sounds/weapon/BRASS_C1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..0398dc8774603ddf99661c9903f0e6f9b9a5c43d GIT binary patch literal 4717 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/BRASS_C2.ogg b/src/main/resources/assets/hbm/sounds/weapon/BRASS_C2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c16753f77b53503bcb365031676acf8aee0626b7 GIT binary patch literal 5281 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/BRASS_C4.ogg b/src/main/resources/assets/hbm/sounds/weapon/BRASS_C4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a94b2078395858851b302041c77db2276cd52fc7 GIT binary patch literal 4530 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/BRASS_C5.ogg b/src/main/resources/assets/hbm/sounds/weapon/BRASS_C5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..79890e955595d7a6fba242f635344a3541c74b4c GIT binary patch literal 6288 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 b&&04%RoYT3Fk{C2!Q9fcpo`(nEu#Mh8!9LO literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/DSAOUNC2.ogg b/src/main/resources/assets/hbm/sounds/weapon/DSAOUNC2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6179b63661ddaf29a711abab4158c26619974efd GIT binary patch literal 6466 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 NI&Za(;KG)H{te40^MC*V literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/DSAOUNC3.ogg b/src/main/resources/assets/hbm/sounds/weapon/DSAOUNC3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6b09798ca41e1e2b152f0ed9e7ac8804c3dccf8d GIT binary patch literal 6658 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/DSBOUNC1.ogg b/src/main/resources/assets/hbm/sounds/weapon/DSBOUNC1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..100fc5dd050e8c4c6e56a235e0fb8fb98131fc40 GIT binary patch literal 4774 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/DSSHELL1.ogg b/src/main/resources/assets/hbm/sounds/weapon/DSSHELL1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a64fffc514fa08cfa19ba12412774e7f6a555cf8 GIT binary patch literal 4721 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/hbm/sounds/weapon/DSSHELL2.ogg b/src/main/resources/assets/hbm/sounds/weapon/DSSHELL2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..98983bf66290b100b7a83f284b6e80ca338941ff GIT binary patch literal 4582 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