mine the nitra for ammo

This commit is contained in:
Boblet 2026-05-19 16:23:45 +02:00
parent 387909641c
commit e42bb12984
8 changed files with 154 additions and 28 deletions

View File

@ -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

View File

@ -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<GenericRecipe> {
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)));

View File

@ -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<Entity> 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;

View File

@ -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<EntityLivingBase> 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<ItemStack> 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<ItemStack> 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) {

View File

@ -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

View File

@ -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

View File

@ -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.<br><br>Do note that touching the spinning sawblade is not healthy."
}
}

View File

@ -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.<br><br>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."
}
}