Merge branch 'HbmMods:master' into master

This commit is contained in:
George Paton 2025-03-07 16:50:40 +11:00 committed by GitHub
commit df5253df1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
207 changed files with 1419 additions and 664 deletions

View File

@ -12,6 +12,7 @@
* NTM Reloaded: https://github.com/TheOriginalGolem/Hbm-s-Nuclear-Tech-GIT/releases
* NTM Extended Edition (Alcater): https://github.com/Alcatergit/Hbm-s-Nuclear-Tech-GIT/releases
* NTM WarFactory: https://github.com/MisterNorwood/Hbm-s-Nuclear-Tech-GIT/releases
For 1.18, try Martin's remake: https://codeberg.org/MartinTheDragon/Nuclear-Tech-Mod-Remake/releases

View File

@ -1,29 +1,29 @@
## Added
* A new legendary weapon
* `/ntmserver`
* Functions like `/ntmclient` but for common settings
* Can toggle `DAMAGE_COMPATIBILITY_MODE`, off by default, enables a more compatible (but slightly jankier) version of the bullet damage code
* `MINE_<xxx>_DAMAGE` can be used to adjust landmine damage
* `TAINT_TRAILS` now replaces the hardcore taint config option, making taint blocks more potent and the potion effect trail taint blocks
## Changed
* Updated russian localization
* Large deposits (hematite, malachite, bauxite) and caves (sulfur, asbestos) can now be toggled in the config
* Removed recipes for most old particle accelerator parts
* Dense coils no longer have recipes either for the most part, all coils with no recipes can be recycled back into dense wires
* Natural gas can now be processed in a pyrolysis oven, 12k of gas yields 8k hydrogen and one graphite ingot
* Saturnite now has an alternate recipe, adding one pile of borax for doubled output
* All mass storage units (except wood) are now substantially cheaper
* Reduced base spread for all 12 and 10 gauge buckshot shells from 0.05 to 0.035
* Reduced legendary 12 lever action's spread multiplier from x1.35 to x1.15
* Bullet casings now spawn with randomized angular velocity
* Bullet casings now correctly bounce off walls, and change angles when bouncing
* Two previously unobtainable legendaries are now in the red room loot pool (about 10x less common than most other items)
* Fat mines now use the standardized mini nuke code
* Fat mines now have a base damage of exactly 100, being identical to demolition mini nukes
* Fat mines now gib affected entities
* IV bags now use `setHealth` operations instead of dealing damage, preventing health duplication by just avoiding the damage
* The settings tool can now copy and paste the "paint" from paintable cables and fluid ducts
* Changed the way taint works
* Instead of neon purple vines, taint is bow a greyish sludge
* Taint now actively replaces blocks instead of growing along them
* Taint is still limited in spread, however taint spread is lower underground, taint decays three times faster in intensity if the block is not exposed to air, making taint spread more along the surface
* Taint has a 25% chance of splashing down when replacing a block with no supports, causing structures to collapse and taint to spread faster
* Similar to soil sand, entities will sink in taint and get slowed down
* The sludge consumeth
* `enableGuns` config option now applies to SEDNA system guns, simply canceling all gun-related keybinds
* Cinnabar dust, if registered by another mod, can now be acidized into cinnabar using hydrogen peroxide
* Copper wires, like AA and gold, can now be welded into dense wires
## Fixed
* Fixed an issue where `/ntmreload` would load fluids after recipes, meaning that recipes using newly added fluids would not work correctly, as the fluids don't exist by the time the recipe is loaded
* Fixed bedrock coltan being way too common, drowning out almost all other bedrock ores
* Fixed rotary furnace not saving its output stack
* Fixed strand caster water check being incorrect, creating negative water by allowing operations with insufficient cooling
* Fixed radar not using the small remaining amount of power, causing the animation getting stuck
* Fixed the new system structures being way too common
* Fixed RBMKs losing all their flux when reloading the world
* Fixed issue where DODD fuel item stats would only update when the GUI was open
* Fixed muzzle flashes not being fullbright
* Fixed guns having their name permanently visible over the toolbar
* Fixed hangman being absolutely gigantic when dropped
* Fixed animation error on the MAS-36
* Fixed drone docks, requester and provider crates not dropping their contents when broken
* Fixed all missing texture errors that appear in the startup log
* Potentially fixed a crash with mekanism during the recipe change phase

View File

@ -12,6 +12,7 @@ credits=HbMinecraft,\
\ MellowArpeggiation (new animation system, turbine sounds, sound fixes, industrial lights, better particle diodes),\
\ Pheo (textures, various machines, models, weapons),\
\ Vær (gas centrifuges, better worldgen, ZIRNOX, CP-1 parts, starter guide, new cyclotron, weapon animations),\
\ UFFR (RTG pellets, guns, casings, euphemium capacitor, nucleartech.wiki),\
\ LePeep (coilgun model, BDCL QC),\
\ Adam29 (liquid petroleum, ethanol, electric furnace),\
\ Pvndols (thorium fuel recipe, gas turbine),\
@ -33,7 +34,6 @@ credits=HbMinecraft,\
\ Maksymisio (polish localization)\
\ el3ctro4ndre (italian localization),\
\ Pu-238 (Tom impact effects),\
\ UFFR (RTG pellets, guns, casings, euphemium capacitor),\
\ Frooz (gun models),\
\ VT-6/24 (models, textures),\
\ Nos (models),\

View File

@ -3,7 +3,7 @@ package api.hbm.energymk2;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toclient.AuxParticlePacketNT;
import com.hbm.uninos.IGenProvider;
import com.hbm.uninos.networkproviders.PowerProvider;
import com.hbm.uninos.networkproviders.PowerNetProvider;
import com.hbm.util.Compat;
import api.hbm.energymk2.Nodespace.PowerNode;
@ -14,7 +14,7 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
/** If it sends energy, use this */
public interface IEnergyProviderMK2 extends IEnergyHandlerMK2, IGenProvider<PowerProvider> {
public interface IEnergyProviderMK2 extends IEnergyHandlerMK2, IGenProvider<PowerNetProvider> {
/** Uses up available power, default implementation has no sanity checking, make sure that the requested power is lequal to the current power */
public default void usePower(long power) {

View File

@ -4,7 +4,7 @@ import com.hbm.interfaces.NotableComments;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toclient.AuxParticlePacketNT;
import com.hbm.uninos.IGenReceiver;
import com.hbm.uninos.networkproviders.PowerProvider;
import com.hbm.uninos.networkproviders.PowerNetProvider;
import com.hbm.util.Compat;
import api.hbm.energymk2.Nodespace.PowerNode;
@ -16,7 +16,7 @@ import net.minecraftforge.common.util.ForgeDirection;
/** If it receives energy, use this */
@NotableComments
public interface IEnergyReceiverMK2 extends IEnergyHandlerMK2, IGenReceiver<PowerProvider> {
public interface IEnergyReceiverMK2 extends IEnergyHandlerMK2, IGenReceiver<PowerNetProvider> {
public default long transferPower(long power) {
if(power + this.getPower() <= this.getMaxPower()) {

View File

@ -3,7 +3,7 @@ package api.hbm.energymk2;
import com.hbm.interfaces.NotableComments;
import com.hbm.uninos.GenNode;
import com.hbm.uninos.UniNodespace;
import com.hbm.uninos.networkproviders.PowerProvider;
import com.hbm.uninos.networkproviders.PowerNetProvider;
import com.hbm.util.fauxpointtwelve.BlockPos;
import com.hbm.util.fauxpointtwelve.DirPos;
@ -18,7 +18,7 @@ import net.minecraft.world.World;
*/
public class Nodespace {
public static final PowerProvider THE_POWER_PROVIDER = new PowerProvider();
public static final PowerNetProvider THE_POWER_PROVIDER = new PowerNetProvider();
@Deprecated public static PowerNode getNode(World world, int x, int y, int z) {
return (PowerNode) UniNodespace.getNode(world, x, y, z, THE_POWER_PROVIDER);

View File

@ -0,0 +1,11 @@
package api.hbm.fluidmk2;
import com.hbm.uninos.NodeNet;
public class FluidNetMK2 extends NodeNet {
@Override
public void update() {
}
}

View File

@ -0,0 +1,19 @@
package api.hbm.fluidmk2;
import com.hbm.uninos.GenNode;
import com.hbm.uninos.INetworkProvider;
import com.hbm.util.fauxpointtwelve.BlockPos;
import com.hbm.util.fauxpointtwelve.DirPos;
public class FluidNode extends GenNode<FluidNetMK2> {
public FluidNode(INetworkProvider<FluidNetMK2> provider, BlockPos... positions) {
super(provider, positions);
}
@Override
public FluidNode setConnections(DirPos... connections) {
super.setConnections(connections);
return this;
}
}

View File

@ -0,0 +1,12 @@
package api.hbm.fluidmk2;
import com.hbm.inventory.fluid.FluidType;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
public interface IFluidConnectorBlockMK2 {
/** dir is the face that is connected to, the direction going outwards from the block */
public boolean canConnect(FluidType type, IBlockAccess world, int x, int y, int z, ForgeDirection dir);
}

View File

@ -0,0 +1,17 @@
package api.hbm.fluidmk2;
import com.hbm.inventory.fluid.FluidType;
import net.minecraftforge.common.util.ForgeDirection;
public interface IFluidConnectorMK2 {
/**
* Whether the given side can be connected to
* @param dir
* @return
*/
public default boolean canConnect(FluidType type, ForgeDirection dir) {
return dir != ForgeDirection.UNKNOWN;
}
}

View File

@ -0,0 +1,23 @@
package api.hbm.fluidmk2;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.lib.Library;
import com.hbm.util.fauxpointtwelve.BlockPos;
import com.hbm.util.fauxpointtwelve.DirPos;
import net.minecraft.tileentity.TileEntity;
public interface IFluidPipeMK2 {
public default FluidNode createNode(FluidType type) {
TileEntity tile = (TileEntity) this;
return new FluidNode(type.getNetworkProvider(), new BlockPos(tile.xCoord, tile.yCoord, tile.zCoord)).setConnections(
new DirPos(tile.xCoord + 1, tile.yCoord, tile.zCoord, Library.POS_X),
new DirPos(tile.xCoord - 1, tile.yCoord, tile.zCoord, Library.NEG_X),
new DirPos(tile.xCoord, tile.yCoord + 1, tile.zCoord, Library.POS_Y),
new DirPos(tile.xCoord, tile.yCoord - 1, tile.zCoord, Library.NEG_Y),
new DirPos(tile.xCoord, tile.yCoord, tile.zCoord + 1, Library.POS_Z),
new DirPos(tile.xCoord, tile.yCoord, tile.zCoord - 1, Library.NEG_Z)
);
}
}

View File

@ -0,0 +1,11 @@
package api.hbm.fluidmk2;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.uninos.IGenProvider;
import com.hbm.uninos.networkproviders.FluidNetProvider;
public interface IFluidProviderMK2 extends IGenProvider<FluidNetProvider> {
public void useUpFluid(FluidType type, int pressure, long amount);
public long getProviderSpeed(FluidType type, int pressure);
}

View File

@ -0,0 +1,12 @@
package api.hbm.fluidmk2;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.uninos.IGenReceiver;
import com.hbm.uninos.networkproviders.FluidNetProvider;
public interface IFluidReceiverMK2 extends IGenReceiver<FluidNetProvider> {
/** Sends fluid of the desired type and pressure to the receiver, returns the remainder */
public long transferFluid(FluidType type, int pressure, long amount);
public long getReceiverSpeed(FluidType type, int pressure);
}

View File

@ -0,0 +1,16 @@
/**
*
*/
/**
* @author hbm
*
*/
package api.hbm.fluidmk2;
/*
It's rather shrimple: the shiny new energy system using universal nodespace, but hit with a hammer until it works with fluids.
Has a few extra bits and pieces for handling, but the concept is basically the same.
Sounds good?
*/

View File

@ -0,0 +1,13 @@
package api.hbm.recipe;
public interface IRecipeRegisterListener {
/**
* Called during SerializableRecipe.initialize(), after the defaults are loaded but before the template is written.
* Due to the way the recipes are handled, calling it once is not enough, it has to be called once for every SerializableRecipe
* instance handled, therefore the load operation passes the type name of the recipe, so that the listeners know what type of recipe
* to register at that point. Note that the actual SerializableRecipe instance is irrelevant, since recipes are static anyway,
* and direct tampering with SerializableRecipes is not recommended.
*/
public void onRecipeLoad(String recipeClassName);
}

View File

@ -0,0 +1,17 @@
package api.hbm.recipe;
/*
Quick guide on how to make robust and safe recipe integration:
* Implement IRecipeRegisterListener, the resulting class will handle all recipes, and the onRecipeLoad method is called every time the SerializableRecipe system updates
* Register your IRecipeRegisterListener using CompatExternal.registerRecipeRegisterListener, this has to happen before the SerializableRecipe initializes, doing this during PreInit should be safe
* In your IRecipeRegisterListener, check the supplied recipe type string (which will be the class name of the SerializableRecipe currently being registered) and register your custom recipes accordingly using CompatRecipeRegistry
Explanation:
* Order of operations is important for the recipes to work, if recipes are loaded outside the scope of SerializableRecipe.initialize, they will not work correctly
* If recipes are registered before the init, they are deleted, if they are registered after the init, they will not be part of the config template file, and get deleted when running /ntmreload
* Machines change all the time, so the recipe classes should not be considered API, since the compat would break immediately if a machine is changed or removed
* CompatRecipeRegistry promises to never change its method signatures, and have solid sanity checking when recipes are registered, allowing it to make the bst of whatever data is thrown at it
* Using this dedicated registry class means that even if a machine is changed or removed, the recipes will continue to work to the best of its abilities
*/

View File

@ -2177,7 +2177,7 @@ public class ModBlocks {
mass_storage = new BlockMassStorage().setBlockName("mass_storage").setStepSound(Block.soundTypeMetal).setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab);
boxcar = new DecoBlock(Material.iron).setBlockName("boxcar").setStepSound(Block.soundTypeMetal).setHardness(10.0F).setResistance(10.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":boxcar");
boat = new DecoBlock(Material.iron).setBlockName("boat").setStepSound(Block.soundTypeMetal).setHardness(10.0F).setResistance(10.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":boat");
boat = new DecoBlock(Material.iron).setBlockName("boat").setStepSound(Block.soundTypeMetal).setHardness(10.0F).setResistance(10.0F).setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":asphalt");
machine_well = new MachineOilWell().setBlockName("machine_well").setHardness(5.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":machine_well");
machine_pumpjack = new MachinePumpjack().setBlockName("machine_pumpjack").setHardness(5.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":machine_pumpjack");
@ -2279,7 +2279,7 @@ public class ModBlocks {
crystal_virus = new CrystalVirus(Material.iron).setBlockName("crystal_virus").setHardness(15.0F).setResistance(Float.POSITIVE_INFINITY).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":crystal_virus");
crystal_hardened = new BlockGeneric(Material.iron).setBlockName("crystal_hardened").setHardness(15.0F).setResistance(Float.POSITIVE_INFINITY).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":crystal_hardened");
crystal_pulsar = new CrystalPulsar(Material.iron).setBlockName("crystal_pulsar").setHardness(15.0F).setResistance(Float.POSITIVE_INFINITY).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":crystal_pulsar");
taint = new BlockTaint(Material.iron).setBlockName("taint").setHardness(15.0F).setResistance(10.0F).setCreativeTab(null);
taint = new BlockTaint(Material.iron).setBlockName("taint").setHardness(15.0F).setResistance(10.0F).setCreativeTab(null).setBlockTextureName(RefStrings.MODID + ":taint");
vent_chlorine = new BlockVent(Material.iron).setBlockName("vent_chlorine").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vent_chlorine");
vent_cloud = new BlockVent(Material.iron).setBlockName("vent_cloud").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":vent_cloud");
@ -3476,7 +3476,7 @@ public class ModBlocks {
GameRegistry.registerBlock(crystal_virus, crystal_virus.getUnlocalizedName());
GameRegistry.registerBlock(crystal_hardened, crystal_hardened.getUnlocalizedName());
GameRegistry.registerBlock(crystal_pulsar, crystal_pulsar.getUnlocalizedName());
GameRegistry.registerBlock(taint, ItemTaintBlock.class, taint.getUnlocalizedName());
register(taint);
GameRegistry.registerBlock(cheater_virus, cheater_virus.getUnlocalizedName());
GameRegistry.registerBlock(cheater_virus_seed, cheater_virus_seed.getUnlocalizedName());
GameRegistry.registerBlock(ntm_dirt, ntm_dirt.getUnlocalizedName());

View File

@ -4,169 +4,71 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.hbm.blocks.ModBlocks;
import com.hbm.blocks.ITooltipProvider;
import com.hbm.entity.mob.EntityTaintCrab;
import com.hbm.entity.mob.EntityCreeperTainted;
import com.hbm.entity.mob.EntityTeslaCrab;
import com.hbm.potion.HbmPotion;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityFallingBlock;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
public class BlockTaint extends Block/*Container*/ {
@SideOnly(Side.CLIENT)
private IIcon[] icons;
public class BlockTaint extends Block implements ITooltipProvider {
public BlockTaint(Material p_i45386_1_) {
super(p_i45386_1_);
this.setTickRandomly(true);
public BlockTaint(Material mat) {
super(mat);
this.setTickRandomly(true);
}
/*@Override
public TileEntity createNewTileEntity(World p_149915_1_, int p_149915_2_) {
return new TileEntityTaint();
}*/
@SideOnly(Side.CLIENT)
public IIcon getIcon(int p_149691_1_, int meta)
{
return this.icons[meta % this.icons.length];
}
public int damageDropped(int meta)
{
return 0;
}
@Override public MapColor getMapColor(int meta) { return MapColor.grayColor; }
@Override public Item getItemDropped(int i, Random rand, int j) { return null; }
public static int func_150032_b(int p_150032_0_)
{
return func_150031_c(p_150032_0_);
}
public static int func_150031_c(int p_150031_0_)
{
return p_150031_0_ & 15;
}
@SideOnly(Side.CLIENT)
public void getSubBlocks(Item p_149666_1_, CreativeTabs p_149666_2_, List p_149666_3_)
{
for (int i = 0; i < 16; ++i)
{
p_149666_3_.add(new ItemStack(p_149666_1_, 1, i));
}
}
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister p_149651_1_)
{
this.icons = new IIcon[16];
for (int i = 0; i < this.icons.length; ++i)
{
this.icons[i] = p_149651_1_.registerIcon("hbm:taint_" + i);
}
}
public MapColor getMapColor(int p_149728_1_)
{
return MapColor.purpleColor;
}
public static int renderID = RenderingRegistry.getNextAvailableRenderId();
@Override
public int getRenderType(){
return renderID;
public void updateTick(World world, int x, int y, int z, Random rand) {
int meta = world.getBlockMetadata(x, y, z);
if(meta >= 15) return;
for(int i = -3; i <= 3; i++) for(int j = -3; j <= 3; j++) for(int k = -3; k <= 3; k++) {
if(Math.abs(i) + Math.abs(j) + Math.abs(k) > 4) continue;
if(rand.nextFloat() > 0.25F) continue;
Block b = world.getBlock(x + i, y + j, z + k);
if(!b.isNormalCube() || b.isAir(world, x + i, y + j, z + k)) continue;
int targetMeta = meta + 1;
boolean hasAir = false;
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
if(world.getBlock(x + i + dir.offsetX, y + j + dir.offsetY, z + k + dir.offsetZ).isAir(world, x + i + dir.offsetX, y + j + dir.offsetY, z + k + dir.offsetZ)) {
hasAir = true;
break;
}
}
if(!hasAir) targetMeta = meta + 3;
if(targetMeta > 15) continue;
if(b == this && world.getBlockMetadata(x + i, y + j, z + k) >= targetMeta) continue;
world.setBlock(x + i, y + j, z + k, this, targetMeta, 3);
if(rand.nextFloat() < 0.25F && BlockFalling.func_149831_e(world, x + i, y + j - 1, z + k)) {
EntityFallingBlock falling = new EntityFallingBlock(world, x + i + 0.5, y + j + 0.5, z + k + 0.5, this, targetMeta);
world.spawnEntityInWorld(falling);
}
}
}
@Override
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_)
{
return null;
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public boolean renderAsNormalBlock() {
return false;
}
public void onNeighborBlockChange(World world, int x, int y, int z, Block b)
{
if(!hasPosNeightbour(world, x, y, z) && !world.isRemote)
world.setBlockToAir(x, y, z);
}
public void updateTick(World world, int x, int y, int z, Random rand)
{
int meta = world.getBlockMetadata(x, y, z);
if(!world.isRemote && meta < 15) {
for(int i = 0; i < 15; i++) {
int a = rand.nextInt(11) + x - 5;
int b = rand.nextInt(11) + y - 5;
int c = rand.nextInt(11) + z - 5;
if(world.getBlock(a, b, c).isReplaceable(world, a, b, c) && hasPosNeightbour(world, a, b, c))
world.setBlock(a, b, c, ModBlocks.taint, meta + 1, 2);
}
for(int i = 0; i < 85; i++) {
int a = rand.nextInt(7) + x - 3;
int b = rand.nextInt(7) + y - 3;
int c = rand.nextInt(7) + z - 3;
if(world.getBlock(a, b, c).isReplaceable(world, a, b, c) && hasPosNeightbour(world, a, b, c))
world.setBlock(a, b, c, ModBlocks.taint, meta + 1, 2);
}
}
}
public static boolean hasPosNeightbour(World world, int x, int y, int z) {
Block b0 = world.getBlock(x + 1, y, z);
Block b1 = world.getBlock(x, y + 1, z);
Block b2 = world.getBlock(x, y, z + 1);
Block b3 = world.getBlock(x - 1, y, z);
Block b4 = world.getBlock(x, y - 1, z);
Block b5 = world.getBlock(x, y, z - 1);
boolean b = (b0.renderAsNormalBlock() && b0.getMaterial().isOpaque()) ||
(b1.renderAsNormalBlock() && b1.getMaterial().isOpaque()) ||
(b2.renderAsNormalBlock() && b2.getMaterial().isOpaque()) ||
(b3.renderAsNormalBlock() && b3.getMaterial().isOpaque()) ||
(b4.renderAsNormalBlock() && b4.getMaterial().isOpaque()) ||
(b5.renderAsNormalBlock() && b5.getMaterial().isOpaque());
return b;
}
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
return null;
}
@Override
public AxisAlignedBB getSelectedBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
return AxisAlignedBB.getBoundingBox(par2, par3, par4, par2, par3, par4);
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {
return AxisAlignedBB.getBoundingBox(x, y, z, x + 1, y + 0.75, z + 1);
}
@Override
@ -174,36 +76,43 @@ public class BlockTaint extends Block/*Container*/ {
int meta = world.getBlockMetadata(x, y, z);
int level = 15 - meta;
List<ItemStack> list = new ArrayList<ItemStack>();
PotionEffect effect = new PotionEffect(HbmPotion.taint.id, 15 * 20, level);
effect.setCurativeItems(list);
if(entity instanceof EntityLivingBase) {
if(world.rand.nextInt(50) == 0) {
((EntityLivingBase)entity).addPotionEffect(effect);
}
}
if(entity != null && entity.getClass().equals(EntityCreeper.class)) {
EntityCreeperTainted creep = new EntityCreeperTainted(world);
creep.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, entity.rotationYaw, entity.rotationPitch);
if(!world.isRemote) {
entity.setDead();
world.spawnEntityInWorld(creep);
}
}
if(entity instanceof EntityTeslaCrab) {
EntityTaintCrab crab = new EntityTaintCrab(world);
crab.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, entity.rotationYaw, entity.rotationPitch);
entity.motionX *= 0.6;
entity.motionZ *= 0.6;
if(!world.isRemote) {
entity.setDead();
world.spawnEntityInWorld(crab);
}
}
List<ItemStack> list = new ArrayList<ItemStack>();
PotionEffect effect = new PotionEffect(HbmPotion.taint.id, 15 * 20, level);
effect.setCurativeItems(list);
if(entity instanceof EntityLivingBase) {
if(world.rand.nextInt(50) == 0) {
((EntityLivingBase) entity).addPotionEffect(effect);
}
}
if(entity != null && entity.getClass().equals(EntityCreeper.class)) {
EntityCreeperTainted creep = new EntityCreeperTainted(world);
creep.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, entity.rotationYaw, entity.rotationPitch);
if(!world.isRemote) {
entity.setDead();
world.spawnEntityInWorld(creep);
}
}
if(entity instanceof EntityTeslaCrab) {
EntityTaintCrab crab = new EntityTaintCrab(world);
crab.setLocationAndAngles(entity.posX, entity.posY, entity.posZ, entity.rotationYaw, entity.rotationPitch);
if(!world.isRemote) {
entity.setDead();
world.spawnEntityInWorld(crab);
}
}
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) {
list.add("DO NOT TOUCH, BREATHE OR STARE AT.");
}
}

View File

@ -3,8 +3,8 @@ package com.hbm.blocks.bomb;
import java.util.Random;
import com.hbm.blocks.ModBlocks;
import com.hbm.config.ServerConfig;
import com.hbm.explosion.ExplosionLarge;
import com.hbm.explosion.ExplosionNukeSmall;
import com.hbm.explosion.vanillant.ExplosionVNT;
import com.hbm.explosion.vanillant.standard.BlockAllocatorStandard;
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
@ -13,8 +13,13 @@ import com.hbm.explosion.vanillant.standard.ExplosionEffectWeapon;
import com.hbm.explosion.vanillant.standard.PlayerProcessorStandard;
import com.hbm.interfaces.IBomb;
import com.hbm.items.ModItems;
import com.hbm.items.weapon.sedna.factory.XFactoryCatapult;
import com.hbm.main.MainRegistry;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toclient.AuxParticlePacketNT;
import com.hbm.tileentity.bomb.TileEntityLandmine;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.BlockFence;
@ -23,6 +28,7 @@ import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.IBlockAccess;
@ -138,7 +144,7 @@ public class Landmine extends BlockContainer implements IBomb {
if(this == ModBlocks.mine_ap) {
ExplosionVNT vnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 3F);
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(0.5, 10F).setupPiercing(5F, 0.2F));
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(0.5, ServerConfig.MINE_AP_DAMAGE.get()).setupPiercing(5F, 0.2F));
vnt.setPlayerProcessor(new PlayerProcessorStandard());
vnt.setSFX(new ExplosionEffectWeapon(5, 1F, 0.5F));
vnt.explode();
@ -146,13 +152,13 @@ public class Landmine extends BlockContainer implements IBomb {
ExplosionVNT vnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 4F);
vnt.setBlockAllocator(new BlockAllocatorStandard());
vnt.setBlockProcessor(new BlockProcessorStandard());
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(1, 35).setupPiercing(15F, 0.2F));
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(1, ServerConfig.MINE_HE_DAMAGE.get()).setupPiercing(15F, 0.2F));
vnt.setPlayerProcessor(new PlayerProcessorStandard());
vnt.setSFX(new ExplosionEffectWeapon(15, 3.5F, 1.25F));
vnt.explode();
} else if(this == ModBlocks.mine_shrap) {
ExplosionVNT vnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 3F);
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(0.5, 7.5F));
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(0.5, ServerConfig.MINE_SHRAP_DAMAGE.get()));
vnt.setPlayerProcessor(new PlayerProcessorStandard());
vnt.setSFX(new ExplosionEffectWeapon(5, 1F, 0.5F));
vnt.explode();
@ -160,7 +166,20 @@ public class Landmine extends BlockContainer implements IBomb {
ExplosionLarge.spawnShrapnelShower(world, x + 0.5, y + 0.5, z + 0.5, 0, 1D, 0, 45, 0.2D);
ExplosionLarge.spawnShrapnels(world, x + 0.5, y + 0.5, z + 0.5, 5);
} else if(this == ModBlocks.mine_fat) {
ExplosionNukeSmall.explode(world, x + 0.5, y + 0.5, z + 0.5, ExplosionNukeSmall.PARAMS_MEDIUM);
ExplosionVNT vnt = new ExplosionVNT(world, x + 0.5, y + 0.5, z + 0.5, 10);
vnt.setBlockAllocator(new BlockAllocatorStandard(64));
vnt.setBlockProcessor(new BlockProcessorStandard());
vnt.setEntityProcessor(new EntityProcessorCrossSmooth(2, ServerConfig.MINE_NUKE_DAMAGE.get()).withRangeMod(1.5F));
vnt.setPlayerProcessor(new PlayerProcessorStandard());
vnt.explode();
XFactoryCatapult.incrementRad(world, x, y, z, 1.5F);
NBTTagCompound data = new NBTTagCompound();
data.setString("type", "muke");
data.setBoolean("balefire", MainRegistry.polaroidID == 11 || world.rand.nextInt(100) == 0);
PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(data, x + 0.5, y + 0.5, z + 0.5), new TargetPoint(world.provider.dimensionId, x + 0.5, y + 0.5, z + 0.5, 250));
}
}

View File

@ -18,6 +18,6 @@ public class BlockGenericStairs extends BlockStairs {
recipeGen.add(new Object[] {block, meta, this});
this.setBlockTextureName(RefStrings.MODID + ":concrete_smooth");
this.setBlockTextureName(RefStrings.MODID + ":concrete");
}
}

View File

@ -39,7 +39,7 @@ public class BlockMultiSlab extends BlockSlab implements IStepTickReceiver {
}
}
this.setBlockTextureName(RefStrings.MODID + ":concrete_smooth");
this.setBlockTextureName(RefStrings.MODID + ":concrete");
}
@Override

View File

@ -4,11 +4,11 @@ import java.util.Random;
import com.hbm.blocks.ModBlocks;
import com.hbm.blocks.bomb.BlockDetonatable;
import com.hbm.blocks.bomb.BlockTaint;
import com.hbm.blocks.machine.BlockFluidBarrel;
import com.hbm.entity.item.EntityTNTPrimedBase;
import com.hbm.explosion.ExplosionThermo;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
@ -68,7 +68,8 @@ public class RedBarrel extends BlockDetonatable {
int a = rand.nextInt(9) - 4 + ix;
int b = rand.nextInt(9) - 4 + iy;
int c = rand.nextInt(9) - 4 + iz;
if(world.getBlock(a, b, c).isReplaceable(world, a, b, c) && BlockTaint.hasPosNeightbour(world, a, b, c)) {
Block block = world.getBlock(a, b, c);
if(block.isNormalCube() && !block.isAir(world, a, b, c)) {
world.setBlock(a, b, c, ModBlocks.taint, rand.nextInt(3) + 4, 2);
}
}

View File

@ -2,6 +2,7 @@ package com.hbm.blocks.network;
import api.hbm.block.IToolable;
import com.hbm.blocks.IBlockMultiPass;
import com.hbm.interfaces.ICopiable;
import com.hbm.lib.RefStrings;
import com.hbm.render.block.RenderBlockMultipass;
import com.hbm.tileentity.network.TileEntityCableBaseNT;
@ -124,7 +125,7 @@ public class BlockCablePaintable extends BlockContainer implements IToolable, IB
return IBlockMultiPass.getRenderType();
}
public static class TileEntityCablePaintable extends TileEntityCableBaseNT {
public static class TileEntityCablePaintable extends TileEntityCableBaseNT implements ICopiable {
private Block block;
private int meta;
@ -168,5 +169,23 @@ public class BlockCablePaintable extends BlockContainer implements IToolable, IB
if(block != null) nbt.setInteger("block", Block.getIdFromBlock(block));
nbt.setInteger("meta", meta);
}
@Override
public NBTTagCompound getSettings(World world, int x, int y, int z) {
NBTTagCompound nbt = new NBTTagCompound();
if(block != null) {
nbt.setInteger("paintblock", Block.getIdFromBlock(block));
nbt.setInteger("paintmeta", meta);
}
return nbt;
}
@Override
public void pasteSettings(NBTTagCompound nbt, int index, World world, EntityPlayer player, int x, int y, int z) {
if(nbt.hasKey("paintblock")) {
this.block = Block.getBlockById(nbt.getInteger("paintblock"));
this.meta = nbt.getInteger("paintmeta");
}
}
}
}

View File

@ -9,16 +9,21 @@ import com.hbm.tileentity.network.TileEntityDroneRequester;
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import java.util.List;
import java.util.Random;
public class DroneDock extends BlockContainer implements ITooltipProvider {
@ -69,4 +74,53 @@ public class DroneDock extends BlockContainer implements ITooltipProvider {
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) {
this.addStandardInfo(stack, player, list, ext);
}
@Override
public void breakBlock(World world, int x, int y, int z, Block block, int meta) {
if(this == ModBlocks.drone_dock) this.dropContents(world, x, y, z, block, meta, 0, 9);
if(this == ModBlocks.drone_crate_provider) this.dropContents(world, x, y, z, block, meta, 0, 9);
if(this == ModBlocks.drone_crate_requester) this.dropContents(world, x, y, z, block, meta, 9, 18);
super.breakBlock(world, x, y, z, block, meta);
}
private final Random rand = new Random();
public void dropContents(World world, int x, int y, int z, Block block, int meta, int start, int end) {
ISidedInventory sidedInventory = (ISidedInventory) world.getTileEntity(x, y, z);
if(sidedInventory != null) {
for(int i1 = start; i1 < end; ++i1) {
ItemStack stack = sidedInventory.getStackInSlot(i1);
if(stack != null) {
float f = this.rand.nextFloat() * 0.8F + 0.1F;
float f1 = this.rand.nextFloat() * 0.8F + 0.1F;
float f2 = this.rand.nextFloat() * 0.8F + 0.1F;
while(stack.stackSize > 0) {
int j1 = this.rand.nextInt(21) + 10;
if(j1 > stack.stackSize) {
j1 = stack.stackSize;
}
stack.stackSize -= j1;
EntityItem entity = new EntityItem(world, x + f, y + f1, z + f2, new ItemStack(stack.getItem(), j1, stack.getItemDamage()));
if(stack.hasTagCompound()) {
entity.getEntityItem().setTagCompound((NBTTagCompound) stack.getTagCompound().copy());
}
float f3 = 0.05F;
entity.motionX = (float) this.rand.nextGaussian() * f3;
entity.motionY = (float) this.rand.nextGaussian() * f3 + 0.2F;
entity.motionZ = (float) this.rand.nextGaussian() * f3;
world.spawnEntityInWorld(entity);
}
}
}
world.func_147453_f(x, y, z, block);
}
}
}

View File

@ -3,6 +3,7 @@ package com.hbm.blocks.network;
import api.hbm.block.IToolable;
import com.hbm.blocks.IBlockMultiPass;
import com.hbm.blocks.ILookOverlay;
import com.hbm.interfaces.ICopiable;
import com.hbm.lib.RefStrings;
import com.hbm.render.block.RenderBlockMultipass;
import com.hbm.tileentity.network.TileEntityPipeBaseNT;
@ -163,7 +164,7 @@ public class FluidDuctPaintable extends FluidDuctBase implements IToolable, IBlo
ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text);
}
public static class TileEntityPipePaintable extends TileEntityPipeBaseNT {
public static class TileEntityPipePaintable extends TileEntityPipeBaseNT implements ICopiable {
private Block block;
private int meta;
@ -195,5 +196,23 @@ public class FluidDuctPaintable extends FluidDuctBase implements IToolable, IBlo
if(block != null) nbt.setInteger("block", Block.getIdFromBlock(block));
nbt.setInteger("meta", meta);
}
@Override
public NBTTagCompound getSettings(World world, int x, int y, int z) {
NBTTagCompound nbt = new NBTTagCompound();
if(block != null) {
nbt.setInteger("paintblock", Block.getIdFromBlock(block));
nbt.setInteger("paintmeta", meta);
}
return nbt;
}
@Override
public void pasteSettings(NBTTagCompound nbt, int index, World world, EntityPlayer player, int x, int y, int z) {
if(nbt.hasKey("paintblock")) {
this.block = Block.getBlockById(nbt.getInteger("paintblock"));
this.meta = nbt.getInteger("paintmeta");
}
}
}
}

View File

@ -1,24 +1,18 @@
package com.hbm.commands;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.HashMap;
import com.hbm.config.ClientConfig;
import com.hbm.config.ClientConfig.ConfigWrapper;
import com.hbm.config.RunningConfig.ConfigWrapper;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import cpw.mods.fml.relauncher.Side;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.client.ClientCommandHandler;
public class CommandReloadClient extends CommandBase {
public class CommandReloadClient extends CommandReloadConfig {
public static void register() {
if(FMLLaunchHandler.side() != Side.CLIENT) return;
@ -34,95 +28,26 @@ public class CommandReloadClient extends CommandBase {
public String getCommandUsage(ICommandSender sender) {
return "/ntmclient help";
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return sender instanceof EntityPlayer;
}
@Override
public void processCommand(ICommandSender sender, String[] args) {
if(args.length < 1) throw new CommandException(getCommandUsage(sender));
String operator = args[0];
if("help".equals(operator)) {
if(args.length >= 2) {
String command = args[1];
if("help".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows usage for /ntmclient subcommands."));
if("list".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows all client variable names and values."));
if("reload".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Reads client variables from the config file."));
if("get".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows value for the specified variable name."));
if("set".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Sets a variable's value and saves it to the config file."));
} else {
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "help " + EnumChatFormatting.RED + "<command>"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "list"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "reload"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "get " + EnumChatFormatting.RED + "<name>"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "set " + EnumChatFormatting.RED + "<name> <value>"));
}
return;
}
if("list".equals(operator)) {
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "CLIENT VARIABLES:"));
for(Entry<String, ConfigWrapper> line : ClientConfig.configMap.entrySet()) {
sender.addChatMessage(new ChatComponentText(" " + EnumChatFormatting.GOLD + line.getKey() + ": " + EnumChatFormatting.YELLOW + line.getValue().value));
}
return;
}
if("reload".equals(operator)) {
ClientConfig.reload();
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Variables loaded from config file."));
return;
}
if(args.length < 2) throw new CommandException(getCommandUsage(sender));
String key = args[1];
if("get".equals(operator)) {
ConfigWrapper wrapper = ClientConfig.configMap.get(key);
if(wrapper == null) throw new CommandException("Key does not exist.");
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + key + ": " + EnumChatFormatting.YELLOW + wrapper.value));
return;
}
if(args.length < 3) throw new CommandException(getCommandUsage(sender));
String value = args[2];
if("set".equals(operator)) {
ConfigWrapper wrapper = ClientConfig.configMap.get(key);
if(wrapper == null) throw new CommandException("Key does not exist.");
try {
wrapper.update(value);
ClientConfig.refresh();
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Value updated."));
} catch(Exception ex) {
throw new CommandException("Error parsing type for " + wrapper.value.getClass().getSimpleName() + ": " + ex.getLocalizedMessage());
}
return;
}
throw new CommandException(getCommandUsage(sender));
}
@SuppressWarnings("rawtypes")
@Override
public List addTabCompletionOptions(ICommandSender sender, String[] args) {
if(!(sender instanceof EntityPlayer)) return Collections.emptyList();
if(args.length < 1) return Collections.emptyList();
if(args.length == 1) return getListOfStringsMatchingLastWord(args, "list", "reload", "get", "set");
String operator = args[0];
if(args.length == 2 && ("get".equals(operator) || "set".equals(operator))) {
return getListOfStringsFromIterableMatchingLastWord(args, ClientConfig.configMap.keySet().stream().map(String::valueOf).collect(Collectors.toList()));
}
return Collections.emptyList();
@Override public void help(ICommandSender sender, String[] args) {
if(args.length >= 2) {
String command = args[1];
if("help".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows usage for /ntmclient subcommands."));
if("list".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows all client variable names and values."));
if("reload".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Reads client variables from the config file."));
if("get".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows value for the specified variable name."));
if("set".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Sets a variable's value and saves it to the config file."));
} else {
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "help " + EnumChatFormatting.RED + "<command>"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "list"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "reload"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "get " + EnumChatFormatting.RED + "<name>"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmclient " + EnumChatFormatting.GOLD + "set " + EnumChatFormatting.RED + "<name> <value>"));
}
}
@Override public HashMap<String, ConfigWrapper> getConfigMap() { return ClientConfig.configMap; }
@Override public void refresh() { ClientConfig.refresh(); }
@Override public void reload() { ClientConfig.reload(); }
@Override public String getTitle() { return "CLIENT VARIABLES:"; }
}

View File

@ -0,0 +1,102 @@
package com.hbm.commands;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import com.hbm.config.RunningConfig.ConfigWrapper;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
public abstract class CommandReloadConfig extends CommandBase {
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return sender instanceof EntityPlayer;
}
public abstract void help(ICommandSender sender, String[] args);
public abstract HashMap<String, ConfigWrapper> getConfigMap();
public abstract void refresh();
public abstract void reload();
public abstract String getTitle();
@Override
public void processCommand(ICommandSender sender, String[] args) {
if(args.length < 1) throw new CommandException(getCommandUsage(sender));
String operator = args[0];
if("help".equals(operator)) {
help(sender, args);
return;
}
if("list".equals(operator)) {
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + getTitle()));
for(Entry<String, ConfigWrapper> line : getConfigMap().entrySet()) {
sender.addChatMessage(new ChatComponentText(" " + EnumChatFormatting.GOLD + line.getKey() + ": " + EnumChatFormatting.YELLOW + line.getValue().value));
}
return;
}
if("reload".equals(operator)) {
reload();
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Variables loaded from config file."));
return;
}
if(args.length < 2) throw new CommandException(getCommandUsage(sender));
String key = args[1];
if("get".equals(operator)) {
ConfigWrapper wrapper = getConfigMap().get(key);
if(wrapper == null) throw new CommandException("Key does not exist.");
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + key + ": " + EnumChatFormatting.YELLOW + wrapper.value));
return;
}
if(args.length < 3) throw new CommandException(getCommandUsage(sender));
String value = args[2];
if("set".equals(operator)) {
ConfigWrapper wrapper = getConfigMap().get(key);
if(wrapper == null) throw new CommandException("Key does not exist.");
try {
wrapper.update(value);
refresh();
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Value updated."));
} catch(Exception ex) {
throw new CommandException("Error parsing type for " + wrapper.value.getClass().getSimpleName() + ": " + ex.getLocalizedMessage());
}
return;
}
throw new CommandException(getCommandUsage(sender));
}
@SuppressWarnings("rawtypes")
@Override
public List addTabCompletionOptions(ICommandSender sender, String[] args) {
if(!(sender instanceof EntityPlayer)) return Collections.emptyList();
if(args.length < 1) return Collections.emptyList();
if(args.length == 1) return getListOfStringsMatchingLastWord(args, "list", "reload", "get", "set");
String operator = args[0];
if(args.length == 2 && ("get".equals(operator) || "set".equals(operator))) {
return getListOfStringsFromIterableMatchingLastWord(args, getConfigMap().keySet().stream().map(String::valueOf).collect(Collectors.toList()));
}
return Collections.emptyList();
}
}

View File

@ -0,0 +1,45 @@
package com.hbm.commands;
import java.util.HashMap;
import com.hbm.config.RunningConfig.ConfigWrapper;
import com.hbm.config.ServerConfig;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
public class CommandReloadServer extends CommandReloadConfig {
@Override
public String getCommandName() {
return "ntmserver";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/ntmserver help";
}
@Override public void help(ICommandSender sender, String[] args) {
if(args.length >= 2) {
String command = args[1];
if("help".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows usage for /ntmserver subcommands."));
if("list".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows all server variable names and values."));
if("reload".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Reads server variables from the config file."));
if("get".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Shows value for the specified variable name."));
if("set".equals(command)) sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Sets a variable's value and saves it to the config file."));
} else {
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmserver " + EnumChatFormatting.GOLD + "help " + EnumChatFormatting.RED + "<command>"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmserver " + EnumChatFormatting.GOLD + "list"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmserver " + EnumChatFormatting.GOLD + "reload"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmserver " + EnumChatFormatting.GOLD + "get " + EnumChatFormatting.RED + "<name>"));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "/ntmserver " + EnumChatFormatting.GOLD + "set " + EnumChatFormatting.RED + "<name> <value>"));
}
}
@Override public HashMap<String, ConfigWrapper> getConfigMap() { return ServerConfig.configMap; }
@Override public void refresh() { ServerConfig.refresh(); }
@Override public void reload() { ServerConfig.reload(); }
@Override public String getTitle() { return "SERVER VARIABLES:"; }
}

View File

@ -1,24 +1,13 @@
package com.hbm.config;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonWriter;
import com.hbm.main.MainRegistry;
import com.hbm.util.Compat;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
// https://youtube.com/shorts/XTHZWqZt_AI
public class ClientConfig {
public class ClientConfig extends RunningConfig {
public static final Gson gson = new Gson();
public static HashMap<String, ConfigWrapper> configMap = new HashMap();
@ -65,112 +54,28 @@ public class ClientConfig {
/** Initializes defaults, then reads the config file if it exists, then writes the config file. */
public static void initConfig() {
initDefaults();
File folder = MainRegistry.configHbmDir;
File config = new File(folder.getAbsolutePath() + File.separatorChar + "hbmClient.json");
File config = getConfig("hbmClient.json");
if(config.exists()) readConfig(config);
refresh();
}
/** Writes over the config file using the running config. */
public static void refresh() {
File folder = MainRegistry.configHbmDir;
File config = new File(folder.getAbsolutePath() + File.separatorChar + "hbmClient.json");
File config = getConfig("hbmClient.json");
writeConfig(config);
}
/** Writes over the running config using the config file. */
public static void reload() {
File folder = MainRegistry.configHbmDir;
File config = new File(folder.getAbsolutePath() + File.separatorChar + "hbmClient.json");
File config = getConfig("hbmClient.json");
if(config.exists()) readConfig(config);
}
private static void readConfig(File config) {
try {
JsonObject json = gson.fromJson(new FileReader(config), JsonObject.class);
for(Entry<String, ConfigWrapper> line : configMap.entrySet()) {
if(json.has(line.getKey())) {
JsonElement value = json.get(line.getKey());
try {
//world's shittiest dynamic type parser
if(configMap.containsKey(line.getKey())) {
if(line.getValue().value instanceof String) configMap.get(line.getKey()).set(value.getAsString());
if(line.getValue().value instanceof Float) configMap.get(line.getKey()).set(value.getAsFloat());
if(line.getValue().value instanceof Double) configMap.get(line.getKey()).set(value.getAsDouble());
if(line.getValue().value instanceof Integer) configMap.get(line.getKey()).set(value.getAsInt());
if(line.getValue().value instanceof Boolean) configMap.get(line.getKey()).set(value.getAsBoolean());
}
//gson doesn't give me the option to read the raw value of a JsonPrimitive so we have to this shit effectively twice
//once to make sure that the parsed data matches with what's determined by the default,
//and a second time in the ConfigWrapper to add ease of reading the data without needing manual casts
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
RunningConfig.readConfig(config, configMap);
}
private static void writeConfig(File config) {
try {
JsonWriter writer = new JsonWriter(new FileWriter(config));
writer.setIndent(" ");
writer.beginObject();
writer.name("info").value("This file can be edited ingame using the /ntmclient command.");
List<String> keys = new ArrayList();
keys.addAll(configMap.keySet());
Collections.sort(keys); //readability is cool
for(String key : keys) {
ConfigWrapper wrapper = configMap.get(key);
Object value = wrapper.value;
//this sucks and i am too stupid to come up with something better
if(value instanceof String) writer.name(key).value((String) value);
if(value instanceof Float) writer.name(key).value((Float) value);
if(value instanceof Double) writer.name(key).value((Double) value);
if(value instanceof Integer) writer.name(key).value((Integer) value);
if(value instanceof Boolean) writer.name(key).value((Boolean) value);
}
writer.endObject();
writer.close();
} catch(IOException e) {
e.printStackTrace();
}
}
public static class ConfigWrapper<T> {
public T value;
public ConfigWrapper(T o) {
this.value = o;
}
public T get() { return value; }
public void set(T value) { this.value = value; }
public void update(String param) {
Object stupidBufferObject = null; // wahh wahh can't cast Float to T wahh wahh shut the fuck up
if(value instanceof String) stupidBufferObject = param;
if(value instanceof Float) stupidBufferObject = Float.parseFloat(param);
if(value instanceof Double) stupidBufferObject = Double.parseDouble(param);
if(value instanceof Integer) stupidBufferObject = Integer.parseInt(param);
if(value instanceof Boolean) stupidBufferObject = Boolean.parseBoolean(param);
if(stupidBufferObject != null) this.value = (T) stupidBufferObject;
}
RunningConfig.writeConfig(config, configMap, "This file can be edited ingame using the /ntmclient command.");
}
}

View File

@ -23,13 +23,11 @@ public class GeneralConfig {
public static boolean enableVaults = true;
public static boolean enableCataclysm = false;
public static boolean enableExtendedLogging = false;
public static boolean enableHardcoreTaint = false;
public static boolean enableGuns = true;
public static boolean enableVirus = true;
public static boolean enableCrosshairs = true;
public static boolean enableReflectorCompat = false;
public static boolean enableRenderDistCheck = true;
public static boolean enableReEval = true;
public static boolean enableSilentCompStackErrors = true;
public static boolean enableSkyboxes = true;
public static boolean enableImpactWorldProvider = true;
@ -42,7 +40,6 @@ public class GeneralConfig {
public static boolean enableSoundExtension = true;
public static boolean enableMekanismChanges = true;
public static int normalSoundChannels = 200;
public static int hintPos = 0;
public static boolean enableExpensiveMode = false;
@ -100,15 +97,12 @@ public class GeneralConfig {
enableVaults = config.get(CATEGORY_GENERAL, "1.15_enableVaultSpawn", true, "Allows locked safes to spawn").getBoolean(true);
enableCataclysm = config.get(CATEGORY_GENERAL, "1.17_enableCataclysm", false, "Causes satellites to fall whenever a mob dies").getBoolean(false);
enableExtendedLogging = config.get(CATEGORY_GENERAL, "1.18_enableExtendedLogging", false, "Logs uses of the detonator, nuclear explosions, missile launches, grenades, etc.").getBoolean(false);
enableHardcoreTaint = config.get(CATEGORY_GENERAL, "1.19_enableHardcoreTaint", false, "Allows tainted mobs to spread taint").getBoolean(false);
enableGuns = config.get(CATEGORY_GENERAL, "1.20_enableGuns", true, "Prevents new system guns to be fired").getBoolean(true);
enableVirus = config.get(CATEGORY_GENERAL, "1.21_enableVirus", false, "Allows virus blocks to spread").getBoolean(false);
enableCrosshairs = config.get(CATEGORY_GENERAL, "1.22_enableCrosshairs", true, "Shows custom crosshairs when an NTM gun is being held").getBoolean(true);
enableReflectorCompat = config.get(CATEGORY_GENERAL, "1.24_enableReflectorCompat", false, "Enable old reflector oredict name (\"plateDenseLead\") instead of new \"plateTungCar\"").getBoolean(false);
enableRenderDistCheck = config.get(CATEGORY_GENERAL, "1.25_enableRenderDistCheck", true, "Check invalid render distances (over 16, without OptiFine) and fix it").getBoolean(true);
enableReEval = config.get(CATEGORY_GENERAL, "1.27_enableReEval", true, "Allows re-evaluating power networks on link remove instead of destroying and recreating").getBoolean(true);
enableSilentCompStackErrors = config.get(CATEGORY_GENERAL, "1.28_enableSilentCompStackErrors", false, "Enabling this will disable log spam created by unregistered items in ComparableStack instances.").getBoolean(false);
hintPos = CommonConfig.createConfigInt(config, CATEGORY_GENERAL, "1.29_hudOverlayPosition", "0: Top left\n1: Top right\n2: Center right\n3: Center Left", 0);
enableSkyboxes = config.get(CATEGORY_GENERAL, "1.31_enableSkyboxes", true, "If enabled, will try to use NTM's custom skyboxes.").getBoolean(true);
enableImpactWorldProvider = config.get(CATEGORY_GENERAL, "1.32_enableImpactWorldProvider", true, "If enabled, registers custom world provider which modifies lighting and sky colors for post impact effects.").getBoolean(true);
enableStatReRegistering = config.get(CATEGORY_GENERAL, "1.33_enableStatReRegistering", true, "If enabled, will re-register item crafting/breaking/usage stats in order to fix a forge bug where modded items just won't show up.").getBoolean(true);

View File

@ -0,0 +1,116 @@
package com.hbm.config;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonWriter;
import com.hbm.main.MainRegistry;
public class RunningConfig {
public static final Gson gson = new Gson();
public static File getConfig(String name) {
File folder = MainRegistry.configHbmDir;
return new File(folder.getAbsolutePath() + File.separatorChar + name);
}
public static void readConfig(File config, HashMap<String, ConfigWrapper> configMap) {
try {
JsonObject json = gson.fromJson(new FileReader(config), JsonObject.class);
for(Entry<String, ConfigWrapper> line : configMap.entrySet()) {
if(json.has(line.getKey())) {
JsonElement value = json.get(line.getKey());
try {
//world's shittiest dynamic type parser
if(configMap.containsKey(line.getKey())) {
if(line.getValue().value instanceof String) configMap.get(line.getKey()).set(value.getAsString());
if(line.getValue().value instanceof Float) configMap.get(line.getKey()).set(value.getAsFloat());
if(line.getValue().value instanceof Double) configMap.get(line.getKey()).set(value.getAsDouble());
if(line.getValue().value instanceof Integer) configMap.get(line.getKey()).set(value.getAsInt());
if(line.getValue().value instanceof Boolean) configMap.get(line.getKey()).set(value.getAsBoolean());
}
//gson doesn't give me the option to read the raw value of a JsonPrimitive so we have to this shit effectively twice
//once to make sure that the parsed data matches with what's determined by the default,
//and a second time in the ConfigWrapper to add ease of reading the data without needing manual casts
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
public static void writeConfig(File config, HashMap<String, ConfigWrapper> configMap, String info) {
try {
JsonWriter writer = new JsonWriter(new FileWriter(config));
writer.setIndent(" ");
writer.beginObject();
writer.name("info").value(info);
List<String> keys = new ArrayList();
keys.addAll(configMap.keySet());
Collections.sort(keys); //readability is cool
for(String key : keys) {
ConfigWrapper wrapper = configMap.get(key);
Object value = wrapper.value;
//this sucks and i am too stupid to come up with something better
if(value instanceof String) writer.name(key).value((String) value);
if(value instanceof Float) writer.name(key).value((Float) value);
if(value instanceof Double) writer.name(key).value((Double) value);
if(value instanceof Integer) writer.name(key).value((Integer) value);
if(value instanceof Boolean) writer.name(key).value((Boolean) value);
}
writer.endObject();
writer.close();
} catch(IOException e) {
e.printStackTrace();
}
}
public static class ConfigWrapper<T> {
public T value;
public ConfigWrapper(T o) {
this.value = o;
}
public T get() { return value; }
public void set(T value) { this.value = value; }
public void update(String param) {
Object stupidBufferObject = null; // wahh wahh can't cast Float to T wahh wahh shut the fuck up
if(value instanceof String) stupidBufferObject = param;
if(value instanceof Float) stupidBufferObject = Float.parseFloat(param);
if(value instanceof Double) stupidBufferObject = Double.parseDouble(param);
if(value instanceof Integer) stupidBufferObject = Integer.parseInt(param);
if(value instanceof Boolean) stupidBufferObject = Boolean.parseBoolean(param);
if(stupidBufferObject != null) this.value = (T) stupidBufferObject;
}
}
}

View File

@ -0,0 +1,56 @@
package com.hbm.config;
import java.io.File;
import java.util.HashMap;
import com.google.gson.Gson;
public class ServerConfig extends RunningConfig {
public static final Gson gson = new Gson();
public static HashMap<String, ConfigWrapper> configMap = new HashMap();
public static ConfigWrapper<Boolean> DAMAGE_COMPATIBILITY_MODE = new ConfigWrapper(false);
public static ConfigWrapper<Float> MINE_AP_DAMAGE = new ConfigWrapper(10F);
public static ConfigWrapper<Float> MINE_HE_DAMAGE = new ConfigWrapper(35F);
public static ConfigWrapper<Float> MINE_SHRAP_DAMAGE = new ConfigWrapper(7.5F);
public static ConfigWrapper<Float> MINE_NUKE_DAMAGE = new ConfigWrapper(100F);
public static ConfigWrapper<Boolean> TAINT_TRAILS = new ConfigWrapper(false);
private static void initDefaults() {
configMap.put("DAMAGE_COMPATIBILITY_MODE", DAMAGE_COMPATIBILITY_MODE);
configMap.put("MINE_AP_DAMAGE", MINE_AP_DAMAGE);
configMap.put("MINE_HE_DAMAGE", MINE_HE_DAMAGE);
configMap.put("MINE_SHRAP_DAMAGE", MINE_SHRAP_DAMAGE);
configMap.put("MINE_NUKE_DAMAGE", MINE_NUKE_DAMAGE);
configMap.put("TAINT_TRAILS", TAINT_TRAILS);
}
/** Initializes defaults, then reads the config file if it exists, then writes the config file. */
public static void initConfig() {
initDefaults();
File config = getConfig("hbmServer.json");
if(config.exists()) readConfig(config);
refresh();
}
/** Writes over the config file using the running config. */
public static void refresh() {
File config = getConfig("hbmServer.json");
writeConfig(config);
}
/** Writes over the running config using the config file. */
public static void reload() {
File config = getConfig("hbmServer.json");
if(config.exists()) readConfig(config);
}
private static void readConfig(File config) {
RunningConfig.readConfig(config, configMap);
}
private static void writeConfig(File config) {
RunningConfig.writeConfig(config, configMap, "This file can be edited ingame using the /ntmserver command.");
}
}

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List;
import com.hbm.blocks.ModBlocks;
import com.hbm.blocks.bomb.BlockTaint;
import com.hbm.entity.effect.EntityNukeTorex;
import com.hbm.entity.logic.EntityBalefire;
import com.hbm.entity.logic.EntityNukeExplosionMK5;
@ -22,6 +21,7 @@ import com.hbm.items.weapon.ItemCustomMissilePart.WarheadType;
import com.hbm.main.MainRegistry;
import api.hbm.entity.IRadarDetectableNT;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@ -211,7 +211,8 @@ public class EntityMissileCustom extends EntityMissileBaseNT implements IChunkLo
int a = rand.nextInt(r) + (int) posX - (r / 2 - 1);
int b = rand.nextInt(r) + (int) posY - (r / 2 - 1);
int c = rand.nextInt(r) + (int) posZ - (r / 2 - 1);
if(worldObj.getBlock(a, b, c).isReplaceable(worldObj, a, b, c) && BlockTaint.hasPosNeightbour(worldObj, a, b, c)) {
Block block = worldObj.getBlock(a, b, c);
if(block.isNormalCube() && !block.isAir(worldObj, a, b, c)) {
worldObj.setBlock(a, b, c, ModBlocks.taint, rand.nextInt(3) + 4, 2);
}
}

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List;
import com.hbm.blocks.ModBlocks;
import com.hbm.blocks.bomb.BlockTaint;
import com.hbm.config.BombConfig;
import com.hbm.entity.effect.EntityBlackHole;
import com.hbm.entity.effect.EntityCloudFleija;
@ -128,7 +127,10 @@ public abstract class EntityMissileTier0 extends EntityMissileBaseNT {
int a = rand.nextInt(11) + (int) this.posX - 5;
int b = rand.nextInt(11) + (int) this.posY - 5;
int c = rand.nextInt(11) + (int) this.posZ - 5;
if(worldObj.getBlock(a, b, c).isReplaceable(worldObj, a, b, c) && BlockTaint.hasPosNeightbour(worldObj, a, b, c)) worldObj.setBlock(a, b, c, ModBlocks.taint);
Block block = worldObj.getBlock(a, b, c);
if(block.isNormalCube() && !block.isAir(worldObj, a, b, c)) {
worldObj.setBlock(a, b, c, ModBlocks.taint, rand.nextInt(3) + 4, 2);
}
}
}
@Override public ItemStack getDebrisRareDrop() { return new ItemStack(ModItems.powder_spark_mix, 1); }

View File

@ -1,7 +1,7 @@
package com.hbm.entity.mob;
import com.hbm.blocks.ModBlocks;
import com.hbm.config.GeneralConfig;
import com.hbm.config.ServerConfig;
import api.hbm.entity.IRadiationImmune;
import net.minecraft.block.Block;
@ -55,9 +55,9 @@ public class EntityCreeperTainted extends EntityCreeper implements IRadiationImm
int a = rand.nextInt(15) + (int) posX - 7;
int b = rand.nextInt(15) + (int) posY - 7;
int c = rand.nextInt(15) + (int) posZ - 7;
if(worldObj.getBlock(a, b, c).isReplaceable(worldObj, a, b, c) && hasPosNeightbour(worldObj, a, b, c)) {
if(!GeneralConfig.enableHardcoreTaint) {
Block block = worldObj.getBlock(a, b, c);
if(block.isNormalCube() && !block.isAir(worldObj, a, b, c)) {
if(!ServerConfig.TAINT_TRAILS.get()) {
worldObj.setBlock(a, b, c, ModBlocks.taint, rand.nextInt(3) + 5, 2);
} else {
worldObj.setBlock(a, b, c, ModBlocks.taint, rand.nextInt(3), 2);
@ -71,9 +71,9 @@ public class EntityCreeperTainted extends EntityCreeper implements IRadiationImm
int a = rand.nextInt(7) + (int) posX - 3;
int b = rand.nextInt(7) + (int) posY - 3;
int c = rand.nextInt(7) + (int) posZ - 3;
if(worldObj.getBlock(a, b, c).isReplaceable(worldObj, a, b, c) && hasPosNeightbour(worldObj, a, b, c)) {
if(!GeneralConfig.enableHardcoreTaint) {
Block block = worldObj.getBlock(a, b, c);
if(block.isNormalCube() && !block.isAir(worldObj, a, b, c)) {
if(!ServerConfig.TAINT_TRAILS.get()) {
worldObj.setBlock(a, b, c, ModBlocks.taint, rand.nextInt(6) + 10, 2);
} else {
worldObj.setBlock(a, b, c, ModBlocks.taint, rand.nextInt(3) + 4, 2);

View File

@ -12,7 +12,7 @@ import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
public class ExplosionNukeSmall {
@Deprecated public class ExplosionNukeSmall {
public static void explode(World world, double posX, double posY, double posZ, MukeParams params) {

View File

@ -0,0 +1,178 @@
package com.hbm.handler.nei;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.recipe.TemplateRecipeHandler;
import com.hbm.blocks.ModBlocks;
import com.hbm.handler.imc.ICompatNHNEI;
import com.hbm.itempool.ItemPool;
import com.hbm.itempool.ItemPoolsSatellite;
import com.hbm.items.ModItems;
import com.hbm.lib.RefStrings;
import com.hbm.saveddata.satellites.SatelliteMiner;
import com.hbm.util.ItemStackUtil;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.WeightedRandomChestContent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static codechicken.lib.gui.GuiDraw.drawTexturedModalRect;
public class SatelliteHandler extends TemplateRecipeHandler implements ICompatNHNEI {
@Override
public ItemStack[] getMachinesForRecipe() {
return new ItemStack[] {
new ItemStack(ModBlocks.sat_dock)
};
}
@Override
public String getRecipeID() {
return "ntmSatellite";
}
@Override
public String getRecipeName() {
return "Satellite";
}
@Override
public String getGuiTexture() {
return RefStrings.MODID + ":textures/gui/nei/gui_nei_anvil.png";
}
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
if(outputId.equals("ntmSatellite")) {
for(Item satelliteItem : new Item[]{ModItems.sat_miner, ModItems.sat_lunar_miner}) {
String poolName = SatelliteMiner.getCargoForItem(satelliteItem);
if(poolName == null) {
continue;
}
this.addRecipeToList(satelliteItem, ItemPool.getPool(poolName));
}
} else {
super.loadCraftingRecipes(outputId, results);
}
}
@Override
public void loadCraftingRecipes(ItemStack result) {
for(Item satelliteItem : new Item[]{ModItems.sat_miner, ModItems.sat_lunar_miner}) {
String poolName = SatelliteMiner.getCargoForItem(satelliteItem);
if(poolName == null) {
continue;
}
WeightedRandomChestContent[] pool = ItemPool.getPool(poolName);
for(WeightedRandomChestContent poolEntry : pool) {
if(NEIServerUtils.areStacksSameTypeCrafting(poolEntry.theItemId, result)) {
this.addRecipeToList(satelliteItem, pool);
break;
}
}
}
}
@Override
public void loadUsageRecipes(String inputId, Object... ingredients) {
if(inputId.equals("ntmSatellite")) {
loadCraftingRecipes("ntmSatellite");
} else {
super.loadUsageRecipes(inputId, ingredients);
}
}
@Override
public void loadUsageRecipes(ItemStack ingredient) {
if(ingredient.getItem() == ModItems.sat_miner) {
this.addRecipeToList(ModItems.sat_miner, ItemPool.getPool(ItemPoolsSatellite.POOL_SAT_MINER));
} else if(ingredient.getItem() == ModItems.sat_lunar_miner) {
this.addRecipeToList(ModItems.sat_lunar_miner, ItemPool.getPool(ItemPoolsSatellite.POOL_SAT_LUNAR));
}
}
private void addRecipeToList(Item poolItem, WeightedRandomChestContent[] poolEntries) {
List<ItemStack> outs = new ArrayList<>();
int weight = Arrays.stream(poolEntries).mapToInt(poolEntry -> poolEntry.itemWeight).sum();
for(WeightedRandomChestContent poolEntry : poolEntries) {
ItemStack stack = poolEntry.theItemId.copy();
float chance = 100F * poolEntry.itemWeight / weight;
ItemStackUtil.addTooltipToStack(stack, EnumChatFormatting.RED + "" + ((int)(chance * 10F) / 10F) + "%");
outs.add(stack);
}
this.arecipes.add(new RecipeSet(new ItemStack(poolItem), outs));
}
@Override
public void drawBackground(int recipe) {
super.drawBackground(recipe);
drawTexturedModalRect(11, 23, 113, 105, 18, 18); //in
drawTexturedModalRect(47, 5, 5, 87, 108, 54); //out
drawTexturedModalRect(29, 14, 131, 96, 18, 36); //operation
}
public class RecipeSet extends TemplateRecipeHandler.CachedRecipe {
List<PositionedStack> input = new ArrayList<>();
List<PositionedStack> output = new ArrayList<>();
PositionedStack satelliteDock;
public RecipeSet(Object in, List<ItemStack> out) {
//not the prettiest of solutions but certainly the most pleasant to work with
int inLine = 1;
int outLine = 1;
int inOX = 0;
int inOY = 0;
int outOX = 0;
int outOY = 0;
int anvX = 0;
int anvY = 31;
outLine = 6;
inOX = 12;
inOY = 24;
outOX = 48;
outOY = 6;
anvX = 30;
this.input.add(new PositionedStack(in, inOX, inOY));
int overflowCount = out.size() / 18;
for(int i = 0; i < Math.min(out.size(), 18); i++) {
ItemStack[] stacks = new ItemStack[overflowCount + 1];
for(int j = 0; j < overflowCount + 1 && j * 18 + i < out.size(); j++) {
stacks[j] = out.get(j * 18 + i);
}
this.output.add(new PositionedStack(stacks, outOX + 18 * (i % outLine), outOY + 18 * (i / outLine)));
}
this.satelliteDock = new PositionedStack(new ItemStack(ModBlocks.sat_dock), anvX, anvY);
}
@Override
public List<PositionedStack> getIngredients() {
return getCycledIngredients(cycleticks / 20, input);
}
@Override
public PositionedStack getResult() {
return output.get(0);
}
@Override
public List<PositionedStack> getOtherStacks() {
ArrayList<PositionedStack> stacks = new ArrayList<>(output);
stacks.add(satelliteDock);
return getCycledIngredients(cycleticks / 20, stacks);
}
}
}

View File

@ -13,8 +13,10 @@ import com.hbm.inventory.fluid.trait.*;
import com.hbm.inventory.fluid.trait.FluidTraitSimple.*;
import com.hbm.lib.RefStrings;
import com.hbm.render.util.EnumSymbol;
import com.hbm.uninos.INetworkProvider;
import com.hbm.util.I18nUtil;
import api.hbm.fluidmk2.FluidNetMK2;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.tileentity.TileEntity;
@ -252,4 +254,8 @@ public class FluidType {
public String name() {
return this.stringId;
}
public INetworkProvider<FluidNetMK2> getNetworkProvider() {
return null; //TBI
}
}

View File

@ -46,6 +46,8 @@ public class ArcWelderRecipes extends SerializableRecipe {
new OreDictStack(ANY_BISMOIDBRONZE.plateCast(), 2), new OreDictStack(CMB.plateWelded(), 1), new ComparableStack(ModItems.ingot_cft)));
//Dense Wires
recipes.add(new ArcWelderRecipe(new ItemStack(ModItems.wire_dense, 1, Mats.MAT_COPPER.id), 100, 10_000L,
new OreDictStack(CU.wireFine(), 8)));
recipes.add(new ArcWelderRecipe(new ItemStack(ModItems.wire_dense, 1, Mats.MAT_ALLOY.id), 100, 10_000L,
new OreDictStack(ALLOY.wireFine(), 8)));
recipes.add(new ArcWelderRecipe(new ItemStack(ModItems.wire_dense, 1, Mats.MAT_GOLD.id), 100, 10_000L,

View File

@ -77,7 +77,7 @@ public class BlastFurnaceRecipes extends SerializableRecipe {
hiddenRecipes.add(new ComparableStack(ModItems.meteorite_sword_alloyed));
}
private static void addRecipe(Object in1, Object in2, ItemStack out) {
public static void addRecipe(Object in1, Object in2, ItemStack out) {
if(in1 instanceof Item) in1 = new ComparableStack((Item) in1);
if(in1 instanceof Block) in1 = new ComparableStack((Block) in1);

View File

@ -19,7 +19,7 @@ import net.minecraft.item.ItemStack;
public class BreederRecipes extends SerializableRecipe {
private static HashMap<ComparableStack, BreederRecipe> recipes = new HashMap();
public static HashMap<ComparableStack, BreederRecipe> recipes = new HashMap();
@Override
public void registerDefaults() {

View File

@ -43,7 +43,7 @@ import net.minecraftforge.oredict.OreDictionary;
public class CentrifugeRecipes extends SerializableRecipe {
private static HashMap<AStack, ItemStack[]> recipes = new HashMap();
public static HashMap<AStack, ItemStack[]> recipes = new HashMap();
@Override
public void registerDefaults() {

View File

@ -38,7 +38,7 @@ public class ChemplantRecipes extends SerializableRecipe {
@Override
public void registerDefaults() {
//6-30, formerly oil cracking, coal liquefaction and solidifciation
//6-30, formerly oil cracking, coal liquefaction and solidification
registerOtherOil();
recipes.add(new ChemRecipe(36, "COOLANT", 50)

View File

@ -25,7 +25,7 @@ import net.minecraft.item.ItemStack;
public class CokerRecipes extends SerializableRecipe {
private static HashMap<FluidType, Triplet<Integer, ItemStack, FluidStack>> recipes = new HashMap();
public static HashMap<FluidType, Triplet<Integer, ItemStack, FluidStack>> recipes = new HashMap();
@Override
public void registerDefaults() {
@ -68,7 +68,7 @@ public class CokerRecipes extends SerializableRecipe {
registerRecipe(VITRIOL, 4000, new ItemStack(ModItems.powder_iron), new FluidStack(SULFURIC_ACID, 500));
}
private static void registerAuto(FluidType fluid, FluidType type) {
public static void registerAuto(FluidType fluid, FluidType type) {
registerSFAuto(fluid, 820_000L, DictFrame.fromOne(ModItems.coke, EnumCokeType.PETROLEUM), type); //3200 burntime * 1.25 burntime bonus * 200 TU/t + 20000TU per operation
}
private static void registerSFAuto(FluidType fluid, long tuPerSF, ItemStack fuel, FluidType type) {

View File

@ -34,7 +34,7 @@ import net.minecraft.item.ItemStack;
public class CombinationRecipes extends SerializableRecipe {
private static HashMap<Object, Pair<ItemStack, FluidStack>> recipes = new HashMap();
public static HashMap<Object, Pair<ItemStack, FluidStack>> recipes = new HashMap();
@Override
public void registerDefaults() {

View File

@ -36,7 +36,7 @@ public class CrackingRecipes extends SerializableRecipe {
public static final int xyl_crack_aroma = 80;
public static final int xyl_crack_petro = 20;
private static Map<FluidType, Pair<FluidStack, FluidStack>> cracking = new HashMap();
public static Map<FluidType, Pair<FluidStack, FluidStack>> cracking = new HashMap();
@Override
public void registerDefaults() {

View File

@ -235,6 +235,12 @@ public class CrystallizerRecipes extends SerializableRecipe {
registerRecipe(P_WHITE.dust(), new CrystallizerRecipe(new ItemStack(ModItems.ingot_phosphorus), utilityTime), new FluidStack(Fluids.AROMATICS, 50));
}
/// COMPAT CINNABAR DUST ///
List<ItemStack> dustCinnabar = OreDictionary.getOres(CINNABAR.dust());
if(dustCinnabar != null && !dustCinnabar.isEmpty()) {
registerRecipe(CINNABAR.dust(), new CrystallizerRecipe(new ItemStack(ModItems.cinnebar), utilityTime), new FluidStack(Fluids.PEROXIDE, 50));
}
if(!IMCCrystallizer.buffer.isEmpty()) {
recipes.putAll(IMCCrystallizer.buffer);
MainRegistry.logger.info("Fetched " + IMCCrystallizer.buffer.size() + " IMC crystallizer recipes!");

View File

@ -19,7 +19,7 @@ import net.minecraft.item.ItemStack;
public class FractionRecipes extends SerializableRecipe {
private static Map<FluidType, Pair<FluidStack, FluidStack>> fractions = new HashMap();
public static Map<FluidType, Pair<FluidStack, FluidStack>> fractions = new HashMap();
@Override
public void registerDefaults() {
@ -40,8 +40,8 @@ public class FractionRecipes extends SerializableRecipe {
fractions.put(Fluids.OIL_COKER, new Pair(new FluidStack(Fluids.CRACKOIL, 30), new FluidStack(Fluids.HEATINGOIL, 70)));
fractions.put(Fluids.NAPHTHA_COKER, new Pair(new FluidStack(Fluids.NAPHTHA_CRACK, 75), new FluidStack(Fluids.LIGHTOIL_CRACK, 25)));
fractions.put(Fluids.GAS_COKER, new Pair(new FluidStack(Fluids.AROMATICS, 25), new FluidStack(Fluids.CARBONDIOXIDE, 75)));
fractions.put(Fluids.CHLOROCALCITE_MIX, new Pair(new FluidStack(Fluids.CHLOROCALCITE_CLEANED, 50), new FluidStack(Fluids.COLLOID, 50)));
fractions.put(Fluids.BAUXITE_SOLUTION, new Pair(new FluidStack(Fluids.REDMUD, 50), new FluidStack(Fluids.SODIUM_ALUMINATE, 50)));
fractions.put(Fluids.CHLOROCALCITE_MIX, new Pair(new FluidStack(Fluids.CHLOROCALCITE_CLEANED, 50), new FluidStack(Fluids.COLLOID, 50)));
fractions.put(Fluids.BAUXITE_SOLUTION, new Pair(new FluidStack(Fluids.REDMUD, 50), new FluidStack(Fluids.SODIUM_ALUMINATE, 50)));
}
public static Pair<FluidStack, FluidStack> getFractions(FluidType oil) {

View File

@ -14,7 +14,7 @@ import com.hbm.tileentity.machine.TileEntityHadron.EnumHadronState;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
public class HadronRecipes extends SerializableRecipe {
@Deprecated public class HadronRecipes extends SerializableRecipe {
/*
* Since we're dealing with like 10 or so recipes, using a HashMap (or to combine two keys, a HashMap *in* a HashMap)

View File

@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack;
public class HydrotreatingRecipes extends SerializableRecipe {
private static HashMap<FluidType, Triplet<FluidStack, FluidStack, FluidStack>> recipes = new HashMap();
public static HashMap<FluidType, Triplet<FluidStack, FluidStack, FluidStack>> recipes = new HashMap();
@Override
public void registerDefaults() {

View File

@ -27,7 +27,7 @@ import net.minecraftforge.oredict.OreDictionary;
public class LiquefactionRecipes extends SerializableRecipe {
private static HashMap<Object, FluidStack> recipes = new HashMap();
public static HashMap<Object, FluidStack> recipes = new HashMap();
@Override
public void registerDefaults() {

View File

@ -124,7 +124,7 @@ public class PyroOvenRecipes extends SerializableRecipe {
.out(new FluidStack(Fluids.HYDROGEN, 8_000)).out(new ItemStack(ModItems.ingot_graphite, 1)));
}
private static void registerSFAuto(FluidType fluid) {
public static void registerSFAuto(FluidType fluid) {
registerSFAuto(fluid, 1_440_000L, ModItems.solid_fuel); //3200 burntime * 1.5 burntime bonus * 300 TU/t
}
private static void registerSFAuto(FluidType fluid, long tuPerSF, Item fuel) {

View File

@ -18,7 +18,7 @@ import net.minecraft.item.ItemStack;
public class ReformingRecipes extends SerializableRecipe {
private static HashMap<FluidType, Triplet<FluidStack, FluidStack, FluidStack>> recipes = new HashMap();
public static HashMap<FluidType, Triplet<FluidStack, FluidStack, FluidStack>> recipes = new HashMap();
@Override
public void registerDefaults() {

View File

@ -56,7 +56,7 @@ public class SolidificationRecipes extends SerializableRecipe {
//aromatics can be idfk wax or soap or sth, perhaps artificial lubricant?
//on that note, add more leaded variants
private static HashMap<FluidType, Pair<Integer, ItemStack>> recipes = new HashMap();
public static HashMap<FluidType, Pair<Integer, ItemStack>> recipes = new HashMap();
@Override
public void registerDefaults() {

View File

@ -38,8 +38,8 @@ import net.minecraftforge.oredict.OreDictionary;
public class AnvilRecipes extends SerializableRecipe {
private static List<AnvilSmithingRecipe> smithingRecipes = new ArrayList();
private static List<AnvilConstructionRecipe> constructionRecipes = new ArrayList();
public static List<AnvilSmithingRecipe> smithingRecipes = new ArrayList();
public static List<AnvilConstructionRecipe> constructionRecipes = new ArrayList();
public static void register() {
registerSmithing();

View File

@ -29,6 +29,7 @@ import com.hbm.items.ModItems;
import com.hbm.main.MainRegistry;
import com.hbm.util.Tuple.Pair;
import api.hbm.recipe.IRecipeRegisterListener;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@ -37,6 +38,7 @@ public abstract class SerializableRecipe {
public static final Gson gson = new Gson();
public static List<SerializableRecipe> recipeHandlers = new ArrayList();
public static List<IRecipeRegisterListener> additionalListeners = new ArrayList();
public boolean modified = false;
@ -114,6 +116,10 @@ public abstract class SerializableRecipe {
MainRegistry.logger.info("No recipe file found, registering defaults for " + recipe.getFileName());
recipe.registerDefaults();
for(IRecipeRegisterListener listener : additionalListeners) {
listener.onRecipeLoad(recipe.getClass().getSimpleName());
}
File recTemplate = new File(recDir.getAbsolutePath() + File.separatorChar + "_" + recipe.getFileName());
MainRegistry.logger.info("Writing template file " + recTemplate.getName());
recipe.writeTemplateFile(recTemplate);
@ -141,7 +147,7 @@ public abstract class SerializableRecipe {
public abstract void writeRecipe(Object recipe, JsonWriter writer) throws IOException;
/** Registers the default recipes */
public abstract void registerDefaults();
/** Deletes all existing recipes, currenly unused */
/** Deletes all existing recipes, currently unused */
public abstract void deleteRecipes();
/** A routine called after registering all recipes, whether it's a template or not. Good for IMC functionality. */
public void registerPost() { }

View File

@ -3022,7 +3022,8 @@ public class ModItems {
iv_empty = new ItemSimpleConsumable().setUseActionServer((stack, user) -> {
if(user.hurtResistantTime <= 0) {
ItemSimpleConsumable.giveSoundAndDecrement(stack, user, "hbm:item.syringe", new ItemStack(ModItems.iv_blood));
user.attackEntityFrom(DamageSource.magic, 5F);
user.setHealth(Math.max(user.getHealth() - 5F, 0F));
if(user.getHealth() <= 0) user.onDeath(DamageSource.magic);
}
}).setUnlocalizedName("iv_empty").setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":iv_empty");
@ -3829,7 +3830,7 @@ public class ModItems {
gun_b92_ammo = new GunB92Cell().setUnlocalizedName("gun_b92_ammo").setMaxStackSize(1).setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":gun_b92_ammo_alt");
gun_b92 = new GunB92().setUnlocalizedName("gun_b92").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":gun_b92");
gun_cryolator_ammo = new Item().setUnlocalizedName("gun_cryolator_ammo").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":gun_cryolator_ammo");
gun_cryocannon = new ItemCryoCannon(GunEnergyFactory.getCryoCannonConfig()).setUnlocalizedName("gun_cryocannon").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":gun_cryocannon");
gun_cryocannon = new ItemCryoCannon(GunEnergyFactory.getCryoCannonConfig()).setUnlocalizedName("gun_cryocannon").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":gun_darter");
gun_fireext = new ItemGunBase(GunEnergyFactory.getExtConfig()).setUnlocalizedName("gun_fireext").setCreativeTab(MainRegistry.weaponTab).setTextureName(RefStrings.MODID + ":gun_fireext");
ToolMaterial matCrucible = EnumHelper.addToolMaterial("CRUCIBLE", 10, 3, 50.0F, 100.0F, 0);

View File

@ -1,40 +0,0 @@
package com.hbm.items.block;
import java.util.List;
import com.hbm.blocks.bomb.BlockTaint;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
public class ItemTaintBlock extends ItemBlock
{
public ItemTaintBlock(Block p_i45358_1_)
{
super(p_i45358_1_);
this.setMaxDamage(0);
this.setHasSubtypes(true);
}
@SideOnly(Side.CLIENT)
public IIcon getIconFromDamage(int p_77617_1_)
{
return this.field_150939_a.func_149735_b(2, BlockTaint.func_150032_b(p_77617_1_));
}
public int getMetadata(int p_77647_1_)
{
return p_77647_1_;
}
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean bool)
{
list.add("DO NOT TOUCH, BREATHE OR STARE AT.");
}
}

View File

@ -54,7 +54,7 @@ public class ItemAmmoHIMARS extends Item {
public ItemAmmoHIMARS() {
this.setHasSubtypes(true);
this.setCreativeTab(MainRegistry.weaponTab);
this.setTextureName(RefStrings.MODID + ":ammo_rocket");
this.setTextureName(RefStrings.MODID + ":ammo_standard.rocket_he");
this.setMaxStackSize(1);
init();
}

View File

@ -5,6 +5,7 @@ import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import com.hbm.config.GeneralConfig;
import com.hbm.handler.HbmKeybinds.EnumKeybind;
import com.hbm.interfaces.IItemHUD;
import com.hbm.items.IEquipReceiver;
@ -169,6 +170,8 @@ public class ItemGunBaseNT extends Item implements IKeybindReceiver, IEquipRecei
}
public void handleKeybind(EntityLivingBase entity, IInventory inventory, ItemStack stack, EnumKeybind keybind, boolean newState) {
if(!GeneralConfig.enableGuns) return;
int configs = this.configs_DNA.length;
for(int i = 0; i < configs; i++) {

View File

@ -191,7 +191,7 @@ public class XFactory762mm {
.addBus("LIFT", new BusAnimationSequence().hold(200).addPos(30, 0, 0, 500, IType.SIN_FULL).holdUntil(1200).addPos(0, 0, 0, 500, IType.SIN_FULL))
.addBus("SHOW_CLIP", new BusAnimationSequence().setPos(1, 1, 1))
.addBus("CLIP", new BusAnimationSequence().setPos(2, -3, 0).hold(250).addPos(0.5, 1, 0, 500, IType.SIN_DOWN).addPos(0, 0, 0, 250, IType.SIN_FULL).hold(400).addPos(-0.5, 0.5, 0, 150).addPos(-3, -3, 0, 250, IType.SIN_UP))
.addBus("BULLETS", new BusAnimationSequence().setPos(2, -4, 0).hold(250).addPos(0.5, 1, 0, 500, IType.SIN_DOWN).addPos(0, 0, 0, 250, IType.SIN_FULL).hold(150).addPos(0, -1.5, 0, 250, IType.SIN_DOWN));
.addBus("BULLETS", new BusAnimationSequence().setPos(2, -3, 0).hold(250).addPos(0.5, 1, 0, 500, IType.SIN_DOWN).addPos(0, 0, 0, 250, IType.SIN_FULL).hold(150).addPos(0, -1.5, 0, 250, IType.SIN_DOWN));
case JAMMED: return new BusAnimation()
.addBus("LIFT", new BusAnimationSequence().hold(250).addPos(-15, 0, 0, 500, IType.SIN_FULL).holdUntil(1650).addPos(0, 0, 0, 500, IType.SIN_FULL))
.addBus("BOLT_TURN", new BusAnimationSequence().hold(250).addPos(0, 0, turn, 150).holdUntil(1250).addPos(0, 0, 0, 150))

View File

@ -771,7 +771,6 @@ public class ClientProxy extends ServerProxy {
@Override
public void registerBlockRenderer() {
RenderingRegistry.registerBlockHandler(new RenderTaintBlock());
RenderingRegistry.registerBlockHandler(new RenderScaffoldBlock());
RenderingRegistry.registerBlockHandler(new RenderTapeBlock());
RenderingRegistry.registerBlockHandler(new RenderSteelBeam());

View File

@ -1175,30 +1175,34 @@ public class CraftingManager {
List<IRecipe> toDestroy = new ArrayList();
for(Object o : net.minecraft.item.crafting.CraftingManager.getInstance().getRecipeList()) {
if(o instanceof IRecipe) {
IRecipe rec = (IRecipe)o;
ItemStack stack = rec.getRecipeOutput();
for(ItemStack target : targets) {
if(stack != null && stack.getItem() == target.getItem() && stack.getItemDamage() == target.getItemDamage()) toDestroy.add(rec);
List recipeList = net.minecraft.item.crafting.CraftingManager.getInstance().getRecipeList();
synchronized(recipeList) { //this is how threading works. i think.
for(Object o : recipeList) {
if(o instanceof IRecipe) {
IRecipe rec = (IRecipe)o;
ItemStack stack = rec.getRecipeOutput();
for(ItemStack target : targets) {
if(stack != null && stack.getItem() == target.getItem() && stack.getItemDamage() == target.getItemDamage()) toDestroy.add(rec);
}
}
}
}
if(toDestroy.size() > 0) {
net.minecraft.item.crafting.CraftingManager.getInstance().getRecipeList().removeAll(toDestroy);
}
if(Loader.isModLoaded("Mekanism")) {
Item disassembler = (Item) Item.itemRegistry.getObject("Mekanism:AtomicDisassembler");
if(disassembler != null) addRecipeAuto(new ItemStack(disassembler, 1), "GAG", "EIE", " I ", 'G', GOLD.plateCast(), 'A', "alloyUltimate", 'E', "battery", 'I', "ingotRefinedObsidian");
}
if(Loader.isModLoaded("MekanismGenerators")) {
Block generator = (Block) Block.blockRegistry.getObject("MekanismGenerators:Generator");
if(generator != null) addRecipeAuto(new ItemStack(generator, 1, 6), " T ", "TAT", "BCB", 'T', TI.plateCast(), 'A', "alloyAdvanced", 'B', "battery", 'C', ANY_PLASTIC.ingot());
if(toDestroy.size() > 0) {
recipeList.removeAll(toDestroy);
}
if(Loader.isModLoaded("Mekanism")) {
Item disassembler = (Item) Item.itemRegistry.getObject("Mekanism:AtomicDisassembler");
if(disassembler != null) addRecipeAuto(new ItemStack(disassembler, 1), "GAG", "EIE", " I ", 'G', GOLD.plateCast(), 'A', "alloyUltimate", 'E', "battery", 'I', "ingotRefinedObsidian");
}
if(Loader.isModLoaded("MekanismGenerators")) {
Block generator = (Block) Block.blockRegistry.getObject("MekanismGenerators:Generator");
if(generator != null) addRecipeAuto(new ItemStack(generator, 1, 6), " T ", "TAT", "BCB", 'T', TI.plateCast(), 'A', "alloyAdvanced", 'B', "battery", 'C', ANY_PLASTIC.ingot());
}
}
}
}

View File

@ -861,7 +861,9 @@ public class MainRegistry {
FalloutConfigJSON.initialize();
ItemPoolConfigJSON.initialize();
ClientConfig.initConfig();
ServerConfig.initConfig();
TileEntityNukeCustom.registerBombItems();
ArmorUtil.register();
@ -948,6 +950,7 @@ public class MainRegistry {
event.registerServerCommand(new CommandSatellites());
event.registerServerCommand(new CommandRadiation());
event.registerServerCommand(new CommandPacketInfo());
event.registerServerCommand(new CommandReloadServer());
}
@EventHandler

View File

@ -114,6 +114,7 @@ import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.event.entity.player.PlayerUseItemEvent;
import net.minecraftforge.event.world.BlockEvent.BreakEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.logging.log4j.Level;
@ -1231,6 +1232,18 @@ public class ModEventHandler {
}*/
}
@SubscribeEvent
public void onChunkLoad(ChunkEvent.Load event) {
//test for automatic in-world block replacement
/*for(int x = 0; x < 16; x++) for(int y = 0; y < 255; y++) for(int z = 0; z < 16; z++) {
if(event.getChunk().getBlock(x, y, z) instanceof MachineArcFurnace) {
event.getChunk().func_150807_a(x, y, z, Blocks.air, 0);
}
}*/
}
@SubscribeEvent
public void onPlayerClone(net.minecraftforge.event.entity.player.PlayerEvent.Clone event) {

View File

@ -43,6 +43,7 @@ public class NEIRegistry {
handlers.add(new CrucibleCastingHandler());
handlers.add(new ToolingHandler());
handlers.add(new ConstructionHandler());
handlers.add(new SatelliteHandler());
//universal boyes
handlers.add(new ZirnoxRecipeHandler());

View File

@ -3,9 +3,8 @@ package com.hbm.potion;
import java.lang.reflect.Field;
import com.hbm.blocks.ModBlocks;
import com.hbm.blocks.bomb.BlockTaint;
import com.hbm.config.GeneralConfig;
import com.hbm.config.PotionConfig;
import com.hbm.config.ServerConfig;
import com.hbm.entity.mob.EntityTaintCrab;
import com.hbm.entity.mob.EntityCreeperTainted;
import com.hbm.explosion.ExplosionLarge;
@ -19,6 +18,7 @@ import com.hbm.util.ContaminationUtil.HazardType;
import cpw.mods.fml.relauncher.ReflectionHelper;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.passive.EntityCow;
@ -107,17 +107,15 @@ public class HbmPotion extends Potion {
if(!(entity instanceof EntityCreeperTainted) && !(entity instanceof EntityTaintCrab) && entity.worldObj.rand.nextInt(40) == 0)
entity.attackEntityFrom(ModDamageSource.taint, (level + 1));
if(GeneralConfig.enableHardcoreTaint && !entity.worldObj.isRemote) {
if(ServerConfig.TAINT_TRAILS.get() && !entity.worldObj.isRemote) {
int x = (int)(entity.posX - 1);
int y = (int)entity.posY;
int z = (int)(entity.posZ);
int x = (int) Math.floor(entity.posX);
int y = (int) Math.floor(entity.posY);
int z = (int) Math.floor(entity.posZ);
if(entity.worldObj.getBlock(x, y, z)
.isReplaceable(entity.worldObj, x, y, z) &&
BlockTaint.hasPosNeightbour(entity.worldObj, x, y, z)) {
entity.worldObj.setBlock(x, y, z, ModBlocks.taint, 14, 2);
Block b = entity.worldObj.getBlock(x, y - 1, z);
if(y > 1 && b.isNormalCube() && !b.isAir(entity.worldObj, x, y - 1, z)) {
entity.worldObj.setBlock(x, y - 1, z, ModBlocks.taint, 14, 2);
}
}
}

View File

@ -82,6 +82,7 @@ public class BusAnimationSequence {
/** Repeats the previous keyframe for a duration depending on the previous keyframes. Useful for getting different buses to sync up. */
public BusAnimationSequence holdUntil(int end) {
int duration = end - getTotalTime();
//FIXME: holdUntil breaks as soon as the animation speed is not 1
return hold(duration);
}

View File

@ -1,124 +0,0 @@
package com.hbm.render.block;
import com.hbm.blocks.bomb.BlockTaint;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
public class RenderTaintBlock implements ISimpleBlockRenderingHandler {
@Override
public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { }
@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
Tessellator tessellator = Tessellator.instance;
IIcon iicon = block.getIcon(0, world.getBlockMetadata(x, y, z));
if (renderer.hasOverrideBlockTexture())
{
iicon = renderer.overrideBlockTexture;
}
boolean ceil = world.getBlock(x, y + 1, z).isNormalCube();
boolean floor = world.getBlock(x, y - 1, z).isNormalCube();
boolean side1 = world.getBlock(x, y, z + 1).isNormalCube();
boolean side2 = world.getBlock(x - 1, y, z).isNormalCube();
boolean side3 = world.getBlock(x, y, z - 1).isNormalCube();
boolean side4 = world.getBlock(x + 1, y, z).isNormalCube();
tessellator.setBrightness(block.getMixedBrightnessForBlock(renderer.blockAccess, x, y, z));
int l = block.colorMultiplier(renderer.blockAccess, x, y, z);
float f = (float)(l >> 16 & 255) / 255.0F;
float f1 = (float)(l >> 8 & 255) / 255.0F;
float f2 = (float)(l & 255) / 255.0F;
tessellator.setColorOpaque_F(f, f1, f2);
double d3 = (double)iicon.getMinU();
double d4 = (double)iicon.getMinV();
double d0 = (double)iicon.getMaxU();
double d1 = (double)iicon.getMaxV();
double d2 = 0.05D;
renderer.blockAccess.getBlockMetadata(x, y, z);
if (side2)
{
tessellator.addVertexWithUV((double)x + d2, (double)(y + 1), (double)(z + 1), d3, d4);
tessellator.addVertexWithUV((double)x + d2, (double)(y + 0), (double)(z + 1), d3, d1);
tessellator.addVertexWithUV((double)x + d2, (double)(y + 0), (double)(z + 0), d0, d1);
tessellator.addVertexWithUV((double)x + d2, (double)(y + 1), (double)(z + 0), d0, d4);
tessellator.addVertexWithUV((double)x + d2, (double)(y + 1), (double)(z + 0), d0, d4);
tessellator.addVertexWithUV((double)x + d2, (double)(y + 0), (double)(z + 0), d0, d1);
tessellator.addVertexWithUV((double)x + d2, (double)(y + 0), (double)(z + 1), d3, d1);
tessellator.addVertexWithUV((double)x + d2, (double)(y + 1), (double)(z + 1), d3, d4);
}
if (side4)
{
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 0), (double)(z + 1), d0, d1);
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 1), (double)(z + 1), d0, d4);
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 1), (double)(z + 0), d3, d4);
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 0), (double)(z + 0), d3, d1);
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 0), (double)(z + 0), d3, d1);
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 1), (double)(z + 0), d3, d4);
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 1), (double)(z + 1), d0, d4);
tessellator.addVertexWithUV((double)(x + 1) - d2, (double)(y + 0), (double)(z + 1), d0, d1);
}
if (side3)
{
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 0), (double)z + d2, d0, d1);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 1), (double)z + d2, d0, d4);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 1), (double)z + d2, d3, d4);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 0), (double)z + d2, d3, d1);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 0), (double)z + d2, d3, d1);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 1), (double)z + d2, d3, d4);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 1), (double)z + d2, d0, d4);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 0), (double)z + d2, d0, d1);
}
if (side1)
{
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 1), (double)(z + 1) - d2, d3, d4);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 0), (double)(z + 1) - d2, d3, d1);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 0), (double)(z + 1) - d2, d0, d1);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 1), (double)(z + 1) - d2, d0, d4);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 1), (double)(z + 1) - d2, d0, d4);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 0), (double)(z + 1) - d2, d0, d1);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 0), (double)(z + 1) - d2, d3, d1);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 1), (double)(z + 1) - d2, d3, d4);
}
if (ceil)
{
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 1) - d2, (double)(z + 0), d3, d4);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 1) - d2, (double)(z + 1), d3, d1);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 1) - d2, (double)(z + 1), d0, d1);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 1) - d2, (double)(z + 0), d0, d4);
}
if (floor)
{
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 0) + d2, (double)(z + 0), d0, d4);
tessellator.addVertexWithUV((double)(x + 0), (double)(y + 0) + d2, (double)(z + 1), d0, d1);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 0) + d2, (double)(z + 1), d3, d1);
tessellator.addVertexWithUV((double)(x + 1), (double)(y + 0) + d2, (double)(z + 0), d3, d4);
}
return true;
}
@Override
public boolean shouldRender3DInInventory(int modelId) {
return false;
}
@Override
public int getRenderId() {
return BlockTaint.renderID;
}
}

View File

@ -2,6 +2,7 @@ package com.hbm.saveddata.satellites;
import com.hbm.itempool.ItemPoolsSatellite;
import com.hbm.util.WeightedRandomObject;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import java.util.HashMap;
@ -13,15 +14,15 @@ public class SatelliteMiner extends Satellite {
private static final HashMap<Class<? extends SatelliteMiner>, String> CARGO = new HashMap<>();
public long lastOp;
public SatelliteMiner() {
this.satIface = Interfaces.NONE;
}
public void writeToNBT(NBTTagCompound nbt) {
nbt.setLong("lastOp", lastOp);
}
public void readFromNBT(NBTTagCompound nbt) {
lastOp = nbt.getLong("lastOp");
}
@ -42,6 +43,16 @@ public class SatelliteMiner extends Satellite {
return CARGO.get(getClass());
}
/**
* Gets the cargo key for the satellite item. If the item is not a miner satellite null is returned.
* @param satelliteItem - Satellite item
* @return - Returns {@link com.hbm.itempool.ItemPool} key or null if the item is not a mining satellite.
*/
public static String getCargoForItem(Item satelliteItem) {
Class<? extends Satellite> satelliteClass = itemToClass.getOrDefault(satelliteItem, null);
return satelliteClass != null ? CARGO.getOrDefault(satelliteClass, null) : null;
}
static {
registerCargo(SatelliteMiner.class, ItemPoolsSatellite.POOL_SAT_MINER);
}

View File

@ -29,6 +29,7 @@ import io.netty.buffer.ByteBuf;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Callback;
import li.cil.oc.api.machine.Context;
import li.cil.oc.api.network.SimpleComponent;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
@ -42,7 +43,7 @@ import java.util.ArrayList;
import java.util.List;
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")})
public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBMKFluxReceiver, IRBMKLoadable, IInfoProviderEC, CompatHandler.OCComponent {
public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBMKFluxReceiver, IRBMKLoadable, IInfoProviderEC, SimpleComponent, CompatHandler.OCComponent {
// New system!!
// Used for receiving flux (calculating outbound flux/burning rods)

View File

@ -1,17 +1,24 @@
package com.hbm.tileentity.network;
import com.hbm.handler.CompatHandler;
import com.hbm.interfaces.IControlReceiver;
import com.hbm.tileentity.TileEntityLoadedBase;
import com.hbm.util.BufferUtil;
import cpw.mods.fml.common.Optional;
import io.netty.buffer.ByteBuf;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Callback;
import li.cil.oc.api.machine.Context;
import li.cil.oc.api.network.SimpleComponent;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
public class TileEntityRadioTorchBase extends TileEntityLoadedBase implements IControlReceiver {
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")})
public class TileEntityRadioTorchBase extends TileEntityLoadedBase implements IControlReceiver, SimpleComponent, CompatHandler.OCComponent {
/** channel we're broadcasting on/listening to */
public String channel = "";
@ -103,4 +110,31 @@ public class TileEntityRadioTorchBase extends TileEntityLoadedBase implements IC
this.markDirty();
}
@Override
@Optional.Method(modid = "OpenComputers")
public String getComponentName() {
return "radio_torch";
}
@Callback(direct = true, limit = 4, doc = "setChannle(channel: string) -- Set the channel the torch is listening/broadcasting to")
@Optional.Method(modid = "OpenComputers")
public Object[] setChannel(Context context, Arguments args) {
channel = args.checkString(0);
return new Object[] {};
}
@Callback(direct = true, limit = 4, doc = "setPolling(value: boolean) -- Switches state change mode to tick-based polling")
@Optional.Method(modid = "OpenComputers")
public Object[] setPolling(Context context, Arguments args) {
polling = args.checkBoolean(0);
return new Object[] {};
}
@Callback(direct = true, limit = 4, doc = "setCustomMap(value: boolean) -- Switches redstone passthrough to custom signal mapping")
@Optional.Method(modid = "OpenComputers")
public Object[] setCustomMap(Context context, Arguments args) {
customMap = args.checkBoolean(0);
return new Object[] {};
}
}

View File

@ -10,6 +10,7 @@ public class GenNode<N extends NodeNet> {
public N net;
public boolean expired = false;
public boolean recentlyChanged = true;
/** Used for distinguishing the node type when saving it to UNINOS' node map */
public INetworkProvider networkProvider;
public GenNode(INetworkProvider<N> provider, BlockPos... positions) {

View File

@ -0,0 +1,13 @@
package com.hbm.uninos.networkproviders;
import com.hbm.uninos.INetworkProvider;
import api.hbm.fluidmk2.FluidNetMK2;
public class FluidNetProvider implements INetworkProvider<FluidNetMK2> {
@Override
public FluidNetMK2 provideNetwork() {
return new FluidNetMK2();
}
}

View File

@ -4,7 +4,7 @@ import com.hbm.uninos.INetworkProvider;
import api.hbm.energymk2.PowerNetMK2;
public class PowerProvider implements INetworkProvider<PowerNetMK2> {
public class PowerNetProvider implements INetworkProvider<PowerNetMK2> {
@Override
public PowerNetMK2 provideNetwork() {

View File

@ -10,11 +10,14 @@ import java.util.function.Consumer;
import api.hbm.energymk2.IEnergyHandlerMK2;
import api.hbm.energymk2.IEnergyReceiverMK2;
import api.hbm.fluid.IFluidUser;
import api.hbm.recipe.IRecipeRegisterListener;
import com.hbm.blocks.BlockDummyable;
import com.hbm.entity.missile.EntityMissileCustom;
import com.hbm.explosion.ExplosionNukeSmall;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.fluid.tank.FluidTank;
import com.hbm.inventory.recipes.loader.SerializableRecipe;
import com.hbm.items.weapon.ItemCustomMissilePart.WarheadType;
import com.hbm.tileentity.machine.TileEntityDummy;
import com.hbm.tileentity.turret.TileEntityTurretSentry;
@ -186,6 +189,15 @@ public class CompatExternal {
public static void setWarheadLabel(WarheadType type, String label) { type.labelCustom = label; }
public static void setWarheadImpact(WarheadType type, Consumer<EntityMissileCustom> impact) { type.impactCustom = impact; }
public static void setWarheadUpdate(WarheadType type, Consumer<EntityMissileCustom> update) { type.updateCustom = update; }
/**
* Registers an IRecipeRegisterListener to the recipe system. The listener is called every time a SerializableRecipe instance has its recipes loaded, before the
* config files are written, but after the defaults are initialized.
* @param listener
*/
public static void registerRecipeRegisterListener(IRecipeRegisterListener listener) {
SerializableRecipe.additionalListeners.add(listener);
}
public static void compatExamples() {
// Makes all cows be targeted by turrets if player mode is active in addition to the existing rules. Applies to all entities that inherit EntityCow.

View File

@ -0,0 +1,264 @@
package com.hbm.util;
import java.util.Arrays;
import com.hbm.interfaces.Untested;
import com.hbm.inventory.FluidStack;
import com.hbm.inventory.RecipesCommon.*;
import com.hbm.inventory.fluid.FluidType;
import com.hbm.inventory.material.Mats.MaterialStack;
import com.hbm.inventory.recipes.*;
import com.hbm.inventory.recipes.AmmoPressRecipes.AmmoPressRecipe;
import com.hbm.inventory.recipes.ArcFurnaceRecipes.ArcFurnaceRecipe;
import com.hbm.inventory.recipes.ArcWelderRecipes.ArcWelderRecipe;
import com.hbm.inventory.recipes.BreederRecipes.BreederRecipe;
import com.hbm.inventory.recipes.CrucibleRecipes.CrucibleRecipe;
import com.hbm.inventory.recipes.CrystallizerRecipes.CrystallizerRecipe;
import com.hbm.inventory.recipes.ElectrolyserFluidRecipes.ElectrolysisRecipe;
import com.hbm.inventory.recipes.ElectrolyserMetalRecipes.ElectrolysisMetalRecipe;
import com.hbm.inventory.recipes.ExposureChamberRecipes.ExposureChamberRecipe;
import com.hbm.inventory.recipes.ParticleAcceleratorRecipes.ParticleAcceleratorRecipe;
import com.hbm.inventory.recipes.PedestalRecipes.PedestalExtraCondition;
import com.hbm.inventory.recipes.PedestalRecipes.PedestalRecipe;
import com.hbm.inventory.recipes.PyroOvenRecipes.PyroOvenRecipe;
import com.hbm.inventory.recipes.RotaryFurnaceRecipes.RotaryFurnaceRecipe;
import com.hbm.inventory.recipes.ChemplantRecipes.ChemRecipe;
import com.hbm.inventory.recipes.CompressorRecipes.CompressorRecipe;
import com.hbm.inventory.recipes.SolderingRecipes.SolderingRecipe;
import com.hbm.inventory.recipes.anvil.AnvilRecipes;
import com.hbm.inventory.recipes.anvil.AnvilRecipes.AnvilConstructionRecipe;
import com.hbm.inventory.recipes.anvil.AnvilRecipes.AnvilOutput;
import com.hbm.inventory.recipes.anvil.AnvilRecipes.OverlayType;
import com.hbm.items.machine.ItemStamp.StampType;
import com.hbm.util.Tuple.Pair;
import com.hbm.util.Tuple.Triplet;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
/**
* Public methods for registering recipes. Method signature should never change, only the body to reflect any changes to recipes/machines themselves.
* Recipe creation is either 1:1 with the original SerializableRecipe or even simpler (in the case of the compressor, two FluidStacks instead of a ton of loose numbers).
* Call these with a registered IRecipeRegisterListener, otherwise the recipe loading/reloading will break the custom recipes.
* @author hbm
*/
@Untested
public class CompatRecipeRegistry {
public static void registerPress(StampType stamp, AStack input, ItemStack output) {
PressRecipes.recipes.put(new Pair(input, stamp), output);
}
/** Same loose rules as BlastFurnaceRecipes, valid inputs are Items, Blocks, ItemStacks, ComparableStacks, Strings (for oredict) and DictFrames */
public static void registerBlastFurnace(Object[] inputs, ItemStack output) {
if(inputs.length != 2) return;
BlastFurnaceRecipes.addRecipe(inputs[0], inputs[1], output);
}
public static void registerShredder(AStack input, ItemStack output) {
for(ItemStack allItems : input.extractForNEI()) {
ComparableStack comp = new ComparableStack(allItems);
ShredderRecipes.shredderRecipes.put(comp, output);
}
}
/** Items should strictly be categorized as pcb, topping or solder. An item that is used as a topping in one recipe should not be a pcb in another.
* This is because the soldering station's item IO will automatically place items based on this category, and having items in more than one category would break it. */
public static void registerSoldering(ItemStack output, int time, long power, FluidStack fluid, AStack[] toppings, AStack[] pcb, AStack[] solder) {
SolderingRecipes.recipes.add(new SolderingRecipe(output, time, power, fluid, copyFirst(toppings, 3), copyFirst(pcb, 2), copyFirst(solder, 1)));
}
/** Chemplant recipes need unique IDs, game will crash when an ID collision is detected! */
public static void registerChemplant(int id, String name, int duration, AStack[] inputItems, FluidStack[] inputFluids, ItemStack[] outputItems, FluidStack[] outputFluids) {
ChemRecipe recipe = new ChemRecipe(id, name, duration);
if(inputItems != null) recipe.inputItems(copyFirst(inputItems, 4));
if(inputFluids != null) recipe.inputFluids(copyFirst(inputFluids, 2));
if(outputItems != null) recipe.outputItems(copyFirst(outputItems, 4));
if(outputFluids != null) recipe.outputFluids(copyFirst(outputFluids, 2));
ChemplantRecipes.recipes.add(recipe);
}
/** Either solid or liquid output can be null */
public static void registerCombination(AStack input, ItemStack output, FluidStack fluid) {
if(output == null && fluid == null) return;
Object o = input instanceof OreDictStack ? ((OreDictStack) input).name : input;
CombinationRecipes.recipes.put(o, new Pair(output, fluid));
}
/** Crucible recipes need unique IDs, game will crash when an ID collision is detected! */
public static void registerCrucible(int index, String name, int frequency, ItemStack icon, MaterialStack[] input, MaterialStack[] output) {
CrucibleRecipe recipe = new CrucibleRecipe(index, name, frequency, icon).inputs(input).outputs(output);
CrucibleRecipes.recipes.add(recipe);
}
public static void registerCentrifuge(AStack input, ItemStack[] outputs) {
CentrifugeRecipes.recipes.put(input, copyFirst(outputs, 4));
}
public static void registerCrystallizer(AStack input, ItemStack output, int time, float productivity, FluidStack fluid) {
CrystallizerRecipe recipe = new CrystallizerRecipe(output, time).prod(productivity);
CrystallizerRecipes.registerRecipe(input instanceof OreDictStack ? ((OreDictStack) input).name : input, recipe, fluid);
}
/** Fractions always use 100mB of input fluid per operation. None of the outputs can be null. */
public static void registerFraction(FluidType input, FluidStack[] output) {
if(output.length != 2) return;
FractionRecipes.fractions.put(input, new Pair(output[0], output[1]));
}
/** Cracking always uses 100mB of input fluid and 200mB of steam per operation. None of the outputs can be null. */
public static void registerCracking(FluidType input, FluidStack[] output) {
if(output.length != 2) return;
CrackingRecipes.cracking.put(input, new Pair(output[0], output[1]));
}
/** Reforming always uses 100mB of input fluid per operation. None of the outputs can be null. */
public static void registerReforming(FluidType input, FluidStack[] output) {
output = copyFirst(output, 3);
if(output.length < 3) return;
ReformingRecipes.recipes.put(input, new Triplet(output[0], output[1], output[2]));
}
/** Hydrotreating always uses 100mB of input fluid per operation. None of the outputs can be null. */
public static void registerHydrotreating(FluidType input, FluidStack hydrogen, FluidStack[] output) {
output = copyFirst(output, 2);
if(output.length < 2) return;
HydrotreatingRecipes.recipes.put(input, new Triplet(hydrogen, output[0], output[1]));
}
public static void registerLiquefaction(AStack input, FluidStack output) {
LiquefactionRecipes.recipes.put(input instanceof OreDictStack ? ((OreDictStack) input).name : input, output);
}
public static void registerSolidifying(FluidStack input, ItemStack output) {
SolidificationRecipes.recipes.put(input.type, new Pair(input.fill, output));
}
public static void registerCoker(FluidStack input, ItemStack output, FluidStack fluid) {
CokerRecipes.recipes.put(input.type, new Triplet(input.fill, output, fluid));
}
/** Registers a coker recipe based on the standardized fluid to coke values */
public static void registerCokerAuto(FluidType input, FluidType output) {
CokerRecipes.registerAuto(input, output);
}
public static void registerPyro(FluidStack inputFluid, AStack inputItem, FluidStack outputFluid, ItemStack outputItem, int duration) {
PyroOvenRecipes.recipes.add(new PyroOvenRecipe(duration).in(inputFluid).in(inputItem).out(outputFluid).out(outputItem));
}
/** Registers a pyro oven recipe based on the standardized fluid to solid fuel values */
public static void registerPyroAuto(FluidType input) {
PyroOvenRecipes.registerSFAuto(input);
}
/** Breeding reactor does not handle OreDictStacks */
public static void registerBreeder(ComparableStack input, ItemStack output, int flux) {
BreederRecipes.recipes.put(input, new BreederRecipe(output, flux));
}
public static void registerCyclotron(ComparableStack box, AStack target, ItemStack output, int antimatter) {
CyclotronRecipes.recipes.put(new Pair(box, target), new Pair(output, antimatter));
}
/** Fuel pools do not handle OreDictStacks */
public static void registerFuelPool(ComparableStack input, ItemStack output) {
FuelPoolRecipes.recipes.put(input, output);
}
//TBI mixer
public static void registerOutgasser(AStack input, ItemStack output, FluidStack fluid) {
OutgasserRecipes.recipes.put(input, new Pair(output, fluid));
}
public static void registerCompressor(FluidStack input, FluidStack output, int time) {
CompressorRecipes.recipes.put(new Pair(input.type, input.pressure), new CompressorRecipe(input.fill, output, time));
}
/** Byproduct array can be null, fluid output length must be 2 */
public static void registerElectrolyzerFluid(FluidStack input, FluidStack[] output, ItemStack[] byproduct, int time) {
output = copyFirst(output, 2);
if(output.length < 2) return;
if(byproduct != null) byproduct = copyFirst(byproduct, 3);
ElectrolyserFluidRecipes.recipes.put(input.type, new ElectrolysisRecipe(input.fill, output[0], output[1], time, byproduct));
}
/** Output array length must be 2, outputs can be null. Byproduct array can be null. */
public static void registerElectrolyzerMetal(AStack input, MaterialStack[] output, ItemStack[] byproduct, int time) {
output = copyFirst(output, 2);
if(byproduct != null) byproduct = copyFirst(byproduct, 6);
ElectrolyserMetalRecipes.recipes.put(input, new ElectrolysisMetalRecipe(output[0], output[1], time, byproduct));
}
public static void registerArcWelder(ItemStack output, int time, long power, FluidStack fluid, AStack[] inputs) {
ArcWelderRecipes.recipes.add(new ArcWelderRecipe(output, time, power, fluid, copyFirst(inputs, 3)));
}
public static void registerRotaryFurnace(MaterialStack output, int time, int steam, FluidStack fluid, AStack[] inputs) {
RotaryFurnaceRecipes.recipes.add(new RotaryFurnaceRecipe(output, time, steam, fluid, copyFirst(inputs, 3)));
}
/** Particles will always perform 8 recipes */
public static void registerExposureChamber(AStack particle, AStack input, ItemStack output) {
ExposureChamberRecipes.recipes.add(new ExposureChamberRecipe(particle, input, output));
}
/** Input needs two AStacks, output can take 1-2 ItemStacks. If the same recipe with different
* momentum should yield different results, register the lower momentum recipes first. */
public static void registerParticleAccelerator(AStack[] input, int momentum, ItemStack[] output) {
input = copyFirst(input, 2);
if(input.length < 2) return;
output = copyFirst(output, 2);
if(output.length < 1) return;
ParticleAcceleratorRecipes.recipes.add(new ParticleAcceleratorRecipe(input[0], input[1], momentum, output[0], output.length > 1 ? output[1] : null));
}
public static void registerAmmoPress(ItemStack output, AStack[] input) {
if(input.length != 9) return;
AmmoPressRecipes.recipes.add(new AmmoPressRecipe(output, input));
}
public static void registerAssembler(ItemStack output, AStack[] input, int time) {
AssemblerRecipes.makeRecipe(new ComparableStack(output), copyFirst(input, 12), time);
}
/** Registers an assembler recipe but with the template only being obtainable via the specified folders */
public static void registerAssembler(ItemStack output, AStack[] input, int time, Item... folder) {
AssemblerRecipes.makeRecipe(new ComparableStack(output), copyFirst(input, 12), time, folder);
}
public static void registerAnvilConstruction(AStack[] input, AnvilOutput[] output, int tier, int overlayIndex) {
AnvilRecipes.constructionRecipes.add(new AnvilConstructionRecipe(input, output).setTier(tier).setOverlay(EnumUtil.grabEnumSafely(OverlayType.class, overlayIndex)));
}
public static void registerAnvilConstruction(AStack[] input, AnvilOutput[] output, int tierLower, int tierUpper, int overlayIndex) {
AnvilRecipes.constructionRecipes.add(new AnvilConstructionRecipe(input, output).setTierRange(tierLower, tierUpper).setOverlay(EnumUtil.grabEnumSafely(OverlayType.class, overlayIndex)));
}
public static void registerPedestal(ItemStack output, AStack[] input) {
registerPedestal(output, input, 0);
}
public static void registerPedestal(ItemStack output, AStack[] input, int condition) {
input = copyFirst(input, 9);
if(input.length < 9) return;
PedestalRecipes.recipes.add(new PedestalRecipe(output, input).extra(EnumUtil.grabEnumSafely(PedestalExtraCondition.class, condition)));
}
/** Either output or fluid can be null */
public static void registerArcFurnace(AStack input, ItemStack output, MaterialStack fluid) {
if(output == null && fluid == null) return;
ArcFurnaceRecipes.recipeList.add(new Pair(input, new ArcFurnaceRecipe().solid(output).fluid(fluid)));
}
/////////////////////////////////////////////////////////////////////////////////////////
/** If the supplied array exceeds the specified length, creates a copy and trunkates the array. Otherwise, returns the original array */
private static <T> T[] copyFirst(T[] array, int amount) {
if(array.length <= amount) return array;
return Arrays.copyOf(array, amount);
}
}

View File

@ -3,6 +3,8 @@ package com.hbm.util;
import java.lang.reflect.Method;
import java.util.List;
import com.hbm.config.ServerConfig;
import cpw.mods.fml.relauncher.ReflectionHelper;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
@ -21,7 +23,8 @@ import net.minecraftforge.common.ForgeHooks;
public class EntityDamageUtil {
public static boolean attackEntityFromIgnoreIFrame(Entity victim, DamageSource src, float damage) {
/** Shitty hack, if the first attack fails, it retries with damage + previous damage, allowing damage to penetrate */
@Deprecated public static boolean attackEntityFromIgnoreIFrame(Entity victim, DamageSource src, float damage) {
if(!victim.attackEntityFrom(src, damage)) {
@ -38,6 +41,7 @@ public class EntityDamageUtil {
}
}
/** New and improved entity damage calc - only use this one */
public static boolean attackEntityFromNT(EntityLivingBase living, DamageSource source, float amount, boolean ignoreIFrame, boolean allowSpecialCancel, double knockbackMultiplier, float pierceDT, float pierce) {
if(living instanceof EntityPlayerMP && source.getEntity() instanceof EntityPlayer) {
EntityPlayerMP playerMP = (EntityPlayerMP) living;
@ -45,14 +49,55 @@ public class EntityDamageUtil {
if(!playerMP.canAttackPlayer(attacker)) return false; //handles wack-ass no PVP rule as well as scoreboard friendly fire
}
DamageResistanceHandler.setup(pierceDT, pierce);
living.attackEntityFrom(source, 0F);
boolean ret = attackEntityFromNTInternal(living, source, amount, ignoreIFrame, allowSpecialCancel, knockbackMultiplier);
//boolean ret = living.attackEntityFrom(source, amount);
DamageResistanceHandler.reset();
return ret;
}
private static boolean attackEntityFromNTInternal(EntityLivingBase living, DamageSource source, float amount, boolean ignoreIFrame, boolean allowSpecialCancel, double knockbackMultiplier) {
boolean superCompatibility = ServerConfig.DAMAGE_COMPATIBILITY_MODE.get();
return superCompatibility
? attackEntitySuperCompatibility(living, source, amount, ignoreIFrame, allowSpecialCancel, knockbackMultiplier)
: attackEntitySEDNAPatch(living, source, amount, ignoreIFrame, allowSpecialCancel, knockbackMultiplier);
}
/**
* MK2 SEDNA damage system, currently untested. An even hackier, yet more compatible solution using the vanilla damage calc directly but tweaking certain apsects.
* Limitation: Does not apply DR piercing to vanilla armor
*/
private static boolean attackEntitySuperCompatibility(EntityLivingBase living, DamageSource source, float amount, boolean ignoreIFrame, boolean allowSpecialCancel, double knockbackMultiplier) {
//disable iframes
if(ignoreIFrame) { living.lastDamage = 0F; living.hurtResistantTime = 0; }
//cache last velocity
double motionX = living.motionX;
double motionY = living.motionX;
double motionZ = living.motionX;
//bam!
boolean ret = living.attackEntityFrom(source, amount);
//restore last velocity
living.motionX = motionX;
living.motionY = motionY;
living.motionZ = motionZ;
//apply own knockback
Entity entity = source.getEntity();
if(entity != null) {
double deltaX = entity.posX - living.posX;
double deltaZ;
for(deltaZ = entity.posZ - living.posZ; deltaX * deltaX + deltaZ * deltaZ < 1.0E-4D; deltaZ = (Math.random() - Math.random()) * 0.01D) {
deltaX = (Math.random() - Math.random()) * 0.01D;
}
living.attackedAtYaw = (float) (Math.atan2(deltaZ, deltaX) * 180.0D / Math.PI) - living.rotationYaw;
if(knockbackMultiplier > 0) knockBack(living, entity, amount, deltaX, deltaZ, knockbackMultiplier);
}
return ret;
}
/** MK1 SEDNA damage system, basically re-implements the vanilla code (only from Entity, child class code is effectively ignored) with some adjustments */
private static boolean attackEntitySEDNAPatch(EntityLivingBase living, DamageSource source, float amount, boolean ignoreIFrame, boolean allowSpecialCancel, double knockbackMultiplier) {
living.attackEntityFrom(source, 0F);
if(ignoreIFrame) living.lastDamage = 0F;
if(ForgeHooks.onLivingAttack(living, source, amount) && allowSpecialCancel) return false;
if(living.isEntityInvulnerable()) return false;
if(living.worldObj.isRemote) return false;
@ -183,9 +228,7 @@ public class EntityDamageUtil {
return amount;
}
public static void damageArmorNT(EntityLivingBase living, float amount) {
}
public static void damageArmorNT(EntityLivingBase living, float amount) { }
/** Currently just a copy of the vanilla damage code */
@Deprecated public static boolean attackEntityFromNT(EntityLivingBase living, DamageSource source, float amount) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

Some files were not shown because too many files have changed in this diff Show More