diff --git a/changelog b/changelog index a095a3967..4e97bda2f 100644 --- a/changelog +++ b/changelog @@ -7,8 +7,11 @@ * Can be upgraded with an auxiliary electric engine to double the firerate * Automatic thresher * A specialized machine for automatically harvesting crops in a 7x7 area - * Replaces the buzzsaw's temporary functiionality to do just that (the buzzsaw now loses that ability) + * Replaces the buzzsaw's temporary functionality to do just that (the buzzsaw now loses that ability) * Drops harvested items using a chute instead of leaving them on the farmland + * When cutting down hemp, willows, and other NTM double plants, only the top part will be cut off, no matter where the thresher touches it + * Can also harvest items from sunflowers and tall grass without breaking the blocks + * Can also handle tall plants like cacti and sugar cane ## Changed * RoR graphs can now have their min and max bounds set to a fixed number @@ -35,6 +38,8 @@ * Removed the template crates entirely for being literally useless * Oil bubbles can no longer go down to Y:0, they now have a minimum center height of Y:15 * The automatic buzzsaw and thresher now have sound loops when active +* The shredder auto shotgun now uses the plasma damage type instead of laser +* Added "nitra to ammunition" recipe in the assembly machine, turning large piles of nitra into random casings/propellants ## Fixed * Fixed RoR graph showing the wrong name in the GUI diff --git a/src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java b/src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java index 0f9c117f4..c6a9fe89d 100644 --- a/src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java +++ b/src/main/java/com/hbm/inventory/recipes/AssemblyMachineRecipes.java @@ -32,6 +32,8 @@ import com.hbm.items.machine.ItemDrillbit.EnumDrillType; import com.hbm.items.machine.ItemPACoil.EnumCoilType; import com.hbm.items.machine.ItemPistons.EnumPistonType; import com.hbm.items.weapon.ItemAmmoHIMARS; +import com.hbm.items.weapon.grenade.ItemGrenadeFuze.EnumGrenadeFuze; +import com.hbm.items.weapon.grenade.ItemGrenadeShell.EnumGrenadeShell; import com.hbm.items.weapon.sedna.factory.GunFactory.EnumAmmo; import com.hbm.items.weapon.sedna.factory.GunFactory.EnumAmmoSecret; @@ -993,6 +995,22 @@ public class AssemblyMachineRecipes extends GenericRecipes { new ComparableStack(ModItems.photo_panel, 12), new ComparableStack(ModItems.battery_pack, 1, EnumBatteryPack.BATTERY_LITHIUM))); + this.register(new GenericRecipe("ass.nitra").setupNamed(200, 500) + .inputItems(new ComparableStack(ModItems.nitra)) + .setIconToFirstIngredient() + .outputItems(new ChanceOutputMulti( + new ChanceOutput(new ItemStack(ModItems.casing, 1, EnumCasingType.SHOTSHELL.ordinal()), 20), + new ChanceOutput(new ItemStack(ModItems.casing, 1, EnumCasingType.BUCKSHOT.ordinal()), 10), + new ChanceOutput(new ItemStack(ModItems.casing, 2, EnumCasingType.SMALL.ordinal()), 20), + new ChanceOutput(new ItemStack(ModItems.casing, 1, EnumCasingType.LARGE.ordinal()), 10), + new ChanceOutput(new ItemStack(Items.gunpowder), 30), + new ChanceOutput(new ItemStack(ModItems.cordite), 20), + new ChanceOutput(new ItemStack(ModItems.ballistite), 20), + new ChanceOutput(new ItemStack(ModItems.grenade_shell, 1, EnumGrenadeShell.FRAG.ordinal()), 5), + new ChanceOutput(new ItemStack(ModItems.grenade_shell, 1, EnumGrenadeShell.STICK.ordinal()), 5), + new ChanceOutput(new ItemStack(ModItems.grenade_fuze, 1, EnumGrenadeFuze.S3.ordinal()), 10) + ))); + this.register(new GenericRecipe("ass.emptypackage").setup(40, 100).outputItems(new ItemStack(ModItems.fluid_pack_empty, 1)) .inputItems(new OreDictStack(TI.plate(), 4), new OreDictStack(ANY_PLASTIC.ingot(), 2))); diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java index c36d5772e..f7524d48a 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactory12ga.java @@ -156,7 +156,7 @@ public class XFactory12ga { public static BulletConfig makeShredderSubmunition(BulletConfig original) { BulletConfig cfg = original.clone(); - cfg.setRicochetAngle(90).setRicochetCount(3).setVel(0.5F).setLife(50).setupDamageClass(DamageClass.LASER).setOnRicochet(LAMBDA_SHREDDER_RICOCHET); + cfg.setRicochetAngle(90).setRicochetCount(3).setVel(0.5F).setLife(50).setupDamageClass(DamageClass.PLASMA).setOnRicochet(LAMBDA_SHREDDER_RICOCHET); return cfg; } @@ -190,7 +190,7 @@ public class XFactory12ga { spawnPulse(bullet.worldObj, mop, bullet.rotationYaw, bullet.rotationPitch); List blast = bullet.worldObj.getEntitiesWithinAABBExcludingEntity(bullet, AxisAlignedBB.getBoundingBox(bullet.posX, bullet.posY, bullet.posZ, bullet.posX, bullet.posY, bullet.posZ).expand(0.5, 0.5, 0.5)); - DamageSource source = BulletConfig.getDamage(bullet, bullet.getThrower(), DamageClass.LASER); + DamageSource source = BulletConfig.getDamage(bullet, bullet.getThrower(), DamageClass.PLASMA); for(Entity e : blast) { if(!e.isEntityAlive()) continue; diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineThresher.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineThresher.java index 02fcaf73b..ffc71f2be 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineThresher.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineThresher.java @@ -3,9 +3,12 @@ package com.hbm.tileentity.machine; import java.util.ArrayList; import java.util.List; +import com.hbm.blocks.generic.BlockTallPlant; +import com.hbm.blocks.generic.BlockTallPlant.EnumTallFlower; import com.hbm.handler.threading.PacketThreading; import com.hbm.inventory.fluid.Fluids; import com.hbm.inventory.fluid.tank.FluidTank; +import com.hbm.items.ModItems; import com.hbm.lib.ModDamageSource; import com.hbm.main.MainRegistry; import com.hbm.main.NTMSounds; @@ -26,7 +29,9 @@ import net.minecraft.block.IGrowable; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityTrackerEntry; import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.monster.IMob; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.play.server.S12PacketEntityVelocity; @@ -107,16 +112,24 @@ public class TileEntityMachineThresher extends TileEntityLoadedBase implements I } if(this.angle != 0) { - Vec3 pivot = Vec3.createVectorHelper(xCoord + 0.5 + dir.offsetX, yCoord + 0.5, zCoord + 0.5); + Vec3 pivot = Vec3.createVectorHelper(xCoord + 0.5 - dir.offsetX, yCoord + 0.5, zCoord + 0.5 - dir.offsetZ); Vec3 upperArm = Vec3.createVectorHelper(-dir.offsetX * 4, 0, -dir.offsetZ * 4); - upperArm.rotateAroundX((float) Math.toRadians(82.5 - angle)); Vec3 lowerArm = Vec3.createVectorHelper(-dir.offsetX * 4, 0, -dir.offsetZ * 4); - lowerArm.rotateAroundX((float) -Math.toRadians(82.5 - angle)); - Vec3 armTip = Vec3.createVectorHelper(-dir.offsetX * 3, 0, -dir.offsetZ * 3); + if(dir.offsetZ != 0) { + upperArm.rotateAroundX((float) Math.toRadians(82.5 - angle)); + lowerArm.rotateAroundX((float) -Math.toRadians(82.5 - angle)); + } + if(dir.offsetX != 0) { + upperArm.rotateAroundZ((float) Math.toRadians(82.5 - angle)); + lowerArm.rotateAroundZ((float) -Math.toRadians(82.5 - angle)); + } + Vec3 armTip = Vec3.createVectorHelper(-dir.offsetX * 2, 0, -dir.offsetZ * 2); double endX = pivot.xCoord + upperArm.xCoord + lowerArm.xCoord + armTip.xCoord; double endZ = pivot.zCoord + upperArm.zCoord + lowerArm.zCoord + armTip.zCoord; + //ParticleUtil.spawnGasFlame(worldObj, endX, yCoord, endZ, 0, 0.2, 0); + for(int i = -3; i <= 3; i++) { int hitX = (int) Math.floor(endX + rot.offsetX * i); int hitZ = (int) Math.floor(endZ + rot.offsetZ * i); @@ -128,16 +141,41 @@ public class TileEntityMachineThresher extends TileEntityLoadedBase implements I this.state = 2; break; } - - if(!this.shouldIgnore(worldObj, hitX, yCoord, hitZ, b, meta)) { - this.cutCrop(hitX, yCoord, hitZ); + + if(b == Blocks.double_plant) { + // sunflower + if((meta & 7) == 0 && worldObj.rand.nextInt(250) == 0) { + worldObj.playAuxSFX(2001, hitX, yCoord, hitZ, Block.getIdFromBlock(b) + (meta << 12)); + this.dropItem(new ItemStack(Blocks.double_plant, 1, 0)); + } + // tall grass + if((meta & 7) == 2 && worldObj.rand.nextInt(100) == 0) { + worldObj.playAuxSFX(2001, hitX, yCoord, hitZ, Block.getIdFromBlock(b) + (meta << 12)); + this.dropItem(new ItemStack(Items.wheat_seeds, 1, 0)); + } + continue; } + + // NTM tall plants like hemp + if(b instanceof BlockTallPlant) { + this.cutTallPlant(b, meta, hitX, yCoord, hitZ); + continue; + } + + if(b == Blocks.reeds || b == Blocks.cactus) { + this.cutCane(b, hitX, yCoord, hitZ); + continue; + } + // IGrowable also covers anything that accepts bone + // meal, so we have to handle actual crops last + if(b instanceof IGrowable && !this.shouldIgnore(worldObj, hitX, yCoord, hitZ, b, meta)) this.cutCrop(b, meta, hitX, yCoord, hitZ); } List affected = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getBoundingBox(endX, yCoord + 0.5, endZ, endX, yCoord + 0.5, endZ).expand(Math.abs(dir.offsetX * 0.5) + Math.abs(rot.offsetX * 4.5), 0.5, Math.abs(dir.offsetZ * 0.5) + Math.abs(rot.offsetZ * 4.5))); for(EntityLivingBase e : affected) { if(e.isEntityAlive() && e.attackEntityFrom(ModDamageSource.turbofan, 100)) { + if(e instanceof IMob && !e.isEntityAlive()) this.dropItem(new ItemStack(ModItems.nitra_small)); worldObj.playSoundEffect(e.posX, e.posY, e.posZ, "mob.zombie.woodbreak", 2.0F, 0.95F + worldObj.rand.nextFloat() * 0.2F); int count = Math.min((int)Math.ceil(e.getMaxHealth() / 4), 250); NBTTagCompound data = new NBTTagCompound(); @@ -225,20 +263,55 @@ public class TileEntityMachineThresher extends TileEntityLoadedBase implements I } public static boolean shouldIgnore(World world, int x, int y, int z, Block b, int meta) { - + if((b instanceof IGrowable)) { return ((IGrowable) b).func_149851_a(world, x, y, z, world.isRemote); } return false; } + + protected void cutTallPlant(Block b, int meta, int x, int y, int z) { + + // if we hit the lower block, shift focus one block up + if(meta <= 7) { + y++; + // if it's a lower block and the block above isn't the same, cancel + if(worldObj.getBlock(x, y, z) != b) return; + meta = worldObj.getBlockMetadata(x, y, z); + } + + // ignore immature willow + if(meta == EnumTallFlower.CD2.ordinal() + 8 || meta == EnumTallFlower.CD3.ordinal() + 8) return; - protected void cutCrop(int x, int y, int z) { + worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(b) + (meta << 12)); + ArrayList drops = b.getDrops(worldObj, x, y, z, meta, 0); + for(ItemStack drop : drops) dropItem(drop); + worldObj.setBlock(x, y, z, Blocks.air); + } + + /** Removes the to two blocks from a three block crop like cacti and sugar cane */ + protected void cutCane(Block target, int x, int y, int z) { + + // people may be inclined to incorrectly place this thing one block above + // the intended operating level, so we compensate for that + int offset = worldObj.getBlock(x, y - 1, z) == target ? -1 : 0; + + // top to bottom + for(int i = 2 + offset; i > 0 + offset; i--) { + Block b = worldObj.getBlock(x, y + i, z); + int meta = worldObj.getBlockMetadata(x, y + i, z); + worldObj.playAuxSFX(2001, x, y + i, z, Block.getIdFromBlock(b) + (meta << 12)); + ArrayList drops = b.getDrops(worldObj, x, y + i, z, meta, 0); + for(ItemStack drop : drops) dropItem(drop); + worldObj.setBlock(x, y + i, z, Blocks.air); + } + } + + /** Harvests and re-plants crops like wheat */ + protected void cutCrop(Block b, int meta, int x, int y, int z) { Block soil = worldObj.getBlock(x, y - 1, z); - Block b = worldObj.getBlock(x, y, z); - int meta = worldObj.getBlockMetadata(x, y, z); - worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(b) + (meta << 12)); Block replacementBlock = Blocks.air; @@ -260,19 +333,7 @@ public class TileEntityMachineThresher extends TileEntityLoadedBase implements I } } - ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()); - double spawnX = xCoord + 0.5 - dir.offsetX * 0.75; - double spawnZ = zCoord + 0.5 - dir.offsetZ * 0.75; - - EntityItem entityItem = new EntityItem(worldObj, spawnX, yCoord, spawnZ, drop); - entityItem.delayBeforeCanPickup = 10; - worldObj.spawnEntityInWorld(entityItem); - - entityItem.motionX = dir.offsetX * -0.2 + 0.2; - entityItem.motionZ = dir.offsetZ * -0.2; - EntityTrackerEntry entry = TrackerUtil.getTrackerEntry((WorldServer) worldObj, entityItem.getEntityId()); - entry.func_151259_a(new S12PacketEntityVelocity(entityItem.getEntityId(), entityItem.motionX, entityItem.motionY, entityItem.motionZ)); - + dropItem(drop); } // Apparently, until 1.14 full-grown wheat could sometimes drop no seeds at all @@ -286,6 +347,22 @@ public class TileEntityMachineThresher extends TileEntityLoadedBase implements I worldObj.setBlock(x, y, z, replacementBlock, replacementMeta, 3); } + + protected void dropItem(ItemStack drop) { + + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()); + double spawnX = xCoord + 0.5 - dir.offsetX * 0.75; + double spawnZ = zCoord + 0.5 - dir.offsetZ * 0.75; + + EntityItem entityItem = new EntityItem(worldObj, spawnX, yCoord, spawnZ, drop); + entityItem.delayBeforeCanPickup = 10; + worldObj.spawnEntityInWorld(entityItem); + + entityItem.motionX = dir.offsetX * -0.2 + 0.2; + entityItem.motionZ = dir.offsetZ * -0.2; + EntityTrackerEntry entry = TrackerUtil.getTrackerEntry((WorldServer) worldObj, entityItem.getEntityId()); + entry.func_151259_a(new S12PacketEntityVelocity(entityItem.getEntityId(), entityItem.motionX, entityItem.motionY, entityItem.motionZ)); + } @Override public void serialize(ByteBuf buf) { diff --git a/src/main/resources/assets/hbm/lang/de_DE.lang b/src/main/resources/assets/hbm/lang/de_DE.lang index 08d51d270..f35e91ff8 100644 --- a/src/main/resources/assets/hbm/lang/de_DE.lang +++ b/src/main/resources/assets/hbm/lang/de_DE.lang @@ -129,6 +129,8 @@ armorMod.type.leggings=Beinschienen armorMod.type.servo=Servos armorMod.type.special=Spezial +ass.nitra=Nitra zu Munition + autoswitch=Teil der Rezeptgruppe "%s"$Rezept ändert sich basierend auf das erste Item autoswitch.pile=Wiederaufbereitung Chicago-Pile-Brennstoff autoswitch.plate=Wiederaufbereitung Plattenbrennstoff diff --git a/src/main/resources/assets/hbm/lang/en_US.lang b/src/main/resources/assets/hbm/lang/en_US.lang index 033f9973c..274436882 100644 --- a/src/main/resources/assets/hbm/lang/en_US.lang +++ b/src/main/resources/assets/hbm/lang/en_US.lang @@ -184,6 +184,8 @@ armorMod.type.leggings=Leggings armorMod.type.servo=Servos armorMod.type.special=Special +ass.nitra=Nitra to Ammunition + autoswitch=Part of auto switch group "%s"$Recipe changes based on first ingredient autoswitch.pile=Reprocessing Chicago Pile Rods autoswitch.plate=Reprocessing Plate Fuel diff --git a/src/main/resources/assets/hbm/manual/machine/autosaw.json b/src/main/resources/assets/hbm/manual/machine/autosaw.json new file mode 100644 index 000000000..6be306008 --- /dev/null +++ b/src/main/resources/assets/hbm/manual/machine/autosaw.json @@ -0,0 +1,11 @@ +{ + "name": "Automatic Buzzsaw", + "icon": ["hbm:tile.machine_autosaw", 1, 0], + "trigger": [["hbm:tile.machine_autosaw"]], + "title": { + "en_US": "Automatic Buzzsaw" + }, + "content": { + "en_US": "Automatic machine that will cut down trees and plants in a 10 block radius. When supplied with fuel (like wood oil), it will constantly revolve at a slow pace, and only extend if plant or wood blocks are detected. Trees can be felled in full and are replanted if leaves were present. The buzzsaw is designed to be placed on the same level as the trees, so the sawblade should strike the second lowest log block of the tree, however hitting the lowest still works. Sugar cane and cacti can be harvested too, assuming the saw is placed at the same height, so that the blade doesn't break the lowest block. Mustard willows are only cut when mature. Harvested plants will be dropped on the spot, unlike the [[automatic thresher|Automatic Thresher]] which dispenses them from the machine, so a collection system has to be set up, for example employing fans.

Do note that touching the spinning sawblade is not healthy." + } +} diff --git a/src/main/resources/assets/hbm/manual/machine/thresher.json b/src/main/resources/assets/hbm/manual/machine/thresher.json new file mode 100644 index 000000000..85ca99b81 --- /dev/null +++ b/src/main/resources/assets/hbm/manual/machine/thresher.json @@ -0,0 +1,11 @@ +{ + "name": "Automatic Thresher", + "icon": ["hbm:tile.machine_thresher", 1, 0], + "trigger": [["hbm:tile.machine_thresher"]], + "title": { + "en_US": "Automatic Thresher" + }, + "content": { + "en_US": "Automatic machine that will harvest crops and plants in a 7x7 area. When supplied with fuel (like wood oil), it will extend in intervals between 10-15 seconds, even if no blocks can be harvested. Crops like wheat and carrots will be replanted automatically when harvested. Sugar cane and cacti can be harvested too, if the lowest block is hit by the thresher then it will be kept, and only the upper blocks are broken. Also works on double plants like hemp and mustard willow, where only the upper block is removed, regardless of where the thresher hits the plant. Mustard willows are only harvested when mature. Sunflowers and tall grass also yield items, but due to them not being growable crops, they aren't broken at all, only yielding sunflowers and wheat seeds respectively at a low rate. Unlike the [[automatic buzzsaw|Automatic Buzzsaw]], the thresher will collect the harvested items and eject them at the back of the machine.

Hostile mobs struck by the thresher's reel will yield small piles of nitra on death. The operating parts are still dangerous to players and passive mobs, though." + } +}