From 00e8675a15308632396778e1d03c29169c2fa3ba Mon Sep 17 00:00:00 2001 From: Bob Date: Sat, 4 Feb 2023 15:28:24 +0100 Subject: [PATCH] spent casings for turrets, finished 12ga percussive caps --- .../entity/projectile/EntityBulletBase.java | 4 + .../hbm/handler/guncfg/Gun12GaugeFactory.java | 75 +++++++++--------- .../com/hbm/handler/guncfg/Gun5mmFactory.java | 2 +- .../hbm/handler/guncfg/GunCannonFactory.java | 18 +++++ .../com/hbm/handler/guncfg/GunDGKFactory.java | 9 +++ src/main/java/com/hbm/items/ModItems.java | 2 +- .../com/hbm/items/weapon/ItemAmmoArty.java | 28 ++++--- .../com/hbm/particle/ParticleSpentCasing.java | 6 +- .../java/com/hbm/particle/SpentCasing.java | 10 +++ .../turret/TileEntityTurretArty.java | 28 +++++++ .../turret/TileEntityTurretBaseNT.java | 40 ++++++---- .../turret/TileEntityTurretChekhov.java | 26 +++++- .../turret/TileEntityTurretFriendly.java | 8 ++ .../turret/TileEntityTurretHoward.java | 33 ++++++++ .../turret/TileEntityTurretHowardDamaged.java | 4 + .../turret/TileEntityTurretJeremy.java | 30 +++++++ .../turret/TileEntityTurretSentry.java | 25 ++++++ src/main/resources/assets/hbm/lang/de_DE.lang | 1 + src/main/resources/assets/hbm/lang/en_US.lang | 1 + .../hbm/textures/models/turrets/howard.png | Bin 1900 -> 1932 bytes 20 files changed, 280 insertions(+), 70 deletions(-) diff --git a/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java b/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java index ccff05ac4..81e67cac1 100644 --- a/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java +++ b/src/main/java/com/hbm/entity/projectile/EntityBulletBase.java @@ -251,6 +251,10 @@ public class EntityBulletBase extends Entity implements IProjectile { } if(config.maxAge == 0) { + + if(this.config.bUpdate != null) + this.config.bUpdate.behaveUpdate(this); + this.setDead(); return; } diff --git a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java index 51940cc74..3789f36f2 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun12GaugeFactory.java @@ -9,6 +9,7 @@ import com.hbm.handler.BulletConfiguration; import com.hbm.handler.CasingEjector; import com.hbm.handler.GunConfiguration; import com.hbm.interfaces.IBulletHurtBehavior; +import com.hbm.interfaces.IBulletUpdateBehavior; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ItemAmmoEnums.Ammo12Gauge; import com.hbm.items.ModItems; @@ -110,14 +111,7 @@ public class Gun12GaugeFactory { config.firingSound = "hbm:weapon.shotgunPump"; config.reloadType = GunConfiguration.RELOAD_SINGLE; - - config.config = new ArrayList(); - config.config.add(BulletConfigSyncingUtil.G12_NORMAL); - config.config.add(BulletConfigSyncingUtil.G12_INCENDIARY); - config.config.add(BulletConfigSyncingUtil.G12_SHRAPNEL); - config.config.add(BulletConfigSyncingUtil.G12_DU); - config.config.add(BulletConfigSyncingUtil.G12_AM); - config.config.add(BulletConfigSyncingUtil.G12_SLEEK); + config.config = HbmCollection.twelveGauge; config.ejector = EJECTOR_SPAS_ALT; @@ -305,43 +299,50 @@ public class Gun12GaugeFactory { public static BulletConfiguration get12GaugePercussionConfig() { - BulletConfiguration bullet = new BulletConfiguration(); + BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); bullet.ammo = new ComparableStack(ModItems.ammo_12gauge.stackFromEnum(Ammo12Gauge.PERCUSSION)); + bullet.velocity = 2F; bullet.spread = 0F; - bullet.spentCasing = CASING12GAUGE.clone().register("12GaPerc").setColor(0x9E1616, SpentCasing.COLOR_CASE_12GA); - + bullet.wear = 10; + bullet.dmgMin = 30F; + bullet.dmgMax = 30F; bullet.maxAge = 0; + + bullet.spentCasing = CASING12GAUGE.clone().register("12GaPerc").setColor(0x9E1616, SpentCasing.COLOR_CASE_12GA); - bullet.bUpdate = (entityBullet) -> { + bullet.bUpdate = new IBulletUpdateBehavior() { - if(!entityBullet.worldObj.isRemote) { + @Override + public void behaveUpdate(EntityBulletBase bullet) { - Vec3 vec = Vec3.createVectorHelper(entityBullet.motionX, entityBullet.motionY, entityBullet.motionZ); - double radius = vec.lengthVector(); - double x = entityBullet.posX + vec.xCoord; - double y = entityBullet.posY + vec.yCoord; - double z = entityBullet.posZ + vec.zCoord; - AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(x, y, z, x, y, z).expand(radius, radius, radius); - List list = entityBullet.worldObj.getEntitiesWithinAABBExcludingEntity(entityBullet.shooter, aabb); - - for(Entity e : list) { - DamageSource source = entityBullet.shooter instanceof EntityPlayer ? DamageSource.causePlayerDamage((EntityPlayer) entityBullet.shooter) : DamageSource.magic; - e.attackEntityFrom(source, 30F); + if(!bullet.worldObj.isRemote) { + + Vec3 vec = Vec3.createVectorHelper(bullet.motionX, bullet.motionY, bullet.motionZ); + double radius = 4; + double x = bullet.posX + vec.xCoord; + double y = bullet.posY + vec.yCoord; + double z = bullet.posZ + vec.zCoord; + AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(x, y, z, x, y, z).expand(radius, radius, radius); + List list = bullet.worldObj.getEntitiesWithinAABBExcludingEntity(bullet.shooter, aabb); + + for(Entity e : list) { + DamageSource source = bullet.shooter instanceof EntityPlayer ? DamageSource.causePlayerDamage((EntityPlayer) bullet.shooter) : DamageSource.magic; + e.attackEntityFrom(source, 30F); + } + + NBTTagCompound data = new NBTTagCompound(); + data.setString("type", "plasmablast"); + data.setFloat("r", 0.75F); + data.setFloat("g", 0.75F); + data.setFloat("b", 0.75F); + data.setFloat("pitch", (float) -bullet.rotationPitch + 90); + data.setFloat("yaw", (float) bullet.rotationYaw); + data.setFloat("scale", 2F); + PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, x, y, z), new TargetPoint(bullet.dimension, x, y, z, 100)); + + bullet.setDead(); } - - NBTTagCompound data = new NBTTagCompound(); - data.setString("type", "plasmablast"); - data.setFloat("r", 0.75F); - data.setFloat("g", 0.75F); - data.setFloat("b", 0.75F); - data.setFloat("pitch", (float) Math.toDegrees(entityBullet.rotationPitch)); - data.setFloat("yaw", (float) Math.toDegrees(entityBullet.rotationYaw)); - data.setFloat("scale", 2F); - PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, x, y, z), - new TargetPoint(entityBullet.dimension, x, y, z, 100)); - - entityBullet.setDead(); } }; diff --git a/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java b/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java index 7fa4b6bc8..d1afb609a 100644 --- a/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/Gun5mmFactory.java @@ -19,7 +19,7 @@ public class Gun5mmFactory { static { EJECTOR_MINIGUN = new CasingEjector().setMotion(-0.4, 0.1, 0).setOffset(-0.35, -0.2, 0.35).setAngleRange(0.01F, 0.03F).setAmount(5); - CASING5MM = new SpentCasing(CasingType.STRAIGHT).setScale(1F).setBounceMotion(0.05F, 0.02F).setColor(SpentCasing.COLOR_CASE_BRASS); + CASING5MM = new SpentCasing(CasingType.STRAIGHT).setScale(1.25F).setBounceMotion(0.05F, 0.02F).setColor(SpentCasing.COLOR_CASE_BRASS); } public static GunConfiguration getMinigunConfig() { diff --git a/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java b/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java index 1012f7147..67098cf5a 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunCannonFactory.java @@ -6,8 +6,16 @@ import com.hbm.interfaces.IBulletImpactBehavior; import com.hbm.inventory.RecipesCommon.ComparableStack; import com.hbm.items.ItemAmmoEnums.Ammo240Shell; import com.hbm.items.ModItems; +import com.hbm.particle.SpentCasing; +import com.hbm.particle.SpentCasing.CasingType; public class GunCannonFactory { + + protected static SpentCasing CASINNG240MM; + + static { + CASINNG240MM = new SpentCasing(CasingType.BOTTLENECK).setScale(7.5F).setBounceMotion(0.02F, 0.05F).setColor(SpentCasing.COLOR_CASE_BRASS); + } public static BulletConfiguration getShellConfig() { @@ -19,6 +27,8 @@ public class GunCannonFactory { bullet.explosive = 4F; bullet.blockDamage = false; + bullet.spentCasing = CASINNG240MM.register("240MM"); //same instance everywhere, only register once + return bullet; } @@ -32,6 +42,8 @@ public class GunCannonFactory { bullet.explosive = 4F; bullet.blockDamage = true; + bullet.spentCasing = CASINNG240MM; + return bullet; } @@ -45,6 +57,8 @@ public class GunCannonFactory { bullet.doesPenetrate = true; bullet.style = BulletConfiguration.STYLE_APDS; + bullet.spentCasing = CASINNG240MM; + return bullet; } @@ -58,6 +72,8 @@ public class GunCannonFactory { bullet.doesPenetrate = true; bullet.style = BulletConfiguration.STYLE_APDS; + bullet.spentCasing = CASINNG240MM; + return bullet; } @@ -77,6 +93,8 @@ public class GunCannonFactory { } }; + bullet.spentCasing = CASINNG240MM; + 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 68206c61b..9d96786c2 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunDGKFactory.java @@ -3,13 +3,22 @@ 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.SpentCasing; +import com.hbm.particle.SpentCasing.CasingType; public class GunDGKFactory { + + public static final SpentCasing CASINGDGK; + + static { + CASINGDGK = new SpentCasing(CasingType.STRAIGHT).setScale(1.5F).setBounceMotion(0.05F, 0.02F).setColor(SpentCasing.COLOR_CASE_BRASS).setMaxAge(60); //3 instead of 12 seconds + } public static BulletConfiguration getDGKConfig() { BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); bullet.ammo = new ComparableStack(ModItems.ammo_dgk); + bullet.spentCasing = CASINGDGK.register("DGK"); return bullet; } diff --git a/src/main/java/com/hbm/items/ModItems.java b/src/main/java/com/hbm/items/ModItems.java index 345ff0c30..fe302d335 100644 --- a/src/main/java/com/hbm/items/ModItems.java +++ b/src/main/java/com/hbm/items/ModItems.java @@ -4432,7 +4432,7 @@ public class ModItems { ammo_folly = new ItemCustomLore().setUnlocalizedName("ammo_folly"); ammo_folly_nuclear = new ItemCustomLore().setUnlocalizedName("ammo_folly_nuclear"); ammo_folly_du = new ItemCustomLore().setUnlocalizedName("ammo_folly_du"); - ammo_dgk = new ItemCustomLore().setUnlocalizedName("ammo_dgk"); + //ammo_dgk = new ItemCustomLore().setUnlocalizedName("ammo_dgk"); ammo_arty = new ItemAmmoArty().setUnlocalizedName("ammo_arty"); ammo_himars = new ItemAmmoHIMARS().setUnlocalizedName("ammo_himars"); /*ammo_nuke = new ItemAmmo().setUnlocalizedName("ammo_nuke"); diff --git a/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java b/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java index 1b9b64709..0a07f4ee3 100644 --- a/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java +++ b/src/main/java/com/hbm/items/weapon/ItemAmmoArty.java @@ -20,6 +20,8 @@ import com.hbm.lib.RefStrings; import com.hbm.main.MainRegistry; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; +import com.hbm.particle.SpentCasing; +import com.hbm.particle.SpentCasing.CasingType; import com.hbm.potion.HbmPotion; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @@ -171,14 +173,16 @@ public class ItemAmmoArty extends Item { return "item." + itemTypes[Math.abs(stack.getItemDamage()) % itemTypes.length].name; } + protected static SpentCasing SIXTEEN_INCH_CASE = new SpentCasing(CasingType.STRAIGHT).setScale(15F, 15F, 10F); + public abstract class ArtilleryShell { String name; + public SpentCasing casing; - public ArtilleryShell() { } - - public ArtilleryShell(String name) { + public ArtilleryShell(String name, int casingColor) { this.name = name; + this.casing = SIXTEEN_INCH_CASE.clone().register(name).setColor(casingColor); } public abstract void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop); @@ -231,12 +235,12 @@ public class ItemAmmoArty extends Item { private void init() { /* STANDARD SHELLS */ - this.itemTypes[NORMAL] = new ArtilleryShell("ammo_arty") { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 10F, 3F, false); }}; - this.itemTypes[CLASSIC] = new ArtilleryShell("ammo_arty_classic") { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 5F, false); }}; - this.itemTypes[EXPLOSIVE] = new ArtilleryShell("ammo_arty_he") { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 3F, true); }}; + this.itemTypes[NORMAL] = new ArtilleryShell("ammo_arty", SpentCasing.COLOR_CASE_16INCH) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 10F, 3F, false); }}; + this.itemTypes[CLASSIC] = new ArtilleryShell("ammo_arty_classic", SpentCasing.COLOR_CASE_16INCH) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 5F, false); }}; + this.itemTypes[EXPLOSIVE] = new ArtilleryShell("ammo_arty_he", SpentCasing.COLOR_CASE_16INCH) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { standardExplosion(shell, mop, 15F, 3F, true); }}; /* MINI NUKE */ - this.itemTypes[MINI_NUKE] = new ArtilleryShell("ammo_arty_mini_nuke") { + this.itemTypes[MINI_NUKE] = new ArtilleryShell("ammo_arty_mini_nuke", SpentCasing.COLOR_CASE_16INCH_NUKE) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { shell.killAndClear(); Vec3 vec = Vec3.createVectorHelper(shell.motionX, shell.motionY, shell.motionZ).normalize(); @@ -245,7 +249,7 @@ public class ItemAmmoArty extends Item { }; /* FULL NUKE */ - this.itemTypes[NUKE] = new ArtilleryShell("ammo_arty_nuke") { + this.itemTypes[NUKE] = new ArtilleryShell("ammo_arty_nuke", SpentCasing.COLOR_CASE_16INCH_NUKE) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { shell.worldObj.spawnEntityInWorld(EntityNukeExplosionMK5.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); @@ -258,7 +262,7 @@ public class ItemAmmoArty extends Item { }; /* PHOSPHORUS */ - this.itemTypes[PHOSPHORUS] = new ArtilleryShell("ammo_arty_phosphorus") { + this.itemTypes[PHOSPHORUS] = new ArtilleryShell("ammo_arty_phosphorus", SpentCasing.COLOR_CASE_16INCH_PHOS) { 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); @@ -287,7 +291,7 @@ public class ItemAmmoArty extends Item { }; /* THIS DOOFUS */ - this.itemTypes[CARGO] = new ArtilleryShell("ammo_arty_cargo") { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { + this.itemTypes[CARGO] = new ArtilleryShell("ammo_arty_cargo", SpentCasing.COLOR_CASE_16INCH) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { if(mop.typeOfHit == MovingObjectType.BLOCK) { shell.setPosition(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord); shell.getStuck(mop.blockX, mop.blockY, mop.blockZ); @@ -295,11 +299,11 @@ public class ItemAmmoArty extends Item { }}; /* CLUSTER SHELLS */ - this.itemTypes[PHOSPHORUS_MULTI] = new ArtilleryShell("ammo_arty_phosphorus_multi") { + this.itemTypes[PHOSPHORUS_MULTI] = new ArtilleryShell("ammo_arty_phosphorus_multi", SpentCasing.COLOR_CASE_16INCH_PHOS) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { ItemAmmoArty.this.itemTypes[PHOSPHORUS].onImpact(shell, mop); } public void onUpdate(EntityArtilleryShell shell) { standardCluster(shell, PHOSPHORUS, 10, 300, 5); } }; - this.itemTypes[MINI_NUKE_MULTI] = new ArtilleryShell("ammo_arty_mini_nuke_multi") { + this.itemTypes[MINI_NUKE_MULTI] = new ArtilleryShell("ammo_arty_mini_nuke_multi", SpentCasing.COLOR_CASE_16INCH_NUKE) { public void onImpact(EntityArtilleryShell shell, MovingObjectPosition mop) { ItemAmmoArty.this.itemTypes[MINI_NUKE].onImpact(shell, mop); } 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 be583baa2..f21599e8e 100644 --- a/src/main/java/com/hbm/particle/ParticleSpentCasing.java +++ b/src/main/java/com/hbm/particle/ParticleSpentCasing.java @@ -25,8 +25,8 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; @SideOnly(Side.CLIENT) -public class ParticleSpentCasing extends EntityFX -{ +public class ParticleSpentCasing extends EntityFX { + public static final Random rand = new Random(); private static float dScale = 0.05F, smokeJitter = 0.025F, smokeAccel = 0.5F; private static byte maxSmokeGen = 60, maxSmokeLife = 120; @@ -49,7 +49,7 @@ public class ParticleSpentCasing extends EntityFX this.momentumYaw = momentumYaw; this.config = config; - particleMaxAge = 240; + particleMaxAge = config.getMaxAge(); smoke = rand.nextFloat() < config.getSmokeChance(); motionX = mx; diff --git a/src/main/java/com/hbm/particle/SpentCasing.java b/src/main/java/com/hbm/particle/SpentCasing.java index b66db9107..ae229f026 100644 --- a/src/main/java/com/hbm/particle/SpentCasing.java +++ b/src/main/java/com/hbm/particle/SpentCasing.java @@ -12,6 +12,9 @@ public class SpentCasing implements Cloneable { public static final int COLOR_CASE_12GA = 0x757575; public static final int COLOR_CASE_4GA = 0xD8D8D8; public static final int COLOR_CASE_44 = 0x3E3E3E; + public static final int COLOR_CASE_16INCH = 0xD89128; + public static final int COLOR_CASE_16INCH_PHOS = 0xC8C8C8; + public static final int COLOR_CASE_16INCH_NUKE = 0x495443; public static final HashMap casingMap = new HashMap(); @@ -38,6 +41,7 @@ public class SpentCasing implements Cloneable { private float smokeChance; private float bounceYaw = 0F; private float bouncePitch = 0F; + private int maxAge = 240; public SpentCasing(CasingType type) { this.type = type; @@ -89,6 +93,11 @@ public class SpentCasing implements Cloneable { this.bouncePitch = pitch; return this; } + + public SpentCasing setMaxAge(int age) { + this.maxAge = age; + return this; + } public String getName() { return this.registryName; } public float getScaleX() { return this.scaleX; } @@ -100,6 +109,7 @@ public class SpentCasing implements Cloneable { public float getSmokeChance() { return this.smokeChance; } public float getBounceYaw() { return this.bounceYaw; } public float getBouncePitch() { return this.bouncePitch; } + public int getMaxAge() { return this.maxAge; } @Override public SpentCasing clone() { diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java index 4ad7a19ee..616ca6e1c 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretArty.java @@ -5,9 +5,11 @@ import java.util.List; import com.hbm.blocks.BlockDummyable; import com.hbm.entity.projectile.EntityArtilleryShell; +import com.hbm.handler.CasingEjector; import com.hbm.inventory.container.ContainerTurretBase; import com.hbm.inventory.gui.GUITurretArty; import com.hbm.items.ModItems; +import com.hbm.items.weapon.ItemAmmoArty; import com.hbm.lib.Library; import com.hbm.main.MainRegistry; import com.hbm.packet.AuxParticlePacketNT; @@ -210,6 +212,13 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen proj.setWhistle(true); worldObj.spawnEntityInWorld(proj); + + casingDelay = this.casingDelay(); + } + + @Override + public int casingDelay() { + return 5; } protected void updateConnections() { @@ -333,6 +342,12 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen this.didJustShoot = false; + if(casingDelay > 0) { + casingDelay--; + } else { + spawnCasing(); + } + } else { Vec3 vec = Vec3.createVectorHelper(this.getBarrelLength(), 0, 0); @@ -364,6 +379,7 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen ItemStack conf = this.getShellLoaded(); if(conf != null) { + cachedCasingConfig = ItemAmmoArty.itemTypes[conf.getItemDamage()].casing; this.spawnShell(conf); this.conusmeAmmo(ModItems.ammo_arty); this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.jeremy_fire", 25.0F, 1.0F); @@ -388,6 +404,18 @@ public class TileEntityTurretArty extends TileEntityTurretBaseArtillery implemen } } + protected static CasingEjector ejector = new CasingEjector().setMotion(0, 1.2, 0.5).setAngleRange(0.1F, 0.1F); + + @Override + protected CasingEjector getEjector() { + return ejector; + } + + @Override + protected Vec3 getCasingSpawnPos() { + return this.getTurretPos(); + } + @Override public void handleButtonPacket(int value, int meta) { if(meta == 5) { diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java index c169b4cd9..bebae0017 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretBaseNT.java @@ -12,16 +12,20 @@ import com.hbm.entity.missile.EntitySiegeDropship; import com.hbm.entity.projectile.EntityBulletBase; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.CasingEjector; import com.hbm.interfaces.IControlReceiver; 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.packet.AuxParticlePacketNT; +import com.hbm.packet.PacketDispatcher; import com.hbm.particle.SpentCasing; import com.hbm.tileentity.TileEntityMachineBase; import api.hbm.energy.IEnergyUser; +import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.entity.Entity; @@ -216,6 +220,14 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple NBTTagCompound data = this.writePacket(); this.networkPack(data, 250); + if(usesCasings() && this.casingDelay() > 0) { + if(casingDelay > 0) { + casingDelay--; + } else { + spawnCasing(); + } + } + } else { Vec3 vec = Vec3.createVectorHelper(this.getBarrelLength(), 0, 0); @@ -230,14 +242,6 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple else this.lastRotationYaw -= Math.PI * 2; } - - if(usesCasings() && this.casingDelay() > 0) { - if(casingDelay > 0) { - casingDelay--; - } else { - spawnCasing(); - } - } } } @@ -353,10 +357,11 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple worldObj.spawnEntityInWorld(proj); if(usesCasings()) { - if(this.casingDelay() == 0) + if(this.casingDelay() == 0) { spawnCasing(); - else + } else { casingDelay = this.casingDelay(); + } } } @@ -846,20 +851,25 @@ public abstract class TileEntityTurretBaseNT extends TileEntityMachineBase imple return this.getTurretPos(); } + protected CasingEjector getEjector() { + return null; + } + protected void spawnCasing() { if(cachedCasingConfig == null) return; + CasingEjector ej = getEjector(); Vec3 spawn = this.getCasingSpawnPos(); - final NBTTagCompound data = new NBTTagCompound(); + NBTTagCompound data = new NBTTagCompound(); data.setString("type", "casing"); - data.setDouble("posX", spawn.xCoord); - data.setDouble("posY", spawn.yCoord); - data.setDouble("posZ", spawn.zCoord); data.setFloat("pitch", (float) rotationPitch); data.setFloat("yaw", (float) rotationYaw); data.setBoolean("crouched", false); data.setString("name", cachedCasingConfig.getName()); - MainRegistry.proxy.effectNT(data); + if(ej != null) data.setInteger("ej", ej.getId()); + PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, spawn.xCoord, spawn.yCoord, spawn.zCoord), new TargetPoint(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, 50)); + + cachedCasingConfig = 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..7e2af2be1 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretChekhov.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretChekhov.java @@ -5,6 +5,7 @@ import java.util.List; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.CasingEjector; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; @@ -73,6 +74,7 @@ public class TileEntityTurretChekhov extends TileEntityTurretBaseNT { BulletConfiguration conf = this.getFirstConfigLoaded(); if(conf != null) { + this.cachedCasingConfig = conf.spentCasing; this.spawnBullet(conf); this.conusmeAmmo(conf.ammo); this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.chekhov_fire", 2.0F, 1.0F); @@ -91,6 +93,24 @@ public class TileEntityTurretChekhov extends TileEntityTurretBaseNT { } } } + + @Override + protected Vec3 getCasingSpawnPos() { + + Vec3 pos = this.getTurretPos(); + Vec3 vec = Vec3.createVectorHelper(-1.125, 0.125, 0.25); + vec.rotateAroundZ((float) -this.rotationPitch); + vec.rotateAroundY((float) -(this.rotationYaw + Math.PI * 0.5)); + + return Vec3.createVectorHelper(pos.xCoord + vec.xCoord, pos.yCoord + vec.yCoord, pos.zCoord + vec.zCoord); + } + + protected static CasingEjector ejector = new CasingEjector().setMotion(-0.8, 0.8, 0).setAngleRange(0.1F, 0.1F); + + @Override + protected CasingEjector getEjector() { + return ejector; + } public int getDelay() { return 2; @@ -139,7 +159,11 @@ public class TileEntityTurretChekhov extends TileEntityTurretBaseNT { @Override public void manualSetup() { - manual = true; } + + @Override + public boolean usesCasings() { + return true; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java index cadfc4c94..8a0b679b1 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretFriendly.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import com.hbm.handler.BulletConfigSyncingUtil; +import com.hbm.handler.CasingEjector; public class TileEntityTurretFriendly extends TileEntityTurretChekhov { @@ -31,4 +32,11 @@ public class TileEntityTurretFriendly extends TileEntityTurretChekhov { public int getDelay() { return 5; } + + protected static CasingEjector ejector = new CasingEjector().setMotion(-0.3, 0.6, 0).setAngleRange(0.02F, 0.05F); + + @Override + protected CasingEjector getEjector() { + return ejector; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java index 94df68742..a295b1487 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHoward.java @@ -6,9 +6,12 @@ import java.util.List; import com.hbm.config.WeaponConfig; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.CasingEjector; +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.SpentCasing; import com.hbm.util.EntityDamageUtil; import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; @@ -126,9 +129,16 @@ public class TileEntityTurretHoward extends TileEntityTurretBaseNT { if(loaded > 0 && this.tPos != null) { + SpentCasing cfg = GunDGKFactory.CASINGDGK; + this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.howard_fire", 4.0F, 0.9F + worldObj.rand.nextFloat() * 0.3F); this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.howard_fire", 4.0F, 1F + worldObj.rand.nextFloat() * 0.3F); + for(int i = 0; i < 2; i++) { + this.cachedCasingConfig = cfg; + this.spawnCasing(); + } + if(timer % 2 == 0) { loaded--; @@ -174,4 +184,27 @@ public class TileEntityTurretHoward extends TileEntityTurretBaseNT { super.writeToNBT(nbt); nbt.setInteger("loaded", loaded); } + + @Override + protected Vec3 getCasingSpawnPos() { + + Vec3 pos = this.getTurretPos(); + Vec3 vec = Vec3.createVectorHelper(-0.875, 0.2, -0.125); + vec.rotateAroundZ((float) -this.rotationPitch); + vec.rotateAroundY((float) -(this.rotationYaw + Math.PI * 0.5)); + + return Vec3.createVectorHelper(pos.xCoord + vec.xCoord, pos.yCoord + vec.yCoord, pos.zCoord + vec.zCoord); + } + + protected static CasingEjector ejector = new CasingEjector().setAngleRange(0.01F, 0.01F).setMotion(0, 0, -0.1); + + @Override + protected CasingEjector getEjector() { + return ejector.setMotion(0.4, 0, 0).setAngleRange(0.02F, 0.03F); + } + + @Override + public boolean usesCasings() { + return true; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHowardDamaged.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHowardDamaged.java index 284706ca9..92066229d 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHowardDamaged.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretHowardDamaged.java @@ -1,6 +1,7 @@ package com.hbm.tileentity.turret; import com.hbm.config.WeaponConfig; +import com.hbm.handler.guncfg.GunDGKFactory; import com.hbm.lib.ModDamageSource; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; @@ -70,6 +71,9 @@ public class TileEntityTurretHowardDamaged extends TileEntityTurretHoward { this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.howard_fire", 4.0F, 0.7F + worldObj.rand.nextFloat() * 0.3F); + this.cachedCasingConfig = GunDGKFactory.CASINGDGK; + this.spawnCasing(); + if(worldObj.rand.nextInt(100) + 1 <= WeaponConfig.ciwsHitrate * 0.5) EntityDamageUtil.attackEntityFromIgnoreIFrame(this.target, ModDamageSource.shrapnel, 2F + worldObj.rand.nextInt(2)); diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java index feddb8f2c..3b142f53b 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretJeremy.java @@ -5,6 +5,7 @@ import java.util.List; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.CasingEjector; import com.hbm.packet.AuxParticlePacketNT; import com.hbm.packet.PacketDispatcher; @@ -84,6 +85,7 @@ public class TileEntityTurretJeremy extends TileEntityTurretBaseNT { BulletConfiguration conf = this.getFirstConfigLoaded(); if(conf != null) { + this.cachedCasingConfig = conf.spentCasing; this.spawnBullet(conf); this.conusmeAmmo(conf.ammo); this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.jeremy_fire", 4.0F, 1.0F); @@ -103,4 +105,32 @@ public class TileEntityTurretJeremy extends TileEntityTurretBaseNT { } } } + + @Override + protected Vec3 getCasingSpawnPos() { + + Vec3 pos = this.getTurretPos(); + Vec3 vec = Vec3.createVectorHelper(-2, 0, 0); + vec.rotateAroundZ((float) -this.rotationPitch); + vec.rotateAroundY((float) -(this.rotationYaw + Math.PI * 0.5)); + + return Vec3.createVectorHelper(pos.xCoord + vec.xCoord, pos.yCoord + vec.yCoord, pos.zCoord + vec.zCoord); + } + + protected static CasingEjector ejector = new CasingEjector().setAngleRange(0.01F, 0.01F).setMotion(0, 0, -0.1); + + @Override + protected CasingEjector getEjector() { + return ejector; + } + + @Override + public boolean usesCasings() { + return true; + } + + @Override + public int casingDelay() { + return 22; + } } diff --git a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretSentry.java b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretSentry.java index 1b8bd59e2..5a1a1326b 100644 --- a/src/main/java/com/hbm/tileentity/turret/TileEntityTurretSentry.java +++ b/src/main/java/com/hbm/tileentity/turret/TileEntityTurretSentry.java @@ -5,6 +5,7 @@ import java.util.List; import com.hbm.handler.BulletConfigSyncingUtil; import com.hbm.handler.BulletConfiguration; +import com.hbm.handler.CasingEjector; import com.hbm.inventory.container.ContainerTurretBase; import com.hbm.inventory.gui.GUITurretSentry; import com.hbm.packet.AuxParticlePacketNT; @@ -164,6 +165,7 @@ public class TileEntityTurretSentry extends TileEntityTurretBaseNT implements IG BulletConfiguration conf = this.getFirstConfigLoaded(); if(conf != null) { + this.cachedCasingConfig = conf.spentCasing; this.spawnBullet(conf); this.conusmeAmmo(conf.ammo); this.worldObj.playSoundEffect(xCoord, yCoord, zCoord, "hbm:turret.sentry_fire", 2.0F, 1.0F); @@ -192,6 +194,29 @@ public class TileEntityTurretSentry extends TileEntityTurretBaseNT implements IG } } } + + @Override + protected Vec3 getCasingSpawnPos() { + + Vec3 pos = this.getTurretPos(); + Vec3 vec = Vec3.createVectorHelper(0, 0.25,-0.125); + vec.rotateAroundZ((float) -this.rotationPitch); + vec.rotateAroundY((float) -(this.rotationYaw + Math.PI * 0.5)); + + return Vec3.createVectorHelper(pos.xCoord + vec.xCoord, pos.yCoord + vec.yCoord, pos.zCoord + vec.zCoord); + } + + protected static CasingEjector ejector = new CasingEjector().setMotion(-0.3, 0.6, 0).setAngleRange(0.01F, 0.01F); + + @Override + protected CasingEjector getEjector() { + return ejector.setMotion(0.3, 0.6, 0); + } + + @Override + public boolean usesCasings() { + return true; + } @Override protected void seekNewTarget() { diff --git a/src/main/resources/assets/hbm/lang/de_DE.lang b/src/main/resources/assets/hbm/lang/de_DE.lang index a30e8c37b..3ee5c30f2 100644 --- a/src/main/resources/assets/hbm/lang/de_DE.lang +++ b/src/main/resources/assets/hbm/lang/de_DE.lang @@ -789,6 +789,7 @@ item.ammo_12gauge.name=Kaliber 12 Schrot item.ammo_12gauge_du.name=Kaliber 12 Schrot (Uranbeschichtung) item.ammo_12gauge_incendiary.name=Kaliber 12 Schrot (Brand) item.ammo_12gauge_marauder.name=Kaliber 12 Taktische Anti-Marauder Schrotpatrone +item.ammo_12gauge_percussion.name=Kaliber 12 Sprengkapsel item.ammo_12gauge_shrapnel.name=Kaliber 12 Schrot (Schrapnell) item.ammo_12gauge_sleek.name=Kaliber 12 Schrot (IF-F&E) item.ammo_20gauge.name=Kaliber 20 Schrot diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index 63d2dc848..7fc06eb46 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -1391,6 +1391,7 @@ item.ammo_12gauge.name=12 Gauge Buckshot item.ammo_12gauge_du.name=12 Gauge Buckshot (Uranium Coated) item.ammo_12gauge_incendiary.name=12 Gauge Buckshot (Incendiary) item.ammo_12gauge_marauder.name=12 Gauge Tactical Anti-Marauder Shell +item.ammo_12gauge_percussion.name=12 Gauge Percussion Cap item.ammo_12gauge_shrapnel.name=12 Gauge Buckshot (Shrapnel) item.ammo_12gauge_sleek.name=12 Gauge Buckshot (IF-R&D) item.ammo_20gauge.name=20 Gauge Buckshot diff --git a/src/main/resources/assets/hbm/textures/models/turrets/howard.png b/src/main/resources/assets/hbm/textures/models/turrets/howard.png index 44f4817df547c0f872f9ed723d2c2af433a45ff7..3e40888c2fe60e9e1448429c5bcd233c0b9b2750 100644 GIT binary patch delta 1901 zcmV-z2a@>g4vY_wG=D=$L_t(|ob6mah}%dM{Wv_lH{ZO?O!@B5DHx@foCm`$-4VH-DD7-|zFR<3;WX0LRD2Ya{_cDfI^OnHB+?CdL$phlf0m=>t|IL{Wqw z2+(S^5Cj1_osQA*Znq1Yrq7B-U00|El(uCZw~7CWsu>Or4&nfd!dftK9TA3MYFpOv zA~-%iR<_>=q6ULOA?F@NQ5-A)S3b$~xJ_Jp(^oVC6MsQY6h&Armsl>BF$uHT%*i@# zNBS$=2#qR=*=*(v27@?S48ssdM@J4lZu_3Pd6X5RqA1E8?NntVY(qA6RiknrCDi}A zU@#bPK@25G%p0j@Z34UE=0z^Hq5A!PpJ%0HHX(-$VIe+#{FrF(bUKyImC_Jvl!#nR zLA59EjDK4|mGdhjM-^zbT9x)ML+hjHTbw7g0hG_23&{Nxk;ArDiPTLH1U9?P#EqUu z$v8VZOYFDX?X`1+4-!5Jz(#YEGIoKhOtwe@0!WxLxm{c%M?u1r1wnwjckco~=05GG zXcj(iG$#8U6;ZVRZTKV^360XFN95mi5WEcDzkh$9*uQu0p7vZ_bjP27JJa&34>Bs9 zM}2D;3$}gy{PurLKscVLVF~&!uQL^zVgJ>I%$CYRo#f>z5d7#rI3PNIOva~*GHk&zO z9)FW}ErniN26ASih#X~Q$c5MJYWs*;?K;y(m6_p3Q52{9%c3s%LjDAC&;S5<%91Di z$$_U1@b@@w8UYwxUia9tMcxGf@6#uECnxb+d3t)v0pRn)hxqZ$oA~5juV?+urP?5C z#&9?^($)tL9&iAdOeWUkbEa^p*-QAS*MDq9(l4WgMvccS(imfo=fO(WMqt<9-{%0} z@9%R;769A=(Ae9<`T2QfM^)AJiNRMnYuaW?suet9D@{_6R2JI0zLSd!h(C(Gy*=e` z70T50Wr2pj^bMyZr8)en{nvOrwnh@5uj||S~Kr zurhbIF1Nz;>CUYZRI3rvYKvcIZm-vK{QZ4?a&Zy+DxFDt z@#4kWz}Q;lHGw=RCLy_P`GgFkC*{*cc@WQ|0O0pKcepOF5TJu&(>It5y6T*)>)yV7 zTSy+y^HTeL907DvYw`(@3ADLB@8rZ0WMz@0o6y?IdW$}EZ|ZP3OcX=vUVjuCXxKv5 z7m>D*>Z9b0L=o7i>y!O}ye|*D?mU~>3PDiXOS%bceVId5L6kP|@&s6Qo^9yX>8LC! zQz?@eMG>acsROJ&tOI~ouU;9+oQo*kK-jG7yS$H9qlCGmQD9Ysr9BsIQ)!j_wP9Ik zi8?<&$7cXvHxQ1C$V@lTI)789JFf~K1?U|;h0at8!sMyK;o%`S(JCcTiRFx5FRKr0 zur;tI{g~AD$yh8FM)%j%n*djY<*nP;x{soDd2~tRa$8w2addQ)*!MgyQ`R(163-%& zlw~4Kv2~(UNE>)M_+@-kS}mUd9a!0v$zRZ$f)=~xL0yT`Y80JEm468)I-QQOJf`33 zs)&^d6-zFaMtxOdlfi_kkI-pMnkHp^kX-~@CyG9>c&IerLLXdrUKJU2Qxm6}JE>r* zNdj9ZN+2t5I2;bSe2%J3M$x2f-rSu$;kBKys0C4`bq%Uzj=I2BQdS3RA6wh1>r+7_ zV--G$n`qT_Kxv{jRez<*E?0DEz`z)Dq;Q>gyIsuZa}?Qno)`D+c^;q7=ZTl2Z2v{& z0ltBM2tt=O1X;8Sso88=tLbBmao_h7eTjX!ebcCgkIDjls})s9u~z-``F`e`k%N*L3if0MKkUQ{{0Sr_NQ^eShC~bn-QuO|)7qv|6o9 zS)wRH6h(;R7(ozZwyT5Zd6db_WHpsTCQqY`Fg#q>%_YEcxwQ4@%AgvAj6~h_A~-xe z#A30)d_GT=?-Xs2hdA2v+~fPcrG$L2#f_eaeo|Rxm;qoTqYz0LEz}F+mZeT zcS56zA_xL!I2$ab%nnzh7Dvsma(N0w+!Zt)xS2Zg4QB3`B3x>lX zWyJ6Vv3Vn}S(`wEJ-o=xHdKEw7*JhGW)pIVU>4&1{5)0O?RG1hD`g?kC>FVxg4dqB zGj0Z1&VR3r995v*ZdcmA2&IqWM{%Ci22eh8&LFl^L=M|p#Zot67}{)Bi#t7!Dgx$% zm`?(*(cGkn25^(fW=TK*DN`nvvwOrSh?%l546(Pj2LRf0zMZ03_$s3@X4bcjlt!u2 zBjW!$2)-$(qC5Hw)R~oEeGpOUdemJ4A%qe_D1ZBJyM5JqR7#^-t(MgE0a!DAcMU31 zIMOQhT@BzSv!DvGWu(dcg6#gRbFrPeW;h5TbUYrX3!f9PvdLt^G_5kSzD0c+n3y+? z#L{Fb=TSirIBXu1cP)j#w+zJ0L=id4%8(0h$<6TzvD&nD9#v+BAIEW$?k|hFfWN;_d9ncD9)RZVE-o)GwSNs&wXctLzRX$kWu~NB!4tC5Bne4np`1sZ zUR{Cxc2&JwW>BY1WsyfiY-p3UeSN&Y+N8FL z!2~0#>^?ffXFI@p6vvxDTPDxidek;d;dDB6uKiM~vrM(A=)OK4s=%e{93MlY-|svA z{ysgux=MVN%A~z|^=hqSY_0N|K!5BMlaSoDd`yP%v-0VpJV@qI0Py>R2UHbUFz}sY z(>IuOx~z`wzW49n7m~;Gyv%l=#sEL5HTeX{1j<~WcY5kDvUDV=CbYJ)-mDGPNF9wv zsm+k8fx-tGwxIhW(iSp(l$eny0vr4KL_Z*&iyg13XER&D2+A6yo50qWIe%n3h_X6f zoB+$}*@kMJj+aGdDn%0GIL2%?bAZ){bpY_@%^M?`a}lNL2%G!*uAigSC}!^XD6lHR zvfhg?lWCRswP9H(iMqVJ#Ag6sHxQ1q$V}DIDpRJaSA~xP)Q+Bq%2YDK#Hqs3(GfM# zDk)K^<&1t`*M>FN>R6L@E`KgAQsHA@%!@lC5`K2 zWx>Sp@p0vezR*H z)RicuM)C8gGQmW*+clQQ^jlpSu_B>t$)(b$uWD>Em@xGbDvim~B!Arp*+sB*qWBkP zFO}t6_!n2zt0JRrYT{&bCmBpNiDBzRG3fG!qtS?pb!25CiY8_A=I+D^ukDOQEr>GR z*C1Qws0(Z*WmT~Dv9+yzeKN3Qti&f#6Ro-pC{5I+cBzu<6W(~Wtx>!-0rFi)fL*PsD{4&? zke0!C9gYfV(%u)B^#*g~y| z%8SMKzv8=g4~uXP;6vtlp5t#XJjeHan)g1FW0ssiki6S}?$$O^WamkU00000NkvXX Hu0mjfOh2M!