Merge branch 'HbmMods:master' into master

This commit is contained in:
Night Heron 2025-04-11 01:24:41 +08:00 committed by GitHub
commit 0cb6d3530f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
46 changed files with 1342 additions and 150 deletions

View File

@ -10,10 +10,8 @@
name: Java CI with Gradle
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: "0 0 * * *"
jobs:
build:

View File

@ -20,6 +20,9 @@ This should go without saying, but please don't PR code that was never actually
**Addendum:** Because apparently some people think that testing is somehow optional, it is now **mandatory** to test the code both on a client and on a server. If the PR contains compat code, the game has to work **with and without** the mod that the compat is for.
## No refactor PRs
Your refactors suck ass and usually something ends up breaking.
## Communication
If you're planning on adding some new thing or doing a grand change, it's best to ask whether that's a good idea before spending 50 hours on a project that won't end up getting merged, due to issues that could have been entirely avoidable with communication.

View File

@ -6,6 +6,18 @@
* Aircraft carriers can spawn naval mines, which behave like landmines
* New weapon mods
* The laser rifle now has a shotgun barrel, extended capacitor and automatic receiver
* Compact compressor
* Only a third as tall as the regular compressor with a footprint less than twice as wide
* Comes with a frame that allows for stacking of multiple compressors without it looking ugly
* Otherwise identical to the regular compressor
* Pneumatic tubes
* Allows instant item transport without laggy entities
* Requires compressed air to work, air compression determines the max range (10 - 1,000m)
* Has various filter and order options
* Muffler compatible
* Air intake
* Simple machine that uses 100HE/t to produce 1B of compressed air
* Also looks really cool to have on the roof of factories
## Changed
* .75 bolts now work as advertised
@ -26,6 +38,8 @@
* Placing conveyor belts now creates a draggable ghost that will automatically attempt to pathfind towards the destination
* Lifts and chutes are placed automatically, meaning they no longer need crafting recipes
* Changed the optimized receiver generic gun mod to +15% damage
* The xenon chemical plant recipes as well as biogas now require compressed air instead of no fluid at all
* Removed old unused radar configs
## Fixed
* Fixed taint destroying bedrock
@ -37,4 +51,6 @@
* Fixed issues with the new crate functionality
* Fixed dupe regarding the toolbox
* Fixed dummies with no OC components taking up a ton of component slots
* Fixed infested glyphids spawning maggots also on the clientside, creating unkillable ghosts
* Fixed infested glyphids spawning maggots also on the clientside, creating unkillable ghosts
* Fixed top left column not being selectable in the RBMK console
* Fixed CIWS hitrate config being read wrong

View File

@ -4,6 +4,7 @@ import com.hbm.handler.threading.PacketThreading;
import com.hbm.interfaces.NotableComments;
import com.hbm.packet.toclient.AuxParticlePacketNT;
import com.hbm.util.Compat;
import com.hbm.util.fauxpointtwelve.DirPos;
import api.hbm.energymk2.Nodespace.PowerNode;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
@ -31,6 +32,8 @@ public interface IEnergyReceiverMK2 extends IEnergyHandlerMK2 {
return this.getMaxPower();
}
public default void trySubscribe(World world, DirPos pos) { trySubscribe(world, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); }
public default void trySubscribe(World world, int x, int y, int z, ForgeDirection dir) {
TileEntity te = Compat.getTileStandard(world, x, y, z);

View File

@ -7,20 +7,12 @@ import com.hbm.blocks.gas.*;
import com.hbm.blocks.generic.*;
import com.hbm.blocks.generic.BlockHazard.ExtDisplayEffect;
import com.hbm.blocks.machine.*;
import com.hbm.blocks.machine.albion.BlockPABeamline;
import com.hbm.blocks.machine.albion.BlockPADetector;
import com.hbm.blocks.machine.albion.BlockPADipole;
import com.hbm.blocks.machine.albion.BlockPAQuadrupole;
import com.hbm.blocks.machine.albion.BlockPARFC;
import com.hbm.blocks.machine.albion.BlockPASource;
import com.hbm.blocks.machine.albion.*;
import com.hbm.blocks.machine.pile.*;
import com.hbm.blocks.machine.rbmk.*;
import com.hbm.blocks.network.*;
import com.hbm.blocks.rail.*;
import com.hbm.blocks.test.TestCharge;
import com.hbm.blocks.test.TestCore;
import com.hbm.blocks.test.TestEventTester;
import com.hbm.blocks.test.TestObjTester;
import com.hbm.blocks.test.*;
import com.hbm.blocks.turret.*;
import com.hbm.items.block.*;
import com.hbm.items.bomb.ItemPrototypeBlock;
@ -990,6 +982,7 @@ public class ModBlocks {
public static Block machine_liquefactor;
public static Block machine_solidifier;
public static Block machine_intake;
public static Block machine_compressor;
public static Block machine_compressor_compact;
@ -1962,7 +1955,7 @@ public class ModBlocks {
drone_crate_provider = new DroneDock().setBlockName("drone_crate_provider").setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":drone_crate_provider");
drone_crate_requester = new DroneDock().setBlockName("drone_crate_requester").setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":drone_crate_requester");
pneumatic_tube = new PneumoTube().setBlockName("pneumatic_tube").setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":pneumatic_tube");
pneumatic_tube = new PneumoTube().setBlockName("pneumatic_tube").setStepSound(ModSoundTypes.pipe).setHardness(0.1F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":pneumatic_tube");
chain = new BlockChain(Material.iron).setBlockName("dungeon_chain").setHardness(0.25F).setResistance(2.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":chain");
@ -2266,6 +2259,7 @@ public class ModBlocks {
machine_liquefactor = new MachineLiquefactor().setBlockName("machine_liquefactor").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine");
machine_solidifier = new MachineSolidifier().setBlockName("machine_solidifier").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine");
machine_intake = new MachineIntake().setBlockName("machine_intake").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine");
machine_compressor = new MachineCompressor().setBlockName("machine_compressor").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine");
machine_compressor_compact = new MachineCompressorCompact().setBlockName("machine_compressor_compact").setHardness(10.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel_machine");
@ -3291,6 +3285,7 @@ public class ModBlocks {
GameRegistry.registerBlock(machine_deuterium_tower, machine_deuterium_tower.getUnlocalizedName());
GameRegistry.registerBlock(machine_liquefactor, ItemBlockBase.class, machine_liquefactor.getUnlocalizedName());
GameRegistry.registerBlock(machine_solidifier, ItemBlockBase.class, machine_solidifier.getUnlocalizedName());
register(machine_intake);
register(machine_compressor);
register(machine_compressor_compact);
GameRegistry.registerBlock(machine_electrolyser, machine_electrolyser.getUnlocalizedName());

View File

@ -6,11 +6,7 @@ import com.hbm.blocks.ModBlocks;
import com.hbm.config.ServerConfig;
import com.hbm.explosion.ExplosionLarge;
import com.hbm.explosion.vanillant.ExplosionVNT;
import com.hbm.explosion.vanillant.standard.BlockAllocatorStandard;
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
import com.hbm.explosion.vanillant.standard.EntityProcessorCrossSmooth;
import com.hbm.explosion.vanillant.standard.ExplosionEffectWeapon;
import com.hbm.explosion.vanillant.standard.PlayerProcessorStandard;
import com.hbm.explosion.vanillant.standard.*;
import com.hbm.interfaces.IBomb;
import com.hbm.items.ModItems;
import com.hbm.items.weapon.sedna.factory.XFactoryCatapult;
@ -179,7 +175,7 @@ public class Landmine extends BlockContainer implements IBomb {
ExplosionLarge.spawnShrapnels(world, x + 0.5, y + 0.5, z + 0.5, 5);
} else if(this == ModBlocks.mine_naval) {
ExplosionVNT vnt = new ExplosionVNT(world, x + 5, y + 5, z + 5, 25F);
vnt.setBlockAllocator(new BlockAllocatorStandard(64));
vnt.setBlockAllocator(new BlockAllocatorWater(32));
vnt.setBlockProcessor(new BlockProcessorStandard());
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(0.5, ServerConfig.MINE_NAVAL_DAMAGE.get()).setupPiercing(5F, 0.2F));
vnt.setPlayerProcessor(new PlayerProcessorStandard());

View File

@ -0,0 +1,50 @@
package com.hbm.blocks.machine;
import java.util.ArrayList;
import java.util.List;
import com.hbm.blocks.BlockDummyable;
import com.hbm.blocks.ILookOverlay;
import com.hbm.tileentity.TileEntityProxyCombo;
import com.hbm.tileentity.machine.TileEntityMachineIntake;
import com.hbm.util.BobMathUtil;
import com.hbm.util.I18nUtil;
import net.minecraft.block.material.Material;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre;
public class MachineIntake extends BlockDummyable implements ILookOverlay {
public MachineIntake() {
super(Material.iron);
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
if(meta >= 12) return new TileEntityMachineIntake();
return new TileEntityProxyCombo().power().fluid();
}
@Override public int[] getDimensions() { return new int[] {0, 0, 1, 0, 1, 0}; }
@Override public int getOffset() { return 0; }
@Override
public void printHook(Pre event, World world, int x, int y, int z) {
int[] pos = this.findCore(world, x, y, z);
if(pos == null) return;
TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]);
if(!(te instanceof TileEntityMachineIntake)) return;
TileEntityMachineIntake intake = (TileEntityMachineIntake) te;
List<String> text = new ArrayList();
text.add((intake.power < intake.getMaxPower() / 20 ? EnumChatFormatting.RED : EnumChatFormatting.GREEN) + "Power: " + BobMathUtil.getShortNumber(intake.power) + "HE");
text.add(EnumChatFormatting.RED + "<- " + EnumChatFormatting.RESET + intake.compair.getTankType().getLocalizedName() + ": " + intake.compair.getFill() + "/" + intake.compair.getMaxFill() + "mB");
ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text);
}
}

View File

@ -3,16 +3,19 @@ package com.hbm.blocks.network;
import java.util.ArrayList;
import java.util.List;
import com.hbm.blocks.ITooltipProvider;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.lib.Library;
import com.hbm.lib.RefStrings;
import com.hbm.main.MainRegistry;
import com.hbm.tileentity.network.TileEntityPneumoTube;
import com.hbm.util.Compat;
import api.hbm.block.IToolable;
import api.hbm.fluidmk2.IFluidConnectorBlockMK2;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.BlockContainer;
@ -21,6 +24,7 @@ import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
@ -29,12 +33,13 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.ForgeDirection;
public class PneumoTube extends BlockContainer implements IToolable, IFluidConnectorBlockMK2 {
public class PneumoTube extends BlockContainer implements IToolable, IFluidConnectorBlockMK2, ITooltipProvider {
@SideOnly(Side.CLIENT) public IIcon baseIcon;
@SideOnly(Side.CLIENT) public IIcon iconIn;
@SideOnly(Side.CLIENT) public IIcon iconOut;
@SideOnly(Side.CLIENT) public IIcon iconConnector;
@SideOnly(Side.CLIENT) public IIcon iconStraight;
@SideOnly(Side.CLIENT) public IIcon activeIcon;
public boolean[] renderSides = new boolean[] {true, true, true, true, true, true};
@ -62,6 +67,7 @@ public class PneumoTube extends BlockContainer implements IToolable, IFluidConne
iconIn = reg.registerIcon(RefStrings.MODID + ":pneumatic_tube_in");
iconOut = reg.registerIcon(RefStrings.MODID + ":pneumatic_tube_out");
iconConnector = reg.registerIcon(RefStrings.MODID + ":pneumatic_tube_connector");
iconStraight = reg.registerIcon(RefStrings.MODID + ":pneumatic_tube_straight");
this.activeIcon = this.baseIcon = this.blockIcon;
}
@ -81,6 +87,24 @@ public class PneumoTube extends BlockContainer implements IToolable, IFluidConne
public void resetRenderSides() {
for(int i = 0; i < 6; i++) renderSides[i] = true;
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
if(player.getHeldItem() != null && ToolType.getType(player.getHeldItem()) == ToolType.SCREWDRIVER) return false;
if(!player.isSneaking()) {
TileEntity tile = world.getTileEntity(x, y, z);
if(tile instanceof TileEntityPneumoTube) {
TileEntityPneumoTube tube = (TileEntityPneumoTube) tile;
if(tube.isCompressor()) {
FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z);
return true;
}
}
return false;
} else {
return false;
}
}
@Override
public boolean onScrew(World world, EntityPlayer player, int x, int y, int z, int side, float fX, float fY, float fZ, ToolType tool) {
@ -92,11 +116,12 @@ public class PneumoTube extends BlockContainer implements IToolable, IFluidConne
ForgeDirection rot = player.isSneaking() ? tube.ejectionDir : tube.insertionDir;
ForgeDirection oth = player.isSneaking() ? tube.insertionDir : tube.ejectionDir;
for(int i = 0; i < 6; i++) {
for(int i = 0; i < 7; i++) {
rot = ForgeDirection.getOrientation((rot.ordinal() + 1) % 7);
if(rot == ForgeDirection.UNKNOWN) break; //unknown is always valid, simply disables this part
if(rot == oth) continue; //skip if both positions collide
TileEntity tile = Compat.getTileStandard(world, x + rot.offsetX, y + rot.offsetY, z + rot.offsetZ);
if(tile instanceof TileEntityPneumoTube) continue;
if(tile instanceof IInventory) break; //valid if connected to an IInventory
}
@ -118,12 +143,12 @@ public class PneumoTube extends BlockContainer implements IToolable, IFluidConne
bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y + lower, z + lower, x + upper, y + upper, z + upper));
if(canConnectTo(world, x, y, z, Library.POS_X) || canConnectToAir(world, x, y, z, Library.NEG_X)) bbs.add(AxisAlignedBB.getBoundingBox(x + upper, y + lower, z + lower, x + 1, y + upper, z + upper));
if(canConnectTo(world, x, y, z, Library.NEG_X) || canConnectToAir(world, x, y, z, Library.POS_X)) bbs.add(AxisAlignedBB.getBoundingBox(x, y + lower, z + lower, x + lower, y + upper, z + upper));
if(canConnectTo(world, x, y, z, Library.POS_Y) || canConnectToAir(world, x, y, z, Library.NEG_Y)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y + upper, z + lower, x + upper, y + 1, z + upper));
if(canConnectTo(world, x, y, z, Library.NEG_Y) || canConnectToAir(world, x, y, z, Library.POS_Y)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y, z + lower, x + upper, y + lower, z + upper));
if(canConnectTo(world, x, y, z, Library.POS_Z) || canConnectToAir(world, x, y, z, Library.NEG_Z)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y + lower, z + upper, x + upper, y + upper, z + 1));
if(canConnectTo(world, x, y, z, Library.NEG_Z) || canConnectToAir(world, x, y, z, Library.POS_Z)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y + lower, z, x + upper, y + upper, z + lower));
if(canConnectTo(world, x, y, z, Library.POS_X) || canConnectToAir(world, x, y, z, Library.POS_X)) bbs.add(AxisAlignedBB.getBoundingBox(x + upper, y + lower, z + lower, x + 1, y + upper, z + upper));
if(canConnectTo(world, x, y, z, Library.NEG_X) || canConnectToAir(world, x, y, z, Library.NEG_X)) bbs.add(AxisAlignedBB.getBoundingBox(x, y + lower, z + lower, x + lower, y + upper, z + upper));
if(canConnectTo(world, x, y, z, Library.POS_Y) || canConnectToAir(world, x, y, z, Library.POS_Y)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y + upper, z + lower, x + upper, y + 1, z + upper));
if(canConnectTo(world, x, y, z, Library.NEG_Y) || canConnectToAir(world, x, y, z, Library.NEG_Y)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y, z + lower, x + upper, y + lower, z + upper));
if(canConnectTo(world, x, y, z, Library.POS_Z) || canConnectToAir(world, x, y, z, Library.POS_Z)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y + lower, z + upper, x + upper, y + upper, z + 1));
if(canConnectTo(world, x, y, z, Library.NEG_Z) || canConnectToAir(world, x, y, z, Library.NEG_Z)) bbs.add(AxisAlignedBB.getBoundingBox(x + lower, y + lower, z, x + upper, y + upper, z + lower));
for(AxisAlignedBB bb : bbs) {
if(entityBounding.intersectsWith(bb)) {
@ -185,12 +210,23 @@ public class PneumoTube extends BlockContainer implements IToolable, IFluidConne
public boolean canConnectToAir(IBlockAccess world, int x, int y, int z, ForgeDirection dir) {
TileEntityPneumoTube tube = (TileEntityPneumoTube) world.getTileEntity(x, y, z);
if(tube != null && tube.insertionDir == ForgeDirection.UNKNOWN) return false;
if(tube != null) {
if(!tube.isCompressor()) return false;
if(tube.ejectionDir == dir || tube.insertionDir == dir) return false;
}
TileEntity tile = world.getTileEntity(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ);
if(tile instanceof TileEntityPneumoTube) return false;
return Library.canConnectFluid(world, x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ, dir, Fluids.AIR);
}
@Override
public boolean canConnect(FluidType type, IBlockAccess world, int x, int y, int z, ForgeDirection dir) {
TileEntityPneumoTube tube = (TileEntityPneumoTube) world.getTileEntity(x, y, z);
return tube != null && tube.insertionDir != ForgeDirection.UNKNOWN;
return tube != null && tube.isCompressor();
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) {
addStandardInfo(stack, player, list, ext);
}
}

View File

@ -5,9 +5,6 @@ import net.minecraftforge.common.config.Property;
public class WeaponConfig {
public static int radarRange = 1000;
public static int radarBuffer = 30;
public static int radarAltitude = 55;
public static int ciwsHitrate = 50;
public static boolean dropCell = true;
@ -21,18 +18,9 @@ public class WeaponConfig {
public static void loadFromConfig(Configuration config) {
final String CATEGORY_MISSILE = CommonConfig.CATEGORY_MISSILE;
Property propRadarRange = config.get(CATEGORY_MISSILE, "7.00_radarRange", 1000);
propRadarRange.comment = "Range of the radar, 50 will result in 100x100 block area covered";
radarRange = propRadarRange.getInt();
Property propRadarBuffer = config.get(CATEGORY_MISSILE, "7.01_radarBuffer", 30);
propRadarBuffer.comment = "How high entities have to be above the radar to be detected";
radarBuffer = propRadarBuffer.getInt();
Property propRadarAltitude = config.get(CATEGORY_MISSILE, "7.02_radarAltitude", 55);
propRadarAltitude.comment = "Y height required for the radar to work";
radarAltitude = propRadarAltitude.getInt();
Property propCiwsHitrate = config.get(CATEGORY_MISSILE, "7.03_ciwsAccuracy", 50);
propCiwsHitrate.comment = "Additional modifier for CIWS accuracy";
ciwsHitrate = propRadarAltitude.getInt();
ciwsHitrate = propCiwsHitrate.getInt();
final String CATEGORY_DROPS = CommonConfig.CATEGORY_DROPS;
dropCell = CommonConfig.createConfigBool(config, CATEGORY_DROPS, "10.00_dropCell", "Whether antimatter cells should explode when dropped", true);

View File

@ -0,0 +1,78 @@
package com.hbm.explosion.vanillant.standard;
import java.util.HashSet;
import com.hbm.explosion.vanillant.ExplosionVNT;
import com.hbm.explosion.vanillant.interfaces.IBlockAllocator;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.util.MathHelper;
import net.minecraft.world.ChunkPosition;
import net.minecraft.world.World;
public class BlockAllocatorWater implements IBlockAllocator {
protected int resolution;
public BlockAllocatorWater(int resolution) {
this.resolution = resolution;
}
@Override
public HashSet<ChunkPosition> allocate(ExplosionVNT explosion, World world, double x, double y, double z, float size) {
HashSet<ChunkPosition> affectedBlocks = new HashSet<>();
for (int i = 0; i < this.resolution; ++i) {
for (int j = 0; j < this.resolution; ++j) {
for (int k = 0; k < this.resolution; ++k) {
if (i == 0 || i == this.resolution - 1 || j == 0 || j == this.resolution - 1 || k == 0 || k == this.resolution - 1) {
double d0 = (float) i / ((float) this.resolution - 1.0F) * 2.0F - 1.0F;
double d1 = (float) j / ((float) this.resolution - 1.0F) * 2.0F - 1.0F;
double d2 = (float) k / ((float) this.resolution - 1.0F) * 2.0F - 1.0F;
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 /= d3;
d1 /= d3;
d2 /= d3;
float powerRemaining = size * (0.7F + world.rand.nextFloat() * 0.6F);
double currentX = x;
double currentY = y;
double currentZ = z;
for (float stepSize = 0.3F; powerRemaining > 0.0F; powerRemaining -= stepSize * 0.75F) {
int blockX = MathHelper.floor_double(currentX);
int blockY = MathHelper.floor_double(currentY);
int blockZ = MathHelper.floor_double(currentZ);
Block block = world.getBlock(blockX, blockY, blockZ);
Material material = block.getMaterial();
// im braindead and copy code 🧃🐱👤
if (material != Material.air && !material.isLiquid()) {
float blockResistance = explosion.exploder != null ?
explosion.exploder.func_145772_a(explosion.compat, world, blockX, blockY, blockZ, block) :
block.getExplosionResistance(null, world, blockX, blockY, blockZ, x, y, z);
powerRemaining -= (blockResistance + 0.3F) * stepSize;
}
if (powerRemaining > 0.0F &&
(explosion.exploder == null || explosion.exploder.func_145774_a(explosion.compat, world, blockX, blockY, blockZ, block, powerRemaining)) &&
!material.isLiquid()) {
affectedBlocks.add(new ChunkPosition(blockX, blockY, blockZ));
}
currentX += d0 * (double) stepSize;
currentY += d1 * (double) stepSize;
currentZ += d2 * (double) stepSize;
}
}
}
}
}
return affectedBlocks;
}
}

View File

@ -13,60 +13,60 @@ public class ContainerMachineRTG extends Container {
private TileEntityMachineRTG testNuke;
private int heat;
public ContainerMachineRTG(InventoryPlayer invPlayer, TileEntityMachineRTG tedf) {
heat = 0;
testNuke = tedf;
this.addSlotToContainer(new Slot(tedf, 0, 26, 17));
this.addSlotToContainer(new Slot(tedf, 1, 44, 17));
this.addSlotToContainer(new Slot(tedf, 2, 62, 17));
this.addSlotToContainer(new Slot(tedf, 3, 80, 17));
this.addSlotToContainer(new Slot(tedf, 4, 98, 17));
this.addSlotToContainer(new Slot(tedf, 5, 26, 35));
this.addSlotToContainer(new Slot(tedf, 6, 44, 35));
this.addSlotToContainer(new Slot(tedf, 7, 62, 35));
this.addSlotToContainer(new Slot(tedf, 8, 80, 35));
this.addSlotToContainer(new Slot(tedf, 9, 98, 35));
this.addSlotToContainer(new Slot(tedf, 10, 26, 53));
this.addSlotToContainer(new Slot(tedf, 11, 44, 53));
this.addSlotToContainer(new Slot(tedf, 12, 62, 53));
this.addSlotToContainer(new Slot(tedf, 13, 80, 53));
this.addSlotToContainer(new Slot(tedf, 14, 98, 53));
this.addSlotToContainer(new Slot(tedf, 0, 16, 18));
this.addSlotToContainer(new Slot(tedf, 1, 34, 18));
this.addSlotToContainer(new Slot(tedf, 2, 52, 18));
this.addSlotToContainer(new Slot(tedf, 3, 70, 18));
this.addSlotToContainer(new Slot(tedf, 4, 88, 18));
this.addSlotToContainer(new Slot(tedf, 5, 16, 36));
this.addSlotToContainer(new Slot(tedf, 6, 34, 36));
this.addSlotToContainer(new Slot(tedf, 7, 52, 36));
this.addSlotToContainer(new Slot(tedf, 8, 70, 36));
this.addSlotToContainer(new Slot(tedf, 9, 88, 36));
this.addSlotToContainer(new Slot(tedf, 10, 16, 54));
this.addSlotToContainer(new Slot(tedf, 11, 34, 54));
this.addSlotToContainer(new Slot(tedf, 12, 52, 54));
this.addSlotToContainer(new Slot(tedf, 13, 70, 54));
this.addSlotToContainer(new Slot(tedf, 14, 88, 54));
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 9; j++)
{
this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
this.addSlotToContainer(new Slot(invPlayer, j + i * 9 + 9, 8 + j * 18, 106 + i * 18));
}
}
for(int i = 0; i < 9; i++)
{
this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 142));
this.addSlotToContainer(new Slot(invPlayer, i, 8 + i * 18, 164));
}
}
@Override
public void addCraftingToCrafters(ICrafting crafting) {
super.addCraftingToCrafters(crafting);
crafting.sendProgressBarUpdate(this, 0, this.testNuke.heat);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int par2)
{
public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int par2)
{
ItemStack var3 = null;
Slot var4 = (Slot) this.inventorySlots.get(par2);
if (var4 != null && var4.getHasStack())
{
ItemStack var5 = var4.getStack();
var3 = var5.copy();
if (par2 <= 14) {
if (par2 <= 14) {
if (!this.mergeItemStack(var5, 15, this.inventorySlots.size(), true))
{
return null;
@ -74,9 +74,9 @@ public class ContainerMachineRTG extends Container {
}
else if (!this.mergeItemStack(var5, 0, 15, false))
{
return null;
return null;
}
if (var5.stackSize == 0)
{
var4.putStack((ItemStack) null);
@ -86,19 +86,19 @@ public class ContainerMachineRTG extends Container {
var4.onSlotChanged();
}
}
return var3;
}
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return testNuke.isUseableByPlayer(player);
}
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
for(int i = 0; i < this.crafters.size(); i++)
{
ICrafting par1 = (ICrafting)this.crafters.get(i);
@ -111,7 +111,7 @@ public class ContainerMachineRTG extends Container {
this.heat = this.testNuke.heat;
}
@Override
public void updateProgressBar(int i, int j) {
if(i == 0)

View File

@ -49,9 +49,7 @@ public class FluidTank {
}
public FluidTank withPressure(int pressure) {
if(this.pressure != pressure) this.setFill(0);
this.pressure = pressure;
return this;
}

View File

@ -19,61 +19,59 @@ public class GUIMachineRTG extends GuiInfoContainer {
private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/gui_rtg.png");
private TileEntityMachineRTG rtg;
public GUIMachineRTG(InventoryPlayer invPlayer, TileEntityMachineRTG tedf) {
super(new ContainerMachineRTG(invPlayer, tedf));
rtg = tedf;
this.xSize = 176;
this.ySize = 166;
this.ySize = 188;
}
@Override
public void drawScreen(int mouseX, int mouseY, float f) {
super.drawScreen(mouseX, mouseY, f);
this.drawElectricityInfo(this, mouseX, mouseY, guiLeft + 152, guiTop + 69 - 52, 16, 52, rtg.power, rtg.powerMax);
this.drawElectricityInfo(this, mouseX, mouseY, guiLeft + 146, guiTop + 9, 16, 51, rtg.power, rtg.powerMax);
String[] heatText = I18nUtil.resolveKeyArray("desc.gui.rtg.heat", rtg.heat);
this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 134, guiTop + 17, 16, 52, mouseX, mouseY, heatText);
this.drawCustomInfoStat(mouseX, mouseY, guiLeft + 124, guiTop + 9, 16, 51, mouseX, mouseY, heatText);
List<ItemRTGPellet> pellets = ItemRTGPellet.pelletList;
String[] pelletText = new String[pellets.size() + 1];
pelletText[0] = I18nUtil.resolveKey("desc.gui.rtg.pellets");
for(int i = 0; i < pellets.size(); i++) {
ItemRTGPellet pellet = pellets.get(i);
pelletText[i + 1] = I18nUtil.resolveKey("desc.gui.rtg.pelletPower", I18nUtil.resolveKey(pellet.getUnlocalizedName() + ".name"), pellet.getHeat() * 5);
}
this.drawCustomInfoStat(mouseX, mouseY, guiLeft - 16, guiTop + 36, 16, 16, guiLeft - 8, guiTop + 36 + 16, pelletText);
this.drawCustomInfoStat(mouseX, mouseY, guiLeft - 12, guiTop + 25, 16, 16, guiLeft - 8, guiTop + 36 + 16, pelletText);
}
@Override
protected void drawGuiContainerForegroundLayer( int i, int j) {
String name = this.rtg.hasCustomInventoryName() ? this.rtg.getInventoryName() : I18n.format(this.rtg.getInventoryName());
this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752);
this.fontRendererObj.drawString(name, 13 ,7, 10925486);
this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
}
@Override
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
if(rtg.hasHeat())
{
int i = rtg.getHeatScaled(52);
drawTexturedModalRect(guiLeft + 134, guiTop + 69 - i, 176, 52 - i, 16, i);
if (rtg.hasHeat()) {
int i = rtg.getHeatScaled(51); // was 50
drawTexturedModalRect(guiLeft + 124, guiTop + 61 - i, 176, 10 + (51 - i), 16, i);
}
if(rtg.hasPower())
{
int i = (int)rtg.getPowerScaled(52);
drawTexturedModalRect(guiLeft + 152, guiTop + 69 - i, 192, 52 - i, 16, i);
if (rtg.hasPower()) {
int i = (int) rtg.getPowerScaled(51); // was 50
drawTexturedModalRect(guiLeft + 146, guiTop + 61 - i, 192, 10 + (51 - i), 16, i);
}
this.drawInfoPanel(guiLeft - 16, guiTop + 36, 16, 16, 2);
this.drawInfoPanel(guiLeft - 12, guiTop + 25, 16, 16, 2);
}
}

View File

@ -0,0 +1,110 @@
package com.hbm.inventory.gui;
import java.util.Arrays;
import org.lwjgl.opengl.GL11;
import com.hbm.inventory.container.ContainerPneumoTube;
import com.hbm.lib.RefStrings;
import com.hbm.module.ModulePatternMatcher;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toserver.NBTControlPacket;
import com.hbm.render.util.GaugeUtil;
import com.hbm.tileentity.network.TileEntityPneumoTube;
import com.hbm.uninos.networkproviders.PneumaticNetwork;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
public class GUIPneumoTube extends GuiInfoContainer {
private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/storage/gui_pneumatic_pipe.png");
public TileEntityPneumoTube tube;
public GUIPneumoTube(InventoryPlayer invPlayer, TileEntityPneumoTube tedf) {
super(new ContainerPneumoTube(invPlayer, tedf));
this.tube = tedf;
this.xSize = 176;
this.ySize = 185;
}
@Override
public void drawScreen(int x, int y, float interp) {
super.drawScreen(x, y, interp);
tube.compair.renderTankInfo(this, x, y, guiLeft + 7, guiTop + 16, 18, 18);
this.drawCustomInfoStat(x, y, guiLeft + 7, guiTop + 52, 18, 18, x, y, (tube.redstone ? (EnumChatFormatting.GREEN + "ON ") : (EnumChatFormatting.RED + "OFF ")) + EnumChatFormatting.RESET + "with Redstone");
this.drawCustomInfoStat(x, y, guiLeft + 6, guiTop + 36, 20, 8, x, y, "Compressor: " + tube.compair.getPressure() + " PU", "Max range: " + tube.getRangeFromPressure(tube.compair.getPressure()) + "m");
this.drawCustomInfoStat(x, y, guiLeft + 151, guiTop + 16, 18, 18, x, y, EnumChatFormatting.YELLOW + "Receiver order:", tube.receiveOrder == PneumaticNetwork.RECEIVE_ROBIN ? "Round robin" : "Random");
this.drawCustomInfoStat(x, y, guiLeft + 151, guiTop + 52, 18, 18, x, y, EnumChatFormatting.YELLOW + "Provider slot order:", tube.sendOrder == PneumaticNetwork.SEND_FIRST ? "First to last" : tube.sendOrder == PneumaticNetwork.SEND_LAST ? "Last to first" : "Random");
if(this.mc.thePlayer.inventory.getItemStack() == null) {
for(int i = 0; i < 15; ++i) {
Slot slot = (Slot) this.inventorySlots.inventorySlots.get(i);
if(this.isMouseOverSlot(slot, x, y) && tube.pattern.modes[i] != null) {
this.func_146283_a(Arrays.asList(new String[] { EnumChatFormatting.RED + "Right click to change", ModulePatternMatcher.getLabel(tube.pattern.modes[i]) }), x, y - 30);
}
}
}
}
@Override
protected void mouseClicked(int x, int y, int i) {
super.mouseClicked(x, y, i);
click(x, y, 7, 52, 18, 18, "redstone");
click(x, y, 6, 36, 20, 8, "pressure");
click(x, y, 128, 30, 14, 26, "whitelist");
click(x, y, 151, 16, 18, 18, "receive");
click(x, y, 151, 52, 18, 18, "send");
}
public void click(int x, int y, int left, int top, int sizeX, int sizeY, String name) {
if(checkClick(x, y, left, top, sizeX, sizeY)) {
mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
NBTTagCompound data = new NBTTagCompound();
data.setBoolean(name, true);
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, tube.xCoord, tube.yCoord, tube.zCoord));
}
}
@Override
protected void drawGuiContainerForegroundLayer(int i, int j) {
String name = this.tube.hasCustomInventoryName() ? this.tube.getInventoryName() : I18n.format(this.tube.getInventoryName());
this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 5, 4210752);
this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
}
@Override
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
if(tube.redstone) drawTexturedModalRect(guiLeft + 7, guiTop + 52, 179, 0, 18, 18);
if(tube.whitelist) {
drawTexturedModalRect(guiLeft + 139, guiTop + 33, 176, 0, 3, 6);
} else {
drawTexturedModalRect(guiLeft + 139, guiTop + 47, 176, 0, 3, 6);
}
drawTexturedModalRect(guiLeft + 151, guiTop + 16, 197, 18 * tube.receiveOrder, 18, 18);
drawTexturedModalRect(guiLeft + 151, guiTop + 52, 215, 18 * tube.sendOrder, 18, 18);
drawTexturedModalRect(guiLeft + 6 + 4 * (tube.compair.getPressure() - 1), guiTop + 36, 179, 18, 4, 8);
GaugeUtil.drawSmoothGauge(guiLeft + 16, guiTop + 25, this.zLevel, (double) tube.compair.getFill() / (double) tube.compair.getMaxFill(), 5, 2, 1, 0xCA6C43, 0xAB4223);
}
}

View File

@ -134,7 +134,7 @@ public class GUIRBMKConsole extends GuiScreen {
int index = ((mouseX - bX - guiLeft) / size + (mouseY - bY - guiTop) / size * 15);
if(index > 0 && index < selection.length && console.columns[index] != null) {
if(index >= 0 && index < selection.length && console.columns[index] != null) {
this.selection[index] = !this.selection[index];
mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 0.75F + (this.selection[index] ? 0.25F : 0.0F)));

View File

@ -219,10 +219,12 @@ public class ChemplantRecipes extends SerializableRecipe {
new FluidStack(Fluids.HYDROGEN, 400),
new FluidStack(Fluids.OXYGEN, 400)));
recipes.add(new ChemRecipe(59, "XENON", 300)
.inputFluids(new FluidStack(Fluids.NONE, 0))
.inputFluids(new FluidStack(Fluids.AIR, 16_000))
.outputFluids(new FluidStack(Fluids.XENON, 50)));
recipes.add(new ChemRecipe(60, "XENON_OXY", 20)
.inputFluids(new FluidStack(Fluids.OXYGEN, 250))
.inputFluids(
new FluidStack(Fluids.AIR, 8_000),
new FluidStack(Fluids.OXYGEN, 250))
.outputFluids(new FluidStack(Fluids.XENON, 50)));
recipes.add(new ChemRecipe(62, "BALEFIRE", 100)
.inputItems(new ComparableStack(ModItems.egg_balefire_shard))
@ -327,7 +329,7 @@ public class ChemplantRecipes extends SerializableRecipe {
new ComparableStack(ModItems.nugget_bismuth, 4))
.inputFluids(new FluidStack(Fluids.PEROXIDE, 1000, 5))
.outputFluids(new FluidStack(Fluids.DEATH, 1000, 0)));
//one bucket of ethanol equals 275_000 TU using the diesel baseline0
//one bucket of ethanol equals 275_000 TU using the diesel baseline
//the coal baseline is 400_000 per piece
//if we assume a burntime of 1.5 ops (300 ticks) for sugar at 100 TU/t that would equal a total of 30_000 TU
recipes.add(new ChemRecipe(75, "ETHANOL", 50)
@ -399,6 +401,7 @@ public class ChemplantRecipes extends SerializableRecipe {
public static void registerOtherOil() {
recipes.add(new ChemRecipe(31, "BP_BIOGAS", 60)
.inputItems(new ComparableStack(ModItems.biomass, 16)) //if we assume 1B BF = 500k and translate that to 2B BG = 500k, then each biomass is worth ~31k or roughly 1.5 furnace operations
.inputFluids(new FluidStack(Fluids.AIR, 4000))
.outputFluids(new FluidStack(2000, Fluids.BIOGAS)));
recipes.add(new ChemRecipe(32, "BP_BIOFUEL", 60)
.inputFluids(new FluidStack(1500, Fluids.BIOGAS), new FluidStack(250, Fluids.ETHANOL))

View File

@ -31,17 +31,12 @@ import net.minecraft.util.ResourceLocation;
// clientonly...
public class ArmorModel extends ItemArmor {
@SideOnly(Side.CLIENT)
private static final ModelGoggles modelGoggles = new ModelGoggles();
@SideOnly(Side.CLIENT)
private static final ModelHat modelHat = new ModelHat(0);
@SideOnly(Side.CLIENT)
private static final ModelCloak modelCloak = new ModelCloak();
@SideOnly(Side.CLIENT) private ModelGoggles modelGoggles;
@SideOnly(Side.CLIENT) private ModelHat modelHat;
@SideOnly(Side.CLIENT) private ModelCloak modelCloak;
@SideOnly(Side.CLIENT)
private static final ResourceLocation[] gogglesBlurs = IntStream.range(0, 6)
.mapToObj(i -> new ResourceLocation(RefStrings.MODID + ":textures/misc/overlay_goggles_" + i + ".png"))
.toArray(ResourceLocation[]::new);
private ResourceLocation[] gogglesBlurs;
public ArmorModel(ArmorMaterial armorMaterial, int armorType) {
super(armorMaterial, 0, armorType);
@ -52,16 +47,19 @@ public class ArmorModel extends ItemArmor {
public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) {
if(this == ModItems.goggles) {
if(armorSlot == 0) {
if(modelGoggles == null) modelGoggles = new ModelGoggles();
return modelGoggles;
}
}
if(this == ModItems.hat) {
if(armorSlot == 0) {
if(modelHat == null) modelHat = new ModelHat(0);
return modelHat;
}
}
if(this == ModItems.cape_radiation || this == ModItems.cape_gasmask || this == ModItems.cape_schrabidium || this == ModItems.cape_hidden) {
if(armorSlot == 1) {
if(modelCloak == null) modelCloak = new ModelCloak();
return modelCloak;
}
}
@ -94,6 +92,10 @@ public class ArmorModel extends ItemArmor {
if(this != ModItems.goggles && this != ModItems.hazmat_helmet_red && this != ModItems.hazmat_helmet_grey)
return;
if(gogglesBlurs == null) gogglesBlurs = IntStream.range(0, 6)
.mapToObj(i -> new ResourceLocation(RefStrings.MODID + ":textures/misc/overlay_goggles_" + i + ".png"))
.toArray(ResourceLocation[]::new);
GL11.glEnable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_DEPTH_TEST);
@ -124,15 +126,8 @@ public class ArmorModel extends ItemArmor {
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean bool) {
if(this == ModItems.cape_radiation) {
list.add("Avalible for everyone");
}
if(this == ModItems.cape_gasmask) {
list.add("Avalible for everyone");
}
if(this == ModItems.cape_schrabidium) {
list.add("Avalible for everyone");
}
if(this == ModItems.cape_radiation) list.add("Avalible for everyone");
if(this == ModItems.cape_gasmask) list.add("Avalible for everyone");
if(this == ModItems.cape_schrabidium) list.add("Avalible for everyone");
}
}

View File

@ -308,6 +308,7 @@ public class ClientProxy extends ServerProxy {
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineCatalyticCracker.class, new RenderCatalyticCracker());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineLiquefactor.class, new RenderLiquefactor());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineSolidifier.class, new RenderSolidifier());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineIntake.class, new RenderIntake());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineCompressor.class, new RenderCompressor());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineCompressorCompact.class, new RenderCompressorCompact());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineDrain.class, new RenderDrain());

View File

@ -598,6 +598,9 @@ public class CraftingManager {
addShapelessAuto(new ItemStack(ModBlocks.fluid_duct_gauge), new Object[] { ModBlocks.fluid_duct_paintable, STEEL.ingot(), DictFrame.fromOne(ModItems.circuit, EnumCircuitType.BASIC) });
addRecipeAuto(new ItemStack(ModBlocks.fluid_valve, 1), new Object[] { "S", "W", 'S', Blocks.lever, 'W', ModBlocks.fluid_duct_paintable });
addRecipeAuto(new ItemStack(ModBlocks.fluid_switch, 1), new Object[] { "S", "W", 'S', REDSTONE.dust(), 'W', ModBlocks.fluid_duct_paintable });
addRecipeAuto(new ItemStack(ModBlocks.pneumatic_tube, 8), new Object[] { "CRC", 'C', CU.plateCast(), 'R', ANY_RUBBER.ingot() });
addRecipeAuto(new ItemStack(ModBlocks.pneumatic_tube, 24), new Object[] { "CRC", 'C', CU.plateWelded(), 'R', ANY_RUBBER.ingot() });
addRecipeAuto(new ItemStack(ModItems.template_folder, 1), new Object[] { "LPL", "BPB", "LPL", 'P', Items.paper, 'L', "dye", 'B', "dye" });
addRecipeAuto(new ItemStack(ModItems.pellet_antimatter, 1), new Object[] { "###", "###", "###", '#', ModItems.cell_antimatter });
addRecipeAuto(new ItemStack(ModItems.fluid_tank_empty, 8), new Object[] { "121", "1G1", "121", '1', AL.plate(), '2', IRON.plate(), 'G', KEY_ANYPANE });
@ -998,6 +1001,7 @@ public class CraftingManager {
addShapelessAuto(new ItemStack(ModItems.ingot_firebrick, 4), new Object[] { ModBlocks.brick_fire });
addRecipeAuto(new ItemStack(ModBlocks.machine_drain), new Object[] { "PPP", "T ", "PPP", 'P', STEEL.plateCast(), 'T', ModItems.tank_steel });
addRecipeAuto(new ItemStack(ModBlocks.machine_intake), new Object[] { "GGG", "PMP", "PTP", 'G', ModBlocks.steel_grate, 'P', STEEL.plate(), 'M', ModItems.motor, 'T', ModItems.tank_steel });
addRecipeAuto(new ItemStack(ModBlocks.filing_cabinet, 1, DecoCabinetEnum.STEEL.ordinal()), new Object[] { " P ", "PIP", " P ", 'P', STEEL.plate(), 'I', ModItems.plate_polymer });

View File

@ -112,6 +112,9 @@ public class ResourceManager {
//Cooling Tower
public static final IModelCustom tower_small = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/tower_small.obj")).asVBO();
public static final IModelCustom tower_large = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/tower_large.obj")).asVBO();
//Air stuff
public static final IModelCustom intake = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/intake.obj")).asVBO();
public static final IModelCustom condenser = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/condenser.obj")).asVBO();
//Wood burner
@ -493,6 +496,7 @@ public class ResourceManager {
public static final ResourceLocation hydrotreater_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/hydrotreater.png");
public static final ResourceLocation liquefactor_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/liquefactor.png");
public static final ResourceLocation solidifier_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/solidifier.png");
public static final ResourceLocation intake_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/intake.png");
public static final ResourceLocation compressor_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/compressor.png");
public static final ResourceLocation compressor_compact_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/compressor_compact.png");
public static final ResourceLocation coker_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/coker.png");

View File

@ -31,20 +31,25 @@ public class RenderPneumoTube implements ISimpleBlockRenderingHandler {
renderer.setRenderBounds(lower, lower, 0, upper, upper, 1);
renderer.uvRotateTop = 2;
renderer.uvRotateBottom = 1;
tessellator.startDrawingQuads();
tessellator.setNormal(0F, 1F, 0F); renderer.renderFaceYPos(block, 0, 0, 0, duct.getIcon(0, 0));
tessellator.setNormal(0F, -1F, 0F); renderer.renderFaceYNeg(block, 0, 0, 0, duct.getIcon(0, 0));
tessellator.setNormal(1F, 0F, 0F); renderer.renderFaceXPos(block, 0, 0, 0, duct.getIcon(0, 0));
tessellator.setNormal(-1F, 0F, 0F); renderer.renderFaceXNeg(block, 0, 0, 0, duct.getIcon(0, 0));
tessellator.setNormal(0F, 1F, 0F); renderer.renderFaceYPos(block, 0, 0, 0, duct.iconStraight);
tessellator.setNormal(0F, -1F, 0F); renderer.renderFaceYNeg(block, 0, 0, 0, duct.iconStraight);
tessellator.setNormal(1F, 0F, 0F); renderer.renderFaceXPos(block, 0, 0, 0, duct.iconStraight);
tessellator.setNormal(-1F, 0F, 0F); renderer.renderFaceXNeg(block, 0, 0, 0, duct.iconStraight);
tessellator.setNormal(0F, 0F, 1F); renderer.renderFaceZPos(block, 0, 0, 0, duct.iconConnector);
tessellator.setNormal(0F, 0F, -1F); renderer.renderFaceZNeg(block, 0, 0, 0, duct.iconConnector);
tessellator.draw();
renderer.uvRotateTop = 0;
renderer.uvRotateBottom = 0;
}
@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
renderer = RenderBlocksNT.INSTANCE.setWorld(world);
Tessellator tessellator = Tessellator.instance;
@ -65,29 +70,46 @@ public class RenderPneumoTube implements ISimpleBlockRenderingHandler {
double lower = 0.3125D;
double upper = 0.6875D;
boolean hasConnections = tile != null && (tile.isCompressor() || tile.isEndpoint());
//Straight along X
if(mask == 0b110000) {
if(mask == 0b110000 && !hasConnections) {
renderer.setRenderBounds(0.0D, lower, lower, 1.0D, upper, upper);
duct.renderSides[4] = false;
duct.renderSides[5] = false;
duct.activeIcon = duct.iconStraight;
renderer.renderStandardBlock(block, x, y, z);
duct.resetRenderSides();
// Straight along Z
} else if(mask == 0b000011) {
} else if(mask == 0b000011 && !hasConnections) {
renderer.setRenderBounds(lower, lower, 0.0D, upper, upper, 1.0D);
duct.renderSides[2] = false;
duct.renderSides[3] = false;
duct.activeIcon = duct.iconStraight;
renderer.uvRotateTop = 2;
renderer.uvRotateBottom = 1;
renderer.renderStandardBlock(block, x, y, z);
duct.resetRenderSides();
renderer.uvRotateTop = 0;
renderer.uvRotateBottom = 0;
//Straight along Y
} else if(mask == 0b001100) {
} else if(mask == 0b001100 && !hasConnections) {
renderer.setRenderBounds(lower, 0.0D, lower, upper, 1.0D, upper);
duct.renderSides[0] = false;
duct.renderSides[1] = false;
duct.activeIcon = duct.iconStraight;
renderer.uvRotateNorth = 2;
renderer.uvRotateSouth = 2;
renderer.uvRotateEast = 2;
renderer.uvRotateWest = 2;
renderer.renderStandardBlock(block, x, y, z);
duct.resetRenderSides();
renderer.uvRotateNorth = 0;
renderer.uvRotateSouth = 0;
renderer.uvRotateEast = 0;
renderer.uvRotateWest = 0;
//Any
} else {
renderer.setRenderBounds(lower, lower, lower, upper, upper, upper);
@ -115,6 +137,8 @@ public class RenderPneumoTube implements ISimpleBlockRenderingHandler {
}
}
duct.activeIcon = duct.baseIcon;
return true;
}
@ -158,10 +182,10 @@ public class RenderPneumoTube implements ISimpleBlockRenderingHandler {
if(dir == Library.NEG_Y) {
duct.renderSides[1] = false;
duct.renderSides[0] = false;
renderer.setRenderBounds(lower, upper, lower, upper, cUpper, upper);
renderer.setRenderBounds(lower, cLower, lower, upper, lower, upper);
renderer.renderStandardBlock(duct, x, y, z); duct.resetRenderSides();
duct.activeIcon = newIcon;
renderer.setRenderBounds(nLower, cUpper, nLower, nUpper, 1, nUpper);
renderer.setRenderBounds(nLower, 0, nLower, nUpper, nLower, nUpper);
renderer.renderStandardBlock(duct, x, y, z);
}
@ -177,10 +201,10 @@ public class RenderPneumoTube implements ISimpleBlockRenderingHandler {
if(dir == Library.NEG_Z) {
duct.renderSides[3] = false;
duct.renderSides[2] = false;
renderer.setRenderBounds(lower, lower, upper, upper, upper, cUpper);
renderer.setRenderBounds(lower, lower, cLower, upper, upper, lower);
renderer.renderStandardBlock(duct, x, y, z); duct.resetRenderSides();
duct.activeIcon = newIcon;
renderer.setRenderBounds(nLower, nLower, cUpper, nUpper, nUpper, 1);
renderer.setRenderBounds(nLower, nLower, 0, nUpper, nUpper, cLower);
renderer.renderStandardBlock(duct, x, y, z);
}

View File

@ -509,6 +509,20 @@ public class ItemRenderLibrary {
GL11.glEnable(GL11.GL_CULL_FACE);
}});
renderers.put(Item.getItemFromBlock(ModBlocks.mine_naval), new ItemRenderBase() {
public void renderInventory() {
GL11.glTranslated(0, 2, -1);
GL11.glScaled(5, 5, 5);
}
public void renderCommon() {
GL11.glTranslated(0, 0, 0);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glShadeModel(GL11.GL_SMOOTH);
bindTexture(ResourceManager.mine_naval_tex);
ResourceManager.mine_naval.renderAll();
GL11.glEnable(GL11.GL_CULL_FACE);
}});
renderers.put(Item.getItemFromBlock(ModBlocks.mine_fat), new ItemRenderBase() {
public void renderInventory() {
GL11.glTranslated(0, -1, 0);

View File

@ -0,0 +1,68 @@
package com.hbm.render.tileentity;
import org.lwjgl.opengl.GL11;
import com.hbm.blocks.ModBlocks;
import com.hbm.main.ResourceManager;
import com.hbm.render.item.ItemRenderBase;
import com.hbm.tileentity.machine.TileEntityMachineIntake;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.item.Item;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.client.IItemRenderer;
public class RenderIntake extends TileEntitySpecialRenderer implements IItemRendererProvider {
@Override
public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f) {
GL11.glPushMatrix();
GL11.glTranslated(x + 0.5D, y, z + 0.5D);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_CULL_FACE);
switch(tileEntity.getBlockMetadata() - 10) {
case 2: GL11.glRotatef(90, 0F, 1F, 0F); break;
case 4: GL11.glRotatef(180, 0F, 1F, 0F); break;
case 3: GL11.glRotatef(270, 0F, 1F, 0F); break;
case 5: GL11.glRotatef(0, 0F, 1F, 0F); break;
}
GL11.glTranslated(-0.5, 0, 0.5);
TileEntityMachineIntake compressor = (TileEntityMachineIntake) tileEntity;
bindTexture(ResourceManager.intake_tex);
ResourceManager.intake.renderPart("Base");
float rot = compressor.prevFan + (compressor.fan - compressor.prevFan) * f;
GL11.glPushMatrix();
GL11.glTranslated(0, 0, 0);
GL11.glRotatef(-rot, 0, 1, 0);
GL11.glTranslated(0, 0, 0);
ResourceManager.intake.renderPart("Fan");
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glPopMatrix();
}
@Override
public Item getItemForRenderer() {
return Item.getItemFromBlock(ModBlocks.machine_intake);
}
@Override
public IItemRenderer getRenderer() {
return new ItemRenderBase( ) {
public void renderInventory() {
GL11.glScaled(5, 5, 5);
}
public void renderCommon() {
bindTexture(ResourceManager.intake_tex); ResourceManager.intake.renderAll();
}
};
}
}

View File

@ -61,6 +61,10 @@ public class GaugeUtil {
}
public static void drawSmoothGauge(int x, int y, double z, double progress, double tipLength, double backLength, double backSide, int color) {
drawSmoothGauge(x, y, z, progress, tipLength, backLength, backSide, color, 0x000000);
}
public static void drawSmoothGauge(int x, int y, double z, double progress, double tipLength, double backLength, double backSide, int color, int colorOuter) {
GL11.glDisable(GL11.GL_TEXTURE_2D);
progress = MathHelper.clamp_double(progress, 0, 1);
@ -76,7 +80,7 @@ public class GaugeUtil {
Tessellator tess = Tessellator.instance;
tess.startDrawing(GL11.GL_TRIANGLES);
tess.setColorOpaque_F(0F, 0F, 0F);
tess.setColorOpaque_I(colorOuter);
double mult = 1.5;
tess.addVertex(x + tip.xCoord * mult, y + tip.yCoord * mult, z);
tess.addVertex(x + left.xCoord * mult, y + left.yCoord * mult, z);

View File

@ -330,6 +330,7 @@ public class TileMappings {
put(TileEntityDeuteriumTower.class, "tileentity_deuterium_tower");
put(TileEntityMachineLiquefactor.class, "tileentity_liquefactor");
put(TileEntityMachineSolidifier.class, "tileentity_solidifier");
put(TileEntityMachineIntake.class, "tileentity_intake");
put(TileEntityMachineCompressor.class, "tileentity_compressor");
put(TileEntityMachineCompressorCompact.class, "tileentity_compressor_compact");
put(TileEntityElectrolyser.class, "tileentity_electrolyser");

View File

@ -19,7 +19,7 @@ public class TileEntityMachineCompressorCompact extends TileEntityMachineCompres
this.prevFanSpin = this.fanSpin;
if(this.isOn) {
this.fanSpin += 15;
this.fanSpin += 45;
if(this.fanSpin >= 360) {
this.prevFanSpin -= 360;

View File

@ -0,0 +1,141 @@
package com.hbm.tileentity.machine;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.inventory.fluid.tank.FluidTank;
import com.hbm.tileentity.TileEntityLoadedBase;
import com.hbm.util.fauxpointtwelve.DirPos;
import api.hbm.energymk2.IEnergyReceiverMK2;
import api.hbm.fluidmk2.IFluidStandardSenderMK2;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.ForgeDirection;
public class TileEntityMachineIntake extends TileEntityLoadedBase implements IEnergyReceiverMK2, IFluidStandardSenderMK2 {
public FluidTank compair;
public long power;
public float fan = 0;
public float prevFan = 0;
public TileEntityMachineIntake() {
this.compair = new FluidTank(Fluids.AIR, 1_000);
}
@Override
public void updateEntity() {
if(!worldObj.isRemote) {
if(this.power >= this.getMaxPower() / 20) {
this.compair.setFill(this.compair.getMaxFill());
this.power -= this.getMaxPower() / 20;
}
for(DirPos pos : getConPos()) {
if(this.compair.getFill() > 0) this.tryProvide(compair, worldObj, pos);
this.trySubscribe(worldObj, pos);
}
this.networkPackNT(50);
} else {
this.prevFan = this.fan;
if(this.power >= this.getMaxPower() / 20) {
this.fan += 45;
if(this.fan >= 360) {
this.fan -= 360;
this.prevFan -= 360;
}
}
}
}
public DirPos[] getConPos() {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10);
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
return new DirPos[] {
new DirPos(xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ, dir),
new DirPos(xCoord + dir.offsetX + rot.offsetX, yCoord, zCoord + dir.offsetZ + rot.offsetZ, dir),
new DirPos(xCoord - dir.offsetX * 2, yCoord, zCoord - dir.offsetZ * 2, dir.getOpposite()),
new DirPos(xCoord - dir.offsetX * 2 + rot.offsetX, yCoord, zCoord - dir.offsetZ * 2 + rot.offsetZ, dir.getOpposite()),
new DirPos(xCoord + rot.offsetX * 2, yCoord, zCoord + rot.offsetZ * 2, rot),
new DirPos(xCoord + rot.offsetX * 2 - dir.offsetX, yCoord, zCoord + rot.offsetZ * 2 - dir.offsetZ, rot),
new DirPos(xCoord - rot.offsetX, yCoord, zCoord - rot.offsetZ, rot.getOpposite()),
new DirPos(xCoord - rot.offsetX - dir.offsetX, yCoord, zCoord - rot.offsetZ - dir.offsetZ, rot.getOpposite())
};
}
@Override
public void serialize(ByteBuf buf) {
super.serialize(buf);
buf.writeLong(power);
compair.serialize(buf);
}
@Override
public void deserialize(ByteBuf buf) {
super.deserialize(buf);
this.power = buf.readLong();
compair.deserialize(buf);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
this.power = nbt.getLong("power");
compair.readFromNBT(nbt, "compair");
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
nbt.setLong("power", power);
compair.writeToNBT(nbt, "compair");
}
@Override public boolean canConnect(ForgeDirection dir) { return dir != ForgeDirection.UP && dir != ForgeDirection.DOWN; }
@Override public boolean canConnect(FluidType type, ForgeDirection dir) { return type == Fluids.AIR && dir != ForgeDirection.UP && dir != ForgeDirection.DOWN; }
@Override public void setPower(long i) { power = i; }
@Override public long getPower() { return power; }
@Override public long getMaxPower() { return 2_000; }
@Override public FluidTank[] getAllTanks() { return new FluidTank[] {compair}; }
@Override public FluidTank[] getSendingTanks() { return new FluidTank[] {compair}; }
AxisAlignedBB bb = null;
@Override
public AxisAlignedBB getRenderBoundingBox() {
if(bb == null) {
bb = AxisAlignedBB.getBoundingBox(
xCoord - 1,
yCoord,
zCoord - 1,
xCoord + 2,
yCoord + 1,
zCoord + 2
);
}
return bb;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared() {
return 65536.0D;
}
}

View File

@ -126,10 +126,12 @@ public class TileEntityCraneRouter extends TileEntityMachineBase implements IGUI
public boolean hasPermission(EntityPlayer player) {
return Vec3.createVectorHelper(xCoord - player.posX, yCoord - player.posY, zCoord - player.posZ).lengthVector() < 20;
}
@Override
public int[] getFilterSlots() {
return new int[]{0, slots.length};
}
@Override
public void receiveControl(NBTTagCompound data) {
if(data.hasKey("toggle")) {

View File

@ -1,34 +1,57 @@
package com.hbm.tileentity.network;
import com.hbm.inventory.container.ContainerPneumoTube;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.inventory.fluid.tank.FluidTank;
import com.hbm.inventory.gui.GUIPneumoTube;
import com.hbm.lib.Library;
import com.hbm.module.ModulePatternMatcher;
import com.hbm.tileentity.IControlReceiverFilter;
import com.hbm.tileentity.IGUIProvider;
import com.hbm.tileentity.TileEntityMachineBase;
import com.hbm.uninos.GenNode;
import com.hbm.uninos.UniNodespace;
import com.hbm.uninos.networkproviders.PneumaticNetwork;
import com.hbm.uninos.networkproviders.PneumaticNetworkProvider;
import com.hbm.util.Compat;
import com.hbm.util.EnumUtil;
import com.hbm.util.fauxpointtwelve.BlockPos;
import com.hbm.util.fauxpointtwelve.DirPos;
import api.hbm.fluidmk2.IFluidStandardReceiverMK2;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIProvider {
public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIProvider, IFluidStandardReceiverMK2, IControlReceiverFilter {
public ModulePatternMatcher pattern = new ModulePatternMatcher(15);
public ForgeDirection insertionDir = ForgeDirection.UNKNOWN;
public ForgeDirection ejectionDir = ForgeDirection.UNKNOWN;
public boolean whitelist = false;
public boolean redstone = false;
public byte sendOrder = 0;
public byte receiveOrder = 0;
public int soundDelay = 0;
public FluidTank compair;
protected PneumaticNode node;
public TileEntityPneumoTube() {
super(15);
this.compair = new FluidTank(Fluids.AIR, 4_000).withPressure(1);
@ -38,19 +61,125 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP
public String getName() {
return "container.pneumoTube";
}
public boolean matchesFilter(ItemStack stack) {
for(int i = 0; i < 15; i++) {
ItemStack filter = slots[i];
if(filter != null && this.pattern.isValidForFilter(filter, i, stack)) {
return true;
}
}
return false;
}
@Override
public void updateEntity() {
if(!worldObj.isRemote) {
if(this.soundDelay > 0) this.soundDelay--;
if(this.node == null || this.node.expired) {
this.node = (PneumaticNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, PneumaticNetworkProvider.THE_PROVIDER);
if(this.node == null || this.node.expired) {
this.node = (PneumaticNode) new PneumaticNode(new BlockPos(xCoord, yCoord, zCoord)).setConnections(
new DirPos(xCoord + 1, yCoord, zCoord, Library.POS_X),
new DirPos(xCoord - 1, yCoord, zCoord, Library.NEG_X),
new DirPos(xCoord, yCoord + 1, zCoord, Library.POS_Y),
new DirPos(xCoord, yCoord - 1, zCoord, Library.NEG_Y),
new DirPos(xCoord, yCoord, zCoord + 1, Library.POS_Z),
new DirPos(xCoord, yCoord, zCoord - 1, Library.NEG_Z)
);
UniNodespace.createNode(worldObj, this.node);
}
}
if(this.isCompressor() && (!this.worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord) ^ this.redstone)) {
int randTime = Math.abs((int) (worldObj.getTotalWorldTime() + this.getIdentifier(xCoord, yCoord, zCoord)));
if(worldObj.getTotalWorldTime() % 10 == 0) for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
if(dir != this.insertionDir && dir != this.ejectionDir) {
this.trySubscribe(compair.getTankType(), worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, dir);
}
}
if(randTime % 5 == 0 && this.node != null && !this.node.expired && this.node.net != null && this.compair.getFill() >= 50) {
TileEntity sendFrom = Compat.getTileStandard(worldObj, xCoord + insertionDir.offsetX, yCoord + insertionDir.offsetY, zCoord + insertionDir.offsetZ);
if(sendFrom instanceof IInventory) {
PneumaticNetwork net = node.net;
if(net.send((IInventory) sendFrom, this, this.insertionDir.getOpposite(), sendOrder, receiveOrder, getRangeFromPressure(compair.getPressure()))) {
this.compair.setFill(this.compair.getFill() - 50);
if(this.soundDelay <= 0 && !this.muffled) {
worldObj.playSoundEffect(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, "hbm:weapon.reload.tubeFwoomp", 0.25F, 0.9F + worldObj.rand.nextFloat() * 0.2F);
this.soundDelay = 20;
}
}
}
}
}
if(this.isEndpoint() && this.node != null && this.node.net != null && worldObj.getTotalWorldTime() % 10 == 0) {
TileEntity tile = Compat.getTileStandard(worldObj, xCoord + this.ejectionDir.offsetX, yCoord + this.ejectionDir.offsetY, zCoord + this.ejectionDir.offsetZ);
if(tile instanceof IInventory) this.node.net.addReceiver((IInventory) tile, this.ejectionDir);
}
this.networkPackNT(15);
}
}
public static int getRangeFromPressure(int pressure) {
if(pressure == 0) return 0;
if(pressure == 1) return 10;
if(pressure == 2) return 25;
if(pressure == 3) return 100;
if(pressure == 4) return 250;
if(pressure == 5) return 1_000;
return 0;
}
// tactfully copy pasted from BlockPos
public static int getIdentifier(int x, int y, int z) {
return (y + z * 27644437) * 27644437 + x;
}
@Override
public long getReceiverSpeed(FluidType type, int pressure) {
return MathHelper.clamp_int((this.compair.getMaxFill() - this.compair.getFill()) / 25, 1, 100);
}
@Override
public boolean canConnect(FluidType type, ForgeDirection dir) {
return dir != this.insertionDir && dir != this.ejectionDir && type == Fluids.AIR;
}
@Override
public void invalidate() {
super.invalidate();
if(!worldObj.isRemote) {
if(this.node != null) {
UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, PneumaticNetworkProvider.THE_PROVIDER);
}
}
}
public boolean isCompressor() { return this.insertionDir != ForgeDirection.UNKNOWN; }
public boolean isEndpoint() { return this.ejectionDir != ForgeDirection.UNKNOWN; }
@Override
public void serialize(ByteBuf buf) {
super.serialize(buf);
buf.writeBoolean(redstone);
buf.writeBoolean(whitelist);
buf.writeByte(sendOrder);
buf.writeByte(receiveOrder);
pattern.serialize(buf);
compair.serialize(buf);
}
@ -58,6 +187,10 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP
@Override
public void deserialize(ByteBuf buf) {
super.deserialize(buf);
this.redstone = buf.readBoolean();
this.whitelist = buf.readBoolean();
this.sendOrder = buf.readByte();
this.receiveOrder = buf.readByte();
pattern.deserialize(buf);
compair.deserialize(buf);
}
@ -83,7 +216,7 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP
NBTTagCompound nbt = pkt.func_148857_g();
this.insertionDir = EnumUtil.grabEnumSafely(ForgeDirection.class, nbt.getByte("insertionDir"));
this.ejectionDir = EnumUtil.grabEnumSafely(ForgeDirection.class, nbt.getByte("ejectionDir"));
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); // that's right, we're gonna cheat
}
@Override
@ -93,6 +226,9 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP
this.ejectionDir = EnumUtil.grabEnumSafely(ForgeDirection.class, nbt.getByte("ejectionDir"));
this.compair.readFromNBT(nbt, "tank");
this.pattern.readFromNBT(nbt);
this.whitelist = nbt.getBoolean("whitelist");
this.redstone = nbt.getBoolean("redstone");
}
@Override
@ -102,6 +238,9 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP
nbt.setByte("ejectionDir", (byte) ejectionDir.ordinal());
this.compair.writeToNBT(nbt, "tank");
this.pattern.writeToNBT(nbt);
nbt.setBoolean("whitelist", whitelist);
nbt.setBoolean("redstone", redstone);
}
@Override
@ -112,6 +251,44 @@ public class TileEntityPneumoTube extends TileEntityMachineBase implements IGUIP
@Override
@SideOnly(Side.CLIENT)
public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) {
return null;
return new GUIPneumoTube(player.inventory, this);
}
@Override
public void receiveControl(NBTTagCompound data) {
if(data.hasKey("whitelist")) {
this.whitelist = !this.whitelist;
}
if(data.hasKey("redstone")) {
this.redstone = !this.redstone;
}
if(data.hasKey("pressure")) {
int pressure = this.compair.getPressure() + 1;
if(pressure > 5) pressure = 1;
this.compair.withPressure(pressure);
}
if(data.hasKey("send")) {
this.sendOrder++;
if(this.sendOrder > 2) this.sendOrder = 0;
}
if(data.hasKey("receive")) {
this.receiveOrder++;
if(this.receiveOrder > 1) this.receiveOrder = 0;
}
this.markDirty();
}
@Override public boolean hasPermission(EntityPlayer player) { return this.isUseableByPlayer(player); }
@Override public int[] getFilterSlots() { return new int[] {0, 15}; }
@Override public FluidTank[] getAllTanks() { return new FluidTank[] {compair}; }
@Override public FluidTank[] getReceivingTanks() { return new FluidTank[] {compair}; }
public static class PneumaticNode extends GenNode<PneumaticNetwork> {
public PneumaticNode(BlockPos... positions) {
super(PneumaticNetworkProvider.THE_PROVIDER, positions);
}
}
}

View File

@ -0,0 +1,209 @@
package com.hbm.uninos.networkproviders;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import com.hbm.tileentity.network.TileEntityPneumoTube;
import com.hbm.uninos.NodeNet;
import com.hbm.util.BobMathUtil;
import com.hbm.util.ItemStackUtil;
import com.hbm.util.Tuple.Pair;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraftforge.common.util.ForgeDirection;
public class PneumaticNetwork extends NodeNet {
public static final byte SEND_FIRST = 0;
public static final byte SEND_LAST = 1;
public static final byte SEND_RANDOM = 2;
public static final byte RECEIVE_ROBIN = 0;
public static final byte RECEIVE_RANDOM = 1;
public Random rand = new Random();
public int nextReceiver = 0;
protected static final int timeout = 1_000;
public static final int ITEMS_PER_TRANSFER = 64;
// while the system has parts that expects IInventires to be TileEntities to work properly (mostly range checks),
// it can actually handle non-TileEntities just fine.
public HashMap<IInventory, Pair<ForgeDirection, Long>> receivers = new HashMap();
public void addReceiver(IInventory inventory, ForgeDirection pipeDir) {
receivers.put(inventory, new Pair(pipeDir, System.currentTimeMillis()));
}
@Override public void update() {
// weeds out invalid targets
// technically not necessary since that step is taken during the send operation,
// but we still want to reap garbage data that would otherwise accumulate
long timestamp = System.currentTimeMillis();
receivers.entrySet().removeIf(x -> { return (timestamp - x.getValue().getValue() > timeout) || NodeNet.isBadLink(x.getKey()); });
}
public boolean send(IInventory source, TileEntityPneumoTube tube, ForgeDirection accessDir, int sendOrder, int receiveOrder, int maxRange) {
// turns out there may be a short time window where the cleanup hasn't happened yet, but chunkloading has already caused tiles to go invalid
// so we just run it again here, just to be sure.
long timestamp = System.currentTimeMillis();
receivers.entrySet().removeIf(x -> { return (timestamp - x.getValue().getValue() > timeout) || NodeNet.isBadLink(x.getKey()); });
if(receivers.isEmpty()) return false;
int sourceSide = accessDir.ordinal();
int[] sourceSlotAccess = getSlotAccess(source, sourceSide);
if(sendOrder == SEND_LAST) BobMathUtil.reverseIntArray(sourceSlotAccess);
if(sendOrder == SEND_RANDOM) BobMathUtil.shuffleIntArray(sourceSlotAccess);
// for round robin, receivers are ordered by proximity to the source
ReceiverComparator comparator = new ReceiverComparator(tube);
List<Entry<IInventory, Pair<ForgeDirection, Long>>> receiverList = new ArrayList(receivers.size());
receiverList.addAll(receivers.entrySet());
receiverList.sort(comparator);
int index = nextReceiver % receivers.size();
Entry<IInventory, Pair<ForgeDirection, Long>> chosenReceiverEntry = null;
if(receiveOrder == RECEIVE_ROBIN) chosenReceiverEntry = receiverList.get(index);
if(receiveOrder == RECEIVE_RANDOM) chosenReceiverEntry = receiverList.get(rand.nextInt(receiverList.size()));
if(chosenReceiverEntry == null) return false;
IInventory dest = chosenReceiverEntry.getKey();
ISidedInventory sidedDest = dest instanceof ISidedInventory ? (ISidedInventory) dest : null;
ISidedInventory sidedSource = source instanceof ISidedInventory ? (ISidedInventory) source : null;
TileEntity tile1 = source instanceof TileEntity ? (TileEntity) source : null;
TileEntity tile2 = dest instanceof TileEntity ? (TileEntity) dest : null;
// range check for our compression level, skip if either source or dest aren't tile entities
if(tile1 != null && tile2 != null) {
int sq = (tile1.xCoord - tile2.xCoord) * (tile1.xCoord - tile2.xCoord) + (tile1.yCoord - tile2.yCoord) * (tile1.yCoord - tile2.yCoord) + (tile1.zCoord - tile2.zCoord) * (tile1.zCoord - tile2.zCoord);
if(sq > maxRange * maxRange) {
nextReceiver++;
return false;
}
}
int destSide = chosenReceiverEntry.getValue().getKey().getOpposite().ordinal();
int[] destSlotAccess = getSlotAccess(dest, destSide);
int itemsLeftToSend = ITEMS_PER_TRANSFER; // not actually individual items, but rather the total "mass", based on max stack size
boolean didSomething = false;
for(int sourceIndex : sourceSlotAccess) {
ItemStack sourceStack = source.getStackInSlot(sourceIndex);
if(sourceStack == null) continue;
if(sidedSource != null && !sidedSource.canExtractItem(sourceIndex, sourceStack, sourceSide)) continue;
boolean match = tube.matchesFilter(sourceStack);
if((match && !tube.whitelist) || (!match && tube.whitelist)) continue;
// the "mass" of an item. something that only stacks to 4 has a "mass" of 16. max transfer mass is 64, i.e. one standard stack, or one single unstackable item
int proportionalValue = MathHelper.clamp_int(64 / sourceStack.getMaxStackSize(), 1, 64);
// try to fill partial stacks first
for(int destIndex : destSlotAccess) {
ItemStack destStack = dest.getStackInSlot(destIndex);
if(destStack == null) continue;
if(!dest.isItemValidForSlot(destIndex, sourceStack)) continue;
if(sidedDest != null && !sidedDest.canInsertItem(destIndex, sourceStack, destSide)) continue;
if(!ItemStackUtil.areStacksCompatible(sourceStack, destStack)) continue;
int toMove = BobMathUtil.min(sourceStack.stackSize, destStack.getMaxStackSize() - destStack.stackSize, dest.getInventoryStackLimit() - destStack.stackSize, itemsLeftToSend / proportionalValue);
if(toMove <= 0) continue;
sourceStack.stackSize -= toMove;
if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null);
destStack.stackSize += toMove;
itemsLeftToSend -= toMove * proportionalValue;
didSomething = true;
if(itemsLeftToSend <= 0) break;
}
// if there's stuff left to send, occupy empty slots
if(itemsLeftToSend > 0 && sourceStack.stackSize > 0) for(int destIndex : destSlotAccess) {
if(dest.getStackInSlot(destIndex) != null) continue;
if(!dest.isItemValidForSlot(destIndex, sourceStack)) continue;
if(sidedDest != null && !sidedDest.canInsertItem(destIndex, sourceStack, destSide)) continue;
int toMove = BobMathUtil.min(sourceStack.stackSize, dest.getInventoryStackLimit(), itemsLeftToSend / proportionalValue);
if(toMove <= 0) continue;
ItemStack newStack = sourceStack.copy();
newStack.stackSize = toMove;
sourceStack.stackSize -= toMove;
if(sourceStack.stackSize <= 0) source.setInventorySlotContents(sourceIndex, null);
dest.setInventorySlotContents(destIndex, newStack);
itemsLeftToSend -= toMove * proportionalValue;
didSomething = true;
break;
}
if(itemsLeftToSend <= 0) break;
}
// make sure both parties are saved to disk and increment the counter for round robin
if(didSomething) {
nextReceiver++;
source.markDirty();
dest.markDirty();
}
return didSomething;
}
/** Returns an array of accessible slots from the given side of an IInventory. If it's an ISidedInventory, uses the sided restrictions instead. */
public static int[] getSlotAccess(IInventory inventory, int dir) {
if(inventory instanceof ISidedInventory) {
int[] slotAccess = ((ISidedInventory) inventory).getAccessibleSlotsFromSide(dir);
return Arrays.copyOf(slotAccess, slotAccess.length); //we mess with the order, so better not use the original array
} else {
int[] slotAccess = new int[inventory.getSizeInventory()];
for(int i = 0; i < inventory.getSizeInventory(); i++) slotAccess[i] = i;
return slotAccess;
}
}
/** Compares IInventory by distance, going off the assumption that they are TileEntities. Uses positional data for tie-breaking if the distance is the same. */
public static class ReceiverComparator implements Comparator<Entry<IInventory, Pair<ForgeDirection, Long>>> {
private TileEntityPneumoTube origin;
public ReceiverComparator(TileEntityPneumoTube origin) {
this.origin = origin;
}
@Override
public int compare(Entry<IInventory, Pair<ForgeDirection, Long>> o1, Entry<IInventory, Pair<ForgeDirection, Long>> o2) {
TileEntity tile1 = o1.getKey() instanceof TileEntity ? (TileEntity) o1.getKey() : null;
TileEntity tile2 = o2.getKey() instanceof TileEntity ? (TileEntity) o2.getKey() : null;
// prioritize actual TileEntities
if(tile1 == null && tile2 != null) return 1;
if(tile1 != null && tile2 == null) return -1;
if(tile1 == null && tile2 == null) return 0;
// calculate distances from origin
int dist1 = (tile1.xCoord - origin.xCoord) * (tile1.xCoord - origin.xCoord) + (tile1.yCoord - origin.yCoord) * (tile1.yCoord - origin.yCoord) + (tile1.zCoord - origin.zCoord) * (tile1.zCoord - origin.zCoord);
int dist2 = (tile2.xCoord - origin.xCoord) * (tile2.xCoord - origin.xCoord) + (tile2.yCoord - origin.yCoord) * (tile2.yCoord - origin.yCoord) + (tile2.zCoord - origin.zCoord) * (tile2.zCoord - origin.zCoord);
// tier-breaker: use hash value instead
if(dist1 == dist2) {
return TileEntityPneumoTube.getIdentifier(tile1.xCoord, tile1.yCoord, tile1.zCoord) - TileEntityPneumoTube.getIdentifier(tile2.xCoord, tile2.yCoord, tile2.zCoord);
}
// no tie? return difference of the distances
return dist1 - dist2;
}
}
}

View File

@ -0,0 +1,13 @@
package com.hbm.uninos.networkproviders;
import com.hbm.uninos.INetworkProvider;
public class PneumaticNetworkProvider implements INetworkProvider<PneumaticNetwork>{
public static PneumaticNetworkProvider THE_PROVIDER = new PneumaticNetworkProvider();
@Override
public PneumaticNetwork provideNetwork() {
return new PneumaticNetwork();
}
}

View File

@ -260,7 +260,26 @@ public class BobMathUtil {
public static int[] collectionToIntArray(Collection<? extends Object> in, ToIntFunction<? super Object> mapper) {
return Arrays.stream(in.toArray()).mapToInt(mapper).toArray();
}
}
public static void shuffleIntArray(int[] array) {
Random rand = new Random();
for(int i = array.length - 1; i > 0; i--) {
int r = rand.nextInt(i + 1);
int temp = array[r];
array[r] = array[i];
array[i] = temp;
}
}
public static void reverseIntArray(int[] array) {
int len = array.length;
for(int i = 0; i < len / 2; i++) {
int temp = array[i];
array[i] = array[len - 1 - i];
array[len - 1 - i] = temp;
}
}
/** Soft peak sine */
public static double sps(double x) {

View File

@ -66,7 +66,7 @@ public class DamageResistanceHandler {
if(!config.exists()) {
initDefaults();
writeDefault(template);
//writeDefault(template);
} else {
///
}

View File

@ -198,4 +198,8 @@ public class ItemStackUtil {
world.func_147453_f(x, y, z, block);
}
}
public static boolean areStacksCompatible(ItemStack sta1, ItemStack sta2) {
return sta1.getItem() == sta2.getItem() && sta1.getItemDamage() == sta2.getItemDamage() && ItemStack.areItemStackTagsEqual(sta1, sta2);
}
}

View File

@ -410,6 +410,7 @@ container.paDipole=Dipol
container.paQuadrupole=Quad.
container.paSource=Teilchenquelle
container.plasmaHeater=Plasmaerhitzer
container.pneumoTube=Rohrpost
container.press=Befeuerte Presse
container.puf6_tank=PuF6 Tank
container.pumpjack=Pferdekopfpumpe
@ -702,6 +703,7 @@ hbm.key.toggleHUD=HUD umschalten
hbm.key.trainInv=Zug-Inventar
hbm.key.reload=Nachladen
hbmfluid.air=Druckluft
hbmfluid.amat=Antimaterie
hbmfluid.aromatics=Aromatische Kohlenwasserstoffe
hbmfluid.aschrab=Antischrabidium
@ -4524,6 +4526,7 @@ tile.machine_icf_press.name=ICF-Brennstoffpellet-Fabrikant
tile.machine_industrial_boiler.name=Industrieller Boiler
tile.machine_industrial_boiler.desc=Großer Boiler zum Verdampfen von Wasser oder$Erhitzen von Öl. Benötigt externe Hitzequelle.$Wärmestransferrate: ΔT*0.01 TU/t$Überdrucksicher
tile.machine_industrial_generator.name=Industrieller Generator
tile.machine_intake.name=Lufteinlass
tile.machine_keyforge.name=Schlossertisch
tile.machine_large_turbine.name=Industrielle Dampfturbine
tile.machine_large_turbine.desc=Effizienz: 100%%
@ -4755,6 +4758,8 @@ tile.plant_tall.weed.name=Hanf
tile.plasma.name=Plasma
tile.plasma_heater.name=Plasmaerhitzer
tile.plushie.name=%s Plüschfigur
tile.pneumatic_tube.name=Rohrpost
tile.pneumatic_tube.desc=Sendted Items mit Druckluft.$Rechtsklick mit Schraubenzieher aktiviert den Eingang.$Shift-Rechtskick mit Schrabuenzieher aktiviert den Ausgang.$Eingänge können konfiguriert und mit Druckluft verbunden werden.$Sendet bis zu einem Stack, vier Mal pro Sekunde.
tile.pole_satellite_receiver.name=Satellitenschüssel
tile.pole_top.name=Antennenspitze
tile.press_preheater.name=Presse-Vorheizer

View File

@ -813,6 +813,7 @@ container.paDipole=Dipole
container.paQuadrupole=Quad.
container.paSource=Particle Source
container.plasmaHeater=Plasma Heater
container.pneumoTube=Pneumatic Tube
container.press=Burner Press
container.puf6_tank=PuF6 Tank
container.pumpjack=Pumpjack
@ -1410,6 +1411,7 @@ hbm.key.toggleHUD=Toggle HUD
hbm.key.trainInv=Train Inventory
hbm.key.reload=Reload
hbmfluid.air=Compressed Air
hbmfluid.alumina=Alumina
hbmfluid.amat=Antimatter
hbmfluid.aromatics=Aromatic Hydrocarbons
@ -5658,6 +5660,7 @@ tile.machine_icf_press.desc=Fills ICF Fuel pellets$Left fuel slot is accepted by
tile.machine_industrial_boiler.name=Industrial Boiler
tile.machine_industrial_boiler.desc=Large boiler that can boil water or heat up oil.$Requires external heat source.$Heat transfer rate: ΔT*0.01 TU/t$Cannot explode
tile.machine_industrial_generator.name=Industrial Generator
tile.machine_intake.name=Air Intake
tile.machine_keyforge.name=Locksmith Table
tile.machine_large_turbine.name=Industrial Steam Turbine
tile.machine_large_turbine.desc=Efficiency: 100%%
@ -5901,6 +5904,8 @@ tile.plant_tall.weed.name=Hemp
tile.plasma.name=Plasma
tile.plasma_heater.name=Plasma Heater
tile.plushie.name=%s Plushie
tile.pneumatic_tube.name=Pneumatic Tube
tile.pneumatic_tube.desc=Sends items using compressed air.$Right-click with screwdriver to toggle an input.$Shift right-click with screwdriver to toggle an output.$Inputs can be configured, and connected to compressed air.$Sends up to one stack, four times per second.
tile.pole_satellite_receiver.name=Satellite Dish
tile.pole_top.name=Antenna Top
tile.press_preheater.name=Burner Press Preheater

View File

@ -0,0 +1,230 @@
# Blender v2.79 (sub 0) OBJ File: 'intake.blend'
# www.blender.org
o Fan
v 0.000000 0.750000 -0.125000
v -0.108253 0.750000 -0.062500
v -0.108253 0.750000 0.062500
v 0.000000 0.750000 0.125000
v 0.108253 0.750000 0.062500
v 0.108253 0.750000 -0.062500
v 0.000000 0.875000 -0.125000
v -0.108253 0.875000 -0.062500
v -0.108253 0.875000 0.062500
v 0.000000 0.875000 0.125000
v 0.108253 0.875000 0.062500
v 0.108253 0.875000 -0.062500
v -0.108253 0.828676 -0.060370
v -0.108253 0.796324 0.060370
v -0.541266 0.873161 -0.226389
v -0.541266 0.751839 0.226389
v 0.001844 0.828676 0.123935
v 0.106409 0.796324 0.063565
v 0.074575 0.873161 0.581944
v 0.466691 0.751839 0.355556
v 0.106409 0.828676 -0.063565
v 0.001844 0.796324 -0.123935
v 0.466691 0.873161 -0.355556
v 0.074574 0.751839 -0.581944
vt 0.869565 -0.000000
vt 0.826087 0.025641
vt 0.826087 -0.000000
vt 0.739130 -0.000000
vt 0.695652 0.025641
vt 0.695652 -0.000000
vt 0.913043 -0.000000
vt 0.869565 0.025641
vt 0.782609 0.025641
vt 0.782609 -0.000000
vt 0.739130 0.025641
vt 0.956522 -0.000000
vt 0.913043 0.025641
vt 0.761043 0.028899
vt 0.782956 0.051282
vt 0.717218 0.073665
vt 0.956522 0.128205
vt 0.847826 0.025641
vt 0.891304 0.025641
vt 0.891304 0.025641
vt 0.782609 0.128205
vt 0.847826 0.025641
vt 0.891304 0.025641
vt 0.782609 0.128205
vt 0.847826 0.025641
vt 0.956522 0.025641
vt 0.761043 0.073665
vt 0.695305 0.051282
vt 0.717218 0.028899
vt 0.782609 0.128205
vt 0.956522 0.128205
vt 0.956522 0.128205
vn -1.0000 0.0000 0.0000
vn 1.0000 0.0000 0.0000
vn -0.5000 0.0000 0.8660
vn -0.5000 0.0000 -0.8660
vn 0.5000 0.0000 -0.8660
vn 0.5000 0.0000 0.8660
vn 0.0000 1.0000 -0.0000
vn -0.0000 0.9659 0.2588
vn 0.2241 0.9659 -0.1294
vn -0.2241 0.9659 -0.1294
s off
f 3/1/1 8/2/1 2/3/1
f 6/4/2 11/5/2 5/6/2
f 4/7/3 9/8/3 3/1/3
f 2/3/4 7/9/4 1/10/4
f 1/10/5 12/11/5 6/4/5
f 5/12/6 10/13/6 4/7/6
f 12/14/7 7/15/7 9/16/7
f 15/17/8 14/18/8 13/19/8
f 17/20/9 20/21/9 18/22/9
f 21/23/10 24/24/10 22/25/10
f 3/1/1 9/8/1 8/2/1
f 6/4/2 12/11/2 11/5/2
f 4/7/3 10/13/3 9/8/3
f 2/3/4 8/2/4 7/9/4
f 1/10/5 7/9/5 12/11/5
f 5/12/6 11/26/6 10/13/6
f 7/15/7 8/27/7 9/16/7
f 9/16/7 10/28/7 11/29/7
f 11/29/7 12/14/7 9/16/7
f 15/17/8 16/30/8 14/18/8
f 17/20/9 19/31/9 20/21/9
f 21/23/10 23/32/10 24/24/10
o Base
v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v 1.000000 0.000000 -1.000000
v -0.875000 0.750000 0.875000
v 0.875000 0.750000 0.875000
v -0.875000 0.750000 -0.875000
v 0.875000 0.750000 -0.875000
v -1.000000 0.750000 -1.000000
v -1.000000 0.750000 1.000000
v 1.000000 0.750000 1.000000
v 1.000000 0.750000 -1.000000
v -0.625000 1.000000 -0.625000
v -0.625000 1.000000 0.625000
v 0.625000 1.000000 0.625000
v 0.625000 1.000000 -0.625000
v -0.875000 1.000000 -0.875000
v -0.875000 1.000000 0.875000
v 0.875000 1.000000 0.875000
v 0.875000 1.000000 -0.875000
v -0.625000 0.750000 -0.625000
v -0.625000 0.750000 0.625000
v 0.625000 0.750000 0.625000
v 0.625000 0.750000 -0.625000
v -0.625000 1.000000 -0.625000
v -0.625000 1.000000 0.625000
v 0.625000 1.000000 0.625000
v 0.625000 1.000000 -0.625000
vt 0.695652 -0.000000
vt -0.000000 0.410256
vt -0.000000 -0.000000
vt 0.652174 0.589744
vt 0.043478 0.641026
vt 0.043478 0.589744
vt 0.695652 0.410256
vt -0.000000 0.564103
vt -0.000000 0.410256
vt 0.695652 0.410256
vt -0.000000 0.564103
vt -0.000000 0.410256
vt 0.695652 0.410256
vt 0.000000 0.564103
vt 0.000000 0.410256
vt 0.695652 0.410256
vt -0.000000 0.564103
vt 0.043478 0.589744
vt 0.695652 0.564103
vt 0.652174 0.589744
vt 0.043478 0.589744
vt 0.695652 0.564103
vt 0.652174 0.589744
vt 0.695652 0.564103
vt 0.043478 0.589744
vt 0.695652 0.564103
vt 0.652174 0.589744
vt 0.565217 0.692308
vt 0.130435 0.743590
vt 0.130435 0.692308
vt 0.043478 0.641026
vt 0.043478 0.641026
vt 0.043478 0.641026
vt 0.130435 0.692308
vt 0.652174 0.641026
vt 0.565217 0.692308
vt 0.130435 0.692308
vt 0.652174 0.641026
vt 0.565217 0.692308
vt 0.652174 0.641026
vt 0.130435 0.692308
vt 0.652174 0.641026
vt 0.565217 0.692308
vt 0.565217 1.000000
vt 0.130435 1.000000
vt 0.130435 0.743590
vt 0.130435 0.743590
vt 0.130435 0.743590
vt 0.565217 0.743590
vt 1.000000 1.000000
vt 0.565217 1.000000
vt 0.565217 0.743590
vt 0.565217 0.743590
vt 0.565217 0.743590
vt 0.565217 0.743590
vt 1.000000 0.743590
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 1.0000 0.0000
s off
f 27/33/11 26/34/11 25/35/11
f 32/36/12 43/37/12 30/38/12
f 25/39/13 33/40/13 27/41/13
f 27/42/14 36/43/14 28/44/14
f 26/45/15 34/46/15 25/47/15
f 28/48/12 35/49/12 26/34/12
f 31/50/16 34/51/16 29/52/16
f 29/53/16 35/54/16 30/55/16
f 30/38/16 36/56/16 32/36/16
f 32/57/16 33/58/16 31/59/16
f 40/60/13 47/61/13 39/62/13
f 29/52/13 41/63/13 31/50/13
f 31/59/14 44/64/14 32/57/14
f 30/55/15 42/65/15 29/53/15
f 37/66/16 42/67/16 38/68/16
f 38/69/16 43/70/16 39/71/16
f 39/62/16 44/72/16 40/60/16
f 40/73/16 41/74/16 37/75/16
f 47/61/16 45/76/16 46/77/16
f 38/68/12 45/78/12 37/66/12
f 37/75/15 48/79/15 40/73/15
f 39/71/14 46/80/14 38/69/14
f 51/81/16 49/82/16 50/83/16
f 27/33/11 28/48/11 26/34/11
f 32/36/12 44/72/12 43/37/12
f 25/39/13 34/51/13 33/40/13
f 27/42/14 33/58/14 36/43/14
f 26/45/15 35/54/15 34/46/15
f 28/48/12 36/56/12 35/49/12
f 31/50/16 33/40/16 34/51/16
f 29/53/16 34/46/16 35/54/16
f 30/38/16 35/49/16 36/56/16
f 32/57/16 36/43/16 33/58/16
f 40/60/13 48/84/13 47/61/13
f 29/52/13 42/67/13 41/63/13
f 31/59/14 41/74/14 44/64/14
f 30/55/15 43/70/15 42/65/15
f 37/66/16 41/63/16 42/67/16
f 38/69/16 42/65/16 43/70/16
f 39/62/16 43/37/16 44/72/16
f 40/73/16 44/64/16 41/74/16
f 47/61/16 48/84/16 45/76/16
f 38/68/12 46/85/12 45/78/12
f 37/75/15 45/86/15 48/79/15
f 39/71/14 47/87/14 46/80/14
f 51/81/16 52/88/16 49/82/16

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 351 B

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B