Reworked the Belt Observer
- Belt observers now have four modes with different useful behaviours #83 - Fixed belt actors not syncing when items are not held in place but replaced - Upward facing deployers can now act as item displays - Fixed deployer fake players persisting after disassembling a portable contraption - Creepers no longer take revenge on Deployers by default
|
@ -6,6 +6,8 @@ public class CKinetics extends ConfigBase {
|
|||
public ConfigInt crushingDamage = i(4, 0, "crushingDamage", Comments.crushingDamage);
|
||||
public ConfigInt maxMotorSpeed = i(256, 64, "maxMotorSpeed", Comments.rpm, Comments.maxMotorSpeed);
|
||||
public ConfigInt maxRotationSpeed = i(256, 64, "maxRotationSpeed", Comments.rpm, Comments.maxRotationSpeed);
|
||||
public ConfigEnum<DeployerAggroSetting> ignoreDeployerAttacks =
|
||||
e(DeployerAggroSetting.CREEPERS, "ignoreDeployerAttacks", Comments.ignoreDeployerAttacks);
|
||||
|
||||
public ConfigGroup fan = group(0, "encasedFan", "Encased Fan");
|
||||
public ConfigInt fanPushDistance = i(20, 5, "fanPushDistance", Comments.fanPushDistance);
|
||||
|
@ -24,7 +26,8 @@ public class CKinetics extends ConfigBase {
|
|||
public ConfigGroup state = group(0, "stats", Comments.stats);
|
||||
public ConfigFloat mediumSpeed = f(30, 0, 4096, "mediumSpeed", Comments.rpm, Comments.mediumSpeed);
|
||||
public ConfigFloat fastSpeed = f(100, 0, 65535, "fastSpeed", Comments.rpm, Comments.fastSpeed);
|
||||
public ConfigFloat mediumStressImpact = f(8, 0, 4096, "mediumStressImpact", Comments.su, Comments.mediumStressImpact);
|
||||
public ConfigFloat mediumStressImpact =
|
||||
f(8, 0, 4096, "mediumStressImpact", Comments.su, Comments.mediumStressImpact);
|
||||
public ConfigFloat highStressImpact = f(32, 0, 65535, "highStressImpact", Comments.su, Comments.highStressImpact);
|
||||
public ConfigFloat mediumCapacity = f(128, 0, 4096, "mediumCapacity", Comments.su, Comments.mediumCapacity);
|
||||
public ConfigFloat highCapacity = f(512, 0, 65535, "highCapacity", Comments.su, Comments.highCapacity);
|
||||
|
@ -61,6 +64,11 @@ public class CKinetics extends ConfigBase {
|
|||
static String mediumCapacity = "Minimum added Capacity by sources to be considered 'medium'";
|
||||
static String highCapacity = "Minimum added Capacity by sources to be considered 'high'";
|
||||
static String stress = "Fine tune the kinetic stats of individual components";
|
||||
static String ignoreDeployerAttacks = "Select what mobs should ignore Deployers when attacked by them.";
|
||||
}
|
||||
|
||||
public static enum DeployerAggroSetting {
|
||||
ALL, CREEPERS, NONE
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
|||
import net.minecraftforge.common.ForgeConfigSpec.Builder;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.EnumValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.IntValue;
|
||||
|
||||
public abstract class ConfigBase {
|
||||
|
@ -61,6 +62,10 @@ public abstract class ConfigBase {
|
|||
protected ConfigInt i(int current, int min, String name, String... comment) {
|
||||
return i(current, min, Integer.MAX_VALUE, name, comment);
|
||||
}
|
||||
|
||||
protected <T extends Enum<T>> ConfigEnum<T> e(T defaultValue, String name, String... comment) {
|
||||
return new ConfigEnum<>(name, defaultValue, comment);
|
||||
}
|
||||
|
||||
protected ConfigGroup group(int depth, String name, String... comment) {
|
||||
return new ConfigGroup(name, depth, comment);
|
||||
|
@ -153,6 +158,14 @@ public abstract class ConfigBase {
|
|||
super(name, builder -> builder.define(name, def), comment);
|
||||
}
|
||||
}
|
||||
|
||||
public class ConfigEnum<T extends Enum<T>> extends CValue<T, EnumValue<T>> {
|
||||
|
||||
public ConfigEnum(String name, T defaultValue, String[] comment) {
|
||||
super(name, builder -> builder.defineEnum(name, defaultValue), comment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ConfigFloat extends CValue<Double, DoubleValue> {
|
||||
|
||||
|
|
|
@ -6,12 +6,17 @@ import java.util.UUID;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.simibubi.create.config.AllConfigs;
|
||||
import com.simibubi.create.config.CKinetics;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.MobEntity;
|
||||
import net.minecraft.entity.Pose;
|
||||
import net.minecraft.entity.monster.CreeperEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -32,6 +37,7 @@ import net.minecraftforge.common.util.FakePlayer;
|
|||
import net.minecraftforge.event.entity.EntityEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingExperienceDropEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
|
@ -107,6 +113,30 @@ public class DeployerFakePlayer extends FakePlayer {
|
|||
event.setCanceled(true);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void entitiesDontRetaliate(LivingSetAttackTargetEvent event) {
|
||||
if (!(event.getTarget() instanceof DeployerFakePlayer))
|
||||
return;
|
||||
LivingEntity entityLiving = event.getEntityLiving();
|
||||
if (!(entityLiving instanceof MobEntity))
|
||||
return;
|
||||
MobEntity mob = (MobEntity) entityLiving;
|
||||
|
||||
CKinetics.DeployerAggroSetting setting = AllConfigs.SERVER.kinetics.ignoreDeployerAttacks.get();
|
||||
|
||||
switch (setting) {
|
||||
case ALL:
|
||||
mob.setAttackTarget(null);
|
||||
break;
|
||||
case CREEPERS:
|
||||
if (mob instanceof CreeperEntity)
|
||||
mob.setAttackTarget(null);
|
||||
break;
|
||||
case NONE:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
private static class FakePlayNetHandler extends ServerPlayNetHandler {
|
||||
public FakePlayNetHandler(MinecraftServer server, ServerPlayerEntity playerIn) {
|
||||
super(server, NETWORK_MANAGER, playerIn);
|
||||
|
|
|
@ -91,8 +91,12 @@ public class DeployerMovementBehaviour extends MovementBehaviour {
|
|||
if (context.world.isRemote)
|
||||
return;
|
||||
tryDisposeOfEverything(context);
|
||||
DeployerFakePlayer player = getPlayer(context);
|
||||
if (player == null)
|
||||
return;
|
||||
player.remove();
|
||||
}
|
||||
|
||||
|
||||
private void tryGrabbingItem(MovementContext context) {
|
||||
DeployerFakePlayer player = getPlayer(context);
|
||||
if (player == null)
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.foundation.behaviour.filtering.FilteringRenderer;
|
||||
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
|
@ -62,22 +63,37 @@ public class DeployerTileEntityRenderer extends SafeTileEntityRenderer<DeployerT
|
|||
|
||||
float yRot = AngleHelper.horizontalAngle(facing) + 180;
|
||||
float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0;
|
||||
boolean displayMode = facing == Direction.UP && te.speed == 0 && !punching;
|
||||
|
||||
GlStateManager.rotatef(yRot, 0, 1, 0);
|
||||
GlStateManager.rotatef(zRot, 1, 0, 0);
|
||||
GlStateManager.translated(0, 0, -11 / 16f);
|
||||
if (!displayMode) {
|
||||
GlStateManager.rotatef(zRot, 1, 0, 0);
|
||||
GlStateManager.translated(0, 0, -11 / 16f);
|
||||
}
|
||||
|
||||
if (punching)
|
||||
GlStateManager.translatef(0, 1 / 8f, -1 / 16f);
|
||||
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
boolean isBlockItem =
|
||||
(te.heldItem.getItem() instanceof BlockItem) && itemRenderer.getModelWithOverrides(te.heldItem).isGui3d();
|
||||
float scale = punching ? .75f : isBlockItem ? .75f - 1 / 64f : .5f;
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
TransformType transform = punching ? TransformType.THIRD_PERSON_RIGHT_HAND : TransformType.FIXED;
|
||||
itemRenderer.renderItem(te.heldItem, transform);
|
||||
|
||||
TransformType transform = TransformType.NONE;
|
||||
boolean isBlockItem = (te.heldItem.getItem() instanceof BlockItem)
|
||||
&& itemRenderer.getModelWithOverrides(te.heldItem).isGui3d();
|
||||
|
||||
if (displayMode) {
|
||||
float scale = isBlockItem ? 1.25f : 1;
|
||||
GlStateManager.translated(0, isBlockItem ? 9 / 16f : 11 / 16f, 0);
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
transform = TransformType.GROUND;
|
||||
GlStateManager.rotatef(AnimationTickHolder.getRenderTick(), 0, 1, 0);
|
||||
|
||||
} else {
|
||||
float scale = punching ? .75f : isBlockItem ? .75f - 1 / 64f : .5f;
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
transform = punching ? TransformType.THIRD_PERSON_RIGHT_HAND : TransformType.FIXED;
|
||||
}
|
||||
|
||||
itemRenderer.renderItem(te.heldItem, transform);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
|
|
|
@ -137,12 +137,15 @@ public class BeltInventory {
|
|||
if (beltSegment == null)
|
||||
break;
|
||||
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
|
||||
ItemStack stackBefore = current.stack.copy();
|
||||
if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) {
|
||||
current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
||||
current.locked = true;
|
||||
belt.sendData();
|
||||
continue Items;
|
||||
}
|
||||
if (!stackBefore.equals(current.stack, true))
|
||||
belt.sendData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,6 +290,12 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
public BeltInventory getInventory() {
|
||||
if (!isController()) {
|
||||
BeltTileEntity controllerTE = getControllerTE();
|
||||
if (controllerTE != null)
|
||||
return controllerTE.getInventory();
|
||||
return null;
|
||||
}
|
||||
if (inventory == null)
|
||||
inventory = new BeltInventory(this);
|
||||
return inventory;
|
||||
|
|
|
@ -8,7 +8,9 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
|
@ -22,22 +24,33 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BeltObserverBlock extends HorizontalBlock
|
||||
implements IWithTileEntity<BeltObserverTileEntity>, IBeltAttachment {
|
||||
implements IWithTileEntity<BeltObserverTileEntity>, IBeltAttachment, IWrenchable {
|
||||
|
||||
public static BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
public static BooleanProperty BELT = BooleanProperty.create("belt");
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
public static final BooleanProperty BELT = BooleanProperty.create("belt");
|
||||
public static final EnumProperty<Mode> MODE = EnumProperty.create("mode", Mode.class);
|
||||
|
||||
public BeltObserverBlock() {
|
||||
super(Properties.from(Blocks.ANDESITE));
|
||||
|
@ -64,7 +77,7 @@ public class BeltObserverBlock extends HorizontalBlock
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(POWERED, HORIZONTAL_FACING, BELT);
|
||||
builder.add(POWERED, HORIZONTAL_FACING, BELT, MODE);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
|
||||
|
@ -167,52 +180,93 @@ public class BeltObserverBlock extends HorizontalBlock
|
|||
|
||||
@Override
|
||||
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
state.processingDuration = 0;
|
||||
FilteringBehaviour behaviour = TileEntityBehaviour.get(te.getWorld(), state.attachmentPos,
|
||||
FilteringBehaviour.TYPE);
|
||||
if (behaviour != null) {
|
||||
if (!behaviour.test(transported.stack)) {
|
||||
state.processingDuration = -1;
|
||||
return false;
|
||||
World world = te.getWorld();
|
||||
BlockState blockState = world.getBlockState(state.attachmentPos);
|
||||
if (blockState.get(MODE) == Mode.DETECT)
|
||||
return false;
|
||||
|
||||
FilteringBehaviour behaviour =
|
||||
TileEntityBehaviour.get(te.getWorld(), state.attachmentPos, FilteringBehaviour.TYPE);
|
||||
if (behaviour != null && !behaviour.test(transported.stack))
|
||||
return false;
|
||||
|
||||
world.setBlockState(state.attachmentPos, blockState.with(POWERED, true));
|
||||
world.notifyNeighborsOfStateChange(state.attachmentPos, this);
|
||||
withTileEntityDo(world, state.attachmentPos, BeltObserverTileEntity::resetTurnOffCooldown);
|
||||
|
||||
Mode mode = blockState.get(MODE);
|
||||
if (mode == Mode.EJECT || mode == Mode.SPLIT) {
|
||||
ItemStack copy = transported.stack.copy();
|
||||
ItemStack toEject = mode == Mode.EJECT ? transported.stack : copy.split(transported.stack.getCount() / 2);
|
||||
|
||||
if (!toEject.isEmpty()) {
|
||||
if (!eject(world, toEject, state.attachmentPos, blockState.get(HORIZONTAL_FACING)))
|
||||
return true;
|
||||
transported.stack = mode == Mode.EJECT ? ItemStack.EMPTY : copy;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
World world = te.getWorld();
|
||||
BlockState blockState = world.getBlockState(state.attachmentPos);
|
||||
if (state.processingDuration == 0) {
|
||||
world.setBlockState(state.attachmentPos, blockState.with(POWERED, true));
|
||||
world.getPendingBlockTicks().scheduleTick(state.attachmentPos, this, 6);
|
||||
world.notifyNeighborsOfStateChange(state.attachmentPos, this);
|
||||
return true;
|
||||
withTileEntityDo(world, state.attachmentPos, BeltObserverTileEntity::resetTurnOffCooldown);
|
||||
|
||||
Mode mode = blockState.get(MODE);
|
||||
if (mode == Mode.EJECT || mode == Mode.SPLIT) {
|
||||
ItemStack copy = transported.stack.copy();
|
||||
ItemStack toEject = mode == Mode.EJECT ? transported.stack : copy.split(transported.stack.getCount() / 2);
|
||||
|
||||
if (!eject(world, toEject, state.attachmentPos, blockState.get(HORIZONTAL_FACING)))
|
||||
return true;
|
||||
transported.stack = mode == Mode.EJECT ? ItemStack.EMPTY : copy;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean eject(World world, ItemStack stack, BlockPos observerPos, Direction facing) {
|
||||
BlockPos potentialBeltPos = observerPos.offset(facing, 2);
|
||||
TileEntity tileEntity = world.getTileEntity(potentialBeltPos);
|
||||
if (tileEntity instanceof BeltTileEntity) {
|
||||
BeltTileEntity belt = (BeltTileEntity) tileEntity;
|
||||
return belt.tryInsertingFromSide(facing, stack, false);
|
||||
}
|
||||
|
||||
boolean empty = world.getBlockState(potentialBeltPos).getCollisionShape(world, potentialBeltPos).isEmpty();
|
||||
float yOffset = empty ? 0 : .5f;
|
||||
AxisAlignedBB bb = new AxisAlignedBB(empty ? potentialBeltPos : potentialBeltPos.up());
|
||||
if (!world.getEntitiesWithinAABBExcludingEntity(null, bb).isEmpty())
|
||||
return false;
|
||||
|
||||
Vec3d motion = new Vec3d(facing.getDirectionVec()).scale(1 / 16f);
|
||||
Vec3d entityPos = VecHelper.getCenterOf(potentialBeltPos).add(0, yOffset + .25f, 0).subtract(motion);
|
||||
ItemEntity entity = new ItemEntity(world, entityPos.x, entityPos.y, entityPos.z, stack);
|
||||
entity.setMotion(motion);
|
||||
entity.setPickupDelay(5);
|
||||
world.playSound(null, observerPos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f, .1f);
|
||||
world.addEntity(entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
||||
if (te.getWorld().isRemote)
|
||||
return false;
|
||||
|
||||
if (state.processingEntity != entity) {
|
||||
state.processingEntity = entity;
|
||||
state.processingDuration = 0;
|
||||
}
|
||||
|
||||
if (entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > .5f)
|
||||
return false;
|
||||
if (state.processingDuration == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
World world = te.getWorld();
|
||||
BlockState blockState = world.getBlockState(state.attachmentPos);
|
||||
if (blockState.get(POWERED))
|
||||
return false;
|
||||
|
||||
state.processingDuration = -1;
|
||||
world.setBlockState(state.attachmentPos, blockState.with(POWERED, true));
|
||||
world.getPendingBlockTicks().scheduleTick(state.attachmentPos, this, 6);
|
||||
world.notifyNeighborsOfStateChange(state.attachmentPos, this);
|
||||
withTileEntityDo(te.getWorld(), state.attachmentPos, BeltObserverTileEntity::resetTurnOffCooldown);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -222,4 +276,23 @@ public class BeltObserverBlock extends HorizontalBlock
|
|||
worldIn.notifyNeighborsOfStateChange(pos, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
World world = context.getWorld();
|
||||
if (!world.isRemote) {
|
||||
world.setBlockState(context.getPos(), state.with(POWERED, false).cycle(MODE), 3);
|
||||
world.notifyNeighborsOfStateChange(context.getPos(), this);
|
||||
}
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
public enum Mode implements IStringSerializable {
|
||||
DETECT, PULSE, EJECT, SPLIT;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return Lang.asId(name());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,8 +9,12 @@ import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
|||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltObserverBlock.Mode;
|
||||
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -18,9 +22,65 @@ public class BeltObserverTileEntity extends SmartTileEntity {
|
|||
|
||||
private static FilteringBehaviour.SlotPositioning slots;
|
||||
private FilteringBehaviour filtering;
|
||||
public int turnOffTicks = 0;
|
||||
|
||||
public BeltObserverTileEntity() {
|
||||
super(AllTileEntities.ENTITY_DETECTOR.type);
|
||||
setLazyTickRate(20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (turnOffTicks > 0) {
|
||||
turnOffTicks--;
|
||||
if (turnOffTicks == 0)
|
||||
world.getPendingBlockTicks().scheduleTick(pos, getBlockState().getBlock(), 1);
|
||||
}
|
||||
|
||||
if (!isActive())
|
||||
return;
|
||||
if (getBlockState().get(BeltObserverBlock.MODE) != Mode.DETECT)
|
||||
return;
|
||||
|
||||
TileEntity tileEntity =
|
||||
world.getTileEntity(pos.offset(getBlockState().get(BeltObserverBlock.HORIZONTAL_FACING)));
|
||||
if (!(tileEntity instanceof BeltTileEntity))
|
||||
return;
|
||||
BeltTileEntity belt = (BeltTileEntity) tileEntity;
|
||||
BeltTileEntity controllerTE = belt.getControllerTE();
|
||||
if (controllerTE == null)
|
||||
return;
|
||||
|
||||
controllerTE.getInventory().forEachWithin(belt.index + .5f, .45f, stack -> {
|
||||
if (filtering.test(stack.stack) && turnOffTicks != 6) {
|
||||
world.setBlockState(pos, getBlockState().with(BeltObserverBlock.POWERED, true));
|
||||
world.notifyNeighborsOfStateChange(pos, getBlockState().getBlock());
|
||||
resetTurnOffCooldown();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private boolean isActive() {
|
||||
return getBlockState().get(BeltObserverBlock.BELT);
|
||||
}
|
||||
|
||||
public void resetTurnOffCooldown() {
|
||||
turnOffTicks = 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.putInt("TurnOff", turnOffTicks);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
turnOffTicks = compound.getInt("TurnOff");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,23 +1,86 @@
|
|||
{
|
||||
"variants": {
|
||||
"powered=false,belt=false,facing=south": { "model": "create:block/entity_detector", "y": 0 },
|
||||
"powered=false,belt=false,facing=east": { "model": "create:block/entity_detector", "y": 270 },
|
||||
"powered=false,belt=false,facing=north": { "model": "create:block/entity_detector", "y": 180 },
|
||||
"powered=false,belt=false,facing=west": { "model": "create:block/entity_detector", "y": 90 },
|
||||
"mode=detect,powered=false,belt=false,facing=south": { "model": "create:block/belt_observer/detect", "y": 0 },
|
||||
"mode=detect,powered=false,belt=false,facing=east": { "model": "create:block/belt_observer/detect", "y": 270 },
|
||||
"mode=detect,powered=false,belt=false,facing=north": { "model": "create:block/belt_observer/detect", "y": 180 },
|
||||
"mode=detect,powered=false,belt=false,facing=west": { "model": "create:block/belt_observer/detect", "y": 90 },
|
||||
|
||||
"powered=true,belt=false,facing=south": { "model": "create:block/entity_detector_powered", "y": 0 },
|
||||
"powered=true,belt=false,facing=east": { "model": "create:block/entity_detector_powered", "y": 270 },
|
||||
"powered=true,belt=false,facing=north": { "model": "create:block/entity_detector_powered", "y": 180 },
|
||||
"powered=true,belt=false,facing=west": { "model": "create:block/entity_detector_powered", "y": 90 },
|
||||
"mode=detect,powered=true,belt=false,facing=south": { "model": "create:block/belt_observer/detect_powered", "y": 0 },
|
||||
"mode=detect,powered=true,belt=false,facing=east": { "model": "create:block/belt_observer/detect_powered", "y": 270 },
|
||||
"mode=detect,powered=true,belt=false,facing=north": { "model": "create:block/belt_observer/detect_powered", "y": 180 },
|
||||
"mode=detect,powered=true,belt=false,facing=west": { "model": "create:block/belt_observer/detect_powered", "y": 90 },
|
||||
|
||||
"powered=false,belt=true,facing=south": { "model": "create:block/entity_detector_with_belt", "y": 0 },
|
||||
"powered=false,belt=true,facing=east": { "model": "create:block/entity_detector_with_belt", "y": 270 },
|
||||
"powered=false,belt=true,facing=north": { "model": "create:block/entity_detector_with_belt", "y": 180 },
|
||||
"powered=false,belt=true,facing=west": { "model": "create:block/entity_detector_with_belt", "y": 90 },
|
||||
"mode=detect,powered=false,belt=true,facing=south": { "model": "create:block/belt_observer/detect_belt", "y": 0 },
|
||||
"mode=detect,powered=false,belt=true,facing=east": { "model": "create:block/belt_observer/detect_belt", "y": 270 },
|
||||
"mode=detect,powered=false,belt=true,facing=north": { "model": "create:block/belt_observer/detect_belt", "y": 180 },
|
||||
"mode=detect,powered=false,belt=true,facing=west": { "model": "create:block/belt_observer/detect_belt", "y": 90 },
|
||||
|
||||
"powered=true,belt=true,facing=south": { "model": "create:block/entity_detector_with_belt_powered", "y": 0 },
|
||||
"powered=true,belt=true,facing=east": { "model": "create:block/entity_detector_with_belt_powered", "y": 270 },
|
||||
"powered=true,belt=true,facing=north": { "model": "create:block/entity_detector_with_belt_powered", "y": 180 },
|
||||
"powered=true,belt=true,facing=west": { "model": "create:block/entity_detector_with_belt_powered", "y": 90 }
|
||||
"mode=detect,powered=true,belt=true,facing=south": { "model": "create:block/belt_observer/detect_belt_powered", "y": 0 },
|
||||
"mode=detect,powered=true,belt=true,facing=east": { "model": "create:block/belt_observer/detect_belt_powered", "y": 270 },
|
||||
"mode=detect,powered=true,belt=true,facing=north": { "model": "create:block/belt_observer/detect_belt_powered", "y": 180 },
|
||||
"mode=detect,powered=true,belt=true,facing=west": { "model": "create:block/belt_observer/detect_belt_powered", "y": 90 },
|
||||
|
||||
|
||||
"mode=pulse,powered=false,belt=false,facing=south": { "model": "create:block/belt_observer/pulse", "y": 0 },
|
||||
"mode=pulse,powered=false,belt=false,facing=east": { "model": "create:block/belt_observer/pulse", "y": 270 },
|
||||
"mode=pulse,powered=false,belt=false,facing=north": { "model": "create:block/belt_observer/pulse", "y": 180 },
|
||||
"mode=pulse,powered=false,belt=false,facing=west": { "model": "create:block/belt_observer/pulse", "y": 90 },
|
||||
|
||||
"mode=pulse,powered=true,belt=false,facing=south": { "model": "create:block/belt_observer/pulse_powered", "y": 0 },
|
||||
"mode=pulse,powered=true,belt=false,facing=east": { "model": "create:block/belt_observer/pulse_powered", "y": 270 },
|
||||
"mode=pulse,powered=true,belt=false,facing=north": { "model": "create:block/belt_observer/pulse_powered", "y": 180 },
|
||||
"mode=pulse,powered=true,belt=false,facing=west": { "model": "create:block/belt_observer/pulse_powered", "y": 90 },
|
||||
|
||||
"mode=pulse,powered=false,belt=true,facing=south": { "model": "create:block/belt_observer/pulse_belt", "y": 0 },
|
||||
"mode=pulse,powered=false,belt=true,facing=east": { "model": "create:block/belt_observer/pulse_belt", "y": 270 },
|
||||
"mode=pulse,powered=false,belt=true,facing=north": { "model": "create:block/belt_observer/pulse_belt", "y": 180 },
|
||||
"mode=pulse,powered=false,belt=true,facing=west": { "model": "create:block/belt_observer/pulse_belt", "y": 90 },
|
||||
|
||||
"mode=pulse,powered=true,belt=true,facing=south": { "model": "create:block/belt_observer/pulse_belt_powered", "y": 0 },
|
||||
"mode=pulse,powered=true,belt=true,facing=east": { "model": "create:block/belt_observer/pulse_belt_powered", "y": 270 },
|
||||
"mode=pulse,powered=true,belt=true,facing=north": { "model": "create:block/belt_observer/pulse_belt_powered", "y": 180 },
|
||||
"mode=pulse,powered=true,belt=true,facing=west": { "model": "create:block/belt_observer/pulse_belt_powered", "y": 90 },
|
||||
|
||||
|
||||
"mode=eject,powered=false,belt=false,facing=south": { "model": "create:block/belt_observer/eject", "y": 0 },
|
||||
"mode=eject,powered=false,belt=false,facing=east": { "model": "create:block/belt_observer/eject", "y": 270 },
|
||||
"mode=eject,powered=false,belt=false,facing=north": { "model": "create:block/belt_observer/eject", "y": 180 },
|
||||
"mode=eject,powered=false,belt=false,facing=west": { "model": "create:block/belt_observer/eject", "y": 90 },
|
||||
|
||||
"mode=eject,powered=true,belt=false,facing=south": { "model": "create:block/belt_observer/eject_powered", "y": 0 },
|
||||
"mode=eject,powered=true,belt=false,facing=east": { "model": "create:block/belt_observer/eject_powered", "y": 270 },
|
||||
"mode=eject,powered=true,belt=false,facing=north": { "model": "create:block/belt_observer/eject_powered", "y": 180 },
|
||||
"mode=eject,powered=true,belt=false,facing=west": { "model": "create:block/belt_observer/eject_powered", "y": 90 },
|
||||
|
||||
"mode=eject,powered=false,belt=true,facing=south": { "model": "create:block/belt_observer/eject_belt", "y": 0 },
|
||||
"mode=eject,powered=false,belt=true,facing=east": { "model": "create:block/belt_observer/eject_belt", "y": 270 },
|
||||
"mode=eject,powered=false,belt=true,facing=north": { "model": "create:block/belt_observer/eject_belt", "y": 180 },
|
||||
"mode=eject,powered=false,belt=true,facing=west": { "model": "create:block/belt_observer/eject_belt", "y": 90 },
|
||||
|
||||
"mode=eject,powered=true,belt=true,facing=south": { "model": "create:block/belt_observer/eject_belt_powered", "y": 0 },
|
||||
"mode=eject,powered=true,belt=true,facing=east": { "model": "create:block/belt_observer/eject_belt_powered", "y": 270 },
|
||||
"mode=eject,powered=true,belt=true,facing=north": { "model": "create:block/belt_observer/eject_belt_powered", "y": 180 },
|
||||
"mode=eject,powered=true,belt=true,facing=west": { "model": "create:block/belt_observer/eject_belt_powered", "y": 90 },
|
||||
|
||||
|
||||
"mode=split,powered=false,belt=false,facing=south": { "model": "create:block/belt_observer/split", "y": 0 },
|
||||
"mode=split,powered=false,belt=false,facing=east": { "model": "create:block/belt_observer/split", "y": 270 },
|
||||
"mode=split,powered=false,belt=false,facing=north": { "model": "create:block/belt_observer/split", "y": 180 },
|
||||
"mode=split,powered=false,belt=false,facing=west": { "model": "create:block/belt_observer/split", "y": 90 },
|
||||
|
||||
"mode=split,powered=true,belt=false,facing=south": { "model": "create:block/belt_observer/split_powered", "y": 0 },
|
||||
"mode=split,powered=true,belt=false,facing=east": { "model": "create:block/belt_observer/split_powered", "y": 270 },
|
||||
"mode=split,powered=true,belt=false,facing=north": { "model": "create:block/belt_observer/split_powered", "y": 180 },
|
||||
"mode=split,powered=true,belt=false,facing=west": { "model": "create:block/belt_observer/split_powered", "y": 90 },
|
||||
|
||||
"mode=split,powered=false,belt=true,facing=south": { "model": "create:block/belt_observer/split_belt", "y": 0 },
|
||||
"mode=split,powered=false,belt=true,facing=east": { "model": "create:block/belt_observer/split_belt", "y": 270 },
|
||||
"mode=split,powered=false,belt=true,facing=north": { "model": "create:block/belt_observer/split_belt", "y": 180 },
|
||||
"mode=split,powered=false,belt=true,facing=west": { "model": "create:block/belt_observer/split_belt", "y": 90 },
|
||||
|
||||
"mode=split,powered=true,belt=true,facing=south": { "model": "create:block/belt_observer/split_belt_powered", "y": 0 },
|
||||
"mode=split,powered=true,belt=true,facing=east": { "model": "create:block/belt_observer/split_belt_powered", "y": 270 },
|
||||
"mode=split,powered=true,belt=true,facing=north": { "model": "create:block/belt_observer/split_belt_powered", "y": 180 },
|
||||
"mode=split,powered=true,belt=true,facing=west": { "model": "create:block/belt_observer/split_belt_powered", "y": 90 }
|
||||
}
|
||||
}
|
|
@ -953,11 +953,15 @@
|
|||
"block.create.brass_casing.tooltip.behaviour1": "_Reinforces_ _belts_ with a brass foundation. Reinforced Belts can support _Belt_ _Tunnels_ aswell as _Extractors,_ _Funnels_ and _Transposers_ interacting with the belt from the sides and below.",
|
||||
|
||||
"block.create.entity_detector.tooltip": "BELT OBSERVER",
|
||||
"block.create.entity_detector.tooltip.summary": "Detects items passing by on a _Mechanical_ _Belt_ in front of it. Works well with a _Piston_ on top, pushing certain items off.",
|
||||
"block.create.entity_detector.tooltip.condition1": "When item matches Filter",
|
||||
"block.create.entity_detector.tooltip.behaviour1": "Provides a short _Redstone_ _pulse_ to all sides. An Empty Filter matches all passing items.",
|
||||
"block.create.entity_detector.tooltip.control1": "R-Click on Filter Space",
|
||||
"block.create.entity_detector.tooltip.action1": "Assigns currently _held_ _stack_ as the _Filter._ Observer will react to this item type only.",
|
||||
"block.create.entity_detector.tooltip.summary": "Detects items and entities passing by on a _Mechanical_ _Belt_ in front of it. Use a _Wrench_ to cycle its behaviour. Non-items will always be handled in detect mode regarless of the setting.",
|
||||
"block.create.entity_detector.tooltip.condition1": "Detect Mode",
|
||||
"block.create.entity_detector.tooltip.behaviour1": "Provides redstone _while_ a _matching_ _item_ _is_ in the observed belt segment.",
|
||||
"block.create.entity_detector.tooltip.condition2": "Pulse Mode",
|
||||
"block.create.entity_detector.tooltip.behaviour2": "Emits a _pulse_ when a _matching_ _item_ _passes_ the center of the observed belt segment.",
|
||||
"block.create.entity_detector.tooltip.condition3": "Eject Mode",
|
||||
"block.create.entity_detector.tooltip.behaviour3": "_Ejects_ _matching_ _items_ off the side. If the target belt or space is _occupied,_ the item will be _held_ _in_ _place._",
|
||||
"block.create.entity_detector.tooltip.condition4": "Split Mode",
|
||||
"block.create.entity_detector.tooltip.behaviour4": "_Splits_ a _matching_ _item_ _stack_ and _ejects_ _half_ of it off the side.",
|
||||
|
||||
"block.create.pulse_repeater.tooltip": "PULSE REPEATER",
|
||||
"block.create.pulse_repeater.tooltip.summary": "A simple circuit for cutting passing redstone signals to a length of _1_ _tick._",
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
"textures": {
|
||||
"brass_casing": "create:block/brass_casing",
|
||||
"extractor": "create:block/extractor",
|
||||
"particle": "create:block/entity_detector_off",
|
||||
"entity_detector_off": "create:block/entity_detector_off",
|
||||
"entity_detector_front": "create:block/entity_detector_front"
|
||||
"particle": "#texture",
|
||||
"entity_detector_off": "#texture",
|
||||
"entity_detector_front": "create:block/belt_observer_front"
|
||||
},
|
||||
"elements": [
|
||||
{
|
|
@ -4,9 +4,9 @@
|
|||
"textures": {
|
||||
"3": "create:block/extractor",
|
||||
"brass_casing": "create:block/brass_casing",
|
||||
"particle": "create:block/entity_detector_off",
|
||||
"entity_detector_off": "create:block/entity_detector_off",
|
||||
"entity_detector_front": "create:block/entity_detector_front"
|
||||
"particle": "#texture",
|
||||
"entity_detector_off": "#texture",
|
||||
"entity_detector_front": "create:block/belt_observer_front"
|
||||
},
|
||||
"elements": [
|
||||
{
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt",
|
||||
"textures": {
|
||||
"3": "create:block/extractor_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base",
|
||||
"textures": {
|
||||
"extractor": "create:block/extractor_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_detect"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_detect"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_detect_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_detect_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_eject"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_eject"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_eject_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_eject_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_pulse"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_pulse"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_pulse_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_pulse_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_split"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_split"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_belt_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_split_powered"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/belt_observer/base_powered",
|
||||
"textures": {
|
||||
"texture": "create:block/belt_observer_split_powered"
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"parent": "create:block/entity_detector",
|
||||
"textures": {
|
||||
"extractor": "create:block/extractor_powered",
|
||||
"entity_detector_off": "create:block/entity_detector_on",
|
||||
"particle": "create:block/entity_detector_on"
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"parent": "create:block/entity_detector_with_belt",
|
||||
"textures": {
|
||||
"3": "create:block/extractor_powered",
|
||||
"entity_detector_off": "create:block/entity_detector_on",
|
||||
"particle": "create:block/entity_detector_on"
|
||||
}
|
||||
}
|
|
@ -15,8 +15,8 @@
|
|||
},
|
||||
"textures": {
|
||||
"brass_casing": "create:block/brass_casing",
|
||||
"entity_detector_off": "create:block/entity_detector_off",
|
||||
"entity_detector_front": "create:block/entity_detector_front"
|
||||
"entity_detector_off": "create:block/belt_observer_detect",
|
||||
"entity_detector_front": "create:block/belt_observer_front"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
|
|
After Width: | Height: | Size: 518 B |
After Width: | Height: | Size: 507 B |
After Width: | Height: | Size: 532 B |
After Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 541 B |
After Width: | Height: | Size: 560 B |
After Width: | Height: | Size: 557 B |
After Width: | Height: | Size: 557 B |
Before Width: | Height: | Size: 426 B After Width: | Height: | Size: 547 B |
Before Width: | Height: | Size: 529 B |
Before Width: | Height: | Size: 544 B |