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:
parent
64186ec813
commit
462e14166c
104 changed files with 3812 additions and 158 deletions
|
@ -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()
|
|
@ -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); }
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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)
|
||||
{}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 + "'");
|
||||
|
|
168
1.12/src/main/java/wile/engineersdecor/detail/TreeCutting.java
Normal file
168
1.12/src/main/java/wile/engineersdecor/detail/TreeCutting.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue