1.12: ModBlocks class renamed to ModContent. Mineal Smelter released. Window sub models stripped (issue #19). Block opacity of full blocks fixed (issue #50). Factory Dropper continuous mode added (issue #51). Experimental features added.

This commit is contained in:
stfwi 2019-09-10 18:14:42 +02:00
parent 64186ec813
commit 462e14166c
104 changed files with 3812 additions and 158 deletions

View file

@ -10,11 +10,11 @@
* Note: Straight forward definition of different blocks/entities
* to make recipes, models and texture definitions easier.
*/
package wile.engineersdecor.blocks;
package wile.engineersdecor;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModAuxiliaries;
import wile.engineersdecor.detail.ModConfig;
import wile.engineersdecor.detail.*;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.items.*;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
@ -35,7 +35,7 @@ import java.util.Collections;
import javax.annotation.Nonnull;
@SuppressWarnings("unused")
public class ModBlocks
public class ModContent
{
//--------------------------------------------------------------------------------------------------------------------
//-- Blocks
@ -73,6 +73,8 @@ public class ModBlocks
public static final BlockDecorGlassBlock PANZERGLASS_BLOCK = new BlockDecorGlassBlock("panzerglass_block", 0, Material.GLASS, 1f, 2000f, SoundType.GLASS);
public static final BlockDecorSlab PANZERGLASS_SLAB = new BlockDecorSlab("panzerglass_slab", BlockDecor.CFG_TRANSLUCENT, Material.GLASS, 1f, 2000f, SoundType.GLASS);
public static final BlockDecorFull TREATED_WOOD_FLOOR = new BlockDecorFull("treated_wood_floor", 0, Material.WOOD, 0.5f, 10f, SoundType.WOOD);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorCraftingTable TREATED_WOOD_CRAFTING_TABLE = new BlockDecorCraftingTable(
@ -85,7 +87,7 @@ public class ModBlocks
public static final BlockDecorFurnace SMALL_LAB_FURNACE = new BlockDecorFurnace(
"small_lab_furnace",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|
BlockDecor.CFG_ELECTRICAL,
BlockDecor.CFG_ELECTRICAL,
Material.IRON, 0.5f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15,16)
);
@ -118,12 +120,26 @@ public class ModBlocks
ModAuxiliaries.getPixeledAABB(1.1,0,1.1, 14.9,16,14.9)
);
public static final BlockDecorSolarPanel SMALL_SOLAR_PANEL = new BlockDecorSolarPanel(
"small_solar_panel",
BlockDecor.CFG_LOOK_PLACEMENT,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,11.5,16)
);
public static final BlockDecorTreeCutter SMALL_TREE_CUTTER = new BlockDecorTreeCutter(
"small_tree_cutter",
BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,8,16)
);
//--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT,
BlockDecor.CFG_CUTOUT,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
@ -131,7 +147,7 @@ public class ModBlocks
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve_redstone",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED,
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
@ -139,7 +155,7 @@ public class ModBlocks
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = new BlockDecorPipeValve(
"straight_pipe_valve_redstone_analog",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED|BlockDecor.CFG_ANALOG,
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_REDSTONE_CONTROLLED|BlockDecor.CFG_ANALOG,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(4,4,0, 12,12,16)
);
@ -147,7 +163,7 @@ public class ModBlocks
public static final BlockDecorPassiveFluidAccumulator PASSIVE_FLUID_ACCUMULATOR = new BlockDecorPassiveFluidAccumulator(
"passive_fluid_accumulator",
BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|
BlockDecor.CFG_CUTOUT,
BlockDecor.CFG_CUTOUT,
Material.IRON, 0.7f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
);
@ -408,8 +424,16 @@ public class ModBlocks
BlockDecorMineralSmelter.BTileEntity.class, "te_small_mineral_smelter"
);
private static final TileEntityRegistrationData SMALL_SOLAR_PANEL_TEI = new TileEntityRegistrationData(
BlockDecorSolarPanel.BTileEntity.class, "te_small_solar_panel"
);
private static final TileEntityRegistrationData SMALL_TREE_CUTTER_TEI = new TileEntityRegistrationData(
BlockDecorTreeCutter.BTileEntity.class, "te_small_tree_cutter"
);
//--------------------------------------------------------------------------------------------------------------------
//-- Registration list
//-- Block registration list
//--------------------------------------------------------------------------------------------------------------------
private static final Object content[] = {
@ -420,6 +444,7 @@ public class ModBlocks
SMALL_WASTE_INCINERATOR, WASTE_INCINERATOR_TEI,
STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE, STRAIGHT_PIPE_VALVE_TEI,
PASSIVE_FLUID_ACCUMULATOR, PASSIVE_FLUID_ACCUMULATOR_TEI,
SMALL_MINERAL_SMELTER, SMALL_MINERAL_SMELTER_TEI,
CLINKER_BRICK_BLOCK,
CLINKER_BRICK_SLAB,
CLINKER_BRICK_STAIRS,
@ -467,11 +492,47 @@ public class ModBlocks
};
private static final Object dev_content[] = {
SMALL_MINERAL_SMELTER, SMALL_MINERAL_SMELTER_TEI,
PANZERGLASS_SLAB, // check if another class is needed due to is_side_visible
SIGN_MINDSTEP,
PANZERGLASS_SLAB, // @todo: check if another class is needed due to is_side_visible
SMALL_SOLAR_PANEL,SMALL_SOLAR_PANEL_TEI, // @todo: check power tuning <= Peltier generator
TREATED_WOOD_FLOOR, // @todo: check if textures need improvement
SMALL_TREE_CUTTER,SMALL_TREE_CUTTER_TEI, // @todo: test
};
//--------------------------------------------------------------------------------------------------------------------
//-- Items
//--------------------------------------------------------------------------------------------------------------------
private static final Item[] modItems = {
};
private static final ArrayList<Item> registeredItems = new ArrayList<>();
@Nonnull
public static List<Item> getRegisteredItems()
{ return Collections.unmodifiableList(registeredItems); }
public static final void registerItems(RegistryEvent.Register<Item> event)
{
// Config based registry selection
int num_registrations_skipped = 0;
ArrayList<Item> allItems = new ArrayList<>();
Collections.addAll(allItems, modItems);
final boolean woor = ModConfig.isWithoutOptOutRegistration();
for(Item e:allItems) {
if((!woor) || (!ModConfig.isOptedOut(e))) {
registeredItems.add(e);
} else {
++num_registrations_skipped;
}
}
for(Item e:registeredItems) event.getRegistry().register(e);
ModEngineersDecor.logger.info("Registered " + Integer.toString(registeredItems.size()) + " items.");
if(num_registrations_skipped > 0) {
ModEngineersDecor.logger.info("Skipped registration of " + num_registrations_skipped + " items.");
}
}
//--------------------------------------------------------------------------------------------------------------------
//-- Init
//--------------------------------------------------------------------------------------------------------------------
@ -531,6 +592,9 @@ public class ModBlocks
for(Block e:registeredBlocks) {
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(e), 0, new ModelResourceLocation(e.getRegistryName(), "inventory"));
}
for(Item e:registeredItems) {
if(e instanceof ItemDecor) ((ItemDecor)e).initModel();
}
}
// Invoked from CommonProxy.registerItems()

View file

@ -10,7 +10,6 @@ package wile.engineersdecor;
import wile.engineersdecor.detail.*;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.items.*;
import net.minecraft.world.World;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.client.multiplayer.WorldClient;
@ -124,11 +123,11 @@ public class ModEngineersDecor
{
@SubscribeEvent
public static void registerBlocks(final RegistryEvent.Register<Block> event)
{ ModBlocks.registerBlocks(event); }
{ ModContent.registerBlocks(event); }
@SubscribeEvent
public static void registerItems(final RegistryEvent.Register<Item> event)
{ ModBlocks.registerItemBlocks(event); ModItems.registerItems(event); }
{ ModContent.registerItemBlocks(event); ModContent.registerItems(event); }
@SubscribeEvent
public static void registerRecipes(RegistryEvent.Register<IRecipe> event)
@ -137,14 +136,14 @@ public class ModEngineersDecor
@SideOnly(Side.CLIENT)
@SubscribeEvent
public static void registerModels(final ModelRegistryEvent event)
{ ModBlocks.initModels(); ModItems.initModels(); }
{ ModContent.initModels(); }
}
public static final CreativeTabs CREATIVE_TAB_ENGINEERSDECOR = (new CreativeTabs("tabengineersdecor") {
@Override
@SideOnly(Side.CLIENT)
public @Nonnull ItemStack createIcon()
{ return new ItemStack(ModBlocks.SIGN_MODLOGO); }
{ return new ItemStack(ModContent.SIGN_MODLOGO); }
});
//--------------------------------------------------------------------------------------------------------------------

View file

@ -37,6 +37,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public class BlockDecor extends Block
{
@ -77,9 +78,8 @@ public class BlockDecor extends Block
setHardness((hardness > 0) ? hardness : 5.0f);
setResistance((resistance > 0) ? resistance : 10.0f);
setSoundType((sound==null) ? SoundType.STONE : sound);
setLightOpacity(0);
// @todo double check that instance variable
// not sure here ... if((config & CFG_TRANSLUCENT) != 0) this.translucent = true;
if(((config & (CFG_CUTOUT|CFG_TRANSLUCENT))!=0)) setLightOpacity(0);
if((config & CFG_TRANSLUCENT) != 0) this.translucent = true;
this.config = config;
this.aabb = boundingboxes;
}
@ -192,5 +192,4 @@ public class BlockDecor extends Block
@SuppressWarnings("deprecation")
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos)
{}
}

View file

@ -248,7 +248,7 @@ public class BlockDecorDropper extends BlockDecorDirected
Networking.PacketTileNotify.sendToServer(te, nbt);
} else if(isPointInRegion(162, 66, 7, 9, mouseX, mouseY)) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("manual_trigger", 1);
nbt.setInteger("drop_logic", container.fields_[5] ^ BTileEntity.DROPLOGIC_CONTINUOUS);
Networking.PacketTileNotify.sendToServer(te, nbt);
} else if(isPointInRegion(132, 66, 9, 9, mouseX, mouseY)) {
NBTTagCompound nbt = new NBTTagCompound();
@ -322,8 +322,10 @@ public class BlockDecorDropper extends BlockDecorDirected
{
int filter_gate_offset = ((container.fields_[5] & BTileEntity.DROPLOGIC_FILTER_ANDGATE) != 0) ? 11 : 0;
int extern_gate_offset = ((container.fields_[5] & BTileEntity.DROPLOGIC_EXTERN_ANDGATE) != 0) ? 11 : 0;
int pulse_mode_offset = ((container.fields_[5] & BTileEntity.DROPLOGIC_CONTINUOUS ) != 0) ? 10 : 0;
drawTexturedModalRect(x0+132, y0+66, 179+filter_gate_offset, 66, 9, 9);
drawTexturedModalRect(x0+148, y0+66, 179+extern_gate_offset, 66, 9, 9);
drawTexturedModalRect(x0+162, y0+66, 200+pulse_mode_offset, 66, 9, 9);
}
// drop timer running indicator
{
@ -456,10 +458,11 @@ public class BlockDecorDropper extends BlockDecorDirected
public static final int MAX_DROP_COUNT = 32;
public static final int DROP_PERIOD_OFFSET = 10;
///
public static final int DROPLOGIC_FILTER_ANDGATE = 0x1;
public static final int DROPLOGIC_EXTERN_ANDGATE = 0x2;
public static final int DROPLOGIC_SILENT_DROP = 0x4;
public static final int DROPLOGIC_SILENT_OPEN = 0x8;
public static final int DROPLOGIC_FILTER_ANDGATE = 0x01;
public static final int DROPLOGIC_EXTERN_ANDGATE = 0x02;
public static final int DROPLOGIC_SILENT_DROP = 0x04;
public static final int DROPLOGIC_SILENT_OPEN = 0x08;
public static final int DROPLOGIC_CONTINUOUS = 0x10;
///
private int filter_matches_[] = new int[CTRL_SLOTS_SIZE];
private int open_timer_ = 0;
@ -799,8 +802,10 @@ public class BlockDecorDropper extends BlockDecorDirected
if(--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
boolean dirty = block_power_updated_;
boolean redstone_trigger = (block_power_signal_ && block_power_updated_);
final boolean continuous_mode = (drop_logic_ & DROPLOGIC_CONTINUOUS)!=0;
boolean redstone_trigger = (block_power_signal_ && ((block_power_updated_) || (continuous_mode)));
boolean filter_trigger;
boolean filter_defined = false;
boolean trigger;
// Trigger logic
{
@ -808,9 +813,9 @@ public class BlockDecorDropper extends BlockDecorDirected
for(int i=INPUT_SLOTS_FIRST; i<(INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE); ++i) {
if(stacks_.get(i).getCount() >= drop_count_) { droppable_slot_found = true; break; }
}
int filter_nset = 0;
// From filters / inventory checks
{
int filter_nset = 0;
int last_filter_matches_[] = filter_matches_.clone();
boolean slot_assigned = false;
for(int ci=0; ci<CTRL_SLOTS_SIZE; ++ci) {
@ -836,12 +841,13 @@ public class BlockDecorDropper extends BlockDecorDirected
if(filter_matches_[i] > 1) ++nmatched;
if(filter_matches_[i] != last_filter_matches_[i]) dirty = true;
}
filter_trigger = ((filter_nset >0) && (nmatched > 0));
filter_defined = (filter_nset > 0);
filter_trigger = ((filter_nset > 0) && (nmatched > 0));
if(((drop_logic_ & DROPLOGIC_FILTER_ANDGATE) != 0) && (nmatched != filter_nset)) filter_trigger = false;
}
// gates
{
if(filter_nset > 0) {
if(filter_defined) {
trigger = ((drop_logic_ & DROPLOGIC_EXTERN_ANDGATE) != 0) ? (filter_trigger && redstone_trigger) : (filter_trigger || redstone_trigger);
} else {
trigger = redstone_trigger;

View file

@ -54,4 +54,8 @@ public class BlockDecorFull extends BlockDecor
public boolean isNormalCube(IBlockState state)
{ return true; }
@Override
public int getLightValue(IBlockState state, IBlockAccess world, BlockPos pos)
{ return (int)((config & CFG_LIGHT_VALUE_MASK) >> CFG_LIGHT_VALUE_SHIFT); }
}

View file

@ -15,6 +15,7 @@ import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.util.EnumHand;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.material.Material;
@ -108,9 +109,9 @@ public class BlockDecorHorizontalSupport extends BlockDecor
final EnumFacing dfacing = dstate.getValue(BlockDecorStraightPole.FACING);
final BlockDecorStraightPole pole = (BlockDecorStraightPole)dstate.getBlock();
if((dfacing.getAxis() == EnumFacing.Axis.Y)) {
if((pole==ModBlocks.THICK_STEEL_POLE) || ((pole==ModBlocks.THICK_STEEL_POLE_HEAD) && (dfacing==EnumFacing.UP))) {
if((pole==ModContent.THICK_STEEL_POLE) || ((pole==ModContent.THICK_STEEL_POLE_HEAD) && (dfacing==EnumFacing.UP))) {
down_connector = 2;
} else if((pole==ModBlocks.THIN_STEEL_POLE) || ((pole==ModBlocks.THIN_STEEL_POLE_HEAD) && (dfacing==EnumFacing.UP))) {
} else if((pole==ModContent.THIN_STEEL_POLE) || ((pole==ModContent.THIN_STEEL_POLE_HEAD) && (dfacing==EnumFacing.UP))) {
down_connector = 1;
}
}

View file

@ -0,0 +1,177 @@
/*
* @file BlockDecorDirected.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Smaller (cutout) block with a defined facing.
*/
package wile.engineersdecor.blocks;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.SoundType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.world.World;
import net.minecraft.world.IBlockAccess;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BlockDecorSolarPanel extends BlockDecor
{
public static final PropertyInteger EXPOSITION = PropertyInteger.create("exposition", 0, 4);
public BlockDecorSolarPanel(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB)
{ super(registryName, config, material, hardness, resistance, sound, unrotatedAABB); }
@Override
public boolean isOpaqueCube(IBlockState state)
{ return false; }
@Override
public boolean isFullCube(IBlockState state)
{ return false; }
@Override
public boolean isNormalCube(IBlockState state)
{ return false; }
@Override
public boolean canCreatureSpawn(IBlockState state, IBlockAccess world, BlockPos pos, net.minecraft.entity.EntityLiving.SpawnPlacementType type)
{ return false; }
@Override
public int getLightValue(IBlockState state, IBlockAccess world, BlockPos pos)
{ return 0; }
@Override
public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face)
{ return BlockFaceShape.UNDEFINED; }
@Override
public IBlockState getStateFromMeta(int meta)
{ return this.getDefaultState().withProperty(EXPOSITION, (meta & 0x7)); }
@Override
public int getMetaFromState(IBlockState state)
{ return state.getValue(EXPOSITION); }
@Override
protected BlockStateContainer createBlockState()
{ return new BlockStateContainer(this, EXPOSITION); }
@Override
public boolean canPlaceBlockOnSide(World world, BlockPos pos, EnumFacing side)
{ return super.canPlaceBlockOnSide(world, pos, side); }
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand)
{ return getDefaultState().withProperty(EXPOSITION, 0); }
@Override
public boolean hasTileEntity(IBlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(World world, IBlockState state)
{ return new BlockDecorSolarPanel.BTileEntity(); }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickable
{
public static final int DEFAULT_PEAK_POWER = 45;
public static final int TICK_INTERVAL = 8;
public static final int ACCUMULATION_INTERVAL = 4;
private static final EnumFacing transfer_directions_[] = {EnumFacing.DOWN, EnumFacing.EAST, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.NORTH };
private static int peak_power_per_tick_ = DEFAULT_PEAK_POWER;
private static int max_power_storage_ = 10000;
private int tick_timer_ = 0;
private int recalc_timer_ = 0;
private int accumulated_power_ = 0;
public static void on_config(int peak_power_per_tick)
{
peak_power_per_tick_ = peak_power_per_tick;
ModEngineersDecor.logger.info("Config small solar panel: Peak production:" + peak_power_per_tick_ + "/tick");
}
//------------------------------------------------------------------------------------------------------------------
public BTileEntity()
{}
public void readnbt(NBTTagCompound nbt, boolean update_packet)
{ accumulated_power_ = nbt.getInteger("energy"); }
protected void writenbt(NBTTagCompound nbt, boolean update_packet)
{ nbt.setInteger("energy", accumulated_power_); }
// TileEntity ------------------------------------------------------------------------------
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorSolarPanel)); }
@Override
public void readFromNBT(NBTTagCompound nbt)
{ super.readFromNBT(nbt); readnbt(nbt, false); }
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{ super.writeToNBT(nbt); writenbt(nbt, false); return nbt; }
@Override
public void update()
{
if((world.isRemote) || (--tick_timer_ > 0)) return;
tick_timer_ = TICK_INTERVAL;
if(!world.canSeeSky(pos)) { tick_timer_ = TICK_INTERVAL * 5; return; }
if(accumulated_power_ > 0) {
for(int i=0; (i<transfer_directions_.length) && (accumulated_power_>0); ++i) {
final EnumFacing f = transfer_directions_[i];
TileEntity te = world.getTileEntity(pos.offset(f));
if((te==null) || (!(te.hasCapability(CapabilityEnergy.ENERGY, f.getOpposite())))) continue;
IEnergyStorage es = te.getCapability(CapabilityEnergy.ENERGY, f.getOpposite());
if(!es.canReceive()) continue;
accumulated_power_ = MathHelper.clamp(accumulated_power_-es.receiveEnergy(accumulated_power_, false),0, accumulated_power_);
}
}
if(--recalc_timer_ > 0) return;
recalc_timer_ = ACCUMULATION_INTERVAL + ((int)(Math.random()+.5));
IBlockState state = world.getBlockState(pos);
int theta = ((((int)(world.getCelestialAngleRadians(1f) * (180.0/Math.PI)))+90) % 360);
int e = 2;
if(theta > 340) e = 2;
else if(theta < 45) e = 0;
else if(theta < 80) e = 1;
else if(theta < 100) e = 2;
else if(theta < 135) e = 3;
else if(theta < 190) e = 4;
IBlockState nstate = state.withProperty(EXPOSITION, e);
if(nstate != state) world.setBlockState(pos, nstate, 1|2);
double rf = Math.abs(1.0-(((double)Math.abs(MathHelper.clamp(theta, 0, 180)-90))/90));
rf = Math.sqrt(rf) * world.getSunBrightnessFactor(1f) * ((TICK_INTERVAL*ACCUMULATION_INTERVAL)+2) * peak_power_per_tick_;
accumulated_power_ = Math.min(accumulated_power_+(int)rf, max_power_storage_);
}
}
}

View file

@ -0,0 +1,209 @@
/*
* @file BlockFurnace.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* ED Lab furnace.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.TreeCutting;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.world.World;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.*;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Random;
public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
{
public static final PropertyBool ACTIVE = PropertyBool.create("active");
public BlockDecorTreeCutter(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB)
{
super(registryName, config, material, hardness, resistance, sound, unrotatedAABB);
setLightOpacity(0);
}
@Override
protected BlockStateContainer createBlockState()
{ return new BlockStateContainer(this, FACING, ACTIVE); }
@Override
public IBlockState getStateFromMeta(int meta)
{ return getDefaultState().withProperty(FACING, EnumFacing.byHorizontalIndex(meta & 0x3)).withProperty(ACTIVE, (meta & 0x4)!=0); }
@Override
public int getMetaFromState(IBlockState state)
{ return (state.getValue(FACING).getHorizontalIndex() & 0x3) | (state.getValue(ACTIVE) ? 4 : 0); }
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand)
{ return super.getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, hand).withProperty(ACTIVE, false); }
@Override
public boolean hasTileEntity(IBlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(World world, IBlockState state)
{ return new BlockDecorTreeCutter.BTileEntity(); }
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random rnd)
{
if((state.getBlock()!=this) || (!state.getValue(ACTIVE))) return;
final double rv = rnd.nextDouble();
if(rv > 0.8) return;
final double x=0.5+pos.getX(), y=0.5+pos.getY(), z=0.5+pos.getZ();
final double xc=0.52, xr=rnd.nextDouble()*0.4-0.2, yr=(y-0.3+rnd.nextDouble()*0.2);
switch(state.getValue(FACING)) {
case WEST: world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x-xc, yr, z+xr, 0.0, 0.0, 0.0); break;
case EAST: world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x+xc, yr, z+xr, 0.0, 0.0, 0.0); break;
case NORTH: world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x+xr, yr, z-xc, 0.0, 0.0, 0.0); break;
default: world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, x+xr, yr, z+xc, 0.0, 0.0, 0.0); break;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickable, IEnergyStorage
{
public static final int IDLE_TICK_INTERVAL = 40;
public static final int TICK_INTERVAL = 5;
public static final int BOOST_FACTOR = 6;
public static final int DEFAULT_BOOST_ENERGY = 64;
public static final int DEFAULT_CUTTING_TIME_NEEDED = 20 * 60; // 60 secs, so that people don't come to the bright idea to carry one with them.
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY;
private static int cutting_time_needed = DEFAULT_CUTTING_TIME_NEEDED;
private int tick_timer_;
private int proc_time_elapsed_; // small, not saved in nbt.
private int boost_energy_; // small, not saved in nbt.
public static void on_config(int boost_energy_per_tick)
{
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
ModEngineersDecor.logger.info("Config tree cutter: Boost energy consumption:" + boost_energy_consumption + "rf/t");
}
public BTileEntity()
{}
// TileEntity ------------------------------------------------------------------------------
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorTreeCutter)); }
// IEnergyStorage ----------------------------------------------------------------------------
@Override
public boolean canExtract()
{ return false; }
@Override
public boolean canReceive()
{ return true; }
@Override
public int getMaxEnergyStored()
{ return boost_energy_consumption; }
@Override
public int getEnergyStored()
{ return boost_energy_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{ // only speedup support, no buffering, not in nbt -> no markdirty
if((boost_energy_ >= boost_energy_consumption) || (maxReceive < boost_energy_consumption)) return 0;
if(!simulate) boost_energy_ = boost_energy_consumption;
return boost_energy_consumption;
}
// Capability export ----------------------------------------------------------------------------
@Override
public boolean hasCapability(Capability<?> cap, EnumFacing facing)
{ return ((cap==CapabilityEnergy.ENERGY)) || super.hasCapability(cap, facing); }
@Override
@SuppressWarnings("unchecked")
@Nullable
public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing)
{
if(capability == CapabilityEnergy.ENERGY) {
return (T)this;
} else {
return super.getCapability(capability, facing);
}
}
// ITickable ------------------------------------------------------------------------------------
@Override
public void update()
{
if(--tick_timer_ > 0) return;
if(world.isRemote) {
if(!world.getBlockState(pos).getValue(ACTIVE)) {
tick_timer_ = TICK_INTERVAL;
} else {
tick_timer_ = 1;
world.playSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BLOCK_WOOD_HIT, SoundCategory.BLOCKS, 0.1f, 1.0f, false);
}
} else {
tick_timer_ = TICK_INTERVAL;
final IBlockState device_state = world.getBlockState(pos);
final BlockPos tree_pos = pos.offset(device_state.getValue(FACING));
final IBlockState tree_state = world.getBlockState(tree_pos);
if(!TreeCutting.canChop(tree_state) || (world.isBlockPowered(pos))) {
if(device_state.getValue(ACTIVE)) world.setBlockState(pos, device_state.withProperty(ACTIVE, false), 1|2);
proc_time_elapsed_ = 0;
tick_timer_ = IDLE_TICK_INTERVAL;
return;
}
proc_time_elapsed_ += TICK_INTERVAL;
if(boost_energy_ >= boost_energy_consumption) { boost_energy_ = 0; proc_time_elapsed_ += TICK_INTERVAL*BOOST_FACTOR; }
boolean active = true;
if(proc_time_elapsed_ >= cutting_time_needed) {
proc_time_elapsed_ = 0;
TreeCutting.chopTree(world, tree_state, tree_pos, 512, false);
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BLOCK_WOOD_BREAK, SoundCategory.BLOCKS, 1.0f, 1.0f);
active = false;
}
if(device_state.getValue(ACTIVE) != active) {
world.setBlockState(pos, device_state.withProperty(ACTIVE, active), 1|2);
}
}
}
}
}

View file

@ -0,0 +1,101 @@
/*
* @file BlockCategories.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Oredict based block category cache.
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.block.*;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class BlockCategories
{
private static Set<Block> logs_ = new HashSet<Block>();
private static Set<Block> leaves_ = new HashSet<Block>();
public static final Set<Block> logs()
{ return logs_; } // wrap in case immutable needed one time.
public static final Set<Block> leaves()
{ return leaves_; }
public static boolean isLog(IBlockState state)
{
final Block block = state.getBlock();
return (block instanceof BlockLog) || (block instanceof BlockNewLog) || (logs().contains(block));
}
public static boolean isLeaves(IBlockState state)
{
if(state.getMaterial()==Material.LEAVES) return true;
final Block block = state.getBlock();
return (block instanceof BlockLeaves) || (leaves().contains(block));
}
public static final boolean isSameLeaves(IBlockState a, IBlockState b)
{ return (a.getBlock() == b.getBlock()); }
public static final boolean isSameLog(IBlockState a, IBlockState b)
{
// very strange ...
if(a.getBlock()!=b.getBlock()) {
return false;
} else if(a.getBlock() instanceof BlockNewLog) {
return a.getValue(BlockNewLog.VARIANT) == b.getValue(BlockNewLog.VARIANT);
} else if(a.getBlock() instanceof BlockOldLog) {
return a.getValue(BlockOldLog.VARIANT) == b.getValue(BlockOldLog.VARIANT);
} else {
// Uagh, that hurts the heart of performance ...
final IProperty<?> prop = a.getPropertyKeys().stream().filter( (IProperty<?> p) -> (p.getName().contains("variant") || p.getName().contains("type"))).findFirst().orElse(null);
if(prop==null) return false;
return a.getValue(prop).equals(b.getValue(prop));
}
}
public static final void reload()
{
{
HashSet<Block> logs = new HashSet<Block>();
for(final String ore_name : OreDictionary.getOreNames()) {
if(!ore_name.startsWith("logWood")) continue;
final List<ItemStack> stacks = OreDictionary.getOres(ore_name, false);
for(ItemStack stack : stacks) {
final Item item = stack.getItem();
if(!(item instanceof ItemBlock)) continue;
logs.add(((ItemBlock)item).getBlock());
}
}
logs_ = logs;
ModEngineersDecor.logger.info("Found "+logs.size()+" types of 'choppable' log.");
}
{
HashSet<Block> leaves = new HashSet<Block>();
for(final String ore_name : OreDictionary.getOreNames()) {
if(!ore_name.startsWith("treeLeaves")) continue;
final List<ItemStack> stacks = OreDictionary.getOres(ore_name, false);
for(ItemStack stack : stacks) {
final Item item = stack.getItem();
if(!(item instanceof ItemBlock)) continue;
leaves.add(((ItemBlock)item).getBlock());
}
}
leaves_ = leaves;
ModEngineersDecor.logger.info("Found "+leaves.size()+" types of leaves.");
}
}
}

View file

@ -9,6 +9,7 @@
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.*;
import net.minecraftforge.common.config.Config;
@ -320,6 +321,17 @@ public class ModConfig
@Config.Name("E-furnace: Power consumption")
@Config.RangeInt(min=10, max=256)
public int e_furnace_power_consumption = BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_ENERGY_CONSUMPTION;
@Config.Comment({
"Defines the peak power production (at noon) of the Small Solar Panel. " +
"Note that the agerage power is much less, as no power is produced at all during the night, " +
"and the power curve is nonlinear rising/falling during the day. Bad weather conditions also " +
"decrease the production. " +
"The config value can be changed on-the-fly for tuning."
})
@Config.Name("Solar panel: Peak power")
@Config.RangeInt(min=5, max=128)
public int solar_panel_peak_power = BlockDecorSolarPanel.BTileEntity.DEFAULT_PEAK_POWER;
}
@SuppressWarnings("unused")
@ -340,7 +352,7 @@ public class ModConfig
@SuppressWarnings("unused")
public static final void onPostInit(FMLPostInitializationEvent event)
{ for(Block e:ModBlocks.getRegisteredBlocks()) ModConfig.isOptedOut(e, true); }
{ for(Block e: ModContent.getRegisteredBlocks()) ModConfig.isOptedOut(e, true); }
private static final ArrayList<String> includes_ = new ArrayList<String>();
private static final ArrayList<String> excludes_ = new ArrayList<String>();
@ -360,7 +372,7 @@ public class ModConfig
public static final boolean isOptedOut(final @Nullable Block block, boolean with_log_details)
{
if((block == null) || (optout==null)) return true;
if(block == ModBlocks.SIGN_MODLOGO) return true;
if(block == ModContent.SIGN_MODLOGO) return true;
if((!zmisc.with_experimental) && (block instanceof ModAuxiliaries.IExperimentalFeature)) return true;
final String rn = block.getRegistryName().getPath();
// Force-include/exclude pattern matching
@ -432,6 +444,7 @@ public class ModConfig
BlockDecorCraftingTable.on_config(optout.without_crafting_table_history, false, tweaks.with_crafting_quickmove_buttons);
BlockDecorPipeValve.on_config(tweaks.pipevalve_max_flowrate, tweaks.pipevalve_redstone_slope);
BlockDecorFurnaceElectrical.BTileEntity.on_config(tweaks.e_furnace_speed_percent, tweaks.e_furnace_power_consumption);
BlockDecorSolarPanel.BTileEntity.on_config(tweaks.solar_panel_peak_power);
{
optout.includes = optout.includes.toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", "");
if(!optout.includes.isEmpty()) ModEngineersDecor.logger.info("Pattern includes: '" + optout.includes + "'");

View file

@ -0,0 +1,168 @@
/*
* @file TreeCutting.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Simple tree cutting algorithm.
*/
package wile.engineersdecor.detail;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.Block;
import net.minecraft.block.BlockVine;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import java.util.*;
public class TreeCutting
{
private static final List<Vec3i> hoffsets = ImmutableList.of(
new Vec3i( 1,0, 0), new Vec3i( 1,0, 1), new Vec3i( 0,0, 1),
new Vec3i(-1,0, 1), new Vec3i(-1,0, 0), new Vec3i(-1,0,-1),
new Vec3i( 0,0,-1), new Vec3i( 1,0,-1)
);
private static List<BlockPos> findBlocksAround(final World world, final BlockPos centerPos, final IBlockState leaf_type_state, final Set<BlockPos> checked, int recursion_left)
{
ArrayList<BlockPos> to_decay = new ArrayList<BlockPos>();
for(int y=-1; y<=1; ++y) {
final BlockPos layer = centerPos.add(0,y,0);
for(Vec3i v:hoffsets) {
BlockPos pos = layer.add(v);
if((!checked.contains(pos)) && BlockCategories.isSameLeaves(leaf_type_state, world.getBlockState(pos))) {
checked.add(pos);
to_decay.add(pos);
if(recursion_left > 0) {
to_decay.addAll(findBlocksAround(world, pos, leaf_type_state, checked, recursion_left-1));
}
}
}
}
return to_decay;
}
public static boolean canChop(IBlockState state)
{ return BlockCategories.isLog(state); }
/**
* Chops a tree, returns the damage that the cutting tool shall take
*/
public static int chopTree(World world, IBlockState broken_state, BlockPos startPos, int max_blocks_to_break, boolean without_target_block)
{
if(!BlockCategories.isLog(broken_state)) return 0;
final long ymin = startPos.getY();
final long max_leaf_distance = 6;
Set<BlockPos> checked = new HashSet<BlockPos>();
ArrayList<BlockPos> to_break = new ArrayList<BlockPos>();
ArrayList<BlockPos> to_decay = new ArrayList<BlockPos>();
checked.add(startPos);
// Initial simple layer-up search of same logs. This forms the base corpus, and only leaves and
// leaf-enclosed logs attached to this corpus may be broken/decayed.
{
LinkedList<BlockPos> queue = new LinkedList<BlockPos>();
LinkedList<BlockPos> upqueue = new LinkedList<BlockPos>();
queue.add(startPos);
int cutlevel = 0;
int steps_left = 64;
while(!queue.isEmpty() && (--steps_left >= 0)) {
final BlockPos pos = queue.removeFirst();
// Vertical search
final BlockPos uppos = pos.up();
final IBlockState upstate = world.getBlockState(uppos);
if(!checked.contains(uppos)) {
checked.add(uppos);
if(BlockCategories.isSameLog(upstate, broken_state)) {
// Up is log
upqueue.add(uppos);
to_break.add(uppos);
steps_left = 64;
} else {
boolean isleaf = BlockCategories.isLeaves(upstate);
if(isleaf || world.isAirBlock(uppos) || (upstate.getBlock() instanceof BlockVine)) {
if(isleaf) to_decay.add(uppos);
// Up is air, check adjacent for diagonal up (e.g. Accacia)
for(Vec3i v:hoffsets) {
final BlockPos p = uppos.add(v);
if(checked.contains(p)) continue;
checked.add(p);
final IBlockState st = world.getBlockState(p);
final Block bl = st.getBlock();
if(BlockCategories.isSameLog(st, broken_state)) {
queue.add(p);
to_break.add(p);
} else if(BlockCategories.isLeaves(st)) {
to_decay.add(p);
}
}
}
}
}
// Lateral search
for(Vec3i v:hoffsets) {
final BlockPos p = pos.add(v);
if(checked.contains(p)) continue;
checked.add(p);
if(p.distanceSq(new BlockPos(startPos.getX(), p.getY(), startPos.getZ())) > (3+cutlevel*cutlevel)) continue;
final IBlockState st = world.getBlockState(p);
final Block bl = st.getBlock();
if(BlockCategories.isSameLog(st, broken_state)) {
queue.add(p);
to_break.add(p);
} else if(BlockCategories.isLeaves(st)) {
to_decay.add(p);
}
}
if(queue.isEmpty() && (!upqueue.isEmpty())) {
queue = upqueue;
upqueue = new LinkedList<BlockPos>();
++cutlevel;
}
}
}
{
// Determine lose logs between the leafs
for(BlockPos pos:to_decay) {
int dist = 1;
to_break.addAll(findBlocksAround(world, pos, broken_state, checked, dist));
}
}
if(!to_decay.isEmpty()) {
final IBlockState leaf_type_state = world.getBlockState(to_decay.get(0));
final ArrayList<BlockPos> leafs = to_decay;
to_decay = new ArrayList<BlockPos>();
for(BlockPos pos:leafs) {
int dist = 2;
to_decay.add(pos);
to_decay.addAll(findBlocksAround(world, pos, leaf_type_state, checked, dist));
}
}
if(without_target_block) {
checked.remove(startPos);
} else {
to_break.add(startPos);
}
int num_broken = 0;
Collections.reverse(to_break);
for(BlockPos pos:to_break) {
if(++num_broken > max_blocks_to_break) break;
IBlockState state = world.getBlockState(pos);
world.setBlockToAir(pos);
state.getBlock().dropBlockAsItem(world, pos, state, 0);
}
for(BlockPos pos:to_decay) {
if(++num_broken > max_blocks_to_break) break;
IBlockState state = world.getBlockState(pos);
world.setBlockToAir(pos);
state.getBlock().dropBlockAsItem(world, pos, state, 0);
}
{
// And now the bill.
return MathHelper.clamp(((to_break.size()*6/5)+(to_decay.size()/10)-1), 1, 65535);
}
}
}

View file

@ -9,8 +9,8 @@
package wile.engineersdecor.eapi.jei;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.BlockDecorCraftingTable;
import wile.engineersdecor.blocks.ModBlocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.detail.ModConfig;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
@ -25,7 +25,7 @@ public class JEIPlugin implements mezz.jei.api.IModPlugin
{
// Block/item hiding
try {
for(Block e:ModBlocks.getRegisteredBlocks()) {
for(Block e:ModContent.getRegisteredBlocks()) {
if(ModConfig.isOptedOut(e)) {
ItemStack stack = new ItemStack(Item.getItemFromBlock(e));
if(stack != null) {

View file

@ -1,63 +0,0 @@
/*
* @file ModItems.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Definition and initialisation of items of this module.
*/
package wile.engineersdecor.items;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ModConfig;
import net.minecraft.item.Item;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import javax.annotation.Nonnull;
@SuppressWarnings("unused")
public class ModItems
{
private static final Item[] modItems = {
};
private static final ArrayList<Item> registeredItems = new ArrayList<>();
@Nonnull
public static List<Item> getRegisteredItems()
{ return Collections.unmodifiableList(registeredItems); }
public static final void registerItems(RegistryEvent.Register<Item> event)
{
// Config based registry selection
int num_registrations_skipped = 0;
ArrayList<Item> allItems = new ArrayList<>();
Collections.addAll(allItems, modItems);
final boolean woor = ModConfig.isWithoutOptOutRegistration();
for(Item e:allItems) {
if((!woor) || (!ModConfig.isOptedOut(e))) {
registeredItems.add(e);
} else {
++num_registrations_skipped;
}
}
for(Item e:registeredItems) event.getRegistry().register(e);
ModEngineersDecor.logger.info("Registered " + Integer.toString(registeredItems.size()) + " items.");
if(num_registrations_skipped > 0) {
ModEngineersDecor.logger.info("Skipped registration of " + num_registrations_skipped + " items.");
}
}
@SideOnly(Side.CLIENT)
public static final void initModels()
{
for(Item e:registeredItems) {
if(e instanceof ItemDecor) ((ItemDecor)e).initModel();
}
}
}