diff --git a/changelog b/changelog index 1f85ec8e0..6e6163f03 100644 --- a/changelog +++ b/changelog @@ -11,6 +11,16 @@ * The conveyor ejector now has a "only take maximum possible" toggle * Enabling this means that, if stack ejection upgrades are installed, only stacks that meet the limit can be ejected * Items with a lower maximum stacksize will be ejected regardless +* Survey scanners now pick up bedrock oil +* The conveyor sorter filter slots now have directional labels instead of only color coding + * Apparently color blind people exist? +* Conveyor sorters can now process boxes + * All stacks are sorted individually, and each batch of items that comes out of one side is sent as a box +* Conveyor boxers can now accept boxes, this is useful for batching up partial boxes that come out of sorters +* Conveyor inserters can now accept boxes directly instead of causing them to burst open +* Conveyor inserters now have a special rule when supplying an arc furnace where instead of trying a full stack and then one item, the first always failing and the last being too slow, they will supply the slot target amount instead + * Given the cycle delay and the lid's movement speed, the inserters should now be fast enough to fully supply a speed III arc furnace +* Skeletons can bow be gibbed by explosions, although it will spawn clean bone particles and omit the gore splash effect ## Fixed * Fixed the T-51b set not having radiation resistance diff --git a/src/main/java/com/hbm/blocks/network/CraneBoxer.java b/src/main/java/com/hbm/blocks/network/CraneBoxer.java index 2498e734c..66702e603 100644 --- a/src/main/java/com/hbm/blocks/network/CraneBoxer.java +++ b/src/main/java/com/hbm/blocks/network/CraneBoxer.java @@ -6,6 +6,7 @@ import api.hbm.conveyor.IEnterableBlock; import com.hbm.lib.RefStrings; import com.hbm.tileentity.network.TileEntityCraneBase; import com.hbm.tileentity.network.TileEntityCraneBoxer; + import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; @@ -84,9 +85,21 @@ public class CraneBoxer extends BlockCraneBase implements IEnterableBlock { @Override public boolean canPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { - return false; + return true; } @Override - public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { } + public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { + TileEntityCraneBoxer unboxer = (TileEntityCraneBoxer) world.getTileEntity(x, y, z); + ForgeDirection accessedSide = getOutputSide(world, x, y, z).getOpposite(); + + for(ItemStack stack : entity.getItemStacks()) { + ItemStack remainder = CraneInserter.addToInventory(unboxer, unboxer.getAccessibleSlotsFromSide(accessedSide.ordinal()), stack, accessedSide.ordinal()); + + if(remainder != null && remainder.stackSize > 0) { + EntityItem drop = new EntityItem(world, x + 0.5, y + 0.5, z + 0.5, remainder.copy()); + world.spawnEntityInWorld(drop); + } + } + } } diff --git a/src/main/java/com/hbm/blocks/network/CraneInserter.java b/src/main/java/com/hbm/blocks/network/CraneInserter.java index e4cb74967..f152a4fd3 100644 --- a/src/main/java/com/hbm/blocks/network/CraneInserter.java +++ b/src/main/java/com/hbm/blocks/network/CraneInserter.java @@ -145,19 +145,51 @@ public class CraneInserter extends BlockCraneBase implements IEnterableBlock { return toAdd; } - @Override - public boolean canPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { - return false; - } + @Override public boolean canPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { return true; } @Override - public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { } + public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { + ForgeDirection outputDirection = getOutputSide(world, x, y, z); + TileEntity te = world.getTileEntity(x + outputDirection.offsetX, y + outputDirection.offsetY, z + outputDirection.offsetZ); - @Override - public boolean hasComparatorInputOverride() { - return true; + if(entity == null || entity.getItemStacks() == null || entity.getItemStacks().length == 0) { + return; + } + + ItemStack[] toAdd = entity.getItemStacks(); + + if(!world.isBlockIndirectlyGettingPowered(x, y, z)) { + int[] access = null; + + if(te instanceof ISidedInventory) { + ISidedInventory sided = (ISidedInventory) te; + access = InventoryUtil.masquerade(sided, outputDirection.getOpposite().ordinal()); + } + + if(te instanceof IInventory) { + IInventory inv = (IInventory) te; + + for(ItemStack stack : toAdd) addToInventory(inv, access, stack, outputDirection.getOpposite().ordinal()); + } + } + + TileEntityCraneInserter inserter = null; + + for(ItemStack stack : toAdd) { + + if(stack.stackSize > 0) { + inserter = (TileEntityCraneInserter) world.getTileEntity(x, y, z); + addToInventory(inserter, null, stack, outputDirection.getOpposite().ordinal()); + } + if(stack.stackSize > 0 && inserter != null && !inserter.destroyer) { + EntityItem drop = new EntityItem(world, x + 0.5, y + 0.5, z + 0.5, stack.copy()); + world.spawnEntityInWorld(drop); + } + } } + @Override public boolean hasComparatorInputOverride() { return true; } + @Override public int getComparatorInputOverride(World world, int x, int y, int z, int side) { return Container.calcRedstoneFromInventory((TileEntityCraneInserter)world.getTileEntity(x, y, z)); diff --git a/src/main/java/com/hbm/blocks/network/CraneRouter.java b/src/main/java/com/hbm/blocks/network/CraneRouter.java index af4db88bb..7ed933fee 100644 --- a/src/main/java/com/hbm/blocks/network/CraneRouter.java +++ b/src/main/java/com/hbm/blocks/network/CraneRouter.java @@ -7,6 +7,7 @@ import api.hbm.conveyor.IEnterableBlock; import com.hbm.blocks.IBlockMultiPass; import com.hbm.blocks.ITooltipProvider; import com.hbm.entity.item.EntityMovingItem; +import com.hbm.entity.item.EntityMovingPackage; import com.hbm.items.tool.ItemConveyorWand; import com.hbm.lib.RefStrings; import com.hbm.main.MainRegistry; @@ -115,16 +116,100 @@ public class CraneRouter extends BlockContainer implements IBlockMultiPass, IEnt return 7; } - @Override - public boolean canItemEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorItem entity) { - return true; - } + @Override public boolean canItemEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorItem entity) { return true; } + @Override public boolean canPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { return true; } @Override public void onItemEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorItem entity) { - TileEntityCraneRouter router = (TileEntityCraneRouter) world.getTileEntity(x, y, z); - ItemStack stack = entity.getItemStack(); + List[] sort = this.sort(world, x, y, z, entity.getItemStack()); + for(int i = 0; i < 7; i++) { + ForgeDirection d = ForgeDirection.getOrientation(i); + List list = sort[i]; + + if(d == ForgeDirection.UNKNOWN) { + for(ItemStack stack : list) world.spawnEntityInWorld(new EntityItem(world, x + 0.5, y + 0.5, z + 0.5, stack)); + } else { + for(ItemStack stack : list) sendOnRoute(world, x, y, z, stack, d); + } + } + + } + + protected void sendOnRoute(World world, int x, int y, int z, ItemStack item, ForgeDirection dir) { + IConveyorBelt belt = null; + Block block = world.getBlock(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ); + + if(block instanceof IConveyorBelt) { + belt = (IConveyorBelt) block; + } + + if(belt != null) { + EntityMovingItem moving = new EntityMovingItem(world); + Vec3 pos = Vec3.createVectorHelper(x + 0.5 + dir.offsetX * 0.55, y + 0.5 + dir.offsetY * 0.55, z + 0.5 + dir.offsetZ * 0.55); + Vec3 snap = belt.getClosestSnappingPosition(world, x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ, pos); + moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); + moving.setItemStack(item); + world.spawnEntityInWorld(moving); + } else { + world.spawnEntityInWorld(new EntityItem(world, x + 0.5 + dir.offsetX * 0.55, y + 0.5 + dir.offsetY * 0.55, z + 0.5 + dir.offsetZ * 0.55, item)); + } + } + + @Override + public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { + List[] sort = this.sort(world, x, y, z, entity.getItemStacks()); + + for(int i = 0; i < 7; i++) { + ForgeDirection d = ForgeDirection.getOrientation(i); + List list = sort[i]; + if(list.isEmpty()) continue; + + if(d == ForgeDirection.UNKNOWN) { + for(ItemStack stack : list) world.spawnEntityInWorld(new EntityItem(world, x + 0.5, y + 0.5, z + 0.5, stack)); + } else { + + IConveyorBelt belt = null; + Block block = world.getBlock(x + d.offsetX, y + d.offsetY, z + d.offsetZ); + if(block instanceof IConveyorBelt) belt = (IConveyorBelt) block; + + if(belt != null) { + EntityMovingPackage moving = new EntityMovingPackage(world); + Vec3 pos = Vec3.createVectorHelper(x + 0.5 + d.offsetX * 0.55, y + 0.5 + d.offsetY * 0.55, z + 0.5 + d.offsetZ * 0.55); + Vec3 snap = belt.getClosestSnappingPosition(world, x + d.offsetX, y + d.offsetY, z + d.offsetZ, pos); + moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); + moving.setItemStacks(list.toArray(new ItemStack[0])); + world.spawnEntityInWorld(moving); + } else { + for(ItemStack stack : list) world.spawnEntityInWorld(new EntityItem(world, x + 0.5 + d.offsetX * 0.55, y + 0.5 + d.offsetY * 0.55, z + 0.5 + d.offsetZ * 0.55, stack)); + } + } + } + } + + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + this.addStandardInfo(stack, player, list, ext); + } + + /** Accepts an arbitrary amount of ItemStacks (either solo or from boxes) and returns an array corresponding with ForgeDirections, + * with each direction having a list of items being output in that direction. Index 6 is used for UNKNOWN, i.e. unsortable items. + * Returned lists are populated with COPIES of the original stacks. */ + public static List[] sort(World world, int x, int y, int z, ItemStack... stacks) { + TileEntityCraneRouter router = (TileEntityCraneRouter) world.getTileEntity(x, y, z); + List[] output = new List[7]; + for(int i = 0; i < 7; i++) output[i] = new ArrayList(); + + for(ItemStack stack : stacks) { + if(stack == null) continue; + ForgeDirection dir = getOutputDir(router, stack.copy()); + output[dir.ordinal()].add(stack); + } + + return output; + } + + public static ForgeDirection getOutputDir(TileEntityCraneRouter router, ItemStack stack) { List validDirs = new ArrayList(); //check filters for all sides @@ -168,40 +253,10 @@ public class CraneRouter extends BlockContainer implements IBlockMultiPass, IEnt } if(validDirs.isEmpty()) { - world.spawnEntityInWorld(new EntityItem(world, x + 0.5, y + 0.5, z + 0.5, stack.copy())); - return; + return ForgeDirection.UNKNOWN; } - int i = world.rand.nextInt(validDirs.size()); - sendOnRoute(world, x, y, z, entity, validDirs.get(i)); - } - - protected void sendOnRoute(World world, int x, int y, int z, IConveyorItem item, ForgeDirection dir) { - - IConveyorBelt belt = null; - Block block = world.getBlock(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ); - - if(block instanceof IConveyorBelt) { - belt = (IConveyorBelt) block; - } - - if(belt != null) { - EntityMovingItem moving = new EntityMovingItem(world); - Vec3 pos = Vec3.createVectorHelper(x + 0.5 + dir.offsetX * 0.55, y + 0.5 + dir.offsetY * 0.55, z + 0.5 + dir.offsetZ * 0.55); - Vec3 snap = belt.getClosestSnappingPosition(world, x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ, pos); - moving.setPosition(snap.xCoord, snap.yCoord, snap.zCoord); - moving.setItemStack(item.getItemStack()); - world.spawnEntityInWorld(moving); - } else { - world.spawnEntityInWorld(new EntityItem(world, x + 0.5 + dir.offsetX * 0.55, y + 0.5 + dir.offsetY * 0.55, z + 0.5 + dir.offsetZ * 0.55, item.getItemStack())); - } - } - - @Override public boolean canPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { return false; } - @Override public void onPackageEnter(World world, int x, int y, int z, ForgeDirection dir, IConveyorPackage entity) { } - - @Override - public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { - this.addStandardInfo(stack, player, list, ext); + int i = router.getWorldObj().rand.nextInt(validDirs.size()); + return validDirs.get(i); } } diff --git a/src/main/java/com/hbm/entity/item/EntityMovingPackage.java b/src/main/java/com/hbm/entity/item/EntityMovingPackage.java index ddf2fb77d..65bb7cfd9 100644 --- a/src/main/java/com/hbm/entity/item/EntityMovingPackage.java +++ b/src/main/java/com/hbm/entity/item/EntityMovingPackage.java @@ -74,6 +74,7 @@ public class EntityMovingPackage extends EntityMovingConveyorObject implements I @Override public void enterBlock(IEnterableBlock enterable, BlockPos pos, ForgeDirection dir) { + if(this.isDead) return; if(enterable.canPackageEnter(worldObj, pos.getX(), pos.getY(), pos.getZ(), dir, this)) { enterable.onPackageEnter(worldObj, pos.getX(), pos.getY(), pos.getZ(), dir, this); diff --git a/src/main/java/com/hbm/items/tool/ItemSurveyScanner.java b/src/main/java/com/hbm/items/tool/ItemSurveyScanner.java index e4906b2ea..cb73d7e5a 100644 --- a/src/main/java/com/hbm/items/tool/ItemSurveyScanner.java +++ b/src/main/java/com/hbm/items/tool/ItemSurveyScanner.java @@ -26,6 +26,7 @@ public class ItemSurveyScanner extends Item { boolean hasOil = false; boolean hasColtan = false; + boolean hasBedrockOil = false; boolean hasDepth = false; boolean hasSchist = false; boolean hasAussie = false; @@ -40,6 +41,7 @@ public class ItemSurveyScanner extends Item { //wow, this sucks! if(block == ModBlocks.ore_oil) hasOil = true; else if(block == ModBlocks.ore_coltan) hasColtan = true; + else if(block == ModBlocks.ore_bedrock_oil) hasBedrockOil = true; else if(block == ModBlocks.stone_depth) hasDepth = true; else if(block == ModBlocks.stone_depth_nether) hasDepth = true; else if(block == ModBlocks.stone_gneiss) hasSchist = true; @@ -55,6 +57,7 @@ public class ItemSurveyScanner extends Item { } if(hasOil) player.addChatComponentMessage(new ChatComponentText("Found OIL!").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.BLACK))); + if(hasBedrockOil) player.addChatComponentMessage(new ChatComponentText("Found BEDROCK OIL!").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.BLACK))); if(hasColtan) player.addChatComponentMessage(new ChatComponentText("Found COLTAN!").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD))); if(hasDepth) player.addChatComponentMessage(new ChatComponentText("Found DEPTH ROCK!").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GRAY))); if(hasSchist) player.addChatComponentMessage(new ChatComponentText("Found SCHIST!").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.DARK_AQUA))); diff --git a/src/main/java/com/hbm/items/tool/ItemToolAbility.java b/src/main/java/com/hbm/items/tool/ItemToolAbility.java index cca7f351b..dfcac8ae8 100644 --- a/src/main/java/com/hbm/items/tool/ItemToolAbility.java +++ b/src/main/java/com/hbm/items/tool/ItemToolAbility.java @@ -385,6 +385,7 @@ public class ItemToolAbility extends ItemTool implements IDepthRockTool, IGUIPro if(removedByPlayer && canHarvest) { try { + blockCaptureDrops.invoke(block, true); block.harvestBlock(world, player, x, y, z, l); List drops = (List)blockCaptureDrops.invoke(block, false); diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java b/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java index 661b4185a..c7fb51289 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/ConfettiUtil.java @@ -45,10 +45,11 @@ public class ConfettiUtil { if(entity instanceof EntityCyberCrab) return; if(entity instanceof EntityTeslaCrab) return; if(entity instanceof EntityTaintCrab) return; - if(entity instanceof EntitySkeleton) return; if(entity instanceof EntitySlime) return; SkeletonCreator.composeEffectGib(entity.worldObj, entity, 0.25F); + + if(entity instanceof EntitySkeleton) return; NBTTagCompound vdat = new NBTTagCompound(); vdat.setString("type", "giblets"); diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java b/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java index d2daf744c..e7787c983 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/GunFactory.java @@ -68,6 +68,7 @@ public class GunFactory { XFactory35800.init(); XFactory45.init(); XFactoryTool.init(); + XFactoryDrill.init(); ModItems.weapon_mod_test = new ItemEnumMulti(EnumModTest.class, true, true).setUnlocalizedName("weapon_mod_test").setMaxStackSize(1); ModItems.weapon_mod_generic = new ItemEnumMulti(EnumModGeneric.class, true, true).setUnlocalizedName("weapon_mod_generic").setMaxStackSize(1).setCreativeTab(MainRegistry.weaponTab); diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryDrill.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryDrill.java new file mode 100644 index 000000000..65ef98f00 --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryDrill.java @@ -0,0 +1,116 @@ +package com.hbm.items.weapon.sedna.factory; + +import java.util.function.BiConsumer; + +import com.hbm.blocks.ModBlocks; +import com.hbm.inventory.fluid.Fluids; +import com.hbm.items.ModItems; +import com.hbm.items.weapon.sedna.Crosshair; +import com.hbm.items.weapon.sedna.GunConfig; +import com.hbm.items.weapon.sedna.ItemGunBaseNT; +import com.hbm.items.weapon.sedna.Receiver; +import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext; +import com.hbm.items.weapon.sedna.ItemGunBaseNT.WeaponQuality; +import com.hbm.items.weapon.sedna.impl.ItemGunDrill; +import com.hbm.items.weapon.sedna.mags.IMagazine; +import com.hbm.items.weapon.sedna.mags.MagazineLiquidEngine; +import com.hbm.items.weapon.sedna.mods.WeaponModManager; +import com.hbm.render.anim.AnimationEnums.GunAnimation; +import com.hbm.util.EntityDamageUtil; + +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.network.play.server.S28PacketEffect; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; + +public class XFactoryDrill { + + public static final String D_REACH = "D_REACH"; + public static final String F_DTNEG = "F_DTNEG"; + public static final String F_PIERCE = "F_PIERCE"; + public static final String I_AOE = "I_AOE"; + public static final String I_HARVEST = "I_HARVEST"; + + public static void init() { + + ModItems.gun_drill = new ItemGunDrill(WeaponQuality.UTILITY, new GunConfig() + .dura(3_000).draw(10).inspect(55).hideCrosshair(false).crosshair(Crosshair.L_CIRCUMFLEX) + .rec(new Receiver(0) + .dmg(10F).delay(20).auto(true).jam(0) + .mag(new MagazineLiquidEngine(0, 4_000, Fluids.GASOLINE, Fluids.GASOLINE_LEADED, Fluids.COALGAS, Fluids.COALGAS_LEADED)) + .offset(1, -0.0625 * 2.5, -0.25D) + .canFire(Lego.LAMBDA_STANDARD_CAN_FIRE).fire(LAMBDA_DRILL_FIRE)) + .pp(Lego.LAMBDA_STANDARD_CLICK_PRIMARY).pr(Lego.LAMBDA_STANDARD_RELOAD).decider(GunStateDecider.LAMBDA_STANDARD_DECIDER) + //.anim(LAMBDA_CT_ANIMS).orchestra(Orchestras.ORCHESTRA_CHARGE_THROWER) + ).setUnlocalizedName("gun_drill"); + } + + public static BiConsumer LAMBDA_DRILL_FIRE = (stack, ctx) -> { + doStandardFire(stack, ctx, GunAnimation.CYCLE, true); + }; + + public static void doStandardFire(ItemStack stack, LambdaContext ctx, GunAnimation anim, boolean calcWear) { + EntityPlayer player = ctx.getPlayer(); + int index = ctx.configIndex; + if(anim != null) ItemGunBaseNT.playAnimation(player, stack, anim, ctx.configIndex); + + Receiver primary = ctx.config.getReceivers(stack)[0]; + IMagazine mag = primary.getMagazine(stack); + + MovingObjectPosition mop = EntityDamageUtil.getMouseOver(ctx.getPlayer(), getModdableReach(stack, 5.0D)); + if(mop != null) { + if(mop.typeOfHit == mop.typeOfHit.ENTITY) { + float damage = 5.0F; + if(mop.entityHit instanceof EntityLivingBase) { + EntityDamageUtil.attackEntityFromNT((EntityLivingBase) mop.entityHit, DamageSource.causePlayerDamage(ctx.getPlayer()), damage, true, true, 0.1F, getModdableDTNegation(stack, 2F), getModdablePiercing(stack, 0.15F)); + } else { + mop.entityHit.attackEntityFrom(DamageSource.causePlayerDamage(ctx.getPlayer()), damage); + } + } + if(player != null && mop.typeOfHit == mop.typeOfHit.BLOCK) { + + int aoe = getModdableAoE(stack, 1); + for(int i = -aoe; i <= aoe; i++) for(int j = -aoe; j <= aoe; j++) for(int k = -aoe; k <= aoe; k++) { + breakExtraBlock(player.worldObj, mop.blockX + i, mop.blockY + j, mop.blockZ + k, player, mop.blockX, mop.blockY, mop.blockZ); + } + } + } + + mag.useUpAmmo(stack, ctx.inventory, 10); + if(calcWear) ItemGunBaseNT.setWear(stack, index, Math.min(ItemGunBaseNT.getWear(stack, index), ctx.config.getDurability(stack))); + } + + public static void breakExtraBlock(World world, int x, int y, int z, EntityPlayer playerEntity, int refX, int refY, int refZ) { + if(world.isAirBlock(x, y, z)) return; + if(!(playerEntity instanceof EntityPlayerMP)) return; + + EntityPlayerMP player = (EntityPlayerMP) playerEntity; + Block block = world.getBlock(x, y, z); + int meta = world.getBlockMetadata(x, y, z); + + if(!block.canHarvestBlock(player, meta) || (block.getBlockHardness(world, x, y, z) == -1.0F && block.getPlayerRelativeBlockHardness(player, world, x, y, z) == 0.0F) || block == ModBlocks.stone_keyhole) { + world.playSoundAtEntity(player, "random.break", 0.5F, 0.8F + world.rand.nextFloat() * 0.6F); + return; + } + + // we are serverside and tryHarvestBlock already invokes the 2001 packet for every player except the user, so we manually send it for the user as well + player.theItemInWorldManager.tryHarvestBlock(x, y, z); + + if(world.getBlock(x, y, z) == Blocks.air) { // only do this when the block was destroyed. if the block doesn't create air when broken, this breaks, but it's no big deal + player.playerNetServerHandler.sendPacket(new S28PacketEffect(2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12), false)); + } + } + + // this system technically doesn't need to be part of the GunCfg or Receiver or anything, we can just do this and it works the exact same + public static double getModdableReach(ItemStack stack, double base) { return WeaponModManager.eval(base, stack, D_REACH, ModItems.gun_drill, 0); } + public static float getModdableDTNegation(ItemStack stack, float base) { return WeaponModManager.eval(base, stack, F_DTNEG, ModItems.gun_drill, 0); } + public static float getModdablePiercing(ItemStack stack, float base) { return WeaponModManager.eval(base, stack, F_PIERCE, ModItems.gun_drill, 0); } + public static int getModdableAoE(ItemStack stack, int base) { return WeaponModManager.eval(base, stack, I_AOE, ModItems.gun_drill, 0); } + public static int getModdableHarvestLevel(ItemStack stack, int base) { return WeaponModManager.eval(base, stack, I_HARVEST, ModItems.gun_drill, 0); } +} diff --git a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryTool.java b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryTool.java index 5fbd2d7e5..3237bd1d0 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryTool.java +++ b/src/main/java/com/hbm/items/weapon/sedna/factory/XFactoryTool.java @@ -24,7 +24,6 @@ import com.hbm.items.weapon.sedna.ItemGunBaseNT.LambdaContext; import com.hbm.items.weapon.sedna.ItemGunBaseNT.WeaponQuality; import com.hbm.items.weapon.sedna.factory.GunFactory.EnumAmmo; import com.hbm.items.weapon.sedna.impl.ItemGunChargeThrower; -import com.hbm.items.weapon.sedna.impl.ItemGunDrill; import com.hbm.items.weapon.sedna.mags.MagazineFullReload; import com.hbm.lib.RefStrings; import com.hbm.main.MainRegistry; @@ -276,17 +275,6 @@ public class XFactoryTool { .setupStandardConfiguration() .anim(LAMBDA_CT_ANIMS).orchestra(Orchestras.ORCHESTRA_CHARGE_THROWER) ).setUnlocalizedName("gun_charge_thrower"); - - ModItems.gun_drill = new ItemGunDrill(WeaponQuality.UTILITY, new GunConfig() - .dura(3_000).draw(10).inspect(55).reloadChangeType(true).hideCrosshair(false).crosshair(Crosshair.L_CIRCUMFLEX) - .rec(new Receiver(0) - .dmg(10F).delay(4).dry(10).auto(true).spread(0F).spreadHipfire(0F).reload(60).jam(0).sound("hbm:weapon.fire.grenade", 1.0F, 1.0F) - .mag(new MagazineFullReload(0, 1).addConfigs(ct_hook, ct_mortar, ct_mortar_charge)) - .offset(1, -0.0625 * 2.5, -0.25D) - .setupStandardFire()) - .setupStandardConfiguration() - //.anim(LAMBDA_CT_ANIMS).orchestra(Orchestras.ORCHESTRA_CHARGE_THROWER) - ).setUnlocalizedName("gun_drill"); } public static BiConsumer LAMBDA_RECOIL_CT = (stack, ctx) -> { diff --git a/src/main/java/com/hbm/items/weapon/sedna/impl/ItemGunDrill.java b/src/main/java/com/hbm/items/weapon/sedna/impl/ItemGunDrill.java index 3a888903d..55ef58dd5 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/impl/ItemGunDrill.java +++ b/src/main/java/com/hbm/items/weapon/sedna/impl/ItemGunDrill.java @@ -1,11 +1,16 @@ package com.hbm.items.weapon.sedna.impl; import com.hbm.inventory.fluid.FluidType; +import com.hbm.inventory.fluid.Fluids; import com.hbm.items.weapon.sedna.GunConfig; import com.hbm.items.weapon.sedna.ItemGunBaseNT; +import com.hbm.items.weapon.sedna.factory.XFactoryDrill; +import com.hbm.items.weapon.sedna.mags.IMagazine; +import com.hbm.items.weapon.sedna.mags.MagazineLiquidEngine; import api.hbm.energymk2.IBatteryItem; import api.hbm.fluidmk2.IFillableItem; +import net.minecraft.block.Block; import net.minecraft.item.ItemStack; public class ItemGunDrill extends ItemGunBaseNT implements IFillableItem, IBatteryItem { @@ -13,66 +18,66 @@ public class ItemGunDrill extends ItemGunBaseNT implements IFillableItem, IBatte public ItemGunDrill(WeaponQuality quality, GunConfig... cfg) { super(quality, cfg); } + + @Override + public int getHarvestLevel(ItemStack stack, String toolClass) { + return XFactoryDrill.getModdableHarvestLevel(stack, ToolMaterial.IRON.getHarvestLevel()); + } + + @Override + public boolean canHarvestBlock(Block par1Block, ItemStack itemStack) { + return true; // this lets us break things that have no set harvest level (i.e. most NTM shit) + } @Override public boolean acceptsFluid(FluidType type, ItemStack stack) { - return false; + IMagazine mag = ((ItemGunBaseNT) stack.getItem()).getConfig(stack, 0).getReceivers(stack)[0].getMagazine(stack); + return mag instanceof MagazineLiquidEngine; } @Override public int tryFill(FluidType type, int amount, ItemStack stack) { + IMagazine mag = ((ItemGunBaseNT) stack.getItem()).getConfig(stack, 0).getReceivers(stack)[0].getMagazine(stack); + + if(mag instanceof MagazineLiquidEngine) { + MagazineLiquidEngine engine = (MagazineLiquidEngine) mag; + int toFill = Math.min(amount, 50); + toFill = Math.min(toFill, engine.getCapacity(stack) - this.getFill(stack)); + engine.setAmount(stack, this.getFill(stack) + toFill); + return amount - toFill; + } + return 0; } @Override public boolean providesFluid(FluidType type, ItemStack stack) { return false; } - - @Override - public int tryEmpty(FluidType type, int amount, ItemStack stack) { - return 0; - } + @Override public int tryEmpty(FluidType type, int amount, ItemStack stack) { return amount; } @Override public FluidType getFirstFluidType(ItemStack stack) { - return null; + IMagazine mag = ((ItemGunBaseNT) stack.getItem()).getConfig(stack, 0).getReceivers(stack)[0].getMagazine(stack); + if(mag instanceof MagazineLiquidEngine) return ((MagazineLiquidEngine) mag).getType(stack, null); + return Fluids.NONE; } - + @Override public int getFill(ItemStack stack) { - return 0; - } - - @Override - public void chargeBattery(ItemStack stack, long i) { + IMagazine mag = ((ItemGunBaseNT) stack.getItem()).getConfig(stack, 0).getReceivers(stack)[0].getMagazine(stack); - } - - @Override - public void setCharge(ItemStack stack, long i) { + if(mag instanceof MagazineLiquidEngine) { + MagazineLiquidEngine engine = (MagazineLiquidEngine) mag; + return engine.getAmount(stack, null); + } - } - - @Override - public void dischargeBattery(ItemStack stack, long i) { - - } - - @Override - public long getCharge(ItemStack stack) { return 0; } - @Override - public long getMaxCharge(ItemStack stack) { - return 0; - } - - @Override - public long getChargeRate() { - return 0; - } - - @Override - public long getDischargeRate() { - return 0; - } + // TBI + @Override public void chargeBattery(ItemStack stack, long i) { } + @Override public void setCharge(ItemStack stack, long i) { } + @Override public void dischargeBattery(ItemStack stack, long i) { } + @Override public long getCharge(ItemStack stack) { return 0; } + @Override public long getMaxCharge(ItemStack stack) { return 0; } + @Override public long getChargeRate() { return 0; } + @Override public long getDischargeRate() { return 0; } } diff --git a/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineFluid.java b/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineFluid.java index 1f0056825..f22c950ff 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineFluid.java +++ b/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineFluid.java @@ -57,7 +57,7 @@ public class MagazineFluid implements IMagazine { @Override public SpentCasing getCasing(ItemStack stack, IInventory inventory) { return null; } @Override public ItemStack getIconForHUD(ItemStack stack, EntityPlayer player) { return new ItemStack(ModItems.fluid_icon, 1, this.getMagType(stack, index)); } - @Override public String reportAmmoStateForHUD(ItemStack stack, EntityPlayer player) { return getIconForHUD(stack, player).getDisplayName(); } + @Override public String reportAmmoStateForHUD(ItemStack stack, EntityPlayer player) { return getAmount(stack, player.inventory) + "mB"; } @Override public void setAmountBeforeReload(ItemStack stack, int amount) { ItemGunBaseNT.setValueInt(stack, KEY_MAG_PREV + index, amount); } @Override public int getAmountBeforeReload(ItemStack stack) { return ItemGunBaseNT.getValueInt(stack, KEY_MAG_PREV + index); } diff --git a/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineLiquidEngine.java b/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineLiquidEngine.java new file mode 100644 index 000000000..4dd8e984b --- /dev/null +++ b/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineLiquidEngine.java @@ -0,0 +1,59 @@ +package com.hbm.items.weapon.sedna.mags; + +import com.hbm.inventory.fluid.FluidType; +import com.hbm.items.ModItems; +import com.hbm.items.weapon.sedna.ItemGunBaseNT; +import com.hbm.particle.SpentCasing; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +/** Type of fixed ammo engine */ +public class MagazineLiquidEngine implements IMagazine { + + public static final String KEY_MAG_COUNT = "magcount"; + public static final String KEY_MAG_PREV = "magprev"; + public static final String KEY_MAG_AFTER = "magafter"; + + /** A number so the gun tell multiple mags apart */ + public int index; + /** How much ammo this mag can hold */ + public int capacity; + /** Whichever fluids we can pour in this bastard */ + public FluidType[] acceptedTypes; + + public MagazineLiquidEngine(int index, int capacity, FluidType... acceptedTypes) { + this.index = index; + this.capacity = capacity; + this.acceptedTypes = acceptedTypes; + } + + @Override public FluidType getType(ItemStack stack, IInventory inventory) { return acceptedTypes[0]; } + @Override public void setType(ItemStack stack, FluidType type) { } + @Override public int getCapacity(ItemStack stack) { return capacity; } + + @Override + public void useUpAmmo(ItemStack stack, IInventory inventory, int amount) { + this.setAmount(stack, this.getAmount(stack, inventory) - amount); + } + + @Override public int getAmount(ItemStack stack, IInventory inventory) { return getMagCount(stack, index); } + @Override public void setAmount(ItemStack stack, int amount) { setMagCount(stack, index, amount); } + + @Override public boolean canReload(ItemStack stack, IInventory inventory) { return false; } + @Override public void initNewType(ItemStack stack, IInventory inventory) { } + @Override public void reloadAction(ItemStack stack, IInventory inventory) { } + @Override public SpentCasing getCasing(ItemStack stack, IInventory inventory) { return null; } + + @Override public ItemStack getIconForHUD(ItemStack stack, EntityPlayer player) { return new ItemStack(ModItems.fluid_icon, 1, this.getType(stack, player.inventory).getID()); } + @Override public String reportAmmoStateForHUD(ItemStack stack, EntityPlayer player) { return getAmount(stack, player.inventory) + "mB"; } + + @Override public void setAmountBeforeReload(ItemStack stack, int amount) { ItemGunBaseNT.setValueInt(stack, KEY_MAG_PREV + index, amount); } + @Override public int getAmountBeforeReload(ItemStack stack) { return ItemGunBaseNT.getValueInt(stack, KEY_MAG_PREV + index); } + @Override public void setAmountAfterReload(ItemStack stack, int amount) { ItemGunBaseNT.setValueInt(stack, KEY_MAG_AFTER + index, amount); } + @Override public int getAmountAfterReload(ItemStack stack) { return ItemGunBaseNT.getValueInt(stack, KEY_MAG_AFTER + index); } + + public static int getMagCount(ItemStack stack, int index) { return ItemGunBaseNT.getValueInt(stack, KEY_MAG_COUNT + index); } + public static void setMagCount(ItemStack stack, int index, int value) { ItemGunBaseNT.setValueInt(stack, KEY_MAG_COUNT + index, value); } +} diff --git a/src/main/java/com/hbm/particle/helper/SkeletonCreator.java b/src/main/java/com/hbm/particle/helper/SkeletonCreator.java index 059ae65a8..ed789c60d 100644 --- a/src/main/java/com/hbm/particle/helper/SkeletonCreator.java +++ b/src/main/java/com/hbm/particle/helper/SkeletonCreator.java @@ -60,6 +60,7 @@ public class SkeletonCreator implements IParticleCreator { float force = data.getFloat("force"); int entityID = data.getInteger("entityID"); Entity entity = world.getEntityByID(entityID); + boolean skel = entity instanceof EntitySkeleton; if(!(entity instanceof EntityLivingBase)) return; EntityLivingBase living = (EntityLivingBase) entity; @@ -72,12 +73,16 @@ public class SkeletonCreator implements IParticleCreator { if(bonealizer != null) { BoneDefinition[] bones = bonealizer.apply(living); for(BoneDefinition bone : bones) { - if(gib && rand.nextBoolean()) continue; + if(gib && rand.nextBoolean() && !skel) continue; ParticleSkeleton skeleton = new ParticleSkeleton(Minecraft.getMinecraft().getTextureManager(), world, bone.x, bone.y, bone.z, brightness, brightness, brightness, bone.type); skeleton.prevRotationYaw = skeleton.rotationYaw = bone.yaw; skeleton.prevRotationPitch = skeleton.rotationPitch = bone.pitch; if(gib) { skeleton.makeGib(); + if(skel) { + skeleton.useTexture = skeleton.texture; + skeleton.useTextureExt = skeleton.texture_ext; + } skeleton.motionX = rand.nextGaussian() * force; skeleton.motionY = (rand.nextGaussian() + 1) * force; skeleton.motionZ = rand.nextGaussian() * force; diff --git a/src/main/java/com/hbm/render/item/weapon/sedna/ItemRenderDrill.java b/src/main/java/com/hbm/render/item/weapon/sedna/ItemRenderDrill.java index dc77ef450..e16341924 100644 --- a/src/main/java/com/hbm/render/item/weapon/sedna/ItemRenderDrill.java +++ b/src/main/java/com/hbm/render/item/weapon/sedna/ItemRenderDrill.java @@ -3,6 +3,7 @@ package com.hbm.render.item.weapon.sedna; import org.lwjgl.opengl.GL11; import com.hbm.items.weapon.sedna.ItemGunBaseNT; +import com.hbm.items.weapon.sedna.mags.IMagazine; import com.hbm.main.ResourceManager; import net.minecraft.client.Minecraft; @@ -20,43 +21,61 @@ public class ItemRenderDrill extends ItemRenderWeaponBase { float offset = 0.8F; standardAimingTransform(stack, -1.25F * offset, -1.75F * offset, 1.75F * offset, - 0, -4.6825 / 8D, 0.75); - - GL11.glRotated(15, 0, 1, 0); - GL11.glRotated(-10, 1, 0, 0); + -1F * offset, -1.75F * offset, 1.25F * offset); } @Override public void renderFirstPerson(ItemStack stack) { - + ItemGunBaseNT gun = (ItemGunBaseNT) stack.getItem(); Minecraft.getMinecraft().renderEngine.bindTexture(ResourceManager.drill_tex); double scale = 0.375D; GL11.glScaled(scale, scale, scale); + IMagazine mag = gun.getConfig(stack, 0).getReceivers(stack)[0].getMagazine(stack); + double gauge = (double) mag.getAmount(stack, null) / (double) mag.getCapacity(stack); + + float aimingProgress = ItemGunBaseNT.prevAimingProgress + (ItemGunBaseNT.aimingProgress - ItemGunBaseNT.prevAimingProgress) * interp; + GL11.glRotated(15 * (1 - aimingProgress), 0, 1, 0); + GL11.glRotated(-10 * (1 - aimingProgress), 1, 0, 0); + GL11.glShadeModel(GL11.GL_SMOOTH); ResourceManager.drill.renderPart("Base"); GL11.glPushMatrix(); GL11.glTranslated(1, 2.0625, -1.75); GL11.glRotated(45, 1, 0, 0); - GL11.glRotated(-135, 0, 0, 1); + GL11.glRotated(-135 + gauge * 270, 0, 0, 1); GL11.glRotated(-45, 1, 0, 0); GL11.glTranslated(-1, -2.0625, 1.75); ResourceManager.drill.renderPart("Gauge"); GL11.glPopMatrix(); - + + double rot = System.currentTimeMillis() / 3 % 360D; + double rot2 = rot * 5; + + GL11.glPushMatrix(); + GL11.glTranslated(0, Math.sin(rot2 * Math.PI / 180) * 0.125 - 0.125, 0); ResourceManager.drill.renderPart("Piston1"); - ResourceManager.drill.renderPart("Piston2"); - ResourceManager.drill.renderPart("Piston3"); + GL11.glPopMatrix(); GL11.glPushMatrix(); - GL11.glRotated(System.currentTimeMillis() / 3 % 360D, 0, 0, -1); + GL11.glTranslated(0, Math.sin(rot2 * Math.PI / 180 + Math.PI * 2D / 3D) * 0.125 - 0.125, 0); + ResourceManager.drill.renderPart("Piston2"); + GL11.glPopMatrix(); + + GL11.glPushMatrix(); + GL11.glTranslated(0, Math.sin(rot2 * Math.PI / 180 + Math.PI * 4D / 3D) * 0.125 - 0.125, 0); + ResourceManager.drill.renderPart("Piston3"); + GL11.glPopMatrix(); + + GL11.glPushMatrix(); + GL11.glRotated(rot, 0, 0, -1); ResourceManager.drill.renderPart("DrillBack"); GL11.glPopMatrix(); GL11.glPushMatrix(); - GL11.glRotated(System.currentTimeMillis() / 3 % 360D, 0, 0, 1); + GL11.glRotated(rot, 0, 0, 1); ResourceManager.drill.renderPart("DrillFront"); GL11.glPopMatrix(); @@ -66,7 +85,7 @@ public class ItemRenderDrill extends ItemRenderWeaponBase { @Override public void setupThirdPerson(ItemStack stack) { super.setupThirdPerson(stack); - double scale = 1.75D; + double scale = 2.25D; GL11.glScaled(scale, scale, scale); GL11.glTranslated(1, -2, 6); } @@ -83,10 +102,10 @@ public class ItemRenderDrill extends ItemRenderWeaponBase { @Override public void setupModTable(ItemStack stack) { - double scale = -7.5D; + double scale = -8.75D; GL11.glScaled(scale, scale, scale); GL11.glRotated(90, 0, 1, 0); - GL11.glTranslated(0, 2, 0); + GL11.glTranslated(0, 0, 0); } @Override diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java b/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java index 3d55bf30f..266bd2332 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityCraneInserter.java @@ -5,6 +5,8 @@ import com.hbm.interfaces.IControlReceiver; import com.hbm.inventory.container.ContainerCraneInserter; import com.hbm.inventory.gui.GUICraneInserter; import com.hbm.tileentity.IGUIProvider; +import com.hbm.tileentity.TileEntityProxyBase; +import com.hbm.tileentity.machine.TileEntityMachineArcFurnaceLarge; import com.hbm.util.InventoryUtil; import cpw.mods.fml.relauncher.Side; @@ -40,7 +42,7 @@ public class TileEntityCraneInserter extends TileEntityCraneBase implements IGUI super.updateEntity(); if(!worldObj.isRemote) { - if (!this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) {ForgeDirection outputSide = getOutputSide(); + if(!this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord)) {ForgeDirection outputSide = getOutputSide(); TileEntity te = worldObj.getTileEntity(xCoord + outputSide.offsetX, yCoord + outputSide.offsetY, zCoord + outputSide.offsetZ); int[] access = null; @@ -51,6 +53,8 @@ public class TileEntityCraneInserter extends TileEntityCraneBase implements IGUI access = InventoryUtil.masquerade(sided, outputSide.getOpposite().ordinal()); } + boolean didSomething = false; + if(te instanceof IInventory) { for(int i = 0; i < slots.length; i++) { @@ -62,26 +66,44 @@ public class TileEntityCraneInserter extends TileEntityCraneBase implements IGUI if(ret == null || ret.stackSize != stack.stackSize) { slots[i] = ret; this.markDirty(); - return; + didSomething = true; + break; } } } //if the previous operation fails, repeat but use single items instead of the whole stack instead //this should fix cases where the inserter can't insert into something that has a stack size limitation - for(int i = 0; i < slots.length; i++) { + if(!didSomething) for(int i = 0; i < slots.length; i++) { ItemStack stack = slots[i]; if(stack != null) { stack = stack.copy(); - stack.stackSize = 1; + + int overshoot = 0; + if(te instanceof TileEntityProxyBase) te = ((TileEntityProxyBase) te).getTE(); // we can't get this far without some slots being exposed, so the result has to be compatible with IInventory anyway + if(te instanceof TileEntityMachineArcFurnaceLarge) { + int toInsert = Math.min(stack.stackSize, ((TileEntityMachineArcFurnaceLarge) te).getMaxInputSize()); + overshoot = stack.stackSize - toInsert; + stack.stackSize = toInsert; + } else { + stack.stackSize = 1; + } + ItemStack ret = CraneInserter.addToInventory((IInventory) te, access, stack.copy(), outputSide.getOpposite().ordinal()); if(ret == null || ret.stackSize != stack.stackSize) { - this.decrStackSize(i, 1); + slots[i] = ret; + if(slots[1] != null) { + slots[i].stackSize += overshoot; + } else if(overshoot > 0){ + slots[i] = stack.copy(); + slots[i].stackSize = overshoot; + } this.markDirty(); - return; + didSomething = true; + break; } } } diff --git a/src/main/resources/assets/hbm/textures/gui/storage/gui_crane_router.png b/src/main/resources/assets/hbm/textures/gui/storage/gui_crane_router.png index 767966144..0957afd8c 100644 Binary files a/src/main/resources/assets/hbm/textures/gui/storage/gui_crane_router.png and b/src/main/resources/assets/hbm/textures/gui/storage/gui_crane_router.png differ diff --git a/src/main/resources/assets/hbm/textures/models/weapons/drill.png b/src/main/resources/assets/hbm/textures/models/weapons/drill.png index c07d7c3a2..de7c228a8 100644 Binary files a/src/main/resources/assets/hbm/textures/models/weapons/drill.png and b/src/main/resources/assets/hbm/textures/models/weapons/drill.png differ