diff --git a/src/main/java/com/hbm/calc/EasyLocation.java b/src/main/java/com/hbm/calc/EasyLocation.java index d9fbe6a88..c22e6b484 100644 --- a/src/main/java/com/hbm/calc/EasyLocation.java +++ b/src/main/java/com/hbm/calc/EasyLocation.java @@ -263,11 +263,6 @@ public class EasyLocation implements Cloneable, Comparable, ISeria return Objects.hash(dimID, posX, posY, posZ); } - public Vec3 toVec3() - { - return Vec3.createVectorHelper(posX, posY, posZ); - } - @Override public int compareTo(EasyLocation o) { diff --git a/src/main/java/com/hbm/handler/guncfg/GunNPCFactory.java b/src/main/java/com/hbm/handler/guncfg/GunNPCFactory.java index 0e00ee59e..af258a31a 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunNPCFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunNPCFactory.java @@ -28,6 +28,43 @@ import net.minecraft.util.Vec3; public class GunNPCFactory { + public static GunConfiguration getSMGConfig() + { + final GunConfiguration config = GunOSIPRFactory.getOSIPRConfig().clone(); + + config.name = "pulseSMG"; + config.rateOfFire = 1; + config.reloadDuration = 10; + + return config; + } + + public static GunConfiguration getHMGConfig() + { + final GunConfiguration config = GunOSIPRFactory.getOSIPRConfig().clone(); + + config.name = "pulseHMG"; + config.rateOfFire = 1; + config.reloadDuration *= 2; + config.ammoCap = 120; + + return config; + } + + public static GunConfiguration getHeavySGConfig() + { + final GunConfiguration config = Gun4GaugeFactory.getKS23Config().clone(); + + config.name = "heavySG"; + config.rateOfFire = 10; + config.manufacturer = EnumGunManufacturer.COMBINE; + config.ammoCap = 12; + config.reloadDuration = 50; + config.config = HbmCollection.fourGauge; + + return config; + } + public static BulletConfiguration getMaskmanOrb() { BulletConfiguration bullet = new BulletConfiguration(); @@ -330,16 +367,4 @@ public class GunNPCFactory { return bullet; } - - public static GunConfiguration getHeavySGConfig() - { - final GunConfiguration config = new GunConfiguration(); - - config.manufacturer = EnumGunManufacturer.COMBINE; - config.ammoCap = 12; - config.reloadDuration = 50; - config.config = HbmCollection.fourGauge; - - return config; - } } \ No newline at end of file diff --git a/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java b/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java index 6057d267c..e662b397d 100644 --- a/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java +++ b/src/main/java/com/hbm/handler/guncfg/GunOSIPRFactory.java @@ -68,29 +68,6 @@ public class GunOSIPRFactory { return config; } - public static GunConfiguration getSMGConfig() - { - final GunConfiguration config = getOSIPRConfig().clone(); - - config.name = "pulseSMG"; - config.rateOfFire = 1; - config.reloadDuration = 10; - - return config; - } - - public static GunConfiguration getHMGConfig() - { - final GunConfiguration config = getOSIPRConfig().clone(); - - config.name = "pulseHMG"; - config.rateOfFire = 1; - config.reloadDuration *= 2; - config.ammoCap = 120; - - return config; - } - static final float inaccuracy = 1.25f; public static BulletConfiguration getPulseConfig() { @@ -109,6 +86,7 @@ public class GunOSIPRFactory { return bullet; } + static final byte ballVel = 2; public static BulletConfiguration getPulseChargedConfig() { BulletConfiguration bullet = BulletConfigFactory.standardBulletConfig(); @@ -125,17 +103,30 @@ public class GunOSIPRFactory { bullet.liveAfterImpact = true; bullet.spread = 0; bullet.gravity = 0; - bullet.maxAge *= 2; - bullet.velocity /= 2; + bullet.maxAge = 150; + bullet.velocity = ballVel; bullet.bHurt = (ball, entity) -> { if (entity instanceof EntityLivingBase) { - entity.addVelocity(ball.motionX, ball.motionY, ball.motionZ); + final EntityLivingBase entityLiving = (EntityLivingBase) entity; + entity.addVelocity(ball.motionX / 2, ball.motionY / 2, ball.motionZ / 2); - if (entity != ball.shooter && ((EntityLivingBase) entity).getHealth() <= 1000) - ((EntityLivingBase) entity).addPotionEffect(new PotionEffect(HbmPotion.bang.id, 1, 0)); + if (entity == ball.shooter) + return; + + if (entityLiving.getHealth() <= 1000) + { + entityLiving.addPotionEffect(new PotionEffect(HbmPotion.bang.id, 1, 0)); + entityLiving.setLastAttacker(ball.shooter); + } else if (entityLiving.getHealth() > 1000) + { + ball.setDead(); + return; + } + +// tryRedirectBall(ball, entityLiving); } }; @@ -144,6 +135,8 @@ public class GunOSIPRFactory { final Block block = ball.worldObj.getBlock(x, y, z); if (block instanceof RedBarrel) ((RedBarrel) block).explode(ball.worldObj, x, y, z); + +// tryRedirectBall(ball, null); }; bullet.bImpact = (ball, x, y, z) -> @@ -151,8 +144,44 @@ public class GunOSIPRFactory { final Block block = ball.worldObj.getBlock(x, y, z); if (block instanceof RedBarrel) ((RedBarrel) block).explode(ball.worldObj, x, y, z); + +// tryRedirectBall(ball, null); }; 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 diff --git a/src/main/java/com/hbm/interfaces/ILocationProvider.java b/src/main/java/com/hbm/interfaces/ILocationProvider.java index 33ebc5929..eff02cc25 100644 --- a/src/main/java/com/hbm/interfaces/ILocationProvider.java +++ b/src/main/java/com/hbm/interfaces/ILocationProvider.java @@ -17,6 +17,13 @@ public interface ILocationProvider public double posZ(); public boolean hasWorld(); public World getWorld(); + @Override + public String toString(); + + public default Vec3 toVec3() + { + return Vec3.createVectorHelper(posX(), posY(), posZ()); + } public default double[] getCoordDouble() { return new double[] {posX(), posY(), posZ()}; @@ -124,6 +131,14 @@ public interface ILocationProvider { return entity.worldObj; } + @Override + public String toString() + { + final StringBuilder builder = new StringBuilder(); + builder.append("DelegatedEntityLocation [posX()=").append(posX()).append(", posY()=").append(posY()) + .append(", posZ()=").append(posZ()).append(", hasWorld()=").append(hasWorld()).append(']'); + return builder.toString(); + } } static class DelegatedTileEntityLocation implements ILocationProvider @@ -159,6 +174,13 @@ public interface ILocationProvider { return tileEntity.getWorldObj(); } - + @Override + public String toString() + { + final StringBuilder builder = new StringBuilder(); + builder.append("DelegatedTileEntityLocation [posX()=").append(posX()).append(", posY()=").append(posY()) + .append(", posZ()=").append(posZ()).append(", hasWorld()=").append(hasWorld()).append(']'); + return builder.toString(); + } } } diff --git a/src/main/java/com/hbm/items/weapon/ItemGunBase.java b/src/main/java/com/hbm/items/weapon/ItemGunBase.java index 2902cf5db..58186803b 100644 --- a/src/main/java/com/hbm/items/weapon/ItemGunBase.java +++ b/src/main/java/com/hbm/items/weapon/ItemGunBase.java @@ -161,7 +161,8 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu return false; } - public boolean hasAmmo(ItemStack stack, EntityPlayer player, boolean main) {GunConfiguration config = mainConfig; + public boolean hasAmmo(ItemStack stack, EntityPlayer player, boolean main) { + GunConfiguration config = mainConfig; if(!main) config = altConfig; @@ -286,6 +287,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu public void endActionClient(ItemStack stack, World world, EntityPlayer player, boolean main) { } //reload action, if existent + @Deprecated protected void reload(ItemStack stack, World world, EntityPlayer player) { if(getReloadCycle(stack) < 0 && stack == player.getHeldItem()) { @@ -311,7 +313,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu if(getMag(stack) < mainConfig.ammoCap) { - if(InventoryUtil.doesPlayerHaveAStack(player, ammo, true)) { + if(InventoryUtil.doesPlayerHaveAStack(player, ammo, true, false)) { setMag(stack, Math.min(getMag(stack) + bulletCfg.ammoCount, mainConfig.ammoCap)); } else { setIsReloading(stack, false); @@ -339,7 +341,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu final BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(config); - if (InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false)) { + if (InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false, false)) { bulletCfg = cfg; setMagType(stack, mainConfig.config.indexOf(config)); break; @@ -360,7 +362,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu if(getMag(stack) < mainConfig.ammoCap) { - if(InventoryUtil.doesPlayerHaveAStack(player, bulletCfg.ammo, true)) { + if(InventoryUtil.doesPlayerHaveAStack(player, bulletCfg.ammo, true, false)) { setMag(stack, Math.min(getMag(stack) + bulletCfg.ammoCount, mainConfig.ammoCap)); } else { setIsReloading(stack, false); @@ -399,24 +401,34 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu return; } - final BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(mainConfig.config.get(getMagType(stack))); - final ComparableStack ammo = cfg.ammo.copy(); - if(getReloadCycle(stack) <= 0) { if (getMag(stack) == 0) resetAmmoType(stack, world, player); -// if(getMag(stack) == 0) -// resetAmmoType(stack, world, player); - + final BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(mainConfig.config.get(getMagType(stack))); + final ComparableStack ammo = cfg.ammo.copy(); - final int countNeeded = (mainConfig.reloadType == GunConfiguration.RELOAD_FULL) ? mainConfig.ammoCap - getMag(stack) : 1; - final int countAvailable = InventoryUtil.countAStackMatches(player, ammo, true); - final boolean hasLoaded = countAvailable > 0; - final int toAdd = Math.min(countAvailable * cfg.ammoCount, countNeeded); + // Rounds needed + final int countNeeded = (mainConfig.reloadType == GunConfiguration.RELOAD_FULL) ? mainConfig.ammoCap - getMag(stack) : 1; + // Amount of ammo item stacks + final int availableStacks = InventoryUtil.countAStackMatches(player, ammo, true); + // Amount of possible fills given the amount of stacks + final int availableFills = availableStacks * cfg.ammoCount; + // If it has available it will always reload + final boolean hasLoaded = availableFills > 0; + // Amount of ammo to add to the gun in this reload cycle + final int toAdd = Math.min(availableFills * cfg.ammoCount, countNeeded); + // How many items to consume, different than availableStacks and toAdd to prevent potential accidental waste and non-consumptions final int toConsume = (int) Math.ceil((double) toAdd / cfg.ammoCount); + // Skip logic if cannot reload + if (availableFills == 0) + { + setIsReloading(stack, false); + return; + } + ammo.stacksize = toConsume; setMag(stack, getMag(stack) + toAdd); if (getMag(stack) >= mainConfig.ammoCap) @@ -426,7 +438,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu if(hasLoaded && mainConfig.reloadSoundEnd) world.playSoundAtEntity(player, mainConfig.reloadSound, 1.0F, 1.0F); - InventoryUtil.doesPlayerHaveAStack(player, ammo, true); + InventoryUtil.doesPlayerHaveAStack(player, ammo, true, false); } else { setReloadCycle(stack, getReloadCycle(stack) - 1); } @@ -474,41 +486,33 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu if(getMag(stack) == 0) { - for(Integer config : mainConfig.config) { - - BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(config); - - return InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false); - } + for (int config : mainConfig.config) + if (InventoryUtil.doesPlayerHaveAStack(player, BulletConfigSyncingUtil.pullConfig(config).ammo, false, false)) + return true; + + return false; } else { ComparableStack ammo = BulletConfigSyncingUtil.pullConfig(mainConfig.config.get(getMagType(stack))).ammo; - return InventoryUtil.doesPlayerHaveAStack(player, ammo, false); + return InventoryUtil.doesPlayerHaveAStack(player, ammo, false, false); } - - return false; } //searches the player's inv for next fitting ammo type and changes the gun's mag protected void resetAmmoType(ItemStack stack, World world, EntityPlayer player) { - System.out.println("Current type: " + getMagType(stack)); - for(int config : mainConfig.config) { - System.out.println("Checking: " + config); + final BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(config); - BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(config); - - if(InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false)) { + if(InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false, false)) { setMagType(stack, mainConfig.config.indexOf(config)); - System.out.println("Mag type reset"); break; } - System.out.println("Not available"); } + } //item mouseover text @@ -613,7 +617,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(config); - if(InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false)) { + if(InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false, false)) { ammo = cfg.ammo; break; } @@ -632,7 +636,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu BulletConfiguration cfg = BulletConfigSyncingUtil.pullConfig(config); - if(InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false)) { + if(InventoryUtil.doesPlayerHaveAStack(player, cfg.ammo, false, false)) { return cfg; } } @@ -670,7 +674,7 @@ public class ItemGunBase extends Item implements IHoldableWeapon, IItemHUD, IEqu if(config.reloadType != GunConfiguration.RELOAD_NONE) { setMag(stack, getMag(stack) - 1); } else { - InventoryUtil.doesPlayerHaveAStack(player, getBeltType(player, stack, main), true); + InventoryUtil.doesPlayerHaveAStack(player, getBeltType(player, stack, main), true, false); } } diff --git a/src/main/java/com/hbm/items/weapon/ItemGunChemthrower.java b/src/main/java/com/hbm/items/weapon/ItemGunChemthrower.java index 07703d4f8..4778b2d6b 100644 --- a/src/main/java/com/hbm/items/weapon/ItemGunChemthrower.java +++ b/src/main/java/com/hbm/items/weapon/ItemGunChemthrower.java @@ -79,10 +79,10 @@ public class ItemGunChemthrower extends ItemGunBase implements IFillableItem { return; - if(config.reloadType != mainConfig.RELOAD_NONE) { + if(config.reloadType != GunConfiguration.RELOAD_NONE) { setMag(stack, getMag(stack) - this.getConsumption(stack)); } else { - InventoryUtil.doesPlayerHaveAStack(player, getBeltType(player, stack, main), true); + InventoryUtil.doesPlayerHaveAStack(player, getBeltType(player, stack, main), true, true); } } @@ -91,6 +91,7 @@ public class ItemGunChemthrower extends ItemGunBase implements IFillableItem { return false; } + @Override protected void spawnProjectile(World world, EntityPlayer player, ItemStack stack, int config) { //spawn fluid projectile @@ -169,11 +170,11 @@ public class ItemGunChemthrower extends ItemGunBase implements IFillableItem { @Override protected void reload2(ItemStack stack, World world, EntityPlayer player) { - this.setIsReloading(stack, false); + ItemGunBase.setIsReloading(stack, false); } public FluidType getFluidType(ItemStack stack) { - return Fluids.fromID(this.getMagType(stack)); + return Fluids.fromID(ItemGunBase.getMagType(stack)); } public int getConsumption(ItemStack stack) { @@ -182,7 +183,7 @@ public class ItemGunChemthrower extends ItemGunBase implements IFillableItem { @Override public boolean acceptsFluid(FluidType type, ItemStack stack) { - return getFluidType(stack) == type || this.getMag(stack) == 0; + return getFluidType(stack) == type || ItemGunBase.getMag(stack) == 0; } public static final int transferSpeed = 50; @@ -193,16 +194,16 @@ public class ItemGunChemthrower extends ItemGunBase implements IFillableItem { if(!acceptsFluid(type, stack)) return amount; - if(this.getMag(stack) == 0) - this.setMagType(stack, type.getID()); + if(ItemGunBase.getMag(stack) == 0) + ItemGunBase.setMagType(stack, type.getID()); - int fill = this.getMag(stack); + int fill = ItemGunBase.getMag(stack); int req = this.mainConfig.ammoCap - fill; int toFill = Math.min(amount, req); toFill = Math.min(toFill, transferSpeed); - this.setMag(stack, fill + toFill); + ItemGunBase.setMag(stack, fill + toFill); return amount - toFill; } @@ -215,11 +216,11 @@ public class ItemGunChemthrower extends ItemGunBase implements IFillableItem { @Override public int tryEmpty(FluidType type, int amount, ItemStack stack) { - int fill = this.getMag(stack); + int fill = ItemGunBase.getMag(stack); int toUnload = Math.min(fill, amount); toUnload = Math.min(toUnload, transferSpeed); - this.setMag(stack, fill - toUnload); + ItemGunBase.setMag(stack, fill - toUnload); return toUnload; } diff --git a/src/main/java/com/hbm/items/weapon/ItemGunTWR.java b/src/main/java/com/hbm/items/weapon/ItemGunTWR.java index c72838740..49407a8f8 100644 --- a/src/main/java/com/hbm/items/weapon/ItemGunTWR.java +++ b/src/main/java/com/hbm/items/weapon/ItemGunTWR.java @@ -50,10 +50,12 @@ public class ItemGunTWR extends ItemGunBase final DamageSource dmgSrc = new EntityDamageSourceIndirect("twr" + world.rand.nextInt(2) + 2, player, livingEntity).setDamageIsAbsolute().setDamageBypassesArmor().setDamageAllowedInCreativeMode(); if (!livingEntity.attackEntityFrom(dmgSrc, 750)) livingEntity.setHealth(livingEntity.getHealth() - 750); - livingEntity.setLastAttacker(player); - livingEntity.onDeath(dmgSrc); - } - else + if (livingEntity.getHealth() <= 0 || livingEntity.isDead) + { + livingEntity.setLastAttacker(player); + livingEntity.onDeath(dmgSrc); + } + } else entity.setDead(); } } diff --git a/src/main/java/com/hbm/lib/Library.java b/src/main/java/com/hbm/lib/Library.java index 93c4fb185..3c261c648 100644 --- a/src/main/java/com/hbm/lib/Library.java +++ b/src/main/java/com/hbm/lib/Library.java @@ -48,7 +48,7 @@ import net.minecraftforge.common.util.ForgeDirection; @Spaghetti("this whole class") public class Library { - static Random rand = new Random(); + static final Random rand = new Random(); //this is a list of UUIDs used for various things, primarily for accessories. //for a comprehensive list, check RenderAccessoryUtility.java @@ -675,6 +675,23 @@ public class Library { return flag; } + /** + * Produces a gibberish string of random uppercase and lowercase letters and digits. + * @param length The length of the desired string + * @return The produced gibberish string + */ + public static String randomString(int length) + { + final StringBuilder builder = new StringBuilder(length); + for (int i = 0; i < length; i++) + { + builder.append(rand.nextBoolean() + ? (char) (rand.nextInt(26) + (rand.nextBoolean() ? 65 : 97)) + : rand.nextInt(10)); + } + return builder.toString(); + } + public static boolean isObstructed(World world, ILocationProvider loc1, ILocationProvider loc2) { return isObstructed(world, loc1.posX(), loc1.posY(), loc1.posZ(), loc2.posX(), loc2.posY(), loc2.posZ()); diff --git a/src/main/java/com/hbm/render/item/weapon/ItemRenderM2.java b/src/main/java/com/hbm/render/item/weapon/ItemRenderM2.java index 875e4b40a..460921482 100644 --- a/src/main/java/com/hbm/render/item/weapon/ItemRenderM2.java +++ b/src/main/java/com/hbm/render/item/weapon/ItemRenderM2.java @@ -29,7 +29,7 @@ public class ItemRenderM2 extends ItemRenderBase GL11.glScalef(scale1, scale1, -scale1); // GL11.glRotatef(10, 1, 0, 0); GL11.glRotatef(-90, 0, 1, 0); - GL11.glTranslatef(0, 0.5f, -5); + GL11.glTranslatef(-0.4f, 0.5f, -5); GL11.glRotatef(30, 1, 0, 0); break; case EQUIPPED_FIRST_PERSON: diff --git a/src/main/java/com/hbm/util/InventoryUtil.java b/src/main/java/com/hbm/util/InventoryUtil.java index 09e1499cb..9f631f009 100644 --- a/src/main/java/com/hbm/util/InventoryUtil.java +++ b/src/main/java/com/hbm/util/InventoryUtil.java @@ -1,6 +1,5 @@ package com.hbm.util; -import java.util.ArrayList; import java.util.List; import com.hbm.inventory.RecipesCommon.AStack; @@ -228,16 +227,47 @@ public class InventoryUtil { int count = 0; for (ItemStack itemStack : inventory) if (itemStack != null) - if (stack.matchesRecipe(itemStack, ignoreSize)) - count += ignoreSize ? itemStack.stackSize : stack.stacksize;// TODO - return count; + if (stack.matchesRecipe(itemStack, true)) + count += itemStack.stackSize; + return ignoreSize ? count : count / stack.stacksize; } - public static boolean doesPlayerHaveAStack(EntityPlayer player, AStack stack, boolean shouldRemove) + public static boolean doesPlayerHaveAStack(EntityPlayer player, AStack stack, boolean shouldRemove, boolean ignoreSize) { - final List stacks = new ArrayList<>(); - stacks.add(stack); - return doesPlayerHaveAStacks(player, stacks, shouldRemove); + return doesInventoryHaveAStack(player.inventory.mainInventory, stack, shouldRemove, ignoreSize); + } + + public static boolean doesInventoryHaveAStack(ItemStack[] inventory, AStack stack, boolean shouldRemove, boolean ignoreSize) + { + final int totalMatches; + int totalStacks = 0; + for (ItemStack itemStack : inventory) + { + if (itemStack != null && stack.matchesRecipe(itemStack, ignoreSize)) + totalStacks += itemStack.stackSize; + if (!shouldRemove && ignoreSize && totalStacks > 0) + return true; + } + + totalMatches = ignoreSize ? totalStacks : totalStacks / stack.stacksize; + + if (shouldRemove) + { + int consumedStacks = 0, requiredStacks = ignoreSize ? 1 : stack.stacksize; + for (ItemStack itemStack : inventory) + { + if (consumedStacks > requiredStacks) + break; + if (itemStack != null && stack.matchesRecipe(itemStack, true)) + { + final int toConsume = Math.min(itemStack.stackSize, requiredStacks - consumedStacks); + itemStack.stackSize -= toConsume; + consumedStacks += toConsume; + } + } + } + + return totalMatches > 0; } /** diff --git a/src/main/resources/assets/hbm/textures/items/ammo_12gauge.png b/src/main/resources/assets/hbm/textures/items/ammo_12gauge.stock.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_12gauge.png rename to src/main/resources/assets/hbm/textures/items/ammo_12gauge.stock.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_20gauge.png b/src/main/resources/assets/hbm/textures/items/ammo_20gauge.stock.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_20gauge.png rename to src/main/resources/assets/hbm/textures/items/ammo_20gauge.stock.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_22lr.png b/src/main/resources/assets/hbm/textures/items/ammo_22lr.stock.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_22lr.png rename to src/main/resources/assets/hbm/textures/items/ammo_22lr.stock.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_44.png b/src/main/resources/assets/hbm/textures/items/ammo_44.stock.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_44.png rename to src/main/resources/assets/hbm/textures/items/ammo_44.stock.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_5mm.png b/src/main/resources/assets/hbm/textures/items/ammo_5mm.stock.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_5mm.png rename to src/main/resources/assets/hbm/textures/items/ammo_5mm.stock.png diff --git a/src/main/resources/assets/hbm/textures/items/ammo_9mm.png b/src/main/resources/assets/hbm/textures/items/ammo_9mm.stock.png similarity index 100% rename from src/main/resources/assets/hbm/textures/items/ammo_9mm.png rename to src/main/resources/assets/hbm/textures/items/ammo_9mm.stock.png