mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-24 14:06:42 +01:00
Extractors and Linked Extractors
- Added extractors for dropping items from an inventory - Further generalized Wireless Redstone actors - Made the crushing wheel more dramatic - Stationary Drills will drop items more carefully
This commit is contained in:
parent
22fc9d1100
commit
a0734dffaf
15 changed files with 754 additions and 220 deletions
|
@ -22,9 +22,11 @@ import com.simibubi.create.modules.contraptions.relays.GearboxTileEntityRenderer
|
||||||
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity;
|
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntityRenderer;
|
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntityRenderer;
|
||||||
import com.simibubi.create.modules.economy.ShopShelfTileEntity;
|
import com.simibubi.create.modules.economy.ShopShelfTileEntity;
|
||||||
|
import com.simibubi.create.modules.logistics.block.ExtractorTileEntity;
|
||||||
import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity;
|
import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity;
|
||||||
|
import com.simibubi.create.modules.logistics.block.LinkedExtractorTileEntity;
|
||||||
import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity;
|
import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity;
|
||||||
import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntityRenderer;
|
import com.simibubi.create.modules.logistics.block.LinkedTileEntityRenderer;
|
||||||
import com.simibubi.create.modules.logistics.block.StockswitchTileEntity;
|
import com.simibubi.create.modules.logistics.block.StockswitchTileEntity;
|
||||||
import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity;
|
import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity;
|
||||||
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
|
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
|
||||||
|
@ -66,6 +68,8 @@ public enum AllTileEntities {
|
||||||
REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE),
|
REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE),
|
||||||
STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH),
|
STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH),
|
||||||
FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE),
|
FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE),
|
||||||
|
EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR),
|
||||||
|
LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR),
|
||||||
|
|
||||||
// Economy
|
// Economy
|
||||||
SHOP_SHELF(ShopShelfTileEntity::new, AllBlocks.SHOP_SHELF),
|
SHOP_SHELF(ShopShelfTileEntity::new, AllBlocks.SHOP_SHELF),
|
||||||
|
@ -110,7 +114,8 @@ public enum AllTileEntities {
|
||||||
bind(DrillTileEntity.class, new KineticTileEntityRenderer());
|
bind(DrillTileEntity.class, new KineticTileEntityRenderer());
|
||||||
bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer());
|
bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer());
|
||||||
bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer());
|
bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer());
|
||||||
bind(RedstoneBridgeTileEntity.class, new RedstoneBridgeTileEntityRenderer());
|
bind(RedstoneBridgeTileEntity.class, new LinkedTileEntityRenderer());
|
||||||
|
bind(LinkedExtractorTileEntity.class, new LinkedTileEntityRenderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.simibubi.create.foundation.utility;
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -29,4 +31,9 @@ public class VecHelper {
|
||||||
return new Vec3d(pos).add(.5f, .5f, .5f);
|
return new Vec3d(pos).add(.5f, .5f, .5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vec3d offsetRandomly(Vec3d vec, Random r, float radius) {
|
||||||
|
return new Vec3d(vec.x + (r.nextFloat() - .5f) * 2 * radius, vec.y + (r.nextFloat() - .5f) * 2 * radius,
|
||||||
|
vec.z + (r.nextFloat() - .5f) * 2 * radius);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,15 +60,15 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
Inventory inventory = new Inventory();
|
Inventory inventory = new Inventory();
|
||||||
NonNullList<ItemStack> stacks = NonNullList.withSize(10, ItemStack.EMPTY);
|
NonNullList<ItemStack> stacks = NonNullList.withSize(10, ItemStack.EMPTY);
|
||||||
ItemStackHelper.loadAllItems(nbt, stacks);
|
ItemStackHelper.loadAllItems(nbt, stacks);
|
||||||
|
|
||||||
for (int slot = 0; slot < stacks.size(); slot++)
|
for (int slot = 0; slot < stacks.size(); slot++)
|
||||||
inventory.setInventorySlotContents(slot, stacks.get(slot));
|
inventory.setInventorySlotContents(slot, stacks.get(slot));
|
||||||
inventory.processingDuration = nbt.getInt("ProcessingTime");
|
inventory.processingDuration = nbt.getInt("ProcessingTime");
|
||||||
inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe");
|
inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe");
|
||||||
|
|
||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStackHandler getItems() {
|
public ItemStackHandler getItems() {
|
||||||
return (ItemStackHandler) inv;
|
return (ItemStackHandler) inv;
|
||||||
}
|
}
|
||||||
|
@ -97,14 +97,14 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
float speed = crushingspeed / 2.5f;
|
float speed = crushingspeed / 2.5f;
|
||||||
|
|
||||||
if (!hasEntity()) {
|
if (!hasEntity()) {
|
||||||
|
|
||||||
float processingSpeed = speed / (!contents.appliedRecipe? contents.getStackInSlot(0).getCount() : 1);
|
float processingSpeed = speed / (!contents.appliedRecipe ? contents.getStackInSlot(0).getCount() : 1);
|
||||||
contents.processingDuration -= processingSpeed;
|
contents.processingDuration -= processingSpeed;
|
||||||
spawnParticles(contents.getStackInSlot(0));
|
spawnParticles(contents.getStackInSlot(0));
|
||||||
|
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (contents.processingDuration < 20 && !contents.appliedRecipe) {
|
if (contents.processingDuration < 20 && !contents.appliedRecipe) {
|
||||||
applyRecipe();
|
applyRecipe();
|
||||||
contents.appliedRecipe = true;
|
contents.appliedRecipe = true;
|
||||||
|
@ -167,8 +167,9 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
||||||
|
|
||||||
Random r = world.rand;
|
Random r = world.rand;
|
||||||
world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(),
|
for (int i = 0; i < 4; i++)
|
||||||
pos.getZ() + r.nextFloat(), 0, 0, 0);
|
world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(),
|
||||||
|
pos.getZ() + r.nextFloat(), 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyRecipe() {
|
private void applyRecipe() {
|
||||||
|
@ -178,16 +179,16 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
if (recipe.isPresent()) {
|
if (recipe.isPresent()) {
|
||||||
int rolls = contents.getStackInSlot(0).getCount();
|
int rolls = contents.getStackInSlot(0).getCount();
|
||||||
contents.clear();
|
contents.clear();
|
||||||
|
|
||||||
for (int roll = 0; roll < rolls; roll++) {
|
for (int roll = 0; roll < rolls; roll++) {
|
||||||
List<ItemStack> rolledResults = recipe.get().rollResults();
|
List<ItemStack> rolledResults = recipe.get().rollResults();
|
||||||
|
|
||||||
for (int i = 0; i < rolledResults.size(); i++) {
|
for (int i = 0; i < rolledResults.size(); i++) {
|
||||||
ItemStack stack = rolledResults.get(i);
|
ItemStack stack = rolledResults.get(i);
|
||||||
|
|
||||||
for (int slot = 0; slot < contents.getSizeInventory(); slot++) {
|
for (int slot = 0; slot < contents.getSizeInventory(); slot++) {
|
||||||
stack = contents.getItems().insertItem(slot, stack, false);
|
stack = contents.getItems().insertItem(slot, stack, false);
|
||||||
|
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,29 @@ package com.simibubi.create.modules.contraptions.receivers;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
|
|
||||||
import net.minecraft.block.AirBlock;
|
import net.minecraft.block.AirBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.fluid.IFluidState;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.GameRules;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
|
||||||
public class DrillTileEntity extends KineticTileEntity implements ITickableTileEntity {
|
public class DrillTileEntity extends KineticTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
private static final AtomicInteger NEXT_DRILL_ID = new AtomicInteger();
|
private static final AtomicInteger NEXT_DRILL_ID = new AtomicInteger();
|
||||||
|
|
||||||
private int ticksUntilNextProgress;
|
private int ticksUntilNextProgress;
|
||||||
private int destroyProgress;
|
private int destroyProgress;
|
||||||
private int drillId = -NEXT_DRILL_ID.incrementAndGet();
|
private int drillId = -NEXT_DRILL_ID.incrementAndGet();
|
||||||
|
@ -34,21 +43,21 @@ public class DrillTileEntity extends KineticTileEntity implements ITickableTileE
|
||||||
public void destroyNextTick() {
|
public void destroyNextTick() {
|
||||||
ticksUntilNextProgress = 1;
|
ticksUntilNextProgress = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT write(CompoundNBT compound) {
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
compound.putInt("Progress", destroyProgress);
|
compound.putInt("Progress", destroyProgress);
|
||||||
compound.putInt("NextTick", ticksUntilNextProgress);
|
compound.putInt("NextTick", ticksUntilNextProgress);
|
||||||
return super.write(compound);
|
return super.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(CompoundNBT compound) {
|
public void read(CompoundNBT compound) {
|
||||||
destroyProgress = compound.getInt("Progress");
|
destroyProgress = compound.getInt("Progress");
|
||||||
ticksUntilNextProgress = compound.getInt("NextTick");
|
ticksUntilNextProgress = compound.getInt("NextTick");
|
||||||
super.read(compound);
|
super.read(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove() {
|
public void remove() {
|
||||||
if (!world.isRemote && destroyProgress != 0) {
|
if (!world.isRemote && destroyProgress != 0) {
|
||||||
|
@ -64,33 +73,52 @@ public class DrillTileEntity extends KineticTileEntity implements ITickableTileE
|
||||||
return;
|
return;
|
||||||
if (speed == 0)
|
if (speed == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ticksUntilNextProgress < 0)
|
if (ticksUntilNextProgress < 0)
|
||||||
return;
|
return;
|
||||||
if (ticksUntilNextProgress-- > 0)
|
if (ticksUntilNextProgress-- > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING));
|
BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING));
|
||||||
BlockState stateToBreak = world.getBlockState(posToBreak);
|
BlockState stateToBreak = world.getBlockState(posToBreak);
|
||||||
float blockHardness = stateToBreak.getBlockHardness(world, posToBreak);
|
float blockHardness = stateToBreak.getBlockHardness(world, posToBreak);
|
||||||
|
|
||||||
if (stateToBreak.getMaterial().isLiquid() || stateToBreak.getBlock() instanceof AirBlock || blockHardness == -1) {
|
if (stateToBreak.getMaterial().isLiquid() || stateToBreak.getBlock() instanceof AirBlock
|
||||||
|
|| blockHardness == -1) {
|
||||||
destroyProgress = 0;
|
destroyProgress = 0;
|
||||||
world.sendBlockBreakProgress(drillId, posToBreak, -1);
|
world.sendBlockBreakProgress(drillId, posToBreak, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float breakSpeed = Math.abs(speed / 100f);
|
float breakSpeed = Math.abs(speed / 100f);
|
||||||
destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
|
destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
|
||||||
|
|
||||||
if (destroyProgress >= 10) {
|
if (destroyProgress >= 10) {
|
||||||
world.destroyBlock(posToBreak, true);
|
|
||||||
|
IFluidState ifluidstate = world.getFluidState(pos);
|
||||||
|
world.playEvent(2001, posToBreak, Block.getStateId(stateToBreak));
|
||||||
|
TileEntity tileentity = stateToBreak.hasTileEntity() ? world.getTileEntity(posToBreak) : null;
|
||||||
|
Vec3d vec = VecHelper.offsetRandomly(VecHelper.getCenterOf(posToBreak), world.rand, .125f);
|
||||||
|
|
||||||
|
Block.getDrops(stateToBreak, (ServerWorld) world, posToBreak, tileentity).forEach((stack) -> {
|
||||||
|
if (!stack.isEmpty() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)
|
||||||
|
&& !world.restoringBlockSnapshots) {
|
||||||
|
ItemEntity itementity = new ItemEntity(world, vec.x, vec.y, vec.z, stack);
|
||||||
|
itementity.setDefaultPickupDelay();
|
||||||
|
itementity.setMotion(Vec3d.ZERO);
|
||||||
|
world.addEntity(itementity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
stateToBreak.spawnAdditionalDrops(world, posToBreak, ItemStack.EMPTY);
|
||||||
|
world.setBlockState(posToBreak, ifluidstate.getBlockState(), 3);
|
||||||
|
|
||||||
destroyProgress = 0;
|
destroyProgress = 0;
|
||||||
ticksUntilNextProgress = -1;
|
ticksUntilNextProgress = -1;
|
||||||
world.sendBlockBreakProgress(drillId, posToBreak, -1);
|
world.sendBlockBreakProgress(drillId, posToBreak, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ticksUntilNextProgress = (int) (blockHardness / breakSpeed);
|
ticksUntilNextProgress = (int) (blockHardness / breakSpeed);
|
||||||
world.sendBlockBreakProgress(drillId, posToBreak, (int) destroyProgress);
|
world.sendBlockBreakProgress(drillId, posToBreak, (int) destroyProgress);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.modules.logistics;
|
||||||
|
|
||||||
import com.simibubi.create.modules.logistics.FrequencyHandler.Frequency;
|
import com.simibubi.create.modules.logistics.FrequencyHandler.Frequency;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ public interface IHaveWireless {
|
||||||
|
|
||||||
public Frequency getFrequencyFirst();
|
public Frequency getFrequencyFirst();
|
||||||
public Frequency getFrequencyLast();
|
public Frequency getFrequencyLast();
|
||||||
|
public void setFrequency(boolean first, ItemStack stack);
|
||||||
public World getWorld();
|
public World getWorld();
|
||||||
public BlockPos getPos();
|
public BlockPos getPos();
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,21 @@ import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.HorizontalBlock;
|
import net.minecraft.block.HorizontalBlock;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
import net.minecraft.state.StateContainer.Builder;
|
import net.minecraft.state.StateContainer.Builder;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.IWorldReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class ExtractorBlock extends HorizontalBlock {
|
public class ExtractorBlock extends HorizontalBlock {
|
||||||
|
@ -34,6 +39,22 @@ public class ExtractorBlock extends HorizontalBlock {
|
||||||
super.fillStateContainer(builder);
|
super.fillStateContainer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTileEntity(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
|
return new ExtractorTileEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||||
|
BlockRayTraceResult hit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||||
BlockState state = getDefaultState();
|
BlockState state = getDefaultState();
|
||||||
|
@ -47,6 +68,31 @@ public class ExtractorBlock extends HorizontalBlock {
|
||||||
return state.with(POWERED, Boolean.valueOf(context.getWorld().isBlockPowered(context.getPos())));
|
return state.with(POWERED, Boolean.valueOf(context.getWorld().isBlockPowered(context.getPos())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||||
|
updateObservedInventory(state, worldIn, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
||||||
|
if (world.isRemote())
|
||||||
|
return;
|
||||||
|
if (!isObserving(state, pos, neighbor))
|
||||||
|
return;
|
||||||
|
updateObservedInventory(state, world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateObservedInventory(BlockState state, IWorldReader world, BlockPos pos) {
|
||||||
|
IExtractor extractor = (IExtractor) world.getTileEntity(pos);
|
||||||
|
if (extractor == null)
|
||||||
|
return;
|
||||||
|
extractor.neighborChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isObserving(BlockState state, BlockPos pos, BlockPos observing) {
|
||||||
|
return observing.equals(pos.offset(state.get(HORIZONTAL_FACING)));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||||
boolean isMoving) {
|
boolean isMoving) {
|
||||||
|
@ -56,6 +102,10 @@ public class ExtractorBlock extends HorizontalBlock {
|
||||||
boolean previouslyPowered = state.get(POWERED);
|
boolean previouslyPowered = state.get(POWERED);
|
||||||
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
|
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
|
||||||
worldIn.setBlockState(pos, state.cycle(POWERED), 2);
|
worldIn.setBlockState(pos, state.cycle(POWERED), 2);
|
||||||
|
IExtractor extractor = (IExtractor) worldIn.getTileEntity(pos);
|
||||||
|
if (extractor == null)
|
||||||
|
return;
|
||||||
|
extractor.setLocked(!previouslyPowered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.simibubi.create.modules.logistics.block;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllTileEntities;
|
||||||
|
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||||
|
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, ITickableTileEntity {
|
||||||
|
|
||||||
|
private State state;
|
||||||
|
private int cooldown;
|
||||||
|
private LazyOptional<IItemHandler> inventory;
|
||||||
|
|
||||||
|
public ExtractorTileEntity() {
|
||||||
|
super(AllTileEntities.EXTRACTOR.type);
|
||||||
|
state = State.WAITING_FOR_ITEM;
|
||||||
|
inventory = LazyOptional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setState(State state) {
|
||||||
|
if (state == State.ON_COOLDOWN)
|
||||||
|
cooldown = EXTRACTOR_COOLDOWN;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int tickCooldown() {
|
||||||
|
return cooldown--;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getInventoryPos() {
|
||||||
|
return getPos().offset(getBlockState().get(BlockStateProperties.HORIZONTAL_FACING));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LazyOptional<IItemHandler> getInventory() {
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInventory(LazyOptional<IItemHandler> inventory) {
|
||||||
|
this.inventory = inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
package com.simibubi.create.modules.logistics.block;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
|
import com.simibubi.create.modules.logistics.IHaveWireless;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
|
||||||
|
@EventBusSubscriber(value = Dist.CLIENT)
|
||||||
|
public interface IBlockWithFrequency {
|
||||||
|
|
||||||
|
public Pair<Vec3d, Vec3d> getFrequencyItemPositions(BlockState state);
|
||||||
|
public Direction getFrequencyItemFacing(BlockState state);
|
||||||
|
|
||||||
|
public default float getItemHitboxScale() {
|
||||||
|
return 2 / 16f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public default boolean handleActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player,
|
||||||
|
Hand handIn, BlockRayTraceResult hit) {
|
||||||
|
TileEntity te = worldIn.getTileEntity(pos);
|
||||||
|
if (te == null || !(te instanceof IHaveWireless))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
IHaveWireless actor = (IHaveWireless) te;
|
||||||
|
Pair<Vec3d, Vec3d> positions = getFrequencyItemPositions(state);
|
||||||
|
ItemStack stack = player.getHeldItem(handIn);
|
||||||
|
Vec3d vec = new Vec3d(pos);
|
||||||
|
Vec3d first = positions.getLeft().add(vec);
|
||||||
|
Vec3d second = positions.getRight().add(vec);
|
||||||
|
float scale = getItemHitboxScale();
|
||||||
|
|
||||||
|
if (new AxisAlignedBB(first, first).grow(scale).contains(hit.getHitVec())) {
|
||||||
|
if (worldIn.isRemote)
|
||||||
|
return true;
|
||||||
|
actor.setFrequency(true, stack);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new AxisAlignedBB(second, second).grow(scale).contains(hit.getHitVec())) {
|
||||||
|
if (worldIn.isRemote)
|
||||||
|
return true;
|
||||||
|
actor.setFrequency(false, stack);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static void onDrawBlockHighlight(DrawBlockHighlightEvent event) {
|
||||||
|
if (event.getTarget() == null || !(event.getTarget() instanceof BlockRayTraceResult))
|
||||||
|
return;
|
||||||
|
|
||||||
|
BlockRayTraceResult result = (BlockRayTraceResult) event.getTarget();
|
||||||
|
ClientWorld world = Minecraft.getInstance().world;
|
||||||
|
BlockPos pos = result.getPos();
|
||||||
|
BlockState state = world.getBlockState(pos);
|
||||||
|
|
||||||
|
if (!(state.getBlock() instanceof IBlockWithFrequency))
|
||||||
|
return;
|
||||||
|
|
||||||
|
IBlockWithFrequency freqBlock = (IBlockWithFrequency) state.getBlock();
|
||||||
|
Pair<Vec3d, Vec3d> positions = freqBlock.getFrequencyItemPositions(state);
|
||||||
|
Vec3d vec = new Vec3d(pos);
|
||||||
|
Vec3d first = positions.getLeft().add(vec);
|
||||||
|
Vec3d second = positions.getRight().add(vec);
|
||||||
|
float scale = freqBlock.getItemHitboxScale();
|
||||||
|
|
||||||
|
AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(scale);
|
||||||
|
AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(scale);
|
||||||
|
|
||||||
|
TessellatorHelper.prepareForDrawing();
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA,
|
||||||
|
GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE,
|
||||||
|
GlStateManager.DestFactor.ZERO);
|
||||||
|
GlStateManager.disableTexture();
|
||||||
|
GlStateManager.depthMask(false);
|
||||||
|
GlStateManager.matrixMode(5889);
|
||||||
|
|
||||||
|
if (firstBB.contains(result.getHitVec())) {
|
||||||
|
GlStateManager.lineWidth(2);
|
||||||
|
WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f);
|
||||||
|
} else {
|
||||||
|
GlStateManager.lineWidth(2);
|
||||||
|
WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), .5f, .5f, .2f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondBB.contains(result.getHitVec())) {
|
||||||
|
GlStateManager.lineWidth(2);
|
||||||
|
WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f);
|
||||||
|
} else {
|
||||||
|
GlStateManager.lineWidth(2);
|
||||||
|
WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), .5f, .5f, .2f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager.matrixMode(5888);
|
||||||
|
GlStateManager.depthMask(true);
|
||||||
|
GlStateManager.enableTexture();
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
GlStateManager.lineWidth(1);
|
||||||
|
TessellatorHelper.cleanUpAfterDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
package com.simibubi.create.modules.logistics.block;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
// Its like delegation but better!
|
||||||
|
public interface IExtractor extends ITickableTileEntity {
|
||||||
|
|
||||||
|
public static final int EXTRACTOR_COOLDOWN = 20;
|
||||||
|
public static final int EXTRACTION_COUNT = 16;
|
||||||
|
|
||||||
|
public enum State {
|
||||||
|
WAITING_FOR_ITEM, WAITING_FOR_SPACE, RUNNING, ON_COOLDOWN, LOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState();
|
||||||
|
|
||||||
|
public void setState(State state);
|
||||||
|
|
||||||
|
public int tickCooldown();
|
||||||
|
|
||||||
|
public World getWorld();
|
||||||
|
|
||||||
|
public BlockPos getPos();
|
||||||
|
|
||||||
|
public BlockPos getInventoryPos();
|
||||||
|
|
||||||
|
public LazyOptional<IItemHandler> getInventory();
|
||||||
|
|
||||||
|
public void setInventory(LazyOptional<IItemHandler> inventory);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void tick() {
|
||||||
|
State state = getState();
|
||||||
|
|
||||||
|
if (state == State.LOCKED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (state == State.ON_COOLDOWN) {
|
||||||
|
int cooldown = tickCooldown();
|
||||||
|
if (cooldown <= 0)
|
||||||
|
setState(State.RUNNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasSpace = hasSpaceForExtracting();
|
||||||
|
boolean hasInventory = getInventory().isPresent();
|
||||||
|
ItemStack toExtract = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
if (hasSpace && hasInventory)
|
||||||
|
toExtract = extract(true);
|
||||||
|
|
||||||
|
if (state == State.WAITING_FOR_SPACE) {
|
||||||
|
if (hasSpace)
|
||||||
|
setState(State.RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == State.RUNNING) {
|
||||||
|
if (!hasSpace) {
|
||||||
|
setState(State.WAITING_FOR_SPACE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!hasInventory || toExtract.isEmpty()) {
|
||||||
|
setState(State.WAITING_FOR_ITEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
extract(false);
|
||||||
|
setState(State.ON_COOLDOWN);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public default void setLocked(boolean locked) {
|
||||||
|
setState(locked ? State.LOCKED : State.ON_COOLDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public default void neighborChanged() {
|
||||||
|
boolean hasSpace = hasSpaceForExtracting();
|
||||||
|
boolean hasInventory = getInventory().isPresent();
|
||||||
|
ItemStack toExtract = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
if (hasSpace && hasInventory)
|
||||||
|
toExtract = extract(true);
|
||||||
|
|
||||||
|
if (getState() == State.WAITING_FOR_ITEM) {
|
||||||
|
if (!hasInventory) {
|
||||||
|
if (findNewInventory()) {
|
||||||
|
setState(State.RUNNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!toExtract.isEmpty())
|
||||||
|
setState(State.RUNNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean hasSpaceForExtracting() {
|
||||||
|
return getWorld().getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
default ItemStack extract(boolean simulate) {
|
||||||
|
IItemHandler inv = getInventory().orElse(null);
|
||||||
|
ItemStack extracting = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||||
|
ItemStack stack = inv.extractItem(slot, EXTRACTION_COUNT - extracting.getCount(), true);
|
||||||
|
ItemStack compare = stack.copy();
|
||||||
|
compare.setCount(extracting.getCount());
|
||||||
|
if (!extracting.isEmpty() && !extracting.equals(compare, false))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (extracting.isEmpty())
|
||||||
|
extracting = stack.copy();
|
||||||
|
else
|
||||||
|
extracting.grow(stack.getCount());
|
||||||
|
|
||||||
|
if (!simulate)
|
||||||
|
inv.extractItem(slot, stack.getCount(), false);
|
||||||
|
if (extracting.getCount() >= EXTRACTION_COUNT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!simulate) {
|
||||||
|
World world = getWorld();
|
||||||
|
Vec3d pos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0);
|
||||||
|
ItemEntity entityIn = new ItemEntity(world, pos.x, pos.y, pos.z, extracting);
|
||||||
|
entityIn.setMotion(Vec3d.ZERO);
|
||||||
|
world.addEntity(entityIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return extracting;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean findNewInventory() {
|
||||||
|
BlockPos invPos = getInventoryPos();
|
||||||
|
World world = getWorld();
|
||||||
|
|
||||||
|
if (!world.isBlockPresent(invPos))
|
||||||
|
return false;
|
||||||
|
BlockState invState = world.getBlockState(invPos);
|
||||||
|
|
||||||
|
if (!invState.hasTileEntity())
|
||||||
|
return false;
|
||||||
|
TileEntity invTE = world.getTileEntity(invPos);
|
||||||
|
|
||||||
|
LazyOptional<IItemHandler> inventory = invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
|
||||||
|
setInventory(inventory);
|
||||||
|
if (inventory.isPresent()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,31 +1,108 @@
|
||||||
package com.simibubi.create.modules.logistics.block;
|
package com.simibubi.create.modules.logistics.block;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
import net.minecraft.util.BlockRenderLayer;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class LinkedExtractorBlock extends ExtractorBlock {
|
public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFrequency {
|
||||||
|
|
||||||
|
private static final List<Pair<Vec3d, Vec3d>> itemPositions = new ArrayList<>(Direction.values().length);
|
||||||
|
|
||||||
public LinkedExtractorBlock() {
|
public LinkedExtractorBlock() {
|
||||||
super();
|
super();
|
||||||
|
cacheItemPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockRenderLayer getRenderLayer() {
|
public BlockRenderLayer getRenderLayer() {
|
||||||
return BlockRenderLayer.CUTOUT;
|
return BlockRenderLayer.CUTOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTileEntity(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
|
return new LinkedExtractorTileEntity();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||||
return super.getStateForPlacement(context).with(POWERED, false);
|
return super.getStateForPlacement(context).with(POWERED, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||||
boolean isMoving) {
|
boolean isMoving) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||||
|
BlockRayTraceResult hit) {
|
||||||
|
return super.onBlockActivated(state, worldIn, pos, player, handIn, hit)
|
||||||
|
|| handleActivated(state, worldIn, pos, player, handIn, hit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cacheItemPositions() {
|
||||||
|
if (!itemPositions.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vec3d first = Vec3d.ZERO;
|
||||||
|
Vec3d second = Vec3d.ZERO;
|
||||||
|
Vec3d shift = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||||
|
float zFightOffset = 1 / 128f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
Direction facing = Direction.byHorizontalIndex(i);
|
||||||
|
first = new Vec3d(11.5f / 16f + zFightOffset, 4f / 16f, 14f / 16f );
|
||||||
|
second = new Vec3d(11.5f / 16f + zFightOffset, 8f / 16f, 14f / 16f);
|
||||||
|
|
||||||
|
float angle = facing.getHorizontalAngle();
|
||||||
|
if (facing.getAxis() == Axis.X)
|
||||||
|
angle = -angle;
|
||||||
|
|
||||||
|
first = VecHelper.rotate(first.subtract(shift), angle, Axis.Y).add(shift);
|
||||||
|
second = VecHelper.rotate(second.subtract(shift), angle, Axis.Y).add(shift);
|
||||||
|
|
||||||
|
itemPositions.add(Pair.of(first, second));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemHitboxScale() {
|
||||||
|
return 3/32f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<Vec3d, Vec3d> getFrequencyItemPositions(BlockState state) {
|
||||||
|
Direction facing = state.get(HORIZONTAL_FACING);
|
||||||
|
return itemPositions.get(facing.getHorizontalIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Direction getFrequencyItemFacing(BlockState state) {
|
||||||
|
return state.get(HORIZONTAL_FACING).rotateYCCW();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package com.simibubi.create.modules.logistics.block;
|
||||||
|
|
||||||
|
import static net.minecraft.state.properties.BlockStateProperties.POWERED;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllTileEntities;
|
||||||
|
import com.simibubi.create.modules.logistics.IReceiveWireless;
|
||||||
|
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
public class LinkedExtractorTileEntity extends LinkedTileEntity
|
||||||
|
implements IReceiveWireless, ITickableTileEntity, IExtractor {
|
||||||
|
|
||||||
|
public boolean receivedSignal;
|
||||||
|
|
||||||
|
private State state;
|
||||||
|
private int cooldown;
|
||||||
|
private LazyOptional<IItemHandler> inventory;
|
||||||
|
|
||||||
|
public LinkedExtractorTileEntity() {
|
||||||
|
super(AllTileEntities.LINKED_EXTRACTOR.type);
|
||||||
|
state = State.WAITING_FOR_ITEM;
|
||||||
|
inventory = LazyOptional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSignal(boolean powered) {
|
||||||
|
receivedSignal = powered;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
IExtractor.super.tick();
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
if (receivedSignal != getBlockState().get(POWERED)) {
|
||||||
|
setLocked(receivedSignal);
|
||||||
|
world.setBlockState(pos, getBlockState().cycle(POWERED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setState(State state) {
|
||||||
|
if (state == State.ON_COOLDOWN)
|
||||||
|
cooldown = EXTRACTOR_COOLDOWN;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int tickCooldown() {
|
||||||
|
return cooldown--;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getInventoryPos() {
|
||||||
|
return getPos().offset(getBlockState().get(BlockStateProperties.HORIZONTAL_FACING));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LazyOptional<IItemHandler> getInventory() {
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInventory(LazyOptional<IItemHandler> inventory) {
|
||||||
|
this.inventory = inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.simibubi.create.modules.logistics.block;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||||
|
import com.simibubi.create.modules.logistics.FrequencyHandler;
|
||||||
|
import com.simibubi.create.modules.logistics.FrequencyHandler.Frequency;
|
||||||
|
import com.simibubi.create.modules.logistics.IHaveWireless;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
|
||||||
|
public abstract class LinkedTileEntity extends SyncedTileEntity implements IHaveWireless {
|
||||||
|
|
||||||
|
public Frequency frequencyFirst;
|
||||||
|
public Frequency frequencyLast;
|
||||||
|
|
||||||
|
public LinkedTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||||
|
super(tileEntityTypeIn);
|
||||||
|
frequencyFirst = new Frequency(ItemStack.EMPTY);
|
||||||
|
frequencyLast = new Frequency(ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
super.onLoad();
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
FrequencyHandler.addToNetwork(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
super.remove();
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
FrequencyHandler.removeFromNetwork(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
|
compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT()));
|
||||||
|
compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT()));
|
||||||
|
return super.write(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(CompoundNBT compound) {
|
||||||
|
frequencyFirst = new Frequency(ItemStack.read(compound.getCompound("FrequencyFirst")));
|
||||||
|
frequencyLast = new Frequency(ItemStack.read(compound.getCompound("FrequencyLast")));
|
||||||
|
super.read(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFrequency(boolean first, ItemStack stack) {
|
||||||
|
stack = stack.copy();
|
||||||
|
stack.setCount(1);
|
||||||
|
ItemStack toCompare = first ? frequencyFirst.getStack() : frequencyLast.getStack();
|
||||||
|
boolean changed = !ItemStack.areItemsEqual(stack, toCompare)
|
||||||
|
|| !ItemStack.areItemStackTagsEqual(stack, toCompare);
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
FrequencyHandler.removeFromNetwork(this);
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
frequencyFirst = new Frequency(stack);
|
||||||
|
else
|
||||||
|
frequencyLast = new Frequency(stack);
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sendData();
|
||||||
|
FrequencyHandler.addToNetwork(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Frequency getFrequencyFirst() {
|
||||||
|
return frequencyFirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Frequency getFrequencyLast() {
|
||||||
|
return frequencyLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,72 +5,75 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.ItemRenderer;
|
import net.minecraft.client.renderer.ItemRenderer;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class RedstoneBridgeTileEntityRenderer extends TileEntityRenderer<RedstoneBridgeTileEntity> {
|
public class LinkedTileEntityRenderer extends TileEntityRenderer<LinkedTileEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RedstoneBridgeTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
public void render(LinkedTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||||
int destroyStage) {
|
int destroyStage) {
|
||||||
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||||
|
|
||||||
Direction facing = tileEntityIn.getBlockState().get(BlockStateProperties.FACING);
|
BlockState state = tileEntityIn.getBlockState();
|
||||||
|
IBlockWithFrequency block = (IBlockWithFrequency) state.getBlock();
|
||||||
|
Direction facing = block.getFrequencyItemFacing(state);
|
||||||
|
float scale = block.getItemHitboxScale();
|
||||||
|
|
||||||
TessellatorHelper.prepareForDrawing();
|
TessellatorHelper.prepareForDrawing();
|
||||||
|
|
||||||
Pair<Vec3d, Vec3d> itemPositions = RedstoneBridgeBlock.getFrequencyItemPositions(tileEntityIn.getBlockState());
|
Pair<Vec3d, Vec3d> itemPositions = block.getFrequencyItemPositions(state);
|
||||||
Vec3d first = itemPositions.getLeft();
|
Vec3d first = itemPositions.getLeft();
|
||||||
Vec3d second = itemPositions.getRight();
|
Vec3d second = itemPositions.getRight();
|
||||||
BlockPos pos = tileEntityIn.getPos();
|
BlockPos pos = tileEntityIn.getPos();
|
||||||
GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ());
|
GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
|
||||||
renderFrequencyItem(tileEntityIn.frequencyFirst.getStack(), first, facing);
|
renderFrequencyItem(tileEntityIn.frequencyFirst.getStack(), first, facing, scale - 2/16f);
|
||||||
renderFrequencyItem(tileEntityIn.frequencyLast.getStack(), second, facing);
|
renderFrequencyItem(tileEntityIn.frequencyLast.getStack(), second, facing, scale - 2/16f);
|
||||||
|
|
||||||
TessellatorHelper.cleanUpAfterDrawing();
|
TessellatorHelper.cleanUpAfterDrawing();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderFrequencyItem(ItemStack stack, Vec3d position, Direction facing) {
|
private void renderFrequencyItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff) {
|
||||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||||
boolean vertical = facing.getAxis().isVertical();
|
boolean vertical = facing.getAxis().isVertical();
|
||||||
|
|
||||||
IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(stack);
|
IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(stack);
|
||||||
boolean blockItem = modelWithOverrides.isGui3d();
|
boolean blockItem = modelWithOverrides.isGui3d();
|
||||||
|
|
||||||
float offX = 0;
|
float offX = 0;
|
||||||
float offY = vertical && !blockItem ? 0 : 0;
|
float offY = vertical && !blockItem ? 0 : 0;
|
||||||
float offZ = !blockItem ? 1/4f : 0;
|
float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff : 0;
|
||||||
if (vertical)
|
if (vertical)
|
||||||
offZ = -offZ;
|
offZ = -offZ;
|
||||||
|
|
||||||
float rotX = vertical ? 90 : 0;
|
float rotX = vertical ? 90 : 0;
|
||||||
float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0);
|
float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0);
|
||||||
float rotZ = vertical && facing == Direction.DOWN ? 180 : 0;
|
float rotZ = vertical && facing == Direction.DOWN ? 180 : 0;
|
||||||
if (facing.getAxis() == Axis.X) {
|
if (facing.getAxis() == Axis.X) {
|
||||||
// offZ = -offZ;
|
|
||||||
rotY = -rotY;
|
rotY = -rotY;
|
||||||
}
|
}
|
||||||
|
|
||||||
float scale = !blockItem ? .25f : .5f;
|
float scale = !blockItem ? .25f : .5f;
|
||||||
|
scale *= 1 + 8 * scaleDiff;
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
GlStateManager.pushMatrix();
|
||||||
GlStateManager.translated(position.x, position.y, position.z);
|
GlStateManager.translated(position.x, position.y, position.z);
|
||||||
GlStateManager.scaled(scale, scale, scale);
|
|
||||||
GlStateManager.rotatef(rotZ, 0, 0, 1);
|
GlStateManager.rotatef(rotZ, 0, 0, 1);
|
||||||
GlStateManager.rotatef(rotY, 0, 1, 0);
|
GlStateManager.rotatef(rotY, 0, 1, 0);
|
||||||
GlStateManager.rotatef(rotX, 1, 0, 0);
|
GlStateManager.rotatef(rotX, 1, 0, 0);
|
||||||
|
GlStateManager.scaled(scale, scale, scale);
|
||||||
GlStateManager.translatef(offX, offY, offZ);
|
GlStateManager.translatef(offX, offY, offZ);
|
||||||
itemRenderer.renderItem(stack, TransformType.FIXED);
|
itemRenderer.renderItem(stack, TransformType.FIXED);
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
|
@ -5,23 +5,17 @@ import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||||
import com.simibubi.create.foundation.utility.ITooltip;
|
import com.simibubi.create.foundation.utility.ITooltip;
|
||||||
import com.simibubi.create.foundation.utility.ItemDescription;
|
import com.simibubi.create.foundation.utility.ItemDescription;
|
||||||
import com.simibubi.create.foundation.utility.ItemDescription.Palette;
|
import com.simibubi.create.foundation.utility.ItemDescription.Palette;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
|
||||||
import com.simibubi.create.foundation.utility.TooltipHolder;
|
import com.simibubi.create.foundation.utility.TooltipHolder;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
|
||||||
import net.minecraft.client.util.ITooltipFlag;
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -33,7 +27,6 @@ import net.minecraft.util.BlockRenderLayer;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.BlockRayTraceResult;
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -46,12 +39,8 @@ import net.minecraft.world.IWorldReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
|
||||||
|
|
||||||
@EventBusSubscriber(value = Dist.CLIENT)
|
public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITooltip, IBlockWithFrequency {
|
||||||
public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITooltip {
|
|
||||||
|
|
||||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||||
public static final BooleanProperty RECEIVER = BooleanProperty.create("receiver");
|
public static final BooleanProperty RECEIVER = BooleanProperty.create("receiver");
|
||||||
|
@ -151,15 +140,12 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool
|
||||||
@Override
|
@Override
|
||||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||||
BlockRayTraceResult hit) {
|
BlockRayTraceResult hit) {
|
||||||
Direction facing = state.get(FACING);
|
|
||||||
Pair<Vec3d, Vec3d> positions = itemPositions.get(facing.getIndex());
|
|
||||||
ItemStack stack = player.getHeldItem(handIn);
|
|
||||||
RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(pos);
|
|
||||||
|
|
||||||
if (te == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (player.isSneaking()) {
|
if (player.isSneaking()) {
|
||||||
|
RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(pos);
|
||||||
|
if (te == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!worldIn.isRemote) {
|
if (!worldIn.isRemote) {
|
||||||
Boolean wasReceiver = state.get(RECEIVER);
|
Boolean wasReceiver = state.get(RECEIVER);
|
||||||
boolean blockPowered = worldIn.isBlockPowered(pos);
|
boolean blockPowered = worldIn.isBlockPowered(pos);
|
||||||
|
@ -172,86 +158,7 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3d vec = new Vec3d(pos);
|
return handleActivated(state, worldIn, pos, player, handIn, hit);
|
||||||
Vec3d first = positions.getLeft().add(vec);
|
|
||||||
Vec3d second = positions.getRight().add(vec);
|
|
||||||
|
|
||||||
if (new AxisAlignedBB(first, first).grow(2 / 16f).contains(hit.getHitVec())) {
|
|
||||||
if (worldIn.isRemote)
|
|
||||||
return true;
|
|
||||||
te.setFrequency(true, stack);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new AxisAlignedBB(second, second).grow(2 / 16f).contains(hit.getHitVec())) {
|
|
||||||
if (worldIn.isRemote)
|
|
||||||
return true;
|
|
||||||
te.setFrequency(false, stack);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
|
||||||
public static void onDrawBlockHighlight(DrawBlockHighlightEvent event) {
|
|
||||||
if (event.getTarget() == null || !(event.getTarget() instanceof BlockRayTraceResult))
|
|
||||||
return;
|
|
||||||
|
|
||||||
BlockRayTraceResult result = (BlockRayTraceResult) event.getTarget();
|
|
||||||
ClientWorld world = Minecraft.getInstance().world;
|
|
||||||
BlockPos pos = result.getPos();
|
|
||||||
BlockState state = world.getBlockState(pos);
|
|
||||||
|
|
||||||
if (!AllBlocks.REDSTONE_BRIDGE.typeOf(state))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Direction facing = state.get(FACING);
|
|
||||||
Pair<Vec3d, Vec3d> positions = itemPositions.get(facing.getIndex());
|
|
||||||
RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) world.getTileEntity(pos);
|
|
||||||
|
|
||||||
if (te == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vec3d vec = new Vec3d(pos);
|
|
||||||
Vec3d first = positions.getLeft().add(vec);
|
|
||||||
Vec3d second = positions.getRight().add(vec);
|
|
||||||
|
|
||||||
AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(2 / 16f);
|
|
||||||
AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(2 / 16f);
|
|
||||||
|
|
||||||
TessellatorHelper.prepareForDrawing();
|
|
||||||
GlStateManager.enableBlend();
|
|
||||||
GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA,
|
|
||||||
GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE,
|
|
||||||
GlStateManager.DestFactor.ZERO);
|
|
||||||
GlStateManager.disableTexture();
|
|
||||||
GlStateManager.depthMask(false);
|
|
||||||
GlStateManager.matrixMode(5889);
|
|
||||||
|
|
||||||
if (firstBB.contains(result.getHitVec())) {
|
|
||||||
GlStateManager.lineWidth(2);
|
|
||||||
WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f);
|
|
||||||
} else {
|
|
||||||
GlStateManager.lineWidth(2);
|
|
||||||
WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), .5f, .5f, .2f, 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondBB.contains(result.getHitVec())) {
|
|
||||||
GlStateManager.lineWidth(2);
|
|
||||||
WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f);
|
|
||||||
} else {
|
|
||||||
GlStateManager.lineWidth(2);
|
|
||||||
WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), .5f, .5f, .2f, 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
GlStateManager.matrixMode(5888);
|
|
||||||
GlStateManager.depthMask(true);
|
|
||||||
GlStateManager.enableTexture();
|
|
||||||
GlStateManager.disableBlend();
|
|
||||||
GlStateManager.lineWidth(1);
|
|
||||||
TessellatorHelper.cleanUpAfterDrawing();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -334,10 +241,15 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pair<Vec3d, Vec3d> getFrequencyItemPositions(BlockState state) {
|
public Pair<Vec3d, Vec3d> getFrequencyItemPositions(BlockState state) {
|
||||||
Direction facing = state.get(FACING);
|
Direction facing = state.get(FACING);
|
||||||
return itemPositions.get(facing.getIndex());
|
return itemPositions.get(facing.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Direction getFrequencyItemFacing(BlockState state) {
|
||||||
|
return state.get(FACING);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@OnlyIn(value = Dist.CLIENT)
|
@OnlyIn(value = Dist.CLIENT)
|
||||||
|
|
|
@ -3,127 +3,59 @@ package com.simibubi.create.modules.logistics.block;
|
||||||
import static net.minecraft.state.properties.BlockStateProperties.POWERED;
|
import static net.minecraft.state.properties.BlockStateProperties.POWERED;
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
|
||||||
import com.simibubi.create.modules.logistics.FrequencyHandler;
|
|
||||||
import com.simibubi.create.modules.logistics.FrequencyHandler.Frequency;
|
|
||||||
import com.simibubi.create.modules.logistics.IReceiveWireless;
|
import com.simibubi.create.modules.logistics.IReceiveWireless;
|
||||||
import com.simibubi.create.modules.logistics.ITransmitWireless;
|
import com.simibubi.create.modules.logistics.ITransmitWireless;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class RedstoneBridgeTileEntity extends SyncedTileEntity
|
public class RedstoneBridgeTileEntity extends LinkedTileEntity
|
||||||
implements ITickableTileEntity, IReceiveWireless, ITransmitWireless {
|
implements ITickableTileEntity, IReceiveWireless, ITransmitWireless {
|
||||||
|
|
||||||
public Frequency frequencyFirst;
|
|
||||||
public Frequency frequencyLast;
|
|
||||||
public boolean receivedSignal;
|
public boolean receivedSignal;
|
||||||
public boolean transmittedSignal;
|
public boolean transmittedSignal;
|
||||||
|
|
||||||
public RedstoneBridgeTileEntity() {
|
public RedstoneBridgeTileEntity() {
|
||||||
super(AllTileEntities.REDSTONE_BRIDGE.type);
|
super(AllTileEntities.REDSTONE_BRIDGE.type);
|
||||||
frequencyFirst = new Frequency(ItemStack.EMPTY);
|
|
||||||
frequencyLast = new Frequency(ItemStack.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
super.onLoad();
|
|
||||||
if (world.isRemote)
|
|
||||||
return;
|
|
||||||
FrequencyHandler.addToNetwork(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
super.remove();
|
|
||||||
if (world.isRemote)
|
|
||||||
return;
|
|
||||||
FrequencyHandler.removeFromNetwork(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFrequency(boolean first, ItemStack stack) {
|
|
||||||
stack = stack.copy();
|
|
||||||
stack.setCount(1);
|
|
||||||
ItemStack toCompare = first ? frequencyFirst.getStack() : frequencyLast.getStack();
|
|
||||||
boolean changed = !ItemStack.areItemsEqual(stack, toCompare)
|
|
||||||
|| !ItemStack.areItemStackTagsEqual(stack, toCompare);
|
|
||||||
|
|
||||||
if (changed)
|
|
||||||
FrequencyHandler.removeFromNetwork(this);
|
|
||||||
|
|
||||||
if (first)
|
|
||||||
frequencyFirst = new Frequency(stack);
|
|
||||||
else
|
|
||||||
frequencyLast = new Frequency(stack);
|
|
||||||
|
|
||||||
if (!changed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sendData();
|
|
||||||
FrequencyHandler.addToNetwork(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Frequency getFrequencyFirst() {
|
|
||||||
return frequencyFirst;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Frequency getFrequencyLast() {
|
|
||||||
return frequencyLast;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getSignal() {
|
public boolean getSignal() {
|
||||||
return transmittedSignal;
|
return transmittedSignal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void transmit(boolean signal) {
|
|
||||||
transmittedSignal = signal;
|
|
||||||
notifySignalChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSignal(boolean powered) {
|
public void setSignal(boolean powered) {
|
||||||
receivedSignal = powered;
|
receivedSignal = powered;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isTransmitter() {
|
|
||||||
return !getBlockState().get(RedstoneBridgeBlock.RECEIVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isBlockPowered() {
|
public void transmit(boolean signal) {
|
||||||
return getBlockState().get(POWERED);
|
transmittedSignal = signal;
|
||||||
|
notifySignalChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT write(CompoundNBT compound) {
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT()));
|
|
||||||
compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT()));
|
|
||||||
compound.putBoolean("Transmit", transmittedSignal);
|
compound.putBoolean("Transmit", transmittedSignal);
|
||||||
return super.write(compound);
|
return super.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(CompoundNBT compound) {
|
public void read(CompoundNBT compound) {
|
||||||
frequencyFirst = new Frequency(ItemStack.read(compound.getCompound("FrequencyFirst")));
|
|
||||||
frequencyLast = new Frequency(ItemStack.read(compound.getCompound("FrequencyLast")));
|
|
||||||
transmittedSignal = compound.getBoolean("Transmit");
|
transmittedSignal = compound.getBoolean("Transmit");
|
||||||
super.read(compound);
|
super.read(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (isTransmitter())
|
if (!getBlockState().get(RedstoneBridgeBlock.RECEIVER))
|
||||||
return;
|
return;
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
if (receivedSignal != isBlockPowered()) {
|
if (receivedSignal != getBlockState().get(POWERED)) {
|
||||||
world.setBlockState(pos, getBlockState().cycle(POWERED));
|
world.setBlockState(pos, getBlockState().cycle(POWERED));
|
||||||
Direction attachedFace = getBlockState().get(BlockStateProperties.FACING).getOpposite();
|
Direction attachedFace = getBlockState().get(BlockStateProperties.FACING).getOpposite();
|
||||||
BlockPos attachedPos = pos.offset(attachedFace);
|
BlockPos attachedPos = pos.offset(attachedFace);
|
||||||
|
|
Loading…
Reference in a new issue