mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-23 21:46:40 +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.GearshifterTileEntityRenderer;
|
||||
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.LinkedExtractorTileEntity;
|
||||
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.schematics.block.SchematicTableTileEntity;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
|
||||
|
@ -66,6 +68,8 @@ public enum AllTileEntities {
|
|||
REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE),
|
||||
STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH),
|
||||
FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE),
|
||||
EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR),
|
||||
LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR),
|
||||
|
||||
// Economy
|
||||
SHOP_SHELF(ShopShelfTileEntity::new, AllBlocks.SHOP_SHELF),
|
||||
|
@ -110,7 +114,8 @@ public enum AllTileEntities {
|
|||
bind(DrillTileEntity.class, new KineticTileEntityRenderer());
|
||||
bind(CrushingWheelTileEntity.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)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -29,4 +31,9 @@ public class VecHelper {
|
|||
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();
|
||||
NonNullList<ItemStack> stacks = NonNullList.withSize(10, ItemStack.EMPTY);
|
||||
ItemStackHelper.loadAllItems(nbt, stacks);
|
||||
|
||||
|
||||
for (int slot = 0; slot < stacks.size(); slot++)
|
||||
inventory.setInventorySlotContents(slot, stacks.get(slot));
|
||||
inventory.processingDuration = nbt.getInt("ProcessingTime");
|
||||
inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe");
|
||||
inventory.processingDuration = nbt.getInt("ProcessingTime");
|
||||
inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe");
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
|
||||
public ItemStackHandler getItems() {
|
||||
return (ItemStackHandler) inv;
|
||||
}
|
||||
|
@ -97,14 +97,14 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
float speed = crushingspeed / 2.5f;
|
||||
|
||||
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;
|
||||
spawnParticles(contents.getStackInSlot(0));
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
|
||||
if (contents.processingDuration < 20 && !contents.appliedRecipe) {
|
||||
applyRecipe();
|
||||
contents.appliedRecipe = true;
|
||||
|
@ -167,8 +167,9 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
||||
|
||||
Random r = world.rand;
|
||||
world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(),
|
||||
pos.getZ() + r.nextFloat(), 0, 0, 0);
|
||||
for (int i = 0; i < 4; i++)
|
||||
world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(),
|
||||
pos.getZ() + r.nextFloat(), 0, 0, 0);
|
||||
}
|
||||
|
||||
private void applyRecipe() {
|
||||
|
@ -178,16 +179,16 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
if (recipe.isPresent()) {
|
||||
int rolls = contents.getStackInSlot(0).getCount();
|
||||
contents.clear();
|
||||
|
||||
|
||||
for (int roll = 0; roll < rolls; roll++) {
|
||||
List<ItemStack> rolledResults = recipe.get().rollResults();
|
||||
|
||||
|
||||
for (int i = 0; i < rolledResults.size(); i++) {
|
||||
ItemStack stack = rolledResults.get(i);
|
||||
|
||||
|
||||
for (int slot = 0; slot < contents.getSizeInventory(); slot++) {
|
||||
stack = contents.getItems().insertItem(slot, stack, false);
|
||||
|
||||
|
||||
if (stack.isEmpty())
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3,20 +3,29 @@ package com.simibubi.create.modules.contraptions.receivers;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
import net.minecraft.block.AirBlock;
|
||||
import net.minecraft.block.Block;
|
||||
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.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
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 {
|
||||
|
||||
private static final AtomicInteger NEXT_DRILL_ID = new AtomicInteger();
|
||||
|
||||
|
||||
private int ticksUntilNextProgress;
|
||||
private int destroyProgress;
|
||||
private int drillId = -NEXT_DRILL_ID.incrementAndGet();
|
||||
|
@ -34,21 +43,21 @@ public class DrillTileEntity extends KineticTileEntity implements ITickableTileE
|
|||
public void destroyNextTick() {
|
||||
ticksUntilNextProgress = 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.putInt("Progress", destroyProgress);
|
||||
compound.putInt("NextTick", ticksUntilNextProgress);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
destroyProgress = compound.getInt("Progress");
|
||||
ticksUntilNextProgress = compound.getInt("NextTick");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (!world.isRemote && destroyProgress != 0) {
|
||||
|
@ -64,33 +73,52 @@ public class DrillTileEntity extends KineticTileEntity implements ITickableTileE
|
|||
return;
|
||||
if (speed == 0)
|
||||
return;
|
||||
|
||||
|
||||
if (ticksUntilNextProgress < 0)
|
||||
return;
|
||||
if (ticksUntilNextProgress-- > 0)
|
||||
return;
|
||||
|
||||
|
||||
BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING));
|
||||
BlockState stateToBreak = world.getBlockState(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;
|
||||
world.sendBlockBreakProgress(drillId, posToBreak, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
float breakSpeed = Math.abs(speed / 100f);
|
||||
destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
|
||||
|
||||
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;
|
||||
ticksUntilNextProgress = -1;
|
||||
world.sendBlockBreakProgress(drillId, posToBreak, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ticksUntilNextProgress = (int) (blockHardness / breakSpeed);
|
||||
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 net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
@ -9,6 +10,7 @@ public interface IHaveWireless {
|
|||
|
||||
public Frequency getFrequencyFirst();
|
||||
public Frequency getFrequencyLast();
|
||||
public void setFrequency(boolean first, ItemStack stack);
|
||||
public World getWorld();
|
||||
public BlockPos getPos();
|
||||
|
||||
|
|
|
@ -4,16 +4,21 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
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.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ExtractorBlock extends HorizontalBlock {
|
||||
|
@ -34,6 +39,22 @@ public class ExtractorBlock extends HorizontalBlock {
|
|||
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
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
BlockState state = getDefaultState();
|
||||
|
@ -47,6 +68,31 @@ public class ExtractorBlock extends HorizontalBlock {
|
|||
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
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
|
@ -56,6 +102,10 @@ public class ExtractorBlock extends HorizontalBlock {
|
|||
boolean previouslyPowered = state.get(POWERED);
|
||||
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
|
||||
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;
|
||||
|
||||
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.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
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.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
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() {
|
||||
super();
|
||||
cacheItemPositions();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new LinkedExtractorTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
return super.getStateForPlacement(context).with(POWERED, false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
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.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class RedstoneBridgeTileEntityRenderer extends TileEntityRenderer<RedstoneBridgeTileEntity> {
|
||||
public class LinkedTileEntityRenderer extends TileEntityRenderer<LinkedTileEntity> {
|
||||
|
||||
@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) {
|
||||
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();
|
||||
|
||||
Pair<Vec3d, Vec3d> itemPositions = RedstoneBridgeBlock.getFrequencyItemPositions(tileEntityIn.getBlockState());
|
||||
Pair<Vec3d, Vec3d> itemPositions = block.getFrequencyItemPositions(state);
|
||||
Vec3d first = itemPositions.getLeft();
|
||||
Vec3d second = itemPositions.getRight();
|
||||
BlockPos pos = tileEntityIn.getPos();
|
||||
GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
renderFrequencyItem(tileEntityIn.frequencyFirst.getStack(), first, facing);
|
||||
renderFrequencyItem(tileEntityIn.frequencyLast.getStack(), second, facing);
|
||||
renderFrequencyItem(tileEntityIn.frequencyFirst.getStack(), first, facing, scale - 2/16f);
|
||||
renderFrequencyItem(tileEntityIn.frequencyLast.getStack(), second, facing, scale - 2/16f);
|
||||
|
||||
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();
|
||||
boolean vertical = facing.getAxis().isVertical();
|
||||
|
||||
|
||||
IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(stack);
|
||||
boolean blockItem = modelWithOverrides.isGui3d();
|
||||
|
||||
|
||||
float offX = 0;
|
||||
float offY = vertical && !blockItem ? 0 : 0;
|
||||
float offZ = !blockItem ? 1/4f : 0;
|
||||
float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff : 0;
|
||||
if (vertical)
|
||||
offZ = -offZ;
|
||||
|
||||
|
||||
float rotX = vertical ? 90 : 0;
|
||||
float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0);
|
||||
float rotZ = vertical && facing == Direction.DOWN ? 180 : 0;
|
||||
if (facing.getAxis() == Axis.X) {
|
||||
// offZ = -offZ;
|
||||
rotY = -rotY;
|
||||
}
|
||||
|
||||
|
||||
float scale = !blockItem ? .25f : .5f;
|
||||
scale *= 1 + 8 * scaleDiff;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(position.x, position.y, position.z);
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
GlStateManager.rotatef(rotZ, 0, 0, 1);
|
||||
GlStateManager.rotatef(rotY, 0, 1, 0);
|
||||
GlStateManager.rotatef(rotX, 1, 0, 0);
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
GlStateManager.translatef(offX, offY, offZ);
|
||||
itemRenderer.renderItem(stack, TransformType.FIXED);
|
||||
GlStateManager.popMatrix();
|
|
@ -5,23 +5,17 @@ import java.util.List;
|
|||
|
||||
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.utility.ITooltip;
|
||||
import com.simibubi.create.foundation.utility.ItemDescription;
|
||||
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.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
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.world.ClientWorld;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -33,7 +27,6 @@ import net.minecraft.util.BlockRenderLayer;
|
|||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
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;
|
||||
|
@ -46,12 +39,8 @@ import net.minecraft.world.IWorldReader;
|
|||
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 class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITooltip {
|
||||
public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITooltip, IBlockWithFrequency {
|
||||
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
public static final BooleanProperty RECEIVER = BooleanProperty.create("receiver");
|
||||
|
@ -151,15 +140,12 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool
|
|||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
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()) {
|
||||
RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(pos);
|
||||
if (te == null)
|
||||
return false;
|
||||
|
||||
if (!worldIn.isRemote) {
|
||||
Boolean wasReceiver = state.get(RECEIVER);
|
||||
boolean blockPowered = worldIn.isBlockPowered(pos);
|
||||
|
@ -172,86 +158,7 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool
|
|||
return true;
|
||||
}
|
||||
|
||||
Vec3d vec = new Vec3d(pos);
|
||||
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();
|
||||
return handleActivated(state, worldIn, pos, player, handIn, hit);
|
||||
}
|
||||
|
||||
@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);
|
||||
return itemPositions.get(facing.getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getFrequencyItemFacing(BlockState state) {
|
||||
return state.get(FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
|
|
|
@ -3,127 +3,59 @@ package com.simibubi.create.modules.logistics.block;
|
|||
import static net.minecraft.state.properties.BlockStateProperties.POWERED;
|
||||
|
||||
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.ITransmitWireless;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class RedstoneBridgeTileEntity extends SyncedTileEntity
|
||||
public class RedstoneBridgeTileEntity extends LinkedTileEntity
|
||||
implements ITickableTileEntity, IReceiveWireless, ITransmitWireless {
|
||||
|
||||
public Frequency frequencyFirst;
|
||||
public Frequency frequencyLast;
|
||||
public boolean receivedSignal;
|
||||
public boolean transmittedSignal;
|
||||
|
||||
public RedstoneBridgeTileEntity() {
|
||||
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
|
||||
public boolean getSignal() {
|
||||
return transmittedSignal;
|
||||
}
|
||||
|
||||
public void transmit(boolean signal) {
|
||||
transmittedSignal = signal;
|
||||
notifySignalChange();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSignal(boolean powered) {
|
||||
receivedSignal = powered;
|
||||
}
|
||||
|
||||
protected boolean isTransmitter() {
|
||||
return !getBlockState().get(RedstoneBridgeBlock.RECEIVER);
|
||||
}
|
||||
|
||||
protected boolean isBlockPowered() {
|
||||
return getBlockState().get(POWERED);
|
||||
public void transmit(boolean signal) {
|
||||
transmittedSignal = signal;
|
||||
notifySignalChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
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")));
|
||||
transmittedSignal = compound.getBoolean("Transmit");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (isTransmitter())
|
||||
if (!getBlockState().get(RedstoneBridgeBlock.RECEIVER))
|
||||
return;
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (receivedSignal != isBlockPowered()) {
|
||||
if (receivedSignal != getBlockState().get(POWERED)) {
|
||||
world.setBlockState(pos, getBlockState().cycle(POWERED));
|
||||
Direction attachedFace = getBlockState().get(BlockStateProperties.FACING).getOpposite();
|
||||
BlockPos attachedPos = pos.offset(attachedFace);
|
||||
|
|
Loading…
Reference in a new issue